Commit 766fb95ba06e1bbf531d30dc05e21b2d4a0e8dd2

Authored by Sidney Amani
Committed by Artem Bityutskiy
1 parent 36b477d005

UBI: allow direct user-space I/O

Introduce a new ioctl UBI_IOCSETPROP to set properties
on a volume. Also add the first property:
UBI_PROP_DIRECT_WRITE, this property is used to set the
ability to use direct writes in userspace

Signed-off-by: Sidney Amani <seed@uffs.org>
Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>

Showing 4 changed files with 66 additions and 19 deletions Side-by-side Diff

drivers/mtd/ubi/Kconfig.debug
... ... @@ -33,16 +33,6 @@
33 33 This option switches the background thread off by default. The thread
34 34 may be also be enabled/disabled via UBI sysfs.
35 35  
36   -config MTD_UBI_DEBUG_USERSPACE_IO
37   - bool "Direct user-space write/erase support"
38   - default n
39   - depends on MTD_UBI_DEBUG
40   - help
41   - By default, users cannot directly write and erase individual
42   - eraseblocks of dynamic volumes, and have to use update operation
43   - instead. This option enables this capability - it is very useful for
44   - debugging and testing.
45   -
46 36 config MTD_UBI_DEBUG_EMULATE_BITFLIPS
47 37 bool "Emulate flash bit-flips"
48 38 depends on MTD_UBI_DEBUG
drivers/mtd/ubi/cdev.c
... ... @@ -259,12 +259,9 @@
259 259 return err ? err : count_save - count;
260 260 }
261 261  
262   -#ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO
263   -
264 262 /*
265 263 * This function allows to directly write to dynamic UBI volumes, without
266   - * issuing the volume update operation. Available only as a debugging feature.
267   - * Very useful for testing UBI.
  264 + * issuing the volume update operation.
268 265 */
269 266 static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
270 267 size_t count, loff_t *offp)
... ... @@ -276,6 +273,9 @@
276 273 size_t count_save = count;
277 274 char *tbuf;
278 275  
  276 + if (!vol->direct_writes)
  277 + return -EPERM;
  278 +
279 279 dbg_gen("requested: write %zd bytes to offset %lld of volume %u",
280 280 count, *offp, vol->vol_id);
281 281  
... ... @@ -339,10 +339,6 @@
339 339 return err ? err : count_save - count;
340 340 }
341 341  
342   -#else
343   -#define vol_cdev_direct_write(file, buf, count, offp) (-EPERM)
344   -#endif /* CONFIG_MTD_UBI_DEBUG_USERSPACE_IO */
345   -
346 342 static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
347 343 size_t count, loff_t *offp)
348 344 {
... ... @@ -549,6 +545,30 @@
549 545 break;
550 546 }
551 547 err = ubi_is_mapped(desc, lnum);
  548 + break;
  549 + }
  550 +
  551 + /* Set volume property command*/
  552 + case UBI_IOCSETPROP:
  553 + {
  554 + struct ubi_set_prop_req req;
  555 +
  556 + err = copy_from_user(&req, argp,
  557 + sizeof(struct ubi_set_prop_req));
  558 + if (err) {
  559 + err = -EFAULT;
  560 + break;
  561 + }
  562 + switch (req.property) {
  563 + case UBI_PROP_DIRECT_WRITE:
  564 + mutex_lock(&ubi->volumes_mutex);
  565 + desc->vol->direct_writes = !!req.value;
  566 + mutex_unlock(&ubi->volumes_mutex);
  567 + break;
  568 + default:
  569 + err = -EINVAL;
  570 + break;
  571 + }
552 572 break;
553 573 }
554 574  
drivers/mtd/ubi/ubi.h
... ... @@ -206,6 +206,7 @@
206 206 * @upd_marker: %1 if the update marker is set for this volume
207 207 * @updating: %1 if the volume is being updated
208 208 * @changing_leb: %1 if the atomic LEB change ioctl command is in progress
  209 + * @direct_writes: %1 if direct writes are enabled for this volume
209 210 *
210 211 * @gluebi_desc: gluebi UBI volume descriptor
211 212 * @gluebi_refcount: reference count of the gluebi MTD device
... ... @@ -253,6 +254,7 @@
253 254 unsigned int upd_marker:1;
254 255 unsigned int updating:1;
255 256 unsigned int changing_leb:1;
  257 + unsigned int direct_writes:1;
256 258  
257 259 #ifdef CONFIG_MTD_UBI_GLUEBI
258 260 /*
... ... @@ -304,7 +306,8 @@
304 306 * @vtbl_size: size of the volume table in bytes
305 307 * @vtbl: in-RAM volume table copy
306 308 * @volumes_mutex: protects on-flash volume table and serializes volume
307   - * changes, like creation, deletion, update, re-size and re-name
  309 + * changes, like creation, deletion, update, re-size,
  310 + * re-name and set property
308 311 *
309 312 * @max_ec: current highest erase counter value
310 313 * @mean_ec: current mean erase counter value
include/mtd/ubi-user.h
... ... @@ -124,6 +124,14 @@
124 124 * To check if a logical eraseblock is mapped to a physical eraseblock, the
125 125 * %UBI_IOCEBISMAP ioctl command should be used. It returns %0 if the LEB is
126 126 * not mapped, and %1 if it is mapped.
  127 + *
  128 + * Set an UBI volume property
  129 + * ~~~~~~~~~~~~~~~~~~~~~~~~~
  130 + *
  131 + * To set an UBI volume property the %UBI_IOCSETPROP ioctl command should be
  132 + * used. A pointer to a &struct ubi_set_prop_req object is expected to be
  133 + * passed. The object describes which property should be set, and to which value
  134 + * it should be set.
127 135 */
128 136  
129 137 /*
... ... @@ -175,6 +183,8 @@
175 183 #define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, int32_t)
176 184 /* Check if LEB is mapped command */
177 185 #define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, int32_t)
  186 +/* Set an UBI volume property */
  187 +#define UBI_IOCSETPROP _IOW(UBI_VOL_IOC_MAGIC, 6, struct ubi_set_prop_req)
178 188  
179 189 /* Maximum MTD device name length supported by UBI */
180 190 #define MAX_UBI_MTD_NAME_LEN 127
... ... @@ -210,6 +220,16 @@
210 220 UBI_STATIC_VOLUME = 4,
211 221 };
212 222  
  223 +/*
  224 + * UBI set property ioctl constants
  225 + *
  226 + * @UBI_PROP_DIRECT_WRITE: allow / disallow user to directly write and
  227 + * erase individual eraseblocks on dynamic volumes
  228 + */
  229 +enum {
  230 + UBI_PROP_DIRECT_WRITE = 1,
  231 +};
  232 +
213 233 /**
214 234 * struct ubi_attach_req - attach MTD device request.
215 235 * @ubi_num: UBI device number to create
... ... @@ -372,6 +392,20 @@
372 392 int8_t dtype;
373 393 int8_t padding[3];
374 394 } __attribute__ ((packed));
  395 +
  396 +
  397 +/**
  398 + * struct ubi_set_prop_req - a data structure used to set an ubi volume
  399 + * property.
  400 + * @property: property to set (%UBI_PROP_DIRECT_WRITE)
  401 + * @padding: reserved for future, not used, has to be zeroed
  402 + * @value: value to set
  403 + */
  404 +struct ubi_set_prop_req {
  405 + uint8_t property;
  406 + uint8_t padding[7];
  407 + uint64_t value;
  408 +} __attribute__ ((packed));
375 409  
376 410 #endif /* __UBI_USER_H__ */