Patch "cifs: Fix reacquisition of volume cookie on still-live connection" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    cifs: Fix reacquisition of volume cookie on still-live connection

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     cifs-fix-reacquisition-of-volume-cookie-on-still-liv.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 0463487c002d53d83d346bb7ca8f90a93e358c6a
Author: David Howells <dhowells@xxxxxxxxxx>
Date:   Thu Apr 4 16:05:19 2024 +0100

    cifs: Fix reacquisition of volume cookie on still-live connection
    
    [ Upstream commit dad80c6bff770d25f67ec25fe011730e4a463008 ]
    
    During mount, cifs_mount_get_tcon() gets a tcon resource connection record
    and then attaches an fscache volume cookie to it.  However, it does this
    irrespective of whether or not the tcon returned from cifs_get_tcon() is a
    new record or one that's already in use.  This leads to a warning about a
    volume cookie collision and a leaked volume cookie because tcon->fscache
    gets reset.
    
    Fix this be adding a mutex and a "we've already tried this" flag and only
    doing it once for the lifetime of the tcon.
    
    [!] Note: Looking at cifs_mount_get_tcon(), a more general solution may
    actually be required.  Reacquiring the volume cookie isn't the only thing
    that function does: it also partially reinitialises the tcon record without
    any locking - which may cause live filesystem ops already using the tcon
    through a previous mount to malfunction.
    
    This can be reproduced simply by something like:
    
        mount //example.com/test /xfstest.test -o user=shares,pass=xxx,fsc
        mount //example.com/test /mnt -o user=shares,pass=xxx,fsc
    
    Fixes: 70431bfd825d ("cifs: Support fscache indexing rewrite")
    Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
    Acked-by: Paulo Alcantara (Red Hat) <pc@xxxxxxxxxxxxx>
    cc: Shyam Prasad N <sprasad@xxxxxxxxxxxxx>
    cc: linux-cifs@xxxxxxxxxxxxxxx
    cc: linux-fsdevel@xxxxxxxxxxxxxxx
    Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 68fd61a564089..12a48e1d80c3f 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1247,7 +1247,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;
diff --git a/fs/smb/client/fscache.c b/fs/smb/client/fscache.c
index a4ee801b29394..ecabc4b400535 100644
--- a/fs/smb/client/fscache.c
+++ b/fs/smb/client/fscache.c
@@ -43,12 +43,23 @@ int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
 	char *key;
 	int ret = -ENOMEM;
 
+	if (tcon->fscache_acquired)
+		return 0;
+
+	mutex_lock(&tcon->fscache_lock);
+	if (tcon->fscache_acquired) {
+		mutex_unlock(&tcon->fscache_lock);
+		return 0;
+	}
+	tcon->fscache_acquired = true;
+
 	tcon->fscache = NULL;
 	switch (sa->sa_family) {
 	case AF_INET:
 	case AF_INET6:
 		break;
 	default:
+		mutex_unlock(&tcon->fscache_lock);
 		cifs_dbg(VFS, "Unknown network family '%d'\n", sa->sa_family);
 		return -EINVAL;
 	}
@@ -57,6 +68,7 @@ int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
 
 	sharename = extract_sharename(tcon->tree_name);
 	if (IS_ERR(sharename)) {
+		mutex_unlock(&tcon->fscache_lock);
 		cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__);
 		return PTR_ERR(sharename);
 	}
@@ -90,6 +102,7 @@ int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
 	kfree(key);
 out:
 	kfree(sharename);
+	mutex_unlock(&tcon->fscache_lock);
 	return ret;
 }
 
diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
index 74627d647818a..0d13db80e67c9 100644
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -141,6 +141,9 @@ tcon_info_alloc(bool dir_leases_enabled)
 	atomic_set(&ret_buf->num_local_opens, 0);
 	atomic_set(&ret_buf->num_remote_opens, 0);
 	ret_buf->stats_from_time = ktime_get_real_seconds();
+#ifdef CONFIG_CIFS_FSCACHE
+	mutex_init(&ret_buf->fscache_lock);
+#endif
 
 	return ret_buf;
 }




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux