aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c114
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
2689error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ 2704error0: /* 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
2693error1: /* Just cancel transaction */ 2708error1: /* 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