PSARC/2007/121 zfs set copies
6459491 want 'zfs set copies=' to use ditto blocks for user data
--- a/usr/src/common/zfs/zfs_prop.c Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/common/zfs/zfs_prop.c Fri Mar 16 00:42:33 2007 -0700
@@ -176,6 +176,9 @@
"on | off", "XATTR", B_TRUE, B_TRUE },
{ "numclones", prop_type_number, 0, NULL, prop_readonly,
ZFS_TYPE_SNAPSHOT, NULL, NULL, B_FALSE, B_FALSE },
+ { "copies", prop_type_index, 1, "1", prop_inherit,
+ ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+ "1 | 2 | 3", "COPIES", B_TRUE, B_TRUE },
};
#define ZFS_PROP_COUNT ((sizeof (zfs_prop_table))/(sizeof (prop_desc_t)))
@@ -361,6 +364,13 @@
{ NULL }
};
+static zfs_index_t copies_table[] = {
+ { "1", 1 },
+ { "2", 2 },
+ { "3", 3 },
+ { NULL }
+};
+
static zfs_index_t *
zfs_prop_index_table(zfs_prop_t prop)
{
@@ -375,6 +385,8 @@
return (acl_mode_table);
case ZFS_PROP_ACLINHERIT:
return (acl_inherit_table);
+ case ZFS_PROP_COPIES:
+ return (copies_table);
default:
return (NULL);
}
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c Fri Mar 16 00:42:33 2007 -0700
@@ -1537,6 +1537,7 @@
case ZFS_PROP_SNAPDIR:
case ZFS_PROP_ACLMODE:
case ZFS_PROP_ACLINHERIT:
+ case ZFS_PROP_COPIES:
val = getprop_uint64(zhp, prop, &source);
verify(zfs_prop_index_to_string(prop, val, &strval) == 0);
(void) strlcpy(propbuf, strval, proplen);
--- a/usr/src/uts/common/fs/zfs/dbuf.c Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/dbuf.c Fri Mar 16 00:42:33 2007 -0700
@@ -2094,7 +2094,7 @@
os->os_dsl_dataset, db->db_blkptr, zio, tx);
dr->dr_zio = arc_write(zio, os->os_spa, checksum, compress,
- dmu_get_replication_level(os->os_spa, &zb, dn->dn_type), txg,
+ dmu_get_replication_level(os, &zb, dn->dn_type), txg,
db->db_blkptr, data, dbuf_write_ready, dbuf_write_done, db,
ZIO_PRIORITY_ASYNC_WRITE, zio_flags, &zb);
}
--- a/usr/src/uts/common/fs/zfs/dmu.c Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/dmu.c Fri Mar 16 00:42:33 2007 -0700
@@ -797,7 +797,7 @@
zio = arc_write(pio, os->os_spa,
zio_checksum_select(db->db_dnode->dn_checksum, os->os_checksum),
zio_compress_select(db->db_dnode->dn_compress, os->os_compress),
- dmu_get_replication_level(os->os_spa, &zb, db->db_dnode->dn_type),
+ dmu_get_replication_level(os, &zb, db->db_dnode->dn_type),
txg, bp, dr->dt.dl.dr_data, NULL, dmu_sync_done, in,
ZIO_PRIORITY_SYNC_WRITE, zio_flags, &zb);
@@ -854,22 +854,19 @@
dnode_rele(dn, FTAG);
}
-/*
- * XXX - eventually, this should take into account per-dataset (or
- * even per-object?) user requests for higher levels of replication.
- */
int
-dmu_get_replication_level(spa_t *spa, zbookmark_t *zb, dmu_object_type_t ot)
+dmu_get_replication_level(objset_impl_t *os,
+ zbookmark_t *zb, dmu_object_type_t ot)
{
- int ncopies = 1;
+ int ncopies = os->os_copies;
- if (dmu_ot[ot].ot_metadata)
+ /* If it's the mos, it should have max copies set. */
+ ASSERT(zb->zb_objset != 0 ||
+ ncopies == spa_max_replication(os->os_spa));
+
+ if (dmu_ot[ot].ot_metadata || zb->zb_level != 0)
ncopies++;
- if (zb->zb_level != 0)
- ncopies++;
- if (zb->zb_objset == 0 && zb->zb_object == 0)
- ncopies++;
- return (MIN(ncopies, spa_max_replication(spa)));
+ return (MIN(ncopies, spa_max_replication(os->os_spa)));
}
int
--- a/usr/src/uts/common/fs/zfs/dmu_objset.c Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/dmu_objset.c Fri Mar 16 00:42:33 2007 -0700
@@ -117,6 +117,20 @@
osi->os_compress = zio_compress_select(newval, ZIO_COMPRESS_ON_VALUE);
}
+static void
+copies_changed_cb(void *arg, uint64_t newval)
+{
+ objset_impl_t *osi = arg;
+
+ /*
+ * Inheritance and range checking should have been done by now.
+ */
+ ASSERT(newval > 0);
+ ASSERT(newval <= spa_max_replication(osi->os_spa));
+
+ osi->os_copies = newval;
+}
+
void
dmu_objset_byteswap(void *buf, size_t size)
{
@@ -178,6 +192,9 @@
if (err == 0)
err = dsl_prop_register(ds, "compression",
compression_changed_cb, osi);
+ if (err == 0)
+ err = dsl_prop_register(ds, "copies",
+ copies_changed_cb, osi);
if (err) {
VERIFY(arc_buf_remove_ref(osi->os_phys_buf,
&osi->os_phys_buf) == 1);
@@ -188,6 +205,7 @@
/* It's the meta-objset. */
osi->os_checksum = ZIO_CHECKSUM_FLETCHER_4;
osi->os_compress = ZIO_COMPRESS_LZJB;
+ osi->os_copies = spa_max_replication(spa);
}
osi->os_zil = zil_alloc(&osi->os, &osi->os_phys->os_zil_header);
@@ -348,6 +366,8 @@
checksum_changed_cb, osi));
VERIFY(0 == dsl_prop_unregister(ds, "compression",
compression_changed_cb, osi));
+ VERIFY(0 == dsl_prop_unregister(ds, "copies",
+ copies_changed_cb, osi));
}
/*
@@ -767,7 +787,7 @@
os->os_rootbp, pio, tx);
zio = arc_write(pio, os->os_spa, os->os_md_checksum,
os->os_md_compress,
- dmu_get_replication_level(os->os_spa, &zb, DMU_OT_OBJSET),
+ dmu_get_replication_level(os, &zb, DMU_OT_OBJSET),
tx->tx_txg, os->os_rootbp, os->os_phys_buf, ready, killer, os,
ZIO_PRIORITY_ASYNC_WRITE, zio_flags, &zb);
--- a/usr/src/uts/common/fs/zfs/sys/dmu.h Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/sys/dmu.h Fri Mar 16 00:42:33 2007 -0700
@@ -60,6 +60,7 @@
struct zbookmark;
struct spa;
struct nvlist;
+struct objset_impl;
typedef struct objset objset_t;
typedef struct dmu_tx dmu_tx_t;
@@ -280,7 +281,7 @@
* Decide how many copies of a given block we should make. Can be from
* 1 to SPA_DVAS_PER_BP.
*/
-int dmu_get_replication_level(struct spa *spa, struct zbookmark *zb,
+int dmu_get_replication_level(struct objset_impl *, struct zbookmark *zb,
dmu_object_type_t ot);
/*
* The bonus data is accessed more or less like a regular buffer.
--- a/usr/src/uts/common/fs/zfs/sys/dmu_objset.h Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/sys/dmu_objset.h Fri Mar 16 00:42:33 2007 -0700
@@ -68,6 +68,7 @@
objset_t os;
uint8_t os_checksum; /* can change, under dsl_dir's locks */
uint8_t os_compress; /* can change, under dsl_dir's locks */
+ uint8_t os_copies; /* can change, under dsl_dir's locks */
uint8_t os_md_checksum;
uint8_t os_md_compress;
--- a/usr/src/uts/common/sys/fs/zfs.h Fri Mar 16 00:25:23 2007 -0700
+++ b/usr/src/uts/common/sys/fs/zfs.h Fri Mar 16 00:42:33 2007 -0700
@@ -93,7 +93,8 @@
ZFS_PROP_SHAREISCSI,
ZFS_PROP_ISCSIOPTIONS, /* not exposed to the user */
ZFS_PROP_XATTR,
- ZFS_PROP_NUMCLONES /* not exposed to the user */
+ ZFS_PROP_NUMCLONES, /* not exposed to the user */
+ ZFS_PROP_COPIES
} zfs_prop_t;
#define ZFS_PROP_VALUE "value"