summaryrefslogtreecommitdiff
path: root/fs/aufs/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aufs/xattr.c')
-rw-r--r--fs/aufs/xattr.c344
1 files changed, 0 insertions, 344 deletions
diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c
deleted file mode 100644
index b7e13ca3e..000000000
--- a/fs/aufs/xattr.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Junjiro R. Okajima
- *
- * This program, aufs is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * handling xattr functions
- */
-
-#include <linux/xattr.h>
-#include "aufs.h"
-
-static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags)
-{
- if (!ignore_flags)
- goto out;
- switch (err) {
- case -ENOMEM:
- case -EDQUOT:
- goto out;
- }
-
- if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) {
- err = 0;
- goto out;
- }
-
-#define cmp(brattr, prefix) do { \
- if (!strncmp(name, XATTR_##prefix##_PREFIX, \
- XATTR_##prefix##_PREFIX_LEN)) { \
- if (ignore_flags & AuBrAttr_ICEX_##brattr) \
- err = 0; \
- goto out; \
- } \
- } while (0)
-
- cmp(SEC, SECURITY);
- cmp(SYS, SYSTEM);
- cmp(TR, TRUSTED);
- cmp(USR, USER);
-#undef cmp
-
- if (ignore_flags & AuBrAttr_ICEX_OTH)
- err = 0;
-
-out:
- return err;
-}
-
-static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1;
-
-static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src,
- char *name, char **buf, unsigned int ignore_flags,
- unsigned int verbose)
-{
- int err;
- ssize_t ssz;
- struct inode *h_idst;
-
- ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS);
- err = ssz;
- if (unlikely(err <= 0)) {
- if (err == -ENODATA
- || (err == -EOPNOTSUPP
- && ((ignore_flags & au_xattr_out_of_list)
- || (au_test_nfs_noacl(d_inode(h_src))
- && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS)
- || !strcmp(name,
- XATTR_NAME_POSIX_ACL_DEFAULT))))
- ))
- err = 0;
- if (err && (verbose || au_debug_test()))
- pr_err("%s, err %d\n", name, err);
- goto out;
- }
-
- /* unlock it temporary */
- h_idst = d_inode(h_dst);
- mutex_unlock(&h_idst->i_mutex);
- err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0);
- mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
- if (unlikely(err)) {
- if (verbose || au_debug_test())
- pr_err("%s, err %d\n", name, err);
- err = au_xattr_ignore(err, name, ignore_flags);
- }
-
-out:
- return err;
-}
-
-int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags,
- unsigned int verbose)
-{
- int err, unlocked, acl_access, acl_default;
- ssize_t ssz;
- struct inode *h_isrc, *h_idst;
- char *value, *p, *o, *e;
-
- /* try stopping to update the source inode while we are referencing */
- /* there should not be the parent-child relationship between them */
- h_isrc = d_inode(h_src);
- h_idst = d_inode(h_dst);
- mutex_unlock(&h_idst->i_mutex);
- mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD);
- mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2);
- unlocked = 0;
-
- /* some filesystems don't list POSIX ACL, for example tmpfs */
- ssz = vfs_listxattr(h_src, NULL, 0);
- err = ssz;
- if (unlikely(err < 0)) {
- AuTraceErr(err);
- if (err == -ENODATA
- || err == -EOPNOTSUPP)
- err = 0; /* ignore */
- goto out;
- }
-
- err = 0;
- p = NULL;
- o = NULL;
- if (ssz) {
- err = -ENOMEM;
- p = kmalloc(ssz, GFP_NOFS);
- o = p;
- if (unlikely(!p))
- goto out;
- err = vfs_listxattr(h_src, p, ssz);
- }
- mutex_unlock(&h_isrc->i_mutex);
- unlocked = 1;
- AuDbg("err %d, ssz %zd\n", err, ssz);
- if (unlikely(err < 0))
- goto out_free;
-
- err = 0;
- e = p + ssz;
- value = NULL;
- acl_access = 0;
- acl_default = 0;
- while (!err && p < e) {
- acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS,
- sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1);
- acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT,
- sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)
- - 1);
- err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags,
- verbose);
- p += strlen(p) + 1;
- }
- AuTraceErr(err);
- ignore_flags |= au_xattr_out_of_list;
- if (!err && !acl_access) {
- err = au_do_cpup_xattr(h_dst, h_src,
- XATTR_NAME_POSIX_ACL_ACCESS, &value,
- ignore_flags, verbose);
- AuTraceErr(err);
- }
- if (!err && !acl_default) {
- err = au_do_cpup_xattr(h_dst, h_src,
- XATTR_NAME_POSIX_ACL_DEFAULT, &value,
- ignore_flags, verbose);
- AuTraceErr(err);
- }
-
- kfree(value);
-
-out_free:
- kfree(o);
-out:
- if (!unlocked)
- mutex_unlock(&h_isrc->i_mutex);
- AuTraceErr(err);
- return err;
-}
-
-/* ---------------------------------------------------------------------- */
-
-enum {
- AU_XATTR_LIST,
- AU_XATTR_GET
-};
-
-struct au_lgxattr {
- int type;
- union {
- struct {
- char *list;
- size_t size;
- } list;
- struct {
- const char *name;
- void *value;
- size_t size;
- } get;
- } u;
-};
-
-static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg)
-{
- ssize_t err;
- struct path h_path;
- struct super_block *sb;
-
- sb = dentry->d_sb;
- err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
- if (unlikely(err))
- goto out;
- err = au_h_path_getattr(dentry, /*force*/1, &h_path);
- if (unlikely(err))
- goto out_si;
- if (unlikely(!h_path.dentry))
- /* illegally overlapped or something */
- goto out_di; /* pretending success */
-
- /* always topmost entry only */
- switch (arg->type) {
- case AU_XATTR_LIST:
- err = vfs_listxattr(h_path.dentry,
- arg->u.list.list, arg->u.list.size);
- break;
- case AU_XATTR_GET:
- err = vfs_getxattr(h_path.dentry,
- arg->u.get.name, arg->u.get.value,
- arg->u.get.size);
- break;
- }
-
-out_di:
- di_read_unlock(dentry, AuLock_IR);
-out_si:
- si_read_unlock(sb);
-out:
- AuTraceErr(err);
- return err;
-}
-
-ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size)
-{
- struct au_lgxattr arg = {
- .type = AU_XATTR_LIST,
- .u.list = {
- .list = list,
- .size = size
- },
- };
-
- return au_lgxattr(dentry, &arg);
-}
-
-ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value,
- size_t size)
-{
- struct au_lgxattr arg = {
- .type = AU_XATTR_GET,
- .u.get = {
- .name = name,
- .value = value,
- .size = size
- },
- };
-
- return au_lgxattr(dentry, &arg);
-}
-
-int aufs_setxattr(struct dentry *dentry, const char *name, const void *value,
- size_t size, int flags)
-{
- struct au_srxattr arg = {
- .type = AU_XATTR_SET,
- .u.set = {
- .name = name,
- .value = value,
- .size = size,
- .flags = flags
- },
- };
-
- return au_srxattr(dentry, &arg);
-}
-
-int aufs_removexattr(struct dentry *dentry, const char *name)
-{
- struct au_srxattr arg = {
- .type = AU_XATTR_REMOVE,
- .u.remove = {
- .name = name
- },
- };
-
- return au_srxattr(dentry, &arg);
-}
-
-/* ---------------------------------------------------------------------- */
-
-#if 0
-static size_t au_xattr_list(struct dentry *dentry, char *list, size_t list_size,
- const char *name, size_t name_len, int type)
-{
- return aufs_listxattr(dentry, list, list_size);
-}
-
-static int au_xattr_get(struct dentry *dentry, const char *name, void *buffer,
- size_t size, int type)
-{
- return aufs_getxattr(dentry, name, buffer, size);
-}
-
-static int au_xattr_set(struct dentry *dentry, const char *name,
- const void *value, size_t size, int flags, int type)
-{
- return aufs_setxattr(dentry, name, value, size, flags);
-}
-
-static const struct xattr_handler au_xattr_handler = {
- /* no prefix, no flags */
- .list = au_xattr_list,
- .get = au_xattr_get,
- .set = au_xattr_set
- /* why no remove? */
-};
-
-static const struct xattr_handler *au_xattr_handlers[] = {
- &au_xattr_handler
-};
-
-void au_xattr_init(struct super_block *sb)
-{
- /* sb->s_xattr = au_xattr_handlers; */
-}
-#endif