diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/Makefile | 1 | ||||
-rw-r--r-- | usr/src/lib/libc/extract-copyright.pl | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/nfs/nfs4_client_state.c | 32 | ||||
-rw-r--r-- | usr/src/uts/common/fs/nfs/nfs4_vnops.c | 22 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dmu.c | 57 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/dsl_pool.c | 11 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/sys/dsl_pool.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/nfs/nfs4_clnt.h | 4 |
8 files changed, 91 insertions, 40 deletions
diff --git a/usr/src/Makefile b/usr/src/Makefile index 5fe34ddd48..0320a35159 100644 --- a/usr/src/Makefile +++ b/usr/src/Makefile @@ -25,6 +25,7 @@ # Copyright 2014 Garrett D'Amore <garrett@damore.org> # Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2016 Toomas Soome <tsoome@me.com> +# Copyright 2016 Joyent, Inc. # # diff --git a/usr/src/lib/libc/extract-copyright.pl b/usr/src/lib/libc/extract-copyright.pl index 09a35a52e5..b254abbe45 100644 --- a/usr/src/lib/libc/extract-copyright.pl +++ b/usr/src/lib/libc/extract-copyright.pl @@ -114,7 +114,7 @@ foreach $a (@FILES) { dofile($a); } -foreach my $lic (keys %LICENSE) { +foreach my $lic (sort keys %LICENSE) { my @files = @{$LICENSE{$lic}}; print "\nThe following files from the C library:\n"; foreach my $f (@files) { diff --git a/usr/src/uts/common/fs/nfs/nfs4_client_state.c b/usr/src/uts/common/fs/nfs/nfs4_client_state.c index 969729b3f8..d8e79a9f4a 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_client_state.c +++ b/usr/src/uts/common/fs/nfs/nfs4_client_state.c @@ -552,7 +552,7 @@ nfs4_get_open_stateid(rnode4_t *rp, cred_t *cr, mntinfo4_t *mi, stateid4 *sid) */ stateid4 nfs4_get_w_stateid(cred_t *cr, rnode4_t *rp, pid_t pid, mntinfo4_t *mi, - nfs_opnum4 op, nfs4_stateid_types_t *sid_tp) + nfs_opnum4 op, nfs4_stateid_types_t *sid_tp) { stateid4 sid; @@ -596,7 +596,7 @@ nfs4_get_w_stateid(cred_t *cr, rnode4_t *rp, pid_t pid, mntinfo4_t *mi, */ stateid4 nfs4_get_stateid(cred_t *cr, rnode4_t *rp, pid_t pid, mntinfo4_t *mi, - nfs_opnum4 op, nfs4_stateid_types_t *sid_tp, bool_t async_read) + nfs_opnum4 op, nfs4_stateid_types_t *sid_tp, bool_t async_read) { stateid4 sid; @@ -780,7 +780,7 @@ create_open_stream(nfs4_open_owner_t *oop, rnode4_t *rp) */ nfs4_open_stream_t * find_or_create_open_stream(nfs4_open_owner_t *oop, rnode4_t *rp, - int *created_osp) + int *created_osp) { nfs4_open_stream_t *osp; @@ -1000,11 +1000,11 @@ int bypass_otw[2]; /* * Checks to see if the OPEN OTW is necessary that is, if it's already * been opened with the same access and deny bits we are now asking for. - * Note, this assumes that *vpp is a rnode. + * Note, this assumes that *vp is a rnode. */ int nfs4_is_otw_open_necessary(nfs4_open_owner_t *oop, int flag, vnode_t *vp, - int just_been_created, int *errorp, int acc, nfs4_recov_state_t *rsp) + int just_been_created, int *errorp, int acc, nfs4_recov_state_t *rsp) { rnode4_t *rp; nfs4_open_stream_t *osp; @@ -1181,7 +1181,7 @@ get_dtype(rnode4_t *rp) void nfs4_setup_lock_args(nfs4_lock_owner_t *lop, nfs4_open_owner_t *oop, - nfs4_open_stream_t *osp, clientid4 clientid, locker4 *locker) + nfs4_open_stream_t *osp, clientid4 clientid, locker4 *locker) { ASSERT(lop->lo_flags & NFS4_LOCK_SEQID_INUSE); if (lop->lo_just_created == NFS4_JUST_CREATED) { @@ -1311,8 +1311,8 @@ nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *lop) */ nfsstat4 nfs4_find_or_create_lock_owner(pid_t pid, rnode4_t *rp, cred_t *cr, - nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp, - nfs4_lock_owner_t **lopp) + nfs4_open_owner_t **oopp, nfs4_open_stream_t **ospp, + nfs4_lock_owner_t **lopp) { nfs4_lock_owner_t *lop, *next_lop; mntinfo4_t *mi; @@ -1445,7 +1445,7 @@ failed: */ static nfs4_open_owner_t * find_freed_open_owner(cred_t *cr, nfs4_oo_hash_bucket_t *bucketp, - mntinfo4_t *mi) + mntinfo4_t *mi) { nfs4_open_owner_t *foop; @@ -1538,7 +1538,7 @@ nfs4_get_open_seqid(nfs4_open_owner_t *oop) */ void nfs4_set_open_seqid(seqid4 seqid, nfs4_open_owner_t *oop, - nfs4_tag_type_t tag_type) + nfs4_tag_type_t tag_type) { ASSERT(oop->oo_seqid_inuse); oop->oo_seqid = seqid; @@ -1608,7 +1608,7 @@ nfs4_get_otw_cred(cred_t *cr, mntinfo4_t *mi, nfs4_open_owner_t *provided_oop) */ cred_t * nfs4_get_otw_cred_by_osp(rnode4_t *rp, cred_t *cr, - nfs4_open_stream_t **osp, bool_t *first_time, bool_t *last_time) + nfs4_open_stream_t **osp, bool_t *first_time, bool_t *last_time) { nfs4_open_stream_t *next_osp = NULL; cred_t *ret_cr; @@ -1758,8 +1758,8 @@ nfs4_create_bseqid_entry(nfs4_open_owner_t *oop, nfs4_lock_owner_t *lop, void nfs4open_dg_save_lost_rqst(int error, nfs4_lost_rqst_t *lost_rqstp, - nfs4_open_owner_t *oop, nfs4_open_stream_t *osp, cred_t *cr, - vnode_t *vp, int access_close, int deny_close) + nfs4_open_owner_t *oop, nfs4_open_stream_t *osp, cred_t *cr, + vnode_t *vp, int access_close, int deny_close) { lost_rqstp->lr_putfirst = FALSE; @@ -1796,8 +1796,8 @@ nfs4open_dg_save_lost_rqst(int error, nfs4_lost_rqst_t *lost_rqstp, */ void nfs4_open_downgrade(int access_close, int deny_close, nfs4_open_owner_t *oop, - nfs4_open_stream_t *osp, vnode_t *vp, cred_t *cr, nfs4_lost_rqst_t *lrp, - nfs4_error_t *ep, cred_t **recov_credpp, seqid4 *recov_seqidp) + nfs4_open_stream_t *osp, vnode_t *vp, cred_t *cr, nfs4_lost_rqst_t *lrp, + nfs4_error_t *ep, cred_t **recov_credpp, seqid4 *recov_seqidp) { mntinfo4_t *mi; int downgrade_acc, downgrade_deny; @@ -2012,7 +2012,7 @@ no_args_out: */ void nfs4_resend_open_otw(vnode_t **vpp, nfs4_lost_rqst_t *resend_rqstp, - nfs4_error_t *ep) + nfs4_error_t *ep) { COMPOUND4args_clnt args; COMPOUND4res_clnt res; diff --git a/usr/src/uts/common/fs/nfs/nfs4_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_vnops.c index 941fcbe4b3..04b85265cb 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c +++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c @@ -116,7 +116,7 @@ typedef enum nfs4_acl_op { NFS4_ACL_SET } nfs4_acl_op_t; -static struct lm_sysid *nfs4_find_sysid(mntinfo4_t *mi); +static struct lm_sysid *nfs4_find_sysid(mntinfo4_t *); static void nfs4_update_dircaches(change_info4 *, vnode_t *, vnode_t *, char *, dirattr_info_t *); @@ -10510,7 +10510,6 @@ nfs4_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, return (EINTR); } - if (vp->v_flag & VNOCACHE) { error = EAGAIN; goto done; @@ -10948,8 +10947,9 @@ nfs4_frlock(vnode_t *vp, int cmd, struct flock64 *bfp, int flag, } if (lwp != NULL) lwp->lwp_nostop--; - } else - cv_wait(&rp->r_cv, &rp->r_statelock); + } else { + cv_wait(&rp->r_cv, &rp->r_statelock); + } } mutex_exit(&rp->r_statelock); if (rc != 0) @@ -13012,7 +13012,7 @@ nfs4frlock_pre_setup(clock_t *tick_delayp, nfs4_recov_state_t *recov_statep, /* * Initialize and allocate the data structures necessary for * the nfs4frlock call. - * Allocates argsp's op array, frees up the saved_rqstpp if there is one. + * Allocates argsp's op array. */ static void nfs4frlock_call_init(COMPOUND4args_clnt *argsp, COMPOUND4args_clnt **argspp, @@ -13361,12 +13361,7 @@ nfs4frlock_setup_locku_args(nfs4_lock_call_type_t ctype, nfs_argop4 *argop, locku_args = &argop->nfs_argop4_u.oplocku; *locku_argsp = locku_args; - /* - * XXX what should locku_args->locktype be? - * setting to ALWAYS be READ_LT so at least - * it is a valid locktype. - */ - + /* locktype should be set to any legal value */ locku_args->locktype = READ_LT; pid = ctype == NFS4_LCK_CTYPE_NORM ? curproc->p_pidp->pid_id : @@ -13504,8 +13499,6 @@ out: /* * After we get the reply from the server, record the proper information * for possible resend lock requests. - * - * Allocates memory for the saved_rqstp if we have a lost lock to save. */ static void nfs4frlock_save_lost_rqst(nfs4_lock_call_type_t ctype, int error, @@ -14283,7 +14276,6 @@ recov_retry: switch (cmd) { case F_GETLK: - case F_O_GETLK: nfs4frlock_setup_lockt_args(ctype, &argop[1], &lockt_args, argsp, flk, rp); break; @@ -15898,7 +15890,7 @@ nfs4_reinstitute_local_lock_state(vnode_t *vp, flock64_t *lost_flp, cred_t *cr, * Now we have the list of intersections with the lost lock. These are * the locks that were/are active before the server replied to the * last/lost lock. Issue these locks to the server here. Playing these - * locks to the server will re-establish aur current local locking state + * locks to the server will re-establish our current local locking state * with the v4 server. * If we get an error, send SIGLOST to the application for that lock. */ diff --git a/usr/src/uts/common/fs/zfs/dmu.c b/usr/src/uts/common/fs/zfs/dmu.c index e858c701a4..f62e719377 100644 --- a/usr/src/uts/common/fs/zfs/dmu.c +++ b/usr/src/uts/common/fs/zfs/dmu.c @@ -56,6 +56,14 @@ */ int zfs_nopwrite_enabled = 1; +/* + * Tunable to control percentage of dirtied blocks from frees in one TXG. + * After this threshold is crossed, additional dirty blocks from frees + * wait until the next TXG. + * A value of zero will disable this throttle. + */ +uint32_t zfs_per_txg_dirty_frees_percent = 30; + const dmu_object_type_info_t dmu_ot[DMU_OT_NUMTYPES] = { { DMU_BSWAP_UINT8, TRUE, "unallocated" }, { DMU_BSWAP_ZAP, TRUE, "object directory" }, @@ -717,15 +725,25 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset, { uint64_t object_size = (dn->dn_maxblkid + 1) * dn->dn_datablksz; int err; + uint64_t dirty_frees_threshold; + dsl_pool_t *dp = dmu_objset_pool(os); if (offset >= object_size) return (0); + if (zfs_per_txg_dirty_frees_percent <= 100) + dirty_frees_threshold = + zfs_per_txg_dirty_frees_percent * zfs_dirty_data_max / 100; + else + dirty_frees_threshold = zfs_dirty_data_max / 4; + if (length == DMU_OBJECT_END || offset + length > object_size) length = object_size - offset; while (length != 0) { - uint64_t chunk_end, chunk_begin; + uint64_t chunk_end, chunk_begin, chunk_len; + uint64_t long_free_dirty_all_txgs = 0; + dmu_tx_t *tx; if (dmu_objset_zfs_unmounting(dn->dn_objset)) return (SET_ERROR(EINTR)); @@ -739,9 +757,28 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset, ASSERT3U(chunk_begin, >=, offset); ASSERT3U(chunk_begin, <=, chunk_end); - dmu_tx_t *tx = dmu_tx_create(os); - dmu_tx_hold_free(tx, dn->dn_object, - chunk_begin, chunk_end - chunk_begin); + chunk_len = chunk_end - chunk_begin; + + mutex_enter(&dp->dp_lock); + for (int t = 0; t < TXG_SIZE; t++) { + long_free_dirty_all_txgs += + dp->dp_long_free_dirty_pertxg[t]; + } + mutex_exit(&dp->dp_lock); + + /* + * To avoid filling up a TXG with just frees wait for + * the next TXG to open before freeing more chunks if + * we have reached the threshold of frees + */ + if (dirty_frees_threshold != 0 && + long_free_dirty_all_txgs >= dirty_frees_threshold) { + txg_wait_open(dp, 0); + continue; + } + + tx = dmu_tx_create(os); + dmu_tx_hold_free(tx, dn->dn_object, chunk_begin, chunk_len); /* * Mark this transaction as typically resulting in a net @@ -753,10 +790,18 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset, dmu_tx_abort(tx); return (err); } - dnode_free_range(dn, chunk_begin, chunk_end - chunk_begin, tx); + + mutex_enter(&dp->dp_lock); + dp->dp_long_free_dirty_pertxg[dmu_tx_get_txg(tx) & TXG_MASK] += + chunk_len; + mutex_exit(&dp->dp_lock); + DTRACE_PROBE3(free__long__range, + uint64_t, long_free_dirty_all_txgs, uint64_t, chunk_len, + uint64_t, dmu_tx_get_txg(tx)); + dnode_free_range(dn, chunk_begin, chunk_len, tx); dmu_tx_commit(tx); - length -= chunk_end - chunk_begin; + length -= chunk_len; } return (0); } diff --git a/usr/src/uts/common/fs/zfs/dsl_pool.c b/usr/src/uts/common/fs/zfs/dsl_pool.c index 0d44ba6ac6..307f384277 100644 --- a/usr/src/uts/common/fs/zfs/dsl_pool.c +++ b/usr/src/uts/common/fs/zfs/dsl_pool.c @@ -24,6 +24,7 @@ * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ #include <sys/dsl_pool.h> @@ -494,6 +495,16 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg) dsl_pool_undirty_space(dp, dp->dp_dirty_pertxg[txg & TXG_MASK], txg); /* + * Update the long range free counter after + * we're done syncing user data + */ + mutex_enter(&dp->dp_lock); + ASSERT(spa_sync_pass(dp->dp_spa) == 1 || + dp->dp_long_free_dirty_pertxg[txg & TXG_MASK] == 0); + dp->dp_long_free_dirty_pertxg[txg & TXG_MASK] = 0; + mutex_exit(&dp->dp_lock); + + /* * After the data blocks have been written (ensured by the zio_wait() * above), update the user/group space accounting. */ diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_pool.h b/usr/src/uts/common/fs/zfs/sys/dsl_pool.h index 0e27a53820..3e2914640c 100644 --- a/usr/src/uts/common/fs/zfs/sys/dsl_pool.h +++ b/usr/src/uts/common/fs/zfs/sys/dsl_pool.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SYS_DSL_POOL_H @@ -103,6 +104,7 @@ typedef struct dsl_pool { kcondvar_t dp_spaceavail_cv; uint64_t dp_dirty_pertxg[TXG_SIZE]; uint64_t dp_dirty_total; + uint64_t dp_long_free_dirty_pertxg[TXG_SIZE]; uint64_t dp_mos_used_delta; uint64_t dp_mos_compressed_delta; uint64_t dp_mos_uncompressed_delta; diff --git a/usr/src/uts/common/nfs/nfs4_clnt.h b/usr/src/uts/common/nfs/nfs4_clnt.h index 25064e76ac..8f8cb7d78e 100644 --- a/usr/src/uts/common/nfs/nfs4_clnt.h +++ b/usr/src/uts/common/nfs/nfs4_clnt.h @@ -1597,7 +1597,7 @@ extern clock_t nfs_write_error_interval; * Found through rnodes. * * The os_open_ref_count keeps track the number of open file descriptor - * refernces on this data structure. It will be bumped for any successful + * references on this data structure. It will be bumped for any successful * OTW OPEN call and any OPEN call that determines the OTW call is not * necessary and the open stream hasn't just been created (see * nfs4_is_otw_open_necessary). @@ -1625,7 +1625,7 @@ extern clock_t nfs_write_error_interval; * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the * lost state queue. * - * 'open_stateid' is set the last open stateid returned by the server unless + * 'open_stateid' is set to the last open stateid returned by the server unless * 'os_delegation' is 1, in which case 'open_stateid' refers to the * delegation stateid returned by the server. This is used in cases where the * client tries to OPEN a file but already has a suitable delegation, so we |