mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
three smb3 client fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmhNnYsACgkQiiy9cAdy T1HNMwv+N3G4LGJljr25eIk6ycFA5HLH/XCCo/BjUiue1MBPIDqckpEmnM1e583+ cDnW/h01R8TLpM5yYppZSymvEoVfErAOsGlCEb+a1CSwbnK4RyGQfowNgJYMUsvA pJDFjqwfZjXoPMz/KO4WKBkrOqXgo41aAVwCm4b4N/KNBz06G52IX1PD9P8gaech LLts/3JxX6oUU/w06fCGqqPwtf3qa/EIOBD9qaAQ3SPLXCLdpdd6szuLcux5yWNf ncXB//fZZFpT4Ylb46bexENHV4Q664KdI6f11+IcaR1kgvEhSrgwpXb/c4G3wmk4 wl0+Qn7kYdjcPCLtAkmo2LzcaDzLN3I9I5zYl+y2r7MiUixPzN27oYr6bNE4M+Z8 FIaQ3VOtpY7jHnvILjtjTP2xKF/Oo1KgeqHS+yBTkp7TvUPY8AWG/em+mzb+ZShv 9zCTjdt8k6taIh1uaZIDLd5tSQAE2wN20XjBbV4CHeM6z6GoFneXNCeZAf84+xRe pSLQpof1 =QF6Q -----END PGP SIGNATURE----- Merge tag 'v6.16-rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull smb client fixes from Steve French: - SMB3.1.1 POSIX extensions fix for char remapping - Fix for repeated directory listings when directory leases enabled - deferred close handle reuse fix * tag 'v6.16-rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: smb: improve directory cache reuse for readdir operations smb: client: fix perf regression with deferred closes smb: client: disable path remapping with POSIX extensions
This commit is contained in:
commit
8c6bc74c7f
|
@ -270,6 +270,8 @@ configured for Unix Extensions (and the client has not disabled
|
|||
illegal Windows/NTFS/SMB characters to a remap range (this mount parameter
|
||||
is the default for SMB3). This remap (``mapposix``) range is also
|
||||
compatible with Mac (and "Services for Mac" on some older Windows).
|
||||
When POSIX Extensions for SMB 3.1.1 are negotiated, remapping is automatically
|
||||
disabled.
|
||||
|
||||
CIFS VFS Mount Options
|
||||
======================
|
||||
|
|
|
@ -21,9 +21,9 @@ struct cached_dirent {
|
|||
struct cached_dirents {
|
||||
bool is_valid:1;
|
||||
bool is_failed:1;
|
||||
struct dir_context *ctx; /*
|
||||
* Only used to make sure we only take entries
|
||||
* from a single context. Never dereferenced.
|
||||
struct file *file; /*
|
||||
* Used to associate the cache with a single
|
||||
* open file instance.
|
||||
*/
|
||||
struct mutex de_mutex;
|
||||
int pos; /* Expected ctx->pos */
|
||||
|
|
|
@ -3718,9 +3718,15 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* if new SMB3.11 POSIX extensions are supported do not remap / and \ */
|
||||
if (tcon->posix_extensions)
|
||||
/*
|
||||
* if new SMB3.11 POSIX extensions are supported, do not change anything in the
|
||||
* path (i.e., do not remap / and \ and do not map any special characters)
|
||||
*/
|
||||
if (tcon->posix_extensions) {
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
|
||||
cifs_sb->mnt_cifs_flags &= ~(CIFS_MOUNT_MAP_SFM_CHR |
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
/* tell server which Unix caps we support */
|
||||
|
|
|
@ -999,15 +999,18 @@ int cifs_open(struct inode *inode, struct file *file)
|
|||
rc = cifs_get_readable_path(tcon, full_path, &cfile);
|
||||
}
|
||||
if (rc == 0) {
|
||||
if (file->f_flags == cfile->f_flags) {
|
||||
unsigned int oflags = file->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC);
|
||||
unsigned int cflags = cfile->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC);
|
||||
|
||||
if (cifs_convert_flags(oflags, 0) == cifs_convert_flags(cflags, 0) &&
|
||||
(oflags & (O_SYNC|O_DIRECT)) == (cflags & (O_SYNC|O_DIRECT))) {
|
||||
file->private_data = cfile;
|
||||
spin_lock(&CIFS_I(inode)->deferred_lock);
|
||||
cifs_del_deferred_close(cfile);
|
||||
spin_unlock(&CIFS_I(inode)->deferred_lock);
|
||||
goto use_cache;
|
||||
} else {
|
||||
_cifsFileInfo_put(cfile, true, false);
|
||||
}
|
||||
_cifsFileInfo_put(cfile, true, false);
|
||||
} else {
|
||||
/* hard link on the defeered close file */
|
||||
rc = cifs_get_hardlink_path(tcon, inode, file);
|
||||
|
|
|
@ -851,9 +851,9 @@ static bool emit_cached_dirents(struct cached_dirents *cde,
|
|||
}
|
||||
|
||||
static void update_cached_dirents_count(struct cached_dirents *cde,
|
||||
struct dir_context *ctx)
|
||||
struct file *file)
|
||||
{
|
||||
if (cde->ctx != ctx)
|
||||
if (cde->file != file)
|
||||
return;
|
||||
if (cde->is_valid || cde->is_failed)
|
||||
return;
|
||||
|
@ -862,9 +862,9 @@ static void update_cached_dirents_count(struct cached_dirents *cde,
|
|||
}
|
||||
|
||||
static void finished_cached_dirents_count(struct cached_dirents *cde,
|
||||
struct dir_context *ctx)
|
||||
struct dir_context *ctx, struct file *file)
|
||||
{
|
||||
if (cde->ctx != ctx)
|
||||
if (cde->file != file)
|
||||
return;
|
||||
if (cde->is_valid || cde->is_failed)
|
||||
return;
|
||||
|
@ -877,11 +877,12 @@ static void finished_cached_dirents_count(struct cached_dirents *cde,
|
|||
static void add_cached_dirent(struct cached_dirents *cde,
|
||||
struct dir_context *ctx,
|
||||
const char *name, int namelen,
|
||||
struct cifs_fattr *fattr)
|
||||
struct cifs_fattr *fattr,
|
||||
struct file *file)
|
||||
{
|
||||
struct cached_dirent *de;
|
||||
|
||||
if (cde->ctx != ctx)
|
||||
if (cde->file != file)
|
||||
return;
|
||||
if (cde->is_valid || cde->is_failed)
|
||||
return;
|
||||
|
@ -911,7 +912,8 @@ static void add_cached_dirent(struct cached_dirents *cde,
|
|||
static bool cifs_dir_emit(struct dir_context *ctx,
|
||||
const char *name, int namelen,
|
||||
struct cifs_fattr *fattr,
|
||||
struct cached_fid *cfid)
|
||||
struct cached_fid *cfid,
|
||||
struct file *file)
|
||||
{
|
||||
bool rc;
|
||||
ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
|
||||
|
@ -923,7 +925,7 @@ static bool cifs_dir_emit(struct dir_context *ctx,
|
|||
if (cfid) {
|
||||
mutex_lock(&cfid->dirents.de_mutex);
|
||||
add_cached_dirent(&cfid->dirents, ctx, name, namelen,
|
||||
fattr);
|
||||
fattr, file);
|
||||
mutex_unlock(&cfid->dirents.de_mutex);
|
||||
}
|
||||
|
||||
|
@ -1023,7 +1025,7 @@ static int cifs_filldir(char *find_entry, struct file *file,
|
|||
cifs_prime_dcache(file_dentry(file), &name, &fattr);
|
||||
|
||||
return !cifs_dir_emit(ctx, name.name, name.len,
|
||||
&fattr, cfid);
|
||||
&fattr, cfid, file);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1074,8 +1076,8 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
|
|||
* we need to initialize scanning and storing the
|
||||
* directory content.
|
||||
*/
|
||||
if (ctx->pos == 0 && cfid->dirents.ctx == NULL) {
|
||||
cfid->dirents.ctx = ctx;
|
||||
if (ctx->pos == 0 && cfid->dirents.file == NULL) {
|
||||
cfid->dirents.file = file;
|
||||
cfid->dirents.pos = 2;
|
||||
}
|
||||
/*
|
||||
|
@ -1143,7 +1145,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
|
|||
} else {
|
||||
if (cfid) {
|
||||
mutex_lock(&cfid->dirents.de_mutex);
|
||||
finished_cached_dirents_count(&cfid->dirents, ctx);
|
||||
finished_cached_dirents_count(&cfid->dirents, ctx, file);
|
||||
mutex_unlock(&cfid->dirents.de_mutex);
|
||||
}
|
||||
cifs_dbg(FYI, "Could not find entry\n");
|
||||
|
@ -1184,7 +1186,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
|
|||
ctx->pos++;
|
||||
if (cfid) {
|
||||
mutex_lock(&cfid->dirents.de_mutex);
|
||||
update_cached_dirents_count(&cfid->dirents, ctx);
|
||||
update_cached_dirents_count(&cfid->dirents, file);
|
||||
mutex_unlock(&cfid->dirents.de_mutex);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user