diff options
-rw-r--r-- | commands/ubi.c | 2 | ||||
-rw-r--r-- | drivers/mtd/ubi/barebox.c | 19 | ||||
-rw-r--r-- | fs/devfs.c | 5 | ||||
-rw-r--r-- | fs/fs.c | 2 | ||||
-rw-r--r-- | include/driver.h | 1 | ||||
-rw-r--r-- | lib/libfile.c | 22 |
6 files changed, 40 insertions, 11 deletions
diff --git a/commands/ubi.c b/commands/ubi.c index 4c445d2216..5e2758400a 100644 --- a/commands/ubi.c +++ b/commands/ubi.c @@ -42,7 +42,7 @@ static int do_ubiupdatevol(int argc, char *argv[]) return 1; } - fd_vol = open(argv[optind], O_WRONLY); + fd_vol = open(argv[optind], O_WRONLY | O_TRUNC); if (fd_vol < 0) { perror("open volume"); ret = 1; diff --git a/drivers/mtd/ubi/barebox.c b/drivers/mtd/ubi/barebox.c index 329cf4564a..d67e566db6 100644 --- a/drivers/mtd/ubi/barebox.c +++ b/drivers/mtd/ubi/barebox.c @@ -162,6 +162,21 @@ static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs) return ofs; } +static int ubi_volume_cdev_truncate(struct cdev *cdev, size_t size) +{ + struct ubi_volume_cdev_priv *priv = cdev->priv; + struct ubi_device *ubi = priv->ubi; + struct ubi_volume *vol = priv->vol; + uint64_t rsvd_bytes; + + rsvd_bytes = (long long)vol->reserved_pebs * + ubi->leb_size - vol->data_pad; + if (size > rsvd_bytes) + return -ENOSPC; + + return 0; +} + static int ubi_volume_cdev_ioctl(struct cdev *cdev, int cmd, void *buf) { struct ubi_volume_cdev_priv *priv = cdev->priv; @@ -210,6 +225,7 @@ static struct file_operations ubi_volume_fops = { .write = ubi_volume_cdev_write, .lseek = ubi_volume_cdev_lseek, .ioctl = ubi_volume_cdev_ioctl, + .truncate = ubi_volume_cdev_truncate, }; int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol) @@ -228,9 +244,6 @@ int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol) cdev->priv = priv; cdev->size = vol->used_bytes; - if (vol->vol_type == UBI_STATIC_VOLUME) - cdev->flags = DEVFS_IS_CHARACTER_DEV; - cdev->dev = &vol->dev; ubi_msg(ubi, "registering %s as /dev/%s", vol->name, cdev->name); ret = devfs_create(cdev); diff --git a/fs/devfs.c b/fs/devfs.c index 6fabcf8ffa..2a7b1b3466 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -168,6 +168,11 @@ static int devfs_ioctl(struct device_d *_dev, FILE *f, int request, void *buf) static int devfs_truncate(struct device_d *dev, FILE *f, ulong 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])) @@ -682,7 +682,7 @@ int open(const char *pathname, int flags, ...) if (ret) goto out; - if (!(s.st_mode & S_IFCHR) && (flags & O_TRUNC)) { + if (flags & O_TRUNC) { ret = fsdrv->truncate(&fsdev->dev, f, 0); f->size = 0; if (ret) diff --git a/include/driver.h b/include/driver.h index 80aa8d821c..6abaaad8b4 100644 --- a/include/driver.h +++ b/include/driver.h @@ -434,6 +434,7 @@ struct file_operations { int (*erase)(struct cdev*, loff_t count, loff_t offset); int (*protect)(struct cdev*, size_t count, loff_t offset, int prot); int (*memmap)(struct cdev*, void **map, int flags); + int (*truncate)(struct cdev*, size_t size); }; #define MAX_PARTUUID_STR sizeof("00112233-4455-6677-8899-AABBCCDDEEFF") diff --git a/lib/libfile.c b/lib/libfile.c index cba2f02a23..049ec32d77 100644 --- a/lib/libfile.c +++ b/lib/libfile.c @@ -263,9 +263,10 @@ int copy_file(const char *src, const char *dst, int verbose) int srcfd = 0, dstfd = 0; int r, w; int ret = 1, err1 = 0; + int mode; void *buf; int total = 0; - struct stat statbuf; + struct stat srcstat, dststat; rw_buf = xmalloc(RW_BUF_SIZE); @@ -275,17 +276,26 @@ int copy_file(const char *src, const char *dst, int verbose) goto out; } - dstfd = open(dst, O_WRONLY | O_CREAT | O_TRUNC); + ret = stat(dst, &dststat); + if (ret) + goto out; + + mode = O_WRONLY | O_CREAT; + + if (S_ISREG(dststat.st_mode)) + mode |= O_TRUNC; + + dstfd = open(dst, mode); if (dstfd < 0) { printf("could not open %s: %s\n", dst, errno_str()); goto out; } if (verbose) { - if (stat(src, &statbuf) < 0) - statbuf.st_size = 0; + if (stat(src, &srcstat) < 0) + srcstat.st_size = 0; - init_progression_bar(statbuf.st_size); + init_progression_bar(srcstat.st_size); } while (1) { @@ -310,7 +320,7 @@ int copy_file(const char *src, const char *dst, int verbose) } if (verbose) { - if (statbuf.st_size && statbuf.st_size != FILESIZE_MAX) + if (srcstat.st_size && srcstat.st_size != FILESIZE_MAX) show_progress(total); else show_progress(total / 16384); |