aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-09-27 20:05:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-09-27 20:05:14 -0400
commit1e3827bf8aebe29af2d6e49b89d85dfae4d0154f (patch)
tree7e61ad7bcac7ef4ea9ecd46640ec3729e383c819
parent6111da3432b10b2c56a21a5d8671aee46435326d (diff)
parentd2fa4a8476b911782f7e5167db18770222ac40c3 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "Assorted fixes + unifying __d_move() and __d_materialise_dentry() + minimal regression fix for d_path() of victims of overwriting rename() ported on top of that" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: Don't exchange "short" filenames unconditionally. fold swapping ->d_name.hash into switch_names() fold unlocking the children into dentry_unlock_parents_for_move() kill __d_materialise_dentry() __d_materialise_dentry(): flip the order of arguments __d_move(): fold manipulations with ->d_child/->d_subdirs don't open-code d_rehash() in d_materialise_unique() pull rehashing and unlocking the target dentry into __d_materialise_dentry() ufs: deal with nfsd/iget races fuse: honour max_read and max_write in direct_io mode shmem: fix nlink for rename overwrite directory
-rw-r--r--fs/dcache.c112
-rw-r--r--fs/direct-io.c2
-rw-r--r--fs/fuse/file.c1
-rw-r--r--fs/ufs/ialloc.c6
-rw-r--r--fs/ufs/namei.c4
-rw-r--r--include/linux/uio.h2
-rw-r--r--mm/iov_iter.c14
-rw-r--r--mm/shmem.c4
8 files changed, 60 insertions, 85 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 7a5b51440afa..cb25a1a5e307 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2372,7 +2372,8 @@ void dentry_update_name_case(struct dentry *dentry, struct qstr *name)
2372} 2372}
2373EXPORT_SYMBOL(dentry_update_name_case); 2373EXPORT_SYMBOL(dentry_update_name_case);
2374 2374
2375static void switch_names(struct dentry *dentry, struct dentry *target) 2375static void switch_names(struct dentry *dentry, struct dentry *target,
2376 bool exchange)
2376{ 2377{
2377 if (dname_external(target)) { 2378 if (dname_external(target)) {
2378 if (dname_external(dentry)) { 2379 if (dname_external(dentry)) {
@@ -2406,13 +2407,19 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
2406 */ 2407 */
2407 unsigned int i; 2408 unsigned int i;
2408 BUILD_BUG_ON(!IS_ALIGNED(DNAME_INLINE_LEN, sizeof(long))); 2409 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 }
2409 for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) { 2416 for (i = 0; i < DNAME_INLINE_LEN / sizeof(long); i++) {
2410 swap(((long *) &dentry->d_iname)[i], 2417 swap(((long *) &dentry->d_iname)[i],
2411 ((long *) &target->d_iname)[i]); 2418 ((long *) &target->d_iname)[i]);
2412 } 2419 }
2413 } 2420 }
2414 } 2421 }
2415 swap(dentry->d_name.len, target->d_name.len); 2422 swap(dentry->d_name.hash_len, target->d_name.hash_len);
2416} 2423}
2417 2424
2418static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target) 2425static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target)
@@ -2442,25 +2449,29 @@ static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target)
2442 } 2449 }
2443} 2450}
2444 2451
2445static void dentry_unlock_parents_for_move(struct dentry *dentry, 2452static void dentry_unlock_for_move(struct dentry *dentry, struct dentry *target)
2446 struct dentry *target)
2447{ 2453{
2448 if (target->d_parent != dentry->d_parent) 2454 if (target->d_parent != dentry->d_parent)
2449 spin_unlock(&dentry->d_parent->d_lock); 2455 spin_unlock(&dentry->d_parent->d_lock);
2450 if (target->d_parent != target) 2456 if (target->d_parent != target)
2451 spin_unlock(&target->d_parent->d_lock); 2457 spin_unlock(&target->d_parent->d_lock);
2458 spin_unlock(&target->d_lock);
2459 spin_unlock(&dentry->d_lock);
2452} 2460}
2453 2461
2454/* 2462/*
2455 * When switching names, the actual string doesn't strictly have to 2463 * When switching names, the actual string doesn't strictly have to
2456 * be preserved in the target - because we're dropping the target 2464 * be preserved in the target - because we're dropping the target
2457 * anyway. As such, we can just do a simple memcpy() to copy over 2465 * anyway. As such, we can just do a simple memcpy() to copy over
2458 * the new name before we switch. 2466 * the new name before we switch, unless we are going to rehash
2459 * 2467 * it. Note that if we *do* unhash the target, we are not allowed
2460 * Note that we have to be a lot more careful about getting the hash 2468 * to rehash it without giving it a new name/hash key - whether
2461 * switched - we have to switch the hash value properly even if it 2469 * we swap or overwrite the names here, resulting name won't match
2462 * then no longer matches the actual (corrupted) string of the target. 2470 * the reality in filesystem; it's only there for d_path() purposes.
2463 * The hash value has to match the hash queue that the dentry is on.. 2471 * Note that all of this is happening under rename_lock, so the
2472 * any hash lookup seeing it in the middle of manipulations will
2473 * be discarded anyway. So we do not care what happens to the hash
2474 * key in that case.
2464 */ 2475 */
2465/* 2476/*
2466 * __d_move - move a dentry 2477 * __d_move - move a dentry
@@ -2506,36 +2517,30 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
2506 d_hash(dentry->d_parent, dentry->d_name.hash)); 2517 d_hash(dentry->d_parent, dentry->d_name.hash));
2507 } 2518 }
2508 2519
2509 list_del(&dentry->d_u.d_child);
2510 list_del(&target->d_u.d_child);
2511
2512 /* Switch the names.. */ 2520 /* Switch the names.. */
2513 switch_names(dentry, target); 2521 switch_names(dentry, target, exchange);
2514 swap(dentry->d_name.hash, target->d_name.hash);
2515 2522
2516 /* ... and switch the parents */ 2523 /* ... and switch them in the tree */
2517 if (IS_ROOT(dentry)) { 2524 if (IS_ROOT(dentry)) {
2525 /* splicing a tree */
2518 dentry->d_parent = target->d_parent; 2526 dentry->d_parent = target->d_parent;
2519 target->d_parent = target; 2527 target->d_parent = target;
2520 INIT_LIST_HEAD(&target->d_u.d_child); 2528 list_del_init(&target->d_u.d_child);
2529 list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2521 } else { 2530 } else {
2531 /* swapping two dentries */
2522 swap(dentry->d_parent, target->d_parent); 2532 swap(dentry->d_parent, target->d_parent);
2523 2533 list_move(&target->d_u.d_child, &target->d_parent->d_subdirs);
2524 /* And add them back to the (new) parent lists */ 2534 list_move(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2525 list_add(&target->d_u.d_child, &target->d_parent->d_subdirs); 2535 if (exchange)
2536 fsnotify_d_move(target);
2537 fsnotify_d_move(dentry);
2526 } 2538 }
2527 2539
2528 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
2529
2530 write_seqcount_end(&target->d_seq); 2540 write_seqcount_end(&target->d_seq);
2531 write_seqcount_end(&dentry->d_seq); 2541 write_seqcount_end(&dentry->d_seq);
2532 2542
2533 dentry_unlock_parents_for_move(dentry, target); 2543 dentry_unlock_for_move(dentry, target);
2534 if (exchange)
2535 fsnotify_d_move(target);
2536 spin_unlock(&target->d_lock);
2537 fsnotify_d_move(dentry);
2538 spin_unlock(&dentry->d_lock);
2539} 2544}
2540 2545
2541/* 2546/*
@@ -2633,45 +2638,6 @@ out_err:
2633 return ret; 2638 return ret;
2634} 2639}
2635 2640
2636/*
2637 * Prepare an anonymous dentry for life in the superblock's dentry tree as a
2638 * named dentry in place of the dentry to be replaced.
2639 * returns with anon->d_lock held!
2640 */
2641static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
2642{
2643 struct dentry *dparent;
2644
2645 dentry_lock_for_move(anon, dentry);
2646
2647 write_seqcount_begin(&dentry->d_seq);
2648 write_seqcount_begin_nested(&anon->d_seq, DENTRY_D_LOCK_NESTED);
2649
2650 dparent = dentry->d_parent;
2651
2652 switch_names(dentry, anon);
2653 swap(dentry->d_name.hash, anon->d_name.hash);
2654
2655 dentry->d_parent = dentry;
2656 list_del_init(&dentry->d_u.d_child);
2657 anon->d_parent = dparent;
2658 if (likely(!d_unhashed(anon))) {
2659 hlist_bl_lock(&anon->d_sb->s_anon);
2660 __hlist_bl_del(&anon->d_hash);
2661 anon->d_hash.pprev = NULL;
2662 hlist_bl_unlock(&anon->d_sb->s_anon);
2663 }
2664 list_move(&anon->d_u.d_child, &dparent->d_subdirs);
2665
2666 write_seqcount_end(&dentry->d_seq);
2667 write_seqcount_end(&anon->d_seq);
2668
2669 dentry_unlock_parents_for_move(anon, dentry);
2670 spin_unlock(&dentry->d_lock);
2671
2672 /* anon->d_lock still locked, returns locked */
2673}
2674
2675/** 2641/**
2676 * d_splice_alias - splice a disconnected dentry into the tree if one exists 2642 * d_splice_alias - splice a disconnected dentry into the tree if one exists
2677 * @inode: the inode which may have a disconnected dentry 2643 * @inode: the inode which may have a disconnected dentry
@@ -2717,10 +2683,8 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
2717 return ERR_PTR(-EIO); 2683 return ERR_PTR(-EIO);
2718 } 2684 }
2719 write_seqlock(&rename_lock); 2685 write_seqlock(&rename_lock);
2720 __d_materialise_dentry(dentry, new); 2686 __d_move(new, dentry, false);
2721 write_sequnlock(&rename_lock); 2687 write_sequnlock(&rename_lock);
2722 _d_rehash(new);
2723 spin_unlock(&new->d_lock);
2724 spin_unlock(&inode->i_lock); 2688 spin_unlock(&inode->i_lock);
2725 security_d_instantiate(new, inode); 2689 security_d_instantiate(new, inode);
2726 iput(inode); 2690 iput(inode);
@@ -2780,7 +2744,7 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2780 } else if (IS_ROOT(alias)) { 2744 } else if (IS_ROOT(alias)) {
2781 /* Is this an anonymous mountpoint that we 2745 /* Is this an anonymous mountpoint that we
2782 * could splice into our tree? */ 2746 * could splice into our tree? */
2783 __d_materialise_dentry(dentry, alias); 2747 __d_move(alias, dentry, false);
2784 write_sequnlock(&rename_lock); 2748 write_sequnlock(&rename_lock);
2785 goto found; 2749 goto found;
2786 } else { 2750 } else {
@@ -2807,13 +2771,9 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
2807 actual = __d_instantiate_unique(dentry, inode); 2771 actual = __d_instantiate_unique(dentry, inode);
2808 if (!actual) 2772 if (!actual)
2809 actual = dentry; 2773 actual = dentry;
2810 else
2811 BUG_ON(!d_unhashed(actual));
2812 2774
2813 spin_lock(&actual->d_lock); 2775 d_rehash(actual);
2814found: 2776found:
2815 _d_rehash(actual);
2816 spin_unlock(&actual->d_lock);
2817 spin_unlock(&inode->i_lock); 2777 spin_unlock(&inode->i_lock);
2818out_nolock: 2778out_nolock:
2819 if (actual == dentry) { 2779 if (actual == dentry) {
diff --git a/fs/direct-io.c b/fs/direct-io.c
index c3116404ab49..e181b6b2e297 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -158,7 +158,7 @@ static inline int dio_refill_pages(struct dio *dio, struct dio_submit *sdio)
158{ 158{
159 ssize_t ret; 159 ssize_t ret;
160 160
161 ret = iov_iter_get_pages(sdio->iter, dio->pages, DIO_PAGES, 161 ret = iov_iter_get_pages(sdio->iter, dio->pages, LONG_MAX, DIO_PAGES,
162 &sdio->from); 162 &sdio->from);
163 163
164 if (ret < 0 && sdio->blocks_available && (dio->rw & WRITE)) { 164 if (ret < 0 && sdio->blocks_available && (dio->rw & WRITE)) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 912061ac4baf..caa8d95b24e8 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1305,6 +1305,7 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
1305 size_t start; 1305 size_t start;
1306 ssize_t ret = iov_iter_get_pages(ii, 1306 ssize_t ret = iov_iter_get_pages(ii,
1307 &req->pages[req->num_pages], 1307 &req->pages[req->num_pages],
1308 *nbytesp - nbytes,
1308 req->max_pages - req->num_pages, 1309 req->max_pages - req->num_pages,
1309 &start); 1310 &start);
1310 if (ret < 0) 1311 if (ret < 0)
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index a9cc75ffa925..7caa01652888 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -298,7 +298,10 @@ cg_found:
298 ufsi->i_oeftflag = 0; 298 ufsi->i_oeftflag = 0;
299 ufsi->i_dir_start_lookup = 0; 299 ufsi->i_dir_start_lookup = 0;
300 memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1)); 300 memset(&ufsi->i_u1, 0, sizeof(ufsi->i_u1));
301 insert_inode_hash(inode); 301 if (insert_inode_locked(inode) < 0) {
302 err = -EIO;
303 goto failed;
304 }
302 mark_inode_dirty(inode); 305 mark_inode_dirty(inode);
303 306
304 if (uspi->fs_magic == UFS2_MAGIC) { 307 if (uspi->fs_magic == UFS2_MAGIC) {
@@ -337,6 +340,7 @@ cg_found:
337fail_remove_inode: 340fail_remove_inode:
338 unlock_ufs(sb); 341 unlock_ufs(sb);
339 clear_nlink(inode); 342 clear_nlink(inode);
343 unlock_new_inode(inode);
340 iput(inode); 344 iput(inode);
341 UFSD("EXIT (FAILED): err %d\n", err); 345 UFSD("EXIT (FAILED): err %d\n", err);
342 return ERR_PTR(err); 346 return ERR_PTR(err);
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 2df62a73f20c..fd65deb4b5f0 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -38,10 +38,12 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
38{ 38{
39 int err = ufs_add_link(dentry, inode); 39 int err = ufs_add_link(dentry, inode);
40 if (!err) { 40 if (!err) {
41 unlock_new_inode(inode);
41 d_instantiate(dentry, inode); 42 d_instantiate(dentry, inode);
42 return 0; 43 return 0;
43 } 44 }
44 inode_dec_link_count(inode); 45 inode_dec_link_count(inode);
46 unlock_new_inode(inode);
45 iput(inode); 47 iput(inode);
46 return err; 48 return err;
47} 49}
@@ -155,6 +157,7 @@ out_notlocked:
155 157
156out_fail: 158out_fail:
157 inode_dec_link_count(inode); 159 inode_dec_link_count(inode);
160 unlock_new_inode(inode);
158 iput(inode); 161 iput(inode);
159 goto out; 162 goto out;
160} 163}
@@ -210,6 +213,7 @@ out:
210out_fail: 213out_fail:
211 inode_dec_link_count(inode); 214 inode_dec_link_count(inode);
212 inode_dec_link_count(inode); 215 inode_dec_link_count(inode);
216 unlock_new_inode(inode);
213 iput (inode); 217 iput (inode);
214 inode_dec_link_count(dir); 218 inode_dec_link_count(dir);
215 unlock_ufs(dir->i_sb); 219 unlock_ufs(dir->i_sb);
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 48d64e6ab292..290fbf0b6b8a 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -84,7 +84,7 @@ unsigned long iov_iter_alignment(const struct iov_iter *i);
84void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov, 84void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov,
85 unsigned long nr_segs, size_t count); 85 unsigned long nr_segs, size_t count);
86ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, 86ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
87 unsigned maxpages, size_t *start); 87 size_t maxsize, unsigned maxpages, size_t *start);
88ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, 88ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
89 size_t maxsize, size_t *start); 89 size_t maxsize, size_t *start);
90int iov_iter_npages(const struct iov_iter *i, int maxpages); 90int iov_iter_npages(const struct iov_iter *i, int maxpages);
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index ab88dc0ea1d3..9a09f2034fcc 100644
--- a/mm/iov_iter.c
+++ b/mm/iov_iter.c
@@ -310,7 +310,7 @@ void iov_iter_init(struct iov_iter *i, int direction,
310EXPORT_SYMBOL(iov_iter_init); 310EXPORT_SYMBOL(iov_iter_init);
311 311
312static ssize_t get_pages_iovec(struct iov_iter *i, 312static ssize_t get_pages_iovec(struct iov_iter *i,
313 struct page **pages, unsigned maxpages, 313 struct page **pages, size_t maxsize, unsigned maxpages,
314 size_t *start) 314 size_t *start)
315{ 315{
316 size_t offset = i->iov_offset; 316 size_t offset = i->iov_offset;
@@ -323,6 +323,8 @@ static ssize_t get_pages_iovec(struct iov_iter *i,
323 len = iov->iov_len - offset; 323 len = iov->iov_len - offset;
324 if (len > i->count) 324 if (len > i->count)
325 len = i->count; 325 len = i->count;
326 if (len > maxsize)
327 len = maxsize;
326 addr = (unsigned long)iov->iov_base + offset; 328 addr = (unsigned long)iov->iov_base + offset;
327 len += *start = addr & (PAGE_SIZE - 1); 329 len += *start = addr & (PAGE_SIZE - 1);
328 if (len > maxpages * PAGE_SIZE) 330 if (len > maxpages * PAGE_SIZE)
@@ -588,13 +590,15 @@ static unsigned long alignment_bvec(const struct iov_iter *i)
588} 590}
589 591
590static ssize_t get_pages_bvec(struct iov_iter *i, 592static ssize_t get_pages_bvec(struct iov_iter *i,
591 struct page **pages, unsigned maxpages, 593 struct page **pages, size_t maxsize, unsigned maxpages,
592 size_t *start) 594 size_t *start)
593{ 595{
594 const struct bio_vec *bvec = i->bvec; 596 const struct bio_vec *bvec = i->bvec;
595 size_t len = bvec->bv_len - i->iov_offset; 597 size_t len = bvec->bv_len - i->iov_offset;
596 if (len > i->count) 598 if (len > i->count)
597 len = i->count; 599 len = i->count;
600 if (len > maxsize)
601 len = maxsize;
598 /* can't be more than PAGE_SIZE */ 602 /* can't be more than PAGE_SIZE */
599 *start = bvec->bv_offset + i->iov_offset; 603 *start = bvec->bv_offset + i->iov_offset;
600 604
@@ -711,13 +715,13 @@ unsigned long iov_iter_alignment(const struct iov_iter *i)
711EXPORT_SYMBOL(iov_iter_alignment); 715EXPORT_SYMBOL(iov_iter_alignment);
712 716
713ssize_t iov_iter_get_pages(struct iov_iter *i, 717ssize_t iov_iter_get_pages(struct iov_iter *i,
714 struct page **pages, unsigned maxpages, 718 struct page **pages, size_t maxsize, unsigned maxpages,
715 size_t *start) 719 size_t *start)
716{ 720{
717 if (i->type & ITER_BVEC) 721 if (i->type & ITER_BVEC)
718 return get_pages_bvec(i, pages, maxpages, start); 722 return get_pages_bvec(i, pages, maxsize, maxpages, start);
719 else 723 else
720 return get_pages_iovec(i, pages, maxpages, start); 724 return get_pages_iovec(i, pages, maxsize, maxpages, start);
721} 725}
722EXPORT_SYMBOL(iov_iter_get_pages); 726EXPORT_SYMBOL(iov_iter_get_pages);
723 727
diff --git a/mm/shmem.c b/mm/shmem.c
index 0e5fb225007c..469f90d56051 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2367,8 +2367,10 @@ static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struc
2367 2367
2368 if (new_dentry->d_inode) { 2368 if (new_dentry->d_inode) {
2369 (void) shmem_unlink(new_dir, new_dentry); 2369 (void) shmem_unlink(new_dir, new_dentry);
2370 if (they_are_dirs) 2370 if (they_are_dirs) {
2371 drop_nlink(new_dentry->d_inode);
2371 drop_nlink(old_dir); 2372 drop_nlink(old_dir);
2373 }
2372 } else if (they_are_dirs) { 2374 } else if (they_are_dirs) {
2373 drop_nlink(old_dir); 2375 drop_nlink(old_dir);
2374 inc_nlink(new_dir); 2376 inc_nlink(new_dir);