diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 226 |
1 files changed, 122 insertions, 104 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index d3438c72dca..67205f6198b 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -68,26 +68,22 @@ | |||
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 | */ |
71 | STATIC int | 71 | int |
72 | xfs_find_handle( | 72 | xfs_find_handle( |
73 | unsigned int cmd, | 73 | unsigned int cmd, |
74 | void __user *arg) | 74 | xfs_fsop_handlereq_t *hreq) |
75 | { | 75 | { |
76 | int hsize; | 76 | int hsize; |
77 | xfs_handle_t handle; | 77 | xfs_handle_t handle; |
78 | xfs_fsop_handlereq_t hreq; | ||
79 | struct inode *inode; | 78 | struct inode *inode; |
80 | 79 | ||
81 | if (copy_from_user(&hreq, arg, sizeof(hreq))) | ||
82 | return -XFS_ERROR(EFAULT); | ||
83 | |||
84 | memset((char *)&handle, 0, sizeof(handle)); | 80 | memset((char *)&handle, 0, sizeof(handle)); |
85 | 81 | ||
86 | switch (cmd) { | 82 | switch (cmd) { |
87 | case XFS_IOC_PATH_TO_FSHANDLE: | 83 | case XFS_IOC_PATH_TO_FSHANDLE: |
88 | case XFS_IOC_PATH_TO_HANDLE: { | 84 | case XFS_IOC_PATH_TO_HANDLE: { |
89 | struct path path; | 85 | struct path path; |
90 | int error = user_lpath((const char __user *)hreq.path, &path); | 86 | int error = user_lpath((const char __user *)hreq->path, &path); |
91 | if (error) | 87 | if (error) |
92 | return error; | 88 | return error; |
93 | 89 | ||
@@ -101,7 +97,7 @@ xfs_find_handle( | |||
101 | case XFS_IOC_FD_TO_HANDLE: { | 97 | case XFS_IOC_FD_TO_HANDLE: { |
102 | struct file *file; | 98 | struct file *file; |
103 | 99 | ||
104 | file = fget(hreq.fd); | 100 | file = fget(hreq->fd); |
105 | if (!file) | 101 | if (!file) |
106 | return -EBADF; | 102 | return -EBADF; |
107 | 103 | ||
@@ -158,8 +154,8 @@ xfs_find_handle( | |||
158 | } | 154 | } |
159 | 155 | ||
160 | /* now copy our handle into the user buffer & write out the size */ | 156 | /* now copy our handle into the user buffer & write out the size */ |
161 | if (copy_to_user(hreq.ohandle, &handle, hsize) || | 157 | if (copy_to_user(hreq->ohandle, &handle, hsize) || |
162 | copy_to_user(hreq.ohandlen, &hsize, sizeof(__s32))) { | 158 | copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) { |
163 | iput(inode); | 159 | iput(inode); |
164 | return -XFS_ERROR(EFAULT); | 160 | return -XFS_ERROR(EFAULT); |
165 | } | 161 | } |
@@ -249,27 +245,25 @@ xfs_vget_fsop_handlereq( | |||
249 | return 0; | 245 | return 0; |
250 | } | 246 | } |
251 | 247 | ||
252 | STATIC int | 248 | int |
253 | xfs_open_by_handle( | 249 | xfs_open_by_handle( |
254 | xfs_mount_t *mp, | 250 | xfs_mount_t *mp, |
255 | void __user *arg, | 251 | xfs_fsop_handlereq_t *hreq, |
256 | struct file *parfilp, | 252 | struct file *parfilp, |
257 | struct inode *parinode) | 253 | struct inode *parinode) |
258 | { | 254 | { |
255 | const struct cred *cred = current_cred(); | ||
259 | int error; | 256 | int error; |
260 | int new_fd; | 257 | int new_fd; |
261 | int permflag; | 258 | int permflag; |
262 | struct file *filp; | 259 | struct file *filp; |
263 | struct inode *inode; | 260 | struct inode *inode; |
264 | struct dentry *dentry; | 261 | struct dentry *dentry; |
265 | xfs_fsop_handlereq_t hreq; | ||
266 | 262 | ||
267 | if (!capable(CAP_SYS_ADMIN)) | 263 | if (!capable(CAP_SYS_ADMIN)) |
268 | return -XFS_ERROR(EPERM); | 264 | return -XFS_ERROR(EPERM); |
269 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
270 | return -XFS_ERROR(EFAULT); | ||
271 | 265 | ||
272 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode); | 266 | error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode); |
273 | if (error) | 267 | if (error) |
274 | return -error; | 268 | return -error; |
275 | 269 | ||
@@ -280,10 +274,10 @@ xfs_open_by_handle( | |||
280 | } | 274 | } |
281 | 275 | ||
282 | #if BITS_PER_LONG != 32 | 276 | #if BITS_PER_LONG != 32 |
283 | hreq.oflags |= O_LARGEFILE; | 277 | hreq->oflags |= O_LARGEFILE; |
284 | #endif | 278 | #endif |
285 | /* Put open permission in namei format. */ | 279 | /* Put open permission in namei format. */ |
286 | permflag = hreq.oflags; | 280 | permflag = hreq->oflags; |
287 | if ((permflag+1) & O_ACCMODE) | 281 | if ((permflag+1) & O_ACCMODE) |
288 | permflag++; | 282 | permflag++; |
289 | if (permflag & O_TRUNC) | 283 | if (permflag & O_TRUNC) |
@@ -321,15 +315,16 @@ xfs_open_by_handle( | |||
321 | mntget(parfilp->f_path.mnt); | 315 | mntget(parfilp->f_path.mnt); |
322 | 316 | ||
323 | /* Create file pointer. */ | 317 | /* Create file pointer. */ |
324 | filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags); | 318 | filp = dentry_open(dentry, parfilp->f_path.mnt, hreq->oflags, cred); |
325 | if (IS_ERR(filp)) { | 319 | if (IS_ERR(filp)) { |
326 | put_unused_fd(new_fd); | 320 | put_unused_fd(new_fd); |
327 | return -XFS_ERROR(-PTR_ERR(filp)); | 321 | return -XFS_ERROR(-PTR_ERR(filp)); |
328 | } | 322 | } |
323 | |||
329 | if (inode->i_mode & S_IFREG) { | 324 | if (inode->i_mode & S_IFREG) { |
330 | /* invisible operation should not change atime */ | 325 | /* invisible operation should not change atime */ |
331 | filp->f_flags |= O_NOATIME; | 326 | filp->f_flags |= O_NOATIME; |
332 | filp->f_op = &xfs_invis_file_operations; | 327 | filp->f_mode |= FMODE_NOCMTIME; |
333 | } | 328 | } |
334 | 329 | ||
335 | fd_install(new_fd, filp); | 330 | fd_install(new_fd, filp); |
@@ -362,24 +357,21 @@ do_readlink( | |||
362 | } | 357 | } |
363 | 358 | ||
364 | 359 | ||
365 | STATIC int | 360 | int |
366 | xfs_readlink_by_handle( | 361 | xfs_readlink_by_handle( |
367 | xfs_mount_t *mp, | 362 | xfs_mount_t *mp, |
368 | void __user *arg, | 363 | xfs_fsop_handlereq_t *hreq, |
369 | struct inode *parinode) | 364 | struct inode *parinode) |
370 | { | 365 | { |
371 | struct inode *inode; | 366 | struct inode *inode; |
372 | xfs_fsop_handlereq_t hreq; | ||
373 | __u32 olen; | 367 | __u32 olen; |
374 | void *link; | 368 | void *link; |
375 | int error; | 369 | int error; |
376 | 370 | ||
377 | if (!capable(CAP_SYS_ADMIN)) | 371 | if (!capable(CAP_SYS_ADMIN)) |
378 | return -XFS_ERROR(EPERM); | 372 | return -XFS_ERROR(EPERM); |
379 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
380 | return -XFS_ERROR(EFAULT); | ||
381 | 373 | ||
382 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode); | 374 | error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode); |
383 | if (error) | 375 | if (error) |
384 | return -error; | 376 | return -error; |
385 | 377 | ||
@@ -389,7 +381,7 @@ xfs_readlink_by_handle( | |||
389 | goto out_iput; | 381 | goto out_iput; |
390 | } | 382 | } |
391 | 383 | ||
392 | if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) { | 384 | if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) { |
393 | error = -XFS_ERROR(EFAULT); | 385 | error = -XFS_ERROR(EFAULT); |
394 | goto out_iput; | 386 | goto out_iput; |
395 | } | 387 | } |
@@ -401,7 +393,7 @@ xfs_readlink_by_handle( | |||
401 | error = -xfs_readlink(XFS_I(inode), link); | 393 | error = -xfs_readlink(XFS_I(inode), link); |
402 | if (error) | 394 | if (error) |
403 | goto out_kfree; | 395 | goto out_kfree; |
404 | error = do_readlink(hreq.ohandle, olen, link); | 396 | error = do_readlink(hreq->ohandle, olen, link); |
405 | if (error) | 397 | if (error) |
406 | goto out_kfree; | 398 | goto out_kfree; |
407 | 399 | ||
@@ -500,7 +492,7 @@ xfs_attrlist_by_handle( | |||
500 | return -error; | 492 | return -error; |
501 | } | 493 | } |
502 | 494 | ||
503 | STATIC int | 495 | int |
504 | xfs_attrmulti_attr_get( | 496 | xfs_attrmulti_attr_get( |
505 | struct inode *inode, | 497 | struct inode *inode, |
506 | char *name, | 498 | char *name, |
@@ -529,7 +521,7 @@ xfs_attrmulti_attr_get( | |||
529 | return error; | 521 | return error; |
530 | } | 522 | } |
531 | 523 | ||
532 | STATIC int | 524 | int |
533 | xfs_attrmulti_attr_set( | 525 | xfs_attrmulti_attr_set( |
534 | struct inode *inode, | 526 | struct inode *inode, |
535 | char *name, | 527 | char *name, |
@@ -559,7 +551,7 @@ xfs_attrmulti_attr_set( | |||
559 | return error; | 551 | return error; |
560 | } | 552 | } |
561 | 553 | ||
562 | STATIC int | 554 | int |
563 | xfs_attrmulti_attr_remove( | 555 | xfs_attrmulti_attr_remove( |
564 | struct inode *inode, | 556 | struct inode *inode, |
565 | char *name, | 557 | char *name, |
@@ -661,19 +653,26 @@ xfs_attrmulti_by_handle( | |||
661 | return -error; | 653 | return -error; |
662 | } | 654 | } |
663 | 655 | ||
664 | STATIC int | 656 | int |
665 | xfs_ioc_space( | 657 | xfs_ioc_space( |
666 | struct xfs_inode *ip, | 658 | struct xfs_inode *ip, |
667 | struct inode *inode, | 659 | struct inode *inode, |
668 | struct file *filp, | 660 | struct file *filp, |
669 | int ioflags, | 661 | int ioflags, |
670 | unsigned int cmd, | 662 | unsigned int cmd, |
671 | void __user *arg) | 663 | xfs_flock64_t *bf) |
672 | { | 664 | { |
673 | xfs_flock64_t bf; | ||
674 | int attr_flags = 0; | 665 | int attr_flags = 0; |
675 | int error; | 666 | int error; |
676 | 667 | ||
668 | /* | ||
669 | * Only allow the sys admin to reserve space unless | ||
670 | * unwritten extents are enabled. | ||
671 | */ | ||
672 | if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) && | ||
673 | !capable(CAP_SYS_ADMIN)) | ||
674 | return -XFS_ERROR(EPERM); | ||
675 | |||
677 | if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) | 676 | if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) |
678 | return -XFS_ERROR(EPERM); | 677 | return -XFS_ERROR(EPERM); |
679 | 678 | ||
@@ -683,16 +682,12 @@ xfs_ioc_space( | |||
683 | if (!S_ISREG(inode->i_mode)) | 682 | if (!S_ISREG(inode->i_mode)) |
684 | return -XFS_ERROR(EINVAL); | 683 | return -XFS_ERROR(EINVAL); |
685 | 684 | ||
686 | if (copy_from_user(&bf, arg, sizeof(bf))) | ||
687 | return -XFS_ERROR(EFAULT); | ||
688 | |||
689 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) | 685 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
690 | attr_flags |= XFS_ATTR_NONBLOCK; | 686 | attr_flags |= XFS_ATTR_NONBLOCK; |
691 | if (ioflags & IO_INVIS) | 687 | if (ioflags & IO_INVIS) |
692 | attr_flags |= XFS_ATTR_DMI; | 688 | attr_flags |= XFS_ATTR_DMI; |
693 | 689 | ||
694 | error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos, | 690 | error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags); |
695 | NULL, attr_flags); | ||
696 | return -error; | 691 | return -error; |
697 | } | 692 | } |
698 | 693 | ||
@@ -1007,7 +1002,7 @@ xfs_ioctl_setattr( | |||
1007 | * to the file owner ID, except in cases where the | 1002 | * to the file owner ID, except in cases where the |
1008 | * CAP_FSETID capability is applicable. | 1003 | * CAP_FSETID capability is applicable. |
1009 | */ | 1004 | */ |
1010 | if (current->fsuid != ip->i_d.di_uid && !capable(CAP_FOWNER)) { | 1005 | if (current_fsuid() != ip->i_d.di_uid && !capable(CAP_FOWNER)) { |
1011 | code = XFS_ERROR(EPERM); | 1006 | code = XFS_ERROR(EPERM); |
1012 | goto error_return; | 1007 | goto error_return; |
1013 | } | 1008 | } |
@@ -1104,10 +1099,6 @@ xfs_ioctl_setattr( | |||
1104 | 1099 | ||
1105 | /* | 1100 | /* |
1106 | * Change file ownership. Must be the owner or privileged. | 1101 | * Change file ownership. Must be the owner or privileged. |
1107 | * If the system was configured with the "restricted_chown" | ||
1108 | * option, the owner is not permitted to give away the file, | ||
1109 | * and can change the group id only to a group of which he | ||
1110 | * or she is a member. | ||
1111 | */ | 1102 | */ |
1112 | if (mask & FSX_PROJID) { | 1103 | if (mask & FSX_PROJID) { |
1113 | /* | 1104 | /* |
@@ -1136,7 +1127,7 @@ xfs_ioctl_setattr( | |||
1136 | * the superblock version number since projids didn't | 1127 | * the superblock version number since projids didn't |
1137 | * exist before DINODE_VERSION_2 and SB_VERSION_NLINK. | 1128 | * exist before DINODE_VERSION_2 and SB_VERSION_NLINK. |
1138 | */ | 1129 | */ |
1139 | if (ip->i_d.di_version == XFS_DINODE_VERSION_1) | 1130 | if (ip->i_d.di_version == 1) |
1140 | xfs_bump_ino_vers2(tp, ip); | 1131 | xfs_bump_ino_vers2(tp, ip); |
1141 | } | 1132 | } |
1142 | 1133 | ||
@@ -1255,43 +1246,67 @@ xfs_ioc_setxflags( | |||
1255 | } | 1246 | } |
1256 | 1247 | ||
1257 | STATIC int | 1248 | STATIC int |
1249 | xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full) | ||
1250 | { | ||
1251 | struct getbmap __user *base = *ap; | ||
1252 | |||
1253 | /* copy only getbmap portion (not getbmapx) */ | ||
1254 | if (copy_to_user(base, bmv, sizeof(struct getbmap))) | ||
1255 | return XFS_ERROR(EFAULT); | ||
1256 | |||
1257 | *ap += sizeof(struct getbmap); | ||
1258 | return 0; | ||
1259 | } | ||
1260 | |||
1261 | STATIC int | ||
1258 | xfs_ioc_getbmap( | 1262 | xfs_ioc_getbmap( |
1259 | struct xfs_inode *ip, | 1263 | struct xfs_inode *ip, |
1260 | int ioflags, | 1264 | int ioflags, |
1261 | unsigned int cmd, | 1265 | unsigned int cmd, |
1262 | void __user *arg) | 1266 | void __user *arg) |
1263 | { | 1267 | { |
1264 | struct getbmap bm; | 1268 | struct getbmapx bmx; |
1265 | int iflags; | ||
1266 | int error; | 1269 | int error; |
1267 | 1270 | ||
1268 | if (copy_from_user(&bm, arg, sizeof(bm))) | 1271 | if (copy_from_user(&bmx, arg, sizeof(struct getbmapx))) |
1269 | return -XFS_ERROR(EFAULT); | 1272 | return -XFS_ERROR(EFAULT); |
1270 | 1273 | ||
1271 | if (bm.bmv_count < 2) | 1274 | if (bmx.bmv_count < 2) |
1272 | return -XFS_ERROR(EINVAL); | 1275 | return -XFS_ERROR(EINVAL); |
1273 | 1276 | ||
1274 | iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); | 1277 | bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); |
1275 | if (ioflags & IO_INVIS) | 1278 | if (ioflags & IO_INVIS) |
1276 | iflags |= BMV_IF_NO_DMAPI_READ; | 1279 | bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ; |
1277 | 1280 | ||
1278 | error = xfs_getbmap(ip, &bm, (struct getbmap __user *)arg+1, iflags); | 1281 | error = xfs_getbmap(ip, &bmx, xfs_getbmap_format, |
1282 | (struct getbmap *)arg+1); | ||
1279 | if (error) | 1283 | if (error) |
1280 | return -error; | 1284 | return -error; |
1281 | 1285 | ||
1282 | if (copy_to_user(arg, &bm, sizeof(bm))) | 1286 | /* copy back header - only size of getbmap */ |
1287 | if (copy_to_user(arg, &bmx, sizeof(struct getbmap))) | ||
1283 | return -XFS_ERROR(EFAULT); | 1288 | return -XFS_ERROR(EFAULT); |
1284 | return 0; | 1289 | return 0; |
1285 | } | 1290 | } |
1286 | 1291 | ||
1287 | STATIC int | 1292 | STATIC int |
1293 | xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full) | ||
1294 | { | ||
1295 | struct getbmapx __user *base = *ap; | ||
1296 | |||
1297 | if (copy_to_user(base, bmv, sizeof(struct getbmapx))) | ||
1298 | return XFS_ERROR(EFAULT); | ||
1299 | |||
1300 | *ap += sizeof(struct getbmapx); | ||
1301 | return 0; | ||
1302 | } | ||
1303 | |||
1304 | STATIC int | ||
1288 | xfs_ioc_getbmapx( | 1305 | xfs_ioc_getbmapx( |
1289 | struct xfs_inode *ip, | 1306 | struct xfs_inode *ip, |
1290 | void __user *arg) | 1307 | void __user *arg) |
1291 | { | 1308 | { |
1292 | struct getbmapx bmx; | 1309 | struct getbmapx bmx; |
1293 | struct getbmap bm; | ||
1294 | int iflags; | ||
1295 | int error; | 1310 | int error; |
1296 | 1311 | ||
1297 | if (copy_from_user(&bmx, arg, sizeof(bmx))) | 1312 | if (copy_from_user(&bmx, arg, sizeof(bmx))) |
@@ -1300,46 +1315,46 @@ xfs_ioc_getbmapx( | |||
1300 | if (bmx.bmv_count < 2) | 1315 | if (bmx.bmv_count < 2) |
1301 | return -XFS_ERROR(EINVAL); | 1316 | return -XFS_ERROR(EINVAL); |
1302 | 1317 | ||
1303 | /* | 1318 | if (bmx.bmv_iflags & (~BMV_IF_VALID)) |
1304 | * Map input getbmapx structure to a getbmap | ||
1305 | * structure for xfs_getbmap. | ||
1306 | */ | ||
1307 | GETBMAP_CONVERT(bmx, bm); | ||
1308 | |||
1309 | iflags = bmx.bmv_iflags; | ||
1310 | |||
1311 | if (iflags & (~BMV_IF_VALID)) | ||
1312 | return -XFS_ERROR(EINVAL); | 1319 | return -XFS_ERROR(EINVAL); |
1313 | 1320 | ||
1314 | iflags |= BMV_IF_EXTENDED; | 1321 | error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format, |
1315 | 1322 | (struct getbmapx *)arg+1); | |
1316 | error = xfs_getbmap(ip, &bm, (struct getbmapx __user *)arg+1, iflags); | ||
1317 | if (error) | 1323 | if (error) |
1318 | return -error; | 1324 | return -error; |
1319 | 1325 | ||
1320 | GETBMAP_CONVERT(bm, bmx); | 1326 | /* copy back header */ |
1321 | 1327 | if (copy_to_user(arg, &bmx, sizeof(struct getbmapx))) | |
1322 | if (copy_to_user(arg, &bmx, sizeof(bmx))) | ||
1323 | return -XFS_ERROR(EFAULT); | 1328 | return -XFS_ERROR(EFAULT); |
1324 | 1329 | ||
1325 | return 0; | 1330 | return 0; |
1326 | } | 1331 | } |
1327 | 1332 | ||
1328 | int | 1333 | /* |
1329 | xfs_ioctl( | 1334 | * Note: some of the ioctl's return positive numbers as a |
1330 | xfs_inode_t *ip, | 1335 | * byte count indicating success, such as readlink_by_handle. |
1336 | * So we don't "sign flip" like most other routines. This means | ||
1337 | * true errors need to be returned as a negative value. | ||
1338 | */ | ||
1339 | long | ||
1340 | xfs_file_ioctl( | ||
1331 | struct file *filp, | 1341 | struct file *filp, |
1332 | int ioflags, | ||
1333 | unsigned int cmd, | 1342 | unsigned int cmd, |
1334 | void __user *arg) | 1343 | unsigned long p) |
1335 | { | 1344 | { |
1336 | struct inode *inode = filp->f_path.dentry->d_inode; | 1345 | struct inode *inode = filp->f_path.dentry->d_inode; |
1337 | xfs_mount_t *mp = ip->i_mount; | 1346 | struct xfs_inode *ip = XFS_I(inode); |
1347 | struct xfs_mount *mp = ip->i_mount; | ||
1348 | void __user *arg = (void __user *)p; | ||
1349 | int ioflags = 0; | ||
1338 | int error; | 1350 | int error; |
1339 | 1351 | ||
1340 | xfs_itrace_entry(XFS_I(inode)); | 1352 | if (filp->f_mode & FMODE_NOCMTIME) |
1341 | switch (cmd) { | 1353 | ioflags |= IO_INVIS; |
1342 | 1354 | ||
1355 | xfs_itrace_entry(ip); | ||
1356 | |||
1357 | switch (cmd) { | ||
1343 | case XFS_IOC_ALLOCSP: | 1358 | case XFS_IOC_ALLOCSP: |
1344 | case XFS_IOC_FREESP: | 1359 | case XFS_IOC_FREESP: |
1345 | case XFS_IOC_RESVSP: | 1360 | case XFS_IOC_RESVSP: |
@@ -1347,17 +1362,13 @@ xfs_ioctl( | |||
1347 | case XFS_IOC_ALLOCSP64: | 1362 | case XFS_IOC_ALLOCSP64: |
1348 | case XFS_IOC_FREESP64: | 1363 | case XFS_IOC_FREESP64: |
1349 | case XFS_IOC_RESVSP64: | 1364 | case XFS_IOC_RESVSP64: |
1350 | case XFS_IOC_UNRESVSP64: | 1365 | case XFS_IOC_UNRESVSP64: { |
1351 | /* | 1366 | xfs_flock64_t bf; |
1352 | * Only allow the sys admin to reserve space unless | ||
1353 | * unwritten extents are enabled. | ||
1354 | */ | ||
1355 | if (!xfs_sb_version_hasextflgbit(&mp->m_sb) && | ||
1356 | !capable(CAP_SYS_ADMIN)) | ||
1357 | return -EPERM; | ||
1358 | |||
1359 | return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg); | ||
1360 | 1367 | ||
1368 | if (copy_from_user(&bf, arg, sizeof(bf))) | ||
1369 | return -XFS_ERROR(EFAULT); | ||
1370 | return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf); | ||
1371 | } | ||
1361 | case XFS_IOC_DIOINFO: { | 1372 | case XFS_IOC_DIOINFO: { |
1362 | struct dioattr da; | 1373 | struct dioattr da; |
1363 | xfs_buftarg_t *target = | 1374 | xfs_buftarg_t *target = |
@@ -1417,18 +1428,30 @@ xfs_ioctl( | |||
1417 | 1428 | ||
1418 | case XFS_IOC_FD_TO_HANDLE: | 1429 | case XFS_IOC_FD_TO_HANDLE: |
1419 | case XFS_IOC_PATH_TO_HANDLE: | 1430 | case XFS_IOC_PATH_TO_HANDLE: |
1420 | case XFS_IOC_PATH_TO_FSHANDLE: | 1431 | case XFS_IOC_PATH_TO_FSHANDLE: { |
1421 | return xfs_find_handle(cmd, arg); | 1432 | xfs_fsop_handlereq_t hreq; |
1422 | 1433 | ||
1423 | case XFS_IOC_OPEN_BY_HANDLE: | 1434 | if (copy_from_user(&hreq, arg, sizeof(hreq))) |
1424 | return xfs_open_by_handle(mp, arg, filp, inode); | 1435 | return -XFS_ERROR(EFAULT); |
1436 | return xfs_find_handle(cmd, &hreq); | ||
1437 | } | ||
1438 | case XFS_IOC_OPEN_BY_HANDLE: { | ||
1439 | xfs_fsop_handlereq_t hreq; | ||
1425 | 1440 | ||
1441 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
1442 | return -XFS_ERROR(EFAULT); | ||
1443 | return xfs_open_by_handle(mp, &hreq, filp, inode); | ||
1444 | } | ||
1426 | case XFS_IOC_FSSETDM_BY_HANDLE: | 1445 | case XFS_IOC_FSSETDM_BY_HANDLE: |
1427 | return xfs_fssetdm_by_handle(mp, arg, inode); | 1446 | return xfs_fssetdm_by_handle(mp, arg, inode); |
1428 | 1447 | ||
1429 | case XFS_IOC_READLINK_BY_HANDLE: | 1448 | case XFS_IOC_READLINK_BY_HANDLE: { |
1430 | return xfs_readlink_by_handle(mp, arg, inode); | 1449 | xfs_fsop_handlereq_t hreq; |
1431 | 1450 | ||
1451 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
1452 | return -XFS_ERROR(EFAULT); | ||
1453 | return xfs_readlink_by_handle(mp, &hreq, inode); | ||
1454 | } | ||
1432 | case XFS_IOC_ATTRLIST_BY_HANDLE: | 1455 | case XFS_IOC_ATTRLIST_BY_HANDLE: |
1433 | return xfs_attrlist_by_handle(mp, arg, inode); | 1456 | return xfs_attrlist_by_handle(mp, arg, inode); |
1434 | 1457 | ||
@@ -1436,7 +1459,11 @@ xfs_ioctl( | |||
1436 | return xfs_attrmulti_by_handle(mp, arg, filp, inode); | 1459 | return xfs_attrmulti_by_handle(mp, arg, filp, inode); |
1437 | 1460 | ||
1438 | case XFS_IOC_SWAPEXT: { | 1461 | case XFS_IOC_SWAPEXT: { |
1439 | error = xfs_swapext((struct xfs_swapext __user *)arg); | 1462 | struct xfs_swapext sxp; |
1463 | |||
1464 | if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t))) | ||
1465 | return -XFS_ERROR(EFAULT); | ||
1466 | error = xfs_swapext(&sxp); | ||
1440 | return -error; | 1467 | return -error; |
1441 | } | 1468 | } |
1442 | 1469 | ||
@@ -1492,9 +1519,6 @@ xfs_ioctl( | |||
1492 | case XFS_IOC_FSGROWFSDATA: { | 1519 | case XFS_IOC_FSGROWFSDATA: { |
1493 | xfs_growfs_data_t in; | 1520 | xfs_growfs_data_t in; |
1494 | 1521 | ||
1495 | if (!capable(CAP_SYS_ADMIN)) | ||
1496 | return -EPERM; | ||
1497 | |||
1498 | if (copy_from_user(&in, arg, sizeof(in))) | 1522 | if (copy_from_user(&in, arg, sizeof(in))) |
1499 | return -XFS_ERROR(EFAULT); | 1523 | return -XFS_ERROR(EFAULT); |
1500 | 1524 | ||
@@ -1505,9 +1529,6 @@ xfs_ioctl( | |||
1505 | case XFS_IOC_FSGROWFSLOG: { | 1529 | case XFS_IOC_FSGROWFSLOG: { |
1506 | xfs_growfs_log_t in; | 1530 | xfs_growfs_log_t in; |
1507 | 1531 | ||
1508 | if (!capable(CAP_SYS_ADMIN)) | ||
1509 | return -EPERM; | ||
1510 | |||
1511 | if (copy_from_user(&in, arg, sizeof(in))) | 1532 | if (copy_from_user(&in, arg, sizeof(in))) |
1512 | return -XFS_ERROR(EFAULT); | 1533 | return -XFS_ERROR(EFAULT); |
1513 | 1534 | ||
@@ -1518,9 +1539,6 @@ xfs_ioctl( | |||
1518 | case XFS_IOC_FSGROWFSRT: { | 1539 | case XFS_IOC_FSGROWFSRT: { |
1519 | xfs_growfs_rt_t in; | 1540 | xfs_growfs_rt_t in; |
1520 | 1541 | ||
1521 | if (!capable(CAP_SYS_ADMIN)) | ||
1522 | return -EPERM; | ||
1523 | |||
1524 | if (copy_from_user(&in, arg, sizeof(in))) | 1542 | if (copy_from_user(&in, arg, sizeof(in))) |
1525 | return -XFS_ERROR(EFAULT); | 1543 | return -XFS_ERROR(EFAULT); |
1526 | 1544 | ||