five small cifs/smb3 fixes, two for stable
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAl5dnvEACgkQiiy9cAdy T1FaWAv/XnyYfYh6H4fhtgtfNxW9xt9mkHo/AohHcf2rk2erqjVz0lHVe7SuS9C5 EpDYnijZKa//aiIV6VzDymPaMrXQZ+oCAExAzLPmWZnLeZ65Q02K2P1F3KvURdue 4nLjuOyzyG4YYkoBi4wKneu1Ji377m9L6BpSfM+MzPScCOl8OV/vv/nBRY1N6gIY Rreq5iipRaDhifsaOgiA501sUu7mvpPEHNpluCtFmY4iTHQzYqjWZ5ZGXr2xz63n 5VV8KWWn/p3nhJGt7L/1aynws59AdEd5GNZ5FbDQHokx9n3MMnyl4QGDzUehnhlY Ym6n50QA5QMn9I9NLg8I2aD6z4vNIj9kZxersoHduf4UsA9CyPaucUIyV81mt683 AZIqtz8H21fgJXOQ3nv4uNc8Yyt1SGQfFDo1EfphwLl6LaE8rx3CFEnVoNLM+jqb nyRB/NxLtDWVQhYM8Bg/TP7iMqknHtarfZirv48LFdXLlhb83+qpSSHy0zVy9vli y/0B7rEI =zLW4 -----END PGP SIGNATURE----- Merge tag '5.6-rc4-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull cifs fixes from Steve French: "Five small cifs/smb3 fixes, two for stable (one for a reconnect problem and the other fixes a use case when renaming an open file)" * tag '5.6-rc4-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: Use #define in cifs_dbg cifs: fix rename() by ensuring source handle opened with DELETE bit cifs: add missing mount option to /proc/mounts cifs: fix potential mismatch of UNC paths cifs: don't leak -EAGAIN for stat() during reconnect
This commit is contained in:
commit
8b614cb8f1
11 changed files with 44 additions and 20 deletions
|
@ -324,6 +324,8 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
|
|||
if (full_path == NULL)
|
||||
goto cdda_exit;
|
||||
|
||||
convert_delimiter(full_path, '\\');
|
||||
|
||||
cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path);
|
||||
|
||||
if (!cifs_sb_master_tlink(cifs_sb)) {
|
||||
|
|
|
@ -530,6 +530,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
|||
|
||||
if (tcon->seal)
|
||||
seq_puts(s, ",seal");
|
||||
else if (tcon->ses->server->ignore_signature)
|
||||
seq_puts(s, ",signloosely");
|
||||
if (tcon->nocase)
|
||||
seq_puts(s, ",nocase");
|
||||
if (tcon->local_lease)
|
||||
|
|
|
@ -1281,6 +1281,7 @@ struct cifs_fid {
|
|||
__u64 volatile_fid; /* volatile file id for smb2 */
|
||||
__u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for smb2 */
|
||||
__u8 create_guid[16];
|
||||
__u32 access;
|
||||
struct cifs_pending_open *pending_open;
|
||||
unsigned int epoch;
|
||||
#ifdef CONFIG_CIFS_DEBUG2
|
||||
|
@ -1741,6 +1742,12 @@ static inline bool is_retryable_error(int error)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* cifs_get_writable_file() flags */
|
||||
#define FIND_WR_ANY 0
|
||||
#define FIND_WR_FSUID_ONLY 1
|
||||
#define FIND_WR_WITH_DELETE 2
|
||||
|
||||
#define MID_FREE 0
|
||||
#define MID_REQUEST_ALLOCATED 1
|
||||
#define MID_REQUEST_SUBMITTED 2
|
||||
|
|
|
@ -134,11 +134,12 @@ extern bool backup_cred(struct cifs_sb_info *);
|
|||
extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
|
||||
extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
|
||||
unsigned int bytes_written);
|
||||
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
|
||||
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
|
||||
extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
|
||||
bool fsuid_only,
|
||||
int flags,
|
||||
struct cifsFileInfo **ret_file);
|
||||
extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
|
||||
int flags,
|
||||
struct cifsFileInfo **ret_file);
|
||||
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
|
||||
extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
|
||||
|
|
|
@ -1492,6 +1492,7 @@ openRetry:
|
|||
*oplock = rsp->OplockLevel;
|
||||
/* cifs fid stays in le */
|
||||
oparms->fid->netfid = rsp->Fid;
|
||||
oparms->fid->access = desired_access;
|
||||
|
||||
/* Let caller know file was created so we can set the mode. */
|
||||
/* Do we care about the CreateAction in any other cases? */
|
||||
|
@ -2115,7 +2116,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
|
|||
wdata2->tailsz = tailsz;
|
||||
wdata2->bytes = cur_len;
|
||||
|
||||
rc = cifs_get_writable_file(CIFS_I(inode), false,
|
||||
rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
|
||||
&wdata2->cfile);
|
||||
if (!wdata2->cfile) {
|
||||
cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
|
||||
|
|
|
@ -1958,7 +1958,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
|
|||
|
||||
/* Return -EBADF if no handle is found and general rc otherwise */
|
||||
int
|
||||
cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
|
||||
cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags,
|
||||
struct cifsFileInfo **ret_file)
|
||||
{
|
||||
struct cifsFileInfo *open_file, *inv_file = NULL;
|
||||
|
@ -1966,7 +1966,8 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
|
|||
bool any_available = false;
|
||||
int rc = -EBADF;
|
||||
unsigned int refind = 0;
|
||||
|
||||
bool fsuid_only = flags & FIND_WR_FSUID_ONLY;
|
||||
bool with_delete = flags & FIND_WR_WITH_DELETE;
|
||||
*ret_file = NULL;
|
||||
|
||||
/*
|
||||
|
@ -1998,6 +1999,8 @@ refind_writable:
|
|||
continue;
|
||||
if (fsuid_only && !uid_eq(open_file->uid, current_fsuid()))
|
||||
continue;
|
||||
if (with_delete && !(open_file->fid.access & DELETE))
|
||||
continue;
|
||||
if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
|
||||
if (!open_file->invalidHandle) {
|
||||
/* found a good writable file */
|
||||
|
@ -2045,12 +2048,12 @@ refind_writable:
|
|||
}
|
||||
|
||||
struct cifsFileInfo *
|
||||
find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only)
|
||||
find_writable_file(struct cifsInodeInfo *cifs_inode, int flags)
|
||||
{
|
||||
struct cifsFileInfo *cfile;
|
||||
int rc;
|
||||
|
||||
rc = cifs_get_writable_file(cifs_inode, fsuid_only, &cfile);
|
||||
rc = cifs_get_writable_file(cifs_inode, flags, &cfile);
|
||||
if (rc)
|
||||
cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc);
|
||||
|
||||
|
@ -2059,6 +2062,7 @@ find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only)
|
|||
|
||||
int
|
||||
cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
|
||||
int flags,
|
||||
struct cifsFileInfo **ret_file)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
|
@ -2085,7 +2089,7 @@ cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
|
|||
kfree(full_path);
|
||||
cinode = CIFS_I(d_inode(cfile->dentry));
|
||||
spin_unlock(&tcon->open_file_lock);
|
||||
return cifs_get_writable_file(cinode, 0, ret_file);
|
||||
return cifs_get_writable_file(cinode, flags, ret_file);
|
||||
}
|
||||
|
||||
spin_unlock(&tcon->open_file_lock);
|
||||
|
@ -2162,7 +2166,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
|
|||
if (mapping->host->i_size - offset < (loff_t)to)
|
||||
to = (unsigned)(mapping->host->i_size - offset);
|
||||
|
||||
rc = cifs_get_writable_file(CIFS_I(mapping->host), false, &open_file);
|
||||
rc = cifs_get_writable_file(CIFS_I(mapping->host), FIND_WR_ANY,
|
||||
&open_file);
|
||||
if (!rc) {
|
||||
bytes_written = cifs_write(open_file, open_file->pid,
|
||||
write_data, to - from, &offset);
|
||||
|
@ -2355,7 +2360,7 @@ retry:
|
|||
if (cfile)
|
||||
cifsFileInfo_put(cfile);
|
||||
|
||||
rc = cifs_get_writable_file(CIFS_I(inode), false, &cfile);
|
||||
rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile);
|
||||
|
||||
/* in case of an error store it to return later */
|
||||
if (rc)
|
||||
|
|
|
@ -653,8 +653,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
|
|||
*/
|
||||
if ((fattr->cf_nlink < 1) && !tcon->unix_ext &&
|
||||
!info->DeletePending) {
|
||||
cifs_dbg(1, "bogus file nlink value %u\n",
|
||||
fattr->cf_nlink);
|
||||
cifs_dbg(VFS, "bogus file nlink value %u\n",
|
||||
fattr->cf_nlink);
|
||||
fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
|
||||
}
|
||||
}
|
||||
|
@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
struct super_block *sb = dentry->d_sb;
|
||||
char *full_path = NULL;
|
||||
int count = 0;
|
||||
|
||||
if (inode == NULL)
|
||||
return -ENOENT;
|
||||
|
@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
|
|||
full_path, inode, inode->i_count.counter,
|
||||
dentry, cifs_get_time(dentry), jiffies);
|
||||
|
||||
again:
|
||||
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
|
||||
else
|
||||
rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
|
||||
xid, NULL);
|
||||
|
||||
if (rc == -EAGAIN && count++ < 10)
|
||||
goto again;
|
||||
out:
|
||||
kfree(full_path);
|
||||
free_xid(xid);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -2278,7 +2282,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
|
|||
* writebehind data than the SMB timeout for the SetPathInfo
|
||||
* request would allow
|
||||
*/
|
||||
open_file = find_writable_file(cifsInode, true);
|
||||
open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);
|
||||
if (open_file) {
|
||||
tcon = tlink_tcon(open_file->tlink);
|
||||
server = tcon->ses->server;
|
||||
|
@ -2428,7 +2432,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
|||
args->ctime = NO_CHANGE_64;
|
||||
|
||||
args->device = 0;
|
||||
open_file = find_writable_file(cifsInode, true);
|
||||
open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);
|
||||
if (open_file) {
|
||||
u16 nfid = open_file->fid.netfid;
|
||||
u32 npid = open_file->pid;
|
||||
|
@ -2531,7 +2535,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
|||
rc = 0;
|
||||
|
||||
if (attrs->ia_valid & ATTR_MTIME) {
|
||||
rc = cifs_get_writable_file(cifsInode, false, &wfile);
|
||||
rc = cifs_get_writable_file(cifsInode, FIND_WR_ANY, &wfile);
|
||||
if (!rc) {
|
||||
tcon = tlink_tcon(wfile->tlink);
|
||||
rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid);
|
||||
|
|
|
@ -766,7 +766,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
|
|||
struct cifs_tcon *tcon;
|
||||
|
||||
/* if the file is already open for write, just use that fileid */
|
||||
open_file = find_writable_file(cinode, true);
|
||||
open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY);
|
||||
if (open_file) {
|
||||
fid.netfid = open_file->fid.netfid;
|
||||
netpid = open_file->pid;
|
||||
|
|
|
@ -521,7 +521,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
|
|||
cifs_i = CIFS_I(inode);
|
||||
dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
|
||||
data.Attributes = cpu_to_le32(dosattrs);
|
||||
cifs_get_writable_path(tcon, name, &cfile);
|
||||
cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile);
|
||||
tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
|
||||
FILE_WRITE_ATTRIBUTES, FILE_CREATE,
|
||||
CREATE_NOT_FILE, ACL_NO_MODE,
|
||||
|
@ -577,7 +577,7 @@ smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
{
|
||||
struct cifsFileInfo *cfile;
|
||||
|
||||
cifs_get_writable_path(tcon, from_name, &cfile);
|
||||
cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile);
|
||||
|
||||
return smb2_set_path_attr(xid, tcon, from_name, to_name,
|
||||
cifs_sb, DELETE, SMB2_OP_RENAME, cfile);
|
||||
|
|
|
@ -1364,6 +1364,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
|
|||
|
||||
cfile->fid.persistent_fid = fid->persistent_fid;
|
||||
cfile->fid.volatile_fid = fid->volatile_fid;
|
||||
cfile->fid.access = fid->access;
|
||||
#ifdef CONFIG_CIFS_DEBUG2
|
||||
cfile->fid.mid = fid->mid;
|
||||
#endif /* CIFS_DEBUG2 */
|
||||
|
@ -3327,7 +3328,7 @@ static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offs
|
|||
* some servers (Windows2016) will not reflect recent writes in
|
||||
* QUERY_ALLOCATED_RANGES until SMB2_flush is called.
|
||||
*/
|
||||
wrcfile = find_writable_file(cifsi, false);
|
||||
wrcfile = find_writable_file(cifsi, FIND_WR_ANY);
|
||||
if (wrcfile) {
|
||||
filemap_write_and_wait(inode->i_mapping);
|
||||
smb2_flush_file(xid, tcon, &wrcfile->fid);
|
||||
|
|
|
@ -2771,6 +2771,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
|
|||
atomic_inc(&tcon->num_remote_opens);
|
||||
oparms->fid->persistent_fid = rsp->PersistentFileId;
|
||||
oparms->fid->volatile_fid = rsp->VolatileFileId;
|
||||
oparms->fid->access = oparms->desired_access;
|
||||
#ifdef CONFIG_CIFS_DEBUG2
|
||||
oparms->fid->mid = le64_to_cpu(rsp->sync_hdr.MessageId);
|
||||
#endif /* CIFS_DEBUG2 */
|
||||
|
|
Loading…
Reference in a new issue