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

📄 export.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
	current->sigpending = 0;	want_lock++;	while (hash_count || hash_lock) {		interruptible_sleep_on(&hash_wait);		if (signal_pending(current))			break;	}	want_lock--;	/* restore the task's signals */	spin_lock_irq(&current->sigmask_lock);	recalc_sigpending(current);	spin_unlock_irq(&current->sigmask_lock);	if (!hash_count && !hash_lock)		goto lock_it;	return -EINTR;}voidexp_unlock(void){	if (!hash_count && !hash_lock)		printk(KERN_WARNING "exp_unlock: not locked!\n");	if (hash_count)		hash_count--;	else		hash_lock = 0;	wake_up(&hash_wait);}/* * Find a valid client given an inet address. We always move the most * recently used client to the front of the hash chain to speed up * future lookups. * Locking against other processes is the responsibility of the caller. */struct svc_client *exp_getclient(struct sockaddr_in *sin){	struct svc_clnthash	**hp, **head, *tmp;	unsigned long		addr = sin->sin_addr.s_addr;	if (!initialized)		return NULL;	head = &clnt_hash[CLIENT_HASH(addr)];	for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {		if (tmp->h_addr.s_addr == addr) {			/* Move client to the front */			if (head != hp) {				*hp = tmp->h_next;				tmp->h_next = *head;				*head = tmp;			}			return tmp->h_client;		}	}	return NULL;}/* * Find a client given its identifier. */static svc_client *exp_getclientbyname(char *ident){	svc_client *	clp;	for (clp = clients; clp; clp = clp->cl_next) {		if (!strcmp(clp->cl_ident, ident))			return clp;	}	return NULL;}struct flags {	int flag;	char *name[2];} expflags[] = {	{ NFSEXP_READONLY, {"ro", "rw"}},	{ NFSEXP_INSECURE_PORT, {"insecure", ""}},	{ NFSEXP_ROOTSQUASH, {"root_squash", "no_root_squash"}},	{ NFSEXP_ALLSQUASH, {"all_squash", ""}},	{ NFSEXP_ASYNC, {"async", "sync"}},	{ NFSEXP_GATHERED_WRITES, {"wdelay", "no_wdelay"}},	{ NFSEXP_UIDMAP, {"uidmap", ""}},	{ NFSEXP_KERBEROS, { "kerberos", ""}},	{ NFSEXP_SUNSECURE, { "sunsecure", ""}},	{ NFSEXP_CROSSMNT, {"nohide", ""}},	{ NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},	{ NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},#ifdef MSNFS	{ NFSEXP_MSNFS, {"msnfs", ""}},#endif	{ 0, {"", ""}}};static intexp_flags(char *buffer, int flag){    int len = 0, first = 0;    struct flags *flg = expflags;    for (;flg->flag;flg++) {        int state = (flg->flag & flag)?0:1;        if (!flg->flag)		break;        if (*flg->name[state]) {		len += sprintf(buffer + len, "%s%s",                               first++?",":"", flg->name[state]);        }    }    return len;}/* mangling borrowed from fs/super.c *//* Use octal escapes, like mount does, for embedded spaces etc. */static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };static intmangle(const unsigned char *s, char *buf, int len) {        char *sp;        int n;        sp = buf;        while(*s && sp-buf < len-3) {                for (n = 0; n < sizeof(need_escaping); n++) {                        if (*s == need_escaping[n]) {                                *sp++ = '\\';                                *sp++ = '0' + ((*s & 0300) >> 6);                                *sp++ = '0' + ((*s & 070) >> 3);                                *sp++ = '0' + (*s & 07);                                goto next;                        }                }                *sp++ = *s;        next:                s++;        }        return sp - buf;	/* no trailing NUL */}#define FREEROOM	((int)PAGE_SIZE-200-len)#define MANGLE(s)	len += mangle((s), buffer+len, FREEROOM);intexp_procfs_exports(char *buffer, char **start, off_t offset,                             int length, int *eof, void *data){	struct svc_clnthash	**hp, **head, *tmp;	struct svc_client	*clp;	svc_export *exp;	off_t	pos = 0;        off_t	begin = 0;        int	len = 0;	int	i,j;        len += sprintf(buffer, "# Version 1.1\n");        len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n");	for (clp = clients; clp; clp = clp->cl_next) {		for (i = 0; i < NFSCLNT_EXPMAX; i++) {			exp = clp->cl_export[i];			while (exp) {				int first = 0;				MANGLE(exp->ex_path);				buffer[len++]='\t';				MANGLE(clp->cl_ident);				buffer[len++]='(';				len += exp_flags(buffer+len, exp->ex_flags);				len += sprintf(buffer+len, ") # ");				for (j = 0; j < clp->cl_naddr; j++) {					struct in_addr	addr = clp->cl_addr[j]; 					head = &clnt_hash[CLIENT_HASH(addr.s_addr)];					for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {						if (tmp->h_addr.s_addr == addr.s_addr) {							if (first++) len += sprintf(buffer+len, "%s", " ");							if (tmp->h_client != clp)								len += sprintf(buffer+len, "(");							len += sprintf(buffer+len, "%d.%d.%d.%d",									htonl(addr.s_addr) >> 24 & 0xff,									htonl(addr.s_addr) >> 16 & 0xff,									htonl(addr.s_addr) >>  8 & 0xff,									htonl(addr.s_addr) >>  0 & 0xff);							if (tmp->h_client != clp)							  len += sprintf(buffer+len, ")");							break;						}					}				}				exp = exp->ex_next;				buffer[len++]='\n';				pos=begin+len;				if(pos<offset) {					len=0;					begin=pos;				}				if (pos > offset + length)					goto done;			}		}	}	*eof = 1;done:	*start = buffer + (offset - begin);	len -= (offset - begin);	if ( len > length )		len = length;	return len;}/* * Add or modify a client. * Change requests may involve the list of host addresses. The list of * exports and possibly existing uid maps are left untouched. */intexp_addclient(struct nfsctl_client *ncp){	struct svc_clnthash *	ch[NFSCLNT_ADDRMAX];	svc_client *		clp;	int			i, err, change = 0, ilen;	/* First, consistency check. */	err = -EINVAL;	if (!(ilen = exp_verify_string(ncp->cl_ident, NFSCLNT_IDMAX)))		goto out;	if (ncp->cl_naddr > NFSCLNT_ADDRMAX)		goto out;	/* Lock the hashtable */	if ((err = exp_writelock()) < 0)		goto out;	/* First check if this is a change request for a client. */	for (clp = clients; clp; clp = clp->cl_next)		if (!strcmp(clp->cl_ident, ncp->cl_ident))			break;	err = -ENOMEM;	if (clp) {		change = 1;	} else {		if (!(clp = kmalloc(sizeof(*clp), GFP_KERNEL)))			goto out_unlock;		memset(clp, 0, sizeof(*clp));		dprintk("created client %s (%p)\n", ncp->cl_ident, clp);		strcpy(clp->cl_ident, ncp->cl_ident);		clp->cl_idlen = ilen;	}	/* Allocate hash buckets */	for (i = 0; i < ncp->cl_naddr; i++) {		ch[i] = kmalloc(sizeof(struct svc_clnthash), GFP_KERNEL);		if (!ch[i]) {			while (i--)				kfree(ch[i]);			if (!change)				kfree(clp);			goto out_unlock;		}	}	/* Copy addresses. */	for (i = 0; i < ncp->cl_naddr; i++) {		clp->cl_addr[i] = ncp->cl_addrlist[i];	}	clp->cl_naddr = ncp->cl_naddr;	/* Remove old client hash entries. */	if (change)		exp_unhashclient(clp);	/* Insert client into hashtable. */	for (i = 0; i < ncp->cl_naddr; i++) {		struct in_addr	addr = clp->cl_addr[i];		int		hash;		hash = CLIENT_HASH(addr.s_addr);		ch[i]->h_client = clp;		ch[i]->h_addr = addr;		ch[i]->h_next = clnt_hash[hash];		clnt_hash[hash] = ch[i];	}	if (!change) {		clp->cl_next = clients;		clients = clp;	}	err = 0;out_unlock:	exp_unlock();out:	return err;}/* * Delete a client given an identifier. */intexp_delclient(struct nfsctl_client *ncp){	svc_client	**clpp, *clp;	int		err;	err = -EINVAL;	if (!exp_verify_string(ncp->cl_ident, NFSCLNT_IDMAX))		goto out;	/* Lock the hashtable */	if ((err = exp_writelock()) < 0)		goto out;	err = -EINVAL;	for (clpp = &clients; (clp = *clpp); clpp = &(clp->cl_next))		if (!strcmp(ncp->cl_ident, clp->cl_ident))			break;	if (clp) {		*clpp = clp->cl_next;		exp_freeclient(clp);		err = 0;	}	exp_unlock();out:	return err;}/* * Free a client. The caller has already removed it from the client list. */static voidexp_freeclient(svc_client *clp){	exp_unhashclient(clp);	/* umap_free(&(clp->cl_umap)); */	exp_unexport_all(clp);	nfsd_lockd_unexport(clp);	kfree (clp);}/* * Remove client from hashtable. We first collect all hashtable * entries and free them in one go. * The hash table must be writelocked by the caller. */static voidexp_unhashclient(svc_client *clp){	struct svc_clnthash	**hpp, *hp, *ch[NFSCLNT_ADDRMAX];	int			i, count, err;again:	err = 0;	for (i = 0, count = 0; i < CLIENT_HASHMAX && !err; i++) {		hpp = clnt_hash + i;		while ((hp = *hpp) && !err) {			if (hp->h_client == clp) {				*hpp = hp->h_next;				ch[count++] = hp;				err = (count >= NFSCLNT_ADDRMAX);			} else {				hpp = &(hp->h_next);			}		}	}	if (count != clp->cl_naddr)		printk(KERN_WARNING "nfsd: bad address count in freeclient!\n");	if (err)		goto again;	for (i = 0; i < count; i++)		kfree (ch[i]);}/* * Lockd is shutting down and tells us to unregister all clients */voidexp_nlmdetach(void){	struct svc_client	*clp;	for (clp = clients; clp; clp = clp->cl_next)		nfsd_lockd_unexport(clp);}/* * Verify that string is non-empty and does not exceed max length. */static intexp_verify_string(char *cp, int max){	int	i;	for (i = 0; i < max; i++)		if (!cp[i])			return i;	cp[i] = 0;	printk(KERN_NOTICE "nfsd: couldn't validate string %s\n", cp);	return 0;}/* * Initialize the exports module. */voidnfsd_export_init(void){	int		i;	dprintk("nfsd: initializing export module.\n");	if (initialized)		return;	for (i = 0; i < CLIENT_HASHMAX; i++)		clnt_hash[i] = NULL;	clients = NULL;	initialized = 1;}/* * Shutdown the exports module. */voidnfsd_export_shutdown(void){	int	i;	dprintk("nfsd: shutting down export module.\n");	if (!initialized)		return;	if (exp_writelock() < 0) {		printk(KERN_WARNING "Weird: hashtable locked in exp_shutdown");		return;	}	for (i = 0; i < CLIENT_HASHMAX; i++) {		while (clnt_hash[i])			exp_freeclient(clnt_hash[i]->h_client);	}	clients = NULL; /* we may be restarted before the module unloads */		exp_unlock();	dprintk("nfsd: export shutdown complete.\n");}

⌨️ 快捷键说明

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