.cmp_bkey = xattr_cmp_bkey,
};
-const char *bch2_xattr_invalid(const struct bch_fs *c, struct bkey_s_c k)
+int bch2_xattr_invalid(const struct bch_fs *c, struct bkey_s_c k,
+ unsigned flags, struct printbuf *err)
{
const struct xattr_handler *handler;
struct bkey_s_c_xattr xattr = bkey_s_c_to_xattr(k);
- if (bkey_val_bytes(k.k) < sizeof(struct bch_xattr))
- return "value too small";
+ if (bkey_val_bytes(k.k) < sizeof(struct bch_xattr)) {
+ prt_printf(err, "incorrect value size (%zu < %zu)",
+ bkey_val_bytes(k.k), sizeof(*xattr.v));
+ return -BCH_ERR_invalid_bkey;
+ }
if (bkey_val_u64s(k.k) <
xattr_val_u64s(xattr.v->x_name_len,
- le16_to_cpu(xattr.v->x_val_len)))
- return "value too small";
+ le16_to_cpu(xattr.v->x_val_len))) {
+ prt_printf(err, "value too small (%zu < %u)",
+ bkey_val_u64s(k.k),
+ xattr_val_u64s(xattr.v->x_name_len,
+ le16_to_cpu(xattr.v->x_val_len)));
+ return -BCH_ERR_invalid_bkey;
+ }
+ /* XXX why +4 ? */
if (bkey_val_u64s(k.k) >
xattr_val_u64s(xattr.v->x_name_len,
- le16_to_cpu(xattr.v->x_val_len) + 4))
- return "value too big";
+ le16_to_cpu(xattr.v->x_val_len) + 4)) {
+ prt_printf(err, "value too big (%zu > %u)",
+ bkey_val_u64s(k.k),
+ xattr_val_u64s(xattr.v->x_name_len,
+ le16_to_cpu(xattr.v->x_val_len) + 4));
+ return -BCH_ERR_invalid_bkey;
+ }
handler = bch2_xattr_type_to_handler(xattr.v->x_type);
- if (!handler)
- return "invalid type";
+ if (!handler) {
+ prt_printf(err, "invalid type (%u)", xattr.v->x_type);
+ return -BCH_ERR_invalid_bkey;
+ }
- if (memchr(xattr.v->x_name, '\0', xattr.v->x_name_len))
- return "xattr name has invalid characters";
+ if (memchr(xattr.v->x_name, '\0', xattr.v->x_name_len)) {
+ prt_printf(err, "xattr name has invalid characters");
+ return -BCH_ERR_invalid_bkey;
+ }
- return NULL;
+ return 0;
}
void bch2_xattr_to_text(struct printbuf *out, struct bch_fs *c,
handler = bch2_xattr_type_to_handler(xattr.v->x_type);
if (handler && handler->prefix)
- pr_buf(out, "%s", handler->prefix);
+ prt_printf(out, "%s", handler->prefix);
else if (handler)
- pr_buf(out, "(type %u)", xattr.v->x_type);
+ prt_printf(out, "(type %u)", xattr.v->x_type);
else
- pr_buf(out, "(unknown type %u)", xattr.v->x_type);
+ prt_printf(out, "(unknown type %u)", xattr.v->x_type);
- pr_buf(out, "%.*s:%.*s",
+ prt_printf(out, "%.*s:%.*s",
xattr.v->x_name_len,
xattr.v->x_name,
le16_to_cpu(xattr.v->x_val_len),
offset = iter.pos.offset;
bch2_trans_iter_exit(&trans, &iter);
err:
- if (ret == -EINTR)
+ if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
goto retry;
bch2_trans_exit(&trans);
if (ret)
- return ret;
+ goto out;
ret = bch2_xattr_list_bcachefs(c, &inode->ei_inode, &buf, false);
if (ret)
- return ret;
+ goto out;
ret = bch2_xattr_list_bcachefs(c, &inode->ei_inode, &buf, true);
if (ret)
- return ret;
+ goto out;
return buf.used;
+out:
+ return bch2_err_class(ret);
}
static int bch2_xattr_get_handler(const struct xattr_handler *handler,
{
struct bch_inode_info *inode = to_bch_ei(vinode);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
+ int ret;
- return bch2_xattr_get(c, inode, name, buffer, size, handler->flags);
+ ret = bch2_xattr_get(c, inode, name, buffer, size, handler->flags);
+ return bch2_err_class(ret);
}
static int bch2_xattr_set_handler(const struct xattr_handler *handler,
struct bch_inode_info *inode = to_bch_ei(vinode);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch_hash_info hash = bch2_hash_info_init(c, &inode->ei_inode);
+ int ret;
- return bch2_trans_do(c, NULL, NULL, 0,
+ ret = bch2_trans_do(c, NULL, NULL, 0,
bch2_xattr_set(&trans, inode_inum(inode), &hash,
name, value, size,
handler->flags, flags));
+ return bch2_err_class(ret);
}
static const struct xattr_handler bch_xattr_user_handler = {
struct bch_inode_info *inode = to_bch_ei(vinode);
struct bch_fs *c = inode->v.i_sb->s_fs_info;
struct bch_opts opts =
- bch2_inode_opts_to_opts(bch2_inode_opts_get(&inode->ei_inode));
+ bch2_inode_opts_to_opts(&inode->ei_inode);
const struct bch_option *opt;
int id, inode_opt_id;
struct printbuf out = PRINTBUF;
memcpy(buf, value, size);
buf[size] = '\0';
- ret = bch2_opt_parse(c, NULL, opt, buf, &v);
+ ret = bch2_opt_parse(c, opt, buf, &v, NULL);
kfree(buf);
if (ret < 0)