Commit 8f502a40 authored by Allison Henderson's avatar Allison Henderson

xfs: Add delay ready attr set routines

This patch modifies the attr set routines to be delay ready. This means
they no longer roll or commit transactions, but instead return -EAGAIN
to have the calling routine roll and refresh the transaction.  In this
series, xfs_attr_set_args has become xfs_attr_set_iter, which uses a
state machine like switch to keep track of where it was when EAGAIN was
returned. See xfs_attr.h for a more detailed diagram of the states.

Two new helper functions have been added: xfs_attr_rmtval_find_space and
xfs_attr_rmtval_set_blk.  They provide a subset of logic similar to
xfs_attr_rmtval_set, but they store the current block in the delay attr
context to allow the caller to roll the transaction between allocations.
This helps to simplify and consolidate code used by
xfs_attr_leaf_addname and xfs_attr_node_addname. xfs_attr_set_args has
now become a simple loop to refresh the transaction until the operation
is completed.  Lastly, xfs_attr_rmtval_remove is no longer used, and is
removed.
Signed-off-by: default avatarAllison Henderson <allison.henderson@oracle.com>
Reviewed-by: default avatarChandan Babu R <chandanrlinux@gmail.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
parent 2b74b03c
This diff is collapsed.
This diff is collapsed.
...@@ -439,9 +439,9 @@ xfs_attr_rmtval_get( ...@@ -439,9 +439,9 @@ xfs_attr_rmtval_get(
/* /*
* Find a "hole" in the attribute address space large enough for us to drop the * Find a "hole" in the attribute address space large enough for us to drop the
* new attribute's value into * new attributes value into
*/ */
STATIC int int
xfs_attr_rmt_find_hole( xfs_attr_rmt_find_hole(
struct xfs_da_args *args) struct xfs_da_args *args)
{ {
...@@ -468,7 +468,7 @@ xfs_attr_rmt_find_hole( ...@@ -468,7 +468,7 @@ xfs_attr_rmt_find_hole(
return 0; return 0;
} }
STATIC int int
xfs_attr_rmtval_set_value( xfs_attr_rmtval_set_value(
struct xfs_da_args *args) struct xfs_da_args *args)
{ {
...@@ -627,6 +627,69 @@ xfs_attr_rmtval_set( ...@@ -627,6 +627,69 @@ xfs_attr_rmtval_set(
return xfs_attr_rmtval_set_value(args); return xfs_attr_rmtval_set_value(args);
} }
/*
* Find a hole for the attr and store it in the delayed attr context. This
* initializes the context to roll through allocating an attr extent for a
* delayed attr operation
*/
int
xfs_attr_rmtval_find_space(
struct xfs_delattr_context *dac)
{
struct xfs_da_args *args = dac->da_args;
struct xfs_bmbt_irec *map = &dac->map;
int error;
dac->lblkno = 0;
dac->blkcnt = 0;
args->rmtblkcnt = 0;
args->rmtblkno = 0;
memset(map, 0, sizeof(struct xfs_bmbt_irec));
error = xfs_attr_rmt_find_hole(args);
if (error)
return error;
dac->blkcnt = args->rmtblkcnt;
dac->lblkno = args->rmtblkno;
return 0;
}
/*
* Write one block of the value associated with an attribute into the
* out-of-line buffer that we have defined for it. This is similar to a subset
* of xfs_attr_rmtval_set, but records the current block to the delayed attr
* context, and leaves transaction handling to the caller.
*/
int
xfs_attr_rmtval_set_blk(
struct xfs_delattr_context *dac)
{
struct xfs_da_args *args = dac->da_args;
struct xfs_inode *dp = args->dp;
struct xfs_bmbt_irec *map = &dac->map;
int nmap;
int error;
nmap = 1;
error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)dac->lblkno,
dac->blkcnt, XFS_BMAPI_ATTRFORK, args->total,
map, &nmap);
if (error)
return error;
ASSERT(nmap == 1);
ASSERT((map->br_startblock != DELAYSTARTBLOCK) &&
(map->br_startblock != HOLESTARTBLOCK));
/* roll attribute extent map forwards */
dac->lblkno += map->br_blockcount;
dac->blkcnt -= map->br_blockcount;
return 0;
}
/* /*
* 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.
...@@ -668,37 +731,6 @@ xfs_attr_rmtval_invalidate( ...@@ -668,37 +731,6 @@ xfs_attr_rmtval_invalidate(
return 0; return 0;
} }
/*
* Remove the value associated with an attribute by deleting the
* out-of-line buffer that it is stored on.
*/
int
xfs_attr_rmtval_remove(
struct xfs_da_args *args)
{
int error;
struct xfs_delattr_context dac = {
.da_args = args,
};
trace_xfs_attr_rmtval_remove(args);
/*
* Keep de-allocating extents until the remote-value region is gone.
*/
do {
error = __xfs_attr_rmtval_remove(&dac);
if (error && error != -EAGAIN)
break;
error = xfs_attr_trans_roll(&dac);
if (error)
return error;
} while (true);
return error;
}
/* /*
* Remove the value associated with an attribute by deleting the out-of-line * Remove the value associated with an attribute by deleting the out-of-line
* buffer that it is stored on. Returns -EAGAIN for the caller to refresh the * buffer that it is stored on. Returns -EAGAIN for the caller to refresh the
......
...@@ -10,9 +10,12 @@ int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen); ...@@ -10,9 +10,12 @@ int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
int xfs_attr_rmtval_get(struct xfs_da_args *args); int xfs_attr_rmtval_get(struct xfs_da_args *args);
int xfs_attr_rmtval_set(struct xfs_da_args *args); int xfs_attr_rmtval_set(struct xfs_da_args *args);
int xfs_attr_rmtval_remove(struct xfs_da_args *args);
int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map, int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
xfs_buf_flags_t incore_flags); xfs_buf_flags_t incore_flags);
int xfs_attr_rmtval_invalidate(struct xfs_da_args *args); int xfs_attr_rmtval_invalidate(struct xfs_da_args *args);
int __xfs_attr_rmtval_remove(struct xfs_delattr_context *dac); int __xfs_attr_rmtval_remove(struct xfs_delattr_context *dac);
int xfs_attr_rmt_find_hole(struct xfs_da_args *args);
int xfs_attr_rmtval_set_value(struct xfs_da_args *args);
int xfs_attr_rmtval_set_blk(struct xfs_delattr_context *dac);
int xfs_attr_rmtval_find_space(struct xfs_delattr_context *dac);
#endif /* __XFS_ATTR_REMOTE_H__ */ #endif /* __XFS_ATTR_REMOTE_H__ */
...@@ -1943,7 +1943,6 @@ DEFINE_ATTR_EVENT(xfs_attr_refillstate); ...@@ -1943,7 +1943,6 @@ DEFINE_ATTR_EVENT(xfs_attr_refillstate);
DEFINE_ATTR_EVENT(xfs_attr_rmtval_get); DEFINE_ATTR_EVENT(xfs_attr_rmtval_get);
DEFINE_ATTR_EVENT(xfs_attr_rmtval_set); DEFINE_ATTR_EVENT(xfs_attr_rmtval_set);
DEFINE_ATTR_EVENT(xfs_attr_rmtval_remove);
#define DEFINE_DA_EVENT(name) \ #define DEFINE_DA_EVENT(name) \
DEFINE_EVENT(xfs_da_class, name, \ DEFINE_EVENT(xfs_da_class, name, \
......
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