Merge tag 'pull-file' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Oct 2022 00:13:18 +0000 (17:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Oct 2022 00:13:18 +0000 (17:13 -0700)
Pull vfs file updates from Al Viro:
 "struct file-related stuff"

* tag 'pull-file' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  dma_buf_getfile(): don't bother with ->f_flags reassignments
  Change calling conventions for filldir_t
  locks: fix TOCTOU race when granting write lease

23 files changed:
Documentation/filesystems/porting.rst
arch/alpha/kernel/osf_sys.c
drivers/dma-buf/dma-buf.c
fs/afs/dir.c
fs/ecryptfs/file.c
fs/exportfs/expfs.c
fs/fat/dir.c
fs/file_table.c
fs/gfs2/export.c
fs/internal.h
fs/ksmbd/smb2pdu.c
fs/ksmbd/vfs.c
fs/nfsd/nfs4recover.c
fs/nfsd/vfs.c
fs/ocfs2/dir.c
fs/ocfs2/journal.c
fs/open.c
fs/overlayfs/readdir.c
fs/readdir.c
fs/reiserfs/xattr.c
fs/xfs/scrub/dir.c
fs/xfs/scrub/parent.c
include/linux/fs.h

index aee9aaf9f3df78bd578e87c8ce845da74abc9a86..e8f370d9ce9c33ef7df635b72d6d6fcbcbbd11d7 100644 (file)
@@ -922,3 +922,14 @@ is provided - file_open_root_mnt().  In-tree users adjusted.
 no_llseek is gone; don't set .llseek to that - just leave it NULL instead.
 Checks for "does that file have llseek(2), or should it fail with ESPIPE"
 should be done by looking at FMODE_LSEEK in file->f_mode.
+
+---
+
+*mandatory*
+
+filldir_t (readdir callbacks) calling conventions have changed.  Instead of
+returning 0 or -E... it returns bool now.  false means "no more" (as -E... used
+to) and true - "keep going" (as 0 in old calling conventions).  Rationale:
+callers never looked at specific -E... values anyway.  ->iterate() and
+->iterate_shared() instance require no changes at all, all filldir_t ones in
+the tree converted.
index b3ad8c44c971de259e2947a0e8b70096b601b9eb..68ec314d3fac3baa77a6f92770964039c6483922 100644 (file)
@@ -108,7 +108,7 @@ struct osf_dirent_callback {
        int error;
 };
 
-static int
+static bool
 osf_filldir(struct dir_context *ctx, const char *name, int namlen,
            loff_t offset, u64 ino, unsigned int d_type)
 {
@@ -120,11 +120,11 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,
 
        buf->error = -EINVAL;   /* only used if we fail */
        if (reclen > buf->count)
-               return -EINVAL;
+               return false;
        d_ino = ino;
        if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
                buf->error = -EOVERFLOW;
-               return -EOVERFLOW;
+               return false;
        }
        if (buf->basep) {
                if (put_user(offset, buf->basep))
@@ -141,10 +141,10 @@ osf_filldir(struct dir_context *ctx, const char *name, int namlen,
        dirent = (void __user *)dirent + reclen;
        buf->dirent = dirent;
        buf->count -= reclen;
-       return 0;
+       return true;
 Efault:
        buf->error = -EFAULT;
-       return -EFAULT;
+       return false;
 }
 
 SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
index 5ec2f314b6e9e4d0c2b184644dcf3c67f13ee65a..dd0f83ee505b7f34efec89fae1f06c176ce85213 100644 (file)
@@ -531,11 +531,11 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
         * value.
         */
        inode->i_ino = atomic64_add_return(1, &dmabuf_inode);
+       flags &= O_ACCMODE | O_NONBLOCK;
        file = alloc_file_pseudo(inode, dma_buf_mnt, "dmabuf",
                                 flags, &dma_buf_fops);
        if (IS_ERR(file))
                goto err_alloc_file;
-       file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
        file->private_data = dmabuf;
        file->f_path.dentry->d_fsdata = dmabuf;
 
index 56ae5cd5184f08c4f5757face83a8cb870d7cd7d..230c2d19116d9daf79840db2e67beaadf127c4d6 100644 (file)
@@ -24,9 +24,9 @@ static int afs_readdir(struct file *file, struct dir_context *ctx);
 static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
 static int afs_d_delete(const struct dentry *dentry);
 static void afs_d_iput(struct dentry *dentry, struct inode *inode);
-static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
+static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
                                  loff_t fpos, u64 ino, unsigned dtype);
-static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
+static bool afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
                              loff_t fpos, u64 ino, unsigned dtype);
 static int afs_create(struct user_namespace *mnt_userns, struct inode *dir,
                      struct dentry *dentry, umode_t mode, bool excl);
@@ -568,7 +568,7 @@ static int afs_readdir(struct file *file, struct dir_context *ctx)
  * - if afs_dir_iterate_block() spots this function, it'll pass the FID
  *   uniquifier through dtype
  */
-static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
+static bool afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
                                  int nlen, loff_t fpos, u64 ino, unsigned dtype)
 {
        struct afs_lookup_one_cookie *cookie =
@@ -584,16 +584,16 @@ static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
 
        if (cookie->name.len != nlen ||
            memcmp(cookie->name.name, name, nlen) != 0) {
-               _leave(" = 0 [no]");
-               return 0;
+               _leave(" = true [keep looking]");
+               return true;
        }
 
        cookie->fid.vnode = ino;
        cookie->fid.unique = dtype;
        cookie->found = 1;
 
-       _leave(" = -1 [found]");
-       return -1;
+       _leave(" = false [found]");
+       return false;
 }
 
 /*
@@ -636,12 +636,11 @@ static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
  * - if afs_dir_iterate_block() spots this function, it'll pass the FID
  *   uniquifier through dtype
  */
-static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
+static bool afs_lookup_filldir(struct dir_context *ctx, const char *name,
                              int nlen, loff_t fpos, u64 ino, unsigned dtype)
 {
        struct afs_lookup_cookie *cookie =
                container_of(ctx, struct afs_lookup_cookie, ctx);
-       int ret;
 
        _enter("{%s,%u},%s,%u,,%llu,%u",
               cookie->name.name, cookie->name.len, name, nlen,
@@ -663,12 +662,10 @@ static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
                cookie->fids[1].unique  = dtype;
                cookie->found = 1;
                if (cookie->one_only)
-                       return -1;
+                       return false;
        }
 
-       ret = cookie->nr_fids >= 50 ? -1 : 0;
-       _leave(" = %d", ret);
-       return ret;
+       return cookie->nr_fids < 50;
 }
 
 /*
index 18d5b91cb573edc34e4e3e8876911b14c6c2fe76..c29814a66c5b41dda8b113ed994de9db2b58f105 100644 (file)
@@ -53,7 +53,7 @@ struct ecryptfs_getdents_callback {
 };
 
 /* Inspired by generic filldir in fs/readdir.c */
-static int
+static bool
 ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
                 int lower_namelen, loff_t offset, u64 ino, unsigned int d_type)
 {
@@ -61,18 +61,19 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
                container_of(ctx, struct ecryptfs_getdents_callback, ctx);
        size_t name_size;
        char *name;
-       int rc;
+       int err;
+       bool res;
 
        buf->filldir_called++;
-       rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
-                                                 buf->sb, lower_name,
-                                                 lower_namelen);
-       if (rc) {
-               if (rc != -EINVAL) {
+       err = ecryptfs_decode_and_decrypt_filename(&name, &name_size,
+                                                  buf->sb, lower_name,
+                                                  lower_namelen);
+       if (err) {
+               if (err != -EINVAL) {
                        ecryptfs_printk(KERN_DEBUG,
                                        "%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
-                                       __func__, lower_name, rc);
-                       return rc;
+                                       __func__, lower_name, err);
+                       return false;
                }
 
                /* Mask -EINVAL errors as these are most likely due a plaintext
@@ -81,16 +82,15 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
                 * the "lost+found" dentry in the root directory of an Ext4
                 * filesystem.
                 */
-               return 0;
+               return true;
        }
 
        buf->caller->pos = buf->ctx.pos;
-       rc = !dir_emit(buf->caller, name, name_size, ino, d_type);
+       res = dir_emit(buf->caller, name, name_size, ino, d_type);
        kfree(name);
-       if (!rc)
+       if (res)
                buf->entries_written++;
-
-       return rc;
+       return res;
 }
 
 /**
@@ -111,14 +111,8 @@ static int ecryptfs_readdir(struct file *file, struct dir_context *ctx)
        lower_file = ecryptfs_file_to_lower(file);
        rc = iterate_dir(lower_file, &buf.ctx);
        ctx->pos = buf.ctx.pos;
-       if (rc < 0)
-               goto out;
-       if (buf.filldir_called && !buf.entries_written)
-               goto out;
-       if (rc >= 0)
-               fsstack_copy_attr_atime(inode,
-                                       file_inode(lower_file));
-out:
+       if (rc >= 0 && (buf.entries_written || !buf.filldir_called))
+               fsstack_copy_attr_atime(inode, file_inode(lower_file));
        return rc;
 }
 
index 3ef80d000e13d5a46e886492583322e8344f182e..c648a493faf23865780924ece6dceda506d75152 100644 (file)
@@ -248,21 +248,20 @@ struct getdents_callback {
  * A rather strange filldir function to capture
  * the name matching the specified inode number.
  */
-static int filldir_one(struct dir_context *ctx, const char *name, int len,
+static bool filldir_one(struct dir_context *ctx, const char *name, int len,
                        loff_t pos, u64 ino, unsigned int d_type)
 {
        struct getdents_callback *buf =
                container_of(ctx, struct getdents_callback, ctx);
-       int result = 0;
 
        buf->sequence++;
        if (buf->ino == ino && len <= NAME_MAX) {
                memcpy(buf->name, name, len);
                buf->name[len] = '\0';
                buf->found = 1;
-               result = -1;
+               return false;   // no more
        }
-       return result;
+       return true;
 }
 
 /**
index 249825017da759a338fcd575cce47fab7e6b1c3b..00235b8a1823af6b7d6a54cdb12439d2f3365e04 100644 (file)
@@ -705,7 +705,7 @@ static int fat_readdir(struct file *file, struct dir_context *ctx)
 }
 
 #define FAT_IOCTL_FILLDIR_FUNC(func, dirent_type)                         \
-static int func(struct dir_context *ctx, const char *name, int name_len,   \
+static bool func(struct dir_context *ctx, const char *name, int name_len,  \
                             loff_t offset, u64 ino, unsigned int d_type)  \
 {                                                                         \
        struct fat_ioctl_filldir_callback *buf =                           \
@@ -714,7 +714,7 @@ static int func(struct dir_context *ctx, const char *name, int name_len,   \
        struct dirent_type __user *d2 = d1 + 1;                            \
                                                                           \
        if (buf->result)                                                   \
-               return -EINVAL;                                            \
+               return false;                                              \
        buf->result++;                                                     \
                                                                           \
        if (name != NULL) {                                                \
@@ -750,10 +750,10 @@ static int func(struct dir_context *ctx, const char *name, int name_len,   \
                    put_user(short_len, &d1->d_reclen))                    \
                        goto efault;                                       \
        }                                                                  \
-       return 0;                                                          \
+       return true;                                                       \
 efault:                                                                           \
        buf->result = -EFAULT;                                             \
-       return -EFAULT;                                                    \
+       return false;                                                      \
 }
 
 FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
index 99c6796c9f28a67eb897611832584d77b95021b9..dd88701e54a93aa33958d03b1dbca5715e290c92 100644 (file)
@@ -324,12 +324,7 @@ static void __fput(struct file *file)
        }
        fops_put(file->f_op);
        put_pid(file->f_owner.pid);
-       if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
-               i_readcount_dec(inode);
-       if (mode & FMODE_WRITER) {
-               put_write_access(inode);
-               __mnt_drop_write(mnt);
-       }
+       put_file_access(file);
        dput(dentry);
        if (unlikely(mode & FMODE_NEED_UNMOUNT))
                dissolve_on_fput(mnt);
index 756d05779200dcdac43f67daa0fea9e9ccd3ff6d..cf40895233f5a88147d4dff2caf79b38794e40d9 100644 (file)
@@ -66,7 +66,7 @@ struct get_name_filldir {
        char *name;
 };
 
-static int get_name_filldir(struct dir_context *ctx, const char *name,
+static bool get_name_filldir(struct dir_context *ctx, const char *name,
                            int length, loff_t offset, u64 inum,
                            unsigned int type)
 {
@@ -74,12 +74,12 @@ static int get_name_filldir(struct dir_context *ctx, const char *name,
                container_of(ctx, struct get_name_filldir, ctx);
 
        if (inum != gnfd->inum.no_addr)
-               return 0;
+               return true;
 
        memcpy(gnfd->name, name, length);
        gnfd->name[length] = 0;
 
-       return 1;
+       return false;
 }
 
 static int gfs2_get_name(struct dentry *parent, char *name,
index 3e206d3e317c404bb8f014844b8d78be0dedc846..4372d67a37533198ee3ba37ff375a25b4d051c77 100644 (file)
@@ -102,6 +102,16 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
 extern struct file *alloc_empty_file(int, const struct cred *);
 extern struct file *alloc_empty_file_noaccount(int, const struct cred *);
 
+static inline void put_file_access(struct file *file)
+{
+       if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
+               i_readcount_dec(file->f_inode);
+       } else if (file->f_mode & FMODE_WRITER) {
+               put_write_access(file->f_inode);
+               __mnt_drop_write(file->f_path.mnt);
+       }
+}
+
 /*
  * super.c
  */
index 19412ac701a65cbfcf25a9a0f1a1b8a234c54cb7..bfa6b41d895b106f8507ab15596dc4a2892bb0d0 100644 (file)
@@ -3776,7 +3776,7 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
        return 0;
 }
 
-static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
+static bool __query_dir(struct dir_context *ctx, const char *name, int namlen,
                       loff_t offset, u64 ino, unsigned int d_type)
 {
        struct ksmbd_readdir_data       *buf;
@@ -3790,22 +3790,20 @@ static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
 
        /* dot and dotdot entries are already reserved */
        if (!strcmp(".", name) || !strcmp("..", name))
-               return 0;
+               return true;
        if (ksmbd_share_veto_filename(priv->work->tcon->share_conf, name))
-               return 0;
+               return true;
        if (!match_pattern(name, namlen, priv->search_pattern))
-               return 0;
+               return true;
 
        d_info->name            = name;
        d_info->name_len        = namlen;
        rc = reserve_populate_dentry(d_info, priv->info_level);
        if (rc)
-               return rc;
-       if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY) {
+               return false;
+       if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY)
                d_info->out_buf_len = 0;
-               return 0;
-       }
-       return 0;
+       return true;
 }
 
 static void restart_ctx(struct dir_context *ctx)
index 78d01033604c6b469f88f1fab62921732c81e6e2..48b2b901f6e5503876b98603ae97c807fc1a4d7b 100644 (file)
@@ -1105,7 +1105,7 @@ int ksmbd_vfs_unlink(struct user_namespace *user_ns,
        return err;
 }
 
-static int __dir_empty(struct dir_context *ctx, const char *name, int namlen,
+static bool __dir_empty(struct dir_context *ctx, const char *name, int namlen,
                       loff_t offset, u64 ino, unsigned int d_type)
 {
        struct ksmbd_readdir_data *buf;
@@ -1113,9 +1113,7 @@ static int __dir_empty(struct dir_context *ctx, const char *name, int namlen,
        buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
        buf->dirent_count++;
 
-       if (buf->dirent_count > 2)
-               return -ENOTEMPTY;
-       return 0;
+       return buf->dirent_count <= 2;
 }
 
 /**
@@ -1142,7 +1140,7 @@ int ksmbd_vfs_empty_dir(struct ksmbd_file *fp)
        return err;
 }
 
-static int __caseless_lookup(struct dir_context *ctx, const char *name,
+static bool __caseless_lookup(struct dir_context *ctx, const char *name,
                             int namlen, loff_t offset, u64 ino,
                             unsigned int d_type)
 {
@@ -1151,13 +1149,13 @@ static int __caseless_lookup(struct dir_context *ctx, const char *name,
        buf = container_of(ctx, struct ksmbd_readdir_data, ctx);
 
        if (buf->used != namlen)
-               return 0;
+               return true;
        if (!strncasecmp((char *)buf->private, name, namlen)) {
                memcpy((char *)buf->private, name, namlen);
                buf->dirent_count = 1;
-               return -EEXIST;
+               return false;
        }
-       return 0;
+       return true;
 }
 
 /**
index 5d680045fa2c7fcb6377b41b1b656df5abccfde6..78b8cd9651d5b929cd1352f55ee652c577f61960 100644 (file)
@@ -266,7 +266,7 @@ struct nfs4_dir_ctx {
        struct list_head names;
 };
 
-static int
+static bool
 nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
                loff_t offset, u64 ino, unsigned int d_type)
 {
@@ -275,14 +275,14 @@ nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
        struct name_list *entry;
 
        if (namlen != HEXDIR_LEN - 1)
-               return 0;
+               return true;
        entry = kmalloc(sizeof(struct name_list), GFP_KERNEL);
        if (entry == NULL)
-               return -ENOMEM;
+               return false;
        memcpy(entry->name, name, HEXDIR_LEN - 1);
        entry->name[HEXDIR_LEN - 1] = '\0';
        list_add(&entry->list, &ctx->names);
-       return 0;
+       return true;
 }
 
 static int
index 83be89905cbf299fcccd27f162c99ee4605edae2..f650afedd67fafc5d71bbfe41a845ae4a721afe6 100644 (file)
@@ -1854,7 +1854,7 @@ struct readdir_data {
        int             full;
 };
 
-static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
+static bool nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
                                 int namlen, loff_t offset, u64 ino,
                                 unsigned int d_type)
 {
@@ -1866,7 +1866,7 @@ static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
        reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64));
        if (buf->used + reclen > PAGE_SIZE) {
                buf->full = 1;
-               return -EINVAL;
+               return false;
        }
 
        de->namlen = namlen;
@@ -1876,7 +1876,7 @@ static int nfsd_buffered_filldir(struct dir_context *ctx, const char *name,
        memcpy(de->name, name, namlen);
        buf->used += reclen;
 
-       return 0;
+       return true;
 }
 
 static __be32 nfsd_buffered_readdir(struct file *file, struct svc_fh *fhp,
index 81c3d65d68fec7cd4eb7061f1a5cefd81e65d60d..694471fc46b822c30dcec6cce927b278bf72d0c3 100644 (file)
@@ -2032,7 +2032,7 @@ struct ocfs2_empty_dir_priv {
        unsigned seen_other;
        unsigned dx_dir;
 };
-static int ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
+static bool ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
                                   int name_len, loff_t pos, u64 ino,
                                   unsigned type)
 {
@@ -2052,7 +2052,7 @@ static int ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
         */
        if (name_len == 1 && !strncmp(".", name, 1) && pos == 0) {
                p->seen_dot = 1;
-               return 0;
+               return true;
        }
 
        if (name_len == 2 && !strncmp("..", name, 2) &&
@@ -2060,13 +2060,13 @@ static int ocfs2_empty_dir_filldir(struct dir_context *ctx, const char *name,
                p->seen_dot_dot = 1;
 
                if (p->dx_dir && p->seen_dot)
-                       return 1;
+                       return false;
 
-               return 0;
+               return true;
        }
 
        p->seen_other = 1;
-       return 1;
+       return false;
 }
 
 static int ocfs2_empty_dir_dx(struct inode *inode,
index fa87d89cf75422f1aaac4f95726fb31be1267a3c..126671e6caeda6e777b0861b622f43a23578329a 100644 (file)
@@ -2057,7 +2057,7 @@ struct ocfs2_orphan_filldir_priv {
        enum ocfs2_orphan_reco_type orphan_reco_type;
 };
 
-static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
+static bool ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
                                int name_len, loff_t pos, u64 ino,
                                unsigned type)
 {
@@ -2066,21 +2066,21 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
        struct inode *iter;
 
        if (name_len == 1 && !strncmp(".", name, 1))
-               return 0;
+               return true;
        if (name_len == 2 && !strncmp("..", name, 2))
-               return 0;
+               return true;
 
        /* do not include dio entry in case of orphan scan */
        if ((p->orphan_reco_type == ORPHAN_NO_NEED_TRUNCATE) &&
                        (!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
                        OCFS2_DIO_ORPHAN_PREFIX_LEN)))
-               return 0;
+               return true;
 
        /* Skip bad inodes so that recovery can continue */
        iter = ocfs2_iget(p->osb, ino,
                          OCFS2_FI_FLAG_ORPHAN_RECOVERY, 0);
        if (IS_ERR(iter))
-               return 0;
+               return true;
 
        if (!strncmp(name, OCFS2_DIO_ORPHAN_PREFIX,
                        OCFS2_DIO_ORPHAN_PREFIX_LEN))
@@ -2090,7 +2090,7 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
         * happen concurrently with unlink/rename */
        if (OCFS2_I(iter)->ip_next_orphan) {
                iput(iter);
-               return 0;
+               return true;
        }
 
        trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno);
@@ -2099,7 +2099,7 @@ static int ocfs2_orphan_filldir(struct dir_context *ctx, const char *name,
        OCFS2_I(iter)->ip_next_orphan = p->head;
        p->head = iter;
 
-       return 0;
+       return true;
 }
 
 static int ocfs2_queue_orphans(struct ocfs2_super *osb,
index cf7e5c350a54be924b40fff310ba03177d539905..a81319b6177f69a4b905688136c0231a6a3700dc 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -842,7 +842,9 @@ static int do_dentry_open(struct file *f,
                return 0;
        }
 
-       if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
+       if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
+               i_readcount_inc(inode);
+       } else if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
                error = get_write_access(inode);
                if (unlikely(error))
                        goto cleanup_file;
@@ -882,8 +884,6 @@ static int do_dentry_open(struct file *f,
                        goto cleanup_all;
        }
        f->f_mode |= FMODE_OPENED;
-       if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
-               i_readcount_inc(inode);
        if ((f->f_mode & FMODE_READ) &&
             likely(f->f_op->read || f->f_op->read_iter))
                f->f_mode |= FMODE_CAN_READ;
@@ -937,10 +937,7 @@ cleanup_all:
        if (WARN_ON_ONCE(error > 0))
                error = -EINVAL;
        fops_put(f->f_op);
-       if (f->f_mode & FMODE_WRITER) {
-               put_write_access(inode);
-               __mnt_drop_write(f->f_path.mnt);
-       }
+       put_file_access(f);
 cleanup_file:
        path_put(&f->f_path);
        f->f_path.mnt = NULL;
index 78f62cc1797becb9caac4d1842a5278f81cf2f71..8c25d185cdc0d6abeda9727c77705f914709a1db 100644 (file)
@@ -170,7 +170,7 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
        return p;
 }
 
-static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
+static bool ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
                                  const char *name, int len, u64 ino,
                                  unsigned int d_type)
 {
@@ -179,22 +179,22 @@ static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
        struct ovl_cache_entry *p;
 
        if (ovl_cache_entry_find_link(name, len, &newp, &parent))
-               return 0;
+               return true;
 
        p = ovl_cache_entry_new(rdd, name, len, ino, d_type);
        if (p == NULL) {
                rdd->err = -ENOMEM;
-               return -ENOMEM;
+               return false;
        }
 
        list_add_tail(&p->l_node, rdd->list);
        rb_link_node(&p->node, parent, newp);
        rb_insert_color(&p->node, rdd->root);
 
-       return 0;
+       return true;
 }
 
-static int ovl_fill_lowest(struct ovl_readdir_data *rdd,
+static bool ovl_fill_lowest(struct ovl_readdir_data *rdd,
                           const char *name, int namelen,
                           loff_t offset, u64 ino, unsigned int d_type)
 {
@@ -211,7 +211,7 @@ static int ovl_fill_lowest(struct ovl_readdir_data *rdd,
                        list_add_tail(&p->l_node, &rdd->middle);
        }
 
-       return rdd->err;
+       return rdd->err == 0;
 }
 
 void ovl_cache_free(struct list_head *list)
@@ -250,7 +250,7 @@ static void ovl_cache_put(struct ovl_dir_file *od, struct dentry *dentry)
        }
 }
 
-static int ovl_fill_merge(struct dir_context *ctx, const char *name,
+static bool ovl_fill_merge(struct dir_context *ctx, const char *name,
                          int namelen, loff_t offset, u64 ino,
                          unsigned int d_type)
 {
@@ -528,7 +528,7 @@ fail:
        goto out;
 }
 
-static int ovl_fill_plain(struct dir_context *ctx, const char *name,
+static bool ovl_fill_plain(struct dir_context *ctx, const char *name,
                          int namelen, loff_t offset, u64 ino,
                          unsigned int d_type)
 {
@@ -540,11 +540,11 @@ static int ovl_fill_plain(struct dir_context *ctx, const char *name,
        p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type);
        if (p == NULL) {
                rdd->err = -ENOMEM;
-               return -ENOMEM;
+               return false;
        }
        list_add_tail(&p->l_node, rdd->list);
 
-       return 0;
+       return true;
 }
 
 static int ovl_dir_read_impure(struct path *path,  struct list_head *list,
@@ -648,7 +648,7 @@ struct ovl_readdir_translate {
        bool xinowarn;
 };
 
-static int ovl_fill_real(struct dir_context *ctx, const char *name,
+static bool ovl_fill_real(struct dir_context *ctx, const char *name,
                           int namelen, loff_t offset, u64 ino,
                           unsigned int d_type)
 {
@@ -1027,7 +1027,7 @@ void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper,
        inode_unlock(upper->d_inode);
 }
 
-static int ovl_check_d_type(struct dir_context *ctx, const char *name,
+static bool ovl_check_d_type(struct dir_context *ctx, const char *name,
                          int namelen, loff_t offset, u64 ino,
                          unsigned int d_type)
 {
@@ -1036,12 +1036,12 @@ static int ovl_check_d_type(struct dir_context *ctx, const char *name,
 
        /* Even if d_type is not supported, DT_DIR is returned for . and .. */
        if (!strncmp(name, ".", namelen) || !strncmp(name, "..", namelen))
-               return 0;
+               return true;
 
        if (d_type != DT_UNKNOWN)
                rdd->d_type_supported = true;
 
-       return 0;
+       return true;
 }
 
 /*
index 09e8ed7d416141406ed5b2eacef0a9de30120bd3..9c53edb60c03130d119bcc7f2197b30dbc4d690f 100644 (file)
@@ -140,7 +140,7 @@ struct readdir_callback {
        int result;
 };
 
-static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
+static bool fillonedir(struct dir_context *ctx, const char *name, int namlen,
                      loff_t offset, u64 ino, unsigned int d_type)
 {
        struct readdir_callback *buf =
@@ -149,14 +149,14 @@ static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
        unsigned long d_ino;
 
        if (buf->result)
-               return -EINVAL;
+               return false;
        buf->result = verify_dirent_name(name, namlen);
-       if (buf->result < 0)
-               return buf->result;
+       if (buf->result)
+               return false;
        d_ino = ino;
        if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
                buf->result = -EOVERFLOW;
-               return -EOVERFLOW;
+               return false;
        }
        buf->result++;
        dirent = buf->dirent;
@@ -169,12 +169,12 @@ static int fillonedir(struct dir_context *ctx, const char *name, int namlen,
        unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
        unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
        user_write_access_end();
-       return 0;
+       return true;
 efault_end:
        user_write_access_end();
 efault:
        buf->result = -EFAULT;
-       return -EFAULT;
+       return false;
 }
 
 SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
@@ -219,7 +219,7 @@ struct getdents_callback {
        int error;
 };
 
-static int filldir(struct dir_context *ctx, const char *name, int namlen,
+static bool filldir(struct dir_context *ctx, const char *name, int namlen,
                   loff_t offset, u64 ino, unsigned int d_type)
 {
        struct linux_dirent __user *dirent, *prev;
@@ -232,18 +232,18 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
 
        buf->error = verify_dirent_name(name, namlen);
        if (unlikely(buf->error))
-               return buf->error;
+               return false;
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
-               return -EINVAL;
+               return false;
        d_ino = ino;
        if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
                buf->error = -EOVERFLOW;
-               return -EOVERFLOW;
+               return false;
        }
        prev_reclen = buf->prev_reclen;
        if (prev_reclen && signal_pending(current))
-               return -EINTR;
+               return false;
        dirent = buf->current_dir;
        prev = (void __user *) dirent - prev_reclen;
        if (!user_write_access_begin(prev, reclen + prev_reclen))
@@ -260,12 +260,12 @@ static int filldir(struct dir_context *ctx, const char *name, int namlen,
        buf->current_dir = (void __user *)dirent + reclen;
        buf->prev_reclen = reclen;
        buf->count -= reclen;
-       return 0;
+       return true;
 efault_end:
        user_write_access_end();
 efault:
        buf->error = -EFAULT;
-       return -EFAULT;
+       return false;
 }
 
 SYSCALL_DEFINE3(getdents, unsigned int, fd,
@@ -307,7 +307,7 @@ struct getdents_callback64 {
        int error;
 };
 
-static int filldir64(struct dir_context *ctx, const char *name, int namlen,
+static bool filldir64(struct dir_context *ctx, const char *name, int namlen,
                     loff_t offset, u64 ino, unsigned int d_type)
 {
        struct linux_dirent64 __user *dirent, *prev;
@@ -319,13 +319,13 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
 
        buf->error = verify_dirent_name(name, namlen);
        if (unlikely(buf->error))
-               return buf->error;
+               return false;
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
-               return -EINVAL;
+               return false;
        prev_reclen = buf->prev_reclen;
        if (prev_reclen && signal_pending(current))
-               return -EINTR;
+               return false;
        dirent = buf->current_dir;
        prev = (void __user *)dirent - prev_reclen;
        if (!user_write_access_begin(prev, reclen + prev_reclen))
@@ -342,13 +342,13 @@ static int filldir64(struct dir_context *ctx, const char *name, int namlen,
        buf->prev_reclen = reclen;
        buf->current_dir = (void __user *)dirent + reclen;
        buf->count -= reclen;
-       return 0;
+       return true;
 
 efault_end:
        user_write_access_end();
 efault:
        buf->error = -EFAULT;
-       return -EFAULT;
+       return false;
 }
 
 SYSCALL_DEFINE3(getdents64, unsigned int, fd,
@@ -397,7 +397,7 @@ struct compat_readdir_callback {
        int result;
 };
 
-static int compat_fillonedir(struct dir_context *ctx, const char *name,
+static bool compat_fillonedir(struct dir_context *ctx, const char *name,
                             int namlen, loff_t offset, u64 ino,
                             unsigned int d_type)
 {
@@ -407,14 +407,14 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
        compat_ulong_t d_ino;
 
        if (buf->result)
-               return -EINVAL;
+               return false;
        buf->result = verify_dirent_name(name, namlen);
-       if (buf->result < 0)
-               return buf->result;
+       if (buf->result)
+               return false;
        d_ino = ino;
        if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
                buf->result = -EOVERFLOW;
-               return -EOVERFLOW;
+               return false;
        }
        buf->result++;
        dirent = buf->dirent;
@@ -427,12 +427,12 @@ static int compat_fillonedir(struct dir_context *ctx, const char *name,
        unsafe_put_user(namlen, &dirent->d_namlen, efault_end);
        unsafe_copy_dirent_name(dirent->d_name, name, namlen, efault_end);
        user_write_access_end();
-       return 0;
+       return true;
 efault_end:
        user_write_access_end();
 efault:
        buf->result = -EFAULT;
-       return -EFAULT;
+       return false;
 }
 
 COMPAT_SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
@@ -471,7 +471,7 @@ struct compat_getdents_callback {
        int error;
 };
 
-static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
+static bool compat_filldir(struct dir_context *ctx, const char *name, int namlen,
                loff_t offset, u64 ino, unsigned int d_type)
 {
        struct compat_linux_dirent __user *dirent, *prev;
@@ -484,18 +484,18 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
 
        buf->error = verify_dirent_name(name, namlen);
        if (unlikely(buf->error))
-               return buf->error;
+               return false;
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count)
-               return -EINVAL;
+               return false;
        d_ino = ino;
        if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
                buf->error = -EOVERFLOW;
-               return -EOVERFLOW;
+               return false;
        }
        prev_reclen = buf->prev_reclen;
        if (prev_reclen && signal_pending(current))
-               return -EINTR;
+               return false;
        dirent = buf->current_dir;
        prev = (void __user *) dirent - prev_reclen;
        if (!user_write_access_begin(prev, reclen + prev_reclen))
@@ -511,12 +511,12 @@ static int compat_filldir(struct dir_context *ctx, const char *name, int namlen,
        buf->prev_reclen = reclen;
        buf->current_dir = (void __user *)dirent + reclen;
        buf->count -= reclen;
-       return 0;
+       return true;
 efault_end:
        user_write_access_end();
 efault:
        buf->error = -EFAULT;
-       return -EFAULT;
+       return false;
 }
 
 COMPAT_SYSCALL_DEFINE3(getdents, unsigned int, fd,
index 4366413692836261925eb57edf0f47fd881f4a64..8b2d52443f415ca49160c7032856ed2cc7ae2023 100644 (file)
@@ -189,7 +189,7 @@ struct reiserfs_dentry_buf {
        struct dentry *dentries[8];
 };
 
-static int
+static bool
 fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
                   loff_t offset, u64 ino, unsigned int d_type)
 {
@@ -200,16 +200,16 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
        WARN_ON_ONCE(!inode_is_locked(d_inode(dbuf->xadir)));
 
        if (dbuf->count == ARRAY_SIZE(dbuf->dentries))
-               return -ENOSPC;
+               return false;
 
        if (name[0] == '.' && (namelen < 2 ||
                               (namelen == 2 && name[1] == '.')))
-               return 0;
+               return true;
 
        dentry = lookup_one_len(name, dbuf->xadir, namelen);
        if (IS_ERR(dentry)) {
                dbuf->err = PTR_ERR(dentry);
-               return PTR_ERR(dentry);
+               return false;
        } else if (d_really_is_negative(dentry)) {
                /* A directory entry exists, but no file? */
                reiserfs_error(dentry->d_sb, "xattr-20003",
@@ -218,11 +218,11 @@ fill_with_dentries(struct dir_context *ctx, const char *name, int namelen,
                               dentry, dbuf->xadir);
                dput(dentry);
                dbuf->err = -EIO;
-               return -EIO;
+               return false;
        }
 
        dbuf->dentries[dbuf->count++] = dentry;
-       return 0;
+       return true;
 }
 
 static void
@@ -797,7 +797,7 @@ struct listxattr_buf {
        struct dentry *dentry;
 };
 
-static int listxattr_filler(struct dir_context *ctx, const char *name,
+static bool listxattr_filler(struct dir_context *ctx, const char *name,
                            int namelen, loff_t offset, u64 ino,
                            unsigned int d_type)
 {
@@ -813,19 +813,19 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
                                                    name);
                if (!handler /* Unsupported xattr name */ ||
                    (handler->list && !handler->list(b->dentry)))
-                       return 0;
+                       return true;
                size = namelen + 1;
                if (b->buf) {
                        if (b->pos + size > b->size) {
                                b->pos = -ERANGE;
-                               return -ERANGE;
+                               return false;
                        }
                        memcpy(b->buf + b->pos, name, namelen);
                        b->buf[b->pos + namelen] = 0;
                }
                b->pos += size;
        }
-       return 0;
+       return true;
 }
 
 /*
index 5abb5fdb71d93992e53f040d1552f68ab7a26443..b594f02a52c479c198aab5d7414a3a36329c5512 100644 (file)
@@ -99,7 +99,7 @@ out:
  * we check the inode number to make sure it's sane, then we check that
  * we can look up this filename.  Finally, we check the ftype.
  */
-STATIC int
+STATIC bool
 xchk_dir_actor(
        struct dir_context      *dir_iter,
        const char              *name,
@@ -124,7 +124,7 @@ xchk_dir_actor(
                        xfs_dir2_dataptr_to_db(mp->m_dir_geo, pos));
 
        if (xchk_should_terminate(sdc->sc, &error))
-               return error;
+               return !error;
 
        /* Does this inode number make sense? */
        if (!xfs_verify_dir_ino(mp, ino)) {
@@ -191,8 +191,8 @@ out:
         * and return zero to xchk_directory.
         */
        if (error == 0 && sdc->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
-               return -EFSCORRUPTED;
-       return error;
+               return false;
+       return !error;
 }
 
 /* Scrub a directory btree record. */
index ab182a5cd0c0adca5d987f8bb72b3ca01a3ca0c1..d8dff3fd80530c8ed2f6f6a33b18afbdbfbfc1bf 100644 (file)
@@ -38,7 +38,7 @@ struct xchk_parent_ctx {
 };
 
 /* Look for a single entry in a directory pointing to an inode. */
-STATIC int
+STATIC bool
 xchk_parent_actor(
        struct dir_context      *dc,
        const char              *name,
@@ -62,7 +62,7 @@ xchk_parent_actor(
        if (xchk_should_terminate(spc->sc, &error))
                spc->cancelled = true;
 
-       return error;
+       return !error;
 }
 
 /* Count the number of dentries in the parent dir that point to this inode. */
index 0830486f47efbc4cc7c14914e083dd0a2aacee97..7591d2d2dcbba9a0a1e501a3759c23f195caade6 100644 (file)
@@ -2038,9 +2038,10 @@ umode_t mode_strip_sgid(struct user_namespace *mnt_userns,
  * the kernel specify what kind of dirent layout it wants to have.
  * This allows the kernel to read directories into kernel space or
  * to have different dirent layouts depending on the binary type.
+ * Return 'true' to keep going and 'false' if there are no more entries.
  */
 struct dir_context;
-typedef int (*filldir_t)(struct dir_context *, const char *, int, loff_t, u64,
+typedef bool (*filldir_t)(struct dir_context *, const char *, int, loff_t, u64,
                         unsigned);
 
 struct dir_context {
@@ -3540,17 +3541,17 @@ static inline bool dir_emit(struct dir_context *ctx,
                            const char *name, int namelen,
                            u64 ino, unsigned type)
 {
-       return ctx->actor(ctx, name, namelen, ctx->pos, ino, type) == 0;
+       return ctx->actor(ctx, name, namelen, ctx->pos, ino, type);
 }
 static inline bool dir_emit_dot(struct file *file, struct dir_context *ctx)
 {
        return ctx->actor(ctx, ".", 1, ctx->pos,
-                         file->f_path.dentry->d_inode->i_ino, DT_DIR) == 0;
+                         file->f_path.dentry->d_inode->i_ino, DT_DIR);
 }
 static inline bool dir_emit_dotdot(struct file *file, struct dir_context *ctx)
 {
        return ctx->actor(ctx, "..", 2, ctx->pos,
-                         parent_ino(file->f_path.dentry), DT_DIR) == 0;
+                         parent_ino(file->f_path.dentry), DT_DIR);
 }
 static inline bool dir_emit_dots(struct file *file, struct dir_context *ctx)
 {