diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 114 |
1 files changed, 65 insertions, 49 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 19cf90a9c762..c4eca5ed5dab 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "xfs_ialloc.h" | 42 | #include "xfs_ialloc.h" |
43 | #include "xfs_alloc.h" | 43 | #include "xfs_alloc.h" |
44 | #include "xfs_bmap.h" | 44 | #include "xfs_bmap.h" |
45 | #include "xfs_acl.h" | ||
45 | #include "xfs_attr.h" | 46 | #include "xfs_attr.h" |
46 | #include "xfs_rw.h" | 47 | #include "xfs_rw.h" |
47 | #include "xfs_error.h" | 48 | #include "xfs_error.h" |
@@ -118,7 +119,7 @@ xfs_setattr( | |||
118 | */ | 119 | */ |
119 | ASSERT(udqp == NULL); | 120 | ASSERT(udqp == NULL); |
120 | ASSERT(gdqp == NULL); | 121 | ASSERT(gdqp == NULL); |
121 | code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, ip->i_d.di_projid, | 122 | code = xfs_qm_vop_dqalloc(ip, uid, gid, ip->i_d.di_projid, |
122 | qflags, &udqp, &gdqp); | 123 | qflags, &udqp, &gdqp); |
123 | if (code) | 124 | if (code) |
124 | return code; | 125 | return code; |
@@ -180,10 +181,11 @@ xfs_setattr( | |||
180 | * Do a quota reservation only if uid/gid is actually | 181 | * Do a quota reservation only if uid/gid is actually |
181 | * going to change. | 182 | * going to change. |
182 | */ | 183 | */ |
183 | if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || | 184 | if (XFS_IS_QUOTA_RUNNING(mp) && |
184 | (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { | 185 | ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || |
186 | (XFS_IS_GQUOTA_ON(mp) && igid != gid))) { | ||
185 | ASSERT(tp); | 187 | ASSERT(tp); |
186 | code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, | 188 | code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp, |
187 | capable(CAP_FOWNER) ? | 189 | capable(CAP_FOWNER) ? |
188 | XFS_QMOPT_FORCE_RES : 0); | 190 | XFS_QMOPT_FORCE_RES : 0); |
189 | if (code) /* out of quota */ | 191 | if (code) /* out of quota */ |
@@ -217,7 +219,7 @@ xfs_setattr( | |||
217 | /* | 219 | /* |
218 | * Make sure that the dquots are attached to the inode. | 220 | * Make sure that the dquots are attached to the inode. |
219 | */ | 221 | */ |
220 | code = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED); | 222 | code = xfs_qm_dqattach_locked(ip, 0); |
221 | if (code) | 223 | if (code) |
222 | goto error_return; | 224 | goto error_return; |
223 | 225 | ||
@@ -351,21 +353,21 @@ xfs_setattr( | |||
351 | * in the transaction. | 353 | * in the transaction. |
352 | */ | 354 | */ |
353 | if (iuid != uid) { | 355 | if (iuid != uid) { |
354 | if (XFS_IS_UQUOTA_ON(mp)) { | 356 | if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) { |
355 | ASSERT(mask & ATTR_UID); | 357 | ASSERT(mask & ATTR_UID); |
356 | ASSERT(udqp); | 358 | ASSERT(udqp); |
357 | olddquot1 = XFS_QM_DQVOPCHOWN(mp, tp, ip, | 359 | olddquot1 = xfs_qm_vop_chown(tp, ip, |
358 | &ip->i_udquot, udqp); | 360 | &ip->i_udquot, udqp); |
359 | } | 361 | } |
360 | ip->i_d.di_uid = uid; | 362 | ip->i_d.di_uid = uid; |
361 | inode->i_uid = uid; | 363 | inode->i_uid = uid; |
362 | } | 364 | } |
363 | if (igid != gid) { | 365 | if (igid != gid) { |
364 | if (XFS_IS_GQUOTA_ON(mp)) { | 366 | if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) { |
365 | ASSERT(!XFS_IS_PQUOTA_ON(mp)); | 367 | ASSERT(!XFS_IS_PQUOTA_ON(mp)); |
366 | ASSERT(mask & ATTR_GID); | 368 | ASSERT(mask & ATTR_GID); |
367 | ASSERT(gdqp); | 369 | ASSERT(gdqp); |
368 | olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, | 370 | olddquot2 = xfs_qm_vop_chown(tp, ip, |
369 | &ip->i_gdquot, gdqp); | 371 | &ip->i_gdquot, gdqp); |
370 | } | 372 | } |
371 | ip->i_d.di_gid = gid; | 373 | ip->i_d.di_gid = gid; |
@@ -461,13 +463,25 @@ xfs_setattr( | |||
461 | /* | 463 | /* |
462 | * Release any dquot(s) the inode had kept before chown. | 464 | * Release any dquot(s) the inode had kept before chown. |
463 | */ | 465 | */ |
464 | XFS_QM_DQRELE(mp, olddquot1); | 466 | xfs_qm_dqrele(olddquot1); |
465 | XFS_QM_DQRELE(mp, olddquot2); | 467 | xfs_qm_dqrele(olddquot2); |
466 | XFS_QM_DQRELE(mp, udqp); | 468 | xfs_qm_dqrele(udqp); |
467 | XFS_QM_DQRELE(mp, gdqp); | 469 | xfs_qm_dqrele(gdqp); |
468 | 470 | ||
469 | if (code) { | 471 | if (code) |
470 | return code; | 472 | return code; |
473 | |||
474 | /* | ||
475 | * XXX(hch): Updating the ACL entries is not atomic vs the i_mode | ||
476 | * update. We could avoid this with linked transactions | ||
477 | * and passing down the transaction pointer all the way | ||
478 | * to attr_set. No previous user of the generic | ||
479 | * Posix ACL code seems to care about this issue either. | ||
480 | */ | ||
481 | if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { | ||
482 | code = -xfs_acl_chmod(inode); | ||
483 | if (code) | ||
484 | return XFS_ERROR(code); | ||
471 | } | 485 | } |
472 | 486 | ||
473 | if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && | 487 | if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) && |
@@ -482,8 +496,8 @@ xfs_setattr( | |||
482 | commit_flags |= XFS_TRANS_ABORT; | 496 | commit_flags |= XFS_TRANS_ABORT; |
483 | /* FALLTHROUGH */ | 497 | /* FALLTHROUGH */ |
484 | error_return: | 498 | error_return: |
485 | XFS_QM_DQRELE(mp, udqp); | 499 | xfs_qm_dqrele(udqp); |
486 | XFS_QM_DQRELE(mp, gdqp); | 500 | xfs_qm_dqrele(gdqp); |
487 | if (tp) { | 501 | if (tp) { |
488 | xfs_trans_cancel(tp, commit_flags); | 502 | xfs_trans_cancel(tp, commit_flags); |
489 | } | 503 | } |
@@ -739,7 +753,8 @@ xfs_free_eofblocks( | |||
739 | /* | 753 | /* |
740 | * Attach the dquots to the inode up front. | 754 | * Attach the dquots to the inode up front. |
741 | */ | 755 | */ |
742 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 756 | error = xfs_qm_dqattach(ip, 0); |
757 | if (error) | ||
743 | return error; | 758 | return error; |
744 | 759 | ||
745 | /* | 760 | /* |
@@ -1181,7 +1196,8 @@ xfs_inactive( | |||
1181 | 1196 | ||
1182 | ASSERT(ip->i_d.di_nlink == 0); | 1197 | ASSERT(ip->i_d.di_nlink == 0); |
1183 | 1198 | ||
1184 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 1199 | error = xfs_qm_dqattach(ip, 0); |
1200 | if (error) | ||
1185 | return VN_INACTIVE_CACHE; | 1201 | return VN_INACTIVE_CACHE; |
1186 | 1202 | ||
1187 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | 1203 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); |
@@ -1307,7 +1323,7 @@ xfs_inactive( | |||
1307 | /* | 1323 | /* |
1308 | * Credit the quota account(s). The inode is gone. | 1324 | * Credit the quota account(s). The inode is gone. |
1309 | */ | 1325 | */ |
1310 | XFS_TRANS_MOD_DQUOT_BYINO(mp, tp, ip, XFS_TRANS_DQ_ICOUNT, -1); | 1326 | xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1); |
1311 | 1327 | ||
1312 | /* | 1328 | /* |
1313 | * Just ignore errors at this point. There is nothing we can | 1329 | * Just ignore errors at this point. There is nothing we can |
@@ -1323,11 +1339,11 @@ xfs_inactive( | |||
1323 | xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: " | 1339 | xfs_fs_cmn_err(CE_NOTE, mp, "xfs_inactive: " |
1324 | "xfs_trans_commit() returned error %d", error); | 1340 | "xfs_trans_commit() returned error %d", error); |
1325 | } | 1341 | } |
1342 | |||
1326 | /* | 1343 | /* |
1327 | * Release the dquots held by inode, if any. | 1344 | * Release the dquots held by inode, if any. |
1328 | */ | 1345 | */ |
1329 | XFS_QM_DQDETACH(mp, ip); | 1346 | xfs_qm_dqdetach(ip); |
1330 | |||
1331 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | 1347 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); |
1332 | 1348 | ||
1333 | out: | 1349 | out: |
@@ -1427,8 +1443,7 @@ xfs_create( | |||
1427 | /* | 1443 | /* |
1428 | * Make sure that we have allocated dquot(s) on disk. | 1444 | * Make sure that we have allocated dquot(s) on disk. |
1429 | */ | 1445 | */ |
1430 | error = XFS_QM_DQVOPALLOC(mp, dp, | 1446 | error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, |
1431 | current_fsuid(), current_fsgid(), prid, | ||
1432 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); | 1447 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); |
1433 | if (error) | 1448 | if (error) |
1434 | goto std_return; | 1449 | goto std_return; |
@@ -1489,7 +1504,7 @@ xfs_create( | |||
1489 | /* | 1504 | /* |
1490 | * Reserve disk quota and the inode. | 1505 | * Reserve disk quota and the inode. |
1491 | */ | 1506 | */ |
1492 | error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); | 1507 | error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, resblks, 1, 0); |
1493 | if (error) | 1508 | if (error) |
1494 | goto out_trans_cancel; | 1509 | goto out_trans_cancel; |
1495 | 1510 | ||
@@ -1561,7 +1576,7 @@ xfs_create( | |||
1561 | * These ids of the inode couldn't have changed since the new | 1576 | * These ids of the inode couldn't have changed since the new |
1562 | * inode has been locked ever since it was created. | 1577 | * inode has been locked ever since it was created. |
1563 | */ | 1578 | */ |
1564 | XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp); | 1579 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp); |
1565 | 1580 | ||
1566 | /* | 1581 | /* |
1567 | * xfs_trans_commit normally decrements the vnode ref count | 1582 | * xfs_trans_commit normally decrements the vnode ref count |
@@ -1580,8 +1595,8 @@ xfs_create( | |||
1580 | goto out_dqrele; | 1595 | goto out_dqrele; |
1581 | } | 1596 | } |
1582 | 1597 | ||
1583 | XFS_QM_DQRELE(mp, udqp); | 1598 | xfs_qm_dqrele(udqp); |
1584 | XFS_QM_DQRELE(mp, gdqp); | 1599 | xfs_qm_dqrele(gdqp); |
1585 | 1600 | ||
1586 | *ipp = ip; | 1601 | *ipp = ip; |
1587 | 1602 | ||
@@ -1602,8 +1617,8 @@ xfs_create( | |||
1602 | out_trans_cancel: | 1617 | out_trans_cancel: |
1603 | xfs_trans_cancel(tp, cancel_flags); | 1618 | xfs_trans_cancel(tp, cancel_flags); |
1604 | out_dqrele: | 1619 | out_dqrele: |
1605 | XFS_QM_DQRELE(mp, udqp); | 1620 | xfs_qm_dqrele(udqp); |
1606 | XFS_QM_DQRELE(mp, gdqp); | 1621 | xfs_qm_dqrele(gdqp); |
1607 | 1622 | ||
1608 | if (unlock_dp_on_error) | 1623 | if (unlock_dp_on_error) |
1609 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 1624 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
@@ -1837,11 +1852,11 @@ xfs_remove( | |||
1837 | return error; | 1852 | return error; |
1838 | } | 1853 | } |
1839 | 1854 | ||
1840 | error = XFS_QM_DQATTACH(mp, dp, 0); | 1855 | error = xfs_qm_dqattach(dp, 0); |
1841 | if (error) | 1856 | if (error) |
1842 | goto std_return; | 1857 | goto std_return; |
1843 | 1858 | ||
1844 | error = XFS_QM_DQATTACH(mp, ip, 0); | 1859 | error = xfs_qm_dqattach(ip, 0); |
1845 | if (error) | 1860 | if (error) |
1846 | goto std_return; | 1861 | goto std_return; |
1847 | 1862 | ||
@@ -2028,11 +2043,11 @@ xfs_link( | |||
2028 | 2043 | ||
2029 | /* Return through std_return after this point. */ | 2044 | /* Return through std_return after this point. */ |
2030 | 2045 | ||
2031 | error = XFS_QM_DQATTACH(mp, sip, 0); | 2046 | error = xfs_qm_dqattach(sip, 0); |
2032 | if (error) | 2047 | if (error) |
2033 | goto std_return; | 2048 | goto std_return; |
2034 | 2049 | ||
2035 | error = XFS_QM_DQATTACH(mp, tdp, 0); | 2050 | error = xfs_qm_dqattach(tdp, 0); |
2036 | if (error) | 2051 | if (error) |
2037 | goto std_return; | 2052 | goto std_return; |
2038 | 2053 | ||
@@ -2205,8 +2220,7 @@ xfs_symlink( | |||
2205 | /* | 2220 | /* |
2206 | * Make sure that we have allocated dquot(s) on disk. | 2221 | * Make sure that we have allocated dquot(s) on disk. |
2207 | */ | 2222 | */ |
2208 | error = XFS_QM_DQVOPALLOC(mp, dp, | 2223 | error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, |
2209 | current_fsuid(), current_fsgid(), prid, | ||
2210 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); | 2224 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); |
2211 | if (error) | 2225 | if (error) |
2212 | goto std_return; | 2226 | goto std_return; |
@@ -2248,7 +2262,7 @@ xfs_symlink( | |||
2248 | /* | 2262 | /* |
2249 | * Reserve disk quota : blocks and inode. | 2263 | * Reserve disk quota : blocks and inode. |
2250 | */ | 2264 | */ |
2251 | error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0); | 2265 | error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, resblks, 1, 0); |
2252 | if (error) | 2266 | if (error) |
2253 | goto error_return; | 2267 | goto error_return; |
2254 | 2268 | ||
@@ -2288,7 +2302,7 @@ xfs_symlink( | |||
2288 | /* | 2302 | /* |
2289 | * Also attach the dquot(s) to it, if applicable. | 2303 | * Also attach the dquot(s) to it, if applicable. |
2290 | */ | 2304 | */ |
2291 | XFS_QM_DQVOPCREATE(mp, tp, ip, udqp, gdqp); | 2305 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp); |
2292 | 2306 | ||
2293 | if (resblks) | 2307 | if (resblks) |
2294 | resblks -= XFS_IALLOC_SPACE_RES(mp); | 2308 | resblks -= XFS_IALLOC_SPACE_RES(mp); |
@@ -2376,8 +2390,8 @@ xfs_symlink( | |||
2376 | goto error2; | 2390 | goto error2; |
2377 | } | 2391 | } |
2378 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 2392 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
2379 | XFS_QM_DQRELE(mp, udqp); | 2393 | xfs_qm_dqrele(udqp); |
2380 | XFS_QM_DQRELE(mp, gdqp); | 2394 | xfs_qm_dqrele(gdqp); |
2381 | 2395 | ||
2382 | /* Fall through to std_return with error = 0 or errno from | 2396 | /* Fall through to std_return with error = 0 or errno from |
2383 | * xfs_trans_commit */ | 2397 | * xfs_trans_commit */ |
@@ -2401,8 +2415,8 @@ std_return: | |||
2401 | cancel_flags |= XFS_TRANS_ABORT; | 2415 | cancel_flags |= XFS_TRANS_ABORT; |
2402 | error_return: | 2416 | error_return: |
2403 | xfs_trans_cancel(tp, cancel_flags); | 2417 | xfs_trans_cancel(tp, cancel_flags); |
2404 | XFS_QM_DQRELE(mp, udqp); | 2418 | xfs_qm_dqrele(udqp); |
2405 | XFS_QM_DQRELE(mp, gdqp); | 2419 | xfs_qm_dqrele(gdqp); |
2406 | 2420 | ||
2407 | if (unlock_dp_on_error) | 2421 | if (unlock_dp_on_error) |
2408 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | 2422 | xfs_iunlock(dp, XFS_ILOCK_EXCL); |
@@ -2541,7 +2555,8 @@ xfs_alloc_file_space( | |||
2541 | if (XFS_FORCED_SHUTDOWN(mp)) | 2555 | if (XFS_FORCED_SHUTDOWN(mp)) |
2542 | return XFS_ERROR(EIO); | 2556 | return XFS_ERROR(EIO); |
2543 | 2557 | ||
2544 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 2558 | error = xfs_qm_dqattach(ip, 0); |
2559 | if (error) | ||
2545 | return error; | 2560 | return error; |
2546 | 2561 | ||
2547 | if (len <= 0) | 2562 | if (len <= 0) |
@@ -2628,8 +2643,8 @@ retry: | |||
2628 | break; | 2643 | break; |
2629 | } | 2644 | } |
2630 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 2645 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
2631 | error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, | 2646 | error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks, |
2632 | qblocks, 0, quota_flag); | 2647 | 0, quota_flag); |
2633 | if (error) | 2648 | if (error) |
2634 | goto error1; | 2649 | goto error1; |
2635 | 2650 | ||
@@ -2688,7 +2703,7 @@ dmapi_enospc_check: | |||
2688 | 2703 | ||
2689 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ | 2704 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ |
2690 | xfs_bmap_cancel(&free_list); | 2705 | xfs_bmap_cancel(&free_list); |
2691 | XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag); | 2706 | xfs_trans_unreserve_quota_nblks(tp, ip, qblocks, 0, quota_flag); |
2692 | 2707 | ||
2693 | error1: /* Just cancel transaction */ | 2708 | error1: /* Just cancel transaction */ |
2694 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | 2709 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); |
@@ -2827,7 +2842,8 @@ xfs_free_file_space( | |||
2827 | 2842 | ||
2828 | xfs_itrace_entry(ip); | 2843 | xfs_itrace_entry(ip); |
2829 | 2844 | ||
2830 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 2845 | error = xfs_qm_dqattach(ip, 0); |
2846 | if (error) | ||
2831 | return error; | 2847 | return error; |
2832 | 2848 | ||
2833 | error = 0; | 2849 | error = 0; |
@@ -2953,9 +2969,9 @@ xfs_free_file_space( | |||
2953 | break; | 2969 | break; |
2954 | } | 2970 | } |
2955 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 2971 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
2956 | error = XFS_TRANS_RESERVE_QUOTA(mp, tp, | 2972 | error = xfs_trans_reserve_quota(tp, mp, |
2957 | ip->i_udquot, ip->i_gdquot, resblks, 0, | 2973 | ip->i_udquot, ip->i_gdquot, |
2958 | XFS_QMOPT_RES_REGBLKS); | 2974 | resblks, 0, XFS_QMOPT_RES_REGBLKS); |
2959 | if (error) | 2975 | if (error) |
2960 | goto error1; | 2976 | goto error1; |
2961 | 2977 | ||