/*
- * Copyright (c) International Business Machines Corp., 2006
+ * Copyright © International Business Machines Corp., 2006
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* ~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To set an UBI volume property the %UBI_IOCSETPROP ioctl command should be
- * used. A pointer to a &struct ubi_set_prop_req object is expected to be
+ * used. A pointer to a &struct ubi_set_vol_prop_req object is expected to be
* passed. The object describes which property should be set, and to which value
* it should be set.
*/
/* Check if LEB is mapped command */
#define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, int32_t)
/* Set an UBI volume property */
-#define UBI_IOCSETPROP _IOW(UBI_VOL_IOC_MAGIC, 6, struct ubi_set_prop_req)
+#define UBI_IOCSETVOLPROP _IOW(UBI_VOL_IOC_MAGIC, 6, \
+ struct ubi_set_vol_prop_req)
/* Maximum MTD device name length supported by UBI */
#define MAX_UBI_MTD_NAME_LEN 127
/* Maximum amount of UBI volumes that can be re-named at one go */
#define UBI_MAX_RNVOL 32
-/*
- * UBI data type hint constants.
- *
- * UBI_LONGTERM: long-term data
- * UBI_SHORTTERM: short-term data
- * UBI_UNKNOWN: data persistence is unknown
- *
- * These constants are used when data is written to UBI volumes in order to
- * help the UBI wear-leveling unit to find more appropriate physical
- * eraseblocks.
- */
-enum {
- UBI_LONGTERM = 1,
- UBI_SHORTTERM = 2,
- UBI_UNKNOWN = 3,
-};
-
/*
* UBI volume type constants.
*
};
/*
- * UBI set property ioctl constants
+ * UBI set volume property ioctl constants.
*
- * @UBI_PROP_DIRECT_WRITE: allow / disallow user to directly write and
- * erase individual eraseblocks on dynamic volumes
+ * @UBI_VOL_PROP_DIRECT_WRITE: allow (any non-zero value) or disallow (value 0)
+ * user to directly write and erase individual
+ * eraseblocks on dynamic volumes
*/
enum {
- UBI_PROP_DIRECT_WRITE = 1,
+ UBI_VOL_PROP_DIRECT_WRITE = 1,
};
/**
int16_t name_len;
int8_t padding2[4];
char name[UBI_MAX_VOLUME_NAME + 1];
-} __attribute__ ((packed));
+} __attribute__((packed));
/**
* struct ubi_rsvol_req - a data structure used in volume re-size requests.
struct ubi_rsvol_req {
int64_t bytes;
int32_t vol_id;
-} __attribute__ ((packed));
+} __attribute__((packed));
/**
* struct ubi_rnvol_req - volumes re-name request.
int8_t padding2[2];
char name[UBI_MAX_VOLUME_NAME + 1];
} ents[UBI_MAX_RNVOL];
-} __attribute__ ((packed));
+} __attribute__((packed));
/**
* struct ubi_leb_change_req - a data structure used in atomic LEB change
* requests.
* @lnum: logical eraseblock number to change
* @bytes: how many bytes will be written to the logical eraseblock
- * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
+ * @dtype: pass "3" for better compatibility with old kernels
* @padding: reserved for future, not used, has to be zeroed
+ *
+ * The @dtype field used to inform UBI about what kind of data will be written
+ * to the LEB: long term (value 1), short term (value 2), unknown (value 3).
+ * UBI tried to pick a PEB with lower erase counter for short term data and a
+ * PEB with higher erase counter for long term data. But this was not really
+ * used because users usually do not know this and could easily mislead UBI. We
+ * removed this feature in May 2012. UBI currently just ignores the @dtype
+ * field. But for better compatibility with older kernels it is recommended to
+ * set @dtype to 3 (unknown).
*/
struct ubi_leb_change_req {
int32_t lnum;
int32_t bytes;
- int8_t dtype;
+ int8_t dtype; /* obsolete, do not use! */
int8_t padding[7];
-} __attribute__ ((packed));
+} __attribute__((packed));
/**
* struct ubi_map_req - a data structure used in map LEB requests.
+ * @dtype: pass "3" for better compatibility with old kernels
* @lnum: logical eraseblock number to unmap
- * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
* @padding: reserved for future, not used, has to be zeroed
*/
struct ubi_map_req {
int32_t lnum;
- int8_t dtype;
+ int8_t dtype; /* obsolete, do not use! */
int8_t padding[3];
-} __attribute__ ((packed));
+} __attribute__((packed));
/**
- * struct ubi_set_prop_req - a data structure used to set an ubi volume
- * property.
- * @property: property to set (%UBI_PROP_DIRECT_WRITE)
+ * struct ubi_set_vol_prop_req - a data structure used to set an UBI volume
+ * property.
+ * @property: property to set (%UBI_VOL_PROP_DIRECT_WRITE)
* @padding: reserved for future, not used, has to be zeroed
* @value: value to set
*/
-struct ubi_set_prop_req {
- uint8_t property;
- uint8_t padding[7];
- uint64_t value;
-} __attribute__ ((packed));
+struct ubi_set_vol_prop_req {
+ uint8_t property;
+ uint8_t padding[7];
+ uint64_t value;
+} __attribute__((packed));
#endif /* __UBI_USER_H__ */
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
- err = write_leb(lnum++, alen, buf, UBI_SHORTTERM);
+ err = write_leb(lnum++, alen, buf);
if (err)
goto out;
p = buf;
set_ltab(c, lnum, c->leb_size - alen,
alen - len);
memset(p, 0xff, alen - len);
- err = write_leb(lnum++, alen, buf, UBI_SHORTTERM);
+ err = write_leb(lnum++, alen, buf);
if (err)
goto out;
p = buf;
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
- err = write_leb(lnum++, alen, buf, UBI_SHORTTERM);
+ err = write_leb(lnum++, alen, buf);
if (err)
goto out;
p = buf;
alen = ALIGN(len, c->min_io_size);
set_ltab(c, lnum, c->leb_size - alen, alen - len);
memset(p, 0xff, alen - len);
- err = write_leb(lnum++, alen, buf, UBI_SHORTTERM);
+ err = write_leb(lnum++, alen, buf);
if (err)
goto out;
p = buf;
/* Write remaining buffer */
memset(p, 0xff, alen - len);
- err = write_leb(lnum, alen, buf, UBI_SHORTTERM);
+ err = write_leb(lnum, alen, buf);
if (err)
goto out;
* @lnum: LEB number
* @len: length of data in the buffer
* @buf: buffer (must be at least c->leb_size bytes)
- * @dtype: expected data type
*/
-int write_leb(int lnum, int len, void *buf, int dtype)
+int write_leb(int lnum, int len, void *buf)
{
off64_t pos = (off64_t)lnum * c->leb_size;
dbg_msg(3, "LEB %d len %d", lnum, len);
memset(buf + len, 0xff, c->leb_size - len);
if (out_ubi)
- if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size, dtype))
+ if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size))
return sys_err_msg("ubi_leb_change_start failed");
if (lseek64(out_fd, pos, SEEK_SET) != pos)
/**
* write_empty_leb - copy the image of an empty LEB to the output target.
* @lnum: LEB number
- * @dtype: expected data type
*/
-static int write_empty_leb(int lnum, int dtype)
+static int write_empty_leb(int lnum)
{
- return write_leb(lnum, 0, leb_buf, dtype);
+ return write_leb(lnum, 0, leb_buf);
}
/**
* @node: node
* @len: node length
* @lnum: LEB number
- * @dtype: expected data type
*/
-static int write_node(void *node, int len, int lnum, int dtype)
+static int write_node(void *node, int len, int lnum)
{
prepare_node(node, len);
len = do_pad(leb_buf, len);
- return write_leb(lnum, len, leb_buf, dtype);
+ return write_leb(lnum, len, leb_buf);
}
/**
if (!head_offs)
return 0;
len = do_pad(leb_buf, head_offs);
- err = write_leb(head_lnum, len, leb_buf, UBI_UNKNOWN);
+ err = write_leb(head_lnum, len, leb_buf);
if (err)
return err;
set_lprops(head_lnum, head_offs, head_flags);
int err;
c->gc_lnum = head_lnum++;
- err = write_empty_leb(c->gc_lnum, UBI_LONGTERM);
+ err = write_empty_leb(c->gc_lnum);
if (err)
return err;
set_lprops(c->gc_lnum, 0, 0);
if (c->space_fixup)
sup.flags |= cpu_to_le32(UBIFS_FLG_SPACE_FIXUP);
- return write_node(&sup, UBIFS_SB_NODE_SZ, UBIFS_SB_LNUM, UBI_LONGTERM);
+ return write_node(&sup, UBIFS_SB_NODE_SZ, UBIFS_SB_LNUM);
}
/**
mst.total_dark = cpu_to_le64(c->lst.total_dark);
mst.leb_cnt = cpu_to_le32(c->leb_cnt);
- err = write_node(&mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM,
- UBI_SHORTTERM);
+ err = write_node(&mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM);
if (err)
return err;
- err = write_node(&mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1,
- UBI_SHORTTERM);
+ err = write_node(&mst, UBIFS_MST_NODE_SZ, UBIFS_MST_LNUM + 1);
if (err)
return err;
cs.ch.node_type = UBIFS_CS_NODE;
cs.cmt_no = cpu_to_le64(0);
- err = write_node(&cs, UBIFS_CS_NODE_SZ, lnum, UBI_UNKNOWN);
+ err = write_node(&cs, UBIFS_CS_NODE_SZ, lnum);
if (err)
return err;
lnum += 1;
for (i = 1; i < c->log_lebs; i++, lnum++) {
- err = write_empty_leb(lnum, UBI_UNKNOWN);
+ err = write_empty_leb(lnum);
if (err)
return err;
}
lnum = c->nhead_lnum + 1;
while (lnum <= c->lpt_last) {
- err = write_empty_leb(lnum++, UBI_SHORTTERM);
+ err = write_empty_leb(lnum++);
if (err)
return err;
}
lnum = UBIFS_LOG_LNUM + c->log_lebs + c->lpt_lebs;
for (i = 0; i < c->orph_lebs; i++, lnum++) {
- err = write_empty_leb(lnum, UBI_SHORTTERM);
+ err = write_empty_leb(lnum);
if (err)
return err;
}
if (out_fd == -1)
return sys_err_msg("cannot open the UBI volume '%s'",
output);
- if (ubi_set_property(out_fd, UBI_PROP_DIRECT_WRITE, 1))
+ if (ubi_set_property(out_fd, UBI_VOL_PROP_DIRECT_WRITE, 1))
return sys_err_msg("ubi_set_property failed");
if (check_volume_empty())
struct hashtable_itr;
-int write_leb(int lnum, int len, void *buf, int dtype);
+int write_leb(int lnum, int len, void *buf);
int parse_devtable(const char *tbl_file);
struct path_htbl_element *devtbl_find_path(const char *path);
struct name_htbl_element *devtbl_find_name(struct path_htbl_element *ph_elt,
return NULL;
}
- ret = ubi_set_property(fd, UBI_PROP_DIRECT_WRITE, 1);
+ ret = ubi_set_property(fd, UBI_VOL_PROP_DIRECT_WRITE, 1);
if (ret) {
failed("ubi_set_property");
errmsg("cannot set property for \"%s\"\n", vol_node);
* @fd: volume character device file descriptor
* @lnum: LEB number to change
* @bytes: how many bytes of new data will be written to the LEB
- * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN)
*
* This function initiates atomic LEB change operation and returns %0 in case
* of success and %-1 in case of error. he caller is assumed to write @bytes
* data to the volume @fd afterward.
*/
-int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes, int dtype);
+int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes);
/**
* ubi_set_property - set volume propety.
* @fd: volume character device file descriptor
- * @property: the property to change (%UBI_PROP_DIRECT_WRITE, etc)
+ * @property: the property to change (%UBI_VOL_PROP_DIRECT_WRITE, etc)
* @value: new value of the changed property
*
* This function changes a property of a volume. Returns zero in case of
return 0;
}
-int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes, int dtype)
+int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes)
{
struct ubi_leb_change_req req;
memset(&req, 0, sizeof(struct ubi_leb_change_req));
req.lnum = lnum;
req.bytes = bytes;
- req.dtype = dtype;
+ req.dtype = 3;
if (ioctl(fd, UBI_IOCEBCH, &req))
return -1;
int ubi_set_property(int fd, uint8_t property, uint64_t value)
{
- struct ubi_set_prop_req r;
+ struct ubi_set_vol_prop_req r;
- memset(&r, 0, sizeof(struct ubi_set_prop_req));
+ memset(&r, 0, sizeof(struct ubi_set_vol_prop_req));
r.property = property;
r.value = value;
- return ioctl(fd, UBI_IOCSETPROP, &r);
+ return ioctl(fd, UBI_IOCSETVOLPROP, &r);
}
int ubi_leb_unmap(int fd, int lnum)