Skip to content

Commit 8c6bc74

Browse files
committed
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
2 parents ac91b4d + 72dd796 commit 8c6bc74

File tree

5 files changed

+35
-22
lines changed

5 files changed

+35
-22
lines changed

Documentation/admin-guide/cifs/usage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ configured for Unix Extensions (and the client has not disabled
270270
illegal Windows/NTFS/SMB characters to a remap range (this mount parameter
271271
is the default for SMB3). This remap (``mapposix``) range is also
272272
compatible with Mac (and "Services for Mac" on some older Windows).
273+
When POSIX Extensions for SMB 3.1.1 are negotiated, remapping is automatically
274+
disabled.
273275

274276
CIFS VFS Mount Options
275277
======================

fs/smb/client/cached_dir.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ struct cached_dirent {
2121
struct cached_dirents {
2222
bool is_valid:1;
2323
bool is_failed:1;
24-
struct dir_context *ctx; /*
25-
* Only used to make sure we only take entries
26-
* from a single context. Never dereferenced.
27-
*/
24+
struct file *file; /*
25+
* Used to associate the cache with a single
26+
* open file instance.
27+
*/
2828
struct mutex de_mutex;
2929
int pos; /* Expected ctx->pos */
3030
struct list_head entries;

fs/smb/client/connect.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3718,9 +3718,15 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
37183718
goto out;
37193719
}
37203720

3721-
/* if new SMB3.11 POSIX extensions are supported do not remap / and \ */
3722-
if (tcon->posix_extensions)
3721+
/*
3722+
* if new SMB3.11 POSIX extensions are supported, do not change anything in the
3723+
* path (i.e., do not remap / and \ and do not map any special characters)
3724+
*/
3725+
if (tcon->posix_extensions) {
37233726
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
3727+
cifs_sb->mnt_cifs_flags &= ~(CIFS_MOUNT_MAP_SFM_CHR |
3728+
CIFS_MOUNT_MAP_SPECIAL_CHR);
3729+
}
37243730

37253731
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
37263732
/* tell server which Unix caps we support */

fs/smb/client/file.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -999,15 +999,18 @@ int cifs_open(struct inode *inode, struct file *file)
999999
rc = cifs_get_readable_path(tcon, full_path, &cfile);
10001000
}
10011001
if (rc == 0) {
1002-
if (file->f_flags == cfile->f_flags) {
1002+
unsigned int oflags = file->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC);
1003+
unsigned int cflags = cfile->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC);
1004+
1005+
if (cifs_convert_flags(oflags, 0) == cifs_convert_flags(cflags, 0) &&
1006+
(oflags & (O_SYNC|O_DIRECT)) == (cflags & (O_SYNC|O_DIRECT))) {
10031007
file->private_data = cfile;
10041008
spin_lock(&CIFS_I(inode)->deferred_lock);
10051009
cifs_del_deferred_close(cfile);
10061010
spin_unlock(&CIFS_I(inode)->deferred_lock);
10071011
goto use_cache;
1008-
} else {
1009-
_cifsFileInfo_put(cfile, true, false);
10101012
}
1013+
_cifsFileInfo_put(cfile, true, false);
10111014
} else {
10121015
/* hard link on the defeered close file */
10131016
rc = cifs_get_hardlink_path(tcon, inode, file);

fs/smb/client/readdir.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -851,9 +851,9 @@ static bool emit_cached_dirents(struct cached_dirents *cde,
851851
}
852852

853853
static void update_cached_dirents_count(struct cached_dirents *cde,
854-
struct dir_context *ctx)
854+
struct file *file)
855855
{
856-
if (cde->ctx != ctx)
856+
if (cde->file != file)
857857
return;
858858
if (cde->is_valid || cde->is_failed)
859859
return;
@@ -862,9 +862,9 @@ static void update_cached_dirents_count(struct cached_dirents *cde,
862862
}
863863

864864
static void finished_cached_dirents_count(struct cached_dirents *cde,
865-
struct dir_context *ctx)
865+
struct dir_context *ctx, struct file *file)
866866
{
867-
if (cde->ctx != ctx)
867+
if (cde->file != file)
868868
return;
869869
if (cde->is_valid || cde->is_failed)
870870
return;
@@ -877,11 +877,12 @@ static void finished_cached_dirents_count(struct cached_dirents *cde,
877877
static void add_cached_dirent(struct cached_dirents *cde,
878878
struct dir_context *ctx,
879879
const char *name, int namelen,
880-
struct cifs_fattr *fattr)
880+
struct cifs_fattr *fattr,
881+
struct file *file)
881882
{
882883
struct cached_dirent *de;
883884

884-
if (cde->ctx != ctx)
885+
if (cde->file != file)
885886
return;
886887
if (cde->is_valid || cde->is_failed)
887888
return;
@@ -911,7 +912,8 @@ static void add_cached_dirent(struct cached_dirents *cde,
911912
static bool cifs_dir_emit(struct dir_context *ctx,
912913
const char *name, int namelen,
913914
struct cifs_fattr *fattr,
914-
struct cached_fid *cfid)
915+
struct cached_fid *cfid,
916+
struct file *file)
915917
{
916918
bool rc;
917919
ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
@@ -923,7 +925,7 @@ static bool cifs_dir_emit(struct dir_context *ctx,
923925
if (cfid) {
924926
mutex_lock(&cfid->dirents.de_mutex);
925927
add_cached_dirent(&cfid->dirents, ctx, name, namelen,
926-
fattr);
928+
fattr, file);
927929
mutex_unlock(&cfid->dirents.de_mutex);
928930
}
929931

@@ -1023,7 +1025,7 @@ static int cifs_filldir(char *find_entry, struct file *file,
10231025
cifs_prime_dcache(file_dentry(file), &name, &fattr);
10241026

10251027
return !cifs_dir_emit(ctx, name.name, name.len,
1026-
&fattr, cfid);
1028+
&fattr, cfid, file);
10271029
}
10281030

10291031

@@ -1074,8 +1076,8 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
10741076
* we need to initialize scanning and storing the
10751077
* directory content.
10761078
*/
1077-
if (ctx->pos == 0 && cfid->dirents.ctx == NULL) {
1078-
cfid->dirents.ctx = ctx;
1079+
if (ctx->pos == 0 && cfid->dirents.file == NULL) {
1080+
cfid->dirents.file = file;
10791081
cfid->dirents.pos = 2;
10801082
}
10811083
/*
@@ -1143,7 +1145,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
11431145
} else {
11441146
if (cfid) {
11451147
mutex_lock(&cfid->dirents.de_mutex);
1146-
finished_cached_dirents_count(&cfid->dirents, ctx);
1148+
finished_cached_dirents_count(&cfid->dirents, ctx, file);
11471149
mutex_unlock(&cfid->dirents.de_mutex);
11481150
}
11491151
cifs_dbg(FYI, "Could not find entry\n");
@@ -1184,7 +1186,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
11841186
ctx->pos++;
11851187
if (cfid) {
11861188
mutex_lock(&cfid->dirents.de_mutex);
1187-
update_cached_dirents_count(&cfid->dirents, ctx);
1189+
update_cached_dirents_count(&cfid->dirents, file);
11881190
mutex_unlock(&cfid->dirents.de_mutex);
11891191
}
11901192

0 commit comments

Comments
 (0)