Import 2.3.5
[davej-history.git] / fs / coda / cnode.c
blobdd1e03f5feda3f9f8439ad04ef674b6c987cff6a
1 /* cnode related routines for the coda kernel code
2 (C) 1996 Peter Braam
3 */
5 #include <linux/types.h>
6 #include <linux/string.h>
7 #include <linux/time.h>
9 #include <linux/coda.h>
10 #include <linux/coda_linux.h>
11 #include <linux/coda_fs_i.h>
12 #include <linux/coda_psdev.h>
14 extern int coda_debug;
15 extern int coda_print_entry;
17 /* cnode.c */
18 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
20 CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
22 if (coda_debug & D_SUPER )
23 print_vattr(attr);
25 coda_vattr_to_iattr(inode, attr);
27 if (S_ISREG(inode->i_mode))
28 inode->i_op = &coda_file_inode_operations;
29 else if (S_ISDIR(inode->i_mode))
30 inode->i_op = &coda_dir_inode_operations;
31 else if (S_ISLNK(inode->i_mode))
32 inode->i_op = &coda_symlink_inode_operations;
33 else
34 init_special_inode(inode, inode->i_mode, attr->va_rdev);
37 /* this is effectively coda_iget:
38 - get attributes (might be cached)
39 - get the inode for the fid using vfs iget
40 - link the two up if this is needed
41 - fill in the attributes
43 int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
45 struct coda_inode_info *cnp;
46 struct coda_sb_info *sbi= coda_sbp(sb);
47 struct coda_vattr attr;
48 int error;
49 ino_t ino;
51 ENTRY;
53 /*
54 * We get inode numbers from Venus -- see venus source
57 error = venus_getattr(sb, fid, &attr);
58 if ( error ) {
59 CDEBUG(D_CNODE,
60 "coda_cnode_make: coda_getvattr returned %d for %s.\n",
61 error, coda_f2s(fid));
62 *inode = NULL;
63 return error;
66 ino = attr.va_fileid;
67 *inode = iget(sb, ino);
68 if ( !*inode ) {
69 printk("coda_cnode_make: iget failed\n");
70 return -ENOMEM;
73 cnp = ITOC(*inode);
74 if ( cnp->c_magic != 0 ) {
75 printk("coda_cnode make on initialized inode %ld, old %s new
76 %s!\n",
77 (*inode)->i_ino, coda_f2s(&cnp->c_fid), coda_f2s2(fid));
78 iput(*inode);
79 return -ENOENT;
82 memset(cnp, 0, (int) sizeof(struct coda_inode_info));
83 cnp->c_fid = *fid;
84 cnp->c_magic = CODA_CNODE_MAGIC;
85 cnp->c_flags = 0;
86 cnp->c_vnode = *inode;
87 INIT_LIST_HEAD(&(cnp->c_cnhead));
88 INIT_LIST_HEAD(&(cnp->c_volrootlist));
90 /* fill in the inode attributes */
91 if ( coda_f2i(fid) != ino ) {
92 if ( !coda_fid_is_weird(fid) )
93 printk("Coda: unknown weird fid: ino %ld, fid %s."
94 "Tell Peter.\n", ino, coda_f2s(&cnp->c_fid));
95 list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
96 CDEBUG(D_UPCALL, "Added %ld ,%s to volroothead\n",
97 ino, coda_f2s(&cnp->c_fid));
100 coda_fill_inode(*inode, &attr);
101 CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
102 (*inode)->i_ino, (*inode)->i_count,
103 coda_f2s(&cnp->c_fid));
105 EXIT;
106 return 0;
109 inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
111 int eq;
112 eq = ( (fid1->Vnode == fid2->Vnode) &&
113 (fid1->Volume == fid2->Volume) &&
114 (fid1->Unique == fid2->Unique) );
115 return eq;
118 void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
119 struct ViceFid *newfid)
121 struct coda_inode_info *cnp;
122 struct coda_sb_info *sbi= coda_sbp(inode->i_sb);
124 cnp = ITOC(inode);
126 if ( ! coda_fideq(&cnp->c_fid, oldfid) )
127 printk("What? oldfid != cnp->c_fid. Call 911.\n");
129 cnp->c_fid = *newfid;
131 list_del(&cnp->c_volrootlist);
132 if ( !coda_fid_is_weird(newfid) )
133 list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
135 return;
141 /* convert a fid to an inode. Mostly we can compute
142 the inode number from the FID, but not for volume
143 mount points: those are in a list */
144 struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
146 ino_t nr;
147 struct inode *inode;
148 struct coda_inode_info *cnp;
149 ENTRY;
152 if ( !sb ) {
153 printk("coda_fid_to_inode: no sb!\n");
154 return NULL;
157 if ( !fid ) {
158 printk("coda_fid_to_inode: no fid!\n");
159 return NULL;
161 CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
164 if ( coda_fid_is_weird(fid) ) {
165 struct coda_inode_info *cii;
166 struct list_head *lh, *le;
167 struct coda_sb_info *sbi = coda_sbp(sb);
168 le = lh = &sbi->sbi_volroothead;
170 while ( (le = le->next) != lh ) {
171 cii = list_entry(le, struct coda_inode_info,
172 c_volrootlist);
173 CDEBUG(D_DOWNCALL, "iterating, now doing %s, ino %ld\n",
174 coda_f2s(&cii->c_fid), cii->c_vnode->i_ino);
175 if ( coda_fideq(&cii->c_fid, fid) ) {
176 inode = cii->c_vnode;
177 CDEBUG(D_INODE, "volume root, found %ld\n", cii->c_vnode->i_ino);
178 if ( cii->c_magic != CODA_CNODE_MAGIC )
179 printk("%s: Bad magic in inode, tell Peter.\n",
180 __FUNCTION__);
181 return cii->c_vnode;
185 return NULL;
188 /* fid is not weird: ino should be computable */
189 nr = coda_f2i(fid);
190 inode = iget(sb, nr);
191 if ( !inode ) {
192 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
193 sb, nr);
194 return NULL;
197 /* check if this inode is linked to a cnode */
198 cnp = ITOC(inode);
199 if ( cnp->c_magic != CODA_CNODE_MAGIC ) {
200 CDEBUG(D_INODE, "uninitialized inode. Return.\n");
201 iput(inode);
202 return NULL;
205 /* make sure fid is the one we want;
206 unfortunately Venus will shamelessly send us mount-symlinks.
207 These have the same inode as the root of the volume they
208 mount, but the fid will be wrong.
210 if ( !coda_fideq(fid, &(cnp->c_fid)) ) {
211 /* printk("coda_fid2inode: bad cnode (ino %ld, fid %s)"
212 "Tell Peter.\n", nr, coda_f2s(fid)); */
213 iput(inode);
214 return NULL;
217 CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
218 iput(inode);
219 return inode;
222 /* the CONTROL inode is made without asking attributes from Venus */
223 int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
225 int error = 0;
227 *inode = iget(sb, CTL_INO);
228 if ( *inode ) {
229 (*inode)->i_op = &coda_ioctl_inode_operations;
230 (*inode)->i_mode = 00444;
231 error = 0;
232 } else {
233 error = -ENOMEM;
236 return error;