mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	9p: Replace the fidlist with an IDR
The p9_idpool being used to allocate the IDs uses an IDR to allocate the IDs ... which we then keep in a doubly-linked list, rather than in the IDR which allocated them. We can use an IDR directly which saves two pointers per p9_fid, and a tiny memory allocation per p9_client. Link: http://lkml.kernel.org/r/20180711210225.19730-4-willy@infradead.org Signed-off-by: Matthew Wilcox <willy@infradead.org> Cc: Eric Van Hensbergen <ericvh@gmail.com> Cc: Ron Minnich <rminnich@sandia.gov> Cc: Latchesar Ionkov <lucho@ionkov.net> Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
This commit is contained in:
		
							parent
							
								
									b5303be2be
								
							
						
					
					
						commit
						f28cdf0430
					
				
					 2 changed files with 19 additions and 34 deletions
				
			
		| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
#define NET_9P_CLIENT_H
 | 
			
		||||
 | 
			
		||||
#include <linux/utsname.h>
 | 
			
		||||
#include <linux/idr.h>
 | 
			
		||||
 | 
			
		||||
/* Number of requests per row */
 | 
			
		||||
#define P9_ROW_MAXTAG 255
 | 
			
		||||
| 
						 | 
				
			
			@ -128,8 +129,7 @@ struct p9_req_t {
 | 
			
		|||
 * @proto_version: 9P protocol version to use
 | 
			
		||||
 * @trans_mod: module API instantiated with this client
 | 
			
		||||
 * @trans: tranport instance state and API
 | 
			
		||||
 * @fidpool: fid handle accounting for session
 | 
			
		||||
 * @fidlist: List of active fid handles
 | 
			
		||||
 * @fids: All active FID handles
 | 
			
		||||
 * @tagpool - transaction id accounting for session
 | 
			
		||||
 * @reqs - 2D array of requests
 | 
			
		||||
 * @max_tag - current maximum tag id allocated
 | 
			
		||||
| 
						 | 
				
			
			@ -169,8 +169,7 @@ struct p9_client {
 | 
			
		|||
		} tcp;
 | 
			
		||||
	} trans_opts;
 | 
			
		||||
 | 
			
		||||
	struct p9_idpool *fidpool;
 | 
			
		||||
	struct list_head fidlist;
 | 
			
		||||
	struct idr fids;
 | 
			
		||||
 | 
			
		||||
	struct p9_idpool *tagpool;
 | 
			
		||||
	struct p9_req_t *reqs[P9_ROW_MAXTAG];
 | 
			
		||||
| 
						 | 
				
			
			@ -188,7 +187,6 @@ struct p9_client {
 | 
			
		|||
 * @iounit: the server reported maximum transaction size for this file
 | 
			
		||||
 * @uid: the numeric uid of the local user who owns this handle
 | 
			
		||||
 * @rdir: readdir accounting structure (allocated on demand)
 | 
			
		||||
 * @flist: per-client-instance fid tracking
 | 
			
		||||
 * @dlist: per-dentry fid tracking
 | 
			
		||||
 *
 | 
			
		||||
 * TODO: This needs lots of explanation.
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +202,6 @@ struct p9_fid {
 | 
			
		|||
 | 
			
		||||
	void *rdir;
 | 
			
		||||
 | 
			
		||||
	struct list_head flist;
 | 
			
		||||
	struct hlist_node dlist;	/* list of all fids attached to a dentry */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -909,30 +909,29 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
 | 
			
		|||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	struct p9_fid *fid;
 | 
			
		||||
	unsigned long flags;
 | 
			
		||||
 | 
			
		||||
	p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
 | 
			
		||||
	fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
 | 
			
		||||
	if (!fid)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	ret = p9_idpool_get(clnt->fidpool);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		goto error;
 | 
			
		||||
	fid->fid = ret;
 | 
			
		||||
 | 
			
		||||
	memset(&fid->qid, 0, sizeof(struct p9_qid));
 | 
			
		||||
	fid->mode = -1;
 | 
			
		||||
	fid->uid = current_fsuid();
 | 
			
		||||
	fid->clnt = clnt;
 | 
			
		||||
	fid->rdir = NULL;
 | 
			
		||||
	spin_lock_irqsave(&clnt->lock, flags);
 | 
			
		||||
	list_add(&fid->flist, &clnt->fidlist);
 | 
			
		||||
	spin_unlock_irqrestore(&clnt->lock, flags);
 | 
			
		||||
	fid->fid = 0;
 | 
			
		||||
 | 
			
		||||
	return fid;
 | 
			
		||||
	idr_preload(GFP_KERNEL);
 | 
			
		||||
	spin_lock_irq(&clnt->lock);
 | 
			
		||||
	ret = idr_alloc_u32(&clnt->fids, fid, &fid->fid, P9_NOFID - 1,
 | 
			
		||||
			    GFP_NOWAIT);
 | 
			
		||||
	spin_unlock_irq(&clnt->lock);
 | 
			
		||||
	idr_preload_end();
 | 
			
		||||
 | 
			
		||||
	if (!ret)
 | 
			
		||||
		return fid;
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
	kfree(fid);
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -944,9 +943,8 @@ static void p9_fid_destroy(struct p9_fid *fid)
 | 
			
		|||
 | 
			
		||||
	p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid);
 | 
			
		||||
	clnt = fid->clnt;
 | 
			
		||||
	p9_idpool_put(fid->fid, clnt->fidpool);
 | 
			
		||||
	spin_lock_irqsave(&clnt->lock, flags);
 | 
			
		||||
	list_del(&fid->flist);
 | 
			
		||||
	idr_remove(&clnt->fids, fid->fid);
 | 
			
		||||
	spin_unlock_irqrestore(&clnt->lock, flags);
 | 
			
		||||
	kfree(fid->rdir);
 | 
			
		||||
	kfree(fid);
 | 
			
		||||
| 
						 | 
				
			
			@ -1029,7 +1027,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
 | 
			
		|||
	memcpy(clnt->name, client_id, strlen(client_id) + 1);
 | 
			
		||||
 | 
			
		||||
	spin_lock_init(&clnt->lock);
 | 
			
		||||
	INIT_LIST_HEAD(&clnt->fidlist);
 | 
			
		||||
	idr_init(&clnt->fids);
 | 
			
		||||
 | 
			
		||||
	err = p9_tag_init(clnt);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -1049,18 +1047,12 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
 | 
			
		|||
		goto destroy_tagpool;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clnt->fidpool = p9_idpool_create();
 | 
			
		||||
	if (IS_ERR(clnt->fidpool)) {
 | 
			
		||||
		err = PTR_ERR(clnt->fidpool);
 | 
			
		||||
		goto put_trans;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
 | 
			
		||||
		 clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
 | 
			
		||||
 | 
			
		||||
	err = clnt->trans_mod->create(clnt, dev_name, options);
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto destroy_fidpool;
 | 
			
		||||
		goto put_trans;
 | 
			
		||||
 | 
			
		||||
	if (clnt->msize > clnt->trans_mod->maxsize)
 | 
			
		||||
		clnt->msize = clnt->trans_mod->maxsize;
 | 
			
		||||
| 
						 | 
				
			
			@ -1073,8 +1065,6 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
 | 
			
		|||
 | 
			
		||||
close_trans:
 | 
			
		||||
	clnt->trans_mod->close(clnt);
 | 
			
		||||
destroy_fidpool:
 | 
			
		||||
	p9_idpool_destroy(clnt->fidpool);
 | 
			
		||||
put_trans:
 | 
			
		||||
	v9fs_put_trans(clnt->trans_mod);
 | 
			
		||||
destroy_tagpool:
 | 
			
		||||
| 
						 | 
				
			
			@ -1087,7 +1077,8 @@ EXPORT_SYMBOL(p9_client_create);
 | 
			
		|||
 | 
			
		||||
void p9_client_destroy(struct p9_client *clnt)
 | 
			
		||||
{
 | 
			
		||||
	struct p9_fid *fid, *fidptr;
 | 
			
		||||
	struct p9_fid *fid;
 | 
			
		||||
	int id;
 | 
			
		||||
 | 
			
		||||
	p9_debug(P9_DEBUG_MUX, "clnt %p\n", clnt);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1096,14 +1087,11 @@ void p9_client_destroy(struct p9_client *clnt)
 | 
			
		|||
 | 
			
		||||
	v9fs_put_trans(clnt->trans_mod);
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) {
 | 
			
		||||
	idr_for_each_entry(&clnt->fids, fid, id) {
 | 
			
		||||
		pr_info("Found fid %d not clunked\n", fid->fid);
 | 
			
		||||
		p9_fid_destroy(fid);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (clnt->fidpool)
 | 
			
		||||
		p9_idpool_destroy(clnt->fidpool);
 | 
			
		||||
 | 
			
		||||
	p9_tag_cleanup(clnt);
 | 
			
		||||
 | 
			
		||||
	kfree(clnt);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue