Skip to content

Commit 8b614cb

Browse files
committed
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
2 parents 2873dc2 + fb4b5f1 commit 8b614cb

File tree

11 files changed

+44
-20
lines changed

11 files changed

+44
-20
lines changed

fs/cifs/cifs_dfs_ref.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
324324
if (full_path == NULL)
325325
goto cdda_exit;
326326

327+
convert_delimiter(full_path, '\\');
328+
327329
cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path);
328330

329331
if (!cifs_sb_master_tlink(cifs_sb)) {

fs/cifs/cifsfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
530530

531531
if (tcon->seal)
532532
seq_puts(s, ",seal");
533+
else if (tcon->ses->server->ignore_signature)
534+
seq_puts(s, ",signloosely");
533535
if (tcon->nocase)
534536
seq_puts(s, ",nocase");
535537
if (tcon->local_lease)

fs/cifs/cifsglob.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,7 @@ struct cifs_fid {
12811281
__u64 volatile_fid; /* volatile file id for smb2 */
12821282
__u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for smb2 */
12831283
__u8 create_guid[16];
1284+
__u32 access;
12841285
struct cifs_pending_open *pending_open;
12851286
unsigned int epoch;
12861287
#ifdef CONFIG_CIFS_DEBUG2
@@ -1741,6 +1742,12 @@ static inline bool is_retryable_error(int error)
17411742
return false;
17421743
}
17431744

1745+
1746+
/* cifs_get_writable_file() flags */
1747+
#define FIND_WR_ANY 0
1748+
#define FIND_WR_FSUID_ONLY 1
1749+
#define FIND_WR_WITH_DELETE 2
1750+
17441751
#define MID_FREE 0
17451752
#define MID_REQUEST_ALLOCATED 1
17461753
#define MID_REQUEST_SUBMITTED 2

fs/cifs/cifsproto.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,12 @@ extern bool backup_cred(struct cifs_sb_info *);
134134
extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
135135
extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
136136
unsigned int bytes_written);
137-
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
137+
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
138138
extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
139-
bool fsuid_only,
139+
int flags,
140140
struct cifsFileInfo **ret_file);
141141
extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
142+
int flags,
142143
struct cifsFileInfo **ret_file);
143144
extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
144145
extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,

fs/cifs/cifssmb.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,7 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
14921492
*oplock = rsp->OplockLevel;
14931493
/* cifs fid stays in le */
14941494
oparms->fid->netfid = rsp->Fid;
1495+
oparms->fid->access = desired_access;
14951496

14961497
/* Let caller know file was created so we can set the mode. */
14971498
/* Do we care about the CreateAction in any other cases? */
@@ -2115,7 +2116,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
21152116
wdata2->tailsz = tailsz;
21162117
wdata2->bytes = cur_len;
21172118

2118-
rc = cifs_get_writable_file(CIFS_I(inode), false,
2119+
rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
21192120
&wdata2->cfile);
21202121
if (!wdata2->cfile) {
21212122
cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",

fs/cifs/file.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,15 +1958,16 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
19581958

19591959
/* Return -EBADF if no handle is found and general rc otherwise */
19601960
int
1961-
cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
1961+
cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags,
19621962
struct cifsFileInfo **ret_file)
19631963
{
19641964
struct cifsFileInfo *open_file, *inv_file = NULL;
19651965
struct cifs_sb_info *cifs_sb;
19661966
bool any_available = false;
19671967
int rc = -EBADF;
19681968
unsigned int refind = 0;
1969-
1969+
bool fsuid_only = flags & FIND_WR_FSUID_ONLY;
1970+
bool with_delete = flags & FIND_WR_WITH_DELETE;
19701971
*ret_file = NULL;
19711972

19721973
/*
@@ -1998,6 +1999,8 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
19981999
continue;
19992000
if (fsuid_only && !uid_eq(open_file->uid, current_fsuid()))
20002001
continue;
2002+
if (with_delete && !(open_file->fid.access & DELETE))
2003+
continue;
20012004
if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
20022005
if (!open_file->invalidHandle) {
20032006
/* found a good writable file */
@@ -2045,12 +2048,12 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
20452048
}
20462049

20472050
struct cifsFileInfo *
2048-
find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only)
2051+
find_writable_file(struct cifsInodeInfo *cifs_inode, int flags)
20492052
{
20502053
struct cifsFileInfo *cfile;
20512054
int rc;
20522055

2053-
rc = cifs_get_writable_file(cifs_inode, fsuid_only, &cfile);
2056+
rc = cifs_get_writable_file(cifs_inode, flags, &cfile);
20542057
if (rc)
20552058
cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc);
20562059

@@ -2059,6 +2062,7 @@ find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only)
20592062

20602063
int
20612064
cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
2065+
int flags,
20622066
struct cifsFileInfo **ret_file)
20632067
{
20642068
struct list_head *tmp;
@@ -2085,7 +2089,7 @@ cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
20852089
kfree(full_path);
20862090
cinode = CIFS_I(d_inode(cfile->dentry));
20872091
spin_unlock(&tcon->open_file_lock);
2088-
return cifs_get_writable_file(cinode, 0, ret_file);
2092+
return cifs_get_writable_file(cinode, flags, ret_file);
20892093
}
20902094

20912095
spin_unlock(&tcon->open_file_lock);
@@ -2162,7 +2166,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
21622166
if (mapping->host->i_size - offset < (loff_t)to)
21632167
to = (unsigned)(mapping->host->i_size - offset);
21642168

2165-
rc = cifs_get_writable_file(CIFS_I(mapping->host), false, &open_file);
2169+
rc = cifs_get_writable_file(CIFS_I(mapping->host), FIND_WR_ANY,
2170+
&open_file);
21662171
if (!rc) {
21672172
bytes_written = cifs_write(open_file, open_file->pid,
21682173
write_data, to - from, &offset);
@@ -2355,7 +2360,7 @@ static int cifs_writepages(struct address_space *mapping,
23552360
if (cfile)
23562361
cifsFileInfo_put(cfile);
23572362

2358-
rc = cifs_get_writable_file(CIFS_I(inode), false, &cfile);
2363+
rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile);
23592364

23602365
/* in case of an error store it to return later */
23612366
if (rc)

fs/cifs/inode.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
653653
*/
654654
if ((fattr->cf_nlink < 1) && !tcon->unix_ext &&
655655
!info->DeletePending) {
656-
cifs_dbg(1, "bogus file nlink value %u\n",
657-
fattr->cf_nlink);
656+
cifs_dbg(VFS, "bogus file nlink value %u\n",
657+
fattr->cf_nlink);
658658
fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
659659
}
660660
}
@@ -2073,6 +2073,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
20732073
struct inode *inode = d_inode(dentry);
20742074
struct super_block *sb = dentry->d_sb;
20752075
char *full_path = NULL;
2076+
int count = 0;
20762077

20772078
if (inode == NULL)
20782079
return -ENOENT;
@@ -2094,15 +2095,18 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
20942095
full_path, inode, inode->i_count.counter,
20952096
dentry, cifs_get_time(dentry), jiffies);
20962097

2098+
again:
20972099
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
20982100
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
20992101
else
21002102
rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
21012103
xid, NULL);
2102-
2104+
if (rc == -EAGAIN && count++ < 10)
2105+
goto again;
21032106
out:
21042107
kfree(full_path);
21052108
free_xid(xid);
2109+
21062110
return rc;
21072111
}
21082112

@@ -2278,7 +2282,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
22782282
* writebehind data than the SMB timeout for the SetPathInfo
22792283
* request would allow
22802284
*/
2281-
open_file = find_writable_file(cifsInode, true);
2285+
open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);
22822286
if (open_file) {
22832287
tcon = tlink_tcon(open_file->tlink);
22842288
server = tcon->ses->server;
@@ -2428,7 +2432,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
24282432
args->ctime = NO_CHANGE_64;
24292433

24302434
args->device = 0;
2431-
open_file = find_writable_file(cifsInode, true);
2435+
open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);
24322436
if (open_file) {
24332437
u16 nfid = open_file->fid.netfid;
24342438
u32 npid = open_file->pid;
@@ -2531,7 +2535,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
25312535
rc = 0;
25322536

25332537
if (attrs->ia_valid & ATTR_MTIME) {
2534-
rc = cifs_get_writable_file(cifsInode, false, &wfile);
2538+
rc = cifs_get_writable_file(cifsInode, FIND_WR_ANY, &wfile);
25352539
if (!rc) {
25362540
tcon = tlink_tcon(wfile->tlink);
25372541
rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid);

fs/cifs/smb1ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
766766
struct cifs_tcon *tcon;
767767

768768
/* if the file is already open for write, just use that fileid */
769-
open_file = find_writable_file(cinode, true);
769+
open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY);
770770
if (open_file) {
771771
fid.netfid = open_file->fid.netfid;
772772
netpid = open_file->pid;

fs/cifs/smb2inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
521521
cifs_i = CIFS_I(inode);
522522
dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
523523
data.Attributes = cpu_to_le32(dosattrs);
524-
cifs_get_writable_path(tcon, name, &cfile);
524+
cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile);
525525
tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
526526
FILE_WRITE_ATTRIBUTES, FILE_CREATE,
527527
CREATE_NOT_FILE, ACL_NO_MODE,
@@ -577,7 +577,7 @@ smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon,
577577
{
578578
struct cifsFileInfo *cfile;
579579

580-
cifs_get_writable_path(tcon, from_name, &cfile);
580+
cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile);
581581

582582
return smb2_set_path_attr(xid, tcon, from_name, to_name,
583583
cifs_sb, DELETE, SMB2_OP_RENAME, cfile);

fs/cifs/smb2ops.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
13641364

13651365
cfile->fid.persistent_fid = fid->persistent_fid;
13661366
cfile->fid.volatile_fid = fid->volatile_fid;
1367+
cfile->fid.access = fid->access;
13671368
#ifdef CONFIG_CIFS_DEBUG2
13681369
cfile->fid.mid = fid->mid;
13691370
#endif /* CIFS_DEBUG2 */
@@ -3327,7 +3328,7 @@ static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offs
33273328
* some servers (Windows2016) will not reflect recent writes in
33283329
* QUERY_ALLOCATED_RANGES until SMB2_flush is called.
33293330
*/
3330-
wrcfile = find_writable_file(cifsi, false);
3331+
wrcfile = find_writable_file(cifsi, FIND_WR_ANY);
33313332
if (wrcfile) {
33323333
filemap_write_and_wait(inode->i_mapping);
33333334
smb2_flush_file(xid, tcon, &wrcfile->fid);

fs/cifs/smb2pdu.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,6 +2771,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
27712771
atomic_inc(&tcon->num_remote_opens);
27722772
oparms->fid->persistent_fid = rsp->PersistentFileId;
27732773
oparms->fid->volatile_fid = rsp->VolatileFileId;
2774+
oparms->fid->access = oparms->desired_access;
27742775
#ifdef CONFIG_CIFS_DEBUG2
27752776
oparms->fid->mid = le64_to_cpu(rsp->sync_hdr.MessageId);
27762777
#endif /* CIFS_DEBUG2 */

0 commit comments

Comments
 (0)