diff options
author | sandeen@sandeen.net <sandeen@sandeen.net> | 2008-11-25 22:20:06 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-12-02 01:08:01 -0500 |
commit | 743bb4650da9e2595d6cedd01c680b5b9398c74a (patch) | |
tree | d0bf4740672bdd77a7cd2dde0af7a564fcfe62d6 /fs | |
parent | 0e446673a15a4e9c336b67c1a638eb12c21d0993 (diff) |
[XFS] Move copy_from_user calls out of ioctl helpers into ioctl switch.
Moving the copy_from_user out of some of the ioctl helpers will
make it easier for the compat ioctl switch to copy in the right
struct, then just pass to the underlying helper.
Also, move common access checks into the helpers themselves,
and out of the native ioctl switch code, to reduce code
duplication between native & compat ioctl callers.
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 109 | ||||
-rw-r--r-- | fs/xfs/xfs_dfrag.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_dfrag.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_fsops.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 2 |
5 files changed, 63 insertions, 64 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 534b175f3a41..03c55b8fa373 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -71,23 +71,19 @@ | |||
71 | STATIC int | 71 | STATIC 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 | } |
@@ -252,7 +248,7 @@ xfs_vget_fsop_handlereq( | |||
252 | STATIC int | 248 | STATIC 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 | { |
@@ -262,14 +258,11 @@ xfs_open_by_handle( | |||
262 | struct file *filp; | 258 | struct file *filp; |
263 | struct inode *inode; | 259 | struct inode *inode; |
264 | struct dentry *dentry; | 260 | struct dentry *dentry; |
265 | xfs_fsop_handlereq_t hreq; | ||
266 | 261 | ||
267 | if (!capable(CAP_SYS_ADMIN)) | 262 | if (!capable(CAP_SYS_ADMIN)) |
268 | return -XFS_ERROR(EPERM); | 263 | return -XFS_ERROR(EPERM); |
269 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
270 | return -XFS_ERROR(EFAULT); | ||
271 | 264 | ||
272 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode); | 265 | error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode); |
273 | if (error) | 266 | if (error) |
274 | return -error; | 267 | return -error; |
275 | 268 | ||
@@ -280,10 +273,10 @@ xfs_open_by_handle( | |||
280 | } | 273 | } |
281 | 274 | ||
282 | #if BITS_PER_LONG != 32 | 275 | #if BITS_PER_LONG != 32 |
283 | hreq.oflags |= O_LARGEFILE; | 276 | hreq->oflags |= O_LARGEFILE; |
284 | #endif | 277 | #endif |
285 | /* Put open permission in namei format. */ | 278 | /* Put open permission in namei format. */ |
286 | permflag = hreq.oflags; | 279 | permflag = hreq->oflags; |
287 | if ((permflag+1) & O_ACCMODE) | 280 | if ((permflag+1) & O_ACCMODE) |
288 | permflag++; | 281 | permflag++; |
289 | if (permflag & O_TRUNC) | 282 | if (permflag & O_TRUNC) |
@@ -321,7 +314,7 @@ xfs_open_by_handle( | |||
321 | mntget(parfilp->f_path.mnt); | 314 | mntget(parfilp->f_path.mnt); |
322 | 315 | ||
323 | /* Create file pointer. */ | 316 | /* Create file pointer. */ |
324 | filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags); | 317 | filp = dentry_open(dentry, parfilp->f_path.mnt, hreq->oflags); |
325 | if (IS_ERR(filp)) { | 318 | if (IS_ERR(filp)) { |
326 | put_unused_fd(new_fd); | 319 | put_unused_fd(new_fd); |
327 | return -XFS_ERROR(-PTR_ERR(filp)); | 320 | return -XFS_ERROR(-PTR_ERR(filp)); |
@@ -365,21 +358,18 @@ do_readlink( | |||
365 | STATIC int | 358 | STATIC int |
366 | xfs_readlink_by_handle( | 359 | xfs_readlink_by_handle( |
367 | xfs_mount_t *mp, | 360 | xfs_mount_t *mp, |
368 | void __user *arg, | 361 | xfs_fsop_handlereq_t *hreq, |
369 | struct inode *parinode) | 362 | struct inode *parinode) |
370 | { | 363 | { |
371 | struct inode *inode; | 364 | struct inode *inode; |
372 | xfs_fsop_handlereq_t hreq; | ||
373 | __u32 olen; | 365 | __u32 olen; |
374 | void *link; | 366 | void *link; |
375 | int error; | 367 | int error; |
376 | 368 | ||
377 | if (!capable(CAP_SYS_ADMIN)) | 369 | if (!capable(CAP_SYS_ADMIN)) |
378 | return -XFS_ERROR(EPERM); | 370 | return -XFS_ERROR(EPERM); |
379 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
380 | return -XFS_ERROR(EFAULT); | ||
381 | 371 | ||
382 | error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode); | 372 | error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode); |
383 | if (error) | 373 | if (error) |
384 | return -error; | 374 | return -error; |
385 | 375 | ||
@@ -389,7 +379,7 @@ xfs_readlink_by_handle( | |||
389 | goto out_iput; | 379 | goto out_iput; |
390 | } | 380 | } |
391 | 381 | ||
392 | if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) { | 382 | if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) { |
393 | error = -XFS_ERROR(EFAULT); | 383 | error = -XFS_ERROR(EFAULT); |
394 | goto out_iput; | 384 | goto out_iput; |
395 | } | 385 | } |
@@ -401,7 +391,7 @@ xfs_readlink_by_handle( | |||
401 | error = -xfs_readlink(XFS_I(inode), link); | 391 | error = -xfs_readlink(XFS_I(inode), link); |
402 | if (error) | 392 | if (error) |
403 | goto out_kfree; | 393 | goto out_kfree; |
404 | error = do_readlink(hreq.ohandle, olen, link); | 394 | error = do_readlink(hreq->ohandle, olen, link); |
405 | if (error) | 395 | if (error) |
406 | goto out_kfree; | 396 | goto out_kfree; |
407 | 397 | ||
@@ -668,12 +658,19 @@ xfs_ioc_space( | |||
668 | struct file *filp, | 658 | struct file *filp, |
669 | int ioflags, | 659 | int ioflags, |
670 | unsigned int cmd, | 660 | unsigned int cmd, |
671 | void __user *arg) | 661 | xfs_flock64_t *bf) |
672 | { | 662 | { |
673 | xfs_flock64_t bf; | ||
674 | int attr_flags = 0; | 663 | int attr_flags = 0; |
675 | int error; | 664 | int error; |
676 | 665 | ||
666 | /* | ||
667 | * Only allow the sys admin to reserve space unless | ||
668 | * unwritten extents are enabled. | ||
669 | */ | ||
670 | if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) && | ||
671 | !capable(CAP_SYS_ADMIN)) | ||
672 | return -XFS_ERROR(EPERM); | ||
673 | |||
677 | if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) | 674 | if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) |
678 | return -XFS_ERROR(EPERM); | 675 | return -XFS_ERROR(EPERM); |
679 | 676 | ||
@@ -683,15 +680,12 @@ xfs_ioc_space( | |||
683 | if (!S_ISREG(inode->i_mode)) | 680 | if (!S_ISREG(inode->i_mode)) |
684 | return -XFS_ERROR(EINVAL); | 681 | return -XFS_ERROR(EINVAL); |
685 | 682 | ||
686 | if (copy_from_user(&bf, arg, sizeof(bf))) | ||
687 | return -XFS_ERROR(EFAULT); | ||
688 | |||
689 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) | 683 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
690 | attr_flags |= XFS_ATTR_NONBLOCK; | 684 | attr_flags |= XFS_ATTR_NONBLOCK; |
691 | if (ioflags & IO_INVIS) | 685 | if (ioflags & IO_INVIS) |
692 | attr_flags |= XFS_ATTR_DMI; | 686 | attr_flags |= XFS_ATTR_DMI; |
693 | 687 | ||
694 | error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos, attr_flags); | 688 | error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags); |
695 | return -error; | 689 | return -error; |
696 | } | 690 | } |
697 | 691 | ||
@@ -1356,17 +1350,13 @@ xfs_ioctl( | |||
1356 | case XFS_IOC_ALLOCSP64: | 1350 | case XFS_IOC_ALLOCSP64: |
1357 | case XFS_IOC_FREESP64: | 1351 | case XFS_IOC_FREESP64: |
1358 | case XFS_IOC_RESVSP64: | 1352 | case XFS_IOC_RESVSP64: |
1359 | case XFS_IOC_UNRESVSP64: | 1353 | case XFS_IOC_UNRESVSP64: { |
1360 | /* | 1354 | xfs_flock64_t bf; |
1361 | * Only allow the sys admin to reserve space unless | ||
1362 | * unwritten extents are enabled. | ||
1363 | */ | ||
1364 | if (!xfs_sb_version_hasextflgbit(&mp->m_sb) && | ||
1365 | !capable(CAP_SYS_ADMIN)) | ||
1366 | return -EPERM; | ||
1367 | |||
1368 | return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg); | ||
1369 | 1355 | ||
1356 | if (copy_from_user(&bf, arg, sizeof(bf))) | ||
1357 | return -XFS_ERROR(EFAULT); | ||
1358 | return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf); | ||
1359 | } | ||
1370 | case XFS_IOC_DIOINFO: { | 1360 | case XFS_IOC_DIOINFO: { |
1371 | struct dioattr da; | 1361 | struct dioattr da; |
1372 | xfs_buftarg_t *target = | 1362 | xfs_buftarg_t *target = |
@@ -1426,18 +1416,30 @@ xfs_ioctl( | |||
1426 | 1416 | ||
1427 | case XFS_IOC_FD_TO_HANDLE: | 1417 | case XFS_IOC_FD_TO_HANDLE: |
1428 | case XFS_IOC_PATH_TO_HANDLE: | 1418 | case XFS_IOC_PATH_TO_HANDLE: |
1429 | case XFS_IOC_PATH_TO_FSHANDLE: | 1419 | case XFS_IOC_PATH_TO_FSHANDLE: { |
1430 | return xfs_find_handle(cmd, arg); | 1420 | xfs_fsop_handlereq_t hreq; |
1431 | 1421 | ||
1432 | case XFS_IOC_OPEN_BY_HANDLE: | 1422 | if (copy_from_user(&hreq, arg, sizeof(hreq))) |
1433 | return xfs_open_by_handle(mp, arg, filp, inode); | 1423 | return -XFS_ERROR(EFAULT); |
1424 | return xfs_find_handle(cmd, &hreq); | ||
1425 | } | ||
1426 | case XFS_IOC_OPEN_BY_HANDLE: { | ||
1427 | xfs_fsop_handlereq_t hreq; | ||
1434 | 1428 | ||
1429 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
1430 | return -XFS_ERROR(EFAULT); | ||
1431 | return xfs_open_by_handle(mp, &hreq, filp, inode); | ||
1432 | } | ||
1435 | case XFS_IOC_FSSETDM_BY_HANDLE: | 1433 | case XFS_IOC_FSSETDM_BY_HANDLE: |
1436 | return xfs_fssetdm_by_handle(mp, arg, inode); | 1434 | return xfs_fssetdm_by_handle(mp, arg, inode); |
1437 | 1435 | ||
1438 | case XFS_IOC_READLINK_BY_HANDLE: | 1436 | case XFS_IOC_READLINK_BY_HANDLE: { |
1439 | return xfs_readlink_by_handle(mp, arg, inode); | 1437 | xfs_fsop_handlereq_t hreq; |
1440 | 1438 | ||
1439 | if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t))) | ||
1440 | return -XFS_ERROR(EFAULT); | ||
1441 | return xfs_readlink_by_handle(mp, &hreq, inode); | ||
1442 | } | ||
1441 | case XFS_IOC_ATTRLIST_BY_HANDLE: | 1443 | case XFS_IOC_ATTRLIST_BY_HANDLE: |
1442 | return xfs_attrlist_by_handle(mp, arg, inode); | 1444 | return xfs_attrlist_by_handle(mp, arg, inode); |
1443 | 1445 | ||
@@ -1445,7 +1447,11 @@ xfs_ioctl( | |||
1445 | return xfs_attrmulti_by_handle(mp, arg, filp, inode); | 1447 | return xfs_attrmulti_by_handle(mp, arg, filp, inode); |
1446 | 1448 | ||
1447 | case XFS_IOC_SWAPEXT: { | 1449 | case XFS_IOC_SWAPEXT: { |
1448 | error = xfs_swapext((struct xfs_swapext __user *)arg); | 1450 | struct xfs_swapext sxp; |
1451 | |||
1452 | if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t))) | ||
1453 | return -XFS_ERROR(EFAULT); | ||
1454 | error = xfs_swapext(&sxp); | ||
1449 | return -error; | 1455 | return -error; |
1450 | } | 1456 | } |
1451 | 1457 | ||
@@ -1501,9 +1507,6 @@ xfs_ioctl( | |||
1501 | case XFS_IOC_FSGROWFSDATA: { | 1507 | case XFS_IOC_FSGROWFSDATA: { |
1502 | xfs_growfs_data_t in; | 1508 | xfs_growfs_data_t in; |
1503 | 1509 | ||
1504 | if (!capable(CAP_SYS_ADMIN)) | ||
1505 | return -EPERM; | ||
1506 | |||
1507 | if (copy_from_user(&in, arg, sizeof(in))) | 1510 | if (copy_from_user(&in, arg, sizeof(in))) |
1508 | return -XFS_ERROR(EFAULT); | 1511 | return -XFS_ERROR(EFAULT); |
1509 | 1512 | ||
@@ -1514,9 +1517,6 @@ xfs_ioctl( | |||
1514 | case XFS_IOC_FSGROWFSLOG: { | 1517 | case XFS_IOC_FSGROWFSLOG: { |
1515 | xfs_growfs_log_t in; | 1518 | xfs_growfs_log_t in; |
1516 | 1519 | ||
1517 | if (!capable(CAP_SYS_ADMIN)) | ||
1518 | return -EPERM; | ||
1519 | |||
1520 | if (copy_from_user(&in, arg, sizeof(in))) | 1520 | if (copy_from_user(&in, arg, sizeof(in))) |
1521 | return -XFS_ERROR(EFAULT); | 1521 | return -XFS_ERROR(EFAULT); |
1522 | 1522 | ||
@@ -1527,9 +1527,6 @@ xfs_ioctl( | |||
1527 | case XFS_IOC_FSGROWFSRT: { | 1527 | case XFS_IOC_FSGROWFSRT: { |
1528 | xfs_growfs_rt_t in; | 1528 | xfs_growfs_rt_t in; |
1529 | 1529 | ||
1530 | if (!capable(CAP_SYS_ADMIN)) | ||
1531 | return -EPERM; | ||
1532 | |||
1533 | if (copy_from_user(&in, arg, sizeof(in))) | 1530 | if (copy_from_user(&in, arg, sizeof(in))) |
1534 | return -XFS_ERROR(EFAULT); | 1531 | return -XFS_ERROR(EFAULT); |
1535 | 1532 | ||
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 75b0cd4da0ea..b4c1ee713492 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -49,9 +49,8 @@ | |||
49 | */ | 49 | */ |
50 | int | 50 | int |
51 | xfs_swapext( | 51 | xfs_swapext( |
52 | xfs_swapext_t __user *sxu) | 52 | xfs_swapext_t *sxp) |
53 | { | 53 | { |
54 | xfs_swapext_t *sxp; | ||
55 | xfs_inode_t *ip, *tip; | 54 | xfs_inode_t *ip, *tip; |
56 | struct file *file, *target_file; | 55 | struct file *file, *target_file; |
57 | int error = 0; | 56 | int error = 0; |
@@ -62,11 +61,6 @@ xfs_swapext( | |||
62 | goto out; | 61 | goto out; |
63 | } | 62 | } |
64 | 63 | ||
65 | if (copy_from_user(sxp, sxu, sizeof(xfs_swapext_t))) { | ||
66 | error = XFS_ERROR(EFAULT); | ||
67 | goto out_free_sxp; | ||
68 | } | ||
69 | |||
70 | /* Pull information for the target fd */ | 64 | /* Pull information for the target fd */ |
71 | file = fget((int)sxp->sx_fdtarget); | 65 | file = fget((int)sxp->sx_fdtarget); |
72 | if (!file) { | 66 | if (!file) { |
diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h index da178205be68..4f55a6306558 100644 --- a/fs/xfs/xfs_dfrag.h +++ b/fs/xfs/xfs_dfrag.h | |||
@@ -46,7 +46,7 @@ typedef struct xfs_swapext | |||
46 | /* | 46 | /* |
47 | * Syscall interface for xfs_swapext | 47 | * Syscall interface for xfs_swapext |
48 | */ | 48 | */ |
49 | int xfs_swapext(struct xfs_swapext __user *sx); | 49 | int xfs_swapext(struct xfs_swapext *sx); |
50 | 50 | ||
51 | int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, | 51 | int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip, |
52 | struct xfs_swapext *sxp); | 52 | struct xfs_swapext *sxp); |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index f1d0585041b9..852b6d32e8d0 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -435,6 +435,9 @@ xfs_growfs_data( | |||
435 | xfs_growfs_data_t *in) | 435 | xfs_growfs_data_t *in) |
436 | { | 436 | { |
437 | int error; | 437 | int error; |
438 | |||
439 | if (!capable(CAP_SYS_ADMIN)) | ||
440 | return XFS_ERROR(EPERM); | ||
438 | if (!mutex_trylock(&mp->m_growlock)) | 441 | if (!mutex_trylock(&mp->m_growlock)) |
439 | return XFS_ERROR(EWOULDBLOCK); | 442 | return XFS_ERROR(EWOULDBLOCK); |
440 | error = xfs_growfs_data_private(mp, in); | 443 | error = xfs_growfs_data_private(mp, in); |
@@ -448,6 +451,9 @@ xfs_growfs_log( | |||
448 | xfs_growfs_log_t *in) | 451 | xfs_growfs_log_t *in) |
449 | { | 452 | { |
450 | int error; | 453 | int error; |
454 | |||
455 | if (!capable(CAP_SYS_ADMIN)) | ||
456 | return XFS_ERROR(EPERM); | ||
451 | if (!mutex_trylock(&mp->m_growlock)) | 457 | if (!mutex_trylock(&mp->m_growlock)) |
452 | return XFS_ERROR(EWOULDBLOCK); | 458 | return XFS_ERROR(EWOULDBLOCK); |
453 | error = xfs_growfs_log_private(mp, in); | 459 | error = xfs_growfs_log_private(mp, in); |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index f18b9b281799..edf12c7b834c 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -1876,6 +1876,8 @@ xfs_growfs_rt( | |||
1876 | /* | 1876 | /* |
1877 | * Initial error checking. | 1877 | * Initial error checking. |
1878 | */ | 1878 | */ |
1879 | if (!capable(CAP_SYS_ADMIN)) | ||
1880 | return XFS_ERROR(EPERM); | ||
1879 | if (mp->m_rtdev_targp == NULL || mp->m_rbmip == NULL || | 1881 | if (mp->m_rtdev_targp == NULL || mp->m_rbmip == NULL || |
1880 | (nrblocks = in->newblocks) <= sbp->sb_rblocks || | 1882 | (nrblocks = in->newblocks) <= sbp->sb_rblocks || |
1881 | (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize))) | 1883 | (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize))) |