xfs: current queue for 3.8
cover xfs: current queue for 3.8
Hi folks,
This is my current patch queue for the 3.8 merge window. We are now getting close to the window opening (at -rc5 now), so I'd really like to see this stuff into the dev tree ASAP so that there is some wider test coverage before the merge window comes along.
The bulk of this patch series has been reviewed and revised over the past month. The only new patch in this is the additional attribute trace points that I needed to track down the corruption problem I recently fixed.
Other than that, I've reordered the patches to make growfs use uncached buffers ahead of the verifier series and rebased the verifier series on top of it. i also folded the fixes I had in additional patches back into the base patches in the verifier series.
I'm not sure whether I have captured all the Reviewed-by tags that people have given - if necessary I can go back and search the lists for them all and add the ones I've missed....
Diffstat for the series is:
$ git diff --stat --summary -C -M 074dad5..f02d23b fs/xfs/Kconfig | 1 + fs/xfs/Makefile | 1 - fs/xfs/uuid.h | 6 + fs/xfs/xfs_ag.h | 4 + fs/xfs/xfs_alloc.c | 141 ++++++++++++--- fs/xfs/xfs_alloc.h | 3 + fs/xfs/xfs_alloc_btree.c | 77 +++++++++ fs/xfs/xfs_alloc_btree.h | 2 + fs/xfs/xfs_aops.c | 2 +- fs/xfs/xfs_attr.c | 103 +++++------ fs/xfs/xfs_attr_leaf.c | 143 ++++++++++------ fs/xfs/xfs_attr_leaf.h | 6 + fs/xfs/xfs_bmap.c | 64 ++++--- fs/xfs/xfs_bmap_btree.c | 63 +++++++ fs/xfs/xfs_bmap_btree.h | 1 + fs/xfs/xfs_btree.c | 111 +++++++----- fs/xfs/xfs_btree.h | 22 ++- fs/xfs/xfs_buf.c | 59 +++++-- fs/xfs/xfs_buf.h | 27 ++- fs/xfs/xfs_cksum.h | 63 +++++++ fs/xfs/xfs_da_btree.c | 141 ++++++++++++--- fs/xfs/xfs_da_btree.h | 10 +- fs/xfs/xfs_dfrag.c | 13 +- fs/xfs/xfs_dir2_block.c | 436 +++++++++++++++++++++++++++-------------------- fs/xfs/xfs_dir2_data.c | 170 ++++++++++++++---- fs/xfs/xfs_dir2_leaf.c | 172 +++++++++++++------ fs/xfs/xfs_dir2_node.c | 288 ++++++++++++++++++++----------- fs/xfs/xfs_dir2_priv.h | 19 ++- fs/xfs/xfs_dquot.c | 135 ++++++++++++--- fs/xfs/xfs_file.c | 27 +-- fs/xfs/xfs_fs_subr.c | 96 ----------- fs/xfs/xfs_fsops.c | 137 ++++++++++----- fs/xfs/xfs_ialloc.c | 74 +++++--- fs/xfs/xfs_ialloc.h | 4 +- fs/xfs/xfs_ialloc_btree.c | 55 ++++++ fs/xfs/xfs_ialloc_btree.h | 2 + fs/xfs/xfs_inode.c | 131 ++++++++------ fs/xfs/xfs_inode.h | 1 + fs/xfs/xfs_iops.c | 4 +- fs/xfs/xfs_itable.c | 3 +- fs/xfs/xfs_linux.h | 1 + fs/xfs/xfs_log.c | 135 ++++++++++++--- fs/xfs/xfs_log_priv.h | 11 +- fs/xfs/xfs_log_recover.c | 145 ++++++++-------- fs/xfs/xfs_mount.c | 130 +++++++++----- fs/xfs/xfs_mount.h | 4 +- fs/xfs/xfs_qm.c | 5 +- fs/xfs/xfs_rtalloc.c | 15 +- fs/xfs/xfs_sb.h | 10 +- fs/xfs/xfs_trace.h | 54 +++++- fs/xfs/xfs_trans.h | 19 +-- fs/xfs/xfs_trans_buf.c | 9 +- fs/xfs/xfs_vnodeops.c | 48 ++++-- fs/xfs/xfs_vnodeops.h | 7 - 54 files changed, 2327 insertions(+), 1083 deletions(-) create mode 100644 fs/xfs/xfs_cksum.h delete mode 100644 fs/xfs/xfs_fs_subr.c
It seems pretty solid - all the bug fixes I've been pushing out recently have been found as a result of testing this patch series. They have started life at the end of the series, and once confirmed to fix the problem have been re-ordered to the start. Hence the series has been seeing all the testing I have been doing recently.
I really do not want this stuff to miss the 3.8 window due to a repeat of the last cycle's misadventures. Given how quiet -rc5 was, we might only be 2 weeks away from the 3.8 merge window opening. Which means that, realistically, this series need to be finalised by the end of the week so that it's got some soak time in linux-next before it moves into Linus' tree.
The main reason I don't want this to miss 3.8 is that I'm planning on 3.9 for all the CRC metadata format changes and supporting code to be ready. There's a lot more code for coming for 3.9 than there is in this patch series (probably twice the size) and it's a lot more complex, so the less that ends up in 3.9 from this series the better...
Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 1/32 xfs: add more attribute tree trace points.
From: Dave Chinner <[email protected]>
Added when debugging recent attribute tree problems to more finely trace code execution through the maze of twisty passages that makes up the attr code.
--- fs/xfs/xfs_attr.c | 18 ++++++++++++++++ fs/xfs/xfs_attr_leaf.c | 37 +++++++++++++++++++-------------- fs/xfs/xfs_da_btree.c | 6 ++++++ fs/xfs/xfs_trace.h | 54 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 16 deletions(-)
fs/xfs/xfs_attr.c +18 -0
@@ -1155,6 +1155,8 @@ xfs_attr_leaf_get(xfs_da_args_t *args)struct xfs_buf *bp;int error; +trace_xfs_attr_leaf_get (args); + args->blkno =0 ; error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp,XFS_ATTR_FORK );
@@ -1185,6 +1187,8 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)int error;struct xfs_buf *bp; +trace_xfs_attr_leaf_list (context); + context->cursor->blkno =0 ; error =xfs_da_read_buf (NULL , context->dp,0 ,-1 , &bp,XFS_ATTR_FORK );if (error)
@@ -1653,6 +1657,8 @@ xfs_attr_fillstate(xfs_da_state_t *state)xfs_da_state_blk_t *blk;int level; +trace_xfs_attr_fillstate (state->args); +/* * Roll down the "path" in the state structure, storing the on-disk * block number for those buffers in the "path".
@@ -1699,6 +1705,8 @@ xfs_attr_refillstate(xfs_da_state_t *state)xfs_da_state_blk_t *blk;int level, error; +trace_xfs_attr_refillstate (state->args); +/* * Roll down the "path" in the state structure, storing the on-disk * block number for those buffers in the "path".
@@ -1755,6 +1763,8 @@ xfs_attr_node_get(xfs_da_args_t *args)int error, retval;int i; +trace_xfs_attr_node_get (args); + state =xfs_da_state_alloc (); state->args = args; state->mp = args->dp->i_mount;
@@ -1804,6 +1814,8 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)int error, i;struct xfs_buf *bp; +trace_xfs_attr_node_list (context); + cursor = context->cursor; cursor->initted =1 ;
@@ -1959,6 +1971,8 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)int nmap, error, tmp, valuelen, blkcnt, i;xfs_dablk_t lblkno; +trace_xfs_attr_rmtval_get (args); +ASSERT (!(args->flags &ATTR_KERNOVAL )); mp = args->dp->i_mount;
@@ -2014,6 +2028,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)xfs_dablk_t lblkno;int blkcnt, valuelen, nmap, error, tmp, committed; +trace_xfs_attr_rmtval_set (args); + dp = args->dp; mp = dp->i_mount; src = args->value;
@@ -2143,6 +2159,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)xfs_dablk_t lblkno;int valuelen, blkcnt, nmap, error, done, committed; +trace_xfs_attr_rmtval_remove (args); + mp = args->dp->i_mount;/*
fs/xfs/xfs_attr_leaf.c +22 -15
@@ -57,7 +57,8 @@ STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block, struct xfs_buf **bpp); STATIC int xfs_attr_leaf_add_work(struct xfs_buf *leaf_buffer,xfs_da_args_t *args,int freemap_index); -STATIC void xfs_attr_leaf_compact(xfs_trans_t *tp, struct xfs_buf *leaf_buffer); +STATIC void xfs_attr_leaf_compact(struct xfs_da_args *args, +struct xfs_buf *leaf_buffer); STATIC void xfs_attr_leaf_rebalance(xfs_da_state_t *state,xfs_da_state_blk_t *blk1,xfs_da_state_blk_t *blk2);
@@ -1071,7 +1072,7 @@ xfs_attr_leaf_add(* Compact the entries to coalesce free space. * This may change the hdr->count via dropping INCOMPLETE entries. */ -xfs_attr_leaf_compact (args->trans, bp); +xfs_attr_leaf_compact (args, bp);/* * After compaction, the block is guaranteed to have only one
@@ -1102,6 +1103,8 @@ xfs_attr_leaf_add_work(xfs_mount_t *mp;int tmp, i; +trace_xfs_attr_leaf_add_work (args); + leaf = bp->b_addr;ASSERT (leaf->hdr.info.magic ==cpu_to_be16 (XFS_ATTR_LEAF_MAGIC )); hdr = &leaf->hdr;
@@ -1214,15 +1217,17 @@ xfs_attr_leaf_add_work(*/ STATIC voidxfs_attr_leaf_compact ( -struct xfs_trans *trans, -struct xfs_buf *bp) +struct xfs_da_args *args, +struct xfs_buf *bp) { -xfs_attr_leafblock_t *leaf_s, *leaf_d; -xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; -xfs_mount_t *mp; -char *tmpbuffer; +xfs_attr_leafblock_t *leaf_s, *leaf_d; +xfs_attr_leaf_hdr_t *hdr_s, *hdr_d; +struct xfs_trans *trans = args->trans; +struct xfs_mount *mp = trans->t_mountp; +char *tmpbuffer; + +trace_xfs_attr_leaf_compact (args); - mp = trans->t_mountp; tmpbuffer =kmem_alloc (XFS_LBSIZE (mp),KM_SLEEP );ASSERT (tmpbuffer !=NULL );memcpy (tmpbuffer, bp->b_addr,XFS_LBSIZE (mp));
@@ -1345,9 +1350,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, max =be16_to_cpu (hdr2->firstused) -sizeof (xfs_attr_leaf_hdr_t); max -=be16_to_cpu (hdr2->count) *sizeof (xfs_attr_leaf_entry_t); -if (space > max) { -xfs_attr_leaf_compact (args->trans, blk2->bp); - } +if (space > max) +xfs_attr_leaf_compact (args, blk2->bp);/* * Move high entries from leaf1 to low end of leaf2.
@@ -1378,9 +1382,8 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, max =be16_to_cpu (hdr1->firstused) -sizeof (xfs_attr_leaf_hdr_t); max -=be16_to_cpu (hdr1->count) *sizeof (xfs_attr_leaf_entry_t); -if (space > max) { -xfs_attr_leaf_compact (args->trans, blk1->bp); - } +if (space > max) +xfs_attr_leaf_compact (args, blk1->bp);/* * Move low entries from leaf2 to high end of leaf1.
@@ -1577,6 +1580,8 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)xfs_dablk_t blkno;struct xfs_buf *bp; +trace_xfs_attr_leaf_toosmall (state->args); +/* * Check for the degenerate case of the block being over 50% full. * If so, it's not worth even looking to see if we might be able
@@ -1702,6 +1707,8 @@ xfs_attr_leaf_remove(int tablesize, tmp, i;xfs_mount_t *mp; +trace_xfs_attr_leaf_remove (args); + leaf = bp->b_addr;ASSERT (leaf->hdr.info.magic ==cpu_to_be16 (XFS_ATTR_LEAF_MAGIC )); hdr = &leaf->hdr;
fs/xfs/xfs_da_btree.c +6 -0
@@ -779,6 +779,8 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)xfs_dablk_t blkno;struct xfs_buf *bp; +trace_xfs_da_node_toosmall (state->args); +/* * Check for the degenerate case of the block being over 50% full. * If so, it's not worth even looking to see if we might be able
@@ -900,6 +902,8 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)xfs_dahash_t lasthash=0 ;int level, count; +trace_xfs_da_fixhashpath (state->args); + level = path->active-1 ; blk = &path->blk[ level ];switch (blk->magic) {
@@ -1417,6 +1421,8 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,xfs_dablk_t blkno=0 ;int level, error; +trace_xfs_da_path_shift (state->args); +/* * Roll up the Btree looking for the first block where our * current index is not at the edge of the block. Note that
fs/xfs/xfs_trace.h +53 -1
98 lines not on this page · raw message
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 01/32] xfs: add more attribute tree trace points.
Quoted 8 lines · Dave Chinner
From: Dave Chinner<[email protected]>
Added when debugging recent attribute tree problems to more finely trace code execution through the maze of twisty passages that makes up the attr code.
Signed-off-by Dave Chinner<[email protected]>---
Looks good.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 01/32] xfs: add more attribute tree trace points.
In reply to Dave ChinnerQuoted 5 lines · Dave Chinner
From: Dave Chinner <[email protected]>
Added when debugging recent attribute tree problems to more finely trace code execution through the maze of twisty passages that makes up the attr code.
Looks good.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 2/32 xfs: remove xfs_tosspages
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
It's a buggy, unnecessary wrapper that is duplicating truncate_pagecache_range().
When replacing the call in xfs_change_file_space(), also ensure that the length being allocated/freed is always positive before making any changes. These checks are done in the lower extent manipulation functions, too, but we need to do them before any page cache operations.
--- fs/xfs/xfs_dfrag.c | 3 +-- fs/xfs/xfs_fs_subr.c | 12 ------------ fs/xfs/xfs_vnodeops.c | 28 +++++++++++++++++++++++----- fs/xfs/xfs_vnodeops.h | 2 -- 4 files changed, 24 insertions(+), 21 deletions(-)
fs/xfs/xfs_dfrag.c +1 -2
@@ -315,8 +315,7 @@ xfs_swap_extents(* are safe. We don't really care if non-io related * fields change. */ - -xfs_tosspages (ip,0 ,-1 ,FI_REMAPF ); +truncate_pagecache_range (VFS_I (ip),0 ,-1 ); tp =xfs_trans_alloc (mp,XFS_TRANS_SWAPEXT ); if ((error = xfs_trans_reserve(tp, 0,
fs/xfs/xfs_fs_subr.c +0 -12
@@ -25,18 +25,6 @@* note: all filemap functions return negative error codes. These * need to be inverted before returning to the xfs core functions. */ -void -xfs_tosspages ( -xfs_inode_t *ip, -xfs_off_t first, -xfs_off_t last, -int fiopt) -{ -/* can't toss partial tail pages, so mask them out */ - last &= ~(PAGE_SIZE -1 ); -truncate_inode_pages_range (VFS_I (ip)->i_mapping, first, last -1 ); -} - int xfs_flushinval_pages( xfs_inode_t *ip,
fs/xfs/xfs_vnodeops.c +23 -5
@@ -2118,7 +2118,6 @@ xfs_change_file_space(xfs_fsize_t fsize;int setprealloc;xfs_off_t startoffset; -xfs_off_t llen;xfs_trans_t *tp;struct iattr iattr;int prealloc_type;
@@ -2139,12 +2138,30 @@ xfs_change_file_space(return XFS_ERROR (EINVAL ); } - llen = bf->l_len >0 ? bf->l_len -1 : bf->l_len; +/* +* length of <= 0 for resv/unresv/zero is invalid. length for +* alloc/free is ignored completely and we have no idea what userspace +* might have set it to, so set it to zero to allow range +* checks to pass. +*/ +switch (cmd) { +case XFS_IOC_ZERO_RANGE : +case XFS_IOC_RESVSP : +case XFS_IOC_RESVSP64 : +case XFS_IOC_UNRESVSP : +case XFS_IOC_UNRESVSP64 : +if (bf->l_len <=0 ) +return XFS_ERROR (EINVAL ); +break ; +default : + bf->l_len =0 ; +break ; + }if (bf->l_start <0 || bf->l_start > mp->m_super->s_maxbytes || - bf->l_start + llen <0 || - bf->l_start + llen > mp->m_super->s_maxbytes) + bf->l_start + bf->l_len <0 || + bf->l_start + bf->l_len >= mp->m_super->s_maxbytes)return XFS_ERROR (EINVAL ); bf->l_whence =0 ;
@@ -2169,7 +2186,8 @@ xfs_change_file_space(switch (cmd) {case XFS_IOC_ZERO_RANGE : prealloc_type |=XFS_BMAPI_CONVERT ; -xfs_tosspages (ip, startoffset, startoffset + bf->l_len,0 ); +truncate_pagecache_range (VFS_I (ip), startoffset, +round_down (startoffset + bf->l_len,PAGE_SIZE ) -1 );/* FALLTHRU */ case XFS_IOC_RESVSP :case XFS_IOC_RESVSP64 :
fs/xfs/xfs_vnodeops.h +0 -2
@@ -48,8 +48,6 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,int xfs_attr_remove (struct xfs_inode *dp,const unsigned char *name,int flags);int xfs_attr_list (struct xfs_inode *dp,char *buffer,int bufsize,int flags,struct attrlist_cursor_kern *cursor); -void xfs_tosspages (struct xfs_inode *inode,xfs_off_t first, -xfs_off_t last,int fiopt);int xfs_flushinval_pages (struct xfs_inode *ip,xfs_off_t first,xfs_off_t last,int fiopt); int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 2/32 xfs: remove xfs_tosspages
xfs: remove xfs_tosspages
From: Dave Chinner <[email protected]>
It's a buggy, unnecessary wrapper that is duplicating truncate_pagecache_range().
When replacing the call in xfs_change_file_space(), also ensure that the length being allocated/freed is always positive before making any changes. These checks are done in the lower extent manipulation functions, too, but we need to do them before any page cache operations.
---
v2: fix rounding error in XFS_IOC_ZERO case.
fs/xfs/xfs_dfrag.c | 3 +-- fs/xfs/xfs_fs_subr.c | 12 ------------ fs/xfs/xfs_vnodeops.c | 30 +++++++++++++++++++++++++----- fs/xfs/xfs_vnodeops.h | 2 -- 4 files changed, 26 insertions(+), 21 deletions(-)
fs/xfs/xfs_dfrag.c +1 -2
@@ -315,8 +315,7 @@ xfs_swap_extents(* are safe. We don't really care if non-io related * fields change. */ - -xfs_tosspages (ip,0 ,-1 ,FI_REMAPF ); +truncate_pagecache_range (VFS_I (ip),0 ,-1 ); tp =xfs_trans_alloc (mp,XFS_TRANS_SWAPEXT ); if ((error = xfs_trans_reserve(tp, 0,
fs/xfs/xfs_fs_subr.c +0 -12
@@ -25,18 +25,6 @@* note: all filemap functions return negative error codes. These * need to be inverted before returning to the xfs core functions. */ -void -xfs_tosspages ( -xfs_inode_t *ip, -xfs_off_t first, -xfs_off_t last, -int fiopt) -{ -/* can't toss partial tail pages, so mask them out */ - last &= ~(PAGE_SIZE -1 ); -truncate_inode_pages_range (VFS_I (ip)->i_mapping, first, last -1 ); -} - int xfs_flushinval_pages( xfs_inode_t *ip,
fs/xfs/xfs_vnodeops.c +25 -5
@@ -2118,7 +2118,7 @@ xfs_change_file_space(xfs_fsize_t fsize;int setprealloc;xfs_off_t startoffset; -xfs_off_t llen; +xfs_off_t end;xfs_trans_t *tp;struct iattr iattr;int prealloc_type;
@@ -2139,12 +2139,30 @@ xfs_change_file_space(return XFS_ERROR (EINVAL ); } - llen = bf->l_len >0 ? bf->l_len -1 : bf->l_len; +/* +* length of <= 0 for resv/unresv/zero is invalid. length for +* alloc/free is ignored completely and we have no idea what userspace +* might have set it to, so set it to zero to allow range +* checks to pass. +*/ +switch (cmd) { +case XFS_IOC_ZERO_RANGE : +case XFS_IOC_RESVSP : +case XFS_IOC_RESVSP64 : +case XFS_IOC_UNRESVSP : +case XFS_IOC_UNRESVSP64 : +if (bf->l_len <=0 ) +return XFS_ERROR (EINVAL ); +break ; +default : + bf->l_len =0 ; +break ; + }if (bf->l_start <0 || bf->l_start > mp->m_super->s_maxbytes || - bf->l_start + llen <0 || - bf->l_start + llen > mp->m_super->s_maxbytes) + bf->l_start + bf->l_len <0 || + bf->l_start + bf->l_len >= mp->m_super->s_maxbytes)return XFS_ERROR (EINVAL ); bf->l_whence =0 ;
@@ -2169,7 +2187,9 @@ xfs_change_file_space(switch (cmd) {case XFS_IOC_ZERO_RANGE : prealloc_type |=XFS_BMAPI_CONVERT ; -xfs_tosspages (ip, startoffset, startoffset + bf->l_len,0 ); + end =round_down (startoffset + bf->l_len,PAGE_SIZE ) -1 ; +if (startoffset > end) +truncate_pagecache_range (VFS_I (ip), startoffset, end);/* FALLTHRU */ case XFS_IOC_RESVSP :case XFS_IOC_RESVSP64 :
fs/xfs/xfs_vnodeops.h +0 -2
@@ -48,8 +48,6 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,int xfs_attr_remove (struct xfs_inode *dp,const unsigned char *name,int flags);int xfs_attr_list (struct xfs_inode *dp,char *buffer,int bufsize,int flags,struct attrlist_cursor_kern *cursor); -void xfs_tosspages (struct xfs_inode *inode,xfs_off_t first, -xfs_off_t last,int fiopt);int xfs_flushinval_pages (struct xfs_inode *ip,xfs_off_t first,xfs_off_t last,int fiopt); int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02/32 V2] xfs: remove xfs_tosspages
Quoted 17 lines · Dave Chinner
xfs: remove
xfs_tosspagesFrom: Dave Chinner <[email protected]>
It's a buggy, unnecessary wrapper that is duplicating
truncate_pagecache_range().When replacing the call in
xfs_change_file_space(), also ensure that the length being allocated/freed is always positive before making any changes. These checks are done in the lower extent manipulation functions, too, but we need to do them before any page cache operations.Reported-by Andrew Dahl <[email protected]>Signed-off-by Dave Chinner <[email protected]>---
fs/xfs/xfs_vnodeops.c xfs_change_file_space( · line 2191
Quoted 5 lines
fs/xfs/xfs_vnodeops.c +2
-1case XFS_IOC_ZERO_RANGE : prealloc_type |=XFS_BMAPI_CONVERT ; -xfs_tosspages (ip, startoffset, startoffset + bf->l_len,0 ); + end =round_down (startoffset + bf->l_len,PAGE_SIZE ) -1 ; +if (startoffset > end)
This should be
if (startoffset <= end)
This exact like was in my original patch, though it returned if this was true. -- Also, it needs to be "or equal to" for the case of passing [4095,4096] -- after we round down and subtract one, they'll be equal and the call will zero one byte.
--
I'll follow up with a patch just so Ben can get this pulled today.
Looks great though!
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02.5/32] xfs: remove xfs_tosspages
Reversing the check on XFS_IOC_ZERO_RANGE.
Range should be zeroed if the start is less than or equal to the end.
---
fs/xfs/xfs_vnodeops.c +1 -1
@@ -2188,7 +2188,7 @@ xfs_change_file_space(case XFS_IOC_ZERO_RANGE : prealloc_type |=XFS_BMAPI_CONVERT ; end =round_down (startoffset + bf->l_len,PAGE_SIZE ) -1 ; -if (startoffset > end) +if (startoffset <= end)truncate_pagecache_range (VFS_I (ip), startoffset, end);/* FALLTHRU */ case XFS_IOC_RESVSP :
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Mark Tinguely
Reviewed-byRe: [PATCH 02.5/32] xfs: remove xfs_tosspages
Quoted 8 lines · Andrew Dahl
Reversing the check on
XFS_IOC_ZERO_RANGE.Range should be zeroed if the start is less than or equal to the end.
Signed-off-by Andrew Dahl<[email protected]>---
Tests correctly.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02.5/32] xfs: remove xfs_tosspages
Quoted 11 lines · Mark Tinguely
Quoted 8 lines · Andrew Dahl
Reversing the check on
XFS_IOC_ZERO_RANGE.Range should be zeroed if the start is less than or equal to the end.
Signed-off-by Andrew Dahl<[email protected]>---
Tests correctly.
Actually, it doesn't. Test 242 still fails. Yeah, there was already a regression test for this case, it's just that the golden output wasn't correct so it never detected the single first block zero failure even though it was tested. Now it throws an md5sum mismatch error, indicating that the behaviour has changed iin some unexpected way and something is not right with the world.
$ sudo ./check 242 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-1 3.7.0-rc1-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch
242 - output mismatch (see 242.out.bad)
242.out.bad 2012-11-21 15:41:02.000000000 +1100 renamed from 242.out 2012-11-21 13:13:22.000000000 +1100 +1 -1
@@ -74,4 +74,4 @@ eecb7aa303d121835de05028751d301c 17. data -> hole in single block file 0: [0..7]: unwritten -56819989ef2d9f40785adce8c06b64d0 +5fed275e7617a806f94c173746a2a723
Ran: 242
Failures: 242
Failed 1 of 1 tests
[ Here's a tip for the future: anything that changes allocation corner cases needs to be run through the entire of xfstests suite because they have a nasty habit of causing secondary problems.... ]
I can confirm that the page cache page is not being tossed for this case (end is -1, start is 128) so the fix for the problem in the commit is good, but there's more problems here. Clearly it is that there is data in the page cache:
@@ -74,4 +74,7 @@
eecb7aa303d121835de05028751d301c
17. data -> hole in single block file
0: [0..7]: unwritten
-56819989ef2d9f40785adce8c06b64d0
+0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd
+*
+0001000
+5fed275e7617a806f94c173746a2a723
And that is wrong, wrong, wrong for an unwritten extent.
So, before even looking for the bug, what's the correct behaviour here? It's not directly specified in the man page, but XFS_IOC_ZERO was really only implemented to zero whole blocks. However, it makes sense to handle partial blocks in a sane and consistent manner, zeroing them correctly similar to XFS_IOC_UNRESVSP and hence providing full byte range zeroing capability.
With this in mind, I look just looked at test 290 in more detail. To me, the basic premise of the test is fundamentally wrong:
# Nothing should be tossed unless the range includes a page boundry
XFS_IOC_ZERO's functionality is not defined by page boundaries or kernel internal behaviours - they may influence behaviour, but they certainly don't define the behaviour. What I see in test 290 is an encoding of the current truncate_pagecache_range() semantics, not an encoding of the intent of XFS_IOC_ZERO_RANGE. I didn't pay enough attention to what this test was doing in the first place (my fault), but the current behaviour is, IMO, borderline insane. :/
So, lets just make it sane by updating XFS_IOC_ZERO_RANGE to full byte range granularity - it's simple enough to do. We can fix 242 and 290 quickly enough, anyway...
FWIW, this isn't currently optimal (we can avoid zeroing if the partial blocks fall on holes or unwritten extents), but is a minor problem compared to correct behaviour, and so that can be fixed later.
Cheers,
Dave.
Signature · 20 lines
Dave Chinner [email protected] xfs: byte range granularity for XFS_IOC_ZERO_RANGE From: Dave Chinner <[email protected]> XFS_IOC_ZERO_RANGE simply does not work properly for non page cache aligned ranges. Neither test 242 or 290 exercise this correctly, so the behaviour is completely busted even though the tests pass. Fix it to support full byte range granularity as was originally intended for this ioctl. Signed-off-by: Dave Chinner <[email protected]> --- fs/xfs/xfs_file.c | 2 +- fs/xfs/xfs_vnodeops.c | 84 ++++++++++++++++++++++++++++++++++++------------- fs/xfs/xfs_vnodeops.h | 1 + 3 files changed, 65 insertions(+), 22 deletions(-)
fs/xfs/xfs_file.c +1 -1
@@ -86,7 +86,7 @@ xfs_rw_ilock_demote(* valid before the operation, it will be read from disk before * being partially zeroed. */ -STATIC int +int xfs_iozero( struct xfs_inode *ip, /* inode */ loff_t pos, /* offset in file */
fs/xfs/xfs_vnodeops.c +63 -21
110 lines not on this page · raw message
fs/xfs/xfs_vnodeops.h +1 -0
@@ -49,6 +49,7 @@ int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags);int xfs_attr_list (struct xfs_inode *dp,char *buffer,int bufsize,int flags,struct attrlist_cursor_kern *cursor); +int xfs_iozero (struct xfs_inode *,loff_t ,size_t );int xfs_zero_eof (struct xfs_inode *,xfs_off_t ,xfs_fsize_t );int xfs_free_eofblocks (struct xfs_mount *,struct xfs_inode *,bool );
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02.5/32] xfs: remove xfs_tosspages
On 11/21/2012 02:05 AM, Dave Chinner wrote:
...
Quoted 5 lines
[ Here's a tip for the future: anything that changes allocation corner cases needs to be run through the entire of xfstests suite because they have a nasty habit of causing secondary problems.... ]
Makes sense -- I'll keep that in mind for the future. (Thanks!)
...
Quoted 5 lines
fs/xfs/xfs_vnodeops.c +5
-0+ +STATIC int +xfs_zero_file_space( + struct xfs_inode *ip, + xfs_off_t offset,
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2112
Quoted 10 lines
fs/xfs/xfs_vnodeops.c +10
-0+ xfs_off_t len, + int attr_flags) +{ +struct xfs_mount *mp = ip->i_mount; +uint rounding; +xfs_off_t start; +xfs_off_t end; +int error; + + rounding =max_t (uint,1 << mp->m_sb.sb_blocklog,PAGE_CACHE_SIZE );
Let's say rounding is 4K
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2116
Quoted 4 lines
fs/xfs/xfs_vnodeops.c +4
-0+ +/* round the range iof extents we are going to convert inwards */ + start =round_up (offset, rounding); + end =round_down (offset + len, rounding);
Now, let's say we pass in (4K-1) for the offset and (4K-1).
Then start would be 4K and the end would be 4K, right?
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2119
Quoted 3 lines
fs/xfs/xfs_vnodeops.c +3
-0+ +ASSERT (start >= offset); +ASSERT (end <= offset + len);
These are both true, so this is good.
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2124
Quoted 5 lines
fs/xfs/xfs_vnodeops.c +5
-0+ +if (!(attr_flags &XFS_ATTR_NOLOCK )) +xfs_ilock (ip,XFS_IOLOCK_EXCL ); + +if (start < end -1 ) {
This is false, as expected.
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2135
Quoted 11 lines
fs/xfs/xfs_vnodeops.c +11
-0+/* punch out the page cache over the conversion range */ +truncate_pagecache_range (VFS_I (ip), start, end -1 ); +/* convert the blocks */ + error =xfs_alloc_file_space (ip, start, end - start -1 , +XFS_BMAPI_PREALLOC |XFS_BMAPI_CONVERT , + attr_flags); +if (error) + goto out_unlock; + }else { +/* it's a sub-rounding range */ +ASSERT (offset + len <= rounding);
This is false. (8K - 2) <= 4K -- Not so good.
Maybe (2*rounding) would be better, as offset + len could never be greater than 2rounding (but can be greater than 1rounding). Or removing this assert altogether.
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2144
Quoted 9 lines
fs/xfs/xfs_vnodeops.c +9
-0+ error =xfs_iozero (ip, offset, len); + goto out_unlock; + } + +/* now we've handled the interior of the range, handle the edges */ +if (start != offset) + error =xfs_iozero (ip, offset, start - offset); +if (!error && end != offset + len) + error =xfs_iozero (ip, end, offset + len - end);
This looks good.
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2149
Quoted 5 lines
fs/xfs/xfs_vnodeops.c +5
-0+ +out_unlock: +if (!(attr_flags &XFS_ATTR_NOLOCK )) +xfs_iunlock (ip,XFS_IOLOCK_EXCL ); +return error;
...
Beyond that, I think it all looks good and like what you've done!
Thanks,
Andrew
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02.5/32] xfs: remove xfs_tosspages
Quoted 45 lines · Andrew Dahl
On 11/21/2012 02:05 AM, Dave Chinner wrote:
...Quoted 5 lines
[ Here's a tip for the future: anything that changes allocation corner cases needs to be run through the entire of xfstests suite because they have a nasty habit of causing secondary problems.... ]
Makes sense -- I'll keep that in mind for the future. (Thanks!)
...
Quoted 5 lines
fs/xfs/xfs_vnodeops.c +5
-0+ +STATIC int +xfs_zero_file_space( + struct xfs_inode *ip, + xfs_off_t offset,fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2112
Quoted 10 lines
fs/xfs/xfs_vnodeops.c +10
-0+ xfs_off_t len, + int attr_flags) +{ +struct xfs_mount *mp = ip->i_mount; +uint rounding; +xfs_off_t start; +xfs_off_t end; +int error; + + rounding =max_t (uint,1 << mp->m_sb.sb_blocklog,PAGE_CACHE_SIZE );Let's say rounding is 4K
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2116
Quoted 4 lines
fs/xfs/xfs_vnodeops.c +4
-0+ +/* round the range iof extents we are going to convert inwards */ + start =round_up (offset, rounding); + end =round_down (offset + len, rounding);Now, let's say we pass in (4K-1) for the offset and (4K-1).
Then start would be 4K and the end would be 4K, right?
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2119
Quoted 3 lines
fs/xfs/xfs_vnodeops.c +3
-0+ +ASSERT (start >= offset); +ASSERT (end <= offset + len);These are both true, so this is good.
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2124
Quoted 5 lines
fs/xfs/xfs_vnodeops.c +5
-0+ +if (!(attr_flags &XFS_ATTR_NOLOCK )) +xfs_ilock (ip,XFS_IOLOCK_EXCL ); + +if (start < end -1 ) {This is false, as expected.
Quoted 12 lines
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2135
Quoted 11 lines
fs/xfs/xfs_vnodeops.c +11
-0+/* punch out the page cache over the conversion range */ +truncate_pagecache_range (VFS_I (ip), start, end -1 ); +/* convert the blocks */ + error =xfs_alloc_file_space (ip, start, end - start -1 , +XFS_BMAPI_PREALLOC |XFS_BMAPI_CONVERT , + attr_flags); +if (error) + goto out_unlock; + }else { +/* it's a sub-rounding range */ +ASSERT (offset + len <= rounding);This is false. (8K - 2) <= 4K -- Not so good.
Right, I put this in after testing without thinking too hard about it. It's always completely wrong, because offset can be an arbitrary 64 bit number, and rounding will always be <=64k...
Quoted 3 lines
Maybe (2*rounding) would be better, as offset + len could never be greater than 2rounding (but can be greater than 1rounding). Or removing this assert altogether.
No, the correct thing to assert is:
ASSERT(offset + len <= start);
That is, start is rounded up, and end is rounded down, so for a sub-block range the end should always be less than the start of the next block. That's what my current code has in it.
Quoted 1 line
Beyond that, I think it all looks good and like what you've done!
Thanks for looking at it. now all I've got to do if fix all the test output. :/
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02.5/32] xfs: remove xfs_tosspages
Quoted 4 lines · Dave Chinner
Quoted 3 lines · Andrew Dahl
On 11/21/2012 02:05 AM, Dave Chinner wrote:
...Quoted 1 line
...
Quoted 13 lines
Quoted 4 lines
fs/xfs/xfs_vnodeops.c xfs_free_file_space( · line 2135
Quoted 3 lines
fs/xfs/xfs_vnodeops.c +3
-0+ }else { +/* it's a sub-rounding range */ +ASSERT (offset + len <= rounding);This is false. (8K - 2) <= 4K -- Not so good.
Right, I put this in after testing without thinking too hard about it. It's always completely wrong, because offset can be an arbitrary 64 bit number, and rounding will always be <=64k...
Quoted 3 lines
Maybe (2*rounding) would be better, as offset + len could never be greater than 2rounding (but can be greater than 1rounding). Or removing this assert altogether.
Quoted 7 lines
No, the correct thing to assert is:
ASSERT(offset + len <= start);That is, start is rounded up, and end is rounded down, so for a sub-block range the end should always be less than the start of the next block. That's what my current code has in it.
Ah... that makes sense. Yeah, with that change, I'd say it looks great!
Thanks, Dave.
-Andrew
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02/32 V2] xfs: remove xfs_tosspages
In reply to Andrew DahlQuoted 26 lines · Andrew Dahl
Quoted 17 lines · Dave Chinner
xfs: remove
xfs_tosspagesFrom: Dave Chinner <[email protected]>
It's a buggy, unnecessary wrapper that is duplicating
truncate_pagecache_range().When replacing the call in
xfs_change_file_space(), also ensure that the length being allocated/freed is always positive before making any changes. These checks are done in the lower extent manipulation functions, too, but we need to do them before any page cache operations.Reported-by Andrew Dahl <[email protected]>Signed-off-by Dave Chinner <[email protected]>---
fs/xfs/xfs_vnodeops.c xfs_change_file_space( · line 2191
Quoted 5 lines
fs/xfs/xfs_vnodeops.c +2
-1case XFS_IOC_ZERO_RANGE : prealloc_type |=XFS_BMAPI_CONVERT ; -xfs_tosspages (ip, startoffset, startoffset + bf->l_len,0 ); + end =round_down (startoffset + bf->l_len,PAGE_SIZE ) -1 ; +if (startoffset > end)This should be
Quoted 1 line
if (startoffset <= end)
Duh - that's quite a thinko. :/
And I missed the fact that 242 failed in my rush to get it out. I should have caught that before I sent it. My mistake.
Thanks for getting it fixed, though.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 02/32 V2] xfs: remove xfs_tosspages
In reply to Dave ChinnerQuoted 7 lines · Dave Chinner
xfs: remove
xfs_tosspagesFrom: Dave Chinner <[email protected]>
It's a buggy, unnecessary wrapper that is duplicating
truncate_pagecache_range().
Quoted 8 lines
When replacing the call in
xfs_change_file_space(), also ensure that the length being allocated/freed is always positive before making any changes. These checks are done in the lower extent manipulation functions, too, but we need to do them before any page cache operations.Reported-by Andrew Dahl <[email protected]>Signed-off-by Dave Chinner <[email protected]>
Looks good as long as Andrews fix is included.
I wonder if we should just fix the two places with checks for easy backportability in a first patch and then have a second on top to kill the useless wrapper?
Either way,
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 3/32 xfs: remove xfs_wait_on_pages()
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
It's just a simple wrapper around a VFS function that is only called by another function in xfs_fs_subr.c. Remove it and call the VFS function directly.
--- fs/xfs/xfs_fs_subr.c | 18 ++---------------- fs/xfs/xfs_vnodeops.h | 1 - 2 files changed, 2 insertions(+), 17 deletions(-)
fs/xfs/xfs_fs_subr.c +2 -16
@@ -62,23 +62,9 @@ xfs_flush_pages( last == -1 ? LLONG_MAX : last);if (flags &XBF_ASYNC )return ret; - ret2 =xfs_wait_on_pages (ip, first, last); + ret2 = -filemap_fdatawait_range (mapping, first, + last ==-1 ?XFS_ISIZE (ip) -1 : last);if (!ret) ret = ret2;return ret; } - -int -xfs_wait_on_pages ( -xfs_inode_t *ip, -xfs_off_t first, -xfs_off_t last) -{ -struct address_space *mapping =VFS_I (ip)->i_mapping; - -if (mapping_tagged (mapping,PAGECACHE_TAG_WRITEBACK )) { -return -filemap_fdatawait_range (mapping, first, - last ==-1 ?XFS_ISIZE (ip) -1 : last); - } -return 0 ; -}
fs/xfs/xfs_vnodeops.h +0 -1
@@ -52,7 +52,6 @@ int xfs_flushinval_pages(struct xfs_inode *ip, xfs_off_t first, xfs_off_t last, int fiopt);int xfs_flush_pages (struct xfs_inode *ip,xfs_off_t first,xfs_off_t last,uint64_t flags,int fiopt); -int xfs_wait_on_pages (struct xfs_inode *ip,xfs_off_t first,xfs_off_t last);int xfs_zero_eof (struct xfs_inode *,xfs_off_t ,xfs_fsize_t );int xfs_free_eofblocks (struct xfs_mount *,struct xfs_inode *,bool );
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 03/32] xfs: remove xfs_wait_on_pages()
Quoted 5 lines · Dave Chinner
From: Dave Chinner <[email protected]>
It's just a simple wrapper around a VFS function that is only called by another function in
xfs_fs_subr.c. Remove it and call the VFS function directly.
And what we really should do is call filemap_write_and_wait_range, but that fits into the later patches better (if you haven't done it already..)
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 4/32 xfs: remove xfs_flush_pages
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
It is a complex wrapper around VFS functions, but there are VFS functions that provide exactly the same functionality. Call the VFS functions directly and remove the unnecessary indirection and complexity.
We don't need to care about clearing the XFS_ITRUNCATED flag, as that is done during .writepages. Hence is cleared by the VFS writeback path if there is anything to write back during the flush.
--- fs/xfs/xfs_aops.c | 2 +- fs/xfs/xfs_bmap.c | 2 +- fs/xfs/xfs_fs_subr.c | 24 ------------------------ fs/xfs/xfs_iops.c | 4 ++-- fs/xfs/xfs_vnodeops.c | 7 +++++-- fs/xfs/xfs_vnodeops.h | 2 -- 6 files changed, 9 insertions(+), 32 deletions(-)
fs/xfs/xfs_aops.c +1 -1
@@ -1641,7 +1641,7 @@ xfs_vm_bmap(trace_xfs_vm_bmap (XFS_I (inode));xfs_ilock (ip,XFS_IOLOCK_SHARED ); -xfs_flush_pages (ip, (xfs_off_t )0 ,-1 ,0 ,FI_REMAPF ); +filemap_write_and_wait (mapping);xfs_iunlock (ip,XFS_IOLOCK_SHARED );return generic_block_bmap (mapping, block, xfs_get_blocks); }
fs/xfs/xfs_bmap.c +1 -1
@@ -5599,7 +5599,7 @@ xfs_getbmap(xfs_ilock (ip,XFS_IOLOCK_SHARED );if (whichfork ==XFS_DATA_FORK && !(iflags &BMV_IF_DELALLOC )) {if (ip->i_delayed_blks ||XFS_ISIZE (ip) > ip->i_d.di_size) { - error =xfs_flush_pages (ip,0 ,-1 ,0 ,FI_REMAPF ); + error = -filemap_write_and_wait (VFS_I (ip)->i_mapping);if (error) goto out_unlock_iolock; }
fs/xfs/xfs_fs_subr.c +0 -24
@@ -44,27 +44,3 @@ xfs_flushinval_pages(truncate_inode_pages_range (mapping, first, last);return -ret; } - -int -xfs_flush_pages ( -xfs_inode_t *ip, -xfs_off_t first, -xfs_off_t last, -uint64_t flags, -int fiopt) -{ -struct address_space *mapping =VFS_I (ip)->i_mapping; -int ret =0 ; -int ret2; - -xfs_iflags_clear (ip,XFS_ITRUNCATED ); - ret = -filemap_fdatawrite_range (mapping, first, - last ==-1 ?LLONG_MAX : last); -if (flags &XBF_ASYNC ) -return ret; - ret2 = -filemap_fdatawait_range (mapping, first, - last ==-1 ?XFS_ISIZE (ip) -1 : last); -if (!ret) - ret = ret2; -return ret; -}
fs/xfs/xfs_iops.c +2 -2
@@ -780,8 +780,8 @@ xfs_setattr_size(* care about here. */ if (oldsize != ip->i_d.di_size && newsize > ip->i_d.di_size) { - error =xfs_flush_pages (ip, ip->i_d.di_size, newsize,0 , -FI_NONE ); + error = -filemap_write_and_wait_range (VFS_I (ip)->i_mapping, + ip->i_d.di_size, newsize);if (error) goto out_unlock; }
fs/xfs/xfs_vnodeops.c +5 -2
@@ -428,8 +428,11 @@ xfs_release( truncated =xfs_iflags_test_and_clear (ip,XFS_ITRUNCATED );if (truncated) {xfs_iflags_clear (ip,XFS_IDIRTY_RELEASE ); -if (VN_DIRTY (VFS_I (ip)) && ip->i_delayed_blks >0 ) -xfs_flush_pages (ip,0 ,-1 ,XBF_ASYNC ,FI_NONE ); +if (VN_DIRTY (VFS_I (ip)) && ip->i_delayed_blks >0 ) { + error = -filemap_flush (VFS_I (ip)->i_mapping); +if (error) +return error; + } } }
fs/xfs/xfs_vnodeops.h +0 -2
@@ -50,8 +50,6 @@ int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, int flags, struct attrlist_cursor_kern *cursor);int xfs_flushinval_pages (struct xfs_inode *ip,xfs_off_t first,xfs_off_t last,int fiopt); -int xfs_flush_pages (struct xfs_inode *ip,xfs_off_t first, -xfs_off_t last,uint64_t flags,int fiopt);int xfs_zero_eof (struct xfs_inode *,xfs_off_t ,xfs_fsize_t );int xfs_free_eofblocks (struct xfs_mount *,struct xfs_inode *,bool );
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 04/32] xfs: remove xfs_flush_pages
Quoted 7 lines · Dave Chinner
From: Dave Chinner <[email protected]>
It is a complex wrapper around VFS functions, but there are VFS functions that provide exactly the same functionality. Call the VFS functions directly and remove the unnecessary indirection and complexity.
Quoted 5 lines
We don't need to care about clearing the
XFS_ITRUNCATEDflag, as that is done during .writepages. Hence is cleared by the VFS writeback path if there is anything to write back during the flush.Signed-off-by Dave Chinner <[email protected]>
Looks good,
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 5/32 xfs: remove xfs_flushinval_pages
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
It's just a simple wrapper around VFS functionality, and is actually bugging in that it doesn't remove mappings before invalidating the page cache. Remove it and replace it with the correct VFS functionality.
--- fs/xfs/Makefile | 1 - fs/xfs/xfs_dfrag.c | 10 ++++------ fs/xfs/xfs_file.c | 23 ++++++++++++----------- fs/xfs/xfs_fs_subr.c | 46 ---------------------------------------------- fs/xfs/xfs_vnodeops.c | 11 +++++------ fs/xfs/xfs_vnodeops.h | 2 -- 6 files changed, 21 insertions(+), 72 deletions(-) delete mode 100644 fs/xfs/xfs_fs_subr.c
fs/xfs/Makefile +0 -1
@@ -37,7 +37,6 @@ xfs-y += xfs_aops.o \ xfs_file.o \ xfs_filestream.o \ xfs_fsops.o \ - xfs_fs_subr.o \ xfs_globals.o \ xfs_icache.o \ xfs_ioctl.o \
fs/xfs/xfs_dfrag.c +4 -6
@@ -246,12 +246,10 @@ xfs_swap_extents( goto out_unlock; } -if (VN_CACHED (VFS_I (tip)) !=0 ) { - error =xfs_flushinval_pages (tip,0 ,-1 , -FI_REMAPF_LOCKED ); -if (error) - goto out_unlock; - } + error = -filemap_write_and_wait (VFS_I (ip)->i_mapping); +if (error) + goto out_unlock; +truncate_pagecache_range (VFS_I (ip),0 ,-1 );/* Verify O_DIRECT for ftmp */ if (VN_CACHED (VFS_I (tip)) !=0 ) {
fs/xfs/xfs_file.c +12 -11
@@ -255,15 +255,14 @@ xfs_file_aio_read(xfs_buftarg_t *target =XFS_IS_REALTIME_INODE (ip) ? mp->m_rtdev_targp : mp->m_ddev_targp; -if ((iocb->ki_pos & target->bt_smask) || - (size & target->bt_smask)) { -if (iocb->ki_pos ==i_size_read (inode)) +if ((pos & target->bt_smask) || (size & target->bt_smask)) { +if (pos ==i_size_read (inode))return 0 ;return -XFS_ERROR (EINVAL ); } } - n = mp->m_super->s_maxbytes - iocb->ki_pos; + n = mp->m_super->s_maxbytes - pos;if (n <=0 || size ==0 )return 0 ;
@@ -289,20 +288,21 @@ xfs_file_aio_read(xfs_rw_ilock (ip,XFS_IOLOCK_EXCL );if (inode->i_mapping->nrpages) { - ret = -xfs_flushinval_pages (ip, - (iocb->ki_pos &PAGE_CACHE_MASK ), --1 ,FI_REMAPF_LOCKED ); + ret = -filemap_write_and_wait_range ( +VFS_I (ip)->i_mapping, + pos,-1 );if (ret) {xfs_rw_iunlock (ip,XFS_IOLOCK_EXCL );return ret; } +truncate_pagecache_range (VFS_I (ip), pos,-1 ); }xfs_rw_ilock_demote (ip,XFS_IOLOCK_EXCL ); } -trace_xfs_file_read (ip, size, iocb->ki_pos, ioflags); +trace_xfs_file_read (ip, size, pos, ioflags); - ret =generic_file_aio_read (iocb, iovp, nr_segs, iocb->ki_pos); + ret =generic_file_aio_read (iocb, iovp, nr_segs, pos);if (ret >0 )XFS_STATS_ADD (xs_read_bytes, ret);
@@ -670,10 +670,11 @@ xfs_file_dio_aio_write( goto out;if (mapping->nrpages) { - ret = -xfs_flushinval_pages (ip, (pos &PAGE_CACHE_MASK ),-1 , -FI_REMAPF_LOCKED ); + ret = -filemap_write_and_wait_range (VFS_I (ip)->i_mapping, + pos,-1 );if (ret) goto out; +truncate_pagecache_range (VFS_I (ip), pos,-1 ); }/*
fs/xfs/xfs_fs_subr.c deleted +0 -46
46 lines not on this page · raw message
fs/xfs/xfs_vnodeops.c +5 -6
@@ -1958,12 +1958,11 @@ xfs_free_file_space( rounding =max_t (uint,1 << mp->m_sb.sb_blocklog,PAGE_CACHE_SIZE ); ioffset = offset & ~(rounding -1 ); - -if (VN_CACHED (VFS_I (ip)) !=0 ) { - error =xfs_flushinval_pages (ip, ioffset,-1 ,FI_REMAPF_LOCKED ); -if (error) - goto out_unlock_iolock; - } + error = -filemap_write_and_wait_range (VFS_I (ip)->i_mapping, + ioffset,-1 ); +if (error) + goto out_unlock_iolock; +truncate_pagecache_range (VFS_I (ip), ioffset,-1 );/* * Need to zero the stuff we're not freeing, on disk.
fs/xfs/xfs_vnodeops.h +0 -2
@@ -48,8 +48,6 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,int xfs_attr_remove (struct xfs_inode *dp,const unsigned char *name,int flags);int xfs_attr_list (struct xfs_inode *dp,char *buffer,int bufsize,int flags,struct attrlist_cursor_kern *cursor); -int xfs_flushinval_pages (struct xfs_inode *ip,xfs_off_t first, -xfs_off_t last,int fiopt);int xfs_zero_eof (struct xfs_inode *,xfs_off_t ,xfs_fsize_t );int xfs_free_eofblocks (struct xfs_mount *,struct xfs_inode *,bool );
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 05/32] xfs: remove xfs_flushinval_pages
fs/xfs/xfs_file.c xfs_file_aio_read( · line 265
Quoted 12 lines
fs/xfs/xfs_file.c +3
-4-if ((iocb->ki_pos & target->bt_smask) || - (size & target->bt_smask)) { -if (iocb->ki_pos ==i_size_read (inode)) +if ((pos & target->bt_smask) || (size & target->bt_smask)) { +if (pos ==i_size_read (inode))return 0 ;return -XFS_ERROR (EINVAL ); } } - n = mp->m_super->s_maxbytes - iocb->ki_pos; + n = mp->m_super->s_maxbytes - pos;
What does this have to do with the recent of the patch?
Not that is diapprove, but I don't think it fits here.
fs/xfs/xfs_file.c xfs_file_aio_read( · line 298
Quoted 12 lines
fs/xfs/xfs_file.c +4
-3if (inode->i_mapping->nrpages) { - ret = -xfs_flushinval_pages (ip, - (iocb->ki_pos &PAGE_CACHE_MASK ), --1 ,FI_REMAPF_LOCKED ); + ret = -filemap_write_and_wait_range ( +VFS_I (ip)->i_mapping, + pos,-1 );if (ret) {xfs_rw_iunlock (ip,XFS_IOLOCK_EXCL );return ret; } +truncate_pagecache_range (VFS_I (ip), pos,-1 );
We already have a local "inode" variable that can be used in these two places.
Also the -1 end might be a 1:1 translation of what was there, but is not what we really want. At very least it needs an XXX comment that the range should be revisited.
fs/xfs/xfs_file.c xfs_file_dio_aio_write( · line 677
Quoted 11 lines
fs/xfs/xfs_file.c +3
-2@@ -670,10 +670,11 @@ xfs_file_dio_aio_write( goto out;if (mapping->nrpages) { - ret = -xfs_flushinval_pages (ip, (pos &PAGE_CACHE_MASK ),-1 , -FI_REMAPF_LOCKED ); + ret = -filemap_write_and_wait_range (VFS_I (ip)->i_mapping, + pos,-1 );if (ret) goto out; +truncate_pagecache_range (VFS_I (ip), pos,-1 );
We already have local mapping and inode variables here, same comment about the -1 len.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 05/32] xfs: remove xfs_flushinval_pages
Quoted 10 lines · Christoph Hellwig
Quoted 10 lines
fs/xfs/xfs_file.c +2
-3-if ((iocb->ki_pos & target->bt_smask) || - (size & target->bt_smask)) { -if (iocb->ki_pos ==i_size_read (inode)) +if ((pos & target->bt_smask) || (size & target->bt_smask)) { +if (pos ==i_size_read (inode))return 0 ;return -XFS_ERROR (EINVAL ); } }
Quoted 4 lines
fs/xfs/xfs_file.c xfs_file_aio_read( · line 265
Quoted 2 lines
fs/xfs/xfs_file.c +1
-1- n = mp->m_super->s_maxbytes - iocb->ki_pos; + n = mp->m_super->s_maxbytes - pos;What does this have to do with the recent of the patch?
Left over from an original version of the patch that also changed the ranges of the flushes.
Quoted 17 lines
Not that is diapprove, but I don't think it fits here.
fs/xfs/xfs_file.c xfs_file_aio_read( · line 298
Quoted 12 lines
fs/xfs/xfs_file.c +4
-3if (inode->i_mapping->nrpages) { - ret = -xfs_flushinval_pages (ip, - (iocb->ki_pos &PAGE_CACHE_MASK ), --1 ,FI_REMAPF_LOCKED ); + ret = -filemap_write_and_wait_range ( +VFS_I (ip)->i_mapping, + pos,-1 );if (ret) {xfs_rw_iunlock (ip,XFS_IOLOCK_EXCL );return ret; } +truncate_pagecache_range (VFS_I (ip), pos,-1 );We already have a local "inode" variable that can be used in these two places.
Ah, copy-n-waste problem.
Quoted 3 lines
Also the -1 end might be a 1:1 translation of what was there, but is not what we really want. At very least it needs an XXX comment that the range should be revisited.
Yes, I know, but the original patch I had that changed the ranges to something sensible was causing fsx and other failures all over the place. It appears that setting the ranges appropriately here exposes other (worse) bugs, so I decided to leave doing that until I have time to go on a wild goose chase....
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 05/32] xfs: remove xfs_flushinval_pages
Quoted 5 lines · Dave Chinner
Yes, I know, but the original patch I had that changed the ranges to something sensible was causing fsx and other failures all over the place. It appears that setting the ranges appropriately here exposes other (worse) bugs, so I decided to leave doing that until I have time to go on a wild goose chase....
I'm actually very happy with doing it separately, I just really prefer comments to be put in place on why it's done the way it is in case we forget about it again, which history has shown to happen way too often.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 6/32 xfs: use btree block initialisation functions in growfs
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Factor xfs_btree_init_block() to be independent of the btree cursor, and use the function to initialise btree blocks in the growfs code. This makes adding support for different format btree blocks simple.
--- fs/xfs/xfs_btree.c | 33 ++++++++++++++++++++++++--------- fs/xfs/xfs_btree.h | 11 +++++++++++ fs/xfs/xfs_fsops.c | 37 +++++++++++++------------------------ 3 files changed, 48 insertions(+), 33 deletions(-)
fs/xfs/xfs_btree.c +24 -9
@@ -853,18 +853,22 @@ xfs_btree_set_sibling( } } -STATIC void +void xfs_btree_init_block ( -struct xfs_btree_cur *cur, -int level, -int numrecs, -struct xfs_btree_block *new)/* new block */ +struct xfs_mount *mp, +struct xfs_buf *bp, +__u32 magic, +__u16 level, +__u16 numrecs, +unsigned int flags) { - new->bb_magic =cpu_to_be32 (xfs_magics[cur->bc_btnum]); +struct xfs_btree_block *new =XFS_BUF_TO_BLOCK (bp); + + new->bb_magic =cpu_to_be32 (magic); new->bb_level =cpu_to_be16 (level); new->bb_numrecs =cpu_to_be16 (numrecs); -if (cur->bc_flags &XFS_BTREE_LONG_PTRS ) { +if (flags &XFS_BTREE_LONG_PTRS ) { new->bb_u.l.bb_leftsib =cpu_to_be64 (NULLDFSBNO ); new->bb_u.l.bb_rightsib =cpu_to_be64 (NULLDFSBNO ); }else {
@@ -873,6 +877,17 @@ xfs_btree_init_block( } } +STATIC void +xfs_btree_init_block_cur ( +struct xfs_btree_cur *cur, +int level, +int numrecs, +struct xfs_buf *bp) +{ +xfs_btree_init_block (cur->bc_mp, bp, xfs_magics[cur->bc_btnum], + level, numrecs, cur->bc_flags); +} +/* * Return true if ptr is the last record in the btree and * we need to track updateѕ to this record. The decision
@@ -2183,7 +2198,7 @@ xfs_btree_split( goto error0;/* Fill in the btree header for the new right block. */ -xfs_btree_init_block (cur,xfs_btree_get_level (left),0 , right); +xfs_btree_init_block_cur (cur,xfs_btree_get_level (left),0 , rbp);/* * Split the entries between the old and the new block evenly.
@@ -2492,7 +2507,7 @@ xfs_btree_new_root( nptr =2 ; }/* Fill in the new block's btree header and log it. */ -xfs_btree_init_block (cur, cur->bc_nlevels,2 , new); +xfs_btree_init_block_cur (cur, cur->bc_nlevels,2 , nbp);xfs_btree_log_block (cur, nbp,XFS_BB_ALL_BITS );ASSERT (!xfs_btree_ptr_is_null (cur, &lptr) && !xfs_btree_ptr_is_null (cur, &rptr));
fs/xfs/xfs_btree.h +11 -0
@@ -378,6 +378,17 @@ xfs_btree_reada_bufs(xfs_agblock_t agbno,/* allocation group block number */ xfs_extlen_t count); /* count of filesystem blocks */ +/* +* Initialise a new btree block header +*/ +void +xfs_btree_init_block ( +struct xfs_mount *mp, +struct xfs_buf *bp, +__u32 magic, +__u16 level, +__u16 numrecs, +unsigned int flags);/* * Common btree core entry points.
fs/xfs/xfs_fsops.c +13 -24
@@ -125,7 +125,6 @@ xfs_growfs_data_private(xfs_extlen_t agsize;xfs_extlen_t tmpsize;xfs_alloc_rec_t *arec; -struct xfs_btree_block *block;xfs_buf_t *bp;int bucket;int dpct;
@@ -263,17 +262,14 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } - block =XFS_BUF_TO_BLOCK (bp); -memset (block,0 , mp->m_sb.sb_blocksize); - block->bb_magic =cpu_to_be32 (XFS_ABTB_MAGIC ); - block->bb_level =0 ; - block->bb_numrecs =cpu_to_be16 (1 ); - block->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); - block->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK ); - arec =XFS_ALLOC_REC_ADDR (mp, block,1 ); +xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); +xfs_btree_init_block (mp, bp,XFS_ABTB_MAGIC ,0 ,1 ,0 ); + + arec =XFS_ALLOC_REC_ADDR (mp,XFS_BUF_TO_BLOCK (bp),1 ); arec->ar_startblock =cpu_to_be32 (XFS_PREALLOC_BLOCKS (mp)); arec->ar_blockcount =cpu_to_be32 ( agsize -be32_to_cpu (arec->ar_startblock)); + error =xfs_bwrite (bp);xfs_buf_relse (bp);if (error)
@@ -289,18 +285,15 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } - block =XFS_BUF_TO_BLOCK (bp); -memset (block,0 , mp->m_sb.sb_blocksize); - block->bb_magic =cpu_to_be32 (XFS_ABTC_MAGIC ); - block->bb_level =0 ; - block->bb_numrecs =cpu_to_be16 (1 ); - block->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); - block->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK ); - arec =XFS_ALLOC_REC_ADDR (mp, block,1 ); +xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); +xfs_btree_init_block (mp, bp,XFS_ABTC_MAGIC ,0 ,1 ,0 ); + + arec =XFS_ALLOC_REC_ADDR (mp,XFS_BUF_TO_BLOCK (bp),1 ); arec->ar_startblock =cpu_to_be32 (XFS_PREALLOC_BLOCKS (mp)); arec->ar_blockcount =cpu_to_be32 ( agsize -be32_to_cpu (arec->ar_startblock)); nfree +=be32_to_cpu (arec->ar_blockcount); + error =xfs_bwrite (bp);xfs_buf_relse (bp);if (error)
@@ -316,13 +309,9 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } - block =XFS_BUF_TO_BLOCK (bp); -memset (block,0 , mp->m_sb.sb_blocksize); - block->bb_magic =cpu_to_be32 (XFS_IBT_MAGIC ); - block->bb_level =0 ; - block->bb_numrecs =0 ; - block->bb_u.s.bb_leftsib =cpu_to_be32 (NULLAGBLOCK ); - block->bb_u.s.bb_rightsib =cpu_to_be32 (NULLAGBLOCK ); +xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); +xfs_btree_init_block (mp, bp,XFS_IBT_MAGIC ,0 ,0 ,0 ); + error =xfs_bwrite (bp);xfs_buf_relse (bp);if (error)
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 06/32] xfs: use btree block initialisation functions in growfs
Quoted 6 lines · Dave Chinner
From: Dave Chinner <[email protected]>
Factor
xfs_btree_init_block()to be independent of the btree cursor, and use the function to initialise btree blocks in the growfs code. This makes adding support for different format btree blocks simple.
Quoted 7 lines
Signed-off-by Dave Chinner <[email protected]>--- fs/xfs/xfs_btree.c | 33 ++++++++++++++++++++++++--------- fs/xfs/xfs_btree.h | 11 +++++++++++ fs/xfs/xfs_fsops.c | 37 +++++++++++++------------------------ 3 files changed, 48 insertions(+), 33 deletions(-)
Looks good.
Reviewed-by Rich Johnston <[email protected]>
--Rich
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 06/32] xfs: use btree block initialisation functions in growfs
In reply to Dave ChinnerQuoted 20 lines · Dave Chinner
From: Dave Chinner <[email protected]>
Factor
xfs_btree_init_block()to be independent of the btree cursor, and use the function to initialise btree blocks in the growfs code. This makes adding support for different format btree blocks simple.Signed-off-by Dave Chinner <[email protected]>--- fs/xfs/xfs_btree.c | 33 ++++++++++++++++++++++++--------- fs/xfs/xfs_btree.h | 11 +++++++++++ fs/xfs/xfs_fsops.c | 37 +++++++++++++------------------------ 3 files changed, 48 insertions(+), 33 deletions(-)fs/xfs/xfs_btree.c +0
-0@@ -853,18 +853,22 @@ xfs_btree_set_sibling( } }
fs/xfs/xfs_btree.c xfs_btree_set_sibling( · line 859
Quoted 10 lines
fs/xfs/xfs_btree.c +3
-5-STATIC void +void xfs_btree_init_block( -struct xfs_btree_cur *cur, -int level, -int numrecs, -struct xfs_btree_block *new)/* new block */ + struct xfs_mount *mp, + struct xfs_buf *bp,
Do we need the mount argument here? bp->b_mount should always be initialized.
fs/xfs/xfs_btree.c xfs_btree_set_sibling( · line 865
Quoted 7 lines
fs/xfs/xfs_btree.c +5
-1+__u32 magic, + __u16 level, + __u16 numrecs, + unsigned int flags) { - new->bb_magic =cpu_to_be32 (xfs_magics[cur->bc_btnum]); + struct xfs_btree_block *new = XFS_BUF_TO_BLOCK(bp);
Any reaosn not to pass the btree_block directly instead of the buffer?
fs/xfs/xfs_btree.c xfs_btree_init_block( · line 888
Quoted 9 lines
fs/xfs/xfs_btree.c +9
-0+STATIC void +xfs_btree_init_block_cur ( +struct xfs_btree_cur *cur, +int level, +int numrecs, +struct xfs_buf *bp) +{ +xfs_btree_init_block (cur->bc_mp, bp, xfs_magics[cur->bc_btnum], + level, numrecs, cur->bc_flags);
I'd scrapt this helper.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 06/32] xfs: use btree block initialisation functions in growfs
Quoted 22 lines · Christoph Hellwig
Quoted 21 lines · Dave Chinner
From: Dave Chinner <[email protected]>
Factor
xfs_btree_init_block()to be independent of the btree cursor, and use the function to initialise btree blocks in the growfs code. This makes adding support for different format btree blocks simple.Signed-off-by Dave Chinner <[email protected]>--- fs/xfs/xfs_btree.c | 33 ++++++++++++++++++++++++--------- fs/xfs/xfs_btree.h | 11 +++++++++++ fs/xfs/xfs_fsops.c | 37 +++++++++++++------------------------ 3 files changed, 48 insertions(+), 33 deletions(-)fs/xfs/xfs_btree.c +0
-0@@ -853,18 +853,22 @@ xfs_btree_set_sibling( } }
Quoted 12 lines
fs/xfs/xfs_btree.c xfs_btree_set_sibling( · line 859
Quoted 9 lines
fs/xfs/xfs_btree.c +3
-5-STATIC void +void xfs_btree_init_block( -struct xfs_btree_cur *cur, -int level, -int numrecs, -struct xfs_btree_block *new)/* new block */ + struct xfs_mount *mp, + struct xfs_buf *bp,Do we need the mount argument here?
bp->b_mountshould always be initialized.
Possible.
Quoted 9 lines
fs/xfs/xfs_btree.c xfs_btree_set_sibling( · line 865
Quoted 7 lines
fs/xfs/xfs_btree.c +5
-1+__u32 magic, + __u16 level, + __u16 numrecs, + unsigned int flags) { - new->bb_magic =cpu_to_be32 (xfs_magics[cur->bc_btnum]); + struct xfs_btree_block *new = XFS_BUF_TO_BLOCK(bp);Any reaosn not to pass the
btree_blockdirectly instead of the buffer?
CRC additions require the block number to be put into the structure, so we need to pass the buffer.
Quoted 12 lines
fs/xfs/xfs_btree.c xfs_btree_init_block( · line 888
Quoted 10 lines
fs/xfs/xfs_btree.c +9
-0+STATIC void +xfs_btree_init_block_cur ( +struct xfs_btree_cur *cur, +int level, +int numrecs, +struct xfs_buf *bp) +{ +xfs_btree_init_block (cur->bc_mp, bp, xfs_magics[cur->bc_btnum], + level, numrecs, cur->bc_flags);I'd scrapt this helper.
I only used it to avoid changing existing code. I can remove it when CRCs are introduced if you want, as this touches all this code again.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 7/32 xfs: growfs: use uncached buffers for new headers
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
When writing the new AG headers to disk, we can't attach write verifiers because they have a dependency on the struct xfs-perag being attached to the buffer to be fully initialised and growfs can't fully initialise them until later in the process.
The simplest way to avoid this problem is to use uncached buffers for writing the new headers. These buffers don't have the xfs-perag attached to them, so it's simple to detect in the write verifier and be able to skip the checks that need the xfs-perag.
This enables us to attach the appropriate buffer ops to the buffer and hence calculate CRCs on the way to disk. IT also means that the buffer is torn down immediately, and so the first access to the AG headers will re-read the header from disk and perform full verification of the buffer. This way we also can catch corruptions due to problems that went undetected in growfs.
--- fs/xfs/xfs_fsops.c | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 22 deletions(-)
fs/xfs/xfs_fsops.c +41 -22
@@ -114,6 +114,26 @@ xfs_fs_geometry(return 0 ; } +static struct xfs_buf * +xfs_growfs_get_hdr_buf ( +struct xfs_mount *mp, +xfs_daddr_t blkno, +size_t numblks, +int flags) +{ +struct xfs_buf *bp; + + bp =xfs_buf_get_uncached (mp->m_ddev_targp, numblks, flags); +if (!bp) +return NULL ; + +xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); + bp->b_bn = blkno; + bp->b_maps[0 ].bm_bn = blkno; + +return bp; +} + static int xfs_growfs_data_private( xfs_mount_t *mp, /* mount point for filesystem */
@@ -189,15 +209,15 @@ xfs_growfs_data_private(/* * AG freelist header block */ - bp =xfs_buf_get (mp->m_ddev_targp, -XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); + bp =xfs_growfs_get_hdr_buf (mp, +XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), +XFS_FSS_TO_BB (mp,1 ),0 );if (!bp) { error =ENOMEM ; goto error0; } + agf =XFS_BUF_TO_AGF (bp); -memset (agf,0 , mp->m_sb.sb_sectsize); agf->agf_magicnum =cpu_to_be32 (XFS_AGF_MAGIC ); agf->agf_versionnum =cpu_to_be32 (XFS_AGF_VERSION ); agf->agf_seqno =cpu_to_be32 (agno);
@@ -226,15 +246,15 @@ xfs_growfs_data_private(/* * AG inode header block */ - bp =xfs_buf_get (mp->m_ddev_targp, -XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); + bp =xfs_growfs_get_hdr_buf (mp, +XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), +XFS_FSS_TO_BB (mp,1 ),0 );if (!bp) { error =ENOMEM ; goto error0; } + agi =XFS_BUF_TO_AGI (bp); -memset (agi,0 , mp->m_sb.sb_sectsize); agi->agi_magicnum =cpu_to_be32 (XFS_AGI_MAGIC ); agi->agi_versionnum =cpu_to_be32 (XFS_AGI_VERSION ); agi->agi_seqno =cpu_to_be32 (agno);
@@ -255,16 +275,16 @@ xfs_growfs_data_private(/* * BNO btree root block */ - bp =xfs_buf_get (mp->m_ddev_targp, -XFS_AGB_TO_DADDR (mp, agno,XFS_BNO_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); + bp =xfs_growfs_get_hdr_buf (mp, +XFS_AGB_TO_DADDR (mp, agno,XFS_BNO_BLOCK (mp)), +BTOBB (mp->m_sb.sb_blocksize),0 ); +if (!bp) { error =ENOMEM ; goto error0; } -xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); -xfs_btree_init_block (mp, bp,XFS_ABTB_MAGIC ,0 ,1 ,0 ); +xfs_btree_init_block (mp, bp,XFS_ABTB_MAGIC ,0 ,1 ,0 ); arec =XFS_ALLOC_REC_ADDR (mp,XFS_BUF_TO_BLOCK (bp),1 ); arec->ar_startblock =cpu_to_be32 (XFS_PREALLOC_BLOCKS (mp)); arec->ar_blockcount = cpu_to_be32(
@@ -278,16 +298,15 @@ xfs_growfs_data_private(/* * CNT btree root block */ - bp =xfs_buf_get (mp->m_ddev_targp, -XFS_AGB_TO_DADDR (mp, agno,XFS_CNT_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); + bp =xfs_growfs_get_hdr_buf (mp, +XFS_AGB_TO_DADDR (mp, agno,XFS_CNT_BLOCK (mp)), +BTOBB (mp->m_sb.sb_blocksize),0 );if (!bp) { error =ENOMEM ; goto error0; } -xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); -xfs_btree_init_block (mp, bp,XFS_ABTC_MAGIC ,0 ,1 ,0 ); +xfs_btree_init_block (mp, bp,XFS_ABTC_MAGIC ,0 ,1 ,0 ); arec =XFS_ALLOC_REC_ADDR (mp,XFS_BUF_TO_BLOCK (bp),1 ); arec->ar_startblock =cpu_to_be32 (XFS_PREALLOC_BLOCKS (mp)); arec->ar_blockcount = cpu_to_be32(
@@ -302,14 +321,14 @@ xfs_growfs_data_private(/* * INO btree root block */ - bp =xfs_buf_get (mp->m_ddev_targp, -XFS_AGB_TO_DADDR (mp, agno,XFS_IBT_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); + bp =xfs_growfs_get_hdr_buf (mp, +XFS_AGB_TO_DADDR (mp, agno,XFS_IBT_BLOCK (mp)), +BTOBB (mp->m_sb.sb_blocksize),0 );if (!bp) { error =ENOMEM ; goto error0; } -xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); +xfs_btree_init_block (mp, bp,XFS_IBT_MAGIC ,0 ,0 ,0 ); error =xfs_bwrite (bp);
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 07/32] xfs: growfs: use uncached buffers for new headers
Quoted 19 lines · Dave Chinner
From: Dave Chinner <[email protected]>
When writing the new AG headers to disk, we can't attach write verifiers because they have a dependency on the struct xfs-perag being attached to the buffer to be fully initialised and growfs can't fully initialise them until later in the process.
The simplest way to avoid this problem is to use uncached buffers for writing the new headers. These buffers don't have the xfs-perag attached to them, so it's simple to detect in the write verifier and be able to skip the checks that need the xfs-perag.
This enables us to attach the appropriate buffer ops to the buffer and hence calculate CRCs on the way to disk. IT also means that the buffer is torn down immediately, and so the first access to the AG headers will re-read the header from disk and perform full verification of the buffer. This way we also can catch corruptions due to problems that went undetected in growfs.
Quoted 5 lines
Signed-off-by Dave Chinner <[email protected]>--- fs/xfs/xfs_fsops.c | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 22 deletions(-)
Looks good.
Reviewed-by Rich Johnston <[email protected]>
--Rich
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 8/32 xfs: make growfs initialise the AGFL header
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
For verification purposes, AGFLs need to be initialised to a known set of values. For upcoming CRC changes, they are also headers that need to be initialised. Currently, growfs does neither for the AGFLs
- it ignores them completely. Add initialisation of the AGFL to be full of invalid block numbers (NULLAGBLOCK) to put the infrastructure in place needed for CRC support.
Includes a comment clarification from Jeff Liu.
--- fs/xfs/xfs_fsops.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
fs/xfs/xfs_fsops.c +22 -1
@@ -140,6 +140,7 @@ xfs_growfs_data_private( xfs_growfs_data_t *in) /* growfs data input struct */ {xfs_agf_t *agf; +struct xfs_agfl *agfl;xfs_agi_t *agi;xfs_agnumber_t agno;xfs_extlen_t agsize;
@@ -207,7 +208,7 @@ xfs_growfs_data_private( nfree =0 ;for (agno = nagcount -1 ; agno >= oagcount; agno--, new -= agsize) {/* -* AG freelist header block +* AG freespace header block */ bp = xfs_growfs_get_hdr_buf(mp, XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
@@ -244,6 +245,26 @@ xfs_growfs_data_private( goto error0;/* +* AG freelist header block +*/ + bp =xfs_growfs_get_hdr_buf (mp, +XFS_AG_DADDR (mp, agno,XFS_AGFL_DADDR (mp)), +XFS_FSS_TO_BB (mp,1 ),0 ); +if (!bp) { + error =ENOMEM ; + goto error0; + } + + agfl =XFS_BUF_TO_AGFL (bp); +for (bucket =0 ; bucket <XFS_AGFL_SIZE (mp); bucket++) + agfl->agfl_bno[bucket] =cpu_to_be32 (NULLAGBLOCK ); + + error =xfs_bwrite (bp); +xfs_buf_relse (bp); +if (error) + goto error0; + +/* * AG inode header block */ bp = xfs_growfs_get_hdr_buf(mp,
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 08/32] xfs: make growfs initialise the AGFL header
Quoted 9 lines · Dave Chinner
From: Dave Chinner <[email protected]>
For verification purposes, AGFLs need to be initialised to a known set of values. For upcoming CRC changes, they are also headers that need to be initialised. Currently, growfs does neither for the AGFLs
- it ignores them completely. Add initialisation of the AGFL to be full of invalid block numbers (NULLAGBLOCK) to put the infrastructure in place needed for CRC support.
Quoted 7 lines
Includes a comment clarification from Jeff Liu.
Signed-off-by Dave Chinner <[email protected]>--- fs/xfs/xfs_fsops.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
Looks good.
Reviewed-by Rich Johnston <[email protected]>
--Rich
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 08/32] xfs: make growfs initialise the AGFL header
In reply to Dave ChinnerQuoted 10 lines · Dave Chinner
From: Dave Chinner <[email protected]>
For verification purposes, AGFLs need to be initialised to a known set of values. For upcoming CRC changes, they are also headers that need to be initialised. Currently, growfs does neither for the AGFLs
- it ignores them completely. Add initialisation of the AGFL to be full of invalid block numbers (NULLAGBLOCK) to put the infrastructure in place needed for CRC support.Includes a comment clarification from Jeff Liu.
Looks good.
If you plan to touch this code even more I'd suggst splitting out a helper for each kinda of block / header that is initialized from xfs_growfs_data_private.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 08/32] xfs: make growfs initialise the AGFL header
Quoted 10 lines · Christoph Hellwig
Quoted 9 lines · Dave Chinner
From: Dave Chinner <[email protected]>
For verification purposes, AGFLs need to be initialised to a known set of values. For upcoming CRC changes, they are also headers that need to be initialised. Currently, growfs does neither for the AGFLs
- it ignores them completely. Add initialisation of the AGFL to be full of invalid block numbers (NULLAGBLOCK) to put the infrastructure in place needed for CRC support.
Quoted 7 lines
Quoted 1 line
Includes a comment clarification from Jeff Liu.
Looks good.
If you plan to touch this code even more I'd suggst splitting out a helper for each kinda of block / header that is initialized from
xfs_growfs_data_private.
I thought about doing that, but in the end I wanted to avoid structural changes as much as possible. As it is, I do need to touch bits of it for the CRC code - refactoring it will involve rebasing several patches though... :/
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 9/32 xfs: make buffer read verication an IO completion function
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add a verifier function callback capability to the buffer read interfaces. This will be used by the callers to supply a function that verifies the contents of the buffer when it is read from disk. This patch does not provide callback functions, but simply modifies the interfaces to allow them to be called.
The reason for adding this to the read interfaces is that it is very difficult to tell fom the outside is a buffer was just read from disk or whether we just pulled it out of cache. Supplying a callbck allows the buffer cache to use it's internal knowledge of the buffer to execute it only when the buffer is read from disk.
It is intended that the verifier functions will mark the buffer with an EFSCORRUPTED error when verification fails. This allows the reading context to distinguish a verification error from an IO error, and potentially take further actions on the buffer (e.g. attempt repair) based on the error reported.
--- fs/xfs/xfs_alloc.c | 4 ++-- fs/xfs/xfs_attr.c | 2 +- fs/xfs/xfs_btree.c | 21 ++++++++++++--------- fs/xfs/xfs_buf.c | 13 +++++++++---- fs/xfs/xfs_buf.h | 20 ++++++++++++-------- fs/xfs/xfs_da_btree.c | 4 ++-- fs/xfs/xfs_dir2_leaf.c | 2 +- fs/xfs/xfs_dquot.c | 4 ++-- fs/xfs/xfs_fsops.c | 4 ++-- fs/xfs/xfs_ialloc.c | 2 +- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_log.c | 3 +-- fs/xfs/xfs_log_recover.c | 8 +++++--- fs/xfs/xfs_mount.c | 6 +++--- fs/xfs/xfs_qm.c | 5 +++-- fs/xfs/xfs_rtalloc.c | 6 +++--- fs/xfs/xfs_trans.h | 19 ++++++++----------- fs/xfs/xfs_trans_buf.c | 9 ++++++--- fs/xfs/xfs_vnodeops.c | 2 +- 19 files changed, 75 insertions(+), 61 deletions(-)
fs/xfs/xfs_alloc.c +2 -2
@@ -447,7 +447,7 @@ xfs_alloc_read_agfl( error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGFL_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , &bp); +XFS_FSS_TO_BB (mp,1 ),0 , &bp,NULL );if (error)return error;ASSERT (!xfs_buf_geterror (bp));
@@ -2110,7 +2110,7 @@ xfs_read_agf( error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ), flags, bpp); +XFS_FSS_TO_BB (mp,1 ), flags, bpp,NULL );if (error)return error;if (!*bpp)
fs/xfs/xfs_attr.c +1 -1
@@ -1994,7 +1994,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args) dblkno =XFS_FSB_TO_DADDR (mp, map[i].br_startblock); blkcnt =XFS_FSB_TO_BB (mp, map[i].br_blockcount); error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp, - dblkno, blkcnt,0 , &bp); + dblkno, blkcnt,0 , &bp,NULL );if (error)return (error);
fs/xfs/xfs_btree.c +12 -9
@@ -266,9 +266,12 @@ xfs_btree_dup_cursor(for (i =0 ; i < new->bc_nlevels; i++) { new->bc_ptrs[i] = cur->bc_ptrs[i]; new->bc_ra[i] = cur->bc_ra[i]; -if ((bp = cur->bc_bufs[i])) { -if ((error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, -XFS_BUF_ADDR (bp), mp->m_bsize,0 , &bp))) { + bp = cur->bc_bufs[i]; +if (bp) { + error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, +XFS_BUF_ADDR (bp), mp->m_bsize, +0 , &bp,NULL ); +if (error) {xfs_btree_del_cursor (new, error); *ncur =NULL ;return error;
@@ -624,10 +627,10 @@ xfs_btree_read_bufl(ASSERT (fsbno !=NULLFSBLOCK ); d =XFS_FSB_TO_DADDR (mp, fsbno); -if ((error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, d, - mp->m_bsize, lock, &bp))) { + error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, d, + mp->m_bsize, lock, &bp,NULL ); +if (error)return error; - }ASSERT (!xfs_buf_geterror (bp));if (bp)xfs_buf_set_ref (bp, refval);
@@ -650,7 +653,7 @@ xfs_btree_reada_bufl(ASSERT (fsbno !=NULLFSBLOCK ); d =XFS_FSB_TO_DADDR (mp, fsbno); -xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count); +xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count,NULL ); }/*
@@ -670,7 +673,7 @@ xfs_btree_reada_bufs(ASSERT (agno !=NULLAGNUMBER );ASSERT (agbno !=NULLAGBLOCK ); d =XFS_AGB_TO_DADDR (mp, agno, agbno); -xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count); +xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count,NULL ); }STATIC int
@@ -1013,7 +1016,7 @@ xfs_btree_read_buf_block( d =xfs_btree_ptr_to_daddr (cur, ptr); error =xfs_trans_read_buf (mp, cur->bc_tp, mp->m_ddev_targp, d, - mp->m_bsize, flags, bpp); + mp->m_bsize, flags, bpp,NULL );if (error)return error;
fs/xfs/xfs_buf.c +9 -4
@@ -654,7 +654,8 @@ xfs_buf_read_map(struct xfs_buftarg *target, struct xfs_buf_map *map, int nmaps, - xfs_buf_flags_t flags) + xfs_buf_flags_t flags, + xfs_buf_iodone_t verify) { struct xfs_buf *bp;
@@ -666,6 +667,7 @@ xfs_buf_read_map(if (!XFS_BUF_ISDONE (bp)) {XFS_STATS_INC (xb_get_read); + bp->b_iodone = verify;_xfs_buf_read (bp, flags); }else if (flags &XBF_ASYNC ) {/*
@@ -691,13 +693,14 @@ voidxfs_buf_readahead_map ( struct xfs_buftarg *target, struct xfs_buf_map *map, - int nmaps) + int nmaps, + xfs_buf_iodone_t verify) { if (bdi_read_congested(target->bt_bdi)) return;xfs_buf_read_map (target, map, nmaps, -XBF_TRYLOCK |XBF_ASYNC |XBF_READ_AHEAD ); +XBF_TRYLOCK |XBF_ASYNC |XBF_READ_AHEAD , verify); }/*
@@ -709,7 +712,8 @@ xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr, size_t numblks, - int flags) + int flags, + xfs_buf_iodone_t verify) { xfs_buf_t *bp;int error;
@@ -723,6 +727,7 @@ xfs_buf_read_uncached( bp->b_bn = daddr; bp->b_maps[0 ].bm_bn = daddr; bp->b_flags |=XBF_READ ; + bp->b_iodone = verify;xfsbdstrat (target->bt_mount, bp); error =xfs_buf_iowait (bp);
fs/xfs/xfs_buf.h +12 -8
@@ -100,6 +100,7 @@ typedef struct xfs_buftarg {struct xfs_buf ;typedef void (*xfs_buf_iodone_t )(struct xfs_buf *); +#define XB_PAGES 2struct xfs_buf_map {
@@ -159,7 +160,6 @@ typedef struct xfs_buf {#endif } xfs_buf_t; -/* Finding and Reading Buffers */ struct xfs_buf *_xfs_buf_find(struct xfs_buftarg *target, struct xfs_buf_map *map, int nmaps,
@@ -196,9 +196,10 @@ struct xfs_buf *xfs_buf_get_map(struct xfs_buftarg *target, xfs_buf_flags_t flags);struct xfs_buf *xfs_buf_read_map (struct xfs_buftarg *target,struct xfs_buf_map *map,int nmaps, -xfs_buf_flags_t flags); +xfs_buf_flags_t flags,xfs_buf_iodone_t verify);void xfs_buf_readahead_map (struct xfs_buftarg *target, -struct xfs_buf_map *map,int nmaps); +struct xfs_buf_map *map,int nmaps, +xfs_buf_iodone_t verify);static inline struct xfs_buf * xfs_buf_get(
@@ -216,20 +217,22 @@ xfs_buf_read(struct xfs_buftarg *target, xfs_daddr_t blkno, size_t numblks, - xfs_buf_flags_t flags) + xfs_buf_flags_t flags, + xfs_buf_iodone_t verify) {DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks ); -return xfs_buf_read_map (target, &map,1 , flags); +return xfs_buf_read_map (target, &map,1 , flags, verify); }static inline void xfs_buf_readahead (struct xfs_buftarg *target,xfs_daddr_t blkno, -size_t numblks) +size_t numblks, +xfs_buf_iodone_t verify) {DEFINE_SINGLE_BUF_MAP (map, blkno, numblks); -return xfs_buf_readahead_map (target, &map,1 ); +return xfs_buf_readahead_map (target, &map,1 , verify); }struct xfs_buf *xfs_buf_get_empty (struct xfs_buftarg *target,size_t numblks);
@@ -239,7 +242,8 @@ int xfs_buf_associate_memory(struct xfs_buf *bp, void *mem, size_t length);struct xfs_buf *xfs_buf_get_uncached (struct xfs_buftarg *target,size_t numblks,int flags);struct xfs_buf *xfs_buf_read_uncached (struct xfs_buftarg *target, -xfs_daddr_t daddr,size_t numblks,int flags); +xfs_daddr_t daddr,size_t numblks,int flags, +xfs_buf_iodone_t verify);void xfs_buf_hold (struct xfs_buf *bp);/* Releasing Buffers */
fs/xfs/xfs_da_btree.c +2 -2
@@ -2161,7 +2161,7 @@ xfs_da_read_buf( error =xfs_trans_read_buf_map (dp->i_mount, trans, dp->i_mount->m_ddev_targp, - mapp, nmap,0 , &bp); + mapp, nmap,0 , &bp,NULL );if (error) goto out_free;
@@ -2237,7 +2237,7 @@ xfs_da_reada_buf( } mappedbno = mapp[0 ].bm_bn; -xfs_buf_readahead_map (dp->i_mount->m_ddev_targp, mapp, nmap); +xfs_buf_readahead_map (dp->i_mount->m_ddev_targp, mapp, nmap,NULL ); out_free:if (mapp != &map)
fs/xfs/xfs_dir2_leaf.c +1 -1
@@ -926,7 +926,7 @@ xfs_dir2_leaf_readbuf(XFS_FSB_TO_DADDR (mp, map[mip->ra_index].br_startblock + mip->ra_offset), - (int)BTOBB(mp->m_dirblksize)); + (int)BTOBB(mp->m_dirblksize), NULL); mip->ra_current = i; }
fs/xfs/xfs_dquot.c +2 -2
@@ -439,7 +439,7 @@ xfs_qm_dqtobp( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, -0 , &bp); +0 , &bp,NULL );if (error || !bp)return XFS_ERROR (error); }
@@ -920,7 +920,7 @@ xfs_qm_dqflush(* Get the buffer containing the on-disk dquot */ error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp, dqp->q_blkno, - mp->m_quotainfo->qi_dqchunklen,0 , &bp); + mp->m_quotainfo->qi_dqchunklen,0 , &bp,NULL );if (error) goto out_unlock;
fs/xfs/xfs_fsops.c +2 -2
@@ -168,7 +168,7 @@ xfs_growfs_data_private( dpct = pct - mp->m_sb.sb_imax_pct; bp =xfs_buf_read_uncached (mp->m_ddev_targp,XFS_FSB_TO_BB (mp, nb) -XFS_FSS_TO_BB (mp,1 ), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 ,NULL );if (!bp)return EIO ;xfs_buf_relse (bp);
@@ -439,7 +439,7 @@ xfs_growfs_data_private(if (agno < oagcount) { error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , &bp); +XFS_FSS_TO_BB (mp,1 ),0 , &bp,NULL ); }else { bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
fs/xfs/xfs_ialloc.c +1 -1
@@ -1490,7 +1490,7 @@ xfs_read_agi( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , bpp); +XFS_FSS_TO_BB (mp,1 ),0 , bpp,NULL );if (error)return error;
fs/xfs/xfs_inode.c +1 -1
@@ -408,7 +408,7 @@ xfs_imap_to_bp( buf_flags |=XBF_UNMAPPED ; error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, imap->im_blkno, - (int )imap->im_len, buf_flags, &bp); + (int )imap->im_len, buf_flags, &bp,NULL );if (error) {if (error !=EAGAIN ) { xfs_warn(mp,
fs/xfs/xfs_log.c +1 -2
@@ -1129,8 +1129,7 @@ xlog_iodone(xfs_buf_t *bp)* with it being freed after writing the unmount record to the * log. */ - -}/* xlog_iodone */ +}/* * Return size of each in-core log record buffer.
fs/xfs/xfs_log_recover.c +5 -3
@@ -2144,7 +2144,7 @@ xlog_recover_buffer_pass2( buf_flags |=XBF_UNMAPPED ; bp =xfs_buf_read (mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len, - buf_flags); + buf_flags,NULL );if (!bp)return XFS_ERROR (ENOMEM ); error = bp->b_error;
@@ -2237,7 +2237,8 @@ xlog_recover_inode_pass2( }trace_xfs_log_recover_inode_recover (log, in_f); - bp =xfs_buf_read (mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,0 ); + bp =xfs_buf_read (mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,0 , +NULL );if (!bp) { error =ENOMEM ; goto error;
@@ -2548,7 +2549,8 @@ xlog_recover_dquot_pass2(ASSERT (dq_f->qlf_len ==1 ); error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp, dq_f->qlf_blkno, -XFS_FSB_TO_BB (mp, dq_f->qlf_len),0 , &bp); +XFS_FSB_TO_BB (mp, dq_f->qlf_len),0 , &bp, +NULL );if (error)return error;
fs/xfs/xfs_mount.c +3 -3
@@ -652,7 +652,7 @@ xfs_readsb(xfs_mount_t *mp, int flags) reread: bp =xfs_buf_read_uncached (mp->m_ddev_targp,XFS_SB_DADDR , -BTOBB (sector_size),0 ); +BTOBB (sector_size),0 ,NULL );if (!bp) {if (loud)xfs_warn (mp,"SB buffer read failed" );
@@ -1002,7 +1002,7 @@ xfs_check_sizes(xfs_mount_t *mp) } bp =xfs_buf_read_uncached (mp->m_ddev_targp, d -XFS_FSS_TO_BB (mp,1 ), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 ,NULL );if (!bp) {xfs_warn (mp,"last sector read failed" );return EIO ;
@@ -1017,7 +1017,7 @@ xfs_check_sizes(xfs_mount_t *mp) } bp =xfs_buf_read_uncached (mp->m_logdev_targp, d -XFS_FSB_TO_BB (mp,1 ), -XFS_FSB_TO_BB (mp,1 ),0 ); +XFS_FSB_TO_BB (mp,1 ),0 ,NULL );if (!bp) {xfs_warn (mp,"log device read failed" );return EIO ;
fs/xfs/xfs_qm.c +3 -2
@@ -892,7 +892,7 @@ xfs_qm_dqiter_bufs(while (blkcnt--) { error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_FSB_TO_DADDR (mp, bno), - mp->m_quotainfo->qi_dqchunklen,0 , &bp); + mp->m_quotainfo->qi_dqchunklen,0 , &bp,NULL );if (error)break ;
@@ -979,7 +979,8 @@ xfs_qm_dqiterate(while (rablkcnt--) {xfs_buf_readahead (mp->m_ddev_targp,XFS_FSB_TO_DADDR (mp, rablkno), - mp->m_quotainfo->qi_dqchunklen); + mp->m_quotainfo->qi_dqchunklen, +NULL ); rablkno++; } }
fs/xfs/xfs_rtalloc.c +3 -3
@@ -870,7 +870,7 @@ xfs_rtbuf_get(ASSERT (map.br_startblock !=NULLFSBLOCK ); error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp,XFS_FSB_TO_DADDR (mp, map.br_startblock), - mp->m_bsize,0 , &bp); + mp->m_bsize,0 , &bp,NULL );if (error)return error;ASSERT (!xfs_buf_geterror (bp));
@@ -1873,7 +1873,7 @@ xfs_growfs_rt(*/ bp =xfs_buf_read_uncached (mp->m_rtdev_targp,XFS_FSB_TO_BB (mp, nrblocks -1 ), -XFS_FSB_TO_BB (mp,1 ),0 ); +XFS_FSB_TO_BB (mp,1 ),0 ,NULL );if (!bp)return EIO ;xfs_buf_relse (bp);
@@ -2220,7 +2220,7 @@ xfs_rtmount_init( } bp =xfs_buf_read_uncached (mp->m_rtdev_targp, d -XFS_FSB_TO_BB (mp,1 ), -XFS_FSB_TO_BB (mp,1 ),0 ); +XFS_FSB_TO_BB (mp,1 ),0 ,NULL );if (!bp) {xfs_warn (mp,"realtime device size check failed" );return EIO ;
fs/xfs/xfs_trans.h +8 -11
@@ -464,10 +464,7 @@ xfs_trans_get_buf(int numblks, uint flags) { -struct xfs_buf_map map = { - .bm_bn = blkno, - .bm_len = numblks, - }; +DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks );return xfs_trans_get_buf_map (tp, target, &map,1 , flags); }
@@ -476,7 +473,8 @@ int xfs_trans_read_buf_map(struct xfs_mount *mp,struct xfs_buftarg *target, struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags, - struct xfs_buf **bpp); + struct xfs_buf **bpp, + xfs_buf_iodone_t verify);static inline int xfs_trans_read_buf(
@@ -486,13 +484,12 @@ xfs_trans_read_buf(xfs_daddr_t blkno, int numblks, xfs_buf_flags_t flags, - struct xfs_buf **bpp) + struct xfs_buf **bpp, + xfs_buf_iodone_t verify) { - struct xfs_buf_map map = { - .bm_bn = blkno, - .bm_len = numblks, - }; -return xfs_trans_read_buf_map (mp, tp, target, &map,1 , flags, bpp); +DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks ); +return xfs_trans_read_buf_map (mp, tp, target, &map,1 , + flags, bpp, verify); }struct xfs_buf *xfs_trans_getsb (xfs_trans_t *,struct xfs_mount *,int );
fs/xfs/xfs_trans_buf.c +6 -3
@@ -257,7 +257,8 @@ xfs_trans_read_buf_map(struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags, - struct xfs_buf **bpp) + struct xfs_buf **bpp, + xfs_buf_iodone_t verify) { xfs_buf_t *bp;xfs_buf_log_item_t *bip;
@@ -265,7 +266,7 @@ xfs_trans_read_buf_map( *bpp =NULL ;if (!tp) { - bp =xfs_buf_read_map (target, map, nmaps, flags); + bp =xfs_buf_read_map (target, map, nmaps, flags, verify);if (!bp)return (flags &XBF_TRYLOCK ) ?EAGAIN :XFS_ERROR (ENOMEM );
@@ -312,7 +313,9 @@ xfs_trans_read_buf_map(if (!(XFS_BUF_ISDONE (bp))) {trace_xfs_trans_read_buf_io (bp, _RET_IP_);ASSERT (!XFS_BUF_ISASYNC (bp)); +ASSERT (bp->b_iodone ==NULL );XFS_BUF_READ (bp); + bp->b_iodone = verify;xfsbdstrat (tp->t_mountp, bp); error =xfs_buf_iowait (bp);if (error) {
@@ -349,7 +352,7 @@ xfs_trans_read_buf_map(return 0 ; } - bp =xfs_buf_read_map (target, map, nmaps, flags); + bp =xfs_buf_read_map (target, map, nmaps, flags, verify);if (bp ==NULL ) { *bpp =NULL ; return (flags & XBF_TRYLOCK) ?
fs/xfs/xfs_vnodeops.c +1 -1
@@ -80,7 +80,7 @@ xfs_readlink_bmap( d =XFS_FSB_TO_DADDR (mp, mval[n].br_startblock); byte_cnt =XFS_FSB_TO_B (mp, mval[n].br_blockcount); - bp =xfs_buf_read (mp->m_ddev_targp, d,BTOBB (byte_cnt),0 ); + bp =xfs_buf_read (mp->m_ddev_targp, d,BTOBB (byte_cnt),0 ,NULL );if (!bp)return XFS_ERROR (ENOMEM ); error = bp->b_error;
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 10/32 xfs: uncached buffer reads need to return an error
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
With verification being done as an IO completion callback, different errors can be returned from a read. Uncached reads only return a buffer or NULL on failure, which means the verification error cannot be returned to the caller.
Split the error handling for these reads into two - a failure to get a buffer will still return NULL, but a read error will return a referenced buffer with b_error set rather than NULL. The caller is responsible for checking the error state of the buffer returned.
--- fs/xfs/xfs_buf.c | 9 ++------- fs/xfs/xfs_fsops.c | 5 +++++ fs/xfs/xfs_mount.c | 6 ++++++ fs/xfs/xfs_rtalloc.c | 9 ++++++++- 4 files changed, 21 insertions(+), 8 deletions(-)
fs/xfs/xfs_buf.c +2 -7
@@ -715,8 +715,7 @@ xfs_buf_read_uncached( int flags, xfs_buf_iodone_t verify) { -xfs_buf_t *bp; -int error; +struct xfs_buf *bp; bp =xfs_buf_get_uncached (target, numblks, flags);if (!bp)
@@ -730,11 +729,7 @@ xfs_buf_read_uncached( bp->b_iodone = verify;xfsbdstrat (target->bt_mount, bp); - error =xfs_buf_iowait (bp); -if (error) { -xfs_buf_relse (bp); -return NULL ; - } +xfs_buf_iowait (bp);return bp; }
fs/xfs/xfs_fsops.c +5 -0
@@ -171,6 +171,11 @@ xfs_growfs_data_private( XFS_FSS_TO_BB(mp, 1), 0, NULL);if (!bp)return EIO ; +if (bp->b_error) { +int error = bp->b_error; +xfs_buf_relse (bp); +return error; + }xfs_buf_relse (bp); new = nb;/* use new as a temporary here */
fs/xfs/xfs_mount.c +6 -0
@@ -658,6 +658,12 @@ reread:xfs_warn (mp,"SB buffer read failed" );return EIO ; } +if (bp->b_error) { + error = bp->b_error; +if (loud) +xfs_warn (mp,"SB validate failed" ); + goto release_buf; + }/* * Initialize the mount structure from the superblock.
fs/xfs/xfs_rtalloc.c +8 -1
@@ -1876,6 +1876,11 @@ xfs_growfs_rt( XFS_FSB_TO_BB(mp, 1), 0, NULL);if (!bp)return EIO ; +if (bp->b_error) { + error = bp->b_error; +xfs_buf_relse (bp); +return error; + }xfs_buf_relse (bp);/*
@@ -2221,8 +2226,10 @@ xfs_rtmount_init( bp =xfs_buf_read_uncached (mp->m_rtdev_targp, d -XFS_FSB_TO_BB (mp,1 ),XFS_FSB_TO_BB (mp,1 ),0 ,NULL ); -if (!bp) { +if (!bp || bp->b_error) {xfs_warn (mp,"realtime device size check failed" ); +if (bp) +xfs_buf_relse (bp);return EIO ; }xfs_buf_relse (bp);
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 11/32 xfs: verify superblocks as they are read from disk
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add a superblock verify callback function and pass it into the buffer read functions. Remove the now redundant verification code that is currently in use.
Adding verification shows that secondary superblocks never have their "sb_inprogress" flag cleared by mkfs.xfs, so when validating the secondary superblocks during a grow operation we have to avoid checking this field. Even if we fix mkfs, we will still have to ignore this field for verification purposes unless a version of mkfs that does not have this bug was used.
--- fs/xfs/xfs_fsops.c | 4 +- fs/xfs/xfs_log_recover.c | 5 ++- fs/xfs/xfs_mount.c | 98 +++++++++++++++++++++++++++++----------------- fs/xfs/xfs_mount.h | 3 +- 4 files changed, 69 insertions(+), 41 deletions(-)
fs/xfs/xfs_fsops.c +3 -1
@@ -444,7 +444,8 @@ xfs_growfs_data_private(if (agno < oagcount) { error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , &bp,NULL ); +XFS_FSS_TO_BB (mp,1 ),0 , &bp, + xfs_sb_read_verify); }else { bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
@@ -462,6 +463,7 @@ xfs_growfs_data_private(break ; }xfs_sb_to_disk (XFS_BUF_TO_SBP (bp), &mp->m_sb,XFS_SB_ALL_BITS ); +/* * If we get an error writing out the alternate superblocks, * just issue a warning and continue. The real work is
fs/xfs/xfs_log_recover.c +3 -2
@@ -3692,13 +3692,14 @@ xlog_do_recover(/* * Now that we've finished replaying all buffer and inode -* updates, re-read in the superblock. +* updates, re-read in the superblock and reverify it. */ bp =xfs_getsb (log->l_mp,0 );XFS_BUF_UNDONE (bp);ASSERT (!(XFS_BUF_ISWRITE (bp)));XFS_BUF_READ (bp);XFS_BUF_UNASYNC (bp); + bp->b_iodone = xfs_sb_read_verify;xfsbdstrat (log->l_mp, bp); error =xfs_buf_iowait (bp);if (error) {
@@ -3710,7 +3711,7 @@ xlog_do_recover(/* Convert superblock from on-disk format */ sbp = &log->l_mp->m_sb; -xfs_sb_from_disk (log->l_mp,XFS_BUF_TO_SBP (bp)); +xfs_sb_from_disk (sbp,XFS_BUF_TO_SBP (bp));ASSERT (sbp->sb_magicnum ==XFS_SB_MAGIC );ASSERT (xfs_sb_good_version (sbp));xfs_buf_relse (bp);
fs/xfs/xfs_mount.c +61 -37
190 lines not on this page · raw message
fs/xfs/xfs_mount.h +2 -1
@@ -385,10 +385,11 @@ extern void xfs_set_low_space_thresholds(struct xfs_mount *);#endif /* __KERNEL__ */ +extern void xfs_sb_read_verify (struct xfs_buf *);extern void xfs_mod_sb (struct xfs_trans *,__int64_t );extern int xfs_initialize_perag (struct xfs_mount *,xfs_agnumber_t ,xfs_agnumber_t *); -extern void xfs_sb_from_disk (struct xfs_mount *,struct xfs_dsb *); +extern void xfs_sb_from_disk (struct xfs_sb *,struct xfs_dsb *);extern void xfs_sb_to_disk (struct xfs_dsb *,struct xfs_sb *,__int64_t );#endif /* __XFS_MOUNT_H__ */
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 11/32] xfs: verify superblocks as they are read from disk
Looks good,
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 12/32 xfs: verify AGF blocks as they are read from disk
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add an AGF block verify callback function and pass it into the buffer read functions. This replaces the existing verification that is done after the read completes.
--- fs/xfs/xfs_alloc.c | 69 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 26 deletions(-)
fs/xfs/xfs_alloc.c +43 -26
@@ -2091,6 +2091,48 @@ xfs_alloc_put_freelist(return 0 ; } +static void +xfs_agf_read_verify ( +struct xfs_buf *bp) + { +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_agf *agf; +int agf_ok; + + agf =XFS_BUF_TO_AGF (bp); + + agf_ok = agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && +XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && +be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && +be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp); + +/* +* during growfs operations, the perag is not fully initialised, +* so we can't use it for any useful checking. growfs ensures we can't +* use it by using uncached buffers that don't have the perag attached +* so we can detect and avoid this problem. +*/ +if (bp->b_pag) + agf_ok = agf_ok &&be32_to_cpu (agf->agf_seqno) == + bp->b_pag->pag_agno; + +if (xfs_sb_version_haslazysbcount (&mp->m_sb)) + agf_ok = agf_ok &&be32_to_cpu (agf->agf_btreeblks) <= +be32_to_cpu (agf->agf_length); + +if (unlikely (XFS_TEST_ERROR (!agf_ok, mp,XFS_ERRTAG_ALLOC_READ_AGF , +XFS_RANDOM_ALLOC_READ_AGF ))) { +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, agf); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } + + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} +/* * Read in the allocation group header (free/alloc section). */
@@ -2102,44 +2144,19 @@ xfs_read_agf(int flags,/* XFS_BUF_ */ struct xfs_buf **bpp) /* buffer for the ag freelist header */ { - struct xfs_agf *agf; /* ag freelist header */ -int agf_ok;/* set if agf is consistent */ int error;ASSERT (agno !=NULLAGNUMBER ); error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ), flags, bpp,NULL ); +XFS_FSS_TO_BB (mp,1 ), flags, bpp, xfs_agf_read_verify);if (error)return error;if (!*bpp)return 0 ;ASSERT (!(*bpp)->b_error); - agf =XFS_BUF_TO_AGF (*bpp); - -/* -* Validate the magic number of the agf block. -*/ - agf_ok = - agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && -XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && -be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && -be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_seqno) == agno; -if (xfs_sb_version_haslazysbcount (&mp->m_sb)) - agf_ok = agf_ok &&be32_to_cpu (agf->agf_btreeblks) <= -be32_to_cpu (agf->agf_length); -if (unlikely (XFS_TEST_ERROR (!agf_ok, mp,XFS_ERRTAG_ALLOC_READ_AGF , -XFS_RANDOM_ALLOC_READ_AGF ))) { -XFS_CORRUPTION_ERROR ("xfs_alloc_read_agf" , -XFS_ERRLEVEL_LOW , mp, agf); -xfs_trans_brelse (tp, *bpp); -return XFS_ERROR (EFSCORRUPTED ); - }xfs_buf_set_ref (*bpp,XFS_AGF_REF );return 0 ; }
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 12/32] xfs: verify AGF blocks as they are read from disk
Dave, you botched a copy & paste here:
fs/xfs/xfs_alloc.c xfs_alloc_put_freelist( · line 2110
Quoted 7 lines · Dave Chinner
fs/xfs/xfs_alloc.c +7
-0+ agf_ok = agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && +XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && +be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && +be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp);
See:
fs/xfs/xfs_alloc.c xfs_read_agf( · line 2132
Quoted 8 lines
fs/xfs/xfs_alloc.c +0
-8- agf_ok = - agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && -XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && -be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && -be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_seqno) == agno;
-Phil
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 12/32] xfs: verify AGF blocks as they are read from disk
Quoted 12 lines · Phil White
Dave, you botched a copy & paste here:
fs/xfs/xfs_alloc.c xfs_alloc_put_freelist( · line 2110
Quoted 7 lines · Dave Chinner
fs/xfs/xfs_alloc.c +7
-0+ agf_ok = agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && +XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && +be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && +be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp);See:
Quoted 8 lines
fs/xfs/xfs_alloc.c xfs_read_agf( · line 2132
Quoted 8 lines
fs/xfs/xfs_alloc.c +0
-8- agf_ok = - agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && -XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && -be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && -be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_seqno) == agno;
Good catch. :)
The agno is still checked in the new code, so it's just a double check of the agf_flcount. i.e. no actual bug. I'll resend an updated patch.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 12/32 xfs: verify AGF blocks as they are read from disk
In reply to Dave Chinnerxfs: verify AGF blocks as they are read from disk
From: Dave Chinner <[email protected]>
Add an AGF block verify callback function and pass it into the buffer read functions. This replaces the existing verification that is done after the read completes.
---
V2: fix duplicate logic in verifier function.
fs/xfs/xfs_alloc.c | 68 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 26 deletions(-)
fs/xfs/xfs_alloc.c +42 -26
@@ -2091,6 +2091,47 @@ xfs_alloc_put_freelist(return 0 ; } +static void +xfs_agf_read_verify ( +struct xfs_buf *bp) + { +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_agf *agf; +int agf_ok; + + agf =XFS_BUF_TO_AGF (bp); + + agf_ok = agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && +XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && +be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && +be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && +be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp); + +/* +* during growfs operations, the perag is not fully initialised, +* so we can't use it for any useful checking. growfs ensures we can't +* use it by using uncached buffers that don't have the perag attached +* so we can detect and avoid this problem. +*/ +if (bp->b_pag) + agf_ok = agf_ok &&be32_to_cpu (agf->agf_seqno) == + bp->b_pag->pag_agno; + +if (xfs_sb_version_haslazysbcount (&mp->m_sb)) + agf_ok = agf_ok &&be32_to_cpu (agf->agf_btreeblks) <= +be32_to_cpu (agf->agf_length); + +if (unlikely (XFS_TEST_ERROR (!agf_ok, mp,XFS_ERRTAG_ALLOC_READ_AGF , +XFS_RANDOM_ALLOC_READ_AGF ))) { +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, agf); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } + + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} +/* * Read in the allocation group header (free/alloc section). */
@@ -2102,44 +2143,19 @@ xfs_read_agf(int flags,/* XFS_BUF_ */ struct xfs_buf **bpp) /* buffer for the ag freelist header */ { - struct xfs_agf *agf; /* ag freelist header */ -int agf_ok;/* set if agf is consistent */ int error;ASSERT (agno !=NULLAGNUMBER ); error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ), flags, bpp,NULL ); +XFS_FSS_TO_BB (mp,1 ), flags, bpp, xfs_agf_read_verify);if (error)return error;if (!*bpp)return 0 ;ASSERT (!(*bpp)->b_error); - agf =XFS_BUF_TO_AGF (*bpp); - -/* -* Validate the magic number of the agf block. -*/ - agf_ok = - agf->agf_magicnum ==cpu_to_be32 (XFS_AGF_MAGIC ) && -XFS_AGF_GOOD_VERSION (be32_to_cpu (agf->agf_versionnum)) && -be32_to_cpu (agf->agf_freeblks) <=be32_to_cpu (agf->agf_length) && -be32_to_cpu (agf->agf_flfirst) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_fllast) <XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_flcount) <=XFS_AGFL_SIZE (mp) && -be32_to_cpu (agf->agf_seqno) == agno; -if (xfs_sb_version_haslazysbcount (&mp->m_sb)) - agf_ok = agf_ok &&be32_to_cpu (agf->agf_btreeblks) <= -be32_to_cpu (agf->agf_length); -if (unlikely (XFS_TEST_ERROR (!agf_ok, mp,XFS_ERRTAG_ALLOC_READ_AGF , -XFS_RANDOM_ALLOC_READ_AGF ))) { -XFS_CORRUPTION_ERROR ("xfs_alloc_read_agf" , -XFS_ERRLEVEL_LOW , mp, agf); -xfs_trans_brelse (tp, *bpp); -return XFS_ERROR (EFSCORRUPTED ); - }xfs_buf_set_ref (*bpp,XFS_AGF_REF );return 0 ; }
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 12/32 V2] xfs: verify AGF blocks as they are read from disk
Quoted 4 lines · Dave Chinner
xfs: verify AGF blocks as they are read from disk
From: Dave Chinner<[email protected]>
Quoted 9 lines
Add an AGF block verify callback function and pass it into the buffer read functions. This replaces the existing verification that is done after the read completes.
Signed-off-by Dave Chinner<[email protected]>Reviewed-by Christoph Hellwig<[email protected]>---
V2: fix duplicate logic in verifier function.
looks good.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 13/32 xfs: verify AGI blocks as they are read from disk
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add an AGI block verify callback function and pass it into the buffer read functions. Remove the now redundant verification code that is currently in use.
--- fs/xfs/xfs_ialloc.c | 56 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 21 deletions(-)
fs/xfs/xfs_ialloc.c +35 -21
@@ -1472,6 +1472,40 @@ xfs_check_agi_unlinked(#define xfs_check_agi_unlinked (agi)#endif +static void +xfs_agi_read_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_agi *agi =XFS_BUF_TO_AGI (bp); +int agi_ok; + +/* +* Validate the magic number of the agi block. +*/ + agi_ok = agi->agi_magicnum ==cpu_to_be32 (XFS_AGI_MAGIC ) && +XFS_AGI_GOOD_VERSION (be32_to_cpu (agi->agi_versionnum)); + +/* +* during growfs operations, the perag is not fully initialised, +* so we can't use it for any useful checking. growfs ensures we can't +* use it by using uncached buffers that don't have the perag attached +* so we can detect and avoid this problem. +*/ +if (bp->b_pag) + agi_ok = agi_ok &&be32_to_cpu (agi->agi_seqno) == + bp->b_pag->pag_agno; + +if (unlikely (XFS_TEST_ERROR (!agi_ok, mp,XFS_ERRTAG_IALLOC_READ_AGI , +XFS_RANDOM_IALLOC_READ_AGI ))) { +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, agi); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } +xfs_check_agi_unlinked (agi); + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} +/* * Read in the allocation group header (inode allocation section) */
@@ -1482,38 +1516,18 @@ xfs_read_agi(xfs_agnumber_t agno,/* allocation group number */ struct xfs_buf **bpp) /* allocation group hdr buf */ { - struct xfs_agi *agi; /* allocation group header */ -int agi_ok;/* agi is consistent */ int error;ASSERT (agno !=NULLAGNUMBER ); error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , bpp,NULL ); +XFS_FSS_TO_BB (mp,1 ),0 , bpp, xfs_agi_read_verify);if (error)return error;ASSERT (!xfs_buf_geterror (*bpp)); - agi =XFS_BUF_TO_AGI (*bpp); - -/* -* Validate the magic number of the agi block. -*/ - agi_ok = agi->agi_magicnum ==cpu_to_be32 (XFS_AGI_MAGIC ) && -XFS_AGI_GOOD_VERSION (be32_to_cpu (agi->agi_versionnum)) && -be32_to_cpu (agi->agi_seqno) == agno; -if (unlikely (XFS_TEST_ERROR (!agi_ok, mp,XFS_ERRTAG_IALLOC_READ_AGI , -XFS_RANDOM_IALLOC_READ_AGI ))) { -XFS_CORRUPTION_ERROR ("xfs_read_agi" ,XFS_ERRLEVEL_LOW , - mp, agi); -xfs_trans_brelse (tp, *bpp); -return XFS_ERROR (EFSCORRUPTED ); - } -xfs_buf_set_ref (*bpp,XFS_AGI_REF ); - -xfs_check_agi_unlinked (agi);return 0 ; }
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 14/32 xfs: verify AGFL blocks as they are read from disk
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add an AGFL block verify callback function and pass it into the buffer read functions.
While this commit adds verification code to the AGFL, it cannot be used reliably until the CRC format change comes along as mkfs does not initialise the full AGFL. Hence it can be full of garbage at the first mount and will fail verification right now. CRC enabled filesystems won't have this problem, so leave the code that has already been written ifdef'd out until the proper time.
--- fs/xfs/xfs_alloc.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
fs/xfs/xfs_alloc.c +38 -1
@@ -430,6 +430,43 @@ xfs_alloc_fixup_trees(return 0 ; } +void +xfs_agfl_read_verify ( +struct xfs_buf *bp) +{ +#ifdef WHEN_CRCS_COME_ALONG +/* +* we cannot actually do any verification of the AGFL because mkfs does +* not initialise the AGFL to zero or NULL. Hence the only valid part of +* the AGFL is what the AGF says is active. We can't get to the AGF, so +* we can't verify just those entries are valid. +* +* This problem goes away when the CRC format change comes along as that +* requires the AGFL to be initialised by mkfs. At that point, we can +* verify the blocks in the agfl -active or not- lie within the bounds +* of the AG. Until then, just leave this check ifdef'd out. +*/ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_agfl *agfl =XFS_BUF_TO_AGFL (bp); +int agfl_ok =1 ; + +int i; + +for (i =0 ; i <XFS_AGFL_SIZE (mp); i++) { +if (be32_to_cpu (agfl->agfl_bno[i]) ==NULLAGBLOCK || +be32_to_cpu (agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks) + agfl_ok =0 ; + } + +if (!agfl_ok) { +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, agfl); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } +#endif + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} +/* * Read in the allocation group free block array. */
@@ -447,7 +484,7 @@ xfs_alloc_read_agfl( error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGFL_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , &bp,NULL ); +XFS_FSS_TO_BB (mp,1 ),0 , &bp, xfs_agfl_read_verify);if (error)return error;ASSERT (!xfs_buf_geterror (bp));
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 15/32 xfs: verify inode buffers as they are read from disk
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add an inode buffer verify callback function and pass it into the buffer read functions. Inodes are special in that the verbose checks will be done when reading the inode, but we still need to sanity check the buffer when that is first read. Always verify the magic numbers in all inodes in the buffer, rather than jus ton debug kernels.
--- fs/xfs/xfs_inode.c | 100 +++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 49 deletions(-)
fs/xfs/xfs_inode.c +51 -49
@@ -382,6 +382,46 @@ xfs_inobp_check( }#endif +static void +xfs_inode_buf_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +int i; +int ni; + +/* +* Validate the magic number and version of every inode in the buffer +*/ + ni =XFS_BB_TO_FSB (mp, bp->b_length) * mp->m_sb.sb_inopblock; +for (i =0 ; i < ni; i++) { +int di_ok; +xfs_dinode_t *dip; + + dip = (struct xfs_dinode *)xfs_buf_offset (bp, + (i << mp->m_sb.sb_inodelog)); + di_ok = dip->di_magic ==cpu_to_be16 (XFS_DINODE_MAGIC ) && +XFS_DINODE_GOOD_VERSION (dip->di_version); +if (unlikely (XFS_TEST_ERROR (!di_ok, mp, +XFS_ERRTAG_ITOBP_INOTOBP , +XFS_RANDOM_ITOBP_INOTOBP ))) { +xfs_buf_ioerror (bp,EFSCORRUPTED ); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_HIGH , + mp, dip); +#ifdef DEBUG +xfs_emerg (mp, +"bad inode magic/vsn daddr %lld #%d (magic=%x)" , + (unsigned long long )bp->b_bn, i, +be16_to_cpu (dip->di_magic)); +ASSERT (0 ); +#endif + } + } +xfs_inobp_check (mp, bp); + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} +/* * This routine is called to map an inode to the buffer containing the on-disk * version of the inode. It returns a pointer to the buffer containing the
@@ -396,71 +436,33 @@ xfs_imap_to_bp(struct xfs_mount *mp, struct xfs_trans *tp, struct xfs_imap *imap, - struct xfs_dinode **dipp, + struct xfs_dinode **dipp, struct xfs_buf **bpp, uint buf_flags, uint iget_flags) { struct xfs_buf *bp;int error; -int i; -int ni; buf_flags |=XBF_UNMAPPED ; error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, imap->im_blkno, - (int )imap->im_len, buf_flags, &bp,NULL ); + (int )imap->im_len, buf_flags, &bp, + xfs_inode_buf_verify);if (error) { -if (error !=EAGAIN ) { -xfs_warn (mp, -"%s: xfs_trans_read_buf() returned error %d." , - __func__, error); - }else { +if (error ==EAGAIN ) {ASSERT (buf_flags &XBF_TRYLOCK ); +return error; } -return error; - } -/* -* Validate the magic number and version of every inode in the buffer -* (if DEBUG kernel) or the first inode in the buffer, otherwise. -*/ -#ifdef DEBUG - ni =BBTOB (imap->im_len) >> mp->m_sb.sb_inodelog; -#else /* usual case */ - ni =1 ; -#endif +if (error ==EFSCORRUPTED && + (iget_flags &XFS_IGET_UNTRUSTED )) +return XFS_ERROR (EINVAL ); -for (i =0 ; i < ni; i++) { -int di_ok; -xfs_dinode_t *dip; - - dip = (xfs_dinode_t *)xfs_buf_offset (bp, - (i << mp->m_sb.sb_inodelog)); - di_ok = dip->di_magic ==cpu_to_be16 (XFS_DINODE_MAGIC ) && -XFS_DINODE_GOOD_VERSION (dip->di_version); -if (unlikely (XFS_TEST_ERROR (!di_ok, mp, -XFS_ERRTAG_ITOBP_INOTOBP , -XFS_RANDOM_ITOBP_INOTOBP ))) { -if (iget_flags &XFS_IGET_UNTRUSTED ) { -xfs_trans_brelse (tp, bp); -return XFS_ERROR (EINVAL ); - } -XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_HIGH , - mp, dip); -#ifdef DEBUG -xfs_emerg (mp, -"bad inode magic/vsn daddr %lld #%d (magic=%x)" , - (unsigned long long )imap->im_blkno, i, -be16_to_cpu (dip->di_magic)); -ASSERT (0 ); -#endif -xfs_trans_brelse (tp, bp); -return XFS_ERROR (EFSCORRUPTED ); - } +xfs_warn (mp,"%s: xfs_trans_read_buf() returned error %d." , + __func__, error); +return error; } -xfs_inobp_check (mp, bp); - *bpp = bp; *dipp = (struct xfs_dinode *)xfs_buf_offset (bp, imap->im_boffset);return 0 ;
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 16/32 xfs: verify btree blocks as they are read from disk
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add an btree block verify callback function and pass it into the buffer read functions. Because each different btree block type requires different verification, add a function to the ops structure that is called from the generic code.
Also, propagate the verification callback functions through the readahead functions, and into the external bmap and bulkstat inode readahead code that uses the generic btree buffer read functions.
--- fs/xfs/xfs_alloc_btree.c | 61 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_bmap.c | 60 ++++++++++++++++++++++++----------------- fs/xfs/xfs_bmap_btree.c | 47 ++++++++++++++++++++++++++++++++ fs/xfs/xfs_bmap_btree.h | 1 + fs/xfs/xfs_btree.c | 66 +++++++++++++++++++++++---------------------- fs/xfs/xfs_btree.h | 10 ++++--- fs/xfs/xfs_ialloc_btree.c | 40 +++++++++++++++++++++++++++ fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_inode.h | 1 + fs/xfs/xfs_itable.c | 3 ++- 10 files changed, 230 insertions(+), 61 deletions(-)
fs/xfs/xfs_alloc_btree.c +61 -0
@@ -272,6 +272,66 @@ xfs_allocbt_key_diff(return (__int64_t )be32_to_cpu (kp->ar_startblock) - rec->ar_startblock; } +void +xfs_allocbt_read_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_btree_block *block =XFS_BUF_TO_BLOCK (bp); +struct xfs_perag *pag = bp->b_pag; +unsigned int level; +int sblock_ok;/* block passes checks */ + +/* +* magic number and level verification +* +* During growfs operations, we can't verify the exact level as the +* perag is not fully initialised and hence not attached to the buffer. +* In this case, check against the maximum tree depth. +*/ + level =be16_to_cpu (block->bb_level); +switch (block->bb_magic) { +case cpu_to_be32 (XFS_ABTB_MAGIC ): +if (pag) + sblock_ok = level < pag->pagf_levels[XFS_BTNUM_BNOi]; +else + sblock_ok = level < mp->m_ag_maxlevels; +break ; +case cpu_to_be32 (XFS_ABTC_MAGIC ): +if (pag) + sblock_ok = level < pag->pagf_levels[XFS_BTNUM_CNTi]; +else + sblock_ok = level < mp->m_ag_maxlevels; +break ; +default : + sblock_ok =0 ; +break ; + } + +/* numrecs verification */ + sblock_ok = sblock_ok && +be16_to_cpu (block->bb_numrecs) <= mp->m_alloc_mxr[level !=0 ]; + +/* sibling pointer verification */ + sblock_ok = sblock_ok && + (block->bb_u.s.bb_leftsib ==cpu_to_be32 (NULLAGBLOCK ) || +be32_to_cpu (block->bb_u.s.bb_leftsib) < mp->m_sb.sb_agblocks) && + block->bb_u.s.bb_leftsib && + (block->bb_u.s.bb_rightsib ==cpu_to_be32 (NULLAGBLOCK ) || +be32_to_cpu (block->bb_u.s.bb_rightsib) < mp->m_sb.sb_agblocks) && + block->bb_u.s.bb_rightsib; + +if (!sblock_ok) { +trace_xfs_btree_corrupt (bp, _RET_IP_); +XFS_CORRUPTION_ERROR ("xfs_allocbt_read_verify" , +XFS_ERRLEVEL_LOW , mp, block); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } + + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} +#ifdef DEBUG STATIC int xfs_allocbt_keys_inorder(
@@ -327,6 +387,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = { .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_allocbt_key_diff, + .read_verify = xfs_allocbt_read_verify, #ifdef DEBUG .keys_inorder = xfs_allocbt_keys_inorder, .recs_inorder = xfs_allocbt_recs_inorder,
fs/xfs/xfs_bmap.c +36 -24
120 lines not on this page · raw message
fs/xfs/xfs_bmap_btree.c +47 -0
65 lines not on this page · raw message
fs/xfs/xfs_bmap_btree.h +1 -0
@@ -232,6 +232,7 @@ extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,extern int xfs_bmbt_get_maxrecs (struct xfs_btree_cur *,int level);extern int xfs_bmdr_maxrecs (struct xfs_mount *,int blocklen,int leaf);extern int xfs_bmbt_maxrecs (struct xfs_mount *,int blocklen,int leaf); +extern void xfs_bmbt_read_verify (struct xfs_buf *bp);extern struct xfs_btree_cur *xfs_bmbt_init_cursor (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,int );
fs/xfs/xfs_btree.c +34 -32
140 lines not on this page · raw message
fs/xfs/xfs_btree.h +7 -3
@@ -188,6 +188,7 @@ struct xfs_btree_ops {__int64_t (*key_diff)(struct xfs_btree_cur *cur,union xfs_btree_key *key); +void (*read_verify)(struct xfs_buf *bp);#ifdef DEBUG /* check that k1 is lower than k2 */ int (*keys_inorder)(struct xfs_btree_cur *cur,
@@ -355,7 +356,8 @@ xfs_btree_read_bufl(xfs_fsblock_t fsbno,/* file system block number */ uint lock, /* lock flags for read_buf */ struct xfs_buf **bpp, /* buffer for fsbno */ - int refval);/* ref count value for buffer */ + int refval, /* ref count value for buffer */ + xfs_buf_iodone_t verify);/* * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -365,7 +367,8 @@ void /* error */xfs_btree_reada_bufl ( struct xfs_mount *mp, /* file system mount point */ xfs_fsblock_t fsbno, /* file system block number */ - xfs_extlen_t count); /* count of filesystem blocks */ + xfs_extlen_t count, /* count of filesystem blocks */ + xfs_buf_iodone_t verify);/* * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -376,7 +379,8 @@ xfs_btree_reada_bufs(struct xfs_mount *mp,/* file system mount point */ xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ - xfs_extlen_t count); /* count of filesystem blocks */ + xfs_extlen_t count, /* count of filesystem blocks */ + xfs_buf_iodone_t verify);/* * Initialise a new btree block header
fs/xfs/xfs_ialloc_btree.c +40 -0
@@ -33,6 +33,7 @@#include "xfs_ialloc.h" #include "xfs_alloc.h" #include "xfs_error.h" +#include "xfs_trace.h" STATIC int
@@ -181,6 +182,44 @@ xfs_inobt_key_diff( cur->bc_rec.i.ir_startino; } +void +xfs_inobt_read_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_btree_block *block =XFS_BUF_TO_BLOCK (bp); +unsigned int level; +int sblock_ok;/* block passes checks */ + +/* magic number and level verification */ + level =be16_to_cpu (block->bb_level); + sblock_ok = block->bb_magic ==cpu_to_be32 (XFS_IBT_MAGIC ) && + level < mp->m_in_maxlevels; + +/* numrecs verification */ + sblock_ok = sblock_ok && +be16_to_cpu (block->bb_numrecs) <= mp->m_inobt_mxr[level !=0 ]; + +/* sibling pointer verification */ + sblock_ok = sblock_ok && + (block->bb_u.s.bb_leftsib ==cpu_to_be32 (NULLAGBLOCK ) || +be32_to_cpu (block->bb_u.s.bb_leftsib) < mp->m_sb.sb_agblocks) && + block->bb_u.s.bb_leftsib && + (block->bb_u.s.bb_rightsib ==cpu_to_be32 (NULLAGBLOCK ) || +be32_to_cpu (block->bb_u.s.bb_rightsib) < mp->m_sb.sb_agblocks) && + block->bb_u.s.bb_rightsib; + +if (!sblock_ok) { +trace_xfs_btree_corrupt (bp, _RET_IP_); +XFS_CORRUPTION_ERROR ("xfs_inobt_read_verify" , +XFS_ERRLEVEL_LOW , mp, block); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } + + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} +#ifdef DEBUG STATIC int xfs_inobt_keys_inorder(
@@ -218,6 +257,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = { .init_rec_from_cur = xfs_inobt_init_rec_from_cur, .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, .key_diff = xfs_inobt_key_diff, + .read_verify = xfs_inobt_read_verify, #ifdef DEBUG .keys_inorder = xfs_inobt_keys_inorder, .recs_inorder = xfs_inobt_recs_inorder,
fs/xfs/xfs_inode.c +1 -1
@@ -382,7 +382,7 @@ xfs_inobp_check( }#endif -static void +void xfs_inode_buf_verify (struct xfs_buf *bp) {
fs/xfs/xfs_inode.h +1 -0
@@ -554,6 +554,7 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, struct xfs_buf **, uint, uint);int xfs_iread (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,uint ); +void xfs_inode_buf_verify (struct xfs_buf *);void xfs_dinode_to_disk (struct xfs_dinode *,struct xfs_icdinode *);void xfs_idestroy_fork (struct xfs_inode *,int );
fs/xfs/xfs_itable.c +2 -1
@@ -396,7 +396,8 @@ xfs_bulkstat(if (xfs_inobt_maskn (chunkidx, nicluster) & ~r.ir_free)xfs_btree_reada_bufs (mp, agno, - agbno, nbcluster); + agbno, nbcluster, + xfs_inode_buf_verify); } irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 17/32 xfs: verify dquot blocks as they are read from disk
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add a dquot buffer verify callback function and pass it into the buffer read functions. This checks all the dquots in a buffer, but cannot completely verify the dquot ids are correct. Also, errors cannot be repaired, so an additional function is added to repair bad dquots in the buffer if such an error is detected in a context where repair is allowed.
--- fs/xfs/xfs_dquot.c | 117 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 95 insertions(+), 22 deletions(-)
fs/xfs/xfs_dquot.c +95 -22
@@ -360,6 +360,89 @@ xfs_qm_dqalloc(return (error); } +STATIC void +xfs_dquot_read_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr; +struct xfs_disk_dquot *ddq; +xfs_dqid_t id =0 ; +int i; + +/* +* On the first read of the buffer, verify that each dquot is valid. +* We don't know what the id of the dquot is supposed to be, just that +* they should be increasing monotonically within the buffer. If the +* first id is corrupt, then it will fail on the second dquot in the +* buffer so corruptions could point to the wrong dquot in this case. +*/ +for (i =0 ; i < mp->m_quotainfo->qi_dqperchunk; i++) { +int error; + + ddq = &d[i].dd_diskdq; + +if (i ==0 ) + id =be32_to_cpu (ddq->d_id); + + error =xfs_qm_dqcheck (mp, ddq, id + i,0 ,XFS_QMOPT_DOWARN , +"xfs_dquot_read_verify" ); +if (error) { +XFS_CORRUPTION_ERROR ("xfs_dquot_read_verify" , +XFS_ERRLEVEL_LOW , mp, d); +xfs_buf_ioerror (bp,EFSCORRUPTED ); +break ; + } + } + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} + +STATIC int +xfs_qm_dqrepair ( +struct xfs_mount *mp, +struct xfs_trans *tp, +struct xfs_dquot *dqp, +xfs_dqid_t firstid, +struct xfs_buf **bpp) +{ +int error; +struct xfs_disk_dquot *ddq; +struct xfs_dqblk *d; +int i; + +/* +* Read the buffer without verification so we get the corrupted +* buffer returned to us. +*/ + error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, + mp->m_quotainfo->qi_dqchunklen, +0 , bpp,NULL ); + +if (error) { +ASSERT (*bpp ==NULL ); +return XFS_ERROR (error); + } + +ASSERT (xfs_buf_islocked (*bpp)); + d = (struct xfs_dqblk *)(*bpp)->b_addr; + +/* Do the actual repair of dquots in this buffer */ +for (i =0 ; i < mp->m_quotainfo->qi_dqperchunk; i++) { + ddq = &d[i].dd_diskdq; + error =xfs_qm_dqcheck (mp, ddq, firstid + i, + dqp->dq_flags &XFS_DQ_ALLTYPES , +XFS_QMOPT_DQREPAIR ,"xfs_qm_dqrepair" ); +if (error) { +/* repair failed, we're screwed */ +xfs_trans_brelse (tp, *bpp); +return XFS_ERROR (EIO ); + } + } + +return 0 ; +} +/* * Maps a dquot to the buffer containing its on-disk version. * This returns a ptr to the buffer containing the on-disk dquot
@@ -378,7 +461,6 @@ xfs_qm_dqtobp(xfs_buf_t *bp;xfs_inode_t *quotip =XFS_DQ_TO_QIP (dqp);xfs_mount_t *mp = dqp->q_mount; -xfs_disk_dquot_t *ddq;xfs_dqid_t id =be32_to_cpu (dqp->q_core.d_id);xfs_trans_t *tp = (tpp ? *tpp :NULL );
@@ -439,33 +521,24 @@ xfs_qm_dqtobp( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, -0 , &bp,NULL ); -if (error || !bp) -return XFS_ERROR (error); - } +0 , &bp, xfs_dquot_read_verify); -ASSERT (xfs_buf_islocked (bp)); - -/* -* calculate the location of the dquot inside the buffer. -*/ - ddq = bp->b_addr + dqp->q_bufoffset; +if (error ==EFSCORRUPTED && (flags &XFS_QMOPT_DQREPAIR )) { +xfs_dqid_t firstid = (xfs_dqid_t )map.br_startoff * + mp->m_quotainfo->qi_dqperchunk; +ASSERT (bp ==NULL ); + error =xfs_qm_dqrepair (mp, tp, dqp, firstid, &bp); + } -/* -* A simple sanity check in case we got a corrupted dquot... -*/ - error =xfs_qm_dqcheck (mp, ddq, id, dqp->dq_flags &XFS_DQ_ALLTYPES , - flags & (XFS_QMOPT_DQREPAIR |XFS_QMOPT_DOWARN ), -"dqtobp" ); -if (error) { -if (!(flags &XFS_QMOPT_DQREPAIR )) { -xfs_trans_brelse (tp, bp); -return XFS_ERROR (EIO ); +if (error) { +ASSERT (bp ==NULL ); +return XFS_ERROR (error); } } +ASSERT (xfs_buf_islocked (bp)); *O_bpp = bp; - *O_ddpp = ddq; + *O_ddpp = bp->b_addr + dqp->q_bufoffset;return (0 ); }
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 17/32 xfs: verify dquot blocks as they are read from disk
xfs: verify dquot blocks as they are read from disk
From: Dave Chinner <[email protected]>
Add a dquot buffer verify callback function and pass it into the buffer read functions. This checks all the dquots in a buffer, but cannot completely verify the dquot ids are correct. Also, errors cannot be repaired, so an additional function is added to repair bad dquots in the buffer if such an error is detected in a context where repair is allowed.
---
V2: quotacheck wasn't verifying dquots as they were read from disk
fs/xfs/xfs_dquot.c | 117 ++++++++++++++++++++++++++++++++++++++++++---------- fs/xfs/xfs_dquot.h | 1 + fs/xfs/xfs_qm.c | 3 +- 3 files changed, 98 insertions(+), 23 deletions(-)
fs/xfs/xfs_dquot.c +95 -22
@@ -360,6 +360,89 @@ xfs_qm_dqalloc(return (error); } +void +xfs_dquot_read_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_dqblk *d = (struct xfs_dqblk *)bp->b_addr; +struct xfs_disk_dquot *ddq; +xfs_dqid_t id =0 ; +int i; + +/* +* On the first read of the buffer, verify that each dquot is valid. +* We don't know what the id of the dquot is supposed to be, just that +* they should be increasing monotonically within the buffer. If the +* first id is corrupt, then it will fail on the second dquot in the +* buffer so corruptions could point to the wrong dquot in this case. +*/ +for (i =0 ; i < mp->m_quotainfo->qi_dqperchunk; i++) { +int error; + + ddq = &d[i].dd_diskdq; + +if (i ==0 ) + id =be32_to_cpu (ddq->d_id); + + error =xfs_qm_dqcheck (mp, ddq, id + i,0 ,XFS_QMOPT_DOWARN , +"xfs_dquot_read_verify" ); +if (error) { +XFS_CORRUPTION_ERROR ("xfs_dquot_read_verify" , +XFS_ERRLEVEL_LOW , mp, d); +xfs_buf_ioerror (bp,EFSCORRUPTED ); +break ; + } + } + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} + +STATIC int +xfs_qm_dqrepair ( +struct xfs_mount *mp, +struct xfs_trans *tp, +struct xfs_dquot *dqp, +xfs_dqid_t firstid, +struct xfs_buf **bpp) +{ +int error; +struct xfs_disk_dquot *ddq; +struct xfs_dqblk *d; +int i; + +/* +* Read the buffer without verification so we get the corrupted +* buffer returned to us. +*/ + error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, + mp->m_quotainfo->qi_dqchunklen, +0 , bpp,NULL ); + +if (error) { +ASSERT (*bpp ==NULL ); +return XFS_ERROR (error); + } + +ASSERT (xfs_buf_islocked (*bpp)); + d = (struct xfs_dqblk *)(*bpp)->b_addr; + +/* Do the actual repair of dquots in this buffer */ +for (i =0 ; i < mp->m_quotainfo->qi_dqperchunk; i++) { + ddq = &d[i].dd_diskdq; + error =xfs_qm_dqcheck (mp, ddq, firstid + i, + dqp->dq_flags &XFS_DQ_ALLTYPES , +XFS_QMOPT_DQREPAIR ,"xfs_qm_dqrepair" ); +if (error) { +/* repair failed, we're screwed */ +xfs_trans_brelse (tp, *bpp); +return XFS_ERROR (EIO ); + } + } + +return 0 ; +} +/* * Maps a dquot to the buffer containing its on-disk version. * This returns a ptr to the buffer containing the on-disk dquot
@@ -378,7 +461,6 @@ xfs_qm_dqtobp(xfs_buf_t *bp;xfs_inode_t *quotip =XFS_DQ_TO_QIP (dqp);xfs_mount_t *mp = dqp->q_mount; -xfs_disk_dquot_t *ddq;xfs_dqid_t id =be32_to_cpu (dqp->q_core.d_id);xfs_trans_t *tp = (tpp ? *tpp :NULL );
@@ -439,33 +521,24 @@ xfs_qm_dqtobp( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, -0 , &bp,NULL ); -if (error || !bp) -return XFS_ERROR (error); - } +0 , &bp, xfs_dquot_read_verify); -ASSERT (xfs_buf_islocked (bp)); - -/* -* calculate the location of the dquot inside the buffer. -*/ - ddq = bp->b_addr + dqp->q_bufoffset; +if (error ==EFSCORRUPTED && (flags &XFS_QMOPT_DQREPAIR )) { +xfs_dqid_t firstid = (xfs_dqid_t )map.br_startoff * + mp->m_quotainfo->qi_dqperchunk; +ASSERT (bp ==NULL ); + error =xfs_qm_dqrepair (mp, tp, dqp, firstid, &bp); + } -/* -* A simple sanity check in case we got a corrupted dquot... -*/ - error =xfs_qm_dqcheck (mp, ddq, id, dqp->dq_flags &XFS_DQ_ALLTYPES , - flags & (XFS_QMOPT_DQREPAIR |XFS_QMOPT_DOWARN ), -"dqtobp" ); -if (error) { -if (!(flags &XFS_QMOPT_DQREPAIR )) { -xfs_trans_brelse (tp, bp); -return XFS_ERROR (EIO ); +if (error) { +ASSERT (bp ==NULL ); +return XFS_ERROR (error); } } +ASSERT (xfs_buf_islocked (bp)); *O_bpp = bp; - *O_ddpp = ddq; + *O_ddpp = bp->b_addr + dqp->q_bufoffset;return (0 ); }
fs/xfs/xfs_dquot.h +1 -0
@@ -140,6 +140,7 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)extern int xfs_qm_dqread (struct xfs_mount *,xfs_dqid_t ,uint ,uint ,struct xfs_dquot **); +extern void xfs_dquot_read_verify (struct xfs_buf *bp);extern void xfs_qm_dqdestroy (xfs_dquot_t *);extern int xfs_qm_dqflush (struct xfs_dquot *,struct xfs_buf **);extern void xfs_qm_dqunpin_wait (xfs_dquot_t *);
fs/xfs/xfs_qm.c +2 -1
@@ -892,7 +892,8 @@ xfs_qm_dqiter_bufs(while (blkcnt--) { error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_FSB_TO_DADDR (mp, bno), - mp->m_quotainfo->qi_dqchunklen,0 , &bp,NULL ); + mp->m_quotainfo->qi_dqchunklen,0 , &bp, + xfs_dquot_read_verify);if (error)break ;
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 11 lines · Dave Chinner
xfs: verify dquot blocks as they are read from disk
From: Dave Chinner<[email protected]>
Add a dquot buffer verify callback function and pass it into the buffer read functions. This checks all the dquots in a buffer, but cannot completely verify the dquot ids are correct. Also, errors cannot be repaired, so an additional function is added to repair bad dquots in the buffer if such an error is detected in a context where repair is allowed.
Quoted 5 lines
Signed-off-by Dave Chinner<[email protected]>Reviewed-by Phil White<[email protected]>---
V2: quotacheck wasn't verifying dquots as they were read from disk
FYI:
The xfs_quota program does not generate output with V2 which causes xfstest 050 to fails.
--Mark.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 18 lines · Mark Tinguely
Quoted 11 lines · Dave Chinner
xfs: verify dquot blocks as they are read from disk
From: Dave Chinner<[email protected]>
Add a dquot buffer verify callback function and pass it into the buffer read functions. This checks all the dquots in a buffer, but cannot completely verify the dquot ids are correct. Also, errors cannot be repaired, so an additional function is added to repair bad dquots in the buffer if such an error is detected in a context where repair is allowed.
Quoted 5 lines
Signed-off-by Dave Chinner<[email protected]>Reviewed-by Phil White<[email protected]>---
V2: quotacheck wasn't verifying dquots as they were read from disk
Quoted 4 lines
FYI:
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.
I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact xfs_quota behaviour. The test passes just fine here:
$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch
050 14s ... 15s
Ran: 050
Passed all 1 tests
So perhaps there's something else going wrong on your machine?
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 38 lines · Dave Chinner
Quoted 18 lines · Mark Tinguely
Quoted 11 lines · Dave Chinner
xfs: verify dquot blocks as they are read from disk
From: Dave Chinner<[email protected]>
Add a dquot buffer verify callback function and pass it into the buffer read functions. This checks all the dquots in a buffer, but cannot completely verify the dquot ids are correct. Also, errors cannot be repaired, so an additional function is added to repair bad dquots in the buffer if such an error is detected in a context where repair is allowed.
Quoted 5 lines
Signed-off-by Dave Chinner<[email protected]>Reviewed-by Phil White<[email protected]>---
V2: quotacheck wasn't verifying dquots as they were read from diskQuoted 4 lines
FYI:
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch050 14s ... 15s
Ran: 050
Passed all 1 tests
Quoted 5 lines
So perhaps there's something else going wrong on your machine?
Cheers,
Dave.
I will do more investigating. With V2 050 output:
QA output created by 050
*** user
meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
data = bsize=XXX blocks=XXX, imaxpct=PCT
= sunit=XXX swidth=XXX, unwritten=X
naming =VERN bsize=XXX
log =LDEV bsize=XXX blocks=XXX
realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
*** report no quota settings
*** report initial settings
*** push past the soft inode limit
*** push past the soft block limit
...
Maybe it is my xfs_quota app, although it works fine with V1 kernel sources.
--Mark.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 32 lines · Mark Tinguely
Quoted 14 lines · Dave Chinner
Quoted 2 lines · Mark Tinguely
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratchQuoted 5 lines
050 14s ... 15s
Ran: 050
Passed all 1 testsSo perhaps there's something else going wrong on your machine?
I will do more investigating. With V2 050 output:
QA output created by 050
*** user
meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
data = bsize=XXX blocks=XXX, imaxpct=PCT
= sunit=XXX swidth=XXX, unwritten=X
naming =VERN bsize=XXX
log =LDEV bsize=XXX blocks=XXX
realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
Quoted 7 lines
*** report no quota settings
*** report initial settings
*** push past the soft inode limit
*** push past the soft block limit
Curious. There aren't any errors in the syslog/dmesg saying that buffers failed verification during the quota check runs, are there? Also, what platform are you testing on?
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 41 lines · Dave Chinner
Quoted 32 lines · Mark Tinguely
Quoted 14 lines · Dave Chinner
Quoted 2 lines · Mark Tinguely
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratchQuoted 5 lines
050 14s ... 15s
Ran: 050
Passed all 1 testsSo perhaps there's something else going wrong on your machine?
I will do more investigating. With V2 050 output:
QA output created by 050
*** user
meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
data = bsize=XXX blocks=XXX, imaxpct=PCT
= sunit=XXX swidth=XXX, unwritten=X
naming =VERN bsize=XXX
log =LDEV bsize=XXX blocks=XXX
realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXXQuoted 7 lines
*** report no quota settings
*** report initial settings
*** push past the soft inode limit
*** push past the soft block limit
Quoted 7 lines
Curious. There aren't any errors in the syslog/dmesg saying that buffers failed verification during the quota check runs, are there? Also, what platform are you testing on?
Cheers,
Dave.
No error message in dmesg nor /var/log/messages
This is a x86_64.
It is running OSS with most recent commit:
commit 579b62faa5fb16ffeeb88cda5e2c4e95730881af
Your two series:
xfs: fixes for 3.7-rc6 xfs: current queue for 3.8
I added the XFS_SB_VERSION2_CRCBIT attribute to xfsprogs and enabled it in mkfs.xfs and remade the test/scratch filesystems.
I will refresh the kernel when the rest of the 3.8 queue series is updated in OSS.
--Mark.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 33 lines · Mark Tinguely
Quoted 20 lines · Dave Chinner
Quoted 19 lines · Mark Tinguely
Quoted 18 lines · Dave Chinner
Quoted 2 lines · Mark Tinguely
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch050 14s ... 15s
Ran: 050
Passed all 1 testsQuoted 5 lines
Quoted 1 line
Quoted 1 line
So perhaps there's something else going wrong on your machine?
Curious. There aren't any errors in the syslog/dmesg saying that buffers failed verification during the quota check runs, are there? Also, what platform are you testing on?
No error message in dmesg nor
/var/log/messagesThis is a
x86_64.It is running OSS with most recent commit:
Quoted 8 lines
commit
579b62faa5fb16ffeeb88cda5e2c4e95730881afYour two series:
xfs: fixes for 3.7-rc6 xfs: current queue for 3.8I added the
XFS_SB_VERSION2_CRCBITattribute to xfsprogs and enabled it in mkfs.xfs and remade the test/scratch filesystems.
That's likely your problem. Why are you testing with this bit set - that's to indicate that there are on disk format changes, and none of them occur in this patch set. Hence the kernel should be refusing to mount any filesystem with that bit set. As such, I'm using a standard userspace for all this regression testing, because filesystems with the CRC bit should be failed during mount on 3.8.
/me goes looking....
Ok, the kernel isn't refusing to mount when that bit is set. That's a bug in the patch that introduces the CRC bit that I borked when splitting it out of a larger patch. I'll send an updated patch (it's the xfs: add CRC infrastructure patch).
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 50 lines · Dave Chinner
Quoted 33 lines · Mark Tinguely
Quoted 20 lines · Dave Chinner
Quoted 19 lines · Mark Tinguely
Quoted 18 lines · Dave Chinner
Quoted 2 lines · Mark Tinguely
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch050 14s ... 15s
Ran: 050
Passed all 1 testsQuoted 5 lines
Quoted 1 line
Quoted 1 line
So perhaps there's something else going wrong on your machine?
Curious. There aren't any errors in the syslog/dmesg saying that buffers failed verification during the quota check runs, are there? Also, what platform are you testing on?
No error message in dmesg nor
/var/log/messagesThis is a
x86_64.It is running OSS with most recent commit:
Quoted 8 lines
commit
579b62faa5fb16ffeeb88cda5e2c4e95730881afYour two series:
xfs: fixes for 3.7-rc6 xfs: current queue for 3.8I added the
XFS_SB_VERSION2_CRCBITattribute to xfsprogs and enabled it in mkfs.xfs and remade the test/scratch filesystems.That's likely your problem. Why are you testing with this bit set - that's to indicate that there are on disk format changes, and none of them occur in this patch set. Hence the kernel should be refusing to mount any filesystem with that bit set. As such, I'm using a standard userspace for all this regression testing, because filesystems with the CRC bit should be failed during mount on 3.8.
Quoted 6 lines
/me goes looking....
Ok, the kernel isn't refusing to mount when that bit is set. That's a bug in the patch that introduces the CRC bit that I borked when splitting it out of a larger patch. I'll send an updated patch (it's the xfs: add CRC infrastructure patch).
FWIW, if I intended this patch set to be tested with a feature bit set or modified userspace, I would have posted patches that modify the userspace tools appropriately. If you see something that requires userspace tool modification to make use of, then you should be asking questions about that during review rather than quietly modifying userspace tools yourself to test said changes.
In most cases, enabling kernel feature bits (i.e. presence in the GOOD flags) without corresponding changes to userspace is a bug, as demonstrated here...
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
In reply to Dave ChinnerQuoted 50 lines · Dave Chinner
Quoted 33 lines · Mark Tinguely
Quoted 20 lines · Dave Chinner
Quoted 19 lines · Mark Tinguely
Quoted 18 lines · Dave Chinner
Quoted 2 lines · Mark Tinguely
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch050 14s ... 15s
Ran: 050
Passed all 1 testsQuoted 5 lines
Quoted 1 line
Quoted 1 line
So perhaps there's something else going wrong on your machine?
Curious. There aren't any errors in the syslog/dmesg saying that buffers failed verification during the quota check runs, are there? Also, what platform are you testing on?
No error message in dmesg nor
/var/log/messagesThis is a
x86_64.It is running OSS with most recent commit:
Quoted 8 lines
commit
579b62faa5fb16ffeeb88cda5e2c4e95730881afYour two series:
xfs: fixes for 3.7-rc6 xfs: current queue for 3.8I added the
XFS_SB_VERSION2_CRCBITattribute to xfsprogs and enabled it in mkfs.xfs and remade the test/scratch filesystems.That's likely your problem. Why are you testing with this bit set - that's to indicate that there are on disk format changes, and none of them occur in this patch set. Hence the kernel should be refusing to mount any filesystem with that bit set. As such, I'm using a standard userspace for all this regression testing, because filesystems with the CRC bit should be failed during mount on 3.8.
Quoted 7 lines
/me goes looking....
Ok, the kernel isn't refusing to mount when that bit is set. That's a bug in the patch that introduces the CRC bit that I borked when splitting it out of a larger patch. I'll send an updated patch (it's the xfs: add CRC infrastructure patch).
removing the attribute bit from the filesystem/tools does not change the failure on 050 with V2 patches.
--Mark.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 53 lines · Mark Tinguely
Quoted 52 lines · Dave Chinner
Quoted 33 lines · Mark Tinguely
Quoted 20 lines · Dave Chinner
Quoted 19 lines · Mark Tinguely
Quoted 18 lines · Dave Chinner
Quoted 2 lines · Mark Tinguely
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch050 14s ... 15s
Ran: 050
Passed all 1 testsQuoted 5 lines
Quoted 1 line
Quoted 1 line
So perhaps there's something else going wrong on your machine?
Curious. There aren't any errors in the syslog/dmesg saying that buffers failed verification during the quota check runs, are there? Also, what platform are you testing on?
No error message in dmesg nor
/var/log/messagesThis is a
x86_64.It is running OSS with most recent commit:
Quoted 8 lines
commit
579b62faa5fb16ffeeb88cda5e2c4e95730881afYour two series:
xfs: fixes for 3.7-rc6 xfs: current queue for 3.8I added the
XFS_SB_VERSION2_CRCBITattribute to xfsprogs and enabled it in mkfs.xfs and remade the test/scratch filesystems.That's likely your problem. Why are you testing with this bit set - that's to indicate that there are on disk format changes, and none of them occur in this patch set. Hence the kernel should be refusing to mount any filesystem with that bit set. As such, I'm using a standard userspace for all this regression testing, because filesystems with the CRC bit should be failed during mount on 3.8.
/me goes looking....
Quoted 8 lines
Quoted 5 lines
Ok, the kernel isn't refusing to mount when that bit is set. That's a bug in the patch that introduces the CRC bit that I borked when splitting it out of a larger patch. I'll send an updated patch (it's the xfs: add CRC infrastructure patch).
removing the attribute bit from the filesystem/tools does not change the failure on 050 with V2 patches.
Can you join #xfs on freenode so we can discuss this in realtime? There's way too much latency on email....
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 17/32 V2] xfs: verify dquot blocks as they are read from disk
Quoted 60 lines · Dave Chinner
Quoted 59 lines · Mark Tinguely
Quoted 57 lines · Dave Chinner
Quoted 33 lines · Mark Tinguely
Quoted 20 lines · Dave Chinner
Quoted 19 lines · Mark Tinguely
Quoted 18 lines · Dave Chinner
Quoted 2 lines · Mark Tinguely
The
xfs_quotaprogram does not generate output with V2 which causes xfstest 050 to fails.I don't think that has anything to do with this patch orthechange for V2 - V2 only changes quotacheck behaviour, and that doesn't impact
xfs_quotabehaviour. The test passes just fine here:$ sudo ./check 050 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test-2 3.7.0-rc5-dgc+ MKFS_OPTIONS -- -f -bsize=4096 /dev/vdb MOUNT_OPTIONS -- /dev/vdb /mnt/scratch050 14s ... 15s
Ran: 050
Passed all 1 testsQuoted 5 lines
Quoted 1 line
Quoted 1 line
So perhaps there's something else going wrong on your machine?
Curious. There aren't any errors in the syslog/dmesg saying that buffers failed verification during the quota check runs, are there? Also, what platform are you testing on?
No error message in dmesg nor
/var/log/messagesThis is a
x86_64.It is running OSS with most recent commit:
Quoted 8 lines
commit
579b62faa5fb16ffeeb88cda5e2c4e95730881afYour two series:
xfs: fixes for 3.7-rc6 xfs: current queue for 3.8I added the
XFS_SB_VERSION2_CRCBITattribute to xfsprogs and enabled it in mkfs.xfs and remade the test/scratch filesystems.That's likely your problem. Why are you testing with this bit set - that's to indicate that there are on disk format changes, and none of them occur in this patch set. Hence the kernel should be refusing to mount any filesystem with that bit set. As such, I'm using a standard userspace for all this regression testing, because filesystems with the CRC bit should be failed during mount on 3.8.
/me goes looking....
Ok, the kernel isn't refusing to mount when that bit is set. That's a bug in the patch that introduces the CRC bit that I borked when splitting it out of a larger patch. I'll send an updated patch (it's the xfs: add CRC infrastructure patch).
Quoted 5 lines
Quoted 2 lines
removing the attribute bit from the filesystem/tools does not change the failure on 050 with V2 patches.
Can you join #xfs on freenode so we can discuss this in realtime? There's way too much latency on email....
To keep everyone in the loop:
TL,DR: A bug in xfs_quota, exposed by the repeated output fix, patch already on the list to fix it.
Longer:
[16/11/12 09:41] <dchinner> tinguely: ping
[16/11/12 09:41] <tinguely> The xfstests 050 must be something I am doing wrong on the x86_64 machine because I just tried the same source on a x86_32 machine and they work fine. [16/11/12 09:41] <dchinner> what does strace tell you?
[16/11/12 09:42] <dchinner> is xfs_quota actually getting anything back from the kernel?
[16/11/12 09:52] <tinguely> I don;t see xfs_quota doing a ioctl.
[16/11/12 09:58] <dchinner> it's quotactl() cals you need to look for, not ioctl
[16/11/12 09:58] <dchinner> something like:
[16/11/12 09:58] <dchinner> quotactl(Q_XGETQUOTA|0x2 /* ???QUOTA */, "/dev/vdb", 0, {version=1, flags=XFS_PROJ_QUOTA, .....
[16/11/12 09:59] <dchinner> all I've done is modified 050 so it doesn't remove it's temporary files
[16/11/12 09:59] <tinguely> there are none. It seems like the program dies immediately
[16/11/12 09:59] <dchinner> what command are you running?
[16/11/12 10:00] <dchinner> can you pastebin the strace output?
[16/11/12 10:01] <tinguely> There is only one call to /usr/bin/quota and one to /usr/sbin/xfs_quota
[16/11/12 10:02] <dchinner> I'm not sure what you are running - you are tracing 050?
[16/11/12 10:03] <dchinner> what you need to do is modify 050 to not remove temporary files (comment it out of the cleanup function)
[16/11/12 10:03] <dchinner> run 050
[16/11/12 10:03] <dchinner> then find the projid files in /tmp
[16/11/12 10:03] <dchinner> mount scratch with project quota
[16/11/12 10:04] <dchinner> and run the last xfs_quota comand under strace like:
[16/11/12 10:04] <dchinner> $ sudo strace xfs_quota -x -D /tmp/6345.projects -P /tmp/6345.projid -c "repquota -birnN -p" /dev/vdb
[16/11/12 10:25] <tinguely> after the libraries are loaded xfs_quota does:
[16/11/12 10:25] <tinguely> access("/proc/self/mounts", R_OK) = 0
[16/11/12 10:25] <tinguely> open("/proc/self/mounts", O_RDONLY) = 3
[16/11/12 10:25] <tinguely> fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
[16/11/12 10:25] <tinguely> mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0e4e147000
[16/11/12 10:25] <tinguely> read(3, "rootfs / rootfs rw 0 0\ndevtmpfs "..., 1024) = 1024
[16/11/12 10:25] <tinguely> read(3, "cls 0 0\ncgroup /sys/fs/cgroup/bl"..., 1024) = 788
[16/11/12 10:25] <tinguely> stat("/test2", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
[16/11/12 10:25] <tinguely> close(3) = 0
[16/11/12 10:25] <tinguely> munmap(0x7f0e4e147000, 4096) = 0
[16/11/12 10:25] <tinguely> open("/tmp/8282.projects", O_RDONLY) = 3[16/11/12 10:25] <tinguely> fstat(3, {st_mode=S_IFREG|0644, st_size=9, ...}) = 0
[16/11/12 10:25] <tinguely> mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0e4e147000
[16/11/12 10:26] <tinguely> read(3, "1:/test2\n", 4096) = 9
[16/11/12 10:26] <tinguely> stat("/test2", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0 [16/11/12 10:26] <tinguely> stat("/test2", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
[16/11/12 10:26] <tinguely> read(3, "", 4096) = 0 [16/11/12 10:26] <tinguely> close(3) = 0 [16/11/12 10:26] <tinguely> munmap(0x7f0e4e147000, 4096) = 0 [16/11/12 10:26] <tinguely> exit_group(0) = ?
[16/11/12 10:26] <tinguely> scratch is mounted: /dev/sda3 /test2 xfs rw,pquota 0 0
[16/11/12 10:26] <dchinner> what command did you run?
[16/11/12 10:27] * sandeen points at a pastebin ;)
[16/11/12 10:27] <dchinner> FWIW, it is faster and better to use pastebins for large amounts of info (e.g. pastebin.org) [16/11/12 10:27] <tinguely> strace xfs_quota -D /tmp/8282.projects -P /tmp/8282.projid -x -c "repquota -birnN -p" /dev/sda3 [16/11/12 10:27] <dchinner> snap!
[16/11/12 10:29] <dchinner> so it hasn't tried to read the projid file at all
[16/11/12 10:31] <dchinner> tinguely: how is xfs-quota supposed to translate /dev/sda3 to a filesystem mount point? [16/11/12 10:32] <tinguely> sorry got SCRATCH_MNT and SCRATCH_DEV switched on the copy.
[16/11/12 10:33] <dchinner> no, the test does lookup via SCRATCH_DEV
[16/11/12 10:34] <dchinner> what's in /proc/self/mounts ?
[16/11/12 10:34] <tinguely> /dev/sda2 /test1 xfs rw,relatime,attr2,inode64,noquota 0 0
[16/11/12 10:34] <tinguely> /dev/sda3 /test2 xfs rw,relatime,attr2,inode64,prjquota 0 0
[16/11/12 10:37] <tinguely> open("/proc/self/mounts", O_RDONLY) = 3
[16/11/12 10:37] <tinguely> open("/tmp/8282.projects", O_RDONLY) = 3
[16/11/12 10:38] <tinguely> read(3, "1:/test2\n", 4096) = 9
[16/11/12 10:38] <tinguely> stat("/test2", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
[16/11/12 10:38] <tinguely> stat("/test2", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
[16/11/12 10:38] <tinguely> read(3, "", 4096) = 0
[16/11/12 10:38] <tinguely> close(3) = 0
[16/11/12 10:38] <tinguely> munmap(0x7fc89aa63000, 4096) = 0
[16/11/12 10:38] <tinguely> exit_group(0) = ?[16/11/12 10:40] <dchinner> Ok, so it's terminating somewhere in xfs_quota
[16/11/12 10:40] <dchinner> i.e. not a kernel problem
[16/11/12 10:41] <tinguely> yep.
[16/11/12 10:41] * dchinner goes and updates his test machines to his current xfsprogs dev tree rather than the current -rc
[16/11/12 10:42] <tinguely> I will do a full source tree update tomorrow. don't know why v1 works.
[16/11/12 10:49] <dchinner> I see that the problem is a recent modification to xfs_quota
[16/11/12 10:50] <dchinner> i.e. the patch to stop outputs being repeated multiple times
[16/11/12 10:50] <dchinner> if you add the "-a" flag, it works
[16/11/12 10:51] <dchinner> the problem has something to do with the way the fstable is initialised
[16/11/12 10:52] <sandeen> dchinner, which commit? I don't see much in quota/ ?
[16/11/12 10:52] <dchinner> it's not committed yet
[16/11/12 10:52] <dchinner> it's a patch I sent a week ago or so
[16/11/12 10:53] <sandeen> oh
[16/11/12 11:03] <tinguely> xfs_quota: fix report command parsing
[16/11/12 11:05] <tinguely> yep, I had that installed.
[16/11/12 11:15] <dchinner> there's some deeper screwiness going on with xfs-quota here
[16/11/12 11:15] <dchinner> the original version works if you give it the command line "-c" option
[16/11/12 11:15] <dchinner> but if you run the same command interactively, it gives no output
[16/11/12 11:16] <dchinner> so it looks like all I've done is expose an existing bug
[16/11/12 11:17] <tinguely> Do you want me to tell Rich to hold commiting the patch?
[16/11/12 11:18] <dchinner> yes, all I've done is made the command line version get called in exactly the same way as the interactive command is called
[16/11/12 11:18] <dchinner> tinguely: doesn't matter, either way it is a separate patch
[16/11/12 11:18] <tinguely> okay, lets put it in. It is not a major issue.
[16/11/12 11:20] <dchinner> ok, now I understand a bit better
[16/11/12 11:21] <dchinner> this is a maze of twisty passages
[16/11/12 11:22] <dchinner> the original problem was that the report command was being called multiple times, once for each entry in the fs table
[16/11/12 11:24] <dchinner> this is very non-obvious, because the iteration of the table is done via a callback that is only executed if the command is not marked as CMD_FLAG_GLOBAL
[16/11/12 11:25] <dchinner> and that table iteration is done by setting a global variable "fs_path" to a different index in the table in teh callback
[16/11/12 11:26] <dchinner> Now the fs table contains more than just mount points - it also contains project quota root directories
[16/11/12 11:26] <dchinner> and the initialisation of the table uses the fs_path global variable to initialise the entry
[16/11/12 11:26] <dchinner> so when initialisation is complete, fs_path points at teh last entry that was entered into the table.
[16/11/12 11:27] <dchinner> That will *always* be a project path if they are configured on the system.
[16/11/12 11:28] <dchinner> so now, if we treat the report command as global, we don't ever re-initialise fs_path to point to the device/mountpt that was specified on the command line
[16/11/12 11:28] <tinguely> ouch
[16/11/12 11:29] <dchinner> and so when the report command is run, it points to a project path and ignores it.
[16/11/12 11:32] <dchinner> the original problem was that for a given report command, it can iterate the entire fstable itself (e.g. the -a flag for "all mounts"), so when it gets called for each table entry, and iterates the entire table itself, you get multiple outputs [16/11/12 11:34] <dchinner> so the original fix for this is good, it's just left us tripping over an incorrectly initialised fs_path pointer.
....
[16/11/12 12:14] <dchinner> patch sent
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 18/32 xfs: add verifier callback to directory read code
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
--- fs/xfs/xfs_attr.c | 23 ++++++++++++----------- fs/xfs/xfs_attr_leaf.c | 18 +++++++++--------- fs/xfs/xfs_da_btree.c | 44 ++++++++++++++++++++++++++++---------------- fs/xfs/xfs_da_btree.h | 7 ++++--- fs/xfs/xfs_dir2_block.c | 23 ++++++++++++----------- fs/xfs/xfs_dir2_leaf.c | 33 ++++++++++++++++----------------- fs/xfs/xfs_dir2_node.c | 43 ++++++++++++++++++++----------------------- fs/xfs/xfs_file.c | 2 +- 8 files changed, 102 insertions(+), 91 deletions(-)
fs/xfs/xfs_attr.c +12 -11
@@ -904,7 +904,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) dp = args->dp; args->blkno =0 ; error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error)return (error);ASSERT (bp !=NULL );
@@ -1032,7 +1032,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)* remove the "old" attr from that block (neat, huh!) */ error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , - &bp,XFS_ATTR_FORK ); + &bp,XFS_ATTR_FORK ,NULL );if (error)return (error);ASSERT (bp !=NULL );
@@ -1101,7 +1101,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) dp = args->dp; args->blkno =0 ; error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error) {return (error); }
@@ -1159,7 +1159,7 @@ xfs_attr_leaf_get(xfs_da_args_t *args) args->blkno =0 ; error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error)return (error);ASSERT (bp !=NULL );
@@ -1190,7 +1190,8 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)trace_xfs_attr_leaf_list (context); context->cursor->blkno =0 ; - error =xfs_da_read_buf (NULL , context->dp,0 ,-1 , &bp,XFS_ATTR_FORK ); + error =xfs_da_read_buf (NULL , context->dp,0 ,-1 , &bp,XFS_ATTR_FORK , +NULL );if (error)return XFS_ERROR (error);ASSERT (bp !=NULL );
@@ -1605,7 +1606,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) state->path.blk[0 ].bp =NULL ; error =xfs_da_read_buf (args->trans, args->dp,0 ,-1 , &bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error) goto out; ASSERT((((xfs_attr_leafblock_t *)bp->b_addr)->hdr.info.magic) ==
@@ -1718,7 +1719,7 @@ xfs_attr_refillstate(xfs_da_state_t *state) error =xfs_da_read_buf (state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, - &blk->bp,XFS_ATTR_FORK ); + &blk->bp,XFS_ATTR_FORK ,NULL );if (error)return (error); }else {
@@ -1737,7 +1738,7 @@ xfs_attr_refillstate(xfs_da_state_t *state) error =xfs_da_read_buf (state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, - &blk->bp,XFS_ATTR_FORK ); + &blk->bp,XFS_ATTR_FORK ,NULL );if (error)return (error); }else {
@@ -1827,7 +1828,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) bp =NULL ;if (cursor->blkno >0 ) { error =xfs_da_read_buf (NULL , context->dp, cursor->blkno,-1 , - &bp,XFS_ATTR_FORK ); + &bp,XFS_ATTR_FORK ,NULL );if ((error !=0 ) && (error !=EFSCORRUPTED ))return (error);if (bp) {
@@ -1870,7 +1871,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)for (;;) { error =xfs_da_read_buf (NULL , context->dp, cursor->blkno,-1 , &bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error)return (error);if (unlikely (bp ==NULL )) {
@@ -1937,7 +1938,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) cursor->blkno =be32_to_cpu (leaf->hdr.info.forw);xfs_trans_brelse (NULL , bp); error =xfs_da_read_buf (NULL , context->dp, cursor->blkno,-1 , - &bp,XFS_ATTR_FORK ); + &bp,XFS_ATTR_FORK ,NULL );if (error)return (error);if (unlikely ((bp ==NULL ))) {
fs/xfs/xfs_attr_leaf.c +9 -9
@@ -871,7 +871,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args)if (error) goto out; error =xfs_da_read_buf (args->trans, args->dp,0 ,-1 , &bp1, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error) goto out;ASSERT (bp1 !=NULL );
@@ -1642,7 +1642,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)if (blkno ==0 )continue ; error =xfs_da_read_buf (state->args->trans, state->args->dp, - blkno,-1 , &bp,XFS_ATTR_FORK ); + blkno,-1 , &bp,XFS_ATTR_FORK ,NULL );if (error)return (error);ASSERT (bp !=NULL );
@@ -2519,7 +2519,7 @@ xfs_attr_leaf_clearflag(xfs_da_args_t *args)* Set up the operation. */ error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error) {return (error); }
@@ -2584,7 +2584,7 @@ xfs_attr_leaf_setflag(xfs_da_args_t *args)* Set up the operation. */ error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error) {return (error); }
@@ -2641,7 +2641,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)* Read the block containing the "old" attr */ error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp1, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error) {return (error); }
@@ -2652,7 +2652,7 @@ xfs_attr_leaf_flipflags(xfs_da_args_t *args)*/ if (args->blkno2 != args->blkno) { error =xfs_da_read_buf (args->trans, args->dp, args->blkno2, --1 , &bp2,XFS_ATTR_FORK ); +-1 , &bp2,XFS_ATTR_FORK ,NULL );if (error) {return (error); }
@@ -2753,7 +2753,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)* the extents in reverse order the extent containing * block 0 must still be there. */ - error =xfs_da_read_buf (*trans, dp,0 ,-1 , &bp,XFS_ATTR_FORK ); + error =xfs_da_read_buf (*trans, dp,0 ,-1 , &bp,XFS_ATTR_FORK ,NULL );if (error)return (error); blkno =XFS_BUF_ADDR (bp);
@@ -2839,7 +2839,7 @@ xfs_attr_node_inactive(* before we come back to this one. */ error =xfs_da_read_buf (*trans, dp, child_fsb,-2 , &child_bp, -XFS_ATTR_FORK ); +XFS_ATTR_FORK ,NULL );if (error)return (error);if (child_bp) {
@@ -2880,7 +2880,7 @@ xfs_attr_node_inactive(*/ if ((i+1 ) < count) { error =xfs_da_read_buf (*trans, dp,0 , parent_blkno, - &bp,XFS_ATTR_FORK ); + &bp,XFS_ATTR_FORK ,NULL );if (error)return (error); child_fsb =be32_to_cpu (node->btree[i+1 ].before);
fs/xfs/xfs_da_btree.c +28 -16
140 lines not on this page · raw message
fs/xfs/xfs_da_btree.h +4 -3
@@ -18,7 +18,6 @@#ifndef __XFS_DA_BTREE_H__#define __XFS_DA_BTREE_H__ -struct xfs_buf ;struct xfs_bmap_free ;struct xfs_inode ;struct xfs_mount ;
@@ -226,9 +225,11 @@ int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp, struct xfs_buf **bp, int whichfork);int xfs_da_read_buf (struct xfs_trans *trans,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mappedbno, -struct xfs_buf **bpp,int whichfork); +struct xfs_buf **bpp,int whichfork, +xfs_buf_iodone_t verifier);xfs_daddr_t xfs_da_reada_buf (struct xfs_trans *trans,struct xfs_inode *dp, -xfs_dablk_t bno,int whichfork); +xfs_dablk_t bno,int whichfork, +xfs_buf_iodone_t verifier);int xfs_da_shrink_inode (xfs_da_args_t *args,xfs_dablk_t dead_blkno,struct xfs_buf *dead_buf);
fs/xfs/xfs_dir2_block.c +12 -11
@@ -97,10 +97,10 @@ xfs_dir2_block_addname(/* * Read the (one and only) directory block into dabuf bp. */ -if ((error = -xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &bp,XFS_DATA_FORK ))) { + error =xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &bp, +XFS_DATA_FORK ,NULL ); +if (error)return error; - }ASSERT (bp !=NULL ); hdr = bp->b_addr;/*
@@ -457,7 +457,7 @@ xfs_dir2_block_getdents(* Can't read the block, give up, else get dabuf in bp. */ error =xfs_da_read_buf (NULL , dp, mp->m_dirdatablk,-1 , - &bp,XFS_DATA_FORK ); + &bp,XFS_DATA_FORK ,NULL );if (error)return error;
@@ -640,10 +640,10 @@ xfs_dir2_block_lookup_int(/* * Read the buffer, return error if we can't get it. */ -if ((error = -xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &bp,XFS_DATA_FORK ))) { + error =xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &bp, +XFS_DATA_FORK ,NULL ); +if (error)return error; - }ASSERT (bp !=NULL ); hdr = bp->b_addr;xfs_dir2_data_check (dp, bp);
@@ -917,10 +917,11 @@ xfs_dir2_leaf_to_block(/* * Read the data block if we don't already have it, give up if it fails. */ -if (dbp ==NULL && - (error =xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &dbp, -XFS_DATA_FORK ))) { -return error; +if (!dbp) { + error =xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &dbp, +XFS_DATA_FORK ,NULL ); +if (error) +return error; } hdr = dbp->b_addr;ASSERT (hdr->magic ==cpu_to_be32 (XFS_DIR2_DATA_MAGIC ));
fs/xfs/xfs_dir2_leaf.c +16 -17
@@ -315,10 +315,9 @@ xfs_dir2_leaf_addname(* Read the leaf block. */ error =xfs_da_read_buf (tp, dp, mp->m_dirleafblk,-1 , &lbp, -XFS_DATA_FORK ); -if (error) { +XFS_DATA_FORK ,NULL ); +if (error)return error; - }ASSERT (lbp !=NULL );/* * Look up the entry by hash value and name.
@@ -500,9 +499,9 @@ xfs_dir2_leaf_addname(* Just read that one in. */ else { -if ((error = -xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, use_block), --1 , &dbp,XFS_DATA_FORK ))) { + error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, use_block), +-1 , &dbp,XFS_DATA_FORK ,NULL ); +if (error) {xfs_trans_brelse (tp, lbp);return error; }
@@ -895,7 +894,7 @@ xfs_dir2_leaf_readbuf( error =xfs_da_read_buf (NULL , dp, map->br_startoff, map->br_blockcount >= mp->m_dirblkfsbs ?XFS_FSB_TO_DADDR (mp, map->br_startblock) :-1 , - &bp,XFS_DATA_FORK ); + &bp,XFS_DATA_FORK ,NULL );/* * Should just skip over the data block instead of giving up.
@@ -938,7 +937,7 @@ xfs_dir2_leaf_readbuf(xfs_da_reada_buf (NULL , dp, map[mip->ra_index].br_startoff + mip->ra_offset, -XFS_DATA_FORK ); +XFS_DATA_FORK ,NULL ); mip->ra_current = i; }
@@ -1376,7 +1375,7 @@ xfs_dir2_leaf_lookup_int(* Read the leaf block into the buffer. */ error =xfs_da_read_buf (tp, dp, mp->m_dirleafblk,-1 , &lbp, -XFS_DATA_FORK ); +XFS_DATA_FORK ,NULL );if (error)return error; *lbpp = lbp;
@@ -1411,7 +1410,7 @@ xfs_dir2_leaf_lookup_int(xfs_trans_brelse (tp, dbp); error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, newdb), --1 , &dbp,XFS_DATA_FORK ); +-1 , &dbp,XFS_DATA_FORK ,NULL );if (error) {xfs_trans_brelse (tp, lbp);return error;
@@ -1453,7 +1452,7 @@ xfs_dir2_leaf_lookup_int(xfs_trans_brelse (tp, dbp); error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, cidb), --1 , &dbp,XFS_DATA_FORK ); +-1 , &dbp,XFS_DATA_FORK ,NULL );if (error) {xfs_trans_brelse (tp, lbp);return error;
@@ -1738,10 +1737,10 @@ xfs_dir2_leaf_trim_data(/* * Read the offending data block. We need its buffer. */ -if ((error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, db),-1 , &dbp, -XFS_DATA_FORK ))) { + error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, db),-1 , &dbp, +XFS_DATA_FORK ,NULL ); +if (error)return error; - } leaf = lbp->b_addr; ltp =xfs_dir2_leaf_tail_p (mp, leaf);
@@ -1864,10 +1863,10 @@ xfs_dir2_node_to_leaf(/* * Read the freespace block. */ -if ((error =xfs_da_read_buf (tp, dp, mp->m_dirfreeblk,-1 , &fbp, -XFS_DATA_FORK ))) { + error =xfs_da_read_buf (tp, dp, mp->m_dirfreeblk,-1 , &fbp, +XFS_DATA_FORK ,NULL ); +if (error)return error; - } free = fbp->b_addr;ASSERT (free->hdr.magic ==cpu_to_be32 (XFS_DIR2_FREE_MAGIC ));ASSERT (!free->hdr.firstdb);
fs/xfs/xfs_dir2_node.c +20 -23
96 lines not on this page · raw message
fs/xfs/xfs_file.c +1 -1
@@ -891,7 +891,7 @@ xfs_dir_open(*/ mode =xfs_ilock_map_shared (ip);if (ip->i_d.di_nextents >0 ) -xfs_da_reada_buf (NULL , ip,0 ,XFS_DATA_FORK ); +xfs_da_reada_buf (NULL , ip,0 ,XFS_DATA_FORK ,NULL );xfs_iunlock (ip, mode);return 0 ; }
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 19/32 xfs: factor dir2 block read operations
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
In preparation for verifying dir2 block format buffers, factor the read operations out of the block operations (lookup, addname, getdents) and some of the additional logic to make it easier to understand an dmodify the code.
--- fs/xfs/xfs_dir2_block.c | 386 +++++++++++++++++++++++++---------------------- 1 file changed, 209 insertions(+), 177 deletions(-)
fs/xfs/xfs_dir2_block.c +209 -177
@@ -56,6 +56,178 @@ xfs_dir_startup(void) xfs_dir_hash_dotdot =xfs_da_hashname ((unsigned char *)".." ,2 ); } +static int +xfs_dir2_block_read ( +struct xfs_trans *tp, +struct xfs_inode *dp, +struct xfs_buf **bpp) +{ +struct xfs_mount *mp = dp->i_mount; + +return xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , bpp, +XFS_DATA_FORK ,NULL ); +} + +static void +xfs_dir2_block_need_space ( +struct xfs_dir2_data_hdr *hdr, +struct xfs_dir2_block_tail *btp, +struct xfs_dir2_leaf_entry *blp, +__be16 **tagpp, +struct xfs_dir2_data_unused **dupp, +struct xfs_dir2_data_unused **enddupp, +int *compact, +int len) +{ +struct xfs_dir2_data_free *bf; +__be16 *tagp =NULL ; +struct xfs_dir2_data_unused *dup =NULL ; +struct xfs_dir2_data_unused *enddup =NULL ; + + *compact =0 ; + bf = hdr->bestfree; + +/* +* If there are stale entries we'll use one for the leaf. +*/ +if (btp->stale) { +if (be16_to_cpu (bf[0 ].length) >= len) { +/* +* The biggest entry enough to avoid compaction. +*/ + dup = (xfs_dir2_data_unused_t *) + ((char *)hdr +be16_to_cpu (bf[0 ].offset)); + goto out; + } + +/* +* Will need to compact to make this work. +* Tag just before the first leaf entry. +*/ + *compact =1 ; + tagp = (__be16 *)blp -1 ; + +/* Data object just before the first leaf entry. */ + dup = (xfs_dir2_data_unused_t *)((char *)hdr +be16_to_cpu (*tagp)); + +/* +* If it's not free then the data will go where the +* leaf data starts now, if it works at all. +*/ +if (be16_to_cpu (dup->freetag) ==XFS_DIR2_DATA_FREE_TAG ) { +if (be16_to_cpu (dup->length) + (be32_to_cpu (btp->stale) -1 ) * + (uint )sizeof (*blp) < len) + dup =NULL ; + }else if ((be32_to_cpu (btp->stale) -1 ) * (uint )sizeof (*blp) < len) + dup =NULL ; +else + dup = (xfs_dir2_data_unused_t *)blp; + goto out; + } + +/* +* no stale entries, so just use free space. +* Tag just before the first leaf entry. +*/ + tagp = (__be16 *)blp -1 ; + +/* Data object just before the first leaf entry. */ + enddup = (xfs_dir2_data_unused_t *)((char *)hdr +be16_to_cpu (*tagp)); + +/* +* If it's not free then can't do this add without cleaning up: +* the space before the first leaf entry needs to be free so it +* can be expanded to hold the pointer to the new entry. +*/ +if (be16_to_cpu (enddup->freetag) ==XFS_DIR2_DATA_FREE_TAG ) { +/* +* Check out the biggest freespace and see if it's the same one. +*/ + dup = (xfs_dir2_data_unused_t *) + ((char *)hdr +be16_to_cpu (bf[0 ].offset)); +if (dup != enddup) { +/* +* Not the same free entry, just check its length. +*/ +if (be16_to_cpu (dup->length) < len) + dup =NULL ; + goto out; + } + +/* +* It is the biggest freespace, can it hold the leaf too? +*/ +if (be16_to_cpu (dup->length) < len + (uint )sizeof (*blp)) { +/* +* Yes, use the second-largest entry instead if it works. +*/ +if (be16_to_cpu (bf[1 ].length) >= len) + dup = (xfs_dir2_data_unused_t *) + ((char *)hdr +be16_to_cpu (bf[1 ].offset)); +else + dup =NULL ; + } + } +out: + *tagpp = tagp; + *dupp = dup; + *enddupp = enddup; +} + +/* +* compact the leaf entries. +* Leave the highest-numbered stale entry stale. +* XXX should be the one closest to mid but mid is not yet computed. +*/ +static void +xfs_dir2_block_compact ( +struct xfs_trans *tp, +struct xfs_buf *bp, +struct xfs_dir2_data_hdr *hdr, +struct xfs_dir2_block_tail *btp, +struct xfs_dir2_leaf_entry *blp, +int *needlog, +int *lfloghigh, +int *lfloglow) +{ +int fromidx;/* source leaf index */ +int toidx;/* target leaf index */ +int needscan =0 ; +int highstale;/* high stale index */ + + fromidx = toidx =be32_to_cpu (btp->count) -1 ; + highstale = *lfloghigh =-1 ; +for (; fromidx >=0 ; fromidx--) { +if (blp[fromidx].address ==cpu_to_be32 (XFS_DIR2_NULL_DATAPTR )) { +if (highstale ==-1 ) + highstale = toidx; +else { +if (*lfloghigh ==-1 ) + *lfloghigh = toidx; +continue ; + } + } +if (fromidx < toidx) + blp[toidx] = blp[fromidx]; + toidx--; + } + *lfloglow = toidx +1 - (be32_to_cpu (btp->stale) -1 ); + *lfloghigh -=be32_to_cpu (btp->stale) -1 ; +be32_add_cpu (&btp->count, -(be32_to_cpu (btp->stale) -1 )); +xfs_dir2_data_make_free (tp, bp, + (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), + (xfs_dir2_data_aoff_t)((be32_to_cpu (btp->stale) -1 ) *sizeof (*blp)), + needlog, &needscan); + blp +=be32_to_cpu (btp->stale) -1 ; + btp->stale =cpu_to_be32 (1 ); +/* +* If we now need to rebuild the bestfree map, do so. +* This needs to happen before the next call to use_free. +*/ +if (needscan) +xfs_dir2_data_freescan (tp->t_mountp, hdr, needlog); +} +/* * Add an entry to a block directory. */
@@ -63,7 +235,6 @@ int /* error */xfs_dir2_block_addname ( xfs_da_args_t *args) /* directory op arguments */ { -xfs_dir2_data_free_t *bf;/* bestfree table in block */ xfs_dir2_data_hdr_t *hdr;/* block header */ xfs_dir2_leaf_entry_t *blp;/* block leaf entries */ struct xfs_buf *bp;/* buffer for block */
@@ -94,134 +265,44 @@ xfs_dir2_block_addname( dp = args->dp; tp = args->trans; mp = dp->i_mount; -/* -* Read the (one and only) directory block into dabuf bp. -*/ - error =xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &bp, -XFS_DATA_FORK ,NULL ); + +/* Read the (one and only) directory block into bp. */ + error =xfs_dir2_block_read (tp, dp, &bp);if (error)return error; -ASSERT (bp !=NULL ); - hdr = bp->b_addr; -/* -* Check the magic number, corrupted if wrong. -*/ -if (unlikely (hdr->magic !=cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC ))) { -XFS_CORRUPTION_ERROR ("xfs_dir2_block_addname" , -XFS_ERRLEVEL_LOW , mp, hdr); -xfs_trans_brelse (tp, bp); -return XFS_ERROR (EFSCORRUPTED ); - } + len =xfs_dir2_data_entsize (args->namelen); +/* * Set up pointers to parts of the block. */ - bf = hdr->bestfree; + hdr = bp->b_addr; btp =xfs_dir2_block_tail_p (mp, hdr); blp =xfs_dir2_block_leaf_p (btp); +/* -* No stale entries? Need space for entry and new leaf. -*/ -if (!btp->stale) { -/* -* Tag just before the first leaf entry. -*/ - tagp = (__be16 *)blp -1 ; -/* -* Data object just before the first leaf entry. -*/ - enddup = (xfs_dir2_data_unused_t *)((char *)hdr +be16_to_cpu (*tagp)); -/* -* If it's not free then can't do this add without cleaning up: -* the space before the first leaf entry needs to be free so it -* can be expanded to hold the pointer to the new entry. -*/ -if (be16_to_cpu (enddup->freetag) !=XFS_DIR2_DATA_FREE_TAG ) - dup = enddup =NULL ; -/* -* Check out the biggest freespace and see if it's the same one. -*/ -else { - dup = (xfs_dir2_data_unused_t *) - ((char *)hdr +be16_to_cpu (bf[0 ].offset)); -if (dup == enddup) { -/* -* It is the biggest freespace, is it too small -* to hold the new leaf too? -*/ -if (be16_to_cpu (dup->length) < len + (uint )sizeof (*blp)) { -/* -* Yes, we use the second-largest -* entry instead if it works. -*/ -if (be16_to_cpu (bf[1 ].length) >= len) - dup = (xfs_dir2_data_unused_t *) - ((char *)hdr + -be16_to_cpu (bf[1 ].offset)); -else - dup =NULL ; - } - }else { -/* -* Not the same free entry, -* just check its length. -*/ -if (be16_to_cpu (dup->length) < len) { - dup =NULL ; - } - } - } - compact =0 ; - } -/* -* If there are stale entries we'll use one for the leaf. -* Is the biggest entry enough to avoid compaction? -*/ -else if (be16_to_cpu (bf[0 ].length) >= len) { - dup = (xfs_dir2_data_unused_t *) - ((char *)hdr +be16_to_cpu (bf[0 ].offset)); - compact =0 ; - } -/* -* Will need to compact to make this work. +* Find out if we can reuse stale entries or whether we need extra +* space for entry and new leaf. */ -else { -/* -* Tag just before the first leaf entry. -*/ - tagp = (__be16 *)blp -1 ; -/* -* Data object just before the first leaf entry. -*/ - dup = (xfs_dir2_data_unused_t *)((char *)hdr +be16_to_cpu (*tagp)); -/* -* If it's not free then the data will go where the -* leaf data starts now, if it works at all. -*/ -if (be16_to_cpu (dup->freetag) ==XFS_DIR2_DATA_FREE_TAG ) { -if (be16_to_cpu (dup->length) + (be32_to_cpu (btp->stale) -1 ) * - (uint )sizeof (*blp) < len) - dup =NULL ; - }else if ((be32_to_cpu (btp->stale) -1 ) * (uint )sizeof (*blp) < len) - dup =NULL ; -else - dup = (xfs_dir2_data_unused_t *)blp; - compact =1 ; - } +xfs_dir2_block_need_space (hdr, btp, blp, &tagp, &dup, + &enddup, &compact, len); +/* -* If this isn't a real add, we're done with the buffer. +* Done everything we need for a space check now. */ -if (args->op_flags &XFS_DA_OP_JUSTCHECK ) +if (args->op_flags &XFS_DA_OP_JUSTCHECK ) {xfs_trans_brelse (tp, bp); +if (!dup) +return XFS_ERROR (ENOSPC ); +return 0 ; + } +/* * If we don't have space for the new entry & leaf ... */ if (!dup) { -/* -* Not trying to actually do anything, or don't have -* a space reservation: return no-space. -*/ -if ((args->op_flags &XFS_DA_OP_JUSTCHECK ) || args->total ==0 ) +/* Don't have a space reservation: return no-space. */ +if (args->total ==0 )return XFS_ERROR (ENOSPC );/* * Convert to the next larger format.
@@ -232,65 +313,24 @@ xfs_dir2_block_addname(return error;return xfs_dir2_leaf_addname (args); } -/* -* Just checking, and it would work, so say so. -*/ -if (args->op_flags &XFS_DA_OP_JUSTCHECK ) -return 0 ; + needlog = needscan =0 ; +/* * If need to compact the leaf entries, do it now. -* Leave the highest-numbered stale entry stale. -* XXX should be the one closest to mid but mid is not yet computed. -*/ -if (compact) { -int fromidx;/* source leaf index */ -int toidx;/* target leaf index */ - -for (fromidx = toidx =be32_to_cpu (btp->count) -1 , - highstale = lfloghigh =-1 ; - fromidx >=0 ; - fromidx--) { -if (blp[fromidx].address == -cpu_to_be32 (XFS_DIR2_NULL_DATAPTR )) { -if (highstale ==-1 ) - highstale = toidx; -else { -if (lfloghigh ==-1 ) - lfloghigh = toidx; -continue ; - } - } -if (fromidx < toidx) - blp[toidx] = blp[fromidx]; - toidx--; - } - lfloglow = toidx +1 - (be32_to_cpu (btp->stale) -1 ); - lfloghigh -=be32_to_cpu (btp->stale) -1 ; -be32_add_cpu (&btp->count, -(be32_to_cpu (btp->stale) -1 )); -xfs_dir2_data_make_free (tp, bp, - (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), - (xfs_dir2_data_aoff_t)((be32_to_cpu (btp->stale) -1 ) *sizeof (*blp)), - &needlog, &needscan); - blp +=be32_to_cpu (btp->stale) -1 ; - btp->stale =cpu_to_be32 (1 ); -/* -* If we now need to rebuild the bestfree map, do so. -* This needs to happen before the next call to use_free. -*/ -if (needscan) { -xfs_dir2_data_freescan (mp, hdr, &needlog); - needscan =0 ; - } - } -/* -* Set leaf logging boundaries to impossible state. -* For the no-stale case they're set explicitly. */ +if (compact) +xfs_dir2_block_compact (tp, bp, hdr, btp, blp, &needlog, + &lfloghigh, &lfloglow);else if (btp->stale) { +/* +* Set leaf logging boundaries to impossible state. +* For the no-stale case they're set explicitly. +*/ lfloglow =be32_to_cpu (btp->count); lfloghigh =-1 ; } +/* * Find the slot that's first lower than our hash value, -1 if none. */
@@ -450,18 +490,13 @@ xfs_dir2_block_getdents(/* * If the block number in the offset is out of range, we're done. */ -if (xfs_dir2_dataptr_to_db (mp, *offset) > mp->m_dirdatablk) { +if (xfs_dir2_dataptr_to_db (mp, *offset) > mp->m_dirdatablk)return 0 ; - } -/* -* Can't read the block, give up, else get dabuf in bp. -*/ - error =xfs_da_read_buf (NULL , dp, mp->m_dirdatablk,-1 , - &bp,XFS_DATA_FORK ,NULL ); + + error =xfs_dir2_block_read (NULL , dp, &bp);if (error)return error; -ASSERT (bp !=NULL );/* * Extract the byte offset we start at from the seek pointer. * We'll skip entries before this.
@@ -637,14 +672,11 @@ xfs_dir2_block_lookup_int( dp = args->dp; tp = args->trans; mp = dp->i_mount; -/* -* Read the buffer, return error if we can't get it. -*/ - error =xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &bp, -XFS_DATA_FORK ,NULL ); + + error =xfs_dir2_block_read (tp, dp, &bp);if (error)return error; -ASSERT (bp !=NULL ); + hdr = bp->b_addr;xfs_dir2_data_check (dp, bp); btp =xfs_dir2_block_tail_p (mp, hdr);
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 19/32] xfs: factor dir2 block read operations
Quoted 8 lines · Dave Chinner
From: Dave Chinner <[email protected]>
In preparation for verifying dir2 block format buffers, factor the read operations out of the block operations (lookup, addname, getdents) and some of the additional logic to make it easier to understand an dmodify the code.
Signed-off-by Dave Chinner <[email protected]>
This was a difficult review. I think you have at least three ideas in here which could be split up. Please keep the reviewer in mind.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 19/32] xfs: factor dir2 block read operations
Quoted 8 lines · Ben Myers
Quoted 7 lines · Dave Chinner
From: Dave Chinner <[email protected]>
In preparation for verifying dir2 block format buffers, factor the read operations out of the block operations (lookup, addname, getdents) and some of the additional logic to make it easier to understand an dmodify the code.
Quoted 4 lines
Quoted 1 line
Signed-off-by Dave Chinner <[email protected]>This was a difficult review. I think you have at least three ideas in here which could be split up. Please keep the reviewer in mind.
I do, but it's a trade-off.
If I split every patch upon fine grained "idea" boundaries, I'm going to generate 5x the number of patches compared to what I'm already posting. Massively deep patch stacks that have top to bottom dependencies (which these patch series have) are a nightmare to maintain and develop, and I'm already at that limit given the number of patches I already have on top of this series. If I can't manage the series, then it doesn't matter whether it's easy to review or not - the work simply won't get done because I'll be spending all my time patch monkeying instead of writing and testing code....
IOWs, I'm making the series as fine grained as possible, but there are going to be some patches where splitting them up is just make-work that provides zero gain whilst increasing management overhead....
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 20/32 xfs: verify dir2 block format buffers
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add a dir2 block format read verifier. To fully verify every block when read, call xfs_dir2_data_check() on them. Change xfs_dir2_data_check() to do runtime checking, convert ASSERT() checks to XFS_WANT_CORRUPTED_RETURN(), which will trigger an ASSERT failure on debug kernels, but on production kernels will dump an error to dmesg and return EFSCORRUPTED to the caller.
--- fs/xfs/xfs_dir2_block.c | 22 +++++++++++++- fs/xfs/xfs_dir2_data.c | 73 ++++++++++++++++++++++++++++------------------- fs/xfs/xfs_dir2_priv.h | 4 ++- 3 files changed, 68 insertions(+), 31 deletions(-)
fs/xfs/xfs_dir2_block.c +21 -1
@@ -56,6 +56,26 @@ xfs_dir_startup(void) xfs_dir_hash_dotdot =xfs_da_hashname ((unsigned char *)".." ,2 ); } +static void +xfs_dir2_block_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_dir2_data_hdr *hdr = bp->b_addr; +int block_ok =0 ; + + block_ok = hdr->magic ==cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC ); + block_ok = block_ok &&__xfs_dir2_data_check (NULL , bp) ==0 ; + +if (!block_ok) { +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } + + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} + static int xfs_dir2_block_read( struct xfs_trans *tp,
@@ -65,7 +85,7 @@ xfs_dir2_block_read(struct xfs_mount *mp = dp->i_mount;return xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , bpp, -XFS_DATA_FORK ,NULL ); +XFS_DATA_FORK , xfs_dir2_block_verify); } static void
fs/xfs/xfs_dir2_data.c +44 -29
149 lines not on this page · raw message
fs/xfs/xfs_dir2_priv.h +3 -1
@@ -41,10 +41,12 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,/* xfs_dir2_data.c */ #ifdef DEBUG -extern void xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp); +#define xfs_dir2_data_check (dp,bp) __xfs_dir2_data_check(dp, bp);#else #define xfs_dir2_data_check (dp,bp)#endif +extern int __xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp); +extern struct xfs_dir2_data_free *xfs_dir2_data_freeinsert (struct xfs_dir2_data_hdr *hdr,struct xfs_dir2_data_unused *dup,int *loghead);
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 21/32 xfs: factor dir2 free block reading
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Also factor out the updating of the free block when removing entries from leaf blocks, and add a verifier callback for reads.
--- fs/xfs/xfs_dir2_leaf.c | 3 +- fs/xfs/xfs_dir2_node.c | 218 +++++++++++++++++++++++++++++++----------------- fs/xfs/xfs_dir2_priv.h | 2 + 3 files changed, 143 insertions(+), 80 deletions(-)
fs/xfs/xfs_dir2_leaf.c +1 -2
@@ -1863,8 +1863,7 @@ xfs_dir2_node_to_leaf(/* * Read the freespace block. */ - error =xfs_da_read_buf (tp, dp, mp->m_dirfreeblk,-1 , &fbp, -XFS_DATA_FORK ,NULL ); + error =xfs_dir2_free_read (tp, dp, mp->m_dirfreeblk, &fbp);if (error)return error; free = fbp->b_addr;
fs/xfs/xfs_dir2_node.c +140 -78
281 lines not on this page · raw message
fs/xfs/xfs_dir2_priv.h +2 -0
@@ -117,6 +117,8 @@ extern int xfs_dir2_node_removename(struct xfs_da_args *args);extern int xfs_dir2_node_replace (struct xfs_da_args *args);extern int xfs_dir2_node_trim_free (struct xfs_da_args *args,xfs_fileoff_t fo,int *rvalp); +extern int xfs_dir2_free_read (struct xfs_trans *tp,struct xfs_inode *dp, +xfs_dablk_t fbno,struct xfs_buf **bpp);/* xfs_dir2_sf.c */ extern xfs_ino_t xfs_dir2_sf_get_parent_ino (struct xfs_dir2_sf_hdr *sfp);
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 22/32 xfs: factor out dir2 data block reading
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
And add a verifier callback function while there.
--- fs/xfs/xfs_dir2_block.c | 3 +-- fs/xfs/xfs_dir2_data.c | 32 ++++++++++++++++++++++++++++++++ fs/xfs/xfs_dir2_leaf.c | 38 +++++++++++++++++--------------------- fs/xfs/xfs_dir2_node.c | 8 ++++---- fs/xfs/xfs_dir2_priv.h | 2 ++ 5 files changed, 56 insertions(+), 27 deletions(-)
fs/xfs/xfs_dir2_block.c +1 -2
@@ -970,8 +970,7 @@ xfs_dir2_leaf_to_block(* Read the data block if we don't already have it, give up if it fails. */ if (!dbp) { - error =xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , &dbp, -XFS_DATA_FORK ,NULL ); + error =xfs_dir2_data_read (tp, dp, mp->m_dirdatablk,-1 , &dbp);if (error)return error; }
fs/xfs/xfs_dir2_data.c +32 -0
@@ -185,6 +185,38 @@ __xfs_dir2_data_check(return 0 ; } +static void +xfs_dir2_data_verify ( +struct xfs_buf *bp) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_dir2_data_hdr *hdr = bp->b_addr; +int block_ok =0 ; + + block_ok = hdr->magic ==cpu_to_be32 (XFS_DIR2_DATA_MAGIC ); + block_ok = block_ok &&__xfs_dir2_data_check (NULL , bp) ==0 ; + +if (!block_ok) { +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } + + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} + +int +xfs_dir2_data_read ( +struct xfs_trans *tp, +struct xfs_inode *dp, +xfs_dablk_t bno, +xfs_daddr_t mapped_bno, +struct xfs_buf **bpp) +{ +return xfs_da_read_buf (tp, dp, bno, mapped_bno, bpp, +XFS_DATA_FORK , xfs_dir2_data_verify); +} +/* * Given a data block and an unused entry from that block, * return the bestfree entry if any that corresponds to it.
fs/xfs/xfs_dir2_leaf.c +17 -21
@@ -493,14 +493,14 @@ xfs_dir2_leaf_addname( hdr = dbp->b_addr; bestsp[use_block] = hdr->bestfree[0 ].length; grown =1 ; - } -/* -* Already had space in some data block. -* Just read that one in. -*/ -else { - error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, use_block), --1 , &dbp,XFS_DATA_FORK ,NULL ); + }else { +/* +* Already had space in some data block. +* Just read that one in. +*/ + error =xfs_dir2_data_read (tp, dp, +xfs_dir2_db_to_da (mp, use_block), +-1 , &dbp);if (error) {xfs_trans_brelse (tp, lbp);return error;
@@ -508,7 +508,6 @@ xfs_dir2_leaf_addname( hdr = dbp->b_addr; grown =0 ; } -xfs_dir2_data_check (dp, dbp);/* * Point to the biggest freespace in our data block. */
@@ -891,10 +890,9 @@ xfs_dir2_leaf_readbuf(* Read the directory block starting at the first mapping. */ mip->curdb =xfs_dir2_da_to_db (mp, map->br_startoff); - error =xfs_da_read_buf (NULL , dp, map->br_startoff, + error =xfs_dir2_data_read (NULL , dp, map->br_startoff, map->br_blockcount >= mp->m_dirblkfsbs ? -XFS_FSB_TO_DADDR (mp, map->br_startblock) :-1 , - &bp,XFS_DATA_FORK ,NULL ); +XFS_FSB_TO_DADDR (mp, map->br_startblock) :-1 , &bp);/* * Should just skip over the data block instead of giving up.
@@ -1408,14 +1406,13 @@ xfs_dir2_leaf_lookup_int(if (newdb != curdb) {if (dbp)xfs_trans_brelse (tp, dbp); - error =xfs_da_read_buf (tp, dp, -xfs_dir2_db_to_da (mp, newdb), --1 , &dbp,XFS_DATA_FORK ,NULL ); + error =xfs_dir2_data_read (tp, dp, +xfs_dir2_db_to_da (mp, newdb), +-1 , &dbp);if (error) {xfs_trans_brelse (tp, lbp);return error; } -xfs_dir2_data_check (dp, dbp); curdb = newdb; }/*
@@ -1450,9 +1447,9 @@ xfs_dir2_leaf_lookup_int(ASSERT (cidb !=-1 );if (cidb != curdb) {xfs_trans_brelse (tp, dbp); - error =xfs_da_read_buf (tp, dp, -xfs_dir2_db_to_da (mp, cidb), --1 , &dbp,XFS_DATA_FORK ,NULL ); + error =xfs_dir2_data_read (tp, dp, +xfs_dir2_db_to_da (mp, cidb), +-1 , &dbp);if (error) {xfs_trans_brelse (tp, lbp);return error;
@@ -1737,8 +1734,7 @@ xfs_dir2_leaf_trim_data(/* * Read the offending data block. We need its buffer. */ - error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, db),-1 , &dbp, -XFS_DATA_FORK ,NULL ); + error =xfs_dir2_data_read (tp, dp,xfs_dir2_db_to_da (mp, db),-1 , &dbp);if (error)return error;
fs/xfs/xfs_dir2_node.c +4 -4
@@ -583,9 +583,9 @@ xfs_dir2_leafn_lookup_for_entry(ASSERT (state->extravalid); curbp = state->extrablk.bp; }else { - error =xfs_da_read_buf (tp, dp, + error =xfs_dir2_data_read (tp, dp,xfs_dir2_db_to_da (mp, newdb), --1 , &curbp,XFS_DATA_FORK ,NULL ); +-1 , &curbp);if (error)return error; }
@@ -1692,8 +1692,8 @@ xfs_dir2_node_addname_int(/* * Read the data block in. */ - error =xfs_da_read_buf (tp, dp,xfs_dir2_db_to_da (mp, dbno), --1 , &dbp,XFS_DATA_FORK ,NULL ); + error =xfs_dir2_data_read (tp, dp,xfs_dir2_db_to_da (mp, dbno), +-1 , &dbp);if (error)return error; hdr = dbp->b_addr;
fs/xfs/xfs_dir2_priv.h +2 -0
@@ -46,6 +46,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,#define xfs_dir2_data_check (dp,bp)#endif extern int __xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp); +extern int xfs_dir2_data_read (struct xfs_trans *tp,struct xfs_inode *dp, +xfs_dablk_t bno,xfs_daddr_t mapped_bno,struct xfs_buf **bpp);extern struct xfs_dir2_data_free * xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 23/32 xfs: factor dir2 leaf read
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
--- fs/xfs/xfs_dir2_leaf.c | 73 ++++++++++++++++++++++++++++++++++++++++-------- fs/xfs/xfs_dir2_node.c | 6 ++-- fs/xfs/xfs_dir2_priv.h | 2 ++ 3 files changed, 67 insertions(+), 14 deletions(-)
fs/xfs/xfs_dir2_leaf.c +62 -11
@@ -48,6 +48,62 @@ static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp, int first, int last);static void xfs_dir2_leaf_log_tail (struct xfs_trans *tp,struct xfs_buf *bp); +static void +xfs_dir2_leaf_verify ( +struct xfs_buf *bp, +__be16 magic) +{ +struct xfs_mount *mp = bp->b_target->bt_mount; +struct xfs_dir2_leaf_hdr *hdr = bp->b_addr; +int block_ok =0 ; + + block_ok = hdr->info.magic == magic; +if (!block_ok) { +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr); +xfs_buf_ioerror (bp,EFSCORRUPTED ); + } + + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); +} + +static void +xfs_dir2_leaf1_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); +} + +static void +xfs_dir2_leafn_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); +} + +static int +xfs_dir2_leaf_read ( +struct xfs_trans *tp, +struct xfs_inode *dp, +xfs_dablk_t fbno, +xfs_daddr_t mappedbno, +struct xfs_buf **bpp) +{ +return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, +XFS_DATA_FORK , xfs_dir2_leaf1_verify); +} + +int +xfs_dir2_leafn_read ( +struct xfs_trans *tp, +struct xfs_inode *dp, +xfs_dablk_t fbno, +xfs_daddr_t mappedbno, +struct xfs_buf **bpp) +{ +return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, +XFS_DATA_FORK , xfs_dir2_leafn_verify); +}/* * Convert a block form directory to a leaf form directory.
@@ -311,14 +367,11 @@ xfs_dir2_leaf_addname( dp = args->dp; tp = args->trans; mp = dp->i_mount; -/* -* Read the leaf block. -*/ - error =xfs_da_read_buf (tp, dp, mp->m_dirleafblk,-1 , &lbp, -XFS_DATA_FORK ,NULL ); + + error =xfs_dir2_leaf_read (tp, dp, mp->m_dirleafblk,-1 , &lbp);if (error)return error; -ASSERT (lbp !=NULL ); +/* * Look up the entry by hash value and name. * We know it's not there, our caller has already done a lookup.
@@ -1369,13 +1422,11 @@ xfs_dir2_leaf_lookup_int( dp = args->dp; tp = args->trans; mp = dp->i_mount; -/* -* Read the leaf block into the buffer. -*/ - error =xfs_da_read_buf (tp, dp, mp->m_dirleafblk,-1 , &lbp, -XFS_DATA_FORK ,NULL ); + + error =xfs_dir2_leaf_read (tp, dp, mp->m_dirleafblk,-1 , &lbp);if (error)return error; + *lbpp = lbp; leaf = lbp->b_addr;xfs_dir2_leaf_check (dp, lbp);
fs/xfs/xfs_dir2_node.c +3 -3
@@ -1232,11 +1232,11 @@ xfs_dir2_leafn_toosmall(/* * Read the sibling leaf block. */ - error =xfs_da_read_buf (state->args->trans, state->args->dp, - blkno,-1 , &bp,XFS_DATA_FORK ,NULL ); + error =xfs_dir2_leafn_read (state->args->trans, state->args->dp, + blkno,-1 , &bp);if (error)return error; -ASSERT (bp !=NULL ); +/* * Count bytes in the two blocks combined. */
fs/xfs/xfs_dir2_priv.h +2 -0
@@ -70,6 +70,8 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);/* xfs_dir2_leaf.c */ +extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp, +xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp);extern int xfs_dir2_block_to_leaf (struct xfs_da_args *args,struct xfs_buf *dbp);extern int xfs_dir2_leaf_addname (struct xfs_da_args *args);
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 24/32 xfs: factor and verify attr leaf reads
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Some reads are not converted yet because it isn't obvious ahead of time what the format of the block is going to be. Need to determine how to tell if the first block in the tree is a node or leaf format block. That will be done in later patches.
--- fs/xfs/xfs_attr.c | 70 +++++++++++-------------------------------- fs/xfs/xfs_attr_leaf.c | 78 ++++++++++++++++++++++++++++-------------------- fs/xfs/xfs_attr_leaf.h | 3 ++ 3 files changed, 66 insertions(+), 85 deletions(-)
fs/xfs/xfs_attr.c +18 -52
@@ -903,11 +903,9 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)*/ dp = args->dp; args->blkno =0 ; - error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ,NULL ); + error =xfs_attr_leaf_read (args->trans, args->dp, args->blkno,-1 , &bp);if (error) -return (error); -ASSERT (bp !=NULL ); +return error;/* * Look up the given attribute in the leaf block. Figure out if
@@ -1031,12 +1029,12 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)* Read in the block containing the "old" attr, then * remove the "old" attr from that block (neat, huh!) */ - error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , - &bp,XFS_ATTR_FORK ,NULL ); + error =xfs_attr_leaf_read (args->trans, args->dp, args->blkno, +-1 , &bp);if (error) -return (error); -ASSERT (bp !=NULL ); - (void )xfs_attr_leaf_remove (bp, args); +return error; + +xfs_attr_leaf_remove (bp, args);/* * If the result is small enough, shrink it all into the inode.
@@ -1100,20 +1098,17 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)*/ dp = args->dp; args->blkno =0 ; - error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ,NULL ); -if (error) { -return (error); - } + error =xfs_attr_leaf_read (args->trans, args->dp, args->blkno,-1 , &bp); +if (error) +return error; -ASSERT (bp !=NULL ); error =xfs_attr_leaf_lookup_int (bp, args);if (error ==ENOATTR ) {xfs_trans_brelse (args->trans, bp);return (error); } - (void )xfs_attr_leaf_remove (bp, args); +xfs_attr_leaf_remove (bp, args);/* * If the result is small enough, shrink it all into the inode.
@@ -1158,11 +1153,9 @@ xfs_attr_leaf_get(xfs_da_args_t *args)trace_xfs_attr_leaf_get (args); args->blkno =0 ; - error =xfs_da_read_buf (args->trans, args->dp, args->blkno,-1 , &bp, -XFS_ATTR_FORK ,NULL ); + error =xfs_attr_leaf_read (args->trans, args->dp, args->blkno,-1 , &bp);if (error) -return (error); -ASSERT (bp !=NULL ); +return error; error =xfs_attr_leaf_lookup_int (bp, args);if (error !=EEXIST ) {
@@ -1183,25 +1176,15 @@ xfs_attr_leaf_get(xfs_da_args_t *args) STATIC intxfs_attr_leaf_list (xfs_attr_list_context_t *context) { -xfs_attr_leafblock_t *leaf;int error;struct xfs_buf *bp;trace_xfs_attr_leaf_list (context); context->cursor->blkno =0 ; - error =xfs_da_read_buf (NULL , context->dp,0 ,-1 , &bp,XFS_ATTR_FORK , -NULL ); + error =xfs_attr_leaf_read (NULL , context->dp,0 ,-1 , &bp);if (error)return XFS_ERROR (error); -ASSERT (bp !=NULL ); - leaf = bp->b_addr; -if (unlikely (leaf->hdr.info.magic !=cpu_to_be16 (XFS_ATTR_LEAF_MAGIC ))) { -XFS_CORRUPTION_ERROR ("xfs_attr_leaf_list" ,XFS_ERRLEVEL_LOW , - context->dp->i_mount, leaf); -xfs_trans_brelse (NULL , bp); -return XFS_ERROR (EFSCORRUPTED ); - } error =xfs_attr_leaf_list_int (bp, context);xfs_trans_brelse (NULL , bp);
@@ -1605,12 +1588,9 @@ xfs_attr_node_removename(xfs_da_args_t *args)ASSERT (state->path.blk[0 ].bp); state->path.blk[0 ].bp =NULL ; - error =xfs_da_read_buf (args->trans, args->dp,0 ,-1 , &bp, -XFS_ATTR_FORK ,NULL ); + error =xfs_attr_leaf_read (args->trans, args->dp,0 ,-1 , &bp);if (error) goto out; -ASSERT ((((xfs_attr_leafblock_t *)bp->b_addr)->hdr.info.magic) == -cpu_to_be16 (XFS_ATTR_LEAF_MAGIC ));if ((forkoff =xfs_attr_shortform_allfit (bp, dp))) {xfs_bmap_init (args->flist, args->firstblock);
@@ -1920,14 +1900,6 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)*/ for (;;) { leaf = bp->b_addr; -if (unlikely (leaf->hdr.info.magic != -cpu_to_be16 (XFS_ATTR_LEAF_MAGIC ))) { -XFS_CORRUPTION_ERROR ("xfs_attr_node_list(4)" , -XFS_ERRLEVEL_LOW , - context->dp->i_mount, leaf); -xfs_trans_brelse (NULL , bp); -return (XFS_ERROR (EFSCORRUPTED )); - } error =xfs_attr_leaf_list_int (bp, context);if (error) {xfs_trans_brelse (NULL , bp);
@@ -1937,16 +1909,10 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)break ; cursor->blkno =be32_to_cpu (leaf->hdr.info.forw);xfs_trans_brelse (NULL , bp); - error =xfs_da_read_buf (NULL , context->dp, cursor->blkno,-1 , - &bp,XFS_ATTR_FORK ,NULL ); + error =xfs_attr_leaf_read (NULL , context->dp, cursor->blkno,-1 , + &bp);if (error) -return (error); -if (unlikely ((bp ==NULL ))) { -XFS_ERROR_REPORT ("xfs_attr_node_list(5)" , -XFS_ERRLEVEL_LOW , - context->dp->i_mount); -return (XFS_ERROR (EFSCORRUPTED )); - } +return error; }xfs_trans_brelse (NULL , bp);return (0 );
fs/xfs/xfs_attr_leaf.c +45 -33
145 lines not on this page · raw message
fs/xfs/xfs_attr_leaf.h +3 -0
@@ -227,6 +227,9 @@ int xfs_attr_leaf_to_shortform(struct xfs_buf *bp,int xfs_attr_leaf_clearflag (struct xfs_da_args *args);int xfs_attr_leaf_setflag (struct xfs_da_args *args);int xfs_attr_leaf_flipflags (xfs_da_args_t *args); +int xfs_attr_leaf_read (struct xfs_trans *tp,struct xfs_inode *dp, +xfs_dablk_t bno,xfs_daddr_t mappedbno, +struct xfs_buf **bpp);/* * Routines used for growing the Btree.
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 25/32 xfs: add xfs_da_node verification
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
--- fs/xfs/xfs_attr.c | 22 ++++------ fs/xfs/xfs_attr_leaf.c | 12 +++--- fs/xfs/xfs_attr_leaf.h | 8 ++-- fs/xfs/xfs_da_btree.c | 109 ++++++++++++++++++++++++++++++++++++------------ fs/xfs/xfs_da_btree.h | 3 ++ fs/xfs/xfs_dir2_leaf.c | 2 +- fs/xfs/xfs_dir2_priv.h | 1 + 7 files changed, 107 insertions(+), 50 deletions(-)
fs/xfs/xfs_attr.c +8 -14
@@ -1696,10 +1696,10 @@ xfs_attr_refillstate(xfs_da_state_t *state)ASSERT ((path->active >=0 ) && (path->active <XFS_DA_NODE_MAXDEPTH ));for (blk = path->blk, level =0 ; level < path->active; blk++, level++) {if (blk->disk_blkno) { - error =xfs_da_read_buf (state->args->trans, + error =xfs_da_node_read (state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, - &blk->bp,XFS_ATTR_FORK ,NULL ); + &blk->bp,XFS_ATTR_FORK );if (error)return (error); }else {
@@ -1715,10 +1715,10 @@ xfs_attr_refillstate(xfs_da_state_t *state)ASSERT ((path->active >=0 ) && (path->active <XFS_DA_NODE_MAXDEPTH ));for (blk = path->blk, level =0 ; level < path->active; blk++, level++) {if (blk->disk_blkno) { - error =xfs_da_read_buf (state->args->trans, + error =xfs_da_node_read (state->args->trans, state->args->dp, blk->blkno, blk->disk_blkno, - &blk->bp,XFS_ATTR_FORK ,NULL ); + &blk->bp,XFS_ATTR_FORK );if (error)return (error); }else {
@@ -1807,8 +1807,8 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)*/ bp =NULL ;if (cursor->blkno >0 ) { - error =xfs_da_read_buf (NULL , context->dp, cursor->blkno,-1 , - &bp,XFS_ATTR_FORK ,NULL ); + error =xfs_da_node_read (NULL , context->dp, cursor->blkno,-1 , + &bp,XFS_ATTR_FORK );if ((error !=0 ) && (error !=EFSCORRUPTED ))return (error);if (bp) {
@@ -1849,17 +1849,11 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)if (bp ==NULL ) { cursor->blkno =0 ;for (;;) { - error =xfs_da_read_buf (NULL , context->dp, + error =xfs_da_node_read (NULL , context->dp, cursor->blkno,-1 , &bp, -XFS_ATTR_FORK ,NULL ); +XFS_ATTR_FORK );if (error)return (error); -if (unlikely (bp ==NULL )) { -XFS_ERROR_REPORT ("xfs_attr_node_list(2)" , -XFS_ERRLEVEL_LOW , - context->dp->i_mount); -return (XFS_ERROR (EFSCORRUPTED )); - } node = bp->b_addr;if (node->hdr.info.magic ==cpu_to_be16 (XFS_ATTR_LEAF_MAGIC ))
fs/xfs/xfs_attr_leaf.c +6 -6
@@ -88,7 +88,7 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, xfs_mount_t *mp); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); -static void +void xfs_attr_leaf_verify (struct xfs_buf *bp) {
@@ -2765,7 +2765,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)* the extents in reverse order the extent containing * block 0 must still be there. */ - error =xfs_da_read_buf (*trans, dp,0 ,-1 , &bp,XFS_ATTR_FORK ,NULL ); + error =xfs_da_node_read (*trans, dp,0 ,-1 , &bp,XFS_ATTR_FORK );if (error)return (error); blkno =XFS_BUF_ADDR (bp);
@@ -2850,8 +2850,8 @@ xfs_attr_node_inactive(* traversal of the tree so we may deal with many blocks * before we come back to this one. */ - error =xfs_da_read_buf (*trans, dp, child_fsb,-2 , &child_bp, -XFS_ATTR_FORK ,NULL ); + error =xfs_da_node_read (*trans, dp, child_fsb,-2 , &child_bp, +XFS_ATTR_FORK );if (error)return (error);if (child_bp) {
@@ -2891,8 +2891,8 @@ xfs_attr_node_inactive(* child block number. */ if ((i+1 ) < count) { - error =xfs_da_read_buf (*trans, dp,0 , parent_blkno, - &bp,XFS_ATTR_FORK ,NULL ); + error =xfs_da_node_read (*trans, dp,0 , parent_blkno, + &bp,XFS_ATTR_FORK );if (error)return (error); child_fsb =be32_to_cpu (node->btree[i+1 ].before);
fs/xfs/xfs_attr_leaf.h +5 -3
@@ -227,9 +227,6 @@ int xfs_attr_leaf_to_shortform(struct xfs_buf *bp,int xfs_attr_leaf_clearflag (struct xfs_da_args *args);int xfs_attr_leaf_setflag (struct xfs_da_args *args);int xfs_attr_leaf_flipflags (xfs_da_args_t *args); -int xfs_attr_leaf_read (struct xfs_trans *tp,struct xfs_inode *dp, -xfs_dablk_t bno,xfs_daddr_t mappedbno, -struct xfs_buf **bpp);/* * Routines used for growing the Btree.
@@ -264,4 +261,9 @@ int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, struct xfs_buf *leaf2_bp);int xfs_attr_leaf_newentsize (int namelen,int valuelen,int blocksize,int *local); +int xfs_attr_leaf_read (struct xfs_trans *tp,struct xfs_inode *dp, +xfs_dablk_t bno,xfs_daddr_t mappedbno, +struct xfs_buf **bpp); +void xfs_attr_leaf_verify (struct xfs_buf *bp); +#endif /* __XFS_ATTR_LEAF_H__ */
fs/xfs/xfs_da_btree.c +83 -26
197 lines not on this page · raw message
fs/xfs/xfs_da_btree.h +3 -0
@@ -213,6 +213,9 @@ int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,*/ int xfs_da_blk_link (xfs_da_state_t *state,xfs_da_state_blk_t *old_blk,xfs_da_state_blk_t *new_blk); +int xfs_da_node_read (struct xfs_trans *tp,struct xfs_inode *dp, +xfs_dablk_t bno,xfs_daddr_t mappedbno, +struct xfs_buf **bpp,int which_fork);/* * Utility routines.
fs/xfs/xfs_dir2_leaf.c +1 -1
@@ -74,7 +74,7 @@ xfs_dir2_leaf1_verify(xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); } -static void +void xfs_dir2_leafn_verify (struct xfs_buf *bp) {
fs/xfs/xfs_dir2_priv.h +1 -0
@@ -70,6 +70,7 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);/* xfs_dir2_leaf.c */ +extern void xfs_dir2_leafn_verify (struct xfs_buf *bp);extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 26/32 xfs: Add verifiers to dir2 data readahead.
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
--- fs/xfs/xfs_da_btree.c | 4 ++-- fs/xfs/xfs_da_btree.h | 4 ++-- fs/xfs/xfs_dir2_data.c | 13 ++++++++++++- fs/xfs/xfs_dir2_leaf.c | 11 +++++------ fs/xfs/xfs_dir2_priv.h | 2 ++ fs/xfs/xfs_file.c | 4 +++- 6 files changed, 26 insertions(+), 12 deletions(-)
fs/xfs/xfs_da_btree.c +2 -2
@@ -2285,10 +2285,10 @@ xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, xfs_dablk_t bno, + xfs_daddr_t mappedbno, int whichfork, xfs_buf_iodone_t verifier) { - xfs_daddr_t mappedbno = -1; struct xfs_buf_map map;struct xfs_buf_map *mapp;int nmap;
@@ -2296,7 +2296,7 @@ xfs_da_reada_buf( mapp = ↦ nmap =1 ; - error =xfs_dabuf_map (trans, dp, bno,-1 , whichfork, + error =xfs_dabuf_map (trans, dp, bno, mappedbno, whichfork, &mapp, &nmap);if (error) {/* mapping a hole is not an error, but we don't continue */
fs/xfs/xfs_da_btree.h +2 -2
@@ -231,8 +231,8 @@ int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, struct xfs_buf **bpp, int whichfork, xfs_buf_iodone_t verifier);xfs_daddr_t xfs_da_reada_buf (struct xfs_trans *trans,struct xfs_inode *dp, -xfs_dablk_t bno,int whichfork, -xfs_buf_iodone_t verifier); +xfs_dablk_t bno,xfs_daddr_t mapped_bno, +int whichfork,xfs_buf_iodone_t verifier);int xfs_da_shrink_inode (xfs_da_args_t *args,xfs_dablk_t dead_blkno,struct xfs_buf *dead_buf);
fs/xfs/xfs_dir2_data.c +12 -1
@@ -185,7 +185,7 @@ __xfs_dir2_data_check(return 0 ; } -static void +void xfs_dir2_data_verify (struct xfs_buf *bp) {
@@ -217,6 +217,17 @@ xfs_dir2_data_read( XFS_DATA_FORK, xfs_dir2_data_verify); } +int +xfs_dir2_data_readahead ( +struct xfs_trans *tp, +struct xfs_inode *dp, +xfs_dablk_t bno, +xfs_daddr_t mapped_bno) +{ +return xfs_da_reada_buf (tp, dp, bno, mapped_bno, +XFS_DATA_FORK , xfs_dir2_data_verify); +} +/* * Given a data block and an unused entry from that block, * return the bestfree entry if any that corresponds to it.
fs/xfs/xfs_dir2_leaf.c +5 -6
@@ -972,11 +972,11 @@ xfs_dir2_leaf_readbuf(*/ if (i > mip->ra_current && map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { -xfs_buf_readahead (mp->m_ddev_targp, +xfs_dir2_data_readahead (NULL , dp, + map[mip->ra_index].br_startoff + mip->ra_offset,XFS_FSB_TO_DADDR (mp, map[mip->ra_index].br_startblock + - mip->ra_offset), - (int )BTOBB (mp->m_dirblksize),NULL ); + mip->ra_offset)); mip->ra_current = i; }
@@ -985,10 +985,9 @@ xfs_dir2_leaf_readbuf(* use our mapping, but this is a very rare case. */ else if (i > mip->ra_current) { -xfs_da_reada_buf (NULL , dp, +xfs_dir2_data_readahead (NULL , dp, map[mip->ra_index].br_startoff + - mip->ra_offset, -XFS_DATA_FORK ,NULL ); + mip->ra_offset,-1 ); mip->ra_current = i; }
fs/xfs/xfs_dir2_priv.h +2 -0
@@ -48,6 +48,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,extern int __xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp);extern int xfs_dir2_data_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mapped_bno,struct xfs_buf **bpp); +extern int xfs_dir2_data_readahead (struct xfs_trans *tp,struct xfs_inode *dp, +xfs_dablk_t bno,xfs_daddr_t mapped_bno);extern struct xfs_dir2_data_free * xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,
fs/xfs/xfs_file.c +3 -1
@@ -31,6 +31,8 @@#include "xfs_error.h" #include "xfs_vnodeops.h" #include "xfs_da_btree.h" +#include "xfs_dir2_format.h" +#include "xfs_dir2_priv.h" #include "xfs_ioctl.h" #include "xfs_trace.h"
@@ -891,7 +893,7 @@ xfs_dir_open(*/ mode =xfs_ilock_map_shared (ip);if (ip->i_d.di_nextents >0 ) -xfs_da_reada_buf (NULL , ip,0 ,XFS_DATA_FORK ,NULL ); +xfs_dir2_data_readahead (NULL , ip,0 ,-1 );xfs_iunlock (ip, mode);return 0 ; }
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 27/32 xfs: add buffer pre-write callback
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Add a callback to the buffer write path to enable verification of the buffer and CRC calculation prior to issuing the write to the underlying storage.
If the callback function detects some kind of failure or error condition, it must mark the buffer with an error so that the caller can take appropriate action. In the case of xfs_buf_ioapply(), a corrupt metadta buffer willt rigger a shutdown of the filesystem, because something is clearly wrong and we can't allow corrupt metadata to be written to disk.
--- fs/xfs/xfs_buf.c | 16 ++++++++++++++++ fs/xfs/xfs_buf.h | 3 +++ 2 files changed, 19 insertions(+)
fs/xfs/xfs_buf.c +16 -0
@@ -569,7 +569,9 @@ found:*/ if (bp->b_flags &XBF_STALE ) {ASSERT ((bp->b_flags & _XBF_DELWRI_Q) ==0 ); +ASSERT (bp->b_iodone ==NULL ); bp->b_flags &= _XBF_KMEM | _XBF_PAGES; + bp->b_pre_io =NULL ; }trace_xfs_buf_find (bp, flags, _RET_IP_);
@@ -1324,6 +1326,20 @@ _xfs_buf_ioapply( rw |=REQ_META ;/* +* run the pre-io callback function if it exists. If this function +* fails it will mark the buffer with an error and the IO should +* not be dispatched. +*/ +if (bp->b_pre_io) { + bp->b_pre_io (bp); +if (bp->b_error) { +xfs_force_shutdown (bp->b_target->bt_mount, +SHUTDOWN_CORRUPT_INCORE ); +return ; + } + } + +/* * Walk all the vectors issuing IO on them. Set up the initial offset * into the buffer and the desired IO size before we start - * _xfs_buf_ioapply_vec() will modify them appropriately for each
fs/xfs/xfs_buf.h +3 -0
@@ -155,6 +155,9 @@ typedef struct xfs_buf {unsigned int b_offset;/* page offset in first page */ unsigned short b_error;/* error code on I/O */ +void (*b_pre_io)(struct xfs_buf *); +/* pre-io callback function */ +#ifdef XFS_BUF_LOCK_TRACKING int b_last_holder;#endif
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH 27/32 xfs: add buffer pre-write callback
xfs: add buffer pre-write callback
From: Dave Chinner <[email protected]>
Add a callback to the buffer write path to enable verification of the buffer and CRC calculation prior to issuing the write to the underlying storage.
If the callback function detects some kind of failure or error condition, it must mark the buffer with an error so that the caller can take appropriate action. In the case of xfs_buf_ioapply(), a corrupt metadta buffer willt rigger a shutdown of the filesystem, because something is clearly wrong and we can't allow corrupt metadata to be written to disk.
---
Reposting the version I have in case there was a missing update.
fs/xfs/xfs_buf.c | 16 ++++++++++++++++ fs/xfs/xfs_buf.h | 3 +++ 2 files changed, 19 insertions(+)
fs/xfs/xfs_buf.c +16 -0
@@ -569,7 +569,9 @@ found:*/ if (bp->b_flags &XBF_STALE ) {ASSERT ((bp->b_flags & _XBF_DELWRI_Q) ==0 ); +ASSERT (bp->b_iodone ==NULL ); bp->b_flags &= _XBF_KMEM | _XBF_PAGES; + bp->b_pre_io =NULL ; }trace_xfs_buf_find (bp, flags, _RET_IP_);
@@ -1314,6 +1316,20 @@ _xfs_buf_ioapply( rw |=REQ_META ;/* +* run the pre-io callback function if it exists. If this function +* fails it will mark the buffer with an error and the IO should +* not be dispatched. +*/ +if (bp->b_pre_io) { + bp->b_pre_io (bp); +if (bp->b_error) { +xfs_force_shutdown (bp->b_target->bt_mount, +SHUTDOWN_CORRUPT_INCORE ); +return ; + } + } + +/* * Walk all the vectors issuing IO on them. Set up the initial offset * into the buffer and the desired IO size before we start - * _xfs_buf_ioapply_vec() will modify them appropriately for each
fs/xfs/xfs_buf.h +3 -0
@@ -155,6 +155,9 @@ typedef struct xfs_buf {unsigned int b_offset;/* page offset in first page */ unsigned short b_error;/* error code on I/O */ +void (*b_pre_io)(struct xfs_buf *); +/* pre-io callback function */ +#ifdef XFS_BUF_LOCK_TRACKING int b_last_holder;#endif
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 28/32 xfs: add pre-write metadata buffer verifier callbacks
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
These verifiers are essentially the same code as the read verifiers, but do not require ioend processing. Hence factor the read verifier functions and add a new write verifier wrapper that is used as the callback.
This is done as one large patch for all verifiers rather than one patch per verifier as the change is largely mechanical. This includes hooking up the write verifier via the read verifier function.
Hooking up the write verifier for buffers obtained via xfs_trans_get_buf() will be done in a separate patch as that touches code in many different places rather than just the verifier functions.
--- fs/xfs/xfs_alloc.c | 35 ++++++++++++++++++++++++++++++++--- fs/xfs/xfs_alloc_btree.c | 21 +++++++++++++++++---- fs/xfs/xfs_attr_leaf.c | 19 +++++++++++++++++-- fs/xfs/xfs_attr_leaf.h | 2 +- fs/xfs/xfs_bmap_btree.c | 21 +++++++++++++++++---- fs/xfs/xfs_da_btree.c | 37 +++++++++++++++++++++++++------------ fs/xfs/xfs_dir2_block.c | 16 +++++++++++++++- fs/xfs/xfs_dir2_data.c | 19 +++++++++++++++++-- fs/xfs/xfs_dir2_leaf.c | 31 ++++++++++++++++++++++++------- fs/xfs/xfs_dir2_node.c | 17 ++++++++++++++++- fs/xfs/xfs_dir2_priv.h | 2 +- fs/xfs/xfs_dquot.c | 22 ++++++++++++++++++---- fs/xfs/xfs_ialloc.c | 17 ++++++++++++++++- fs/xfs/xfs_ialloc_btree.c | 19 ++++++++++++++++--- fs/xfs/xfs_inode.c | 19 +++++++++++++++++-- fs/xfs/xfs_inode.h | 2 +- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_mount.c | 19 +++++++++++++++++-- 18 files changed, 268 insertions(+), 52 deletions(-)
fs/xfs/xfs_alloc.c +32 -3
@@ -430,8 +430,8 @@ xfs_alloc_fixup_trees(return 0 ; } -void -xfs_agfl_read_verify ( +static void +xfs_agfl_verify (struct xfs_buf *bp) {#ifdef WHEN_CRCS_COME_ALONG
@@ -463,6 +463,21 @@ xfs_agfl_read_verify( xfs_buf_ioerror(bp, EFSCORRUPTED); }#endif +} + +static void +xfs_agfl_write_verify ( +struct xfs_buf *bp) +{ +xfs_agfl_verify (bp); +} + +void +xfs_agfl_read_verify ( +struct xfs_buf *bp) +{ +xfs_agfl_verify (bp); + bp->b_pre_io = xfs_agfl_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -2129,7 +2144,7 @@ xfs_alloc_put_freelist( }static void -xfs_agf_read_verify ( +xfs_agf_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -2165,7 +2180,21 @@ xfs_agf_read_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, agf);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_agf_write_verify ( +struct xfs_buf *bp) +{ +xfs_agf_verify (bp); +} +void +xfs_agf_read_verify ( +struct xfs_buf *bp) +{ +xfs_agf_verify (bp); + bp->b_pre_io = xfs_agf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_alloc_btree.c +17 -4
@@ -272,8 +272,8 @@ xfs_allocbt_key_diff(return (__int64_t )be32_to_cpu (kp->ar_startblock) - rec->ar_startblock; } -void -xfs_allocbt_read_verify ( +static void +xfs_allocbt_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -323,11 +323,24 @@ xfs_allocbt_read_verify(if (!sblock_ok) {trace_xfs_btree_corrupt (bp, _RET_IP_); -XFS_CORRUPTION_ERROR ("xfs_allocbt_read_verify" , -XFS_ERRLEVEL_LOW , mp, block); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, block);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} +static void +xfs_allocbt_write_verify ( +struct xfs_buf *bp) +{ +xfs_allocbt_verify (bp); +} + +void +xfs_allocbt_read_verify ( +struct xfs_buf *bp) +{ +xfs_allocbt_verify (bp); + bp->b_pre_io = xfs_allocbt_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_attr_leaf.c +17 -2
@@ -88,7 +88,7 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, xfs_mount_t *mp); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); -void +static void xfs_attr_leaf_verify (struct xfs_buf *bp) {
@@ -101,11 +101,26 @@ xfs_attr_leaf_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_attr_leaf_write_verify ( +struct xfs_buf *bp) +{ +xfs_attr_leaf_verify (bp); +} +void +xfs_attr_leaf_read_verify ( +struct xfs_buf *bp) +{ +xfs_attr_leaf_verify (bp); + bp->b_pre_io = xfs_attr_leaf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); } + int xfs_attr_leaf_read( struct xfs_trans *tp,
@@ -115,7 +130,7 @@ xfs_attr_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, -XFS_ATTR_FORK , xfs_attr_leaf_verify); +XFS_ATTR_FORK , xfs_attr_leaf_read_verify); }/*========================================================================
fs/xfs/xfs_attr_leaf.h +1 -1
@@ -264,6 +264,6 @@ int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,int xfs_attr_leaf_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); -void xfs_attr_leaf_verify (struct xfs_buf *bp); +void xfs_attr_leaf_read_verify (struct xfs_buf *bp);#endif /* __XFS_ATTR_LEAF_H__ */
fs/xfs/xfs_bmap_btree.c +17 -4
@@ -708,8 +708,8 @@ xfs_bmbt_key_diff( cur->bc_rec.b.br_startoff; } -void -xfs_bmbt_read_verify ( +static void +xfs_bmbt_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -744,11 +744,24 @@ xfs_bmbt_read_verify(if (!lblock_ok) {trace_xfs_btree_corrupt (bp, _RET_IP_); -XFS_CORRUPTION_ERROR ("xfs_bmbt_read_verify" , -XFS_ERRLEVEL_LOW , mp, block); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, block);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} +static void +xfs_bmbt_write_verify ( +struct xfs_buf *bp) +{ +xfs_bmbt_verify (bp); +} + +void +xfs_bmbt_read_verify ( +struct xfs_buf *bp) +{ +xfs_bmbt_verify (bp); + bp->b_pre_io = xfs_bmbt_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_da_btree.c +25 -12
@@ -92,7 +92,7 @@ STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);static void -__xfs_da_node_verify ( +xfs_da_node_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -108,12 +108,17 @@ __xfs_da_node_verify(xfs_buf_ioerror (bp,EFSCORRUPTED ); } - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); }static void -xfs_da_node_verify ( +xfs_da_node_write_verify ( +struct xfs_buf *bp) +{ +xfs_da_node_verify (bp); +} + +static void +xfs_da_node_read_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -121,21 +126,22 @@ xfs_da_node_verify(switch (be16_to_cpu (info->magic)) {case XFS_DA_NODE_MAGIC : -__xfs_da_node_verify (bp); -return ; +xfs_da_node_verify (bp); +break ;case XFS_ATTR_LEAF_MAGIC : -xfs_attr_leaf_verify (bp); +xfs_attr_leaf_read_verify (bp);return ;case XFS_DIR2_LEAFN_MAGIC : -xfs_dir2_leafn_verify (bp); +xfs_dir2_leafn_read_verify (bp);return ;default : +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , + mp, info); +xfs_buf_ioerror (bp,EFSCORRUPTED );break ; } -XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, info); -xfs_buf_ioerror (bp,EFSCORRUPTED ); - + bp->b_pre_io = xfs_da_node_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -150,7 +156,7 @@ xfs_da_node_read( int which_fork) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, - which_fork, xfs_da_node_verify); + which_fork, xfs_da_node_read_verify); }/*========================================================================
@@ -816,7 +822,14 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)xfs_da_blkinfo_onlychild_validate (bp->b_addr,be16_to_cpu (oldroot->hdr.level)); +/* +* This could be copying a leaf back into the root block in the case of +* there only being a single leaf block left in the tree. Hence we have +* to update the pre_io pointer as well to match the buffer type change +* that could occur. +*/ memcpy (root_blk->bp->b_addr, bp->b_addr, state->blocksize); + root_blk->bp->b_pre_io = bp->b_pre_io;xfs_trans_log_buf (args->trans, root_blk->bp,0 , state->blocksize -1 ); error =xfs_da_shrink_inode (args, child, bp);return (error);
fs/xfs/xfs_dir2_block.c +15 -1
@@ -71,7 +71,21 @@ xfs_dir2_block_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} +static void +xfs_dir2_block_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_block_verify (bp); +} + +void +xfs_dir2_block_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_block_verify (bp); + bp->b_pre_io = xfs_dir2_block_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -85,7 +99,7 @@ xfs_dir2_block_read(struct xfs_mount *mp = dp->i_mount;return xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , bpp, -XFS_DATA_FORK , xfs_dir2_block_verify); +XFS_DATA_FORK , xfs_dir2_block_read_verify); } static void
fs/xfs/xfs_dir2_data.c +17 -2
@@ -200,11 +200,26 @@ xfs_dir2_data_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_dir2_data_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_data_verify (bp); +} +void +xfs_dir2_data_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_data_verify (bp); + bp->b_pre_io = xfs_dir2_data_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); } + int xfs_dir2_data_read( struct xfs_trans *tp,
@@ -214,7 +229,7 @@ xfs_dir2_data_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, bno, mapped_bno, bpp, -XFS_DATA_FORK , xfs_dir2_data_verify); +XFS_DATA_FORK , xfs_dir2_data_read_verify); }int
@@ -225,7 +240,7 @@ xfs_dir2_data_readahead( xfs_daddr_t mapped_bno) {return xfs_da_reada_buf (tp, dp, bno, mapped_bno, -XFS_DATA_FORK , xfs_dir2_data_verify); +XFS_DATA_FORK , xfs_dir2_data_read_verify); }/*
fs/xfs/xfs_dir2_leaf.c +24 -7
@@ -62,23 +62,40 @@ xfs_dir2_leaf_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_dir2_leaf1_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); +} +static void +xfs_dir2_leaf1_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); + bp->b_pre_io = xfs_dir2_leaf1_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }static void -xfs_dir2_leaf1_verify ( -struct xfs_buf *bp) +xfs_dir2_leafn_write_verify ( +struct xfs_buf *bp) { -xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); }void -xfs_dir2_leafn_verify ( -struct xfs_buf *bp) +xfs_dir2_leafn_read_verify ( +struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); + bp->b_pre_io = xfs_dir2_leafn_write_verify; + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); } static int
@@ -90,7 +107,7 @@ xfs_dir2_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leaf1_verify); +XFS_DATA_FORK , xfs_dir2_leaf1_read_verify); }int
@@ -102,7 +119,7 @@ xfs_dir2_leafn_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leafn_verify); +XFS_DATA_FORK , xfs_dir2_leafn_read_verify); }/*
fs/xfs/xfs_dir2_node.c +16 -1
@@ -69,11 +69,26 @@ xfs_dir2_free_verify( XFS_ERRLEVEL_LOW, mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_dir2_free_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_free_verify (bp); +} +void +xfs_dir2_free_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_free_verify (bp); + bp->b_pre_io = xfs_dir2_free_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); } + static int __xfs_dir2_free_read( struct xfs_trans *tp,
@@ -83,7 +98,7 @@ __xfs_dir2_free_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_free_verify); +XFS_DATA_FORK , xfs_dir2_free_read_verify); }int
fs/xfs/xfs_dir2_priv.h +1 -1
@@ -72,7 +72,7 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);/* xfs_dir2_leaf.c */ -extern void xfs_dir2_leafn_verify (struct xfs_buf *bp); +extern void xfs_dir2_leafn_read_verify (struct xfs_buf *bp);extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
fs/xfs/xfs_dquot.c +18 -4
@@ -361,7 +361,7 @@ xfs_qm_dqalloc( } STATIC void -xfs_dquot_read_verify ( +xfs_dquot_buf_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -388,12 +388,26 @@ xfs_dquot_read_verify( error =xfs_qm_dqcheck (mp, ddq, id + i,0 ,XFS_QMOPT_DOWARN ,"xfs_dquot_read_verify" );if (error) { -XFS_CORRUPTION_ERROR ("xfs_dquot_read_verify" , -XFS_ERRLEVEL_LOW , mp, d); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, d);xfs_buf_ioerror (bp,EFSCORRUPTED );break ; } } +} + +static void +xfs_dquot_buf_write_verify ( +struct xfs_buf *bp) +{ +xfs_dquot_buf_verify (bp); +} + +static void +xfs_dquot_buf_read_verify ( +struct xfs_buf *bp) +{ +xfs_dquot_buf_verify (bp); + bp->b_pre_io = xfs_dquot_buf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -521,7 +535,7 @@ xfs_qm_dqtobp( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, -0 , &bp, xfs_dquot_read_verify); +0 , &bp, xfs_dquot_buf_read_verify);if (error ==EFSCORRUPTED && (flags &XFS_QMOPT_DQREPAIR )) { xfs_dqid_t firstid = (xfs_dqid_t)map.br_startoff *
fs/xfs/xfs_ialloc.c +16 -1
@@ -1473,7 +1473,7 @@ xfs_check_agi_unlinked(#endif static void -xfs_agi_read_verify ( +xfs_agi_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -1502,6 +1502,21 @@ xfs_agi_read_verify(xfs_buf_ioerror (bp,EFSCORRUPTED ); }xfs_check_agi_unlinked (agi); +} + +static void +xfs_agi_write_verify ( +struct xfs_buf *bp) +{ +xfs_agi_verify (bp); +} + +void +xfs_agi_read_verify ( +struct xfs_buf *bp) +{ +xfs_agi_verify (bp); + bp->b_pre_io = xfs_agi_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_ialloc_btree.c +16 -3
@@ -183,7 +183,7 @@ xfs_inobt_key_diff( }void -xfs_inobt_read_verify ( +xfs_inobt_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -211,11 +211,24 @@ xfs_inobt_read_verify(if (!sblock_ok) {trace_xfs_btree_corrupt (bp, _RET_IP_); -XFS_CORRUPTION_ERROR ("xfs_inobt_read_verify" , -XFS_ERRLEVEL_LOW , mp, block); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, block);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_inobt_write_verify ( +struct xfs_buf *bp) +{ +xfs_inobt_verify (bp); +} +void +xfs_inobt_read_verify ( +struct xfs_buf *bp) +{ +xfs_inobt_verify (bp); + bp->b_pre_io = xfs_inobt_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_inode.c +17 -2
@@ -382,7 +382,7 @@ xfs_inobp_check( }#endif -void +static void xfs_inode_buf_verify (struct xfs_buf *bp) {
@@ -418,6 +418,21 @@ xfs_inode_buf_verify( } }xfs_inobp_check (mp, bp); +} + +static void +xfs_inode_buf_write_verify ( +struct xfs_buf *bp) +{ +xfs_inode_buf_verify (bp); +} + +void +xfs_inode_buf_read_verify ( +struct xfs_buf *bp) +{ +xfs_inode_buf_verify (bp); + bp->b_pre_io = xfs_inode_buf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -447,7 +462,7 @@ xfs_imap_to_bp( buf_flags |=XBF_UNMAPPED ; error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, imap->im_blkno, (int )imap->im_len, buf_flags, &bp, - xfs_inode_buf_verify); + xfs_inode_buf_read_verify);if (error) {if (error ==EAGAIN ) {ASSERT (buf_flags &XBF_TRYLOCK );
fs/xfs/xfs_inode.h +1 -1
@@ -554,7 +554,7 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, struct xfs_buf **, uint, uint);int xfs_iread (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,uint ); -void xfs_inode_buf_verify (struct xfs_buf *); +void xfs_inode_buf_read_verify (struct xfs_buf *);void xfs_dinode_to_disk (struct xfs_dinode *,struct xfs_icdinode *);void xfs_idestroy_fork (struct xfs_inode *,int );
fs/xfs/xfs_itable.c +1 -1
@@ -397,7 +397,7 @@ xfs_bulkstat( & ~r.ir_free)xfs_btree_reada_bufs (mp, agno, agbno, nbcluster, - xfs_inode_buf_verify); + xfs_inode_buf_read_verify); } irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;
fs/xfs/xfs_mount.c +17 -2
@@ -612,8 +612,8 @@ xfs_sb_to_disk( } } -void -xfs_sb_read_verify ( +static void +xfs_sb_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -629,6 +629,21 @@ xfs_sb_read_verify( error =xfs_mount_validate_sb (mp, &sb, bp->b_bn ==XFS_SB_DADDR );if (error)xfs_buf_ioerror (bp, error); +} + +static void +xfs_sb_write_verify ( +struct xfs_buf *bp) +{ +xfs_sb_verify (bp); +} + +void +xfs_sb_read_verify ( +struct xfs_buf *bp) +{ +xfs_sb_verify (bp); + bp->b_pre_io = xfs_sb_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 28/32 xfs: add pre-write metadata buffer verifier callbacks
xfs: add pre-write metadata buffer verifier callbacks
From: Dave Chinner <[email protected]>
These verifiers are essentially the same code as the read verifiers, but do not require ioend processing. Hence factor the read verifier functions and add a new write verifier wrapper that is used as the callback.
This is done as one large patch for all verifiers rather than one patch per verifier as the change is largely mechanical. This includes hooking up the write verifier via the read verifier function.
Hooking up the write verifier for buffers obtained via xfs_trans_get_buf() will be done in a separate patch as that touches code in many different places rather than just the verifier functions.
---
V2: fold in quotacheck dquot verifier changes.
fs/xfs/xfs_alloc.c | 35 ++++++++++++++++++++++++++++++++--- fs/xfs/xfs_alloc_btree.c | 21 +++++++++++++++++---- fs/xfs/xfs_attr_leaf.c | 19 +++++++++++++++++-- fs/xfs/xfs_attr_leaf.h | 2 +- fs/xfs/xfs_bmap_btree.c | 21 +++++++++++++++++---- fs/xfs/xfs_da_btree.c | 37 +++++++++++++++++++++++++------------ fs/xfs/xfs_dir2_block.c | 16 +++++++++++++++- fs/xfs/xfs_dir2_data.c | 19 +++++++++++++++++-- fs/xfs/xfs_dir2_leaf.c | 31 ++++++++++++++++++++++++------- fs/xfs/xfs_dir2_node.c | 17 ++++++++++++++++- fs/xfs/xfs_dir2_priv.h | 2 +- fs/xfs/xfs_dquot.c | 27 +++++++++++++++++++++------ fs/xfs/xfs_dquot.h | 2 +- fs/xfs/xfs_ialloc.c | 17 ++++++++++++++++- fs/xfs/xfs_ialloc_btree.c | 19 ++++++++++++++++--- fs/xfs/xfs_inode.c | 19 +++++++++++++++++-- fs/xfs/xfs_inode.h | 2 +- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_mount.c | 19 +++++++++++++++++-- fs/xfs/xfs_qm.c | 2 +- 20 files changed, 273 insertions(+), 56 deletions(-)
fs/xfs/xfs_alloc.c +32 -3
@@ -430,8 +430,8 @@ xfs_alloc_fixup_trees(return 0 ; } -void -xfs_agfl_read_verify ( +static void +xfs_agfl_verify (struct xfs_buf *bp) {#ifdef WHEN_CRCS_COME_ALONG
@@ -463,6 +463,21 @@ xfs_agfl_read_verify( xfs_buf_ioerror(bp, EFSCORRUPTED); }#endif +} + +static void +xfs_agfl_write_verify ( +struct xfs_buf *bp) +{ +xfs_agfl_verify (bp); +} + +void +xfs_agfl_read_verify ( +struct xfs_buf *bp) +{ +xfs_agfl_verify (bp); + bp->b_pre_io = xfs_agfl_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -2129,7 +2144,7 @@ xfs_alloc_put_freelist( }static void -xfs_agf_read_verify ( +xfs_agf_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -2164,7 +2179,21 @@ xfs_agf_read_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, agf);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_agf_write_verify ( +struct xfs_buf *bp) +{ +xfs_agf_verify (bp); +} +void +xfs_agf_read_verify ( +struct xfs_buf *bp) +{ +xfs_agf_verify (bp); + bp->b_pre_io = xfs_agf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_alloc_btree.c +17 -4
@@ -272,8 +272,8 @@ xfs_allocbt_key_diff(return (__int64_t )be32_to_cpu (kp->ar_startblock) - rec->ar_startblock; } -void -xfs_allocbt_read_verify ( +static void +xfs_allocbt_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -323,11 +323,24 @@ xfs_allocbt_read_verify(if (!sblock_ok) {trace_xfs_btree_corrupt (bp, _RET_IP_); -XFS_CORRUPTION_ERROR ("xfs_allocbt_read_verify" , -XFS_ERRLEVEL_LOW , mp, block); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, block);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} +static void +xfs_allocbt_write_verify ( +struct xfs_buf *bp) +{ +xfs_allocbt_verify (bp); +} + +void +xfs_allocbt_read_verify ( +struct xfs_buf *bp) +{ +xfs_allocbt_verify (bp); + bp->b_pre_io = xfs_allocbt_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_attr_leaf.c +17 -2
@@ -88,7 +88,7 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, xfs_mount_t *mp); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); -void +static void xfs_attr_leaf_verify (struct xfs_buf *bp) {
@@ -101,11 +101,26 @@ xfs_attr_leaf_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_attr_leaf_write_verify ( +struct xfs_buf *bp) +{ +xfs_attr_leaf_verify (bp); +} +void +xfs_attr_leaf_read_verify ( +struct xfs_buf *bp) +{ +xfs_attr_leaf_verify (bp); + bp->b_pre_io = xfs_attr_leaf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); } + int xfs_attr_leaf_read( struct xfs_trans *tp,
@@ -115,7 +130,7 @@ xfs_attr_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, -XFS_ATTR_FORK , xfs_attr_leaf_verify); +XFS_ATTR_FORK , xfs_attr_leaf_read_verify); }/*========================================================================
fs/xfs/xfs_attr_leaf.h +1 -1
@@ -264,6 +264,6 @@ int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,int xfs_attr_leaf_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); -void xfs_attr_leaf_verify (struct xfs_buf *bp); +void xfs_attr_leaf_read_verify (struct xfs_buf *bp);#endif /* __XFS_ATTR_LEAF_H__ */
fs/xfs/xfs_bmap_btree.c +17 -4
@@ -708,8 +708,8 @@ xfs_bmbt_key_diff( cur->bc_rec.b.br_startoff; } -void -xfs_bmbt_read_verify ( +static void +xfs_bmbt_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -744,11 +744,24 @@ xfs_bmbt_read_verify(if (!lblock_ok) {trace_xfs_btree_corrupt (bp, _RET_IP_); -XFS_CORRUPTION_ERROR ("xfs_bmbt_read_verify" , -XFS_ERRLEVEL_LOW , mp, block); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, block);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} +static void +xfs_bmbt_write_verify ( +struct xfs_buf *bp) +{ +xfs_bmbt_verify (bp); +} + +void +xfs_bmbt_read_verify ( +struct xfs_buf *bp) +{ +xfs_bmbt_verify (bp); + bp->b_pre_io = xfs_bmbt_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_da_btree.c +25 -12
@@ -92,7 +92,7 @@ STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);static void -__xfs_da_node_verify ( +xfs_da_node_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -108,12 +108,17 @@ __xfs_da_node_verify(xfs_buf_ioerror (bp,EFSCORRUPTED ); } - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); }static void -xfs_da_node_verify ( +xfs_da_node_write_verify ( +struct xfs_buf *bp) +{ +xfs_da_node_verify (bp); +} + +static void +xfs_da_node_read_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -121,21 +126,22 @@ xfs_da_node_verify(switch (be16_to_cpu (info->magic)) {case XFS_DA_NODE_MAGIC : -__xfs_da_node_verify (bp); -return ; +xfs_da_node_verify (bp); +break ;case XFS_ATTR_LEAF_MAGIC : -xfs_attr_leaf_verify (bp); +xfs_attr_leaf_read_verify (bp);return ;case XFS_DIR2_LEAFN_MAGIC : -xfs_dir2_leafn_verify (bp); +xfs_dir2_leafn_read_verify (bp);return ;default : +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , + mp, info); +xfs_buf_ioerror (bp,EFSCORRUPTED );break ; } -XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, info); -xfs_buf_ioerror (bp,EFSCORRUPTED ); - + bp->b_pre_io = xfs_da_node_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -150,7 +156,7 @@ xfs_da_node_read( int which_fork) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, - which_fork, xfs_da_node_verify); + which_fork, xfs_da_node_read_verify); }/*========================================================================
@@ -816,7 +822,14 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)xfs_da_blkinfo_onlychild_validate (bp->b_addr,be16_to_cpu (oldroot->hdr.level)); +/* +* This could be copying a leaf back into the root block in the case of +* there only being a single leaf block left in the tree. Hence we have +* to update the pre_io pointer as well to match the buffer type change +* that could occur. +*/ memcpy (root_blk->bp->b_addr, bp->b_addr, state->blocksize); + root_blk->bp->b_pre_io = bp->b_pre_io;xfs_trans_log_buf (args->trans, root_blk->bp,0 , state->blocksize -1 ); error =xfs_da_shrink_inode (args, child, bp);return (error);
fs/xfs/xfs_dir2_block.c +15 -1
@@ -71,7 +71,21 @@ xfs_dir2_block_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} +static void +xfs_dir2_block_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_block_verify (bp); +} + +void +xfs_dir2_block_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_block_verify (bp); + bp->b_pre_io = xfs_dir2_block_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -85,7 +99,7 @@ xfs_dir2_block_read(struct xfs_mount *mp = dp->i_mount;return xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , bpp, -XFS_DATA_FORK , xfs_dir2_block_verify); +XFS_DATA_FORK , xfs_dir2_block_read_verify); } static void
fs/xfs/xfs_dir2_data.c +17 -2
@@ -200,11 +200,26 @@ xfs_dir2_data_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_dir2_data_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_data_verify (bp); +} +void +xfs_dir2_data_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_data_verify (bp); + bp->b_pre_io = xfs_dir2_data_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); } + int xfs_dir2_data_read( struct xfs_trans *tp,
@@ -214,7 +229,7 @@ xfs_dir2_data_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, bno, mapped_bno, bpp, -XFS_DATA_FORK , xfs_dir2_data_verify); +XFS_DATA_FORK , xfs_dir2_data_read_verify); }int
@@ -225,7 +240,7 @@ xfs_dir2_data_readahead( xfs_daddr_t mapped_bno) {return xfs_da_reada_buf (tp, dp, bno, mapped_bno, -XFS_DATA_FORK , xfs_dir2_data_verify); +XFS_DATA_FORK , xfs_dir2_data_read_verify); }/*
fs/xfs/xfs_dir2_leaf.c +24 -7
@@ -62,23 +62,40 @@ xfs_dir2_leaf_verify(XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_dir2_leaf1_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); +} +static void +xfs_dir2_leaf1_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); + bp->b_pre_io = xfs_dir2_leaf1_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }static void -xfs_dir2_leaf1_verify ( -struct xfs_buf *bp) +xfs_dir2_leafn_write_verify ( +struct xfs_buf *bp) { -xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); +xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); }void -xfs_dir2_leafn_verify ( -struct xfs_buf *bp) +xfs_dir2_leafn_read_verify ( +struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); + bp->b_pre_io = xfs_dir2_leafn_write_verify; + bp->b_iodone =NULL ; +xfs_buf_ioend (bp,0 ); } static int
@@ -90,7 +107,7 @@ xfs_dir2_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leaf1_verify); +XFS_DATA_FORK , xfs_dir2_leaf1_read_verify); }int
@@ -102,7 +119,7 @@ xfs_dir2_leafn_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leafn_verify); +XFS_DATA_FORK , xfs_dir2_leafn_read_verify); }/*
fs/xfs/xfs_dir2_node.c +16 -1
@@ -69,11 +69,26 @@ xfs_dir2_free_verify( XFS_ERRLEVEL_LOW, mp, hdr);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_dir2_free_write_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_free_verify (bp); +} +void +xfs_dir2_free_read_verify ( +struct xfs_buf *bp) +{ +xfs_dir2_free_verify (bp); + bp->b_pre_io = xfs_dir2_free_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); } + static int __xfs_dir2_free_read( struct xfs_trans *tp,
@@ -83,7 +98,7 @@ __xfs_dir2_free_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_free_verify); +XFS_DATA_FORK , xfs_dir2_free_read_verify); }int
fs/xfs/xfs_dir2_priv.h +1 -1
@@ -72,7 +72,7 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);/* xfs_dir2_leaf.c */ -extern void xfs_dir2_leafn_verify (struct xfs_buf *bp); +extern void xfs_dir2_leafn_read_verify (struct xfs_buf *bp);extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
fs/xfs/xfs_dquot.c +21 -6
@@ -360,8 +360,8 @@ xfs_qm_dqalloc(return (error); } -void -xfs_dquot_read_verify ( +static void +xfs_dquot_buf_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -388,12 +388,26 @@ xfs_dquot_read_verify( error =xfs_qm_dqcheck (mp, ddq, id + i,0 ,XFS_QMOPT_DOWARN ,"xfs_dquot_read_verify" );if (error) { -XFS_CORRUPTION_ERROR ("xfs_dquot_read_verify" , -XFS_ERRLEVEL_LOW , mp, d); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, d);xfs_buf_ioerror (bp,EFSCORRUPTED );break ; } } +} + +static void +xfs_dquot_buf_write_verify ( +struct xfs_buf *bp) +{ +xfs_dquot_buf_verify (bp); +} + +void +xfs_dquot_buf_read_verify ( +struct xfs_buf *bp) +{ +xfs_dquot_buf_verify (bp); + bp->b_pre_io = xfs_dquot_buf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -413,7 +427,7 @@ xfs_qm_dqrepair(/* * Read the buffer without verification so we get the corrupted -* buffer returned to us. +* buffer returned to us. make sure we verify it on write, though. */ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen,
@@ -423,6 +437,7 @@ xfs_qm_dqrepair(ASSERT (*bpp ==NULL );return XFS_ERROR (error); } + (*bpp)->b_pre_io = xfs_dquot_buf_write_verify;ASSERT (xfs_buf_islocked (*bpp)); d = (struct xfs_dqblk *)(*bpp)->b_addr;
@@ -521,7 +536,7 @@ xfs_qm_dqtobp( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, -0 , &bp, xfs_dquot_read_verify); +0 , &bp, xfs_dquot_buf_read_verify);if (error ==EFSCORRUPTED && (flags &XFS_QMOPT_DQREPAIR )) { xfs_dqid_t firstid = (xfs_dqid_t)map.br_startoff *
fs/xfs/xfs_dquot.h +1 -1
@@ -140,7 +140,7 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)extern int xfs_qm_dqread (struct xfs_mount *,xfs_dqid_t ,uint ,uint ,struct xfs_dquot **); -extern void xfs_dquot_read_verify (struct xfs_buf *bp); +extern void xfs_dquot_buf_read_verify (struct xfs_buf *bp);extern void xfs_qm_dqdestroy (xfs_dquot_t *);extern int xfs_qm_dqflush (struct xfs_dquot *,struct xfs_buf **);extern void xfs_qm_dqunpin_wait (xfs_dquot_t *);
fs/xfs/xfs_ialloc.c +16 -1
@@ -1473,7 +1473,7 @@ xfs_check_agi_unlinked(#endif static void -xfs_agi_read_verify ( +xfs_agi_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -1502,6 +1502,21 @@ xfs_agi_read_verify(xfs_buf_ioerror (bp,EFSCORRUPTED ); }xfs_check_agi_unlinked (agi); +} + +static void +xfs_agi_write_verify ( +struct xfs_buf *bp) +{ +xfs_agi_verify (bp); +} + +void +xfs_agi_read_verify ( +struct xfs_buf *bp) +{ +xfs_agi_verify (bp); + bp->b_pre_io = xfs_agi_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_ialloc_btree.c +16 -3
@@ -183,7 +183,7 @@ xfs_inobt_key_diff( }void -xfs_inobt_read_verify ( +xfs_inobt_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -211,11 +211,24 @@ xfs_inobt_read_verify(if (!sblock_ok) {trace_xfs_btree_corrupt (bp, _RET_IP_); -XFS_CORRUPTION_ERROR ("xfs_inobt_read_verify" , -XFS_ERRLEVEL_LOW , mp, block); +XFS_CORRUPTION_ERROR (__func__,XFS_ERRLEVEL_LOW , mp, block);xfs_buf_ioerror (bp,EFSCORRUPTED ); } +} + +static void +xfs_inobt_write_verify ( +struct xfs_buf *bp) +{ +xfs_inobt_verify (bp); +} +void +xfs_inobt_read_verify ( +struct xfs_buf *bp) +{ +xfs_inobt_verify (bp); + bp->b_pre_io = xfs_inobt_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_inode.c +17 -2
@@ -382,7 +382,7 @@ xfs_inobp_check( }#endif -void +static void xfs_inode_buf_verify (struct xfs_buf *bp) {
@@ -418,6 +418,21 @@ xfs_inode_buf_verify( } }xfs_inobp_check (mp, bp); +} + +static void +xfs_inode_buf_write_verify ( +struct xfs_buf *bp) +{ +xfs_inode_buf_verify (bp); +} + +void +xfs_inode_buf_read_verify ( +struct xfs_buf *bp) +{ +xfs_inode_buf_verify (bp); + bp->b_pre_io = xfs_inode_buf_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
@@ -447,7 +462,7 @@ xfs_imap_to_bp( buf_flags |=XBF_UNMAPPED ; error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, imap->im_blkno, (int )imap->im_len, buf_flags, &bp, - xfs_inode_buf_verify); + xfs_inode_buf_read_verify);if (error) {if (error ==EAGAIN ) {ASSERT (buf_flags &XBF_TRYLOCK );
fs/xfs/xfs_inode.h +1 -1
@@ -554,7 +554,7 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, struct xfs_buf **, uint, uint);int xfs_iread (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,uint ); -void xfs_inode_buf_verify (struct xfs_buf *); +void xfs_inode_buf_read_verify (struct xfs_buf *);void xfs_dinode_to_disk (struct xfs_dinode *,struct xfs_icdinode *);void xfs_idestroy_fork (struct xfs_inode *,int );
fs/xfs/xfs_itable.c +1 -1
@@ -397,7 +397,7 @@ xfs_bulkstat( & ~r.ir_free)xfs_btree_reada_bufs (mp, agno, agbno, nbcluster, - xfs_inode_buf_verify); + xfs_inode_buf_read_verify); } irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;
fs/xfs/xfs_mount.c +17 -2
@@ -612,8 +612,8 @@ xfs_sb_to_disk( } } -void -xfs_sb_read_verify ( +static void +xfs_sb_verify (struct xfs_buf *bp) {struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -629,6 +629,21 @@ xfs_sb_read_verify( error =xfs_mount_validate_sb (mp, &sb, bp->b_bn ==XFS_SB_DADDR );if (error)xfs_buf_ioerror (bp, error); +} + +static void +xfs_sb_write_verify ( +struct xfs_buf *bp) +{ +xfs_sb_verify (bp); +} + +void +xfs_sb_read_verify ( +struct xfs_buf *bp) +{ +xfs_sb_verify (bp); + bp->b_pre_io = xfs_sb_write_verify; bp->b_iodone =NULL ;xfs_buf_ioend (bp,0 ); }
fs/xfs/xfs_qm.c +1 -1
@@ -893,7 +893,7 @@ xfs_qm_dqiter_bufs( error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_FSB_TO_DADDR (mp, bno), mp->m_quotainfo->qi_dqchunklen,0 , &bp, - xfs_dquot_read_verify); + xfs_dquot_buf_read_verify);if (error)break ;
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 28/32 V2] xfs: add pre-write metadata buffer verifier callbacks
Quoted 14 lines · Dave Chinner
xfs: add pre-write metadata buffer verifier callbacks
From: Dave Chinner<[email protected]>
These verifiers are essentially the same code as the read verifiers, but do not require ioend processing. Hence factor the read verifier functions and add a new write verifier wrapper that is used as the callback.
This is done as one large patch for all verifiers rather than one patch per verifier as the change is largely mechanical. This includes hooking up the write verifier via the read verifier function.
Quoted 9 lines
Hooking up the write verifier for buffers obtained via
xfs_trans_get_buf()will be done in a separate patch as that touches code in many different places rather than just the verifier functions.Signed-off-by Dave Chinner<[email protected]>---
V2: fold in quotacheck dquot verifier changes.
Looks good.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 29/32 xfs: connect up write verifiers to new buffers
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
Metadata buffers that are read from disk have write verifiers already attached to them, but newly allocated buffers do not. Add appropriate write verifiers to all new metadata buffers.
--- fs/xfs/xfs_alloc.c | 8 ++-- fs/xfs/xfs_alloc.h | 3 ++ fs/xfs/xfs_alloc_btree.c | 1 + fs/xfs/xfs_attr_leaf.c | 4 +- fs/xfs/xfs_bmap.c | 2 + fs/xfs/xfs_bmap_btree.c | 3 +- fs/xfs/xfs_bmap_btree.h | 1 + fs/xfs/xfs_btree.c | 1 + fs/xfs/xfs_btree.h | 2 + fs/xfs/xfs_da_btree.c | 3 ++ fs/xfs/xfs_dir2_block.c | 2 + fs/xfs/xfs_dir2_data.c | 11 +++-- fs/xfs/xfs_dir2_leaf.c | 19 ++++++--- fs/xfs/xfs_dir2_node.c | 24 +++++++---- fs/xfs/xfs_dir2_priv.h | 2 + fs/xfs/xfs_dquot.c | 104 ++++++++++++++++++++++----------------------- fs/xfs/xfs_fsops.c | 8 +++- fs/xfs/xfs_ialloc.c | 5 ++- fs/xfs/xfs_ialloc.h | 4 +- fs/xfs/xfs_ialloc_btree.c | 1 + fs/xfs/xfs_inode.c | 14 +++++- fs/xfs/xfs_inode.h | 1 + fs/xfs/xfs_mount.c | 2 +- fs/xfs/xfs_mount.h | 1 + 24 files changed, 138 insertions(+), 88 deletions(-)
fs/xfs/xfs_alloc.c +4 -4
@@ -465,14 +465,14 @@ xfs_agfl_verify(#endif } -static void +void xfs_agfl_write_verify (struct xfs_buf *bp) {xfs_agfl_verify (bp); } -void +static void xfs_agfl_read_verify (struct xfs_buf *bp) {
@@ -2182,14 +2182,14 @@ xfs_agf_verify( } } -static void +void xfs_agf_write_verify (struct xfs_buf *bp) {xfs_agf_verify (bp); } -void +static void xfs_agf_read_verify (struct xfs_buf *bp) {
fs/xfs/xfs_alloc.h +3 -0
@@ -238,4 +238,7 @@ xfs_alloc_freespace_map(u64 start, u64 length); +void xfs_agf_write_verify (struct xfs_buf *bp); +void xfs_agfl_write_verify (struct xfs_buf *bp); +#endif /* __XFS_ALLOC_H__ */
fs/xfs/xfs_alloc_btree.c +1 -0
@@ -401,6 +401,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = { .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_allocbt_key_diff, .read_verify = xfs_allocbt_read_verify, + .write_verify = xfs_allocbt_write_verify, #ifdef DEBUG .keys_inorder = xfs_allocbt_keys_inorder, .recs_inorder = xfs_allocbt_recs_inorder,
fs/xfs/xfs_attr_leaf.c +2 -2
@@ -924,7 +924,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) XFS_ATTR_FORK);if (error) goto out; -ASSERT (bp2 !=NULL ); + bp2->b_pre_io = bp1->b_pre_io;memcpy (bp2->b_addr, bp1->b_addr,XFS_LBSIZE (dp->i_mount)); bp1 =NULL ;xfs_trans_log_buf (args->trans, bp2,0 ,XFS_LBSIZE (dp->i_mount) -1 );
@@ -978,7 +978,7 @@ xfs_attr_leaf_create( XFS_ATTR_FORK);if (error)return (error); -ASSERT (bp !=NULL ); + bp->b_pre_io = xfs_attr_leaf_write_verify; leaf = bp->b_addr;memset ((char *)leaf,0 ,XFS_LBSIZE (dp->i_mount)); hdr = &leaf->hdr;
fs/xfs/xfs_bmap.c +2 -0
@@ -3124,6 +3124,7 @@ xfs_bmap_extents_to_btree(/* * Fill in the child block. */ + abp->b_pre_io = xfs_bmbt_write_verify; ablock =XFS_BUF_TO_BLOCK (abp); ablock->bb_magic =cpu_to_be32 (XFS_BMAP_MAGIC ); ablock->bb_level =0 ;
@@ -3270,6 +3271,7 @@ xfs_bmap_local_to_extents(ASSERT (args.len ==1 ); *firstblock = args.fsbno; bp =xfs_btree_get_bufl (args.mp, tp, args.fsbno,0 ); + bp->b_pre_io = xfs_bmbt_write_verify;memcpy (bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);xfs_trans_log_buf (tp, bp,0 , ifp->if_bytes -1 );xfs_bmap_forkoff_reset (args.mp, ip, whichfork);
fs/xfs/xfs_bmap_btree.c +2 -1
@@ -749,7 +749,7 @@ xfs_bmbt_verify( } } -static void +void xfs_bmbt_write_verify (struct xfs_buf *bp) {
@@ -806,6 +806,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = { .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, .key_diff = xfs_bmbt_key_diff, .read_verify = xfs_bmbt_read_verify, + .write_verify = xfs_bmbt_write_verify, #ifdef DEBUG .keys_inorder = xfs_bmbt_keys_inorder, .recs_inorder = xfs_bmbt_recs_inorder,
fs/xfs/xfs_bmap_btree.h +1 -0
@@ -233,6 +233,7 @@ extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);extern int xfs_bmdr_maxrecs (struct xfs_mount *,int blocklen,int leaf);extern int xfs_bmbt_maxrecs (struct xfs_mount *,int blocklen,int leaf);extern void xfs_bmbt_read_verify (struct xfs_buf *bp); +extern void xfs_bmbt_write_verify (struct xfs_buf *bp);extern struct xfs_btree_cur *xfs_bmbt_init_cursor (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,int );
fs/xfs/xfs_btree.c +1 -0
@@ -996,6 +996,7 @@ xfs_btree_get_buf_block(if (!*bpp)return ENOMEM ; + (*bpp)->b_pre_io = cur->bc_ops->write_verify; *block =XFS_BUF_TO_BLOCK (*bpp);return 0 ; }
fs/xfs/xfs_btree.h +2 -0
@@ -189,6 +189,8 @@ struct xfs_btree_ops { union xfs_btree_key *key);void (*read_verify)(struct xfs_buf *bp); +void (*write_verify)(struct xfs_buf *bp); +#ifdef DEBUG /* check that k1 is lower than k2 */ int (*keys_inorder)(struct xfs_btree_cur *cur,
fs/xfs/xfs_da_btree.c +3 -0
@@ -193,6 +193,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,xfs_trans_log_buf (tp, bp,XFS_DA_LOGRANGE (node, &node->hdr,sizeof (node->hdr))); + bp->b_pre_io = xfs_da_node_write_verify; *bpp = bp;return (0 ); }
@@ -392,6 +393,8 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, }memcpy (node, oldroot, size);xfs_trans_log_buf (tp, bp,0 , size -1 ); + + bp->b_pre_io = blk1->bp->b_pre_io; blk1->bp = bp; blk1->blkno = blkno;
fs/xfs/xfs_dir2_block.c +2 -0
@@ -1010,6 +1010,7 @@ xfs_dir2_leaf_to_block(/* * Start converting it to block form. */ + dbp->b_pre_io = xfs_dir2_block_write_verify; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC ); needlog =1 ; needscan =0 ;
@@ -1139,6 +1140,7 @@ xfs_dir2_sf_to_block(kmem_free (sfp);return error; } + bp->b_pre_io = xfs_dir2_block_write_verify; hdr = bp->b_addr; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC );/*
fs/xfs/xfs_dir2_data.c +5 -6
@@ -185,7 +185,7 @@ __xfs_dir2_data_check(return 0 ; } -void +static void xfs_dir2_data_verify (struct xfs_buf *bp) {
@@ -202,14 +202,14 @@ xfs_dir2_data_verify( } } -static void +void xfs_dir2_data_write_verify (struct xfs_buf *bp) {xfs_dir2_data_verify (bp); } -void +static void xfs_dir2_data_read_verify (struct xfs_buf *bp) {
@@ -482,10 +482,9 @@ xfs_dir2_data_init(*/ error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, blkno),-1 , &bp,XFS_DATA_FORK ); -if (error) { +if (error)return error; - } -ASSERT (bp !=NULL ); + bp->b_pre_io = xfs_dir2_data_write_verify;/* * Initialize the header.
fs/xfs/xfs_dir2_leaf.c +12 -7
@@ -81,7 +81,7 @@ xfs_dir2_leaf1_read_verify(xfs_buf_ioend (bp,0 ); } -static void +void xfs_dir2_leafn_write_verify (struct xfs_buf *bp) {
@@ -198,6 +198,7 @@ xfs_dir2_block_to_leaf(/* * Fix up the block header, make it a data block. */ + dbp->b_pre_io = xfs_dir2_data_write_verify; hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );if (needscan)xfs_dir2_data_freescan (mp, hdr, &needlog);
@@ -1243,15 +1244,14 @@ xfs_dir2_leaf_init(* Get the buffer for the block. */ error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, bno),-1 , &bp, -XFS_DATA_FORK ); -if (error) { +XFS_DATA_FORK ); +if (error)return error; - } -ASSERT (bp !=NULL ); - leaf = bp->b_addr; +/* * Initialize the header. */ + leaf = bp->b_addr; leaf->hdr.info.magic =cpu_to_be16 (magic); leaf->hdr.info.forw =0 ; leaf->hdr.info.back =0 ;
@@ -1264,10 +1264,12 @@ xfs_dir2_leaf_init(* the block. */ if (magic ==XFS_DIR2_LEAF1_MAGIC ) { + bp->b_pre_io = xfs_dir2_leaf1_write_verify; ltp =xfs_dir2_leaf_tail_p (mp, leaf); ltp->bestcount =0 ;xfs_dir2_leaf_log_tail (tp, bp); - } + }else + bp->b_pre_io = xfs_dir2_leafn_write_verify; *bpp = bp;return 0 ; }
@@ -1951,7 +1953,10 @@ xfs_dir2_node_to_leaf(xfs_dir2_leaf_compact (args, lbp); elsexfs_dir2_leaf_log_header (tp ,lbp ); + + lbp->b_pre_io = xfs_dir2_leaf1_write_verify; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC ); +/* * Set up the leaf tail from the freespace block. */
fs/xfs/xfs_dir2_node.c +15 -9
@@ -197,11 +197,12 @@ xfs_dir2_leaf_to_node(/* * Get the buffer for the new freespace block. */ -if ((error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, fdb),-1 , &fbp, -XFS_DATA_FORK ))) { + error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, fdb),-1 , &fbp, +XFS_DATA_FORK ); +if (error)return error; - } -ASSERT (fbp !=NULL ); + fbp->b_pre_io = xfs_dir2_free_write_verify; + free = fbp->b_addr; leaf = lbp->b_addr; ltp =xfs_dir2_leaf_tail_p (mp, leaf);
@@ -223,7 +224,10 @@ xfs_dir2_leaf_to_node( *to =cpu_to_be16 (off); } free->hdr.nused =cpu_to_be32 (n); + + lbp->b_pre_io = xfs_dir2_leafn_write_verify; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC ); +/* * Log everything. */
@@ -632,6 +636,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index = (int )((char *)dep - (char *)curbp->b_addr); state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; + curbp->b_pre_io = xfs_dir2_data_write_verify;if (cmp ==XFS_CMP_EXACT )return XFS_ERROR (EEXIST ); }
@@ -646,6 +651,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index =-1 ; state->extrablk.blkno = curdb; state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; + curbp->b_pre_io = xfs_dir2_data_write_verify; }else {/* If the curbp is not the CI match block, drop it */ if (state->extrablk.bp != curbp)
@@ -1638,12 +1644,12 @@ xfs_dir2_node_addname_int(/* * Get a buffer for the new block. */ -if ((error =xfs_da_get_buf (tp, dp, -xfs_dir2_db_to_da (mp, fbno), --1 , &fbp,XFS_DATA_FORK ))) { + error =xfs_da_get_buf (tp, dp, +xfs_dir2_db_to_da (mp, fbno), +-1 , &fbp,XFS_DATA_FORK ); +if (error)return error; - } -ASSERT (fbp !=NULL ); + fbp->b_pre_io = xfs_dir2_free_write_verify;/* * Initialize the new block to be empty, and remember
fs/xfs/xfs_dir2_priv.h +2 -0
@@ -45,6 +45,7 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,#else #define xfs_dir2_data_check (dp,bp)#endif +extern void xfs_dir2_data_write_verify (struct xfs_buf *bp);extern int __xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp);extern int xfs_dir2_data_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mapped_bno,struct xfs_buf **bpp);
@@ -73,6 +74,7 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp,/* xfs_dir2_leaf.c */ extern void xfs_dir2_leafn_read_verify (struct xfs_buf *bp); +extern void xfs_dir2_leafn_write_verify (struct xfs_buf *bp);extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
fs/xfs/xfs_dquot.c +52 -52
122 lines not on this page · raw message
fs/xfs/xfs_fsops.c +6 -2
@@ -222,6 +222,7 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } + bp->b_pre_io = xfs_agf_write_verify; agf =XFS_BUF_TO_AGF (bp); agf->agf_magicnum =cpu_to_be32 (XFS_AGF_MAGIC );
@@ -259,6 +260,7 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } + bp->b_pre_io = xfs_agfl_write_verify; agfl =XFS_BUF_TO_AGFL (bp);for (bucket =0 ; bucket <XFS_AGFL_SIZE (mp); bucket++)
@@ -279,6 +281,7 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } + bp->b_pre_io = xfs_agi_write_verify; agi =XFS_BUF_TO_AGI (bp); agi->agi_magicnum =cpu_to_be32 (XFS_AGI_MAGIC );
@@ -450,9 +453,10 @@ xfs_growfs_data_private( bp =xfs_trans_get_buf (NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)),XFS_FSS_TO_BB (mp,1 ),0 ); -if (bp) +if (bp) {xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); -else + bp->b_pre_io = xfs_sb_write_verify; + }else error =ENOMEM ; }
fs/xfs/xfs_ialloc.c +3 -2
@@ -210,6 +210,7 @@ xfs_ialloc_inode_init(* to log a whole cluster of inodes instead of all the * individual transactions causing a lot of log traffic. */ + fbuf->b_pre_io = xfs_inode_buf_write_verify;xfs_buf_zero (fbuf,0 , ninodes << mp->m_sb.sb_inodelog);for (i =0 ; i < ninodes; i++) {int ioffset = i << mp->m_sb.sb_inodelog;
@@ -1504,14 +1505,14 @@ xfs_agi_verify(xfs_check_agi_unlinked (agi); } -static void +void xfs_agi_write_verify (struct xfs_buf *bp) {xfs_agi_verify (bp); } -void +static void xfs_agi_read_verify (struct xfs_buf *bp) {
fs/xfs/xfs_ialloc.h +3 -1
@@ -147,7 +147,9 @@ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,/* * Get the data from the pointed-to record. */ -extern int xfs_inobt_get_rec (struct xfs_btree_cur *cur, +int xfs_inobt_get_rec (struct xfs_btree_cur *cur,xfs_inobt_rec_incore_t *rec,int *stat); +void xfs_agi_write_verify (struct xfs_buf *bp); +#endif /* __XFS_IALLOC_H__ */
fs/xfs/xfs_ialloc_btree.c +1 -0
@@ -271,6 +271,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = { .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, .key_diff = xfs_inobt_key_diff, .read_verify = xfs_inobt_read_verify, + .write_verify = xfs_inobt_write_verify, #ifdef DEBUG .keys_inorder = xfs_inobt_keys_inorder, .recs_inorder = xfs_inobt_recs_inorder,
fs/xfs/xfs_inode.c +13 -1
@@ -420,7 +420,7 @@ xfs_inode_buf_verify(xfs_inobp_check (mp, bp); } -static void +void xfs_inode_buf_write_verify (struct xfs_buf *bp) {
@@ -1782,6 +1782,18 @@ xfs_ifree_cluster(if (!bp)return ENOMEM ; + +/* +* This buffer may not have been correctly initialised as we +* didn't read it from disk. That's not important because we are +* only using to mark the buffer as stale in the log, and to +* attach stale cached inodes on it. That means it will never be +* dispatched for IO. If it is, we want to know about it, and we +* want it to fail. We can acheive this by adding a write +* verifier to the buffer. +*/ + bp->b_pre_io = xfs_inode_buf_write_verify; +/* * Walk the inodes already attached to the buffer and mark them * stale. These will all have the flush locks held, so an
fs/xfs/xfs_inode.h +1 -0
@@ -555,6 +555,7 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,int xfs_iread (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,uint );void xfs_inode_buf_read_verify (struct xfs_buf *); +void xfs_inode_buf_write_verify (struct xfs_buf *);void xfs_dinode_to_disk (struct xfs_dinode *,struct xfs_icdinode *);void xfs_idestroy_fork (struct xfs_inode *,int );
fs/xfs/xfs_mount.c +1 -1
@@ -631,7 +631,7 @@ xfs_sb_verify(xfs_buf_ioerror (bp, error); } -static void +void xfs_sb_write_verify (struct xfs_buf *bp) {
fs/xfs/xfs_mount.h +1 -0
@@ -386,6 +386,7 @@ extern void xfs_set_low_space_thresholds(struct xfs_mount *);#endif /* __KERNEL__ */ extern void xfs_sb_read_verify (struct xfs_buf *); +extern void xfs_sb_write_verify (struct xfs_buf *bp);extern void xfs_mod_sb (struct xfs_trans *,__int64_t );extern int xfs_initialize_perag (struct xfs_mount *,xfs_agnumber_t ,xfs_agnumber_t *);
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 29/32 xfs: connect up write verifiers to new buffers
xfs: connect up write verifiers to new buffers
From: Dave Chinner <[email protected]>
Metadata buffers that are read from disk have write verifiers already attached to them, but newly allocated buffers do not. Add appropriate write verifiers to all new metadata buffers.
---
V2: fold in quotacheck dquot verifier changes.
fs/xfs/xfs_alloc.c | 8 ++-- fs/xfs/xfs_alloc.h | 3 ++ fs/xfs/xfs_alloc_btree.c | 1 + fs/xfs/xfs_attr_leaf.c | 4 +- fs/xfs/xfs_bmap.c | 2 + fs/xfs/xfs_bmap_btree.c | 3 +- fs/xfs/xfs_bmap_btree.h | 1 + fs/xfs/xfs_btree.c | 1 + fs/xfs/xfs_btree.h | 2 + fs/xfs/xfs_da_btree.c | 3 ++ fs/xfs/xfs_dir2_block.c | 2 + fs/xfs/xfs_dir2_data.c | 11 +++-- fs/xfs/xfs_dir2_leaf.c | 19 ++++++--- fs/xfs/xfs_dir2_node.c | 24 +++++++---- fs/xfs/xfs_dir2_priv.h | 2 + fs/xfs/xfs_dquot.c | 104 ++++++++++++++++++++++----------------------- fs/xfs/xfs_fsops.c | 8 +++- fs/xfs/xfs_ialloc.c | 5 ++- fs/xfs/xfs_ialloc.h | 4 +- fs/xfs/xfs_ialloc_btree.c | 1 + fs/xfs/xfs_inode.c | 14 +++++- fs/xfs/xfs_inode.h | 1 + fs/xfs/xfs_mount.c | 2 +- fs/xfs/xfs_mount.h | 1 + 24 files changed, 137 insertions(+), 89 deletions(-)
fs/xfs/xfs_alloc.c +4 -4
@@ -465,14 +465,14 @@ xfs_agfl_verify(#endif } -static void +void xfs_agfl_write_verify (struct xfs_buf *bp) {xfs_agfl_verify (bp); } -void +static void xfs_agfl_read_verify (struct xfs_buf *bp) {
@@ -2181,14 +2181,14 @@ xfs_agf_verify( } } -static void +void xfs_agf_write_verify (struct xfs_buf *bp) {xfs_agf_verify (bp); } -void +static void xfs_agf_read_verify (struct xfs_buf *bp) {
fs/xfs/xfs_alloc.h +3 -0
@@ -238,4 +238,7 @@ xfs_alloc_freespace_map(u64 start, u64 length); +void xfs_agf_write_verify (struct xfs_buf *bp); +void xfs_agfl_write_verify (struct xfs_buf *bp); +#endif /* __XFS_ALLOC_H__ */
fs/xfs/xfs_alloc_btree.c +1 -0
@@ -401,6 +401,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = { .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_allocbt_key_diff, .read_verify = xfs_allocbt_read_verify, + .write_verify = xfs_allocbt_write_verify, #ifdef DEBUG .keys_inorder = xfs_allocbt_keys_inorder, .recs_inorder = xfs_allocbt_recs_inorder,
fs/xfs/xfs_attr_leaf.c +2 -2
@@ -924,7 +924,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) XFS_ATTR_FORK);if (error) goto out; -ASSERT (bp2 !=NULL ); + bp2->b_pre_io = bp1->b_pre_io;memcpy (bp2->b_addr, bp1->b_addr,XFS_LBSIZE (dp->i_mount)); bp1 =NULL ;xfs_trans_log_buf (args->trans, bp2,0 ,XFS_LBSIZE (dp->i_mount) -1 );
@@ -978,7 +978,7 @@ xfs_attr_leaf_create( XFS_ATTR_FORK);if (error)return (error); -ASSERT (bp !=NULL ); + bp->b_pre_io = xfs_attr_leaf_write_verify; leaf = bp->b_addr;memset ((char *)leaf,0 ,XFS_LBSIZE (dp->i_mount)); hdr = &leaf->hdr;
fs/xfs/xfs_bmap.c +2 -0
@@ -3124,6 +3124,7 @@ xfs_bmap_extents_to_btree(/* * Fill in the child block. */ + abp->b_pre_io = xfs_bmbt_write_verify; ablock =XFS_BUF_TO_BLOCK (abp); ablock->bb_magic =cpu_to_be32 (XFS_BMAP_MAGIC ); ablock->bb_level =0 ;
@@ -3270,6 +3271,7 @@ xfs_bmap_local_to_extents(ASSERT (args.len ==1 ); *firstblock = args.fsbno; bp =xfs_btree_get_bufl (args.mp, tp, args.fsbno,0 ); + bp->b_pre_io = xfs_bmbt_write_verify;memcpy (bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);xfs_trans_log_buf (tp, bp,0 , ifp->if_bytes -1 );xfs_bmap_forkoff_reset (args.mp, ip, whichfork);
fs/xfs/xfs_bmap_btree.c +2 -1
@@ -749,7 +749,7 @@ xfs_bmbt_verify( } } -static void +void xfs_bmbt_write_verify (struct xfs_buf *bp) {
@@ -806,6 +806,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = { .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, .key_diff = xfs_bmbt_key_diff, .read_verify = xfs_bmbt_read_verify, + .write_verify = xfs_bmbt_write_verify, #ifdef DEBUG .keys_inorder = xfs_bmbt_keys_inorder, .recs_inorder = xfs_bmbt_recs_inorder,
fs/xfs/xfs_bmap_btree.h +1 -0
@@ -233,6 +233,7 @@ extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);extern int xfs_bmdr_maxrecs (struct xfs_mount *,int blocklen,int leaf);extern int xfs_bmbt_maxrecs (struct xfs_mount *,int blocklen,int leaf);extern void xfs_bmbt_read_verify (struct xfs_buf *bp); +extern void xfs_bmbt_write_verify (struct xfs_buf *bp);extern struct xfs_btree_cur *xfs_bmbt_init_cursor (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,int );
fs/xfs/xfs_btree.c +1 -0
@@ -996,6 +996,7 @@ xfs_btree_get_buf_block(if (!*bpp)return ENOMEM ; + (*bpp)->b_pre_io = cur->bc_ops->write_verify; *block =XFS_BUF_TO_BLOCK (*bpp);return 0 ; }
fs/xfs/xfs_btree.h +2 -0
@@ -189,6 +189,8 @@ struct xfs_btree_ops { union xfs_btree_key *key);void (*read_verify)(struct xfs_buf *bp); +void (*write_verify)(struct xfs_buf *bp); +#ifdef DEBUG /* check that k1 is lower than k2 */ int (*keys_inorder)(struct xfs_btree_cur *cur,
fs/xfs/xfs_da_btree.c +3 -0
@@ -193,6 +193,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,xfs_trans_log_buf (tp, bp,XFS_DA_LOGRANGE (node, &node->hdr,sizeof (node->hdr))); + bp->b_pre_io = xfs_da_node_write_verify; *bpp = bp;return (0 ); }
@@ -392,6 +393,8 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, }memcpy (node, oldroot, size);xfs_trans_log_buf (tp, bp,0 , size -1 ); + + bp->b_pre_io = blk1->bp->b_pre_io; blk1->bp = bp; blk1->blkno = blkno;
fs/xfs/xfs_dir2_block.c +2 -0
@@ -1010,6 +1010,7 @@ xfs_dir2_leaf_to_block(/* * Start converting it to block form. */ + dbp->b_pre_io = xfs_dir2_block_write_verify; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC ); needlog =1 ; needscan =0 ;
@@ -1139,6 +1140,7 @@ xfs_dir2_sf_to_block(kmem_free (sfp);return error; } + bp->b_pre_io = xfs_dir2_block_write_verify; hdr = bp->b_addr; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC );/*
fs/xfs/xfs_dir2_data.c +5 -6
@@ -185,7 +185,7 @@ __xfs_dir2_data_check(return 0 ; } -void +static void xfs_dir2_data_verify (struct xfs_buf *bp) {
@@ -202,14 +202,14 @@ xfs_dir2_data_verify( } } -static void +void xfs_dir2_data_write_verify (struct xfs_buf *bp) {xfs_dir2_data_verify (bp); } -void +static void xfs_dir2_data_read_verify (struct xfs_buf *bp) {
@@ -482,10 +482,9 @@ xfs_dir2_data_init(*/ error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, blkno),-1 , &bp,XFS_DATA_FORK ); -if (error) { +if (error)return error; - } -ASSERT (bp !=NULL ); + bp->b_pre_io = xfs_dir2_data_write_verify;/* * Initialize the header.
fs/xfs/xfs_dir2_leaf.c +12 -7
@@ -81,7 +81,7 @@ xfs_dir2_leaf1_read_verify(xfs_buf_ioend (bp,0 ); } -static void +void xfs_dir2_leafn_write_verify (struct xfs_buf *bp) {
@@ -198,6 +198,7 @@ xfs_dir2_block_to_leaf(/* * Fix up the block header, make it a data block. */ + dbp->b_pre_io = xfs_dir2_data_write_verify; hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );if (needscan)xfs_dir2_data_freescan (mp, hdr, &needlog);
@@ -1243,15 +1244,14 @@ xfs_dir2_leaf_init(* Get the buffer for the block. */ error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, bno),-1 , &bp, -XFS_DATA_FORK ); -if (error) { +XFS_DATA_FORK ); +if (error)return error; - } -ASSERT (bp !=NULL ); - leaf = bp->b_addr; +/* * Initialize the header. */ + leaf = bp->b_addr; leaf->hdr.info.magic =cpu_to_be16 (magic); leaf->hdr.info.forw =0 ; leaf->hdr.info.back =0 ;
@@ -1264,10 +1264,12 @@ xfs_dir2_leaf_init(* the block. */ if (magic ==XFS_DIR2_LEAF1_MAGIC ) { + bp->b_pre_io = xfs_dir2_leaf1_write_verify; ltp =xfs_dir2_leaf_tail_p (mp, leaf); ltp->bestcount =0 ;xfs_dir2_leaf_log_tail (tp, bp); - } + }else + bp->b_pre_io = xfs_dir2_leafn_write_verify; *bpp = bp;return 0 ; }
@@ -1951,7 +1953,10 @@ xfs_dir2_node_to_leaf(xfs_dir2_leaf_compact (args, lbp); elsexfs_dir2_leaf_log_header (tp ,lbp ); + + lbp->b_pre_io = xfs_dir2_leaf1_write_verify; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC ); +/* * Set up the leaf tail from the freespace block. */
fs/xfs/xfs_dir2_node.c +15 -9
@@ -197,11 +197,12 @@ xfs_dir2_leaf_to_node(/* * Get the buffer for the new freespace block. */ -if ((error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, fdb),-1 , &fbp, -XFS_DATA_FORK ))) { + error =xfs_da_get_buf (tp, dp,xfs_dir2_db_to_da (mp, fdb),-1 , &fbp, +XFS_DATA_FORK ); +if (error)return error; - } -ASSERT (fbp !=NULL ); + fbp->b_pre_io = xfs_dir2_free_write_verify; + free = fbp->b_addr; leaf = lbp->b_addr; ltp =xfs_dir2_leaf_tail_p (mp, leaf);
@@ -223,7 +224,10 @@ xfs_dir2_leaf_to_node( *to =cpu_to_be16 (off); } free->hdr.nused =cpu_to_be32 (n); + + lbp->b_pre_io = xfs_dir2_leafn_write_verify; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC ); +/* * Log everything. */
@@ -632,6 +636,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index = (int )((char *)dep - (char *)curbp->b_addr); state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; + curbp->b_pre_io = xfs_dir2_data_write_verify;if (cmp ==XFS_CMP_EXACT )return XFS_ERROR (EEXIST ); }
@@ -646,6 +651,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index =-1 ; state->extrablk.blkno = curdb; state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; + curbp->b_pre_io = xfs_dir2_data_write_verify; }else {/* If the curbp is not the CI match block, drop it */ if (state->extrablk.bp != curbp)
@@ -1638,12 +1644,12 @@ xfs_dir2_node_addname_int(/* * Get a buffer for the new block. */ -if ((error =xfs_da_get_buf (tp, dp, -xfs_dir2_db_to_da (mp, fbno), --1 , &fbp,XFS_DATA_FORK ))) { + error =xfs_da_get_buf (tp, dp, +xfs_dir2_db_to_da (mp, fbno), +-1 , &fbp,XFS_DATA_FORK ); +if (error)return error; - } -ASSERT (fbp !=NULL ); + fbp->b_pre_io = xfs_dir2_free_write_verify;/* * Initialize the new block to be empty, and remember
fs/xfs/xfs_dir2_priv.h +2 -0
@@ -45,6 +45,7 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,#else #define xfs_dir2_data_check (dp,bp)#endif +extern void xfs_dir2_data_write_verify (struct xfs_buf *bp);extern int __xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp);extern int xfs_dir2_data_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mapped_bno,struct xfs_buf **bpp);
@@ -73,6 +74,7 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp,/* xfs_dir2_leaf.c */ extern void xfs_dir2_leafn_read_verify (struct xfs_buf *bp); +extern void xfs_dir2_leafn_write_verify (struct xfs_buf *bp);extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
fs/xfs/xfs_dquot.c +51 -53
123 lines not on this page · raw message
fs/xfs/xfs_fsops.c +6 -2
@@ -222,6 +222,7 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } + bp->b_pre_io = xfs_agf_write_verify; agf =XFS_BUF_TO_AGF (bp); agf->agf_magicnum =cpu_to_be32 (XFS_AGF_MAGIC );
@@ -259,6 +260,7 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } + bp->b_pre_io = xfs_agfl_write_verify; agfl =XFS_BUF_TO_AGFL (bp);for (bucket =0 ; bucket <XFS_AGFL_SIZE (mp); bucket++)
@@ -279,6 +281,7 @@ xfs_growfs_data_private( error =ENOMEM ; goto error0; } + bp->b_pre_io = xfs_agi_write_verify; agi =XFS_BUF_TO_AGI (bp); agi->agi_magicnum =cpu_to_be32 (XFS_AGI_MAGIC );
@@ -450,9 +453,10 @@ xfs_growfs_data_private( bp =xfs_trans_get_buf (NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)),XFS_FSS_TO_BB (mp,1 ),0 ); -if (bp) +if (bp) {xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); -else + bp->b_pre_io = xfs_sb_write_verify; + }else error =ENOMEM ; }
fs/xfs/xfs_ialloc.c +3 -2
@@ -210,6 +210,7 @@ xfs_ialloc_inode_init(* to log a whole cluster of inodes instead of all the * individual transactions causing a lot of log traffic. */ + fbuf->b_pre_io = xfs_inode_buf_write_verify;xfs_buf_zero (fbuf,0 , ninodes << mp->m_sb.sb_inodelog);for (i =0 ; i < ninodes; i++) {int ioffset = i << mp->m_sb.sb_inodelog;
@@ -1504,14 +1505,14 @@ xfs_agi_verify(xfs_check_agi_unlinked (agi); } -static void +void xfs_agi_write_verify (struct xfs_buf *bp) {xfs_agi_verify (bp); } -void +static void xfs_agi_read_verify (struct xfs_buf *bp) {
fs/xfs/xfs_ialloc.h +3 -1
@@ -147,7 +147,9 @@ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,/* * Get the data from the pointed-to record. */ -extern int xfs_inobt_get_rec (struct xfs_btree_cur *cur, +int xfs_inobt_get_rec (struct xfs_btree_cur *cur,xfs_inobt_rec_incore_t *rec,int *stat); +void xfs_agi_write_verify (struct xfs_buf *bp); +#endif /* __XFS_IALLOC_H__ */
fs/xfs/xfs_ialloc_btree.c +1 -0
@@ -271,6 +271,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = { .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, .key_diff = xfs_inobt_key_diff, .read_verify = xfs_inobt_read_verify, + .write_verify = xfs_inobt_write_verify, #ifdef DEBUG .keys_inorder = xfs_inobt_keys_inorder, .recs_inorder = xfs_inobt_recs_inorder,
fs/xfs/xfs_inode.c +13 -1
@@ -420,7 +420,7 @@ xfs_inode_buf_verify(xfs_inobp_check (mp, bp); } -static void +void xfs_inode_buf_write_verify (struct xfs_buf *bp) {
@@ -1782,6 +1782,18 @@ xfs_ifree_cluster(if (!bp)return ENOMEM ; + +/* +* This buffer may not have been correctly initialised as we +* didn't read it from disk. That's not important because we are +* only using to mark the buffer as stale in the log, and to +* attach stale cached inodes on it. That means it will never be +* dispatched for IO. If it is, we want to know about it, and we +* want it to fail. We can acheive this by adding a write +* verifier to the buffer. +*/ + bp->b_pre_io = xfs_inode_buf_write_verify; +/* * Walk the inodes already attached to the buffer and mark them * stale. These will all have the flush locks held, so an
fs/xfs/xfs_inode.h +1 -0
@@ -555,6 +555,7 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,int xfs_iread (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,uint );void xfs_inode_buf_read_verify (struct xfs_buf *); +void xfs_inode_buf_write_verify (struct xfs_buf *);void xfs_dinode_to_disk (struct xfs_dinode *,struct xfs_icdinode *);void xfs_idestroy_fork (struct xfs_inode *,int );
fs/xfs/xfs_mount.c +1 -1
@@ -631,7 +631,7 @@ xfs_sb_verify(xfs_buf_ioerror (bp, error); } -static void +void xfs_sb_write_verify (struct xfs_buf *bp) {
fs/xfs/xfs_mount.h +1 -0
@@ -386,6 +386,7 @@ extern void xfs_set_low_space_thresholds(struct xfs_mount *);#endif /* __KERNEL__ */ extern void xfs_sb_read_verify (struct xfs_buf *); +extern void xfs_sb_write_verify (struct xfs_buf *bp);extern void xfs_mod_sb (struct xfs_trans *,__int64_t );extern int xfs_initialize_perag (struct xfs_mount *,xfs_agnumber_t ,xfs_agnumber_t *);
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 30/32 xfs: convert buffer verifiers to an ops structure.
In reply to Dave ChinnerFrom: Dave Chinner <[email protected]>
To separate the verifiers from iodone functions and associate read and write verifiers at the same time, introduce a buffer verifier operations structure to the xfs_buf.
This avoids the need for assigning the write verifier, clearing the iodone function and re-running ioend processing in the read verifier, and gets rid of the nasty "b_pre_io" name for the write verifier function pointer. If we ever need to, it will also be easier to add further content specific callbacks to a buffer with an ops structure in place.
We also avoid needing to export verifier functions, instead we can simply export the ops structures for those that are needed outside the function they are defined in.
This patch also fixes a directory block readahead verifier issue it exposed.
This patch also adds ops callbacks to the inode/alloc btree blocks initialised by growfs. These will need more work before they will work with CRCs.
--- fs/xfs/xfs_ag.h | 4 +++ fs/xfs/xfs_alloc.c | 28 +++++++++++--------- fs/xfs/xfs_alloc.h | 4 +-- fs/xfs/xfs_alloc_btree.c | 18 +++++++------ fs/xfs/xfs_alloc_btree.h | 2 ++ fs/xfs/xfs_attr_leaf.c | 19 +++++++------- fs/xfs/xfs_attr_leaf.h | 3 ++- fs/xfs/xfs_bmap.c | 22 ++++++++-------- fs/xfs/xfs_bmap_btree.c | 20 +++++++------- fs/xfs/xfs_bmap_btree.h | 3 +-- fs/xfs/xfs_btree.c | 26 +++++++++---------- fs/xfs/xfs_btree.h | 9 +++---- fs/xfs/xfs_buf.c | 63 ++++++++++++++++++++++++++------------------- fs/xfs/xfs_buf.h | 24 ++++++++++------- fs/xfs/xfs_da_btree.c | 40 +++++++++++++++++----------- fs/xfs/xfs_da_btree.h | 4 +-- fs/xfs/xfs_dir2_block.c | 20 +++++++------- fs/xfs/xfs_dir2_data.c | 52 ++++++++++++++++++++++++++++++------- fs/xfs/xfs_dir2_leaf.c | 36 ++++++++++++++------------ fs/xfs/xfs_dir2_node.c | 26 ++++++++++--------- fs/xfs/xfs_dir2_priv.h | 10 ++++--- fs/xfs/xfs_dquot.c | 16 +++++++----- fs/xfs/xfs_fsops.c | 29 ++++++++++++--------- fs/xfs/xfs_ialloc.c | 18 +++++++------ fs/xfs/xfs_ialloc.h | 2 +- fs/xfs/xfs_ialloc_btree.c | 17 ++++++------ fs/xfs/xfs_ialloc_btree.h | 2 ++ fs/xfs/xfs_inode.c | 22 +++++++++------- fs/xfs/xfs_inode.h | 3 +-- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_mount.c | 35 +++++++++++++++---------- fs/xfs/xfs_mount.h | 4 +-- fs/xfs/xfs_trans.h | 6 ++--- fs/xfs/xfs_trans_buf.c | 8 +++--- 35 files changed, 353 insertions(+), 246 deletions(-)
fs/xfs/xfs_ag.h +4 -0
@@ -108,6 +108,8 @@ typedef struct xfs_agf {extern int xfs_read_agf (struct xfs_mount *mp,struct xfs_trans *tp,xfs_agnumber_t agno,int flags,struct xfs_buf **bpp); +extern const struct xfs_buf_ops xfs_agf_buf_ops; +/* * Size of the unlinked inode hash table in the agi. */
@@ -161,6 +163,8 @@ typedef struct xfs_agi {extern int xfs_read_agi (struct xfs_mount *mp,struct xfs_trans *tp,xfs_agnumber_t agno,struct xfs_buf **bpp); +extern const struct xfs_buf_ops xfs_agi_buf_ops; +/* * The third a.g. block contains the a.g. freelist, an array * of block pointers to blocks owned by the allocation btree code.
fs/xfs/xfs_alloc.c +16 -12
@@ -465,7 +465,7 @@ xfs_agfl_verify(#endif } -void +static void xfs_agfl_write_verify (struct xfs_buf *bp) {
@@ -477,11 +477,13 @@ xfs_agfl_read_verify( struct xfs_buf *bp) {xfs_agfl_verify (bp); - bp->b_pre_io = xfs_agfl_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_agfl_buf_ops = { + .verify_read = xfs_agfl_read_verify, + .verify_write = xfs_agfl_write_verify, +}; +/* * Read in the allocation group free block array. */
@@ -499,7 +501,7 @@ xfs_alloc_read_agfl( error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGFL_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , &bp, xfs_agfl_read_verify); +XFS_FSS_TO_BB (mp,1 ),0 , &bp, &xfs_agfl_buf_ops);if (error)return error;ASSERT (!xfs_buf_geterror (bp));
@@ -2182,23 +2184,25 @@ xfs_agf_verify( } } -void -xfs_agf_write_verify ( +static void +xfs_agf_read_verify (struct xfs_buf *bp) {xfs_agf_verify (bp); }static void -xfs_agf_read_verify ( +xfs_agf_write_verify (struct xfs_buf *bp) {xfs_agf_verify (bp); - bp->b_pre_io = xfs_agf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_agf_buf_ops = { + .verify_read = xfs_agf_read_verify, + .verify_write = xfs_agf_write_verify, +}; +/* * Read in the allocation group header (free/alloc section). */
@@ -2216,7 +2220,7 @@ xfs_read_agf( error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ), flags, bpp, xfs_agf_read_verify); +XFS_FSS_TO_BB (mp,1 ), flags, bpp, &xfs_agf_buf_ops);if (error)return error;if (!*bpp)
fs/xfs/xfs_alloc.h +2 -2
@@ -238,7 +238,7 @@ xfs_alloc_freespace_map(u64 start, u64 length); -void xfs_agf_write_verify (struct xfs_buf *bp); -void xfs_agfl_write_verify (struct xfs_buf *bp); +extern const struct xfs_buf_ops xfs_agf_buf_ops; +extern const struct xfs_buf_ops xfs_agfl_buf_ops;#endif /* __XFS_ALLOC_H__ */
fs/xfs/xfs_alloc_btree.c +10 -8
@@ -329,22 +329,25 @@ xfs_allocbt_verify( }static void -xfs_allocbt_write_verify ( +xfs_allocbt_read_verify (struct xfs_buf *bp) {xfs_allocbt_verify (bp); } -void -xfs_allocbt_read_verify ( +static void +xfs_allocbt_write_verify (struct xfs_buf *bp) {xfs_allocbt_verify (bp); - bp->b_pre_io = xfs_allocbt_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_allocbt_buf_ops = { + .verify_read = xfs_allocbt_read_verify, + .verify_write = xfs_allocbt_write_verify, +}; + +#ifdef DEBUG STATIC int xfs_allocbt_keys_inorder(
@@ -400,8 +403,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = { .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_allocbt_key_diff, - .read_verify = xfs_allocbt_read_verify, - .write_verify = xfs_allocbt_write_verify, + .buf_ops = &xfs_allocbt_buf_ops, #ifdef DEBUG .keys_inorder = xfs_allocbt_keys_inorder, .recs_inorder = xfs_allocbt_recs_inorder,
fs/xfs/xfs_alloc_btree.h +2 -0
@@ -93,4 +93,6 @@ extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *, xfs_agnumber_t, xfs_btnum_t);extern int xfs_allocbt_maxrecs (struct xfs_mount *,int ,int ); +extern const struct xfs_buf_ops xfs_allocbt_buf_ops; +#endif /* __XFS_ALLOC_BTREE_H__ */
fs/xfs/xfs_attr_leaf.c +10 -9
@@ -104,22 +104,23 @@ xfs_attr_leaf_verify( }static void -xfs_attr_leaf_write_verify ( +xfs_attr_leaf_read_verify (struct xfs_buf *bp) {xfs_attr_leaf_verify (bp); } -void -xfs_attr_leaf_read_verify ( +static void +xfs_attr_leaf_write_verify (struct xfs_buf *bp) {xfs_attr_leaf_verify (bp); - bp->b_pre_io = xfs_attr_leaf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_attr_leaf_buf_ops = { + .verify_read = xfs_attr_leaf_read_verify, + .verify_write = xfs_attr_leaf_write_verify, +};int xfs_attr_leaf_read(
@@ -130,7 +131,7 @@ xfs_attr_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, -XFS_ATTR_FORK , xfs_attr_leaf_read_verify); +XFS_ATTR_FORK , &xfs_attr_leaf_buf_ops); }/*========================================================================
@@ -924,7 +925,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) XFS_ATTR_FORK);if (error) goto out; - bp2->b_pre_io = bp1->b_pre_io; + bp2->b_ops = bp1->b_ops;memcpy (bp2->b_addr, bp1->b_addr,XFS_LBSIZE (dp->i_mount)); bp1 =NULL ;xfs_trans_log_buf (args->trans, bp2,0 ,XFS_LBSIZE (dp->i_mount) -1 );
@@ -978,7 +979,7 @@ xfs_attr_leaf_create( XFS_ATTR_FORK);if (error)return (error); - bp->b_pre_io = xfs_attr_leaf_write_verify; + bp->b_ops = &xfs_attr_leaf_buf_ops; leaf = bp->b_addr;memset ((char *)leaf,0 ,XFS_LBSIZE (dp->i_mount)); hdr = &leaf->hdr;
fs/xfs/xfs_attr_leaf.h +2 -1
@@ -264,6 +264,7 @@ int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,int xfs_attr_leaf_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); -void xfs_attr_leaf_read_verify (struct xfs_buf *bp); + +extern const struct xfs_buf_ops xfs_attr_leaf_buf_ops;#endif /* __XFS_ATTR_LEAF_H__ */
fs/xfs/xfs_bmap.c +11 -11
@@ -2663,7 +2663,7 @@ xfs_bmap_btree_to_extents(return error;#endif error =xfs_btree_read_bufl (mp, tp, cbno,0 , &cbp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; cblock =XFS_BUF_TO_BLOCK (cbp);
@@ -3124,7 +3124,7 @@ xfs_bmap_extents_to_btree(/* * Fill in the child block. */ - abp->b_pre_io = xfs_bmbt_write_verify; + abp->b_ops = &xfs_bmbt_buf_ops; ablock =XFS_BUF_TO_BLOCK (abp); ablock->bb_magic =cpu_to_be32 (XFS_BMAP_MAGIC ); ablock->bb_level =0 ;
@@ -3271,7 +3271,7 @@ xfs_bmap_local_to_extents(ASSERT (args.len ==1 ); *firstblock = args.fsbno; bp =xfs_btree_get_bufl (args.mp, tp, args.fsbno,0 ); - bp->b_pre_io = xfs_bmbt_write_verify; + bp->b_ops = &xfs_bmbt_buf_ops;memcpy (bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);xfs_trans_log_buf (tp, bp,0 , ifp->if_bytes -1 );xfs_bmap_forkoff_reset (args.mp, ip, whichfork);
@@ -4082,7 +4082,7 @@ xfs_bmap_read_extents(*/ while (level-- >0 ) { error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp, -XFS_BMAP_BTREE_REF , xfs_bmbt_read_verify); +XFS_BMAP_BTREE_REF , &xfs_bmbt_buf_ops);if (error)return error; block =XFS_BUF_TO_BLOCK (bp);
@@ -4129,7 +4129,7 @@ xfs_bmap_read_extents( nextbno =be64_to_cpu (block->bb_u.l.bb_rightsib);if (nextbno !=NULLFSBLOCK )xfs_btree_reada_bufl (mp, nextbno,1 , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);/* * Copy records into the extent records. */
@@ -4162,7 +4162,7 @@ xfs_bmap_read_extents(if (bno ==NULLFSBLOCK )break ; error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp, -XFS_BMAP_BTREE_REF , xfs_bmbt_read_verify); +XFS_BMAP_BTREE_REF , &xfs_bmbt_buf_ops);if (error)return error; block =XFS_BUF_TO_BLOCK (bp);
@@ -5880,7 +5880,7 @@ xfs_bmap_check_leaf_extents( bp_release =1 ; error =xfs_btree_read_bufl (mp,NULL , bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error) goto error_norelse; }
@@ -5966,7 +5966,7 @@ xfs_bmap_check_leaf_extents( bp_release =1 ; error =xfs_btree_read_bufl (mp,NULL , bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error) goto error_norelse; }
@@ -6061,7 +6061,7 @@ xfs_bmap_count_tree(int numrecs; error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; *count +=1 ;
@@ -6073,7 +6073,7 @@ xfs_bmap_count_tree(while (nextbno !=NULLFSBLOCK ) { error =xfs_btree_read_bufl (mp, tp, nextbno,0 , &nbp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; *count +=1 ;
@@ -6105,7 +6105,7 @@ xfs_bmap_count_tree( bno = nextbno; error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; *count +=1 ;
fs/xfs/xfs_bmap_btree.c +11 -9
@@ -749,23 +749,26 @@ xfs_bmbt_verify( } } -void -xfs_bmbt_write_verify ( +static void +xfs_bmbt_read_verify (struct xfs_buf *bp) {xfs_bmbt_verify (bp); } -void -xfs_bmbt_read_verify ( +static void +xfs_bmbt_write_verify (struct xfs_buf *bp) {xfs_bmbt_verify (bp); - bp->b_pre_io = xfs_bmbt_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_bmbt_buf_ops = { + .verify_read = xfs_bmbt_read_verify, + .verify_write = xfs_bmbt_write_verify, +}; + +#ifdef DEBUG STATIC int xfs_bmbt_keys_inorder(
@@ -805,8 +808,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = { .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, .key_diff = xfs_bmbt_key_diff, - .read_verify = xfs_bmbt_read_verify, - .write_verify = xfs_bmbt_write_verify, + .buf_ops = &xfs_bmbt_buf_ops, #ifdef DEBUG .keys_inorder = xfs_bmbt_keys_inorder, .recs_inorder = xfs_bmbt_recs_inorder,
fs/xfs/xfs_bmap_btree.h +1 -2
@@ -232,11 +232,10 @@ extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,extern int xfs_bmbt_get_maxrecs (struct xfs_btree_cur *,int level);extern int xfs_bmdr_maxrecs (struct xfs_mount *,int blocklen,int leaf);extern int xfs_bmbt_maxrecs (struct xfs_mount *,int blocklen,int leaf); -extern void xfs_bmbt_read_verify (struct xfs_buf *bp); -extern void xfs_bmbt_write_verify (struct xfs_buf *bp);extern struct xfs_btree_cur *xfs_bmbt_init_cursor (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,int ); +extern const struct xfs_buf_ops xfs_bmbt_buf_ops;#endif /* __XFS_BMAP_BTREE_H__ */
fs/xfs/xfs_btree.c +13 -13
@@ -271,7 +271,7 @@ xfs_btree_dup_cursor( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp,XFS_BUF_ADDR (bp), mp->m_bsize,0 , &bp, - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops);if (error) {xfs_btree_del_cursor (new, error); *ncur =NULL ;
@@ -621,7 +621,7 @@ xfs_btree_read_bufl(uint lock,/* lock flags for read_buf */ struct xfs_buf **bpp, /* buffer for fsbno */ int refval, /* ref count value for buffer */ - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { struct xfs_buf *bp; /* return value */xfs_daddr_t d;/* real disk block address */
@@ -630,7 +630,7 @@ xfs_btree_read_bufl(ASSERT (fsbno !=NULLFSBLOCK ); d =XFS_FSB_TO_DADDR (mp, fsbno); error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, d, - mp->m_bsize, lock, &bp, verify); + mp->m_bsize, lock, &bp, ops);if (error)return error;ASSERT (!xfs_buf_geterror (bp));
@@ -650,13 +650,13 @@ xfs_btree_reada_bufl(struct xfs_mount *mp,/* file system mount point */ xfs_fsblock_t fsbno, /* file system block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { xfs_daddr_t d;ASSERT (fsbno !=NULLFSBLOCK ); d =XFS_FSB_TO_DADDR (mp, fsbno); -xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, verify); +xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, ops); }/*
@@ -670,14 +670,14 @@ xfs_btree_reada_bufs(xfs_agnumber_t agno,/* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { xfs_daddr_t d;ASSERT (agno !=NULLAGNUMBER );ASSERT (agbno !=NULLAGBLOCK ); d =XFS_AGB_TO_DADDR (mp, agno, agbno); -xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, verify); +xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, ops); }STATIC int
@@ -692,13 +692,13 @@ xfs_btree_readahead_lblock(if ((lr &XFS_BTCUR_LEFTRA ) && left !=NULLDFSBNO ) {xfs_btree_reada_bufl (cur->bc_mp, left,1 , - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops); rval++; }if ((lr &XFS_BTCUR_RIGHTRA ) && right !=NULLDFSBNO ) {xfs_btree_reada_bufl (cur->bc_mp, right,1 , - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops); rval++; }
@@ -718,13 +718,13 @@ xfs_btree_readahead_sblock(if ((lr &XFS_BTCUR_LEFTRA ) && left !=NULLAGBLOCK ) {xfs_btree_reada_bufs (cur->bc_mp, cur->bc_private.a.agno, - left,1 , cur->bc_ops->read_verify); + left,1 , cur->bc_ops->buf_ops); rval++; }if ((lr &XFS_BTCUR_RIGHTRA ) && right !=NULLAGBLOCK ) {xfs_btree_reada_bufs (cur->bc_mp, cur->bc_private.a.agno, - right,1 , cur->bc_ops->read_verify); + right,1 , cur->bc_ops->buf_ops); rval++; }
@@ -996,7 +996,7 @@ xfs_btree_get_buf_block(if (!*bpp)return ENOMEM ; - (*bpp)->b_pre_io = cur->bc_ops->write_verify; + (*bpp)->b_ops = cur->bc_ops->buf_ops; *block =XFS_BUF_TO_BLOCK (*bpp);return 0 ; }
@@ -1024,7 +1024,7 @@ xfs_btree_read_buf_block( d =xfs_btree_ptr_to_daddr (cur, ptr); error =xfs_trans_read_buf (mp, cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, flags, bpp, - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops);if (error)return error;
fs/xfs/xfs_btree.h +4 -5
@@ -188,8 +188,7 @@ struct xfs_btree_ops {__int64_t (*key_diff)(struct xfs_btree_cur *cur,union xfs_btree_key *key); -void (*read_verify)(struct xfs_buf *bp); -void (*write_verify)(struct xfs_buf *bp); +const struct xfs_buf_ops *buf_ops;#ifdef DEBUG /* check that k1 is lower than k2 */
@@ -359,7 +358,7 @@ xfs_btree_read_bufl(uint lock,/* lock flags for read_buf */ struct xfs_buf **bpp, /* buffer for fsbno */ int refval, /* ref count value for buffer */ - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);/* * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -370,7 +369,7 @@ xfs_btree_reada_bufl(struct xfs_mount *mp,/* file system mount point */ xfs_fsblock_t fsbno, /* file system block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);/* * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -382,7 +381,7 @@ xfs_btree_reada_bufs(xfs_agnumber_t agno,/* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);/* * Initialise a new btree block header
fs/xfs/xfs_buf.c +37 -26
144 lines not on this page · raw message
fs/xfs/xfs_buf.h +14 -10
@@ -111,6 +111,11 @@ struct xfs_buf_map {#define DEFINE_SINGLE_BUF_MAP (map, blkno, numblk) \ struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; +struct xfs_buf_ops { +void (*verify_read)(struct xfs_buf *); +void (*verify_write)(struct xfs_buf *); +}; + typedef struct xfs_buf { /* * first cacheline holds all the fields needed for an uncontended cache
@@ -154,9 +159,7 @@ typedef struct xfs_buf {unsigned int b_page_count;/* size of page array */ unsigned int b_offset;/* page offset in first page */ unsigned short b_error;/* error code on I/O */ - -void (*b_pre_io)(struct xfs_buf *); -/* pre-io callback function */ +const struct xfs_buf_ops *b_ops;#ifdef XFS_BUF_LOCK_TRACKING int b_last_holder;
@@ -199,10 +202,11 @@ struct xfs_buf *xfs_buf_get_map(struct xfs_buftarg *target, xfs_buf_flags_t flags);struct xfs_buf *xfs_buf_read_map (struct xfs_buftarg *target,struct xfs_buf_map *map,int nmaps, -xfs_buf_flags_t flags,xfs_buf_iodone_t verify); +xfs_buf_flags_t flags, +const struct xfs_buf_ops *ops);void xfs_buf_readahead_map (struct xfs_buftarg *target,struct xfs_buf_map *map,int nmaps, -xfs_buf_iodone_t verify); +const struct xfs_buf_ops *ops);static inline struct xfs_buf * xfs_buf_get(
@@ -221,10 +225,10 @@ xfs_buf_read(xfs_daddr_t blkno, size_t numblks, xfs_buf_flags_t flags, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) {DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks ); -return xfs_buf_read_map (target, &map,1 , flags, verify); +return xfs_buf_read_map (target, &map,1 , flags, ops); } static inline void
@@ -232,10 +236,10 @@ xfs_buf_readahead(struct xfs_buftarg *target, xfs_daddr_t blkno, size_t numblks, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) {DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks ); -return xfs_buf_readahead_map (target, &map,1 , verify); +return xfs_buf_readahead_map (target, &map,1 , ops); }struct xfs_buf *xfs_buf_get_empty (struct xfs_buftarg *target,size_t numblks);
@@ -246,7 +250,7 @@ struct xfs_buf *xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks, int flags);struct xfs_buf *xfs_buf_read_uncached (struct xfs_buftarg *target,xfs_daddr_t daddr,size_t numblks,int flags, -xfs_buf_iodone_t verify); +const struct xfs_buf_ops *ops);void xfs_buf_hold (struct xfs_buf *bp);/* Releasing Buffers */
fs/xfs/xfs_da_btree.c +25 -15
@@ -117,6 +117,12 @@ xfs_da_node_write_verify(xfs_da_node_verify (bp); } +/* +* leaf/node format detection on trees is sketchy, so a node read can be done on +* leaf level blocks when detection identifies the tree as a node format tree +* incorrectly. In this case, we need to swap the verifier to match the correct +* format of the block being read. +*/ static void xfs_da_node_read_verify (struct xfs_buf *bp)
@@ -129,10 +135,12 @@ xfs_da_node_read_verify(xfs_da_node_verify (bp);break ;case XFS_ATTR_LEAF_MAGIC : -xfs_attr_leaf_read_verify (bp); + bp->b_ops = &xfs_attr_leaf_buf_ops; + bp->b_ops->verify_read (bp);return ;case XFS_DIR2_LEAFN_MAGIC : -xfs_dir2_leafn_read_verify (bp); + bp->b_ops = &xfs_dir2_leafn_buf_ops; + bp->b_ops->verify_read (bp);return ;default : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
@@ -140,12 +148,14 @@ xfs_da_node_read_verify(xfs_buf_ioerror (bp,EFSCORRUPTED );break ; } - - bp->b_pre_io = xfs_da_node_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_da_node_buf_ops = { + .verify_read = xfs_da_node_read_verify, + .verify_write = xfs_da_node_write_verify, +}; + + int xfs_da_node_read( struct xfs_trans *tp,
@@ -156,7 +166,7 @@ xfs_da_node_read( int which_fork) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, - which_fork, xfs_da_node_read_verify); + which_fork, &xfs_da_node_buf_ops); }/*========================================================================
@@ -193,7 +203,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,xfs_trans_log_buf (tp, bp,XFS_DA_LOGRANGE (node, &node->hdr,sizeof (node->hdr))); - bp->b_pre_io = xfs_da_node_write_verify; + bp->b_ops = &xfs_da_node_buf_ops; *bpp = bp;return (0 ); }
@@ -394,7 +404,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,memcpy (node, oldroot, size);xfs_trans_log_buf (tp, bp,0 , size -1 ); - bp->b_pre_io = blk1->bp->b_pre_io; + bp->b_ops = blk1->bp->b_ops; blk1->bp = bp; blk1->blkno = blkno;
@@ -828,11 +838,11 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)/* * This could be copying a leaf back into the root block in the case of * there only being a single leaf block left in the tree. Hence we have -* to update the pre_io pointer as well to match the buffer type change +* to update the b_ops pointer as well to match the buffer type change * that could occur. */ memcpy (root_blk->bp->b_addr, bp->b_addr, state->blocksize); - root_blk->bp->b_pre_io = bp->b_pre_io; + root_blk->bp->b_ops = bp->b_ops;xfs_trans_log_buf (args->trans, root_blk->bp,0 , state->blocksize -1 ); error =xfs_da_shrink_inode (args, child, bp);return (error);
@@ -2223,7 +2233,7 @@ xfs_da_read_buf(xfs_daddr_t mappedbno, struct xfs_buf **bpp, int whichfork, - xfs_buf_iodone_t verifier) + const struct xfs_buf_ops *ops) { struct xfs_buf *bp;struct xfs_buf_map map;
@@ -2245,7 +2255,7 @@ xfs_da_read_buf( error =xfs_trans_read_buf_map (dp->i_mount, trans, dp->i_mount->m_ddev_targp, - mapp, nmap,0 , &bp, verifier); + mapp, nmap,0 , &bp, ops);if (error) goto out_free;
@@ -2303,7 +2313,7 @@ xfs_da_reada_buf(xfs_dablk_t bno, xfs_daddr_t mappedbno, int whichfork, - xfs_buf_iodone_t verifier) + const struct xfs_buf_ops *ops) { struct xfs_buf_map map;struct xfs_buf_map *mapp;
@@ -2322,7 +2332,7 @@ xfs_da_reada_buf( } mappedbno = mapp[0 ].bm_bn; -xfs_buf_readahead_map (dp->i_mount->m_ddev_targp, mapp, nmap,NULL ); +xfs_buf_readahead_map (dp->i_mount->m_ddev_targp, mapp, nmap, ops); out_free:if (mapp != &map)
fs/xfs/xfs_da_btree.h +2 -2
@@ -229,10 +229,10 @@ int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp,int xfs_da_read_buf (struct xfs_trans *trans,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mappedbno,struct xfs_buf **bpp,int whichfork, -xfs_buf_iodone_t verifier); +const struct xfs_buf_ops *ops);xfs_daddr_t xfs_da_reada_buf (struct xfs_trans *trans,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mapped_bno, -int whichfork,xfs_buf_iodone_t verifier); +int whichfork,const struct xfs_buf_ops *ops);int xfs_da_shrink_inode (xfs_da_args_t *args,xfs_dablk_t dead_blkno,struct xfs_buf *dead_buf);
fs/xfs/xfs_dir2_block.c +11 -9
@@ -74,22 +74,24 @@ xfs_dir2_block_verify( }static void -xfs_dir2_block_write_verify ( +xfs_dir2_block_read_verify (struct xfs_buf *bp) {xfs_dir2_block_verify (bp); } -void -xfs_dir2_block_read_verify ( +static void +xfs_dir2_block_write_verify (struct xfs_buf *bp) {xfs_dir2_block_verify (bp); - bp->b_pre_io = xfs_dir2_block_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_dir2_block_buf_ops = { + .verify_read = xfs_dir2_block_read_verify, + .verify_write = xfs_dir2_block_write_verify, +}; + static int xfs_dir2_block_read( struct xfs_trans *tp,
@@ -99,7 +101,7 @@ xfs_dir2_block_read(struct xfs_mount *mp = dp->i_mount;return xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , bpp, -XFS_DATA_FORK , xfs_dir2_block_read_verify); +XFS_DATA_FORK , &xfs_dir2_block_buf_ops); } static void
@@ -1010,7 +1012,7 @@ xfs_dir2_leaf_to_block(/* * Start converting it to block form. */ - dbp->b_pre_io = xfs_dir2_block_write_verify; + dbp->b_ops = &xfs_dir2_block_buf_ops; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC ); needlog =1 ; needscan =0 ;
@@ -1140,7 +1142,7 @@ xfs_dir2_sf_to_block(kmem_free (sfp);return error; } - bp->b_pre_io = xfs_dir2_block_write_verify; + bp->b_ops = &xfs_dir2_block_buf_ops; hdr = bp->b_addr; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC );/*
fs/xfs/xfs_dir2_data.c +43 -9
87 lines not on this page · raw message
fs/xfs/xfs_dir2_leaf.c +20 -16
@@ -65,39 +65,43 @@ xfs_dir2_leaf_verify( }static void -xfs_dir2_leaf1_write_verify ( +xfs_dir2_leaf1_read_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); }static void -xfs_dir2_leaf1_read_verify ( +xfs_dir2_leaf1_write_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); - bp->b_pre_io = xfs_dir2_leaf1_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); }void -xfs_dir2_leafn_write_verify ( +xfs_dir2_leafn_read_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); }void -xfs_dir2_leafn_read_verify ( +xfs_dir2_leafn_write_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); - bp->b_pre_io = xfs_dir2_leafn_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +static const struct xfs_buf_ops xfs_dir2_leaf1_buf_ops = { + .verify_read = xfs_dir2_leaf1_read_verify, + .verify_write = xfs_dir2_leaf1_write_verify, +}; + +const struct xfs_buf_ops xfs_dir2_leafn_buf_ops = { + .verify_read = xfs_dir2_leafn_read_verify, + .verify_write = xfs_dir2_leafn_write_verify, +}; + static int xfs_dir2_leaf_read( struct xfs_trans *tp,
@@ -107,7 +111,7 @@ xfs_dir2_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leaf1_read_verify); +XFS_DATA_FORK , &xfs_dir2_leaf1_buf_ops); }int
@@ -119,7 +123,7 @@ xfs_dir2_leafn_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leafn_read_verify); +XFS_DATA_FORK , &xfs_dir2_leafn_buf_ops); }/*
@@ -198,7 +202,7 @@ xfs_dir2_block_to_leaf(/* * Fix up the block header, make it a data block. */ - dbp->b_pre_io = xfs_dir2_data_write_verify; + dbp->b_ops = &xfs_dir2_data_buf_ops; hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );if (needscan)xfs_dir2_data_freescan (mp, hdr, &needlog);
@@ -1264,12 +1268,12 @@ xfs_dir2_leaf_init(* the block. */ if (magic ==XFS_DIR2_LEAF1_MAGIC ) { - bp->b_pre_io = xfs_dir2_leaf1_write_verify; + bp->b_ops = &xfs_dir2_leaf1_buf_ops; ltp =xfs_dir2_leaf_tail_p (mp, leaf); ltp->bestcount =0 ;xfs_dir2_leaf_log_tail (tp, bp); }else - bp->b_pre_io = xfs_dir2_leafn_write_verify; + bp->b_ops = &xfs_dir2_leafn_buf_ops; *bpp = bp;return 0 ; }
@@ -1954,7 +1958,7 @@ xfs_dir2_node_to_leaf(else xfs_dir2_leaf_log_header (tp, lbp); - lbp->b_pre_io = xfs_dir2_leaf1_write_verify; + lbp->b_ops = &xfs_dir2_leaf1_buf_ops; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC );/*
fs/xfs/xfs_dir2_node.c +14 -12
@@ -72,22 +72,24 @@ xfs_dir2_free_verify( }static void -xfs_dir2_free_write_verify ( +xfs_dir2_free_read_verify (struct xfs_buf *bp) {xfs_dir2_free_verify (bp); } -void -xfs_dir2_free_read_verify ( +static void +xfs_dir2_free_write_verify (struct xfs_buf *bp) {xfs_dir2_free_verify (bp); - bp->b_pre_io = xfs_dir2_free_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +static const struct xfs_buf_ops xfs_dir2_free_buf_ops = { + .verify_read = xfs_dir2_free_read_verify, + .verify_write = xfs_dir2_free_write_verify, +}; +static int __xfs_dir2_free_read(
@@ -98,7 +100,7 @@ __xfs_dir2_free_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_free_read_verify); +XFS_DATA_FORK , &xfs_dir2_free_buf_ops); }int
@@ -201,7 +203,7 @@ xfs_dir2_leaf_to_node( XFS_DATA_FORK);if (error)return error; - fbp->b_pre_io = xfs_dir2_free_write_verify; + fbp->b_ops = &xfs_dir2_free_buf_ops; free = fbp->b_addr; leaf = lbp->b_addr;
@@ -225,7 +227,7 @@ xfs_dir2_leaf_to_node( } free->hdr.nused =cpu_to_be32 (n); - lbp->b_pre_io = xfs_dir2_leafn_write_verify; + lbp->b_ops = &xfs_dir2_leafn_buf_ops; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC );/*
@@ -636,7 +638,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index = (int )((char *)dep - (char *)curbp->b_addr); state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; - curbp->b_pre_io = xfs_dir2_data_write_verify; + curbp->b_ops = &xfs_dir2_data_buf_ops;if (cmp ==XFS_CMP_EXACT )return XFS_ERROR (EEXIST ); }
@@ -651,7 +653,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index =-1 ; state->extrablk.blkno = curdb; state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; - curbp->b_pre_io = xfs_dir2_data_write_verify; + curbp->b_ops = &xfs_dir2_data_buf_ops; }else {/* If the curbp is not the CI match block, drop it */ if (state->extrablk.bp != curbp)
@@ -1649,7 +1651,7 @@ xfs_dir2_node_addname_int( -1, &fbp, XFS_DATA_FORK);if (error)return error; - fbp->b_pre_io = xfs_dir2_free_write_verify; + fbp->b_ops = &xfs_dir2_free_buf_ops;/* * Initialize the new block to be empty, and remember
fs/xfs/xfs_dir2_priv.h +7 -3
@@ -30,6 +30,8 @@ extern int xfs_dir_cilookup_result(struct xfs_da_args *args, const unsigned char *name, int len);/* xfs_dir2_block.c */ +extern const struct xfs_buf_ops xfs_dir2_block_buf_ops; +extern int xfs_dir2_block_addname (struct xfs_da_args *args);extern int xfs_dir2_block_getdents (struct xfs_inode *dp,void *dirent,xfs_off_t *offset,filldir_t filldir);
@@ -45,7 +47,9 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,#else #define xfs_dir2_data_check (dp,bp)#endif -extern void xfs_dir2_data_write_verify (struct xfs_buf *bp); + +extern const struct xfs_buf_ops xfs_dir2_data_buf_ops; +extern int __xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp);extern int xfs_dir2_data_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mapped_bno,struct xfs_buf **bpp);
@@ -73,8 +77,8 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);/* xfs_dir2_leaf.c */ -extern void xfs_dir2_leafn_read_verify (struct xfs_buf *bp); -extern void xfs_dir2_leafn_write_verify (struct xfs_buf *bp); +extern const struct xfs_buf_ops xfs_dir2_leafn_buf_ops; +extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
fs/xfs/xfs_dquot.c +9 -7
@@ -285,22 +285,24 @@ xfs_dquot_buf_verify( }static void -xfs_dquot_buf_write_verify ( +xfs_dquot_buf_read_verify (struct xfs_buf *bp) {xfs_dquot_buf_verify (bp); }static void -xfs_dquot_buf_read_verify ( +xfs_dquot_buf_write_verify (struct xfs_buf *bp) {xfs_dquot_buf_verify (bp); - bp->b_pre_io = xfs_dquot_buf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +static const struct xfs_buf_ops xfs_dquot_buf_ops = { + .verify_read = xfs_dquot_buf_read_verify, + .verify_write = xfs_dquot_buf_write_verify, +}; +/* * Allocate a block and fill it with dquots. * This is called when the bmapi finds a hole.
@@ -366,7 +368,7 @@ xfs_qm_dqalloc( error =xfs_buf_geterror (bp);if (error) goto error1; - bp->b_pre_io = xfs_dquot_buf_write_verify; + bp->b_ops = &xfs_dquot_buf_ops;/* * Make a chunk of dquots out of this buffer and log
@@ -535,7 +537,7 @@ xfs_qm_dqtobp( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, -0 , &bp, xfs_dquot_buf_read_verify); +0 , &bp, &xfs_dquot_buf_ops);if (error ==EFSCORRUPTED && (flags &XFS_QMOPT_DQREPAIR )) { xfs_dqid_t firstid = (xfs_dqid_t)map.br_startoff *
fs/xfs/xfs_fsops.c +17 -12
@@ -119,7 +119,8 @@ xfs_growfs_get_hdr_buf(struct xfs_mount *mp, xfs_daddr_t blkno, size_t numblks, - int flags) + int flags, + const struct xfs_buf_ops *ops) { struct xfs_buf *bp;
@@ -130,6 +131,7 @@ xfs_growfs_get_hdr_buf(xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); bp->b_bn = blkno; bp->b_maps[0 ].bm_bn = blkno; + bp->b_ops = ops;return bp; }
@@ -217,12 +219,12 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 , + &xfs_agf_buf_ops);if (!bp) { error =ENOMEM ; goto error0; } - bp->b_pre_io = xfs_agf_write_verify; agf =XFS_BUF_TO_AGF (bp); agf->agf_magicnum =cpu_to_be32 (XFS_AGF_MAGIC );
@@ -255,12 +257,12 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AG_DADDR (mp, agno,XFS_AGFL_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 , + &xfs_agfl_buf_ops);if (!bp) { error =ENOMEM ; goto error0; } - bp->b_pre_io = xfs_agfl_write_verify; agfl =XFS_BUF_TO_AGFL (bp);for (bucket =0 ; bucket <XFS_AGFL_SIZE (mp); bucket++)
@@ -276,12 +278,12 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 , + &xfs_agi_buf_ops);if (!bp) { error =ENOMEM ; goto error0; } - bp->b_pre_io = xfs_agi_write_verify; agi =XFS_BUF_TO_AGI (bp); agi->agi_magicnum =cpu_to_be32 (XFS_AGI_MAGIC );
@@ -306,7 +308,8 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AGB_TO_DADDR (mp, agno,XFS_BNO_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); +BTOBB (mp->m_sb.sb_blocksize),0 , + &xfs_allocbt_buf_ops);if (!bp) { error =ENOMEM ;
@@ -329,7 +332,8 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AGB_TO_DADDR (mp, agno,XFS_CNT_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); +BTOBB (mp->m_sb.sb_blocksize),0 , + &xfs_allocbt_buf_ops);if (!bp) { error =ENOMEM ; goto error0;
@@ -352,7 +356,8 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AGB_TO_DADDR (mp, agno,XFS_IBT_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); +BTOBB (mp->m_sb.sb_blocksize),0 , + &xfs_inobt_buf_ops);if (!bp) { error =ENOMEM ; goto error0;
@@ -448,14 +453,14 @@ xfs_growfs_data_private( error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)),XFS_FSS_TO_BB (mp,1 ),0 , &bp, - xfs_sb_read_verify); + &xfs_sb_buf_ops); }else { bp =xfs_trans_get_buf (NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)),XFS_FSS_TO_BB (mp,1 ),0 );if (bp) { + bp->b_ops = &xfs_sb_buf_ops;xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); - bp->b_pre_io = xfs_sb_write_verify; }else error =ENOMEM ; }
fs/xfs/xfs_ialloc.c +10 -8
@@ -210,7 +210,7 @@ xfs_ialloc_inode_init(* to log a whole cluster of inodes instead of all the * individual transactions causing a lot of log traffic. */ - fbuf->b_pre_io = xfs_inode_buf_write_verify; + fbuf->b_ops = &xfs_inode_buf_ops;xfs_buf_zero (fbuf,0 , ninodes << mp->m_sb.sb_inodelog);for (i =0 ; i < ninodes; i++) {int ioffset = i << mp->m_sb.sb_inodelog;
@@ -1505,23 +1505,25 @@ xfs_agi_verify(xfs_check_agi_unlinked (agi); } -void -xfs_agi_write_verify ( +static void +xfs_agi_read_verify (struct xfs_buf *bp) {xfs_agi_verify (bp); }static void -xfs_agi_read_verify ( +xfs_agi_write_verify (struct xfs_buf *bp) {xfs_agi_verify (bp); - bp->b_pre_io = xfs_agi_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_agi_buf_ops = { + .verify_read = xfs_agi_read_verify, + .verify_write = xfs_agi_write_verify, +}; +/* * Read in the allocation group header (inode allocation section) */
@@ -1538,7 +1540,7 @@ xfs_read_agi( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , bpp, xfs_agi_read_verify); +XFS_FSS_TO_BB (mp,1 ),0 , bpp, &xfs_agi_buf_ops);if (error)return error;
fs/xfs/xfs_ialloc.h +1 -1
@@ -150,6 +150,6 @@ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,int xfs_inobt_get_rec (struct xfs_btree_cur *cur,xfs_inobt_rec_incore_t *rec,int *stat); -void xfs_agi_write_verify (struct xfs_buf *bp); +extern const struct xfs_buf_ops xfs_agi_buf_ops;#endif /* __XFS_IALLOC_H__ */
fs/xfs/xfs_ialloc_btree.c +9 -8
@@ -217,22 +217,24 @@ xfs_inobt_verify( }static void -xfs_inobt_write_verify ( +xfs_inobt_read_verify (struct xfs_buf *bp) {xfs_inobt_verify (bp); } -void -xfs_inobt_read_verify ( +static void +xfs_inobt_write_verify (struct xfs_buf *bp) {xfs_inobt_verify (bp); - bp->b_pre_io = xfs_inobt_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_inobt_buf_ops = { + .verify_read = xfs_inobt_read_verify, + .verify_write = xfs_inobt_write_verify, +}; +#ifdef DEBUG STATIC int xfs_inobt_keys_inorder(
@@ -270,8 +272,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = { .init_rec_from_cur = xfs_inobt_init_rec_from_cur, .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, .key_diff = xfs_inobt_key_diff, - .read_verify = xfs_inobt_read_verify, - .write_verify = xfs_inobt_write_verify, + .buf_ops = &xfs_inobt_buf_ops, #ifdef DEBUG .keys_inorder = xfs_inobt_keys_inorder, .recs_inorder = xfs_inobt_recs_inorder,
fs/xfs/xfs_ialloc_btree.h +2 -0
@@ -109,4 +109,6 @@ extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *, struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t);extern int xfs_inobt_maxrecs (struct xfs_mount *,int ,int ); +extern const struct xfs_buf_ops xfs_inobt_buf_ops; +#endif /* __XFS_IALLOC_BTREE_H__ */
fs/xfs/xfs_inode.c +13 -9
@@ -420,23 +420,27 @@ xfs_inode_buf_verify(xfs_inobp_check (mp, bp); } -void -xfs_inode_buf_write_verify ( + +static void +xfs_inode_buf_read_verify (struct xfs_buf *bp) {xfs_inode_buf_verify (bp); } -void -xfs_inode_buf_read_verify ( +static void +xfs_inode_buf_write_verify (struct xfs_buf *bp) {xfs_inode_buf_verify (bp); - bp->b_pre_io = xfs_inode_buf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_inode_buf_ops = { + .verify_read = xfs_inode_buf_read_verify, + .verify_write = xfs_inode_buf_write_verify, +}; + +/* * This routine is called to map an inode to the buffer containing the on-disk * version of the inode. It returns a pointer to the buffer containing the
@@ -462,7 +466,7 @@ xfs_imap_to_bp( buf_flags |=XBF_UNMAPPED ; error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, imap->im_blkno, (int )imap->im_len, buf_flags, &bp, - xfs_inode_buf_read_verify); + &xfs_inode_buf_ops);if (error) {if (error ==EAGAIN ) {ASSERT (buf_flags &XBF_TRYLOCK );
@@ -1792,7 +1796,7 @@ xfs_ifree_cluster(* want it to fail. We can acheive this by adding a write * verifier to the buffer. */ - bp->b_pre_io = xfs_inode_buf_write_verify; + bp->b_ops = &xfs_inode_buf_ops;/* * Walk the inodes already attached to the buffer and mark them
fs/xfs/xfs_inode.h +1 -2
@@ -554,8 +554,6 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, struct xfs_buf **, uint, uint);int xfs_iread (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,uint ); -void xfs_inode_buf_read_verify (struct xfs_buf *); -void xfs_inode_buf_write_verify (struct xfs_buf *);void xfs_dinode_to_disk (struct xfs_dinode *,struct xfs_icdinode *);void xfs_idestroy_fork (struct xfs_inode *,int );
@@ -600,5 +598,6 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);extern struct kmem_zone *xfs_ifork_zone;extern struct kmem_zone *xfs_inode_zone;extern struct kmem_zone *xfs_ili_zone; +extern const struct xfs_buf_ops xfs_inode_buf_ops;#endif /* __XFS_INODE_H__ */
fs/xfs/xfs_itable.c +1 -1
@@ -397,7 +397,7 @@ xfs_bulkstat( & ~r.ir_free)xfs_btree_reada_bufs (mp, agno, agbno, nbcluster, - xfs_inode_buf_read_verify); + &xfs_inode_buf_ops); } irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;
fs/xfs/xfs_log_recover.c +1 -1
@@ -3699,7 +3699,7 @@ xlog_do_recover(ASSERT (!(XFS_BUF_ISWRITE (bp)));XFS_BUF_READ (bp);XFS_BUF_UNASYNC (bp); - bp->b_iodone = xfs_sb_read_verify; + bp->b_ops = &xfs_sb_buf_ops;xfsbdstrat (log->l_mp, bp); error =xfs_buf_iowait (bp);if (error) {
fs/xfs/xfs_mount.c +21 -14
@@ -631,21 +631,11 @@ xfs_sb_verify(xfs_buf_ioerror (bp, error); } -void -xfs_sb_write_verify ( -struct xfs_buf *bp) -{ -xfs_sb_verify (bp); -} - -void +static void xfs_sb_read_verify (struct xfs_buf *bp) {xfs_sb_verify (bp); - bp->b_pre_io = xfs_sb_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); }/*
@@ -654,7 +644,7 @@ xfs_sb_read_verify(* If we find an XFS superblock, the run a normal, noisy mount because we are * really going to mount it and want to know about errors. */ -void +static void xfs_sb_quiet_read_verify (struct xfs_buf *bp) {
@@ -671,6 +661,23 @@ xfs_sb_quiet_read_verify(xfs_buf_ioerror (bp,EFSCORRUPTED ); } +static void +xfs_sb_write_verify ( +struct xfs_buf *bp) +{ +xfs_sb_verify (bp); +} + +const struct xfs_buf_ops xfs_sb_buf_ops = { + .verify_read = xfs_sb_read_verify, + .verify_write = xfs_sb_write_verify, +}; + +static const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { + .verify_read = xfs_sb_quiet_read_verify, + .verify_write = xfs_sb_write_verify, +}; +/* * xfs_readsb *
@@ -697,8 +704,8 @@ xfs_readsb(xfs_mount_t *mp, int flags) reread: bp =xfs_buf_read_uncached (mp->m_ddev_targp,XFS_SB_DADDR ,BTOBB (sector_size),0 , - loud ? xfs_sb_read_verify - : xfs_sb_quiet_read_verify); + loud ? &xfs_sb_buf_ops + : &xfs_sb_quiet_buf_ops);if (!bp) {if (loud)xfs_warn (mp,"SB buffer read failed" );
fs/xfs/xfs_mount.h +2 -2
@@ -385,12 +385,12 @@ extern void xfs_set_low_space_thresholds(struct xfs_mount *);#endif /* __KERNEL__ */ -extern void xfs_sb_read_verify (struct xfs_buf *); -extern void xfs_sb_write_verify (struct xfs_buf *bp);extern void xfs_mod_sb (struct xfs_trans *,__int64_t );extern int xfs_initialize_perag (struct xfs_mount *,xfs_agnumber_t ,xfs_agnumber_t *);extern void xfs_sb_from_disk (struct xfs_sb *,struct xfs_dsb *);extern void xfs_sb_to_disk (struct xfs_dsb *,struct xfs_sb *,__int64_t ); +extern const struct xfs_buf_ops xfs_sb_buf_ops; +#endif /* __XFS_MOUNT_H__ */
fs/xfs/xfs_trans.h +3 -3
@@ -474,7 +474,7 @@ int xfs_trans_read_buf_map(struct xfs_mount *mp, struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp, - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);static inline int xfs_trans_read_buf(
@@ -485,11 +485,11 @@ xfs_trans_read_buf(int numblks, xfs_buf_flags_t flags, struct xfs_buf **bpp, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) {DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks );return xfs_trans_read_buf_map (mp, tp, target, &map,1 , - flags, bpp, verify); + flags, bpp, ops); }struct xfs_buf *xfs_trans_getsb (xfs_trans_t *,struct xfs_mount *,int );
fs/xfs/xfs_trans_buf.c +4 -4
@@ -258,7 +258,7 @@ xfs_trans_read_buf_map(int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { xfs_buf_t *bp;xfs_buf_log_item_t *bip;
@@ -266,7 +266,7 @@ xfs_trans_read_buf_map( *bpp =NULL ;if (!tp) { - bp =xfs_buf_read_map (target, map, nmaps, flags, verify); + bp =xfs_buf_read_map (target, map, nmaps, flags, ops);if (!bp)return (flags &XBF_TRYLOCK ) ?EAGAIN :XFS_ERROR (ENOMEM );
@@ -315,7 +315,7 @@ xfs_trans_read_buf_map(ASSERT (!XFS_BUF_ISASYNC (bp));ASSERT (bp->b_iodone ==NULL );XFS_BUF_READ (bp); - bp->b_iodone = verify; + bp->b_ops = ops;xfsbdstrat (tp->t_mountp, bp); error =xfs_buf_iowait (bp);if (error) {
@@ -352,7 +352,7 @@ xfs_trans_read_buf_map(return 0 ; } - bp =xfs_buf_read_map (target, map, nmaps, flags, verify); + bp =xfs_buf_read_map (target, map, nmaps, flags, ops);if (bp ==NULL ) { *bpp =NULL ; return (flags & XBF_TRYLOCK) ?
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 30/32 xfs: convert buffer verifiers to an ops structure.
xfs: convert buffer verifiers to an ops structure.
From: Dave Chinner <[email protected]>
To separate the verifiers from iodone functions and associate read and write verifiers at the same time, introduce a buffer verifier operations structure to the xfs_buf.
This avoids the need for assigning the write verifier, clearing the iodone function and re-running ioend processing in the read verifier, and gets rid of the nasty "b_pre_io" name for the write verifier function pointer. If we ever need to, it will also be easier to add further content specific callbacks to a buffer with an ops structure in place.
We also avoid needing to export verifier functions, instead we can simply export the ops structures for those that are needed outside the function they are defined in.
This patch also fixes a directory block readahead verifier issue it exposed.
This patch also adds ops callbacks to the inode/alloc btree blocks initialised by growfs. These will need more work before they will work with CRCs.
---
V2: fold in quotacheck dquot verifier changes.
fs/xfs/xfs_ag.h | 4 +++ fs/xfs/xfs_alloc.c | 28 +++++++++++--------- fs/xfs/xfs_alloc.h | 4 +-- fs/xfs/xfs_alloc_btree.c | 18 +++++++------ fs/xfs/xfs_alloc_btree.h | 2 ++ fs/xfs/xfs_attr_leaf.c | 19 +++++++------- fs/xfs/xfs_attr_leaf.h | 3 ++- fs/xfs/xfs_bmap.c | 22 ++++++++-------- fs/xfs/xfs_bmap_btree.c | 20 +++++++------- fs/xfs/xfs_bmap_btree.h | 3 +-- fs/xfs/xfs_btree.c | 26 +++++++++---------- fs/xfs/xfs_btree.h | 9 +++---- fs/xfs/xfs_buf.c | 63 ++++++++++++++++++++++++++------------------- fs/xfs/xfs_buf.h | 24 ++++++++++------- fs/xfs/xfs_da_btree.c | 40 +++++++++++++++++----------- fs/xfs/xfs_da_btree.h | 4 +-- fs/xfs/xfs_dir2_block.c | 20 +++++++------- fs/xfs/xfs_dir2_data.c | 52 ++++++++++++++++++++++++++++++------- fs/xfs/xfs_dir2_leaf.c | 36 ++++++++++++++------------ fs/xfs/xfs_dir2_node.c | 26 ++++++++++--------- fs/xfs/xfs_dir2_priv.h | 10 ++++--- fs/xfs/xfs_dquot.c | 18 +++++++------ fs/xfs/xfs_dquot.h | 3 ++- fs/xfs/xfs_fsops.c | 29 ++++++++++++--------- fs/xfs/xfs_ialloc.c | 18 +++++++------ fs/xfs/xfs_ialloc.h | 2 +- fs/xfs/xfs_ialloc_btree.c | 17 ++++++------ fs/xfs/xfs_ialloc_btree.h | 2 ++ fs/xfs/xfs_inode.c | 22 +++++++++------- fs/xfs/xfs_inode.h | 3 +-- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_mount.c | 35 +++++++++++++++---------- fs/xfs/xfs_mount.h | 4 +-- fs/xfs/xfs_qm.c | 2 +- fs/xfs/xfs_trans.h | 6 ++--- fs/xfs/xfs_trans_buf.c | 8 +++--- 37 files changed, 357 insertions(+), 249 deletions(-)
fs/xfs/xfs_ag.h +4 -0
@@ -108,6 +108,8 @@ typedef struct xfs_agf {extern int xfs_read_agf (struct xfs_mount *mp,struct xfs_trans *tp,xfs_agnumber_t agno,int flags,struct xfs_buf **bpp); +extern const struct xfs_buf_ops xfs_agf_buf_ops; +/* * Size of the unlinked inode hash table in the agi. */
@@ -161,6 +163,8 @@ typedef struct xfs_agi {extern int xfs_read_agi (struct xfs_mount *mp,struct xfs_trans *tp,xfs_agnumber_t agno,struct xfs_buf **bpp); +extern const struct xfs_buf_ops xfs_agi_buf_ops; +/* * The third a.g. block contains the a.g. freelist, an array * of block pointers to blocks owned by the allocation btree code.
fs/xfs/xfs_alloc.c +16 -12
@@ -465,7 +465,7 @@ xfs_agfl_verify(#endif } -void +static void xfs_agfl_write_verify (struct xfs_buf *bp) {
@@ -477,11 +477,13 @@ xfs_agfl_read_verify( struct xfs_buf *bp) {xfs_agfl_verify (bp); - bp->b_pre_io = xfs_agfl_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_agfl_buf_ops = { + .verify_read = xfs_agfl_read_verify, + .verify_write = xfs_agfl_write_verify, +}; +/* * Read in the allocation group free block array. */
@@ -499,7 +501,7 @@ xfs_alloc_read_agfl( error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGFL_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , &bp, xfs_agfl_read_verify); +XFS_FSS_TO_BB (mp,1 ),0 , &bp, &xfs_agfl_buf_ops);if (error)return error;ASSERT (!xfs_buf_geterror (bp));
@@ -2181,23 +2183,25 @@ xfs_agf_verify( } } -void -xfs_agf_write_verify ( +static void +xfs_agf_read_verify (struct xfs_buf *bp) {xfs_agf_verify (bp); }static void -xfs_agf_read_verify ( +xfs_agf_write_verify (struct xfs_buf *bp) {xfs_agf_verify (bp); - bp->b_pre_io = xfs_agf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_agf_buf_ops = { + .verify_read = xfs_agf_read_verify, + .verify_write = xfs_agf_write_verify, +}; +/* * Read in the allocation group header (free/alloc section). */
@@ -2215,7 +2219,7 @@ xfs_read_agf( error =xfs_trans_read_buf ( mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ), flags, bpp, xfs_agf_read_verify); +XFS_FSS_TO_BB (mp,1 ), flags, bpp, &xfs_agf_buf_ops);if (error)return error;if (!*bpp)
fs/xfs/xfs_alloc.h +2 -2
@@ -238,7 +238,7 @@ xfs_alloc_freespace_map(u64 start, u64 length); -void xfs_agf_write_verify (struct xfs_buf *bp); -void xfs_agfl_write_verify (struct xfs_buf *bp); +extern const struct xfs_buf_ops xfs_agf_buf_ops; +extern const struct xfs_buf_ops xfs_agfl_buf_ops;#endif /* __XFS_ALLOC_H__ */
fs/xfs/xfs_alloc_btree.c +10 -8
@@ -329,22 +329,25 @@ xfs_allocbt_verify( }static void -xfs_allocbt_write_verify ( +xfs_allocbt_read_verify (struct xfs_buf *bp) {xfs_allocbt_verify (bp); } -void -xfs_allocbt_read_verify ( +static void +xfs_allocbt_write_verify (struct xfs_buf *bp) {xfs_allocbt_verify (bp); - bp->b_pre_io = xfs_allocbt_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_allocbt_buf_ops = { + .verify_read = xfs_allocbt_read_verify, + .verify_write = xfs_allocbt_write_verify, +}; + +#ifdef DEBUG STATIC int xfs_allocbt_keys_inorder(
@@ -400,8 +403,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = { .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, .key_diff = xfs_allocbt_key_diff, - .read_verify = xfs_allocbt_read_verify, - .write_verify = xfs_allocbt_write_verify, + .buf_ops = &xfs_allocbt_buf_ops, #ifdef DEBUG .keys_inorder = xfs_allocbt_keys_inorder, .recs_inorder = xfs_allocbt_recs_inorder,
fs/xfs/xfs_alloc_btree.h +2 -0
@@ -93,4 +93,6 @@ extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *, xfs_agnumber_t, xfs_btnum_t);extern int xfs_allocbt_maxrecs (struct xfs_mount *,int ,int ); +extern const struct xfs_buf_ops xfs_allocbt_buf_ops; +#endif /* __XFS_ALLOC_BTREE_H__ */
fs/xfs/xfs_attr_leaf.c +10 -9
@@ -104,22 +104,23 @@ xfs_attr_leaf_verify( }static void -xfs_attr_leaf_write_verify ( +xfs_attr_leaf_read_verify (struct xfs_buf *bp) {xfs_attr_leaf_verify (bp); } -void -xfs_attr_leaf_read_verify ( +static void +xfs_attr_leaf_write_verify (struct xfs_buf *bp) {xfs_attr_leaf_verify (bp); - bp->b_pre_io = xfs_attr_leaf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_attr_leaf_buf_ops = { + .verify_read = xfs_attr_leaf_read_verify, + .verify_write = xfs_attr_leaf_write_verify, +};int xfs_attr_leaf_read(
@@ -130,7 +131,7 @@ xfs_attr_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, -XFS_ATTR_FORK , xfs_attr_leaf_read_verify); +XFS_ATTR_FORK , &xfs_attr_leaf_buf_ops); }/*========================================================================
@@ -924,7 +925,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args) XFS_ATTR_FORK);if (error) goto out; - bp2->b_pre_io = bp1->b_pre_io; + bp2->b_ops = bp1->b_ops;memcpy (bp2->b_addr, bp1->b_addr,XFS_LBSIZE (dp->i_mount)); bp1 =NULL ;xfs_trans_log_buf (args->trans, bp2,0 ,XFS_LBSIZE (dp->i_mount) -1 );
@@ -978,7 +979,7 @@ xfs_attr_leaf_create( XFS_ATTR_FORK);if (error)return (error); - bp->b_pre_io = xfs_attr_leaf_write_verify; + bp->b_ops = &xfs_attr_leaf_buf_ops; leaf = bp->b_addr;memset ((char *)leaf,0 ,XFS_LBSIZE (dp->i_mount)); hdr = &leaf->hdr;
fs/xfs/xfs_attr_leaf.h +2 -1
@@ -264,6 +264,7 @@ int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,int xfs_attr_leaf_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); -void xfs_attr_leaf_read_verify (struct xfs_buf *bp); + +extern const struct xfs_buf_ops xfs_attr_leaf_buf_ops;#endif /* __XFS_ATTR_LEAF_H__ */
fs/xfs/xfs_bmap.c +11 -11
@@ -2663,7 +2663,7 @@ xfs_bmap_btree_to_extents(return error;#endif error =xfs_btree_read_bufl (mp, tp, cbno,0 , &cbp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; cblock =XFS_BUF_TO_BLOCK (cbp);
@@ -3124,7 +3124,7 @@ xfs_bmap_extents_to_btree(/* * Fill in the child block. */ - abp->b_pre_io = xfs_bmbt_write_verify; + abp->b_ops = &xfs_bmbt_buf_ops; ablock =XFS_BUF_TO_BLOCK (abp); ablock->bb_magic =cpu_to_be32 (XFS_BMAP_MAGIC ); ablock->bb_level =0 ;
@@ -3271,7 +3271,7 @@ xfs_bmap_local_to_extents(ASSERT (args.len ==1 ); *firstblock = args.fsbno; bp =xfs_btree_get_bufl (args.mp, tp, args.fsbno,0 ); - bp->b_pre_io = xfs_bmbt_write_verify; + bp->b_ops = &xfs_bmbt_buf_ops;memcpy (bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);xfs_trans_log_buf (tp, bp,0 , ifp->if_bytes -1 );xfs_bmap_forkoff_reset (args.mp, ip, whichfork);
@@ -4082,7 +4082,7 @@ xfs_bmap_read_extents(*/ while (level-- >0 ) { error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp, -XFS_BMAP_BTREE_REF , xfs_bmbt_read_verify); +XFS_BMAP_BTREE_REF , &xfs_bmbt_buf_ops);if (error)return error; block =XFS_BUF_TO_BLOCK (bp);
@@ -4129,7 +4129,7 @@ xfs_bmap_read_extents( nextbno =be64_to_cpu (block->bb_u.l.bb_rightsib);if (nextbno !=NULLFSBLOCK )xfs_btree_reada_bufl (mp, nextbno,1 , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);/* * Copy records into the extent records. */
@@ -4162,7 +4162,7 @@ xfs_bmap_read_extents(if (bno ==NULLFSBLOCK )break ; error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp, -XFS_BMAP_BTREE_REF , xfs_bmbt_read_verify); +XFS_BMAP_BTREE_REF , &xfs_bmbt_buf_ops);if (error)return error; block =XFS_BUF_TO_BLOCK (bp);
@@ -5880,7 +5880,7 @@ xfs_bmap_check_leaf_extents( bp_release =1 ; error =xfs_btree_read_bufl (mp,NULL , bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error) goto error_norelse; }
@@ -5966,7 +5966,7 @@ xfs_bmap_check_leaf_extents( bp_release =1 ; error =xfs_btree_read_bufl (mp,NULL , bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error) goto error_norelse; }
@@ -6061,7 +6061,7 @@ xfs_bmap_count_tree(int numrecs; error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; *count +=1 ;
@@ -6073,7 +6073,7 @@ xfs_bmap_count_tree(while (nextbno !=NULLFSBLOCK ) { error =xfs_btree_read_bufl (mp, tp, nextbno,0 , &nbp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; *count +=1 ;
@@ -6105,7 +6105,7 @@ xfs_bmap_count_tree( bno = nextbno; error =xfs_btree_read_bufl (mp, tp, bno,0 , &bp,XFS_BMAP_BTREE_REF , - xfs_bmbt_read_verify); + &xfs_bmbt_buf_ops);if (error)return error; *count +=1 ;
fs/xfs/xfs_bmap_btree.c +11 -9
@@ -749,23 +749,26 @@ xfs_bmbt_verify( } } -void -xfs_bmbt_write_verify ( +static void +xfs_bmbt_read_verify (struct xfs_buf *bp) {xfs_bmbt_verify (bp); } -void -xfs_bmbt_read_verify ( +static void +xfs_bmbt_write_verify (struct xfs_buf *bp) {xfs_bmbt_verify (bp); - bp->b_pre_io = xfs_bmbt_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_bmbt_buf_ops = { + .verify_read = xfs_bmbt_read_verify, + .verify_write = xfs_bmbt_write_verify, +}; + +#ifdef DEBUG STATIC int xfs_bmbt_keys_inorder(
@@ -805,8 +808,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = { .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, .key_diff = xfs_bmbt_key_diff, - .read_verify = xfs_bmbt_read_verify, - .write_verify = xfs_bmbt_write_verify, + .buf_ops = &xfs_bmbt_buf_ops, #ifdef DEBUG .keys_inorder = xfs_bmbt_keys_inorder, .recs_inorder = xfs_bmbt_recs_inorder,
fs/xfs/xfs_bmap_btree.h +1 -2
@@ -232,11 +232,10 @@ extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,extern int xfs_bmbt_get_maxrecs (struct xfs_btree_cur *,int level);extern int xfs_bmdr_maxrecs (struct xfs_mount *,int blocklen,int leaf);extern int xfs_bmbt_maxrecs (struct xfs_mount *,int blocklen,int leaf); -extern void xfs_bmbt_read_verify (struct xfs_buf *bp); -extern void xfs_bmbt_write_verify (struct xfs_buf *bp);extern struct xfs_btree_cur *xfs_bmbt_init_cursor (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,int ); +extern const struct xfs_buf_ops xfs_bmbt_buf_ops;#endif /* __XFS_BMAP_BTREE_H__ */
fs/xfs/xfs_btree.c +13 -13
@@ -271,7 +271,7 @@ xfs_btree_dup_cursor( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp,XFS_BUF_ADDR (bp), mp->m_bsize,0 , &bp, - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops);if (error) {xfs_btree_del_cursor (new, error); *ncur =NULL ;
@@ -621,7 +621,7 @@ xfs_btree_read_bufl(uint lock,/* lock flags for read_buf */ struct xfs_buf **bpp, /* buffer for fsbno */ int refval, /* ref count value for buffer */ - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { struct xfs_buf *bp; /* return value */xfs_daddr_t d;/* real disk block address */
@@ -630,7 +630,7 @@ xfs_btree_read_bufl(ASSERT (fsbno !=NULLFSBLOCK ); d =XFS_FSB_TO_DADDR (mp, fsbno); error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, d, - mp->m_bsize, lock, &bp, verify); + mp->m_bsize, lock, &bp, ops);if (error)return error;ASSERT (!xfs_buf_geterror (bp));
@@ -650,13 +650,13 @@ xfs_btree_reada_bufl(struct xfs_mount *mp,/* file system mount point */ xfs_fsblock_t fsbno, /* file system block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { xfs_daddr_t d;ASSERT (fsbno !=NULLFSBLOCK ); d =XFS_FSB_TO_DADDR (mp, fsbno); -xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, verify); +xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, ops); }/*
@@ -670,14 +670,14 @@ xfs_btree_reada_bufs(xfs_agnumber_t agno,/* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { xfs_daddr_t d;ASSERT (agno !=NULLAGNUMBER );ASSERT (agbno !=NULLAGBLOCK ); d =XFS_AGB_TO_DADDR (mp, agno, agbno); -xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, verify); +xfs_buf_readahead (mp->m_ddev_targp, d, mp->m_bsize * count, ops); }STATIC int
@@ -692,13 +692,13 @@ xfs_btree_readahead_lblock(if ((lr &XFS_BTCUR_LEFTRA ) && left !=NULLDFSBNO ) {xfs_btree_reada_bufl (cur->bc_mp, left,1 , - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops); rval++; }if ((lr &XFS_BTCUR_RIGHTRA ) && right !=NULLDFSBNO ) {xfs_btree_reada_bufl (cur->bc_mp, right,1 , - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops); rval++; }
@@ -718,13 +718,13 @@ xfs_btree_readahead_sblock(if ((lr &XFS_BTCUR_LEFTRA ) && left !=NULLAGBLOCK ) {xfs_btree_reada_bufs (cur->bc_mp, cur->bc_private.a.agno, - left,1 , cur->bc_ops->read_verify); + left,1 , cur->bc_ops->buf_ops); rval++; }if ((lr &XFS_BTCUR_RIGHTRA ) && right !=NULLAGBLOCK ) {xfs_btree_reada_bufs (cur->bc_mp, cur->bc_private.a.agno, - right,1 , cur->bc_ops->read_verify); + right,1 , cur->bc_ops->buf_ops); rval++; }
@@ -996,7 +996,7 @@ xfs_btree_get_buf_block(if (!*bpp)return ENOMEM ; - (*bpp)->b_pre_io = cur->bc_ops->write_verify; + (*bpp)->b_ops = cur->bc_ops->buf_ops; *block =XFS_BUF_TO_BLOCK (*bpp);return 0 ; }
@@ -1024,7 +1024,7 @@ xfs_btree_read_buf_block( d =xfs_btree_ptr_to_daddr (cur, ptr); error =xfs_trans_read_buf (mp, cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, flags, bpp, - cur->bc_ops->read_verify); + cur->bc_ops->buf_ops);if (error)return error;
fs/xfs/xfs_btree.h +4 -5
@@ -188,8 +188,7 @@ struct xfs_btree_ops {__int64_t (*key_diff)(struct xfs_btree_cur *cur,union xfs_btree_key *key); -void (*read_verify)(struct xfs_buf *bp); -void (*write_verify)(struct xfs_buf *bp); +const struct xfs_buf_ops *buf_ops;#ifdef DEBUG /* check that k1 is lower than k2 */
@@ -359,7 +358,7 @@ xfs_btree_read_bufl(uint lock,/* lock flags for read_buf */ struct xfs_buf **bpp, /* buffer for fsbno */ int refval, /* ref count value for buffer */ - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);/* * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -370,7 +369,7 @@ xfs_btree_reada_bufl(struct xfs_mount *mp,/* file system mount point */ xfs_fsblock_t fsbno, /* file system block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);/* * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -382,7 +381,7 @@ xfs_btree_reada_bufs(xfs_agnumber_t agno,/* allocation group number */ xfs_agblock_t agbno, /* allocation group block number */ xfs_extlen_t count, /* count of filesystem blocks */ - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);/* * Initialise a new btree block header
fs/xfs/xfs_buf.c +37 -26
144 lines not on this page · raw message
fs/xfs/xfs_buf.h +14 -10
@@ -111,6 +111,11 @@ struct xfs_buf_map {#define DEFINE_SINGLE_BUF_MAP (map, blkno, numblk) \ struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; +struct xfs_buf_ops { +void (*verify_read)(struct xfs_buf *); +void (*verify_write)(struct xfs_buf *); +}; + typedef struct xfs_buf { /* * first cacheline holds all the fields needed for an uncontended cache
@@ -154,9 +159,7 @@ typedef struct xfs_buf {unsigned int b_page_count;/* size of page array */ unsigned int b_offset;/* page offset in first page */ unsigned short b_error;/* error code on I/O */ - -void (*b_pre_io)(struct xfs_buf *); -/* pre-io callback function */ +const struct xfs_buf_ops *b_ops;#ifdef XFS_BUF_LOCK_TRACKING int b_last_holder;
@@ -199,10 +202,11 @@ struct xfs_buf *xfs_buf_get_map(struct xfs_buftarg *target, xfs_buf_flags_t flags);struct xfs_buf *xfs_buf_read_map (struct xfs_buftarg *target,struct xfs_buf_map *map,int nmaps, -xfs_buf_flags_t flags,xfs_buf_iodone_t verify); +xfs_buf_flags_t flags, +const struct xfs_buf_ops *ops);void xfs_buf_readahead_map (struct xfs_buftarg *target,struct xfs_buf_map *map,int nmaps, -xfs_buf_iodone_t verify); +const struct xfs_buf_ops *ops);static inline struct xfs_buf * xfs_buf_get(
@@ -221,10 +225,10 @@ xfs_buf_read(xfs_daddr_t blkno, size_t numblks, xfs_buf_flags_t flags, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) {DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks ); -return xfs_buf_read_map (target, &map,1 , flags, verify); +return xfs_buf_read_map (target, &map,1 , flags, ops); } static inline void
@@ -232,10 +236,10 @@ xfs_buf_readahead(struct xfs_buftarg *target, xfs_daddr_t blkno, size_t numblks, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) {DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks ); -return xfs_buf_readahead_map (target, &map,1 , verify); +return xfs_buf_readahead_map (target, &map,1 , ops); }struct xfs_buf *xfs_buf_get_empty (struct xfs_buftarg *target,size_t numblks);
@@ -246,7 +250,7 @@ struct xfs_buf *xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks, int flags);struct xfs_buf *xfs_buf_read_uncached (struct xfs_buftarg *target,xfs_daddr_t daddr,size_t numblks,int flags, -xfs_buf_iodone_t verify); +const struct xfs_buf_ops *ops);void xfs_buf_hold (struct xfs_buf *bp);/* Releasing Buffers */
fs/xfs/xfs_da_btree.c +25 -15
@@ -117,6 +117,12 @@ xfs_da_node_write_verify(xfs_da_node_verify (bp); } +/* +* leaf/node format detection on trees is sketchy, so a node read can be done on +* leaf level blocks when detection identifies the tree as a node format tree +* incorrectly. In this case, we need to swap the verifier to match the correct +* format of the block being read. +*/ static void xfs_da_node_read_verify (struct xfs_buf *bp)
@@ -129,10 +135,12 @@ xfs_da_node_read_verify(xfs_da_node_verify (bp);break ;case XFS_ATTR_LEAF_MAGIC : -xfs_attr_leaf_read_verify (bp); + bp->b_ops = &xfs_attr_leaf_buf_ops; + bp->b_ops->verify_read (bp);return ;case XFS_DIR2_LEAFN_MAGIC : -xfs_dir2_leafn_read_verify (bp); + bp->b_ops = &xfs_dir2_leafn_buf_ops; + bp->b_ops->verify_read (bp);return ;default : XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
@@ -140,12 +148,14 @@ xfs_da_node_read_verify(xfs_buf_ioerror (bp,EFSCORRUPTED );break ; } - - bp->b_pre_io = xfs_da_node_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_da_node_buf_ops = { + .verify_read = xfs_da_node_read_verify, + .verify_write = xfs_da_node_write_verify, +}; + + int xfs_da_node_read( struct xfs_trans *tp,
@@ -156,7 +166,7 @@ xfs_da_node_read( int which_fork) {return xfs_da_read_buf (tp, dp, bno, mappedbno, bpp, - which_fork, xfs_da_node_read_verify); + which_fork, &xfs_da_node_buf_ops); }/*========================================================================
@@ -193,7 +203,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,xfs_trans_log_buf (tp, bp,XFS_DA_LOGRANGE (node, &node->hdr,sizeof (node->hdr))); - bp->b_pre_io = xfs_da_node_write_verify; + bp->b_ops = &xfs_da_node_buf_ops; *bpp = bp;return (0 ); }
@@ -394,7 +404,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,memcpy (node, oldroot, size);xfs_trans_log_buf (tp, bp,0 , size -1 ); - bp->b_pre_io = blk1->bp->b_pre_io; + bp->b_ops = blk1->bp->b_ops; blk1->bp = bp; blk1->blkno = blkno;
@@ -828,11 +838,11 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)/* * This could be copying a leaf back into the root block in the case of * there only being a single leaf block left in the tree. Hence we have -* to update the pre_io pointer as well to match the buffer type change +* to update the b_ops pointer as well to match the buffer type change * that could occur. */ memcpy (root_blk->bp->b_addr, bp->b_addr, state->blocksize); - root_blk->bp->b_pre_io = bp->b_pre_io; + root_blk->bp->b_ops = bp->b_ops;xfs_trans_log_buf (args->trans, root_blk->bp,0 , state->blocksize -1 ); error =xfs_da_shrink_inode (args, child, bp);return (error);
@@ -2223,7 +2233,7 @@ xfs_da_read_buf(xfs_daddr_t mappedbno, struct xfs_buf **bpp, int whichfork, - xfs_buf_iodone_t verifier) + const struct xfs_buf_ops *ops) { struct xfs_buf *bp;struct xfs_buf_map map;
@@ -2245,7 +2255,7 @@ xfs_da_read_buf( error =xfs_trans_read_buf_map (dp->i_mount, trans, dp->i_mount->m_ddev_targp, - mapp, nmap,0 , &bp, verifier); + mapp, nmap,0 , &bp, ops);if (error) goto out_free;
@@ -2303,7 +2313,7 @@ xfs_da_reada_buf(xfs_dablk_t bno, xfs_daddr_t mappedbno, int whichfork, - xfs_buf_iodone_t verifier) + const struct xfs_buf_ops *ops) { struct xfs_buf_map map;struct xfs_buf_map *mapp;
@@ -2322,7 +2332,7 @@ xfs_da_reada_buf( } mappedbno = mapp[0 ].bm_bn; -xfs_buf_readahead_map (dp->i_mount->m_ddev_targp, mapp, nmap,NULL ); +xfs_buf_readahead_map (dp->i_mount->m_ddev_targp, mapp, nmap, ops); out_free:if (mapp != &map)
fs/xfs/xfs_da_btree.h +2 -2
@@ -229,10 +229,10 @@ int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp,int xfs_da_read_buf (struct xfs_trans *trans,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mappedbno,struct xfs_buf **bpp,int whichfork, -xfs_buf_iodone_t verifier); +const struct xfs_buf_ops *ops);xfs_daddr_t xfs_da_reada_buf (struct xfs_trans *trans,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mapped_bno, -int whichfork,xfs_buf_iodone_t verifier); +int whichfork,const struct xfs_buf_ops *ops);int xfs_da_shrink_inode (xfs_da_args_t *args,xfs_dablk_t dead_blkno,struct xfs_buf *dead_buf);
fs/xfs/xfs_dir2_block.c +11 -9
@@ -74,22 +74,24 @@ xfs_dir2_block_verify( }static void -xfs_dir2_block_write_verify ( +xfs_dir2_block_read_verify (struct xfs_buf *bp) {xfs_dir2_block_verify (bp); } -void -xfs_dir2_block_read_verify ( +static void +xfs_dir2_block_write_verify (struct xfs_buf *bp) {xfs_dir2_block_verify (bp); - bp->b_pre_io = xfs_dir2_block_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_dir2_block_buf_ops = { + .verify_read = xfs_dir2_block_read_verify, + .verify_write = xfs_dir2_block_write_verify, +}; + static int xfs_dir2_block_read( struct xfs_trans *tp,
@@ -99,7 +101,7 @@ xfs_dir2_block_read(struct xfs_mount *mp = dp->i_mount;return xfs_da_read_buf (tp, dp, mp->m_dirdatablk,-1 , bpp, -XFS_DATA_FORK , xfs_dir2_block_read_verify); +XFS_DATA_FORK , &xfs_dir2_block_buf_ops); } static void
@@ -1010,7 +1012,7 @@ xfs_dir2_leaf_to_block(/* * Start converting it to block form. */ - dbp->b_pre_io = xfs_dir2_block_write_verify; + dbp->b_ops = &xfs_dir2_block_buf_ops; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC ); needlog =1 ; needscan =0 ;
@@ -1140,7 +1142,7 @@ xfs_dir2_sf_to_block(kmem_free (sfp);return error; } - bp->b_pre_io = xfs_dir2_block_write_verify; + bp->b_ops = &xfs_dir2_block_buf_ops; hdr = bp->b_addr; hdr->magic =cpu_to_be32 (XFS_DIR2_BLOCK_MAGIC );/*
fs/xfs/xfs_dir2_data.c +43 -9
87 lines not on this page · raw message
fs/xfs/xfs_dir2_leaf.c +20 -16
@@ -65,39 +65,43 @@ xfs_dir2_leaf_verify( }static void -xfs_dir2_leaf1_write_verify ( +xfs_dir2_leaf1_read_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); }static void -xfs_dir2_leaf1_read_verify ( +xfs_dir2_leaf1_write_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC )); - bp->b_pre_io = xfs_dir2_leaf1_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); }void -xfs_dir2_leafn_write_verify ( +xfs_dir2_leafn_read_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); }void -xfs_dir2_leafn_read_verify ( +xfs_dir2_leafn_write_verify (struct xfs_buf *bp) {xfs_dir2_leaf_verify (bp,cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC )); - bp->b_pre_io = xfs_dir2_leafn_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +static const struct xfs_buf_ops xfs_dir2_leaf1_buf_ops = { + .verify_read = xfs_dir2_leaf1_read_verify, + .verify_write = xfs_dir2_leaf1_write_verify, +}; + +const struct xfs_buf_ops xfs_dir2_leafn_buf_ops = { + .verify_read = xfs_dir2_leafn_read_verify, + .verify_write = xfs_dir2_leafn_write_verify, +}; + static int xfs_dir2_leaf_read( struct xfs_trans *tp,
@@ -107,7 +111,7 @@ xfs_dir2_leaf_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leaf1_read_verify); +XFS_DATA_FORK , &xfs_dir2_leaf1_buf_ops); }int
@@ -119,7 +123,7 @@ xfs_dir2_leafn_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_leafn_read_verify); +XFS_DATA_FORK , &xfs_dir2_leafn_buf_ops); }/*
@@ -198,7 +202,7 @@ xfs_dir2_block_to_leaf(/* * Fix up the block header, make it a data block. */ - dbp->b_pre_io = xfs_dir2_data_write_verify; + dbp->b_ops = &xfs_dir2_data_buf_ops; hdr->magic =cpu_to_be32 (XFS_DIR2_DATA_MAGIC );if (needscan)xfs_dir2_data_freescan (mp, hdr, &needlog);
@@ -1264,12 +1268,12 @@ xfs_dir2_leaf_init(* the block. */ if (magic ==XFS_DIR2_LEAF1_MAGIC ) { - bp->b_pre_io = xfs_dir2_leaf1_write_verify; + bp->b_ops = &xfs_dir2_leaf1_buf_ops; ltp =xfs_dir2_leaf_tail_p (mp, leaf); ltp->bestcount =0 ;xfs_dir2_leaf_log_tail (tp, bp); }else - bp->b_pre_io = xfs_dir2_leafn_write_verify; + bp->b_ops = &xfs_dir2_leafn_buf_ops; *bpp = bp;return 0 ; }
@@ -1954,7 +1958,7 @@ xfs_dir2_node_to_leaf(else xfs_dir2_leaf_log_header (tp, lbp); - lbp->b_pre_io = xfs_dir2_leaf1_write_verify; + lbp->b_ops = &xfs_dir2_leaf1_buf_ops; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAF1_MAGIC );/*
fs/xfs/xfs_dir2_node.c +14 -12
@@ -72,22 +72,24 @@ xfs_dir2_free_verify( }static void -xfs_dir2_free_write_verify ( +xfs_dir2_free_read_verify (struct xfs_buf *bp) {xfs_dir2_free_verify (bp); } -void -xfs_dir2_free_read_verify ( +static void +xfs_dir2_free_write_verify (struct xfs_buf *bp) {xfs_dir2_free_verify (bp); - bp->b_pre_io = xfs_dir2_free_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +static const struct xfs_buf_ops xfs_dir2_free_buf_ops = { + .verify_read = xfs_dir2_free_read_verify, + .verify_write = xfs_dir2_free_write_verify, +}; +static int __xfs_dir2_free_read(
@@ -98,7 +100,7 @@ __xfs_dir2_free_read( struct xfs_buf **bpp) {return xfs_da_read_buf (tp, dp, fbno, mappedbno, bpp, -XFS_DATA_FORK , xfs_dir2_free_read_verify); +XFS_DATA_FORK , &xfs_dir2_free_buf_ops); }int
@@ -201,7 +203,7 @@ xfs_dir2_leaf_to_node( XFS_DATA_FORK);if (error)return error; - fbp->b_pre_io = xfs_dir2_free_write_verify; + fbp->b_ops = &xfs_dir2_free_buf_ops; free = fbp->b_addr; leaf = lbp->b_addr;
@@ -225,7 +227,7 @@ xfs_dir2_leaf_to_node( } free->hdr.nused =cpu_to_be32 (n); - lbp->b_pre_io = xfs_dir2_leafn_write_verify; + lbp->b_ops = &xfs_dir2_leafn_buf_ops; leaf->hdr.info.magic =cpu_to_be16 (XFS_DIR2_LEAFN_MAGIC );/*
@@ -636,7 +638,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index = (int )((char *)dep - (char *)curbp->b_addr); state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; - curbp->b_pre_io = xfs_dir2_data_write_verify; + curbp->b_ops = &xfs_dir2_data_buf_ops;if (cmp ==XFS_CMP_EXACT )return XFS_ERROR (EEXIST ); }
@@ -651,7 +653,7 @@ xfs_dir2_leafn_lookup_for_entry( state->extrablk.index =-1 ; state->extrablk.blkno = curdb; state->extrablk.magic =XFS_DIR2_DATA_MAGIC ; - curbp->b_pre_io = xfs_dir2_data_write_verify; + curbp->b_ops = &xfs_dir2_data_buf_ops; }else {/* If the curbp is not the CI match block, drop it */ if (state->extrablk.bp != curbp)
@@ -1649,7 +1651,7 @@ xfs_dir2_node_addname_int( -1, &fbp, XFS_DATA_FORK);if (error)return error; - fbp->b_pre_io = xfs_dir2_free_write_verify; + fbp->b_ops = &xfs_dir2_free_buf_ops;/* * Initialize the new block to be empty, and remember
fs/xfs/xfs_dir2_priv.h +7 -3
@@ -30,6 +30,8 @@ extern int xfs_dir_cilookup_result(struct xfs_da_args *args, const unsigned char *name, int len);/* xfs_dir2_block.c */ +extern const struct xfs_buf_ops xfs_dir2_block_buf_ops; +extern int xfs_dir2_block_addname (struct xfs_da_args *args);extern int xfs_dir2_block_getdents (struct xfs_inode *dp,void *dirent,xfs_off_t *offset,filldir_t filldir);
@@ -45,7 +47,9 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,#else #define xfs_dir2_data_check (dp,bp)#endif -extern void xfs_dir2_data_write_verify (struct xfs_buf *bp); + +extern const struct xfs_buf_ops xfs_dir2_data_buf_ops; +extern int __xfs_dir2_data_check (struct xfs_inode *dp,struct xfs_buf *bp);extern int xfs_dir2_data_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t bno,xfs_daddr_t mapped_bno,struct xfs_buf **bpp);
@@ -73,8 +77,8 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp, xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);/* xfs_dir2_leaf.c */ -extern void xfs_dir2_leafn_read_verify (struct xfs_buf *bp); -extern void xfs_dir2_leafn_write_verify (struct xfs_buf *bp); +extern const struct xfs_buf_ops xfs_dir2_leafn_buf_ops; +extern int xfs_dir2_leafn_read (struct xfs_trans *tp,struct xfs_inode *dp,xfs_dablk_t fbno,xfs_daddr_t mappedbno,struct xfs_buf **bpp); extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
fs/xfs/xfs_dquot.c +10 -8
@@ -284,22 +284,24 @@ xfs_dquot_buf_verify( }static void -xfs_dquot_buf_write_verify ( +xfs_dquot_buf_read_verify (struct xfs_buf *bp) {xfs_dquot_buf_verify (bp); }void -xfs_dquot_buf_read_verify ( +xfs_dquot_buf_write_verify (struct xfs_buf *bp) {xfs_dquot_buf_verify (bp); - bp->b_pre_io = xfs_dquot_buf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_dquot_buf_ops = { + .verify_read = xfs_dquot_buf_read_verify, + .verify_write = xfs_dquot_buf_write_verify, +}; +/* * Allocate a block and fill it with dquots. * This is called when the bmapi finds a hole.
@@ -365,7 +367,7 @@ xfs_qm_dqalloc( error =xfs_buf_geterror (bp);if (error) goto error1; - bp->b_pre_io = xfs_dquot_buf_write_verify; + bp->b_ops = &xfs_dquot_buf_ops;/* * Make a chunk of dquots out of this buffer and log
@@ -435,7 +437,7 @@ xfs_qm_dqrepair(ASSERT (*bpp ==NULL );return XFS_ERROR (error); } - (*bpp)->b_pre_io = xfs_dquot_buf_write_verify; + (*bpp)->b_ops = &xfs_dquot_buf_ops;ASSERT (xfs_buf_islocked (*bpp)); d = (struct xfs_dqblk *)(*bpp)->b_addr;
@@ -534,7 +536,7 @@ xfs_qm_dqtobp( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, -0 , &bp, xfs_dquot_buf_read_verify); +0 , &bp, &xfs_dquot_buf_ops);if (error ==EFSCORRUPTED && (flags &XFS_QMOPT_DQREPAIR )) { xfs_dqid_t firstid = (xfs_dqid_t)map.br_startoff *
fs/xfs/xfs_dquot.h +2 -1
@@ -140,7 +140,6 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)extern int xfs_qm_dqread (struct xfs_mount *,xfs_dqid_t ,uint ,uint ,struct xfs_dquot **); -extern void xfs_dquot_buf_read_verify (struct xfs_buf *bp);extern void xfs_qm_dqdestroy (xfs_dquot_t *);extern int xfs_qm_dqflush (struct xfs_dquot *,struct xfs_buf **);extern void xfs_qm_dqunpin_wait (xfs_dquot_t *);
@@ -162,4 +161,6 @@ static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp) return dqp; } +extern const struct xfs_buf_ops xfs_dquot_buf_ops; +#endif /* __XFS_DQUOT_H__ */
fs/xfs/xfs_fsops.c +17 -12
@@ -119,7 +119,8 @@ xfs_growfs_get_hdr_buf(struct xfs_mount *mp, xfs_daddr_t blkno, size_t numblks, - int flags) + int flags, + const struct xfs_buf_ops *ops) { struct xfs_buf *bp;
@@ -130,6 +131,7 @@ xfs_growfs_get_hdr_buf(xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); bp->b_bn = blkno; bp->b_maps[0 ].bm_bn = blkno; + bp->b_ops = ops;return bp; }
@@ -217,12 +219,12 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AG_DADDR (mp, agno,XFS_AGF_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 , + &xfs_agf_buf_ops);if (!bp) { error =ENOMEM ; goto error0; } - bp->b_pre_io = xfs_agf_write_verify; agf =XFS_BUF_TO_AGF (bp); agf->agf_magicnum =cpu_to_be32 (XFS_AGF_MAGIC );
@@ -255,12 +257,12 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AG_DADDR (mp, agno,XFS_AGFL_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 , + &xfs_agfl_buf_ops);if (!bp) { error =ENOMEM ; goto error0; } - bp->b_pre_io = xfs_agfl_write_verify; agfl =XFS_BUF_TO_AGFL (bp);for (bucket =0 ; bucket <XFS_AGFL_SIZE (mp); bucket++)
@@ -276,12 +278,12 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 ); +XFS_FSS_TO_BB (mp,1 ),0 , + &xfs_agi_buf_ops);if (!bp) { error =ENOMEM ; goto error0; } - bp->b_pre_io = xfs_agi_write_verify; agi =XFS_BUF_TO_AGI (bp); agi->agi_magicnum =cpu_to_be32 (XFS_AGI_MAGIC );
@@ -306,7 +308,8 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AGB_TO_DADDR (mp, agno,XFS_BNO_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); +BTOBB (mp->m_sb.sb_blocksize),0 , + &xfs_allocbt_buf_ops);if (!bp) { error =ENOMEM ;
@@ -329,7 +332,8 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AGB_TO_DADDR (mp, agno,XFS_CNT_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); +BTOBB (mp->m_sb.sb_blocksize),0 , + &xfs_allocbt_buf_ops);if (!bp) { error =ENOMEM ; goto error0;
@@ -352,7 +356,8 @@ xfs_growfs_data_private(*/ bp =xfs_growfs_get_hdr_buf (mp,XFS_AGB_TO_DADDR (mp, agno,XFS_IBT_BLOCK (mp)), -BTOBB (mp->m_sb.sb_blocksize),0 ); +BTOBB (mp->m_sb.sb_blocksize),0 , + &xfs_inobt_buf_ops);if (!bp) { error =ENOMEM ; goto error0;
@@ -448,14 +453,14 @@ xfs_growfs_data_private( error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)),XFS_FSS_TO_BB (mp,1 ),0 , &bp, - xfs_sb_read_verify); + &xfs_sb_buf_ops); }else { bp =xfs_trans_get_buf (NULL , mp->m_ddev_targp,XFS_AGB_TO_DADDR (mp, agno,XFS_SB_BLOCK (mp)),XFS_FSS_TO_BB (mp,1 ),0 );if (bp) { + bp->b_ops = &xfs_sb_buf_ops;xfs_buf_zero (bp,0 ,BBTOB (bp->b_length)); - bp->b_pre_io = xfs_sb_write_verify; }else error =ENOMEM ; }
fs/xfs/xfs_ialloc.c +10 -8
@@ -210,7 +210,7 @@ xfs_ialloc_inode_init(* to log a whole cluster of inodes instead of all the * individual transactions causing a lot of log traffic. */ - fbuf->b_pre_io = xfs_inode_buf_write_verify; + fbuf->b_ops = &xfs_inode_buf_ops;xfs_buf_zero (fbuf,0 , ninodes << mp->m_sb.sb_inodelog);for (i =0 ; i < ninodes; i++) {int ioffset = i << mp->m_sb.sb_inodelog;
@@ -1505,23 +1505,25 @@ xfs_agi_verify(xfs_check_agi_unlinked (agi); } -void -xfs_agi_write_verify ( +static void +xfs_agi_read_verify (struct xfs_buf *bp) {xfs_agi_verify (bp); }static void -xfs_agi_read_verify ( +xfs_agi_write_verify (struct xfs_buf *bp) {xfs_agi_verify (bp); - bp->b_pre_io = xfs_agi_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_agi_buf_ops = { + .verify_read = xfs_agi_read_verify, + .verify_write = xfs_agi_write_verify, +}; +/* * Read in the allocation group header (inode allocation section) */
@@ -1538,7 +1540,7 @@ xfs_read_agi( error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp,XFS_AG_DADDR (mp, agno,XFS_AGI_DADDR (mp)), -XFS_FSS_TO_BB (mp,1 ),0 , bpp, xfs_agi_read_verify); +XFS_FSS_TO_BB (mp,1 ),0 , bpp, &xfs_agi_buf_ops);if (error)return error;
fs/xfs/xfs_ialloc.h +1 -1
@@ -150,6 +150,6 @@ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,int xfs_inobt_get_rec (struct xfs_btree_cur *cur,xfs_inobt_rec_incore_t *rec,int *stat); -void xfs_agi_write_verify (struct xfs_buf *bp); +extern const struct xfs_buf_ops xfs_agi_buf_ops;#endif /* __XFS_IALLOC_H__ */
fs/xfs/xfs_ialloc_btree.c +9 -8
@@ -217,22 +217,24 @@ xfs_inobt_verify( }static void -xfs_inobt_write_verify ( +xfs_inobt_read_verify (struct xfs_buf *bp) {xfs_inobt_verify (bp); } -void -xfs_inobt_read_verify ( +static void +xfs_inobt_write_verify (struct xfs_buf *bp) {xfs_inobt_verify (bp); - bp->b_pre_io = xfs_inobt_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_inobt_buf_ops = { + .verify_read = xfs_inobt_read_verify, + .verify_write = xfs_inobt_write_verify, +}; +#ifdef DEBUG STATIC int xfs_inobt_keys_inorder(
@@ -270,8 +272,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = { .init_rec_from_cur = xfs_inobt_init_rec_from_cur, .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, .key_diff = xfs_inobt_key_diff, - .read_verify = xfs_inobt_read_verify, - .write_verify = xfs_inobt_write_verify, + .buf_ops = &xfs_inobt_buf_ops, #ifdef DEBUG .keys_inorder = xfs_inobt_keys_inorder, .recs_inorder = xfs_inobt_recs_inorder,
fs/xfs/xfs_ialloc_btree.h +2 -0
@@ -109,4 +109,6 @@ extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *, struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t);extern int xfs_inobt_maxrecs (struct xfs_mount *,int ,int ); +extern const struct xfs_buf_ops xfs_inobt_buf_ops; +#endif /* __XFS_IALLOC_BTREE_H__ */
fs/xfs/xfs_inode.c +13 -9
@@ -420,23 +420,27 @@ xfs_inode_buf_verify(xfs_inobp_check (mp, bp); } -void -xfs_inode_buf_write_verify ( + +static void +xfs_inode_buf_read_verify (struct xfs_buf *bp) {xfs_inode_buf_verify (bp); } -void -xfs_inode_buf_read_verify ( +static void +xfs_inode_buf_write_verify (struct xfs_buf *bp) {xfs_inode_buf_verify (bp); - bp->b_pre_io = xfs_inode_buf_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); } +const struct xfs_buf_ops xfs_inode_buf_ops = { + .verify_read = xfs_inode_buf_read_verify, + .verify_write = xfs_inode_buf_write_verify, +}; + +/* * This routine is called to map an inode to the buffer containing the on-disk * version of the inode. It returns a pointer to the buffer containing the
@@ -462,7 +466,7 @@ xfs_imap_to_bp( buf_flags |=XBF_UNMAPPED ; error =xfs_trans_read_buf (mp, tp, mp->m_ddev_targp, imap->im_blkno, (int )imap->im_len, buf_flags, &bp, - xfs_inode_buf_read_verify); + &xfs_inode_buf_ops);if (error) {if (error ==EAGAIN ) {ASSERT (buf_flags &XBF_TRYLOCK );
@@ -1792,7 +1796,7 @@ xfs_ifree_cluster(* want it to fail. We can acheive this by adding a write * verifier to the buffer. */ - bp->b_pre_io = xfs_inode_buf_write_verify; + bp->b_ops = &xfs_inode_buf_ops;/* * Walk the inodes already attached to the buffer and mark them
fs/xfs/xfs_inode.h +1 -2
@@ -554,8 +554,6 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *, struct xfs_buf **, uint, uint);int xfs_iread (struct xfs_mount *,struct xfs_trans *,struct xfs_inode *,uint ); -void xfs_inode_buf_read_verify (struct xfs_buf *); -void xfs_inode_buf_write_verify (struct xfs_buf *);void xfs_dinode_to_disk (struct xfs_dinode *,struct xfs_icdinode *);void xfs_idestroy_fork (struct xfs_inode *,int );
@@ -600,5 +598,6 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);extern struct kmem_zone *xfs_ifork_zone;extern struct kmem_zone *xfs_inode_zone;extern struct kmem_zone *xfs_ili_zone; +extern const struct xfs_buf_ops xfs_inode_buf_ops;#endif /* __XFS_INODE_H__ */
fs/xfs/xfs_itable.c +1 -1
@@ -397,7 +397,7 @@ xfs_bulkstat( & ~r.ir_free)xfs_btree_reada_bufs (mp, agno, agbno, nbcluster, - xfs_inode_buf_read_verify); + &xfs_inode_buf_ops); } irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount;
fs/xfs/xfs_log_recover.c +1 -1
@@ -3699,7 +3699,7 @@ xlog_do_recover(ASSERT (!(XFS_BUF_ISWRITE (bp)));XFS_BUF_READ (bp);XFS_BUF_UNASYNC (bp); - bp->b_iodone = xfs_sb_read_verify; + bp->b_ops = &xfs_sb_buf_ops;xfsbdstrat (log->l_mp, bp); error =xfs_buf_iowait (bp);if (error) {
fs/xfs/xfs_mount.c +21 -14
@@ -631,21 +631,11 @@ xfs_sb_verify(xfs_buf_ioerror (bp, error); } -void -xfs_sb_write_verify ( -struct xfs_buf *bp) -{ -xfs_sb_verify (bp); -} - -void +static void xfs_sb_read_verify (struct xfs_buf *bp) {xfs_sb_verify (bp); - bp->b_pre_io = xfs_sb_write_verify; - bp->b_iodone =NULL ; -xfs_buf_ioend (bp,0 ); }/*
@@ -654,7 +644,7 @@ xfs_sb_read_verify(* If we find an XFS superblock, the run a normal, noisy mount because we are * really going to mount it and want to know about errors. */ -void +static void xfs_sb_quiet_read_verify (struct xfs_buf *bp) {
@@ -671,6 +661,23 @@ xfs_sb_quiet_read_verify(xfs_buf_ioerror (bp,EFSCORRUPTED ); } +static void +xfs_sb_write_verify ( +struct xfs_buf *bp) +{ +xfs_sb_verify (bp); +} + +const struct xfs_buf_ops xfs_sb_buf_ops = { + .verify_read = xfs_sb_read_verify, + .verify_write = xfs_sb_write_verify, +}; + +static const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { + .verify_read = xfs_sb_quiet_read_verify, + .verify_write = xfs_sb_write_verify, +}; +/* * xfs_readsb *
@@ -697,8 +704,8 @@ xfs_readsb(xfs_mount_t *mp, int flags) reread: bp =xfs_buf_read_uncached (mp->m_ddev_targp,XFS_SB_DADDR ,BTOBB (sector_size),0 , - loud ? xfs_sb_read_verify - : xfs_sb_quiet_read_verify); + loud ? &xfs_sb_buf_ops + : &xfs_sb_quiet_buf_ops);if (!bp) {if (loud)xfs_warn (mp,"SB buffer read failed" );
fs/xfs/xfs_mount.h +2 -2
@@ -385,12 +385,12 @@ extern void xfs_set_low_space_thresholds(struct xfs_mount *);#endif /* __KERNEL__ */ -extern void xfs_sb_read_verify (struct xfs_buf *); -extern void xfs_sb_write_verify (struct xfs_buf *bp);extern void xfs_mod_sb (struct xfs_trans *,__int64_t );extern int xfs_initialize_perag (struct xfs_mount *,xfs_agnumber_t ,xfs_agnumber_t *);extern void xfs_sb_from_disk (struct xfs_sb *,struct xfs_dsb *);extern void xfs_sb_to_disk (struct xfs_dsb *,struct xfs_sb *,__int64_t ); +extern const struct xfs_buf_ops xfs_sb_buf_ops; +#endif /* __XFS_MOUNT_H__ */
fs/xfs/xfs_qm.c +1 -1
@@ -893,7 +893,7 @@ xfs_qm_dqiter_bufs( error =xfs_trans_read_buf (mp,NULL , mp->m_ddev_targp,XFS_FSB_TO_DADDR (mp, bno), mp->m_quotainfo->qi_dqchunklen,0 , &bp, - xfs_dquot_buf_read_verify); + &xfs_dquot_buf_ops);if (error)break ;
fs/xfs/xfs_trans.h +3 -3
@@ -474,7 +474,7 @@ int xfs_trans_read_buf_map(struct xfs_mount *mp, struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp, - xfs_buf_iodone_t verify); + const struct xfs_buf_ops *ops);static inline int xfs_trans_read_buf(
@@ -485,11 +485,11 @@ xfs_trans_read_buf(int numblks, xfs_buf_flags_t flags, struct xfs_buf **bpp, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) {DEFINE_SINGLE_BUF_MAP (map ,blkno ,numblks );return xfs_trans_read_buf_map (mp, tp, target, &map,1 , - flags, bpp, verify); + flags, bpp, ops); }struct xfs_buf *xfs_trans_getsb (xfs_trans_t *,struct xfs_mount *,int );
fs/xfs/xfs_trans_buf.c +4 -4
@@ -258,7 +258,7 @@ xfs_trans_read_buf_map(int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp, - xfs_buf_iodone_t verify) + const struct xfs_buf_ops *ops) { xfs_buf_t *bp;xfs_buf_log_item_t *bip;
@@ -266,7 +266,7 @@ xfs_trans_read_buf_map( *bpp =NULL ;if (!tp) { - bp =xfs_buf_read_map (target, map, nmaps, flags, verify); + bp =xfs_buf_read_map (target, map, nmaps, flags, ops);if (!bp)return (flags &XBF_TRYLOCK ) ?EAGAIN :XFS_ERROR (ENOMEM );
@@ -315,7 +315,7 @@ xfs_trans_read_buf_map(ASSERT (!XFS_BUF_ISASYNC (bp));ASSERT (bp->b_iodone ==NULL );XFS_BUF_READ (bp); - bp->b_iodone = verify; + bp->b_ops = ops;xfsbdstrat (tp->t_mountp, bp); error =xfs_buf_iowait (bp);if (error) {
@@ -352,7 +352,7 @@ xfs_trans_read_buf_map(return 0 ; } - bp =xfs_buf_read_map (target, map, nmaps, flags, verify); + bp =xfs_buf_read_map (target, map, nmaps, flags, ops);if (bp ==NULL ) { *bpp =NULL ; return (flags & XBF_TRYLOCK) ?
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 31/32 xfs: add CRC infrastructure
In reply to Dave ChinnerFrom: Christoph Hellwig <[email protected]>
- add a mount feature bit for CRC enabled filesystems
- add some helpers for generating and verifying the CRCs
- add a copy_uuid helper
The checksumming helpers are losely based on similar ones in sctp, all other bits come from Dave Chinner.
--- fs/xfs/Kconfig | 1 + fs/xfs/uuid.h | 6 +++++ fs/xfs/xfs_cksum.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_linux.h | 1 + fs/xfs/xfs_sb.h | 10 ++++++++- 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 fs/xfs/xfs_cksum.h
fs/xfs/Kconfig +1 -0
@@ -2,6 +2,7 @@ config XFS_FS tristate "XFS filesystem support" depends on BLOCK select EXPORTFS + select LIBCRC32C help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can
fs/xfs/uuid.h +6 -0
@@ -26,4 +26,10 @@ extern int uuid_is_nil(uuid_t *uuid);extern int uuid_equal (uuid_t *uuid1,uuid_t *uuid2);extern void uuid_getnodeuniq (uuid_t *uuid,int fsid [2 ]); +static inline void +uuid_copy (uuid_t *dst,uuid_t *src) +{ +memcpy (dst, src,sizeof (uuid_t)); +} +#endif /* __XFS_SUPPORT_UUID_H__ */
fs/xfs/xfs_cksum.h new file +63 -0
63 lines not on this page · raw message
fs/xfs/xfs_linux.h +1 -0
@@ -44,6 +44,7 @@#include <linux/kernel.h> #include <linux/blkdev.h> #include <linux/slab.h> +#include <linux/crc32c.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/file.h>
fs/xfs/xfs_sb.h +9 -1
@@ -81,11 +81,13 @@ struct xfs_mount;#define XFS_SB_VERSION2_ATTR2BIT 0x00000008/* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010/* parent pointers */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080/* 32 bit project id */ +#define XFS_SB_VERSION2_CRCBIT 0x00000100/* metadata CRCs */ #define XFS_SB_VERSION2_OKREALFBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ XFS_SB_VERSION2_ATTR2BIT | \ - XFS_SB_VERSION2_PROJID32BIT) + XFS_SB_VERSION2_PROJID32BIT | \ + XFS_SB_VERSION2_CRCBIT)#define XFS_SB_VERSION2_OKSASHFBITS \ (0)#define XFS_SB_VERSION2_OKREALBITS \
@@ -503,6 +505,12 @@ static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp) (sbp->sb_features2 &XFS_SB_VERSION2_PROJID32BIT ); } +static inline int xfs_sb_version_hascrc (xfs_sb_t *sbp) +{ +return (xfs_sb_version_hasmorebits (sbp) && + (sbp->sb_features2 &XFS_SB_VERSION2_CRCBIT )); +} +/* * end of superblock version macros */
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH 31/32] xfs: add CRC infrastructure
Quoted 6 lines · Dave Chinner
From: Christoph Hellwig<[email protected]>
- add a mount feature bit for CRC enabled filesystems
- add some helpers for generating and verifying the CRCs
- add acopy_uuidhelper
Quoted 6 lines
The checksumming helpers are losely based on similar ones in sctp, all other bits come from Dave Chinner.
Signed-off-by Christoph Hellwig<[email protected]>Signed-off-by Dave Chinner<[email protected]>---
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v2 31/32 xfs: add CRC infrastructure
In reply to Dave Chinnerxfs: add CRC infrastructure
From: Christoph Hellwig <[email protected]>
- add a mount feature bit for CRC enabled filesystems
- add some helpers for generating and verifying the CRCs
- add a copy_uuid helper
The checksumming helpers are losely based on similar ones in sctp, all other bits come from Dave Chinner.
---
Version 2:
- Make sure that CRC enable filesystems are not mountable at this point in time.
fs/xfs/Kconfig | 1 + fs/xfs/uuid.h | 6 +++++ fs/xfs/xfs_cksum.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_linux.h | 1 + fs/xfs/xfs_sb.h | 7 ++++++ 5 files changed, 78 insertions(+)
fs/xfs/Kconfig +1 -0
@@ -2,6 +2,7 @@ config XFS_FS tristate "XFS filesystem support" depends on BLOCK select EXPORTFS + select LIBCRC32C help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can
fs/xfs/uuid.h +6 -0
@@ -26,4 +26,10 @@ extern int uuid_is_nil(uuid_t *uuid);extern int uuid_equal (uuid_t *uuid1,uuid_t *uuid2);extern void uuid_getnodeuniq (uuid_t *uuid,int fsid [2 ]); +static inline void +uuid_copy (uuid_t *dst,uuid_t *src) +{ +memcpy (dst, src,sizeof (uuid_t)); +} +#endif /* __XFS_SUPPORT_UUID_H__ */
fs/xfs/xfs_cksum.h new file +63 -0
63 lines not on this page · raw message
fs/xfs/xfs_linux.h +1 -0
@@ -44,6 +44,7 @@#include <linux/kernel.h> #include <linux/blkdev.h> #include <linux/slab.h> +#include <linux/crc32c.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/file.h>
fs/xfs/xfs_sb.h +7 -0
@@ -81,6 +81,7 @@ struct xfs_mount;#define XFS_SB_VERSION2_ATTR2BIT 0x00000008/* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010/* parent pointers */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080/* 32 bit project id */ +#define XFS_SB_VERSION2_CRCBIT 0x00000100/* metadata CRCs */ #define XFS_SB_VERSION2_OKREALFBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
@@ -503,6 +504,12 @@ static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp) (sbp->sb_features2 &XFS_SB_VERSION2_PROJID32BIT ); } +static inline int xfs_sb_version_hascrc (xfs_sb_t *sbp) +{ +return (xfs_sb_version_hasmorebits (sbp) && + (sbp->sb_features2 &XFS_SB_VERSION2_CRCBIT )); +} +/* * end of superblock version macros */
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH 32/32 xfs: add CRC checks to the log
In reply to Dave ChinnerFrom: Christoph Hellwig <[email protected]>
Implement CRCs for the log buffers. We re-use a field in struct xlog_rec_header that was used for a weak checksum of the log buffer payload in debug builds before.
The new checksumming uses the crc32c checksum we will use elsewhere in XFS, and also protects the record header and addition cycle data.
Due to this there are some interesting changes in xlog_sync, as we need to do the cycle wrapping for the split buffer case much earlier, as we would touch the buffer after generating the checksum otherwise.
The CRC calculation is always enabled, even for non-CRC filesystems, as adding this CRC does not change the log format. On non-CRC filesystems, only issue an alert if a CRC mismatch is found and allow recovery to continue - this will act as an indicator that log recovery problems are a result of log corruption. On CRC enabled filesystems, however, log recovery will fail.
Note that existing debug kernels will write a simple checksum value to the log, so the first time this is run on a filesystem taht was last used on a debug kernel it will through CRC mismatch warning errors. These can be ignored.
Initially based on a patch from Dave Chinner, then modified significantly by Christoph Hellwig. Modified again by Dave Chinner to get to this version.
--- fs/xfs/xfs_log.c | 132 ++++++++++++++++++++++++++++++++++++++-------- fs/xfs/xfs_log_priv.h | 11 ++-- fs/xfs/xfs_log_recover.c | 132 ++++++++++++++++++++++------------------------ 3 files changed, 176 insertions(+), 99 deletions(-)
fs/xfs/xfs_log.c +109 -23
@@ -35,6 +35,7 @@#include "xfs_inode.h" #include "xfs_trace.h" #include "xfs_fsops.h" +#include "xfs_cksum.h" kmem_zone_t *xfs_log_ticket_zone;
@@ -1490,6 +1491,84 @@ xlog_grant_push_ail( }/* +* Stamp cycle number in every block +*/ +STATIC void +xlog_pack_data ( +struct xlog *log, +struct xlog_in_core *iclog, +int roundoff) +{ +int i, j, k; +int size = iclog->ic_offset + roundoff; +__be32 cycle_lsn; +xfs_caddr_t dp; + + cycle_lsn =CYCLE_LSN_DISK (iclog->ic_header.h_lsn); + + dp = iclog->ic_datap; +for (i =0 ; i <BTOBB (size); i++) { +if (i >= (XLOG_HEADER_CYCLE_SIZE /BBSIZE )) +break ; + iclog->ic_header.h_cycle_data[i] = *(__be32 *)dp; + *(__be32 *)dp = cycle_lsn; + dp +=BBSIZE ; + } + +if (xfs_sb_version_haslogv2 (&log->l_mp->m_sb)) { +xlog_in_core_2_t *xhdr = iclog->ic_data; + +for ( ; i <BTOBB (size); i++) { + j = i / (XLOG_HEADER_CYCLE_SIZE /BBSIZE ); + k = i % (XLOG_HEADER_CYCLE_SIZE /BBSIZE ); + xhdr[j].hic_xheader.xh_cycle_data[k] = *(__be32 *)dp; + *(__be32 *)dp = cycle_lsn; + dp +=BBSIZE ; + } + +for (i =1 ; i < log->l_iclog_heads; i++) + xhdr[i].hic_xheader.xh_cycle = cycle_lsn; + } +} + +/* +* Calculate the checksum for a log buffer. +* +* This is a little more complicated than it should be because the various +* headers and the actual data are non-contiguous. +*/ +__be32 +xlog_cksum ( +struct xlog *log, +struct xlog_rec_header *rhead, +char *dp, +int size) +{ +__uint32_t crc; + +/* first generate the crc for the record header ... */ + crc =xfs_start_cksum ((char *)rhead, +sizeof (struct xlog_rec_header ), + offsetof(struct xlog_rec_header , h_crc)); + +/* ... then for additional cycle data for v2 logs ... */ +if (xfs_sb_version_haslogv2 (&log->l_mp->m_sb)) { +union xlog_in_core2 *xhdr = (union xlog_in_core2 *)rhead; +int i; + +for (i =1 ; i < log->l_iclog_heads; i++) { + crc =crc32c (crc, &xhdr[i].hic_xheader, +sizeof (struct xlog_rec_ext_header )); + } + } + +/* ... and finally for the payload */ + crc =crc32c (crc, dp, size); + +return xfs_end_cksum (crc); +} + +/* * The bdstrat callback function for log bufs. This gives us a central * place to trap bufs in case we get hit by a log I/O error and need to * shutdown. Actually, in practice, even when we didn't get a log error,
@@ -1549,7 +1628,6 @@ xlog_sync(struct xlog *log, struct xlog_in_core *iclog) { - xfs_caddr_t dptr; /* pointer to byte sized element */ xfs_buf_t *bp;int i;uint count;/* byte count of bwrite */
@@ -1558,6 +1636,7 @@ xlog_sync(int split =0 ;/* split write into two regions */ int error;int v2 =xfs_sb_version_haslogv2 (&log->l_mp->m_sb); +int size;XFS_STATS_INC (xs_log_writes);ASSERT (atomic_read (&iclog->ic_refcnt) ==0 );
@@ -1588,13 +1667,10 @@ xlog_sync(xlog_pack_data (log, iclog, roundoff);/* real byte length */ -if (v2) { - iclog->ic_header.h_len = -cpu_to_be32 (iclog->ic_offset + roundoff); - }else { - iclog->ic_header.h_len = -cpu_to_be32 (iclog->ic_offset); - } + size = iclog->ic_offset; +if (v2) + size += roundoff; + iclog->ic_header.h_len =cpu_to_be32 (size); bp = iclog->ic_bp;XFS_BUF_SET_ADDR (bp,BLOCK_LSN (be64_to_cpu (iclog->ic_header.h_lsn)));
@@ -1603,12 +1679,36 @@ xlog_sync(/* Do we need to split this write into 2 parts? */ if (XFS_BUF_ADDR (bp) +BTOBB (count) > log->l_logBBsize) { +char *dptr; + split = count - (BBTOB (log->l_logBBsize -XFS_BUF_ADDR (bp))); count =BBTOB (log->l_logBBsize -XFS_BUF_ADDR (bp)); - iclog->ic_bwritecnt =2 ;/* split into 2 writes */ + iclog->ic_bwritecnt =2 ; + +/* +* Bump the cycle numbers at the start of each block in the +* part of the iclog that ends up in the buffer that gets +* written to the start of the log. +* +* Watch out for the header magic number case, though. +*/ + dptr = (char *)&iclog->ic_header + count; +for (i =0 ; i < split; i +=BBSIZE ) { +__uint32_t cycle =be32_to_cpu (*(__be32 *)dptr); +if (++cycle ==XLOG_HEADER_MAGIC_NUM ) + cycle++; + *(__be32 *)dptr =cpu_to_be32 (cycle); + + dptr +=BBSIZE ; + } }else { iclog->ic_bwritecnt =1 ; } + +/* calculcate the checksum */ + iclog->ic_header.h_crc =xlog_cksum (log, &iclog->ic_header, + iclog->ic_datap, size); + bp->b_io_length =BTOBB (count); bp->b_fspriv = iclog;XFS_BUF_ZEROFLAGS (bp);
@@ -1662,19 +1762,6 @@ xlog_sync( bp->b_flags |=XBF_SYNCIO ;if (log->l_mp->m_flags &XFS_MOUNT_BARRIER ) bp->b_flags |=XBF_FUA ; - dptr = bp->b_addr; -/* -* Bump the cycle numbers at the start of each block -* since this part of the buffer is at the start of -* a new cycle. Watch out for the header magic number -* case, though. -*/ -for (i =0 ; i < split; i +=BBSIZE ) { -be32_add_cpu ((__be32 *)dptr,1 ); -if (be32_to_cpu (*(__be32 *)dptr) ==XLOG_HEADER_MAGIC_NUM ) -be32_add_cpu ((__be32 *)dptr,1 ); - dptr +=BBSIZE ; - }ASSERT (XFS_BUF_ADDR (bp) <= log->l_logBBsize-1 );ASSERT (XFS_BUF_ADDR (bp) +BTOBB (count) <= log->l_logBBsize);
@@ -1691,7 +1778,6 @@ xlog_sync(return 0 ; }/* xlog_sync */ -/* * Deallocate a log structure */
fs/xfs/xfs_log_priv.h +4 -7
@@ -139,7 +139,6 @@ static inline uint xlog_get_client_id(__be32 i)/* * Flags for log structure */ -#define XLOG_CHKSUM_MISMATCH 0x1/* used only during recovery */ #define XLOG_ACTIVE_RECOVERY 0x2/* in the middle of recovery */ #define XLOG_RECOVERY_NEEDED 0x4/* log was recovered */ #define XLOG_IO_ERROR 0x8/* log hit an I/O error, and being
@@ -291,7 +290,7 @@ typedef struct xlog_rec_header {__be32 h_len;/* len in bytes; should be 64-bit aligned: 4 */ __be64 h_lsn;/* lsn of this LR : 8 */ __be64 h_tail_lsn;/* lsn of 1st LR w/ buffers not committed: 8 */ -__be32 h_chksum;/* may not be used; non-zero if used : 4 */ +__le32 h_crc;/* crc of log record : 4 */ __be32 h_prev_block;/* block number to previous LR : 4 */ __be32 h_num_logops;/* number of log operations in this LR : 4 */ __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE /BBSIZE ];
@@ -555,11 +554,9 @@ xlog_recover(extern int xlog_recover_finish (struct xlog *log); -extern void -xlog_pack_data ( -struct xlog *log, -struct xlog_in_core *iclog, -int ); + +extern __be32 xlog_cksum (struct xlog *log,struct xlog_rec_header *rhead, +char *dp,int size);extern kmem_zone_t *xfs_log_ticket_zone; struct xlog_ticket *
fs/xfs/xfs_log_recover.c +63 -69
182 lines not on this page · raw message
Signature · 6 lines
1.7.10 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs