Whamcloud - gitweb
3d24664d921855022f01e768a4f124184a9f2e3e
[fs/lustre-release.git] / lustre / smfs / fsfilt.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/lib/fsfilt_smfs.c
5  *  Lustre filesystem abstraction routines
6  *
7  *  Copyright (C) 2004 Cluster File Systems, Inc.
8  *   Author: Wang Di <wangdi@clusterfs.com>
9  *
10  *   This file is part of Lustre, http://www.lustre.org.
11  *
12  *   Lustre is free software; you can redistribute it and/or
13  *   modify it under the terms of version 2 of the GNU General Public
14  *   License as published by the Free Software Foundation.
15  *
16  *   Lustre is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with Lustre; if not, write to the Free Software
23  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #define DEBUG_SUBSYSTEM S_SM
27
28 #include <linux/fs.h>
29 #include <linux/jbd.h>
30 #include <linux/slab.h>
31 #include <linux/pagemap.h>
32 #include <linux/quotaops.h>
33 #include <linux/version.h>
34 #include <libcfs/kp30.h>
35 #include <linux/obd.h>
36 #include <linux/obd_class.h>
37
38 #include <linux/lustre_fsfilt.h>
39 #include <linux/lustre_smfs.h>
40 #include <linux/lustre_snap.h>
41
42 #include "smfs_internal.h"
43
44 static void *fsfilt_smfs_start(struct inode *inode, int op,
45                                void *desc_private, int logs)
46 {
47         void *handle;
48         struct inode *cache_inode = I2CI(inode);
49         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
50         int extra = 0;
51         int opcode = op;
52         
53         if (cache_fsfilt == NULL)
54                 return NULL;
55
56         if (!cache_fsfilt->fs_start)
57                 return ERR_PTR(-ENOSYS);
58         
59         //opcode can be changed here. 
60         //For example, unlink is rename in nature for undo plugin 
61         extra = SMFS_PLG_HELP(inode->i_sb, PLG_TRANS_SIZE, &opcode);
62
63         handle = cache_fsfilt->fs_start(cache_inode, op, desc_private,
64                                         logs + extra);
65
66         return handle;
67 }
68
69 static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
70                                    int niocount, struct niobuf_local *nb,
71                                    void *desc_private, int logs)
72 {
73         struct fsfilt_operations *cache_fsfilt;
74         struct dentry *cache_dentry = NULL;
75         struct inode *cache_inode = NULL;
76         struct fsfilt_objinfo cache_fso;
77         void   *rc = NULL;
78
79         ENTRY;
80         
81         cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
82         if (cache_fsfilt == NULL)
83                 RETURN(NULL);
84
85         cache_inode = I2CI(fso->fso_dentry->d_inode);
86         cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);
87         if (!cache_dentry)
88                 RETURN(ERR_PTR(-ENOMEM));
89         
90         cache_fso.fso_dentry = cache_dentry;
91         cache_fso.fso_bufcnt = fso->fso_bufcnt;
92
93         if (!cache_fsfilt->fs_brw_start) {
94                 rc =  ERR_PTR(-ENOSYS);
95                 goto exit;
96         }
97         
98         rc = cache_fsfilt->fs_brw_start(objcount, &cache_fso, niocount, nb,
99                                         desc_private, logs);
100 exit:
101         post_smfs_dentry(cache_dentry);
102         RETURN(rc);
103 }
104
105 /* FIXME-WANGDI: here we can easily have inode == NULL due to
106    mds_open() behavior. It passes NULL inode to mds_finish_transno()
107    sometimes. Probably we should have spare way to get cache fsfilt
108    operations. */
109 static int fsfilt_smfs_commit(struct super_block *sb, struct inode *inode, 
110                               void *h, int force_sync)
111 {
112         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
113         struct super_block *csb = S2CSB(sb); 
114         struct inode *cache_inode = NULL;
115         int    rc = -EIO;
116         
117         ENTRY;
118         
119         if (inode)
120                 cache_inode = I2CI(inode);
121
122         if (cache_fsfilt == NULL)
123                 RETURN(rc);
124
125         if (!cache_fsfilt->fs_commit)
126                 RETURN(-ENOSYS);
127
128         rc = cache_fsfilt->fs_commit(csb, cache_inode, h, force_sync);
129
130         RETURN(rc);
131 }
132
133 static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
134                                     void **wait_handle)
135 {
136         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
137         struct inode *cache_inode = NULL;
138         int    rc = -EIO;
139
140         cache_inode = I2CI(inode);
141         if (cache_fsfilt == NULL)
142                 RETURN(-EINVAL);
143
144         if (!cache_fsfilt->fs_commit_async)
145                 RETURN(-ENOSYS);
146
147         rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
148
149         RETURN(rc);
150 }
151
152 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
153 {
154         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
155         struct inode *cache_inode = NULL;
156         int    rc = -EIO;
157
158         cache_inode = I2CI(inode);
159         if (cache_fsfilt == NULL)
160                 RETURN(-EINVAL);
161
162         if (!cache_fsfilt->fs_commit_wait)
163                 RETURN(-ENOSYS);
164
165         rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
166
167         RETURN(rc);
168 }
169
170 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
171                                  unsigned int cmd, unsigned long arg)
172 {
173         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
174         struct inode *cache_inode = I2CI(inode);
175         struct smfs_file_info *sfi = NULL;
176         struct file * cache_file = NULL;
177         int    rc = -EIO;
178         ENTRY;
179
180         if (!cache_fsfilt || !cache_inode)
181                 RETURN(rc);
182
183         if (!cache_fsfilt->fs_iocontrol)
184                 RETURN(-ENOSYS);
185
186
187         if (file != NULL) {
188                 sfi = F2SMFI(file);
189                 if (sfi->magic != SMFS_FILE_MAGIC)
190                         BUG();
191                 cache_file = sfi->c_file;
192         }
193         
194         pre_smfs_inode(inode, cache_inode);
195         
196         rc = cache_fsfilt->fs_iocontrol(cache_inode, cache_file, cmd, arg);
197
198         post_smfs_inode(inode, cache_inode);
199
200         RETURN(rc);
201 }
202
203 static int fsfilt_smfs_send_bio(int rw, struct inode *inode, void *bio)
204 {
205         struct inode *cache_inode;
206         struct fsfilt_operations *cache_fsfilt;
207         
208         ENTRY;
209         
210         cache_fsfilt = I2FOPS(inode);
211         if (!cache_fsfilt)
212                 RETURN(-EINVAL);
213
214         cache_inode = I2CI(inode);
215         if (!cache_inode)
216                 RETURN(-EINVAL);
217
218         if (!cache_fsfilt->fs_send_bio)
219                 RETURN(-ENOSYS);
220
221         return cache_fsfilt->fs_send_bio(rw, cache_inode, bio);
222 }
223
224 static struct page * fsfilt_smfs_getpage(struct inode *inode, long int index)
225 {
226         struct  fsfilt_operations *cache_fsfilt;
227         struct  inode *cache_inode;
228         ENTRY;
229         cache_fsfilt = I2FOPS(inode);
230         if (!cache_fsfilt)
231                 RETURN(ERR_PTR(-EINVAL));
232
233         cache_inode = I2CI(inode);
234         if (!cache_inode)
235                 RETURN(ERR_PTR(-EINVAL));
236
237         if (!cache_fsfilt->fs_getpage)
238                 RETURN(ERR_PTR(-ENOSYS));
239 #if CONFIG_SNAPFS
240         if (SMFS_DO_COW(S2SMI(inode->i_sb))) {
241                 struct address_space_operations *aops = 
242                                 cache_inode->i_mapping->a_ops;
243                 if (aops->bmap(cache_inode->i_mapping, index)) {
244                         struct inode *ind_inode = NULL;
245                         struct inode *cache_ind = NULL;
246                         struct page  *page = NULL;
247                         
248                         ind_inode = smfs_cow_get_ind(inode, index);
249                         if (!ind_inode) {
250                                 RETURN(ERR_PTR(-EIO));
251                         }
252                         cache_ind = I2CI(ind_inode);
253                         /*FIXME cow inode should be bottom fs inode */         
254                         page = cache_fsfilt->fs_getpage(cache_ind, index);
255                         iput(ind_inode); 
256                         RETURN(page);
257                 } 
258         }
259 #endif
260         return cache_fsfilt->fs_getpage(cache_inode, index);
261 }
262
263 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
264                                     size_t count, loff_t *off)
265 {
266         struct fsfilt_operations *cache_fsfilt;
267         struct smfs_file_info *sfi;
268         struct inode *cache_inode;
269         loff_t tmp_ppos;
270         loff_t *cache_ppos;
271         ssize_t rc = -EIO;
272         struct hook_msg msg = {
273                 .dentry = file->f_dentry,
274         };
275
276         ENTRY;
277
278         cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
279         if (!cache_fsfilt)
280                 RETURN(rc);
281
282         cache_inode = I2CI(file->f_dentry->d_inode);
283         if (!cache_inode)
284                 RETURN(rc);
285
286         sfi = F2SMFI(file);
287         if (sfi->magic != SMFS_FILE_MAGIC)
288                 BUG();
289
290         if (off != &(file->f_pos))
291                 cache_ppos = &tmp_ppos;
292         else
293                 cache_ppos = &sfi->c_file->f_pos;
294         *cache_ppos = *off;
295
296         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
297         SMFS_PRE_HOOK(file->f_dentry->d_inode, HOOK_READDIR, &msg);
298
299 #if CONFIG_SNAPFS
300         /*readdir page*/
301         if (smfs_dotsnap_inode(file->f_dentry->d_inode)) {
302                 struct fsfilt_operations *snapops = 
303                                         I2SNAPOPS(file->f_dentry->d_inode);
304                 
305                 LASSERT(S_ISDIR(file->f_dentry->d_inode->i_mode));
306                 
307                 rc = snapops->fs_read_dotsnap_dir_page(sfi->c_file, buf, count, 
308                                                        cache_ppos); 
309         } else {
310                 if (cache_fsfilt->fs_readpage)
311                         rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
312                                                        cache_ppos);
313         }
314 #else
315         if (cache_fsfilt->fs_readpage)
316                 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf, count,
317                                                cache_ppos);
318
319 #endif
320         SMFS_POST_HOOK(file->f_dentry->d_inode, HOOK_READDIR, &msg, rc);
321         *off = *cache_ppos;
322         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
323         duplicate_file(file, sfi->c_file);
324
325         RETURN(rc);
326 }
327
328
329 static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
330                                       struct super_block *sb, __u64 last_rcvd,
331                                       void *handle, fsfilt_cb_t cb_func,
332                                       void *cb_data)
333 {
334         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
335         struct super_block *csb = S2CSB(sb);
336         int rc = -EIO;
337         
338         ENTRY;
339         
340         if (!cache_fsfilt)
341                  RETURN(rc);
342         if (cache_fsfilt->fs_add_journal_cb)
343                 rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
344                                                      handle, cb_func, cb_data);
345         RETURN(rc);
346 }
347
348 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
349 {
350         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
351         struct super_block *csb = S2CSB(sb);
352         int rc = -EIO;
353
354         ENTRY;
355         
356         if (!cache_fsfilt)
357                 RETURN(rc);
358
359         if (!cache_fsfilt->fs_statfs)
360                 RETURN(-ENOSYS);
361
362         rc = cache_fsfilt->fs_statfs(csb, osfs);
363         duplicate_sb(csb, sb);
364
365         RETURN(rc);
366 }
367
368 static int fsfilt_smfs_sync(struct super_block *sb)
369 {
370         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
371         struct super_block *csb = S2CSB(sb);
372         int    rc = -ENOSYS;
373
374         if (!cache_fsfilt)
375                 RETURN(-EINVAL);
376
377         if (cache_fsfilt->fs_sync)
378                 rc = cache_fsfilt->fs_sync(csb);
379
380         RETURN(rc);
381 }
382
383 int fsfilt_smfs_map_inode_pages(struct inode *inode, struct page **page,
384                                 int pages, unsigned long *blocks, int *created,
385                                 int create, struct semaphore *sem)
386 {
387         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
388         struct  inode *cache_inode = NULL;
389         int     rc = -EIO;
390         /*
391         struct hook_rw_msg  msg = {
392                 .write = create,
393         };
394         */
395         ENTRY;
396         
397         if (!cache_fsfilt)
398                 RETURN(-EINVAL);
399
400         cache_inode = I2CI(inode);
401
402         if (!cache_inode)
403                 RETURN(rc);
404
405         if (!cache_fsfilt->fs_map_inode_pages)
406                 RETURN(-ENOSYS);
407
408         down(&cache_inode->i_sem);
409         //SMFS_PRE_HOOK(inode, HOOK_MAP_PAGES, &msg);
410
411         rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
412                                               created, create, sem);
413
414         up(&cache_inode->i_sem);
415
416         RETURN(rc);
417 }
418
419 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
420                                       int nblocks, loff_t newsize)
421 {
422         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
423         struct  inode *cache_inode = NULL;
424         int     rc = -EIO;
425
426         if (!cache_fsfilt)
427                 RETURN(-EINVAL);
428
429         cache_inode = I2CI(inode);
430
431         if (!cache_inode)
432                 RETURN(-EINVAL);
433
434         if (!cache_fsfilt->fs_prep_san_write)
435                 RETURN(-ENOSYS);
436
437         down(&cache_inode->i_sem);
438         rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, nblocks,
439                                              newsize);
440         up(&cache_inode->i_sem);
441
442         RETURN(rc);
443 }
444
445 static int fsfilt_smfs_read_record(struct file * file, void *buf,
446                                    int size, loff_t *offs)
447 {
448         struct  fsfilt_operations *cache_fsfilt;
449         struct  inode *cache_inode;
450         struct  smfs_file_info *sfi;
451         loff_t  tmp_ppos;
452         loff_t  *cache_ppos;
453         ssize_t rc;
454
455         ENTRY;
456         cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
457         if (!cache_fsfilt)
458                 RETURN(-EINVAL);
459
460         cache_inode = I2CI(file->f_dentry->d_inode);
461
462         if (!cache_inode)
463                 RETURN(-EINVAL);
464
465         sfi = F2SMFI(file);
466         if (sfi->magic != SMFS_FILE_MAGIC) BUG();
467
468         if (offs != &(file->f_pos))
469                 cache_ppos = &tmp_ppos;
470         else
471                 cache_ppos = &sfi->c_file->f_pos;
472         *cache_ppos = *offs;
473
474         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
475
476         if (!cache_fsfilt->fs_read_record)
477                 RETURN(-ENOSYS);
478
479         rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, size, cache_ppos);
480
481         *offs = *cache_ppos;
482         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
483         duplicate_file(file, sfi->c_file);
484
485         RETURN(rc);
486 }
487
488 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
489                                     loff_t *offs, int force_sync)
490 {
491         struct  fsfilt_operations *cache_fsfilt;
492         struct  inode *cache_inode;
493         struct  smfs_file_info *sfi;
494         loff_t  tmp_ppos;
495         loff_t  *cache_ppos;
496         ssize_t rc = -EIO;
497
498         ENTRY;
499
500         cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
501         if (!cache_fsfilt)
502                 RETURN(-EINVAL);
503
504         cache_inode = I2CI(file->f_dentry->d_inode);
505
506         if (!cache_inode)
507                 RETURN(-EINVAL);
508
509         sfi = F2SMFI(file);
510         if (sfi->magic != SMFS_FILE_MAGIC)
511                 BUG();
512
513         if (offs != &(file->f_pos))
514                 cache_ppos = &tmp_ppos;
515         else
516                 cache_ppos = &sfi->c_file->f_pos;
517         *cache_ppos = *offs;
518
519         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
520
521         if (!cache_fsfilt->fs_write_record)
522                 RETURN(-ENOSYS);
523
524         rc = cache_fsfilt->fs_write_record(sfi->c_file, buf,
525                                            bufsize, cache_ppos, force_sync);
526         *offs = *cache_ppos;
527         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
528         duplicate_file(file, sfi->c_file);
529
530         RETURN(rc);
531 }
532
533 static int fsfilt_smfs_post_setup(struct obd_device *obd, struct vfsmount *mnt,
534                                   struct dentry *root_dentry)//, void *data)
535 {
536         struct super_block *sb = NULL;
537         int rc = 0;
538
539         ENTRY;
540         
541         if (mnt) {
542                 sb = mnt->mnt_sb;
543                 
544                 LASSERT(obd);
545                 S2SMI(sb)->smsi_exp = obd->obd_self_export;
546                
547                 rc = smfs_post_setup(obd, mnt, root_dentry);//, data);
548                 if (rc) {
549                         CERROR("post_setup fails in obd %p rc=%d", obd, rc);
550                 }
551         }
552         
553         RETURN(rc);
554 }
555
556 static int fsfilt_smfs_post_cleanup(struct obd_device *obd,
557                                     struct vfsmount *mnt)
558 {
559         struct super_block *sb = NULL;
560         int rc = 0;
561         ENTRY;
562         
563         if (mnt) {
564                 sb = mnt->mnt_sb;
565                 smfs_post_cleanup(sb);
566         }
567         
568         RETURN(rc);
569 }
570
571 static int fsfilt_smfs_set_fs_flags(struct inode *inode, int flags)
572 {
573         int rc = 0;
574         ENTRY;
575
576         if (flags & SM_ALL_PLG) /* enable all plugins */
577                 SMFS_SET(I2SMI(inode)->smi_flags, SMFS_PLG_ALL);
578 #if 0
579         if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
580                 SMFS_SET_INODE_COW(inode);
581 #endif
582         RETURN(rc);
583 }
584
585 static int fsfilt_smfs_clear_fs_flags(struct inode *inode, int flags)
586 {
587         int rc = 0;
588         ENTRY;
589         /*
590         if (SMFS_DO_REC(S2SMI(inode->i_sb)) && (flags & SM_DO_REC))
591                 SMFS_CLEAN_INODE_REC(inode);
592         if (SMFS_DO_COW(S2SMI(inode->i_sb)) && (flags & SM_DO_COW))
593                 SMFS_CLEAN_INODE_COW(inode);
594         */
595         if(flags & SM_ALL_PLG) /* disable all plugins */
596                 SMFS_CLEAR(I2SMI(inode)->smi_flags, SMFS_PLG_ALL);
597         RETURN(rc);
598 }
599
600 static int fsfilt_smfs_get_fs_flags(struct dentry *de)
601 {
602         struct inode *inode = de->d_inode;
603         int flags = 0;
604         ENTRY;
605
606         LASSERT(inode);
607         
608         flags = I2SMI(inode)->smi_flags & S2SMI(inode->i_sb)->plg_flags;
609        
610         RETURN(flags); 
611 }
612
613 static int fsfilt_smfs_set_ost_flags(struct super_block *sb)
614 {
615         return 0;
616 }
617
618 static int fsfilt_smfs_set_mds_flags(struct super_block *sb)
619 {
620         return 0;
621 }
622
623 #if 0
624 static int fsfilt_smfs_get_reint_log_ctxt(struct super_block *sb,
625                                           struct llog_ctxt **ctxt)
626 {
627         struct smfs_super_info *smfs_info = S2SMI(sb);
628         int rc = 0;
629
630         *ctxt = smfs_info->smsi_kml_log;
631         RETURN(rc);
632 }
633 #endif
634
635 static int fsfilt_smfs_setup(struct obd_device *obd, struct super_block *sb)
636 {
637         struct smfs_super_info *smfs_info = S2SMI(sb);
638         struct fsfilt_operations *cache_fsfilt;
639         struct super_block *csb;
640         int rc = 0;
641
642         ENTRY;
643         
644         /* It should be initialized olready by smfs_read_super(). */
645         if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
646                     cache_fsfilt = fsfilt_get_ops(smfs_info->smsi_cache_ftype);
647
648         if (!cache_fsfilt)
649                 RETURN(-ENOENT);
650
651         csb = S2CSB(sb);
652         if (cache_fsfilt->fs_setup) 
653                 rc = cache_fsfilt->fs_setup(obd, csb);
654         
655         duplicate_sb(sb, csb);
656         
657         RETURN(rc);
658 }
659
660 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
661                                struct iattr *iattr, int do_trunc)
662 {
663         struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
664         struct dentry *cache_dentry = NULL;
665         struct inode *cache_inode = I2CI(dentry->d_inode);
666         struct smfs_super_info *sbi = S2SMI(dentry->d_inode->i_sb);
667         struct hook_attr_msg msg = {
668                 .dentry = dentry,
669                 .attr = iattr
670         };
671         int    rc = -EIO;
672
673         if (!cache_fsfilt)
674                 RETURN(rc);
675
676         if (!cache_fsfilt->fs_setattr)
677                 RETURN(-ENOSYS);
678
679         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
680         if (!cache_dentry)
681                 RETURN(-ENOMEM);
682
683         pre_smfs_inode(dentry->d_inode, cache_inode);
684
685         SMFS_PRE_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg);
686         
687         if (SMFS_DO_HND_IBLOCKS(sbi)) {
688                 /* size-on-mds changes i_blocks directly to reflect
689                  * aggregated i_blocks from all OSTs -bzzz */
690                 cache_inode->i_blocks = dentry->d_inode->i_blocks;
691         }
692
693         rc = cache_fsfilt->fs_setattr(cache_dentry, handle, iattr, do_trunc);
694
695         SMFS_POST_HOOK(dentry->d_inode, HOOK_F_SETATTR, &msg, rc);
696         post_smfs_inode(dentry->d_inode, cache_inode);
697
698         post_smfs_dentry(cache_dentry);
699         RETURN(rc);
700 }
701 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle, char *name,
702                                  void *buffer, int buffer_size)
703 {
704         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
705         struct  inode *cache_inode = NULL;
706         struct hook_xattr_msg msg = {
707                 .name = name,
708                 .buffer = buffer,
709                 .buffer_size = buffer_size
710         };
711         int     rc = -EIO;
712         
713         ENTRY;
714         
715         if (!cache_fsfilt)
716                 RETURN(-EIO);
717
718         cache_inode = I2CI(inode);
719         if (!cache_inode)
720                 RETURN(rc);
721         
722         pre_smfs_inode(inode, cache_inode);
723         SMFS_PRE_HOOK(inode, HOOK_F_SETXATTR, &msg);
724         if (cache_fsfilt->fs_set_xattr)
725                 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name,
726                                                 buffer, buffer_size);
727          
728         SMFS_POST_HOOK(inode, HOOK_F_SETXATTR, &msg, rc);
729         post_smfs_inode(inode, cache_inode);
730
731         RETURN(rc);
732 }
733
734 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
735                                  void *buffer, int buffer_size)
736 {
737         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
738         struct inode *cache_inode = NULL;
739         int    rc = -EIO;
740
741         if (!cache_fsfilt)
742                 RETURN(rc);
743
744         cache_inode = I2CI(inode);
745         if (!cache_inode)
746                 RETURN(rc);
747
748         pre_smfs_inode(inode, cache_inode);
749         if (cache_fsfilt->fs_get_xattr)
750                 rc = cache_fsfilt->fs_get_xattr(cache_inode, name,
751                                                 buffer, buffer_size);
752         post_smfs_inode(inode, cache_inode);
753
754         RETURN(rc);
755 }
756
757 #define XATTR_LUSTRE_MDS_LOV_EA         "lov"
758 #define XATTR_LUSTRE_MDS_MEA_EA         "mea"
759 #define XATTR_LUSTRE_MDS_MID_EA         "mid"
760 #define XATTR_LUSTRE_MDS_SID_EA         "sid"
761 #define XATTR_LUSTRE_MDS_PID_EA         "pid"
762 #define XATTR_LUSTRE_MDS_KEY_EA         "key"
763
764 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
765                               void *lmm, int lmm_size, enum ea_type type)
766 {
767         int rc;
768         
769         switch(type) {
770         case EA_LOV:
771                 rc = fsfilt_smfs_set_xattr(inode, handle,
772                                            XATTR_LUSTRE_MDS_LOV_EA,
773                                            lmm, lmm_size);
774                 break;
775         case EA_MEA:
776                 rc = fsfilt_smfs_set_xattr(inode, handle,
777                                            XATTR_LUSTRE_MDS_MEA_EA,
778                                            lmm, lmm_size);
779                 break;
780         case EA_SID:
781                 rc = fsfilt_smfs_set_xattr(inode, handle,
782                                            XATTR_LUSTRE_MDS_SID_EA,
783                                            lmm, lmm_size);
784                 break;
785         case EA_MID:
786                 rc = fsfilt_smfs_set_xattr(inode, handle,
787                                            XATTR_LUSTRE_MDS_MID_EA,
788                                            lmm, lmm_size);
789                 break;
790         case EA_PID:
791                 rc = fsfilt_smfs_set_xattr(inode, handle,
792                                            XATTR_LUSTRE_MDS_PID_EA,
793                                            lmm, lmm_size);
794                 break;
795         case EA_KEY:
796                 rc = fsfilt_smfs_set_xattr(inode, handle,
797                                            XATTR_LUSTRE_MDS_KEY_EA,
798                                            lmm, lmm_size);
799                 break;
800         default:
801                 rc = -EINVAL;
802         }
803
804         return rc;
805 }
806
807 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm,
808                               int lmm_size, enum ea_type type)
809 {
810         int rc;
811         
812         switch (type) {
813         case EA_LOV:
814                 rc = fsfilt_smfs_get_xattr(inode,
815                                            XATTR_LUSTRE_MDS_LOV_EA,
816                                            lmm, lmm_size);
817                 break;
818         case EA_MEA:
819                 rc = fsfilt_smfs_get_xattr(inode,
820                                            XATTR_LUSTRE_MDS_MEA_EA,
821                                            lmm, lmm_size);
822                 break;
823         case EA_SID:
824                 rc = fsfilt_smfs_get_xattr(inode,
825                                            XATTR_LUSTRE_MDS_SID_EA,
826                                            lmm, lmm_size);
827                 break;
828         case EA_MID:
829                 rc = fsfilt_smfs_get_xattr(inode,
830                                            XATTR_LUSTRE_MDS_MID_EA,
831                                            lmm, lmm_size);
832                 break;
833         case EA_PID:
834                 rc = fsfilt_smfs_get_xattr(inode,
835                                            XATTR_LUSTRE_MDS_PID_EA,
836                                            lmm, lmm_size);
837                 break;
838         case EA_KEY:
839                 rc = fsfilt_smfs_get_xattr(inode,
840                                            XATTR_LUSTRE_MDS_KEY_EA,
841                                            lmm, lmm_size);
842                 break;
843         default:
844                 rc = -EINVAL;
845         }
846         
847         return rc;
848 }
849
850 static int fsfilt_smfs_insert_extents_ea(struct inode *inode,
851                                          unsigned long from, unsigned long num)
852 {
853         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
854         struct inode *cache_inode = NULL;
855         int    rc = -EIO;
856
857         if (!cache_fsfilt)
858                 RETURN(rc);
859
860         cache_inode = I2CI(inode);
861         if (!cache_inode)
862                 RETURN(rc);
863
864         pre_smfs_inode(inode, cache_inode);
865
866         if (cache_fsfilt->fs_insert_extents_ea)
867                 rc = cache_fsfilt->fs_insert_extents_ea(cache_inode, from, num);
868
869         post_smfs_inode(inode, cache_inode);
870         return rc;
871 }
872
873 static int fsfilt_smfs_remove_extents_ea(struct inode *inode,
874                                          unsigned long from, unsigned long num)
875 {
876         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
877         struct inode *cache_inode = NULL;
878         int    rc = -EIO;
879
880         if (!cache_fsfilt)
881                 RETURN(rc);
882
883         cache_inode = I2CI(inode);
884         if (!cache_inode)
885                 RETURN(rc);
886
887         pre_smfs_inode(inode, cache_inode);
888
889         if (cache_fsfilt->fs_remove_extents_ea)
890                 rc = cache_fsfilt->fs_remove_extents_ea(cache_inode, from, num);
891
892         post_smfs_inode(inode, cache_inode);
893         return rc;
894 }
895
896 static int fsfilt_smfs_init_extents_ea(struct inode *inode)
897 {
898         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
899         struct inode *cache_inode = NULL;
900         int    rc = -EIO;
901         ENTRY;
902
903         if (!cache_fsfilt)
904                 RETURN(rc);
905
906         cache_inode = I2CI(inode);
907         if (!cache_inode)
908                 RETURN(rc);
909
910         pre_smfs_inode(inode, cache_inode);
911
912         if (cache_fsfilt->fs_init_extents_ea)
913                 rc = cache_fsfilt->fs_init_extents_ea(cache_inode);
914
915         post_smfs_inode(inode, cache_inode);
916         return rc;
917 }
918
919 static int fsfilt_smfs_free_extents(struct super_block *sb, ino_t ino,
920                                     char *pbuf, int size)
921 {
922         OBD_FREE(pbuf, size * (sizeof(struct ldlm_extent)));
923         return 0;
924 }
925
926 static int fsfilt_smfs_write_extents(struct dentry *dentry,
927                                      unsigned long from, unsigned long num)
928 {
929         /* TODO: fix this later */
930 #if 0
931         int rc = 0;
932         struct inode * cache_inode = I2CI(dentry->d_inode);
933         struct hook_write_msg msg = {
934                 .dentry = dentry,
935                 .count = num,
936                 .pos = from
937         };
938
939         ENTRY;
940         
941         pre_smfs_inode(dentry->d_inode, cache_inode);
942  
943         SMFS_PRE_HOOK(dentry->d_inode, HOOK_WRITE, &msg);
944         
945         rc = smfs_write_extents(dentry->d_inode, dentry, from, num);
946         SMFS_POST_HOOK(dentry->d_inode, HOOK_WRITE, &msg, rc);
947         post_smfs_inode(dentry->d_inode, cache_inode);
948         
949         RETURN(rc);
950 #endif
951         ENTRY;
952         RETURN(0);
953 }
954
955 static int fsfilt_smfs_precreate_rec(struct dentry *dentry, int *count, 
956                                      struct obdo *oa)
957 {
958         int rc = 0;
959         /* Why to log precreate?? MDS will do this in any case
960         if (SMFS_DO_REC(S2SMI(dentry->d_inode->i_sb)))
961                 rc = smfs_rec_precreate(dentry, count, oa);
962         */
963         return rc;
964 }
965
966 // should be rewrote when needed
967 static int fsfilt_smfs_get_ino_write_extents(struct super_block *sb, ino_t ino,
968                                              char **pbuf, int *size)
969 {
970         int rc = 0;
971 #if 0
972         struct fs_extent *fs_extents;
973         struct ldlm_extent *extents = NULL;
974         struct inode *inode;
975         struct inode *cache_inode;
976         struct fsfilt_operations *cache_fsfilt = NULL;
977         struct lvfs_run_ctxt saved;
978         int    fs_ex_size, ex_num, flags;
979         char   *buf = NULL, *ex_buf = NULL;
980         ENTRY;
981
982         push_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
983
984         inode = iget(sb, ino);
985
986         if (!inode || is_bad_inode(inode)) {
987                 CWARN("Can not get inode %lu ino\n", ino);
988                 GOTO(out, rc = 0);
989         }
990         cache_inode = I2CI(inode);
991         cache_fsfilt = I2FOPS(inode);
992
993         rc = cache_fsfilt->fs_get_xattr(cache_inode, REINT_EXTENTS_FLAGS,
994                                         &flags, sizeof(int));
995         if (!(flags & SMFS_OVER_WRITE) && !(flags & SMFS_DIRTY_WRITE)) {
996                 GOTO(out, rc = 0);
997         } else if (flags & SMFS_OVER_WRITE) {
998                 *size = 1;
999                 OBD_ALLOC(ex_buf, sizeof(struct ldlm_extent));
1000                 if (!ex_buf)
1001                         GOTO(out, rc=-ENOMEM);
1002                 extents = (struct ldlm_extent*)(ex_buf);
1003                 extents->start = 0;
1004                 extents->end = 0xffffffff;
1005         }
1006         if (rc < 0)
1007                 GOTO(out, rc);
1008         rc = cache_fsfilt->fs_get_write_extents_num(cache_inode, &fs_ex_size);
1009         if (rc)
1010                 GOTO(out, rc);
1011         OBD_ALLOC(buf, fs_ex_size);
1012         if (!buf)
1013                 GOTO(out, rc=-ENOMEM);
1014
1015         rc = cache_fsfilt->fs_get_inode_write_extents(cache_inode, &buf,
1016                                                       &fs_ex_size);
1017         if (rc < 0)
1018                 GOTO(out, rc);
1019         rc = 0;
1020         ex_num = fs_ex_size / sizeof(struct fs_extent);
1021         *size =  ex_num;
1022         OBD_ALLOC(ex_buf, ex_num* sizeof(struct ldlm_extent));
1023         if (!ex_buf)
1024                 GOTO(out, rc=-ENOMEM);
1025
1026         fs_extents = (struct fs_extent*)(buf);
1027         extents = (struct ldlm_extent*)(ex_buf);
1028         while (ex_num > 0) {
1029                 int blk_size = I2CI(inode)->i_blksize;
1030
1031                 extents->start = fs_extents->e_block * blk_size;
1032                 extents->end = extents->start + fs_extents->e_num * blk_size;
1033                 fs_extents++;
1034                 extents++;
1035                 ex_num--;
1036         }
1037         *pbuf = ex_buf;
1038 out:
1039         iput(inode);
1040         if (buf)
1041                 OBD_FREE(buf, fs_ex_size);
1042         if (rc && extents)
1043                 OBD_FREE(ex_buf, (*size) * (sizeof(struct ldlm_extent)));
1044         pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL);
1045 #endif
1046         return rc;
1047 }
1048
1049 static int fsfilt_smfs_set_snap_item(struct super_block *sb, char *name)
1050 {
1051         int rc = 0;
1052
1053         ENTRY;
1054 #if CONFIG_SNAPFS
1055 #warning "still not implement for add snap item -wangdi"         
1056 #endif
1057         RETURN(rc);        
1058 }
1059 static int fsfilt_smfs_do_write_cow(struct dentry *de, void *extents,
1060                                     int num_extents)
1061 {
1062         int rc = 0;
1063 #if CONFIG_SNAPFS
1064         struct write_extents *w_ext = (struct write_extents *)extents;
1065         int i = 0;
1066         ENTRY;
1067         for (i = 0; i < num_extents; i++) {
1068                size_t count = w_ext->w_count;
1069                loff_t off = w_ext->w_pos;
1070                rc = smfs_cow_write_pre(de->d_inode, de, &count, &off);
1071                if (rc)
1072                         RETURN(rc);  
1073                w_ext ++;
1074         }
1075 #endif
1076         RETURN(rc);
1077 }
1078
1079 static int fsfilt_smfs_add_dir_entry(struct obd_device * obd,
1080                                      struct dentry * parent, char* name,
1081                                      int namelen, unsigned long ino,
1082                                      unsigned long generation,
1083                                      unsigned long mds,
1084                                      unsigned long fid) 
1085 {
1086         struct fsfilt_operations *cache_fsfilt = I2FOPS(parent->d_inode);
1087         struct dentry *cache_dentry = NULL, *dentry = NULL;
1088         struct inode *cache_parent = I2CI(parent->d_inode);
1089         int    rc = -EIO;
1090
1091         ENTRY;
1092         
1093         if (!cache_fsfilt)
1094                 RETURN(rc);
1095
1096         if (!cache_fsfilt->fs_add_dir_entry)
1097                 RETURN(-ENOSYS);
1098
1099         dentry = ll_lookup_one_len(name, parent, namelen);
1100         if (IS_ERR(dentry)) {
1101                 CERROR("can't lookup %*s in %lu/%lu: %d\n", namelen,
1102                        name, parent->d_inode->i_ino,
1103                        (unsigned long) parent->d_inode->i_generation,
1104                        (int) PTR_ERR(dentry));
1105                 RETURN(PTR_ERR(dentry));
1106         }
1107         if (dentry->d_inode != NULL || dentry->d_flags & DCACHE_CROSS_REF) {
1108                 CERROR("dentry %*s(0x%p) found\n", dentry->d_name.len,
1109                        dentry->d_name.name, dentry);
1110                 l_dput(dentry);
1111                 RETURN(-EEXIST);
1112         }
1113         /* mds_reint_rename() may use this method to add dir entry 
1114          * that points onto local inode. and we don't want to find
1115          * it cross-ref by subsequent lookups */
1116         d_drop(dentry);
1117
1118         dentry->d_flags |= DCACHE_CROSS_REF;
1119         dentry->d_inum = ino;
1120         dentry->d_mdsnum = mds;
1121         dentry->d_generation = generation;
1122         dentry->d_fid = fid;
1123         l_dput(dentry);
1124
1125         cache_dentry = pre_smfs_dentry(NULL, cache_parent, parent);
1126         if (!cache_dentry) {
1127                 RETURN(-ENOMEM);
1128         }
1129
1130         pre_smfs_inode(parent->d_inode, cache_parent);
1131         
1132         rc = cache_fsfilt->fs_add_dir_entry(obd, cache_dentry, name, namelen,
1133                                             ino, generation, mds, fid);
1134
1135         post_smfs_inode(parent->d_inode, cache_parent);
1136         
1137         post_smfs_dentry(cache_dentry);
1138         
1139         RETURN(rc);
1140         
1141 }
1142
1143 static int fsfilt_smfs_del_dir_entry(struct obd_device * obd,
1144                                      struct dentry * dentry) 
1145 {
1146         struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_parent->d_inode);
1147         struct dentry *cache_dentry = NULL, *cache_parent = NULL;
1148         struct inode * cache_dir = I2CI(dentry->d_parent->d_inode);
1149         struct inode * cache_inode = NULL;
1150         int    rc = -EIO;
1151
1152         ENTRY;
1153         
1154         if (!cache_fsfilt)
1155                 RETURN(rc);
1156
1157         if (!cache_fsfilt->fs_del_dir_entry)
1158                 RETURN(-ENOSYS);
1159
1160         if (dentry->d_inode)
1161                 cache_inode = I2CI(dentry->d_inode);
1162         
1163         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
1164         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
1165         if (!cache_parent || !cache_dentry) {
1166                 rc = (-ENOMEM);
1167                 goto exit;
1168         }
1169
1170         pre_smfs_inode(dentry->d_parent->d_inode, cache_dir);
1171         pre_smfs_inode(dentry->d_inode, cache_inode);
1172         
1173         rc = cache_fsfilt->fs_del_dir_entry(obd, cache_dentry);
1174
1175         if (!rc) {
1176                 d_drop(dentry);
1177                 if (cache_inode) {
1178                         post_smfs_inode(dentry->d_inode, cache_inode);
1179                         if (S_ISDIR(dentry->d_inode->i_mode))
1180                                 dentry->d_parent->d_inode->i_nlink--;
1181                 }
1182                 post_smfs_inode(dentry->d_parent->d_inode, cache_dir);                        
1183         }
1184 exit:
1185         post_smfs_dentry(cache_dentry);
1186         post_smfs_dentry(cache_parent);
1187         RETURN(rc);
1188         
1189 }
1190
1191 static int fsfilt_smfs_set_info (struct super_block *sb, struct inode * inode,
1192                                  __u32 keylen, void *key,
1193                                  __u32 valsize, void *val)
1194 {
1195         int rc = 0;
1196         struct plg_info_msg msg = {
1197                 .key = key,
1198                 .val = val,
1199         };       
1200         ENTRY;
1201         
1202         if (keylen >= 9 && memcmp(key, "file_read", 9) == 0) {
1203                 /* 
1204                  * this key used to inform smfs on OST about incoming r/w
1205                  */
1206                 struct lustre_id * id = val;
1207                 struct hook_rw_msg msg = {
1208                         .write = 0,
1209                         .id = id,
1210                 };
1211                 if (inode)
1212                         SMFS_POST_HOOK(inode, HOOK_SI_READ, &msg, rc);
1213         }
1214         else if (keylen >= 10 && memcmp(key, "file_write", 10) == 0) {
1215                 /* 
1216                  * this key used to inform smfs on OST about incoming r/w
1217                  */
1218                 struct lustre_id * id = val;
1219                 struct hook_rw_msg msg = {
1220                         .write = 1,
1221                         .id = id,
1222                 };
1223                 if (inode)
1224                         SMFS_POST_HOOK(inode, HOOK_SI_WRITE, &msg, rc);
1225         }
1226         else if (keylen >= 10 && memcmp(key, "audit_info", 10) == 0) {
1227                 /* this key used to pass audit data on MDS */
1228                 struct audit_info * info = val;
1229                                 
1230                 SMFS_POST_HOOK(inode, HOOK_SPECIAL, info, info->m.result);
1231         }
1232         else if (keylen >= 8 && memcmp(key, "auditlog", 8) == 0) {
1233                 /* 
1234                  * this key used to inform smfs on OST about client audit data
1235                  */
1236
1237                 audit_client_log(sb, val);
1238         }
1239         else if (keylen == 5 && memcmp(key, "audit", 5) == 0) {
1240                 smfs_set_audit(sb, inode, (__u64 *)val);
1241         }   
1242         else if (keylen == 7 && memcmp(key, "id2name", 7) == 0) {
1243                 rc = SMFS_PLG_HELP(sb, PLG_SET_INFO, &msg);
1244         }
1245         else
1246                 rc = -ENOENT;
1247                 
1248         RETURN(rc);
1249 }
1250
1251 static int fsfilt_smfs_get_info (struct super_block *sb, struct inode * inode,
1252                                  __u32 keylen, void *key,
1253                                  __u32 *valsize, void *val)
1254 {
1255         int rc = -ENOENT;
1256         
1257         ENTRY;
1258         
1259         if (keylen == 5 && strcmp(key, "audit") == 0) {
1260                 __u64 * mask = val;
1261                 rc = smfs_get_audit(sb, inode, NULL, mask);
1262         }
1263                         
1264         RETURN(rc);
1265 }
1266
1267 static struct fsfilt_operations fsfilt_smfs_ops = {
1268         .fs_type                = "smfs",
1269         .fs_owner               = THIS_MODULE,
1270         .fs_start               = fsfilt_smfs_start,
1271         .fs_brw_start           = fsfilt_smfs_brw_start,
1272         .fs_commit              = fsfilt_smfs_commit,
1273         .fs_commit_async        = fsfilt_smfs_commit_async,
1274         .fs_commit_wait         = fsfilt_smfs_commit_wait,
1275         .fs_setattr             = fsfilt_smfs_setattr,
1276         .fs_iocontrol           = fsfilt_smfs_iocontrol,
1277         .fs_set_md              = fsfilt_smfs_set_md,
1278         .fs_get_md              = fsfilt_smfs_get_md,
1279         .fs_readpage            = fsfilt_smfs_readpage,
1280         .fs_getpage             = fsfilt_smfs_getpage,
1281         .fs_add_journal_cb      = fsfilt_smfs_add_journal_cb,
1282         .fs_statfs              = fsfilt_smfs_statfs,
1283         .fs_sync                = fsfilt_smfs_sync,
1284         .fs_map_inode_pages     = fsfilt_smfs_map_inode_pages,
1285         .fs_prep_san_write      = fsfilt_smfs_prep_san_write,
1286         .fs_write_record        = fsfilt_smfs_write_record,
1287         .fs_read_record         = fsfilt_smfs_read_record,
1288         .fs_setup               = fsfilt_smfs_setup,
1289         .fs_send_bio            = fsfilt_smfs_send_bio,
1290         .fs_set_xattr           = fsfilt_smfs_set_xattr,
1291         .fs_get_xattr           = fsfilt_smfs_get_xattr,
1292         .fs_get_op_len          = NULL,
1293         .fs_del_dir_entry       = fsfilt_smfs_del_dir_entry,
1294         .fs_add_dir_entry       = fsfilt_smfs_add_dir_entry,
1295         .fs_insert_extents_ea   = fsfilt_smfs_insert_extents_ea,
1296         .fs_remove_extents_ea   = fsfilt_smfs_remove_extents_ea,
1297         .fs_init_extents_ea     = fsfilt_smfs_init_extents_ea,
1298         .fs_get_ino_write_extents = fsfilt_smfs_get_ino_write_extents,
1299         .fs_get_write_extents_num = NULL,
1300
1301         .fs_free_write_extents  = fsfilt_smfs_free_extents,
1302         .fs_write_extents       = fsfilt_smfs_write_extents,
1303         .fs_post_setup          = fsfilt_smfs_post_setup,
1304         .fs_post_cleanup        = fsfilt_smfs_post_cleanup,
1305         .fs_set_fs_flags        = fsfilt_smfs_set_fs_flags,
1306         .fs_clear_fs_flags      = fsfilt_smfs_clear_fs_flags,
1307         .fs_get_fs_flags        = fsfilt_smfs_get_fs_flags,
1308         .fs_set_ost_flags       = fsfilt_smfs_set_ost_flags,
1309         .fs_set_mds_flags       = fsfilt_smfs_set_mds_flags,
1310         .fs_precreate_rec       = fsfilt_smfs_precreate_rec,
1311         .fs_set_info            = fsfilt_smfs_set_info,
1312         .fs_get_info            = fsfilt_smfs_get_info,
1313         .fs_set_snap_item       = fsfilt_smfs_set_snap_item,
1314         .fs_do_write_cow        = fsfilt_smfs_do_write_cow,
1315 };
1316
1317 struct fsfilt_operations *get_smfs_fs_ops(void)
1318 {
1319         return (&fsfilt_smfs_ops);
1320 }
1321 EXPORT_SYMBOL(get_smfs_fs_ops);
1322
1323