From 73fdb01e2882cae3515a47b44ba32ec2408a916b Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 May 2013 18:02:04 +1000 Subject: [PATCH] --- yaml --- r: 376479 b: refs/heads/master c: 58a72281555bf301f6dff24db2db205c87ef8db1 h: refs/heads/master i: 376477: 7b8bb7bfd2c26c4e2cdea4a63fd554e15a518be5 376475: 3439cbe0f0632b9c13b4d070fd03e18f24db1cb5 376471: a31b3ad91fa519c3e2f341cb4a10007ed1aab155 376463: e9da356f64b0558cabd4920bca915d38d9ebaa9b 376447: 8407caa030f392144efd434e9af9a6ab8b79aa56 v: v3 --- [refs] | 2 +- trunk/fs/xfs/xfs_attr_remote.c | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index e1c46a3da36d..693efb6be06b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 26f714450c3907ce07c41a0bd1bea40368e0b4da +refs/heads/master: 58a72281555bf301f6dff24db2db205c87ef8db1 diff --git a/trunk/fs/xfs/xfs_attr_remote.c b/trunk/fs/xfs/xfs_attr_remote.c index e207bf0004b6..d8bcb2d742d1 100644 --- a/trunk/fs/xfs/xfs_attr_remote.c +++ b/trunk/fs/xfs/xfs_attr_remote.c @@ -468,19 +468,25 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) mp = args->dp->i_mount; /* - * Roll through the "value", invalidating the attribute value's - * blocks. + * Roll through the "value", invalidating the attribute value's blocks. + * Note that args->rmtblkcnt is the minimum number of data blocks we'll + * see for a CRC enabled remote attribute. Each extent will have a + * header, and so we may have more blocks than we realise here. If we + * fail to map the blocks correctly, we'll have problems with the buffer + * lookups. */ lblkno = args->rmtblkno; - valuelen = args->rmtblkcnt; + valuelen = args->valuelen; + blkcnt = xfs_attr3_rmt_blocks(mp, valuelen); while (valuelen > 0) { + int dblkcnt; + /* * Try to remember where we decided to put the value. */ nmap = 1; error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, - args->rmtblkcnt, &map, &nmap, - XFS_BMAPI_ATTRFORK); + blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK); if (error) return(error); ASSERT(nmap == 1); @@ -488,28 +494,31 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args) (map.br_startblock != HOLESTARTBLOCK)); dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), - blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); + dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); /* * If the "remote" value is in the cache, remove it. */ - bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt, XBF_TRYLOCK); + bp = xfs_incore(mp->m_ddev_targp, dblkno, dblkcnt, XBF_TRYLOCK); if (bp) { xfs_buf_stale(bp); xfs_buf_relse(bp); bp = NULL; } - valuelen -= map.br_blockcount; + valuelen -= XFS_ATTR3_RMT_BUF_SPACE(mp, + XFS_FSB_TO_B(mp, map.br_blockcount)); lblkno += map.br_blockcount; + blkcnt -= map.br_blockcount; + blkcnt = max(blkcnt, xfs_attr3_rmt_blocks(mp, valuelen)); } /* * Keep de-allocating extents until the remote-value region is gone. */ + blkcnt = lblkno - args->rmtblkno; lblkno = args->rmtblkno; - blkcnt = args->rmtblkcnt; done = 0; while (!done) { xfs_bmap_init(args->flist, args->firstblock);