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 inline int coda_fideq(ViceFid
*fid1
, ViceFid
*fid2
)
16 if (fid1
->Vnode
!= fid2
->Vnode
) return 0;
17 if (fid1
->Volume
!= fid2
->Volume
) return 0;
18 if (fid1
->Unique
!= fid2
->Unique
) return 0;
22 inline int coda_isnullfid(ViceFid
*fid
)
24 if (fid
->Vnode
|| fid
->Volume
|| fid
->Unique
) return 0;
28 static struct inode_operations coda_symlink_inode_operations
= {
29 .readlink
= page_readlink
,
30 .follow_link
= page_follow_link
,
31 .setattr
= coda_setattr
,
35 static void coda_fill_inode(struct inode
*inode
, struct coda_vattr
*attr
)
37 coda_vattr_to_iattr(inode
, attr
);
39 if (S_ISREG(inode
->i_mode
)) {
40 inode
->i_op
= &coda_file_inode_operations
;
41 inode
->i_fop
= &coda_file_operations
;
42 } else if (S_ISDIR(inode
->i_mode
)) {
43 inode
->i_op
= &coda_dir_inode_operations
;
44 inode
->i_fop
= &coda_dir_operations
;
45 } else if (S_ISLNK(inode
->i_mode
)) {
46 inode
->i_op
= &coda_symlink_inode_operations
;
47 inode
->i_data
.a_ops
= &coda_symlink_aops
;
48 inode
->i_mapping
= &inode
->i_data
;
50 init_special_inode(inode
, inode
->i_mode
, attr
->va_rdev
);
53 static int coda_test_inode(struct inode
*inode
, void *data
)
55 ViceFid
*fid
= (ViceFid
*)data
;
56 return coda_fideq(&(ITOC(inode
)->c_fid
), fid
);
59 static int coda_set_inode(struct inode
*inode
, void *data
)
61 ViceFid
*fid
= (ViceFid
*)data
;
62 ITOC(inode
)->c_fid
= *fid
;
66 static int coda_fail_inode(struct inode
*inode
, void *data
)
71 struct inode
* coda_iget(struct super_block
* sb
, ViceFid
* fid
,
72 struct coda_vattr
* attr
)
75 struct coda_inode_info
*cii
;
76 struct coda_sb_info
*sbi
= coda_sbp(sb
);
77 unsigned long hash
= coda_f2i(fid
);
79 inode
= iget5_locked(sb
, hash
, coda_test_inode
, coda_set_inode
, fid
);
82 return ERR_PTR(-ENOMEM
);
84 if (inode
->i_state
& I_NEW
) {
86 /* we still need to set i_ino for things like stat(2) */
89 list_add(&cii
->c_cilist
, &sbi
->sbi_cihead
);
90 unlock_new_inode(inode
);
93 /* always replace the attributes, type might have changed */
94 coda_fill_inode(inode
, attr
);
98 /* this is effectively coda_iget:
99 - get attributes (might be cached)
100 - get the inode for the fid using vfs iget
101 - link the two up if this is needed
102 - fill in the attributes
104 int coda_cnode_make(struct inode
**inode
, ViceFid
*fid
, struct super_block
*sb
)
106 struct coda_vattr attr
;
109 /* We get inode numbers from Venus -- see venus source */
110 error
= venus_getattr(sb
, fid
, &attr
);
116 *inode
= coda_iget(sb
, fid
, &attr
);
117 if ( IS_ERR(*inode
) ) {
118 printk("coda_cnode_make: coda_iget failed\n");
119 return PTR_ERR(*inode
);
125 void coda_replace_fid(struct inode
*inode
, struct ViceFid
*oldfid
,
126 struct ViceFid
*newfid
)
128 struct coda_inode_info
*cii
;
129 unsigned long hash
= coda_f2i(newfid
);
133 if (!coda_fideq(&cii
->c_fid
, oldfid
))
136 /* replace fid and rehash inode */
137 /* XXX we probably need to hold some lock here! */
138 remove_inode_hash(inode
);
139 cii
->c_fid
= *newfid
;
141 __insert_inode_hash(inode
, hash
);
144 /* convert a fid to an inode. */
145 struct inode
*coda_fid_to_inode(ViceFid
*fid
, struct super_block
*sb
)
148 unsigned long hash
= coda_f2i(fid
);
151 printk("coda_fid_to_inode: no sb!\n");
155 inode
= iget5_locked(sb
, hash
, coda_test_inode
, coda_fail_inode
, fid
);
159 /* we should never see newly created inodes because we intentionally
160 * fail in the initialization callback */
161 BUG_ON(inode
->i_state
& I_NEW
);
166 /* the CONTROL inode is made without asking attributes from Venus */
167 int coda_cnode_makectl(struct inode
**inode
, struct super_block
*sb
)
171 *inode
= new_inode(sb
);
173 (*inode
)->i_ino
= CTL_INO
;
174 (*inode
)->i_op
= &coda_ioctl_inode_operations
;
175 (*inode
)->i_fop
= &coda_ioctl_operations
;
176 (*inode
)->i_mode
= 0444;