forked from Minki/linux
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "Followups to the parallel lookup work: - update docs - restore killability of the places that used to take ->i_mutex killably now that we have down_write_killable() merged - Additionally, it turns out that I missed a prerequisite for security_d_instantiate() stuff - ->getxattr() wasn't the only thing that could be called before dentry is attached to inode; with smack we needed the same treatment applied to ->setxattr() as well" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: switch ->setxattr() to passing dentry and inode separately switch xattr_handler->set() to passing dentry and inode separately restore killability of old mutex_lock_killable(&inode->i_mutex) users add down_write_killable_nested() update D/f/directory-locking
This commit is contained in:
commit
d102a56edb
@ -1,30 +1,37 @@
|
|||||||
Locking scheme used for directory operations is based on two
|
Locking scheme used for directory operations is based on two
|
||||||
kinds of locks - per-inode (->i_mutex) and per-filesystem
|
kinds of locks - per-inode (->i_rwsem) and per-filesystem
|
||||||
(->s_vfs_rename_mutex).
|
(->s_vfs_rename_mutex).
|
||||||
|
|
||||||
When taking the i_mutex on multiple non-directory objects, we
|
When taking the i_rwsem on multiple non-directory objects, we
|
||||||
always acquire the locks in order by increasing address. We'll call
|
always acquire the locks in order by increasing address. We'll call
|
||||||
that "inode pointer" order in the following.
|
that "inode pointer" order in the following.
|
||||||
|
|
||||||
For our purposes all operations fall in 5 classes:
|
For our purposes all operations fall in 5 classes:
|
||||||
|
|
||||||
1) read access. Locking rules: caller locks directory we are accessing.
|
1) read access. Locking rules: caller locks directory we are accessing.
|
||||||
|
The lock is taken shared.
|
||||||
|
|
||||||
2) object creation. Locking rules: same as above.
|
2) object creation. Locking rules: same as above, but the lock is taken
|
||||||
|
exclusive.
|
||||||
|
|
||||||
3) object removal. Locking rules: caller locks parent, finds victim,
|
3) object removal. Locking rules: caller locks parent, finds victim,
|
||||||
locks victim and calls the method.
|
locks victim and calls the method. Locks are exclusive.
|
||||||
|
|
||||||
4) rename() that is _not_ cross-directory. Locking rules: caller locks
|
4) rename() that is _not_ cross-directory. Locking rules: caller locks
|
||||||
the parent and finds source and target. If target already exists, lock
|
the parent and finds source and target. In case of exchange (with
|
||||||
it. If source is a non-directory, lock it. If that means we need to
|
RENAME_EXCHANGE in rename2() flags argument) lock both. In any case,
|
||||||
lock both, lock them in inode pointer order.
|
if the target already exists, lock it. If the source is a non-directory,
|
||||||
|
lock it. If we need to lock both, lock them in inode pointer order.
|
||||||
|
Then call the method. All locks are exclusive.
|
||||||
|
NB: we might get away with locking the the source (and target in exchange
|
||||||
|
case) shared.
|
||||||
|
|
||||||
5) link creation. Locking rules:
|
5) link creation. Locking rules:
|
||||||
* lock parent
|
* lock parent
|
||||||
* check that source is not a directory
|
* check that source is not a directory
|
||||||
* lock source
|
* lock source
|
||||||
* call the method.
|
* call the method.
|
||||||
|
All locks are exclusive.
|
||||||
|
|
||||||
6) cross-directory rename. The trickiest in the whole bunch. Locking
|
6) cross-directory rename. The trickiest in the whole bunch. Locking
|
||||||
rules:
|
rules:
|
||||||
@ -35,11 +42,12 @@ rules:
|
|||||||
fail with -ENOTEMPTY
|
fail with -ENOTEMPTY
|
||||||
* if new parent is equal to or is a descendent of source
|
* if new parent is equal to or is a descendent of source
|
||||||
fail with -ELOOP
|
fail with -ELOOP
|
||||||
* If target exists, lock it. If source is a non-directory, lock
|
* If it's an exchange, lock both the source and the target.
|
||||||
it. In case that means we need to lock both source and target,
|
* If the target exists, lock it. If the source is a non-directory,
|
||||||
do so in inode pointer order.
|
lock it. If we need to lock both, do so in inode pointer order.
|
||||||
* call the method.
|
* call the method.
|
||||||
|
All ->i_rwsem are taken exclusive. Again, we might get away with locking
|
||||||
|
the the source (and target in exchange case) shared.
|
||||||
|
|
||||||
The rules above obviously guarantee that all directories that are going to be
|
The rules above obviously guarantee that all directories that are going to be
|
||||||
read, modified or removed by method will be locked by caller.
|
read, modified or removed by method will be locked by caller.
|
||||||
@ -73,7 +81,7 @@ objects - A < B iff A is an ancestor of B.
|
|||||||
attempt to acquire some lock and already holds at least one lock. Let's
|
attempt to acquire some lock and already holds at least one lock. Let's
|
||||||
consider the set of contended locks. First of all, filesystem lock is
|
consider the set of contended locks. First of all, filesystem lock is
|
||||||
not contended, since any process blocked on it is not holding any locks.
|
not contended, since any process blocked on it is not holding any locks.
|
||||||
Thus all processes are blocked on ->i_mutex.
|
Thus all processes are blocked on ->i_rwsem.
|
||||||
|
|
||||||
By (3), any process holding a non-directory lock can only be
|
By (3), any process holding a non-directory lock can only be
|
||||||
waiting on another non-directory lock with a larger address. Therefore
|
waiting on another non-directory lock with a larger address. Therefore
|
||||||
|
@ -578,3 +578,10 @@ in your dentry operations instead.
|
|||||||
--
|
--
|
||||||
[mandatory]
|
[mandatory]
|
||||||
->atomic_open() calls without O_CREAT may happen in parallel.
|
->atomic_open() calls without O_CREAT may happen in parallel.
|
||||||
|
--
|
||||||
|
[mandatory]
|
||||||
|
->setxattr() and xattr_handler.set() get dentry and inode passed separately.
|
||||||
|
dentry might be yet to be attached to inode, so do _not_ use its ->d_inode
|
||||||
|
in the instances. Rationale: !@#!@# security_d_instantiate() needs to be
|
||||||
|
called before we attach dentry to inode and !@#!@##!@$!$#!@#$!@$!@$ smack
|
||||||
|
->d_instantiate() uses not just ->getxattr() but ->setxattr() as well.
|
||||||
|
@ -976,8 +976,8 @@ static inline __u64 ll_file_maxbytes(struct inode *inode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* llite/xattr.c */
|
/* llite/xattr.c */
|
||||||
int ll_setxattr(struct dentry *dentry, const char *name,
|
int ll_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags);
|
const char *name, const void *value, size_t size, int flags);
|
||||||
ssize_t ll_getxattr(struct dentry *dentry, struct inode *inode,
|
ssize_t ll_getxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const char *name, void *buffer, size_t size);
|
const char *name, void *buffer, size_t size);
|
||||||
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
||||||
|
@ -211,11 +211,9 @@ int ll_setxattr_common(struct inode *inode, const char *name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ll_setxattr(struct dentry *dentry, const char *name,
|
int ll_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value, size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
LASSERT(inode);
|
LASSERT(inode);
|
||||||
LASSERT(name);
|
LASSERT(name);
|
||||||
|
|
||||||
|
@ -239,13 +239,13 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
|
static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
struct posix_acl *acl;
|
struct posix_acl *acl;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
v9ses = v9fs_dentry2v9ses(dentry);
|
v9ses = v9fs_dentry2v9ses(dentry);
|
||||||
/*
|
/*
|
||||||
|
@ -147,8 +147,9 @@ static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
|
static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
const char *full_name = xattr_full_name(handler, name);
|
const char *full_name = xattr_full_name(handler, name);
|
||||||
|
|
||||||
|
@ -100,8 +100,8 @@ static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bad_inode_setxattr(struct dentry *dentry, const char *name,
|
static int bad_inode_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value, size_t size, int flags)
|
||||||
{
|
{
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -846,11 +846,9 @@ static noinline int btrfs_mksubvol(struct path *parent,
|
|||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
inode_lock_nested(dir, I_MUTEX_PARENT);
|
error = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT);
|
||||||
// XXX: should've been
|
if (error == -EINTR)
|
||||||
// mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT);
|
return error;
|
||||||
// if (error == -EINTR)
|
|
||||||
// return error;
|
|
||||||
|
|
||||||
dentry = lookup_one_len(name, parent->dentry, namelen);
|
dentry = lookup_one_len(name, parent->dentry, namelen);
|
||||||
error = PTR_ERR(dentry);
|
error = PTR_ERR(dentry);
|
||||||
@ -2377,11 +2375,9 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
||||||
inode_lock_nested(dir, I_MUTEX_PARENT);
|
err = down_write_killable_nested(&dir->i_rwsem, I_MUTEX_PARENT);
|
||||||
// XXX: should've been
|
if (err == -EINTR)
|
||||||
// err = mutex_lock_killable_nested(&dir->i_mutex, I_MUTEX_PARENT);
|
goto out_drop_write;
|
||||||
// if (err == -EINTR)
|
|
||||||
// goto out_drop_write;
|
|
||||||
dentry = lookup_one_len(vol_args->name, parent, namelen);
|
dentry = lookup_one_len(vol_args->name, parent, namelen);
|
||||||
if (IS_ERR(dentry)) {
|
if (IS_ERR(dentry)) {
|
||||||
err = PTR_ERR(dentry);
|
err = PTR_ERR(dentry);
|
||||||
@ -2571,7 +2567,7 @@ out_dput:
|
|||||||
dput(dentry);
|
dput(dentry);
|
||||||
out_unlock_dir:
|
out_unlock_dir:
|
||||||
inode_unlock(dir);
|
inode_unlock(dir);
|
||||||
//out_drop_write:
|
out_drop_write:
|
||||||
mnt_drop_write_file(file);
|
mnt_drop_write_file(file);
|
||||||
out:
|
out:
|
||||||
kfree(vol_args);
|
kfree(vol_args);
|
||||||
|
@ -380,23 +380,21 @@ static int btrfs_xattr_handler_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
|
static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size,
|
const char *name, const void *buffer,
|
||||||
int flags)
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
name = xattr_full_name(handler, name);
|
name = xattr_full_name(handler, name);
|
||||||
return __btrfs_setxattr(NULL, inode, name, buffer, size, flags);
|
return __btrfs_setxattr(NULL, inode, name, buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
|
static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry,
|
struct dentry *unused, struct inode *inode,
|
||||||
const char *name, const void *value,
|
const char *name, const void *value,
|
||||||
size_t size, int flags)
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
name = xattr_full_name(handler, name);
|
name = xattr_full_name(handler, name);
|
||||||
return btrfs_set_prop(d_inode(dentry), name, value, size, flags);
|
return btrfs_set_prop(inode, name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct xattr_handler btrfs_security_xattr_handler = {
|
static const struct xattr_handler btrfs_security_xattr_handler = {
|
||||||
|
@ -1056,12 +1056,13 @@ static int ceph_get_xattr_handler(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ceph_set_xattr_handler(const struct xattr_handler *handler,
|
static int ceph_set_xattr_handler(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
if (!ceph_is_valid_xattr(name))
|
if (!ceph_is_valid_xattr(name))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return __ceph_setxattr(d_inode(dentry), name, value, size, flags);
|
return __ceph_setxattr(inode, name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xattr_handler ceph_other_xattr_handler = {
|
const struct xattr_handler ceph_other_xattr_handler = {
|
||||||
|
@ -39,8 +39,9 @@
|
|||||||
enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT };
|
enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT };
|
||||||
|
|
||||||
static int cifs_xattr_set(const struct xattr_handler *handler,
|
static int cifs_xattr_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
int rc = -EOPNOTSUPP;
|
int rc = -EOPNOTSUPP;
|
||||||
unsigned int xid;
|
unsigned int xid;
|
||||||
@ -99,12 +100,12 @@ static int cifs_xattr_set(const struct xattr_handler *handler,
|
|||||||
if (value &&
|
if (value &&
|
||||||
pTcon->ses->server->ops->set_acl)
|
pTcon->ses->server->ops->set_acl)
|
||||||
rc = pTcon->ses->server->ops->set_acl(pacl,
|
rc = pTcon->ses->server->ops->set_acl(pacl,
|
||||||
size, d_inode(dentry),
|
size, inode,
|
||||||
full_path, CIFS_ACL_DACL);
|
full_path, CIFS_ACL_DACL);
|
||||||
else
|
else
|
||||||
rc = -EOPNOTSUPP;
|
rc = -EOPNOTSUPP;
|
||||||
if (rc == 0) /* force revalidate of the inode */
|
if (rc == 0) /* force revalidate of the inode */
|
||||||
CIFS_I(d_inode(dentry))->time = 0;
|
CIFS_I(inode)->time = 0;
|
||||||
kfree(pacl);
|
kfree(pacl);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_CIFS_ACL */
|
#endif /* CONFIG_CIFS_ACL */
|
||||||
|
@ -1141,12 +1141,13 @@ ecryptfs_write_metadata_to_contents(struct inode *ecryptfs_inode,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
|
ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
|
||||||
|
struct inode *ecryptfs_inode,
|
||||||
char *page_virt, size_t size)
|
char *page_virt, size_t size)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ecryptfs_setxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME, page_virt,
|
rc = ecryptfs_setxattr(ecryptfs_dentry, ecryptfs_inode,
|
||||||
size, 0);
|
ECRYPTFS_XATTR_NAME, page_virt, size, 0);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1215,8 +1216,8 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
|
|||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
|
||||||
rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt,
|
rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, ecryptfs_inode,
|
||||||
size);
|
virt, size);
|
||||||
else
|
else
|
||||||
rc = ecryptfs_write_metadata_to_contents(ecryptfs_inode, virt,
|
rc = ecryptfs_write_metadata_to_contents(ecryptfs_inode, virt,
|
||||||
virt_len);
|
virt_len);
|
||||||
|
@ -609,8 +609,8 @@ ssize_t
|
|||||||
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
|
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
|
||||||
const char *name, void *value, size_t size);
|
const char *name, void *value, size_t size);
|
||||||
int
|
int
|
||||||
ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
|
||||||
size_t size, int flags);
|
const void *value, size_t size, int flags);
|
||||||
int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
|
int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
|
||||||
#ifdef CONFIG_ECRYPT_FS_MESSAGING
|
#ifdef CONFIG_ECRYPT_FS_MESSAGING
|
||||||
int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
|
int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
|
||||||
|
@ -1001,7 +1001,8 @@ static int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
|
const char *name, const void *value,
|
||||||
size_t size, int flags)
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@ -1014,8 +1015,8 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = vfs_setxattr(lower_dentry, name, value, size, flags);
|
rc = vfs_setxattr(lower_dentry, name, value, size, flags);
|
||||||
if (!rc && d_really_is_positive(dentry))
|
if (!rc && inode)
|
||||||
fsstack_copy_attr_all(d_inode(dentry), d_inode(lower_dentry));
|
fsstack_copy_attr_all(inode, d_inode(lower_dentry));
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,8 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
|
|||||||
if (size < 0)
|
if (size < 0)
|
||||||
size = 8;
|
size = 8;
|
||||||
put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
|
put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
|
||||||
rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
|
rc = lower_inode->i_op->setxattr(lower_dentry, lower_inode,
|
||||||
|
ECRYPTFS_XATTR_NAME,
|
||||||
xattr_virt, size, 0);
|
xattr_virt, size, 0);
|
||||||
inode_unlock(lower_inode);
|
inode_unlock(lower_inode);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
@ -18,10 +18,11 @@ ext2_xattr_security_get(const struct xattr_handler *handler,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ext2_xattr_security_set(const struct xattr_handler *handler,
|
ext2_xattr_security_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_SECURITY, name,
|
return ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY, name,
|
||||||
value, size, flags);
|
value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,11 @@ ext2_xattr_trusted_get(const struct xattr_handler *handler,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ext2_xattr_trusted_set(const struct xattr_handler *handler,
|
ext2_xattr_trusted_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_TRUSTED, name,
|
return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name,
|
||||||
value, size, flags);
|
value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +29,14 @@ ext2_xattr_user_get(const struct xattr_handler *handler,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ext2_xattr_user_set(const struct xattr_handler *handler,
|
ext2_xattr_user_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
if (!test_opt(dentry->d_sb, XATTR_USER))
|
if (!test_opt(inode->i_sb, XATTR_USER))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
return ext2_xattr_set(d_inode(dentry), EXT2_XATTR_INDEX_USER,
|
return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER,
|
||||||
name, value, size, flags);
|
name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +22,11 @@ ext4_xattr_security_get(const struct xattr_handler *handler,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ext4_xattr_security_set(const struct xattr_handler *handler,
|
ext4_xattr_security_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_SECURITY,
|
return ext4_xattr_set(inode, EXT4_XATTR_INDEX_SECURITY,
|
||||||
name, value, size, flags);
|
name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,11 @@ ext4_xattr_trusted_get(const struct xattr_handler *handler,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ext4_xattr_trusted_set(const struct xattr_handler *handler,
|
ext4_xattr_trusted_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_TRUSTED,
|
return ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED,
|
||||||
name, value, size, flags);
|
name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,12 +30,13 @@ ext4_xattr_user_get(const struct xattr_handler *handler,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
ext4_xattr_user_set(const struct xattr_handler *handler,
|
ext4_xattr_user_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
if (!test_opt(dentry->d_sb, XATTR_USER))
|
if (!test_opt(inode->i_sb, XATTR_USER))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return ext4_xattr_set(d_inode(dentry), EXT4_XATTR_INDEX_USER,
|
return ext4_xattr_set(inode, EXT4_XATTR_INDEX_USER,
|
||||||
name, value, size, flags);
|
name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,10 +50,11 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
|
static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name, const void *value,
|
struct dentry *unused, struct inode *inode,
|
||||||
|
const char *name, const void *value,
|
||||||
size_t size, int flags)
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
|
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
|
||||||
|
|
||||||
switch (handler->flags) {
|
switch (handler->flags) {
|
||||||
case F2FS_XATTR_INDEX_USER:
|
case F2FS_XATTR_INDEX_USER:
|
||||||
@ -69,7 +70,7 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
|
|||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return f2fs_setxattr(d_inode(dentry), handler->flags, name,
|
return f2fs_setxattr(inode, handler->flags, name,
|
||||||
value, size, NULL, flags);
|
value, size, NULL, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,11 +96,10 @@ static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
|
static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name, const void *value,
|
struct dentry *unused, struct inode *inode,
|
||||||
|
const char *name, const void *value,
|
||||||
size_t size, int flags)
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
if (!inode_owner_or_capable(inode))
|
if (!inode_owner_or_capable(inode))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
|
@ -1719,10 +1719,10 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
|
|||||||
return fuse_update_attributes(inode, stat, NULL, NULL);
|
return fuse_update_attributes(inode, stat, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fuse_setxattr(struct dentry *entry, const char *name,
|
static int fuse_setxattr(struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(entry);
|
|
||||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||||
FUSE_ARGS(args);
|
FUSE_ARGS(args);
|
||||||
struct fuse_setxattr_in inarg;
|
struct fuse_setxattr_in inarg;
|
||||||
|
@ -1251,10 +1251,10 @@ int __gfs2_xattr_set(struct inode *inode, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gfs2_xattr_set(const struct xattr_handler *handler,
|
static int gfs2_xattr_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
struct gfs2_inode *ip = GFS2_I(inode);
|
struct gfs2_inode *ip = GFS2_I(inode);
|
||||||
struct gfs2_holder gh;
|
struct gfs2_holder gh;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
#include "hfs_fs.h"
|
#include "hfs_fs.h"
|
||||||
#include "btree.h"
|
#include "btree.h"
|
||||||
|
|
||||||
int hfs_setxattr(struct dentry *dentry, const char *name,
|
int hfs_setxattr(struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
struct hfs_find_data fd;
|
struct hfs_find_data fd;
|
||||||
hfs_cat_rec rec;
|
hfs_cat_rec rec;
|
||||||
struct hfs_cat_file *file;
|
struct hfs_cat_file *file;
|
||||||
|
@ -212,7 +212,7 @@ extern void hfs_evict_inode(struct inode *);
|
|||||||
extern void hfs_delete_inode(struct inode *);
|
extern void hfs_delete_inode(struct inode *);
|
||||||
|
|
||||||
/* attr.c */
|
/* attr.c */
|
||||||
extern int hfs_setxattr(struct dentry *dentry, const char *name,
|
extern int hfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
|
||||||
const void *value, size_t size, int flags);
|
const void *value, size_t size, int flags);
|
||||||
extern ssize_t hfs_getxattr(struct dentry *dentry, struct inode *inode,
|
extern ssize_t hfs_getxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const char *name, void *value, size_t size);
|
const char *name, void *value, size_t size);
|
||||||
|
@ -424,7 +424,7 @@ static int copy_name(char *buffer, const char *xattr_name, int name_len)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hfsplus_setxattr(struct dentry *dentry, const char *name,
|
int hfsplus_setxattr(struct inode *inode, const char *name,
|
||||||
const void *value, size_t size, int flags,
|
const void *value, size_t size, int flags,
|
||||||
const char *prefix, size_t prefixlen)
|
const char *prefix, size_t prefixlen)
|
||||||
{
|
{
|
||||||
@ -437,8 +437,7 @@ int hfsplus_setxattr(struct dentry *dentry, const char *name,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
strcpy(xattr_name, prefix);
|
strcpy(xattr_name, prefix);
|
||||||
strcpy(xattr_name + prefixlen, name);
|
strcpy(xattr_name + prefixlen, name);
|
||||||
res = __hfsplus_setxattr(d_inode(dentry), xattr_name, value, size,
|
res = __hfsplus_setxattr(inode, xattr_name, value, size, flags);
|
||||||
flags);
|
|
||||||
kfree(xattr_name);
|
kfree(xattr_name);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -864,8 +863,9 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
|
static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size, int flags)
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Don't allow setting properly prefixed attributes
|
* Don't allow setting properly prefixed attributes
|
||||||
@ -880,7 +880,7 @@ static int hfsplus_osx_setxattr(const struct xattr_handler *handler,
|
|||||||
* creates), so we pass the name through unmodified (after
|
* creates), so we pass the name through unmodified (after
|
||||||
* ensuring it doesn't conflict with another namespace).
|
* ensuring it doesn't conflict with another namespace).
|
||||||
*/
|
*/
|
||||||
return __hfsplus_setxattr(d_inode(dentry), name, buffer, size, flags);
|
return __hfsplus_setxattr(inode, name, buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xattr_handler hfsplus_xattr_osx_handler = {
|
const struct xattr_handler hfsplus_xattr_osx_handler = {
|
||||||
|
@ -21,7 +21,7 @@ extern const struct xattr_handler *hfsplus_xattr_handlers[];
|
|||||||
int __hfsplus_setxattr(struct inode *inode, const char *name,
|
int __hfsplus_setxattr(struct inode *inode, const char *name,
|
||||||
const void *value, size_t size, int flags);
|
const void *value, size_t size, int flags);
|
||||||
|
|
||||||
int hfsplus_setxattr(struct dentry *dentry, const char *name,
|
int hfsplus_setxattr(struct inode *inode, const char *name,
|
||||||
const void *value, size_t size, int flags,
|
const void *value, size_t size, int flags,
|
||||||
const char *prefix, size_t prefixlen);
|
const char *prefix, size_t prefixlen);
|
||||||
|
|
||||||
|
@ -23,10 +23,11 @@ static int hfsplus_security_getxattr(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int hfsplus_security_setxattr(const struct xattr_handler *handler,
|
static int hfsplus_security_setxattr(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size, int flags)
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return hfsplus_setxattr(dentry, name, buffer, size, flags,
|
return hfsplus_setxattr(inode, name, buffer, size, flags,
|
||||||
XATTR_SECURITY_PREFIX,
|
XATTR_SECURITY_PREFIX,
|
||||||
XATTR_SECURITY_PREFIX_LEN);
|
XATTR_SECURITY_PREFIX_LEN);
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,11 @@ static int hfsplus_trusted_getxattr(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int hfsplus_trusted_setxattr(const struct xattr_handler *handler,
|
static int hfsplus_trusted_setxattr(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size, int flags)
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return hfsplus_setxattr(dentry, name, buffer, size, flags,
|
return hfsplus_setxattr(inode, name, buffer, size, flags,
|
||||||
XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
|
XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,10 +21,11 @@ static int hfsplus_user_getxattr(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int hfsplus_user_setxattr(const struct xattr_handler *handler,
|
static int hfsplus_user_setxattr(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size, int flags)
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return hfsplus_setxattr(dentry, name, buffer, size, flags,
|
return hfsplus_setxattr(inode, name, buffer, size, flags,
|
||||||
XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
|
XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,10 +57,11 @@ static int jffs2_security_getxattr(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int jffs2_security_setxattr(const struct xattr_handler *handler,
|
static int jffs2_security_setxattr(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size, int flags)
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_SECURITY,
|
return do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
|
||||||
name, buffer, size, flags);
|
name, buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,11 @@ static int jffs2_trusted_getxattr(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
|
static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size, int flags)
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_TRUSTED,
|
return do_jffs2_setxattr(inode, JFFS2_XPREFIX_TRUSTED,
|
||||||
name, buffer, size, flags);
|
name, buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +25,11 @@ static int jffs2_user_getxattr(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int jffs2_user_setxattr(const struct xattr_handler *handler,
|
static int jffs2_user_setxattr(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buffer, size_t size, int flags)
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return do_jffs2_setxattr(d_inode(dentry), JFFS2_XPREFIX_USER,
|
return do_jffs2_setxattr(inode, JFFS2_XPREFIX_USER,
|
||||||
name, buffer, size, flags);
|
name, buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,11 +943,10 @@ static int jfs_xattr_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int jfs_xattr_set(const struct xattr_handler *handler,
|
static int jfs_xattr_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
name = xattr_full_name(handler, name);
|
name = xattr_full_name(handler, name);
|
||||||
return __jfs_xattr_set(inode, name, value, size, flags);
|
return __jfs_xattr_set(inode, name, value, size, flags);
|
||||||
}
|
}
|
||||||
@ -962,11 +961,10 @@ static int jfs_xattr_get_os2(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int jfs_xattr_set_os2(const struct xattr_handler *handler,
|
static int jfs_xattr_set_os2(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
if (is_known_namespace(name))
|
if (is_known_namespace(name))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return __jfs_xattr_set(inode, name, value, size, flags);
|
return __jfs_xattr_set(inode, name, value, size, flags);
|
||||||
|
@ -160,10 +160,11 @@ static int kernfs_node_setsecdata(struct kernfs_node *kn, void **secdata,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kernfs_iop_setxattr(struct dentry *dentry, const char *name,
|
int kernfs_iop_setxattr(struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct kernfs_node *kn = dentry->d_fsdata;
|
struct kernfs_node *kn = inode->i_private;
|
||||||
struct kernfs_iattrs *attrs;
|
struct kernfs_iattrs *attrs;
|
||||||
void *secdata;
|
void *secdata;
|
||||||
int error;
|
int error;
|
||||||
@ -175,11 +176,11 @@ int kernfs_iop_setxattr(struct dentry *dentry, const char *name,
|
|||||||
|
|
||||||
if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
|
if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) {
|
||||||
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
|
const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
|
||||||
error = security_inode_setsecurity(d_inode(dentry), suffix,
|
error = security_inode_setsecurity(inode, suffix,
|
||||||
value, size, flags);
|
value, size, flags);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
error = security_inode_getsecctx(d_inode(dentry),
|
error = security_inode_getsecctx(inode,
|
||||||
&secdata, &secdata_len);
|
&secdata, &secdata_len);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
@ -81,7 +81,8 @@ int kernfs_iop_permission(struct inode *inode, int mask);
|
|||||||
int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr);
|
int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr);
|
||||||
int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
int kernfs_iop_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
struct kstat *stat);
|
struct kstat *stat);
|
||||||
int kernfs_iop_setxattr(struct dentry *dentry, const char *name, const void *value,
|
int kernfs_iop_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
|
const char *name, const void *value,
|
||||||
size_t size, int flags);
|
size_t size, int flags);
|
||||||
int kernfs_iop_removexattr(struct dentry *dentry, const char *name);
|
int kernfs_iop_removexattr(struct dentry *dentry, const char *name);
|
||||||
ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode,
|
ssize_t kernfs_iop_getxattr(struct dentry *dentry, struct inode *inode,
|
||||||
|
@ -1118,8 +1118,9 @@ static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
|
|||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int empty_dir_setxattr(struct dentry *dentry, const char *name,
|
static int empty_dir_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -5015,12 +5015,11 @@ static int nfs4_do_set_security_label(struct inode *inode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nfs4_set_security_label(struct dentry *dentry, const void *buf, size_t buflen)
|
nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
struct nfs4_label ilabel, *olabel = NULL;
|
struct nfs4_label ilabel, *olabel = NULL;
|
||||||
struct nfs_fattr fattr;
|
struct nfs_fattr fattr;
|
||||||
struct rpc_cred *cred;
|
struct rpc_cred *cred;
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
|
if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
|
||||||
@ -6281,11 +6280,11 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp)
|
|||||||
#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
|
#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
|
||||||
|
|
||||||
static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
|
static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *key,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buf, size_t buflen,
|
const char *key, const void *buf,
|
||||||
int flags)
|
size_t buflen, int flags)
|
||||||
{
|
{
|
||||||
return nfs4_proc_set_acl(d_inode(dentry), buf, buflen);
|
return nfs4_proc_set_acl(inode, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
|
static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
|
||||||
@ -6303,12 +6302,12 @@ static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
|
|||||||
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
||||||
|
|
||||||
static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
|
static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *key,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *buf, size_t buflen,
|
const char *key, const void *buf,
|
||||||
int flags)
|
size_t buflen, int flags)
|
||||||
{
|
{
|
||||||
if (security_ismaclabel(key))
|
if (security_ismaclabel(key))
|
||||||
return nfs4_set_security_label(dentry, buf, buflen);
|
return nfs4_set_security_label(inode, buf, buflen);
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -7254,10 +7254,11 @@ static int ocfs2_xattr_security_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
|
static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_SECURITY,
|
return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
|
||||||
name, value, size, flags);
|
name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7325,10 +7326,11 @@ static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler,
|
static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_TRUSTED,
|
return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_TRUSTED,
|
||||||
name, value, size, flags);
|
name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7354,15 +7356,16 @@ static int ocfs2_xattr_user_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ocfs2_xattr_user_set(const struct xattr_handler *handler,
|
static int ocfs2_xattr_user_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||||
|
|
||||||
if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
|
if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
return ocfs2_xattr_set(d_inode(dentry), OCFS2_XATTR_INDEX_USER,
|
return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_USER,
|
||||||
name, value, size, flags);
|
name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,13 +448,14 @@ out_unlock:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int orangefs_xattr_set_default(const struct xattr_handler *handler,
|
static int orangefs_xattr_set_default(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry,
|
struct dentry *unused,
|
||||||
|
struct inode *inode,
|
||||||
const char *name,
|
const char *name,
|
||||||
const void *buffer,
|
const void *buffer,
|
||||||
size_t size,
|
size_t size,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
return orangefs_inode_setxattr(dentry->d_inode,
|
return orangefs_inode_setxattr(inode,
|
||||||
ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
|
ORANGEFS_XATTR_NAME_DEFAULT_PREFIX,
|
||||||
name,
|
name,
|
||||||
buffer,
|
buffer,
|
||||||
@ -478,13 +479,14 @@ static int orangefs_xattr_get_default(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int orangefs_xattr_set_trusted(const struct xattr_handler *handler,
|
static int orangefs_xattr_set_trusted(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry,
|
struct dentry *unused,
|
||||||
|
struct inode *inode,
|
||||||
const char *name,
|
const char *name,
|
||||||
const void *buffer,
|
const void *buffer,
|
||||||
size_t size,
|
size_t size,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
return orangefs_inode_setxattr(dentry->d_inode,
|
return orangefs_inode_setxattr(inode,
|
||||||
ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
|
ORANGEFS_XATTR_NAME_TRUSTED_PREFIX,
|
||||||
name,
|
name,
|
||||||
buffer,
|
buffer,
|
||||||
|
@ -210,8 +210,9 @@ static bool ovl_is_private_xattr(const char *name)
|
|||||||
return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
|
return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ovl_setxattr(struct dentry *dentry, const char *name,
|
int ovl_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct dentry *upperdentry;
|
struct dentry *upperdentry;
|
||||||
|
@ -172,8 +172,9 @@ int ovl_check_d_type_supported(struct path *realpath);
|
|||||||
/* inode.c */
|
/* inode.c */
|
||||||
int ovl_setattr(struct dentry *dentry, struct iattr *attr);
|
int ovl_setattr(struct dentry *dentry, struct iattr *attr);
|
||||||
int ovl_permission(struct inode *inode, int mask);
|
int ovl_permission(struct inode *inode, int mask);
|
||||||
int ovl_setxattr(struct dentry *dentry, const char *name,
|
int ovl_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags);
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags);
|
||||||
ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
|
ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
|
||||||
const char *name, void *value, size_t size);
|
const char *name, void *value, size_t size);
|
||||||
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
|
ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
|
||||||
|
@ -210,9 +210,7 @@ static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
|
|||||||
|
|
||||||
old_cred = ovl_override_creds(rdd->dentry->d_sb);
|
old_cred = ovl_override_creds(rdd->dentry->d_sb);
|
||||||
|
|
||||||
inode_lock(dir->d_inode);
|
err = down_write_killable(&dir->d_inode->i_rwsem);
|
||||||
err = 0;
|
|
||||||
// XXX: err = mutex_lock_killable(&dir->d_inode->i_mutex);
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
while (rdd->first_maybe_whiteout) {
|
while (rdd->first_maybe_whiteout) {
|
||||||
p = rdd->first_maybe_whiteout;
|
p = rdd->first_maybe_whiteout;
|
||||||
|
@ -822,10 +822,10 @@ posix_acl_xattr_get(const struct xattr_handler *handler,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
posix_acl_xattr_set(const struct xattr_handler *handler,
|
posix_acl_xattr_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_backing_inode(dentry);
|
|
||||||
struct posix_acl *acl = NULL;
|
struct posix_acl *acl = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
12
fs/readdir.c
12
fs/readdir.c
@ -35,13 +35,13 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
|
|||||||
if (res)
|
if (res)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (shared)
|
if (shared) {
|
||||||
inode_lock_shared(inode);
|
inode_lock_shared(inode);
|
||||||
else
|
} else {
|
||||||
inode_lock(inode);
|
res = down_write_killable(&inode->i_rwsem);
|
||||||
// res = mutex_lock_killable(&inode->i_mutex);
|
if (res)
|
||||||
// if (res)
|
goto out;
|
||||||
// goto out;
|
}
|
||||||
|
|
||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
if (!IS_DEADDIR(inode)) {
|
if (!IS_DEADDIR(inode)) {
|
||||||
|
@ -20,13 +20,14 @@ security_get(const struct xattr_handler *handler, struct dentry *unused,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
security_set(const struct xattr_handler *handler, struct dentry *dentry,
|
security_set(const struct xattr_handler *handler, struct dentry *unused,
|
||||||
const char *name, const void *buffer, size_t size, int flags)
|
struct inode *inode, const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
if (IS_PRIVATE(d_inode(dentry)))
|
if (IS_PRIVATE(inode))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
return reiserfs_xattr_set(d_inode(dentry),
|
return reiserfs_xattr_set(inode,
|
||||||
xattr_full_name(handler, name),
|
xattr_full_name(handler, name),
|
||||||
buffer, size, flags);
|
buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,14 @@ trusted_get(const struct xattr_handler *handler, struct dentry *unused,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
|
trusted_set(const struct xattr_handler *handler, struct dentry *unused,
|
||||||
const char *name, const void *buffer, size_t size, int flags)
|
struct inode *inode, const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
|
if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
return reiserfs_xattr_set(d_inode(dentry),
|
return reiserfs_xattr_set(inode,
|
||||||
xattr_full_name(handler, name),
|
xattr_full_name(handler, name),
|
||||||
buffer, size, flags);
|
buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,13 @@ user_get(const struct xattr_handler *handler, struct dentry *unused,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
user_set(const struct xattr_handler *handler, struct dentry *dentry,
|
user_set(const struct xattr_handler *handler, struct dentry *unused,
|
||||||
const char *name, const void *buffer, size_t size, int flags)
|
struct inode *inode, const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
if (!reiserfs_xattrs_user(dentry->d_sb))
|
if (!reiserfs_xattrs_user(inode->i_sb))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return reiserfs_xattr_set(d_inode(dentry),
|
return reiserfs_xattr_set(inode,
|
||||||
xattr_full_name(handler, name),
|
xattr_full_name(handler, name),
|
||||||
buffer, size, flags);
|
buffer, size, flags);
|
||||||
}
|
}
|
||||||
|
@ -579,11 +579,10 @@ static int ubifs_xattr_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ubifs_xattr_set(const struct xattr_handler *handler,
|
static int ubifs_xattr_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *dentry, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode = d_inode(dentry);
|
|
||||||
|
|
||||||
dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
|
dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd",
|
||||||
name, inode->i_ino, dentry, size);
|
name, inode->i_ino, dentry, size);
|
||||||
|
|
||||||
|
10
fs/xattr.c
10
fs/xattr.c
@ -100,7 +100,7 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
|
|||||||
if (issec)
|
if (issec)
|
||||||
inode->i_flags &= ~S_NOSEC;
|
inode->i_flags &= ~S_NOSEC;
|
||||||
if (inode->i_op->setxattr) {
|
if (inode->i_op->setxattr) {
|
||||||
error = inode->i_op->setxattr(dentry, name, value, size, flags);
|
error = inode->i_op->setxattr(dentry, inode, name, value, size, flags);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
fsnotify_xattr(dentry);
|
fsnotify_xattr(dentry);
|
||||||
security_inode_post_setxattr(dentry, name, value,
|
security_inode_post_setxattr(dentry, name, value,
|
||||||
@ -745,7 +745,8 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
|
|||||||
* Find the handler for the prefix and dispatch its set() operation.
|
* Find the handler for the prefix and dispatch its set() operation.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
|
generic_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
|
||||||
|
const void *value, size_t size, int flags)
|
||||||
{
|
{
|
||||||
const struct xattr_handler *handler;
|
const struct xattr_handler *handler;
|
||||||
|
|
||||||
@ -754,7 +755,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz
|
|||||||
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
|
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
|
||||||
if (IS_ERR(handler))
|
if (IS_ERR(handler))
|
||||||
return PTR_ERR(handler);
|
return PTR_ERR(handler);
|
||||||
return handler->set(handler, dentry, name, value, size, flags);
|
return handler->set(handler, dentry, inode, name, value, size, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -769,7 +770,8 @@ generic_removexattr(struct dentry *dentry, const char *name)
|
|||||||
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
|
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
|
||||||
if (IS_ERR(handler))
|
if (IS_ERR(handler))
|
||||||
return PTR_ERR(handler);
|
return PTR_ERR(handler);
|
||||||
return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
|
return handler->set(handler, dentry, d_inode(dentry), name, NULL,
|
||||||
|
0, XATTR_REPLACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(generic_getxattr);
|
EXPORT_SYMBOL(generic_getxattr);
|
||||||
|
@ -74,11 +74,12 @@ xfs_forget_acl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry,
|
xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
|
||||||
const char *name, const void *value, size_t size, int flags)
|
struct inode *inode, const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
int xflags = handler->flags;
|
int xflags = handler->flags;
|
||||||
struct xfs_inode *ip = XFS_I(d_inode(dentry));
|
struct xfs_inode *ip = XFS_I(inode);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Convert Linux syscall to XFS internal ATTR flags */
|
/* Convert Linux syscall to XFS internal ATTR flags */
|
||||||
@ -92,7 +93,7 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry,
|
|||||||
error = xfs_attr_set(ip, (unsigned char *)name,
|
error = xfs_attr_set(ip, (unsigned char *)name,
|
||||||
(void *)value, size, xflags);
|
(void *)value, size, xflags);
|
||||||
if (!error)
|
if (!error)
|
||||||
xfs_forget_acl(d_inode(dentry), name, xflags);
|
xfs_forget_acl(inode, name, xflags);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -1729,7 +1729,8 @@ struct inode_operations {
|
|||||||
struct inode *, struct dentry *, unsigned int);
|
struct inode *, struct dentry *, unsigned int);
|
||||||
int (*setattr) (struct dentry *, struct iattr *);
|
int (*setattr) (struct dentry *, struct iattr *);
|
||||||
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
|
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
|
||||||
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
|
int (*setxattr) (struct dentry *, struct inode *,
|
||||||
|
const char *, const void *, size_t, int);
|
||||||
ssize_t (*getxattr) (struct dentry *, struct inode *,
|
ssize_t (*getxattr) (struct dentry *, struct inode *,
|
||||||
const char *, void *, size_t);
|
const char *, void *, size_t);
|
||||||
ssize_t (*listxattr) (struct dentry *, char *, size_t);
|
ssize_t (*listxattr) (struct dentry *, char *, size_t);
|
||||||
|
@ -156,6 +156,7 @@ extern void downgrade_write(struct rw_semaphore *sem);
|
|||||||
*/
|
*/
|
||||||
extern void down_read_nested(struct rw_semaphore *sem, int subclass);
|
extern void down_read_nested(struct rw_semaphore *sem, int subclass);
|
||||||
extern void down_write_nested(struct rw_semaphore *sem, int subclass);
|
extern void down_write_nested(struct rw_semaphore *sem, int subclass);
|
||||||
|
extern int down_write_killable_nested(struct rw_semaphore *sem, int subclass);
|
||||||
extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock);
|
extern void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest_lock);
|
||||||
|
|
||||||
# define down_write_nest_lock(sem, nest_lock) \
|
# define down_write_nest_lock(sem, nest_lock) \
|
||||||
@ -176,6 +177,7 @@ extern void up_read_non_owner(struct rw_semaphore *sem);
|
|||||||
# define down_read_nested(sem, subclass) down_read(sem)
|
# define down_read_nested(sem, subclass) down_read(sem)
|
||||||
# define down_write_nest_lock(sem, nest_lock) down_write(sem)
|
# define down_write_nest_lock(sem, nest_lock) down_write(sem)
|
||||||
# define down_write_nested(sem, subclass) down_write(sem)
|
# define down_write_nested(sem, subclass) down_write(sem)
|
||||||
|
# define down_write_killable_nested(sem, subclass) down_write_killable(sem)
|
||||||
# define down_read_non_owner(sem) down_read(sem)
|
# define down_read_non_owner(sem) down_read(sem)
|
||||||
# define up_read_non_owner(sem) up_read(sem)
|
# define up_read_non_owner(sem) up_read(sem)
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,8 +33,8 @@ struct xattr_handler {
|
|||||||
struct inode *inode, const char *name, void *buffer,
|
struct inode *inode, const char *name, void *buffer,
|
||||||
size_t size);
|
size_t size);
|
||||||
int (*set)(const struct xattr_handler *, struct dentry *dentry,
|
int (*set)(const struct xattr_handler *, struct dentry *dentry,
|
||||||
const char *name, const void *buffer, size_t size,
|
struct inode *inode, const char *name, const void *buffer,
|
||||||
int flags);
|
size_t size, int flags);
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *xattr_full_name(const struct xattr_handler *, const char *);
|
const char *xattr_full_name(const struct xattr_handler *, const char *);
|
||||||
@ -54,7 +54,8 @@ int vfs_removexattr(struct dentry *, const char *);
|
|||||||
|
|
||||||
ssize_t generic_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size);
|
ssize_t generic_getxattr(struct dentry *dentry, struct inode *inode, const char *name, void *buffer, size_t size);
|
||||||
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
|
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
|
||||||
int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
|
int generic_setxattr(struct dentry *dentry, struct inode *inode,
|
||||||
|
const char *name, const void *value, size_t size, int flags);
|
||||||
int generic_removexattr(struct dentry *dentry, const char *name);
|
int generic_removexattr(struct dentry *dentry, const char *name);
|
||||||
ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
|
ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
|
||||||
char **xattr_value, size_t size, gfp_t flags);
|
char **xattr_value, size_t size, gfp_t flags);
|
||||||
|
@ -173,6 +173,22 @@ void down_write_nested(struct rw_semaphore *sem, int subclass)
|
|||||||
|
|
||||||
EXPORT_SYMBOL(down_write_nested);
|
EXPORT_SYMBOL(down_write_nested);
|
||||||
|
|
||||||
|
int __sched down_write_killable_nested(struct rw_semaphore *sem, int subclass)
|
||||||
|
{
|
||||||
|
might_sleep();
|
||||||
|
rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
|
||||||
|
|
||||||
|
if (LOCK_CONTENDED_RETURN(sem, __down_write_trylock, __down_write_killable)) {
|
||||||
|
rwsem_release(&sem->dep_map, 1, _RET_IP_);
|
||||||
|
return -EINTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
rwsem_set_owner(sem);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(down_write_killable_nested);
|
||||||
|
|
||||||
void up_read_non_owner(struct rw_semaphore *sem)
|
void up_read_non_owner(struct rw_semaphore *sem)
|
||||||
{
|
{
|
||||||
__up_read(sem);
|
__up_read(sem);
|
||||||
|
@ -2645,10 +2645,11 @@ static int shmem_xattr_handler_get(const struct xattr_handler *handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int shmem_xattr_handler_set(const struct xattr_handler *handler,
|
static int shmem_xattr_handler_set(const struct xattr_handler *handler,
|
||||||
struct dentry *dentry, const char *name,
|
struct dentry *unused, struct inode *inode,
|
||||||
const void *value, size_t size, int flags)
|
const char *name, const void *value,
|
||||||
|
size_t size, int flags)
|
||||||
{
|
{
|
||||||
struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
|
struct shmem_inode_info *info = SHMEM_I(inode);
|
||||||
|
|
||||||
name = xattr_full_name(handler, name);
|
name = xattr_full_name(handler, name);
|
||||||
return simple_xattr_set(&info->xattrs, name, value, size, flags);
|
return simple_xattr_set(&info->xattrs, name, value, size, flags);
|
||||||
|
@ -3514,7 +3514,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
|
|||||||
*/
|
*/
|
||||||
if (isp->smk_flags & SMK_INODE_CHANGED) {
|
if (isp->smk_flags & SMK_INODE_CHANGED) {
|
||||||
isp->smk_flags &= ~SMK_INODE_CHANGED;
|
isp->smk_flags &= ~SMK_INODE_CHANGED;
|
||||||
rc = inode->i_op->setxattr(dp,
|
rc = inode->i_op->setxattr(dp, inode,
|
||||||
XATTR_NAME_SMACKTRANSMUTE,
|
XATTR_NAME_SMACKTRANSMUTE,
|
||||||
TRANS_TRUE, TRANS_TRUE_SIZE,
|
TRANS_TRUE, TRANS_TRUE_SIZE,
|
||||||
0);
|
0);
|
||||||
|
Loading…
Reference in New Issue
Block a user