summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnzo Matsumiya <ematsumiya@suse.de>2025-09-12 14:46:54 -0300
committerEnzo Matsumiya <ematsumiya@suse.de>2025-09-12 17:27:38 -0300
commit88ec1e734bbae9acaff4ac5b22d85dcb50df670b (patch)
treeeec26334483b23ca1d77914a4ec8ff5edb719363
parent4244daa61f7c8288f7d059763954b515603dd30a (diff)
downloadlinux-88ec1e734bbae9acaff4ac5b22d85dcb50df670b.tar.gz
linux-88ec1e734bbae9acaff4ac5b22d85dcb50df670b.tar.bz2
linux-88ec1e734bbae9acaff4ac5b22d85dcb50df670b.zip
smb: client: add CFID_LOOKUP_PARENT lookup modifier
Add support for find_cached_dir() to lookup for a path's parent. * will be used to set ParentLeaseKey on opens Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
-rw-r--r--fs/smb/client/cached_dir.c24
-rw-r--r--fs/smb/client/cached_dir.h4
2 files changed, 27 insertions, 1 deletions
diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index c4f110fc66d5..ad9c95c20c4e 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -134,10 +134,28 @@ static const char *path_no_prefix(struct cifs_sb_info *cifs_sb,
struct cached_fid *find_cached_dir(struct cached_fids *cfids, const void *key, int mode)
{
struct cached_fid *cfid;
+ char *parent_path = NULL;
if (!cfids || !key)
return NULL;
+ /* special case */
+ if (mode == CFID_LOOKUP_PARENT) {
+ const char *path = key;
+
+ if (!*path)
+ return NULL;
+
+ parent_path = strrchr(path, cfids->dirsep);
+ if (!parent_path)
+ return NULL;
+
+ parent_path = kstrndup(path, parent_path - path, GFP_ATOMIC);
+ if (!parent_path)
+ return NULL;
+
+ key = parent_path;
+ }
retry_find:
cfid = find_cfid(cfids, key, mode);
if (cfid) {
@@ -159,6 +177,8 @@ retry_find:
}
}
+ kfree(parent_path);
+
return cfid;
}
@@ -200,9 +220,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, const char *path,
ses = tcon->ses;
cfids = tcon->cfids;
-
if (!cfids)
return -EOPNOTSUPP;
+
+ if (!cfids->dirsep)
+ cfids->dirsep = CIFS_DIR_SEP(cifs_sb);
replay_again:
/* reinitialize for possible replay */
flags = 0;
diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h
index 73e28b04b519..537730a74867 100644
--- a/fs/smb/client/cached_dir.h
+++ b/fs/smb/client/cached_dir.h
@@ -55,11 +55,15 @@ struct cached_fids {
int num_entries;
struct list_head entries;
struct delayed_work laundromat_work;
+
+ /* convenience for CFID_LOOKUP_PARENT */
+ int dirsep;
};
/* Lookup modes for find_cached_dir() */
enum {
CFID_LOOKUP_PATH,
+ CFID_LOOKUP_PARENT,
CFID_LOOKUP_DENTRY,
CFID_LOOKUP_LEASEKEY,
};