OSDN Git Service

xfs: factor the ag length extension code into libxfs
authorDave Chinner <dchinner@redhat.com>
Mon, 14 May 2018 06:10:08 +0000 (23:10 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 16 May 2018 01:12:51 +0000 (18:12 -0700)
Growfs currently manually codes the extension of the last AG in a
filesytem during the growfs process. Factor that out of the growfs
code and move it into libxfs along with teh rest of the AG header
modification code.

Signed-Off-By: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ag.h
fs/xfs/xfs_fsops.c

index 5baa22c..9345802 100644 (file)
@@ -16,6 +16,7 @@
 #include "xfs_alloc_btree.h"
 #include "xfs_rmap_btree.h"
 #include "xfs_alloc.h"
+#include "xfs_ialloc.h"
 #include "xfs_rmap.h"
 #include "xfs_ag.h"
 
@@ -402,3 +403,62 @@ xfs_ag_init_headers(
        }
        return error;
 }
+
+/*
+ * Extent the AG indicated by the @id by the length passed in
+ */
+int
+xfs_ag_extend_space(
+       struct xfs_mount        *mp,
+       struct xfs_trans        *tp,
+       struct aghdr_init_data  *id,
+       xfs_extlen_t            len)
+{
+       struct xfs_owner_info   oinfo;
+       struct xfs_buf          *bp;
+       struct xfs_agi          *agi;
+       struct xfs_agf          *agf;
+       int                     error;
+
+       /*
+        * Change the agi length.
+        */
+       error = xfs_ialloc_read_agi(mp, tp, id->agno, &bp);
+       if (error)
+               return error;
+
+       agi = XFS_BUF_TO_AGI(bp);
+       be32_add_cpu(&agi->agi_length, len);
+       ASSERT(id->agno == mp->m_sb.sb_agcount - 1 ||
+              be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
+       xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
+
+       /*
+        * Change agf length.
+        */
+       error = xfs_alloc_read_agf(mp, tp, id->agno, 0, &bp);
+       if (error)
+               return error;
+
+       agf = XFS_BUF_TO_AGF(bp);
+       be32_add_cpu(&agf->agf_length, len);
+       ASSERT(agf->agf_length == agi->agi_length);
+       xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
+
+       /*
+        * Free the new space.
+        *
+        * XFS_RMAP_OWN_NULL is used here to tell the rmap btree that
+        * this doesn't actually exist in the rmap btree.
+        */
+       xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_NULL);
+       error = xfs_rmap_free(tp, bp, id->agno,
+                               be32_to_cpu(agf->agf_length) - len,
+                               len, &oinfo);
+       if (error)
+               return error;
+
+       return  xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, id->agno,
+                                       be32_to_cpu(agf->agf_length) - len),
+                               len, &oinfo, XFS_AG_RESV_NONE);
+}
index 69f2fd4..412702e 100644 (file)
@@ -7,6 +7,9 @@
 #ifndef __LIBXFS_AG_H
 #define __LIBXFS_AG_H 1
 
+struct xfs_mount;
+struct xfs_trans;
+
 struct aghdr_init_data {
        /* per ag data */
        xfs_agblock_t           agno;           /* ag to init */
@@ -20,6 +23,8 @@ struct aghdr_init_data {
        xfs_btnum_t             type;           /* type of btree root block */
 };
 
-int xfs_ag_init_headers( struct xfs_mount *mp, struct aghdr_init_data *id);
+int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
+int xfs_ag_extend_space(struct xfs_mount *mp, struct xfs_trans *tp,
+                       struct aghdr_init_data *id, xfs_extlen_t len);
 
 #endif /* __LIBXFS_AG_H */
index c5087b7..bc7ef18 100644 (file)
 #include "xfs_trans.h"
 #include "xfs_error.h"
 #include "xfs_btree.h"
-#include "xfs_alloc_btree.h"
 #include "xfs_alloc.h"
-#include "xfs_rmap_btree.h"
-#include "xfs_ialloc.h"
 #include "xfs_fsops.h"
 #include "xfs_trans_space.h"
 #include "xfs_rtalloc.h"
 #include "xfs_trace.h"
 #include "xfs_log.h"
-#include "xfs_rmap.h"
 #include "xfs_ag.h"
 #include "xfs_ag_resv.h"
 
@@ -48,8 +44,6 @@ xfs_growfs_data_private(
        xfs_mount_t             *mp,            /* mount point for filesystem */
        xfs_growfs_data_t       *in)            /* growfs data input struct */
 {
-       xfs_agf_t               *agf;
-       xfs_agi_t               *agi;
        xfs_buf_t               *bp;
        int                     error;
        xfs_agnumber_t          nagcount;
@@ -132,57 +126,9 @@ xfs_growfs_data_private(
 
        xfs_trans_agblocks_delta(tp, id.nfree);
 
-       /*
-        * There are new blocks in the old last a.g.
-        */
+       /* If there are new blocks in the old last AG, extend it. */
        if (new) {
-               struct xfs_owner_info   oinfo;
-
-               /*
-                * Change the agi length.
-                */
-               error = xfs_ialloc_read_agi(mp, tp, id.agno, &bp);
-               if (error)
-                       goto out_trans_cancel;
-
-               ASSERT(bp);
-               agi = XFS_BUF_TO_AGI(bp);
-               be32_add_cpu(&agi->agi_length, new);
-               ASSERT(nagcount == oagcount ||
-                      be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
-               xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);
-
-               /*
-                * Change agf length.
-                */
-               error = xfs_alloc_read_agf(mp, tp, id.agno, 0, &bp);
-               if (error)
-                       goto out_trans_cancel;
-
-               ASSERT(bp);
-               agf = XFS_BUF_TO_AGF(bp);
-               be32_add_cpu(&agf->agf_length, new);
-               ASSERT(be32_to_cpu(agf->agf_length) ==
-                      be32_to_cpu(agi->agi_length));
-
-               xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);
-
-               /*
-                * Free the new space.
-                *
-                * XFS_RMAP_OWN_NULL is used here to tell the rmap btree that
-                * this doesn't actually exist in the rmap btree.
-                */
-               xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_NULL);
-               error = xfs_rmap_free(tp, bp, id.agno,
-                               be32_to_cpu(agf->agf_length) - new,
-                               new, &oinfo);
-               if (error)
-                       goto out_trans_cancel;
-               error = xfs_free_extent(tp,
-                               XFS_AGB_TO_FSB(mp, id.agno,
-                                       be32_to_cpu(agf->agf_length) - new),
-                               new, &oinfo, XFS_AG_RESV_NONE);
+               error = xfs_ag_extend_space(mp, tp, &id, new);
                if (error)
                        goto out_trans_cancel;
        }