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

Merge

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