three small smb3 client fixes

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmRDSFEACgkQiiy9cAdy
 T1FUiQwAr0/Di4S4U5XDZNDdW9/4qFqI95ciShsIFb6cXtMQeauTImOp5zDEaW2x
 mn31RZSIMDK+Ljximh4W2phH+5k47K51tVXetWCVOHIPBc1h4AUAz5XmhChtirJ9
 seqhPx2wIi+4TH3gvKkc8xxmZ6HMfZ+F7nuc72eZ1rnO91VoLRywpACItKO2Q8Vu
 XSGMgjiaP0KshyxIcBwKXxHjnaOBF6nBBENU/sHkNZNRngzi/+Xcr371eijbs8Ay
 hk7RPnH04uOYwkFs+9gFpSyYtkdn9iTaPScYWE9UDTeZl8xuQJnGlGXQ1CEZHfkh
 OBzb2/UCX77ggnuFyukP8e5ZsrdGEaotjYgmsb7s7BO9eqAcBRp31SKhIbvIZvTG
 IBLBtWFNSvdoKk1EUvu2iKHxcGcZ3EFjLTmx5pwcAwmBLp+UM/i+IcxvS+b2uPif
 mVIzsXPRI6yi9uJ7PPqtBlkhNrwNk4cfs1hkeXOqN7XGBaQjx89wydMGJDF9otse
 BsNDDXmF
 =KXCn
 -----END PGP SIGNATURE-----

Merge tag '6.3-rc7-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:
 "Three small smb3 client fixes:

   - two important fixes for unbuffered read regression with the
     iov_iter changes (e.g. read soon after mount in some multichannel
     scenarios)

   - DFS prefix path fix (also for stable)"

* tag '6.3-rc7-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: Reapply lost fix from commit 30b2b2196d
  cifs: Fix unbuffered read
  cifs: avoid dup prefix path in dfs_get_automount_devname()
This commit is contained in:
Linus Torvalds 2023-04-22 09:18:35 -07:00
commit 84ebdb8e0d
4 changed files with 24 additions and 14 deletions

View File

@ -171,8 +171,6 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path)
mnt = ERR_CAST(full_path); mnt = ERR_CAST(full_path);
goto out; goto out;
} }
convert_delimiter(full_path, '/');
cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path); cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path);
tmp = *cur_ctx; tmp = *cur_ctx;

View File

@ -34,19 +34,33 @@ static inline int dfs_get_referral(struct cifs_mount_ctx *mnt_ctx, const char *p
cifs_remap(cifs_sb), path, ref, tl); cifs_remap(cifs_sb), path, ref, tl);
} }
/* Return DFS full path out of a dentry set for automount */
static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page) static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
{ {
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct TCP_Server_Info *server = tcon->ses->server; struct TCP_Server_Info *server = tcon->ses->server;
size_t len;
char *s;
if (unlikely(!server->origin_fullpath)) if (unlikely(!server->origin_fullpath))
return ERR_PTR(-EREMOTE); return ERR_PTR(-EREMOTE);
return __build_path_from_dentry_optional_prefix(dentry, page, s = dentry_path_raw(dentry, page, PATH_MAX);
server->origin_fullpath, if (IS_ERR(s))
strlen(server->origin_fullpath), return s;
true); /* for root, we want "" */
if (!s[1])
s++;
len = strlen(server->origin_fullpath);
if (s < (char *)page + len)
return ERR_PTR(-ENAMETOOLONG);
s -= len;
memcpy(s, server->origin_fullpath, len);
convert_delimiter(s, '/');
return s;
} }
static inline void dfs_put_root_smb_sessions(struct list_head *head) static inline void dfs_put_root_smb_sessions(struct list_head *head)

View File

@ -4010,7 +4010,6 @@ static void
collect_uncached_read_data(struct cifs_aio_ctx *ctx) collect_uncached_read_data(struct cifs_aio_ctx *ctx)
{ {
struct cifs_readdata *rdata, *tmp; struct cifs_readdata *rdata, *tmp;
struct iov_iter *to = &ctx->iter;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
int rc; int rc;
@ -4076,9 +4075,6 @@ again:
kref_put(&rdata->refcount, cifs_readdata_release); kref_put(&rdata->refcount, cifs_readdata_release);
} }
if (!ctx->direct_io)
ctx->total_len = ctx->len - iov_iter_count(to);
/* mask nodata case */ /* mask nodata case */
if (rc == -ENODATA) if (rc == -ENODATA)
rc = 0; rc = 0;

View File

@ -4180,10 +4180,12 @@ smb2_readv_callback(struct mid_q_entry *mid)
struct smb2_hdr *shdr = struct smb2_hdr *shdr =
(struct smb2_hdr *)rdata->iov[0].iov_base; (struct smb2_hdr *)rdata->iov[0].iov_base;
struct cifs_credits credits = { .value = 0, .instance = 0 }; struct cifs_credits credits = { .value = 0, .instance = 0 };
struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], .rq_nvec = 1 };
.rq_nvec = 1,
.rq_iter = rdata->iter, if (rdata->got_bytes) {
.rq_iter_size = iov_iter_count(&rdata->iter), }; rqst.rq_iter = rdata->iter;
rqst.rq_iter_size = iov_iter_count(&rdata->iter);
};
WARN_ONCE(rdata->server != mid->server, WARN_ONCE(rdata->server != mid->server,
"rdata server %p != mid server %p", "rdata server %p != mid server %p",