]> www.infradead.org Git - users/willy/xarray.git/commitdiff
xfs: Convert m_perag_tree to XArray
authorMatthew Wilcox <willy@infradead.org>
Tue, 25 Sep 2018 22:52:51 +0000 (18:52 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 8 Aug 2019 02:36:47 +0000 (22:36 -0400)
This is a relatively straightforward conversion to the XArray API.
I've renamed a few tags to marks in this patch; more will follow in
later patches.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
fs/xfs/libxfs/xfs_sb.c
fs/xfs/libxfs/xfs_sb.h
fs/xfs/xfs_icache.c
fs/xfs/xfs_icache.h
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_super.c

index a08dd8f40346fae595b455e86dc784b90a3c4767..7639bf9b8737258e33f905046bb295a09f91291b 100644 (file)
@@ -43,7 +43,7 @@ xfs_perag_get(
        int                     ref = 0;
 
        rcu_read_lock();
-       pag = radix_tree_lookup(&mp->m_perag_tree, agno);
+       pag = xa_load(&mp->m_perags, agno);
        if (pag) {
                ASSERT(atomic_read(&pag->pag_ref) >= 0);
                ref = atomic_inc_return(&pag->pag_ref);
@@ -54,22 +54,21 @@ xfs_perag_get(
 }
 
 /*
- * search from @first to find the next perag with the given tag set.
+ * search from @first to find the next perag with the given mark set.
  */
 struct xfs_perag *
-xfs_perag_get_tag(
+xfs_perag_get_mark(
        struct xfs_mount        *mp,
        xfs_agnumber_t          first,
-       int                     tag)
+       xa_mark_t               mark)
 {
        struct xfs_perag        *pag;
-       int                     found;
        int                     ref;
+       unsigned long           index = first;
 
        rcu_read_lock();
-       found = radix_tree_gang_lookup_tag(&mp->m_perag_tree,
-                                       (void **)&pag, first, 1, tag);
-       if (found <= 0) {
+       pag = xa_find(&mp->m_perags, &index, ULONG_MAX, mark);
+       if (!pag) {
                rcu_read_unlock();
                return NULL;
        }
index 92465a9a516204b40771b80fcfb3d8ccdbda900c..2459f5f7d663aabc40efe322f24c79dd46ba7158 100644 (file)
@@ -17,8 +17,8 @@ struct xfs_perag;
  * perag get/put wrappers for ref counting
  */
 extern struct xfs_perag *xfs_perag_get(struct xfs_mount *, xfs_agnumber_t);
-extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t,
-                                          int tag);
+extern struct xfs_perag *xfs_perag_get_mark(struct xfs_mount *, xfs_agnumber_t,
+                                          xa_mark_t mark);
 extern void    xfs_perag_put(struct xfs_perag *pag);
 extern int     xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t);
 
index 0b0fd10a36d4da80870e3d3734c6908acf721fa5..2484dceab35ac2f2eaa0e7d4218fe3e5677851fa 100644 (file)
@@ -149,13 +149,10 @@ static void
 xfs_reclaim_work_queue(
        struct xfs_mount        *mp)
 {
-
-       rcu_read_lock();
-       if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_RECLAIM_TAG)) {
+       if (xa_marked(&mp->m_perags, XFS_ICI_RECLAIM_MARK)) {
                queue_delayed_work(mp->m_reclaim_workqueue, &mp->m_reclaim_work,
                        msecs_to_jiffies(xfs_syncd_centisecs / 6 * 10));
        }
-       rcu_read_unlock();
 }
 
 /*
@@ -186,11 +183,8 @@ xfs_perag_set_reclaim_tag(
        if (pag->pag_ici_reclaimable++)
                return;
 
-       /* propagate the reclaim tag up into the perag radix tree */
-       spin_lock(&mp->m_perag_lock);
-       radix_tree_tag_set(&mp->m_perag_tree, pag->pag_agno,
-                          XFS_ICI_RECLAIM_TAG);
-       spin_unlock(&mp->m_perag_lock);
+       /* propagate the reclaim tag up into the perag xarray */
+       xa_set_mark(&mp->m_perags, pag->pag_agno, XFS_ICI_RECLAIM_MARK);
 
        /* schedule periodic background inode reclaim */
        xfs_reclaim_work_queue(mp);
@@ -208,11 +202,8 @@ xfs_perag_clear_reclaim_tag(
        if (--pag->pag_ici_reclaimable)
                return;
 
-       /* clear the reclaim tag from the perag radix tree */
-       spin_lock(&mp->m_perag_lock);
-       radix_tree_tag_clear(&mp->m_perag_tree, pag->pag_agno,
-                            XFS_ICI_RECLAIM_TAG);
-       spin_unlock(&mp->m_perag_lock);
+       /* clear the reclaim tag from the perag xarray */
+       xa_clear_mark(&mp->m_perags, pag->pag_agno, XFS_ICI_RECLAIM_MARK);
        trace_xfs_perag_clear_reclaim(mp, pag->pag_agno, -1, _RET_IP_);
 }
 
@@ -893,12 +884,10 @@ void
 xfs_queue_eofblocks(
        struct xfs_mount *mp)
 {
-       rcu_read_lock();
-       if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_EOFBLOCKS_TAG))
+       if (xa_marked(&mp->m_perags, XFS_ICI_EOFBLOCKS_MARK))
                queue_delayed_work(mp->m_eofblocks_workqueue,
                                   &mp->m_eofblocks_work,
                                   msecs_to_jiffies(xfs_eofb_secs * 1000));
-       rcu_read_unlock();
 }
 
 void
@@ -920,12 +909,10 @@ void
 xfs_queue_cowblocks(
        struct xfs_mount *mp)
 {
-       rcu_read_lock();
-       if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_COWBLOCKS_TAG))
+       if (xa_marked(&mp->m_perags, XFS_ICI_COWBLOCKS_MARK))
                queue_delayed_work(mp->m_eofblocks_workqueue,
                                   &mp->m_cowblocks_work,
                                   msecs_to_jiffies(xfs_cowb_secs * 1000));
-       rcu_read_unlock();
 }
 
 void
@@ -993,7 +980,7 @@ xfs_inode_ag_iterator_tag(
        xfs_agnumber_t          ag;
 
        ag = 0;
-       while ((pag = xfs_perag_get_tag(mp, ag, tag))) {
+       while ((pag = xfs_perag_get_mark(mp, ag, tag))) {
                ag = pag->pag_agno + 1;
                error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag,
                                          0);
@@ -1250,7 +1237,7 @@ xfs_reclaim_inodes_ag(
 restart:
        ag = 0;
        skipped = 0;
-       while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
+       while ((pag = xfs_perag_get_mark(mp, ag, XFS_ICI_RECLAIM_MARK))) {
                unsigned long   first_index = 0;
                int             done = 0;
                int             nr_found = 0;
@@ -1397,7 +1384,7 @@ xfs_reclaim_inodes_count(
        xfs_agnumber_t          ag = 0;
        int                     reclaimable = 0;
 
-       while ((pag = xfs_perag_get_tag(mp, ag, XFS_ICI_RECLAIM_TAG))) {
+       while ((pag = xfs_perag_get_mark(mp, ag, XFS_ICI_RECLAIM_MARK))) {
                ag = pag->pag_agno + 1;
                reclaimable += pag->pag_ici_reclaimable;
                xfs_perag_put(pag);
@@ -1598,40 +1585,38 @@ xfs_iflag_for_tag(
 }
 
 static void
-__xfs_inode_set_blocks_tag(
+__xfs_inode_set_blocks_mark(
        xfs_inode_t     *ip,
        void            (*execute)(struct xfs_mount *mp),
        void            (*set_tp)(struct xfs_mount *mp, xfs_agnumber_t agno,
                                  int error, unsigned long caller_ip),
-       int             tag)
+       xa_mark_t       mark)
 {
        struct xfs_mount *mp = ip->i_mount;
        struct xfs_perag *pag;
-       int tagged;
+       int marked;
 
        /*
-        * Don't bother locking the AG and looking up in the radix trees
-        * if we already know that we have the tag set.
+        * Don't bother locking the AG and looking up in the xarray
+        * if we already know that we have the mark set.
         */
-       if (ip->i_flags & xfs_iflag_for_tag(tag))
+       if (ip->i_flags & xfs_iflag_for_tag(mark))
                return;
        spin_lock(&ip->i_flags_lock);
-       ip->i_flags |= xfs_iflag_for_tag(tag);
+       ip->i_flags |= xfs_iflag_for_tag(mark);
        spin_unlock(&ip->i_flags_lock);
 
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
        spin_lock(&pag->pag_ici_lock);
 
-       tagged = radix_tree_tagged(&pag->pag_ici_root, tag);
+       marked = radix_tree_tagged(&pag->pag_ici_root, mark);
        radix_tree_tag_set(&pag->pag_ici_root,
-                          XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), tag);
-       if (!tagged) {
-               /* propagate the eofblocks tag up into the perag radix tree */
-               spin_lock(&ip->i_mount->m_perag_lock);
-               radix_tree_tag_set(&ip->i_mount->m_perag_tree,
+                          XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), mark);
+       if (!marked) {
+               /* propagate the eofblocks mark up into the perag xarray */
+               xa_set_mark(&ip->i_mount->m_perags,
                                   XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
-                                  tag);
-               spin_unlock(&ip->i_mount->m_perag_lock);
+                                  mark);
 
                /* kick off background trimming */
                execute(ip->i_mount);
@@ -1648,37 +1633,35 @@ xfs_inode_set_eofblocks_tag(
        xfs_inode_t     *ip)
 {
        trace_xfs_inode_set_eofblocks_tag(ip);
-       return __xfs_inode_set_blocks_tag(ip, xfs_queue_eofblocks,
+       return __xfs_inode_set_blocks_mark(ip, xfs_queue_eofblocks,
                        trace_xfs_perag_set_eofblocks,
-                       XFS_ICI_EOFBLOCKS_TAG);
+                       XFS_ICI_EOFBLOCKS_MARK);
 }
 
 static void
-__xfs_inode_clear_blocks_tag(
+__xfs_inode_clear_blocks_mark(
        xfs_inode_t     *ip,
        void            (*clear_tp)(struct xfs_mount *mp, xfs_agnumber_t agno,
                                    int error, unsigned long caller_ip),
-       int             tag)
+       xa_mark_t       mark)
 {
        struct xfs_mount *mp = ip->i_mount;
        struct xfs_perag *pag;
 
        spin_lock(&ip->i_flags_lock);
-       ip->i_flags &= ~xfs_iflag_for_tag(tag);
+       ip->i_flags &= ~xfs_iflag_for_tag(mark);
        spin_unlock(&ip->i_flags_lock);
 
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
        spin_lock(&pag->pag_ici_lock);
 
        radix_tree_tag_clear(&pag->pag_ici_root,
-                            XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), tag);
-       if (!radix_tree_tagged(&pag->pag_ici_root, tag)) {
-               /* clear the eofblocks tag from the perag radix tree */
-               spin_lock(&ip->i_mount->m_perag_lock);
-               radix_tree_tag_clear(&ip->i_mount->m_perag_tree,
+                            XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), mark);
+       if (!radix_tree_tagged(&pag->pag_ici_root, mark)) {
+               /* clear the eofblocks mark from the perag xarray */
+               xa_clear_mark(&ip->i_mount->m_perags,
                                     XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
-                                    tag);
-               spin_unlock(&ip->i_mount->m_perag_lock);
+                                    mark);
                clear_tp(ip->i_mount, pag->pag_agno, -1, _RET_IP_);
        }
 
@@ -1691,8 +1674,9 @@ xfs_inode_clear_eofblocks_tag(
        xfs_inode_t     *ip)
 {
        trace_xfs_inode_clear_eofblocks_tag(ip);
-       return __xfs_inode_clear_blocks_tag(ip,
-                       trace_xfs_perag_clear_eofblocks, XFS_ICI_EOFBLOCKS_TAG);
+       return __xfs_inode_clear_blocks_mark(ip,
+                       trace_xfs_perag_clear_eofblocks,
+                       XFS_ICI_EOFBLOCKS_MARK);
 }
 
 /*
@@ -1804,9 +1788,9 @@ xfs_inode_set_cowblocks_tag(
        xfs_inode_t     *ip)
 {
        trace_xfs_inode_set_cowblocks_tag(ip);
-       return __xfs_inode_set_blocks_tag(ip, xfs_queue_cowblocks,
+       return __xfs_inode_set_blocks_mark(ip, xfs_queue_cowblocks,
                        trace_xfs_perag_set_cowblocks,
-                       XFS_ICI_COWBLOCKS_TAG);
+                       XFS_ICI_COWBLOCKS_MARK);
 }
 
 void
@@ -1814,8 +1798,9 @@ xfs_inode_clear_cowblocks_tag(
        xfs_inode_t     *ip)
 {
        trace_xfs_inode_clear_cowblocks_tag(ip);
-       return __xfs_inode_clear_blocks_tag(ip,
-                       trace_xfs_perag_clear_cowblocks, XFS_ICI_COWBLOCKS_TAG);
+       return __xfs_inode_clear_blocks_mark(ip,
+                       trace_xfs_perag_clear_cowblocks,
+                       XFS_ICI_COWBLOCKS_MARK);
 }
 
 /* Disable post-EOF and CoW block auto-reclamation. */
index 48f1fd2bb6ad861b49fdf3dcb29bb3efbab54e76..cc786b109e054e3ea799e77534a73472d5b860f9 100644 (file)
@@ -21,13 +21,16 @@ struct xfs_eofblocks {
 #define SYNC_TRYLOCK           0x0002  /* only try to lock inodes */
 
 /*
- * tags for inode radix tree
+ * marks for inode xarray
  */
 #define XFS_ICI_NO_TAG         (-1)    /* special flag for an untagged lookup
                                           in xfs_inode_ag_iterator */
 #define XFS_ICI_RECLAIM_TAG    0       /* inode is to be reclaimed */
 #define XFS_ICI_EOFBLOCKS_TAG  1       /* inode has blocks beyond EOF */
 #define XFS_ICI_COWBLOCKS_TAG  2       /* inode can have cow blocks to gc */
+#define XFS_ICI_RECLAIM_MARK   XA_MARK_0 /* inode is to be reclaimed */
+#define XFS_ICI_EOFBLOCKS_MARK XA_MARK_1 /* inode has blocks beyond EOF */
+#define XFS_ICI_COWBLOCKS_MARK XA_MARK_2 /* inode can have cow blocks to gc */
 
 /*
  * Flags for xfs_iget()
index 322da69092909078fb16222877ddcf7ad9c1a62d..73a741f2e4a7721d376e3f85932c513aeb0ae122 100644 (file)
@@ -141,9 +141,7 @@ xfs_free_perag(
        struct xfs_perag *pag;
 
        for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
-               spin_lock(&mp->m_perag_lock);
-               pag = radix_tree_delete(&mp->m_perag_tree, agno);
-               spin_unlock(&mp->m_perag_lock);
+               pag = xa_erase(&mp->m_perags, agno);
                ASSERT(pag);
                ASSERT(atomic_read(&pag->pag_ref) == 0);
                xfs_iunlink_destroy(pag);
@@ -183,7 +181,7 @@ xfs_initialize_perag(
        int             error = -ENOMEM;
 
        /*
-        * Walk the current per-ag tree so we don't try to initialise AGs
+        * Walk the current per-ag array so we don't try to initialise AGs
         * that already exist (growfs case). Allocate and insert all the
         * AGs we don't find ready for initialisation.
         */
@@ -209,19 +207,9 @@ xfs_initialize_perag(
                pag->pagb_count = 0;
                pag->pagb_tree = RB_ROOT;
 
-               if (radix_tree_preload(GFP_NOFS))
-                       goto out_hash_destroy;
-
-               spin_lock(&mp->m_perag_lock);
-               if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {
-                       BUG();
-                       spin_unlock(&mp->m_perag_lock);
-                       radix_tree_preload_end();
-                       error = -EEXIST;
+               error = xa_err(xa_store(&mp->m_perags, index, pag, GFP_NOFS));
+               if (error)
                        goto out_hash_destroy;
-               }
-               spin_unlock(&mp->m_perag_lock);
-               radix_tree_preload_end();
                /* first new pag is fully initialized */
                if (first_initialised == NULLAGNUMBER)
                        first_initialised = index;
@@ -247,7 +235,7 @@ out_free_pag:
 out_unwind_new_pags:
        /* unwind any prior newly initialized pags */
        for (index = first_initialised; index < agcount; index++) {
-               pag = radix_tree_delete(&mp->m_perag_tree, index);
+               pag = xa_erase(&mp->m_perags, index);
                if (!pag)
                        break;
                xfs_buf_hash_destroy(pag);
index 4adb6837439ac38fa600f0bd1f373634cef5bb78..05e34dffe28b66a5cd806f16b09711f4fda75265 100644 (file)
@@ -145,8 +145,7 @@ typedef struct xfs_mount {
        xfs_extlen_t            m_ag_prealloc_blocks; /* reserved ag blocks */
        uint                    m_alloc_set_aside; /* space we can't use */
        uint                    m_ag_max_usable; /* max space per AG */
-       struct radix_tree_root  m_perag_tree;   /* per-ag accounting info */
-       spinlock_t              m_perag_lock;   /* lock for m_perag_tree */
+       struct xarray           m_perags;       /* per-ag accounting info */
        struct mutex            m_growlock;     /* growfs mutex */
        int                     m_fixedfsid[2]; /* unchanged for life of FS */
        uint64_t                m_flags;        /* global mount flags */
index f9450235533cc4fcbeab7c3f5aba5f6a38cf1e99..ca6de89cd0c74ee54eb70ea626a0f886eb01448e 100644 (file)
@@ -1553,8 +1553,7 @@ xfs_mount_alloc(
        mp->m_super = sb;
        spin_lock_init(&mp->m_sb_lock);
        spin_lock_init(&mp->m_agirotor_lock);
-       INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);
-       spin_lock_init(&mp->m_perag_lock);
+       xa_init(&mp->m_perags);
        mutex_init(&mp->m_growlock);
        atomic_set(&mp->m_active_trans, 0);
        INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);