Import 2.1.89
[davej-history.git] / fs / coda / super.c
blob5410fb50d81c00aef48b26a5428e770f9ac36147
1 /*
2 * Super block/filesystem wide operations
4 * Copryright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk> and
5 * Michael Callahan <callahan@maths.ox.ac.uk>
6 *
7 * Rewritten for Linux 2.1.?? Peter Braam <braam@cs.cmu.edu>
8 * Copyright (C) Carnegie Mellon University
9 */
11 #define __NO_VERSION__
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/string.h>
16 #include <linux/stat.h>
17 #include <linux/errno.h>
18 #include <linux/locks.h>
19 #include <linux/unistd.h>
21 #include <asm/system.h>
22 #include <asm/uaccess.h>
24 #include <linux/fs.h>
25 #include <linux/stat.h>
26 #include <linux/errno.h>
27 #include <linux/locks.h>
28 #include <linux/string.h>
29 #include <asm/uaccess.h>
30 #include <linux/vmalloc.h>
31 #include <asm/segment.h>
33 #include <linux/coda.h>
34 #include <linux/coda_linux.h>
35 #include <linux/coda_psdev.h>
36 #include <linux/coda_fs_i.h>
37 #include <linux/coda_cache.h>
40 /* VFS super_block ops */
41 static struct super_block *coda_read_super(struct super_block *,void*,int);
42 static voidcoda_read_inode(struct inode *);
43 static intcoda_notify_change(struct dentry *dentry,struct iattr *attr);
44 static voidcoda_put_inode(struct inode *);
45 static voidcoda_delete_inode(struct inode *);
46 static voidcoda_put_super(struct super_block *);
47 static intcoda_statfs(struct super_block *sb,struct statfs *buf,
48 int bufsiz);
50 /* helper functions */
51 staticinlinestruct vcomm *coda_psinode2vcomm(struct inode *inode);
52 static intcoda_get_psdev(void*,struct inode **);
53 static struct coda_sb_info *coda_psinode2sbi(struct inode *inode);
55 /* exported operations */
56 struct super_operations coda_super_operations =
58 coda_read_inode,/* read_inode */
59 NULL,/* write_inode */
60 coda_put_inode,/* put_inode */
61 coda_delete_inode,/* delete_inode */
62 coda_notify_change,/* notify_change */
63 coda_put_super,/* put_super */
64 NULL,/* write_super */
65 coda_statfs,/* statfs */
66 NULL /* remount_fs */
70 * globals
72 struct coda_sb_info coda_super_info[MAX_CODADEVS];
75 static struct super_block *coda_read_super(struct super_block *sb,
76 void*data,int silent)
78 struct inode *psdev =0, *root =0;
79 struct coda_sb_info *sbi = NULL;
80 struct vcomm *vc = NULL;
81 ViceFid fid;
82 kdev_t dev = sb->s_dev;
83 int error;
84 char str[50];
86 ENTRY;
87 MOD_INC_USE_COUNT;
88 if(coda_get_psdev(data, &psdev))
89 goto error;
91 vc =coda_psinode2vcomm(psdev);
92 if( !vc )
93 goto error;
94 vc->vc_sb = sb;
95 vc->vc_inuse =1;
97 sbi =coda_psinode2sbi(psdev);
98 if( !sbi )
99 goto error;
100 sbi->sbi_psdev = psdev;
101 sbi->sbi_vcomm = vc;
102 INIT_LIST_HEAD(&(sbi->sbi_cchead));
103 INIT_LIST_HEAD(&(sbi->sbi_volroothead));
105 lock_super(sb);
106 sb->u.generic_sbp = sbi;
107 sb->s_blocksize =1024;/* XXXXX what do we put here?? */
108 sb->s_blocksize_bits =10;
109 sb->s_magic = CODA_SUPER_MAGIC;
110 sb->s_dev = dev;
111 sb->s_op = &coda_super_operations;
113 /* get root fid from Venus: this needs the root inode */
114 error =venus_rootfid(sb, &fid);
115 if( error ) {
116 printk("coda_read_super: coda_get_rootfid failed with %d\n",
117 error);
118 sb->s_dev =0;
119 unlock_super(sb);
120 goto error;
122 printk("coda_read_super: rootfid is %s\n",coda_f2s(&fid));
124 /* make root inode */
125 error =coda_cnode_make(&root, &fid, sb);
126 if( error || !root ) {
127 printk("Failure of coda_cnode_make for root: error %d\n", error);
128 sb->s_dev =0;
129 unlock_super(sb);
130 goto error;
133 printk("coda_read_super: rootinode is %ld dev %d\n",
134 root->i_ino, root->i_dev);
135 sbi->sbi_root = root;
136 sb->s_root =d_alloc_root(root, NULL);
137 unlock_super(sb);
138 EXIT;
139 return sb;
141 error:
142 EXIT;
143 MOD_DEC_USE_COUNT;
144 if(sbi) {
145 sbi->sbi_vcomm = NULL;
146 sbi->sbi_root = NULL;
148 if( vc ) {
149 vc->vc_sb = NULL;
150 vc->vc_inuse =0;
152 if(root) {
153 iput(root);
155 sb->s_dev =0;
156 return NULL;
159 static voidcoda_put_super(struct super_block *sb)
161 struct coda_sb_info *sb_info;
163 ENTRY;
165 lock_super(sb);
167 sb->s_dev =0;
168 coda_cache_clear_all(sb);
169 sb_info =coda_sbp(sb);
170 sb_info->sbi_vcomm->vc_inuse =0;
171 sb_info->sbi_vcomm->vc_sb = NULL;
172 printk("Coda: Bye bye.\n");
173 memset(sb_info,0,sizeof(* sb_info));
175 unlock_super(sb);
176 MOD_DEC_USE_COUNT;
177 EXIT;
180 /* all filling in of inodes postponed until lookup */
181 static voidcoda_read_inode(struct inode *inode)
183 struct coda_inode_info *cnp;
184 ENTRY;
185 cnp =ITOC(inode);
186 cnp->c_magic =0;
187 return;
190 static voidcoda_put_inode(struct inode *in)
192 ENTRY;
194 CDEBUG(D_INODE,"ino: %ld, count %d\n", in->i_ino, in->i_count);
196 if( in->i_count ==1)
197 in->i_nlink =0;
201 static voidcoda_delete_inode(struct inode *inode)
203 struct coda_inode_info *cnp;
204 struct inode *open_inode;
206 ENTRY;
207 CDEBUG(D_SUPER," inode->ino: %ld, count: %d\n",
208 inode->i_ino, inode->i_count);
210 cnp =ITOC(inode);
211 if( inode->i_ino == CTL_INO || cnp->c_magic != CODA_CNODE_MAGIC ) {
212 clear_inode(inode);
213 return;
217 if(coda_fid_is_volroot(&cnp->c_fid) )
218 list_del(&cnp->c_volrootlist);
220 open_inode = cnp->c_ovp;
221 if( open_inode ) {
222 CDEBUG(D_SUPER,"DELINO cached file: ino %ld count %d.\n",
223 open_inode->i_ino, open_inode->i_count);
224 cnp->c_ovp = NULL;
225 iput(open_inode);
228 coda_cache_clear_cnp(cnp);
230 inode->u.generic_ip = NULL;
231 clear_inode(inode);
232 EXIT;
235 static intcoda_notify_change(struct dentry *de,struct iattr *iattr)
237 struct inode *inode = de->d_inode;
238 struct coda_inode_info *cnp;
239 struct coda_vattr vattr;
240 int error;
242 ENTRY;
243 memset(&vattr,0,sizeof(vattr));
244 cnp =ITOC(inode);
245 CHECK_CNODE(cnp);
247 coda_iattr_to_vattr(iattr, &vattr);
248 vattr.va_type = C_VNON;/* cannot set type */
249 CDEBUG(D_SUPER,"vattr.va_mode %o\n", vattr.va_mode);
251 error =venus_setattr(inode->i_sb, &cnp->c_fid, &vattr);
253 if( !error ) {
254 coda_vattr_to_iattr(inode, &vattr);
255 coda_cache_clear_cnp(cnp);
257 CDEBUG(D_SUPER,"inode.i_mode %o, error %d\n",
258 inode->i_mode, error);
260 EXIT;
261 return error;
264 /* we need _something_ for this routine. Let's mimic AFS */
265 static intcoda_statfs(struct super_block *sb,struct statfs *buf,
266 int bufsiz)
268 struct statfs tmp;
270 tmp.f_type = CODA_SUPER_MAGIC;
271 tmp.f_bsize =1024;
272 tmp.f_blocks =9000000;
273 tmp.f_bfree =9000000;
274 tmp.f_bavail =9000000;
275 tmp.f_files =9000000;
276 tmp.f_ffree =9000000;
277 tmp.f_namelen =0;
278 copy_to_user(buf, &tmp, bufsiz);
279 return0;
283 /* init_coda: used by filesystems.c to register coda */
285 struct file_system_type coda_fs_type = {
286 "coda",0, coda_read_super, NULL
289 intinit_coda_fs(void)
291 returnregister_filesystem(&coda_fs_type);
294 /* MODULE stuff is in psdev.c */
296 /* helpers */
297 staticinlinestruct vcomm *coda_psinode2vcomm(struct inode *inode)
300 unsigned int minor =MINOR(inode->i_rdev);
301 CDEBUG(D_PSDEV,"minor %d\n", minor);
302 if( minor < MAX_CODADEVS )
303 return&(psdev_vcomm[minor]);
304 else
305 return NULL;
308 static struct coda_sb_info *coda_psinode2sbi(struct inode *inode)
310 unsigned int minor =MINOR(inode->i_rdev);
312 CDEBUG(D_PSDEV,"minor %d\n", minor);
313 if( (minor >=0) && (minor < MAX_CODADEVS))
314 return&(coda_super_info[minor]);
315 else
316 return NULL;
319 /* name lookup for psdev passed in by mount */
320 static intcoda_get_psdev(void*data,struct inode **res_dev)
322 char**psdev_path;
323 struct inode *psdev =0;
324 struct dentry *ent=NULL;
327 if( ! data ) {
328 printk("coda_get_psdev: no data!\n");
329 return1;
332 psdev_path = data;
333 ent =namei((char*) *psdev_path);
334 if(IS_ERR(ent)) {
335 printk("namei error %ld for %d\n",PTR_ERR(ent),
336 (int) psdev_path);
337 return1;
339 psdev = ent->d_inode;
341 if(!S_ISCHR(psdev->i_mode)) {
342 printk("not a character device\n");
343 return1;
345 CDEBUG(D_PSDEV,"major %d, minor %d, count %d\n",
346 MAJOR(psdev->i_rdev),
347 MINOR(psdev->i_rdev), psdev->i_count);
349 if(MAJOR(psdev->i_rdev) != CODA_PSDEV_MAJOR) {
350 printk("device %d not a Coda PSDEV device\n",
351 MAJOR(psdev->i_rdev));
352 return1;
355 if(MINOR(psdev->i_rdev) >= MAX_CODADEVS) {
356 printk("minor %d not an allocated Coda PSDEV\n",
357 psdev->i_rdev);
358 return1;
361 if(psdev->i_count <1) {
362 printk("coda device minor %d not open (i_count = %d)\n",
363 MINOR(psdev->i_rdev), psdev->i_count);
364 return1;
367 *res_dev = psdev;
368 EXIT;
369 return0;
close