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
@ -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 {
|
|||||||
* @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 {
|
|||||||
} 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 {
|
|||||||
* @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 {
|
|||||||
|
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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);
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user