Whamcloud - gitweb
Land b_smallfix onto HEAD (20040512_1806)
[fs/lustre-release.git] / lustre / lvfs / fsfilt_smfs.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) 2002, 2003 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_FILTER
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 <linux/kp30.h>
35 #include <linux/lustre_fsfilt.h>
36 #include <linux/lustre_smfs.h>
37 #include <linux/obd.h>
38 #include <linux/obd_class.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41
42 static void *fsfilt_smfs_start(struct inode *inode, int op, 
43                                void *desc_private, int logs)
44 {
45         void *handle;
46         struct inode *cache_inode = I2CI(inode);
47         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
48
49         if (cache_fsfilt == NULL)
50                 return NULL;
51
52         if (!cache_fsfilt->fs_start)
53                 return ERR_PTR(-ENOSYS);
54                 
55         handle = cache_fsfilt->fs_start(cache_inode, op, 
56                                         desc_private, logs);
57         return handle;
58 }
59
60 static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
61                                    int niocount, struct niobuf_local *nb,
62                                    void *desc_private, int logs)
63 {
64         struct fsfilt_operations *cache_fsfilt;
65         struct dentry *cache_dentry = NULL;
66         struct inode *cache_inode = NULL;
67         struct fsfilt_objinfo cache_fso;
68         void   *rc = NULL;
69         
70         ENTRY; 
71         cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
72         if (cache_fsfilt == NULL) 
73                 return NULL;
74
75         cache_inode = I2CI(fso->fso_dentry->d_inode);
76         cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);     
77     
78         if (!cache_dentry)
79                 GOTO(exit, rc = ERR_PTR(-ENOMEM));
80     
81         cache_fso.fso_dentry = cache_dentry; 
82         cache_fso.fso_bufcnt = fso->fso_bufcnt;
83  
84         if (!cache_fsfilt->fs_brw_start)
85                 return ERR_PTR(-ENOSYS);
86                 
87         rc = (cache_fsfilt->fs_brw_start(objcount, &cache_fso, 
88                                          niocount, nb, desc_private,
89                                          logs));
90 exit:
91         post_smfs_dentry(cache_dentry); 
92         return rc; 
93 }
94
95 static int fsfilt_smfs_commit(struct inode *inode, void *h, 
96                               int force_sync)
97 {
98         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
99         struct inode *cache_inode = NULL;
100         int    rc = -EIO;      
101  
102         cache_inode = I2CI(inode);
103  
104         if (cache_fsfilt == NULL)
105                 RETURN(rc);
106        
107         if (!cache_fsfilt->fs_commit) 
108                 RETURN(-ENOSYS);
109         
110         rc = cache_fsfilt->fs_commit(cache_inode, h, force_sync);
111         
112         RETURN(rc);
113 }
114
115 static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
116                                     void **wait_handle)
117 {
118         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
119         struct inode *cache_inode = NULL;
120         int    rc = -EIO;      
121  
122         cache_inode = I2CI(inode);
123         if (cache_fsfilt == NULL)
124                 RETURN(-EINVAL);
125        
126         if (!cache_fsfilt->fs_commit_async)
127                 RETURN(-ENOSYS);
128                 
129         rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
130         
131         RETURN(rc);
132 }
133
134 static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
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_wait) 
145                 RETURN(-ENOSYS);
146         
147         rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
148         
149         RETURN(rc);
150 }
151
152 static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
153                                struct iattr *iattr, int do_trunc)
154 {
155         struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
156         struct dentry *cache_dentry = NULL;
157         struct inode *cache_inode = NULL;
158         int    rc = -EIO;
159  
160         if (!cache_fsfilt) 
161                 RETURN(rc);
162  
163         cache_inode = I2CI(dentry->d_inode); 
164        
165         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);      
166         if (!cache_dentry)
167                 GOTO(exit, rc = -ENOMEM);
168   
169         pre_smfs_inode(dentry->d_inode, cache_inode);
170         
171         if (!cache_fsfilt->fs_setattr)
172                 RETURN(-ENOSYS);
173                 
174         rc = cache_fsfilt->fs_setattr(cache_dentry, handle, 
175                                       iattr, do_trunc);
176         
177         post_smfs_inode(dentry->d_inode, cache_inode);
178        
179 exit:
180         post_smfs_dentry(cache_dentry);
181         RETURN(rc);                    
182 }
183
184 static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
185                                  unsigned int cmd, unsigned long arg)
186 {
187         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
188         struct inode *cache_inode = NULL;
189         struct smfs_file_info *sfi = NULL;
190         int    rc = -EIO;                                                                                                                                                                                                     
191         ENTRY;
192                                                                                                                                                                                                      
193         if (!cache_fsfilt) 
194                 RETURN(rc);
195         
196         cache_inode = I2CI(inode);
197        
198         if (!cache_inode)
199                 RETURN(rc);
200
201         if (file != NULL) {
202                 sfi = F2SMFI(file);
203                 
204                 if (sfi->magic != SMFS_FILE_MAGIC) 
205                         BUG();
206         } else {
207                 sfi = NULL;
208         }
209         
210         if (!cache_fsfilt->fs_iocontrol)
211                 RETURN(-ENOSYS);
212     
213         if (sfi) {
214                 rc = cache_fsfilt->fs_iocontrol(cache_inode,
215                                                 sfi->c_file, 
216                                                 cmd, arg);
217         } else {
218                 rc = cache_fsfilt->fs_iocontrol(cache_inode,
219                                                 NULL, cmd, arg);
220         }
221         
222         /* FIXME-UMKA: Should this be in duplicate_inode()? */
223         if (rc == 0 && cmd == EXT3_IOC_SETFLAGS)
224                 inode->i_flags = cache_inode->i_flags;
225                 
226         post_smfs_inode(inode, cache_inode); 
227
228         RETURN(rc);
229 }
230
231 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
232                               void *lmm, int lmm_size)
233 {
234         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
235         struct inode *cache_inode = NULL;
236         int    rc = -EIO;
237   
238         if (!cache_fsfilt) 
239                 RETURN(-EINVAL);
240         
241         cache_inode = I2CI(inode);
242        
243         if (!cache_inode)
244                 RETURN(-ENOENT);
245        
246         pre_smfs_inode(inode, cache_inode); 
247         
248         if (!cache_fsfilt->fs_set_md)
249                 RETURN(-ENOSYS);
250                 
251         down(&cache_inode->i_sem);
252                 
253         rc = cache_fsfilt->fs_set_md(cache_inode, handle,
254                                      lmm, lmm_size); 
255                                      
256         up(&cache_inode->i_sem);
257         
258         post_smfs_inode(inode, cache_inode); 
259         
260         RETURN(rc); 
261 }
262
263 /* Must be called with i_sem held */
264 static int fsfilt_smfs_get_md(struct inode *inode, void *lmm, int lmm_size)
265 {
266         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
267         struct inode *cache_inode = NULL;
268         int    rc = -EIO;
269   
270         if (!cache_fsfilt) 
271                 RETURN(-EINVAL);
272         
273         cache_inode = I2CI(inode);
274        
275         if (!cache_inode)
276                 RETURN(-ENOENT);
277        
278         pre_smfs_inode(inode, cache_inode); 
279         
280         if (!cache_fsfilt->fs_get_md)
281                 RETURN(-ENOSYS);
282                 
283         down(&cache_inode->i_sem);
284         
285         rc = cache_fsfilt->fs_get_md(cache_inode, lmm, 
286                                      lmm_size); 
287                                      
288         up(&cache_inode->i_sem);
289         
290         post_smfs_inode(inode, cache_inode); 
291        
292         RETURN(rc); 
293 }
294
295 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
296 static int fsfilt_smfs_send_bio(struct inode *inode, 
297                                 struct bio *bio)
298 #else
299 static int fsfilt_smfs_send_bio(struct inode *inode, 
300                                 struct kiobuf *bio)
301 #endif
302 {
303         struct inode *cache_inode;
304         struct fsfilt_operations *cache_fsfilt;
305         
306         cache_fsfilt = I2FOPS(inode);
307         if (!cache_fsfilt) 
308                 RETURN(-EINVAL);
309         
310         cache_inode = I2CI(inode);
311         if (!cache_inode)
312                 RETURN(-EINVAL);
313         
314         if (!cache_fsfilt->fs_send_bio)
315                 RETURN(-ENOSYS);
316                 
317         return cache_fsfilt->fs_send_bio(cache_inode, bio);
318 }
319
320 static struct page *
321 fsfilt_smfs_getpage(struct inode *inode, long int index)
322 {
323         struct  fsfilt_operations *cache_fsfilt;
324         struct  inode *cache_inode;
325
326         cache_fsfilt = I2FOPS(inode);
327         if (!cache_fsfilt) 
328                 RETURN(ERR_PTR(-EINVAL));
329         
330         cache_inode = I2CI(inode);
331         if (!cache_inode)
332                 RETURN(ERR_PTR(-EINVAL));
333         
334         if (!cache_fsfilt->fs_getpage)
335                 RETURN(ERR_PTR(-ENOSYS));
336         
337         return cache_fsfilt->fs_getpage(cache_inode, index);
338 }
339
340 static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
341                                     size_t count, loff_t *off)
342 {
343         struct fsfilt_operations *cache_fsfilt;
344         struct smfs_file_info *sfi; 
345         struct inode *cache_inode;
346         loff_t tmp_ppos;
347         loff_t *cache_ppos;
348         ssize_t rc = -EIO;
349
350         ENTRY;
351
352         cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
353         if (!cache_fsfilt) 
354                 RETURN(rc);
355         
356         cache_inode = I2CI(file->f_dentry->d_inode);
357         if (!cache_inode)
358                 RETURN(rc);
359
360         sfi = F2SMFI(file);
361         if (sfi->magic != SMFS_FILE_MAGIC)
362                 BUG();
363         
364         if (off != &(file->f_pos)) {
365                 cache_ppos = &tmp_ppos;
366         } else {
367                 cache_ppos = &sfi->c_file->f_pos;
368         }
369         *cache_ppos = *off;
370         
371         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
372         
373         if (cache_fsfilt->fs_readpage) 
374                 rc = cache_fsfilt->fs_readpage(sfi->c_file, buf,
375                                                count, cache_ppos);
376         
377         *off = *cache_ppos;
378         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
379         duplicate_file(file, sfi->c_file);
380         
381         RETURN(rc);
382 }
383
384 static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
385                                       struct super_block *sb,
386                                       __u64 last_rcvd, void *handle,
387                                       fsfilt_cb_t cb_func,
388                                       void *cb_data)
389 {
390         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
391         struct super_block *csb = S2CSB(sb);
392         int rc = -EIO;
393
394         if (!cache_fsfilt) 
395                  RETURN(rc);
396         if (cache_fsfilt->fs_add_journal_cb)
397                 rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
398                                                      handle, cb_func, cb_data);
399         RETURN(rc);
400 }
401
402 static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
403 {
404         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
405         struct super_block *csb = S2CSB(sb);
406         int rc = -EIO;
407
408         if (!cache_fsfilt)
409                 RETURN(rc);
410         
411         if (!cache_fsfilt->fs_statfs)
412                 RETURN(-ENOSYS);
413                 
414         rc = cache_fsfilt->fs_statfs(csb, osfs);
415         duplicate_sb(csb, sb);
416         
417         RETURN(rc);
418 }
419
420 static int fsfilt_smfs_sync(struct super_block *sb)
421 {
422         struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
423         struct super_block *csb = S2CSB(sb);
424         int    rc = -EIO;
425  
426         if(!cache_fsfilt)
427                 RETURN(-EINVAL);
428         
429         if (!cache_fsfilt->fs_sync)
430                 RETURN(-ENOSYS);
431         
432         rc = cache_fsfilt->fs_sync(csb);
433         
434         RETURN(rc); 
435 }
436
437 int fsfilt_smfs_map_inode_pages(struct inode *inode, struct page **page,
438                                 int pages, unsigned long *blocks, 
439                                 int *created, int create,
440                                 struct semaphore *sem)
441 {
442         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
443         struct  inode *cache_inode = NULL;
444         int     rc = -EIO;
445          
446         if (!cache_fsfilt)
447                 RETURN(-EINVAL);
448         
449         cache_inode = I2CI(inode);
450        
451         if (!cache_inode)
452                 RETURN(rc);
453
454         if (!cache_fsfilt->fs_map_inode_pages) 
455                 RETURN(-ENOSYS);
456         
457         down(&cache_inode->i_sem);
458         rc = cache_fsfilt->fs_map_inode_pages(cache_inode, page, pages, blocks,
459                                               created, create, NULL);
460         up(&cache_inode->i_sem);
461         
462         RETURN(rc);
463 }
464
465 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
466                                       int nblocks, loff_t newsize)
467 {
468         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
469         struct  inode *cache_inode = NULL;
470         int     rc = -EIO;
471          
472         if (!cache_fsfilt)
473                 RETURN(-EINVAL);
474         
475         cache_inode = I2CI(inode);
476        
477         if (!cache_inode)
478                 RETURN(-EINVAL);
479
480         if (!cache_fsfilt->fs_prep_san_write)
481                 RETURN(-ENOSYS);
482         
483         down(&cache_inode->i_sem);
484         rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, 
485                                              nblocks, newsize);
486         up(&cache_inode->i_sem);
487         
488         RETURN(rc);
489 }
490
491 static int fsfilt_smfs_read_record(struct file * file, void *buf,
492                                    int size, loff_t *offs)
493 {
494         struct  fsfilt_operations *cache_fsfilt;
495         struct  inode *cache_inode;
496         struct  smfs_file_info *sfi; 
497         loff_t  tmp_ppos;
498         loff_t  *cache_ppos;
499         ssize_t rc;
500         
501         ENTRY;
502         cache_fsfilt = I2FOPS(file->f_dentry->d_inode); 
503         if (!cache_fsfilt) 
504                 RETURN(-EINVAL);
505         
506         cache_inode = I2CI(file->f_dentry->d_inode);
507         
508         if (!cache_inode)
509                 RETURN(-EINVAL);
510
511         sfi = F2SMFI(file);
512         if (sfi->magic != SMFS_FILE_MAGIC) BUG();
513         
514         if (offs != &(file->f_pos)) {
515                 cache_ppos = &tmp_ppos;
516         } else {
517                 cache_ppos = &sfi->c_file->f_pos;
518         }
519         *cache_ppos = *offs;
520
521         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
522
523         if (!cache_fsfilt->fs_read_record)
524                 RETURN(-ENOSYS);
525                 
526         rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, 
527                                           size, cache_ppos);
528         
529         *offs = *cache_ppos;
530         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
531         duplicate_file(file, sfi->c_file); 
532         
533         RETURN(rc);
534 }
535
536 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
537                                     loff_t *offs, int force_sync)
538 {
539         struct  fsfilt_operations *cache_fsfilt;
540         struct  inode *cache_inode;
541         struct  smfs_file_info *sfi; 
542         loff_t  tmp_ppos;
543         loff_t  *cache_ppos;
544         ssize_t rc = -EIO;
545
546         ENTRY;
547
548         cache_fsfilt = I2FOPS(file->f_dentry->d_inode); 
549         if (!cache_fsfilt) 
550                 RETURN(-EINVAL);
551         
552         cache_inode = I2CI(file->f_dentry->d_inode);
553         
554         if (!cache_inode)
555                 RETURN(-EINVAL);
556
557         sfi = F2SMFI(file);
558         if (sfi->magic != SMFS_FILE_MAGIC) BUG();
559         
560         if (offs != &(file->f_pos)) {
561                 cache_ppos = &tmp_ppos;
562         } else {
563                 cache_ppos = &sfi->c_file->f_pos;
564         }
565         *cache_ppos = *offs;
566        
567         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
568         
569         if (!cache_fsfilt->fs_write_record)
570                 RETURN(-ENOSYS);
571         
572         rc = cache_fsfilt->fs_write_record(sfi->c_file, buf, 
573                                            bufsize, cache_ppos, force_sync);
574         *offs = *cache_ppos; 
575         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
576         duplicate_file(file, sfi->c_file); 
577         
578         RETURN(rc);
579 }
580
581 static int fsfilt_smfs_setup(struct super_block *sb)
582 {
583         struct smfs_super_info *smfs_info = S2SMI(sb);
584         struct fsfilt_operations *cache_fsfilt;
585         struct super_block *csb;
586         int rc = 0;
587
588         /* It should be initialized olready by smfs_read_super(). */
589         if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
590                 cache_fsfilt = fsfilt_get_ops(smfs_info->cache_fs_type);
591
592         if (!cache_fsfilt)
593                 RETURN(-ENOENT);
594         
595         csb = S2CSB(sb);
596
597         if (cache_fsfilt->fs_setup) 
598                 rc = cache_fsfilt->fs_setup(csb);
599         
600         RETURN(rc);
601 }
602
603 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle,
604                                  char *name,  void *buffer, 
605                                  int buffer_size)
606 {
607         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
608         struct  inode *cache_inode = NULL;
609         int     rc = -EIO;
610          
611         if (!cache_fsfilt)
612                 RETURN(rc);
613         
614         cache_inode = I2CI(inode);
615         if (!cache_inode)
616                 RETURN(rc);
617         
618         pre_smfs_inode(inode, cache_inode); 
619        
620         if (cache_fsfilt->fs_set_xattr) 
621                 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name, 
622                                                 buffer, buffer_size);
623         post_smfs_inode(inode, cache_inode); 
624         
625         RETURN(rc);
626 }
627
628 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
629                                  void *buffer, int buffer_size)
630 {
631         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
632         struct inode *cache_inode = NULL;
633         int    rc = -EIO;
634
635          if (!cache_fsfilt)
636                 RETURN(rc);
637         
638         cache_inode = I2CI(inode);
639         if (!cache_inode)
640                 RETURN(rc);
641         
642         pre_smfs_inode(inode, cache_inode); 
643        
644         if (cache_fsfilt->fs_get_xattr) 
645                 rc = cache_fsfilt->fs_get_xattr(cache_inode, name, 
646                                                 buffer, buffer_size);
647         post_smfs_inode(inode, cache_inode); 
648         
649         RETURN(rc);
650 }
651
652 static struct fsfilt_operations fsfilt_smfs_ops = {
653         .fs_type                = "smfs",
654         .fs_owner               = THIS_MODULE,
655         .fs_start               = fsfilt_smfs_start,
656         .fs_brw_start           = fsfilt_smfs_brw_start,
657         .fs_commit              = fsfilt_smfs_commit,
658         .fs_commit_async        = fsfilt_smfs_commit_async,
659         .fs_commit_wait         = fsfilt_smfs_commit_wait,
660         .fs_setattr             = fsfilt_smfs_setattr,
661         .fs_iocontrol           = fsfilt_smfs_iocontrol,
662         .fs_set_md              = fsfilt_smfs_set_md,
663         .fs_get_md              = fsfilt_smfs_get_md,
664         .fs_readpage            = fsfilt_smfs_readpage,
665         .fs_getpage             = fsfilt_smfs_getpage,
666         .fs_add_journal_cb      = fsfilt_smfs_add_journal_cb,
667         .fs_statfs              = fsfilt_smfs_statfs,
668         .fs_sync                = fsfilt_smfs_sync,
669         .fs_map_inode_pages     = fsfilt_smfs_map_inode_pages,
670         .fs_prep_san_write      = fsfilt_smfs_prep_san_write,
671         .fs_write_record        = fsfilt_smfs_write_record,
672         .fs_read_record         = fsfilt_smfs_read_record,
673         .fs_setup               = fsfilt_smfs_setup,
674         .fs_send_bio            = fsfilt_smfs_send_bio,
675         .fs_set_xattr           = fsfilt_smfs_set_xattr,
676         .fs_get_xattr           = fsfilt_smfs_get_xattr,
677         
678         /* FIXME-UMKA: probably fsfilt_smfs_get_op_len() should be put here
679          * too. */
680 };
681
682 static int __init fsfilt_smfs_init(void)
683 {
684         int rc;
685         
686         rc = fsfilt_register_ops(&fsfilt_smfs_ops);
687         return rc;
688 }
689
690 static void __exit fsfilt_smfs_exit(void)
691 {
692         fsfilt_unregister_ops(&fsfilt_smfs_ops);
693 }
694
695 module_init(fsfilt_smfs_init);
696 module_exit(fsfilt_smfs_exit);
697
698 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
699 MODULE_DESCRIPTION("Lustre SMFS Filesystem Helper v0.1");
700 MODULE_LICENSE("GPL");