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()
This commit is contained in:
@@ -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);
|
||||
@@ -469,6 +471,14 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
|
||||
err = allocate_budget(c, page, ui, appending);
|
||||
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
|
||||
@@ -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.
|
||||
|
Reference in New Issue
Block a user