Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 198362
b: refs/heads/master
c: ccf7c23
h: refs/heads/master
v: v3
  • Loading branch information
Dave Chinner authored and Alex Elder committed May 24, 2010
1 parent c9ec4c5 commit 4170565
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: df806158b0f6eb24247773b4a19b8b59d7217e59
refs/heads/master: ccf7c23fc129e75ef60e6f59f60a485b7a056598
14 changes: 14 additions & 0 deletions trunk/fs/xfs/xfs_buf_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,20 @@ xfs_buf_item_format(
vecp++;
nvecs = 1;

/*
* If it is an inode buffer, transfer the in-memory state to the
* format flags and clear the in-memory state. We do not transfer
* this state if the inode buffer allocation has not yet been committed
* to the log as setting the XFS_BLI_INODE_BUF flag will prevent
* correct replay of the inode allocation.
*/
if (bip->bli_flags & XFS_BLI_INODE_BUF) {
if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
xfs_log_item_in_current_chkpt(&bip->bli_item)))
bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF;
bip->bli_flags &= ~XFS_BLI_INODE_BUF;
}

if (bip->bli_flags & XFS_BLI_STALE) {
/*
* The buffer is stale, so all we need to log
Expand Down
4 changes: 3 additions & 1 deletion trunk/fs/xfs/xfs_buf_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,16 @@ typedef struct xfs_buf_log_format {
#define XFS_BLI_LOGGED 0x08
#define XFS_BLI_INODE_ALLOC_BUF 0x10
#define XFS_BLI_STALE_INODE 0x20
#define XFS_BLI_INODE_BUF 0x40

#define XFS_BLI_FLAGS \
{ XFS_BLI_HOLD, "HOLD" }, \
{ XFS_BLI_DIRTY, "DIRTY" }, \
{ XFS_BLI_STALE, "STALE" }, \
{ XFS_BLI_LOGGED, "LOGGED" }, \
{ XFS_BLI_INODE_ALLOC_BUF, "INODE_ALLOC" }, \
{ XFS_BLI_STALE_INODE, "STALE_INODE" }
{ XFS_BLI_STALE_INODE, "STALE_INODE" }, \
{ XFS_BLI_INODE_BUF, "INODE_BUF" }


#ifdef __KERNEL__
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/xfs/xfs_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ xlog_tid_t xfs_log_get_trans_ident(struct xfs_trans *tp);
int xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
struct xfs_log_vec *log_vector,
xfs_lsn_t *commit_lsn, int flags);
bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip);

#endif

Expand Down
45 changes: 45 additions & 0 deletions trunk/fs/xfs/xfs_log_cil.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,15 @@ xlog_cil_insert(
list_move_tail(&item->li_cil, &cil->xc_cil);
ctx->nvecs += diff_iovecs;

/*
* If this is the first time the item is being committed to the CIL,
* store the sequence number on the log item so we can tell
* in future commits whether this is the first checkpoint the item is
* being committed into.
*/
if (!item->li_seq)
item->li_seq = ctx->sequence;

/*
* Now transfer enough transaction reservation to the context ticket
* for the checkpoint. The context ticket is special - the unit
Expand Down Expand Up @@ -325,6 +334,10 @@ xlog_cil_free_logvec(
* For more specific information about the order of operations in
* xfs_log_commit_cil() please refer to the comments in
* xfs_trans_commit_iclog().
*
* Called with the context lock already held in read mode to lock out
* background commit, returns without it held once background commits are
* allowed again.
*/
int
xfs_log_commit_cil(
Expand Down Expand Up @@ -678,3 +691,35 @@ xlog_cil_push_lsn(
spin_unlock(&cil->xc_cil_lock);
return commit_lsn;
}

/*
* Check if the current log item was first committed in this sequence.
* We can't rely on just the log item being in the CIL, we have to check
* the recorded commit sequence number.
*
* Note: for this to be used in a non-racy manner, it has to be called with
* CIL flushing locked out. As a result, it should only be used during the
* transaction commit process when deciding what to format into the item.
*/
bool
xfs_log_item_in_current_chkpt(
struct xfs_log_item *lip)
{
struct xfs_cil_ctx *ctx;

if (!(lip->li_mountp->m_flags & XFS_MOUNT_DELAYLOG))
return false;
if (list_empty(&lip->li_cil))
return false;

ctx = lip->li_mountp->m_log->l_cilp->xc_ctx;

/*
* li_seq is written on the first commit of a log item to record the
* first checkpoint it is written to. Hence if it is different to the
* current sequence, we're in a new checkpoint.
*/
if (XFS_LSN_CMP(lip->li_seq, ctx->sequence) != 0)
return false;
return true;
}
1 change: 1 addition & 0 deletions trunk/fs/xfs/xfs_trans.h
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@ typedef struct xfs_log_item {
/* delayed logging */
struct list_head li_cil; /* CIL pointers */
struct xfs_log_vec *li_lv; /* active log vector */
xfs_lsn_t li_seq; /* CIL commit seq */
} xfs_log_item_t;

#define XFS_LI_IN_AIL 0x1
Expand Down
20 changes: 10 additions & 10 deletions trunk/fs/xfs/xfs_trans_buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ xfs_trans_binval(
XFS_BUF_UNDELAYWRITE(bp);
XFS_BUF_STALE(bp);
bip->bli_flags |= XFS_BLI_STALE;
bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_DIRTY);
bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY);
bip->bli_format.blf_flags &= ~XFS_BLF_INODE_BUF;
bip->bli_format.blf_flags |= XFS_BLF_CANCEL;
memset((char *)(bip->bli_format.blf_data_map), 0,
Expand All @@ -802,16 +802,16 @@ xfs_trans_binval(
}

/*
* This call is used to indicate that the buffer contains on-disk
* inodes which must be handled specially during recovery. They
* require special handling because only the di_next_unlinked from
* the inodes in the buffer should be recovered. The rest of the
* data in the buffer is logged via the inodes themselves.
* This call is used to indicate that the buffer contains on-disk inodes which
* must be handled specially during recovery. They require special handling
* because only the di_next_unlinked from the inodes in the buffer should be
* recovered. The rest of the data in the buffer is logged via the inodes
* themselves.
*
* All we do is set the XFS_BLI_INODE_BUF flag in the buffer's log
* format structure so that we'll know what to do at recovery time.
* All we do is set the XFS_BLI_INODE_BUF flag in the items flags so it can be
* transferred to the buffer's log format structure so that we'll know what to
* do at recovery time.
*/
/* ARGSUSED */
void
xfs_trans_inode_buf(
xfs_trans_t *tp,
Expand All @@ -826,7 +826,7 @@ xfs_trans_inode_buf(
bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
ASSERT(atomic_read(&bip->bli_refcount) > 0);

bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF;
bip->bli_flags |= XFS_BLI_INODE_BUF;
}

/*
Expand Down

0 comments on commit 4170565

Please sign in to comment.