Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


d26fcb27095e1a46d095065deafb7edd0171e9e1
[palacios.git] / linux_module / palacios-file.c
1 /* Palacios file interface 
2  * (c) Jack Lange, 2010
3  */
4
5
6 #include <linux/fs.h>
7 #include <linux/file.h>
8 #include <linux/spinlock.h>
9 #include <linux/uaccess.h>
10 #include <linux/module.h>
11
12 #include "palacios.h"
13
14 #include <palacios/vmm_file.h>
15
16 static struct list_head global_files;
17
18 struct palacios_file {
19     struct file * filp;
20
21     char * path;
22     int mode;
23     
24     spinlock_t lock;
25
26     struct v3_guest * guest;
27     
28
29     struct list_head file_node;
30 };
31
32
33
34 static void * palacios_file_open(const char * path, int mode, void * private_data) {
35     struct v3_guest * guest = (struct v3_guest *)private_data;
36     struct palacios_file * pfile = NULL;
37     
38     pfile = kmalloc(sizeof(struct palacios_file), GFP_KERNEL);
39     memset(pfile, 0, sizeof(struct palacios_file));
40
41     if ((mode & FILE_OPEN_MODE_READ) && (mode & FILE_OPEN_MODE_WRITE)) { 
42         pfile->mode = O_RDWR;
43     } else if (mode & FILE_OPEN_MODE_READ) { 
44         pfile->mode = O_RDONLY;
45     } else if (mode & FILE_OPEN_MODE_WRITE) { 
46         pfile->mode = O_WRONLY;
47     } 
48
49     pfile->filp = filp_open(path, pfile->mode, 0);
50     
51     if (pfile->filp == NULL) {
52         printk("Cannot open file: %s\n", path);
53         return NULL;
54     }
55
56     pfile->path = kmalloc(strlen(path) + 1, GFP_KERNEL);
57     strncpy(pfile->path, path, strlen(path));
58     pfile->guest = guest;
59     
60     spin_lock_init(&(pfile->lock));
61
62     if (guest == NULL) {
63         list_add(&(pfile->file_node), &(global_files));
64     } else {
65         list_add(&(pfile->file_node), &(guest->files));
66     } 
67
68
69     return pfile;
70 }
71
72 static int palacios_file_close(void * file_ptr) {
73     struct palacios_file * pfile = (struct palacios_file *)file_ptr;
74
75     filp_close(pfile->filp, NULL);
76     
77     list_del(&(pfile->file_node));
78
79     kfree(pfile);
80
81     return 0;
82 }
83
84 static long long palacios_file_size(void * file_ptr) {
85     struct palacios_file * pfile = (struct palacios_file *)file_ptr;
86     struct file * filp = pfile->filp;
87     struct kstat s;
88     int ret;
89     
90     ret = vfs_getattr(filp->f_path.mnt, filp->f_path.dentry, &s);
91
92     if (ret != 0) {
93         printk("Failed to fstat file\n");
94         return -1;
95     }
96
97     return s.size;
98 }
99
100 static long long palacios_file_read(void * file_ptr, void * buffer, long long length, long long offset){
101     struct palacios_file * pfile = (struct palacios_file *)file_ptr;
102     struct file * filp = pfile->filp;
103     ssize_t ret;
104     mm_segment_t old_fs;
105         
106     old_fs = get_fs();
107     set_fs(get_ds());
108         
109     ret = vfs_read(filp, buffer, length, &offset);
110         
111     set_fs(old_fs);
112         
113     if (ret <= 0) {
114         printk("sys_read of %p for %lld bytes failed\n", filp, length);         
115     }
116         
117     return ret;
118 }
119
120
121 static long long palacios_file_write(void * file_ptr, void * buffer, long long length, long long offset) {
122     struct palacios_file * pfile = (struct palacios_file *)file_ptr;
123     struct file * filp = pfile->filp;
124     mm_segment_t old_fs;
125     ssize_t ret;
126
127     old_fs = get_fs();
128     set_fs(get_ds());
129
130     ret = vfs_write(filp, buffer, length, &offset);
131         
132     set_fs(old_fs);
133
134  
135     if (ret <= 0) {
136         printk("sys_write failed\n");           
137     }
138         
139     return ret;
140 }
141
142
143 static struct v3_file_hooks palacios_file_hooks = {
144         .open           = palacios_file_open,
145         .close          = palacios_file_close,
146         .read           = palacios_file_read,
147         .write          = palacios_file_write,
148         .size           = palacios_file_size,
149 };
150
151
152 int palacios_file_init( void ) {
153     INIT_LIST_HEAD(&(global_files));
154
155     V3_Init_File(&palacios_file_hooks);
156
157     return 0;
158 }