aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-07 21:39:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-07 21:39:15 -0400
commit33198c165b7afd500f7b6b7680ef994296805ef0 (patch)
tree4c56417bad2cc75e5d76e0e66fc6896b38a872b2
parent3ea4fcc5fe7f990266ddd3139ef5ae66d625bd13 (diff)
parent0f41074a65757b46acbdd4293f0de8a70b147406 (diff)
Merge tag 'for-linus-v4.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux
Pull Writeback error handling fixes from Jeff Layton: "The main rationale for all of these changes is to tighten up writeback error reporting to userland. There are many ways now that writeback errors can be lost, such that fsync/fdatasync/msync return 0 when writeback actually failed. This pile contains a small set of cleanups and writeback error handling fixes that I was able to break off from the main pile (#2). Two of the patches in this pile are trivial. The exceptions are the patch to fix up error handling in write_one_page, and the patch to make JFS pay attention to write_one_page errors" * tag 'for-linus-v4.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux: fs: remove call_fsync helper function mm: clean up error handling in write_one_page JFS: do not ignore return code from write_one_page() mm: drop "wait" parameter from write_one_page()
-rw-r--r--fs/exofs/dir.c2
-rw-r--r--fs/ext2/dir.c2
-rw-r--r--fs/jfs/jfs_metapage.c7
-rw-r--r--fs/jfs/jfs_metapage.h1
-rw-r--r--fs/minix/dir.c2
-rw-r--r--fs/sync.c2
-rw-r--r--fs/sysv/dir.c2
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/mm.h2
-rw-r--r--ipc/shm.c2
-rw-r--r--mm/page-writeback.c19
12 files changed, 23 insertions, 26 deletions
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
index 8eeb694332fe..98233a97b7b8 100644
--- a/fs/exofs/dir.c
+++ b/fs/exofs/dir.c
@@ -72,7 +72,7 @@ static int exofs_commit_chunk(struct page *page, loff_t pos, unsigned len)
72 set_page_dirty(page); 72 set_page_dirty(page);
73 73
74 if (IS_DIRSYNC(dir)) 74 if (IS_DIRSYNC(dir))
75 err = write_one_page(page, 1); 75 err = write_one_page(page);
76 else 76 else
77 unlock_page(page); 77 unlock_page(page);
78 78
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index d9650c9508e4..e2709695b177 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -100,7 +100,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
100 } 100 }
101 101
102 if (IS_DIRSYNC(dir)) { 102 if (IS_DIRSYNC(dir)) {
103 err = write_one_page(page, 1); 103 err = write_one_page(page);
104 if (!err) 104 if (!err)
105 err = sync_inode_metadata(dir, 1); 105 err = sync_inode_metadata(dir, 1);
106 } else { 106 } else {
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index ce93db3aef3c..65120a471729 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -664,6 +664,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
664 INCREMENT(mpStat.pagealloc); 664 INCREMENT(mpStat.pagealloc);
665 mp = alloc_metapage(GFP_NOFS); 665 mp = alloc_metapage(GFP_NOFS);
666 mp->page = page; 666 mp->page = page;
667 mp->sb = inode->i_sb;
667 mp->flag = 0; 668 mp->flag = 0;
668 mp->xflag = COMMIT_PAGE; 669 mp->xflag = COMMIT_PAGE;
669 mp->count = 1; 670 mp->count = 1;
@@ -711,7 +712,8 @@ void force_metapage(struct metapage *mp)
711 get_page(page); 712 get_page(page);
712 lock_page(page); 713 lock_page(page);
713 set_page_dirty(page); 714 set_page_dirty(page);
714 write_one_page(page, 1); 715 if (write_one_page(page))
716 jfs_error(mp->sb, "write_one_page() failed\n");
715 clear_bit(META_forcewrite, &mp->flag); 717 clear_bit(META_forcewrite, &mp->flag);
716 put_page(page); 718 put_page(page);
717} 719}
@@ -756,7 +758,8 @@ void release_metapage(struct metapage * mp)
756 set_page_dirty(page); 758 set_page_dirty(page);
757 if (test_bit(META_sync, &mp->flag)) { 759 if (test_bit(META_sync, &mp->flag)) {
758 clear_bit(META_sync, &mp->flag); 760 clear_bit(META_sync, &mp->flag);
759 write_one_page(page, 1); 761 if (write_one_page(page))
762 jfs_error(mp->sb, "write_one_page() failed\n");
760 lock_page(page); /* write_one_page unlocks the page */ 763 lock_page(page); /* write_one_page unlocks the page */
761 } 764 }
762 } else if (mp->lsn) /* discard_metapage doesn't remove it */ 765 } else if (mp->lsn) /* discard_metapage doesn't remove it */
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
index a869fb4a20d6..8b0ee514eb84 100644
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -38,6 +38,7 @@ struct metapage {
38 38
39 /* implementation */ 39 /* implementation */
40 struct page *page; 40 struct page *page;
41 struct super_block *sb;
41 unsigned int logical_size; 42 unsigned int logical_size;
42 43
43 /* Journal management */ 44 /* Journal management */
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 7edc9b395700..baa9721f1299 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -57,7 +57,7 @@ static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
57 mark_inode_dirty(dir); 57 mark_inode_dirty(dir);
58 } 58 }
59 if (IS_DIRSYNC(dir)) 59 if (IS_DIRSYNC(dir))
60 err = write_one_page(page, 1); 60 err = write_one_page(page);
61 else 61 else
62 unlock_page(page); 62 unlock_page(page);
63 return err; 63 return err;
diff --git a/fs/sync.c b/fs/sync.c
index 11ba023434b1..2a54c1f22035 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -192,7 +192,7 @@ int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
192 spin_unlock(&inode->i_lock); 192 spin_unlock(&inode->i_lock);
193 mark_inode_dirty_sync(inode); 193 mark_inode_dirty_sync(inode);
194 } 194 }
195 return call_fsync(file, start, end, datasync); 195 return file->f_op->fsync(file, start, end, datasync);
196} 196}
197EXPORT_SYMBOL(vfs_fsync_range); 197EXPORT_SYMBOL(vfs_fsync_range);
198 198
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 5bdae85ceef7..f5191cb2c947 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -45,7 +45,7 @@ static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
45 mark_inode_dirty(dir); 45 mark_inode_dirty(dir);
46 } 46 }
47 if (IS_DIRSYNC(dir)) 47 if (IS_DIRSYNC(dir))
48 err = write_one_page(page, 1); 48 err = write_one_page(page);
49 else 49 else
50 unlock_page(page); 50 unlock_page(page);
51 return err; 51 return err;
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index de01b8f2aa78..48609f1d9580 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -53,7 +53,7 @@ static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
53 mark_inode_dirty(dir); 53 mark_inode_dirty(dir);
54 } 54 }
55 if (IS_DIRSYNC(dir)) 55 if (IS_DIRSYNC(dir))
56 err = write_one_page(page, 1); 56 err = write_one_page(page);
57 else 57 else
58 unlock_page(page); 58 unlock_page(page);
59 return err; 59 return err;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 818568c8e5ed..978fb5966a25 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1748,12 +1748,6 @@ static inline int call_mmap(struct file *file, struct vm_area_struct *vma)
1748 return file->f_op->mmap(file, vma); 1748 return file->f_op->mmap(file, vma);
1749} 1749}
1750 1750
1751static inline int call_fsync(struct file *file, loff_t start, loff_t end,
1752 int datasync)
1753{
1754 return file->f_op->fsync(file, start, end, datasync);
1755}
1756
1757ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, 1751ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
1758 unsigned long nr_segs, unsigned long fast_segs, 1752 unsigned long nr_segs, unsigned long fast_segs,
1759 struct iovec *fast_pointer, 1753 struct iovec *fast_pointer,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6f543a47fc92..46b9ac5e8569 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2171,7 +2171,7 @@ extern void filemap_map_pages(struct vm_fault *vmf,
2171extern int filemap_page_mkwrite(struct vm_fault *vmf); 2171extern int filemap_page_mkwrite(struct vm_fault *vmf);
2172 2172
2173/* mm/page-writeback.c */ 2173/* mm/page-writeback.c */
2174int write_one_page(struct page *page, int wait); 2174int __must_check write_one_page(struct page *page);
2175void task_dirty_inc(struct task_struct *tsk); 2175void task_dirty_inc(struct task_struct *tsk);
2176 2176
2177/* readahead.c */ 2177/* readahead.c */
diff --git a/ipc/shm.c b/ipc/shm.c
index 34c4344e8d4b..f45c7959b264 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -452,7 +452,7 @@ static int shm_fsync(struct file *file, loff_t start, loff_t end, int datasync)
452 452
453 if (!sfd->file->f_op->fsync) 453 if (!sfd->file->f_op->fsync)
454 return -EINVAL; 454 return -EINVAL;
455 return call_fsync(sfd->file, start, end, datasync); 455 return sfd->file->f_op->fsync(sfd->file, start, end, datasync);
456} 456}
457 457
458static long shm_fallocate(struct file *file, int mode, loff_t offset, 458static long shm_fallocate(struct file *file, int mode, loff_t offset,
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 8989eada0ef7..0b60cc7ddac2 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2366,15 +2366,15 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
2366} 2366}
2367 2367
2368/** 2368/**
2369 * write_one_page - write out a single page and optionally wait on I/O 2369 * write_one_page - write out a single page and wait on I/O
2370 * @page: the page to write 2370 * @page: the page to write
2371 * @wait: if true, wait on writeout
2372 * 2371 *
2373 * The page must be locked by the caller and will be unlocked upon return. 2372 * The page must be locked by the caller and will be unlocked upon return.
2374 * 2373 *
2375 * write_one_page() returns a negative error code if I/O failed. 2374 * Note that the mapping's AS_EIO/AS_ENOSPC flags will be cleared when this
2375 * function returns.
2376 */ 2376 */
2377int write_one_page(struct page *page, int wait) 2377int write_one_page(struct page *page)
2378{ 2378{
2379 struct address_space *mapping = page->mapping; 2379 struct address_space *mapping = page->mapping;
2380 int ret = 0; 2380 int ret = 0;
@@ -2385,21 +2385,20 @@ int write_one_page(struct page *page, int wait)
2385 2385
2386 BUG_ON(!PageLocked(page)); 2386 BUG_ON(!PageLocked(page));
2387 2387
2388 if (wait) 2388 wait_on_page_writeback(page);
2389 wait_on_page_writeback(page);
2390 2389
2391 if (clear_page_dirty_for_io(page)) { 2390 if (clear_page_dirty_for_io(page)) {
2392 get_page(page); 2391 get_page(page);
2393 ret = mapping->a_ops->writepage(page, &wbc); 2392 ret = mapping->a_ops->writepage(page, &wbc);
2394 if (ret == 0 && wait) { 2393 if (ret == 0)
2395 wait_on_page_writeback(page); 2394 wait_on_page_writeback(page);
2396 if (PageError(page))
2397 ret = -EIO;
2398 }
2399 put_page(page); 2395 put_page(page);
2400 } else { 2396 } else {
2401 unlock_page(page); 2397 unlock_page(page);
2402 } 2398 }
2399
2400 if (!ret)
2401 ret = filemap_check_errors(mapping);
2403 return ret; 2402 return ret;
2404} 2403}
2405EXPORT_SYMBOL(write_one_page); 2404EXPORT_SYMBOL(write_one_page);