diff mbox

[v2] Btrfs: clarify do_chunk_alloc()'s return value

Message ID 1469815790-13511-1-git-send-email-bo.li.liu@oracle.com (mailing list archive)
State Accepted
Headers show

Commit Message

Liu Bo July 29, 2016, 6:09 p.m. UTC
Function start_transaction() can return ERR_PTR(1) when flush is
BTRFS_RESERVE_FLUSH_LIMIT, so the call graph is

start_transaction (return ERR_PTR(1))
  -> btrfs_block_rsv_add (return 1)
     -> reserve_metadata_bytes (return 1)
        -> flush_space (return 1)
           -> do_chunk_alloc  (return 1)

With BTRFS_RESERVE_FLUSH_LIMIT, if flush_space is already on the
flush_state of ALLOC_CHUNK and it successfully allocates a new
chunk, then instead of trying to reserve space again,
reserve_metadata_bytes returns 1 immediately.

Eventually the callers who call start_transaction() usually just
do the IS_ERR() check which ERR_PTR(1) can pass, then it'll get
a panic when dereferencing a pointer which is ERR_PTR(1).

The following patch fixes the above problem.
"btrfs: flush_space: treat return value of do_chunk_alloc properly"
https://patchwork.kernel.org/patch/7778651/

This add comments to clarify do_chunk_alloc()'s return value.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
---
v2: Since there is already a patch fixing the problem, lets do the 
    comment part separately.

 fs/btrfs/extent-tree.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

David Sterba Aug. 18, 2016, 12:36 p.m. UTC | #1
On Fri, Jul 29, 2016 at 11:09:50AM -0700, Liu Bo wrote:
> Function start_transaction() can return ERR_PTR(1) when flush is
> BTRFS_RESERVE_FLUSH_LIMIT, so the call graph is
> 
> start_transaction (return ERR_PTR(1))
>   -> btrfs_block_rsv_add (return 1)
>      -> reserve_metadata_bytes (return 1)
>         -> flush_space (return 1)
>            -> do_chunk_alloc  (return 1)
> 
> With BTRFS_RESERVE_FLUSH_LIMIT, if flush_space is already on the
> flush_state of ALLOC_CHUNK and it successfully allocates a new
> chunk, then instead of trying to reserve space again,
> reserve_metadata_bytes returns 1 immediately.
> 
> Eventually the callers who call start_transaction() usually just
> do the IS_ERR() check which ERR_PTR(1) can pass, then it'll get
> a panic when dereferencing a pointer which is ERR_PTR(1).
> 
> The following patch fixes the above problem.
> "btrfs: flush_space: treat return value of do_chunk_alloc properly"
> https://patchwork.kernel.org/patch/7778651/
> 
> This add comments to clarify do_chunk_alloc()'s return value.
> 
> Signed-off-by: Liu Bo <bo.li.liu@oracle.com>

Patch queued, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 7a35c9d..921cde6 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4457,6 +4457,15 @@  void check_system_chunk(struct btrfs_trans_handle *trans,
 	}
 }
 
+/*
+ * If force is CHUNK_ALLOC_FORCE:
+ *    - return 1 if it successfully allocates a chunk,
+ *    - return errors including -ENOSPC otherwise.
+ * If force is NOT CHUNK_ALLOC_FORCE:
+ *    - return 0 if it doesn't need to allocate a new chunk,
+ *    - return 1 if it successfully allocates a chunk,
+ *    - return errors including -ENOSPC otherwise.
+ */
 static int do_chunk_alloc(struct btrfs_trans_handle *trans,
 			  struct btrfs_root *extent_root, u64 flags, int force)
 {