]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
xfs: refactor the ioend merging code
authorChristoph Hellwig <hch@lst.de>
Thu, 17 Oct 2019 20:12:07 +0000 (13:12 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 21 Oct 2019 15:51:59 +0000 (08:51 -0700)
Introduce two nicely abstracted helper, which can be moved to the iomap
code later.  Also use list_first_entry_or_null to simplify the code a
bit.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-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/xfs_aops.c

index 91899de2be09e4ad595c15e26258d56b8eb18b48..c29ef69d1e513aff73f3964aced67ba9f349be60 100644 (file)
@@ -116,6 +116,22 @@ xfs_destroy_ioend(
        }
 }
 
+static void
+xfs_destroy_ioends(
+       struct xfs_ioend        *ioend,
+       int                     error)
+{
+       struct list_head        tmp;
+
+       list_replace_init(&ioend->io_list, &tmp);
+       xfs_destroy_ioend(ioend, error);
+       while ((ioend = list_first_entry_or_null(&tmp, struct xfs_ioend,
+                       io_list))) {
+               list_del_init(&ioend->io_list);
+               xfs_destroy_ioend(ioend, error);
+       }
+}
+
 /*
  * Fast and loose check if this write could update the on-disk inode size.
  */
@@ -230,7 +246,6 @@ STATIC void
 xfs_end_ioend(
        struct xfs_ioend        *ioend)
 {
-       struct list_head        ioend_list;
        struct xfs_inode        *ip = XFS_I(ioend->io_inode);
        xfs_off_t               offset = ioend->io_offset;
        size_t                  size = ioend->io_size;
@@ -275,16 +290,7 @@ xfs_end_ioend(
 done:
        if (ioend->io_append_trans)
                error = xfs_setfilesize_ioend(ioend, error);
-       list_replace_init(&ioend->io_list, &ioend_list);
-       xfs_destroy_ioend(ioend, error);
-
-       while (!list_empty(&ioend_list)) {
-               ioend = list_first_entry(&ioend_list, struct xfs_ioend,
-                               io_list);
-               list_del_init(&ioend->io_list);
-               xfs_destroy_ioend(ioend, error);
-       }
-
+       xfs_destroy_ioends(ioend, error);
        memalloc_nofs_restore(nofs_flag);
 }
 
@@ -333,17 +339,18 @@ xfs_ioend_try_merge(
        struct xfs_ioend        *ioend,
        struct list_head        *more_ioends)
 {
-       struct xfs_ioend        *next_ioend;
+       struct xfs_ioend        *next;
+
+       INIT_LIST_HEAD(&ioend->io_list);
 
-       while (!list_empty(more_ioends)) {
-               next_ioend = list_first_entry(more_ioends, struct xfs_ioend,
-                               io_list);
-               if (!xfs_ioend_can_merge(ioend, next_ioend))
+       while ((next = list_first_entry_or_null(more_ioends, struct xfs_ioend,
+                       io_list))) {
+               if (!xfs_ioend_can_merge(ioend, next))
                        break;
-               list_move_tail(&next_ioend->io_list, &ioend->io_list);
-               ioend->io_size += next_ioend->io_size;
-               if (next_ioend->io_append_trans)
-                       xfs_ioend_merge_append_transactions(ioend, next_ioend);
+               list_move_tail(&next->io_list, &ioend->io_list);
+               ioend->io_size += next->io_size;
+               if (next->io_append_trans)
+                       xfs_ioend_merge_append_transactions(ioend, next);
        }
 }
 
@@ -366,29 +373,33 @@ xfs_ioend_compare(
        return 0;
 }
 
+static void
+xfs_sort_ioends(
+       struct list_head        *ioend_list)
+{
+       list_sort(NULL, ioend_list, xfs_ioend_compare);
+}
+
 /* Finish all pending io completions. */
 void
 xfs_end_io(
        struct work_struct      *work)
 {
-       struct xfs_inode        *ip;
+       struct xfs_inode        *ip =
+               container_of(work, struct xfs_inode, i_ioend_work);
        struct xfs_ioend        *ioend;
-       struct list_head        completion_list;
+       struct list_head        tmp;
        unsigned long           flags;
 
-       ip = container_of(work, struct xfs_inode, i_ioend_work);
-
        spin_lock_irqsave(&ip->i_ioend_lock, flags);
-       list_replace_init(&ip->i_ioend_list, &completion_list);
+       list_replace_init(&ip->i_ioend_list, &tmp);
        spin_unlock_irqrestore(&ip->i_ioend_lock, flags);
 
-       list_sort(NULL, &completion_list, xfs_ioend_compare);
-
-       while (!list_empty(&completion_list)) {
-               ioend = list_first_entry(&completion_list, struct xfs_ioend,
-                               io_list);
+       xfs_sort_ioends(&tmp);
+       while ((ioend = list_first_entry_or_null(&tmp, struct xfs_ioend,
+                       io_list))) {
                list_del_init(&ioend->io_list);
-               xfs_ioend_try_merge(ioend, &completion_list);
+               xfs_ioend_try_merge(ioend, &tmp);
                xfs_end_ioend(ioend);
        }
 }