Commit baab935f authored by NeilBrown's avatar NeilBrown Committed by Linus Torvalds
Browse files

[PATCH] knfsd: Convert sunrpc_cache to use krefs



.. it makes some of the code nicer.

Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ebd0cb1a
Loading
Loading
Loading
Loading
+24 −27
Original line number Diff line number Diff line
@@ -57,19 +57,18 @@ static int exp_verify_string(char *cp, int max);
#define	EXPKEY_HASHMASK		(EXPKEY_HASHMAX -1)
static struct cache_head *expkey_table[EXPKEY_HASHMAX];

void expkey_put(struct cache_head *item, struct cache_detail *cd)
void expkey_put(struct kref *ref)
{
	if (cache_put(item, cd)) {
		struct svc_expkey *key = container_of(item, struct svc_expkey, h);
		if (test_bit(CACHE_VALID, &item->flags) &&
		    !test_bit(CACHE_NEGATIVE, &item->flags)) {
	struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);

	if (test_bit(CACHE_VALID, &key->h.flags) &&
	    !test_bit(CACHE_NEGATIVE, &key->h.flags)) {
		dput(key->ek_dentry);
		mntput(key->ek_mnt);
	}
	auth_domain_put(key->ek_client);
	kfree(key);
}
}

static void expkey_request(struct cache_detail *cd,
			   struct cache_head *h,
@@ -158,7 +157,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
		set_bit(CACHE_NEGATIVE, &key.h.flags);
		ek = svc_expkey_update(&key, ek);
		if (ek)
			expkey_put(&ek->h, &svc_expkey_cache);
			cache_put(&ek->h, &svc_expkey_cache);
		else err = -ENOMEM;
	} else {
		struct nameidata nd;
@@ -172,7 +171,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
		
		ek = svc_expkey_update(&key, ek);
		if (ek)
			expkey_put(&ek->h, &svc_expkey_cache);
			cache_put(&ek->h, &svc_expkey_cache);
		else
			err = -ENOMEM;
		path_release(&nd);
@@ -318,16 +317,14 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)

static struct cache_head *export_table[EXPORT_HASHMAX];

void svc_export_put(struct cache_head *item, struct cache_detail *cd)
static void svc_export_put(struct kref *ref)
{
	if (cache_put(item, cd)) {
		struct svc_export *exp = container_of(item, struct svc_export, h);
	struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
	dput(exp->ex_dentry);
	mntput(exp->ex_mnt);
	auth_domain_put(exp->ex_client);
	kfree(exp);
}
}

static void svc_export_request(struct cache_detail *cd,
			       struct cache_head *h,
@@ -633,7 +630,7 @@ static int exp_set_key(svc_client *clp, int fsid_type, u32 *fsidv,
	if (ek)
		ek = svc_expkey_update(&key,ek);
	if (ek) {
		expkey_put(&ek->h, &svc_expkey_cache);
		cache_put(&ek->h, &svc_expkey_cache);
		return 0;
	}
	return -ENOMEM;
@@ -762,7 +759,7 @@ static void exp_fsid_unhash(struct svc_export *exp)
	ek = exp_get_fsid_key(exp->ex_client, exp->ex_fsid);
	if (ek && !IS_ERR(ek)) {
		ek->h.expiry_time = get_seconds()-1;
		expkey_put(&ek->h, &svc_expkey_cache);
		cache_put(&ek->h, &svc_expkey_cache);
	}
	svc_expkey_cache.nextcheck = get_seconds();
}
@@ -800,7 +797,7 @@ static void exp_unhash(struct svc_export *exp)
	ek = exp_get_key(exp->ex_client, inode->i_sb->s_dev, inode->i_ino);
	if (ek && !IS_ERR(ek)) {
		ek->h.expiry_time = get_seconds()-1;
		expkey_put(&ek->h, &svc_expkey_cache);
		cache_put(&ek->h, &svc_expkey_cache);
	}
	svc_expkey_cache.nextcheck = get_seconds();
}
@@ -902,7 +899,7 @@ finish:
	if (exp)
		exp_put(exp);
	if (fsid_key && !IS_ERR(fsid_key))
		expkey_put(&fsid_key->h, &svc_expkey_cache);
		cache_put(&fsid_key->h, &svc_expkey_cache);
	if (clp)
		auth_domain_put(clp);
	path_release(&nd);
@@ -1030,7 +1027,7 @@ exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
		return ERR_PTR(PTR_ERR(ek));

	exp = exp_get_by_name(clp, ek->ek_mnt, ek->ek_dentry, reqp);
	expkey_put(&ek->h, &svc_expkey_cache);
	cache_put(&ek->h, &svc_expkey_cache);

	if (!exp || IS_ERR(exp))
		return ERR_PTR(PTR_ERR(exp));
@@ -1068,7 +1065,7 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
	else
		rv = fh_compose(fhp, exp,
				fsid_key->ek_dentry, NULL);
	expkey_put(&fsid_key->h, &svc_expkey_cache);
	cache_put(&fsid_key->h, &svc_expkey_cache);
	return rv;
}

@@ -1187,7 +1184,7 @@ static int e_show(struct seq_file *m, void *p)
	cache_get(&exp->h);
	if (cache_check(&svc_export_cache, &exp->h, NULL))
		return 0;
	if (cache_put(&exp->h, &svc_export_cache)) BUG();
	cache_put(&exp->h, &svc_export_cache);
	return svc_export_show(m, &svc_export_cache, cp);
}

+8 −10
Original line number Diff line number Diff line
@@ -96,13 +96,11 @@ ent_init(struct cache_head *cnew, struct cache_head *citm)
}

static void
ent_put(struct cache_head *ch, struct cache_detail *cd)
ent_put(struct kref *ref)
{
	if (cache_put(ch, cd)) {
		struct ent *map = container_of(ch, struct ent, h);
	struct ent *map = container_of(ref, struct ent, h.ref);
	kfree(map);
}
}

static struct cache_head *
ent_alloc(void)
@@ -270,7 +268,7 @@ idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
	if (res == NULL)
		goto out;

	ent_put(&res->h, &idtoname_cache);
	cache_put(&res->h, &idtoname_cache);

	error = 0;
out:
@@ -433,7 +431,7 @@ nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
	if (res == NULL)
		goto out;

	ent_put(&res->h, &nametoid_cache);
	cache_put(&res->h, &nametoid_cache);
	error = 0;
out:
	kfree(buf1);
@@ -562,7 +560,7 @@ do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *),
		goto out_put;
	return 0;
out_put:
	ent_put(&(*item)->h, detail);
	cache_put(&(*item)->h, detail);
out_err:
	*item = NULL;
	return ret;
@@ -613,7 +611,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
	if (ret)
		return ret;
	*id = item->id;
	ent_put(&item->h, &nametoid_cache);
	cache_put(&item->h, &nametoid_cache);
	return 0;
}

@@ -635,7 +633,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
	ret = strlen(item->name);
	BUG_ON(ret > IDMAP_NAMESZ);
	memcpy(name, item->name, ret);
	ent_put(&item->h, &idtoname_cache);
	cache_put(&item->h, &idtoname_cache);
	return ret;
}

+1 −1
Original line number Diff line number Diff line
@@ -506,7 +506,7 @@ fh_put(struct svc_fh *fhp)
		nfsd_nr_put++;
	}
	if (exp) {
		svc_export_put(&exp->h, &svc_export_cache);
		cache_put(&exp->h, &svc_export_cache);
		fhp->fh_export = NULL;
	}
	return;
+1 −3
Original line number Diff line number Diff line
@@ -102,13 +102,11 @@ int exp_rootfh(struct auth_domain *,
int			exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp, struct cache_req *creq);
int			nfserrno(int errno);

extern void expkey_put(struct cache_head *item, struct cache_detail *cd);
extern void svc_export_put(struct cache_head *item, struct cache_detail *cd);
extern struct cache_detail svc_export_cache, svc_expkey_cache;

static inline void exp_put(struct svc_export *exp)
{
	svc_export_put(&exp->h, &svc_export_cache);
	cache_put(&exp->h, &svc_export_cache);
}

static inline void exp_get(struct svc_export *exp)
+6 −7
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ struct cache_head {
	time_t		last_refresh;   /* If CACHE_PENDING, this is when upcall 
					 * was sent, else this is when update was received
					 */
	atomic_t 	refcnt;
	struct kref	ref;
	unsigned long	flags;
};
#define	CACHE_VALID	0	/* Entry contains valid data */
@@ -68,8 +68,7 @@ struct cache_detail {
	atomic_t		inuse; /* active user-space update or lookup */

	char			*name;
	void			(*cache_put)(struct cache_head *,
					     struct cache_detail*);
	void			(*cache_put)(struct kref *);

	void			(*cache_request)(struct cache_detail *cd,
						 struct cache_head *h,
@@ -151,17 +150,17 @@ extern void cache_clean_deferred(void *owner);

static inline struct cache_head  *cache_get(struct cache_head *h)
{
	atomic_inc(&h->refcnt);
	kref_get(&h->ref);
	return h;
}


static inline int cache_put(struct cache_head *h, struct cache_detail *cd)
static inline void cache_put(struct cache_head *h, struct cache_detail *cd)
{
	if (atomic_read(&h->refcnt) <= 2 &&
	if (atomic_read(&h->ref.refcount) <= 2 &&
	    h->expiry_time < cd->nextcheck)
		cd->nextcheck = h->expiry_time;
	return atomic_dec_and_test(&h->refcnt);
	kref_put(&h->ref, cd->cache_put);
}

extern void cache_init(struct cache_head *h);
Loading