Commit 62a0d8b2 authored by Christoph Hellwig's avatar Christoph Hellwig

Merge

parents 46b11ba9 a9bc2790
......@@ -1299,7 +1299,6 @@ pagebuf_iorequest( /* start real I/O */
int status = 0;
int i, map_i, total_nr_pages, nr_pages;
struct bio *bio;
struct bio_vec *bvec;
int offset = pb->pb_offset;
int size = pb->pb_count_desired;
sector_t sector = pb->pb_bn;
......@@ -1335,13 +1334,8 @@ pagebuf_iorequest( /* start real I/O */
bio->bi_sector = sector - (offset >> BBSHIFT);
bio->bi_end_io = bio_end_io_pagebuf;
bio->bi_private = pb;
bio->bi_vcnt++;
bio->bi_size = PAGE_CACHE_SIZE;
bvec = bio->bi_io_vec;
bvec->bv_page = pb->pb_pages[0];
bvec->bv_len = PAGE_CACHE_SIZE;
bvec->bv_offset = 0;
bio_add_page(bio, pb->pb_pages[0], PAGE_CACHE_SIZE, 0);
atomic_inc(&pb->pb_io_remaining);
submit_bio(READ, bio);
......@@ -1389,9 +1383,7 @@ pagebuf_iorequest( /* start real I/O */
bio->bi_end_io = bio_end_io_pagebuf;
bio->bi_private = pb;
bvec = bio->bi_io_vec;
for (; size && nr_pages; nr_pages--, bvec++, map_i++) {
for (; size && nr_pages; nr_pages--, map_i++) {
int nbytes = PAGE_CACHE_SIZE - offset;
if (nbytes > size)
......
......@@ -379,7 +379,8 @@ xfs_buf_item_pin(
*/
void
xfs_buf_item_unpin(
xfs_buf_log_item_t *bip)
xfs_buf_log_item_t *bip,
int stale)
{
xfs_mount_t *mp;
xfs_buf_t *bp;
......@@ -396,7 +397,8 @@ xfs_buf_item_unpin(
freed = atomic_dec_and_test(&bip->bli_refcount);
mp = bip->bli_item.li_mountp;
xfs_bunpin(bp);
if (freed && (bip->bli_flags & XFS_BLI_STALE)) {
if (freed && stale) {
ASSERT(bip->bli_flags & XFS_BLI_STALE);
ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
ASSERT(XFS_BUF_ISSTALE(bp));
......@@ -418,7 +420,6 @@ xfs_buf_item_unpin(
ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL);
xfs_buf_relse(bp);
}
}
/*
......@@ -435,6 +436,7 @@ xfs_buf_item_unpin_remove(
{
xfs_buf_t *bp;
xfs_log_item_desc_t *lidp;
int stale = 0;
bp = bip->bli_buf;
/*
......@@ -454,6 +456,7 @@ xfs_buf_item_unpin_remove(
* will be able to bump up the refcount.
*/
lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) bip);
stale = lidp->lid_flags & XFS_LID_BUF_STALE;
xfs_trans_free_item(tp, lidp);
/*
* Since the transaction no longer refers to the buffer,
......@@ -462,7 +465,7 @@ xfs_buf_item_unpin_remove(
XFS_BUF_SET_FSPRIVATE2(bp, NULL);
}
xfs_buf_item_unpin(bip);
xfs_buf_item_unpin(bip, stale);
return;
}
......@@ -686,7 +689,7 @@ struct xfs_item_ops xfs_buf_item_ops = {
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
xfs_buf_item_format,
.iop_pin = (void(*)(xfs_log_item_t*))xfs_buf_item_pin,
.iop_unpin = (void(*)(xfs_log_item_t*))xfs_buf_item_unpin,
.iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_buf_item_unpin,
.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
xfs_buf_item_unpin_remove,
.iop_trylock = (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock,
......
......@@ -93,9 +93,11 @@ xfs_qm_dquot_logitem_pin(
* anyone in xfs_dqwait_unpin() if the count goes to 0. The
* dquot must have been previously pinned with a call to xfs_dqpin().
*/
/* ARGSUSED */
STATIC void
xfs_qm_dquot_logitem_unpin(
xfs_dq_logitem_t *logitem)
xfs_dq_logitem_t *logitem,
int stale)
{
unsigned long s;
xfs_dquot_t *dqp;
......@@ -116,7 +118,7 @@ xfs_qm_dquot_logitem_unpin_remove(
xfs_dq_logitem_t *logitem,
xfs_trans_t *tp)
{
xfs_qm_dquot_logitem_unpin(logitem);
xfs_qm_dquot_logitem_unpin(logitem, 0);
}
/*
......@@ -396,7 +398,8 @@ struct xfs_item_ops xfs_dquot_item_ops = {
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
xfs_qm_dquot_logitem_format,
.iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin,
.iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unpin,
.iop_unpin = (void(*)(xfs_log_item_t*, int))
xfs_qm_dquot_logitem_unpin,
.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
xfs_qm_dquot_logitem_unpin_remove,
.iop_trylock = (uint(*)(xfs_log_item_t*))
......@@ -492,7 +495,7 @@ xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t *qf)
*/
/*ARGSUSED*/
STATIC void
xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf)
xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale)
{
return;
}
......@@ -613,7 +616,8 @@ struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
xfs_qm_qoff_logitem_format,
.iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
.iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin,
.iop_unpin = (void(*)(xfs_log_item_t* ,int))
xfs_qm_qoff_logitem_unpin,
.iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
xfs_qm_qoff_logitem_unpin_remove,
.iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
......@@ -635,7 +639,8 @@ struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
xfs_qm_qoff_logitem_format,
.iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
.iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin,
.iop_unpin = (void(*)(xfs_log_item_t*, int))
xfs_qm_qoff_logitem_unpin,
.iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
xfs_qm_qoff_logitem_unpin_remove,
.iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
......
......@@ -105,7 +105,7 @@ xfs_efi_item_pin(xfs_efi_log_item_t *efip)
*/
/*ARGSUSED*/
STATIC void
xfs_efi_item_unpin(xfs_efi_log_item_t *efip)
xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
{
int nexts;
int size;
......@@ -280,7 +280,7 @@ struct xfs_item_ops xfs_efi_item_ops = {
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
xfs_efi_item_format,
.iop_pin = (void(*)(xfs_log_item_t*))xfs_efi_item_pin,
.iop_unpin = (void(*)(xfs_log_item_t*))xfs_efi_item_unpin,
.iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efi_item_unpin,
.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
xfs_efi_item_unpin_remove,
.iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efi_item_trylock,
......@@ -474,7 +474,7 @@ xfs_efd_item_pin(xfs_efd_log_item_t *efdp)
*/
/*ARGSUSED*/
STATIC void
xfs_efd_item_unpin(xfs_efd_log_item_t *efdp)
xfs_efd_item_unpin(xfs_efd_log_item_t *efdp, int stale)
{
return;
}
......@@ -607,7 +607,7 @@ struct xfs_item_ops xfs_efd_item_ops = {
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
xfs_efd_item_format,
.iop_pin = (void(*)(xfs_log_item_t*))xfs_efd_item_pin,
.iop_unpin = (void(*)(xfs_log_item_t*))xfs_efd_item_unpin,
.iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_efd_item_unpin,
.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
xfs_efd_item_unpin_remove,
.iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efd_item_trylock,
......
......@@ -534,9 +534,11 @@ xfs_inode_item_pin(
* item which was previously pinned with a call to xfs_inode_item_pin().
* Just call xfs_iunpin() on the inode to do this.
*/
/* ARGSUSED */
STATIC void
xfs_inode_item_unpin(
xfs_inode_log_item_t *iip)
xfs_inode_log_item_t *iip,
int stale)
{
xfs_iunpin(iip->ili_inode);
}
......@@ -880,7 +882,7 @@ struct xfs_item_ops xfs_inode_item_ops = {
.iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
xfs_inode_item_format,
.iop_pin = (void(*)(xfs_log_item_t*))xfs_inode_item_pin,
.iop_unpin = (void(*)(xfs_log_item_t*))xfs_inode_item_unpin,
.iop_unpin = (void(*)(xfs_log_item_t*, int))xfs_inode_item_unpin,
.iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
xfs_inode_item_unpin_remove,
.iop_trylock = (uint(*)(xfs_log_item_t*))xfs_inode_item_trylock,
......
......@@ -45,7 +45,7 @@
/* Local miscellaneous function prototypes */
STATIC int xlog_bdstrat_cb(struct xfs_buf *);
STATIC int xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket,
xfs_lsn_t *);
xlog_in_core_t **, xfs_lsn_t *);
STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp,
dev_t log_dev,
xfs_daddr_t blk_offset,
......@@ -55,7 +55,9 @@ STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
STATIC void xlog_unalloc_log(xlog_t *log);
STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
int nentries, xfs_log_ticket_t tic,
xfs_lsn_t *start_lsn, uint flags);
xfs_lsn_t *start_lsn,
xlog_in_core_t **commit_iclog,
uint flags);
/* local state machine functions */
STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int);
......@@ -70,10 +72,6 @@ STATIC int xlog_state_get_iclog_space(xlog_t *log,
xlog_ticket_t *ticket,
int *continued_write,
int *logoffsetp);
STATIC int xlog_state_lsn_is_synced(xlog_t *log,
xfs_lsn_t lsn,
xfs_log_callback_t *cb,
int *abortflg);
STATIC void xlog_state_put_ticket(xlog_t *log,
xlog_ticket_t *tic);
STATIC int xlog_state_release_iclog(xlog_t *log,
......@@ -254,6 +252,7 @@ xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
xfs_lsn_t
xfs_log_done(xfs_mount_t *mp,
xfs_log_ticket_t xtic,
void **iclog,
uint flags)
{
xlog_t *log = mp->m_log;
......@@ -271,7 +270,8 @@ xfs_log_done(xfs_mount_t *mp,
* If we get an error, just continue and give back the log ticket.
*/
(((ticket->t_flags & XLOG_TIC_INITED) == 0) &&
(xlog_commit_record(mp, ticket, &lsn)))) {
(xlog_commit_record(mp, ticket,
(xlog_in_core_t **)iclog, &lsn)))) {
lsn = (xfs_lsn_t) -1;
if (ticket->t_flags & XLOG_TIC_PERM_RESERV) {
flags |= XFS_LOG_REL_PERM_RESERV;
......@@ -354,21 +354,39 @@ xfs_log_force(xfs_mount_t *mp,
* been synced to disk, we add the callback to the callback list of the
* in-core log.
*/
void
int
xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
xfs_lsn_t lsn, /* lsn looking for */
void *iclog_hndl, /* iclog to hang callback off */
xfs_log_callback_t *cb)
{
xlog_t *log = mp->m_log;
int abortflg;
xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
int abortflg, spl;
#if defined(DEBUG) || defined(XLOG_NOLOG)
if (! xlog_debug && xlog_devt == log->l_dev)
return;
return 0;
#endif
cb->cb_next = 0;
if (xlog_state_lsn_is_synced(log, lsn, cb, &abortflg))
spl = LOG_LOCK(log);
abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
if (!abortflg) {
ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) ||
(iclog->ic_state == XLOG_STATE_WANT_SYNC));
cb->cb_next = 0;
*(iclog->ic_callback_tail) = cb;
iclog->ic_callback_tail = &(cb->cb_next);
}
LOG_UNLOCK(log, spl);
if (!abortflg) {
if (xlog_state_release_iclog(log, iclog)) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
return EIO;
}
} else {
cb->cb_func(cb->cb_arg, abortflg);
}
return 0;
} /* xfs_log_notify */
......@@ -611,7 +629,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
/* remove inited flag */
((xlog_ticket_t *)tic)->t_flags = 0;
error = xlog_write(mp, reg, 1, tic, &lsn,
XLOG_UNMOUNT_TRANS);
NULL, XLOG_UNMOUNT_TRANS);
/*
* At this point, we're umounting anyway,
* so there's no point in transitioning log state
......@@ -717,7 +735,7 @@ xfs_log_write(xfs_mount_t * mp,
if (XLOG_FORCED_SHUTDOWN(log))
return XFS_ERROR(EIO);
if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, 0))) {
if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
}
return (error);
......@@ -1259,6 +1277,7 @@ xlog_alloc_log(xfs_mount_t *mp,
STATIC int
xlog_commit_record(xfs_mount_t *mp,
xlog_ticket_t *ticket,
xlog_in_core_t **iclog,
xfs_lsn_t *commitlsnp)
{
int error;
......@@ -1267,8 +1286,9 @@ xlog_commit_record(xfs_mount_t *mp,
reg[0].i_addr = 0;
reg[0].i_len = 0;
ASSERT_ALWAYS(iclog);
if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
XLOG_COMMIT_TRANS))) {
iclog, XLOG_COMMIT_TRANS))) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
}
return (error);
......@@ -1614,6 +1634,7 @@ xlog_write(xfs_mount_t * mp,
int nentries,
xfs_log_ticket_t tic,
xfs_lsn_t *start_lsn,
xlog_in_core_t **commit_iclog,
uint flags)
{
xlog_t *log = mp->m_log;
......@@ -1776,7 +1797,10 @@ xlog_write(xfs_mount_t * mp,
if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
xlog_state_want_sync(log, iclog);
if ((error = xlog_state_release_iclog(log, iclog)))
if (commit_iclog) {
ASSERT(flags & XLOG_COMMIT_TRANS);
*commit_iclog = iclog;
} else if ((error = xlog_state_release_iclog(log, iclog)))
return (error);
if (index == nentries)
return 0; /* we are done */
......@@ -1788,6 +1812,11 @@ xlog_write(xfs_mount_t * mp,
} /* for (index = 0; index < nentries; ) */
ASSERT(len == 0);
if (commit_iclog) {
ASSERT(flags & XLOG_COMMIT_TRANS);
*commit_iclog = iclog;
return 0;
}
return (xlog_state_release_iclog(log, iclog));
} /* xlog_write */
......@@ -2060,6 +2089,12 @@ xlog_state_do_callback(
if (!(iclog->ic_state & XLOG_STATE_IOERROR))
iclog->ic_state = XLOG_STATE_DIRTY;
/*
* Transition from DIRTY to ACTIVE if applicable.
* NOP if STATE_IOERROR.
*/
xlog_state_clean_log(log);
/* wake up threads waiting in xfs_log_force() */
sv_broadcast(&iclog->ic_forcesema);
......@@ -2098,12 +2133,6 @@ xlog_state_do_callback(
}
#endif
/*
* Transition from DIRTY to ACTIVE if applicable. NOP if
* STATE_IOERROR.
*/
xlog_state_clean_log(log);
if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) {
flushcnt = log->l_flushcnt;
log->l_flushcnt = 0;
......@@ -2654,52 +2683,6 @@ xlog_ungrant_log_space(xlog_t *log,
} /* xlog_ungrant_log_space */
/*
* If the lsn is not found or the iclog with the lsn is in the callback
* state, we need to call the function directly. This is done outside
* this function's scope. Otherwise, we insert the callback at the end
* of the iclog's callback list.
*/
int
xlog_state_lsn_is_synced(xlog_t *log,
xfs_lsn_t lsn,
xfs_log_callback_t *cb,
int *abortflg)
{
xlog_in_core_t *iclog;
SPLDECL(s);
int lsn_is_synced = 1;
*abortflg = 0;
s = LOG_LOCK(log);
iclog = log->l_iclog;
do {
if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) != lsn) {
iclog = iclog->ic_next;
continue;
} else {
if (iclog->ic_state & XLOG_STATE_DIRTY) /* call it*/
break;
if (iclog->ic_state & XLOG_STATE_IOERROR) {
*abortflg = XFS_LI_ABORTED;
break;
}
/* insert callback onto end of list */
cb->cb_next = 0;
*(iclog->ic_callback_tail) = cb;
iclog->ic_callback_tail = &(cb->cb_next);
lsn_is_synced = 0;
break;
}
} while (iclog != log->l_iclog);
LOG_UNLOCK(log, s);
return lsn_is_synced;
} /* xlog_state_lsn_is_synced */
/*
* Atomically put back used ticket.
*/
......
......@@ -148,6 +148,7 @@ typedef struct xfs_log_callback {
struct xfs_mount;
xfs_lsn_t xfs_log_done(struct xfs_mount *mp,
xfs_log_ticket_t ticket,
void **iclog,
uint flags);
int xfs_log_force(struct xfs_mount *mp,
xfs_lsn_t lsn,
......@@ -160,8 +161,8 @@ int xfs_log_mount(struct xfs_mount *mp,
int xfs_log_mount_finish(struct xfs_mount *mp, int);
void xfs_log_move_tail(struct xfs_mount *mp,
xfs_lsn_t tail_lsn);
void xfs_log_notify(struct xfs_mount *mp,
xfs_lsn_t lsn,
int xfs_log_notify(struct xfs_mount *mp,
void *iclog,
xfs_log_callback_t *callback_entry);
int xfs_log_reserve(struct xfs_mount *mp,
int length,
......
......@@ -285,7 +285,7 @@ xfs_trans_reserve(
} else {
log_flags = 0;
}
xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags);
xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);
tp->t_ticket = NULL;
tp->t_log_res = 0;
tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES;
......@@ -669,6 +669,7 @@ xfs_trans_commit(
#if defined(XLOG_NOLOG) || defined(DEBUG)
static xfs_lsn_t trans_lsn = 1;
#endif
void *commit_iclog;
int shutdown;
commit_lsn = -1;
......@@ -706,7 +707,8 @@ xfs_trans_commit(
xfs_trans_unreserve_and_mod_dquots(tp);
}
if (tp->t_ticket) {
commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags);
commit_lsn = xfs_log_done(mp, tp->t_ticket,
NULL, log_flags);
if (commit_lsn == -1 && !shutdown)
shutdown = XFS_ERROR(EIO);
}
......@@ -773,7 +775,7 @@ xfs_trans_commit(
#if defined(XLOG_NOLOG) || defined(DEBUG)
if (xlog_debug) {
commit_lsn = xfs_log_done(mp, tp->t_ticket,
log_flags);
&commit_iclog, log_flags);
} else {
commit_lsn = 0;
tp->t_lsn = trans_lsn++;
......@@ -785,7 +787,7 @@ xfs_trans_commit(
* any time. However, all the items associated with the transaction
* are still locked and pinned in memory.
*/
commit_lsn = xfs_log_done(mp, tp->t_ticket, log_flags);
commit_lsn = xfs_log_done(mp, tp->t_ticket, &commit_iclog, log_flags);
#endif
tp->t_commit_lsn = commit_lsn;
......@@ -845,21 +847,28 @@ xfs_trans_commit(
if (xlog_debug) {
tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed;
tp->t_logcb.cb_arg = tp;
xfs_log_notify(mp, commit_lsn, &(tp->t_logcb));
error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
} else {
xfs_trans_committed(tp, 0);
}
#else
tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed;
tp->t_logcb.cb_arg = tp;
xfs_log_notify(mp, commit_lsn, &(tp->t_logcb));
/* We need to pass the iclog buffer which was used for the
* transaction commit record into this function, attach
* the callback to it, and then release it. This will guarantee
* that we do callbacks on the transaction in the correct order.
*/
error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb));
#endif
/*
* If the transaction needs to be synchronous, then force the
* log out now and wait for it.
*/
if (sync) {
error = xfs_log_force(mp, commit_lsn,
if (!error)
error = xfs_log_force(mp, commit_lsn,
XFS_LOG_FORCE | XFS_LOG_SYNC);
XFS_STATS_INC(xfsstats.xs_trans_sync);
} else {
......@@ -1070,7 +1079,7 @@ xfs_trans_cancel(
} else {
log_flags = 0;
}
xfs_log_done(tp->t_mountp, tp->t_ticket, log_flags);
xfs_log_done(tp->t_mountp, tp->t_ticket, NULL, log_flags);
}
xfs_trans_free_items(tp, flags);
xfs_trans_free_busy(tp);
......@@ -1262,8 +1271,11 @@ xfs_trans_chunk_committed(
/*
* Now that we've repositioned the item in the AIL,
* unpin it so it can be flushed.
* unpin it so it can be flushed. Pass information
* about buffer stale state down from the log item
* flags, if anyone else stales the buffer we do not
* want to pay any attention to it.
*/
IOP_UNPIN(lip);
IOP_UNPIN(lip, lidp->lid_flags & XFS_LID_BUF_STALE);
}
}
......@@ -170,7 +170,7 @@ typedef struct xfs_item_ops {
uint (*iop_size)(xfs_log_item_t *);
void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
void (*iop_pin)(xfs_log_item_t *);
void (*iop_unpin)(xfs_log_item_t *);
void (*iop_unpin)(xfs_log_item_t *, int);
void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *);
uint (*iop_trylock)(xfs_log_item_t *);
void (*iop_unlock)(xfs_log_item_t *);
......@@ -184,7 +184,7 @@ typedef struct xfs_item_ops {
#define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip)
#define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp)
#define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip)
#define IOP_UNPIN(ip) (*(ip)->li_ops->iop_unpin)(ip)
#define IOP_UNPIN(ip, flags) (*(ip)->li_ops->iop_unpin)(ip, flags)
#define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp)
#define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip)
#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip)
......@@ -222,6 +222,7 @@ typedef struct xfs_log_item_desc {
#define XFS_LID_DIRTY 0x1
#define XFS_LID_PINNED 0x2
#define XFS_LID_SYNC_UNLOCK 0x4
#define XFS_LID_BUF_STALE 0x8
/*
* This structure is used to maintain a chunk list of log_item_desc
......
......@@ -796,6 +796,7 @@ xfs_trans_log_buf(xfs_trans_t *tp,
tp->t_flags |= XFS_TRANS_DIRTY;
lidp->lid_flags |= XFS_LID_DIRTY;
lidp->lid_flags &= ~XFS_LID_BUF_STALE;
bip->bli_flags |= XFS_BLI_LOGGED;
xfs_buf_item_log(bip, first, last);
xfs_buf_item_trace("BLOG", bip);
......@@ -882,7 +883,7 @@ xfs_trans_binval(
bip->bli_format.blf_flags |= XFS_BLI_CANCEL;
memset((char *)(bip->bli_format.blf_data_map), 0,
(bip->bli_format.blf_map_size * sizeof(uint)));
lidp->lid_flags |= XFS_LID_DIRTY;
lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE;
tp->t_flags |= XFS_TRANS_DIRTY;
xfs_buftrace("XFS_BINVAL", bp);
xfs_buf_item_trace("BINVAL", bip);
......
......@@ -873,7 +873,6 @@ xfs_syncsub(
boolean_t mount_locked;
boolean_t vnode_refed;
int preempt;
int do_mmap_flush;
xfs_dinode_t *dip;
xfs_buf_log_item_t *bip;
xfs_iptr_t *ipointer;
......@@ -944,8 +943,6 @@ xfs_syncsub(
fflag = XFS_B_DELWRI;
if (flags & SYNC_WAIT)
fflag = 0; /* synchronous overrides all */
do_mmap_flush = (flags & (SYNC_DELWRI|SYNC_BDFLUSH)) !=
(SYNC_DELWRI|SYNC_BDFLUSH);
base_lock_flags = XFS_ILOCK_SHARED;
if (flags & (SYNC_DELWRI | SYNC_CLOSE)) {
......@@ -1177,12 +1174,8 @@ xfs_syncsub(
* across calls to the buffer cache.
*/
xfs_iunlock(ip, XFS_ILOCK_SHARED);
if (do_mmap_flush) {
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1,
fflag, FI_NONE, error);
} else {
filemap_fdatawrite(LINVFS_GET_IP(vp)->i_mapping);
}
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1,
fflag, FI_NONE, error);
xfs_ilock(ip, XFS_ILOCK_SHARED);
}
......
......@@ -5248,6 +5248,7 @@ xfsidbg_xtp(xfs_trans_t *tp)
"dirty", /* 0x1 */
"pinned", /* 0x2 */
"sync unlock", /* 0x4 */
"buf stale", /* 0x8 */
0
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment