All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.