diff options
author | Darrick J. Wong <djwong@kernel.org> | 2023-04-12 04:00:31 +0200 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2023-04-12 04:00:31 +0200 |
commit | b996c9a80664b970b73961c83bede243b999341e (patch) | |
tree | 84f78676af5906af628e7195b663ca7290ca2685 /fs/xfs/scrub/attr.c | |
parent | xfs: split usedmap from xchk_xattr_buf.buf (diff) | |
download | linux-b996c9a80664b970b73961c83bede243b999341e.tar.xz linux-b996c9a80664b970b73961c83bede243b999341e.zip |
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>
Diffstat (limited to 'fs/xfs/scrub/attr.c')
-rw-r--r-- | fs/xfs/scrub/attr.c | 89 |
1 files changed, 43 insertions, 46 deletions
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index 65ec503c8a38..7f723f206146 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -31,6 +31,9 @@ xchk_xattr_buf_cleanup( ab->freemap = NULL; kvfree(ab->usedmap); 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, gfp_t flags) { - size_t sz = value_size; size_t bmp_sz; struct xchk_xattr_buf *ab = sc->buf; - unsigned long *old_usedmap = NULL; - unsigned long *old_freemap = NULL; + void *new_val; bmp_sz = sizeof(long) * BITS_TO_LONGS(sc->mp->m_attr_geo->blksize); - /* - * If there's already a buffer, figure out if we need to reallocate it - * 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; - } + if (ab) + goto resize_value; - /* - * 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); + ab = kvzalloc(sizeof(struct xchk_xattr_buf), flags); if (!ab) return -ENOMEM; - ab->sz = sz; sc->buf = ab; sc->buf_cleanup = xchk_xattr_buf_cleanup; - if (old_usedmap) { - ab->usedmap = old_usedmap; - } else { - ab->usedmap = kvmalloc(bmp_sz, flags); - if (!ab->usedmap) - return -ENOMEM; - } + ab->usedmap = kvmalloc(bmp_sz, flags); + if (!ab->usedmap) + return -ENOMEM; - if (old_freemap) { - ab->freemap = old_freemap; - } else { - ab->freemap = kvmalloc(bmp_sz, flags); - if (!ab->freemap) - return -ENOMEM; + ab->freemap = kvmalloc(bmp_sz, flags); + 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; } + new_val = kvmalloc(value_size, flags); + if (!new_val) + return -ENOMEM; + + ab->value = new_val; + ab->value_sz = value_size; return 0; } @@ -140,11 +134,24 @@ xchk_xattr_listent( int namelen, 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 xfs_da_args args = { NULL }; int error = 0; sx = container_of(context, struct xchk_xattr, context); + ab = sx->sc->buf; if (xchk_should_terminate(sx->sc, &error)) { context->seen_enough = error; @@ -182,17 +189,7 @@ xchk_xattr_listent( return; } - args.op_flags = XFS_DA_OP_NOTIME; - 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; + args.value = ab->value; error = xfs_attr_get_ilocked(&args); /* ENODATA means the hash lookup failed and the attr is bad */ |