Commit 9d1ddab2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '6.9-rc5-smb-client-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull smb client fixes from Steve French:

 - fscache fix

 - fix for case where we could use uninitialized lease

 - add tracepoint for debugging refcounting of tcon

 - fix mount option regression (e.g. forceuid vs. noforceuid when uid=
   specified) caused by conversion to the new mount API

* tag '6.9-rc5-smb-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: reinstate original behavior again for forceuid/forcegid
  smb: client: fix rename(2) regression against samba
  cifs: Add tracing for the cifs_tcon struct refcounting
  cifs: Fix reacquisition of volume cookie on still-live connection
parents 71b1543c 77d8aa79
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -389,6 +389,7 @@ cifs_alloc_inode(struct super_block *sb)
	 * server, can not assume caching of file data or metadata.
	 */
	cifs_set_oplock_level(cifs_inode, 0);
	cifs_inode->lease_granted = false;
	cifs_inode->flags = 0;
	spin_lock_init(&cifs_inode->writers_lock);
	cifs_inode->writers = 0;
@@ -739,6 +740,8 @@ static void cifs_umount_begin(struct super_block *sb)

	spin_lock(&cifs_tcp_ses_lock);
	spin_lock(&tcon->tc_lock);
	trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
			    netfs_trace_tcon_ref_see_umount);
	if ((tcon->tc_count > 1) || (tcon->status == TID_EXITING)) {
		/* we have other mounts to same share or we have
		   already tried to umount this and woken up
+3 −0
Original line number Diff line number Diff line
@@ -1190,6 +1190,7 @@ struct cifs_fattr {
 */
struct cifs_tcon {
	struct list_head tcon_list;
	int debug_id;		/* Debugging for tracing */
	int tc_count;
	struct list_head rlist; /* reconnect list */
	spinlock_t tc_lock;  /* protect anything here that is not protected */
@@ -1276,7 +1277,9 @@ struct cifs_tcon {
	__u32 max_cached_dirs;
#ifdef CONFIG_CIFS_FSCACHE
	u64 resource_id;		/* server resource id */
	bool fscache_acquired;		/* T if we've tried acquiring a cookie */
	struct fscache_volume *fscache;	/* cookie for share */
	struct mutex fscache_lock;	/* Prevent regetting a cookie */
#endif
	struct list_head pending_opens;	/* list of incomplete opens */
	struct cached_fids *cfids;
+4 −5
Original line number Diff line number Diff line
@@ -303,7 +303,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
		     struct TCP_Server_Info *primary_server);
extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
				 int from_reconnect);
extern void cifs_put_tcon(struct cifs_tcon *tcon);
extern void cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);

extern void cifs_release_automount_timer(void);

@@ -530,8 +530,9 @@ extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);

extern struct cifs_ses *sesInfoAlloc(void);
extern void sesInfoFree(struct cifs_ses *);
extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled);
extern void tconInfoFree(struct cifs_tcon *);
extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled,
					 enum smb3_tcon_ref_trace trace);
extern void tconInfoFree(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace);

extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
		   __u32 *pexpected_response_sequence_number);
@@ -721,8 +722,6 @@ static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
		return options;
}

struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon);
void cifs_put_tcon_super(struct super_block *sb);
int cifs_wait_for_server_reconnect(struct TCP_Server_Info *server, bool retry);

/* Put references of @ses and its children */
+12 −9
Original line number Diff line number Diff line
@@ -1943,7 +1943,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
	}

	/* no need to setup directory caching on IPC share, so pass in false */
	tcon = tcon_info_alloc(false);
	tcon = tcon_info_alloc(false, netfs_trace_tcon_ref_new_ipc);
	if (tcon == NULL)
		return -ENOMEM;

@@ -1960,7 +1960,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)

	if (rc) {
		cifs_server_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc);
		tconInfoFree(tcon);
		tconInfoFree(tcon, netfs_trace_tcon_ref_free_ipc_fail);
		goto out;
	}

@@ -2043,7 +2043,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
	 * files on session close, as specified in MS-SMB2 3.3.5.6 Receiving an
	 * SMB2 LOGOFF Request.
	 */
	tconInfoFree(tcon);
	tconInfoFree(tcon, netfs_trace_tcon_ref_free_ipc);
	if (do_logoff) {
		xid = get_xid();
		rc = server->ops->logoff(xid, ses);
@@ -2432,6 +2432,8 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
			continue;
		}
		++tcon->tc_count;
		trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
				    netfs_trace_tcon_ref_get_find);
		spin_unlock(&tcon->tc_lock);
		spin_unlock(&cifs_tcp_ses_lock);
		return tcon;
@@ -2441,7 +2443,7 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
}

void
cifs_put_tcon(struct cifs_tcon *tcon)
cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
{
	unsigned int xid;
	struct cifs_ses *ses;
@@ -2457,6 +2459,7 @@ cifs_put_tcon(struct cifs_tcon *tcon)
	cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
	spin_lock(&cifs_tcp_ses_lock);
	spin_lock(&tcon->tc_lock);
	trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count - 1, trace);
	if (--tcon->tc_count > 0) {
		spin_unlock(&tcon->tc_lock);
		spin_unlock(&cifs_tcp_ses_lock);
@@ -2493,7 +2496,7 @@ cifs_put_tcon(struct cifs_tcon *tcon)
	_free_xid(xid);

	cifs_fscache_release_super_cookie(tcon);
	tconInfoFree(tcon);
	tconInfoFree(tcon, netfs_trace_tcon_ref_free);
	cifs_put_smb_ses(ses);
}

@@ -2547,7 +2550,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
		nohandlecache = ctx->nohandlecache;
	else
		nohandlecache = true;
	tcon = tcon_info_alloc(!nohandlecache);
	tcon = tcon_info_alloc(!nohandlecache, netfs_trace_tcon_ref_new);
	if (tcon == NULL) {
		rc = -ENOMEM;
		goto out_fail;
@@ -2737,7 +2740,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
	return tcon;

out_fail:
	tconInfoFree(tcon);
	tconInfoFree(tcon, netfs_trace_tcon_ref_free_fail);
	return ERR_PTR(rc);
}

@@ -2754,7 +2757,7 @@ cifs_put_tlink(struct tcon_link *tlink)
	}

	if (!IS_ERR(tlink_tcon(tlink)))
		cifs_put_tcon(tlink_tcon(tlink));
		cifs_put_tcon(tlink_tcon(tlink), netfs_trace_tcon_ref_put_tlink);
	kfree(tlink);
}

@@ -3319,7 +3322,7 @@ void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx)
	int rc = 0;

	if (mnt_ctx->tcon)
		cifs_put_tcon(mnt_ctx->tcon);
		cifs_put_tcon(mnt_ctx->tcon, netfs_trace_tcon_ref_put_mnt_ctx);
	else if (mnt_ctx->ses)
		cifs_put_smb_ses(mnt_ctx->ses);
	else if (mnt_ctx->server)
+12 −0
Original line number Diff line number Diff line
@@ -748,6 +748,16 @@ static int smb3_fs_context_validate(struct fs_context *fc)
	/* set the port that we got earlier */
	cifs_set_port((struct sockaddr *)&ctx->dstaddr, ctx->port);

	if (ctx->uid_specified && !ctx->forceuid_specified) {
		ctx->override_uid = 1;
		pr_notice("enabling forceuid mount option implicitly because uid= option is specified\n");
	}

	if (ctx->gid_specified && !ctx->forcegid_specified) {
		ctx->override_gid = 1;
		pr_notice("enabling forcegid mount option implicitly because gid= option is specified\n");
	}

	if (ctx->override_uid && !ctx->uid_specified) {
		ctx->override_uid = 0;
		pr_notice("ignoring forceuid mount option specified with no uid= option\n");
@@ -1019,12 +1029,14 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
			ctx->override_uid = 0;
		else
			ctx->override_uid = 1;
		ctx->forceuid_specified = true;
		break;
	case Opt_forcegid:
		if (result.negated)
			ctx->override_gid = 0;
		else
			ctx->override_gid = 1;
		ctx->forcegid_specified = true;
		break;
	case Opt_perm:
		if (result.negated)
Loading