665 */ |
665 */ |
666 while (n > 0) { |
666 while (n > 0) { |
667 /* |
667 /* |
668 * Start a transaction. |
668 * Start a transaction. |
669 */ |
669 */ |
|
670 if (zfs_usergroup_overquota(zfsvfs, |
|
671 B_FALSE, zp->z_phys->zp_uid) || |
|
672 zfs_usergroup_overquota(zfsvfs, |
|
673 B_TRUE, zp->z_phys->zp_gid)) { |
|
674 error = EDQUOT; |
|
675 break; |
|
676 } |
670 woff = uio->uio_loffset; |
677 woff = uio->uio_loffset; |
671 tx = dmu_tx_create(zfsvfs->z_os); |
678 tx = dmu_tx_create(zfsvfs->z_os); |
672 dmu_tx_hold_bonus(tx, zp->z_id); |
679 dmu_tx_hold_bonus(tx, zp->z_id); |
673 dmu_tx_hold_write(tx, zp->z_id, woff, MIN(n, max_blksz)); |
680 dmu_tx_hold_write(tx, zp->z_id, woff, MIN(n, max_blksz)); |
674 error = dmu_tx_assign(tx, TXG_NOWAIT); |
681 error = dmu_tx_assign(tx, TXG_NOWAIT); |
1181 } |
1188 } |
1182 |
1189 |
1183 if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, vsecp, |
1190 if ((error = zfs_acl_ids_create(dzp, 0, vap, cr, vsecp, |
1184 &acl_ids)) != 0) |
1191 &acl_ids)) != 0) |
1185 goto out; |
1192 goto out; |
|
1193 if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { |
|
1194 error = EDQUOT; |
|
1195 goto out; |
|
1196 } |
1186 |
1197 |
1187 tx = dmu_tx_create(os); |
1198 tx = dmu_tx_create(os); |
1188 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
1199 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
1189 fuid_dirtied = zfsvfs->z_fuid_dirty; |
1200 fuid_dirtied = zfsvfs->z_fuid_dirty; |
1190 if (fuid_dirtied) { |
1201 if (fuid_dirtied) |
1191 if (zfsvfs->z_fuid_obj == 0) { |
1202 zfs_fuid_txhold(zfsvfs, tx); |
1192 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
|
1193 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, |
|
1194 FUID_SIZE_ESTIMATE(zfsvfs)); |
|
1195 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, |
|
1196 FALSE, NULL); |
|
1197 } else { |
|
1198 dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj); |
|
1199 dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0, |
|
1200 FUID_SIZE_ESTIMATE(zfsvfs)); |
|
1201 } |
|
1202 } |
|
1203 dmu_tx_hold_bonus(tx, dzp->z_id); |
1203 dmu_tx_hold_bonus(tx, dzp->z_id); |
1204 dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); |
1204 dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); |
1205 if (acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) { |
1205 if (acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) { |
1206 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, |
1206 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, |
1207 0, SPA_MAXBLOCKSIZE); |
1207 0, SPA_MAXBLOCKSIZE); |
1606 &acl_ids)) != 0) { |
1606 &acl_ids)) != 0) { |
1607 zfs_dirent_unlock(dl); |
1607 zfs_dirent_unlock(dl); |
1608 ZFS_EXIT(zfsvfs); |
1608 ZFS_EXIT(zfsvfs); |
1609 return (error); |
1609 return (error); |
1610 } |
1610 } |
|
1611 if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { |
|
1612 zfs_dirent_unlock(dl); |
|
1613 ZFS_EXIT(zfsvfs); |
|
1614 return (EDQUOT); |
|
1615 } |
1611 |
1616 |
1612 /* |
1617 /* |
1613 * Add a new entry to the directory. |
1618 * Add a new entry to the directory. |
1614 */ |
1619 */ |
1615 tx = dmu_tx_create(zfsvfs->z_os); |
1620 tx = dmu_tx_create(zfsvfs->z_os); |
1616 dmu_tx_hold_zap(tx, dzp->z_id, TRUE, dirname); |
1621 dmu_tx_hold_zap(tx, dzp->z_id, TRUE, dirname); |
1617 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); |
1622 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); |
1618 fuid_dirtied = zfsvfs->z_fuid_dirty; |
1623 fuid_dirtied = zfsvfs->z_fuid_dirty; |
1619 if (fuid_dirtied) { |
1624 if (fuid_dirtied) |
1620 if (zfsvfs->z_fuid_obj == 0) { |
1625 zfs_fuid_txhold(zfsvfs, tx); |
1621 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
|
1622 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, |
|
1623 FUID_SIZE_ESTIMATE(zfsvfs)); |
|
1624 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL); |
|
1625 } else { |
|
1626 dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj); |
|
1627 dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0, |
|
1628 FUID_SIZE_ESTIMATE(zfsvfs)); |
|
1629 } |
|
1630 } |
|
1631 if (acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) |
1626 if (acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) |
1632 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, |
1627 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, |
1633 0, SPA_MAXBLOCKSIZE); |
1628 0, SPA_MAXBLOCKSIZE); |
1634 error = dmu_tx_assign(tx, TXG_NOWAIT); |
1629 error = dmu_tx_assign(tx, TXG_NOWAIT); |
1635 if (error) { |
1630 if (error) { |
2621 if (mask & AT_MODE) { |
2616 if (mask & AT_MODE) { |
2622 uint64_t pmode = pzp->zp_mode; |
2617 uint64_t pmode = pzp->zp_mode; |
2623 |
2618 |
2624 new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT); |
2619 new_mode = (pmode & S_IFMT) | (vap->va_mode & ~S_IFMT); |
2625 |
2620 |
2626 if (err = zfs_acl_chmod_setattr(zp, &aclp, new_mode)) { |
2621 if (err = zfs_acl_chmod_setattr(zp, &aclp, new_mode)) |
2627 dmu_tx_abort(tx); |
2622 goto out; |
2628 ZFS_EXIT(zfsvfs); |
|
2629 return (err); |
|
2630 } |
|
2631 if (pzp->zp_acl.z_acl_extern_obj) { |
2623 if (pzp->zp_acl.z_acl_extern_obj) { |
2632 /* Are we upgrading ACL from old V0 format to new V1 */ |
2624 /* Are we upgrading ACL from old V0 format to new V1 */ |
2633 if (zfsvfs->z_version <= ZPL_VERSION_FUID && |
2625 if (zfsvfs->z_version <= ZPL_VERSION_FUID && |
2634 pzp->zp_acl.z_acl_version == |
2626 pzp->zp_acl.z_acl_version == |
2635 ZFS_ACL_VERSION_INITIAL) { |
2627 ZFS_ACL_VERSION_INITIAL) { |
2650 } |
2642 } |
2651 |
2643 |
2652 if (mask & (AT_UID | AT_GID)) { |
2644 if (mask & (AT_UID | AT_GID)) { |
2653 if (pzp->zp_xattr) { |
2645 if (pzp->zp_xattr) { |
2654 err = zfs_zget(zp->z_zfsvfs, pzp->zp_xattr, &attrzp); |
2646 err = zfs_zget(zp->z_zfsvfs, pzp->zp_xattr, &attrzp); |
2655 if (err) { |
2647 if (err) |
2656 dmu_tx_abort(tx); |
2648 goto out; |
2657 ZFS_EXIT(zfsvfs); |
|
2658 if (aclp) |
|
2659 zfs_acl_free(aclp); |
|
2660 return (err); |
|
2661 } |
|
2662 dmu_tx_hold_bonus(tx, attrzp->z_id); |
2649 dmu_tx_hold_bonus(tx, attrzp->z_id); |
2663 } |
2650 } |
2664 if (mask & AT_UID) { |
2651 if (mask & AT_UID) { |
2665 new_uid = zfs_fuid_create(zfsvfs, |
2652 new_uid = zfs_fuid_create(zfsvfs, |
2666 (uint64_t)vap->va_uid, cr, ZFS_OWNER, &fuidp); |
2653 (uint64_t)vap->va_uid, cr, ZFS_OWNER, &fuidp); |
2667 } |
2654 if (new_uid != pzp->zp_uid && |
|
2655 zfs_usergroup_overquota(zfsvfs, B_FALSE, new_uid)) { |
|
2656 err = EDQUOT; |
|
2657 goto out; |
|
2658 } |
|
2659 } |
|
2660 |
2668 if (mask & AT_GID) { |
2661 if (mask & AT_GID) { |
2669 new_gid = zfs_fuid_create(zfsvfs, (uint64_t)vap->va_gid, |
2662 new_gid = zfs_fuid_create(zfsvfs, (uint64_t)vap->va_gid, |
2670 cr, ZFS_GROUP, &fuidp); |
2663 cr, ZFS_GROUP, &fuidp); |
|
2664 if (new_gid != pzp->zp_gid && |
|
2665 zfs_usergroup_overquota(zfsvfs, B_TRUE, new_gid)) { |
|
2666 err = EDQUOT; |
|
2667 goto out; |
|
2668 } |
2671 } |
2669 } |
2672 fuid_dirtied = zfsvfs->z_fuid_dirty; |
2670 fuid_dirtied = zfsvfs->z_fuid_dirty; |
2673 if (fuid_dirtied) { |
2671 if (fuid_dirtied) { |
2674 if (zfsvfs->z_fuid_obj == 0) { |
2672 if (zfsvfs->z_fuid_obj == 0) { |
2675 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
2673 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
2808 zfs_fuid_sync(zfsvfs, tx); |
2790 zfs_fuid_sync(zfsvfs, tx); |
2809 |
2791 |
2810 if (mask != 0) |
2792 if (mask != 0) |
2811 zfs_log_setattr(zilog, tx, TX_SETATTR, zp, vap, mask, fuidp); |
2793 zfs_log_setattr(zilog, tx, TX_SETATTR, zp, vap, mask, fuidp); |
2812 |
2794 |
2813 if (fuidp) |
|
2814 zfs_fuid_info_free(fuidp); |
|
2815 mutex_exit(&zp->z_lock); |
2795 mutex_exit(&zp->z_lock); |
2816 |
2796 |
2817 dmu_tx_commit(tx); |
2797 out: |
2818 |
|
2819 if (attrzp) |
2798 if (attrzp) |
2820 VN_RELE(ZTOV(attrzp)); |
2799 VN_RELE(ZTOV(attrzp)); |
2821 |
2800 |
|
2801 if (aclp) { |
|
2802 zfs_acl_free(aclp); |
|
2803 aclp = NULL; |
|
2804 } |
|
2805 |
|
2806 if (fuidp) { |
|
2807 zfs_fuid_info_free(fuidp); |
|
2808 fuidp = NULL; |
|
2809 } |
|
2810 |
|
2811 if (err) |
|
2812 dmu_tx_abort(tx); |
|
2813 else |
|
2814 dmu_tx_commit(tx); |
|
2815 |
|
2816 if (err == ERESTART) |
|
2817 goto top; |
2822 |
2818 |
2823 ZFS_EXIT(zfsvfs); |
2819 ZFS_EXIT(zfsvfs); |
2824 return (err); |
2820 return (err); |
2825 } |
2821 } |
2826 |
2822 |
3284 ZFS_EXIT(zfsvfs); |
3280 ZFS_EXIT(zfsvfs); |
3285 return (error); |
3281 return (error); |
3286 } |
3282 } |
3287 |
3283 |
3288 VERIFY(0 == zfs_acl_ids_create(dzp, 0, vap, cr, NULL, &acl_ids)); |
3284 VERIFY(0 == zfs_acl_ids_create(dzp, 0, vap, cr, NULL, &acl_ids)); |
|
3285 if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { |
|
3286 zfs_acl_ids_free(&acl_ids); |
|
3287 zfs_dirent_unlock(dl); |
|
3288 ZFS_EXIT(zfsvfs); |
|
3289 return (EDQUOT); |
|
3290 } |
3289 tx = dmu_tx_create(zfsvfs->z_os); |
3291 tx = dmu_tx_create(zfsvfs->z_os); |
3290 fuid_dirtied = zfsvfs->z_fuid_dirty; |
3292 fuid_dirtied = zfsvfs->z_fuid_dirty; |
3291 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, MAX(1, len)); |
3293 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, MAX(1, len)); |
3292 dmu_tx_hold_bonus(tx, dzp->z_id); |
3294 dmu_tx_hold_bonus(tx, dzp->z_id); |
3293 dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); |
3295 dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); |
3294 if (acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) |
3296 if (acl_ids.z_aclp->z_acl_bytes > ZFS_ACE_SPACE) |
3295 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, SPA_MAXBLOCKSIZE); |
3297 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, SPA_MAXBLOCKSIZE); |
3296 if (fuid_dirtied) { |
3298 if (fuid_dirtied) |
3297 if (zfsvfs->z_fuid_obj == 0) { |
3299 zfs_fuid_txhold(zfsvfs, tx); |
3298 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
|
3299 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, |
|
3300 FUID_SIZE_ESTIMATE(zfsvfs)); |
|
3301 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL); |
|
3302 } else { |
|
3303 dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj); |
|
3304 dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0, |
|
3305 FUID_SIZE_ESTIMATE(zfsvfs)); |
|
3306 } |
|
3307 } |
|
3308 error = dmu_tx_assign(tx, TXG_NOWAIT); |
3300 error = dmu_tx_assign(tx, TXG_NOWAIT); |
3309 if (error) { |
3301 if (error) { |
3310 zfs_acl_ids_free(&acl_ids); |
3302 zfs_acl_ids_free(&acl_ids); |
3311 zfs_dirent_unlock(dl); |
3303 zfs_dirent_unlock(dl); |
3312 if (error == ERESTART) { |
3304 if (error == ERESTART) { |
3355 |
3347 |
3356 /* |
3348 /* |
3357 * Insert the new object into the directory. |
3349 * Insert the new object into the directory. |
3358 */ |
3350 */ |
3359 (void) zfs_link_create(dl, zp, tx, ZNEW); |
3351 (void) zfs_link_create(dl, zp, tx, ZNEW); |
3360 out: |
|
3361 if (error == 0) { |
3352 if (error == 0) { |
3362 uint64_t txtype = TX_SYMLINK; |
3353 uint64_t txtype = TX_SYMLINK; |
3363 if (flags & FIGNORECASE) |
3354 if (flags & FIGNORECASE) |
3364 txtype |= TX_CI; |
3355 txtype |= TX_CI; |
3365 zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link); |
3356 zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link); |
3639 page_list_break(&pp, &trunc, npages); |
3630 page_list_break(&pp, &trunc, npages); |
3640 /* ignore pages past end of file */ |
3631 /* ignore pages past end of file */ |
3641 if (trunc) |
3632 if (trunc) |
3642 pvn_write_done(trunc, flags); |
3633 pvn_write_done(trunc, flags); |
3643 len = filesz - off; |
3634 len = filesz - off; |
|
3635 } |
|
3636 |
|
3637 if (zfs_usergroup_overquota(zfsvfs, B_FALSE, zp->z_phys->zp_uid) || |
|
3638 zfs_usergroup_overquota(zfsvfs, B_TRUE, zp->z_phys->zp_gid)) { |
|
3639 err = EDQUOT; |
|
3640 goto out; |
3644 } |
3641 } |
3645 top: |
3642 top: |
3646 tx = dmu_tx_create(zfsvfs->z_os); |
3643 tx = dmu_tx_create(zfsvfs->z_os); |
3647 dmu_tx_hold_write(tx, zp->z_id, off, len); |
3644 dmu_tx_hold_write(tx, zp->z_id, off, len); |
3648 dmu_tx_hold_bonus(tx, zp->z_id); |
3645 dmu_tx_hold_bonus(tx, zp->z_id); |