You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
3.9 KiB

/* vim:set ts=4 sw=4 tw=0 noet ft=c:
*
* fs/sdcardfs/xattr.c
*
* Copyright (c) 2013 Samsung Electronics Co. Ltd
* Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
* Sunghwan Yun, Sungjong Seo
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
* distribution for more details.
*/
#include <linux/xattr.h>
#include "sdcardfs.h"
int sdcardfs_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
int rc;
struct path lower_path;
struct dentry *lower_dentry = NULL;
const struct cred *saved_cred = NULL;
if (dentry == NULL || dentry->d_inode == NULL)
return -ENOMEM;
/* save current_cred and override it */
saved_cred = override_fsids(SDCARDFS_SB(dentry->d_inode->i_sb),
SDCARDFS_I(dentry->d_inode)->data);
if (!saved_cred)
return -ENOMEM;
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
dget(lower_dentry);
rc = vfs_setxattr(lower_dentry, name, value, size, flags);
dput(lower_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
revert_fsids(saved_cred);
return rc;
}
ssize_t sdcardfs_getxattr(struct dentry *dentry,
const char *name, void *value, size_t size)
{
ssize_t rc;
struct path lower_path;
struct dentry *lower_dentry = NULL;
const struct cred *saved_cred = NULL;
if (dentry == NULL || dentry->d_inode == NULL)
return -ENOMEM;
/* save current_cred and override it */
saved_cred = override_fsids(SDCARDFS_SB(dentry->d_inode->i_sb),
SDCARDFS_I(dentry->d_inode)->data);
if (!saved_cred)
return -ENOMEM;
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
dget(lower_dentry);
rc = vfs_getxattr(lower_dentry, name, value, size);
dput(lower_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
revert_fsids(saved_cred);
return rc;
}
ssize_t sdcardfs_listxattr(struct dentry *dentry, char *list, size_t size)
{
ssize_t rc;
struct path lower_path;
struct dentry *lower_dentry = NULL;
const struct cred *saved_cred = NULL;
/* save current_cred and override it */
saved_cred = override_fsids(SDCARDFS_SB(dentry->d_inode->i_sb),
SDCARDFS_I(dentry->d_inode)->data);
if (!saved_cred)
return -ENOMEM;
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
dget(lower_dentry);
rc = vfs_listxattr(lower_dentry, list, size);
dput(lower_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
revert_fsids(saved_cred);
return rc;
}
int sdcardfs_removexattr(struct dentry *dentry, const char *name)
{
ssize_t rc;
struct path lower_path;
struct dentry *lower_dentry = NULL;
const struct cred *saved_cred = NULL;
/* save current_cred and override it */
saved_cred = override_fsids(SDCARDFS_SB(dentry->d_inode->i_sb),
SDCARDFS_I(dentry->d_inode)->data);
if (!saved_cred)
return -ENOMEM;
sdcardfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
dget(lower_dentry);
rc = vfs_removexattr(lower_dentry, name);
dput(lower_dentry);
sdcardfs_put_lower_path(dentry, &lower_path);
revert_fsids(saved_cred);
return rc;
}
static int sdcardfs_xattr_get(const struct xattr_handler *handler,
struct dentry *dentry, struct inode *inode,
const char *name, void *value, size_t size,
int flags)
{
return (int)sdcardfs_getxattr(dentry, name, value, size);
}
static int sdcardfs_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 sdcardfs_removexattr(dentry, name);
return sdcardfs_setxattr(dentry, name, value, size, flags);
}
static const struct xattr_handler sdcardfs_xattr_handler = {
.prefix = "",
.get = sdcardfs_xattr_get,
.set = sdcardfs_xattr_set,
};
const struct xattr_handler *sdcardfs_xattr_handlers[] = {
&sdcardfs_xattr_handler,
NULL
};