mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Five smb3 client fixes, most also for stable
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmXP2xEACgkQiiy9cAdy T1EGMwwAiclDnZEtlHRK80Kmncnk7JaLnmHqLLfgIocVo0MDnaUrJVftj43F2OP/ za1uJfI9uM+lgM+vbEjldLxMf8yVnt6MpgzwXBZftppFpVPAwiwvGh4m4RAKreUj SnE/WEINjj3p3dTJdnKup3Ff2hDXm9VBLpGPWwUTQ0RNWROO7hUtnTyeGRCZKEgy uCVVU8AS5DAvBpuWZ+K0zG/omts42fP399GkQUD5Pz8DgOaFCMfQU33/zPFQEkPX idnXH3KL4SHTFvytTTRCgHGg2x5MLersC6zYqwlgTD9YkGpr1UbuIRYvVO793Bek VqhQTsnSnQSTuJ5lCH7elcLhF8XPF/qM+sRw/OoidgUwMMDjN0jMkwxBk+MX8Gw2 6lJfWAjTjRhanF6s501fEGd4YPFIBAysmW1XLiS12ot05s5k9D7sp+EjklPsSxvX VrHHtcElY9rwh5sk7gZsmBl2U2x8k4ZvZeq6dIqQAvg+oQAbi9mTFrGuxsC3jD/x LP2cFzhW =v3wq -----END PGP SIGNATURE----- Merge tag '6.8-rc4-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull smb client fixes from Steve French: "Five smb3 client fixes, most also for stable: - Two multichannel fixes (one to fix potential handle leak on retry) - Work around possible serious data corruption (due to change in folios in 6.3, for cases when non standard maximum write size negotiated) - Symlink creation fix - Multiuser automount fix" * tag '6.8-rc4-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb: Fix regression in writes when non-standard maximum write size negotiated smb: client: handle path separator of created SMB symlinks smb: client: set correct id, uid and cruid for multiuser automounts cifs: update the same create_guid on replay cifs: fix underflow in parse_server_interfaces()
This commit is contained in:
commit
55f626f2d0
@ -242,6 +242,7 @@ replay_again:
|
||||
.desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES,
|
||||
.disposition = FILE_OPEN,
|
||||
.fid = pfid,
|
||||
.replay = !!(retries),
|
||||
};
|
||||
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
|
@ -1378,6 +1378,7 @@ struct cifs_open_parms {
|
||||
struct cifs_fid *fid;
|
||||
umode_t mode;
|
||||
bool reconnect:1;
|
||||
bool replay:1; /* indicates that this open is for a replay */
|
||||
};
|
||||
|
||||
struct cifs_fid {
|
||||
|
@ -3444,8 +3444,18 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
|
||||
* the user on mount
|
||||
*/
|
||||
if ((cifs_sb->ctx->wsize == 0) ||
|
||||
(cifs_sb->ctx->wsize > server->ops->negotiate_wsize(tcon, ctx)))
|
||||
cifs_sb->ctx->wsize = server->ops->negotiate_wsize(tcon, ctx);
|
||||
(cifs_sb->ctx->wsize > server->ops->negotiate_wsize(tcon, ctx))) {
|
||||
cifs_sb->ctx->wsize =
|
||||
round_down(server->ops->negotiate_wsize(tcon, ctx), PAGE_SIZE);
|
||||
/*
|
||||
* in the very unlikely event that the server sent a max write size under PAGE_SIZE,
|
||||
* (which would get rounded down to 0) then reset wsize to absolute minimum eg 4096
|
||||
*/
|
||||
if (cifs_sb->ctx->wsize == 0) {
|
||||
cifs_sb->ctx->wsize = PAGE_SIZE;
|
||||
cifs_dbg(VFS, "wsize too small, reset to minimum ie PAGE_SIZE, usually 4096\n");
|
||||
}
|
||||
}
|
||||
if ((cifs_sb->ctx->rsize == 0) ||
|
||||
(cifs_sb->ctx->rsize > server->ops->negotiate_rsize(tcon, ctx)))
|
||||
cifs_sb->ctx->rsize = server->ops->negotiate_rsize(tcon, ctx);
|
||||
|
@ -1111,6 +1111,17 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
|
||||
case Opt_wsize:
|
||||
ctx->wsize = result.uint_32;
|
||||
ctx->got_wsize = true;
|
||||
if (ctx->wsize % PAGE_SIZE != 0) {
|
||||
ctx->wsize = round_down(ctx->wsize, PAGE_SIZE);
|
||||
if (ctx->wsize == 0) {
|
||||
ctx->wsize = PAGE_SIZE;
|
||||
cifs_dbg(VFS, "wsize too small, reset to minimum %ld\n", PAGE_SIZE);
|
||||
} else {
|
||||
cifs_dbg(VFS,
|
||||
"wsize rounded down to %d to multiple of PAGE_SIZE %ld\n",
|
||||
ctx->wsize, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Opt_acregmax:
|
||||
ctx->acregmax = HZ * result.uint_32;
|
||||
|
@ -168,6 +168,21 @@ static char *automount_fullpath(struct dentry *dentry, void *page)
|
||||
return s;
|
||||
}
|
||||
|
||||
static void fs_context_set_ids(struct smb3_fs_context *ctx)
|
||||
{
|
||||
kuid_t uid = current_fsuid();
|
||||
kgid_t gid = current_fsgid();
|
||||
|
||||
if (ctx->multiuser) {
|
||||
if (!ctx->uid_specified)
|
||||
ctx->linux_uid = uid;
|
||||
if (!ctx->gid_specified)
|
||||
ctx->linux_gid = gid;
|
||||
}
|
||||
if (!ctx->cruid_specified)
|
||||
ctx->cred_uid = uid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a vfsmount that we can automount
|
||||
*/
|
||||
@ -205,6 +220,7 @@ static struct vfsmount *cifs_do_automount(struct path *path)
|
||||
tmp.leaf_fullpath = NULL;
|
||||
tmp.UNC = tmp.prepath = NULL;
|
||||
tmp.dfs_root_ses = NULL;
|
||||
fs_context_set_ids(&tmp);
|
||||
|
||||
rc = smb3_fs_context_dup(ctx, &tmp);
|
||||
if (rc) {
|
||||
|
@ -619,7 +619,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (bytes_left >= sizeof(*p)) {
|
||||
while (bytes_left >= (ssize_t)sizeof(*p)) {
|
||||
memset(&tmp_iface, 0, sizeof(tmp_iface));
|
||||
tmp_iface.speed = le64_to_cpu(p->LinkSpeed);
|
||||
tmp_iface.rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0;
|
||||
@ -1204,6 +1204,7 @@ replay_again:
|
||||
.disposition = FILE_OPEN,
|
||||
.create_options = cifs_create_options(cifs_sb, 0),
|
||||
.fid = &fid,
|
||||
.replay = !!(retries),
|
||||
};
|
||||
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
@ -1569,6 +1570,7 @@ replay_again:
|
||||
.disposition = FILE_OPEN,
|
||||
.create_options = cifs_create_options(cifs_sb, create_options),
|
||||
.fid = &fid,
|
||||
.replay = !!(retries),
|
||||
};
|
||||
|
||||
if (qi.flags & PASSTHRU_FSCTL) {
|
||||
@ -2295,6 +2297,7 @@ replay_again:
|
||||
.disposition = FILE_OPEN,
|
||||
.create_options = cifs_create_options(cifs_sb, 0),
|
||||
.fid = fid,
|
||||
.replay = !!(retries),
|
||||
};
|
||||
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
@ -2681,6 +2684,7 @@ replay_again:
|
||||
.disposition = FILE_OPEN,
|
||||
.create_options = cifs_create_options(cifs_sb, 0),
|
||||
.fid = &fid,
|
||||
.replay = !!(retries),
|
||||
};
|
||||
|
||||
rc = SMB2_open_init(tcon, server,
|
||||
@ -5213,7 +5217,7 @@ static int smb2_create_reparse_symlink(const unsigned int xid,
|
||||
struct inode *new;
|
||||
struct kvec iov;
|
||||
__le16 *path;
|
||||
char *sym;
|
||||
char *sym, sep = CIFS_DIR_SEP(cifs_sb);
|
||||
u16 len, plen;
|
||||
int rc = 0;
|
||||
|
||||
@ -5227,7 +5231,8 @@ static int smb2_create_reparse_symlink(const unsigned int xid,
|
||||
.symlink_target = sym,
|
||||
};
|
||||
|
||||
path = cifs_convert_path_to_utf16(symname, cifs_sb);
|
||||
convert_delimiter(sym, sep);
|
||||
path = cifs_convert_path_to_utf16(sym, cifs_sb);
|
||||
if (!path) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
@ -5250,7 +5255,10 @@ static int smb2_create_reparse_symlink(const unsigned int xid,
|
||||
buf->PrintNameLength = cpu_to_le16(plen);
|
||||
memcpy(buf->PathBuffer, path, plen);
|
||||
buf->Flags = cpu_to_le32(*symname != '/' ? SYMLINK_FLAG_RELATIVE : 0);
|
||||
if (*sym != sep)
|
||||
buf->Flags = cpu_to_le32(SYMLINK_FLAG_RELATIVE);
|
||||
|
||||
convert_delimiter(sym, '/');
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = len;
|
||||
new = smb2_get_reparse_inode(&data, inode->i_sb, xid,
|
||||
|
@ -2404,8 +2404,13 @@ create_durable_v2_buf(struct cifs_open_parms *oparms)
|
||||
*/
|
||||
buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout);
|
||||
buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
|
||||
generate_random_uuid(buf->dcontext.CreateGuid);
|
||||
memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
|
||||
|
||||
/* for replay, we should not overwrite the existing create guid */
|
||||
if (!oparms->replay) {
|
||||
generate_random_uuid(buf->dcontext.CreateGuid);
|
||||
memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
|
||||
} else
|
||||
memcpy(buf->dcontext.CreateGuid, pfid->create_guid, 16);
|
||||
|
||||
/* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */
|
||||
buf->Name[0] = 'D';
|
||||
@ -3142,6 +3147,7 @@ replay_again:
|
||||
/* reinitialize for possible replay */
|
||||
flags = 0;
|
||||
server = cifs_pick_channel(ses);
|
||||
oparms->replay = !!(retries);
|
||||
|
||||
cifs_dbg(FYI, "create/open\n");
|
||||
if (!ses || !server)
|
||||
|
Loading…
Reference in New Issue
Block a user