diff options
Diffstat (limited to 'fs/afs/inode.c')
-rw-r--r-- | fs/afs/inode.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 1e4897a048d2..aae55dd15108 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -54,8 +54,21 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
54 | inode->i_fop = &afs_dir_file_operations; | 54 | inode->i_fop = &afs_dir_file_operations; |
55 | break; | 55 | break; |
56 | case AFS_FTYPE_SYMLINK: | 56 | case AFS_FTYPE_SYMLINK: |
57 | inode->i_mode = S_IFLNK | vnode->status.mode; | 57 | /* Symlinks with a mode of 0644 are actually mountpoints. */ |
58 | inode->i_op = &page_symlink_inode_operations; | 58 | if ((vnode->status.mode & 0777) == 0644) { |
59 | inode->i_flags |= S_AUTOMOUNT; | ||
60 | |||
61 | spin_lock(&vnode->lock); | ||
62 | set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags); | ||
63 | spin_unlock(&vnode->lock); | ||
64 | |||
65 | inode->i_mode = S_IFDIR | 0555; | ||
66 | inode->i_op = &afs_mntpt_inode_operations; | ||
67 | inode->i_fop = &afs_mntpt_file_operations; | ||
68 | } else { | ||
69 | inode->i_mode = S_IFLNK | vnode->status.mode; | ||
70 | inode->i_op = &page_symlink_inode_operations; | ||
71 | } | ||
59 | inode_nohighmem(inode); | 72 | inode_nohighmem(inode); |
60 | break; | 73 | break; |
61 | default: | 74 | default: |
@@ -70,27 +83,15 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) | |||
70 | 83 | ||
71 | set_nlink(inode, vnode->status.nlink); | 84 | set_nlink(inode, vnode->status.nlink); |
72 | inode->i_uid = vnode->status.owner; | 85 | inode->i_uid = vnode->status.owner; |
73 | inode->i_gid = GLOBAL_ROOT_GID; | 86 | inode->i_gid = vnode->status.group; |
74 | inode->i_size = vnode->status.size; | 87 | inode->i_size = vnode->status.size; |
75 | inode->i_ctime.tv_sec = vnode->status.mtime_server; | 88 | inode->i_ctime.tv_sec = vnode->status.mtime_client; |
76 | inode->i_ctime.tv_nsec = 0; | 89 | inode->i_ctime.tv_nsec = 0; |
77 | inode->i_atime = inode->i_mtime = inode->i_ctime; | 90 | inode->i_atime = inode->i_mtime = inode->i_ctime; |
78 | inode->i_blocks = 0; | 91 | inode->i_blocks = 0; |
79 | inode->i_generation = vnode->fid.unique; | 92 | inode->i_generation = vnode->fid.unique; |
80 | inode->i_version = vnode->status.data_version; | 93 | inode->i_version = vnode->status.data_version; |
81 | inode->i_mapping->a_ops = &afs_fs_aops; | 94 | inode->i_mapping->a_ops = &afs_fs_aops; |
82 | |||
83 | /* check to see whether a symbolic link is really a mountpoint */ | ||
84 | if (vnode->status.type == AFS_FTYPE_SYMLINK) { | ||
85 | afs_mntpt_check_symlink(vnode, key); | ||
86 | |||
87 | if (test_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags)) { | ||
88 | inode->i_mode = S_IFDIR | vnode->status.mode; | ||
89 | inode->i_op = &afs_mntpt_inode_operations; | ||
90 | inode->i_fop = &afs_mntpt_file_operations; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | return 0; | 95 | return 0; |
95 | } | 96 | } |
96 | 97 | ||
@@ -245,12 +246,13 @@ struct inode *afs_iget(struct super_block *sb, struct key *key, | |||
245 | vnode->cb_version = 0; | 246 | vnode->cb_version = 0; |
246 | vnode->cb_expiry = 0; | 247 | vnode->cb_expiry = 0; |
247 | vnode->cb_type = 0; | 248 | vnode->cb_type = 0; |
248 | vnode->cb_expires = get_seconds(); | 249 | vnode->cb_expires = ktime_get_real_seconds(); |
249 | } else { | 250 | } else { |
250 | vnode->cb_version = cb->version; | 251 | vnode->cb_version = cb->version; |
251 | vnode->cb_expiry = cb->expiry; | 252 | vnode->cb_expiry = cb->expiry; |
252 | vnode->cb_type = cb->type; | 253 | vnode->cb_type = cb->type; |
253 | vnode->cb_expires = vnode->cb_expiry + get_seconds(); | 254 | vnode->cb_expires = vnode->cb_expiry + |
255 | ktime_get_real_seconds(); | ||
254 | } | 256 | } |
255 | } | 257 | } |
256 | 258 | ||
@@ -323,7 +325,7 @@ int afs_validate(struct afs_vnode *vnode, struct key *key) | |||
323 | !test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags) && | 325 | !test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags) && |
324 | !test_bit(AFS_VNODE_MODIFIED, &vnode->flags) && | 326 | !test_bit(AFS_VNODE_MODIFIED, &vnode->flags) && |
325 | !test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { | 327 | !test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) { |
326 | if (vnode->cb_expires < get_seconds() + 10) { | 328 | if (vnode->cb_expires < ktime_get_real_seconds() + 10) { |
327 | _debug("callback expired"); | 329 | _debug("callback expired"); |
328 | set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); | 330 | set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); |
329 | } else { | 331 | } else { |
@@ -444,7 +446,7 @@ void afs_evict_inode(struct inode *inode) | |||
444 | 446 | ||
445 | mutex_lock(&vnode->permits_lock); | 447 | mutex_lock(&vnode->permits_lock); |
446 | permits = vnode->permits; | 448 | permits = vnode->permits; |
447 | rcu_assign_pointer(vnode->permits, NULL); | 449 | RCU_INIT_POINTER(vnode->permits, NULL); |
448 | mutex_unlock(&vnode->permits_lock); | 450 | mutex_unlock(&vnode->permits_lock); |
449 | if (permits) | 451 | if (permits) |
450 | call_rcu(&permits->rcu, afs_zap_permits); | 452 | call_rcu(&permits->rcu, afs_zap_permits); |