From: Jack Lange Date: Thu, 27 Oct 2011 21:35:51 +0000 (-0400) Subject: added directory creation to the file interface X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=c4beaffa640916f82593013a1b272ce09ee1cfbd added directory creation to the file interface --- diff --git a/linux_module/iface-file.c b/linux_module/iface-file.c index 965023a..3d8ab4d 100644 --- a/linux_module/iface-file.c +++ b/linux_module/iface-file.c @@ -4,6 +4,8 @@ #include +#include +#include #include #include #include @@ -16,6 +18,7 @@ static struct list_head global_files; +#define isprint(a) ((a >= ' ') && (a <= '~')) struct palacios_file { struct file * filp; @@ -39,6 +42,120 @@ struct vm_file_state { +static int palacios_file_mkdir(const char * pathname, unsigned short perms, int recurse); + +static int mkdir_recursive(const char * path, unsigned short perms) { + char * tmp_str = NULL; + char * dirname_ptr; + char * tmp_iter; + + tmp_str = kmalloc(strlen(path) + 1, GFP_KERNEL); + memset(tmp_str, 0, strlen(path) + 1); + strncpy(tmp_str, path, strlen(path)); + + dirname_ptr = tmp_str; + tmp_iter = tmp_str; + + // parse path string, call palacios_file_mkdir recursively. + + + while (dirname_ptr != NULL) { + int done = 0; + + while ((*tmp_iter != '/') && + (*tmp_iter != '\0')) { + + if ( (!isprint(*tmp_iter))) { + printk("Invalid character in path name (%d)\n", *tmp_iter); + return -1; + } else { + tmp_iter++; + } + } + + if (*tmp_iter == '/') { + *tmp_iter = '\0'; + } else { + done = 1; + } + + // Ignore empty directories + if ((tmp_iter - dirname_ptr) > 1) { + palacios_file_mkdir(tmp_str, perms, 0); + } + + if (done) { + break; + } else { + *tmp_iter = '/'; + } + + tmp_iter++; + + dirname_ptr = tmp_iter; + } + + kfree(tmp_str); + + return 0; +} + +static int palacios_file_mkdir(const char * pathname, unsigned short perms, int recurse) { + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) + /* DO NOT REFERENCE THIS VARIABLE */ + /* It only exists to provide version compatibility */ + struct path tmp_path; +#endif + + struct path * path_ptr = NULL; + struct dentry * dentry; + int ret = 0; + + + + if (recurse != 0) { + return mkdir_recursive(pathname, perms); + } + + /* Before Linux 3.1 this was somewhat more difficult */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) + { + struct nameidata nd; + ret = kern_path_parent(pathname, &nd); + + if (ret != 0) { + printk("%s:%d - Error: kern_path_parent() returned error for (%s)\n", __FILE__, __LINE__, + pathname); + return -1; + } + + dentry = lookup_create(&nd, 1); + path_ptr = &(nd.path); + } +#else + { + dentry = kern_path_create(AT_FDCWD, pathname, &tmp_path, 1); + + if (IS_ERR(dentry)) { + return -1; + } + + path_ptr = &tmp_path; + } +#endif + + + if (!IS_ERR(dentry)) { + ret = vfs_mkdir(path_ptr->dentry->d_inode, dentry, perms); + } + + mutex_unlock(&(path_ptr->dentry->d_inode->i_mutex)); + path_put(path_ptr); + return ret; +} + + static void * palacios_file_open(const char * path, int mode, void * private_data) { struct v3_guest * guest = (struct v3_guest *)private_data; struct palacios_file * pfile = NULL; @@ -170,6 +287,7 @@ static struct v3_file_hooks palacios_file_hooks = { .read = palacios_file_read, .write = palacios_file_write, .size = palacios_file_size, + .mkdir = palacios_file_mkdir, }; diff --git a/palacios/include/interfaces/vmm_file.h b/palacios/include/interfaces/vmm_file.h index 46b89b1..69b78d8 100644 --- a/palacios/include/interfaces/vmm_file.h +++ b/palacios/include/interfaces/vmm_file.h @@ -27,6 +27,8 @@ #ifdef __V3VEE__ typedef void * v3_file_t; +int v3_mkdir(char * path, uint16_t permissions, uint8_t recursive); + v3_file_t v3_file_open(struct v3_vm_info * vm, char * path, uint8_t mode); int v3_file_close(v3_file_t file); @@ -42,6 +44,7 @@ uint64_t v3_file_write(v3_file_t file, uint8_t * buf, uint64_t len, uint64_t off #define FILE_OPEN_MODE_CREATE (1 << 2) struct v3_file_hooks { + int (*mkdir)(const char * path, unsigned short perms, int recursive); void * (*open)(const char * path, int mode, void * host_data); int (*close)(void * fd); diff --git a/palacios/src/interfaces/vmm_file.c b/palacios/src/interfaces/vmm_file.c index c22267a..c4d3f28 100644 --- a/palacios/src/interfaces/vmm_file.c +++ b/palacios/src/interfaces/vmm_file.c @@ -34,6 +34,13 @@ void V3_Init_File(struct v3_file_hooks * hooks) { } +int v3_mkdir(char * path, uint16_t permissions, uint8_t recursive) { + V3_ASSERT(file_hooks); + V3_ASSERT(file_hooks->mkdir); + + return file_hooks->mkdir(path, permissions, recursive); +} + v3_file_t v3_file_open(struct v3_vm_info * vm, char * path, uint8_t mode) { void * priv_data = NULL; V3_ASSERT(file_hooks);