⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs4idmap.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  fs/nfsd/nfs4idmap.c * *  Mapping of UID/GIDs to name and vice versa. * *  Copyright (c) 2002, 2003 The Regents of the University of *  Michigan.  All rights reserved. * *  Marius Aamodt Eriksen <marius@umich.edu> * *  Redistribution and use in source and binary forms, with or without *  modification, are permitted provided that the following conditions *  are met: * *  1. Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer. *  2. Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution. *  3. Neither the name of the University nor the names of its *     contributors may be used to endorse or promote products derived *     from this software without specific prior written permission. * *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <linux/module.h>#include <linux/init.h>#include <linux/mm.h>#include <linux/utsname.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/sunrpc/clnt.h>#include <linux/nfs.h>#include <linux/nfs4.h>#include <linux/nfs_fs.h>#include <linux/nfs_page.h>#include <linux/sunrpc/cache.h>#include <linux/nfsd_idmap.h>#include <linux/list.h>#include <linux/time.h>#include <linux/seq_file.h>#include <linux/sunrpc/svcauth.h>/* * Cache entry *//* * XXX we know that IDMAP_NAMESZ < PAGE_SIZE, but it's ugly to rely on * that. */#define IDMAP_TYPE_USER  0#define IDMAP_TYPE_GROUP 1struct ent {	struct cache_head h;	int               type;		       /* User / Group */	uid_t             id;	char              name[IDMAP_NAMESZ];	char              authname[IDMAP_NAMESZ];};/* Common entry handling */#define ENT_HASHBITS          8#define ENT_HASHMAX           (1 << ENT_HASHBITS)#define ENT_HASHMASK          (ENT_HASHMAX - 1)static voident_init(struct cache_head *cnew, struct cache_head *citm){	struct ent *new = container_of(cnew, struct ent, h);	struct ent *itm = container_of(citm, struct ent, h);	new->id = itm->id;	new->type = itm->type;	strlcpy(new->name, itm->name, sizeof(new->name));	strlcpy(new->authname, itm->authname, sizeof(new->name));}static voident_put(struct kref *ref){	struct ent *map = container_of(ref, struct ent, h.ref);	kfree(map);}static struct cache_head *ent_alloc(void){	struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL);	if (e)		return &e->h;	else		return NULL;}/* * ID -> Name cache */static struct cache_head *idtoname_table[ENT_HASHMAX];static uint32_tidtoname_hash(struct ent *ent){	uint32_t hash;	hash = hash_str(ent->authname, ENT_HASHBITS);	hash = hash_long(hash ^ ent->id, ENT_HASHBITS);	/* Flip LSB for user/group */	if (ent->type == IDMAP_TYPE_GROUP)		hash ^= 1;	return hash;}static voididtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,    int *blen){ 	struct ent *ent = container_of(ch, struct ent, h);	char idstr[11];	qword_add(bpp, blen, ent->authname);	snprintf(idstr, sizeof(idstr), "%u", ent->id);	qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");	qword_add(bpp, blen, idstr);	(*bpp)[-1] = '\n';}static intidtoname_match(struct cache_head *ca, struct cache_head *cb){	struct ent *a = container_of(ca, struct ent, h);	struct ent *b = container_of(cb, struct ent, h);	return (a->id == b->id && a->type == b->type &&	    strcmp(a->authname, b->authname) == 0);}static intidtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h){	struct ent *ent;	if (h == NULL) {		seq_puts(m, "#domain type id [name]\n");		return 0;	}	ent = container_of(h, struct ent, h);	seq_printf(m, "%s %s %u", ent->authname,			ent->type == IDMAP_TYPE_GROUP ? "group" : "user",			ent->id);	if (test_bit(CACHE_VALID, &h->flags))		seq_printf(m, " %s", ent->name);	seq_printf(m, "\n");	return 0;}static voidwarn_no_idmapd(struct cache_detail *detail){	printk("nfsd: nfsv4 idmapping failing: has idmapd %s?\n",			detail->last_close? "died" : "not been started");}static int         idtoname_parse(struct cache_detail *, char *, int);static struct ent *idtoname_lookup(struct ent *);static struct ent *idtoname_update(struct ent *, struct ent *);static struct cache_detail idtoname_cache = {	.owner		= THIS_MODULE,	.hash_size	= ENT_HASHMAX,	.hash_table	= idtoname_table,	.name		= "nfs4.idtoname",	.cache_put	= ent_put,	.cache_request	= idtoname_request,	.cache_parse	= idtoname_parse,	.cache_show	= idtoname_show,	.warn_no_listener = warn_no_idmapd,	.match		= idtoname_match,	.init		= ent_init,	.update		= ent_init,	.alloc		= ent_alloc,};intidtoname_parse(struct cache_detail *cd, char *buf, int buflen){	struct ent ent, *res;	char *buf1, *bp;	int len;	int error = -EINVAL;	if (buf[buflen - 1] != '\n')		return (-EINVAL);	buf[buflen - 1]= '\0';	buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);	if (buf1 == NULL)		return (-ENOMEM);	memset(&ent, 0, sizeof(ent));	/* Authentication name */	if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)		goto out;	memcpy(ent.authname, buf1, sizeof(ent.authname));	/* Type */	if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)		goto out;	ent.type = strcmp(buf1, "user") == 0 ?		IDMAP_TYPE_USER : IDMAP_TYPE_GROUP;	/* ID */	if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)		goto out;	ent.id = simple_strtoul(buf1, &bp, 10);	if (bp == buf1)		goto out;	/* expiry */	ent.h.expiry_time = get_expiry(&buf);	if (ent.h.expiry_time == 0)		goto out;	error = -ENOMEM;	res = idtoname_lookup(&ent);	if (!res)		goto out;	/* Name */	error = -EINVAL;	len = qword_get(&buf, buf1, PAGE_SIZE);	if (len < 0)		goto out;	if (len == 0)		set_bit(CACHE_NEGATIVE, &ent.h.flags);	else {		if (error >= IDMAP_NAMESZ) {			error = -EINVAL;			goto out;		}		memcpy(ent.name, buf1, sizeof(ent.name));	}	error = -ENOMEM;	res = idtoname_update(&ent, res);	if (res == NULL)		goto out;	cache_put(&res->h, &idtoname_cache);	error = 0;out:	kfree(buf1);	return error;}static struct ent *idtoname_lookup(struct ent *item){	struct cache_head *ch = sunrpc_cache_lookup(&idtoname_cache,						    &item->h,						    idtoname_hash(item));	if (ch)		return container_of(ch, struct ent, h);	else		return NULL;}static struct ent *idtoname_update(struct ent *new, struct ent *old){	struct cache_head *ch = sunrpc_cache_update(&idtoname_cache,						    &new->h, &old->h,						    idtoname_hash(new));	if (ch)		return container_of(ch, struct ent, h);	else		return NULL;}/* * Name -> ID cache */static struct cache_head *nametoid_table[ENT_HASHMAX];static inline intnametoid_hash(struct ent *ent){	return hash_str(ent->name, ENT_HASHBITS);}static voidnametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,    int *blen){ 	struct ent *ent = container_of(ch, struct ent, h);	qword_add(bpp, blen, ent->authname);	qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");	qword_add(bpp, blen, ent->name);	(*bpp)[-1] = '\n';}static intnametoid_match(struct cache_head *ca, struct cache_head *cb){	struct ent *a = container_of(ca, struct ent, h);	struct ent *b = container_of(cb, struct ent, h);	return (a->type == b->type && strcmp(a->name, b->name) == 0 &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -