Commit 103a022d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '5.5-rc1-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cfis fixes from Steve French:
 "Three small smb3 fixes: this addresses two recent issues reported in
  additional testing during rc1, a refcount underflow and a problem with
  an intermittent crash in SMB2_open_init"

* tag '5.5-rc1-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  CIFS: Close cached root handle only if it has a lease
  SMB3: Fix crash in SMB2_open_init due to uninitialized field in compounding path
  smb3: fix refcount underflow warning on unmount when no directory leases
parents 81c64b0b d9191319
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1061,7 +1061,7 @@ cap_unix(struct cifs_ses *ses)
struct cached_fid {
	bool is_valid:1;	/* Do we have a useable root fid */
	bool file_all_info_is_valid:1;

	bool has_lease:1;
	struct kref refcount;
	struct cifs_fid *fid;
	struct mutex fid_mutex;
+3 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
#include "smb2proto.h"
#include "fscache.h"
#include "smbdirect.h"
#ifdef CONFIG_CIFS_DFS_UPCALL
@@ -112,6 +113,8 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)

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

+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
		goto finished;
	}

	memset(&oparms, 0, sizeof(struct cifs_open_parms));
	oparms.tcon = tcon;
	oparms.desired_access = desired_access;
	oparms.disposition = create_disposition;
+18 −1
Original line number Diff line number Diff line
@@ -616,6 +616,7 @@ smb2_close_cached_fid(struct kref *ref)
			   cfid->fid->volatile_fid);
		cfid->is_valid = false;
		cfid->file_all_info_is_valid = false;
		cfid->has_lease = false;
	}
}

@@ -626,13 +627,28 @@ void close_shroot(struct cached_fid *cfid)
	mutex_unlock(&cfid->fid_mutex);
}

void close_shroot_lease_locked(struct cached_fid *cfid)
{
	if (cfid->has_lease) {
		cfid->has_lease = false;
		kref_put(&cfid->refcount, smb2_close_cached_fid);
	}
}

void close_shroot_lease(struct cached_fid *cfid)
{
	mutex_lock(&cfid->fid_mutex);
	close_shroot_lease_locked(cfid);
	mutex_unlock(&cfid->fid_mutex);
}

void
smb2_cached_lease_break(struct work_struct *work)
{
	struct cached_fid *cfid = container_of(work,
				struct cached_fid, lease_break);

	close_shroot(cfid);
	close_shroot_lease(cfid);
}

/*
@@ -773,6 +789,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
	/* BB TBD check to see if oplock level check can be removed below */
	if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) {
		kref_get(&tcon->crfid.refcount);
		tcon->crfid.has_lease = true;
		smb2_parse_contexts(server, o_rsp,
				&oparms.fid->epoch,
				oparms.fid->lease_key, &oplock, NULL);
+1 −1
Original line number Diff line number Diff line
@@ -1847,7 +1847,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
	if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
		return 0;

	close_shroot(&tcon->crfid);
	close_shroot_lease(&tcon->crfid);

	rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, (void **) &req,
			     &total_len);
Loading