components/zsh/Completion/Unix/Command/_zfs
branchs11-update
changeset 3021 b9308977c65b
parent 3020 a14aae53a1c7
child 3023 90190872ae3e
equal deleted inserted replaced
3020:a14aae53a1c7 3021:b9308977c65b
     1 #compdef zfs
       
     2 # Synced with the S11U1 man page
       
     3 
       
     4 _zfs() {
       
     5 	local context state line expl
       
     6 	typeset -A opt_args
       
     7 	local -a subcmds rw_properties rw_propnames ro_properties create_properties
       
     8 	local -a share_nfs_ro_properties share_nfs_rw_properties
       
     9 	local -a share_smb_ro_properties share_nfs_rw_properties
       
    10 	local -a share_ro_properties share_rw_properties
       
    11 	local -a difffields delegatable_perms
       
    12 
       
    13 	subcmds=(
       
    14 		"create" "destroy" "clone" "promote" "rename" "snapshot"
       
    15 		"rollback" "list" "set" "get" "inherit" "mount" "unmount"
       
    16 		"share" "unshare" "send" "receive" "allow" "unallow"
       
    17 		"upgrade" "userspace" "groupspace" "hold" "holds" "release"
       
    18 		"diff" "key" "help"
       
    19 	)
       
    20 
       
    21 	share_nfs_ro_properties=(
       
    22 		"share.nfs.all"
       
    23 	)
       
    24 
       
    25 	share_nfs_rw_properties=(
       
    26 		"share.nfs:value:(on off)"
       
    27 		"share.nfs.aclok:value:(on off)"
       
    28 		"share.nfs.acflfab:value:(on off)"
       
    29 		"share.nfs.anon:uid:"
       
    30 		"share.nfs.charset.euc-cn:access-list:"
       
    31 		"share.nfs.charset.euc-jpms:access-list:"
       
    32 		"share.nfs.charset.euc-kr:access-list:"
       
    33 		"share.nfs.charset.euc-tw:access-list:"
       
    34 		"share.nfs.charset.iso8859-1:access-list:"
       
    35 		"share.nfs.charset.iso8859-2:access-list:"
       
    36 		"share.nfs.charset.iso8859-5:access-list:"
       
    37 		"share.nfs.charset.iso8859-6:access-list:"
       
    38 		"share.nfs.charset.iso8859-7:access-list:"
       
    39 		"share.nfs.charset.iso8859-8:access-list:"
       
    40 		"share.nfs.charset.iso8859-9:access-list:"
       
    41 		"share.nfs.charset.iso8859-13:access-list:"
       
    42 		"share.nfs.charset.iso8859-15:access-list:"
       
    43 		"share.nfs.charset.koi8-r:access-list:"
       
    44 		"share.nfs.index:file:_files"
       
    45 		"share.nfs.log:nfslog.conf tag:"
       
    46 		"share.nfs.nosub:value:(on off)"
       
    47 		"share.nfs.nosuid:value:(on off)"
       
    48 		"share.nfs.public:value:(on off)"
       
    49 		"share.nfs.sec:security-mode-list:"
       
    50 		"share.nfs.sec.default.none:access-list:"
       
    51 		"share.nfs.sec.default.ro:access-list:"
       
    52 		"share.nfs.sec.default.root:access-list:"
       
    53 		"share.nfs.sec.default.root_mapping:uid:"
       
    54 		"share.nfs.sec.default.rw:access-list:"
       
    55 		"share.nfs.sec.default.window:seconds"
       
    56 		"share.nfs.sec.dh.none:access-list:"
       
    57 		"share.nfs.sec.dh.ro:access-list:"
       
    58 		"share.nfs.sec.dh.root:access-list:"
       
    59 		"share.nfs.sec.dh.root_mapping:uid:"
       
    60 		"share.nfs.sec.dh.rw:access-list:"
       
    61 		"share.nfs.sec.dh.window:seconds"
       
    62 		"share.nfs.sec.krb5.none:access-list:"
       
    63 		"share.nfs.sec.krb5.ro:access-list:"
       
    64 		"share.nfs.sec.krb5.root:access-list:"
       
    65 		"share.nfs.sec.krb5.root_mapping:uid:"
       
    66 		"share.nfs.sec.krb5.rw:access-list:"
       
    67 		"share.nfs.sec.krb5.window:seconds"
       
    68 		"share.nfs.sec.krb5i.none:access-list:"
       
    69 		"share.nfs.sec.krb5i.ro:access-list:"
       
    70 		"share.nfs.sec.krb5i.root:access-list:"
       
    71 		"share.nfs.sec.krb5i.root_mapping:uid:"
       
    72 		"share.nfs.sec.krb5i.rw:access-list:"
       
    73 		"share.nfs.sec.krb5i.window:seconds"
       
    74 		"share.nfs.sec.krb5p.none:access-list:"
       
    75 		"share.nfs.sec.krb5p.ro:access-list:"
       
    76 		"share.nfs.sec.krb5p.root:access-list:"
       
    77 		"share.nfs.sec.krb5p.root_mapping:uid:"
       
    78 		"share.nfs.sec.krb5p.rw:access-list:"
       
    79 		"share.nfs.sec.krb5p.window:seconds"
       
    80 		"share.nfs.sec.none.none:access-list:"
       
    81 		"share.nfs.sec.none.ro:access-list:"
       
    82 		"share.nfs.sec.none.root:access-list:"
       
    83 		"share.nfs.sec.none.root_mapping:uid:"
       
    84 		"share.nfs.sec.none.rw:access-list:"
       
    85 		"share.nfs.sec.none.window:seconds"
       
    86 		"share.nfs.sec.sys.none:access-list:"
       
    87 		"share.nfs.sec.sys.ro:access-list:"
       
    88 		"share.nfs.sec.sys.root:access-list:"
       
    89 		"share.nfs.sec.sys.root_mapping:uid:"
       
    90 		"share.nfs.sec.sys.rw:access-list:"
       
    91 		"share.nfs.sec.sys.window:seconds"
       
    92 	)
       
    93 
       
    94 	share_smb_ro_properties=(
       
    95 		"share.smb.all"
       
    96 	)
       
    97 
       
    98 	share_smb_rw_properties=(
       
    99 		"share.smb:value:(on off)"
       
   100 		"share.smb.ad-container"
       
   101 		"share.smb.abe"
       
   102 		"share.smb.csc:value:(disabled manual auto vdo)"
       
   103 		"share.smb.catia:value:(on off)"
       
   104 		"share.smb.dfsroot:value:(on off)"
       
   105 		"share.smb.guestok:value:(on off)"
       
   106 		"share.smb.ro:access-list:"
       
   107 		"share.smb.rw:access-list:"
       
   108 		"share.smb.none:access-list:"
       
   109 	)
       
   110 
       
   111 	share_ro_properties=(
       
   112 		"share.all"
       
   113 		"share.fs"
       
   114 		"share.name"
       
   115 		"share.point"
       
   116 		"share.protocols"
       
   117 		"share.state"
       
   118 		$share_nfs_ro_properties
       
   119 		$share_smb_ro_properties
       
   120 	)
       
   121 
       
   122 	share_rw_properties=(
       
   123 		"share.desc:description:"
       
   124 		"share.noauto:value:(on off)"
       
   125 		"share.path:path:"
       
   126 		$share_nfs_rw_properties
       
   127 		$share_smb_rw_properties
       
   128 	)
       
   129 
       
   130 	# TODO: userused@ and groupused@ could have more extensive handling
       
   131 	ro_properties=(
       
   132 		"name" "type" "creation" "used" "available" "referenced"
       
   133 		"compressratio" "mounted" "origin" "usedbychildren"
       
   134 		"usedbydataset" "usedbyrefreservation" "usedbysnapshots"
       
   135 		"defer_destroy" "userused@" "userrefs" "groupused@"
       
   136 		"keychangedate" "keystatus" "rekeydate"
       
   137 		$share_ro_properties
       
   138 	)
       
   139 
       
   140 	# TODO: Be cleverer about what values can be set.  Is there any way to
       
   141 	# set the sorting for *size properties to false by default?
       
   142 	rw_properties=(
       
   143 		"aclinherit:value:(discard noallow restricted passthrough passthrough-x)"
       
   144 		"aclmode:value:(discard mask passthrough)"
       
   145 		"atime:value:(on off)"
       
   146 		"canmount:value:(on off noauto)"
       
   147 		"checksum:value:(on off fletcher2 fletcher4 sha256 sha256+mac)"
       
   148 		"compression:value:(on off lzjb gzip gzip-{1..9} zle)"
       
   149 		"copies:value:(1 2 3)"
       
   150 		"dedup:value:(on off verify sha256 sha256,verify)"
       
   151 		"devices:value:(on off)"
       
   152 		"encryption:value:(off on aes128-ccm aes-192-ccm aes-256-ccm aes-128-gcm aes-192-gcm aes-256-gcm)"
       
   153 		"exec:value:(on off)"
       
   154 		"groupquota@:value:" # TODO: complete group=size|none
       
   155 		"keysource:value:_zfs_keysource_props"
       
   156 		"logbias:value:(latency throughput)"
       
   157 		"mlslabel:value:(none)" # TODO: list sensitivity labels
       
   158 		"mountpoint:path, 'legacy', or 'none':{if [[ -prefix /* ]]; then _path_files -/; else _wanted mountpoints expl 'mountpoint (type \"/\" to start completing paths)' compadd legacy none; fi}"
       
   159 		"multilevel:value:(on off)"
       
   160 		"nbmand:value:(on off)"
       
   161 		"primarycache:value:(all none metadata)"
       
   162 		"quota:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == quota= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'quota' compadd none; fi}"
       
   163 		"readonly:value:(on off)"
       
   164 		"recordsize:value:(512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M)"
       
   165 		"refquota:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == refquota= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'refquota' compadd none; fi}"
       
   166 		"refreservation:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == refreservation= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'refreservation' compadd none; fi}"
       
   167 		"reservation:value:{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == reservation= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'reservation' compadd none; fi}"
       
   168 		"rstchown:value:(on off)"
       
   169 		"secondarycache:value:(all none metadata)"
       
   170 		"setuid:value:(on off)"
       
   171 		"shadow:value:" # TODO: complete URI|none
       
   172 		"share:share properties:"
       
   173 		"snapdir:value:(hidden visible)"
       
   174 		"sync:value:(standard always disabled)"
       
   175 		"userquota@:value:" # TODO: complete user=size|none
       
   176 		"version:value:(1 2 3 4 current)"
       
   177 		"volsize:value:" # <size>
       
   178 		"vscan:value:(on off)"
       
   179 		"xattr:value:(on off)"
       
   180 		"zoned:value:(on off)"
       
   181 		$share_rw_properties
       
   182 	)
       
   183 
       
   184 	create_properties=(
       
   185 		$rw_properties
       
   186 		"casesensitivity:value:(sensitive insensitive mixed)"
       
   187 		"normalization:value:(none formC formD formKC formKD)"
       
   188 		"utf8only:value:(on off)"
       
   189 		"volblocksize:value:(512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M)"
       
   190 	)
       
   191 
       
   192 	delegatable_perms=(
       
   193 		"allow" "clone" "create" "destroy" "diff" "hold" "key"
       
   194 		"keychange" "mount" "promote" "receive" "release" "rename"
       
   195 		"rollback" "send" "share" "snapshot"
       
   196 		"groupused" "userused" "userprop"
       
   197 		${create_properties%%:*}
       
   198 	)
       
   199 
       
   200 	rw_propnames=( ${rw_properties%%:*} )
       
   201 
       
   202 	difffields=(
       
   203 		object parent size links linkschange name oldname user group
       
   204 		ctime mtime atime crtime
       
   205 	)
       
   206 
       
   207 	if [[ $service == "zfs" ]]; then
       
   208 		_arguments -C -A "-*" \
       
   209 			'-\?[Help]' \
       
   210 			'*::command:->subcmd' && return 0
       
   211 
       
   212 		if (( CURRENT == 1 )); then
       
   213 			_wanted commands expl "zfs subcommand" compadd -a subcmds
       
   214 			return
       
   215 		fi
       
   216 		service="$words[1]"
       
   217 		curcontext="${curcontext%:*}=$service:"
       
   218 	fi
       
   219 
       
   220 	case $service in
       
   221 	("create")
       
   222 		_arguments -A "-*" \
       
   223 			'-p[Create parent datasets]' \
       
   224 			'-o[Set initial properties]:property:_values -s , "property" $create_properties' \
       
   225 			- set1 \
       
   226 			':filesystem:_zfs_dataset -t fs -e "parent dataset"' \
       
   227 			- set2 \
       
   228 			'-s[Create sparse volume]' \
       
   229 			'-b[Set volblocksize]:blocksize:' \
       
   230 			'-V[Set size]:size:' \
       
   231 			':volume:_zfs_dataset -t fs -e "parent dataset"'
       
   232 		;;
       
   233 
       
   234 	("destroy")
       
   235 		_arguments -A "-*" \
       
   236 			'-r[Recursively destroy all children]' \
       
   237 			'-R[Recursively destroy all dependents]' \
       
   238 			- set1 \
       
   239 			'-d[delete or mark deferred]' \
       
   240 			':snapshot:_zfs_dataset -t snap' \
       
   241 			- set2 \
       
   242 			'-f[Force unmounts]' \
       
   243 			':filesystem/volume/snapshot:_zfs_dataset -t fs -t vol'
       
   244 		;;
       
   245 
       
   246 	("snapshot")
       
   247 		_arguments -A "-*" \
       
   248 			'-r[Recursively snapshot all descendant datasets]' \
       
   249 			'-o[Set property]:property:_values -s , "property" $create_properties' \
       
   250 			':filesystem/volume:_zfs_dataset -t fs -t vol -S@'
       
   251 		;;
       
   252 
       
   253 	("rollback")
       
   254 		_arguments -A "-*" \
       
   255 			'-r[Recursively destroy more recent snapshots]' \
       
   256 			'-R[Recursively destroy more recent snapshots and clones]' \
       
   257 			'-f[Force unmounts]' \
       
   258 			':snapshot:_zfs_dataset -t snap'
       
   259 		;;
       
   260 
       
   261 	("clone")
       
   262 		# XXX needs to bail if there are no snapshots
       
   263 		_arguments -A "-*" \
       
   264 			'-p[Create parent datasets]' \
       
   265 			'-K[Create encryption key]' \
       
   266 			'-o[Set property]:property:_values -s , "property" $create_properties' \
       
   267 			':snapshot:_zfs_dataset -t snap' \
       
   268 			':filesystem/volume:_zfs_dataset -t fs -e "parent dataset"'
       
   269 		;;
       
   270 
       
   271 	("promote")
       
   272 		_arguments \
       
   273 			':filesystem:_zfs_dataset -t clone' \
       
   274 		;;
       
   275 
       
   276 	("rename")
       
   277 		_arguments -A "-*" \
       
   278 			'(-r)-p[Create parent datasets]' \
       
   279 			'(-p)-r[Recursively rename snapshots of all descendent datasets]' \
       
   280 			':dataset:_zfs_dataset -r1' \
       
   281 			':dataset:_zfs_dataset -r2'
       
   282 		;;
       
   283 
       
   284 	("list")
       
   285 		_arguments -A "-*" \
       
   286 			'-r[Recursively display children]' \
       
   287 			'-H[Scripting mode]' \
       
   288 			'-d[Depth]:value:' \
       
   289 			'-o[Properties to list]:property:_values -s , "property" $ro_properties $rw_propnames' \
       
   290 			'*-s[Sort key (ascending)]:property:_values "property" $ro_properties $rw_propnames' \
       
   291 			'*-S[Sort key (descending)]:property:_values "property" $ro_properties $rw_propnames' \
       
   292 			'-t[Dataset types to list]:dataset type:_values -s , "dataset type" all filesystem snapshot volume' \
       
   293 			'*:filesystem/volume/snapshot/path:_zfs_dataset -p'
       
   294 		;;
       
   295 
       
   296 	("set")
       
   297 		_arguments \
       
   298 			'-r[Recursively apply value]' \
       
   299 			':property:_values -s , "property" $rw_properties' \
       
   300 			'*:filesystem/volume:_zfs_dataset -t fs -t vol'
       
   301 		;;
       
   302 
       
   303 	("get")
       
   304 		_arguments -A "-*" \
       
   305 			"-r[Recursively display children's properties]" \
       
   306 			'-d[Depth]:value:' \
       
   307 			'-H[Scripting mode]' \
       
   308 			'-p[Display numbers exactly]' \
       
   309 			'-s[Specify sources]:source:_values -s , "source" local default inherited temporary none' \
       
   310 			'-o[Specify fields]:field:_values -s , "field" name property value source' \
       
   311 			':property:_values -s , "property" $ro_properties $rw_propnames all' \
       
   312 			'*:filesystem/volume/snapshot:_zfs_dataset'
       
   313 		;;
       
   314 
       
   315 	("inherit")
       
   316 		_arguments -A "-*" \
       
   317 			'-r[Recursively inherit property for all children]' \
       
   318 			'-S[Revert to received property value]' \
       
   319 			':property:_values -s , "property" $ro_properties $rw_properties' \
       
   320 			'*:filesystem/volume:_zfs_dataset -t fs -t vol'
       
   321 		;;
       
   322 
       
   323 	("userspace"|"groupspace")
       
   324 		_arguments -A "-*" \
       
   325 			'-n[Print numeric ID]' \
       
   326 			'-i[Translate SID to POSIX ID]' \
       
   327 			'-H[Tab-delimited output with no headers]' \
       
   328 			'-p[Parseable mode]' \
       
   329 			'-o[Properties to list]:property:_values -s , "property" type name used quota' \
       
   330 			'*-s[Sort key (ascending)]:property:_values "property" type name used quota' \
       
   331 			'*-S[Sort key (descending)]:property:_values "property" type name used quota' \
       
   332 			'-t[Types to list]:type:_values -s , "type" all posixuser smbuser posixgroup smbgroup' \
       
   333 			'*:filesystem/volume/snapshot:_zfs_dataset'
       
   334 		;;
       
   335 
       
   336 	("mount")
       
   337 		_arguments -A "-*" \
       
   338 			'-o[Mount options]:mount options:_values -s , "option" {,no}{devices,exec,setuid} ro rw' \
       
   339 			'-O[Overlay mount]' \
       
   340 			'-v[Report mount progress]' \
       
   341 			- set1 \
       
   342 			':filesystem:_zfs_dataset -t fs' \
       
   343 			- set2 \
       
   344 			'-a[Mount all available ZFS filesystems]'
       
   345 		;;
       
   346 
       
   347 	("unmount")
       
   348 		_arguments -A "-*" \
       
   349 			- set1 \
       
   350 			'-f[Force unmount]' \
       
   351 			':filesystem:_zfs_dataset -t fs -t mtpt' \
       
   352 			- set2 \
       
   353 			'-a[Unmount all ZFS filesystems]'
       
   354 		;;
       
   355 
       
   356 	("share")
       
   357 		_arguments -A "-*" \
       
   358 			- set1 \
       
   359 			'-a[Share all available ZFS filesystems]' \
       
   360 			- set2 \
       
   361 			'-r[Share filesystems recursively]' \
       
   362 			':filesystem:_zfs_dataset -t fs' \
       
   363 			- set3 \
       
   364 			'*-o[Create a share with these properties]:property:_values -w "share properties" $share_rw_properties' \
       
   365 			'-u[Create a share without sharing it]' \
       
   366 			':filesystem:_zfs_dataset -t fs' \
       
   367 			- set4 \
       
   368 			':filesystem:_zfs_dataset -t fs -t mtpt -t share'
       
   369 		;;
       
   370 
       
   371 	("unshare")
       
   372 		_arguments -A "-*" \
       
   373 			- set1 \
       
   374 			'-a[Unshare all shared ZFS filesystems]' \
       
   375 			- set2 \
       
   376 			'-r[Unshare filesystems recursively]' \
       
   377 			':filesystem:_zfs_dataset -t fs' \
       
   378 			- set3 \
       
   379 			':filesystem:_zfs_dataset -t fs -t mtpt -t share'
       
   380 		;;
       
   381 
       
   382 	("send")
       
   383 		_arguments -A "-*" \
       
   384 			'-b' \
       
   385 			'-i[Generate an incremental stream]:snapshot:_zfs_dataset -t snap' \
       
   386 			'-D[Perform dedup processing]' \
       
   387 			'-p[Send properties]' \
       
   388 			'-v[Verbose]' \
       
   389 			- set1 \
       
   390 			'-I[Generate an incremental stream with intermediary snapshots]:snapshot:_zfs_dataset -t snap' \
       
   391 			'-R[Generate a replication stream package]' \
       
   392 			':snapshot:_zfs_dataset -t snap' \
       
   393 			- set2 \
       
   394 			'-c[Create a self-contained stream]' \
       
   395 			'-r[Generate a recursive stream package]' \
       
   396 			':snapshot:_zfs_dataset -t snap'
       
   397 		;;
       
   398 
       
   399 	("receive")
       
   400 		_arguments -A "-*" \
       
   401 			'-v[Verbose]' \
       
   402 			'-n[Do not receive the stream]' \
       
   403 			'-F[Force a rollback if necessary]' \
       
   404 			'-u[Filesystem is not mounted]' \
       
   405 			'-o[Include property change in the stream]::' \
       
   406 			'-x[Exclude property change from the stream]:property:' \
       
   407 			- set1 \
       
   408 			':filesystem/volume/snapshot:_zfs_dataset' \
       
   409 			- set2 \
       
   410 			'(-e)-d[Set path prefix from stream, excluding only pool name]' \
       
   411 			'(-d)-e[Set path prefix from stream, using last path element]' \
       
   412 			'-:filesystem:_zfs_dataset -t fs'
       
   413 		;;
       
   414 
       
   415 	("allow")
       
   416 		_arguments -A "-*" \
       
   417 			- set1 \
       
   418 			':filesystem/volume:_zfs_dataset -t fs -t vol' \
       
   419 			- set2 \
       
   420 			'(-g)-u[User]:user:_users' \
       
   421 			'(-u)-g[Group]:group:_groups' \
       
   422 			'-l[Allow for named dataset]' \
       
   423 			'-d[Allow for descendent datasets]' \
       
   424 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   425 			':filesystem/volume:_zfs_dataset -t fs -t vol' \
       
   426 			- set3 \
       
   427 			'-e[Everyone]' \
       
   428 			'-l[Allow for named dataset]' \
       
   429 			'-d[Allow for descendent datasets]' \
       
   430 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   431 			':filesystem/volume:_zfs_dataset -t fs -t vol' \
       
   432 			- set4 \
       
   433 			'-c[Create-time permissions]' \
       
   434 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   435 			':filesystem/volume:_zfs_dataset -t fs -t vol' \
       
   436 			- set5 \
       
   437 			'-s[Define or modify permission sets]' \
       
   438 			':setname:' \
       
   439 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   440 			':filesystem/volume:_zfs_dataset -t fs -t vol'
       
   441 		;;
       
   442 
       
   443 	("unallow")
       
   444 		_arguments -A "-*" \
       
   445 			'-r[Recursive removal]' \
       
   446 			- set1 \
       
   447 			'-s[Remove permissions from or delete a permission set]:permission set:' \
       
   448 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   449 			':filesystem/volume:_zfs_dataset -t fs -t vol' \
       
   450 			- set2 \
       
   451 			'(-g)-u[User]:user:_users' \
       
   452 			'(-u)-g[Group]:group:_groups' \
       
   453 			'-l[Allow for named dataset]' \
       
   454 			'-d[Allow for descendent datasets]' \
       
   455 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   456 			':filesystem/volume:_zfs_dataset -t fs -t vol' \
       
   457 			- set3 \
       
   458 			'-e[Everyone]' \
       
   459 			'-l[Allow for named dataset]' \
       
   460 			'-d[Allow for descendent datasets]' \
       
   461 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   462 			':filesystem/volume:_zfs_dataset -t fs -t vol' \
       
   463 			- set4 \
       
   464 			'-c[Create-time permissions]' \
       
   465 			':permissions or sets:_values -s , "permission or set" $delegatable_perms' \
       
   466 			':filesystem/volume:_zfs_dataset -t fs -t vol'
       
   467 		;;
       
   468 
       
   469 	("upgrade")
       
   470 		_arguments -A "-*" \
       
   471 			- set1 \
       
   472 			'-v[Verbose]' \
       
   473 			- set2 \
       
   474 			'-a[Upgrade all filesystems on all pools]' \
       
   475 			'-r[Upgrade descendent filesystems, too]' \
       
   476 			'-V[Upgrade to specified version]:version:(1 2)' \
       
   477 			- set3 \
       
   478 			'-r[Upgrade descendent filesystems, too]' \
       
   479 			'-V[Upgrade to specified version]:version:(1 2)' \
       
   480 			':filesystem:_zfs_dataset -t fs'
       
   481 		;;
       
   482 
       
   483 	("hold")
       
   484 		_arguments -A "-*" \
       
   485 			'-r[Apply hold recursively]' \
       
   486 			':tag:' \
       
   487 			':snapshot:_zfs_dataset -t snap'
       
   488 		;;
       
   489 
       
   490 	("holds")
       
   491 		_arguments -A "-*" \
       
   492 			'-r[List holds recursively]' \
       
   493 			':snapshot:_zfs_dataset -t snap'
       
   494 		;;
       
   495 
       
   496 	("release")
       
   497 		_arguments -A "-*" \
       
   498 			'-r[Release holds recursively]' \
       
   499 			':tag:' \
       
   500 			':snapshot:_zfs_dataset -t snap'
       
   501 		;;
       
   502 
       
   503 	("diff")
       
   504 		_arguments -A "-*" \
       
   505 			'-F[Add column for filetype character]' \
       
   506 			'-H[Parseable output]' \
       
   507 			'-e[Only show new and changed files]' \
       
   508 			'*-o[Show fields]:field:_values "field" $difffields' \
       
   509 			'-t[Add column for ctime]' \
       
   510 			- set1 \
       
   511 			':snapshot:_zfs_dataset -t snap' \
       
   512 			':snapshot or filesystem:_zfs_dataset -t snap -t fs' \
       
   513 			- set2 \
       
   514 			'-E[Show difference from empty]' \
       
   515 			':snapshot or filesystem:_zfs_dataset -t snap -t fs'
       
   516 		;;
       
   517 
       
   518 	("key")
       
   519 		_arguments -A "-*" \
       
   520 			- set1 \
       
   521 			'-a[Apply to all datasets in all pools]' \
       
   522 			'(-u -K -f)-l[Load the encryption key]' \
       
   523 			'(-l -K)-u[Unload the encryption key]' \
       
   524 			'(-l -u -f)-K[Create a new data encryption key]' \
       
   525 			'(-l -K)-f[Unmount the dataset before unloading the encryption key]' \
       
   526 			'-r[Apply recursively]' \
       
   527 			':filesystem or volume:_zfs_dataset -t fs -t vol' \
       
   528 			- set2 \
       
   529 			'-c[Change the encryption key]' \
       
   530 			'-o[Change a property]:property:_zfs_keysource_props' \
       
   531 			':filesystem or volume:_zfs_dataset -t fs -t vol'
       
   532 		;;
       
   533 
       
   534 	("help")
       
   535 		_arguments -A "-*" \
       
   536 			- set1 \
       
   537 			':command:($subcmds $delegatable_perms $ro_properties ${rw_properties%%:*} properties)' \
       
   538 			- set2 \
       
   539 			'-l[Display property information]' \
       
   540 			': :(properties)'
       
   541 		;;
       
   542 
       
   543 	(*)
       
   544 		_message "unknown zfs subcommand: $service"
       
   545 		;;
       
   546 	esac
       
   547 }
       
   548 
       
   549 _zfs "$@"