Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux

Resolved conflicts:
  fs/xfs/xfs_trans_priv.h:
    - deleted struct xfs_ail field xa_flags
    - kept field xa_log_flush in struct xfs_ail
  fs/xfs/xfs_trans_ail.c:
    - in xfsaild_push(), in XFS_ITEM_PUSHBUF case, replaced
      "flush_log = 1" with "ailp->xa_log_flush++"

Signed-off-by: Alex Elder <aelder@sgi.com>
This commit is contained in:
Alex Elder
2011-10-17 15:42:02 -05:00
101 changed files with 469 additions and 336 deletions

View File

@@ -28,8 +28,6 @@
#include "xfs_trans_priv.h"
#include "xfs_error.h"
struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
#ifdef DEBUG
/*
* Check that the list is sorted as it should be.
@@ -356,16 +354,10 @@ xfs_ail_delete(
xfs_trans_ail_cursor_clear(ailp, lip);
}
/*
* xfs_ail_worker does the work of pushing on the AIL. It will requeue itself
* to run at a later time if there is more work to do to complete the push.
*/
STATIC void
xfs_ail_worker(
struct work_struct *work)
static long
xfsaild_push(
struct xfs_ail *ailp)
{
struct xfs_ail *ailp = container_of(to_delayed_work(work),
struct xfs_ail, xa_work);
xfs_mount_t *mp = ailp->xa_mount;
struct xfs_ail_cursor cur;
xfs_log_item_t *lip;
@@ -439,8 +431,13 @@ xfs_ail_worker(
case XFS_ITEM_PUSHBUF:
XFS_STATS_INC(xs_push_ail_pushbuf);
IOP_PUSHBUF(lip);
ailp->xa_last_pushed_lsn = lsn;
if (!IOP_PUSHBUF(lip)) {
stuck++;
flush_log = 1;
} else {
ailp->xa_last_pushed_lsn = lsn;
}
push_xfsbufd = 1;
break;
@@ -452,7 +449,6 @@ xfs_ail_worker(
case XFS_ITEM_LOCKED:
XFS_STATS_INC(xs_push_ail_locked);
ailp->xa_last_pushed_lsn = lsn;
stuck++;
break;
@@ -504,20 +500,6 @@ out_done:
ailp->xa_last_pushed_lsn = 0;
ailp->xa_log_flush = 0;
/*
* We clear the XFS_AIL_PUSHING_BIT first before checking
* whether the target has changed. If the target has changed,
* this pushes the requeue race directly onto the result of the
* atomic test/set bit, so we are guaranteed that either the
* the pusher that changed the target or ourselves will requeue
* the work (but not both).
*/
clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags);
smp_rmb();
if (XFS_LSN_CMP(ailp->xa_target, target) == 0 ||
test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
return;
tout = 50;
} else if (XFS_LSN_CMP(lsn, target) >= 0) {
/*
@@ -544,9 +526,30 @@ out_done:
ailp->xa_last_pushed_lsn = 0;
}
/* There is more to do, requeue us. */
queue_delayed_work(xfs_syncd_wq, &ailp->xa_work,
msecs_to_jiffies(tout));
return tout;
}
static int
xfsaild(
void *data)
{
struct xfs_ail *ailp = data;
long tout = 0; /* milliseconds */
while (!kthread_should_stop()) {
if (tout && tout <= 20)
__set_current_state(TASK_KILLABLE);
else
__set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(tout ?
msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT);
try_to_freeze();
tout = xfsaild_push(ailp);
}
return 0;
}
/*
@@ -581,8 +584,9 @@ xfs_ail_push(
*/
smp_wmb();
xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn);
if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0);
smp_wmb();
wake_up_process(ailp->xa_task);
}
/*
@@ -820,9 +824,18 @@ xfs_trans_ail_init(
INIT_LIST_HEAD(&ailp->xa_ail);
INIT_LIST_HEAD(&ailp->xa_cursors);
spin_lock_init(&ailp->xa_lock);
INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker);
ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
ailp->xa_mount->m_fsname);
if (IS_ERR(ailp->xa_task))
goto out_free_ailp;
mp->m_ail = ailp;
return 0;
out_free_ailp:
kmem_free(ailp);
return ENOMEM;
}
void
@@ -831,6 +844,6 @@ xfs_trans_ail_destroy(
{
struct xfs_ail *ailp = mp->m_ail;
cancel_delayed_work_sync(&ailp->xa_work);
kthread_stop(ailp->xa_task);
kmem_free(ailp);
}