new helper: inode_wrong_type()
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 2 Mar 2021 01:37:10 +0000 (20:37 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 8 Mar 2021 15:19:35 +0000 (10:19 -0500)
inode_wrong_type(inode, mode) returns true if setting inode->i_mode
to given value would've changed the inode type.  We have enough of
those checks open-coded to make a helper worthwhile.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c
fs/cifs/inode.c
fs/fuse/dir.c
fs/fuse/inode.c
fs/fuse/readdir.c
fs/nfs/inode.c
fs/nfsd/nfsproc.c
fs/overlayfs/namei.c
include/linux/fs.h

index 8d97f0b..7957065 100644 (file)
@@ -399,7 +399,7 @@ static int v9fs_test_inode(struct inode *inode, void *data)
 
        umode = p9mode2unixmode(v9ses, st, &rdev);
        /* don't match inode of different type */
-       if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
+       if (inode_wrong_type(inode, umode))
                return 0;
 
        /* compare qid details */
@@ -1390,7 +1390,7 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
         * Don't update inode if the file type is different
         */
        umode = p9mode2unixmode(v9ses, st, &rdev);
-       if ((inode->i_mode & S_IFMT) != (umode & S_IFMT))
+       if (inode_wrong_type(inode, umode))
                goto out;
 
        /*
index 1dc7af0..df0b87b 100644 (file)
@@ -59,7 +59,7 @@ static int v9fs_test_inode_dotl(struct inode *inode, void *data)
        struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
 
        /* don't match inode of different type */
-       if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
+       if (inode_wrong_type(inode, st->st_mode))
                return 0;
 
        if (inode->i_generation != st->st_gen)
@@ -959,7 +959,7 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
        /*
         * Don't update inode if the file type is different
         */
-       if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
+       if (inode_wrong_type(inode, st->st_mode))
                goto out;
 
        /*
index 7c61bc9..d46b36d 100644 (file)
@@ -426,8 +426,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                }
 
                /* if filetype is different, return error */
-               if (unlikely(((*pinode)->i_mode & S_IFMT) !=
-                   (fattr.cf_mode & S_IFMT))) {
+               if (unlikely(inode_wrong_type(*pinode, fattr.cf_mode))) {
                        CIFS_I(*pinode)->time = 0; /* force reval */
                        rc = -ESTALE;
                        goto cgiiu_exit;
@@ -1249,7 +1248,7 @@ cifs_find_inode(struct inode *inode, void *opaque)
                return 0;
 
        /* don't match inode of different type */
-       if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
+       if (inode_wrong_type(inode, fattr->cf_mode))
                return 0;
 
        /* if it's not a directory or has no dentries, then flag it */
index 06a1870..2400b98 100644 (file)
@@ -252,7 +252,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                if (ret == -ENOMEM)
                        goto out;
                if (ret || fuse_invalid_attr(&outarg.attr) ||
-                   (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
+                   inode_wrong_type(inode, outarg.attr.mode))
                        goto invalid;
 
                forget_all_cached_acls(inode);
@@ -1054,7 +1054,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
        err = fuse_simple_request(fm, &args);
        if (!err) {
                if (fuse_invalid_attr(&outarg.attr) ||
-                   (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+                   inode_wrong_type(inode, outarg.attr.mode)) {
                        fuse_make_bad(inode);
                        err = -EIO;
                } else {
@@ -1703,7 +1703,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
        }
 
        if (fuse_invalid_attr(&outarg.attr) ||
-           (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
+           inode_wrong_type(inode, outarg.attr.mode)) {
                fuse_make_bad(inode);
                err = -EIO;
                goto error;
index b0e18b4..b4b956d 100644 (file)
@@ -350,7 +350,7 @@ retry:
                inode->i_generation = generation;
                fuse_init_inode(inode, attr);
                unlock_new_inode(inode);
-       } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
+       } else if (inode_wrong_type(inode, attr->mode)) {
                /* Inode has changed type, any I/O on the old should fail */
                fuse_make_bad(inode);
                iput(inode);
index 3441ffa..277f704 100644 (file)
@@ -202,7 +202,7 @@ retry:
                inode = d_inode(dentry);
                if (!inode ||
                    get_node_id(inode) != o->nodeid ||
-                   ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
+                   inode_wrong_type(inode, o->attr.mode)) {
                        d_invalidate(dentry);
                        dput(dentry);
                        goto retry;
index 749bbea..b0da240 100644 (file)
@@ -334,7 +334,7 @@ nfs_find_actor(struct inode *inode, void *opaque)
 
        if (NFS_FILEID(inode) != fattr->fileid)
                return 0;
-       if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode))
+       if (inode_wrong_type(inode, fattr->mode))
                return 0;
        if (nfs_compare_fh(NFS_FH(inode), fh))
                return 0;
@@ -1460,7 +1460,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
                        return 0;
                return -ESTALE;
        }
-       if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
+       if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && inode_wrong_type(inode, fattr->mode))
                return -ESTALE;
 
 
@@ -1875,7 +1875,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
        /*
         * Make sure the inode's type hasn't changed.
         */
-       if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
+       if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && inode_wrong_type(inode, fattr->mode)) {
                /*
                * Big trouble! The inode has become a different object.
                */
index a8d5449..6d51687 100644 (file)
@@ -381,7 +381,7 @@ nfsd_proc_create(struct svc_rqst *rqstp)
 
                /* Make sure the type and device matches */
                resp->status = nfserr_exist;
-               if (inode && type != (inode->i_mode & S_IFMT))
+               if (inode && inode_wrong_type(inode, type))
                        goto out_unlock;
        }
 
index 3fe05fb..1d57397 100644 (file)
@@ -371,7 +371,7 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
                return PTR_ERR(origin);
 
        if (upperdentry && !ovl_is_whiteout(upperdentry) &&
-           ((d_inode(origin)->i_mode ^ d_inode(upperdentry)->i_mode) & S_IFMT))
+           inode_wrong_type(d_inode(upperdentry), d_inode(origin)->i_mode))
                goto invalid;
 
        if (!*stackp)
@@ -730,7 +730,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
                index = ERR_PTR(-ESTALE);
                goto out;
        } else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) ||
-                  ((inode->i_mode ^ d_inode(origin)->i_mode) & S_IFMT)) {
+                  inode_wrong_type(inode, d_inode(origin)->i_mode)) {
                /*
                 * Index should always be of the same file type as origin
                 * except for the case of a whiteout index. A whiteout
index ec8f3dd..9e0d76a 100644 (file)
@@ -2884,6 +2884,11 @@ static inline bool execute_ok(struct inode *inode)
        return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode);
 }
 
+static inline bool inode_wrong_type(const struct inode *inode, umode_t mode)
+{
+       return (inode->i_mode ^ mode) & S_IFMT;
+}
+
 static inline void file_start_write(struct file *file)
 {
        if (!S_ISREG(file_inode(file)->i_mode))