diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-12-05 00:35:38 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-12-06 10:46:36 -0500 |
commit | 49a70f278658894d2899824cd4037095fb6711fe (patch) | |
tree | 8fc0e55be04a421ee9091a989c30807d891d7930 /fs/nfs/write.c | |
parent | 277459d2e2cd40594967757e8fd016c4c7016614 (diff) |
NFS: Cleanup: add common helper nfs_page_length()
Clean up a lot of ad-hoc page length calculations in fs/nfs/write.c
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 55 |
1 files changed, 10 insertions, 45 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 6df8319de060..3f6ca5229562 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <linux/smp_lock.h> | 63 | #include <linux/smp_lock.h> |
64 | 64 | ||
65 | #include "delegation.h" | 65 | #include "delegation.h" |
66 | #include "internal.h" | ||
66 | #include "iostat.h" | 67 | #include "iostat.h" |
67 | 68 | ||
68 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 69 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
@@ -199,30 +200,15 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c | |||
199 | */ | 200 | */ |
200 | static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count) | 201 | static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count) |
201 | { | 202 | { |
202 | loff_t end_offs; | ||
203 | |||
204 | if (PageUptodate(page)) | 203 | if (PageUptodate(page)) |
205 | return; | 204 | return; |
206 | if (base != 0) | 205 | if (base != 0) |
207 | return; | 206 | return; |
208 | if (count == PAGE_CACHE_SIZE) { | 207 | if (count != nfs_page_length(page)) |
209 | SetPageUptodate(page); | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | end_offs = i_size_read(page->mapping->host) - 1; | ||
214 | if (end_offs < 0) | ||
215 | return; | ||
216 | /* Is this the last page? */ | ||
217 | if (page->index != (unsigned long)(end_offs >> PAGE_CACHE_SHIFT)) | ||
218 | return; | 208 | return; |
219 | /* This is the last page: set PG_uptodate if we cover the entire | 209 | if (count != PAGE_CACHE_SIZE) |
220 | * extent of the data, then zero the rest of the page. | ||
221 | */ | ||
222 | if (count == (unsigned int)(end_offs & (PAGE_CACHE_SIZE - 1)) + 1) { | ||
223 | memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); | 210 | memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); |
224 | SetPageUptodate(page); | 211 | SetPageUptodate(page); |
225 | } | ||
226 | } | 212 | } |
227 | 213 | ||
228 | /* | 214 | /* |
@@ -330,9 +316,7 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) | |||
330 | { | 316 | { |
331 | struct nfs_open_context *ctx; | 317 | struct nfs_open_context *ctx; |
332 | struct inode *inode = page->mapping->host; | 318 | struct inode *inode = page->mapping->host; |
333 | unsigned long end_index; | 319 | unsigned offset; |
334 | unsigned offset = PAGE_CACHE_SIZE; | ||
335 | loff_t i_size = i_size_read(inode); | ||
336 | int inode_referenced = 0; | 320 | int inode_referenced = 0; |
337 | int priority = wb_priority(wbc); | 321 | int priority = wb_priority(wbc); |
338 | int err; | 322 | int err; |
@@ -350,22 +334,15 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) | |||
350 | */ | 334 | */ |
351 | if (igrab(inode) != 0) | 335 | if (igrab(inode) != 0) |
352 | inode_referenced = 1; | 336 | inode_referenced = 1; |
353 | end_index = i_size >> PAGE_CACHE_SHIFT; | ||
354 | 337 | ||
355 | /* Ensure we've flushed out any previous writes */ | 338 | /* Ensure we've flushed out any previous writes */ |
356 | nfs_wb_page_priority(inode, page, priority); | 339 | nfs_wb_page_priority(inode, page, priority); |
357 | 340 | ||
358 | /* easy case */ | 341 | err = 0; |
359 | if (page->index < end_index) | 342 | offset = nfs_page_length(page); |
360 | goto do_it; | 343 | if (!offset) |
361 | /* things got complicated... */ | ||
362 | offset = i_size & (PAGE_CACHE_SIZE-1); | ||
363 | |||
364 | /* OK, are we completely out? */ | ||
365 | err = 0; /* potential race with truncate - ignore */ | ||
366 | if (page->index >= end_index+1 || !offset) | ||
367 | goto out; | 344 | goto out; |
368 | do_it: | 345 | |
369 | ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE); | 346 | ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE); |
370 | if (ctx == NULL) { | 347 | if (ctx == NULL) { |
371 | err = -EBADF; | 348 | err = -EBADF; |
@@ -826,20 +803,8 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
826 | * fragmenting write requests. | 803 | * fragmenting write requests. |
827 | */ | 804 | */ |
828 | if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { | 805 | if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { |
829 | loff_t end_offs = i_size_read(inode) - 1; | 806 | count = max(count + offset, nfs_page_length(page)); |
830 | unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT; | ||
831 | |||
832 | count += offset; | ||
833 | offset = 0; | 807 | offset = 0; |
834 | if (unlikely(end_offs < 0)) { | ||
835 | /* Do nothing */ | ||
836 | } else if (page->index == end_index) { | ||
837 | unsigned int pglen; | ||
838 | pglen = (unsigned int)(end_offs & (PAGE_CACHE_SIZE-1)) + 1; | ||
839 | if (count < pglen) | ||
840 | count = pglen; | ||
841 | } else if (page->index < end_index) | ||
842 | count = PAGE_CACHE_SIZE; | ||
843 | } | 808 | } |
844 | 809 | ||
845 | /* | 810 | /* |