diff options
Diffstat (limited to 'fs/cifs/file.c')
| -rw-r--r-- | fs/cifs/file.c | 33 | 
1 files changed, 17 insertions, 16 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 4b95700c507c..5ad15de2bb4f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -253,6 +253,12 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,  		rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,  					 xid, fid); +	if (rc) { +		server->ops->close(xid, tcon, fid); +		if (rc == -ESTALE) +			rc = -EOPENSTALE; +	} +  out:  	kfree(buf);  	return rc; @@ -1840,13 +1846,12 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,  {  	struct cifsFileInfo *open_file = NULL;  	struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); -	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);  	/* only filter by fsuid on multiuser mounts */  	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))  		fsuid_only = false; -	spin_lock(&tcon->open_file_lock); +	spin_lock(&cifs_inode->open_file_lock);  	/* we could simply get the first_list_entry since write-only entries  	   are always at the end of the list but since the first entry might  	   have a close pending, we go through the whole list */ @@ -1858,7 +1863,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,  				/* found a good file */  				/* lock it so it will not be closed on us */  				cifsFileInfo_get(open_file); -				spin_unlock(&tcon->open_file_lock); +				spin_unlock(&cifs_inode->open_file_lock);  				return open_file;  			} /* else might as well continue, and look for  			     another, or simply have the caller reopen it @@ -1866,7 +1871,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,  		} else /* write only file */  			break; /* write only files are last so must be done */  	} -	spin_unlock(&tcon->open_file_lock); +	spin_unlock(&cifs_inode->open_file_lock);  	return NULL;  } @@ -1877,7 +1882,6 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,  {  	struct cifsFileInfo *open_file, *inv_file = NULL;  	struct cifs_sb_info *cifs_sb; -	struct cifs_tcon *tcon;  	bool any_available = false;  	int rc = -EBADF;  	unsigned int refind = 0; @@ -1897,16 +1901,15 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,  	}  	cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); -	tcon = cifs_sb_master_tcon(cifs_sb);  	/* only filter by fsuid on multiuser mounts */  	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))  		fsuid_only = false; -	spin_lock(&tcon->open_file_lock); +	spin_lock(&cifs_inode->open_file_lock);  refind_writable:  	if (refind > MAX_REOPEN_ATT) { -		spin_unlock(&tcon->open_file_lock); +		spin_unlock(&cifs_inode->open_file_lock);  		return rc;  	}  	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { @@ -1918,7 +1921,7 @@ refind_writable:  			if (!open_file->invalidHandle) {  				/* found a good writable file */  				cifsFileInfo_get(open_file); -				spin_unlock(&tcon->open_file_lock); +				spin_unlock(&cifs_inode->open_file_lock);  				*ret_file = open_file;  				return 0;  			} else { @@ -1938,7 +1941,7 @@ refind_writable:  		cifsFileInfo_get(inv_file);  	} -	spin_unlock(&tcon->open_file_lock); +	spin_unlock(&cifs_inode->open_file_lock);  	if (inv_file) {  		rc = cifs_reopen_file(inv_file, false); @@ -1953,7 +1956,7 @@ refind_writable:  		cifsFileInfo_put(inv_file);  		++refind;  		inv_file = NULL; -		spin_lock(&tcon->open_file_lock); +		spin_lock(&cifs_inode->open_file_lock);  		goto refind_writable;  	} @@ -4461,17 +4464,15 @@ static int cifs_readpage(struct file *file, struct page *page)  static int is_inode_writable(struct cifsInodeInfo *cifs_inode)  {  	struct cifsFileInfo *open_file; -	struct cifs_tcon *tcon = -		cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb)); -	spin_lock(&tcon->open_file_lock); +	spin_lock(&cifs_inode->open_file_lock);  	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {  		if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { -			spin_unlock(&tcon->open_file_lock); +			spin_unlock(&cifs_inode->open_file_lock);  			return 1;  		}  	} -	spin_unlock(&tcon->open_file_lock); +	spin_unlock(&cifs_inode->open_file_lock);  	return 0;  }  | 
