Release 4.7 fs/xattr.c
/*
File: fs/xattr.c
Extended attribute handling.
Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
*/
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/xattr.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/security.h>
#include <linux/evm.h>
#include <linux/syscalls.h>
#include <linux/export.h>
#include <linux/fsnotify.h>
#include <linux/audit.h>
#include <linux/vmalloc.h>
#include <linux/posix_acl_xattr.h>
#include <asm/uaccess.h>
/*
* Check permissions for extended attribute access. This is a bit complicated
* because different namespaces have very different rules.
*/
static int
xattr_permission(struct inode *inode, const char *name, int mask)
{
/*
* We can never set or remove an extended attribute on a read-only
* filesystem or on an immutable / append-only inode.
*/
if (mask & MAY_WRITE) {
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
return -EPERM;
}
/*
* No restriction for security.* and system.* from the VFS. Decision
* on these is left to the underlying filesystem / security module.
*/
if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
return 0;
/*
* The trusted.* namespace can only be accessed by privileged users.
*/
if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
if (!capable(CAP_SYS_ADMIN))
return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
return 0;
}
/*
* In the user.* namespace, only regular files and directories can have
* extended attributes. For sticky directories, only the owner and
* privileged users can write attributes.
*/
if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
(mask & MAY_WRITE) && !inode_owner_or_capable(inode))
return -EPERM;
}
return inode_permission(inode, mask);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
andrew morton | andrew morton | 139 | 70.92% | 1 | 16.67% |
andreas gruenbacher | andreas gruenbacher | 54 | 27.55% | 2 | 33.33% |
serge hallyn | serge hallyn | 1 | 0.51% | 1 | 16.67% |
al viro | al viro | 1 | 0.51% | 1 | 16.67% |
satyam sharma | satyam sharma | 1 | 0.51% | 1 | 16.67% |
| Total | 196 | 100.00% | 6 | 100.00% |
/**
* __vfs_setxattr_noperm - perform setxattr operation without performing
* permission checks.
*
* @dentry - object to perform setxattr on
* @name - xattr name to set
* @value - value to set @name to
* @size - size of @value
* @flags - flags to pass into filesystem operations
*
* returns the result of the internal setxattr or setsecurity operations.
*
* This function requires the caller to lock the inode's i_mutex before it
* is executed. It also assumes that the caller will make the appropriate
* permission checks.
*/
int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
struct inode *inode = dentry->d_inode;
int error = -EOPNOTSUPP;
int issec = !strncmp(name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN);
if (issec)
inode->i_flags &= ~S_NOSEC;
if (inode->i_op->setxattr) {
error = inode->i_op->setxattr(dentry, inode, name, value, size, flags);
if (!error) {
fsnotify_xattr(dentry);
security_inode_post_setxattr(dentry, name, value,
size, flags);
}
} else if (issec) {
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
error = security_inode_setsecurity(inode, suffix, value,
size, flags);
if (!error)
fsnotify_xattr(dentry);
}
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
christoph hellwig | christoph hellwig | 128 | 77.58% | 1 | 16.67% |
andi kleen | andi kleen | 25 | 15.15% | 1 | 16.67% |
david p. quigley | david p. quigley | 7 | 4.24% | 1 | 16.67% |
al viro | al viro | 2 | 1.21% | 1 | 16.67% |
david howells | david howells | 2 | 1.21% | 1 | 16.67% |
andrew morton | andrew morton | 1 | 0.61% | 1 | 16.67% |
| Total | 165 | 100.00% | 6 | 100.00% |
int
vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t size, int flags)
{
struct inode *inode = dentry->d_inode;
int error;
error = xattr_permission(inode, name, MAY_WRITE);
if (error)
return error;
inode_lock(inode);
error = security_inode_setxattr(dentry, name, value, size, flags);
if (error)
goto out;
error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
out:
inode_unlock(inode);
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david p. quigley | david p. quigley | 96 | 88.89% | 1 | 33.33% |
christoph hellwig | christoph hellwig | 10 | 9.26% | 1 | 33.33% |
al viro | al viro | 2 | 1.85% | 1 | 33.33% |
| Total | 108 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL_GPL(vfs_setxattr);
ssize_t
xattr_getsecurity(struct inode *inode, const char *name, void *value,
size_t size)
{
void *buffer = NULL;
ssize_t len;
if (!value || !size) {
len = security_inode_getsecurity(inode, name, &buffer, false);
goto out_noalloc;
}
len = security_inode_getsecurity(inode, name, &buffer, true);
if (len < 0)
return len;
if (size < len) {
len = -ERANGE;
goto out;
}
memcpy(value, buffer, len);
out:
security_release_secctx(buffer, len);
out_noalloc:
return len;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david p. quigley | david p. quigley | 119 | 99.17% | 1 | 50.00% |
christoph hellwig | christoph hellwig | 1 | 0.83% | 1 | 50.00% |
| Total | 120 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL_GPL(xattr_getsecurity);
/*
* vfs_getxattr_alloc - allocate memory, if necessary, before calling getxattr
*
* Allocate memory, if not already allocated, or re-allocate correct size,
* before retrieving the extended attribute.
*
* Returns the result of alloc, if failed, or the getxattr operation.
*/
ssize_t
vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
size_t xattr_size, gfp_t flags)
{
struct inode *inode = dentry->d_inode;
char *value = *xattr_value;
int error;
error = xattr_permission(inode, name, MAY_READ);
if (error)
return error;
if (!inode->i_op->getxattr)
return -EOPNOTSUPP;
error = inode->i_op->getxattr(dentry, inode, name, NULL, 0);
if (error < 0)
return error;
if (!value || (error > xattr_size)) {
value = krealloc(*xattr_value, error + 1, flags);
if (!value)
return -ENOMEM;
memset(value, 0, error + 1);
}
error = inode->i_op->getxattr(dentry, inode, name, value, error);
*xattr_value = value;
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
mimi zohar | mimi zohar | 174 | 97.75% | 1 | 50.00% |
al viro | al viro | 4 | 2.25% | 1 | 50.00% |
| Total | 178 | 100.00% | 2 | 100.00% |
ssize_t
vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
{
struct inode *inode = dentry->d_inode;
int error;
error = xattr_permission(inode, name, MAY_READ);
if (error)
return error;
error = security_inode_getxattr(dentry, name);
if (error)
return error;
if (!strncmp(name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN)) {
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
int ret = xattr_getsecurity(inode, suffix, value, size);
/*
* Only overwrite the return value if a security module
* is actually active.
*/
if (ret == -EOPNOTSUPP)
goto nolsm;
return ret;
}
nolsm:
if (inode->i_op->getxattr)
error = inode->i_op->getxattr(dentry, inode, name, value, size);
else
error = -EOPNOTSUPP;
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
christoph hellwig | christoph hellwig | 94 | 59.87% | 1 | 16.67% |
david p. quigley | david p. quigley | 40 | 25.48% | 2 | 33.33% |
andrew morton | andrew morton | 20 | 12.74% | 1 | 16.67% |
al viro | al viro | 2 | 1.27% | 1 | 16.67% |
david howells | david howells | 1 | 0.64% | 1 | 16.67% |
| Total | 157 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(vfs_getxattr);
ssize_t
vfs_listxattr(struct dentry *d, char *list, size_t size)
{
ssize_t error;
error = security_inode_listxattr(d);
if (error)
return error;
error = -EOPNOTSUPP;
if (d->d_inode->i_op->listxattr) {
error = d->d_inode->i_op->listxattr(d, list, size);
} else {
error = security_inode_listsecurity(d->d_inode, list, size);
if (size && error > size)
error = -ERANGE;
}
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
bill nottingham | bill nottingham | 100 | 100.00% | 1 | 100.00% |
| Total | 100 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL_GPL(vfs_listxattr);
int
vfs_removexattr(struct dentry *dentry, const char *name)
{
struct inode *inode = dentry->d_inode;
int error;
if (!inode->i_op->removexattr)
return -EOPNOTSUPP;
error = xattr_permission(inode, name, MAY_WRITE);
if (error)
return error;
inode_lock(inode);
error = security_inode_removexattr(dentry, name);
if (error)
goto out;
error = inode->i_op->removexattr(dentry, name);
if (!error) {
fsnotify_xattr(dentry);
evm_inode_post_removexattr(dentry, name);
}
out:
inode_unlock(inode);
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
christoph hellwig | christoph hellwig | 78 | 64.46% | 1 | 14.29% |
andrew morton | andrew morton | 18 | 14.88% | 1 | 14.29% |
mimi zohar | mimi zohar | 13 | 10.74% | 2 | 28.57% |
dmitry kasatkin | dmitry kasatkin | 9 | 7.44% | 1 | 14.29% |
al viro | al viro | 2 | 1.65% | 1 | 14.29% |
david howells | david howells | 1 | 0.83% | 1 | 14.29% |
| Total | 121 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL_GPL(vfs_removexattr);
/*
* Extended attribute SET operations
*/
static long
setxattr(struct dentry *d, const char __user *name, const void __user *value,
size_t size, int flags)
{
int error;
void *kvalue = NULL;
char kname[XATTR_NAME_MAX + 1];
if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
return -EINVAL;
error = strncpy_from_user(kname, name, sizeof(kname));
if (error == 0 || error == sizeof(kname))
error = -ERANGE;
if (error < 0)
return error;
if (size) {
if (size > XATTR_SIZE_MAX)
return -E2BIG;
kvalue = kmalloc(size, GFP_KERNEL | __GFP_NOWARN);
if (!kvalue) {
kvalue = vmalloc(size);
if (!kvalue)
return -ENOMEM;
}
if (copy_from_user(kvalue, value, size)) {
error = -EFAULT;
goto out;
}
if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
(strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
posix_acl_fix_xattr_from_user(kvalue, size);
}
error = vfs_setxattr(d, kname, kvalue, size, flags);
out:
kvfree(kvalue);
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 78 | 34.06% | 1 | 9.09% |
andrew morton | andrew morton | 57 | 24.89% | 2 | 18.18% |
nathan scott | nathan scott | 32 | 13.97% | 1 | 9.09% |
eric w. biederman | eric w. biederman | 31 | 13.54% | 1 | 9.09% |
stephen d. smalley | stephen d. smalley | 15 | 6.55% | 1 | 9.09% |
christoph hellwig | christoph hellwig | 7 | 3.06% | 1 | 9.09% |
richard weinberger | richard weinberger | 3 | 1.31% | 1 | 9.09% |
andries brouwer | andries brouwer | 2 | 0.87% | 1 | 9.09% |
li zefan | li zefan | 2 | 0.87% | 1 | 9.09% |
david howells | david howells | 2 | 0.87% | 1 | 9.09% |
| Total | 229 | 100.00% | 11 | 100.00% |
static int path_setxattr(const char __user *pathname,
const char __user *name, const void __user *value,
size_t size, int flags, unsigned int lookup_flags)
{
struct path path;
int error;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
return error;
error = mnt_want_write(path.mnt);
if (!error) {
error = setxattr(path.dentry, name, value, size, flags);
mnt_drop_write(path.mnt);
}
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
goto retry;
}
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 43 | 32.82% | 1 | 14.29% |
eric biggers | eric biggers | 32 | 24.43% | 1 | 14.29% |
jeff layton | jeff layton | 25 | 19.08% | 1 | 14.29% |
dave hansen | dave hansen | 23 | 17.56% | 1 | 14.29% |
jan blunck | jan blunck | 4 | 3.05% | 2 | 28.57% |
al viro | al viro | 4 | 3.05% | 1 | 14.29% |
| Total | 131 | 100.00% | 7 | 100.00% |
SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
const char __user *, name, const void __user *, value,
size_t, size, int, flags)
{
return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW);
}
SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
const char __user *, name, const void __user *, value,
size_t, size, int, flags)
{
return path_setxattr(pathname, name, value, size, flags, 0);
}
SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
const void __user *,value, size_t, size, int, flags)
{
struct fd f = fdget(fd);
int error = -EBADF;
if (!f.file)
return error;
audit_file(f.file);
error = mnt_want_write_file(f.file);
if (!error) {
error = setxattr(f.file->f_path.dentry, name, value, size, flags);
mnt_drop_write_file(f.file);
}
fdput(f);
return error;
}
/*
* Extended attribute GET operations
*/
static ssize_t
getxattr(struct dentry *d, const char __user *name, void __user *value,
size_t size)
{
ssize_t error;
void *kvalue = NULL;
char kname[XATTR_NAME_MAX + 1];
error = strncpy_from_user(kname, name, sizeof(kname));
if (error == 0 || error == sizeof(kname))
error = -ERANGE;
if (error < 0)
return error;
if (size) {
if (size > XATTR_SIZE_MAX)
size = XATTR_SIZE_MAX;
kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
if (!kvalue) {
kvalue = vmalloc(size);
if (!kvalue)
return -ENOMEM;
}
}
error = vfs_getxattr(d, kname, kvalue, size);
if (error > 0) {
if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
(strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
posix_acl_fix_xattr_to_user(kvalue, size);
if (size && copy_to_user(value, kvalue, error))
error = -EFAULT;
} else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
/* The file system tried to returned a value bigger
than XATTR_SIZE_MAX bytes. Not possible. */
error = -E2BIG;
}
kvfree(kvalue);
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 85 | 36.80% | 1 | 6.25% |
andrew morton | andrew morton | 45 | 19.48% | 2 | 12.50% |
nathan scott | nathan scott | 35 | 15.15% | 3 | 18.75% |
eric w. biederman | eric w. biederman | 31 | 13.42% | 1 | 6.25% |
sasha levin | sasha levin | 14 | 6.06% | 1 | 6.25% |
stephen d. smalley | stephen d. smalley | 10 | 4.33% | 2 | 12.50% |
richard weinberger | richard weinberger | 3 | 1.30% | 1 | 6.25% |
greg kroah-hartman | greg kroah-hartman | 3 | 1.30% | 1 | 6.25% |
andries brouwer | andries brouwer | 2 | 0.87% | 1 | 6.25% |
james morris | james morris | 1 | 0.43% | 1 | 6.25% |
christoph hellwig | christoph hellwig | 1 | 0.43% | 1 | 6.25% |
david howells | david howells | 1 | 0.43% | 1 | 6.25% |
| Total | 231 | 100.00% | 16 | 100.00% |
static ssize_t path_getxattr(const char __user *pathname,
const char __user *name, void __user *value,
size_t size, unsigned int lookup_flags)
{
struct path path;
ssize_t error;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
return error;
error = getxattr(path.dentry, name, value, size);
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
goto retry;
}
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 40 | 39.22% | 1 | 14.29% |
eric biggers | eric biggers | 28 | 27.45% | 1 | 14.29% |
jeff layton | jeff layton | 25 | 24.51% | 1 | 14.29% |
jan blunck | jan blunck | 4 | 3.92% | 2 | 28.57% |
al viro | al viro | 4 | 3.92% | 1 | 14.29% |
nathan scott | nathan scott | 1 | 0.98% | 1 | 14.29% |
| Total | 102 | 100.00% | 7 | 100.00% |
SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
const char __user *, name, void __user *, value, size_t, size)
{
return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW);
}
SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
const char __user *, name, void __user *, value, size_t, size)
{
return path_getxattr(pathname, name, value, size, 0);
}
SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
void __user *, value, size_t, size)
{
struct fd f = fdget(fd);
ssize_t error = -EBADF;
if (!f.file)
return error;
audit_file(f.file);
error = getxattr(f.file->f_path.dentry, name, value, size);
fdput(f);
return error;
}
/*
* Extended attribute LIST operations
*/
static ssize_t
listxattr(struct dentry *d, char __user *list, size_t size)
{
ssize_t error;
char *klist = NULL;
if (size) {
if (size > XATTR_LIST_MAX)
size = XATTR_LIST_MAX;
klist = kmalloc(size, __GFP_NOWARN | GFP_KERNEL);
if (!klist) {
klist = vmalloc(size);
if (!klist)
return -ENOMEM;
}
}
error = vfs_listxattr(d, klist, size);
if (error > 0) {
if (size && copy_to_user(list, klist, error))
error = -EFAULT;
} else if (error == -ERANGE && size >= XATTR_LIST_MAX) {
/* The file system tried to returned a list bigger
than XATTR_LIST_MAX bytes. Not possible. */
error = -E2BIG;
}
kvfree(klist);
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 64 | 44.76% | 1 | 9.09% |
andrew morton | andrew morton | 58 | 40.56% | 3 | 27.27% |
stephen d. smalley | stephen d. smalley | 11 | 7.69% | 1 | 9.09% |
nathan scott | nathan scott | 3 | 2.10% | 2 | 18.18% |
richard weinberger | richard weinberger | 3 | 2.10% | 1 | 9.09% |
dave jones | dave jones | 2 | 1.40% | 1 | 9.09% |
bill nottingham | bill nottingham | 1 | 0.70% | 1 | 9.09% |
andries brouwer | andries brouwer | 1 | 0.70% | 1 | 9.09% |
| Total | 143 | 100.00% | 11 | 100.00% |
static ssize_t path_listxattr(const char __user *pathname, char __user *list,
size_t size, unsigned int lookup_flags)
{
struct path path;
ssize_t error;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
return error;
error = listxattr(path.dentry, list, size);
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
goto retry;
}
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 38 | 40.43% | 1 | 14.29% |
jeff layton | jeff layton | 25 | 26.60% | 1 | 14.29% |
eric biggers | eric biggers | 22 | 23.40% | 1 | 14.29% |
al viro | al viro | 4 | 4.26% | 1 | 14.29% |
jan blunck | jan blunck | 4 | 4.26% | 2 | 28.57% |
nathan scott | nathan scott | 1 | 1.06% | 1 | 14.29% |
| Total | 94 | 100.00% | 7 | 100.00% |
SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
size_t, size)
{
return path_listxattr(pathname, list, size, LOOKUP_FOLLOW);
}
SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
size_t, size)
{
return path_listxattr(pathname, list, size, 0);
}
SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
{
struct fd f = fdget(fd);
ssize_t error = -EBADF;
if (!f.file)
return error;
audit_file(f.file);
error = listxattr(f.file->f_path.dentry, list, size);
fdput(f);
return error;
}
/*
* Extended attribute REMOVE operations
*/
static long
removexattr(struct dentry *d, const char __user *name)
{
int error;
char kname[XATTR_NAME_MAX + 1];
error = strncpy_from_user(kname, name, sizeof(kname));
if (error == 0 || error == sizeof(kname))
error = -ERANGE;
if (error < 0)
return error;
return vfs_removexattr(d, kname);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 41 | 53.25% | 1 | 20.00% |
nathan scott | nathan scott | 32 | 41.56% | 1 | 20.00% |
christoph hellwig | christoph hellwig | 2 | 2.60% | 1 | 20.00% |
andries brouwer | andries brouwer | 1 | 1.30% | 1 | 20.00% |
david howells | david howells | 1 | 1.30% | 1 | 20.00% |
| Total | 77 | 100.00% | 5 | 100.00% |
static int path_removexattr(const char __user *pathname,
const char __user *name, unsigned int lookup_flags)
{
struct path path;
int error;
retry:
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
if (error)
return error;
error = mnt_want_write(path.mnt);
if (!error) {
error = removexattr(path.dentry, name);
mnt_drop_write(path.mnt);
}
path_put(&path);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
goto retry;
}
return error;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
linus torvalds | linus torvalds | 37 | 32.74% | 1 | 14.29% |
jeff layton | jeff layton | 25 | 22.12% | 1 | 14.29% |
dave hansen | dave hansen | 23 | 20.35% | 1 | 14.29% |
eric biggers | eric biggers | 20 | 17.70% | 1 | 14.29% |
jan blunck | jan blunck | 4 | 3.54% | 2 | 28.57% |
al viro | al viro | 4 | 3.54% | 1 | 14.29% |
| Total | 113 | 100.00% | 7 | 100.00% |
SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
const char __user *, name)
{
return path_removexattr(pathname, name, LOOKUP_FOLLOW);
}
SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
const char __user *, name)
{
return path_removexattr(pathname, name, 0);
}
SYSCALL_DEFINE2(fremovexattr,