Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs xattr updates from Al Viro: "xattr stuff from Andreas This completes the switch to xattr_handler ->get()/->set() from ->getxattr/->setxattr/->removexattr" * 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: Remove {get,set,remove}xattr inode operations xattr: Stop calling {get,set,remove}xattr inode operations vfs: Check for the IOP_XATTR flag in listxattr xattr: Add __vfs_{get,set,remove}xattr helpers libfs: Use IOP_XATTR flag for empty directory handling vfs: Use IOP_XATTR flag for bad-inode handling vfs: Add IOP_XATTR inode operations flag vfs: Move xattr_resolve_name to the front of fs/xattr.c ecryptfs: Switch to generic xattr handlers sockfs: Get rid of getxattr iop sockfs: getxattr: Fail with -EOPNOTSUPP for invalid attribute names kernfs: Switch to generic xattr handlers hfs: Switch to generic xattr handlers jffs2: Remove jffs2_{get,set,remove}xattr macros xattr: Remove unnecessary NULL attribute name check
This commit is contained in:
@@ -715,4 +715,6 @@ int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
|
||||
int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
|
||||
loff_t offset);
|
||||
|
||||
extern const struct xattr_handler *ecryptfs_xattr_handlers[];
|
||||
|
||||
#endif /* #ifndef ECRYPTFS_KERNEL_H */
|
||||
|
@@ -1005,15 +1005,14 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
|
||||
const char *name, const void *value,
|
||||
size_t size, int flags)
|
||||
{
|
||||
int rc = 0;
|
||||
int rc;
|
||||
struct dentry *lower_dentry;
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
if (!d_inode(lower_dentry)->i_op->setxattr) {
|
||||
if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) {
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = vfs_setxattr(lower_dentry, name, value, size, flags);
|
||||
if (!rc && inode)
|
||||
fsstack_copy_attr_all(inode, d_inode(lower_dentry));
|
||||
@@ -1025,15 +1024,14 @@ ssize_t
|
||||
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
|
||||
const char *name, void *value, size_t size)
|
||||
{
|
||||
int rc = 0;
|
||||
int rc;
|
||||
|
||||
if (!lower_inode->i_op->getxattr) {
|
||||
if (!(lower_inode->i_opflags & IOP_XATTR)) {
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
inode_lock(lower_inode);
|
||||
rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
|
||||
name, value, size);
|
||||
rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size);
|
||||
inode_unlock(lower_inode);
|
||||
out:
|
||||
return rc;
|
||||
@@ -1066,19 +1064,22 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
|
||||
static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
|
||||
const char *name)
|
||||
{
|
||||
int rc = 0;
|
||||
int rc;
|
||||
struct dentry *lower_dentry;
|
||||
struct inode *lower_inode;
|
||||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
if (!d_inode(lower_dentry)->i_op->removexattr) {
|
||||
lower_inode = ecryptfs_inode_to_lower(inode);
|
||||
if (!(lower_inode->i_opflags & IOP_XATTR)) {
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
inode_lock(d_inode(lower_dentry));
|
||||
rc = d_inode(lower_dentry)->i_op->removexattr(lower_dentry, name);
|
||||
inode_unlock(d_inode(lower_dentry));
|
||||
inode_lock(lower_inode);
|
||||
rc = __vfs_removexattr(lower_dentry, name);
|
||||
inode_unlock(lower_inode);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
@@ -1089,10 +1090,7 @@ const struct inode_operations ecryptfs_symlink_iops = {
|
||||
.permission = ecryptfs_permission,
|
||||
.setattr = ecryptfs_setattr,
|
||||
.getattr = ecryptfs_getattr_link,
|
||||
.setxattr = ecryptfs_setxattr,
|
||||
.getxattr = ecryptfs_getxattr,
|
||||
.listxattr = ecryptfs_listxattr,
|
||||
.removexattr = ecryptfs_removexattr
|
||||
};
|
||||
|
||||
const struct inode_operations ecryptfs_dir_iops = {
|
||||
@@ -1107,18 +1105,43 @@ const struct inode_operations ecryptfs_dir_iops = {
|
||||
.rename = ecryptfs_rename,
|
||||
.permission = ecryptfs_permission,
|
||||
.setattr = ecryptfs_setattr,
|
||||
.setxattr = ecryptfs_setxattr,
|
||||
.getxattr = ecryptfs_getxattr,
|
||||
.listxattr = ecryptfs_listxattr,
|
||||
.removexattr = ecryptfs_removexattr
|
||||
};
|
||||
|
||||
const struct inode_operations ecryptfs_main_iops = {
|
||||
.permission = ecryptfs_permission,
|
||||
.setattr = ecryptfs_setattr,
|
||||
.getattr = ecryptfs_getattr,
|
||||
.setxattr = ecryptfs_setxattr,
|
||||
.getxattr = ecryptfs_getxattr,
|
||||
.listxattr = ecryptfs_listxattr,
|
||||
.removexattr = ecryptfs_removexattr
|
||||
};
|
||||
|
||||
static int ecryptfs_xattr_get(const struct xattr_handler *handler,
|
||||
struct dentry *dentry, struct inode *inode,
|
||||
const char *name, void *buffer, size_t size)
|
||||
{
|
||||
return ecryptfs_getxattr(dentry, inode, name, buffer, size);
|
||||
}
|
||||
|
||||
static int ecryptfs_xattr_set(const struct xattr_handler *handler,
|
||||
struct dentry *dentry, struct inode *inode,
|
||||
const char *name, const void *value, size_t size,
|
||||
int flags)
|
||||
{
|
||||
if (value)
|
||||
return ecryptfs_setxattr(dentry, inode, name, value, size, flags);
|
||||
else {
|
||||
BUG_ON(flags != XATTR_REPLACE);
|
||||
return ecryptfs_removexattr(dentry, inode, name);
|
||||
}
|
||||
}
|
||||
|
||||
const struct xattr_handler ecryptfs_xattr_handler = {
|
||||
.prefix = "", /* match anything */
|
||||
.get = ecryptfs_xattr_get,
|
||||
.set = ecryptfs_xattr_set,
|
||||
};
|
||||
|
||||
const struct xattr_handler *ecryptfs_xattr_handlers[] = {
|
||||
&ecryptfs_xattr_handler,
|
||||
NULL
|
||||
};
|
||||
|
@@ -529,6 +529,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
|
||||
/* ->kill_sb() will take care of sbi after that point */
|
||||
sbi = NULL;
|
||||
s->s_op = &ecryptfs_sops;
|
||||
s->s_xattr = ecryptfs_xattr_handlers;
|
||||
s->s_d_op = &ecryptfs_dops;
|
||||
|
||||
err = "Reading sb failed";
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <linux/file.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/xattr.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include "ecryptfs_kernel.h"
|
||||
|
||||
@@ -422,7 +423,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
|
||||
struct inode *lower_inode = d_inode(lower_dentry);
|
||||
int rc;
|
||||
|
||||
if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) {
|
||||
if (!(lower_inode->i_opflags & IOP_XATTR)) {
|
||||
printk(KERN_WARNING
|
||||
"No support for setting xattr in lower filesystem\n");
|
||||
rc = -ENOSYS;
|
||||
@@ -436,15 +437,13 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
|
||||
goto out;
|
||||
}
|
||||
inode_lock(lower_inode);
|
||||
size = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
|
||||
ECRYPTFS_XATTR_NAME,
|
||||
xattr_virt, PAGE_SIZE);
|
||||
size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
|
||||
xattr_virt, PAGE_SIZE);
|
||||
if (size < 0)
|
||||
size = 8;
|
||||
put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
|
||||
rc = lower_inode->i_op->setxattr(lower_dentry, lower_inode,
|
||||
ECRYPTFS_XATTR_NAME,
|
||||
xattr_virt, size, 0);
|
||||
rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
|
||||
xattr_virt, size, 0);
|
||||
inode_unlock(lower_inode);
|
||||
if (rc)
|
||||
printk(KERN_ERR "Error whilst attempting to write inode size "
|
||||
|
Reference in New Issue
Block a user