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.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 18863315211f..227336228299 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -29,7 +29,7 @@ struct afs_iget_data {
29/* 29/*
30 * map the AFS file status to the inode member variables 30 * map the AFS file status to the inode member variables
31 */ 31 */
32static int afs_inode_map_status(struct afs_vnode *vnode) 32static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
33{ 33{
34 struct inode *inode = AFS_VNODE_TO_I(vnode); 34 struct inode *inode = AFS_VNODE_TO_I(vnode);
35 35
@@ -44,7 +44,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode)
44 case AFS_FTYPE_FILE: 44 case AFS_FTYPE_FILE:
45 inode->i_mode = S_IFREG | vnode->status.mode; 45 inode->i_mode = S_IFREG | vnode->status.mode;
46 inode->i_op = &afs_file_inode_operations; 46 inode->i_op = &afs_file_inode_operations;
47 inode->i_fop = &generic_ro_fops; 47 inode->i_fop = &afs_file_operations;
48 break; 48 break;
49 case AFS_FTYPE_DIR: 49 case AFS_FTYPE_DIR:
50 inode->i_mode = S_IFDIR | vnode->status.mode; 50 inode->i_mode = S_IFDIR | vnode->status.mode;
@@ -73,7 +73,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode)
73 73
74 /* check to see whether a symbolic link is really a mountpoint */ 74 /* check to see whether a symbolic link is really a mountpoint */
75 if (vnode->status.type == AFS_FTYPE_SYMLINK) { 75 if (vnode->status.type == AFS_FTYPE_SYMLINK) {
76 afs_mntpt_check_symlink(vnode); 76 afs_mntpt_check_symlink(vnode, key);
77 77
78 if (test_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags)) { 78 if (test_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags)) {
79 inode->i_mode = S_IFDIR | vnode->status.mode; 79 inode->i_mode = S_IFDIR | vnode->status.mode;
@@ -115,7 +115,8 @@ static int afs_iget5_set(struct inode *inode, void *opaque)
115/* 115/*
116 * inode retrieval 116 * inode retrieval
117 */ 117 */
118inline struct inode *afs_iget(struct super_block *sb, struct afs_fid *fid) 118inline struct inode *afs_iget(struct super_block *sb, struct key *key,
119 struct afs_fid *fid)
119{ 120{
120 struct afs_iget_data data = { .fid = *fid }; 121 struct afs_iget_data data = { .fid = *fid };
121 struct afs_super_info *as; 122 struct afs_super_info *as;
@@ -157,10 +158,10 @@ inline struct inode *afs_iget(struct super_block *sb, struct afs_fid *fid)
157 158
158 /* okay... it's a new inode */ 159 /* okay... it's a new inode */
159 set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); 160 set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
160 ret = afs_vnode_fetch_status(vnode); 161 ret = afs_vnode_fetch_status(vnode, NULL, key);
161 if (ret < 0) 162 if (ret < 0)
162 goto bad_inode; 163 goto bad_inode;
163 ret = afs_inode_map_status(vnode); 164 ret = afs_inode_map_status(vnode, key);
164 if (ret < 0) 165 if (ret < 0)
165 goto bad_inode; 166 goto bad_inode;
166 167
@@ -201,6 +202,7 @@ int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
201 */ 202 */
202void afs_clear_inode(struct inode *inode) 203void afs_clear_inode(struct inode *inode)
203{ 204{
205 struct afs_permits *permits;
204 struct afs_vnode *vnode; 206 struct afs_vnode *vnode;
205 207
206 vnode = AFS_FS_I(inode); 208 vnode = AFS_FS_I(inode);
@@ -233,5 +235,12 @@ void afs_clear_inode(struct inode *inode)
233 vnode->cache = NULL; 235 vnode->cache = NULL;
234#endif 236#endif
235 237
238 mutex_lock(&vnode->permits_lock);
239 permits = vnode->permits;
240 rcu_assign_pointer(vnode->permits, NULL);
241 mutex_unlock(&vnode->permits_lock);
242 if (permits)
243 call_rcu(&permits->rcu, afs_zap_permits);
244
236 _leave(""); 245 _leave("");
237} 246}