1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2021-2024 Oracle. All Rights Reserved.
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;