Permalink
Browse files

WIP - fix asynchronous delete

Problem
  The zfs_delete_blocks parameter, which is supposed to act as a
  size threshold over which files will be deleted asynchronously,
  does not work as intended.  It's implemented in zfs_remove(),
  which in ZoL, is used both as a VFS function and also internally to
  remove the components of directory-based xattrs.  When called from
  the VFS reference count on the inode following zfs_dirent_lock()
  will always be at least 2, 1 for the initial allocation and 1
  for the reference taken in zfs_zget().  This causes "toobig"
  to always be false.

Potential solution
  Since the removal of normal files actually takes place over the
  evict() path, add async removal handling to zfs_zinactive() which
  will always be called vi iput_final() with a zero reference count.

NOTE: If this scheme works properly, all the zfs_delete_blocks/async
handling should be able to be removed from zfs_remove().
  • Loading branch information...
dweeezil committed Oct 10, 2018
1 parent dfbe267 commit 342b93fd84d9b857316c38d45d3baa899fc829dc
Showing with 12 additions and 2 deletions.
  1. +12 −2 module/zfs/zfs_znode.c
View
@@ -80,6 +80,8 @@
#define ZNODE_STAT_ADD(stat) /* nothing */
#endif /* ZNODE_STATS */
extern unsigned long zfs_delete_blocks;
/*
* Functions needed for userland (ie: libzpool) are not put under
* #ifdef_KERNEL; the rest of the functions have dependencies
@@ -1112,7 +1114,6 @@ zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp)
if (hdl != NULL) {
zp = sa_get_userdata(hdl);
/*
* Since "SA" does immediate eviction we
* should never find a sa handle that doesn't
@@ -1359,11 +1360,20 @@ zfs_zinactive(znode_t *zp)
* closed. The file will remain in the unlinked set.
*/
if (zp->z_unlinked) {
boolean_t toobig = toobig = zp->z_size > zp->z_blksz * zfs_delete_blocks;
taskq_t *itq = dsl_pool_iput_taskq(
dmu_objset_pool(ZTOZSB(zp)->z_os));
ASSERT(!zfsvfs->z_issnap);
if (!zfs_is_readonly(zfsvfs)) {
mutex_exit(&zp->z_lock);
zfs_znode_hold_exit(zfsvfs, zh);
zfs_rmnode(zp);
if (toobig && !taskq_member(itq, curthread))
VERIFY(taskq_dispatch(itq,
(task_func_t *)zfs_rmnode,
zp, TQ_SLEEP) != TASKQID_INVALID);
else
zfs_rmnode(zp);
return;
}
}

0 comments on commit 342b93f

Please sign in to comment.