]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/zfs_vnops.c
OpenZFS 8997 - ztest assertion failure in zil_lwb_write_issue
[mirror_zfs.git] / module / zfs / zfs_vnops.c
index 8a7ad702ca219f4d76ef0f7488d82bdf6ae2bef1..4805f89772961a8667a2a8ae57ad509467a1e9a2 100644 (file)
  *
  *     If dmu_tx_assign() returns ERESTART and zfsvfs->z_assign is TXG_NOWAIT,
  *     then drop all locks, call dmu_tx_wait(), and try again.  On subsequent
- *     calls to dmu_tx_assign(), pass TXG_WAITED rather than TXG_NOWAIT,
+ *     calls to dmu_tx_assign(), pass TXG_NOTHROTTLE in addition to TXG_NOWAIT,
  *     to indicate that this operation has already called dmu_tx_wait().
  *     This will ensure that we don't retry forever, waiting a short bit
  *     each time.
  *     rw_enter(...);                  // grab any other locks you need
  *     tx = dmu_tx_create(...);        // get DMU tx
  *     dmu_tx_hold_*();                // hold each object you might modify
- *     error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+ *     error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
  *     if (error) {
  *             rw_exit(...);           // drop locks
  *             zfs_dirent_unlock(dl);  // unlock directory entry
@@ -398,6 +398,7 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio)
                pp = find_lock_page(mp, start >> PAGE_SHIFT);
                if (pp) {
                        ASSERT(PageUptodate(pp));
+                       unlock_page(pp);
 
                        pb = kmap(pp);
                        error = uiomove(pb + off, bytes, UIO_READ, uio);
@@ -407,7 +408,6 @@ mappedread(struct inode *ip, int nbytes, uio_t *uio)
                                flush_dcache_page(pp);
 
                        mark_page_accessed(pp);
-                       unlock_page(pp);
                        put_page(pp);
                } else {
                        error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
@@ -1427,7 +1427,8 @@ top:
                        dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
                            0, acl_ids.z_aclp->z_acl_bytes);
                }
-               error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+               error = dmu_tx_assign(tx,
+                   (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
                if (error) {
                        zfs_dirent_unlock(dl);
                        if (error == ERESTART) {
@@ -1443,22 +1444,10 @@ top:
                }
                zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
 
-               error = zfs_link_create(dl, zp, tx, ZNEW);
-               if (error != 0) {
-                       /*
-                        * Since, we failed to add the directory entry for it,
-                        * delete the newly created dnode.
-                        */
-                       zfs_znode_delete(zp, tx);
-                       remove_inode_hash(ZTOI(zp));
-                       zfs_acl_ids_free(&acl_ids);
-                       dmu_tx_commit(tx);
-                       goto out;
-               }
-
                if (fuid_dirtied)
                        zfs_fuid_sync(zfsvfs, tx);
 
+               (void) zfs_link_create(dl, zp, tx, ZNEW);
                txtype = zfs_log_create_txtype(Z_FILE, vsecp, vap);
                if (flag & FIGNORECASE)
                        txtype |= TX_CI;
@@ -1614,7 +1603,7 @@ top:
                dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
                    0, acl_ids.z_aclp->z_acl_bytes);
        }
-       error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+       error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
        if (error) {
                if (error == ERESTART) {
                        waited = B_TRUE;
@@ -1787,7 +1776,7 @@ top:
         */
        dmu_tx_mark_netfree(tx);
 
-       error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+       error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
        if (error) {
                zfs_dirent_unlock(dl);
                if (error == ERESTART) {
@@ -2029,7 +2018,7 @@ top:
        dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
            ZFS_SA_BASE_ATTR_SIZE);
 
-       error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+       error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
        if (error) {
                zfs_dirent_unlock(dl);
                if (error == ERESTART) {
@@ -2049,18 +2038,13 @@ top:
         */
        zfs_mknode(dzp, vap, tx, cr, 0, &zp, &acl_ids);
 
+       if (fuid_dirtied)
+               zfs_fuid_sync(zfsvfs, tx);
+
        /*
         * Now put new name in parent dir.
         */
-       error = zfs_link_create(dl, zp, tx, ZNEW);
-       if (error != 0) {
-               zfs_znode_delete(zp, tx);
-               remove_inode_hash(ZTOI(zp));
-               goto out;
-       }
-
-       if (fuid_dirtied)
-               zfs_fuid_sync(zfsvfs, tx);
+       (void) zfs_link_create(dl, zp, tx, ZNEW);
 
        *ipp = ZTOI(zp);
 
@@ -2070,7 +2054,6 @@ top:
        zfs_log_create(zilog, tx, txtype, dzp, zp, dirname, vsecp,
            acl_ids.z_fuidp, vap);
 
-out:
        zfs_acl_ids_free(&acl_ids);
 
        dmu_tx_commit(tx);
@@ -2080,14 +2063,10 @@ out:
        if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
                zil_commit(zilog, 0);
 
-       if (error != 0) {
-               iput(ZTOI(zp));
-       } else {
-               zfs_inode_update(dzp);
-               zfs_inode_update(zp);
-       }
+       zfs_inode_update(dzp);
+       zfs_inode_update(zp);
        ZFS_EXIT(zfsvfs);
-       return (error);
+       return (0);
 }
 
 /*
@@ -2178,7 +2157,7 @@ top:
        zfs_sa_upgrade_txholds(tx, zp);
        zfs_sa_upgrade_txholds(tx, dzp);
        dmu_tx_mark_netfree(tx);
-       error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+       error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
        if (error) {
                rw_exit(&zp->z_parent_lock);
                rw_exit(&zp->z_name_lock);
@@ -2245,7 +2224,7 @@ out:
  */
 /* ARGSUSED */
 int
-zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
+zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
 {
        znode_t         *zp = ITOZ(ip);
        zfsvfs_t        *zfsvfs = ITOZSB(ip);
@@ -2350,7 +2329,7 @@ zfs_readdir(struct inode *ip, struct dir_context *ctx, cred_t *cr)
                        type = ZFS_DIRENT_TYPE(zap.za_first_integer);
                }
 
-               done = !dir_emit(ctx, zap.za_name, strlen(zap.za_name),
+               done = !zpl_dir_emit(ctx, zap.za_name, strlen(zap.za_name),
                    objnum, type);
                if (done)
                        break;
@@ -3180,7 +3159,7 @@ top:
 
        if (mask & (ATTR_MTIME | ATTR_SIZE)) {
                ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
-               ZTOI(zp)->i_mtime = timespec_trunc(vap->va_mtime,
+               ZTOI(zp)->i_mtime = zpl_inode_timespec_trunc(vap->va_mtime,
                    ZTOI(zp)->i_sb->s_time_gran);
 
                SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL,
@@ -3189,7 +3168,7 @@ top:
 
        if (mask & (ATTR_CTIME | ATTR_SIZE)) {
                ZFS_TIME_ENCODE(&vap->va_ctime, ctime);
-               ZTOI(zp)->i_ctime = timespec_trunc(vap->va_ctime,
+               ZTOI(zp)->i_ctime = zpl_inode_timespec_trunc(vap->va_ctime,
                    ZTOI(zp)->i_sb->s_time_gran);
                SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
                    ctime, sizeof (ctime));
@@ -3645,7 +3624,7 @@ top:
 
        zfs_sa_upgrade_txholds(tx, szp);
        dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
-       error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+       error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
        if (error) {
                if (zl != NULL)
                        zfs_rename_unlock(&zl);
@@ -3705,13 +3684,6 @@ top:
                                VERIFY3U(zfs_link_destroy(tdl, szp, tx,
                                    ZRENAMING, NULL), ==, 0);
                        }
-               } else {
-                       /*
-                        * If we had removed the existing target, subsequent
-                        * call to zfs_link_create() to add back the same entry
-                        * but, the new dnode (szp) should not fail.
-                        */
-                       ASSERT(tzp == NULL);
                }
        }
 
@@ -3844,7 +3816,7 @@ top:
        }
        if (fuid_dirtied)
                zfs_fuid_txhold(zfsvfs, tx);
-       error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+       error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
        if (error) {
                zfs_dirent_unlock(dl);
                if (error == ERESTART) {
@@ -3882,18 +3854,14 @@ top:
        /*
         * Insert the new object into the directory.
         */
-       error = zfs_link_create(dl, zp, tx, ZNEW);
-       if (error != 0) {
-               zfs_znode_delete(zp, tx);
-               remove_inode_hash(ZTOI(zp));
-       } else {
-               if (flags & FIGNORECASE)
-                       txtype |= TX_CI;
-               zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
+       (void) zfs_link_create(dl, zp, tx, ZNEW);
 
-               zfs_inode_update(dzp);
-               zfs_inode_update(zp);
-       }
+       if (flags & FIGNORECASE)
+               txtype |= TX_CI;
+       zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
+
+       zfs_inode_update(dzp);
+       zfs_inode_update(zp);
 
        zfs_acl_ids_free(&acl_ids);
 
@@ -3901,14 +3869,10 @@ top:
 
        zfs_dirent_unlock(dl);
 
-       if (error == 0) {
-               *ipp = ZTOI(zp);
+       *ipp = ZTOI(zp);
 
-               if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
-                       zil_commit(zilog, 0);
-       } else {
-               iput(ZTOI(zp));
-       }
+       if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+               zil_commit(zilog, 0);
 
        ZFS_EXIT(zfsvfs);
        return (error);
@@ -4078,7 +4042,7 @@ top:
 
        zfs_sa_upgrade_txholds(tx, szp);
        zfs_sa_upgrade_txholds(tx, dzp);
-       error = dmu_tx_assign(tx, waited ? TXG_WAITED : TXG_NOWAIT);
+       error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
        if (error) {
                zfs_dirent_unlock(dl);
                if (error == ERESTART) {