Skip to content

Commit

Permalink
Merge tag '6.1-rc-smb3-client-fixes-part1' of git://git.samba.org/sfr…
Browse files Browse the repository at this point in the history
…ench/cifs-2.6

Pull cifs updates from Steve French:

 - data corruption fix when cache disabled

 - four RDMA (smbdirect) improvements, including enabling support for
   SoftiWARP

 - four signing improvements

 - three directory lease improvements

 - four cleanup fixes

 - minor security fix

 - two debugging improvements

* tag '6.1-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6: (21 commits)
  smb3: fix oops in calculating shash_setkey
  cifs: secmech: use shash_desc directly, remove sdesc
  smb3: rename encryption/decryption TFMs
  cifs: replace kfree() with kfree_sensitive() for sensitive data
  cifs: remove initialization value
  cifs: Replace a couple of one-element arrays with flexible-array members
  smb3: do not log confusing message when server returns no network interfaces
  smb3: define missing create contexts
  cifs: store a pointer to a fid in the cfid structure instead of the struct
  cifs: improve handlecaching
  cifs: Make tcon contain a wrapper structure cached_fids instead of cached_fid
  smb3: add dynamic trace points for tree disconnect
  Fix formatting of client smbdirect RDMA logging
  Handle variable number of SGEs in client smbdirect send.
  Reduce client smbdirect max receive segment size
  Decrease the number of SMB3 smbdirect client SGEs
  cifs: Fix the error length of VALIDATE_NEGOTIATE_INFO message
  cifs: destage dirty pages before re-reading them for cache=none
  cifs: return correct error in ->calc_signature()
  MAINTAINERS: Add Tom Talpey as cifs.ko reviewer
  ...
  • Loading branch information
Linus Torvalds committed Oct 11, 2022
2 parents dc91485 + 958553d commit ac1e8c6
Show file tree
Hide file tree
Showing 30 changed files with 445 additions and 424 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -5170,6 +5170,7 @@ M: Steve French <sfrench@samba.org>
R: Paulo Alcantara <pc@cjr.nz> (DFS, global name space)
R: Ronnie Sahlberg <lsahlber@redhat.com> (directory leases, sparse files)
R: Shyam Prasad N <sprasad@microsoft.com> (multichannel)
R: Tom Talpey <tom@talpey.com> (RDMA, smbdirect)
L: linux-cifs@vger.kernel.org
L: samba-technical@lists.samba.org (moderated for non-subscribers)
S: Supported
Expand Down
92 changes: 72 additions & 20 deletions fs/cifs/cached_dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "smb2proto.h"
#include "cached_dir.h"

struct cached_fid *init_cached_dir(const char *path);

/*
* Open the and cache a directory handle.
* If error then *cfid is not initialized.
Expand Down Expand Up @@ -47,12 +49,19 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
if (cifs_sb->root == NULL)
return -ENOENT;

if (strlen(path))
if (!path[0])
dentry = cifs_sb->root;
else
return -ENOENT;

dentry = cifs_sb->root;
cfid = tcon->cfids->cfid;
if (cfid == NULL) {
cfid = init_cached_dir(path);
tcon->cfids->cfid = cfid;
}
if (cfid == NULL)
return -ENOMEM;

cfid = tcon->cfid;
mutex_lock(&cfid->fid_mutex);
if (cfid->is_valid) {
cifs_dbg(FYI, "found a cached root file handle\n");
Expand Down Expand Up @@ -160,7 +169,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
if (rc == -EREMCHG) {
tcon->need_reconnect = true;
pr_warn_once("server share %s deleted\n",
tcon->treeName);
tcon->tree_name);
}
goto oshr_exit;
}
Expand All @@ -177,7 +186,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
cfid->tcon = tcon;
cfid->is_valid = true;
cfid->dentry = dentry;
dget(dentry);
if (dentry)
dget(dentry);
kref_init(&cfid->refcount);

/* BB TBD check to see if oplock level check can be removed below */
Expand Down Expand Up @@ -226,7 +236,9 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
{
struct cached_fid *cfid;

cfid = tcon->cfid;
cfid = tcon->cfids->cfid;
if (cfid == NULL)
return -ENOENT;

mutex_lock(&cfid->fid_mutex);
if (cfid->dentry == dentry) {
Expand Down Expand Up @@ -320,7 +332,9 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
tcon = tlink_tcon(tlink);
if (IS_ERR(tcon))
continue;
cfid = tcon->cfid;
cfid = tcon->cfids->cfid;
if (cfid == NULL)
continue;
mutex_lock(&cfid->fid_mutex);
if (cfid->dentry) {
dput(cfid->dentry);
Expand All @@ -336,12 +350,17 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
*/
void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
{
mutex_lock(&tcon->cfid->fid_mutex);
tcon->cfid->is_valid = false;
struct cached_fid *cfid = tcon->cfids->cfid;

if (cfid == NULL)
return;

mutex_lock(&cfid->fid_mutex);
cfid->is_valid = false;
/* cached handle is not valid, so SMB2_CLOSE won't be sent below */
close_cached_dir_lease_locked(tcon->cfid);
memset(&tcon->cfid->fid, 0, sizeof(struct cifs_fid));
mutex_unlock(&tcon->cfid->fid_mutex);
close_cached_dir_lease_locked(cfid);
memset(&cfid->fid, 0, sizeof(struct cifs_fid));
mutex_unlock(&cfid->fid_mutex);
}

static void
Expand All @@ -355,34 +374,67 @@ smb2_cached_lease_break(struct work_struct *work)

int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
{
if (tcon->cfid->is_valid &&
struct cached_fid *cfid = tcon->cfids->cfid;

if (cfid == NULL)
return false;

if (cfid->is_valid &&
!memcmp(lease_key,
tcon->cfid->fid.lease_key,
cfid->fid.lease_key,
SMB2_LEASE_KEY_SIZE)) {
tcon->cfid->time = 0;
INIT_WORK(&tcon->cfid->lease_break,
cfid->time = 0;
INIT_WORK(&cfid->lease_break,
smb2_cached_lease_break);
queue_work(cifsiod_wq,
&tcon->cfid->lease_break);
&cfid->lease_break);
return true;
}
return false;
}

struct cached_fid *init_cached_dir(void)
struct cached_fid *init_cached_dir(const char *path)
{
struct cached_fid *cfid;

cfid = kzalloc(sizeof(*cfid), GFP_KERNEL);
if (!cfid)
return NULL;
cfid->path = kstrdup(path, GFP_KERNEL);
if (!cfid->path) {
kfree(cfid);
return NULL;
}

INIT_LIST_HEAD(&cfid->dirents.entries);
mutex_init(&cfid->dirents.de_mutex);
mutex_init(&cfid->fid_mutex);
return cfid;
}

void free_cached_dir(struct cifs_tcon *tcon)
void free_cached_dir(struct cached_fid *cfid)
{
kfree(cfid->path);
cfid->path = NULL;
kfree(cfid);
}

struct cached_fids *init_cached_dirs(void)
{
kfree(tcon->cfid);
struct cached_fids *cfids;

cfids = kzalloc(sizeof(*cfids), GFP_KERNEL);
if (!cfids)
return NULL;
mutex_init(&cfids->cfid_list_mutex);
return cfids;
}

void free_cached_dirs(struct cached_fids *cfids)
{
if (cfids->cfid) {
free_cached_dir(cfids->cfid);
cfids->cfid = NULL;
}
kfree(cfids);
}
10 changes: 8 additions & 2 deletions fs/cifs/cached_dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct cached_dirents {
};

struct cached_fid {
const char *path;
bool is_valid:1; /* Do we have a useable root fid */
bool file_all_info_is_valid:1;
bool has_lease:1;
Expand All @@ -45,8 +46,13 @@ struct cached_fid {
struct cached_dirents dirents;
};

extern struct cached_fid *init_cached_dir(void);
extern void free_cached_dir(struct cifs_tcon *tcon);
struct cached_fids {
struct mutex cfid_list_mutex;
struct cached_fid *cfid;
};

extern struct cached_fids *init_cached_dirs(void);
extern void free_cached_dirs(struct cached_fids *cfids);
extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
const char *path,
struct cifs_sb_info *cifs_sb,
Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/cifs_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
{
__u32 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);

seq_printf(m, "%s Mounts: %d ", tcon->treeName, tcon->tc_count);
seq_printf(m, "%s Mounts: %d ", tcon->tree_name, tcon->tc_count);
if (tcon->nativeFileSystem)
seq_printf(m, "Type: %s ", tcon->nativeFileSystem);
seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d",
Expand Down Expand Up @@ -601,7 +601,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
i++;
seq_printf(m, "\n%d) %s", i, tcon->treeName);
seq_printf(m, "\n%d) %s", i, tcon->tree_name);
if (tcon->need_reconnect)
seq_puts(m, "\tDISCONNECTED ");
seq_printf(m, "\nSMBs: %d",
Expand Down
6 changes: 3 additions & 3 deletions fs/cifs/cifs_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ do { \
#define cifs_tcon_dbg_func(ratefunc, type, fmt, ...) \
do { \
const char *tn = ""; \
if (tcon && tcon->treeName) \
tn = tcon->treeName; \
if (tcon && tcon->tree_name) \
tn = tcon->tree_name; \
if ((type) & FYI && cifsFYI & CIFS_INFO) { \
pr_debug_ ## ratefunc("%s: %s " fmt, \
__FILE__, tn, ##__VA_ARGS__); \
Expand Down Expand Up @@ -150,7 +150,7 @@ do { \
#define cifs_tcon_dbg(type, fmt, ...) \
do { \
if (0) \
pr_debug("%s " fmt, tcon->treeName, ##__VA_ARGS__); \
pr_debug("%s " fmt, tcon->tree_name, ##__VA_ARGS__); \
} while (0)

#define cifs_info(fmt, ...) \
Expand Down
12 changes: 6 additions & 6 deletions fs/cifs/cifs_swn.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,23 +256,23 @@ static struct cifs_swn_reg *cifs_find_swn_reg(struct cifs_tcon *tcon)
const char *share_name;
const char *net_name;

net_name = extract_hostname(tcon->treeName);
net_name = extract_hostname(tcon->tree_name);
if (IS_ERR(net_name)) {
int ret;

ret = PTR_ERR(net_name);
cifs_dbg(VFS, "%s: failed to extract host name from target '%s': %d\n",
__func__, tcon->treeName, ret);
__func__, tcon->tree_name, ret);
return ERR_PTR(-EINVAL);
}

share_name = extract_sharename(tcon->treeName);
share_name = extract_sharename(tcon->tree_name);
if (IS_ERR(share_name)) {
int ret;

ret = PTR_ERR(share_name);
cifs_dbg(VFS, "%s: failed to extract share name from target '%s': %d\n",
__func__, tcon->treeName, ret);
__func__, tcon->tree_name, ret);
kfree(net_name);
return ERR_PTR(-EINVAL);
}
Expand Down Expand Up @@ -335,14 +335,14 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon)
goto fail;
}

reg->net_name = extract_hostname(tcon->treeName);
reg->net_name = extract_hostname(tcon->tree_name);
if (IS_ERR(reg->net_name)) {
ret = PTR_ERR(reg->net_name);
cifs_dbg(VFS, "%s: failed to extract host name from target: %d\n", __func__, ret);
goto fail_idr;
}

reg->share_name = extract_sharename(tcon->treeName);
reg->share_name = extract_sharename(tcon->tree_name);
if (IS_ERR(reg->share_name)) {
ret = PTR_ERR(reg->share_name);
cifs_dbg(VFS, "%s: failed to extract share name from target: %d\n", __func__, ret);
Expand Down
Loading

0 comments on commit ac1e8c6

Please sign in to comment.