From: Dave Kleikamp Date: Wed, 20 Jun 2012 21:05:59 +0000 (-0500) Subject: ocfs2:btrfs: aio-dio-loop changes broke setrlimit behavior [orabug 14207636] X-Git-Tag: v2.6.39-400.9.0~516^2~8^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=2877d364d6e8070595b0c99efa6333309fc7bffd;p=users%2Fjedix%2Flinux-maple.git ocfs2:btrfs: aio-dio-loop changes broke setrlimit behavior [orabug 14207636] The aio-dio changes for the loop device driver broke ocfs2 and btrfs's handling of rlimit. generic_write_checks() adjusts the IO byte count to account for the rlimit, but the updated count was not being reflected in the iov_iter data structure. Signed-off-by: Dave Kleikamp --- diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 0afdb8f81a20..a458d1397e28 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1338,13 +1338,13 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, u64 start_pos; ssize_t num_written = 0; ssize_t err = 0; - size_t count; + size_t count, ocount; vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); mutex_lock(&inode->i_mutex); - count = iov_iter_count(iter); + ocount = count = iov_iter_count(iter); current->backing_dev_info = inode->i_mapping->backing_dev_info; err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); @@ -1396,6 +1396,9 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb, num_written = __btrfs_direct_write(iocb, iter, pos, ppos, count); } else { + if (count != ocount) + iov_iter_shorten(iter, count); + num_written = __btrfs_buffered_write(file, iter, pos); if (num_written > 0) *ppos = pos + num_written; diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 87bcf38dfa21..2df0c6392348 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2223,7 +2223,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, int ret, direct_io, appending, rw_level, have_alloc_sem = 0; int can_do_direct, has_refcount = 0; ssize_t written = 0; - size_t count; /* after file limit checks */ + size_t count, ocount; loff_t old_size, *ppos = &iocb->ki_pos; u32 old_clusters; struct file *file = iocb->ki_filp; @@ -2352,7 +2352,7 @@ relock: ocfs2_iocb_set_rw_locked(iocb, rw_level); - count = iov_iter_count(iter); + ocount = count = iov_iter_count(iter); ret = generic_write_checks(file, ppos, &count, S_ISBLK(inode->i_mode)); if (ret) @@ -2366,6 +2366,9 @@ relock: goto out_dio; } } else { + if (count != ocount) + iov_iter_shorten(iter, count); + current->backing_dev_info = file->f_mapping->backing_dev_info; written = generic_file_buffered_write_iter(iocb, iter, *ppos, ppos, 0); diff --git a/mm/iov-iter.c b/mm/iov-iter.c index 5a0b94951d87..5006cdbfb5dc 100644 --- a/mm/iov-iter.c +++ b/mm/iov-iter.c @@ -358,6 +358,7 @@ static int ii_iovec_shorten(struct iov_iter *i, size_t count) { struct iovec *iov = (struct iovec *)i->data; i->nr_segs = iov_shorten(iov, i->nr_segs, count); + i->count = count; return 0; }