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

Commit 1dbd6608 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'linus' into x86/urgent

parents 5aaca7a7 c714a534
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -340,6 +340,7 @@
#define OPEN_NO_RECALL          0x00400000
#define OPEN_FREE_SPACE_QUERY   0x00800000	/* should be zero */
#define CREATE_OPTIONS_MASK     0x007FFFFF
#define CREATE_OPTION_READONLY	0x10000000
#define CREATE_OPTION_SPECIAL   0x20000000   /* system. NB not sent over wire */

/* ImpersonationLevel flags */
+6 −10
Original line number Diff line number Diff line
@@ -1224,11 +1224,8 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
	else /* BB FIXME BB */
		pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);

	/* if ((omode & S_IWUGO) == 0)
		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
	/*  Above line causes problems due to vfs splitting create into two
	    pieces - need to set mode after file created not while it is
	    being created */
	if (create_options & CREATE_OPTION_READONLY)
		pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);

	/* BB FIXME BB */
/*	pSMB->CreateOptions = cpu_to_le32(create_options &
@@ -1331,17 +1328,16 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
		pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
	else
		pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);

	/* XP does not handle ATTR_POSIX_SEMANTICS */
	/* but it helps speed up case sensitive checks for other
	servers such as Samba */
	if (tcon->ses->capabilities & CAP_UNIX)
		pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);

	/* if ((omode & S_IWUGO) == 0)
		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
	/*  Above line causes problems due to vfs splitting create into two
		pieces - need to set mode after file created not while it is
		being created */
	if (create_options & CREATE_OPTION_READONLY)
		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);

	pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
	pSMB->CreateDisposition = cpu_to_le32(openDisposition);
	pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
+40 −39
Original line number Diff line number Diff line
@@ -348,7 +348,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
	int reconnect;

	current->flags |= PF_MEMALLOC;
	server->tsk = current;	/* save process info to wake at shutdown */
	cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
	write_lock(&GlobalSMBSeslock);
	atomic_inc(&tcpSesAllocCount);
@@ -651,10 +650,20 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)

	spin_lock(&GlobalMid_Lock);
	server->tcpStatus = CifsExiting;
	server->tsk = NULL;
	spin_unlock(&GlobalMid_Lock);

	/* don't exit until kthread_stop is called */
	set_current_state(TASK_UNINTERRUPTIBLE);
	while (!kthread_should_stop()) {
		schedule();
		set_current_state(TASK_UNINTERRUPTIBLE);
	}
	set_current_state(TASK_RUNNING);

	/* check if we have blocked requests that need to free */
	/* Note that cifs_max_pending is normally 50, but
	can be set at module install time to as little as two */
	spin_lock(&GlobalMid_Lock);
	if (atomic_read(&server->inFlight) >= cifs_max_pending)
		atomic_set(&server->inFlight, cifs_max_pending - 1);
	/* We do not want to set the max_pending too low or we
@@ -1323,37 +1332,38 @@ cifs_find_tcp_session(struct in_addr *target_ip_addr,
{
	struct list_head *tmp;
	struct cifsSesInfo *ses;

	*psrvTcp = NULL;
	read_lock(&GlobalSMBSeslock);

	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?? */
		if (!ses->server)
			continue;

		if (target_ip_addr &&
		    ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
				continue;
		else if (target_ip6_addr &&
			 memcmp(&ses->server->addr.sockAddr6.sin6_addr,
				target_ip6_addr, sizeof(*target_ip6_addr)))
				continue;
		/* BB lock server and tcp session; increment use count here?? */

		/* found a match on the TCP session */
		*psrvTcp = ses->server;

		/* BB check if reconnection needed */
				if (strncmp
				    (ses->userName, userName,
				     MAX_USERNAME_SIZE) == 0){
		if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
			read_unlock(&GlobalSMBSeslock);
			/* Found exact match on both TCP and
			   SMB sessions */
			return ses;
		}
			}
		}
		/* else tcp and smb sessions need reconnection */
	}
	read_unlock(&GlobalSMBSeslock);

	return NULL;
}

@@ -2186,15 +2196,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
			srvTcp->tcpStatus = CifsExiting;
			spin_unlock(&GlobalMid_Lock);
			if (srvTcp->tsk) {
				struct task_struct *tsk;
				/* If we could verify that kthread_stop would
				   always wake up processes blocked in
				   tcp in recv_mesg then we could remove the
				   send_sig call */
				force_sig(SIGKILL, srvTcp->tsk);
				tsk = srvTcp->tsk;
				if (tsk)
					kthread_stop(tsk);
				kthread_stop(srvTcp->tsk);
			}
		}
		 /* If find_unc succeeded then rc == 0 so we can not end */
@@ -2210,23 +2217,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
					if ((temp_rc == -ESHUTDOWN) &&
					    (pSesInfo->server) &&
					    (pSesInfo->server->tsk)) {
						struct task_struct *tsk;
						force_sig(SIGKILL,
							pSesInfo->server->tsk);
						tsk = pSesInfo->server->tsk;
						if (tsk)
							kthread_stop(tsk);
						kthread_stop(pSesInfo->server->tsk);
					}
				} else {
					cFYI(1, ("No session or bad tcon"));
					if ((pSesInfo->server) &&
					    (pSesInfo->server->tsk)) {
						struct task_struct *tsk;
						force_sig(SIGKILL,
							pSesInfo->server->tsk);
						tsk = pSesInfo->server->tsk;
						if (tsk)
							kthread_stop(tsk);
						kthread_stop(pSesInfo->server->tsk);
					}
				}
				sesInfoFree(pSesInfo);
+13 −3
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
{
	int rc = -ENOENT;
	int xid;
	int create_options = CREATE_NOT_DIR;
	int oplock = 0;
	int desiredAccess = GENERIC_READ | GENERIC_WRITE;
	__u16 fileHandle;
@@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
		FreeXid(xid);
		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)
		create_options |= CREATE_OPTION_READONLY;

	if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
		rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
			 desiredAccess, CREATE_NOT_DIR,
			 desiredAccess, create_options,
			 &fileHandle, &oplock, buf, cifs_sb->local_nls,
			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
	else
@@ -187,7 +198,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,
			desiredAccess, CREATE_NOT_DIR,
			desiredAccess, create_options,
			&fileHandle, &oplock, buf, cifs_sb->local_nls,
			cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
	}
@@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
		/* 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)) {
			mode &= ~current->fs->umask;
			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
				CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
					(__u64)current->fsuid,
+21 −14
Original line number Diff line number Diff line
@@ -974,8 +974,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
		  * failed to get it from the server or was set bogus */
		if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
				direntry->d_inode->i_nlink = 2;
		if (pTcon->unix_ext) {
		mode &= ~current->fs->umask;
		if (pTcon->unix_ext) {
			if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
				CIFSSMBUnixSetPerms(xid, pTcon, full_path,
						    mode,
@@ -994,9 +994,16 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
						    CIFS_MOUNT_MAP_SPECIAL_CHR);
			}
		} else {
			/* BB to be implemented via Windows secrty descriptors
			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
						 -1, -1, local_nls); */
			if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
			    (mode & S_IWUGO) == 0) {
				FILE_BASIC_INFO pInfo;
				memset(&pInfo, 0, sizeof(pInfo));
				pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
				CIFSSMBSetTimes(xid, pTcon, full_path,
						&pInfo, cifs_sb->local_nls,
						cifs_sb->mnt_cifs_flags &
						CIFS_MOUNT_MAP_SPECIAL_CHR);
			}
			if (direntry->d_inode) {
				direntry->d_inode->i_mode = mode;
				direntry->d_inode->i_mode |= S_IFDIR;
@@ -1408,18 +1415,19 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
	__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
	struct cifsInodeInfo *cifsInode;
	struct inode *inode = direntry->d_inode;

	xid = GetXid();

	cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
		 direntry->d_name.name, attrs->ia_valid));

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

	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
		/* check if we have permission to change attrs */
		rc = inode_change_ok(direntry->d_inode, attrs);
		rc = inode_change_ok(inode, attrs);
		if (rc < 0) {
			FreeXid(xid);
			return rc;
@@ -1432,7 +1440,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
		FreeXid(xid);
		return -ENOMEM;
	}
	cifsInode = CIFS_I(direntry->d_inode);
	cifsInode = CIFS_I(inode);

	if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
		/*
@@ -1443,9 +1451,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
		   will be truncated anyway? Also, should we error out here if
		   the flush returns error?
		 */
		rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
		rc = filemap_write_and_wait(inode->i_mapping);
		if (rc != 0) {
			CIFS_I(direntry->d_inode)->write_behind_rc = rc;
			cifsInode->write_behind_rc = rc;
			rc = 0;
		}
	}
@@ -1521,9 +1529,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
		   */

		if (rc == 0) {
			rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
			cifs_truncate_page(direntry->d_inode->i_mapping,
					   direntry->d_inode->i_size);
			rc = cifs_vmtruncate(inode, attrs->ia_size);
			cifs_truncate_page(inode->i_mapping, inode->i_size);
		} else
			goto cifs_setattr_exit;
	}
@@ -1557,7 +1564,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
		rc = 0;
#ifdef CONFIG_CIFS_EXPERIMENTAL
		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
			rc = mode_to_acl(direntry->d_inode, full_path, mode);
			rc = mode_to_acl(inode, full_path, mode);
		else if ((mode & S_IWUGO) == 0) {
#else
		if ((mode & S_IWUGO) == 0) {
@@ -1665,7 +1672,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
	/* do not need local check to inode_check_ok since the server does
	   that */
	if (!rc)
		rc = inode_setattr(direntry->d_inode, attrs);
		rc = inode_setattr(inode, attrs);
cifs_setattr_exit:
	kfree(full_path);
	FreeXid(xid);
Loading