Linux 2.2.0
[davej-history.git] / fs / coda / cnode.c
blob2a099d86518a84f25d1283ecd965de48086c4c59
1 /* cnode related routines for the coda kernel code
2 (C) 1996 Peter Braam
3 */
5 #include <linux/types.h>
6 #include <linux/time.h>
8 #include <linux/coda.h>
9 #include <linux/coda_linux.h>
10 #include <linux/coda_fs_i.h>
11 #include <linux/coda_psdev.h>
13 extern int coda_debug;
14 extern int coda_print_entry;
16 /* cnode.c */
17 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
19 CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
21 if (coda_debug & D_SUPER )
22 print_vattr(attr);
24 coda_vattr_to_iattr(inode, attr);
26 if (S_ISREG(inode->i_mode))
27 inode->i_op = &coda_file_inode_operations;
28 else if (S_ISDIR(inode->i_mode))
29 inode->i_op = &coda_dir_inode_operations;
30 else if (S_ISLNK(inode->i_mode))
31 inode->i_op = &coda_symlink_inode_operations;
32 else if (S_ISCHR(inode->i_mode)) {
33 inode->i_op = &chrdev_inode_operations;
34 inode->i_rdev = to_kdev_t(attr->va_rdev);
35 } else if (S_ISBLK(inode->i_mode)) {
36 inode->i_op = &blkdev_inode_operations;
37 inode->i_rdev = to_kdev_t(attr->va_rdev);
38 } else if (S_ISFIFO(inode->i_mode))
39 init_fifo(inode);
40 else if (S_ISSOCK(inode->i_mode))
41 inode->i_op = NULL;
42 else {
43 printk ("coda_fill_inode: what's this? i_mode = %o\n",
44 inode->i_mode);
45 inode->i_op = NULL;
49 /* this is effectively coda_iget:
50 - get attributes (might be cached)
51 - get the inode for the fid using vfs iget
52 - link the two up if this is needed
53 - fill in the attributes
55 int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
57 struct coda_inode_info *cnp;
58 struct coda_sb_info *sbi= coda_sbp(sb);
59 struct coda_vattr attr;
60 int error;
61 ino_t ino;
63 ENTRY;
65 /*
66 * We get inode numbers from Venus -- see venus source
69 error = venus_getattr(sb, fid, &attr);
70 if ( error ) {
71 CDEBUG(D_CNODE,
72 "coda_cnode_make: coda_getvattr returned %d for %s.\n",
73 error, coda_f2s(fid));
74 *inode = NULL;
75 return error;
78 ino = attr.va_fileid;
79 *inode = iget(sb, ino);
80 if ( !*inode ) {
81 printk("coda_cnode_make: iget failed\n");
82 return -ENOMEM;
85 cnp = ITOC(*inode);
86 if ( cnp->c_magic != 0 ) {
87 printk("coda_cnode make on initialized inode %ld, old %s new
88 %s!\n",
89 (*inode)->i_ino, coda_f2s(&cnp->c_fid), coda_f2s2(fid));
90 iput(*inode);
91 return -ENOENT;
94 memset(cnp, 0, (int) sizeof(struct coda_inode_info));
95 cnp->c_fid = *fid;
96 cnp->c_magic = CODA_CNODE_MAGIC;
97 cnp->c_flags = 0;
98 cnp->c_vnode = *inode;
99 INIT_LIST_HEAD(&(cnp->c_cnhead));
100 INIT_LIST_HEAD(&(cnp->c_volrootlist));
102 /* fill in the inode attributes */
103 if ( coda_f2i(fid) != ino ) {
104 if ( !coda_fid_is_weird(fid) )
105 printk("Coda: unknown weird fid: ino %ld, fid %s."
106 "Tell Peter.\n", ino, coda_f2s(&cnp->c_fid));
107 list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
108 CDEBUG(D_UPCALL, "Added %ld ,%s to volroothead\n",
109 ino, coda_f2s(&cnp->c_fid));
112 coda_fill_inode(*inode, &attr);
113 CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
114 (*inode)->i_ino, (*inode)->i_count,
115 coda_f2s(&cnp->c_fid));
117 EXIT;
118 return 0;
121 inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
123 int eq;
124 eq = ( (fid1->Vnode == fid2->Vnode) &&
125 (fid1->Volume == fid2->Volume) &&
126 (fid1->Unique == fid2->Unique) );
127 return eq;
130 void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
131 struct ViceFid *newfid)
133 struct coda_inode_info *cnp;
134 struct coda_sb_info *sbi= coda_sbp(inode->i_sb);
136 cnp = ITOC(inode);
138 if ( ! coda_fideq(&cnp->c_fid, oldfid) )
139 printk("What? oldfid != cnp->c_fid. Call 911.\n");
141 cnp->c_fid = *newfid;
143 list_del(&cnp->c_volrootlist);
144 if ( !coda_fid_is_weird(newfid) )
145 list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
147 return;
153 /* convert a fid to an inode. Mostly we can compute
154 the inode number from the FID, but not for volume
155 mount points: those are in a list */
156 struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
158 ino_t nr;
159 struct inode *inode;
160 struct coda_inode_info *cnp;
161 ENTRY;
164 if ( !sb ) {
165 printk("coda_fid_to_inode: no sb!\n");
166 return NULL;
169 if ( !fid ) {
170 printk("coda_fid_to_inode: no fid!\n");
171 return NULL;
173 CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
176 if ( coda_fid_is_weird(fid) ) {
177 struct coda_inode_info *cii;
178 struct list_head *lh, *le;
179 struct coda_sb_info *sbi = coda_sbp(sb);
180 le = lh = &sbi->sbi_volroothead;
182 while ( (le = le->next) != lh ) {
183 cii = list_entry(le, struct coda_inode_info,
184 c_volrootlist);
185 CDEBUG(D_DOWNCALL, "iterating, now doing %s, ino %ld\n",
186 coda_f2s(&cii->c_fid), cii->c_vnode->i_ino);
187 if ( coda_fideq(&cii->c_fid, fid) ) {
188 inode = cii->c_vnode;
189 CDEBUG(D_INODE, "volume root, found %ld\n", cii->c_vnode->i_ino);
190 if ( cii->c_magic != CODA_CNODE_MAGIC )
191 printk("%s: Bad magic in inode, tell Peter.\n",
192 __FUNCTION__);
193 return cii->c_vnode;
197 return NULL;
200 /* fid is not weird: ino should be computable */
201 nr = coda_f2i(fid);
202 inode = iget(sb, nr);
203 if ( !inode ) {
204 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
205 sb, nr);
206 return NULL;
209 /* check if this inode is linked to a cnode */
210 cnp = ITOC(inode);
211 if ( cnp->c_magic != CODA_CNODE_MAGIC ) {
212 CDEBUG(D_INODE, "uninitialized inode. Return.\n");
213 iput(inode);
214 return NULL;
217 /* make sure fid is the one we want;
218 unfortunately Venus will shamelessly send us mount-symlinks.
219 These have the same inode as the root of the volume they
220 mount, but the fid will be wrong.
222 if ( !coda_fideq(fid, &(cnp->c_fid)) ) {
223 /* printk("coda_fid2inode: bad cnode (ino %ld, fid %s)"
224 "Tell Peter.\n", nr, coda_f2s(fid)); */
225 iput(inode);
226 return NULL;
229 CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
230 iput(inode);
231 return inode;
234 /* the CONTROL inode is made without asking attributes from Venus */
235 int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
237 int error = 0;
239 *inode = iget(sb, CTL_INO);
240 if ( *inode ) {
241 (*inode)->i_op = &coda_ioctl_inode_operations;
242 (*inode)->i_mode = 00444;
243 error = 0;
244 } else {
245 error = -ENOMEM;
248 return error;