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