Whamcloud - gitweb
0072f36d5eda1dd5be6db48d0805353b49eb7390
[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  * Copryright (C) 1999 Stelias Computing Inc. <braam@stelias.com>
6  * Copryright (C) 1999 Seagate Technology Inc.
7  *
8  */
9
10 #define EXPORT_SYMTAB
11
12 #include <linux/config.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/mm.h>
16 #include <linux/string.h>
17 #include <linux/stat.h>
18 #include <linux/errno.h>
19 #include <linux/locks.h>
20 #include <linux/unistd.h>
21
22 #include <asm/system.h>
23 #include <asm/uaccess.h>
24
25 #include <linux/fs.h>
26 #include <linux/stat.h>
27 #include <asm/uaccess.h>
28 #include <linux/vmalloc.h>
29 #include <asm/segment.h>
30
31 #include <linux/obd_support.h>
32 #include <linux/obd_class.h>
33 #include <linux/obd_sim.h>  /* XXX for development/debugging only */
34 #include <obdfs.h>
35
36 /* VFS super_block ops */
37 static struct super_block *obdfs_read_super(struct super_block *, void *, int);
38 static void obdfs_read_inode(struct inode *);
39 static int  obdfs_notify_change(struct dentry *dentry, struct iattr *attr);
40 static void obdfs_write_inode(struct inode *);
41 static void obdfs_delete_inode(struct inode *);
42 static void obdfs_put_super(struct super_block *);
43 static int obdfs_statfs(struct super_block *sb, struct statfs *buf, 
44                        int bufsiz);
45
46 /* exported operations */
47 struct super_operations obdfs_super_operations =
48 {
49         obdfs_read_inode,       /* read_inode */
50         obdfs_write_inode,      /* write_inode */
51         NULL,                   /* put_inode */
52         obdfs_delete_inode,     /* delete_inode */
53         obdfs_notify_change,    /* notify_change */
54         obdfs_put_super,        /* put_super */
55         NULL,                   /* write_super */
56         obdfs_statfs,           /* statfs */
57         NULL                    /* remount_fs */
58 };
59
60 struct obdfs_sb_info obdfs_super_info;
61 int obd_minor = 0;
62 int obd_root_ino = 2;
63
64 static struct super_block * obdfs_read_super(struct super_block *sb, 
65                                             void *data, int silent)
66 {
67         struct inode *root = 0; 
68         struct obdfs_sb_info *sbi = NULL;
69         int error = 0;
70         unsigned long blocksize;
71         unsigned long blocksize_bits;
72         unsigned long root_ino;
73         int scratch;
74         
75
76         ENTRY;
77         MOD_INC_USE_COUNT; 
78
79         sbi = &obdfs_super_info;
80
81         if ( sbi->osi_super ) {
82                 printk("Already mounted\n");
83                 MOD_DEC_USE_COUNT;
84                 return NULL;
85         }
86
87         sbi->osi_obd = &obd_dev[obd_minor];
88         sbi->osi_ops = sbi->osi_obd->obd_type->typ_ops;
89         
90         error  = sbi->osi_ops->o_connect(sbi->osi_obd, &sbi->osi_conn_info);
91         if ( error ) {
92                 printk("OBDFS: cannot connect to 0x%x.\n", obd_minor);
93                 goto error;
94         }
95
96         sbi->osi_super = sb;
97
98         error = sbi->osi_ops->o_get_info(sbi->osi_conn_info.conn_id, 
99                                          strlen("blocksize"), 
100                                          "blocksize", 
101                                          &scratch, (void *)&blocksize);
102         if ( error ) {
103                 printk("Getinfo call to drive failed (blocksize)\n");
104                 goto error;
105         }
106
107         error = sbi->osi_ops->o_get_info(sbi->osi_conn_info.conn_id, 
108                                          strlen("blocksize_bits"), 
109                                          "blocksize_bits", 
110                                          &scratch, (void *)&blocksize_bits);
111         if ( error ) {
112                 printk("Getinfo call to drive failed (blocksize_bits)\n");
113                 goto error;
114         }
115
116         error = sbi->osi_ops->o_get_info(sbi->osi_conn_info.conn_id, 
117                                          strlen("root_ino"), 
118                                          "root_ino", 
119                                          &scratch, (void *)&root_ino);
120         if ( error ) {
121                 printk("Getinfo call to drive failed (root_ino)\n");
122                 goto error;
123         }
124         
125
126         lock_super(sb);
127         sb->u.generic_sbp = sbi;
128         
129         sb->s_blocksize = blocksize;
130         sb->s_blocksize_bits = (unsigned char)blocksize_bits;
131         sb->s_magic = OBDFS_SUPER_MAGIC;
132         sb->s_op = &obdfs_super_operations;
133
134         /* make root inode */
135         root = iget(sb, root_ino);
136         if (!root || is_bad_inode(root)) {
137             printk("OBDFS: bad iget for root\n");
138             sb->s_dev = 0;
139             error = ENOENT;
140             unlock_super(sb);
141             goto error;
142         } 
143
144         printk("obdfs_read_super: rootinode is %ld dev %d\n", 
145                root->i_ino, root->i_dev);
146         sb->s_root = d_alloc_root(root);
147         unlock_super(sb);
148         EXIT;  
149         return sb;
150
151  error:
152         EXIT;  
153         MOD_DEC_USE_COUNT;
154         if (sbi) {
155                 sbi->osi_super = NULL;
156         }
157         if (root) {
158                 iput(root);
159         }
160         sb->s_dev = 0;
161         return NULL;
162 }
163
164 static void obdfs_put_super(struct super_block *sb)
165 {
166         struct obdfs_sb_info *sbi;
167
168         ENTRY;
169
170
171         sb->s_dev = 0;
172         
173         /* XXX flush stuff */
174         sbi = sb->u.generic_sbp;
175         sb->u.generic_sbp = NULL;
176         sbi->osi_ops->o_disconnect(sbi->osi_conn_info.conn_id);
177         sbi->osi_super = NULL;
178
179         
180         printk("OBDFS: Bye bye.\n");
181         memset(sbi, 0, sizeof(* sbi));
182
183         MOD_DEC_USE_COUNT;
184         EXIT;
185 }
186
187 extern struct inode_operations obdfs_inode_ops;
188
189 /* all filling in of inodes postponed until lookup */
190 static void obdfs_read_inode(struct inode *inode)
191 {
192         int error;
193         struct obdfs_sb_info *sbi = inode->i_sb->u.generic_sbp;
194         ENTRY;
195
196         error = sbi->osi_ops->o_getattr(sbi->osi_conn_info.conn_id, 
197                                         inode->i_ino, inode);
198         if (error) {
199                 printk("obdfs_read_inode: ibd_getattr fails (%d)\n", error);
200                 return;
201         }
202
203         inode->i_op = &obdfs_inode_ops;
204         return;
205 }
206
207 static void obdfs_write_inode(struct inode *inode) 
208 {
209         struct obdfs_sb_info *sbi;
210         int error;
211         
212         sbi = inode->i_sb->u.generic_sbp;
213         error = sbi->osi_ops->o_setattr(sbi->osi_conn_info.conn_id, 
214                                         inode->i_ino, inode);
215         if (error) {
216                 printk("obdfs_write_inode: ibd_setattr fails (%d)\n", error);
217                 return;
218         }
219
220         return;
221 }
222
223 static void obdfs_delete_inode(struct inode *inode)
224 {
225         struct obdfs_sb_info *sbi;
226         int error;
227         ENTRY;
228
229         sbi = inode->i_sb->u.generic_sbp;
230         error = sbi->osi_ops->o_destroy(sbi->osi_conn_info.conn_id, 
231                                         inode->i_ino);
232         if (error) {
233                 printk("obdfs_delete_node: ibd_destroy fails (%d)\n", error);
234                 return;
235         }
236
237         EXIT;
238 }
239
240 static int  obdfs_notify_change(struct dentry *de, struct iattr *iattr)
241 {
242         struct inode *inode = de->d_inode;
243         struct iattr saved_copy;
244         struct obdfs_sb_info * sbi;
245         int error;
246
247         ENTRY;
248         inode_to_iattr(inode, &saved_copy);
249
250         sbi = inode->i_sb->u.generic_sbp;
251         inode_setattr(inode, iattr);
252         error = sbi->osi_ops->o_setattr(sbi->osi_conn_info.conn_id, 
253                                         inode->i_ino, inode);
254         if ( error ) {
255                 inode_setattr(inode, &saved_copy);
256                 printk("obdfs_notify_change: obd_setattr fails (%d)\n", error);
257                 return error;
258         }
259         EXIT;
260         return error;
261 }
262
263
264 static int obdfs_statfs(struct super_block *sb, struct statfs *buf, 
265                        int bufsize)
266 {
267         struct statfs tmp;
268         struct obdfs_sb_info * sbi;
269         int error;
270
271         ENTRY;
272
273         sbi = sb->u.generic_sbp;
274         error = sbi->osi_ops->o_statfs(sbi->osi_conn_info.conn_id, &tmp);
275         if ( error ) { 
276                 printk("obdfs_notify_change: obd_statfs fails (%d)\n", error);
277                 return error;
278         }
279         copy_to_user(buf, &tmp, (bufsize<sizeof(tmp)) ? bufsize : sizeof(tmp));
280
281         EXIT;
282
283         return error; 
284 }
285
286 struct file_system_type obdfs_fs_type = {
287    "obdfs", 0, obdfs_read_super, NULL
288 };
289
290 int init_obdfs(void)
291 {
292         printk(KERN_INFO "OBDFS v0.1, braam@stelias.com\n");
293
294         obdfs_sysctl_init();
295
296         obd_sbi = &obdfs_super_info;
297         obd_fso = &obdfs_file_ops;
298
299         return register_filesystem(&obdfs_fs_type);
300 }
301
302
303 #ifdef MODULE
304 int init_module(void)
305 {
306         return init_obdfs();
307 }
308
309 void cleanup_module(void)
310 {
311         ENTRY;
312
313         obdfs_sysctl_clean();
314         unregister_filesystem(&obdfs_fs_type);
315 }
316 void obdfs_psdev_dec_use_count(void)
317 {
318         MOD_DEC_USE_COUNT;
319 }
320
321 EXPORT_SYMBOL(obdfs_psdev_dec_use_count);
322
323 #endif