diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-06-10 18:31:00 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-07-09 12:08:45 -0400 |
commit | efc91ed0191e3fc62bb1c556ac93fc4e661214d2 (patch) | |
tree | 291dba382da5d609c5bd35b5e369324ecbb95c00 /fs/nfs/file.c | |
parent | b390c2b55c830eb3b64633fa8d8b8837e073e458 (diff) |
NFS: Optimise append writes with holes
If a file is being extended, and we're creating a hole, we might as well
declare the entire page to be up to date.
This patch significantly improves the write performance for sparse files
in the case where lseek(SEEK_END) is used to append several non-contiguous
writes at intervals of < PAGE_SIZE.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7c73f06692b6..7ac89a845a5e 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -344,6 +344,26 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, | |||
344 | unsigned offset = pos & (PAGE_CACHE_SIZE - 1); | 344 | unsigned offset = pos & (PAGE_CACHE_SIZE - 1); |
345 | int status; | 345 | int status; |
346 | 346 | ||
347 | /* | ||
348 | * Zero any uninitialised parts of the page, and then mark the page | ||
349 | * as up to date if it turns out that we're extending the file. | ||
350 | */ | ||
351 | if (!PageUptodate(page)) { | ||
352 | unsigned pglen = nfs_page_length(page); | ||
353 | unsigned end = offset + len; | ||
354 | |||
355 | if (pglen == 0) { | ||
356 | zero_user_segments(page, 0, offset, | ||
357 | end, PAGE_CACHE_SIZE); | ||
358 | SetPageUptodate(page); | ||
359 | } else if (end >= pglen) { | ||
360 | zero_user_segment(page, end, PAGE_CACHE_SIZE); | ||
361 | if (offset == 0) | ||
362 | SetPageUptodate(page); | ||
363 | } else | ||
364 | zero_user_segment(page, pglen, PAGE_CACHE_SIZE); | ||
365 | } | ||
366 | |||
347 | lock_kernel(); | 367 | lock_kernel(); |
348 | status = nfs_updatepage(file, page, offset, copied); | 368 | status = nfs_updatepage(file, page, offset, copied); |
349 | unlock_kernel(); | 369 | unlock_kernel(); |