All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@zeniv.linux.org.uk>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-fsdevel@vger.kernel.org, Jeff Layton <jlayton@kernel.org>,
	David Howells <dhowells@redhat.com>,
	Hans de Goede <hdegoede@redhat.com>,
	Mike Marshall <hubcap@omnibond.com>,
	Joseph Qi <joseph.qi@linux.alibaba.com>,
	Bob Peterson <rpeterso@redhat.com>,
	Steve French <sfrench@samba.org>,
	Richard Weinberger <richard@nod.at>,
	Dominique Martinet <asmadeus@codewreck.org>,
	Arnd Bergmann <arnd@arndb.de>
Subject: [PATCH v2 11/15] cifs: have cifs_fattr_to_inode() refuse to change type on live inode
Date: Sat, 13 Mar 2021 04:38:20 +0000	[thread overview]
Message-ID: <20210313043824.1283821-11-viro@zeniv.linux.org.uk> (raw)
In-Reply-To: <20210313043824.1283821-1-viro@zeniv.linux.org.uk>

... instead of trying to do that in the callers (and missing some,
at that)

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 fs/cifs/cifsproto.h |  2 +-
 fs/cifs/file.c      |  2 +-
 fs/cifs/inode.c     | 42 +++++++++++++++---------------------------
 fs/cifs/readdir.c   |  4 +---
 4 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 75ce6f742b8d..2a72dc24b00a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -194,7 +194,7 @@ extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
 				     struct cifs_sb_info *cifs_sb);
 extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
 					struct cifs_sb_info *);
-extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
+extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
 extern struct inode *cifs_iget(struct super_block *sb,
 			       struct cifs_fattr *fattr);
 
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 26de4329d161..78266f0e0595 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -165,7 +165,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
 			goto posix_open_ret;
 		}
 	} else {
-		cifs_fattr_to_inode(*pinode, &fattr);
+		rc = cifs_fattr_to_inode(*pinode, &fattr);
 	}
 
 posix_open_ret:
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 80c487fcf10e..51cb1ca829ec 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -157,12 +157,18 @@ cifs_nlink_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
 }
 
 /* populate an inode with info from a cifs_fattr struct */
-void
+int
 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
 {
 	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 
+	if (!(inode->i_state & I_NEW) &&
+	    unlikely(inode_wrong_type(inode, fattr->cf_mode))) {
+		CIFS_I(inode)->time = 0; /* force reval */
+		return -ESTALE;
+	}
+
 	cifs_revalidate_cache(inode, fattr);
 
 	spin_lock(&inode->i_lock);
@@ -219,6 +225,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
 		inode->i_flags |= S_AUTOMOUNT;
 	if (inode->i_state & I_NEW)
 		cifs_set_ops(inode);
+	return 0;
 }
 
 void
@@ -363,7 +370,7 @@ cifs_get_file_info_unix(struct file *filp)
 		rc = 0;
 	}
 
-	cifs_fattr_to_inode(inode, &fattr);
+	rc = cifs_fattr_to_inode(inode, &fattr);
 	free_xid(xid);
 	return rc;
 }
@@ -426,13 +433,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 		}
 
 		/* if filetype is different, return error */
-		if (unlikely(inode_wrong_type(*pinode, fattr.cf_mode))) {
-			CIFS_I(*pinode)->time = 0; /* force reval */
-			rc = -ESTALE;
-			goto cgiiu_exit;
-		}
-
-		cifs_fattr_to_inode(*pinode, &fattr);
+		rc = cifs_fattr_to_inode(*pinode, &fattr);
 	}
 
 cgiiu_exit:
@@ -782,7 +783,8 @@ cifs_get_file_info(struct file *filp)
 	 */
 	fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
 	fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
-	cifs_fattr_to_inode(inode, &fattr);
+	/* if filetype is different, return error */
+	rc = cifs_fattr_to_inode(inode, &fattr);
 cgfi_exit:
 	free_xid(xid);
 	return rc;
@@ -1099,16 +1101,8 @@ cifs_get_inode_info(struct inode **inode,
 			rc = -ESTALE;
 			goto out;
 		}
-
 		/* if filetype is different, return error */
-		if (unlikely(((*inode)->i_mode & S_IFMT) !=
-		    (fattr.cf_mode & S_IFMT))) {
-			CIFS_I(*inode)->time = 0; /* force reval */
-			rc = -ESTALE;
-			goto out;
-		}
-
-		cifs_fattr_to_inode(*inode, &fattr);
+		rc = cifs_fattr_to_inode(*inode, &fattr);
 	}
 out:
 	cifs_buf_release(smb1_backup_rsp_buf);
@@ -1214,14 +1208,7 @@ smb311_posix_get_inode_info(struct inode **inode,
 		}
 
 		/* if filetype is different, return error */
-		if (unlikely(((*inode)->i_mode & S_IFMT) !=
-		    (fattr.cf_mode & S_IFMT))) {
-			CIFS_I(*inode)->time = 0; /* force reval */
-			rc = -ESTALE;
-			goto out;
-		}
-
-		cifs_fattr_to_inode(*inode, &fattr);
+		rc = cifs_fattr_to_inode(*inode, &fattr);
 	}
 out:
 	cifs_put_tlink(tlink);
@@ -1316,6 +1303,7 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
 			}
 		}
 
+		/* can't fail - see cifs_find_inode() */
 		cifs_fattr_to_inode(inode, fattr);
 		if (sb->s_flags & SB_NOATIME)
 			inode->i_flags |= S_NOATIME | S_NOCMTIME;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 80bf4c6f4c7b..e563c0fb47cb 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -119,9 +119,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
 			/* update inode in place
 			 * if both i_ino and i_mode didn't change */
 			if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid &&
-			    (inode->i_mode & S_IFMT) ==
-			    (fattr->cf_mode & S_IFMT)) {
-				cifs_fattr_to_inode(inode, fattr);
+			    cifs_fattr_to_inode(inode, fattr) == 0) {
 				dput(dentry);
 				return;
 			}
-- 
2.11.0


  parent reply	other threads:[~2021-03-13  4:41 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <YDqRThxQOVQO9uOx@zeniv-ca.linux.org.uk>
2021-03-13  4:35 ` [RFC][PATCHSET v2] inode type bits fixes Al Viro
2021-03-13  4:38   ` [PATCH v2 01/15] new helper: inode_wrong_type() Al Viro
2021-03-13  4:38     ` [PATCH v2 02/15] ceph: fix up error handling with snapdirs Al Viro
2021-03-13  4:38     ` [PATCH v2 03/15] ceph: don't allow type or device number to change on non-I_NEW inodes Al Viro
2021-03-13  4:38     ` [PATCH v2 04/15] afs: Fix updating of i_mode due to 3rd party change Al Viro
2021-03-13  4:38     ` [PATCH v2 05/15] vboxsf: don't allow to change the inode type Al Viro
2021-03-13  4:38     ` [PATCH v2 06/15] orangefs_inode_is_stale(): i_mode type bits do *not* form a bitmap Al Viro
2021-03-13  4:38     ` [PATCH v2 07/15] ocfs2_inode_lock_update(): make sure we don't change the type bits of i_mode Al Viro
2021-03-13  4:38     ` [PATCH v2 08/15] gfs2: be careful with inode refresh Al Viro
2021-03-13  4:38     ` [PATCH v2 09/15] do_cifs_create(): don't set ->i_mode of something we had not created Al Viro
2021-03-15 17:12       ` Jeff Layton
2021-03-13  4:38     ` [PATCH v2 10/15] cifs: have ->mkdir() handle race with another client sanely Al Viro
2021-03-15 17:08       ` Jeff Layton
2021-03-13  4:38     ` Al Viro [this message]
2021-03-15 17:13       ` [PATCH v2 11/15] cifs: have cifs_fattr_to_inode() refuse to change type on live inode Jeff Layton
2021-03-13  4:38     ` [PATCH v2 12/15] hostfs_mknod(): don't bother with init_special_inode() Al Viro
2021-03-13  4:38     ` [PATCH v2 13/15] openpromfs: don't do unlock_new_inode() until the new inode is set up Al Viro
2021-03-13  4:38     ` [PATCH v2 14/15] 9p: missing chunk of "fs/9p: Don't update file type when updating file attributes" Al Viro
2021-03-15 17:14       ` Jeff Layton
2021-03-13  4:38     ` [PATCH v2 15/15] spufs: fix bogosity in S_ISGID handling Al Viro
2021-03-15 17:19     ` [PATCH v2 01/15] new helper: inode_wrong_type() Jeff Layton

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=20210313043824.1283821-11-viro@zeniv.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=arnd@arndb.de \
    --cc=asmadeus@codewreck.org \
    --cc=dhowells@redhat.com \
    --cc=hdegoede@redhat.com \
    --cc=hubcap@omnibond.com \
    --cc=jlayton@kernel.org \
    --cc=joseph.qi@linux.alibaba.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=richard@nod.at \
    --cc=rpeterso@redhat.com \
    --cc=sfrench@samba.org \
    --cc=torvalds@linux-foundation.org \
    /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.