]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
smb: client: use ParentLeaseKey in open_cached_dir
authorHenrique Carvalho <henrique.carvalho@suse.com>
Thu, 8 May 2025 16:37:50 +0000 (13:37 -0300)
committerSteve French <stfrench@microsoft.com>
Mon, 2 Jun 2025 01:46:45 +0000 (20:46 -0500)
Implement ParentLeaseKey logic in open_cached_dir() by looking up the
parent cfid, copying its lease key into the fid struct, and setting
the appropriate lease flag.

Fixes: f047390a097e ("CIFS: Add create lease v2 context for SMB3")
Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cached_dir.c

index 240d82c6f908063b9efc0c8726ec1d44f12aa289..7482b7caa575e47d87503246c0a74d59f230a37f 100644 (file)
@@ -154,6 +154,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
        struct cached_fids *cfids;
        const char *npath;
        int retries = 0, cur_sleep = 1;
+       __le32 lease_flags = 0;
 
        if (cifs_sb->root == NULL)
                return -ENOENT;
@@ -200,6 +201,8 @@ replay_again:
        }
        spin_unlock(&cfids->cfid_list_lock);
 
+       pfid = &cfid->fid;
+
        /*
         * Skip any prefix paths in @path as lookup_positive_unlocked() ends up
         * calling ->lookup() which already adds those through
@@ -221,6 +224,25 @@ replay_again:
                        rc = -ENOENT;
                        goto out;
                }
+               if (dentry->d_parent && server->dialect >= SMB30_PROT_ID) {
+                       struct cached_fid *parent_cfid;
+
+                       spin_lock(&cfids->cfid_list_lock);
+                       list_for_each_entry(parent_cfid, &cfids->entries, entry) {
+                               if (parent_cfid->dentry == dentry->d_parent) {
+                                       cifs_dbg(FYI, "found a parent cached file handle\n");
+                                       if (parent_cfid->has_lease && parent_cfid->time) {
+                                               lease_flags
+                                                       |= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE;
+                                               memcpy(pfid->parent_lease_key,
+                                                      parent_cfid->fid.lease_key,
+                                                      SMB2_LEASE_KEY_SIZE);
+                                       }
+                                       break;
+                               }
+                       }
+                       spin_unlock(&cfids->cfid_list_lock);
+               }
        }
        cfid->dentry = dentry;
        cfid->tcon = tcon;
@@ -235,7 +257,6 @@ replay_again:
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
 
-       pfid = &cfid->fid;
        server->ops->new_lease_key(pfid);
 
        memset(rqst, 0, sizeof(rqst));
@@ -255,6 +276,7 @@ replay_again:
                                   FILE_READ_EA,
                .disposition = FILE_OPEN,
                .fid = pfid,
+               .lease_flags = lease_flags,
                .replay = !!(retries),
        };