orangefs: convert to fileattr
Use the fileattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Cc: Mike Marshall <hubcap@omnibond.com>
This commit is contained in:
parent
88b631cbfb
commit
1f26b0627b
@ -375,84 +375,6 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int orangefs_getflags(struct inode *inode, unsigned long *uval)
|
|
||||||
{
|
|
||||||
__u64 val = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = orangefs_inode_getxattr(inode,
|
|
||||||
"user.pvfs2.meta_hint",
|
|
||||||
&val, sizeof(val));
|
|
||||||
if (ret < 0 && ret != -ENODATA)
|
|
||||||
return ret;
|
|
||||||
else if (ret == -ENODATA)
|
|
||||||
val = 0;
|
|
||||||
*uval = val;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform a miscellaneous operation on a file.
|
|
||||||
*/
|
|
||||||
static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
|
||||||
struct inode *inode = file_inode(file);
|
|
||||||
int ret = -ENOTTY;
|
|
||||||
__u64 val = 0;
|
|
||||||
unsigned long uval;
|
|
||||||
|
|
||||||
gossip_debug(GOSSIP_FILE_DEBUG,
|
|
||||||
"orangefs_ioctl: called with cmd %d\n",
|
|
||||||
cmd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* we understand some general ioctls on files, such as the immutable
|
|
||||||
* and append flags
|
|
||||||
*/
|
|
||||||
if (cmd == FS_IOC_GETFLAGS) {
|
|
||||||
ret = orangefs_getflags(inode, &uval);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
gossip_debug(GOSSIP_FILE_DEBUG,
|
|
||||||
"orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n",
|
|
||||||
(unsigned long long)uval);
|
|
||||||
return put_user(uval, (int __user *)arg);
|
|
||||||
} else if (cmd == FS_IOC_SETFLAGS) {
|
|
||||||
unsigned long old_uval;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
if (get_user(uval, (int __user *)arg))
|
|
||||||
return -EFAULT;
|
|
||||||
/*
|
|
||||||
* ORANGEFS_MIRROR_FL is set internally when the mirroring mode
|
|
||||||
* is turned on for a file. The user is not allowed to turn
|
|
||||||
* on this bit, but the bit is present if the user first gets
|
|
||||||
* the flags and then updates the flags with some new
|
|
||||||
* settings. So, we ignore it in the following edit. bligon.
|
|
||||||
*/
|
|
||||||
if ((uval & ~ORANGEFS_MIRROR_FL) &
|
|
||||||
(~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) {
|
|
||||||
gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
ret = orangefs_getflags(inode, &old_uval);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
ret = vfs_ioc_setflags_prepare(inode, old_uval, uval);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
val = uval;
|
|
||||||
gossip_debug(GOSSIP_FILE_DEBUG,
|
|
||||||
"orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n",
|
|
||||||
(unsigned long long)val);
|
|
||||||
ret = orangefs_inode_setxattr(inode,
|
|
||||||
"user.pvfs2.meta_hint",
|
|
||||||
&val, sizeof(val), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static vm_fault_t orangefs_fault(struct vm_fault *vmf)
|
static vm_fault_t orangefs_fault(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
struct file *file = vmf->vma->vm_file;
|
struct file *file = vmf->vma->vm_file;
|
||||||
@ -657,7 +579,6 @@ const struct file_operations orangefs_file_operations = {
|
|||||||
.read_iter = orangefs_file_read_iter,
|
.read_iter = orangefs_file_read_iter,
|
||||||
.write_iter = orangefs_file_write_iter,
|
.write_iter = orangefs_file_write_iter,
|
||||||
.lock = orangefs_lock,
|
.lock = orangefs_lock,
|
||||||
.unlocked_ioctl = orangefs_ioctl,
|
|
||||||
.mmap = orangefs_file_mmap,
|
.mmap = orangefs_file_mmap,
|
||||||
.open = generic_file_open,
|
.open = generic_file_open,
|
||||||
.splice_read = generic_file_splice_read,
|
.splice_read = generic_file_splice_read,
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/bvec.h>
|
#include <linux/bvec.h>
|
||||||
|
#include <linux/fileattr.h>
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "orangefs-kernel.h"
|
#include "orangefs-kernel.h"
|
||||||
#include "orangefs-bufmap.h"
|
#include "orangefs-bufmap.h"
|
||||||
@ -954,6 +955,53 @@ int orangefs_update_time(struct inode *inode, struct timespec64 *time, int flags
|
|||||||
return __orangefs_setattr(inode, &iattr);
|
return __orangefs_setattr(inode, &iattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int orangefs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
|
||||||
|
{
|
||||||
|
u64 val = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
gossip_debug(GOSSIP_FILE_DEBUG, "%s: called on %pd\n", __func__,
|
||||||
|
dentry);
|
||||||
|
|
||||||
|
ret = orangefs_inode_getxattr(d_inode(dentry),
|
||||||
|
"user.pvfs2.meta_hint",
|
||||||
|
&val, sizeof(val));
|
||||||
|
if (ret < 0 && ret != -ENODATA)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
gossip_debug(GOSSIP_FILE_DEBUG, "%s: flags=%u\n", __func__, (u32) val);
|
||||||
|
|
||||||
|
fileattr_fill_flags(fa, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int orangefs_fileattr_set(struct user_namespace *mnt_userns,
|
||||||
|
struct dentry *dentry, struct fileattr *fa)
|
||||||
|
{
|
||||||
|
u64 val = 0;
|
||||||
|
|
||||||
|
gossip_debug(GOSSIP_FILE_DEBUG, "%s: called on %pd\n", __func__,
|
||||||
|
dentry);
|
||||||
|
/*
|
||||||
|
* ORANGEFS_MIRROR_FL is set internally when the mirroring mode is
|
||||||
|
* turned on for a file. The user is not allowed to turn on this bit,
|
||||||
|
* but the bit is present if the user first gets the flags and then
|
||||||
|
* updates the flags with some new settings. So, we ignore it in the
|
||||||
|
* following edit. bligon.
|
||||||
|
*/
|
||||||
|
if (fileattr_has_fsx(fa) ||
|
||||||
|
(fa->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL | ORANGEFS_MIRROR_FL))) {
|
||||||
|
gossip_err("%s: only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n",
|
||||||
|
__func__);
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
val = fa->flags;
|
||||||
|
gossip_debug(GOSSIP_FILE_DEBUG, "%s: flags=%u\n", __func__, (u32) val);
|
||||||
|
return orangefs_inode_setxattr(d_inode(dentry),
|
||||||
|
"user.pvfs2.meta_hint",
|
||||||
|
&val, sizeof(val), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* ORANGEFS2 implementation of VFS inode operations for files */
|
/* ORANGEFS2 implementation of VFS inode operations for files */
|
||||||
static const struct inode_operations orangefs_file_inode_operations = {
|
static const struct inode_operations orangefs_file_inode_operations = {
|
||||||
.get_acl = orangefs_get_acl,
|
.get_acl = orangefs_get_acl,
|
||||||
@ -963,6 +1011,8 @@ static const struct inode_operations orangefs_file_inode_operations = {
|
|||||||
.listxattr = orangefs_listxattr,
|
.listxattr = orangefs_listxattr,
|
||||||
.permission = orangefs_permission,
|
.permission = orangefs_permission,
|
||||||
.update_time = orangefs_update_time,
|
.update_time = orangefs_update_time,
|
||||||
|
.fileattr_get = orangefs_fileattr_get,
|
||||||
|
.fileattr_set = orangefs_fileattr_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int orangefs_init_iops(struct inode *inode)
|
static int orangefs_init_iops(struct inode *inode)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user