Skip to content

Commit 9cbae74

Browse files
author
Miklos Szeredi
committed
hfsplus: 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>
1 parent d701ea2 commit 9cbae74

4 files changed

Lines changed: 59 additions & 95 deletions

File tree

fs/hfsplus/dir.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,8 @@ const struct inode_operations hfsplus_dir_inode_operations = {
569569
.rename = hfsplus_rename,
570570
.getattr = hfsplus_getattr,
571571
.listxattr = hfsplus_listxattr,
572+
.fileattr_get = hfsplus_fileattr_get,
573+
.fileattr_set = hfsplus_fileattr_set,
572574
};
573575

574576
const struct file_operations hfsplus_dir_operations = {

fs/hfsplus/hfsplus_fs.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -344,17 +344,6 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb)
344344
#define hfs_brec_goto hfsplus_brec_goto
345345
#define hfs_part_find hfsplus_part_find
346346

347-
/*
348-
* definitions for ext2 flag ioctls (linux really needs a generic
349-
* interface for this).
350-
*/
351-
352-
/* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support
353-
* chattr/lsattr */
354-
#define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS
355-
#define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS
356-
357-
358347
/*
359348
* hfs+-specific ioctl for making the filesystem bootable
360349
*/
@@ -493,6 +482,9 @@ int hfsplus_getattr(struct user_namespace *mnt_userns, const struct path *path,
493482
unsigned int query_flags);
494483
int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end,
495484
int datasync);
485+
int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa);
486+
int hfsplus_fileattr_set(struct user_namespace *mnt_userns,
487+
struct dentry *dentry, struct fileattr *fa);
496488

497489
/* ioctl.c */
498490
long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);

fs/hfsplus/inode.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/sched.h>
1818
#include <linux/cred.h>
1919
#include <linux/uio.h>
20+
#include <linux/fileattr.h>
2021

2122
#include "hfsplus_fs.h"
2223
#include "hfsplus_raw.h"
@@ -353,6 +354,8 @@ static const struct inode_operations hfsplus_file_inode_operations = {
353354
.setattr = hfsplus_setattr,
354355
.getattr = hfsplus_getattr,
355356
.listxattr = hfsplus_listxattr,
357+
.fileattr_get = hfsplus_fileattr_get,
358+
.fileattr_set = hfsplus_fileattr_set,
356359
};
357360

358361
static const struct file_operations hfsplus_file_operations = {
@@ -628,3 +631,54 @@ int hfsplus_cat_write_inode(struct inode *inode)
628631
hfs_find_exit(&fd);
629632
return 0;
630633
}
634+
635+
int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa)
636+
{
637+
struct inode *inode = d_inode(dentry);
638+
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
639+
unsigned int flags = 0;
640+
641+
if (inode->i_flags & S_IMMUTABLE)
642+
flags |= FS_IMMUTABLE_FL;
643+
if (inode->i_flags & S_APPEND)
644+
flags |= FS_APPEND_FL;
645+
if (hip->userflags & HFSPLUS_FLG_NODUMP)
646+
flags |= FS_NODUMP_FL;
647+
648+
fileattr_fill_flags(fa, flags);
649+
650+
return 0;
651+
}
652+
653+
int hfsplus_fileattr_set(struct user_namespace *mnt_userns,
654+
struct dentry *dentry, struct fileattr *fa)
655+
{
656+
struct inode *inode = d_inode(dentry);
657+
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
658+
unsigned int new_fl = 0;
659+
660+
if (fileattr_has_fsx(fa))
661+
return -EOPNOTSUPP;
662+
663+
/* don't silently ignore unsupported ext2 flags */
664+
if (fa->flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL))
665+
return -EOPNOTSUPP;
666+
667+
if (fa->flags & FS_IMMUTABLE_FL)
668+
new_fl |= S_IMMUTABLE;
669+
670+
if (fa->flags & FS_APPEND_FL)
671+
new_fl |= S_APPEND;
672+
673+
inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND);
674+
675+
if (fa->flags & FS_NODUMP_FL)
676+
hip->userflags |= HFSPLUS_FLG_NODUMP;
677+
else
678+
hip->userflags &= ~HFSPLUS_FLG_NODUMP;
679+
680+
inode->i_ctime = current_time(inode);
681+
mark_inode_dirty(inode);
682+
683+
return 0;
684+
}

fs/hfsplus/ioctl.c

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -57,95 +57,11 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags)
5757
return 0;
5858
}
5959

60-
static inline unsigned int hfsplus_getflags(struct inode *inode)
61-
{
62-
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
63-
unsigned int flags = 0;
64-
65-
if (inode->i_flags & S_IMMUTABLE)
66-
flags |= FS_IMMUTABLE_FL;
67-
if (inode->i_flags & S_APPEND)
68-
flags |= FS_APPEND_FL;
69-
if (hip->userflags & HFSPLUS_FLG_NODUMP)
70-
flags |= FS_NODUMP_FL;
71-
return flags;
72-
}
73-
74-
static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags)
75-
{
76-
struct inode *inode = file_inode(file);
77-
unsigned int flags = hfsplus_getflags(inode);
78-
79-
return put_user(flags, user_flags);
80-
}
81-
82-
static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags)
83-
{
84-
struct inode *inode = file_inode(file);
85-
struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
86-
unsigned int flags, new_fl = 0;
87-
unsigned int oldflags = hfsplus_getflags(inode);
88-
int err = 0;
89-
90-
err = mnt_want_write_file(file);
91-
if (err)
92-
goto out;
93-
94-
if (!inode_owner_or_capable(&init_user_ns, inode)) {
95-
err = -EACCES;
96-
goto out_drop_write;
97-
}
98-
99-
if (get_user(flags, user_flags)) {
100-
err = -EFAULT;
101-
goto out_drop_write;
102-
}
103-
104-
inode_lock(inode);
105-
106-
err = vfs_ioc_setflags_prepare(inode, oldflags, flags);
107-
if (err)
108-
goto out_unlock_inode;
109-
110-
/* don't silently ignore unsupported ext2 flags */
111-
if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) {
112-
err = -EOPNOTSUPP;
113-
goto out_unlock_inode;
114-
}
115-
116-
if (flags & FS_IMMUTABLE_FL)
117-
new_fl |= S_IMMUTABLE;
118-
119-
if (flags & FS_APPEND_FL)
120-
new_fl |= S_APPEND;
121-
122-
inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND);
123-
124-
if (flags & FS_NODUMP_FL)
125-
hip->userflags |= HFSPLUS_FLG_NODUMP;
126-
else
127-
hip->userflags &= ~HFSPLUS_FLG_NODUMP;
128-
129-
inode->i_ctime = current_time(inode);
130-
mark_inode_dirty(inode);
131-
132-
out_unlock_inode:
133-
inode_unlock(inode);
134-
out_drop_write:
135-
mnt_drop_write_file(file);
136-
out:
137-
return err;
138-
}
139-
14060
long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
14161
{
14262
void __user *argp = (void __user *)arg;
14363

14464
switch (cmd) {
145-
case HFSPLUS_IOC_EXT2_GETFLAGS:
146-
return hfsplus_ioctl_getflags(file, argp);
147-
case HFSPLUS_IOC_EXT2_SETFLAGS:
148-
return hfsplus_ioctl_setflags(file, argp);
14965
case HFSPLUS_IOC_BLESS:
15066
return hfsplus_ioctl_bless(file, argp);
15167
default:

0 commit comments

Comments
 (0)