Author: delphij
Date: Wed Jul  9 18:32:40 2014
New Revision: 268464
URL: http://svnweb.freebsd.org/changeset/base/268464

Log:
  MFV r268452:
  
  Explicitly mark file removal transactions as "presumed to result
  in a net free of space" so they will not fail with ENOSPC.
  
  Illumos issue:        4950 files sometimes can't be removed from a full
                filesystem
  MFC after:    2 weeks

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
Directory Properties:
  head/sys/cddl/contrib/opensolaris/   (props changed)

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c   Wed Jul  9 
17:31:57 2014        (r268463)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c   Wed Jul  9 
18:32:40 2014        (r268464)
@@ -672,6 +672,12 @@ dmu_free_long_range_impl(objset_t *os, d
                dmu_tx_t *tx = dmu_tx_create(os);
                dmu_tx_hold_free(tx, dn->dn_object,
                    chunk_begin, chunk_end - chunk_begin);
+
+               /*
+                * Mark this transaction as typically resulting in a net
+                * reduction in space used.
+                */
+               dmu_tx_mark_netfree(tx);
                err = dmu_tx_assign(tx, TXG_WAIT);
                if (err) {
                        dmu_tx_abort(tx);
@@ -723,6 +729,7 @@ dmu_free_long_object(objset_t *os, uint6
        tx = dmu_tx_create(os);
        dmu_tx_hold_bonus(tx, object);
        dmu_tx_hold_free(tx, object, 0, DMU_OBJECT_END);
+       dmu_tx_mark_netfree(tx);
        err = dmu_tx_assign(tx, TXG_WAIT);
        if (err == 0) {
                err = dmu_object_free(os, object, tx);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c        Wed Jul 
 9 17:31:57 2014        (r268463)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c        Wed Jul 
 9 18:32:40 2014        (r268464)
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  */
 
 #include <sys/dmu.h>
@@ -583,6 +583,32 @@ dmu_tx_count_free(dmu_tx_hold_t *txh, ui
        txh->txh_space_tounref += unref;
 }
 
+/*
+ * This function marks the transaction as being a "net free".  The end
+ * result is that refquotas will be disabled for this transaction, and
+ * this transaction will be able to use half of the pool space overhead
+ * (see dsl_pool_adjustedsize()).  Therefore this function should only
+ * be called for transactions that we expect will not cause a net increase
+ * in the amount of space used (but it's OK if that is occasionally not true).
+ */
+void
+dmu_tx_mark_netfree(dmu_tx_t *tx)
+{
+       dmu_tx_hold_t *txh;
+
+       txh = dmu_tx_hold_object_impl(tx, tx->tx_objset,
+           DMU_NEW_OBJECT, THT_FREE, 0, 0);
+
+       /*
+        * Pretend that this operation will free 1GB of space.  This
+        * should be large enough to cancel out the largest write.
+        * We don't want to use something like UINT64_MAX, because that would
+        * cause overflows when doing math with these values (e.g. in
+        * dmu_tx_try_assign()).
+        */
+       txh->txh_space_tofree = txh->txh_space_tounref = 1024 * 1024 * 1024;
+}
+
 void
 dmu_tx_hold_free(dmu_tx_t *tx, uint64_t object, uint64_t off, uint64_t len)
 {

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h       Wed Jul 
 9 17:31:57 2014        (r268463)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h       Wed Jul 
 9 18:32:40 2014        (r268464)
@@ -569,6 +569,7 @@ void dmu_tx_abort(dmu_tx_t *tx);
 int dmu_tx_assign(dmu_tx_t *tx, enum txg_how txg_how);
 void dmu_tx_wait(dmu_tx_t *tx);
 void dmu_tx_commit(dmu_tx_t *tx);
+void dmu_tx_mark_netfree(dmu_tx_t *tx);
 
 /*
  * To register a commit callback, dmu_tx_callback_register() must be called.

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c       Wed Jul 
 9 17:31:57 2014        (r268463)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c       Wed Jul 
 9 18:32:40 2014        (r268464)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -559,6 +559,7 @@ zfs_purgedir(znode_t *dzp)
                dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
                /* Is this really needed ? */
                zfs_sa_upgrade_txholds(tx, xzp);
+               dmu_tx_mark_netfree(tx);
                error = dmu_tx_assign(tx, TXG_WAIT);
                if (error) {
                        dmu_tx_abort(tx);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c     Wed Jul 
 9 17:31:57 2014        (r268463)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c     Wed Jul 
 9 18:32:40 2014        (r268464)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2014 by Delphix. All rights reserved.
  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  */
 
@@ -1568,7 +1568,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode
  *             cr      - credentials of caller.
  *             flag    - large file flag [UNUSED].
  *             ct      - caller context
- *             vsecp   - ACL to be set
+ *             vsecp   - ACL to be set
  *
  *     OUT:    vpp     - vnode of created or trunc'd entry.
  *
@@ -1850,7 +1850,7 @@ zfs_remove(vnode_t *dvp, char *name, cre
        zfsvfs_t        *zfsvfs = dzp->z_zfsvfs;
        zilog_t         *zilog;
        uint64_t        acl_obj, xattr_obj;
-       uint64_t        xattr_obj_unlinked = 0;
+       uint64_t        xattr_obj_unlinked = 0;
        uint64_t        obj = 0;
        zfs_dirlock_t   *dl;
        dmu_tx_t        *tx;
@@ -1950,6 +1950,14 @@ top:
        /* charge as an update -- would be nice not to charge at all */
        dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
 
+       /*
+        * Mark this transaction as typically resulting in a net free of
+        * space, unless object removal will be delayed indefinitely
+        * (due to active holds on the vnode due to the file being open).
+        */
+       if (may_delete_now)
+               dmu_tx_mark_netfree(tx);
+
        error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
        if (error) {
                zfs_dirent_unlock(dl);
@@ -1980,7 +1988,6 @@ top:
        }
 
        if (unlinked) {
-
                /*
                 * Hold z_lock so that we can make sure that the ACL obj
                 * hasn't changed.  Could have been deleted due to
@@ -5056,13 +5063,13 @@ zfs_addmap(vnode_t *vp, offset_t off, st
  * last page is pushed.  The problem occurs when the msync() call is omitted,
  * which by far the most common case:
  *
- *     open()
- *     mmap()
- *     <modify memory>
- *     munmap()
- *     close()
- *     <time lapse>
- *     putpage() via fsflush
+ *     open()
+ *     mmap()
+ *     <modify memory>
+ *     munmap()
+ *     close()
+ *     <time lapse>
+ *     putpage() via fsflush
  *
  * If we wait until fsflush to come along, we can have a modification time that
  * is some arbitrary point in the future.  In order to prevent this in the
@@ -5555,7 +5562,7 @@ const fs_operation_def_t zfs_dvnodeops_t
        VOPNAME_PATHCONF,       { .vop_pathconf = zfs_pathconf },
        VOPNAME_GETSECATTR,     { .vop_getsecattr = zfs_getsecattr },
        VOPNAME_SETSECATTR,     { .vop_setsecattr = zfs_setsecattr },
-       VOPNAME_VNEVENT,        { .vop_vnevent = fs_vnevent_support },
+       VOPNAME_VNEVENT,        { .vop_vnevent = fs_vnevent_support },
        NULL,                   NULL
 };
 
@@ -5589,8 +5596,8 @@ const fs_operation_def_t zfs_fvnodeops_t
        VOPNAME_GETSECATTR,     { .vop_getsecattr = zfs_getsecattr },
        VOPNAME_SETSECATTR,     { .vop_setsecattr = zfs_setsecattr },
        VOPNAME_VNEVENT,        { .vop_vnevent = fs_vnevent_support },
-       VOPNAME_REQZCBUF,       { .vop_reqzcbuf = zfs_reqzcbuf },
-       VOPNAME_RETZCBUF,       { .vop_retzcbuf = zfs_retzcbuf },
+       VOPNAME_REQZCBUF,       { .vop_reqzcbuf = zfs_reqzcbuf },
+       VOPNAME_RETZCBUF,       { .vop_retzcbuf = zfs_retzcbuf },
        NULL,                   NULL
 };
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c     Wed Jul 
 9 17:31:57 2014        (r268463)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c     Wed Jul 
 9 18:32:40 2014        (r268464)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  */
 
 /* Portions Copyright 2007 Jeremy Teo */
@@ -1510,7 +1510,7 @@ zfs_no_putpage(vnode_t *vp, page_t *pp, 
  *     IN:     zp      - znode of file to free data in.
  *             end     - new end-of-file
  *
- *     RETURN: 0 on success, error code on failure
+ *     RETURN: 0 on success, error code on failure
  */
 static int
 zfs_extend(znode_t *zp, uint64_t end)
@@ -1583,7 +1583,7 @@ zfs_extend(znode_t *zp, uint64_t end)
  *             off     - start of section to free.
  *             len     - length of section to free.
  *
- *     RETURN: 0 on success, error code on failure
+ *     RETURN: 0 on success, error code on failure
  */
 static int
 zfs_free_range(znode_t *zp, uint64_t off, uint64_t len)
@@ -1630,7 +1630,7 @@ zfs_free_range(znode_t *zp, uint64_t off
  *     IN:     zp      - znode of file to free data in.
  *             end     - new end-of-file.
  *
- *     RETURN: 0 on success, error code on failure
+ *     RETURN: 0 on success, error code on failure
  */
 static int
 zfs_trunc(znode_t *zp, uint64_t end)
@@ -1664,6 +1664,7 @@ zfs_trunc(znode_t *zp, uint64_t end)
        tx = dmu_tx_create(zfsvfs->z_os);
        dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
        zfs_sa_upgrade_txholds(tx, zp);
+       dmu_tx_mark_netfree(tx);
        error = dmu_tx_assign(tx, TXG_WAIT);
        if (error) {
                dmu_tx_abort(tx);
@@ -1706,7 +1707,7 @@ zfs_trunc(znode_t *zp, uint64_t end)
  *             flag    - current file open mode flags.
  *             log     - TRUE if this action should be logged
  *
- *     RETURN: 0 on success, error code on failure
+ *     RETURN: 0 on success, error code on failure
  */
 int
 zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log)

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c  Wed Jul  9 
17:31:57 2014        (r268463)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c  Wed Jul  9 
18:32:40 2014        (r268464)
@@ -851,6 +851,7 @@ zvol_update_volsize(objset_t *os, uint64
 
        tx = dmu_tx_create(os);
        dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
+       dmu_tx_mark_netfree(tx);
        error = dmu_tx_assign(tx, TXG_WAIT);
        if (error) {
                dmu_tx_abort(tx);
@@ -1987,6 +1988,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t 
                rl = zfs_range_lock(&zv->zv_znode, df.df_start, df.df_length,
                    RL_WRITER);
                tx = dmu_tx_create(zv->zv_objset);
+               dmu_tx_mark_netfree(tx);
                error = dmu_tx_assign(tx, TXG_WAIT);
                if (error != 0) {
                        dmu_tx_abort(tx);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to