diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 05:28:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 05:28:42 -0400 |
commit | 77c688ac87183537ed0fb84ec2cb8fa8ec97c458 (patch) | |
tree | d18e117e05c0d71463823536165ddd9ad75b6bc5 /fs | |
parent | 5e40d331bd72447197f26525f21711c4a265b6a6 (diff) | |
parent | a457606a6f81cfddfc9da1ef2a8bf2c65a8eb35e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
"The big thing in this pile is Eric's unmount-on-rmdir series; we
finally have everything we need for that. The final piece of prereqs
is delayed mntput() - now filesystem shutdown always happens on
shallow stack.
Other than that, we have several new primitives for iov_iter (Matt
Wilcox, culled from his XIP-related series) pushing the conversion to
->read_iter()/ ->write_iter() a bit more, a bunch of fs/dcache.c
cleanups and fixes (including the external name refcounting, which
gives consistent behaviour of d_move() wrt procfs symlinks for long
and short names alike) and assorted cleanups and fixes all over the
place.
This is just the first pile; there's a lot of stuff from various
people that ought to go in this window. Starting with
unionmount/overlayfs mess... ;-/"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (60 commits)
fs/file_table.c: Update alloc_file() comment
vfs: Deduplicate code shared by xattr system calls operating on paths
reiserfs: remove pointless forward declaration of struct nameidata
don't need that forward declaration of struct nameidata in dcache.h anymore
take dname_external() into fs/dcache.c
let path_init() failures treated the same way as subsequent link_path_walk()
fix misuses of f_count() in ppp and netlink
ncpfs: use list_for_each_entry() for d_subdirs walk
vfs: move getname() from callers to do_mount()
gfs2_atomic_open(): skip lookups on hashed dentry
[infiniband] remove pointless assignments
gadgetfs: saner API for gadgetfs_create_file()
f_fs: saner API for ffs_sb_create_file()
jfs: don't hash direct inode
[s390] remove pointless assignment of ->f_op in vmlogrdr ->open()
ecryptfs: ->f_op is never NULL
android: ->f_op is never NULL
nouveau: __iomem misannotations
missing annotation in fs/file.c
fs: namespace: suppress 'may be used uninitialized' warnings
...
Diffstat (limited to 'fs')
46 files changed, 502 insertions, 537 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index d51ec9fafcc8..47db55aee7f2 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -65,8 +65,8 @@ static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any) | |||
65 | { | 65 | { |
66 | struct p9_fid *fid, *ret; | 66 | struct p9_fid *fid, *ret; |
67 | 67 | ||
68 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n", | 68 | p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p) uid %d any %d\n", |
69 | dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid), | 69 | dentry, dentry, from_kuid(&init_user_ns, uid), |
70 | any); | 70 | any); |
71 | ret = NULL; | 71 | ret = NULL; |
72 | /* we'll recheck under lock if there's anything to look in */ | 72 | /* we'll recheck under lock if there's anything to look in */ |
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index cc1cfae726b3..eb14e055ea83 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -266,8 +266,8 @@ v9fs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) | |||
266 | * Now that we do caching with cache mode enabled, We need | 266 | * Now that we do caching with cache mode enabled, We need |
267 | * to support direct IO | 267 | * to support direct IO |
268 | */ | 268 | */ |
269 | p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%s) off/no(%lld/%lu) EINVAL\n", | 269 | p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%pD) off/no(%lld/%lu) EINVAL\n", |
270 | iocb->ki_filp->f_path.dentry->d_name.name, | 270 | iocb->ki_filp, |
271 | (long long)pos, iter->nr_segs); | 271 | (long long)pos, iter->nr_segs); |
272 | 272 | ||
273 | return -EINVAL; | 273 | return -EINVAL; |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index b03dd23feda8..a345b2d659cc 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -49,8 +49,8 @@ | |||
49 | */ | 49 | */ |
50 | static int v9fs_cached_dentry_delete(const struct dentry *dentry) | 50 | static int v9fs_cached_dentry_delete(const struct dentry *dentry) |
51 | { | 51 | { |
52 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n", | 52 | p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n", |
53 | dentry->d_name.name, dentry); | 53 | dentry, dentry); |
54 | 54 | ||
55 | /* Don't cache negative dentries */ | 55 | /* Don't cache negative dentries */ |
56 | if (!dentry->d_inode) | 56 | if (!dentry->d_inode) |
@@ -67,8 +67,8 @@ static int v9fs_cached_dentry_delete(const struct dentry *dentry) | |||
67 | static void v9fs_dentry_release(struct dentry *dentry) | 67 | static void v9fs_dentry_release(struct dentry *dentry) |
68 | { | 68 | { |
69 | struct hlist_node *p, *n; | 69 | struct hlist_node *p, *n; |
70 | p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n", | 70 | p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n", |
71 | dentry->d_name.name, dentry); | 71 | dentry, dentry); |
72 | hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata) | 72 | hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata) |
73 | p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); | 73 | p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); |
74 | dentry->d_fsdata = NULL; | 74 | dentry->d_fsdata = NULL; |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 0b3bfa303dda..4f1151088ebe 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -116,7 +116,7 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx) | |||
116 | int reclen = 0; | 116 | int reclen = 0; |
117 | struct p9_rdir *rdir; | 117 | struct p9_rdir *rdir; |
118 | 118 | ||
119 | p9_debug(P9_DEBUG_VFS, "name %s\n", file->f_path.dentry->d_name.name); | 119 | p9_debug(P9_DEBUG_VFS, "name %pD\n", file); |
120 | fid = file->private_data; | 120 | fid = file->private_data; |
121 | 121 | ||
122 | buflen = fid->clnt->msize - P9_IOHDRSZ; | 122 | buflen = fid->clnt->msize - P9_IOHDRSZ; |
@@ -172,7 +172,7 @@ static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx) | |||
172 | struct p9_rdir *rdir; | 172 | struct p9_rdir *rdir; |
173 | struct p9_dirent curdirent; | 173 | struct p9_dirent curdirent; |
174 | 174 | ||
175 | p9_debug(P9_DEBUG_VFS, "name %s\n", file->f_path.dentry->d_name.name); | 175 | p9_debug(P9_DEBUG_VFS, "name %pD\n", file); |
176 | fid = file->private_data; | 176 | fid = file->private_data; |
177 | 177 | ||
178 | buflen = fid->clnt->msize - P9_READDIRHDRSZ; | 178 | buflen = fid->clnt->msize - P9_READDIRHDRSZ; |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 520c11c2dcca..5594505e6e73 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -301,8 +301,8 @@ static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl) | |||
301 | struct inode *inode = file_inode(filp); | 301 | struct inode *inode = file_inode(filp); |
302 | int ret = -ENOLCK; | 302 | int ret = -ENOLCK; |
303 | 303 | ||
304 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n", | 304 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", |
305 | filp, cmd, fl, filp->f_path.dentry->d_name.name); | 305 | filp, cmd, fl, filp); |
306 | 306 | ||
307 | /* No mandatory locks */ | 307 | /* No mandatory locks */ |
308 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) | 308 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) |
@@ -337,8 +337,8 @@ static int v9fs_file_flock_dotl(struct file *filp, int cmd, | |||
337 | struct inode *inode = file_inode(filp); | 337 | struct inode *inode = file_inode(filp); |
338 | int ret = -ENOLCK; | 338 | int ret = -ENOLCK; |
339 | 339 | ||
340 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n", | 340 | p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", |
341 | filp, cmd, fl, filp->f_path.dentry->d_name.name); | 341 | filp, cmd, fl, filp); |
342 | 342 | ||
343 | /* No mandatory locks */ | 343 | /* No mandatory locks */ |
344 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) | 344 | if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7fa4f7a7653d..296482fc77a9 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -648,7 +648,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
648 | struct p9_fid *dfid, *ofid, *fid; | 648 | struct p9_fid *dfid, *ofid, *fid; |
649 | struct inode *inode; | 649 | struct inode *inode; |
650 | 650 | ||
651 | p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | 651 | p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); |
652 | 652 | ||
653 | err = 0; | 653 | err = 0; |
654 | ofid = NULL; | 654 | ofid = NULL; |
@@ -755,7 +755,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode | |||
755 | struct p9_fid *fid; | 755 | struct p9_fid *fid; |
756 | struct v9fs_session_info *v9ses; | 756 | struct v9fs_session_info *v9ses; |
757 | 757 | ||
758 | p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | 758 | p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); |
759 | err = 0; | 759 | err = 0; |
760 | v9ses = v9fs_inode2v9ses(dir); | 760 | v9ses = v9fs_inode2v9ses(dir); |
761 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); | 761 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); |
@@ -791,8 +791,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
791 | struct inode *inode; | 791 | struct inode *inode; |
792 | char *name; | 792 | char *name; |
793 | 793 | ||
794 | p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p flags: %x\n", | 794 | p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%pd) %p flags: %x\n", |
795 | dir, dentry->d_name.name, dentry, flags); | 795 | dir, dentry, dentry, flags); |
796 | 796 | ||
797 | if (dentry->d_name.len > NAME_MAX) | 797 | if (dentry->d_name.len > NAME_MAX) |
798 | return ERR_PTR(-ENAMETOOLONG); | 798 | return ERR_PTR(-ENAMETOOLONG); |
@@ -1239,7 +1239,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1239 | struct p9_fid *fid; | 1239 | struct p9_fid *fid; |
1240 | struct p9_wstat *st; | 1240 | struct p9_wstat *st; |
1241 | 1241 | ||
1242 | p9_debug(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); | 1242 | p9_debug(P9_DEBUG_VFS, " %pd\n", dentry); |
1243 | retval = -EPERM; | 1243 | retval = -EPERM; |
1244 | v9ses = v9fs_dentry2v9ses(dentry); | 1244 | v9ses = v9fs_dentry2v9ses(dentry); |
1245 | fid = v9fs_fid_lookup(dentry); | 1245 | fid = v9fs_fid_lookup(dentry); |
@@ -1262,8 +1262,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
1262 | retval = min(strlen(st->extension)+1, (size_t)buflen); | 1262 | retval = min(strlen(st->extension)+1, (size_t)buflen); |
1263 | memcpy(buffer, st->extension, retval); | 1263 | memcpy(buffer, st->extension, retval); |
1264 | 1264 | ||
1265 | p9_debug(P9_DEBUG_VFS, "%s -> %s (%.*s)\n", | 1265 | p9_debug(P9_DEBUG_VFS, "%pd -> %s (%.*s)\n", |
1266 | dentry->d_name.name, st->extension, buflen, buffer); | 1266 | dentry, st->extension, buflen, buffer); |
1267 | 1267 | ||
1268 | done: | 1268 | done: |
1269 | p9stat_free(st); | 1269 | p9stat_free(st); |
@@ -1283,7 +1283,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1283 | int len = 0; | 1283 | int len = 0; |
1284 | char *link = __getname(); | 1284 | char *link = __getname(); |
1285 | 1285 | ||
1286 | p9_debug(P9_DEBUG_VFS, "%s\n", dentry->d_name.name); | 1286 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
1287 | 1287 | ||
1288 | if (!link) | 1288 | if (!link) |
1289 | link = ERR_PTR(-ENOMEM); | 1289 | link = ERR_PTR(-ENOMEM); |
@@ -1314,8 +1314,8 @@ v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | |||
1314 | { | 1314 | { |
1315 | char *s = nd_get_link(nd); | 1315 | char *s = nd_get_link(nd); |
1316 | 1316 | ||
1317 | p9_debug(P9_DEBUG_VFS, " %s %s\n", | 1317 | p9_debug(P9_DEBUG_VFS, " %pd %s\n", |
1318 | dentry->d_name.name, IS_ERR(s) ? "<error>" : s); | 1318 | dentry, IS_ERR(s) ? "<error>" : s); |
1319 | if (!IS_ERR(s)) | 1319 | if (!IS_ERR(s)) |
1320 | __putname(s); | 1320 | __putname(s); |
1321 | } | 1321 | } |
@@ -1364,8 +1364,8 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | |||
1364 | static int | 1364 | static int |
1365 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | 1365 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) |
1366 | { | 1366 | { |
1367 | p9_debug(P9_DEBUG_VFS, " %lu,%s,%s\n", | 1367 | p9_debug(P9_DEBUG_VFS, " %lu,%pd,%s\n", |
1368 | dir->i_ino, dentry->d_name.name, symname); | 1368 | dir->i_ino, dentry, symname); |
1369 | 1369 | ||
1370 | return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname); | 1370 | return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname); |
1371 | } | 1371 | } |
@@ -1386,8 +1386,8 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1386 | char *name; | 1386 | char *name; |
1387 | struct p9_fid *oldfid; | 1387 | struct p9_fid *oldfid; |
1388 | 1388 | ||
1389 | p9_debug(P9_DEBUG_VFS, " %lu,%s,%s\n", | 1389 | p9_debug(P9_DEBUG_VFS, " %lu,%pd,%pd\n", |
1390 | dir->i_ino, dentry->d_name.name, old_dentry->d_name.name); | 1390 | dir->i_ino, dentry, old_dentry); |
1391 | 1391 | ||
1392 | oldfid = v9fs_fid_clone(old_dentry); | 1392 | oldfid = v9fs_fid_clone(old_dentry); |
1393 | if (IS_ERR(oldfid)) | 1393 | if (IS_ERR(oldfid)) |
@@ -1428,8 +1428,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rde | |||
1428 | char *name; | 1428 | char *name; |
1429 | u32 perm; | 1429 | u32 perm; |
1430 | 1430 | ||
1431 | p9_debug(P9_DEBUG_VFS, " %lu,%s mode: %hx MAJOR: %u MINOR: %u\n", | 1431 | p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n", |
1432 | dir->i_ino, dentry->d_name.name, mode, | 1432 | dir->i_ino, dentry, mode, |
1433 | MAJOR(rdev), MINOR(rdev)); | 1433 | MAJOR(rdev), MINOR(rdev)); |
1434 | 1434 | ||
1435 | if (!new_valid_dev(rdev)) | 1435 | if (!new_valid_dev(rdev)) |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 1fa85aae24df..02b64f4e576a 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -393,7 +393,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, | |||
393 | struct dentry *dir_dentry; | 393 | struct dentry *dir_dentry; |
394 | struct posix_acl *dacl = NULL, *pacl = NULL; | 394 | struct posix_acl *dacl = NULL, *pacl = NULL; |
395 | 395 | ||
396 | p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); | 396 | p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); |
397 | err = 0; | 397 | err = 0; |
398 | v9ses = v9fs_inode2v9ses(dir); | 398 | v9ses = v9fs_inode2v9ses(dir); |
399 | 399 | ||
@@ -767,8 +767,8 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, | |||
767 | struct p9_fid *dfid, *oldfid; | 767 | struct p9_fid *dfid, *oldfid; |
768 | struct v9fs_session_info *v9ses; | 768 | struct v9fs_session_info *v9ses; |
769 | 769 | ||
770 | p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n", | 770 | p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n", |
771 | dir->i_ino, old_dentry->d_name.name, dentry->d_name.name); | 771 | dir->i_ino, old_dentry, dentry); |
772 | 772 | ||
773 | v9ses = v9fs_inode2v9ses(dir); | 773 | v9ses = v9fs_inode2v9ses(dir); |
774 | dir_dentry = dentry->d_parent; | 774 | dir_dentry = dentry->d_parent; |
@@ -917,7 +917,7 @@ v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd) | |||
917 | char *link = __getname(); | 917 | char *link = __getname(); |
918 | char *target; | 918 | char *target; |
919 | 919 | ||
920 | p9_debug(P9_DEBUG_VFS, "%s\n", dentry->d_name.name); | 920 | p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); |
921 | 921 | ||
922 | if (!link) { | 922 | if (!link) { |
923 | link = ERR_PTR(-ENOMEM); | 923 | link = ERR_PTR(-ENOMEM); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 529300327f45..a1645b88fe8a 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -669,7 +669,6 @@ static int afs_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
669 | 669 | ||
670 | out_valid: | 670 | out_valid: |
671 | dentry->d_fsdata = dir_version; | 671 | dentry->d_fsdata = dir_version; |
672 | out_skip: | ||
673 | dput(parent); | 672 | dput(parent); |
674 | key_put(key); | 673 | key_put(key); |
675 | _leave(" = 1 [valid]"); | 674 | _leave(" = 1 [valid]"); |
@@ -682,10 +681,6 @@ not_found: | |||
682 | spin_unlock(&dentry->d_lock); | 681 | spin_unlock(&dentry->d_lock); |
683 | 682 | ||
684 | out_bad: | 683 | out_bad: |
685 | /* don't unhash if we have submounts */ | ||
686 | if (check_submounts_and_drop(dentry) != 0) | ||
687 | goto out_skip; | ||
688 | |||
689 | _debug("dropping dentry %s/%s", | 684 | _debug("dropping dentry %s/%s", |
690 | parent->d_name.name, dentry->d_name.name); | 685 | parent->d_name.name, dentry->d_name.name); |
691 | dput(parent); | 686 | dput(parent); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index a7be57e39be7..8fa3895cda02 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -255,12 +255,6 @@ static int autofs4_tree_busy(struct vfsmount *mnt, | |||
255 | struct autofs_info *ino = autofs4_dentry_ino(p); | 255 | struct autofs_info *ino = autofs4_dentry_ino(p); |
256 | unsigned int ino_count = atomic_read(&ino->count); | 256 | unsigned int ino_count = atomic_read(&ino->count); |
257 | 257 | ||
258 | /* | ||
259 | * Clean stale dentries below that have not been | ||
260 | * invalidated after a mount fail during lookup | ||
261 | */ | ||
262 | d_invalidate(p); | ||
263 | |||
264 | /* allow for dget above and top is already dgot */ | 258 | /* allow for dget above and top is already dgot */ |
265 | if (p == top) | 259 | if (p == top) |
266 | ino_count += 2; | 260 | ino_count += 2; |
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index ca0ba15a7306..929dec08c348 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -256,11 +256,8 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
256 | (current->mm->start_brk = N_BSSADDR(ex)); | 256 | (current->mm->start_brk = N_BSSADDR(ex)); |
257 | 257 | ||
258 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); | 258 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); |
259 | if (retval < 0) { | 259 | if (retval < 0) |
260 | /* Someone check-me: is this error path enough? */ | ||
261 | send_sig(SIGKILL, current, 0); | ||
262 | return retval; | 260 | return retval; |
263 | } | ||
264 | 261 | ||
265 | install_exec_creds(bprm); | 262 | install_exec_creds(bprm); |
266 | 263 | ||
@@ -278,17 +275,13 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
278 | map_size = ex.a_text+ex.a_data; | 275 | map_size = ex.a_text+ex.a_data; |
279 | #endif | 276 | #endif |
280 | error = vm_brk(text_addr & PAGE_MASK, map_size); | 277 | error = vm_brk(text_addr & PAGE_MASK, map_size); |
281 | if (error != (text_addr & PAGE_MASK)) { | 278 | if (error != (text_addr & PAGE_MASK)) |
282 | send_sig(SIGKILL, current, 0); | ||
283 | return error; | 279 | return error; |
284 | } | ||
285 | 280 | ||
286 | error = read_code(bprm->file, text_addr, pos, | 281 | error = read_code(bprm->file, text_addr, pos, |
287 | ex.a_text+ex.a_data); | 282 | ex.a_text+ex.a_data); |
288 | if ((signed long)error < 0) { | 283 | if ((signed long)error < 0) |
289 | send_sig(SIGKILL, current, 0); | ||
290 | return error; | 284 | return error; |
291 | } | ||
292 | } else { | 285 | } else { |
293 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && | 286 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && |
294 | (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) | 287 | (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) |
@@ -315,28 +308,22 @@ static int load_aout_binary(struct linux_binprm * bprm) | |||
315 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | 308 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
316 | fd_offset); | 309 | fd_offset); |
317 | 310 | ||
318 | if (error != N_TXTADDR(ex)) { | 311 | if (error != N_TXTADDR(ex)) |
319 | send_sig(SIGKILL, current, 0); | ||
320 | return error; | 312 | return error; |
321 | } | ||
322 | 313 | ||
323 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, | 314 | error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, |
324 | PROT_READ | PROT_WRITE | PROT_EXEC, | 315 | PROT_READ | PROT_WRITE | PROT_EXEC, |
325 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, | 316 | MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
326 | fd_offset + ex.a_text); | 317 | fd_offset + ex.a_text); |
327 | if (error != N_DATADDR(ex)) { | 318 | if (error != N_DATADDR(ex)) |
328 | send_sig(SIGKILL, current, 0); | ||
329 | return error; | 319 | return error; |
330 | } | ||
331 | } | 320 | } |
332 | beyond_if: | 321 | beyond_if: |
333 | set_binfmt(&aout_format); | 322 | set_binfmt(&aout_format); |
334 | 323 | ||
335 | retval = set_brk(current->mm->start_brk, current->mm->brk); | 324 | retval = set_brk(current->mm->start_brk, current->mm->brk); |
336 | if (retval < 0) { | 325 | if (retval < 0) |
337 | send_sig(SIGKILL, current, 0); | ||
338 | return retval; | 326 | return retval; |
339 | } | ||
340 | 327 | ||
341 | current->mm->start_stack = | 328 | current->mm->start_stack = |
342 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); | 329 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3892c1a23241..d8fc0605b9d2 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -738,10 +738,8 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
738 | change some of these later */ | 738 | change some of these later */ |
739 | retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), | 739 | retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), |
740 | executable_stack); | 740 | executable_stack); |
741 | if (retval < 0) { | 741 | if (retval < 0) |
742 | send_sig(SIGKILL, current, 0); | ||
743 | goto out_free_dentry; | 742 | goto out_free_dentry; |
744 | } | ||
745 | 743 | ||
746 | current->mm->start_stack = bprm->p; | 744 | current->mm->start_stack = bprm->p; |
747 | 745 | ||
@@ -763,10 +761,8 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
763 | and clear the area. */ | 761 | and clear the area. */ |
764 | retval = set_brk(elf_bss + load_bias, | 762 | retval = set_brk(elf_bss + load_bias, |
765 | elf_brk + load_bias); | 763 | elf_brk + load_bias); |
766 | if (retval) { | 764 | if (retval) |
767 | send_sig(SIGKILL, current, 0); | ||
768 | goto out_free_dentry; | 765 | goto out_free_dentry; |
769 | } | ||
770 | nbyte = ELF_PAGEOFFSET(elf_bss); | 766 | nbyte = ELF_PAGEOFFSET(elf_bss); |
771 | if (nbyte) { | 767 | if (nbyte) { |
772 | nbyte = ELF_MIN_ALIGN - nbyte; | 768 | nbyte = ELF_MIN_ALIGN - nbyte; |
@@ -820,7 +816,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
820 | error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, | 816 | error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, |
821 | elf_prot, elf_flags, 0); | 817 | elf_prot, elf_flags, 0); |
822 | if (BAD_ADDR(error)) { | 818 | if (BAD_ADDR(error)) { |
823 | send_sig(SIGKILL, current, 0); | ||
824 | retval = IS_ERR((void *)error) ? | 819 | retval = IS_ERR((void *)error) ? |
825 | PTR_ERR((void*)error) : -EINVAL; | 820 | PTR_ERR((void*)error) : -EINVAL; |
826 | goto out_free_dentry; | 821 | goto out_free_dentry; |
@@ -851,7 +846,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
851 | elf_ppnt->p_memsz > TASK_SIZE || | 846 | elf_ppnt->p_memsz > TASK_SIZE || |
852 | TASK_SIZE - elf_ppnt->p_memsz < k) { | 847 | TASK_SIZE - elf_ppnt->p_memsz < k) { |
853 | /* set_brk can never work. Avoid overflows. */ | 848 | /* set_brk can never work. Avoid overflows. */ |
854 | send_sig(SIGKILL, current, 0); | ||
855 | retval = -EINVAL; | 849 | retval = -EINVAL; |
856 | goto out_free_dentry; | 850 | goto out_free_dentry; |
857 | } | 851 | } |
@@ -883,12 +877,9 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
883 | * up getting placed where the bss needs to go. | 877 | * up getting placed where the bss needs to go. |
884 | */ | 878 | */ |
885 | retval = set_brk(elf_bss, elf_brk); | 879 | retval = set_brk(elf_bss, elf_brk); |
886 | if (retval) { | 880 | if (retval) |
887 | send_sig(SIGKILL, current, 0); | ||
888 | goto out_free_dentry; | 881 | goto out_free_dentry; |
889 | } | ||
890 | if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { | 882 | if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { |
891 | send_sig(SIGSEGV, current, 0); | ||
892 | retval = -EFAULT; /* Nobody gets to see this, but.. */ | 883 | retval = -EFAULT; /* Nobody gets to see this, but.. */ |
893 | goto out_free_dentry; | 884 | goto out_free_dentry; |
894 | } | 885 | } |
@@ -909,7 +900,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
909 | elf_entry += loc->interp_elf_ex.e_entry; | 900 | elf_entry += loc->interp_elf_ex.e_entry; |
910 | } | 901 | } |
911 | if (BAD_ADDR(elf_entry)) { | 902 | if (BAD_ADDR(elf_entry)) { |
912 | force_sig(SIGSEGV, current); | ||
913 | retval = IS_ERR((void *)elf_entry) ? | 903 | retval = IS_ERR((void *)elf_entry) ? |
914 | (int)elf_entry : -EINVAL; | 904 | (int)elf_entry : -EINVAL; |
915 | goto out_free_dentry; | 905 | goto out_free_dentry; |
@@ -922,7 +912,6 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
922 | } else { | 912 | } else { |
923 | elf_entry = loc->elf_ex.e_entry; | 913 | elf_entry = loc->elf_ex.e_entry; |
924 | if (BAD_ADDR(elf_entry)) { | 914 | if (BAD_ADDR(elf_entry)) { |
925 | force_sig(SIGSEGV, current); | ||
926 | retval = -EINVAL; | 915 | retval = -EINVAL; |
927 | goto out_free_dentry; | 916 | goto out_free_dentry; |
928 | } | 917 | } |
@@ -934,19 +923,15 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
934 | 923 | ||
935 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES | 924 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES |
936 | retval = arch_setup_additional_pages(bprm, !!elf_interpreter); | 925 | retval = arch_setup_additional_pages(bprm, !!elf_interpreter); |
937 | if (retval < 0) { | 926 | if (retval < 0) |
938 | send_sig(SIGKILL, current, 0); | ||
939 | goto out; | 927 | goto out; |
940 | } | ||
941 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ | 928 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ |
942 | 929 | ||
943 | install_exec_creds(bprm); | 930 | install_exec_creds(bprm); |
944 | retval = create_elf_tables(bprm, &loc->elf_ex, | 931 | retval = create_elf_tables(bprm, &loc->elf_ex, |
945 | load_addr, interp_load_addr); | 932 | load_addr, interp_load_addr); |
946 | if (retval < 0) { | 933 | if (retval < 0) |
947 | send_sig(SIGKILL, current, 0); | ||
948 | goto out; | 934 | goto out; |
949 | } | ||
950 | /* N.B. passed_fileno might not be initialized? */ | 935 | /* N.B. passed_fileno might not be initialized? */ |
951 | current->mm->end_code = end_code; | 936 | current->mm->end_code = end_code; |
952 | current->mm->start_code = start_code; | 937 | current->mm->start_code = start_code; |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index fe2a643ee005..d3634bfb7fe1 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -317,8 +317,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
317 | goto error; | 317 | goto error; |
318 | 318 | ||
319 | /* there's now no turning back... the old userspace image is dead, | 319 | /* there's now no turning back... the old userspace image is dead, |
320 | * defunct, deceased, etc. after this point we have to exit via | 320 | * defunct, deceased, etc. |
321 | * error_kill */ | 321 | */ |
322 | set_personality(PER_LINUX_FDPIC); | 322 | set_personality(PER_LINUX_FDPIC); |
323 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) | 323 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) |
324 | current->personality |= READ_IMPLIES_EXEC; | 324 | current->personality |= READ_IMPLIES_EXEC; |
@@ -343,24 +343,22 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
343 | 343 | ||
344 | retval = setup_arg_pages(bprm, current->mm->start_stack, | 344 | retval = setup_arg_pages(bprm, current->mm->start_stack, |
345 | executable_stack); | 345 | executable_stack); |
346 | if (retval < 0) { | 346 | if (retval < 0) |
347 | send_sig(SIGKILL, current, 0); | 347 | goto error; |
348 | goto error_kill; | ||
349 | } | ||
350 | #endif | 348 | #endif |
351 | 349 | ||
352 | /* load the executable and interpreter into memory */ | 350 | /* load the executable and interpreter into memory */ |
353 | retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, | 351 | retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, |
354 | "executable"); | 352 | "executable"); |
355 | if (retval < 0) | 353 | if (retval < 0) |
356 | goto error_kill; | 354 | goto error; |
357 | 355 | ||
358 | if (interpreter_name) { | 356 | if (interpreter_name) { |
359 | retval = elf_fdpic_map_file(&interp_params, interpreter, | 357 | retval = elf_fdpic_map_file(&interp_params, interpreter, |
360 | current->mm, "interpreter"); | 358 | current->mm, "interpreter"); |
361 | if (retval < 0) { | 359 | if (retval < 0) { |
362 | printk(KERN_ERR "Unable to load interpreter\n"); | 360 | printk(KERN_ERR "Unable to load interpreter\n"); |
363 | goto error_kill; | 361 | goto error; |
364 | } | 362 | } |
365 | 363 | ||
366 | allow_write_access(interpreter); | 364 | allow_write_access(interpreter); |
@@ -397,7 +395,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
397 | if (IS_ERR_VALUE(current->mm->start_brk)) { | 395 | if (IS_ERR_VALUE(current->mm->start_brk)) { |
398 | retval = current->mm->start_brk; | 396 | retval = current->mm->start_brk; |
399 | current->mm->start_brk = 0; | 397 | current->mm->start_brk = 0; |
400 | goto error_kill; | 398 | goto error; |
401 | } | 399 | } |
402 | 400 | ||
403 | current->mm->brk = current->mm->start_brk; | 401 | current->mm->brk = current->mm->start_brk; |
@@ -410,7 +408,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm) | |||
410 | install_exec_creds(bprm); | 408 | install_exec_creds(bprm); |
411 | if (create_elf_fdpic_tables(bprm, current->mm, | 409 | if (create_elf_fdpic_tables(bprm, current->mm, |
412 | &exec_params, &interp_params) < 0) | 410 | &exec_params, &interp_params) < 0) |
413 | goto error_kill; | 411 | goto error; |
414 | 412 | ||
415 | kdebug("- start_code %lx", current->mm->start_code); | 413 | kdebug("- start_code %lx", current->mm->start_code); |
416 | kdebug("- end_code %lx", current->mm->end_code); | 414 | kdebug("- end_code %lx", current->mm->end_code); |
@@ -449,12 +447,6 @@ error: | |||
449 | kfree(interp_params.phdrs); | 447 | kfree(interp_params.phdrs); |
450 | kfree(interp_params.loadmap); | 448 | kfree(interp_params.loadmap); |
451 | return retval; | 449 | return retval; |
452 | |||
453 | /* unrecoverable error - kill the process */ | ||
454 | error_kill: | ||
455 | send_sig(SIGSEGV, current, 0); | ||
456 | goto error; | ||
457 | |||
458 | } | 450 | } |
459 | 451 | ||
460 | /*****************************************************************************/ | 452 | /*****************************************************************************/ |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e732274f1afd..0fe1aa047f15 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2419,9 +2419,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2419 | goto out_dput; | 2419 | goto out_dput; |
2420 | } | 2420 | } |
2421 | 2421 | ||
2422 | err = d_invalidate(dentry); | 2422 | d_invalidate(dentry); |
2423 | if (err) | ||
2424 | goto out_unlock; | ||
2425 | 2423 | ||
2426 | down_write(&root->fs_info->subvol_sem); | 2424 | down_write(&root->fs_info->subvol_sem); |
2427 | 2425 | ||
@@ -2506,7 +2504,6 @@ out_release: | |||
2506 | btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); | 2504 | btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); |
2507 | out_up_write: | 2505 | out_up_write: |
2508 | up_write(&root->fs_info->subvol_sem); | 2506 | up_write(&root->fs_info->subvol_sem); |
2509 | out_unlock: | ||
2510 | if (err) { | 2507 | if (err) { |
2511 | spin_lock(&dest->root_item_lock); | 2508 | spin_lock(&dest->root_item_lock); |
2512 | root_flags = btrfs_root_flags(&dest->root_item); | 2509 | root_flags = btrfs_root_flags(&dest->root_item); |
diff --git a/fs/buffer.c b/fs/buffer.c index 44c14a87750e..d1f704806264 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2318,6 +2318,11 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping, | |||
2318 | err = 0; | 2318 | err = 0; |
2319 | 2319 | ||
2320 | balance_dirty_pages_ratelimited(mapping); | 2320 | balance_dirty_pages_ratelimited(mapping); |
2321 | |||
2322 | if (unlikely(fatal_signal_pending(current))) { | ||
2323 | err = -EINTR; | ||
2324 | goto out; | ||
2325 | } | ||
2321 | } | 2326 | } |
2322 | 2327 | ||
2323 | /* page covers the boundary, find the boundary offset */ | 2328 | /* page covers the boundary, find the boundary offset */ |
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index 25e745b8eb1b..616db0e77b44 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c | |||
@@ -880,7 +880,6 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
880 | { | 880 | { |
881 | struct cachefiles_object *object; | 881 | struct cachefiles_object *object; |
882 | struct cachefiles_cache *cache; | 882 | struct cachefiles_cache *cache; |
883 | mm_segment_t old_fs; | ||
884 | struct file *file; | 883 | struct file *file; |
885 | struct path path; | 884 | struct path path; |
886 | loff_t pos, eof; | 885 | loff_t pos, eof; |
@@ -914,36 +913,27 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
914 | if (IS_ERR(file)) { | 913 | if (IS_ERR(file)) { |
915 | ret = PTR_ERR(file); | 914 | ret = PTR_ERR(file); |
916 | } else { | 915 | } else { |
917 | ret = -EIO; | 916 | pos = (loff_t) page->index << PAGE_SHIFT; |
918 | if (file->f_op->write) { | 917 | |
919 | pos = (loff_t) page->index << PAGE_SHIFT; | 918 | /* we mustn't write more data than we have, so we have |
920 | 919 | * to beware of a partial page at EOF */ | |
921 | /* we mustn't write more data than we have, so we have | 920 | eof = object->fscache.store_limit_l; |
922 | * to beware of a partial page at EOF */ | 921 | len = PAGE_SIZE; |
923 | eof = object->fscache.store_limit_l; | 922 | if (eof & ~PAGE_MASK) { |
924 | len = PAGE_SIZE; | 923 | ASSERTCMP(pos, <, eof); |
925 | if (eof & ~PAGE_MASK) { | 924 | if (eof - pos < PAGE_SIZE) { |
926 | ASSERTCMP(pos, <, eof); | 925 | _debug("cut short %llx to %llx", |
927 | if (eof - pos < PAGE_SIZE) { | 926 | pos, eof); |
928 | _debug("cut short %llx to %llx", | 927 | len = eof - pos; |
929 | pos, eof); | 928 | ASSERTCMP(pos + len, ==, eof); |
930 | len = eof - pos; | ||
931 | ASSERTCMP(pos + len, ==, eof); | ||
932 | } | ||
933 | } | 929 | } |
934 | |||
935 | data = kmap(page); | ||
936 | file_start_write(file); | ||
937 | old_fs = get_fs(); | ||
938 | set_fs(KERNEL_DS); | ||
939 | ret = file->f_op->write( | ||
940 | file, (const void __user *) data, len, &pos); | ||
941 | set_fs(old_fs); | ||
942 | kunmap(page); | ||
943 | file_end_write(file); | ||
944 | if (ret != len) | ||
945 | ret = -EIO; | ||
946 | } | 930 | } |
931 | |||
932 | data = kmap(page); | ||
933 | ret = __kernel_write(file, data, len, &pos); | ||
934 | kunmap(page); | ||
935 | if (ret != len) | ||
936 | ret = -EIO; | ||
947 | fput(file); | 937 | fput(file); |
948 | } | 938 | } |
949 | 939 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index c29d6ae68874..b6c59eaa4f64 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1069,7 +1069,6 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
1069 | ceph_dentry_lru_touch(dentry); | 1069 | ceph_dentry_lru_touch(dentry); |
1070 | } else { | 1070 | } else { |
1071 | ceph_dir_clear_complete(dir); | 1071 | ceph_dir_clear_complete(dir); |
1072 | d_drop(dentry); | ||
1073 | } | 1072 | } |
1074 | iput(dir); | 1073 | iput(dir); |
1075 | return valid; | 1074 | return valid; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6cbd9c688cfe..073640675a39 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -461,8 +461,8 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
461 | 461 | ||
462 | xid = get_xid(); | 462 | xid = get_xid(); |
463 | 463 | ||
464 | cifs_dbg(FYI, "parent inode = 0x%p name is: %s and dentry = 0x%p\n", | 464 | cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", |
465 | inode, direntry->d_name.name, direntry); | 465 | inode, direntry, direntry); |
466 | 466 | ||
467 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); | 467 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); |
468 | if (IS_ERR(tlink)) { | 468 | if (IS_ERR(tlink)) { |
@@ -540,8 +540,8 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, | |||
540 | struct cifs_fid fid; | 540 | struct cifs_fid fid; |
541 | __u32 oplock; | 541 | __u32 oplock; |
542 | 542 | ||
543 | cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p\n", | 543 | cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n", |
544 | inode, direntry->d_name.name, direntry); | 544 | inode, direntry, direntry); |
545 | 545 | ||
546 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); | 546 | tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); |
547 | rc = PTR_ERR(tlink); | 547 | rc = PTR_ERR(tlink); |
@@ -713,8 +713,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
713 | 713 | ||
714 | xid = get_xid(); | 714 | xid = get_xid(); |
715 | 715 | ||
716 | cifs_dbg(FYI, "parent inode = 0x%p name is: %s and dentry = 0x%p\n", | 716 | cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", |
717 | parent_dir_inode, direntry->d_name.name, direntry); | 717 | parent_dir_inode, direntry, direntry); |
718 | 718 | ||
719 | /* check whether path exists */ | 719 | /* check whether path exists */ |
720 | 720 | ||
@@ -833,7 +833,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) | |||
833 | { | 833 | { |
834 | int rc = 0; | 834 | int rc = 0; |
835 | 835 | ||
836 | cifs_dbg(FYI, "In cifs d_delete, name = %s\n", direntry->d_name.name); | 836 | cifs_dbg(FYI, "In cifs d_delete, name = %pd\n", direntry); |
837 | 837 | ||
838 | return rc; | 838 | return rc; |
839 | } */ | 839 | } */ |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5f29354b072a..8f7b40fd8f3b 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1650,8 +1650,8 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, | |||
1650 | 1650 | ||
1651 | cifs_sb = CIFS_SB(dentry->d_sb); | 1651 | cifs_sb = CIFS_SB(dentry->d_sb); |
1652 | 1652 | ||
1653 | cifs_dbg(FYI, "write %zd bytes to offset %lld of %s\n", | 1653 | cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n", |
1654 | write_size, *offset, dentry->d_name.name); | 1654 | write_size, *offset, dentry); |
1655 | 1655 | ||
1656 | tcon = tlink_tcon(open_file->tlink); | 1656 | tcon = tlink_tcon(open_file->tlink); |
1657 | server = tcon->ses->server; | 1657 | server = tcon->ses->server; |
@@ -2273,8 +2273,8 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, | |||
2273 | 2273 | ||
2274 | xid = get_xid(); | 2274 | xid = get_xid(); |
2275 | 2275 | ||
2276 | cifs_dbg(FYI, "Sync file - name: %s datasync: 0x%x\n", | 2276 | cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n", |
2277 | file->f_path.dentry->d_name.name, datasync); | 2277 | file, datasync); |
2278 | 2278 | ||
2279 | if (!CIFS_CACHE_READ(CIFS_I(inode))) { | 2279 | if (!CIFS_CACHE_READ(CIFS_I(inode))) { |
2280 | rc = cifs_zap_mapping(inode); | 2280 | rc = cifs_zap_mapping(inode); |
@@ -2315,8 +2315,8 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
2315 | 2315 | ||
2316 | xid = get_xid(); | 2316 | xid = get_xid(); |
2317 | 2317 | ||
2318 | cifs_dbg(FYI, "Sync file - name: %s datasync: 0x%x\n", | 2318 | cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n", |
2319 | file->f_path.dentry->d_name.name, datasync); | 2319 | file, datasync); |
2320 | 2320 | ||
2321 | tcon = tlink_tcon(smbfile->tlink); | 2321 | tcon = tlink_tcon(smbfile->tlink); |
2322 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { | 2322 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 7899a40465b3..8fd4ee8e07ff 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1419,8 +1419,8 @@ cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode, | |||
1419 | d_instantiate(dentry, newinode); | 1419 | d_instantiate(dentry, newinode); |
1420 | 1420 | ||
1421 | #ifdef CONFIG_CIFS_DEBUG2 | 1421 | #ifdef CONFIG_CIFS_DEBUG2 |
1422 | cifs_dbg(FYI, "instantiated dentry %p %s to inode %p\n", | 1422 | cifs_dbg(FYI, "instantiated dentry %p %pd to inode %p\n", |
1423 | dentry, dentry->d_name.name, newinode); | 1423 | dentry, dentry, newinode); |
1424 | 1424 | ||
1425 | if (newinode->i_nlink != 2) | 1425 | if (newinode->i_nlink != 2) |
1426 | cifs_dbg(FYI, "unexpected number of links %d\n", | 1426 | cifs_dbg(FYI, "unexpected number of links %d\n", |
@@ -2111,8 +2111,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) | |||
2111 | struct cifs_unix_set_info_args *args = NULL; | 2111 | struct cifs_unix_set_info_args *args = NULL; |
2112 | struct cifsFileInfo *open_file; | 2112 | struct cifsFileInfo *open_file; |
2113 | 2113 | ||
2114 | cifs_dbg(FYI, "setattr_unix on file %s attrs->ia_valid=0x%x\n", | 2114 | cifs_dbg(FYI, "setattr_unix on file %pd attrs->ia_valid=0x%x\n", |
2115 | direntry->d_name.name, attrs->ia_valid); | 2115 | direntry, attrs->ia_valid); |
2116 | 2116 | ||
2117 | xid = get_xid(); | 2117 | xid = get_xid(); |
2118 | 2118 | ||
@@ -2254,8 +2254,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2254 | 2254 | ||
2255 | xid = get_xid(); | 2255 | xid = get_xid(); |
2256 | 2256 | ||
2257 | cifs_dbg(FYI, "setattr on file %s attrs->iavalid 0x%x\n", | 2257 | cifs_dbg(FYI, "setattr on file %pd attrs->iavalid 0x%x\n", |
2258 | direntry->d_name.name, attrs->ia_valid); | 2258 | direntry, attrs->ia_valid); |
2259 | 2259 | ||
2260 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) | 2260 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) |
2261 | attrs->ia_valid |= ATTR_FORCE; | 2261 | attrs->ia_valid |= ATTR_FORCE; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b334a89d6a66..d2141f101382 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -87,8 +87,6 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, | |||
87 | return; | 87 | return; |
88 | 88 | ||
89 | if (dentry) { | 89 | if (dentry) { |
90 | int err; | ||
91 | |||
92 | inode = dentry->d_inode; | 90 | inode = dentry->d_inode; |
93 | if (inode) { | 91 | if (inode) { |
94 | /* | 92 | /* |
@@ -105,10 +103,8 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, | |||
105 | goto out; | 103 | goto out; |
106 | } | 104 | } |
107 | } | 105 | } |
108 | err = d_invalidate(dentry); | 106 | d_invalidate(dentry); |
109 | dput(dentry); | 107 | dput(dentry); |
110 | if (err) | ||
111 | return; | ||
112 | } | 108 | } |
113 | 109 | ||
114 | /* | 110 | /* |
diff --git a/fs/compat.c b/fs/compat.c index 66d3d3c6b4b2..b13df99f3534 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -794,25 +794,21 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, | |||
794 | char *kernel_type; | 794 | char *kernel_type; |
795 | unsigned long data_page; | 795 | unsigned long data_page; |
796 | char *kernel_dev; | 796 | char *kernel_dev; |
797 | struct filename *dir; | ||
798 | int retval; | 797 | int retval; |
799 | 798 | ||
800 | retval = copy_mount_string(type, &kernel_type); | 799 | kernel_type = copy_mount_string(type); |
801 | if (retval < 0) | 800 | retval = PTR_ERR(kernel_type); |
801 | if (IS_ERR(kernel_type)) | ||
802 | goto out; | 802 | goto out; |
803 | 803 | ||
804 | dir = getname(dir_name); | 804 | kernel_dev = copy_mount_string(dev_name); |
805 | retval = PTR_ERR(dir); | 805 | retval = PTR_ERR(kernel_dev); |
806 | if (IS_ERR(dir)) | 806 | if (IS_ERR(kernel_dev)) |
807 | goto out1; | 807 | goto out1; |
808 | 808 | ||
809 | retval = copy_mount_string(dev_name, &kernel_dev); | ||
810 | if (retval < 0) | ||
811 | goto out2; | ||
812 | |||
813 | retval = copy_mount_options(data, &data_page); | 809 | retval = copy_mount_options(data, &data_page); |
814 | if (retval < 0) | 810 | if (retval < 0) |
815 | goto out3; | 811 | goto out2; |
816 | 812 | ||
817 | retval = -EINVAL; | 813 | retval = -EINVAL; |
818 | 814 | ||
@@ -821,19 +817,17 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, | |||
821 | do_ncp_super_data_conv((void *)data_page); | 817 | do_ncp_super_data_conv((void *)data_page); |
822 | } else if (!strcmp(kernel_type, NFS4_NAME)) { | 818 | } else if (!strcmp(kernel_type, NFS4_NAME)) { |
823 | if (do_nfs4_super_data_conv((void *) data_page)) | 819 | if (do_nfs4_super_data_conv((void *) data_page)) |
824 | goto out4; | 820 | goto out3; |
825 | } | 821 | } |
826 | } | 822 | } |
827 | 823 | ||
828 | retval = do_mount(kernel_dev, dir->name, kernel_type, | 824 | retval = do_mount(kernel_dev, dir_name, kernel_type, |
829 | flags, (void*)data_page); | 825 | flags, (void*)data_page); |
830 | 826 | ||
831 | out4: | ||
832 | free_page(data_page); | ||
833 | out3: | 827 | out3: |
834 | kfree(kernel_dev); | 828 | free_page(data_page); |
835 | out2: | 829 | out2: |
836 | putname(dir); | 830 | kfree(kernel_dev); |
837 | out1: | 831 | out1: |
838 | kfree(kernel_type); | 832 | kfree(kernel_type); |
839 | out: | 833 | out: |
diff --git a/fs/dcache.c b/fs/dcache.c index cb25a1a5e307..d5a23fd0da90 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -235,18 +235,49 @@ static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *c | |||
235 | return dentry_string_cmp(cs, ct, tcount); | 235 | return dentry_string_cmp(cs, ct, tcount); |
236 | } | 236 | } |
237 | 237 | ||
238 | struct external_name { | ||
239 | union { | ||
240 | atomic_t count; | ||
241 | struct rcu_head head; | ||
242 | } u; | ||
243 | unsigned char name[]; | ||
244 | }; | ||
245 | |||
246 | static inline struct external_name *external_name(struct dentry *dentry) | ||
247 | { | ||
248 | return container_of(dentry->d_name.name, struct external_name, name[0]); | ||
249 | } | ||
250 | |||
238 | static void __d_free(struct rcu_head *head) | 251 | static void __d_free(struct rcu_head *head) |
239 | { | 252 | { |
240 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); | 253 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); |
241 | 254 | ||
242 | WARN_ON(!hlist_unhashed(&dentry->d_alias)); | 255 | WARN_ON(!hlist_unhashed(&dentry->d_alias)); |
243 | if (dname_external(dentry)) | ||
244 | kfree(dentry->d_name.name); | ||
245 | kmem_cache_free(dentry_cache, dentry); | 256 | kmem_cache_free(dentry_cache, dentry); |
246 | } | 257 | } |
247 | 258 | ||
259 | static void __d_free_external(struct rcu_head *head) | ||
260 | { | ||
261 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); | ||
262 | WARN_ON(!hlist_unhashed(&dentry->d_alias)); | ||
263 | kfree(external_name(dentry)); | ||
264 | kmem_cache_free(dentry_cache, dentry); | ||
265 | } | ||
266 | |||
267 | static inline int dname_external(const struct dentry *dentry) | ||
268 | { | ||
269 | return dentry->d_name.name != dentry->d_iname; | ||
270 | } | ||
271 | |||
248 | static void dentry_free(struct dentry *dentry) | 272 | static void dentry_free(struct dentry *dentry) |
249 | { | 273 | { |
274 | if (unlikely(dname_external(dentry))) { | ||
275 | struct external_name *p = external_name(dentry); | ||
276 | if (likely(atomic_dec_and_test(&p->u.count))) { | ||
277 | call_rcu(&dentry->d_u.d_rcu, __d_free_external); | ||
278 | return; | ||
279 | } | ||
280 | } | ||
250 | /* if dentry was never visible to RCU, immediate free is OK */ | 281 | /* if dentry was never visible to RCU, immediate free is OK */ |
251 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) | 282 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) |
252 | __d_free(&dentry->d_u.d_rcu); | 283 | __d_free(&dentry->d_u.d_rcu); |
@@ -456,7 +487,7 @@ static void __dentry_kill(struct dentry *dentry) | |||
456 | * inform the fs via d_prune that this dentry is about to be | 487 | * inform the fs via d_prune that this dentry is about to be |
457 | * unhashed and destroyed. | 488 | * unhashed and destroyed. |
458 | */ | 489 | */ |
459 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && !d_unhashed(dentry)) | 490 | if (dentry->d_flags & DCACHE_OP_PRUNE) |
460 | dentry->d_op->d_prune(dentry); | 491 | dentry->d_op->d_prune(dentry); |
461 | 492 | ||
462 | if (dentry->d_flags & DCACHE_LRU_LIST) { | 493 | if (dentry->d_flags & DCACHE_LRU_LIST) { |
@@ -619,62 +650,6 @@ kill_it: | |||
619 | } | 650 | } |
620 | EXPORT_SYMBOL(dput); | 651 | EXPORT_SYMBOL(dput); |
621 | 652 | ||
622 | /** | ||
623 | * d_invalidate - invalidate a dentry | ||
624 | * @dentry: dentry to invalidate | ||
625 | * | ||
626 | * Try to invalidate the dentry if it turns out to be | ||
627 | * possible. If there are other dentries that can be | ||
628 | * reached through this one we can't delete it and we | ||
629 | * return -EBUSY. On success we return 0. | ||
630 | * | ||
631 | * no dcache lock. | ||
632 | */ | ||
633 | |||
634 | int d_invalidate(struct dentry * dentry) | ||
635 | { | ||
636 | /* | ||
637 | * If it's already been dropped, return OK. | ||
638 | */ | ||
639 | spin_lock(&dentry->d_lock); | ||
640 | if (d_unhashed(dentry)) { | ||
641 | spin_unlock(&dentry->d_lock); | ||
642 | return 0; | ||
643 | } | ||
644 | /* | ||
645 | * Check whether to do a partial shrink_dcache | ||
646 | * to get rid of unused child entries. | ||
647 | */ | ||
648 | if (!list_empty(&dentry->d_subdirs)) { | ||
649 | spin_unlock(&dentry->d_lock); | ||
650 | shrink_dcache_parent(dentry); | ||
651 | spin_lock(&dentry->d_lock); | ||
652 | } | ||
653 | |||
654 | /* | ||
655 | * Somebody else still using it? | ||
656 | * | ||
657 | * If it's a directory, we can't drop it | ||
658 | * for fear of somebody re-populating it | ||
659 | * with children (even though dropping it | ||
660 | * would make it unreachable from the root, | ||
661 | * we might still populate it if it was a | ||
662 | * working directory or similar). | ||
663 | * We also need to leave mountpoints alone, | ||
664 | * directory or not. | ||
665 | */ | ||
666 | if (dentry->d_lockref.count > 1 && dentry->d_inode) { | ||
667 | if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) { | ||
668 | spin_unlock(&dentry->d_lock); | ||
669 | return -EBUSY; | ||
670 | } | ||
671 | } | ||
672 | |||
673 | __d_drop(dentry); | ||
674 | spin_unlock(&dentry->d_lock); | ||
675 | return 0; | ||
676 | } | ||
677 | EXPORT_SYMBOL(d_invalidate); | ||
678 | 653 | ||
679 | /* This must be called with d_lock held */ | 654 | /* This must be called with d_lock held */ |
680 | static inline void __dget_dlock(struct dentry *dentry) | 655 | static inline void __dget_dlock(struct dentry *dentry) |
@@ -735,7 +710,8 @@ EXPORT_SYMBOL(dget_parent); | |||
735 | * acquire the reference to alias and return it. Otherwise return NULL. | 710 | * acquire the reference to alias and return it. Otherwise return NULL. |
736 | * Notice that if inode is a directory there can be only one alias and | 711 | * Notice that if inode is a directory there can be only one alias and |
737 | * it can be unhashed only if it has no children, or if it is the root | 712 | * it can be unhashed only if it has no children, or if it is the root |
738 | * of a filesystem. | 713 | * of a filesystem, or if the directory was renamed and d_revalidate |
714 | * was the first vfs operation to notice. | ||
739 | * | 715 | * |
740 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer | 716 | * If the inode has an IS_ROOT, DCACHE_DISCONNECTED alias, then prefer |
741 | * any other hashed alias over that one. | 717 | * any other hashed alias over that one. |
@@ -799,20 +775,13 @@ restart: | |||
799 | hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 775 | hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { |
800 | spin_lock(&dentry->d_lock); | 776 | spin_lock(&dentry->d_lock); |
801 | if (!dentry->d_lockref.count) { | 777 | if (!dentry->d_lockref.count) { |
802 | /* | 778 | struct dentry *parent = lock_parent(dentry); |
803 | * inform the fs via d_prune that this dentry | 779 | if (likely(!dentry->d_lockref.count)) { |
804 | * is about to be unhashed and destroyed. | 780 | __dentry_kill(dentry); |
805 | */ | 781 | goto restart; |
806 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && | 782 | } |
807 | !d_unhashed(dentry)) | 783 | if (parent) |
808 | dentry->d_op->d_prune(dentry); | 784 | spin_unlock(&parent->d_lock); |
809 | |||
810 | __dget_dlock(dentry); | ||
811 | __d_drop(dentry); | ||
812 | spin_unlock(&dentry->d_lock); | ||
813 | spin_unlock(&inode->i_lock); | ||
814 | dput(dentry); | ||
815 | goto restart; | ||
816 | } | 785 | } |
817 | spin_unlock(&dentry->d_lock); | 786 | spin_unlock(&dentry->d_lock); |
818 | } | 787 | } |
@@ -1193,7 +1162,7 @@ EXPORT_SYMBOL(have_submounts); | |||
1193 | * reachable (e.g. NFS can unhash a directory dentry and then the complete | 1162 | * reachable (e.g. NFS can unhash a directory dentry and then the complete |
1194 | * subtree can become unreachable). | 1163 | * subtree can become unreachable). |
1195 | * | 1164 | * |
1196 | * Only one of check_submounts_and_drop() and d_set_mounted() must succeed. For | 1165 | * Only one of d_invalidate() and d_set_mounted() must succeed. For |
1197 | * this reason take rename_lock and d_lock on dentry and ancestors. | 1166 | * this reason take rename_lock and d_lock on dentry and ancestors. |
1198 | */ | 1167 | */ |
1199 | int d_set_mounted(struct dentry *dentry) | 1168 | int d_set_mounted(struct dentry *dentry) |
@@ -1202,7 +1171,7 @@ int d_set_mounted(struct dentry *dentry) | |||
1202 | int ret = -ENOENT; | 1171 | int ret = -ENOENT; |
1203 | write_seqlock(&rename_lock); | 1172 | write_seqlock(&rename_lock); |
1204 | for (p = dentry->d_parent; !IS_ROOT(p); p = p->d_parent) { | 1173 | for (p = dentry->d_parent; !IS_ROOT(p); p = p->d_parent) { |
1205 | /* Need exclusion wrt. check_submounts_and_drop() */ | 1174 | /* Need exclusion wrt. d_invalidate() */ |
1206 | spin_lock(&p->d_lock); | 1175 | spin_lock(&p->d_lock); |
1207 | if (unlikely(d_unhashed(p))) { | 1176 | if (unlikely(d_unhashed(p))) { |
1208 | spin_unlock(&p->d_lock); | 1177 | spin_unlock(&p->d_lock); |
@@ -1346,70 +1315,84 @@ void shrink_dcache_for_umount(struct super_block *sb) | |||
1346 | } | 1315 | } |
1347 | } | 1316 | } |
1348 | 1317 | ||
1349 | static enum d_walk_ret check_and_collect(void *_data, struct dentry *dentry) | 1318 | struct detach_data { |
1319 | struct select_data select; | ||
1320 | struct dentry *mountpoint; | ||
1321 | }; | ||
1322 | static enum d_walk_ret detach_and_collect(void *_data, struct dentry *dentry) | ||
1350 | { | 1323 | { |
1351 | struct select_data *data = _data; | 1324 | struct detach_data *data = _data; |
1352 | 1325 | ||
1353 | if (d_mountpoint(dentry)) { | 1326 | if (d_mountpoint(dentry)) { |
1354 | data->found = -EBUSY; | 1327 | __dget_dlock(dentry); |
1328 | data->mountpoint = dentry; | ||
1355 | return D_WALK_QUIT; | 1329 | return D_WALK_QUIT; |
1356 | } | 1330 | } |
1357 | 1331 | ||
1358 | return select_collect(_data, dentry); | 1332 | return select_collect(&data->select, dentry); |
1359 | } | 1333 | } |
1360 | 1334 | ||
1361 | static void check_and_drop(void *_data) | 1335 | static void check_and_drop(void *_data) |
1362 | { | 1336 | { |
1363 | struct select_data *data = _data; | 1337 | struct detach_data *data = _data; |
1364 | 1338 | ||
1365 | if (d_mountpoint(data->start)) | 1339 | if (!data->mountpoint && !data->select.found) |
1366 | data->found = -EBUSY; | 1340 | __d_drop(data->select.start); |
1367 | if (!data->found) | ||
1368 | __d_drop(data->start); | ||
1369 | } | 1341 | } |
1370 | 1342 | ||
1371 | /** | 1343 | /** |
1372 | * check_submounts_and_drop - prune dcache, check for submounts and drop | 1344 | * d_invalidate - detach submounts, prune dcache, and drop |
1345 | * @dentry: dentry to invalidate (aka detach, prune and drop) | ||
1373 | * | 1346 | * |
1374 | * All done as a single atomic operation relative to has_unlinked_ancestor(). | 1347 | * no dcache lock. |
1375 | * Returns 0 if successfully unhashed @parent. If there were submounts then | ||
1376 | * return -EBUSY. | ||
1377 | * | 1348 | * |
1378 | * @dentry: dentry to prune and drop | 1349 | * The final d_drop is done as an atomic operation relative to |
1350 | * rename_lock ensuring there are no races with d_set_mounted. This | ||
1351 | * ensures there are no unhashed dentries on the path to a mountpoint. | ||
1379 | */ | 1352 | */ |
1380 | int check_submounts_and_drop(struct dentry *dentry) | 1353 | void d_invalidate(struct dentry *dentry) |
1381 | { | 1354 | { |
1382 | int ret = 0; | 1355 | /* |
1356 | * If it's already been dropped, return OK. | ||
1357 | */ | ||
1358 | spin_lock(&dentry->d_lock); | ||
1359 | if (d_unhashed(dentry)) { | ||
1360 | spin_unlock(&dentry->d_lock); | ||
1361 | return; | ||
1362 | } | ||
1363 | spin_unlock(&dentry->d_lock); | ||
1383 | 1364 | ||
1384 | /* Negative dentries can be dropped without further checks */ | 1365 | /* Negative dentries can be dropped without further checks */ |
1385 | if (!dentry->d_inode) { | 1366 | if (!dentry->d_inode) { |
1386 | d_drop(dentry); | 1367 | d_drop(dentry); |
1387 | goto out; | 1368 | return; |
1388 | } | 1369 | } |
1389 | 1370 | ||
1390 | for (;;) { | 1371 | for (;;) { |
1391 | struct select_data data; | 1372 | struct detach_data data; |
1392 | 1373 | ||
1393 | INIT_LIST_HEAD(&data.dispose); | 1374 | data.mountpoint = NULL; |
1394 | data.start = dentry; | 1375 | INIT_LIST_HEAD(&data.select.dispose); |
1395 | data.found = 0; | 1376 | data.select.start = dentry; |
1377 | data.select.found = 0; | ||
1378 | |||
1379 | d_walk(dentry, &data, detach_and_collect, check_and_drop); | ||
1396 | 1380 | ||
1397 | d_walk(dentry, &data, check_and_collect, check_and_drop); | 1381 | if (data.select.found) |
1398 | ret = data.found; | 1382 | shrink_dentry_list(&data.select.dispose); |
1399 | 1383 | ||
1400 | if (!list_empty(&data.dispose)) | 1384 | if (data.mountpoint) { |
1401 | shrink_dentry_list(&data.dispose); | 1385 | detach_mounts(data.mountpoint); |
1386 | dput(data.mountpoint); | ||
1387 | } | ||
1402 | 1388 | ||
1403 | if (ret <= 0) | 1389 | if (!data.mountpoint && !data.select.found) |
1404 | break; | 1390 | break; |
1405 | 1391 | ||
1406 | cond_resched(); | 1392 | cond_resched(); |
1407 | } | 1393 | } |
1408 | |||
1409 | out: | ||
1410 | return ret; | ||
1411 | } | 1394 | } |
1412 | EXPORT_SYMBOL(check_submounts_and_drop); | 1395 | EXPORT_SYMBOL(d_invalidate); |
1413 | 1396 | ||
1414 | /** | 1397 | /** |
1415 | * __d_alloc - allocate a dcache entry | 1398 | * __d_alloc - allocate a dcache entry |
@@ -1438,11 +1421,14 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) | |||
1438 | */ | 1421 | */ |
1439 | dentry->d_iname[DNAME_INLINE_LEN-1] = 0; | 1422 | dentry->d_iname[DNAME_INLINE_LEN-1] = 0; |
1440 | if (name->len > DNAME_INLINE_LEN-1) { | 1423 | if (name->len > DNAME_INLINE_LEN-1) { |
1441 | dname = kmalloc(name->len + 1, GFP_KERNEL); | 1424 | size_t size = offsetof(struct external_name, name[1]); |
1442 | if (!dname) { | 1425 | struct external_name *p = kmalloc(size + name->len, GFP_KERNEL); |
1426 | if (!p) { | ||
1443 | kmem_cache_free(dentry_cache, dentry); | 1427 | kmem_cache_free(dentry_cache, dentry); |
1444 | return NULL; | 1428 | return NULL; |
1445 | } | 1429 | } |
1430 | atomic_set(&p->u.count, 1); | ||
1431 | dname = p->name; | ||
1446 | } else { | 1432 | } else { |
1447 | dname = dentry->d_iname; | 1433 | dname = dentry->d_iname; |
1448 | } | 1434 | } |
@@ -2112,10 +2098,10 @@ struct dentry *d_lookup(const struct dentry *parent, const struct qstr *name) | |||
2112 | struct dentry *dentry; | 2098 | struct dentry *dentry; |
2113 | unsigned seq; | 2099 | unsigned seq; |
2114 | 2100 | ||
2115 | do { | 2101 | do { |
2116 | seq = read_seqbegin(&rename_lock); | 2102 | seq = read_seqbegin(&rename_lock); |
2117 | dentry = __d_lookup(parent, name); | 2103 | dentry = __d_lookup(parent, name); |
2118 | if (dentry) | 2104 | if (dentry) |
2119 | break; | 2105 | break; |
2120 | } while (read_seqretry(&rename_lock, seq)); | 2106 | } while (read_seqretry(&rename_lock, seq)); |
2121 | return dentry; | 2107 | return dentry; |
@@ -2372,11 +2358,10 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name) | |||
2372 | } | 2358 | } |
2373 | EXPORT_SYMBOL(dentry_update_name_case); | 2359 | EXPORT_SYMBOL(dentry_update_name_case); |
2374 | 2360 | ||
2375 | static void switch_names(struct dentry *dentry, struct dentry *target, | 2361 | static void swap_names(struct dentry *dentry, struct dentry *target) |
2376 | bool exchange) | ||
2377 | { | 2362 | { |
2378 | if (dname_external(target)) { | 2363 | if (unlikely(dname_external(target))) { |
2379 | if (dname_external(dentry)) { | 2364 | if (unlikely(dname_external(dentry))) { |
2380 | /* | 2365 | /* |
2381 | * Both external: swap the pointers | 2366 | * Both external: swap the pointers |
2382 | */ | 2367 | */ |
@@ -2392,7 +2377,7 @@ static void switch_names(struct dentry *dentry, struct dentry *target, | |||
2392 | target->d_name.name = target->d_iname; | 2377 | target->d_name.name = target->d_iname; |
2393 | } | 2378 | } |
2394 | } else { | 2379 | } else { |
2395 | if (dname_external(dentry)) { | 2380 | if (unlikely(dname_external(dentry))) { |
2396 | /* | 2381 | /* |
2397 | * dentry:external, target:internal. Give dentry's | 2382 | * dentry:external, target:internal. Give dentry's |
2398 | * storage to target and make dentry internal | 2383 | * storage to target and make dentry internal |
@@ -2407,12 +2392,6 @@ static void switch_names(struct dentry *dentry, struct dentry *target, | |||
2407 | */ | 2392 | */ |
2408 | unsigned int i; | 2393 | unsigned int i; |
2409 | BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long))); | 2394 | BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long))); |
2410 | if (!exchange) { | ||
2411 | memcpy(dentry->d_iname, target->d_name.name, | ||
2412 | target->d_name.len + 1); | ||
2413 | dentry->d_name.hash_len = target->d_name.hash_len; | ||
2414 | return; | ||
2415 | } | ||
2416 | for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { | 2395 | for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { |
2417 | swap(((long *) &dentry->d_iname)[i], | 2396 | swap(((long *) &dentry->d_iname)[i], |
2418 | ((long *) &target->d_iname)[i]); | 2397 | ((long *) &target->d_iname)[i]); |
@@ -2422,6 +2401,24 @@ static void switch_names(struct dentry *dentry, struct dentry *target, | |||
2422 | swap(dentry->d_name.hash_len, target->d_name.hash_len); | 2401 | swap(dentry->d_name.hash_len, target->d_name.hash_len); |
2423 | } | 2402 | } |
2424 | 2403 | ||
2404 | static void copy_name(struct dentry *dentry, struct dentry *target) | ||
2405 | { | ||
2406 | struct external_name *old_name = NULL; | ||
2407 | if (unlikely(dname_external(dentry))) | ||
2408 | old_name = external_name(dentry); | ||
2409 | if (unlikely(dname_external(target))) { | ||
2410 | atomic_inc(&external_name(target)->u.count); | ||
2411 | dentry->d_name = target->d_name; | ||
2412 | } else { | ||
2413 | memcpy(dentry->d_iname, target->d_name.name, | ||
2414 | target->d_name.len + 1); | ||
2415 | dentry->d_name.name = dentry->d_iname; | ||
2416 | dentry->d_name.hash_len = target->d_name.hash_len; | ||
2417 | } | ||
2418 | if (old_name && likely(atomic_dec_and_test(&old_name->u.count))) | ||
2419 | kfree_rcu(old_name, u.head); | ||
2420 | } | ||
2421 | |||
2425 | static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target) | 2422 | static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target) |
2426 | { | 2423 | { |
2427 | /* | 2424 | /* |
@@ -2518,7 +2515,10 @@ static void __d_move(struct dentry *dentry, struct dentry *target, | |||
2518 | } | 2515 | } |
2519 | 2516 | ||
2520 | /* Switch the names.. */ | 2517 | /* Switch the names.. */ |
2521 | switch_names(dentry, target, exchange); | 2518 | if (exchange) |
2519 | swap_names(dentry, target); | ||
2520 | else | ||
2521 | copy_name(dentry, target); | ||
2522 | 2522 | ||
2523 | /* ... and switch them in the tree */ | 2523 | /* ... and switch them in the tree */ |
2524 | if (IS_ROOT(dentry)) { | 2524 | if (IS_ROOT(dentry)) { |
@@ -2625,10 +2625,8 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2625 | goto out_err; | 2625 | goto out_err; |
2626 | m2 = &alias->d_parent->d_inode->i_mutex; | 2626 | m2 = &alias->d_parent->d_inode->i_mutex; |
2627 | out_unalias: | 2627 | out_unalias: |
2628 | if (likely(!d_mountpoint(alias))) { | 2628 | __d_move(alias, dentry, false); |
2629 | __d_move(alias, dentry, false); | 2629 | ret = alias; |
2630 | ret = alias; | ||
2631 | } | ||
2632 | out_err: | 2630 | out_err: |
2633 | spin_unlock(&inode->i_lock); | 2631 | spin_unlock(&inode->i_lock); |
2634 | if (m2) | 2632 | if (m2) |
@@ -2810,6 +2808,9 @@ static int prepend(char **buffer, int *buflen, const char *str, int namelen) | |||
2810 | * the beginning of the name. The sequence number check at the caller will | 2808 | * the beginning of the name. The sequence number check at the caller will |
2811 | * retry it again when a d_move() does happen. So any garbage in the buffer | 2809 | * retry it again when a d_move() does happen. So any garbage in the buffer |
2812 | * due to mismatched pointer and length will be discarded. | 2810 | * due to mismatched pointer and length will be discarded. |
2811 | * | ||
2812 | * Data dependency barrier is needed to make sure that we see that terminating | ||
2813 | * NUL. Alpha strikes again, film at 11... | ||
2813 | */ | 2814 | */ |
2814 | static int prepend_name(char **buffer, int *buflen, struct qstr *name) | 2815 | static int prepend_name(char **buffer, int *buflen, struct qstr *name) |
2815 | { | 2816 | { |
@@ -2817,6 +2818,8 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
2817 | u32 dlen = ACCESS_ONCE(name->len); | 2818 | u32 dlen = ACCESS_ONCE(name->len); |
2818 | char *p; | 2819 | char *p; |
2819 | 2820 | ||
2821 | smp_read_barrier_depends(); | ||
2822 | |||
2820 | *buflen -= dlen + 1; | 2823 | *buflen -= dlen + 1; |
2821 | if (*buflen < 0) | 2824 | if (*buflen < 0) |
2822 | return -ENAMETOOLONG; | 2825 | return -ENAMETOOLONG; |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index b4b6ab9873ae..f5bce9096555 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -327,7 +327,7 @@ ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
327 | struct file *lower_file = ecryptfs_file_to_lower(file); | 327 | struct file *lower_file = ecryptfs_file_to_lower(file); |
328 | long rc = -ENOIOCTLCMD; | 328 | long rc = -ENOIOCTLCMD; |
329 | 329 | ||
330 | if (lower_file->f_op && lower_file->f_op->compat_ioctl) | 330 | if (lower_file->f_op->compat_ioctl) |
331 | rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); | 331 | rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); |
332 | return rc; | 332 | return rc; |
333 | } | 333 | } |
@@ -1372,18 +1372,23 @@ int search_binary_handler(struct linux_binprm *bprm) | |||
1372 | read_unlock(&binfmt_lock); | 1372 | read_unlock(&binfmt_lock); |
1373 | bprm->recursion_depth++; | 1373 | bprm->recursion_depth++; |
1374 | retval = fmt->load_binary(bprm); | 1374 | retval = fmt->load_binary(bprm); |
1375 | read_lock(&binfmt_lock); | ||
1376 | put_binfmt(fmt); | ||
1375 | bprm->recursion_depth--; | 1377 | bprm->recursion_depth--; |
1376 | if (retval >= 0 || retval != -ENOEXEC || | 1378 | if (retval < 0 && !bprm->mm) { |
1377 | bprm->mm == NULL || bprm->file == NULL) { | 1379 | /* we got to flush_old_exec() and failed after it */ |
1378 | put_binfmt(fmt); | 1380 | read_unlock(&binfmt_lock); |
1381 | force_sigsegv(SIGSEGV, current); | ||
1382 | return retval; | ||
1383 | } | ||
1384 | if (retval != -ENOEXEC || !bprm->file) { | ||
1385 | read_unlock(&binfmt_lock); | ||
1379 | return retval; | 1386 | return retval; |
1380 | } | 1387 | } |
1381 | read_lock(&binfmt_lock); | ||
1382 | put_binfmt(fmt); | ||
1383 | } | 1388 | } |
1384 | read_unlock(&binfmt_lock); | 1389 | read_unlock(&binfmt_lock); |
1385 | 1390 | ||
1386 | if (need_retry && retval == -ENOEXEC) { | 1391 | if (need_retry) { |
1387 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && | 1392 | if (printable(bprm->buf[0]) && printable(bprm->buf[1]) && |
1388 | printable(bprm->buf[2]) && printable(bprm->buf[3])) | 1393 | printable(bprm->buf[2]) && printable(bprm->buf[3])) |
1389 | return retval; | 1394 | return retval; |
@@ -750,6 +750,7 @@ bool get_close_on_exec(unsigned int fd) | |||
750 | 750 | ||
751 | static int do_dup2(struct files_struct *files, | 751 | static int do_dup2(struct files_struct *files, |
752 | struct file *file, unsigned fd, unsigned flags) | 752 | struct file *file, unsigned fd, unsigned flags) |
753 | __releases(&files->file_lock) | ||
753 | { | 754 | { |
754 | struct file *tofree; | 755 | struct file *tofree; |
755 | struct fdtable *fdt; | 756 | struct fdtable *fdt; |
diff --git a/fs/file_table.c b/fs/file_table.c index 0bab12b20460..3f85411b03ce 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -150,18 +150,10 @@ over: | |||
150 | 150 | ||
151 | /** | 151 | /** |
152 | * alloc_file - allocate and initialize a 'struct file' | 152 | * alloc_file - allocate and initialize a 'struct file' |
153 | * @mnt: the vfsmount on which the file will reside | 153 | * |
154 | * @dentry: the dentry representing the new file | 154 | * @path: the (dentry, vfsmount) pair for the new file |
155 | * @mode: the mode with which the new file will be opened | 155 | * @mode: the mode with which the new file will be opened |
156 | * @fop: the 'struct file_operations' for the new file | 156 | * @fop: the 'struct file_operations' for the new file |
157 | * | ||
158 | * Use this instead of get_empty_filp() to get a new | ||
159 | * 'struct file'. Do so because of the same initialization | ||
160 | * pitfalls reasons listed for init_file(). This is a | ||
161 | * preferred interface to using init_file(). | ||
162 | * | ||
163 | * If all the callers of init_file() are eliminated, its | ||
164 | * code should be moved into this function. | ||
165 | */ | 157 | */ |
166 | struct file *alloc_file(struct path *path, fmode_t mode, | 158 | struct file *alloc_file(struct path *path, fmode_t mode, |
167 | const struct file_operations *fop) | 159 | const struct file_operations *fop) |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index de1d84af9f7c..dbab798f5caf 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -274,9 +274,6 @@ out: | |||
274 | 274 | ||
275 | invalid: | 275 | invalid: |
276 | ret = 0; | 276 | ret = 0; |
277 | |||
278 | if (!(flags & LOOKUP_RCU) && check_submounts_and_drop(entry) != 0) | ||
279 | ret = 1; | ||
280 | goto out; | 277 | goto out; |
281 | } | 278 | } |
282 | 279 | ||
@@ -1289,9 +1286,7 @@ static int fuse_direntplus_link(struct file *file, | |||
1289 | d_drop(dentry); | 1286 | d_drop(dentry); |
1290 | } else if (get_node_id(inode) != o->nodeid || | 1287 | } else if (get_node_id(inode) != o->nodeid || |
1291 | ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { | 1288 | ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { |
1292 | err = d_invalidate(dentry); | 1289 | d_invalidate(dentry); |
1293 | if (err) | ||
1294 | goto out; | ||
1295 | } else if (is_bad_inode(inode)) { | 1290 | } else if (is_bad_inode(inode)) { |
1296 | err = -EIO; | 1291 | err = -EIO; |
1297 | goto out; | 1292 | goto out; |
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c index d3a5d4e29ba5..589f4ea9381c 100644 --- a/fs/gfs2/dentry.c +++ b/fs/gfs2/dentry.c | |||
@@ -93,9 +93,6 @@ invalid_gunlock: | |||
93 | if (!had_lock) | 93 | if (!had_lock) |
94 | gfs2_glock_dq_uninit(&d_gh); | 94 | gfs2_glock_dq_uninit(&d_gh); |
95 | invalid: | 95 | invalid: |
96 | if (check_submounts_and_drop(dentry) != 0) | ||
97 | goto valid; | ||
98 | |||
99 | dput(parent); | 96 | dput(parent); |
100 | return 0; | 97 | return 0; |
101 | 98 | ||
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index fcf42eadb69c..c4ed823d150e 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -1245,6 +1245,9 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1245 | struct dentry *d; | 1245 | struct dentry *d; |
1246 | bool excl = !!(flags & O_EXCL); | 1246 | bool excl = !!(flags & O_EXCL); |
1247 | 1247 | ||
1248 | if (!d_unhashed(dentry)) | ||
1249 | goto skip_lookup; | ||
1250 | |||
1248 | d = __gfs2_lookup(dir, dentry, file, opened); | 1251 | d = __gfs2_lookup(dir, dentry, file, opened); |
1249 | if (IS_ERR(d)) | 1252 | if (IS_ERR(d)) |
1250 | return PTR_ERR(d); | 1253 | return PTR_ERR(d); |
@@ -1261,6 +1264,8 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1261 | } | 1264 | } |
1262 | 1265 | ||
1263 | BUG_ON(d != NULL); | 1266 | BUG_ON(d != NULL); |
1267 | |||
1268 | skip_lookup: | ||
1264 | if (!(flags & O_CREAT)) | 1269 | if (!(flags & O_CREAT)) |
1265 | return -ENOENT; | 1270 | return -ENOENT; |
1266 | 1271 | ||
diff --git a/fs/internal.h b/fs/internal.h index b2623200107b..9477f8f6aefc 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -56,7 +56,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, | |||
56 | * namespace.c | 56 | * namespace.c |
57 | */ | 57 | */ |
58 | extern int copy_mount_options(const void __user *, unsigned long *); | 58 | extern int copy_mount_options(const void __user *, unsigned long *); |
59 | extern int copy_mount_string(const void __user *, char **); | 59 | extern char *copy_mount_string(const void __user *); |
60 | 60 | ||
61 | extern struct vfsmount *lookup_mnt(struct path *); | 61 | extern struct vfsmount *lookup_mnt(struct path *); |
62 | extern int finish_automount(struct vfsmount *, struct path *); | 62 | extern int finish_automount(struct vfsmount *, struct path *); |
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index 413ef89c2d1b..046fee8b6e9b 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h | |||
@@ -134,8 +134,6 @@ struct jffs2_sb_info { | |||
134 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ | 134 | struct rw_semaphore wbuf_sem; /* Protects the write buffer */ |
135 | 135 | ||
136 | struct delayed_work wbuf_dwork; /* write-buffer write-out work */ | 136 | struct delayed_work wbuf_dwork; /* write-buffer write-out work */ |
137 | int wbuf_queued; /* non-zero delayed work is queued */ | ||
138 | spinlock_t wbuf_dwork_lock; /* protects wbuf_dwork and and wbuf_queued */ | ||
139 | 137 | ||
140 | unsigned char *oobbuf; | 138 | unsigned char *oobbuf; |
141 | int oobavail; /* How many bytes are available for JFFS2 in OOB */ | 139 | int oobavail; /* How many bytes are available for JFFS2 in OOB */ |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index a6597d60d76d..09ed55190ee2 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -1162,10 +1162,6 @@ static void delayed_wbuf_sync(struct work_struct *work) | |||
1162 | struct jffs2_sb_info *c = work_to_sb(work); | 1162 | struct jffs2_sb_info *c = work_to_sb(work); |
1163 | struct super_block *sb = OFNI_BS_2SFFJ(c); | 1163 | struct super_block *sb = OFNI_BS_2SFFJ(c); |
1164 | 1164 | ||
1165 | spin_lock(&c->wbuf_dwork_lock); | ||
1166 | c->wbuf_queued = 0; | ||
1167 | spin_unlock(&c->wbuf_dwork_lock); | ||
1168 | |||
1169 | if (!(sb->s_flags & MS_RDONLY)) { | 1165 | if (!(sb->s_flags & MS_RDONLY)) { |
1170 | jffs2_dbg(1, "%s()\n", __func__); | 1166 | jffs2_dbg(1, "%s()\n", __func__); |
1171 | jffs2_flush_wbuf_gc(c, 0); | 1167 | jffs2_flush_wbuf_gc(c, 0); |
@@ -1180,14 +1176,9 @@ void jffs2_dirty_trigger(struct jffs2_sb_info *c) | |||
1180 | if (sb->s_flags & MS_RDONLY) | 1176 | if (sb->s_flags & MS_RDONLY) |
1181 | return; | 1177 | return; |
1182 | 1178 | ||
1183 | spin_lock(&c->wbuf_dwork_lock); | 1179 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); |
1184 | if (!c->wbuf_queued) { | 1180 | if (queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay)) |
1185 | jffs2_dbg(1, "%s()\n", __func__); | 1181 | jffs2_dbg(1, "%s()\n", __func__); |
1186 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
1187 | queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay); | ||
1188 | c->wbuf_queued = 1; | ||
1189 | } | ||
1190 | spin_unlock(&c->wbuf_dwork_lock); | ||
1191 | } | 1182 | } |
1192 | 1183 | ||
1193 | int jffs2_nand_flash_setup(struct jffs2_sb_info *c) | 1184 | int jffs2_nand_flash_setup(struct jffs2_sb_info *c) |
@@ -1211,7 +1202,6 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c) | |||
1211 | 1202 | ||
1212 | /* Initialise write buffer */ | 1203 | /* Initialise write buffer */ |
1213 | init_rwsem(&c->wbuf_sem); | 1204 | init_rwsem(&c->wbuf_sem); |
1214 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1215 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1205 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1216 | c->wbuf_pagesize = c->mtd->writesize; | 1206 | c->wbuf_pagesize = c->mtd->writesize; |
1217 | c->wbuf_ofs = 0xFFFFFFFF; | 1207 | c->wbuf_ofs = 0xFFFFFFFF; |
@@ -1251,7 +1241,6 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) { | |||
1251 | 1241 | ||
1252 | /* Initialize write buffer */ | 1242 | /* Initialize write buffer */ |
1253 | init_rwsem(&c->wbuf_sem); | 1243 | init_rwsem(&c->wbuf_sem); |
1254 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1255 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1244 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1256 | c->wbuf_pagesize = c->mtd->erasesize; | 1245 | c->wbuf_pagesize = c->mtd->erasesize; |
1257 | 1246 | ||
@@ -1311,7 +1300,6 @@ int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) { | |||
1311 | 1300 | ||
1312 | /* Initialize write buffer */ | 1301 | /* Initialize write buffer */ |
1313 | init_rwsem(&c->wbuf_sem); | 1302 | init_rwsem(&c->wbuf_sem); |
1314 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1315 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1303 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1316 | 1304 | ||
1317 | c->wbuf_pagesize = c->mtd->writesize; | 1305 | c->wbuf_pagesize = c->mtd->writesize; |
@@ -1346,7 +1334,6 @@ int jffs2_ubivol_setup(struct jffs2_sb_info *c) { | |||
1346 | return 0; | 1334 | return 0; |
1347 | 1335 | ||
1348 | init_rwsem(&c->wbuf_sem); | 1336 | init_rwsem(&c->wbuf_sem); |
1349 | spin_lock_init(&c->wbuf_dwork_lock); | ||
1350 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); | 1337 | INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); |
1351 | 1338 | ||
1352 | c->wbuf_pagesize = c->mtd->writesize; | 1339 | c->wbuf_pagesize = c->mtd->writesize; |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index adf8cb045b9e..93e897e588a8 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -550,7 +550,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
550 | inode->i_ino = 0; | 550 | inode->i_ino = 0; |
551 | inode->i_size = sb->s_bdev->bd_inode->i_size; | 551 | inode->i_size = sb->s_bdev->bd_inode->i_size; |
552 | inode->i_mapping->a_ops = &jfs_metapage_aops; | 552 | inode->i_mapping->a_ops = &jfs_metapage_aops; |
553 | insert_inode_hash(inode); | 553 | hlist_add_fake(&inode->i_hash); |
554 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); | 554 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); |
555 | 555 | ||
556 | sbi->direct_inode = inode; | 556 | sbi->direct_inode = inode; |
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index a693f5b01ae6..1c771931bb60 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -463,21 +463,10 @@ static int kernfs_dop_revalidate(struct dentry *dentry, unsigned int flags) | |||
463 | goto out_bad; | 463 | goto out_bad; |
464 | 464 | ||
465 | mutex_unlock(&kernfs_mutex); | 465 | mutex_unlock(&kernfs_mutex); |
466 | out_valid: | ||
467 | return 1; | 466 | return 1; |
468 | out_bad: | 467 | out_bad: |
469 | mutex_unlock(&kernfs_mutex); | 468 | mutex_unlock(&kernfs_mutex); |
470 | out_bad_unlocked: | 469 | out_bad_unlocked: |
471 | /* | ||
472 | * @dentry doesn't match the underlying kernfs node, drop the | ||
473 | * dentry and force lookup. If we have submounts we must allow the | ||
474 | * vfs caches to lie about the state of the filesystem to prevent | ||
475 | * leaks and other nasty things, so use check_submounts_and_drop() | ||
476 | * instead of d_drop(). | ||
477 | */ | ||
478 | if (check_submounts_and_drop(dentry) != 0) | ||
479 | goto out_valid; | ||
480 | |||
481 | return 0; | 470 | return 0; |
482 | } | 471 | } |
483 | 472 | ||
diff --git a/fs/mount.h b/fs/mount.h index 6740a6215529..f82c62840905 100644 --- a/fs/mount.h +++ b/fs/mount.h | |||
@@ -21,6 +21,7 @@ struct mnt_pcp { | |||
21 | struct mountpoint { | 21 | struct mountpoint { |
22 | struct hlist_node m_hash; | 22 | struct hlist_node m_hash; |
23 | struct dentry *m_dentry; | 23 | struct dentry *m_dentry; |
24 | struct hlist_head m_list; | ||
24 | int m_count; | 25 | int m_count; |
25 | }; | 26 | }; |
26 | 27 | ||
@@ -29,7 +30,10 @@ struct mount { | |||
29 | struct mount *mnt_parent; | 30 | struct mount *mnt_parent; |
30 | struct dentry *mnt_mountpoint; | 31 | struct dentry *mnt_mountpoint; |
31 | struct vfsmount mnt; | 32 | struct vfsmount mnt; |
32 | struct rcu_head mnt_rcu; | 33 | union { |
34 | struct rcu_head mnt_rcu; | ||
35 | struct llist_node mnt_llist; | ||
36 | }; | ||
33 | #ifdef CONFIG_SMP | 37 | #ifdef CONFIG_SMP |
34 | struct mnt_pcp __percpu *mnt_pcp; | 38 | struct mnt_pcp __percpu *mnt_pcp; |
35 | #else | 39 | #else |
@@ -48,6 +52,7 @@ struct mount { | |||
48 | struct mount *mnt_master; /* slave is on master->mnt_slave_list */ | 52 | struct mount *mnt_master; /* slave is on master->mnt_slave_list */ |
49 | struct mnt_namespace *mnt_ns; /* containing namespace */ | 53 | struct mnt_namespace *mnt_ns; /* containing namespace */ |
50 | struct mountpoint *mnt_mp; /* where is it mounted */ | 54 | struct mountpoint *mnt_mp; /* where is it mounted */ |
55 | struct hlist_node mnt_mp_list; /* list mounts with the same mountpoint */ | ||
51 | #ifdef CONFIG_FSNOTIFY | 56 | #ifdef CONFIG_FSNOTIFY |
52 | struct hlist_head mnt_fsnotify_marks; | 57 | struct hlist_head mnt_fsnotify_marks; |
53 | __u32 mnt_fsnotify_mask; | 58 | __u32 mnt_fsnotify_mask; |
@@ -82,6 +87,15 @@ extern struct mount *__lookup_mnt_last(struct vfsmount *, struct dentry *); | |||
82 | 87 | ||
83 | extern bool legitimize_mnt(struct vfsmount *, unsigned); | 88 | extern bool legitimize_mnt(struct vfsmount *, unsigned); |
84 | 89 | ||
90 | extern void __detach_mounts(struct dentry *dentry); | ||
91 | |||
92 | static inline void detach_mounts(struct dentry *dentry) | ||
93 | { | ||
94 | if (!d_mountpoint(dentry)) | ||
95 | return; | ||
96 | __detach_mounts(dentry); | ||
97 | } | ||
98 | |||
85 | static inline void get_mnt_ns(struct mnt_namespace *ns) | 99 | static inline void get_mnt_ns(struct mnt_namespace *ns) |
86 | { | 100 | { |
87 | atomic_inc(&ns->count); | 101 | atomic_inc(&ns->count); |
@@ -112,3 +126,12 @@ struct proc_mounts { | |||
112 | #define proc_mounts(p) (container_of((p), struct proc_mounts, m)) | 126 | #define proc_mounts(p) (container_of((p), struct proc_mounts, m)) |
113 | 127 | ||
114 | extern const struct seq_operations mounts_op; | 128 | extern const struct seq_operations mounts_op; |
129 | |||
130 | extern bool __is_local_mountpoint(struct dentry *dentry); | ||
131 | static inline bool is_local_mountpoint(struct dentry *dentry) | ||
132 | { | ||
133 | if (!d_mountpoint(dentry)) | ||
134 | return false; | ||
135 | |||
136 | return __is_local_mountpoint(dentry); | ||
137 | } | ||
diff --git a/fs/namei.c b/fs/namei.c index 3ddb044f3702..43927d14db67 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1306,7 +1306,8 @@ static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, | |||
1306 | if (error < 0) { | 1306 | if (error < 0) { |
1307 | dput(dentry); | 1307 | dput(dentry); |
1308 | return ERR_PTR(error); | 1308 | return ERR_PTR(error); |
1309 | } else if (!d_invalidate(dentry)) { | 1309 | } else { |
1310 | d_invalidate(dentry); | ||
1310 | dput(dentry); | 1311 | dput(dentry); |
1311 | dentry = NULL; | 1312 | dentry = NULL; |
1312 | } | 1313 | } |
@@ -1435,10 +1436,9 @@ unlazy: | |||
1435 | dput(dentry); | 1436 | dput(dentry); |
1436 | return status; | 1437 | return status; |
1437 | } | 1438 | } |
1438 | if (!d_invalidate(dentry)) { | 1439 | d_invalidate(dentry); |
1439 | dput(dentry); | 1440 | dput(dentry); |
1440 | goto need_lookup; | 1441 | goto need_lookup; |
1441 | } | ||
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | path->mnt = mnt; | 1444 | path->mnt = mnt; |
@@ -1950,7 +1950,7 @@ static int path_lookupat(int dfd, const char *name, | |||
1950 | err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base); | 1950 | err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base); |
1951 | 1951 | ||
1952 | if (unlikely(err)) | 1952 | if (unlikely(err)) |
1953 | return err; | 1953 | goto out; |
1954 | 1954 | ||
1955 | current->total_link_count = 0; | 1955 | current->total_link_count = 0; |
1956 | err = link_path_walk(name, nd); | 1956 | err = link_path_walk(name, nd); |
@@ -1982,6 +1982,7 @@ static int path_lookupat(int dfd, const char *name, | |||
1982 | } | 1982 | } |
1983 | } | 1983 | } |
1984 | 1984 | ||
1985 | out: | ||
1985 | if (base) | 1986 | if (base) |
1986 | fput(base); | 1987 | fput(base); |
1987 | 1988 | ||
@@ -2301,7 +2302,7 @@ path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags | |||
2301 | 2302 | ||
2302 | err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base); | 2303 | err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base); |
2303 | if (unlikely(err)) | 2304 | if (unlikely(err)) |
2304 | return err; | 2305 | goto out; |
2305 | 2306 | ||
2306 | current->total_link_count = 0; | 2307 | current->total_link_count = 0; |
2307 | err = link_path_walk(name, &nd); | 2308 | err = link_path_walk(name, &nd); |
@@ -3565,7 +3566,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
3565 | mutex_lock(&dentry->d_inode->i_mutex); | 3566 | mutex_lock(&dentry->d_inode->i_mutex); |
3566 | 3567 | ||
3567 | error = -EBUSY; | 3568 | error = -EBUSY; |
3568 | if (d_mountpoint(dentry)) | 3569 | if (is_local_mountpoint(dentry)) |
3569 | goto out; | 3570 | goto out; |
3570 | 3571 | ||
3571 | error = security_inode_rmdir(dir, dentry); | 3572 | error = security_inode_rmdir(dir, dentry); |
@@ -3579,6 +3580,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
3579 | 3580 | ||
3580 | dentry->d_inode->i_flags |= S_DEAD; | 3581 | dentry->d_inode->i_flags |= S_DEAD; |
3581 | dont_mount(dentry); | 3582 | dont_mount(dentry); |
3583 | detach_mounts(dentry); | ||
3582 | 3584 | ||
3583 | out: | 3585 | out: |
3584 | mutex_unlock(&dentry->d_inode->i_mutex); | 3586 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -3681,7 +3683,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate | |||
3681 | return -EPERM; | 3683 | return -EPERM; |
3682 | 3684 | ||
3683 | mutex_lock(&target->i_mutex); | 3685 | mutex_lock(&target->i_mutex); |
3684 | if (d_mountpoint(dentry)) | 3686 | if (is_local_mountpoint(dentry)) |
3685 | error = -EBUSY; | 3687 | error = -EBUSY; |
3686 | else { | 3688 | else { |
3687 | error = security_inode_unlink(dir, dentry); | 3689 | error = security_inode_unlink(dir, dentry); |
@@ -3690,8 +3692,10 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate | |||
3690 | if (error) | 3692 | if (error) |
3691 | goto out; | 3693 | goto out; |
3692 | error = dir->i_op->unlink(dir, dentry); | 3694 | error = dir->i_op->unlink(dir, dentry); |
3693 | if (!error) | 3695 | if (!error) { |
3694 | dont_mount(dentry); | 3696 | dont_mount(dentry); |
3697 | detach_mounts(dentry); | ||
3698 | } | ||
3695 | } | 3699 | } |
3696 | } | 3700 | } |
3697 | out: | 3701 | out: |
@@ -4126,7 +4130,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4126 | mutex_lock(&target->i_mutex); | 4130 | mutex_lock(&target->i_mutex); |
4127 | 4131 | ||
4128 | error = -EBUSY; | 4132 | error = -EBUSY; |
4129 | if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry)) | 4133 | if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry)) |
4130 | goto out; | 4134 | goto out; |
4131 | 4135 | ||
4132 | if (max_links && new_dir != old_dir) { | 4136 | if (max_links && new_dir != old_dir) { |
@@ -4164,6 +4168,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4164 | if (is_dir) | 4168 | if (is_dir) |
4165 | target->i_flags |= S_DEAD; | 4169 | target->i_flags |= S_DEAD; |
4166 | dont_mount(new_dentry); | 4170 | dont_mount(new_dentry); |
4171 | detach_mounts(new_dentry); | ||
4167 | } | 4172 | } |
4168 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) { | 4173 | if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) { |
4169 | if (!(flags & RENAME_EXCHANGE)) | 4174 | if (!(flags & RENAME_EXCHANGE)) |
diff --git a/fs/namespace.c b/fs/namespace.c index ef42d9bee212..348562f14e93 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/proc_ns.h> | 23 | #include <linux/proc_ns.h> |
24 | #include <linux/magic.h> | 24 | #include <linux/magic.h> |
25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
26 | #include <linux/task_work.h> | ||
26 | #include "pnode.h" | 27 | #include "pnode.h" |
27 | #include "internal.h" | 28 | #include "internal.h" |
28 | 29 | ||
@@ -224,6 +225,7 @@ static struct mount *alloc_vfsmnt(const char *name) | |||
224 | INIT_LIST_HEAD(&mnt->mnt_share); | 225 | INIT_LIST_HEAD(&mnt->mnt_share); |
225 | INIT_LIST_HEAD(&mnt->mnt_slave_list); | 226 | INIT_LIST_HEAD(&mnt->mnt_slave_list); |
226 | INIT_LIST_HEAD(&mnt->mnt_slave); | 227 | INIT_LIST_HEAD(&mnt->mnt_slave); |
228 | INIT_HLIST_NODE(&mnt->mnt_mp_list); | ||
227 | #ifdef CONFIG_FSNOTIFY | 229 | #ifdef CONFIG_FSNOTIFY |
228 | INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); | 230 | INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); |
229 | #endif | 231 | #endif |
@@ -666,11 +668,45 @@ struct vfsmount *lookup_mnt(struct path *path) | |||
666 | return m; | 668 | return m; |
667 | } | 669 | } |
668 | 670 | ||
669 | static struct mountpoint *new_mountpoint(struct dentry *dentry) | 671 | /* |
672 | * __is_local_mountpoint - Test to see if dentry is a mountpoint in the | ||
673 | * current mount namespace. | ||
674 | * | ||
675 | * The common case is dentries are not mountpoints at all and that | ||
676 | * test is handled inline. For the slow case when we are actually | ||
677 | * dealing with a mountpoint of some kind, walk through all of the | ||
678 | * mounts in the current mount namespace and test to see if the dentry | ||
679 | * is a mountpoint. | ||
680 | * | ||
681 | * The mount_hashtable is not usable in the context because we | ||
682 | * need to identify all mounts that may be in the current mount | ||
683 | * namespace not just a mount that happens to have some specified | ||
684 | * parent mount. | ||
685 | */ | ||
686 | bool __is_local_mountpoint(struct dentry *dentry) | ||
687 | { | ||
688 | struct mnt_namespace *ns = current->nsproxy->mnt_ns; | ||
689 | struct mount *mnt; | ||
690 | bool is_covered = false; | ||
691 | |||
692 | if (!d_mountpoint(dentry)) | ||
693 | goto out; | ||
694 | |||
695 | down_read(&namespace_sem); | ||
696 | list_for_each_entry(mnt, &ns->list, mnt_list) { | ||
697 | is_covered = (mnt->mnt_mountpoint == dentry); | ||
698 | if (is_covered) | ||
699 | break; | ||
700 | } | ||
701 | up_read(&namespace_sem); | ||
702 | out: | ||
703 | return is_covered; | ||
704 | } | ||
705 | |||
706 | static struct mountpoint *lookup_mountpoint(struct dentry *dentry) | ||
670 | { | 707 | { |
671 | struct hlist_head *chain = mp_hash(dentry); | 708 | struct hlist_head *chain = mp_hash(dentry); |
672 | struct mountpoint *mp; | 709 | struct mountpoint *mp; |
673 | int ret; | ||
674 | 710 | ||
675 | hlist_for_each_entry(mp, chain, m_hash) { | 711 | hlist_for_each_entry(mp, chain, m_hash) { |
676 | if (mp->m_dentry == dentry) { | 712 | if (mp->m_dentry == dentry) { |
@@ -681,6 +717,14 @@ static struct mountpoint *new_mountpoint(struct dentry *dentry) | |||
681 | return mp; | 717 | return mp; |
682 | } | 718 | } |
683 | } | 719 | } |
720 | return NULL; | ||
721 | } | ||
722 | |||
723 | static struct mountpoint *new_mountpoint(struct dentry *dentry) | ||
724 | { | ||
725 | struct hlist_head *chain = mp_hash(dentry); | ||
726 | struct mountpoint *mp; | ||
727 | int ret; | ||
684 | 728 | ||
685 | mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); | 729 | mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); |
686 | if (!mp) | 730 | if (!mp) |
@@ -695,6 +739,7 @@ static struct mountpoint *new_mountpoint(struct dentry *dentry) | |||
695 | mp->m_dentry = dentry; | 739 | mp->m_dentry = dentry; |
696 | mp->m_count = 1; | 740 | mp->m_count = 1; |
697 | hlist_add_head(&mp->m_hash, chain); | 741 | hlist_add_head(&mp->m_hash, chain); |
742 | INIT_HLIST_HEAD(&mp->m_list); | ||
698 | return mp; | 743 | return mp; |
699 | } | 744 | } |
700 | 745 | ||
@@ -702,6 +747,7 @@ static void put_mountpoint(struct mountpoint *mp) | |||
702 | { | 747 | { |
703 | if (!--mp->m_count) { | 748 | if (!--mp->m_count) { |
704 | struct dentry *dentry = mp->m_dentry; | 749 | struct dentry *dentry = mp->m_dentry; |
750 | BUG_ON(!hlist_empty(&mp->m_list)); | ||
705 | spin_lock(&dentry->d_lock); | 751 | spin_lock(&dentry->d_lock); |
706 | dentry->d_flags &= ~DCACHE_MOUNTED; | 752 | dentry->d_flags &= ~DCACHE_MOUNTED; |
707 | spin_unlock(&dentry->d_lock); | 753 | spin_unlock(&dentry->d_lock); |
@@ -748,6 +794,7 @@ static void detach_mnt(struct mount *mnt, struct path *old_path) | |||
748 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; | 794 | mnt->mnt_mountpoint = mnt->mnt.mnt_root; |
749 | list_del_init(&mnt->mnt_child); | 795 | list_del_init(&mnt->mnt_child); |
750 | hlist_del_init_rcu(&mnt->mnt_hash); | 796 | hlist_del_init_rcu(&mnt->mnt_hash); |
797 | hlist_del_init(&mnt->mnt_mp_list); | ||
751 | put_mountpoint(mnt->mnt_mp); | 798 | put_mountpoint(mnt->mnt_mp); |
752 | mnt->mnt_mp = NULL; | 799 | mnt->mnt_mp = NULL; |
753 | } | 800 | } |
@@ -764,6 +811,7 @@ void mnt_set_mountpoint(struct mount *mnt, | |||
764 | child_mnt->mnt_mountpoint = dget(mp->m_dentry); | 811 | child_mnt->mnt_mountpoint = dget(mp->m_dentry); |
765 | child_mnt->mnt_parent = mnt; | 812 | child_mnt->mnt_parent = mnt; |
766 | child_mnt->mnt_mp = mp; | 813 | child_mnt->mnt_mp = mp; |
814 | hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list); | ||
767 | } | 815 | } |
768 | 816 | ||
769 | /* | 817 | /* |
@@ -957,6 +1005,46 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | |||
957 | return ERR_PTR(err); | 1005 | return ERR_PTR(err); |
958 | } | 1006 | } |
959 | 1007 | ||
1008 | static void cleanup_mnt(struct mount *mnt) | ||
1009 | { | ||
1010 | /* | ||
1011 | * This probably indicates that somebody messed | ||
1012 | * up a mnt_want/drop_write() pair. If this | ||
1013 | * happens, the filesystem was probably unable | ||
1014 | * to make r/w->r/o transitions. | ||
1015 | */ | ||
1016 | /* | ||
1017 | * The locking used to deal with mnt_count decrement provides barriers, | ||
1018 | * so mnt_get_writers() below is safe. | ||
1019 | */ | ||
1020 | WARN_ON(mnt_get_writers(mnt)); | ||
1021 | if (unlikely(mnt->mnt_pins.first)) | ||
1022 | mnt_pin_kill(mnt); | ||
1023 | fsnotify_vfsmount_delete(&mnt->mnt); | ||
1024 | dput(mnt->mnt.mnt_root); | ||
1025 | deactivate_super(mnt->mnt.mnt_sb); | ||
1026 | mnt_free_id(mnt); | ||
1027 | call_rcu(&mnt->mnt_rcu, delayed_free_vfsmnt); | ||
1028 | } | ||
1029 | |||
1030 | static void __cleanup_mnt(struct rcu_head *head) | ||
1031 | { | ||
1032 | cleanup_mnt(container_of(head, struct mount, mnt_rcu)); | ||
1033 | } | ||
1034 | |||
1035 | static LLIST_HEAD(delayed_mntput_list); | ||
1036 | static void delayed_mntput(struct work_struct *unused) | ||
1037 | { | ||
1038 | struct llist_node *node = llist_del_all(&delayed_mntput_list); | ||
1039 | struct llist_node *next; | ||
1040 | |||
1041 | for (; node; node = next) { | ||
1042 | next = llist_next(node); | ||
1043 | cleanup_mnt(llist_entry(node, struct mount, mnt_llist)); | ||
1044 | } | ||
1045 | } | ||
1046 | static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput); | ||
1047 | |||
960 | static void mntput_no_expire(struct mount *mnt) | 1048 | static void mntput_no_expire(struct mount *mnt) |
961 | { | 1049 | { |
962 | rcu_read_lock(); | 1050 | rcu_read_lock(); |
@@ -982,24 +1070,18 @@ static void mntput_no_expire(struct mount *mnt) | |||
982 | list_del(&mnt->mnt_instance); | 1070 | list_del(&mnt->mnt_instance); |
983 | unlock_mount_hash(); | 1071 | unlock_mount_hash(); |
984 | 1072 | ||
985 | /* | 1073 | if (likely(!(mnt->mnt.mnt_flags & MNT_INTERNAL))) { |
986 | * This probably indicates that somebody messed | 1074 | struct task_struct *task = current; |
987 | * up a mnt_want/drop_write() pair. If this | 1075 | if (likely(!(task->flags & PF_KTHREAD))) { |
988 | * happens, the filesystem was probably unable | 1076 | init_task_work(&mnt->mnt_rcu, __cleanup_mnt); |
989 | * to make r/w->r/o transitions. | 1077 | if (!task_work_add(task, &mnt->mnt_rcu, true)) |
990 | */ | 1078 | return; |
991 | /* | 1079 | } |
992 | * The locking used to deal with mnt_count decrement provides barriers, | 1080 | if (llist_add(&mnt->mnt_llist, &delayed_mntput_list)) |
993 | * so mnt_get_writers() below is safe. | 1081 | schedule_delayed_work(&delayed_mntput_work, 1); |
994 | */ | 1082 | return; |
995 | WARN_ON(mnt_get_writers(mnt)); | 1083 | } |
996 | if (unlikely(mnt->mnt_pins.first)) | 1084 | cleanup_mnt(mnt); |
997 | mnt_pin_kill(mnt); | ||
998 | fsnotify_vfsmount_delete(&mnt->mnt); | ||
999 | dput(mnt->mnt.mnt_root); | ||
1000 | deactivate_super(mnt->mnt.mnt_sb); | ||
1001 | mnt_free_id(mnt); | ||
1002 | call_rcu(&mnt->mnt_rcu, delayed_free_vfsmnt); | ||
1003 | } | 1085 | } |
1004 | 1086 | ||
1005 | void mntput(struct vfsmount *mnt) | 1087 | void mntput(struct vfsmount *mnt) |
@@ -1272,6 +1354,7 @@ void umount_tree(struct mount *mnt, int how) | |||
1272 | if (how < 2) | 1354 | if (how < 2) |
1273 | p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; | 1355 | p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; |
1274 | if (mnt_has_parent(p)) { | 1356 | if (mnt_has_parent(p)) { |
1357 | hlist_del_init(&p->mnt_mp_list); | ||
1275 | put_mountpoint(p->mnt_mp); | 1358 | put_mountpoint(p->mnt_mp); |
1276 | mnt_add_count(p->mnt_parent, -1); | 1359 | mnt_add_count(p->mnt_parent, -1); |
1277 | /* move the reference to mountpoint into ->mnt_ex_mountpoint */ | 1360 | /* move the reference to mountpoint into ->mnt_ex_mountpoint */ |
@@ -1385,6 +1468,37 @@ static int do_umount(struct mount *mnt, int flags) | |||
1385 | return retval; | 1468 | return retval; |
1386 | } | 1469 | } |
1387 | 1470 | ||
1471 | /* | ||
1472 | * __detach_mounts - lazily unmount all mounts on the specified dentry | ||
1473 | * | ||
1474 | * During unlink, rmdir, and d_drop it is possible to loose the path | ||
1475 | * to an existing mountpoint, and wind up leaking the mount. | ||
1476 | * detach_mounts allows lazily unmounting those mounts instead of | ||
1477 | * leaking them. | ||
1478 | * | ||
1479 | * The caller may hold dentry->d_inode->i_mutex. | ||
1480 | */ | ||
1481 | void __detach_mounts(struct dentry *dentry) | ||
1482 | { | ||
1483 | struct mountpoint *mp; | ||
1484 | struct mount *mnt; | ||
1485 | |||
1486 | namespace_lock(); | ||
1487 | mp = lookup_mountpoint(dentry); | ||
1488 | if (!mp) | ||
1489 | goto out_unlock; | ||
1490 | |||
1491 | lock_mount_hash(); | ||
1492 | while (!hlist_empty(&mp->m_list)) { | ||
1493 | mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); | ||
1494 | umount_tree(mnt, 2); | ||
1495 | } | ||
1496 | unlock_mount_hash(); | ||
1497 | put_mountpoint(mp); | ||
1498 | out_unlock: | ||
1499 | namespace_unlock(); | ||
1500 | } | ||
1501 | |||
1388 | /* | 1502 | /* |
1389 | * Is the caller allowed to modify his namespace? | 1503 | * Is the caller allowed to modify his namespace? |
1390 | */ | 1504 | */ |
@@ -1742,7 +1856,9 @@ retry: | |||
1742 | namespace_lock(); | 1856 | namespace_lock(); |
1743 | mnt = lookup_mnt(path); | 1857 | mnt = lookup_mnt(path); |
1744 | if (likely(!mnt)) { | 1858 | if (likely(!mnt)) { |
1745 | struct mountpoint *mp = new_mountpoint(dentry); | 1859 | struct mountpoint *mp = lookup_mountpoint(dentry); |
1860 | if (!mp) | ||
1861 | mp = new_mountpoint(dentry); | ||
1746 | if (IS_ERR(mp)) { | 1862 | if (IS_ERR(mp)) { |
1747 | namespace_unlock(); | 1863 | namespace_unlock(); |
1748 | mutex_unlock(&dentry->d_inode->i_mutex); | 1864 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -2398,21 +2514,9 @@ int copy_mount_options(const void __user * data, unsigned long *where) | |||
2398 | return 0; | 2514 | return 0; |
2399 | } | 2515 | } |
2400 | 2516 | ||
2401 | int copy_mount_string(const void __user *data, char **where) | 2517 | char *copy_mount_string(const void __user *data) |
2402 | { | 2518 | { |
2403 | char *tmp; | 2519 | return data ? strndup_user(data, PAGE_SIZE) : NULL; |
2404 | |||
2405 | if (!data) { | ||
2406 | *where = NULL; | ||
2407 | return 0; | ||
2408 | } | ||
2409 | |||
2410 | tmp = strndup_user(data, PAGE_SIZE); | ||
2411 | if (IS_ERR(tmp)) | ||
2412 | return PTR_ERR(tmp); | ||
2413 | |||
2414 | *where = tmp; | ||
2415 | return 0; | ||
2416 | } | 2520 | } |
2417 | 2521 | ||
2418 | /* | 2522 | /* |
@@ -2429,7 +2533,7 @@ int copy_mount_string(const void __user *data, char **where) | |||
2429 | * Therefore, if this magic number is present, it carries no information | 2533 | * Therefore, if this magic number is present, it carries no information |
2430 | * and must be discarded. | 2534 | * and must be discarded. |
2431 | */ | 2535 | */ |
2432 | long do_mount(const char *dev_name, const char *dir_name, | 2536 | long do_mount(const char *dev_name, const char __user *dir_name, |
2433 | const char *type_page, unsigned long flags, void *data_page) | 2537 | const char *type_page, unsigned long flags, void *data_page) |
2434 | { | 2538 | { |
2435 | struct path path; | 2539 | struct path path; |
@@ -2441,15 +2545,11 @@ long do_mount(const char *dev_name, const char *dir_name, | |||
2441 | flags &= ~MS_MGC_MSK; | 2545 | flags &= ~MS_MGC_MSK; |
2442 | 2546 | ||
2443 | /* Basic sanity checks */ | 2547 | /* Basic sanity checks */ |
2444 | |||
2445 | if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) | ||
2446 | return -EINVAL; | ||
2447 | |||
2448 | if (data_page) | 2548 | if (data_page) |
2449 | ((char *)data_page)[PAGE_SIZE - 1] = 0; | 2549 | ((char *)data_page)[PAGE_SIZE - 1] = 0; |
2450 | 2550 | ||
2451 | /* ... and get the mountpoint */ | 2551 | /* ... and get the mountpoint */ |
2452 | retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); | 2552 | retval = user_path(dir_name, &path); |
2453 | if (retval) | 2553 | if (retval) |
2454 | return retval; | 2554 | return retval; |
2455 | 2555 | ||
@@ -2674,37 +2774,30 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | |||
2674 | { | 2774 | { |
2675 | int ret; | 2775 | int ret; |
2676 | char *kernel_type; | 2776 | char *kernel_type; |
2677 | struct filename *kernel_dir; | ||
2678 | char *kernel_dev; | 2777 | char *kernel_dev; |
2679 | unsigned long data_page; | 2778 | unsigned long data_page; |
2680 | 2779 | ||
2681 | ret = copy_mount_string(type, &kernel_type); | 2780 | kernel_type = copy_mount_string(type); |
2682 | if (ret < 0) | 2781 | ret = PTR_ERR(kernel_type); |
2782 | if (IS_ERR(kernel_type)) | ||
2683 | goto out_type; | 2783 | goto out_type; |
2684 | 2784 | ||
2685 | kernel_dir = getname(dir_name); | 2785 | kernel_dev = copy_mount_string(dev_name); |
2686 | if (IS_ERR(kernel_dir)) { | 2786 | ret = PTR_ERR(kernel_dev); |
2687 | ret = PTR_ERR(kernel_dir); | 2787 | if (IS_ERR(kernel_dev)) |
2688 | goto out_dir; | ||
2689 | } | ||
2690 | |||
2691 | ret = copy_mount_string(dev_name, &kernel_dev); | ||
2692 | if (ret < 0) | ||
2693 | goto out_dev; | 2788 | goto out_dev; |
2694 | 2789 | ||
2695 | ret = copy_mount_options(data, &data_page); | 2790 | ret = copy_mount_options(data, &data_page); |
2696 | if (ret < 0) | 2791 | if (ret < 0) |
2697 | goto out_data; | 2792 | goto out_data; |
2698 | 2793 | ||
2699 | ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags, | 2794 | ret = do_mount(kernel_dev, dir_name, kernel_type, flags, |
2700 | (void *) data_page); | 2795 | (void *) data_page); |
2701 | 2796 | ||
2702 | free_page(data_page); | 2797 | free_page(data_page); |
2703 | out_data: | 2798 | out_data: |
2704 | kfree(kernel_dev); | 2799 | kfree(kernel_dev); |
2705 | out_dev: | 2800 | out_dev: |
2706 | putname(kernel_dir); | ||
2707 | out_dir: | ||
2708 | kfree(kernel_type); | 2801 | kfree(kernel_type); |
2709 | out_type: | 2802 | out_type: |
2710 | return ret; | 2803 | return ret; |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 08b8ea8c353e..314e7add99b8 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -388,7 +388,6 @@ static struct dentry * | |||
388 | ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | 388 | ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) |
389 | { | 389 | { |
390 | struct dentry *dent = dentry; | 390 | struct dentry *dent = dentry; |
391 | struct list_head *next; | ||
392 | 391 | ||
393 | if (d_validate(dent, parent)) { | 392 | if (d_validate(dent, parent)) { |
394 | if (dent->d_name.len <= NCP_MAXPATHLEN && | 393 | if (dent->d_name.len <= NCP_MAXPATHLEN && |
@@ -404,9 +403,7 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
404 | 403 | ||
405 | /* If a pointer is invalid, we search the dentry. */ | 404 | /* If a pointer is invalid, we search the dentry. */ |
406 | spin_lock(&parent->d_lock); | 405 | spin_lock(&parent->d_lock); |
407 | next = parent->d_subdirs.next; | 406 | list_for_each_entry(dent, &parent->d_subdirs, d_u.d_child) { |
408 | while (next != &parent->d_subdirs) { | ||
409 | dent = list_entry(next, struct dentry, d_u.d_child); | ||
410 | if ((unsigned long)dent->d_fsdata == fpos) { | 407 | if ((unsigned long)dent->d_fsdata == fpos) { |
411 | if (dent->d_inode) | 408 | if (dent->d_inode) |
412 | dget(dent); | 409 | dget(dent); |
@@ -415,7 +412,6 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos) | |||
415 | spin_unlock(&parent->d_lock); | 412 | spin_unlock(&parent->d_lock); |
416 | goto out; | 413 | goto out; |
417 | } | 414 | } |
418 | next = next->next; | ||
419 | } | 415 | } |
420 | spin_unlock(&parent->d_lock); | 416 | spin_unlock(&parent->d_lock); |
421 | return NULL; | 417 | return NULL; |
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h index 32c06587351a..52cb19d66ecb 100644 --- a/fs/ncpfs/ncplib_kernel.h +++ b/fs/ncpfs/ncplib_kernel.h | |||
@@ -188,20 +188,14 @@ static inline void | |||
188 | ncp_renew_dentries(struct dentry *parent) | 188 | ncp_renew_dentries(struct dentry *parent) |
189 | { | 189 | { |
190 | struct ncp_server *server = NCP_SERVER(parent->d_inode); | 190 | struct ncp_server *server = NCP_SERVER(parent->d_inode); |
191 | struct list_head *next; | ||
192 | struct dentry *dentry; | 191 | struct dentry *dentry; |
193 | 192 | ||
194 | spin_lock(&parent->d_lock); | 193 | spin_lock(&parent->d_lock); |
195 | next = parent->d_subdirs.next; | 194 | list_for_each_entry(dentry, &parent->d_subdirs, d_u.d_child) { |
196 | while (next != &parent->d_subdirs) { | ||
197 | dentry = list_entry(next, struct dentry, d_u.d_child); | ||
198 | |||
199 | if (dentry->d_fsdata == NULL) | 195 | if (dentry->d_fsdata == NULL) |
200 | ncp_age_dentry(server, dentry); | 196 | ncp_age_dentry(server, dentry); |
201 | else | 197 | else |
202 | ncp_new_dentry(dentry); | 198 | ncp_new_dentry(dentry); |
203 | |||
204 | next = next->next; | ||
205 | } | 199 | } |
206 | spin_unlock(&parent->d_lock); | 200 | spin_unlock(&parent->d_lock); |
207 | } | 201 | } |
@@ -210,16 +204,12 @@ static inline void | |||
210 | ncp_invalidate_dircache_entries(struct dentry *parent) | 204 | ncp_invalidate_dircache_entries(struct dentry *parent) |
211 | { | 205 | { |
212 | struct ncp_server *server = NCP_SERVER(parent->d_inode); | 206 | struct ncp_server *server = NCP_SERVER(parent->d_inode); |
213 | struct list_head *next; | ||
214 | struct dentry *dentry; | 207 | struct dentry *dentry; |
215 | 208 | ||
216 | spin_lock(&parent->d_lock); | 209 | spin_lock(&parent->d_lock); |
217 | next = parent->d_subdirs.next; | 210 | list_for_each_entry(dentry, &parent->d_subdirs, d_u.d_child) { |
218 | while (next != &parent->d_subdirs) { | ||
219 | dentry = list_entry(next, struct dentry, d_u.d_child); | ||
220 | dentry->d_fsdata = NULL; | 211 | dentry->d_fsdata = NULL; |
221 | ncp_age_dentry(server, dentry); | 212 | ncp_age_dentry(server, dentry); |
222 | next = next->next; | ||
223 | } | 213 | } |
224 | spin_unlock(&parent->d_lock); | 214 | spin_unlock(&parent->d_lock); |
225 | } | 215 | } |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 36d921f0c602..06e8cfcbb670 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -486,8 +486,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
486 | nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label); | 486 | nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label); |
487 | goto out; | 487 | goto out; |
488 | } else { | 488 | } else { |
489 | if (d_invalidate(dentry) != 0) | 489 | d_invalidate(dentry); |
490 | goto out; | ||
491 | dput(dentry); | 490 | dput(dentry); |
492 | } | 491 | } |
493 | } | 492 | } |
@@ -1211,10 +1210,6 @@ out_zap_parent: | |||
1211 | if (IS_ROOT(dentry)) | 1210 | if (IS_ROOT(dentry)) |
1212 | goto out_valid; | 1211 | goto out_valid; |
1213 | } | 1212 | } |
1214 | /* If we have submounts, don't unhash ! */ | ||
1215 | if (check_submounts_and_drop(dentry) != 0) | ||
1216 | goto out_valid; | ||
1217 | |||
1218 | dput(parent); | 1213 | dput(parent); |
1219 | dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n", | 1214 | dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n", |
1220 | __func__, dentry); | 1215 | __func__, dentry); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 950100e326a1..772efa45a452 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1565,7 +1565,6 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags) | |||
1565 | put_task_struct(task); | 1565 | put_task_struct(task); |
1566 | return 1; | 1566 | return 1; |
1567 | } | 1567 | } |
1568 | d_drop(dentry); | ||
1569 | return 0; | 1568 | return 0; |
1570 | } | 1569 | } |
1571 | 1570 | ||
@@ -1702,9 +1701,6 @@ out: | |||
1702 | put_task_struct(task); | 1701 | put_task_struct(task); |
1703 | 1702 | ||
1704 | out_notask: | 1703 | out_notask: |
1705 | if (status <= 0) | ||
1706 | d_drop(dentry); | ||
1707 | |||
1708 | return status; | 1704 | return status; |
1709 | } | 1705 | } |
1710 | 1706 | ||
@@ -2618,8 +2614,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) | |||
2618 | /* no ->d_hash() rejects on procfs */ | 2614 | /* no ->d_hash() rejects on procfs */ |
2619 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); | 2615 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); |
2620 | if (dentry) { | 2616 | if (dentry) { |
2621 | shrink_dcache_parent(dentry); | 2617 | d_invalidate(dentry); |
2622 | d_drop(dentry); | ||
2623 | dput(dentry); | 2618 | dput(dentry); |
2624 | } | 2619 | } |
2625 | 2620 | ||
@@ -2639,8 +2634,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) | |||
2639 | name.len = snprintf(buf, sizeof(buf), "%d", pid); | 2634 | name.len = snprintf(buf, sizeof(buf), "%d", pid); |
2640 | dentry = d_hash_and_lookup(dir, &name); | 2635 | dentry = d_hash_and_lookup(dir, &name); |
2641 | if (dentry) { | 2636 | if (dentry) { |
2642 | shrink_dcache_parent(dentry); | 2637 | d_invalidate(dentry); |
2643 | d_drop(dentry); | ||
2644 | dput(dentry); | 2638 | dput(dentry); |
2645 | } | 2639 | } |
2646 | 2640 | ||
diff --git a/fs/proc/fd.c b/fs/proc/fd.c index 955bb55fab8c..e11d7c590bb0 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c | |||
@@ -129,8 +129,6 @@ static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags) | |||
129 | } | 129 | } |
130 | put_task_struct(task); | 130 | put_task_struct(task); |
131 | } | 131 | } |
132 | |||
133 | d_drop(dentry); | ||
134 | return 0; | 132 | return 0; |
135 | } | 133 | } |
136 | 134 | ||
diff --git a/fs/read_write.c b/fs/read_write.c index 009d8542a889..7d9318c3d43c 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -513,6 +513,8 @@ ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t | |||
513 | return ret; | 513 | return ret; |
514 | } | 514 | } |
515 | 515 | ||
516 | EXPORT_SYMBOL(__kernel_write); | ||
517 | |||
516 | ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) | 518 | ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) |
517 | { | 519 | { |
518 | ssize_t ret; | 520 | ssize_t ret; |
diff --git a/fs/reiserfs/xattr.h b/fs/reiserfs/xattr.h index 857ec7e3016f..f620e9678dd5 100644 --- a/fs/reiserfs/xattr.h +++ b/fs/reiserfs/xattr.h | |||
@@ -7,7 +7,6 @@ struct inode; | |||
7 | struct dentry; | 7 | struct dentry; |
8 | struct iattr; | 8 | struct iattr; |
9 | struct super_block; | 9 | struct super_block; |
10 | struct nameidata; | ||
11 | 10 | ||
12 | int reiserfs_xattr_register_handlers(void) __init; | 11 | int reiserfs_xattr_register_handlers(void) __init; |
13 | void reiserfs_xattr_unregister_handlers(void); | 12 | void reiserfs_xattr_unregister_handlers(void); |
diff --git a/fs/super.c b/fs/super.c index 1b836107acee..eae088f6aaae 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -80,6 +80,8 @@ static unsigned long super_cache_scan(struct shrinker *shrink, | |||
80 | inodes = list_lru_count_node(&sb->s_inode_lru, sc->nid); | 80 | inodes = list_lru_count_node(&sb->s_inode_lru, sc->nid); |
81 | dentries = list_lru_count_node(&sb->s_dentry_lru, sc->nid); | 81 | dentries = list_lru_count_node(&sb->s_dentry_lru, sc->nid); |
82 | total_objects = dentries + inodes + fs_objects + 1; | 82 | total_objects = dentries + inodes + fs_objects + 1; |
83 | if (!total_objects) | ||
84 | total_objects = 1; | ||
83 | 85 | ||
84 | /* proportion the scan between the caches */ | 86 | /* proportion the scan between the caches */ |
85 | dentries = mult_frac(sc->nr_to_scan, dentries, total_objects); | 87 | dentries = mult_frac(sc->nr_to_scan, dentries, total_objects); |
diff --git a/fs/xattr.c b/fs/xattr.c index c69e6d43a0d2..64e83efb742d 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -364,13 +364,12 @@ out: | |||
364 | return error; | 364 | return error; |
365 | } | 365 | } |
366 | 366 | ||
367 | SYSCALL_DEFINE5(setxattr, const char __user *, pathname, | 367 | static int path_setxattr(const char __user *pathname, |
368 | const char __user *, name, const void __user *, value, | 368 | const char __user *name, const void __user *value, |
369 | size_t, size, int, flags) | 369 | size_t size, int flags, unsigned int lookup_flags) |
370 | { | 370 | { |
371 | struct path path; | 371 | struct path path; |
372 | int error; | 372 | int error; |
373 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
374 | retry: | 373 | retry: |
375 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 374 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
376 | if (error) | 375 | if (error) |
@@ -388,28 +387,18 @@ retry: | |||
388 | return error; | 387 | return error; |
389 | } | 388 | } |
390 | 389 | ||
390 | SYSCALL_DEFINE5(setxattr, const char __user *, pathname, | ||
391 | const char __user *, name, const void __user *, value, | ||
392 | size_t, size, int, flags) | ||
393 | { | ||
394 | return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW); | ||
395 | } | ||
396 | |||
391 | SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, | 397 | SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, |
392 | const char __user *, name, const void __user *, value, | 398 | const char __user *, name, const void __user *, value, |
393 | size_t, size, int, flags) | 399 | size_t, size, int, flags) |
394 | { | 400 | { |
395 | struct path path; | 401 | return path_setxattr(pathname, name, value, size, flags, 0); |
396 | int error; | ||
397 | unsigned int lookup_flags = 0; | ||
398 | retry: | ||
399 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
400 | if (error) | ||
401 | return error; | ||
402 | error = mnt_want_write(path.mnt); | ||
403 | if (!error) { | ||
404 | error = setxattr(path.dentry, name, value, size, flags); | ||
405 | mnt_drop_write(path.mnt); | ||
406 | } | ||
407 | path_put(&path); | ||
408 | if (retry_estale(error, lookup_flags)) { | ||
409 | lookup_flags |= LOOKUP_REVAL; | ||
410 | goto retry; | ||
411 | } | ||
412 | return error; | ||
413 | } | 402 | } |
414 | 403 | ||
415 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, | 404 | SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, |
@@ -481,12 +470,12 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, | |||
481 | return error; | 470 | return error; |
482 | } | 471 | } |
483 | 472 | ||
484 | SYSCALL_DEFINE4(getxattr, const char __user *, pathname, | 473 | static ssize_t path_getxattr(const char __user *pathname, |
485 | const char __user *, name, void __user *, value, size_t, size) | 474 | const char __user *name, void __user *value, |
475 | size_t size, unsigned int lookup_flags) | ||
486 | { | 476 | { |
487 | struct path path; | 477 | struct path path; |
488 | ssize_t error; | 478 | ssize_t error; |
489 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
490 | retry: | 479 | retry: |
491 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 480 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
492 | if (error) | 481 | if (error) |
@@ -500,23 +489,16 @@ retry: | |||
500 | return error; | 489 | return error; |
501 | } | 490 | } |
502 | 491 | ||
492 | SYSCALL_DEFINE4(getxattr, const char __user *, pathname, | ||
493 | const char __user *, name, void __user *, value, size_t, size) | ||
494 | { | ||
495 | return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW); | ||
496 | } | ||
497 | |||
503 | SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, | 498 | SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, |
504 | const char __user *, name, void __user *, value, size_t, size) | 499 | const char __user *, name, void __user *, value, size_t, size) |
505 | { | 500 | { |
506 | struct path path; | 501 | return path_getxattr(pathname, name, value, size, 0); |
507 | ssize_t error; | ||
508 | unsigned int lookup_flags = 0; | ||
509 | retry: | ||
510 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
511 | if (error) | ||
512 | return error; | ||
513 | error = getxattr(path.dentry, name, value, size); | ||
514 | path_put(&path); | ||
515 | if (retry_estale(error, lookup_flags)) { | ||
516 | lookup_flags |= LOOKUP_REVAL; | ||
517 | goto retry; | ||
518 | } | ||
519 | return error; | ||
520 | } | 502 | } |
521 | 503 | ||
522 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, | 504 | SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, |
@@ -571,12 +553,11 @@ listxattr(struct dentry *d, char __user *list, size_t size) | |||
571 | return error; | 553 | return error; |
572 | } | 554 | } |
573 | 555 | ||
574 | SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, | 556 | static ssize_t path_listxattr(const char __user *pathname, char __user *list, |
575 | size_t, size) | 557 | size_t size, unsigned int lookup_flags) |
576 | { | 558 | { |
577 | struct path path; | 559 | struct path path; |
578 | ssize_t error; | 560 | ssize_t error; |
579 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
580 | retry: | 561 | retry: |
581 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 562 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
582 | if (error) | 563 | if (error) |
@@ -590,23 +571,16 @@ retry: | |||
590 | return error; | 571 | return error; |
591 | } | 572 | } |
592 | 573 | ||
574 | SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, | ||
575 | size_t, size) | ||
576 | { | ||
577 | return path_listxattr(pathname, list, size, LOOKUP_FOLLOW); | ||
578 | } | ||
579 | |||
593 | SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, | 580 | SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, |
594 | size_t, size) | 581 | size_t, size) |
595 | { | 582 | { |
596 | struct path path; | 583 | return path_listxattr(pathname, list, size, 0); |
597 | ssize_t error; | ||
598 | unsigned int lookup_flags = 0; | ||
599 | retry: | ||
600 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
601 | if (error) | ||
602 | return error; | ||
603 | error = listxattr(path.dentry, list, size); | ||
604 | path_put(&path); | ||
605 | if (retry_estale(error, lookup_flags)) { | ||
606 | lookup_flags |= LOOKUP_REVAL; | ||
607 | goto retry; | ||
608 | } | ||
609 | return error; | ||
610 | } | 584 | } |
611 | 585 | ||
612 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) | 586 | SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) |
@@ -640,12 +614,11 @@ removexattr(struct dentry *d, const char __user *name) | |||
640 | return vfs_removexattr(d, kname); | 614 | return vfs_removexattr(d, kname); |
641 | } | 615 | } |
642 | 616 | ||
643 | SYSCALL_DEFINE2(removexattr, const char __user *, pathname, | 617 | static int path_removexattr(const char __user *pathname, |
644 | const char __user *, name) | 618 | const char __user *name, unsigned int lookup_flags) |
645 | { | 619 | { |
646 | struct path path; | 620 | struct path path; |
647 | int error; | 621 | int error; |
648 | unsigned int lookup_flags = LOOKUP_FOLLOW; | ||
649 | retry: | 622 | retry: |
650 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | 623 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); |
651 | if (error) | 624 | if (error) |
@@ -663,27 +636,16 @@ retry: | |||
663 | return error; | 636 | return error; |
664 | } | 637 | } |
665 | 638 | ||
639 | SYSCALL_DEFINE2(removexattr, const char __user *, pathname, | ||
640 | const char __user *, name) | ||
641 | { | ||
642 | return path_removexattr(pathname, name, LOOKUP_FOLLOW); | ||
643 | } | ||
644 | |||
666 | SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, | 645 | SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, |
667 | const char __user *, name) | 646 | const char __user *, name) |
668 | { | 647 | { |
669 | struct path path; | 648 | return path_removexattr(pathname, name, 0); |
670 | int error; | ||
671 | unsigned int lookup_flags = 0; | ||
672 | retry: | ||
673 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
674 | if (error) | ||
675 | return error; | ||
676 | error = mnt_want_write(path.mnt); | ||
677 | if (!error) { | ||
678 | error = removexattr(path.dentry, name); | ||
679 | mnt_drop_write(path.mnt); | ||
680 | } | ||
681 | path_put(&path); | ||
682 | if (retry_estale(error, lookup_flags)) { | ||
683 | lookup_flags |= LOOKUP_REVAL; | ||
684 | goto retry; | ||
685 | } | ||
686 | return error; | ||
687 | } | 649 | } |
688 | 650 | ||
689 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | 651 | SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) |