Compare commits
188 Commits
zfs-0.6.5.
...
zfs-0.6.5-
Author | SHA1 | Date |
---|---|---|
Tony Hutter | 2bc71fa976 | |
Tony Hutter | 5a20d4283c | |
alaviss | bf04e4d442 | |
DHE | 5e6057b574 | |
loli10K | 94d353a0bf | |
Tony Hutter | e9fc1bd5e6 | |
Tony Hutter | b88f4d7ba7 | |
Brian Behlendorf | 3e297b90f5 | |
Justin Lecher | 709f25e248 | |
Olaf Faaland | cd2209b75e | |
Tony Hutter | a57fa2c532 | |
Brian Behlendorf | 590509b75e | |
Matthew Ahrens | d07a8deac8 | |
Chunwei Chen | 69494c6aff | |
Chunwei Chen | 412e3c26a9 | |
LOLi | ed9cb8390b | |
LOLi | cb8210d125 | |
Brian Behlendorf | 21fd04ec40 | |
Brian Behlendorf | e4cb6ee6a5 | |
Brian Behlendorf | a83a4f9d10 | |
Matthew Ahrens | 1e5f75ecbe | |
Ned Bass | 36ccb9db43 | |
jxiong | a2c9518711 | |
Tony Hutter | cc519c4027 | |
Chunwei Chen | dbb48937ce | |
Tim Chase | 34a3a7c660 | |
Brian Behlendorf | 4a4c57d5ff | |
Chunwei Chen | 2094a93e87 | |
loli10K | 03336d011c | |
Brian Behlendorf | f0a4bfbe4d | |
Brian Behlendorf | ebef1f2fb6 | |
Chunwei Chen | 00a1a11989 | |
Olaf Faaland | b4c181dc76 | |
Olaf Faaland | 626ba3142b | |
Brian Behlendorf | 0bbd80c058 | |
Chunwei Chen | 10fbf7c406 | |
Chunwei Chen | 1ad7f89628 | |
Chunwei Chen | 5137c95dec | |
Chunwei Chen | a0e099580a | |
Chunwei Chen | 5070e5311c | |
Chunwei Chen | 110470266d | |
Chunwei Chen | d425320ac8 | |
Chunwei Chen | 2a51899946 | |
Chunwei Chen | f3da7a1b40 | |
Richard Yao | 625ee0a5e0 | |
Gvozden Neskovic | 9dd467a271 | |
Isaac Huang | 6ebfe58117 | |
Tim Chase | 39d65926c9 | |
Brian Behlendorf | a57228e51c | |
Brian Behlendorf | bea68ec5bf | |
Tim Chase | 88fa992878 | |
Chunwei Chen | c09af45f7b | |
Chunwei Chen | 64c259c509 | |
Neal Gompa (ニール・ゴンパ) | 447040c31d | |
tuxoko | 734e235f67 | |
Hajo Möller | ffcd0c5434 | |
LOLi | d2beed9116 | |
Tim Chase | 4c83fa9b87 | |
Brian Behlendorf | cbf8713874 | |
Stian Ellingsen | dc3d6a6db1 | |
Stian Ellingsen | d71db895a1 | |
tuxoko | 42dae6d7a6 | |
Brian Behlendorf | f85c85ea06 | |
Chunwei Chen | 670508f080 | |
Chunwei Chen | 28172e8aa7 | |
tuxoko | c0716f13ef | |
DeHackEd | dbc95a682c | |
Chunwei Chen | 20a0763746 | |
Brian Behlendorf | e56852059f | |
Ned Bass | 1f734a62ac | |
Brian Behlendorf | ffddb4dfab | |
Brian Behlendorf | 8fe1fb14cb | |
Brian Behlendorf | bf8b4a9fd5 | |
Brian Behlendorf | 39a78fe9d4 | |
Chunwei Chen | 6ae0dbdc8a | |
Brian Behlendorf | a0591c4370 | |
Brian Behlendorf | 68b8d22c6e | |
smh | 3d824a8878 | |
GeLiXin | e5c02cbb03 | |
GeLiXin | e66b546cb7 | |
GeLiXin | c23686524f | |
GeLiXin | 74acdfc682 | |
Paul Dagnelie | d9e1eec9a2 | |
Matthew Ahrens | 1421562a0d | |
Chunwei Chen | 58000c3ec7 | |
Tim Chase | e871059bc4 | |
Chunwei Chen | 91f81c42f0 | |
Chunwei Chen | 2ab9247411 | |
Chunwei Chen | af4e50750b | |
Chunwei Chen | 3602878ff7 | |
Chunwei Chen | 9f5f758d77 | |
Chunwei Chen | d5b0e7fcf1 | |
Chunwei Chen | ec9b8fae06 | |
Chunwei Chen | f7923f4ada | |
Ned Bass | 5acbedbbe8 | |
Rich Ercolani | 3a8e13688b | |
Peng | 4f96e68fad | |
Chunwei Chen | a77cea5f0f | |
Tim Chase | db3f5edcf1 | |
Brian Behlendorf | 6ae855d8a7 | |
Grischa Zengel | ff2a2b208d | |
Turbo Fredriksson | 1db6030de2 | |
Chunwei Chen | f3f0c589c3 | |
Chunwei Chen | 26e2bfa770 | |
Brian Behlendorf | 97a1bbd4ea | |
Brian Behlendorf | 01d9981349 | |
Chunwei Chen | 7043281906 | |
Chunwei Chen | 1aff4bb235 | |
Chunwei Chen | 55b8857346 | |
Chunwei Chen | 703c9f5893 | |
Matthew Ahrens | 2ea36ad824 | |
Brian Behlendorf | efde19487c | |
AndCycle | 347cdb6e61 | |
Brian Behlendorf | 2aec0bf4c5 | |
Marcel Huber | 9a6fcfd47d | |
Ned Bass | d30abebc85 | |
Tim Chase | 52475b507a | |
Brian Behlendorf | 2cb77346cb | |
Brian Behlendorf | c9ca152fd1 | |
Chunwei Chen | 21ea9460fa | |
Colin Ian King | 354424de5a | |
Brian Behlendorf | d746e2ea0e | |
Colin Ian King | 60a4ea3f94 | |
Brian Behlendorf | fbffa53a5c | |
Ned Bass | 6400ae85ee | |
Chunwei Chen | 31dbe4b404 | |
Brian Behlendorf | a64fb11bf3 | |
Gordan Bobic | 5e202e55ef | |
Ned Bass | 21f21fe859 | |
Boris Protopopov | d0337e80ca | |
Boris Protopopov | 9d02f9557f | |
Boris Protopopov | 682be6e0c9 | |
Richard Sharpe | 82ff881071 | |
Richard Sharpe | a99c845fdc | |
Tim Chase | d41e763c72 | |
Brian Behlendorf | b145e23daf | |
Brian Behlendorf | 83a5c8541e | |
Richard Yao | eb02072279 | |
John Wren Kennedy | fa567594b8 | |
Brian Behlendorf | 75233289fc | |
Dimitri John Ledkov | 5f5bc92754 | |
Paul Dagnelie | 63ce7b6fcf | |
Ned Bass | 504ff59709 | |
Brian Behlendorf | 84638a5d0c | |
Brian Behlendorf | 9986e9f544 | |
Brian Behlendorf | 9842008fc0 | |
Brian Behlendorf | b3c9e2caf5 | |
Olaf Faaland | f00a5734f6 | |
Hajo Möller | ee24b44f5e | |
Christian Neukirchen | a5ab85824d | |
Tim Chase | 6f7acfc9c9 | |
Chunwei Chen | a08add3067 | |
Brian Behlendorf | 0a2f95748d | |
Brian Behlendorf | 3b9fd93d0b | |
Brian Behlendorf | 05c3401e3f | |
Ned Bass | a5dae61721 | |
Ned Bass | 1ffc4c150e | |
Chunwei Chen | d621aa5431 | |
Chunwei Chen | 19d991a99e | |
Chunwei Chen | 0bf37725f8 | |
Brian Behlendorf | 3445a340d5 | |
Jason Zaman | 44f547af98 | |
Brian Behlendorf | a0dba38cd4 | |
Brian Behlendorf | 2b50578e29 | |
tuxoko | a3fcc7c48b | |
tuxoko | becc31dda7 | |
Brian Behlendorf | d8ac2b39c9 | |
tuxoko | 13a9527913 | |
Brian Behlendorf | 627b35a68d | |
cable2999 | 5856071367 | |
Olaf Faaland | 637fb2fcfa | |
Brian Behlendorf | 8bdac257b8 | |
Brian Behlendorf | a0b4635fb0 | |
Brian Behlendorf | cb98d1ef27 | |
Chunwei Chen | 813a4af70e | |
Brian Behlendorf | e16c04d643 | |
Chunwei Chen | 9b41d9c1b2 | |
Chunwei Chen | c5e30a0ff9 | |
Brian Behlendorf | 279e27db23 | |
Brian Behlendorf | 5f4004efc0 | |
Kamil Domański | 65d65b7a8d | |
DHE | f7dfb8b07a | |
Chunwei Chen | 15126e5d08 | |
Chunwei Chen | e909a45d22 | |
Ned Bass | 9aaf60b66d | |
Justin T. Gibbs | f9f5394f74 | |
Chunwei Chen | cd887ab869 | |
James Lee | 16a276f109 |
2
META
2
META
|
@ -1,7 +1,7 @@
|
|||
Meta: 1
|
||||
Name: zfs
|
||||
Branch: 1.0
|
||||
Version: 0.6.5.2
|
||||
Version: 0.6.5.11
|
||||
Release: 1
|
||||
Release-Tags: relext
|
||||
License: CDDL
|
||||
|
|
|
@ -55,6 +55,13 @@ shellcheck:
|
|||
done; \
|
||||
fi
|
||||
|
||||
lint: cppcheck
|
||||
|
||||
cppcheck:
|
||||
@if type cppcheck > /dev/null 2>&1; then \
|
||||
cppcheck --quiet --force ${top_srcdir}; \
|
||||
fi
|
||||
|
||||
ctags:
|
||||
$(RM) tags
|
||||
find $(top_srcdir) -name .git -prune -o -name '*.[hc]' | xargs ctags
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
#!/bin/sh
|
||||
|
||||
### prepare
|
||||
#TEST_PREPARE_WATCHDOG="no"
|
||||
|
||||
### SPLAT
|
||||
#TEST_SPLAT_SKIP="yes"
|
||||
#TEST_SPLAT_OPTIONS="-acvx"
|
||||
|
||||
### ztest
|
||||
#TEST_ZTEST_SKIP="yes"
|
||||
#TEST_ZTEST_TIMEOUT=1800
|
||||
#TEST_ZTEST_DIR="/var/tmp/"
|
||||
#TEST_ZTEST_OPTIONS="-V"
|
||||
|
||||
### ziltest
|
||||
#TEST_ZILTEST_SKIP="yes"
|
||||
#TEST_ZILTEST_OPTIONS=""
|
||||
|
||||
### zconfig
|
||||
#TEST_ZCONFIG_SKIP="yes"
|
||||
TEST_ZCONFIG_OPTIONS="-c -s10"
|
||||
|
||||
### zimport
|
||||
#TEST_ZIMPORT_SKIP="yes"
|
||||
#TEST_ZIMPORT_DIR="/var/tmp/zimport"
|
||||
#TEST_ZIMPORT_VERSIONS="master installed"
|
||||
#TEST_ZIMPORT_POOLS="zol-0.6.1 zol-0.6.2 master installed"
|
||||
#TEST_ZIMPORT_OPTIONS="-c"
|
||||
|
||||
### xfstests
|
||||
#TEST_XFSTESTS_SKIP="yes"
|
||||
#TEST_XFSTESTS_URL="https://github.com/behlendorf/xfstests/archive/"
|
||||
#TEST_XFSTESTS_VER="zfs.tar.gz"
|
||||
#TEST_XFSTESTS_POOL="tank"
|
||||
#TEST_XFSTESTS_FS="xfstests"
|
||||
#TEST_XFSTESTS_VDEV="/var/tmp/vdev"
|
||||
#TEST_XFSTESTS_OPTIONS=""
|
||||
|
||||
### filebench
|
||||
#TEST_FILEBENCH_SKIP="yes"
|
||||
#TEST_FILEBENCH_URL="http://build.zfsonlinux.org/"
|
||||
#TEST_FILEBENCH_VER="filebench-1.4.9.1.tar.gz"
|
||||
#TEST_FILEBENCH_RUNTIME=10
|
||||
#TEST_FILEBENCH_POOL="tank"
|
||||
#TEST_FILEBENCH_FS="filebench"
|
||||
#TEST_FILEBENCH_VDEV="/var/tmp/vdev"
|
||||
#TEST_FILEBENCH_DIR="/$TEST_FILEBENCH_POOL/$TEST_FILEBENCH_FS"
|
||||
#TEST_FILEBENCH_OPTIONS=""
|
||||
|
||||
### zfsstress
|
||||
#TEST_ZFSSTRESS_SKIP="yes"
|
||||
#TEST_ZFSSTRESS_URL="https://github.com/nedbass/zfsstress/archive/"
|
||||
#TEST_ZFSSTRESS_VER="master.tar.gz"
|
||||
#TEST_ZFSSTRESS_RUNTIME=300
|
||||
#TEST_ZFSSTRESS_POOL="tank"
|
||||
#TEST_ZFSSTRESS_FS="fish"
|
||||
#TEST_ZFSSTRESS_VDEV="/var/tmp/vdev"
|
||||
#TEST_ZFSSTRESS_DIR="/$TEST_ZFSSTRESS_POOL/$TEST_ZFSSTRESS_FS"
|
||||
#TEST_ZFSSTRESS_OPTIONS=""
|
||||
|
||||
### per-builder customization
|
||||
#
|
||||
# BB_NAME=builder-name <distribution-version-architecture-type>
|
||||
# - distribution=Amazon,Debian,Fedora,RHEL,SUSE,Ubuntu
|
||||
# - version=x.y
|
||||
# - architecture=x86_64,i686,arm,aarch64
|
||||
# - type=build,test
|
||||
#
|
||||
case "$BB_NAME" in
|
||||
Amazon*)
|
||||
;;
|
||||
CentOS*)
|
||||
# Sporadic segmentation faults
|
||||
TEST_ZTEST_SKIP="yes"
|
||||
# Sporadic VERIFY(!zilog_is_dirty(zilog)) failed
|
||||
TEST_ZILTEST_SKIP="yes"
|
||||
;;
|
||||
Debian*)
|
||||
;;
|
||||
Fedora*)
|
||||
;;
|
||||
RHEL*)
|
||||
;;
|
||||
SUSE*)
|
||||
;;
|
||||
Ubuntu*)
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
|
@ -94,7 +94,7 @@ def get_Kstat():
|
|||
|
||||
def div1():
|
||||
sys.stdout.write("\n")
|
||||
for i in xrange(18):
|
||||
for i in range(18):
|
||||
sys.stdout.write("%s" % "----")
|
||||
sys.stdout.write("\n")
|
||||
|
||||
|
@ -1060,7 +1060,7 @@ def _tunable_summary(Kstat):
|
|||
if alternate_tunable_layout:
|
||||
format = "\t%s=%s\n"
|
||||
|
||||
if show_tunable_descriptions and descriptions.has_key(name):
|
||||
if show_tunable_descriptions and name in descriptions:
|
||||
sys.stdout.write("\t# %s\n" % descriptions[name])
|
||||
|
||||
sys.stdout.write(format % (name, values[name]))
|
||||
|
@ -1132,7 +1132,7 @@ def main():
|
|||
if 'p' in args:
|
||||
try:
|
||||
pages.append(unSub[int(args['p']) - 1])
|
||||
except IndexError , e:
|
||||
except IndexError as e:
|
||||
sys.stderr.write('the argument to -p must be between 1 and ' +
|
||||
str(len(unSub)) + '\n')
|
||||
sys.exit()
|
||||
|
|
|
@ -97,8 +97,8 @@ cols = {
|
|||
v = {}
|
||||
hdr = ["time", "read", "miss", "miss%", "dmis", "dm%", "pmis", "pm%", "mmis",
|
||||
"mm%", "arcsz", "c"]
|
||||
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "rmis",
|
||||
"dread", "pread", "read"]
|
||||
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "dread",
|
||||
"pread", "read"]
|
||||
sint = 1 # Default interval is 1 second
|
||||
count = 1 # Default count is 1
|
||||
hdr_intr = 20 # Print header every 20 lines of output
|
||||
|
|
|
@ -34,7 +34,7 @@ import errno
|
|||
|
||||
bhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"]
|
||||
bxhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize",
|
||||
"meta", "state", "dbholds", "list", "atype", "index", "flags",
|
||||
"meta", "state", "dbholds", "list", "atype", "flags",
|
||||
"count", "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2",
|
||||
"l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype",
|
||||
"data_bs", "meta_bs", "bsize", "lvls", "dholds", "blocks", "dsize"]
|
||||
|
@ -45,7 +45,7 @@ dxhdr = ["pool", "objset", "object", "dtype", "btype", "data_bs", "meta_bs",
|
|||
"bsize", "lvls", "dholds", "blocks", "dsize", "cached", "direct",
|
||||
"indirect", "bonus", "spill"]
|
||||
dincompat = ["level", "blkid", "offset", "dbsize", "meta", "state", "dbholds",
|
||||
"list", "atype", "index", "flags", "count", "asize", "access",
|
||||
"list", "atype", "flags", "count", "asize", "access",
|
||||
"mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize",
|
||||
"l2_comp", "aholds"]
|
||||
|
||||
|
@ -53,7 +53,7 @@ thdr = ["pool", "objset", "dtype", "cached"]
|
|||
txhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect",
|
||||
"bonus", "spill"]
|
||||
tincompat = ["object", "level", "blkid", "offset", "dbsize", "meta", "state",
|
||||
"dbholds", "list", "atype", "index", "flags", "count", "asize",
|
||||
"dbholds", "list", "atype", "flags", "count", "asize",
|
||||
"access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr",
|
||||
"l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs",
|
||||
"bsize", "lvls", "dholds", "blocks", "dsize"]
|
||||
|
@ -72,7 +72,6 @@ cols = {
|
|||
"dbholds": [7, 1000, "number of holds on buffer"],
|
||||
"list": [4, -1, "which ARC list contains this buffer"],
|
||||
"atype": [7, -1, "ARC header type (data or metadata)"],
|
||||
"index": [5, -1, "buffer's index into its ARC list"],
|
||||
"flags": [8, -1, "ARC read flags"],
|
||||
"count": [5, -1, "ARC data count"],
|
||||
"asize": [7, 1024, "size of this ARC buffer"],
|
||||
|
@ -387,9 +386,9 @@ def update_dict(d, k, line, labels):
|
|||
|
||||
def print_dict(d):
|
||||
print_header()
|
||||
for pool in d.keys():
|
||||
for objset in d[pool].keys():
|
||||
for v in d[pool][objset].values():
|
||||
for pool in list(d.keys()):
|
||||
for objset in list(d[pool].keys()):
|
||||
for v in list(d[pool][objset].values()):
|
||||
print_values(v)
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <libzfs.h>
|
||||
#include <locale.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define ZS_COMMENT 0x00000000 /* comment */
|
||||
#define ZS_ZFSUTIL 0x00000001 /* caller is zfs(8) */
|
||||
|
@ -76,7 +77,10 @@ static const option_map_t option_map[] = {
|
|||
{ MNTOPT_RELATIME, MS_RELATIME, ZS_COMMENT },
|
||||
#endif
|
||||
#ifdef MS_STRICTATIME
|
||||
{ MNTOPT_DFRATIME, MS_STRICTATIME, ZS_COMMENT },
|
||||
{ MNTOPT_STRICTATIME, MS_STRICTATIME, ZS_COMMENT },
|
||||
#endif
|
||||
#ifdef MS_LAZYTIME
|
||||
{ MNTOPT_LAZYTIME, MS_LAZYTIME, ZS_COMMENT },
|
||||
#endif
|
||||
{ MNTOPT_CONTEXT, MS_COMMENT, ZS_COMMENT },
|
||||
{ MNTOPT_FSCONTEXT, MS_COMMENT, ZS_COMMENT },
|
||||
|
@ -389,7 +393,7 @@ main(int argc, char **argv)
|
|||
opterr = 0;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "sfnvo:h?")) != -1) {
|
||||
while ((c = getopt_long(argc, argv, "sfnvo:h?", 0, 0)) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
sloppy = 1;
|
||||
|
@ -604,10 +608,23 @@ main(int argc, char **argv)
|
|||
"failed for unknown reason.\n"), dataset);
|
||||
}
|
||||
return (MOUNT_SYSERR);
|
||||
#ifdef MS_MANDLOCK
|
||||
case EPERM:
|
||||
if (mntflags & MS_MANDLOCK) {
|
||||
(void) fprintf(stderr, gettext("filesystem "
|
||||
"'%s' has the 'nbmand=on' property set, "
|
||||
"this mount\noption may be disabled in "
|
||||
"your kernel. Use 'zfs set nbmand=off'\n"
|
||||
"to disable this option and try to "
|
||||
"mount the filesystem again.\n"), dataset);
|
||||
return (MOUNT_SYSERR);
|
||||
}
|
||||
/* fallthru */
|
||||
#endif
|
||||
default:
|
||||
(void) fprintf(stderr, gettext("filesystem "
|
||||
"'%s' can not be mounted due to error "
|
||||
"%d\n"), dataset, errno);
|
||||
"'%s' can not be mounted: %s\n"), dataset,
|
||||
strerror(errno));
|
||||
return (MOUNT_USAGE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,9 +184,9 @@ sas_handler() {
|
|||
return
|
||||
fi
|
||||
|
||||
# Get the raw scsi device name from multipath -l. Strip off
|
||||
# Get the raw scsi device name from multipath -ll. Strip off
|
||||
# leading pipe symbols to make field numbering consistent.
|
||||
DEV=`multipath -l $DM_NAME |
|
||||
DEV=`multipath -ll $DM_NAME |
|
||||
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
|
||||
if [ -z "$DEV" ] ; then
|
||||
return
|
||||
|
|
|
@ -67,13 +67,22 @@
|
|||
zio_compress_table[(idx)].ci_name : "UNKNOWN")
|
||||
#define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
|
||||
zio_checksum_table[(idx)].ci_name : "UNKNOWN")
|
||||
#define ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \
|
||||
dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ? \
|
||||
dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
|
||||
#define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : \
|
||||
(((idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA) ? \
|
||||
DMU_OT_ZAP_OTHER : DMU_OT_NUMTYPES))
|
||||
|
||||
static char *
|
||||
zdb_ot_name(dmu_object_type_t type)
|
||||
{
|
||||
if (type < DMU_OT_NUMTYPES)
|
||||
return (dmu_ot[type].ot_name);
|
||||
else if ((type & DMU_OT_NEWTYPE) &&
|
||||
((type & DMU_OT_BYTESWAP_MASK) < DMU_BSWAP_NUMFUNCS))
|
||||
return (dmu_ot_byteswap[type & DMU_OT_BYTESWAP_MASK].ob_name);
|
||||
else
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
|
||||
#ifndef lint
|
||||
extern int zfs_recover;
|
||||
extern uint64_t zfs_arc_max, zfs_arc_meta_limit;
|
||||
|
@ -469,7 +478,7 @@ static void
|
|||
dump_bpobj_subobjs(objset_t *os, uint64_t object, void *data, size_t size)
|
||||
{
|
||||
dmu_object_info_t doi;
|
||||
uint64_t i;
|
||||
int64_t i;
|
||||
|
||||
VERIFY0(dmu_object_info(os, object, &doi));
|
||||
uint64_t *subobjs = kmem_alloc(doi.doi_max_offset, KM_SLEEP);
|
||||
|
@ -488,7 +497,7 @@ dump_bpobj_subobjs(objset_t *os, uint64_t object, void *data, size_t size)
|
|||
}
|
||||
|
||||
for (i = 0; i <= last_nonzero; i++) {
|
||||
(void) printf("\t%llu\n", (longlong_t)subobjs[i]);
|
||||
(void) printf("\t%llu\n", (u_longlong_t)subobjs[i]);
|
||||
}
|
||||
kmem_free(subobjs, doi.doi_max_offset);
|
||||
}
|
||||
|
@ -1925,12 +1934,12 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header)
|
|||
|
||||
(void) printf("%10lld %3u %5s %5s %5s %5s %6s %s%s\n",
|
||||
(u_longlong_t)object, doi.doi_indirection, iblk, dblk,
|
||||
asize, lsize, fill, ZDB_OT_NAME(doi.doi_type), aux);
|
||||
asize, lsize, fill, zdb_ot_name(doi.doi_type), aux);
|
||||
|
||||
if (doi.doi_bonus_type != DMU_OT_NONE && verbosity > 3) {
|
||||
(void) printf("%10s %3s %5s %5s %5s %5s %6s %s\n",
|
||||
"", "", "", "", "", bonus_size, "bonus",
|
||||
ZDB_OT_NAME(doi.doi_bonus_type));
|
||||
zdb_ot_name(doi.doi_bonus_type));
|
||||
}
|
||||
|
||||
if (verbosity >= 4) {
|
||||
|
@ -3357,8 +3366,10 @@ zdb_read_block(char *thing, spa_t *spa)
|
|||
continue;
|
||||
|
||||
p = &flagstr[i + 1];
|
||||
if (bit == ZDB_FLAG_PRINT_BLKPTR)
|
||||
if (bit == ZDB_FLAG_PRINT_BLKPTR) {
|
||||
blkptr_offset = strtoull(p, &p, 16);
|
||||
i = p - &flagstr[i + 1];
|
||||
}
|
||||
if (*p != ':' && *p != '\0') {
|
||||
(void) printf("***Invalid flag arg: '%s'\n", s);
|
||||
free(dup);
|
||||
|
|
|
@ -444,13 +444,13 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
|
|||
|
||||
/*
|
||||
* If we're recursive, then we always allow filesystems as
|
||||
* arguments. If we also are interested in snapshots, then we
|
||||
* can take volumes as well.
|
||||
* arguments. If we also are interested in snapshots or
|
||||
* bookmarks, then we can take volumes as well.
|
||||
*/
|
||||
argtype = types;
|
||||
if (flags & ZFS_ITER_RECURSE) {
|
||||
argtype |= ZFS_TYPE_FILESYSTEM;
|
||||
if (types & ZFS_TYPE_SNAPSHOT)
|
||||
if (types & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK))
|
||||
argtype |= ZFS_TYPE_VOLUME;
|
||||
}
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ static const char *
|
|||
get_usage(zpool_help_t idx) {
|
||||
switch (idx) {
|
||||
case HELP_ADD:
|
||||
return (gettext("\tadd [-fn] [-o property=value] "
|
||||
return (gettext("\tadd [-fgLnP] [-o property=value] "
|
||||
"<pool> <vdev> ...\n"));
|
||||
case HELP_ATTACH:
|
||||
return (gettext("\tattach [-f] [-o property=value] "
|
||||
|
@ -237,12 +237,12 @@ get_usage(zpool_help_t idx) {
|
|||
"[-R root] [-F [-n]]\n"
|
||||
"\t <pool | id> [newpool]\n"));
|
||||
case HELP_IOSTAT:
|
||||
return (gettext("\tiostat [-v] [-T d|u] [-y] [pool] ... "
|
||||
return (gettext("\tiostat [-gLPvy] [-T d|u] [pool] ... "
|
||||
"[interval [count]]\n"));
|
||||
case HELP_LABELCLEAR:
|
||||
return (gettext("\tlabelclear [-f] <vdev>\n"));
|
||||
case HELP_LIST:
|
||||
return (gettext("\tlist [-Hv] [-o property[,...]] "
|
||||
return (gettext("\tlist [-gHLPv] [-o property[,...]] "
|
||||
"[-T d|u] [pool] ... [interval [count]]\n"));
|
||||
case HELP_OFFLINE:
|
||||
return (gettext("\toffline [-t] <pool> <device> ...\n"));
|
||||
|
@ -258,8 +258,8 @@ get_usage(zpool_help_t idx) {
|
|||
case HELP_SCRUB:
|
||||
return (gettext("\tscrub [-s] <pool> ...\n"));
|
||||
case HELP_STATUS:
|
||||
return (gettext("\tstatus [-vxD] [-T d|u] [pool] ... [interval "
|
||||
"[count]]\n"));
|
||||
return (gettext("\tstatus [-gLPvxD] [-T d|u] [pool] ... "
|
||||
"[interval [count]]\n"));
|
||||
case HELP_UPGRADE:
|
||||
return (gettext("\tupgrade\n"
|
||||
"\tupgrade -v\n"
|
||||
|
@ -272,7 +272,7 @@ get_usage(zpool_help_t idx) {
|
|||
case HELP_SET:
|
||||
return (gettext("\tset <property=value> <pool> \n"));
|
||||
case HELP_SPLIT:
|
||||
return (gettext("\tsplit [-n] [-R altroot] [-o mntopts]\n"
|
||||
return (gettext("\tsplit [-gLnP] [-R altroot] [-o mntopts]\n"
|
||||
"\t [-o property=value] <pool> <newpool> "
|
||||
"[<device> ...]\n"));
|
||||
case HELP_REGUID:
|
||||
|
@ -371,7 +371,7 @@ usage(boolean_t requested)
|
|||
|
||||
void
|
||||
print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
|
||||
boolean_t print_logs)
|
||||
boolean_t print_logs, int name_flags)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
|
@ -392,9 +392,9 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
|
|||
if ((is_log && !print_logs) || (!is_log && print_logs))
|
||||
continue;
|
||||
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c], name_flags);
|
||||
print_vdev_tree(zhp, vname, child[c], indent + 2,
|
||||
B_FALSE);
|
||||
B_FALSE, name_flags);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
@ -502,12 +502,15 @@ add_prop_list_default(const char *propname, char *propval, nvlist_t **props,
|
|||
}
|
||||
|
||||
/*
|
||||
* zpool add [-fn] [-o property=value] <pool> <vdev> ...
|
||||
* zpool add [-fgLnP] [-o property=value] <pool> <vdev> ...
|
||||
*
|
||||
* -f Force addition of devices, even if they appear in use
|
||||
* -g Display guid for individual vdev name.
|
||||
* -L Follow links when resolving vdev path name.
|
||||
* -n Do not add the devices, but display the resulting layout if
|
||||
* they were to be added.
|
||||
* -o Set property=value.
|
||||
* -P Display full path for vdev name.
|
||||
*
|
||||
* Adds the given vdevs to 'pool'. As with create, the bulk of this work is
|
||||
* handled by get_vdev_spec(), which constructs the nvlist needed to pass to
|
||||
|
@ -518,6 +521,7 @@ zpool_do_add(int argc, char **argv)
|
|||
{
|
||||
boolean_t force = B_FALSE;
|
||||
boolean_t dryrun = B_FALSE;
|
||||
int name_flags = 0;
|
||||
int c;
|
||||
nvlist_t *nvroot;
|
||||
char *poolname;
|
||||
|
@ -528,11 +532,17 @@ zpool_do_add(int argc, char **argv)
|
|||
char *propval;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "fno:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "fgLno:P")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
force = B_TRUE;
|
||||
break;
|
||||
case 'g':
|
||||
name_flags |= VDEV_NAME_GUID;
|
||||
break;
|
||||
case 'L':
|
||||
name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||
break;
|
||||
case 'n':
|
||||
dryrun = B_TRUE;
|
||||
break;
|
||||
|
@ -549,6 +559,9 @@ zpool_do_add(int argc, char **argv)
|
|||
(add_prop_list(optarg, propval, &props, B_TRUE)))
|
||||
usage(B_FALSE);
|
||||
break;
|
||||
case 'P':
|
||||
name_flags |= VDEV_NAME_PATH;
|
||||
break;
|
||||
case '?':
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
optopt);
|
||||
|
@ -606,15 +619,19 @@ zpool_do_add(int argc, char **argv)
|
|||
"configuration:\n"), zpool_get_name(zhp));
|
||||
|
||||
/* print original main pool and new tree */
|
||||
print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
|
||||
print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
|
||||
print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE,
|
||||
name_flags);
|
||||
print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE, name_flags);
|
||||
|
||||
/* Do the same for the logs */
|
||||
if (num_logs(poolnvroot) > 0) {
|
||||
print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
|
||||
print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
|
||||
print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE,
|
||||
name_flags);
|
||||
print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE,
|
||||
name_flags);
|
||||
} else if (num_logs(nvroot) > 0) {
|
||||
print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE);
|
||||
print_vdev_tree(zhp, "logs", nvroot, 0, B_TRUE,
|
||||
name_flags);
|
||||
}
|
||||
|
||||
/* Do the same for the caches */
|
||||
|
@ -624,7 +641,7 @@ zpool_do_add(int argc, char **argv)
|
|||
(void) printf(gettext("\tcache\n"));
|
||||
for (c = 0; c < l2children; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, NULL,
|
||||
l2child[c], B_FALSE);
|
||||
l2child[c], name_flags);
|
||||
(void) printf("\t %s\n", vname);
|
||||
free(vname);
|
||||
}
|
||||
|
@ -635,7 +652,7 @@ zpool_do_add(int argc, char **argv)
|
|||
(void) printf(gettext("\tcache\n"));
|
||||
for (c = 0; c < l2children; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, NULL,
|
||||
l2child[c], B_FALSE);
|
||||
l2child[c], name_flags);
|
||||
(void) printf("\t %s\n", vname);
|
||||
free(vname);
|
||||
}
|
||||
|
@ -1082,9 +1099,9 @@ zpool_do_create(int argc, char **argv)
|
|||
(void) printf(gettext("would create '%s' with the "
|
||||
"following layout:\n\n"), poolname);
|
||||
|
||||
print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE);
|
||||
print_vdev_tree(NULL, poolname, nvroot, 0, B_FALSE, 0);
|
||||
if (num_logs(nvroot) > 0)
|
||||
print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE);
|
||||
print_vdev_tree(NULL, "logs", nvroot, 0, B_TRUE, 0);
|
||||
|
||||
ret = 0;
|
||||
} else {
|
||||
|
@ -1311,13 +1328,15 @@ zpool_do_export(int argc, char **argv)
|
|||
* name column.
|
||||
*/
|
||||
static int
|
||||
max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
|
||||
max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max,
|
||||
int name_flags)
|
||||
{
|
||||
char *name = zpool_vdev_name(g_zfs, zhp, nv, B_TRUE);
|
||||
char *name;
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
int ret;
|
||||
|
||||
name = zpool_vdev_name(g_zfs, zhp, nv, name_flags | VDEV_NAME_TYPE_ID);
|
||||
if (strlen(name) + depth > max)
|
||||
max = strlen(name) + depth;
|
||||
|
||||
|
@ -1327,7 +1346,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
|
|||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++)
|
||||
if ((ret = max_width(zhp, child[c], depth + 2,
|
||||
max)) > max)
|
||||
max, name_flags)) > max)
|
||||
max = ret;
|
||||
}
|
||||
|
||||
|
@ -1335,7 +1354,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
|
|||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++)
|
||||
if ((ret = max_width(zhp, child[c], depth + 2,
|
||||
max)) > max)
|
||||
max, name_flags)) > max)
|
||||
max = ret;
|
||||
}
|
||||
|
||||
|
@ -1343,11 +1362,10 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
|
|||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++)
|
||||
if ((ret = max_width(zhp, child[c], depth + 2,
|
||||
max)) > max)
|
||||
max, name_flags)) > max)
|
||||
max = ret;
|
||||
}
|
||||
|
||||
|
||||
return (max);
|
||||
}
|
||||
|
||||
|
@ -1399,9 +1417,9 @@ find_spare(zpool_handle_t *zhp, void *data)
|
|||
/*
|
||||
* Print out configuration state as requested by status_callback.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||
int namewidth, int depth, boolean_t isspare)
|
||||
int namewidth, int depth, boolean_t isspare, int name_flags)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
|
@ -1537,20 +1555,21 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
|||
&ishole);
|
||||
if (islog || ishole)
|
||||
continue;
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||
name_flags | VDEV_NAME_TYPE_ID);
|
||||
print_status_config(zhp, vname, child[c],
|
||||
namewidth, depth + 2, isspare);
|
||||
namewidth, depth + 2, isspare, name_flags);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print the configuration of an exported pool. Iterate over all vdevs in the
|
||||
* pool, printing out the name and status for each one.
|
||||
*/
|
||||
void
|
||||
print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
||||
static void
|
||||
print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
|
||||
int name_flags)
|
||||
{
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
|
@ -1615,8 +1634,10 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
|||
if (is_log)
|
||||
continue;
|
||||
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
|
||||
print_import_config(vname, child[c], namewidth, depth + 2);
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c],
|
||||
name_flags | VDEV_NAME_TYPE_ID);
|
||||
print_import_config(vname, child[c], namewidth, depth + 2,
|
||||
name_flags);
|
||||
free(vname);
|
||||
}
|
||||
|
||||
|
@ -1624,7 +1645,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
|||
&child, &children) == 0) {
|
||||
(void) printf(gettext("\tcache\n"));
|
||||
for (c = 0; c < children; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c],
|
||||
name_flags);
|
||||
(void) printf("\t %s\n", vname);
|
||||
free(vname);
|
||||
}
|
||||
|
@ -1634,7 +1656,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
|||
&child, &children) == 0) {
|
||||
(void) printf(gettext("\tspares\n"));
|
||||
for (c = 0; c < children; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c], B_FALSE);
|
||||
vname = zpool_vdev_name(g_zfs, NULL, child[c],
|
||||
name_flags);
|
||||
(void) printf("\t %s\n", vname);
|
||||
free(vname);
|
||||
}
|
||||
|
@ -1650,7 +1673,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
|||
* works because only the top level vdev is marked "is_log"
|
||||
*/
|
||||
static void
|
||||
print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
|
||||
print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose,
|
||||
int name_flags)
|
||||
{
|
||||
uint_t c, children;
|
||||
nvlist_t **child;
|
||||
|
@ -1669,12 +1693,14 @@ print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
|
|||
&is_log);
|
||||
if (!is_log)
|
||||
continue;
|
||||
name = zpool_vdev_name(g_zfs, zhp, child[c], B_TRUE);
|
||||
name = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||
name_flags | VDEV_NAME_TYPE_ID);
|
||||
if (verbose)
|
||||
print_status_config(zhp, name, child[c], namewidth,
|
||||
2, B_FALSE);
|
||||
2, B_FALSE, name_flags);
|
||||
else
|
||||
print_import_config(name, child[c], namewidth, 2);
|
||||
print_import_config(name, child[c], namewidth, 2,
|
||||
name_flags);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
@ -1923,13 +1949,13 @@ show_import(nvlist_t *config)
|
|||
|
||||
(void) printf(gettext(" config:\n\n"));
|
||||
|
||||
namewidth = max_width(NULL, nvroot, 0, 0);
|
||||
namewidth = max_width(NULL, nvroot, 0, 0, 0);
|
||||
if (namewidth < 10)
|
||||
namewidth = 10;
|
||||
|
||||
print_import_config(name, nvroot, namewidth, 0);
|
||||
print_import_config(name, nvroot, namewidth, 0, 0);
|
||||
if (num_logs(nvroot) > 0)
|
||||
print_logs(NULL, nvroot, namewidth, B_FALSE);
|
||||
print_logs(NULL, nvroot, namewidth, B_FALSE, 0);
|
||||
|
||||
if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
|
||||
(void) printf(gettext("\n\tAdditional devices are known to "
|
||||
|
@ -2438,6 +2464,7 @@ error:
|
|||
|
||||
typedef struct iostat_cbdata {
|
||||
boolean_t cb_verbose;
|
||||
int cb_name_flags;
|
||||
int cb_namewidth;
|
||||
int cb_iteration;
|
||||
zpool_list_t *cb_list;
|
||||
|
@ -2560,7 +2587,8 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
|
|||
if (ishole || islog)
|
||||
continue;
|
||||
|
||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
|
||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
||||
cb->cb_name_flags);
|
||||
print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
|
||||
newchild[c], cb, depth + 2);
|
||||
free(vname);
|
||||
|
@ -2581,7 +2609,7 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
|
|||
|
||||
if (islog) {
|
||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
||||
B_FALSE);
|
||||
cb->cb_name_flags);
|
||||
print_vdev_stats(zhp, vname, oldnv ?
|
||||
oldchild[c] : NULL, newchild[c],
|
||||
cb, depth + 2);
|
||||
|
@ -2607,7 +2635,7 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
|
|||
"-\n", cb->cb_namewidth, "cache");
|
||||
for (c = 0; c < children; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
||||
B_FALSE);
|
||||
cb->cb_name_flags);
|
||||
print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
|
||||
newchild[c], cb, depth + 2);
|
||||
free(vname);
|
||||
|
@ -2700,7 +2728,7 @@ get_namewidth(zpool_handle_t *zhp, void *data)
|
|||
cb->cb_namewidth = strlen(zpool_get_name(zhp));
|
||||
else
|
||||
cb->cb_namewidth = max_width(zhp, nvroot, 0,
|
||||
cb->cb_namewidth);
|
||||
cb->cb_namewidth, cb->cb_name_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2800,8 +2828,11 @@ get_timestamp_arg(char c)
|
|||
}
|
||||
|
||||
/*
|
||||
* zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
|
||||
* zpool iostat [-gLPv] [-T d|u] [pool] ... [interval [count]]
|
||||
*
|
||||
* -g Display guid for individual vdev name.
|
||||
* -L Follow links when resolving vdev path name.
|
||||
* -P Display full path for vdev name.
|
||||
* -v Display statistics for individual vdevs
|
||||
* -T Display a timestamp in date(1) or Unix format
|
||||
*
|
||||
|
@ -2821,11 +2852,23 @@ zpool_do_iostat(int argc, char **argv)
|
|||
zpool_list_t *list;
|
||||
boolean_t verbose = B_FALSE;
|
||||
boolean_t omit_since_boot = B_FALSE;
|
||||
iostat_cbdata_t cb;
|
||||
boolean_t guid = B_FALSE;
|
||||
boolean_t follow_links = B_FALSE;
|
||||
boolean_t full_name = B_FALSE;
|
||||
iostat_cbdata_t cb = { 0 };
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "T:vy")) != -1) {
|
||||
while ((c = getopt(argc, argv, "gLPT:vy")) != -1) {
|
||||
switch (c) {
|
||||
case 'g':
|
||||
guid = B_TRUE;
|
||||
break;
|
||||
case 'L':
|
||||
follow_links = B_TRUE;
|
||||
break;
|
||||
case 'P':
|
||||
full_name = B_TRUE;
|
||||
break;
|
||||
case 'T':
|
||||
get_timestamp_arg(*optarg);
|
||||
break;
|
||||
|
@ -2870,6 +2913,12 @@ zpool_do_iostat(int argc, char **argv)
|
|||
*/
|
||||
cb.cb_list = list;
|
||||
cb.cb_verbose = verbose;
|
||||
if (guid)
|
||||
cb.cb_name_flags |= VDEV_NAME_GUID;
|
||||
if (follow_links)
|
||||
cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||
if (full_name)
|
||||
cb.cb_name_flags |= VDEV_NAME_PATH;
|
||||
cb.cb_iteration = 0;
|
||||
cb.cb_namewidth = 0;
|
||||
|
||||
|
@ -2953,6 +3002,7 @@ zpool_do_iostat(int argc, char **argv)
|
|||
|
||||
typedef struct list_cbdata {
|
||||
boolean_t cb_verbose;
|
||||
int cb_name_flags;
|
||||
int cb_namewidth;
|
||||
boolean_t cb_scripted;
|
||||
zprop_list_t *cb_proplist;
|
||||
|
@ -3128,6 +3178,9 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
|||
uint_t c, children;
|
||||
char *vname;
|
||||
boolean_t scripted = cb->cb_scripted;
|
||||
uint64_t islog = B_FALSE;
|
||||
boolean_t haslog = B_FALSE;
|
||||
char *dashes = "%-*s - - - - - -\n";
|
||||
|
||||
verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
|
||||
(uint64_t **)&vs, &c) == 0);
|
||||
|
@ -3178,24 +3231,51 @@ print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
|||
ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
|
||||
continue;
|
||||
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
|
||||
if (nvlist_lookup_uint64(child[c],
|
||||
ZPOOL_CONFIG_IS_LOG, &islog) == 0 && islog) {
|
||||
haslog = B_TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||
cb->cb_name_flags);
|
||||
print_list_stats(zhp, vname, child[c], cb, depth + 2);
|
||||
free(vname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Include level 2 ARC devices in iostat output
|
||||
*/
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
||||
&child, &children) != 0)
|
||||
return;
|
||||
if (haslog == B_TRUE) {
|
||||
/* LINTED E_SEC_PRINTF_VAR_FMT */
|
||||
(void) printf(dashes, cb->cb_namewidth, "log");
|
||||
for (c = 0; c < children; c++) {
|
||||
if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
|
||||
&islog) != 0 || !islog)
|
||||
continue;
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||
cb->cb_name_flags);
|
||||
print_list_stats(zhp, vname, child[c], cb, depth + 2);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
if (children > 0) {
|
||||
(void) printf("%-*s - - - - - "
|
||||
"-\n", cb->cb_namewidth, "cache");
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
||||
&child, &children) == 0 && children > 0) {
|
||||
/* LINTED E_SEC_PRINTF_VAR_FMT */
|
||||
(void) printf(dashes, cb->cb_namewidth, "cache");
|
||||
for (c = 0; c < children; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||
B_FALSE);
|
||||
cb->cb_name_flags);
|
||||
print_list_stats(zhp, vname, child[c], cb, depth + 2);
|
||||
free(vname);
|
||||
}
|
||||
}
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, &child,
|
||||
&children) == 0 && children > 0) {
|
||||
/* LINTED E_SEC_PRINTF_VAR_FMT */
|
||||
(void) printf(dashes, cb->cb_namewidth, "spare");
|
||||
for (c = 0; c < children; c++) {
|
||||
vname = zpool_vdev_name(g_zfs, zhp, child[c],
|
||||
cb->cb_name_flags);
|
||||
print_list_stats(zhp, vname, child[c], cb, depth + 2);
|
||||
free(vname);
|
||||
}
|
||||
|
@ -3227,13 +3307,16 @@ list_callback(zpool_handle_t *zhp, void *data)
|
|||
}
|
||||
|
||||
/*
|
||||
* zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
|
||||
* zpool list [-gHLP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
|
||||
*
|
||||
* -g Display guid for individual vdev name.
|
||||
* -H Scripted mode. Don't display headers, and separate properties
|
||||
* by a single tab.
|
||||
* -L Follow links when resolving vdev path name.
|
||||
* -o List of properties to display. Defaults to
|
||||
* "name,size,allocated,free,expandsize,fragmentation,capacity,"
|
||||
* "dedupratio,health,altroot"
|
||||
* -P Display full path for vdev name.
|
||||
* -T Display a timestamp in date(1) or Unix format
|
||||
*
|
||||
* List all pools in the system, whether or not they're healthy. Output space
|
||||
|
@ -3254,14 +3337,23 @@ zpool_do_list(int argc, char **argv)
|
|||
boolean_t first = B_TRUE;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
|
||||
while ((c = getopt(argc, argv, ":gHLo:PT:v")) != -1) {
|
||||
switch (c) {
|
||||
case 'g':
|
||||
cb.cb_name_flags |= VDEV_NAME_GUID;
|
||||
break;
|
||||
case 'H':
|
||||
cb.cb_scripted = B_TRUE;
|
||||
break;
|
||||
case 'L':
|
||||
cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||
break;
|
||||
case 'o':
|
||||
props = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
cb.cb_name_flags |= VDEV_NAME_PATH;
|
||||
break;
|
||||
case 'T':
|
||||
get_timestamp_arg(*optarg);
|
||||
break;
|
||||
|
@ -3517,13 +3609,16 @@ zpool_do_detach(int argc, char **argv)
|
|||
}
|
||||
|
||||
/*
|
||||
* zpool split [-n] [-o prop=val] ...
|
||||
* zpool split [-gLnP] [-o prop=val] ...
|
||||
* [-o mntopt] ...
|
||||
* [-R altroot] <pool> <newpool> [<device> ...]
|
||||
*
|
||||
* -g Display guid for individual vdev name.
|
||||
* -L Follow links when resolving vdev path name.
|
||||
* -n Do not split the pool, but display the resulting layout if
|
||||
* it were to be split.
|
||||
* -o Set property=value, or set mount options.
|
||||
* -P Display full path for vdev name.
|
||||
* -R Mount the split-off pool under an alternate root.
|
||||
*
|
||||
* Splits the named pool and gives it the new pool name. Devices to be split
|
||||
|
@ -3547,10 +3642,17 @@ zpool_do_split(int argc, char **argv)
|
|||
|
||||
flags.dryrun = B_FALSE;
|
||||
flags.import = B_FALSE;
|
||||
flags.name_flags = 0;
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, ":R:no:")) != -1) {
|
||||
while ((c = getopt(argc, argv, ":gLR:no:P")) != -1) {
|
||||
switch (c) {
|
||||
case 'g':
|
||||
flags.name_flags |= VDEV_NAME_GUID;
|
||||
break;
|
||||
case 'L':
|
||||
flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||
break;
|
||||
case 'R':
|
||||
flags.import = B_TRUE;
|
||||
if (add_prop_list(
|
||||
|
@ -3578,6 +3680,9 @@ zpool_do_split(int argc, char **argv)
|
|||
mntopts = optarg;
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
flags.name_flags |= VDEV_NAME_PATH;
|
||||
break;
|
||||
case ':':
|
||||
(void) fprintf(stderr, gettext("missing argument for "
|
||||
"'%c' option\n"), optopt);
|
||||
|
@ -3625,7 +3730,8 @@ zpool_do_split(int argc, char **argv)
|
|||
if (flags.dryrun) {
|
||||
(void) printf(gettext("would create '%s' with the "
|
||||
"following layout:\n\n"), newpool);
|
||||
print_vdev_tree(NULL, newpool, config, 0, B_FALSE);
|
||||
print_vdev_tree(NULL, newpool, config, 0, B_FALSE,
|
||||
flags.name_flags);
|
||||
}
|
||||
nvlist_free(config);
|
||||
}
|
||||
|
@ -4031,6 +4137,7 @@ zpool_do_scrub(int argc, char **argv)
|
|||
|
||||
typedef struct status_cbdata {
|
||||
int cb_count;
|
||||
int cb_name_flags;
|
||||
boolean_t cb_allpools;
|
||||
boolean_t cb_verbose;
|
||||
boolean_t cb_explain;
|
||||
|
@ -4187,7 +4294,7 @@ print_error_log(zpool_handle_t *zhp)
|
|||
|
||||
static void
|
||||
print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
|
||||
int namewidth)
|
||||
int namewidth, int name_flags)
|
||||
{
|
||||
uint_t i;
|
||||
char *name;
|
||||
|
@ -4198,16 +4305,16 @@ print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
|
|||
(void) printf(gettext("\tspares\n"));
|
||||
|
||||
for (i = 0; i < nspares; i++) {
|
||||
name = zpool_vdev_name(g_zfs, zhp, spares[i], B_FALSE);
|
||||
name = zpool_vdev_name(g_zfs, zhp, spares[i], name_flags);
|
||||
print_status_config(zhp, name, spares[i],
|
||||
namewidth, 2, B_TRUE);
|
||||
namewidth, 2, B_TRUE, name_flags);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
|
||||
int namewidth)
|
||||
int namewidth, int name_flags)
|
||||
{
|
||||
uint_t i;
|
||||
char *name;
|
||||
|
@ -4218,9 +4325,9 @@ print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
|
|||
(void) printf(gettext("\tcache\n"));
|
||||
|
||||
for (i = 0; i < nl2cache; i++) {
|
||||
name = zpool_vdev_name(g_zfs, zhp, l2cache[i], B_FALSE);
|
||||
name = zpool_vdev_name(g_zfs, zhp, l2cache[i], name_flags);
|
||||
print_status_config(zhp, name, l2cache[i],
|
||||
namewidth, 2, B_FALSE);
|
||||
namewidth, 2, B_FALSE, name_flags);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
@ -4562,7 +4669,7 @@ status_callback(zpool_handle_t *zhp, void *data)
|
|||
ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
|
||||
print_scan_status(ps);
|
||||
|
||||
namewidth = max_width(zhp, nvroot, 0, 0);
|
||||
namewidth = max_width(zhp, nvroot, 0, 0, cbp->cb_name_flags);
|
||||
if (namewidth < 10)
|
||||
namewidth = 10;
|
||||
|
||||
|
@ -4570,17 +4677,20 @@ status_callback(zpool_handle_t *zhp, void *data)
|
|||
(void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
|
||||
"NAME", "STATE", "READ", "WRITE", "CKSUM");
|
||||
print_status_config(zhp, zpool_get_name(zhp), nvroot,
|
||||
namewidth, 0, B_FALSE);
|
||||
namewidth, 0, B_FALSE, cbp->cb_name_flags);
|
||||
|
||||
if (num_logs(nvroot) > 0)
|
||||
print_logs(zhp, nvroot, namewidth, B_TRUE);
|
||||
print_logs(zhp, nvroot, namewidth, B_TRUE,
|
||||
cbp->cb_name_flags);
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
|
||||
&l2cache, &nl2cache) == 0)
|
||||
print_l2cache(zhp, l2cache, nl2cache, namewidth);
|
||||
print_l2cache(zhp, l2cache, nl2cache, namewidth,
|
||||
cbp->cb_name_flags);
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
||||
&spares, &nspares) == 0)
|
||||
print_spares(zhp, spares, nspares, namewidth);
|
||||
print_spares(zhp, spares, nspares, namewidth,
|
||||
cbp->cb_name_flags);
|
||||
|
||||
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
|
||||
&nerr) == 0) {
|
||||
|
@ -4628,8 +4738,11 @@ status_callback(zpool_handle_t *zhp, void *data)
|
|||
}
|
||||
|
||||
/*
|
||||
* zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
|
||||
* zpool status [-gLPvx] [-T d|u] [pool] ... [interval [count]]
|
||||
*
|
||||
* -g Display guid for individual vdev name.
|
||||
* -L Follow links when resolving vdev path name.
|
||||
* -P Display full path for vdev name.
|
||||
* -v Display complete error logs
|
||||
* -x Display only pools with potential problems
|
||||
* -D Display dedup status (undocumented)
|
||||
|
@ -4646,8 +4759,17 @@ zpool_do_status(int argc, char **argv)
|
|||
status_cbdata_t cb = { 0 };
|
||||
|
||||
/* check options */
|
||||
while ((c = getopt(argc, argv, "vxDT:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "gLPvxDT:")) != -1) {
|
||||
switch (c) {
|
||||
case 'g':
|
||||
cb.cb_name_flags |= VDEV_NAME_GUID;
|
||||
break;
|
||||
case 'L':
|
||||
cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||
break;
|
||||
case 'P':
|
||||
cb.cb_name_flags |= VDEV_NAME_PATH;
|
||||
break;
|
||||
case 'v':
|
||||
cb.cb_verbose = B_TRUE;
|
||||
break;
|
||||
|
@ -5916,6 +6038,7 @@ main(int argc, char **argv)
|
|||
|
||||
(void) setlocale(LC_ALL, "");
|
||||
(void) textdomain(TEXT_DOMAIN);
|
||||
srand(time(NULL));
|
||||
|
||||
dprintf_setup(&argc, argv);
|
||||
|
||||
|
|
|
@ -1206,12 +1206,10 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
|||
|
||||
/*
|
||||
* Remove any previously existing symlink from a udev path to
|
||||
* the device before labeling the disk. This makes
|
||||
* zpool_label_disk_wait() truly wait for the new link to show
|
||||
* up instead of returning if it finds an old link still in
|
||||
* place. Otherwise there is a window between when udev
|
||||
* deletes and recreates the link during which access attempts
|
||||
* will fail with ENOENT.
|
||||
* the device before labeling the disk. This ensures that
|
||||
* only newly created links are used. Otherwise there is a
|
||||
* window between when udev deletes and recreates the link
|
||||
* during which access attempts will fail with ENOENT.
|
||||
*/
|
||||
strncpy(udevpath, path, MAXPATHLEN);
|
||||
(void) zfs_append_partition(udevpath, MAXPATHLEN);
|
||||
|
@ -1235,6 +1233,8 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
|||
* and then block until udev creates the new link.
|
||||
*/
|
||||
if (!is_exclusive || !is_spare(NULL, udevpath)) {
|
||||
char *devnode = strrchr(devpath, '/') + 1;
|
||||
|
||||
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
||||
if (ret == 0) {
|
||||
ret = lstat64(udevpath, &statbuf);
|
||||
|
@ -1242,18 +1242,29 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
|||
(void) unlink(udevpath);
|
||||
}
|
||||
|
||||
if (zpool_label_disk(g_zfs, zhp,
|
||||
strrchr(devpath, '/') + 1) == -1)
|
||||
/*
|
||||
* When labeling a pool the raw device node name
|
||||
* is provided as it appears under /dev/.
|
||||
*/
|
||||
if (zpool_label_disk(g_zfs, zhp, devnode) == -1)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Wait for udev to signal the device is available
|
||||
* by the provided path.
|
||||
*/
|
||||
ret = zpool_label_disk_wait(udevpath, DISK_LABEL_WAIT);
|
||||
if (ret) {
|
||||
(void) fprintf(stderr, gettext("cannot "
|
||||
"resolve path '%s': %d\n"), udevpath, ret);
|
||||
return (-1);
|
||||
(void) fprintf(stderr,
|
||||
gettext("missing link: %s was "
|
||||
"partitioned but %s is missing\n"),
|
||||
devnode, udevpath);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
(void) zero_label(udevpath);
|
||||
ret = zero_label(udevpath);
|
||||
if (ret)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
include $(top_srcdir)/config/Rules.am
|
||||
|
||||
AM_CFLAGS += $(DEBUG_STACKFLAGS) $(FRAME_LARGER_THAN)
|
||||
# -Wnoformat-truncation to get rid of compiler warning for unchecked
|
||||
# truncating snprintfs on gcc 7.1.1.
|
||||
AM_CFLAGS += $(DEBUG_STACKFLAGS) $(FRAME_LARGER_THAN) $(NO_FORMAT_TRUNCATION)
|
||||
|
||||
DEFAULT_INCLUDES += \
|
||||
-I$(top_srcdir)/include \
|
||||
|
|
|
@ -7,7 +7,8 @@ AM_CFLAGS += ${NO_BOOL_COMPARE}
|
|||
AM_CFLAGS += -fno-strict-aliasing
|
||||
AM_CPPFLAGS = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT
|
||||
AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64
|
||||
AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DTEXT_DOMAIN=\"zfs-linux-user\"
|
||||
AM_CPPFLAGS += -D_LARGEFILE64_SOURCE -DHAVE_LARGE_STACKS=1
|
||||
AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-linux-user\"
|
||||
AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
|
||||
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
||||
AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
|
||||
|
|
|
@ -39,6 +39,35 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_RELEASE], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 3.14 API change,
|
||||
dnl # set_cached_acl() and forget_cached_acl() changed from inline to
|
||||
dnl # EXPORT_SYMBOL. In the former case, they may not be usable because of
|
||||
dnl # posix_acl_release. In the latter case, we can always use them.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE], [
|
||||
AC_MSG_CHECKING([whether set_cached_acl() is usable])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/module.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/posix_acl.h>
|
||||
|
||||
MODULE_LICENSE("$ZFS_META_LICENSE");
|
||||
],[
|
||||
struct inode *ip = NULL;
|
||||
struct posix_acl *acl = posix_acl_alloc(1, 0);
|
||||
set_cached_acl(ip, ACL_TYPE_ACCESS, acl);
|
||||
forget_cached_acl(ip, ACL_TYPE_ACCESS);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SET_CACHED_ACL_USABLE, 1,
|
||||
[posix_acl_release() is usable])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 3.1 API change,
|
||||
dnl # posix_acl_chmod_masq() is not exported anymore and posix_acl_chmod()
|
||||
|
@ -75,27 +104,6 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CHMOD], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.30 API change,
|
||||
dnl # caching of ACL into the inode was added in this version.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_CACHING], [
|
||||
AC_MSG_CHECKING([whether inode has i_acl and i_default_acl])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
],[
|
||||
struct inode ino;
|
||||
ino.i_acl = NULL;
|
||||
ino.i_default_acl = NULL;
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_POSIX_ACL_CACHING, 1,
|
||||
[inode contains i_acl and i_default_acl])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 3.1 API change,
|
||||
dnl # posix_acl_equiv_mode now wants an umode_t* instead of a mode_t*
|
||||
|
@ -117,6 +125,30 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
|
|||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 4.8 API change,
|
||||
dnl # The function posix_acl_valid now must be passed a namespace.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS], [
|
||||
AC_MSG_CHECKING([whether posix_acl_valid() wants user namespace])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
#include <linux/posix_acl.h>
|
||||
],[
|
||||
struct user_namespace *user_ns = NULL;
|
||||
const struct posix_acl *acl = NULL;
|
||||
int error;
|
||||
|
||||
error = posix_acl_valid(user_ns, acl);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_POSIX_ACL_VALID_WITH_NS, 1,
|
||||
[posix_acl_valid() wants user namespace])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.27 API change,
|
||||
dnl # Check if inode_operations contains the function permission
|
||||
|
@ -247,18 +279,45 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
|||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.30 API change,
|
||||
dnl # current_umask exists only since this version.
|
||||
dnl # 3.14 API change,
|
||||
dnl # Check if inode_operations contains the function set_acl
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CURRENT_UMASK], [
|
||||
AC_MSG_CHECKING([whether current_umask exists])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
||||
AC_MSG_CHECKING([whether iops->set_acl() exists])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
|
||||
int set_acl_fn(struct inode *inode, struct posix_acl *acl, int type)
|
||||
{ return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.set_acl = set_acl_fn,
|
||||
};
|
||||
],[
|
||||
current_umask();
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_CURRENT_UMASK, 1, [current_umask() exists])
|
||||
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 4.7 API change,
|
||||
dnl # The kernel get_acl will now check cache before calling i_op->get_acl and
|
||||
dnl # do set_cached_acl after that, so i_op->get_acl don't need to do that
|
||||
dnl # anymore.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE], [
|
||||
AC_MSG_CHECKING([whether uncached_acl_sentinel() exists])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
],[
|
||||
void *sentinel __attribute__ ((unused)) = uncached_acl_sentinel(NULL);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_KERNEL_GET_ACL_HANDLE_CACHE, 1, [uncached_acl_sentinel() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
dnl #
|
||||
dnl # Linux 4.9-rc5+ ABI, removal of the .aio_fsync field
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
|
||||
AC_MSG_CHECKING([whether fops->aio_fsync() exists])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
|
||||
static const struct file_operations
|
||||
fops __attribute__ ((unused)) = {
|
||||
.aio_fsync = NULL,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_FILE_AIO_FSYNC, 1, [fops->aio_fsync() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
dnl #
|
||||
dnl # 2.6.32 - 2.6.33, bdi_setup_and_register() is not exported.
|
||||
dnl # 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
|
||||
dnl # 4.0 - x.y, bdi_setup_and_register() takes 2 arguments.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER], [
|
||||
AC_MSG_CHECKING([whether bdi_setup_and_register() wants 2 args])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/backing-dev.h>
|
||||
struct backing_dev_info bdi;
|
||||
], [
|
||||
char *name = "bdi";
|
||||
int error __attribute__((unused)) =
|
||||
bdi_setup_and_register(&bdi, name);
|
||||
], [bdi_setup_and_register], [mm/backing-dev.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_2ARGS_BDI_SETUP_AND_REGISTER, 1,
|
||||
[bdi_setup_and_register() wants 2 args])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether bdi_setup_and_register() wants 3 args])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/backing-dev.h>
|
||||
struct backing_dev_info bdi;
|
||||
], [
|
||||
char *name = "bdi";
|
||||
unsigned int cap = BDI_CAP_MAP_COPY;
|
||||
int error __attribute__((unused)) =
|
||||
bdi_setup_and_register(&bdi, name, cap);
|
||||
], [bdi_setup_and_register], [mm/backing-dev.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_3ARGS_BDI_SETUP_AND_REGISTER, 1,
|
||||
[bdi_setup_and_register() wants 3 args])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
])
|
|
@ -0,0 +1,56 @@
|
|||
dnl #
|
||||
dnl # 2.6.32 - 2.6.33, bdi_setup_and_register() is not exported.
|
||||
dnl # 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
|
||||
dnl # 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments.
|
||||
dnl # 4.12 - x.y, super_setup_bdi_name() new interface.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BDI], [
|
||||
AC_MSG_CHECKING([whether super_setup_bdi_name() exists])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/fs.h>
|
||||
struct super_block sb;
|
||||
], [
|
||||
char *name = "bdi";
|
||||
int error __attribute__((unused)) =
|
||||
super_setup_bdi_name(&sb, name);
|
||||
], [super_setup_bdi_name], [fs/super.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SUPER_SETUP_BDI_NAME, 1,
|
||||
[super_setup_bdi_name() exits])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether bdi_setup_and_register() wants 2 args])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/backing-dev.h>
|
||||
struct backing_dev_info bdi;
|
||||
], [
|
||||
char *name = "bdi";
|
||||
int error __attribute__((unused)) =
|
||||
bdi_setup_and_register(&bdi, name);
|
||||
], [bdi_setup_and_register], [mm/backing-dev.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_2ARGS_BDI_SETUP_AND_REGISTER, 1,
|
||||
[bdi_setup_and_register() wants 2 args])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether bdi_setup_and_register() wants 3 args])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/backing-dev.h>
|
||||
struct backing_dev_info bdi;
|
||||
], [
|
||||
char *name = "bdi";
|
||||
unsigned int cap = BDI_CAP_MAP_COPY;
|
||||
int error __attribute__((unused)) =
|
||||
bdi_setup_and_register(&bdi, name, cap);
|
||||
], [bdi_setup_and_register], [mm/backing-dev.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_3ARGS_BDI_SETUP_AND_REGISTER, 1,
|
||||
[bdi_setup_and_register() wants 3 args])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
|
@ -0,0 +1,84 @@
|
|||
dnl #
|
||||
dnl # Linux 4.8 API,
|
||||
dnl #
|
||||
dnl # The bio_op() helper was introduced as a replacement for explicitly
|
||||
dnl # checking the bio->bi_rw flags. The following checks are used to
|
||||
dnl # detect if a specific operation is supported.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_DISCARD], [
|
||||
AC_MSG_CHECKING([whether REQ_OP_DISCARD is defined])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/blk_types.h>
|
||||
],[
|
||||
int op __attribute__ ((unused)) = REQ_OP_DISCARD;
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_REQ_OP_DISCARD, 1,
|
||||
[REQ_OP_DISCARD is defined])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE], [
|
||||
AC_MSG_CHECKING([whether REQ_OP_SECURE_ERASE is defined])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/blk_types.h>
|
||||
],[
|
||||
int op __attribute__ ((unused)) = REQ_OP_SECURE_ERASE;
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_REQ_OP_SECURE_ERASE, 1,
|
||||
[REQ_OP_SECURE_ERASE is defined])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_REQ_OP_FLUSH], [
|
||||
AC_MSG_CHECKING([whether REQ_OP_FLUSH is defined])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/blk_types.h>
|
||||
],[
|
||||
int op __attribute__ ((unused)) = REQ_OP_FLUSH;
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_REQ_OP_FLUSH, 1,
|
||||
[REQ_OP_FLUSH is defined])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BIO_BI_OPF], [
|
||||
AC_MSG_CHECKING([whether bio->bi_opf is defined])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/bio.h>
|
||||
],[
|
||||
struct bio bio __attribute__ ((unused));
|
||||
bio.bi_opf = 0;
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BIO_BI_OPF, 1, [bio->bi_opf is defined])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS], [
|
||||
AC_MSG_CHECKING([whether bio_set_op_attrs is available])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/bio.h>
|
||||
],[
|
||||
struct bio *bio __attribute__ ((unused)) = NULL;
|
||||
|
||||
bio_set_op_attrs(bio, 0, 0);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BIO_SET_OP_ATTRS, 1,
|
||||
[bio_set_op_attrs is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -22,25 +22,64 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
|
|||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
|
||||
[blk_queue_flush() is available])
|
||||
|
||||
AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/module.h>
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
MODULE_LICENSE("$ZFS_META_LICENSE");
|
||||
],[
|
||||
struct request_queue *q = NULL;
|
||||
(void) blk_queue_flush(q, REQ_FLUSH);
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
|
||||
[blk_queue_flush() is GPL-only])
|
||||
])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
|
||||
dnl #
|
||||
dnl # 4.7 API change
|
||||
dnl # Replace blk_queue_flush with blk_queue_write_cache
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether blk_queue_write_cache() exists])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
MODULE_LICENSE("$ZFS_META_LICENSE");
|
||||
],[
|
||||
struct request_queue *q = NULL;
|
||||
(void) blk_queue_flush(q, REQ_FLUSH);
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
blk_queue_write_cache(q, true, true);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
|
||||
[blk_queue_flush() is GPL-only])
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE, 1,
|
||||
[blk_queue_write_cache() exists])
|
||||
|
||||
AC_MSG_CHECKING([whether blk_queue_write_cache() is GPL-only])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
MODULE_LICENSE("$ZFS_META_LICENSE");
|
||||
],[
|
||||
struct request_queue *q = NULL;
|
||||
blk_queue_write_cache(q, true, true);
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY, 1,
|
||||
[blk_queue_write_cache() is GPL-only])
|
||||
])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
EXTRA_KCFLAGS="$tmp_flags"
|
||||
])
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
dnl #
|
||||
dnl # 2.6.32-2.6.35 API - The BIO_RW_UNPLUG enum can be used as a hint
|
||||
dnl # to unplug the queue.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG], [
|
||||
AC_MSG_CHECKING([whether the BIO_RW_UNPLUG enum is available])
|
||||
tmp_flags="$EXTRA_KCFLAGS"
|
||||
EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
extern enum bio_rw_flags rw;
|
||||
|
||||
rw = BIO_RW_UNPLUG;
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG, 1,
|
||||
[BIO_RW_UNPLUG is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
EXTRA_KCFLAGS="$tmp_flags"
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG], [
|
||||
AC_MSG_CHECKING([whether struct blk_plug is available])
|
||||
tmp_flags="$EXTRA_KCFLAGS"
|
||||
EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/blkdev.h>
|
||||
],[
|
||||
struct blk_plug plug;
|
||||
|
||||
blk_start_plug(&plug);
|
||||
blk_finish_plug(&plug);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_BLK_QUEUE_HAVE_BLK_PLUG, 1,
|
||||
[struct blk_plug is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
EXTRA_KCFLAGS="$tmp_flags"
|
||||
])
|
|
@ -0,0 +1,19 @@
|
|||
dnl #
|
||||
dnl # 4.9, current_time() added
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME],
|
||||
[AC_MSG_CHECKING([whether current_time() exists])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/fs.h>
|
||||
], [
|
||||
struct inode ip;
|
||||
struct timespec now __attribute__ ((unused));
|
||||
|
||||
now = current_time(&ip);
|
||||
], [current_time], [fs/inode.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_CURRENT_TIME, 1, [current_time() exists])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -1,24 +0,0 @@
|
|||
dnl #
|
||||
dnl # 4.2 API change
|
||||
dnl # This kernel retired the nameidata structure which forced the
|
||||
dnl # restructuring of the follow_link() prototype and how it is called.
|
||||
dnl # We check for the new interface rather than detecting the old one.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [
|
||||
AC_MSG_CHECKING([whether iops->follow_link() passes nameidata])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
const char *follow_link(struct dentry *de, void **cookie)
|
||||
{ return "symlink"; }
|
||||
static struct inode_operations iops __attribute__ ((unused)) = {
|
||||
.follow_link = follow_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1,
|
||||
[iops->follow_link() nameidata])
|
||||
])
|
||||
])
|
|
@ -0,0 +1,22 @@
|
|||
dnl #
|
||||
dnl # 4.10 API
|
||||
dnl #
|
||||
dnl # NULL inode_operations.readlink implies generic_readlink(), which
|
||||
dnl # has been made static.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL], [
|
||||
AC_MSG_CHECKING([whether generic_readlink is global])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
],[
|
||||
int i __attribute__ ((unused));
|
||||
|
||||
i = generic_readlink(NULL, NULL, 0);
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_GENERIC_READLINK, 1,
|
||||
[generic_readlink is global])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
|
@ -0,0 +1,100 @@
|
|||
dnl #
|
||||
dnl # Supported get_link() interfaces checked newest to oldest.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_FOLLOW_LINK], [
|
||||
dnl #
|
||||
dnl # 4.2 API change
|
||||
dnl # - This kernel retired the nameidata structure.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether iops->follow_link() passes cookie])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
const char *follow_link(struct dentry *de,
|
||||
void **cookie) { return "symlink"; }
|
||||
static struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.follow_link = follow_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_FOLLOW_LINK_COOKIE, 1,
|
||||
[iops->follow_link() cookie])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.32 API
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether iops->follow_link() passes nameidata])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
void *follow_link(struct dentry *de, struct
|
||||
nameidata *nd) { return (void *)NULL; }
|
||||
static struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.follow_link = follow_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_FOLLOW_LINK_NAMEIDATA, 1,
|
||||
[iops->follow_link() nameidata])
|
||||
],[
|
||||
AC_MSG_ERROR(no; please file a bug report)
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_GET_LINK], [
|
||||
dnl #
|
||||
dnl # 4.5 API change
|
||||
dnl # The get_link interface has added a delayed done call and
|
||||
dnl # used it to retire the put_link() interface.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether iops->get_link() passes delayed])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
const char *get_link(struct dentry *de, struct inode *ip,
|
||||
struct delayed_call *done) { return "symlink"; }
|
||||
static struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.get_link = get_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GET_LINK_DELAYED, 1,
|
||||
[iops->get_link() delayed])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 4.5 API change
|
||||
dnl # The follow_link() interface has been replaced by
|
||||
dnl # get_link() which behaves the same as before except:
|
||||
dnl # - An inode is passed as a separate argument
|
||||
dnl # - When called in RCU mode a NULL dentry is passed.
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether iops->get_link() passes cookie])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
const char *get_link(struct dentry *de, struct
|
||||
inode *ip, void **cookie) { return "symlink"; }
|
||||
static struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.get_link = get_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GET_LINK_COOKIE, 1,
|
||||
[iops->get_link() cookie])
|
||||
],[
|
||||
dnl #
|
||||
dnl # Check for the follow_link APIs.
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
ZFS_AC_KERNEL_FOLLOW_LINK
|
||||
])
|
||||
])
|
||||
])
|
|
@ -0,0 +1,67 @@
|
|||
dnl #
|
||||
dnl # Linux 4.11 API
|
||||
dnl # See torvalds/linux@a528d35
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_PATH_KERNEL_IOPS_GETATTR], [
|
||||
AC_MSG_CHECKING([whether iops->getattr() takes a path])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
|
||||
int test_getattr(
|
||||
const struct path *p, struct kstat *k,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
{ return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.getattr = test_getattr,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
|
||||
[iops->getattr() takes a path])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
|
||||
dnl #
|
||||
dnl # Linux 3.9 - 4.10 API
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR], [
|
||||
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
|
||||
int test_getattr(
|
||||
struct vfsmount *mnt, struct dentry *d,
|
||||
struct kstat *k)
|
||||
{ return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.getattr = test_getattr,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
|
||||
[iops->getattr() takes a vfsmount])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
dnl #
|
||||
dnl # The interface of the getattr callback from the inode_operations
|
||||
dnl # structure changed. Also, the interface of the simple_getattr()
|
||||
dnl # function provided by the kernel changed.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR], [
|
||||
ZFS_AC_PATH_KERNEL_IOPS_GETATTR
|
||||
ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR
|
||||
])
|
|
@ -1,17 +1,29 @@
|
|||
dnl #
|
||||
dnl # 2.6.27 API change
|
||||
dnl # lookup_bdev() was exported.
|
||||
dnl # 2.6.27, lookup_bdev() was exported.
|
||||
dnl # 4.4.0-6.21 - x.y on Ubuntu, lookup_bdev() takes 2 arguments.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV],
|
||||
[AC_MSG_CHECKING([whether lookup_bdev() is available])
|
||||
[AC_MSG_CHECKING([whether lookup_bdev() wants 1 arg])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/fs.h>
|
||||
], [
|
||||
lookup_bdev(NULL);
|
||||
], [lookup_bdev], [fs/block_dev.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_LOOKUP_BDEV, 1, [lookup_bdev() is available])
|
||||
AC_DEFINE(HAVE_1ARG_LOOKUP_BDEV, 1, [lookup_bdev() wants 1 arg])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether lookup_bdev() wants 2 args])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/fs.h>
|
||||
], [
|
||||
lookup_bdev(NULL, FMODE_READ);
|
||||
], [lookup_bdev], [fs/block_dev.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_2ARGS_LOOKUP_BDEV, 1,
|
||||
[lookup_bdev() wants 2 args])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
])
|
|
@ -2,6 +2,9 @@ dnl #
|
|||
dnl # Linux 3.2 API Change
|
||||
dnl # make_request_fn returns void instead of int.
|
||||
dnl #
|
||||
dnl # Linux 4.4 API Change
|
||||
dnl # make_request_fn returns blk_qc_t.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
||||
AC_MSG_CHECKING([whether make_request_fn() returns int])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
|
@ -36,8 +39,27 @@ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
|||
AC_DEFINE(MAKE_REQUEST_FN_RET, void,
|
||||
[make_request_fn() returns void])
|
||||
],[
|
||||
AC_MSG_ERROR(no - Please file a bug report at
|
||||
https://github.com/zfsonlinux/zfs/issues/new)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether make_request_fn() returns blk_qc_t])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
blk_qc_t make_request(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
return (BLK_QC_T_NONE);
|
||||
}
|
||||
],[
|
||||
blk_queue_make_request(NULL, &make_request);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MAKE_REQUEST_FN_RET, blk_qc_t,
|
||||
[make_request_fn() returns blk_qc_t])
|
||||
AC_DEFINE(HAVE_MAKE_REQUEST_FN_RET_QC, 1,
|
||||
[Noting that make_request_fn() returns blk_qc_t])
|
||||
],[
|
||||
AC_MSG_ERROR(no - Please file a bug report at
|
||||
https://github.com/zfsonlinux/zfs/issues/new)
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
dnl #
|
||||
dnl # 4.2 API change
|
||||
dnl # This kernel retired the nameidata structure which forced the
|
||||
dnl # restructuring of the put_link() prototype and how it is called.
|
||||
dnl # We check for the new interface rather than detecting the old one.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [
|
||||
AC_MSG_CHECKING([whether iops->put_link() passes nameidata])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
void put_link(struct inode *ip, void *cookie) { return; }
|
||||
static struct inode_operations iops __attribute__ ((unused)) = {
|
||||
.put_link = put_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PUT_LINK_NAMEIDATA, 1,
|
||||
[iops->put_link() nameidata])
|
||||
])
|
||||
])
|
|
@ -0,0 +1,60 @@
|
|||
dnl #
|
||||
dnl # Supported symlink APIs
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_PUT_LINK], [
|
||||
dnl #
|
||||
dnl # 4.5 API change
|
||||
dnl # get_link() uses delayed done, there is no put_link() interface.
|
||||
dnl #
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#if !defined(HAVE_GET_LINK_DELAYED)
|
||||
#error "Expecting get_link() delayed done"
|
||||
#endif
|
||||
],[
|
||||
],[
|
||||
AC_DEFINE(HAVE_PUT_LINK_DELAYED, 1, [iops->put_link() delayed])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 4.2 API change
|
||||
dnl # This kernel retired the nameidata structure.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether iops->put_link() passes cookie])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
void put_link(struct inode *ip, void *cookie)
|
||||
{ return; }
|
||||
static struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.put_link = put_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PUT_LINK_COOKIE, 1,
|
||||
[iops->put_link() cookie])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.32 API
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether iops->put_link() passes nameidata])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
void put_link(struct dentry *de, struct
|
||||
nameidata *nd, void *ptr) { return; }
|
||||
static struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.put_link = put_link,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PUT_LINK_NAMEIDATA, 1,
|
||||
[iops->put_link() nameidata])
|
||||
],[
|
||||
AC_MSG_ERROR(no; please file a bug report)
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
|
@ -0,0 +1,25 @@
|
|||
dnl #
|
||||
dnl # 4.9 API change,
|
||||
dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
|
||||
dnl # flags.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
|
||||
AC_MSG_CHECKING([whether iops->rename() wants flags])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
int rename_fn(struct inode *sip, struct dentry *sdp,
|
||||
struct inode *tip, struct dentry *tdp,
|
||||
unsigned int flags) { return 0; }
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.rename = rename_fn,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1, [iops->rename() wants flags])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -0,0 +1,23 @@
|
|||
dnl #
|
||||
dnl # 4.9 API change
|
||||
dnl # The inode_change_ok() function has been renamed setattr_prepare()
|
||||
dnl # and updated to take a dentry rather than an inode.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE],
|
||||
[AC_MSG_CHECKING([whether setattr_prepare() is available])
|
||||
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||
#include <linux/fs.h>
|
||||
], [
|
||||
struct dentry *dentry = NULL;
|
||||
struct iattr *attr = NULL;
|
||||
int error;
|
||||
|
||||
error = setattr_prepare(dentry, attr);
|
||||
], [setattr_prepare], [fs/attr.c], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_SETATTR_PREPARE, 1,
|
||||
[setattr_prepare() is available])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -0,0 +1,20 @@
|
|||
dnl #
|
||||
dnl # 4.8 API change
|
||||
dnl # The rw argument has been removed from submit_bio/submit_bio_wait.
|
||||
dnl # Callers are now expected to set bio->bi_rw instead of passing it in.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SUBMIT_BIO], [
|
||||
AC_MSG_CHECKING([whether submit_bio() wants 1 arg])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/bio.h>
|
||||
],[
|
||||
blk_qc_t blk_qc;
|
||||
struct bio *bio = NULL;
|
||||
blk_qc = submit_bio(bio);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_1ARG_SUBMIT_BIO, 1, [submit_bio() wants 1 arg])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -1,8 +1,8 @@
|
|||
dnl #
|
||||
dnl # 3.11 API change
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
|
||||
AC_MSG_CHECKING([whether fops->iterate() is available])
|
||||
dnl #
|
||||
dnl # 4.7 API change
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether fops->iterate_shared() is available])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
int iterate(struct file *filp, struct dir_context * context)
|
||||
|
@ -10,34 +10,55 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
|
|||
|
||||
static const struct file_operations fops
|
||||
__attribute__ ((unused)) = {
|
||||
.iterate = iterate,
|
||||
.iterate_shared = iterate,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_VFS_ITERATE, 1,
|
||||
[fops->iterate() is available])
|
||||
AC_DEFINE(HAVE_VFS_ITERATE_SHARED, 1,
|
||||
[fops->iterate_shared() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
AC_MSG_CHECKING([whether fops->readdir() is available])
|
||||
dnl #
|
||||
dnl # 3.11 API change
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether fops->iterate() is available])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
int readdir(struct file *filp, void *entry, filldir_t func)
|
||||
int iterate(struct file *filp, struct dir_context * context)
|
||||
{ return 0; }
|
||||
|
||||
static const struct file_operations fops
|
||||
__attribute__ ((unused)) = {
|
||||
.readdir = readdir,
|
||||
.iterate = iterate,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_VFS_READDIR, 1,
|
||||
[fops->readdir() is available])
|
||||
AC_DEFINE(HAVE_VFS_ITERATE, 1,
|
||||
[fops->iterate() is available])
|
||||
],[
|
||||
AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
|
||||
])
|
||||
AC_MSG_RESULT(no)
|
||||
|
||||
AC_MSG_CHECKING([whether fops->readdir() is available])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
int readdir(struct file *filp, void *entry, filldir_t func)
|
||||
{ return 0; }
|
||||
|
||||
static const struct file_operations fops
|
||||
__attribute__ ((unused)) = {
|
||||
.readdir = readdir,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_VFS_READDIR, 1,
|
||||
[fops->readdir() is available])
|
||||
],[
|
||||
AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
dnl #
|
||||
dnl # Linux 4.1.x API
|
||||
dnl # Linux 3.16 API
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
|
||||
[AC_MSG_CHECKING([whether fops->read/write_iter() are available])
|
||||
|
@ -21,6 +21,47 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
|
|||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
|
||||
[fops->read/write_iter() are available])
|
||||
|
||||
ZFS_AC_KERNEL_NEW_SYNC_READ
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Linux 4.1 API
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ],
|
||||
[AC_MSG_CHECKING([whether new_sync_read() is available])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
],[
|
||||
new_sync_read(NULL, NULL, 0, NULL);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_NEW_SYNC_READ, 1,
|
||||
[new_sync_read() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Linux 4.1.x API
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS],
|
||||
[AC_MSG_CHECKING([whether generic_write_checks() takes kiocb])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
|
||||
],[
|
||||
struct kiocb *iocb = NULL;
|
||||
struct iov_iter *iov = NULL;
|
||||
generic_write_checks(iocb, iov);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GENERIC_WRITE_CHECKS_KIOCB, 1,
|
||||
[generic_write_checks() takes kiocb])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
|
|
@ -3,8 +3,8 @@ dnl # 2.6.35 API change,
|
|||
dnl # The 'struct xattr_handler' was constified in the generic
|
||||
dnl # super_block structure.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER],
|
||||
[AC_MSG_CHECKING([whether super_block uses const struct xattr_hander])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
|
||||
AC_MSG_CHECKING([whether super_block uses const struct xattr_handler])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
#include <linux/xattr.h>
|
||||
|
@ -26,24 +26,78 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER],
|
|||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_CONST_XATTR_HANDLER, 1,
|
||||
[super_block uses const struct xattr_hander])
|
||||
[super_block uses const struct xattr_handler])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.33 API change,
|
||||
dnl # The xattr_hander->get() callback was changed to take a dentry
|
||||
dnl # instead of an inode, and a handler_flags argument was added.
|
||||
dnl # 4.5 API change,
|
||||
dnl # struct xattr_handler added new member "name".
|
||||
dnl # xattr_handler which matches to whole name rather than prefix should use
|
||||
dnl # "name" instead of "prefix", e.g. "system.posix_acl_access"
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
|
||||
AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
|
||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
|
||||
AC_MSG_CHECKING([whether xattr_handler has name])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int get(struct dentry *dentry, const char *name,
|
||||
void *buffer, size_t size, int handler_flags) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.name = XATTR_NAME_POSIX_ACL_ACCESS,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_HANDLER_NAME, 1,
|
||||
[xattr_handler has name])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 4.9 API change,
|
||||
dnl # iops->{set,get,remove}xattr and generic_{set,get,remove}xattr are
|
||||
dnl # removed. xattr operations will directly go through sb->s_xattr.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR], [
|
||||
AC_MSG_CHECKING([whether generic_setxattr() exists])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/fs.h>
|
||||
#include <linux/xattr.h>
|
||||
|
||||
static const struct inode_operations
|
||||
iops __attribute__ ((unused)) = {
|
||||
.setxattr = generic_setxattr
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_GENERIC_SETXATTR, 1,
|
||||
[generic_setxattr() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Supported xattr handler get() interfaces checked newest to oldest.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
|
||||
dnl #
|
||||
dnl # 4.7 API change,
|
||||
dnl # The xattr_handler->get() callback was changed to take both
|
||||
dnl # dentry and inode.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether xattr_handler->get() wants both dentry and inode])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int get(const struct xattr_handler *handler,
|
||||
struct dentry *dentry, struct inode *inode,
|
||||
const char *name, void *buffer, size_t size) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.get = get,
|
||||
|
@ -51,26 +105,102 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
|
|||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_DENTRY_XATTR_GET, 1,
|
||||
[xattr_handler->get() wants dentry])
|
||||
AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
|
||||
[xattr_handler->get() wants both dentry and inode])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
dnl #
|
||||
dnl # 4.4 API change,
|
||||
dnl # The xattr_handler->get() callback was changed to take a
|
||||
dnl # attr_handler, and handler_flags argument was removed and
|
||||
dnl # should be accessed by handler->flags.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int get(const struct xattr_handler *handler,
|
||||
struct dentry *dentry, const char *name,
|
||||
void *buffer, size_t size) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.get = get,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
|
||||
[xattr_handler->get() wants xattr_handler])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.33 API change,
|
||||
dnl # The xattr_handler->get() callback was changed to take
|
||||
dnl # a dentry instead of an inode, and a handler_flags
|
||||
dnl # argument was added.
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int get(struct dentry *dentry, const char *name,
|
||||
void *buffer, size_t size, int handler_flags)
|
||||
{ return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.get = get,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
|
||||
[xattr_handler->get() wants dentry])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.32 API
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether xattr_handler->get() wants inode])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int get(struct inode *ip, const char *name,
|
||||
void *buffer, size_t size) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.get = get,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
|
||||
[xattr_handler->get() wants inode])
|
||||
],[
|
||||
AC_MSG_ERROR([no; please file a bug report])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.33 API change,
|
||||
dnl # The xattr_hander->set() callback was changed to take a dentry
|
||||
dnl # instead of an inode, and a handler_flags argument was added.
|
||||
dnl # Supported xattr handler set() interfaces checked newest to oldest.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
||||
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
|
||||
dnl #
|
||||
dnl # 4.7 API change,
|
||||
dnl # The xattr_handler->set() callback was changed to take both
|
||||
dnl # dentry and inode.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether xattr_handler->set() wants both dentry and inode])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int set(struct dentry *dentry, const char *name,
|
||||
const void *buffer, size_t size, int flags,
|
||||
int handler_flags) { return 0; }
|
||||
int set(const struct xattr_handler *handler,
|
||||
struct dentry *dentry, struct inode *inode,
|
||||
const char *name, const void *buffer,
|
||||
size_t size, int flags)
|
||||
{ return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.set = set,
|
||||
|
@ -78,26 +208,98 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
|||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_DENTRY_XATTR_SET, 1,
|
||||
[xattr_handler->set() wants dentry])
|
||||
AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
|
||||
[xattr_handler->set() wants both dentry and inode])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
dnl #
|
||||
dnl # 4.4 API change,
|
||||
dnl # The xattr_handler->set() callback was changed to take a
|
||||
dnl # xattr_handler, and handler_flags argument was removed and
|
||||
dnl # should be accessed by handler->flags.
|
||||
dnl #
|
||||
AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int set(const struct xattr_handler *handler,
|
||||
struct dentry *dentry, const char *name,
|
||||
const void *buffer, size_t size, int flags)
|
||||
{ return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.set = set,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
|
||||
[xattr_handler->set() wants xattr_handler])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.33 API change,
|
||||
dnl # The xattr_handler->set() callback was changed to take a
|
||||
dnl # dentry instead of an inode, and a handler_flags
|
||||
dnl # argument was added.
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int set(struct dentry *dentry, const char *name,
|
||||
const void *buffer, size_t size, int flags,
|
||||
int handler_flags) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.set = set,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
|
||||
[xattr_handler->set() wants dentry])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.32 API
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether xattr_handler->set() wants inode])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
int set(struct inode *ip, const char *name,
|
||||
const void *buffer, size_t size, int flags)
|
||||
{ return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.set = set,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
|
||||
[xattr_handler->set() wants inode])
|
||||
],[
|
||||
AC_MSG_ERROR([no; please file a bug report])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.33 API change,
|
||||
dnl # The xattr_hander->list() callback was changed to take a dentry
|
||||
dnl # instead of an inode, and a handler_flags argument was added.
|
||||
dnl # Supported xattr handler list() interfaces checked newest to oldest.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
|
||||
AC_MSG_CHECKING([whether xattr_handler->list() wants dentry])
|
||||
dnl # 4.5 API change,
|
||||
dnl # The xattr_handler->list() callback was changed to take only a
|
||||
dnl # dentry and it only needs to return if it's accessable.
|
||||
AC_MSG_CHECKING([whether xattr_handler->list() wants simple])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
size_t list(struct dentry *dentry, char *list, size_t list_size,
|
||||
const char *name, size_t name_len, int handler_flags)
|
||||
{ return 0; }
|
||||
bool list(struct dentry *dentry) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.list = list,
|
||||
|
@ -105,10 +307,87 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
|
|||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_DENTRY_XATTR_LIST, 1,
|
||||
[xattr_handler->list() wants dentry])
|
||||
AC_DEFINE(HAVE_XATTR_LIST_SIMPLE, 1,
|
||||
[xattr_handler->list() wants simple])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 4.4 API change,
|
||||
dnl # The xattr_handler->list() callback was changed to take a
|
||||
dnl # xattr_handler, and handler_flags argument was removed
|
||||
dnl # and should be accessed by handler->flags.
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether xattr_handler->list() wants xattr_handler])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
size_t list(const struct xattr_handler *handler,
|
||||
struct dentry *dentry, char *list, size_t list_size,
|
||||
const char *name, size_t name_len) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.list = list,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_LIST_HANDLER, 1,
|
||||
[xattr_handler->list() wants xattr_handler])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.33 API change,
|
||||
dnl # The xattr_handler->list() callback was changed
|
||||
dnl # to take a dentry instead of an inode, and a
|
||||
dnl # handler_flags argument was added.
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether xattr_handler->list() wants dentry])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
size_t list(struct dentry *dentry,
|
||||
char *list, size_t list_size,
|
||||
const char *name, size_t name_len,
|
||||
int handler_flags) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.list = list,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_LIST_DENTRY, 1,
|
||||
[xattr_handler->list() wants dentry])
|
||||
],[
|
||||
dnl #
|
||||
dnl # 2.6.32 API
|
||||
dnl #
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(
|
||||
[whether xattr_handler->list() wants inode])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/xattr.h>
|
||||
|
||||
size_t list(struct inode *ip, char *lst,
|
||||
size_t list_size, const char *name,
|
||||
size_t name_len) { return 0; }
|
||||
static const struct xattr_handler
|
||||
xops __attribute__ ((unused)) = {
|
||||
.list = list,
|
||||
};
|
||||
],[
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_XATTR_LIST_INODE, 1,
|
||||
[xattr_handler->list() wants inode])
|
||||
],[
|
||||
AC_MSG_ERROR(
|
||||
[no; please file a bug report])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||
ZFS_AC_KERNEL_CONFIG
|
||||
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
|
||||
ZFS_AC_KERNEL_CURRENT_BIO_TAIL
|
||||
ZFS_AC_KERNEL_SUBMIT_BIO
|
||||
ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||
ZFS_AC_KERNEL_TYPE_FMODE_T
|
||||
|
@ -22,31 +23,43 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||
ZFS_AC_KERNEL_BIO_BVEC_ITER
|
||||
ZFS_AC_KERNEL_BIO_FAILFAST_DTD
|
||||
ZFS_AC_KERNEL_REQ_FAILFAST_MASK
|
||||
ZFS_AC_KERNEL_REQ_OP_DISCARD
|
||||
ZFS_AC_KERNEL_REQ_OP_SECURE_ERASE
|
||||
ZFS_AC_KERNEL_REQ_OP_FLUSH
|
||||
ZFS_AC_KERNEL_BIO_BI_OPF
|
||||
ZFS_AC_KERNEL_BIO_END_IO_T_ARGS
|
||||
ZFS_AC_KERNEL_BIO_RW_BARRIER
|
||||
ZFS_AC_KERNEL_BIO_RW_DISCARD
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_FLUSH
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BIO_RW_UNPLUG
|
||||
ZFS_AC_KERNEL_BLK_QUEUE_HAVE_BLK_PLUG
|
||||
ZFS_AC_KERNEL_GET_DISK_RO
|
||||
ZFS_AC_KERNEL_GET_GENDISK
|
||||
ZFS_AC_KERNEL_HAVE_BIO_SET_OP_ATTRS
|
||||
ZFS_AC_KERNEL_GENERIC_READLINK_GLOBAL
|
||||
ZFS_AC_KERNEL_DISCARD_GRANULARITY
|
||||
ZFS_AC_KERNEL_CONST_XATTR_HANDLER
|
||||
ZFS_AC_KERNEL_XATTR_HANDLER_NAME
|
||||
ZFS_AC_KERNEL_XATTR_HANDLER_GET
|
||||
ZFS_AC_KERNEL_XATTR_HANDLER_SET
|
||||
ZFS_AC_KERNEL_XATTR_HANDLER_LIST
|
||||
ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
|
||||
ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
|
||||
ZFS_AC_KERNEL_POSIX_ACL_RELEASE
|
||||
ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE
|
||||
ZFS_AC_KERNEL_POSIX_ACL_CHMOD
|
||||
ZFS_AC_KERNEL_POSIX_ACL_CACHING
|
||||
ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
|
||||
ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
|
||||
ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
|
||||
ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
|
||||
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
|
||||
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
|
||||
ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
|
||||
ZFS_AC_KERNEL_CURRENT_UMASK
|
||||
ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
|
||||
ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR
|
||||
ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
|
||||
ZFS_AC_KERNEL_SHOW_OPTIONS
|
||||
ZFS_AC_KERNEL_FILE_INODE
|
||||
ZFS_AC_KERNEL_FSYNC
|
||||
|
@ -55,16 +68,18 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||
ZFS_AC_KERNEL_NR_CACHED_OBJECTS
|
||||
ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
|
||||
ZFS_AC_KERNEL_FALLOCATE
|
||||
ZFS_AC_KERNEL_AIO_FSYNC
|
||||
ZFS_AC_KERNEL_MKDIR_UMODE_T
|
||||
ZFS_AC_KERNEL_LOOKUP_NAMEIDATA
|
||||
ZFS_AC_KERNEL_CREATE_NAMEIDATA
|
||||
ZFS_AC_KERNEL_FOLLOW_LINK
|
||||
ZFS_AC_KERNEL_GET_LINK
|
||||
ZFS_AC_KERNEL_PUT_LINK
|
||||
ZFS_AC_KERNEL_TRUNCATE_RANGE
|
||||
ZFS_AC_KERNEL_AUTOMOUNT
|
||||
ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE
|
||||
ZFS_AC_KERNEL_COMMIT_METADATA
|
||||
ZFS_AC_KERNEL_CLEAR_INODE
|
||||
ZFS_AC_KERNEL_SETATTR_PREPARE
|
||||
ZFS_AC_KERNEL_INSERT_INODE_LOCKED
|
||||
ZFS_AC_KERNEL_D_MAKE_ROOT
|
||||
ZFS_AC_KERNEL_D_OBTAIN_ALIAS
|
||||
|
@ -81,17 +96,21 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
|||
ZFS_AC_KERNEL_SHRINK_CONTROL_HAS_NID
|
||||
ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD
|
||||
ZFS_AC_KERNEL_S_D_OP
|
||||
ZFS_AC_KERNEL_BDI_SETUP_AND_REGISTER
|
||||
ZFS_AC_KERNEL_BDI
|
||||
ZFS_AC_KERNEL_SET_NLINK
|
||||
ZFS_AC_KERNEL_ELEVATOR_CHANGE
|
||||
ZFS_AC_KERNEL_5ARG_SGET
|
||||
ZFS_AC_KERNEL_LSEEK_EXECUTE
|
||||
ZFS_AC_KERNEL_VFS_ITERATE
|
||||
ZFS_AC_KERNEL_VFS_RW_ITERATE
|
||||
ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS
|
||||
ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
|
||||
ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
|
||||
ZFS_AC_KERNEL_MAKE_REQUEST_FN
|
||||
ZFS_AC_KERNEL_GENERIC_IO_ACCT
|
||||
ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
|
||||
ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR
|
||||
ZFS_AC_KERNEL_CURRENT_TIME
|
||||
|
||||
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
|
||||
KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
|
||||
|
@ -448,21 +467,49 @@ dnl # detected at configure time and cause a build failure. Otherwise
|
|||
dnl # modules may be successfully built that behave incorrectly.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG], [
|
||||
AC_RUN_IFELSE([
|
||||
AC_LANG_PROGRAM([
|
||||
#include "$LINUX/include/linux/license.h"
|
||||
AS_IF([test "x$cross_compiling" != xyes], [
|
||||
AC_RUN_IFELSE([
|
||||
AC_LANG_PROGRAM([
|
||||
#include "$LINUX/include/linux/license.h"
|
||||
], [
|
||||
return !license_is_gpl_compatible("$ZFS_META_LICENSE");
|
||||
])
|
||||
], [
|
||||
AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1],
|
||||
[Define to 1 if GPL-only symbols can be used])
|
||||
], [
|
||||
return !license_is_gpl_compatible("$ZFS_META_LICENSE");
|
||||
])
|
||||
], [
|
||||
AC_DEFINE([ZFS_IS_GPL_COMPATIBLE], [1],
|
||||
[Define to 1 if GPL-only symbols can be used])
|
||||
], [
|
||||
])
|
||||
|
||||
ZFS_AC_KERNEL_CONFIG_THREAD_SIZE
|
||||
ZFS_AC_KERNEL_CONFIG_DEBUG_LOCK_ALLOC
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check configured THREAD_SIZE
|
||||
dnl #
|
||||
dnl # The stack size will vary by architecture, but as of Linux 3.15 on x86_64
|
||||
dnl # the default thread stack size was increased to 16K from 8K. Therefore,
|
||||
dnl # on newer kernels and some architectures stack usage optimizations can be
|
||||
dnl # conditionally applied to improve performance without negatively impacting
|
||||
dnl # stability.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG_THREAD_SIZE], [
|
||||
AC_MSG_CHECKING([whether kernel was built with 16K or larger stacks])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/module.h>
|
||||
],[
|
||||
#if (THREAD_SIZE < 16384)
|
||||
#error "THREAD_SIZE is less than 16K"
|
||||
#endif
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_LARGE_STACKS, 1, [kernel has large stacks])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # Check CONFIG_DEBUG_LOCK_ALLOC
|
||||
dnl #
|
||||
|
@ -572,7 +619,7 @@ dnl #
|
|||
dnl # ZFS_LINUX_CONFIG
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_LINUX_CONFIG],
|
||||
[AC_MSG_CHECKING([whether Linux was built with CONFIG_$1])
|
||||
[AC_MSG_CHECKING([whether kernel was built with CONFIG_$1])
|
||||
ZFS_LINUX_TRY_COMPILE([
|
||||
#include <linux/module.h>
|
||||
],[
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
dnl #
|
||||
dnl # glibc 2.25
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS], [
|
||||
AC_MSG_CHECKING([makedev() is declared in sys/sysmacros.h])
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
#include <sys/sysmacros.h>
|
||||
],[
|
||||
int k;
|
||||
k = makedev(0,0);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_MAKEDEV_IN_SYSMACROS, 1,
|
||||
[makedev() is declared in sys/sysmacros.h])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # glibc X < Y < 2.25
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV], [
|
||||
AC_MSG_CHECKING([makedev() is declared in sys/mkdev.h])
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
#include <sys/mkdev.h>
|
||||
],[
|
||||
int k;
|
||||
k = makedev(0,0);
|
||||
],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_MAKEDEV_IN_MKDEV, 1,
|
||||
[makedev() is declared in sys/mkdev.h])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
|
@ -0,0 +1,22 @@
|
|||
dnl #
|
||||
dnl # Check if gcc supports -Wno-format-truncation option.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_CONFIG_USER_NO_FORMAT_TRUNCATION], [
|
||||
AC_MSG_CHECKING([for -Wno-format-truncation support])
|
||||
|
||||
saved_flags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Wno-format-truncation"
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])],
|
||||
[
|
||||
NO_FORMAT_TRUNCATION=-Wno-format-truncation
|
||||
AC_MSG_RESULT([yes])
|
||||
],
|
||||
[
|
||||
NO_FORMAT_TRUNCATION=
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
CFLAGS="$saved_flags"
|
||||
AC_SUBST([NO_FORMAT_TRUNCATION])
|
||||
])
|
|
@ -13,6 +13,9 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
|
|||
ZFS_AC_CONFIG_USER_LIBBLKID
|
||||
ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
|
||||
ZFS_AC_CONFIG_USER_RUNSTATEDIR
|
||||
ZFS_AC_CONFIG_USER_MAKEDEV_IN_SYSMACROS
|
||||
ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV
|
||||
ZFS_AC_CONFIG_USER_NO_FORMAT_TRUNCATION
|
||||
dnl #
|
||||
dnl # Checks for library functions
|
||||
AC_CHECK_FUNCS([mlockall])
|
||||
|
|
|
@ -55,6 +55,8 @@ adjust_obj_paths()
|
|||
for MODULE in "${MODULES[@]}"
|
||||
do
|
||||
adjust_obj_paths "$KERNEL_DIR/fs/zfs/$MODULE/Makefile"
|
||||
sed -i.bak '/obj =/d' "$KERNEL_DIR/fs/zfs/$MODULE/Makefile"
|
||||
sed -i.bak '/src =/d' "$KERNEL_DIR/fs/zfs/$MODULE/Makefile"
|
||||
done
|
||||
|
||||
cat > "$KERNEL_DIR/fs/zfs/Kconfig" <<"EOF"
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#!@SHELL@
|
||||
#
|
||||
# zfs-import This script will import/export zfs pools.
|
||||
# zfs-import This script will import ZFS pools
|
||||
#
|
||||
# chkconfig: 2345 01 99
|
||||
# description: This script will import/export zfs pools during system
|
||||
# boot/shutdown.
|
||||
# It is also responsible for all userspace zfs services.
|
||||
# description: This script will perform a verbatim import of ZFS pools
|
||||
# during system boot.
|
||||
# probe: true
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
|
@ -17,7 +16,7 @@
|
|||
# X-Start-Before: checkfs
|
||||
# X-Stop-After: zfs-mount
|
||||
# Short-Description: Import ZFS pools
|
||||
# Description: Run the `zpool import` or `zpool export` commands.
|
||||
# Description: Run the `zpool import` command.
|
||||
### END INIT INFO
|
||||
#
|
||||
# NOTE: Not having '$local_fs' on Required-Start but only on Required-Stop
|
||||
|
@ -43,6 +42,16 @@ do_depend()
|
|||
keyword -lxc -openvz -prefix -vserver
|
||||
}
|
||||
|
||||
# Use the zpool cache file to import pools
|
||||
do_verbatim_import()
|
||||
{
|
||||
if [ -f "$ZPOOL_CACHE" ]
|
||||
then
|
||||
zfs_action "Importing ZFS pool(s)" \
|
||||
"$ZPOOL" import -c "$ZPOOL_CACHE" -N -a
|
||||
fi
|
||||
}
|
||||
|
||||
# Support function to get a list of all pools, separated with ';'
|
||||
find_pools()
|
||||
{
|
||||
|
@ -60,8 +69,8 @@ find_pools()
|
|||
echo "${pools%%;}" # Return without the last ';'.
|
||||
}
|
||||
|
||||
# Import all pools
|
||||
do_import()
|
||||
# Find and import all visible pools, even exported ones
|
||||
do_import_all_visible()
|
||||
{
|
||||
local already_imported available_pools pool npools
|
||||
local exception dir ZPOOL_IMPORT_PATH RET=0 r=1
|
||||
|
@ -109,7 +118,7 @@ do_import()
|
|||
fi
|
||||
fi
|
||||
|
||||
# Filter out any exceptions...
|
||||
# Filter out any exceptions...
|
||||
if [ -n "$ZFS_POOL_EXCEPTIONS" ]
|
||||
then
|
||||
local found=""
|
||||
|
@ -249,41 +258,15 @@ do_import()
|
|||
return "$RET"
|
||||
}
|
||||
|
||||
# Export all pools
|
||||
do_export()
|
||||
do_import()
|
||||
{
|
||||
local already_imported pool root_pool RET r
|
||||
RET=0
|
||||
|
||||
root_pool=$(get_root_pool)
|
||||
|
||||
[ -n "$init" ] && zfs_log_begin_msg "Exporting ZFS pool(s)"
|
||||
|
||||
# Find list of already imported pools.
|
||||
already_imported=$(find_pools "$ZPOOL" list -H -oname)
|
||||
|
||||
OLD_IFS="$IFS" ; IFS=";"
|
||||
for pool in $already_imported; do
|
||||
[ "$pool" = "$root_pool" ] && continue
|
||||
|
||||
if [ -z "$init" ]
|
||||
then
|
||||
# Interactive - one 'Importing ...' line per pool
|
||||
zfs_log_begin_msg "Exporting ZFS pool $pool"
|
||||
else
|
||||
# Not interactive - a dot for each pool.
|
||||
zfs_log_progress_msg "."
|
||||
fi
|
||||
|
||||
"$ZPOOL" export "$pool"
|
||||
r="$?" ; RET=$((RET + r))
|
||||
[ -z "$init" ] && zfs_log_end_msg "$r"
|
||||
done
|
||||
IFS="$OLD_IFS"
|
||||
|
||||
[ -n "$init" ] && zfs_log_end_msg "$RET"
|
||||
|
||||
return "$RET"
|
||||
if check_boolean "$ZPOOL_IMPORT_ALL_VISIBLE"
|
||||
then
|
||||
do_import_all_visible
|
||||
else
|
||||
# This is the default option
|
||||
do_verbatim_import
|
||||
fi
|
||||
}
|
||||
|
||||
# Output the status and list of pools
|
||||
|
@ -323,14 +306,6 @@ do_start()
|
|||
fi
|
||||
}
|
||||
|
||||
do_stop()
|
||||
{
|
||||
# Check to see if the module is even loaded.
|
||||
check_module_loaded "zfs" || exit 0
|
||||
|
||||
do_export
|
||||
}
|
||||
|
||||
# ----------------------------------------------------
|
||||
|
||||
if [ ! -e /etc/gentoo-release ]
|
||||
|
@ -340,7 +315,7 @@ then
|
|||
do_start
|
||||
;;
|
||||
stop)
|
||||
do_stop
|
||||
# no-op
|
||||
;;
|
||||
status)
|
||||
do_status
|
||||
|
@ -350,7 +325,7 @@ then
|
|||
;;
|
||||
*)
|
||||
[ -n "$1" ] && echo "Error: Unknown command $1."
|
||||
echo "Usage: $0 {start|stop|status}"
|
||||
echo "Usage: $0 {start|status}"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
@ -360,6 +335,5 @@ else
|
|||
# Create wrapper functions since Gentoo don't use the case part.
|
||||
depend() { do_depend; }
|
||||
start() { do_start; }
|
||||
stop() { do_stop; }
|
||||
status() { do_status; }
|
||||
fi
|
||||
|
|
|
@ -16,6 +16,24 @@ ZFS_SHARE='yes'
|
|||
# Run `zfs unshare -a` during system stop?
|
||||
ZFS_UNSHARE='yes'
|
||||
|
||||
# By default, a verbatim import of all pools is performed at boot based on the
|
||||
# contents of the default zpool cache file. The contents of the cache are
|
||||
# managed automatically by the 'zpool import' and 'zpool export' commands.
|
||||
#
|
||||
# By setting this to 'yes', the system will instead search all devices for
|
||||
# pools and attempt to import them all at boot, even those that have been
|
||||
# exported. Under this mode, the search path can be controlled by the
|
||||
# ZPOOL_IMPORT_PATH variable and a list of pools that should not be imported
|
||||
# can be listed in the ZFS_POOL_EXCEPTIONS variable.
|
||||
#
|
||||
# Note that importing all visible pools may include pools that you don't
|
||||
# expect, such as those on removable devices and SANs, and those pools may
|
||||
# proceed to mount themselves in places you do not want them to. The results
|
||||
# can be unpredictable and possibly dangerous. Only enable this option if you
|
||||
# understand this risk and have complete physical control over your system and
|
||||
# SAN to prevent the insertion of malicious pools.
|
||||
ZPOOL_IMPORT_ALL_VISIBLE='no'
|
||||
|
||||
# Specify specific path(s) to look for device nodes and/or links for the
|
||||
# pool import(s). See zpool(8) for more information about this variable.
|
||||
# It supersedes the old USE_DISK_BY_ID which indicated that it would only
|
||||
|
@ -23,6 +41,18 @@ ZFS_UNSHARE='yes'
|
|||
# The old variable will still work in the code, but is deprecated.
|
||||
#ZPOOL_IMPORT_PATH="/dev/disk/by-vdev:/dev/disk/by-id"
|
||||
|
||||
# List of pools that should NOT be imported at boot
|
||||
# when ZPOOL_IMPORT_ALL_VISIBLE is 'yes'.
|
||||
# This is a space separated list.
|
||||
#ZFS_POOL_EXCEPTIONS="test2"
|
||||
|
||||
# List of pools that SHOULD be imported at boot by the initramfs
|
||||
# instead of trying to import all available pools. If this is set
|
||||
# then ZFS_POOL_EXCEPTIONS is ignored.
|
||||
# Only applicable for Debian GNU/Linux {dkms,initramfs}.
|
||||
# This is a semi-colon separated list.
|
||||
#ZFS_POOL_IMPORT="pool1;pool2"
|
||||
|
||||
# Should the datasets be mounted verbosely?
|
||||
# A mount counter will be used when mounting if set to 'yes'.
|
||||
VERBOSE_MOUNT='no'
|
||||
|
@ -97,17 +127,6 @@ ZFS_INITRD_POST_MODPROBE_SLEEP='0'
|
|||
# Example: If root FS is 'rpool/ROOT/rootfs', this would make sense.
|
||||
#ZFS_INITRD_ADDITIONAL_DATASETS="rpool/ROOT/usr rpool/ROOT/var"
|
||||
|
||||
# List of pools that should NOT be imported at boot?
|
||||
# This is a space separated list.
|
||||
#ZFS_POOL_EXCEPTIONS="test2"
|
||||
|
||||
# List of pools to import?
|
||||
# If this variable is set, there will be NO auto-import of ANY other
|
||||
# pool. In essence, there will be no auto detection of availible pools.
|
||||
# This is a semi-colon separated list.
|
||||
# Makes the variable ZFS_POOL_EXCEPTIONS above redundant (won't be checked).
|
||||
#ZFS_POOL_IMPORT="pool1;pool2"
|
||||
|
||||
# Optional arguments for the ZFS Event Daemon (ZED).
|
||||
# See zed(8) for more information on available options.
|
||||
#ZED_ARGS="-M"
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
zfs
|
||||
# Always load kernel modules at boot. The default behavior is to load the
|
||||
# kernel modules in the zfs-import-*.service or when blkid(8) detects a pool.
|
||||
#zfs
|
||||
|
|
|
@ -1,2 +1,7 @@
|
|||
# ZFS is enabled by default
|
||||
enable zfs.*
|
||||
enable zfs-import-cache.service
|
||||
disable zfs-import-scan.service
|
||||
enable zfs-mount.service
|
||||
enable zfs-share.service
|
||||
enable zfs-zed.service
|
||||
enable zfs.target
|
||||
|
|
|
@ -2,7 +2,7 @@ systemdpreset_DATA = \
|
|||
50-zfs.preset
|
||||
|
||||
systemdunit_DATA = \
|
||||
zed.service \
|
||||
zfs-zed.service \
|
||||
zfs-import-cache.service \
|
||||
zfs-import-scan.service \
|
||||
zfs-mount.service \
|
||||
|
@ -10,7 +10,7 @@ systemdunit_DATA = \
|
|||
zfs.target
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(top_srcdir)/etc/systemd/system/zed.service.in \
|
||||
$(top_srcdir)/etc/systemd/system/zfs-zed.service.in \
|
||||
$(top_srcdir)/etc/systemd/system/zfs-import-cache.service.in \
|
||||
$(top_srcdir)/etc/systemd/system/zfs-import-scan.service.in \
|
||||
$(top_srcdir)/etc/systemd/system/zfs-mount.service.in \
|
||||
|
|
|
@ -4,6 +4,7 @@ DefaultDependencies=no
|
|||
Requires=systemd-udev-settle.service
|
||||
After=systemd-udev-settle.service
|
||||
After=cryptsetup.target
|
||||
After=systemd-remount-fs.service
|
||||
ConditionPathExists=@sysconfdir@/zfs/zpool.cache
|
||||
|
||||
[Service]
|
||||
|
@ -11,3 +12,7 @@ Type=oneshot
|
|||
RemainAfterExit=yes
|
||||
ExecStartPre=/sbin/modprobe zfs
|
||||
ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN
|
||||
|
||||
[Install]
|
||||
WantedBy=zfs-mount.service
|
||||
WantedBy=zfs.target
|
||||
|
|
|
@ -10,4 +10,8 @@ ConditionPathExists=!@sysconfdir@/zfs/zpool.cache
|
|||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStartPre=/sbin/modprobe zfs
|
||||
ExecStart=@sbindir@/zpool import -d /dev/disk/by-id -aN
|
||||
ExecStart=@sbindir@/zpool import -aN -o cachefile=none
|
||||
|
||||
[Install]
|
||||
WantedBy=zfs-mount.service
|
||||
WantedBy=zfs.target
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
[Unit]
|
||||
Description=Mount ZFS filesystems
|
||||
DefaultDependencies=no
|
||||
Wants=zfs-import-cache.service
|
||||
Wants=zfs-import-scan.service
|
||||
Requires=systemd-udev-settle.service
|
||||
After=systemd-udev-settle.service
|
||||
After=zfs-import-cache.service
|
||||
After=zfs-import-scan.service
|
||||
After=systemd-remount-fs.service
|
||||
Before=local-fs.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=@sbindir@/zfs mount -a
|
||||
WorkingDirectory=-/sbin/
|
||||
|
||||
[Install]
|
||||
WantedBy=zfs-share.service
|
||||
WantedBy=zfs.target
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
[Unit]
|
||||
Description=ZFS file system shares
|
||||
After=nfs-server.service
|
||||
After=nfs-server.service nfs-kernel-server.service
|
||||
After=smb.service
|
||||
After=zfs-mount.service
|
||||
Requires=zfs-mount.service
|
||||
PartOf=nfs-server.service
|
||||
PartOf=nfs-server.service nfs-kernel-server.service
|
||||
PartOf=smb.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStartPre=-@bindir@/rm /etc/dfs/sharetab
|
||||
ExecStartPre=-@bindir@/rm -f /etc/dfs/sharetab
|
||||
ExecStart=@sbindir@/zfs share -a
|
||||
|
||||
[Install]
|
||||
WantedBy=zfs.target
|
||||
|
|
|
@ -7,3 +7,7 @@ After=zfs-import-scan.service
|
|||
[Service]
|
||||
ExecStart=@sbindir@/zed -F
|
||||
Restart=on-abort
|
||||
|
||||
[Install]
|
||||
Alias=zed.service
|
||||
WantedBy=zfs.target
|
|
@ -1,8 +1,5 @@
|
|||
[Unit]
|
||||
Description=ZFS startup target
|
||||
Requires=zfs-mount.service
|
||||
Requires=zfs-share.service
|
||||
Wants=zed.service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
|
@ -248,6 +248,7 @@ typedef struct splitflags {
|
|||
|
||||
/* after splitting, import the pool */
|
||||
int import : 1;
|
||||
int name_flags;
|
||||
} splitflags_t;
|
||||
|
||||
/*
|
||||
|
@ -406,8 +407,15 @@ struct zfs_cmd;
|
|||
|
||||
extern const char *zfs_history_event_names[];
|
||||
|
||||
typedef enum {
|
||||
VDEV_NAME_PATH = 1 << 0,
|
||||
VDEV_NAME_GUID = 1 << 1,
|
||||
VDEV_NAME_FOLLOW_LINKS = 1 << 2,
|
||||
VDEV_NAME_TYPE_ID = 1 << 3,
|
||||
} vdev_name_t;
|
||||
|
||||
extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *,
|
||||
boolean_t verbose);
|
||||
int name_flags);
|
||||
extern int zpool_upgrade(zpool_handle_t *, uint64_t);
|
||||
extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
|
||||
extern int zpool_history_unpack(char *, uint64_t, uint64_t *,
|
||||
|
|
|
@ -46,11 +46,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef VERIFY
|
||||
#undef VERIFY
|
||||
#endif
|
||||
#define VERIFY verify
|
||||
|
||||
typedef struct libzfs_fru {
|
||||
char *zf_device;
|
||||
char *zf_fru;
|
||||
|
|
|
@ -37,21 +37,48 @@ typedef unsigned __bitwise__ fmode_t;
|
|||
#endif /* HAVE_FMODE_T */
|
||||
|
||||
/*
|
||||
* 2.6.36 API change,
|
||||
* 4.7 - 4.x API,
|
||||
* The blk_queue_write_cache() interface has replaced blk_queue_flush()
|
||||
* interface. However, the new interface is GPL-only thus we implement
|
||||
* our own trivial wrapper when the GPL-only version is detected.
|
||||
*
|
||||
* 2.6.36 - 4.6 API,
|
||||
* The blk_queue_flush() interface has replaced blk_queue_ordered()
|
||||
* interface. However, while the old interface was available to all the
|
||||
* new one is GPL-only. Thus if the GPL-only version is detected we
|
||||
* implement our own trivial helper compatibility funcion. The hope is
|
||||
* that long term this function will be opened up.
|
||||
* implement our own trivial helper.
|
||||
*
|
||||
* 2.6.x - 2.6.35
|
||||
* Legacy blk_queue_ordered() interface.
|
||||
*/
|
||||
#if defined(HAVE_BLK_QUEUE_FLUSH) && defined(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY)
|
||||
#define blk_queue_flush __blk_queue_flush
|
||||
static inline void
|
||||
__blk_queue_flush(struct request_queue *q, unsigned int flags)
|
||||
blk_queue_set_write_cache(struct request_queue *q, bool wc, bool fua)
|
||||
{
|
||||
q->flush_flags = flags & (REQ_FLUSH | REQ_FUA);
|
||||
#if defined(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY)
|
||||
spin_lock_irq(q->queue_lock);
|
||||
if (wc)
|
||||
queue_flag_set(QUEUE_FLAG_WC, q);
|
||||
else
|
||||
queue_flag_clear(QUEUE_FLAG_WC, q);
|
||||
if (fua)
|
||||
queue_flag_set(QUEUE_FLAG_FUA, q);
|
||||
else
|
||||
queue_flag_clear(QUEUE_FLAG_FUA, q);
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
#elif defined(HAVE_BLK_QUEUE_WRITE_CACHE)
|
||||
blk_queue_write_cache(q, wc, fua);
|
||||
#elif defined(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY)
|
||||
if (wc)
|
||||
q->flush_flags |= REQ_FLUSH;
|
||||
if (fua)
|
||||
q->flush_flags |= REQ_FUA;
|
||||
#elif defined(HAVE_BLK_QUEUE_FLUSH)
|
||||
blk_queue_flush(q, (wc ? REQ_FLUSH : 0) | (fua ? REQ_FUA : 0));
|
||||
#else
|
||||
blk_queue_ordered(q, QUEUE_ORDERED_DRAIN, NULL);
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_BLK_QUEUE_FLUSH && HAVE_BLK_QUEUE_FLUSH_GPL_ONLY */
|
||||
|
||||
/*
|
||||
* Most of the blk_* macros were removed in 2.6.36. Ostensibly this was
|
||||
* done to improve readability and allow easier grepping. However, from
|
||||
|
@ -234,12 +261,21 @@ bio_set_flags_failfast(struct block_device *bdev, int *flags)
|
|||
|
||||
/*
|
||||
* 2.6.27 API change
|
||||
* The function was exported for use, prior to this it existed by the
|
||||
* The function was exported for use, prior to this it existed but the
|
||||
* symbol was not exported.
|
||||
*
|
||||
* 4.4.0-6.21 API change for Ubuntu
|
||||
* lookup_bdev() gained a second argument, FMODE_*, to check inode permissions.
|
||||
*/
|
||||
#ifndef HAVE_LOOKUP_BDEV
|
||||
#define lookup_bdev(path) ERR_PTR(-ENOTSUP)
|
||||
#endif
|
||||
#ifdef HAVE_1ARG_LOOKUP_BDEV
|
||||
#define vdev_lookup_bdev(path) lookup_bdev(path)
|
||||
#else
|
||||
#ifdef HAVE_2ARGS_LOOKUP_BDEV
|
||||
#define vdev_lookup_bdev(path) lookup_bdev(path, 0)
|
||||
#else
|
||||
#define vdev_lookup_bdev(path) ERR_PTR(-ENOTSUP)
|
||||
#endif /* HAVE_2ARGS_LOOKUP_BDEV */
|
||||
#endif /* HAVE_1ARG_LOOKUP_BDEV */
|
||||
|
||||
/*
|
||||
* 2.6.30 API change
|
||||
|
@ -265,48 +301,172 @@ bio_set_flags_failfast(struct block_device *bdev, int *flags)
|
|||
#endif /* HAVE_BDEV_LOGICAL_BLOCK_SIZE */
|
||||
#endif /* HAVE_BDEV_PHYSICAL_BLOCK_SIZE */
|
||||
|
||||
#ifndef HAVE_BIO_SET_OP_ATTRS
|
||||
/*
|
||||
* 2.6.37 API change
|
||||
* The WRITE_FLUSH, WRITE_FUA, and WRITE_FLUSH_FUA flags have been
|
||||
* introduced as a replacement for WRITE_BARRIER. This was done to
|
||||
* allow richer semantics to be expressed to the block layer. It is
|
||||
* the block layers responsibility to choose the correct way to
|
||||
* implement these semantics.
|
||||
*
|
||||
* The existence of these flags implies that REQ_FLUSH an REQ_FUA are
|
||||
* defined. Thus we can safely define VDEV_REQ_FLUSH and VDEV_REQ_FUA
|
||||
* compatibility macros.
|
||||
* Kernels without bio_set_op_attrs use bi_rw for the bio flags.
|
||||
*/
|
||||
#ifdef WRITE_FLUSH_FUA
|
||||
#define VDEV_WRITE_FLUSH_FUA WRITE_FLUSH_FUA
|
||||
#define VDEV_REQ_FLUSH REQ_FLUSH
|
||||
#define VDEV_REQ_FUA REQ_FUA
|
||||
#else
|
||||
#define VDEV_WRITE_FLUSH_FUA WRITE_BARRIER
|
||||
#ifdef HAVE_BIO_RW_BARRIER
|
||||
#define VDEV_REQ_FLUSH (1 << BIO_RW_BARRIER)
|
||||
#define VDEV_REQ_FUA (1 << BIO_RW_BARRIER)
|
||||
#else
|
||||
#define VDEV_REQ_FLUSH REQ_HARDBARRIER
|
||||
#define VDEV_REQ_FUA REQ_FUA
|
||||
#endif
|
||||
static inline void
|
||||
bio_set_op_attrs(struct bio *bio, unsigned rw, unsigned flags)
|
||||
{
|
||||
bio->bi_rw |= rw | flags;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 2.6.32 API change
|
||||
* Use the normal I/O patch for discards.
|
||||
* bio_set_flush - Set the appropriate flags in a bio to guarantee
|
||||
* data are on non-volatile media on completion.
|
||||
*
|
||||
* 2.6.X - 2.6.36 API,
|
||||
* WRITE_BARRIER - Tells the block layer to commit all previously submitted
|
||||
* writes to stable storage before this one is started and that the current
|
||||
* write is on stable storage upon completion. Also prevents reordering
|
||||
* on both sides of the current operation.
|
||||
*
|
||||
* 2.6.37 - 4.8 API,
|
||||
* Introduce WRITE_FLUSH, WRITE_FUA, and WRITE_FLUSH_FUA flags as a
|
||||
* replacement for WRITE_BARRIER to allow expressing richer semantics
|
||||
* to the block layer. It's up to the block layer to implement the
|
||||
* semantics correctly. Use the WRITE_FLUSH_FUA flag combination.
|
||||
*
|
||||
* 4.8 - 4.9 API,
|
||||
* REQ_FLUSH was renamed to REQ_PREFLUSH. For consistency with previous
|
||||
* ZoL releases, prefer the WRITE_FLUSH_FUA flag set if it's available.
|
||||
*
|
||||
* 4.10 API,
|
||||
* The read/write flags and their modifiers, including WRITE_FLUSH,
|
||||
* WRITE_FUA and WRITE_FLUSH_FUA were removed from fs.h in
|
||||
* torvalds/linux@70fd7614 and replaced by direct flag modification
|
||||
* of the REQ_ flags in bio->bi_opf. Use REQ_PREFLUSH.
|
||||
*/
|
||||
#ifdef QUEUE_FLAG_DISCARD
|
||||
#ifdef HAVE_BIO_RW_DISCARD
|
||||
#define VDEV_REQ_DISCARD (1 << BIO_RW_DISCARD)
|
||||
static inline void
|
||||
bio_set_flush(struct bio *bio)
|
||||
{
|
||||
#if defined(REQ_PREFLUSH) /* >= 4.10 */
|
||||
bio_set_op_attrs(bio, 0, REQ_PREFLUSH);
|
||||
#elif defined(WRITE_FLUSH_FUA) /* >= 2.6.37 and <= 4.9 */
|
||||
bio_set_op_attrs(bio, 0, WRITE_FLUSH_FUA);
|
||||
#elif defined(WRITE_BARRIER) /* < 2.6.37 */
|
||||
bio_set_op_attrs(bio, 0, WRITE_BARRIER);
|
||||
#else
|
||||
#define VDEV_REQ_DISCARD REQ_DISCARD
|
||||
#error "Allowing the build will cause bio_set_flush requests to be ignored."
|
||||
"Please file an issue report at: "
|
||||
"https://github.com/zfsonlinux/zfs/issues/new"
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 4.8 - 4.x API,
|
||||
* REQ_OP_FLUSH
|
||||
*
|
||||
* 4.8-rc0 - 4.8-rc1,
|
||||
* REQ_PREFLUSH
|
||||
*
|
||||
* 2.6.36 - 4.7 API,
|
||||
* REQ_FLUSH
|
||||
*
|
||||
* 2.6.x - 2.6.35 API,
|
||||
* HAVE_BIO_RW_BARRIER
|
||||
*
|
||||
* Used to determine if a cache flush has been requested. This check has
|
||||
* been left intentionally broad in order to cover both a legacy flush
|
||||
* and the new preflush behavior introduced in Linux 4.8. This is correct
|
||||
* in all cases but may have a performance impact for some kernels. It
|
||||
* has the advantage of minimizing kernel specific changes in the zvol code.
|
||||
*
|
||||
*/
|
||||
static inline boolean_t
|
||||
bio_is_flush(struct bio *bio)
|
||||
{
|
||||
#if defined(HAVE_REQ_OP_FLUSH) && defined(HAVE_BIO_BI_OPF)
|
||||
return ((bio_op(bio) == REQ_OP_FLUSH) || (bio->bi_opf & REQ_PREFLUSH));
|
||||
#elif defined(REQ_PREFLUSH) && defined(HAVE_BIO_BI_OPF)
|
||||
return (bio->bi_opf & REQ_PREFLUSH);
|
||||
#elif defined(REQ_PREFLUSH) && !defined(HAVE_BIO_BI_OPF)
|
||||
return (bio->bi_rw & REQ_PREFLUSH);
|
||||
#elif defined(REQ_FLUSH)
|
||||
return (bio->bi_rw & REQ_FLUSH);
|
||||
#elif defined(HAVE_BIO_RW_BARRIER)
|
||||
return (bio->bi_rw & (1 << BIO_RW_BARRIER));
|
||||
#else
|
||||
#error "Allowing the build will cause flush requests to be ignored. Please "
|
||||
"file an issue report at: https://github.com/zfsonlinux/zfs/issues/new"
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 4.8 - 4.x API,
|
||||
* REQ_FUA flag moved to bio->bi_opf
|
||||
*
|
||||
* 2.6.x - 4.7 API,
|
||||
* REQ_FUA
|
||||
*/
|
||||
static inline boolean_t
|
||||
bio_is_fua(struct bio *bio)
|
||||
{
|
||||
#if defined(HAVE_BIO_BI_OPF)
|
||||
return (bio->bi_opf & REQ_FUA);
|
||||
#elif defined(REQ_FUA)
|
||||
return (bio->bi_rw & REQ_FUA);
|
||||
#else
|
||||
#error "Allowing the build will cause fua requests to be ignored. Please "
|
||||
"file an issue report at: https://github.com/zfsonlinux/zfs/issues/new"
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 4.8 - 4.x API,
|
||||
* REQ_OP_DISCARD
|
||||
*
|
||||
* 2.6.36 - 4.7 API,
|
||||
* REQ_DISCARD
|
||||
*
|
||||
* 2.6.28 - 2.6.35 API,
|
||||
* BIO_RW_DISCARD
|
||||
*
|
||||
* In all cases the normal I/O path is used for discards. The only
|
||||
* difference is how the kernel tags individual I/Os as discards.
|
||||
*
|
||||
* Note that 2.6.32 era kernels provide both BIO_RW_DISCARD and REQ_DISCARD,
|
||||
* where BIO_RW_DISCARD is the correct interface. Therefore, it is important
|
||||
* that the HAVE_BIO_RW_DISCARD check occur before the REQ_DISCARD check.
|
||||
*/
|
||||
static inline boolean_t
|
||||
bio_is_discard(struct bio *bio)
|
||||
{
|
||||
#if defined(HAVE_REQ_OP_DISCARD)
|
||||
return (bio_op(bio) == REQ_OP_DISCARD);
|
||||
#elif defined(HAVE_BIO_RW_DISCARD)
|
||||
return (bio->bi_rw & (1 << BIO_RW_DISCARD));
|
||||
#elif defined(REQ_DISCARD)
|
||||
return (bio->bi_rw & REQ_DISCARD);
|
||||
#else
|
||||
#error "Allowing the build will cause discard requests to become writes "
|
||||
"potentially triggering the DMU_MAX_ACCESS assertion. Please file a "
|
||||
"potentially triggering the DMU_MAX_ACCESS assertion. Please file "
|
||||
"an issue report at: https://github.com/zfsonlinux/zfs/issues/new"
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 4.8 - 4.x API,
|
||||
* REQ_OP_SECURE_ERASE
|
||||
*
|
||||
* 2.6.36 - 4.7 API,
|
||||
* REQ_SECURE
|
||||
*
|
||||
* 2.6.x - 2.6.35 API,
|
||||
* Unsupported by kernel
|
||||
*/
|
||||
static inline boolean_t
|
||||
bio_is_secure_erase(struct bio *bio)
|
||||
{
|
||||
#if defined(HAVE_REQ_OP_SECURE_ERASE)
|
||||
return (bio_op(bio) == REQ_OP_SECURE_ERASE);
|
||||
#elif defined(REQ_SECURE)
|
||||
return (bio->bi_rw & REQ_SECURE);
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* 2.6.33 API change
|
||||
|
|
|
@ -69,45 +69,115 @@ truncate_setsize(struct inode *ip, loff_t new)
|
|||
/*
|
||||
* 2.6.32 - 2.6.33, bdi_setup_and_register() is not available.
|
||||
* 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
|
||||
* 4.0 - x.y, bdi_setup_and_register() takes 2 arguments.
|
||||
* 4.0 - 4.11, bdi_setup_and_register() takes 2 arguments.
|
||||
* 4.12 - x.y, super_setup_bdi_name() new interface.
|
||||
*/
|
||||
#if defined(HAVE_2ARGS_BDI_SETUP_AND_REGISTER)
|
||||
#if defined(HAVE_SUPER_SETUP_BDI_NAME)
|
||||
extern atomic_long_t zfs_bdi_seq;
|
||||
|
||||
static inline int
|
||||
zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
|
||||
zpl_bdi_setup(struct super_block *sb, char *name)
|
||||
{
|
||||
return (bdi_setup_and_register(bdi, name));
|
||||
return super_setup_bdi_name(sb, "%.28s-%ld", name,
|
||||
atomic_long_inc_return(&zfs_bdi_seq));
|
||||
}
|
||||
static inline void
|
||||
zpl_bdi_destroy(struct super_block *sb)
|
||||
{
|
||||
}
|
||||
#elif defined(HAVE_2ARGS_BDI_SETUP_AND_REGISTER)
|
||||
static inline int
|
||||
zpl_bdi_setup(struct super_block *sb, char *name)
|
||||
{
|
||||
struct backing_dev_info *bdi;
|
||||
int error;
|
||||
|
||||
bdi = kmem_zalloc(sizeof (struct backing_dev_info), KM_SLEEP);
|
||||
error = bdi_setup_and_register(bdi, name);
|
||||
if (error) {
|
||||
kmem_free(bdi, sizeof (struct backing_dev_info));
|
||||
return (error);
|
||||
}
|
||||
|
||||
sb->s_bdi = bdi;
|
||||
|
||||
return (0);
|
||||
}
|
||||
static inline void
|
||||
zpl_bdi_destroy(struct super_block *sb)
|
||||
{
|
||||
struct backing_dev_info *bdi = sb->s_bdi;
|
||||
|
||||
bdi_destroy(bdi);
|
||||
kmem_free(bdi, sizeof (struct backing_dev_info));
|
||||
sb->s_bdi = NULL;
|
||||
}
|
||||
#elif defined(HAVE_3ARGS_BDI_SETUP_AND_REGISTER)
|
||||
static inline int
|
||||
zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
|
||||
zpl_bdi_setup(struct super_block *sb, char *name)
|
||||
{
|
||||
return (bdi_setup_and_register(bdi, name, BDI_CAP_MAP_COPY));
|
||||
struct backing_dev_info *bdi;
|
||||
int error;
|
||||
|
||||
bdi = kmem_zalloc(sizeof (struct backing_dev_info), KM_SLEEP);
|
||||
error = bdi_setup_and_register(bdi, name, BDI_CAP_MAP_COPY);
|
||||
if (error) {
|
||||
kmem_free(sb->s_bdi, sizeof (struct backing_dev_info));
|
||||
return (error);
|
||||
}
|
||||
|
||||
sb->s_bdi = bdi;
|
||||
|
||||
return (0);
|
||||
}
|
||||
static inline void
|
||||
zpl_bdi_destroy(struct super_block *sb)
|
||||
{
|
||||
struct backing_dev_info *bdi = sb->s_bdi;
|
||||
|
||||
bdi_destroy(bdi);
|
||||
kmem_free(bdi, sizeof (struct backing_dev_info));
|
||||
sb->s_bdi = NULL;
|
||||
}
|
||||
#else
|
||||
extern atomic_long_t zfs_bdi_seq;
|
||||
|
||||
static inline int
|
||||
zpl_bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
|
||||
zpl_bdi_setup(struct super_block *sb, char *name)
|
||||
{
|
||||
char tmp[32];
|
||||
struct backing_dev_info *bdi;
|
||||
int error;
|
||||
|
||||
bdi = kmem_zalloc(sizeof (struct backing_dev_info), KM_SLEEP);
|
||||
bdi->name = name;
|
||||
bdi->capabilities = BDI_CAP_MAP_COPY;
|
||||
|
||||
error = bdi_init(bdi);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
sprintf(tmp, "%.28s%s", name, "-%d");
|
||||
error = bdi_register(bdi, NULL, tmp,
|
||||
atomic_long_inc_return(&zfs_bdi_seq));
|
||||
if (error) {
|
||||
bdi_destroy(bdi);
|
||||
kmem_free(bdi, sizeof (struct backing_dev_info));
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (error);
|
||||
error = bdi_register(bdi, NULL, "%.28s-%ld", name,
|
||||
atomic_long_inc_return(&zfs_bdi_seq));
|
||||
if (error) {
|
||||
bdi_destroy(bdi);
|
||||
kmem_free(bdi, sizeof (struct backing_dev_info));
|
||||
return (error);
|
||||
}
|
||||
|
||||
sb->s_bdi = bdi;
|
||||
|
||||
return (0);
|
||||
}
|
||||
static inline void
|
||||
zpl_bdi_destroy(struct super_block *sb)
|
||||
{
|
||||
struct backing_dev_info *bdi = sb->s_bdi;
|
||||
|
||||
bdi_destroy(bdi);
|
||||
kmem_free(bdi, sizeof (struct backing_dev_info));
|
||||
sb->s_bdi = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -202,22 +272,11 @@ lseek_execute(
|
|||
* At 60 seconds the kernel will also begin issuing RCU stall warnings.
|
||||
*/
|
||||
#include <linux/posix_acl.h>
|
||||
#ifndef HAVE_POSIX_ACL_CACHING
|
||||
#define ACL_NOT_CACHED ((void *)(-1))
|
||||
#endif /* HAVE_POSIX_ACL_CACHING */
|
||||
|
||||
#if defined(HAVE_POSIX_ACL_RELEASE) && !defined(HAVE_POSIX_ACL_RELEASE_GPL_ONLY)
|
||||
|
||||
#define zpl_posix_acl_release(arg) posix_acl_release(arg)
|
||||
#define zpl_set_cached_acl(ip, ty, n) set_cached_acl(ip, ty, n)
|
||||
#define zpl_forget_cached_acl(ip, ty) forget_cached_acl(ip, ty)
|
||||
|
||||
#else
|
||||
|
||||
static inline void
|
||||
zpl_posix_acl_free(void *arg) {
|
||||
kfree(arg);
|
||||
}
|
||||
void zpl_posix_acl_release_impl(struct posix_acl *);
|
||||
|
||||
static inline void
|
||||
zpl_posix_acl_release(struct posix_acl *acl)
|
||||
|
@ -225,15 +284,17 @@ zpl_posix_acl_release(struct posix_acl *acl)
|
|||
if ((acl == NULL) || (acl == ACL_NOT_CACHED))
|
||||
return;
|
||||
|
||||
if (atomic_dec_and_test(&acl->a_refcount)) {
|
||||
taskq_dispatch_delay(system_taskq, zpl_posix_acl_free, acl,
|
||||
TQ_SLEEP, ddi_get_lbolt() + 60*HZ);
|
||||
}
|
||||
if (atomic_dec_and_test(&acl->a_refcount))
|
||||
zpl_posix_acl_release_impl(acl);
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL_RELEASE */
|
||||
|
||||
#ifdef HAVE_SET_CACHED_ACL_USABLE
|
||||
#define zpl_set_cached_acl(ip, ty, n) set_cached_acl(ip, ty, n)
|
||||
#define zpl_forget_cached_acl(ip, ty) forget_cached_acl(ip, ty)
|
||||
#else
|
||||
static inline void
|
||||
zpl_set_cached_acl(struct inode *ip, int type, struct posix_acl *newer) {
|
||||
#ifdef HAVE_POSIX_ACL_CACHING
|
||||
struct posix_acl *older = NULL;
|
||||
|
||||
spin_lock(&ip->i_lock);
|
||||
|
@ -255,14 +316,13 @@ zpl_set_cached_acl(struct inode *ip, int type, struct posix_acl *newer) {
|
|||
spin_unlock(&ip->i_lock);
|
||||
|
||||
zpl_posix_acl_release(older);
|
||||
#endif /* HAVE_POSIX_ACL_CACHING */
|
||||
}
|
||||
|
||||
static inline void
|
||||
zpl_forget_cached_acl(struct inode *ip, int type) {
|
||||
zpl_set_cached_acl(ip, type, (struct posix_acl *)ACL_NOT_CACHED);
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL_RELEASE */
|
||||
#endif /* HAVE_SET_CACHED_ACL_USABLE */
|
||||
|
||||
#ifndef HAVE___POSIX_ACL_CHMOD
|
||||
#ifdef HAVE_POSIX_ACL_CHMOD
|
||||
|
@ -320,15 +380,19 @@ typedef umode_t zpl_equivmode_t;
|
|||
#else
|
||||
typedef mode_t zpl_equivmode_t;
|
||||
#endif /* HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T */
|
||||
#endif /* CONFIG_FS_POSIX_ACL */
|
||||
|
||||
#ifndef HAVE_CURRENT_UMASK
|
||||
static inline int
|
||||
current_umask(void)
|
||||
{
|
||||
return (current->fs->umask);
|
||||
}
|
||||
#endif /* HAVE_CURRENT_UMASK */
|
||||
/*
|
||||
* 4.8 API change,
|
||||
* posix_acl_valid() now must be passed a namespace, the namespace from
|
||||
* from super block associated with the given inode is used for this purpose.
|
||||
*/
|
||||
#ifdef HAVE_POSIX_ACL_VALID_WITH_NS
|
||||
#define zpl_posix_acl_valid(ip, acl) posix_acl_valid(ip->i_sb->s_user_ns, acl)
|
||||
#else
|
||||
#define zpl_posix_acl_valid(ip, acl) posix_acl_valid(acl)
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_FS_POSIX_ACL */
|
||||
|
||||
/*
|
||||
* 2.6.38 API change,
|
||||
|
@ -363,4 +427,69 @@ static inline struct inode *file_inode(const struct file *f)
|
|||
#define zpl_follow_up(path) follow_up(path)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.9 API change
|
||||
*/
|
||||
#ifndef HAVE_SETATTR_PREPARE
|
||||
static inline int
|
||||
setattr_prepare(struct dentry *dentry, struct iattr *ia)
|
||||
{
|
||||
return (inode_change_ok(dentry->d_inode, ia));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.11 API change
|
||||
* These macros are defined by kernel 4.11. We define them so that the same
|
||||
* code builds under kernels < 4.11 and >= 4.11. The macros are set to 0 so
|
||||
* that it will create obvious failures if they are accidentally used when built
|
||||
* against a kernel >= 4.11.
|
||||
*/
|
||||
|
||||
#ifndef STATX_BASIC_STATS
|
||||
#define STATX_BASIC_STATS 0
|
||||
#endif
|
||||
|
||||
#ifndef AT_STATX_SYNC_AS_STAT
|
||||
#define AT_STATX_SYNC_AS_STAT 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.11 API change
|
||||
* 4.11 takes struct path *, < 4.11 takes vfsmount *
|
||||
*/
|
||||
|
||||
#ifdef HAVE_VFSMOUNT_IOPS_GETATTR
|
||||
#define ZPL_GETATTR_WRAPPER(func) \
|
||||
static int \
|
||||
func(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) \
|
||||
{ \
|
||||
struct path path = { .mnt = mnt, .dentry = dentry }; \
|
||||
return func##_impl(&path, stat, STATX_BASIC_STATS, \
|
||||
AT_STATX_SYNC_AS_STAT); \
|
||||
}
|
||||
#elif defined(HAVE_PATH_IOPS_GETATTR)
|
||||
#define ZPL_GETATTR_WRAPPER(func) \
|
||||
static int \
|
||||
func(const struct path *path, struct kstat *stat, u32 request_mask, \
|
||||
unsigned int query_flags) \
|
||||
{ \
|
||||
return (func##_impl(path, stat, request_mask, query_flags)); \
|
||||
}
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.9 API change
|
||||
* Preferred interface to get the current FS time.
|
||||
*/
|
||||
#if !defined(HAVE_CURRENT_TIME)
|
||||
static inline struct timespec
|
||||
current_time(struct inode *ip)
|
||||
{
|
||||
return (timespec_trunc(current_kernel_time(), ip->i_sb->s_time_gran));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZFS_VFS_H */
|
||||
|
|
|
@ -41,12 +41,99 @@ typedef const struct xattr_handler xattr_handler_t;
|
|||
typedef struct xattr_handler xattr_handler_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 3.7 API change,
|
||||
* Preferred XATTR_NAME_* definitions introduced, these are mapped to
|
||||
* the previous definitions for older kernels.
|
||||
*/
|
||||
#ifndef XATTR_NAME_POSIX_ACL_DEFAULT
|
||||
#define XATTR_NAME_POSIX_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT
|
||||
#endif
|
||||
|
||||
#ifndef XATTR_NAME_POSIX_ACL_ACCESS
|
||||
#define XATTR_NAME_POSIX_ACL_ACCESS POSIX_ACL_XATTR_ACCESS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.5 API change,
|
||||
*/
|
||||
#if defined(HAVE_XATTR_LIST_SIMPLE)
|
||||
#define ZPL_XATTR_LIST_WRAPPER(fn) \
|
||||
static bool \
|
||||
fn(struct dentry *dentry) \
|
||||
{ \
|
||||
return (!!__ ## fn(dentry->d_inode, NULL, 0, NULL, 0)); \
|
||||
}
|
||||
/*
|
||||
* 4.4 API change,
|
||||
*/
|
||||
#elif defined(HAVE_XATTR_LIST_DENTRY)
|
||||
#define ZPL_XATTR_LIST_WRAPPER(fn) \
|
||||
static size_t \
|
||||
fn(struct dentry *dentry, char *list, size_t list_size, \
|
||||
const char *name, size_t name_len, int type) \
|
||||
{ \
|
||||
return (__ ## fn(dentry->d_inode, \
|
||||
list, list_size, name, name_len)); \
|
||||
}
|
||||
/*
|
||||
* 2.6.33 API change,
|
||||
* The xattr_hander->get() callback was changed to take a dentry
|
||||
*/
|
||||
#elif defined(HAVE_XATTR_LIST_HANDLER)
|
||||
#define ZPL_XATTR_LIST_WRAPPER(fn) \
|
||||
static size_t \
|
||||
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
||||
char *list, size_t list_size, const char *name, size_t name_len) \
|
||||
{ \
|
||||
return (__ ## fn(dentry->d_inode, \
|
||||
list, list_size, name, name_len)); \
|
||||
}
|
||||
/*
|
||||
* 2.6.32 API
|
||||
*/
|
||||
#elif defined(HAVE_XATTR_LIST_INODE)
|
||||
#define ZPL_XATTR_LIST_WRAPPER(fn) \
|
||||
static size_t \
|
||||
fn(struct inode *ip, char *list, size_t list_size, \
|
||||
const char *name, size_t name_len) \
|
||||
{ \
|
||||
return (__ ## fn(ip, list, list_size, name, name_len)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.7 API change,
|
||||
* The xattr_handler->get() callback was changed to take a both dentry and
|
||||
* inode, because the dentry might not be attached to an inode yet.
|
||||
*/
|
||||
#if defined(HAVE_XATTR_GET_DENTRY_INODE)
|
||||
#define ZPL_XATTR_GET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
||||
struct inode *inode, const char *name, void *buffer, size_t size) \
|
||||
{ \
|
||||
return (__ ## fn(inode, name, buffer, size)); \
|
||||
}
|
||||
/*
|
||||
* 4.4 API change,
|
||||
* The xattr_handler->get() callback was changed to take a xattr_handler,
|
||||
* and handler_flags argument was removed and should be accessed by
|
||||
* handler->flags.
|
||||
*/
|
||||
#elif defined(HAVE_XATTR_GET_HANDLER)
|
||||
#define ZPL_XATTR_GET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
||||
const char *name, void *buffer, size_t size) \
|
||||
{ \
|
||||
return (__ ## fn(dentry->d_inode, name, buffer, size)); \
|
||||
}
|
||||
/*
|
||||
* 2.6.33 API change,
|
||||
* The xattr_handler->get() callback was changed to take a dentry
|
||||
* instead of an inode, and a handler_flags argument was added.
|
||||
*/
|
||||
#ifdef HAVE_DENTRY_XATTR_GET
|
||||
#elif defined(HAVE_XATTR_GET_DENTRY)
|
||||
#define ZPL_XATTR_GET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \
|
||||
|
@ -54,21 +141,52 @@ fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \
|
|||
{ \
|
||||
return (__ ## fn(dentry->d_inode, name, buffer, size)); \
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* 2.6.32 API
|
||||
*/
|
||||
#elif defined(HAVE_XATTR_GET_INODE)
|
||||
#define ZPL_XATTR_GET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(struct inode *ip, const char *name, void *buffer, size_t size) \
|
||||
{ \
|
||||
return (__ ## fn(ip, name, buffer, size)); \
|
||||
}
|
||||
#endif /* HAVE_DENTRY_XATTR_GET */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4.7 API change,
|
||||
* The xattr_handler->set() callback was changed to take a both dentry and
|
||||
* inode, because the dentry might not be attached to an inode yet.
|
||||
*/
|
||||
#if defined(HAVE_XATTR_SET_DENTRY_INODE)
|
||||
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
||||
struct inode *inode, const char *name, const void *buffer, \
|
||||
size_t size, int flags) \
|
||||
{ \
|
||||
return (__ ## fn(inode, name, buffer, size, flags)); \
|
||||
}
|
||||
/*
|
||||
* 4.4 API change,
|
||||
* The xattr_handler->set() callback was changed to take a xattr_handler,
|
||||
* and handler_flags argument was removed and should be accessed by
|
||||
* handler->flags.
|
||||
*/
|
||||
#elif defined(HAVE_XATTR_SET_HANDLER)
|
||||
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
||||
const char *name, const void *buffer, size_t size, int flags) \
|
||||
{ \
|
||||
return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
|
||||
}
|
||||
/*
|
||||
* 2.6.33 API change,
|
||||
* The xattr_hander->set() callback was changed to take a dentry
|
||||
* The xattr_handler->set() callback was changed to take a dentry
|
||||
* instead of an inode, and a handler_flags argument was added.
|
||||
*/
|
||||
#ifdef HAVE_DENTRY_XATTR_SET
|
||||
#elif defined(HAVE_XATTR_SET_DENTRY)
|
||||
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(struct dentry *dentry, const char *name, const void *buffer, \
|
||||
|
@ -76,7 +194,10 @@ fn(struct dentry *dentry, const char *name, const void *buffer, \
|
|||
{ \
|
||||
return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* 2.6.32 API
|
||||
*/
|
||||
#elif defined(HAVE_XATTR_SET_INODE)
|
||||
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||
static int \
|
||||
fn(struct inode *ip, const char *name, const void *buffer, \
|
||||
|
@ -84,7 +205,7 @@ fn(struct inode *ip, const char *name, const void *buffer, \
|
|||
{ \
|
||||
return (__ ## fn(ip, name, buffer, size, flags)); \
|
||||
}
|
||||
#endif /* HAVE_DENTRY_XATTR_SET */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY
|
||||
#define zpl_security_inode_init_security(ip, dip, qstr, nm, val, len) \
|
||||
|
@ -96,20 +217,20 @@ fn(struct inode *ip, const char *name, const void *buffer, \
|
|||
|
||||
/*
|
||||
* Linux 3.7 API change. posix_acl_{from,to}_xattr gained the user_ns
|
||||
* parameter. For the HAVE_POSIX_ACL_FROM_XATTR_USERNS version the
|
||||
* userns _may_ not be correct because it's used outside the RCU.
|
||||
* parameter. All callers are expected to pass the &init_user_ns which
|
||||
* is available through the init credential (kcred).
|
||||
*/
|
||||
#ifdef HAVE_POSIX_ACL_FROM_XATTR_USERNS
|
||||
static inline struct posix_acl *
|
||||
zpl_acl_from_xattr(const void *value, int size)
|
||||
{
|
||||
return (posix_acl_from_xattr(CRED()->user_ns, value, size));
|
||||
return (posix_acl_from_xattr(kcred->user_ns, value, size));
|
||||
}
|
||||
|
||||
static inline int
|
||||
zpl_acl_to_xattr(struct posix_acl *acl, void *value, int size)
|
||||
{
|
||||
return (posix_acl_to_xattr(CRED()->user_ns, acl, value, size));
|
||||
return (posix_acl_to_xattr(kcred->user_ns, acl, value, size));
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
@ -230,9 +230,25 @@ typedef struct dmu_buf_impl {
|
|||
/* User callback information. */
|
||||
dmu_buf_user_t *db_user;
|
||||
|
||||
uint8_t db_immediate_evict;
|
||||
/*
|
||||
* Evict user data as soon as the dirty and reference
|
||||
* counts are equal.
|
||||
*/
|
||||
uint8_t db_user_immediate_evict;
|
||||
|
||||
/*
|
||||
* This block was freed while a read or write was
|
||||
* active.
|
||||
*/
|
||||
uint8_t db_freed_in_flight;
|
||||
|
||||
/*
|
||||
* dnode_evict_dbufs() or dnode_evict_bonus() tried to
|
||||
* evict this dbuf, but couldn't due to outstanding
|
||||
* references. Evict once the refcount drops to 0.
|
||||
*/
|
||||
uint8_t db_pending_evict;
|
||||
|
||||
uint8_t db_dirtycnt;
|
||||
} dmu_buf_impl_t;
|
||||
|
||||
|
|
|
@ -93,7 +93,6 @@ struct objset {
|
|||
uint8_t os_copies;
|
||||
enum zio_checksum os_dedup_checksum;
|
||||
boolean_t os_dedup_verify;
|
||||
boolean_t os_evicting;
|
||||
zfs_logbias_op_t os_logbias;
|
||||
zfs_cache_type_t os_primary_cache;
|
||||
zfs_cache_type_t os_secondary_cache;
|
||||
|
|
|
@ -221,6 +221,7 @@ int dsl_dataset_own_obj(struct dsl_pool *dp, uint64_t dsobj,
|
|||
void dsl_dataset_disown(dsl_dataset_t *ds, void *tag);
|
||||
void dsl_dataset_name(dsl_dataset_t *ds, char *name);
|
||||
boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, void *tag);
|
||||
int dsl_dataset_namelen(dsl_dataset_t *ds);
|
||||
uint64_t dsl_dataset_create_sync(dsl_dir_t *pds, const char *lastname,
|
||||
dsl_dataset_t *origin, uint64_t flags, cred_t *, dmu_tx_t *);
|
||||
uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef enum dmu_objset_type {
|
|||
#define ZAP_MAXNAMELEN 256
|
||||
#define ZAP_MAXVALUELEN (1024 * 8)
|
||||
#define ZAP_OLDMAXVALUELEN 1024
|
||||
#define ZFS_MAX_DATASET_NAME_LEN 256
|
||||
|
||||
/*
|
||||
* Dataset properties are identified by these constants and must be added to
|
||||
|
|
|
@ -68,8 +68,9 @@
|
|||
#define MNTOPT_NOFAIL "nofail" /* no failure */
|
||||
#define MNTOPT_RELATIME "relatime" /* allow relative time updates */
|
||||
#define MNTOPT_NORELATIME "norelatime" /* do not allow relative time updates */
|
||||
#define MNTOPT_DFRATIME "strictatime" /* Deferred access time updates */
|
||||
#define MNTOPT_NODFRATIME "nostrictatime" /* No Deferred access time updates */
|
||||
#define MNTOPT_STRICTATIME "strictatime" /* strict access time updates */
|
||||
#define MNTOPT_NOSTRICTATIME "nostrictatime" /* No strict access time updates */
|
||||
#define MNTOPT_LAZYTIME "lazytime" /* Defer access time writing */
|
||||
#define MNTOPT_SETUID "suid" /* Both setuid and devices allowed */
|
||||
#define MNTOPT_NOSETUID "nosuid" /* Neither setuid nor devices allowed */
|
||||
#define MNTOPT_OWNER "owner" /* allow owner mount */
|
||||
|
|
|
@ -40,6 +40,17 @@ extern "C" {
|
|||
*/
|
||||
#define FTAG ((char *)__func__)
|
||||
|
||||
/*
|
||||
* Starting with 4.11, torvalds/linux@f405df5, the linux kernel defines a
|
||||
* refcount_t type of its own. The macro below effectively changes references
|
||||
* in the ZFS code from refcount_t to zfs_refcount_t at compile time, so that
|
||||
* existing code need not be altered, reducing conflicts when landing openZFS
|
||||
* patches.
|
||||
*/
|
||||
|
||||
#define refcount_t zfs_refcount_t
|
||||
#define refcount_add zfs_refcount_add
|
||||
|
||||
#ifdef ZFS_DEBUG
|
||||
typedef struct reference {
|
||||
list_node_t ref_link;
|
||||
|
@ -55,7 +66,7 @@ typedef struct refcount {
|
|||
list_t rc_removed;
|
||||
int64_t rc_count;
|
||||
int64_t rc_removed_count;
|
||||
} refcount_t;
|
||||
} zfs_refcount_t;
|
||||
|
||||
/* Note: refcount_t must be initialized with refcount_create[_untracked]() */
|
||||
|
||||
|
@ -65,7 +76,7 @@ void refcount_destroy(refcount_t *rc);
|
|||
void refcount_destroy_many(refcount_t *rc, uint64_t number);
|
||||
int refcount_is_zero(refcount_t *rc);
|
||||
int64_t refcount_count(refcount_t *rc);
|
||||
int64_t refcount_add(refcount_t *rc, void *holder_tag);
|
||||
int64_t zfs_refcount_add(refcount_t *rc, void *holder_tag);
|
||||
int64_t refcount_remove(refcount_t *rc, void *holder_tag);
|
||||
int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_tag);
|
||||
int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder_tag);
|
||||
|
@ -86,7 +97,7 @@ typedef struct refcount {
|
|||
#define refcount_destroy_many(rc, number) ((rc)->rc_count = 0)
|
||||
#define refcount_is_zero(rc) ((rc)->rc_count == 0)
|
||||
#define refcount_count(rc) ((rc)->rc_count)
|
||||
#define refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
|
||||
#define zfs_refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
|
||||
#define refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1)
|
||||
#define refcount_add_many(rc, number, holder) \
|
||||
atomic_add_64_nv(&(rc)->rc_count, number)
|
||||
|
|
|
@ -82,6 +82,10 @@ typedef struct sa_bulk_attr {
|
|||
uint16_t sa_size;
|
||||
} sa_bulk_attr_t;
|
||||
|
||||
/*
|
||||
* The on-disk format of sa_hdr_phys_t limits SA lengths to 16-bit values.
|
||||
*/
|
||||
#define SA_ATTR_MAX_LEN UINT16_MAX
|
||||
|
||||
/*
|
||||
* special macro for adding entries for bulk attr support
|
||||
|
@ -95,6 +99,7 @@ typedef struct sa_bulk_attr {
|
|||
|
||||
#define SA_ADD_BULK_ATTR(b, idx, attr, func, data, len) \
|
||||
{ \
|
||||
ASSERT3U(len, <=, SA_ATTR_MAX_LEN); \
|
||||
b[idx].sa_attr = attr;\
|
||||
b[idx].sa_data_func = func; \
|
||||
b[idx].sa_data = data; \
|
||||
|
|
|
@ -446,6 +446,10 @@ _NOTE(CONSTCOND) } while (0)
|
|||
((zc1).zc_word[2] - (zc2).zc_word[2]) | \
|
||||
((zc1).zc_word[3] - (zc2).zc_word[3])))
|
||||
|
||||
#define ZIO_CHECKSUM_IS_ZERO(zc) \
|
||||
(0 == ((zc)->zc_word[0] | (zc)->zc_word[1] | \
|
||||
(zc)->zc_word[2] | (zc)->zc_word[3]))
|
||||
|
||||
#define DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0)
|
||||
|
||||
#define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SPA_IMPL_H
|
||||
|
@ -252,6 +253,7 @@ struct spa {
|
|||
uint64_t spa_deadman_synctime; /* deadman expiration timer */
|
||||
uint64_t spa_errata; /* errata issues detected */
|
||||
spa_stats_t spa_stats; /* assorted spa statistics */
|
||||
taskq_t *spa_zvol_taskq; /* Taskq for minor managment */
|
||||
|
||||
/*
|
||||
* spa_refcount & spa_config_lock must be the last elements
|
||||
|
|
|
@ -56,7 +56,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__field(uint64_t, z_mapcnt)
|
||||
__field(uint64_t, z_gen)
|
||||
__field(uint64_t, z_size)
|
||||
__array(uint64_t, z_atime, 2)
|
||||
__field(uint64_t, z_links)
|
||||
__field(uint64_t, z_pflags)
|
||||
__field(uint64_t, z_uid)
|
||||
|
@ -64,7 +63,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__field(uint32_t, z_sync_cnt)
|
||||
__field(mode_t, z_mode)
|
||||
__field(boolean_t, z_is_sa)
|
||||
__field(boolean_t, z_is_zvol)
|
||||
__field(boolean_t, z_is_mapped)
|
||||
__field(boolean_t, z_is_ctldir)
|
||||
__field(boolean_t, z_is_stale)
|
||||
|
@ -95,8 +93,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__entry->z_mapcnt = zn->z_mapcnt;
|
||||
__entry->z_gen = zn->z_gen;
|
||||
__entry->z_size = zn->z_size;
|
||||
__entry->z_atime[0] = zn->z_atime[0];
|
||||
__entry->z_atime[1] = zn->z_atime[1];
|
||||
__entry->z_links = zn->z_links;
|
||||
__entry->z_pflags = zn->z_pflags;
|
||||
__entry->z_uid = zn->z_uid;
|
||||
|
@ -104,7 +100,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__entry->z_sync_cnt = zn->z_sync_cnt;
|
||||
__entry->z_mode = zn->z_mode;
|
||||
__entry->z_is_sa = zn->z_is_sa;
|
||||
__entry->z_is_zvol = zn->z_is_zvol;
|
||||
__entry->z_is_mapped = zn->z_is_mapped;
|
||||
__entry->z_is_ctldir = zn->z_is_ctldir;
|
||||
__entry->z_is_stale = zn->z_is_stale;
|
||||
|
@ -126,9 +121,9 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
),
|
||||
TP_printk("zn { id %llu unlinked %u atime_dirty %u "
|
||||
"zn_prefetch %u moved %u blksz %u seq %u "
|
||||
"mapcnt %llu gen %llu size %llu atime 0x%llx:0x%llx "
|
||||
"mapcnt %llu gen %llu size %llu "
|
||||
"links %llu pflags %llu uid %llu gid %llu "
|
||||
"sync_cnt %u mode 0x%x is_sa %d is_zvol %d "
|
||||
"sync_cnt %u mode 0x%x is_sa %d "
|
||||
"is_mapped %d is_ctldir %d is_stale %d inode { "
|
||||
"ino %lu nlink %u version %llu size %lli blkbits %u "
|
||||
"bytes %u mode 0x%x generation %x } } ace { type %u "
|
||||
|
@ -136,10 +131,10 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
|||
__entry->z_id, __entry->z_unlinked, __entry->z_atime_dirty,
|
||||
__entry->z_zn_prefetch, __entry->z_moved, __entry->z_blksz,
|
||||
__entry->z_seq, __entry->z_mapcnt, __entry->z_gen,
|
||||
__entry->z_size, __entry->z_atime[0], __entry->z_atime[1],
|
||||
__entry->z_size,
|
||||
__entry->z_links, __entry->z_pflags, __entry->z_uid,
|
||||
__entry->z_gid, __entry->z_sync_cnt, __entry->z_mode,
|
||||
__entry->z_is_sa, __entry->z_is_zvol, __entry->z_is_mapped,
|
||||
__entry->z_is_sa, __entry->z_is_mapped,
|
||||
__entry->z_is_ctldir, __entry->z_is_stale, __entry->i_ino,
|
||||
__entry->i_nlink, __entry->i_version, __entry->i_size,
|
||||
__entry->i_blkbits, __entry->i_bytes, __entry->i_mode,
|
||||
|
|
|
@ -37,9 +37,5 @@ typedef struct vdev_disk {
|
|||
struct block_device *vd_bdev;
|
||||
} vdev_disk_t;
|
||||
|
||||
extern int vdev_disk_physio(struct block_device *, caddr_t,
|
||||
size_t, uint64_t, int);
|
||||
extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _SYS_VDEV_DISK_H */
|
||||
|
|
|
@ -225,7 +225,7 @@ typedef struct xvattr {
|
|||
* of requested attributes (xva_reqattrmap[]).
|
||||
*/
|
||||
#define XVA_SET_REQ(xvap, attr) \
|
||||
ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR); \
|
||||
ASSERT((xvap)->xva_vattr.va_mask & AT_XVATTR); \
|
||||
ASSERT((xvap)->xva_magic == XVA_MAGIC); \
|
||||
(xvap)->xva_reqattrmap[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
|
||||
/*
|
||||
|
@ -233,7 +233,7 @@ typedef struct xvattr {
|
|||
* of requested attributes (xva_reqattrmap[]).
|
||||
*/
|
||||
#define XVA_CLR_REQ(xvap, attr) \
|
||||
ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR); \
|
||||
ASSERT((xvap)->xva_vattr.va_mask & AT_XVATTR); \
|
||||
ASSERT((xvap)->xva_magic == XVA_MAGIC); \
|
||||
(xvap)->xva_reqattrmap[XVA_INDEX(attr)] &= ~XVA_ATTRBIT(attr)
|
||||
|
||||
|
@ -242,7 +242,7 @@ typedef struct xvattr {
|
|||
* of returned attributes (xva_rtnattrmap[]).
|
||||
*/
|
||||
#define XVA_SET_RTN(xvap, attr) \
|
||||
ASSERT((xvap)->xva_vattr.va_mask | AT_XVATTR); \
|
||||
ASSERT((xvap)->xva_vattr.va_mask & AT_XVATTR); \
|
||||
ASSERT((xvap)->xva_magic == XVA_MAGIC); \
|
||||
(XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
|
||||
|
||||
|
@ -251,7 +251,7 @@ typedef struct xvattr {
|
|||
* to see of the corresponding attribute bit is set. If so, returns non-zero.
|
||||
*/
|
||||
#define XVA_ISSET_REQ(xvap, attr) \
|
||||
((((xvap)->xva_vattr.va_mask | AT_XVATTR) && \
|
||||
((((xvap)->xva_vattr.va_mask & AT_XVATTR) && \
|
||||
((xvap)->xva_magic == XVA_MAGIC) && \
|
||||
((xvap)->xva_mapsize > XVA_INDEX(attr))) ? \
|
||||
((xvap)->xva_reqattrmap[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) : 0)
|
||||
|
@ -261,7 +261,7 @@ typedef struct xvattr {
|
|||
* to see of the corresponding attribute bit is set. If so, returns non-zero.
|
||||
*/
|
||||
#define XVA_ISSET_RTN(xvap, attr) \
|
||||
((((xvap)->xva_vattr.va_mask | AT_XVATTR) && \
|
||||
((((xvap)->xva_vattr.va_mask & AT_XVATTR) && \
|
||||
((xvap)->xva_magic == XVA_MAGIC) && \
|
||||
((xvap)->xva_mapsize > XVA_INDEX(attr))) ? \
|
||||
((XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) : 0)
|
||||
|
|
|
@ -213,6 +213,7 @@ int zap_lookup_norm(objset_t *ds, uint64_t zapobj, const char *name,
|
|||
int zap_lookup_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
|
||||
int key_numints, uint64_t integer_size, uint64_t num_integers, void *buf);
|
||||
int zap_contains(objset_t *ds, uint64_t zapobj, const char *name);
|
||||
int zap_prefetch(objset_t *os, uint64_t zapobj, const char *name);
|
||||
int zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
|
||||
int key_numints);
|
||||
|
||||
|
|
|
@ -77,7 +77,8 @@ extern int zfsctl_snapdir_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
|
|||
extern void zfsctl_snapdir_inactive(struct inode *ip);
|
||||
extern int zfsctl_snapshot_mount(struct path *path, int flags);
|
||||
extern int zfsctl_snapshot_unmount(char *snapname, int flags);
|
||||
extern int zfsctl_snapshot_unmount_delay(uint64_t objsetid, int delay);
|
||||
extern int zfsctl_snapshot_unmount_delay(spa_t *spa, uint64_t objsetid,
|
||||
int delay);
|
||||
extern int zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid,
|
||||
zfs_sb_t **zsb);
|
||||
|
||||
|
|
|
@ -32,7 +32,9 @@ extern "C" {
|
|||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/zfs_znode.h>
|
||||
#include <sys/list.h>
|
||||
#include <sys/avl.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
typedef enum {
|
||||
RL_READER,
|
||||
|
@ -40,8 +42,16 @@ typedef enum {
|
|||
RL_APPEND
|
||||
} rl_type_t;
|
||||
|
||||
typedef struct zfs_rlock {
|
||||
kmutex_t zr_mutex; /* protects changes to zr_avl */
|
||||
avl_tree_t zr_avl; /* avl tree of range locks */
|
||||
uint64_t *zr_size; /* points to znode->z_size */
|
||||
uint_t *zr_blksz; /* points to znode->z_blksz */
|
||||
uint64_t *zr_max_blksz; /* points to zsb->z_max_blksz */
|
||||
} zfs_rlock_t;
|
||||
|
||||
typedef struct rl {
|
||||
znode_t *r_zp; /* znode this lock applies to */
|
||||
zfs_rlock_t *r_zrl;
|
||||
avl_node_t r_node; /* avl node link */
|
||||
uint64_t r_off; /* file range offset */
|
||||
uint64_t r_len; /* file range length */
|
||||
|
@ -61,7 +71,8 @@ typedef struct rl {
|
|||
* is converted to RL_WRITER that specified to lock from the start of the
|
||||
* end of file. Returns the range lock structure.
|
||||
*/
|
||||
rl_t *zfs_range_lock(znode_t *zp, uint64_t off, uint64_t len, rl_type_t type);
|
||||
rl_t *zfs_range_lock(zfs_rlock_t *zrl, uint64_t off, uint64_t len,
|
||||
rl_type_t type);
|
||||
|
||||
/* Unlock range and destroy range lock structure. */
|
||||
void zfs_range_unlock(rl_t *rl);
|
||||
|
@ -78,6 +89,23 @@ void zfs_range_reduce(rl_t *rl, uint64_t off, uint64_t len);
|
|||
*/
|
||||
int zfs_range_compare(const void *arg1, const void *arg2);
|
||||
|
||||
static inline void
|
||||
zfs_rlock_init(zfs_rlock_t *zrl)
|
||||
{
|
||||
mutex_init(&zrl->zr_mutex, NULL, MUTEX_DEFAULT, NULL);
|
||||
avl_create(&zrl->zr_avl, zfs_range_compare,
|
||||
sizeof (rl_t), offsetof(rl_t, r_node));
|
||||
zrl->zr_size = NULL;
|
||||
zrl->zr_blksz = NULL;
|
||||
zrl->zr_max_blksz = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
zfs_rlock_destroy(zfs_rlock_t *zrl)
|
||||
{
|
||||
avl_destroy(&zrl->zr_avl);
|
||||
mutex_destroy(&zrl->zr_mutex);
|
||||
}
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -64,7 +64,6 @@ typedef struct zfs_mntopts {
|
|||
|
||||
typedef struct zfs_sb {
|
||||
struct super_block *z_sb; /* generic super_block */
|
||||
struct backing_dev_info z_bdi; /* generic backing dev info */
|
||||
struct zfs_sb *z_parent; /* parent fs */
|
||||
objset_t *z_os; /* objset reference */
|
||||
zfs_mntopts_t *z_mntopts; /* passed mount options */
|
||||
|
@ -112,8 +111,9 @@ typedef struct zfs_sb {
|
|||
uint64_t z_groupquota_obj;
|
||||
uint64_t z_replay_eof; /* New end of file - replay only */
|
||||
sa_attr_type_t *z_attr_table; /* SA attr mapping->id */
|
||||
#define ZFS_OBJ_MTX_SZ 256
|
||||
kmutex_t *z_hold_mtx; /* znode hold locks */
|
||||
uint64_t z_hold_size; /* znode hold array size */
|
||||
avl_tree_t *z_hold_trees; /* znode hold trees */
|
||||
kmutex_t *z_hold_locks; /* znode hold locks */
|
||||
} zfs_sb_t;
|
||||
|
||||
#define ZFS_SUPER_MAGIC 0x2fc12fc1
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <sys/rrwlock.h>
|
||||
#include <sys/zfs_sa.h>
|
||||
#include <sys/zfs_stat.h>
|
||||
#include <sys/zfs_rlock.h>
|
||||
#endif
|
||||
#include <sys/zfs_acl.h>
|
||||
#include <sys/zil.h>
|
||||
|
@ -187,8 +188,7 @@ typedef struct znode {
|
|||
krwlock_t z_parent_lock; /* parent lock for directories */
|
||||
krwlock_t z_name_lock; /* "master" lock for dirent locks */
|
||||
zfs_dirlock_t *z_dirlocks; /* directory entry lock list */
|
||||
kmutex_t z_range_lock; /* protects changes to z_range_avl */
|
||||
avl_tree_t z_range_avl; /* avl tree of file range locks */
|
||||
zfs_rlock_t z_range_lock; /* file range lock */
|
||||
uint8_t z_unlinked; /* file has been unlinked */
|
||||
uint8_t z_atime_dirty; /* atime needs to be synced */
|
||||
uint8_t z_zn_prefetch; /* Prefetch znodes? */
|
||||
|
@ -198,7 +198,6 @@ typedef struct znode {
|
|||
uint64_t z_mapcnt; /* number of pages mapped to file */
|
||||
uint64_t z_gen; /* generation (cached) */
|
||||
uint64_t z_size; /* file size (cached) */
|
||||
uint64_t z_atime[2]; /* atime (cached) */
|
||||
uint64_t z_links; /* file links (cached) */
|
||||
uint64_t z_pflags; /* pflags (cached) */
|
||||
uint64_t z_uid; /* uid fuid (cached) */
|
||||
|
@ -209,17 +208,21 @@ typedef struct znode {
|
|||
zfs_acl_t *z_acl_cached; /* cached acl */
|
||||
krwlock_t z_xattr_lock; /* xattr data lock */
|
||||
nvlist_t *z_xattr_cached; /* cached xattrs */
|
||||
struct znode *z_xattr_parent; /* xattr parent znode */
|
||||
list_node_t z_link_node; /* all znodes in fs link */
|
||||
sa_handle_t *z_sa_hdl; /* handle to sa data */
|
||||
boolean_t z_is_sa; /* are we native sa? */
|
||||
boolean_t z_is_zvol; /* are we used by the zvol */
|
||||
boolean_t z_is_mapped; /* are we mmap'ed */
|
||||
boolean_t z_is_ctldir; /* are we .zfs entry */
|
||||
boolean_t z_is_stale; /* are we stale due to rollback? */
|
||||
struct inode z_inode; /* generic vfs inode */
|
||||
} znode_t;
|
||||
|
||||
typedef struct znode_hold {
|
||||
uint64_t zh_obj; /* object id */
|
||||
kmutex_t zh_lock; /* lock serializing object access */
|
||||
avl_node_t zh_node; /* avl tree linkage */
|
||||
refcount_t zh_refcount; /* active consumer reference count */
|
||||
} znode_hold_t;
|
||||
|
||||
/*
|
||||
* Range locking rules
|
||||
|
@ -273,17 +276,11 @@ typedef struct znode {
|
|||
/*
|
||||
* Macros for dealing with dmu_buf_hold
|
||||
*/
|
||||
#define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1))
|
||||
#define ZFS_OBJ_MUTEX(zsb, obj_num) \
|
||||
(&(zsb)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)])
|
||||
#define ZFS_OBJ_HOLD_ENTER(zsb, obj_num) \
|
||||
mutex_enter(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
||||
#define ZFS_OBJ_HOLD_TRYENTER(zsb, obj_num) \
|
||||
mutex_tryenter(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
||||
#define ZFS_OBJ_HOLD_EXIT(zsb, obj_num) \
|
||||
mutex_exit(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
||||
#define ZFS_OBJ_HOLD_OWNED(zsb, obj_num) \
|
||||
mutex_owned(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
||||
#define ZFS_OBJ_MTX_SZ 64
|
||||
#define ZFS_OBJ_MTX_MAX (1024 * 1024)
|
||||
#define ZFS_OBJ_HASH(zsb, obj) ((obj) & ((zsb->z_hold_size) - 1))
|
||||
|
||||
extern unsigned int zfs_object_mutex_size;
|
||||
|
||||
/* Encode ZFS stored time values from a struct timespec */
|
||||
#define ZFS_TIME_ENCODE(tp, stmp) \
|
||||
|
@ -306,20 +303,17 @@ typedef struct znode {
|
|||
#define STATE_CHANGED (ATTR_CTIME)
|
||||
#define CONTENT_MODIFIED (ATTR_MTIME | ATTR_CTIME)
|
||||
|
||||
#define ZFS_ACCESSTIME_STAMP(zsb, zp) \
|
||||
if ((zsb)->z_atime && !(zfs_is_readonly(zsb))) \
|
||||
zfs_tstamp_update_setup(zp, ACCESSED, NULL, NULL, B_FALSE);
|
||||
|
||||
extern int zfs_init_fs(zfs_sb_t *, znode_t **);
|
||||
extern void zfs_set_dataprop(objset_t *);
|
||||
extern void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *,
|
||||
dmu_tx_t *tx);
|
||||
extern void zfs_tstamp_update_setup(znode_t *, uint_t, uint64_t [2],
|
||||
uint64_t [2], boolean_t);
|
||||
uint64_t [2]);
|
||||
extern void zfs_grow_blocksize(znode_t *, uint64_t, dmu_tx_t *);
|
||||
extern int zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t);
|
||||
extern void zfs_znode_init(void);
|
||||
extern void zfs_znode_fini(void);
|
||||
extern int zfs_znode_hold_compare(const void *, const void *);
|
||||
extern int zfs_zget(zfs_sb_t *, uint64_t, znode_t **);
|
||||
extern int zfs_rezget(znode_t *);
|
||||
extern void zfs_zinactive(znode_t *);
|
||||
|
|
|
@ -525,6 +525,7 @@ extern void *zio_buf_alloc(size_t size);
|
|||
extern void zio_buf_free(void *buf, size_t size);
|
||||
extern void *zio_data_buf_alloc(size_t size);
|
||||
extern void zio_data_buf_free(void *buf, size_t size);
|
||||
extern void *zio_buf_alloc_flags(size_t size, int flags);
|
||||
|
||||
extern void zio_resubmit_stage_async(void *);
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ extern ssize_t zpl_xattr_list(struct dentry *dentry, char *buf, size_t size);
|
|||
extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip,
|
||||
const struct qstr *qstr);
|
||||
#if defined(CONFIG_FS_POSIX_ACL)
|
||||
extern int zpl_set_acl(struct inode *ip, int type, struct posix_acl *acl);
|
||||
extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
|
||||
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
|
||||
#if !defined(HAVE_GET_ACL)
|
||||
#if defined(HAVE_CHECK_ACL_WITH_FLAGS)
|
||||
|
@ -123,7 +123,7 @@ extern const struct inode_operations zpl_ops_snapdirs;
|
|||
extern const struct file_operations zpl_fops_shares;
|
||||
extern const struct inode_operations zpl_ops_shares;
|
||||
|
||||
#ifdef HAVE_VFS_ITERATE
|
||||
#if defined(HAVE_VFS_ITERATE) || defined(HAVE_VFS_ITERATE_SHARED)
|
||||
|
||||
#define DIR_CONTEXT_INIT(_dirent, _actor, _pos) { \
|
||||
.actor = _actor, \
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_ZVOL_H
|
||||
|
@ -31,24 +32,22 @@
|
|||
#define ZVOL_OBJ 1ULL
|
||||
#define ZVOL_ZAP_OBJ 2ULL
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern void zvol_create_minors(spa_t *spa, const char *name, boolean_t async);
|
||||
extern void zvol_remove_minors(spa_t *spa, const char *name, boolean_t async);
|
||||
extern void zvol_rename_minors(spa_t *spa, const char *oldname,
|
||||
const char *newname, boolean_t async);
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern int zvol_check_volsize(uint64_t volsize, uint64_t blocksize);
|
||||
extern int zvol_check_volblocksize(const char *name, uint64_t volblocksize);
|
||||
extern int zvol_get_stats(objset_t *os, nvlist_t *nv);
|
||||
extern boolean_t zvol_is_zvol(const char *);
|
||||
extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
|
||||
extern int zvol_create_minor(const char *name);
|
||||
extern int zvol_create_minors(const char *name);
|
||||
extern int zvol_remove_minor(const char *name);
|
||||
extern void zvol_remove_minors(const char *name);
|
||||
extern void zvol_rename_minors(const char *oldname, const char *newname);
|
||||
extern int zvol_set_volsize(const char *, uint64_t);
|
||||
extern int zvol_set_volblocksize(const char *, uint64_t);
|
||||
extern int zvol_set_snapdev(const char *, uint64_t);
|
||||
extern int zvol_set_snapdev(const char *, zprop_source_t, uint64_t);
|
||||
|
||||
extern int zvol_init(void);
|
||||
extern void zvol_fini(void);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _SYS_ZVOL_H */
|
||||
|
|
|
@ -88,7 +88,7 @@ struct dk_map2 default_vtoc_map[NDKMAP] = {
|
|||
#if defined(_SUNOS_VTOC_16)
|
||||
|
||||
#if defined(i386) || defined(__amd64) || defined(__arm) || \
|
||||
defined(__powerpc) || defined(__sparc)
|
||||
defined(__powerpc) || defined(__sparc) || defined(__s390__)
|
||||
{ V_BOOT, V_UNMNT }, /* i - 8 */
|
||||
{ V_ALTSCTR, 0 }, /* j - 9 */
|
||||
|
||||
|
|
|
@ -507,7 +507,7 @@
|
|||
movl 16(%esp), %ebx
|
||||
movl 20(%esp), %ecx
|
||||
subl %eax, %ebx
|
||||
adcl %edx, %ecx
|
||||
sbbl %edx, %ecx
|
||||
lock
|
||||
cmpxchg8b (%edi)
|
||||
jne 1b
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <sys/mnttab.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
|
@ -31,69 +31,66 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __assert_c99
|
||||
static inline void
|
||||
__assert_c99(const char *expr, const char *file, int line, const char *func)
|
||||
{
|
||||
fprintf(stderr, "%s:%i: %s: Assertion `%s` failed.\n",
|
||||
file, line, func, expr);
|
||||
abort();
|
||||
}
|
||||
#endif /* __assert_c99 */
|
||||
|
||||
#ifndef verify
|
||||
#if defined(__STDC__)
|
||||
#if __STDC_VERSION__ - 0 >= 199901L
|
||||
#define verify(EX) (void)((EX) || \
|
||||
(__assert_c99(#EX, __FILE__, __LINE__, __func__), 0))
|
||||
#else
|
||||
#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
|
||||
#endif /* __STDC_VERSION__ - 0 >= 199901L */
|
||||
#else
|
||||
#define verify(EX) (void)((EX) || (_assert("EX", __FILE__, __LINE__), 0))
|
||||
#endif /* __STDC__ */
|
||||
#endif /* verify */
|
||||
|
||||
#undef VERIFY
|
||||
#undef ASSERT
|
||||
|
||||
#define VERIFY verify
|
||||
#define ASSERT assert
|
||||
|
||||
extern void __assert(const char *, const char *, int);
|
||||
#include <stdarg.h>
|
||||
|
||||
static inline int
|
||||
assfail(const char *buf, const char *file, int line)
|
||||
libspl_assert(const char *buf, const char *file, const char *func, int line)
|
||||
{
|
||||
__assert(buf, file, line);
|
||||
return (0);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
|
||||
abort();
|
||||
}
|
||||
|
||||
/* BEGIN CSTYLED */
|
||||
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE) do { \
|
||||
const TYPE __left = (TYPE)(LEFT); \
|
||||
const TYPE __right = (TYPE)(RIGHT); \
|
||||
if (!(__left OP __right)) { \
|
||||
char *__buf = alloca(256); \
|
||||
(void) snprintf(__buf, 256, "%s %s %s (0x%llx %s 0x%llx)", \
|
||||
#LEFT, #OP, #RIGHT, \
|
||||
(u_longlong_t)__left, #OP, (u_longlong_t)__right); \
|
||||
assfail(__buf, __FILE__, __LINE__); \
|
||||
} \
|
||||
/* printf version of libspl_assert */
|
||||
static inline void
|
||||
libspl_assertf(const char *file, const char *func, int line, char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
|
||||
va_end(args);
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef verify
|
||||
#undef verify
|
||||
#endif
|
||||
|
||||
#define VERIFY(cond) \
|
||||
(void) ((!(cond)) && \
|
||||
libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
|
||||
#define verify(cond) \
|
||||
(void) ((!(cond)) && \
|
||||
libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
|
||||
|
||||
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE) \
|
||||
do { \
|
||||
const TYPE __left = (TYPE)(LEFT); \
|
||||
const TYPE __right = (TYPE)(RIGHT); \
|
||||
if (!(__left OP __right)) \
|
||||
libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
|
||||
"%s %s %s (0x%llx %s 0x%llx)", #LEFT, #OP, #RIGHT); \
|
||||
} while (0)
|
||||
/* END CSTYLED */
|
||||
|
||||
#define VERIFY3S(x, y, z) VERIFY3_IMPL(x, y, z, int64_t)
|
||||
#define VERIFY3U(x, y, z) VERIFY3_IMPL(x, y, z, uint64_t)
|
||||
#define VERIFY3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t)
|
||||
#define VERIFY0(x) VERIFY3_IMPL(x, ==, 0, uint64_t)
|
||||
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define ASSERT3S(x, y, z) ((void)0)
|
||||
#define ASSERT3U(x, y, z) ((void)0)
|
||||
#define ASSERT3P(x, y, z) ((void)0)
|
||||
#define ASSERT0(x) ((void)0)
|
||||
#define ASSERT(x) ((void)0)
|
||||
#define assert(x) ((void)0)
|
||||
#define ASSERTV(x)
|
||||
#define IMPLY(A, B) ((void)0)
|
||||
#define EQUIV(A, B) ((void)0)
|
||||
|
@ -102,13 +99,17 @@ assfail(const char *buf, const char *file, int line)
|
|||
#define ASSERT3U(x, y, z) VERIFY3U(x, y, z)
|
||||
#define ASSERT3P(x, y, z) VERIFY3P(x, y, z)
|
||||
#define ASSERT0(x) VERIFY0(x)
|
||||
#define ASSERT(x) VERIFY(x)
|
||||
#define assert(x) VERIFY(x)
|
||||
#define ASSERTV(x) x
|
||||
#define IMPLY(A, B) \
|
||||
((void)(((!(A)) || (B)) || \
|
||||
assfail("(" #A ") implies (" #B ")", __FILE__, __LINE__)))
|
||||
libspl_assert("(" #A ") implies (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
#define EQUIV(A, B) \
|
||||
((void)((!!(A) == !!(B)) || \
|
||||
assfail("(" #A ") is equivalent to (" #B ")", __FILE__, __LINE__)))
|
||||
libspl_assert("(" #A ") is equivalent to (" #B ")", \
|
||||
__FILE__, __FUNCTION__, __LINE__)))
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ extern "C" {
|
|||
#define _SUNOS_VTOC_16
|
||||
|
||||
/* powerpc arch specific defines */
|
||||
#elif defined(__powerpc) || defined(__powerpc__)
|
||||
#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__)
|
||||
|
||||
#if !defined(__powerpc)
|
||||
#define __powerpc
|
||||
|
@ -88,11 +88,13 @@ extern "C" {
|
|||
#define __powerpc__
|
||||
#endif
|
||||
|
||||
#if defined(__powerpc64__)
|
||||
#if !defined(_LP64)
|
||||
#ifdef __powerpc64__
|
||||
#define _LP64
|
||||
#endif
|
||||
#else
|
||||
#define _LP32
|
||||
#if !defined(_ILP32)
|
||||
#define _ILP32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -113,6 +115,16 @@ extern "C" {
|
|||
#define __arm__
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__)
|
||||
#if !defined(_LP64)
|
||||
#define _LP64
|
||||
#endif
|
||||
#else
|
||||
#if !defined(_ILP32)
|
||||
#define _ILP32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__ARMEL__) || defined(__AARCH64EL__)
|
||||
#define _LITTLE_ENDIAN
|
||||
#else
|
||||
|
@ -122,7 +134,7 @@ extern "C" {
|
|||
#define _SUNOS_VTOC_16
|
||||
|
||||
/* sparc arch specific defines */
|
||||
#elif defined(__sparc) || defined(__sparc__)
|
||||
#elif defined(__sparc) || defined(__sparc__) || defined(__sparc64__)
|
||||
|
||||
#if !defined(__sparc)
|
||||
#define __sparc
|
||||
|
@ -135,21 +147,32 @@ extern "C" {
|
|||
#define _BIG_ENDIAN
|
||||
#define _SUNOS_VTOC_16
|
||||
|
||||
/* sparc64 arch specific defines */
|
||||
#elif defined(__sparc64) || defined(__sparc64__)
|
||||
|
||||
#if !defined(__sparc64)
|
||||
#define __sparc64
|
||||
#if defined(__sparc64__)
|
||||
#if !defined(_LP64)
|
||||
#define _LP64
|
||||
#endif
|
||||
#else
|
||||
#if !defined(_ILP32)
|
||||
#define _ILP32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__sparc64__)
|
||||
#define __sparc64__
|
||||
/* s390 arch specific defines */
|
||||
#elif defined(__s390__)
|
||||
#if defined(__s390x__)
|
||||
#if !defined(_LP64)
|
||||
#define _LP64
|
||||
#endif
|
||||
#else
|
||||
#if !defined(_ILP32)
|
||||
#define _ILP32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define _BIG_ENDIAN
|
||||
#define _SUNOS_VTOC_16
|
||||
|
||||
#else /* Currently x86_64, i386, arm, powerpc, and sparc are supported */
|
||||
#else /* Currently x86_64, i386, arm, powerpc, s390, and sparc are supported */
|
||||
#error "Unsupported ISA type"
|
||||
#endif
|
||||
|
||||
|
@ -157,6 +180,10 @@ extern "C" {
|
|||
#error "Both _ILP32 and _LP64 are defined"
|
||||
#endif
|
||||
|
||||
#if !defined(_ILP32) && !defined(_LP64)
|
||||
#error "Neither _ILP32 or _LP64 are defined"
|
||||
#endif
|
||||
|
||||
#if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
|
||||
#error "Both _LITTLE_ENDIAN and _BIG_ENDIAN are defined"
|
||||
#endif
|
||||
|
|
|
@ -42,16 +42,13 @@
|
|||
|
||||
#define makedevice(maj, min) makedev(maj, min)
|
||||
#define _sysconf(a) sysconf(a)
|
||||
#define __NORETURN __attribute__((noreturn))
|
||||
|
||||
/*
|
||||
* Compatibility macros/typedefs needed for Solaris -> Linux port
|
||||
*/
|
||||
#define P2ALIGN(x, align) ((x) & -(align))
|
||||
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
|
||||
#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
|
||||
#define P2ROUNDUP_TYPED(x, align, type) \
|
||||
(-(-(type)(x) & -(type)(align)))
|
||||
#define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)
|
||||
#define P2BOUNDARY(off, len, align) \
|
||||
(((off) ^ ((off) + (len) - 1)) > (align) - 1)
|
||||
#define P2PHASE(x, align) ((x) & ((align) - 1))
|
||||
|
@ -79,7 +76,7 @@
|
|||
#define P2NPHASE_TYPED(x, align, type) \
|
||||
(-(type)(x) & ((type)(align) - 1))
|
||||
#define P2ROUNDUP_TYPED(x, align, type) \
|
||||
(-(-(type)(x) & -(type)(align)))
|
||||
((((type)(x) - 1) | ((type)(align) - 1)) + 1)
|
||||
#define P2END_TYPED(x, align, type) \
|
||||
(-(~(type)(x) & -(type)(align)))
|
||||
#define P2PHASEUP_TYPED(x, align, phase, type) \
|
||||
|
|
|
@ -27,10 +27,15 @@
|
|||
#ifndef _LIBSPL_SYS_TYPES_H
|
||||
#define _LIBSPL_SYS_TYPES_H
|
||||
|
||||
#if defined(HAVE_MAKEDEV_IN_SYSMACROS)
|
||||
#include <sys/sysmacros.h>
|
||||
#elif defined(HAVE_MAKEDEV_IN_MKDEV)
|
||||
#include <sys/mkdev.h>
|
||||
#endif
|
||||
|
||||
#include <sys/isa_defs.h>
|
||||
#include <sys/feature_tests.h>
|
||||
#include_next <sys/types.h>
|
||||
#include <sys/param.h> /* for NBBY */
|
||||
#include <sys/types32.h>
|
||||
#include <sys/va_list.h>
|
||||
|
||||
|
@ -53,7 +58,6 @@ typedef u_longlong_t u_offset_t;
|
|||
typedef u_longlong_t len_t;
|
||||
typedef longlong_t diskaddr_t;
|
||||
|
||||
typedef ulong_t pfn_t; /* page frame number */
|
||||
typedef ulong_t pgcnt_t; /* number of pages */
|
||||
typedef long spgcnt_t; /* signed number of pages */
|
||||
|
||||
|
@ -96,4 +100,6 @@ typedef union {
|
|||
} lloff_t;
|
||||
#endif
|
||||
|
||||
#include <sys/param.h> /* for NBBY */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3315,8 +3315,9 @@ zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
|
|||
char name[ZFS_MAXNAMELEN];
|
||||
int rv = 0;
|
||||
|
||||
(void) snprintf(name, sizeof (name),
|
||||
"%s@%s", zhp->zfs_name, dd->snapname);
|
||||
if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
|
||||
dd->snapname) >= sizeof (name))
|
||||
return (EINVAL);
|
||||
|
||||
if (lzc_exists(name))
|
||||
verify(nvlist_add_boolean(dd->nvl, name) == 0);
|
||||
|
@ -3534,8 +3535,9 @@ zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
|
|||
int rv = 0;
|
||||
|
||||
if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
|
||||
(void) snprintf(name, sizeof (name),
|
||||
"%s@%s", zfs_get_name(zhp), sd->sd_snapname);
|
||||
if (snprintf(name, sizeof (name), "%s@%s", zfs_get_name(zhp),
|
||||
sd->sd_snapname) >= sizeof (name))
|
||||
return (EINVAL);
|
||||
|
||||
fnvlist_add_boolean(sd->sd_nvl, name);
|
||||
|
||||
|
@ -3889,7 +3891,6 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||
}
|
||||
|
||||
if (recursive) {
|
||||
|
||||
parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
|
||||
if (parentname == NULL) {
|
||||
ret = -1;
|
||||
|
@ -3902,8 +3903,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||
ret = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
|
||||
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0,
|
||||
force_unmount ? MS_FORCE : 0)) == NULL)
|
||||
return (-1);
|
||||
|
@ -3952,23 +3952,23 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
|||
* On failure, we still want to remount any filesystems that
|
||||
* were previously mounted, so we don't alter the system state.
|
||||
*/
|
||||
if (!recursive)
|
||||
if (cl != NULL)
|
||||
(void) changelist_postfix(cl);
|
||||
} else {
|
||||
if (!recursive) {
|
||||
if (cl != NULL) {
|
||||
changelist_rename(cl, zfs_get_name(zhp), target);
|
||||
ret = changelist_postfix(cl);
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
if (parentname) {
|
||||
if (parentname != NULL) {
|
||||
free(parentname);
|
||||
}
|
||||
if (zhrp) {
|
||||
if (zhrp != NULL) {
|
||||
zfs_close(zhrp);
|
||||
}
|
||||
if (cl) {
|
||||
if (cl != NULL) {
|
||||
changelist_free(cl);
|
||||
}
|
||||
return (ret);
|
||||
|
@ -4259,8 +4259,9 @@ zfs_hold_one(zfs_handle_t *zhp, void *arg)
|
|||
char name[ZFS_MAXNAMELEN];
|
||||
int rv = 0;
|
||||
|
||||
(void) snprintf(name, sizeof (name),
|
||||
"%s@%s", zhp->zfs_name, ha->snapname);
|
||||
if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
|
||||
ha->snapname) >= sizeof (name))
|
||||
return (EINVAL);
|
||||
|
||||
if (lzc_exists(name))
|
||||
fnvlist_add_string(ha->nvl, name, ha->tag);
|
||||
|
@ -4379,8 +4380,11 @@ zfs_release_one(zfs_handle_t *zhp, void *arg)
|
|||
int rv = 0;
|
||||
nvlist_t *existing_holds;
|
||||
|
||||
(void) snprintf(name, sizeof (name),
|
||||
"%s@%s", zhp->zfs_name, ha->snapname);
|
||||
if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
|
||||
ha->snapname) >= sizeof (name)) {
|
||||
ha->error = EINVAL;
|
||||
rv = EINVAL;
|
||||
}
|
||||
|
||||
if (lzc_get_holds(name, &existing_holds) != 0) {
|
||||
ha->error = ENOENT;
|
||||
|
|
|
@ -97,6 +97,8 @@ typedef struct pool_list {
|
|||
name_entry_t *names;
|
||||
} pool_list_t;
|
||||
|
||||
#define DEV_BYID_PATH "/dev/disk/by-id/"
|
||||
|
||||
static char *
|
||||
get_devid(const char *path)
|
||||
{
|
||||
|
@ -121,6 +123,40 @@ get_devid(const char *path)
|
|||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait up to timeout_ms for udev to set up the device node. The device is
|
||||
* considered ready when the provided path have been verified to exist and
|
||||
* it has been allowed to settle. At this point the device the device can
|
||||
* be accessed reliably. Depending on the complexity of the udev rules thisi
|
||||
* process could take several seconds.
|
||||
*/
|
||||
int
|
||||
zpool_label_disk_wait(char *path, int timeout_ms)
|
||||
{
|
||||
int settle_ms = 50;
|
||||
long sleep_ms = 10;
|
||||
hrtime_t start, settle;
|
||||
struct stat64 statbuf;
|
||||
|
||||
start = gethrtime();
|
||||
settle = 0;
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
if ((stat64(path, &statbuf) == 0) && (errno == 0)) {
|
||||
if (settle == 0)
|
||||
settle = gethrtime();
|
||||
else if (NSEC2MSEC(gethrtime() - settle) >= settle_ms)
|
||||
return (0);
|
||||
} else if (errno != ENOENT) {
|
||||
return (errno);
|
||||
}
|
||||
|
||||
usleep(sleep_ms * MILLISEC);
|
||||
} while (NSEC2MSEC(gethrtime() - start) < timeout_ms);
|
||||
|
||||
return (ENODEV);
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through and fix up any path and/or devid information for the given vdev
|
||||
|
@ -162,7 +198,6 @@ fix_paths(nvlist_t *nv, name_entry_t *names)
|
|||
best = NULL;
|
||||
for (ne = names; ne != NULL; ne = ne->ne_next) {
|
||||
if (ne->ne_guid == guid) {
|
||||
|
||||
if (path == NULL) {
|
||||
best = ne;
|
||||
break;
|
||||
|
@ -186,7 +221,7 @@ fix_paths(nvlist_t *nv, name_entry_t *names)
|
|||
}
|
||||
|
||||
/* Prefer paths earlier in the search order. */
|
||||
if (best->ne_num_labels == best->ne_num_labels &&
|
||||
if (ne->ne_num_labels == best->ne_num_labels &&
|
||||
ne->ne_order < best->ne_order) {
|
||||
best = ne;
|
||||
continue;
|
||||
|
@ -352,6 +387,118 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
|
|||
return (0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBBLKID
|
||||
static int
|
||||
add_path(libzfs_handle_t *hdl, pool_list_t *pools, uint64_t pool_guid,
|
||||
uint64_t vdev_guid, const char *path, int order)
|
||||
{
|
||||
nvlist_t *label;
|
||||
uint64_t guid;
|
||||
int error, fd, num_labels;
|
||||
|
||||
fd = open64(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return (errno);
|
||||
|
||||
error = zpool_read_label(fd, &label, &num_labels);
|
||||
close(fd);
|
||||
|
||||
if (error || label == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
error = nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID, &guid);
|
||||
if (error || guid != pool_guid) {
|
||||
nvlist_free(label);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
error = nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &guid);
|
||||
if (error || guid != vdev_guid) {
|
||||
nvlist_free(label);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
error = add_config(hdl, pools, path, order, num_labels, label);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
add_configs_from_label_impl(libzfs_handle_t *hdl, pool_list_t *pools,
|
||||
nvlist_t *nvroot, uint64_t pool_guid, uint64_t vdev_guid)
|
||||
{
|
||||
char udevpath[MAXPATHLEN];
|
||||
char *path;
|
||||
nvlist_t **child;
|
||||
uint_t c, children;
|
||||
uint64_t guid;
|
||||
int error;
|
||||
|
||||
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
|
||||
&child, &children) == 0) {
|
||||
for (c = 0; c < children; c++) {
|
||||
error = add_configs_from_label_impl(hdl, pools,
|
||||
child[c], pool_guid, vdev_guid);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (nvroot == NULL)
|
||||
return (0);
|
||||
|
||||
error = nvlist_lookup_uint64(nvroot, ZPOOL_CONFIG_GUID, &guid);
|
||||
if ((error != 0) || (guid != vdev_guid))
|
||||
return (0);
|
||||
|
||||
error = nvlist_lookup_string(nvroot, ZPOOL_CONFIG_PATH, &path);
|
||||
if (error == 0)
|
||||
(void) add_path(hdl, pools, pool_guid, vdev_guid, path, 0);
|
||||
|
||||
error = nvlist_lookup_string(nvroot, ZPOOL_CONFIG_DEVID, &path);
|
||||
if (error == 0) {
|
||||
sprintf(udevpath, "%s%s", DEV_BYID_PATH, path);
|
||||
(void) add_path(hdl, pools, pool_guid, vdev_guid, udevpath, 1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a disk label call add_config() for all known paths to the device
|
||||
* as described by the label itself. The paths are added in the following
|
||||
* priority order: 'path', 'devid', 'devnode'. As these alternate paths are
|
||||
* added the labels are verified to make sure they refer to the same device.
|
||||
*/
|
||||
static int
|
||||
add_configs_from_label(libzfs_handle_t *hdl, pool_list_t *pools,
|
||||
char *devname, int num_labels, nvlist_t *label)
|
||||
{
|
||||
nvlist_t *nvroot;
|
||||
uint64_t pool_guid;
|
||||
uint64_t vdev_guid;
|
||||
int error;
|
||||
|
||||
if (nvlist_lookup_nvlist(label, ZPOOL_CONFIG_VDEV_TREE, &nvroot) ||
|
||||
nvlist_lookup_uint64(label, ZPOOL_CONFIG_POOL_GUID, &pool_guid) ||
|
||||
nvlist_lookup_uint64(label, ZPOOL_CONFIG_GUID, &vdev_guid))
|
||||
return (ENOENT);
|
||||
|
||||
/* Allow devlinks to stabilize so all paths are available. */
|
||||
zpool_label_disk_wait(devname, DISK_LABEL_WAIT);
|
||||
|
||||
/* Add alternate paths as described by the label vdev_tree. */
|
||||
(void) add_configs_from_label_impl(hdl, pools, nvroot,
|
||||
pool_guid, vdev_guid);
|
||||
|
||||
/* Add the device node /dev/sdX path as a last resort. */
|
||||
error = add_config(hdl, pools, devname, 100, num_labels, label);
|
||||
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_LIBBLKID */
|
||||
|
||||
/*
|
||||
* Returns true if the named pool matches the given GUID.
|
||||
*/
|
||||
|
@ -975,9 +1122,7 @@ zpool_find_import_blkid(libzfs_handle_t *hdl, pool_list_t *pools)
|
|||
blkid_cache cache;
|
||||
blkid_dev_iterate iter;
|
||||
blkid_dev dev;
|
||||
const char *devname;
|
||||
nvlist_t *config;
|
||||
int fd, err, num_labels;
|
||||
int err;
|
||||
|
||||
err = blkid_get_cache(&cache, NULL);
|
||||
if (err != 0) {
|
||||
|
@ -1008,25 +1153,23 @@ zpool_find_import_blkid(libzfs_handle_t *hdl, pool_list_t *pools)
|
|||
}
|
||||
|
||||
while (blkid_dev_next(iter, &dev) == 0) {
|
||||
devname = blkid_dev_devname(dev);
|
||||
nvlist_t *label;
|
||||
char *devname;
|
||||
int fd, num_labels;
|
||||
|
||||
devname = (char *) blkid_dev_devname(dev);
|
||||
if ((fd = open64(devname, O_RDONLY)) < 0)
|
||||
continue;
|
||||
|
||||
err = zpool_read_label(fd, &config, &num_labels);
|
||||
err = zpool_read_label(fd, &label, &num_labels);
|
||||
(void) close(fd);
|
||||
|
||||
if (err != 0) {
|
||||
(void) no_memory(hdl);
|
||||
goto err_blkid3;
|
||||
}
|
||||
if (err || label == NULL)
|
||||
continue;
|
||||
|
||||
if (config != NULL) {
|
||||
err = add_config(hdl, pools, devname, 0,
|
||||
num_labels, config);
|
||||
if (err != 0)
|
||||
goto err_blkid3;
|
||||
}
|
||||
add_configs_from_label(hdl, pools, devname, num_labels, label);
|
||||
}
|
||||
err = 0;
|
||||
|
||||
err_blkid3:
|
||||
blkid_dev_iterate_end(iter);
|
||||
|
@ -1194,16 +1337,33 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
|
|||
|
||||
if (config != NULL) {
|
||||
boolean_t matched = B_TRUE;
|
||||
boolean_t aux = B_FALSE;
|
||||
char *pname;
|
||||
|
||||
if ((iarg->poolname != NULL) &&
|
||||
/*
|
||||
* Check if it's a spare or l2cache device. If
|
||||
* it is, we need to skip the name and guid
|
||||
* check since they don't exist on aux device
|
||||
* label.
|
||||
*/
|
||||
if (iarg->poolname != NULL ||
|
||||
iarg->guid != 0) {
|
||||
uint64_t state;
|
||||
aux = nvlist_lookup_uint64(config,
|
||||
ZPOOL_CONFIG_POOL_STATE,
|
||||
&state) == 0 &&
|
||||
(state == POOL_STATE_SPARE ||
|
||||
state == POOL_STATE_L2CACHE);
|
||||
}
|
||||
|
||||
if ((iarg->poolname != NULL) && !aux &&
|
||||
(nvlist_lookup_string(config,
|
||||
ZPOOL_CONFIG_POOL_NAME, &pname) == 0)) {
|
||||
|
||||
if (strcmp(iarg->poolname, pname))
|
||||
matched = B_FALSE;
|
||||
|
||||
} else if (iarg->guid != 0) {
|
||||
} else if (iarg->guid != 0 && !aux) {
|
||||
uint64_t this_guid;
|
||||
|
||||
matched = nvlist_lookup_uint64(config,
|
||||
|
|
|
@ -204,8 +204,11 @@ zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data)
|
|||
bmark_name = nvpair_name(pair);
|
||||
bmark_props = fnvpair_value_nvlist(pair);
|
||||
|
||||
(void) snprintf(name, sizeof (name), "%s#%s", zhp->zfs_name,
|
||||
bmark_name);
|
||||
if (snprintf(name, sizeof (name), "%s#%s", zhp->zfs_name,
|
||||
bmark_name) >= sizeof (name)) {
|
||||
err = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
nzhp = make_bookmark_handle(zhp, name, bmark_props);
|
||||
if (nzhp == NULL)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -363,6 +364,14 @@ zfs_add_options(zfs_handle_t *zhp, char *options, int len)
|
|||
|
||||
error = zfs_add_option(zhp, options, len,
|
||||
ZFS_PROP_ATIME, MNTOPT_ATIME, MNTOPT_NOATIME);
|
||||
/*
|
||||
* don't add relatime/strictatime when atime=off, otherwise strictatime
|
||||
* will force atime=on
|
||||
*/
|
||||
if (strstr(options, MNTOPT_NOATIME) == NULL) {
|
||||
error = zfs_add_option(zhp, options, len,
|
||||
ZFS_PROP_RELATIME, MNTOPT_RELATIME, MNTOPT_STRICTATIME);
|
||||
}
|
||||
error = error ? error : zfs_add_option(zhp, options, len,
|
||||
ZFS_PROP_DEVICES, MNTOPT_DEVICES, MNTOPT_NODEVICES);
|
||||
error = error ? error : zfs_add_option(zhp, options, len,
|
||||
|
@ -744,13 +753,6 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
|
|||
if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
|
||||
return (0);
|
||||
|
||||
if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
|
||||
(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
|
||||
dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
|
||||
zfs_get_name(zhp), sa_errorstr(ret));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
|
||||
/*
|
||||
* Return success if there are no share options.
|
||||
|
@ -761,6 +763,14 @@ zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
|
|||
strcmp(shareopts, "off") == 0)
|
||||
continue;
|
||||
|
||||
ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API);
|
||||
if (ret != SA_OK) {
|
||||
(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
|
||||
dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
|
||||
zfs_get_name(zhp), sa_errorstr(ret));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the 'zoned' property is set, then zfs_is_mountable()
|
||||
* will have already bailed out if we are in the global zone.
|
||||
|
@ -1072,7 +1082,7 @@ libzfs_dataset_cmp(const void *a, const void *b)
|
|||
if (gotb)
|
||||
return (1);
|
||||
|
||||
return (strcmp(zfs_get_name(a), zfs_get_name(b)));
|
||||
return (strcmp(zfs_get_name(*za), zfs_get_name(*zb)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1378,8 +1378,7 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
|
|||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"device '%s' contains an EFI label and "
|
||||
"cannot be used on root pools."),
|
||||
zpool_vdev_name(hdl, NULL, spares[s],
|
||||
B_FALSE));
|
||||
zpool_vdev_name(hdl, NULL, spares[s], 0));
|
||||
return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
|
||||
}
|
||||
}
|
||||
|
@ -1700,7 +1699,7 @@ print_vdev_tree(libzfs_handle_t *hdl, const char *name, nvlist_t *nv,
|
|||
return;
|
||||
|
||||
for (c = 0; c < children; c++) {
|
||||
vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
|
||||
vname = zpool_vdev_name(hdl, NULL, child[c], VDEV_NAME_TYPE_ID);
|
||||
print_vdev_tree(hdl, vname, child[c], indent + 2);
|
||||
free(vname);
|
||||
}
|
||||
|
@ -1892,7 +1891,12 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
|
|||
"one or more devices are already in use\n"));
|
||||
(void) zfs_error(hdl, EZFS_BADDEV, desc);
|
||||
break;
|
||||
|
||||
case ENAMETOOLONG:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"new name of at least one dataset is longer than "
|
||||
"the maximum allowable length"));
|
||||
(void) zfs_error(hdl, EZFS_NAMETOOLONG, desc);
|
||||
break;
|
||||
default:
|
||||
(void) zpool_standard_error(hdl, error, desc);
|
||||
zpool_explain_recover(hdl,
|
||||
|
@ -2688,7 +2692,7 @@ zpool_vdev_attach(zpool_handle_t *zhp,
|
|||
verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
|
||||
ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
|
||||
|
||||
if ((newname = zpool_vdev_name(NULL, NULL, child[0], B_FALSE)) == NULL)
|
||||
if ((newname = zpool_vdev_name(NULL, NULL, child[0], 0)) == NULL)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
|
@ -2879,11 +2883,11 @@ find_vdev_entry(zpool_handle_t *zhp, nvlist_t **mchild, uint_t mchildren,
|
|||
for (mc = 0; mc < mchildren; mc++) {
|
||||
uint_t sc;
|
||||
char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
|
||||
mchild[mc], B_FALSE);
|
||||
mchild[mc], 0);
|
||||
|
||||
for (sc = 0; sc < schildren; sc++) {
|
||||
char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
|
||||
schild[sc], B_FALSE);
|
||||
schild[sc], 0);
|
||||
boolean_t result = (strcmp(mpath, spath) == 0);
|
||||
|
||||
free(spath);
|
||||
|
@ -3424,21 +3428,34 @@ strip_partition(libzfs_handle_t *hdl, char *path)
|
|||
*/
|
||||
char *
|
||||
zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
||||
boolean_t verbose)
|
||||
int name_flags)
|
||||
{
|
||||
char *path, *devid, *type;
|
||||
char *path, *devid, *type, *env;
|
||||
uint64_t value;
|
||||
char buf[PATH_BUF_LEN];
|
||||
char tmpbuf[PATH_BUF_LEN];
|
||||
vdev_stat_t *vs;
|
||||
uint_t vsc;
|
||||
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
|
||||
&value) == 0) {
|
||||
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
|
||||
&value) == 0);
|
||||
(void) snprintf(buf, sizeof (buf), "%llu",
|
||||
(u_longlong_t)value);
|
||||
env = getenv("ZPOOL_VDEV_NAME_PATH");
|
||||
if (env && (strtoul(env, NULL, 0) > 0 ||
|
||||
!strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
|
||||
name_flags |= VDEV_NAME_PATH;
|
||||
|
||||
env = getenv("ZPOOL_VDEV_NAME_GUID");
|
||||
if (env && (strtoul(env, NULL, 0) > 0 ||
|
||||
!strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
|
||||
name_flags |= VDEV_NAME_GUID;
|
||||
|
||||
env = getenv("ZPOOL_VDEV_NAME_FOLLOW_LINKS");
|
||||
if (env && (strtoul(env, NULL, 0) > 0 ||
|
||||
!strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
|
||||
name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT, &value) == 0 ||
|
||||
name_flags & VDEV_NAME_GUID) {
|
||||
nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &value);
|
||||
(void) snprintf(buf, sizeof (buf), "%llu", (u_longlong_t)value);
|
||||
path = buf;
|
||||
} else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
|
||||
/*
|
||||
|
@ -3479,11 +3496,21 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
|||
devid_str_free(newdevid);
|
||||
}
|
||||
|
||||
if (name_flags & VDEV_NAME_FOLLOW_LINKS) {
|
||||
char *rp = realpath(path, NULL);
|
||||
if (rp) {
|
||||
strlcpy(buf, rp, sizeof (buf));
|
||||
path = buf;
|
||||
free(rp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For a block device only use the name.
|
||||
*/
|
||||
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
|
||||
if (strcmp(type, VDEV_TYPE_DISK) == 0) {
|
||||
if ((strcmp(type, VDEV_TYPE_DISK) == 0) &&
|
||||
!(name_flags & VDEV_NAME_PATH)) {
|
||||
path = strrchr(path, '/');
|
||||
path++;
|
||||
}
|
||||
|
@ -3491,8 +3518,8 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
|||
/*
|
||||
* Remove the partition from the path it this is a whole disk.
|
||||
*/
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
|
||||
&value) == 0 && value) {
|
||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value)
|
||||
== 0 && value && !(name_flags & VDEV_NAME_PATH)) {
|
||||
return (strip_partition(hdl, path));
|
||||
}
|
||||
} else {
|
||||
|
@ -3514,7 +3541,7 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
|||
* We identify each top-level vdev by using a <type-id>
|
||||
* naming convention.
|
||||
*/
|
||||
if (verbose) {
|
||||
if (name_flags & VDEV_NAME_TYPE_ID) {
|
||||
uint64_t id;
|
||||
|
||||
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
|
||||
|
@ -4072,29 +4099,6 @@ find_start_block(nvlist_t *config)
|
|||
return (MAXOFFSET_T);
|
||||
}
|
||||
|
||||
int
|
||||
zpool_label_disk_wait(char *path, int timeout)
|
||||
{
|
||||
struct stat64 statbuf;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Wait timeout miliseconds for a newly created device to be available
|
||||
* from the given path. There is a small window when a /dev/ device
|
||||
* will exist and the udev link will not, so we must wait for the
|
||||
* symlink. Depending on the udev rules this may take a few seconds.
|
||||
*/
|
||||
for (i = 0; i < timeout; i++) {
|
||||
usleep(1000);
|
||||
|
||||
errno = 0;
|
||||
if ((stat64(path, &statbuf) == 0) && (errno == 0))
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
zpool_label_disk_check(char *path)
|
||||
{
|
||||
|
@ -4120,6 +4124,32 @@ zpool_label_disk_check(char *path)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a unique partition name for the ZFS member. Partitions must
|
||||
* have unique names to ensure udev will be able to create symlinks under
|
||||
* /dev/disk/by-partlabel/ for all pool members. The partition names are
|
||||
* of the form <pool>-<unique-id>.
|
||||
*/
|
||||
static void
|
||||
zpool_label_name(char *label_name, int label_size)
|
||||
{
|
||||
uint64_t id = 0;
|
||||
int fd;
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd > 0) {
|
||||
if (read(fd, &id, sizeof (id)) != sizeof (id))
|
||||
id = 0;
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
id = (((uint64_t)rand()) << 32) | (uint64_t)rand();
|
||||
|
||||
snprintf(label_name, label_size, "zfs-%016llx", (u_longlong_t) id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Label an individual disk. The name provided is the short name,
|
||||
* stripped of any leading /dev path.
|
||||
|
@ -4210,7 +4240,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
|
|||
* can get, in the absence of V_OTHER.
|
||||
*/
|
||||
vtoc->efi_parts[0].p_tag = V_USR;
|
||||
(void) strcpy(vtoc->efi_parts[0].p_name, "zfs");
|
||||
zpool_label_name(vtoc->efi_parts[0].p_name, EFI_PART_NAME_LEN);
|
||||
|
||||
vtoc->efi_parts[8].p_start = slice_size + start_block;
|
||||
vtoc->efi_parts[8].p_size = resv;
|
||||
|
@ -4234,12 +4264,11 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
|
|||
(void) close(fd);
|
||||
efi_free(vtoc);
|
||||
|
||||
/* Wait for the first expected partition to appear. */
|
||||
|
||||
(void) snprintf(path, sizeof (path), "%s/%s", DISK_ROOT, name);
|
||||
(void) zfs_append_partition(path, MAXPATHLEN);
|
||||
|
||||
rval = zpool_label_disk_wait(path, 3000);
|
||||
/* Wait to udev to signal use the device has settled. */
|
||||
rval = zpool_label_disk_wait(path, DISK_LABEL_WAIT);
|
||||
if (rval) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to "
|
||||
"detect device partitions on '%s': %d"), path, rval);
|
||||
|
|
|
@ -1487,9 +1487,13 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
|
|||
drr_versioninfo, DMU_COMPOUNDSTREAM);
|
||||
DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
|
||||
drr_versioninfo, featureflags);
|
||||
(void) snprintf(drr.drr_u.drr_begin.drr_toname,
|
||||
if (snprintf(drr.drr_u.drr_begin.drr_toname,
|
||||
sizeof (drr.drr_u.drr_begin.drr_toname),
|
||||
"%s@%s", zhp->zfs_name, tosnap);
|
||||
"%s@%s", zhp->zfs_name, tosnap) >=
|
||||
sizeof (drr.drr_u.drr_begin.drr_toname)) {
|
||||
err = EINVAL;
|
||||
goto stderr_out;
|
||||
}
|
||||
drr.drr_payloadlen = buflen;
|
||||
err = cksum_and_write(&drr, sizeof (drr), &zc, outfd);
|
||||
|
||||
|
@ -2003,7 +2007,7 @@ created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
|
|||
uint64_t guid1, uint64_t guid2)
|
||||
{
|
||||
nvlist_t *nvfs;
|
||||
char *fsname, *snapname;
|
||||
char *fsname = NULL, *snapname = NULL;
|
||||
char buf[ZFS_MAXNAMELEN];
|
||||
int rv;
|
||||
zfs_handle_t *guid1hdl, *guid2hdl;
|
||||
|
@ -2689,7 +2693,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|||
ENOENT);
|
||||
|
||||
if (stream_avl != NULL) {
|
||||
char *snapname;
|
||||
char *snapname = NULL;
|
||||
nvlist_t *lookup = NULL;
|
||||
nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
|
||||
&snapname);
|
||||
nvlist_t *props;
|
||||
|
@ -2710,6 +2715,11 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
|||
nvlist_free(props);
|
||||
if (ret != 0)
|
||||
return (-1);
|
||||
|
||||
if (0 == nvlist_lookup_nvlist(fs, "snapprops", &lookup)) {
|
||||
VERIFY(0 == nvlist_lookup_nvlist(lookup,
|
||||
snapname, &snapprops_nvlist));
|
||||
}
|
||||
}
|
||||
|
||||
cp = NULL;
|
||||
|
|
|
@ -1024,16 +1024,18 @@ zfs_strcmp_pathname(char *name, char *cmp, int wholedisk)
|
|||
int path_len, cmp_len;
|
||||
char path_name[MAXPATHLEN];
|
||||
char cmp_name[MAXPATHLEN];
|
||||
char *dir;
|
||||
char *dir, *dup;
|
||||
|
||||
/* Strip redundant slashes if one exists due to ZPOOL_IMPORT_PATH */
|
||||
memset(cmp_name, 0, MAXPATHLEN);
|
||||
dir = strtok(cmp, "/");
|
||||
dup = strdup(cmp);
|
||||
dir = strtok(dup, "/");
|
||||
while (dir) {
|
||||
strcat(cmp_name, "/");
|
||||
strcat(cmp_name, dir);
|
||||
dir = strtok(NULL, "/");
|
||||
}
|
||||
free(dup);
|
||||
|
||||
if (name[0] != '/')
|
||||
return (zfs_strcmp_shortname(name, cmp_name, wholedisk));
|
||||
|
@ -1350,7 +1352,8 @@ zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (cbp->cb_columns[i + 1] == GET_COL_NONE)
|
||||
if (i == (ZFS_GET_NCOLS - 1) ||
|
||||
cbp->cb_columns[i + 1] == GET_COL_NONE)
|
||||
(void) printf("%s", str);
|
||||
else if (cbp->cb_scripted)
|
||||
(void) printf("%s\t", str);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -1322,3 +1323,24 @@ spl_fstrans_check(void)
|
|||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
zvol_create_minors(spa_t *spa, const char *name, boolean_t async)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
zvol_remove_minor(spa_t *spa, const char *name, boolean_t async)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
zvol_remove_minors(spa_t *spa, const char *name, boolean_t async)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname,
|
||||
boolean_t async)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -24,6 +24,19 @@ Description of the different parameters to the ZFS module.
|
|||
.sp
|
||||
.LP
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.na
|
||||
\fBignore_hole_birth\fR (int)
|
||||
.ad
|
||||
.RS 12n
|
||||
When set, the hole_birth optimization will not be used, and all holes will
|
||||
always be sent on zfs send. Useful if you suspect your datasets are affected
|
||||
by a bug in hole_birth.
|
||||
.sp
|
||||
Use \fB1\fR (default) for on and \fB0\fR for off.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.na
|
||||
|
@ -870,7 +883,12 @@ Default value: \fB10\fR.
|
|||
Minimum asynchronous write I/Os active to each device.
|
||||
See the section "ZFS I/O SCHEDULER".
|
||||
.sp
|
||||
Default value: \fB1\fR.
|
||||
Lower values are associated with better latency on rotational media but poorer
|
||||
resilver performance. The default value of 2 was chosen as a compromise. A
|
||||
value of 3 has been shown to improve resilver performance further at a cost of
|
||||
further increasing latency.
|
||||
.sp
|
||||
Default value: \fB2\fR.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
|
@ -1598,6 +1616,23 @@ Prioritize requeued I/O
|
|||
Default value: \fB0\fR.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.na
|
||||
\fBzio_taskq_batch_pct\fR (uint)
|
||||
.ad
|
||||
.RS 12n
|
||||
Percentage of online CPUs (or CPU cores, etc) which will run a worker thread
|
||||
for IO. These workers are responsible for IO work such as compression and
|
||||
checksum calculations. Fractional number of CPUs will be rounded down.
|
||||
.sp
|
||||
The default value of 75 was chosen to avoid using all CPUs which can result in
|
||||
latency issues and inconsistent application performance, especially when high
|
||||
compression is enabled.
|
||||
.sp
|
||||
Default value: \fB75\fR.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.na
|
||||
|
|
201
man/man8/zpool.8
201
man/man8/zpool.8
|
@ -26,7 +26,7 @@ zpool \- configures ZFS storage pools
|
|||
|
||||
.LP
|
||||
.nf
|
||||
\fBzpool add\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fIvdev\fR ...
|
||||
\fBzpool add\fR [\fB-fgLnP\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fIvdev\fR ...
|
||||
.fi
|
||||
|
||||
.LP
|
||||
|
@ -94,7 +94,7 @@ zpool \- configures ZFS storage pools
|
|||
|
||||
.LP
|
||||
.nf
|
||||
\fBzpool iostat\fR [\fB-T\fR d | u ] [\fB-v\fR] [\fB-y\fR] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]
|
||||
\fBzpool iostat\fR [\fB-T\fR d | u ] [\fB-gLPvy\fR] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]
|
||||
.fi
|
||||
|
||||
.LP
|
||||
|
@ -104,7 +104,7 @@ zpool \- configures ZFS storage pools
|
|||
|
||||
.LP
|
||||
.nf
|
||||
\fBzpool list\fR [\fB-T\fR d | u ] [\fB-Hv\fR] [\fB-o\fR \fIproperty\fR[,...]] [\fIpool\fR] ...
|
||||
\fBzpool list\fR [\fB-T\fR d | u ] [\fB-HgLPv\fR] [\fB-o\fR \fIproperty\fR[,...]] [\fIpool\fR] ...
|
||||
[\fIinterval\fR[\fIcount\fR]]
|
||||
.fi
|
||||
|
||||
|
@ -150,12 +150,12 @@ zpool \- configures ZFS storage pools
|
|||
|
||||
.LP
|
||||
.nf
|
||||
\fBzpool split\fR [\fB-n\fR] [\fB-R\fR \fIaltroot\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fInewpool\fR [\fIdevice\fR ...]
|
||||
\fBzpool split\fR [\fB-gLnP\fR] [\fB-R\fR \fIaltroot\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fInewpool\fR [\fIdevice\fR ...]
|
||||
.fi
|
||||
|
||||
.LP
|
||||
.nf
|
||||
\fBzpool status\fR [\fB-xvD\fR] [\fB-T\fR d | u] [\fIpool\fR] ... [\fIinterval\fR [\fIcount\fR]]
|
||||
\fBzpool status\fR [\fB-gLPvxD\fR] [\fB-T\fR d | u] [\fIpool\fR] ... [\fIinterval\fR [\fIcount\fR]]
|
||||
.fi
|
||||
|
||||
.LP
|
||||
|
@ -836,7 +836,7 @@ Displays a help message.
|
|||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fBzpool add\fR [\fB-fn\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fIvdev\fR ...\fR
|
||||
\fB\fBzpool add\fR [\fB-fgLnP\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fIvdev\fR ...\fR
|
||||
.ad
|
||||
.sp .6
|
||||
.RS 4n
|
||||
|
@ -852,6 +852,28 @@ Adds the specified virtual devices to the given pool. The \fIvdev\fR specificati
|
|||
Forces use of \fBvdev\fRs, even if they appear in use or specify a conflicting replication level. Not all devices can be overridden in this manner.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-g\fR\fR
|
||||
.ad
|
||||
.RS 6n
|
||||
.rt
|
||||
Display vdev GUIDs instead of the normal device names. These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-L\fR\fR
|
||||
.ad
|
||||
.RS 6n
|
||||
.rt
|
||||
Display real paths for vdevs resolving all symbolic links. This can be used to look up the current block device name regardless of the /dev/disk/ path used to open it.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
|
@ -863,6 +885,17 @@ Forces use of \fBvdev\fRs, even if they appear in use or specify a conflicting r
|
|||
Displays the configuration that would be used without actually adding the \fBvdev\fRs. The actual pool creation can still fail due to insufficient privileges or device sharing.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-P\fR\fR
|
||||
.ad
|
||||
.RS 6n
|
||||
.rt
|
||||
Display full paths for vdevs instead of only the last component of the path. This can be used in conjunction with the \fB-L\fR flag.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
|
@ -1608,7 +1641,7 @@ Allows a pool to import when there is a missing log device.
|
|||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fBzpool iostat\fR [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-v\fR] [\fB-y\fR] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]\fR
|
||||
\fB\fBzpool iostat\fR [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-gLPvy\fR] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]\fR
|
||||
.ad
|
||||
.sp .6
|
||||
.RS 4n
|
||||
|
@ -1626,6 +1659,39 @@ Display a time stamp.
|
|||
Specify \fBu\fR for a printed representation of the internal representation of time. See \fBtime\fR(2). Specify \fBd\fR for standard date format. See \fBdate\fR(1).
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-g\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display vdev GUIDs instead of the normal device names. These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-L\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display real paths for vdevs resolving all symbolic links. This can be used to look up the current block device name regardless of the /dev/disk/ path used to open it.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-P\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display full paths for vdevs instead of only the last component of the path. This can be used in conjunction with the \fB-L\fR flag.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
|
@ -1676,7 +1742,7 @@ Treat exported or foreign devices as inactive.
|
|||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fBzpool list\fR [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-Hv\fR] [\fB-o\fR \fIprops\fR[,...]] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]\fR
|
||||
\fB\fBzpool list\fR [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-HgLPv\fR] [\fB-o\fR \fIprops\fR[,...]] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]\fR
|
||||
.ad
|
||||
.sp .6
|
||||
.RS 4n
|
||||
|
@ -1692,6 +1758,39 @@ Lists the given pools along with a health status and space usage. If no \fIpools
|
|||
Scripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-g\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display vdev GUIDs instead of the normal device names. These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-L\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display real paths for vdevs resolving all symbolic links. This can be used to look up the current block device name regardless of the /dev/disk/ path used to open it.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-P\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display full paths for vdevs instead of only the last component of the path. This can be used in conjunction with the \fB-L\fR flag.
|
||||
.RE
|
||||
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
|
@ -1886,7 +1985,7 @@ Sets the given property on the specified pool. See the "Properties" section for
|
|||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fBzpool split\fR [\fB-n\fR] [\fB-R\fR \fIaltroot\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fInewpool\fR [\fIdevice\fR ...]
|
||||
\fBzpool split\fR [\fB-gLnP\fR] [\fB-R\fR \fIaltroot\fR] [\fB-o\fR \fIproperty=value\fR] \fIpool\fR \fInewpool\fR [\fIdevice\fR ...]
|
||||
.ad
|
||||
.sp .6
|
||||
.RS 4n
|
||||
|
@ -1894,6 +1993,28 @@ Split devices off \fIpool\fR creating \fInewpool\fR. All \fBvdev\fRs in \fIpool\
|
|||
|
||||
The optional \fIdevice\fR specification causes the specified device(s) to be included in the new pool and, should any devices remain unspecified, the last device in each mirror is used as would be by default.
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-g\fR\fR
|
||||
.ad
|
||||
.RS 6n
|
||||
.rt
|
||||
Display vdev GUIDs instead of the normal device names. These GUIDs can be used in place of device names for the zpool detach/offline/remove/replace commands.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-L\fR\fR
|
||||
.ad
|
||||
.RS 6n
|
||||
.rt
|
||||
Display real paths for vdevs resolving all symbolic links. This can be used to look up the current block device name regardless of the /dev/disk/ path used to open it.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
|
@ -1905,6 +2026,17 @@ The optional \fIdevice\fR specification causes the specified device(s) to be inc
|
|||
Do dry run, do not actually perform the split. Print out the expected configuration of \fInewpool\fR.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-P\fR\fR
|
||||
.ad
|
||||
.RS 6n
|
||||
.rt
|
||||
Display full paths for vdevs instead of only the last component of the path. This can be used in conjunction with the \fB-L\fR flag.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
|
@ -1933,22 +2065,45 @@ Sets the specified property for \fInewpool\fR. See the “Properties” section
|
|||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fBzpool status\fR [\fB-xvD\fR] [\fB-T\fR d | u] [\fIpool\fR] ... [\fIinterval\fR [\fIcount\fR]]
|
||||
\fBzpool status\fR [\fB-gLPvxD\fR] [\fB-T\fR d | u] [\fIpool\fR] ... [\fIinterval\fR [\fIcount\fR]]
|
||||
.ad
|
||||
.sp .6
|
||||
.RS 4n
|
||||
Displays the detailed health status for the given pools. If no \fIpool\fR is specified, then the status of each pool in the system is displayed. For more information on pool and device health, see the "Device Failure and Recovery" section.
|
||||
.sp
|
||||
If a scrub or resilver is in progress, this command reports the percentage done and the estimated time to completion. Both of these are only approximate, because the amount of data in the pool and the other workloads on the system can change.
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-x\fR\fR
|
||||
\fB\fB-g\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Only display status for pools that are exhibiting errors or are otherwise unavailable. Warnings about pools not using the latest on-disk format will not be included.
|
||||
Display vdev GUIDs instead of the normal device names. These GUIDs can be used innplace of device names for the zpool detach/offline/remove/replace commands.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-L\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display real paths for vdevs resolving all symbolic links. This can be used to look up the current block device name regardless of the /dev/disk/ path used to open it.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-P\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Display full paths for vdevs instead of only the last component of the path. This can be used in conjunction with the \fB-L\fR flag.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
|
@ -1962,6 +2117,17 @@ Only display status for pools that are exhibiting errors or are otherwise unavai
|
|||
Displays verbose data error information, printing out a complete list of all data errors since the last complete pool scrub.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
.na
|
||||
\fB\fB-x\fR\fR
|
||||
.ad
|
||||
.RS 12n
|
||||
.rt
|
||||
Only display status for pools that are exhibiting errors or are otherwise unavailable. Warnings about pools not using the latest on-disk format will not be included.
|
||||
.RE
|
||||
|
||||
.sp
|
||||
.ne 2
|
||||
.mk
|
||||
|
@ -2401,6 +2567,17 @@ Cause \fBzpool\fR to dump core on exit for the purposes of running \fB::findleak
|
|||
.B "ZPOOL_IMPORT_PATH"
|
||||
The search path for devices or files to use with the pool. This is a colon-separated list of directories in which \fBzpool\fR looks for device nodes and files.
|
||||
Similar to the \fB-d\fR option in \fIzpool import\fR.
|
||||
.TP
|
||||
.B "ZPOOL_VDEV_NAME_GUID"
|
||||
Cause \fBzpool\fR subcommands to output vdev guids by default. This behavior
|
||||
is identical to the \fBzpool status -g\fR command line option.
|
||||
.TP
|
||||
.B "ZPOOL_VDEV_NAME_FOLLOW_LINKS"
|
||||
Cause \fBzpool\fR subcommands to follow links for vdev names by default. This behavior is identical to the \fBzpool status -L\fR command line option.
|
||||
.TP
|
||||
.B "ZPOOL_VDEV_NAME_PATH"
|
||||
Cause \fBzpool\fR subcommands to output full vdev path names by default. This
|
||||
behavior is identical to the \fBzpool status -p\fR command line option.
|
||||
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
|
|
|
@ -47,7 +47,7 @@ modules_install:
|
|||
KERNELRELEASE=@LINUX_VERSION@
|
||||
@# Remove extraneous build products when packaging
|
||||
kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@; \
|
||||
if [ -n $$kmoddir ]; then \
|
||||
if [ -n "$(DESTDIR)" ]; then \
|
||||
find $$kmoddir -name 'modules.*' | xargs $(RM); \
|
||||
fi
|
||||
sysmap=$(DESTDIR)$(INSTALL_MOD_PATH)/boot/System.map-@LINUX_VERSION@; \
|
||||
|
|
|
@ -630,7 +630,7 @@ avl_insert_here(
|
|||
void
|
||||
avl_add(avl_tree_t *tree, void *new_node)
|
||||
{
|
||||
avl_index_t where;
|
||||
avl_index_t where = 0;
|
||||
|
||||
/*
|
||||
* This is unfortunate. We want to call panic() here, even for
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2016 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <sys/stropts.h>
|
||||
|
@ -138,6 +139,11 @@ static int nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type,
|
|||
#define NVPAIR2I_NVP(nvp) \
|
||||
((i_nvp_t *)((size_t)(nvp) - offsetof(i_nvp_t, nvi_nvp)))
|
||||
|
||||
#ifdef _KERNEL
|
||||
int nvpair_max_recursion = 20;
|
||||
#else
|
||||
int nvpair_max_recursion = 100;
|
||||
#endif
|
||||
|
||||
int
|
||||
nv_alloc_init(nv_alloc_t *nva, const nv_alloc_ops_t *nvo, /* args */ ...)
|
||||
|
@ -2017,6 +2023,7 @@ typedef struct {
|
|||
const nvs_ops_t *nvs_ops;
|
||||
void *nvs_private;
|
||||
nvpriv_t *nvs_priv;
|
||||
int nvs_recursion;
|
||||
} nvstream_t;
|
||||
|
||||
/*
|
||||
|
@ -2168,9 +2175,16 @@ static int
|
|||
nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
|
||||
{
|
||||
switch (nvs->nvs_op) {
|
||||
case NVS_OP_ENCODE:
|
||||
return (nvs_operation(nvs, embedded, NULL));
|
||||
case NVS_OP_ENCODE: {
|
||||
int err;
|
||||
|
||||
if (nvs->nvs_recursion >= nvpair_max_recursion)
|
||||
return (EINVAL);
|
||||
nvs->nvs_recursion++;
|
||||
err = nvs_operation(nvs, embedded, NULL);
|
||||
nvs->nvs_recursion--;
|
||||
return (err);
|
||||
}
|
||||
case NVS_OP_DECODE: {
|
||||
nvpriv_t *priv;
|
||||
int err;
|
||||
|
@ -2183,8 +2197,12 @@ nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
|
|||
|
||||
nvlist_init(embedded, embedded->nvl_nvflag, priv);
|
||||
|
||||
if (nvs->nvs_recursion >= nvpair_max_recursion)
|
||||
return (EINVAL);
|
||||
nvs->nvs_recursion++;
|
||||
if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
|
||||
nvlist_free(embedded);
|
||||
nvs->nvs_recursion--;
|
||||
return (err);
|
||||
}
|
||||
default:
|
||||
|
@ -2272,6 +2290,7 @@ nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen, int encoding,
|
|||
return (EINVAL);
|
||||
|
||||
nvs.nvs_op = nvs_op;
|
||||
nvs.nvs_recursion = 0;
|
||||
|
||||
/*
|
||||
* For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and
|
||||
|
|
|
@ -1451,6 +1451,13 @@ arc_buf_info(arc_buf_t *ab, arc_buf_info_t *abi, int state_index)
|
|||
l2arc_buf_hdr_t *l2hdr = NULL;
|
||||
arc_state_t *state = NULL;
|
||||
|
||||
memset(abi, 0, sizeof (arc_buf_info_t));
|
||||
|
||||
if (hdr == NULL)
|
||||
return;
|
||||
|
||||
abi->abi_flags = hdr->b_flags;
|
||||
|
||||
if (HDR_HAS_L1HDR(hdr)) {
|
||||
l1hdr = &hdr->b_l1hdr;
|
||||
state = l1hdr->b_state;
|
||||
|
@ -1458,9 +1465,6 @@ arc_buf_info(arc_buf_t *ab, arc_buf_info_t *abi, int state_index)
|
|||
if (HDR_HAS_L2HDR(hdr))
|
||||
l2hdr = &hdr->b_l2hdr;
|
||||
|
||||
memset(abi, 0, sizeof (arc_buf_info_t));
|
||||
abi->abi_flags = hdr->b_flags;
|
||||
|
||||
if (l1hdr) {
|
||||
abi->abi_datacnt = l1hdr->b_datacnt;
|
||||
abi->abi_access = l1hdr->b_arc_access;
|
||||
|
@ -2697,12 +2701,7 @@ arc_prune_task(void *ptr)
|
|||
if (func != NULL)
|
||||
func(ap->p_adjust, ap->p_private);
|
||||
|
||||
/* Callback unregistered concurrently with execution */
|
||||
if (refcount_remove(&ap->p_refcnt, func) == 0) {
|
||||
ASSERT(!list_link_active(&ap->p_node));
|
||||
refcount_destroy(&ap->p_refcnt);
|
||||
kmem_free(ap, sizeof (*ap));
|
||||
}
|
||||
refcount_remove(&ap->p_refcnt, func);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3179,13 +3178,10 @@ arc_flush(spa_t *spa, boolean_t retry)
|
|||
void
|
||||
arc_shrink(int64_t to_free)
|
||||
{
|
||||
if (arc_c > arc_c_min) {
|
||||
|
||||
if (arc_c > arc_c_min + to_free)
|
||||
atomic_add_64(&arc_c, -to_free);
|
||||
else
|
||||
arc_c = arc_c_min;
|
||||
uint64_t c = arc_c;
|
||||
|
||||
if (c > to_free && c - to_free > arc_c_min) {
|
||||
arc_c = c - to_free;
|
||||
atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift));
|
||||
if (arc_c > arc_size)
|
||||
arc_c = MAX(arc_size, arc_c_min);
|
||||
|
@ -3193,6 +3189,8 @@ arc_shrink(int64_t to_free)
|
|||
arc_p = (arc_c >> 1);
|
||||
ASSERT(arc_c >= arc_c_min);
|
||||
ASSERT((int64_t)arc_p >= 0);
|
||||
} else {
|
||||
arc_c = arc_c_min;
|
||||
}
|
||||
|
||||
if (arc_size > arc_c)
|
||||
|
@ -3373,6 +3371,11 @@ arc_kmem_reap_now(void)
|
|||
}
|
||||
|
||||
for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) {
|
||||
#ifdef _ILP32
|
||||
/* reach upper limit of cache size on 32-bit */
|
||||
if (zio_buf_cache[i] == NULL)
|
||||
break;
|
||||
#endif
|
||||
if (zio_buf_cache[i] != prev_cache) {
|
||||
prev_cache = zio_buf_cache[i];
|
||||
kmem_cache_reap_now(zio_buf_cache[i]);
|
||||
|
@ -3757,7 +3760,7 @@ arc_adapt(int bytes, arc_state_t *state)
|
|||
* If we're within (2 * maxblocksize) bytes of the target
|
||||
* cache size, increment the target cache size
|
||||
*/
|
||||
VERIFY3U(arc_c, >=, 2ULL << SPA_MAXBLOCKSHIFT);
|
||||
ASSERT3U(arc_c, >=, 2ULL << SPA_MAXBLOCKSHIFT);
|
||||
if (arc_size >= arc_c - (2ULL << SPA_MAXBLOCKSHIFT)) {
|
||||
atomic_add_64(&arc_c, (int64_t)bytes);
|
||||
if (arc_c > arc_c_max)
|
||||
|
@ -4316,17 +4319,11 @@ top:
|
|||
|
||||
/*
|
||||
* Gracefully handle a damaged logical block size as a
|
||||
* checksum error by passing a dummy zio to the done callback.
|
||||
* checksum error.
|
||||
*/
|
||||
if (size > spa_maxblocksize(spa)) {
|
||||
if (done) {
|
||||
rzio = zio_null(pio, spa, NULL,
|
||||
NULL, NULL, zio_flags);
|
||||
rzio->io_error = ECKSUM;
|
||||
done(rzio, buf, private);
|
||||
zio_nowait(rzio);
|
||||
}
|
||||
rc = ECKSUM;
|
||||
ASSERT3P(buf, ==, NULL);
|
||||
rc = SET_ERROR(ECKSUM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -4564,13 +4561,19 @@ arc_add_prune_callback(arc_prune_func_t *func, void *private)
|
|||
void
|
||||
arc_remove_prune_callback(arc_prune_t *p)
|
||||
{
|
||||
boolean_t wait = B_FALSE;
|
||||
mutex_enter(&arc_prune_mtx);
|
||||
list_remove(&arc_prune_list, p);
|
||||
if (refcount_remove(&p->p_refcnt, &arc_prune_list) == 0) {
|
||||
refcount_destroy(&p->p_refcnt);
|
||||
kmem_free(p, sizeof (*p));
|
||||
}
|
||||
if (refcount_remove(&p->p_refcnt, &arc_prune_list) > 0)
|
||||
wait = B_TRUE;
|
||||
mutex_exit(&arc_prune_mtx);
|
||||
|
||||
/* wait for arc_prune_task to finish */
|
||||
if (wait)
|
||||
taskq_wait_outstanding(arc_prune_taskq, 0);
|
||||
ASSERT0(refcount_count(&p->p_refcnt));
|
||||
refcount_destroy(&p->p_refcnt);
|
||||
kmem_free(p, sizeof (*p));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5100,7 +5103,9 @@ arc_tempreserve_space(uint64_t reserve, uint64_t txg)
|
|||
int error;
|
||||
uint64_t anon_size;
|
||||
|
||||
if (reserve > arc_c/4 && !arc_no_grow)
|
||||
if (!arc_no_grow &&
|
||||
reserve > arc_c/4 &&
|
||||
reserve * 4 > (2ULL << SPA_MAXBLOCKSHIFT))
|
||||
arc_c = MIN(arc_c_max, reserve * 4);
|
||||
|
||||
/*
|
||||
|
@ -5244,7 +5249,7 @@ arc_tuning_update(void)
|
|||
arc_c_max = zfs_arc_max;
|
||||
arc_c = arc_c_max;
|
||||
arc_p = (arc_c >> 1);
|
||||
arc_meta_limit = MIN(arc_meta_limit, arc_c_max);
|
||||
arc_meta_limit = MIN(arc_meta_limit, (3 * arc_c_max) / 4);
|
||||
}
|
||||
|
||||
/* Valid range: 32M - <arc_c_max> */
|
||||
|
@ -5470,14 +5475,15 @@ arc_init(void)
|
|||
* If it has been set by a module parameter, take that.
|
||||
* Otherwise, use a percentage of physical memory defined by
|
||||
* zfs_dirty_data_max_percent (default 10%) with a cap at
|
||||
* zfs_dirty_data_max_max (default 25% of physical memory).
|
||||
* zfs_dirty_data_max_max (default 4G or 25% of physical memory).
|
||||
*/
|
||||
if (zfs_dirty_data_max_max == 0)
|
||||
zfs_dirty_data_max_max = physmem * PAGESIZE *
|
||||
zfs_dirty_data_max_max_percent / 100;
|
||||
zfs_dirty_data_max_max = MIN(4ULL * 1024 * 1024 * 1024,
|
||||
(uint64_t)physmem * PAGESIZE *
|
||||
zfs_dirty_data_max_max_percent / 100);
|
||||
|
||||
if (zfs_dirty_data_max == 0) {
|
||||
zfs_dirty_data_max = physmem * PAGESIZE *
|
||||
zfs_dirty_data_max = (uint64_t)physmem * PAGESIZE *
|
||||
zfs_dirty_data_max_percent / 100;
|
||||
zfs_dirty_data_max = MIN(zfs_dirty_data_max,
|
||||
zfs_dirty_data_max_max);
|
||||
|
|
|
@ -303,7 +303,7 @@ dbuf_verify_user(dmu_buf_impl_t *db, dbvu_verify_type_t verify_type)
|
|||
*/
|
||||
ASSERT3U(holds, >=, db->db_dirtycnt);
|
||||
} else {
|
||||
if (db->db_immediate_evict == TRUE)
|
||||
if (db->db_user_immediate_evict == TRUE)
|
||||
ASSERT3U(holds, >=, db->db_dirtycnt);
|
||||
else
|
||||
ASSERT3U(holds, >, 0);
|
||||
|
@ -1880,8 +1880,9 @@ dbuf_create(dnode_t *dn, uint8_t level, uint64_t blkid,
|
|||
db->db_blkptr = blkptr;
|
||||
|
||||
db->db_user = NULL;
|
||||
db->db_immediate_evict = 0;
|
||||
db->db_freed_in_flight = 0;
|
||||
db->db_user_immediate_evict = FALSE;
|
||||
db->db_freed_in_flight = FALSE;
|
||||
db->db_pending_evict = FALSE;
|
||||
|
||||
if (blkid == DMU_BONUS_BLKID) {
|
||||
ASSERT3P(parent, ==, dn->dn_dbuf);
|
||||
|
@ -2318,12 +2319,13 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag)
|
|||
arc_buf_freeze(db->db_buf);
|
||||
|
||||
if (holds == db->db_dirtycnt &&
|
||||
db->db_level == 0 && db->db_immediate_evict)
|
||||
db->db_level == 0 && db->db_user_immediate_evict)
|
||||
dbuf_evict_user(db);
|
||||
|
||||
if (holds == 0) {
|
||||
if (db->db_blkid == DMU_BONUS_BLKID) {
|
||||
dnode_t *dn;
|
||||
boolean_t evict_dbuf = db->db_pending_evict;
|
||||
|
||||
/*
|
||||
* If the dnode moves here, we cannot cross this
|
||||
|
@ -2338,7 +2340,7 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag)
|
|||
* Decrementing the dbuf count means that the bonus
|
||||
* buffer's dnode hold is no longer discounted in
|
||||
* dnode_move(). The dnode cannot move until after
|
||||
* the dnode_rele_and_unlock() below.
|
||||
* the dnode_rele() below.
|
||||
*/
|
||||
DB_DNODE_EXIT(db);
|
||||
|
||||
|
@ -2348,35 +2350,10 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag)
|
|||
*/
|
||||
mutex_exit(&db->db_mtx);
|
||||
|
||||
/*
|
||||
* If the dnode has been freed, evict the bonus
|
||||
* buffer immediately. The data in the bonus
|
||||
* buffer is no longer relevant and this prevents
|
||||
* a stale bonus buffer from being associated
|
||||
* with this dnode_t should the dnode_t be reused
|
||||
* prior to being destroyed.
|
||||
*/
|
||||
mutex_enter(&dn->dn_mtx);
|
||||
if (dn->dn_type == DMU_OT_NONE ||
|
||||
dn->dn_free_txg != 0) {
|
||||
/*
|
||||
* Drop dn_mtx. It is a leaf lock and
|
||||
* cannot be held when dnode_evict_bonus()
|
||||
* acquires other locks in order to
|
||||
* perform the eviction.
|
||||
*
|
||||
* Freed dnodes cannot be reused until the
|
||||
* last hold is released. Since this bonus
|
||||
* buffer has a hold, the dnode will remain
|
||||
* in the free state, even without dn_mtx
|
||||
* held, until the dnode_rele_and_unlock()
|
||||
* below.
|
||||
*/
|
||||
mutex_exit(&dn->dn_mtx);
|
||||
if (evict_dbuf)
|
||||
dnode_evict_bonus(dn);
|
||||
mutex_enter(&dn->dn_mtx);
|
||||
}
|
||||
dnode_rele_and_unlock(dn, db);
|
||||
|
||||
dnode_rele(dn, db);
|
||||
} else if (db->db_buf == NULL) {
|
||||
/*
|
||||
* This is a special case: we never associated this
|
||||
|
@ -2423,7 +2400,7 @@ dbuf_rele_and_unlock(dmu_buf_impl_t *db, void *tag)
|
|||
} else {
|
||||
dbuf_clear(db);
|
||||
}
|
||||
} else if (db->db_objset->os_evicting ||
|
||||
} else if (db->db_pending_evict ||
|
||||
arc_buf_eviction_needed(db->db_buf)) {
|
||||
dbuf_clear(db);
|
||||
} else {
|
||||
|
@ -2471,7 +2448,7 @@ dmu_buf_set_user_ie(dmu_buf_t *db_fake, dmu_buf_user_t *user)
|
|||
{
|
||||
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
|
||||
|
||||
db->db_immediate_evict = TRUE;
|
||||
db->db_user_immediate_evict = TRUE;
|
||||
return (dmu_buf_set_user(db_fake, user));
|
||||
}
|
||||
|
||||
|
@ -2651,6 +2628,22 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
|||
|
||||
if (db->db_blkid == DMU_SPILL_BLKID) {
|
||||
mutex_enter(&dn->dn_mtx);
|
||||
if (!(dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR)) {
|
||||
/*
|
||||
* In the previous transaction group, the bonus buffer
|
||||
* was entirely used to store the attributes for the
|
||||
* dnode which overrode the dn_spill field. However,
|
||||
* when adding more attributes to the file a spill
|
||||
* block was required to hold the extra attributes.
|
||||
*
|
||||
* Make sure to clear the garbage left in the dn_spill
|
||||
* field from the previous attributes in the bonus
|
||||
* buffer. Otherwise, after writing out the spill
|
||||
* block to the new allocated dva, it will free
|
||||
* the old block pointed to by the invalid dn_spill.
|
||||
*/
|
||||
db->db_blkptr = NULL;
|
||||
}
|
||||
dn->dn_phys->dn_flags |= DNODE_FLAG_SPILL_BLKPTR;
|
||||
mutex_exit(&dn->dn_mtx);
|
||||
}
|
||||
|
|
|
@ -148,7 +148,6 @@ dbuf_stats_hash_table_data(char *buf, size_t size, void *data)
|
|||
}
|
||||
|
||||
mutex_enter(&db->db_mtx);
|
||||
mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
|
||||
|
||||
if (db->db_state != DB_EVICTING) {
|
||||
length = __dbuf_stats_hash_table_data(buf, size, db);
|
||||
|
@ -157,7 +156,6 @@ dbuf_stats_hash_table_data(char *buf, size_t size, void *data)
|
|||
}
|
||||
|
||||
mutex_exit(&db->db_mtx);
|
||||
mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx));
|
||||
}
|
||||
mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue