fs: fix kernel_read prototype
authorChristoph Hellwig <hch@lst.de>
Fri, 1 Sep 2017 15:39:13 +0000 (17:39 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 4 Sep 2017 23:05:15 +0000 (19:05 -0400)
Use proper ssize_t and size_t types for the return value and count
argument, move the offset last and make it an in/out argument like
all other read/write helpers, and make the buf argument a void pointer
to get rid of lots of casts in the callers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
17 files changed:
arch/mips/kernel/elf.c
arch/x86/ia32/ia32_aout.c
drivers/media/pci/cx25821/cx25821-audio-upstream.c
drivers/mtd/nand/nandsim.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/binfmt_flat.c
fs/binfmt_misc.c
fs/coda/dir.c
fs/ecryptfs/read_write.c
fs/exec.c
fs/read_write.c
include/linux/fs.h
kernel/sysctl_binary.c
net/9p/trans_fd.c
security/keys/big_key.c

index 5c429d70e17f6f24cbcfd0fa912c67eccd11f28f..0828d6d963b7294291203500caa95592d962981c 100644 (file)
@@ -87,6 +87,7 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
        bool elf32;
        u32 flags;
        int ret;
+       loff_t pos;
 
        elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32;
        flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags;
@@ -108,21 +109,16 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
 
                if (phdr32->p_filesz < sizeof(abiflags))
                        return -EINVAL;
-
-               ret = kernel_read(elf, phdr32->p_offset,
-                                 (char *)&abiflags,
-                                 sizeof(abiflags));
+               pos = phdr32->p_offset;
        } else {
                if (phdr64->p_type != PT_MIPS_ABIFLAGS)
                        return 0;
                if (phdr64->p_filesz < sizeof(abiflags))
                        return -EINVAL;
-
-               ret = kernel_read(elf, phdr64->p_offset,
-                                 (char *)&abiflags,
-                                 sizeof(abiflags));
+               pos = phdr64->p_offset;
        }
 
+       ret = kernel_read(elf, &abiflags, sizeof(abiflags), &pos);
        if (ret < 0)
                return ret;
        if (ret != sizeof(abiflags))
index 8d0879f1d42cad890057408160e253ca026503b9..8e02b30cf08e16a2ca5b3d0b6aa97bda051a2c85 100644 (file)
@@ -407,10 +407,10 @@ static int load_aout_library(struct file *file)
        unsigned long bss, start_addr, len, error;
        int retval;
        struct exec ex;
-
+       loff_t pos = 0;
 
        retval = -ENOEXEC;
-       error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
+       error = kernel_read(file, &ex, sizeof(ex), &pos);
        if (error != sizeof(ex))
                goto out;
 
index b94eb1c0023d810c9ed7fcb50b9c88d4b222b5fe..ada26d4acfb4087074dd6af618270eb52235fa20 100644 (file)
@@ -277,7 +277,7 @@ static int cx25821_get_audio_data(struct cx25821_dev *dev,
                p = (char *)dev->_audiodata_buf_virt_addr + frame_offset;
 
        for (i = 0; i < dev->_audio_lines_count; i++) {
-               int n = kernel_read(file, file_offset, mybuf, AUDIO_LINE_SIZE);
+               int n = kernel_read(file, mybuf, AUDIO_LINE_SIZE, &file_offset);
                if (n < AUDIO_LINE_SIZE) {
                        pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
                                __func__);
@@ -290,7 +290,6 @@ static int cx25821_get_audio_data(struct cx25821_dev *dev,
                        memcpy(p, mybuf, n);
                        p += n;
                }
-               file_offset += n;
        }
        dev->_audioframe_count++;
        fput(file);
@@ -318,7 +317,7 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev,
 {
        char *p = (void *)dev->_audiodata_buf_virt_addr;
        struct file *file;
-       loff_t offset;
+       loff_t file_offset = 0;
        int i, j;
 
        file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
@@ -328,11 +327,11 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev,
                return PTR_ERR(file);
        }
 
-       for (j = 0, offset = 0; j < NUM_AUDIO_FRAMES; j++) {
+       for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
                for (i = 0; i < dev->_audio_lines_count; i++) {
                        char buf[AUDIO_LINE_SIZE];
-                       int n = kernel_read(file, offset, buf,
-                                               AUDIO_LINE_SIZE);
+                       loff_t offset = file_offset;
+                       int n = kernel_read(file, buf, AUDIO_LINE_SIZE, &file_offset);
 
                        if (n < AUDIO_LINE_SIZE) {
                                pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
@@ -344,8 +343,6 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev,
 
                        if (p)
                                memcpy(p + offset, buf, n);
-
-                       offset += n;
                }
                dev->_audioframe_count++;
        }
index e4211c3cc49b2ac054a080fd34d83db56f9556da..a8089656879a8023e142aa1886e5e61c2d4fad85 100644 (file)
@@ -1379,7 +1379,7 @@ static ssize_t read_file(struct nandsim *ns, struct file *file, void *buf, size_
        if (err)
                return err;
        noreclaim_flag = memalloc_noreclaim_save();
-       tx = kernel_read(file, pos, buf, count);
+       tx = kernel_read(file, buf, count, &pos);
        memalloc_noreclaim_restore(noreclaim_flag);
        put_pages(ns);
        return tx;
index 9be82c4e14a409a4872094190ea63aa23ef0c1d1..ce1824f47ba6a32222e4df6cea90099de101b9f8 100644 (file)
@@ -341,11 +341,12 @@ static int load_aout_library(struct file *file)
        unsigned long error;
        int retval;
        struct exec ex;
+       loff_t pos = 0;
 
        inode = file_inode(file);
 
        retval = -ENOEXEC;
-       error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
+       error = kernel_read(file, &ex, sizeof(ex), &pos);
        if (error != sizeof(ex))
                goto out;
 
index 6466153f2bf099d357166192710167667abefa09..2f928b87c90e7042c87b2dccb25f76eb2cef77da 100644 (file)
@@ -409,6 +409,7 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex,
 {
        struct elf_phdr *elf_phdata = NULL;
        int retval, size, err = -1;
+       loff_t pos = elf_ex->e_phoff;
 
        /*
         * If the size of this structure has changed, then punt, since
@@ -432,8 +433,7 @@ static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex,
                goto out;
 
        /* Read in the program headers */
-       retval = kernel_read(elf_file, elf_ex->e_phoff,
-                            (char *)elf_phdata, size);
+       retval = kernel_read(elf_file, elf_phdata, size, &pos);
        if (retval != size) {
                err = (retval < 0) ? retval : -EIO;
                goto out;
@@ -698,6 +698,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
                struct elfhdr interp_elf_ex;
        } *loc;
        struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE;
+       loff_t pos;
 
        loc = kmalloc(sizeof(*loc), GFP_KERNEL);
        if (!loc) {
@@ -750,9 +751,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
                        if (!elf_interpreter)
                                goto out_free_ph;
 
-                       retval = kernel_read(bprm->file, elf_ppnt->p_offset,
-                                            elf_interpreter,
-                                            elf_ppnt->p_filesz);
+                       pos = elf_ppnt->p_offset;
+                       retval = kernel_read(bprm->file, elf_interpreter,
+                                            elf_ppnt->p_filesz, &pos);
                        if (retval != elf_ppnt->p_filesz) {
                                if (retval >= 0)
                                        retval = -EIO;
@@ -776,9 +777,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
                        would_dump(bprm, interpreter);
 
                        /* Get the exec headers */
-                       retval = kernel_read(interpreter, 0,
-                                            (void *)&loc->interp_elf_ex,
-                                            sizeof(loc->interp_elf_ex));
+                       pos = 0;
+                       retval = kernel_read(interpreter, &loc->interp_elf_ex,
+                                            sizeof(loc->interp_elf_ex), &pos);
                        if (retval != sizeof(loc->interp_elf_ex)) {
                                if (retval >= 0)
                                        retval = -EIO;
@@ -1175,9 +1176,10 @@ static int load_elf_library(struct file *file)
        unsigned long elf_bss, bss, len;
        int retval, error, i, j;
        struct elfhdr elf_ex;
+       loff_t pos = 0;
 
        error = -ENOEXEC;
-       retval = kernel_read(file, 0, (char *)&elf_ex, sizeof(elf_ex));
+       retval = kernel_read(file, &elf_ex, sizeof(elf_ex), &pos);
        if (retval != sizeof(elf_ex))
                goto out;
 
@@ -1201,7 +1203,8 @@ static int load_elf_library(struct file *file)
 
        eppnt = elf_phdata;
        error = -ENOEXEC;
-       retval = kernel_read(file, elf_ex.e_phoff, (char *)eppnt, j);
+       pos =  elf_ex.e_phoff;
+       retval = kernel_read(file, eppnt, j, &pos);
        if (retval != j)
                goto out_free_ph;
 
index cf93a4fad01218575e3b0f4c9b2806a2b16111dc..b4ebfe203a68af0b4c688e7bd54436f4947c1f99 100644 (file)
@@ -145,6 +145,7 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,
        struct elf32_phdr *phdr;
        unsigned long size;
        int retval, loop;
+       loff_t pos = params->hdr.e_phoff;
 
        if (params->hdr.e_phentsize != sizeof(struct elf_phdr))
                return -ENOMEM;
@@ -156,8 +157,7 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,
        if (!params->phdrs)
                return -ENOMEM;
 
-       retval = kernel_read(file, params->hdr.e_phoff,
-                            (char *) params->phdrs, size);
+       retval = kernel_read(file, params->phdrs, size, &pos);
        if (unlikely(retval != size))
                return retval < 0 ? retval : -ENOEXEC;
 
@@ -199,6 +199,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
        char *interpreter_name = NULL;
        int executable_stack;
        int retval, i;
+       loff_t pos;
 
        kdebug("____ LOAD %d ____", current->pid);
 
@@ -246,10 +247,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
                        if (!interpreter_name)
                                goto error;
 
-                       retval = kernel_read(bprm->file,
-                                            phdr->p_offset,
-                                            interpreter_name,
-                                            phdr->p_filesz);
+                       pos = phdr->p_offset;
+                       retval = kernel_read(bprm->file, interpreter_name,
+                                            phdr->p_filesz, &pos);
                        if (unlikely(retval != phdr->p_filesz)) {
                                if (retval >= 0)
                                        retval = -ENOEXEC;
@@ -277,8 +277,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
                         */
                        would_dump(bprm, interpreter);
 
-                       retval = kernel_read(interpreter, 0, bprm->buf,
-                                            BINPRM_BUF_SIZE);
+                       pos = 0;
+                       retval = kernel_read(interpreter, bprm->buf,
+                                       BINPRM_BUF_SIZE, &pos);
                        if (unlikely(retval != BINPRM_BUF_SIZE)) {
                                if (retval >= 0)
                                        retval = -ENOEXEC;
index a1e6860b6f46a091e28855eb5b6ed48c937aebac..afb7e9d521d2e648a2082fe28ec66b9195183ca7 100644 (file)
@@ -176,19 +176,14 @@ static int create_flat_tables(struct linux_binprm *bprm, unsigned long arg_start
 #define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
 #define RESERVED     0xC0 /* bit 6,7:   reserved */
 
-static int decompress_exec(
-       struct linux_binprm *bprm,
-       unsigned long offset,
-       char *dst,
-       long len,
-       int fd)
+static int decompress_exec(struct linux_binprm *bprm, loff_t fpos, char *dst,
+               long len, int fd)
 {
        unsigned char *buf;
        z_stream strm;
-       loff_t fpos;
        int ret, retval;
 
-       pr_debug("decompress_exec(offset=%lx,buf=%p,len=%lx)\n", offset, dst, len);
+       pr_debug("decompress_exec(offset=%llx,buf=%p,len=%lx)\n", fpos, dst, len);
 
        memset(&strm, 0, sizeof(strm));
        strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
@@ -204,13 +199,11 @@ static int decompress_exec(
        }
 
        /* Read in first chunk of data and parse gzip header. */
-       fpos = offset;
-       ret = kernel_read(bprm->file, offset, buf, LBUFSIZE);
+       ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos);
 
        strm.next_in = buf;
        strm.avail_in = ret;
        strm.total_in = 0;
-       fpos += ret;
 
        retval = -ENOEXEC;
 
@@ -276,7 +269,7 @@ static int decompress_exec(
        }
 
        while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) {
-               ret = kernel_read(bprm->file, fpos, buf, LBUFSIZE);
+               ret = kernel_read(bprm->file, buf, LBUFSIZE, &fpos);
                if (ret <= 0)
                        break;
                len -= ret;
@@ -284,7 +277,6 @@ static int decompress_exec(
                strm.next_in = buf;
                strm.avail_in = ret;
                strm.total_in = 0;
-               fpos += ret;
        }
 
        if (ret < 0) {
index f4718098ac31885b64ebaba7c03af5fe75515092..ce7181ea60fa9af516e2a8774fd1fc2fac38274a 100644 (file)
@@ -218,12 +218,15 @@ static int load_misc_binary(struct linux_binprm *bprm)
 
        bprm->file = interp_file;
        if (fmt->flags & MISC_FMT_CREDENTIALS) {
+               loff_t pos = 0;
+
                /*
                 * No need to call prepare_binprm(), it's already been
                 * done.  bprm->buf is stale, update from interp_file.
                 */
                memset(bprm->buf, 0, BINPRM_BUF_SIZE);
-               retval = kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
+               retval = kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE,
+                               &pos);
        } else
                retval = prepare_binprm(bprm);
 
index c0474ac6cbf200eb458eaf5e3f2359e9b0edfcab..274ab5586dd064a49fba35cad7201be9dc47e84b 100644 (file)
@@ -368,9 +368,10 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx)
                goto out;
 
        while (1) {
+               loff_t pos = ctx->pos - 2;
+
                /* read entries from the directory file */
-               ret = kernel_read(host_file, ctx->pos - 2, (char *)vdir,
-                                 sizeof(*vdir));
+               ret = kernel_read(host_file, vdir, sizeof(*vdir), &pos);
                if (ret < 0) {
                        pr_err("%s: read dir %s failed %d\n",
                               __func__, coda_f2s(&cii->c_fid), ret);
index 039e627194a93b99eca8d20ca483c42598d517ca..d8af0e99bfaf0f3047e9bda854a7689189760b01 100644 (file)
@@ -237,7 +237,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
        lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file;
        if (!lower_file)
                return -EIO;
-       return kernel_read(lower_file, offset, data, size);
+       return kernel_read(lower_file, data, size, &offset);
 }
 
 /**
index 8adcc5eaa175ccdc099164ef0b77d1d9f8d6aa4a..15fb4d56cc4306221728d5a29c878df8cd955140 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -922,8 +922,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 
        pos = 0;
        while (pos < i_size) {
-               bytes = kernel_read(file, pos, (char *)(*buf) + pos,
-                                   i_size - pos);
+               bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
                if (bytes < 0) {
                        ret = bytes;
                        goto out;
@@ -931,7 +930,6 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 
                if (bytes == 0)
                        break;
-               pos += bytes;
        }
 
        if (pos != i_size) {
@@ -1524,6 +1522,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm)
 int prepare_binprm(struct linux_binprm *bprm)
 {
        int retval;
+       loff_t pos = 0;
 
        bprm_fill_uid(bprm);
 
@@ -1534,7 +1533,7 @@ int prepare_binprm(struct linux_binprm *bprm)
        bprm->cred_prepared = 1;
 
        memset(bprm->buf, 0, BINPRM_BUF_SIZE);
-       return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
+       return kernel_read(bprm->file, bprm->buf, BINPRM_BUF_SIZE, &pos);
 }
 
 EXPORT_SYMBOL(prepare_binprm);
index 1ea862bc7efd203532a025b78f955c94cdc016a4..9cf1de855b7ab280d454e1ca29b6d353903f73de 100644 (file)
@@ -415,17 +415,15 @@ ssize_t __vfs_read(struct file *file, char __user *buf, size_t count,
 }
 EXPORT_SYMBOL(__vfs_read);
 
-int kernel_read(struct file *file, loff_t offset, char *addr,
-               unsigned long count)
+ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
 {
        mm_segment_t old_fs;
-       loff_t pos = offset;
-       int result;
+       ssize_t result;
 
        old_fs = get_fs();
        set_fs(get_ds());
        /* The cast to a user pointer is valid due to the set_fs() */
-       result = vfs_read(file, (void __user *)addr, count, &pos);
+       result = vfs_read(file, (void __user *)buf, count, pos);
        set_fs(old_fs);
        return result;
 }
index cbfe127bccf8b112a2d65289a4ec7fef4809da22..2ba8f38a4d632748b290c34f2fe41b78822a5ff7 100644 (file)
@@ -2772,13 +2772,13 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
        return kernel_read_file_str[id];
 }
 
-extern int kernel_read(struct file *, loff_t, char *, unsigned long);
 extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
                            enum kernel_read_file_id);
 extern int kernel_read_file_from_path(char *, void **, loff_t *, loff_t,
                                      enum kernel_read_file_id);
 extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t,
                                    enum kernel_read_file_id);
+extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
 extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
 extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern struct file * open_exec(const char *);
index 02e1859f2ca82e086f0ac73b08c4df07766edede..243fa1c28b4a3ce6be87948404b980ce5ed1aacd 100644 (file)
@@ -986,8 +986,9 @@ static ssize_t bin_intvec(struct file *file,
                size_t length = oldlen / sizeof(*vec);
                char *str, *end;
                int i;
+               loff_t pos = 0;
 
-               result = kernel_read(file, 0, buffer, BUFSZ - 1);
+               result = kernel_read(file, buffer, BUFSZ - 1, &pos);
                if (result < 0)
                        goto out_kfree;
 
@@ -1057,8 +1058,9 @@ static ssize_t bin_ulongvec(struct file *file,
                size_t length = oldlen / sizeof(*vec);
                char *str, *end;
                int i;
+               loff_t pos = 0;
 
-               result = kernel_read(file, 0, buffer, BUFSZ - 1);
+               result = kernel_read(file, buffer, BUFSZ - 1, &pos);
                if (result < 0)
                        goto out_kfree;
 
@@ -1120,8 +1122,9 @@ static ssize_t bin_uuid(struct file *file,
        if (oldval && oldlen) {
                char buf[UUID_STRING_LEN + 1];
                uuid_t uuid;
+               loff_t pos = 0;
 
-               result = kernel_read(file, 0, buf, sizeof(buf) - 1);
+               result = kernel_read(file, buf, sizeof(buf) - 1, &pos);
                if (result < 0)
                        goto out;
 
@@ -1154,8 +1157,9 @@ static ssize_t bin_dn_node_address(struct file *file,
                char buf[15], *nodep;
                unsigned long area, node;
                __le16 dnaddr;
+               loff_t pos = 0;
 
-               result = kernel_read(file, 0, buf, sizeof(buf) - 1);
+               result = kernel_read(file, buf, sizeof(buf) - 1, &pos);
                if (result < 0)
                        goto out;
 
index ddfa86648f957de9eef3d45d8815eb4154b0a7bc..f12815777bebf05f3b9555eeb565c46f1c2c1d90 100644 (file)
@@ -272,6 +272,7 @@ static int p9_fd_read(struct p9_client *client, void *v, int len)
 {
        int ret;
        struct p9_trans_fd *ts = NULL;
+       loff_t pos;
 
        if (client && client->status != Disconnected)
                ts = client->trans;
@@ -282,7 +283,8 @@ static int p9_fd_read(struct p9_client *client, void *v, int len)
        if (!(ts->rd->f_flags & O_NONBLOCK))
                p9_debug(P9_DEBUG_ERROR, "blocking read ...\n");
 
-       ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
+       pos = ts->rd->f_pos;
+       ret = kernel_read(ts->rd, v, len, &pos);
        if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
                client->status = Disconnected;
        return ret;
index 835c1ab30d01eb9a8e94b411fce09b856772efb9..9f4c86cade8ec6432605abcf7469e61ce6fb7700 100644 (file)
@@ -295,6 +295,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
                u8 *data;
                u8 *enckey = (u8 *)key->payload.data[big_key_data];
                size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher));
+               loff_t pos = 0;
 
                data = kmalloc(enclen, GFP_KERNEL);
                if (!data)
@@ -307,7 +308,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen)
                }
 
                /* read file to kernel and decrypt */
-               ret = kernel_read(file, 0, data, enclen);
+               ret = kernel_read(file, data, enclen, &pos);
                if (ret >= 0 && ret != enclen) {
                        ret = -EIO;
                        goto err_fput;