diff options
Diffstat (limited to 'fs/afs/inode.c')
-rw-r--r-- | fs/afs/inode.c | 107 |
1 files changed, 34 insertions, 73 deletions
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 900c8bb1c3b8..18863315211f 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -19,9 +19,6 @@ | |||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/pagemap.h> | 21 | #include <linux/pagemap.h> |
22 | #include "volume.h" | ||
23 | #include "vnode.h" | ||
24 | #include "super.h" | ||
25 | #include "internal.h" | 22 | #include "internal.h" |
26 | 23 | ||
27 | struct afs_iget_data { | 24 | struct afs_iget_data { |
@@ -40,7 +37,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode) | |||
40 | vnode->status.type, | 37 | vnode->status.type, |
41 | vnode->status.nlink, | 38 | vnode->status.nlink, |
42 | vnode->status.size, | 39 | vnode->status.size, |
43 | vnode->status.version, | 40 | vnode->status.data_version, |
44 | vnode->status.mode); | 41 | vnode->status.mode); |
45 | 42 | ||
46 | switch (vnode->status.type) { | 43 | switch (vnode->status.type) { |
@@ -78,7 +75,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode) | |||
78 | if (vnode->status.type == AFS_FTYPE_SYMLINK) { | 75 | if (vnode->status.type == AFS_FTYPE_SYMLINK) { |
79 | afs_mntpt_check_symlink(vnode); | 76 | afs_mntpt_check_symlink(vnode); |
80 | 77 | ||
81 | if (vnode->flags & AFS_VNODE_MOUNTPOINT) { | 78 | if (test_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags)) { |
82 | inode->i_mode = S_IFDIR | vnode->status.mode; | 79 | inode->i_mode = S_IFDIR | vnode->status.mode; |
83 | inode->i_op = &afs_mntpt_inode_operations; | 80 | inode->i_op = &afs_mntpt_inode_operations; |
84 | inode->i_fop = &afs_mntpt_file_operations; | 81 | inode->i_fop = &afs_mntpt_file_operations; |
@@ -89,25 +86,6 @@ static int afs_inode_map_status(struct afs_vnode *vnode) | |||
89 | } | 86 | } |
90 | 87 | ||
91 | /* | 88 | /* |
92 | * attempt to fetch the status of an inode, coelescing multiple simultaneous | ||
93 | * fetches | ||
94 | */ | ||
95 | static int afs_inode_fetch_status(struct inode *inode) | ||
96 | { | ||
97 | struct afs_vnode *vnode; | ||
98 | int ret; | ||
99 | |||
100 | vnode = AFS_FS_I(inode); | ||
101 | |||
102 | ret = afs_vnode_fetch_status(vnode); | ||
103 | |||
104 | if (ret == 0) | ||
105 | ret = afs_inode_map_status(vnode); | ||
106 | |||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * iget5() comparator | 89 | * iget5() comparator |
112 | */ | 90 | */ |
113 | static int afs_iget5_test(struct inode *inode, void *opaque) | 91 | static int afs_iget5_test(struct inode *inode, void *opaque) |
@@ -137,8 +115,7 @@ static int afs_iget5_set(struct inode *inode, void *opaque) | |||
137 | /* | 115 | /* |
138 | * inode retrieval | 116 | * inode retrieval |
139 | */ | 117 | */ |
140 | inline int afs_iget(struct super_block *sb, struct afs_fid *fid, | 118 | inline struct inode *afs_iget(struct super_block *sb, struct afs_fid *fid) |
141 | struct inode **_inode) | ||
142 | { | 119 | { |
143 | struct afs_iget_data data = { .fid = *fid }; | 120 | struct afs_iget_data data = { .fid = *fid }; |
144 | struct afs_super_info *as; | 121 | struct afs_super_info *as; |
@@ -155,20 +132,18 @@ inline int afs_iget(struct super_block *sb, struct afs_fid *fid, | |||
155 | &data); | 132 | &data); |
156 | if (!inode) { | 133 | if (!inode) { |
157 | _leave(" = -ENOMEM"); | 134 | _leave(" = -ENOMEM"); |
158 | return -ENOMEM; | 135 | return ERR_PTR(-ENOMEM); |
159 | } | 136 | } |
160 | 137 | ||
138 | _debug("GOT INODE %p { vl=%x vn=%x, u=%x }", | ||
139 | inode, fid->vid, fid->vnode, fid->unique); | ||
140 | |||
161 | vnode = AFS_FS_I(inode); | 141 | vnode = AFS_FS_I(inode); |
162 | 142 | ||
163 | /* deal with an existing inode */ | 143 | /* deal with an existing inode */ |
164 | if (!(inode->i_state & I_NEW)) { | 144 | if (!(inode->i_state & I_NEW)) { |
165 | ret = afs_vnode_fetch_status(vnode); | 145 | _leave(" = %p", inode); |
166 | if (ret == 0) | 146 | return inode; |
167 | *_inode = inode; | ||
168 | else | ||
169 | iput(inode); | ||
170 | _leave(" = %d", ret); | ||
171 | return ret; | ||
172 | } | 147 | } |
173 | 148 | ||
174 | #ifdef AFS_CACHING_SUPPORT | 149 | #ifdef AFS_CACHING_SUPPORT |
@@ -181,21 +156,19 @@ inline int afs_iget(struct super_block *sb, struct afs_fid *fid, | |||
181 | #endif | 156 | #endif |
182 | 157 | ||
183 | /* okay... it's a new inode */ | 158 | /* okay... it's a new inode */ |
184 | inode->i_flags |= S_NOATIME; | 159 | set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); |
185 | vnode->flags |= AFS_VNODE_CHANGED; | 160 | ret = afs_vnode_fetch_status(vnode); |
186 | ret = afs_inode_fetch_status(inode); | 161 | if (ret < 0) |
187 | if (ret<0) | 162 | goto bad_inode; |
163 | ret = afs_inode_map_status(vnode); | ||
164 | if (ret < 0) | ||
188 | goto bad_inode; | 165 | goto bad_inode; |
189 | 166 | ||
190 | /* success */ | 167 | /* success */ |
168 | inode->i_flags |= S_NOATIME; | ||
191 | unlock_new_inode(inode); | 169 | unlock_new_inode(inode); |
192 | 170 | _leave(" = %p [CB { v=%u t=%u }]", inode, vnode->cb_version, vnode->cb_type); | |
193 | *_inode = inode; | 171 | return inode; |
194 | _leave(" = 0 [CB { v=%u x=%lu t=%u }]", | ||
195 | vnode->cb_version, | ||
196 | vnode->cb_timeout.timo_jif, | ||
197 | vnode->cb_type); | ||
198 | return 0; | ||
199 | 172 | ||
200 | /* failure */ | 173 | /* failure */ |
201 | bad_inode: | 174 | bad_inode: |
@@ -204,7 +177,7 @@ bad_inode: | |||
204 | iput(inode); | 177 | iput(inode); |
205 | 178 | ||
206 | _leave(" = %d [bad]", ret); | 179 | _leave(" = %d [bad]", ret); |
207 | return ret; | 180 | return ERR_PTR(ret); |
208 | } | 181 | } |
209 | 182 | ||
210 | /* | 183 | /* |
@@ -213,36 +186,13 @@ bad_inode: | |||
213 | int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, | 186 | int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, |
214 | struct kstat *stat) | 187 | struct kstat *stat) |
215 | { | 188 | { |
216 | struct afs_vnode *vnode; | ||
217 | struct inode *inode; | 189 | struct inode *inode; |
218 | int ret; | ||
219 | 190 | ||
220 | inode = dentry->d_inode; | 191 | inode = dentry->d_inode; |
221 | 192 | ||
222 | _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version); | 193 | _enter("{ ino=%lu v=%lu }", inode->i_ino, inode->i_version); |
223 | 194 | ||
224 | vnode = AFS_FS_I(inode); | ||
225 | |||
226 | ret = afs_inode_fetch_status(inode); | ||
227 | if (ret == -ENOENT) { | ||
228 | _leave(" = %d [%d %p]", | ||
229 | ret, atomic_read(&dentry->d_count), dentry->d_inode); | ||
230 | return ret; | ||
231 | } else if (ret < 0) { | ||
232 | make_bad_inode(inode); | ||
233 | _leave(" = %d", ret); | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | /* transfer attributes from the inode structure to the stat | ||
238 | * structure */ | ||
239 | generic_fillattr(inode, stat); | 195 | generic_fillattr(inode, stat); |
240 | |||
241 | _leave(" = 0 CB { v=%u x=%u t=%u }", | ||
242 | vnode->cb_version, | ||
243 | vnode->cb_expiry, | ||
244 | vnode->cb_type); | ||
245 | |||
246 | return 0; | 196 | return 0; |
247 | } | 197 | } |
248 | 198 | ||
@@ -260,12 +210,23 @@ void afs_clear_inode(struct inode *inode) | |||
260 | vnode->fid.vnode, | 210 | vnode->fid.vnode, |
261 | vnode->cb_version, | 211 | vnode->cb_version, |
262 | vnode->cb_expiry, | 212 | vnode->cb_expiry, |
263 | vnode->cb_type | 213 | vnode->cb_type); |
264 | ); | ||
265 | 214 | ||
266 | BUG_ON(inode->i_ino != vnode->fid.vnode); | 215 | _debug("CLEAR INODE %p", inode); |
216 | |||
217 | ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode); | ||
218 | |||
219 | afs_give_up_callback(vnode); | ||
220 | |||
221 | if (vnode->server) { | ||
222 | spin_lock(&vnode->server->fs_lock); | ||
223 | rb_erase(&vnode->server_rb, &vnode->server->fs_vnodes); | ||
224 | spin_unlock(&vnode->server->fs_lock); | ||
225 | afs_put_server(vnode->server); | ||
226 | vnode->server = NULL; | ||
227 | } | ||
267 | 228 | ||
268 | afs_vnode_give_up_callback(vnode); | 229 | ASSERT(!vnode->cb_promised); |
269 | 230 | ||
270 | #ifdef AFS_CACHING_SUPPORT | 231 | #ifdef AFS_CACHING_SUPPORT |
271 | cachefs_relinquish_cookie(vnode->cache, 0); | 232 | cachefs_relinquish_cookie(vnode->cache, 0); |