All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ronnie Sahlberg <lsahlber@redhat.com>
To: linux-cifs <linux-cifs@vger.kernel.org>
Cc: Steve French <smfrench@gmail.com>, Ronnie Sahlberg <lsahlber@redhat.com>
Subject: [PATCH 3/9] cifs: Add constructor/destructors for tcon->cfid
Date: Tue,  9 Aug 2022 12:11:50 +1000	[thread overview]
Message-ID: <20220809021156.3086869-4-lsahlber@redhat.com> (raw)
In-Reply-To: <20220809021156.3086869-1-lsahlber@redhat.com>

and move the structure definitions into cached_dir.h

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cached_dir.c | 114 ++++++++++++++++++++++++++-----------------
 fs/cifs/cached_dir.h |  38 +++++++++++++++
 fs/cifs/cifsglob.h   |  38 +--------------
 fs/cifs/misc.c       |  20 ++++----
 fs/cifs/smb2inode.c  |   4 +-
 fs/cifs/smb2ops.c    |   8 +--
 6 files changed, 123 insertions(+), 99 deletions(-)

diff --git a/fs/cifs/cached_dir.c b/fs/cifs/cached_dir.c
index f2e17c1d5196..7ca085299890 100644
--- a/fs/cifs/cached_dir.c
+++ b/fs/cifs/cached_dir.c
@@ -18,7 +18,7 @@
 int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 		const char *path,
 		struct cifs_sb_info *cifs_sb,
-		struct cached_fid **cfid)
+		struct cached_fid **ret_cfid)
 {
 	struct cifs_ses *ses;
 	struct TCP_Server_Info *server;
@@ -35,7 +35,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	u8 oplock = SMB2_OPLOCK_LEVEL_II;
 	struct cifs_fid *pfid;
 	struct dentry *dentry;
-
+	struct cached_fid *cfid;
+	  
 	if (tcon == NULL || tcon->nohandlecache ||
 	    is_smb1_server(tcon->ses->server))
 		return -ENOTSUPP;
@@ -51,12 +52,13 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 
 	dentry = cifs_sb->root;
 
-	mutex_lock(&tcon->cfid.fid_mutex);
-	if (tcon->cfid.is_valid) {
+	cfid = tcon->cfid;
+	mutex_lock(&cfid->fid_mutex);
+	if (cfid->is_valid) {
 		cifs_dbg(FYI, "found a cached root file handle\n");
-		*cfid = &tcon->cfid;
-		kref_get(&tcon->cfid.refcount);
-		mutex_unlock(&tcon->cfid.fid_mutex);
+		*ret_cfid = cfid;
+		kref_get(&cfid->refcount);
+		mutex_unlock(&cfid->fid_mutex);
 		return 0;
 	}
 
@@ -67,7 +69,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	 * thus causing a deadlock
 	 */
 
-	mutex_unlock(&tcon->cfid.fid_mutex);
+	mutex_unlock(&cfid->fid_mutex);
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -75,7 +77,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	if (!server->ops->new_lease_key)
 		return -EIO;
 
-	pfid = tcon->cfid.fid;
+	pfid = &cfid->fid;
 	server->ops->new_lease_key(pfid);
 
 	memset(rqst, 0, sizeof(rqst));
@@ -118,14 +120,14 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	rc = compound_send_recv(xid, ses, server,
 				flags, 2, rqst,
 				resp_buftype, rsp_iov);
-	mutex_lock(&tcon->cfid.fid_mutex);
+	mutex_lock(&cfid->fid_mutex);
 
 	/*
 	 * Now we need to check again as the cached root might have
 	 * been successfully re-opened from a concurrent process
 	 */
 
-	if (tcon->cfid.is_valid) {
+	if (cfid->is_valid) {
 		/* work was already done */
 
 		/* stash fids for close() later */
@@ -138,9 +140,9 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 		 * caller expects this func to set the fid in cfid to valid
 		 * cached root, so increment the refcount.
 		 */
-		kref_get(&tcon->cfid.refcount);
+		kref_get(&cfid->refcount);
 
-		mutex_unlock(&tcon->cfid.fid_mutex);
+		mutex_unlock(&cfid->fid_mutex);
 
 		if (rc == 0) {
 			/* close extra handle outside of crit sec */
@@ -170,11 +172,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
 #endif /* CIFS_DEBUG2 */
 
-	tcon->cfid.tcon = tcon;
-	tcon->cfid.is_valid = true;
-	tcon->cfid.dentry = dentry;
+	cfid->tcon = tcon;
+	cfid->is_valid = true;
+	cfid->dentry = dentry;
 	dget(dentry);
-	kref_init(&tcon->cfid.refcount);
+	kref_init(&cfid->refcount);
 
 	/* BB TBD check to see if oplock level check can be removed below */
 	if (o_rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE) {
@@ -182,8 +184,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 		 * See commit 2f94a3125b87. Increment the refcount when we
 		 * get a lease for root, release it if lease break occurs
 		 */
-		kref_get(&tcon->cfid.refcount);
-		tcon->cfid.has_lease = true;
+		kref_get(&cfid->refcount);
+		cfid->has_lease = true;
 		smb2_parse_contexts(server, o_rsp,
 				&oparms.fid->epoch,
 				    oparms.fid->lease_key, &oplock,
@@ -198,37 +200,41 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 				le16_to_cpu(qi_rsp->OutputBufferOffset),
 				sizeof(struct smb2_file_all_info),
 				&rsp_iov[1], sizeof(struct smb2_file_all_info),
-				(char *)&tcon->cfid.file_all_info))
-		tcon->cfid.file_all_info_is_valid = true;
-	tcon->cfid.time = jiffies;
+				(char *)&cfid->file_all_info))
+		cfid->file_all_info_is_valid = true;
+	cfid->time = jiffies;
 
 
 oshr_exit:
-	mutex_unlock(&tcon->cfid.fid_mutex);
+	mutex_unlock(&cfid->fid_mutex);
 oshr_free:
 	SMB2_open_free(&rqst[0]);
 	SMB2_query_info_free(&rqst[1]);
 	free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
 	free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
 	if (rc == 0) {
-		*cfid = &tcon->cfid;	
-}
+		*ret_cfid = cfid;	
+	}
 	return rc;
 }
 
 int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
 			      struct dentry *dentry,
-			      struct cached_fid **cfid)
+			      struct cached_fid **ret_cfid)
 {
-	mutex_lock(&tcon->cfid.fid_mutex);
-	if (tcon->cfid.dentry == dentry) {
+	struct cached_fid *cfid;
+
+	cfid = tcon->cfid;
+
+	mutex_lock(&cfid->fid_mutex);
+	if (cfid->dentry == dentry) {
 		cifs_dbg(FYI, "found a cached root file handle by dentry\n");
-		*cfid = &tcon->cfid;
-		kref_get(&tcon->cfid.refcount);
-		mutex_unlock(&tcon->cfid.fid_mutex);
+		*ret_cfid = cfid;
+		kref_get(&cfid->refcount);
+		mutex_unlock(&cfid->fid_mutex);
 		return 0;
 	}
-	mutex_unlock(&tcon->cfid.fid_mutex);
+	mutex_unlock(&cfid->fid_mutex);
 	return -ENOENT;
 }
 
@@ -241,8 +247,8 @@ smb2_close_cached_fid(struct kref *ref)
 
 	if (cfid->is_valid) {
 		cifs_dbg(FYI, "clear cached root file handle\n");
-		SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid,
-			   cfid->fid->volatile_fid);
+		SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
+			   cfid->fid.volatile_fid);
 	}
 
 	/*
@@ -312,7 +318,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
 		tcon = tlink_tcon(tlink);
 		if (IS_ERR(tcon))
 			continue;
-		cfid = &tcon->cfid;
+		cfid = tcon->cfid;
 		mutex_lock(&cfid->fid_mutex);
 		if (cfid->dentry) {
 			dput(cfid->dentry);
@@ -328,12 +334,12 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
  */
 void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
 {
-	mutex_lock(&tcon->cfid.fid_mutex);
-	tcon->cfid.is_valid = false;
+	mutex_lock(&tcon->cfid->fid_mutex);
+	tcon->cfid->is_valid = false;
 	/* cached handle is not valid, so SMB2_CLOSE won't be sent below */
-	close_cached_dir_lease_locked(&tcon->cfid);
-	memset(tcon->cfid.fid, 0, sizeof(struct cifs_fid));
-	mutex_unlock(&tcon->cfid.fid_mutex);
+	close_cached_dir_lease_locked(tcon->cfid);
+	memset(&tcon->cfid->fid, 0, sizeof(struct cifs_fid));
+	mutex_unlock(&tcon->cfid->fid_mutex);
 }
 
 static void
@@ -347,17 +353,35 @@ smb2_cached_lease_break(struct work_struct *work)
 
 int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
 {
-	if (tcon->cfid.is_valid &&
+	if (tcon->cfid->is_valid &&
 	    !memcmp(lease_key,
-		    tcon->cfid.fid->lease_key,
+		    tcon->cfid->fid.lease_key,
 		    SMB2_LEASE_KEY_SIZE)) {
-		tcon->cfid.time = 0;
-		INIT_WORK(&tcon->cfid.lease_break,
+		tcon->cfid->time = 0;
+		INIT_WORK(&tcon->cfid->lease_break,
 			  smb2_cached_lease_break);
 		queue_work(cifsiod_wq,
-			   &tcon->cfid.lease_break);
+			   &tcon->cfid->lease_break);
 		spin_unlock(&cifs_tcp_ses_lock);
 		return true;
 	}
 	return false;
 }
+
+struct cached_fid *init_cached_dir(void)
+{
+	struct cached_fid *cfid;
+
+	cfid = kzalloc(sizeof(*cfid), GFP_KERNEL);
+	if (!cfid)
+		return NULL;
+	INIT_LIST_HEAD(&cfid->dirents.entries);
+	mutex_init(&cfid->dirents.de_mutex);
+	mutex_init(&cfid->fid_mutex);
+	return cfid;
+}
+
+void free_cached_dir(struct cifs_tcon *tcon)
+{
+	kfree(tcon->cfid);
+}
diff --git a/fs/cifs/cached_dir.h b/fs/cifs/cached_dir.h
index 3731c755eea5..b44edfbd8e1a 100644
--- a/fs/cifs/cached_dir.h
+++ b/fs/cifs/cached_dir.h
@@ -9,6 +9,44 @@
 #define _CACHED_DIR_H
 
 
+struct cached_dirent {
+	struct list_head entry;
+	char *name;
+	int namelen;
+	loff_t pos;
+
+	struct cifs_fattr fattr;
+};
+
+struct cached_dirents {
+	bool is_valid:1;
+	bool is_failed:1;
+	struct dir_context *ctx; /*
+				  * Only used to make sure we only take entries
+				  * from a single context. Never dereferenced.
+				  */
+	struct mutex de_mutex;
+	int pos;		 /* Expected ctx->pos */
+	struct list_head entries;
+};
+
+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;
+	struct cifs_tcon *tcon;
+	struct dentry *dentry;
+	struct work_struct lease_break;
+	struct smb2_file_all_info file_all_info;
+	struct cached_dirents dirents;
+};
+
+extern struct cached_fid *init_cached_dir(void);
+extern void free_cached_dir(struct cifs_tcon *tcon);
 extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 			   const char *path,
 			   struct cifs_sb_info *cifs_sb,
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 657fabb9067b..d3b233a2737d 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1125,42 +1125,6 @@ struct cifs_fattr {
 	u32             cf_cifstag;
 };
 
-struct cached_dirent {
-	struct list_head entry;
-	char *name;
-	int namelen;
-	loff_t pos;
-
-	struct cifs_fattr fattr;
-};
-
-struct cached_dirents {
-	bool is_valid:1;
-	bool is_failed:1;
-	struct dir_context *ctx; /*
-				  * Only used to make sure we only take entries
-				  * from a single context. Never dereferenced.
-				  */
-	struct mutex de_mutex;
-	int pos;		 /* Expected ctx->pos */
-	struct list_head entries;
-};
-
-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;
-	struct cifs_tcon *tcon;
-	struct dentry *dentry;
-	struct work_struct lease_break;
-	struct smb2_file_all_info file_all_info;
-	struct cached_dirents dirents;
-};
-
 /*
  * there is one of these for each connection to a resource on a particular
  * session
@@ -1253,7 +1217,7 @@ struct cifs_tcon {
 	struct fscache_volume *fscache;	/* cookie for share */
 #endif
 	struct list_head pending_opens;	/* list of incomplete opens */
-	struct cached_fid cfid; /* Cached root fid */
+	struct cached_fid *cfid; /* Cached root fid */
 	/* BB add field for back pointer to sb struct(s)? */
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	struct list_head ulist; /* cache update list */
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index fa1a03ddbbe2..4e2e3b557591 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -23,6 +23,7 @@
 #include "dns_resolve.h"
 #endif
 #include "fs_context.h"
+#include "cached_dir.h"
 
 extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
@@ -115,13 +116,11 @@ tconInfoAlloc(void)
 	ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL);
 	if (!ret_buf)
 		return NULL;
-	ret_buf->cfid.fid = kzalloc(sizeof(*ret_buf->cfid.fid), GFP_KERNEL);
-	if (!ret_buf->cfid.fid) {
+	ret_buf->cfid = init_cached_dir();
+	if (!ret_buf->cfid) {
 		kfree(ret_buf);
 		return NULL;
 	}
-	INIT_LIST_HEAD(&ret_buf->cfid.dirents.entries);
-	mutex_init(&ret_buf->cfid.dirents.de_mutex);
 
 	atomic_inc(&tconInfoAllocCount);
 	ret_buf->status = TID_NEW;
@@ -129,7 +128,6 @@ tconInfoAlloc(void)
 	INIT_LIST_HEAD(&ret_buf->openFileList);
 	INIT_LIST_HEAD(&ret_buf->tcon_list);
 	spin_lock_init(&ret_buf->open_file_lock);
-	mutex_init(&ret_buf->cfid.fid_mutex);
 	spin_lock_init(&ret_buf->stat_lock);
 	atomic_set(&ret_buf->num_local_opens, 0);
 	atomic_set(&ret_buf->num_remote_opens, 0);
@@ -138,17 +136,17 @@ tconInfoAlloc(void)
 }
 
 void
-tconInfoFree(struct cifs_tcon *buf_to_free)
+tconInfoFree(struct cifs_tcon *tcon)
 {
-	if (buf_to_free == NULL) {
+	if (tcon == NULL) {
 		cifs_dbg(FYI, "Null buffer passed to tconInfoFree\n");
 		return;
 	}
+	free_cached_dir(tcon);
 	atomic_dec(&tconInfoAllocCount);
-	kfree(buf_to_free->nativeFileSystem);
-	kfree_sensitive(buf_to_free->password);
-	kfree(buf_to_free->cfid.fid);
-	kfree(buf_to_free);
+	kfree(tcon->nativeFileSystem);
+	kfree_sensitive(tcon->password);
+	kfree(tcon);
 }
 
 struct smb_hdr *
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 09f01f70e020..9696184a09e3 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -524,8 +524,8 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
 					       &cfid->file_all_info);
 		} else {
 			rc = SMB2_query_info(xid, tcon,
-					     cfid->fid->persistent_fid,
-					     cfid->fid->volatile_fid, smb2_data);
+					     cfid->fid.persistent_fid,
+					     cfid->fid.volatile_fid, smb2_data);
 			if (!rc)
 				move_smb2_info_to_cifs(data, smb2_data);
 		}
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 01aafedc477e..e50b6ef309e1 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -722,7 +722,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
 
 	rc = open_cached_dir(xid, tcon, "", cifs_sb, &cfid);
 	if (rc == 0)
-		memcpy(&fid, cfid->fid, sizeof(struct cifs_fid));
+		memcpy(&fid, &cfid->fid, sizeof(struct cifs_fid));
 	else
 		rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
 			       NULL, NULL);
@@ -784,7 +784,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
 	struct cifs_open_parms oparms;
 	struct cifs_fid fid;
 
-	if ((*full_path == 0) && tcon->cfid.is_valid)
+	if ((*full_path == 0) && tcon->cfid->is_valid)
 		return 0;
 
 	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
@@ -2458,8 +2458,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
 	if (cfid) {
 		rc = SMB2_query_info_init(tcon, server,
 					  &rqst[1],
-					  cfid->fid->persistent_fid,
-					  cfid->fid->volatile_fid,
+					  cfid->fid.persistent_fid,
+					  cfid->fid.volatile_fid,
 					  class, type, 0,
 					  output_len, 0,
 					  NULL);
-- 
2.35.3


  parent reply	other threads:[~2022-08-09  2:12 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-09  2:11 WIP: Expand directory handle cache to also cache non-root directories Ronnie Sahlberg
2022-08-09  2:11 ` [PATCH 1/9] cifs: Move cached-dir functions into a separate file Ronnie Sahlberg
2022-08-11  2:53   ` Steve French
2022-08-11  3:08     ` Steve French
2022-08-11 13:03   ` Paulo Alcantara
2022-08-09  2:11 ` [PATCH 2/9] cifs: Do not use tcon->cfid directly, use the cfid we get from open_cached_dir Ronnie Sahlberg
2022-08-09  4:22   ` Steve French
2022-08-11 13:03   ` Paulo Alcantara
2022-08-09  2:11 ` Ronnie Sahlberg [this message]
2022-08-11 13:15   ` [PATCH 3/9] cifs: Add constructor/destructors for tcon->cfid Paulo Alcantara
2022-08-12  0:14     ` Steve French
2022-08-09  2:11 ` [PATCH 4/9] cifs: Make tcon contain a wrapper structure cached_fids instead of cached_fid Ronnie Sahlberg
2022-08-11 13:16   ` Paulo Alcantara
2022-08-09  2:11 ` [PATCH 5/9] cifs: Do not access tcon->cfids->cfid directly from is_path_accessible Ronnie Sahlberg
2022-08-11 13:20   ` Paulo Alcantara
2022-08-12  0:56     ` Steve French
2022-08-12  0:57       ` Steve French
2022-08-12  1:26         ` Steve French
2022-08-12  1:34           ` Steve French
2022-08-09  2:11 ` [PATCH 6/9] cifs: cifs: handlecache, only track the dentry for the root handle Ronnie Sahlberg
2022-08-11 13:34   ` Paulo Alcantara
2022-08-09  2:11 ` [PATCH 7/9] cifs: store a pointer to a fid in the cfid structure instead of the struct Ronnie Sahlberg
2022-08-11 13:37   ` Paulo Alcantara
2022-08-09  2:11 ` [PATCH 8/9] cifs: don't unlock cifs_tcp_ses_lock in cached_dir_lease_break() Ronnie Sahlberg
2022-08-11 13:38   ` Paulo Alcantara
2022-08-11 15:27     ` Steve French
2022-08-09  2:11 ` [PATCH 9/9] cifs: start caching all directories we open and get a lease for Ronnie Sahlberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220809021156.3086869-4-lsahlber@redhat.com \
    --to=lsahlber@redhat.com \
    --cc=linux-cifs@vger.kernel.org \
    --cc=smfrench@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.