Compare commits
184 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 |
2
META
2
META
|
@ -1,7 +1,7 @@
|
||||||
Meta: 1
|
Meta: 1
|
||||||
Name: zfs
|
Name: zfs
|
||||||
Branch: 1.0
|
Branch: 1.0
|
||||||
Version: 0.6.5.3
|
Version: 0.6.5.11
|
||||||
Release: 1
|
Release: 1
|
||||||
Release-Tags: relext
|
Release-Tags: relext
|
||||||
License: CDDL
|
License: CDDL
|
||||||
|
|
|
@ -55,6 +55,13 @@ shellcheck:
|
||||||
done; \
|
done; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
lint: cppcheck
|
||||||
|
|
||||||
|
cppcheck:
|
||||||
|
@if type cppcheck > /dev/null 2>&1; then \
|
||||||
|
cppcheck --quiet --force ${top_srcdir}; \
|
||||||
|
fi
|
||||||
|
|
||||||
ctags:
|
ctags:
|
||||||
$(RM) tags
|
$(RM) tags
|
||||||
find $(top_srcdir) -name .git -prune -o -name '*.[hc]' | xargs ctags
|
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():
|
def div1():
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
for i in xrange(18):
|
for i in range(18):
|
||||||
sys.stdout.write("%s" % "----")
|
sys.stdout.write("%s" % "----")
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
|
|
||||||
|
@ -1060,7 +1060,7 @@ def _tunable_summary(Kstat):
|
||||||
if alternate_tunable_layout:
|
if alternate_tunable_layout:
|
||||||
format = "\t%s=%s\n"
|
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("\t# %s\n" % descriptions[name])
|
||||||
|
|
||||||
sys.stdout.write(format % (name, values[name]))
|
sys.stdout.write(format % (name, values[name]))
|
||||||
|
@ -1132,7 +1132,7 @@ def main():
|
||||||
if 'p' in args:
|
if 'p' in args:
|
||||||
try:
|
try:
|
||||||
pages.append(unSub[int(args['p']) - 1])
|
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 ' +
|
sys.stderr.write('the argument to -p must be between 1 and ' +
|
||||||
str(len(unSub)) + '\n')
|
str(len(unSub)) + '\n')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
|
@ -97,8 +97,8 @@ cols = {
|
||||||
v = {}
|
v = {}
|
||||||
hdr = ["time", "read", "miss", "miss%", "dmis", "dm%", "pmis", "pm%", "mmis",
|
hdr = ["time", "read", "miss", "miss%", "dmis", "dm%", "pmis", "pm%", "mmis",
|
||||||
"mm%", "arcsz", "c"]
|
"mm%", "arcsz", "c"]
|
||||||
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "rmis",
|
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "dread",
|
||||||
"dread", "pread", "read"]
|
"pread", "read"]
|
||||||
sint = 1 # Default interval is 1 second
|
sint = 1 # Default interval is 1 second
|
||||||
count = 1 # Default count is 1
|
count = 1 # Default count is 1
|
||||||
hdr_intr = 20 # Print header every 20 lines of output
|
hdr_intr = 20 # Print header every 20 lines of output
|
||||||
|
|
|
@ -34,7 +34,7 @@ import errno
|
||||||
|
|
||||||
bhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"]
|
bhdr = ["pool", "objset", "object", "level", "blkid", "offset", "dbsize"]
|
||||||
bxhdr = ["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",
|
"count", "asize", "access", "mru", "gmru", "mfu", "gmfu", "l2",
|
||||||
"l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype",
|
"l2_dattr", "l2_asize", "l2_comp", "aholds", "dtype", "btype",
|
||||||
"data_bs", "meta_bs", "bsize", "lvls", "dholds", "blocks", "dsize"]
|
"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",
|
"bsize", "lvls", "dholds", "blocks", "dsize", "cached", "direct",
|
||||||
"indirect", "bonus", "spill"]
|
"indirect", "bonus", "spill"]
|
||||||
dincompat = ["level", "blkid", "offset", "dbsize", "meta", "state", "dbholds",
|
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",
|
"mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr", "l2_asize",
|
||||||
"l2_comp", "aholds"]
|
"l2_comp", "aholds"]
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ thdr = ["pool", "objset", "dtype", "cached"]
|
||||||
txhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect",
|
txhdr = ["pool", "objset", "dtype", "cached", "direct", "indirect",
|
||||||
"bonus", "spill"]
|
"bonus", "spill"]
|
||||||
tincompat = ["object", "level", "blkid", "offset", "dbsize", "meta", "state",
|
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",
|
"access", "mru", "gmru", "mfu", "gmfu", "l2", "l2_dattr",
|
||||||
"l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs",
|
"l2_asize", "l2_comp", "aholds", "btype", "data_bs", "meta_bs",
|
||||||
"bsize", "lvls", "dholds", "blocks", "dsize"]
|
"bsize", "lvls", "dholds", "blocks", "dsize"]
|
||||||
|
@ -72,7 +72,6 @@ cols = {
|
||||||
"dbholds": [7, 1000, "number of holds on buffer"],
|
"dbholds": [7, 1000, "number of holds on buffer"],
|
||||||
"list": [4, -1, "which ARC list contains this buffer"],
|
"list": [4, -1, "which ARC list contains this buffer"],
|
||||||
"atype": [7, -1, "ARC header type (data or metadata)"],
|
"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"],
|
"flags": [8, -1, "ARC read flags"],
|
||||||
"count": [5, -1, "ARC data count"],
|
"count": [5, -1, "ARC data count"],
|
||||||
"asize": [7, 1024, "size of this ARC buffer"],
|
"asize": [7, 1024, "size of this ARC buffer"],
|
||||||
|
@ -387,9 +386,9 @@ def update_dict(d, k, line, labels):
|
||||||
|
|
||||||
def print_dict(d):
|
def print_dict(d):
|
||||||
print_header()
|
print_header()
|
||||||
for pool in d.keys():
|
for pool in list(d.keys()):
|
||||||
for objset in d[pool].keys():
|
for objset in list(d[pool].keys()):
|
||||||
for v in d[pool][objset].values():
|
for v in list(d[pool][objset].values()):
|
||||||
print_values(v)
|
print_values(v)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
#define ZS_COMMENT 0x00000000 /* comment */
|
#define ZS_COMMENT 0x00000000 /* comment */
|
||||||
#define ZS_ZFSUTIL 0x00000001 /* caller is zfs(8) */
|
#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 },
|
{ MNTOPT_RELATIME, MS_RELATIME, ZS_COMMENT },
|
||||||
#endif
|
#endif
|
||||||
#ifdef MS_STRICTATIME
|
#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
|
#endif
|
||||||
{ MNTOPT_CONTEXT, MS_COMMENT, ZS_COMMENT },
|
{ MNTOPT_CONTEXT, MS_COMMENT, ZS_COMMENT },
|
||||||
{ MNTOPT_FSCONTEXT, MS_COMMENT, ZS_COMMENT },
|
{ MNTOPT_FSCONTEXT, MS_COMMENT, ZS_COMMENT },
|
||||||
|
@ -389,7 +393,7 @@ main(int argc, char **argv)
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "sfnvo:h?")) != -1) {
|
while ((c = getopt_long(argc, argv, "sfnvo:h?", 0, 0)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 's':
|
case 's':
|
||||||
sloppy = 1;
|
sloppy = 1;
|
||||||
|
@ -604,10 +608,23 @@ main(int argc, char **argv)
|
||||||
"failed for unknown reason.\n"), dataset);
|
"failed for unknown reason.\n"), dataset);
|
||||||
}
|
}
|
||||||
return (MOUNT_SYSERR);
|
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:
|
default:
|
||||||
(void) fprintf(stderr, gettext("filesystem "
|
(void) fprintf(stderr, gettext("filesystem "
|
||||||
"'%s' can not be mounted due to error "
|
"'%s' can not be mounted: %s\n"), dataset,
|
||||||
"%d\n"), dataset, errno);
|
strerror(errno));
|
||||||
return (MOUNT_USAGE);
|
return (MOUNT_USAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,9 +184,9 @@ sas_handler() {
|
||||||
return
|
return
|
||||||
fi
|
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.
|
# leading pipe symbols to make field numbering consistent.
|
||||||
DEV=`multipath -l $DM_NAME |
|
DEV=`multipath -ll $DM_NAME |
|
||||||
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
|
awk '/running/{gsub("^[|]"," "); print $3 ; exit}'`
|
||||||
if [ -z "$DEV" ] ; then
|
if [ -z "$DEV" ] ; then
|
||||||
return
|
return
|
||||||
|
|
|
@ -67,13 +67,22 @@
|
||||||
zio_compress_table[(idx)].ci_name : "UNKNOWN")
|
zio_compress_table[(idx)].ci_name : "UNKNOWN")
|
||||||
#define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
|
#define ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
|
||||||
zio_checksum_table[(idx)].ci_name : "UNKNOWN")
|
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) : \
|
#define ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : \
|
||||||
(((idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA) ? \
|
(((idx) == DMU_OTN_ZAP_DATA || (idx) == DMU_OTN_ZAP_METADATA) ? \
|
||||||
DMU_OT_ZAP_OTHER : DMU_OT_NUMTYPES))
|
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
|
#ifndef lint
|
||||||
extern int zfs_recover;
|
extern int zfs_recover;
|
||||||
extern uint64_t zfs_arc_max, zfs_arc_meta_limit;
|
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)
|
dump_bpobj_subobjs(objset_t *os, uint64_t object, void *data, size_t size)
|
||||||
{
|
{
|
||||||
dmu_object_info_t doi;
|
dmu_object_info_t doi;
|
||||||
uint64_t i;
|
int64_t i;
|
||||||
|
|
||||||
VERIFY0(dmu_object_info(os, object, &doi));
|
VERIFY0(dmu_object_info(os, object, &doi));
|
||||||
uint64_t *subobjs = kmem_alloc(doi.doi_max_offset, KM_SLEEP);
|
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++) {
|
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);
|
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",
|
(void) printf("%10lld %3u %5s %5s %5s %5s %6s %s%s\n",
|
||||||
(u_longlong_t)object, doi.doi_indirection, iblk, dblk,
|
(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) {
|
if (doi.doi_bonus_type != DMU_OT_NONE && verbosity > 3) {
|
||||||
(void) printf("%10s %3s %5s %5s %5s %5s %6s %s\n",
|
(void) printf("%10s %3s %5s %5s %5s %5s %6s %s\n",
|
||||||
"", "", "", "", "", bonus_size, "bonus",
|
"", "", "", "", "", bonus_size, "bonus",
|
||||||
ZDB_OT_NAME(doi.doi_bonus_type));
|
zdb_ot_name(doi.doi_bonus_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbosity >= 4) {
|
if (verbosity >= 4) {
|
||||||
|
@ -3357,8 +3366,10 @@ zdb_read_block(char *thing, spa_t *spa)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p = &flagstr[i + 1];
|
p = &flagstr[i + 1];
|
||||||
if (bit == ZDB_FLAG_PRINT_BLKPTR)
|
if (bit == ZDB_FLAG_PRINT_BLKPTR) {
|
||||||
blkptr_offset = strtoull(p, &p, 16);
|
blkptr_offset = strtoull(p, &p, 16);
|
||||||
|
i = p - &flagstr[i + 1];
|
||||||
|
}
|
||||||
if (*p != ':' && *p != '\0') {
|
if (*p != ':' && *p != '\0') {
|
||||||
(void) printf("***Invalid flag arg: '%s'\n", s);
|
(void) printf("***Invalid flag arg: '%s'\n", s);
|
||||||
free(dup);
|
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
|
* If we're recursive, then we always allow filesystems as
|
||||||
* arguments. If we also are interested in snapshots, then we
|
* arguments. If we also are interested in snapshots or
|
||||||
* can take volumes as well.
|
* bookmarks, then we can take volumes as well.
|
||||||
*/
|
*/
|
||||||
argtype = types;
|
argtype = types;
|
||||||
if (flags & ZFS_ITER_RECURSE) {
|
if (flags & ZFS_ITER_RECURSE) {
|
||||||
argtype |= ZFS_TYPE_FILESYSTEM;
|
argtype |= ZFS_TYPE_FILESYSTEM;
|
||||||
if (types & ZFS_TYPE_SNAPSHOT)
|
if (types & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK))
|
||||||
argtype |= ZFS_TYPE_VOLUME;
|
argtype |= ZFS_TYPE_VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ static const char *
|
||||||
get_usage(zpool_help_t idx) {
|
get_usage(zpool_help_t idx) {
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case HELP_ADD:
|
case HELP_ADD:
|
||||||
return (gettext("\tadd [-fn] [-o property=value] "
|
return (gettext("\tadd [-fgLnP] [-o property=value] "
|
||||||
"<pool> <vdev> ...\n"));
|
"<pool> <vdev> ...\n"));
|
||||||
case HELP_ATTACH:
|
case HELP_ATTACH:
|
||||||
return (gettext("\tattach [-f] [-o property=value] "
|
return (gettext("\tattach [-f] [-o property=value] "
|
||||||
|
@ -237,12 +237,12 @@ get_usage(zpool_help_t idx) {
|
||||||
"[-R root] [-F [-n]]\n"
|
"[-R root] [-F [-n]]\n"
|
||||||
"\t <pool | id> [newpool]\n"));
|
"\t <pool | id> [newpool]\n"));
|
||||||
case HELP_IOSTAT:
|
case HELP_IOSTAT:
|
||||||
return (gettext("\tiostat [-v] [-T d|u] [-y] [pool] ... "
|
return (gettext("\tiostat [-gLPvy] [-T d|u] [pool] ... "
|
||||||
"[interval [count]]\n"));
|
"[interval [count]]\n"));
|
||||||
case HELP_LABELCLEAR:
|
case HELP_LABELCLEAR:
|
||||||
return (gettext("\tlabelclear [-f] <vdev>\n"));
|
return (gettext("\tlabelclear [-f] <vdev>\n"));
|
||||||
case HELP_LIST:
|
case HELP_LIST:
|
||||||
return (gettext("\tlist [-Hv] [-o property[,...]] "
|
return (gettext("\tlist [-gHLPv] [-o property[,...]] "
|
||||||
"[-T d|u] [pool] ... [interval [count]]\n"));
|
"[-T d|u] [pool] ... [interval [count]]\n"));
|
||||||
case HELP_OFFLINE:
|
case HELP_OFFLINE:
|
||||||
return (gettext("\toffline [-t] <pool> <device> ...\n"));
|
return (gettext("\toffline [-t] <pool> <device> ...\n"));
|
||||||
|
@ -258,8 +258,8 @@ get_usage(zpool_help_t idx) {
|
||||||
case HELP_SCRUB:
|
case HELP_SCRUB:
|
||||||
return (gettext("\tscrub [-s] <pool> ...\n"));
|
return (gettext("\tscrub [-s] <pool> ...\n"));
|
||||||
case HELP_STATUS:
|
case HELP_STATUS:
|
||||||
return (gettext("\tstatus [-vxD] [-T d|u] [pool] ... [interval "
|
return (gettext("\tstatus [-gLPvxD] [-T d|u] [pool] ... "
|
||||||
"[count]]\n"));
|
"[interval [count]]\n"));
|
||||||
case HELP_UPGRADE:
|
case HELP_UPGRADE:
|
||||||
return (gettext("\tupgrade\n"
|
return (gettext("\tupgrade\n"
|
||||||
"\tupgrade -v\n"
|
"\tupgrade -v\n"
|
||||||
|
@ -272,7 +272,7 @@ get_usage(zpool_help_t idx) {
|
||||||
case HELP_SET:
|
case HELP_SET:
|
||||||
return (gettext("\tset <property=value> <pool> \n"));
|
return (gettext("\tset <property=value> <pool> \n"));
|
||||||
case HELP_SPLIT:
|
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> "
|
"\t [-o property=value] <pool> <newpool> "
|
||||||
"[<device> ...]\n"));
|
"[<device> ...]\n"));
|
||||||
case HELP_REGUID:
|
case HELP_REGUID:
|
||||||
|
@ -371,7 +371,7 @@ usage(boolean_t requested)
|
||||||
|
|
||||||
void
|
void
|
||||||
print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
|
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;
|
nvlist_t **child;
|
||||||
uint_t c, children;
|
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))
|
if ((is_log && !print_logs) || (!is_log && print_logs))
|
||||||
continue;
|
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,
|
print_vdev_tree(zhp, vname, child[c], indent + 2,
|
||||||
B_FALSE);
|
B_FALSE, name_flags);
|
||||||
free(vname);
|
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
|
* -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
|
* -n Do not add the devices, but display the resulting layout if
|
||||||
* they were to be added.
|
* they were to be added.
|
||||||
* -o Set property=value.
|
* -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
|
* 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
|
* 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 force = B_FALSE;
|
||||||
boolean_t dryrun = B_FALSE;
|
boolean_t dryrun = B_FALSE;
|
||||||
|
int name_flags = 0;
|
||||||
int c;
|
int c;
|
||||||
nvlist_t *nvroot;
|
nvlist_t *nvroot;
|
||||||
char *poolname;
|
char *poolname;
|
||||||
|
@ -528,11 +532,17 @@ zpool_do_add(int argc, char **argv)
|
||||||
char *propval;
|
char *propval;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "fno:")) != -1) {
|
while ((c = getopt(argc, argv, "fgLno:P")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'f':
|
case 'f':
|
||||||
force = B_TRUE;
|
force = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'g':
|
||||||
|
name_flags |= VDEV_NAME_GUID;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
dryrun = B_TRUE;
|
dryrun = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -549,6 +559,9 @@ zpool_do_add(int argc, char **argv)
|
||||||
(add_prop_list(optarg, propval, &props, B_TRUE)))
|
(add_prop_list(optarg, propval, &props, B_TRUE)))
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
name_flags |= VDEV_NAME_PATH;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
optopt);
|
optopt);
|
||||||
|
@ -606,15 +619,19 @@ zpool_do_add(int argc, char **argv)
|
||||||
"configuration:\n"), zpool_get_name(zhp));
|
"configuration:\n"), zpool_get_name(zhp));
|
||||||
|
|
||||||
/* print original main pool and new tree */
|
/* print original main pool and new tree */
|
||||||
print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE);
|
print_vdev_tree(zhp, poolname, poolnvroot, 0, B_FALSE,
|
||||||
print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE);
|
name_flags);
|
||||||
|
print_vdev_tree(zhp, NULL, nvroot, 0, B_FALSE, name_flags);
|
||||||
|
|
||||||
/* Do the same for the logs */
|
/* Do the same for the logs */
|
||||||
if (num_logs(poolnvroot) > 0) {
|
if (num_logs(poolnvroot) > 0) {
|
||||||
print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE);
|
print_vdev_tree(zhp, "logs", poolnvroot, 0, B_TRUE,
|
||||||
print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE);
|
name_flags);
|
||||||
|
print_vdev_tree(zhp, NULL, nvroot, 0, B_TRUE,
|
||||||
|
name_flags);
|
||||||
} else if (num_logs(nvroot) > 0) {
|
} 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 */
|
/* Do the same for the caches */
|
||||||
|
@ -624,7 +641,7 @@ zpool_do_add(int argc, char **argv)
|
||||||
(void) printf(gettext("\tcache\n"));
|
(void) printf(gettext("\tcache\n"));
|
||||||
for (c = 0; c < l2children; c++) {
|
for (c = 0; c < l2children; c++) {
|
||||||
vname = zpool_vdev_name(g_zfs, NULL,
|
vname = zpool_vdev_name(g_zfs, NULL,
|
||||||
l2child[c], B_FALSE);
|
l2child[c], name_flags);
|
||||||
(void) printf("\t %s\n", vname);
|
(void) printf("\t %s\n", vname);
|
||||||
free(vname);
|
free(vname);
|
||||||
}
|
}
|
||||||
|
@ -635,7 +652,7 @@ zpool_do_add(int argc, char **argv)
|
||||||
(void) printf(gettext("\tcache\n"));
|
(void) printf(gettext("\tcache\n"));
|
||||||
for (c = 0; c < l2children; c++) {
|
for (c = 0; c < l2children; c++) {
|
||||||
vname = zpool_vdev_name(g_zfs, NULL,
|
vname = zpool_vdev_name(g_zfs, NULL,
|
||||||
l2child[c], B_FALSE);
|
l2child[c], name_flags);
|
||||||
(void) printf("\t %s\n", vname);
|
(void) printf("\t %s\n", vname);
|
||||||
free(vname);
|
free(vname);
|
||||||
}
|
}
|
||||||
|
@ -1082,9 +1099,9 @@ zpool_do_create(int argc, char **argv)
|
||||||
(void) printf(gettext("would create '%s' with the "
|
(void) printf(gettext("would create '%s' with the "
|
||||||
"following layout:\n\n"), poolname);
|
"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)
|
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;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1311,13 +1328,15 @@ zpool_do_export(int argc, char **argv)
|
||||||
* name column.
|
* name column.
|
||||||
*/
|
*/
|
||||||
static int
|
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;
|
nvlist_t **child;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
name = zpool_vdev_name(g_zfs, zhp, nv, name_flags | VDEV_NAME_TYPE_ID);
|
||||||
if (strlen(name) + depth > max)
|
if (strlen(name) + depth > max)
|
||||||
max = strlen(name) + depth;
|
max = strlen(name) + depth;
|
||||||
|
|
||||||
|
@ -1327,7 +1346,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
|
||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++)
|
for (c = 0; c < children; c++)
|
||||||
if ((ret = max_width(zhp, child[c], depth + 2,
|
if ((ret = max_width(zhp, child[c], depth + 2,
|
||||||
max)) > max)
|
max, name_flags)) > max)
|
||||||
max = ret;
|
max = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1335,7 +1354,7 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
|
||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++)
|
for (c = 0; c < children; c++)
|
||||||
if ((ret = max_width(zhp, child[c], depth + 2,
|
if ((ret = max_width(zhp, child[c], depth + 2,
|
||||||
max)) > max)
|
max, name_flags)) > max)
|
||||||
max = ret;
|
max = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1343,11 +1362,10 @@ max_width(zpool_handle_t *zhp, nvlist_t *nv, int depth, int max)
|
||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
for (c = 0; c < children; c++)
|
for (c = 0; c < children; c++)
|
||||||
if ((ret = max_width(zhp, child[c], depth + 2,
|
if ((ret = max_width(zhp, child[c], depth + 2,
|
||||||
max)) > max)
|
max, name_flags)) > max)
|
||||||
max = ret;
|
max = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return (max);
|
return (max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1399,9 +1417,9 @@ find_spare(zpool_handle_t *zhp, void *data)
|
||||||
/*
|
/*
|
||||||
* Print out configuration state as requested by status_callback.
|
* 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,
|
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;
|
nvlist_t **child;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
|
@ -1537,20 +1555,21 @@ print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||||
&ishole);
|
&ishole);
|
||||||
if (islog || ishole)
|
if (islog || ishole)
|
||||||
continue;
|
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],
|
print_status_config(zhp, vname, child[c],
|
||||||
namewidth, depth + 2, isspare);
|
namewidth, depth + 2, isspare, name_flags);
|
||||||
free(vname);
|
free(vname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print the configuration of an exported pool. Iterate over all vdevs in the
|
* Print the configuration of an exported pool. Iterate over all vdevs in the
|
||||||
* pool, printing out the name and status for each one.
|
* pool, printing out the name and status for each one.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth,
|
||||||
|
int name_flags)
|
||||||
{
|
{
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
uint_t c, children;
|
uint_t c, children;
|
||||||
|
@ -1615,8 +1634,10 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
||||||
if (is_log)
|
if (is_log)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vname = zpool_vdev_name(g_zfs, NULL, child[c], B_TRUE);
|
vname = zpool_vdev_name(g_zfs, NULL, child[c],
|
||||||
print_import_config(vname, child[c], namewidth, depth + 2);
|
name_flags | VDEV_NAME_TYPE_ID);
|
||||||
|
print_import_config(vname, child[c], namewidth, depth + 2,
|
||||||
|
name_flags);
|
||||||
free(vname);
|
free(vname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1624,7 +1645,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
(void) printf(gettext("\tcache\n"));
|
(void) printf(gettext("\tcache\n"));
|
||||||
for (c = 0; c < children; c++) {
|
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);
|
(void) printf("\t %s\n", vname);
|
||||||
free(vname);
|
free(vname);
|
||||||
}
|
}
|
||||||
|
@ -1634,7 +1656,8 @@ print_import_config(const char *name, nvlist_t *nv, int namewidth, int depth)
|
||||||
&child, &children) == 0) {
|
&child, &children) == 0) {
|
||||||
(void) printf(gettext("\tspares\n"));
|
(void) printf(gettext("\tspares\n"));
|
||||||
for (c = 0; c < children; c++) {
|
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);
|
(void) printf("\t %s\n", vname);
|
||||||
free(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"
|
* works because only the top level vdev is marked "is_log"
|
||||||
*/
|
*/
|
||||||
static void
|
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;
|
uint_t c, children;
|
||||||
nvlist_t **child;
|
nvlist_t **child;
|
||||||
|
@ -1669,12 +1693,14 @@ print_logs(zpool_handle_t *zhp, nvlist_t *nv, int namewidth, boolean_t verbose)
|
||||||
&is_log);
|
&is_log);
|
||||||
if (!is_log)
|
if (!is_log)
|
||||||
continue;
|
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)
|
if (verbose)
|
||||||
print_status_config(zhp, name, child[c], namewidth,
|
print_status_config(zhp, name, child[c], namewidth,
|
||||||
2, B_FALSE);
|
2, B_FALSE, name_flags);
|
||||||
else
|
else
|
||||||
print_import_config(name, child[c], namewidth, 2);
|
print_import_config(name, child[c], namewidth, 2,
|
||||||
|
name_flags);
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1923,13 +1949,13 @@ show_import(nvlist_t *config)
|
||||||
|
|
||||||
(void) printf(gettext(" config:\n\n"));
|
(void) printf(gettext(" config:\n\n"));
|
||||||
|
|
||||||
namewidth = max_width(NULL, nvroot, 0, 0);
|
namewidth = max_width(NULL, nvroot, 0, 0, 0);
|
||||||
if (namewidth < 10)
|
if (namewidth < 10)
|
||||||
namewidth = 10;
|
namewidth = 10;
|
||||||
|
|
||||||
print_import_config(name, nvroot, namewidth, 0);
|
print_import_config(name, nvroot, namewidth, 0, 0);
|
||||||
if (num_logs(nvroot) > 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) {
|
if (reason == ZPOOL_STATUS_BAD_GUID_SUM) {
|
||||||
(void) printf(gettext("\n\tAdditional devices are known to "
|
(void) printf(gettext("\n\tAdditional devices are known to "
|
||||||
|
@ -2438,6 +2464,7 @@ error:
|
||||||
|
|
||||||
typedef struct iostat_cbdata {
|
typedef struct iostat_cbdata {
|
||||||
boolean_t cb_verbose;
|
boolean_t cb_verbose;
|
||||||
|
int cb_name_flags;
|
||||||
int cb_namewidth;
|
int cb_namewidth;
|
||||||
int cb_iteration;
|
int cb_iteration;
|
||||||
zpool_list_t *cb_list;
|
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)
|
if (ishole || islog)
|
||||||
continue;
|
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,
|
print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
|
||||||
newchild[c], cb, depth + 2);
|
newchild[c], cb, depth + 2);
|
||||||
free(vname);
|
free(vname);
|
||||||
|
@ -2581,7 +2609,7 @@ print_vdev_stats(zpool_handle_t *zhp, const char *name, nvlist_t *oldnv,
|
||||||
|
|
||||||
if (islog) {
|
if (islog) {
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
vname = zpool_vdev_name(g_zfs, zhp, newchild[c],
|
||||||
B_FALSE);
|
cb->cb_name_flags);
|
||||||
print_vdev_stats(zhp, vname, oldnv ?
|
print_vdev_stats(zhp, vname, oldnv ?
|
||||||
oldchild[c] : NULL, newchild[c],
|
oldchild[c] : NULL, newchild[c],
|
||||||
cb, depth + 2);
|
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");
|
"-\n", cb->cb_namewidth, "cache");
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, newchild[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,
|
print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
|
||||||
newchild[c], cb, depth + 2);
|
newchild[c], cb, depth + 2);
|
||||||
free(vname);
|
free(vname);
|
||||||
|
@ -2700,7 +2728,7 @@ get_namewidth(zpool_handle_t *zhp, void *data)
|
||||||
cb->cb_namewidth = strlen(zpool_get_name(zhp));
|
cb->cb_namewidth = strlen(zpool_get_name(zhp));
|
||||||
else
|
else
|
||||||
cb->cb_namewidth = max_width(zhp, nvroot, 0,
|
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
|
* -v Display statistics for individual vdevs
|
||||||
* -T Display a timestamp in date(1) or Unix format
|
* -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;
|
zpool_list_t *list;
|
||||||
boolean_t verbose = B_FALSE;
|
boolean_t verbose = B_FALSE;
|
||||||
boolean_t omit_since_boot = 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 */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "T:vy")) != -1) {
|
while ((c = getopt(argc, argv, "gLPT:vy")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'g':
|
||||||
|
guid = B_TRUE;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
follow_links = B_TRUE;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
full_name = B_TRUE;
|
||||||
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
get_timestamp_arg(*optarg);
|
get_timestamp_arg(*optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -2870,6 +2913,12 @@ zpool_do_iostat(int argc, char **argv)
|
||||||
*/
|
*/
|
||||||
cb.cb_list = list;
|
cb.cb_list = list;
|
||||||
cb.cb_verbose = verbose;
|
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_iteration = 0;
|
||||||
cb.cb_namewidth = 0;
|
cb.cb_namewidth = 0;
|
||||||
|
|
||||||
|
@ -2953,6 +3002,7 @@ zpool_do_iostat(int argc, char **argv)
|
||||||
|
|
||||||
typedef struct list_cbdata {
|
typedef struct list_cbdata {
|
||||||
boolean_t cb_verbose;
|
boolean_t cb_verbose;
|
||||||
|
int cb_name_flags;
|
||||||
int cb_namewidth;
|
int cb_namewidth;
|
||||||
boolean_t cb_scripted;
|
boolean_t cb_scripted;
|
||||||
zprop_list_t *cb_proplist;
|
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;
|
uint_t c, children;
|
||||||
char *vname;
|
char *vname;
|
||||||
boolean_t scripted = cb->cb_scripted;
|
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,
|
verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
|
||||||
(uint64_t **)&vs, &c) == 0);
|
(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)
|
ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
|
||||||
continue;
|
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);
|
print_list_stats(zhp, vname, child[c], cb, depth + 2);
|
||||||
free(vname);
|
free(vname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (haslog == B_TRUE) {
|
||||||
* Include level 2 ARC devices in iostat output
|
/* LINTED E_SEC_PRINTF_VAR_FMT */
|
||||||
*/
|
(void) printf(dashes, cb->cb_namewidth, "log");
|
||||||
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
for (c = 0; c < children; c++) {
|
||||||
&child, &children) != 0)
|
if (nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
|
||||||
return;
|
&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) {
|
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
|
||||||
(void) printf("%-*s - - - - - "
|
&child, &children) == 0 && children > 0) {
|
||||||
"-\n", cb->cb_namewidth, "cache");
|
/* LINTED E_SEC_PRINTF_VAR_FMT */
|
||||||
|
(void) printf(dashes, cb->cb_namewidth, "cache");
|
||||||
for (c = 0; c < children; c++) {
|
for (c = 0; c < children; c++) {
|
||||||
vname = zpool_vdev_name(g_zfs, zhp, child[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);
|
print_list_stats(zhp, vname, child[c], cb, depth + 2);
|
||||||
free(vname);
|
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
|
* -H Scripted mode. Don't display headers, and separate properties
|
||||||
* by a single tab.
|
* by a single tab.
|
||||||
|
* -L Follow links when resolving vdev path name.
|
||||||
* -o List of properties to display. Defaults to
|
* -o List of properties to display. Defaults to
|
||||||
* "name,size,allocated,free,expandsize,fragmentation,capacity,"
|
* "name,size,allocated,free,expandsize,fragmentation,capacity,"
|
||||||
* "dedupratio,health,altroot"
|
* "dedupratio,health,altroot"
|
||||||
|
* -P Display full path for vdev name.
|
||||||
* -T Display a timestamp in date(1) or Unix format
|
* -T Display a timestamp in date(1) or Unix format
|
||||||
*
|
*
|
||||||
* List all pools in the system, whether or not they're healthy. Output space
|
* 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;
|
boolean_t first = B_TRUE;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
|
while ((c = getopt(argc, argv, ":gHLo:PT:v")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'g':
|
||||||
|
cb.cb_name_flags |= VDEV_NAME_GUID;
|
||||||
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
cb.cb_scripted = B_TRUE;
|
cb.cb_scripted = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'L':
|
||||||
|
cb.cb_name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
props = optarg;
|
props = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
cb.cb_name_flags |= VDEV_NAME_PATH;
|
||||||
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
get_timestamp_arg(*optarg);
|
get_timestamp_arg(*optarg);
|
||||||
break;
|
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] ...
|
* [-o mntopt] ...
|
||||||
* [-R altroot] <pool> <newpool> [<device> ...]
|
* [-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
|
* -n Do not split the pool, but display the resulting layout if
|
||||||
* it were to be split.
|
* it were to be split.
|
||||||
* -o Set property=value, or set mount options.
|
* -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.
|
* -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
|
* 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.dryrun = B_FALSE;
|
||||||
flags.import = B_FALSE;
|
flags.import = B_FALSE;
|
||||||
|
flags.name_flags = 0;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, ":R:no:")) != -1) {
|
while ((c = getopt(argc, argv, ":gLR:no:P")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'g':
|
||||||
|
flags.name_flags |= VDEV_NAME_GUID;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
flags.name_flags |= VDEV_NAME_FOLLOW_LINKS;
|
||||||
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
flags.import = B_TRUE;
|
flags.import = B_TRUE;
|
||||||
if (add_prop_list(
|
if (add_prop_list(
|
||||||
|
@ -3578,6 +3680,9 @@ zpool_do_split(int argc, char **argv)
|
||||||
mntopts = optarg;
|
mntopts = optarg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'P':
|
||||||
|
flags.name_flags |= VDEV_NAME_PATH;
|
||||||
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
(void) fprintf(stderr, gettext("missing argument for "
|
(void) fprintf(stderr, gettext("missing argument for "
|
||||||
"'%c' option\n"), optopt);
|
"'%c' option\n"), optopt);
|
||||||
|
@ -3625,7 +3730,8 @@ zpool_do_split(int argc, char **argv)
|
||||||
if (flags.dryrun) {
|
if (flags.dryrun) {
|
||||||
(void) printf(gettext("would create '%s' with the "
|
(void) printf(gettext("would create '%s' with the "
|
||||||
"following layout:\n\n"), newpool);
|
"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);
|
nvlist_free(config);
|
||||||
}
|
}
|
||||||
|
@ -4031,6 +4137,7 @@ zpool_do_scrub(int argc, char **argv)
|
||||||
|
|
||||||
typedef struct status_cbdata {
|
typedef struct status_cbdata {
|
||||||
int cb_count;
|
int cb_count;
|
||||||
|
int cb_name_flags;
|
||||||
boolean_t cb_allpools;
|
boolean_t cb_allpools;
|
||||||
boolean_t cb_verbose;
|
boolean_t cb_verbose;
|
||||||
boolean_t cb_explain;
|
boolean_t cb_explain;
|
||||||
|
@ -4187,7 +4294,7 @@ print_error_log(zpool_handle_t *zhp)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
|
print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
|
||||||
int namewidth)
|
int namewidth, int name_flags)
|
||||||
{
|
{
|
||||||
uint_t i;
|
uint_t i;
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -4198,16 +4305,16 @@ print_spares(zpool_handle_t *zhp, nvlist_t **spares, uint_t nspares,
|
||||||
(void) printf(gettext("\tspares\n"));
|
(void) printf(gettext("\tspares\n"));
|
||||||
|
|
||||||
for (i = 0; i < nspares; i++) {
|
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],
|
print_status_config(zhp, name, spares[i],
|
||||||
namewidth, 2, B_TRUE);
|
namewidth, 2, B_TRUE, name_flags);
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
|
print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
|
||||||
int namewidth)
|
int namewidth, int name_flags)
|
||||||
{
|
{
|
||||||
uint_t i;
|
uint_t i;
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -4218,9 +4325,9 @@ print_l2cache(zpool_handle_t *zhp, nvlist_t **l2cache, uint_t nl2cache,
|
||||||
(void) printf(gettext("\tcache\n"));
|
(void) printf(gettext("\tcache\n"));
|
||||||
|
|
||||||
for (i = 0; i < nl2cache; i++) {
|
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],
|
print_status_config(zhp, name, l2cache[i],
|
||||||
namewidth, 2, B_FALSE);
|
namewidth, 2, B_FALSE, name_flags);
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4562,7 +4669,7 @@ status_callback(zpool_handle_t *zhp, void *data)
|
||||||
ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
|
ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
|
||||||
print_scan_status(ps);
|
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)
|
if (namewidth < 10)
|
||||||
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,
|
(void) printf(gettext("\t%-*s %-8s %5s %5s %5s\n"), namewidth,
|
||||||
"NAME", "STATE", "READ", "WRITE", "CKSUM");
|
"NAME", "STATE", "READ", "WRITE", "CKSUM");
|
||||||
print_status_config(zhp, zpool_get_name(zhp), nvroot,
|
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)
|
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,
|
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
|
||||||
&l2cache, &nl2cache) == 0)
|
&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,
|
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
|
||||||
&spares, &nspares) == 0)
|
&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,
|
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
|
||||||
&nerr) == 0) {
|
&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
|
* -v Display complete error logs
|
||||||
* -x Display only pools with potential problems
|
* -x Display only pools with potential problems
|
||||||
* -D Display dedup status (undocumented)
|
* -D Display dedup status (undocumented)
|
||||||
|
@ -4646,8 +4759,17 @@ zpool_do_status(int argc, char **argv)
|
||||||
status_cbdata_t cb = { 0 };
|
status_cbdata_t cb = { 0 };
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, "vxDT:")) != -1) {
|
while ((c = getopt(argc, argv, "gLPvxDT:")) != -1) {
|
||||||
switch (c) {
|
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':
|
case 'v':
|
||||||
cb.cb_verbose = B_TRUE;
|
cb.cb_verbose = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -5916,6 +6038,7 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
(void) setlocale(LC_ALL, "");
|
(void) setlocale(LC_ALL, "");
|
||||||
(void) textdomain(TEXT_DOMAIN);
|
(void) textdomain(TEXT_DOMAIN);
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
dprintf_setup(&argc, argv);
|
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
|
* Remove any previously existing symlink from a udev path to
|
||||||
* the device before labeling the disk. This makes
|
* the device before labeling the disk. This ensures that
|
||||||
* zpool_label_disk_wait() truly wait for the new link to show
|
* only newly created links are used. Otherwise there is a
|
||||||
* up instead of returning if it finds an old link still in
|
* window between when udev deletes and recreates the link
|
||||||
* place. Otherwise there is a window between when udev
|
* during which access attempts will fail with ENOENT.
|
||||||
* deletes and recreates the link during which access attempts
|
|
||||||
* will fail with ENOENT.
|
|
||||||
*/
|
*/
|
||||||
strncpy(udevpath, path, MAXPATHLEN);
|
strncpy(udevpath, path, MAXPATHLEN);
|
||||||
(void) zfs_append_partition(udevpath, 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.
|
* and then block until udev creates the new link.
|
||||||
*/
|
*/
|
||||||
if (!is_exclusive || !is_spare(NULL, udevpath)) {
|
if (!is_exclusive || !is_spare(NULL, udevpath)) {
|
||||||
|
char *devnode = strrchr(devpath, '/') + 1;
|
||||||
|
|
||||||
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
ret = strncmp(udevpath, UDISK_ROOT, strlen(UDISK_ROOT));
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = lstat64(udevpath, &statbuf);
|
ret = lstat64(udevpath, &statbuf);
|
||||||
|
@ -1242,18 +1242,29 @@ make_disks(zpool_handle_t *zhp, nvlist_t *nv)
|
||||||
(void) unlink(udevpath);
|
(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);
|
return (-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for udev to signal the device is available
|
||||||
|
* by the provided path.
|
||||||
|
*/
|
||||||
ret = zpool_label_disk_wait(udevpath, DISK_LABEL_WAIT);
|
ret = zpool_label_disk_wait(udevpath, DISK_LABEL_WAIT);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
(void) fprintf(stderr, gettext("cannot "
|
(void) fprintf(stderr,
|
||||||
"resolve path '%s': %d\n"), udevpath, ret);
|
gettext("missing link: %s was "
|
||||||
return (-1);
|
"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
|
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 += \
|
DEFAULT_INCLUDES += \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
|
|
|
@ -7,7 +7,8 @@ AM_CFLAGS += ${NO_BOOL_COMPARE}
|
||||||
AM_CFLAGS += -fno-strict-aliasing
|
AM_CFLAGS += -fno-strict-aliasing
|
||||||
AM_CPPFLAGS = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT
|
AM_CPPFLAGS = -D_GNU_SOURCE -D__EXTENSIONS__ -D_REENTRANT
|
||||||
AM_CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_FILE_OFFSET_BITS=64
|
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 += -DLIBEXECDIR=\"$(libexecdir)\"
|
||||||
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
|
||||||
AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
|
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 #
|
||||||
dnl # 3.1 API change,
|
dnl # 3.1 API change,
|
||||||
dnl # posix_acl_chmod_masq() is not exported anymore and posix_acl_chmod()
|
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 #
|
||||||
dnl # 3.1 API change,
|
dnl # 3.1 API change,
|
||||||
dnl # posix_acl_equiv_mode now wants an umode_t* instead of a mode_t*
|
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 #
|
||||||
dnl # 2.6.27 API change,
|
dnl # 2.6.27 API change,
|
||||||
dnl # Check if inode_operations contains the function permission
|
dnl # Check if inode_operations contains the function permission
|
||||||
|
@ -247,18 +279,45 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 2.6.30 API change,
|
dnl # 3.14 API change,
|
||||||
dnl # current_umask exists only since this version.
|
dnl # Check if inode_operations contains the function set_acl
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_CURRENT_UMASK], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
|
||||||
AC_MSG_CHECKING([whether current_umask exists])
|
AC_MSG_CHECKING([whether iops->set_acl() exists])
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#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_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)
|
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_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
|
AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
|
||||||
[blk_queue_flush() is available])
|
[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_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([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/module.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
|
||||||
MODULE_LICENSE("$ZFS_META_LICENSE");
|
|
||||||
],[
|
],[
|
||||||
struct request_queue *q = NULL;
|
struct request_queue *q = NULL;
|
||||||
(void) blk_queue_flush(q, REQ_FLUSH);
|
blk_queue_write_cache(q, true, true);
|
||||||
],[
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
|
AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE, 1,
|
||||||
[blk_queue_flush() is GPL-only])
|
[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"
|
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 #
|
||||||
dnl # 2.6.27 API change
|
dnl # 2.6.27, lookup_bdev() was exported.
|
||||||
dnl # lookup_bdev() was exported.
|
dnl # 4.4.0-6.21 - x.y on Ubuntu, lookup_bdev() takes 2 arguments.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_LOOKUP_BDEV],
|
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([
|
ZFS_LINUX_TRY_COMPILE_SYMBOL([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
], [
|
], [
|
||||||
lookup_bdev(NULL);
|
lookup_bdev(NULL);
|
||||||
], [lookup_bdev], [fs/block_dev.c], [
|
], [lookup_bdev], [fs/block_dev.c], [
|
||||||
AC_MSG_RESULT(yes)
|
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_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 # Linux 3.2 API Change
|
||||||
dnl # make_request_fn returns void instead of int.
|
dnl # make_request_fn returns void instead of int.
|
||||||
dnl #
|
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_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
||||||
AC_MSG_CHECKING([whether make_request_fn() returns int])
|
AC_MSG_CHECKING([whether make_request_fn() returns int])
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
|
@ -36,8 +39,27 @@ AC_DEFUN([ZFS_AC_KERNEL_MAKE_REQUEST_FN], [
|
||||||
AC_DEFINE(MAKE_REQUEST_FN_RET, void,
|
AC_DEFINE(MAKE_REQUEST_FN_RET, void,
|
||||||
[make_request_fn() returns void])
|
[make_request_fn() returns void])
|
||||||
],[
|
],[
|
||||||
AC_MSG_ERROR(no - Please file a bug report at
|
AC_MSG_RESULT(no)
|
||||||
https://github.com/zfsonlinux/zfs/issues/new)
|
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_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([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
int iterate(struct file *filp, struct dir_context * context)
|
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
|
static const struct file_operations fops
|
||||||
__attribute__ ((unused)) = {
|
__attribute__ ((unused)) = {
|
||||||
.iterate = iterate,
|
.iterate_shared = iterate,
|
||||||
};
|
};
|
||||||
],[
|
],[
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_VFS_ITERATE, 1,
|
AC_DEFINE(HAVE_VFS_ITERATE_SHARED, 1,
|
||||||
[fops->iterate() is available])
|
[fops->iterate_shared() is available])
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
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([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#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; }
|
{ return 0; }
|
||||||
|
|
||||||
static const struct file_operations fops
|
static const struct file_operations fops
|
||||||
__attribute__ ((unused)) = {
|
__attribute__ ((unused)) = {
|
||||||
.readdir = readdir,
|
.iterate = iterate,
|
||||||
};
|
};
|
||||||
],[
|
],[
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_VFS_READDIR, 1,
|
AC_DEFINE(HAVE_VFS_ITERATE, 1,
|
||||||
[fops->readdir() is available])
|
[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 #
|
||||||
dnl # Linux 4.1.x API
|
dnl # Linux 3.16 API
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
|
AC_DEFUN([ZFS_AC_KERNEL_VFS_RW_ITERATE],
|
||||||
[AC_MSG_CHECKING([whether fops->read/write_iter() are available])
|
[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_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
|
AC_DEFINE(HAVE_VFS_RW_ITERATE, 1,
|
||||||
[fops->read/write_iter() are available])
|
[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)
|
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 # The 'struct xattr_handler' was constified in the generic
|
||||||
dnl # super_block structure.
|
dnl # super_block structure.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER],
|
AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER], [
|
||||||
[AC_MSG_CHECKING([whether super_block uses const struct xattr_hander])
|
AC_MSG_CHECKING([whether super_block uses const struct xattr_handler])
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
@ -26,24 +26,78 @@ AC_DEFUN([ZFS_AC_KERNEL_CONST_XATTR_HANDLER],
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT([yes])
|
AC_MSG_RESULT([yes])
|
||||||
AC_DEFINE(HAVE_CONST_XATTR_HANDLER, 1,
|
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])
|
AC_MSG_RESULT([no])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 2.6.33 API change,
|
dnl # 4.5 API change,
|
||||||
dnl # The xattr_hander->get() callback was changed to take a dentry
|
dnl # struct xattr_handler added new member "name".
|
||||||
dnl # instead of an inode, and a handler_flags argument was added.
|
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 #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
|
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
|
||||||
AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
|
AC_MSG_CHECKING([whether xattr_handler has name])
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
int get(struct dentry *dentry, const char *name,
|
static const struct xattr_handler
|
||||||
void *buffer, size_t size, int handler_flags) { return 0; }
|
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
|
static const struct xattr_handler
|
||||||
xops __attribute__ ((unused)) = {
|
xops __attribute__ ((unused)) = {
|
||||||
.get = get,
|
.get = get,
|
||||||
|
@ -51,26 +105,102 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
|
||||||
],[
|
],[
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_DENTRY_XATTR_GET, 1,
|
AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
|
||||||
[xattr_handler->get() wants dentry])
|
[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 #
|
||||||
dnl # 2.6.33 API change,
|
dnl # Supported xattr handler set() interfaces checked newest to oldest.
|
||||||
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 #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
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([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
int set(struct dentry *dentry, const char *name,
|
int set(const struct xattr_handler *handler,
|
||||||
const void *buffer, size_t size, int flags,
|
struct dentry *dentry, struct inode *inode,
|
||||||
int handler_flags) { return 0; }
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
|
{ return 0; }
|
||||||
static const struct xattr_handler
|
static const struct xattr_handler
|
||||||
xops __attribute__ ((unused)) = {
|
xops __attribute__ ((unused)) = {
|
||||||
.set = set,
|
.set = set,
|
||||||
|
@ -78,26 +208,98 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
||||||
],[
|
],[
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_DENTRY_XATTR_SET, 1,
|
AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
|
||||||
[xattr_handler->set() wants dentry])
|
[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 #
|
||||||
dnl # 2.6.33 API change,
|
dnl # Supported xattr handler list() interfaces checked newest to oldest.
|
||||||
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 #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
|
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([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
size_t list(struct dentry *dentry, char *list, size_t list_size,
|
bool list(struct dentry *dentry) { return 0; }
|
||||||
const char *name, size_t name_len, int handler_flags)
|
|
||||||
{ return 0; }
|
|
||||||
static const struct xattr_handler
|
static const struct xattr_handler
|
||||||
xops __attribute__ ((unused)) = {
|
xops __attribute__ ((unused)) = {
|
||||||
.list = list,
|
.list = list,
|
||||||
|
@ -105,10 +307,87 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_LIST], [
|
||||||
],[
|
],[
|
||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_DENTRY_XATTR_LIST, 1,
|
AC_DEFINE(HAVE_XATTR_LIST_SIMPLE, 1,
|
||||||
[xattr_handler->list() wants dentry])
|
[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_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_CONFIG
|
||||||
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
|
ZFS_AC_KERNEL_DECLARE_EVENT_CLASS
|
||||||
ZFS_AC_KERNEL_CURRENT_BIO_TAIL
|
ZFS_AC_KERNEL_CURRENT_BIO_TAIL
|
||||||
|
ZFS_AC_KERNEL_SUBMIT_BIO
|
||||||
ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS
|
ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS
|
||||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||||
ZFS_AC_KERNEL_TYPE_FMODE_T
|
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_BVEC_ITER
|
||||||
ZFS_AC_KERNEL_BIO_FAILFAST_DTD
|
ZFS_AC_KERNEL_BIO_FAILFAST_DTD
|
||||||
ZFS_AC_KERNEL_REQ_FAILFAST_MASK
|
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_END_IO_T_ARGS
|
||||||
ZFS_AC_KERNEL_BIO_RW_BARRIER
|
ZFS_AC_KERNEL_BIO_RW_BARRIER
|
||||||
ZFS_AC_KERNEL_BIO_RW_DISCARD
|
ZFS_AC_KERNEL_BIO_RW_DISCARD
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_FLUSH
|
ZFS_AC_KERNEL_BLK_QUEUE_FLUSH
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
|
ZFS_AC_KERNEL_BLK_QUEUE_MAX_HW_SECTORS
|
||||||
ZFS_AC_KERNEL_BLK_QUEUE_MAX_SEGMENTS
|
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_DISK_RO
|
||||||
ZFS_AC_KERNEL_GET_GENDISK
|
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_DISCARD_GRANULARITY
|
||||||
ZFS_AC_KERNEL_CONST_XATTR_HANDLER
|
ZFS_AC_KERNEL_CONST_XATTR_HANDLER
|
||||||
|
ZFS_AC_KERNEL_XATTR_HANDLER_NAME
|
||||||
ZFS_AC_KERNEL_XATTR_HANDLER_GET
|
ZFS_AC_KERNEL_XATTR_HANDLER_GET
|
||||||
ZFS_AC_KERNEL_XATTR_HANDLER_SET
|
ZFS_AC_KERNEL_XATTR_HANDLER_SET
|
||||||
ZFS_AC_KERNEL_XATTR_HANDLER_LIST
|
ZFS_AC_KERNEL_XATTR_HANDLER_LIST
|
||||||
ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
|
ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
|
||||||
ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
|
ZFS_AC_KERNEL_POSIX_ACL_FROM_XATTR_USERNS
|
||||||
ZFS_AC_KERNEL_POSIX_ACL_RELEASE
|
ZFS_AC_KERNEL_POSIX_ACL_RELEASE
|
||||||
|
ZFS_AC_KERNEL_SET_CACHED_ACL_USABLE
|
||||||
ZFS_AC_KERNEL_POSIX_ACL_CHMOD
|
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_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
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
|
ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
|
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
|
ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
|
||||||
ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
|
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_SHOW_OPTIONS
|
||||||
ZFS_AC_KERNEL_FILE_INODE
|
ZFS_AC_KERNEL_FILE_INODE
|
||||||
ZFS_AC_KERNEL_FSYNC
|
ZFS_AC_KERNEL_FSYNC
|
||||||
|
@ -55,16 +68,18 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
||||||
ZFS_AC_KERNEL_NR_CACHED_OBJECTS
|
ZFS_AC_KERNEL_NR_CACHED_OBJECTS
|
||||||
ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
|
ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
|
||||||
ZFS_AC_KERNEL_FALLOCATE
|
ZFS_AC_KERNEL_FALLOCATE
|
||||||
|
ZFS_AC_KERNEL_AIO_FSYNC
|
||||||
ZFS_AC_KERNEL_MKDIR_UMODE_T
|
ZFS_AC_KERNEL_MKDIR_UMODE_T
|
||||||
ZFS_AC_KERNEL_LOOKUP_NAMEIDATA
|
ZFS_AC_KERNEL_LOOKUP_NAMEIDATA
|
||||||
ZFS_AC_KERNEL_CREATE_NAMEIDATA
|
ZFS_AC_KERNEL_CREATE_NAMEIDATA
|
||||||
ZFS_AC_KERNEL_FOLLOW_LINK
|
ZFS_AC_KERNEL_GET_LINK
|
||||||
ZFS_AC_KERNEL_PUT_LINK
|
ZFS_AC_KERNEL_PUT_LINK
|
||||||
ZFS_AC_KERNEL_TRUNCATE_RANGE
|
ZFS_AC_KERNEL_TRUNCATE_RANGE
|
||||||
ZFS_AC_KERNEL_AUTOMOUNT
|
ZFS_AC_KERNEL_AUTOMOUNT
|
||||||
ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE
|
ZFS_AC_KERNEL_ENCODE_FH_WITH_INODE
|
||||||
ZFS_AC_KERNEL_COMMIT_METADATA
|
ZFS_AC_KERNEL_COMMIT_METADATA
|
||||||
ZFS_AC_KERNEL_CLEAR_INODE
|
ZFS_AC_KERNEL_CLEAR_INODE
|
||||||
|
ZFS_AC_KERNEL_SETATTR_PREPARE
|
||||||
ZFS_AC_KERNEL_INSERT_INODE_LOCKED
|
ZFS_AC_KERNEL_INSERT_INODE_LOCKED
|
||||||
ZFS_AC_KERNEL_D_MAKE_ROOT
|
ZFS_AC_KERNEL_D_MAKE_ROOT
|
||||||
ZFS_AC_KERNEL_D_OBTAIN_ALIAS
|
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_SHRINK_CONTROL_HAS_NID
|
||||||
ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD
|
ZFS_AC_KERNEL_S_INSTANCES_LIST_HEAD
|
||||||
ZFS_AC_KERNEL_S_D_OP
|
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_SET_NLINK
|
||||||
ZFS_AC_KERNEL_ELEVATOR_CHANGE
|
ZFS_AC_KERNEL_ELEVATOR_CHANGE
|
||||||
ZFS_AC_KERNEL_5ARG_SGET
|
ZFS_AC_KERNEL_5ARG_SGET
|
||||||
ZFS_AC_KERNEL_LSEEK_EXECUTE
|
ZFS_AC_KERNEL_LSEEK_EXECUTE
|
||||||
ZFS_AC_KERNEL_VFS_ITERATE
|
ZFS_AC_KERNEL_VFS_ITERATE
|
||||||
ZFS_AC_KERNEL_VFS_RW_ITERATE
|
ZFS_AC_KERNEL_VFS_RW_ITERATE
|
||||||
|
ZFS_AC_KERNEL_GENERIC_WRITE_CHECKS
|
||||||
ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
|
ZFS_AC_KERNEL_KMAP_ATOMIC_ARGS
|
||||||
ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
|
ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
|
||||||
ZFS_AC_KERNEL_MAKE_REQUEST_FN
|
ZFS_AC_KERNEL_MAKE_REQUEST_FN
|
||||||
ZFS_AC_KERNEL_GENERIC_IO_ACCT
|
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"], [
|
AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
|
||||||
KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
|
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 # modules may be successfully built that behave incorrectly.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_CONFIG], [
|
AC_DEFUN([ZFS_AC_KERNEL_CONFIG], [
|
||||||
AC_RUN_IFELSE([
|
AS_IF([test "x$cross_compiling" != xyes], [
|
||||||
AC_LANG_PROGRAM([
|
AC_RUN_IFELSE([
|
||||||
#include "$LINUX/include/linux/license.h"
|
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
|
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 #
|
||||||
dnl # Check CONFIG_DEBUG_LOCK_ALLOC
|
dnl # Check CONFIG_DEBUG_LOCK_ALLOC
|
||||||
dnl #
|
dnl #
|
||||||
|
@ -572,7 +619,7 @@ dnl #
|
||||||
dnl # ZFS_LINUX_CONFIG
|
dnl # ZFS_LINUX_CONFIG
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_LINUX_CONFIG],
|
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([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/module.h>
|
#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_LIBBLKID
|
||||||
ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
|
ZFS_AC_CONFIG_USER_FRAME_LARGER_THAN
|
||||||
ZFS_AC_CONFIG_USER_RUNSTATEDIR
|
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 #
|
||||||
dnl # Checks for library functions
|
dnl # Checks for library functions
|
||||||
AC_CHECK_FUNCS([mlockall])
|
AC_CHECK_FUNCS([mlockall])
|
||||||
|
|
|
@ -55,6 +55,8 @@ adjust_obj_paths()
|
||||||
for MODULE in "${MODULES[@]}"
|
for MODULE in "${MODULES[@]}"
|
||||||
do
|
do
|
||||||
adjust_obj_paths "$KERNEL_DIR/fs/zfs/$MODULE/Makefile"
|
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
|
done
|
||||||
|
|
||||||
cat > "$KERNEL_DIR/fs/zfs/Kconfig" <<"EOF"
|
cat > "$KERNEL_DIR/fs/zfs/Kconfig" <<"EOF"
|
||||||
|
|
|
@ -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
|
# 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
|
50-zfs.preset
|
||||||
|
|
||||||
systemdunit_DATA = \
|
systemdunit_DATA = \
|
||||||
zed.service \
|
zfs-zed.service \
|
||||||
zfs-import-cache.service \
|
zfs-import-cache.service \
|
||||||
zfs-import-scan.service \
|
zfs-import-scan.service \
|
||||||
zfs-mount.service \
|
zfs-mount.service \
|
||||||
|
@ -10,7 +10,7 @@ systemdunit_DATA = \
|
||||||
zfs.target
|
zfs.target
|
||||||
|
|
||||||
EXTRA_DIST = \
|
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-cache.service.in \
|
||||||
$(top_srcdir)/etc/systemd/system/zfs-import-scan.service.in \
|
$(top_srcdir)/etc/systemd/system/zfs-import-scan.service.in \
|
||||||
$(top_srcdir)/etc/systemd/system/zfs-mount.service.in \
|
$(top_srcdir)/etc/systemd/system/zfs-mount.service.in \
|
||||||
|
|
|
@ -4,6 +4,7 @@ DefaultDependencies=no
|
||||||
Requires=systemd-udev-settle.service
|
Requires=systemd-udev-settle.service
|
||||||
After=systemd-udev-settle.service
|
After=systemd-udev-settle.service
|
||||||
After=cryptsetup.target
|
After=cryptsetup.target
|
||||||
|
After=systemd-remount-fs.service
|
||||||
ConditionPathExists=@sysconfdir@/zfs/zpool.cache
|
ConditionPathExists=@sysconfdir@/zfs/zpool.cache
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
@ -11,3 +12,7 @@ Type=oneshot
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
ExecStartPre=/sbin/modprobe zfs
|
ExecStartPre=/sbin/modprobe zfs
|
||||||
ExecStart=@sbindir@/zpool import -c @sysconfdir@/zfs/zpool.cache -aN
|
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
|
Type=oneshot
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
ExecStartPre=/sbin/modprobe zfs
|
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]
|
[Unit]
|
||||||
Description=Mount ZFS filesystems
|
Description=Mount ZFS filesystems
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
Wants=zfs-import-cache.service
|
|
||||||
Wants=zfs-import-scan.service
|
|
||||||
Requires=systemd-udev-settle.service
|
|
||||||
After=systemd-udev-settle.service
|
After=systemd-udev-settle.service
|
||||||
After=zfs-import-cache.service
|
After=zfs-import-cache.service
|
||||||
After=zfs-import-scan.service
|
After=zfs-import-scan.service
|
||||||
|
After=systemd-remount-fs.service
|
||||||
Before=local-fs.target
|
Before=local-fs.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
ExecStart=@sbindir@/zfs mount -a
|
ExecStart=@sbindir@/zfs mount -a
|
||||||
|
WorkingDirectory=-/sbin/
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=zfs-share.service
|
||||||
|
WantedBy=zfs.target
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=ZFS file system shares
|
Description=ZFS file system shares
|
||||||
After=nfs-server.service
|
After=nfs-server.service nfs-kernel-server.service
|
||||||
After=smb.service
|
After=smb.service
|
||||||
After=zfs-mount.service
|
After=zfs-mount.service
|
||||||
Requires=zfs-mount.service
|
PartOf=nfs-server.service nfs-kernel-server.service
|
||||||
PartOf=nfs-server.service
|
|
||||||
PartOf=smb.service
|
PartOf=smb.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
ExecStartPre=-@bindir@/rm /etc/dfs/sharetab
|
ExecStartPre=-@bindir@/rm -f /etc/dfs/sharetab
|
||||||
ExecStart=@sbindir@/zfs share -a
|
ExecStart=@sbindir@/zfs share -a
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=zfs.target
|
||||||
|
|
|
@ -7,3 +7,7 @@ After=zfs-import-scan.service
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=@sbindir@/zed -F
|
ExecStart=@sbindir@/zed -F
|
||||||
Restart=on-abort
|
Restart=on-abort
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
Alias=zed.service
|
||||||
|
WantedBy=zfs.target
|
|
@ -1,8 +1,5 @@
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=ZFS startup target
|
Description=ZFS startup target
|
||||||
Requires=zfs-mount.service
|
|
||||||
Requires=zfs-share.service
|
|
||||||
Wants=zed.service
|
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|
|
@ -248,6 +248,7 @@ typedef struct splitflags {
|
||||||
|
|
||||||
/* after splitting, import the pool */
|
/* after splitting, import the pool */
|
||||||
int import : 1;
|
int import : 1;
|
||||||
|
int name_flags;
|
||||||
} splitflags_t;
|
} splitflags_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -406,8 +407,15 @@ struct zfs_cmd;
|
||||||
|
|
||||||
extern const char *zfs_history_event_names[];
|
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 *,
|
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_upgrade(zpool_handle_t *, uint64_t);
|
||||||
extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
|
extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
|
||||||
extern int zpool_history_unpack(char *, uint64_t, uint64_t *,
|
extern int zpool_history_unpack(char *, uint64_t, uint64_t *,
|
||||||
|
|
|
@ -46,11 +46,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VERIFY
|
|
||||||
#undef VERIFY
|
|
||||||
#endif
|
|
||||||
#define VERIFY verify
|
|
||||||
|
|
||||||
typedef struct libzfs_fru {
|
typedef struct libzfs_fru {
|
||||||
char *zf_device;
|
char *zf_device;
|
||||||
char *zf_fru;
|
char *zf_fru;
|
||||||
|
|
|
@ -37,21 +37,48 @@ typedef unsigned __bitwise__ fmode_t;
|
||||||
#endif /* HAVE_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()
|
* The blk_queue_flush() interface has replaced blk_queue_ordered()
|
||||||
* interface. However, while the old interface was available to all the
|
* 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
|
* new one is GPL-only. Thus if the GPL-only version is detected we
|
||||||
* implement our own trivial helper compatibility funcion. The hope is
|
* implement our own trivial helper.
|
||||||
* that long term this function will be opened up.
|
*
|
||||||
|
* 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
|
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
|
* Most of the blk_* macros were removed in 2.6.36. Ostensibly this was
|
||||||
* done to improve readability and allow easier grepping. However, from
|
* 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
|
* 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.
|
* 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
|
#ifdef HAVE_1ARG_LOOKUP_BDEV
|
||||||
#define lookup_bdev(path) ERR_PTR(-ENOTSUP)
|
#define vdev_lookup_bdev(path) lookup_bdev(path)
|
||||||
#endif
|
#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
|
* 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_LOGICAL_BLOCK_SIZE */
|
||||||
#endif /* HAVE_BDEV_PHYSICAL_BLOCK_SIZE */
|
#endif /* HAVE_BDEV_PHYSICAL_BLOCK_SIZE */
|
||||||
|
|
||||||
|
#ifndef HAVE_BIO_SET_OP_ATTRS
|
||||||
/*
|
/*
|
||||||
* 2.6.37 API change
|
* Kernels without bio_set_op_attrs use bi_rw for the bio flags.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
#ifdef WRITE_FLUSH_FUA
|
static inline void
|
||||||
#define VDEV_WRITE_FLUSH_FUA WRITE_FLUSH_FUA
|
bio_set_op_attrs(struct bio *bio, unsigned rw, unsigned flags)
|
||||||
#define VDEV_REQ_FLUSH REQ_FLUSH
|
{
|
||||||
#define VDEV_REQ_FUA REQ_FUA
|
bio->bi_rw |= rw | flags;
|
||||||
#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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2.6.32 API change
|
* bio_set_flush - Set the appropriate flags in a bio to guarantee
|
||||||
* Use the normal I/O patch for discards.
|
* 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
|
static inline void
|
||||||
#ifdef HAVE_BIO_RW_DISCARD
|
bio_set_flush(struct bio *bio)
|
||||||
#define VDEV_REQ_DISCARD (1 << BIO_RW_DISCARD)
|
{
|
||||||
|
#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
|
#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
|
#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
|
#else
|
||||||
#error "Allowing the build will cause discard requests to become writes "
|
#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"
|
"an issue report at: https://github.com/zfsonlinux/zfs/issues/new"
|
||||||
#endif
|
#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
|
* 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.32 - 2.6.33, bdi_setup_and_register() is not available.
|
||||||
* 2.6.34 - 3.19, bdi_setup_and_register() takes 3 arguments.
|
* 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
|
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)
|
#elif defined(HAVE_3ARGS_BDI_SETUP_AND_REGISTER)
|
||||||
static inline int
|
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
|
#else
|
||||||
extern atomic_long_t zfs_bdi_seq;
|
extern atomic_long_t zfs_bdi_seq;
|
||||||
|
|
||||||
static inline int
|
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;
|
int error;
|
||||||
|
|
||||||
|
bdi = kmem_zalloc(sizeof (struct backing_dev_info), KM_SLEEP);
|
||||||
bdi->name = name;
|
bdi->name = name;
|
||||||
bdi->capabilities = BDI_CAP_MAP_COPY;
|
bdi->capabilities = BDI_CAP_MAP_COPY;
|
||||||
|
|
||||||
error = bdi_init(bdi);
|
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) {
|
if (error) {
|
||||||
bdi_destroy(bdi);
|
kmem_free(bdi, sizeof (struct backing_dev_info));
|
||||||
return (error);
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -202,22 +272,11 @@ lseek_execute(
|
||||||
* At 60 seconds the kernel will also begin issuing RCU stall warnings.
|
* At 60 seconds the kernel will also begin issuing RCU stall warnings.
|
||||||
*/
|
*/
|
||||||
#include <linux/posix_acl.h>
|
#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)
|
#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_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
|
#else
|
||||||
|
void zpl_posix_acl_release_impl(struct posix_acl *);
|
||||||
static inline void
|
|
||||||
zpl_posix_acl_free(void *arg) {
|
|
||||||
kfree(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
zpl_posix_acl_release(struct posix_acl *acl)
|
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))
|
if ((acl == NULL) || (acl == ACL_NOT_CACHED))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (atomic_dec_and_test(&acl->a_refcount)) {
|
if (atomic_dec_and_test(&acl->a_refcount))
|
||||||
taskq_dispatch_delay(system_taskq, zpl_posix_acl_free, acl,
|
zpl_posix_acl_release_impl(acl);
|
||||||
TQ_SLEEP, ddi_get_lbolt() + 60*HZ);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#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
|
static inline void
|
||||||
zpl_set_cached_acl(struct inode *ip, int type, struct posix_acl *newer) {
|
zpl_set_cached_acl(struct inode *ip, int type, struct posix_acl *newer) {
|
||||||
#ifdef HAVE_POSIX_ACL_CACHING
|
|
||||||
struct posix_acl *older = NULL;
|
struct posix_acl *older = NULL;
|
||||||
|
|
||||||
spin_lock(&ip->i_lock);
|
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);
|
spin_unlock(&ip->i_lock);
|
||||||
|
|
||||||
zpl_posix_acl_release(older);
|
zpl_posix_acl_release(older);
|
||||||
#endif /* HAVE_POSIX_ACL_CACHING */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
zpl_forget_cached_acl(struct inode *ip, int type) {
|
zpl_forget_cached_acl(struct inode *ip, int type) {
|
||||||
zpl_set_cached_acl(ip, type, (struct posix_acl *)ACL_NOT_CACHED);
|
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
|
#ifndef HAVE___POSIX_ACL_CHMOD
|
||||||
#ifdef HAVE_POSIX_ACL_CHMOD
|
#ifdef HAVE_POSIX_ACL_CHMOD
|
||||||
|
@ -320,15 +380,19 @@ typedef umode_t zpl_equivmode_t;
|
||||||
#else
|
#else
|
||||||
typedef mode_t zpl_equivmode_t;
|
typedef mode_t zpl_equivmode_t;
|
||||||
#endif /* HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T */
|
#endif /* HAVE_POSIX_ACL_EQUIV_MODE_UMODE_T */
|
||||||
#endif /* CONFIG_FS_POSIX_ACL */
|
|
||||||
|
|
||||||
#ifndef HAVE_CURRENT_UMASK
|
/*
|
||||||
static inline int
|
* 4.8 API change,
|
||||||
current_umask(void)
|
* 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.
|
||||||
return (current->fs->umask);
|
*/
|
||||||
}
|
#ifdef HAVE_POSIX_ACL_VALID_WITH_NS
|
||||||
#endif /* HAVE_CURRENT_UMASK */
|
#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,
|
* 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)
|
#define zpl_follow_up(path) follow_up(path)
|
||||||
#endif
|
#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 */
|
#endif /* _ZFS_VFS_H */
|
||||||
|
|
|
@ -41,12 +41,99 @@ typedef const struct xattr_handler xattr_handler_t;
|
||||||
typedef struct xattr_handler xattr_handler_t;
|
typedef struct xattr_handler xattr_handler_t;
|
||||||
#endif
|
#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,
|
* 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.
|
* 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) \
|
#define ZPL_XATTR_GET_WRAPPER(fn) \
|
||||||
static int \
|
static int \
|
||||||
fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \
|
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)); \
|
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) \
|
#define ZPL_XATTR_GET_WRAPPER(fn) \
|
||||||
static int \
|
static int \
|
||||||
fn(struct inode *ip, const char *name, void *buffer, size_t size) \
|
fn(struct inode *ip, const char *name, void *buffer, size_t size) \
|
||||||
{ \
|
{ \
|
||||||
return (__ ## fn(ip, name, buffer, 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,
|
* 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.
|
* 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) \
|
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||||
static int \
|
static int \
|
||||||
fn(struct dentry *dentry, const char *name, const void *buffer, \
|
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)); \
|
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) \
|
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||||
static int \
|
static int \
|
||||||
fn(struct inode *ip, const char *name, const void *buffer, \
|
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)); \
|
return (__ ## fn(ip, name, buffer, size, flags)); \
|
||||||
}
|
}
|
||||||
#endif /* HAVE_DENTRY_XATTR_SET */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY
|
#ifdef HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY
|
||||||
#define zpl_security_inode_init_security(ip, dip, qstr, nm, val, len) \
|
#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
|
* 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
|
* parameter. All callers are expected to pass the &init_user_ns which
|
||||||
* userns _may_ not be correct because it's used outside the RCU.
|
* is available through the init credential (kcred).
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_POSIX_ACL_FROM_XATTR_USERNS
|
#ifdef HAVE_POSIX_ACL_FROM_XATTR_USERNS
|
||||||
static inline struct posix_acl *
|
static inline struct posix_acl *
|
||||||
zpl_acl_from_xattr(const void *value, int size)
|
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
|
static inline int
|
||||||
zpl_acl_to_xattr(struct posix_acl *acl, void *value, int size)
|
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
|
#else
|
||||||
|
|
|
@ -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_disown(dsl_dataset_t *ds, void *tag);
|
||||||
void dsl_dataset_name(dsl_dataset_t *ds, char *name);
|
void dsl_dataset_name(dsl_dataset_t *ds, char *name);
|
||||||
boolean_t dsl_dataset_tryown(dsl_dataset_t *ds, void *tag);
|
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,
|
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 *);
|
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,
|
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_MAXNAMELEN 256
|
||||||
#define ZAP_MAXVALUELEN (1024 * 8)
|
#define ZAP_MAXVALUELEN (1024 * 8)
|
||||||
#define ZAP_OLDMAXVALUELEN 1024
|
#define ZAP_OLDMAXVALUELEN 1024
|
||||||
|
#define ZFS_MAX_DATASET_NAME_LEN 256
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dataset properties are identified by these constants and must be added to
|
* Dataset properties are identified by these constants and must be added to
|
||||||
|
|
|
@ -68,8 +68,9 @@
|
||||||
#define MNTOPT_NOFAIL "nofail" /* no failure */
|
#define MNTOPT_NOFAIL "nofail" /* no failure */
|
||||||
#define MNTOPT_RELATIME "relatime" /* allow relative time updates */
|
#define MNTOPT_RELATIME "relatime" /* allow relative time updates */
|
||||||
#define MNTOPT_NORELATIME "norelatime" /* do not allow relative time updates */
|
#define MNTOPT_NORELATIME "norelatime" /* do not allow relative time updates */
|
||||||
#define MNTOPT_DFRATIME "strictatime" /* Deferred access time updates */
|
#define MNTOPT_STRICTATIME "strictatime" /* strict access time updates */
|
||||||
#define MNTOPT_NODFRATIME "nostrictatime" /* No Deferred 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_SETUID "suid" /* Both setuid and devices allowed */
|
||||||
#define MNTOPT_NOSETUID "nosuid" /* Neither setuid nor devices allowed */
|
#define MNTOPT_NOSETUID "nosuid" /* Neither setuid nor devices allowed */
|
||||||
#define MNTOPT_OWNER "owner" /* allow owner mount */
|
#define MNTOPT_OWNER "owner" /* allow owner mount */
|
||||||
|
|
|
@ -40,6 +40,17 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define FTAG ((char *)__func__)
|
#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
|
#ifdef ZFS_DEBUG
|
||||||
typedef struct reference {
|
typedef struct reference {
|
||||||
list_node_t ref_link;
|
list_node_t ref_link;
|
||||||
|
@ -55,7 +66,7 @@ typedef struct refcount {
|
||||||
list_t rc_removed;
|
list_t rc_removed;
|
||||||
int64_t rc_count;
|
int64_t rc_count;
|
||||||
int64_t rc_removed_count;
|
int64_t rc_removed_count;
|
||||||
} refcount_t;
|
} zfs_refcount_t;
|
||||||
|
|
||||||
/* Note: refcount_t must be initialized with refcount_create[_untracked]() */
|
/* 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);
|
void refcount_destroy_many(refcount_t *rc, uint64_t number);
|
||||||
int refcount_is_zero(refcount_t *rc);
|
int refcount_is_zero(refcount_t *rc);
|
||||||
int64_t refcount_count(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_remove(refcount_t *rc, void *holder_tag);
|
||||||
int64_t refcount_add_many(refcount_t *rc, uint64_t number, 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);
|
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_destroy_many(rc, number) ((rc)->rc_count = 0)
|
||||||
#define refcount_is_zero(rc) ((rc)->rc_count == 0)
|
#define refcount_is_zero(rc) ((rc)->rc_count == 0)
|
||||||
#define refcount_count(rc) ((rc)->rc_count)
|
#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_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1)
|
||||||
#define refcount_add_many(rc, number, holder) \
|
#define refcount_add_many(rc, number, holder) \
|
||||||
atomic_add_64_nv(&(rc)->rc_count, number)
|
atomic_add_64_nv(&(rc)->rc_count, number)
|
||||||
|
|
|
@ -82,6 +82,10 @@ typedef struct sa_bulk_attr {
|
||||||
uint16_t sa_size;
|
uint16_t sa_size;
|
||||||
} sa_bulk_attr_t;
|
} 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
|
* 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) \
|
#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_attr = attr;\
|
||||||
b[idx].sa_data_func = func; \
|
b[idx].sa_data_func = func; \
|
||||||
b[idx].sa_data = data; \
|
b[idx].sa_data = data; \
|
||||||
|
|
|
@ -446,6 +446,10 @@ _NOTE(CONSTCOND) } while (0)
|
||||||
((zc1).zc_word[2] - (zc2).zc_word[2]) | \
|
((zc1).zc_word[2] - (zc2).zc_word[2]) | \
|
||||||
((zc1).zc_word[3] - (zc2).zc_word[3])))
|
((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 DVA_IS_VALID(dva) (DVA_GET_ASIZE(dva) != 0)
|
||||||
|
|
||||||
#define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \
|
#define ZIO_SET_CHECKSUM(zcp, w0, w1, w2, w3) \
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2014 Spectra Logic Corporation, 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
|
#ifndef _SYS_SPA_IMPL_H
|
||||||
|
@ -252,6 +253,7 @@ struct spa {
|
||||||
uint64_t spa_deadman_synctime; /* deadman expiration timer */
|
uint64_t spa_deadman_synctime; /* deadman expiration timer */
|
||||||
uint64_t spa_errata; /* errata issues detected */
|
uint64_t spa_errata; /* errata issues detected */
|
||||||
spa_stats_t spa_stats; /* assorted spa statistics */
|
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
|
* 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_mapcnt)
|
||||||
__field(uint64_t, z_gen)
|
__field(uint64_t, z_gen)
|
||||||
__field(uint64_t, z_size)
|
__field(uint64_t, z_size)
|
||||||
__array(uint64_t, z_atime, 2)
|
|
||||||
__field(uint64_t, z_links)
|
__field(uint64_t, z_links)
|
||||||
__field(uint64_t, z_pflags)
|
__field(uint64_t, z_pflags)
|
||||||
__field(uint64_t, z_uid)
|
__field(uint64_t, z_uid)
|
||||||
|
@ -64,7 +63,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
||||||
__field(uint32_t, z_sync_cnt)
|
__field(uint32_t, z_sync_cnt)
|
||||||
__field(mode_t, z_mode)
|
__field(mode_t, z_mode)
|
||||||
__field(boolean_t, z_is_sa)
|
__field(boolean_t, z_is_sa)
|
||||||
__field(boolean_t, z_is_zvol)
|
|
||||||
__field(boolean_t, z_is_mapped)
|
__field(boolean_t, z_is_mapped)
|
||||||
__field(boolean_t, z_is_ctldir)
|
__field(boolean_t, z_is_ctldir)
|
||||||
__field(boolean_t, z_is_stale)
|
__field(boolean_t, z_is_stale)
|
||||||
|
@ -95,8 +93,6 @@ DECLARE_EVENT_CLASS(zfs_ace_class,
|
||||||
__entry->z_mapcnt = zn->z_mapcnt;
|
__entry->z_mapcnt = zn->z_mapcnt;
|
||||||
__entry->z_gen = zn->z_gen;
|
__entry->z_gen = zn->z_gen;
|
||||||
__entry->z_size = zn->z_size;
|
__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_links = zn->z_links;
|
||||||
__entry->z_pflags = zn->z_pflags;
|
__entry->z_pflags = zn->z_pflags;
|
||||||
__entry->z_uid = zn->z_uid;
|
__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_sync_cnt = zn->z_sync_cnt;
|
||||||
__entry->z_mode = zn->z_mode;
|
__entry->z_mode = zn->z_mode;
|
||||||
__entry->z_is_sa = zn->z_is_sa;
|
__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_mapped = zn->z_is_mapped;
|
||||||
__entry->z_is_ctldir = zn->z_is_ctldir;
|
__entry->z_is_ctldir = zn->z_is_ctldir;
|
||||||
__entry->z_is_stale = zn->z_is_stale;
|
__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 "
|
TP_printk("zn { id %llu unlinked %u atime_dirty %u "
|
||||||
"zn_prefetch %u moved %u blksz %u seq %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 "
|
"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 { "
|
"is_mapped %d is_ctldir %d is_stale %d inode { "
|
||||||
"ino %lu nlink %u version %llu size %lli blkbits %u "
|
"ino %lu nlink %u version %llu size %lli blkbits %u "
|
||||||
"bytes %u mode 0x%x generation %x } } ace { type %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_id, __entry->z_unlinked, __entry->z_atime_dirty,
|
||||||
__entry->z_zn_prefetch, __entry->z_moved, __entry->z_blksz,
|
__entry->z_zn_prefetch, __entry->z_moved, __entry->z_blksz,
|
||||||
__entry->z_seq, __entry->z_mapcnt, __entry->z_gen,
|
__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_links, __entry->z_pflags, __entry->z_uid,
|
||||||
__entry->z_gid, __entry->z_sync_cnt, __entry->z_mode,
|
__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->z_is_ctldir, __entry->z_is_stale, __entry->i_ino,
|
||||||
__entry->i_nlink, __entry->i_version, __entry->i_size,
|
__entry->i_nlink, __entry->i_version, __entry->i_size,
|
||||||
__entry->i_blkbits, __entry->i_bytes, __entry->i_mode,
|
__entry->i_blkbits, __entry->i_bytes, __entry->i_mode,
|
||||||
|
|
|
@ -37,9 +37,5 @@ typedef struct vdev_disk {
|
||||||
struct block_device *vd_bdev;
|
struct block_device *vd_bdev;
|
||||||
} vdev_disk_t;
|
} 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 /* _KERNEL */
|
||||||
#endif /* _SYS_VDEV_DISK_H */
|
#endif /* _SYS_VDEV_DISK_H */
|
||||||
|
|
|
@ -225,7 +225,7 @@ typedef struct xvattr {
|
||||||
* of requested attributes (xva_reqattrmap[]).
|
* of requested attributes (xva_reqattrmap[]).
|
||||||
*/
|
*/
|
||||||
#define XVA_SET_REQ(xvap, attr) \
|
#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); \
|
ASSERT((xvap)->xva_magic == XVA_MAGIC); \
|
||||||
(xvap)->xva_reqattrmap[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
|
(xvap)->xva_reqattrmap[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
|
||||||
/*
|
/*
|
||||||
|
@ -233,7 +233,7 @@ typedef struct xvattr {
|
||||||
* of requested attributes (xva_reqattrmap[]).
|
* of requested attributes (xva_reqattrmap[]).
|
||||||
*/
|
*/
|
||||||
#define XVA_CLR_REQ(xvap, attr) \
|
#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); \
|
ASSERT((xvap)->xva_magic == XVA_MAGIC); \
|
||||||
(xvap)->xva_reqattrmap[XVA_INDEX(attr)] &= ~XVA_ATTRBIT(attr)
|
(xvap)->xva_reqattrmap[XVA_INDEX(attr)] &= ~XVA_ATTRBIT(attr)
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ typedef struct xvattr {
|
||||||
* of returned attributes (xva_rtnattrmap[]).
|
* of returned attributes (xva_rtnattrmap[]).
|
||||||
*/
|
*/
|
||||||
#define XVA_SET_RTN(xvap, attr) \
|
#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); \
|
ASSERT((xvap)->xva_magic == XVA_MAGIC); \
|
||||||
(XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] |= XVA_ATTRBIT(attr)
|
(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.
|
* to see of the corresponding attribute bit is set. If so, returns non-zero.
|
||||||
*/
|
*/
|
||||||
#define XVA_ISSET_REQ(xvap, attr) \
|
#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_magic == XVA_MAGIC) && \
|
||||||
((xvap)->xva_mapsize > XVA_INDEX(attr))) ? \
|
((xvap)->xva_mapsize > XVA_INDEX(attr))) ? \
|
||||||
((xvap)->xva_reqattrmap[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) : 0)
|
((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.
|
* to see of the corresponding attribute bit is set. If so, returns non-zero.
|
||||||
*/
|
*/
|
||||||
#define XVA_ISSET_RTN(xvap, attr) \
|
#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_magic == XVA_MAGIC) && \
|
||||||
((xvap)->xva_mapsize > XVA_INDEX(attr))) ? \
|
((xvap)->xva_mapsize > XVA_INDEX(attr))) ? \
|
||||||
((XVA_RTNATTRMAP(xvap))[XVA_INDEX(attr)] & XVA_ATTRBIT(attr)) : 0)
|
((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 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 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_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 zap_prefetch_uint64(objset_t *os, uint64_t zapobj, const uint64_t *key,
|
||||||
int key_numints);
|
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 void zfsctl_snapdir_inactive(struct inode *ip);
|
||||||
extern int zfsctl_snapshot_mount(struct path *path, int flags);
|
extern int zfsctl_snapshot_mount(struct path *path, int flags);
|
||||||
extern int zfsctl_snapshot_unmount(char *snapname, 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,
|
extern int zfsctl_lookup_objset(struct super_block *sb, uint64_t objsetid,
|
||||||
zfs_sb_t **zsb);
|
zfs_sb_t **zsb);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,9 @@ extern "C" {
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
|
|
||||||
#include <sys/zfs_znode.h>
|
#include <sys/list.h>
|
||||||
|
#include <sys/avl.h>
|
||||||
|
#include <sys/condvar.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RL_READER,
|
RL_READER,
|
||||||
|
@ -40,8 +42,16 @@ typedef enum {
|
||||||
RL_APPEND
|
RL_APPEND
|
||||||
} rl_type_t;
|
} 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 {
|
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 */
|
avl_node_t r_node; /* avl node link */
|
||||||
uint64_t r_off; /* file range offset */
|
uint64_t r_off; /* file range offset */
|
||||||
uint64_t r_len; /* file range length */
|
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
|
* is converted to RL_WRITER that specified to lock from the start of the
|
||||||
* end of file. Returns the range lock structure.
|
* 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. */
|
/* Unlock range and destroy range lock structure. */
|
||||||
void zfs_range_unlock(rl_t *rl);
|
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);
|
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 */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -64,7 +64,6 @@ typedef struct zfs_mntopts {
|
||||||
|
|
||||||
typedef struct zfs_sb {
|
typedef struct zfs_sb {
|
||||||
struct super_block *z_sb; /* generic super_block */
|
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 */
|
struct zfs_sb *z_parent; /* parent fs */
|
||||||
objset_t *z_os; /* objset reference */
|
objset_t *z_os; /* objset reference */
|
||||||
zfs_mntopts_t *z_mntopts; /* passed mount options */
|
zfs_mntopts_t *z_mntopts; /* passed mount options */
|
||||||
|
@ -112,8 +111,9 @@ typedef struct zfs_sb {
|
||||||
uint64_t z_groupquota_obj;
|
uint64_t z_groupquota_obj;
|
||||||
uint64_t z_replay_eof; /* New end of file - replay only */
|
uint64_t z_replay_eof; /* New end of file - replay only */
|
||||||
sa_attr_type_t *z_attr_table; /* SA attr mapping->id */
|
sa_attr_type_t *z_attr_table; /* SA attr mapping->id */
|
||||||
#define ZFS_OBJ_MTX_SZ 256
|
uint64_t z_hold_size; /* znode hold array size */
|
||||||
kmutex_t *z_hold_mtx; /* znode hold locks */
|
avl_tree_t *z_hold_trees; /* znode hold trees */
|
||||||
|
kmutex_t *z_hold_locks; /* znode hold locks */
|
||||||
} zfs_sb_t;
|
} zfs_sb_t;
|
||||||
|
|
||||||
#define ZFS_SUPER_MAGIC 0x2fc12fc1
|
#define ZFS_SUPER_MAGIC 0x2fc12fc1
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <sys/rrwlock.h>
|
#include <sys/rrwlock.h>
|
||||||
#include <sys/zfs_sa.h>
|
#include <sys/zfs_sa.h>
|
||||||
#include <sys/zfs_stat.h>
|
#include <sys/zfs_stat.h>
|
||||||
|
#include <sys/zfs_rlock.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/zfs_acl.h>
|
#include <sys/zfs_acl.h>
|
||||||
#include <sys/zil.h>
|
#include <sys/zil.h>
|
||||||
|
@ -187,8 +188,7 @@ typedef struct znode {
|
||||||
krwlock_t z_parent_lock; /* parent lock for directories */
|
krwlock_t z_parent_lock; /* parent lock for directories */
|
||||||
krwlock_t z_name_lock; /* "master" lock for dirent locks */
|
krwlock_t z_name_lock; /* "master" lock for dirent locks */
|
||||||
zfs_dirlock_t *z_dirlocks; /* directory entry lock list */
|
zfs_dirlock_t *z_dirlocks; /* directory entry lock list */
|
||||||
kmutex_t z_range_lock; /* protects changes to z_range_avl */
|
zfs_rlock_t z_range_lock; /* file range lock */
|
||||||
avl_tree_t z_range_avl; /* avl tree of file range locks */
|
|
||||||
uint8_t z_unlinked; /* file has been unlinked */
|
uint8_t z_unlinked; /* file has been unlinked */
|
||||||
uint8_t z_atime_dirty; /* atime needs to be synced */
|
uint8_t z_atime_dirty; /* atime needs to be synced */
|
||||||
uint8_t z_zn_prefetch; /* Prefetch znodes? */
|
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_mapcnt; /* number of pages mapped to file */
|
||||||
uint64_t z_gen; /* generation (cached) */
|
uint64_t z_gen; /* generation (cached) */
|
||||||
uint64_t z_size; /* file size (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_links; /* file links (cached) */
|
||||||
uint64_t z_pflags; /* pflags (cached) */
|
uint64_t z_pflags; /* pflags (cached) */
|
||||||
uint64_t z_uid; /* uid fuid (cached) */
|
uint64_t z_uid; /* uid fuid (cached) */
|
||||||
|
@ -209,17 +208,21 @@ typedef struct znode {
|
||||||
zfs_acl_t *z_acl_cached; /* cached acl */
|
zfs_acl_t *z_acl_cached; /* cached acl */
|
||||||
krwlock_t z_xattr_lock; /* xattr data lock */
|
krwlock_t z_xattr_lock; /* xattr data lock */
|
||||||
nvlist_t *z_xattr_cached; /* cached xattrs */
|
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 */
|
list_node_t z_link_node; /* all znodes in fs link */
|
||||||
sa_handle_t *z_sa_hdl; /* handle to sa data */
|
sa_handle_t *z_sa_hdl; /* handle to sa data */
|
||||||
boolean_t z_is_sa; /* are we native sa? */
|
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_mapped; /* are we mmap'ed */
|
||||||
boolean_t z_is_ctldir; /* are we .zfs entry */
|
boolean_t z_is_ctldir; /* are we .zfs entry */
|
||||||
boolean_t z_is_stale; /* are we stale due to rollback? */
|
boolean_t z_is_stale; /* are we stale due to rollback? */
|
||||||
struct inode z_inode; /* generic vfs inode */
|
struct inode z_inode; /* generic vfs inode */
|
||||||
} znode_t;
|
} 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
|
* Range locking rules
|
||||||
|
@ -273,17 +276,11 @@ typedef struct znode {
|
||||||
/*
|
/*
|
||||||
* Macros for dealing with dmu_buf_hold
|
* Macros for dealing with dmu_buf_hold
|
||||||
*/
|
*/
|
||||||
#define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1))
|
#define ZFS_OBJ_MTX_SZ 64
|
||||||
#define ZFS_OBJ_MUTEX(zsb, obj_num) \
|
#define ZFS_OBJ_MTX_MAX (1024 * 1024)
|
||||||
(&(zsb)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)])
|
#define ZFS_OBJ_HASH(zsb, obj) ((obj) & ((zsb->z_hold_size) - 1))
|
||||||
#define ZFS_OBJ_HOLD_ENTER(zsb, obj_num) \
|
|
||||||
mutex_enter(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
extern unsigned int zfs_object_mutex_size;
|
||||||
#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)))
|
|
||||||
|
|
||||||
/* Encode ZFS stored time values from a struct timespec */
|
/* Encode ZFS stored time values from a struct timespec */
|
||||||
#define ZFS_TIME_ENCODE(tp, stmp) \
|
#define ZFS_TIME_ENCODE(tp, stmp) \
|
||||||
|
@ -306,20 +303,17 @@ typedef struct znode {
|
||||||
#define STATE_CHANGED (ATTR_CTIME)
|
#define STATE_CHANGED (ATTR_CTIME)
|
||||||
#define CONTENT_MODIFIED (ATTR_MTIME | 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 int zfs_init_fs(zfs_sb_t *, znode_t **);
|
||||||
extern void zfs_set_dataprop(objset_t *);
|
extern void zfs_set_dataprop(objset_t *);
|
||||||
extern void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *,
|
extern void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *,
|
||||||
dmu_tx_t *tx);
|
dmu_tx_t *tx);
|
||||||
extern void zfs_tstamp_update_setup(znode_t *, uint_t, uint64_t [2],
|
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 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 int zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t);
|
||||||
extern void zfs_znode_init(void);
|
extern void zfs_znode_init(void);
|
||||||
extern void zfs_znode_fini(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_zget(zfs_sb_t *, uint64_t, znode_t **);
|
||||||
extern int zfs_rezget(znode_t *);
|
extern int zfs_rezget(znode_t *);
|
||||||
extern void zfs_zinactive(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_buf_free(void *buf, size_t size);
|
||||||
extern void *zio_data_buf_alloc(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_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 *);
|
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,
|
extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip,
|
||||||
const struct qstr *qstr);
|
const struct qstr *qstr);
|
||||||
#if defined(CONFIG_FS_POSIX_ACL)
|
#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);
|
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
|
||||||
#if !defined(HAVE_GET_ACL)
|
#if !defined(HAVE_GET_ACL)
|
||||||
#if defined(HAVE_CHECK_ACL_WITH_FLAGS)
|
#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 file_operations zpl_fops_shares;
|
||||||
extern const struct inode_operations zpl_ops_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) { \
|
#define DIR_CONTEXT_INIT(_dirent, _actor, _pos) { \
|
||||||
.actor = _actor, \
|
.actor = _actor, \
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_ZVOL_H
|
#ifndef _SYS_ZVOL_H
|
||||||
|
@ -31,24 +32,22 @@
|
||||||
#define ZVOL_OBJ 1ULL
|
#define ZVOL_OBJ 1ULL
|
||||||
#define ZVOL_ZAP_OBJ 2ULL
|
#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_volsize(uint64_t volsize, uint64_t blocksize);
|
||||||
extern int zvol_check_volblocksize(const char *name, uint64_t volblocksize);
|
extern int zvol_check_volblocksize(const char *name, uint64_t volblocksize);
|
||||||
extern int zvol_get_stats(objset_t *os, nvlist_t *nv);
|
extern int zvol_get_stats(objset_t *os, nvlist_t *nv);
|
||||||
extern boolean_t zvol_is_zvol(const char *);
|
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 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_volsize(const char *, uint64_t);
|
||||||
extern int zvol_set_volblocksize(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 int zvol_init(void);
|
||||||
extern void zvol_fini(void);
|
extern void zvol_fini(void);
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
#endif /* _SYS_ZVOL_H */
|
#endif /* _SYS_ZVOL_H */
|
||||||
|
|
|
@ -88,7 +88,7 @@ struct dk_map2 default_vtoc_map[NDKMAP] = {
|
||||||
#if defined(_SUNOS_VTOC_16)
|
#if defined(_SUNOS_VTOC_16)
|
||||||
|
|
||||||
#if defined(i386) || defined(__amd64) || defined(__arm) || \
|
#if defined(i386) || defined(__amd64) || defined(__arm) || \
|
||||||
defined(__powerpc) || defined(__sparc)
|
defined(__powerpc) || defined(__sparc) || defined(__s390__)
|
||||||
{ V_BOOT, V_UNMNT }, /* i - 8 */
|
{ V_BOOT, V_UNMNT }, /* i - 8 */
|
||||||
{ V_ALTSCTR, 0 }, /* j - 9 */
|
{ V_ALTSCTR, 0 }, /* j - 9 */
|
||||||
|
|
||||||
|
|
|
@ -507,7 +507,7 @@
|
||||||
movl 16(%esp), %ebx
|
movl 16(%esp), %ebx
|
||||||
movl 20(%esp), %ecx
|
movl 20(%esp), %ecx
|
||||||
subl %eax, %ebx
|
subl %eax, %ebx
|
||||||
adcl %edx, %ecx
|
sbbl %edx, %ecx
|
||||||
lock
|
lock
|
||||||
cmpxchg8b (%edi)
|
cmpxchg8b (%edi)
|
||||||
jne 1b
|
jne 1b
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <sys/mnttab.h>
|
#include <sys/mnttab.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/sysmacros.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
|
@ -31,69 +31,66 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.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);
|
|
||||||
|
|
||||||
static inline int
|
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);
|
fprintf(stderr, "%s\n", buf);
|
||||||
return (0);
|
fprintf(stderr, "ASSERT at %s:%d:%s()", file, line, func);
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BEGIN CSTYLED */
|
/* printf version of libspl_assert */
|
||||||
#define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE) do { \
|
static inline void
|
||||||
const TYPE __left = (TYPE)(LEFT); \
|
libspl_assertf(const char *file, const char *func, int line, char *format, ...)
|
||||||
const TYPE __right = (TYPE)(RIGHT); \
|
{
|
||||||
if (!(__left OP __right)) { \
|
va_list args;
|
||||||
char *__buf = alloca(256); \
|
|
||||||
(void) snprintf(__buf, 256, "%s %s %s (0x%llx %s 0x%llx)", \
|
va_start(args, format);
|
||||||
#LEFT, #OP, #RIGHT, \
|
vfprintf(stderr, format, args);
|
||||||
(u_longlong_t)__left, #OP, (u_longlong_t)__right); \
|
fprintf(stderr, "\n");
|
||||||
assfail(__buf, __FILE__, __LINE__); \
|
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)
|
} while (0)
|
||||||
/* END CSTYLED */
|
|
||||||
|
|
||||||
#define VERIFY3S(x, y, z) VERIFY3_IMPL(x, y, z, int64_t)
|
#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 VERIFY3U(x, y, z) VERIFY3_IMPL(x, y, z, uint64_t)
|
||||||
#define VERIFY3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t)
|
#define VERIFY3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t)
|
||||||
#define VERIFY0(x) VERIFY3_IMPL(x, ==, 0, uint64_t)
|
#define VERIFY0(x) VERIFY3_IMPL(x, ==, 0, uint64_t)
|
||||||
|
|
||||||
|
#ifdef assert
|
||||||
|
#undef assert
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define ASSERT3S(x, y, z) ((void)0)
|
#define ASSERT3S(x, y, z) ((void)0)
|
||||||
#define ASSERT3U(x, y, z) ((void)0)
|
#define ASSERT3U(x, y, z) ((void)0)
|
||||||
#define ASSERT3P(x, y, z) ((void)0)
|
#define ASSERT3P(x, y, z) ((void)0)
|
||||||
#define ASSERT0(x) ((void)0)
|
#define ASSERT0(x) ((void)0)
|
||||||
|
#define ASSERT(x) ((void)0)
|
||||||
|
#define assert(x) ((void)0)
|
||||||
#define ASSERTV(x)
|
#define ASSERTV(x)
|
||||||
#define IMPLY(A, B) ((void)0)
|
#define IMPLY(A, B) ((void)0)
|
||||||
#define EQUIV(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 ASSERT3U(x, y, z) VERIFY3U(x, y, z)
|
||||||
#define ASSERT3P(x, y, z) VERIFY3P(x, y, z)
|
#define ASSERT3P(x, y, z) VERIFY3P(x, y, z)
|
||||||
#define ASSERT0(x) VERIFY0(x)
|
#define ASSERT0(x) VERIFY0(x)
|
||||||
|
#define ASSERT(x) VERIFY(x)
|
||||||
|
#define assert(x) VERIFY(x)
|
||||||
#define ASSERTV(x) x
|
#define ASSERTV(x) x
|
||||||
#define IMPLY(A, B) \
|
#define IMPLY(A, B) \
|
||||||
((void)(((!(A)) || (B)) || \
|
((void)(((!(A)) || (B)) || \
|
||||||
assfail("(" #A ") implies (" #B ")", __FILE__, __LINE__)))
|
libspl_assert("(" #A ") implies (" #B ")", \
|
||||||
|
__FILE__, __FUNCTION__, __LINE__)))
|
||||||
#define EQUIV(A, B) \
|
#define EQUIV(A, B) \
|
||||||
((void)((!!(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 */
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ extern "C" {
|
||||||
#define _SUNOS_VTOC_16
|
#define _SUNOS_VTOC_16
|
||||||
|
|
||||||
/* powerpc arch specific defines */
|
/* powerpc arch specific defines */
|
||||||
#elif defined(__powerpc) || defined(__powerpc__)
|
#elif defined(__powerpc) || defined(__powerpc__) || defined(__powerpc64__)
|
||||||
|
|
||||||
#if !defined(__powerpc)
|
#if !defined(__powerpc)
|
||||||
#define __powerpc
|
#define __powerpc
|
||||||
|
@ -88,11 +88,13 @@ extern "C" {
|
||||||
#define __powerpc__
|
#define __powerpc__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__powerpc64__)
|
||||||
#if !defined(_LP64)
|
#if !defined(_LP64)
|
||||||
#ifdef __powerpc64__
|
|
||||||
#define _LP64
|
#define _LP64
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#define _LP32
|
#if !defined(_ILP32)
|
||||||
|
#define _ILP32
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -113,6 +115,16 @@ extern "C" {
|
||||||
#define __arm__
|
#define __arm__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
#if !defined(_LP64)
|
||||||
|
#define _LP64
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if !defined(_ILP32)
|
||||||
|
#define _ILP32
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__ARMEL__) || defined(__AARCH64EL__)
|
#if defined(__ARMEL__) || defined(__AARCH64EL__)
|
||||||
#define _LITTLE_ENDIAN
|
#define _LITTLE_ENDIAN
|
||||||
#else
|
#else
|
||||||
|
@ -122,7 +134,7 @@ extern "C" {
|
||||||
#define _SUNOS_VTOC_16
|
#define _SUNOS_VTOC_16
|
||||||
|
|
||||||
/* sparc arch specific defines */
|
/* sparc arch specific defines */
|
||||||
#elif defined(__sparc) || defined(__sparc__)
|
#elif defined(__sparc) || defined(__sparc__) || defined(__sparc64__)
|
||||||
|
|
||||||
#if !defined(__sparc)
|
#if !defined(__sparc)
|
||||||
#define __sparc
|
#define __sparc
|
||||||
|
@ -135,21 +147,32 @@ extern "C" {
|
||||||
#define _BIG_ENDIAN
|
#define _BIG_ENDIAN
|
||||||
#define _SUNOS_VTOC_16
|
#define _SUNOS_VTOC_16
|
||||||
|
|
||||||
/* sparc64 arch specific defines */
|
#if defined(__sparc64__)
|
||||||
#elif defined(__sparc64) || defined(__sparc64__)
|
#if !defined(_LP64)
|
||||||
|
#define _LP64
|
||||||
#if !defined(__sparc64)
|
#endif
|
||||||
#define __sparc64
|
#else
|
||||||
|
#if !defined(_ILP32)
|
||||||
|
#define _ILP32
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(__sparc64__)
|
/* s390 arch specific defines */
|
||||||
#define __sparc64__
|
#elif defined(__s390__)
|
||||||
|
#if defined(__s390x__)
|
||||||
|
#if !defined(_LP64)
|
||||||
|
#define _LP64
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if !defined(_ILP32)
|
||||||
|
#define _ILP32
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _BIG_ENDIAN
|
#define _BIG_ENDIAN
|
||||||
#define _SUNOS_VTOC_16
|
#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"
|
#error "Unsupported ISA type"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -157,6 +180,10 @@ extern "C" {
|
||||||
#error "Both _ILP32 and _LP64 are defined"
|
#error "Both _ILP32 and _LP64 are defined"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_ILP32) && !defined(_LP64)
|
||||||
|
#error "Neither _ILP32 or _LP64 are defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
|
#if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
|
||||||
#error "Both _LITTLE_ENDIAN and _BIG_ENDIAN are defined"
|
#error "Both _LITTLE_ENDIAN and _BIG_ENDIAN are defined"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,16 +42,13 @@
|
||||||
|
|
||||||
#define makedevice(maj, min) makedev(maj, min)
|
#define makedevice(maj, min) makedev(maj, min)
|
||||||
#define _sysconf(a) sysconf(a)
|
#define _sysconf(a) sysconf(a)
|
||||||
#define __NORETURN __attribute__((noreturn))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compatibility macros/typedefs needed for Solaris -> Linux port
|
* Compatibility macros/typedefs needed for Solaris -> Linux port
|
||||||
*/
|
*/
|
||||||
#define P2ALIGN(x, align) ((x) & -(align))
|
#define P2ALIGN(x, align) ((x) & -(align))
|
||||||
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
|
#define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1)
|
||||||
#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
|
#define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1)
|
||||||
#define P2ROUNDUP_TYPED(x, align, type) \
|
|
||||||
(-(-(type)(x) & -(type)(align)))
|
|
||||||
#define P2BOUNDARY(off, len, align) \
|
#define P2BOUNDARY(off, len, align) \
|
||||||
(((off) ^ ((off) + (len) - 1)) > (align) - 1)
|
(((off) ^ ((off) + (len) - 1)) > (align) - 1)
|
||||||
#define P2PHASE(x, align) ((x) & ((align) - 1))
|
#define P2PHASE(x, align) ((x) & ((align) - 1))
|
||||||
|
@ -79,7 +76,7 @@
|
||||||
#define P2NPHASE_TYPED(x, align, type) \
|
#define P2NPHASE_TYPED(x, align, type) \
|
||||||
(-(type)(x) & ((type)(align) - 1))
|
(-(type)(x) & ((type)(align) - 1))
|
||||||
#define P2ROUNDUP_TYPED(x, align, type) \
|
#define P2ROUNDUP_TYPED(x, align, type) \
|
||||||
(-(-(type)(x) & -(type)(align)))
|
((((type)(x) - 1) | ((type)(align) - 1)) + 1)
|
||||||
#define P2END_TYPED(x, align, type) \
|
#define P2END_TYPED(x, align, type) \
|
||||||
(-(~(type)(x) & -(type)(align)))
|
(-(~(type)(x) & -(type)(align)))
|
||||||
#define P2PHASEUP_TYPED(x, align, phase, type) \
|
#define P2PHASEUP_TYPED(x, align, phase, type) \
|
||||||
|
|
|
@ -27,10 +27,15 @@
|
||||||
#ifndef _LIBSPL_SYS_TYPES_H
|
#ifndef _LIBSPL_SYS_TYPES_H
|
||||||
#define _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/isa_defs.h>
|
||||||
#include <sys/feature_tests.h>
|
#include <sys/feature_tests.h>
|
||||||
#include_next <sys/types.h>
|
#include_next <sys/types.h>
|
||||||
#include <sys/param.h> /* for NBBY */
|
|
||||||
#include <sys/types32.h>
|
#include <sys/types32.h>
|
||||||
#include <sys/va_list.h>
|
#include <sys/va_list.h>
|
||||||
|
|
||||||
|
@ -53,7 +58,6 @@ typedef u_longlong_t u_offset_t;
|
||||||
typedef u_longlong_t len_t;
|
typedef u_longlong_t len_t;
|
||||||
typedef longlong_t diskaddr_t;
|
typedef longlong_t diskaddr_t;
|
||||||
|
|
||||||
typedef ulong_t pfn_t; /* page frame number */
|
|
||||||
typedef ulong_t pgcnt_t; /* number of pages */
|
typedef ulong_t pgcnt_t; /* number of pages */
|
||||||
typedef long spgcnt_t; /* signed number of pages */
|
typedef long spgcnt_t; /* signed number of pages */
|
||||||
|
|
||||||
|
@ -96,4 +100,6 @@ typedef union {
|
||||||
} lloff_t;
|
} lloff_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sys/param.h> /* for NBBY */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3315,8 +3315,9 @@ zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
|
||||||
char name[ZFS_MAXNAMELEN];
|
char name[ZFS_MAXNAMELEN];
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
(void) snprintf(name, sizeof (name),
|
if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
|
||||||
"%s@%s", zhp->zfs_name, dd->snapname);
|
dd->snapname) >= sizeof (name))
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
if (lzc_exists(name))
|
if (lzc_exists(name))
|
||||||
verify(nvlist_add_boolean(dd->nvl, name) == 0);
|
verify(nvlist_add_boolean(dd->nvl, name) == 0);
|
||||||
|
@ -3534,8 +3535,9 @@ zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
|
if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
|
||||||
(void) snprintf(name, sizeof (name),
|
if (snprintf(name, sizeof (name), "%s@%s", zfs_get_name(zhp),
|
||||||
"%s@%s", zfs_get_name(zhp), sd->sd_snapname);
|
sd->sd_snapname) >= sizeof (name))
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
fnvlist_add_boolean(sd->sd_nvl, name);
|
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) {
|
if (recursive) {
|
||||||
|
|
||||||
parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
|
parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
|
||||||
if (parentname == NULL) {
|
if (parentname == NULL) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -3902,8 +3903,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
} else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
|
||||||
} else {
|
|
||||||
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0,
|
if ((cl = changelist_gather(zhp, ZFS_PROP_NAME, 0,
|
||||||
force_unmount ? MS_FORCE : 0)) == NULL)
|
force_unmount ? MS_FORCE : 0)) == NULL)
|
||||||
return (-1);
|
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
|
* On failure, we still want to remount any filesystems that
|
||||||
* were previously mounted, so we don't alter the system state.
|
* were previously mounted, so we don't alter the system state.
|
||||||
*/
|
*/
|
||||||
if (!recursive)
|
if (cl != NULL)
|
||||||
(void) changelist_postfix(cl);
|
(void) changelist_postfix(cl);
|
||||||
} else {
|
} else {
|
||||||
if (!recursive) {
|
if (cl != NULL) {
|
||||||
changelist_rename(cl, zfs_get_name(zhp), target);
|
changelist_rename(cl, zfs_get_name(zhp), target);
|
||||||
ret = changelist_postfix(cl);
|
ret = changelist_postfix(cl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (parentname) {
|
if (parentname != NULL) {
|
||||||
free(parentname);
|
free(parentname);
|
||||||
}
|
}
|
||||||
if (zhrp) {
|
if (zhrp != NULL) {
|
||||||
zfs_close(zhrp);
|
zfs_close(zhrp);
|
||||||
}
|
}
|
||||||
if (cl) {
|
if (cl != NULL) {
|
||||||
changelist_free(cl);
|
changelist_free(cl);
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -4259,8 +4259,9 @@ zfs_hold_one(zfs_handle_t *zhp, void *arg)
|
||||||
char name[ZFS_MAXNAMELEN];
|
char name[ZFS_MAXNAMELEN];
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
(void) snprintf(name, sizeof (name),
|
if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
|
||||||
"%s@%s", zhp->zfs_name, ha->snapname);
|
ha->snapname) >= sizeof (name))
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
if (lzc_exists(name))
|
if (lzc_exists(name))
|
||||||
fnvlist_add_string(ha->nvl, name, ha->tag);
|
fnvlist_add_string(ha->nvl, name, ha->tag);
|
||||||
|
@ -4379,8 +4380,11 @@ zfs_release_one(zfs_handle_t *zhp, void *arg)
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
nvlist_t *existing_holds;
|
nvlist_t *existing_holds;
|
||||||
|
|
||||||
(void) snprintf(name, sizeof (name),
|
if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
|
||||||
"%s@%s", zhp->zfs_name, ha->snapname);
|
ha->snapname) >= sizeof (name)) {
|
||||||
|
ha->error = EINVAL;
|
||||||
|
rv = EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (lzc_get_holds(name, &existing_holds) != 0) {
|
if (lzc_get_holds(name, &existing_holds) != 0) {
|
||||||
ha->error = ENOENT;
|
ha->error = ENOENT;
|
||||||
|
|
|
@ -97,6 +97,8 @@ typedef struct pool_list {
|
||||||
name_entry_t *names;
|
name_entry_t *names;
|
||||||
} pool_list_t;
|
} pool_list_t;
|
||||||
|
|
||||||
|
#define DEV_BYID_PATH "/dev/disk/by-id/"
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
get_devid(const char *path)
|
get_devid(const char *path)
|
||||||
{
|
{
|
||||||
|
@ -121,6 +123,40 @@ get_devid(const char *path)
|
||||||
return (ret);
|
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
|
* 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;
|
best = NULL;
|
||||||
for (ne = names; ne != NULL; ne = ne->ne_next) {
|
for (ne = names; ne != NULL; ne = ne->ne_next) {
|
||||||
if (ne->ne_guid == guid) {
|
if (ne->ne_guid == guid) {
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
best = ne;
|
best = ne;
|
||||||
break;
|
break;
|
||||||
|
@ -186,7 +221,7 @@ fix_paths(nvlist_t *nv, name_entry_t *names)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prefer paths earlier in the search order. */
|
/* 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) {
|
ne->ne_order < best->ne_order) {
|
||||||
best = ne;
|
best = ne;
|
||||||
continue;
|
continue;
|
||||||
|
@ -352,6 +387,118 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
|
||||||
return (0);
|
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.
|
* 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_cache cache;
|
||||||
blkid_dev_iterate iter;
|
blkid_dev_iterate iter;
|
||||||
blkid_dev dev;
|
blkid_dev dev;
|
||||||
const char *devname;
|
int err;
|
||||||
nvlist_t *config;
|
|
||||||
int fd, err, num_labels;
|
|
||||||
|
|
||||||
err = blkid_get_cache(&cache, NULL);
|
err = blkid_get_cache(&cache, NULL);
|
||||||
if (err != 0) {
|
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) {
|
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)
|
if ((fd = open64(devname, O_RDONLY)) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
err = zpool_read_label(fd, &config, &num_labels);
|
err = zpool_read_label(fd, &label, &num_labels);
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
|
|
||||||
if (err != 0) {
|
if (err || label == NULL)
|
||||||
(void) no_memory(hdl);
|
continue;
|
||||||
goto err_blkid3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config != NULL) {
|
add_configs_from_label(hdl, pools, devname, num_labels, label);
|
||||||
err = add_config(hdl, pools, devname, 0,
|
|
||||||
num_labels, config);
|
|
||||||
if (err != 0)
|
|
||||||
goto err_blkid3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
err = 0;
|
||||||
|
|
||||||
err_blkid3:
|
err_blkid3:
|
||||||
blkid_dev_iterate_end(iter);
|
blkid_dev_iterate_end(iter);
|
||||||
|
@ -1194,16 +1337,33 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg)
|
||||||
|
|
||||||
if (config != NULL) {
|
if (config != NULL) {
|
||||||
boolean_t matched = B_TRUE;
|
boolean_t matched = B_TRUE;
|
||||||
|
boolean_t aux = B_FALSE;
|
||||||
char *pname;
|
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,
|
(nvlist_lookup_string(config,
|
||||||
ZPOOL_CONFIG_POOL_NAME, &pname) == 0)) {
|
ZPOOL_CONFIG_POOL_NAME, &pname) == 0)) {
|
||||||
|
|
||||||
if (strcmp(iarg->poolname, pname))
|
if (strcmp(iarg->poolname, pname))
|
||||||
matched = B_FALSE;
|
matched = B_FALSE;
|
||||||
|
|
||||||
} else if (iarg->guid != 0) {
|
} else if (iarg->guid != 0 && !aux) {
|
||||||
uint64_t this_guid;
|
uint64_t this_guid;
|
||||||
|
|
||||||
matched = nvlist_lookup_uint64(config,
|
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_name = nvpair_name(pair);
|
||||||
bmark_props = fnvpair_value_nvlist(pair);
|
bmark_props = fnvpair_value_nvlist(pair);
|
||||||
|
|
||||||
(void) snprintf(name, sizeof (name), "%s#%s", zhp->zfs_name,
|
if (snprintf(name, sizeof (name), "%s#%s", zhp->zfs_name,
|
||||||
bmark_name);
|
bmark_name) >= sizeof (name)) {
|
||||||
|
err = EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
nzhp = make_bookmark_handle(zhp, name, bmark_props);
|
nzhp = make_bookmark_handle(zhp, name, bmark_props);
|
||||||
if (nzhp == NULL)
|
if (nzhp == NULL)
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* 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,
|
error = zfs_add_option(zhp, options, len,
|
||||||
ZFS_PROP_ATIME, MNTOPT_ATIME, MNTOPT_NOATIME);
|
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,
|
error = error ? error : zfs_add_option(zhp, options, len,
|
||||||
ZFS_PROP_DEVICES, MNTOPT_DEVICES, MNTOPT_NODEVICES);
|
ZFS_PROP_DEVICES, MNTOPT_DEVICES, MNTOPT_NODEVICES);
|
||||||
error = error ? error : zfs_add_option(zhp, options, len,
|
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))
|
if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
|
||||||
return (0);
|
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++) {
|
for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
|
||||||
/*
|
/*
|
||||||
* Return success if there are no share options.
|
* 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)
|
strcmp(shareopts, "off") == 0)
|
||||||
continue;
|
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()
|
* If the 'zoned' property is set, then zfs_is_mountable()
|
||||||
* will have already bailed out if we are in the global zone.
|
* 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)
|
if (gotb)
|
||||||
return (1);
|
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,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
"device '%s' contains an EFI label and "
|
"device '%s' contains an EFI label and "
|
||||||
"cannot be used on root pools."),
|
"cannot be used on root pools."),
|
||||||
zpool_vdev_name(hdl, NULL, spares[s],
|
zpool_vdev_name(hdl, NULL, spares[s], 0));
|
||||||
B_FALSE));
|
|
||||||
return (zfs_error(hdl, EZFS_POOL_NOTSUP, msg));
|
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;
|
return;
|
||||||
|
|
||||||
for (c = 0; c < children; c++) {
|
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);
|
print_vdev_tree(hdl, vname, child[c], indent + 2);
|
||||||
free(vname);
|
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"));
|
"one or more devices are already in use\n"));
|
||||||
(void) zfs_error(hdl, EZFS_BADDEV, desc);
|
(void) zfs_error(hdl, EZFS_BADDEV, desc);
|
||||||
break;
|
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:
|
default:
|
||||||
(void) zpool_standard_error(hdl, error, desc);
|
(void) zpool_standard_error(hdl, error, desc);
|
||||||
zpool_explain_recover(hdl,
|
zpool_explain_recover(hdl,
|
||||||
|
@ -2688,7 +2692,7 @@ zpool_vdev_attach(zpool_handle_t *zhp,
|
||||||
verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
|
verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
|
||||||
ZPOOL_CONFIG_VDEV_TREE, &config_root) == 0);
|
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);
|
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++) {
|
for (mc = 0; mc < mchildren; mc++) {
|
||||||
uint_t sc;
|
uint_t sc;
|
||||||
char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
|
char *mpath = zpool_vdev_name(zhp->zpool_hdl, zhp,
|
||||||
mchild[mc], B_FALSE);
|
mchild[mc], 0);
|
||||||
|
|
||||||
for (sc = 0; sc < schildren; sc++) {
|
for (sc = 0; sc < schildren; sc++) {
|
||||||
char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
|
char *spath = zpool_vdev_name(zhp->zpool_hdl, zhp,
|
||||||
schild[sc], B_FALSE);
|
schild[sc], 0);
|
||||||
boolean_t result = (strcmp(mpath, spath) == 0);
|
boolean_t result = (strcmp(mpath, spath) == 0);
|
||||||
|
|
||||||
free(spath);
|
free(spath);
|
||||||
|
@ -3424,21 +3428,34 @@ strip_partition(libzfs_handle_t *hdl, char *path)
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
|
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;
|
uint64_t value;
|
||||||
char buf[PATH_BUF_LEN];
|
char buf[PATH_BUF_LEN];
|
||||||
char tmpbuf[PATH_BUF_LEN];
|
char tmpbuf[PATH_BUF_LEN];
|
||||||
vdev_stat_t *vs;
|
vdev_stat_t *vs;
|
||||||
uint_t vsc;
|
uint_t vsc;
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NOT_PRESENT,
|
env = getenv("ZPOOL_VDEV_NAME_PATH");
|
||||||
&value) == 0) {
|
if (env && (strtoul(env, NULL, 0) > 0 ||
|
||||||
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
|
!strncasecmp(env, "YES", 3) || !strncasecmp(env, "ON", 2)))
|
||||||
&value) == 0);
|
name_flags |= VDEV_NAME_PATH;
|
||||||
(void) snprintf(buf, sizeof (buf), "%llu",
|
|
||||||
(u_longlong_t)value);
|
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;
|
path = buf;
|
||||||
} else if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) == 0) {
|
} 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);
|
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.
|
* For a block device only use the name.
|
||||||
*/
|
*/
|
||||||
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
|
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 = strrchr(path, '/');
|
||||||
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.
|
* Remove the partition from the path it this is a whole disk.
|
||||||
*/
|
*/
|
||||||
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK,
|
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_WHOLE_DISK, &value)
|
||||||
&value) == 0 && value) {
|
== 0 && value && !(name_flags & VDEV_NAME_PATH)) {
|
||||||
return (strip_partition(hdl, path));
|
return (strip_partition(hdl, path));
|
||||||
}
|
}
|
||||||
} else {
|
} 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>
|
* We identify each top-level vdev by using a <type-id>
|
||||||
* naming convention.
|
* naming convention.
|
||||||
*/
|
*/
|
||||||
if (verbose) {
|
if (name_flags & VDEV_NAME_TYPE_ID) {
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
|
|
||||||
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
|
verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ID,
|
||||||
|
@ -4072,29 +4099,6 @@ find_start_block(nvlist_t *config)
|
||||||
return (MAXOFFSET_T);
|
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
|
int
|
||||||
zpool_label_disk_check(char *path)
|
zpool_label_disk_check(char *path)
|
||||||
{
|
{
|
||||||
|
@ -4120,6 +4124,32 @@ zpool_label_disk_check(char *path)
|
||||||
return (0);
|
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,
|
* Label an individual disk. The name provided is the short name,
|
||||||
* stripped of any leading /dev path.
|
* 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.
|
* can get, in the absence of V_OTHER.
|
||||||
*/
|
*/
|
||||||
vtoc->efi_parts[0].p_tag = V_USR;
|
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_start = slice_size + start_block;
|
||||||
vtoc->efi_parts[8].p_size = resv;
|
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);
|
(void) close(fd);
|
||||||
efi_free(vtoc);
|
efi_free(vtoc);
|
||||||
|
|
||||||
/* Wait for the first expected partition to appear. */
|
|
||||||
|
|
||||||
(void) snprintf(path, sizeof (path), "%s/%s", DISK_ROOT, name);
|
(void) snprintf(path, sizeof (path), "%s/%s", DISK_ROOT, name);
|
||||||
(void) zfs_append_partition(path, MAXPATHLEN);
|
(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) {
|
if (rval) {
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to "
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "failed to "
|
||||||
"detect device partitions on '%s': %d"), path, rval);
|
"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);
|
drr_versioninfo, DMU_COMPOUNDSTREAM);
|
||||||
DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
|
DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
|
||||||
drr_versioninfo, featureflags);
|
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),
|
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;
|
drr.drr_payloadlen = buflen;
|
||||||
err = cksum_and_write(&drr, sizeof (drr), &zc, outfd);
|
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)
|
uint64_t guid1, uint64_t guid2)
|
||||||
{
|
{
|
||||||
nvlist_t *nvfs;
|
nvlist_t *nvfs;
|
||||||
char *fsname, *snapname;
|
char *fsname = NULL, *snapname = NULL;
|
||||||
char buf[ZFS_MAXNAMELEN];
|
char buf[ZFS_MAXNAMELEN];
|
||||||
int rv;
|
int rv;
|
||||||
zfs_handle_t *guid1hdl, *guid2hdl;
|
zfs_handle_t *guid1hdl, *guid2hdl;
|
||||||
|
@ -2689,7 +2693,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||||
ENOENT);
|
ENOENT);
|
||||||
|
|
||||||
if (stream_avl != NULL) {
|
if (stream_avl != NULL) {
|
||||||
char *snapname;
|
char *snapname = NULL;
|
||||||
|
nvlist_t *lookup = NULL;
|
||||||
nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
|
nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
|
||||||
&snapname);
|
&snapname);
|
||||||
nvlist_t *props;
|
nvlist_t *props;
|
||||||
|
@ -2710,6 +2715,11 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
|
||||||
nvlist_free(props);
|
nvlist_free(props);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
|
if (0 == nvlist_lookup_nvlist(fs, "snapprops", &lookup)) {
|
||||||
|
VERIFY(0 == nvlist_lookup_nvlist(lookup,
|
||||||
|
snapname, &snapprops_nvlist));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cp = NULL;
|
cp = NULL;
|
||||||
|
|
|
@ -1024,16 +1024,18 @@ zfs_strcmp_pathname(char *name, char *cmp, int wholedisk)
|
||||||
int path_len, cmp_len;
|
int path_len, cmp_len;
|
||||||
char path_name[MAXPATHLEN];
|
char path_name[MAXPATHLEN];
|
||||||
char cmp_name[MAXPATHLEN];
|
char cmp_name[MAXPATHLEN];
|
||||||
char *dir;
|
char *dir, *dup;
|
||||||
|
|
||||||
/* Strip redundant slashes if one exists due to ZPOOL_IMPORT_PATH */
|
/* Strip redundant slashes if one exists due to ZPOOL_IMPORT_PATH */
|
||||||
memset(cmp_name, 0, MAXPATHLEN);
|
memset(cmp_name, 0, MAXPATHLEN);
|
||||||
dir = strtok(cmp, "/");
|
dup = strdup(cmp);
|
||||||
|
dir = strtok(dup, "/");
|
||||||
while (dir) {
|
while (dir) {
|
||||||
strcat(cmp_name, "/");
|
strcat(cmp_name, "/");
|
||||||
strcat(cmp_name, dir);
|
strcat(cmp_name, dir);
|
||||||
dir = strtok(NULL, "/");
|
dir = strtok(NULL, "/");
|
||||||
}
|
}
|
||||||
|
free(dup);
|
||||||
|
|
||||||
if (name[0] != '/')
|
if (name[0] != '/')
|
||||||
return (zfs_strcmp_shortname(name, cmp_name, wholedisk));
|
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;
|
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);
|
(void) printf("%s", str);
|
||||||
else if (cbp->cb_scripted)
|
else if (cbp->cb_scripted)
|
||||||
(void) printf("%s\t", str);
|
(void) printf("%s\t", str);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -1322,3 +1323,24 @@ spl_fstrans_check(void)
|
||||||
{
|
{
|
||||||
return (0);
|
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
|
.sp
|
||||||
.LP
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.na
|
.na
|
||||||
|
@ -870,7 +883,12 @@ Default value: \fB10\fR.
|
||||||
Minimum asynchronous write I/Os active to each device.
|
Minimum asynchronous write I/Os active to each device.
|
||||||
See the section "ZFS I/O SCHEDULER".
|
See the section "ZFS I/O SCHEDULER".
|
||||||
.sp
|
.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
|
.RE
|
||||||
|
|
||||||
.sp
|
.sp
|
||||||
|
@ -1598,6 +1616,23 @@ Prioritize requeued I/O
|
||||||
Default value: \fB0\fR.
|
Default value: \fB0\fR.
|
||||||
.RE
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.na
|
.na
|
||||||
|
|
201
man/man8/zpool.8
201
man/man8/zpool.8
|
@ -26,7 +26,7 @@ zpool \- configures ZFS storage pools
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
.nf
|
.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
|
.fi
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
|
@ -94,7 +94,7 @@ zpool \- configures ZFS storage pools
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
.nf
|
.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
|
.fi
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
|
@ -104,7 +104,7 @@ zpool \- configures ZFS storage pools
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
.nf
|
.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]]
|
[\fIinterval\fR[\fIcount\fR]]
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
@ -150,12 +150,12 @@ zpool \- configures ZFS storage pools
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
.nf
|
.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
|
.fi
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
.nf
|
.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
|
.fi
|
||||||
|
|
||||||
.LP
|
.LP
|
||||||
|
@ -836,7 +836,7 @@ Displays a help message.
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.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
|
.ad
|
||||||
.sp .6
|
.sp .6
|
||||||
.RS 4n
|
.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.
|
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
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.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.
|
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
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
|
@ -1608,7 +1641,7 @@ Allows a pool to import when there is a missing log device.
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.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
|
.ad
|
||||||
.sp .6
|
.sp .6
|
||||||
.RS 4n
|
.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).
|
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
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
|
@ -1676,7 +1742,7 @@ Treat exported or foreign devices as inactive.
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.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
|
.ad
|
||||||
.sp .6
|
.sp .6
|
||||||
.RS 4n
|
.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.
|
Scripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space.
|
||||||
.RE
|
.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
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.na
|
||||||
|
@ -1886,7 +1985,7 @@ Sets the given property on the specified pool. See the "Properties" section for
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.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
|
.ad
|
||||||
.sp .6
|
.sp .6
|
||||||
.RS 4n
|
.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.
|
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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.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.
|
Do dry run, do not actually perform the split. Print out the expected configuration of \fInewpool\fR.
|
||||||
.RE
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
|
@ -1933,22 +2065,45 @@ Sets the specified property for \fInewpool\fR. See the “Properties” section
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.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
|
.ad
|
||||||
.sp .6
|
.sp .6
|
||||||
.RS 4n
|
.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.
|
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
|
.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.
|
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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
.na
|
.na
|
||||||
\fB\fB-x\fR\fR
|
\fB\fB-g\fR\fR
|
||||||
.ad
|
.ad
|
||||||
.RS 12n
|
.RS 12n
|
||||||
.rt
|
.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
|
.RE
|
||||||
|
|
||||||
.sp
|
.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.
|
Displays verbose data error information, printing out a complete list of all data errors since the last complete pool scrub.
|
||||||
.RE
|
.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
|
.sp
|
||||||
.ne 2
|
.ne 2
|
||||||
.mk
|
.mk
|
||||||
|
@ -2401,6 +2567,17 @@ Cause \fBzpool\fR to dump core on exit for the purposes of running \fB::findleak
|
||||||
.B "ZPOOL_IMPORT_PATH"
|
.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.
|
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.
|
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
|
.SH SEE ALSO
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -47,7 +47,7 @@ modules_install:
|
||||||
KERNELRELEASE=@LINUX_VERSION@
|
KERNELRELEASE=@LINUX_VERSION@
|
||||||
@# Remove extraneous build products when packaging
|
@# Remove extraneous build products when packaging
|
||||||
kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@; \
|
kmoddir=$(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/@LINUX_VERSION@; \
|
||||||
if [ -n $$kmoddir ]; then \
|
if [ -n "$(DESTDIR)" ]; then \
|
||||||
find $$kmoddir -name 'modules.*' | xargs $(RM); \
|
find $$kmoddir -name 'modules.*' | xargs $(RM); \
|
||||||
fi
|
fi
|
||||||
sysmap=$(DESTDIR)$(INSTALL_MOD_PATH)/boot/System.map-@LINUX_VERSION@; \
|
sysmap=$(DESTDIR)$(INSTALL_MOD_PATH)/boot/System.map-@LINUX_VERSION@; \
|
||||||
|
|
|
@ -630,7 +630,7 @@ avl_insert_here(
|
||||||
void
|
void
|
||||||
avl_add(avl_tree_t *tree, void *new_node)
|
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
|
* 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) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2015, 2016 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/stropts.h>
|
#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) \
|
#define NVPAIR2I_NVP(nvp) \
|
||||||
((i_nvp_t *)((size_t)(nvp) - offsetof(i_nvp_t, nvi_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
|
int
|
||||||
nv_alloc_init(nv_alloc_t *nva, const nv_alloc_ops_t *nvo, /* args */ ...)
|
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;
|
const nvs_ops_t *nvs_ops;
|
||||||
void *nvs_private;
|
void *nvs_private;
|
||||||
nvpriv_t *nvs_priv;
|
nvpriv_t *nvs_priv;
|
||||||
|
int nvs_recursion;
|
||||||
} nvstream_t;
|
} nvstream_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2168,9 +2175,16 @@ static int
|
||||||
nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
|
nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
|
||||||
{
|
{
|
||||||
switch (nvs->nvs_op) {
|
switch (nvs->nvs_op) {
|
||||||
case NVS_OP_ENCODE:
|
case NVS_OP_ENCODE: {
|
||||||
return (nvs_operation(nvs, embedded, NULL));
|
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: {
|
case NVS_OP_DECODE: {
|
||||||
nvpriv_t *priv;
|
nvpriv_t *priv;
|
||||||
int err;
|
int err;
|
||||||
|
@ -2183,8 +2197,12 @@ nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
|
||||||
|
|
||||||
nvlist_init(embedded, embedded->nvl_nvflag, priv);
|
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)
|
if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
|
||||||
nvlist_free(embedded);
|
nvlist_free(embedded);
|
||||||
|
nvs->nvs_recursion--;
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -2272,6 +2290,7 @@ nvlist_common(nvlist_t *nvl, char *buf, size_t *buflen, int encoding,
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
nvs.nvs_op = nvs_op;
|
nvs.nvs_op = nvs_op;
|
||||||
|
nvs.nvs_recursion = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For NVS_OP_ENCODE and NVS_OP_DECODE make sure an nvlist and
|
* 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;
|
l2arc_buf_hdr_t *l2hdr = NULL;
|
||||||
arc_state_t *state = 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)) {
|
if (HDR_HAS_L1HDR(hdr)) {
|
||||||
l1hdr = &hdr->b_l1hdr;
|
l1hdr = &hdr->b_l1hdr;
|
||||||
state = l1hdr->b_state;
|
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))
|
if (HDR_HAS_L2HDR(hdr))
|
||||||
l2hdr = &hdr->b_l2hdr;
|
l2hdr = &hdr->b_l2hdr;
|
||||||
|
|
||||||
memset(abi, 0, sizeof (arc_buf_info_t));
|
|
||||||
abi->abi_flags = hdr->b_flags;
|
|
||||||
|
|
||||||
if (l1hdr) {
|
if (l1hdr) {
|
||||||
abi->abi_datacnt = l1hdr->b_datacnt;
|
abi->abi_datacnt = l1hdr->b_datacnt;
|
||||||
abi->abi_access = l1hdr->b_arc_access;
|
abi->abi_access = l1hdr->b_arc_access;
|
||||||
|
@ -2697,12 +2701,7 @@ arc_prune_task(void *ptr)
|
||||||
if (func != NULL)
|
if (func != NULL)
|
||||||
func(ap->p_adjust, ap->p_private);
|
func(ap->p_adjust, ap->p_private);
|
||||||
|
|
||||||
/* Callback unregistered concurrently with execution */
|
refcount_remove(&ap->p_refcnt, func);
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3179,13 +3178,10 @@ arc_flush(spa_t *spa, boolean_t retry)
|
||||||
void
|
void
|
||||||
arc_shrink(int64_t to_free)
|
arc_shrink(int64_t to_free)
|
||||||
{
|
{
|
||||||
if (arc_c > arc_c_min) {
|
uint64_t c = arc_c;
|
||||||
|
|
||||||
if (arc_c > arc_c_min + to_free)
|
|
||||||
atomic_add_64(&arc_c, -to_free);
|
|
||||||
else
|
|
||||||
arc_c = arc_c_min;
|
|
||||||
|
|
||||||
|
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));
|
atomic_add_64(&arc_p, -(arc_p >> arc_shrink_shift));
|
||||||
if (arc_c > arc_size)
|
if (arc_c > arc_size)
|
||||||
arc_c = MAX(arc_size, arc_c_min);
|
arc_c = MAX(arc_size, arc_c_min);
|
||||||
|
@ -3193,6 +3189,8 @@ arc_shrink(int64_t to_free)
|
||||||
arc_p = (arc_c >> 1);
|
arc_p = (arc_c >> 1);
|
||||||
ASSERT(arc_c >= arc_c_min);
|
ASSERT(arc_c >= arc_c_min);
|
||||||
ASSERT((int64_t)arc_p >= 0);
|
ASSERT((int64_t)arc_p >= 0);
|
||||||
|
} else {
|
||||||
|
arc_c = arc_c_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arc_size > arc_c)
|
if (arc_size > arc_c)
|
||||||
|
@ -3373,6 +3371,11 @@ arc_kmem_reap_now(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; i++) {
|
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) {
|
if (zio_buf_cache[i] != prev_cache) {
|
||||||
prev_cache = zio_buf_cache[i];
|
prev_cache = zio_buf_cache[i];
|
||||||
kmem_cache_reap_now(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
|
* If we're within (2 * maxblocksize) bytes of the target
|
||||||
* cache size, increment the target cache size
|
* 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)) {
|
if (arc_size >= arc_c - (2ULL << SPA_MAXBLOCKSHIFT)) {
|
||||||
atomic_add_64(&arc_c, (int64_t)bytes);
|
atomic_add_64(&arc_c, (int64_t)bytes);
|
||||||
if (arc_c > arc_c_max)
|
if (arc_c > arc_c_max)
|
||||||
|
@ -4316,17 +4319,11 @@ top:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gracefully handle a damaged logical block size as a
|
* 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 (size > spa_maxblocksize(spa)) {
|
||||||
if (done) {
|
ASSERT3P(buf, ==, NULL);
|
||||||
rzio = zio_null(pio, spa, NULL,
|
rc = SET_ERROR(ECKSUM);
|
||||||
NULL, NULL, zio_flags);
|
|
||||||
rzio->io_error = ECKSUM;
|
|
||||||
done(rzio, buf, private);
|
|
||||||
zio_nowait(rzio);
|
|
||||||
}
|
|
||||||
rc = ECKSUM;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4564,13 +4561,19 @@ arc_add_prune_callback(arc_prune_func_t *func, void *private)
|
||||||
void
|
void
|
||||||
arc_remove_prune_callback(arc_prune_t *p)
|
arc_remove_prune_callback(arc_prune_t *p)
|
||||||
{
|
{
|
||||||
|
boolean_t wait = B_FALSE;
|
||||||
mutex_enter(&arc_prune_mtx);
|
mutex_enter(&arc_prune_mtx);
|
||||||
list_remove(&arc_prune_list, p);
|
list_remove(&arc_prune_list, p);
|
||||||
if (refcount_remove(&p->p_refcnt, &arc_prune_list) == 0) {
|
if (refcount_remove(&p->p_refcnt, &arc_prune_list) > 0)
|
||||||
refcount_destroy(&p->p_refcnt);
|
wait = B_TRUE;
|
||||||
kmem_free(p, sizeof (*p));
|
|
||||||
}
|
|
||||||
mutex_exit(&arc_prune_mtx);
|
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
|
void
|
||||||
|
@ -5100,7 +5103,9 @@ arc_tempreserve_space(uint64_t reserve, uint64_t txg)
|
||||||
int error;
|
int error;
|
||||||
uint64_t anon_size;
|
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);
|
arc_c = MIN(arc_c_max, reserve * 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5244,7 +5249,7 @@ arc_tuning_update(void)
|
||||||
arc_c_max = zfs_arc_max;
|
arc_c_max = zfs_arc_max;
|
||||||
arc_c = arc_c_max;
|
arc_c = arc_c_max;
|
||||||
arc_p = (arc_c >> 1);
|
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> */
|
/* Valid range: 32M - <arc_c_max> */
|
||||||
|
@ -5470,14 +5475,15 @@ arc_init(void)
|
||||||
* If it has been set by a module parameter, take that.
|
* If it has been set by a module parameter, take that.
|
||||||
* Otherwise, use a percentage of physical memory defined by
|
* Otherwise, use a percentage of physical memory defined by
|
||||||
* zfs_dirty_data_max_percent (default 10%) with a cap at
|
* 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)
|
if (zfs_dirty_data_max_max == 0)
|
||||||
zfs_dirty_data_max_max = physmem * PAGESIZE *
|
zfs_dirty_data_max_max = MIN(4ULL * 1024 * 1024 * 1024,
|
||||||
zfs_dirty_data_max_max_percent / 100;
|
(uint64_t)physmem * PAGESIZE *
|
||||||
|
zfs_dirty_data_max_max_percent / 100);
|
||||||
|
|
||||||
if (zfs_dirty_data_max == 0) {
|
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_percent / 100;
|
||||||
zfs_dirty_data_max = MIN(zfs_dirty_data_max,
|
zfs_dirty_data_max = MIN(zfs_dirty_data_max,
|
||||||
zfs_dirty_data_max_max);
|
zfs_dirty_data_max_max);
|
||||||
|
|
|
@ -2628,6 +2628,22 @@ dbuf_sync_leaf(dbuf_dirty_record_t *dr, dmu_tx_t *tx)
|
||||||
|
|
||||||
if (db->db_blkid == DMU_SPILL_BLKID) {
|
if (db->db_blkid == DMU_SPILL_BLKID) {
|
||||||
mutex_enter(&dn->dn_mtx);
|
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;
|
dn->dn_phys->dn_flags |= DNODE_FLAG_SPILL_BLKPTR;
|
||||||
mutex_exit(&dn->dn_mtx);
|
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_enter(&db->db_mtx);
|
||||||
mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
|
|
||||||
|
|
||||||
if (db->db_state != DB_EVICTING) {
|
if (db->db_state != DB_EVICTING) {
|
||||||
length = __dbuf_stats_hash_table_data(buf, size, db);
|
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_exit(&db->db_mtx);
|
||||||
mutex_enter(DBUF_HASH_MUTEX(h, dsh->idx));
|
|
||||||
}
|
}
|
||||||
mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
|
mutex_exit(DBUF_HASH_MUTEX(h, dsh->idx));
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
#include <sys/vmsystm.h>
|
#include <sys/vmsystm.h>
|
||||||
#include <sys/zfs_znode.h>
|
#include <sys/zfs_znode.h>
|
||||||
|
#include <linux/kmap_compat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1056,6 +1057,7 @@ dmu_bio_copy(void *arg_buf, int size, struct bio *bio, size_t bio_offset)
|
||||||
char *bv_buf;
|
char *bv_buf;
|
||||||
int tocpy, bv_len, bv_offset;
|
int tocpy, bv_len, bv_offset;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
void *paddr;
|
||||||
|
|
||||||
bio_for_each_segment4(bv, bvp, bio, iter) {
|
bio_for_each_segment4(bv, bvp, bio, iter) {
|
||||||
|
|
||||||
|
@ -1080,14 +1082,15 @@ dmu_bio_copy(void *arg_buf, int size, struct bio *bio, size_t bio_offset)
|
||||||
tocpy = MIN(bv_len, size - offset);
|
tocpy = MIN(bv_len, size - offset);
|
||||||
ASSERT3S(tocpy, >=, 0);
|
ASSERT3S(tocpy, >=, 0);
|
||||||
|
|
||||||
bv_buf = page_address(bvp->bv_page) + bv_offset;
|
paddr = zfs_kmap_atomic(bvp->bv_page, KM_USER0);
|
||||||
ASSERT3P(bv_buf, !=, NULL);
|
bv_buf = paddr + bv_offset;
|
||||||
|
ASSERT3P(paddr, !=, NULL);
|
||||||
|
|
||||||
if (bio_data_dir(bio) == WRITE)
|
if (bio_data_dir(bio) == WRITE)
|
||||||
memcpy(arg_buf + offset, bv_buf, tocpy);
|
memcpy(arg_buf + offset, bv_buf, tocpy);
|
||||||
else
|
else
|
||||||
memcpy(bv_buf, arg_buf + offset, tocpy);
|
memcpy(bv_buf, arg_buf + offset, tocpy);
|
||||||
|
zfs_kunmap_atomic(paddr, KM_USER0);
|
||||||
offset += tocpy;
|
offset += tocpy;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2013, 2014 by Delphix. All rights reserved.
|
* Copyright (c) 2013, 2015 by Delphix. All rights reserved.
|
||||||
* Copyright 2014 HybridCluster. All rights reserved.
|
* Copyright 2014 HybridCluster. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -50,6 +50,12 @@ dmu_object_alloc(objset_t *os, dmu_object_type_t ot, int blocksize,
|
||||||
* reasonably sparse (at most 1/4 full). Look from the
|
* reasonably sparse (at most 1/4 full). Look from the
|
||||||
* beginning once, but after that keep looking from here.
|
* beginning once, but after that keep looking from here.
|
||||||
* If we can't find one, just keep going from here.
|
* If we can't find one, just keep going from here.
|
||||||
|
*
|
||||||
|
* Note that dmu_traverse depends on the behavior that we use
|
||||||
|
* multiple blocks of the dnode object before going back to
|
||||||
|
* reuse objects. Any change to this algorithm should preserve
|
||||||
|
* that property or find another solution to the issues
|
||||||
|
* described in traverse_visitbp.
|
||||||
*/
|
*/
|
||||||
if (P2PHASE(object, L2_dnode_count) == 0) {
|
if (P2PHASE(object, L2_dnode_count) == 0) {
|
||||||
uint64_t offset = restarted ? object << DNODE_SHIFT : 0;
|
uint64_t offset = restarted ? object << DNODE_SHIFT : 0;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
|
||||||
* Copyright (c) 2015 Nexenta Systems, Inc. All rights reserved.
|
* Copyright (c) 2015 Nexenta Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2015, STRATO AG, Inc. All rights reserved.
|
* Copyright (c) 2015, STRATO AG, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Portions Copyright 2010 Robert Milkowski */
|
/* Portions Copyright 2010 Robert Milkowski */
|
||||||
|
@ -900,6 +901,8 @@ dmu_objset_create_sync(void *arg, dmu_tx_t *tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_history_log_internal_ds(ds, "create", tx, "");
|
spa_history_log_internal_ds(ds, "create", tx, "");
|
||||||
|
zvol_create_minors(dp->dp_spa, doca->doca_name, B_TRUE);
|
||||||
|
|
||||||
dsl_dataset_rele(ds, FTAG);
|
dsl_dataset_rele(ds, FTAG);
|
||||||
dsl_dir_rele(pdd, FTAG);
|
dsl_dir_rele(pdd, FTAG);
|
||||||
}
|
}
|
||||||
|
@ -993,6 +996,7 @@ dmu_objset_clone_sync(void *arg, dmu_tx_t *tx)
|
||||||
dsl_dataset_name(origin, namebuf);
|
dsl_dataset_name(origin, namebuf);
|
||||||
spa_history_log_internal_ds(ds, "clone", tx,
|
spa_history_log_internal_ds(ds, "clone", tx,
|
||||||
"origin=%s (%llu)", namebuf, origin->ds_object);
|
"origin=%s (%llu)", namebuf, origin->ds_object);
|
||||||
|
zvol_create_minors(dp->dp_spa, doca->doca_clone, B_TRUE);
|
||||||
dsl_dataset_rele(ds, FTAG);
|
dsl_dataset_rele(ds, FTAG);
|
||||||
dsl_dataset_rele(origin, FTAG);
|
dsl_dataset_rele(origin, FTAG);
|
||||||
dsl_dir_rele(pdd, FTAG);
|
dsl_dir_rele(pdd, FTAG);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
|
||||||
|
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/dmu.h>
|
#include <sys/dmu.h>
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
#include <sys/blkptr.h>
|
#include <sys/blkptr.h>
|
||||||
#include <sys/dsl_bookmark.h>
|
#include <sys/dsl_bookmark.h>
|
||||||
#include <sys/zfeature.h>
|
#include <sys/zfeature.h>
|
||||||
|
#include <sys/zvol.h>
|
||||||
|
|
||||||
/* Set this tunable to TRUE to replace corrupt data with 0x2f5baddb10c */
|
/* Set this tunable to TRUE to replace corrupt data with 0x2f5baddb10c */
|
||||||
int zfs_send_corrupt_data = B_FALSE;
|
int zfs_send_corrupt_data = B_FALSE;
|
||||||
|
@ -67,7 +69,7 @@ typedef struct dump_bytes_io {
|
||||||
} dump_bytes_io_t;
|
} dump_bytes_io_t;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_bytes_strategy(void *arg)
|
dump_bytes_cb(void *arg)
|
||||||
{
|
{
|
||||||
dump_bytes_io_t *dbi = (dump_bytes_io_t *)arg;
|
dump_bytes_io_t *dbi = (dump_bytes_io_t *)arg;
|
||||||
dmu_sendarg_t *dsp = dbi->dbi_dsp;
|
dmu_sendarg_t *dsp = dbi->dbi_dsp;
|
||||||
|
@ -94,6 +96,9 @@ dump_bytes(dmu_sendarg_t *dsp, void *buf, int len)
|
||||||
dbi.dbi_buf = buf;
|
dbi.dbi_buf = buf;
|
||||||
dbi.dbi_len = len;
|
dbi.dbi_len = len;
|
||||||
|
|
||||||
|
#if defined(HAVE_LARGE_STACKS)
|
||||||
|
dump_bytes_cb(&dbi);
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* The vn_rdwr() call is performed in a taskq to ensure that there is
|
* The vn_rdwr() call is performed in a taskq to ensure that there is
|
||||||
* always enough stack space to write safely to the target filesystem.
|
* always enough stack space to write safely to the target filesystem.
|
||||||
|
@ -101,7 +106,8 @@ dump_bytes(dmu_sendarg_t *dsp, void *buf, int len)
|
||||||
* them and they are used in vdev_file.c for a similar purpose.
|
* them and they are used in vdev_file.c for a similar purpose.
|
||||||
*/
|
*/
|
||||||
spa_taskq_dispatch_sync(dmu_objset_spa(dsp->dsa_os), ZIO_TYPE_FREE,
|
spa_taskq_dispatch_sync(dmu_objset_spa(dsp->dsa_os), ZIO_TYPE_FREE,
|
||||||
ZIO_TASKQ_ISSUE, dump_bytes_strategy, &dbi, TQ_SLEEP);
|
ZIO_TASKQ_ISSUE, dump_bytes_cb, &dbi, TQ_SLEEP);
|
||||||
|
#endif /* HAVE_LARGE_STACKS */
|
||||||
|
|
||||||
return (dsp->dsa_err);
|
return (dsp->dsa_err);
|
||||||
}
|
}
|
||||||
|
@ -2162,6 +2168,7 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
|
||||||
dsl_dataset_phys(ds)->ds_flags &= ~DS_FLAG_INCONSISTENT;
|
dsl_dataset_phys(ds)->ds_flags &= ~DS_FLAG_INCONSISTENT;
|
||||||
}
|
}
|
||||||
drc->drc_newsnapobj = dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj;
|
drc->drc_newsnapobj = dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj;
|
||||||
|
zvol_create_minors(dp->dp_spa, drc->drc_tofs, B_TRUE);
|
||||||
/*
|
/*
|
||||||
* Release the hold from dmu_recv_begin. This must be done before
|
* Release the hold from dmu_recv_begin. This must be done before
|
||||||
* we return to open context, so that when we free the dataset's dnode,
|
* we return to open context, so that when we free the dataset's dnode,
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue