Whamcloud - gitweb
minor fix for build on amd64.
[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_page(struct inode *inode, struct page *page,
438                                unsigned long *blocks, int *created, int create)
439 {
440         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
441         struct  inode *cache_inode = NULL;
442         int     rc = -EIO;
443          
444         if (!cache_fsfilt)
445                 RETURN(-EINVAL);
446         
447         cache_inode = I2CI(inode);
448        
449         if (!cache_inode)
450                 RETURN(rc);
451
452         if (!cache_fsfilt->fs_map_inode_page) 
453                 RETURN(-ENOSYS);
454         
455         down(&cache_inode->i_sem);
456         rc = cache_fsfilt->fs_map_inode_page(cache_inode, page, 
457                                              blocks, created, create);
458         up(&cache_inode->i_sem);
459         
460         RETURN(rc);
461 }
462
463 static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
464                                       int nblocks, loff_t newsize)
465 {
466         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
467         struct  inode *cache_inode = NULL;
468         int     rc = -EIO;
469          
470         if (!cache_fsfilt)
471                 RETURN(-EINVAL);
472         
473         cache_inode = I2CI(inode);
474        
475         if (!cache_inode)
476                 RETURN(-EINVAL);
477
478         if (!cache_fsfilt->fs_prep_san_write)
479                 RETURN(-ENOSYS);
480         
481         down(&cache_inode->i_sem);
482         rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, 
483                                              nblocks, newsize);
484         up(&cache_inode->i_sem);
485         
486         RETURN(rc);
487 }
488
489 static int fsfilt_smfs_read_record(struct file * file, void *buf,
490                                    int size, loff_t *offs)
491 {
492         struct  fsfilt_operations *cache_fsfilt;
493         struct  inode *cache_inode;
494         struct  smfs_file_info *sfi; 
495         loff_t  tmp_ppos;
496         loff_t  *cache_ppos;
497         ssize_t rc;
498         
499         ENTRY;
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) BUG();
511         
512         if (offs != &(file->f_pos)) {
513                 cache_ppos = &tmp_ppos;
514         } else {
515                 cache_ppos = &sfi->c_file->f_pos;
516         }
517         *cache_ppos = *offs;
518
519         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
520
521         if (!cache_fsfilt->fs_read_record)
522                 RETURN(-ENOSYS);
523                 
524         rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, 
525                                           size, cache_ppos);
526         
527         *offs = *cache_ppos;
528         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
529         duplicate_file(file, sfi->c_file); 
530         
531         RETURN(rc);
532 }
533
534 static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
535                                     loff_t *offs, int force_sync)
536 {
537         struct  fsfilt_operations *cache_fsfilt;
538         struct  inode *cache_inode;
539         struct  smfs_file_info *sfi; 
540         loff_t  tmp_ppos;
541         loff_t  *cache_ppos;
542         ssize_t rc = -EIO;
543
544         ENTRY;
545
546         cache_fsfilt = I2FOPS(file->f_dentry->d_inode); 
547         if (!cache_fsfilt) 
548                 RETURN(-EINVAL);
549         
550         cache_inode = I2CI(file->f_dentry->d_inode);
551         
552         if (!cache_inode)
553                 RETURN(-EINVAL);
554
555         sfi = F2SMFI(file);
556         if (sfi->magic != SMFS_FILE_MAGIC) BUG();
557         
558         if (offs != &(file->f_pos)) {
559                 cache_ppos = &tmp_ppos;
560         } else {
561                 cache_ppos = &sfi->c_file->f_pos;
562         }
563         *cache_ppos = *offs;
564        
565         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
566         
567         if (!cache_fsfilt->fs_write_record)
568                 RETURN(-ENOSYS);
569         
570         rc = cache_fsfilt->fs_write_record(sfi->c_file, buf, 
571                                            bufsize, cache_ppos, force_sync);
572         *offs = *cache_ppos; 
573         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
574         duplicate_file(file, sfi->c_file); 
575         
576         RETURN(rc);
577 }
578
579 static int fsfilt_smfs_setup(struct super_block *sb)
580 {
581         struct smfs_super_info *smfs_info = S2SMI(sb);
582         struct fsfilt_operations *cache_fsfilt;
583         struct super_block *csb;
584         int rc = 0;
585
586         /* It should be initialized olready by smfs_read_super(). */
587         if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
588                 cache_fsfilt = fsfilt_get_ops(smfs_info->cache_fs_type);
589
590         if (!cache_fsfilt)
591                 RETURN(-ENOENT);
592         
593         csb = S2CSB(sb);
594
595         if (cache_fsfilt->fs_setup) 
596                 rc = cache_fsfilt->fs_setup(csb);
597         
598         RETURN(rc);
599 }
600
601 static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle,
602                                  char *name,  void *buffer, 
603                                  int buffer_size)
604 {
605         struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
606         struct  inode *cache_inode = NULL;
607         int     rc = -EIO;
608          
609         if (!cache_fsfilt)
610                 RETURN(rc);
611         
612         cache_inode = I2CI(inode);
613         if (!cache_inode)
614                 RETURN(rc);
615         
616         pre_smfs_inode(inode, cache_inode); 
617        
618         if (cache_fsfilt->fs_set_xattr) 
619                 rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name, 
620                                                 buffer, buffer_size);
621         post_smfs_inode(inode, cache_inode); 
622         
623         RETURN(rc);
624 }
625
626 static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
627                                  void *buffer, int buffer_size)
628 {
629         struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
630         struct inode *cache_inode = NULL;
631         int    rc = -EIO;
632
633          if (!cache_fsfilt)
634                 RETURN(rc);
635         
636         cache_inode = I2CI(inode);
637         if (!cache_inode)
638                 RETURN(rc);
639         
640         pre_smfs_inode(inode, cache_inode); 
641        
642         if (cache_fsfilt->fs_get_xattr) 
643                 rc = cache_fsfilt->fs_get_xattr(cache_inode, name, 
644                                                 buffer, buffer_size);
645         post_smfs_inode(inode, cache_inode); 
646         
647         RETURN(rc);
648 }
649
650 static struct fsfilt_operations fsfilt_smfs_ops = {
651         .fs_type                = "smfs",
652         .fs_owner               = THIS_MODULE,
653         .fs_start               = fsfilt_smfs_start,
654         .fs_brw_start           = fsfilt_smfs_brw_start,
655         .fs_commit              = fsfilt_smfs_commit,
656         .fs_commit_async        = fsfilt_smfs_commit_async,
657         .fs_commit_wait         = fsfilt_smfs_commit_wait,
658         .fs_setattr             = fsfilt_smfs_setattr,
659         .fs_iocontrol           = fsfilt_smfs_iocontrol,
660         .fs_set_md              = fsfilt_smfs_set_md,
661         .fs_get_md              = fsfilt_smfs_get_md,
662         .fs_readpage            = fsfilt_smfs_readpage,
663         .fs_getpage             = fsfilt_smfs_getpage,
664         .fs_add_journal_cb      = fsfilt_smfs_add_journal_cb,
665         .fs_statfs              = fsfilt_smfs_statfs,
666         .fs_sync                = fsfilt_smfs_sync,
667         .fs_map_inode_page      = fsfilt_smfs_map_inode_page,
668         .fs_prep_san_write      = fsfilt_smfs_prep_san_write,
669         .fs_write_record        = fsfilt_smfs_write_record,
670         .fs_read_record         = fsfilt_smfs_read_record,
671         .fs_setup               = fsfilt_smfs_setup,
672         .fs_send_bio            = fsfilt_smfs_send_bio,
673         .fs_set_xattr           = fsfilt_smfs_set_xattr,
674         .fs_get_xattr           = fsfilt_smfs_get_xattr,
675         
676         /* FIXME-UMKA: probably fsfilt_smfs_get_op_len() should be put here
677          * too. */
678 };
679
680 static int __init fsfilt_smfs_init(void)
681 {
682         int rc;
683         
684         rc = fsfilt_register_ops(&fsfilt_smfs_ops);
685         return rc;
686 }
687
688 static void __exit fsfilt_smfs_exit(void)
689 {
690         fsfilt_unregister_ops(&fsfilt_smfs_ops);
691 }
692
693 module_init(fsfilt_smfs_init);
694 module_exit(fsfilt_smfs_exit);
695
696 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
697 MODULE_DESCRIPTION("Lustre SMFS Filesystem Helper v0.1");
698 MODULE_LICENSE("GPL");