Skip to content

Commit 2a19866

Browse files
committed
Merge tag '5.12-rc-smb3-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs updates from Steve French: - improvements to root directory metadata caching - addition of new "rasize" mount parameter which can significantly increase read ahead performance (e.g. copy can be much faster, especially with multichannel) - addition of support for insert and collapse range - improvements to error handling in mount * tag '5.12-rc-smb3-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6: (40 commits) cifs: update internal version number smb3: add rasize mount parameter to improve readahead performance smb3: limit noisy error cifs: fix leak in cifs_smb3_do_mount() ctx cifs: remove unnecessary copies of tcon->crfid.fid cifs: Return correct error code from smb2_get_enc_key cifs: fix out-of-bound memory access when calling smb3_notify() at mount point smb2: fix use-after-free in smb2_ioctl_query_info() cifs: export supported mount options via new mount_params /proc file cifs: log mount errors using cifs_errorf() cifs: add fs_context param to parsing helpers cifs: make fs_context error logging wrapper cifs: add FALLOC_FL_INSERT_RANGE support cifs: add support for FALLOC_FL_COLLAPSE_RANGE cifs: check the timestamp for the cached dirent when deciding on revalidate cifs: pass the dentry instead of the inode down to the revalidation check functions cifs: add a timestamp to track when the lease of the cached dir was taken cifs: add a function to get a cached dir based on its dentry cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache cifs: store a pointer to the root dentry in cifs_sb_info once we have completed mounting the share ...
2 parents c065c42 + a8a6082 commit 2a19866

32 files changed

Lines changed: 724 additions & 550 deletions

Documentation/admin-guide/cifs/usage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ DebugData Displays information about active CIFS sessions and
714714
version.
715715
Stats Lists summary resource usage information as well as per
716716
share statistics.
717+
open_files List all the open file handles on all active SMB sessions.
717718
======================= =======================================================
718719

719720
Configuration pseudo-files:
@@ -794,6 +795,8 @@ LinuxExtensionsEnabled If set to one then the client will attempt to
794795
support and want to map the uid and gid fields
795796
to values supplied at mount (rather than the
796797
actual values, then set this to zero. (default 1)
798+
dfscache List the content of the DFS cache.
799+
If set to 0, the client will clear the cache.
797800
======================= =======================================================
798801

799802
These experimental features and tracing can be enabled by changing flags in

fs/cifs/cifs_debug.c

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,14 @@
1717
#include "cifsproto.h"
1818
#include "cifs_debug.h"
1919
#include "cifsfs.h"
20+
#include "fs_context.h"
2021
#ifdef CONFIG_CIFS_DFS_UPCALL
2122
#include "dfs_cache.h"
2223
#endif
2324
#ifdef CONFIG_CIFS_SMB_DIRECT
2425
#include "smbdirect.h"
2526
#endif
26-
#ifdef CONFIG_CIFS_SWN_UPCALL
2727
#include "cifs_swn.h"
28-
#endif
2928

3029
void
3130
cifs_dump_mem(char *label, void *data, int length)
@@ -118,10 +117,8 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
118117
seq_printf(m, " POSIX Extensions");
119118
if (tcon->ses->server->ops->dump_share_caps)
120119
tcon->ses->server->ops->dump_share_caps(m, tcon);
121-
#ifdef CONFIG_CIFS_SWN_UPCALL
122120
if (tcon->use_witness)
123121
seq_puts(m, " Witness");
124-
#endif
125122

126123
if (tcon->need_reconnect)
127124
seq_puts(m, "\tDISCONNECTED ");
@@ -490,10 +487,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
490487

491488
spin_unlock(&cifs_tcp_ses_lock);
492489
seq_putc(m, '\n');
493-
494-
#ifdef CONFIG_CIFS_SWN_UPCALL
495490
cifs_swn_dump(m);
496-
#endif
491+
497492
/* BB add code to dump additional info such as TCP session info now */
498493
return 0;
499494
}
@@ -702,6 +697,7 @@ static const struct proc_ops cifs_lookup_cache_proc_ops;
702697
static const struct proc_ops traceSMB_proc_ops;
703698
static const struct proc_ops cifs_security_flags_proc_ops;
704699
static const struct proc_ops cifs_linux_ext_proc_ops;
700+
static const struct proc_ops cifs_mount_params_proc_ops;
705701

706702
void
707703
cifs_proc_init(void)
@@ -726,6 +722,8 @@ cifs_proc_init(void)
726722
proc_create("LookupCacheEnabled", 0644, proc_fs_cifs,
727723
&cifs_lookup_cache_proc_ops);
728724

725+
proc_create("mount_params", 0444, proc_fs_cifs, &cifs_mount_params_proc_ops);
726+
729727
#ifdef CONFIG_CIFS_DFS_UPCALL
730728
proc_create("dfscache", 0644, proc_fs_cifs, &dfscache_proc_ops);
731729
#endif
@@ -764,6 +762,7 @@ cifs_proc_clean(void)
764762
remove_proc_entry("SecurityFlags", proc_fs_cifs);
765763
remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
766764
remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
765+
remove_proc_entry("mount_params", proc_fs_cifs);
767766

768767
#ifdef CONFIG_CIFS_DFS_UPCALL
769768
remove_proc_entry("dfscache", proc_fs_cifs);
@@ -1023,6 +1022,51 @@ static const struct proc_ops cifs_security_flags_proc_ops = {
10231022
.proc_release = single_release,
10241023
.proc_write = cifs_security_flags_proc_write,
10251024
};
1025+
1026+
/* To make it easier to debug, can help to show mount params */
1027+
static int cifs_mount_params_proc_show(struct seq_file *m, void *v)
1028+
{
1029+
const struct fs_parameter_spec *p;
1030+
const char *type;
1031+
1032+
for (p = smb3_fs_parameters; p->name; p++) {
1033+
/* cannot use switch with pointers... */
1034+
if (!p->type) {
1035+
if (p->flags == fs_param_neg_with_no)
1036+
type = "noflag";
1037+
else
1038+
type = "flag";
1039+
} else if (p->type == fs_param_is_bool)
1040+
type = "bool";
1041+
else if (p->type == fs_param_is_u32)
1042+
type = "u32";
1043+
else if (p->type == fs_param_is_u64)
1044+
type = "u64";
1045+
else if (p->type == fs_param_is_string)
1046+
type = "string";
1047+
else
1048+
type = "unknown";
1049+
1050+
seq_printf(m, "%s:%s\n", p->name, type);
1051+
}
1052+
1053+
return 0;
1054+
}
1055+
1056+
static int cifs_mount_params_proc_open(struct inode *inode, struct file *file)
1057+
{
1058+
return single_open(file, cifs_mount_params_proc_show, NULL);
1059+
}
1060+
1061+
static const struct proc_ops cifs_mount_params_proc_ops = {
1062+
.proc_open = cifs_mount_params_proc_open,
1063+
.proc_read = seq_read,
1064+
.proc_lseek = seq_lseek,
1065+
.proc_release = single_release,
1066+
/* No need for write for now */
1067+
/* .proc_write = cifs_mount_params_proc_write, */
1068+
};
1069+
10261070
#else
10271071
inline void cifs_proc_init(void)
10281072
{

fs/cifs/cifs_dfs_ref.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt,
270270
char *mountdata;
271271
char *devname;
272272

273-
devname = kstrndup(fullpath, strlen(fullpath), GFP_KERNEL);
273+
devname = kstrdup(fullpath, GFP_KERNEL);
274274
if (!devname)
275275
return ERR_PTR(-ENOMEM);
276276

@@ -302,6 +302,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
302302
struct cifs_sb_info *cifs_sb;
303303
struct cifs_ses *ses;
304304
struct cifs_tcon *tcon;
305+
void *page;
305306
char *full_path, *root_path;
306307
unsigned int xid;
307308
int rc;
@@ -324,10 +325,13 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
324325
goto cdda_exit;
325326
}
326327

328+
page = alloc_dentry_path();
327329
/* always use tree name prefix */
328-
full_path = build_path_from_dentry_optional_prefix(mntpt, true);
329-
if (full_path == NULL)
330-
goto cdda_exit;
330+
full_path = build_path_from_dentry_optional_prefix(mntpt, page, true);
331+
if (IS_ERR(full_path)) {
332+
mnt = ERR_CAST(full_path);
333+
goto free_full_path;
334+
}
331335

332336
convert_delimiter(full_path, '\\');
333337

@@ -385,7 +389,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
385389
free_root_path:
386390
kfree(root_path);
387391
free_full_path:
388-
kfree(full_path);
392+
free_dentry_path(page);
389393
cdda_exit:
390394
cifs_dbg(FYI, "leaving %s\n" , __func__);
391395
return mnt;

fs/cifs/cifs_fs_sb.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,9 @@ struct cifs_sb_info {
8181
* (cifs_autodisable_serverino) in order to match new mounts.
8282
*/
8383
bool mnt_cifs_serverino_autodisabled;
84+
/*
85+
* Available once the mount has completed.
86+
*/
87+
struct dentry *root;
8488
};
8589
#endif /* _CIFS_FS_SB_H */

fs/cifs/cifs_swn.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88
#ifndef _CIFS_SWN_H
99
#define _CIFS_SWN_H
10+
#include "cifsglob.h"
1011

1112
struct cifs_tcon;
1213
struct sk_buff;
1314
struct genl_info;
1415

16+
#ifdef CONFIG_CIFS_SWN_UPCALL
1517
extern int cifs_swn_register(struct cifs_tcon *tcon);
1618

1719
extern int cifs_swn_unregister(struct cifs_tcon *tcon);
@@ -22,4 +24,29 @@ extern void cifs_swn_dump(struct seq_file *m);
2224

2325
extern void cifs_swn_check(void);
2426

27+
static inline bool cifs_swn_set_server_dstaddr(struct TCP_Server_Info *server)
28+
{
29+
if (server->use_swn_dstaddr) {
30+
server->dstaddr = server->swn_dstaddr;
31+
return true;
32+
}
33+
return false;
34+
}
35+
36+
static inline void cifs_swn_reset_server_dstaddr(struct TCP_Server_Info *server)
37+
{
38+
server->use_swn_dstaddr = false;
39+
}
40+
41+
#else
42+
43+
static inline int cifs_swn_register(struct cifs_tcon *tcon) { return 0; }
44+
static inline int cifs_swn_unregister(struct cifs_tcon *tcon) { return 0; }
45+
static inline int cifs_swn_notify(struct sk_buff *s, struct genl_info *i) { return 0; }
46+
static inline void cifs_swn_dump(struct seq_file *m) {}
47+
static inline void cifs_swn_check(void) {}
48+
static inline bool cifs_swn_set_server_dstaddr(struct TCP_Server_Info *server) { return false; }
49+
static inline void cifs_swn_reset_server_dstaddr(struct TCP_Server_Info *server) {}
50+
51+
#endif /* CONFIG_CIFS_SWN_UPCALL */
2552
#endif /* _CIFS_SWN_H */

fs/cifs/cifsacl.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,11 +1094,9 @@ static int set_chmod_dacl(struct cifs_acl *pdacl, struct cifs_acl *pndacl,
10941094
struct cifs_ace *pnntace = NULL;
10951095
char *nacl_base = NULL;
10961096
u32 num_aces = 0;
1097-
__u64 nmode;
10981097
bool new_aces_set = false;
10991098

11001099
/* Assuming that pndacl and pnmode are never NULL */
1101-
nmode = *pnmode;
11021100
nacl_base = (char *)pndacl;
11031101
nsize = sizeof(struct cifs_acl);
11041102

@@ -1651,7 +1649,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
16511649
* Add three ACEs for owner, group, everyone getting rid of other ACEs
16521650
* as chmod disables ACEs and set the security descriptor. Allocate
16531651
* memory for the smb header, set security descriptor request security
1654-
* descriptor parameters, and secuirty descriptor itself
1652+
* descriptor parameters, and security descriptor itself
16551653
*/
16561654
nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN);
16571655
pnntsd = kmalloc(nsecdesclen, GFP_KERNEL);

fs/cifs/cifsfs.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,11 @@ cifs_read_super(struct super_block *sb)
217217
rc = super_setup_bdi(sb);
218218
if (rc)
219219
goto out_no_root;
220-
/* tune readahead according to rsize */
221-
sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
220+
/* tune readahead according to rsize if readahead size not set on mount */
221+
if (cifs_sb->ctx->rasize)
222+
sb->s_bdi->ra_pages = cifs_sb->ctx->rasize / PAGE_SIZE;
223+
else
224+
sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
222225

223226
sb->s_blocksize = CIFS_MAX_MSGSIZE;
224227
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
@@ -257,6 +260,29 @@ cifs_read_super(struct super_block *sb)
257260
static void cifs_kill_sb(struct super_block *sb)
258261
{
259262
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
263+
struct cifs_tcon *tcon;
264+
struct cached_fid *cfid;
265+
266+
/*
267+
* We ned to release all dentries for the cached directories
268+
* before we kill the sb.
269+
*/
270+
if (cifs_sb->root) {
271+
dput(cifs_sb->root);
272+
cifs_sb->root = NULL;
273+
}
274+
tcon = cifs_sb_master_tcon(cifs_sb);
275+
if (tcon) {
276+
cfid = &tcon->crfid;
277+
mutex_lock(&cfid->fid_mutex);
278+
if (cfid->dentry) {
279+
280+
dput(cfid->dentry);
281+
cfid->dentry = NULL;
282+
}
283+
mutex_unlock(&cfid->fid_mutex);
284+
}
285+
260286
kill_anon_super(sb);
261287
cifs_umount(cifs_sb);
262288
}
@@ -626,6 +652,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
626652
seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
627653
seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);
628654
seq_printf(s, ",bsize=%u", cifs_sb->ctx->bsize);
655+
if (cifs_sb->ctx->rasize)
656+
seq_printf(s, ",rasize=%u", cifs_sb->ctx->rasize);
629657
if (tcon->ses->server->min_offload)
630658
seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
631659
seq_printf(s, ",echo_interval=%lu",
@@ -656,10 +684,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
656684
seq_printf(s, ",multichannel,max_channels=%zu",
657685
tcon->ses->chan_max);
658686

659-
#ifdef CONFIG_CIFS_SWN_UPCALL
660687
if (tcon->use_witness)
661688
seq_puts(s, ",witness");
662-
#endif
663689

664690
return 0;
665691
}
@@ -834,6 +860,12 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
834860
goto out;
835861
}
836862

863+
/* cifs_setup_volume_info->smb3_parse_devname() redups UNC & prepath */
864+
kfree(cifs_sb->ctx->UNC);
865+
cifs_sb->ctx->UNC = NULL;
866+
kfree(cifs_sb->ctx->prepath);
867+
cifs_sb->ctx->prepath = NULL;
868+
837869
rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC);
838870
if (rc) {
839871
root = ERR_PTR(rc);
@@ -888,6 +920,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
888920
if (IS_ERR(root))
889921
goto out_super;
890922

923+
if (cifs_sb)
924+
cifs_sb->root = dget(root);
925+
891926
cifs_dbg(FYI, "dentry root is: %p\n", root);
892927
return root;
893928

@@ -1528,10 +1563,6 @@ init_cifs(void)
15281563
int rc = 0;
15291564
cifs_proc_init();
15301565
INIT_LIST_HEAD(&cifs_tcp_ses_list);
1531-
#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
1532-
INIT_LIST_HEAD(&GlobalDnotifyReqList);
1533-
INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
1534-
#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
15351566
/*
15361567
* Initialize Global counters
15371568
*/

fs/cifs/cifsfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,5 +165,5 @@ extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
165165
extern const struct export_operations cifs_export_ops;
166166
#endif /* CONFIG_CIFS_NFSD_EXPORT */
167167

168-
#define CIFS_VERSION "2.31"
168+
#define CIFS_VERSION "2.32"
169169
#endif /* _CIFSFS_H */

0 commit comments

Comments
 (0)