Commit 2b753053 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull smb client fixes from Steve French:

 - Three DFS fixes: DFS mount fix, fix for noisy log msg and one to
   remove some unused code

 - SMB3 Lease fix

* tag 'v6.14rc1-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  smb: client: change lease epoch type from unsigned int to __u16
  smb: client: get rid of kstrdup() in get_ses_refpath()
  smb: client: fix noisy when tree connecting to DFS interlink targets
  smb: client: don't trust DFSREF_STORAGE_SERVER bit
parents 7ee983c8 57e4a9bd
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -357,7 +357,7 @@ struct smb_version_operations {
	int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *);
	void (*downgrade_oplock)(struct TCP_Server_Info *server,
				 struct cifsInodeInfo *cinode, __u32 oplock,
				 unsigned int epoch, bool *purge_cache);
				 __u16 epoch, bool *purge_cache);
	/* process transaction2 response */
	bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
			     char *, int);
@@ -552,12 +552,12 @@ struct smb_version_operations {
	/* if we can do cache read operations */
	bool (*is_read_op)(__u32);
	/* set oplock level for the inode */
	void (*set_oplock_level)(struct cifsInodeInfo *, __u32, unsigned int,
				 bool *);
	void (*set_oplock_level)(struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch,
				 bool *purge_cache);
	/* create lease context buffer for CREATE request */
	char * (*create_lease_buf)(u8 *lease_key, u8 oplock);
	/* parse lease context buffer and return oplock/epoch info */
	__u8 (*parse_lease_buf)(void *buf, unsigned int *epoch, char *lkey);
	__u8 (*parse_lease_buf)(void *buf, __u16 *epoch, char *lkey);
	ssize_t (*copychunk_range)(const unsigned int,
			struct cifsFileInfo *src_file,
			struct cifsFileInfo *target_file,
@@ -1447,7 +1447,7 @@ struct cifs_fid {
	__u8 create_guid[16];
	__u32 access;
	struct cifs_pending_open *pending_open;
	unsigned int epoch;
	__u16 epoch;
#ifdef CONFIG_CIFS_DEBUG2
	__u64 mid;
#endif /* CIFS_DEBUG2 */
@@ -1480,7 +1480,7 @@ struct cifsFileInfo {
	bool oplock_break_cancelled:1;
	bool status_file_deleted:1; /* file has been deleted */
	bool offload:1; /* offload final part of _put to a wq */
	unsigned int oplock_epoch; /* epoch from the lease break */
	__u16 oplock_epoch; /* epoch from the lease break */
	__u32 oplock_level; /* oplock/lease level from the lease break */
	int count;
	spinlock_t file_info_lock; /* protects four flag/count fields above */
@@ -1577,7 +1577,7 @@ struct cifsInodeInfo {
	spinlock_t	open_file_lock;	/* protects openFileList */
	__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
	unsigned int oplock;		/* oplock/lease level we have */
	unsigned int epoch;		/* used to track lease state changes */
	__u16 epoch;		/* used to track lease state changes */
#define CIFS_INODE_PENDING_OPLOCK_BREAK   (0) /* oplock break in progress */
#define CIFS_INODE_PENDING_WRITERS	  (1) /* Writes in progress */
#define CIFS_INODE_FLAG_UNUSED		  (2) /* Unused flag */
+16 −14
Original line number Diff line number Diff line
@@ -150,18 +150,19 @@ static int __dfs_referral_walk(struct dfs_ref_walk *rw)
			if (rc)
				continue;

			if (tgt.flags & DFSREF_STORAGE_SERVER) {
			rc = cifs_mount_get_tcon(mnt_ctx);
				if (!rc)
			if (rc) {
				if (tgt.server_type == DFS_TYPE_LINK &&
				    DFS_INTERLINK(tgt.flags))
					rc = -EREMOTE;
			} else {
				rc = cifs_is_path_remote(mnt_ctx);
				if (!rc) {
					ref_walk_set_tgt_hint(rw);
					break;
				}
				if (rc != -EREMOTE)
					continue;
			}

			if (rc == -EREMOTE) {
				rc = ref_walk_advance(rw);
				if (!rc) {
					rc = setup_dfs_ref(&tgt, rw);
@@ -171,6 +172,7 @@ static int __dfs_referral_walk(struct dfs_ref_walk *rw)
					goto again;
				}
			}
		}
	} while (rc && ref_walk_descend(rw));

	free_dfs_info_param(&tgt);
+7 −0
Original line number Diff line number Diff line
@@ -188,4 +188,11 @@ static inline void dfs_put_root_smb_sessions(struct list_head *head)
	}
}

static inline const char *dfs_ses_refpath(struct cifs_ses *ses)
{
	const char *path = ses->server->leaf_fullpath;

	return path ? path + 1 : ERR_PTR(-ENOENT);
}

#endif /* _CIFS_DFS_H */
+5 −22
Original line number Diff line number Diff line
@@ -1136,33 +1136,19 @@ static bool is_ses_good(struct cifs_ses *ses)
	return ret;
}

static char *get_ses_refpath(struct cifs_ses *ses)
{
	struct TCP_Server_Info *server = ses->server;
	char *path = ERR_PTR(-ENOENT);

	if (server->leaf_fullpath) {
		path = kstrdup(server->leaf_fullpath + 1, GFP_KERNEL);
		if (!path)
			path = ERR_PTR(-ENOMEM);
	}
	return path;
}

/* Refresh dfs referral of @ses */
static void refresh_ses_referral(struct cifs_ses *ses)
{
	struct cache_entry *ce;
	unsigned int xid;
	char *path;
	const char *path;
	int rc = 0;

	xid = get_xid();

	path = get_ses_refpath(ses);
	path = dfs_ses_refpath(ses);
	if (IS_ERR(path)) {
		rc = PTR_ERR(path);
		path = NULL;
		goto out;
	}

@@ -1181,7 +1167,6 @@ static void refresh_ses_referral(struct cifs_ses *ses)

out:
	free_xid(xid);
	kfree(path);
}

static int __refresh_tcon_referral(struct cifs_tcon *tcon,
@@ -1231,19 +1216,18 @@ static void refresh_tcon_referral(struct cifs_tcon *tcon, bool force_refresh)
	struct dfs_info3_param *refs = NULL;
	struct cache_entry *ce;
	struct cifs_ses *ses;
	unsigned int xid;
	bool needs_refresh;
	char *path;
	const char *path;
	unsigned int xid;
	int numrefs = 0;
	int rc = 0;

	xid = get_xid();
	ses = tcon->ses;

	path = get_ses_refpath(ses);
	path = dfs_ses_refpath(ses);
	if (IS_ERR(path)) {
		rc = PTR_ERR(path);
		path = NULL;
		goto out;
	}

@@ -1271,7 +1255,6 @@ static void refresh_tcon_referral(struct cifs_tcon *tcon, bool force_refresh)

out:
	free_xid(xid);
	kfree(path);
	free_dfs_info_array(refs, numrefs);
}

+1 −1
Original line number Diff line number Diff line
@@ -377,7 +377,7 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
static void
cifs_downgrade_oplock(struct TCP_Server_Info *server,
		      struct cifsInodeInfo *cinode, __u32 oplock,
		      unsigned int epoch, bool *purge_cache)
		      __u16 epoch, bool *purge_cache)
{
	cifs_set_oplock_level(cinode, oplock);
}
Loading