Notable upstream pull request merges:
  #13805 Configure zed's diagnosis engine with vdev properties
  #14110 zfs list: Allow more fields in ZFS_ITER_SIMPLE mode
  #14121 Batch enqueue/dequeue for bqueue
  #14123 arc_read()/arc_access() refactoring and cleanup
  #14159 Bypass metaslab throttle for removal allocations
  #14243 Implement uncached prefetch
  #14251 Cache dbuf_hash() calculation
  #14253 Allow reciever to override encryption property in case of replication
  #14254 Restrict visibility of per-dataset kstats inside FreeBSD jails
  #14255 Zero end of embedded block buffer in dump_write_embedded()
  #14263 Cleanups identified by CodeQL and Coverity
  #14264 Miscellaneous fixes
  #14272 Change ZEVENT_POOL_GUID to ZEVENT_POOL to display pool names
  #14287 FreeBSD: Remove stray debug printf
  #14288 Colorize zfs diff output
  #14289 deadlock between spa_errlog_lock and dp_config_rwlock
  #14291 FreeBSD: Fix potential boot panic with bad label
  #14292 Add tunable to allow changing micro ZAP's max size
  #14293 Turn default_bs and default_ibs into ZFS_MODULE_PARAMs
  #14295 zed: add hotplug support for spare vdevs
  #14304 Activate filesystem features only in syncing context
  #14311 zpool: do guid-based comparison in is_vdev_cb()
  #14317 Pack zrlock_t by 8 bytes
  #14320 Update arc_summary and arcstat outputs
  #14328 FreeBSD: catch up to 1400077
  #14376 Use setproctitle to report progress of zfs send
  #14340 Remove some dead ARC code
  #14358 Wait for txg sync if the last DRR_FREEOBJECTS might result in a hole
  #14360 libzpool: fix ddi_strtoull to update nptr
  #14364 Fix unprotected zfs_znode_dmu_fini
  #14379 zfs_receive_one: Check for the more likely error first
  #14380 Cleanup of dead code suggested by Clang Static Analyzer
  #14397 Avoid passing an uninitialized index to dsl_prop_known_index
  #14404 Fix reading uninitialized variable in receive_read
  #14407 free_blocks(): Fix reports from 2016 PVS Studio FreeBSD report
  #14418 Introduce minimal ZIL block commit delay
  #14422 x86 assembly: fix .size placement and replace .align with .balign

Obtained from:	OpenZFS
OpenZFS commit:	9cd71c8604
This commit is contained in:
Martin Matuska 2023-01-25 19:50:29 +01:00
commit 15f0b8c309
220 changed files with 4476 additions and 2136 deletions

View file

@ -318,7 +318,7 @@ be_promote_dependent_clones(zfs_handle_t *zfs_hdl, struct be_destroy_data *bdd)
struct promote_entry *entry;
snprintf(bdd->target_name, BE_MAXPATHLEN, "%s/", zfs_get_name(zfs_hdl));
err = zfs_iter_dependents(zfs_hdl, true, be_dependent_clone_cb, bdd);
err = zfs_iter_dependents(zfs_hdl, 0, true, be_dependent_clone_cb, bdd);
/*
* Drain the list and walk away from it if we're only deleting a
@ -360,13 +360,13 @@ be_destroy_cb(zfs_handle_t *zfs_hdl, void *data)
bdd = (struct be_destroy_data *)data;
if (bdd->snapname == NULL) {
err = zfs_iter_children(zfs_hdl, be_destroy_cb, data);
err = zfs_iter_children(zfs_hdl, 0, be_destroy_cb, data);
if (err != 0)
return (err);
return (zfs_destroy(zfs_hdl, false));
}
/* If we're dealing with snapshots instead, delete that one alone */
err = zfs_iter_filesystems(zfs_hdl, be_destroy_cb, data);
err = zfs_iter_filesystems(zfs_hdl, 0, be_destroy_cb, data);
if (err != 0)
return (err);
/*
@ -777,7 +777,7 @@ be_clone_cb(zfs_handle_t *ds, void *data)
if (ldc->depth_limit == -1 || ldc->depth < ldc->depth_limit) {
ldc->depth++;
err = zfs_iter_filesystems(ds, be_clone_cb, ldc);
err = zfs_iter_filesystems(ds, 0, be_clone_cb, ldc);
ldc->depth--;
}

View file

@ -141,7 +141,7 @@ be_mount_iter(zfs_handle_t *zfs_hdl, void *data)
skipmount:
++info->depth;
err = zfs_iter_filesystems(zfs_hdl, be_mount_iter, info);
err = zfs_iter_filesystems(zfs_hdl, 0, be_mount_iter, info);
--info->depth;
return (err);
}
@ -158,7 +158,7 @@ be_umount_iter(zfs_handle_t *zfs_hdl, void *data)
info = (struct be_mount_info *)data;
++info->depth;
if((err = zfs_iter_filesystems(zfs_hdl, be_umount_iter, info)) != 0) {
if((err = zfs_iter_filesystems(zfs_hdl, 0, be_umount_iter, info)) != 0) {
return (err);
}
--info->depth;
@ -205,7 +205,7 @@ be_mounted_at(libbe_handle_t *lbh, const char *path, nvlist_t *details)
info.path = path;
info.name = NULL;
zfs_iter_filesystems(root_hdl, be_mountcheck_cb, &info);
zfs_iter_filesystems(root_hdl, 0, be_mountcheck_cb, &info);
zfs_close(root_hdl);
if (info.name != NULL) {

View file

@ -258,7 +258,7 @@ be_proplist_update(prop_data_t *data)
&data->bootonce);
/* XXX TODO: some error checking here */
zfs_iter_filesystems(root_hdl, prop_list_builder_cb, data);
zfs_iter_filesystems(root_hdl, 0, prop_list_builder_cb, data);
zfs_close(root_hdl);
@ -269,7 +269,7 @@ static int
snapshot_proplist_update(zfs_handle_t *hdl, prop_data_t *data)
{
return (zfs_iter_snapshots_sorted(hdl, prop_list_builder_cb, data,
return (zfs_iter_snapshots_sorted(hdl, 0, prop_list_builder_cb, data,
0, 0));
}

View file

@ -6,6 +6,9 @@ bc
build-essential
curl
dbench
debhelper-compat
dh-python
dkms
fakeroot
fio
gdb
@ -33,12 +36,15 @@ mdadm
nfs-kernel-server
pamtester
parted
po-debconf
python3
python3-all-dev
python3-cffi
python3-dev
python3-packaging
python3-pip
python3-setuptools
python3-sphinx
rng-tools-debian
rsync
samba

View file

@ -15,9 +15,6 @@ jobs:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Reclaim disk space
run: |
${{ github.workspace }}/.github/workflows/scripts/reclaim_disk_space.sh
- name: Install dependencies
run: |
sudo apt-get update
@ -32,15 +29,18 @@ jobs:
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan
- name: Make
run: |
make -j$(nproc) --no-print-directory --silent pkg-utils pkg-kmod
make --no-print-directory --silent native-deb-utils native-deb-kmod
mv ../*.deb .
rm ./openzfs-zfs-dkms*.deb ./openzfs-zfs-dracut*.deb
- name: Install
run: |
sudo dpkg -i *.deb
# Update order of directories to search for modules, otherwise
# Ubuntu will load kernel-shipped ones.
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
sudo depmod
sudo modprobe zfs
sudo dpkg -i *.deb
# Native Debian packages enable and start the services
# Stop zfs-zed daemon, as it may interfere with some ZTS test cases
sudo systemctl stop zfs-zed
# Workaround for cloud-init bug
# see https://github.com/openzfs/zfs/issues/12644
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
@ -55,8 +55,9 @@ jobs:
- name: Clear the kernel ring buffer
run: |
sudo dmesg -c >/var/tmp/dmesg-prerun
- name: Report disk space
- name: Reclaim and report disk space
run: |
${{ github.workspace }}/.github/workflows/scripts/reclaim_disk_space.sh
df -h /
- name: Tests
run: |

View file

@ -11,9 +11,6 @@ jobs:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Reclaim disk space
run: |
${{ github.workspace }}/.github/workflows/scripts/reclaim_disk_space.sh
- name: Install dependencies
run: |
sudo apt-get update
@ -28,15 +25,18 @@ jobs:
./configure --enable-debug --enable-debuginfo --enable-asan --enable-ubsan
- name: Make
run: |
make -j$(nproc) --no-print-directory --silent pkg-utils pkg-kmod
make --no-print-directory --silent native-deb-utils native-deb-kmod
mv ../*.deb .
rm ./openzfs-zfs-dkms*.deb ./openzfs-zfs-dracut*.deb
- name: Install
run: |
sudo dpkg -i *.deb
# Update order of directories to search for modules, otherwise
# Ubuntu will load kernel-shipped ones.
sudo sed -i.bak 's/updates/extra updates/' /etc/depmod.d/ubuntu.conf
sudo depmod
sudo modprobe zfs
sudo dpkg -i *.deb
# Native Debian packages enable and start the services
# Stop zfs-zed daemon, as it may interfere with some ZTS test cases
sudo systemctl stop zfs-zed
# Workaround for cloud-init bug
# see https://github.com/openzfs/zfs/issues/12644
FILE=/lib/udev/rules.d/10-cloud-init-hook-hotplug.rules
@ -51,8 +51,9 @@ jobs:
- name: Clear the kernel ring buffer
run: |
sudo dmesg -c >/var/tmp/dmesg-prerun
- name: Report disk space
- name: Reclaim and report disk space
run: |
${{ github.workspace }}/.github/workflows/scripts/reclaim_disk_space.sh
df -h /
- name: Tests
run: |

View file

@ -1,2 +1,2 @@
The [OpenZFS Code of Conduct](http://www.open-zfs.org/wiki/Code_of_Conduct)
The [OpenZFS Code of Conduct](https://openzfs.org/wiki/Code_of_Conduct)
applies to spaces associated with the OpenZFS project, including GitHub.

View file

@ -6,5 +6,5 @@ Release: 1
Release-Tags: relext
License: CDDL
Author: OpenZFS
Linux-Maximum: 6.0
Linux-Maximum: 6.1
Linux-Minimum: 3.10

View file

@ -558,8 +558,12 @@ def section_arc(kstats_dict):
arc_target_size = arc_stats['c']
arc_max = arc_stats['c_max']
arc_min = arc_stats['c_min']
anon_size = arc_stats['anon_size']
mfu_size = arc_stats['mfu_size']
mru_size = arc_stats['mru_size']
mfug_size = arc_stats['mfu_ghost_size']
mrug_size = arc_stats['mru_ghost_size']
unc_size = arc_stats['uncached_size']
meta_limit = arc_stats['arc_meta_limit']
meta_size = arc_stats['arc_meta_used']
dnode_limit = arc_stats['arc_dnode_limit']
@ -574,11 +578,17 @@ def section_arc(kstats_dict):
f_perc(arc_min, arc_max), f_bytes(arc_min))
prt_i2('Max size (high water):',
target_size_ratio, f_bytes(arc_max))
caches_size = int(mfu_size)+int(mru_size)
caches_size = int(anon_size)+int(mfu_size)+int(mru_size)+int(unc_size)
prt_i2('Anonymouns data size:',
f_perc(anon_size, caches_size), f_bytes(anon_size))
prt_i2('Most Frequently Used (MFU) cache size:',
f_perc(mfu_size, caches_size), f_bytes(mfu_size))
prt_i2('Most Recently Used (MRU) cache size:',
f_perc(mru_size, caches_size), f_bytes(mru_size))
prt_i1('Most Frequently Used (MFU) ghost size:', f_bytes(mfug_size))
prt_i1('Most Recently Used (MRU) ghost size:', f_bytes(mrug_size))
prt_i2('Uncached data size:',
f_perc(unc_size, caches_size), f_bytes(unc_size))
prt_i2('Metadata cache size (hard limit):',
f_perc(meta_limit, arc_max), f_bytes(meta_limit))
prt_i2('Metadata cache size (current):',
@ -626,78 +636,119 @@ def section_archits(kstats_dict):
"""
arc_stats = isolate_section('arcstats', kstats_dict)
all_accesses = int(arc_stats['hits'])+int(arc_stats['misses'])
actual_hits = int(arc_stats['mfu_hits'])+int(arc_stats['mru_hits'])
prt_1('ARC total accesses (hits + misses):', f_hits(all_accesses))
ta_todo = (('Cache hit ratio:', arc_stats['hits']),
('Cache miss ratio:', arc_stats['misses']),
('Actual hit ratio (MFU + MRU hits):', actual_hits))
all_accesses = int(arc_stats['hits'])+int(arc_stats['iohits'])+\
int(arc_stats['misses'])
prt_1('ARC total accesses:', f_hits(all_accesses))
ta_todo = (('Total hits:', arc_stats['hits']),
('Total I/O hits:', arc_stats['iohits']),
('Total misses:', arc_stats['misses']))
for title, value in ta_todo:
prt_i2(title, f_perc(value, all_accesses), f_hits(value))
print()
dd_total = int(arc_stats['demand_data_hits']) +\
int(arc_stats['demand_data_iohits']) +\
int(arc_stats['demand_data_misses'])
prt_i2('Data demand efficiency:',
f_perc(arc_stats['demand_data_hits'], dd_total),
f_hits(dd_total))
dp_total = int(arc_stats['prefetch_data_hits']) +\
int(arc_stats['prefetch_data_misses'])
prt_i2('Data prefetch efficiency:',
f_perc(arc_stats['prefetch_data_hits'], dp_total),
f_hits(dp_total))
known_hits = int(arc_stats['mfu_hits']) +\
int(arc_stats['mru_hits']) +\
int(arc_stats['mfu_ghost_hits']) +\
int(arc_stats['mru_ghost_hits'])
anon_hits = int(arc_stats['hits'])-known_hits
prt_2('ARC demand data accesses:', f_perc(dd_total, all_accesses),
f_hits(dd_total))
dd_todo = (('Demand data hits:', arc_stats['demand_data_hits']),
('Demand data I/O hits:', arc_stats['demand_data_iohits']),
('Demand data misses:', arc_stats['demand_data_misses']))
for title, value in dd_todo:
prt_i2(title, f_perc(value, dd_total), f_hits(value))
print()
print('Cache hits by cache type:')
dm_total = int(arc_stats['demand_metadata_hits']) +\
int(arc_stats['demand_metadata_iohits']) +\
int(arc_stats['demand_metadata_misses'])
prt_2('ARC demand metadata accesses:', f_perc(dm_total, all_accesses),
f_hits(dm_total))
dm_todo = (('Demand metadata hits:', arc_stats['demand_metadata_hits']),
('Demand metadata I/O hits:',
arc_stats['demand_metadata_iohits']),
('Demand metadata misses:', arc_stats['demand_metadata_misses']))
for title, value in dm_todo:
prt_i2(title, f_perc(value, dm_total), f_hits(value))
print()
pd_total = int(arc_stats['prefetch_data_hits']) +\
int(arc_stats['prefetch_data_iohits']) +\
int(arc_stats['prefetch_data_misses'])
prt_2('ARC prefetch metadata accesses:', f_perc(pd_total, all_accesses),
f_hits(pd_total))
pd_todo = (('Prefetch data hits:', arc_stats['prefetch_data_hits']),
('Prefetch data I/O hits:', arc_stats['prefetch_data_iohits']),
('Prefetch data misses:', arc_stats['prefetch_data_misses']))
for title, value in pd_todo:
prt_i2(title, f_perc(value, pd_total), f_hits(value))
print()
pm_total = int(arc_stats['prefetch_metadata_hits']) +\
int(arc_stats['prefetch_metadata_iohits']) +\
int(arc_stats['prefetch_metadata_misses'])
prt_2('ARC prefetch metadata accesses:', f_perc(pm_total, all_accesses),
f_hits(pm_total))
pm_todo = (('Prefetch metadata hits:',
arc_stats['prefetch_metadata_hits']),
('Prefetch metadata I/O hits:',
arc_stats['prefetch_metadata_iohits']),
('Prefetch metadata misses:',
arc_stats['prefetch_metadata_misses']))
for title, value in pm_todo:
prt_i2(title, f_perc(value, pm_total), f_hits(value))
print()
all_prefetches = int(arc_stats['predictive_prefetch'])+\
int(arc_stats['prescient_prefetch'])
prt_2('ARC predictive prefetches:',
f_perc(arc_stats['predictive_prefetch'], all_prefetches),
f_hits(arc_stats['predictive_prefetch']))
prt_i2('Demand hits after predictive:',
f_perc(arc_stats['demand_hit_predictive_prefetch'],
arc_stats['predictive_prefetch']),
f_hits(arc_stats['demand_hit_predictive_prefetch']))
prt_i2('Demand I/O hits after predictive:',
f_perc(arc_stats['demand_iohit_predictive_prefetch'],
arc_stats['predictive_prefetch']),
f_hits(arc_stats['demand_iohit_predictive_prefetch']))
never = int(arc_stats['predictive_prefetch']) -\
int(arc_stats['demand_hit_predictive_prefetch']) -\
int(arc_stats['demand_iohit_predictive_prefetch'])
prt_i2('Never demanded after predictive:',
f_perc(never, arc_stats['predictive_prefetch']),
f_hits(never))
print()
prt_2('ARC prescient prefetches:',
f_perc(arc_stats['prescient_prefetch'], all_prefetches),
f_hits(arc_stats['prescient_prefetch']))
prt_i2('Demand hits after prescient:',
f_perc(arc_stats['demand_hit_prescient_prefetch'],
arc_stats['prescient_prefetch']),
f_hits(arc_stats['demand_hit_prescient_prefetch']))
prt_i2('Demand I/O hits after prescient:',
f_perc(arc_stats['demand_iohit_prescient_prefetch'],
arc_stats['prescient_prefetch']),
f_hits(arc_stats['demand_iohit_prescient_prefetch']))
never = int(arc_stats['prescient_prefetch'])-\
int(arc_stats['demand_hit_prescient_prefetch'])-\
int(arc_stats['demand_iohit_prescient_prefetch'])
prt_i2('Never demanded after prescient:',
f_perc(never, arc_stats['prescient_prefetch']),
f_hits(never))
print()
print('ARC states hits of all accesses:')
cl_todo = (('Most frequently used (MFU):', arc_stats['mfu_hits']),
('Most recently used (MRU):', arc_stats['mru_hits']),
('Most frequently used (MFU) ghost:',
arc_stats['mfu_ghost_hits']),
('Most recently used (MRU) ghost:',
arc_stats['mru_ghost_hits']))
arc_stats['mru_ghost_hits']),
('Uncached:', arc_stats['uncached_hits']))
for title, value in cl_todo:
prt_i2(title, f_perc(value, arc_stats['hits']), f_hits(value))
# For some reason, anon_hits can turn negative, which is weird. Until we
# have figured out why this happens, we just hide the problem, following
# the behavior of the original arc_summary.
if anon_hits >= 0:
prt_i2('Anonymously used:',
f_perc(anon_hits, arc_stats['hits']), f_hits(anon_hits))
print()
print('Cache hits by data type:')
dt_todo = (('Demand data:', arc_stats['demand_data_hits']),
('Prefetch data:', arc_stats['prefetch_data_hits']),
('Demand metadata:', arc_stats['demand_metadata_hits']),
('Prefetch metadata:',
arc_stats['prefetch_metadata_hits']))
for title, value in dt_todo:
prt_i2(title, f_perc(value, arc_stats['hits']), f_hits(value))
print()
print('Cache misses by data type:')
dm_todo = (('Demand data:', arc_stats['demand_data_misses']),
('Prefetch data:',
arc_stats['prefetch_data_misses']),
('Demand metadata:', arc_stats['demand_metadata_misses']),
('Prefetch metadata:',
arc_stats['prefetch_metadata_misses']))
for title, value in dm_todo:
prt_i2(title, f_perc(value, arc_stats['misses']), f_hits(value))
prt_i2(title, f_perc(value, all_accesses), f_hits(value))
print()
@ -708,11 +759,17 @@ def section_dmu(kstats_dict):
zfetch_access_total = int(zfetch_stats['hits'])+int(zfetch_stats['misses'])
prt_1('DMU prefetch efficiency:', f_hits(zfetch_access_total))
prt_i2('Hit ratio:', f_perc(zfetch_stats['hits'], zfetch_access_total),
prt_1('DMU predictive prefetcher calls:', f_hits(zfetch_access_total))
prt_i2('Stream hits:',
f_perc(zfetch_stats['hits'], zfetch_access_total),
f_hits(zfetch_stats['hits']))
prt_i2('Miss ratio:', f_perc(zfetch_stats['misses'], zfetch_access_total),
prt_i2('Stream misses:',
f_perc(zfetch_stats['misses'], zfetch_access_total),
f_hits(zfetch_stats['misses']))
prt_i2('Streams limit reached:',
f_perc(zfetch_stats['max_streams'], zfetch_stats['misses']),
f_hits(zfetch_stats['max_streams']))
prt_i1('Prefetches issued', f_hits(zfetch_stats['io_issued']))
print()

View file

@ -62,31 +62,64 @@ from signal import signal, SIGINT, SIGWINCH, SIG_DFL
cols = {
# HDR: [Size, Scale, Description]
"time": [8, -1, "Time"],
"hits": [4, 1000, "ARC reads per second"],
"hits": [4, 1000, "ARC hits per second"],
"iohs": [4, 1000, "ARC I/O hits per second"],
"miss": [4, 1000, "ARC misses per second"],
"read": [4, 1000, "Total ARC accesses per second"],
"hit%": [4, 100, "ARC hit percentage"],
"ioh%": [4, 100, "ARC I/O hit percentage"],
"miss%": [5, 100, "ARC miss percentage"],
"dhit": [4, 1000, "Demand hits per second"],
"dioh": [4, 1000, "Demand I/O hits per second"],
"dmis": [4, 1000, "Demand misses per second"],
"dh%": [3, 100, "Demand hit percentage"],
"di%": [3, 100, "Demand I/O hit percentage"],
"dm%": [3, 100, "Demand miss percentage"],
"ddhit": [5, 1000, "Demand data hits per second"],
"ddioh": [5, 1000, "Demand data I/O hits per second"],
"ddmis": [5, 1000, "Demand data misses per second"],
"ddh%": [4, 100, "Demand data hit percentage"],
"ddi%": [4, 100, "Demand data I/O hit percentage"],
"ddm%": [4, 100, "Demand data miss percentage"],
"dmhit": [5, 1000, "Demand metadata hits per second"],
"dmioh": [5, 1000, "Demand metadata I/O hits per second"],
"dmmis": [5, 1000, "Demand metadata misses per second"],
"dmh%": [4, 100, "Demand metadata hit percentage"],
"dmi%": [4, 100, "Demand metadata I/O hit percentage"],
"dmm%": [4, 100, "Demand metadata miss percentage"],
"phit": [4, 1000, "Prefetch hits per second"],
"pioh": [4, 1000, "Prefetch I/O hits per second"],
"pmis": [4, 1000, "Prefetch misses per second"],
"ph%": [3, 100, "Prefetch hits percentage"],
"pi%": [3, 100, "Prefetch I/O hits percentage"],
"pm%": [3, 100, "Prefetch miss percentage"],
"pdhit": [5, 1000, "Prefetch data hits per second"],
"pdioh": [5, 1000, "Prefetch data I/O hits per second"],
"pdmis": [5, 1000, "Prefetch data misses per second"],
"pdh%": [4, 100, "Prefetch data hits percentage"],
"pdi%": [4, 100, "Prefetch data I/O hits percentage"],
"pdm%": [4, 100, "Prefetch data miss percentage"],
"pmhit": [5, 1000, "Prefetch metadata hits per second"],
"pmioh": [5, 1000, "Prefetch metadata I/O hits per second"],
"pmmis": [5, 1000, "Prefetch metadata misses per second"],
"pmh%": [4, 100, "Prefetch metadata hits percentage"],
"pmi%": [4, 100, "Prefetch metadata I/O hits percentage"],
"pmm%": [4, 100, "Prefetch metadata miss percentage"],
"mhit": [4, 1000, "Metadata hits per second"],
"mioh": [4, 1000, "Metadata I/O hits per second"],
"mmis": [4, 1000, "Metadata misses per second"],
"mread": [5, 1000, "Metadata accesses per second"],
"mh%": [3, 100, "Metadata hit percentage"],
"mi%": [3, 100, "Metadata I/O hit percentage"],
"mm%": [3, 100, "Metadata miss percentage"],
"arcsz": [5, 1024, "ARC size"],
"size": [4, 1024, "ARC size"],
"c": [4, 1024, "ARC target size"],
"size": [5, 1024, "ARC size"],
"c": [5, 1024, "ARC target size"],
"mfu": [4, 1000, "MFU list hits per second"],
"mru": [4, 1000, "MRU list hits per second"],
"mfug": [4, 1000, "MFU ghost list hits per second"],
"mrug": [4, 1000, "MRU ghost list hits per second"],
"unc": [4, 1000, "Uncached list hits per second"],
"eskip": [5, 1000, "evict_skip per second"],
"el2skip": [7, 1000, "evict skip, due to l2 writes, per second"],
"el2cach": [7, 1024, "Size of L2 cached evictions per second"],
@ -96,7 +129,11 @@ cols = {
"el2inel": [7, 1024, "Size of L2 ineligible evictions per second"],
"mtxmis": [6, 1000, "mutex_miss per second"],
"dread": [5, 1000, "Demand accesses per second"],
"ddread": [6, 1000, "Demand data accesses per second"],
"dmread": [6, 1000, "Demand metadata accesses per second"],
"pread": [5, 1000, "Prefetch accesses per second"],
"pdread": [6, 1000, "Prefetch data accesses per second"],
"pmread": [6, 1000, "Prefetch metadata accesses per second"],
"l2hits": [6, 1000, "L2ARC hits per second"],
"l2miss": [6, 1000, "L2ARC misses per second"],
"l2read": [6, 1000, "Total L2ARC accesses per second"],
@ -116,23 +153,22 @@ cols = {
"l2size": [6, 1024, "Size of the L2ARC"],
"l2bytes": [7, 1024, "Bytes read per second from the L2ARC"],
"grow": [4, 1000, "ARC grow disabled"],
"need": [4, 1024, "ARC reclaim need"],
"free": [4, 1024, "ARC free memory"],
"need": [5, 1024, "ARC reclaim need"],
"free": [5, 1024, "ARC free memory"],
"avail": [5, 1024, "ARC available memory"],
"waste": [5, 1024, "Wasted memory due to round up to pagesize"],
}
v = {}
hdr = ["time", "read", "miss", "miss%", "dmis", "dm%", "pmis", "pm%", "mmis",
"mm%", "size", "c", "avail"]
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "eskip", "mtxmis", "dread",
"pread", "read"]
hdr = ["time", "read", "ddread", "ddh%", "dmread", "dmh%", "pread", "ph%",
"size", "c", "avail"]
xhdr = ["time", "mfu", "mru", "mfug", "mrug", "unc", "eskip", "mtxmis",
"dread", "pread", "read"]
sint = 1 # Default interval is 1 second
count = 1 # Default count is 1
hdr_intr = 20 # Print header every 20 lines of output
opfile = None
sep = " " # Default separator is 2 spaces
version = "0.4"
l2exist = False
cmd = ("Usage: arcstat [-havxp] [-f fields] [-o file] [-s string] [interval "
"[count]]\n")
@ -442,34 +478,80 @@ def calculate():
v = dict()
v["time"] = time.strftime("%H:%M:%S", time.localtime())
v["hits"] = d["hits"] // sint
v["iohs"] = d["iohits"] // sint
v["miss"] = d["misses"] // sint
v["read"] = v["hits"] + v["miss"]
v["read"] = v["hits"] + v["iohs"] + v["miss"]
v["hit%"] = 100 * v["hits"] // v["read"] if v["read"] > 0 else 0
v["miss%"] = 100 - v["hit%"] if v["read"] > 0 else 0
v["ioh%"] = 100 * v["iohs"] // v["read"] if v["read"] > 0 else 0
v["miss%"] = 100 - v["hit%"] - v["ioh%"] if v["read"] > 0 else 0
v["dhit"] = (d["demand_data_hits"] + d["demand_metadata_hits"]) // sint
v["dioh"] = (d["demand_data_iohits"] + d["demand_metadata_iohits"]) // sint
v["dmis"] = (d["demand_data_misses"] + d["demand_metadata_misses"]) // sint
v["dread"] = v["dhit"] + v["dmis"]
v["dread"] = v["dhit"] + v["dioh"] + v["dmis"]
v["dh%"] = 100 * v["dhit"] // v["dread"] if v["dread"] > 0 else 0
v["dm%"] = 100 - v["dh%"] if v["dread"] > 0 else 0
v["di%"] = 100 * v["dioh"] // v["dread"] if v["dread"] > 0 else 0
v["dm%"] = 100 - v["dh%"] - v["di%"] if v["dread"] > 0 else 0
v["ddhit"] = d["demand_data_hits"] // sint
v["ddioh"] = d["demand_data_iohits"] // sint
v["ddmis"] = d["demand_data_misses"] // sint
v["ddread"] = v["ddhit"] + v["ddioh"] + v["ddmis"]
v["ddh%"] = 100 * v["ddhit"] // v["ddread"] if v["ddread"] > 0 else 0
v["ddi%"] = 100 * v["ddioh"] // v["ddread"] if v["ddread"] > 0 else 0
v["ddm%"] = 100 - v["ddh%"] - v["ddi%"] if v["ddread"] > 0 else 0
v["dmhit"] = d["demand_metadata_hits"] // sint
v["dmioh"] = d["demand_metadata_iohits"] // sint
v["dmmis"] = d["demand_metadata_misses"] // sint
v["dmread"] = v["dmhit"] + v["dmioh"] + v["dmmis"]
v["dmh%"] = 100 * v["dmhit"] // v["dmread"] if v["dmread"] > 0 else 0
v["dmi%"] = 100 * v["dmioh"] // v["dmread"] if v["dmread"] > 0 else 0
v["dmm%"] = 100 - v["dmh%"] - v["dmi%"] if v["dmread"] > 0 else 0
v["phit"] = (d["prefetch_data_hits"] + d["prefetch_metadata_hits"]) // sint
v["pioh"] = (d["prefetch_data_iohits"] +
d["prefetch_metadata_iohits"]) // sint
v["pmis"] = (d["prefetch_data_misses"] +
d["prefetch_metadata_misses"]) // sint
v["pread"] = v["phit"] + v["pmis"]
v["pread"] = v["phit"] + v["pioh"] + v["pmis"]
v["ph%"] = 100 * v["phit"] // v["pread"] if v["pread"] > 0 else 0
v["pm%"] = 100 - v["ph%"] if v["pread"] > 0 else 0
v["pi%"] = 100 * v["pioh"] // v["pread"] if v["pread"] > 0 else 0
v["pm%"] = 100 - v["ph%"] - v["pi%"] if v["pread"] > 0 else 0
v["pdhit"] = d["prefetch_data_hits"] // sint
v["pdioh"] = d["prefetch_data_iohits"] // sint
v["pdmis"] = d["prefetch_data_misses"] // sint
v["pdread"] = v["pdhit"] + v["pdioh"] + v["pdmis"]
v["pdh%"] = 100 * v["pdhit"] // v["pdread"] if v["pdread"] > 0 else 0
v["pdi%"] = 100 * v["pdioh"] // v["pdread"] if v["pdread"] > 0 else 0
v["pdm%"] = 100 - v["pdh%"] - v["pdi%"] if v["pdread"] > 0 else 0
v["pmhit"] = d["prefetch_metadata_hits"] // sint
v["pmioh"] = d["prefetch_metadata_iohits"] // sint
v["pmmis"] = d["prefetch_metadata_misses"] // sint
v["pmread"] = v["pmhit"] + v["pmioh"] + v["pmmis"]
v["pmh%"] = 100 * v["pmhit"] // v["pmread"] if v["pmread"] > 0 else 0
v["pmi%"] = 100 * v["pmioh"] // v["pmread"] if v["pmread"] > 0 else 0
v["pmm%"] = 100 - v["pmh%"] - v["pmi%"] if v["pmread"] > 0 else 0
v["mhit"] = (d["prefetch_metadata_hits"] +
d["demand_metadata_hits"]) // sint
v["mioh"] = (d["prefetch_metadata_iohits"] +
d["demand_metadata_iohits"]) // sint
v["mmis"] = (d["prefetch_metadata_misses"] +
d["demand_metadata_misses"]) // sint
v["mread"] = v["mhit"] + v["mmis"]
v["mread"] = v["mhit"] + v["mioh"] + v["mmis"]
v["mh%"] = 100 * v["mhit"] // v["mread"] if v["mread"] > 0 else 0
v["mm%"] = 100 - v["mh%"] if v["mread"] > 0 else 0
v["mi%"] = 100 * v["mioh"] // v["mread"] if v["mread"] > 0 else 0
v["mm%"] = 100 - v["mh%"] - v["mi%"] if v["mread"] > 0 else 0
v["arcsz"] = cur["size"]
v["size"] = cur["size"]
@ -478,6 +560,7 @@ def calculate():
v["mru"] = d["mru_hits"] // sint
v["mrug"] = d["mru_ghost_hits"] // sint
v["mfug"] = d["mfu_ghost_hits"] // sint
v["unc"] = d["uncached_hits"] // sint
v["eskip"] = d["evict_skip"] // sint
v["el2skip"] = d["evict_l2_skip"] // sint
v["el2cach"] = d["evict_l2_cached"] // sint

View file

@ -3496,9 +3496,9 @@ dump_object(objset_t *os, uint64_t object, int verbosity,
zdb_nicenum(doi.doi_physical_blocks_512 << 9, asize, sizeof (asize));
zdb_nicenum(doi.doi_bonus_size, bonus_size, sizeof (bonus_size));
zdb_nicenum(doi.doi_dnodesize, dnsize, sizeof (dnsize));
(void) sprintf(fill, "%6.2f", 100.0 * doi.doi_fill_count *
doi.doi_data_block_size / (object == 0 ? DNODES_PER_BLOCK : 1) /
doi.doi_max_offset);
(void) snprintf(fill, sizeof (fill), "%6.2f", 100.0 *
doi.doi_fill_count * doi.doi_data_block_size / (object == 0 ?
DNODES_PER_BLOCK : 1) / doi.doi_max_offset);
aux[0] = '\0';
@ -4341,26 +4341,26 @@ dump_l2arc_log_entries(uint64_t log_entries,
}
static void
dump_l2arc_log_blkptr(l2arc_log_blkptr_t lbps)
dump_l2arc_log_blkptr(const l2arc_log_blkptr_t *lbps)
{
(void) printf("|\t\tdaddr: %llu\n", (u_longlong_t)lbps.lbp_daddr);
(void) printf("|\t\tdaddr: %llu\n", (u_longlong_t)lbps->lbp_daddr);
(void) printf("|\t\tpayload_asize: %llu\n",
(u_longlong_t)lbps.lbp_payload_asize);
(u_longlong_t)lbps->lbp_payload_asize);
(void) printf("|\t\tpayload_start: %llu\n",
(u_longlong_t)lbps.lbp_payload_start);
(u_longlong_t)lbps->lbp_payload_start);
(void) printf("|\t\tlsize: %llu\n",
(u_longlong_t)L2BLK_GET_LSIZE((&lbps)->lbp_prop));
(u_longlong_t)L2BLK_GET_LSIZE(lbps->lbp_prop));
(void) printf("|\t\tasize: %llu\n",
(u_longlong_t)L2BLK_GET_PSIZE((&lbps)->lbp_prop));
(u_longlong_t)L2BLK_GET_PSIZE(lbps->lbp_prop));
(void) printf("|\t\tcompralgo: %llu\n",
(u_longlong_t)L2BLK_GET_COMPRESS((&lbps)->lbp_prop));
(u_longlong_t)L2BLK_GET_COMPRESS(lbps->lbp_prop));
(void) printf("|\t\tcksumalgo: %llu\n",
(u_longlong_t)L2BLK_GET_CHECKSUM((&lbps)->lbp_prop));
(u_longlong_t)L2BLK_GET_CHECKSUM(lbps->lbp_prop));
(void) printf("|\n\n");
}
static void
dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr,
dump_l2arc_log_blocks(int fd, const l2arc_dev_hdr_phys_t *l2dhdr,
l2arc_dev_hdr_phys_t *rebuild)
{
l2arc_log_blk_phys_t this_lb;
@ -4373,13 +4373,13 @@ dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr,
if (!dump_opt['q'])
print_l2arc_log_blocks();
memcpy(lbps, l2dhdr.dh_start_lbps, sizeof (lbps));
memcpy(lbps, l2dhdr->dh_start_lbps, sizeof (lbps));
dev.l2ad_evict = l2dhdr.dh_evict;
dev.l2ad_start = l2dhdr.dh_start;
dev.l2ad_end = l2dhdr.dh_end;
dev.l2ad_evict = l2dhdr->dh_evict;
dev.l2ad_start = l2dhdr->dh_start;
dev.l2ad_end = l2dhdr->dh_end;
if (l2dhdr.dh_start_lbps[0].lbp_daddr == 0) {
if (l2dhdr->dh_start_lbps[0].lbp_daddr == 0) {
/* no log blocks to read */
if (!dump_opt['q']) {
(void) printf("No log blocks to read\n");
@ -4391,7 +4391,7 @@ dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr,
L2BLK_GET_PSIZE((&lbps[0])->lbp_prop);
}
dev.l2ad_first = !!(l2dhdr.dh_flags & L2ARC_DEV_HDR_EVICT_FIRST);
dev.l2ad_first = !!(l2dhdr->dh_flags & L2ARC_DEV_HDR_EVICT_FIRST);
for (;;) {
if (!l2arc_log_blkptr_valid(&dev, &lbps[0]))
@ -4412,7 +4412,7 @@ dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr,
failed++;
if (!dump_opt['q']) {
(void) printf("Invalid cksum\n");
dump_l2arc_log_blkptr(lbps[0]);
dump_l2arc_log_blkptr(&lbps[0]);
}
break;
}
@ -4449,11 +4449,11 @@ dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr,
(void) printf("lb[%4llu]\tmagic: %llu\n",
(u_longlong_t)rebuild->dh_lb_count,
(u_longlong_t)this_lb.lb_magic);
dump_l2arc_log_blkptr(lbps[0]);
dump_l2arc_log_blkptr(&lbps[0]);
}
if (dump_opt['l'] > 2 && !dump_opt['q'])
dump_l2arc_log_entries(l2dhdr.dh_log_entries,
dump_l2arc_log_entries(l2dhdr->dh_log_entries,
this_lb.lb_entries,
rebuild->dh_lb_count);
@ -4531,7 +4531,7 @@ dump_l2arc_header(int fd)
(u_longlong_t)l2dhdr.dh_trim_state);
}
dump_l2arc_log_blocks(fd, l2dhdr, &rebuild);
dump_l2arc_log_blocks(fd, &l2dhdr, &rebuild);
/*
* The total aligned size of log blocks and the number of log blocks
* reported in the header of the device may be less than what zdb

View file

@ -170,7 +170,7 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg)
}
zpool_close(zhp);
return (gsp->gs_vdev_guid != 0);
return (gsp->gs_devid != NULL && gsp->gs_vdev_guid != 0);
}
void

View file

@ -39,6 +39,15 @@
#include "zfs_agents.h"
#include "fmd_api.h"
/*
* Default values for the serd engine when processing checksum or io errors. The
* semantics are N <events> in T <seconds>.
*/
#define DEFAULT_CHECKSUM_N 10 /* events */
#define DEFAULT_CHECKSUM_T 600 /* seconds */
#define DEFAULT_IO_N 10 /* events */
#define DEFAULT_IO_T 600 /* seconds */
/*
* Our serd engines are named 'zfs_<pool_guid>_<vdev_guid>_{checksum,io}'. This
* #define reserves enough space for two 64-bit hex values plus the length of
@ -448,6 +457,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
zfs_case_t *zcp, *dcp;
int32_t pool_state;
uint64_t ena, pool_guid, vdev_guid;
uint64_t checksum_n, checksum_t;
uint64_t io_n, io_t;
er_timeval_t pool_load;
er_timeval_t er_when;
nvlist_t *detector;
@ -784,11 +795,21 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
if (fmd_nvl_class_match(hdl, nvl,
ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_IO))) {
if (zcp->zc_data.zc_serd_io[0] == '\0') {
if (nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_N,
&io_n) != 0) {
io_n = DEFAULT_IO_N;
}
if (nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_T,
&io_t) != 0) {
io_t = DEFAULT_IO_T;
}
zfs_serd_name(zcp->zc_data.zc_serd_io,
pool_guid, vdev_guid, "io");
fmd_serd_create(hdl, zcp->zc_data.zc_serd_io,
fmd_prop_get_int32(hdl, "io_N"),
fmd_prop_get_int64(hdl, "io_T"));
io_n,
SEC2NSEC(io_t));
zfs_case_serialize(zcp);
}
if (fmd_serd_record(hdl, zcp->zc_data.zc_serd_io, ep))
@ -813,12 +834,23 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
}
if (zcp->zc_data.zc_serd_checksum[0] == '\0') {
if (nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_N,
&checksum_n) != 0) {
checksum_n = DEFAULT_CHECKSUM_N;
}
if (nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_T,
&checksum_t) != 0) {
checksum_t = DEFAULT_CHECKSUM_T;
}
zfs_serd_name(zcp->zc_data.zc_serd_checksum,
pool_guid, vdev_guid, "checksum");
fmd_serd_create(hdl,
zcp->zc_data.zc_serd_checksum,
fmd_prop_get_int32(hdl, "checksum_N"),
fmd_prop_get_int64(hdl, "checksum_T"));
checksum_n,
SEC2NSEC(checksum_t));
zfs_case_serialize(zcp);
}
if (fmd_serd_record(hdl,

View file

@ -190,10 +190,12 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
uint64_t wholedisk = 0ULL;
uint64_t offline = 0ULL, faulted = 0ULL;
uint64_t guid = 0ULL;
uint64_t is_spare = 0;
char *physpath = NULL, *new_devid = NULL, *enc_sysfs_path = NULL;
char rawpath[PATH_MAX], fullpath[PATH_MAX];
char devpath[PATH_MAX];
int ret;
int online_flag = ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE;
boolean_t is_sd = B_FALSE;
boolean_t is_mpath_wholedisk = B_FALSE;
uint_t c;
@ -219,6 +221,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_FAULTED, &faulted);
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &guid);
(void) nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_IS_SPARE, &is_spare);
/*
* Special case:
@ -309,11 +312,13 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
}
}
if (is_spare)
online_flag |= ZFS_ONLINE_SPARE;
/*
* Attempt to online the device.
*/
if (zpool_vdev_online(zhp, fullpath,
ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE, &newstate) == 0 &&
if (zpool_vdev_online(zhp, fullpath, online_flag, &newstate) == 0 &&
(newstate == VDEV_STATE_HEALTHY ||
newstate == VDEV_STATE_DEGRADED)) {
zed_log_msg(LOG_INFO,
@ -537,6 +542,7 @@ typedef struct dev_data {
uint64_t dd_vdev_guid;
uint64_t dd_new_vdev_guid;
const char *dd_new_devid;
uint64_t dd_num_spares;
} dev_data_t;
static void
@ -547,6 +553,7 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
uint_t c, children;
nvlist_t **child;
uint64_t guid = 0;
uint64_t isspare = 0;
/*
* First iterate over any children.
@ -572,7 +579,7 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
}
/* once a vdev was matched and processed there is nothing left to do */
if (dp->dd_found)
if (dp->dd_found && dp->dd_num_spares == 0)
return;
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &guid);
@ -622,6 +629,10 @@ zfs_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *data)
}
}
if (dp->dd_found == B_TRUE && nvlist_lookup_uint64(nvl,
ZPOOL_CONFIG_IS_SPARE, &isspare) == 0 && isspare)
dp->dd_num_spares++;
(dp->dd_func)(zhp, nvl, dp->dd_islabeled);
}
@ -682,7 +693,9 @@ zfs_iter_pool(zpool_handle_t *zhp, void *data)
}
zpool_close(zhp);
return (dp->dd_found); /* cease iteration after a match */
/* cease iteration after a match */
return (dp->dd_found && dp->dd_num_spares == 0);
}
/*

View file

@ -76,6 +76,8 @@ typedef struct find_cbdata {
uint64_t cb_guid;
zpool_handle_t *cb_zhp;
nvlist_t *cb_vdev;
uint64_t cb_vdev_guid;
uint64_t cb_num_spares;
} find_cbdata_t;
static int
@ -141,6 +143,64 @@ find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, uint64_t search_guid)
return (NULL);
}
static int
remove_spares(zpool_handle_t *zhp, void *data)
{
nvlist_t *config, *nvroot;
nvlist_t **spares;
uint_t nspares;
char *devname;
find_cbdata_t *cbp = data;
uint64_t spareguid = 0;
vdev_stat_t *vs;
unsigned int c;
config = zpool_get_config(zhp, NULL);
if (nvlist_lookup_nvlist(config,
ZPOOL_CONFIG_VDEV_TREE, &nvroot) != 0) {
zpool_close(zhp);
return (0);
}
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
&spares, &nspares) != 0) {
zpool_close(zhp);
return (0);
}
for (int i = 0; i < nspares; i++) {
if (nvlist_lookup_uint64(spares[i], ZPOOL_CONFIG_GUID,
&spareguid) == 0 && spareguid == cbp->cb_vdev_guid) {
devname = zpool_vdev_name(NULL, zhp, spares[i],
B_FALSE);
nvlist_lookup_uint64_array(spares[i],
ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &c);
if (vs->vs_state != VDEV_STATE_REMOVED &&
zpool_vdev_remove_wanted(zhp, devname) == 0)
cbp->cb_num_spares++;
break;
}
}
zpool_close(zhp);
return (0);
}
/*
* Given a vdev guid, find and remove all spares associated with it.
*/
static int
find_and_remove_spares(libzfs_handle_t *zhdl, uint64_t vdev_guid)
{
find_cbdata_t cb;
cb.cb_num_spares = 0;
cb.cb_vdev_guid = vdev_guid;
zpool_iter(zhdl, remove_spares, &cb);
return (cb.cb_num_spares);
}
/*
* Given a (pool, vdev) GUID pair, find the matching pool and vdev.
*/
@ -315,6 +375,8 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
libzfs_handle_t *zhdl = zdp->zrd_hdl;
boolean_t fault_device, degrade_device;
boolean_t is_repair;
boolean_t l2arc = B_FALSE;
boolean_t spare = B_FALSE;
char *scheme;
nvlist_t *vdev = NULL;
char *uuid;
@ -323,7 +385,6 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
boolean_t is_disk;
vdev_aux_t aux;
uint64_t state = 0;
int l2arc;
vdev_stat_t *vs;
unsigned int c;
@ -343,10 +404,26 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
char *devtype;
char *devname;
if (nvlist_lookup_string(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE,
&devtype) == 0) {
if (strcmp(devtype, VDEV_TYPE_SPARE) == 0)
spare = B_TRUE;
else if (strcmp(devtype, VDEV_TYPE_L2CACHE) == 0)
l2arc = B_TRUE;
}
if (nvlist_lookup_uint64(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, &vdev_guid) != 0)
return;
if (spare) {
int nspares = find_and_remove_spares(zhdl, vdev_guid);
fmd_hdl_debug(hdl, "%d spares removed", nspares);
return;
}
if (nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_POOL_GUID,
&pool_guid) != 0 ||
nvlist_lookup_uint64(nvl, FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID,
&vdev_guid) != 0)
&pool_guid) != 0)
return;
if ((zhp = find_by_guid(zhdl, pool_guid, vdev_guid,
@ -367,10 +444,6 @@ zfs_retire_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
state == VDEV_STATE_REMOVED)
return;
l2arc = (nvlist_lookup_string(nvl,
FM_EREPORT_PAYLOAD_ZFS_VDEV_TYPE, &devtype) == 0 &&
strcmp(devtype, VDEV_TYPE_L2CACHE) == 0);
/* Remove the vdev since device is unplugged */
if (l2arc || (strcmp(class, "resource.fs.zfs.removed") == 0)) {
int status = zpool_vdev_remove_wanted(zhp, devname);

View file

@ -38,7 +38,7 @@ if [ "${ZEVENT_VDEV_STATE_STR}" != "FAULTED" ] \
fi
umask 077
note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)"
note_subject="ZFS device fault for pool ${ZEVENT_POOL} on $(hostname)"
note_pathname="$(mktemp)"
{
if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then
@ -66,7 +66,7 @@ note_pathname="$(mktemp)"
[ -n "${ZEVENT_VDEV_GUID}" ] && echo " vguid: ${ZEVENT_VDEV_GUID}"
[ -n "${ZEVENT_VDEV_DEVID}" ] && echo " devid: ${ZEVENT_VDEV_DEVID}"
echo " pool: ${ZEVENT_POOL_GUID}"
echo " pool: ${ZEVENT_POOL} (${ZEVENT_POOL_GUID})"
} > "${note_pathname}"

View file

@ -143,19 +143,20 @@ zfs_callback(zfs_handle_t *zhp, void *data)
(cb->cb_types &
(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME))) &&
zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
(void) zfs_iter_filesystems(zhp, cb->cb_flags,
zfs_callback, data);
}
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
ZFS_TYPE_BOOKMARK)) == 0) && include_snaps) {
(void) zfs_iter_snapshots(zhp,
(cb->cb_flags & ZFS_ITER_SIMPLE) != 0,
(void) zfs_iter_snapshots(zhp, cb->cb_flags,
zfs_callback, data, 0, 0);
}
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks) {
(void) zfs_iter_bookmarks(zhp, zfs_callback, data);
(void) zfs_iter_bookmarks(zhp, cb->cb_flags,
zfs_callback, data);
}
cb->cb_depth--;
@ -211,18 +212,58 @@ zfs_free_sort_columns(zfs_sort_column_t *sc)
}
}
int
zfs_sort_only_by_name(const zfs_sort_column_t *sc)
/*
* Return true if all of the properties to be sorted are populated by
* dsl_dataset_fast_stat(). Note that sc == NULL (no sort) means we
* don't need any extra properties, so returns true.
*/
boolean_t
zfs_sort_only_by_fast(const zfs_sort_column_t *sc)
{
return (sc != NULL && sc->sc_next == NULL &&
sc->sc_prop == ZFS_PROP_NAME);
while (sc != NULL) {
switch (sc->sc_prop) {
case ZFS_PROP_NAME:
case ZFS_PROP_GUID:
case ZFS_PROP_CREATETXG:
case ZFS_PROP_NUMCLONES:
case ZFS_PROP_INCONSISTENT:
case ZFS_PROP_REDACTED:
case ZFS_PROP_ORIGIN:
break;
default:
return (B_FALSE);
}
sc = sc->sc_next;
}
return (B_TRUE);
}
int
zfs_sort_only_by_createtxg(const zfs_sort_column_t *sc)
boolean_t
zfs_list_only_by_fast(const zprop_list_t *p)
{
return (sc != NULL && sc->sc_next == NULL &&
sc->sc_prop == ZFS_PROP_CREATETXG);
if (p == NULL) {
/* NULL means 'all' so we can't use simple mode */
return (B_FALSE);
}
while (p != NULL) {
switch (p->pl_prop) {
case ZFS_PROP_NAME:
case ZFS_PROP_GUID:
case ZFS_PROP_CREATETXG:
case ZFS_PROP_NUMCLONES:
case ZFS_PROP_INCONSISTENT:
case ZFS_PROP_REDACTED:
case ZFS_PROP_ORIGIN:
break;
default:
return (B_FALSE);
}
p = p->pl_next;
}
return (B_TRUE);
}
static int

View file

@ -40,20 +40,12 @@ typedef struct zfs_sort_column {
boolean_t sc_reverse;
} zfs_sort_column_t;
#define ZFS_ITER_RECURSE (1 << 0)
#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
#define ZFS_ITER_DEPTH_LIMIT (1 << 3)
#define ZFS_ITER_RECVD_PROPS (1 << 4)
#define ZFS_ITER_LITERAL_PROPS (1 << 5)
#define ZFS_ITER_SIMPLE (1 << 6)
int zfs_for_each(int, char **, int options, zfs_type_t,
zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
void zfs_free_sort_columns(zfs_sort_column_t *);
int zfs_sort_only_by_name(const zfs_sort_column_t *);
int zfs_sort_only_by_createtxg(const zfs_sort_column_t *);
boolean_t zfs_sort_only_by_fast(const zfs_sort_column_t *);
boolean_t zfs_list_only_by_fast(const zprop_list_t *);
#ifdef __cplusplus
}

View file

@ -327,15 +327,15 @@ get_usage(zfs_help_t idx)
case HELP_ROLLBACK:
return (gettext("\trollback [-rRf] <snapshot>\n"));
case HELP_SEND:
return (gettext("\tsend [-DLPbcehnpsvw] "
return (gettext("\tsend [-DLPbcehnpsVvw] "
"[-i|-I snapshot]\n"
"\t [-R [-X dataset[,dataset]...]] <snapshot>\n"
"\tsend [-DnvPLecw] [-i snapshot|bookmark] "
"\tsend [-DnVvPLecw] [-i snapshot|bookmark] "
"<filesystem|volume|snapshot>\n"
"\tsend [-DnPpvLec] [-i bookmark|snapshot] "
"\tsend [-DnPpVvLec] [-i bookmark|snapshot] "
"--redact <bookmark> <snapshot>\n"
"\tsend [-nvPe] -t <receive_resume_token>\n"
"\tsend [-Pnv] --saved filesystem\n"));
"\tsend [-nVvPe] -t <receive_resume_token>\n"
"\tsend [-PnVv] --saved filesystem\n"));
case HELP_SET:
return (gettext("\tset <property=value> ... "
"<filesystem|volume|snapshot> ...\n"));
@ -1531,7 +1531,7 @@ destroy_print_snapshots(zfs_handle_t *fs_zhp, destroy_cbdata_t *cb)
int err;
assert(cb->cb_firstsnap == NULL);
assert(cb->cb_prevsnap == NULL);
err = zfs_iter_snapshots_sorted(fs_zhp, destroy_print_cb, cb, 0, 0);
err = zfs_iter_snapshots_sorted(fs_zhp, 0, destroy_print_cb, cb, 0, 0);
if (cb->cb_firstsnap != NULL) {
uint64_t used = 0;
if (err == 0) {
@ -1557,7 +1557,7 @@ snapshot_to_nvl_cb(zfs_handle_t *zhp, void *arg)
if (!cb->cb_doclones && !cb->cb_defer_destroy) {
cb->cb_target = zhp;
cb->cb_first = B_TRUE;
err = zfs_iter_dependents(zhp, B_TRUE,
err = zfs_iter_dependents(zhp, 0, B_TRUE,
destroy_check_dependent, cb);
}
@ -1575,7 +1575,8 @@ gather_snapshots(zfs_handle_t *zhp, void *arg)
destroy_cbdata_t *cb = arg;
int err = 0;
err = zfs_iter_snapspec(zhp, cb->cb_snapspec, snapshot_to_nvl_cb, cb);
err = zfs_iter_snapspec(zhp, 0, cb->cb_snapspec,
snapshot_to_nvl_cb, cb);
if (err == ENOENT)
err = 0;
if (err != 0)
@ -1588,7 +1589,7 @@ gather_snapshots(zfs_handle_t *zhp, void *arg)
}
if (cb->cb_recurse)
err = zfs_iter_filesystems(zhp, gather_snapshots, cb);
err = zfs_iter_filesystems(zhp, 0, gather_snapshots, cb);
out:
zfs_close(zhp);
@ -1613,7 +1614,7 @@ destroy_clones(destroy_cbdata_t *cb)
* false while destroying the clones.
*/
cb->cb_defer_destroy = B_FALSE;
err = zfs_iter_dependents(zhp, B_FALSE,
err = zfs_iter_dependents(zhp, 0, B_FALSE,
destroy_callback, cb);
cb->cb_defer_destroy = defer;
zfs_close(zhp);
@ -1824,7 +1825,7 @@ zfs_do_destroy(int argc, char **argv)
*/
cb.cb_first = B_TRUE;
if (!cb.cb_doclones &&
zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
zfs_iter_dependents(zhp, 0, B_TRUE, destroy_check_dependent,
&cb) != 0) {
rv = 1;
goto out;
@ -1835,7 +1836,7 @@ zfs_do_destroy(int argc, char **argv)
goto out;
}
cb.cb_batchedsnaps = fnvlist_alloc();
if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
if (zfs_iter_dependents(zhp, 0, B_FALSE, destroy_callback,
&cb) != 0) {
rv = 1;
goto out;
@ -3659,16 +3660,6 @@ found3:;
argc -= optind;
argv += optind;
/*
* If we are only going to list snapshot names and sort by name or
* by createtxg, then we can use faster version.
*/
if (strcmp(fields, "name") == 0 &&
(zfs_sort_only_by_name(sortcol) ||
zfs_sort_only_by_createtxg(sortcol))) {
flags |= ZFS_ITER_SIMPLE;
}
/*
* If "-o space" and no types were specified, don't display snapshots.
*/
@ -3696,6 +3687,15 @@ found3:;
cb.cb_first = B_TRUE;
/*
* If we are only going to list and sort by properties that are "fast"
* then we can use "simple" mode and avoid populating the properties
* nvlist.
*/
if (zfs_list_only_by_fast(cb.cb_proplist) &&
zfs_sort_only_by_fast(sortcol))
flags |= ZFS_ITER_SIMPLE;
ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist,
limit, list_callback, &cb);
@ -4006,7 +4006,7 @@ rollback_check(zfs_handle_t *zhp, void *data)
}
if (cbp->cb_recurse) {
if (zfs_iter_dependents(zhp, B_TRUE,
if (zfs_iter_dependents(zhp, 0, B_TRUE,
rollback_check_dependent, cbp) != 0) {
zfs_close(zhp);
return (-1);
@ -4105,10 +4105,10 @@ zfs_do_rollback(int argc, char **argv)
if (cb.cb_create > 0)
min_txg = cb.cb_create;
if ((ret = zfs_iter_snapshots(zhp, B_FALSE, rollback_check, &cb,
if ((ret = zfs_iter_snapshots(zhp, 0, rollback_check, &cb,
min_txg, 0)) != 0)
goto out;
if ((ret = zfs_iter_bookmarks(zhp, rollback_check, &cb)) != 0)
if ((ret = zfs_iter_bookmarks(zhp, 0, rollback_check, &cb)) != 0)
goto out;
if ((ret = cb.cb_error) != 0)
@ -4250,7 +4250,7 @@ zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
free(name);
if (sd->sd_recursive)
rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
rv = zfs_iter_filesystems(zhp, 0, zfs_snapshot_cb, sd);
zfs_close(zhp);
return (rv);
}
@ -4388,6 +4388,7 @@ zfs_do_send(int argc, char **argv)
{"props", no_argument, NULL, 'p'},
{"parsable", no_argument, NULL, 'P'},
{"dedup", no_argument, NULL, 'D'},
{"proctitle", no_argument, NULL, 'V'},
{"verbose", no_argument, NULL, 'v'},
{"dryrun", no_argument, NULL, 'n'},
{"large-block", no_argument, NULL, 'L'},
@ -4403,7 +4404,7 @@ zfs_do_send(int argc, char **argv)
};
/* check options */
while ((c = getopt_long(argc, argv, ":i:I:RsDpvnPLeht:cwbd:SX:",
while ((c = getopt_long(argc, argv, ":i:I:RsDpVvnPLeht:cwbd:SX:",
long_options, NULL)) != -1) {
switch (c) {
case 'X':
@ -4452,6 +4453,9 @@ zfs_do_send(int argc, char **argv)
case 'P':
flags.parsable = B_TRUE;
break;
case 'V':
flags.progressastitle = B_TRUE;
break;
case 'v':
flags.verbosity++;
flags.progress = B_TRUE;
@ -6310,7 +6314,7 @@ zfs_do_allow_unallow_impl(int argc, char **argv, boolean_t un)
if (un && opts.recursive) {
struct deleg_perms data = { un, update_perm_nvl };
if (zfs_iter_filesystems(zhp, set_deleg_perms,
if (zfs_iter_filesystems(zhp, 0, set_deleg_perms,
&data) != 0)
goto cleanup0;
}
@ -6688,7 +6692,7 @@ get_one_dataset(zfs_handle_t *zhp, void *data)
/*
* Iterate over any nested datasets.
*/
if (zfs_iter_filesystems(zhp, get_one_dataset, data) != 0) {
if (zfs_iter_filesystems(zhp, 0, get_one_dataset, data) != 0) {
zfs_close(zhp);
return (1);
}
@ -8668,6 +8672,7 @@ main(int argc, char **argv)
int i = 0;
const char *cmdname;
char **newargv;
extern char **environ;
(void) setlocale(LC_ALL, "");
(void) setlocale(LC_NUMERIC, "C");
@ -8725,6 +8730,8 @@ main(int argc, char **argv)
libzfs_print_on_error(g_zfs, B_TRUE);
zfs_setproctitle_init(argc, argv, environ);
/*
* Many commands modify input strings for string parsing reasons.
* We create a copy to protect the original argv.

View file

@ -30,6 +30,7 @@
* result in corrupted pools.
*/
#include <zfs_prop.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
@ -646,8 +647,6 @@ zhack_do_label(int argc, char **argv)
int
main(int argc, char **argv)
{
extern void zfs_prop_init(void);
char *path[MAX_NUM_PATHS];
const char *subcommand;
int rv = 0;

View file

@ -421,7 +421,8 @@ get_usage(zpool_help_t idx)
return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
"<\"all\" | property[,...]> <pool> ...\n"));
case HELP_SET:
return (gettext("\tset <property=value> <pool> \n"));
return (gettext("\tset <property=value> <pool>\n"
"\tset <vdev_property=value> <pool> <vdev>\n"));
case HELP_SPLIT:
return (gettext("\tsplit [-gLnPl] [-R altroot] [-o mntopts]\n"
"\t [-o property=value] <pool> <newpool> "
@ -5184,21 +5185,14 @@ get_stat_flags(zpool_list_t *list)
static int
is_vdev_cb(void *zhp_data, nvlist_t *nv, void *cb_data)
{
uint64_t guid;
vdev_cbdata_t *cb = cb_data;
char *name = NULL;
int ret = 1; /* assume match */
zpool_handle_t *zhp = zhp_data;
name = zpool_vdev_name(g_zfs, zhp, nv, cb->cb_name_flags);
if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) != 0)
return (0);
if (strcmp(name, cb->cb_names[0])) {
free(name);
name = zpool_vdev_name(g_zfs, zhp, nv, VDEV_NAME_GUID);
ret = (strcmp(name, cb->cb_names[0]) == 0);
}
free(name);
return (ret);
return (guid == zpool_vdev_path_to_guid(zhp, cb->cb_names[0]));
}
/*
@ -5429,7 +5423,13 @@ print_zpool_dir_scripts(char *dirpath)
if ((dir = opendir(dirpath)) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir(dir)) != NULL) {
sprintf(fullpath, "%s/%s", dirpath, ent->d_name);
if (snprintf(fullpath, sizeof (fullpath), "%s/%s",
dirpath, ent->d_name) >= sizeof (fullpath)) {
(void) fprintf(stderr,
gettext("internal error: "
"ZPOOL_SCRIPTS_PATH too large.\n"));
exit(1);
}
/* Print the scripts */
if (stat(fullpath, &dir_stat) == 0)
@ -8593,37 +8593,17 @@ status_callback(zpool_handle_t *zhp, void *data)
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
&nerr) == 0) {
nvlist_t *nverrlist = NULL;
/*
* If the approximate error count is small, get a
* precise count by fetching the entire log and
* uniquifying the results.
*/
if (nerr > 0 && nerr < 100 && !cbp->cb_verbose &&
zpool_get_errlog(zhp, &nverrlist) == 0) {
nvpair_t *elem;
elem = NULL;
nerr = 0;
while ((elem = nvlist_next_nvpair(nverrlist,
elem)) != NULL) {
nerr++;
}
}
nvlist_free(nverrlist);
(void) printf("\n");
if (nerr == 0)
(void) printf(gettext("errors: No known data "
"errors\n"));
else if (!cbp->cb_verbose)
if (nerr == 0) {
(void) printf(gettext(
"errors: No known data errors\n"));
} else if (!cbp->cb_verbose) {
(void) printf(gettext("errors: %llu data "
"errors, use '-v' for a list\n"),
(u_longlong_t)nerr);
else
} else {
print_error_log(zhp);
}
}
if (cbp->cb_dedup_stats)
@ -8802,7 +8782,7 @@ check_unsupp_fs(zfs_handle_t *zhp, void *unsupp_fs)
(*count)++;
}
zfs_iter_filesystems(zhp, check_unsupp_fs, unsupp_fs);
zfs_iter_filesystems(zhp, 0, check_unsupp_fs, unsupp_fs);
zfs_close(zhp);
@ -10348,29 +10328,27 @@ zpool_do_set(int argc, char **argv)
argc -= 2;
argv += 2;
if (are_vdevs_in_pool(argc, argv, NULL, &cb.cb_vdevs)) {
/* Argument is a vdev */
cb.cb_vdevs.cb_names = argv;
cb.cb_vdevs.cb_names_count = 1;
cb.cb_type = ZFS_TYPE_VDEV;
argc = 0; /* No pools to process */
} else if (are_all_pools(1, argv)) {
/* The first arg is a pool name */
if (are_vdevs_in_pool(argc - 1, argv + 1, argv[0],
&cb.cb_vdevs)) {
/* 2nd argument is a vdev */
cb.cb_vdevs.cb_names = argv + 1;
cb.cb_vdevs.cb_names_count = 1;
cb.cb_type = ZFS_TYPE_VDEV;
argc = 1; /* One pool to process */
} else if (argc > 1) {
(void) fprintf(stderr,
gettext("too many pool names\n"));
usage(B_FALSE);
}
/* argv[0] is pool name */
if (!is_pool(argv[0])) {
(void) fprintf(stderr,
gettext("cannot open '%s': is not a pool\n"), argv[0]);
return (EINVAL);
}
error = for_each_pool(argc, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
/* argv[1], when supplied, is vdev name */
if (argc == 2) {
if (!are_vdevs_in_pool(1, argv + 1, argv[0], &cb.cb_vdevs)) {
(void) fprintf(stderr, gettext(
"cannot find '%s' in '%s': device not in pool\n"),
argv[1], argv[0]);
return (EINVAL);
}
cb.cb_vdevs.cb_names = argv + 1;
cb.cb_vdevs.cb_names_count = 1;
cb.cb_type = ZFS_TYPE_VDEV;
}
error = for_each_pool(1, argv, B_TRUE, NULL, ZFS_TYPE_POOL,
B_FALSE, set_callback, &cb);
return (error);

View file

@ -158,6 +158,8 @@ zstream_do_decompress(int argc, char *argv[])
}
fletcher_4_init();
int begin = 0;
boolean_t seen = B_FALSE;
while (sfread(drr, sizeof (*drr), stdin) != 0) {
struct drr_write *drrw;
uint64_t payload_size = 0;
@ -174,8 +176,13 @@ zstream_do_decompress(int argc, char *argv[])
case DRR_BEGIN:
{
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
VERIFY0(begin++);
seen = B_TRUE;
uint32_t sz = drr->drr_payloadlen;
VERIFY3U(sz, <=, 1U << 28);
int sz = drr->drr_payloadlen;
if (sz != 0) {
if (sz > bufsz) {
buf = realloc(buf, sz);
@ -191,6 +198,13 @@ zstream_do_decompress(int argc, char *argv[])
case DRR_END:
{
struct drr_end *drre = &drr->drr_u.drr_end;
/*
* We would prefer to just check --begin == 0, but
* replication streams have an end of stream END
* record, so we must avoid tripping it.
*/
VERIFY3B(seen, ==, B_TRUE);
begin--;
/*
* Use the recalculated checksum, unless this is
* the END record of a stream package, which has
@ -204,6 +218,7 @@ zstream_do_decompress(int argc, char *argv[])
case DRR_OBJECT:
{
struct drr_object *drro = &drr->drr_u.drr_object;
VERIFY3S(begin, ==, 1);
if (drro->drr_bonuslen > 0) {
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
@ -215,12 +230,14 @@ zstream_do_decompress(int argc, char *argv[])
case DRR_SPILL:
{
struct drr_spill *drrs = &drr->drr_u.drr_spill;
VERIFY3S(begin, ==, 1);
payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs);
(void) sfread(buf, payload_size, stdin);
break;
}
case DRR_WRITE_BYREF:
VERIFY3S(begin, ==, 1);
fprintf(stderr,
"Deduplicated streams are not supported\n");
exit(1);
@ -228,6 +245,7 @@ zstream_do_decompress(int argc, char *argv[])
case DRR_WRITE:
{
VERIFY3S(begin, ==, 1);
drrw = &thedrr.drr_u.drr_write;
payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
ENTRY *p;
@ -321,6 +339,7 @@ zstream_do_decompress(int argc, char *argv[])
case DRR_WRITE_EMBEDDED:
{
VERIFY3S(begin, ==, 1);
struct drr_write_embedded *drrwe =
&drr->drr_u.drr_write_embedded;
payload_size =
@ -332,6 +351,7 @@ zstream_do_decompress(int argc, char *argv[])
case DRR_FREEOBJECTS:
case DRR_FREE:
case DRR_OBJECT_RANGE:
VERIFY3S(begin, ==, 1);
break;
default:

View file

@ -138,6 +138,8 @@ zstream_do_recompress(int argc, char *argv[])
fletcher_4_init();
zio_init();
zstd_init();
int begin = 0;
boolean_t seen = B_FALSE;
while (sfread(drr, sizeof (*drr), stdin) != 0) {
struct drr_write *drrw;
uint64_t payload_size = 0;
@ -155,8 +157,13 @@ zstream_do_recompress(int argc, char *argv[])
case DRR_BEGIN:
{
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
VERIFY0(begin++);
seen = B_TRUE;
uint32_t sz = drr->drr_payloadlen;
VERIFY3U(sz, <=, 1U << 28);
int sz = drr->drr_payloadlen;
if (sz != 0) {
if (sz > bufsz) {
buf = realloc(buf, sz);
@ -172,6 +179,13 @@ zstream_do_recompress(int argc, char *argv[])
case DRR_END:
{
struct drr_end *drre = &drr->drr_u.drr_end;
/*
* We would prefer to just check --begin == 0, but
* replication streams have an end of stream END
* record, so we must avoid tripping it.
*/
VERIFY3B(seen, ==, B_TRUE);
begin--;
/*
* Use the recalculated checksum, unless this is
* the END record of a stream package, which has
@ -185,6 +199,7 @@ zstream_do_recompress(int argc, char *argv[])
case DRR_OBJECT:
{
struct drr_object *drro = &drr->drr_u.drr_object;
VERIFY3S(begin, ==, 1);
if (drro->drr_bonuslen > 0) {
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
@ -196,12 +211,14 @@ zstream_do_recompress(int argc, char *argv[])
case DRR_SPILL:
{
struct drr_spill *drrs = &drr->drr_u.drr_spill;
VERIFY3S(begin, ==, 1);
payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs);
(void) sfread(buf, payload_size, stdin);
break;
}
case DRR_WRITE_BYREF:
VERIFY3S(begin, ==, 1);
fprintf(stderr,
"Deduplicated streams are not supported\n");
exit(1);
@ -209,6 +226,7 @@ zstream_do_recompress(int argc, char *argv[])
case DRR_WRITE:
{
VERIFY3S(begin, ==, 1);
drrw = &thedrr.drr_u.drr_write;
payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
/*
@ -295,6 +313,7 @@ zstream_do_recompress(int argc, char *argv[])
{
struct drr_write_embedded *drrwe =
&drr->drr_u.drr_write_embedded;
VERIFY3S(begin, ==, 1);
payload_size =
P2ROUNDUP((uint64_t)drrwe->drr_psize, 8);
(void) sfread(buf, payload_size, stdin);
@ -304,6 +323,7 @@ zstream_do_recompress(int argc, char *argv[])
case DRR_FREEOBJECTS:
case DRR_FREE:
case DRR_OBJECT_RANGE:
VERIFY3S(begin, ==, 1);
break;
default:

View file

@ -222,6 +222,8 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
char *buf = safe_calloc(bufsz);
FILE *ofp = fdopen(infd, "r");
long offset = ftell(ofp);
int begin = 0;
boolean_t seen = B_FALSE;
while (sfread(drr, sizeof (*drr), ofp) != 0) {
num_records++;
@ -240,6 +242,8 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
struct drr_begin *drrb = &drr->drr_u.drr_begin;
int fflags;
ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
VERIFY0(begin++);
seen = B_TRUE;
assert(drrb->drr_magic == DMU_BACKUP_MAGIC);
@ -250,7 +254,10 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
/* cppcheck-suppress syntaxError */
DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
int sz = drr->drr_payloadlen;
uint32_t sz = drr->drr_payloadlen;
VERIFY3U(sz, <=, 1U << 28);
if (sz != 0) {
if (sz > bufsz) {
free(buf);
@ -266,6 +273,13 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
case DRR_END:
{
struct drr_end *drre = &drr->drr_u.drr_end;
/*
* We would prefer to just check --begin == 0, but
* replication streams have an end of stream END
* record, so we must avoid tripping it.
*/
VERIFY3B(seen, ==, B_TRUE);
begin--;
/*
* Use the recalculated checksum, unless this is
* the END record of a stream package, which has
@ -279,6 +293,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
case DRR_OBJECT:
{
struct drr_object *drro = &drr->drr_u.drr_object;
VERIFY3S(begin, ==, 1);
if (drro->drr_bonuslen > 0) {
payload_size = DRR_OBJECT_PAYLOAD_SIZE(drro);
@ -290,6 +305,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
case DRR_SPILL:
{
struct drr_spill *drrs = &drr->drr_u.drr_spill;
VERIFY3S(begin, ==, 1);
payload_size = DRR_SPILL_PAYLOAD_SIZE(drrs);
(void) sfread(buf, payload_size, ofp);
break;
@ -299,6 +315,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
{
struct drr_write_byref drrwb =
drr->drr_u.drr_write_byref;
VERIFY3S(begin, ==, 1);
num_write_byref_records++;
@ -334,6 +351,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
case DRR_WRITE:
{
struct drr_write *drrw = &drr->drr_u.drr_write;
VERIFY3S(begin, ==, 1);
payload_size = DRR_WRITE_PAYLOAD_SIZE(drrw);
(void) sfread(buf, payload_size, ofp);
@ -346,6 +364,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
{
struct drr_write_embedded *drrwe =
&drr->drr_u.drr_write_embedded;
VERIFY3S(begin, ==, 1);
payload_size =
P2ROUNDUP((uint64_t)drrwe->drr_psize, 8);
(void) sfread(buf, payload_size, ofp);
@ -355,6 +374,7 @@ zfs_redup_stream(int infd, int outfd, boolean_t verbose)
case DRR_FREEOBJECTS:
case DRR_FREE:
case DRR_OBJECT_RANGE:
VERIFY3S(begin, ==, 1);
break;
default:

View file

@ -443,7 +443,7 @@ static ztest_info_t ztest_info[] = {
ZTI_INIT(ztest_dmu_commit_callbacks, 1, &zopt_always),
ZTI_INIT(ztest_zap, 30, &zopt_always),
ZTI_INIT(ztest_zap_parallel, 100, &zopt_always),
ZTI_INIT(ztest_split_pool, 1, &zopt_always),
ZTI_INIT(ztest_split_pool, 1, &zopt_sometimes),
ZTI_INIT(ztest_zil_commit, 1, &zopt_incessant),
ZTI_INIT(ztest_zil_remount, 1, &zopt_sometimes),
ZTI_INIT(ztest_dmu_read_write_zcopy, 1, &zopt_often),
@ -1133,14 +1133,14 @@ process_options(int argc, char **argv)
const char *invalid_what = "ztest";
char *val = zo->zo_alt_ztest;
if (0 != access(val, X_OK) ||
(strrchr(val, '/') == NULL && (errno = EINVAL)))
(strrchr(val, '/') == NULL && (errno == EINVAL)))
goto invalid;
int dirlen = strrchr(val, '/') - val;
strlcpy(zo->zo_alt_libpath, val,
MIN(sizeof (zo->zo_alt_libpath), dirlen + 1));
invalid_what = "library path", val = zo->zo_alt_libpath;
if (strrchr(val, '/') == NULL && (errno = EINVAL))
if (strrchr(val, '/') == NULL && (errno == EINVAL))
goto invalid;
*strrchr(val, '/') = '\0';
strlcat(val, "/lib", sizeof (zo->zo_alt_libpath));
@ -2790,12 +2790,12 @@ ztest_io(ztest_ds_t *zd, uint64_t object, uint64_t offset)
err = ztest_dsl_prop_set_uint64(zd->zd_name,
ZFS_PROP_CHECKSUM, spa_dedup_checksum(ztest_spa),
B_FALSE);
VERIFY(err == 0 || err == ENOSPC);
ASSERT(err == 0 || err == ENOSPC);
err = ztest_dsl_prop_set_uint64(zd->zd_name,
ZFS_PROP_COMPRESSION,
ztest_random_dsl_prop(ZFS_PROP_COMPRESSION),
B_FALSE);
VERIFY(err == 0 || err == ENOSPC);
ASSERT(err == 0 || err == ENOSPC);
(void) pthread_rwlock_unlock(&ztest_name_lock);
VERIFY0(dmu_read(zd->zd_os, object, offset, blocksize, data,
@ -3347,8 +3347,9 @@ ztest_vdev_class_add(ztest_ds_t *zd, uint64_t id)
spa_special_class(spa)->mc_groups == 1 && ztest_random(2) == 0) {
if (ztest_opts.zo_verbose >= 3)
(void) printf("Enabling special VDEV small blocks\n");
(void) ztest_dsl_prop_set_uint64(zd->zd_name,
error = ztest_dsl_prop_set_uint64(zd->zd_name,
ZFS_PROP_SPECIAL_SMALL_BLOCKS, 32768, B_FALSE);
ASSERT(error == 0 || error == ENOSPC);
}
mutex_exit(&ztest_vdev_lock);
@ -3597,6 +3598,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
int newvd_is_spare = B_FALSE;
int newvd_is_dspare = B_FALSE;
int oldvd_is_log;
int oldvd_is_special;
int error, expected_error;
if (ztest_opts.zo_mmp_test)
@ -3671,6 +3673,9 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
oldguid = oldvd->vdev_guid;
oldsize = vdev_get_min_asize(oldvd);
oldvd_is_log = oldvd->vdev_top->vdev_islog;
oldvd_is_special =
oldvd->vdev_top->vdev_alloc_bias == VDEV_BIAS_SPECIAL ||
oldvd->vdev_top->vdev_alloc_bias == VDEV_BIAS_DEDUP;
(void) strlcpy(oldpath, oldvd->vdev_path, MAXPATHLEN);
pvd = oldvd->vdev_parent;
pguid = pvd->vdev_guid;
@ -3749,7 +3754,8 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
pvd->vdev_ops == &vdev_replacing_ops ||
pvd->vdev_ops == &vdev_spare_ops))
expected_error = ENOTSUP;
else if (newvd_is_spare && (!replacing || oldvd_is_log))
else if (newvd_is_spare &&
(!replacing || oldvd_is_log || oldvd_is_special))
expected_error = ENOTSUP;
else if (newvd == oldvd)
expected_error = replacing ? 0 : EBUSY;
@ -4293,7 +4299,7 @@ ztest_snapshot_create(char *osname, uint64_t id)
ztest_record_enospc(FTAG);
return (B_FALSE);
}
if (error != 0 && error != EEXIST) {
if (error != 0 && error != EEXIST && error != ECHRNG) {
fatal(B_FALSE, "ztest_snapshot_create(%s@%s) = %d", osname,
snapname, error);
}
@ -4310,7 +4316,7 @@ ztest_snapshot_destroy(char *osname, uint64_t id)
osname, id);
error = dsl_destroy_snapshot(snapname, B_FALSE);
if (error != 0 && error != ENOENT)
if (error != 0 && error != ENOENT && error != ECHRNG)
fatal(B_FALSE, "ztest_snapshot_destroy(%s) = %d",
snapname, error);
return (B_TRUE);
@ -4359,9 +4365,16 @@ ztest_dmu_objset_create_destroy(ztest_ds_t *zd, uint64_t id)
/*
* Verify that the destroyed dataset is no longer in the namespace.
* It may still be present if the destroy above fails with ENOSPC.
*/
VERIFY3U(ENOENT, ==, ztest_dmu_objset_own(name, DMU_OST_OTHER, B_TRUE,
B_TRUE, FTAG, &os));
error = ztest_dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, B_TRUE,
FTAG, &os);
if (error == 0) {
dmu_objset_disown(os, B_TRUE, FTAG);
ztest_record_enospc(FTAG);
goto out;
}
VERIFY3U(ENOENT, ==, error);
/*
* Verify that we can create a new dataset.
@ -5834,12 +5847,15 @@ ztest_dsl_prop_get_set(ztest_ds_t *zd, uint64_t id)
(void) pthread_rwlock_rdlock(&ztest_name_lock);
for (int p = 0; p < sizeof (proplist) / sizeof (proplist[0]); p++)
(void) ztest_dsl_prop_set_uint64(zd->zd_name, proplist[p],
for (int p = 0; p < sizeof (proplist) / sizeof (proplist[0]); p++) {
int error = ztest_dsl_prop_set_uint64(zd->zd_name, proplist[p],
ztest_random_dsl_prop(proplist[p]), (int)ztest_random(2));
ASSERT(error == 0 || error == ENOSPC);
}
VERIFY0(ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_RECORDSIZE,
ztest_random_blocksize(), (int)ztest_random(2)));
int error = ztest_dsl_prop_set_uint64(zd->zd_name, ZFS_PROP_RECORDSIZE,
ztest_random_blocksize(), (int)ztest_random(2));
ASSERT(error == 0 || error == ENOSPC);
(void) pthread_rwlock_unlock(&ztest_name_lock);
}
@ -6313,7 +6329,7 @@ ztest_scrub_impl(spa_t *spa)
while (dsl_scan_scrubbing(spa_get_dsl(spa)))
txg_wait_synced(spa_get_dsl(spa), 0);
if (spa_get_errlog_size(spa) > 0)
if (spa_approx_errlog_size(spa) > 0)
return (ECKSUM);
ztest_pool_scrubbed = B_TRUE;

View file

@ -97,23 +97,13 @@ AC_DEFUN([AX_PYTHON_DEVEL],[
# Check for a version of Python >= 2.1.0
#
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
ac_supports_python_ver=`cat<<EOD | $PYTHON -
from __future__ import print_function;
import sys;
try:
from packaging import version;
except ImportError:
from distlib import version;
ver = sys.version.split ()[[0]];
(tst_cmp, tst_ver) = ">= '2.1.0'".split ();
tst_ver = tst_ver.strip ("'");
eval ("print (version.LegacyVersion (ver)"+ tst_cmp +"version.LegacyVersion (tst_ver))")
EOD`
ac_supports_python_ver=`$PYTHON -c "import sys; \
ver = sys.version.split ()[[0]]; \
print (ver >= '2.1.0')"`
if test "$ac_supports_python_ver" != "True"; then
if test -z "$PYTHON_NOVERSIONCHECK"; then
AC_MSG_RESULT([no])
m4_ifvaln([$2],[$2],[
AC_MSG_FAILURE([
AC_MSG_FAILURE([
This version of the AC@&t@_PYTHON_DEVEL macro
doesn't work properly with versions of Python before
2.1.0. You may need to re-run configure, setting the
@ -122,7 +112,6 @@ PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
to something else than an empty string.
])
])
else
AC_MSG_RESULT([skip at user request])
fi
@ -131,37 +120,47 @@ to something else than an empty string.
fi
#
# if the macro parameter ``version'' is set, honour it
# If the macro parameter ``version'' is set, honour it.
# A Python shim class, VPy, is used to implement correct version comparisons via
# string expressions, since e.g. a naive textual ">= 2.7.3" won't work for
# Python 2.7.10 (the ".1" being evaluated as less than ".3").
#
if test -n "$1"; then
AC_MSG_CHECKING([for a version of Python $1])
# Why the strip ()? Because if we don't, version.parse
# will, for example, report 3.10.0 >= '3.11.0'
ac_supports_python_ver=`cat<<EOD | $PYTHON -
from __future__ import print_function;
import sys;
try:
from packaging import version;
except ImportError:
from distlib import version;
ver = sys.version.split ()[[0]];
(tst_cmp, tst_ver) = "$1".split ();
tst_ver = tst_ver.strip ("'");
eval ("print (version.LegacyVersion (ver)"+ tst_cmp +"version.LegacyVersion (tst_ver))")
EOD`
cat << EOF > ax_python_devel_vpy.py
class VPy:
def vtup(self, s):
return tuple(map(int, s.strip().replace("rc", ".").split(".")))
def __init__(self):
import sys
self.vpy = tuple(sys.version_info)
def __eq__(self, s):
return self.vpy == self.vtup(s)
def __ne__(self, s):
return self.vpy != self.vtup(s)
def __lt__(self, s):
return self.vpy < self.vtup(s)
def __gt__(self, s):
return self.vpy > self.vtup(s)
def __le__(self, s):
return self.vpy <= self.vtup(s)
def __ge__(self, s):
return self.vpy >= self.vtup(s)
EOF
ac_supports_python_ver=`$PYTHON -c "import ax_python_devel_vpy; \
ver = ax_python_devel_vpy.VPy(); \
print (ver $1)"`
rm -rf ax_python_devel_vpy*.py* __pycache__/ax_python_devel_vpy*.py*
if test "$ac_supports_python_ver" = "True"; then
AC_MSG_RESULT([yes])
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
m4_ifvaln([$2],[$2],[
AC_MSG_ERROR([this package requires Python $1.
AC_MSG_ERROR([this package requires Python $1.
If you have it installed, but it isn't the default Python
interpreter in your system path, please pass the PYTHON_VERSION
variable to configure. See ``configure --help'' for reference.
])
PYTHON_VERSION=""
])
PYTHON_VERSION=""
fi
fi

View file

@ -1,14 +1,17 @@
PHONY += deb-kmod deb-dkms deb-utils deb deb-local
PHONY += deb-kmod deb-dkms deb-utils deb deb-local native-deb-local \
native-deb-utils native-deb-kmod native-deb
deb-local:
native-deb-local:
@(if test "${HAVE_DPKGBUILD}" = "no"; then \
echo -e "\n" \
"*** Required util ${DPKGBUILD} missing. Please install the\n" \
"*** package for your distribution which provides ${DPKGBUILD},\n" \
"*** re-run configure, and try again.\n"; \
exit 1; \
fi; \
if test "${HAVE_ALIEN}" = "no"; then \
fi)
deb-local: native-deb-local
@(if test "${HAVE_ALIEN}" = "no"; then \
echo -e "\n" \
"*** Required util ${ALIEN} missing. Please install the\n" \
"*** package for your distribution which provides ${ALIEN},\n" \
@ -67,7 +70,7 @@ deb-utils: deb-local rpm-utils-initramfs
## to do this, so we install a shim onto the path which calls the real
## dh_shlibdeps with the required arguments.
path_prepend=`mktemp -d /tmp/intercept.XXXXXX`; \
echo "#$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
echo "#!$(SHELL)" > $${path_prepend}/dh_shlibdeps; \
echo "`which dh_shlibdeps` -- \
-xlibuutil3linux -xlibnvpair3linux -xlibzfs5linux -xlibzpool5linux" \
>> $${path_prepend}/dh_shlibdeps; \
@ -75,7 +78,7 @@ deb-utils: deb-local rpm-utils-initramfs
## Debianized packages from the auto-generated dependencies of the new debs,
## which should NOT be mixed with the alien-generated debs created here
chmod +x $${path_prepend}/dh_shlibdeps; \
env PATH=$${path_prepend}:$${PATH} \
env "PATH=$${path_prepend}:$${PATH}" \
fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
$$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
$$pkg8 $$pkg9 $$pkg10 $$pkg11 || exit 1; \
@ -85,3 +88,16 @@ deb-utils: deb-local rpm-utils-initramfs
$$pkg8 $$pkg9 $$pkg10 $$pkg11;
deb: deb-kmod deb-dkms deb-utils
debian:
cp -r contrib/debian debian; chmod +x debian/rules;
native-deb-utils: native-deb-local debian
cp contrib/debian/control debian/control; \
$(DPKGBUILD) -b -rfakeroot -us -uc;
native-deb-kmod: native-deb-local debian
sh scripts/make_gitrev.sh; \
fakeroot debian/rules override_dh_binary-modules;
native-deb: native-deb-utils native-deb-kmod

View file

@ -165,6 +165,9 @@ dnl #
dnl # 5.15 API change,
dnl # Added the bool rcu argument to get_acl for rcu path walk.
dnl #
dnl # 6.2 API change,
dnl # get_acl() was renamed to get_inode_acl()
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
#include <linux/fs.h>
@ -189,6 +192,18 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
.get_acl = get_acl_fn,
};
],[])
ZFS_LINUX_TEST_SRC([inode_operations_get_inode_acl], [
#include <linux/fs.h>
struct posix_acl *get_inode_acl_fn(struct inode *inode, int type,
bool rcu) { return NULL; }
static const struct inode_operations
iops __attribute__ ((unused)) = {
.get_inode_acl = get_inode_acl_fn,
};
],[])
])
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
@ -201,7 +216,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu])
],[
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
ZFS_LINUX_TEST_RESULT([inode_operations_get_inode_acl], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_GET_INODE_ACL, 1, [has iops->get_inode_acl()])
],[
ZFS_LINUX_TEST_ERROR([iops->get_acl() or iops->get_inode_acl()])
])
])
])
])
@ -213,7 +233,22 @@ dnl #
dnl # 5.12 API change,
dnl # set_acl() added a user_namespace* parameter first
dnl #
dnl # 6.2 API change,
dnl # set_acl() second paramter changed to a struct dentry *
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns_dentry], [
#include <linux/fs.h>
int set_acl_fn(struct user_namespace *userns,
struct dentry *dent, struct posix_acl *acl,
int type) { return 0; }
static const struct inode_operations
iops __attribute__ ((unused)) = {
.set_acl = set_acl_fn,
};
],[])
ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [
#include <linux/fs.h>
@ -246,11 +281,18 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
AC_DEFINE(HAVE_SET_ACL_USERNS, 1, [iops->set_acl() takes 4 args])
],[
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns_dentry], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
AC_DEFINE(HAVE_SET_ACL_USERNS_DENTRY_ARG2, 1,
[iops->set_acl() takes 4 args, arg2 is struct dentry *])
],[
AC_MSG_RESULT(no)
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
],[
ZFS_LINUX_REQUIRE_API([i_op->set_acl()], [3.14])
])
])
])
])

View file

@ -3,11 +3,25 @@ dnl # 3.11 API change
dnl # Add support for i_op->tmpfile
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
dnl #
dnl # 6.1 API change
dnl # use struct file instead of struct dentry
dnl #
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
#include <linux/fs.h>
int tmpfile(struct user_namespace *userns,
struct inode *inode, struct file *file,
umode_t mode) { return 0; }
static struct inode_operations
iops __attribute__ ((unused)) = {
.tmpfile = tmpfile,
};
],[])
dnl #
dnl # 5.11 API change
dnl # add support for userns parameter to tmpfile
dnl #
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_userns], [
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_dentry_userns], [
#include <linux/fs.h>
int tmpfile(struct user_namespace *userns,
struct inode *inode, struct dentry *dentry,
@ -17,7 +31,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
.tmpfile = tmpfile,
};
],[])
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_dentry], [
#include <linux/fs.h>
int tmpfile(struct inode *inode, struct dentry *dentry,
umode_t mode) { return 0; }
@ -30,16 +44,24 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
AC_MSG_CHECKING([whether i_op->tmpfile() exists])
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_userns], [
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
],[
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry_userns], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
AC_DEFINE(HAVE_TMPFILE_DENTRY, 1, [i_op->tmpfile() uses old dentry signature])
],[
AC_MSG_RESULT(no)
ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
AC_DEFINE(HAVE_TMPFILE_DENTRY, 1, [i_op->tmpfile() uses old dentry signature])
],[
ZFS_LINUX_REQUIRE_API([i_op->tmpfile()], [3.11])
])
])
])
])

View file

@ -958,3 +958,35 @@ AC_DEFUN([ZFS_LINUX_TRY_COMPILE_HEADER], [
[test -f build/conftest/conftest.ko], [$3], [$4], [$5])
])
])
dnl #
dnl # AS_VERSION_COMPARE_LE
dnl # like AS_VERSION_COMPARE_LE, but runs $3 if (and only if) $1 <= $2
dnl # AS_VERSION_COMPARE_LE (version-1, version-2, [action-if-less-or-equal], [action-if-greater])
dnl #
AC_DEFUN([AS_VERSION_COMPARE_LE], [
AS_VERSION_COMPARE([$1], [$2], [$3], [$3], [$4])
])
dnl #
dnl # ZFS_LINUX_REQUIRE_API
dnl # like ZFS_LINUX_TEST_ERROR, except only fails if the kernel is
dnl # at least some specified version.
dnl #
AC_DEFUN([ZFS_LINUX_REQUIRE_API], [
AS_VERSION_COMPARE_LE([$2], [$kernsrcver], [
AC_MSG_ERROR([
*** None of the expected "$1" interfaces were detected. This
*** interface is expected for kernels version "$2" and above.
*** This may be because your kernel version is newer than what is
*** supported, or you are using a patched custom kernel with
*** incompatible modifications. Newer kernels may have incompatible
*** APIs.
***
*** ZFS Version: $ZFS_META_ALIAS
*** Compatible Kernels: $ZFS_META_KVER_MIN - $ZFS_META_KVER_MAX
])
], [
AC_MSG_RESULT(no)
])
])

View file

@ -464,6 +464,7 @@ AC_DEFUN([ZFS_AC_DPKG], [
AC_SUBST(HAVE_DPKGBUILD)
AC_SUBST(DPKGBUILD)
AC_SUBST(DPKGBUILD_VERSION)
AC_SUBST([CFGOPTS], ["$CFGOPTS"])
])
dnl #

View file

@ -32,6 +32,7 @@
AC_INIT(m4_esyscmd(awk '/^Name:/ {printf $2}' META),
m4_esyscmd(awk '/^Version:/ {printf $2}' META))
CFGOPTS="$*"
AC_LANG(C)
ZFS_AC_META
AC_CONFIG_AUX_DIR([config])
@ -65,6 +66,7 @@ ZFS_AC_DEBUG_KMEM_TRACKING
ZFS_AC_DEBUG_INVARIANTS
AC_CONFIG_FILES([
contrib/debian/rules
Makefile
include/Makefile
lib/libzfs/libzfs.pc

View file

@ -0,0 +1 @@
rules

View file

@ -2,8 +2,7 @@ Source: openzfs-linux
Section: contrib/kernel
Priority: optional
Maintainer: ZFS on Linux specific mailing list <zfs-discuss@list.zfsonlinux.org>
Build-Depends: abigail-tools,
debhelper-compat (= 12),
Build-Depends: debhelper-compat (= 12),
dh-python,
dkms (>> 2.1.1.2-5),
libaio-dev,

View file

@ -1,6 +1,8 @@
#!/bin/sh
set -e
pam-auth-update --package
if ! $(ldd "/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/security/pam_zfs_key.so" | grep -q "libasan") ; then
pam-auth-update --package
fi
#DEBHELPER#

View file

@ -4,13 +4,6 @@ set -e
zedd="/usr/lib/zfs-linux/zed.d"
etcd="/etc/zfs/zed.d"
# enable all default zedlets that are not overridden
while read -r file ; do
etcfile="${etcd}/${file}"
[ -e "${etcfile}" ] && continue
ln -sfT "${zedd}/${file}" "${etcfile}"
done < "${zedd}/DEFAULT-ENABLED"
# remove the overrides created in prerm
find "${etcd}" -maxdepth 1 -lname '/dev/null' -delete
# remove any dangling symlinks to old zedlets

View file

@ -1,16 +0,0 @@
#!/bin/sh
set -e
zedd="/usr/lib/zfs-linux/zed.d"
etcd="/etc/zfs/zed.d"
if [ "$1" != "failed-upgrade" ] && [ -d "${etcd}" ] && [ -d "${zedd}" ] ; then
while read -r file ; do
etcfile="${etcd}/${file}"
( [ -L "${etcfile}" ] || [ -e "${etcfile}" ] ) && continue
ln -sT /dev/null "${etcfile}"
done < "${zedd}/DEFAULT-ENABLED"
fi
#DEBHELPER#

View file

@ -131,5 +131,4 @@ usr/share/man/man8/zstreamdump.8
usr/share/man/man4/spl.4
usr/share/man/man4/zfs.4
usr/share/man/man7/zpool-features.7
usr/share/man/man7/dracut.zfs.7
usr/share/man/man8/zpool_influxdb.8

View file

@ -1,21 +1,6 @@
#!/bin/sh
set -e
# The hostname and hostid of the last system to access a ZFS pool are stored in
# the ZFS pool itself. A pool is foreign if, during `zpool import`, the
# current hostname and hostid are different than the stored values thereof.
#
# The only way of having a stable hostid is to define it in /etc/hostid.
# This postinst helper will check if we already have the hostid stabilized by
# checking the existence of the file /etc/hostid to be 4 bytes at least.
# If this file don't already exists on our system or has less than 4 bytes, then
# a new (random) value is generated with zgenhostid (8) and stored in
# /etc/hostid
if [ ! -f /etc/hostid ] || [ "$(stat -c %s /etc/hostid)" -lt 4 ] ; then
zgenhostid
fi
# When processed to here but zfs kernel module is not loaded, the subsequent
# services would fail to start. In this case the installation process just
# fails at the postinst stage. The user could do

View file

@ -35,7 +35,7 @@ override_dh_autoreconf:
override_dh_auto_configure:
@# Build the userland, but don't build the kernel modules.
dh_auto_configure -- \
dh_auto_configure -- @CFGOPTS@ \
--bindir=/usr/bin \
--sbindir=/sbin \
--libdir=/lib/"$(DEB_HOST_MULTIARCH)" \
@ -195,7 +195,7 @@ override_dh_prep-deb-files:
override_dh_configure_modules: override_dh_configure_modules_stamp
override_dh_configure_modules_stamp:
./configure \
./configure @CFGOPTS@ \
--with-config=kernel \
--with-linux=$(KSRC) \
--with-linux-obj=$(KOBJ)

View file

@ -34,7 +34,7 @@ _load_key_cb() {
case "${KEYLOCATION%%://*}" in
prompt)
for _ in 1 2 3; do
systemd-ask-password --no-tty "Encrypted ZFS password for ${dataset}" | zfs load-key "${ENCRYPTIONROOT}" && break
systemd-ask-password --timeout=0 --no-tty "Encrypted ZFS password for ${dataset}" | zfs load-key "${ENCRYPTIONROOT}" && break
done
;;
http*)

View file

@ -333,25 +333,21 @@ mount_fs()
# Can't use the mountpoint property. Might be one of our
# clones. Check the 'org.zol:mountpoint' property set in
# clone_snap() if that's usable.
mountpoint=$(get_fs_value "$fs" org.zol:mountpoint)
if [ "$mountpoint" = "legacy" ] ||
[ "$mountpoint" = "none" ] ||
[ "$mountpoint" = "-" ]
mountpoint1=$(get_fs_value "$fs" org.zol:mountpoint)
if [ "$mountpoint1" = "legacy" ] ||
[ "$mountpoint1" = "none" ] ||
[ "$mountpoint1" = "-" ]
then
if [ "$fs" != "${ZFS_BOOTFS}" ]; then
# We don't have a proper mountpoint and this
# isn't the root fs.
return 0
else
# Last hail-mary: Hope 'rootmnt' is set!
mountpoint=""
fi
fi
# If it's not a legacy filesystem, it can only be a
# native one...
if [ "$mountpoint" = "legacy" ]; then
ZFS_CMD="mount.zfs"
# Last hail-mary: Hope 'rootmnt' is set!
mountpoint=""
else
mountpoint="$mountpoint1"
fi
fi
@ -505,7 +501,7 @@ clone_snap()
echo "Error: $ZFS_ERROR"
echo ""
echo "Failed to clone snapshot."
echo "Make sure that the any problems are corrected and then make sure"
echo "Make sure that any problems are corrected and then make sure"
echo "that the dataset '$destfs' exists and is bootable."
shell
else

View file

@ -535,7 +535,7 @@ zfs_key_config_get_dataset(zfs_key_config_t *config)
return (NULL);
}
(void) zfs_iter_filesystems(zhp, find_dsname_by_prop_value,
(void) zfs_iter_filesystems(zhp, 0, find_dsname_by_prop_value,
config);
zfs_close(zhp);
char *dsname = config->dsname;

View file

@ -224,9 +224,10 @@ line_worker(char *line, const char *cachefile)
const char *p_systemd_ignore = strtok_r(NULL, "\t", &toktmp) ?: "-";
/* END CSTYLED */
const char *pool = dataset;
if ((toktmp = strchr(pool, '/')) != NULL)
pool = strndupa(pool, toktmp - pool);
size_t pool_len = strlen(dataset);
if ((toktmp = strchr(dataset, '/')) != NULL)
pool_len = toktmp - dataset;
const char *pool = *(tofree++) = strndup(dataset, pool_len);
if (p_nbmand == NULL) {
fprintf(stderr, PROGNAME "[%d]: %s: not enough tokens!\n",
@ -734,7 +735,7 @@ line_worker(char *line, const char *cachefile)
if (tofree >= tofree_all + nitems(tofree_all)) {
/*
* This won't happen as-is:
* we've got 8 slots and allocate 4 things at most.
* we've got 8 slots and allocate 5 things at most.
*/
fprintf(stderr,
PROGNAME "[%d]: %s: need to free %zu > %zu!\n",

View file

@ -6,7 +6,7 @@ ConditionPathIsDirectory=/sys/module/zfs
[Service]
EnvironmentFile=-@initconfdir@/zfs
ExecStart=@sbindir@/zed -F
Restart=on-abort
Restart=always
[Install]
Alias=zed.service

View file

@ -20,6 +20,7 @@ COMMON_H = \
sys/aggsum.h \
sys/arc.h \
sys/arc_impl.h \
sys/asm_linkage.h \
sys/avl.h \
sys/avl_impl.h \
sys/bitops.h \

View file

@ -646,19 +646,27 @@ _LIBZFS_H void zprop_print_one_property(const char *, zprop_get_cbdata_t *,
/*
* Iterator functions.
*/
#define ZFS_ITER_RECURSE (1 << 0)
#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
#define ZFS_ITER_DEPTH_LIMIT (1 << 3)
#define ZFS_ITER_RECVD_PROPS (1 << 4)
#define ZFS_ITER_LITERAL_PROPS (1 << 5)
#define ZFS_ITER_SIMPLE (1 << 6)
typedef int (*zfs_iter_f)(zfs_handle_t *, void *);
_LIBZFS_H int zfs_iter_root(libzfs_handle_t *, zfs_iter_f, void *);
_LIBZFS_H int zfs_iter_children(zfs_handle_t *, zfs_iter_f, void *);
_LIBZFS_H int zfs_iter_dependents(zfs_handle_t *, boolean_t, zfs_iter_f,
_LIBZFS_H int zfs_iter_children(zfs_handle_t *, int, zfs_iter_f, void *);
_LIBZFS_H int zfs_iter_dependents(zfs_handle_t *, int, boolean_t, zfs_iter_f,
void *);
_LIBZFS_H int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *);
_LIBZFS_H int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *,
_LIBZFS_H int zfs_iter_filesystems(zfs_handle_t *, int, zfs_iter_f, void *);
_LIBZFS_H int zfs_iter_snapshots(zfs_handle_t *, int, zfs_iter_f, void *,
uint64_t, uint64_t);
_LIBZFS_H int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *,
_LIBZFS_H int zfs_iter_snapshots_sorted(zfs_handle_t *, int, zfs_iter_f, void *,
uint64_t, uint64_t);
_LIBZFS_H int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f,
_LIBZFS_H int zfs_iter_snapspec(zfs_handle_t *, int, const char *, zfs_iter_f,
void *);
_LIBZFS_H int zfs_iter_bookmarks(zfs_handle_t *, zfs_iter_f, void *);
_LIBZFS_H int zfs_iter_bookmarks(zfs_handle_t *, int, zfs_iter_f, void *);
_LIBZFS_H int zfs_iter_mounted(zfs_handle_t *, zfs_iter_f, void *);
typedef struct get_all_cb {
@ -732,6 +740,9 @@ typedef struct sendflags {
/* show progress (ie. -v) */
boolean_t progress;
/* show progress as process title (ie. -V) */
boolean_t progressastitle;
/* large blocks (>128K) are permitted */
boolean_t largeblock;

View file

@ -170,7 +170,9 @@ struct zfs_cmd;
* List of colors to use
*/
#define ANSI_RED "\033[0;31m"
#define ANSI_GREEN "\033[0;32m"
#define ANSI_YELLOW "\033[0;33m"
#define ANSI_BLUE "\033[0;34m"
#define ANSI_RESET "\033[0m"
#define ANSI_BOLD "\033[1m"
@ -180,6 +182,13 @@ _LIBZUTIL_H int printf_color(const char *color, const char *format, ...);
_LIBZUTIL_H const char *zfs_basename(const char *path);
_LIBZUTIL_H ssize_t zfs_dirnamelen(const char *path);
#ifdef __linux__
_LIBZUTIL_H void zfs_setproctitle_init(int argc, char *argv[], char *envp[]);
_LIBZUTIL_H void zfs_setproctitle(const char *fmt, ...);
#else
#define zfs_setproctitle(fmt, ...) setproctitle(fmt, ##__VA_ARGS__)
#define zfs_setproctitle_init(x, y, z) ((void)0)
#endif
/*
* These functions are used by the ZFS libraries and cmd/zpool code, but are

View file

@ -6,6 +6,8 @@ noinst_HEADERS = \
\
%D%/spl/rpc/xdr.h \
\
%D%/spl/sys/ia32/asm_linkage.h \
\
%D%/spl/sys/acl.h \
%D%/spl/sys/acl_impl.h \
%D%/spl/sys/atomic.h \
@ -88,3 +90,4 @@ noinst_HEADERS = \
%D%/zfs/sys/zfs_vnops_os.h \
%D%/zfs/sys/zfs_znode_impl.h \
%D%/zfs/sys/zpl.h

View file

@ -0,0 +1,178 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IA32_SYS_ASM_LINKAGE_H
#define _IA32_SYS_ASM_LINKAGE_H
#define RET ret
/* Tell compiler to call assembler like Unix */
#undef ASMABI
#define ASMABI __attribute__((sysv_abi))
#define ENDBR
#define SECTION_TEXT .text
#define SECTION_STATIC .data
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASM /* The remainder of this file is only for assembly files */
/*
* make annoying differences in assembler syntax go away
*/
/*
* D16 and A16 are used to insert instructions prefixes; the
* macros help the assembler code be slightly more portable.
*/
#if !defined(__GNUC_AS__)
/*
* /usr/ccs/bin/as prefixes are parsed as separate instructions
*/
#define D16 data16;
#define A16 addr16;
/*
* (There are some weird constructs in constant expressions)
*/
#define _CONST(const) [const]
#define _BITNOT(const) -1!_CONST(const)
#define _MUL(a, b) _CONST(a \* b)
#else
/*
* Why not use the 'data16' and 'addr16' prefixes .. well, the
* assembler doesn't quite believe in real mode, and thus argues with
* us about what we're trying to do.
*/
#define D16 .byte 0x66;
#define A16 .byte 0x67;
#define _CONST(const) (const)
#define _BITNOT(const) ~_CONST(const)
#define _MUL(a, b) _CONST(a * b)
#endif
/*
* C pointers are different sizes between i386 and amd64.
* These constants can be used to compute offsets into pointer arrays.
*/
#if defined(__amd64)
#define CLONGSHIFT 3
#define CLONGSIZE 8
#define CLONGMASK 7
#elif defined(__i386)
#define CLONGSHIFT 2
#define CLONGSIZE 4
#define CLONGMASK 3
#endif
/*
* Since we know we're either ILP32 or LP64 ..
*/
#define CPTRSHIFT CLONGSHIFT
#define CPTRSIZE CLONGSIZE
#define CPTRMASK CLONGMASK
#if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT)
#error "inconsistent shift constants"
#endif
#if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1)
#error "inconsistent mask constants"
#endif
#define ASM_ENTRY_ALIGN 16
/*
* SSE register alignment and save areas
*/
#define XMM_SIZE 16
#define XMM_ALIGN 16
/*
* ENTRY provides the standard procedure entry code and an easy way to
* insert the calls to mcount for profiling. ENTRY_NP is identical, but
* never calls mcount.
*/
#define ENTRY(x) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
x: MCOUNT(x)
#define ENTRY_NP(x) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
x:
#define ENTRY_ALIGN(x, a) \
.text; \
.balign a; \
.globl x; \
x:
/*
* ENTRY2 is identical to ENTRY but provides two labels for the entry point.
*/
#define ENTRY2(x, y) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
x:; \
y: MCOUNT(x)
#define ENTRY_NP2(x, y) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
x:; \
y:
/*
* SET_SIZE trails a function and set the size for the ELF symbol table.
*/
#define SET_SIZE(x)
#define SET_OBJ(x)
#endif /* _ASM */
#ifdef __cplusplus
}
#endif
#endif /* _IA32_SYS_ASM_LINKAGE_H */

View file

@ -109,4 +109,8 @@ kernel_spl_sys_HEADERS = \
%D%/spl/sys/wmsum.h \
%D%/spl/sys/zmod.h \
%D%/spl/sys/zone.h
kernel_spl_ia32dir = $(kernel_spl_sysdir)/ia32
kernel_spl_ia32_HEADERS = \
%D%/spl/sys/ia32/asm_linkage.h
endif

View file

@ -394,7 +394,11 @@ vdev_lookup_bdev(const char *path, dev_t *dev)
static inline void
bio_set_op_attrs(struct bio *bio, unsigned rw, unsigned flags)
{
#if defined(HAVE_BIO_BI_OPF)
bio->bi_opf = rw | flags;
#else
bio->bi_rw |= rw | flags;
#endif /* HAVE_BIO_BI_OPF */
}
#endif

View file

@ -35,6 +35,10 @@
#define d_make_root(inode) d_alloc_root(inode)
#endif /* HAVE_D_MAKE_ROOT */
#ifdef HAVE_DENTRY_D_U_ALIASES
#define d_alias d_u.d_alias
#endif
/*
* 2.6.30 API change,
* The const keyword was added to the 'struct dentry_operations' in
@ -70,11 +74,7 @@ zpl_d_drop_aliases(struct inode *inode)
{
struct dentry *dentry;
spin_lock(&inode->i_lock);
#ifdef HAVE_DENTRY_D_U_ALIASES
hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) {
#else
hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
#endif
if (!IS_ROOT(dentry) && !d_mountpoint(dentry) &&
(dentry->d_inode == inode)) {
d_drop(dentry);

View file

@ -69,6 +69,7 @@
#define kfpu_allowed() 1
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
#ifdef CONFIG_SPE
#define kfpu_begin() \
{ \
preempt_disable(); \
@ -83,6 +84,20 @@
disable_kernel_altivec(); \
preempt_enable(); \
}
#else /* CONFIG_SPE */
#define kfpu_begin() \
{ \
preempt_disable(); \
enable_kernel_altivec(); \
enable_kernel_vsx(); \
}
#define kfpu_end() \
{ \
disable_kernel_vsx(); \
disable_kernel_altivec(); \
preempt_enable(); \
}
#endif
#else
/* seems that before 4.5 no-one bothered */
#define kfpu_begin()

View file

@ -0,0 +1,212 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IA32_SYS_ASM_LINKAGE_H
#define _IA32_SYS_ASM_LINKAGE_H
#if defined(_KERNEL) && defined(__linux__)
#include <linux/linkage.h>
#endif
#ifndef ENDBR
#if defined(__ELF__) && defined(__CET__) && defined(__has_include)
/* CSTYLED */
#if __has_include(<cet.h>)
#include <cet.h>
#ifdef _CET_ENDBR
#define ENDBR _CET_ENDBR
#endif /* _CET_ENDBR */
#endif /* <cet.h> */
#endif /* __ELF__ && __CET__ && __has_include */
#endif /* !ENDBR */
#ifndef ENDBR
#define ENDBR
#endif
#ifndef RET
#define RET ret
#endif
/* You can set to nothing on Unix platforms */
#undef ASMABI
#define ASMABI __attribute__((sysv_abi))
#define SECTION_TEXT .text
#define SECTION_STATIC .section .rodata
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASM /* The remainder of this file is only for assembly files */
/*
* make annoying differences in assembler syntax go away
*/
/*
* D16 and A16 are used to insert instructions prefixes; the
* macros help the assembler code be slightly more portable.
*/
#if !defined(__GNUC_AS__)
/*
* /usr/ccs/bin/as prefixes are parsed as separate instructions
*/
#define D16 data16;
#define A16 addr16;
/*
* (There are some weird constructs in constant expressions)
*/
#define _CONST(const) [const]
#define _BITNOT(const) -1!_CONST(const)
#define _MUL(a, b) _CONST(a \* b)
#else
/*
* Why not use the 'data16' and 'addr16' prefixes .. well, the
* assembler doesn't quite believe in real mode, and thus argues with
* us about what we're trying to do.
*/
#define D16 .byte 0x66;
#define A16 .byte 0x67;
#define _CONST(const) (const)
#define _BITNOT(const) ~_CONST(const)
#define _MUL(a, b) _CONST(a * b)
#endif
/*
* C pointers are different sizes between i386 and amd64.
* These constants can be used to compute offsets into pointer arrays.
*/
#if defined(__amd64)
#define CLONGSHIFT 3
#define CLONGSIZE 8
#define CLONGMASK 7
#elif defined(__i386)
#define CLONGSHIFT 2
#define CLONGSIZE 4
#define CLONGMASK 3
#endif
/*
* Since we know we're either ILP32 or LP64 ..
*/
#define CPTRSHIFT CLONGSHIFT
#define CPTRSIZE CLONGSIZE
#define CPTRMASK CLONGMASK
#if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT)
#error "inconsistent shift constants"
#endif
#if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1)
#error "inconsistent mask constants"
#endif
#define ASM_ENTRY_ALIGN 16
/*
* SSE register alignment and save areas
*/
#define XMM_SIZE 16
#define XMM_ALIGN 16
/*
* ENTRY provides the standard procedure entry code and an easy way to
* insert the calls to mcount for profiling. ENTRY_NP is identical, but
* never calls mcount.
*/
#undef ENTRY
#define ENTRY(x) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
.type x, @function; \
x: MCOUNT(x)
#define ENTRY_NP(x) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
.type x, @function; \
x:
#define ENTRY_ALIGN(x, a) \
.text; \
.balign a; \
.globl x; \
.type x, @function; \
x:
#define FUNCTION(x) \
.type x, @function; \
x:
/*
* ENTRY2 is identical to ENTRY but provides two labels for the entry point.
*/
#define ENTRY2(x, y) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
.type x, @function; \
.type y, @function; \
x:; \
y: MCOUNT(x)
#define ENTRY_NP2(x, y) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
.type x, @function; \
.type y, @function; \
x:; \
y:
/*
* SET_SIZE trails a function and set the size for the ELF symbol table.
*/
#define SET_SIZE(x) \
.size x, [.-x]
#define SET_OBJ(x) .type x, @object
#endif /* _ASM */
#ifdef __cplusplus
}
#endif
#endif /* _IA32_SYS_ASM_LINKAGE_H */

View file

@ -40,6 +40,9 @@ extern void kmem_strfree(char *str);
#define kmem_scnprintf scnprintf
#define POINTER_IS_VALID(p) (!((uintptr_t)(p) & 0x3))
#define POINTER_INVALIDATE(pp) (*(pp) = (void *)((uintptr_t)(*(pp)) | 0x1))
/*
* Memory allocation interfaces
*/

View file

@ -98,9 +98,6 @@ extern struct rw_semaphore spl_kmem_cache_sem;
#define SPL_MAX_KMEM_ORDER_NR_PAGES (KMALLOC_MAX_SIZE >> PAGE_SHIFT)
#endif
#define POINTER_IS_VALID(p) 0 /* Unimplemented */
#define POINTER_INVALIDATE(pp) /* Unimplemented */
typedef int (*spl_kmem_ctor_t)(void *, void *, int);
typedef void (*spl_kmem_dtor_t)(void *, void *);

View file

@ -103,12 +103,13 @@ DEFINE_EVENT(zfs_arc_buf_hdr_class, name, \
TP_PROTO(arc_buf_hdr_t *ab), \
TP_ARGS(ab))
DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__hit);
DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__iohit);
DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__evict);
DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__delete);
DEFINE_ARC_BUF_HDR_EVENT(zfs_new_state__mru);
DEFINE_ARC_BUF_HDR_EVENT(zfs_new_state__mfu);
DEFINE_ARC_BUF_HDR_EVENT(zfs_new_state__uncached);
DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__async__upgrade__sync);
DEFINE_ARC_BUF_HDR_EVENT(zfs_arc__demand__hit__predictive__prefetch);
DEFINE_ARC_BUF_HDR_EVENT(zfs_l2arc__hit);
DEFINE_ARC_BUF_HDR_EVENT(zfs_l2arc__miss);
@ -387,12 +388,13 @@ DEFINE_ARC_WAIT_FOR_EVICTION_EVENT(zfs_arc__wait__for__eviction);
#else
DEFINE_DTRACE_PROBE1(arc__hit);
DEFINE_DTRACE_PROBE1(arc__iohit);
DEFINE_DTRACE_PROBE1(arc__evict);
DEFINE_DTRACE_PROBE1(arc__delete);
DEFINE_DTRACE_PROBE1(new_state__mru);
DEFINE_DTRACE_PROBE1(new_state__mfu);
DEFINE_DTRACE_PROBE1(new_state__uncached);
DEFINE_DTRACE_PROBE1(arc__async__upgrade__sync);
DEFINE_DTRACE_PROBE1(arc__demand__hit__predictive__prefetch);
DEFINE_DTRACE_PROBE1(l2arc__hit);
DEFINE_DTRACE_PROBE1(l2arc__miss);
DEFINE_DTRACE_PROBE2(l2arc__read);

View file

@ -71,11 +71,14 @@ extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip,
#if defined(HAVE_SET_ACL_USERNS)
extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip,
struct posix_acl *acl, int type);
#elif defined(HAVE_SET_ACL_USERNS_DENTRY_ARG2)
extern int zpl_set_acl(struct user_namespace *userns, struct dentry *dentry,
struct posix_acl *acl, int type);
#else
extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
#endif /* HAVE_SET_ACL_USERNS */
#endif /* HAVE_SET_ACL */
#if defined(HAVE_GET_ACL_RCU)
#if defined(HAVE_GET_ACL_RCU) || defined(HAVE_GET_INODE_ACL)
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type, bool rcu);
#elif defined(HAVE_GET_ACL)
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);

View file

@ -115,7 +115,7 @@ typedef enum arc_flags
ARC_FLAG_PREFETCH = 1 << 2, /* I/O is a prefetch */
ARC_FLAG_CACHED = 1 << 3, /* I/O was in cache */
ARC_FLAG_L2CACHE = 1 << 4, /* cache in L2ARC */
ARC_FLAG_PREDICTIVE_PREFETCH = 1 << 5, /* I/O from zfetch */
ARC_FLAG_UNCACHED = 1 << 5, /* evict after use */
ARC_FLAG_PRESCIENT_PREFETCH = 1 << 6, /* long min lifespan */
/*
@ -195,7 +195,6 @@ typedef enum arc_buf_flags {
struct arc_buf {
arc_buf_hdr_t *b_hdr;
arc_buf_t *b_next;
kmutex_t b_evict_lock;
void *b_data;
arc_buf_flags_t b_flags;
};
@ -229,6 +228,7 @@ typedef enum arc_state_type {
ARC_STATE_MFU,
ARC_STATE_MFU_GHOST,
ARC_STATE_L2C_ONLY,
ARC_STATE_UNCACHED,
ARC_STATE_NUMTYPES
} arc_state_type_t;
@ -302,8 +302,8 @@ int arc_referenced(arc_buf_t *buf);
int arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
arc_read_done_func_t *done, void *priv, zio_priority_t priority,
int flags, arc_flags_t *arc_flags, const zbookmark_phys_t *zb);
zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg,
blkptr_t *bp, arc_buf_t *buf, boolean_t l2arc, const zio_prop_t *zp,
zio_t *arc_write(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp,
arc_buf_t *buf, boolean_t uncached, boolean_t l2arc, const zio_prop_t *zp,
arc_write_done_func_t *ready, arc_write_done_func_t *child_ready,
arc_write_done_func_t *physdone, arc_write_done_func_t *done,
void *priv, zio_priority_t priority, int zio_flags,

View file

@ -46,6 +46,7 @@ extern "C" {
* ARC_mru_ghost - recently used, no longer in cache
* ARC_mfu - frequently used, currently cached
* ARC_mfu_ghost - frequently used, no longer in cache
* ARC_uncached - uncacheable prefetch, to be evicted
* ARC_l2c_only - exists in L2ARC but not other states
* When there are no active references to the buffer, they are
* are linked onto a list in one of these arc states. These are
@ -101,9 +102,14 @@ struct arc_callback {
boolean_t acb_compressed;
boolean_t acb_noauth;
boolean_t acb_nobuf;
boolean_t acb_wait;
int acb_wait_error;
kmutex_t acb_wait_lock;
kcondvar_t acb_wait_cv;
zbookmark_phys_t acb_zb;
zio_t *acb_zio_dummy;
zio_t *acb_zio_head;
arc_callback_t *acb_prev;
arc_callback_t *acb_next;
};
@ -150,9 +156,6 @@ struct arc_write_callback {
* these two allocation states.
*/
typedef struct l1arc_buf_hdr {
kmutex_t b_freeze_lock;
zio_cksum_t *b_freeze_cksum;
/* for waiting on reads to complete */
kcondvar_t b_cv;
uint8_t b_byteswap;
@ -175,6 +178,11 @@ typedef struct l1arc_buf_hdr {
arc_callback_t *b_acb;
abd_t *b_pabd;
#ifdef ZFS_DEBUG
zio_cksum_t *b_freeze_cksum;
kmutex_t b_freeze_lock;
#endif
} l1arc_buf_hdr_t;
typedef enum l2arc_dev_hdr_flags_t {
@ -511,20 +519,33 @@ struct arc_buf_hdr {
};
typedef struct arc_stats {
/* Number of requests that were satisfied without I/O. */
kstat_named_t arcstat_hits;
/* Number of requests for which I/O was already running. */
kstat_named_t arcstat_iohits;
/* Number of requests for which I/O has to be issued. */
kstat_named_t arcstat_misses;
/* Same three, but specifically for demand data. */
kstat_named_t arcstat_demand_data_hits;
kstat_named_t arcstat_demand_data_iohits;
kstat_named_t arcstat_demand_data_misses;
/* Same three, but specifically for demand metadata. */
kstat_named_t arcstat_demand_metadata_hits;
kstat_named_t arcstat_demand_metadata_iohits;
kstat_named_t arcstat_demand_metadata_misses;
/* Same three, but specifically for prefetch data. */
kstat_named_t arcstat_prefetch_data_hits;
kstat_named_t arcstat_prefetch_data_iohits;
kstat_named_t arcstat_prefetch_data_misses;
/* Same three, but specifically for prefetch metadata. */
kstat_named_t arcstat_prefetch_metadata_hits;
kstat_named_t arcstat_prefetch_metadata_iohits;
kstat_named_t arcstat_prefetch_metadata_misses;
kstat_named_t arcstat_mru_hits;
kstat_named_t arcstat_mru_ghost_hits;
kstat_named_t arcstat_mfu_hits;
kstat_named_t arcstat_mfu_ghost_hits;
kstat_named_t arcstat_uncached_hits;
kstat_named_t arcstat_deleted;
/*
* Number of buffers that could not be evicted because the hash lock
@ -727,6 +748,21 @@ typedef struct arc_stats {
* ARC_BUFC_METADATA, and linked off the arc_mru_ghost state.
*/
kstat_named_t arcstat_mfu_ghost_evictable_metadata;
/*
* Total number of bytes that are going to be evicted from ARC due to
* ARC_FLAG_UNCACHED being set.
*/
kstat_named_t arcstat_uncached_size;
/*
* Number of data bytes that are going to be evicted from ARC due to
* ARC_FLAG_UNCACHED being set.
*/
kstat_named_t arcstat_uncached_evictable_data;
/*
* Number of metadata bytes that that are going to be evicted from ARC
* due to ARC_FLAG_UNCACHED being set.
*/
kstat_named_t arcstat_uncached_evictable_metadata;
kstat_named_t arcstat_l2_hits;
kstat_named_t arcstat_l2_misses;
/*
@ -844,8 +880,18 @@ typedef struct arc_stats {
kstat_named_t arcstat_meta_max;
kstat_named_t arcstat_meta_min;
kstat_named_t arcstat_async_upgrade_sync;
/* Number of predictive prefetch requests. */
kstat_named_t arcstat_predictive_prefetch;
/* Number of requests for which predictive prefetch has completed. */
kstat_named_t arcstat_demand_hit_predictive_prefetch;
/* Number of requests for which predictive prefetch was running. */
kstat_named_t arcstat_demand_iohit_predictive_prefetch;
/* Number of prescient prefetch requests. */
kstat_named_t arcstat_prescient_prefetch;
/* Number of requests for which prescient prefetch has completed. */
kstat_named_t arcstat_demand_hit_prescient_prefetch;
/* Number of requests for which prescient prefetch was running. */
kstat_named_t arcstat_demand_iohit_prescient_prefetch;
kstat_named_t arcstat_need_free;
kstat_named_t arcstat_sys_free;
kstat_named_t arcstat_raw_size;
@ -855,19 +901,25 @@ typedef struct arc_stats {
typedef struct arc_sums {
wmsum_t arcstat_hits;
wmsum_t arcstat_iohits;
wmsum_t arcstat_misses;
wmsum_t arcstat_demand_data_hits;
wmsum_t arcstat_demand_data_iohits;
wmsum_t arcstat_demand_data_misses;
wmsum_t arcstat_demand_metadata_hits;
wmsum_t arcstat_demand_metadata_iohits;
wmsum_t arcstat_demand_metadata_misses;
wmsum_t arcstat_prefetch_data_hits;
wmsum_t arcstat_prefetch_data_iohits;
wmsum_t arcstat_prefetch_data_misses;
wmsum_t arcstat_prefetch_metadata_hits;
wmsum_t arcstat_prefetch_metadata_iohits;
wmsum_t arcstat_prefetch_metadata_misses;
wmsum_t arcstat_mru_hits;
wmsum_t arcstat_mru_ghost_hits;
wmsum_t arcstat_mfu_hits;
wmsum_t arcstat_mfu_ghost_hits;
wmsum_t arcstat_uncached_hits;
wmsum_t arcstat_deleted;
wmsum_t arcstat_mutex_miss;
wmsum_t arcstat_access_skip;
@ -936,8 +988,12 @@ typedef struct arc_sums {
wmsum_t arcstat_prune;
aggsum_t arcstat_meta_used;
wmsum_t arcstat_async_upgrade_sync;
wmsum_t arcstat_predictive_prefetch;
wmsum_t arcstat_demand_hit_predictive_prefetch;
wmsum_t arcstat_demand_iohit_predictive_prefetch;
wmsum_t arcstat_prescient_prefetch;
wmsum_t arcstat_demand_hit_prescient_prefetch;
wmsum_t arcstat_demand_iohit_prescient_prefetch;
wmsum_t arcstat_raw_size;
wmsum_t arcstat_cached_only_in_progress;
wmsum_t arcstat_abd_chunk_waste_size;
@ -970,6 +1026,7 @@ typedef struct arc_evict_waiter {
#define arc_mfu (&ARC_mfu)
#define arc_mfu_ghost (&ARC_mfu_ghost)
#define arc_l2c_only (&ARC_l2c_only)
#define arc_uncached (&ARC_uncached)
extern taskq_t *arc_prune_taskq;
extern arc_stats_t arc_stats;

View file

@ -0,0 +1,48 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_ASM_LINKAGE_H
#define _SYS_ASM_LINKAGE_H
#define ASMABI
#if defined(__i386) || defined(__amd64)
#include <sys/ia32/asm_linkage.h> /* XX64 x86/sys/asm_linkage.h */
#endif
#if defined(_KERNEL) && defined(HAVE_KERNEL_OBJTOOL)
#include <asm/frame.h>
#else /* userspace */
#define FRAME_BEGIN
#define FRAME_END
#endif
#endif /* _SYS_ASM_LINKAGE_H */

View file

@ -27,10 +27,14 @@ extern "C" {
typedef struct bqueue {
list_t bq_list;
size_t bq_size;
list_t bq_dequeuing_list;
size_t bq_dequeuing_size;
list_t bq_enqueuing_list;
size_t bq_enqueuing_size;
kmutex_t bq_lock;
kcondvar_t bq_add_cv;
kcondvar_t bq_pop_cv;
size_t bq_size;
size_t bq_maxsize;
uint_t bq_fill_fraction;
size_t bq_node_offset;
@ -47,7 +51,6 @@ void bqueue_destroy(bqueue_t *);
void bqueue_enqueue(bqueue_t *, void *, size_t);
void bqueue_enqueue_flush(bqueue_t *, void *, size_t);
void *bqueue_dequeue(bqueue_t *);
boolean_t bqueue_empty(bqueue_t *);
#ifdef __cplusplus
}

View file

@ -55,6 +55,8 @@ extern "C" {
#define DB_RF_NEVERWAIT (1 << 4)
#define DB_RF_CACHED (1 << 5)
#define DB_RF_NO_DECRYPT (1 << 6)
#define DB_RF_PARTIAL_FIRST (1 << 7)
#define DB_RF_PARTIAL_MORE (1 << 8)
/*
* The simplified state transition diagram for dbufs looks like:
@ -294,6 +296,8 @@ typedef struct dmu_buf_impl {
/* Tells us which dbuf cache this dbuf is in, if any */
dbuf_cached_state_t db_caching_status;
uint64_t db_hash;
/* Data which is unique to data (leaf) blocks: */
/* User callback information. */
@ -319,6 +323,9 @@ typedef struct dmu_buf_impl {
uint8_t db_pending_evict;
uint8_t db_dirtycnt;
/* The buffer was partially read. More reads may follow. */
uint8_t db_partial_read;
} dmu_buf_impl_t;
#define DBUF_HASH_MUTEX(h, idx) \
@ -364,7 +371,7 @@ void dbuf_rele_and_unlock(dmu_buf_impl_t *db, const void *tag,
boolean_t evicting);
dmu_buf_impl_t *dbuf_find(struct objset *os, uint64_t object, uint8_t level,
uint64_t blkid);
uint64_t blkid, uint64_t *hash_out);
int dbuf_read(dmu_buf_impl_t *db, zio_t *zio, uint32_t flags);
void dmu_buf_will_not_fill(dmu_buf_t *db, dmu_tx_t *tx);

View file

@ -457,15 +457,11 @@ void dnode_free_interior_slots(dnode_t *dn);
#define DNODE_IS_DIRTY(_dn) \
((_dn)->dn_dirty_txg >= spa_syncing_txg((_dn)->dn_objset->os_spa))
#define DNODE_IS_CACHEABLE(_dn) \
#define DNODE_LEVEL_IS_CACHEABLE(_dn, _level) \
((_dn)->dn_objset->os_primary_cache == ZFS_CACHE_ALL || \
(DMU_OT_IS_METADATA((_dn)->dn_type) && \
(((_level) > 0 || DMU_OT_IS_METADATA((_dn)->dn_type)) && \
(_dn)->dn_objset->os_primary_cache == ZFS_CACHE_METADATA))
#define DNODE_META_IS_CACHEABLE(_dn) \
((_dn)->dn_objset->os_primary_cache == ZFS_CACHE_ALL || \
(_dn)->dn_objset->os_primary_cache == ZFS_CACHE_METADATA)
/*
* Used for dnodestats kstat.
*/

View file

@ -116,7 +116,7 @@ struct dsl_dir {
/* gross estimate of space used by in-flight tx's */
uint64_t dd_tempreserved[TXG_SIZE];
/* amount of space we expect to write; == amount of dirty data */
int64_t dd_space_towrite[TXG_SIZE];
uint64_t dd_space_towrite[TXG_SIZE];
dsl_deadlist_t dd_livelist;
bplist_t dd_pending_frees;

View file

@ -78,6 +78,10 @@ extern "C" {
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_READ_ERRORS "vdev_read_errors"
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_WRITE_ERRORS "vdev_write_errors"
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_ERRORS "vdev_cksum_errors"
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_N "vdev_cksum_n"
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_CKSUM_T "vdev_cksum_t"
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_N "vdev_io_n"
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_IO_T "vdev_io_t"
#define FM_EREPORT_PAYLOAD_ZFS_VDEV_DELAYS "vdev_delays"
#define FM_EREPORT_PAYLOAD_ZFS_PARENT_GUID "parent_guid"
#define FM_EREPORT_PAYLOAD_ZFS_PARENT_TYPE "parent_type"

View file

@ -356,6 +356,10 @@ typedef enum {
VDEV_PROP_REMOVING,
VDEV_PROP_ALLOCATING,
VDEV_PROP_FAILFAST,
VDEV_PROP_CHECKSUM_N,
VDEV_PROP_CHECKSUM_T,
VDEV_PROP_IO_N,
VDEV_PROP_IO_T,
VDEV_NUM_PROPS
} vdev_prop_t;
@ -1657,6 +1661,7 @@ typedef enum {
#define ZFS_ONLINE_UNSPARE 0x2
#define ZFS_ONLINE_FORCEFAULT 0x4
#define ZFS_ONLINE_EXPAND 0x8
#define ZFS_ONLINE_SPARE 0x10
#define ZFS_OFFLINE_TEMPORARY 0x1
/*

View file

@ -1146,7 +1146,7 @@ extern nvlist_t *zfs_event_create(spa_t *spa, vdev_t *vd, const char *type,
extern void zfs_post_remove(spa_t *spa, vdev_t *vd);
extern void zfs_post_state_change(spa_t *spa, vdev_t *vd, uint64_t laststate);
extern void zfs_post_autoreplace(spa_t *spa, vdev_t *vd);
extern uint64_t spa_get_errlog_size(spa_t *spa);
extern uint64_t spa_approx_errlog_size(spa_t *spa);
extern int spa_get_errlog(spa_t *spa, void *uaddr, uint64_t *count);
extern void spa_errlog_rotate(spa_t *spa);
extern void spa_errlog_drain(spa_t *spa);

View file

@ -469,6 +469,14 @@ struct vdev {
zfs_ratelimit_t vdev_delay_rl;
zfs_ratelimit_t vdev_deadman_rl;
zfs_ratelimit_t vdev_checksum_rl;
/*
* Checksum and IO thresholds for tuning ZED
*/
uint64_t vdev_checksum_n;
uint64_t vdev_checksum_t;
uint64_t vdev_io_n;
uint64_t vdev_io_t;
};
#define VDEV_PAD_SIZE (8 << 10)

View file

@ -272,6 +272,8 @@ extern int zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t);
extern void zfs_znode_init(void);
extern void zfs_znode_fini(void);
extern int zfs_znode_hold_compare(const void *, const void *);
extern znode_hold_t *zfs_znode_hold_enter(zfsvfs_t *, uint64_t);
extern void zfs_znode_hold_exit(zfsvfs_t *, znode_hold_t *);
extern int zfs_zget(zfsvfs_t *, uint64_t, znode_t **);
extern int zfs_rezget(znode_t *);
extern void zfs_zinactive(znode_t *);

View file

@ -34,9 +34,8 @@ extern "C" {
typedef struct zrlock {
kmutex_t zr_mtx;
volatile int32_t zr_refcount;
kcondvar_t zr_cv;
uint16_t zr_pad;
volatile int32_t zr_refcount;
#ifdef ZFS_DEBUG
kthread_t *zr_owner;
const char *zr_caller;

View file

@ -67,3 +67,4 @@ nodist_libicp_la_SOURCES += \
module/icp/asm-x86_64/blake3/blake3_sse2.S \
module/icp/asm-x86_64/blake3/blake3_sse41.S
endif

View file

@ -26,6 +26,7 @@ libspl_sysdir = $(libspldir)/sys
libspl_sys_HEADERS = \
%D%/sys/acl.h \
%D%/sys/acl_impl.h \
%D%/sys/asm_linkage.h \
%D%/sys/callb.h \
%D%/sys/cmn_err.h \
%D%/sys/cred.h \
@ -62,6 +63,8 @@ libspl_sys_HEADERS = \
%D%/sys/wmsum.h \
%D%/sys/zone.h
libspl_ia32dir = $(libspldir)/sys/ia32
if BUILD_LINUX
libspl_sys_HEADERS += \
%D%/os/linux/sys/byteorder.h \
@ -72,6 +75,9 @@ libspl_sys_HEADERS += \
%D%/os/linux/sys/stat.h \
%D%/os/linux/sys/sysmacros.h \
%D%/os/linux/sys/zfs_context_os.h
libspl_ia32_HEADERS = \
%D%/os/linux/sys/ia32/asm_linkage.h
endif
if BUILD_FREEBSD
@ -86,9 +92,13 @@ libspl_sys_HEADERS += \
%D%/os/freebsd/sys/sysmacros.h \
%D%/os/freebsd/sys/vfs.h \
%D%/os/freebsd/sys/zfs_context_os.h
libspl_ia32_HEADERS = \
%D%/os/freebsd/sys/ia32/asm_linkage.h
endif
libspl_sys_dktpdir = $(libspl_sysdir)/dktp
libspl_sys_dktp_HEADERS = \
%D%/sys/dktp/fdisk.h

View file

@ -0,0 +1,184 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IA32_SYS_ASM_LINKAGE_H
#define _IA32_SYS_ASM_LINKAGE_H
#if defined(__linux__) && defined(CONFIG_SLS)
#define RET ret; int3
#else
#define RET ret
#endif
/* Tell compiler to call assembler like Unix */
#undef ASMABI
#define ASMABI __attribute__((sysv_abi))
#define ENDBR
#define SECTION_TEXT .text
#define SECTION_STATIC .data
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASM /* The remainder of this file is only for assembly files */
/*
* make annoying differences in assembler syntax go away
*/
/*
* D16 and A16 are used to insert instructions prefixes; the
* macros help the assembler code be slightly more portable.
*/
#if !defined(__GNUC_AS__)
/*
* /usr/ccs/bin/as prefixes are parsed as separate instructions
*/
#define D16 data16;
#define A16 addr16;
/*
* (There are some weird constructs in constant expressions)
*/
#define _CONST(const) [const]
#define _BITNOT(const) -1!_CONST(const)
#define _MUL(a, b) _CONST(a \* b)
#else
/*
* Why not use the 'data16' and 'addr16' prefixes .. well, the
* assembler doesn't quite believe in real mode, and thus argues with
* us about what we're trying to do.
*/
#define D16 .byte 0x66;
#define A16 .byte 0x67;
#define _CONST(const) (const)
#define _BITNOT(const) ~_CONST(const)
#define _MUL(a, b) _CONST(a * b)
#endif
/*
* C pointers are different sizes between i386 and amd64.
* These constants can be used to compute offsets into pointer arrays.
*/
#if defined(__amd64)
#define CLONGSHIFT 3
#define CLONGSIZE 8
#define CLONGMASK 7
#elif defined(__i386)
#define CLONGSHIFT 2
#define CLONGSIZE 4
#define CLONGMASK 3
#endif
/*
* Since we know we're either ILP32 or LP64 ..
*/
#define CPTRSHIFT CLONGSHIFT
#define CPTRSIZE CLONGSIZE
#define CPTRMASK CLONGMASK
#if CPTRSIZE != (1 << CPTRSHIFT) || CLONGSIZE != (1 << CLONGSHIFT)
#error "inconsistent shift constants"
#endif
#if CPTRMASK != (CPTRSIZE - 1) || CLONGMASK != (CLONGSIZE - 1)
#error "inconsistent mask constants"
#endif
#define ASM_ENTRY_ALIGN 16
/*
* SSE register alignment and save areas
*/
#define XMM_SIZE 16
#define XMM_ALIGN 16
/*
* ENTRY provides the standard procedure entry code and an easy way to
* insert the calls to mcount for profiling. ENTRY_NP is identical, but
* never calls mcount.
*/
#define ENTRY(x) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
x: MCOUNT(x)
#define ENTRY_NP(x) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
x:
#define ENTRY_ALIGN(x, a) \
.text; \
.balign a; \
.globl x; \
x:
#define FUNCTION(x) \
.type x, @function; \
x:
/*
* ENTRY2 is identical to ENTRY but provides two labels for the entry point.
*/
#define ENTRY2(x, y) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
x:; \
y: MCOUNT(x)
#define ENTRY_NP2(x, y) \
.text; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
x:; \
y:
/*
* SET_SIZE trails a function and set the size for the ELF symbol table.
*/
#define SET_SIZE(x)
#define SET_OBJ(x)
#endif /* _ASM */
#ifdef __cplusplus
}
#endif
#endif /* _IA32_SYS_ASM_LINKAGE_H */

View file

@ -27,9 +27,6 @@
#ifndef _IA32_SYS_ASM_LINKAGE_H
#define _IA32_SYS_ASM_LINKAGE_H
#include <sys/stack.h>
#include <sys/trap.h>
#if defined(_KERNEL) && defined(__linux__)
#include <linux/linkage.h>
#endif
@ -56,6 +53,13 @@
#define RET ret
#endif
/* You can set to nothing on Unix platforms */
#undef ASMABI
#define ASMABI __attribute__((sysv_abi))
#define SECTION_TEXT .text
#define SECTION_STATIC .section .rodata
#ifdef __cplusplus
extern "C" {
#endif
@ -145,24 +149,35 @@ extern "C" {
#undef ENTRY
#define ENTRY(x) \
.text; \
.align ASM_ENTRY_ALIGN; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
.type x, @function; \
x: MCOUNT(x)
#define ENTRY_NP(x) \
.text; \
.align ASM_ENTRY_ALIGN; \
.balign ASM_ENTRY_ALIGN; \
.globl x; \
.type x, @function; \
x:
#define ENTRY_ALIGN(x, a) \
.text; \
.balign a; \
.globl x; \
.type x, @function; \
x:
#define FUNCTION(x) \
.type x, @function; \
x:
/*
* ENTRY2 is identical to ENTRY but provides two labels for the entry point.
*/
#define ENTRY2(x, y) \
.text; \
.align ASM_ENTRY_ALIGN; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
.type x, @function; \
.type y, @function; \
@ -171,7 +186,7 @@ y: MCOUNT(x)
#define ENTRY_NP2(x, y) \
.text; \
.align ASM_ENTRY_ALIGN; \
.balign ASM_ENTRY_ALIGN; \
.globl x, y; \
.type x, @function; \
.type y, @function; \
@ -185,6 +200,8 @@ x:; \
#define SET_SIZE(x) \
.size x, [.-x]
#define SET_OBJ(x) .type x, @object
#endif /* _ASM */
#ifdef __cplusplus

View file

@ -416,6 +416,8 @@
<elf-symbol name='zfs_send_resume_token_to_nvlist' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_send_saved' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_set_fsacl' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_setproctitle' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_setproctitle_init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_share' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_show_diffs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zfs_smb_acl_add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -2925,13 +2927,14 @@
<abi-instr address-size='64' path='lib/libzfs/libzfs_iter.c' language='LANG_C99'>
<function-decl name='zfs_iter_filesystems' mangled-name='zfs_iter_filesystems' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_filesystems'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='95e97e5e' name='flags'/>
<parameter type-id='d8e49ab9' name='func'/>
<parameter type-id='eaa32e2f' name='data'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='zfs_iter_snapshots' mangled-name='zfs_iter_snapshots' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='c19b74c3' name='simple'/>
<parameter type-id='95e97e5e' name='flags'/>
<parameter type-id='d8e49ab9' name='func'/>
<parameter type-id='eaa32e2f' name='data'/>
<parameter type-id='9c313c2d' name='min_txg'/>
@ -2940,12 +2943,14 @@
</function-decl>
<function-decl name='zfs_iter_bookmarks' mangled-name='zfs_iter_bookmarks' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_bookmarks'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='95e97e5e' name='flags'/>
<parameter type-id='d8e49ab9' name='func'/>
<parameter type-id='eaa32e2f' name='data'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='zfs_iter_snapshots_sorted' mangled-name='zfs_iter_snapshots_sorted' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapshots_sorted'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='95e97e5e' name='flags'/>
<parameter type-id='d8e49ab9' name='callback'/>
<parameter type-id='eaa32e2f' name='data'/>
<parameter type-id='9c313c2d' name='min_txg'/>
@ -2954,6 +2959,7 @@
</function-decl>
<function-decl name='zfs_iter_snapspec' mangled-name='zfs_iter_snapspec' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_snapspec'>
<parameter type-id='9200a744' name='fs_zhp'/>
<parameter type-id='95e97e5e' name='flags'/>
<parameter type-id='80f4b756' name='spec_orig'/>
<parameter type-id='d8e49ab9' name='func'/>
<parameter type-id='eaa32e2f' name='arg'/>
@ -2961,12 +2967,14 @@
</function-decl>
<function-decl name='zfs_iter_children' mangled-name='zfs_iter_children' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_children'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='95e97e5e' name='flags'/>
<parameter type-id='d8e49ab9' name='func'/>
<parameter type-id='eaa32e2f' name='data'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='zfs_iter_dependents' mangled-name='zfs_iter_dependents' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_iter_dependents'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='95e97e5e' name='flags'/>
<parameter type-id='c19b74c3' name='allowrecursion'/>
<parameter type-id='d8e49ab9' name='func'/>
<parameter type-id='eaa32e2f' name='data'/>
@ -3215,7 +3223,11 @@
<enumerator name='VDEV_PROP_REMOVING' value='39'/>
<enumerator name='VDEV_PROP_ALLOCATING' value='40'/>
<enumerator name='VDEV_PROP_FAILFAST' value='41'/>
<enumerator name='VDEV_NUM_PROPS' value='42'/>
<enumerator name='VDEV_PROP_CHECKSUM_N' value='42'/>
<enumerator name='VDEV_PROP_CHECKSUM_T' value='43'/>
<enumerator name='VDEV_PROP_IO_N' value='44'/>
<enumerator name='VDEV_PROP_IO_T' value='45'/>
<enumerator name='VDEV_NUM_PROPS' value='46'/>
</enum-decl>
<typedef-decl name='vdev_prop_t' type-id='1573bec8' id='5aa5c90c'/>
<enum-decl name='vdev_state' id='21566197'>
@ -3828,6 +3840,11 @@
<pointer-type-def type-id='9e59d1d4' size-in-bits='64' id='4ea84b4f'/>
<pointer-type-def type-id='945467e6' size-in-bits='64' id='8def7735'/>
<pointer-type-def type-id='3d3ffb69' size-in-bits='64' id='72a26210'/>
<function-decl name='zfs_setproctitle' mangled-name='zfs_setproctitle' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_setproctitle'>
<parameter type-id='80f4b756'/>
<parameter is-variadic='yes'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zfs_send_progress' mangled-name='zfs_send_progress' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_send_progress'>
<parameter type-id='9200a744' name='zhp'/>
<parameter type-id='95e97e5e' name='fd'/>
@ -4519,6 +4536,12 @@
<parameter type-id='5ce45b60' name='nv'/>
<return type-id='48b5725f'/>
</function-decl>
<function-decl name='zfs_setproctitle_init' mangled-name='zfs_setproctitle_init' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfs_setproctitle_init'>
<parameter type-id='95e97e5e' name='argc'/>
<parameter type-id='9b23c9ad' name='argv'/>
<parameter type-id='9b23c9ad' name='envp'/>
<return type-id='48b5725f'/>
</function-decl>
</abi-instr>
<abi-instr address-size='64' path='lib/libzutil/zutil_device_path.c' language='LANG_C99'>
<typedef-decl name='ssize_t' type-id='41060289' id='79a0948f'/>

View file

@ -552,7 +552,7 @@ change_one(zfs_handle_t *zhp, void *data)
}
if (!clp->cl_alldependents)
ret = zfs_iter_children(zhp, change_one, data);
ret = zfs_iter_children(zhp, 0, change_one, data);
/*
* If we added the handle to the changelist, we will re-use it
@ -721,11 +721,11 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
return (NULL);
}
} else if (clp->cl_alldependents) {
if (zfs_iter_dependents(zhp, B_TRUE, change_one, clp) != 0) {
if (zfs_iter_dependents(zhp, 0, B_TRUE, change_one, clp) != 0) {
changelist_free(clp);
return (NULL);
}
} else if (zfs_iter_children(zhp, change_one, clp) != 0) {
} else if (zfs_iter_children(zhp, 0, change_one, clp) != 0) {
changelist_free(clp);
return (NULL);
}

View file

@ -1226,7 +1226,7 @@ load_keys_cb(zfs_handle_t *zhp, void *arg)
cb->cb_numfailed++;
out:
(void) zfs_iter_filesystems(zhp, load_keys_cb, cb);
(void) zfs_iter_filesystems(zhp, 0, load_keys_cb, cb);
zfs_close(zhp);
/* always return 0, since this function is best effort */

View file

@ -527,7 +527,30 @@ make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc)
zhp->zfs_head_type = pzhp->zfs_type;
zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
zhp->zpool_hdl = zpool_handle(zhp);
zhp->zfs_dmustats = zc->zc_objset_stats;
if (zc->zc_objset_stats.dds_creation_txg != 0) {
/* structure assignment */
zhp->zfs_dmustats = zc->zc_objset_stats;
} else {
if (get_stats_ioctl(zhp, zc) == -1) {
zcmd_free_nvlists(zc);
free(zhp);
return (NULL);
}
if (make_dataset_handle_common(zhp, zc) == -1) {
zcmd_free_nvlists(zc);
free(zhp);
return (NULL);
}
}
if (zhp->zfs_dmustats.dds_is_snapshot ||
strchr(zc->zc_name, '@') != NULL)
zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
zhp->zfs_type = ZFS_TYPE_VOLUME;
else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
return (zhp);
}
@ -690,6 +713,7 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
*/
if (!zfs_validate_name(hdl, path, types, B_FALSE)) {
(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
errno = EINVAL;
return (NULL);
}
@ -733,10 +757,11 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
* Iterate bookmarks to find the right one.
*/
errno = 0;
if ((zfs_iter_bookmarks(pzhp, zfs_open_bookmarks_cb,
if ((zfs_iter_bookmarks(pzhp, 0, zfs_open_bookmarks_cb,
&cb_data) == 0) && (cb_data.zhp == NULL)) {
(void) zfs_error(hdl, EZFS_NOENT, errbuf);
zfs_close(pzhp);
errno = ENOENT;
return (NULL);
}
if (cb_data.zhp == NULL) {
@ -755,6 +780,7 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
if (!(types & zhp->zfs_type)) {
(void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
zfs_close(zhp);
errno = EINVAL;
return (NULL);
}
@ -2083,7 +2109,8 @@ getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
static boolean_t
zfs_is_recvd_props_mode(zfs_handle_t *zhp)
{
return (zhp->zfs_props == zhp->zfs_recvd_props);
return (zhp->zfs_props != NULL &&
zhp->zfs_props == zhp->zfs_recvd_props);
}
static void
@ -2285,19 +2312,28 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
*val = zhp->zfs_dmustats.dds_redacted;
break;
case ZFS_PROP_GUID:
if (zhp->zfs_dmustats.dds_guid != 0)
*val = zhp->zfs_dmustats.dds_guid;
else
*val = getprop_uint64(zhp, prop, source);
break;
case ZFS_PROP_CREATETXG:
/*
* We can directly read createtxg property from zfs
* handle for Filesystem, Snapshot and ZVOL types.
*/
if ((zhp->zfs_type == ZFS_TYPE_FILESYSTEM) ||
if (((zhp->zfs_type == ZFS_TYPE_FILESYSTEM) ||
(zhp->zfs_type == ZFS_TYPE_SNAPSHOT) ||
(zhp->zfs_type == ZFS_TYPE_VOLUME)) {
(zhp->zfs_type == ZFS_TYPE_VOLUME)) &&
(zhp->zfs_dmustats.dds_creation_txg != 0)) {
*val = zhp->zfs_dmustats.dds_creation_txg;
break;
} else {
*val = getprop_uint64(zhp, prop, source);
}
zfs_fallthrough;
default:
switch (zfs_prop_get_type(prop)) {
case PROP_TYPE_NUMBER:
@ -2440,7 +2476,7 @@ get_clones_cb(zfs_handle_t *zhp, void *arg)
}
out:
(void) zfs_iter_children(zhp, get_clones_cb, gca);
(void) zfs_iter_children(zhp, 0, get_clones_cb, gca);
zfs_close(zhp);
return (0);
}
@ -2725,7 +2761,13 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
break;
case ZFS_PROP_ORIGIN:
str = getprop_string(zhp, prop, &source);
if (*zhp->zfs_dmustats.dds_origin != '\0') {
str = (char *)&zhp->zfs_dmustats.dds_origin;
} else {
str = getprop_string(zhp, prop, &source);
}
if (str == NULL || *str == '\0')
str = zfs_prop_default_string(prop);
if (str == NULL)
return (-1);
(void) strlcpy(propbuf, str, proplen);
@ -3883,7 +3925,7 @@ zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
if (lzc_exists(name))
fnvlist_add_boolean(dd->nvl, name);
rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
rv = zfs_iter_filesystems(zhp, 0, zfs_check_snap_cb, dd);
zfs_close(zhp);
return (rv);
}
@ -4121,7 +4163,7 @@ zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
fnvlist_add_boolean(sd->sd_nvl, name);
rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
rv = zfs_iter_filesystems(zhp, 0, zfs_snapshot_cb, sd);
}
zfs_close(zhp);
@ -4298,7 +4340,7 @@ rollback_destroy(zfs_handle_t *zhp, void *data)
rollback_data_t *cbp = data;
if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
cbp->cb_error |= zfs_iter_dependents(zhp, 0, B_FALSE,
rollback_destroy_dependent, cbp);
cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
@ -4338,10 +4380,10 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
if (cb.cb_create > 0)
min_txg = cb.cb_create;
(void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb,
(void) zfs_iter_snapshots(zhp, 0, rollback_destroy, &cb,
min_txg, 0);
(void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
(void) zfs_iter_bookmarks(zhp, 0, rollback_destroy, &cb);
if (cb.cb_error)
return (-1);
@ -4922,7 +4964,7 @@ zfs_hold_one(zfs_handle_t *zhp, void *arg)
fnvlist_add_string(ha->nvl, name, ha->tag);
if (ha->recursive)
rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
rv = zfs_iter_filesystems(zhp, 0, zfs_hold_one, ha);
zfs_close(zhp);
return (rv);
}
@ -5053,7 +5095,7 @@ zfs_release_one(zfs_handle_t *zhp, void *arg)
}
if (ha->recursive)
rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
rv = zfs_iter_filesystems(zhp, 0, zfs_release_one, ha);
zfs_close(zhp);
return (rv);
}

View file

@ -44,6 +44,7 @@
#include <pthread.h>
#include <sys/zfs_ioctl.h>
#include <libzfs.h>
#include <libzutil.h>
#include "libzfs_impl.h"
#define ZDIFF_SNAPDIR "/.zfs/snapshot/"
@ -54,6 +55,10 @@
#define ZDIFF_REMOVED '-'
#define ZDIFF_RENAMED "R"
#define ZDIFF_ADDED_COLOR ANSI_GREEN
#define ZDIFF_MODIFIED_COLOR ANSI_YELLOW
#define ZDIFF_REMOVED_COLOR ANSI_RED
#define ZDIFF_RENAMED_COLOR ANSI_BLUE
/*
* Given a {dsname, object id}, get the object path
@ -128,6 +133,25 @@ stream_bytes(FILE *fp, const char *string)
}
}
/*
* Takes the type of change (like `print_file`), outputs the appropriate color
*/
static const char *
type_to_color(char type)
{
if (type == '+')
return (ZDIFF_ADDED_COLOR);
else if (type == '-')
return (ZDIFF_REMOVED_COLOR);
else if (type == 'M')
return (ZDIFF_MODIFIED_COLOR);
else if (type == 'R')
return (ZDIFF_RENAMED_COLOR);
else
return (NULL);
}
static char
get_what(mode_t what)
{
@ -175,6 +199,8 @@ static void
print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
zfs_stat_t *isb)
{
if (isatty(fileno(fp)))
color_start(ZDIFF_RENAMED_COLOR);
if (di->timestamped)
(void) fprintf(fp, "%10lld.%09lld\t",
(longlong_t)isb->zs_ctime[0],
@ -186,12 +212,18 @@ print_rename(FILE *fp, differ_info_t *di, const char *old, const char *new,
(void) fputs(di->scripted ? "\t" : " -> ", fp);
print_cmn(fp, di, new);
(void) fputc('\n', fp);
if (isatty(fileno(fp)))
color_end();
}
static void
print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
zfs_stat_t *isb)
{
if (isatty(fileno(fp)))
color_start(ZDIFF_MODIFIED_COLOR);
if (di->timestamped)
(void) fprintf(fp, "%10lld.%09lld\t",
(longlong_t)isb->zs_ctime[0],
@ -201,12 +233,17 @@ print_link_change(FILE *fp, differ_info_t *di, int delta, const char *file,
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
print_cmn(fp, di, file);
(void) fprintf(fp, "\t(%+d)\n", delta);
if (isatty(fileno(fp)))
color_end();
}
static void
print_file(FILE *fp, differ_info_t *di, char type, const char *file,
zfs_stat_t *isb)
{
if (isatty(fileno(fp)))
color_start(type_to_color(type));
if (di->timestamped)
(void) fprintf(fp, "%10lld.%09lld\t",
(longlong_t)isb->zs_ctime[0],
@ -216,6 +253,9 @@ print_file(FILE *fp, differ_info_t *di, char type, const char *file,
(void) fprintf(fp, "%c\t", get_what(isb->zs_mode));
print_cmn(fp, di, file);
(void) fputc('\n', fp);
if (isatty(fileno(fp)))
color_end();
}
static int

View file

@ -39,7 +39,8 @@
#include "libzfs_impl.h"
static int
zfs_iter_clones(zfs_handle_t *zhp, zfs_iter_f func, void *data)
zfs_iter_clones(zfs_handle_t *zhp, int flags __maybe_unused, zfs_iter_f func,
void *data)
{
nvlist_t *nvl = zfs_get_clones_nvl(zhp);
nvpair_t *pair;
@ -69,6 +70,7 @@ zfs_do_list_ioctl(zfs_handle_t *zhp, int arg, zfs_cmd_t *zc)
orig_cookie = zc->zc_cookie;
top:
(void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
zc->zc_objset_stats.dds_creation_txg = 0;
rc = zfs_ioctl(zhp->zfs_hdl, arg, zc);
if (rc == -1) {
@ -101,7 +103,7 @@ zfs_do_list_ioctl(zfs_handle_t *zhp, int arg, zfs_cmd_t *zc)
* Iterate over all child filesystems
*/
int
zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
zfs_iter_filesystems(zfs_handle_t *zhp, int flags, zfs_iter_f func, void *data)
{
zfs_cmd_t zc = {"\0"};
zfs_handle_t *nzhp;
@ -112,16 +114,21 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0);
if ((flags & ZFS_ITER_SIMPLE) == ZFS_ITER_SIMPLE)
zc.zc_simple = B_TRUE;
while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_DATASET_LIST_NEXT,
&zc)) == 0) {
if (zc.zc_simple)
nzhp = make_dataset_simple_handle_zc(zhp, &zc);
else
nzhp = make_dataset_handle_zc(zhp->zfs_hdl, &zc);
/*
* Silently ignore errors, as the only plausible explanation is
* that the pool has since been removed.
*/
if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl,
&zc)) == NULL) {
if (nzhp == NULL)
continue;
}
if ((ret = func(nzhp, data)) != 0) {
zcmd_free_nvlists(&zc);
@ -136,7 +143,7 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data)
* Iterate over all snapshots
*/
int
zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
zfs_iter_snapshots(zfs_handle_t *zhp, int flags, zfs_iter_f func,
void *data, uint64_t min_txg, uint64_t max_txg)
{
zfs_cmd_t zc = {"\0"};
@ -148,7 +155,7 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
zhp->zfs_type == ZFS_TYPE_BOOKMARK)
return (0);
zc.zc_simple = simple;
zc.zc_simple = (flags & ZFS_ITER_SIMPLE) != 0;
zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0);
@ -168,7 +175,7 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT,
&zc)) == 0) {
if (simple)
if (zc.zc_simple)
nzhp = make_dataset_simple_handle_zc(zhp, &zc);
else
nzhp = make_dataset_handle_zc(zhp->zfs_hdl, &zc);
@ -190,7 +197,8 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
* Iterate over all bookmarks
*/
int
zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data)
zfs_iter_bookmarks(zfs_handle_t *zhp, int flags __maybe_unused,
zfs_iter_f func, void *data)
{
zfs_handle_t *nzhp;
nvlist_t *props = NULL;
@ -297,8 +305,8 @@ zfs_snapshot_compare(const void *larg, const void *rarg)
}
int
zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data,
uint64_t min_txg, uint64_t max_txg)
zfs_iter_snapshots_sorted(zfs_handle_t *zhp, int flags, zfs_iter_f callback,
void *data, uint64_t min_txg, uint64_t max_txg)
{
int ret = 0;
zfs_node_t *node;
@ -308,7 +316,7 @@ zfs_iter_snapshots_sorted(zfs_handle_t *zhp, zfs_iter_f callback, void *data,
avl_create(&avl, zfs_snapshot_compare,
sizeof (zfs_node_t), offsetof(zfs_node_t, zn_avlnode));
ret = zfs_iter_snapshots(zhp, B_FALSE, zfs_sort_snaps, &avl, min_txg,
ret = zfs_iter_snapshots(zhp, flags, zfs_sort_snaps, &avl, min_txg,
max_txg);
for (node = avl_first(&avl); node != NULL; node = AVL_NEXT(&avl, node))
@ -371,7 +379,7 @@ snapspec_cb(zfs_handle_t *zhp, void *arg)
* return ENOENT at the end.
*/
int
zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
zfs_iter_snapspec(zfs_handle_t *fs_zhp, int flags, const char *spec_orig,
zfs_iter_f func, void *arg)
{
char *buf, *comma_separated, *cp;
@ -411,7 +419,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
}
}
err = zfs_iter_snapshots_sorted(fs_zhp,
err = zfs_iter_snapshots_sorted(fs_zhp, flags,
snapspec_cb, &ssa, 0, 0);
if (ret == 0)
ret = err;
@ -448,14 +456,14 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
* and as close as possible.
*/
int
zfs_iter_children(zfs_handle_t *zhp, zfs_iter_f func, void *data)
zfs_iter_children(zfs_handle_t *zhp, int flags, zfs_iter_f func, void *data)
{
int ret;
if ((ret = zfs_iter_snapshots(zhp, B_FALSE, func, data, 0, 0)) != 0)
if ((ret = zfs_iter_snapshots(zhp, flags, func, data, 0, 0)) != 0)
return (ret);
return (zfs_iter_filesystems(zhp, func, data));
return (zfs_iter_filesystems(zhp, flags, func, data));
}
@ -466,6 +474,7 @@ typedef struct iter_stack_frame {
typedef struct iter_dependents_arg {
boolean_t first;
int flags;
boolean_t allowrecursion;
iter_stack_frame_t *stack;
zfs_iter_f func;
@ -481,7 +490,7 @@ iter_dependents_cb(zfs_handle_t *zhp, void *arg)
ida->first = B_FALSE;
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
err = zfs_iter_clones(zhp, iter_dependents_cb, ida);
err = zfs_iter_clones(zhp, ida->flags, iter_dependents_cb, ida);
} else if (zhp->zfs_type != ZFS_TYPE_BOOKMARK) {
iter_stack_frame_t isf;
iter_stack_frame_t *f;
@ -515,9 +524,10 @@ iter_dependents_cb(zfs_handle_t *zhp, void *arg)
isf.zhp = zhp;
isf.next = ida->stack;
ida->stack = &isf;
err = zfs_iter_filesystems(zhp, iter_dependents_cb, ida);
err = zfs_iter_filesystems(zhp, ida->flags,
iter_dependents_cb, ida);
if (err == 0)
err = zfs_iter_snapshots(zhp, B_FALSE,
err = zfs_iter_snapshots(zhp, ida->flags,
iter_dependents_cb, ida, 0, 0);
ida->stack = isf.next;
}
@ -531,10 +541,11 @@ iter_dependents_cb(zfs_handle_t *zhp, void *arg)
}
int
zfs_iter_dependents(zfs_handle_t *zhp, boolean_t allowrecursion,
zfs_iter_dependents(zfs_handle_t *zhp, int flags, boolean_t allowrecursion,
zfs_iter_f func, void *data)
{
iter_dependents_arg_t ida;
ida.flags = flags;
ida.allowrecursion = allowrecursion;
ida.stack = NULL;
ida.func = func;

View file

@ -940,7 +940,7 @@ zfs_iter_cb(zfs_handle_t *zhp, void *data)
}
libzfs_add_handle(cbp, zhp);
if (zfs_iter_filesystems(zhp, zfs_iter_cb, cbp) != 0) {
if (zfs_iter_filesystems(zhp, 0, zfs_iter_cb, cbp) != 0) {
zfs_close(zhp);
return (-1);
}
@ -1289,7 +1289,7 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
* over all child filesystems.
*/
libzfs_add_handle(&cb, zfsp);
if (zfs_iter_filesystems(zfsp, zfs_iter_cb, &cb) != 0)
if (zfs_iter_filesystems(zfsp, 0, zfs_iter_cb, &cb) != 0)
goto out;
/*

View file

@ -2961,7 +2961,7 @@ zpool_vdev_online(zpool_handle_t *zhp, const char *path, int flags,
zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
if (avail_spare)
if (!(flags & ZFS_ONLINE_SPARE) && avail_spare)
return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
#ifndef __FreeBSD__
@ -3098,9 +3098,6 @@ zpool_vdev_remove_wanted(zpool_handle_t *zhp, const char *path)
zc.zc_guid = fnvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID);
if (avail_spare)
return (zfs_error(hdl, EZFS_ISSPARE, errbuf));
zc.zc_cookie = VDEV_STATE_REMOVED;
if (zfs_ioctl(hdl, ZFS_IOC_VDEV_SET_STATE, &zc) == 0)
@ -4133,33 +4130,28 @@ zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
{
zfs_cmd_t zc = {"\0"};
libzfs_handle_t *hdl = zhp->zpool_hdl;
uint64_t count;
zbookmark_phys_t *zb = NULL;
int i;
zbookmark_phys_t *buf;
uint64_t buflen = 10000; /* approx. 1MB of RAM */
if (fnvlist_lookup_uint64(zhp->zpool_config,
ZPOOL_CONFIG_ERRCOUNT) == 0)
return (0);
/*
* Retrieve the raw error list from the kernel. If the number of errors
* has increased, allocate more space and continue until we get the
* entire list.
* Retrieve the raw error list from the kernel. If it doesn't fit,
* allocate a larger buffer and retry.
*/
count = fnvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT);
if (count == 0)
return (0);
zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
count * sizeof (zbookmark_phys_t));
zc.zc_nvlist_dst_size = count;
(void) strcpy(zc.zc_name, zhp->zpool_name);
for (;;) {
buf = zfs_alloc(zhp->zpool_hdl,
buflen * sizeof (zbookmark_phys_t));
zc.zc_nvlist_dst = (uintptr_t)buf;
zc.zc_nvlist_dst_size = buflen;
if (zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_ERROR_LOG,
&zc) != 0) {
free((void *)(uintptr_t)zc.zc_nvlist_dst);
free(buf);
if (errno == ENOMEM) {
void *dst;
count = zc.zc_nvlist_dst_size;
dst = zfs_alloc(zhp->zpool_hdl, count *
sizeof (zbookmark_phys_t));
zc.zc_nvlist_dst = (uintptr_t)dst;
buflen *= 2;
} else {
return (zpool_standard_error_fmt(hdl, errno,
dgettext(TEXT_DOMAIN, "errors: List of "
@ -4177,18 +4169,17 @@ zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
* _not_ copied as part of the process. So we point the start of our
* array appropriate and decrement the total number of elements.
*/
zb = ((zbookmark_phys_t *)(uintptr_t)zc.zc_nvlist_dst) +
zc.zc_nvlist_dst_size;
count -= zc.zc_nvlist_dst_size;
zbookmark_phys_t *zb = buf + zc.zc_nvlist_dst_size;
uint64_t zblen = buflen - zc.zc_nvlist_dst_size;
qsort(zb, count, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
qsort(zb, zblen, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);
/*
* Fill in the nverrlistp with nvlist's of dataset and object numbers.
*/
for (i = 0; i < count; i++) {
for (uint64_t i = 0; i < zblen; i++) {
nvlist_t *nv;
/* ignoring zb_blkid and zb_level for now */
@ -4215,11 +4206,11 @@ zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
nvlist_free(nv);
}
free((void *)(uintptr_t)zc.zc_nvlist_dst);
free(buf);
return (0);
nomem:
free((void *)(uintptr_t)zc.zc_nvlist_dst);
free(buf);
return (no_memory(zhp->zpool_hdl));
}
@ -5011,6 +5002,17 @@ zpool_get_vdev_prop_value(nvlist_t *nvprop, vdev_prop_t prop, char *prop_name,
(u_longlong_t)intval);
}
break;
case VDEV_PROP_CHECKSUM_N:
case VDEV_PROP_CHECKSUM_T:
case VDEV_PROP_IO_N:
case VDEV_PROP_IO_T:
if (intval == UINT64_MAX) {
(void) strlcpy(buf, "-", len);
} else {
(void) snprintf(buf, len, "%llu",
(u_longlong_t)intval);
}
break;
case VDEV_PROP_FRAGMENTATION:
if (intval == UINT64_MAX) {
(void) strlcpy(buf, "-", len);

View file

@ -83,6 +83,8 @@ typedef struct progress_arg {
boolean_t pa_parsable;
boolean_t pa_estimate;
int pa_verbosity;
boolean_t pa_astitle;
uint64_t pa_size;
} progress_arg_t;
static int
@ -616,10 +618,10 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
min_txg = fromsnap_txg;
if (!sd->replicate && tosnap_txg != 0)
max_txg = tosnap_txg;
(void) zfs_iter_snapshots_sorted(zhp, send_iterate_snap, sd,
(void) zfs_iter_snapshots_sorted(zhp, 0, send_iterate_snap, sd,
min_txg, max_txg);
} else {
char snapname[MAXPATHLEN];
char snapname[MAXPATHLEN] = { 0 };
zfs_handle_t *snap;
(void) snprintf(snapname, sizeof (snapname), "%s@%s",
@ -659,7 +661,7 @@ send_iterate_fs(zfs_handle_t *zhp, void *arg)
/* Iterate over children. */
if (sd->recursive)
rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);
rv = zfs_iter_filesystems(zhp, 0, send_iterate_fs, sd);
out:
/* Restore saved fields. */
@ -733,6 +735,7 @@ typedef struct send_dump_data {
boolean_t seenfrom, seento, replicate, doall, fromorigin;
boolean_t dryrun, parsable, progress, embed_data, std_out;
boolean_t large_block, compress, raw, holds;
boolean_t progressastitle;
int outfd;
boolean_t err;
nvlist_t *fss;
@ -931,12 +934,13 @@ send_progress_thread(void *arg)
zfs_handle_t *zhp = pa->pa_zhp;
uint64_t bytes;
uint64_t blocks;
uint64_t total = pa->pa_size / 100;
char buf[16];
time_t t;
struct tm tm;
int err;
if (!pa->pa_parsable) {
if (!pa->pa_parsable && pa->pa_verbosity != 0) {
(void) fprintf(stderr,
"TIME %s %sSNAPSHOT %s\n",
pa->pa_estimate ? "BYTES" : " SENT",
@ -959,6 +963,17 @@ send_progress_thread(void *arg)
(void) time(&t);
localtime_r(&t, &tm);
if (pa->pa_astitle) {
char buf_bytes[16];
char buf_size[16];
int pct;
zfs_nicenum(bytes, buf_bytes, sizeof (buf_bytes));
zfs_nicenum(pa->pa_size, buf_size, sizeof (buf_size));
pct = (total > 0) ? bytes / total : 100;
zfs_setproctitle("sending %s (%d%%: %s/%s)",
zhp->zfs_name, MIN(pct, 100), buf_bytes, buf_size);
}
if (pa->pa_verbosity >= 2 && pa->pa_parsable) {
(void) fprintf(stderr,
"%02d:%02d:%02d\t%llu\t%llu\t%s\n",
@ -975,7 +990,7 @@ send_progress_thread(void *arg)
(void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
tm.tm_hour, tm.tm_min, tm.tm_sec,
(u_longlong_t)bytes, zhp->zfs_name);
} else {
} else if (pa->pa_verbosity != 0) {
zfs_nicebytes(bytes, buf, sizeof (buf));
(void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
tm.tm_hour, tm.tm_min, tm.tm_sec,
@ -1183,12 +1198,14 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
* If progress reporting is requested, spawn a new thread to
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
*/
if (sdd->progress) {
if (sdd->progress || sdd->progressastitle) {
pa.pa_zhp = zhp;
pa.pa_fd = sdd->outfd;
pa.pa_parsable = sdd->parsable;
pa.pa_estimate = B_FALSE;
pa.pa_verbosity = sdd->verbosity;
pa.pa_size = sdd->size;
pa.pa_astitle = sdd->progressastitle;
if ((err = pthread_create(&tid, NULL,
send_progress_thread, &pa)) != 0) {
@ -1200,7 +1217,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
fromorigin, sdd->outfd, flags, sdd->debugnv);
if (sdd->progress &&
if ((sdd->progress || sdd->progressastitle) &&
send_progress_thread_exit(zhp->zfs_hdl, tid))
return (-1);
}
@ -1274,7 +1291,7 @@ dump_filesystem(zfs_handle_t *zhp, send_dump_data_t *sdd)
zhp->zfs_name, sdd->tosnap);
}
}
rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, sdd,
rv = zfs_iter_snapshots_sorted(zhp, 0, dump_snapshot, sdd,
min_txg, max_txg);
} else {
char snapname[MAXPATHLEN] = { 0 };
@ -1289,7 +1306,7 @@ dump_filesystem(zfs_handle_t *zhp, send_dump_data_t *sdd)
if (snap != NULL)
rv = dump_snapshot(snap, sdd);
else
rv = -1;
rv = errno;
}
/* Dump tosnap. */
@ -1301,7 +1318,7 @@ dump_filesystem(zfs_handle_t *zhp, send_dump_data_t *sdd)
if (snap != NULL)
rv = dump_snapshot(snap, sdd);
else
rv = -1;
rv = errno;
}
}
@ -1536,7 +1553,7 @@ lzc_flags_from_sendflags(const sendflags_t *flags)
static int
estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
uint64_t resumeobj, uint64_t resumeoff, uint64_t bytes,
const char *redactbook, char *errbuf)
const char *redactbook, char *errbuf, uint64_t *sizep)
{
uint64_t size;
FILE *fout = flags->dryrun ? stdout : stderr;
@ -1544,7 +1561,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
int err = 0;
pthread_t ptid;
if (flags->progress) {
if (flags->progress || flags->progressastitle) {
pa.pa_zhp = zhp;
pa.pa_fd = fd;
pa.pa_parsable = flags->parsable;
@ -1563,10 +1580,15 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
err = lzc_send_space_resume_redacted(zhp->zfs_name, from,
lzc_flags_from_sendflags(flags), resumeobj, resumeoff, bytes,
redactbook, fd, &size);
*sizep = size;
if (flags->progress && send_progress_thread_exit(zhp->zfs_hdl, ptid))
if ((flags->progress || flags->progressastitle) &&
send_progress_thread_exit(zhp->zfs_hdl, ptid))
return (-1);
if (!flags->progress && !flags->parsable)
return (err);
if (err != 0) {
zfs_error_aux(zhp->zfs_hdl, "%s", strerror(err));
return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
@ -1743,6 +1765,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
uint64_t *redact_snap_guids = NULL;
int num_redact_snaps = 0;
char *redact_book = NULL;
uint64_t size = 0;
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot resume send"));
@ -1828,7 +1851,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
enum lzc_send_flags lzc_flags = lzc_flags_from_sendflags(flags) |
lzc_flags_from_resume_nvl(resume_nvl);
if (flags->verbosity != 0) {
if (flags->verbosity != 0 || flags->progressastitle) {
/*
* Some of these may have come from the resume token, set them
* here for size estimate purposes.
@ -1845,7 +1868,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
if (lzc_flags & LZC_SEND_FLAG_SAVED)
tmpflags.saved = B_TRUE;
error = estimate_size(zhp, fromname, outfd, &tmpflags,
resumeobj, resumeoff, bytes, redact_book, errbuf);
resumeobj, resumeoff, bytes, redact_book, errbuf, &size);
}
if (!flags->dryrun) {
@ -1855,12 +1878,14 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
* If progress reporting is requested, spawn a new thread to
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
*/
if (flags->progress) {
if (flags->progress || flags->progressastitle) {
pa.pa_zhp = zhp;
pa.pa_fd = outfd;
pa.pa_parsable = flags->parsable;
pa.pa_estimate = B_FALSE;
pa.pa_verbosity = flags->verbosity;
pa.pa_size = size;
pa.pa_astitle = flags->progressastitle;
error = pthread_create(&tid, NULL,
send_progress_thread, &pa);
@ -1877,8 +1902,11 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
if (redact_book != NULL)
free(redact_book);
if (flags->progress && send_progress_thread_exit(hdl, tid))
if ((flags->progressastitle || flags->progress) &&
send_progress_thread_exit(hdl, tid)) {
zfs_close(zhp);
return (-1);
}
char errbuf[ERRBUFLEN];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
@ -2313,6 +2341,7 @@ zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sdd.verbosity = flags->verbosity;
sdd.parsable = flags->parsable;
sdd.progress = flags->progress;
sdd.progressastitle = flags->progressastitle;
sdd.dryrun = flags->dryrun;
sdd.large_block = flags->largeblock;
sdd.embed_data = flags->embed_data;
@ -2562,6 +2591,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
char *name = zhp->zfs_name;
pthread_t ptid;
progress_arg_t pa = { 0 };
uint64_t size = 0;
char errbuf[ERRBUFLEN];
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
@ -2644,9 +2674,9 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
/*
* Perform size estimate if verbose was specified.
*/
if (flags->verbosity != 0) {
if (flags->verbosity != 0 || flags->progressastitle) {
err = estimate_size(zhp, from, fd, flags, 0, 0, 0, redactbook,
errbuf);
errbuf, &size);
if (err != 0)
return (err);
}
@ -2658,12 +2688,14 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
* If progress reporting is requested, spawn a new thread to poll
* ZFS_IOC_SEND_PROGRESS at a regular interval.
*/
if (flags->progress) {
if (flags->progress || flags->progressastitle) {
pa.pa_zhp = zhp;
pa.pa_fd = fd;
pa.pa_parsable = flags->parsable;
pa.pa_estimate = B_FALSE;
pa.pa_verbosity = flags->verbosity;
pa.pa_size = size;
pa.pa_astitle = flags->progressastitle;
err = pthread_create(&ptid, NULL,
send_progress_thread, &pa);
@ -2677,7 +2709,8 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
err = lzc_send_redacted(name, from, fd,
lzc_flags_from_sendflags(flags), redactbook);
if (flags->progress && send_progress_thread_exit(hdl, ptid))
if ((flags->progress || flags->progressastitle) &&
send_progress_thread_exit(hdl, ptid))
return (-1);
if (err == 0 && (flags->props || flags->holds || flags->backup)) {
@ -3125,9 +3158,9 @@ guid_to_name_cb(zfs_handle_t *zhp, void *arg)
return (EEXIST);
}
err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
err = zfs_iter_children(zhp, 0, guid_to_name_cb, gtnd);
if (err != EEXIST && gtnd->bookmark_ok)
err = zfs_iter_bookmarks(zhp, guid_to_name_cb, gtnd);
err = zfs_iter_bookmarks(zhp, 0, guid_to_name_cb, gtnd);
zfs_close(zhp);
return (err);
}
@ -3181,9 +3214,10 @@ guid_to_name_redact_snaps(libzfs_handle_t *hdl, const char *parent,
continue;
int err = guid_to_name_cb(zfs_handle_dup(zhp), &gtnd);
if (err != EEXIST)
err = zfs_iter_children(zhp, guid_to_name_cb, &gtnd);
err = zfs_iter_children(zhp, 0, guid_to_name_cb, &gtnd);
if (err != EEXIST && bookmark_ok)
err = zfs_iter_bookmarks(zhp, guid_to_name_cb, &gtnd);
err = zfs_iter_bookmarks(zhp, 0, guid_to_name_cb,
&gtnd);
zfs_close(zhp);
if (err == EEXIST)
return (0);
@ -4149,6 +4183,15 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
goto error;
}
/*
* For plain replicated send, we can ignore encryption
* properties other than first stream
*/
if ((zfs_prop_encryption_key_param(prop) || prop ==
ZFS_PROP_ENCRYPTION) && !newfs && recursive && !raw) {
continue;
}
/* incremental streams can only exclude encryption properties */
if ((zfs_prop_encryption_key_param(prop) ||
prop == ZFS_PROP_ENCRYPTION) && !newfs &&
@ -4250,7 +4293,8 @@ zfs_setup_cmdline_props(libzfs_handle_t *hdl, zfs_type_t type,
if (cp != NULL)
*cp = '\0';
if (!raw && zfs_crypto_create(hdl, namebuf, voprops, NULL,
if (!raw && !(!newfs && recursive) &&
zfs_crypto_create(hdl, namebuf, voprops, NULL,
B_FALSE, wkeydata_out, wkeylen_out) != 0) {
fnvlist_free(voprops);
ret = zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
@ -5073,14 +5117,14 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
*cp = '@';
break;
case EINVAL:
if (flags->resumable) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"kernel modules must be upgraded to "
"receive this stream."));
} else if (embedded && !raw) {
if (embedded && !raw) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"incompatible embedded data stream "
"feature with encrypted receive."));
} else if (flags->resumable) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"kernel modules must be upgraded to "
"receive this stream."));
}
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
break;
@ -5153,6 +5197,14 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
destsnap);
*cp = '@';
break;
case E2BIG:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"zfs receive required kernel memory allocation "
"larger than the system can support. Please file "
"an issue at the OpenZFS issue tracker:\n"
"https://github.com/openzfs/zfs/issues/new"));
(void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
break;
case EBUSY:
if (hastoken) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,

View file

@ -222,7 +222,6 @@ check_status(nvlist_t *config, boolean_t isimport,
{
pool_scan_stat_t *ps = NULL;
uint_t vsc, psc;
uint64_t nerr;
uint64_t suspended;
uint64_t hostid = 0;
uint64_t errata = 0;
@ -392,6 +391,7 @@ check_status(nvlist_t *config, boolean_t isimport,
* Persistent data errors.
*/
if (!isimport) {
uint64_t nerr;
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
&nerr) == 0 && nerr != 0)
return (ZPOOL_STATUS_CORRUPT_DATA);

View file

@ -1681,6 +1681,18 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
*ivalp = UINT64_MAX;
}
/*
* Special handling for "checksum_*=none". In this case it's not
* 0 but UINT64_MAX.
*/
if ((type & ZFS_TYPE_VDEV) && isnone &&
(prop == VDEV_PROP_CHECKSUM_N ||
prop == VDEV_PROP_CHECKSUM_T ||
prop == VDEV_PROP_IO_N ||
prop == VDEV_PROP_IO_T)) {
*ivalp = UINT64_MAX;
}
/*
* Special handling for setting 'refreservation' to 'auto'. Use
* UINT64_MAX to tell the caller to use zfs_fix_auto_resv().
@ -2010,15 +2022,20 @@ use_color(void)
void
color_start(const char *color)
{
if (use_color())
if (use_color()) {
fputs(color, stdout);
fflush(stdout);
}
}
void
color_end(void)
{
if (use_color())
if (use_color()) {
fputs(ANSI_RESET, stdout);
fflush(stdout);
}
}
/* printf() with a color. If color is NULL, then do a normal printf. */

View file

@ -770,10 +770,8 @@ random_get_pseudo_bytes(uint8_t *ptr, size_t len)
int
ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
{
(void) nptr;
char *end;
*result = strtoull(str, &end, base);
errno = 0;
*result = strtoull(str, nptr, base);
if (*result == 0)
return (errno);
return (0);

View file

@ -17,6 +17,7 @@ libzutil_la_SOURCES = \
if BUILD_LINUX
libzutil_la_SOURCES += \
%D%/os/linux/zutil_setproctitle.c \
%D%/os/linux/zutil_device_path_os.c \
%D%/os/linux/zutil_import_os.c
endif

View file

@ -0,0 +1,299 @@
/*
* Copyright © 2013 Guillem Jover <guillem@hadrons.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#include <libzutil.h>
static struct {
/* Original value. */
const char *arg0;
/* Title space available. */
char *base, *end;
/* Pointer to original nul character within base. */
char *nul;
boolean_t warned;
boolean_t reset;
int error;
} SPT;
#define LIBBSD_IS_PATHNAME_SEPARATOR(c) ((c) == '/')
#define SPT_MAXTITLE 255
extern const char *__progname;
static const char *
getprogname(void)
{
return (__progname);
}
static void
setprogname(const char *progname)
{
size_t i;
for (i = strlen(progname); i > 0; i--) {
if (LIBBSD_IS_PATHNAME_SEPARATOR(progname[i - 1])) {
__progname = progname + i;
return;
}
}
__progname = progname;
}
static inline size_t
spt_min(size_t a, size_t b)
{
return ((a < b) ? a : b);
}
/*
* For discussion on the portability of the various methods, see
* https://lists.freebsd.org/pipermail/freebsd-stable/2008-June/043136.html
*/
static int
spt_clearenv(void)
{
char **tmp;
tmp = malloc(sizeof (*tmp));
if (tmp == NULL)
return (errno);
tmp[0] = NULL;
environ = tmp;
return (0);
}
static int
spt_copyenv(int envc, char *envp[])
{
char **envcopy;
char *eq;
int envsize;
int i, error;
if (environ != envp)
return (0);
/*
* Make a copy of the old environ array of pointers, in case
* clearenv() or setenv() is implemented to free the internal
* environ array, because we will need to access the old environ
* contents to make the new copy.
*/
envsize = (envc + 1) * sizeof (char *);
envcopy = malloc(envsize);
if (envcopy == NULL)
return (errno);
memcpy(envcopy, envp, envsize);
error = spt_clearenv();
if (error) {
environ = envp;
free(envcopy);
return (error);
}
for (i = 0; envcopy[i]; i++) {
eq = strchr(envcopy[i], '=');
if (eq == NULL)
continue;
*eq = '\0';
if (setenv(envcopy[i], eq + 1, 1) < 0)
error = errno;
*eq = '=';
if (error) {
environ = envp;
free(envcopy);
return (error);
}
}
/*
* Dispose of the shallow copy, now that we've finished transfering
* the old environment.
*/
free(envcopy);
return (0);
}
static int
spt_copyargs(int argc, char *argv[])
{
char *tmp;
int i;
for (i = 1; i < argc || (i >= argc && argv[i]); i++) {
if (argv[i] == NULL)
continue;
tmp = strdup(argv[i]);
if (tmp == NULL)
return (errno);
argv[i] = tmp;
}
return (0);
}
void
zfs_setproctitle_init(int argc, char *argv[], char *envp[])
{
char *base, *end, *nul, *tmp;
int i, envc, error;
/* Try to make sure we got called with main() arguments. */
if (argc < 0)
return;
base = argv[0];
if (base == NULL)
return;
nul = base + strlen(base);
end = nul + 1;
for (i = 0; i < argc || (i >= argc && argv[i]); i++) {
if (argv[i] == NULL || argv[i] != end)
continue;
end = argv[i] + strlen(argv[i]) + 1;
}
for (i = 0; envp[i]; i++) {
if (envp[i] != end)
continue;
end = envp[i] + strlen(envp[i]) + 1;
}
envc = i;
SPT.arg0 = strdup(argv[0]);
if (SPT.arg0 == NULL) {
SPT.error = errno;
return;
}
tmp = strdup(getprogname());
if (tmp == NULL) {
SPT.error = errno;
return;
}
setprogname(tmp);
error = spt_copyenv(envc, envp);
if (error) {
SPT.error = error;
return;
}
error = spt_copyargs(argc, argv);
if (error) {
SPT.error = error;
return;
}
SPT.nul = nul;
SPT.base = base;
SPT.end = end;
}
void
zfs_setproctitle(const char *fmt, ...)
{
/* Use buffer in case argv[0] is passed. */
char buf[SPT_MAXTITLE + 1];
va_list ap;
char *nul;
int len;
if (SPT.base == NULL) {
if (!SPT.warned) {
warnx("setproctitle not initialized, please"
"call zfs_setproctitle_init()");
SPT.warned = B_TRUE;
}
return;
}
if (fmt) {
if (fmt[0] == '-') {
/* Skip program name prefix. */
fmt++;
len = 0;
} else {
/* Print program name heading for grep. */
snprintf(buf, sizeof (buf), "%s: ", getprogname());
len = strlen(buf);
}
va_start(ap, fmt);
len += vsnprintf(buf + len, sizeof (buf) - len, fmt, ap);
va_end(ap);
} else {
len = snprintf(buf, sizeof (buf), "%s", SPT.arg0);
}
if (len <= 0) {
SPT.error = errno;
return;
}
if (!SPT.reset) {
memset(SPT.base, 0, SPT.end - SPT.base);
SPT.reset = B_TRUE;
} else {
memset(SPT.base, 0, spt_min(sizeof (buf), SPT.end - SPT.base));
}
len = spt_min(len, spt_min(sizeof (buf), SPT.end - SPT.base) - 1);
memcpy(SPT.base, buf, len);
nul = SPT.base + len;
if (nul < SPT.nul) {
*SPT.nul = '.';
} else if (nul == SPT.nul && nul + 1 < SPT.end) {
*SPT.nul = ' ';
*++nul = '\0';
}
}

View file

@ -12,7 +12,7 @@
.\" Copyright (c) 2015 by Delphix. All rights reserved.
.\" Copyright (c) 2020 by AJ Jordan. All rights reserved.
.\"
.Dd May 26, 2021
.Dd December 23, 2022
.Dt ARCSTAT 1
.Os
.
@ -35,33 +35,83 @@ prints various ZFS ARC and L2ARC statistics in vmstat-like fashion:
.It Sy c
ARC target size
.It Sy dh%
Demand data hit percentage
Demand hit percentage
.It Sy di%
Demand I/O hit percentage
.It Sy dm%
Demand miss percentage
.It Sy ddh%
Demand data hit percentage
.It Sy ddi%
Demand data I/O hit percentage
.It Sy ddm%
Demand data miss percentage
.It Sy dmh%
Demand metadata hit percentage
.It Sy dmi%
Demand metadata I/O hit percentage
.It Sy dmm%
Demand metadata miss percentage
.It Sy mfu
MFU list hits per second
.It Sy mh%
Metadata hit percentage
.It Sy mi%
Metadata I/O hit percentage
.It Sy mm%
Metadata miss percentage
.It Sy mru
MRU list hits per second
.It Sy ph%
Prefetch hits percentage
.It Sy pi%
Prefetch I/O hits percentage
.It Sy pm%
Prefetch miss percentage
.It Sy pdh%
Prefetch data hits percentage
.It Sy pdi%
Prefetch data I/O hits percentage
.It Sy pdm%
Prefetch data miss percentage
.It Sy pmh%
Prefetch metadata hits percentage
.It Sy pmi%
Prefetch metadata I/O hits percentage
.It Sy pmm%
Prefetch metadata miss percentage
.It Sy dhit
Demand data hits per second
Demand hits per second
.It Sy dioh
Demand I/O hits per second
.It Sy dmis
Demand misses per second
.It Sy ddhit
Demand data hits per second
.It Sy ddioh
Demand data I/O hits per second
.It Sy ddmis
Demand data misses per second
.It Sy dmhit
Demand metadata hits per second
.It Sy dmioh
Demand metadata I/O hits per second
.It Sy dmmis
Demand metadata misses per second
.It Sy hit%
ARC hit percentage
.It Sy hits
ARC reads per second
ARC hits per second
.It Sy ioh%
ARC I/O hits percentage
.It Sy iohs
ARC I/O hits per second
.It Sy mfug
MFU ghost list hits per second
.It Sy mhit
Metadata hits per second
.It Sy mioh
Metadata I/O hits per second
.It Sy miss
ARC misses per second
.It Sy mmis
@ -70,8 +120,22 @@ Metadata misses per second
MRU ghost list hits per second
.It Sy phit
Prefetch hits per second
.It Sy pioh
Prefetch I/O hits per second
.It Sy pmis
Prefetch misses per second
.It Sy pdhit
Prefetch data hits per second
.It Sy pdioh
Prefetch data I/O hits per second
.It Sy pdmis
Prefetch data misses per second
.It Sy pmhit
Prefetch metadata hits per second
.It Sy pmioh
Prefetch metadata I/O hits per second
.It Sy pmmis
Prefetch metadata misses per second
.It Sy read
Total ARC accesses per second
.It Sy time
@ -81,8 +145,14 @@ ARC size
.It Sy arcsz
Alias for
.Sy size
.It Sy unc
Uncached list hits per second
.It Sy dread
Demand accesses per second
.It Sy ddread
Demand data accesses per second
.It Sy dmread
Demand metadata accesses per second
.It Sy eskip
evict_skip per second
.It Sy miss%
@ -91,6 +161,10 @@ ARC miss percentage
Metadata accesses per second
.It Sy pread
Prefetch accesses per second
.It Sy pdread
Prefetch data accesses per second
.It Sy pmread
Prefetch metadata accesses per second
.It Sy l2hit%
L2ARC access hit percentage
.It Sy l2hits

View file

@ -15,7 +15,7 @@
.\" own identifying information:
.\" Portions Copyright [yyyy] [name of copyright owner]
.\"
.Dd November 9, 2022
.Dd January 10, 2023
.Dt ZFS 4
.Os
.
@ -239,6 +239,12 @@ relative to the pool.
Make some blocks above a certain size be gang blocks.
This option is used by the test suite to facilitate testing.
.
.It Sy zfs_default_bs Ns = Ns Sy 9 Po 512 B Pc Pq int
Default dnode block size as a power of 2.
.
.It Sy zfs_default_ibs Ns = Ns Sy 17 Po 128 KiB Pc Pq int
Default dnode indirect block size as a power of 2.
.
.It Sy zfs_history_output_max Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
When attempting to log an output nvlist of an ioctl in the on-disk history,
the output will not be stored if it is larger than this size (in bytes).
@ -496,6 +502,10 @@ prefetch the entire object (all leaf blocks).
However, this is limited by
.Sy dmu_prefetch_max .
.
.It Sy zap_micro_max_size Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq int
Maximum micro ZAP size.
A micro ZAP is upgraded to a fat ZAP, once it grows beyond the specified size.
.
.It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64
If prefetching is enabled, disable prefetching for reads larger than this size.
.
@ -1094,7 +1104,10 @@ This parameter takes precedence over
.No See Sx ZFS TRANSACTION DELAY .
.Pp
Defaults to
.Sy physical_ram/4 ,
.Sy min(physical_ram/4, 4GiB) ,
or
.Sy min(physical_ram/4, 1GiB)
for 32-bit systems.
.
.It Sy zfs_dirty_data_max_max_percent Ns = Ns Sy 25 Ns % Pq uint
Maximum allowable value of
@ -1391,7 +1404,7 @@ _
* 2 ZFS_DEBUG_DBUF_VERIFY Enable extra dbuf verifications.
* 4 ZFS_DEBUG_DNODE_VERIFY Enable extra dnode verifications.
8 ZFS_DEBUG_SNAPNAMES Enable snapshot name verification.
16 ZFS_DEBUG_MODIFY Check for illegally modified ARC buffers.
* 16 ZFS_DEBUG_MODIFY Check for illegally modified ARC buffers.
64 ZFS_DEBUG_ZIO_FREE Enable verification of block frees.
128 ZFS_DEBUG_HISTOGRAM_VERIFY Enable extra spacemap histogram verifications.
256 ZFS_DEBUG_METASLAB_VERIFY Verify space accounting on disk matches in-memory \fBrange_trees\fP.
@ -2196,6 +2209,13 @@ On very fragmented pools, lowering this
.Pq typically to Sy 36 KiB
can improve performance.
.
.It Sy zil_min_commit_timeout Ns = Ns Sy 5000 Pq u64
This sets the minimum delay in nanoseconds ZIL care to delay block commit,
waiting for more records.
If ZIL writes are too fast, kernel may not be able sleep for so short interval,
increasing log latency above allowed by
.Sy zfs_commit_timeout_pct .
.
.It Sy zil_nocacheflush Ns = Ns Sy 0 Ns | Ns 1 Pq int
Disable the cache flush commands that are normally sent to disk by
the ZIL after an LWB write has completed.

View file

@ -43,7 +43,8 @@ section, below.
.Ss Native Properties
Every vdev has a set of properties that export statistics about the vdev
as well as control various behaviors.
Properties are NOT inherited from top-level vdevs.
Properties are not inherited from top-level vdevs, with the exception of
checksum_n, checksum_t, io_n, and io_t.
.Pp
The values of numeric properties can be specified using human-readable suffixes
.Po for example,
@ -114,9 +115,19 @@ The cumulative size of all operations of each type performed by this vdev
If this device is currently being removed from the pool
.El
.Pp
The following native properties can be used to change the behavior of a ZFS
dataset.
The following native properties can be used to change the behavior of a vdev.
.Bl -tag -width "allocating"
.It Sy checksum_n , checksum_t , io_n , io_t
Tune the fault management daemon by specifying checksum/io thresholds of <N>
errors in <T> seconds, respectively.
These properties can be set on leaf and top-level vdevs.
When the property is set on the leaf and top-level vdev, the value of the leaf
vdev will be used.
If the property is only set on the top-level vdev, this value will be used.
The value of these properties do not persist across vdev replacement.
For this reason, it is advisable to set the property on the top-level vdev -
not on the leaf vdev itself.
The default values are 10 errors in 600 seconds.
.It Sy comment
A text comment up to 8192 characters long
.It Sy bootsize

View file

@ -29,7 +29,7 @@
.\" Copyright 2018 Nexenta Systems, Inc.
.\" Copyright 2019 Joyent, Inc.
.\"
.Dd March 16, 2022
.Dd January 12, 2023
.Dt ZFS-SEND 8
.Os
.
@ -39,29 +39,29 @@
.Sh SYNOPSIS
.Nm zfs
.Cm send
.Op Fl DLPbcehnpsvw
.Op Fl DLPVbcehnpsvw
.Op Fl R Op Fl X Ar dataset Ns Oo , Ns Ar dataset Oc Ns
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
.Ar snapshot
.Nm zfs
.Cm send
.Op Fl DLPcensvw
.Op Fl DLPVcensvw
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm zfs
.Cm send
.Fl -redact Ar redaction_bookmark
.Op Fl DLPcenpv
.Op Fl DLPVcenpv
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Ar snapshot
.Nm zfs
.Cm send
.Op Fl Penv
.Op Fl PVenv
.Fl t
.Ar receive_resume_token
.Nm zfs
.Cm send
.Op Fl Pnv
.Op Fl PVnv
.Fl S Ar filesystem
.Nm zfs
.Cm redact
@ -73,7 +73,7 @@
.It Xo
.Nm zfs
.Cm send
.Op Fl DLPbcehnpsvw
.Op Fl DLPVbcehnpsvw
.Op Fl R Op Fl X Ar dataset Ns Oo , Ns Ar dataset Oc Ns
.Op Oo Fl I Ns | Ns Fl i Oc Ar snapshot
.Ar snapshot
@ -142,6 +142,8 @@ If the
flag is used to send encrypted datasets, then
.Fl w
must also be specified.
.It Fl V , -proctitle
Set the process title to a per-second report of how much data has been sent.
.It Fl X , -exclude Ar dataset Ns Oo , Ns Ar dataset Oc Ns
With
.Fl R ,
@ -302,7 +304,7 @@ You will be able to receive your streams on future versions of ZFS.
.It Xo
.Nm zfs
.Cm send
.Op Fl DLPcenvw
.Op Fl DLPVcenvw
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Xc
@ -436,7 +438,7 @@ This information includes a per-second report of how much data has been sent.
.Nm zfs
.Cm send
.Fl -redact Ar redaction_bookmark
.Op Fl DLPcenpv
.Op Fl DLPVcenpv
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Ar snapshot
.Xc
@ -530,7 +532,7 @@ raw sends and redacted sends cannot be combined at this time.
.It Xo
.Nm zfs
.Cm send
.Op Fl Penv
.Op Fl PVenv
.Fl t
.Ar receive_resume_token
.Xc
@ -545,7 +547,7 @@ for more details.
.It Xo
.Nm zfs
.Cm send
.Op Fl Pnv
.Op Fl PVnv
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Fl S
.Ar filesystem

View file

@ -737,6 +737,10 @@ command will be undone if the share is ever unshared (like via a reboot).
.
.Sh ENVIRONMENT VARIABLES
.Bl -tag -width "ZFS_MODULE_TIMEOUT"
.It Sy ZFS_COLOR
Use ANSI color in
.Nm zfs Cm diff
output.
.It Sy ZFS_MOUNT_HELPER
Cause
.Nm zfs Cm mount

View file

@ -151,10 +151,10 @@ zfs-$(CONFIG_PPC) += $(addprefix icp/,$(ICP_OBJS_PPC_PPC64))
zfs-$(CONFIG_PPC64) += $(addprefix icp/,$(ICP_OBJS_PPC_PPC64))
$(addprefix $(obj)/icp/,$(ICP_OBJS) $(ICP_OBJS_X86) $(ICP_OBJS_X86_64) \
$(ICP_OBJS_ARM64) $(ICP_OBJS_PPC_PPC64)) : asflags-y += -I$(icp_include)
$(ICP_OBJS_ARM64) $(ICP_OBJS_PPC_PPC64)) : asflags-y += -I$(icp_include) -I$(zfs_include)/os/linux/spl -I$(zfs_include)
$(addprefix $(obj)/icp/,$(ICP_OBJS) $(ICP_OBJS_X86) $(ICP_OBJS_X86_64) \
$(ICP_OBJS_ARM64) $(ICP_OBJS_PPC_PPC64)) : ccflags-y += -I$(icp_include)
$(ICP_OBJS_ARM64) $(ICP_OBJS_PPC_PPC64)) : ccflags-y += -I$(icp_include) -I$(zfs_include)/os/linux/spl -I$(zfs_include)
# Suppress objtool "return with modified stack frame" warnings.
OBJECT_FILES_NON_STANDARD_aesni-gcm-x86_64.o := y

View file

@ -211,7 +211,7 @@ aes_alloc_keysched(size_t *size, int kmflag)
{
aes_key_t *keysched;
keysched = (aes_key_t *)kmem_alloc(sizeof (aes_key_t), kmflag);
keysched = kmem_alloc(sizeof (aes_key_t), kmflag);
if (keysched != NULL) {
*size = sizeof (aes_key_t);
return (keysched);

View file

@ -26,15 +26,16 @@
#include <sys/simd.h>
#include <sys/types.h>
#include <sys/asm_linkage.h>
/* These functions are used to execute AES-NI instructions: */
extern int rijndael_key_setup_enc_intel(uint32_t rk[],
extern ASMABI int rijndael_key_setup_enc_intel(uint32_t rk[],
const uint32_t cipherKey[], uint64_t keyBits);
extern int rijndael_key_setup_dec_intel(uint32_t rk[],
extern ASMABI int rijndael_key_setup_dec_intel(uint32_t rk[],
const uint32_t cipherKey[], uint64_t keyBits);
extern void aes_encrypt_intel(const uint32_t rk[], int Nr,
extern ASMABI void aes_encrypt_intel(const uint32_t rk[], int Nr,
const uint32_t pt[4], uint32_t ct[4]);
extern void aes_decrypt_intel(const uint32_t rk[], int Nr,
extern ASMABI void aes_decrypt_intel(const uint32_t rk[], int Nr,
const uint32_t ct[4], uint32_t pt[4]);

View file

@ -35,6 +35,7 @@ extern "C" {
#include <sys/types.h>
#include <sys/blake3.h>
#include <sys/simd.h>
#include <sys/asm_linkage.h>
/*
* Methods used to define BLAKE3 assembler implementations

Some files were not shown because too many files have changed in this diff Show more