Whamcloud - gitweb
land b_md onto HEAD. the highlights:
[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/extN_fs.h>
10 #include <linux/extN_jbd.h>
11 #include <linux/extN_xattr.h>
12 #include <linux/kp30.h>
13 #include <linux/lustre_fsfilt.h>
14
15 LIST_HEAD(fsfilt_types);
16
17 static struct fsfilt_operations *fsfilt_search_type(const char *type)
18 {
19         struct fsfilt_operations *found;
20         struct list_head *p;
21
22         list_for_each(p, &fsfilt_types) {
23                 found = list_entry(p, struct fsfilt_operations, fs_list);
24                 if (!strcmp(found->fs_type, type)) {
25                         return found;
26                 }
27         }
28         return NULL;
29 }
30
31 int fsfilt_register_ops(struct fsfilt_operations *fs_ops)
32 {
33         struct fsfilt_operations *found;
34
35         /* lock fsfilt_types list */
36         if ((found = fsfilt_search_type(fs_ops->fs_type))) {
37                 if (found != fs_ops) {
38                         CERROR("different operations for type %s\n",
39                                fs_ops->fs_type);
40                         /* unlock fsfilt_types list */
41                         RETURN(-EEXIST);
42                 }
43         } else {
44                 MOD_INC_USE_COUNT;
45                 list_add(&fs_ops->fs_list, &fsfilt_types);
46         }
47
48         /* unlock fsfilt_types list */
49         return 0;
50 }
51
52 void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops)
53 {
54         struct list_head *p;
55
56         /* lock fsfilt_types list */
57         list_for_each(p, &fsfilt_types) {
58                 struct fsfilt_operations *found;
59
60                 found = list_entry(p, typeof(*found), fs_list);
61                 if (found == fs_ops) {
62                         list_del(p);
63                         MOD_DEC_USE_COUNT;
64                         break;
65                 }
66         }
67         /* unlock fsfilt_types list */
68 }
69
70 struct fsfilt_operations *fsfilt_get_ops(char *type)
71 {
72         struct fsfilt_operations *fs_ops;
73
74         /* lock fsfilt_types list */
75         if (!(fs_ops = fsfilt_search_type(type))) {
76                 char name[32];
77                 int rc;
78
79                 snprintf(name, sizeof(name) - 1, "fsfilt_%s", type);
80                 name[sizeof(name) - 1] = '\0';
81
82                 if ((rc = request_module(name))) {
83                         fs_ops = fsfilt_search_type(type);
84                         CDEBUG(D_INFO, "Loaded module '%s'\n", name);
85                         if (!fs_ops)
86                                 rc = -ENOENT;
87                 }
88
89                 if (rc) {
90                         CERROR("Can't find fsfilt_%s interface\n", name);
91                         RETURN(ERR_PTR(rc));
92                         /* unlock fsfilt_types list */
93                 }
94         }
95         __MOD_INC_USE_COUNT(fs_ops->fs_owner);
96         /* unlock fsfilt_types list */
97
98         return fs_ops;
99 }
100
101 void fsfilt_put_ops(struct fsfilt_operations *fs_ops)
102 {
103         __MOD_DEC_USE_COUNT(fs_ops->fs_owner);
104 }
105
106
107 EXPORT_SYMBOL(fsfilt_register_ops);
108 EXPORT_SYMBOL(fsfilt_unregister_ops);
109 EXPORT_SYMBOL(fsfilt_get_ops);
110 EXPORT_SYMBOL(fsfilt_put_ops);