usr/src/uts/common/fs/zfs/zfs_vnops.c
changeset 9396 f41cf682d0d3
parent 9321 dca349c475c1
child 9412 4aefd8704ce0
equal deleted inserted replaced
9395:2db090840cf7 9396:f41cf682d0d3
   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);
  2685 		}
  2683 		}
  2686 	}
  2684 	}
  2687 
  2685 
  2688 	err = dmu_tx_assign(tx, TXG_NOWAIT);
  2686 	err = dmu_tx_assign(tx, TXG_NOWAIT);
  2689 	if (err) {
  2687 	if (err) {
  2690 		if (attrzp)
  2688 		if (err == ERESTART)
  2691 			VN_RELE(ZTOV(attrzp));
       
  2692 
       
  2693 		if (aclp) {
       
  2694 			zfs_acl_free(aclp);
       
  2695 			aclp = NULL;
       
  2696 		}
       
  2697 
       
  2698 		if (err == ERESTART) {
       
  2699 			dmu_tx_wait(tx);
  2689 			dmu_tx_wait(tx);
  2700 			dmu_tx_abort(tx);
  2690 		goto out;
  2701 			goto top;
       
  2702 		}
       
  2703 		dmu_tx_abort(tx);
       
  2704 		ZFS_EXIT(zfsvfs);
       
  2705 		return (err);
       
  2706 	}
  2691 	}
  2707 
  2692 
  2708 	dmu_buf_will_dirty(zp->z_dbuf, tx);
  2693 	dmu_buf_will_dirty(zp->z_dbuf, tx);
  2709 
  2694 
  2710 	/*
  2695 	/*
  2738 		pzp->zp_gid = new_gid;
  2723 		pzp->zp_gid = new_gid;
  2739 		if (attrzp)
  2724 		if (attrzp)
  2740 			attrzp->z_phys->zp_gid = new_gid;
  2725 			attrzp->z_phys->zp_gid = new_gid;
  2741 	}
  2726 	}
  2742 
  2727 
  2743 	if (aclp)
       
  2744 		zfs_acl_free(aclp);
       
  2745 
       
  2746 	if (attrzp)
  2728 	if (attrzp)
  2747 		mutex_exit(&attrzp->z_lock);
  2729 		mutex_exit(&attrzp->z_lock);
  2748 
  2730 
  2749 	if (mask & AT_ATIME)
  2731 	if (mask & AT_ATIME)
  2750 		ZFS_TIME_ENCODE(&vap->va_atime, pzp->zp_atime);
  2732 		ZFS_TIME_ENCODE(&vap->va_atime, pzp->zp_atime);
  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);