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