aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/inode.c')
-rw-r--r--fs/afs/inode.c107
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
27struct afs_iget_data { 24struct 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 */
95static 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 */
113static int afs_iget5_test(struct inode *inode, void *opaque) 91static 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 */
140inline int afs_iget(struct super_block *sb, struct afs_fid *fid, 118inline 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 */
201bad_inode: 174bad_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:
213int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, 186int 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);