Whamcloud - gitweb
- merge 0.7rc1 from b_devel to HEAD (20030612 merge point)
[fs/lustre-release.git] / lustre / obdclass / fsfilt.c
1 #define EXPORT_SYMTAB
2 #define DEBUG_SUBSYSTEM S_FILTER
3
4 #include <linux/fs.h>
5 #include <linux/jbd.h>
6 #include <linux/module.h>
7 #include <linux/kmod.h>
8 #include <linux/slab.h>
9 #include <linux/kp30.h>
10 #include <linux/lustre_fsfilt.h>
11
12 LIST_HEAD(fsfilt_types);
13
14 static struct fsfilt_operations *fsfilt_search_type(const char *type)
15 {
16         struct fsfilt_operations *found;
17         struct list_head *p;
18
19         list_for_each(p, &fsfilt_types) {
20                 found = list_entry(p, struct fsfilt_operations, fs_list);
21                 if (!strcmp(found->fs_type, type)) {
22                         return found;
23                 }
24         }
25         return NULL;
26 }
27
28 int fsfilt_register_ops(struct fsfilt_operations *fs_ops)
29 {
30         struct fsfilt_operations *found;
31
32         /* lock fsfilt_types list */
33         if ((found = fsfilt_search_type(fs_ops->fs_type))) {
34                 if (found != fs_ops) {
35                         CERROR("different operations for type %s\n",
36                                fs_ops->fs_type);
37                         /* unlock fsfilt_types list */
38                         RETURN(-EEXIST);
39                 }
40         } else {
41                 PORTAL_MODULE_USE;
42                 list_add(&fs_ops->fs_list, &fsfilt_types);
43         }
44
45         /* unlock fsfilt_types list */
46         return 0;
47 }
48
49 void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops)
50 {
51         struct list_head *p;
52
53         /* lock fsfilt_types list */
54         list_for_each(p, &fsfilt_types) {
55                 struct fsfilt_operations *found;
56
57                 found = list_entry(p, typeof(*found), fs_list);
58                 if (found == fs_ops) {
59                         list_del(p);
60                         PORTAL_MODULE_UNUSE;
61                         break;
62                 }
63         }
64         /* unlock fsfilt_types list */
65 }
66
67 struct fsfilt_operations *fsfilt_get_ops(char *type)
68 {
69         struct fsfilt_operations *fs_ops;
70
71         /* lock fsfilt_types list */
72         if (!(fs_ops = fsfilt_search_type(type))) {
73                 char name[32];
74                 int rc;
75
76                 snprintf(name, sizeof(name) - 1, "fsfilt_%s", type);
77                 name[sizeof(name) - 1] = '\0';
78
79                 if ((rc = request_module(name))) {
80                         fs_ops = fsfilt_search_type(type);
81                         CDEBUG(D_INFO, "Loaded module '%s'\n", name);
82                         if (!fs_ops)
83                                 rc = -ENOENT;
84                 }
85
86                 if (rc) {
87                         CERROR("Can't find fsfilt_%s interface\n", name);
88                         RETURN(ERR_PTR(rc));
89                         /* unlock fsfilt_types list */
90                 }
91         }
92         __MOD_INC_USE_COUNT(fs_ops->fs_owner);
93         /* unlock fsfilt_types list */
94
95         return fs_ops;
96 }
97
98 void fsfilt_put_ops(struct fsfilt_operations *fs_ops)
99 {
100         __MOD_DEC_USE_COUNT(fs_ops->fs_owner);
101 }
102
103
104 EXPORT_SYMBOL(fsfilt_register_ops);
105 EXPORT_SYMBOL(fsfilt_unregister_ops);
106 EXPORT_SYMBOL(fsfilt_get_ops);
107 EXPORT_SYMBOL(fsfilt_put_ops);