diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/vfs_dentry.c | 1 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 2 | ||||
-rw-r--r-- | fs/dcache.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 8 | ||||
-rw-r--r-- | fs/nfs/dir.c | 40 | ||||
-rw-r--r-- | fs/nfs/nfs4super.c | 6 | ||||
-rw-r--r-- | fs/nfs/super.c | 6 |
7 files changed, 53 insertions, 13 deletions
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index 64600b5d0522..9ad68628522c 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -137,6 +137,7 @@ out_valid: | |||
137 | 137 | ||
138 | const struct dentry_operations v9fs_cached_dentry_operations = { | 138 | const struct dentry_operations v9fs_cached_dentry_operations = { |
139 | .d_revalidate = v9fs_lookup_revalidate, | 139 | .d_revalidate = v9fs_lookup_revalidate, |
140 | .d_weak_revalidate = v9fs_lookup_revalidate, | ||
140 | .d_delete = v9fs_cached_dentry_delete, | 141 | .d_delete = v9fs_cached_dentry_delete, |
141 | .d_release = v9fs_dentry_release, | 142 | .d_release = v9fs_dentry_release, |
142 | }; | 143 | }; |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 137d50396898..91dad63e5a2d 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -363,5 +363,5 @@ struct file_system_type v9fs_fs_type = { | |||
363 | .mount = v9fs_mount, | 363 | .mount = v9fs_mount, |
364 | .kill_sb = v9fs_kill_super, | 364 | .kill_sb = v9fs_kill_super, |
365 | .owner = THIS_MODULE, | 365 | .owner = THIS_MODULE, |
366 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT, | 366 | .fs_flags = FS_RENAME_DOES_D_MOVE, |
367 | }; | 367 | }; |
diff --git a/fs/dcache.c b/fs/dcache.c index ebab049826c0..68220dd0c135 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1358,6 +1358,7 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) | |||
1358 | WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH | | 1358 | WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH | |
1359 | DCACHE_OP_COMPARE | | 1359 | DCACHE_OP_COMPARE | |
1360 | DCACHE_OP_REVALIDATE | | 1360 | DCACHE_OP_REVALIDATE | |
1361 | DCACHE_OP_WEAK_REVALIDATE | | ||
1361 | DCACHE_OP_DELETE )); | 1362 | DCACHE_OP_DELETE )); |
1362 | dentry->d_op = op; | 1363 | dentry->d_op = op; |
1363 | if (!op) | 1364 | if (!op) |
@@ -1368,6 +1369,8 @@ void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op) | |||
1368 | dentry->d_flags |= DCACHE_OP_COMPARE; | 1369 | dentry->d_flags |= DCACHE_OP_COMPARE; |
1369 | if (op->d_revalidate) | 1370 | if (op->d_revalidate) |
1370 | dentry->d_flags |= DCACHE_OP_REVALIDATE; | 1371 | dentry->d_flags |= DCACHE_OP_REVALIDATE; |
1372 | if (op->d_weak_revalidate) | ||
1373 | dentry->d_flags |= DCACHE_OP_WEAK_REVALIDATE; | ||
1371 | if (op->d_delete) | 1374 | if (op->d_delete) |
1372 | dentry->d_flags |= DCACHE_OP_DELETE; | 1375 | dentry->d_flags |= DCACHE_OP_DELETE; |
1373 | if (op->d_prune) | 1376 | if (op->d_prune) |
diff --git a/fs/namei.c b/fs/namei.c index 052c095c2808..dc984fee5532 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -600,14 +600,10 @@ static int complete_walk(struct nameidata *nd) | |||
600 | if (likely(!(nd->flags & LOOKUP_JUMPED))) | 600 | if (likely(!(nd->flags & LOOKUP_JUMPED))) |
601 | return 0; | 601 | return 0; |
602 | 602 | ||
603 | if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE))) | 603 | if (likely(!(dentry->d_flags & DCACHE_OP_WEAK_REVALIDATE))) |
604 | return 0; | 604 | return 0; |
605 | 605 | ||
606 | if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))) | 606 | status = dentry->d_op->d_weak_revalidate(dentry, nd->flags); |
607 | return 0; | ||
608 | |||
609 | /* Note: we do not d_invalidate() */ | ||
610 | status = d_revalidate(dentry, nd->flags); | ||
611 | if (status > 0) | 607 | if (status > 0) |
612 | return 0; | 608 | return 0; |
613 | 609 | ||
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index a8bd28cde7e2..f23f455be42b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1136,6 +1136,45 @@ out_error: | |||
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | /* | 1138 | /* |
1139 | * A weaker form of d_revalidate for revalidating just the dentry->d_inode | ||
1140 | * when we don't really care about the dentry name. This is called when a | ||
1141 | * pathwalk ends on a dentry that was not found via a normal lookup in the | ||
1142 | * parent dir (e.g.: ".", "..", procfs symlinks or mountpoint traversals). | ||
1143 | * | ||
1144 | * In this situation, we just want to verify that the inode itself is OK | ||
1145 | * since the dentry might have changed on the server. | ||
1146 | */ | ||
1147 | static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags) | ||
1148 | { | ||
1149 | int error; | ||
1150 | struct inode *inode = dentry->d_inode; | ||
1151 | |||
1152 | /* | ||
1153 | * I believe we can only get a negative dentry here in the case of a | ||
1154 | * procfs-style symlink. Just assume it's correct for now, but we may | ||
1155 | * eventually need to do something more here. | ||
1156 | */ | ||
1157 | if (!inode) { | ||
1158 | dfprintk(LOOKUPCACHE, "%s: %s/%s has negative inode\n", | ||
1159 | __func__, dentry->d_parent->d_name.name, | ||
1160 | dentry->d_name.name); | ||
1161 | return 1; | ||
1162 | } | ||
1163 | |||
1164 | if (is_bad_inode(inode)) { | ||
1165 | dfprintk(LOOKUPCACHE, "%s: %s/%s has dud inode\n", | ||
1166 | __func__, dentry->d_parent->d_name.name, | ||
1167 | dentry->d_name.name); | ||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1171 | error = nfs_revalidate_inode(NFS_SERVER(inode), inode); | ||
1172 | dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n", | ||
1173 | __func__, inode->i_ino, error ? "invalid" : "valid"); | ||
1174 | return !error; | ||
1175 | } | ||
1176 | |||
1177 | /* | ||
1139 | * This is called from dput() when d_count is going to 0. | 1178 | * This is called from dput() when d_count is going to 0. |
1140 | */ | 1179 | */ |
1141 | static int nfs_dentry_delete(const struct dentry *dentry) | 1180 | static int nfs_dentry_delete(const struct dentry *dentry) |
@@ -1202,6 +1241,7 @@ static void nfs_d_release(struct dentry *dentry) | |||
1202 | 1241 | ||
1203 | const struct dentry_operations nfs_dentry_operations = { | 1242 | const struct dentry_operations nfs_dentry_operations = { |
1204 | .d_revalidate = nfs_lookup_revalidate, | 1243 | .d_revalidate = nfs_lookup_revalidate, |
1244 | .d_weak_revalidate = nfs_weak_revalidate, | ||
1205 | .d_delete = nfs_dentry_delete, | 1245 | .d_delete = nfs_dentry_delete, |
1206 | .d_iput = nfs_dentry_iput, | 1246 | .d_iput = nfs_dentry_iput, |
1207 | .d_automount = nfs_d_automount, | 1247 | .d_automount = nfs_d_automount, |
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 84d2e9e2f313..569b166cc050 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c | |||
@@ -28,7 +28,7 @@ static struct file_system_type nfs4_remote_fs_type = { | |||
28 | .name = "nfs4", | 28 | .name = "nfs4", |
29 | .mount = nfs4_remote_mount, | 29 | .mount = nfs4_remote_mount, |
30 | .kill_sb = nfs_kill_super, | 30 | .kill_sb = nfs_kill_super, |
31 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 31 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static struct file_system_type nfs4_remote_referral_fs_type = { | 34 | static struct file_system_type nfs4_remote_referral_fs_type = { |
@@ -36,7 +36,7 @@ static struct file_system_type nfs4_remote_referral_fs_type = { | |||
36 | .name = "nfs4", | 36 | .name = "nfs4", |
37 | .mount = nfs4_remote_referral_mount, | 37 | .mount = nfs4_remote_referral_mount, |
38 | .kill_sb = nfs_kill_super, | 38 | .kill_sb = nfs_kill_super, |
39 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 39 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct file_system_type nfs4_referral_fs_type = { | 42 | struct file_system_type nfs4_referral_fs_type = { |
@@ -44,7 +44,7 @@ struct file_system_type nfs4_referral_fs_type = { | |||
44 | .name = "nfs4", | 44 | .name = "nfs4", |
45 | .mount = nfs4_referral_mount, | 45 | .mount = nfs4_referral_mount, |
46 | .kill_sb = nfs_kill_super, | 46 | .kill_sb = nfs_kill_super, |
47 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 47 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static const struct super_operations nfs4_sops = { | 50 | static const struct super_operations nfs4_sops = { |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2e7e8c878e5d..92acc26f9c5f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -292,7 +292,7 @@ struct file_system_type nfs_fs_type = { | |||
292 | .name = "nfs", | 292 | .name = "nfs", |
293 | .mount = nfs_fs_mount, | 293 | .mount = nfs_fs_mount, |
294 | .kill_sb = nfs_kill_super, | 294 | .kill_sb = nfs_kill_super, |
295 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 295 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, |
296 | }; | 296 | }; |
297 | EXPORT_SYMBOL_GPL(nfs_fs_type); | 297 | EXPORT_SYMBOL_GPL(nfs_fs_type); |
298 | 298 | ||
@@ -301,7 +301,7 @@ struct file_system_type nfs_xdev_fs_type = { | |||
301 | .name = "nfs", | 301 | .name = "nfs", |
302 | .mount = nfs_xdev_mount, | 302 | .mount = nfs_xdev_mount, |
303 | .kill_sb = nfs_kill_super, | 303 | .kill_sb = nfs_kill_super, |
304 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 304 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, |
305 | }; | 305 | }; |
306 | 306 | ||
307 | const struct super_operations nfs_sops = { | 307 | const struct super_operations nfs_sops = { |
@@ -331,7 +331,7 @@ struct file_system_type nfs4_fs_type = { | |||
331 | .name = "nfs4", | 331 | .name = "nfs4", |
332 | .mount = nfs_fs_mount, | 332 | .mount = nfs_fs_mount, |
333 | .kill_sb = nfs_kill_super, | 333 | .kill_sb = nfs_kill_super, |
334 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | 334 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, |
335 | }; | 335 | }; |
336 | EXPORT_SYMBOL_GPL(nfs4_fs_type); | 336 | EXPORT_SYMBOL_GPL(nfs4_fs_type); |
337 | 337 | ||