Skip to content

Commit 307e14c

Browse files
committed
Merge tag '6.3-rc-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs client updates from Steve French: "The largest subset of this is from David Howells et al: making the cifs/smb3 driver pass iov_iters down to the lowest layers, directly to the network transport rather than passing lists of pages around, helping multiple areas: - Pin user pages, thereby fixing the race between concurrent DIO read and fork, where the pages containing the DIO read buffer may end up belonging to the child process and not the parent - with the result that the parent might not see the retrieved data. - cifs shouldn't take refs on pages extracted from non-user-backed iterators (eg. KVEC). With these changes, cifs will apply the appropriate cleanup. - Making it easier to transition to using folios in cifs rather than pages by dealing with them through BVEC and XARRAY iterators. - Allowing cifs to use the new splice function The remainder are: - fixes for stable, including various fixes for uninitialized memory, wrong length field causing mount issue to very old servers, important directory lease fixes and reconnect fixes - cleanups (unused code removal, change one element array usage, and a change form strtobool to kstrtobool, and Kconfig cleanups) - SMBDIRECT (RDMA) fixes including iov_iter integration and UAF fixes - reconnect fixes - multichannel fixes, including improving channel allocation (to least used channel) - remove the last use of lock_page_killable by moving to folio_lock_killable" * tag '6.3-rc-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: (46 commits) update internal module version number for cifs.ko cifs: update ip_addr for ses only for primary chan setup cifs: use tcon allocation functions even for dummy tcon cifs: use the least loaded channel for sending requests cifs: DIO to/from KVEC-type iterators should now work cifs: Remove unused code cifs: Build the RDMA SGE list directly from an iterator cifs: Change the I/O paths to use an iterator rather than a page list cifs: Add a function to read into an iter from a socket cifs: Add some helper functions cifs: Add a function to Hash the contents of an iterator cifs: Add a function to build an RDMA SGE list from an iterator netfs: Add a function to extract an iterator into a scatterlist netfs: Add a function to extract a UBUF or IOVEC into a BVEC iterator cifs: Implement splice_read to pass down ITER_BVEC not ITER_PIPE splice: Export filemap/direct_splice_read() iov_iter: Add a function to extract a page list from an iterator iov_iter: Define flags to qualify page extraction. splice: Add a func to do a splice from an O_DIRECT file without ITER_PIPE splice: Add a func to do a splice from a buffered file without ITER_PIPE ...
2 parents d8ca6db + fdbf807 commit 307e14c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+3218
-2350
lines changed

block/bio.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,11 +1236,11 @@ static int bio_iov_add_zone_append_page(struct bio *bio, struct page *page,
12361236
*/
12371237
static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
12381238
{
1239+
iov_iter_extraction_t extraction_flags = 0;
12391240
unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt;
12401241
unsigned short entries_left = bio->bi_max_vecs - bio->bi_vcnt;
12411242
struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt;
12421243
struct page **pages = (struct page **)bv;
1243-
unsigned int gup_flags = 0;
12441244
ssize_t size, left;
12451245
unsigned len, i = 0;
12461246
size_t offset, trim;
@@ -1255,7 +1255,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
12551255
pages += entries_left * (PAGE_PTRS_PER_BVEC - 1);
12561256

12571257
if (bio->bi_bdev && blk_queue_pci_p2pdma(bio->bi_bdev->bd_disk->queue))
1258-
gup_flags |= FOLL_PCI_P2PDMA;
1258+
extraction_flags |= ITER_ALLOW_P2PDMA;
12591259

12601260
/*
12611261
* Each segment in the iov is required to be a block size multiple.
@@ -1266,7 +1266,7 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
12661266
*/
12671267
size = iov_iter_get_pages(iter, pages,
12681268
UINT_MAX - bio->bi_iter.bi_size,
1269-
nr_pages, &offset, gup_flags);
1269+
nr_pages, &offset, extraction_flags);
12701270
if (unlikely(size <= 0))
12711271
return size ? size : -EFAULT;
12721272

block/blk-map.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,9 @@ static struct bio *blk_rq_map_bio_alloc(struct request *rq,
264264
static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
265265
gfp_t gfp_mask)
266266
{
267+
iov_iter_extraction_t extraction_flags = 0;
267268
unsigned int max_sectors = queue_max_hw_sectors(rq->q);
268269
unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS);
269-
unsigned int gup_flags = 0;
270270
struct bio *bio;
271271
int ret;
272272
int j;
@@ -279,7 +279,7 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
279279
return -ENOMEM;
280280

281281
if (blk_queue_pci_p2pdma(rq->q))
282-
gup_flags |= FOLL_PCI_P2PDMA;
282+
extraction_flags |= ITER_ALLOW_P2PDMA;
283283

284284
while (iov_iter_count(iter)) {
285285
struct page **pages, *stack_pages[UIO_FASTIOV];
@@ -290,10 +290,10 @@ static int bio_map_user_iov(struct request *rq, struct iov_iter *iter,
290290
if (nr_vecs <= ARRAY_SIZE(stack_pages)) {
291291
pages = stack_pages;
292292
bytes = iov_iter_get_pages(iter, pages, LONG_MAX,
293-
nr_vecs, &offs, gup_flags);
293+
nr_vecs, &offs, extraction_flags);
294294
} else {
295295
bytes = iov_iter_get_pages_alloc(iter, &pages,
296-
LONG_MAX, &offs, gup_flags);
296+
LONG_MAX, &offs, extraction_flags);
297297
}
298298
if (unlikely(bytes <= 0)) {
299299
ret = bytes ? bytes : -EFAULT;

fs/cifs/Kconfig

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,40 +18,38 @@ config CIFS
1818
select DNS_RESOLVER
1919
select ASN1
2020
select OID_REGISTRY
21+
select NETFS_SUPPORT
2122
help
22-
This is the client VFS module for the SMB3 family of NAS protocols,
23-
(including support for the most recent, most secure dialect SMB3.1.1)
24-
as well as for earlier dialects such as SMB2.1, SMB2 and the older
25-
Common Internet File System (CIFS) protocol. CIFS was the successor
26-
to the original dialect, the Server Message Block (SMB) protocol, the
27-
native file sharing mechanism for most early PC operating systems.
28-
29-
The SMB3 protocol is supported by most modern operating systems
30-
and NAS appliances (e.g. Samba, Windows 10, Windows Server 2016,
31-
MacOS) and even in the cloud (e.g. Microsoft Azure).
32-
The older CIFS protocol was included in Windows NT4, 2000 and XP (and
33-
later) as well by Samba (which provides excellent CIFS and SMB3
34-
server support for Linux and many other operating systems). Use of
35-
dialects older than SMB2.1 is often discouraged on public networks.
23+
This is the client VFS module for the SMB3 family of network file
24+
protocols (including the most recent, most secure dialect SMB3.1.1).
25+
This module also includes support for earlier dialects such as
26+
SMB2.1, SMB2 and even the old Common Internet File System (CIFS)
27+
protocol. CIFS was the successor to the original network filesystem
28+
protocol, Server Message Block (SMB ie SMB1), the native file sharing
29+
mechanism for most early PC operating systems.
30+
31+
The SMB3.1.1 protocol is supported by most modern operating systems
32+
and NAS appliances (e.g. Samba, Windows 11, Windows Server 2022,
33+
MacOS) and even in the cloud (e.g. Microsoft Azure) and also by the
34+
Linux kernel server, ksmbd. Support for the older CIFS protocol was
35+
included in Windows NT4, 2000 and XP (and later). Use of dialects
36+
older than SMB2.1 is often discouraged on public networks.
3637
This module also provides limited support for OS/2 and Windows ME
3738
and similar very old servers.
3839

39-
This module provides an advanced network file system client
40-
for mounting to SMB3 (and CIFS) compliant servers. It includes
41-
support for DFS (hierarchical name space), secure per-user
42-
session establishment via Kerberos or NTLM or NTLMv2, RDMA
43-
(smbdirect), advanced security features, per-share encryption,
44-
directory leases, safe distributed caching (oplock), optional packet
45-
signing, Unicode and other internationalization improvements.
40+
This module provides an advanced network file system client for
41+
mounting to SMB3 (and CIFS) compliant servers. It includes support
42+
for DFS (hierarchical name space), secure per-user session
43+
establishment via Kerberos or NTLMv2, RDMA (smbdirect), advanced
44+
security features, per-share encryption, packet-signing, snapshots,
45+
directory leases, safe distributed caching (leases), multichannel,
46+
Unicode and other internationalization improvements.
4647

4748
In general, the default dialects, SMB3 and later, enable better
4849
performance, security and features, than would be possible with CIFS.
49-
Note that when mounting to Samba, due to the CIFS POSIX extensions,
50-
CIFS mounts can provide slightly better POSIX compatibility
51-
than SMB3 mounts. SMB2/SMB3 mount options are also
52-
slightly simpler (compared to CIFS) due to protocol improvements.
5350

54-
If you need to mount to Samba, Azure, Macs or Windows from this machine, say Y.
51+
If you need to mount to Samba, Azure, ksmbd, Macs or Windows from this
52+
machine, say Y.
5553

5654
config CIFS_STATS2
5755
bool "Extended statistics"
@@ -111,12 +109,12 @@ config CIFS_POSIX
111109
depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY && CIFS_XATTR
112110
help
113111
Enabling this option will cause the cifs client to attempt to
114-
negotiate a newer dialect with servers, such as Samba 3.0.5
115-
or later, that optionally can handle more POSIX like (rather
116-
than Windows like) file behavior. It also enables
117-
support for POSIX ACLs (getfacl and setfacl) to servers
118-
(such as Samba 3.10 and later) which can negotiate
119-
CIFS POSIX ACL support. If unsure, say N.
112+
negotiate a feature of the older cifs dialect with servers, such as
113+
Samba 3.0.5 or later, that optionally can handle more POSIX like
114+
(rather than Windows like) file behavior. It also enables support
115+
for POSIX ACLs (getfacl and setfacl) to servers (such as Samba 3.10
116+
and later) which can negotiate CIFS POSIX ACL support. This config
117+
option is not needed when mounting with SMB3.1.1. If unsure, say N.
120118

121119
config CIFS_DEBUG
122120
bool "Enable CIFS debugging routines"
@@ -178,6 +176,8 @@ config CIFS_NFSD_EXPORT
178176
help
179177
Allows NFS server to export a CIFS mounted share (nfsd over cifs)
180178

179+
if CIFS
180+
181181
config CIFS_SMB_DIRECT
182182
bool "SMB Direct support"
183183
depends on CIFS=m && INFINIBAND && INFINIBAND_ADDR_TRANS || CIFS=y && INFINIBAND=y && INFINIBAND_ADDR_TRANS=y
@@ -201,3 +201,5 @@ config CIFS_ROOT
201201
Enables root file system support over SMB protocol.
202202

203203
Most people say N here.
204+
205+
endif

fs/cifs/cached_dir.c

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
static struct cached_fid *init_cached_dir(const char *path);
1616
static void free_cached_dir(struct cached_fid *cfid);
17+
static void smb2_close_cached_fid(struct kref *ref);
1718

1819
static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
1920
const char *path,
@@ -181,12 +182,13 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
181182
rqst[0].rq_iov = open_iov;
182183
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
183184

184-
oparms.tcon = tcon;
185-
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE);
186-
oparms.desired_access = FILE_READ_ATTRIBUTES;
187-
oparms.disposition = FILE_OPEN;
188-
oparms.fid = pfid;
189-
oparms.reconnect = false;
185+
oparms = (struct cifs_open_parms) {
186+
.tcon = tcon,
187+
.create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE),
188+
.desired_access = FILE_READ_ATTRIBUTES,
189+
.disposition = FILE_OPEN,
190+
.fid = pfid,
191+
};
190192

191193
rc = SMB2_open_init(tcon, server,
192194
&rqst[0], &oplock, &oparms, utf16_path);
@@ -220,8 +222,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
220222
}
221223
goto oshr_free;
222224
}
223-
224-
atomic_inc(&tcon->num_remote_opens);
225+
cfid->tcon = tcon;
226+
cfid->is_open = true;
225227

226228
o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
227229
oparms.fid->persistent_fid = o_rsp->PersistentFileId;
@@ -233,12 +235,12 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
233235
if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
234236
goto oshr_free;
235237

236-
237238
smb2_parse_contexts(server, o_rsp,
238239
&oparms.fid->epoch,
239240
oparms.fid->lease_key, &oplock,
240241
NULL, NULL);
241-
242+
if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
243+
goto oshr_free;
242244
qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
243245
if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
244246
goto oshr_free;
@@ -259,9 +261,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
259261
}
260262
}
261263
cfid->dentry = dentry;
262-
cfid->tcon = tcon;
263264
cfid->time = jiffies;
264-
cfid->is_open = true;
265265
cfid->has_lease = true;
266266

267267
oshr_free:
@@ -271,7 +271,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
271271
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
272272
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
273273
spin_lock(&cfids->cfid_list_lock);
274-
if (!cfid->has_lease) {
274+
if (rc && !cfid->has_lease) {
275275
if (cfid->on_list) {
276276
list_del(&cfid->entry);
277277
cfid->on_list = false;
@@ -280,13 +280,27 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
280280
rc = -ENOENT;
281281
}
282282
spin_unlock(&cfids->cfid_list_lock);
283+
if (!rc && !cfid->has_lease) {
284+
/*
285+
* We are guaranteed to have two references at this point.
286+
* One for the caller and one for a potential lease.
287+
* Release the Lease-ref so that the directory will be closed
288+
* when the caller closes the cached handle.
289+
*/
290+
kref_put(&cfid->refcount, smb2_close_cached_fid);
291+
}
283292
if (rc) {
293+
if (cfid->is_open)
294+
SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
295+
cfid->fid.volatile_fid);
284296
free_cached_dir(cfid);
285297
cfid = NULL;
286298
}
287299

288-
if (rc == 0)
300+
if (rc == 0) {
289301
*ret_cfid = cfid;
302+
atomic_inc(&tcon->num_remote_opens);
303+
}
290304

291305
return rc;
292306
}
@@ -335,6 +349,7 @@ smb2_close_cached_fid(struct kref *ref)
335349
if (cfid->is_open) {
336350
SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
337351
cfid->fid.volatile_fid);
352+
atomic_dec(&cfid->tcon->num_remote_opens);
338353
}
339354

340355
free_cached_dir(cfid);

fs/cifs/cifs_debug.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/fs.h>
99
#include <linux/string.h>
1010
#include <linux/ctype.h>
11+
#include <linux/kstrtox.h>
1112
#include <linux/module.h>
1213
#include <linux/proc_fs.h>
1314
#include <linux/uaccess.h>
@@ -455,8 +456,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
455456

456457
spin_lock(&ses->iface_lock);
457458
if (ses->iface_count)
458-
seq_printf(m, "\n\n\tServer interfaces: %zu",
459-
ses->iface_count);
459+
seq_printf(m, "\n\n\tServer interfaces: %zu"
460+
"\tLast updated: %lu seconds ago",
461+
ses->iface_count,
462+
(jiffies - ses->iface_last_update) / HZ);
460463
j = 0;
461464
list_for_each_entry(iface, &ses->iface_list,
462465
iface_head) {
@@ -787,7 +790,7 @@ static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
787790
rc = get_user(c[0], buffer);
788791
if (rc)
789792
return rc;
790-
if (strtobool(c, &bv) == 0)
793+
if (kstrtobool(c, &bv) == 0)
791794
cifsFYI = bv;
792795
else if ((c[0] > '1') && (c[0] <= '9'))
793796
cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings */
@@ -947,7 +950,7 @@ static ssize_t cifs_security_flags_proc_write(struct file *file,
947950

948951
if (count < 3) {
949952
/* single char or single char followed by null */
950-
if (strtobool(flags_string, &bv) == 0) {
953+
if (kstrtobool(flags_string, &bv) == 0) {
951954
global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF;
952955
return count;
953956
} else if (!isdigit(flags_string[0])) {

fs/cifs/cifs_spnego.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct cifs_spnego_msg {
2424
uint32_t flags;
2525
uint32_t sesskey_len;
2626
uint32_t secblob_len;
27-
uint8_t data[1];
27+
uint8_t data[];
2828
};
2929

3030
#ifdef __KERNEL__

fs/cifs/cifsacl.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,14 +1428,15 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
14281428
tcon = tlink_tcon(tlink);
14291429
xid = get_xid();
14301430

1431-
oparms.tcon = tcon;
1432-
oparms.cifs_sb = cifs_sb;
1433-
oparms.desired_access = READ_CONTROL;
1434-
oparms.create_options = cifs_create_options(cifs_sb, 0);
1435-
oparms.disposition = FILE_OPEN;
1436-
oparms.path = path;
1437-
oparms.fid = &fid;
1438-
oparms.reconnect = false;
1431+
oparms = (struct cifs_open_parms) {
1432+
.tcon = tcon,
1433+
.cifs_sb = cifs_sb,
1434+
.desired_access = READ_CONTROL,
1435+
.create_options = cifs_create_options(cifs_sb, 0),
1436+
.disposition = FILE_OPEN,
1437+
.path = path,
1438+
.fid = &fid,
1439+
};
14391440

14401441
rc = CIFS_open(xid, &oparms, &oplock, NULL);
14411442
if (!rc) {
@@ -1494,14 +1495,15 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
14941495
else
14951496
access_flags = WRITE_DAC;
14961497

1497-
oparms.tcon = tcon;
1498-
oparms.cifs_sb = cifs_sb;
1499-
oparms.desired_access = access_flags;
1500-
oparms.create_options = cifs_create_options(cifs_sb, 0);
1501-
oparms.disposition = FILE_OPEN;
1502-
oparms.path = path;
1503-
oparms.fid = &fid;
1504-
oparms.reconnect = false;
1498+
oparms = (struct cifs_open_parms) {
1499+
.tcon = tcon,
1500+
.cifs_sb = cifs_sb,
1501+
.desired_access = access_flags,
1502+
.create_options = cifs_create_options(cifs_sb, 0),
1503+
.disposition = FILE_OPEN,
1504+
.path = path,
1505+
.fid = &fid,
1506+
};
15051507

15061508
rc = CIFS_open(xid, &oparms, &oplock, NULL);
15071509
if (rc) {

0 commit comments

Comments
 (0)