Whamcloud - gitweb
update smfs 1)Add kml in smfs, but still not finish it, will change later according...
[fs/lustre-release.git] / lustre / smfs / file.c
1 /*
2  * file.c
3  */
4
5 #define DEBUG_SUBSYSTEM S_SM
6
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/string.h>
10 #include <linux/slab.h>
11 #include <linux/stat.h>
12 #include <linux/unistd.h>
13 #include <linux/pagemap.h>
14 #include <linux/lustre_idl.h>
15 #include "smfs_internal.h" 
16         
17 /* instantiate a file handle to the cache file */
18 void smfs_prepare_cachefile(struct inode *inode,
19                             struct file *file, 
20                             struct inode *cache_inode,
21                             struct file *cache_file,
22                             struct dentry *cache_dentry)
23 {
24         ENTRY;
25         cache_file->f_pos = file->f_pos;
26         cache_file->f_mode = file->f_mode;
27         cache_file->f_flags = file->f_flags;
28         cache_file->f_count  = file->f_count;
29         cache_file->f_owner  = file->f_owner;
30         cache_file->f_error = file->f_error;
31         cache_file->f_op = inode->i_fop;
32         cache_file->f_dentry = cache_dentry;
33         cache_file->f_dentry->d_inode = cache_inode;
34         cache_file->f_vfsmnt = file->f_vfsmnt;
35         cache_file->private_data = file->private_data;
36         cache_file->f_it = file->f_it;
37         cache_file->f_reada = file->f_reada;
38         cache_file->f_ramax = file->f_ramax;
39         cache_file->f_raend = file->f_raend;
40         cache_file->f_ralen = file->f_ralen;
41         cache_file->f_rawin = file->f_rawin;
42         EXIT;
43 }
44 /* update file structs*/
45 void smfs_update_file(struct file *file, 
46                       struct file *cache_file)
47 {
48         ENTRY;
49         file->f_pos = cache_file->f_pos;
50         file->f_mode = cache_file->f_mode;
51         file->f_flags = cache_file->f_flags;
52         file->f_count  = cache_file->f_count;
53         file->f_owner  = cache_file->f_owner;
54         file->f_reada = cache_file->f_reada;
55         file->f_ramax = cache_file->f_ramax;
56         file->f_raend = cache_file->f_raend;
57         file->f_ralen = cache_file->f_ralen;
58         file->f_rawin = cache_file->f_rawin;
59         EXIT;
60 }
61
62 static ssize_t smfs_write (struct file *filp, const char *buf, 
63                            size_t count, loff_t *ppos)
64 {
65         struct  inode *cache_inode;
66         struct  dentry *dentry = filp->f_dentry;
67         struct  inode *inode = dentry->d_inode;
68         struct  file open_file;
69         struct  dentry open_dentry;
70         loff_t  tmp_ppos;
71         loff_t  *cache_ppos;
72         int     rc = 0;
73         
74         ENTRY;
75         
76         cache_inode = I2CI(inode);
77  
78         if (!cache_inode)
79                 RETURN(-ENOENT);
80         
81         if (ppos != &(filp->f_pos)) {
82                 cache_ppos = &tmp_ppos; 
83         } else {
84                 cache_ppos = &open_file.f_pos; 
85         }
86         *cache_ppos = *ppos;
87         
88         smfs_prepare_cachefile(inode, filp, cache_inode, 
89                                &open_file, &open_dentry);
90         if (cache_inode->i_fop->write)
91                 rc = cache_inode->i_fop->write(&open_file, buf, count, cache_ppos);
92         
93         *ppos = *cache_ppos;
94         duplicate_inode(cache_inode, inode);
95         smfs_update_file(filp, &open_file);
96
97         RETURN(rc);
98 }
99
100 int smfs_ioctl(struct inode * inode, struct file * filp, 
101                unsigned int cmd, unsigned long arg)
102 {
103         struct  inode *cache_inode;
104         struct  dentry *dentry = filp->f_dentry;
105         struct  file open_file;
106         struct  dentry open_dentry;
107         ssize_t rc = 0;
108         
109         ENTRY;
110         
111         cache_inode = I2CI(dentry->d_inode);
112         if (!cache_inode)
113                 RETURN(-ENOENT);
114
115         smfs_prepare_cachefile(inode, filp, cache_inode, 
116                                &open_file, &open_dentry);
117         
118         if (cache_inode->i_fop->ioctl)
119                 rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
120                 
121         duplicate_inode(cache_inode, inode);
122         smfs_update_file(filp, &open_file);
123         RETURN(rc);
124 }
125
126 static ssize_t smfs_read (struct file *filp, char *buf, 
127                           size_t count, loff_t *ppos)
128 {
129         struct  inode *cache_inode;
130         struct  dentry *dentry = filp->f_dentry;
131         struct  inode *inode = dentry->d_inode;
132         struct  file open_file;
133         struct  dentry open_dentry;
134         loff_t  tmp_ppos;
135         loff_t  *cache_ppos;
136         ssize_t rc = 0;
137         
138         ENTRY;
139         
140         cache_inode = I2CI(dentry->d_inode);
141         if (!cache_inode)
142                 RETURN(-ENOENT);
143
144         if (ppos != &(filp->f_pos)) {
145                 cache_ppos = &tmp_ppos; 
146         } else {
147                 cache_ppos = &open_file.f_pos; 
148         }
149         *cache_ppos = *ppos;
150         
151         
152         smfs_prepare_cachefile(inode, filp, cache_inode, 
153                                &open_file, &open_dentry);
154
155         
156         if (cache_inode->i_fop->read)
157                 rc = cache_inode->i_fop->read(&open_file, buf, count, cache_ppos);
158     
159         *ppos = *cache_ppos;
160         duplicate_inode(cache_inode, inode);
161         smfs_update_file(filp, &open_file);
162         RETURN(rc);
163 }
164
165 static loff_t smfs_llseek(struct file *file, 
166                           loff_t offset, 
167                           int origin)
168 {
169         struct  inode *cache_inode;
170         struct  dentry *dentry = file->f_dentry;
171         struct  file open_file;
172         struct  dentry open_dentry;
173         ssize_t rc = 0;
174         
175         ENTRY;
176         
177         cache_inode = I2CI(dentry->d_inode);
178         if (!cache_inode)
179                 RETURN(-ENOENT);
180
181         smfs_prepare_cachefile(dentry->d_inode, file, cache_inode, 
182                                &open_file, &open_dentry);
183         
184         if (cache_inode->i_fop->llseek)
185                 rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
186
187         duplicate_inode(cache_inode, dentry->d_inode);
188         smfs_update_file(file, &open_file);
189                 
190         RETURN(rc);
191 }
192
193 static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
194 {
195         struct inode *inode = file->f_dentry->d_inode;
196         struct inode *cache_inode = NULL;
197         struct  file open_file;
198         struct  dentry open_dentry;
199         int    rc = 0;
200
201         cache_inode = I2CI(inode);
202         if (!cache_inode)
203                 RETURN(-ENOENT);
204
205         smfs_prepare_cachefile(inode, file, cache_inode, 
206                                &open_file, &open_dentry);
207   
208         if (cache_inode->i_mapping == &cache_inode->i_data)
209                 inode->i_mapping = cache_inode->i_mapping;
210
211         if (cache_inode->i_fop->mmap)
212                 rc = cache_inode->i_fop->mmap(&open_file, vma);
213       
214         duplicate_inode(cache_inode, inode);
215         smfs_update_file(file, &open_file);
216         
217         RETURN(rc);
218 }
219
220 static int smfs_open(struct inode * inode, struct file * filp)
221 {
222         struct inode *cache_inode = NULL;
223         struct  file open_file;
224         struct  dentry open_dentry;
225         int    rc = 0;
226
227         cache_inode = I2CI(inode);
228         if (!cache_inode)
229                 RETURN(-ENOENT);
230
231         smfs_prepare_cachefile(inode, filp, cache_inode, 
232                                &open_file, &open_dentry);
233         
234         if (cache_inode->i_fop->open)
235                 rc = cache_inode->i_fop->open(cache_inode, &open_file);
236         
237         duplicate_inode(cache_inode, inode);
238         smfs_update_file(filp, &open_file);
239         
240         RETURN(rc);
241
242 }
243 static int smfs_release(struct inode * inode, struct file * filp)
244 {
245         struct inode *cache_inode = NULL;
246         struct  file open_file;
247         struct  dentry open_dentry;
248         int    rc = 0;
249
250         cache_inode = I2CI(inode);
251         if (!cache_inode)
252                 RETURN(-ENOENT);
253         
254         smfs_prepare_cachefile(inode, filp, cache_inode, 
255                                &open_file, &open_dentry);
256
257         if (cache_inode->i_fop->release)
258                 rc = cache_inode->i_fop->release(cache_inode, &open_file);
259
260         duplicate_inode(cache_inode, inode);
261         smfs_update_file(filp, &open_file);
262         
263         RETURN(rc);
264 }
265 int smfs_fsync(struct file * file, 
266                       struct dentry *dentry, 
267                       int datasync)
268 {
269         struct inode *inode = dentry->d_inode;
270         struct inode *cache_inode;
271         struct  file open_file;
272         struct  dentry open_dentry;
273         int    rc = 0;
274
275         cache_inode = I2CI(inode);
276         if (!cache_inode)
277                 RETURN(-ENOENT);
278         
279         smfs_prepare_cachefile(inode, file, cache_inode, 
280                                &open_file, &open_dentry);
281
282         if (cache_inode->i_fop->fsync)
283                 rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
284         
285         duplicate_inode(cache_inode, inode);
286         smfs_update_file(file, &open_file);
287         
288         RETURN(rc);
289 }
290
291 struct file_operations smfs_file_fops = {
292         llseek:         smfs_llseek,
293         read:           smfs_read,
294         write:          smfs_write,
295         ioctl:          smfs_ioctl,
296         mmap:           smfs_mmap,
297         open:           smfs_open,
298         release:        smfs_release,
299         fsync:          smfs_fsync,
300 };
301
302 static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode)
303 {
304         atomic_set(&dentry->d_count, 1);
305         dentry->d_vfs_flags = 0;
306         dentry->d_flags = 0;
307         dentry->d_inode = inode;
308         dentry->d_op = NULL;
309         dentry->d_fsdata = NULL;
310         dentry->d_mounted = 0;
311         INIT_LIST_HEAD(&dentry->d_hash);
312         INIT_LIST_HEAD(&dentry->d_lru);
313         INIT_LIST_HEAD(&dentry->d_subdirs);
314         INIT_LIST_HEAD(&dentry->d_alias);
315 }
316
317 static void smfs_truncate(struct inode * inode)      
318 {
319         struct  inode *cache_inode;
320
321         cache_inode = I2CI(inode);
322
323         if (!cache_inode)
324                 return;
325         
326         if (cache_inode->i_op->truncate)
327                 cache_inode->i_op->truncate(cache_inode);
328
329         duplicate_inode(inode, cache_inode);            
330         
331         return; 
332
333  
334 int smfs_setattr(struct dentry *dentry, struct iattr *attr)      
335 {
336         struct  inode *cache_inode;
337         struct  dentry open_dentry;
338
339         int     rc = 0;
340
341         cache_inode = I2CI(dentry->d_inode);
342
343         if (!cache_inode) 
344                 RETURN(-ENOENT);
345         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
346         
347         if (cache_inode->i_op->setattr)
348                 rc = cache_inode->i_op->setattr(&open_dentry, attr);
349
350         duplicate_inode(cache_inode, dentry->d_inode);          
351         
352         RETURN(rc);
353
354   
355 int smfs_setxattr(struct dentry *dentry, const char *name,
356                   const void *value, size_t size, int flags)
357 {
358         struct  inode *cache_inode;
359         struct  dentry open_dentry;
360         int     rc = 0;
361
362         cache_inode = I2CI(dentry->d_inode);
363
364         if (!cache_inode) 
365                 RETURN(-ENOENT);
366
367         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
368         
369         if (cache_inode->i_op->setattr)
370                 rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
371
372         duplicate_inode(cache_inode, dentry->d_inode);          
373         RETURN(rc);
374
375                         
376 int smfs_getxattr(struct dentry *dentry, const char *name,
377                   void *buffer, size_t size)
378 {
379         struct  inode *cache_inode;
380         struct  dentry open_dentry;
381         int     rc = 0;
382
383         cache_inode = I2CI(dentry->d_inode);
384
385         if (!cache_inode) 
386                 RETURN(-ENOENT);
387
388         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
389         
390         if (cache_inode->i_op->setattr)
391                 rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
392
393         duplicate_inode(cache_inode, dentry->d_inode);          
394         RETURN(rc);
395 }
396
397 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
398 {
399         struct  inode *cache_inode;
400         struct  dentry open_dentry;
401         int     rc = 0;
402
403         cache_inode = I2CI(dentry->d_inode);
404
405         if (!cache_inode) 
406                 RETURN(-ENOENT);
407
408         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
409         
410         if (cache_inode->i_op->listxattr)
411                 rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
412
413         duplicate_inode(cache_inode, dentry->d_inode);          
414         RETURN(rc);
415 }                                                                                                                                                           
416
417 int smfs_removexattr(struct dentry *dentry, const char *name)
418 {
419         struct  inode *cache_inode;
420         struct  dentry open_dentry;
421         int     rc = 0;
422
423         cache_inode = I2CI(dentry->d_inode);
424
425         if (!cache_inode) 
426                 RETURN(-ENOENT);
427
428         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
429         
430         if (cache_inode->i_op->removexattr)
431                 rc = cache_inode->i_op->removexattr(&open_dentry, name);
432
433         duplicate_inode(cache_inode, dentry->d_inode);          
434         RETURN(rc);
435 }
436
437 struct inode_operations smfs_file_iops = {
438         truncate:       smfs_truncate,          /* BKL held */
439         setattr:        smfs_setattr,           /* BKL held */
440         setxattr:       smfs_setxattr,          /* BKL held */
441         getxattr:       smfs_getxattr,          /* BKL held */
442         listxattr:      smfs_listxattr,         /* BKL held */
443         removexattr:    smfs_removexattr,       /* BKL held */
444 };
445