Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 046462ab authored by Sean Finney's avatar Sean Finney Committed by Steve French
Browse files

cifs: Simplify handling of submount options in cifs_mount.



With CONFIG_DFS_UPCALL enabled, maintain the submount options in
cifs_sb->mountdata, simplifying the code just a bit as well as making
corner-case allocation problems less likely.

Reviewed-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSean Finney <seanius@seanius.net>
Signed-off-by: default avatarPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent b946845a
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -2788,9 +2788,9 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
/*
 * Perform a dfs referral query for a share and (optionally) prefix
 *
 * If a referral is found, mount_data will be set to point at a newly
 * allocated string containing updated options for the submount.
 * Otherwise it will be left untouched.
 * If a referral is found, cifs_sb->mountdata will be (re-)allocated
 * to a string containing updated options for the submount.  Otherwise it
 * will be left untouched.
 *
 * Returns the rc from get_dfs_path to the caller, which can be used to
 * determine whether there were referrals.
@@ -2798,7 +2798,7 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
static int
expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo,
		    struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
		    char **mount_data, int check_prefix)
		    int check_prefix)
{
	int rc;
	unsigned int num_referrals = 0;
@@ -2826,11 +2826,14 @@ expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo,
		free_dfs_info_array(referrals, num_referrals);
		kfree(fake_devname);

		if (cifs_sb->mountdata != NULL)
			kfree(cifs_sb->mountdata);

		if (IS_ERR(mdata)) {
			rc = PTR_ERR(mdata);
			mdata = NULL;
		}
		*mount_data = mdata;
		cifs_sb->mountdata = mdata;
	}
	kfree(full_path);
	return rc;
@@ -2853,6 +2856,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
#ifdef CONFIG_CIFS_DFS_UPCALL
	int referral_walks_count = 0;
try_mount_again:
	mount_data = cifs_sb->mountdata;

	/* cleanup activities if we're chasing a referral */
	if (referral_walks_count) {
@@ -2986,7 +2990,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
	 */
	if (referral_walks_count == 0) {
		int refrc = expand_dfs_referral(xid, pSesInfo, volume_info,
						cifs_sb, &mount_data, false);
						cifs_sb, false);
		if (!refrc) {
			referral_walks_count++;
			goto try_mount_again;
@@ -3028,17 +3032,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
			convert_delimiter(cifs_sb->prepath,
					CIFS_DIR_SEP(cifs_sb));

		if (mount_data != mount_data_global)
			kfree(mount_data);

		rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb,
					 &mount_data, true);
					 true);

		if (!rc) {
			referral_walks_count++;
			goto try_mount_again;
		}
		mount_data = NULL;
		goto mount_fail_check;
#else /* No DFS support, return error on mount */
		rc = -EOPNOTSUPP;
@@ -3072,8 +3072,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
mount_fail_check:
	/* on error free sesinfo and tcon struct if needed */
	if (rc) {
		if (mount_data != mount_data_global)
			kfree(mount_data);
		/* If find_unc succeeded then rc == 0 so we can not end */
		/* up accidentally freeing someone elses tcon struct */
		if (tcon)