Commit 365ca83d509f77f2095976edb8d10ca6e9d86d58
1 parent
c8ad20ffeb
Exists in
master
and in
7 other branches
[XFS] Add support for project quota inheritance, a merge of Glens changes.
SGI-PV: 932952 SGI-Modid: xfs-linux:xfs-kern:22806a Signed-off-by: Nathan Scott <nathans@sgi.com>
Showing 2 changed files with 37 additions and 24 deletions Side-by-side Diff
fs/xfs/xfs_inode.c
... | ... | @@ -1202,26 +1202,32 @@ |
1202 | 1202 | case S_IFREG: |
1203 | 1203 | case S_IFDIR: |
1204 | 1204 | if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { |
1205 | - if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { | |
1206 | - if ((mode & S_IFMT) == S_IFDIR) { | |
1207 | - ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT; | |
1208 | - } else { | |
1209 | - ip->i_d.di_flags |= XFS_DIFLAG_REALTIME; | |
1205 | + uint di_flags = 0; | |
1206 | + | |
1207 | + if ((mode & S_IFMT) == S_IFDIR) { | |
1208 | + if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) | |
1209 | + di_flags |= XFS_DIFLAG_RTINHERIT; | |
1210 | + } else { | |
1211 | + if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { | |
1212 | + di_flags |= XFS_DIFLAG_REALTIME; | |
1210 | 1213 | ip->i_iocore.io_flags |= XFS_IOCORE_RT; |
1211 | 1214 | } |
1212 | 1215 | } |
1213 | 1216 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && |
1214 | 1217 | xfs_inherit_noatime) |
1215 | - ip->i_d.di_flags |= XFS_DIFLAG_NOATIME; | |
1218 | + di_flags |= XFS_DIFLAG_NOATIME; | |
1216 | 1219 | if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) && |
1217 | 1220 | xfs_inherit_nodump) |
1218 | - ip->i_d.di_flags |= XFS_DIFLAG_NODUMP; | |
1221 | + di_flags |= XFS_DIFLAG_NODUMP; | |
1219 | 1222 | if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) && |
1220 | 1223 | xfs_inherit_sync) |
1221 | - ip->i_d.di_flags |= XFS_DIFLAG_SYNC; | |
1224 | + di_flags |= XFS_DIFLAG_SYNC; | |
1222 | 1225 | if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && |
1223 | 1226 | xfs_inherit_nosymlinks) |
1224 | - ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS; | |
1227 | + di_flags |= XFS_DIFLAG_NOSYMLINKS; | |
1228 | + if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | |
1229 | + di_flags |= XFS_DIFLAG_PROJINHERIT; | |
1230 | + ip->i_d.di_flags |= di_flags; | |
1225 | 1231 | } |
1226 | 1232 | /* FALLTHROUGH */ |
1227 | 1233 | case S_IFLNK: |
fs/xfs/xfs_vnodeops.c
... | ... | @@ -507,8 +507,6 @@ |
507 | 507 | * that the group ID supplied to the chown() function |
508 | 508 | * shall be equal to either the group ID or one of the |
509 | 509 | * supplementary group IDs of the calling process. |
510 | - * | |
511 | - * XXX: How does restricted_chown affect projid? | |
512 | 510 | */ |
513 | 511 | if (restricted_chown && |
514 | 512 | (iuid != uid || (igid != gid && |
... | ... | @@ -860,6 +858,8 @@ |
860 | 858 | di_flags |= XFS_DIFLAG_NOATIME; |
861 | 859 | if (vap->va_xflags & XFS_XFLAG_NODUMP) |
862 | 860 | di_flags |= XFS_DIFLAG_NODUMP; |
861 | + if (vap->va_xflags & XFS_XFLAG_PROJINHERIT) | |
862 | + di_flags |= XFS_DIFLAG_PROJINHERIT; | |
863 | 863 | if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { |
864 | 864 | if (vap->va_xflags & XFS_XFLAG_RTINHERIT) |
865 | 865 | di_flags |= XFS_DIFLAG_RTINHERIT; |
... | ... | @@ -1915,7 +1915,9 @@ |
1915 | 1915 | /* Return through std_return after this point. */ |
1916 | 1916 | |
1917 | 1917 | udqp = gdqp = NULL; |
1918 | - 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) | |
1919 | 1921 | prid = (xfs_prid_t)vap->va_projid; |
1920 | 1922 | else |
1921 | 1923 | prid = (xfs_prid_t)dfltprid; |
1922 | 1924 | |
... | ... | @@ -2621,17 +2623,7 @@ |
2621 | 2623 | if (src_vp->v_type == VDIR) |
2622 | 2624 | return XFS_ERROR(EPERM); |
2623 | 2625 | |
2624 | - /* | |
2625 | - * For now, manually find the XFS behavior descriptor for | |
2626 | - * the source vnode. If it doesn't exist then something | |
2627 | - * is wrong and we should just return an error. | |
2628 | - * Eventually we need to figure out how link is going to | |
2629 | - * work in the face of stacked vnodes. | |
2630 | - */ | |
2631 | 2626 | src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); |
2632 | - if (src_bdp == NULL) { | |
2633 | - return XFS_ERROR(EXDEV); | |
2634 | - } | |
2635 | 2627 | sip = XFS_BHVTOI(src_bdp); |
2636 | 2628 | tdp = XFS_BHVTOI(target_dir_bdp); |
2637 | 2629 | mp = tdp->i_mount; |
... | ... | @@ -2698,6 +2690,17 @@ |
2698 | 2690 | goto error_return; |
2699 | 2691 | } |
2700 | 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 | + | |
2701 | 2704 | if (resblks == 0 && |
2702 | 2705 | (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, |
2703 | 2706 | target_namelen))) |
... | ... | @@ -2820,7 +2823,9 @@ |
2820 | 2823 | |
2821 | 2824 | mp = dp->i_mount; |
2822 | 2825 | udqp = gdqp = NULL; |
2823 | - 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) | |
2824 | 2829 | prid = (xfs_prid_t)vap->va_projid; |
2825 | 2830 | else |
2826 | 2831 | prid = (xfs_prid_t)dfltprid; |
... | ... | @@ -3374,7 +3379,9 @@ |
3374 | 3379 | /* Return through std_return after this point. */ |
3375 | 3380 | |
3376 | 3381 | udqp = gdqp = NULL; |
3377 | - 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) | |
3378 | 3385 | prid = (xfs_prid_t)vap->va_projid; |
3379 | 3386 | else |
3380 | 3387 | prid = (xfs_prid_t)dfltprid; |