1 /* Palacios file interface
7 #include <linux/file.h>
8 #include <linux/spinlock.h>
9 #include <linux/uaccess.h>
10 #include <linux/module.h>
13 #include "linux-exts.h"
15 #include <interfaces/vmm_file.h>
17 static struct list_head global_files;
20 struct palacios_file {
28 struct v3_guest * guest;
31 struct list_head file_node;
35 // Currently this just holds the list of open files
36 struct vm_file_state {
37 struct list_head open_files;
42 static void * palacios_file_open(const char * path, int mode, void * private_data) {
43 struct v3_guest * guest = (struct v3_guest *)private_data;
44 struct palacios_file * pfile = NULL;
45 struct vm_file_state * vm_state = NULL;
48 vm_state = get_vm_ext_data(guest, "FILE_INTERFACE");
50 if (vm_state == NULL) {
51 printk("ERROR: Could not locate vm file state for extension FILE_INTERFACE\n");
56 pfile = kmalloc(sizeof(struct palacios_file), GFP_KERNEL);
57 memset(pfile, 0, sizeof(struct palacios_file));
59 if ((mode & FILE_OPEN_MODE_READ) && (mode & FILE_OPEN_MODE_WRITE)) {
61 } else if (mode & FILE_OPEN_MODE_READ) {
62 pfile->mode = O_RDONLY;
63 } else if (mode & FILE_OPEN_MODE_WRITE) {
64 pfile->mode = O_WRONLY;
67 if (mode & FILE_OPEN_MODE_CREATE) {
68 pfile->mode |= O_CREAT;
72 pfile->filp = filp_open(path, pfile->mode, 0);
74 if (pfile->filp == NULL) {
75 printk("Cannot open file: %s\n", path);
79 pfile->path = kmalloc(strlen(path) + 1, GFP_KERNEL);
80 strncpy(pfile->path, path, strlen(path));
83 spin_lock_init(&(pfile->lock));
86 list_add(&(pfile->file_node), &(global_files));
88 list_add(&(pfile->file_node), &(vm_state->open_files));
95 static int palacios_file_close(void * file_ptr) {
96 struct palacios_file * pfile = (struct palacios_file *)file_ptr;
98 filp_close(pfile->filp, NULL);
100 list_del(&(pfile->file_node));
108 static long long palacios_file_size(void * file_ptr) {
109 struct palacios_file * pfile = (struct palacios_file *)file_ptr;
110 struct file * filp = pfile->filp;
114 ret = vfs_getattr(filp->f_path.mnt, filp->f_path.dentry, &s);
117 printk("Failed to fstat file\n");
124 static long long palacios_file_read(void * file_ptr, void * buffer, long long length, long long offset){
125 struct palacios_file * pfile = (struct palacios_file *)file_ptr;
126 struct file * filp = pfile->filp;
133 ret = vfs_read(filp, buffer, length, &offset);
138 printk("sys_read of %p for %lld bytes failed\n", filp, length);
145 static long long palacios_file_write(void * file_ptr, void * buffer, long long length, long long offset) {
146 struct palacios_file * pfile = (struct palacios_file *)file_ptr;
147 struct file * filp = pfile->filp;
154 ret = vfs_write(filp, buffer, length, &offset);
160 printk("sys_write failed\n");
167 static struct v3_file_hooks palacios_file_hooks = {
168 .open = palacios_file_open,
169 .close = palacios_file_close,
170 .read = palacios_file_read,
171 .write = palacios_file_write,
172 .size = palacios_file_size,
177 static int file_init( void ) {
178 INIT_LIST_HEAD(&(global_files));
180 V3_Init_File(&palacios_file_hooks);
186 static int file_deinit( void ) {
187 if (!list_empty(&(global_files))) {
188 printk("Error removing module with open files\n");
194 static int guest_file_init(struct v3_guest * guest, void ** vm_data) {
195 struct vm_file_state * state = kmalloc(sizeof(struct vm_file_state), GFP_KERNEL);
197 INIT_LIST_HEAD(&(state->open_files));
205 static int guest_file_deinit(struct v3_guest * guest, void * vm_data) {
211 static struct linux_ext file_ext = {
212 .name = "FILE_INTERFACE",
214 .deinit = file_deinit,
215 .guest_init = guest_file_init,
216 .guest_deinit = guest_file_deinit
220 register_extension(&file_ext);