diff options
author | Jan Kara <jack@suse.cz> | 2012-06-12 10:20:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-31 01:45:48 -0400 |
commit | d9457dc056249913a7abe8b71dc09e427e590e35 (patch) | |
tree | 8f0c6681d4c5802a6f5a124111b9d3958f0b281b /fs/xfs/xfs_ioctl.c | |
parent | 8e8ad8a57c75f3bda2d03a4c4396a9a7024ad275 (diff) |
xfs: Convert to new freezing code
Generic code now blocks all writers from standard write paths. So we add
blocking of all writers coming from ioctl (we get a protection of ioctl against
racing remount read-only as a bonus) and convert xfs_file_aio_write() to a
non-racy freeze protection. We also keep freeze protection on transaction
start to block internal filesystem writes such as removal of preallocated
blocks.
CC: Ben Myers <bpm@sgi.com>
CC: Alex Elder <elder@kernel.org>
CC: xfs@oss.sgi.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/xfs/xfs_ioctl.c')
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 1f1535d25a9b..0e0232c3b6d9 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -364,9 +364,15 @@ xfs_fssetdm_by_handle( | |||
364 | if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) | 364 | if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t))) |
365 | return -XFS_ERROR(EFAULT); | 365 | return -XFS_ERROR(EFAULT); |
366 | 366 | ||
367 | error = mnt_want_write_file(parfilp); | ||
368 | if (error) | ||
369 | return error; | ||
370 | |||
367 | dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq); | 371 | dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq); |
368 | if (IS_ERR(dentry)) | 372 | if (IS_ERR(dentry)) { |
373 | mnt_drop_write_file(parfilp); | ||
369 | return PTR_ERR(dentry); | 374 | return PTR_ERR(dentry); |
375 | } | ||
370 | 376 | ||
371 | if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) { | 377 | if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) { |
372 | error = -XFS_ERROR(EPERM); | 378 | error = -XFS_ERROR(EPERM); |
@@ -382,6 +388,7 @@ xfs_fssetdm_by_handle( | |||
382 | fsd.fsd_dmstate); | 388 | fsd.fsd_dmstate); |
383 | 389 | ||
384 | out: | 390 | out: |
391 | mnt_drop_write_file(parfilp); | ||
385 | dput(dentry); | 392 | dput(dentry); |
386 | return error; | 393 | return error; |
387 | } | 394 | } |
@@ -634,7 +641,11 @@ xfs_ioc_space( | |||
634 | if (ioflags & IO_INVIS) | 641 | if (ioflags & IO_INVIS) |
635 | attr_flags |= XFS_ATTR_DMI; | 642 | attr_flags |= XFS_ATTR_DMI; |
636 | 643 | ||
644 | error = mnt_want_write_file(filp); | ||
645 | if (error) | ||
646 | return error; | ||
637 | error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags); | 647 | error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags); |
648 | mnt_drop_write_file(filp); | ||
638 | return -error; | 649 | return -error; |
639 | } | 650 | } |
640 | 651 | ||
@@ -1163,6 +1174,7 @@ xfs_ioc_fssetxattr( | |||
1163 | { | 1174 | { |
1164 | struct fsxattr fa; | 1175 | struct fsxattr fa; |
1165 | unsigned int mask; | 1176 | unsigned int mask; |
1177 | int error; | ||
1166 | 1178 | ||
1167 | if (copy_from_user(&fa, arg, sizeof(fa))) | 1179 | if (copy_from_user(&fa, arg, sizeof(fa))) |
1168 | return -EFAULT; | 1180 | return -EFAULT; |
@@ -1171,7 +1183,12 @@ xfs_ioc_fssetxattr( | |||
1171 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) | 1183 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
1172 | mask |= FSX_NONBLOCK; | 1184 | mask |= FSX_NONBLOCK; |
1173 | 1185 | ||
1174 | return -xfs_ioctl_setattr(ip, &fa, mask); | 1186 | error = mnt_want_write_file(filp); |
1187 | if (error) | ||
1188 | return error; | ||
1189 | error = xfs_ioctl_setattr(ip, &fa, mask); | ||
1190 | mnt_drop_write_file(filp); | ||
1191 | return -error; | ||
1175 | } | 1192 | } |
1176 | 1193 | ||
1177 | STATIC int | 1194 | STATIC int |
@@ -1196,6 +1213,7 @@ xfs_ioc_setxflags( | |||
1196 | struct fsxattr fa; | 1213 | struct fsxattr fa; |
1197 | unsigned int flags; | 1214 | unsigned int flags; |
1198 | unsigned int mask; | 1215 | unsigned int mask; |
1216 | int error; | ||
1199 | 1217 | ||
1200 | if (copy_from_user(&flags, arg, sizeof(flags))) | 1218 | if (copy_from_user(&flags, arg, sizeof(flags))) |
1201 | return -EFAULT; | 1219 | return -EFAULT; |
@@ -1210,7 +1228,12 @@ xfs_ioc_setxflags( | |||
1210 | mask |= FSX_NONBLOCK; | 1228 | mask |= FSX_NONBLOCK; |
1211 | fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip)); | 1229 | fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip)); |
1212 | 1230 | ||
1213 | return -xfs_ioctl_setattr(ip, &fa, mask); | 1231 | error = mnt_want_write_file(filp); |
1232 | if (error) | ||
1233 | return error; | ||
1234 | error = xfs_ioctl_setattr(ip, &fa, mask); | ||
1235 | mnt_drop_write_file(filp); | ||
1236 | return -error; | ||
1214 | } | 1237 | } |
1215 | 1238 | ||
1216 | STATIC int | 1239 | STATIC int |
@@ -1385,8 +1408,13 @@ xfs_file_ioctl( | |||
1385 | if (copy_from_user(&dmi, arg, sizeof(dmi))) | 1408 | if (copy_from_user(&dmi, arg, sizeof(dmi))) |
1386 | return -XFS_ERROR(EFAULT); | 1409 | return -XFS_ERROR(EFAULT); |
1387 | 1410 | ||
1411 | error = mnt_want_write_file(filp); | ||
1412 | if (error) | ||
1413 | return error; | ||
1414 | |||
1388 | error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask, | 1415 | error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask, |
1389 | dmi.fsd_dmstate); | 1416 | dmi.fsd_dmstate); |
1417 | mnt_drop_write_file(filp); | ||
1390 | return -error; | 1418 | return -error; |
1391 | } | 1419 | } |
1392 | 1420 | ||
@@ -1434,7 +1462,11 @@ xfs_file_ioctl( | |||
1434 | 1462 | ||
1435 | if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t))) | 1463 | if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t))) |
1436 | return -XFS_ERROR(EFAULT); | 1464 | return -XFS_ERROR(EFAULT); |
1465 | error = mnt_want_write_file(filp); | ||
1466 | if (error) | ||
1467 | return error; | ||
1437 | error = xfs_swapext(&sxp); | 1468 | error = xfs_swapext(&sxp); |
1469 | mnt_drop_write_file(filp); | ||
1438 | return -error; | 1470 | return -error; |
1439 | } | 1471 | } |
1440 | 1472 | ||
@@ -1463,9 +1495,14 @@ xfs_file_ioctl( | |||
1463 | if (copy_from_user(&inout, arg, sizeof(inout))) | 1495 | if (copy_from_user(&inout, arg, sizeof(inout))) |
1464 | return -XFS_ERROR(EFAULT); | 1496 | return -XFS_ERROR(EFAULT); |
1465 | 1497 | ||
1498 | error = mnt_want_write_file(filp); | ||
1499 | if (error) | ||
1500 | return error; | ||
1501 | |||
1466 | /* input parameter is passed in resblks field of structure */ | 1502 | /* input parameter is passed in resblks field of structure */ |
1467 | in = inout.resblks; | 1503 | in = inout.resblks; |
1468 | error = xfs_reserve_blocks(mp, &in, &inout); | 1504 | error = xfs_reserve_blocks(mp, &in, &inout); |
1505 | mnt_drop_write_file(filp); | ||
1469 | if (error) | 1506 | if (error) |
1470 | return -error; | 1507 | return -error; |
1471 | 1508 | ||
@@ -1496,7 +1533,11 @@ xfs_file_ioctl( | |||
1496 | if (copy_from_user(&in, arg, sizeof(in))) | 1533 | if (copy_from_user(&in, arg, sizeof(in))) |
1497 | return -XFS_ERROR(EFAULT); | 1534 | return -XFS_ERROR(EFAULT); |
1498 | 1535 | ||
1536 | error = mnt_want_write_file(filp); | ||
1537 | if (error) | ||
1538 | return error; | ||
1499 | error = xfs_growfs_data(mp, &in); | 1539 | error = xfs_growfs_data(mp, &in); |
1540 | mnt_drop_write_file(filp); | ||
1500 | return -error; | 1541 | return -error; |
1501 | } | 1542 | } |
1502 | 1543 | ||
@@ -1506,7 +1547,11 @@ xfs_file_ioctl( | |||
1506 | if (copy_from_user(&in, arg, sizeof(in))) | 1547 | if (copy_from_user(&in, arg, sizeof(in))) |
1507 | return -XFS_ERROR(EFAULT); | 1548 | return -XFS_ERROR(EFAULT); |
1508 | 1549 | ||
1550 | error = mnt_want_write_file(filp); | ||
1551 | if (error) | ||
1552 | return error; | ||
1509 | error = xfs_growfs_log(mp, &in); | 1553 | error = xfs_growfs_log(mp, &in); |
1554 | mnt_drop_write_file(filp); | ||
1510 | return -error; | 1555 | return -error; |
1511 | } | 1556 | } |
1512 | 1557 | ||
@@ -1516,7 +1561,11 @@ xfs_file_ioctl( | |||
1516 | if (copy_from_user(&in, arg, sizeof(in))) | 1561 | if (copy_from_user(&in, arg, sizeof(in))) |
1517 | return -XFS_ERROR(EFAULT); | 1562 | return -XFS_ERROR(EFAULT); |
1518 | 1563 | ||
1564 | error = mnt_want_write_file(filp); | ||
1565 | if (error) | ||
1566 | return error; | ||
1519 | error = xfs_growfs_rt(mp, &in); | 1567 | error = xfs_growfs_rt(mp, &in); |
1568 | mnt_drop_write_file(filp); | ||
1520 | return -error; | 1569 | return -error; |
1521 | } | 1570 | } |
1522 | 1571 | ||