Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'v7.0-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:
- Fix reconnect when using non-default port
- Fix default retransmission behavior
- Fix open handle reuse in cifs_open
- Fix export for smb2-mapperror-test
- Fix potential corruption on write retry
- Fix potentially uninitialized superblock flags
- Fix missing O_DIRECT and O_SYNC flags on create

* tag 'v7.0-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
cifs: make default value of retrans as zero
smb: client: fix open handle lookup in cifs_open()
smb: client: fix iface port assignment in parse_server_interfaces
smb/client: only export symbol for 'smb2maperror-test' module
smb: client: fix in-place encryption corruption in SMB2_write()
smb: client: fix sbflags initialization
smb: client: fix atomic open with O_DIRECT & O_SYNC

+151 -99
+1 -1
fs/smb/client/cifsacl.c
··· 1489 1489 struct cifsFileInfo *open_file = NULL; 1490 1490 1491 1491 if (inode) 1492 - open_file = find_readable_file(CIFS_I(inode), true); 1492 + open_file = find_readable_file(CIFS_I(inode), FIND_FSUID_ONLY); 1493 1493 if (!open_file) 1494 1494 return get_cifs_acl_by_path(cifs_sb, path, pacllen, info); 1495 1495
+1 -1
fs/smb/client/cifsfs.c
··· 1269 1269 struct cifsFileInfo *writeable_srcfile; 1270 1270 int rc = -EINVAL; 1271 1271 1272 - writeable_srcfile = find_writable_file(src_cifsi, FIND_WR_FSUID_ONLY); 1272 + writeable_srcfile = find_writable_file(src_cifsi, FIND_FSUID_ONLY); 1273 1273 if (writeable_srcfile) { 1274 1274 if (src_tcon->ses->server->ops->set_file_size) 1275 1275 rc = src_tcon->ses->server->ops->set_file_size(
+17 -6
fs/smb/client/cifsglob.h
··· 20 20 #include <linux/utsname.h> 21 21 #include <linux/sched/mm.h> 22 22 #include <linux/netfs.h> 23 + #include <linux/fcntl.h> 23 24 #include "cifs_fs_sb.h" 24 25 #include "cifsacl.h" 25 26 #include <crypto/internal/hash.h> ··· 1885 1884 } 1886 1885 1887 1886 1888 - /* cifs_get_writable_file() flags */ 1889 - enum cifs_writable_file_flags { 1890 - FIND_WR_ANY = 0U, 1891 - FIND_WR_FSUID_ONLY = (1U << 0), 1892 - FIND_WR_WITH_DELETE = (1U << 1), 1893 - FIND_WR_NO_PENDING_DELETE = (1U << 2), 1887 + enum cifs_find_flags { 1888 + FIND_ANY = 0U, 1889 + FIND_FSUID_ONLY = (1U << 0), 1890 + FIND_WITH_DELETE = (1U << 1), 1891 + FIND_NO_PENDING_DELETE = (1U << 2), 1892 + FIND_OPEN_FLAGS = (1U << 3), 1894 1893 }; 1895 1894 1896 1895 #define MID_FREE 0 ··· 2374 2373 static inline bool cifs_forced_shutdown(const struct cifs_sb_info *sbi) 2375 2374 { 2376 2375 return cifs_sb_flags(sbi) & CIFS_MOUNT_SHUTDOWN; 2376 + } 2377 + 2378 + static inline int cifs_open_create_options(unsigned int oflags, int opts) 2379 + { 2380 + /* O_SYNC also has bit for O_DSYNC so following check picks up either */ 2381 + if (oflags & O_SYNC) 2382 + opts |= CREATE_WRITE_THROUGH; 2383 + if (oflags & O_DIRECT) 2384 + opts |= CREATE_NO_BUFFER; 2385 + return opts; 2377 2386 } 2378 2387 2379 2388 #endif /* _CIFS_GLOB_H */
+22 -4
fs/smb/client/cifsproto.h
··· 138 138 ssize_t result); 139 139 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, 140 140 int flags); 141 - int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, 142 - struct cifsFileInfo **ret_file); 141 + int __cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, 142 + unsigned int find_flags, unsigned int open_flags, 143 + struct cifsFileInfo **ret_file); 143 144 int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, int flags, 144 145 struct cifsFileInfo **ret_file); 145 - struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, 146 - bool fsuid_only); 146 + struct cifsFileInfo *__find_readable_file(struct cifsInodeInfo *cifs_inode, 147 + unsigned int find_flags, 148 + unsigned int open_flags); 147 149 int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, 148 150 struct cifsFileInfo **ret_file); 149 151 int cifs_get_hardlink_path(struct cifs_tcon *tcon, struct inode *inode, ··· 596 594 sg_set_page(&sgtable->sgl[sgtable->nents++], 597 595 virt_to_page((void *)addr), buflen, off); 598 596 } 597 + } 598 + 599 + static inline int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, 600 + unsigned int find_flags, 601 + struct cifsFileInfo **ret_file) 602 + { 603 + find_flags &= ~FIND_OPEN_FLAGS; 604 + return __cifs_get_writable_file(cifs_inode, find_flags, 0, ret_file); 605 + } 606 + 607 + static inline struct cifsFileInfo * 608 + find_readable_file(struct cifsInodeInfo *cinode, unsigned int find_flags) 609 + { 610 + find_flags &= ~FIND_OPEN_FLAGS; 611 + find_flags |= FIND_NO_PENDING_DELETE; 612 + return __find_readable_file(cinode, find_flags, 0); 599 613 } 600 614 601 615 #endif /* _CIFSPROTO_H */
+2 -2
fs/smb/client/dir.c
··· 187 187 const char *full_path; 188 188 void *page = alloc_dentry_path(); 189 189 struct inode *newinode = NULL; 190 - unsigned int sbflags; 190 + unsigned int sbflags = cifs_sb_flags(cifs_sb); 191 191 int disposition; 192 192 struct TCP_Server_Info *server = tcon->ses->server; 193 193 struct cifs_open_parms oparms; ··· 308 308 goto out; 309 309 } 310 310 311 + create_options |= cifs_open_create_options(oflags, create_options); 311 312 /* 312 313 * if we're not using unix extensions, see if we need to set 313 314 * ATTR_READONLY on the create call ··· 368 367 * If Open reported that we actually created a file then we now have to 369 368 * set the mode if possible. 370 369 */ 371 - sbflags = cifs_sb_flags(cifs_sb); 372 370 if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) { 373 371 struct cifs_unix_set_info_args args = { 374 372 .mode = mode,
+69 -60
fs/smb/client/file.c
··· 255 255 struct cifs_io_request *req = container_of(wreq, struct cifs_io_request, rreq); 256 256 int ret; 257 257 258 - ret = cifs_get_writable_file(CIFS_I(wreq->inode), FIND_WR_ANY, &req->cfile); 258 + ret = cifs_get_writable_file(CIFS_I(wreq->inode), FIND_ANY, &req->cfile); 259 259 if (ret) { 260 260 cifs_dbg(VFS, "No writable handle in writepages ret=%d\n", ret); 261 261 return; ··· 584 584 *********************************************************************/ 585 585 586 586 disposition = cifs_get_disposition(f_flags); 587 - 588 587 /* BB pass O_SYNC flag through on file attributes .. BB */ 589 - 590 - /* O_SYNC also has bit for O_DSYNC so following check picks up either */ 591 - if (f_flags & O_SYNC) 592 - create_options |= CREATE_WRITE_THROUGH; 593 - 594 - if (f_flags & O_DIRECT) 595 - create_options |= CREATE_NO_BUFFER; 588 + create_options |= cifs_open_create_options(f_flags, create_options); 596 589 597 590 retry_open: 598 591 oparms = (struct cifs_open_parms) { ··· 956 963 return tcon->ses->server->ops->flush(xid, tcon, 957 964 &cfile->fid); 958 965 } 959 - rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile); 966 + rc = cifs_get_writable_file(CIFS_I(inode), FIND_ANY, &cfile); 960 967 if (!rc) { 961 968 tcon = tlink_tcon(cfile->tlink); 962 969 rc = tcon->ses->server->ops->flush(xid, tcon, &cfile->fid); ··· 981 988 return -ERESTARTSYS; 982 989 mapping_set_error(inode->i_mapping, rc); 983 990 984 - cfile = find_writable_file(cinode, FIND_WR_FSUID_ONLY); 991 + cfile = find_writable_file(cinode, FIND_FSUID_ONLY); 985 992 rc = cifs_file_flush(xid, inode, cfile); 986 993 if (!rc) { 987 994 if (cfile) { ··· 1061 1068 1062 1069 /* Get the cached handle as SMB2 close is deferred */ 1063 1070 if (OPEN_FMODE(file->f_flags) & FMODE_WRITE) { 1064 - rc = cifs_get_writable_path(tcon, full_path, 1065 - FIND_WR_FSUID_ONLY | 1066 - FIND_WR_NO_PENDING_DELETE, 1067 - &cfile); 1071 + rc = __cifs_get_writable_file(CIFS_I(inode), 1072 + FIND_FSUID_ONLY | 1073 + FIND_NO_PENDING_DELETE | 1074 + FIND_OPEN_FLAGS, 1075 + file->f_flags, &cfile); 1068 1076 } else { 1069 - rc = cifs_get_readable_path(tcon, full_path, &cfile); 1077 + cfile = __find_readable_file(CIFS_I(inode), 1078 + FIND_NO_PENDING_DELETE | 1079 + FIND_OPEN_FLAGS, 1080 + file->f_flags); 1081 + rc = cfile ? 0 : -ENOENT; 1070 1082 } 1071 1083 if (rc == 0) { 1072 - unsigned int oflags = file->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC); 1073 - unsigned int cflags = cfile->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC); 1074 - 1075 - if (cifs_convert_flags(oflags, 0) == cifs_convert_flags(cflags, 0) && 1076 - (oflags & (O_SYNC|O_DIRECT)) == (cflags & (O_SYNC|O_DIRECT))) { 1077 - file->private_data = cfile; 1078 - spin_lock(&CIFS_I(inode)->deferred_lock); 1079 - cifs_del_deferred_close(cfile); 1080 - spin_unlock(&CIFS_I(inode)->deferred_lock); 1081 - goto use_cache; 1082 - } 1083 - _cifsFileInfo_put(cfile, true, false); 1084 - } else { 1085 - /* hard link on the defeered close file */ 1086 - rc = cifs_get_hardlink_path(tcon, inode, file); 1087 - if (rc) 1088 - cifs_close_deferred_file(CIFS_I(inode)); 1084 + file->private_data = cfile; 1085 + spin_lock(&CIFS_I(inode)->deferred_lock); 1086 + cifs_del_deferred_close(cfile); 1087 + spin_unlock(&CIFS_I(inode)->deferred_lock); 1088 + goto use_cache; 1089 1089 } 1090 + /* hard link on the deferred close file */ 1091 + rc = cifs_get_hardlink_path(tcon, inode, file); 1092 + if (rc) 1093 + cifs_close_deferred_file(CIFS_I(inode)); 1090 1094 1091 1095 if (server->oplocks) 1092 1096 oplock = REQ_OPLOCK; ··· 1304 1314 rdwr_for_fscache = 1; 1305 1315 1306 1316 desired_access = cifs_convert_flags(cfile->f_flags, rdwr_for_fscache); 1307 - 1308 - /* O_SYNC also has bit for O_DSYNC so following check picks up either */ 1309 - if (cfile->f_flags & O_SYNC) 1310 - create_options |= CREATE_WRITE_THROUGH; 1311 - 1312 - if (cfile->f_flags & O_DIRECT) 1313 - create_options |= CREATE_NO_BUFFER; 1317 + create_options |= cifs_open_create_options(cfile->f_flags, 1318 + create_options); 1314 1319 1315 1320 if (server->ops->get_lease_key) 1316 1321 server->ops->get_lease_key(inode, &cfile->fid); ··· 2509 2524 netfs_write_subrequest_terminated(&wdata->subreq, result); 2510 2525 } 2511 2526 2512 - struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, 2513 - bool fsuid_only) 2527 + static bool open_flags_match(struct cifsInodeInfo *cinode, 2528 + unsigned int oflags, unsigned int cflags) 2529 + { 2530 + struct inode *inode = &cinode->netfs.inode; 2531 + int crw = 0, orw = 0; 2532 + 2533 + oflags &= ~(O_CREAT | O_EXCL | O_TRUNC); 2534 + cflags &= ~(O_CREAT | O_EXCL | O_TRUNC); 2535 + 2536 + if (cifs_fscache_enabled(inode)) { 2537 + if (OPEN_FMODE(cflags) & FMODE_WRITE) 2538 + crw = 1; 2539 + if (OPEN_FMODE(oflags) & FMODE_WRITE) 2540 + orw = 1; 2541 + } 2542 + if (cifs_convert_flags(oflags, orw) != cifs_convert_flags(cflags, crw)) 2543 + return false; 2544 + 2545 + return (oflags & (O_SYNC | O_DIRECT)) == (cflags & (O_SYNC | O_DIRECT)); 2546 + } 2547 + 2548 + struct cifsFileInfo *__find_readable_file(struct cifsInodeInfo *cifs_inode, 2549 + unsigned int find_flags, 2550 + unsigned int open_flags) 2514 2551 { 2515 2552 struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode); 2553 + bool fsuid_only = find_flags & FIND_FSUID_ONLY; 2516 2554 struct cifsFileInfo *open_file = NULL; 2517 2555 2518 2556 /* only filter by fsuid on multiuser mounts */ ··· 2548 2540 have a close pending, we go through the whole list */ 2549 2541 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 2550 2542 if (fsuid_only && !uid_eq(open_file->uid, current_fsuid())) 2543 + continue; 2544 + if ((find_flags & FIND_NO_PENDING_DELETE) && 2545 + open_file->status_file_deleted) 2546 + continue; 2547 + if ((find_flags & FIND_OPEN_FLAGS) && 2548 + !open_flags_match(cifs_inode, open_flags, 2549 + open_file->f_flags)) 2551 2550 continue; 2552 2551 if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) { 2553 2552 if ((!open_file->invalidHandle)) { ··· 2574 2559 } 2575 2560 2576 2561 /* Return -EBADF if no handle is found and general rc otherwise */ 2577 - int 2578 - cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, 2579 - struct cifsFileInfo **ret_file) 2562 + int __cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, 2563 + unsigned int find_flags, unsigned int open_flags, 2564 + struct cifsFileInfo **ret_file) 2580 2565 { 2581 2566 struct cifsFileInfo *open_file, *inv_file = NULL; 2582 2567 struct cifs_sb_info *cifs_sb; 2583 2568 bool any_available = false; 2584 2569 int rc = -EBADF; 2585 2570 unsigned int refind = 0; 2586 - bool fsuid_only = flags & FIND_WR_FSUID_ONLY; 2587 - bool with_delete = flags & FIND_WR_WITH_DELETE; 2571 + bool fsuid_only = find_flags & FIND_FSUID_ONLY; 2572 + bool with_delete = find_flags & FIND_WITH_DELETE; 2588 2573 *ret_file = NULL; 2589 2574 2590 2575 /* ··· 2618 2603 continue; 2619 2604 if (with_delete && !(open_file->fid.access & DELETE)) 2620 2605 continue; 2621 - if ((flags & FIND_WR_NO_PENDING_DELETE) && 2606 + if ((find_flags & FIND_NO_PENDING_DELETE) && 2622 2607 open_file->status_file_deleted) 2608 + continue; 2609 + if ((find_flags & FIND_OPEN_FLAGS) && 2610 + !open_flags_match(cifs_inode, open_flags, 2611 + open_file->f_flags)) 2623 2612 continue; 2624 2613 if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { 2625 2614 if (!open_file->invalidHandle) { ··· 2741 2722 cinode = CIFS_I(d_inode(cfile->dentry)); 2742 2723 spin_unlock(&tcon->open_file_lock); 2743 2724 free_dentry_path(page); 2744 - *ret_file = find_readable_file(cinode, 0); 2745 - if (*ret_file) { 2746 - spin_lock(&cinode->open_file_lock); 2747 - if ((*ret_file)->status_file_deleted) { 2748 - spin_unlock(&cinode->open_file_lock); 2749 - cifsFileInfo_put(*ret_file); 2750 - *ret_file = NULL; 2751 - } else { 2752 - spin_unlock(&cinode->open_file_lock); 2753 - } 2754 - } 2725 + *ret_file = find_readable_file(cinode, FIND_ANY); 2755 2726 return *ret_file ? 0 : -ENOENT; 2756 2727 } 2757 2728 ··· 2813 2804 } 2814 2805 2815 2806 if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) { 2816 - smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY); 2807 + smbfile = find_writable_file(CIFS_I(inode), FIND_ANY); 2817 2808 if (smbfile) { 2818 2809 rc = server->ops->flush(xid, tcon, &smbfile->fid); 2819 2810 cifsFileInfo_put(smbfile);
+1 -1
fs/smb/client/fs_context.c
··· 1997 1997 ctx->backupuid_specified = false; /* no backup intent for a user */ 1998 1998 ctx->backupgid_specified = false; /* no backup intent for a group */ 1999 1999 2000 - ctx->retrans = 1; 2000 + ctx->retrans = 0; 2001 2001 ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT; 2002 2002 ctx->symlink_type = CIFS_SYMLINK_TYPE_DEFAULT; 2003 2003 ctx->nonativesocket = 0;
+3 -3
fs/smb/client/inode.c
··· 2997 2997 } 2998 2998 } 2999 2999 3000 - cfile = find_readable_file(cifs_i, false); 3000 + cfile = find_readable_file(cifs_i, FIND_ANY); 3001 3001 if (cfile == NULL) 3002 3002 return -EINVAL; 3003 3003 ··· 3050 3050 size, false); 3051 3051 cifs_dbg(FYI, "%s: set_file_size: rc = %d\n", __func__, rc); 3052 3052 } else { 3053 - open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); 3053 + open_file = find_writable_file(cifsInode, FIND_FSUID_ONLY); 3054 3054 if (open_file) { 3055 3055 tcon = tlink_tcon(open_file->tlink); 3056 3056 server = tcon->ses->server; ··· 3219 3219 open_file->fid.netfid, 3220 3220 open_file->pid); 3221 3221 } else { 3222 - open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); 3222 + open_file = find_writable_file(cifsInode, FIND_FSUID_ONLY); 3223 3223 if (open_file) { 3224 3224 pTcon = tlink_tcon(open_file->tlink); 3225 3225 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args,
+1 -1
fs/smb/client/smb1ops.c
··· 960 960 struct cifs_tcon *tcon; 961 961 962 962 /* if the file is already open for write, just use that fileid */ 963 - open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY); 963 + open_file = find_writable_file(cinode, FIND_FSUID_ONLY); 964 964 965 965 if (open_file) { 966 966 fid.netfid = open_file->fid.netfid;
+10 -12
fs/smb/client/smb2inode.c
··· 1156 1156 cifs_i = CIFS_I(inode); 1157 1157 dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; 1158 1158 data.Attributes = cpu_to_le32(dosattrs); 1159 - cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile); 1159 + cifs_get_writable_path(tcon, name, FIND_ANY, &cfile); 1160 1160 oparms = CIFS_OPARMS(cifs_sb, tcon, name, FILE_WRITE_ATTRIBUTES, 1161 1161 FILE_CREATE, CREATE_NOT_FILE, ACL_NO_MODE); 1162 1162 tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, ··· 1336 1336 __u32 co = file_create_options(source_dentry); 1337 1337 1338 1338 drop_cached_dir_by_name(xid, tcon, from_name, cifs_sb); 1339 - cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile); 1339 + cifs_get_writable_path(tcon, from_name, FIND_WITH_DELETE, &cfile); 1340 1340 1341 1341 int rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, 1342 1342 co, DELETE, SMB2_OP_RENAME, cfile, source_dentry); 1343 1343 if (rc == -EINVAL) { 1344 1344 cifs_dbg(FYI, "invalid lease key, resending request without lease"); 1345 - cifs_get_writable_path(tcon, from_name, 1346 - FIND_WR_WITH_DELETE, &cfile); 1345 + cifs_get_writable_path(tcon, from_name, FIND_WITH_DELETE, &cfile); 1347 1346 rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, 1348 1347 co, DELETE, SMB2_OP_RENAME, cfile, NULL); 1349 1348 } ··· 1376 1377 1377 1378 in_iov.iov_base = &eof; 1378 1379 in_iov.iov_len = sizeof(eof); 1379 - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); 1380 + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); 1380 1381 1381 1382 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_DATA, 1382 1383 FILE_OPEN, 0, ACL_NO_MODE); ··· 1386 1387 cfile, NULL, NULL, dentry); 1387 1388 if (rc == -EINVAL) { 1388 1389 cifs_dbg(FYI, "invalid lease key, resending request without lease"); 1389 - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); 1390 + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); 1390 1391 rc = smb2_compound_op(xid, tcon, cifs_sb, 1391 1392 full_path, &oparms, &in_iov, 1392 1393 &(int){SMB2_OP_SET_EOF}, 1, ··· 1416 1417 (buf->LastWriteTime == 0) && (buf->ChangeTime == 0)) { 1417 1418 if (buf->Attributes == 0) 1418 1419 goto out; /* would be a no op, no sense sending this */ 1419 - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); 1420 + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); 1420 1421 } 1421 1422 1422 1423 oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_ATTRIBUTES, ··· 1475 1476 1476 1477 if (tcon->posix_extensions) { 1477 1478 cmds[1] = SMB2_OP_POSIX_QUERY_INFO; 1478 - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); 1479 + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); 1479 1480 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, 1480 1481 in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); 1481 1482 if (!rc) { ··· 1484 1485 } 1485 1486 } else { 1486 1487 cmds[1] = SMB2_OP_QUERY_INFO; 1487 - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); 1488 + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); 1488 1489 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, 1489 1490 in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); 1490 1491 if (!rc) { ··· 1635 1636 iov[1].iov_base = utf16_path; 1636 1637 iov[1].iov_len = sizeof(*utf16_path) * UniStrlen((wchar_t *)utf16_path); 1637 1638 1638 - cifs_get_writable_path(tcon, full_path, FIND_WR_WITH_DELETE, &cfile); 1639 + cifs_get_writable_path(tcon, full_path, FIND_WITH_DELETE, &cfile); 1639 1640 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov, 1640 1641 cmds, num_cmds, cfile, NULL, NULL, dentry); 1641 1642 if (rc == -EINVAL) { 1642 1643 cifs_dbg(FYI, "invalid lease key, resending request without lease\n"); 1643 - cifs_get_writable_path(tcon, full_path, 1644 - FIND_WR_WITH_DELETE, &cfile); 1644 + cifs_get_writable_path(tcon, full_path, FIND_WITH_DELETE, &cfile); 1645 1645 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov, 1646 1646 cmds, num_cmds, cfile, NULL, NULL, NULL); 1647 1647 }
+6 -3
fs/smb/client/smb2maperror.c
··· 109 109 } 110 110 111 111 #if IS_ENABLED(CONFIG_SMB_KUNIT_TESTS) 112 + #define EXPORT_SYMBOL_FOR_SMB_TEST(sym) \ 113 + EXPORT_SYMBOL_FOR_MODULES(sym, "smb2maperror_test") 114 + 112 115 /* Previous prototype for eliminating the build warning. */ 113 116 const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status); 114 117 ··· 119 116 { 120 117 return smb2_get_err_map(smb2_status); 121 118 } 122 - EXPORT_SYMBOL_GPL(smb2_get_err_map_test); 119 + EXPORT_SYMBOL_FOR_SMB_TEST(smb2_get_err_map_test); 123 120 124 121 const struct status_to_posix_error *smb2_error_map_table_test = smb2_error_map_table; 125 - EXPORT_SYMBOL_GPL(smb2_error_map_table_test); 122 + EXPORT_SYMBOL_FOR_SMB_TEST(smb2_error_map_table_test); 126 123 127 124 unsigned int smb2_error_map_num = ARRAY_SIZE(smb2_error_map_table); 128 - EXPORT_SYMBOL_GPL(smb2_error_map_num); 125 + EXPORT_SYMBOL_FOR_SMB_TEST(smb2_error_map_num); 129 126 #endif
+14 -4
fs/smb/client/smb2ops.c
··· 628 628 struct smb_sockaddr_in6 *p6; 629 629 struct cifs_server_iface *info = NULL, *iface = NULL, *niface = NULL; 630 630 struct cifs_server_iface tmp_iface; 631 + __be16 port; 631 632 ssize_t bytes_left; 632 633 size_t next = 0; 633 634 int nb_iface = 0; ··· 663 662 goto out; 664 663 } 665 664 665 + spin_lock(&ses->server->srv_lock); 666 + if (ses->server->dstaddr.ss_family == AF_INET) 667 + port = ((struct sockaddr_in *)&ses->server->dstaddr)->sin_port; 668 + else if (ses->server->dstaddr.ss_family == AF_INET6) 669 + port = ((struct sockaddr_in6 *)&ses->server->dstaddr)->sin6_port; 670 + else 671 + port = cpu_to_be16(CIFS_PORT); 672 + spin_unlock(&ses->server->srv_lock); 673 + 666 674 while (bytes_left >= (ssize_t)sizeof(*p)) { 667 675 memset(&tmp_iface, 0, sizeof(tmp_iface)); 668 676 /* default to 1Gbps when link speed is unset */ ··· 692 682 memcpy(&addr4->sin_addr, &p4->IPv4Address, 4); 693 683 694 684 /* [MS-SMB2] 2.2.32.5.1.1 Clients MUST ignore these */ 695 - addr4->sin_port = cpu_to_be16(CIFS_PORT); 685 + addr4->sin_port = port; 696 686 697 687 cifs_dbg(FYI, "%s: ipv4 %pI4\n", __func__, 698 688 &addr4->sin_addr); ··· 706 696 /* [MS-SMB2] 2.2.32.5.1.2 Clients MUST ignore these */ 707 697 addr6->sin6_flowinfo = 0; 708 698 addr6->sin6_scope_id = 0; 709 - addr6->sin6_port = cpu_to_be16(CIFS_PORT); 699 + addr6->sin6_port = port; 710 700 711 701 cifs_dbg(FYI, "%s: ipv6 %pI6\n", __func__, 712 702 &addr6->sin6_addr); ··· 3362 3352 struct cifsFileInfo *open_file = NULL; 3363 3353 3364 3354 if (inode && !(info & SACL_SECINFO)) 3365 - open_file = find_readable_file(CIFS_I(inode), true); 3355 + open_file = find_readable_file(CIFS_I(inode), FIND_FSUID_ONLY); 3366 3356 if (!open_file || (info & SACL_SECINFO)) 3367 3357 return get_smb2_acl_by_path(cifs_sb, path, pacllen, info); 3368 3358 ··· 3908 3898 * some servers (Windows2016) will not reflect recent writes in 3909 3899 * QUERY_ALLOCATED_RANGES until SMB2_flush is called. 3910 3900 */ 3911 - wrcfile = find_writable_file(cifsi, FIND_WR_ANY); 3901 + wrcfile = find_writable_file(cifsi, FIND_ANY); 3912 3902 if (wrcfile) { 3913 3903 filemap_write_and_wait(inode->i_mapping); 3914 3904 smb2_flush_file(xid, tcon, &wrcfile->fid);
+4 -1
fs/smb/client/smb2pdu.c
··· 5307 5307 5308 5308 memset(&rqst, 0, sizeof(struct smb_rqst)); 5309 5309 rqst.rq_iov = iov; 5310 - rqst.rq_nvec = n_vec + 1; 5310 + /* iov[0] is the SMB header; move payload to rq_iter for encryption safety */ 5311 + rqst.rq_nvec = 1; 5312 + iov_iter_kvec(&rqst.rq_iter, ITER_SOURCE, &iov[1], n_vec, 5313 + io_parms->length); 5311 5314 5312 5315 if (retries) { 5313 5316 /* Back-off before retry */