]> git.neil.brown.name Git - LaFS.git/commitdiff
Revise error returns for allocation failure.
authorNeilBrown <neilb@suse.de>
Wed, 23 Jun 2010 06:20:28 +0000 (16:20 +1000)
committerNeilBrown <neilb@suse.de>
Fri, 25 Jun 2010 06:46:39 +0000 (16:46 +1000)
lafs_prealloc, like lafs_space_alloc, just succeeds or fails, it
doesn't choose the error type.

lafs_cluster_update_pin and lafs_reserve_block need to indicate
either -ENOSPC or -EAGAIN depending on context.

Signed-off-by: NeilBrown <neilb@suse.de>
block.c
cluster.c
modify.c

diff --git a/block.c b/block.c
index 271245199b7876e9a9f412a7f6e31d8df84524c3..89431fe0844d470457db7b8f8d9a76c1b2beb544 100644 (file)
--- a/block.c
+++ b/block.c
@@ -366,29 +366,26 @@ lafs_reserve_block(struct block *b, int alloc_type)
        else
                err = lafs_setparent(dblk(b));
 
-       if (test_bit(B_Realloc, &b->flags))
-               alloc_type = CleanSpace;
-       if (alloc_type == NewSpace && b->physaddr)
+       /* If there is already a physaddr, or the data is
+        * stored in the inode, then we aren't really allocating
+        * new space.
+        * When unlinking from a small directory, this can
+        * be an issue.
+        */
+       if (alloc_type == NewSpace &&
+           (b->physaddr || (b->fileaddr == 0
+                            && LAFSI(b->inode)->depth == 0)))
                alloc_type = ReleaseSpace;
 
-       if (alloc_type == NewSpace && !b->physaddr &&
-           b->fileaddr == 0 &&
-           LAFSI(b->inode)->depth == 0) {
-               /* HACK. If the file isn't growing, we can use
-                * ReleaseSpace.  But we don't really know.
-                * This is needed for unlink
-                */
-               alloc_type = ReleaseSpace;
-       }
-       if (alloc_type == NewSpace && test_bit(B_InoIdx, &b->flags)) {
-               /* HACK, phys isn't necessarily set for the InoIdx block.
-                * Is this a good way to handle that?
+       if (alloc_type == NewSpace && test_bit(B_InoIdx, &b->flags))
+               /* physaddr isn't necessarily set for the InoIdx block.
                 */
                alloc_type = ReleaseSpace;
-       }
 
+       /* Allocate space in the filesystem */
        err = err ?: lafs_prealloc(b, alloc_type);
 
+       /* Allocate space in the file (and quota set) */
        if (err == 0 && b->physaddr == 0 &&
            !test_bit(B_Index, &b->flags) &&
            !test_and_set_bit(B_Prealloc, &b->flags)) {
@@ -396,8 +393,6 @@ lafs_reserve_block(struct block *b, int alloc_type)
                if (err)
                        clear_bit(B_Prealloc, &b->flags);
        }
-       if (err)
-               return err;
 
        /* Having reserved the block, we need to get a segref,
         * which will involve reserving those blocks too.
@@ -409,7 +404,13 @@ lafs_reserve_block(struct block *b, int alloc_type)
               && !test_bit(B_SegRef, &b->flags))
                err = lafs_seg_ref_block(b, 0);
 
-       return err;
+       if (err == 0)
+               return 0;
+       if (alloc_type == CleanSpace || alloc_type == NewSpace)
+               return -ENOSPC;
+       if (alloc_type == ReleaseSpace)
+               return -EAGAIN;
+       LAFS_BUG(1, b);
 }
 
 int
index 377d53698efe58b2e375d3a10740f3f8a352c9a9..ba2f7b7027ff4d164d766317762297e66e951ee2 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -894,6 +894,7 @@ lafs_cluster_update_prepare(struct update_handle *uh, struct fs *fs,
        uh->reserved = 0;
        return 0;
 }
+
 int
 lafs_cluster_update_pin(struct update_handle *uh)
 {
@@ -903,7 +904,7 @@ lafs_cluster_update_pin(struct update_handle *uh)
                uh->fs->cluster_updates++;
                return 0;
        }
-       return -ENOSPC;
+       return -EAGAIN;
 }
 
 static unsigned long long
index 481057d839e7f2bba0d9bf67875cf48ccee16bd3..33b2cf8d90466519672968b0b697b590f03d43b0 100644 (file)
--- a/modify.c
+++ b/modify.c
@@ -1932,11 +1932,7 @@ int __must_check lafs_prealloc(struct block *blk, int why)
        }
        lafs_space_return(fs, credits);
 
-       /* allocation failed. */
-       if (why == NewSpace)
-               return -ENOSPC;
-       else
-               return -EAGAIN;
+       return -ENOSPC;
 }
 
 /* If a datablock is dirty and pinned to the previous phase,