Skip to content

Commit

Permalink
Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
Browse files Browse the repository at this point in the history
* '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()
  • Loading branch information
Linus Torvalds committed Apr 6, 2009
2 parents 38d9aef + de09757 commit e0724bf
Show file tree
Hide file tree
Showing 17 changed files with 482 additions and 265 deletions.
37 changes: 17 additions & 20 deletions fs/ubifs/budget.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,29 +194,26 @@ static int make_free_space(struct ubifs_info *c)
}

/**
* ubifs_calc_min_idx_lebs - calculate amount of eraseblocks for the index.
* ubifs_calc_min_idx_lebs - calculate amount of LEBs for the index.
* @c: UBIFS file-system description object
*
* This function calculates and returns the number of eraseblocks which should
* be kept for index usage.
* This function calculates and returns the number of LEBs which should be kept
* for index usage.
*/
int ubifs_calc_min_idx_lebs(struct ubifs_info *c)
{
int idx_lebs, eff_leb_size = c->leb_size - c->max_idx_node_sz;
int idx_lebs;
long long idx_size;

idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx;

/* And make sure we have thrice the index size of space reserved */
idx_size = idx_size + (idx_size << 1);

idx_size += idx_size << 1;
/*
* We do not maintain 'old_idx_size' as 'old_idx_lebs'/'old_idx_bytes'
* pair, nor similarly the two variables for the new index size, so we
* have to do this costly 64-bit division on fast-path.
*/
idx_size += eff_leb_size - 1;
idx_lebs = div_u64(idx_size, eff_leb_size);
idx_lebs = div_u64(idx_size + c->idx_leb_size - 1, c->idx_leb_size);
/*
* The index head is not available for the in-the-gaps method, so add an
* extra LEB to compensate.
Expand Down Expand Up @@ -310,23 +307,23 @@ static int can_use_rp(struct ubifs_info *c)
* do_budget_space - reserve flash space for index and data growth.
* @c: UBIFS file-system description object
*
* This function makes sure UBIFS has enough free eraseblocks for index growth
* and data.
* This function makes sure UBIFS has enough free LEBs for index growth and
* data.
*
* When budgeting index space, UBIFS reserves thrice as many LEBs as the index
* would take if it was consolidated and written to the flash. This guarantees
* that the "in-the-gaps" commit method always succeeds and UBIFS will always
* be able to commit dirty index. So this function basically adds amount of
* budgeted index space to the size of the current index, multiplies this by 3,
* and makes sure this does not exceed the amount of free eraseblocks.
* and makes sure this does not exceed the amount of free LEBs.
*
* Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables:
* o @c->lst.idx_lebs is the number of LEBs the index currently uses. It might
* be large, because UBIFS does not do any index consolidation as long as
* there is free space. IOW, the index may take a lot of LEBs, but the LEBs
* will contain a lot of dirt.
* o @c->min_idx_lebs is the the index presumably takes. IOW, the index may be
* consolidated to take up to @c->min_idx_lebs LEBs.
* o @c->min_idx_lebs is the number of LEBS the index presumably takes. IOW,
* the index may be consolidated to take up to @c->min_idx_lebs LEBs.
*
* This function returns zero in case of success, and %-ENOSPC in case of
* failure.
Expand Down Expand Up @@ -695,12 +692,12 @@ long long ubifs_reported_space(const struct ubifs_info *c, long long free)
* This function calculates amount of free space to report to user-space.
*
* Because UBIFS may introduce substantial overhead (the index, node headers,
* alignment, wastage at the end of eraseblocks, etc), it cannot report real
* amount of free flash space it has (well, because not all dirty space is
* reclaimable, UBIFS does not actually know the real amount). If UBIFS did so,
* it would bread user expectations about what free space is. Users seem to
* accustomed to assume that if the file-system reports N bytes of free space,
* they would be able to fit a file of N bytes to the FS. This almost works for
* alignment, wastage at the end of LEBs, etc), it cannot report real amount of
* free flash space it has (well, because not all dirty space is reclaimable,
* UBIFS does not actually know the real amount). If UBIFS did so, it would
* bread user expectations about what free space is. Users seem to accustomed
* to assume that if the file-system reports N bytes of free space, they would
* be able to fit a file of N bytes to the FS. This almost works for
* traditional file-systems, because they have way less overhead than UBIFS.
* So, to keep users happy, UBIFS tries to take the overhead into account.
*/
Expand Down
6 changes: 3 additions & 3 deletions fs/ubifs/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,9 +479,9 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
"bad or corrupted node)");
else {
for (i = 0; i < nlen && dent->name[i]; i++)
printk("%c", dent->name[i]);
printk(KERN_CONT "%c", dent->name[i]);
}
printk("\n");
printk(KERN_CONT "\n");

break;
}
Expand Down Expand Up @@ -1214,7 +1214,7 @@ static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr)

/*
* Make sure the last key in our znode is less or
* equivalent than the the key in zbranch which goes
* equivalent than the key in the zbranch which goes
* after our pointing zbranch.
*/
cmp = keys_cmp(c, max,
Expand Down
16 changes: 13 additions & 3 deletions fs/ubifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions fs/ubifs/find.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
* ubifs_find_free_space - find a data LEB with free space.
* @c: the UBIFS file-system description object
* @min_space: minimum amount of required free space
* @free: contains amount of free space in the LEB on exit
* @offs: contains offset of where free space starts on exit
* @squeeze: whether to try to find space in a non-empty LEB first
*
* This function looks for an LEB with at least @min_space bytes of free space.
Expand All @@ -490,7 +490,7 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
* failed to find a LEB with @min_space bytes of free space and other a negative
* error codes in case of failure.
*/
int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
int squeeze)
{
const struct ubifs_lprops *lprops;
Expand Down Expand Up @@ -558,10 +558,10 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
spin_unlock(&c->space_lock);
}

*free = lprops->free;
*offs = c->leb_size - lprops->free;
ubifs_release_lprops(c);

if (*free == c->leb_size) {
if (*offs == 0) {
/*
* Ensure that empty LEBs have been unmapped. They may not have
* been, for example, because of an unclean unmount. Also
Expand All @@ -573,8 +573,8 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
return err;
}

dbg_find("found LEB %d, free %d", lnum, *free);
ubifs_assert(*free >= min_space);
dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs);
ubifs_assert(*offs <= c->leb_size - min_space);
return lnum;

out:
Expand Down
Loading

0 comments on commit e0724bf

Please sign in to comment.