Whamcloud - gitweb
88e3931761fe8dd5962f7e0efa20326ade184bb3
[fs/lustre-release.git] / lustre / smfs / file.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/smfs/inode.c
5  *  Lustre filesystem abstraction routines
6  *
7  *  Copyright (C) 2004 Cluster File Systems, Inc.
8  *
9  *   This file is part of Lustre, http://www.lustre.org.
10  *
11  *   Lustre is free software; you can redistribute it and/or
12  *   modify it under the terms of version 2 of the GNU General Public
13  *   License as published by the Free Software Foundation.
14  *
15  *   Lustre is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *   GNU General Public License for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with Lustre; if not, write to the Free Software
22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #define DEBUG_SUBSYSTEM S_SM
26
27 #include <linux/module.h>
28 #include <linux/kernel.h>
29 #include <linux/string.h>
30 #include <linux/slab.h>
31 #include <linux/stat.h>
32 #include <linux/unistd.h>
33 #include <linux/pagemap.h>
34 #include <linux/file.h>
35 #include <linux/fs.h>
36 #include <linux/obd_class.h>
37 #include <linux/obd_support.h>
38 #include <linux/lustre_lib.h>
39 #include <linux/lustre_idl.h>
40 #include <linux/lustre_fsfilt.h>
41 #include <linux/lustre_smfs.h>
42 #include <linux/lustre_snap.h>
43
44 #include "smfs_internal.h"
45
46 static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
47                           loff_t *ppos)
48 {
49         struct inode *cache_inode = I2CI(filp->f_dentry->d_inode);
50         struct smfs_file_info *sfi;
51         loff_t *cache_ppos = NULL;
52         int rc = 0;
53         struct hook_write_msg msg = {
54                 .dentry = filp->f_dentry,
55                 .count = count,
56                 .pos = *ppos
57         };
58          
59         ENTRY;
60
61         LASSERT(cache_inode);
62         LASSERT(cache_inode->i_fop->write);
63
64         sfi = F2SMFI(filp);
65
66         if (sfi->magic != SMFS_FILE_MAGIC) 
67                 LBUG();
68
69         if (filp->f_flags & O_APPEND)
70                 msg.pos = filp->f_dentry->d_inode->i_size;
71         
72         pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
73
74         SMFS_PRE_HOOK(filp->f_dentry->d_inode, HOOK_WRITE, &msg);
75
76         if (ppos != &(filp->f_pos)) {
77                 cache_ppos = &msg.pos;
78         } else {
79                 cache_ppos = &sfi->c_file->f_pos;
80         }
81         
82         *cache_ppos = *ppos;
83
84         rc = cache_inode->i_fop->write(sfi->c_file, buf, count,
85                                        cache_ppos);
86         
87         SMFS_POST_HOOK(filp->f_dentry->d_inode, HOOK_WRITE, &msg, rc);
88         
89         post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
90         *ppos = *cache_ppos;
91         duplicate_file(filp, sfi->c_file);
92         
93         RETURN(rc);
94 }
95
96 int smfs_ioctl(struct inode * inode, struct file * filp,
97                unsigned int cmd, unsigned long arg)
98 {
99         struct  inode *cache_inode = I2CI(filp->f_dentry->d_inode);
100         struct  smfs_file_info *sfi;
101         ssize_t rc = 0;
102
103         ENTRY;
104
105         LASSERT(cache_inode);
106         LASSERT(cache_inode->i_fop->ioctl);
107
108         sfi = F2SMFI(filp);
109         if (sfi->magic != SMFS_FILE_MAGIC) 
110                 LBUG();
111
112         pre_smfs_inode(inode, cache_inode);
113
114         rc = cache_inode->i_fop->ioctl(cache_inode, sfi->c_file, cmd, arg);
115         
116         post_smfs_inode(inode, cache_inode);
117         duplicate_file(filp, sfi->c_file);
118
119         RETURN(rc);
120 }
121
122 static ssize_t smfs_read(struct file *filp, char *buf,
123                          size_t count, loff_t *ppos)
124 {
125         struct  inode *cache_inode = I2CI(filp->f_dentry->d_inode);
126         struct  smfs_file_info *sfi;
127         loff_t  tmp_ppos;
128         loff_t  *cache_ppos = NULL;
129         ssize_t rc = 0;
130
131         ENTRY;
132
133         LASSERT(cache_inode);
134         LASSERT(cache_inode->i_fop->read);
135
136         sfi = F2SMFI(filp);
137         if (sfi->magic != SMFS_FILE_MAGIC) 
138                 LBUG();
139
140         if (ppos != &(filp->f_pos)) {
141                 cache_ppos = &tmp_ppos;
142         } else {
143                 cache_ppos = &sfi->c_file->f_pos;
144         }
145         *cache_ppos = *ppos;
146
147         pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
148
149         rc = cache_inode->i_fop->read(sfi->c_file, buf, count, cache_ppos);
150         
151         *ppos = *cache_ppos;
152         post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
153         duplicate_file(filp, sfi->c_file);
154
155         RETURN(rc);
156 }
157
158 static loff_t smfs_llseek(struct file *file, loff_t offset, int origin)
159 {
160         struct  inode *cache_inode = I2CI(file->f_dentry->d_inode);
161         struct  smfs_file_info *sfi;
162         ssize_t rc = 0;
163
164         ENTRY;
165
166         LASSERT(cache_inode);
167         LASSERT(cache_inode->i_fop->llseek);
168
169         sfi = F2SMFI(file);
170         if (sfi->magic != SMFS_FILE_MAGIC) 
171                 LBUG();
172
173         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
174
175         rc = cache_inode->i_fop->llseek(sfi->c_file, offset, origin);
176         
177         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
178         duplicate_file(file, sfi->c_file);
179
180         RETURN(rc);
181 }
182
183 static int smfs_mmap(struct file *file, struct vm_area_struct *vma)
184 {
185         struct inode *inode = file->f_dentry->d_inode;
186         struct smfs_file_info *sfi;
187         struct inode *cache_inode = I2CI(inode);
188         int rc = 0;
189         ENTRY;
190
191         LASSERT(cache_inode);
192         
193         sfi = F2SMFI(file);
194         if (sfi->magic != SMFS_FILE_MAGIC)
195                 LBUG();
196
197         if (cache_inode->i_mapping == &cache_inode->i_data)
198                 inode->i_mapping = cache_inode->i_mapping;
199
200         pre_smfs_inode(inode, cache_inode);
201         
202         rc = cache_inode->i_fop->mmap(sfi->c_file, vma);
203
204         post_smfs_inode(inode, cache_inode);
205         duplicate_file(file, sfi->c_file);
206
207         RETURN(rc);
208 }
209
210 static int smfs_init_cache_file(struct inode *inode, struct file *filp)
211 {
212         struct smfs_file_info *sfi = NULL;
213         struct file *cache_filp = NULL;
214         struct dentry *cache_dentry = NULL;
215         int rc = 0;
216         ENTRY;
217
218         OBD_ALLOC(sfi, sizeof(struct smfs_file_info));
219         if (!sfi)
220                 RETURN(-ENOMEM);
221
222         cache_filp = get_empty_filp();
223         if (!cache_filp) {
224                 rc = -ENOMEM;
225                 goto err_exit;
226         }
227
228         sfi->magic = SMFS_FILE_MAGIC;
229
230         cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry);
231         if (!cache_dentry) {
232                 rc = -ENOMEM;
233                 goto err_exit;
234         }
235
236         cache_filp->f_vfsmnt = filp->f_vfsmnt;
237         cache_filp->f_dentry = cache_dentry;
238         duplicate_file(cache_filp, filp);
239         sfi->c_file = cache_filp;
240
241         if (filp->private_data != NULL)
242                 LBUG();
243
244         filp->private_data = sfi;
245
246         RETURN(0);
247 err_exit:
248         if (sfi)
249                 OBD_FREE(sfi, sizeof(struct smfs_file_info));
250         if (cache_filp)
251                 put_filp(cache_filp);
252         RETURN(rc);
253 }
254
255 static int smfs_cleanup_cache_file(struct file *filp)
256 {
257         struct smfs_file_info *sfi = NULL;
258                 
259         ENTRY;
260
261         if (!filp)
262                 RETURN(0);
263         
264         sfi = F2SMFI(filp);
265
266         post_smfs_dentry(sfi->c_file->f_dentry);
267
268         put_filp(sfi->c_file);
269
270         OBD_FREE(sfi, sizeof(struct smfs_file_info));
271
272         filp->private_data = NULL;
273
274         RETURN(0);
275 }
276
277 int smfs_open(struct inode *inode, struct file *filp)
278 {
279         struct inode *cache_inode = I2CI(inode);
280         int rc = 0;
281         
282         ENTRY;
283         
284         LASSERT(cache_inode);
285         
286         if ((rc = smfs_init_cache_file(inode, filp)))
287                 RETURN(rc);
288         //it possible that backstore fs has no open(), 
289         //but we need it to init cache filp
290         if (cache_inode->i_fop->open) {
291                 rc = cache_inode->i_fop->open(cache_inode, F2CF(filp));
292                 duplicate_file(filp, F2CF(filp));
293         }
294
295         RETURN(rc);
296 }
297
298 int smfs_release(struct inode *inode, struct file *filp)
299 {
300         struct inode *cache_inode = I2CI(inode);
301         struct file *cache_file = NULL;
302         struct smfs_file_info *sfi = NULL;
303         int rc = 0;
304         
305         ENTRY;
306
307         LASSERT(cache_inode);
308         
309         if (filp) {
310                 sfi = F2SMFI(filp);
311                 if (sfi->magic != SMFS_FILE_MAGIC)
312                         LBUG();
313                 cache_file = sfi->c_file;
314         }
315         
316         if (cache_inode->i_fop->release)
317                 rc = cache_inode->i_fop->release(cache_inode, cache_file);
318
319         post_smfs_inode(inode, cache_inode);
320
321         smfs_cleanup_cache_file(filp);
322         
323         RETURN(rc);
324 }
325
326 int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
327 {
328         struct smfs_file_info *sfi = NULL;
329         struct dentry *cache_dentry = NULL;
330         struct file *cache_file = NULL;
331         struct inode *cache_inode = I2CI(dentry->d_inode);
332         int rc = 0;
333
334         ENTRY;
335         
336         LASSERT(cache_inode);
337         LASSERT(cache_inode->i_fop->fsync);
338         
339         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
340         if (!cache_dentry)
341                 RETURN(-ENOMEM);
342
343         if (file) {
344                 sfi = F2SMFI(file);
345                 if (sfi->magic != SMFS_FILE_MAGIC)
346                         LBUG();
347                 cache_file = sfi->c_file;
348         } 
349
350         pre_smfs_inode(dentry->d_inode, cache_inode);
351
352         rc = cache_inode->i_fop->fsync(cache_file,
353                                        cache_dentry, datasync);
354         
355         post_smfs_inode(dentry->d_inode, cache_inode);
356         duplicate_file(file, cache_file);
357         post_smfs_dentry(cache_dentry);
358
359         RETURN(rc);
360 }
361
362 struct file_operations smfs_file_fops = {
363         llseek:         smfs_llseek,
364         read:           smfs_read,
365         write:          smfs_write,
366         ioctl:          smfs_ioctl,
367         mmap:           smfs_mmap,
368         open:           smfs_open,
369         release:        smfs_release,
370         fsync:          smfs_fsync,
371 };
372
373 static void smfs_truncate(struct inode *inode)
374 {
375         struct inode *cache_inode = I2CI(inode);
376
377         if (!cache_inode || !cache_inode->i_op->truncate)
378                 return;
379
380         pre_smfs_inode(inode, cache_inode);
381         
382         cache_inode->i_op->truncate(cache_inode);
383
384         post_smfs_inode(inode, cache_inode);
385
386         return;
387 }
388
389 int smfs_setattr(struct dentry *dentry, struct iattr *attr)
390 {
391         struct inode *cache_inode = I2CI(dentry->d_inode);
392         struct dentry *cache_dentry;
393         void  *handle = NULL;
394         int rc = 0;
395         struct hook_setattr_msg msg = {
396                 .dentry = dentry,
397                 .attr = attr
398         };
399
400         ENTRY;
401         
402         LASSERT(cache_inode);
403         LASSERT(cache_inode->i_op->setattr);
404
405         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
406         if (!cache_dentry)
407                 RETURN(-ENOMEM);
408
409         handle = smfs_trans_start(dentry->d_inode, FSFILT_OP_SETATTR, NULL);
410         if (IS_ERR(handle) ) {
411                 rc = -ENOSPC;
412                 goto exit;
413         }
414
415         pre_smfs_inode(dentry->d_inode, cache_inode);
416         
417         SMFS_PRE_HOOK(dentry->d_inode, HOOK_SETATTR, &msg); 
418                   
419         rc = cache_inode->i_op->setattr(cache_dentry, attr);
420         
421         SMFS_POST_HOOK(dentry->d_inode, HOOK_SETATTR, &msg, rc);
422         
423         post_smfs_inode(dentry->d_inode, cache_inode);
424         smfs_trans_commit(dentry->d_inode, handle, 0);
425 exit:
426         post_smfs_dentry(cache_dentry);
427         RETURN(rc);
428 }
429
430 int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
431                   size_t size, int flags)
432 {
433         struct inode *cache_inode = I2CI(dentry->d_inode);
434         struct dentry *cache_dentry = NULL;
435         int rc = 0;
436
437         ENTRY;
438         
439         LASSERT(cache_inode);
440         LASSERT(cache_inode->i_op->setxattr);
441         
442         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
443         if (!cache_dentry)
444                 RETURN(-ENOMEM);
445
446         pre_smfs_inode(dentry->d_inode, cache_inode);
447
448         rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
449                                          size, flags);
450
451         post_smfs_inode(dentry->d_inode, cache_inode);
452         post_smfs_dentry(cache_dentry);
453
454         RETURN(rc);
455 }
456
457 int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
458                   size_t size)
459 {
460         struct inode *cache_inode = I2CI(dentry->d_inode);
461         struct dentry *cache_dentry;
462         int rc = 0;
463
464         ENTRY;
465         
466         LASSERT(cache_inode);
467         LASSERT(cache_inode->i_op->getxattr);
468         
469         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
470         if (!cache_dentry)
471                 RETURN(-ENOMEM);
472
473         pre_smfs_inode(dentry->d_inode, cache_inode);
474
475         rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
476                                          size);
477
478         post_smfs_inode(dentry->d_inode, cache_inode);
479         post_smfs_dentry(cache_dentry);
480
481         RETURN(rc);
482 }
483
484 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
485 {
486         struct inode *cache_inode = I2CI(dentry->d_inode);
487         struct dentry *cache_dentry;
488         int rc = 0;
489
490         ENTRY;
491         
492         LASSERT(cache_inode);
493         LASSERT(cache_inode->i_op->listxattr);
494
495         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
496         if (!cache_dentry)
497                 RETURN(-ENOMEM);
498
499         pre_smfs_inode(dentry->d_inode, cache_inode);
500
501         rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
502
503         post_smfs_inode(dentry->d_inode, cache_inode);
504         post_smfs_dentry(cache_dentry);
505
506         RETURN(rc);
507 }
508
509 int smfs_removexattr(struct dentry *dentry, const char *name)
510 {
511         struct inode *cache_inode = I2CI(dentry->d_inode);
512         struct dentry *cache_dentry;
513         int rc = 0;
514
515         ENTRY;
516         
517         LASSERT(cache_inode);
518         LASSERT(cache_inode->i_op->removexattr);
519
520         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
521         if (!cache_dentry)
522                 RETURN(-ENOMEM);
523
524         pre_smfs_inode(dentry->d_inode, cache_inode);
525
526         rc = cache_inode->i_op->removexattr(cache_dentry, name);
527
528         post_smfs_inode(dentry->d_inode, cache_inode);
529         post_smfs_dentry(cache_dentry);
530
531         RETURN(rc);
532 }
533
534 int smfs_permission(struct inode *inode, int mask, struct nameidata *nd)
535 {
536         struct inode *cache_inode = I2CI(inode);
537         int rc = 0;
538
539         ENTRY;
540         
541         LASSERT(cache_inode);
542         LASSERT(cache_inode->i_op->permission);
543
544         pre_smfs_inode(inode, cache_inode);
545
546         rc = cache_inode->i_op->permission(cache_inode, mask, nd);
547
548         post_smfs_inode(inode, cache_inode);
549
550         RETURN(rc);
551 }
552
553 struct inode_operations smfs_file_iops = {
554         .truncate       = smfs_truncate,          /* BKL held */
555         .setattr        = smfs_setattr,           /* BKL held */
556         .setxattr       = smfs_setxattr,
557         .getxattr       = smfs_getxattr,
558         .listxattr      = smfs_listxattr,
559         .removexattr    = smfs_removexattr,
560         .permission     = smfs_permission,
561 };
562
563 struct inode_operations smfs_special_iops = {
564         .setattr        = smfs_setattr,           /* BKL held */
565         .setxattr       = smfs_setxattr,
566         .getxattr       = smfs_getxattr,
567         .listxattr      = smfs_listxattr,
568         .removexattr    = smfs_removexattr,
569         .permission     = smfs_permission,
570 };
571