From: Darrick J. Wong <djwong@xxxxxxxxxx> If the extended attributes look bad, try to sift through the rubble to find whatever keys/values we can, stage a new attribute structure in a temporary file and use the atomic extent swapping mechanism to commit the results in bulk. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/scrub/xfarray.c | 24 ++++++++++++++++++++++++ fs/xfs/scrub/xfarray.h | 2 ++ fs/xfs/scrub/xfblob.c | 24 ++++++++++++++++++++++++ fs/xfs/scrub/xfblob.h | 2 ++ 4 files changed, 52 insertions(+) diff --git a/fs/xfs/scrub/xfarray.c b/fs/xfs/scrub/xfarray.c index 8fdd7dd40193..fccb3a3d9199 100644 --- a/fs/xfs/scrub/xfarray.c +++ b/fs/xfs/scrub/xfarray.c @@ -368,3 +368,27 @@ xfarray_load_next( *idx = cur; return 0; } + +/* How many bytes is this array consuming? */ +long long +xfarray_bytes( + struct xfarray *array) +{ + struct xfile_stat statbuf; + int error; + + error = xfile_stat(array->xfile, &statbuf); + if (error) + return error; + + return statbuf.bytes; +} + +/* Empty the entire array. */ +void +xfarray_truncate( + struct xfarray *array) +{ + xfile_discard(array->xfile, 0, MAX_LFS_FILESIZE); + array->nr = 0; +} diff --git a/fs/xfs/scrub/xfarray.h b/fs/xfs/scrub/xfarray.h index 26e2b594f121..8a3af0cecc3e 100644 --- a/fs/xfs/scrub/xfarray.h +++ b/fs/xfs/scrub/xfarray.h @@ -45,6 +45,8 @@ int xfarray_unset(struct xfarray *array, xfarray_idx_t idx); int xfarray_store(struct xfarray *array, xfarray_idx_t idx, const void *ptr); int xfarray_store_anywhere(struct xfarray *array, const void *ptr); bool xfarray_element_is_null(struct xfarray *array, const void *ptr); +void xfarray_truncate(struct xfarray *array); +long long xfarray_bytes(struct xfarray *array); /* Append an element to the array. */ static inline int xfarray_append(struct xfarray *array, const void *ptr) diff --git a/fs/xfs/scrub/xfblob.c b/fs/xfs/scrub/xfblob.c index 1f89d7d13c59..2f89617a2db8 100644 --- a/fs/xfs/scrub/xfblob.c +++ b/fs/xfs/scrub/xfblob.c @@ -150,3 +150,27 @@ xfblob_free( xfile_discard(blob->xfile, cookie, sizeof(key) + key.xb_size); return 0; } + +/* How many bytes is this blob storage object consuming? */ +long long +xfblob_bytes( + struct xfblob *blob) +{ + struct xfile_stat statbuf; + int error; + + error = xfile_stat(blob->xfile, &statbuf); + if (error) + return error; + + return statbuf.bytes; +} + +/* Drop all the blobs. */ +void +xfblob_truncate( + struct xfblob *blob) +{ + xfile_discard(blob->xfile, 0, MAX_LFS_FILESIZE); + blob->last_offset = 0; +} diff --git a/fs/xfs/scrub/xfblob.h b/fs/xfs/scrub/xfblob.h index d1282810bb1d..8a5738e1d568 100644 --- a/fs/xfs/scrub/xfblob.h +++ b/fs/xfs/scrub/xfblob.h @@ -21,5 +21,7 @@ int xfblob_load(struct xfblob *blob, xfblob_cookie cookie, void *ptr, int xfblob_store(struct xfblob *blob, xfblob_cookie *cookie, const void *ptr, uint32_t size); int xfblob_free(struct xfblob *blob, xfblob_cookie cookie); +long long xfblob_bytes(struct xfblob *blob); +void xfblob_truncate(struct xfblob *blob); #endif /* __XFS_SCRUB_XFBLOB_H__ */