Skip to content

Commit 88b631c

Browse files
author
Miklos Szeredi
committed
gfs2: 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: Andreas Gruenbacher <agruenba@redhat.com>
1 parent 9b1bb01 commit 88b631c

File tree

3 files changed

+27
-43
lines changed

3 files changed

+27
-43
lines changed

fs/gfs2/file.c

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/dlm_plock.h>
2626
#include <linux/delay.h>
2727
#include <linux/backing-dev.h>
28+
#include <linux/fileattr.h>
2829

2930
#include "gfs2.h"
3031
#include "incore.h"
@@ -153,23 +154,25 @@ static inline u32 gfs2_gfsflags_to_fsflags(struct inode *inode, u32 gfsflags)
153154
return fsflags;
154155
}
155156

156-
static int gfs2_get_flags(struct file *filp, u32 __user *ptr)
157+
int gfs2_fileattr_get(struct dentry *dentry, struct fileattr *fa)
157158
{
158-
struct inode *inode = file_inode(filp);
159+
struct inode *inode = d_inode(dentry);
159160
struct gfs2_inode *ip = GFS2_I(inode);
160161
struct gfs2_holder gh;
161162
int error;
162163
u32 fsflags;
163164

165+
if (d_is_special(dentry))
166+
return -ENOTTY;
167+
164168
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
165169
error = gfs2_glock_nq(&gh);
166170
if (error)
167171
goto out_uninit;
168172

169173
fsflags = gfs2_gfsflags_to_fsflags(inode, ip->i_diskflags);
170174

171-
if (put_user(fsflags, ptr))
172-
error = -EFAULT;
175+
fileattr_fill_flags(fa, fsflags);
173176

174177
gfs2_glock_dq(&gh);
175178
out_uninit:
@@ -213,33 +216,19 @@ void gfs2_set_inode_flags(struct inode *inode)
213216
* @fsflags: The FS_* inode flags passed in
214217
*
215218
*/
216-
static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask,
219+
static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask,
217220
const u32 fsflags)
218221
{
219-
struct inode *inode = file_inode(filp);
220222
struct gfs2_inode *ip = GFS2_I(inode);
221223
struct gfs2_sbd *sdp = GFS2_SB(inode);
222224
struct buffer_head *bh;
223225
struct gfs2_holder gh;
224226
int error;
225-
u32 new_flags, flags, oldflags;
226-
227-
error = mnt_want_write_file(filp);
228-
if (error)
229-
return error;
227+
u32 new_flags, flags;
230228

231229
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
232230
if (error)
233-
goto out_drop_write;
234-
235-
oldflags = gfs2_gfsflags_to_fsflags(inode, ip->i_diskflags);
236-
error = vfs_ioc_setflags_prepare(inode, oldflags, fsflags);
237-
if (error)
238-
goto out;
239-
240-
error = -EACCES;
241-
if (!inode_owner_or_capable(&init_user_ns, inode))
242-
goto out;
231+
return error;
243232

244233
error = 0;
245234
flags = ip->i_diskflags;
@@ -252,9 +241,6 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask,
252241
goto out;
253242
if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY))
254243
goto out;
255-
if (((new_flags ^ flags) & GFS2_DIF_IMMUTABLE) &&
256-
!capable(CAP_LINUX_IMMUTABLE))
257-
goto out;
258244
if (!IS_IMMUTABLE(inode)) {
259245
error = gfs2_permission(&init_user_ns, inode, MAY_WRITE);
260246
if (error)
@@ -291,20 +277,22 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask,
291277
gfs2_trans_end(sdp);
292278
out:
293279
gfs2_glock_dq_uninit(&gh);
294-
out_drop_write:
295-
mnt_drop_write_file(filp);
296280
return error;
297281
}
298282

299-
static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
283+
int gfs2_fileattr_set(struct user_namespace *mnt_userns,
284+
struct dentry *dentry, struct fileattr *fa)
300285
{
301-
struct inode *inode = file_inode(filp);
302-
u32 fsflags, gfsflags = 0;
286+
struct inode *inode = d_inode(dentry);
287+
u32 fsflags = fa->flags, gfsflags = 0;
303288
u32 mask;
304289
int i;
305290

306-
if (get_user(fsflags, ptr))
307-
return -EFAULT;
291+
if (d_is_special(dentry))
292+
return -ENOTTY;
293+
294+
if (fileattr_has_fsx(fa))
295+
return -EOPNOTSUPP;
308296

309297
for (i = 0; i < ARRAY_SIZE(fsflag_gfs2flag); i++) {
310298
if (fsflags & fsflag_gfs2flag[i].fsflag) {
@@ -325,7 +313,7 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
325313
mask &= ~(GFS2_DIF_TOPDIR | GFS2_DIF_INHERIT_JDATA);
326314
}
327315

328-
return do_gfs2_set_flags(filp, gfsflags, mask, fsflags);
316+
return do_gfs2_set_flags(inode, gfsflags, mask, fsflags);
329317
}
330318

331319
static int gfs2_getlabel(struct file *filp, char __user *label)
@@ -342,10 +330,6 @@ static int gfs2_getlabel(struct file *filp, char __user *label)
342330
static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
343331
{
344332
switch(cmd) {
345-
case FS_IOC_GETFLAGS:
346-
return gfs2_get_flags(filp, (u32 __user *)arg);
347-
case FS_IOC_SETFLAGS:
348-
return gfs2_set_flags(filp, (u32 __user *)arg);
349333
case FITRIM:
350334
return gfs2_fitrim(filp, (void __user *)arg);
351335
case FS_IOC_GETFSLABEL:
@@ -359,13 +343,6 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
359343
static long gfs2_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
360344
{
361345
switch(cmd) {
362-
/* These are just misnamed, they actually get/put from/to user an int */
363-
case FS_IOC32_GETFLAGS:
364-
cmd = FS_IOC_GETFLAGS;
365-
break;
366-
case FS_IOC32_SETFLAGS:
367-
cmd = FS_IOC_SETFLAGS;
368-
break;
369346
/* Keep this list in sync with gfs2_ioctl */
370347
case FITRIM:
371348
case FS_IOC_GETFSLABEL:

fs/gfs2/inode.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,8 @@ static const struct inode_operations gfs2_file_iops = {
21572157
.get_acl = gfs2_get_acl,
21582158
.set_acl = gfs2_set_acl,
21592159
.update_time = gfs2_update_time,
2160+
.fileattr_get = gfs2_fileattr_get,
2161+
.fileattr_set = gfs2_fileattr_set,
21602162
};
21612163

21622164
static const struct inode_operations gfs2_dir_iops = {
@@ -2178,6 +2180,8 @@ static const struct inode_operations gfs2_dir_iops = {
21782180
.set_acl = gfs2_set_acl,
21792181
.update_time = gfs2_update_time,
21802182
.atomic_open = gfs2_atomic_open,
2183+
.fileattr_get = gfs2_fileattr_get,
2184+
.fileattr_set = gfs2_fileattr_set,
21812185
};
21822186

21832187
static const struct inode_operations gfs2_symlink_iops = {

fs/gfs2/inode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ extern loff_t gfs2_seek_hole(struct file *file, loff_t offset);
111111
extern const struct file_operations gfs2_file_fops_nolock;
112112
extern const struct file_operations gfs2_dir_fops_nolock;
113113

114+
extern int gfs2_fileattr_get(struct dentry *dentry, struct fileattr *fa);
115+
extern int gfs2_fileattr_set(struct user_namespace *mnt_userns,
116+
struct dentry *dentry, struct fileattr *fa);
114117
extern void gfs2_set_inode_flags(struct inode *inode);
115118

116119
#ifdef CONFIG_GFS2_FS_LOCKING_DLM

0 commit comments

Comments
 (0)