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

📄 proc.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
 */static intsmb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,			struct smb_fattr *fattr){	char *param = server->temp_buf, *mask = param + 12;	__u16 date, time;	unsigned char *resp_data = NULL;	unsigned char *resp_param = NULL;	int resp_data_len = 0;	int resp_param_len = 0;	int mask_len, result;retry:	mask_len = smb_encode_path(server, mask, SMB_MAXNAMELEN+1, dentry, NULL);	if (mask_len < 0) {		result = mask_len;		goto out;	}	VERBOSE("name=%s, len=%d\n", mask, mask_len);	WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);	WSET(param, 2, 1);	/* max count */	WSET(param, 4, 1);	/* close after this call */	WSET(param, 6, 1);	/* info_level */	DSET(param, 8, 0);	result = smb_trans2_request(server, TRANSACT2_FINDFIRST,				    0, NULL, 12 + mask_len, param,				    &resp_data_len, &resp_data,				    &resp_param_len, &resp_param);	if (result < 0)	{		if (smb_retry(server))			goto retry;		goto out;	}	if (server->rcls != 0)	{ 		result = smb_errno(server);#ifdef SMBFS_PARANOIA		if (result != -ENOENT)			PARANOIA("error for %s, rcls=%d, err=%d\n",				 mask, server->rcls, server->err);#endif		goto out;	}	/* Make sure we got enough data ... */	result = -EINVAL;	if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)	{		PARANOIA("bad result for %s, len=%d, count=%d\n",			 mask, resp_data_len, WVAL(resp_param, 2));		goto out;	}	/*	 * Decode the response into the fattr ...	 */	date = WVAL(resp_data, 0);	time = WVAL(resp_data, 2);	fattr->f_ctime = date_dos2unix(server, date, time);	date = WVAL(resp_data, 4);	time = WVAL(resp_data, 6);	fattr->f_atime = date_dos2unix(server, date, time);	date = WVAL(resp_data, 8);	time = WVAL(resp_data, 10);	fattr->f_mtime = date_dos2unix(server, date, time);	VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n",		mask, date, time, fattr->f_mtime);	fattr->f_size = DVAL(resp_data, 12);	/* ULONG allocation size */	fattr->attr = WVAL(resp_data, 20);	result = 0;out:	return result;}/* * Note: called with the server locked. */static intsmb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,		      struct smb_fattr *fattr){	int result;	char *p;      retry:	p = smb_setup_header(server, SMBgetatr, 0, 0);	result = smb_simple_encode_path(server, &p, dir, NULL);	if (result < 0)		goto out;	smb_setup_bcc(server, p);	if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)	{		if (smb_retry(server))			goto retry;		goto out;	}	fattr->attr    = WVAL(server->packet, smb_vwv0);	fattr->f_mtime = local2utc(server, DVAL(server->packet, smb_vwv1));	fattr->f_size  = DVAL(server->packet, smb_vwv3);	fattr->f_ctime = fattr->f_mtime; 	fattr->f_atime = fattr->f_mtime; #ifdef SMBFS_DEBUG_TIMESTAMP	printk("getattr_core: %s/%s, mtime=%ld\n",	       DENTRY_PATH(dir), fattr->f_mtime);#endif	result = 0;out:	return result;}/* * Note: called with the server locked. * * Bugs Noted: * (1) Win 95 swaps the date and time fields in the standard info level. */static intsmb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,			struct smb_fattr *attr){	char *p, *param = server->temp_buf;	__u16 date, time;	int off_date = 0, off_time = 2;	unsigned char *resp_data = NULL;	unsigned char *resp_param = NULL;	int resp_data_len = 0;	int resp_param_len = 0;	int result;      retry:	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */	DSET(param, 2, 0);	result = smb_encode_path(server, param+6, SMB_MAXNAMELEN+1, dir, NULL);	if (result < 0)		goto out;	p = param + 6 + result;	result = smb_trans2_request(server, TRANSACT2_QPATHINFO,				    0, NULL, p - param, param,				    &resp_data_len, &resp_data,				    &resp_param_len, &resp_param);	if (result < 0)	{		if (smb_retry(server))			goto retry;		goto out;	}	if (server->rcls != 0)	{		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",			&param[6], result, server->rcls, server->err);		result = smb_errno(server);		goto out;	}	result = -ENOENT;	if (resp_data_len < 22)	{		PARANOIA("not enough data for %s, len=%d\n",			 &param[6], resp_data_len);		goto out;	}	/*	 * Kludge alert: Win 95 swaps the date and time field,	 * contrary to the CIFS docs and Win NT practice.	 */	if (server->mnt->flags & SMB_MOUNT_WIN95) {		off_date = 2;		off_time = 0;	}	date = WVAL(resp_data, off_date);	time = WVAL(resp_data, off_time);	attr->f_ctime = date_dos2unix(server, date, time);	date = WVAL(resp_data, 4 + off_date);	time = WVAL(resp_data, 4 + off_time);	attr->f_atime = date_dos2unix(server, date, time);	date = WVAL(resp_data, 8 + off_date);	time = WVAL(resp_data, 8 + off_time);	attr->f_mtime = date_dos2unix(server, date, time);#ifdef SMBFS_DEBUG_TIMESTAMP	printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",	       DENTRY_PATH(dir), date, time, attr->f_mtime);#endif	attr->f_size = DVAL(resp_data, 12);	attr->attr = WVAL(resp_data, 20);	result = 0;out:	return result;}/* * Note: called with the server locked */static intsmb_proc_do_getattr(struct smb_sb_info *server, struct dentry *dir,		    struct smb_fattr *fattr){	int result;	struct inode *inode = dir->d_inode;	smb_init_dirent(server, fattr);	/*	 * Select whether to use core or trans2 getattr.	 * Win 95 appears to break with the trans2 getattr. 	 */	if (server->opt.protocol < SMB_PROTOCOL_LANMAN2 ||	    (server->mnt->flags & (SMB_MOUNT_OLDATTR|SMB_MOUNT_WIN95)) ) {		result = smb_proc_getattr_core(server, dir, fattr);	} else {		if (server->mnt->flags & SMB_MOUNT_DIRATTR)			result = smb_proc_getattr_ff(server, dir, fattr);		else			result = smb_proc_getattr_trans2(server, dir, fattr);	}	/*	 * None of the getattr versions here can make win9x return the right	 * filesize if there are changes made to an open file.	 * A seek-to-end does return the right size, but we only need to do	 * that on files we have written.	 */	if (server->mnt->flags & SMB_MOUNT_WIN95 &&	    inode &&	    inode->u.smbfs_i.flags & SMB_F_LOCALWRITE &&	    smb_is_open(inode))	{		__u16 fileid = inode->u.smbfs_i.fileid;		fattr->f_size = smb_proc_seek(server, fileid, 2, 0);	}	smb_finish_dirent(server, fattr);	return result;}intsmb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr){	struct smb_sb_info *server = server_from_dentry(dir);	int result;	smb_lock_server(server);	result = smb_proc_do_getattr(server, dir, fattr);	smb_unlock_server(server);	return result;}/* * Called with the server locked. Because of bugs in the * core protocol, we use this only to set attributes. See * smb_proc_settime() below for timestamp handling. * * Bugs Noted: * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail * with an undocumented error (ERRDOS code 50). Setting * mtime to 0 allows the attributes to be set. * (2) The extra parameters following the name string aren't * in the CIFS docs, but seem to be necessary for operation. */static intsmb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,		      __u16 attr){	char *p;	int result;      retry:	p = smb_setup_header(server, SMBsetatr, 8, 0);	WSET(server->packet, smb_vwv0, attr);	DSET(server->packet, smb_vwv1, 0); /* mtime */	WSET(server->packet, smb_vwv3, 0); /* reserved values */	WSET(server->packet, smb_vwv4, 0);	WSET(server->packet, smb_vwv5, 0);	WSET(server->packet, smb_vwv6, 0);	WSET(server->packet, smb_vwv7, 0);	result = smb_simple_encode_path(server, &p, dentry, NULL);	if (result < 0)		goto out;	if (p + 2 > (char *)server->packet + server->packet_size) {		result = -ENAMETOOLONG;		goto out;	}	*p++ = 4;	*p++ = 0;	smb_setup_bcc(server, p);	result = smb_request_ok(server, SMBsetatr, 0, 0);	if (result < 0) {		if (smb_retry(server))			goto retry;		goto out;	}	result = 0;out:	return result;}/* * Because of bugs in the trans2 setattr messages, we must set * attributes and timestamps separately. The core SMBsetatr * message seems to be the only reliable way to set attributes. */intsmb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr){	struct smb_sb_info *server = server_from_dentry(dir);	int result;	VERBOSE("setting %s/%s, open=%d\n", 		DENTRY_PATH(dir), smb_is_open(dir->d_inode));	smb_lock_server(server);	result = smb_proc_setattr_core(server, dir, fattr->attr);	smb_unlock_server(server);	return result;}/* * Called with the server locked. Sets the timestamps for an * file open with write permissions. */static intsmb_proc_setattr_ext(struct smb_sb_info *server,		      struct inode *inode, struct smb_fattr *fattr){	__u16 date, time;	int result;      retry:	smb_setup_header(server, SMBsetattrE, 7, 0);	WSET(server->packet, smb_vwv0, inode->u.smbfs_i.fileid);	/* We don't change the creation time */	WSET(server->packet, smb_vwv1, 0);	WSET(server->packet, smb_vwv2, 0);	date_unix2dos(server, fattr->f_atime, &date, &time);	WSET(server->packet, smb_vwv3, date);	WSET(server->packet, smb_vwv4, time);	date_unix2dos(server, fattr->f_mtime, &date, &time);	WSET(server->packet, smb_vwv5, date);	WSET(server->packet, smb_vwv6, time);#ifdef SMBFS_DEBUG_TIMESTAMP	printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n",	       date, time, fattr->f_mtime);#endif	result = smb_request_ok(server, SMBsetattrE, 0, 0);	if (result < 0) {		if (smb_retry(server))			goto retry;		goto out;	}	result = 0;out:	return result;}/* * Note: called with the server locked. * * Bugs Noted: * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't * set the file's attribute flags. */static intsmb_proc_setattr_trans2(struct smb_sb_info *server,			struct dentry *dir, struct smb_fattr *fattr){	__u16 date, time;	char *p, *param = server->temp_buf;	unsigned char *resp_data = NULL;	unsigned char *resp_param = NULL;	int resp_data_len = 0;	int resp_param_len = 0;	int result;	char data[26];      retry:	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */	DSET(param, 2, 0);	result = smb_encode_path(server, param+6, SMB_MAXNAMELEN+1, dir, NULL);	if (result < 0)		goto out;	p = param + 6 + result;	WSET(data, 0, 0); /* creation time */	WSET(data, 2, 0);	date_unix2dos(server, fattr->f_atime, &date, &time);	WSET(data, 4, date);	WSET(data, 6, time);	date_unix2dos(server, fattr->f_mtime, &date, &time);	WSET(data, 8, date);	WSET(data, 10, time);#ifdef SMBFS_DEBUG_TIMESTAMP	printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 	       DENTRY_PATH(dir), date, time, fattr->f_mtime);#endif	DSET(data, 12, 0); /* size */	DSET(data, 16, 0); /* blksize */	WSET(data, 20, 0); /* attr */	DSET(data, 22, 0); /* ULONG EA size */	result = smb_trans2_request(server, TRANSACT2_SETPATHINFO,				    26, data, p - param, param,				    &resp_data_len, &resp_data,				    &resp_param_len, &resp_param);	if (result < 0)	{		if (smb_retry(server))			goto retry;		goto out;	}	result = 0;	if (server->rcls != 0)		result = smb_errno(server);out:	return result;}/* * Set the modify and access timestamps for a file. * * Incredibly enough, in all of SMB there is no message to allow * setting both attributes and timestamps at once.  * * Bugs Noted: * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message  * with info level 1 (INFO_STANDARD). * (2) Win 95 seems not to support setting directory timestamps. * (3) Under the core protocol apparently the only way to set the * timestamp is to open and close the file. */intsmb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr){	struct smb_sb_info *server = server_from_dentry(dentry);	struct inode *inode = dentry->d_inode;	int result;	VERBOSE("setting %s/%s, open=%d\n",		DENTRY_PATH(dentry), smb_is_open(inode));	smb_lock_server(server);	/* setting the time on a Win95 server fails (tridge) */	if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && 	    !(server->mnt->flags & SMB_MOUNT_WIN95)) {		if (smb_is_open(inode) &&		    inode->u.smbfs_i.access != SMB_O_RDONLY)			result = smb_proc_setattr_ext(server, inode, fattr);		else			result = smb_proc_setattr_trans2(server, dentry, fattr);	} else {		/*		 * Fail silently on directories ... timestamp can't be set?		 */		result = 0;		if (S_ISREG(inode->i_mode)) {			/*			 * Set the mtime by opening and closing the file.			 * Note that the file is opened read-only, but this			 * still allows us to set the date (tridge)			 */			result = -EACCES;			if (!smb_is_open(inode))				smb_proc_open(server, dentry, SMB_O_RDONLY);			if (smb_is_open(inode)) {				inode->i_mtime = fattr->f_mtime;				result = smb_proc_close_inode(server, inode);			}		}	}	smb_unlock_server(server);	return result;}intsmb_proc_dskattr(struct super_block *sb, struct statfs *attr){	struct smb_sb_info *server = &(sb->u.smbfs_sb);	int result;	char *p;	long unit;	smb_lock_server(server);      retry:	smb_setup_header(server, SMBdskattr, 0, 0);	if ((result = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {		if (smb_retry(server))			goto retry;		goto out;	}	p = SMB_VWV(server->packet);	unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT;	attr->f_blocks = WVAL(p, 0) * unit;	attr->f_bsize  = SMB_ST_BLKSIZE;	attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit;	result = 0;out:	smb_unlock_server(server);	return result;}

⌨️ 快捷键说明

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