1 /* cnode related routines for the coda kernel code
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 inline int coda_fideq(ViceFid
*fid1
, ViceFid
*fid2
)
19 if (fid1
->Vnode
!= fid2
->Vnode
)
21 if (fid1
->Volume
!= fid2
->Volume
)
23 if (fid1
->Unique
!= fid2
->Unique
)
28 static struct inode_operations coda_symlink_inode_operations
= {
29 readlink
: page_readlink
,
30 follow_link
: page_follow_link
,
31 setattr
: coda_notify_change
,
35 static void coda_fill_inode(struct inode
*inode
, struct coda_vattr
*attr
)
37 CDEBUG(D_SUPER
, "ino: %ld\n", inode
->i_ino
);
39 if (coda_debug
& D_SUPER
)
42 coda_vattr_to_iattr(inode
, attr
);
44 if (S_ISREG(inode
->i_mode
)) {
45 inode
->i_op
= &coda_file_inode_operations
;
46 inode
->i_fop
= &coda_file_operations
;
47 } else if (S_ISDIR(inode
->i_mode
)) {
48 inode
->i_op
= &coda_dir_inode_operations
;
49 inode
->i_fop
= &coda_dir_operations
;
50 } else if (S_ISLNK(inode
->i_mode
)) {
51 inode
->i_op
= &coda_symlink_inode_operations
;
52 inode
->i_data
.a_ops
= &coda_symlink_aops
;
53 inode
->i_mapping
= &inode
->i_data
;
55 init_special_inode(inode
, inode
->i_mode
, attr
->va_rdev
);
58 struct inode
* coda_iget(struct super_block
* sb
, ViceFid
* fid
,
59 struct coda_vattr
* attr
)
62 struct coda_sb_info
*sbi
= coda_sbp(sb
);
63 struct coda_inode_info
*cii
;
64 ino_t ino
= attr
->va_fileid
;
66 inode
= iget(sb
, ino
);
68 CDEBUG(D_CNODE
, "coda_iget: no inode\n");
69 return ERR_PTR(-ENOMEM
);
72 /* check if the inode is already initialized */
74 if (cii
->c_magic
== CODA_CNODE_MAGIC
) {
75 /* see if it is the right one (might have an inode collision) */
76 if ( !coda_fideq(fid
, &cii
->c_fid
) ) {
77 printk("coda_iget: initialized inode old %s new %s!\n",
78 coda_f2s(&cii
->c_fid
), coda_f2s2(fid
));
80 return ERR_PTR(-ENOENT
);
82 /* replace the attributes, type might have changed */
83 coda_fill_inode(inode
, attr
);
87 /* new, empty inode found... initializing */
89 /* Initialize the Coda inode info structure */
90 memset(cii
, 0, (int) sizeof(struct coda_inode_info
));
91 cii
->c_magic
= CODA_CNODE_MAGIC
;
95 INIT_LIST_HEAD(&(cii
->c_cnhead
));
96 INIT_LIST_HEAD(&(cii
->c_volrootlist
));
98 coda_fill_inode(inode
, attr
);
100 /* check if it is a weird fid (hashed fid != ino), f.i mountpoints
101 repair object, expanded local-global conflict trees, etc.
103 if ( coda_f2i(fid
) == ino
)
106 /* check if we expected this weird fid */
107 if ( !coda_fid_is_weird(fid
) ) {
108 printk("Coda: unknown weird fid: ino %ld, fid %s."
109 "Tell Peter.\n", (long)ino
, coda_f2s(&cii
->c_fid
));
113 /* add the inode to a global list so we can find it back later */
114 list_add(&cii
->c_volrootlist
, &sbi
->sbi_volroothead
);
115 CDEBUG(D_CNODE
, "Added %ld, %s to volroothead\n",
116 (long)ino
, coda_f2s(&cii
->c_fid
));
121 /* this is effectively coda_iget:
122 - get attributes (might be cached)
123 - get the inode for the fid using vfs iget
124 - link the two up if this is needed
125 - fill in the attributes
127 int coda_cnode_make(struct inode
**inode
, ViceFid
*fid
, struct super_block
*sb
)
129 struct coda_vattr attr
;
134 /* We get inode numbers from Venus -- see venus source */
136 error
= venus_getattr(sb
, fid
, &attr
);
139 "coda_cnode_make: coda_getvattr returned %d for %s.\n",
140 error
, coda_f2s(fid
));
146 *inode
= coda_iget(sb
, fid
, &attr
);
147 if ( IS_ERR(*inode
) ) {
148 printk("coda_cnode_make: coda_iget failed\n");
150 return PTR_ERR(*inode
);
153 CDEBUG(D_DOWNCALL
, "Done making inode: ino %ld, count %d with %s\n",
154 (*inode
)->i_ino
, atomic_read(&(*inode
)->i_count
),
155 coda_f2s(&(*inode
)->u
.coda_i
.c_fid
));
161 void coda_replace_fid(struct inode
*inode
, struct ViceFid
*oldfid
,
162 struct ViceFid
*newfid
)
164 struct coda_inode_info
*cnp
;
165 struct coda_sb_info
*sbi
= coda_sbp(inode
->i_sb
);
169 if ( ! coda_fideq(&cnp
->c_fid
, oldfid
) )
170 printk("What? oldfid != cnp->c_fid. Call 911.\n");
172 cnp
->c_fid
= *newfid
;
174 list_del(&cnp
->c_volrootlist
);
175 INIT_LIST_HEAD(&cnp
->c_volrootlist
);
176 if ( coda_fid_is_weird(newfid
) )
177 list_add(&cnp
->c_volrootlist
, &sbi
->sbi_volroothead
);
185 /* convert a fid to an inode. Mostly we can compute
186 the inode number from the FID, but not for volume
187 mount points: those are in a list */
188 struct inode
*coda_fid_to_inode(ViceFid
*fid
, struct super_block
*sb
)
192 struct coda_inode_info
*cii
;
196 printk("coda_fid_to_inode: no sb!\n");
201 printk("coda_fid_to_inode: no fid!\n");
204 CDEBUG(D_INODE
, "%s\n", coda_f2s(fid
));
207 if ( coda_fid_is_weird(fid
) ) {
208 struct list_head
*lh
, *le
;
209 struct coda_sb_info
*sbi
= coda_sbp(sb
);
210 le
= lh
= &sbi
->sbi_volroothead
;
212 while ( (le
= le
->next
) != lh
) {
213 cii
= list_entry(le
, struct coda_inode_info
,
215 /* paranoia check, should never trigger */
216 if ( cii
->c_magic
!= CODA_CNODE_MAGIC
)
217 printk("coda_fid_to_inode: Bad magic in inode %x.\n", cii
->c_magic
);
219 CDEBUG(D_DOWNCALL
, "iterating, now doing %s, ino %ld\n",
220 coda_f2s(&cii
->c_fid
), cii
->c_vnode
->i_ino
);
222 if ( coda_fideq(&cii
->c_fid
, fid
) ) {
223 inode
= cii
->c_vnode
;
224 CDEBUG(D_INODE
, "volume root, found %ld\n", inode
->i_ino
);
225 iget(sb
, inode
->i_ino
);
232 /* fid is not weird: ino should be computable */
234 inode
= iget(sb
, nr
);
236 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
241 /* check if this inode is linked to a cnode */
243 if ( cii
->c_magic
!= CODA_CNODE_MAGIC
) {
244 CDEBUG(D_INODE
, "uninitialized inode. Return.\n");
248 /* make sure fid is the one we want */
249 if ( !coda_fideq(fid
, &(cii
->c_fid
)) ) {
251 printk("coda_fid2inode: bad cnode (ino %ld, fid %s)", nr
,
257 CDEBUG(D_INODE
, "found %ld\n", inode
->i_ino
);
265 /* the CONTROL inode is made without asking attributes from Venus */
266 int coda_cnode_makectl(struct inode
**inode
, struct super_block
*sb
)
270 *inode
= iget(sb
, CTL_INO
);
272 (*inode
)->i_op
= &coda_ioctl_inode_operations
;
273 (*inode
)->i_fop
= &coda_ioctl_operations
;
274 (*inode
)->i_mode
= 00444;