Whamcloud - gitweb
7d61a0696623fb9791f1f424fa66f53223d3344b
[fs/lustre-release.git] / lustre / obdfs / super.c
1 /*
2  * OBDFS Super operations
3  *
4  * Copryright (C) 1996 Peter J. Braam <braam@stelias.com>
5  */
6
7 #define EXPORT_SYMTAB
8
9 #include <linux/config.h>
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/mm.h>
13 #include <linux/string.h>
14 #include <linux/stat.h>
15 #include <linux/errno.h>
16 #include <linux/locks.h>
17 #include <linux/unistd.h>
18
19 #include <asm/system.h>
20 #include <asm/uaccess.h>
21
22 #include <linux/fs.h>
23 #include <linux/stat.h>
24 #include <asm/uaccess.h>
25 #include <linux/vmalloc.h>
26 #include <asm/segment.h>
27
28 #include <../obd/linux/sym_obd.h>
29 #include <obdfs.h>
30
31 /* DEBUGGING! */
32 #undef MOD_INC_USE_COUNT
33 #define MOD_INC_USE_COUNT
34 #undef MOD_DEC_USE_COUNT
35 #define MOD_DEC_USE_COUNT
36
37 /* VFS super_block ops */
38 static struct super_block *obdfs_read_super(struct super_block *, void *, int);
39 static void obdfs_read_inode(struct inode *);
40 static int  obdfs_notify_change(struct dentry *dentry, struct iattr *attr);
41 static void obdfs_write_inode(struct inode *);
42 static void obdfs_delete_inode(struct inode *);
43 static void obdfs_put_super(struct super_block *);
44 static int obdfs_statfs(struct super_block *sb, struct statfs *buf, 
45                        int bufsiz);
46
47 /* exported operations */
48 struct super_operations obdfs_super_operations =
49 {
50         obdfs_read_inode,       /* read_inode */
51         obdfs_write_inode,      /* write_inode */
52         NULL,                   /* put_inode */
53         obdfs_delete_inode,     /* delete_inode */
54         obdfs_notify_change,    /* notify_change */
55         obdfs_put_super,        /* put_super */
56         NULL,                   /* write_super */
57         obdfs_statfs,           /* statfs */
58         NULL                    /* remount_fs */
59 };
60
61 struct obdfs_sb_info obdfs_super_info;
62 int obd_minor = 0;
63 int obd_root_ino = 2;
64
65 static struct super_block * obdfs_read_super(struct super_block *sb, 
66                                             void *data, int silent)
67 {
68         struct inode *root = 0; 
69         struct obdfs_sb_info *sbi = NULL;
70         int error = 0;
71
72         ENTRY;
73         MOD_INC_USE_COUNT; 
74
75         sbi = &obdfs_super_info;
76
77         if ( sbi->osi_super ) {
78                 printk("Already mounted\n");
79                 MOD_DEC_USE_COUNT;
80                 return NULL;
81         }
82
83         error  = obd_connect(obd_minor, &sbi->osi_conn_info);
84         if ( error ) {
85                 printk("OBDFS: cannot connect to 0x%x.\n", obd_minor);
86                 goto error;
87         }
88         sbi->osi_super = sb;
89
90         lock_super(sb);
91         sb->u.generic_sbp = sbi;
92         sb->s_blocksize = sbi->osi_conn_info.conn_blocksize;
93         sb->s_blocksize_bits = sbi->osi_conn_info.conn_blocksize_bits;
94         sb->s_magic = OBDFS_SUPER_MAGIC;
95         sb->s_op = &obdfs_super_operations;
96
97         /* make root inode */
98         root = iget(sb, sbi->osi_conn_info.conn_ino);
99         if (!root || is_bad_inode(root)) {
100             printk("OBDFS: bad iget for root\n");
101             sb->s_dev = 0;
102             error = ENOENT;
103             unlock_super(sb);
104             goto error;
105         } 
106
107         printk("obdfs_read_super: rootinode is %ld dev %d\n", 
108                root->i_ino, root->i_dev);
109         sb->s_root = d_alloc_root(root, NULL);
110         unlock_super(sb);
111         EXIT;  
112         return sb;
113
114  error:
115         EXIT;  
116         MOD_DEC_USE_COUNT;
117         if (sbi) {
118                 sbi->osi_super = NULL;
119         }
120         if (root) {
121                 iput(root);
122         }
123         sb->s_dev = 0;
124         return NULL;
125 }
126
127 static void obdfs_put_super(struct super_block *sb)
128 {
129         struct obdfs_sb_info *sbi;
130
131         ENTRY;
132
133
134         sb->s_dev = 0;
135         
136         /* XXX flush stuff */
137         sbi = sb->u.generic_sbp;
138         sb->u.generic_sbp = NULL;
139         obd_disconnect(sbi->osi_conn_info.conn_id);
140         sbi->osi_super = NULL;
141
142         
143         printk("OBDFS: Bye bye.\n");
144         memset(sbi, 0, sizeof(* sbi));
145
146         MOD_DEC_USE_COUNT;
147         EXIT;
148 }
149
150 /* all filling in of inodes postponed until lookup */
151 static void obdfs_read_inode(struct inode *inode)
152 {
153         struct iattr attr;
154         int error;
155         struct obdfs_sb_info *sbi = inode->i_sb->u.generic_sbp;
156         ENTRY;
157
158         error = obd_getattr(sbi->osi_conn_info.conn_id, inode->i_ino, &attr);
159         if (error) {
160                 printk("obdfs_read_inode: ibd_getattr fails (%d)\n", error);
161                 return;
162         }
163
164         inode_setattr(inode, &attr);
165         inode->i_op = NULL;
166         return;
167 }
168
169 static void inode_to_iattr(struct inode *inode, struct iattr *tmp)
170 {
171         tmp->ia_mode = inode->i_mode;
172         tmp->ia_uid = inode->i_uid;
173         tmp->ia_gid = inode->i_gid;
174         tmp->ia_size = inode->i_size;
175         tmp->ia_atime = inode->i_atime;
176         tmp->ia_mtime = inode->i_mtime;
177         tmp->ia_ctime = inode->i_ctime;
178         tmp->ia_attr_flags = inode->i_flags;
179
180         tmp->ia_valid = ~0;
181 }
182
183 static void obdfs_write_inode(struct inode *inode) 
184 {
185         struct obdfs_sb_info *sbi;
186         struct iattr attr;
187         int error;
188         ENTRY;
189         
190         inode_to_iattr(inode, &attr);
191         sbi = inode->i_sb->u.generic_sbp;
192         error = obd_setattr(sbi->osi_conn_info.conn_id, inode->i_ino, &attr);
193         if (error) {
194                 printk("obdfs_write_inode: ibd_setattr fails (%d)\n", error);
195                 return;
196         }
197
198         return;
199 }
200
201 static void obdfs_delete_inode(struct inode *inode)
202 {
203         struct obdfs_sb_info *sbi;
204         int error;
205         ENTRY;
206
207         sbi = inode->i_sb->u.generic_sbp;
208         error = obd_destroy(sbi->osi_conn_info.conn_id , inode->i_ino);
209         if (error) {
210                 printk("obdfs_delete_node: ibd_destroy fails (%d)\n", error);
211                 return;
212         }
213
214         EXIT;
215 }
216
217 static int  obdfs_notify_change(struct dentry *de, struct iattr *iattr)
218 {
219         struct inode *inode = de->d_inode;
220         struct obdfs_sb_info * sbi;
221         int error;
222
223         ENTRY;
224
225         sbi = inode->i_sb->u.generic_sbp;
226         error = obd_setattr(sbi->osi_conn_info.conn_id, inode->i_ino, iattr);
227         if ( error ) {
228                 printk("obdfs_notify_change: obd_setattr fails (%d)\n", error);
229                 return error;
230         } else {
231                 inode_setattr(inode, iattr);
232         }
233         EXIT;
234         return error;
235 }
236
237
238 static int obdfs_statfs(struct super_block *sb, struct statfs *buf, 
239                        int bufsize)
240 {
241         struct statfs tmp;
242         struct obdfs_sb_info * sbi;
243         int error;
244
245         ENTRY;
246
247         sbi = sb->u.generic_sbp;
248         error = obd_statfs(sbi->osi_conn_info.conn_id, &tmp);
249         if ( error ) { 
250                 printk("obdfs_notify_change: obd_statfs fails (%d)\n", error);
251                 return error;
252         }
253         copy_to_user(buf, &tmp, (bufsize<sizeof(tmp)) ? bufsize : sizeof(tmp));
254
255         EXIT;
256
257         return error; 
258 }
259
260 struct file_system_type obdfs_fs_type = {
261    "obdfs", 0, obdfs_read_super, NULL
262 };
263
264 int init_obdfs(void)
265 {
266         printk(KERN_INFO "OBDFS v0.1, braam@stelias.com\n");
267
268         obdfs_sysctl_init();
269         return register_filesystem(&obdfs_fs_type);
270 }
271
272
273 #ifdef MODULE
274 int init_module(void)
275 {
276         return init_obdfs();
277 }
278
279 void cleanup_module(void)
280 {
281         ENTRY;
282
283         obdfs_sysctl_clean();
284 }
285 void obdfs_psdev_dec_use_count(void)
286 {
287         MOD_DEC_USE_COUNT;
288 }
289
290 EXPORT_SYMBOL(obdfs_psdev_dec_use_count);
291
292 #endif