Commit 92e4a673 authored by Jeff Layton's avatar Jeff Layton Committed by Chuck Lever
Browse files

nfsd: simplify the delayed disposal list code



When queueing a dispose list to the appropriate "freeme" lists, it
pointlessly queues the objects one at a time to an intermediate list.

Remove a few helpers and just open code a list_move to make it more
clear and efficient. Better document the resulting functions with
kerneldoc comments.

Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 55fcc7d9
Loading
Loading
Loading
Loading
+22 −42
Original line number Diff line number Diff line
@@ -402,50 +402,27 @@ nfsd_file_dispose_list(struct list_head *dispose)
	}
}

/**
 * nfsd_file_dispose_list_delayed - move list of dead files to net's freeme list
 * @dispose: list of nfsd_files to be disposed
 *
 * Transfers each file to the "freeme" list for its nfsd_net, to eventually
 * be disposed of by the per-net garbage collector.
 */
static void
nfsd_file_list_remove_disposal(struct list_head *dst,
		struct nfsd_fcache_disposal *l)
{
	spin_lock(&l->lock);
	list_splice_init(&l->freeme, dst);
	spin_unlock(&l->lock);
}

static void
nfsd_file_list_add_disposal(struct list_head *files, struct net *net)
nfsd_file_dispose_list_delayed(struct list_head *dispose)
{
	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
	while(!list_empty(dispose)) {
		struct nfsd_file *nf = list_first_entry(dispose,
						struct nfsd_file, nf_lru);
		struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id);
		struct nfsd_fcache_disposal *l = nn->fcache_disposal;

		spin_lock(&l->lock);
	list_splice_tail_init(files, &l->freeme);
		list_move_tail(&nf->nf_lru, &l->freeme);
		spin_unlock(&l->lock);
		queue_work(nfsd_filecache_wq, &l->work);
	}

static void
nfsd_file_list_add_pernet(struct list_head *dst, struct list_head *src,
		struct net *net)
{
	struct nfsd_file *nf, *tmp;

	list_for_each_entry_safe(nf, tmp, src, nf_lru) {
		if (nf->nf_net == net)
			list_move_tail(&nf->nf_lru, dst);
	}
}

static void
nfsd_file_dispose_list_delayed(struct list_head *dispose)
{
	LIST_HEAD(list);
	struct nfsd_file *nf;

	while(!list_empty(dispose)) {
		nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
		nfsd_file_list_add_pernet(&list, dispose, nf->nf_net);
		nfsd_file_list_add_disposal(&list, nf->nf_net);
	}
}

/**
@@ -665,8 +642,8 @@ nfsd_file_close_inode_sync(struct inode *inode)
 * nfsd_file_delayed_close - close unused nfsd_files
 * @work: dummy
 *
 * Walk the LRU list and destroy any entries that have not been used since
 * the last scan.
 * Scrape the freeme list for this nfsd_net, and then dispose of them
 * all.
 */
static void
nfsd_file_delayed_close(struct work_struct *work)
@@ -675,7 +652,10 @@ nfsd_file_delayed_close(struct work_struct *work)
	struct nfsd_fcache_disposal *l = container_of(work,
			struct nfsd_fcache_disposal, work);

	nfsd_file_list_remove_disposal(&head, l);
	spin_lock(&l->lock);
	list_splice_init(&l->freeme, &head);
	spin_unlock(&l->lock);

	nfsd_file_dispose_list(&head);
}