svn commit: r207477 -
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Pawel Jakub Dawidek
pjd at FreeBSD.org
Sat May 1 19:00:33 UTC 2010
Author: pjd
Date: Sat May 1 19:00:33 2010
New Revision: 207477
URL: http://svn.freebsd.org/changeset/base/207477
Log:
MFC r207068,r207334:
r207068:
Allow to modify directory's content even if the ZFS_NOUNLINK (SF_NOUNLINK,
sunlnk) flag is set. We only deny dirctory's removal or rename.
PR: kern/143343
Reported by: marck
r207334:
Backport fix for 'zfs_znode_dmu_init: existing znode for dbuf' panic from OpenSolaris.
PR: kern/144402
Reported by: Alex Bakhtin <alex.bakhtin at gmail.com>
Tested by: Alex Bakhtin <alex.bakhtin at gmail.com>
Obtained from: OpenSolaris, Bug ID 6895088
Modified:
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
stable/8/sys/geom/sched/ (props changed)
Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c Sat May 1 18:56:45 2010 (r207476)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c Sat May 1 19:00:33 2010 (r207477)
@@ -2235,11 +2235,24 @@ zfs_zaccess_common(znode_t *zp, uint32_t
return (EPERM);
}
+#ifdef sun
if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) &&
(zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
*check_privs = B_FALSE;
return (EPERM);
}
+#else
+ /*
+ * In FreeBSD we allow to modify directory's content is ZFS_NOUNLINK
+ * (sunlnk) is set. We just don't allow directory removal, which is
+ * handled in zfs_zaccess_delete().
+ */
+ if ((v4_mode & ACE_DELETE) &&
+ (zp->z_phys->zp_flags & ZFS_NOUNLINK)) {
+ *check_privs = B_FALSE;
+ return (EPERM);
+ }
+#endif
if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) &&
(zp->z_phys->zp_flags & ZFS_AV_QUARANTINED))) {
Modified: stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
==============================================================================
--- stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Sat May 1 18:56:45 2010 (r207476)
+++ stable/8/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c Sat May 1 19:00:33 2010 (r207477)
@@ -704,6 +704,8 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, d
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx);
}
}
+
+ ZFS_OBJ_HOLD_ENTER(zfsvfs, obj);
VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, obj, NULL, &db));
dmu_buf_will_dirty(db, tx);
@@ -765,9 +767,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, d
pzp->zp_mode = MAKEIMODE(vap->va_type, vap->va_mode);
if (!(flag & IS_ROOT_NODE)) {
- ZFS_OBJ_HOLD_ENTER(zfsvfs, obj);
*zpp = zfs_znode_alloc(zfsvfs, db, 0);
- ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
} else {
/*
* If we are creating the root node, the "parent" we
@@ -776,6 +776,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, d
*zpp = dzp;
}
zfs_perm_init(*zpp, dzp, flag, vap, tx, cr, setaclp, fuidp);
+ ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
if (!(flag & IS_ROOT_NODE)) {
vnode_t *vp;
@@ -939,19 +940,31 @@ again:
/*
* Not found create new znode/vnode
+ * but only if file exists.
+ *
+ * There is a small window where zfs_vget() could
+ * find this object while a file create is still in
+ * progress. Since a gen number can never be zero
+ * we will check that to determine if its an allocated
+ * file.
*/
- zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size);
-
- vp = ZTOV(zp);
- vp->v_vflag |= VV_FORCEINSMQ;
- err = insmntque(vp, zfsvfs->z_vfs);
- vp->v_vflag &= ~VV_FORCEINSMQ;
- KASSERT(err == 0, ("insmntque() failed: error %d", err));
- VOP_UNLOCK(vp, 0);
+ if (((znode_phys_t *)db->db_data)->zp_gen != 0) {
+ zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size);
+ *zpp = zp;
+ vp = ZTOV(zp);
+ vp->v_vflag |= VV_FORCEINSMQ;
+ err = insmntque(vp, zfsvfs->z_vfs);
+ vp->v_vflag &= ~VV_FORCEINSMQ;
+ KASSERT(err == 0, ("insmntque() failed: error %d", err));
+ VOP_UNLOCK(vp, 0);
+ err = 0;
+ } else {
+ dmu_buf_rele(db, NULL);
+ err = ENOENT;
+ }
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num);
- *zpp = zp;
- return (0);
+ return (err);
}
int
@@ -1440,6 +1453,7 @@ zfs_create_fs(objset_t *os, cred_t *cr,
uint64_t norm = 0;
nvpair_t *elem;
int error;
+ int i;
znode_t *rootzp = NULL;
vnode_t vnode;
vattr_t vattr;
@@ -1537,6 +1551,9 @@ zfs_create_fs(objset_t *os, cred_t *cr,
list_create(&zfsvfs.z_all_znodes, sizeof (znode_t),
offsetof(znode_t, z_link_node));
+ for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
+ mutex_init(&zfsvfs.z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
+
ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs));
rootzp->z_zfsvfs = &zfsvfs;
zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, 0, NULL, NULL);
@@ -1547,6 +1564,8 @@ zfs_create_fs(objset_t *os, cred_t *cr,
dmu_buf_rele(rootzp->z_dbuf, NULL);
rootzp->z_dbuf = NULL;
+ for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
+ mutex_destroy(&zfsvfs.z_hold_mtx[i]);
mutex_destroy(&zfsvfs.z_znodes_lock);
rootzp->z_vnode = NULL;
kmem_cache_free(znode_cache, rootzp);
More information about the svn-src-stable
mailing list