1 /* cnode related routines for the coda kernel code
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
;
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
)
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
))
40 else if (S_ISSOCK(inode
->i_mode
))
43 printk ("coda_fill_inode: what's this? i_mode = %o\n",
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
;
66 * We get inode numbers from Venus -- see venus source
69 error
= venus_getattr(sb
, fid
, &attr
);
72 "coda_cnode_make: coda_getvattr returned %d for %s.\n",
73 error
, coda_f2s(fid
));
79 *inode
= iget(sb
, ino
);
81 printk("coda_cnode_make: iget failed\n");
86 if ( cnp
->c_magic
!= 0 ) {
87 printk("coda_cnode make on initialized inode %ld, old %s new
89 (*inode
)->i_ino
, coda_f2s(&cnp
->c_fid
), coda_f2s2(fid
));
94 memset(cnp
, 0, (int) sizeof(struct coda_inode_info
));
96 cnp
->c_magic
= CODA_CNODE_MAGIC
;
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
));
121 inline int coda_fideq(ViceFid
*fid1
, ViceFid
*fid2
)
124 eq
= ( (fid1
->Vnode
== fid2
->Vnode
) &&
125 (fid1
->Volume
== fid2
->Volume
) &&
126 (fid1
->Unique
== fid2
->Unique
) );
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
);
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
);
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
)
160 struct coda_inode_info
*cnp
;
165 printk("coda_fid_to_inode: no sb!\n");
170 printk("coda_fid_to_inode: no fid!\n");
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
,
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",
200 /* fid is not weird: ino should be computable */
202 inode
= iget(sb
, nr
);
204 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
209 /* check if this inode is linked to a cnode */
211 if ( cnp
->c_magic
!= CODA_CNODE_MAGIC
) {
212 CDEBUG(D_INODE
, "uninitialized inode. Return.\n");
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)); */
229 CDEBUG(D_INODE
, "found %ld\n", inode
->i_ino
);
234 /* the CONTROL inode is made without asking attributes from Venus */
235 int coda_cnode_makectl(struct inode
**inode
, struct super_block
*sb
)
239 *inode
= iget(sb
, CTL_INO
);
241 (*inode
)->i_op
= &coda_ioctl_inode_operations
;
242 (*inode
)->i_mode
= 00444;