* [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot
[not found] <20210308230735.337-1-lsahlber@redhat.com>
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-04-09 4:42 ` Steve French
2021-04-10 0:05 ` Steve French
2021-03-08 23:07 ` [PATCH 2/9] cifs: pass a path to open_shroot and check if it is the root or not Ronnie Sahlberg
` (7 subsequent siblings)
8 siblings, 2 replies; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
instead of doing it in the callsites for open_shroot.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/smb2inode.c | 24 +++++++++++-------------
fs/cifs/smb2ops.c | 16 ++++++++--------
2 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 1f900b81c34a..3d59614cbe8f 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -511,7 +511,6 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
int rc;
struct smb2_file_all_info *smb2_data;
__u32 create_options = 0;
- bool no_cached_open = tcon->nohandlecache;
struct cifsFileInfo *cfile;
struct cached_fid *cfid = NULL;
@@ -524,23 +523,22 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
return -ENOMEM;
/* If it is a root and its handle is cached then use it */
- if (!strlen(full_path) && !no_cached_open) {
+ if (!strlen(full_path)) {
rc = open_shroot(xid, tcon, cifs_sb, &cfid);
- if (rc)
- goto out;
-
- if (tcon->crfid.file_all_info_is_valid) {
- move_smb2_info_to_cifs(data,
+ if (!rc) {
+ if (tcon->crfid.file_all_info_is_valid) {
+ move_smb2_info_to_cifs(data,
&tcon->crfid.file_all_info);
- } else {
- rc = SMB2_query_info(xid, tcon,
+ } else {
+ rc = SMB2_query_info(xid, tcon,
cfid->fid->persistent_fid,
cfid->fid->volatile_fid, smb2_data);
- if (!rc)
- move_smb2_info_to_cifs(data, smb2_data);
+ if (!rc)
+ move_smb2_info_to_cifs(data, smb2_data);
+ }
+ close_shroot(cfid);
+ goto out;
}
- close_shroot(cfid);
- goto out;
}
cifs_get_readable_path(tcon, full_path, &cfile);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index f5087295424c..7ee6926153b8 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -746,6 +746,9 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
u8 oplock = SMB2_OPLOCK_LEVEL_II;
struct cifs_fid *pfid;
+ if (tcon->nohandlecache)
+ return -ENOTSUPP;
+
mutex_lock(&tcon->crfid.fid_mutex);
if (tcon->crfid.is_valid) {
cifs_dbg(FYI, "found a cached root file handle\n");
@@ -914,7 +917,6 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
struct cifs_open_parms oparms;
struct cifs_fid fid;
- bool no_cached_open = tcon->nohandlecache;
struct cached_fid *cfid = NULL;
oparms.tcon = tcon;
@@ -924,14 +926,12 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = &fid;
oparms.reconnect = false;
- if (no_cached_open) {
+ rc = open_shroot(xid, tcon, cifs_sb, &cfid);
+ if (rc == 0)
+ memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
+ else
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
NULL, NULL);
- } else {
- rc = open_shroot(xid, tcon, cifs_sb, &cfid);
- if (rc == 0)
- memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
- }
if (rc)
return;
@@ -945,7 +945,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
FS_VOLUME_INFORMATION);
SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
- if (no_cached_open)
+ if (cfid == NULL)
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
else
close_shroot(cfid);
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/9] cifs: pass a path to open_shroot and check if it is the root or not
[not found] <20210308230735.337-1-lsahlber@redhat.com>
2021-03-08 23:07 ` [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-04-10 0:08 ` Steve French
2021-03-08 23:07 ` [PATCH 3/9] cifs: rename the *_shroot* functions to *_cached_dir* Ronnie Sahlberg
` (6 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
Move the check for the directory path into the open_shroot() function
but still fail for any non-root directories.
This is preparation for later when we will start using the cache also
for other directories than the root.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/smb2inode.c | 22 ++++++++++------------
fs/cifs/smb2ops.c | 6 +++++-
fs/cifs/smb2proto.h | 1 +
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 3d59614cbe8f..67f80c9561fc 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -523,22 +523,20 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
return -ENOMEM;
/* If it is a root and its handle is cached then use it */
- if (!strlen(full_path)) {
- rc = open_shroot(xid, tcon, cifs_sb, &cfid);
- if (!rc) {
- if (tcon->crfid.file_all_info_is_valid) {
- move_smb2_info_to_cifs(data,
+ rc = open_shroot(xid, tcon, full_path, cifs_sb, &cfid);
+ if (!rc) {
+ if (tcon->crfid.file_all_info_is_valid) {
+ move_smb2_info_to_cifs(data,
&tcon->crfid.file_all_info);
- } else {
- rc = SMB2_query_info(xid, tcon,
+ } else {
+ rc = SMB2_query_info(xid, tcon,
cfid->fid->persistent_fid,
cfid->fid->volatile_fid, smb2_data);
- if (!rc)
- move_smb2_info_to_cifs(data, smb2_data);
- }
- close_shroot(cfid);
- goto out;
+ if (!rc)
+ move_smb2_info_to_cifs(data, smb2_data);
}
+ close_shroot(cfid);
+ goto out;
}
cifs_get_readable_path(tcon, full_path, &cfile);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 7ee6926153b8..96ff946674e6 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -728,6 +728,7 @@ smb2_cached_lease_break(struct work_struct *work)
* Open the directory at the root of a share
*/
int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
+ const char *path,
struct cifs_sb_info *cifs_sb,
struct cached_fid **cfid)
{
@@ -749,6 +750,9 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
if (tcon->nohandlecache)
return -ENOTSUPP;
+ if (strlen(path))
+ return -ENOTSUPP;
+
mutex_lock(&tcon->crfid.fid_mutex);
if (tcon->crfid.is_valid) {
cifs_dbg(FYI, "found a cached root file handle\n");
@@ -926,7 +930,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = &fid;
oparms.reconnect = false;
- rc = open_shroot(xid, tcon, cifs_sb, &cfid);
+ rc = open_shroot(xid, tcon, "", cifs_sb, &cfid);
if (rc == 0)
memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
else
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 9565e27681a5..7e4fc69c8b01 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -70,6 +70,7 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server,
struct mid_q_entry *mid);
extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
+ const char *path,
struct cifs_sb_info *cifs_sb,
struct cached_fid **cfid);
extern void close_shroot(struct cached_fid *cfid);
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/9] cifs: rename the *_shroot* functions to *_cached_dir*
[not found] <20210308230735.337-1-lsahlber@redhat.com>
2021-03-08 23:07 ` [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 2/9] cifs: pass a path to open_shroot and check if it is the root or not Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-04-10 0:10 ` Steve French
2021-03-08 23:07 ` [PATCH 4/9] cifs: store a pointer to the root dentry in cifs_sb_info once we have completed mounting the share Ronnie Sahlberg
` (5 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
These functions will eventually be used to cache any directory, not just the root
so change the names.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/cifssmb.c | 2 +-
fs/cifs/smb2inode.c | 4 ++--
fs/cifs/smb2ops.c | 19 ++++++++++---------
fs/cifs/smb2pdu.c | 2 +-
fs/cifs/smb2proto.h | 14 +++++++-------
5 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 0496934feecb..3419289b7663 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -114,7 +114,7 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
mutex_lock(&tcon->crfid.fid_mutex);
tcon->crfid.is_valid = false;
/* cached handle is not valid, so SMB2_CLOSE won't be sent below */
- close_shroot_lease_locked(&tcon->crfid);
+ close_cached_dir_lease_locked(&tcon->crfid);
memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
mutex_unlock(&tcon->crfid.fid_mutex);
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 67f80c9561fc..0d0bc0b878be 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -523,7 +523,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
return -ENOMEM;
/* If it is a root and its handle is cached then use it */
- rc = open_shroot(xid, tcon, full_path, cifs_sb, &cfid);
+ rc = open_cached_dir(xid, tcon, full_path, cifs_sb, &cfid);
if (!rc) {
if (tcon->crfid.file_all_info_is_valid) {
move_smb2_info_to_cifs(data,
@@ -535,7 +535,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
if (!rc)
move_smb2_info_to_cifs(data, smb2_data);
}
- close_shroot(cfid);
+ close_cached_dir(cfid);
goto out;
}
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 96ff946674e6..d2858c25ff17 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -693,14 +693,14 @@ smb2_close_cached_fid(struct kref *ref)
}
}
-void close_shroot(struct cached_fid *cfid)
+void close_cached_dir(struct cached_fid *cfid)
{
mutex_lock(&cfid->fid_mutex);
kref_put(&cfid->refcount, smb2_close_cached_fid);
mutex_unlock(&cfid->fid_mutex);
}
-void close_shroot_lease_locked(struct cached_fid *cfid)
+void close_cached_dir_lease_locked(struct cached_fid *cfid)
{
if (cfid->has_lease) {
cfid->has_lease = false;
@@ -708,10 +708,10 @@ void close_shroot_lease_locked(struct cached_fid *cfid)
}
}
-void close_shroot_lease(struct cached_fid *cfid)
+void close_cached_dir_lease(struct cached_fid *cfid)
{
mutex_lock(&cfid->fid_mutex);
- close_shroot_lease_locked(cfid);
+ close_cached_dir_lease_locked(cfid);
mutex_unlock(&cfid->fid_mutex);
}
@@ -721,13 +721,14 @@ smb2_cached_lease_break(struct work_struct *work)
struct cached_fid *cfid = container_of(work,
struct cached_fid, lease_break);
- close_shroot_lease(cfid);
+ close_cached_dir_lease(cfid);
}
/*
- * Open the directory at the root of a share
+ * Open the and cache a directory handle.
+ * Only supported for the root handle.
*/
-int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
+int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
const char *path,
struct cifs_sb_info *cifs_sb,
struct cached_fid **cfid)
@@ -930,7 +931,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = &fid;
oparms.reconnect = false;
- rc = open_shroot(xid, tcon, "", cifs_sb, &cfid);
+ rc = open_cached_dir(xid, tcon, "", cifs_sb, &cfid);
if (rc == 0)
memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
else
@@ -952,7 +953,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
if (cfid == NULL)
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
else
- close_shroot(cfid);
+ close_cached_dir(cfid);
}
static void
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 4bbb6126b14d..0a03f8d88173 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1857,7 +1857,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
return 0;
- close_shroot_lease(&tcon->crfid);
+ close_cached_dir_lease(&tcon->crfid);
rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, ses->server,
(void **) &req,
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 7e4fc69c8b01..ddbdf9923625 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -69,13 +69,13 @@ extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server,
extern int smb3_handle_read_data(struct TCP_Server_Info *server,
struct mid_q_entry *mid);
-extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
- const char *path,
- struct cifs_sb_info *cifs_sb,
- struct cached_fid **cfid);
-extern void close_shroot(struct cached_fid *cfid);
-extern void close_shroot_lease(struct cached_fid *cfid);
-extern void close_shroot_lease_locked(struct cached_fid *cfid);
+extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
+ const char *path,
+ struct cifs_sb_info *cifs_sb,
+ struct cached_fid **cfid);
+extern void close_cached_dir(struct cached_fid *cfid);
+extern void close_cached_dir_lease(struct cached_fid *cfid);
+extern void close_cached_dir_lease_locked(struct cached_fid *cfid);
extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst,
struct smb2_file_all_info *src);
extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/9] cifs: store a pointer to the root dentry in cifs_sb_info once we have completed mounting the share
[not found] <20210308230735.337-1-lsahlber@redhat.com>
` (2 preceding siblings ...)
2021-03-08 23:07 ` [PATCH 3/9] cifs: rename the *_shroot* functions to *_cached_dir* Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-04-10 0:57 ` Steve French
2021-03-08 23:07 ` [PATCH 5/9] cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache Ronnie Sahlberg
` (4 subsequent siblings)
8 siblings, 1 reply; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
And use this to only allow to take out a shared handle once the mount has completed and the
sb becomes available.
This will become important in follow up patches where we will start holding a reference to the
directory dentry for the shared handle during the lifetime of the handle.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/cifs_fs_sb.h | 4 ++++
fs/cifs/cifsfs.c | 9 +++++++++
fs/cifs/smb2ops.c | 5 ++++-
3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index aa77edc12212..2a5325a7ae49 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -81,5 +81,9 @@ struct cifs_sb_info {
* (cifs_autodisable_serverino) in order to match new mounts.
*/
bool mnt_cifs_serverino_autodisabled;
+ /*
+ * Available once the mount has completed.
+ */
+ struct dentry *root;
};
#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 3b61f09f3e1b..c075ef1dd755 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -257,6 +257,12 @@ cifs_read_super(struct super_block *sb)
static void cifs_kill_sb(struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+
+ if (cifs_sb->root) {
+ dput(cifs_sb->root);
+ cifs_sb->root = NULL;
+ }
+
kill_anon_super(sb);
cifs_umount(cifs_sb);
}
@@ -886,6 +892,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
if (IS_ERR(root))
goto out_super;
+ if (cifs_sb)
+ cifs_sb->root = dget(root);
+
cifs_dbg(FYI, "dentry root is: %p\n", root);
return root;
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index d2858c25ff17..7f4da573b9e8 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -751,8 +751,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
if (tcon->nohandlecache)
return -ENOTSUPP;
+ if (cifs_sb->root == NULL)
+ return -ENOENT;
+
if (strlen(path))
- return -ENOTSUPP;
+ return -ENOENT;
mutex_lock(&tcon->crfid.fid_mutex);
if (tcon->crfid.is_valid) {
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/9] cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache
[not found] <20210308230735.337-1-lsahlber@redhat.com>
` (3 preceding siblings ...)
2021-03-08 23:07 ` [PATCH 4/9] cifs: store a pointer to the root dentry in cifs_sb_info once we have completed mounting the share Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 6/9] cifs: add a function to get a cached dir based on its dentry Ronnie Sahlberg
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
We need to hold both a reference for the root/superblock as well as the directory that we
are caching. We need to drop these references before we call kill_anon_sb().
At this point, the root and the cached dentries are always the same but this will change
once we start caching other directories as well.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/cifsfs.c | 17 +++++++++++++++++
fs/cifs/cifsglob.h | 1 +
fs/cifs/smb2ops.c | 9 +++++++++
3 files changed, 27 insertions(+)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index c075ef1dd755..154f1c94ea46 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -257,11 +257,28 @@ cifs_read_super(struct super_block *sb)
static void cifs_kill_sb(struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ struct cifs_tcon *tcon;
+ struct cached_fid *cfid;
+ /*
+ * We ned to release all dentries for the cached directories
+ * before we kill the sb.
+ */
if (cifs_sb->root) {
dput(cifs_sb->root);
cifs_sb->root = NULL;
}
+ tcon = cifs_sb_master_tcon(cifs_sb);
+ if (tcon) {
+ cfid = &tcon->crfid;
+ mutex_lock(&cfid->fid_mutex);
+ if (cfid->dentry) {
+
+ dput(cfid->dentry);
+ cfid->dentry = NULL;
+ }
+ mutex_unlock(&cfid->fid_mutex);
+ }
kill_anon_super(sb);
cifs_umount(cifs_sb);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 3de3c5908a72..7d9b47f2f04f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -992,6 +992,7 @@ struct cached_fid {
struct cifs_fid *fid;
struct mutex fid_mutex;
struct cifs_tcon *tcon;
+ struct dentry *dentry;
struct work_struct lease_break;
struct smb2_file_all_info file_all_info;
};
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 7f4da573b9e8..81eb7f10368b 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -690,6 +690,10 @@ smb2_close_cached_fid(struct kref *ref)
cfid->is_valid = false;
cfid->file_all_info_is_valid = false;
cfid->has_lease = false;
+ if (cfid->dentry) {
+ dput(cfid->dentry);
+ cfid->dentry = NULL;
+ }
}
}
@@ -747,6 +751,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
__le16 utf16_path = 0; /* Null - since an open of top of share */
u8 oplock = SMB2_OPLOCK_LEVEL_II;
struct cifs_fid *pfid;
+ struct dentry *dentry;
if (tcon->nohandlecache)
return -ENOTSUPP;
@@ -757,6 +762,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
if (strlen(path))
return -ENOENT;
+ dentry = cifs_sb->root;
+
mutex_lock(&tcon->crfid.fid_mutex);
if (tcon->crfid.is_valid) {
cifs_dbg(FYI, "found a cached root file handle\n");
@@ -881,6 +888,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid));
tcon->crfid.tcon = tcon;
tcon->crfid.is_valid = true;
+ tcon->crfid.dentry = dentry;
+ dget(dentry);
kref_init(&tcon->crfid.refcount);
/* BB TBD check to see if oplock level check can be removed below */
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/9] cifs: add a function to get a cached dir based on its dentry
[not found] <20210308230735.337-1-lsahlber@redhat.com>
` (4 preceding siblings ...)
2021-03-08 23:07 ` [PATCH 5/9] cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 7/9] cifs: add a timestamp to track when the lease of the cached dir was taken Ronnie Sahlberg
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/smb2ops.c | 16 ++++++++++++++++
fs/cifs/smb2proto.h | 3 +++
2 files changed, 19 insertions(+)
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 81eb7f10368b..9e2e1ce915c9 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -925,6 +925,22 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
return rc;
}
+int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
+ struct dentry *dentry,
+ struct cached_fid **cfid)
+{
+ mutex_lock(&tcon->crfid.fid_mutex);
+ if (tcon->crfid.dentry == dentry) {
+ cifs_dbg(FYI, "found a cached root file handle by dentry\n");
+ *cfid = &tcon->crfid;
+ kref_get(&tcon->crfid.refcount);
+ mutex_unlock(&tcon->crfid.fid_mutex);
+ return 0;
+ }
+ mutex_unlock(&tcon->crfid.fid_mutex);
+ return -ENOENT;
+}
+
static void
smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb)
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index ddbdf9923625..3b1cc27947df 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -73,6 +73,9 @@ extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
const char *path,
struct cifs_sb_info *cifs_sb,
struct cached_fid **cfid);
+extern int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
+ struct dentry *dentry,
+ struct cached_fid **cfid);
extern void close_cached_dir(struct cached_fid *cfid);
extern void close_cached_dir_lease(struct cached_fid *cfid);
extern void close_cached_dir_lease_locked(struct cached_fid *cfid);
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 7/9] cifs: add a timestamp to track when the lease of the cached dir was taken
[not found] <20210308230735.337-1-lsahlber@redhat.com>
` (5 preceding siblings ...)
2021-03-08 23:07 ` [PATCH 6/9] cifs: add a function to get a cached dir based on its dentry Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 8/9] cifs: pass the dentry instead of the inode down to the revalidation check functions Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 9/9] cifs: check the timestamp for the cached dirent when deciding on revalidate Ronnie Sahlberg
8 siblings, 0 replies; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
and clear the timestamp when we receive a lease break.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/cifsglob.h | 1 +
fs/cifs/smb2misc.c | 1 +
fs/cifs/smb2ops.c | 2 ++
3 files changed, 4 insertions(+)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7d9b47f2f04f..f6cebb36a27c 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -988,6 +988,7 @@ struct cached_fid {
bool is_valid:1; /* Do we have a useable root fid */
bool file_all_info_is_valid:1;
bool has_lease:1;
+ unsigned long time; /* jiffies of when lease was taken */
struct kref refcount;
struct cifs_fid *fid;
struct mutex fid_mutex;
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index 60d4bd1eae2b..e617d2975c99 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -667,6 +667,7 @@ smb2_is_valid_lease_break(char *buffer)
!memcmp(rsp->LeaseKey,
tcon->crfid.fid->lease_key,
SMB2_LEASE_KEY_SIZE)) {
+ tcon->crfid.time = 0;
INIT_WORK(&tcon->crfid.lease_break,
smb2_cached_lease_break);
queue_work(cifsiod_wq,
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 9e2e1ce915c9..34419b2af8e8 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -912,6 +912,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
&rsp_iov[1], sizeof(struct smb2_file_all_info),
(char *)&tcon->crfid.file_all_info))
tcon->crfid.file_all_info_is_valid = true;
+ tcon->crfid.time = jiffies;
+
oshr_exit:
mutex_unlock(&tcon->crfid.fid_mutex);
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 8/9] cifs: pass the dentry instead of the inode down to the revalidation check functions
[not found] <20210308230735.337-1-lsahlber@redhat.com>
` (6 preceding siblings ...)
2021-03-08 23:07 ` [PATCH 7/9] cifs: add a timestamp to track when the lease of the cached dir was taken Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 9/9] cifs: check the timestamp for the cached dirent when deciding on revalidate Ronnie Sahlberg
8 siblings, 0 replies; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/inode.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 0b0b01ef3ecb..98dc6d70d4fa 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2184,8 +2184,9 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
}
static bool
-cifs_inode_needs_reval(struct inode *inode)
+cifs_dentry_needs_reval(struct dentry *dentry)
{
+ struct inode *inode = d_inode(dentry);
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
@@ -2296,10 +2297,10 @@ cifs_zap_mapping(struct inode *inode)
int cifs_revalidate_file_attr(struct file *filp)
{
int rc = 0;
- struct inode *inode = file_inode(filp);
+ struct dentry *dentry = file_dentry(filp);
struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
- if (!cifs_inode_needs_reval(inode))
+ if (!cifs_dentry_needs_reval(dentry))
return rc;
if (tlink_tcon(cfile->tlink)->unix_ext)
@@ -2322,7 +2323,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
if (inode == NULL)
return -ENOENT;
- if (!cifs_inode_needs_reval(inode))
+ if (!cifs_dentry_needs_reval(dentry))
return rc;
xid = get_xid();
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 9/9] cifs: check the timestamp for the cached dirent when deciding on revalidate
[not found] <20210308230735.337-1-lsahlber@redhat.com>
` (7 preceding siblings ...)
2021-03-08 23:07 ` [PATCH 8/9] cifs: pass the dentry instead of the inode down to the revalidation check functions Ronnie Sahlberg
@ 2021-03-08 23:07 ` Ronnie Sahlberg
8 siblings, 0 replies; 14+ messages in thread
From: Ronnie Sahlberg @ 2021-03-08 23:07 UTC (permalink / raw)
To: linux-cifs; +Cc: Steve French
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
fs/cifs/inode.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 98dc6d70d4fa..95326025d77d 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2189,6 +2189,8 @@ cifs_dentry_needs_reval(struct dentry *dentry)
struct inode *inode = d_inode(dentry);
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cached_fid *cfid = NULL;
if (cifs_i->time == 0)
return true;
@@ -2199,6 +2201,16 @@ cifs_dentry_needs_reval(struct dentry *dentry)
if (!lookupCacheEnabled)
return true;
+ if (!open_cached_dir_by_dentry(tcon, dentry->d_parent, &cfid)) {
+ mutex_lock(&cfid->fid_mutex);
+ if (cfid->time && cifs_i->time > cfid->time) {
+ mutex_unlock(&cfid->fid_mutex);
+ close_cached_dir(cfid);
+ return false;
+ }
+ mutex_unlock(&cfid->fid_mutex);
+ close_cached_dir(cfid);
+ }
/*
* depending on inode type, check if attribute caching disabled for
* files or directories
--
2.13.6
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot
2021-03-08 23:07 ` [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot Ronnie Sahlberg
@ 2021-04-09 4:42 ` Steve French
2021-04-10 0:05 ` Steve French
1 sibling, 0 replies; 14+ messages in thread
From: Steve French @ 2021-04-09 4:42 UTC (permalink / raw)
To: Ronnie Sahlberg; +Cc: linux-cifs
Is there an updated version of this 9 patch series or is this current?
Any additional review feedback on it?
On Mon, Mar 8, 2021 at 5:08 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> instead of doing it in the callsites for open_shroot.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
> fs/cifs/smb2inode.c | 24 +++++++++++-------------
> fs/cifs/smb2ops.c | 16 ++++++++--------
> 2 files changed, 19 insertions(+), 21 deletions(-)
>
> diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
> index 1f900b81c34a..3d59614cbe8f 100644
> --- a/fs/cifs/smb2inode.c
> +++ b/fs/cifs/smb2inode.c
> @@ -511,7 +511,6 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> int rc;
> struct smb2_file_all_info *smb2_data;
> __u32 create_options = 0;
> - bool no_cached_open = tcon->nohandlecache;
> struct cifsFileInfo *cfile;
> struct cached_fid *cfid = NULL;
>
> @@ -524,23 +523,22 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> /* If it is a root and its handle is cached then use it */
> - if (!strlen(full_path) && !no_cached_open) {
> + if (!strlen(full_path)) {
> rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> - if (rc)
> - goto out;
> -
> - if (tcon->crfid.file_all_info_is_valid) {
> - move_smb2_info_to_cifs(data,
> + if (!rc) {
> + if (tcon->crfid.file_all_info_is_valid) {
> + move_smb2_info_to_cifs(data,
> &tcon->crfid.file_all_info);
> - } else {
> - rc = SMB2_query_info(xid, tcon,
> + } else {
> + rc = SMB2_query_info(xid, tcon,
> cfid->fid->persistent_fid,
> cfid->fid->volatile_fid, smb2_data);
> - if (!rc)
> - move_smb2_info_to_cifs(data, smb2_data);
> + if (!rc)
> + move_smb2_info_to_cifs(data, smb2_data);
> + }
> + close_shroot(cfid);
> + goto out;
> }
> - close_shroot(cfid);
> - goto out;
> }
>
> cifs_get_readable_path(tcon, full_path, &cfile);
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index f5087295424c..7ee6926153b8 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -746,6 +746,9 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
> u8 oplock = SMB2_OPLOCK_LEVEL_II;
> struct cifs_fid *pfid;
>
> + if (tcon->nohandlecache)
> + return -ENOTSUPP;
> +
> mutex_lock(&tcon->crfid.fid_mutex);
> if (tcon->crfid.is_valid) {
> cifs_dbg(FYI, "found a cached root file handle\n");
> @@ -914,7 +917,6 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
> struct cifs_open_parms oparms;
> struct cifs_fid fid;
> - bool no_cached_open = tcon->nohandlecache;
> struct cached_fid *cfid = NULL;
>
> oparms.tcon = tcon;
> @@ -924,14 +926,12 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> oparms.fid = &fid;
> oparms.reconnect = false;
>
> - if (no_cached_open) {
> + rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> + if (rc == 0)
> + memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
> + else
> rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
> NULL, NULL);
> - } else {
> - rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> - if (rc == 0)
> - memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
> - }
> if (rc)
> return;
>
> @@ -945,7 +945,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> FS_VOLUME_INFORMATION);
> SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
> FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
> - if (no_cached_open)
> + if (cfid == NULL)
> SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
> else
> close_shroot(cfid);
> --
> 2.13.6
>
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot
2021-03-08 23:07 ` [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot Ronnie Sahlberg
2021-04-09 4:42 ` Steve French
@ 2021-04-10 0:05 ` Steve French
1 sibling, 0 replies; 14+ messages in thread
From: Steve French @ 2021-04-10 0:05 UTC (permalink / raw)
To: Ronnie Sahlberg; +Cc: linux-cifs
checkpatch complains about
WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP
#71: FILE: fs/cifs/smb2ops.c:750:
include/linux/errno.h indicates that these in range 512 through 530 should
never be returned to userspace:
/*
* These should never be seen by user programs. To return one of ERESTART*
* codes, signal_pending() MUST be set. Note that ptrace can observe these
* at syscall exit tracing, but they will never be left for the debugged user
* process to see.
*/
... but since this is not returned to userspace, perhaps it is
harmless. Thoughts?
On Mon, Mar 8, 2021 at 5:08 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> instead of doing it in the callsites for open_shroot.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
> fs/cifs/smb2inode.c | 24 +++++++++++-------------
> fs/cifs/smb2ops.c | 16 ++++++++--------
> 2 files changed, 19 insertions(+), 21 deletions(-)
>
> diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
> index 1f900b81c34a..3d59614cbe8f 100644
> --- a/fs/cifs/smb2inode.c
> +++ b/fs/cifs/smb2inode.c
> @@ -511,7 +511,6 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> int rc;
> struct smb2_file_all_info *smb2_data;
> __u32 create_options = 0;
> - bool no_cached_open = tcon->nohandlecache;
> struct cifsFileInfo *cfile;
> struct cached_fid *cfid = NULL;
>
> @@ -524,23 +523,22 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> /* If it is a root and its handle is cached then use it */
> - if (!strlen(full_path) && !no_cached_open) {
> + if (!strlen(full_path)) {
> rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> - if (rc)
> - goto out;
> -
> - if (tcon->crfid.file_all_info_is_valid) {
> - move_smb2_info_to_cifs(data,
> + if (!rc) {
> + if (tcon->crfid.file_all_info_is_valid) {
> + move_smb2_info_to_cifs(data,
> &tcon->crfid.file_all_info);
> - } else {
> - rc = SMB2_query_info(xid, tcon,
> + } else {
> + rc = SMB2_query_info(xid, tcon,
> cfid->fid->persistent_fid,
> cfid->fid->volatile_fid, smb2_data);
> - if (!rc)
> - move_smb2_info_to_cifs(data, smb2_data);
> + if (!rc)
> + move_smb2_info_to_cifs(data, smb2_data);
> + }
> + close_shroot(cfid);
> + goto out;
> }
> - close_shroot(cfid);
> - goto out;
> }
>
> cifs_get_readable_path(tcon, full_path, &cfile);
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index f5087295424c..7ee6926153b8 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -746,6 +746,9 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
> u8 oplock = SMB2_OPLOCK_LEVEL_II;
> struct cifs_fid *pfid;
>
> + if (tcon->nohandlecache)
> + return -ENOTSUPP;
> +
> mutex_lock(&tcon->crfid.fid_mutex);
> if (tcon->crfid.is_valid) {
> cifs_dbg(FYI, "found a cached root file handle\n");
> @@ -914,7 +917,6 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
> struct cifs_open_parms oparms;
> struct cifs_fid fid;
> - bool no_cached_open = tcon->nohandlecache;
> struct cached_fid *cfid = NULL;
>
> oparms.tcon = tcon;
> @@ -924,14 +926,12 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> oparms.fid = &fid;
> oparms.reconnect = false;
>
> - if (no_cached_open) {
> + rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> + if (rc == 0)
> + memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
> + else
> rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
> NULL, NULL);
> - } else {
> - rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> - if (rc == 0)
> - memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
> - }
> if (rc)
> return;
>
> @@ -945,7 +945,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> FS_VOLUME_INFORMATION);
> SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
> FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
> - if (no_cached_open)
> + if (cfid == NULL)
> SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
> else
> close_shroot(cfid);
> --
> 2.13.6
>
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/9] cifs: pass a path to open_shroot and check if it is the root or not
2021-03-08 23:07 ` [PATCH 2/9] cifs: pass a path to open_shroot and check if it is the root or not Ronnie Sahlberg
@ 2021-04-10 0:08 ` Steve French
0 siblings, 0 replies; 14+ messages in thread
From: Steve French @ 2021-04-10 0:08 UTC (permalink / raw)
To: Ronnie Sahlberg; +Cc: linux-cifs
Similar checkpatch complaint about ENOTSUPP (instead of EOPNOTSUPP)
WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP
#74: FILE: fs/cifs/smb2ops.c:754:
+ return -ENOTSUPP;
the header which defines ENOTSUPP notes:
/*
* These should never be seen by user programs. To return one of ERESTART*
* codes, signal_pending() MUST be set. Note that ptrace can observe these
* at syscall exit tracing, but they will never be left for the debugged user
* process to see.
*/
On Mon, Mar 8, 2021 at 5:07 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> Move the check for the directory path into the open_shroot() function
> but still fail for any non-root directories.
> This is preparation for later when we will start using the cache also
> for other directories than the root.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
> fs/cifs/smb2inode.c | 22 ++++++++++------------
> fs/cifs/smb2ops.c | 6 +++++-
> fs/cifs/smb2proto.h | 1 +
> 3 files changed, 16 insertions(+), 13 deletions(-)
>
> diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
> index 3d59614cbe8f..67f80c9561fc 100644
> --- a/fs/cifs/smb2inode.c
> +++ b/fs/cifs/smb2inode.c
> @@ -523,22 +523,20 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> /* If it is a root and its handle is cached then use it */
> - if (!strlen(full_path)) {
> - rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> - if (!rc) {
> - if (tcon->crfid.file_all_info_is_valid) {
> - move_smb2_info_to_cifs(data,
> + rc = open_shroot(xid, tcon, full_path, cifs_sb, &cfid);
> + if (!rc) {
> + if (tcon->crfid.file_all_info_is_valid) {
> + move_smb2_info_to_cifs(data,
> &tcon->crfid.file_all_info);
> - } else {
> - rc = SMB2_query_info(xid, tcon,
> + } else {
> + rc = SMB2_query_info(xid, tcon,
> cfid->fid->persistent_fid,
> cfid->fid->volatile_fid, smb2_data);
> - if (!rc)
> - move_smb2_info_to_cifs(data, smb2_data);
> - }
> - close_shroot(cfid);
> - goto out;
> + if (!rc)
> + move_smb2_info_to_cifs(data, smb2_data);
> }
> + close_shroot(cfid);
> + goto out;
> }
>
> cifs_get_readable_path(tcon, full_path, &cfile);
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index 7ee6926153b8..96ff946674e6 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -728,6 +728,7 @@ smb2_cached_lease_break(struct work_struct *work)
> * Open the directory at the root of a share
> */
> int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
> + const char *path,
> struct cifs_sb_info *cifs_sb,
> struct cached_fid **cfid)
> {
> @@ -749,6 +750,9 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
> if (tcon->nohandlecache)
> return -ENOTSUPP;
>
> + if (strlen(path))
> + return -ENOTSUPP;
> +
> mutex_lock(&tcon->crfid.fid_mutex);
> if (tcon->crfid.is_valid) {
> cifs_dbg(FYI, "found a cached root file handle\n");
> @@ -926,7 +930,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> oparms.fid = &fid;
> oparms.reconnect = false;
>
> - rc = open_shroot(xid, tcon, cifs_sb, &cfid);
> + rc = open_shroot(xid, tcon, "", cifs_sb, &cfid);
> if (rc == 0)
> memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
> else
> diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
> index 9565e27681a5..7e4fc69c8b01 100644
> --- a/fs/cifs/smb2proto.h
> +++ b/fs/cifs/smb2proto.h
> @@ -70,6 +70,7 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server,
> struct mid_q_entry *mid);
>
> extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
> + const char *path,
> struct cifs_sb_info *cifs_sb,
> struct cached_fid **cfid);
> extern void close_shroot(struct cached_fid *cfid);
> --
> 2.13.6
>
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/9] cifs: rename the *_shroot* functions to *_cached_dir*
2021-03-08 23:07 ` [PATCH 3/9] cifs: rename the *_shroot* functions to *_cached_dir* Ronnie Sahlberg
@ 2021-04-10 0:10 ` Steve French
0 siblings, 0 replies; 14+ messages in thread
From: Steve French @ 2021-04-10 0:10 UTC (permalink / raw)
To: Ronnie Sahlberg; +Cc: linux-cifs
these renames look fine.
On Mon, Mar 8, 2021 at 5:07 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> These functions will eventually be used to cache any directory, not just the root
> so change the names.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
> fs/cifs/cifssmb.c | 2 +-
> fs/cifs/smb2inode.c | 4 ++--
> fs/cifs/smb2ops.c | 19 ++++++++++---------
> fs/cifs/smb2pdu.c | 2 +-
> fs/cifs/smb2proto.h | 14 +++++++-------
> 5 files changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> index 0496934feecb..3419289b7663 100644
> --- a/fs/cifs/cifssmb.c
> +++ b/fs/cifs/cifssmb.c
> @@ -114,7 +114,7 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
> mutex_lock(&tcon->crfid.fid_mutex);
> tcon->crfid.is_valid = false;
> /* cached handle is not valid, so SMB2_CLOSE won't be sent below */
> - close_shroot_lease_locked(&tcon->crfid);
> + close_cached_dir_lease_locked(&tcon->crfid);
> memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid));
> mutex_unlock(&tcon->crfid.fid_mutex);
>
> diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
> index 67f80c9561fc..0d0bc0b878be 100644
> --- a/fs/cifs/smb2inode.c
> +++ b/fs/cifs/smb2inode.c
> @@ -523,7 +523,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> return -ENOMEM;
>
> /* If it is a root and its handle is cached then use it */
> - rc = open_shroot(xid, tcon, full_path, cifs_sb, &cfid);
> + rc = open_cached_dir(xid, tcon, full_path, cifs_sb, &cfid);
> if (!rc) {
> if (tcon->crfid.file_all_info_is_valid) {
> move_smb2_info_to_cifs(data,
> @@ -535,7 +535,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
> if (!rc)
> move_smb2_info_to_cifs(data, smb2_data);
> }
> - close_shroot(cfid);
> + close_cached_dir(cfid);
> goto out;
> }
>
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index 96ff946674e6..d2858c25ff17 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -693,14 +693,14 @@ smb2_close_cached_fid(struct kref *ref)
> }
> }
>
> -void close_shroot(struct cached_fid *cfid)
> +void close_cached_dir(struct cached_fid *cfid)
> {
> mutex_lock(&cfid->fid_mutex);
> kref_put(&cfid->refcount, smb2_close_cached_fid);
> mutex_unlock(&cfid->fid_mutex);
> }
>
> -void close_shroot_lease_locked(struct cached_fid *cfid)
> +void close_cached_dir_lease_locked(struct cached_fid *cfid)
> {
> if (cfid->has_lease) {
> cfid->has_lease = false;
> @@ -708,10 +708,10 @@ void close_shroot_lease_locked(struct cached_fid *cfid)
> }
> }
>
> -void close_shroot_lease(struct cached_fid *cfid)
> +void close_cached_dir_lease(struct cached_fid *cfid)
> {
> mutex_lock(&cfid->fid_mutex);
> - close_shroot_lease_locked(cfid);
> + close_cached_dir_lease_locked(cfid);
> mutex_unlock(&cfid->fid_mutex);
> }
>
> @@ -721,13 +721,14 @@ smb2_cached_lease_break(struct work_struct *work)
> struct cached_fid *cfid = container_of(work,
> struct cached_fid, lease_break);
>
> - close_shroot_lease(cfid);
> + close_cached_dir_lease(cfid);
> }
>
> /*
> - * Open the directory at the root of a share
> + * Open the and cache a directory handle.
> + * Only supported for the root handle.
> */
> -int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
> +int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> const char *path,
> struct cifs_sb_info *cifs_sb,
> struct cached_fid **cfid)
> @@ -930,7 +931,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> oparms.fid = &fid;
> oparms.reconnect = false;
>
> - rc = open_shroot(xid, tcon, "", cifs_sb, &cfid);
> + rc = open_cached_dir(xid, tcon, "", cifs_sb, &cfid);
> if (rc == 0)
> memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
> else
> @@ -952,7 +953,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
> if (cfid == NULL)
> SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
> else
> - close_shroot(cfid);
> + close_cached_dir(cfid);
> }
>
> static void
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index 4bbb6126b14d..0a03f8d88173 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -1857,7 +1857,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
> if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
> return 0;
>
> - close_shroot_lease(&tcon->crfid);
> + close_cached_dir_lease(&tcon->crfid);
>
> rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, ses->server,
> (void **) &req,
> diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
> index 7e4fc69c8b01..ddbdf9923625 100644
> --- a/fs/cifs/smb2proto.h
> +++ b/fs/cifs/smb2proto.h
> @@ -69,13 +69,13 @@ extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server,
> extern int smb3_handle_read_data(struct TCP_Server_Info *server,
> struct mid_q_entry *mid);
>
> -extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
> - const char *path,
> - struct cifs_sb_info *cifs_sb,
> - struct cached_fid **cfid);
> -extern void close_shroot(struct cached_fid *cfid);
> -extern void close_shroot_lease(struct cached_fid *cfid);
> -extern void close_shroot_lease_locked(struct cached_fid *cfid);
> +extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> + const char *path,
> + struct cifs_sb_info *cifs_sb,
> + struct cached_fid **cfid);
> +extern void close_cached_dir(struct cached_fid *cfid);
> +extern void close_cached_dir_lease(struct cached_fid *cfid);
> +extern void close_cached_dir_lease_locked(struct cached_fid *cfid);
> extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst,
> struct smb2_file_all_info *src);
> extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
> --
> 2.13.6
>
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/9] cifs: store a pointer to the root dentry in cifs_sb_info once we have completed mounting the share
2021-03-08 23:07 ` [PATCH 4/9] cifs: store a pointer to the root dentry in cifs_sb_info once we have completed mounting the share Ronnie Sahlberg
@ 2021-04-10 0:57 ` Steve French
0 siblings, 0 replies; 14+ messages in thread
From: Steve French @ 2021-04-10 0:57 UTC (permalink / raw)
To: Ronnie Sahlberg; +Cc: linux-cifs
looks reasonable
On Mon, Mar 8, 2021 at 5:08 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> And use this to only allow to take out a shared handle once the mount has completed and the
> sb becomes available.
> This will become important in follow up patches where we will start holding a reference to the
> directory dentry for the shared handle during the lifetime of the handle.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
> fs/cifs/cifs_fs_sb.h | 4 ++++
> fs/cifs/cifsfs.c | 9 +++++++++
> fs/cifs/smb2ops.c | 5 ++++-
> 3 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index aa77edc12212..2a5325a7ae49 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -81,5 +81,9 @@ struct cifs_sb_info {
> * (cifs_autodisable_serverino) in order to match new mounts.
> */
> bool mnt_cifs_serverino_autodisabled;
> + /*
> + * Available once the mount has completed.
> + */
> + struct dentry *root;
> };
> #endif /* _CIFS_FS_SB_H */
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 3b61f09f3e1b..c075ef1dd755 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -257,6 +257,12 @@ cifs_read_super(struct super_block *sb)
> static void cifs_kill_sb(struct super_block *sb)
> {
> struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
> +
> + if (cifs_sb->root) {
> + dput(cifs_sb->root);
> + cifs_sb->root = NULL;
> + }
> +
> kill_anon_super(sb);
> cifs_umount(cifs_sb);
> }
> @@ -886,6 +892,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
> if (IS_ERR(root))
> goto out_super;
>
> + if (cifs_sb)
> + cifs_sb->root = dget(root);
> +
> cifs_dbg(FYI, "dentry root is: %p\n", root);
> return root;
>
> diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> index d2858c25ff17..7f4da573b9e8 100644
> --- a/fs/cifs/smb2ops.c
> +++ b/fs/cifs/smb2ops.c
> @@ -751,8 +751,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> if (tcon->nohandlecache)
> return -ENOTSUPP;
>
> + if (cifs_sb->root == NULL)
> + return -ENOENT;
> +
> if (strlen(path))
> - return -ENOTSUPP;
> + return -ENOENT;
>
> mutex_lock(&tcon->crfid.fid_mutex);
> if (tcon->crfid.is_valid) {
> --
> 2.13.6
>
--
Thanks,
Steve
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2021-04-10 0:57 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <20210308230735.337-1-lsahlber@redhat.com>
2021-03-08 23:07 ` [PATCH 1/9] cifs: move the check for nohandlecache into open_shroot Ronnie Sahlberg
2021-04-09 4:42 ` Steve French
2021-04-10 0:05 ` Steve French
2021-03-08 23:07 ` [PATCH 2/9] cifs: pass a path to open_shroot and check if it is the root or not Ronnie Sahlberg
2021-04-10 0:08 ` Steve French
2021-03-08 23:07 ` [PATCH 3/9] cifs: rename the *_shroot* functions to *_cached_dir* Ronnie Sahlberg
2021-04-10 0:10 ` Steve French
2021-03-08 23:07 ` [PATCH 4/9] cifs: store a pointer to the root dentry in cifs_sb_info once we have completed mounting the share Ronnie Sahlberg
2021-04-10 0:57 ` Steve French
2021-03-08 23:07 ` [PATCH 5/9] cifs: Grab a reference for the dentry of the cached directory during the lifetime of the cache Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 6/9] cifs: add a function to get a cached dir based on its dentry Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 7/9] cifs: add a timestamp to track when the lease of the cached dir was taken Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 8/9] cifs: pass the dentry instead of the inode down to the revalidation check functions Ronnie Sahlberg
2021-03-08 23:07 ` [PATCH 9/9] cifs: check the timestamp for the cached dirent when deciding on revalidate Ronnie Sahlberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).