aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ioctl.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-12 10:20:39 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-31 01:45:48 -0400
commitd9457dc056249913a7abe8b71dc09e427e590e35 (patch)
tree8f0c6681d4c5802a6f5a124111b9d3958f0b281b /fs/xfs/xfs_ioctl.c
parent8e8ad8a57c75f3bda2d03a4c4396a9a7024ad275 (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.c55
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
1177STATIC int 1194STATIC 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
1216STATIC int 1239STATIC 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