|
@@ -1066,19 +1066,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;
|
|
|
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_op->removexattr) {
|
|
|
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 = lower_inode->i_op->removexattr(lower_dentry, name);
|
|
|
+ inode_unlock(lower_inode);
|
|
|
out:
|
|
|
return rc;
|
|
|
}
|
|
@@ -1089,10 +1092,10 @@ const struct inode_operations ecryptfs_symlink_iops = {
|
|
|
.permission = ecryptfs_permission,
|
|
|
.setattr = ecryptfs_setattr,
|
|
|
.getattr = ecryptfs_getattr_link,
|
|
|
- .setxattr = ecryptfs_setxattr,
|
|
|
- .getxattr = ecryptfs_getxattr,
|
|
|
+ .setxattr = generic_setxattr,
|
|
|
+ .getxattr = generic_getxattr,
|
|
|
.listxattr = ecryptfs_listxattr,
|
|
|
- .removexattr = ecryptfs_removexattr
|
|
|
+ .removexattr = generic_removexattr
|
|
|
};
|
|
|
|
|
|
const struct inode_operations ecryptfs_dir_iops = {
|
|
@@ -1107,18 +1110,49 @@ const struct inode_operations ecryptfs_dir_iops = {
|
|
|
.rename = ecryptfs_rename,
|
|
|
.permission = ecryptfs_permission,
|
|
|
.setattr = ecryptfs_setattr,
|
|
|
- .setxattr = ecryptfs_setxattr,
|
|
|
- .getxattr = ecryptfs_getxattr,
|
|
|
+ .setxattr = generic_setxattr,
|
|
|
+ .getxattr = generic_getxattr,
|
|
|
.listxattr = ecryptfs_listxattr,
|
|
|
- .removexattr = ecryptfs_removexattr
|
|
|
+ .removexattr = generic_removexattr
|
|
|
};
|
|
|
|
|
|
const struct inode_operations ecryptfs_main_iops = {
|
|
|
.permission = ecryptfs_permission,
|
|
|
.setattr = ecryptfs_setattr,
|
|
|
.getattr = ecryptfs_getattr,
|
|
|
- .setxattr = ecryptfs_setxattr,
|
|
|
- .getxattr = ecryptfs_getxattr,
|
|
|
+ .setxattr = generic_setxattr,
|
|
|
+ .getxattr = generic_getxattr,
|
|
|
.listxattr = ecryptfs_listxattr,
|
|
|
- .removexattr = ecryptfs_removexattr
|
|
|
+ .removexattr = generic_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
|
|
|
};
|