xattr: misc refactor

- Check for XATTR_CREATE in setxattr.
- Rename bookmark_attrs -> xattr_names.
- Other misc changes.
This commit is contained in:
CismonX 2025-02-19 11:34:03 +08:00
parent 63c491bc02
commit bd90602d4a
No known key found for this signature in database
GPG key ID: 3094873E29A482FB
8 changed files with 79 additions and 76 deletions

View file

@ -1755,7 +1755,7 @@ struct bookmarkfs_backend_create_resp @{
void *backend_ctx;
uint64_t bookmarks_root_id;
uint64_t tags_root_id;
char const *bookmark_attrs;
char const *xattr_names;
uint32_t flags;
@};
@end example
@ -1796,7 +1796,7 @@ before entering sandbox.
@xref{Tags}.
@end itemize
@item bookmark_attrs
@item xattr_names
Names of extended attributes (@pxref{Extended Attributes}) supported
for this backend context.

View file

@ -261,7 +261,7 @@ struct bookmarkfs_backend_create_resp {
void *backend_ctx;
uint64_t bookmarks_root_id;
uint64_t tags_root_id;
char const *bookmark_attrs;
char const *xattr_names;
uint32_t flags;
};

View file

@ -1745,16 +1745,16 @@ backend_create (
resp_flags |= BOOKMARKFS_BACKEND_EXCLUSIVE;
}
char const *bookmark_attrs = "guid\0date_added\0";
char const *xattr_names = "guid\0date_added\0";
if (opts.other_flags & BACKEND_FILENAME_GUID) {
bookmark_attrs = "title\0date_added\0";
xattr_names = "title\0date_added\0";
}
resp->name = "chromium";
resp->backend_ctx = ctx;
resp->bookmarks_root_id = BOOKMARKS_ROOT_ID;
resp->flags = resp_flags;
resp->bookmark_attrs = bookmark_attrs;
resp->xattr_names = xattr_names;
return 0;
}

View file

@ -2880,16 +2880,16 @@ backend_create (
resp_flags |= BOOKMARKFS_BACKEND_EXCLUSIVE;
}
char const *bookmark_attrs = "guid\0date_added\0description\0";
char const *xattr_names = "guid\0date_added\0description\0";
if (opts.flags & BACKEND_FILENAME_GUID) {
bookmark_attrs = "title\0date_added\0description\0";
xattr_names = "title\0date_added\0description\0";
}
resp->name = "firefox";
resp->backend_ctx = ctx;
resp->bookmarks_root_id = bookmarks_root_id;
resp->tags_root_id = tags_root_id;
resp->bookmark_attrs = bookmark_attrs;
resp->xattr_names = xattr_names;
resp->flags = resp_flags;
return 0;

View file

@ -120,5 +120,6 @@
#endif
#define BOOKMARKFS_HOMEPAGE_URL "https://www.nongnu.org/bookmarkfs/"
#define BOOKMARKFS_XATTR_PREFIX "user.bookmarkfs."
#endif /* !defined(BOOKMARKFS_DEFS_H_) */

View file

@ -33,6 +33,9 @@
#include <fcntl.h>
#include <sys/stat.h>
#ifdef __linux__
# include <sys/xattr.h>
#endif
#include <time.h>
#include <unistd.h>
@ -66,8 +69,6 @@
#define FH_FLAG_DIRTY ( 1u << 0 )
#define FH_FLAG_FSCK ( 1u << 1 )
#define XATTR_PREFIX "user.bookmarkfs."
#define SUBSYS_ID_BITS ( 64 - BOOKMARKFS_BOOKMARK_TYPE_BITS )
#define SUBSYS_ID_MASK ( ((fuse_ino_t)1 << SUBSYS_ID_BITS) - 1 )
#define INODE_SUBSYS_TYPE(ino) ( (ino) >> SUBSYS_ID_BITS )
@ -87,6 +88,16 @@
#define BACKEND_CALL(name, ...) \
ctx.backend_impl->name(ctx.backend_ctx, __VA_ARGS__)
#define BM_XATTR_FOREACH(name, name_len) \
for (char const *name = ctx.xattr_names, *next_; ; name = next_) { \
size_t name_len = strlen(name); \
if (name_len == 0) { \
break; \
} \
next_ = name + name_len + 1;
#define BM_XATTR_FOREACH_END \
}
#define backend_has_tags() ( TAGS_ROOT_ID != UINT64_MAX )
#define backend_has_keywords() ( ctx.flags.has_keyword )
#define send_reply(name, ...) \
@ -139,7 +150,7 @@ struct fs_ctx {
uint64_t bookmarks_root_id;
uint64_t tags_root_id;
size_t file_max;
char const *bookmark_attrs;
char const *xattr_names;
char *buf;
size_t buf_len;
@ -219,7 +230,7 @@ static int bm_set_keyword (uint64_t, char const *, struct stat *);
static int bm_set_tag (uint64_t, uint64_t, char const *, struct stat *);
static int bm_setattr (uint64_t, int, bool, struct fuse_file_info const *,
struct stat *);
static int bm_setxattr (uint64_t, char const *, void const *, size_t);
static int bm_setxattr (uint64_t, char const *, void const *, size_t, int);
static int bm_write (fuse_req_t, int, char const *, size_t, off_t,
struct fs_file_handle *);
static int current_time (struct timespec *);
@ -243,10 +254,10 @@ static int intfs_mkdir (unsigned, char const *, struct stat *);
static int intfs_opendir (unsigned, fuse_ino_t, struct fuse_file_info *);
static int intfs_readdir (fuse_req_t, unsigned, size_t, off_t, uint32_t,
void *);
static bool is_xattr_name (char const *);
static int reply_errcheck (int, char const *, int);
static int subsys_type (fuse_ino_t, uint64_t *);
static int timespec_cmp (struct timespec const *, struct timespec const *);
static int xattr_name (char const *, char const **);
// Forward declaration end
static struct fs_ctx ctx = {
@ -586,10 +597,11 @@ bm_getxattr (
char const *name,
size_t buf_max
) {
if (0 != xattr_name(name, &name)) {
if (!is_xattr_name(name)) {
return -ENOATTR;
}
name += strlen(BOOKMARKFS_XATTR_PREFIX);
struct bm_getxattr_ctx gctx = {
.req = req,
.buf_max = buf_max,
@ -603,7 +615,7 @@ bm_getxattr_cb (
void const *xattr_val,
size_t xattr_len
) {
struct bm_getxattr_ctx *gctx = user_data;
struct bm_getxattr_ctx const *gctx = user_data;
size_t buf_max = gctx->buf_max;
if (buf_max == 0) {
@ -730,14 +742,10 @@ bm_lsxattr (
size_t *buf_len_ptr
) {
size_t buf_len = 0;
for (char const *xattrs = ctx.bookmark_attrs, *next; ; xattrs = next) {
size_t xattr_len = strlen(xattrs) + 1;
if (xattr_len == 1) {
break;
}
next = xattrs + xattr_len;
size_t prefix_len = strlen(BOOKMARKFS_XATTR_PREFIX);
xattr_len += strlen(XATTR_PREFIX);
BM_XATTR_FOREACH(xattr, xattr_len)
xattr_len += prefix_len + 1;
buf_len += xattr_len;
if (buf_max == 0) {
continue;
@ -746,10 +754,9 @@ bm_lsxattr (
return -ERANGE;
}
char *dest = buf + buf_len - xattr_len;
memcpy(dest, XATTR_PREFIX, strlen(XATTR_PREFIX));
dest += strlen(XATTR_PREFIX);
memcpy(dest, xattrs, xattr_len - strlen(XATTR_PREFIX));
}
memcpy(dest, BOOKMARKFS_XATTR_PREFIX, prefix_len);
memcpy(dest + prefix_len, xattr, xattr_len - prefix_len);
BM_XATTR_FOREACH_END
*buf_len_ptr = buf_len;
return 0;
@ -1005,7 +1012,7 @@ bm_rmxattr (
uint64_t UNUSED_VAR(id),
char const *name
) {
if (0 != xattr_name(name, NULL)) {
if (!is_xattr_name(name)) {
return -ENOATTR;
}
return -EPERM;
@ -1132,12 +1139,21 @@ bm_setxattr (
uint64_t id,
char const *name,
void const *val,
size_t val_len
size_t val_len,
int flags
) {
if (0 != xattr_name(name, &name)) {
if (!is_xattr_name(name)) {
return -ENOATTR;
}
#ifdef __linux__
if (flags == XATTR_CREATE) {
return -EEXIST;
}
#else
debug_assert(flags == 0);
#endif
name += strlen(BOOKMARKFS_XATTR_PREFIX);
return BACKEND_CALL(bookmark_set, id, name, 0, val, val_len);
}
@ -1621,6 +1637,29 @@ intfs_readdir (
return send_reply(buf, req, reply_buf - reply_size, reply_size);
}
static bool
is_xattr_name (
char const *name
) {
size_t name_len = strlen(name);
size_t prefix_len = strlen(BOOKMARKFS_XATTR_PREFIX);
if (name_len <= prefix_len) {
return false;
}
if (0 != memcmp(name, BOOKMARKFS_XATTR_PREFIX, prefix_len)) {
return false;
}
name += prefix_len;
name_len -= prefix_len;
BM_XATTR_FOREACH(xattr, xattr_len)
if (name_len == xattr_len && 0 == memcmp(name, xattr, name_len)) {
return true;
}
BM_XATTR_FOREACH_END
return false;
}
static int
reply_errcheck (
int err,
@ -1679,43 +1718,6 @@ timespec_cmp (
return 0;
}
static int
xattr_name (
char const *name,
char const **name_ptr
) {
size_t name_len = strlen(name);
size_t prefix_len = strlen(XATTR_PREFIX);
if (name_len <= prefix_len) {
return -1;
}
if (0 != memcmp(name, XATTR_PREFIX, prefix_len)) {
return -1;
}
name += prefix_len;
name_len -= prefix_len;
for (char const *xattrs = ctx.bookmark_attrs, *next; ; xattrs = next) {
size_t xattr_len = strlen(xattrs);
if (xattr_len == 0) {
break;
}
next = xattrs + xattr_len + 1;
if (name_len != xattr_len) {
continue;
}
if (0 != memcmp(name, xattrs, name_len)) {
continue;
}
if (name_ptr != NULL) {
*name_ptr = name;
}
return 0;
}
return -1;
}
void
fs_init_backend (
struct bookmarkfs_backend const *backend_impl,
@ -1736,7 +1738,7 @@ void
fs_init_metadata (
uint64_t bookmarks_root_id,
uint64_t tags_root_id,
char const *bookmark_attrs
char const *xattr_names
) {
if (bookmarks_root_id != UINT64_MAX) {
ctx.bookmarks_root_id = bookmarks_root_id;
@ -1744,8 +1746,8 @@ fs_init_metadata (
if (tags_root_id != UINT64_MAX) {
ctx.tags_root_id = tags_root_id;
}
if (bookmark_attrs != NULL) {
ctx.bookmark_attrs = bookmark_attrs;
if (xattr_names != NULL) {
ctx.xattr_names = xattr_names;
}
}
@ -2352,7 +2354,7 @@ fs_op_setxattr (
char const *name,
char const *val,
size_t val_len,
int UNUSED_VAR(flags)
int flags
) {
int status = -ERANGE;
if (val_len > ctx.file_max) {
@ -2362,7 +2364,7 @@ fs_op_setxattr (
switch (INODE_SUBSYS_TYPE(ino)) {
case SUBSYS_TYPE_BOOKMARK:
status = bm_setxattr(INODE_SUBSYS_ID(ino), name, val, val_len);
status = bm_setxattr(INODE_SUBSYS_ID(ino), name, val, val_len, flags);
break;
}

View file

@ -52,7 +52,7 @@ void
fs_init_metadata (
uint64_t bookmarks_root_id,
uint64_t tags_root_id,
char const *bookmark_attrs
char const *xattr_names
);
void

View file

@ -212,7 +212,7 @@ init_backend (
struct bookmarkfs_backend_create_resp resp = {
.bookmarks_root_id = UINT64_MAX,
.tags_root_id = UINT64_MAX,
.bookmark_attrs = "",
.xattr_names = "",
};
if (0 != impl->backend_create(&info->backend_conf, &resp)) {
debug_puts("backend_create() failed");
@ -227,7 +227,7 @@ init_backend (
fs_init_backend(impl, resp.backend_ctx);
fs_init_metadata(resp.bookmarks_root_id, resp.tags_root_id,
resp.bookmark_attrs);
resp.xattr_names);
fs_init_opts(info->fs_flags, info->file_max);
return 0;
}