Commit 2ca58e30 authored by Miklos Szeredi's avatar Miklos Szeredi
Browse files

jfs: convert to fileattr



Use the fileattr API to let the VFS handle locking, permission checking and
conversion.

Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
Cc: Dave Kleikamp <shaggy@kernel.org>
parent 9cbae748
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -130,6 +130,8 @@ int jfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
const struct inode_operations jfs_file_inode_operations = {
	.listxattr	= jfs_listxattr,
	.setattr	= jfs_setattr,
	.fileattr_get	= jfs_fileattr_get,
	.fileattr_set	= jfs_fileattr_set,
#ifdef CONFIG_JFS_POSIX_ACL
	.get_acl	= jfs_get_acl,
	.set_acl	= jfs_set_acl,
@@ -147,7 +149,5 @@ const struct file_operations jfs_file_operations = {
	.fsync		= jfs_fsync,
	.release	= jfs_release,
	.unlocked_ioctl = jfs_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= jfs_compat_ioctl,
#endif
	.compat_ioctl	= compat_ptr_ioctl,
};
+40 −71
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/blkdev.h>
#include <asm/current.h>
#include <linux/uaccess.h>
#include <linux/fileattr.h>

#include "jfs_filsys.h"
#include "jfs_debug.h"
@@ -56,69 +57,56 @@ static long jfs_map_ext2(unsigned long flags, int from)
	return mapped;
}

int jfs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
{
	struct jfs_inode_info *jfs_inode = JFS_IP(d_inode(dentry));
	unsigned int flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;

long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
	if (d_is_special(dentry))
		return -ENOTTY;

	fileattr_fill_flags(fa, jfs_map_ext2(flags, 0));

	return 0;
}

int jfs_fileattr_set(struct user_namespace *mnt_userns,
		     struct dentry *dentry, struct fileattr *fa)
{
	struct inode *inode = file_inode(filp);
	struct inode *inode = d_inode(dentry);
	struct jfs_inode_info *jfs_inode = JFS_IP(inode);
	unsigned int flags;

	switch (cmd) {
	case JFS_IOC_GETFLAGS:
		flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;
		flags = jfs_map_ext2(flags, 0);
		return put_user(flags, (int __user *) arg);
	case JFS_IOC_SETFLAGS: {
		unsigned int oldflags;
		int err;

		err = mnt_want_write_file(filp);
		if (err)
			return err;

		if (!inode_owner_or_capable(&init_user_ns, inode)) {
			err = -EACCES;
			goto setflags_out;
		}
		if (get_user(flags, (int __user *) arg)) {
			err = -EFAULT;
			goto setflags_out;
		}
	if (d_is_special(dentry))
		return -ENOTTY;

		flags = jfs_map_ext2(flags, 1);
	if (fileattr_has_fsx(fa))
		return -EOPNOTSUPP;

	flags = jfs_map_ext2(fa->flags, 1);
	if (!S_ISDIR(inode->i_mode))
		flags &= ~JFS_DIRSYNC_FL;

	/* Is it quota file? Do not allow user to mess with it */
		if (IS_NOQUOTA(inode)) {
			err = -EPERM;
			goto setflags_out;
		}

		/* Lock against other parallel changes of flags */
		inode_lock(inode);

		oldflags = jfs_map_ext2(jfs_inode->mode2 & JFS_FL_USER_VISIBLE,
					0);
		err = vfs_ioc_setflags_prepare(inode, oldflags, flags);
		if (err) {
			inode_unlock(inode);
			goto setflags_out;
		}
	if (IS_NOQUOTA(inode))
		return -EPERM;

	flags = flags & JFS_FL_USER_MODIFIABLE;
	flags |= jfs_inode->mode2 & ~JFS_FL_USER_MODIFIABLE;
	jfs_inode->mode2 = flags;

	jfs_set_inode_flags(inode);
		inode_unlock(inode);
	inode->i_ctime = current_time(inode);
	mark_inode_dirty(inode);
setflags_out:
		mnt_drop_write_file(filp);
		return err;

	return 0;
}

long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct inode *inode = file_inode(filp);

	switch (cmd) {
	case FITRIM:
	{
		struct super_block *sb = inode->i_sb;
@@ -156,22 +144,3 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
		return -ENOTTY;
	}
}

#ifdef CONFIG_COMPAT
long jfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	/* While these ioctl numbers defined with 'long' and have different
	 * numbers than the 64bit ABI,
	 * the actual implementation only deals with ints and is compatible.
	 */
	switch (cmd) {
	case JFS_IOC_GETFLAGS32:
		cmd = JFS_IOC_GETFLAGS;
		break;
	case JFS_IOC_SETFLAGS32:
		cmd = JFS_IOC_SETFLAGS;
		break;
	}
	return jfs_ioctl(filp, cmd, arg);
}
#endif
+0 −7
Original line number Diff line number Diff line
@@ -160,11 +160,4 @@ struct dinode {
#define JFS_FL_USER_MODIFIABLE	0x03F80000
#define JFS_FL_INHERIT		0x03C80000

/* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
#define JFS_IOC_GETFLAGS	_IOR('f', 1, long)
#define JFS_IOC_SETFLAGS	_IOW('f', 2, long)

#define JFS_IOC_GETFLAGS32	_IOR('f', 1, int)
#define JFS_IOC_SETFLAGS32	_IOW('f', 2, int)

#endif /*_H_JFS_DINODE */
+3 −1
Original line number Diff line number Diff line
@@ -9,8 +9,10 @@ struct fid;

extern struct inode *ialloc(struct inode *, umode_t);
extern int jfs_fsync(struct file *, loff_t, loff_t, int);
extern int jfs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
extern int jfs_fileattr_set(struct user_namespace *mnt_userns,
			    struct dentry *dentry, struct fileattr *fa);
extern long jfs_ioctl(struct file *, unsigned int, unsigned long);
extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long);
extern struct inode *jfs_iget(struct super_block *, unsigned long);
extern int jfs_commit_inode(struct inode *, int);
extern int jfs_write_inode(struct inode *, struct writeback_control *);
+3 −3
Original line number Diff line number Diff line
@@ -1522,6 +1522,8 @@ const struct inode_operations jfs_dir_inode_operations = {
	.rename		= jfs_rename,
	.listxattr	= jfs_listxattr,
	.setattr	= jfs_setattr,
	.fileattr_get	= jfs_fileattr_get,
	.fileattr_set	= jfs_fileattr_set,
#ifdef CONFIG_JFS_POSIX_ACL
	.get_acl	= jfs_get_acl,
	.set_acl	= jfs_set_acl,
@@ -1533,9 +1535,7 @@ const struct file_operations jfs_dir_operations = {
	.iterate	= jfs_readdir,
	.fsync		= jfs_fsync,
	.unlocked_ioctl = jfs_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= jfs_compat_ioctl,
#endif
	.compat_ioctl	= compat_ptr_ioctl,
	.llseek		= generic_file_llseek,
};