diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-02-13 20:31:47 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-02-13 20:31:47 +0100 |
commit | 314ad8e28161be580af1271bdaf05a4c6e7f6bd1 (patch) | |
tree | a98f1b35cddef99c60fc255bc1ae5408974fc19f /fs | |
parent | 3fe0effd52c960dc3dce0b731ef266113f2d1893 (diff) | |
parent | 504ac299a531a0bd601e6db05dc1c2d3b86a9700 (diff) | |
download | barebox-314ad8e28161be580af1271bdaf05a4c6e7f6bd1.tar.gz barebox-314ad8e28161be580af1271bdaf05a4c6e7f6bd1.tar.xz |
Merge branch 'for-next/lseek'
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bpkfs.c | 4 | ||||
-rw-r--r-- | fs/cramfs/cramfs.c | 7 | ||||
-rw-r--r-- | fs/devfs-core.c | 52 | ||||
-rw-r--r-- | fs/devfs.c | 22 | ||||
-rw-r--r-- | fs/efi.c | 8 | ||||
-rw-r--r-- | fs/efivarfs.c | 10 | ||||
-rw-r--r-- | fs/ext4/ext_barebox.c | 8 | ||||
-rw-r--r-- | fs/fat/fat.c | 7 | ||||
-rw-r--r-- | fs/fs.c | 40 | ||||
-rw-r--r-- | fs/nfs.c | 7 | ||||
-rw-r--r-- | fs/omap4_usbbootfs.c | 9 | ||||
-rw-r--r-- | fs/pstore/fs.c | 4 | ||||
-rw-r--r-- | fs/ramfs.c | 9 | ||||
-rw-r--r-- | fs/ratpfs.c | 11 | ||||
-rw-r--r-- | fs/smhfs.c | 12 | ||||
-rw-r--r-- | fs/squashfs/squashfs.c | 8 | ||||
-rw-r--r-- | fs/tftp.c | 29 | ||||
-rw-r--r-- | fs/ubifs/ubifs.c | 8 | ||||
-rw-r--r-- | fs/uimagefs.c | 4 |
19 files changed, 99 insertions, 160 deletions
diff --git a/fs/bpkfs.c b/fs/bpkfs.c index f1db963d09..655cde09b7 100644 --- a/fs/bpkfs.c +++ b/fs/bpkfs.c @@ -192,7 +192,7 @@ static int bpkfs_read(struct device_d *dev, FILE *file, void *buf, size_t insize } } -static loff_t bpkfs_lseek(struct device_d *dev, FILE *file, loff_t pos) +static int bpkfs_lseek(struct device_d *dev, FILE *file, loff_t pos) { struct bpkfs_handle_data *d = file->priv; @@ -201,7 +201,7 @@ static loff_t bpkfs_lseek(struct device_d *dev, FILE *file, loff_t pos) d->pos = pos; - return pos; + return 0; } struct somfy_readdir { diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index a3ce354c92..3cc0fa787c 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -166,12 +166,6 @@ static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size) return cramfs_read_file(f->f_inode, f->pos, buf, size); } -static loff_t cramfs_lseek(struct device_d *dev, FILE *f, loff_t pos) -{ - f->pos = pos; - return f->pos; -} - #if 0 static int cramfs_info (struct device_d *dev) { @@ -491,7 +485,6 @@ static void cramfs_remove(struct device_d *dev) static struct fs_driver_d cramfs_driver = { .read = cramfs_read, - .lseek = cramfs_lseek, .drv = { .probe = cramfs_probe, .remove = cramfs_remove, diff --git a/fs/devfs-core.c b/fs/devfs-core.c index f017e1c55d..2b93a951f2 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -459,7 +459,6 @@ static const struct cdev_operations loop_ops = { .read = loop_read, .write = loop_write, .memmap = generic_memmap_rw, - .lseek = dev_lseek_default, }; struct cdev *cdev_create_loop(const char *path, ulong flags, loff_t offset) @@ -512,19 +511,29 @@ void cdev_remove_loop(struct cdev *cdev) free(cdev); } -static void memcpy_sz(void *dst, const void *src, size_t count, int rwsize) +static ssize_t mem_copy(struct device_d *dev, void *dst, const void *src, + resource_size_t count, resource_size_t offset, + unsigned long flags) { + ssize_t size; + int rwsize = flags & O_RWSIZE_MASK; + + if (!dev || dev->num_resources < 1) + return -1; + + count = size = min(count, resource_size(&dev->resource[0]) - offset); + /* no rwsize specification given. Do whatever memcpy likes best */ if (!rwsize) { memcpy(dst, src, count); - return; + goto out; } rwsize = rwsize >> O_RWSIZE_SHIFT; - count /= rwsize; + count = ALIGN_DOWN(count, rwsize); - while (count-- > 0) { + while (count) { switch (rwsize) { case 1: *((u8 *)dst) = *((u8 *)src); @@ -541,41 +550,34 @@ static void memcpy_sz(void *dst, const void *src, size_t count, int rwsize) } dst += rwsize; src += rwsize; + count -= rwsize; } +out: + return size; } ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, unsigned long flags) { - unsigned long size; - struct device_d *dev; + struct device_d *dev = cdev->dev; - if (!cdev->dev || cdev->dev->num_resources < 1) + if (!dev) return -1; - dev = cdev->dev; - size = min((resource_size_t)count, - resource_size(&dev->resource[0]) - - (resource_size_t)offset); - memcpy_sz(buf, dev_get_mem_region(dev, 0) + offset, size, flags & O_RWSIZE_MASK); - return size; + return mem_copy(dev, buf, dev_get_mem_region(dev, 0) + offset, + count, offset, flags); } EXPORT_SYMBOL(mem_read); -ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, - unsigned long flags) +ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, + loff_t offset, unsigned long flags) { - unsigned long size; - struct device_d *dev; + struct device_d *dev = cdev->dev; - if (!cdev->dev || cdev->dev->num_resources < 1) + if (!dev) return -1; - dev = cdev->dev; - size = min((resource_size_t)count, - resource_size(&dev->resource[0]) - - (resource_size_t)offset); - memcpy_sz(dev_get_mem_region(dev, 0) + offset, buf, size, flags & O_RWSIZE_MASK); - return size; + return mem_copy(dev, dev_get_mem_region(dev, 0) + offset, buf, + count, offset, flags); } EXPORT_SYMBOL(mem_write); diff --git a/fs/devfs.c b/fs/devfs.c index 81ae2c25a5..a7400df1c5 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -57,18 +57,18 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s return cdev_write(cdev, buf, size, f->pos, f->flags); } -static loff_t devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos) +static int devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos) { struct cdev *cdev = f->priv; - loff_t ret = -1; + int ret; - if (cdev->ops->lseek) + if (cdev->ops->lseek) { ret = cdev->ops->lseek(cdev, pos + cdev->offset); + if (ret < 0) + return ret; + } - if (ret != -1) - f->pos = pos; - - return ret - cdev->offset; + return 0; } static int devfs_erase(struct device_d *_dev, FILE *f, loff_t count, loff_t offset) @@ -168,18 +168,14 @@ static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf) return cdev_ioctl(cdev, request, buf); } -static int devfs_truncate(struct device_d *dev, FILE *f, ulong size) +static int devfs_truncate(struct device_d *dev, FILE *f, loff_t size) { struct cdev *cdev = f->priv; if (cdev->ops->truncate) return cdev->ops->truncate(cdev, size); - if (f->fsdev->dev.num_resources < 1) - return -ENOSPC; - if (size > resource_size(&f->fsdev->dev.resource[0])) - return -ENOSPC; - return 0; + return -EPERM; } static struct inode *devfs_alloc_inode(struct super_block *sb) @@ -292,22 +292,20 @@ static int efifs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i return bufsize; } -static loff_t efifs_lseek(struct device_d *dev, FILE *f, loff_t pos) +static int efifs_lseek(struct device_d *dev, FILE *f, loff_t pos) { struct efifs_file *ufile = f->priv; efi_status_t efiret; - f->pos = pos; - efiret = ufile->entry->set_position(ufile->entry, pos); if (EFI_ERROR(efiret)) { return -efi_errno(efiret); } - return f->pos; + return 0; } -static int efifs_truncate(struct device_d *dev, FILE *f, unsigned long size) +static int efifs_truncate(struct device_d *dev, FILE *f, loff_t size) { struct efifs_file *ufile = f->priv; efi_status_t efiret; diff --git a/fs/efivarfs.c b/fs/efivarfs.c index bf7351e6db..a911eac3bf 100644 --- a/fs/efivarfs.c +++ b/fs/efivarfs.c @@ -288,7 +288,7 @@ static int efivarfs_write(struct device_d *_dev, FILE *f, const void *buf, size_ return insize; } -static int efivarfs_truncate(struct device_d *dev, FILE *f, ulong size) +static int efivarfs_truncate(struct device_d *dev, FILE *f, loff_t size) { struct efivars_file *efile = f->priv; efi_status_t efiret; @@ -307,13 +307,6 @@ static int efivarfs_truncate(struct device_d *dev, FILE *f, ulong size) return 0; } -static loff_t efivarfs_lseek(struct device_d *dev, FILE *f, loff_t pos) -{ - f->pos = pos; - - return f->pos; -} - static DIR *efivarfs_opendir(struct device_d *dev, const char *pathname) { struct efivarfs_priv *priv = dev->priv; @@ -437,7 +430,6 @@ static struct fs_driver_d efivarfs_driver = { .read = efivarfs_read, .write = efivarfs_write, .truncate = efivarfs_truncate, - .lseek = efivarfs_lseek, .opendir = efivarfs_opendir, .readdir = efivarfs_readdir, .closedir = efivarfs_closedir, diff --git a/fs/ext4/ext_barebox.c b/fs/ext4/ext_barebox.c index 1e7da2a4b4..82d4c581e0 100644 --- a/fs/ext4/ext_barebox.c +++ b/fs/ext4/ext_barebox.c @@ -59,13 +59,6 @@ static int ext_read(struct device_d *_dev, FILE *f, void *buf, size_t insize) return ext4fs_read_file(node, f->pos, insize, buf); } -static loff_t ext_lseek(struct device_d *dev, FILE *f, loff_t pos) -{ - f->pos = pos; - - return f->pos; -} - static struct inode *ext_alloc_inode(struct super_block *sb) { struct fs_device_d *fsdev = container_of(sb, struct fs_device_d, sb); @@ -304,7 +297,6 @@ static void ext_remove(struct device_d *dev) static struct fs_driver_d ext_driver = { .read = ext_read, - .lseek = ext_lseek, .type = filetype_ext, .flags = 0, .drv = { diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 49cd78ff92..394c75ffc4 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -177,7 +177,7 @@ static int fat_write(struct device_d *_dev, FILE *f, const void *buf, size_t ins return outsize; } -static int fat_truncate(struct device_d *dev, FILE *f, ulong size) +static int fat_truncate(struct device_d *dev, FILE *f, loff_t size) { FIL *f_file = f->priv; unsigned long lastofs; @@ -268,7 +268,7 @@ static int fat_read(struct device_d *_dev, FILE *f, void *buf, size_t insize) return outsize; } -static loff_t fat_lseek(struct device_d *dev, FILE *f, loff_t pos) +static int fat_lseek(struct device_d *dev, FILE *f, loff_t pos) { FIL *f_file = f->priv; int ret; @@ -277,8 +277,7 @@ static loff_t fat_lseek(struct device_d *dev, FILE *f, loff_t pos) if (ret) return ret; - f->pos = pos; - return pos; + return 0; } static DIR* fat_opendir(struct device_d *dev, const char *pathname) @@ -213,11 +213,16 @@ int ftruncate(int fd, loff_t length) f = &files[fd]; + if (f->size == FILE_SIZE_STREAM) + return 0; + fsdrv = f->fsdev->driver; ret = fsdrv->truncate(&f->fsdev->dev, f, length); - if (ret) + if (ret) { + errno = -ret; return ret; + } f->size = length; @@ -413,41 +418,36 @@ loff_t lseek(int fildes, loff_t offset, int whence) f = &files[fildes]; fsdrv = f->fsdev->driver; - if (!fsdrv->lseek) { - ret = -ENOSYS; - goto out; - } ret = -EINVAL; switch (whence) { case SEEK_SET: - if (f->size != FILE_SIZE_STREAM && offset > f->size) - goto out; - if (IS_ERR_VALUE(offset)) - goto out; - pos = offset; + pos = 0; break; case SEEK_CUR: - if (f->size != FILE_SIZE_STREAM && offset + f->pos > f->size) - goto out; - pos = f->pos + offset; + pos = f->pos; break; case SEEK_END: - if (offset > 0) - goto out; - pos = f->size + offset; + pos = f->size; break; default: goto out; } - pos = fsdrv->lseek(&f->fsdev->dev, f, pos); - if (IS_ERR_VALUE(pos)) { - errno = -pos; - return -1; + pos += offset; + + if (f->size != FILE_SIZE_STREAM && (pos < 0 || pos > f->size)) + goto out; + + if (fsdrv->lseek) { + ret = fsdrv->lseek(&f->fsdev->dev, f, pos); + if (ret < 0) + goto out; } + f->pos = pos; + return pos; out: @@ -928,7 +928,7 @@ static void nfs_handler(void *ctx, char *packet, unsigned len) nfs_len = len; } -static int nfs_truncate(struct device_d *dev, FILE *f, ulong size) +static int nfs_truncate(struct device_d *dev, FILE *f, loff_t size) { return -ENOSYS; } @@ -1060,14 +1060,13 @@ static int nfs_read(struct device_d *dev, FILE *file, void *buf, size_t insize) return kfifo_get(priv->fifo, buf, insize); } -static loff_t nfs_lseek(struct device_d *dev, FILE *file, loff_t pos) +static int nfs_lseek(struct device_d *dev, FILE *file, loff_t pos) { struct file_priv *priv = file->priv; - file->pos = pos; kfifo_reset(priv->fifo); - return file->pos; + return 0; } static int nfs_iterate(struct file *file, struct dir_context *ctx) diff --git a/fs/omap4_usbbootfs.c b/fs/omap4_usbbootfs.c index b35f411cbb..169cde7ddb 100644 --- a/fs/omap4_usbbootfs.c +++ b/fs/omap4_usbbootfs.c @@ -57,7 +57,7 @@ static int omap4_usbbootfs_write( return -ENOSYS; } -static int omap4_usbbootfs_truncate(struct device_d *dev, FILE *f, ulong size) +static int omap4_usbbootfs_truncate(struct device_d *dev, FILE *f, loff_t size) { return -ENOSYS; } @@ -149,12 +149,6 @@ static int omap4_usbbootfs_read( return size; } -static loff_t omap4_usbbootfs_lseek(struct device_d *dev, FILE *f, loff_t pos) -{ - f->pos = pos; - return pos; -} - static DIR *omap4_usbbootfs_opendir(struct device_d *dev, const char *pathname) { return NULL; @@ -191,7 +185,6 @@ static struct fs_driver_d omap4_usbbootfs_driver = { .open = omap4_usbbootfs_open, .close = omap4_usbbootfs_close, .read = omap4_usbbootfs_read, - .lseek = omap4_usbbootfs_lseek, .opendir = omap4_usbbootfs_opendir, .stat = omap4_usbbootfs_stat, /* diff --git a/fs/pstore/fs.c b/fs/pstore/fs.c index a879a68064..9a7e0b5526 100644 --- a/fs/pstore/fs.c +++ b/fs/pstore/fs.c @@ -172,13 +172,13 @@ static int pstore_read(struct device_d *dev, FILE *file, void *buf, return insize; } -static loff_t pstore_lseek(struct device_d *dev, FILE *file, loff_t pos) +static int pstore_lseek(struct device_d *dev, FILE *file, loff_t pos) { struct pstore_private *d = file->priv; d->pos = pos; - return pos; + return 0; } static DIR *pstore_opendir(struct device_d *dev, const char *pathname) diff --git a/fs/ramfs.c b/fs/ramfs.c index 84ecfa0ddb..4fba40d313 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -347,13 +347,7 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i return insize; } -static loff_t ramfs_lseek(struct device_d *dev, FILE *f, loff_t pos) -{ - f->pos = pos; - return f->pos; -} - -static int ramfs_truncate(struct device_d *dev, FILE *f, ulong size) +static int ramfs_truncate(struct device_d *dev, FILE *f, loff_t size) { struct inode *inode = f->f_inode; struct ramfs_inode *node = to_ramfs_inode(inode); @@ -448,7 +442,6 @@ static void ramfs_remove(struct device_d *dev) static struct fs_driver_d ramfs_driver = { .read = ramfs_read, .write = ramfs_write, - .lseek = ramfs_lseek, .truncate = ramfs_truncate, .flags = FS_DRIVER_NO_DEV, .drv = { diff --git a/fs/ratpfs.c b/fs/ratpfs.c index 902289bab1..b6857c6016 100644 --- a/fs/ratpfs.c +++ b/fs/ratpfs.c @@ -77,7 +77,7 @@ static int ratpfs_rm(struct device_d __always_unused *dev, } static int ratpfs_truncate(struct device_d __always_unused *dev, - FILE *f, ulong size) + FILE *f, loff_t size) { int len_tx = 1 /* type */ + 4 /* handle */ @@ -284,14 +284,6 @@ out: return ret; } -static loff_t ratpfs_lseek(struct device_d __always_unused *dev, - FILE *f, loff_t pos) -{ - pr_debug("%s\n", __func__); - f->pos = pos; - return f->pos; -} - static DIR* ratpfs_opendir(struct device_d __always_unused *dev, const char *pathname) { @@ -450,7 +442,6 @@ static struct fs_driver_d ratpfs_driver = { .open = ratpfs_open, .close = ratpfs_close, .read = ratpfs_read, - .lseek = ratpfs_lseek, .opendir = ratpfs_opendir, .readdir = ratpfs_readdir, .closedir = ratpfs_closedir, diff --git a/fs/smhfs.c b/fs/smhfs.c index f1b6d6bb1b..2e99b05979 100644 --- a/fs/smhfs.c +++ b/fs/smhfs.c @@ -56,7 +56,7 @@ static int smhfs_rm(struct device_d __always_unused *dev, static int smhfs_truncate(struct device_d __always_unused *dev, FILE __always_unused *f, - ulong __always_unused size) + loff_t __always_unused size) { return 0; } @@ -109,15 +109,13 @@ static int smhfs_read(struct device_d __always_unused *dev, return -semihosting_errno(); } -static loff_t smhfs_lseek(struct device_d __always_unused *dev, +static int smhfs_lseek(struct device_d __always_unused *dev, FILE *f, loff_t pos) { - if (semihosting_seek(file_to_fd(f), pos)) { + if (semihosting_seek(file_to_fd(f), pos)) return -semihosting_errno(); - } else { - f->pos = pos; - return f->pos; - } + + return 0; } static DIR* smhfs_opendir(struct device_d __always_unused *dev, diff --git a/fs/squashfs/squashfs.c b/fs/squashfs/squashfs.c index d9049b7523..38aff6d5b8 100644 --- a/fs/squashfs/squashfs.c +++ b/fs/squashfs/squashfs.c @@ -231,13 +231,6 @@ static int squashfs_read(struct device_d *_dev, FILE *f, void *buf, return insize; } -static loff_t squashfs_lseek(struct device_d *dev, FILE *f, loff_t pos) -{ - f->pos = pos; - - return pos; -} - struct squashfs_dir { struct file file; struct dentry dentry; @@ -253,7 +246,6 @@ static struct fs_driver_d squashfs_driver = { .open = squashfs_open, .close = squashfs_close, .read = squashfs_read, - .lseek = squashfs_lseek, .type = filetype_squashfs, .drv = { .probe = squashfs_probe, @@ -93,7 +93,7 @@ struct tftp_priv { IPaddr_t server; }; -static int tftp_truncate(struct device_d *dev, FILE *f, ulong size) +static int tftp_truncate(struct device_d *dev, FILE *f, loff_t size) { return 0; } @@ -573,15 +573,17 @@ static int tftp_read(struct device_d *dev, FILE *f, void *buf, size_t insize) return outsize; } -static loff_t tftp_lseek(struct device_d *dev, FILE *f, loff_t pos) +static int tftp_lseek(struct device_d *dev, FILE *f, loff_t pos) { /* We cannot seek backwards without reloading or caching the file */ - if (pos >= f->pos) { - loff_t ret; + loff_t f_pos = f->pos; + + if (pos >= f_pos) { + int ret = 0; char *buf = xmalloc(1024); - while (pos > f->pos) { - size_t len = min_t(size_t, 1024, pos - f->pos); + while (pos > f_pos) { + size_t len = min_t(size_t, 1024, pos - f_pos); ret = tftp_read(dev, f, buf, len); @@ -591,14 +593,21 @@ static loff_t tftp_lseek(struct device_d *dev, FILE *f, loff_t pos) if (ret < 0) goto out_free; - f->pos += ret; + f_pos += ret; } - ret = pos; - out_free: free(buf); - return ret; + if (ret < 0) { + /* + * Update f->pos even if the overall request + * failed since we can't move backwards + */ + f->pos = f_pos; + return ret; + } + + return 0; } return -ENOSYS; diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 7545dd4c9b..494b1f2614 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -394,13 +394,6 @@ static int ubifs_read(struct device_d *_dev, FILE *f, void *buf, size_t insize) return insize; } -static loff_t ubifs_lseek(struct device_d *dev, FILE *f, loff_t pos) -{ - f->pos = pos; - - return pos; -} - static void ubifs_set_rootarg(struct ubifs_priv *priv, struct fs_device_d *fsdev) { struct ubi_volume_info vi = {}; @@ -477,7 +470,6 @@ static struct fs_driver_d ubifs_driver = { .open = ubifs_open, .close = ubifs_close, .read = ubifs_read, - .lseek = ubifs_lseek, .type = filetype_ubifs, .flags = 0, .drv = { diff --git a/fs/uimagefs.c b/fs/uimagefs.c index c120944a46..e5ada82da8 100644 --- a/fs/uimagefs.c +++ b/fs/uimagefs.c @@ -116,7 +116,7 @@ static int uimagefs_read(struct device_d *dev, FILE *file, void *buf, size_t ins } } -static loff_t uimagefs_lseek(struct device_d *dev, FILE *file, loff_t pos) +static int uimagefs_lseek(struct device_d *dev, FILE *file, loff_t pos) { struct uimagefs_handle_data *d = file->priv; @@ -125,7 +125,7 @@ static loff_t uimagefs_lseek(struct device_d *dev, FILE *file, loff_t pos) d->pos = pos; - return pos; + return 0; } static DIR *uimagefs_opendir(struct device_d *dev, const char *pathname) |