X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fiface-file.c;h=67a4e738b1d2ea79bc83a3566dbd158f6385be06;hb=d775bbfa668ce9968bacc0e4257cf86e5ab88e90;hp=091c773cd6d0c0752b3fdaf92dd66c5e708afb24;hpb=94966f95239e03c7df97bd71d6be3e1316239d21;p=palacios.git diff --git a/linux_module/iface-file.c b/linux_module/iface-file.c index 091c773..67a4e73 100644 --- a/linux_module/iface-file.c +++ b/linux_module/iface-file.c @@ -49,8 +49,14 @@ static int mkdir_recursive(const char * path, unsigned short perms) { char * dirname_ptr; char * tmp_iter; - tmp_str = kmalloc(strlen(path) + 1, GFP_KERNEL); + tmp_str = palacios_alloc(strlen(path) + 1); + if (!tmp_str) { + ERROR("Cannot allocate in mkdir recursive\n"); + return -1; + } + memset(tmp_str, 0, strlen(path) + 1); + // will terminate tmp_str strncpy(tmp_str, path, strlen(path)); dirname_ptr = tmp_str; @@ -66,7 +72,8 @@ static int mkdir_recursive(const char * path, unsigned short perms) { (*tmp_iter != '\0')) { if ( (!isprint(*tmp_iter))) { - printk("Invalid character in path name (%d)\n", *tmp_iter); + ERROR("Invalid character in path name (%d)\n", *tmp_iter); + palacios_free(tmp_str); return -1; } else { tmp_iter++; @@ -82,7 +89,8 @@ static int mkdir_recursive(const char * path, unsigned short perms) { // Ignore empty directories if ((tmp_iter - dirname_ptr) > 1) { if (palacios_file_mkdir(tmp_str, perms, 0) != 0) { - printk("Could not create directory (%s)\n", tmp_str); + ERROR("Could not create directory (%s)\n", tmp_str); + palacios_free(tmp_str); return -1; } } @@ -98,7 +106,7 @@ static int mkdir_recursive(const char * path, unsigned short perms) { dirname_ptr = tmp_iter; } - kfree(tmp_str); + palacios_free(tmp_str); return 0; } @@ -111,6 +119,9 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int /* It only exists to provide version compatibility */ struct path tmp_path; #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,41) + struct nameidata nd; +#endif struct path * path_ptr = NULL; struct dentry * dentry; @@ -125,10 +136,8 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int /* Before Linux 3.1 this was somewhat more difficult */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,41) { - struct nameidata nd; - // I'm not 100% sure about the version here, but it was around this time that the API changed -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38) ret = kern_path_parent(pathname, &nd); #else @@ -142,7 +151,7 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int #endif if (ret != 0) { - printk("%s:%d - Error: kern_path_parent() returned error for (%s)\n", __FILE__, __LINE__, + ERROR("%s:%d - Error: kern_path_parent() returned error for (%s)\n", __FILE__, __LINE__, pathname); return -1; } @@ -154,7 +163,7 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int { dentry = kern_path_create(AT_FDCWD, pathname, &tmp_path, 1); - if (IS_ERR(dentry)) { + if (!dentry || IS_ERR(dentry)) { return 0; } @@ -163,7 +172,7 @@ static int palacios_file_mkdir(const char * pathname, unsigned short perms, int #endif - if (!IS_ERR(dentry)) { + if (!(!dentry || IS_ERR(dentry))) { ret = vfs_mkdir(path_ptr->dentry->d_inode, dentry, perms); } @@ -183,12 +192,16 @@ static void * palacios_file_open(const char * path, int mode, void * private_dat vm_state = get_vm_ext_data(guest, "FILE_INTERFACE"); if (vm_state == NULL) { - printk("ERROR: Could not locate vm file state for extension FILE_INTERFACE\n"); + ERROR("ERROR: Could not locate vm file state for extension FILE_INTERFACE\n"); return NULL; } } - pfile = kmalloc(sizeof(struct palacios_file), GFP_KERNEL); + pfile = palacios_alloc(sizeof(struct palacios_file)); + if (!pfile) { + ERROR("Cannot allocate in file open\n"); + return NULL; + } memset(pfile, 0, sizeof(struct palacios_file)); if ((mode & FILE_OPEN_MODE_READ) && (mode & FILE_OPEN_MODE_WRITE)) { @@ -207,18 +220,26 @@ static void * palacios_file_open(const char * path, int mode, void * private_dat pfile->mode |= O_LARGEFILE; - pfile->filp = filp_open(path, pfile->mode, 0); + pfile->filp = filp_open(path, pfile->mode, 0600); // rw------- to start - if (IS_ERR(pfile->filp)) { - printk("Cannot open file: %s\n", path); + if (!pfile->filp || IS_ERR(pfile->filp)) { + ERROR("Cannot open file: %s\n", path); + palacios_free(pfile); return NULL; } - pfile->path = kmalloc(strlen(path) + 1, GFP_KERNEL); - strncpy(pfile->path, path, strlen(path)); + pfile->path = palacios_alloc(strlen(path) + 1); + + if (!pfile->path) { + ERROR("Cannot allocate in file open\n"); + filp_close(pfile->filp,NULL); + palacios_free(pfile); + return NULL; + } + strncpy(pfile->path, path, strlen(path)); // will terminate pfile->path pfile->guest = guest; - spin_lock_init(&(pfile->lock)); + palacios_spinlock_init(&(pfile->lock)); if (guest == NULL) { list_add(&(pfile->file_node), &(global_files)); @@ -233,12 +254,18 @@ static void * palacios_file_open(const char * path, int mode, void * private_dat static int palacios_file_close(void * file_ptr) { struct palacios_file * pfile = (struct palacios_file *)file_ptr; + if (!pfile) { + return -1; + } + filp_close(pfile->filp, NULL); list_del(&(pfile->file_node)); - kfree(pfile->path); - kfree(pfile); + palacios_spinlock_deinit(&(pfile->lock)); + + palacios_free(pfile->path); + palacios_free(pfile); return 0; } @@ -252,7 +279,7 @@ static unsigned long long palacios_file_size(void * file_ptr) { ret = vfs_getattr(filp->f_path.mnt, filp->f_path.dentry, &s); if (ret != 0) { - printk("Failed to fstat file\n"); + ERROR("Failed to fstat file\n"); return -1; } @@ -273,7 +300,7 @@ static unsigned long long palacios_file_read(void * file_ptr, void * buffer, uns set_fs(old_fs); if (ret <= 0) { - printk("sys_read of %p for %lld bytes at offset %llu failed (ret=%ld)\n", filp, length, offset, ret); + ERROR("sys_read of %p for %lld bytes at offset %llu failed (ret=%ld)\n", filp, length, offset, ret); } return ret; @@ -295,7 +322,7 @@ static unsigned long long palacios_file_write(void * file_ptr, void * buffer, un if (ret <= 0) { - printk("sys_write for %llu bytes at offset %llu failed (ret=%ld)\n", length, offset, ret); + ERROR("sys_write for %llu bytes at offset %llu failed (ret=%ld)\n", length, offset, ret); } return ret; @@ -323,15 +350,27 @@ static int file_init( void ) { static int file_deinit( void ) { - if (!list_empty(&(global_files))) { - printk("Error removing module with open files\n"); + struct palacios_file * pfile = NULL; + struct palacios_file * tmp = NULL; + + list_for_each_entry_safe(pfile, tmp, &(global_files), file_node) { + filp_close(pfile->filp, NULL); + list_del(&(pfile->file_node)); + palacios_free(pfile->path); + palacios_free(pfile); } return 0; } static int guest_file_init(struct v3_guest * guest, void ** vm_data) { - struct vm_file_state * state = kmalloc(sizeof(struct vm_file_state), GFP_KERNEL); + struct vm_file_state * state = palacios_alloc(sizeof(struct vm_file_state)); + + if (!state) { + ERROR("Cannot allocate when intializing file services for guest\n"); + return -1; + } + INIT_LIST_HEAD(&(state->open_files)); @@ -343,8 +382,18 @@ static int guest_file_init(struct v3_guest * guest, void ** vm_data) { static int guest_file_deinit(struct v3_guest * guest, void * vm_data) { + struct vm_file_state * state = (struct vm_file_state *)vm_data; + struct palacios_file * pfile = NULL; + struct palacios_file * tmp = NULL; - kfree(vm_data); + list_for_each_entry_safe(pfile, tmp, &(state->open_files), file_node) { + filp_close(pfile->filp, NULL); + list_del(&(pfile->file_node)); + palacios_free(pfile->path); + palacios_free(pfile); + } + + palacios_free(state); return 0; }