Loading fs/xfs/xfs_buf_item.h +0 −11 Original line number Diff line number Diff line Loading @@ -105,17 +105,6 @@ typedef struct xfs_buf_log_item { xfs_buf_log_format_t bli_format; /* in-log header */ } xfs_buf_log_item_t; /* * This structure is used during recovery to record the buf log * items which have been canceled and should not be replayed. */ typedef struct xfs_buf_cancel { xfs_daddr_t bc_blkno; uint bc_len; int bc_refcount; struct xfs_buf_cancel *bc_next; } xfs_buf_cancel_t; void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); void xfs_buf_item_relse(struct xfs_buf *); void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint); Loading fs/xfs/xfs_log_priv.h +4 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ struct xfs_buf; struct log; struct xlog_ticket; struct xfs_buf_cancel; struct xfs_mount; /* Loading Loading @@ -491,7 +490,7 @@ typedef struct log { struct xfs_buftarg *l_targ; /* buftarg of log */ uint l_flags; uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ struct xfs_buf_cancel **l_buf_cancel_table; struct list_head *l_buf_cancel_table; int l_iclog_hsize; /* size of iclog header */ int l_iclog_heads; /* # of iclog header sectors */ uint l_sectBBsize; /* sector size in BBs (2^n) */ Loading Loading @@ -534,6 +533,9 @@ typedef struct log { } xlog_t; #define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE)) #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) /* common routines */ Loading fs/xfs/xfs_log_recover.c +61 −98 Original line number Diff line number Diff line Loading @@ -52,6 +52,17 @@ STATIC void xlog_recover_check_summary(xlog_t *); #define xlog_recover_check_summary(log) #endif /* * This structure is used during recovery to record the buf log items which * have been canceled and should not be replayed. */ struct xfs_buf_cancel { xfs_daddr_t bc_blkno; uint bc_len; int bc_refcount; struct list_head bc_list; }; /* * Sector aligned buffer routines for buffer create/read/write/access */ Loading Loading @@ -1607,15 +1618,11 @@ xlog_recover_reorder_trans( */ STATIC void xlog_recover_do_buffer_pass1( xlog_t *log, struct log *log, xfs_buf_log_format_t *buf_f) { xfs_buf_cancel_t *bcp; xfs_buf_cancel_t *nextp; xfs_buf_cancel_t *prevp; xfs_buf_cancel_t **bucket; xfs_daddr_t blkno = buf_f->blf_blkno; uint len = buf_f->blf_len; struct list_head *bucket; struct xfs_buf_cancel *bcp; /* * If this isn't a cancel buffer item, then just return. Loading @@ -1626,51 +1633,25 @@ xlog_recover_do_buffer_pass1( } /* * Insert an xfs_buf_cancel record into the hash table of * them. If there is already an identical record, bump * its reference count. */ bucket = &log->l_buf_cancel_table[(__uint64_t)blkno % XLOG_BC_TABLE_SIZE]; /* * If the hash bucket is empty then just insert a new record into * the bucket. */ if (*bucket == NULL) { bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t), KM_SLEEP); bcp->bc_blkno = blkno; bcp->bc_len = len; bcp->bc_refcount = 1; bcp->bc_next = NULL; *bucket = bcp; return; } /* * The hash bucket is not empty, so search for duplicates of our * record. If we find one them just bump its refcount. If not * then add us at the end of the list. * Insert an xfs_buf_cancel record into the hash table of them. * If there is already an identical record, bump its reference count. */ prevp = NULL; nextp = *bucket; while (nextp != NULL) { if (nextp->bc_blkno == blkno && nextp->bc_len == len) { nextp->bc_refcount++; bucket = XLOG_BUF_CANCEL_BUCKET(log, buf_f->blf_blkno); list_for_each_entry(bcp, bucket, bc_list) { if (bcp->bc_blkno == buf_f->blf_blkno && bcp->bc_len == buf_f->blf_len) { bcp->bc_refcount++; trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f); return; } prevp = nextp; nextp = nextp->bc_next; } ASSERT(prevp != NULL); bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t), KM_SLEEP); bcp->bc_blkno = blkno; bcp->bc_len = len; bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), KM_SLEEP); bcp->bc_blkno = buf_f->blf_blkno; bcp->bc_len = buf_f->blf_len; bcp->bc_refcount = 1; bcp->bc_next = NULL; prevp->bc_next = bcp; list_add_tail(&bcp->bc_list, bucket); trace_xfs_log_recover_buf_cancel_add(log, buf_f); } Loading @@ -1689,14 +1670,13 @@ xlog_recover_do_buffer_pass1( */ STATIC int xlog_check_buffer_cancelled( xlog_t *log, struct log *log, xfs_daddr_t blkno, uint len, ushort flags) { xfs_buf_cancel_t *bcp; xfs_buf_cancel_t *prevp; xfs_buf_cancel_t **bucket; struct list_head *bucket; struct xfs_buf_cancel *bcp; if (log->l_buf_cancel_table == NULL) { /* Loading @@ -1707,56 +1687,37 @@ xlog_check_buffer_cancelled( return 0; } bucket = &log->l_buf_cancel_table[(__uint64_t)blkno % XLOG_BC_TABLE_SIZE]; bcp = *bucket; if (bcp == NULL) { /* * There is no corresponding entry in the table built * in pass one, so this buffer has not been cancelled. * Search for an entry in the cancel table that matches our buffer. */ ASSERT(!(flags & XFS_BLF_CANCEL)); return 0; bucket = XLOG_BUF_CANCEL_BUCKET(log, blkno); list_for_each_entry(bcp, bucket, bc_list) { if (bcp->bc_blkno == blkno && bcp->bc_len == len) goto found; } /* * Search for an entry in the buffer cancel table that * matches our buffer. * We didn't find a corresponding entry in the table, so return 0 so * that the buffer is NOT cancelled. */ prevp = NULL; while (bcp != NULL) { if (bcp->bc_blkno == blkno && bcp->bc_len == len) { ASSERT(!(flags & XFS_BLF_CANCEL)); return 0; found: /* * We've go a match, so return 1 so that the * recovery of this buffer is cancelled. * If this buffer is actually a buffer cancel * log item, then decrement the refcount on the * one in the table and remove it if this is the * last reference. * We've go a match, so return 1 so that the recovery of this buffer * is cancelled. If this buffer is actually a buffer cancel log * item, then decrement the refcount on the one in the table and * remove it if this is the last reference. */ if (flags & XFS_BLF_CANCEL) { bcp->bc_refcount--; if (bcp->bc_refcount == 0) { if (prevp == NULL) { *bucket = bcp->bc_next; } else { prevp->bc_next = bcp->bc_next; } if (--bcp->bc_refcount == 0) { list_del(&bcp->bc_list); kmem_free(bcp); } } return 1; } prevp = bcp; bcp = bcp->bc_next; } /* * We didn't find a corresponding entry in the table, so * return 0 so that the buffer is NOT cancelled. */ ASSERT(!(flags & XFS_BLF_CANCEL)); return 0; } /* * Perform recovery for a buffer full of inodes. In these buffers, the only Loading Loading @@ -3649,7 +3610,7 @@ xlog_do_log_recovery( xfs_daddr_t head_blk, xfs_daddr_t tail_blk) { int error; int error, i; ASSERT(head_blk != tail_blk); Loading @@ -3657,10 +3618,12 @@ xlog_do_log_recovery( * First do a pass to find all of the cancelled buf log items. * Store them in the buf_cancel_table for use in the second pass. */ log->l_buf_cancel_table = (xfs_buf_cancel_t **)kmem_zalloc(XLOG_BC_TABLE_SIZE * sizeof(xfs_buf_cancel_t*), log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE * sizeof(struct list_head), KM_SLEEP); for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); error = xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS1); if (error != 0) { Loading @@ -3679,7 +3642,7 @@ xlog_do_log_recovery( int i; for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) ASSERT(log->l_buf_cancel_table[i] == NULL); ASSERT(list_empty(&log->l_buf_cancel_table[i])); } #endif /* DEBUG */ Loading Loading
fs/xfs/xfs_buf_item.h +0 −11 Original line number Diff line number Diff line Loading @@ -105,17 +105,6 @@ typedef struct xfs_buf_log_item { xfs_buf_log_format_t bli_format; /* in-log header */ } xfs_buf_log_item_t; /* * This structure is used during recovery to record the buf log * items which have been canceled and should not be replayed. */ typedef struct xfs_buf_cancel { xfs_daddr_t bc_blkno; uint bc_len; int bc_refcount; struct xfs_buf_cancel *bc_next; } xfs_buf_cancel_t; void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); void xfs_buf_item_relse(struct xfs_buf *); void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint); Loading
fs/xfs/xfs_log_priv.h +4 −2 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ struct xfs_buf; struct log; struct xlog_ticket; struct xfs_buf_cancel; struct xfs_mount; /* Loading Loading @@ -491,7 +490,7 @@ typedef struct log { struct xfs_buftarg *l_targ; /* buftarg of log */ uint l_flags; uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ struct xfs_buf_cancel **l_buf_cancel_table; struct list_head *l_buf_cancel_table; int l_iclog_hsize; /* size of iclog header */ int l_iclog_heads; /* # of iclog header sectors */ uint l_sectBBsize; /* sector size in BBs (2^n) */ Loading Loading @@ -534,6 +533,9 @@ typedef struct log { } xlog_t; #define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE)) #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) /* common routines */ Loading
fs/xfs/xfs_log_recover.c +61 −98 Original line number Diff line number Diff line Loading @@ -52,6 +52,17 @@ STATIC void xlog_recover_check_summary(xlog_t *); #define xlog_recover_check_summary(log) #endif /* * This structure is used during recovery to record the buf log items which * have been canceled and should not be replayed. */ struct xfs_buf_cancel { xfs_daddr_t bc_blkno; uint bc_len; int bc_refcount; struct list_head bc_list; }; /* * Sector aligned buffer routines for buffer create/read/write/access */ Loading Loading @@ -1607,15 +1618,11 @@ xlog_recover_reorder_trans( */ STATIC void xlog_recover_do_buffer_pass1( xlog_t *log, struct log *log, xfs_buf_log_format_t *buf_f) { xfs_buf_cancel_t *bcp; xfs_buf_cancel_t *nextp; xfs_buf_cancel_t *prevp; xfs_buf_cancel_t **bucket; xfs_daddr_t blkno = buf_f->blf_blkno; uint len = buf_f->blf_len; struct list_head *bucket; struct xfs_buf_cancel *bcp; /* * If this isn't a cancel buffer item, then just return. Loading @@ -1626,51 +1633,25 @@ xlog_recover_do_buffer_pass1( } /* * Insert an xfs_buf_cancel record into the hash table of * them. If there is already an identical record, bump * its reference count. */ bucket = &log->l_buf_cancel_table[(__uint64_t)blkno % XLOG_BC_TABLE_SIZE]; /* * If the hash bucket is empty then just insert a new record into * the bucket. */ if (*bucket == NULL) { bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t), KM_SLEEP); bcp->bc_blkno = blkno; bcp->bc_len = len; bcp->bc_refcount = 1; bcp->bc_next = NULL; *bucket = bcp; return; } /* * The hash bucket is not empty, so search for duplicates of our * record. If we find one them just bump its refcount. If not * then add us at the end of the list. * Insert an xfs_buf_cancel record into the hash table of them. * If there is already an identical record, bump its reference count. */ prevp = NULL; nextp = *bucket; while (nextp != NULL) { if (nextp->bc_blkno == blkno && nextp->bc_len == len) { nextp->bc_refcount++; bucket = XLOG_BUF_CANCEL_BUCKET(log, buf_f->blf_blkno); list_for_each_entry(bcp, bucket, bc_list) { if (bcp->bc_blkno == buf_f->blf_blkno && bcp->bc_len == buf_f->blf_len) { bcp->bc_refcount++; trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f); return; } prevp = nextp; nextp = nextp->bc_next; } ASSERT(prevp != NULL); bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t), KM_SLEEP); bcp->bc_blkno = blkno; bcp->bc_len = len; bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), KM_SLEEP); bcp->bc_blkno = buf_f->blf_blkno; bcp->bc_len = buf_f->blf_len; bcp->bc_refcount = 1; bcp->bc_next = NULL; prevp->bc_next = bcp; list_add_tail(&bcp->bc_list, bucket); trace_xfs_log_recover_buf_cancel_add(log, buf_f); } Loading @@ -1689,14 +1670,13 @@ xlog_recover_do_buffer_pass1( */ STATIC int xlog_check_buffer_cancelled( xlog_t *log, struct log *log, xfs_daddr_t blkno, uint len, ushort flags) { xfs_buf_cancel_t *bcp; xfs_buf_cancel_t *prevp; xfs_buf_cancel_t **bucket; struct list_head *bucket; struct xfs_buf_cancel *bcp; if (log->l_buf_cancel_table == NULL) { /* Loading @@ -1707,56 +1687,37 @@ xlog_check_buffer_cancelled( return 0; } bucket = &log->l_buf_cancel_table[(__uint64_t)blkno % XLOG_BC_TABLE_SIZE]; bcp = *bucket; if (bcp == NULL) { /* * There is no corresponding entry in the table built * in pass one, so this buffer has not been cancelled. * Search for an entry in the cancel table that matches our buffer. */ ASSERT(!(flags & XFS_BLF_CANCEL)); return 0; bucket = XLOG_BUF_CANCEL_BUCKET(log, blkno); list_for_each_entry(bcp, bucket, bc_list) { if (bcp->bc_blkno == blkno && bcp->bc_len == len) goto found; } /* * Search for an entry in the buffer cancel table that * matches our buffer. * We didn't find a corresponding entry in the table, so return 0 so * that the buffer is NOT cancelled. */ prevp = NULL; while (bcp != NULL) { if (bcp->bc_blkno == blkno && bcp->bc_len == len) { ASSERT(!(flags & XFS_BLF_CANCEL)); return 0; found: /* * We've go a match, so return 1 so that the * recovery of this buffer is cancelled. * If this buffer is actually a buffer cancel * log item, then decrement the refcount on the * one in the table and remove it if this is the * last reference. * We've go a match, so return 1 so that the recovery of this buffer * is cancelled. If this buffer is actually a buffer cancel log * item, then decrement the refcount on the one in the table and * remove it if this is the last reference. */ if (flags & XFS_BLF_CANCEL) { bcp->bc_refcount--; if (bcp->bc_refcount == 0) { if (prevp == NULL) { *bucket = bcp->bc_next; } else { prevp->bc_next = bcp->bc_next; } if (--bcp->bc_refcount == 0) { list_del(&bcp->bc_list); kmem_free(bcp); } } return 1; } prevp = bcp; bcp = bcp->bc_next; } /* * We didn't find a corresponding entry in the table, so * return 0 so that the buffer is NOT cancelled. */ ASSERT(!(flags & XFS_BLF_CANCEL)); return 0; } /* * Perform recovery for a buffer full of inodes. In these buffers, the only Loading Loading @@ -3649,7 +3610,7 @@ xlog_do_log_recovery( xfs_daddr_t head_blk, xfs_daddr_t tail_blk) { int error; int error, i; ASSERT(head_blk != tail_blk); Loading @@ -3657,10 +3618,12 @@ xlog_do_log_recovery( * First do a pass to find all of the cancelled buf log items. * Store them in the buf_cancel_table for use in the second pass. */ log->l_buf_cancel_table = (xfs_buf_cancel_t **)kmem_zalloc(XLOG_BC_TABLE_SIZE * sizeof(xfs_buf_cancel_t*), log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE * sizeof(struct list_head), KM_SLEEP); for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); error = xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS1); if (error != 0) { Loading @@ -3679,7 +3642,7 @@ xlog_do_log_recovery( int i; for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) ASSERT(log->l_buf_cancel_table[i] == NULL); ASSERT(list_empty(&log->l_buf_cancel_table[i])); } #endif /* DEBUG */ Loading