Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f2257b70 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  cifs: make sure we allocate enough storage for socket address
  [CIFS] Make socket retry timeouts consistent between blocking and nonblocking cases
  [CIFS] some cleanup to dir.c prior to addition of posix_open
  [CIFS] revalidate parent inode when rmdir done within that directory
  [CIFS] Rename md5 functions to avoid collision with new rt modules
  cifs: turn smb_send into a wrapper around smb_sendv
parents 1737ef75 a9ac49d3
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -5,7 +5,9 @@ rather than posix (advisory) byte range locks, even though server would
support posix byte range locks.  Fix query of root inode when prefixpath
specified and user does not have access to query information about the
top of the share.  Fix problem in 2.6.28 resolving DFS paths to
Samba servers (worked to Windows).
Samba servers (worked to Windows).  Fix rmdir so that pending search
(readdir) requests do not get invalid results which include the now
removed directory.

Version 1.55
------------
+9 −9
Original line number Diff line number Diff line
@@ -48,11 +48,11 @@ static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
	if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL))
		return -EINVAL;

	MD5Init(&context);
	MD5Update(&context, (char *)&key->data, key->len);
	MD5Update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
	cifs_MD5_init(&context);
	cifs_MD5_update(&context, (char *)&key->data, key->len);
	cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length);

	MD5Final(signature, &context);
	cifs_MD5_final(signature, &context);
	return 0;
}

@@ -96,8 +96,8 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
	if ((iov == NULL) || (signature == NULL) || (key == NULL))
		return -EINVAL;

	MD5Init(&context);
	MD5Update(&context, (char *)&key->data, key->len);
	cifs_MD5_init(&context);
	cifs_MD5_update(&context, (char *)&key->data, key->len);
	for (i = 0; i < n_vec; i++) {
		if (iov[i].iov_len == 0)
			continue;
@@ -110,13 +110,13 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
		if (i == 0) {
			if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
				break; /* nothing to sign or corrupt header */
			MD5Update(&context, iov[0].iov_base+4,
			cifs_MD5_update(&context, iov[0].iov_base+4,
				  iov[0].iov_len-4);
		} else
			MD5Update(&context, iov[i].iov_base, iov[i].iov_len);
			cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len);
	}

	MD5Final(signature, &context);
	cifs_MD5_final(signature, &context);

	return 0;
}
+2 −2
Original line number Diff line number Diff line
@@ -35,8 +35,8 @@ extern struct smb_hdr *cifs_buf_get(void);
extern void cifs_buf_release(void *);
extern struct smb_hdr *cifs_small_buf_get(void);
extern void cifs_small_buf_release(void *);
extern int smb_send(struct socket *, struct smb_hdr *,
			unsigned int /* length */ , struct sockaddr *, bool);
extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
			unsigned int /* length */);
extern unsigned int _GetXid(void);
extern void _FreeXid(unsigned int);
#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid()));
+11 −13
Original line number Diff line number Diff line
@@ -1354,7 +1354,7 @@ cifs_parse_mount_options(char *options, const char *devname,
}

static struct TCP_Server_Info *
cifs_find_tcp_session(struct sockaddr *addr)
cifs_find_tcp_session(struct sockaddr_storage *addr)
{
	struct list_head *tmp;
	struct TCP_Server_Info *server;
@@ -1374,11 +1374,11 @@ cifs_find_tcp_session(struct sockaddr *addr)
		if (server->tcpStatus == CifsNew)
			continue;

		if (addr->sa_family == AF_INET &&
		if (addr->ss_family == AF_INET &&
		    (addr4->sin_addr.s_addr !=
		     server->addr.sockAddr.sin_addr.s_addr))
			continue;
		else if (addr->sa_family == AF_INET6 &&
		else if (addr->ss_family == AF_INET6 &&
			 memcmp(&server->addr.sockAddr6.sin6_addr,
				&addr6->sin6_addr, sizeof(addr6->sin6_addr)))
			continue;
@@ -1419,12 +1419,12 @@ static struct TCP_Server_Info *
cifs_get_tcp_session(struct smb_vol *volume_info)
{
	struct TCP_Server_Info *tcp_ses = NULL;
	struct sockaddr addr;
	struct sockaddr_storage addr;
	struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
	struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
	int rc;

	memset(&addr, 0, sizeof(struct sockaddr));
	memset(&addr, 0, sizeof(struct sockaddr_storage));

	if (volume_info->UNCip && volume_info->UNC) {
		rc = cifs_inet_pton(AF_INET, volume_info->UNCip,
@@ -1435,9 +1435,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
			rc = cifs_inet_pton(AF_INET6, volume_info->UNCip,
					    &sin_server6->sin6_addr.in6_u);
			if (rc > 0)
				addr.sa_family = AF_INET6;
				addr.ss_family = AF_INET6;
		} else {
			addr.sa_family = AF_INET;
			addr.ss_family = AF_INET;
		}

		if (rc <= 0) {
@@ -1502,7 +1502,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
	tcp_ses->tcpStatus = CifsNew;
	++tcp_ses->srv_count;

	if (addr.sa_family == AF_INET6) {
	if (addr.ss_family == AF_INET6) {
		cFYI(1, ("attempting ipv6 connect"));
		/* BB should we allow ipv6 on port 139? */
		/* other OS never observed in Wild doing 139 with v6 */
@@ -1802,7 +1802,7 @@ ipv4_connect(struct TCP_Server_Info *server)
	 *  user space buffer
	 */
	socket->sk->sk_rcvtimeo = 7 * HZ;
	socket->sk->sk_sndtimeo = 3 * HZ;
	socket->sk->sk_sndtimeo = 5 * HZ;

	/* make the bufsizes depend on wsize/rsize and max requests */
	if (server->noautotune) {
@@ -1860,9 +1860,7 @@ ipv4_connect(struct TCP_Server_Info *server)
			smb_buf = (struct smb_hdr *)ses_init_buf;
			/* sizeof RFC1002_SESSION_REQUEST with no scope */
			smb_buf->smb_buf_length = 0x81000044;
			rc = smb_send(socket, smb_buf, 0x44,
				(struct sockaddr *) &server->addr.sockAddr,
				server->noblocksnd);
			rc = smb_send(server, smb_buf, 0x44);
			kfree(ses_init_buf);
			msleep(1); /* RFC1001 layer in at least one server
				      requires very short break before negprot
@@ -1955,7 +1953,7 @@ ipv6_connect(struct TCP_Server_Info *server)
	 * user space buffer
	 */
	socket->sk->sk_rcvtimeo = 7 * HZ;
	socket->sk->sk_sndtimeo = 3 * HZ;
	socket->sk->sk_sndtimeo = 5 * HZ;
	server->ssocket = socket;

	return rc;
+31 −25
Original line number Diff line number Diff line
@@ -129,6 +129,17 @@ build_path_from_dentry(struct dentry *direntry)
	return full_path;
}

static void setup_cifs_dentry(struct cifsTconInfo *tcon,
			      struct dentry *direntry,
			      struct inode *newinode)
{
	if (tcon->nocase)
		direntry->d_op = &cifs_ci_dentry_ops;
	else
		direntry->d_op = &cifs_dentry_ops;
	d_instantiate(direntry, newinode);
}

/* Inode operations in similar order to how they appear in Linux file fs.h */

int
@@ -139,14 +150,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
	int xid;
	int create_options = CREATE_NOT_DIR;
	int oplock = 0;
	/* BB below access is too much for the mknod to request */
	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
	__u16 fileHandle;
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *pTcon;
	struct cifsTconInfo *tcon;
	char *full_path = NULL;
	FILE_ALL_INFO *buf = NULL;
	struct inode *newinode = NULL;
	struct cifsFileInfo *pCifsFile = NULL;
	struct cifsInodeInfo *pCifsInode;
	int disposition = FILE_OVERWRITE_IF;
	bool write_only = false;
@@ -154,7 +165,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
	xid = GetXid();

	cifs_sb = CIFS_SB(inode->i_sb);
	pTcon = cifs_sb->tcon;
	tcon = cifs_sb->tcon;

	full_path = build_path_from_dentry(direntry);
	if (full_path == NULL) {
@@ -162,6 +173,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
		return -ENOMEM;
	}

	mode &= ~current->fs->umask;

	if (nd && (nd->flags & LOOKUP_OPEN)) {
		int oflags = nd->intent.open.flags;

@@ -196,17 +209,15 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
		return -ENOMEM;
	}

	mode &= ~current->fs->umask;

	/*
	 * if we're not using unix extensions, see if we need to set
	 * ATTR_READONLY on the create call
	 */
	if (!pTcon->unix_ext && (mode & S_IWUGO) == 0)
	if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
		create_options |= CREATE_OPTION_READONLY;

	if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
		rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
			 desiredAccess, create_options,
			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -215,7 +226,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,

	if (rc == -EIO) {
		/* old server, retry the open legacy style */
		rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
		rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
			desiredAccess, create_options,
			&fileHandle, &oplock, buf, cifs_sb->local_nls,
			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -225,7 +236,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
	} else {
		/* If Open reported that we actually created a file
		then we now have to set the mode if possible */
		if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
		if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
			struct cifs_unix_set_info_args args = {
				.mode	= mode,
				.ctime	= NO_CHANGE_64,
@@ -244,20 +255,20 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
				args.uid = NO_CHANGE_64;
				args.gid = NO_CHANGE_64;
			}
			CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
			CIFSSMBUnixSetInfo(xid, tcon, full_path, &args,
				cifs_sb->local_nls,
				cifs_sb->mnt_cifs_flags &
					CIFS_MOUNT_MAP_SPECIAL_CHR);
		} else {
			/* BB implement mode setting via Windows security
			   descriptors e.g. */
			/* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/
			/* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/

			/* Could set r/o dos attribute if mode & 0222 == 0 */
		}

		/* server might mask mode so we have to query for it */
		if (pTcon->unix_ext)
		if (tcon->unix_ext)
			rc = cifs_get_inode_info_unix(&newinode, full_path,
						 inode->i_sb, xid);
		else {
@@ -283,22 +294,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
		}

		if (rc != 0) {
			cFYI(1,
			     ("Create worked but get_inode_info failed rc = %d",
			cFYI(1, ("Create worked, get_inode_info failed rc = %d",
				 rc));
		} else {
			if (pTcon->nocase)
				direntry->d_op = &cifs_ci_dentry_ops;
			else
				direntry->d_op = &cifs_dentry_ops;
			d_instantiate(direntry, newinode);
		}
		} else
			setup_cifs_dentry(tcon, direntry, newinode);

		if ((nd == NULL /* nfsd case - nfs srv does not set nd */) ||
			(!(nd->flags & LOOKUP_OPEN))) {
			/* mknod case - do not leave file open */
			CIFSSMBClose(xid, pTcon, fileHandle);
			CIFSSMBClose(xid, tcon, fileHandle);
		} else if (newinode) {
			pCifsFile =
			struct cifsFileInfo *pCifsFile =
			   kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);

			if (pCifsFile == NULL)
@@ -316,7 +322,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
			/* set the following in open now
				pCifsFile->pfile = file; */
			write_lock(&GlobalSMBSeslock);
			list_add(&pCifsFile->tlist, &pTcon->openFileList);
			list_add(&pCifsFile->tlist, &tcon->openFileList);
			pCifsInode = CIFS_I(newinode);
			if (pCifsInode) {
				/* if readable file instance put first in list*/
Loading