diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/f2fs/data.c | 8 | ||||
| -rw-r--r-- | fs/f2fs/gc.c | 1 | ||||
| -rw-r--r-- | fs/f2fs/inline.c | 1 | ||||
| -rw-r--r-- | fs/f2fs/node.c | 1 | ||||
| -rw-r--r-- | fs/f2fs/segment.c | 1 | ||||
| -rw-r--r-- | fs/fs-writeback.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_file.c | 14 |
7 files changed, 21 insertions, 7 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index a670702cf3ff..3d846b027fa1 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1902,7 +1902,13 @@ out: redirty_out: redirty_page_for_writepage(wbc, page); - if (!err) + /* + * pageout() in MM traslates EAGAIN, so calls handle_write_error() + * -> mapping_set_error() -> set_bit(AS_EIO, ...). + * file_write_and_wait_range() will see EIO error, which is critical + * to return value of fsync() followed by atomic_write failure to user. + */ + if (!err || wbc->for_reclaim) return AOP_WRITEPAGE_ACTIVATE; unlock_page(page); return err; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index c009b50d69f5..d28d31cbd7d2 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -693,6 +693,7 @@ static void move_data_block(struct inode *inode, block_t bidx, dec_page_count(fio.sbi, F2FS_DIRTY_META); set_page_writeback(fio.encrypted_page); + ClearPageError(page); /* allocate block address */ f2fs_wait_on_page_writeback(dn.node_page, NODE, true); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 922a213693c1..ac951ee9b20b 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -157,6 +157,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) /* write data page to try to make data consistent */ set_page_writeback(page); + ClearPageError(page); fio.old_blkaddr = dn->data_blkaddr; set_inode_flag(dn->inode, FI_HOT_DATA); write_data_page(dn, &fio); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 3871e7d3f69e..16aee2a7b8a9 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1398,6 +1398,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, fio.op_flags |= WRITE_FLUSH_FUA; set_page_writeback(page); + ClearPageError(page); fio.old_blkaddr = ni.blk_addr; write_node_page(nid, &fio); set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(page)); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index d7bac60ad719..01bc94df9f00 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -2838,6 +2838,7 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page, fio.op_flags &= ~REQ_META; set_page_writeback(page); + ClearPageError(page); f2fs_submit_page_write(&fio); f2fs_update_iostat(sbi, io_type, F2FS_BLKSIZE); diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index da43c4a22e1b..0fe11984db09 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1906,7 +1906,7 @@ void wb_workfn(struct work_struct *work) } if (!list_empty(&wb->work_list)) - mod_delayed_work(bdi_wq, &wb->dwork, 0); + wb_wakeup(wb); else if (wb_has_dirty_io(wb) && dirty_writeback_interval) wb_wakeup_delayed(wb); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 3dd47307363f..e917aec4babe 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -969,22 +969,26 @@ xfs_file_fallocate( if (error) goto out_unlock; } else if (mode & FALLOC_FL_INSERT_RANGE) { - unsigned int blksize_mask = i_blocksize(inode) - 1; + unsigned int blksize_mask = i_blocksize(inode) - 1; + loff_t isize = i_size_read(inode); - new_size = i_size_read(inode) + len; if (offset & blksize_mask || len & blksize_mask) { error = -EINVAL; goto out_unlock; } - /* check the new inode size does not wrap through zero */ - if (new_size > inode->i_sb->s_maxbytes) { + /* + * New inode size must not exceed ->s_maxbytes, accounting for + * possible signed overflow. + */ + if (inode->i_sb->s_maxbytes - isize < len) { error = -EFBIG; goto out_unlock; } + new_size = isize + len; /* Offset should be less than i_size */ - if (offset >= i_size_read(inode)) { + if (offset >= isize) { error = -EINVAL; goto out_unlock; } |
