xfs: split valuebuf from xchk_xattr_buf.buf
Move the xattr value buffer from somewhere in xchk_xattr_buf.buf[] to an explicit pointer. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
parent
80069284b5
commit
b996c9a806
|
@ -31,6 +31,9 @@ xchk_xattr_buf_cleanup(
|
||||||
ab->freemap = NULL;
|
ab->freemap = NULL;
|
||||||
kvfree(ab->usedmap);
|
kvfree(ab->usedmap);
|
||||||
ab->usedmap = NULL;
|
ab->usedmap = NULL;
|
||||||
|
kvfree(ab->value);
|
||||||
|
ab->value = NULL;
|
||||||
|
ab->value_sz = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,54 +47,45 @@ xchk_setup_xattr_buf(
|
||||||
size_t value_size,
|
size_t value_size,
|
||||||
gfp_t flags)
|
gfp_t flags)
|
||||||
{
|
{
|
||||||
size_t sz = value_size;
|
|
||||||
size_t bmp_sz;
|
size_t bmp_sz;
|
||||||
struct xchk_xattr_buf *ab = sc->buf;
|
struct xchk_xattr_buf *ab = sc->buf;
|
||||||
unsigned long *old_usedmap = NULL;
|
void *new_val;
|
||||||
unsigned long *old_freemap = NULL;
|
|
||||||
|
|
||||||
bmp_sz = sizeof(long) * BITS_TO_LONGS(sc->mp->m_attr_geo->blksize);
|
bmp_sz = sizeof(long) * BITS_TO_LONGS(sc->mp->m_attr_geo->blksize);
|
||||||
|
|
||||||
/*
|
if (ab)
|
||||||
* If there's already a buffer, figure out if we need to reallocate it
|
goto resize_value;
|
||||||
* to accommodate a larger size.
|
|
||||||
*/
|
|
||||||
if (ab) {
|
|
||||||
if (sz <= ab->sz)
|
|
||||||
return 0;
|
|
||||||
old_freemap = ab->freemap;
|
|
||||||
old_usedmap = ab->usedmap;
|
|
||||||
kvfree(ab);
|
|
||||||
sc->buf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
ab = kvzalloc(sizeof(struct xchk_xattr_buf), flags);
|
||||||
* Don't zero the buffer upon allocation to avoid runtime overhead.
|
|
||||||
* All users must be careful never to read uninitialized contents.
|
|
||||||
*/
|
|
||||||
ab = kvmalloc(sizeof(*ab) + sz, flags);
|
|
||||||
if (!ab)
|
if (!ab)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
ab->sz = sz;
|
|
||||||
sc->buf = ab;
|
sc->buf = ab;
|
||||||
sc->buf_cleanup = xchk_xattr_buf_cleanup;
|
sc->buf_cleanup = xchk_xattr_buf_cleanup;
|
||||||
|
|
||||||
if (old_usedmap) {
|
ab->usedmap = kvmalloc(bmp_sz, flags);
|
||||||
ab->usedmap = old_usedmap;
|
if (!ab->usedmap)
|
||||||
} else {
|
return -ENOMEM;
|
||||||
ab->usedmap = kvmalloc(bmp_sz, flags);
|
|
||||||
if (!ab->usedmap)
|
ab->freemap = kvmalloc(bmp_sz, flags);
|
||||||
return -ENOMEM;
|
if (!ab->freemap)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
resize_value:
|
||||||
|
if (ab->value_sz >= value_size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ab->value) {
|
||||||
|
kvfree(ab->value);
|
||||||
|
ab->value = NULL;
|
||||||
|
ab->value_sz = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_freemap) {
|
new_val = kvmalloc(value_size, flags);
|
||||||
ab->freemap = old_freemap;
|
if (!new_val)
|
||||||
} else {
|
return -ENOMEM;
|
||||||
ab->freemap = kvmalloc(bmp_sz, flags);
|
|
||||||
if (!ab->freemap)
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ab->value = new_val;
|
||||||
|
ab->value_sz = value_size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,11 +134,24 @@ xchk_xattr_listent(
|
||||||
int namelen,
|
int namelen,
|
||||||
int valuelen)
|
int valuelen)
|
||||||
{
|
{
|
||||||
|
struct xfs_da_args args = {
|
||||||
|
.op_flags = XFS_DA_OP_NOTIME,
|
||||||
|
.attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK,
|
||||||
|
.geo = context->dp->i_mount->m_attr_geo,
|
||||||
|
.whichfork = XFS_ATTR_FORK,
|
||||||
|
.dp = context->dp,
|
||||||
|
.name = name,
|
||||||
|
.namelen = namelen,
|
||||||
|
.hashval = xfs_da_hashname(name, namelen),
|
||||||
|
.trans = context->tp,
|
||||||
|
.valuelen = valuelen,
|
||||||
|
};
|
||||||
|
struct xchk_xattr_buf *ab;
|
||||||
struct xchk_xattr *sx;
|
struct xchk_xattr *sx;
|
||||||
struct xfs_da_args args = { NULL };
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
sx = container_of(context, struct xchk_xattr, context);
|
sx = container_of(context, struct xchk_xattr, context);
|
||||||
|
ab = sx->sc->buf;
|
||||||
|
|
||||||
if (xchk_should_terminate(sx->sc, &error)) {
|
if (xchk_should_terminate(sx->sc, &error)) {
|
||||||
context->seen_enough = error;
|
context->seen_enough = error;
|
||||||
|
@ -182,17 +189,7 @@ xchk_xattr_listent(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
args.op_flags = XFS_DA_OP_NOTIME;
|
args.value = ab->value;
|
||||||
args.attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK;
|
|
||||||
args.geo = context->dp->i_mount->m_attr_geo;
|
|
||||||
args.whichfork = XFS_ATTR_FORK;
|
|
||||||
args.dp = context->dp;
|
|
||||||
args.name = name;
|
|
||||||
args.namelen = namelen;
|
|
||||||
args.hashval = xfs_da_hashname(args.name, args.namelen);
|
|
||||||
args.trans = context->tp;
|
|
||||||
args.value = xchk_xattr_valuebuf(sx->sc);
|
|
||||||
args.valuelen = valuelen;
|
|
||||||
|
|
||||||
error = xfs_attr_get_ilocked(&args);
|
error = xfs_attr_get_ilocked(&args);
|
||||||
/* ENODATA means the hash lookup failed and the attr is bad */
|
/* ENODATA means the hash lookup failed and the attr is bad */
|
||||||
|
|
|
@ -16,24 +16,9 @@ struct xchk_xattr_buf {
|
||||||
/* Bitmap of free space in xattr leaf blocks. */
|
/* Bitmap of free space in xattr leaf blocks. */
|
||||||
unsigned long *freemap;
|
unsigned long *freemap;
|
||||||
|
|
||||||
/* Size of @buf, in bytes. */
|
/* Memory buffer used to extract xattr values. */
|
||||||
size_t sz;
|
void *value;
|
||||||
|
size_t value_sz;
|
||||||
/*
|
|
||||||
* Memory buffer -- used for extracting attr values while walking the
|
|
||||||
* attributes.
|
|
||||||
*/
|
|
||||||
uint8_t buf[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A place to store attribute values. */
|
|
||||||
static inline uint8_t *
|
|
||||||
xchk_xattr_valuebuf(
|
|
||||||
struct xfs_scrub *sc)
|
|
||||||
{
|
|
||||||
struct xchk_xattr_buf *ab = sc->buf;
|
|
||||||
|
|
||||||
return ab->buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __XFS_SCRUB_ATTR_H__ */
|
#endif /* __XFS_SCRUB_ATTR_H__ */
|
||||||
|
|
Loading…
Reference in New Issue