diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-27 20:05:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-27 20:05:14 -0400 |
commit | 1e3827bf8aebe29af2d6e49b89d85dfae4d0154f (patch) | |
tree | 7e61ad7bcac7ef4ea9ecd46640ec3729e383c819 | |
parent | 6111da3432b10b2c56a21a5d8671aee46435326d (diff) | |
parent | d2fa4a8476b911782f7e5167db18770222ac40c3 (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.c | 112 | ||||
-rw-r--r-- | fs/direct-io.c | 2 | ||||
-rw-r--r-- | fs/fuse/file.c | 1 | ||||
-rw-r--r-- | fs/ufs/ialloc.c | 6 | ||||
-rw-r--r-- | fs/ufs/namei.c | 4 | ||||
-rw-r--r-- | include/linux/uio.h | 2 | ||||
-rw-r--r-- | mm/iov_iter.c | 14 | ||||
-rw-r--r-- | mm/shmem.c | 4 |
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 | } |
2373 | EXPORT_SYMBOL(dentry_update_name_case); | 2373 | EXPORT_SYMBOL(dentry_update_name_case); |
2374 | 2374 | ||
2375 | static void switch_names(struct dentry *dentry, struct dentry *target) | 2375 | static 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 | ||
2418 | static void dentry_lock_for_move(struct dentry *dentry, struct dentry *target) | 2425 | static 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 | ||
2445 | static void dentry_unlock_parents_for_move(struct dentry *dentry, | 2452 | static 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 | */ | ||
2641 | static 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); |
2814 | found: | 2776 | found: |
2815 | _d_rehash(actual); | ||
2816 | spin_unlock(&actual->d_lock); | ||
2817 | spin_unlock(&inode->i_lock); | 2777 | spin_unlock(&inode->i_lock); |
2818 | out_nolock: | 2778 | out_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: | |||
337 | fail_remove_inode: | 340 | fail_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 | ||
156 | out_fail: | 158 | out_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: | |||
210 | out_fail: | 213 | out_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); | |||
84 | void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov, | 84 | void 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); |
86 | ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages, | 86 | ssize_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); |
88 | ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages, | 88 | ssize_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); |
90 | int iov_iter_npages(const struct iov_iter *i, int maxpages); | 90 | int 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, | |||
310 | EXPORT_SYMBOL(iov_iter_init); | 310 | EXPORT_SYMBOL(iov_iter_init); |
311 | 311 | ||
312 | static ssize_t get_pages_iovec(struct iov_iter *i, | 312 | static 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 | ||
590 | static ssize_t get_pages_bvec(struct iov_iter *i, | 592 | static 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) | |||
711 | EXPORT_SYMBOL(iov_iter_alignment); | 715 | EXPORT_SYMBOL(iov_iter_alignment); |
712 | 716 | ||
713 | ssize_t iov_iter_get_pages(struct iov_iter *i, | 717 | ssize_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 | } |
722 | EXPORT_SYMBOL(iov_iter_get_pages); | 726 | EXPORT_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); |