[XFS] Use the generic xattr methods.
Use the generic set, get and removexattr methods and supply the s_xattr array with fine-grained handlers. All XFS/Linux highlevel attr handling is rewritten from scratch and placed into fs/xfs/linux-2.6/xfs_xattr.c so that it's separated from the generic low-level code. SGI-PV: 982343 SGI-Modid: xfs-linux-melb:xfs-kern:31234a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
This commit is contained in:

committed by
Niv Sardi

parent
d532506cd8
commit
0ec585163a
@@ -57,11 +57,6 @@
|
||||
* Provide the external interfaces to manage attribute lists.
|
||||
*/
|
||||
|
||||
#define ATTR_SYSCOUNT 2
|
||||
static struct attrnames posix_acl_access;
|
||||
static struct attrnames posix_acl_default;
|
||||
static struct attrnames *attr_system_names[ATTR_SYSCOUNT];
|
||||
|
||||
/*========================================================================
|
||||
* Function prototypes for the kernel.
|
||||
*========================================================================*/
|
||||
@@ -2378,270 +2373,3 @@ xfs_attr_trace_enter(int type, char *where,
|
||||
(void *)a13, (void *)a14, (void *)a15);
|
||||
}
|
||||
#endif /* XFS_ATTR_TRACE */
|
||||
|
||||
|
||||
/*========================================================================
|
||||
* System (pseudo) namespace attribute interface routines.
|
||||
*========================================================================*/
|
||||
|
||||
STATIC int
|
||||
posix_acl_access_set(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_access_remove(
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_access_get(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_access_exists(
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
return xfs_acl_vhasacl_access(vp);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_set(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_get(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_remove(
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_exists(
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
return xfs_acl_vhasacl_default(vp);
|
||||
}
|
||||
|
||||
static struct attrnames posix_acl_access = {
|
||||
.attr_name = "posix_acl_access",
|
||||
.attr_namelen = sizeof("posix_acl_access") - 1,
|
||||
.attr_get = posix_acl_access_get,
|
||||
.attr_set = posix_acl_access_set,
|
||||
.attr_remove = posix_acl_access_remove,
|
||||
.attr_exists = posix_acl_access_exists,
|
||||
};
|
||||
|
||||
static struct attrnames posix_acl_default = {
|
||||
.attr_name = "posix_acl_default",
|
||||
.attr_namelen = sizeof("posix_acl_default") - 1,
|
||||
.attr_get = posix_acl_default_get,
|
||||
.attr_set = posix_acl_default_set,
|
||||
.attr_remove = posix_acl_default_remove,
|
||||
.attr_exists = posix_acl_default_exists,
|
||||
};
|
||||
|
||||
static struct attrnames *attr_system_names[] =
|
||||
{ &posix_acl_access, &posix_acl_default };
|
||||
|
||||
|
||||
/*========================================================================
|
||||
* Namespace-prefix-style attribute name interface routines.
|
||||
*========================================================================*/
|
||||
|
||||
STATIC int
|
||||
attr_generic_set(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return -xfs_attr_set(xfs_vtoi(vp), name, data, size, xflags);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_generic_get(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
int error, asize = size;
|
||||
|
||||
error = xfs_attr_get(xfs_vtoi(vp), name, data, &asize, xflags);
|
||||
if (!error)
|
||||
return asize;
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_generic_remove(
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
return -xfs_attr_remove(xfs_vtoi(vp), name, xflags);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_generic_listadd(
|
||||
attrnames_t *prefix,
|
||||
attrnames_t *namesp,
|
||||
void *data,
|
||||
size_t size,
|
||||
ssize_t *result)
|
||||
{
|
||||
char *p = data + *result;
|
||||
|
||||
*result += prefix->attr_namelen;
|
||||
*result += namesp->attr_namelen + 1;
|
||||
if (!size)
|
||||
return 0;
|
||||
if (*result > size)
|
||||
return -ERANGE;
|
||||
strcpy(p, prefix->attr_name);
|
||||
p += prefix->attr_namelen;
|
||||
strcpy(p, namesp->attr_name);
|
||||
p += namesp->attr_namelen + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_system_list(
|
||||
bhv_vnode_t *vp,
|
||||
void *data,
|
||||
size_t size,
|
||||
ssize_t *result)
|
||||
{
|
||||
attrnames_t *namesp;
|
||||
int i, error = 0;
|
||||
|
||||
for (i = 0; i < ATTR_SYSCOUNT; i++) {
|
||||
namesp = attr_system_names[i];
|
||||
if (!namesp->attr_exists || !namesp->attr_exists(vp))
|
||||
continue;
|
||||
error = attr_generic_listadd(&attr_system, namesp,
|
||||
data, size, result);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
attr_generic_list(
|
||||
bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
|
||||
{
|
||||
attrlist_cursor_kern_t cursor = { 0 };
|
||||
int error;
|
||||
|
||||
error = xfs_attr_list(xfs_vtoi(vp), data, size, xflags, &cursor);
|
||||
if (error > 0)
|
||||
return -error;
|
||||
*result = -error;
|
||||
return attr_system_list(vp, data, size, result);
|
||||
}
|
||||
|
||||
attrnames_t *
|
||||
attr_lookup_namespace(
|
||||
char *name,
|
||||
struct attrnames **names,
|
||||
int nnames)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nnames; i++)
|
||||
if (!strncmp(name, names[i]->attr_name, names[i]->attr_namelen))
|
||||
return names[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_system_set(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
attrnames_t *namesp;
|
||||
int error;
|
||||
|
||||
if (xflags & ATTR_CREATE)
|
||||
return -EINVAL;
|
||||
|
||||
namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
|
||||
if (!namesp)
|
||||
return -EOPNOTSUPP;
|
||||
error = namesp->attr_set(vp, name, data, size, xflags);
|
||||
if (!error)
|
||||
error = vn_revalidate(vp);
|
||||
return error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_system_get(
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
attrnames_t *namesp;
|
||||
|
||||
namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
|
||||
if (!namesp)
|
||||
return -EOPNOTSUPP;
|
||||
return namesp->attr_get(vp, name, data, size, xflags);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_system_remove(
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
attrnames_t *namesp;
|
||||
|
||||
namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
|
||||
if (!namesp)
|
||||
return -EOPNOTSUPP;
|
||||
return namesp->attr_remove(vp, name, xflags);
|
||||
}
|
||||
|
||||
struct attrnames attr_system = {
|
||||
.attr_name = "system.",
|
||||
.attr_namelen = sizeof("system.") - 1,
|
||||
.attr_flag = ATTR_SYSTEM,
|
||||
.attr_get = attr_system_get,
|
||||
.attr_set = attr_system_set,
|
||||
.attr_remove = attr_system_remove,
|
||||
};
|
||||
|
||||
struct attrnames attr_trusted = {
|
||||
.attr_name = "trusted.",
|
||||
.attr_namelen = sizeof("trusted.") - 1,
|
||||
.attr_flag = ATTR_ROOT,
|
||||
.attr_get = attr_generic_get,
|
||||
.attr_set = attr_generic_set,
|
||||
.attr_remove = attr_generic_remove,
|
||||
};
|
||||
|
||||
struct attrnames attr_secure = {
|
||||
.attr_name = "security.",
|
||||
.attr_namelen = sizeof("security.") - 1,
|
||||
.attr_flag = ATTR_SECURE,
|
||||
.attr_get = attr_generic_get,
|
||||
.attr_set = attr_generic_set,
|
||||
.attr_remove = attr_generic_remove,
|
||||
};
|
||||
|
||||
struct attrnames attr_user = {
|
||||
.attr_name = "user.",
|
||||
.attr_namelen = sizeof("user.") - 1,
|
||||
.attr_get = attr_generic_get,
|
||||
.attr_set = attr_generic_set,
|
||||
.attr_remove = attr_generic_remove,
|
||||
};
|
||||
|
||||
struct attrnames *attr_namespaces[] =
|
||||
{ &attr_system, &attr_trusted, &attr_secure, &attr_user };
|
||||
|
Reference in New Issue
Block a user