mm: write iovec cleanup

Hide some of the open-coded nr_segs tests into the iovec helpers.  This is all
to simplify generic_file_buffered_write, because that gets more complex in the
next patch.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Nick Piggin
2007-10-16 01:24:58 -07:00
committed by Linus Torvalds
parent eb2be18931
commit 4a9e5ef1f4
3 changed files with 77 additions and 96 deletions

View File

@@ -1823,12 +1823,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
/*
* handle partial DIO write. Adjust cur_iov if needed.
*/
if (likely(nr_segs == 1))
buf = iov->iov_base + written;
else {
filemap_set_next_iovec(&cur_iov, &iov_offset, written);
buf = cur_iov->iov_base + iov_offset;
}
filemap_set_next_iovec(&cur_iov, nr_segs, &iov_offset, written);
do {
struct page *page;
@@ -1838,6 +1833,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
size_t bytes; /* Bytes to write to page */
size_t copied; /* Bytes copied from user */
buf = cur_iov->iov_base + iov_offset;
offset = (pos & (PAGE_CACHE_SIZE - 1));
index = pos >> PAGE_CACHE_SHIFT;
bytes = PAGE_CACHE_SIZE - offset;
@@ -1869,13 +1865,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
if (unlikely(status))
goto fs_write_aop_error;
if (likely(nr_segs == 1))
copied = filemap_copy_from_user(page, offset,
buf, bytes);
else
copied = filemap_copy_from_user_iovec(page, offset,
cur_iov, iov_offset, bytes);
copied = filemap_copy_from_user(page, offset,
cur_iov, nr_segs, iov_offset, bytes);
flush_dcache_page(page);
status = a_ops->commit_write(file, page, offset, offset+bytes);
if (unlikely(status < 0 || status == AOP_TRUNCATED_PAGE))
goto fs_write_aop_error;
@@ -1886,20 +1879,11 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
if (unlikely(status > 0)) /* filesystem did partial write */
copied = status;
if (likely(copied > 0)) {
written += copied;
count -= copied;
pos += copied;
buf += copied;
if (unlikely(nr_segs > 1)) {
filemap_set_next_iovec(&cur_iov,
&iov_offset, copied);
if (count)
buf = cur_iov->iov_base + iov_offset;
} else {
iov_offset += copied;
}
}
written += copied;
count -= copied;
pos += copied;
filemap_set_next_iovec(&cur_iov, nr_segs, &iov_offset, copied);
unlock_page(page);
mark_page_accessed(page);
page_cache_release(page);