aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-11 14:44:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-11 14:44:11 -0400
commitf6f993328b2abcab86a3c99d7bd9f2066ab03d36 (patch)
treeea6f3902a0fa546493731b3b52a31d98cc747a90 /mm
parentc7a19c795b4b0a3232c157ed29eea85077e95da6 (diff)
parent12a5b5294cb1896e9a3c9fca8ff5a7e3def4e8c6 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "Stuff in here: - acct.c fixes and general rework of mnt_pin mechanism. That allows to go for delayed-mntput stuff, which will permit mntput() on deep stack without worrying about stack overflows - fs shutdown will happen on shallow stack. IOW, we can do Eric's umount-on-rmdir series without introducing tons of stack overflows on new mntput() call chains it introduces. - Bruce's d_splice_alias() patches - more Miklos' rename() stuff. - a couple of regression fixes (stable fodder, in the end of branch) and a fix for API idiocy in iov_iter.c. There definitely will be another pile, maybe even two. I'd like to get Eric's series in this time, but even if we miss it, it'll go right in the beginning of for-next in the next cycle - the tricky part of prereqs is in this pile" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (40 commits) fix copy_tree() regression __generic_file_write_iter(): fix handling of sync error after DIO switch iov_iter_get_pages() to passing maximal number of pages fs: mark __d_obtain_alias static dcache: d_splice_alias should detect loops exportfs: update Exporting documentation dcache: d_find_alias needn't recheck IS_ROOT && DCACHE_DISCONNECTED dcache: remove unused d_find_alias parameter dcache: d_obtain_alias callers don't all want DISCONNECTED dcache: d_splice_alias should ignore DCACHE_DISCONNECTED dcache: d_splice_alias mustn't create directory aliases dcache: close d_move race in d_splice_alias dcache: move d_splice_alias namei: trivial fix to vfs_rename_dir comment VFS: allow ->d_manage() to declare -EISDIR in rcu_walk mode. cifs: support RENAME_NOREPLACE hostfs: support rename flags shmem: support RENAME_EXCHANGE shmem: support RENAME_NOREPLACE btrfs: add RENAME_NOREPLACE ...
Diffstat (limited to 'mm')
-rw-r--r--mm/filemap.c2
-rw-r--r--mm/iov_iter.c17
-rw-r--r--mm/shmem.c32
3 files changed, 39 insertions, 12 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index f501b56ec2c6..90effcdf948d 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2602,7 +2602,7 @@ ssize_t __generic_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
2602 * that this differs from normal direct-io semantics, which 2602 * that this differs from normal direct-io semantics, which
2603 * will return -EFOO even if some bytes were written. 2603 * will return -EFOO even if some bytes were written.
2604 */ 2604 */
2605 if (unlikely(status < 0) && !written) { 2605 if (unlikely(status < 0)) {
2606 err = status; 2606 err = status;
2607 goto out; 2607 goto out;
2608 } 2608 }
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index 7b5dbd1517b5..ab88dc0ea1d3 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, size_t maxsize, 313 struct page **pages, 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,10 +323,10 @@ 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;
328 addr = (unsigned long)iov->iov_base + offset; 326 addr = (unsigned long)iov->iov_base + offset;
329 len += *start = addr & (PAGE_SIZE - 1); 327 len += *start = addr & (PAGE_SIZE - 1);
328 if (len > maxpages * PAGE_SIZE)
329 len = maxpages * PAGE_SIZE;
330 addr &= ~(PAGE_SIZE - 1); 330 addr &= ~(PAGE_SIZE - 1);
331 n = (len + PAGE_SIZE - 1) / PAGE_SIZE; 331 n = (len + PAGE_SIZE - 1) / PAGE_SIZE;
332 res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages); 332 res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages);
@@ -588,15 +588,14 @@ static unsigned long alignment_bvec(const struct iov_iter *i)
588} 588}
589 589
590static ssize_t get_pages_bvec(struct iov_iter *i, 590static ssize_t get_pages_bvec(struct iov_iter *i,
591 struct page **pages, size_t maxsize, 591 struct page **pages, unsigned maxpages,
592 size_t *start) 592 size_t *start)
593{ 593{
594 const struct bio_vec *bvec = i->bvec; 594 const struct bio_vec *bvec = i->bvec;
595 size_t len = bvec->bv_len - i->iov_offset; 595 size_t len = bvec->bv_len - i->iov_offset;
596 if (len > i->count) 596 if (len > i->count)
597 len = i->count; 597 len = i->count;
598 if (len > maxsize) 598 /* can't be more than PAGE_SIZE */
599 len = maxsize;
600 *start = bvec->bv_offset + i->iov_offset; 599 *start = bvec->bv_offset + i->iov_offset;
601 600
602 get_page(*pages = bvec->bv_page); 601 get_page(*pages = bvec->bv_page);
@@ -712,13 +711,13 @@ unsigned long iov_iter_alignment(const struct iov_iter *i)
712EXPORT_SYMBOL(iov_iter_alignment); 711EXPORT_SYMBOL(iov_iter_alignment);
713 712
714ssize_t iov_iter_get_pages(struct iov_iter *i, 713ssize_t iov_iter_get_pages(struct iov_iter *i,
715 struct page **pages, size_t maxsize, 714 struct page **pages, unsigned maxpages,
716 size_t *start) 715 size_t *start)
717{ 716{
718 if (i->type & ITER_BVEC) 717 if (i->type & ITER_BVEC)
719 return get_pages_bvec(i, pages, maxsize, start); 718 return get_pages_bvec(i, pages, maxpages, start);
720 else 719 else
721 return get_pages_iovec(i, pages, maxsize, start); 720 return get_pages_iovec(i, pages, maxpages, start);
722} 721}
723EXPORT_SYMBOL(iov_iter_get_pages); 722EXPORT_SYMBOL(iov_iter_get_pages);
724 723
diff --git a/mm/shmem.c b/mm/shmem.c
index a42add14331c..0e5fb225007c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2323,17 +2323,45 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
2323 return shmem_unlink(dir, dentry); 2323 return shmem_unlink(dir, dentry);
2324} 2324}
2325 2325
2326static int shmem_exchange(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
2327{
2328 bool old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
2329 bool new_is_dir = S_ISDIR(new_dentry->d_inode->i_mode);
2330
2331 if (old_dir != new_dir && old_is_dir != new_is_dir) {
2332 if (old_is_dir) {
2333 drop_nlink(old_dir);
2334 inc_nlink(new_dir);
2335 } else {
2336 drop_nlink(new_dir);
2337 inc_nlink(old_dir);
2338 }
2339 }
2340 old_dir->i_ctime = old_dir->i_mtime =
2341 new_dir->i_ctime = new_dir->i_mtime =
2342 old_dentry->d_inode->i_ctime =
2343 new_dentry->d_inode->i_ctime = CURRENT_TIME;
2344
2345 return 0;
2346}
2347
2326/* 2348/*
2327 * The VFS layer already does all the dentry stuff for rename, 2349 * The VFS layer already does all the dentry stuff for rename,
2328 * we just have to decrement the usage count for the target if 2350 * we just have to decrement the usage count for the target if
2329 * it exists so that the VFS layer correctly free's it when it 2351 * it exists so that the VFS layer correctly free's it when it
2330 * gets overwritten. 2352 * gets overwritten.
2331 */ 2353 */
2332static int shmem_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) 2354static int shmem_rename2(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags)
2333{ 2355{
2334 struct inode *inode = old_dentry->d_inode; 2356 struct inode *inode = old_dentry->d_inode;
2335 int they_are_dirs = S_ISDIR(inode->i_mode); 2357 int they_are_dirs = S_ISDIR(inode->i_mode);
2336 2358
2359 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
2360 return -EINVAL;
2361
2362 if (flags & RENAME_EXCHANGE)
2363 return shmem_exchange(old_dir, old_dentry, new_dir, new_dentry);
2364
2337 if (!simple_empty(new_dentry)) 2365 if (!simple_empty(new_dentry))
2338 return -ENOTEMPTY; 2366 return -ENOTEMPTY;
2339 2367
@@ -3087,7 +3115,7 @@ static const struct inode_operations shmem_dir_inode_operations = {
3087 .mkdir = shmem_mkdir, 3115 .mkdir = shmem_mkdir,
3088 .rmdir = shmem_rmdir, 3116 .rmdir = shmem_rmdir,
3089 .mknod = shmem_mknod, 3117 .mknod = shmem_mknod,
3090 .rename = shmem_rename, 3118 .rename2 = shmem_rename2,
3091 .tmpfile = shmem_tmpfile, 3119 .tmpfile = shmem_tmpfile,
3092#endif 3120#endif
3093#ifdef CONFIG_TMPFS_XATTR 3121#ifdef CONFIG_TMPFS_XATTR