forked from Minki/linux
Writeback error handling fixes (pile #1)
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJZXXLdAAoJEAAOaEEZVoIVtBIP/2BMtyDB5IVaxUuYc9LiFxCZ Y6W4aYEBgPhrct6epV3pnV+SXuzov9F5QZWe1P+lB3e30JHvPhO52OUIT7gSbFbv kKCh+p7Q1vLqaKxONPQpJI5LjlB6e6GIekrI4woA2RWVw+6cUyP0oQTVhsSsgnj/ /GMo2pAqlhR3vnn9cWG93vl+xnrtmckpwFe0g5Jhdp/cVQBrqwxG+1W9rEsJf0nx RN29E7+CyxI3x2KkVdmgsMQkpkM2ooopn//1QDmS3M2sbCrJrLSTRG8LBEcs8fi8 pQZcgW6uHXDH2I0hews1vhJRA38TeXoQfj9OZoFGQcVpbP3ZnjASKioRoQiSsHyQ QRDxUw6C45tjWT0HZ1GaCDMuTMs0z2/zF/E7TaOX6zB2LS/NuIluoVAMkYVyXY3a L39flIddnDaga1ojL+tQK5hhSl9C66++/FsFa2FZ0hLkeXA5WDLhRy0ODW3NaYg8 89pPJDfiocEiI7ULht2Bkk88zFe+K07bQRQ5eoFtSOAxOnWGJCbxn8G8dFZZDHnO XZe3gscbR3DCMJ+agb4V/YOyqCHAJMA/lcnP9v7P+QnrEXSV5yrblk1Gx442xMhv tANcCUI3nb/b2Ma3DW3iZS/iYmhmy/baBSV3n65K9NqtkkIbnqSXxk+5RJd5eKsS 8Y5nyu+6mlcOOxBMkmRo =jRrj -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
33198c165b
@ -72,7 +72,7 @@ static int exofs_commit_chunk(struct page *page, loff_t pos, unsigned len)
|
||||
set_page_dirty(page);
|
||||
|
||||
if (IS_DIRSYNC(dir))
|
||||
err = write_one_page(page, 1);
|
||||
err = write_one_page(page);
|
||||
else
|
||||
unlock_page(page);
|
||||
|
||||
|
@ -100,7 +100,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
|
||||
}
|
||||
|
||||
if (IS_DIRSYNC(dir)) {
|
||||
err = write_one_page(page, 1);
|
||||
err = write_one_page(page);
|
||||
if (!err)
|
||||
err = sync_inode_metadata(dir, 1);
|
||||
} else {
|
||||
|
@ -664,6 +664,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
|
||||
INCREMENT(mpStat.pagealloc);
|
||||
mp = alloc_metapage(GFP_NOFS);
|
||||
mp->page = page;
|
||||
mp->sb = inode->i_sb;
|
||||
mp->flag = 0;
|
||||
mp->xflag = COMMIT_PAGE;
|
||||
mp->count = 1;
|
||||
@ -711,7 +712,8 @@ void force_metapage(struct metapage *mp)
|
||||
get_page(page);
|
||||
lock_page(page);
|
||||
set_page_dirty(page);
|
||||
write_one_page(page, 1);
|
||||
if (write_one_page(page))
|
||||
jfs_error(mp->sb, "write_one_page() failed\n");
|
||||
clear_bit(META_forcewrite, &mp->flag);
|
||||
put_page(page);
|
||||
}
|
||||
@ -756,7 +758,8 @@ void release_metapage(struct metapage * mp)
|
||||
set_page_dirty(page);
|
||||
if (test_bit(META_sync, &mp->flag)) {
|
||||
clear_bit(META_sync, &mp->flag);
|
||||
write_one_page(page, 1);
|
||||
if (write_one_page(page))
|
||||
jfs_error(mp->sb, "write_one_page() failed\n");
|
||||
lock_page(page); /* write_one_page unlocks the page */
|
||||
}
|
||||
} else if (mp->lsn) /* discard_metapage doesn't remove it */
|
||||
|
@ -38,6 +38,7 @@ struct metapage {
|
||||
|
||||
/* implementation */
|
||||
struct page *page;
|
||||
struct super_block *sb;
|
||||
unsigned int logical_size;
|
||||
|
||||
/* Journal management */
|
||||
|
@ -57,7 +57,7 @@ static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
|
||||
mark_inode_dirty(dir);
|
||||
}
|
||||
if (IS_DIRSYNC(dir))
|
||||
err = write_one_page(page, 1);
|
||||
err = write_one_page(page);
|
||||
else
|
||||
unlock_page(page);
|
||||
return err;
|
||||
|
@ -192,7 +192,7 @@ int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
spin_unlock(&inode->i_lock);
|
||||
mark_inode_dirty_sync(inode);
|
||||
}
|
||||
return call_fsync(file, start, end, datasync);
|
||||
return file->f_op->fsync(file, start, end, datasync);
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_fsync_range);
|
||||
|
||||
|
@ -45,7 +45,7 @@ static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
|
||||
mark_inode_dirty(dir);
|
||||
}
|
||||
if (IS_DIRSYNC(dir))
|
||||
err = write_one_page(page, 1);
|
||||
err = write_one_page(page);
|
||||
else
|
||||
unlock_page(page);
|
||||
return err;
|
||||
|
@ -53,7 +53,7 @@ static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
|
||||
mark_inode_dirty(dir);
|
||||
}
|
||||
if (IS_DIRSYNC(dir))
|
||||
err = write_one_page(page, 1);
|
||||
err = write_one_page(page);
|
||||
else
|
||||
unlock_page(page);
|
||||
return err;
|
||||
|
@ -1748,12 +1748,6 @@ static inline int call_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
return file->f_op->mmap(file, vma);
|
||||
}
|
||||
|
||||
static inline int call_fsync(struct file *file, loff_t start, loff_t end,
|
||||
int datasync)
|
||||
{
|
||||
return file->f_op->fsync(file, start, end, datasync);
|
||||
}
|
||||
|
||||
ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
|
||||
unsigned long nr_segs, unsigned long fast_segs,
|
||||
struct iovec *fast_pointer,
|
||||
|
@ -2171,7 +2171,7 @@ extern void filemap_map_pages(struct vm_fault *vmf,
|
||||
extern int filemap_page_mkwrite(struct vm_fault *vmf);
|
||||
|
||||
/* mm/page-writeback.c */
|
||||
int write_one_page(struct page *page, int wait);
|
||||
int __must_check write_one_page(struct page *page);
|
||||
void task_dirty_inc(struct task_struct *tsk);
|
||||
|
||||
/* readahead.c */
|
||||
|
@ -452,7 +452,7 @@ static int shm_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
|
||||
if (!sfd->file->f_op->fsync)
|
||||
return -EINVAL;
|
||||
return call_fsync(sfd->file, start, end, datasync);
|
||||
return sfd->file->f_op->fsync(sfd->file, start, end, datasync);
|
||||
}
|
||||
|
||||
static long shm_fallocate(struct file *file, int mode, loff_t offset,
|
||||
|
@ -2366,15 +2366,15 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
|
||||
}
|
||||
|
||||
/**
|
||||
* write_one_page - write out a single page and optionally wait on I/O
|
||||
* write_one_page - write out a single page and wait on I/O
|
||||
* @page: the page to write
|
||||
* @wait: if true, wait on writeout
|
||||
*
|
||||
* The page must be locked by the caller and will be unlocked upon return.
|
||||
*
|
||||
* write_one_page() returns a negative error code if I/O failed.
|
||||
* Note that the mapping's AS_EIO/AS_ENOSPC flags will be cleared when this
|
||||
* function returns.
|
||||
*/
|
||||
int write_one_page(struct page *page, int wait)
|
||||
int write_one_page(struct page *page)
|
||||
{
|
||||
struct address_space *mapping = page->mapping;
|
||||
int ret = 0;
|
||||
@ -2385,21 +2385,20 @@ int write_one_page(struct page *page, int wait)
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
|
||||
if (wait)
|
||||
wait_on_page_writeback(page);
|
||||
wait_on_page_writeback(page);
|
||||
|
||||
if (clear_page_dirty_for_io(page)) {
|
||||
get_page(page);
|
||||
ret = mapping->a_ops->writepage(page, &wbc);
|
||||
if (ret == 0 && wait) {
|
||||
if (ret == 0)
|
||||
wait_on_page_writeback(page);
|
||||
if (PageError(page))
|
||||
ret = -EIO;
|
||||
}
|
||||
put_page(page);
|
||||
} else {
|
||||
unlock_page(page);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = filemap_check_errors(mapping);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(write_one_page);
|
||||
|
Loading…
Reference in New Issue
Block a user