Blame view

fs/xfs/xfs_ioctl32.c 15 KB
0b61f8a40   Dave Chinner   xfs: convert to S...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
  /*
7b7187698   Nathan Scott   [XFS] Update lice...
3
4
   * Copyright (c) 2004-2005 Silicon Graphics, Inc.
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
   */
62e194ecd   Christoph Hellwig   xfs: use mnt_want...
6
  #include <linux/mount.h>
e89c04133   Darrick J. Wong   xfs: implement th...
7
  #include <linux/fsmap.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
  #include "xfs.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
  #include "xfs_fs.h"
5467b34bd   Darrick J. Wong   xfs: move xfs_ino...
10
  #include "xfs_shared.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
11
  #include "xfs_format.h"
239880ef6   Dave Chinner   xfs: decouple log...
12
13
  #include "xfs_log_format.h"
  #include "xfs_trans_resv.h"
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
14
  #include "xfs_mount.h"
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
15
  #include "xfs_inode.h"
2810bd684   Darrick J. Wong   xfs: convert bulk...
16
  #include "xfs_iwalk.h"
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
17
  #include "xfs_itable.h"
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
18
  #include "xfs_fsops.h"
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
19
  #include "xfs_rtalloc.h"
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
20
  #include "xfs_attr.h"
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
21
  #include "xfs_ioctl.h"
a8272ce0c   David Chinner   [XFS] Fix up spar...
22
  #include "xfs_ioctl32.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
23
  #include "xfs_trace.h"
c368ebcd4   Darrick J. Wong   xfs: hoist xfs_fs...
24
  #include "xfs_sb.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25

526c420c4   Eric Sandeen   [XFS] add handler...
26
27
  #define  _NATIVE_IOC(cmd, type) \
  	  _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type))
ffae263a6   sandeen@sandeen.net   [XFS] Move compat...
28
  #ifdef BROKEN_X86_ALIGNMENT
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
29
30
31
32
  STATIC int
  xfs_compat_flock64_copyin(
  	xfs_flock64_t		*bf,
  	compat_xfs_flock64_t	__user *arg32)
526c420c4   Eric Sandeen   [XFS] add handler...
33
  {
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
34
35
36
37
38
39
40
  	if (get_user(bf->l_type,	&arg32->l_type) ||
  	    get_user(bf->l_whence,	&arg32->l_whence) ||
  	    get_user(bf->l_start,	&arg32->l_start) ||
  	    get_user(bf->l_len,		&arg32->l_len) ||
  	    get_user(bf->l_sysid,	&arg32->l_sysid) ||
  	    get_user(bf->l_pid,		&arg32->l_pid) ||
  	    copy_from_user(bf->l_pad,	&arg32->l_pad,	4*sizeof(u32)))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
41
  		return -EFAULT;
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
42
  	return 0;
526c420c4   Eric Sandeen   [XFS] add handler...
43
  }
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
44
45
46
47
  STATIC int
  xfs_compat_ioc_fsgeometry_v1(
  	struct xfs_mount	  *mp,
  	compat_xfs_fsop_geom_v1_t __user *arg32)
547e00c3c   Michal Marek   [XFS] Compat ioct...
48
  {
1b6d968de   Dave Chinner   xfs: bump XFS_IOC...
49
  	struct xfs_fsop_geom	  fsgeo;
547e00c3c   Michal Marek   [XFS] Compat ioct...
50

910832697   Eric Sandeen   xfs: change some ...
51
  	xfs_fs_geometry(&mp->m_sb, &fsgeo, 3);
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
52
53
  	/* The 32-bit variant simply has some padding at the end */
  	if (copy_to_user(arg32, &fsgeo, sizeof(struct compat_xfs_fsop_geom_v1)))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
54
  		return -EFAULT;
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
55
  	return 0;
547e00c3c   Michal Marek   [XFS] Compat ioct...
56
  }
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
57
  STATIC int
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
58
59
60
61
62
63
  xfs_compat_growfs_data_copyin(
  	struct xfs_growfs_data	 *in,
  	compat_xfs_growfs_data_t __user *arg32)
  {
  	if (get_user(in->newblocks, &arg32->newblocks) ||
  	    get_user(in->imaxpct,   &arg32->imaxpct))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
64
  		return -EFAULT;
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
65
66
67
68
69
70
71
72
73
74
  	return 0;
  }
  
  STATIC int
  xfs_compat_growfs_rt_copyin(
  	struct xfs_growfs_rt	 *in,
  	compat_xfs_growfs_rt_t	__user *arg32)
  {
  	if (get_user(in->newblocks, &arg32->newblocks) ||
  	    get_user(in->extsize,   &arg32->extsize))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
75
  		return -EFAULT;
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
76
77
78
79
  	return 0;
  }
  
  STATIC int
8bfe9d181   Darrick J. Wong   xfs: rename bulks...
80
  xfs_fsinumbers_fmt_compat(
5f19c7fc6   Darrick J. Wong   xfs: introduce v5...
81
82
  	struct xfs_ibulk		*breq,
  	const struct xfs_inumbers	*ig)
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
83
  {
5f19c7fc6   Darrick J. Wong   xfs: introduce v5...
84
85
86
87
88
  	struct compat_xfs_inogrp __user	*p32 = breq->ubuffer;
  	struct xfs_inogrp		ig1;
  	struct xfs_inogrp		*igrp = &ig1;
  
  	xfs_inumbers_to_inogrp(&ig1, ig);
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
89

677717fbd   Darrick J. Wong   xfs: refactor INU...
90
91
92
93
94
95
  	if (put_user(igrp->xi_startino,   &p32->xi_startino) ||
  	    put_user(igrp->xi_alloccount, &p32->xi_alloccount) ||
  	    put_user(igrp->xi_allocmask,  &p32->xi_allocmask))
  		return -EFAULT;
  
  	return xfs_ibulk_advance(breq, sizeof(struct compat_xfs_inogrp));
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
96
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  #else
8bfe9d181   Darrick J. Wong   xfs: rename bulks...
98
  #define xfs_fsinumbers_fmt_compat xfs_fsinumbers_fmt
e5d412f17   sandeen@sandeen.net   [XFS] Reorder xfs...
99
  #endif	/* BROKEN_X86_ALIGNMENT */
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
100

e94fc4a43   sandeen@sandeen.net   [XFS] Add compat ...
101
102
103
104
105
  STATIC int
  xfs_ioctl32_bstime_copyin(
  	xfs_bstime_t		*bstime,
  	compat_xfs_bstime_t	__user *bstime32)
  {
3b62f000c   Arnd Bergmann   xfs: rename compa...
106
  	old_time32_t		sec32;	/* tv_sec differs on 64 vs. 32 */
e94fc4a43   sandeen@sandeen.net   [XFS] Add compat ...
107
108
109
  
  	if (get_user(sec32,		&bstime32->tv_sec)	||
  	    get_user(bstime->tv_nsec,	&bstime32->tv_nsec))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
110
  		return -EFAULT;
e94fc4a43   sandeen@sandeen.net   [XFS] Add compat ...
111
112
113
  	bstime->tv_sec = sec32;
  	return 0;
  }
6f71fb683   Darrick J. Wong   xfs: remove vario...
114
115
116
117
  /*
   * struct xfs_bstat has differing alignment on intel, & bstime_t sizes
   * everywhere
   */
e94fc4a43   sandeen@sandeen.net   [XFS] Add compat ...
118
119
  STATIC int
  xfs_ioctl32_bstat_copyin(
6f71fb683   Darrick J. Wong   xfs: remove vario...
120
121
  	struct xfs_bstat		*bstat,
  	struct compat_xfs_bstat	__user	*bstat32)
e94fc4a43   sandeen@sandeen.net   [XFS] Add compat ...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  {
  	if (get_user(bstat->bs_ino,	&bstat32->bs_ino)	||
  	    get_user(bstat->bs_mode,	&bstat32->bs_mode)	||
  	    get_user(bstat->bs_nlink,	&bstat32->bs_nlink)	||
  	    get_user(bstat->bs_uid,	&bstat32->bs_uid)	||
  	    get_user(bstat->bs_gid,	&bstat32->bs_gid)	||
  	    get_user(bstat->bs_rdev,	&bstat32->bs_rdev)	||
  	    get_user(bstat->bs_blksize,	&bstat32->bs_blksize)	||
  	    get_user(bstat->bs_size,	&bstat32->bs_size)	||
  	    xfs_ioctl32_bstime_copyin(&bstat->bs_atime, &bstat32->bs_atime) ||
  	    xfs_ioctl32_bstime_copyin(&bstat->bs_mtime, &bstat32->bs_mtime) ||
  	    xfs_ioctl32_bstime_copyin(&bstat->bs_ctime, &bstat32->bs_ctime) ||
  	    get_user(bstat->bs_blocks,	&bstat32->bs_size)	||
  	    get_user(bstat->bs_xflags,	&bstat32->bs_size)	||
  	    get_user(bstat->bs_extsize,	&bstat32->bs_extsize)	||
  	    get_user(bstat->bs_extents,	&bstat32->bs_extents)	||
  	    get_user(bstat->bs_gen,	&bstat32->bs_gen)	||
6743099ce   Arkadiusz Mi?kiewicz   xfs: Extend proje...
139
140
  	    get_user(bstat->bs_projid_lo, &bstat32->bs_projid_lo) ||
  	    get_user(bstat->bs_projid_hi, &bstat32->bs_projid_hi) ||
b1d6cc02f   Dave Chinner   xfs: compat_xfs_b...
141
  	    get_user(bstat->bs_forkoff,	&bstat32->bs_forkoff)	||
e94fc4a43   sandeen@sandeen.net   [XFS] Add compat ...
142
143
144
  	    get_user(bstat->bs_dmevmask, &bstat32->bs_dmevmask)	||
  	    get_user(bstat->bs_dmstate,	&bstat32->bs_dmstate)	||
  	    get_user(bstat->bs_aextents, &bstat32->bs_aextents))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
145
  		return -EFAULT;
e94fc4a43   sandeen@sandeen.net   [XFS] Add compat ...
146
147
  	return 0;
  }
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
148
  /* XFS_IOC_FSBULKSTAT and friends */
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
149
150
151
152
  STATIC int
  xfs_bstime_store_compat(
  	compat_xfs_bstime_t	__user *p32,
  	const xfs_bstime_t	*p)
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
153
  {
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
154
  	__s32			sec32;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
155
156
157
158
  
  	sec32 = p->tv_sec;
  	if (put_user(sec32, &p32->tv_sec) ||
  	    put_user(p->tv_nsec, &p32->tv_nsec))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
159
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
160
161
  	return 0;
  }
65fbaf248   sandeen@sandeen.net   [XFS] Fix xfs_bul...
162
  /* Return 0 on success or positive error (to xfs_bulkstat()) */
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
163
  STATIC int
8bfe9d181   Darrick J. Wong   xfs: rename bulks...
164
  xfs_fsbulkstat_one_fmt_compat(
7035f9724   Darrick J. Wong   xfs: introduce ne...
165
166
  	struct xfs_ibulk		*breq,
  	const struct xfs_bulkstat	*bstat)
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
167
  {
7035f9724   Darrick J. Wong   xfs: introduce ne...
168
169
170
171
172
  	struct compat_xfs_bstat	__user	*p32 = breq->ubuffer;
  	struct xfs_bstat		bs1;
  	struct xfs_bstat		*buffer = &bs1;
  
  	xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
65fbaf248   sandeen@sandeen.net   [XFS] Fix xfs_bul...
173
174
175
176
177
178
179
180
181
  
  	if (put_user(buffer->bs_ino,	  &p32->bs_ino)		||
  	    put_user(buffer->bs_mode,	  &p32->bs_mode)	||
  	    put_user(buffer->bs_nlink,	  &p32->bs_nlink)	||
  	    put_user(buffer->bs_uid,	  &p32->bs_uid)		||
  	    put_user(buffer->bs_gid,	  &p32->bs_gid)		||
  	    put_user(buffer->bs_rdev,	  &p32->bs_rdev)	||
  	    put_user(buffer->bs_blksize,  &p32->bs_blksize)	||
  	    put_user(buffer->bs_size,	  &p32->bs_size)	||
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
182
183
184
  	    xfs_bstime_store_compat(&p32->bs_atime, &buffer->bs_atime) ||
  	    xfs_bstime_store_compat(&p32->bs_mtime, &buffer->bs_mtime) ||
  	    xfs_bstime_store_compat(&p32->bs_ctime, &buffer->bs_ctime) ||
65fbaf248   sandeen@sandeen.net   [XFS] Fix xfs_bul...
185
186
187
188
189
190
  	    put_user(buffer->bs_blocks,	  &p32->bs_blocks)	||
  	    put_user(buffer->bs_xflags,	  &p32->bs_xflags)	||
  	    put_user(buffer->bs_extsize,  &p32->bs_extsize)	||
  	    put_user(buffer->bs_extents,  &p32->bs_extents)	||
  	    put_user(buffer->bs_gen,	  &p32->bs_gen)		||
  	    put_user(buffer->bs_projid,	  &p32->bs_projid)	||
6743099ce   Arkadiusz Mi?kiewicz   xfs: Extend proje...
191
  	    put_user(buffer->bs_projid_hi,	&p32->bs_projid_hi)	||
b1d6cc02f   Dave Chinner   xfs: compat_xfs_b...
192
  	    put_user(buffer->bs_forkoff,  &p32->bs_forkoff)	||
65fbaf248   sandeen@sandeen.net   [XFS] Fix xfs_bul...
193
194
  	    put_user(buffer->bs_dmevmask, &p32->bs_dmevmask)	||
  	    put_user(buffer->bs_dmstate,  &p32->bs_dmstate)	||
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
195
  	    put_user(buffer->bs_aextents, &p32->bs_aextents))
2451337dd   Dave Chinner   xfs: global error...
196
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
197

2810bd684   Darrick J. Wong   xfs: convert bulk...
198
  	return xfs_ibulk_advance(breq, sizeof(struct compat_xfs_bstat));
2ee4fa5cb   sandeen@sandeen.net   [XFS] Make the bu...
199
  }
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
200
201
  /* copied from xfs_ioctl.c */
  STATIC int
8bfe9d181   Darrick J. Wong   xfs: rename bulks...
202
  xfs_compat_ioc_fsbulkstat(
2ee4fa5cb   sandeen@sandeen.net   [XFS] Make the bu...
203
204
  	xfs_mount_t		  *mp,
  	unsigned int		  cmd,
6f71fb683   Darrick J. Wong   xfs: remove vario...
205
  	struct compat_xfs_fsop_bulkreq __user *p32)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
  	u32			addr;
2810bd684   Darrick J. Wong   xfs: convert bulk...
208
209
210
211
212
213
  	struct xfs_fsop_bulkreq	bulkreq;
  	struct xfs_ibulk	breq = {
  		.mp		= mp,
  		.ocount		= 0,
  	};
  	xfs_ino_t		lastino;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
214
  	int			error;
7ca860e3c   Nick Bowler   xfs: Fix bulkstat...
215
216
217
218
219
220
  	/*
  	 * Output structure handling functions.  Depending on the command,
  	 * either the xfs_bstat and xfs_inogrp structures are written out
  	 * to userpace memory via bulkreq.ubuffer.  Normally the compat
  	 * functions and structure size are the correct ones to use ...
  	 */
8bfe9d181   Darrick J. Wong   xfs: rename bulks...
221
222
  	inumbers_fmt_pf		inumbers_func = xfs_fsinumbers_fmt_compat;
  	bulkstat_one_fmt_pf	bs_one_func = xfs_fsbulkstat_one_fmt_compat;
7ca860e3c   Nick Bowler   xfs: Fix bulkstat...
223
224
225
226
227
228
229
230
231
232
233
  
  #ifdef CONFIG_X86_X32
  	if (in_x32_syscall()) {
  		/*
  		 * ... but on x32 the input xfs_fsop_bulkreq has pointers
  		 * which must be handled in the "compat" (32-bit) way, while
  		 * the xfs_bstat and xfs_inogrp structures follow native 64-
  		 * bit layout convention.  So adjust accordingly, otherwise
  		 * the data written out in compat layout will not match what
  		 * x32 userspace expects.
  		 */
8bfe9d181   Darrick J. Wong   xfs: rename bulks...
234
235
  		inumbers_func = xfs_fsinumbers_fmt;
  		bs_one_func = xfs_fsbulkstat_one_fmt;
7ca860e3c   Nick Bowler   xfs: Fix bulkstat...
236
237
  	}
  #endif
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
238
239
  	/* done = 1 if there are more stats to get and if bulkstat */
  	/* should be called again (unused here, but used in dmapi) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240

faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
241
  	if (!capable(CAP_SYS_ADMIN))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
242
  		return -EPERM;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
243
244
  
  	if (XFS_FORCED_SHUTDOWN(mp))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
245
  		return -EIO;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
246
247
  
  	if (get_user(addr, &p32->lastip))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
248
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
249
250
251
  	bulkreq.lastip = compat_ptr(addr);
  	if (get_user(bulkreq.icount, &p32->icount) ||
  	    get_user(addr, &p32->ubuffer))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
252
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
253
254
  	bulkreq.ubuffer = compat_ptr(addr);
  	if (get_user(addr, &p32->ocount))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
255
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
256
  	bulkreq.ocount = compat_ptr(addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257

2810bd684   Darrick J. Wong   xfs: convert bulk...
258
  	if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64)))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
259
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
260

2810bd684   Darrick J. Wong   xfs: convert bulk...
261
  	if (bulkreq.icount <= 0)
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
262
  		return -EINVAL;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
263

cd57e594a   Lachlan McIlroy   [XFS] 971064 Vari...
264
  	if (bulkreq.ubuffer == NULL)
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
265
  		return -EINVAL;
cd57e594a   Lachlan McIlroy   [XFS] 971064 Vari...
266

2810bd684   Darrick J. Wong   xfs: convert bulk...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  	breq.ubuffer = bulkreq.ubuffer;
  	breq.icount = bulkreq.icount;
  
  	/*
  	 * FSBULKSTAT_SINGLE expects that *lastip contains the inode number
  	 * that we want to stat.  However, FSINUMBERS and FSBULKSTAT expect
  	 * that *lastip contains either zero or the number of the last inode to
  	 * be examined by the previous call and return results starting with
  	 * the next inode after that.  The new bulk request back end functions
  	 * take the inode to start with, so we have to compute the startino
  	 * parameter from lastino to maintain correct function.  lastino == 0
  	 * is a special case because it has traditionally meant "first inode
  	 * in filesystem".
  	 */
af819d276   sandeen@sandeen.net   [XFS] Fix compat ...
281
  	if (cmd == XFS_IOC_FSINUMBERS_32) {
677717fbd   Darrick J. Wong   xfs: refactor INU...
282
283
284
  		breq.startino = lastino ? lastino + 1 : 0;
  		error = xfs_inumbers(&breq, inumbers_func);
  		lastino = breq.startino - 1;
af819d276   sandeen@sandeen.net   [XFS] Fix compat ...
285
  	} else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE_32) {
2810bd684   Darrick J. Wong   xfs: convert bulk...
286
287
288
289
  		breq.startino = lastino;
  		breq.icount = 1;
  		error = xfs_bulkstat_one(&breq, bs_one_func);
  		lastino = breq.startino;
af819d276   sandeen@sandeen.net   [XFS] Fix compat ...
290
  	} else if (cmd == XFS_IOC_FSBULKSTAT_32) {
2810bd684   Darrick J. Wong   xfs: convert bulk...
291
292
293
294
  		breq.startino = lastino ? lastino + 1 : 0;
  		error = xfs_bulkstat(&breq, bs_one_func);
  		lastino = breq.startino - 1;
  	} else {
2451337dd   Dave Chinner   xfs: global error...
295
  		error = -EINVAL;
2810bd684   Darrick J. Wong   xfs: convert bulk...
296
  	}
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
297
  	if (error)
2451337dd   Dave Chinner   xfs: global error...
298
  		return error;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
299

f16fe3ecd   Darrick J. Wong   xfs: bulkstat sho...
300
  	if (bulkreq.lastip != NULL &&
2810bd684   Darrick J. Wong   xfs: convert bulk...
301
  	    copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t)))
f16fe3ecd   Darrick J. Wong   xfs: bulkstat sho...
302
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
303

f16fe3ecd   Darrick J. Wong   xfs: bulkstat sho...
304
  	if (bulkreq.ocount != NULL &&
2810bd684   Darrick J. Wong   xfs: convert bulk...
305
  	    copy_to_user(bulkreq.ocount, &breq.ocount, sizeof(__s32)))
f16fe3ecd   Darrick J. Wong   xfs: bulkstat sho...
306
  		return -EFAULT;
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
307
308
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
  }
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
310

d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
311
312
313
314
  STATIC int
  xfs_compat_handlereq_copyin(
  	xfs_fsop_handlereq_t		*hreq,
  	compat_xfs_fsop_handlereq_t	__user *arg32)
1fa503df6   Michal Marek   [XFS] Compat ioct...
315
  {
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
316
317
318
  	compat_xfs_fsop_handlereq_t	hreq32;
  
  	if (copy_from_user(&hreq32, arg32, sizeof(compat_xfs_fsop_handlereq_t)))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
319
  		return -EFAULT;
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
320
321
322
323
324
325
326
327
328
329
  
  	hreq->fd = hreq32.fd;
  	hreq->path = compat_ptr(hreq32.path);
  	hreq->oflags = hreq32.oflags;
  	hreq->ihandle = compat_ptr(hreq32.ihandle);
  	hreq->ihandlen = hreq32.ihandlen;
  	hreq->ohandle = compat_ptr(hreq32.ohandle);
  	hreq->ohandlen = compat_ptr(hreq32.ohandlen);
  
  	return 0;
1fa503df6   Michal Marek   [XFS] Compat ioct...
330
  }
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
331
332
333
334
  STATIC struct dentry *
  xfs_compat_handlereq_to_dentry(
  	struct file		*parfilp,
  	compat_xfs_fsop_handlereq_t *hreq)
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
335
  {
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
336
337
  	return xfs_handle_to_dentry(parfilp,
  			compat_ptr(hreq->ihandle), hreq->ihandlen);
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
338
339
340
341
  }
  
  STATIC int
  xfs_compat_attrlist_by_handle(
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
342
  	struct file		*parfilp,
53ac39fdb   Christoph Hellwig   xfs: lift cursor ...
343
  	compat_xfs_fsop_attrlist_handlereq_t __user *p)
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
344
  {
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
345
  	compat_xfs_fsop_attrlist_handlereq_t al_hreq;
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
346
  	struct dentry		*dentry;
53ac39fdb   Christoph Hellwig   xfs: lift cursor ...
347
  	int			error;
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
348
349
  
  	if (!capable(CAP_SYS_ADMIN))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
350
  		return -EPERM;
53ac39fdb   Christoph Hellwig   xfs: lift cursor ...
351
  	if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
352
  		return -EFAULT;
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
353

ab596ad89   Christoph Hellwig   xfs: fix dentry a...
354
355
356
  	dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
  	if (IS_ERR(dentry))
  		return PTR_ERR(dentry);
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
357

eb241c747   Christoph Hellwig   xfs: lift buffer ...
358
359
  	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
  			compat_ptr(al_hreq.buffer), al_hreq.buflen,
53ac39fdb   Christoph Hellwig   xfs: lift cursor ...
360
  			al_hreq.flags, &p->pos);
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
361
362
  	dput(dentry);
  	return error;
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
363
  }
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
364
365
  STATIC int
  xfs_compat_attrmulti_by_handle(
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
366
367
  	struct file				*parfilp,
  	void					__user *arg)
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
368
369
370
371
  {
  	int					error;
  	compat_xfs_attr_multiop_t		*ops;
  	compat_xfs_fsop_attrmulti_handlereq_t	am_hreq;
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
372
  	struct dentry				*dentry;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
373
  	unsigned int				i, size;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
374
375
  
  	if (!capable(CAP_SYS_ADMIN))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
376
  		return -EPERM;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
377
378
  	if (copy_from_user(&am_hreq, arg,
  			   sizeof(compat_xfs_fsop_attrmulti_handlereq_t)))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
379
  		return -EFAULT;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
380

fda168c24   Zhitong Wang   xfs: Fix integer ...
381
382
383
  	/* overflow check */
  	if (am_hreq.opcount >= INT_MAX / sizeof(compat_xfs_attr_multiop_t))
  		return -E2BIG;
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
384
385
386
  	dentry = xfs_compat_handlereq_to_dentry(parfilp, &am_hreq.hreq);
  	if (IS_ERR(dentry))
  		return PTR_ERR(dentry);
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
387

2451337dd   Dave Chinner   xfs: global error...
388
  	error = -E2BIG;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
389
390
  	size = am_hreq.opcount * sizeof(compat_xfs_attr_multiop_t);
  	if (!size || size > 16 * PAGE_SIZE)
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
391
  		goto out_dput;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
392

0e639bdee   Li Zefan   xfs: use memdup_u...
393
394
  	ops = memdup_user(compat_ptr(am_hreq.ops), size);
  	if (IS_ERR(ops)) {
4d949021a   Brian Foster   xfs: remove incor...
395
  		error = PTR_ERR(ops);
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
396
  		goto out_dput;
0e639bdee   Li Zefan   xfs: use memdup_u...
397
  	}
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
398

28750975a   sandeen@sandeen.net   [XFS] Hook up com...
399
400
  	error = 0;
  	for (i = 0; i < am_hreq.opcount; i++) {
d0ce64391   Christoph Hellwig   xfs: factor out a...
401
402
403
404
405
  		ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
  				d_inode(dentry), ops[i].am_opcode,
  				compat_ptr(ops[i].am_attrname),
  				compat_ptr(ops[i].am_attrvalue),
  				&ops[i].am_length, ops[i].am_flags);
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
406
407
408
  	}
  
  	if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))
2451337dd   Dave Chinner   xfs: global error...
409
  		error = -EFAULT;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
410

28750975a   sandeen@sandeen.net   [XFS] Hook up com...
411
  	kfree(ops);
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
412
413
   out_dput:
  	dput(dentry);
2451337dd   Dave Chinner   xfs: global error...
414
  	return error;
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
415
  }
4d4be482a   Christoph Hellwig   [XFS] add a FMODE...
416
417
418
419
420
  long
  xfs_file_compat_ioctl(
  	struct file		*filp,
  	unsigned		cmd,
  	unsigned long		p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  {
496ad9aa8   Al Viro   new helper: file_...
422
  	struct inode		*inode = file_inode(filp);
4d4be482a   Christoph Hellwig   [XFS] add a FMODE...
423
424
  	struct xfs_inode	*ip = XFS_I(inode);
  	struct xfs_mount	*mp = ip->i_mount;
4529e6d7a   Christoph Hellwig   xfs: compat_ioctl...
425
  	void			__user *arg = compat_ptr(p);
4d4be482a   Christoph Hellwig   [XFS] add a FMODE...
426
  	int			error;
cca28fb83   Christoph Hellwig   xfs: split xfs_it...
427
  	trace_xfs_file_compat_ioctl(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
  
  	switch (cmd) {
a9d25bde1   Nick Bowler   xfs: Fix x32 ioct...
430
  #if defined(BROKEN_X86_ALIGNMENT)
526c420c4   Eric Sandeen   [XFS] add handler...
431
432
433
  	case XFS_IOC_ALLOCSP_32:
  	case XFS_IOC_FREESP_32:
  	case XFS_IOC_ALLOCSP64_32:
837a6e7f5   Christoph Hellwig   fs: add generic U...
434
  	case XFS_IOC_FREESP64_32: {
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
435
436
437
  		struct xfs_flock64	bf;
  
  		if (xfs_compat_flock64_copyin(&bf, arg))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
438
  			return -EFAULT;
526c420c4   Eric Sandeen   [XFS] add handler...
439
  		cmd = _NATIVE_IOC(cmd, struct xfs_flock64);
837a6e7f5   Christoph Hellwig   fs: add generic U...
440
  		return xfs_ioc_space(filp, &bf);
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
441
  	}
547e00c3c   Michal Marek   [XFS] Compat ioct...
442
  	case XFS_IOC_FSGEOMETRY_V1_32:
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
443
  		return xfs_compat_ioc_fsgeometry_v1(mp, arg);
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
444
445
446
447
  	case XFS_IOC_FSGROWFSDATA_32: {
  		struct xfs_growfs_data	in;
  
  		if (xfs_compat_growfs_data_copyin(&in, arg))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
448
  			return -EFAULT;
d9457dc05   Jan Kara   xfs: Convert to n...
449
450
451
  		error = mnt_want_write_file(filp);
  		if (error)
  			return error;
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
452
  		error = xfs_growfs_data(mp, &in);
d9457dc05   Jan Kara   xfs: Convert to n...
453
  		mnt_drop_write_file(filp);
2451337dd   Dave Chinner   xfs: global error...
454
  		return error;
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
455
456
457
458
459
  	}
  	case XFS_IOC_FSGROWFSRT_32: {
  		struct xfs_growfs_rt	in;
  
  		if (xfs_compat_growfs_rt_copyin(&in, arg))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
460
  			return -EFAULT;
d9457dc05   Jan Kara   xfs: Convert to n...
461
462
463
  		error = mnt_want_write_file(filp);
  		if (error)
  			return error;
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
464
  		error = xfs_growfs_rt(mp, &in);
d9457dc05   Jan Kara   xfs: Convert to n...
465
  		mnt_drop_write_file(filp);
2451337dd   Dave Chinner   xfs: global error...
466
  		return error;
471d59103   sandeen@sandeen.net   [XFS] Add compat ...
467
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
  #endif
e5d412f17   sandeen@sandeen.net   [XFS] Reorder xfs...
469
470
471
472
473
  	/* long changes size, but xfs only copiese out 32 bits */
  	case XFS_IOC_GETXFLAGS_32:
  	case XFS_IOC_SETXFLAGS_32:
  	case XFS_IOC_GETVERSION_32:
  		cmd = _NATIVE_IOC(cmd, long);
4d4be482a   Christoph Hellwig   [XFS] add a FMODE...
474
  		return xfs_file_ioctl(filp, cmd, p);
3725867dc   Christoph Hellwig   xfs: actually ena...
475
  	case XFS_IOC_SWAPEXT_32: {
e5d412f17   sandeen@sandeen.net   [XFS] Reorder xfs...
476
477
478
479
480
481
482
  		struct xfs_swapext	  sxp;
  		struct compat_xfs_swapext __user *sxu = arg;
  
  		/* Bulk copy in up to the sx_stat field, then copy bstat */
  		if (copy_from_user(&sxp, sxu,
  				   offsetof(struct xfs_swapext, sx_stat)) ||
  		    xfs_ioctl32_bstat_copyin(&sxp.sx_stat, &sxu->sx_stat))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
483
  			return -EFAULT;
d9457dc05   Jan Kara   xfs: Convert to n...
484
485
486
  		error = mnt_want_write_file(filp);
  		if (error)
  			return error;
a133d952b   Dave Chinner   xfs: consolidate ...
487
  		error = xfs_ioc_swapext(&sxp);
d9457dc05   Jan Kara   xfs: Convert to n...
488
  		mnt_drop_write_file(filp);
2451337dd   Dave Chinner   xfs: global error...
489
  		return error;
e5d412f17   sandeen@sandeen.net   [XFS] Reorder xfs...
490
  	}
faa63e958   Michal Marek   [XFS] Fix XFS_IOC...
491
492
493
  	case XFS_IOC_FSBULKSTAT_32:
  	case XFS_IOC_FSBULKSTAT_SINGLE_32:
  	case XFS_IOC_FSINUMBERS_32:
8bfe9d181   Darrick J. Wong   xfs: rename bulks...
494
  		return xfs_compat_ioc_fsbulkstat(mp, cmd, arg);
1fa503df6   Michal Marek   [XFS] Compat ioct...
495
496
  	case XFS_IOC_FD_TO_HANDLE_32:
  	case XFS_IOC_PATH_TO_HANDLE_32:
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
497
498
499
500
  	case XFS_IOC_PATH_TO_FSHANDLE_32: {
  		struct xfs_fsop_handlereq	hreq;
  
  		if (xfs_compat_handlereq_copyin(&hreq, arg))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
501
  			return -EFAULT;
1fa503df6   Michal Marek   [XFS] Compat ioct...
502
  		cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq);
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
503
504
505
506
507
508
  		return xfs_find_handle(cmd, &hreq);
  	}
  	case XFS_IOC_OPEN_BY_HANDLE_32: {
  		struct xfs_fsop_handlereq	hreq;
  
  		if (xfs_compat_handlereq_copyin(&hreq, arg))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
509
  			return -EFAULT;
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
510
  		return xfs_open_by_handle(filp, &hreq);
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
511
512
513
514
515
  	}
  	case XFS_IOC_READLINK_BY_HANDLE_32: {
  		struct xfs_fsop_handlereq	hreq;
  
  		if (xfs_compat_handlereq_copyin(&hreq, arg))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
516
  			return -EFAULT;
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
517
  		return xfs_readlink_by_handle(filp, &hreq);
d5547f9fe   sandeen@sandeen.net   [XFS] Clean up so...
518
  	}
ebeecd2b0   sandeen@sandeen.net   [XFS] Hook up com...
519
  	case XFS_IOC_ATTRLIST_BY_HANDLE_32:
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
520
  		return xfs_compat_attrlist_by_handle(filp, arg);
28750975a   sandeen@sandeen.net   [XFS] Hook up com...
521
  	case XFS_IOC_ATTRMULTI_BY_HANDLE_32:
ab596ad89   Christoph Hellwig   xfs: fix dentry a...
522
  		return xfs_compat_attrmulti_by_handle(filp, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
  	default:
314e01a6d   Christoph Hellwig   xfs: fall back to...
524
  		/* try the native version */
4529e6d7a   Christoph Hellwig   xfs: compat_ioctl...
525
  		return xfs_file_ioctl(filp, cmd, (unsigned long)arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
  }