static ssize_t ubi_volume_cdev_write(struct cdev* cdev, const void *buf, size_t size, loff_t offset, unsigned long flags) { struct ubi_volume_cdev_priv *priv = cdev->priv; struct ubi_volume *vol = priv->vol; struct ubi_device *ubi = priv->ubi; int err; if (!priv->written) { err = ubi_start_update(ubi, vol, vol->used_bytes); if (err < 0) { ubi_err("Cannot start volume update\n"); return err; } } err = ubi_more_update_data(ubi, vol, buf, size); if (err < 0) { ubi_err("Couldnt or partially wrote data \n"); return err; } priv->written += size; return size; }
static ssize_t ubi_volume_cdev_write(struct cdev* cdev, const void *buf, size_t size, loff_t offset, unsigned long flags) { struct ubi_volume_cdev_priv *priv = cdev->priv; struct ubi_volume *vol = priv->vol; struct ubi_device *ubi = priv->ubi; int err; if (!priv->written && !vol->updating) { if (vol->vol_type == UBI_STATIC_VOLUME) return -EROFS; err = ubi_start_update(ubi, vol, vol->used_bytes); if (err < 0) { ubi_err(ubi, "Cannot start volume update"); return err; } } err = ubi_more_update_data(ubi, vol, buf, size); if (err < 0) { ubi_err(ubi, "Couldnt or partially wrote data"); return err; } priv->written += size; return size; }
static int ubi_volume_continue_write(char *volume, void *buf, size_t size) { int err = 1; struct ubi_volume *vol; vol = ubi_find_volume(volume); if (vol == NULL) return ENODEV; err = ubi_more_update_data(ubi, vol, buf, size); if (err < 0) { printf("Couldnt or partially wrote data\n"); return -err; } if (err) { size = err; err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return -err; if (err) { ubi_warn(ubi, "volume %d on UBI device %d is corrupt", vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } vol->checked = 1; ubi_gluebi_updated(vol); } return 0; }
static int ubi_volume_write(char *volume, void *buf, size_t size) { int i = 0, err = -1; int rsvd_bytes = 0; int found = 0; struct ubi_volume *vol; for (i = 0; i < ubi->vtbl_slots; i++) { vol = ubi->volumes[i]; if (vol && !strcmp(vol->name, volume)) { printf("Volume \"%s\" found at volume id %d\n", volume, i); found = 1; break; } } if (!found) { printf("%s volume not found\n", volume); return 1; } rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad); if (size < 0 || size > rsvd_bytes) { printf("rsvd_bytes=%d vol->reserved_pebs=%d ubi->leb_size=%d\n", rsvd_bytes, vol->reserved_pebs, ubi->leb_size); printf("vol->data_pad=%d\n", vol->data_pad); printf("Size > volume size !!\n"); return 1; } err = ubi_start_update(ubi, vol, size); if (err < 0) { printf("Cannot start volume update\n"); return err; } err = ubi_more_update_data(ubi, vol, buf, size); if (err < 0) { printf("Couldnt or partially wrote data \n"); return err; } if (err) { size = err; err = ubi_check_volume(ubi, vol->vol_id); if ( err < 0 ) return err; if (err) { ubi_warn("volume %d on UBI device %d is corrupted", vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } vol->checked = 1; ubi_gluebi_updated(vol); } return 0; }
static int ubi_volume_cdev_close(struct cdev *cdev) { struct ubi_volume_cdev_priv *priv = cdev->priv; struct ubi_volume *vol = priv->vol; struct ubi_device *ubi = priv->ubi; int err; if (priv->written) { int remaining = vol->usable_leb_size - (priv->written % vol->usable_leb_size); if (remaining && vol->vol_type == UBI_DYNAMIC_VOLUME) { void *buf = kmalloc(remaining, GFP_KERNEL); if (!buf) return -ENOMEM; memset(buf, 0xff, remaining); err = ubi_more_update_data(ubi, vol, buf, remaining); kfree(buf); if (err < 0) { ubi_err(ubi, "Couldnt or partially wrote data"); return err; } } if (vol->vol_type == UBI_STATIC_VOLUME) cdev->size = priv->written; err = ubi_finish_update(ubi, vol); if (err) return err; err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) { ubi_err(ubi, "ubi volume check failed: %s", strerror(err)); return err; } if (err) { ubi_warn(ubi, "volume %d on UBI device %d is corrupted", vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } vol->checked = 1; ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED); } return 0; }
static int ubi_volume_write(char *volume, void *buf, size_t size) { int err = 1; int rsvd_bytes = 0; struct ubi_volume *vol; vol = ubi_find_volume(volume); if (vol == NULL) return ENODEV; rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad); if (size < 0 || size > rsvd_bytes) { printf("size > volume size! Aborting!\n"); return EINVAL; } if (!strncmp(vol->name, "Factory", 7) && (!size || size != rsvd_bytes)) { printf("Partial write to volume %s is inhibited\n", vol->name); return EROFS; } err = ubi_start_update(ubi, vol, size); if (err < 0) { printf("Cannot start volume update\n"); return -err; } err = ubi_more_update_data(ubi, vol, buf, size); if (err < 0) { printf("Couldnt or partially wrote data\n"); return -err; } if (err) { size = err; err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return -err; if (err) { ubi_warn("volume %d on UBI device %d is corrupted", vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } vol->checked = 1; ubi_gluebi_updated(vol); } printf("\n0x%x bytes written to volume %s\n", size, volume); return 0; }
static ssize_t vol_cdev_write(struct file *file, const char __user *buf, size_t count, loff_t *offp) { int err = 0; struct ubi_volume_desc *desc = file->private_data; struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; if (!vol->updating && !vol->changing_leb) return vol_cdev_direct_write(file, buf, count, offp); if (vol->updating) err = ubi_more_update_data(ubi, vol, buf, count); else err = ubi_more_leb_change_data(ubi, vol, buf, count); if (err < 0) { ubi_err("cannot accept more %zd bytes of data, error %d", count, err); return err; } if (err) { /* * The operation is finished, @err contains number of actually * written bytes. */ count = err; if (vol->changing_leb) { revoke_exclusive(desc, UBI_READWRITE); return count; } err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return err; if (err) { ubi_warn("volume %d on UBI device %d is corrupted", vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } vol->checked = 1; ubi_gluebi_updated(vol); revoke_exclusive(desc, UBI_READWRITE); } return count; }
static ssize_t vol_cdev_write(struct file *file, const char __user *buf, size_t count, loff_t *offp) { int err = 0; struct ubi_volume_desc *desc = file->private_data; struct ubi_volume *vol = desc->vol; struct ubi_device *ubi = vol->ubi; if (!vol->updating) return vol_cdev_direct_write(file, buf, count, offp); err = ubi_more_update_data(ubi, vol->vol_id, buf, count); if (err < 0) { ubi_err("cannot write %zd bytes of update data", count); return err; } if (err) { /* * Update is finished, @err contains number of actually written * bytes now. */ count = err; err = ubi_check_volume(ubi, vol->vol_id); if (err < 0) return err; if (err) { ubi_warn("volume %d on UBI device %d is corrupted", vol->vol_id, ubi->ubi_num); vol->corrupted = 1; } vol->checked = 1; ubi_gluebi_updated(vol); revoke_exclusive(desc, UBI_READWRITE); } *offp += count; return count; }