diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 15:00:19 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 15:00:19 -0700 |
commit | e0724bf6e4a1f2e678d2b2aab01cae22e17862f0 (patch) | |
tree | 559a8fa8e7a92f8ae0e0a27d4e71f408fa7cec62 /fs/ubifs/file.c | |
parent | 38d9aefb5ce8f26358b0d5cd933cfa9e267105b1 (diff) | |
parent | de0975781a1a8bc92e07eb7681d10ef9bb5e6df9 (diff) | |
download | linux-e0724bf6e4a1f2e678d2b2aab01cae22e17862f0.tar.gz linux-e0724bf6e4a1f2e678d2b2aab01cae22e17862f0.tar.bz2 linux-e0724bf6e4a1f2e678d2b2aab01cae22e17862f0.zip |
Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
* 'linux-next' of git://git.infradead.org/ubifs-2.6:
UBIFS: fix recovery bug
UBIFS: add R/O compatibility
UBIFS: fix compiler warnings
UBIFS: fully sort GCed nodes
UBIFS: fix commentaries
UBIFS: introduce a helpful variable
UBIFS: use KERN_CONT
UBIFS: fix lprops committing bug
UBIFS: fix bogus assertion
UBIFS: fix bug where page is marked uptodate when out of space
UBIFS: amend key_hash return value
UBIFS: improve find function interface
UBIFS: list usage cleanup
UBIFS: fix dbg_chk_lpt_sz()
Diffstat (limited to 'fs/ubifs/file.c')
-rw-r--r-- | fs/ubifs/file.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 0ff89fe71e51..6d34dc7e33e1 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -430,6 +430,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, struct ubifs_inode *ui = ubifs_inode(inode); pgoff_t index = pos >> PAGE_CACHE_SHIFT; int uninitialized_var(err), appending = !!(pos + len > inode->i_size); + int skipped_read = 0; struct page *page; ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size); @@ -444,7 +445,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, if (!PageUptodate(page)) { /* The page is not loaded from the flash */ - if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) + if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE) { /* * We change whole page so no need to load it. But we * have to set the @PG_checked flag to make the further @@ -453,7 +454,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, * the media. */ SetPageChecked(page); - else { + skipped_read = 1; + } else { err = do_readpage(page); if (err) { unlock_page(page); @@ -470,6 +472,14 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, if (unlikely(err)) { ubifs_assert(err == -ENOSPC); /* + * If we skipped reading the page because we were going to + * write all of it, then it is not up to date. + */ + if (skipped_read) { + ClearPageChecked(page); + ClearPageUptodate(page); + } + /* * Budgeting failed which means it would have to force * write-back but didn't, because we set the @fast flag in the * request. Write-back cannot be done now, while we have the @@ -949,7 +959,7 @@ static int do_writepage(struct page *page, int len) * whole index and correct all inode sizes, which is long an unacceptable. * * To prevent situations like this, UBIFS writes pages back only if they are - * within last synchronized inode size, i.e. the the size which has been + * within the last synchronized inode size, i.e. the size which has been * written to the flash media last time. Otherwise, UBIFS forces inode * write-back, thus making sure the on-flash inode contains current inode size, * and then keeps writing pages back. |