Skip to content

Commit 8871d84

Browse files
author
Miklos Szeredi
committed
ubifs: 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: Richard Weinberger <richard@nod.at>
1 parent 03eb606 commit 8871d84

4 files changed

Lines changed: 43 additions & 42 deletions

File tree

fs/ubifs/dir.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,8 @@ const struct inode_operations ubifs_dir_inode_operations = {
16371637
.listxattr = ubifs_listxattr,
16381638
.update_time = ubifs_update_time,
16391639
.tmpfile = ubifs_tmpfile,
1640+
.fileattr_get = ubifs_fileattr_get,
1641+
.fileattr_set = ubifs_fileattr_set,
16401642
};
16411643

16421644
const struct file_operations ubifs_dir_operations = {

fs/ubifs/file.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,8 @@ const struct inode_operations ubifs_file_inode_operations = {
16481648
.getattr = ubifs_getattr,
16491649
.listxattr = ubifs_listxattr,
16501650
.update_time = ubifs_update_time,
1651+
.fileattr_get = ubifs_fileattr_get,
1652+
.fileattr_set = ubifs_fileattr_set,
16511653
};
16521654

16531655
const struct inode_operations ubifs_symlink_inode_operations = {

fs/ubifs/ioctl.c

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include <linux/compat.h>
1616
#include <linux/mount.h>
17+
#include <linux/fileattr.h>
1718
#include "ubifs.h"
1819

1920
/* Need to be kept consistent with checked flags in ioctl2ubifs() */
@@ -103,7 +104,7 @@ static int ubifs2ioctl(int ubifs_flags)
103104

104105
static int setflags(struct inode *inode, int flags)
105106
{
106-
int oldflags, err, release;
107+
int err, release;
107108
struct ubifs_inode *ui = ubifs_inode(inode);
108109
struct ubifs_info *c = inode->i_sb->s_fs_info;
109110
struct ubifs_budget_req req = { .dirtied_ino = 1,
@@ -114,11 +115,6 @@ static int setflags(struct inode *inode, int flags)
114115
return err;
115116

116117
mutex_lock(&ui->ui_mutex);
117-
oldflags = ubifs2ioctl(ui->flags);
118-
err = vfs_ioc_setflags_prepare(inode, oldflags, flags);
119-
if (err)
120-
goto out_unlock;
121-
122118
ui->flags &= ~ioctl2ubifs(UBIFS_SETTABLE_IOCTL_FLAGS);
123119
ui->flags |= ioctl2ubifs(flags);
124120
ubifs_set_inode_flags(inode);
@@ -132,54 +128,52 @@ static int setflags(struct inode *inode, int flags)
132128
if (IS_SYNC(inode))
133129
err = write_inode_now(inode, 1);
134130
return err;
131+
}
135132

136-
out_unlock:
137-
mutex_unlock(&ui->ui_mutex);
138-
ubifs_release_budget(c, &req);
139-
return err;
133+
int ubifs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
134+
{
135+
struct inode *inode = d_inode(dentry);
136+
int flags = ubifs2ioctl(ubifs_inode(inode)->flags);
137+
138+
if (d_is_special(dentry))
139+
return -ENOTTY;
140+
141+
dbg_gen("get flags: %#x, i_flags %#x", flags, inode->i_flags);
142+
fileattr_fill_flags(fa, flags);
143+
144+
return 0;
140145
}
141146

142-
long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
147+
int ubifs_fileattr_set(struct user_namespace *mnt_userns,
148+
struct dentry *dentry, struct fileattr *fa)
143149
{
144-
int flags, err;
145-
struct inode *inode = file_inode(file);
150+
struct inode *inode = d_inode(dentry);
151+
int flags = fa->flags;
146152

147-
switch (cmd) {
148-
case FS_IOC_GETFLAGS:
149-
flags = ubifs2ioctl(ubifs_inode(inode)->flags);
153+
if (d_is_special(dentry))
154+
return -ENOTTY;
150155

151-
dbg_gen("get flags: %#x, i_flags %#x", flags, inode->i_flags);
152-
return put_user(flags, (int __user *) arg);
156+
if (fileattr_has_fsx(fa))
157+
return -EOPNOTSUPP;
153158

154-
case FS_IOC_SETFLAGS: {
155-
if (IS_RDONLY(inode))
156-
return -EROFS;
159+
if (flags & ~UBIFS_GETTABLE_IOCTL_FLAGS)
160+
return -EOPNOTSUPP;
157161

158-
if (!inode_owner_or_capable(&init_user_ns, inode))
159-
return -EACCES;
162+
flags &= UBIFS_SETTABLE_IOCTL_FLAGS;
160163

161-
if (get_user(flags, (int __user *) arg))
162-
return -EFAULT;
164+
if (!S_ISDIR(inode->i_mode))
165+
flags &= ~FS_DIRSYNC_FL;
163166

164-
if (flags & ~UBIFS_GETTABLE_IOCTL_FLAGS)
165-
return -EOPNOTSUPP;
166-
flags &= UBIFS_SETTABLE_IOCTL_FLAGS;
167+
dbg_gen("set flags: %#x, i_flags %#x", flags, inode->i_flags);
168+
return setflags(inode, flags);
169+
}
167170

168-
if (!S_ISDIR(inode->i_mode))
169-
flags &= ~FS_DIRSYNC_FL;
171+
long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
172+
{
173+
int err;
174+
struct inode *inode = file_inode(file);
170175

171-
/*
172-
* Make sure the file-system is read-write and make sure it
173-
* will not become read-only while we are changing the flags.
174-
*/
175-
err = mnt_want_write_file(file);
176-
if (err)
177-
return err;
178-
dbg_gen("set flags: %#x, i_flags %#x", flags, inode->i_flags);
179-
err = setflags(inode, flags);
180-
mnt_drop_write_file(file);
181-
return err;
182-
}
176+
switch (cmd) {
183177
case FS_IOC_SET_ENCRYPTION_POLICY: {
184178
struct ubifs_info *c = inode->i_sb->s_fs_info;
185179

fs/ubifs/ubifs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,9 @@ int ubifs_recover_size(struct ubifs_info *c, bool in_place);
20532053
void ubifs_destroy_size_tree(struct ubifs_info *c);
20542054

20552055
/* ioctl.c */
2056+
int ubifs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
2057+
int ubifs_fileattr_set(struct user_namespace *mnt_userns,
2058+
struct dentry *dentry, struct fileattr *fa);
20562059
long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
20572060
void ubifs_set_inode_flags(struct inode *inode);
20582061
#ifdef CONFIG_COMPAT

0 commit comments

Comments
 (0)