p = value + sizeof(bch_acl_header); while (p < end) { const bch_acl_entry *in = p; unsigned tag = le16_to_cpu(in->e_tag);
prt_str(out, acl_types[tag]);
switch (tag) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER:
p += sizeof(bch_acl_entry_short); break; case ACL_USER:
prt_printf(out, " uid %u", le32_to_cpu(in->e_id));
p += sizeof(bch_acl_entry); break; case ACL_GROUP:
prt_printf(out, " gid %u", le32_to_cpu(in->e_id));
p += sizeof(bch_acl_entry); break;
}
staticinlineint acl_to_xattr_type(int type)
{ switch (type) { case ACL_TYPE_ACCESS: return KEY_TYPE_XATTR_INDEX_POSIX_ACL_ACCESS; case ACL_TYPE_DEFAULT: return KEY_TYPE_XATTR_INDEX_POSIX_ACL_DEFAULT; default:
BUG();
}
}
/* * Convert from filesystem to in-memory representation.
*/ staticstruct posix_acl *bch2_acl_from_disk(struct btree_trans *trans, constvoid *value, size_t size)
{ constvoid *p, *end = value + size; struct posix_acl *acl; struct posix_acl_entry *out; unsigned count = 0; int ret;
if (!value) return NULL; if (size < sizeof(bch_acl_header)) goto invalid; if (((bch_acl_header *)value)->a_version !=
cpu_to_le32(BCH_ACL_VERSION)) goto invalid;
p = value + sizeof(bch_acl_header); while (p < end) { const bch_acl_entry *entry = p;
if (p + sizeof(bch_acl_entry_short) > end) goto invalid;
switch (le16_to_cpu(entry->e_tag)) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER:
p += sizeof(bch_acl_entry_short); break; case ACL_USER: case ACL_GROUP:
p += sizeof(bch_acl_entry); break; default: goto invalid;
}
count++;
}
if (p > end) goto invalid;
if (!count) return NULL;
acl = allocate_dropping_locks(trans, ret,
posix_acl_alloc(count, _gfp)); if (!acl) return ERR_PTR(-ENOMEM); if (ret) {
kfree(acl); return ERR_PTR(ret);
}
out = acl->a_entries;
p = value + sizeof(bch_acl_header); while (p < end) { const bch_acl_entry *in = p;
switch (out->e_tag) { case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER:
p += sizeof(bch_acl_entry_short); break; case ACL_USER:
out->e_uid = make_kuid(&init_user_ns,
le32_to_cpu(in->e_id));
p += sizeof(bch_acl_entry); break; case ACL_GROUP:
out->e_gid = make_kgid(&init_user_ns,
le32_to_cpu(in->e_id));
p += sizeof(bch_acl_entry); break;
}
FOREACH_ACL_ENTRY(acl_e, acl, pe) { switch (acl_e->e_tag) { case ACL_USER: case ACL_GROUP:
nr_long++; break; case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_MASK: case ACL_OTHER:
nr_short++; break; default: return ERR_PTR(-EINVAL);
}
}
struct bkey_s_c k = bch2_hash_lookup(trans, &iter, bch2_xattr_hash_desc,
&hash, inode_inum(inode), &search, 0); int ret = bkey_err(k); if (ret) goto err;
struct bkey_s_c_xattr xattr = bkey_s_c_to_xattr(k);
acl = bch2_acl_from_disk(trans, xattr_val(xattr.v),
le16_to_cpu(xattr.v->x_val_len));
ret = PTR_ERR_OR_ZERO(acl);
err: if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) goto retry;
if (ret)
acl = !bch2_err_matches(ret, ENOENT) ? ERR_PTR(ret) : NULL;
if (!IS_ERR_OR_NULL(acl))
set_cached_acl(&inode->v, type, acl);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.