1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "scrub/scrub.h"
11 #include "scrub/xfile.h"
12 #include "scrub/xfarray.h"
13 #include "scrub/xfblob.h"
18 * Stores and retrieves blobs using an xfile. Objects are appended to the file
19 * and the offset is returned as a magic cookie for retrieval.
22 #define XB_KEY_MAGIC 0xABAADDAD
24 uint32_t xb_magic
; /* XB_KEY_MAGIC */
25 uint32_t xb_size
; /* size of the blob, in bytes */
26 loff_t xb_offset
; /* byte offset of this key */
27 /* blob comes after here */
30 /* Initialize a blob storage object. */
33 const char *description
,
34 struct xfblob
**blobp
)
40 error
= xfile_create(description
, 0, &xfile
);
44 blob
= kmalloc(sizeof(struct xfblob
), XCHK_GFP_FLAGS
);
51 blob
->last_offset
= PAGE_SIZE
;
61 /* Destroy a blob storage object. */
66 xfile_destroy(blob
->xfile
);
70 /* Retrieve a blob. */
81 error
= xfile_load(blob
->xfile
, &key
, sizeof(key
), cookie
);
85 if (key
.xb_magic
!= XB_KEY_MAGIC
|| key
.xb_offset
!= cookie
) {
89 if (size
< key
.xb_size
) {
94 return xfile_load(blob
->xfile
, ptr
, key
.xb_size
,
95 cookie
+ sizeof(key
));
102 xfblob_cookie
*cookie
,
106 struct xb_key key
= {
107 .xb_offset
= blob
->last_offset
,
108 .xb_magic
= XB_KEY_MAGIC
,
111 loff_t pos
= blob
->last_offset
;
114 error
= xfile_store(blob
->xfile
, &key
, sizeof(key
), pos
);
119 error
= xfile_store(blob
->xfile
, ptr
, size
, pos
);
123 *cookie
= blob
->last_offset
;
124 blob
->last_offset
+= sizeof(key
) + size
;
127 xfile_discard(blob
->xfile
, blob
->last_offset
, sizeof(key
));
135 xfblob_cookie cookie
)
140 error
= xfile_load(blob
->xfile
, &key
, sizeof(key
), cookie
);
144 if (key
.xb_magic
!= XB_KEY_MAGIC
|| key
.xb_offset
!= cookie
) {
149 xfile_discard(blob
->xfile
, cookie
, sizeof(key
) + key
.xb_size
);
153 /* How many bytes is this blob storage object consuming? */
158 return xfile_bytes(blob
->xfile
);
161 /* Drop all the blobs. */
166 xfile_discard(blob
->xfile
, PAGE_SIZE
, MAX_LFS_FILESIZE
- PAGE_SIZE
);
167 blob
->last_offset
= PAGE_SIZE
;