Blame view

fs/jfs/ioctl.c 3.94 KB
d9e902668   Herbert Poetzl   JFS: Add missing ...
1
2
3
4
5
6
7
8
  /*
   * linux/fs/jfs/ioctl.c
   *
   * Copyright (C) 2006 Herbert Poetzl
   * adapted from Remy Card's ext2/ioctl.c
   */
  
  #include <linux/fs.h>
d9e902668   Herbert Poetzl   JFS: Add missing ...
9
10
  #include <linux/ctype.h>
  #include <linux/capability.h>
42a74f206   Dave Hansen   [PATCH] r/o bind ...
11
  #include <linux/mount.h>
d9e902668   Herbert Poetzl   JFS: Add missing ...
12
  #include <linux/time.h>
914e26379   Al Viro   [PATCH] severing ...
13
  #include <linux/sched.h>
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
14
  #include <linux/blkdev.h>
d9e902668   Herbert Poetzl   JFS: Add missing ...
15
16
  #include <asm/current.h>
  #include <asm/uaccess.h>
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
17
18
  #include "jfs_filsys.h"
  #include "jfs_debug.h"
d9e902668   Herbert Poetzl   JFS: Add missing ...
19
20
21
  #include "jfs_incore.h"
  #include "jfs_dinode.h"
  #include "jfs_inode.h"
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
22
23
  #include "jfs_dmap.h"
  #include "jfs_discard.h"
d9e902668   Herbert Poetzl   JFS: Add missing ...
24
25
26
27
28
  
  static struct {
  	long jfs_flag;
  	long ext2_flag;
  } jfs_map[] = {
36695673b   David Howells   [PATCH] BLOCK: Mo...
29
30
31
32
33
34
35
  	{JFS_NOATIME_FL,	FS_NOATIME_FL},
  	{JFS_DIRSYNC_FL,	FS_DIRSYNC_FL},
  	{JFS_SYNC_FL,		FS_SYNC_FL},
  	{JFS_SECRM_FL,		FS_SECRM_FL},
  	{JFS_UNRM_FL,		FS_UNRM_FL},
  	{JFS_APPEND_FL,		FS_APPEND_FL},
  	{JFS_IMMUTABLE_FL,	FS_IMMUTABLE_FL},
d9e902668   Herbert Poetzl   JFS: Add missing ...
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  	{0, 0},
  };
  
  static long jfs_map_ext2(unsigned long flags, int from)
  {
  	int index=0;
  	long mapped=0;
  
  	while (jfs_map[index].jfs_flag) {
  		if (from) {
  			if (jfs_map[index].ext2_flag & flags)
  				mapped |= jfs_map[index].jfs_flag;
  		} else {
  			if (jfs_map[index].jfs_flag & flags)
  				mapped |= jfs_map[index].ext2_flag;
  		}
  		index++;
  	}
  	return mapped;
  }
baab81fa5   Andi Kleen   BKL-removal: Use ...
56
  long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
d9e902668   Herbert Poetzl   JFS: Add missing ...
57
  {
496ad9aa8   Al Viro   new helper: file_...
58
  	struct inode *inode = file_inode(filp);
d9e902668   Herbert Poetzl   JFS: Add missing ...
59
60
61
62
63
  	struct jfs_inode_info *jfs_inode = JFS_IP(inode);
  	unsigned int flags;
  
  	switch (cmd) {
  	case JFS_IOC_GETFLAGS:
3e2221c73   Dave Kleikamp   Copy i_flags to j...
64
  		jfs_get_inode_flags(jfs_inode);
d9e902668   Herbert Poetzl   JFS: Add missing ...
65
66
67
68
69
  		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;
42a74f206   Dave Hansen   [PATCH] r/o bind ...
70
  		int err;
d9e902668   Herbert Poetzl   JFS: Add missing ...
71

a561be710   Al Viro   switch a bunch of...
72
  		err = mnt_want_write_file(filp);
42a74f206   Dave Hansen   [PATCH] r/o bind ...
73
74
  		if (err)
  			return err;
d9e902668   Herbert Poetzl   JFS: Add missing ...
75

2e1496707   Serge E. Hallyn   userns: rename is...
76
  		if (!inode_owner_or_capable(inode)) {
42a74f206   Dave Hansen   [PATCH] r/o bind ...
77
78
79
80
81
82
83
  			err = -EACCES;
  			goto setflags_out;
  		}
  		if (get_user(flags, (int __user *) arg)) {
  			err = -EFAULT;
  			goto setflags_out;
  		}
d9e902668   Herbert Poetzl   JFS: Add missing ...
84
85
86
87
  
  		flags = jfs_map_ext2(flags, 1);
  		if (!S_ISDIR(inode->i_mode))
  			flags &= ~JFS_DIRSYNC_FL;
e47776a0a   Jan Kara   Forbid user to ch...
88
  		/* Is it quota file? Do not allow user to mess with it */
42a74f206   Dave Hansen   [PATCH] r/o bind ...
89
90
91
92
  		if (IS_NOQUOTA(inode)) {
  			err = -EPERM;
  			goto setflags_out;
  		}
baab81fa5   Andi Kleen   BKL-removal: Use ...
93
94
  
  		/* Lock against other parallel changes of flags */
5955102c9   Al Viro   wrappers for ->i_...
95
  		inode_lock(inode);
baab81fa5   Andi Kleen   BKL-removal: Use ...
96

3e2221c73   Dave Kleikamp   Copy i_flags to j...
97
  		jfs_get_inode_flags(jfs_inode);
d9e902668   Herbert Poetzl   JFS: Add missing ...
98
99
100
101
102
103
104
105
106
  		oldflags = jfs_inode->mode2;
  
  		/*
  		 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
  		 * the relevant capability.
  		 */
  		if ((oldflags & JFS_IMMUTABLE_FL) ||
  			((flags ^ oldflags) &
  			(JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
baab81fa5   Andi Kleen   BKL-removal: Use ...
107
  			if (!capable(CAP_LINUX_IMMUTABLE)) {
5955102c9   Al Viro   wrappers for ->i_...
108
  				inode_unlock(inode);
42a74f206   Dave Hansen   [PATCH] r/o bind ...
109
110
  				err = -EPERM;
  				goto setflags_out;
baab81fa5   Andi Kleen   BKL-removal: Use ...
111
  			}
d9e902668   Herbert Poetzl   JFS: Add missing ...
112
113
114
115
116
117
118
  		}
  
  		flags = flags & JFS_FL_USER_MODIFIABLE;
  		flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
  		jfs_inode->mode2 = flags;
  
  		jfs_set_inode_flags(inode);
5955102c9   Al Viro   wrappers for ->i_...
119
  		inode_unlock(inode);
d9e902668   Herbert Poetzl   JFS: Add missing ...
120
121
  		inode->i_ctime = CURRENT_TIME_SEC;
  		mark_inode_dirty(inode);
42a74f206   Dave Hansen   [PATCH] r/o bind ...
122
  setflags_out:
2a79f17e4   Al Viro   vfs: mnt_drop_wri...
123
  		mnt_drop_write_file(filp);
42a74f206   Dave Hansen   [PATCH] r/o bind ...
124
  		return err;
d9e902668   Herbert Poetzl   JFS: Add missing ...
125
  	}
b40c2e665   Tino Reichardt   fs/jfs: TRIM supp...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  
  	case FITRIM:
  	{
  		struct super_block *sb = inode->i_sb;
  		struct request_queue *q = bdev_get_queue(sb->s_bdev);
  		struct fstrim_range range;
  		s64 ret = 0;
  
  		if (!capable(CAP_SYS_ADMIN))
  			return -EPERM;
  
  		if (!blk_queue_discard(q)) {
  			jfs_warn("FITRIM not supported on device");
  			return -EOPNOTSUPP;
  		}
  
  		if (copy_from_user(&range, (struct fstrim_range __user *)arg,
  		    sizeof(range)))
  			return -EFAULT;
  
  		range.minlen = max_t(unsigned int, range.minlen,
  			q->limits.discard_granularity);
  
  		ret = jfs_ioc_trim(inode, &range);
  		if (ret < 0)
  			return ret;
  
  		if (copy_to_user((struct fstrim_range __user *)arg, &range,
  		    sizeof(range)))
  			return -EFAULT;
  
  		return 0;
  	}
d9e902668   Herbert Poetzl   JFS: Add missing ...
159
160
161
162
  	default:
  		return -ENOTTY;
  	}
  }
ef1fc2f01   Andi Kleen   BKL-removal: Impl...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  #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