UBIFS: reset no_space flag after inode deletion
authorAdrian Hunter <adrian.hunter@nokia.com>
Wed, 8 Apr 2009 12:07:57 +0000 (14:07 +0200)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Wed, 6 May 2009 07:37:56 +0000 (10:37 +0300)
When UBIFS runs out of space it spends a lot of time trying to
find more space before returning ENOSPC.  As there is no point
repeating that unless something has changed, UBIFS has an
optimization to record that the file system is 100% full and not
try to find space.  That flag was not being reset when a pending
deletion was finally done.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Reviewed-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
fs/ubifs/budget.c
fs/ubifs/super.c

index af1914462f02b172fb2bb9f37c14fc130e7d8b6c..d0231ba783dfaaa4a881e7bdfd9eb91abaf7b3c2 100644 (file)
@@ -628,7 +628,7 @@ void ubifs_convert_page_budget(struct ubifs_info *c)
  *
  * This function releases budget corresponding to a dirty inode. It is usually
  * called when after the inode has been written to the media and marked as
- * clean.
+ * clean. It also causes the "no space" flags to be cleared.
  */
 void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
                                      struct ubifs_inode *ui)
@@ -636,6 +636,7 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
        struct ubifs_budget_req req;
 
        memset(&req, 0, sizeof(struct ubifs_budget_req));
+       /* The "no space" flags will be cleared because dd_growth is > 0 */
        req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8);
        ubifs_release_budget(c, &req);
 }
index faa44f90608a26f885208a7b53ff786dcc371f3a..f2c1c0b79f66b22c22e5ee144cc2e64834d598d2 100644 (file)
@@ -360,6 +360,11 @@ static void ubifs_delete_inode(struct inode *inode)
 out:
        if (ui->dirty)
                ubifs_release_dirty_inode_budget(c, ui);
+       else {
+               /* We've deleted something - clean the "no space" flags */
+               c->nospace = c->nospace_rp = 0;
+               smp_wmb();
+       }
        clear_inode(inode);
 }