Commit f28cdf04 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Dominique Martinet

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.orgSigned-off-by: default avatarMatthew 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: default avatarDominique Martinet <dominique.martinet@cea.fr>
parent b5303be2
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define NET_9P_CLIENT_H #define NET_9P_CLIENT_H
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/idr.h>
/* Number of requests per row */ /* Number of requests per row */
#define P9_ROW_MAXTAG 255 #define P9_ROW_MAXTAG 255
...@@ -128,8 +129,7 @@ struct p9_req_t { ...@@ -128,8 +129,7 @@ struct p9_req_t {
* @proto_version: 9P protocol version to use * @proto_version: 9P protocol version to use
* @trans_mod: module API instantiated with this client * @trans_mod: module API instantiated with this client
* @trans: tranport instance state and API * @trans: tranport instance state and API
* @fidpool: fid handle accounting for session * @fids: All active FID handles
* @fidlist: List of active fid handles
* @tagpool - transaction id accounting for session * @tagpool - transaction id accounting for session
* @reqs - 2D array of requests * @reqs - 2D array of requests
* @max_tag - current maximum tag id allocated * @max_tag - current maximum tag id allocated
...@@ -169,8 +169,7 @@ struct p9_client { ...@@ -169,8 +169,7 @@ struct p9_client {
} tcp; } tcp;
} trans_opts; } trans_opts;
struct p9_idpool *fidpool; struct idr fids;
struct list_head fidlist;
struct p9_idpool *tagpool; struct p9_idpool *tagpool;
struct p9_req_t *reqs[P9_ROW_MAXTAG]; struct p9_req_t *reqs[P9_ROW_MAXTAG];
...@@ -188,7 +187,6 @@ struct p9_client { ...@@ -188,7 +187,6 @@ struct p9_client {
* @iounit: the server reported maximum transaction size for this file * @iounit: the server reported maximum transaction size for this file
* @uid: the numeric uid of the local user who owns this handle * @uid: the numeric uid of the local user who owns this handle
* @rdir: readdir accounting structure (allocated on demand) * @rdir: readdir accounting structure (allocated on demand)
* @flist: per-client-instance fid tracking
* @dlist: per-dentry fid tracking * @dlist: per-dentry fid tracking
* *
* TODO: This needs lots of explanation. * TODO: This needs lots of explanation.
...@@ -204,7 +202,6 @@ struct p9_fid { ...@@ -204,7 +202,6 @@ struct p9_fid {
void *rdir; void *rdir;
struct list_head flist;
struct hlist_node dlist; /* list of all fids attached to a dentry */ 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) ...@@ -909,30 +909,29 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt)
{ {
int ret; int ret;
struct p9_fid *fid; struct p9_fid *fid;
unsigned long flags;
p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt); p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt);
fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
if (!fid) if (!fid)
return NULL; return NULL;
ret = p9_idpool_get(clnt->fidpool);
if (ret < 0)
goto error;
fid->fid = ret;
memset(&fid->qid, 0, sizeof(struct p9_qid)); memset(&fid->qid, 0, sizeof(struct p9_qid));
fid->mode = -1; fid->mode = -1;
fid->uid = current_fsuid(); fid->uid = current_fsuid();
fid->clnt = clnt; fid->clnt = clnt;
fid->rdir = NULL; fid->rdir = NULL;
spin_lock_irqsave(&clnt->lock, flags); fid->fid = 0;
list_add(&fid->flist, &clnt->fidlist);
spin_unlock_irqrestore(&clnt->lock, flags);
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); kfree(fid);
return NULL; return NULL;
} }
...@@ -944,9 +943,8 @@ static void p9_fid_destroy(struct p9_fid *fid) ...@@ -944,9 +943,8 @@ static void p9_fid_destroy(struct p9_fid *fid)
p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid); p9_debug(P9_DEBUG_FID, "fid %d\n", fid->fid);
clnt = fid->clnt; clnt = fid->clnt;
p9_idpool_put(fid->fid, clnt->fidpool);
spin_lock_irqsave(&clnt->lock, flags); spin_lock_irqsave(&clnt->lock, flags);
list_del(&fid->flist); idr_remove(&clnt->fids, fid->fid);
spin_unlock_irqrestore(&clnt->lock, flags); spin_unlock_irqrestore(&clnt->lock, flags);
kfree(fid->rdir); kfree(fid->rdir);
kfree(fid); kfree(fid);
...@@ -1029,7 +1027,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) ...@@ -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); memcpy(clnt->name, client_id, strlen(client_id) + 1);
spin_lock_init(&clnt->lock); spin_lock_init(&clnt->lock);
INIT_LIST_HEAD(&clnt->fidlist); idr_init(&clnt->fids);
err = p9_tag_init(clnt); err = p9_tag_init(clnt);
if (err < 0) if (err < 0)
...@@ -1049,18 +1047,12 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) ...@@ -1049,18 +1047,12 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
goto destroy_tagpool; 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", p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
clnt, clnt->trans_mod, clnt->msize, clnt->proto_version); clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
err = clnt->trans_mod->create(clnt, dev_name, options); err = clnt->trans_mod->create(clnt, dev_name, options);
if (err) if (err)
goto destroy_fidpool; goto put_trans;
if (clnt->msize > clnt->trans_mod->maxsize) if (clnt->msize > clnt->trans_mod->maxsize)
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) ...@@ -1073,8 +1065,6 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
close_trans: close_trans:
clnt->trans_mod->close(clnt); clnt->trans_mod->close(clnt);
destroy_fidpool:
p9_idpool_destroy(clnt->fidpool);
put_trans: put_trans:
v9fs_put_trans(clnt->trans_mod); v9fs_put_trans(clnt->trans_mod);
destroy_tagpool: destroy_tagpool:
...@@ -1087,7 +1077,8 @@ EXPORT_SYMBOL(p9_client_create); ...@@ -1087,7 +1077,8 @@ EXPORT_SYMBOL(p9_client_create);
void p9_client_destroy(struct p9_client *clnt) 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); p9_debug(P9_DEBUG_MUX, "clnt %p\n", clnt);
...@@ -1096,14 +1087,11 @@ void p9_client_destroy(struct p9_client *clnt) ...@@ -1096,14 +1087,11 @@ void p9_client_destroy(struct p9_client *clnt)
v9fs_put_trans(clnt->trans_mod); 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); pr_info("Found fid %d not clunked\n", fid->fid);
p9_fid_destroy(fid); p9_fid_destroy(fid);
} }
if (clnt->fidpool)
p9_idpool_destroy(clnt->fidpool);
p9_tag_cleanup(clnt); p9_tag_cleanup(clnt);
kfree(clnt); kfree(clnt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment