mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-23 11:04:44 +08:00
[XFS] Current usage of buftarg flags is incorrect.
The {test,set,clear}_bit() operations take a bit index for the bit to operate on. The XBT_* flags are defined as bit fields which is incorrect, not to mention the way the bit fields are enumerated is broken too. This was only working by chance. Fix the definitions of the flags and make the code using them use the {test,set,clear}_bit() operations correctly. SGI-PV: 958639 SGI-Modid: xfs-linux-melb:xfs-kern:27565a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
This commit is contained in:
parent
dc74eaad8c
commit
5e6a07dfe4
@ -1687,14 +1687,15 @@ STATIC int
|
|||||||
xfs_buf_delwri_split(
|
xfs_buf_delwri_split(
|
||||||
xfs_buftarg_t *target,
|
xfs_buftarg_t *target,
|
||||||
struct list_head *list,
|
struct list_head *list,
|
||||||
unsigned long age,
|
unsigned long age)
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
xfs_buf_t *bp, *n;
|
xfs_buf_t *bp, *n;
|
||||||
struct list_head *dwq = &target->bt_delwrite_queue;
|
struct list_head *dwq = &target->bt_delwrite_queue;
|
||||||
spinlock_t *dwlk = &target->bt_delwrite_lock;
|
spinlock_t *dwlk = &target->bt_delwrite_lock;
|
||||||
int skipped = 0;
|
int skipped = 0;
|
||||||
|
int force;
|
||||||
|
|
||||||
|
force = test_and_clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
|
||||||
INIT_LIST_HEAD(list);
|
INIT_LIST_HEAD(list);
|
||||||
spin_lock(dwlk);
|
spin_lock(dwlk);
|
||||||
list_for_each_entry_safe(bp, n, dwq, b_list) {
|
list_for_each_entry_safe(bp, n, dwq, b_list) {
|
||||||
@ -1702,7 +1703,7 @@ xfs_buf_delwri_split(
|
|||||||
ASSERT(bp->b_flags & XBF_DELWRI);
|
ASSERT(bp->b_flags & XBF_DELWRI);
|
||||||
|
|
||||||
if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) {
|
if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) {
|
||||||
if (!(flags & XBT_FORCE_FLUSH) &&
|
if (!force &&
|
||||||
time_before(jiffies, bp->b_queuetime + age)) {
|
time_before(jiffies, bp->b_queuetime + age)) {
|
||||||
xfs_buf_unlock(bp);
|
xfs_buf_unlock(bp);
|
||||||
break;
|
break;
|
||||||
@ -1744,9 +1745,7 @@ xfsbufd(
|
|||||||
xfs_buf_timer_centisecs * msecs_to_jiffies(10));
|
xfs_buf_timer_centisecs * msecs_to_jiffies(10));
|
||||||
|
|
||||||
xfs_buf_delwri_split(target, &tmp,
|
xfs_buf_delwri_split(target, &tmp,
|
||||||
xfs_buf_age_centisecs * msecs_to_jiffies(10),
|
xfs_buf_age_centisecs * msecs_to_jiffies(10));
|
||||||
test_bit(XBT_FORCE_FLUSH, &target->bt_flags)
|
|
||||||
? XBT_FORCE_FLUSH : 0);
|
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
while (!list_empty(&tmp)) {
|
while (!list_empty(&tmp)) {
|
||||||
@ -1763,7 +1762,6 @@ xfsbufd(
|
|||||||
if (count)
|
if (count)
|
||||||
blk_run_address_space(target->bt_mapping);
|
blk_run_address_space(target->bt_mapping);
|
||||||
|
|
||||||
clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
|
|
||||||
} while (!kthread_should_stop());
|
} while (!kthread_should_stop());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1786,7 +1784,8 @@ xfs_flush_buftarg(
|
|||||||
xfs_buf_runall_queues(xfsdatad_workqueue);
|
xfs_buf_runall_queues(xfsdatad_workqueue);
|
||||||
xfs_buf_runall_queues(xfslogd_workqueue);
|
xfs_buf_runall_queues(xfslogd_workqueue);
|
||||||
|
|
||||||
pincount = xfs_buf_delwri_split(target, &tmp, 0, XBT_FORCE_FLUSH);
|
set_bit(XBT_FORCE_FLUSH, &target->bt_flags);
|
||||||
|
pincount = xfs_buf_delwri_split(target, &tmp, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dropped the delayed write list lock, now walk the temporary list
|
* Dropped the delayed write list lock, now walk the temporary list
|
||||||
|
@ -69,8 +69,8 @@ typedef enum {
|
|||||||
} xfs_buf_flags_t;
|
} xfs_buf_flags_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XBT_FORCE_SLEEP = (0 << 1),
|
XBT_FORCE_SLEEP = 0,
|
||||||
XBT_FORCE_FLUSH = (1 << 1),
|
XBT_FORCE_FLUSH = 1,
|
||||||
} xfs_buftarg_flags_t;
|
} xfs_buftarg_flags_t;
|
||||||
|
|
||||||
typedef struct xfs_bufhash {
|
typedef struct xfs_bufhash {
|
||||||
|
Loading…
Reference in New Issue
Block a user