linux-cifs.vger.kernel.org archive mirror
 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 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).