Whamcloud - gitweb
Update smfs:some minor fix in smfs
[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         pre_smfs_inode(inode, cache_inode);
91         
92         if (cache_inode->i_fop->write)
93                 rc = cache_inode->i_fop->write(&open_file, buf, count, cache_ppos);
94         
95         *ppos = *cache_ppos;
96         post_smfs_inode(inode, cache_inode);
97         smfs_update_file(filp, &open_file);
98
99         RETURN(rc);
100 }
101
102 int smfs_ioctl(struct inode * inode, struct file * filp, 
103                unsigned int cmd, unsigned long arg)
104 {
105         struct  inode *cache_inode;
106         struct  dentry *dentry = filp->f_dentry;
107         struct  file open_file;
108         struct  dentry open_dentry;
109         ssize_t rc = 0;
110         
111         ENTRY;
112         
113         cache_inode = I2CI(dentry->d_inode);
114         if (!cache_inode)
115                 RETURN(-ENOENT);
116
117         smfs_prepare_cachefile(inode, filp, cache_inode, 
118                                &open_file, &open_dentry);
119         
120         if (cache_inode->i_fop->ioctl)
121                 rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
122                 
123         post_smfs_inode(inode, cache_inode);
124         smfs_update_file(filp, &open_file);
125         RETURN(rc);
126 }
127
128 static ssize_t smfs_read (struct file *filp, char *buf, 
129                           size_t count, loff_t *ppos)
130 {
131         struct  inode *cache_inode;
132         struct  dentry *dentry = filp->f_dentry;
133         struct  inode *inode = dentry->d_inode;
134         struct  file open_file;
135         struct  dentry open_dentry;
136         loff_t  tmp_ppos;
137         loff_t  *cache_ppos;
138         ssize_t rc = 0;
139         
140         ENTRY;
141         
142         cache_inode = I2CI(dentry->d_inode);
143         if (!cache_inode)
144                 RETURN(-ENOENT);
145
146         if (ppos != &(filp->f_pos)) {
147                 cache_ppos = &tmp_ppos; 
148         } else {
149                 cache_ppos = &open_file.f_pos; 
150         }
151         *cache_ppos = *ppos;
152         
153         
154         smfs_prepare_cachefile(inode, filp, cache_inode, 
155                                &open_file, &open_dentry);
156
157         
158         pre_smfs_inode(inode, cache_inode);
159         if (cache_inode->i_fop->read)
160                 rc = cache_inode->i_fop->read(&open_file, buf, count, cache_ppos);
161     
162         *ppos = *cache_ppos;
163         post_smfs_inode(inode, cache_inode);
164         smfs_update_file(filp, &open_file);
165         RETURN(rc);
166 }
167
168 static loff_t smfs_llseek(struct file *file, 
169                           loff_t offset, 
170                           int origin)
171 {
172         struct  inode *cache_inode;
173         struct  dentry *dentry = file->f_dentry;
174         struct  file open_file;
175         struct  dentry open_dentry;
176         ssize_t rc = 0;
177         
178         ENTRY;
179         
180         cache_inode = I2CI(dentry->d_inode);
181         if (!cache_inode)
182                 RETURN(-ENOENT);
183
184         smfs_prepare_cachefile(dentry->d_inode, file, cache_inode, 
185                                &open_file, &open_dentry);
186         
187         pre_smfs_inode(dentry->d_inode, cache_inode);
188         if (cache_inode->i_fop->llseek)
189                 rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
190
191         post_smfs_inode(dentry->d_inode, cache_inode);
192         smfs_update_file(file, &open_file);
193                 
194         RETURN(rc);
195 }
196
197 static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
198 {
199         struct inode *inode = file->f_dentry->d_inode;
200         struct inode *cache_inode = NULL;
201         struct  file open_file;
202         struct  dentry open_dentry;
203         int    rc = 0;
204
205         cache_inode = I2CI(inode);
206         if (!cache_inode)
207                 RETURN(-ENOENT);
208
209         smfs_prepare_cachefile(inode, file, cache_inode, 
210                                &open_file, &open_dentry);
211   
212         if (cache_inode->i_mapping == &cache_inode->i_data)
213                 inode->i_mapping = cache_inode->i_mapping;
214
215         pre_smfs_inode(inode, cache_inode);
216         if (cache_inode->i_fop->mmap)
217                 rc = cache_inode->i_fop->mmap(&open_file, vma);
218       
219         post_smfs_inode(inode, cache_inode);
220         smfs_update_file(file, &open_file);
221         
222         RETURN(rc);
223 }
224
225 static int smfs_open(struct inode * inode, struct file * filp)
226 {
227         struct inode *cache_inode = NULL;
228         struct  file open_file;
229         struct  dentry open_dentry;
230         int    rc = 0;
231
232         cache_inode = I2CI(inode);
233         if (!cache_inode)
234                 RETURN(-ENOENT);
235
236         smfs_prepare_cachefile(inode, filp, cache_inode, 
237                                &open_file, &open_dentry);
238         
239         pre_smfs_inode(inode, cache_inode);
240         if (cache_inode->i_fop->open)
241                 rc = cache_inode->i_fop->open(cache_inode, &open_file);
242         
243         post_smfs_inode(inode, cache_inode);
244         smfs_update_file(filp, &open_file);
245         
246         RETURN(rc);
247
248 }
249 static int smfs_release(struct inode * inode, struct file * filp)
250 {
251         struct inode *cache_inode = NULL;
252         struct  file open_file;
253         struct  dentry open_dentry;
254         int    rc = 0;
255
256         cache_inode = I2CI(inode);
257         if (!cache_inode)
258                 RETURN(-ENOENT);
259         
260         smfs_prepare_cachefile(inode, filp, cache_inode, 
261                                &open_file, &open_dentry);
262
263         pre_smfs_inode(inode, cache_inode);
264         if (cache_inode->i_fop->release)
265                 rc = cache_inode->i_fop->release(cache_inode, &open_file);
266
267         post_smfs_inode(inode, cache_inode);
268         smfs_update_file(filp, &open_file);
269         
270         RETURN(rc);
271 }
272 int smfs_fsync(struct file * file, 
273                       struct dentry *dentry, 
274                       int datasync)
275 {
276         struct inode *inode = dentry->d_inode;
277         struct inode *cache_inode;
278         struct  file open_file;
279         struct  dentry open_dentry;
280         int    rc = 0;
281
282         cache_inode = I2CI(inode);
283         if (!cache_inode)
284                 RETURN(-ENOENT);
285         
286         smfs_prepare_cachefile(inode, file, cache_inode, 
287                                &open_file, &open_dentry);
288
289         pre_smfs_inode(inode, cache_inode);
290         if (cache_inode->i_fop->fsync)
291                 rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
292         
293         post_smfs_inode(inode, cache_inode);
294         smfs_update_file(file, &open_file);
295         
296         RETURN(rc);
297 }
298
299 struct file_operations smfs_file_fops = {
300         llseek:         smfs_llseek,
301         read:           smfs_read,
302         write:          smfs_write,
303         ioctl:          smfs_ioctl,
304         mmap:           smfs_mmap,
305         open:           smfs_open,
306         release:        smfs_release,
307         fsync:          smfs_fsync,
308 };
309
310 static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode)
311 {
312         atomic_set(&dentry->d_count, 1);
313         dentry->d_vfs_flags = 0;
314         dentry->d_flags = 0;
315         dentry->d_inode = inode;
316         dentry->d_op = NULL;
317         dentry->d_fsdata = NULL;
318         dentry->d_mounted = 0;
319         INIT_LIST_HEAD(&dentry->d_hash);
320         INIT_LIST_HEAD(&dentry->d_lru);
321         INIT_LIST_HEAD(&dentry->d_subdirs);
322         INIT_LIST_HEAD(&dentry->d_alias);
323 }
324
325 static void smfs_truncate(struct inode * inode)      
326 {
327         struct  inode *cache_inode;
328
329         cache_inode = I2CI(inode);
330
331         if (!cache_inode)
332                 return;
333         
334         if (cache_inode->i_op->truncate)
335                 cache_inode->i_op->truncate(cache_inode);
336
337         post_smfs_inode(inode, cache_inode);
338         
339         return; 
340
341  
342 int smfs_setattr(struct dentry *dentry, struct iattr *attr)      
343 {
344         struct  inode *cache_inode;
345         struct  dentry open_dentry;
346
347         int     rc = 0;
348
349         cache_inode = I2CI(dentry->d_inode);
350
351         if (!cache_inode) 
352                 RETURN(-ENOENT);
353         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
354         
355         pre_smfs_inode(dentry->d_inode, cache_inode);
356         if (cache_inode->i_op->setattr)
357                 rc = cache_inode->i_op->setattr(&open_dentry, attr);
358
359         post_smfs_inode(dentry->d_inode, cache_inode);
360         
361         RETURN(rc);
362
363   
364 int smfs_setxattr(struct dentry *dentry, const char *name,
365                   const void *value, size_t size, int flags)
366 {
367         struct  inode *cache_inode;
368         struct  dentry open_dentry;
369         int     rc = 0;
370
371         cache_inode = I2CI(dentry->d_inode);
372
373         if (!cache_inode) 
374                 RETURN(-ENOENT);
375
376         pre_smfs_inode(dentry->d_inode, cache_inode);
377         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
378         
379         if (cache_inode->i_op->setattr)
380                 rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
381
382         post_smfs_inode(dentry->d_inode, cache_inode);
383         RETURN(rc);
384
385                         
386 int smfs_getxattr(struct dentry *dentry, const char *name,
387                   void *buffer, size_t size)
388 {
389         struct  inode *cache_inode;
390         struct  dentry open_dentry;
391         int     rc = 0;
392
393         cache_inode = I2CI(dentry->d_inode);
394
395         if (!cache_inode) 
396                 RETURN(-ENOENT);
397
398         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
399         pre_smfs_inode(dentry->d_inode, cache_inode);
400         
401         if (cache_inode->i_op->setattr)
402                 rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
403
404         post_smfs_inode(dentry->d_inode, cache_inode);
405         RETURN(rc);
406 }
407
408 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
409 {
410         struct  inode *cache_inode;
411         struct  dentry open_dentry;
412         int     rc = 0;
413
414         cache_inode = I2CI(dentry->d_inode);
415
416         if (!cache_inode) 
417                 RETURN(-ENOENT);
418
419         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
420         pre_smfs_inode(dentry->d_inode, cache_inode);
421         
422         if (cache_inode->i_op->listxattr)
423                 rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
424
425         post_smfs_inode(dentry->d_inode, cache_inode);
426         RETURN(rc);
427 }                                                                                                                                                           
428
429 int smfs_removexattr(struct dentry *dentry, const char *name)
430 {
431         struct  inode *cache_inode;
432         struct  dentry open_dentry;
433         int     rc = 0;
434
435         cache_inode = I2CI(dentry->d_inode);
436
437         if (!cache_inode) 
438                 RETURN(-ENOENT);
439
440         smfs_prepare_cache_dentry(&open_dentry, cache_inode);
441         pre_smfs_inode(dentry->d_inode, cache_inode);
442         
443         if (cache_inode->i_op->removexattr)
444                 rc = cache_inode->i_op->removexattr(&open_dentry, name);
445
446         post_smfs_inode(dentry->d_inode, cache_inode);
447         RETURN(rc);
448 }
449
450 struct inode_operations smfs_file_iops = {
451         truncate:       smfs_truncate,          /* BKL held */
452         setattr:        smfs_setattr,           /* BKL held */
453         setxattr:       smfs_setxattr,          /* BKL held */
454         getxattr:       smfs_getxattr,          /* BKL held */
455         listxattr:      smfs_listxattr,         /* BKL held */
456         removexattr:    smfs_removexattr,       /* BKL held */
457 };
458