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;
16 inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
18 if (fid1->Vnode != fid2->Vnode) return 0;
19 if (fid1->Volume != fid2->Volume) return 0;
20 if (fid1->Unique != fid2->Unique) return 0;
24 inline int coda_isnullfid(ViceFid *fid)
26 if (fid->Vnode || fid->Volume || fid->Unique) return 0;
30 static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque)
32 return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid)));
35 static struct inode_operations coda_symlink_inode_operations = {
36 readlink: page_readlink,
37 follow_link: page_follow_link,
38 setattr: coda_notify_change,
42 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
44 CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
46 if (coda_debug & D_SUPER )
49 coda_vattr_to_iattr(inode, attr);
51 if (S_ISREG(inode->i_mode)) {
52 inode->i_op = &coda_file_inode_operations;
53 inode->i_fop = &coda_file_operations;
54 } else if (S_ISDIR(inode->i_mode)) {
55 inode->i_op = &coda_dir_inode_operations;
56 inode->i_fop = &coda_dir_operations;
57 } else if (S_ISLNK(inode->i_mode)) {
58 inode->i_op = &coda_symlink_inode_operations;
59 inode->i_data.a_ops = &coda_symlink_aops;
60 inode->i_mapping = &inode->i_data;
62 init_special_inode(inode, inode->i_mode, attr->va_rdev);
65 struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
66 struct coda_vattr * attr)
69 struct coda_inode_info *cii;
70 ino_t ino = coda_f2i(fid);
71 struct coda_sb_info *sbi = coda_sbp(sb);
73 down(&sbi->sbi_iget4_mutex);
74 inode = iget4(sb, ino, coda_inocmp, fid);
77 CDEBUG(D_CNODE, "coda_iget: no inode\n");
78 up(&sbi->sbi_iget4_mutex);
79 return ERR_PTR(-ENOMEM);
82 /* check if the inode is already initialized */
84 if (coda_isnullfid(&cii->c_fid))
85 /* new, empty inode found... initializing */
87 up(&sbi->sbi_iget4_mutex);
89 /* always replace the attributes, type might have changed */
90 coda_fill_inode(inode, attr);
94 /* this is effectively coda_iget:
95 - get attributes (might be cached)
96 - get the inode for the fid using vfs iget
97 - link the two up if this is needed
98 - fill in the attributes
100 int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
102 struct coda_vattr attr;
105 /* We get inode numbers from Venus -- see venus source */
106 error = venus_getattr(sb, fid, &attr);
109 "coda_cnode_make: coda_getvattr returned %d for %s.\n",
110 error, coda_f2s(fid));
115 *inode = coda_iget(sb, fid, &attr);
116 if ( IS_ERR(*inode) ) {
117 printk("coda_cnode_make: coda_iget failed\n");
118 return PTR_ERR(*inode);
121 CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
122 (*inode)->i_ino, atomic_read(&(*inode)->i_count),
123 coda_f2s(&ITOC(*inode)->c_fid));
128 void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
129 struct ViceFid *newfid)
131 struct coda_inode_info *cii;
135 if (!coda_fideq(&cii->c_fid, oldfid))
138 /* replace fid and rehash inode */
139 /* XXX we probably need to hold some lock here! */
140 remove_inode_hash(inode);
141 cii->c_fid = *newfid;
142 inode->i_ino = coda_f2i(newfid);
143 insert_inode_hash(inode);
146 /* convert a fid to an inode. */
147 struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
151 struct coda_inode_info *cii;
152 struct coda_sb_info *sbi;
155 printk("coda_fid_to_inode: no sb!\n");
159 CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
163 down(&sbi->sbi_iget4_mutex);
164 inode = iget4(sb, nr, coda_inocmp, fid);
166 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
173 /* The inode could already be purged due to memory pressure */
174 if (coda_isnullfid(&cii->c_fid)) {
180 CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
181 up(&sbi->sbi_iget4_mutex);
185 up(&sbi->sbi_iget4_mutex);
189 /* the CONTROL inode is made without asking attributes from Venus */
190 int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
194 *inode = iget(sb, CTL_INO);
196 (*inode)->i_op = &coda_ioctl_inode_operations;
197 (*inode)->i_fop = &coda_ioctl_operations;
198 (*inode)->i_mode = 0444;