aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c368
1 files changed, 312 insertions, 56 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index f34bd010eb51..c6399b2cf17c 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -1179,85 +1179,85 @@ xfs_ioc_fsgetxattr(
1179} 1179}
1180 1180
1181STATIC int 1181STATIC int
1182xfs_ioc_xattr( 1182xfs_ioc_fssetxattr(
1183 xfs_inode_t *ip, 1183 xfs_inode_t *ip,
1184 struct file *filp, 1184 struct file *filp,
1185 unsigned int cmd,
1186 void __user *arg) 1185 void __user *arg)
1187{ 1186{
1188 struct fsxattr fa; 1187 struct fsxattr fa;
1189 struct bhv_vattr *vattr; 1188 struct bhv_vattr *vattr;
1190 int error = 0; 1189 int error;
1191 int attr_flags; 1190 int attr_flags;
1192 unsigned int flags; 1191
1192 if (copy_from_user(&fa, arg, sizeof(fa)))
1193 return -EFAULT;
1193 1194
1194 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); 1195 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL);
1195 if (unlikely(!vattr)) 1196 if (unlikely(!vattr))
1196 return -ENOMEM; 1197 return -ENOMEM;
1197 1198
1198 switch (cmd) { 1199 attr_flags = 0;
1199 case XFS_IOC_FSSETXATTR: { 1200 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1200 if (copy_from_user(&fa, arg, sizeof(fa))) { 1201 attr_flags |= ATTR_NONBLOCK;
1201 error = -EFAULT;
1202 break;
1203 }
1204 1202
1205 attr_flags = 0; 1203 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
1206 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1204 vattr->va_xflags = fa.fsx_xflags;
1207 attr_flags |= ATTR_NONBLOCK; 1205 vattr->va_extsize = fa.fsx_extsize;
1206 vattr->va_projid = fa.fsx_projid;
1208 1207
1209 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID; 1208 error = -xfs_setattr(ip, vattr, attr_flags, NULL);
1210 vattr->va_xflags = fa.fsx_xflags; 1209 if (!error)
1211 vattr->va_extsize = fa.fsx_extsize; 1210 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1212 vattr->va_projid = fa.fsx_projid; 1211 kfree(vattr);
1212 return 0;
1213}
1213 1214
1214 error = xfs_setattr(ip, vattr, attr_flags, NULL); 1215STATIC int
1215 if (likely(!error)) 1216xfs_ioc_getxflags(
1216 vn_revalidate(XFS_ITOV(ip)); /* update flags */ 1217 xfs_inode_t *ip,
1217 error = -error; 1218 void __user *arg)
1218 break; 1219{
1219 } 1220 unsigned int flags;
1220 1221
1221 case XFS_IOC_GETXFLAGS: { 1222 flags = xfs_di2lxflags(ip->i_d.di_flags);
1222 flags = xfs_di2lxflags(ip->i_d.di_flags); 1223 if (copy_to_user(arg, &flags, sizeof(flags)))
1223 if (copy_to_user(arg, &flags, sizeof(flags))) 1224 return -EFAULT;
1224 error = -EFAULT; 1225 return 0;
1225 break; 1226}
1226 }
1227 1227
1228 case XFS_IOC_SETXFLAGS: { 1228STATIC int
1229 if (copy_from_user(&flags, arg, sizeof(flags))) { 1229xfs_ioc_setxflags(
1230 error = -EFAULT; 1230 xfs_inode_t *ip,
1231 break; 1231 struct file *filp,
1232 } 1232 void __user *arg)
1233{
1234 struct bhv_vattr *vattr;
1235 unsigned int flags;
1236 int attr_flags;
1237 int error;
1233 1238
1234 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ 1239 if (copy_from_user(&flags, arg, sizeof(flags)))
1235 FS_NOATIME_FL | FS_NODUMP_FL | \ 1240 return -EFAULT;
1236 FS_SYNC_FL)) {
1237 error = -EOPNOTSUPP;
1238 break;
1239 }
1240 1241
1241 attr_flags = 0; 1242 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
1242 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1243 FS_NOATIME_FL | FS_NODUMP_FL | \
1243 attr_flags |= ATTR_NONBLOCK; 1244 FS_SYNC_FL))
1245 return -EOPNOTSUPP;
1244 1246
1245 vattr->va_mask = XFS_AT_XFLAGS; 1247 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL);
1246 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 1248 if (unlikely(!vattr))
1247 xfs_ip2xflags(ip)); 1249 return -ENOMEM;
1248 1250
1249 error = xfs_setattr(ip, vattr, attr_flags, NULL); 1251 attr_flags = 0;
1250 if (likely(!error)) 1252 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1251 vn_revalidate(XFS_ITOV(ip)); /* update flags */ 1253 attr_flags |= ATTR_NONBLOCK;
1252 error = -error;
1253 break;
1254 }
1255 1254
1256 default: 1255 vattr->va_mask = XFS_AT_XFLAGS;
1257 error = -ENOTTY; 1256 vattr->va_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1258 break;
1259 }
1260 1257
1258 error = -xfs_setattr(ip, vattr, attr_flags, NULL);
1259 if (likely(!error))
1260 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1261 kfree(vattr); 1261 kfree(vattr);
1262 return error; 1262 return error;
1263} 1263}
@@ -1332,3 +1332,259 @@ xfs_ioc_getbmapx(
1332 1332
1333 return 0; 1333 return 0;
1334} 1334}
1335
1336int
1337xfs_ioctl(
1338 xfs_inode_t *ip,
1339 struct file *filp,
1340 int ioflags,
1341 unsigned int cmd,
1342 void __user *arg)
1343{
1344 struct inode *inode = filp->f_path.dentry->d_inode;
1345 xfs_mount_t *mp = ip->i_mount;
1346 int error;
1347
1348 xfs_itrace_entry(XFS_I(inode));
1349 switch (cmd) {
1350
1351 case XFS_IOC_ALLOCSP:
1352 case XFS_IOC_FREESP:
1353 case XFS_IOC_RESVSP:
1354 case XFS_IOC_UNRESVSP:
1355 case XFS_IOC_ALLOCSP64:
1356 case XFS_IOC_FREESP64:
1357 case XFS_IOC_RESVSP64:
1358 case XFS_IOC_UNRESVSP64:
1359 /*
1360 * Only allow the sys admin to reserve space unless
1361 * unwritten extents are enabled.
1362 */
1363 if (!xfs_sb_version_hasextflgbit(&mp->m_sb) &&
1364 !capable(CAP_SYS_ADMIN))
1365 return -EPERM;
1366
1367 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
1368
1369 case XFS_IOC_DIOINFO: {
1370 struct dioattr da;
1371 xfs_buftarg_t *target =
1372 XFS_IS_REALTIME_INODE(ip) ?
1373 mp->m_rtdev_targp : mp->m_ddev_targp;
1374
1375 da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
1376 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
1377
1378 if (copy_to_user(arg, &da, sizeof(da)))
1379 return -XFS_ERROR(EFAULT);
1380 return 0;
1381 }
1382
1383 case XFS_IOC_FSBULKSTAT_SINGLE:
1384 case XFS_IOC_FSBULKSTAT:
1385 case XFS_IOC_FSINUMBERS:
1386 return xfs_ioc_bulkstat(mp, cmd, arg);
1387
1388 case XFS_IOC_FSGEOMETRY_V1:
1389 return xfs_ioc_fsgeometry_v1(mp, arg);
1390
1391 case XFS_IOC_FSGEOMETRY:
1392 return xfs_ioc_fsgeometry(mp, arg);
1393
1394 case XFS_IOC_GETVERSION:
1395 return put_user(inode->i_generation, (int __user *)arg);
1396
1397 case XFS_IOC_FSGETXATTR:
1398 return xfs_ioc_fsgetxattr(ip, 0, arg);
1399 case XFS_IOC_FSGETXATTRA:
1400 return xfs_ioc_fsgetxattr(ip, 1, arg);
1401 case XFS_IOC_FSSETXATTR:
1402 return xfs_ioc_fssetxattr(ip, filp, arg);
1403 case XFS_IOC_GETXFLAGS:
1404 return xfs_ioc_getxflags(ip, arg);
1405 case XFS_IOC_SETXFLAGS:
1406 return xfs_ioc_setxflags(ip, filp, arg);
1407
1408 case XFS_IOC_FSSETDM: {
1409 struct fsdmidata dmi;
1410
1411 if (copy_from_user(&dmi, arg, sizeof(dmi)))
1412 return -XFS_ERROR(EFAULT);
1413
1414 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
1415 dmi.fsd_dmstate);
1416 return -error;
1417 }
1418
1419 case XFS_IOC_GETBMAP:
1420 case XFS_IOC_GETBMAPA:
1421 return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
1422
1423 case XFS_IOC_GETBMAPX:
1424 return xfs_ioc_getbmapx(ip, arg);
1425
1426 case XFS_IOC_FD_TO_HANDLE:
1427 case XFS_IOC_PATH_TO_HANDLE:
1428 case XFS_IOC_PATH_TO_FSHANDLE:
1429 return xfs_find_handle(cmd, arg);
1430
1431 case XFS_IOC_OPEN_BY_HANDLE:
1432 return xfs_open_by_handle(mp, arg, filp, inode);
1433
1434 case XFS_IOC_FSSETDM_BY_HANDLE:
1435 return xfs_fssetdm_by_handle(mp, arg, inode);
1436
1437 case XFS_IOC_READLINK_BY_HANDLE:
1438 return xfs_readlink_by_handle(mp, arg, inode);
1439
1440 case XFS_IOC_ATTRLIST_BY_HANDLE:
1441 return xfs_attrlist_by_handle(mp, arg, inode);
1442
1443 case XFS_IOC_ATTRMULTI_BY_HANDLE:
1444 return xfs_attrmulti_by_handle(mp, arg, inode);
1445
1446 case XFS_IOC_SWAPEXT: {
1447 error = xfs_swapext((struct xfs_swapext __user *)arg);
1448 return -error;
1449 }
1450
1451 case XFS_IOC_FSCOUNTS: {
1452 xfs_fsop_counts_t out;
1453
1454 error = xfs_fs_counts(mp, &out);
1455 if (error)
1456 return -error;
1457
1458 if (copy_to_user(arg, &out, sizeof(out)))
1459 return -XFS_ERROR(EFAULT);
1460 return 0;
1461 }
1462
1463 case XFS_IOC_SET_RESBLKS: {
1464 xfs_fsop_resblks_t inout;
1465 __uint64_t in;
1466
1467 if (!capable(CAP_SYS_ADMIN))
1468 return -EPERM;
1469
1470 if (copy_from_user(&inout, arg, sizeof(inout)))
1471 return -XFS_ERROR(EFAULT);
1472
1473 /* input parameter is passed in resblks field of structure */
1474 in = inout.resblks;
1475 error = xfs_reserve_blocks(mp, &in, &inout);
1476 if (error)
1477 return -error;
1478
1479 if (copy_to_user(arg, &inout, sizeof(inout)))
1480 return -XFS_ERROR(EFAULT);
1481 return 0;
1482 }
1483
1484 case XFS_IOC_GET_RESBLKS: {
1485 xfs_fsop_resblks_t out;
1486
1487 if (!capable(CAP_SYS_ADMIN))
1488 return -EPERM;
1489
1490 error = xfs_reserve_blocks(mp, NULL, &out);
1491 if (error)
1492 return -error;
1493
1494 if (copy_to_user(arg, &out, sizeof(out)))
1495 return -XFS_ERROR(EFAULT);
1496
1497 return 0;
1498 }
1499
1500 case XFS_IOC_FSGROWFSDATA: {
1501 xfs_growfs_data_t in;
1502
1503 if (!capable(CAP_SYS_ADMIN))
1504 return -EPERM;
1505
1506 if (copy_from_user(&in, arg, sizeof(in)))
1507 return -XFS_ERROR(EFAULT);
1508
1509 error = xfs_growfs_data(mp, &in);
1510 return -error;
1511 }
1512
1513 case XFS_IOC_FSGROWFSLOG: {
1514 xfs_growfs_log_t in;
1515
1516 if (!capable(CAP_SYS_ADMIN))
1517 return -EPERM;
1518
1519 if (copy_from_user(&in, arg, sizeof(in)))
1520 return -XFS_ERROR(EFAULT);
1521
1522 error = xfs_growfs_log(mp, &in);
1523 return -error;
1524 }
1525
1526 case XFS_IOC_FSGROWFSRT: {
1527 xfs_growfs_rt_t in;
1528
1529 if (!capable(CAP_SYS_ADMIN))
1530 return -EPERM;
1531
1532 if (copy_from_user(&in, arg, sizeof(in)))
1533 return -XFS_ERROR(EFAULT);
1534
1535 error = xfs_growfs_rt(mp, &in);
1536 return -error;
1537 }
1538
1539 case XFS_IOC_FREEZE:
1540 if (!capable(CAP_SYS_ADMIN))
1541 return -EPERM;
1542
1543 if (inode->i_sb->s_frozen == SB_UNFROZEN)
1544 freeze_bdev(inode->i_sb->s_bdev);
1545 return 0;
1546
1547 case XFS_IOC_THAW:
1548 if (!capable(CAP_SYS_ADMIN))
1549 return -EPERM;
1550 if (inode->i_sb->s_frozen != SB_UNFROZEN)
1551 thaw_bdev(inode->i_sb->s_bdev, inode->i_sb);
1552 return 0;
1553
1554 case XFS_IOC_GOINGDOWN: {
1555 __uint32_t in;
1556
1557 if (!capable(CAP_SYS_ADMIN))
1558 return -EPERM;
1559
1560 if (get_user(in, (__uint32_t __user *)arg))
1561 return -XFS_ERROR(EFAULT);
1562
1563 error = xfs_fs_goingdown(mp, in);
1564 return -error;
1565 }
1566
1567 case XFS_IOC_ERROR_INJECTION: {
1568 xfs_error_injection_t in;
1569
1570 if (!capable(CAP_SYS_ADMIN))
1571 return -EPERM;
1572
1573 if (copy_from_user(&in, arg, sizeof(in)))
1574 return -XFS_ERROR(EFAULT);
1575
1576 error = xfs_errortag_add(in.errtag, mp);
1577 return -error;
1578 }
1579
1580 case XFS_IOC_ERROR_CLEARALL:
1581 if (!capable(CAP_SYS_ADMIN))
1582 return -EPERM;
1583
1584 error = xfs_errortag_clearall(mp, 1);
1585 return -error;
1586
1587 default:
1588 return -ENOTTY;
1589 }
1590}