1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds File: linux/xattr.h
41da177e4SLinus Torvalds
51da177e4SLinus Torvalds Extended attributes handling.
61da177e4SLinus Torvalds
71da177e4SLinus Torvalds Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
81da177e4SLinus Torvalds Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
91da177e4SLinus Torvalds Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
101da177e4SLinus Torvalds */
111da177e4SLinus Torvalds #ifndef _LINUX_XATTR_H
121da177e4SLinus Torvalds #define _LINUX_XATTR_H
131da177e4SLinus Torvalds
141dbe3942SEric Paris
1538f38657SAristeu Rozanski #include <linux/slab.h>
161dbe3942SEric Paris #include <linux/types.h>
1738f38657SAristeu Rozanski #include <linux/spinlock.h>
183bef735aSChengguang Xu #include <linux/mm.h>
19c7c7a1a1STycho Andersen #include <linux/user_namespace.h>
20607ca46eSDavid Howells #include <uapi/linux/xattr.h>
211dbe3942SEric Paris
225b0a2075SAdrian Bunk struct inode;
235b0a2075SAdrian Bunk struct dentry;
241da177e4SLinus Torvalds
is_posix_acl_xattr(const char * name)2531acceb9SChristian Brauner static inline bool is_posix_acl_xattr(const char *name)
2631acceb9SChristian Brauner {
2731acceb9SChristian Brauner return (strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
2831acceb9SChristian Brauner (strcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0);
2931acceb9SChristian Brauner }
3031acceb9SChristian Brauner
3198e9cb57SAndreas Gruenbacher /*
3298e9cb57SAndreas Gruenbacher * struct xattr_handler: When @name is set, match attributes with exactly that
3398e9cb57SAndreas Gruenbacher * name. When @prefix is set instead, match attributes with that prefix and
3498e9cb57SAndreas Gruenbacher * with a non-empty suffix.
3598e9cb57SAndreas Gruenbacher */
361da177e4SLinus Torvalds struct xattr_handler {
3798e9cb57SAndreas Gruenbacher const char *name;
38bb435453SStephen Hemminger const char *prefix;
39e409de99SAndreas Gruenbacher int flags; /* fs private flags */
40764a5c6bSAndreas Gruenbacher bool (*list)(struct dentry *dentry);
41e409de99SAndreas Gruenbacher int (*get)(const struct xattr_handler *, struct dentry *dentry,
42b296821aSAl Viro struct inode *inode, const char *name, void *buffer,
43b296821aSAl Viro size_t size);
44e65ce2a5SChristian Brauner int (*set)(const struct xattr_handler *,
4539f60c1cSChristian Brauner struct mnt_idmap *idmap, struct dentry *dentry,
4659301226SAl Viro struct inode *inode, const char *name, const void *buffer,
4759301226SAl Viro size_t size, int flags);
481da177e4SLinus Torvalds };
491da177e4SLinus Torvalds
502db8a948SChristian Brauner /**
512db8a948SChristian Brauner * xattr_handler_can_list - check whether xattr can be listed
522db8a948SChristian Brauner * @handler: handler for this type of xattr
532db8a948SChristian Brauner * @dentry: dentry whose inode xattr to list
542db8a948SChristian Brauner *
552db8a948SChristian Brauner * Determine whether the xattr associated with @dentry can be listed given
562db8a948SChristian Brauner * @handler.
572db8a948SChristian Brauner *
582db8a948SChristian Brauner * Return: true if xattr can be listed, false if not.
592db8a948SChristian Brauner */
xattr_handler_can_list(const struct xattr_handler * handler,struct dentry * dentry)602db8a948SChristian Brauner static inline bool xattr_handler_can_list(const struct xattr_handler *handler,
612db8a948SChristian Brauner struct dentry *dentry)
622db8a948SChristian Brauner {
632db8a948SChristian Brauner return handler && (!handler->list || handler->list(dentry));
642db8a948SChristian Brauner }
652db8a948SChristian Brauner
66e409de99SAndreas Gruenbacher const char *xattr_full_name(const struct xattr_handler *, const char *);
67e409de99SAndreas Gruenbacher
689d8f13baSMimi Zohar struct xattr {
699548906bSTetsuo Handa const char *name;
709d8f13baSMimi Zohar void *value;
719d8f13baSMimi Zohar size_t value_len;
729d8f13baSMimi Zohar };
739d8f13baSMimi Zohar
745d6c3191SAndreas Gruenbacher ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t);
754609e1f1SChristian Brauner ssize_t vfs_getxattr(struct mnt_idmap *, struct dentry *, const char *,
76c7c7a1a1STycho Andersen void *, size_t);
77659564c8SBill Nottingham ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
7839f60c1cSChristian Brauner int __vfs_setxattr(struct mnt_idmap *, struct dentry *, struct inode *,
79c7c7a1a1STycho Andersen const char *, const void *, size_t, int);
8039f60c1cSChristian Brauner int __vfs_setxattr_noperm(struct mnt_idmap *, struct dentry *,
81c7c7a1a1STycho Andersen const char *, const void *, size_t, int);
824609e1f1SChristian Brauner int __vfs_setxattr_locked(struct mnt_idmap *, struct dentry *,
83c7c7a1a1STycho Andersen const char *, const void *, size_t, int,
84c7c7a1a1STycho Andersen struct inode **);
854609e1f1SChristian Brauner int vfs_setxattr(struct mnt_idmap *, struct dentry *, const char *,
866344e669SChristian Brauner const void *, size_t, int);
8739f60c1cSChristian Brauner int __vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *);
884609e1f1SChristian Brauner int __vfs_removexattr_locked(struct mnt_idmap *, struct dentry *,
89c7c7a1a1STycho Andersen const char *, struct inode **);
904609e1f1SChristian Brauner int vfs_removexattr(struct mnt_idmap *, struct dentry *, const char *);
915be196e5SChristoph Hellwig
921da177e4SLinus Torvalds ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
934609e1f1SChristian Brauner int vfs_getxattr_alloc(struct mnt_idmap *idmap,
94c7c7a1a1STycho Andersen struct dentry *dentry, const char *name,
951601fbadSMimi Zohar char **xattr_value, size_t size, gfp_t flags);
9638f38657SAristeu Rozanski
97831be973SChristian Brauner int xattr_supports_user_prefix(struct inode *inode);
98cab8d289SFrank van der Linden
xattr_prefix(const struct xattr_handler * handler)9998e9cb57SAndreas Gruenbacher static inline const char *xattr_prefix(const struct xattr_handler *handler)
10098e9cb57SAndreas Gruenbacher {
10198e9cb57SAndreas Gruenbacher return handler->prefix ?: handler->name;
10298e9cb57SAndreas Gruenbacher }
10398e9cb57SAndreas Gruenbacher
10438f38657SAristeu Rozanski struct simple_xattrs {
1053b4c7bc0SChristian Brauner struct rb_root rb_root;
1063b4c7bc0SChristian Brauner rwlock_t lock;
10738f38657SAristeu Rozanski };
10838f38657SAristeu Rozanski
10938f38657SAristeu Rozanski struct simple_xattr {
1103b4c7bc0SChristian Brauner struct rb_node rb_node;
11138f38657SAristeu Rozanski char *name;
11238f38657SAristeu Rozanski size_t size;
11343951585SGustavo A. R. Silva char value[];
11438f38657SAristeu Rozanski };
11538f38657SAristeu Rozanski
1163b4c7bc0SChristian Brauner void simple_xattrs_init(struct simple_xattrs *xattrs);
117*2daf18a7SHugh Dickins void simple_xattrs_free(struct simple_xattrs *xattrs, size_t *freed_space);
118*2daf18a7SHugh Dickins size_t simple_xattr_space(const char *name, size_t size);
11938f38657SAristeu Rozanski struct simple_xattr *simple_xattr_alloc(const void *value, size_t size);
1205de75970SHugh Dickins void simple_xattr_free(struct simple_xattr *xattr);
12138f38657SAristeu Rozanski int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
12238f38657SAristeu Rozanski void *buffer, size_t size);
1235de75970SHugh Dickins struct simple_xattr *simple_xattr_set(struct simple_xattrs *xattrs,
1245de75970SHugh Dickins const char *name, const void *value,
1255de75970SHugh Dickins size_t size, int flags);
1263b4c7bc0SChristian Brauner ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
1273b4c7bc0SChristian Brauner char *buffer, size_t size);
1283b4c7bc0SChristian Brauner void simple_xattr_add(struct simple_xattrs *xattrs,
12938f38657SAristeu Rozanski struct simple_xattr *new_xattr);
130f2620f16SChristian Brauner int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name);
13138f38657SAristeu Rozanski
1321da177e4SLinus Torvalds #endif /* _LINUX_XATTR_H */
133