Skip to content

Commit fcff0f3

Browse files
pcd1193182behlendorf
authored andcommitted
Illumos 5960, 5925
5960 zfs recv should prefetch indirect blocks 5925 zfs receive -o origin= Reviewed by: Prakash Surya <prakash.surya@delphix.com> Reviewed by: Matthew Ahrens <mahrens@delphix.com> References: https://www.illumos.org/issues/5960 https://www.illumos.org/issues/5925 illumos/illumos-gate@a2cdcdd Porting notes: - [lib/libzfs/libzfs_sendrecv.c] - b8864a2 Fix gcc cast warnings - 325f023 Add linux kernel device support - 5c3f61e Increase Linux pipe buffer size on 'zfs receive' - [module/zfs/zfs_vnops.c] - 3558fd7 Prototype/structure update for Linux - c12e3a5 Restructure zfs_readdir() to fix regressions - [module/zfs/zvol.c] - Function @zvol_map_block() isn't needed in ZoL - 9965059 Prefetch start and end of volumes - [module/zfs/dmu.c] - Fixed ISO C90 - mixed declarations and code - Function dmu_prefetch() 'int i' is initialized before the following code block (c90 vs. c99) - [module/zfs/dbuf.c] - fc5bb51 Fix stack dbuf_hold_impl() - 9b67f60 Illumos 4757, 4913 - 34229a2 Reduce stack usage for recursive traverse_visitbp() - [module/zfs/dmu_send.c] - Fixed ISO C90 - mixed declarations and code - b58986e Use large stacks when available - 241b541 Illumos 5959 - clean up per-dataset feature count code - 77aef6f Use vmem_alloc() for nvlists - 00b4602 Add linux kernel memory support Ported-by: kernelOfTruth kerneloftruth@gmail.com Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
1 parent 00af2ff commit fcff0f3

40 files changed

+1418
-389
lines changed

cmd/zdb/zdb.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2489,6 +2489,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
24892489
dmu_object_type_t type;
24902490
boolean_t is_metadata;
24912491

2492+
if (bp == NULL)
2493+
return (0);
2494+
24922495
if (dump_opt['b'] >= 5 && bp->blk_birth > 0) {
24932496
char blkbuf[BP_SPRINTF_LEN];
24942497
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
@@ -2985,7 +2988,7 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
29852988
avl_index_t where;
29862989
zdb_ddt_entry_t *zdde, zdde_search;
29872990

2988-
if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
2991+
if (bp == NULL || BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
29892992
return (0);
29902993

29912994
if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {

cmd/zfs/zfs_main.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,9 @@ get_usage(zfs_help_t idx)
249249
return (gettext("\tpromote <clone-filesystem>\n"));
250250
case HELP_RECEIVE:
251251
return (gettext("\treceive [-vnFu] <filesystem|volume|"
252-
"snapshot>\n"
253-
"\treceive [-vnFu] [-d | -e] <filesystem>\n"));
252+
"snapshot>\n"
253+
"\treceive [-vnFu] [-o origin=<snapshot>] [-d | -e] "
254+
"<filesystem>\n"));
254255
case HELP_RENAME:
255256
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
256257
"<filesystem|volume|snapshot>\n"
@@ -793,7 +794,7 @@ zfs_do_create(int argc, char **argv)
793794
nomem();
794795
break;
795796
case 'o':
796-
if (parseprop(props, optarg))
797+
if (parseprop(props, optarg) != 0)
797798
goto error;
798799
break;
799800
case 's':
@@ -3622,7 +3623,7 @@ zfs_do_snapshot(int argc, char **argv)
36223623
while ((c = getopt(argc, argv, "ro:")) != -1) {
36233624
switch (c) {
36243625
case 'o':
3625-
if (parseprop(props, optarg))
3626+
if (parseprop(props, optarg) != 0)
36263627
return (1);
36273628
break;
36283629
case 'r':
@@ -3881,10 +3882,19 @@ zfs_do_receive(int argc, char **argv)
38813882
{
38823883
int c, err;
38833884
recvflags_t flags = { 0 };
3885+
nvlist_t *props;
3886+
nvpair_t *nvp = NULL;
3887+
3888+
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
3889+
nomem();
38843890

38853891
/* check options */
3886-
while ((c = getopt(argc, argv, ":denuvF")) != -1) {
3892+
while ((c = getopt(argc, argv, ":o:denuvF")) != -1) {
38873893
switch (c) {
3894+
case 'o':
3895+
if (parseprop(props, optarg) != 0)
3896+
return (1);
3897+
break;
38883898
case 'd':
38893899
flags.isprefix = B_TRUE;
38903900
break;
@@ -3929,6 +3939,13 @@ zfs_do_receive(int argc, char **argv)
39293939
usage(B_FALSE);
39303940
}
39313941

3942+
while ((nvp = nvlist_next_nvpair(props, nvp))) {
3943+
if (strcmp(nvpair_name(nvp), "origin") != 0) {
3944+
(void) fprintf(stderr, gettext("invalid option"));
3945+
usage(B_FALSE);
3946+
}
3947+
}
3948+
39323949
if (isatty(STDIN_FILENO)) {
39333950
(void) fprintf(stderr,
39343951
gettext("Error: Backup stream can not be read "
@@ -3937,7 +3954,7 @@ zfs_do_receive(int argc, char **argv)
39373954
return (1);
39383955
}
39393956

3940-
err = zfs_receive(g_zfs, argv[0], &flags, STDIN_FILENO, NULL);
3957+
err = zfs_receive(g_zfs, argv[0], props, &flags, STDIN_FILENO, NULL);
39413958

39423959
return (err != 0);
39433960
}

cmd/ztest/ztest.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3728,7 +3728,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
37283728
*/
37293729
n = ztest_random(regions) * stride + ztest_random(width);
37303730
s = 1 + ztest_random(2 * width - 1);
3731-
dmu_prefetch(os, bigobj, n * chunksize, s * chunksize);
3731+
dmu_prefetch(os, bigobj, 0, n * chunksize, s * chunksize,
3732+
ZIO_PRIORITY_SYNC_READ);
37323733

37333734
/*
37343735
* Pick a random index and compute the offsets into packobj and bigobj.
@@ -5930,8 +5931,10 @@ ztest_run(ztest_shared_t *zs)
59305931
* Right before closing the pool, kick off a bunch of async I/O;
59315932
* spa_close() should wait for it to complete.
59325933
*/
5933-
for (object = 1; object < 50; object++)
5934-
dmu_prefetch(spa->spa_meta_objset, object, 0, 1ULL << 20);
5934+
for (object = 1; object < 50; object++) {
5935+
dmu_prefetch(spa->spa_meta_objset, object, 0, 0, 1ULL << 20,
5936+
ZIO_PRIORITY_SYNC_READ);
5937+
}
59355938

59365939
/* Verify that at least one commit cb was called in a timely fashion */
59375940
if (zc_cb_counter >= ZTEST_COMMIT_CB_MIN_REG)

include/libzfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,8 +678,8 @@ typedef struct recvflags {
678678
boolean_t nomount;
679679
} recvflags_t;
680680

681-
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t *,
682-
int, avl_tree_t *);
681+
extern int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *,
682+
recvflags_t *, int, avl_tree_t *);
683683

684684
typedef enum diff_flags {
685685
ZFS_DIFF_PARSEABLE = 0x1,

include/sys/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ COMMON_H = \
99
$(top_srcdir)/include/sys/bplist.h \
1010
$(top_srcdir)/include/sys/bpobj.h \
1111
$(top_srcdir)/include/sys/bptree.h \
12+
$(top_srcdir)/include/sys/bqueue.h \
1213
$(top_srcdir)/include/sys/dbuf.h \
1314
$(top_srcdir)/include/sys/ddt.h \
1415
$(top_srcdir)/include/sys/dmu.h \
@@ -96,6 +97,7 @@ COMMON_H = \
9697
$(top_srcdir)/include/sys/zio_compress.h \
9798
$(top_srcdir)/include/sys/zio.h \
9899
$(top_srcdir)/include/sys/zio_impl.h \
100+
$(top_srcdir)/include/sys/zio_priority.h \
99101
$(top_srcdir)/include/sys/zrlock.h
100102

101103
KERNEL_H = \

include/sys/bqueue.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* CDDL HEADER START
3+
*
4+
* This file and its contents are supplied under the terms of the
5+
* Common Development and Distribution License ("CDDL"), version 1.0.
6+
* You may only use this file in accordance with the terms of version
7+
* 1.0 of the CDDL.
8+
*
9+
* A full copy of the text of the CDDL should have accompanied this
10+
* source. A copy of the CDDL is also available via the Internet at
11+
* http://www.illumos.org/license/CDDL.
12+
*
13+
* CDDL HEADER END
14+
*/
15+
/*
16+
* Copyright (c) 2014 by Delphix. All rights reserved.
17+
*/
18+
19+
#ifndef _BQUEUE_H
20+
#define _BQUEUE_H
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
#include <sys/zfs_context.h>
27+
28+
typedef struct bqueue {
29+
list_t bq_list;
30+
kmutex_t bq_lock;
31+
kcondvar_t bq_add_cv;
32+
kcondvar_t bq_pop_cv;
33+
uint64_t bq_size;
34+
uint64_t bq_maxsize;
35+
size_t bq_node_offset;
36+
} bqueue_t;
37+
38+
typedef struct bqueue_node {
39+
list_node_t bqn_node;
40+
uint64_t bqn_size;
41+
} bqueue_node_t;
42+
43+
44+
int bqueue_init(bqueue_t *, uint64_t, size_t);
45+
void bqueue_destroy(bqueue_t *);
46+
void bqueue_enqueue(bqueue_t *, void *, uint64_t);
47+
void *bqueue_dequeue(bqueue_t *);
48+
boolean_t bqueue_empty(bqueue_t *);
49+
50+
#ifdef __cplusplus
51+
}
52+
#endif
53+
54+
#endif /* _BQUEUE_H */

include/sys/dbuf.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,7 @@ typedef struct dbuf_hash_table {
261261
kmutex_t hash_mutexes[DBUF_MUTEXES];
262262
} dbuf_hash_table_t;
263263

264-
265-
uint64_t dbuf_whichblock(struct dnode *di, uint64_t offset);
264+
uint64_t dbuf_whichblock(struct dnode *di, int64_t level, uint64_t offset);
266265

267266
void dbuf_create_bonus(struct dnode *dn);
268267
int dbuf_spill_set_blksz(dmu_buf_t *db, uint64_t blksz, dmu_tx_t *tx);
@@ -272,10 +271,12 @@ void dbuf_rm_spill(struct dnode *dn, dmu_tx_t *tx);
272271
dmu_buf_impl_t *dbuf_hold(struct dnode *dn, uint64_t blkid, void *tag);
273272
dmu_buf_impl_t *dbuf_hold_level(struct dnode *dn, int level, uint64_t blkid,
274273
void *tag);
275-
int dbuf_hold_impl(struct dnode *dn, uint8_t level, uint64_t blkid, int create,
274+
int dbuf_hold_impl(struct dnode *dn, uint8_t level, uint64_t blkid,
275+
boolean_t fail_sparse, boolean_t fail_uncached,
276276
void *tag, dmu_buf_impl_t **dbp);
277277

278-
void dbuf_prefetch(struct dnode *dn, uint64_t blkid, zio_priority_t prio);
278+
void dbuf_prefetch(struct dnode *dn, int64_t level, uint64_t blkid,
279+
zio_priority_t prio, arc_flags_t aflags);
279280

280281
void dbuf_add_ref(dmu_buf_impl_t *db, void *tag);
281282
boolean_t dbuf_try_add_ref(dmu_buf_t *db, objset_t *os, uint64_t obj,

include/sys/dmu.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include <sys/inttypes.h>
4545
#include <sys/cred.h>
4646
#include <sys/fs/zfs.h>
47+
#include <sys/zio_priority.h>
4748
#include <sys/uio.h>
4849

4950
#ifdef __cplusplus
@@ -737,8 +738,8 @@ extern int zfs_max_recordsize;
737738
/*
738739
* Asynchronously try to read in the data.
739740
*/
740-
void dmu_prefetch(objset_t *os, uint64_t object, uint64_t offset,
741-
uint64_t len);
741+
void dmu_prefetch(objset_t *os, uint64_t object, int64_t level, uint64_t offset,
742+
uint64_t len, enum zio_priority pri);
742743

743744
typedef struct dmu_object_info {
744745
/* All sizes are in bytes unless otherwise indicated. */

include/sys/dsl_dataset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2323
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
24-
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
24+
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
2525
* Copyright (c) 2013 Steven Hartland. All rights reserved.
2626
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
2727
*/

include/sys/zfs_context.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,18 @@ extern int aok;
160160

161161
/*
162162
* DTrace SDT probes have different signatures in userland than they do in
163-
* kernel. If they're being used in kernel code, re-define them out of
163+
* the kernel. If they're being used in kernel code, re-define them out of
164164
* existence for their counterparts in libzpool.
165+
*
166+
* Here's an example of how to use the set-error probes in userland:
167+
* zfs$target:::set-error /arg0 == EBUSY/ {stack();}
168+
*
169+
* Here's an example of how to use DTRACE_PROBE probes in userland:
170+
* If there is a probe declared as follows:
171+
* DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn);
172+
* Then you can use it as follows:
173+
* zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/
174+
* {printf("%u %p\n", arg1, arg2);}
165175
*/
166176

167177
#ifdef DTRACE_PROBE

0 commit comments

Comments
 (0)