Whamcloud - gitweb
Added code for obdfs to do writes to files and reads of directories and
[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
71         ENTRY;
72         MOD_INC_USE_COUNT; 
73
74         sbi = &obdfs_super_info;
75
76         if ( sbi->osi_super ) {
77                 printk("Already mounted\n");
78                 MOD_DEC_USE_COUNT;
79                 return NULL;
80         }
81
82         sbi->osi_obd = &obd_dev[obd_minor];
83         sbi->osi_ops = sbi->osi_obd->obd_type->typ_ops;
84         
85         error  = sbi->osi_ops->o_connect(obd_minor, &sbi->osi_conn_info);
86         if ( error ) {
87                 printk("OBDFS: cannot connect to 0x%x.\n", obd_minor);
88                 goto error;
89         }
90
91         sbi->osi_super = sb;
92
93         lock_super(sb);
94         sb->u.generic_sbp = sbi;
95         sb->s_blocksize = sbi->osi_conn_info.conn_blocksize;
96         sb->s_blocksize_bits = sbi->osi_conn_info.conn_blocksize_bits;
97         sb->s_magic = OBDFS_SUPER_MAGIC;
98         sb->s_op = &obdfs_super_operations;
99
100         /* make root inode */
101         root = iget(sb, sbi->osi_conn_info.conn_ino);
102         if (!root || is_bad_inode(root)) {
103             printk("OBDFS: bad iget for root\n");
104             sb->s_dev = 0;
105             error = ENOENT;
106             unlock_super(sb);
107             goto error;
108         } 
109
110         printk("obdfs_read_super: rootinode is %ld dev %d\n", 
111                root->i_ino, root->i_dev);
112         sb->s_root = d_alloc_root(root);
113         unlock_super(sb);
114         EXIT;  
115         return sb;
116
117  error:
118         EXIT;  
119         MOD_DEC_USE_COUNT;
120         if (sbi) {
121                 sbi->osi_super = NULL;
122         }
123         if (root) {
124                 iput(root);
125         }
126         sb->s_dev = 0;
127         return NULL;
128 }
129
130 static void obdfs_put_super(struct super_block *sb)
131 {
132         struct obdfs_sb_info *sbi;
133
134         ENTRY;
135
136
137         sb->s_dev = 0;
138         
139         /* XXX flush stuff */
140         sbi = sb->u.generic_sbp;
141         sb->u.generic_sbp = NULL;
142         sbi->osi_ops->o_disconnect(sbi->osi_conn_info.conn_id);
143         sbi->osi_super = NULL;
144
145         
146         printk("OBDFS: Bye bye.\n");
147         memset(sbi, 0, sizeof(* sbi));
148
149         MOD_DEC_USE_COUNT;
150         EXIT;
151 }
152
153 extern struct inode_operations obdfs_inode_ops;
154
155 /* all filling in of inodes postponed until lookup */
156 static void obdfs_read_inode(struct inode *inode)
157 {
158         struct iattr attr;
159         int error;
160         struct obdfs_sb_info *sbi = inode->i_sb->u.generic_sbp;
161         ENTRY;
162
163         error = sbi->osi_ops->o_getattr(sbi->osi_conn_info.conn_id, 
164                                         inode->i_ino, &attr);
165         if (error) {
166                 printk("obdfs_read_inode: ibd_getattr fails (%d)\n", error);
167                 return;
168         }
169
170         inode_setattr(inode, &attr);
171         inode->i_op = &obdfs_inode_ops;
172         return;
173 }
174
175 static void inode_to_iattr(struct inode *inode, struct iattr *tmp)
176 {
177         tmp->ia_mode = inode->i_mode;
178         tmp->ia_uid = inode->i_uid;
179         tmp->ia_gid = inode->i_gid;
180         tmp->ia_size = inode->i_size;
181         tmp->ia_atime = inode->i_atime;
182         tmp->ia_mtime = inode->i_mtime;
183         tmp->ia_ctime = inode->i_ctime;
184         tmp->ia_attr_flags = inode->i_flags;
185
186         tmp->ia_valid = ~0;
187 }
188
189 static void obdfs_write_inode(struct inode *inode) 
190 {
191         struct obdfs_sb_info *sbi;
192         struct iattr attr;
193         int error;
194         
195         inode_to_iattr(inode, &attr);
196         sbi = inode->i_sb->u.generic_sbp;
197         error = sbi->osi_ops->o_setattr(sbi->osi_conn_info.conn_id, 
198                                         inode->i_ino, &attr);
199         if (error) {
200                 printk("obdfs_write_inode: ibd_setattr fails (%d)\n", error);
201                 return;
202         }
203
204         return;
205 }
206
207 static void obdfs_delete_inode(struct inode *inode)
208 {
209         struct obdfs_sb_info *sbi;
210         int error;
211         ENTRY;
212
213         sbi = inode->i_sb->u.generic_sbp;
214         error = sbi->osi_ops->o_destroy(sbi->osi_conn_info.conn_id, 
215                                         inode->i_ino);
216         if (error) {
217                 printk("obdfs_delete_node: ibd_destroy fails (%d)\n", error);
218                 return;
219         }
220
221         EXIT;
222 }
223
224 static int  obdfs_notify_change(struct dentry *de, struct iattr *iattr)
225 {
226         struct inode *inode = de->d_inode;
227         struct obdfs_sb_info * sbi;
228         int error;
229
230         ENTRY;
231
232         sbi = inode->i_sb->u.generic_sbp;
233         error = sbi->osi_ops->o_setattr(sbi->osi_conn_info.conn_id, 
234                                         inode->i_ino, iattr);
235         if ( error ) {
236                 printk("obdfs_notify_change: obd_setattr fails (%d)\n", error);
237                 return error;
238         } else {
239                 inode_setattr(inode, iattr);
240         }
241         EXIT;
242         return error;
243 }
244
245
246 static int obdfs_statfs(struct super_block *sb, struct statfs *buf, 
247                        int bufsize)
248 {
249         struct statfs tmp;
250         struct obdfs_sb_info * sbi;
251         int error;
252
253         ENTRY;
254
255         sbi = sb->u.generic_sbp;
256         error = sbi->osi_ops->o_statfs(sbi->osi_conn_info.conn_id, &tmp);
257         if ( error ) { 
258                 printk("obdfs_notify_change: obd_statfs fails (%d)\n", error);
259                 return error;
260         }
261         copy_to_user(buf, &tmp, (bufsize<sizeof(tmp)) ? bufsize : sizeof(tmp));
262
263         EXIT;
264
265         return error; 
266 }
267
268 struct file_system_type obdfs_fs_type = {
269    "obdfs", 0, obdfs_read_super, NULL
270 };
271
272 int init_obdfs(void)
273 {
274         printk(KERN_INFO "OBDFS v0.1, braam@stelias.com\n");
275
276         obdfs_sysctl_init();
277
278         obd_sbi = &obdfs_super_info;
279         obd_fso = &obdfs_file_operations;
280
281         return register_filesystem(&obdfs_fs_type);
282 }
283
284
285 #ifdef MODULE
286 int init_module(void)
287 {
288         return init_obdfs();
289 }
290
291 void cleanup_module(void)
292 {
293         ENTRY;
294
295         obdfs_sysctl_clean();
296         unregister_filesystem(&obdfs_fs_type);
297 }
298 void obdfs_psdev_dec_use_count(void)
299 {
300         MOD_DEC_USE_COUNT;
301 }
302
303 EXPORT_SYMBOL(obdfs_psdev_dec_use_count);
304
305 #endif