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

📄 connect.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	set_current_state(TASK_INTERRUPTIBLE);	schedule_timeout(HZ/8);	if(server->ssocket) {		sock_release(csocket);		server->ssocket = NULL;	}	if (smb_buffer) /* buffer usually freed in free_mid - need to free it on error or exit */		cifs_buf_release(smb_buffer);	read_lock(&GlobalSMBSeslock);	if (list_empty(&server->pending_mid_q)) {		/* loop through server session structures attached to this and mark them dead */		list_for_each(tmp, &GlobalSMBSessionList) {			ses =			    list_entry(tmp, struct cifsSesInfo,				       cifsSessionList);			if (ses->server == server) {				ses->status = CifsExiting;				ses->server = NULL;			}		}		read_unlock(&GlobalSMBSeslock);	} else {		spin_lock(&GlobalMid_Lock);		list_for_each(tmp, &server->pending_mid_q) {		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);			if (mid_entry->midState == MID_REQUEST_SUBMITTED) {				cFYI(1,					 (" Clearing Mid 0x%x - waking up ",mid_entry->mid));				task_to_wake = mid_entry->tsk;				if(task_to_wake) {					wake_up_process(task_to_wake);				}			}		}		spin_unlock(&GlobalMid_Lock);		read_unlock(&GlobalSMBSeslock);		set_current_state(TASK_INTERRUPTIBLE);		/* 1/8th of sec is more than enough time for them to exit */		schedule_timeout(HZ/8); 	}	if (list_empty(&server->pending_mid_q)) {		/* mpx threads have not exited yet give them 		at least the smb send timeout time for long ops */		cFYI(1, ("Wait for exit from demultiplex thread"));		set_current_state(TASK_INTERRUPTIBLE);		schedule_timeout(46 * HZ);			/* if threads still have not exited they are probably never		coming home not much else we can do but free the memory */	}	kfree(server);	write_lock(&GlobalSMBSeslock);	atomic_dec(&tcpSesAllocCount);	length = tcpSesAllocCount.counter;	write_unlock(&GlobalSMBSeslock);	if(length  > 0) {		mempool_resize(cifs_req_poolp,			length + CIFS_MIN_RCV_POOL,			GFP_KERNEL);	}	set_current_state(TASK_INTERRUPTIBLE);	schedule_timeout(HZ/4);	return 0;}static void * cifs_kcalloc(size_t size, int type){	void *addr;	addr = kmalloc(size, type);	if (addr)		memset(addr, 0, size);	return addr;}static intcifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol){	char *value;	char *data;	unsigned int  temp_len, i, j;	char separator[2];	separator[0] = ',';	separator[1] = 0; 	memset(vol->source_rfc1001_name,0x20,15);	for(i=0;i < strnlen(system_utsname.nodename,15);i++) {		/* does not have to be a perfect mapping since the field is		informational, only used for servers that do not support		port 445 and it can be overridden at mount time */		vol->source_rfc1001_name[i] = toupper(system_utsname.nodename[i]);	}	vol->source_rfc1001_name[15] = 0;	vol->linux_uid = current->uid;	/* current->euid instead? */	vol->linux_gid = current->gid;	vol->dir_mode = S_IRWXUGO;	/* 2767 perms indicate mandatory locking support */	vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);	/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */	vol->rw = TRUE;	if (!options)		return 1;	if(strncmp(options,"sep=",4) == 0) {		if(options[4] != 0) {			separator[0] = options[4];			options += 5;		} else {			cFYI(1,("Null separator not allowed"));		}	}			while ((data = strsep(&options, separator)) != NULL) {		if (!*data)			continue;		if ((value = strchr(data, '=')) != NULL)			*value++ = '\0';		if (strnicmp(data, "user", 4) == 0) {			if (!value || !*value) {				printk(KERN_WARNING				       "CIFS: invalid or missing username\n");				return 1;	/* needs_arg; */			}			if (strnlen(value, 200) < 200) {				vol->username = value;			} else {				printk(KERN_WARNING "CIFS: username too long\n");				return 1;			}		} else if (strnicmp(data, "pass", 4) == 0) {			if (!value || !*value) {				vol->password = NULL;				continue;			}			temp_len = strlen(value);			/* removed password length check, NTLM passwords				can be arbitrarily long */			/* if comma in password, the string will be 			prematurely null terminated.  Commas in password are			specified across the cifs mount interface by a double			comma ie ,, and a comma used as in other cases ie ','			as a parameter delimiter/separator is single and due			to the strsep above is temporarily zeroed. */			/* NB: password legally can have multiple commas and			the only illegal character in a password is null */							if ((value[temp_len] == 0) && (value[temp_len+1] == separator[0])) {				/* reinsert comma */				value[temp_len] = separator[0];				temp_len+=2;  /* move after the second comma */				while(value[temp_len] != 0)  {					if((value[temp_len] == separator[0]) && (value[temp_len+1] != separator[0])) {						/* single comma indicating start of next parm */						break;					}					temp_len++;				}				if(value[temp_len] == 0) {					options = NULL;				} else {					value[temp_len] = 0;					/* move options to point to start of next parm */					options = value + temp_len + 1;				}				/* go from value to (value + temp_len) condensing double commas to singles */				vol->password = cifs_kcalloc(temp_len, GFP_KERNEL);				for(i=0,j=0;i<temp_len;i++,j++) {					vol->password[j] = value[i];					if(value[i] == separator[0] && value[i+1] == separator[0]) {						/* skip second comma */						i++;					}				}				/* value[temp_len] is zeroed above so					 vol->password[temp_len] guaranteed to be null */			} else {				vol->password = cifs_kcalloc(temp_len + 1, GFP_KERNEL);				strcpy(vol->password, value);			}		} else if (strnicmp(data, "ip", 2) == 0) {			if (!value || !*value) {				vol->UNCip = NULL;			} else if (strnlen(value, 35) < 35) {				vol->UNCip = value;			} else {				printk(KERN_WARNING "CIFS: ip address too long\n");				return 1;			}		} else if ((strnicmp(data, "unc", 3) == 0)			   || (strnicmp(data, "target", 6) == 0)			   || (strnicmp(data, "path", 4) == 0)) {			if (!value || !*value) {				printk(KERN_WARNING				       "CIFS: invalid path to network resource\n");				return 1;	/* needs_arg; */			}			if ((temp_len = strnlen(value, 300)) < 300) {				vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);				if(vol->UNC == NULL)					return 1;				strcpy(vol->UNC,value);				if (strncmp(vol->UNC, "//", 2) == 0) {					vol->UNC[0] = '\\';					vol->UNC[1] = '\\';				} else if (strncmp(vol->UNC, "\\\\", 2) != 0) {	                   					printk(KERN_WARNING					       "CIFS: UNC Path does not begin with // or \\\\ \n");					return 1;				}			} else {				printk(KERN_WARNING "CIFS: UNC name too long\n");				return 1;			}		} else if ((strnicmp(data, "domain", 3) == 0)			   || (strnicmp(data, "workgroup", 5) == 0)) {			if (!value || !*value) {				printk(KERN_WARNING "CIFS: invalid domain name\n");				return 1;	/* needs_arg; */			}			/* BB are there cases in which a comma can be valid in			a domain name and need special handling? */			if (strnlen(value, 65) < 65) {				vol->domainname = value;				cFYI(1, ("Domain name set"));			} else {				printk(KERN_WARNING "CIFS: domain name too long\n");				return 1;			}		} else if (strnicmp(data, "iocharset", 9) == 0) {			if (!value || !*value) {				printk(KERN_WARNING "CIFS: invalid iocharset specified\n");				return 1;	/* needs_arg; */			}			if (strnlen(value, 65) < 65) {				if(strnicmp(value,"default",7))					vol->iocharset = value;				/* if iocharset not set load_nls_default used by caller */				cFYI(1, ("iocharset set to %s",value));			} else {				printk(KERN_WARNING "CIFS: iocharset name too long.\n");				return 1;			}		} else if (strnicmp(data, "uid", 3) == 0) {			if (value && *value) {				vol->linux_uid =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "gid", 3) == 0) {			if (value && *value) {				vol->linux_gid =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "file_mode", 4) == 0) {			if (value && *value) {				vol->file_mode =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "dir_mode", 3) == 0) {			if (value && *value) {				vol->dir_mode =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "port", 4) == 0) {			if (value && *value) {				vol->port =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "rsize", 5) == 0) {			if (value && *value) {				vol->rsize =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "wsize", 5) == 0) {			if (value && *value) {				vol->wsize =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "sockopt", 5) == 0) {			if (value && *value) {				vol->sockopt =					simple_strtoul(value, &value, 0);			}		} else if (strnicmp(data, "netbiosname", 4) == 0) {			if (!value || !*value || (*value == ' ')) {				cFYI(1,("invalid (empty) netbiosname specified"));			} else {				memset(vol->source_rfc1001_name,0x20,15);				for(i=0;i<15;i++) {				/* BB are there cases in which a comma can be 				valid in this workstation netbios name (and need				special handling)? */				/* We do not uppercase netbiosname for user */					if (value[i]==0)						break;					else 						vol->source_rfc1001_name[i] = value[i];				}				/* The string has 16th byte zero still from				set at top of the function  */				if((i==15) && (value[i] != 0))					printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n");			}		} else if (strnicmp(data, "credentials", 4) == 0) {			/* ignore */		} else if (strnicmp(data, "version", 3) == 0) {			/* ignore */		} else if (strnicmp(data, "rw", 2) == 0) {			vol->rw = TRUE;		} else if ((strnicmp(data, "suid", 4) == 0) ||				   (strnicmp(data, "nosuid", 6) == 0) ||				   (strnicmp(data, "exec", 4) == 0) ||				   (strnicmp(data, "noexec", 6) == 0) ||				   (strnicmp(data, "nodev", 5) == 0) ||				   (strnicmp(data, "noauto", 6) == 0) ||				   (strnicmp(data, "dev", 3) == 0)) {			/*  The mount tool or mount.cifs helper (if present)				uses these opts to set flags, and the flags are read				by the kernel vfs layer before we get here (ie				before read super) so there is no point trying to				parse these options again and set anything and it				is ok to just ignore them */			continue;		} else if (strnicmp(data, "ro", 2) == 0) {			vol->rw = FALSE;		} else if (strnicmp(data, "hard", 4) == 0) {			vol->retry = 1;		} else if (strnicmp(data, "soft", 4) == 0) {			vol->retry = 0;		} else if (strnicmp(data, "perm", 4) == 0) {			vol->noperm = 0;		} else if (strnicmp(data, "noperm", 6) == 0) {			vol->noperm = 1;		} else if (strnicmp(data, "setuids", 7) == 0) {			vol->setuids = 1;		} else if (strnicmp(data, "nosetuids", 9) == 0) {			vol->setuids = 0;		} else if (strnicmp(data, "nohard", 6) == 0) {			vol->retry = 0;		} else if (strnicmp(data, "nosoft", 6) == 0) {			vol->retry = 1;		} else if (strnicmp(data, "nointr", 6) == 0) {			vol->intr = 0;		} else if (strnicmp(data, "intr", 4) == 0) {			vol->intr = 1;		} else if (strnicmp(data, "noac", 4) == 0) {			printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");		} else			printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);	}	if (vol->UNC == NULL) {		if(devname == NULL) {			printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");			return 1;		}		if ((temp_len = strnlen(devname, 300)) < 300) {			vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);			if(vol->UNC == NULL)				return 1;			strcpy(vol->UNC,devname);			if (strncmp(vol->UNC, "//", 2) == 0) {				vol->UNC[0] = '\\';				vol->UNC[1] = '\\';			} else if (strncmp(vol->UNC, "\\\\", 2) != 0) {				printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n");				return 1;			}		} else {			printk(KERN_WARNING "CIFS: UNC name too long\n");			return 1;		}	}	if(vol->UNCip == 0)		vol->UNCip = &vol->UNC[2];	return 0;}static struct cifsSesInfo *cifs_find_tcp_session(struct in_addr * target_ip_addr, 		struct in6_addr *target_ip6_addr,		 char *userName, struct TCP_Server_Info **psrvTcp){	struct list_head *tmp;	struct cifsSesInfo *ses;	*psrvTcp = NULL;	read_lock(&GlobalSMBSeslock);	list_for_each(tmp, &GlobalSMBSessionList) {		ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);		if (ses->server) {			if((target_ip_addr && 				(ses->server->addr.sockAddr.sin_addr.s_addr				  == target_ip_addr->s_addr)) || (target_ip6_addr				&& memcmp(&ses->server->addr.sockAddr6.sin6_addr,					target_ip6_addr,sizeof(*target_ip6_addr)))){				/* BB lock server and tcp session and increment use count here?? */				*psrvTcp = ses->server;	/* found a match on the TCP session */				/* BB check if reconnection needed */				if (strncmp				    (ses->userName, userName,				     MAX_USERNAME_SIZE) == 0){					read_unlock(&GlobalSMBSeslock);					return ses;	/* found exact match on both tcp and SMB sessions */				}			}		}		/* else tcp and smb sessions need reconnection */	}	read_unlock(&GlobalSMBSeslock);	return NULL;}static struct cifsTconInfo *find_unc(__be32 new_target_ip_addr, char *uncName, char *userName){	struct list_head *tmp;

⌨️ 快捷键说明

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