Commit 1a485fc1 authored by Allison Collins's avatar Allison Collins Committed by Darrick J. Wong

xfs: Factor out new helper functions xfs_attr_rmtval_set

Break xfs_attr_rmtval_set into two helper functions
xfs_attr_rmt_find_hole and xfs_attr_rmtval_set_value.
xfs_attr_rmtval_set rolls the transaction between the helpers, but
delayed operations cannot.  We will use the helpers later when
constructing new delayed attribute routines.
Signed-off-by: default avatarAllison Collins <allison.henderson@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChandan Rajendra <chandanrlinux@gmail.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Acked-by: default avatarDave Chinner <dchinner@redhat.com>
parent deed9512
...@@ -440,32 +440,23 @@ xfs_attr_rmtval_get( ...@@ -440,32 +440,23 @@ xfs_attr_rmtval_get(
} }
/* /*
* Write the value associated with an attribute into the out-of-line buffer * Find a "hole" in the attribute address space large enough for us to drop the
* that we have defined for it. * new attribute's value into
*/ */
int STATIC int
xfs_attr_rmtval_set( xfs_attr_rmt_find_hole(
struct xfs_da_args *args) struct xfs_da_args *args)
{ {
struct xfs_inode *dp = args->dp; struct xfs_inode *dp = args->dp;
struct xfs_mount *mp = dp->i_mount; struct xfs_mount *mp = dp->i_mount;
struct xfs_bmbt_irec map;
xfs_dablk_t lblkno;
xfs_fileoff_t lfileoff = 0;
uint8_t *src = args->value;
int blkcnt;
int valuelen;
int nmap;
int error; int error;
int offset = 0; int blkcnt;
xfs_fileoff_t lfileoff = 0;
trace_xfs_attr_rmtval_set(args);
/* /*
* Find a "hole" in the attribute address space large enough for * Because CRC enable attributes have headers, we can't just do a
* us to drop the new attribute's value into. Because CRC enable * straight byte to FSB conversion and have to take the header space
* attributes have headers, we can't just do a straight byte to FSB * into account.
* conversion and have to take the header space into account.
*/ */
blkcnt = xfs_attr3_rmt_blocks(mp, args->rmtvaluelen); blkcnt = xfs_attr3_rmt_blocks(mp, args->rmtvaluelen);
error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
...@@ -473,48 +464,26 @@ xfs_attr_rmtval_set( ...@@ -473,48 +464,26 @@ xfs_attr_rmtval_set(
if (error) if (error)
return error; return error;
args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff; args->rmtblkno = (xfs_dablk_t)lfileoff;
args->rmtblkcnt = blkcnt; args->rmtblkcnt = blkcnt;
/* return 0;
* Roll through the "value", allocating blocks on disk as required. }
*/
while (blkcnt > 0) {
/*
* Allocate a single extent, up to the size of the value.
*
* Note that we have to consider this a data allocation as we
* write the remote attribute without logging the contents.
* Hence we must ensure that we aren't using blocks that are on
* the busy list so that we don't overwrite blocks which have
* recently been freed but their transactions are not yet
* committed to disk. If we overwrite the contents of a busy
* extent and then crash then the block may not contain the
* correct metadata after log recovery occurs.
*/
nmap = 1;
error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map,
&nmap);
if (error)
return error;
error = xfs_defer_finish(&args->trans);
if (error)
return error;
ASSERT(nmap == 1);
ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
(map.br_startblock != HOLESTARTBLOCK));
lblkno += map.br_blockcount;
blkcnt -= map.br_blockcount;
/* STATIC int
* Start the next trans in the chain. xfs_attr_rmtval_set_value(
*/ struct xfs_da_args *args)
error = xfs_trans_roll_inode(&args->trans, dp); {
if (error) struct xfs_inode *dp = args->dp;
return error; struct xfs_mount *mp = dp->i_mount;
} struct xfs_bmbt_irec map;
xfs_dablk_t lblkno;
uint8_t *src = args->value;
int blkcnt;
int valuelen;
int nmap;
int error;
int offset = 0;
/* /*
* Roll through the "value", copying the attribute value to the * Roll through the "value", copying the attribute value to the
...@@ -594,6 +563,72 @@ xfs_attr_rmtval_stale( ...@@ -594,6 +563,72 @@ xfs_attr_rmtval_stale(
return 0; return 0;
} }
/*
* Write the value associated with an attribute into the out-of-line buffer
* that we have defined for it.
*/
int
xfs_attr_rmtval_set(
struct xfs_da_args *args)
{
struct xfs_inode *dp = args->dp;
struct xfs_bmbt_irec map;
xfs_dablk_t lblkno;
int blkcnt;
int nmap;
int error;
trace_xfs_attr_rmtval_set(args);
error = xfs_attr_rmt_find_hole(args);
if (error)
return error;
blkcnt = args->rmtblkcnt;
lblkno = (xfs_dablk_t)args->rmtblkno;
/*
* Roll through the "value", allocating blocks on disk as required.
*/
while (blkcnt > 0) {
/*
* Allocate a single extent, up to the size of the value.
*
* Note that we have to consider this a data allocation as we
* write the remote attribute without logging the contents.
* Hence we must ensure that we aren't using blocks that are on
* the busy list so that we don't overwrite blocks which have
* recently been freed but their transactions are not yet
* committed to disk. If we overwrite the contents of a busy
* extent and then crash then the block may not contain the
* correct metadata after log recovery occurs.
*/
nmap = 1;
error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno,
blkcnt, XFS_BMAPI_ATTRFORK, args->total, &map,
&nmap);
if (error)
return error;
error = xfs_defer_finish(&args->trans);
if (error)
return error;
ASSERT(nmap == 1);
ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
(map.br_startblock != HOLESTARTBLOCK));
lblkno += map.br_blockcount;
blkcnt -= map.br_blockcount;
/*
* Start the next trans in the chain.
*/
error = xfs_trans_roll_inode(&args->trans, dp);
if (error)
return error;
}
return xfs_attr_rmtval_set_value(args);
}
/* /*
* Remove the value associated with an attribute by deleting the * Remove the value associated with an attribute by deleting the
* out-of-line buffer that it is stored on. * out-of-line buffer that it is stored on.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment