aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.h47
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c207
3 files changed, 171 insertions, 91 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 03c55b8fa373..498d3e15843b 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -68,7 +68,7 @@
68 * XFS_IOC_PATH_TO_HANDLE 68 * XFS_IOC_PATH_TO_HANDLE
69 * returns full handle for a path 69 * returns full handle for a path
70 */ 70 */
71STATIC int 71int
72xfs_find_handle( 72xfs_find_handle(
73 unsigned int cmd, 73 unsigned int cmd,
74 xfs_fsop_handlereq_t *hreq) 74 xfs_fsop_handlereq_t *hreq)
@@ -245,7 +245,7 @@ xfs_vget_fsop_handlereq(
245 return 0; 245 return 0;
246} 246}
247 247
248STATIC int 248int
249xfs_open_by_handle( 249xfs_open_by_handle(
250 xfs_mount_t *mp, 250 xfs_mount_t *mp,
251 xfs_fsop_handlereq_t *hreq, 251 xfs_fsop_handlereq_t *hreq,
@@ -355,7 +355,7 @@ do_readlink(
355} 355}
356 356
357 357
358STATIC int 358int
359xfs_readlink_by_handle( 359xfs_readlink_by_handle(
360 xfs_mount_t *mp, 360 xfs_mount_t *mp,
361 xfs_fsop_handlereq_t *hreq, 361 xfs_fsop_handlereq_t *hreq,
@@ -651,7 +651,7 @@ xfs_attrmulti_by_handle(
651 return -error; 651 return -error;
652} 652}
653 653
654STATIC int 654int
655xfs_ioc_space( 655xfs_ioc_space(
656 struct xfs_inode *ip, 656 struct xfs_inode *ip,
657 struct inode *inode, 657 struct inode *inode,
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.h b/fs/xfs/linux-2.6/xfs_ioctl.h
new file mode 100644
index 000000000000..2df849f49a5e
--- /dev/null
+++ b/fs/xfs/linux-2.6/xfs_ioctl.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2008 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_IOCTL_H__
19#define __XFS_IOCTL_H__
20
21extern int
22xfs_ioc_space(
23 struct xfs_inode *ip,
24 struct inode *inode,
25 struct file *filp,
26 int ioflags,
27 unsigned int cmd,
28 xfs_flock64_t *bf);
29
30extern int
31xfs_find_handle(
32 unsigned int cmd,
33 xfs_fsop_handlereq_t *hreq);
34
35extern int
36xfs_open_by_handle(
37 xfs_mount_t *mp,
38 xfs_fsop_handlereq_t *hreq,
39 struct file *parfilp,
40 struct inode *parinode);
41
42extern int
43xfs_readlink_by_handle(
44 xfs_mount_t *mp,
45 xfs_fsop_handlereq_t *hreq,
46 struct inode *parinode);
47#endif
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 620bb2d6d26c..35edc054fb99 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -43,55 +43,62 @@
43#include "xfs_error.h" 43#include "xfs_error.h"
44#include "xfs_dfrag.h" 44#include "xfs_dfrag.h"
45#include "xfs_vnodeops.h" 45#include "xfs_vnodeops.h"
46#include "xfs_fsops.h"
47#include "xfs_ioctl.h"
46#include "xfs_ioctl32.h" 48#include "xfs_ioctl32.h"
47 49
48#define _NATIVE_IOC(cmd, type) \ 50#define _NATIVE_IOC(cmd, type) \
49 _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type)) 51 _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type))
50 52
51#ifdef BROKEN_X86_ALIGNMENT 53#ifdef BROKEN_X86_ALIGNMENT
52STATIC unsigned long 54STATIC int
53xfs_ioctl32_flock( 55xfs_compat_flock64_copyin(
54 unsigned long arg) 56 xfs_flock64_t *bf,
57 compat_xfs_flock64_t __user *arg32)
55{ 58{
56 compat_xfs_flock64_t __user *p32 = (void __user *)arg; 59 if (get_user(bf->l_type, &arg32->l_type) ||
57 xfs_flock64_t __user *p = compat_alloc_user_space(sizeof(*p)); 60 get_user(bf->l_whence, &arg32->l_whence) ||
58 61 get_user(bf->l_start, &arg32->l_start) ||
59 if (copy_in_user(&p->l_type, &p32->l_type, sizeof(s16)) || 62 get_user(bf->l_len, &arg32->l_len) ||
60 copy_in_user(&p->l_whence, &p32->l_whence, sizeof(s16)) || 63 get_user(bf->l_sysid, &arg32->l_sysid) ||
61 copy_in_user(&p->l_start, &p32->l_start, sizeof(s64)) || 64 get_user(bf->l_pid, &arg32->l_pid) ||
62 copy_in_user(&p->l_len, &p32->l_len, sizeof(s64)) || 65 copy_from_user(bf->l_pad, &arg32->l_pad, 4*sizeof(u32)))
63 copy_in_user(&p->l_sysid, &p32->l_sysid, sizeof(s32)) || 66 return -XFS_ERROR(EFAULT);
64 copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) || 67 return 0;
65 copy_in_user(&p->l_pad, &p32->l_pad, 4*sizeof(u32)))
66 return -EFAULT;
67
68 return (unsigned long)p;
69} 68}
70 69
71STATIC unsigned long xfs_ioctl32_geom_v1(unsigned long arg) 70STATIC int
71xfs_compat_ioc_fsgeometry_v1(
72 struct xfs_mount *mp,
73 compat_xfs_fsop_geom_v1_t __user *arg32)
72{ 74{
73 compat_xfs_fsop_geom_v1_t __user *p32 = (void __user *)arg; 75 xfs_fsop_geom_t fsgeo;
74 xfs_fsop_geom_v1_t __user *p = compat_alloc_user_space(sizeof(*p)); 76 int error;
75 77
76 if (copy_in_user(p, p32, sizeof(*p32))) 78 error = xfs_fs_geometry(mp, &fsgeo, 3);
77 return -EFAULT; 79 if (error)
78 return (unsigned long)p; 80 return -error;
81 /* The 32-bit variant simply has some padding at the end */
82 if (copy_to_user(arg32, &fsgeo, sizeof(struct compat_xfs_fsop_geom_v1)))
83 return -XFS_ERROR(EFAULT);
84 return 0;
79} 85}
80 86
81STATIC int xfs_inumbers_fmt_compat( 87STATIC int
82 void __user *ubuffer, 88xfs_inumbers_fmt_compat(
83 const xfs_inogrp_t *buffer, 89 void __user *ubuffer,
84 long count, 90 const xfs_inogrp_t *buffer,
85 long *written) 91 long count,
92 long *written)
86{ 93{
87 compat_xfs_inogrp_t __user *p32 = ubuffer; 94 compat_xfs_inogrp_t __user *p32 = ubuffer;
88 long i; 95 long i;
89 96
90 for (i = 0; i < count; i++) { 97 for (i = 0; i < count; i++) {
91 if (put_user(buffer[i].xi_startino, &p32[i].xi_startino) || 98 if (put_user(buffer[i].xi_startino, &p32[i].xi_startino) ||
92 put_user(buffer[i].xi_alloccount, &p32[i].xi_alloccount) || 99 put_user(buffer[i].xi_alloccount, &p32[i].xi_alloccount) ||
93 put_user(buffer[i].xi_allocmask, &p32[i].xi_allocmask)) 100 put_user(buffer[i].xi_allocmask, &p32[i].xi_allocmask))
94 return -EFAULT; 101 return -XFS_ERROR(EFAULT);
95 } 102 }
96 *written = count * sizeof(*p32); 103 *written = count * sizeof(*p32);
97 return 0; 104 return 0;
@@ -103,24 +110,26 @@ STATIC int xfs_inumbers_fmt_compat(
103 110
104/* XFS_IOC_FSBULKSTAT and friends */ 111/* XFS_IOC_FSBULKSTAT and friends */
105 112
106STATIC int xfs_bstime_store_compat( 113STATIC int
107 compat_xfs_bstime_t __user *p32, 114xfs_bstime_store_compat(
108 const xfs_bstime_t *p) 115 compat_xfs_bstime_t __user *p32,
116 const xfs_bstime_t *p)
109{ 117{
110 __s32 sec32; 118 __s32 sec32;
111 119
112 sec32 = p->tv_sec; 120 sec32 = p->tv_sec;
113 if (put_user(sec32, &p32->tv_sec) || 121 if (put_user(sec32, &p32->tv_sec) ||
114 put_user(p->tv_nsec, &p32->tv_nsec)) 122 put_user(p->tv_nsec, &p32->tv_nsec))
115 return -EFAULT; 123 return -XFS_ERROR(EFAULT);
116 return 0; 124 return 0;
117} 125}
118 126
119STATIC int xfs_bulkstat_one_fmt_compat( 127STATIC int
128xfs_bulkstat_one_fmt_compat(
120 void __user *ubuffer, 129 void __user *ubuffer,
121 const xfs_bstat_t *buffer) 130 const xfs_bstat_t *buffer)
122{ 131{
123 compat_xfs_bstat_t __user *p32 = ubuffer; 132 compat_xfs_bstat_t __user *p32 = ubuffer;
124 133
125 if (put_user(buffer->bs_ino, &p32->bs_ino) || 134 if (put_user(buffer->bs_ino, &p32->bs_ino) ||
126 put_user(buffer->bs_mode, &p32->bs_mode) || 135 put_user(buffer->bs_mode, &p32->bs_mode) ||
@@ -142,7 +151,7 @@ STATIC int xfs_bulkstat_one_fmt_compat(
142 put_user(buffer->bs_dmevmask, &p32->bs_dmevmask) || 151 put_user(buffer->bs_dmevmask, &p32->bs_dmevmask) ||
143 put_user(buffer->bs_dmstate, &p32->bs_dmstate) || 152 put_user(buffer->bs_dmstate, &p32->bs_dmstate) ||
144 put_user(buffer->bs_aextents, &p32->bs_aextents)) 153 put_user(buffer->bs_aextents, &p32->bs_aextents))
145 return -EFAULT; 154 return -XFS_ERROR(EFAULT);
146 return sizeof(*p32); 155 return sizeof(*p32);
147} 156}
148 157
@@ -165,20 +174,20 @@ xfs_ioc_bulkstat_compat(
165 /* should be called again (unused here, but used in dmapi) */ 174 /* should be called again (unused here, but used in dmapi) */
166 175
167 if (!capable(CAP_SYS_ADMIN)) 176 if (!capable(CAP_SYS_ADMIN))
168 return -EPERM; 177 return -XFS_ERROR(EPERM);
169 178
170 if (XFS_FORCED_SHUTDOWN(mp)) 179 if (XFS_FORCED_SHUTDOWN(mp))
171 return -XFS_ERROR(EIO); 180 return -XFS_ERROR(EIO);
172 181
173 if (get_user(addr, &p32->lastip)) 182 if (get_user(addr, &p32->lastip))
174 return -EFAULT; 183 return -XFS_ERROR(EFAULT);
175 bulkreq.lastip = compat_ptr(addr); 184 bulkreq.lastip = compat_ptr(addr);
176 if (get_user(bulkreq.icount, &p32->icount) || 185 if (get_user(bulkreq.icount, &p32->icount) ||
177 get_user(addr, &p32->ubuffer)) 186 get_user(addr, &p32->ubuffer))
178 return -EFAULT; 187 return -XFS_ERROR(EFAULT);
179 bulkreq.ubuffer = compat_ptr(addr); 188 bulkreq.ubuffer = compat_ptr(addr);
180 if (get_user(addr, &p32->ocount)) 189 if (get_user(addr, &p32->ocount))
181 return -EFAULT; 190 return -XFS_ERROR(EFAULT);
182 bulkreq.ocount = compat_ptr(addr); 191 bulkreq.ocount = compat_ptr(addr);
183 192
184 if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64))) 193 if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
@@ -216,38 +225,40 @@ xfs_ioc_bulkstat_compat(
216 return 0; 225 return 0;
217} 226}
218 227
219STATIC unsigned long xfs_ioctl32_fshandle(unsigned long arg) 228STATIC int
229xfs_compat_handlereq_copyin(
230 xfs_fsop_handlereq_t *hreq,
231 compat_xfs_fsop_handlereq_t __user *arg32)
220{ 232{
221 compat_xfs_fsop_handlereq_t __user *p32 = (void __user *)arg; 233 compat_xfs_fsop_handlereq_t hreq32;
222 xfs_fsop_handlereq_t __user *p = compat_alloc_user_space(sizeof(*p)); 234
223 u32 addr; 235 if (copy_from_user(&hreq32, arg32, sizeof(compat_xfs_fsop_handlereq_t)))
224 236 return -XFS_ERROR(EFAULT);
225 if (copy_in_user(&p->fd, &p32->fd, sizeof(__u32)) || 237
226 get_user(addr, &p32->path) || 238 hreq->fd = hreq32.fd;
227 put_user(compat_ptr(addr), &p->path) || 239 hreq->path = compat_ptr(hreq32.path);
228 copy_in_user(&p->oflags, &p32->oflags, sizeof(__u32)) || 240 hreq->oflags = hreq32.oflags;
229 get_user(addr, &p32->ihandle) || 241 hreq->ihandle = compat_ptr(hreq32.ihandle);
230 put_user(compat_ptr(addr), &p->ihandle) || 242 hreq->ihandlen = hreq32.ihandlen;
231 copy_in_user(&p->ihandlen, &p32->ihandlen, sizeof(__u32)) || 243 hreq->ohandle = compat_ptr(hreq32.ohandle);
232 get_user(addr, &p32->ohandle) || 244 hreq->ohandlen = compat_ptr(hreq32.ohandlen);
233 put_user(compat_ptr(addr), &p->ohandle) || 245
234 get_user(addr, &p32->ohandlen) || 246 return 0;
235 put_user(compat_ptr(addr), &p->ohandlen))
236 return -EFAULT;
237
238 return (unsigned long)p;
239} 247}
240 248
241STATIC long 249STATIC long
242xfs_compat_ioctl( 250xfs_compat_ioctl(
243 int mode, 251 xfs_inode_t *ip,
244 struct file *file, 252 struct file *filp,
253 int ioflags,
245 unsigned cmd, 254 unsigned cmd,
246 unsigned long arg) 255 void __user *arg)
247{ 256{
248 struct inode *inode = file->f_path.dentry->d_inode; 257 struct inode *inode = filp->f_path.dentry->d_inode;
258 xfs_mount_t *mp = ip->i_mount;
249 int error; 259 int error;
250 260
261 xfs_itrace_entry(XFS_I(inode));
251 switch (cmd) { 262 switch (cmd) {
252 case XFS_IOC_DIOINFO: 263 case XFS_IOC_DIOINFO:
253 case XFS_IOC_FSGEOMETRY: 264 case XFS_IOC_FSGEOMETRY:
@@ -290,14 +301,16 @@ xfs_compat_ioctl(
290 case XFS_IOC_RESVSP_32: 301 case XFS_IOC_RESVSP_32:
291 case XFS_IOC_UNRESVSP_32: 302 case XFS_IOC_UNRESVSP_32:
292 case XFS_IOC_RESVSP64_32: 303 case XFS_IOC_RESVSP64_32:
293 case XFS_IOC_UNRESVSP64_32: 304 case XFS_IOC_UNRESVSP64_32: {
294 arg = xfs_ioctl32_flock(arg); 305 struct xfs_flock64 bf;
306
307 if (xfs_compat_flock64_copyin(&bf, arg))
308 return -XFS_ERROR(EFAULT);
295 cmd = _NATIVE_IOC(cmd, struct xfs_flock64); 309 cmd = _NATIVE_IOC(cmd, struct xfs_flock64);
296 break; 310 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf);
311 }
297 case XFS_IOC_FSGEOMETRY_V1_32: 312 case XFS_IOC_FSGEOMETRY_V1_32:
298 arg = xfs_ioctl32_geom_v1(arg); 313 return xfs_compat_ioc_fsgeometry_v1(mp, arg);
299 cmd = _NATIVE_IOC(cmd, struct xfs_fsop_geom_v1);
300 break;
301#else /* These are handled fine if no alignment issues */ 314#else /* These are handled fine if no alignment issues */
302 case XFS_IOC_ALLOCSP: 315 case XFS_IOC_ALLOCSP:
303 case XFS_IOC_FREESP: 316 case XFS_IOC_FREESP:
@@ -323,35 +336,55 @@ xfs_compat_ioctl(
323 cmd, (void __user*)arg); 336 cmd, (void __user*)arg);
324 case XFS_IOC_FD_TO_HANDLE_32: 337 case XFS_IOC_FD_TO_HANDLE_32:
325 case XFS_IOC_PATH_TO_HANDLE_32: 338 case XFS_IOC_PATH_TO_HANDLE_32:
326 case XFS_IOC_PATH_TO_FSHANDLE_32: 339 case XFS_IOC_PATH_TO_FSHANDLE_32: {
327 case XFS_IOC_OPEN_BY_HANDLE_32: 340 struct xfs_fsop_handlereq hreq;
328 case XFS_IOC_READLINK_BY_HANDLE_32: 341
329 arg = xfs_ioctl32_fshandle(arg); 342 if (xfs_compat_handlereq_copyin(&hreq, arg))
343 return -XFS_ERROR(EFAULT);
330 cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq); 344 cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq);
331 break; 345 return xfs_find_handle(cmd, &hreq);
346 }
347 case XFS_IOC_OPEN_BY_HANDLE_32: {
348 struct xfs_fsop_handlereq hreq;
349
350 if (xfs_compat_handlereq_copyin(&hreq, arg))
351 return -XFS_ERROR(EFAULT);
352 return xfs_open_by_handle(mp, &hreq, filp, inode);
353 }
354 case XFS_IOC_READLINK_BY_HANDLE_32: {
355 struct xfs_fsop_handlereq hreq;
356
357 if (xfs_compat_handlereq_copyin(&hreq, arg))
358 return -XFS_ERROR(EFAULT);
359 return xfs_readlink_by_handle(mp, &hreq, inode);
360 }
332 default: 361 default:
333 return -ENOIOCTLCMD; 362 return -XFS_ERROR(ENOIOCTLCMD);
334 } 363 }
335 364
336 error = xfs_ioctl(XFS_I(inode), file, mode, cmd, (void __user *)arg); 365 error = xfs_ioctl(ip, filp, ioflags, cmd, arg);
337 xfs_iflags_set(XFS_I(inode), XFS_IMODIFIED);
338 return error; 366 return error;
339} 367}
340 368
341long 369long
342xfs_file_compat_ioctl( 370xfs_file_compat_ioctl(
343 struct file *file, 371 struct file *filp,
344 unsigned cmd, 372 unsigned int cmd,
345 unsigned long arg) 373 unsigned long p)
346{ 374{
347 return xfs_compat_ioctl(0, file, cmd, arg); 375 struct inode *inode = filp->f_path.dentry->d_inode;
376
377 return xfs_compat_ioctl(XFS_I(inode), filp, 0, cmd, (void __user *)p);
348} 378}
349 379
350long 380long
351xfs_file_compat_invis_ioctl( 381xfs_file_compat_invis_ioctl(
352 struct file *file, 382 struct file *filp,
353 unsigned cmd, 383 unsigned int cmd,
354 unsigned long arg) 384 unsigned long p)
355{ 385{
356 return xfs_compat_ioctl(IO_INVIS, file, cmd, arg); 386 struct inode *inode = filp->f_path.dentry->d_inode;
387
388 return xfs_compat_ioctl(XFS_I(inode), filp, IO_INVIS, cmd,
389 (void __user *)p);
357} 390}