aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 22:51:18 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 22:51:18 -0400
commit2a5a68b840cbab31baab2d9b2e1e6de3b289ae1e (patch)
tree25b8fc041b4dce6c404ff01b462bc6b58fa7d372 /fs/xfs/xfs_vnodeops.c
parent990a8baf568ca1d0ae65e59783ff821794118d07 (diff)
parente1a40fa907498030b6e432c0dbcb06d7a9f14ee3 (diff)
Merge rsync://oss.sgi.com/git/xfs-2.6
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c95
1 files changed, 64 insertions, 31 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 25a526629b12..1377c868f3f4 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -351,21 +351,28 @@ xfs_setattr(
351 * If the IDs do change before we take the ilock, we're covered 351 * If the IDs do change before we take the ilock, we're covered
352 * because the i_*dquot fields will get updated anyway. 352 * because the i_*dquot fields will get updated anyway.
353 */ 353 */
354 if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { 354 if (XFS_IS_QUOTA_ON(mp) &&
355 (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
355 uint qflags = 0; 356 uint qflags = 0;
356 357
357 if (mask & XFS_AT_UID) { 358 if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
358 uid = vap->va_uid; 359 uid = vap->va_uid;
359 qflags |= XFS_QMOPT_UQUOTA; 360 qflags |= XFS_QMOPT_UQUOTA;
360 } else { 361 } else {
361 uid = ip->i_d.di_uid; 362 uid = ip->i_d.di_uid;
362 } 363 }
363 if (mask & XFS_AT_GID) { 364 if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) {
364 gid = vap->va_gid; 365 gid = vap->va_gid;
365 qflags |= XFS_QMOPT_GQUOTA; 366 qflags |= XFS_QMOPT_GQUOTA;
366 } else { 367 } else {
367 gid = ip->i_d.di_gid; 368 gid = ip->i_d.di_gid;
368 } 369 }
370 if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) {
371 projid = vap->va_projid;
372 qflags |= XFS_QMOPT_PQUOTA;
373 } else {
374 projid = ip->i_d.di_projid;
375 }
369 /* 376 /*
370 * We take a reference when we initialize udqp and gdqp, 377 * We take a reference when we initialize udqp and gdqp,
371 * so it is important that we never blindly double trip on 378 * so it is important that we never blindly double trip on
@@ -373,7 +380,8 @@ xfs_setattr(
373 */ 380 */
374 ASSERT(udqp == NULL); 381 ASSERT(udqp == NULL);
375 ASSERT(gdqp == NULL); 382 ASSERT(gdqp == NULL);
376 code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp); 383 code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags,
384 &udqp, &gdqp);
377 if (code) 385 if (code)
378 return (code); 386 return (code);
379 } 387 }
@@ -499,8 +507,6 @@ xfs_setattr(
499 * that the group ID supplied to the chown() function 507 * that the group ID supplied to the chown() function
500 * shall be equal to either the group ID or one of the 508 * shall be equal to either the group ID or one of the
501 * supplementary group IDs of the calling process. 509 * supplementary group IDs of the calling process.
502 *
503 * XXX: How does restricted_chown affect projid?
504 */ 510 */
505 if (restricted_chown && 511 if (restricted_chown &&
506 (iuid != uid || (igid != gid && 512 (iuid != uid || (igid != gid &&
@@ -510,10 +516,11 @@ xfs_setattr(
510 goto error_return; 516 goto error_return;
511 } 517 }
512 /* 518 /*
513 * Do a quota reservation only if uid or gid is actually 519 * Do a quota reservation only if uid/projid/gid is actually
514 * going to change. 520 * going to change.
515 */ 521 */
516 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || 522 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
523 (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
517 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { 524 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
518 ASSERT(tp); 525 ASSERT(tp);
519 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, 526 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
@@ -774,6 +781,7 @@ xfs_setattr(
774 } 781 }
775 if (igid != gid) { 782 if (igid != gid) {
776 if (XFS_IS_GQUOTA_ON(mp)) { 783 if (XFS_IS_GQUOTA_ON(mp)) {
784 ASSERT(!XFS_IS_PQUOTA_ON(mp));
777 ASSERT(mask & XFS_AT_GID); 785 ASSERT(mask & XFS_AT_GID);
778 ASSERT(gdqp); 786 ASSERT(gdqp);
779 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, 787 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
@@ -782,6 +790,13 @@ xfs_setattr(
782 ip->i_d.di_gid = gid; 790 ip->i_d.di_gid = gid;
783 } 791 }
784 if (iprojid != projid) { 792 if (iprojid != projid) {
793 if (XFS_IS_PQUOTA_ON(mp)) {
794 ASSERT(!XFS_IS_GQUOTA_ON(mp));
795 ASSERT(mask & XFS_AT_PROJID);
796 ASSERT(gdqp);
797 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
798 &ip->i_gdquot, gdqp);
799 }
785 ip->i_d.di_projid = projid; 800 ip->i_d.di_projid = projid;
786 /* 801 /*
787 * We may have to rev the inode as well as 802 * We may have to rev the inode as well as
@@ -843,6 +858,8 @@ xfs_setattr(
843 di_flags |= XFS_DIFLAG_NOATIME; 858 di_flags |= XFS_DIFLAG_NOATIME;
844 if (vap->va_xflags & XFS_XFLAG_NODUMP) 859 if (vap->va_xflags & XFS_XFLAG_NODUMP)
845 di_flags |= XFS_DIFLAG_NODUMP; 860 di_flags |= XFS_DIFLAG_NODUMP;
861 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
862 di_flags |= XFS_DIFLAG_PROJINHERIT;
846 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 863 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
847 if (vap->va_xflags & XFS_XFLAG_RTINHERIT) 864 if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
848 di_flags |= XFS_DIFLAG_RTINHERIT; 865 di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -1898,7 +1915,9 @@ xfs_create(
1898 /* Return through std_return after this point. */ 1915 /* Return through std_return after this point. */
1899 1916
1900 udqp = gdqp = NULL; 1917 udqp = gdqp = NULL;
1901 if (vap->va_mask & XFS_AT_PROJID) 1918 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1919 prid = dp->i_d.di_projid;
1920 else if (vap->va_mask & XFS_AT_PROJID)
1902 prid = (xfs_prid_t)vap->va_projid; 1921 prid = (xfs_prid_t)vap->va_projid;
1903 else 1922 else
1904 prid = (xfs_prid_t)dfltprid; 1923 prid = (xfs_prid_t)dfltprid;
@@ -1907,7 +1926,7 @@ xfs_create(
1907 * Make sure that we have allocated dquot(s) on disk. 1926 * Make sure that we have allocated dquot(s) on disk.
1908 */ 1927 */
1909 error = XFS_QM_DQVOPALLOC(mp, dp, 1928 error = XFS_QM_DQVOPALLOC(mp, dp,
1910 current_fsuid(credp), current_fsgid(credp), 1929 current_fsuid(credp), current_fsgid(credp), prid,
1911 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); 1930 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
1912 if (error) 1931 if (error)
1913 goto std_return; 1932 goto std_return;
@@ -2604,17 +2623,7 @@ xfs_link(
2604 if (src_vp->v_type == VDIR) 2623 if (src_vp->v_type == VDIR)
2605 return XFS_ERROR(EPERM); 2624 return XFS_ERROR(EPERM);
2606 2625
2607 /*
2608 * For now, manually find the XFS behavior descriptor for
2609 * the source vnode. If it doesn't exist then something
2610 * is wrong and we should just return an error.
2611 * Eventually we need to figure out how link is going to
2612 * work in the face of stacked vnodes.
2613 */
2614 src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); 2626 src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops);
2615 if (src_bdp == NULL) {
2616 return XFS_ERROR(EXDEV);
2617 }
2618 sip = XFS_BHVTOI(src_bdp); 2627 sip = XFS_BHVTOI(src_bdp);
2619 tdp = XFS_BHVTOI(target_dir_bdp); 2628 tdp = XFS_BHVTOI(target_dir_bdp);
2620 mp = tdp->i_mount; 2629 mp = tdp->i_mount;
@@ -2681,6 +2690,17 @@ xfs_link(
2681 goto error_return; 2690 goto error_return;
2682 } 2691 }
2683 2692
2693 /*
2694 * If we are using project inheritance, we only allow hard link
2695 * creation in our tree when the project IDs are the same; else
2696 * the tree quota mechanism could be circumvented.
2697 */
2698 if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
2699 (tdp->i_d.di_projid != sip->i_d.di_projid))) {
2700 error = XFS_ERROR(EPERM);
2701 goto error_return;
2702 }
2703
2684 if (resblks == 0 && 2704 if (resblks == 0 &&
2685 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, 2705 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name,
2686 target_namelen))) 2706 target_namelen)))
@@ -2803,7 +2823,9 @@ xfs_mkdir(
2803 2823
2804 mp = dp->i_mount; 2824 mp = dp->i_mount;
2805 udqp = gdqp = NULL; 2825 udqp = gdqp = NULL;
2806 if (vap->va_mask & XFS_AT_PROJID) 2826 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
2827 prid = dp->i_d.di_projid;
2828 else if (vap->va_mask & XFS_AT_PROJID)
2807 prid = (xfs_prid_t)vap->va_projid; 2829 prid = (xfs_prid_t)vap->va_projid;
2808 else 2830 else
2809 prid = (xfs_prid_t)dfltprid; 2831 prid = (xfs_prid_t)dfltprid;
@@ -2812,7 +2834,7 @@ xfs_mkdir(
2812 * Make sure that we have allocated dquot(s) on disk. 2834 * Make sure that we have allocated dquot(s) on disk.
2813 */ 2835 */
2814 error = XFS_QM_DQVOPALLOC(mp, dp, 2836 error = XFS_QM_DQVOPALLOC(mp, dp,
2815 current_fsuid(credp), current_fsgid(credp), 2837 current_fsuid(credp), current_fsgid(credp), prid,
2816 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 2838 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
2817 if (error) 2839 if (error)
2818 goto std_return; 2840 goto std_return;
@@ -3357,7 +3379,9 @@ xfs_symlink(
3357 /* Return through std_return after this point. */ 3379 /* Return through std_return after this point. */
3358 3380
3359 udqp = gdqp = NULL; 3381 udqp = gdqp = NULL;
3360 if (vap->va_mask & XFS_AT_PROJID) 3382 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
3383 prid = dp->i_d.di_projid;
3384 else if (vap->va_mask & XFS_AT_PROJID)
3361 prid = (xfs_prid_t)vap->va_projid; 3385 prid = (xfs_prid_t)vap->va_projid;
3362 else 3386 else
3363 prid = (xfs_prid_t)dfltprid; 3387 prid = (xfs_prid_t)dfltprid;
@@ -3366,7 +3390,7 @@ xfs_symlink(
3366 * Make sure that we have allocated dquot(s) on disk. 3390 * Make sure that we have allocated dquot(s) on disk.
3367 */ 3391 */
3368 error = XFS_QM_DQVOPALLOC(mp, dp, 3392 error = XFS_QM_DQVOPALLOC(mp, dp,
3369 current_fsuid(credp), current_fsgid(credp), 3393 current_fsuid(credp), current_fsgid(credp), prid,
3370 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 3394 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
3371 if (error) 3395 if (error)
3372 goto std_return; 3396 goto std_return;
@@ -4028,7 +4052,7 @@ xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
4028 * errno on error 4052 * errno on error
4029 * 4053 *
4030 */ 4054 */
4031int 4055STATIC int
4032xfs_alloc_file_space( 4056xfs_alloc_file_space(
4033 xfs_inode_t *ip, 4057 xfs_inode_t *ip,
4034 xfs_off_t offset, 4058 xfs_off_t offset,
@@ -4151,9 +4175,8 @@ retry:
4151 break; 4175 break;
4152 } 4176 }
4153 xfs_ilock(ip, XFS_ILOCK_EXCL); 4177 xfs_ilock(ip, XFS_ILOCK_EXCL);
4154 error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, 4178 error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
4155 ip->i_udquot, ip->i_gdquot, resblks, 0, rt ? 4179 ip->i_udquot, ip->i_gdquot, resblks, 0, 0);
4156 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
4157 if (error) 4180 if (error)
4158 goto error1; 4181 goto error1;
4159 4182
@@ -4305,6 +4328,7 @@ xfs_free_file_space(
4305 xfs_off_t len, 4328 xfs_off_t len,
4306 int attr_flags) 4329 int attr_flags)
4307{ 4330{
4331 vnode_t *vp;
4308 int committed; 4332 int committed;
4309 int done; 4333 int done;
4310 xfs_off_t end_dmi_offset; 4334 xfs_off_t end_dmi_offset;
@@ -4325,9 +4349,11 @@ xfs_free_file_space(
4325 xfs_trans_t *tp; 4349 xfs_trans_t *tp;
4326 int need_iolock = 1; 4350 int need_iolock = 1;
4327 4351
4328 vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); 4352 vp = XFS_ITOV(ip);
4329 mp = ip->i_mount; 4353 mp = ip->i_mount;
4330 4354
4355 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
4356
4331 if ((error = XFS_QM_DQATTACH(mp, ip, 0))) 4357 if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
4332 return error; 4358 return error;
4333 4359
@@ -4344,7 +4370,7 @@ xfs_free_file_space(
4344 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 4370 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4345 if (end_dmi_offset > ip->i_d.di_size) 4371 if (end_dmi_offset > ip->i_d.di_size)
4346 end_dmi_offset = ip->i_d.di_size; 4372 end_dmi_offset = ip->i_d.di_size;
4347 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), 4373 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
4348 offset, end_dmi_offset - offset, 4374 offset, end_dmi_offset - offset,
4349 AT_DELAY_FLAG(attr_flags), NULL); 4375 AT_DELAY_FLAG(attr_flags), NULL);
4350 if (error) 4376 if (error)
@@ -4363,7 +4389,14 @@ xfs_free_file_space(
4363 ioffset = offset & ~(rounding - 1); 4389 ioffset = offset & ~(rounding - 1);
4364 if (ilen & (rounding - 1)) 4390 if (ilen & (rounding - 1))
4365 ilen = (ilen + rounding) & ~(rounding - 1); 4391 ilen = (ilen + rounding) & ~(rounding - 1);
4366 xfs_inval_cached_pages(XFS_ITOV(ip), &(ip->i_iocore), ioffset, 0, 0); 4392
4393 if (VN_CACHED(vp) != 0) {
4394 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4395 ctooff(offtoct(ioffset)), -1);
4396 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)),
4397 -1, FI_REMAPF_LOCKED);
4398 }
4399
4367 /* 4400 /*
4368 * Need to zero the stuff we're not freeing, on disk. 4401 * Need to zero the stuff we're not freeing, on disk.
4369 * If its a realtime file & can't use unwritten extents then we 4402 * If its a realtime file & can't use unwritten extents then we