File: /usr/src/linux/fs/coda/cnode.c
1 /* cnode related routines for the coda kernel code
2 (C) 1996 Peter Braam
3 */
4
5 #include <linux/types.h>
6 #include <linux/string.h>
7 #include <linux/time.h>
8
9 #include <linux/coda.h>
10 #include <linux/coda_linux.h>
11 #include <linux/coda_fs_i.h>
12 #include <linux/coda_psdev.h>
13
14 extern int coda_debug;
15 extern int coda_print_entry;
16
17 inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
18 {
19 if (fid1->Vnode != fid2->Vnode) return 0;
20 if (fid1->Volume != fid2->Volume) return 0;
21 if (fid1->Unique != fid2->Unique) return 0;
22 return 1;
23 }
24
25 inline int coda_isnullfid(ViceFid *fid)
26 {
27 if (fid->Vnode || fid->Volume || fid->Unique) return 0;
28 return 1;
29 }
30
31 static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque)
32 {
33 return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid)));
34 }
35
36 static struct inode_operations coda_symlink_inode_operations = {
37 readlink: page_readlink,
38 follow_link: page_follow_link,
39 setattr: coda_notify_change,
40 };
41
42 /* cnode.c */
43 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
44 {
45 CDEBUG(D_SUPER, "ino: %ld\n", inode->i_ino);
46
47 if (coda_debug & D_SUPER )
48 print_vattr(attr);
49
50 coda_vattr_to_iattr(inode, attr);
51
52 if (S_ISREG(inode->i_mode)) {
53 inode->i_op = &coda_file_inode_operations;
54 inode->i_fop = &coda_file_operations;
55 } else if (S_ISDIR(inode->i_mode)) {
56 inode->i_op = &coda_dir_inode_operations;
57 inode->i_fop = &coda_dir_operations;
58 } else if (S_ISLNK(inode->i_mode)) {
59 inode->i_op = &coda_symlink_inode_operations;
60 inode->i_data.a_ops = &coda_symlink_aops;
61 inode->i_mapping = &inode->i_data;
62 } else
63 init_special_inode(inode, inode->i_mode, attr->va_rdev);
64 }
65
66 struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
67 struct coda_vattr * attr)
68 {
69 struct inode *inode;
70 struct coda_inode_info *cii;
71 ino_t ino = coda_f2i(fid);
72
73 inode = iget4(sb, ino, coda_inocmp, fid);
74
75 if ( !inode ) {
76 CDEBUG(D_CNODE, "coda_iget: no inode\n");
77 return ERR_PTR(-ENOMEM);
78 }
79
80 /* check if the inode is already initialized */
81 cii = ITOC(inode);
82 if (coda_isnullfid(&cii->c_fid))
83 /* new, empty inode found... initializing */
84 cii->c_fid = *fid;
85
86 /* we shouldnt see inode collisions anymore */
87 if (!coda_fideq(fid, &cii->c_fid)) BUG();
88
89 /* always replace the attributes, type might have changed */
90 coda_fill_inode(inode, attr);
91 return inode;
92 }
93
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
99 */
100 int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
101 {
102 struct coda_vattr attr;
103 int error;
104
105 ENTRY;
106
107 /* We get inode numbers from Venus -- see venus source */
108 error = venus_getattr(sb, fid, &attr);
109 if ( error ) {
110 CDEBUG(D_CNODE,
111 "coda_cnode_make: coda_getvattr returned %d for %s.\n",
112 error, coda_f2s(fid));
113 *inode = NULL;
114 EXIT;
115 return error;
116 }
117
118 *inode = coda_iget(sb, fid, &attr);
119 if ( IS_ERR(*inode) ) {
120 printk("coda_cnode_make: coda_iget failed\n");
121 EXIT;
122 return PTR_ERR(*inode);
123 }
124
125 CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
126 (*inode)->i_ino, atomic_read(&(*inode)->i_count),
127 coda_f2s(&ITOC(*inode)->c_fid));
128 EXIT;
129 return 0;
130 }
131
132
133 void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
134 struct ViceFid *newfid)
135 {
136 struct coda_inode_info *cii;
137
138 cii = ITOC(inode);
139
140 if (!coda_fideq(&cii->c_fid, oldfid))
141 BUG();
142
143 /* replace fid and rehash inode */
144 /* XXX we probably need to hold some lock here! */
145 remove_inode_hash(inode);
146 cii->c_fid = *newfid;
147 inode->i_ino = coda_f2i(newfid);
148 insert_inode_hash(inode);
149 }
150
151 /* convert a fid to an inode. */
152 struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb)
153 {
154 ino_t nr;
155 struct inode *inode;
156 struct coda_inode_info *cii;
157 ENTRY;
158
159 if ( !sb ) {
160 printk("coda_fid_to_inode: no sb!\n");
161 return NULL;
162 }
163
164 CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
165
166 nr = coda_f2i(fid);
167 inode = iget4(sb, nr, coda_inocmp, fid);
168 if ( !inode ) {
169 printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.\n",
170 sb, (long)nr);
171 return NULL;
172 }
173
174 cii = ITOC(inode);
175
176 /* The inode could already be purged due to memory pressure */
177 if (coda_isnullfid(&cii->c_fid)) {
178 inode->i_nlink = 0;
179 iput(inode);
180 return NULL;
181 }
182
183 /* we shouldn't see inode collisions anymore */
184 if ( !coda_fideq(fid, &cii->c_fid) ) BUG();
185
186 CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
187 return inode;
188 }
189
190 /* the CONTROL inode is made without asking attributes from Venus */
191 int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
192 {
193 int error = 0;
194
195 *inode = iget(sb, CTL_INO);
196 if ( *inode ) {
197 (*inode)->i_op = &coda_ioctl_inode_operations;
198 (*inode)->i_fop = &coda_ioctl_operations;
199 (*inode)->i_mode = 0444;
200 error = 0;
201 } else {
202 error = -ENOMEM;
203 }
204
205 return error;
206 }
207
208