summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2012-09-26 08:57:12 +0000
committermm <mm@FreeBSD.org>2012-09-26 08:57:12 +0000
commitcef02e5cffeef7d1257d10c299971d3b92437921 (patch)
tree5f8047c117bf5b2461ad704f1f3abd1e71054a58
parenteaa983ae0b922fd671dc8e895a183a51454861bd (diff)
downloadFreeBSD-src-cef02e5cffeef7d1257d10c299971d3b92437921.zip
FreeBSD-src-cef02e5cffeef7d1257d10c299971d3b92437921.tar.gz
Update vendor/illumos/dist and vendor-sys/illumos/dist
to illumos-gate 13836:37bf491c434c (illumos ZFS issues #2678, #2811, #3139, #3189, #3208)
-rw-r--r--uts/common/fs/zfs/dmu_tx.c2
-rw-r--r--uts/common/fs/zfs/sys/sa_impl.h3
-rw-r--r--uts/common/fs/zfs/zfs_vfsops.c34
-rw-r--r--uts/common/fs/zfs/zfs_znode.c34
4 files changed, 58 insertions, 15 deletions
diff --git a/uts/common/fs/zfs/dmu_tx.c b/uts/common/fs/zfs/dmu_tx.c
index 4af7404..e44786f 100644
--- a/uts/common/fs/zfs/dmu_tx.c
+++ b/uts/common/fs/zfs/dmu_tx.c
@@ -572,7 +572,7 @@ dmu_tx_count_free(dmu_tx_hold_t *txh, uint64_t off, uint64_t len)
(dn->dn_indblkshift - SPA_BLKPTRSHIFT);
while (level++ < maxlevel) {
- txh->txh_memory_tohold += MIN(blkcnt, (nl1blks >> epbs))
+ txh->txh_memory_tohold += MAX(MIN(blkcnt, nl1blks), 1)
<< dn->dn_indblkshift;
blkcnt = 1 + (blkcnt >> epbs);
}
diff --git a/uts/common/fs/zfs/sys/sa_impl.h b/uts/common/fs/zfs/sys/sa_impl.h
index 6661e47..8ae05ce 100644
--- a/uts/common/fs/zfs/sys/sa_impl.h
+++ b/uts/common/fs/zfs/sys/sa_impl.h
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_SA_IMPL_H
@@ -181,7 +182,7 @@ typedef struct sa_hdr_phys {
*/
#define SA_HDR_LAYOUT_NUM(hdr) BF32_GET(hdr->sa_layout_info, 0, 10)
-#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 16, 3, 0)
+#define SA_HDR_SIZE(hdr) BF32_GET_SB(hdr->sa_layout_info, 10, 6, 3, 0)
#define SA_HDR_LAYOUT_INFO_ENCODE(x, num, size) \
{ \
BF32_SET_SB(x, 10, 6, 3, 0, size); \
diff --git a/uts/common/fs/zfs/zfs_vfsops.c b/uts/common/fs/zfs/zfs_vfsops.c
index 1552ff0..3278a77 100644
--- a/uts/common/fs/zfs/zfs_vfsops.c
+++ b/uts/common/fs/zfs/zfs_vfsops.c
@@ -49,6 +49,7 @@
#include <sys/spa.h>
#include <sys/zap.h>
#include <sys/sa.h>
+#include <sys/sa_impl.h>
#include <sys/varargs.h>
#include <sys/policy.h>
#include <sys/atomic.h>
@@ -63,7 +64,6 @@
#include <sys/dnlc.h>
#include <sys/dmu_objset.h>
#include <sys/spa_boot.h>
-#include <sys/sa.h>
#include "zfs_comutil.h"
int zfsfstype;
@@ -577,7 +577,6 @@ static int
zfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
uint64_t *userp, uint64_t *groupp)
{
- znode_phys_t *znp = data;
int error = 0;
/*
@@ -596,20 +595,18 @@ zfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
return (EEXIST);
if (bonustype == DMU_OT_ZNODE) {
+ znode_phys_t *znp = data;
*userp = znp->zp_uid;
*groupp = znp->zp_gid;
} else {
int hdrsize;
+ sa_hdr_phys_t *sap = data;
+ sa_hdr_phys_t sa = *sap;
+ boolean_t swap = B_FALSE;
ASSERT(bonustype == DMU_OT_SA);
- hdrsize = sa_hdrsize(data);
- if (hdrsize != 0) {
- *userp = *((uint64_t *)((uintptr_t)data + hdrsize +
- SA_UID_OFFSET));
- *groupp = *((uint64_t *)((uintptr_t)data + hdrsize +
- SA_GID_OFFSET));
- } else {
+ if (sa.sa_magic == 0) {
/*
* This should only happen for newly created
* files that haven't had the znode data filled
@@ -617,6 +614,25 @@ zfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
*/
*userp = 0;
*groupp = 0;
+ return (0);
+ }
+ if (sa.sa_magic == BSWAP_32(SA_MAGIC)) {
+ sa.sa_magic = SA_MAGIC;
+ sa.sa_layout_info = BSWAP_16(sa.sa_layout_info);
+ swap = B_TRUE;
+ } else {
+ VERIFY3U(sa.sa_magic, ==, SA_MAGIC);
+ }
+
+ hdrsize = sa_hdrsize(&sa);
+ VERIFY3U(hdrsize, >=, sizeof (sa_hdr_phys_t));
+ *userp = *((uint64_t *)((uintptr_t)data + hdrsize +
+ SA_UID_OFFSET));
+ *groupp = *((uint64_t *)((uintptr_t)data + hdrsize +
+ SA_GID_OFFSET));
+ if (swap) {
+ *userp = BSWAP_64(*userp);
+ *groupp = BSWAP_64(*groupp);
}
}
return (error);
diff --git a/uts/common/fs/zfs/zfs_znode.c b/uts/common/fs/zfs/zfs_znode.c
index 0c86cac..92dc05f 100644
--- a/uts/common/fs/zfs/zfs_znode.c
+++ b/uts/common/fs/zfs/zfs_znode.c
@@ -1947,13 +1947,16 @@ zfs_release_sa_handle(sa_handle_t *hdl, dmu_buf_t *db, void *tag)
* or not the object is an extended attribute directory.
*/
static int
-zfs_obj_to_pobj(sa_handle_t *hdl, sa_attr_type_t *sa_table, uint64_t *pobjp,
- int *is_xattrdir)
+zfs_obj_to_pobj(objset_t *osp, sa_handle_t *hdl, sa_attr_type_t *sa_table,
+ uint64_t *pobjp, int *is_xattrdir)
{
uint64_t parent;
uint64_t pflags;
uint64_t mode;
+ uint64_t parent_mode;
sa_bulk_attr_t bulk[3];
+ sa_handle_t *sa_hdl;
+ dmu_buf_t *sa_db;
int count = 0;
int error;
@@ -1967,9 +1970,32 @@ zfs_obj_to_pobj(sa_handle_t *hdl, sa_attr_type_t *sa_table, uint64_t *pobjp,
if ((error = sa_bulk_lookup(hdl, bulk, count)) != 0)
return (error);
- *pobjp = parent;
+ /*
+ * When a link is removed its parent pointer is not changed and will
+ * be invalid. There are two cases where a link is removed but the
+ * file stays around, when it goes to the delete queue and when there
+ * are additional links.
+ */
+ error = zfs_grab_sa_handle(osp, parent, &sa_hdl, &sa_db, FTAG);
+ if (error != 0)
+ return (error);
+
+ error = sa_lookup(sa_hdl, ZPL_MODE, &parent_mode, sizeof (parent_mode));
+ zfs_release_sa_handle(sa_hdl, sa_db, FTAG);
+ if (error != 0)
+ return (error);
+
*is_xattrdir = ((pflags & ZFS_XATTR) != 0) && S_ISDIR(mode);
+ /*
+ * Extended attributes can be applied to files, directories, etc.
+ * Otherwise the parent must be a directory.
+ */
+ if (!*is_xattrdir && !S_ISDIR(parent_mode))
+ return (EINVAL);
+
+ *pobjp = parent;
+
return (0);
}
@@ -2018,7 +2044,7 @@ zfs_obj_to_path_impl(objset_t *osp, uint64_t obj, sa_handle_t *hdl,
if (prevdb)
zfs_release_sa_handle(prevhdl, prevdb, FTAG);
- if ((error = zfs_obj_to_pobj(sa_hdl, sa_table, &pobj,
+ if ((error = zfs_obj_to_pobj(osp, sa_hdl, sa_table, &pobj,
&is_xattrdir)) != 0)
break;
OpenPOWER on IntegriCloud