This pull request contains updates for both UBI and UBIFS:

- Year 2038 preparations
 - New UBI feature to skip CRC checks of static volumes
 - A new Kconfig option to disable xattrs in UBIFS
 - Lots of fixes in UBIFS, found by our new test framework
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAlt9zFkWHHJpY2hhcmRA
 c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7waiuD/oDYzerOLe0R7n2sRT9zjtY8kCx
 LuizRvDYUlmMynI6EVahfyJy2IixcDmXOklGdxJqUkN5igDC/FORWdQjv2X9y56d
 qZ2dlS8aBvI0ZKBG2ew4VP1H67CXtCw8H9fE32SGotPmxKRUQqt2vKqo+vgQfapH
 eSVPrOaoqoRh+/ieumYXsvFdEUWpa66G3tVMFe4znu+kYRBbGzSszxpuq1ukIls2
 P9wewqbWAZpqn+n9A9+RBIv81g+jH87/acfjK2L7/lT9wsFO7BQGKi373dPbnTa5
 9WsjGEd+Gt0kb4Kjh5QegY97bPqWjmaMj1BLqeQVpSbQqpzkiFMf9GW5+h3XqAfO
 hM1zzgONZMxHdZSKH0bWzIRQbvU6v0d9C4J/elfFuH9ke2XscrxjOtZZQbtbGeYj
 tE7FWoZnB8euXubulGAUBKofzWe+gItBe9+iA29EBETNOemrJyHyKjO0Fe9ze5p2
 bfVFvN62kHz4ZCJoinwO/OpXnCuA91xrVocLOOIreb4dkZ/kqP+YZWFf70FcE1o5
 sPAbAUu+hfb2LbpktEdZHHbhoupfCnJokzfboJMX0NWKRtFXJDONjogJYTFUjrpW
 eXS+55+WFHoLWtx9J2IVmcb3cQrj/W/4J83kSg99cUkVjGpil50zmtzhq9bHzsLc
 wazngueP7kW2l9bSSg==
 =gCyp
 -----END PGP SIGNATURE-----

Merge tag 'upstream-4.19-rc1' of git://git.infradead.org/linux-ubifs

Pull UBI/UBIFS updates from Richard Weinberger:

 - Year 2038 preparations

 - New UBI feature to skip CRC checks of static volumes

 - A new Kconfig option to disable xattrs in UBIFS

 - Lots of fixes in UBIFS, found by our new test framework

* tag 'upstream-4.19-rc1' of git://git.infradead.org/linux-ubifs: (21 commits)
  ubifs: Set default assert action to read-only
  ubifs: Allow setting assert action as mount parameter
  ubifs: Rework ubifs_assert()
  ubifs: Pass struct ubifs_info to ubifs_assert()
  ubifs: Turn two ubifs_assert() into a WARN_ON()
  ubi: expose the volume CRC check skip flag
  ubi: provide a way to skip CRC checks
  ubifs: Use kmalloc_array()
  ubifs: Check data node size before truncate
  Revert "UBIFS: Fix potential integer overflow in allocation"
  ubifs: Add comment on c->commit_sem
  ubifs: introduce Kconfig symbol for xattr support
  ubifs: use swap macro in swap_dirty_idx
  ubifs: tnc: use monotonic znode timestamp
  ubifs: use timespec64 for inode timestamps
  ubifs: xattr: Don't operate on deleted inodes
  ubifs: gc: Fix typo
  ubifs: Fix memory leak in lprobs self-check
  ubi: Initialize Fastmap checkmapping correctly
  ubifs: Fix synced_i_size calculation for xattr inodes
  ...
This commit is contained in:
Linus Torvalds 2018-08-23 15:58:04 -07:00
commit 6f7948f566
41 changed files with 787 additions and 571 deletions

View File

@ -367,6 +367,10 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
return count; return count;
} }
/*
* We voluntarily do not take into account the skip_check flag
* as we want to make sure what we wrote was correctly written.
*/
err = ubi_check_volume(ubi, vol->vol_id); err = ubi_check_volume(ubi, vol->vol_id);
if (err < 0) if (err < 0)
return err; return err;
@ -622,6 +626,13 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
req->vol_type != UBI_STATIC_VOLUME) req->vol_type != UBI_STATIC_VOLUME)
goto bad; goto bad;
if (req->flags & ~UBI_VOL_VALID_FLGS)
goto bad;
if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG &&
req->vol_type != UBI_STATIC_VOLUME)
goto bad;
if (req->alignment > ubi->leb_size) if (req->alignment > ubi->leb_size)
goto bad; goto bad;

View File

@ -202,7 +202,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
desc->mode = mode; desc->mode = mode;
mutex_lock(&ubi->ckvol_mutex); mutex_lock(&ubi->ckvol_mutex);
if (!vol->checked) { if (!vol->checked && !vol->skip_check) {
/* This is the first open - check the volume */ /* This is the first open - check the volume */
err = ubi_check_volume(ubi, vol_id); err = ubi_check_volume(ubi, vol_id);
if (err < 0) { if (err < 0) {

View File

@ -45,6 +45,11 @@ enum {
* Volume flags used in the volume table record. * Volume flags used in the volume table record.
* *
* @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume * @UBI_VTBL_AUTORESIZE_FLG: auto-resize this volume
* @UBI_VTBL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
* open time. Should only be set on volumes that
* are used by upper layers doing this kind of
* check. Main use-case for this flag is
* boot-time reduction
* *
* %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume * %UBI_VTBL_AUTORESIZE_FLG flag can be set only for one volume in the volume
* table. UBI automatically re-sizes the volume which has this flag and makes * table. UBI automatically re-sizes the volume which has this flag and makes
@ -76,6 +81,7 @@ enum {
*/ */
enum { enum {
UBI_VTBL_AUTORESIZE_FLG = 0x01, UBI_VTBL_AUTORESIZE_FLG = 0x01,
UBI_VTBL_SKIP_CRC_CHECK_FLG = 0x02,
}; };
/* /*

View File

@ -327,6 +327,9 @@ struct ubi_eba_leb_desc {
* atomic LEB change * atomic LEB change
* *
* @eba_tbl: EBA table of this volume (LEB->PEB mapping) * @eba_tbl: EBA table of this volume (LEB->PEB mapping)
* @skip_check: %1 if CRC check of this static volume should be skipped.
* Directly reflects the presence of the
* %UBI_VTBL_SKIP_CRC_CHECK_FLG flag in the vtbl entry
* @checked: %1 if this static volume was checked * @checked: %1 if this static volume was checked
* @corrupted: %1 if the volume is corrupted (static volumes only) * @corrupted: %1 if the volume is corrupted (static volumes only)
* @upd_marker: %1 if the update marker is set for this volume * @upd_marker: %1 if the update marker is set for this volume
@ -374,6 +377,7 @@ struct ubi_volume {
void *upd_buf; void *upd_buf;
struct ubi_eba_table *eba_tbl; struct ubi_eba_table *eba_tbl;
unsigned int skip_check:1;
unsigned int checked:1; unsigned int checked:1;
unsigned int corrupted:1; unsigned int corrupted:1;
unsigned int upd_marker:1; unsigned int upd_marker:1;

View File

@ -174,6 +174,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vol->dev.class = &ubi_class; vol->dev.class = &ubi_class;
vol->dev.groups = volume_dev_groups; vol->dev.groups = volume_dev_groups;
if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG)
vol->skip_check = 1;
spin_lock(&ubi->volumes_lock); spin_lock(&ubi->volumes_lock);
if (vol_id == UBI_VOL_NUM_AUTO) { if (vol_id == UBI_VOL_NUM_AUTO) {
/* Find unused volume ID */ /* Find unused volume ID */
@ -299,6 +302,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vtbl_rec.vol_type = UBI_VID_DYNAMIC; vtbl_rec.vol_type = UBI_VID_DYNAMIC;
else else
vtbl_rec.vol_type = UBI_VID_STATIC; vtbl_rec.vol_type = UBI_VID_STATIC;
if (vol->skip_check)
vtbl_rec.flags |= UBI_VTBL_SKIP_CRC_CHECK_FLG;
memcpy(vtbl_rec.name, vol->name, vol->name_len); memcpy(vtbl_rec.name, vol->name, vol->name_len);
err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
@ -733,6 +740,11 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
ubi_err(ubi, "bad used_bytes"); ubi_err(ubi, "bad used_bytes");
goto fail; goto fail;
} }
if (vol->skip_check) {
ubi_err(ubi, "bad skip_check");
goto fail;
}
} else { } else {
if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) { if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
ubi_err(ubi, "bad used_ebs"); ubi_err(ubi, "bad used_ebs");

View File

@ -560,6 +560,9 @@ static int init_volumes(struct ubi_device *ubi,
vol->name[vol->name_len] = '\0'; vol->name[vol->name_len] = '\0';
vol->vol_id = i; vol->vol_id = i;
if (vtbl[i].flags & UBI_VTBL_SKIP_CRC_CHECK_FLG)
vol->skip_check = 1;
if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) { if (vtbl[i].flags & UBI_VTBL_AUTORESIZE_FLG) {
/* Auto re-size flag may be set only for one volume */ /* Auto re-size flag may be set only for one volume */
if (ubi->autoresize_vol_id != -1) { if (ubi->autoresize_vol_id != -1) {
@ -578,6 +581,16 @@ static int init_volumes(struct ubi_device *ubi,
vol->ubi = ubi; vol->ubi = ubi;
reserved_pebs += vol->reserved_pebs; reserved_pebs += vol->reserved_pebs;
/*
* We use ubi->peb_count and not vol->reserved_pebs because
* we want to keep the code simple. Otherwise we'd have to
* resize/check the bitmap upon volume resize too.
* Allocating a few bytes more does not hurt.
*/
err = ubi_fastmap_init_checkmap(vol, ubi->peb_count);
if (err)
return err;
/* /*
* In case of dynamic volume UBI knows nothing about how many * In case of dynamic volume UBI knows nothing about how many
* data is stored there. So assume the whole volume is used. * data is stored there. So assume the whole volume is used.
@ -620,16 +633,6 @@ static int init_volumes(struct ubi_device *ubi,
(long long)(vol->used_ebs - 1) * vol->usable_leb_size; (long long)(vol->used_ebs - 1) * vol->usable_leb_size;
vol->used_bytes += av->last_data_size; vol->used_bytes += av->last_data_size;
vol->last_eb_bytes = av->last_data_size; vol->last_eb_bytes = av->last_data_size;
/*
* We use ubi->peb_count and not vol->reserved_pebs because
* we want to keep the code simple. Otherwise we'd have to
* resize/check the bitmap upon volume resize too.
* Allocating a few bytes more does not hurt.
*/
err = ubi_fastmap_init_checkmap(vol, ubi->peb_count);
if (err)
return err;
} }
/* And add the layout volume */ /* And add the layout volume */

View File

@ -51,9 +51,20 @@ config UBIFS_ATIME_SUPPORT
If unsure, say 'N' If unsure, say 'N'
config UBIFS_FS_XATTR
bool "UBIFS XATTR support"
depends on UBIFS_FS
default y
help
Saying Y here includes support for extended attributes (xattrs).
Xattrs are name:value pairs associated with inodes by
the kernel or by users (see the attr(5) manual page).
If unsure, say Y.
config UBIFS_FS_ENCRYPTION config UBIFS_FS_ENCRYPTION
bool "UBIFS Encryption" bool "UBIFS Encryption"
depends on UBIFS_FS && BLOCK depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
select FS_ENCRYPTION select FS_ENCRYPTION
default n default n
help help
@ -64,7 +75,7 @@ config UBIFS_FS_ENCRYPTION
config UBIFS_FS_SECURITY config UBIFS_FS_SECURITY
bool "UBIFS Security Labels" bool "UBIFS Security Labels"
depends on UBIFS_FS depends on UBIFS_FS && UBIFS_FS_XATTR
default y default y
help help
Security labels provide an access control facility to support Linux Security labels provide an access control facility to support Linux

View File

@ -4,6 +4,7 @@ obj-$(CONFIG_UBIFS_FS) += ubifs.o
ubifs-y += shrinker.o journal.o file.o dir.o super.o sb.o io.o ubifs-y += shrinker.o journal.o file.o dir.o super.o sb.o io.o
ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o
ubifs-y += misc.o ubifs-y += misc.o
ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o
ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o

View File

@ -439,16 +439,16 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
{ {
int err, idx_growth, data_growth, dd_growth, retried = 0; int err, idx_growth, data_growth, dd_growth, retried = 0;
ubifs_assert(req->new_page <= 1); ubifs_assert(c, req->new_page <= 1);
ubifs_assert(req->dirtied_page <= 1); ubifs_assert(c, req->dirtied_page <= 1);
ubifs_assert(req->new_dent <= 1); ubifs_assert(c, req->new_dent <= 1);
ubifs_assert(req->mod_dent <= 1); ubifs_assert(c, req->mod_dent <= 1);
ubifs_assert(req->new_ino <= 1); ubifs_assert(c, req->new_ino <= 1);
ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA); ubifs_assert(c, req->new_ino_d <= UBIFS_MAX_INO_DATA);
ubifs_assert(req->dirtied_ino <= 4); ubifs_assert(c, req->dirtied_ino <= 4);
ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); ubifs_assert(c, req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
ubifs_assert(!(req->new_ino_d & 7)); ubifs_assert(c, !(req->new_ino_d & 7));
ubifs_assert(!(req->dirtied_ino_d & 7)); ubifs_assert(c, !(req->dirtied_ino_d & 7));
data_growth = calc_data_growth(c, req); data_growth = calc_data_growth(c, req);
dd_growth = calc_dd_growth(c, req); dd_growth = calc_dd_growth(c, req);
@ -458,9 +458,9 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req)
again: again:
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
ubifs_assert(c->bi.idx_growth >= 0); ubifs_assert(c, c->bi.idx_growth >= 0);
ubifs_assert(c->bi.data_growth >= 0); ubifs_assert(c, c->bi.data_growth >= 0);
ubifs_assert(c->bi.dd_growth >= 0); ubifs_assert(c, c->bi.dd_growth >= 0);
if (unlikely(c->bi.nospace) && (c->bi.nospace_rp || !can_use_rp(c))) { if (unlikely(c->bi.nospace) && (c->bi.nospace_rp || !can_use_rp(c))) {
dbg_budg("no space"); dbg_budg("no space");
@ -526,20 +526,20 @@ again:
*/ */
void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req) void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
{ {
ubifs_assert(req->new_page <= 1); ubifs_assert(c, req->new_page <= 1);
ubifs_assert(req->dirtied_page <= 1); ubifs_assert(c, req->dirtied_page <= 1);
ubifs_assert(req->new_dent <= 1); ubifs_assert(c, req->new_dent <= 1);
ubifs_assert(req->mod_dent <= 1); ubifs_assert(c, req->mod_dent <= 1);
ubifs_assert(req->new_ino <= 1); ubifs_assert(c, req->new_ino <= 1);
ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA); ubifs_assert(c, req->new_ino_d <= UBIFS_MAX_INO_DATA);
ubifs_assert(req->dirtied_ino <= 4); ubifs_assert(c, req->dirtied_ino <= 4);
ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); ubifs_assert(c, req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
ubifs_assert(!(req->new_ino_d & 7)); ubifs_assert(c, !(req->new_ino_d & 7));
ubifs_assert(!(req->dirtied_ino_d & 7)); ubifs_assert(c, !(req->dirtied_ino_d & 7));
if (!req->recalculate) { if (!req->recalculate) {
ubifs_assert(req->idx_growth >= 0); ubifs_assert(c, req->idx_growth >= 0);
ubifs_assert(req->data_growth >= 0); ubifs_assert(c, req->data_growth >= 0);
ubifs_assert(req->dd_growth >= 0); ubifs_assert(c, req->dd_growth >= 0);
} }
if (req->recalculate) { if (req->recalculate) {
@ -561,13 +561,13 @@ void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
c->bi.dd_growth -= req->dd_growth; c->bi.dd_growth -= req->dd_growth;
c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c); c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
ubifs_assert(c->bi.idx_growth >= 0); ubifs_assert(c, c->bi.idx_growth >= 0);
ubifs_assert(c->bi.data_growth >= 0); ubifs_assert(c, c->bi.data_growth >= 0);
ubifs_assert(c->bi.dd_growth >= 0); ubifs_assert(c, c->bi.dd_growth >= 0);
ubifs_assert(c->bi.min_idx_lebs < c->main_lebs); ubifs_assert(c, c->bi.min_idx_lebs < c->main_lebs);
ubifs_assert(!(c->bi.idx_growth & 7)); ubifs_assert(c, !(c->bi.idx_growth & 7));
ubifs_assert(!(c->bi.data_growth & 7)); ubifs_assert(c, !(c->bi.data_growth & 7));
ubifs_assert(!(c->bi.dd_growth & 7)); ubifs_assert(c, !(c->bi.dd_growth & 7));
spin_unlock(&c->space_lock); spin_unlock(&c->space_lock);
} }
@ -680,7 +680,7 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
int rsvd_idx_lebs, lebs; int rsvd_idx_lebs, lebs;
long long available, outstanding, free; long long available, outstanding, free;
ubifs_assert(c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c)); ubifs_assert(c, c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
outstanding = c->bi.data_growth + c->bi.dd_growth; outstanding = c->bi.data_growth + c->bi.dd_growth;
available = ubifs_calc_available(c, c->bi.min_idx_lebs); available = ubifs_calc_available(c, c->bi.min_idx_lebs);

View File

@ -91,9 +91,9 @@ static int nothing_to_commit(struct ubifs_info *c)
if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags)) if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags))
return 0; return 0;
ubifs_assert(atomic_long_read(&c->dirty_zn_cnt) == 0); ubifs_assert(c, atomic_long_read(&c->dirty_zn_cnt) == 0);
ubifs_assert(c->dirty_pn_cnt == 0); ubifs_assert(c, c->dirty_pn_cnt == 0);
ubifs_assert(c->dirty_nn_cnt == 0); ubifs_assert(c, c->dirty_nn_cnt == 0);
return 1; return 1;
} }
@ -113,7 +113,7 @@ static int do_commit(struct ubifs_info *c)
struct ubifs_lp_stats lst; struct ubifs_lp_stats lst;
dbg_cmt("start"); dbg_cmt("start");
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) { if (c->ro_error) {
err = -EROFS; err = -EROFS;

View File

@ -32,7 +32,7 @@ int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
struct page *ret; struct page *ret;
unsigned int pad_len = round_up(in_len, UBIFS_CIPHER_BLOCK_SIZE); unsigned int pad_len = round_up(in_len, UBIFS_CIPHER_BLOCK_SIZE);
ubifs_assert(pad_len <= *out_len); ubifs_assert(c, pad_len <= *out_len);
dn->compr_size = cpu_to_le16(in_len); dn->compr_size = cpu_to_le16(in_len);
/* pad to full block cipher length */ /* pad to full block cipher length */
@ -63,7 +63,7 @@ int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
return -EINVAL; return -EINVAL;
} }
ubifs_assert(dlen <= UBIFS_BLOCK_SIZE); ubifs_assert(c, dlen <= UBIFS_BLOCK_SIZE);
err = fscrypt_decrypt_page(inode, virt_to_page(&dn->data), dlen, err = fscrypt_decrypt_page(inode, virt_to_page(&dn->data), dlen,
offset_in_page(&dn->data), block); offset_in_page(&dn->data), block);
if (err) { if (err) {

View File

@ -134,7 +134,7 @@ const char *dbg_snprintf_key(const struct ubifs_info *c,
} }
} else } else
len -= snprintf(p, len, "bad key format %d", c->key_fmt); len -= snprintf(p, len, "bad key format %d", c->key_fmt);
ubifs_assert(len > 0); ubifs_assert(c, len > 0);
return p; return p;
} }
@ -276,7 +276,7 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
return; return;
pr_err("List of directory entries:\n"); pr_err("List of directory entries:\n");
ubifs_assert(!mutex_is_locked(&c->tnc_mutex)); ubifs_assert(c, !mutex_is_locked(&c->tnc_mutex));
lowest_dent_key(c, &key, inode->i_ino); lowest_dent_key(c, &key, inode->i_ino);
while (1) { while (1) {
@ -931,7 +931,7 @@ void ubifs_dump_tnc(struct ubifs_info *c)
pr_err("\n"); pr_err("\n");
pr_err("(pid %d) start dumping TNC tree\n", current->pid); pr_err("(pid %d) start dumping TNC tree\n", current->pid);
znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL);
level = znode->level; level = znode->level;
pr_err("== Level %d ==\n", level); pr_err("== Level %d ==\n", level);
while (znode) { while (znode) {
@ -940,7 +940,7 @@ void ubifs_dump_tnc(struct ubifs_info *c)
pr_err("== Level %d ==\n", level); pr_err("== Level %d ==\n", level);
} }
ubifs_dump_znode(c, znode); ubifs_dump_znode(c, znode);
znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode);
} }
pr_err("(pid %d) finish dumping TNC tree\n", current->pid); pr_err("(pid %d) finish dumping TNC tree\n", current->pid);
} }
@ -1183,7 +1183,7 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
union ubifs_key key; union ubifs_key key;
char key_buf[DBG_KEY_BUF_LEN]; char key_buf[DBG_KEY_BUF_LEN];
ubifs_assert(!keys_cmp(c, &zbr1->key, &zbr2->key)); ubifs_assert(c, !keys_cmp(c, &zbr1->key, &zbr2->key));
dent1 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); dent1 = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS);
if (!dent1) if (!dent1)
return -ENOMEM; return -ENOMEM;
@ -1479,7 +1479,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
if (!dbg_is_chk_index(c)) if (!dbg_is_chk_index(c))
return 0; return 0;
ubifs_assert(mutex_is_locked(&c->tnc_mutex)); ubifs_assert(c, mutex_is_locked(&c->tnc_mutex));
if (!c->zroot.znode) if (!c->zroot.znode)
return 0; return 0;
@ -1505,7 +1505,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
} }
prev = znode; prev = znode;
znode = ubifs_tnc_postorder_next(znode); znode = ubifs_tnc_postorder_next(c, znode);
if (!znode) if (!znode)
break; break;
@ -2036,7 +2036,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
long long blk_offs; long long blk_offs;
struct ubifs_data_node *dn = node; struct ubifs_data_node *dn = node;
ubifs_assert(zbr->len >= UBIFS_DATA_NODE_SZ); ubifs_assert(c, zbr->len >= UBIFS_DATA_NODE_SZ);
/* /*
* Search the inode node this data node belongs to and insert * Search the inode node this data node belongs to and insert
@ -2066,7 +2066,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
struct ubifs_dent_node *dent = node; struct ubifs_dent_node *dent = node;
struct fsck_inode *fscki1; struct fsck_inode *fscki1;
ubifs_assert(zbr->len >= UBIFS_DENT_NODE_SZ); ubifs_assert(c, zbr->len >= UBIFS_DENT_NODE_SZ);
err = ubifs_validate_entry(c, dent); err = ubifs_validate_entry(c, dent);
if (err) if (err)
@ -2461,7 +2461,7 @@ static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
{ {
struct ubifs_debug_info *d = c->dbg; struct ubifs_debug_info *d = c->dbg;
ubifs_assert(dbg_is_tst_rcvry(c)); ubifs_assert(c, dbg_is_tst_rcvry(c));
if (!d->pc_cnt) { if (!d->pc_cnt) {
/* First call - decide delay to the power cut */ /* First call - decide delay to the power cut */
@ -3081,6 +3081,28 @@ void dbg_debugfs_exit(void)
debugfs_remove_recursive(dfs_rootdir); debugfs_remove_recursive(dfs_rootdir);
} }
void ubifs_assert_failed(struct ubifs_info *c, const char *expr,
const char *file, int line)
{
ubifs_err(c, "UBIFS assert failed: %s, in %s:%u", expr, file, line);
switch (c->assert_action) {
case ASSACT_PANIC:
BUG();
break;
case ASSACT_RO:
ubifs_ro_mode(c, -EINVAL);
break;
case ASSACT_REPORT:
default:
dump_stack();
break;
}
}
/** /**
* ubifs_debugging_init - initialize UBIFS debugging. * ubifs_debugging_init - initialize UBIFS debugging.
* @c: UBIFS file-system description object * @c: UBIFS file-system description object

View File

@ -148,19 +148,21 @@ struct ubifs_global_debug_info {
unsigned int tst_rcvry:1; unsigned int tst_rcvry:1;
}; };
#define ubifs_assert(expr) do { \ void ubifs_assert_failed(struct ubifs_info *c, const char *expr,
const char *file, int line);
#define ubifs_assert(c, expr) do { \
if (unlikely(!(expr))) { \ if (unlikely(!(expr))) { \
pr_crit("UBIFS assert failed in %s at %u (pid %d)\n", \ ubifs_assert_failed((struct ubifs_info *)c, #expr, __FILE__, \
__func__, __LINE__, current->pid); \ __LINE__); \
dump_stack(); \
} \ } \
} while (0) } while (0)
#define ubifs_assert_cmt_locked(c) do { \ #define ubifs_assert_cmt_locked(c) do { \
if (unlikely(down_write_trylock(&(c)->commit_sem))) { \ if (unlikely(down_write_trylock(&(c)->commit_sem))) { \
up_write(&(c)->commit_sem); \ up_write(&(c)->commit_sem); \
pr_crit("commit lock is not locked!\n"); \ ubifs_err(c, "commit lock is not locked!\n"); \
ubifs_assert(0); \ ubifs_assert(c, 0); \
} \ } \
} while (0) } while (0)

View File

@ -240,8 +240,8 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
} }
if (nm.hash) { if (nm.hash) {
ubifs_assert(fname_len(&nm) == 0); ubifs_assert(c, fname_len(&nm) == 0);
ubifs_assert(fname_name(&nm) == NULL); ubifs_assert(c, fname_name(&nm) == NULL);
dent_key_init_hash(c, &key, dir->i_ino, nm.hash); dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash); err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
} else { } else {
@ -404,7 +404,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
if (whiteout) { if (whiteout) {
init_special_inode(inode, inode->i_mode, WHITEOUT_DEV); init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
ubifs_assert(inode->i_op == &ubifs_file_inode_operations); ubifs_assert(c, inode->i_op == &ubifs_file_inode_operations);
} }
err = ubifs_init_security(dir, inode, &dentry->d_name); err = ubifs_init_security(dir, inode, &dentry->d_name);
@ -421,7 +421,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
} else { } else {
d_tmpfile(dentry, inode); d_tmpfile(dentry, inode);
} }
ubifs_assert(ui->dirty); ubifs_assert(c, ui->dirty);
instantiated = 1; instantiated = 1;
mutex_unlock(&ui->ui_mutex); mutex_unlock(&ui->ui_mutex);
@ -556,7 +556,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
/* File positions 0 and 1 correspond to "." and ".." */ /* File positions 0 and 1 correspond to "." and ".." */
if (ctx->pos < 2) { if (ctx->pos < 2) {
ubifs_assert(!file->private_data); ubifs_assert(c, !file->private_data);
if (!dir_emit_dots(file, ctx)) { if (!dir_emit_dots(file, ctx)) {
if (encrypted) if (encrypted)
fscrypt_fname_free_buffer(&fstr); fscrypt_fname_free_buffer(&fstr);
@ -597,7 +597,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
dbg_gen("ino %llu, new f_pos %#x", dbg_gen("ino %llu, new f_pos %#x",
(unsigned long long)le64_to_cpu(dent->inum), (unsigned long long)le64_to_cpu(dent->inum),
key_hash_flash(c, &dent->key)); key_hash_flash(c, &dent->key));
ubifs_assert(le64_to_cpu(dent->ch.sqnum) > ubifs_assert(c, le64_to_cpu(dent->ch.sqnum) >
ubifs_inode(dir)->creat_sqnum); ubifs_inode(dir)->creat_sqnum);
fname_len(&nm) = le16_to_cpu(dent->nlen); fname_len(&nm) = le16_to_cpu(dent->nlen);
@ -716,8 +716,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
dbg_gen("dent '%pd' to ino %lu (nlink %d) in dir ino %lu", dbg_gen("dent '%pd' to ino %lu (nlink %d) in dir ino %lu",
dentry, inode->i_ino, dentry, inode->i_ino,
inode->i_nlink, dir->i_ino); inode->i_nlink, dir->i_ino);
ubifs_assert(inode_is_locked(dir)); ubifs_assert(c, inode_is_locked(dir));
ubifs_assert(inode_is_locked(inode)); ubifs_assert(c, inode_is_locked(inode));
err = fscrypt_prepare_link(old_dentry, dir, dentry); err = fscrypt_prepare_link(old_dentry, dir, dentry);
if (err) if (err)
@ -804,8 +804,8 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
sz_change = CALC_DENT_SIZE(fname_len(&nm)); sz_change = CALC_DENT_SIZE(fname_len(&nm));
ubifs_assert(inode_is_locked(dir)); ubifs_assert(c, inode_is_locked(dir));
ubifs_assert(inode_is_locked(inode)); ubifs_assert(c, inode_is_locked(inode));
err = dbg_check_synced_i_size(c, inode); err = dbg_check_synced_i_size(c, inode);
if (err) if (err)
goto out_fname; goto out_fname;
@ -896,8 +896,8 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
dbg_gen("directory '%pd', ino %lu in dir ino %lu", dentry, dbg_gen("directory '%pd', ino %lu in dir ino %lu", dentry,
inode->i_ino, dir->i_ino); inode->i_ino, dir->i_ino);
ubifs_assert(inode_is_locked(dir)); ubifs_assert(c, inode_is_locked(dir));
ubifs_assert(inode_is_locked(inode)); ubifs_assert(c, inode_is_locked(inode));
err = ubifs_check_dir_empty(d_inode(dentry)); err = ubifs_check_dir_empty(d_inode(dentry));
if (err) if (err)
return err; return err;
@ -1123,8 +1123,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
struct ubifs_inode *ui; struct ubifs_inode *ui;
struct ubifs_inode *dir_ui = ubifs_inode(dir); struct ubifs_inode *dir_ui = ubifs_inode(dir);
struct ubifs_info *c = dir->i_sb->s_fs_info; struct ubifs_info *c = dir->i_sb->s_fs_info;
int err, len = strlen(symname); int err, sz_change, len = strlen(symname);
int sz_change = CALC_DENT_SIZE(len);
struct fscrypt_str disk_link; struct fscrypt_str disk_link;
struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
.new_ino_d = ALIGN(len, 8), .new_ino_d = ALIGN(len, 8),
@ -1151,6 +1150,8 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
if (err) if (err)
goto out_budg; goto out_budg;
sz_change = CALC_DENT_SIZE(fname_len(&nm));
inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO); inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
err = PTR_ERR(inode); err = PTR_ERR(inode);
@ -1294,7 +1295,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
new_dentry, new_dir->i_ino, flags); new_dentry, new_dir->i_ino, flags);
if (unlink) if (unlink)
ubifs_assert(inode_is_locked(new_inode)); ubifs_assert(c, inode_is_locked(new_inode));
if (unlink && is_dir) { if (unlink && is_dir) {
err = ubifs_check_dir_empty(new_inode); err = ubifs_check_dir_empty(new_inode);
@ -1348,7 +1349,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
whiteout_ui = ubifs_inode(whiteout); whiteout_ui = ubifs_inode(whiteout);
whiteout_ui->data = dev; whiteout_ui->data = dev;
whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0)); whiteout_ui->data_len = ubifs_encode_dev(dev, MKDEV(0, 0));
ubifs_assert(!whiteout_ui->dirty); ubifs_assert(c, !whiteout_ui->dirty);
} }
lock_4_inodes(old_dir, new_dir, new_inode, whiteout); lock_4_inodes(old_dir, new_dir, new_inode, whiteout);
@ -1508,7 +1509,7 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
int err; int err;
struct fscrypt_name fst_nm, snd_nm; struct fscrypt_name fst_nm, snd_nm;
ubifs_assert(fst_inode && snd_inode); ubifs_assert(c, fst_inode && snd_inode);
err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &fst_nm); err = fscrypt_setup_filename(old_dir, &old_dentry->d_name, 0, &fst_nm);
if (err) if (err)
@ -1555,12 +1556,13 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned int flags) unsigned int flags)
{ {
int err; int err;
struct ubifs_info *c = old_dir->i_sb->s_fs_info;
if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT | RENAME_EXCHANGE)) if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT | RENAME_EXCHANGE))
return -EINVAL; return -EINVAL;
ubifs_assert(inode_is_locked(old_dir)); ubifs_assert(c, inode_is_locked(old_dir));
ubifs_assert(inode_is_locked(new_dir)); ubifs_assert(c, inode_is_locked(new_dir));
err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry, err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
flags); flags);
@ -1647,7 +1649,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
.rename = ubifs_rename, .rename = ubifs_rename,
.setattr = ubifs_setattr, .setattr = ubifs_setattr,
.getattr = ubifs_getattr, .getattr = ubifs_getattr,
#ifdef CONFIG_UBIFS_FS_XATTR
.listxattr = ubifs_listxattr, .listxattr = ubifs_listxattr,
#endif
#ifdef CONFIG_UBIFS_ATIME_SUPPORT #ifdef CONFIG_UBIFS_ATIME_SUPPORT
.update_time = ubifs_update_time, .update_time = ubifs_update_time,
#endif #endif

View File

@ -71,7 +71,7 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
return err; return err;
} }
ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_assert(c, le64_to_cpu(dn->ch.sqnum) >
ubifs_inode(inode)->creat_sqnum); ubifs_inode(inode)->creat_sqnum);
len = le32_to_cpu(dn->size); len = le32_to_cpu(dn->size);
if (len <= 0 || len > UBIFS_BLOCK_SIZE) if (len <= 0 || len > UBIFS_BLOCK_SIZE)
@ -115,12 +115,13 @@ static int do_readpage(struct page *page)
unsigned int block, beyond; unsigned int block, beyond;
struct ubifs_data_node *dn; struct ubifs_data_node *dn;
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct ubifs_info *c = inode->i_sb->s_fs_info;
loff_t i_size = i_size_read(inode); loff_t i_size = i_size_read(inode);
dbg_gen("ino %lu, pg %lu, i_size %lld, flags %#lx", dbg_gen("ino %lu, pg %lu, i_size %lld, flags %#lx",
inode->i_ino, page->index, i_size, page->flags); inode->i_ino, page->index, i_size, page->flags);
ubifs_assert(!PageChecked(page)); ubifs_assert(c, !PageChecked(page));
ubifs_assert(!PagePrivate(page)); ubifs_assert(c, !PagePrivate(page));
addr = kmap(page); addr = kmap(page);
@ -441,8 +442,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
int skipped_read = 0; int skipped_read = 0;
struct page *page; struct page *page;
ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size); ubifs_assert(c, ubifs_inode(inode)->ui_size == inode->i_size);
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (unlikely(c->ro_error)) if (unlikely(c->ro_error))
return -EROFS; return -EROFS;
@ -481,7 +482,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
err = allocate_budget(c, page, ui, appending); err = allocate_budget(c, page, ui, appending);
if (unlikely(err)) { if (unlikely(err)) {
ubifs_assert(err == -ENOSPC); ubifs_assert(c, err == -ENOSPC);
/* /*
* If we skipped reading the page because we were going to * If we skipped reading the page because we were going to
* write all of it, then it is not up to date. * write all of it, then it is not up to date.
@ -498,7 +499,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
* everything and fall-back to slow-path. * everything and fall-back to slow-path.
*/ */
if (appending) { if (appending) {
ubifs_assert(mutex_is_locked(&ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
mutex_unlock(&ui->ui_mutex); mutex_unlock(&ui->ui_mutex);
} }
unlock_page(page); unlock_page(page);
@ -595,7 +596,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
* '__set_page_dirty_nobuffers()'. * '__set_page_dirty_nobuffers()'.
*/ */
__mark_inode_dirty(inode, I_DIRTY_DATASYNC); __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
ubifs_assert(mutex_is_locked(&ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
mutex_unlock(&ui->ui_mutex); mutex_unlock(&ui->ui_mutex);
} }
@ -648,7 +649,7 @@ static int populate_page(struct ubifs_info *c, struct page *page,
dn = bu->buf + (bu->zbranch[nn].offs - offs); dn = bu->buf + (bu->zbranch[nn].offs - offs);
ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_assert(c, le64_to_cpu(dn->ch.sqnum) >
ubifs_inode(inode)->creat_sqnum); ubifs_inode(inode)->creat_sqnum);
len = le32_to_cpu(dn->size); len = le32_to_cpu(dn->size);
@ -767,8 +768,8 @@ static int ubifs_do_bulk_read(struct ubifs_info *c, struct bu_info *bu,
bu->buf_len = bu->zbranch[bu->cnt - 1].offs + bu->buf_len = bu->zbranch[bu->cnt - 1].offs +
bu->zbranch[bu->cnt - 1].len - bu->zbranch[bu->cnt - 1].len -
bu->zbranch[0].offs; bu->zbranch[0].offs;
ubifs_assert(bu->buf_len > 0); ubifs_assert(c, bu->buf_len > 0);
ubifs_assert(bu->buf_len <= c->leb_size); ubifs_assert(c, bu->buf_len <= c->leb_size);
bu->buf = kmalloc(bu->buf_len, GFP_NOFS | __GFP_NOWARN); bu->buf = kmalloc(bu->buf_len, GFP_NOFS | __GFP_NOWARN);
if (!bu->buf) if (!bu->buf)
goto out_bu_off; goto out_bu_off;
@ -920,7 +921,7 @@ static int do_writepage(struct page *page, int len)
#ifdef UBIFS_DEBUG #ifdef UBIFS_DEBUG
struct ubifs_inode *ui = ubifs_inode(inode); struct ubifs_inode *ui = ubifs_inode(inode);
spin_lock(&ui->ui_lock); spin_lock(&ui->ui_lock);
ubifs_assert(page->index <= ui->synced_i_size >> PAGE_SHIFT); ubifs_assert(c, page->index <= ui->synced_i_size >> PAGE_SHIFT);
spin_unlock(&ui->ui_lock); spin_unlock(&ui->ui_lock);
#endif #endif
@ -949,7 +950,7 @@ static int do_writepage(struct page *page, int len)
ubifs_ro_mode(c, err); ubifs_ro_mode(c, err);
} }
ubifs_assert(PagePrivate(page)); ubifs_assert(c, PagePrivate(page));
if (PageChecked(page)) if (PageChecked(page))
release_new_page_budget(c); release_new_page_budget(c);
else else
@ -1014,6 +1015,7 @@ static int do_writepage(struct page *page, int len)
static int ubifs_writepage(struct page *page, struct writeback_control *wbc) static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct ubifs_info *c = inode->i_sb->s_fs_info;
struct ubifs_inode *ui = ubifs_inode(inode); struct ubifs_inode *ui = ubifs_inode(inode);
loff_t i_size = i_size_read(inode), synced_i_size; loff_t i_size = i_size_read(inode), synced_i_size;
pgoff_t end_index = i_size >> PAGE_SHIFT; pgoff_t end_index = i_size >> PAGE_SHIFT;
@ -1022,7 +1024,7 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
dbg_gen("ino %lu, pg %lu, pg flags %#lx", dbg_gen("ino %lu, pg %lu, pg flags %#lx",
inode->i_ino, page->index, page->flags); inode->i_ino, page->index, page->flags);
ubifs_assert(PagePrivate(page)); ubifs_assert(c, PagePrivate(page));
/* Is the page fully outside @i_size? (truncate in progress) */ /* Is the page fully outside @i_size? (truncate in progress) */
if (page->index > end_index || (page->index == end_index && !len)) { if (page->index > end_index || (page->index == end_index && !len)) {
@ -1167,7 +1169,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
* 'ubifs_jnl_truncate()' will see an already * 'ubifs_jnl_truncate()' will see an already
* truncated (and up to date) data node. * truncated (and up to date) data node.
*/ */
ubifs_assert(PagePrivate(page)); ubifs_assert(c, PagePrivate(page));
clear_page_dirty_for_io(page); clear_page_dirty_for_io(page);
if (UBIFS_BLOCKS_PER_PAGE_SHIFT) if (UBIFS_BLOCKS_PER_PAGE_SHIFT)
@ -1303,7 +1305,7 @@ static void ubifs_invalidatepage(struct page *page, unsigned int offset,
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct ubifs_info *c = inode->i_sb->s_fs_info; struct ubifs_info *c = inode->i_sb->s_fs_info;
ubifs_assert(PagePrivate(page)); ubifs_assert(c, PagePrivate(page));
if (offset || length < PAGE_SIZE) if (offset || length < PAGE_SIZE)
/* Partial page remains dirty */ /* Partial page remains dirty */
return; return;
@ -1365,11 +1367,10 @@ out:
* granularity, they are not updated. This is an optimization. * granularity, they are not updated. This is an optimization.
*/ */
static inline int mctime_update_needed(const struct inode *inode, static inline int mctime_update_needed(const struct inode *inode,
const struct timespec *now) const struct timespec64 *now)
{ {
struct timespec64 now64 = timespec_to_timespec64(*now); if (!timespec64_equal(&inode->i_mtime, now) ||
if (!timespec64_equal(&inode->i_mtime, &now64) || !timespec64_equal(&inode->i_ctime, now))
!timespec64_equal(&inode->i_ctime, &now64))
return 1; return 1;
return 0; return 0;
} }
@ -1425,7 +1426,7 @@ int ubifs_update_time(struct inode *inode, struct timespec64 *time,
*/ */
static int update_mctime(struct inode *inode) static int update_mctime(struct inode *inode)
{ {
struct timespec now = timespec64_to_timespec(current_time(inode)); struct timespec64 now = current_time(inode);
struct ubifs_inode *ui = ubifs_inode(inode); struct ubifs_inode *ui = ubifs_inode(inode);
struct ubifs_info *c = inode->i_sb->s_fs_info; struct ubifs_info *c = inode->i_sb->s_fs_info;
@ -1462,13 +1463,15 @@ static ssize_t ubifs_write_iter(struct kiocb *iocb, struct iov_iter *from)
static int ubifs_set_page_dirty(struct page *page) static int ubifs_set_page_dirty(struct page *page)
{ {
int ret; int ret;
struct inode *inode = page->mapping->host;
struct ubifs_info *c = inode->i_sb->s_fs_info;
ret = __set_page_dirty_nobuffers(page); ret = __set_page_dirty_nobuffers(page);
/* /*
* An attempt to dirty a page without budgeting for it - should not * An attempt to dirty a page without budgeting for it - should not
* happen. * happen.
*/ */
ubifs_assert(ret == 0); ubifs_assert(c, ret == 0);
return ret; return ret;
} }
@ -1497,14 +1500,17 @@ static int ubifs_migrate_page(struct address_space *mapping,
static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags) static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
{ {
struct inode *inode = page->mapping->host;
struct ubifs_info *c = inode->i_sb->s_fs_info;
/* /*
* An attempt to release a dirty page without budgeting for it - should * An attempt to release a dirty page without budgeting for it - should
* not happen. * not happen.
*/ */
if (PageWriteback(page)) if (PageWriteback(page))
return 0; return 0;
ubifs_assert(PagePrivate(page)); ubifs_assert(c, PagePrivate(page));
ubifs_assert(0); ubifs_assert(c, 0);
ClearPagePrivate(page); ClearPagePrivate(page);
ClearPageChecked(page); ClearPageChecked(page);
return 1; return 1;
@ -1519,13 +1525,13 @@ static vm_fault_t ubifs_vm_page_mkwrite(struct vm_fault *vmf)
struct page *page = vmf->page; struct page *page = vmf->page;
struct inode *inode = file_inode(vmf->vma->vm_file); struct inode *inode = file_inode(vmf->vma->vm_file);
struct ubifs_info *c = inode->i_sb->s_fs_info; struct ubifs_info *c = inode->i_sb->s_fs_info;
struct timespec now = timespec64_to_timespec(current_time(inode)); struct timespec64 now = current_time(inode);
struct ubifs_budget_req req = { .new_page = 1 }; struct ubifs_budget_req req = { .new_page = 1 };
int err, update_time; int err, update_time;
dbg_gen("ino %lu, pg %lu, i_size %lld", inode->i_ino, page->index, dbg_gen("ino %lu, pg %lu, i_size %lld", inode->i_ino, page->index,
i_size_read(inode)); i_size_read(inode));
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (unlikely(c->ro_error)) if (unlikely(c->ro_error))
return VM_FAULT_SIGBUS; /* -EROFS */ return VM_FAULT_SIGBUS; /* -EROFS */
@ -1654,7 +1660,9 @@ const struct address_space_operations ubifs_file_address_operations = {
const struct inode_operations ubifs_file_inode_operations = { const struct inode_operations ubifs_file_inode_operations = {
.setattr = ubifs_setattr, .setattr = ubifs_setattr,
.getattr = ubifs_getattr, .getattr = ubifs_getattr,
#ifdef CONFIG_UBIFS_FS_XATTR
.listxattr = ubifs_listxattr, .listxattr = ubifs_listxattr,
#endif
#ifdef CONFIG_UBIFS_ATIME_SUPPORT #ifdef CONFIG_UBIFS_ATIME_SUPPORT
.update_time = ubifs_update_time, .update_time = ubifs_update_time,
#endif #endif
@ -1664,7 +1672,9 @@ const struct inode_operations ubifs_symlink_inode_operations = {
.get_link = ubifs_get_link, .get_link = ubifs_get_link,
.setattr = ubifs_setattr, .setattr = ubifs_setattr,
.getattr = ubifs_getattr, .getattr = ubifs_getattr,
#ifdef CONFIG_UBIFS_FS_XATTR
.listxattr = ubifs_listxattr, .listxattr = ubifs_listxattr,
#endif
#ifdef CONFIG_UBIFS_ATIME_SUPPORT #ifdef CONFIG_UBIFS_ATIME_SUPPORT
.update_time = ubifs_update_time, .update_time = ubifs_update_time,
#endif #endif

0
fs/ubifs/file.h Normal file
View File

View File

@ -183,18 +183,18 @@ static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c,
&data); &data);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
c->lscan_lnum = data.lnum; c->lscan_lnum = data.lnum;
lprops = ubifs_lpt_lookup_dirty(c, data.lnum); lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
if (IS_ERR(lprops)) if (IS_ERR(lprops))
return lprops; return lprops;
ubifs_assert(lprops->lnum == data.lnum); ubifs_assert(c, lprops->lnum == data.lnum);
ubifs_assert(lprops->free + lprops->dirty >= min_space); ubifs_assert(c, lprops->free + lprops->dirty >= min_space);
ubifs_assert(lprops->dirty >= c->dead_wm || ubifs_assert(c, lprops->dirty >= c->dead_wm ||
(pick_free && (pick_free &&
lprops->free + lprops->dirty == c->leb_size)); lprops->free + lprops->dirty == c->leb_size));
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert(!exclude_index || !(lprops->flags & LPROPS_INDEX)); ubifs_assert(c, !exclude_index || !(lprops->flags & LPROPS_INDEX));
return lprops; return lprops;
} }
@ -315,7 +315,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
lp = idx_lp; lp = idx_lp;
if (lp) { if (lp) {
ubifs_assert(lp->free + lp->dirty >= c->dead_wm); ubifs_assert(c, lp->free + lp->dirty >= c->dead_wm);
goto found; goto found;
} }
@ -326,7 +326,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
err = PTR_ERR(lp); err = PTR_ERR(lp);
goto out; goto out;
} }
ubifs_assert(lp->dirty >= c->dead_wm || ubifs_assert(c, lp->dirty >= c->dead_wm ||
(pick_free && lp->free + lp->dirty == c->leb_size)); (pick_free && lp->free + lp->dirty == c->leb_size));
found: found:
@ -462,15 +462,15 @@ const struct ubifs_lprops *do_find_free_space(struct ubifs_info *c,
&data); &data);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
c->lscan_lnum = data.lnum; c->lscan_lnum = data.lnum;
lprops = ubifs_lpt_lookup_dirty(c, data.lnum); lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
if (IS_ERR(lprops)) if (IS_ERR(lprops))
return lprops; return lprops;
ubifs_assert(lprops->lnum == data.lnum); ubifs_assert(c, lprops->lnum == data.lnum);
ubifs_assert(lprops->free >= min_space); ubifs_assert(c, lprops->free >= min_space);
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert(!(lprops->flags & LPROPS_INDEX)); ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
return lprops; return lprops;
} }
@ -574,7 +574,7 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,
} }
dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs); dbg_find("found LEB %d, free %d", lnum, c->leb_size - *offs);
ubifs_assert(*offs <= c->leb_size - min_space); ubifs_assert(c, *offs <= c->leb_size - min_space);
return lnum; return lnum;
out: out:
@ -642,15 +642,15 @@ static const struct ubifs_lprops *scan_for_leb_for_idx(struct ubifs_info *c)
&data); &data);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);
ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
c->lscan_lnum = data.lnum; c->lscan_lnum = data.lnum;
lprops = ubifs_lpt_lookup_dirty(c, data.lnum); lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
if (IS_ERR(lprops)) if (IS_ERR(lprops))
return lprops; return lprops;
ubifs_assert(lprops->lnum == data.lnum); ubifs_assert(c, lprops->lnum == data.lnum);
ubifs_assert(lprops->free + lprops->dirty == c->leb_size); ubifs_assert(c, lprops->free + lprops->dirty == c->leb_size);
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert(!(lprops->flags & LPROPS_INDEX)); ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
return lprops; return lprops;
} }
@ -690,7 +690,7 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c)
*/ */
if (c->in_a_category_cnt != c->main_lebs || if (c->in_a_category_cnt != c->main_lebs ||
c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) {
ubifs_assert(c->freeable_cnt == 0); ubifs_assert(c, c->freeable_cnt == 0);
lprops = scan_for_leb_for_idx(c); lprops = scan_for_leb_for_idx(c);
if (IS_ERR(lprops)) { if (IS_ERR(lprops)) {
err = PTR_ERR(lprops); err = PTR_ERR(lprops);
@ -750,10 +750,7 @@ static int cmp_dirty_idx(const struct ubifs_lprops **a,
static void swap_dirty_idx(struct ubifs_lprops **a, struct ubifs_lprops **b, static void swap_dirty_idx(struct ubifs_lprops **a, struct ubifs_lprops **b,
int size) int size)
{ {
struct ubifs_lprops *t = *a; swap(*a, *b);
*a = *b;
*b = t;
} }
/** /**
@ -870,15 +867,15 @@ static int find_dirty_idx_leb(struct ubifs_info *c)
if (err) if (err)
return err; return err;
found: found:
ubifs_assert(data.lnum >= c->main_first && data.lnum < c->leb_cnt); ubifs_assert(c, data.lnum >= c->main_first && data.lnum < c->leb_cnt);
c->lscan_lnum = data.lnum; c->lscan_lnum = data.lnum;
lprops = ubifs_lpt_lookup_dirty(c, data.lnum); lprops = ubifs_lpt_lookup_dirty(c, data.lnum);
if (IS_ERR(lprops)) if (IS_ERR(lprops))
return PTR_ERR(lprops); return PTR_ERR(lprops);
ubifs_assert(lprops->lnum == data.lnum); ubifs_assert(c, lprops->lnum == data.lnum);
ubifs_assert(lprops->free + lprops->dirty >= c->min_idx_node_sz); ubifs_assert(c, lprops->free + lprops->dirty >= c->min_idx_node_sz);
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert((lprops->flags & LPROPS_INDEX)); ubifs_assert(c, (lprops->flags & LPROPS_INDEX));
dbg_find("found dirty LEB %d, free %d, dirty %d, flags %#x", dbg_find("found dirty LEB %d, free %d, dirty %d, flags %#x",
lprops->lnum, lprops->free, lprops->dirty, lprops->flags); lprops->lnum, lprops->free, lprops->dirty, lprops->flags);
@ -947,8 +944,8 @@ static int find_dirtiest_idx_leb(struct ubifs_info *c)
} }
dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty, dbg_find("LEB %d, dirty %d and free %d flags %#x", lp->lnum, lp->dirty,
lp->free, lp->flags); lp->free, lp->flags);
ubifs_assert(lp->flags & LPROPS_TAKEN); ubifs_assert(c, lp->flags & LPROPS_TAKEN);
ubifs_assert(lp->flags & LPROPS_INDEX); ubifs_assert(c, lp->flags & LPROPS_INDEX);
return lnum; return lnum;
} }

View File

@ -83,7 +83,7 @@ static int switch_gc_head(struct ubifs_info *c)
int err, gc_lnum = c->gc_lnum; int err, gc_lnum = c->gc_lnum;
struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
ubifs_assert(gc_lnum != -1); ubifs_assert(c, gc_lnum != -1);
dbg_gc("switch GC head from LEB %d:%d to LEB %d (waste %d bytes)", dbg_gc("switch GC head from LEB %d:%d to LEB %d (waste %d bytes)",
wbuf->lnum, wbuf->offs + wbuf->used, gc_lnum, wbuf->lnum, wbuf->offs + wbuf->used, gc_lnum,
c->leb_size - wbuf->offs - wbuf->used); c->leb_size - wbuf->offs - wbuf->used);
@ -131,10 +131,10 @@ static int data_nodes_cmp(void *priv, struct list_head *a, struct list_head *b)
sa = list_entry(a, struct ubifs_scan_node, list); sa = list_entry(a, struct ubifs_scan_node, list);
sb = list_entry(b, struct ubifs_scan_node, list); sb = list_entry(b, struct ubifs_scan_node, list);
ubifs_assert(key_type(c, &sa->key) == UBIFS_DATA_KEY); ubifs_assert(c, key_type(c, &sa->key) == UBIFS_DATA_KEY);
ubifs_assert(key_type(c, &sb->key) == UBIFS_DATA_KEY); ubifs_assert(c, key_type(c, &sb->key) == UBIFS_DATA_KEY);
ubifs_assert(sa->type == UBIFS_DATA_NODE); ubifs_assert(c, sa->type == UBIFS_DATA_NODE);
ubifs_assert(sb->type == UBIFS_DATA_NODE); ubifs_assert(c, sb->type == UBIFS_DATA_NODE);
inuma = key_inum(c, &sa->key); inuma = key_inum(c, &sa->key);
inumb = key_inum(c, &sb->key); inumb = key_inum(c, &sb->key);
@ -175,9 +175,9 @@ static int nondata_nodes_cmp(void *priv, struct list_head *a,
sa = list_entry(a, struct ubifs_scan_node, list); sa = list_entry(a, struct ubifs_scan_node, list);
sb = list_entry(b, struct ubifs_scan_node, list); sb = list_entry(b, struct ubifs_scan_node, list);
ubifs_assert(key_type(c, &sa->key) != UBIFS_DATA_KEY && ubifs_assert(c, key_type(c, &sa->key) != UBIFS_DATA_KEY &&
key_type(c, &sb->key) != UBIFS_DATA_KEY); key_type(c, &sb->key) != UBIFS_DATA_KEY);
ubifs_assert(sa->type != UBIFS_DATA_NODE && ubifs_assert(c, sa->type != UBIFS_DATA_NODE &&
sb->type != UBIFS_DATA_NODE); sb->type != UBIFS_DATA_NODE);
/* Inodes go before directory entries */ /* Inodes go before directory entries */
@ -189,13 +189,13 @@ static int nondata_nodes_cmp(void *priv, struct list_head *a,
if (sb->type == UBIFS_INO_NODE) if (sb->type == UBIFS_INO_NODE)
return 1; return 1;
ubifs_assert(key_type(c, &sa->key) == UBIFS_DENT_KEY || ubifs_assert(c, key_type(c, &sa->key) == UBIFS_DENT_KEY ||
key_type(c, &sa->key) == UBIFS_XENT_KEY); key_type(c, &sa->key) == UBIFS_XENT_KEY);
ubifs_assert(key_type(c, &sb->key) == UBIFS_DENT_KEY || ubifs_assert(c, key_type(c, &sb->key) == UBIFS_DENT_KEY ||
key_type(c, &sb->key) == UBIFS_XENT_KEY); key_type(c, &sb->key) == UBIFS_XENT_KEY);
ubifs_assert(sa->type == UBIFS_DENT_NODE || ubifs_assert(c, sa->type == UBIFS_DENT_NODE ||
sa->type == UBIFS_XENT_NODE); sa->type == UBIFS_XENT_NODE);
ubifs_assert(sb->type == UBIFS_DENT_NODE || ubifs_assert(c, sb->type == UBIFS_DENT_NODE ||
sb->type == UBIFS_XENT_NODE); sb->type == UBIFS_XENT_NODE);
inuma = key_inum(c, &sa->key); inuma = key_inum(c, &sa->key);
@ -250,7 +250,7 @@ static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
/* Separate data nodes and non-data nodes */ /* Separate data nodes and non-data nodes */
list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) { list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
ubifs_assert(snod->type == UBIFS_INO_NODE || ubifs_assert(c, snod->type == UBIFS_INO_NODE ||
snod->type == UBIFS_DATA_NODE || snod->type == UBIFS_DATA_NODE ||
snod->type == UBIFS_DENT_NODE || snod->type == UBIFS_DENT_NODE ||
snod->type == UBIFS_XENT_NODE || snod->type == UBIFS_XENT_NODE ||
@ -266,7 +266,7 @@ static int sort_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
continue; continue;
} }
ubifs_assert(key_type(c, &snod->key) == UBIFS_DATA_KEY || ubifs_assert(c, key_type(c, &snod->key) == UBIFS_DATA_KEY ||
key_type(c, &snod->key) == UBIFS_INO_KEY || key_type(c, &snod->key) == UBIFS_INO_KEY ||
key_type(c, &snod->key) == UBIFS_DENT_KEY || key_type(c, &snod->key) == UBIFS_DENT_KEY ||
key_type(c, &snod->key) == UBIFS_XENT_KEY); key_type(c, &snod->key) == UBIFS_XENT_KEY);
@ -469,21 +469,21 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
int err = 0, lnum = lp->lnum; int err = 0, lnum = lp->lnum;
ubifs_assert(c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 || ubifs_assert(c, c->gc_lnum != -1 || wbuf->offs + wbuf->used == 0 ||
c->need_recovery); c->need_recovery);
ubifs_assert(c->gc_lnum != lnum); ubifs_assert(c, c->gc_lnum != lnum);
ubifs_assert(wbuf->lnum != lnum); ubifs_assert(c, wbuf->lnum != lnum);
if (lp->free + lp->dirty == c->leb_size) { if (lp->free + lp->dirty == c->leb_size) {
/* Special case - a free LEB */ /* Special case - a free LEB */
dbg_gc("LEB %d is free, return it", lp->lnum); dbg_gc("LEB %d is free, return it", lp->lnum);
ubifs_assert(!(lp->flags & LPROPS_INDEX)); ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
if (lp->free != c->leb_size) { if (lp->free != c->leb_size) {
/* /*
* Write buffers must be sync'd before unmapping * Write buffers must be sync'd before unmapping
* freeable LEBs, because one of them may contain data * freeable LEBs, because one of them may contain data
* which obsoletes something in 'lp->pnum'. * which obsoletes something in 'lp->lnum'.
*/ */
err = gc_sync_wbufs(c); err = gc_sync_wbufs(c);
if (err) if (err)
@ -513,7 +513,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
if (IS_ERR(sleb)) if (IS_ERR(sleb))
return PTR_ERR(sleb); return PTR_ERR(sleb);
ubifs_assert(!list_empty(&sleb->nodes)); ubifs_assert(c, !list_empty(&sleb->nodes));
snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list); snod = list_entry(sleb->nodes.next, struct ubifs_scan_node, list);
if (snod->type == UBIFS_IDX_NODE) { if (snod->type == UBIFS_IDX_NODE) {
@ -525,7 +525,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
struct ubifs_idx_node *idx = snod->node; struct ubifs_idx_node *idx = snod->node;
int level = le16_to_cpu(idx->level); int level = le16_to_cpu(idx->level);
ubifs_assert(snod->type == UBIFS_IDX_NODE); ubifs_assert(c, snod->type == UBIFS_IDX_NODE);
key_read(c, ubifs_idx_key(c, idx), &snod->key); key_read(c, ubifs_idx_key(c, idx), &snod->key);
err = ubifs_dirty_idx_node(c, &snod->key, level, lnum, err = ubifs_dirty_idx_node(c, &snod->key, level, lnum,
snod->offs); snod->offs);
@ -648,7 +648,7 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
ubifs_assert_cmt_locked(c); ubifs_assert_cmt_locked(c);
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (ubifs_gc_should_commit(c)) if (ubifs_gc_should_commit(c))
return -EAGAIN; return -EAGAIN;
@ -661,7 +661,7 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
} }
/* We expect the write-buffer to be empty on entry */ /* We expect the write-buffer to be empty on entry */
ubifs_assert(!wbuf->used); ubifs_assert(c, !wbuf->used);
for (i = 0; ; i++) { for (i = 0; ; i++) {
int space_before, space_after; int space_before, space_after;
@ -752,7 +752,7 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
continue; continue;
} }
ubifs_assert(ret == LEB_RETAINED); ubifs_assert(c, ret == LEB_RETAINED);
space_after = c->leb_size - wbuf->offs - wbuf->used; space_after = c->leb_size - wbuf->offs - wbuf->used;
dbg_gc("LEB %d retained, freed %d bytes", lp.lnum, dbg_gc("LEB %d retained, freed %d bytes", lp.lnum,
space_after - space_before); space_after - space_before);
@ -812,8 +812,8 @@ out_unlock:
return ret; return ret;
out: out:
ubifs_assert(ret < 0); ubifs_assert(c, ret < 0);
ubifs_assert(ret != -ENOSPC && ret != -EAGAIN); ubifs_assert(c, ret != -ENOSPC && ret != -EAGAIN);
ubifs_wbuf_sync_nolock(wbuf); ubifs_wbuf_sync_nolock(wbuf);
ubifs_ro_mode(c, ret); ubifs_ro_mode(c, ret);
mutex_unlock(&wbuf->io_mutex); mutex_unlock(&wbuf->io_mutex);
@ -848,8 +848,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
lp = ubifs_fast_find_freeable(c); lp = ubifs_fast_find_freeable(c);
if (!lp) if (!lp)
break; break;
ubifs_assert(!(lp->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
ubifs_assert(!(lp->flags & LPROPS_INDEX)); ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
err = ubifs_leb_unmap(c, lp->lnum); err = ubifs_leb_unmap(c, lp->lnum);
if (err) if (err)
goto out; goto out;
@ -858,8 +858,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
err = PTR_ERR(lp); err = PTR_ERR(lp);
goto out; goto out;
} }
ubifs_assert(!(lp->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
ubifs_assert(!(lp->flags & LPROPS_INDEX)); ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
} }
/* Mark GC'd index LEBs OK to unmap after this commit finishes */ /* Mark GC'd index LEBs OK to unmap after this commit finishes */
@ -880,8 +880,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
} }
ubifs_assert(!(lp->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lp->flags & LPROPS_TAKEN));
ubifs_assert(lp->flags & LPROPS_INDEX); ubifs_assert(c, lp->flags & LPROPS_INDEX);
/* Don't release the LEB until after the next commit */ /* Don't release the LEB until after the next commit */
flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX; flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX;
lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1); lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1);
@ -890,8 +890,8 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
kfree(idx_gc); kfree(idx_gc);
goto out; goto out;
} }
ubifs_assert(lp->flags & LPROPS_TAKEN); ubifs_assert(c, lp->flags & LPROPS_TAKEN);
ubifs_assert(!(lp->flags & LPROPS_INDEX)); ubifs_assert(c, !(lp->flags & LPROPS_INDEX));
idx_gc->lnum = lp->lnum; idx_gc->lnum = lp->lnum;
idx_gc->unmap = 1; idx_gc->unmap = 1;
list_add(&idx_gc->list, &c->idx_gc); list_add(&idx_gc->list, &c->idx_gc);

View File

@ -119,7 +119,7 @@ int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
{ {
int err; int err;
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) if (c->ro_error)
return -EROFS; return -EROFS;
if (!dbg_is_tst_rcvry(c)) if (!dbg_is_tst_rcvry(c))
@ -139,7 +139,7 @@ int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len)
{ {
int err; int err;
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) if (c->ro_error)
return -EROFS; return -EROFS;
if (!dbg_is_tst_rcvry(c)) if (!dbg_is_tst_rcvry(c))
@ -159,7 +159,7 @@ int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
{ {
int err; int err;
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) if (c->ro_error)
return -EROFS; return -EROFS;
if (!dbg_is_tst_rcvry(c)) if (!dbg_is_tst_rcvry(c))
@ -178,7 +178,7 @@ int ubifs_leb_map(struct ubifs_info *c, int lnum)
{ {
int err; int err;
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) if (c->ro_error)
return -EROFS; return -EROFS;
if (!dbg_is_tst_rcvry(c)) if (!dbg_is_tst_rcvry(c))
@ -241,8 +241,8 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
uint32_t crc, node_crc, magic; uint32_t crc, node_crc, magic;
const struct ubifs_ch *ch = buf; const struct ubifs_ch *ch = buf;
ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
ubifs_assert(!(offs & 7) && offs < c->leb_size); ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
magic = le32_to_cpu(ch->magic); magic = le32_to_cpu(ch->magic);
if (magic != UBIFS_NODE_MAGIC) { if (magic != UBIFS_NODE_MAGIC) {
@ -319,7 +319,7 @@ void ubifs_pad(const struct ubifs_info *c, void *buf, int pad)
{ {
uint32_t crc; uint32_t crc;
ubifs_assert(pad >= 0 && !(pad & 7)); ubifs_assert(c, pad >= 0 && !(pad & 7));
if (pad >= UBIFS_PAD_NODE_SZ) { if (pad >= UBIFS_PAD_NODE_SZ) {
struct ubifs_ch *ch = buf; struct ubifs_ch *ch = buf;
@ -382,7 +382,7 @@ void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad)
struct ubifs_ch *ch = node; struct ubifs_ch *ch = node;
unsigned long long sqnum = next_sqnum(c); unsigned long long sqnum = next_sqnum(c);
ubifs_assert(len >= UBIFS_CH_SZ); ubifs_assert(c, len >= UBIFS_CH_SZ);
ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC); ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC);
ch->len = cpu_to_le32(len); ch->len = cpu_to_le32(len);
@ -415,7 +415,7 @@ void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last)
struct ubifs_ch *ch = node; struct ubifs_ch *ch = node;
unsigned long long sqnum = next_sqnum(c); unsigned long long sqnum = next_sqnum(c);
ubifs_assert(len >= UBIFS_CH_SZ); ubifs_assert(c, len >= UBIFS_CH_SZ);
ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC); ch->magic = cpu_to_le32(UBIFS_NODE_MAGIC);
ch->len = cpu_to_le32(len); ch->len = cpu_to_le32(len);
@ -448,9 +448,10 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer)
/** /**
* new_wbuf_timer - start new write-buffer timer. * new_wbuf_timer - start new write-buffer timer.
* @c: UBIFS file-system description object
* @wbuf: write-buffer descriptor * @wbuf: write-buffer descriptor
*/ */
static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) static void new_wbuf_timer_nolock(struct ubifs_info *c, struct ubifs_wbuf *wbuf)
{ {
ktime_t softlimit = ms_to_ktime(dirty_writeback_interval * 10); ktime_t softlimit = ms_to_ktime(dirty_writeback_interval * 10);
unsigned long long delta = dirty_writeback_interval; unsigned long long delta = dirty_writeback_interval;
@ -458,8 +459,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf)
/* centi to milli, milli to nano, then 10% */ /* centi to milli, milli to nano, then 10% */
delta *= 10ULL * NSEC_PER_MSEC / 10ULL; delta *= 10ULL * NSEC_PER_MSEC / 10ULL;
ubifs_assert(!hrtimer_active(&wbuf->timer)); ubifs_assert(c, !hrtimer_active(&wbuf->timer));
ubifs_assert(delta <= ULONG_MAX); ubifs_assert(c, delta <= ULONG_MAX);
if (wbuf->no_timer) if (wbuf->no_timer)
return; return;
@ -508,14 +509,14 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
dbg_io("LEB %d:%d, %d bytes, jhead %s", dbg_io("LEB %d:%d, %d bytes, jhead %s",
wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead)); wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead));
ubifs_assert(!(wbuf->avail & 7)); ubifs_assert(c, !(wbuf->avail & 7));
ubifs_assert(wbuf->offs + wbuf->size <= c->leb_size); ubifs_assert(c, wbuf->offs + wbuf->size <= c->leb_size);
ubifs_assert(wbuf->size >= c->min_io_size); ubifs_assert(c, wbuf->size >= c->min_io_size);
ubifs_assert(wbuf->size <= c->max_write_size); ubifs_assert(c, wbuf->size <= c->max_write_size);
ubifs_assert(wbuf->size % c->min_io_size == 0); ubifs_assert(c, wbuf->size % c->min_io_size == 0);
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->leb_size - wbuf->offs >= c->max_write_size) if (c->leb_size - wbuf->offs >= c->max_write_size)
ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size)); ubifs_assert(c, !((wbuf->offs + wbuf->size) % c->max_write_size));
if (c->ro_error) if (c->ro_error)
return -EROFS; return -EROFS;
@ -576,11 +577,11 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs)
const struct ubifs_info *c = wbuf->c; const struct ubifs_info *c = wbuf->c;
dbg_io("LEB %d:%d, jhead %s", lnum, offs, dbg_jhead(wbuf->jhead)); dbg_io("LEB %d:%d, jhead %s", lnum, offs, dbg_jhead(wbuf->jhead));
ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt);
ubifs_assert(offs >= 0 && offs <= c->leb_size); ubifs_assert(c, offs >= 0 && offs <= c->leb_size);
ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); ubifs_assert(c, offs % c->min_io_size == 0 && !(offs & 7));
ubifs_assert(lnum != wbuf->lnum); ubifs_assert(c, lnum != wbuf->lnum);
ubifs_assert(wbuf->used == 0); ubifs_assert(c, wbuf->used == 0);
spin_lock(&wbuf->lock); spin_lock(&wbuf->lock);
wbuf->lnum = lnum; wbuf->lnum = lnum;
@ -610,7 +611,7 @@ int ubifs_bg_wbufs_sync(struct ubifs_info *c)
{ {
int err, i; int err, i;
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (!c->need_wbuf_sync) if (!c->need_wbuf_sync)
return 0; return 0;
c->need_wbuf_sync = 0; c->need_wbuf_sync = 0;
@ -686,18 +687,18 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len, dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len,
dbg_ntype(((struct ubifs_ch *)buf)->node_type), dbg_ntype(((struct ubifs_ch *)buf)->node_type),
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs + wbuf->used); dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs + wbuf->used);
ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); ubifs_assert(c, len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt);
ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); ubifs_assert(c, wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0);
ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); ubifs_assert(c, !(wbuf->offs & 7) && wbuf->offs <= c->leb_size);
ubifs_assert(wbuf->avail > 0 && wbuf->avail <= wbuf->size); ubifs_assert(c, wbuf->avail > 0 && wbuf->avail <= wbuf->size);
ubifs_assert(wbuf->size >= c->min_io_size); ubifs_assert(c, wbuf->size >= c->min_io_size);
ubifs_assert(wbuf->size <= c->max_write_size); ubifs_assert(c, wbuf->size <= c->max_write_size);
ubifs_assert(wbuf->size % c->min_io_size == 0); ubifs_assert(c, wbuf->size % c->min_io_size == 0);
ubifs_assert(mutex_is_locked(&wbuf->io_mutex)); ubifs_assert(c, mutex_is_locked(&wbuf->io_mutex));
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
ubifs_assert(!c->space_fixup); ubifs_assert(c, !c->space_fixup);
if (c->leb_size - wbuf->offs >= c->max_write_size) if (c->leb_size - wbuf->offs >= c->max_write_size)
ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size)); ubifs_assert(c, !((wbuf->offs + wbuf->size) % c->max_write_size));
if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) { if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) {
err = -ENOSPC; err = -ENOSPC;
@ -834,7 +835,7 @@ exit:
} }
if (wbuf->used) if (wbuf->used)
new_wbuf_timer_nolock(wbuf); new_wbuf_timer_nolock(c, wbuf);
return 0; return 0;
@ -869,10 +870,10 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
dbg_io("LEB %d:%d, %s, length %d (aligned %d)", dbg_io("LEB %d:%d, %s, length %d (aligned %d)",
lnum, offs, dbg_ntype(((struct ubifs_ch *)buf)->node_type), len, lnum, offs, dbg_ntype(((struct ubifs_ch *)buf)->node_type), len,
buf_len); buf_len);
ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size); ubifs_assert(c, offs % c->min_io_size == 0 && offs < c->leb_size);
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
ubifs_assert(!c->space_fixup); ubifs_assert(c, !c->space_fixup);
if (c->ro_error) if (c->ro_error)
return -EROFS; return -EROFS;
@ -909,9 +910,9 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
dbg_io("LEB %d:%d, %s, length %d, jhead %s", lnum, offs, dbg_io("LEB %d:%d, %s, length %d, jhead %s", lnum, offs,
dbg_ntype(type), len, dbg_jhead(wbuf->jhead)); dbg_ntype(type), len, dbg_jhead(wbuf->jhead));
ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); ubifs_assert(c, wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
ubifs_assert(!(offs & 7) && offs < c->leb_size); ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); ubifs_assert(c, type >= 0 && type < UBIFS_NODE_TYPES_CNT);
spin_lock(&wbuf->lock); spin_lock(&wbuf->lock);
overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs); overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs);
@ -984,10 +985,10 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
struct ubifs_ch *ch = buf; struct ubifs_ch *ch = buf;
dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len);
ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
ubifs_assert(len >= UBIFS_CH_SZ && offs + len <= c->leb_size); ubifs_assert(c, len >= UBIFS_CH_SZ && offs + len <= c->leb_size);
ubifs_assert(!(offs & 7) && offs < c->leb_size); ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); ubifs_assert(c, type >= 0 && type < UBIFS_NODE_TYPES_CNT);
err = ubifs_leb_read(c, lnum, buf, offs, len, 0); err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
if (err && err != -EBADMSG) if (err && err != -EBADMSG)

View File

@ -111,7 +111,7 @@ static int reserve_space(struct ubifs_info *c, int jhead, int len)
* better to try to allocate space at the ends of eraseblocks. This is * better to try to allocate space at the ends of eraseblocks. This is
* what the squeeze parameter does. * what the squeeze parameter does.
*/ */
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
squeeze = (jhead == BASEHD); squeeze = (jhead == BASEHD);
again: again:
mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
@ -215,7 +215,7 @@ out_unlock:
out_return: out_return:
/* An error occurred and the LEB has to be returned to lprops */ /* An error occurred and the LEB has to be returned to lprops */
ubifs_assert(err < 0); ubifs_assert(c, err < 0);
err1 = ubifs_return_leb(c, lnum); err1 = ubifs_return_leb(c, lnum);
if (err1 && err == -EAGAIN) if (err1 && err == -EAGAIN)
/* /*
@ -246,7 +246,7 @@ static int write_node(struct ubifs_info *c, int jhead, void *node, int len,
{ {
struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;
ubifs_assert(jhead != GCHD); ubifs_assert(c, jhead != GCHD);
*lnum = c->jheads[jhead].wbuf.lnum; *lnum = c->jheads[jhead].wbuf.lnum;
*offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;
@ -278,7 +278,7 @@ static int write_head(struct ubifs_info *c, int jhead, void *buf, int len,
int err; int err;
struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf; struct ubifs_wbuf *wbuf = &c->jheads[jhead].wbuf;
ubifs_assert(jhead != GCHD); ubifs_assert(c, jhead != GCHD);
*lnum = c->jheads[jhead].wbuf.lnum; *lnum = c->jheads[jhead].wbuf.lnum;
*offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used; *offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;
@ -317,6 +317,7 @@ again:
down_read(&c->commit_sem); down_read(&c->commit_sem);
err = reserve_space(c, jhead, len); err = reserve_space(c, jhead, len);
if (!err) if (!err)
/* c->commit_sem will get released via finish_reservation(). */
return 0; return 0;
up_read(&c->commit_sem); up_read(&c->commit_sem);
@ -548,7 +549,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
struct ubifs_ino_node *ino; struct ubifs_ino_node *ino;
union ubifs_key dent_key, ino_key; union ubifs_key dent_key, ino_key;
ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex));
dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1; dlen = UBIFS_DENT_NODE_SZ + fname_len(nm) + 1;
ilen = UBIFS_INO_NODE_SZ; ilen = UBIFS_INO_NODE_SZ;
@ -664,6 +665,11 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
spin_lock(&ui->ui_lock); spin_lock(&ui->ui_lock);
ui->synced_i_size = ui->ui_size; ui->synced_i_size = ui->ui_size;
spin_unlock(&ui->ui_lock); spin_unlock(&ui->ui_lock);
if (xent) {
spin_lock(&host_ui->ui_lock);
host_ui->synced_i_size = host_ui->ui_size;
spin_unlock(&host_ui->ui_lock);
}
mark_inode_clean(c, ui); mark_inode_clean(c, ui);
mark_inode_clean(c, host_ui); mark_inode_clean(c, host_ui);
return 0; return 0;
@ -707,7 +713,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
dbg_jnlk(key, "ino %lu, blk %u, len %d, key ", dbg_jnlk(key, "ino %lu, blk %u, len %d, key ",
(unsigned long)key_inum(c, key), key_block(c, key), len); (unsigned long)key_inum(c, key), key_block(c, key), len);
ubifs_assert(len <= UBIFS_BLOCK_SIZE); ubifs_assert(c, len <= UBIFS_BLOCK_SIZE);
if (encrypted) if (encrypted)
dlen += UBIFS_CIPHER_BLOCK_SIZE; dlen += UBIFS_CIPHER_BLOCK_SIZE;
@ -738,7 +744,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
out_len = compr_len = dlen - UBIFS_DATA_NODE_SZ; out_len = compr_len = dlen - UBIFS_DATA_NODE_SZ;
ubifs_compress(c, buf, len, &data->data, &compr_len, &compr_type); ubifs_compress(c, buf, len, &data->data, &compr_len, &compr_type);
ubifs_assert(compr_len <= UBIFS_BLOCK_SIZE); ubifs_assert(c, compr_len <= UBIFS_BLOCK_SIZE);
if (encrypted) { if (encrypted) {
err = ubifs_encrypt(inode, data, compr_len, &out_len, key_block(c, key)); err = ubifs_encrypt(inode, data, compr_len, &out_len, key_block(c, key));
@ -898,7 +904,7 @@ int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode)
int err; int err;
struct ubifs_inode *ui = ubifs_inode(inode); struct ubifs_inode *ui = ubifs_inode(inode);
ubifs_assert(inode->i_nlink == 0); ubifs_assert(c, inode->i_nlink == 0);
if (ui->del_cmtno != c->cmt_no) if (ui->del_cmtno != c->cmt_no)
/* A commit happened for sure */ /* A commit happened for sure */
@ -953,10 +959,10 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
int twoparents = (fst_dir != snd_dir); int twoparents = (fst_dir != snd_dir);
void *p; void *p;
ubifs_assert(ubifs_inode(fst_dir)->data_len == 0); ubifs_assert(c, ubifs_inode(fst_dir)->data_len == 0);
ubifs_assert(ubifs_inode(snd_dir)->data_len == 0); ubifs_assert(c, ubifs_inode(snd_dir)->data_len == 0);
ubifs_assert(mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ubifs_inode(fst_dir)->ui_mutex));
ubifs_assert(mutex_is_locked(&ubifs_inode(snd_dir)->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ubifs_inode(snd_dir)->ui_mutex));
dlen1 = UBIFS_DENT_NODE_SZ + fname_len(snd_nm) + 1; dlen1 = UBIFS_DENT_NODE_SZ + fname_len(snd_nm) + 1;
dlen2 = UBIFS_DENT_NODE_SZ + fname_len(fst_nm) + 1; dlen2 = UBIFS_DENT_NODE_SZ + fname_len(fst_nm) + 1;
@ -1096,16 +1102,16 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
int move = (old_dir != new_dir); int move = (old_dir != new_dir);
struct ubifs_inode *uninitialized_var(new_ui); struct ubifs_inode *uninitialized_var(new_ui);
ubifs_assert(ubifs_inode(old_dir)->data_len == 0); ubifs_assert(c, ubifs_inode(old_dir)->data_len == 0);
ubifs_assert(ubifs_inode(new_dir)->data_len == 0); ubifs_assert(c, ubifs_inode(new_dir)->data_len == 0);
ubifs_assert(mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ubifs_inode(old_dir)->ui_mutex));
ubifs_assert(mutex_is_locked(&ubifs_inode(new_dir)->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ubifs_inode(new_dir)->ui_mutex));
dlen1 = UBIFS_DENT_NODE_SZ + fname_len(new_nm) + 1; dlen1 = UBIFS_DENT_NODE_SZ + fname_len(new_nm) + 1;
dlen2 = UBIFS_DENT_NODE_SZ + fname_len(old_nm) + 1; dlen2 = UBIFS_DENT_NODE_SZ + fname_len(old_nm) + 1;
if (new_inode) { if (new_inode) {
new_ui = ubifs_inode(new_inode); new_ui = ubifs_inode(new_inode);
ubifs_assert(mutex_is_locked(&new_ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&new_ui->ui_mutex));
ilen = UBIFS_INO_NODE_SZ; ilen = UBIFS_INO_NODE_SZ;
if (!last_reference) if (!last_reference)
ilen += new_ui->data_len; ilen += new_ui->data_len;
@ -1282,8 +1288,7 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in
int *new_len) int *new_len)
{ {
void *buf; void *buf;
int err, compr_type; int err, dlen, compr_type, out_len, old_dlen;
u32 dlen, out_len, old_dlen;
out_len = le32_to_cpu(dn->size); out_len = le32_to_cpu(dn->size);
buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS); buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS);
@ -1319,7 +1324,7 @@ static int truncate_data_node(const struct ubifs_info *c, const struct inode *in
dn->compr_size = 0; dn->compr_size = 0;
} }
ubifs_assert(out_len <= UBIFS_BLOCK_SIZE); ubifs_assert(c, out_len <= UBIFS_BLOCK_SIZE);
dn->compr_type = cpu_to_le16(compr_type); dn->compr_type = cpu_to_le16(compr_type);
dn->size = cpu_to_le32(*new_len); dn->size = cpu_to_le32(*new_len);
*new_len = UBIFS_DATA_NODE_SZ + out_len; *new_len = UBIFS_DATA_NODE_SZ + out_len;
@ -1358,9 +1363,9 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
dbg_jnl("ino %lu, size %lld -> %lld", dbg_jnl("ino %lu, size %lld -> %lld",
(unsigned long)inum, old_size, new_size); (unsigned long)inum, old_size, new_size);
ubifs_assert(!ui->data_len); ubifs_assert(c, !ui->data_len);
ubifs_assert(S_ISREG(inode->i_mode)); ubifs_assert(c, S_ISREG(inode->i_mode));
ubifs_assert(mutex_is_locked(&ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ + sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ +
UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR; UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR;
@ -1388,7 +1393,16 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
else if (err) else if (err)
goto out_free; goto out_free;
else { else {
if (le32_to_cpu(dn->size) <= dlen) int dn_len = le32_to_cpu(dn->size);
if (dn_len <= 0 || dn_len > UBIFS_BLOCK_SIZE) {
ubifs_err(c, "bad data node (block %u, inode %lu)",
blk, inode->i_ino);
ubifs_dump_node(c, dn);
goto out_free;
}
if (dn_len <= dlen)
dlen = 0; /* Nothing to do */ dlen = 0; /* Nothing to do */
else { else {
err = truncate_data_node(c, inode, blk, dn, &dlen); err = truncate_data_node(c, inode, blk, dn, &dlen);
@ -1488,8 +1502,8 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,
int sync = IS_DIRSYNC(host); int sync = IS_DIRSYNC(host);
struct ubifs_inode *host_ui = ubifs_inode(host); struct ubifs_inode *host_ui = ubifs_inode(host);
ubifs_assert(inode->i_nlink == 0); ubifs_assert(c, inode->i_nlink == 0);
ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex));
/* /*
* Since we are deleting the inode, we do not bother to attach any data * Since we are deleting the inode, we do not bother to attach any data
@ -1598,9 +1612,9 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode,
int sync = IS_DIRSYNC(host); int sync = IS_DIRSYNC(host);
dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino); dbg_jnl("ino %lu, ino %lu", host->i_ino, inode->i_ino);
ubifs_assert(host->i_nlink > 0); ubifs_assert(c, host->i_nlink > 0);
ubifs_assert(inode->i_nlink > 0); ubifs_assert(c, inode->i_nlink > 0);
ubifs_assert(mutex_is_locked(&host_ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&host_ui->ui_mutex));
len1 = UBIFS_INO_NODE_SZ + host_ui->data_len; len1 = UBIFS_INO_NODE_SZ + host_ui->data_len;
len2 = UBIFS_INO_NODE_SZ + ubifs_inode(inode)->data_len; len2 = UBIFS_INO_NODE_SZ + ubifs_inode(inode)->data_len;

View File

@ -161,8 +161,8 @@ static inline void dent_key_init(const struct ubifs_info *c,
{ {
uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
ubifs_assert(!nm->hash && !nm->minor_hash); ubifs_assert(c, !nm->hash && !nm->minor_hash);
key->u32[0] = inum; key->u32[0] = inum;
key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
} }
@ -179,7 +179,7 @@ static inline void dent_key_init_hash(const struct ubifs_info *c,
union ubifs_key *key, ino_t inum, union ubifs_key *key, ino_t inum,
uint32_t hash) uint32_t hash)
{ {
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
key->u32[0] = inum; key->u32[0] = inum;
key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS);
} }
@ -198,7 +198,7 @@ static inline void dent_key_init_flash(const struct ubifs_info *c, void *k,
union ubifs_key *key = k; union ubifs_key *key = k;
uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
key->j32[0] = cpu_to_le32(inum); key->j32[0] = cpu_to_le32(inum);
key->j32[1] = cpu_to_le32(hash | key->j32[1] = cpu_to_le32(hash |
(UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS)); (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS));
@ -231,7 +231,7 @@ static inline void xent_key_init(const struct ubifs_info *c,
{ {
uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
key->u32[0] = inum; key->u32[0] = inum;
key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS); key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
} }
@ -249,7 +249,7 @@ static inline void xent_key_init_flash(const struct ubifs_info *c, void *k,
union ubifs_key *key = k; union ubifs_key *key = k;
uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm));
ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK));
key->j32[0] = cpu_to_le32(inum); key->j32[0] = cpu_to_le32(inum);
key->j32[1] = cpu_to_le32(hash | key->j32[1] = cpu_to_le32(hash |
(UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS)); (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS));
@ -280,7 +280,7 @@ static inline void data_key_init(const struct ubifs_info *c,
union ubifs_key *key, ino_t inum, union ubifs_key *key, ino_t inum,
unsigned int block) unsigned int block)
{ {
ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK)); ubifs_assert(c, !(block & ~UBIFS_S_KEY_BLOCK_MASK));
key->u32[0] = inum; key->u32[0] = inum;
key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS); key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS);
} }

View File

@ -132,7 +132,7 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud)
while (*p) { while (*p) {
parent = *p; parent = *p;
b = rb_entry(parent, struct ubifs_bud, rb); b = rb_entry(parent, struct ubifs_bud, rb);
ubifs_assert(bud->lnum != b->lnum); ubifs_assert(c, bud->lnum != b->lnum);
if (bud->lnum < b->lnum) if (bud->lnum < b->lnum)
p = &(*p)->rb_left; p = &(*p)->rb_left;
else else
@ -145,7 +145,7 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud)
jhead = &c->jheads[bud->jhead]; jhead = &c->jheads[bud->jhead];
list_add_tail(&bud->list, &jhead->buds_list); list_add_tail(&bud->list, &jhead->buds_list);
} else } else
ubifs_assert(c->replaying && c->ro_mount); ubifs_assert(c, c->replaying && c->ro_mount);
/* /*
* Note, although this is a new bud, we anyway account this space now, * Note, although this is a new bud, we anyway account this space now,
@ -189,7 +189,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
} }
mutex_lock(&c->log_mutex); mutex_lock(&c->log_mutex);
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) { if (c->ro_error) {
err = -EROFS; err = -EROFS;
goto out_unlock; goto out_unlock;
@ -244,7 +244,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
if (c->lhead_offs > c->leb_size - c->ref_node_alsz) { if (c->lhead_offs > c->leb_size - c->ref_node_alsz) {
c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum); c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum);
ubifs_assert(c->lhead_lnum != c->ltail_lnum); ubifs_assert(c, c->lhead_lnum != c->ltail_lnum);
c->lhead_offs = 0; c->lhead_offs = 0;
} }
@ -301,7 +301,7 @@ static void remove_buds(struct ubifs_info *c)
{ {
struct rb_node *p; struct rb_node *p;
ubifs_assert(list_empty(&c->old_buds)); ubifs_assert(c, list_empty(&c->old_buds));
c->cmt_bud_bytes = 0; c->cmt_bud_bytes = 0;
spin_lock(&c->buds_lock); spin_lock(&c->buds_lock);
p = rb_first(&c->buds); p = rb_first(&c->buds);
@ -409,7 +409,7 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum)
/* Switch to the next log LEB */ /* Switch to the next log LEB */
if (c->lhead_offs) { if (c->lhead_offs) {
c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum); c->lhead_lnum = ubifs_next_log_lnum(c, c->lhead_lnum);
ubifs_assert(c->lhead_lnum != c->ltail_lnum); ubifs_assert(c, c->lhead_lnum != c->ltail_lnum);
c->lhead_offs = 0; c->lhead_offs = 0;
} }

View File

@ -187,9 +187,9 @@ static int add_to_lpt_heap(struct ubifs_info *c, struct ubifs_lprops *lprops,
/* Compare to some other LEB on the bottom of heap */ /* Compare to some other LEB on the bottom of heap */
/* Pick a position kind of randomly */ /* Pick a position kind of randomly */
cpos = (((size_t)lprops >> 4) & b) + b; cpos = (((size_t)lprops >> 4) & b) + b;
ubifs_assert(cpos >= b); ubifs_assert(c, cpos >= b);
ubifs_assert(cpos < LPT_HEAP_SZ); ubifs_assert(c, cpos < LPT_HEAP_SZ);
ubifs_assert(cpos < heap->cnt); ubifs_assert(c, cpos < heap->cnt);
val1 = get_heap_comp_val(lprops, cat); val1 = get_heap_comp_val(lprops, cat);
val2 = get_heap_comp_val(heap->arr[cpos], cat); val2 = get_heap_comp_val(heap->arr[cpos], cat);
@ -230,8 +230,8 @@ static void remove_from_lpt_heap(struct ubifs_info *c,
int hpos = lprops->hpos; int hpos = lprops->hpos;
heap = &c->lpt_heap[cat - 1]; heap = &c->lpt_heap[cat - 1];
ubifs_assert(hpos >= 0 && hpos < heap->cnt); ubifs_assert(c, hpos >= 0 && hpos < heap->cnt);
ubifs_assert(heap->arr[hpos] == lprops); ubifs_assert(c, heap->arr[hpos] == lprops);
heap->cnt -= 1; heap->cnt -= 1;
if (hpos < heap->cnt) { if (hpos < heap->cnt) {
heap->arr[hpos] = heap->arr[heap->cnt]; heap->arr[hpos] = heap->arr[heap->cnt];
@ -296,13 +296,13 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
list_add(&lprops->list, &c->frdi_idx_list); list_add(&lprops->list, &c->frdi_idx_list);
break; break;
default: default:
ubifs_assert(0); ubifs_assert(c, 0);
} }
lprops->flags &= ~LPROPS_CAT_MASK; lprops->flags &= ~LPROPS_CAT_MASK;
lprops->flags |= cat; lprops->flags |= cat;
c->in_a_category_cnt += 1; c->in_a_category_cnt += 1;
ubifs_assert(c->in_a_category_cnt <= c->main_lebs); ubifs_assert(c, c->in_a_category_cnt <= c->main_lebs);
} }
/** /**
@ -324,20 +324,20 @@ static void ubifs_remove_from_cat(struct ubifs_info *c,
break; break;
case LPROPS_FREEABLE: case LPROPS_FREEABLE:
c->freeable_cnt -= 1; c->freeable_cnt -= 1;
ubifs_assert(c->freeable_cnt >= 0); ubifs_assert(c, c->freeable_cnt >= 0);
/* Fall through */ /* Fall through */
case LPROPS_UNCAT: case LPROPS_UNCAT:
case LPROPS_EMPTY: case LPROPS_EMPTY:
case LPROPS_FRDI_IDX: case LPROPS_FRDI_IDX:
ubifs_assert(!list_empty(&lprops->list)); ubifs_assert(c, !list_empty(&lprops->list));
list_del(&lprops->list); list_del(&lprops->list);
break; break;
default: default:
ubifs_assert(0); ubifs_assert(c, 0);
} }
c->in_a_category_cnt -= 1; c->in_a_category_cnt -= 1;
ubifs_assert(c->in_a_category_cnt >= 0); ubifs_assert(c, c->in_a_category_cnt >= 0);
} }
/** /**
@ -369,7 +369,7 @@ void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops,
list_replace(&old_lprops->list, &new_lprops->list); list_replace(&old_lprops->list, &new_lprops->list);
break; break;
default: default:
ubifs_assert(0); ubifs_assert(c, 0);
} }
} }
@ -412,7 +412,7 @@ int ubifs_categorize_lprops(const struct ubifs_info *c,
return LPROPS_UNCAT; return LPROPS_UNCAT;
if (lprops->free == c->leb_size) { if (lprops->free == c->leb_size) {
ubifs_assert(!(lprops->flags & LPROPS_INDEX)); ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
return LPROPS_EMPTY; return LPROPS_EMPTY;
} }
@ -478,7 +478,7 @@ static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops)
*/ */
int ubifs_calc_dark(const struct ubifs_info *c, int spc) int ubifs_calc_dark(const struct ubifs_info *c, int spc)
{ {
ubifs_assert(!(spc & 7)); ubifs_assert(c, !(spc & 7));
if (spc < c->dark_wm) if (spc < c->dark_wm)
return spc; return spc;
@ -543,27 +543,27 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
dbg_lp("LEB %d, free %d, dirty %d, flags %d", dbg_lp("LEB %d, free %d, dirty %d, flags %d",
lprops->lnum, free, dirty, flags); lprops->lnum, free, dirty, flags);
ubifs_assert(mutex_is_locked(&c->lp_mutex)); ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
ubifs_assert(c->lst.empty_lebs >= 0 && ubifs_assert(c, c->lst.empty_lebs >= 0 &&
c->lst.empty_lebs <= c->main_lebs); c->lst.empty_lebs <= c->main_lebs);
ubifs_assert(c->freeable_cnt >= 0); ubifs_assert(c, c->freeable_cnt >= 0);
ubifs_assert(c->freeable_cnt <= c->main_lebs); ubifs_assert(c, c->freeable_cnt <= c->main_lebs);
ubifs_assert(c->lst.taken_empty_lebs >= 0); ubifs_assert(c, c->lst.taken_empty_lebs >= 0);
ubifs_assert(c->lst.taken_empty_lebs <= c->lst.empty_lebs); ubifs_assert(c, c->lst.taken_empty_lebs <= c->lst.empty_lebs);
ubifs_assert(!(c->lst.total_free & 7) && !(c->lst.total_dirty & 7)); ubifs_assert(c, !(c->lst.total_free & 7) && !(c->lst.total_dirty & 7));
ubifs_assert(!(c->lst.total_dead & 7) && !(c->lst.total_dark & 7)); ubifs_assert(c, !(c->lst.total_dead & 7) && !(c->lst.total_dark & 7));
ubifs_assert(!(c->lst.total_used & 7)); ubifs_assert(c, !(c->lst.total_used & 7));
ubifs_assert(free == LPROPS_NC || free >= 0); ubifs_assert(c, free == LPROPS_NC || free >= 0);
ubifs_assert(dirty == LPROPS_NC || dirty >= 0); ubifs_assert(c, dirty == LPROPS_NC || dirty >= 0);
if (!is_lprops_dirty(c, lprops)) { if (!is_lprops_dirty(c, lprops)) {
lprops = ubifs_lpt_lookup_dirty(c, lprops->lnum); lprops = ubifs_lpt_lookup_dirty(c, lprops->lnum);
if (IS_ERR(lprops)) if (IS_ERR(lprops))
return lprops; return lprops;
} else } else
ubifs_assert(lprops == ubifs_lpt_lookup_dirty(c, lprops->lnum)); ubifs_assert(c, lprops == ubifs_lpt_lookup_dirty(c, lprops->lnum));
ubifs_assert(!(lprops->free & 7) && !(lprops->dirty & 7)); ubifs_assert(c, !(lprops->free & 7) && !(lprops->dirty & 7));
spin_lock(&c->space_lock); spin_lock(&c->space_lock);
if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size) if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size)
@ -768,15 +768,15 @@ const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c)
struct ubifs_lprops *lprops; struct ubifs_lprops *lprops;
struct ubifs_lpt_heap *heap; struct ubifs_lpt_heap *heap;
ubifs_assert(mutex_is_locked(&c->lp_mutex)); ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
heap = &c->lpt_heap[LPROPS_FREE - 1]; heap = &c->lpt_heap[LPROPS_FREE - 1];
if (heap->cnt == 0) if (heap->cnt == 0)
return NULL; return NULL;
lprops = heap->arr[0]; lprops = heap->arr[0];
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert(!(lprops->flags & LPROPS_INDEX)); ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
return lprops; return lprops;
} }
@ -791,15 +791,15 @@ const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c)
{ {
struct ubifs_lprops *lprops; struct ubifs_lprops *lprops;
ubifs_assert(mutex_is_locked(&c->lp_mutex)); ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
if (list_empty(&c->empty_list)) if (list_empty(&c->empty_list))
return NULL; return NULL;
lprops = list_entry(c->empty_list.next, struct ubifs_lprops, list); lprops = list_entry(c->empty_list.next, struct ubifs_lprops, list);
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert(!(lprops->flags & LPROPS_INDEX)); ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
ubifs_assert(lprops->free == c->leb_size); ubifs_assert(c, lprops->free == c->leb_size);
return lprops; return lprops;
} }
@ -814,16 +814,16 @@ const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c)
{ {
struct ubifs_lprops *lprops; struct ubifs_lprops *lprops;
ubifs_assert(mutex_is_locked(&c->lp_mutex)); ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
if (list_empty(&c->freeable_list)) if (list_empty(&c->freeable_list))
return NULL; return NULL;
lprops = list_entry(c->freeable_list.next, struct ubifs_lprops, list); lprops = list_entry(c->freeable_list.next, struct ubifs_lprops, list);
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert(!(lprops->flags & LPROPS_INDEX)); ubifs_assert(c, !(lprops->flags & LPROPS_INDEX));
ubifs_assert(lprops->free + lprops->dirty == c->leb_size); ubifs_assert(c, lprops->free + lprops->dirty == c->leb_size);
ubifs_assert(c->freeable_cnt > 0); ubifs_assert(c, c->freeable_cnt > 0);
return lprops; return lprops;
} }
@ -838,15 +838,15 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c)
{ {
struct ubifs_lprops *lprops; struct ubifs_lprops *lprops;
ubifs_assert(mutex_is_locked(&c->lp_mutex)); ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
if (list_empty(&c->frdi_idx_list)) if (list_empty(&c->frdi_idx_list))
return NULL; return NULL;
lprops = list_entry(c->frdi_idx_list.next, struct ubifs_lprops, list); lprops = list_entry(c->frdi_idx_list.next, struct ubifs_lprops, list);
ubifs_assert(!(lprops->flags & LPROPS_TAKEN)); ubifs_assert(c, !(lprops->flags & LPROPS_TAKEN));
ubifs_assert((lprops->flags & LPROPS_INDEX)); ubifs_assert(c, (lprops->flags & LPROPS_INDEX));
ubifs_assert(lprops->free + lprops->dirty == c->leb_size); ubifs_assert(c, lprops->free + lprops->dirty == c->leb_size);
return lprops; return lprops;
} }
@ -1089,10 +1089,6 @@ static int scan_check_cb(struct ubifs_info *c,
} }
} }
buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
if (!buf)
return -ENOMEM;
/* /*
* After an unclean unmount, empty and freeable LEBs * After an unclean unmount, empty and freeable LEBs
* may contain garbage - do not scan them. * may contain garbage - do not scan them.
@ -1111,6 +1107,10 @@ static int scan_check_cb(struct ubifs_info *c,
return LPT_SCAN_CONTINUE; return LPT_SCAN_CONTINUE;
} }
buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
if (!buf)
return -ENOMEM;
sleb = ubifs_scan(c, lnum, 0, buf, 0); sleb = ubifs_scan(c, lnum, 0, buf, 0);
if (IS_ERR(sleb)) { if (IS_ERR(sleb)) {
ret = PTR_ERR(sleb); ret = PTR_ERR(sleb);

View File

@ -225,21 +225,22 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
/** /**
* pack_bits - pack bit fields end-to-end. * pack_bits - pack bit fields end-to-end.
* @c: UBIFS file-system description object
* @addr: address at which to pack (passed and next address returned) * @addr: address at which to pack (passed and next address returned)
* @pos: bit position at which to pack (passed and next position returned) * @pos: bit position at which to pack (passed and next position returned)
* @val: value to pack * @val: value to pack
* @nrbits: number of bits of value to pack (1-32) * @nrbits: number of bits of value to pack (1-32)
*/ */
static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits) static void pack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, uint32_t val, int nrbits)
{ {
uint8_t *p = *addr; uint8_t *p = *addr;
int b = *pos; int b = *pos;
ubifs_assert(nrbits > 0); ubifs_assert(c, nrbits > 0);
ubifs_assert(nrbits <= 32); ubifs_assert(c, nrbits <= 32);
ubifs_assert(*pos >= 0); ubifs_assert(c, *pos >= 0);
ubifs_assert(*pos < 8); ubifs_assert(c, *pos < 8);
ubifs_assert((val >> nrbits) == 0 || nrbits == 32); ubifs_assert(c, (val >> nrbits) == 0 || nrbits == 32);
if (b) { if (b) {
*p |= ((uint8_t)val) << b; *p |= ((uint8_t)val) << b;
nrbits += b; nrbits += b;
@ -274,13 +275,14 @@ static void pack_bits(uint8_t **addr, int *pos, uint32_t val, int nrbits)
/** /**
* ubifs_unpack_bits - unpack bit fields. * ubifs_unpack_bits - unpack bit fields.
* @c: UBIFS file-system description object
* @addr: address at which to unpack (passed and next address returned) * @addr: address at which to unpack (passed and next address returned)
* @pos: bit position at which to unpack (passed and next position returned) * @pos: bit position at which to unpack (passed and next position returned)
* @nrbits: number of bits of value to unpack (1-32) * @nrbits: number of bits of value to unpack (1-32)
* *
* This functions returns the value unpacked. * This functions returns the value unpacked.
*/ */
uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits) uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, int nrbits)
{ {
const int k = 32 - nrbits; const int k = 32 - nrbits;
uint8_t *p = *addr; uint8_t *p = *addr;
@ -288,10 +290,10 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
uint32_t uninitialized_var(val); uint32_t uninitialized_var(val);
const int bytes = (nrbits + b + 7) >> 3; const int bytes = (nrbits + b + 7) >> 3;
ubifs_assert(nrbits > 0); ubifs_assert(c, nrbits > 0);
ubifs_assert(nrbits <= 32); ubifs_assert(c, nrbits <= 32);
ubifs_assert(*pos >= 0); ubifs_assert(c, *pos >= 0);
ubifs_assert(*pos < 8); ubifs_assert(c, *pos < 8);
if (b) { if (b) {
switch (bytes) { switch (bytes) {
case 2: case 2:
@ -337,7 +339,7 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
p += nrbits >> 3; p += nrbits >> 3;
*addr = p; *addr = p;
*pos = b; *pos = b;
ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32); ubifs_assert(c, (val >> nrbits) == 0 || nrbits - b == 32);
return val; return val;
} }
@ -354,24 +356,24 @@ void ubifs_pack_pnode(struct ubifs_info *c, void *buf,
int i, pos = 0; int i, pos = 0;
uint16_t crc; uint16_t crc;
pack_bits(&addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS); pack_bits(c, &addr, &pos, UBIFS_LPT_PNODE, UBIFS_LPT_TYPE_BITS);
if (c->big_lpt) if (c->big_lpt)
pack_bits(&addr, &pos, pnode->num, c->pcnt_bits); pack_bits(c, &addr, &pos, pnode->num, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) { for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
pack_bits(&addr, &pos, pnode->lprops[i].free >> 3, pack_bits(c, &addr, &pos, pnode->lprops[i].free >> 3,
c->space_bits); c->space_bits);
pack_bits(&addr, &pos, pnode->lprops[i].dirty >> 3, pack_bits(c, &addr, &pos, pnode->lprops[i].dirty >> 3,
c->space_bits); c->space_bits);
if (pnode->lprops[i].flags & LPROPS_INDEX) if (pnode->lprops[i].flags & LPROPS_INDEX)
pack_bits(&addr, &pos, 1, 1); pack_bits(c, &addr, &pos, 1, 1);
else else
pack_bits(&addr, &pos, 0, 1); pack_bits(c, &addr, &pos, 0, 1);
} }
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->pnode_sz - UBIFS_LPT_CRC_BYTES); c->pnode_sz - UBIFS_LPT_CRC_BYTES);
addr = buf; addr = buf;
pos = 0; pos = 0;
pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
} }
/** /**
@ -387,23 +389,23 @@ void ubifs_pack_nnode(struct ubifs_info *c, void *buf,
int i, pos = 0; int i, pos = 0;
uint16_t crc; uint16_t crc;
pack_bits(&addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS); pack_bits(c, &addr, &pos, UBIFS_LPT_NNODE, UBIFS_LPT_TYPE_BITS);
if (c->big_lpt) if (c->big_lpt)
pack_bits(&addr, &pos, nnode->num, c->pcnt_bits); pack_bits(c, &addr, &pos, nnode->num, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) { for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
int lnum = nnode->nbranch[i].lnum; int lnum = nnode->nbranch[i].lnum;
if (lnum == 0) if (lnum == 0)
lnum = c->lpt_last + 1; lnum = c->lpt_last + 1;
pack_bits(&addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits); pack_bits(c, &addr, &pos, lnum - c->lpt_first, c->lpt_lnum_bits);
pack_bits(&addr, &pos, nnode->nbranch[i].offs, pack_bits(c, &addr, &pos, nnode->nbranch[i].offs,
c->lpt_offs_bits); c->lpt_offs_bits);
} }
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->nnode_sz - UBIFS_LPT_CRC_BYTES); c->nnode_sz - UBIFS_LPT_CRC_BYTES);
addr = buf; addr = buf;
pos = 0; pos = 0;
pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
} }
/** /**
@ -419,16 +421,16 @@ void ubifs_pack_ltab(struct ubifs_info *c, void *buf,
int i, pos = 0; int i, pos = 0;
uint16_t crc; uint16_t crc;
pack_bits(&addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS); pack_bits(c, &addr, &pos, UBIFS_LPT_LTAB, UBIFS_LPT_TYPE_BITS);
for (i = 0; i < c->lpt_lebs; i++) { for (i = 0; i < c->lpt_lebs; i++) {
pack_bits(&addr, &pos, ltab[i].free, c->lpt_spc_bits); pack_bits(c, &addr, &pos, ltab[i].free, c->lpt_spc_bits);
pack_bits(&addr, &pos, ltab[i].dirty, c->lpt_spc_bits); pack_bits(c, &addr, &pos, ltab[i].dirty, c->lpt_spc_bits);
} }
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->ltab_sz - UBIFS_LPT_CRC_BYTES); c->ltab_sz - UBIFS_LPT_CRC_BYTES);
addr = buf; addr = buf;
pos = 0; pos = 0;
pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
} }
/** /**
@ -443,14 +445,14 @@ void ubifs_pack_lsave(struct ubifs_info *c, void *buf, int *lsave)
int i, pos = 0; int i, pos = 0;
uint16_t crc; uint16_t crc;
pack_bits(&addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS); pack_bits(c, &addr, &pos, UBIFS_LPT_LSAVE, UBIFS_LPT_TYPE_BITS);
for (i = 0; i < c->lsave_cnt; i++) for (i = 0; i < c->lsave_cnt; i++)
pack_bits(&addr, &pos, lsave[i], c->lnum_bits); pack_bits(c, &addr, &pos, lsave[i], c->lnum_bits);
crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
c->lsave_sz - UBIFS_LPT_CRC_BYTES); c->lsave_sz - UBIFS_LPT_CRC_BYTES);
addr = buf; addr = buf;
pos = 0; pos = 0;
pack_bits(&addr, &pos, crc, UBIFS_LPT_CRC_BITS); pack_bits(c, &addr, &pos, crc, UBIFS_LPT_CRC_BITS);
} }
/** /**
@ -465,7 +467,7 @@ void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty)
return; return;
dbg_lp("LEB %d add %d to %d", dbg_lp("LEB %d add %d to %d",
lnum, dirty, c->ltab[lnum - c->lpt_first].dirty); lnum, dirty, c->ltab[lnum - c->lpt_first].dirty);
ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last); ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
c->ltab[lnum - c->lpt_first].dirty += dirty; c->ltab[lnum - c->lpt_first].dirty += dirty;
} }
@ -481,7 +483,7 @@ static void set_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
dbg_lp("LEB %d free %d dirty %d to %d %d", dbg_lp("LEB %d free %d dirty %d to %d %d",
lnum, c->ltab[lnum - c->lpt_first].free, lnum, c->ltab[lnum - c->lpt_first].free,
c->ltab[lnum - c->lpt_first].dirty, free, dirty); c->ltab[lnum - c->lpt_first].dirty, free, dirty);
ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last); ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
c->ltab[lnum - c->lpt_first].free = free; c->ltab[lnum - c->lpt_first].free = free;
c->ltab[lnum - c->lpt_first].dirty = dirty; c->ltab[lnum - c->lpt_first].dirty = dirty;
} }
@ -639,7 +641,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
goto out; goto out;
} }
ubifs_assert(!c->ltab); ubifs_assert(c, !c->ltab);
c->ltab = ltab; /* Needed by set_ltab */ c->ltab = ltab; /* Needed by set_ltab */
/* Initialize LPT's own lprops */ /* Initialize LPT's own lprops */
@ -918,7 +920,7 @@ static int check_lpt_crc(const struct ubifs_info *c, void *buf, int len)
uint8_t *addr = buf; uint8_t *addr = buf;
uint16_t crc, calc_crc; uint16_t crc, calc_crc;
crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS); crc = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_CRC_BITS);
calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
len - UBIFS_LPT_CRC_BYTES); len - UBIFS_LPT_CRC_BYTES);
if (crc != calc_crc) { if (crc != calc_crc) {
@ -944,7 +946,7 @@ static int check_lpt_type(const struct ubifs_info *c, uint8_t **addr,
{ {
int node_type; int node_type;
node_type = ubifs_unpack_bits(addr, pos, UBIFS_LPT_TYPE_BITS); node_type = ubifs_unpack_bits(c, addr, pos, UBIFS_LPT_TYPE_BITS);
if (node_type != type) { if (node_type != type) {
ubifs_err(c, "invalid type (%d) in LPT node type %d", ubifs_err(c, "invalid type (%d) in LPT node type %d",
node_type, type); node_type, type);
@ -972,16 +974,16 @@ static int unpack_pnode(const struct ubifs_info *c, void *buf,
if (err) if (err)
return err; return err;
if (c->big_lpt) if (c->big_lpt)
pnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits); pnode->num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) { for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
struct ubifs_lprops * const lprops = &pnode->lprops[i]; struct ubifs_lprops * const lprops = &pnode->lprops[i];
lprops->free = ubifs_unpack_bits(&addr, &pos, c->space_bits); lprops->free = ubifs_unpack_bits(c, &addr, &pos, c->space_bits);
lprops->free <<= 3; lprops->free <<= 3;
lprops->dirty = ubifs_unpack_bits(&addr, &pos, c->space_bits); lprops->dirty = ubifs_unpack_bits(c, &addr, &pos, c->space_bits);
lprops->dirty <<= 3; lprops->dirty <<= 3;
if (ubifs_unpack_bits(&addr, &pos, 1)) if (ubifs_unpack_bits(c, &addr, &pos, 1))
lprops->flags = LPROPS_INDEX; lprops->flags = LPROPS_INDEX;
else else
lprops->flags = 0; lprops->flags = 0;
@ -1009,16 +1011,16 @@ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
if (err) if (err)
return err; return err;
if (c->big_lpt) if (c->big_lpt)
nnode->num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits); nnode->num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
for (i = 0; i < UBIFS_LPT_FANOUT; i++) { for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
int lnum; int lnum;
lnum = ubifs_unpack_bits(&addr, &pos, c->lpt_lnum_bits) + lnum = ubifs_unpack_bits(c, &addr, &pos, c->lpt_lnum_bits) +
c->lpt_first; c->lpt_first;
if (lnum == c->lpt_last + 1) if (lnum == c->lpt_last + 1)
lnum = 0; lnum = 0;
nnode->nbranch[i].lnum = lnum; nnode->nbranch[i].lnum = lnum;
nnode->nbranch[i].offs = ubifs_unpack_bits(&addr, &pos, nnode->nbranch[i].offs = ubifs_unpack_bits(c, &addr, &pos,
c->lpt_offs_bits); c->lpt_offs_bits);
} }
err = check_lpt_crc(c, buf, c->nnode_sz); err = check_lpt_crc(c, buf, c->nnode_sz);
@ -1041,8 +1043,8 @@ static int unpack_ltab(const struct ubifs_info *c, void *buf)
if (err) if (err)
return err; return err;
for (i = 0; i < c->lpt_lebs; i++) { for (i = 0; i < c->lpt_lebs; i++) {
int free = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits); int free = ubifs_unpack_bits(c, &addr, &pos, c->lpt_spc_bits);
int dirty = ubifs_unpack_bits(&addr, &pos, c->lpt_spc_bits); int dirty = ubifs_unpack_bits(c, &addr, &pos, c->lpt_spc_bits);
if (free < 0 || free > c->leb_size || dirty < 0 || if (free < 0 || free > c->leb_size || dirty < 0 ||
dirty > c->leb_size || free + dirty > c->leb_size) dirty > c->leb_size || free + dirty > c->leb_size)
@ -1073,7 +1075,7 @@ static int unpack_lsave(const struct ubifs_info *c, void *buf)
if (err) if (err)
return err; return err;
for (i = 0; i < c->lsave_cnt; i++) { for (i = 0; i < c->lsave_cnt; i++) {
int lnum = ubifs_unpack_bits(&addr, &pos, c->lnum_bits); int lnum = ubifs_unpack_bits(c, &addr, &pos, c->lnum_bits);
if (lnum < c->main_first || lnum >= c->leb_cnt) if (lnum < c->main_first || lnum >= c->leb_cnt)
return -EINVAL; return -EINVAL;
@ -1515,7 +1517,7 @@ static struct ubifs_nnode *dirty_cow_nnode(struct ubifs_info *c,
branch->cnode->parent = n; branch->cnode->parent = n;
} }
ubifs_assert(!test_bit(OBSOLETE_CNODE, &nnode->flags)); ubifs_assert(c, !test_bit(OBSOLETE_CNODE, &nnode->flags));
__set_bit(OBSOLETE_CNODE, &nnode->flags); __set_bit(OBSOLETE_CNODE, &nnode->flags);
c->dirty_nn_cnt += 1; c->dirty_nn_cnt += 1;
@ -1558,7 +1560,7 @@ static struct ubifs_pnode *dirty_cow_pnode(struct ubifs_info *c,
__clear_bit(COW_CNODE, &p->flags); __clear_bit(COW_CNODE, &p->flags);
replace_cats(c, pnode, p); replace_cats(c, pnode, p);
ubifs_assert(!test_bit(OBSOLETE_CNODE, &pnode->flags)); ubifs_assert(c, !test_bit(OBSOLETE_CNODE, &pnode->flags));
__set_bit(OBSOLETE_CNODE, &pnode->flags); __set_bit(OBSOLETE_CNODE, &pnode->flags);
c->dirty_pn_cnt += 1; c->dirty_pn_cnt += 1;
@ -1613,7 +1615,7 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum)
dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum, dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
pnode->lprops[iip].free, pnode->lprops[iip].dirty, pnode->lprops[iip].free, pnode->lprops[iip].dirty,
pnode->lprops[iip].flags); pnode->lprops[iip].flags);
ubifs_assert(test_bit(DIRTY_CNODE, &pnode->flags)); ubifs_assert(c, test_bit(DIRTY_CNODE, &pnode->flags));
return &pnode->lprops[iip]; return &pnode->lprops[iip];
} }
@ -1889,9 +1891,9 @@ static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,
lprops->flags = ubifs_categorize_lprops(c, lprops); lprops->flags = ubifs_categorize_lprops(c, lprops);
} }
} else { } else {
ubifs_assert(branch->lnum >= c->lpt_first && ubifs_assert(c, branch->lnum >= c->lpt_first &&
branch->lnum <= c->lpt_last); branch->lnum <= c->lpt_last);
ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size); ubifs_assert(c, branch->offs >= 0 && branch->offs < c->leb_size);
err = ubifs_leb_read(c, branch->lnum, buf, branch->offs, err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
c->pnode_sz, 1); c->pnode_sz, 1);
if (err) if (err)
@ -1935,8 +1937,8 @@ int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum,
start_lnum = c->main_first; start_lnum = c->main_first;
} }
ubifs_assert(start_lnum >= c->main_first && start_lnum < c->leb_cnt); ubifs_assert(c, start_lnum >= c->main_first && start_lnum < c->leb_cnt);
ubifs_assert(end_lnum >= c->main_first && end_lnum < c->leb_cnt); ubifs_assert(c, end_lnum >= c->main_first && end_lnum < c->leb_cnt);
if (!c->nroot) { if (!c->nroot) {
err = ubifs_read_nnode(c, NULL, 0); err = ubifs_read_nnode(c, NULL, 0);
@ -2055,7 +2057,7 @@ again:
iip = pnode->iip; iip = pnode->iip;
while (1) { while (1) {
h -= 1; h -= 1;
ubifs_assert(h >= 0); ubifs_assert(c, h >= 0);
nnode = path[h].ptr.nnode; nnode = path[h].ptr.nnode;
if (iip + 1 < UBIFS_LPT_FANOUT) if (iip + 1 < UBIFS_LPT_FANOUT)
break; break;
@ -2234,7 +2236,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
return 0; return 0;
while (cnode) { while (cnode) {
ubifs_assert(row >= 0); ubifs_assert(c, row >= 0);
nnode = cnode->parent; nnode = cnode->parent;
if (cnode->level) { if (cnode->level) {
/* cnode is a nnode */ /* cnode is a nnode */

View File

@ -34,13 +34,14 @@ static int dbg_populate_lsave(struct ubifs_info *c);
/** /**
* first_dirty_cnode - find first dirty cnode. * first_dirty_cnode - find first dirty cnode.
* @c: UBIFS file-system description object
* @nnode: nnode at which to start * @nnode: nnode at which to start
* *
* This function returns the first dirty cnode or %NULL if there is not one. * This function returns the first dirty cnode or %NULL if there is not one.
*/ */
static struct ubifs_cnode *first_dirty_cnode(struct ubifs_nnode *nnode) static struct ubifs_cnode *first_dirty_cnode(const struct ubifs_info *c, struct ubifs_nnode *nnode)
{ {
ubifs_assert(nnode); ubifs_assert(c, nnode);
while (1) { while (1) {
int i, cont = 0; int i, cont = 0;
@ -64,16 +65,17 @@ static struct ubifs_cnode *first_dirty_cnode(struct ubifs_nnode *nnode)
/** /**
* next_dirty_cnode - find next dirty cnode. * next_dirty_cnode - find next dirty cnode.
* @c: UBIFS file-system description object
* @cnode: cnode from which to begin searching * @cnode: cnode from which to begin searching
* *
* This function returns the next dirty cnode or %NULL if there is not one. * This function returns the next dirty cnode or %NULL if there is not one.
*/ */
static struct ubifs_cnode *next_dirty_cnode(struct ubifs_cnode *cnode) static struct ubifs_cnode *next_dirty_cnode(const struct ubifs_info *c, struct ubifs_cnode *cnode)
{ {
struct ubifs_nnode *nnode; struct ubifs_nnode *nnode;
int i; int i;
ubifs_assert(cnode); ubifs_assert(c, cnode);
nnode = cnode->parent; nnode = cnode->parent;
if (!nnode) if (!nnode)
return NULL; return NULL;
@ -83,7 +85,7 @@ static struct ubifs_cnode *next_dirty_cnode(struct ubifs_cnode *cnode)
if (cnode->level == 0) if (cnode->level == 0)
return cnode; /* cnode is a pnode */ return cnode; /* cnode is a pnode */
/* cnode is a nnode */ /* cnode is a nnode */
return first_dirty_cnode((struct ubifs_nnode *)cnode); return first_dirty_cnode(c, (struct ubifs_nnode *)cnode);
} }
} }
return (struct ubifs_cnode *)nnode; return (struct ubifs_cnode *)nnode;
@ -106,15 +108,15 @@ static int get_cnodes_to_commit(struct ubifs_info *c)
if (!test_bit(DIRTY_CNODE, &c->nroot->flags)) if (!test_bit(DIRTY_CNODE, &c->nroot->flags))
return 0; return 0;
c->lpt_cnext = first_dirty_cnode(c->nroot); c->lpt_cnext = first_dirty_cnode(c, c->nroot);
cnode = c->lpt_cnext; cnode = c->lpt_cnext;
if (!cnode) if (!cnode)
return 0; return 0;
cnt += 1; cnt += 1;
while (1) { while (1) {
ubifs_assert(!test_bit(COW_CNODE, &cnode->flags)); ubifs_assert(c, !test_bit(COW_CNODE, &cnode->flags));
__set_bit(COW_CNODE, &cnode->flags); __set_bit(COW_CNODE, &cnode->flags);
cnext = next_dirty_cnode(cnode); cnext = next_dirty_cnode(c, cnode);
if (!cnext) { if (!cnext) {
cnode->cnext = c->lpt_cnext; cnode->cnext = c->lpt_cnext;
break; break;
@ -125,7 +127,7 @@ static int get_cnodes_to_commit(struct ubifs_info *c)
} }
dbg_cmt("committing %d cnodes", cnt); dbg_cmt("committing %d cnodes", cnt);
dbg_lp("committing %d cnodes", cnt); dbg_lp("committing %d cnodes", cnt);
ubifs_assert(cnt == c->dirty_nn_cnt + c->dirty_pn_cnt); ubifs_assert(c, cnt == c->dirty_nn_cnt + c->dirty_pn_cnt);
return cnt; return cnt;
} }
@ -141,7 +143,7 @@ static void upd_ltab(struct ubifs_info *c, int lnum, int free, int dirty)
dbg_lp("LEB %d free %d dirty %d to %d +%d", dbg_lp("LEB %d free %d dirty %d to %d +%d",
lnum, c->ltab[lnum - c->lpt_first].free, lnum, c->ltab[lnum - c->lpt_first].free,
c->ltab[lnum - c->lpt_first].dirty, free, dirty); c->ltab[lnum - c->lpt_first].dirty, free, dirty);
ubifs_assert(lnum >= c->lpt_first && lnum <= c->lpt_last); ubifs_assert(c, lnum >= c->lpt_first && lnum <= c->lpt_last);
c->ltab[lnum - c->lpt_first].free = free; c->ltab[lnum - c->lpt_first].free = free;
c->ltab[lnum - c->lpt_first].dirty += dirty; c->ltab[lnum - c->lpt_first].dirty += dirty;
} }
@ -237,7 +239,7 @@ static int layout_cnodes(struct ubifs_info *c)
if (err) if (err)
goto no_space; goto no_space;
offs = 0; offs = 0;
ubifs_assert(lnum >= c->lpt_first && ubifs_assert(c, lnum >= c->lpt_first &&
lnum <= c->lpt_last); lnum <= c->lpt_last);
/* Try to place lsave and ltab nicely */ /* Try to place lsave and ltab nicely */
if (!done_lsave) { if (!done_lsave) {
@ -280,7 +282,7 @@ static int layout_cnodes(struct ubifs_info *c)
if (err) if (err)
goto no_space; goto no_space;
offs = 0; offs = 0;
ubifs_assert(lnum >= c->lpt_first && ubifs_assert(c, lnum >= c->lpt_first &&
lnum <= c->lpt_last); lnum <= c->lpt_last);
} }
done_lsave = 1; done_lsave = 1;
@ -300,7 +302,7 @@ static int layout_cnodes(struct ubifs_info *c)
if (err) if (err)
goto no_space; goto no_space;
offs = 0; offs = 0;
ubifs_assert(lnum >= c->lpt_first && ubifs_assert(c, lnum >= c->lpt_first &&
lnum <= c->lpt_last); lnum <= c->lpt_last);
} }
c->ltab_lnum = lnum; c->ltab_lnum = lnum;
@ -423,7 +425,7 @@ static int write_cnodes(struct ubifs_info *c)
if (err) if (err)
goto no_space; goto no_space;
offs = from = 0; offs = from = 0;
ubifs_assert(lnum >= c->lpt_first && ubifs_assert(c, lnum >= c->lpt_first &&
lnum <= c->lpt_last); lnum <= c->lpt_last);
err = ubifs_leb_unmap(c, lnum); err = ubifs_leb_unmap(c, lnum);
if (err) if (err)
@ -480,7 +482,7 @@ static int write_cnodes(struct ubifs_info *c)
if (err) if (err)
goto no_space; goto no_space;
offs = from = 0; offs = from = 0;
ubifs_assert(lnum >= c->lpt_first && ubifs_assert(c, lnum >= c->lpt_first &&
lnum <= c->lpt_last); lnum <= c->lpt_last);
err = ubifs_leb_unmap(c, lnum); err = ubifs_leb_unmap(c, lnum);
if (err) if (err)
@ -506,7 +508,7 @@ static int write_cnodes(struct ubifs_info *c)
if (err) if (err)
goto no_space; goto no_space;
offs = from = 0; offs = from = 0;
ubifs_assert(lnum >= c->lpt_first && ubifs_assert(c, lnum >= c->lpt_first &&
lnum <= c->lpt_last); lnum <= c->lpt_last);
err = ubifs_leb_unmap(c, lnum); err = ubifs_leb_unmap(c, lnum);
if (err) if (err)
@ -806,7 +808,7 @@ static void populate_lsave(struct ubifs_info *c)
struct ubifs_lpt_heap *heap; struct ubifs_lpt_heap *heap;
int i, cnt = 0; int i, cnt = 0;
ubifs_assert(c->big_lpt); ubifs_assert(c, c->big_lpt);
if (!(c->lpt_drty_flgs & LSAVE_DIRTY)) { if (!(c->lpt_drty_flgs & LSAVE_DIRTY)) {
c->lpt_drty_flgs |= LSAVE_DIRTY; c->lpt_drty_flgs |= LSAVE_DIRTY;
ubifs_add_lpt_dirt(c, c->lsave_lnum, c->lsave_sz); ubifs_add_lpt_dirt(c, c->lsave_lnum, c->lsave_sz);
@ -1095,8 +1097,8 @@ static int get_lpt_node_type(const struct ubifs_info *c, uint8_t *buf,
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES; uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int pos = 0, node_type; int pos = 0, node_type;
node_type = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_TYPE_BITS); node_type = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_TYPE_BITS);
*node_num = ubifs_unpack_bits(&addr, &pos, c->pcnt_bits); *node_num = ubifs_unpack_bits(c, &addr, &pos, c->pcnt_bits);
return node_type; return node_type;
} }
@ -1116,7 +1118,7 @@ static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len)
if (len < UBIFS_LPT_CRC_BYTES + (UBIFS_LPT_TYPE_BITS + 7) / 8) if (len < UBIFS_LPT_CRC_BYTES + (UBIFS_LPT_TYPE_BITS + 7) / 8)
return 0; return 0;
node_type = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_TYPE_BITS); node_type = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_TYPE_BITS);
if (node_type == UBIFS_LPT_NOT_A_NODE) if (node_type == UBIFS_LPT_NOT_A_NODE)
return 0; return 0;
node_len = get_lpt_node_len(c, node_type); node_len = get_lpt_node_len(c, node_type);
@ -1124,7 +1126,7 @@ static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len)
return 0; return 0;
pos = 0; pos = 0;
addr = buf; addr = buf;
crc = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_CRC_BITS); crc = ubifs_unpack_bits(c, &addr, &pos, UBIFS_LPT_CRC_BITS);
calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES, calc_crc = crc16(-1, buf + UBIFS_LPT_CRC_BYTES,
node_len - UBIFS_LPT_CRC_BYTES); node_len - UBIFS_LPT_CRC_BYTES);
if (crc != calc_crc) if (crc != calc_crc)
@ -1170,7 +1172,7 @@ static int lpt_gc_lnum(struct ubifs_info *c, int lnum)
node_type = get_lpt_node_type(c, buf, &node_num); node_type = get_lpt_node_type(c, buf, &node_num);
node_len = get_lpt_node_len(c, node_type); node_len = get_lpt_node_len(c, node_type);
offs = c->leb_size - len; offs = c->leb_size - len;
ubifs_assert(node_len != 0); ubifs_assert(c, node_len != 0);
mutex_lock(&c->lp_mutex); mutex_lock(&c->lp_mutex);
err = make_node_dirty(c, node_type, node_num, lnum, offs); err = make_node_dirty(c, node_type, node_num, lnum, offs);
mutex_unlock(&c->lp_mutex); mutex_unlock(&c->lp_mutex);
@ -1195,7 +1197,7 @@ static int lpt_gc(struct ubifs_info *c)
mutex_lock(&c->lp_mutex); mutex_lock(&c->lp_mutex);
for (i = 0; i < c->lpt_lebs; i++) { for (i = 0; i < c->lpt_lebs; i++) {
ubifs_assert(!c->ltab[i].tgc); ubifs_assert(c, !c->ltab[i].tgc);
if (i + c->lpt_first == c->nhead_lnum || if (i + c->lpt_first == c->nhead_lnum ||
c->ltab[i].free + c->ltab[i].dirty == c->leb_size) c->ltab[i].free + c->ltab[i].dirty == c->leb_size)
continue; continue;
@ -1271,7 +1273,7 @@ int ubifs_lpt_start_commit(struct ubifs_info *c)
populate_lsave(c); populate_lsave(c);
cnt = get_cnodes_to_commit(c); cnt = get_cnodes_to_commit(c);
ubifs_assert(cnt != 0); ubifs_assert(c, cnt != 0);
err = layout_cnodes(c); err = layout_cnodes(c);
if (err) if (err)

View File

@ -360,7 +360,7 @@ int ubifs_write_master(struct ubifs_info *c)
{ {
int err, lnum, offs, len; int err, lnum, offs, len;
ubifs_assert(!c->ro_media && !c->ro_mount); ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) if (c->ro_error)
return -EROFS; return -EROFS;

View File

@ -56,3 +56,14 @@ void ubifs_warn(const struct ubifs_info *c, const char *fmt, ...)
va_end(args); va_end(args);
} }
static char *assert_names[] = {
[ASSACT_REPORT] = "report",
[ASSACT_RO] = "read-only",
[ASSACT_PANIC] = "panic",
};
const char *ubifs_assert_action_name(struct ubifs_info *c)
{
return assert_names[c->assert_action];
}

View File

@ -105,25 +105,27 @@ static inline struct ubifs_inode *ubifs_inode(const struct inode *inode)
/** /**
* ubifs_compr_present - check if compressor was compiled in. * ubifs_compr_present - check if compressor was compiled in.
* @compr_type: compressor type to check * @compr_type: compressor type to check
* @c: the UBIFS file-system description object
* *
* This function returns %1 of compressor of type @compr_type is present, and * This function returns %1 of compressor of type @compr_type is present, and
* %0 if not. * %0 if not.
*/ */
static inline int ubifs_compr_present(int compr_type) static inline int ubifs_compr_present(struct ubifs_info *c, int compr_type)
{ {
ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); ubifs_assert(c, compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT);
return !!ubifs_compressors[compr_type]->capi_name; return !!ubifs_compressors[compr_type]->capi_name;
} }
/** /**
* ubifs_compr_name - get compressor name string by its type. * ubifs_compr_name - get compressor name string by its type.
* @compr_type: compressor type * @compr_type: compressor type
* @c: the UBIFS file-system description object
* *
* This function returns compressor type string. * This function returns compressor type string.
*/ */
static inline const char *ubifs_compr_name(int compr_type) static inline const char *ubifs_compr_name(struct ubifs_info *c, int compr_type)
{ {
ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); ubifs_assert(c, compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT);
return ubifs_compressors[compr_type]->name; return ubifs_compressors[compr_type]->name;
} }
@ -262,8 +264,8 @@ static inline void ubifs_get_lprops(struct ubifs_info *c)
*/ */
static inline void ubifs_release_lprops(struct ubifs_info *c) static inline void ubifs_release_lprops(struct ubifs_info *c)
{ {
ubifs_assert(mutex_is_locked(&c->lp_mutex)); ubifs_assert(c, mutex_is_locked(&c->lp_mutex));
ubifs_assert(c->lst.empty_lebs >= 0 && ubifs_assert(c, c->lst.empty_lebs >= 0 &&
c->lst.empty_lebs <= c->main_lebs); c->lst.empty_lebs <= c->main_lebs);
mutex_unlock(&c->lp_mutex); mutex_unlock(&c->lp_mutex);
} }
@ -285,4 +287,6 @@ static inline int ubifs_next_log_lnum(const struct ubifs_info *c, int lnum)
return lnum; return lnum;
} }
const char *ubifs_assert_action_name(struct ubifs_info *c);
#endif /* __UBIFS_MISC_H__ */ #endif /* __UBIFS_MISC_H__ */

View File

@ -172,8 +172,8 @@ int ubifs_orphan_start_commit(struct ubifs_info *c)
spin_lock(&c->orphan_lock); spin_lock(&c->orphan_lock);
last = &c->orph_cnext; last = &c->orph_cnext;
list_for_each_entry(orphan, &c->orph_new, new_list) { list_for_each_entry(orphan, &c->orph_new, new_list) {
ubifs_assert(orphan->new); ubifs_assert(c, orphan->new);
ubifs_assert(!orphan->cmt); ubifs_assert(c, !orphan->cmt);
orphan->new = 0; orphan->new = 0;
orphan->cmt = 1; orphan->cmt = 1;
*last = orphan; *last = orphan;
@ -244,7 +244,7 @@ static int do_write_orph_node(struct ubifs_info *c, int len, int atomic)
int err = 0; int err = 0;
if (atomic) { if (atomic) {
ubifs_assert(c->ohead_offs == 0); ubifs_assert(c, c->ohead_offs == 0);
ubifs_prepare_node(c, c->orph_buf, len, 1); ubifs_prepare_node(c, c->orph_buf, len, 1);
len = ALIGN(len, c->min_io_size); len = ALIGN(len, c->min_io_size);
err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len); err = ubifs_leb_change(c, c->ohead_lnum, c->orph_buf, len);
@ -276,7 +276,7 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
struct ubifs_orph_node *orph; struct ubifs_orph_node *orph;
int gap, err, len, cnt, i; int gap, err, len, cnt, i;
ubifs_assert(c->cmt_orphans > 0); ubifs_assert(c, c->cmt_orphans > 0);
gap = c->leb_size - c->ohead_offs; gap = c->leb_size - c->ohead_offs;
if (gap < UBIFS_ORPH_NODE_SZ + sizeof(__le64)) { if (gap < UBIFS_ORPH_NODE_SZ + sizeof(__le64)) {
c->ohead_lnum += 1; c->ohead_lnum += 1;
@ -295,14 +295,14 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
if (cnt > c->cmt_orphans) if (cnt > c->cmt_orphans)
cnt = c->cmt_orphans; cnt = c->cmt_orphans;
len = UBIFS_ORPH_NODE_SZ + cnt * sizeof(__le64); len = UBIFS_ORPH_NODE_SZ + cnt * sizeof(__le64);
ubifs_assert(c->orph_buf); ubifs_assert(c, c->orph_buf);
orph = c->orph_buf; orph = c->orph_buf;
orph->ch.node_type = UBIFS_ORPH_NODE; orph->ch.node_type = UBIFS_ORPH_NODE;
spin_lock(&c->orphan_lock); spin_lock(&c->orphan_lock);
cnext = c->orph_cnext; cnext = c->orph_cnext;
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
orphan = cnext; orphan = cnext;
ubifs_assert(orphan->cmt); ubifs_assert(c, orphan->cmt);
orph->inos[i] = cpu_to_le64(orphan->inum); orph->inos[i] = cpu_to_le64(orphan->inum);
orphan->cmt = 0; orphan->cmt = 0;
cnext = orphan->cnext; cnext = orphan->cnext;
@ -316,9 +316,9 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
else else
/* Mark the last node of the commit */ /* Mark the last node of the commit */
orph->cmt_no = cpu_to_le64((c->cmt_no) | (1ULL << 63)); orph->cmt_no = cpu_to_le64((c->cmt_no) | (1ULL << 63));
ubifs_assert(c->ohead_offs + len <= c->leb_size); ubifs_assert(c, c->ohead_offs + len <= c->leb_size);
ubifs_assert(c->ohead_lnum >= c->orph_first); ubifs_assert(c, c->ohead_lnum >= c->orph_first);
ubifs_assert(c->ohead_lnum <= c->orph_last); ubifs_assert(c, c->ohead_lnum <= c->orph_last);
err = do_write_orph_node(c, len, atomic); err = do_write_orph_node(c, len, atomic);
c->ohead_offs += ALIGN(len, c->min_io_size); c->ohead_offs += ALIGN(len, c->min_io_size);
c->ohead_offs = ALIGN(c->ohead_offs, 8); c->ohead_offs = ALIGN(c->ohead_offs, 8);
@ -388,7 +388,7 @@ static int consolidate(struct ubifs_info *c)
cnt += 1; cnt += 1;
} }
*last = NULL; *last = NULL;
ubifs_assert(cnt == c->tot_orphans - c->new_orphans); ubifs_assert(c, cnt == c->tot_orphans - c->new_orphans);
c->cmt_orphans = cnt; c->cmt_orphans = cnt;
c->ohead_lnum = c->orph_first; c->ohead_lnum = c->orph_first;
c->ohead_offs = 0; c->ohead_offs = 0;
@ -415,7 +415,7 @@ static int commit_orphans(struct ubifs_info *c)
{ {
int avail, atomic = 0, err; int avail, atomic = 0, err;
ubifs_assert(c->cmt_orphans > 0); ubifs_assert(c, c->cmt_orphans > 0);
avail = avail_orphs(c); avail = avail_orphs(c);
if (avail < c->cmt_orphans) { if (avail < c->cmt_orphans) {
/* Not enough space to write new orphans, so consolidate */ /* Not enough space to write new orphans, so consolidate */
@ -446,8 +446,8 @@ static void erase_deleted(struct ubifs_info *c)
while (dnext) { while (dnext) {
orphan = dnext; orphan = dnext;
dnext = orphan->dnext; dnext = orphan->dnext;
ubifs_assert(!orphan->new); ubifs_assert(c, !orphan->new);
ubifs_assert(orphan->del); ubifs_assert(c, orphan->del);
rb_erase(&orphan->rb, &c->orph_tree); rb_erase(&orphan->rb, &c->orph_tree);
list_del(&orphan->list); list_del(&orphan->list);
c->tot_orphans -= 1; c->tot_orphans -= 1;

View File

@ -444,7 +444,7 @@ static void clean_buf(const struct ubifs_info *c, void **buf, int lnum,
dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs);
ubifs_assert(!(*offs & 7)); ubifs_assert(c, !(*offs & 7));
empty_offs = ALIGN(*offs, c->min_io_size); empty_offs = ALIGN(*offs, c->min_io_size);
pad_len = empty_offs - *offs; pad_len = empty_offs - *offs;
ubifs_pad(c, *buf, pad_len); ubifs_pad(c, *buf, pad_len);
@ -644,7 +644,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
if (IS_ERR(sleb)) if (IS_ERR(sleb))
return sleb; return sleb;
ubifs_assert(len >= 8); ubifs_assert(c, len >= 8);
while (len >= 8) { while (len >= 8) {
dbg_scan("look at LEB %d:%d (%d bytes left)", dbg_scan("look at LEB %d:%d (%d bytes left)",
lnum, offs, len); lnum, offs, len);
@ -966,7 +966,7 @@ int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
{ {
int err; int err;
ubifs_assert(!c->ro_mount || c->remounting_rw); ubifs_assert(c, !c->ro_mount || c->remounting_rw);
dbg_rcvry("checking index head at %d:%d", c->ihead_lnum, c->ihead_offs); dbg_rcvry("checking index head at %d:%d", c->ihead_lnum, c->ihead_offs);
err = recover_head(c, c->ihead_lnum, c->ihead_offs, sbuf); err = recover_head(c, c->ihead_lnum, c->ihead_offs, sbuf);
@ -1187,8 +1187,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
return grab_empty_leb(c); return grab_empty_leb(c);
} }
ubifs_assert(!(lp.flags & LPROPS_INDEX)); ubifs_assert(c, !(lp.flags & LPROPS_INDEX));
ubifs_assert(lp.free + lp.dirty >= wbuf->offs); ubifs_assert(c, lp.free + lp.dirty >= wbuf->offs);
/* /*
* We run the commit before garbage collection otherwise subsequent * We run the commit before garbage collection otherwise subsequent
@ -1216,7 +1216,7 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
return err; return err;
} }
ubifs_assert(err == LEB_RETAINED); ubifs_assert(c, err == LEB_RETAINED);
if (err != LEB_RETAINED) if (err != LEB_RETAINED)
return -EINVAL; return -EINVAL;
@ -1507,7 +1507,7 @@ int ubifs_recover_size(struct ubifs_info *c)
struct inode *inode; struct inode *inode;
struct ubifs_inode *ui; struct ubifs_inode *ui;
ubifs_assert(!e->inode); ubifs_assert(c, !e->inode);
inode = ubifs_iget(c->vfs_sb, e->inum); inode = ubifs_iget(c->vfs_sb, e->inum);
if (IS_ERR(inode)) if (IS_ERR(inode))

View File

@ -273,6 +273,7 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r)
static int replay_entries_cmp(void *priv, struct list_head *a, static int replay_entries_cmp(void *priv, struct list_head *a,
struct list_head *b) struct list_head *b)
{ {
struct ubifs_info *c = priv;
struct replay_entry *ra, *rb; struct replay_entry *ra, *rb;
cond_resched(); cond_resched();
@ -281,7 +282,7 @@ static int replay_entries_cmp(void *priv, struct list_head *a,
ra = list_entry(a, struct replay_entry, list); ra = list_entry(a, struct replay_entry, list);
rb = list_entry(b, struct replay_entry, list); rb = list_entry(b, struct replay_entry, list);
ubifs_assert(ra->sqnum != rb->sqnum); ubifs_assert(c, ra->sqnum != rb->sqnum);
if (ra->sqnum > rb->sqnum) if (ra->sqnum > rb->sqnum)
return 1; return 1;
return -1; return -1;
@ -668,9 +669,9 @@ static int replay_bud(struct ubifs_info *c, struct bud_entry *b)
goto out; goto out;
} }
ubifs_assert(ubifs_search_bud(c, lnum)); ubifs_assert(c, ubifs_search_bud(c, lnum));
ubifs_assert(sleb->endpt - offs >= used); ubifs_assert(c, sleb->endpt - offs >= used);
ubifs_assert(sleb->endpt % c->min_io_size == 0); ubifs_assert(c, sleb->endpt % c->min_io_size == 0);
b->dirty = sleb->endpt - offs - used; b->dirty = sleb->endpt - offs - used;
b->free = c->leb_size - sleb->endpt; b->free = c->leb_size - sleb->endpt;
@ -706,7 +707,7 @@ static int replay_buds(struct ubifs_info *c)
if (err) if (err)
return err; return err;
ubifs_assert(b->sqnum > prev_sqnum); ubifs_assert(c, b->sqnum > prev_sqnum);
prev_sqnum = b->sqnum; prev_sqnum = b->sqnum;
} }
@ -1067,7 +1068,7 @@ int ubifs_replay_journal(struct ubifs_info *c)
c->bi.uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt); c->bi.uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt);
c->bi.uncommitted_idx *= c->max_idx_node_sz; c->bi.uncommitted_idx *= c->max_idx_node_sz;
ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); ubifs_assert(c, c->bud_bytes <= c->max_bud_bytes || c->need_recovery);
dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, highest_inum %lu", dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, highest_inum %lu",
c->lhead_lnum, c->lhead_offs, c->max_sqnum, c->lhead_lnum, c->lhead_offs, c->max_sqnum,
(unsigned long)c->highest_inum); (unsigned long)c->highest_inum);

View File

@ -85,7 +85,7 @@ static int create_default_filesystem(struct ubifs_info *c)
long long tmp64, main_bytes; long long tmp64, main_bytes;
__le64 tmp_le64; __le64 tmp_le64;
__le32 tmp_le32; __le32 tmp_le32;
struct timespec ts; struct timespec64 ts;
/* Some functions called from here depend on the @c->key_len filed */ /* Some functions called from here depend on the @c->key_len filed */
c->key_len = UBIFS_SK_LEN; c->key_len = UBIFS_SK_LEN;
@ -301,8 +301,8 @@ static int create_default_filesystem(struct ubifs_info *c)
ino->creat_sqnum = cpu_to_le64(++c->max_sqnum); ino->creat_sqnum = cpu_to_le64(++c->max_sqnum);
ino->nlink = cpu_to_le32(2); ino->nlink = cpu_to_le32(2);
ktime_get_real_ts(&ts); ktime_get_real_ts64(&ts);
ts = timespec_trunc(ts, DEFAULT_TIME_GRAN); ts = timespec64_trunc(ts, DEFAULT_TIME_GRAN);
tmp_le64 = cpu_to_le64(ts.tv_sec); tmp_le64 = cpu_to_le64(ts.tv_sec);
ino->atime_sec = tmp_le64; ino->atime_sec = tmp_le64;
ino->ctime_sec = tmp_le64; ino->ctime_sec = tmp_le64;
@ -563,7 +563,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
* due to the unavailability of time-travelling equipment. * due to the unavailability of time-travelling equipment.
*/ */
if (c->fmt_version > UBIFS_FORMAT_VERSION) { if (c->fmt_version > UBIFS_FORMAT_VERSION) {
ubifs_assert(!c->ro_media || c->ro_mount); ubifs_assert(c, !c->ro_media || c->ro_mount);
if (!c->ro_mount || if (!c->ro_mount ||
c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) { c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) {
ubifs_err(c, "on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d", ubifs_err(c, "on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d",
@ -705,9 +705,9 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
{ {
int err; int err;
ubifs_assert(len >= 0); ubifs_assert(c, len >= 0);
ubifs_assert(len % c->min_io_size == 0); ubifs_assert(c, len % c->min_io_size == 0);
ubifs_assert(len < c->leb_size); ubifs_assert(c, len < c->leb_size);
if (len == 0) { if (len == 0) {
dbg_mnt("unmap empty LEB %d", lnum); dbg_mnt("unmap empty LEB %d", lnum);
@ -817,8 +817,8 @@ int ubifs_fixup_free_space(struct ubifs_info *c)
int err; int err;
struct ubifs_sb_node *sup; struct ubifs_sb_node *sup;
ubifs_assert(c->space_fixup); ubifs_assert(c, c->space_fixup);
ubifs_assert(!c->ro_mount); ubifs_assert(c, !c->ro_mount);
ubifs_msg(c, "start fixing up free space"); ubifs_msg(c, "start fixing up free space");

View File

@ -176,7 +176,7 @@ void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb,
int lnum, int offs) int lnum, int offs)
{ {
dbg_scan("stop scanning LEB %d at offset %d", lnum, offs); dbg_scan("stop scanning LEB %d at offset %d", lnum, offs);
ubifs_assert(offs % c->min_io_size == 0); ubifs_assert(c, offs % c->min_io_size == 0);
sleb->endpt = ALIGN(offs, c->min_io_size); sleb->endpt = ALIGN(offs, c->min_io_size);
} }

View File

@ -71,10 +71,10 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
{ {
int total_freed = 0; int total_freed = 0;
struct ubifs_znode *znode, *zprev; struct ubifs_znode *znode, *zprev;
int time = get_seconds(); time64_t time = ktime_get_seconds();
ubifs_assert(mutex_is_locked(&c->umount_mutex)); ubifs_assert(c, mutex_is_locked(&c->umount_mutex));
ubifs_assert(mutex_is_locked(&c->tnc_mutex)); ubifs_assert(c, mutex_is_locked(&c->tnc_mutex));
if (!c->zroot.znode || atomic_long_read(&c->clean_zn_cnt) == 0) if (!c->zroot.znode || atomic_long_read(&c->clean_zn_cnt) == 0)
return 0; return 0;
@ -89,7 +89,7 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
* changed only when the 'c->tnc_mutex' is held. * changed only when the 'c->tnc_mutex' is held.
*/ */
zprev = NULL; zprev = NULL;
znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, NULL);
while (znode && total_freed < nr && while (znode && total_freed < nr &&
atomic_long_read(&c->clean_zn_cnt) > 0) { atomic_long_read(&c->clean_zn_cnt) > 0) {
int freed; int freed;
@ -125,7 +125,7 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
else else
c->zroot.znode = NULL; c->zroot.znode = NULL;
freed = ubifs_destroy_tnc_subtree(znode); freed = ubifs_destroy_tnc_subtree(c, znode);
atomic_long_sub(freed, &ubifs_clean_zn_cnt); atomic_long_sub(freed, &ubifs_clean_zn_cnt);
atomic_long_sub(freed, &c->clean_zn_cnt); atomic_long_sub(freed, &c->clean_zn_cnt);
total_freed += freed; total_freed += freed;
@ -136,7 +136,7 @@ static int shrink_tnc(struct ubifs_info *c, int nr, int age, int *contention)
break; break;
zprev = znode; zprev = znode;
znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); znode = ubifs_tnc_levelorder_next(c, c->zroot.znode, znode);
cond_resched(); cond_resched();
} }

View File

@ -89,9 +89,9 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
if (ui->xattr && !S_ISREG(inode->i_mode)) if (ui->xattr && !S_ISREG(inode->i_mode))
return 5; return 5;
if (!ubifs_compr_present(ui->compr_type)) { if (!ubifs_compr_present(c, ui->compr_type)) {
ubifs_warn(c, "inode %lu uses '%s' compression, but it was not compiled in", ubifs_warn(c, "inode %lu uses '%s' compression, but it was not compiled in",
inode->i_ino, ubifs_compr_name(ui->compr_type)); inode->i_ino, ubifs_compr_name(c, ui->compr_type));
} }
err = dbg_check_dir(c, inode); err = dbg_check_dir(c, inode);
@ -296,7 +296,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
struct ubifs_info *c = inode->i_sb->s_fs_info; struct ubifs_info *c = inode->i_sb->s_fs_info;
struct ubifs_inode *ui = ubifs_inode(inode); struct ubifs_inode *ui = ubifs_inode(inode);
ubifs_assert(!ui->xattr); ubifs_assert(c, !ui->xattr);
if (is_bad_inode(inode)) if (is_bad_inode(inode))
return 0; return 0;
@ -349,7 +349,7 @@ static void ubifs_evict_inode(struct inode *inode)
goto out; goto out;
dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode);
ubifs_assert(!atomic_read(&inode->i_count)); ubifs_assert(c, !atomic_read(&inode->i_count));
truncate_inode_pages_final(&inode->i_data); truncate_inode_pages_final(&inode->i_data);
@ -384,9 +384,10 @@ done:
static void ubifs_dirty_inode(struct inode *inode, int flags) static void ubifs_dirty_inode(struct inode *inode, int flags)
{ {
struct ubifs_info *c = inode->i_sb->s_fs_info;
struct ubifs_inode *ui = ubifs_inode(inode); struct ubifs_inode *ui = ubifs_inode(inode);
ubifs_assert(mutex_is_locked(&ui->ui_mutex)); ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
if (!ui->dirty) { if (!ui->dirty) {
ui->dirty = 1; ui->dirty = 1;
dbg_gen("inode %lu", inode->i_ino); dbg_gen("inode %lu", inode->i_ino);
@ -416,7 +417,7 @@ static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_namelen = UBIFS_MAX_NLEN; buf->f_namelen = UBIFS_MAX_NLEN;
buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]); buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]);
buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]); buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]);
ubifs_assert(buf->f_bfree <= c->block_cnt); ubifs_assert(c, buf->f_bfree <= c->block_cnt);
return 0; return 0;
} }
@ -441,9 +442,10 @@ static int ubifs_show_options(struct seq_file *s, struct dentry *root)
if (c->mount_opts.override_compr) { if (c->mount_opts.override_compr) {
seq_printf(s, ",compr=%s", seq_printf(s, ",compr=%s",
ubifs_compr_name(c->mount_opts.compr_type)); ubifs_compr_name(c, c->mount_opts.compr_type));
} }
seq_printf(s, ",assert=%s", ubifs_assert_action_name(c));
seq_printf(s, ",ubi=%d,vol=%d", c->vi.ubi_num, c->vi.vol_id); seq_printf(s, ",ubi=%d,vol=%d", c->vi.ubi_num, c->vi.vol_id);
return 0; return 0;
@ -921,6 +923,7 @@ static int check_volume_empty(struct ubifs_info *c)
* Opt_chk_data_crc: check CRCs when reading data nodes * Opt_chk_data_crc: check CRCs when reading data nodes
* Opt_no_chk_data_crc: do not check CRCs when reading data nodes * Opt_no_chk_data_crc: do not check CRCs when reading data nodes
* Opt_override_compr: override default compressor * Opt_override_compr: override default compressor
* Opt_assert: set ubifs_assert() action
* Opt_err: just end of array marker * Opt_err: just end of array marker
*/ */
enum { enum {
@ -931,6 +934,7 @@ enum {
Opt_chk_data_crc, Opt_chk_data_crc,
Opt_no_chk_data_crc, Opt_no_chk_data_crc,
Opt_override_compr, Opt_override_compr,
Opt_assert,
Opt_ignore, Opt_ignore,
Opt_err, Opt_err,
}; };
@ -945,6 +949,7 @@ static const match_table_t tokens = {
{Opt_override_compr, "compr=%s"}, {Opt_override_compr, "compr=%s"},
{Opt_ignore, "ubi=%s"}, {Opt_ignore, "ubi=%s"},
{Opt_ignore, "vol=%s"}, {Opt_ignore, "vol=%s"},
{Opt_assert, "assert=%s"},
{Opt_err, NULL}, {Opt_err, NULL},
}; };
@ -1045,6 +1050,26 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
c->default_compr = c->mount_opts.compr_type; c->default_compr = c->mount_opts.compr_type;
break; break;
} }
case Opt_assert:
{
char *act = match_strdup(&args[0]);
if (!act)
return -ENOMEM;
if (!strcmp(act, "report"))
c->assert_action = ASSACT_REPORT;
else if (!strcmp(act, "read-only"))
c->assert_action = ASSACT_RO;
else if (!strcmp(act, "panic"))
c->assert_action = ASSACT_PANIC;
else {
ubifs_err(c, "unknown assert action \"%s\"", act);
kfree(act);
return -EINVAL;
}
kfree(act);
break;
}
case Opt_ignore: case Opt_ignore:
break; break;
default: default:
@ -1103,7 +1128,7 @@ static void destroy_journal(struct ubifs_info *c)
*/ */
static void bu_init(struct ubifs_info *c) static void bu_init(struct ubifs_info *c)
{ {
ubifs_assert(c->bulk_read == 1); ubifs_assert(c, c->bulk_read == 1);
if (c->bu.buf) if (c->bu.buf)
return; /* Already initialized */ return; /* Already initialized */
@ -1134,7 +1159,7 @@ again:
*/ */
static int check_free_space(struct ubifs_info *c) static int check_free_space(struct ubifs_info *c)
{ {
ubifs_assert(c->dark_wm > 0); ubifs_assert(c, c->dark_wm > 0);
if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) { if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) {
ubifs_err(c, "insufficient free space to mount in R/W mode"); ubifs_err(c, "insufficient free space to mount in R/W mode");
ubifs_dump_budg(c, &c->bi); ubifs_dump_budg(c, &c->bi);
@ -1234,9 +1259,9 @@ static int mount_ubifs(struct ubifs_info *c)
* Make sure the compressor which is set as default in the superblock * Make sure the compressor which is set as default in the superblock
* or overridden by mount options is actually compiled in. * or overridden by mount options is actually compiled in.
*/ */
if (!ubifs_compr_present(c->default_compr)) { if (!ubifs_compr_present(c, c->default_compr)) {
ubifs_err(c, "'compressor \"%s\" is not compiled in", ubifs_err(c, "'compressor \"%s\" is not compiled in",
ubifs_compr_name(c->default_compr)); ubifs_compr_name(c, c->default_compr));
err = -ENOTSUPP; err = -ENOTSUPP;
goto out_free; goto out_free;
} }
@ -1396,10 +1421,10 @@ static int mount_ubifs(struct ubifs_info *c)
* the journal head LEBs may also be accounted as * the journal head LEBs may also be accounted as
* "empty taken" if they are empty. * "empty taken" if they are empty.
*/ */
ubifs_assert(c->lst.taken_empty_lebs > 0); ubifs_assert(c, c->lst.taken_empty_lebs > 0);
} }
} else } else
ubifs_assert(c->lst.taken_empty_lebs > 0); ubifs_assert(c, c->lst.taken_empty_lebs > 0);
err = dbg_check_filesystem(c); err = dbg_check_filesystem(c);
if (err) if (err)
@ -1429,7 +1454,7 @@ static int mount_ubifs(struct ubifs_info *c)
UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION, c->uuid, UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION, c->uuid,
c->big_lpt ? ", big LPT model" : ", small LPT model"); c->big_lpt ? ", big LPT model" : ", small LPT model");
dbg_gen("default compressor: %s", ubifs_compr_name(c->default_compr)); dbg_gen("default compressor: %s", ubifs_compr_name(c, c->default_compr));
dbg_gen("data journal heads: %d", dbg_gen("data journal heads: %d",
c->jhead_cnt - NONDATA_JHEADS_CNT); c->jhead_cnt - NONDATA_JHEADS_CNT);
dbg_gen("log LEBs: %d (%d - %d)", dbg_gen("log LEBs: %d (%d - %d)",
@ -1610,7 +1635,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
goto out; goto out;
} else { } else {
/* A readonly mount is not allowed to have orphans */ /* A readonly mount is not allowed to have orphans */
ubifs_assert(c->tot_orphans == 0); ubifs_assert(c, c->tot_orphans == 0);
err = ubifs_clear_orphans(c); err = ubifs_clear_orphans(c);
if (err) if (err)
goto out; goto out;
@ -1727,8 +1752,8 @@ static void ubifs_remount_ro(struct ubifs_info *c)
{ {
int i, err; int i, err;
ubifs_assert(!c->need_recovery); ubifs_assert(c, !c->need_recovery);
ubifs_assert(!c->ro_mount); ubifs_assert(c, !c->ro_mount);
mutex_lock(&c->umount_mutex); mutex_lock(&c->umount_mutex);
if (c->bgt) { if (c->bgt) {
@ -1778,9 +1803,9 @@ static void ubifs_put_super(struct super_block *sb)
* to write them back because of I/O errors. * to write them back because of I/O errors.
*/ */
if (!c->ro_error) { if (!c->ro_error) {
ubifs_assert(c->bi.idx_growth == 0); ubifs_assert(c, c->bi.idx_growth == 0);
ubifs_assert(c->bi.dd_growth == 0); ubifs_assert(c, c->bi.dd_growth == 0);
ubifs_assert(c->bi.data_growth == 0); ubifs_assert(c, c->bi.data_growth == 0);
} }
/* /*
@ -1887,7 +1912,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
mutex_unlock(&c->bu_mutex); mutex_unlock(&c->bu_mutex);
} }
ubifs_assert(c->lst.taken_empty_lebs > 0); ubifs_assert(c, c->lst.taken_empty_lebs > 0);
return 0; return 0;
} }
@ -2002,6 +2027,7 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
INIT_LIST_HEAD(&c->orph_list); INIT_LIST_HEAD(&c->orph_list);
INIT_LIST_HEAD(&c->orph_new); INIT_LIST_HEAD(&c->orph_new);
c->no_chk_data_crc = 1; c->no_chk_data_crc = 1;
c->assert_action = ASSACT_RO;
c->highest_inum = UBIFS_FIRST_INO; c->highest_inum = UBIFS_FIRST_INO;
c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM;
@ -2053,7 +2079,9 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
if (c->max_inode_sz > MAX_LFS_FILESIZE) if (c->max_inode_sz > MAX_LFS_FILESIZE)
sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
sb->s_op = &ubifs_super_operations; sb->s_op = &ubifs_super_operations;
#ifdef CONFIG_UBIFS_FS_XATTR
sb->s_xattr = ubifs_xattr_handlers; sb->s_xattr = ubifs_xattr_handlers;
#endif
#ifdef CONFIG_UBIFS_FS_ENCRYPTION #ifdef CONFIG_UBIFS_FS_ENCRYPTION
sb->s_cop = &ubifs_crypt_operations; sb->s_cop = &ubifs_crypt_operations;
#endif #endif
@ -2061,7 +2089,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
mutex_lock(&c->umount_mutex); mutex_lock(&c->umount_mutex);
err = mount_ubifs(c); err = mount_ubifs(c);
if (err) { if (err) {
ubifs_assert(err < 0); ubifs_assert(c, err < 0);
goto out_unlock; goto out_unlock;
} }
@ -2304,8 +2332,8 @@ late_initcall(ubifs_init);
static void __exit ubifs_exit(void) static void __exit ubifs_exit(void)
{ {
ubifs_assert(list_empty(&ubifs_infos)); WARN_ON(list_empty(&ubifs_infos));
ubifs_assert(atomic_long_read(&ubifs_clean_zn_cnt) == 0); WARN_ON(atomic_long_read(&ubifs_clean_zn_cnt) == 0);
dbg_debugfs_exit(); dbg_debugfs_exit();
ubifs_compressors_exit(); ubifs_compressors_exit();

View File

@ -211,7 +211,7 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c,
__set_bit(DIRTY_ZNODE, &zn->flags); __set_bit(DIRTY_ZNODE, &zn->flags);
__clear_bit(COW_ZNODE, &zn->flags); __clear_bit(COW_ZNODE, &zn->flags);
ubifs_assert(!ubifs_zn_obsolete(znode)); ubifs_assert(c, !ubifs_zn_obsolete(znode));
__set_bit(OBSOLETE_ZNODE, &znode->flags); __set_bit(OBSOLETE_ZNODE, &znode->flags);
if (znode->level != 0) { if (znode->level != 0) {
@ -321,9 +321,9 @@ static int lnc_add(struct ubifs_info *c, struct ubifs_zbranch *zbr,
void *lnc_node; void *lnc_node;
const struct ubifs_dent_node *dent = node; const struct ubifs_dent_node *dent = node;
ubifs_assert(!zbr->leaf); ubifs_assert(c, !zbr->leaf);
ubifs_assert(zbr->len != 0); ubifs_assert(c, zbr->len != 0);
ubifs_assert(is_hash_key(c, &zbr->key)); ubifs_assert(c, is_hash_key(c, &zbr->key));
err = ubifs_validate_entry(c, dent); err = ubifs_validate_entry(c, dent);
if (err) { if (err) {
@ -355,8 +355,8 @@ static int lnc_add_directly(struct ubifs_info *c, struct ubifs_zbranch *zbr,
{ {
int err; int err;
ubifs_assert(!zbr->leaf); ubifs_assert(c, !zbr->leaf);
ubifs_assert(zbr->len != 0); ubifs_assert(c, zbr->len != 0);
err = ubifs_validate_entry(c, node); err = ubifs_validate_entry(c, node);
if (err) { if (err) {
@ -398,11 +398,11 @@ static int tnc_read_hashed_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,
{ {
int err; int err;
ubifs_assert(is_hash_key(c, &zbr->key)); ubifs_assert(c, is_hash_key(c, &zbr->key));
if (zbr->leaf) { if (zbr->leaf) {
/* Read from the leaf node cache */ /* Read from the leaf node cache */
ubifs_assert(zbr->len != 0); ubifs_assert(c, zbr->len != 0);
memcpy(node, zbr->leaf, zbr->len); memcpy(node, zbr->leaf, zbr->len);
return 0; return 0;
} }
@ -721,7 +721,7 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
while (1) { while (1) {
err = tnc_prev(c, zn, n); err = tnc_prev(c, zn, n);
if (err == -ENOENT) { if (err == -ENOENT) {
ubifs_assert(*n == 0); ubifs_assert(c, *n == 0);
*n = -1; *n = -1;
return 0; return 0;
} }
@ -761,12 +761,12 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
err = tnc_next(c, zn, n); err = tnc_next(c, zn, n);
if (err) { if (err) {
/* Should be impossible */ /* Should be impossible */
ubifs_assert(0); ubifs_assert(c, 0);
if (err == -ENOENT) if (err == -ENOENT)
err = -EINVAL; err = -EINVAL;
return err; return err;
} }
ubifs_assert(*n == 0); ubifs_assert(c, *n == 0);
*n = -1; *n = -1;
} }
return 0; return 0;
@ -778,7 +778,7 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
return 0; return 0;
if (err == NAME_MATCHES) if (err == NAME_MATCHES)
return 1; return 1;
ubifs_assert(err == NAME_GREATER); ubifs_assert(c, err == NAME_GREATER);
} }
} else { } else {
int nn = *n; int nn = *n;
@ -802,7 +802,7 @@ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key,
*n = nn; *n = nn;
if (err == NAME_MATCHES) if (err == NAME_MATCHES)
return 1; return 1;
ubifs_assert(err == NAME_LESS); ubifs_assert(c, err == NAME_LESS);
} }
} }
} }
@ -843,7 +843,7 @@ static int fallible_matches_name(struct ubifs_info *c,
err = NOT_ON_MEDIA; err = NOT_ON_MEDIA;
goto out_free; goto out_free;
} }
ubifs_assert(err == 1); ubifs_assert(c, err == 1);
err = lnc_add_directly(c, zbr, dent); err = lnc_add_directly(c, zbr, dent);
if (err) if (err)
@ -923,7 +923,7 @@ static int fallible_resolve_collision(struct ubifs_info *c,
while (1) { while (1) {
err = tnc_prev(c, zn, n); err = tnc_prev(c, zn, n);
if (err == -ENOENT) { if (err == -ENOENT) {
ubifs_assert(*n == 0); ubifs_assert(c, *n == 0);
*n = -1; *n = -1;
break; break;
} }
@ -935,12 +935,12 @@ static int fallible_resolve_collision(struct ubifs_info *c,
err = tnc_next(c, zn, n); err = tnc_next(c, zn, n);
if (err) { if (err) {
/* Should be impossible */ /* Should be impossible */
ubifs_assert(0); ubifs_assert(c, 0);
if (err == -ENOENT) if (err == -ENOENT)
err = -EINVAL; err = -EINVAL;
return err; return err;
} }
ubifs_assert(*n == 0); ubifs_assert(c, *n == 0);
*n = -1; *n = -1;
} }
break; break;
@ -1100,8 +1100,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
struct ubifs_znode *zp; struct ubifs_znode *zp;
int *path = c->bottom_up_buf, p = 0; int *path = c->bottom_up_buf, p = 0;
ubifs_assert(c->zroot.znode); ubifs_assert(c, c->zroot.znode);
ubifs_assert(znode); ubifs_assert(c, znode);
if (c->zroot.znode->level > BOTTOM_UP_HEIGHT) { if (c->zroot.znode->level > BOTTOM_UP_HEIGHT) {
kfree(c->bottom_up_buf); kfree(c->bottom_up_buf);
c->bottom_up_buf = kmalloc_array(c->zroot.znode->level, c->bottom_up_buf = kmalloc_array(c->zroot.znode->level,
@ -1120,7 +1120,7 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
if (!zp) if (!zp)
break; break;
n = znode->iip; n = znode->iip;
ubifs_assert(p < c->zroot.znode->level); ubifs_assert(c, p < c->zroot.znode->level);
path[p++] = n; path[p++] = n;
if (!zp->cnext && ubifs_zn_dirty(znode)) if (!zp->cnext && ubifs_zn_dirty(znode))
break; break;
@ -1134,18 +1134,18 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
zp = znode->parent; zp = znode->parent;
if (zp) { if (zp) {
ubifs_assert(path[p - 1] >= 0); ubifs_assert(c, path[p - 1] >= 0);
ubifs_assert(path[p - 1] < zp->child_cnt); ubifs_assert(c, path[p - 1] < zp->child_cnt);
zbr = &zp->zbranch[path[--p]]; zbr = &zp->zbranch[path[--p]];
znode = dirty_cow_znode(c, zbr); znode = dirty_cow_znode(c, zbr);
} else { } else {
ubifs_assert(znode == c->zroot.znode); ubifs_assert(c, znode == c->zroot.znode);
znode = dirty_cow_znode(c, &c->zroot); znode = dirty_cow_znode(c, &c->zroot);
} }
if (IS_ERR(znode) || !p) if (IS_ERR(znode) || !p)
break; break;
ubifs_assert(path[p - 1] >= 0); ubifs_assert(c, path[p - 1] >= 0);
ubifs_assert(path[p - 1] < znode->child_cnt); ubifs_assert(c, path[p - 1] < znode->child_cnt);
znode = znode->zbranch[path[p - 1]].znode; znode = znode->zbranch[path[p - 1]].znode;
} }
@ -1179,10 +1179,10 @@ int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
{ {
int err, exact; int err, exact;
struct ubifs_znode *znode; struct ubifs_znode *znode;
unsigned long time = get_seconds(); time64_t time = ktime_get_seconds();
dbg_tnck(key, "search key "); dbg_tnck(key, "search key ");
ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY); ubifs_assert(c, key_type(c, key) < UBIFS_INVALID_KEY);
znode = c->zroot.znode; znode = c->zroot.znode;
if (unlikely(!znode)) { if (unlikely(!znode)) {
@ -1315,7 +1315,7 @@ static int lookup_level0_dirty(struct ubifs_info *c, const union ubifs_key *key,
{ {
int err, exact; int err, exact;
struct ubifs_znode *znode; struct ubifs_znode *znode;
unsigned long time = get_seconds(); time64_t time = ktime_get_seconds();
dbg_tnck(key, "search and dirty key "); dbg_tnck(key, "search and dirty key ");
@ -1658,9 +1658,9 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
int rlen, overlap; int rlen, overlap;
dbg_io("LEB %d:%d, length %d", lnum, offs, len); dbg_io("LEB %d:%d, length %d", lnum, offs, len);
ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); ubifs_assert(c, wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
ubifs_assert(!(offs & 7) && offs < c->leb_size); ubifs_assert(c, !(offs & 7) && offs < c->leb_size);
ubifs_assert(offs + len <= c->leb_size); ubifs_assert(c, offs + len <= c->leb_size);
spin_lock(&wbuf->lock); spin_lock(&wbuf->lock);
overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs); overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs);
@ -1824,7 +1824,7 @@ static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
goto out_unlock; goto out_unlock;
} }
ubifs_assert(n >= 0); ubifs_assert(c, n >= 0);
err = resolve_collision(c, key, &znode, &n, nm); err = resolve_collision(c, key, &znode, &n, nm);
dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n);
@ -1922,7 +1922,7 @@ static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key,
struct ubifs_znode *znode; struct ubifs_znode *znode;
union ubifs_key start_key; union ubifs_key start_key;
ubifs_assert(is_hash_key(c, key)); ubifs_assert(c, is_hash_key(c, key));
lowest_dent_key(c, &start_key, key_inum(c, key)); lowest_dent_key(c, &start_key, key_inum(c, key));
@ -1993,8 +1993,8 @@ static void correct_parent_keys(const struct ubifs_info *c,
{ {
union ubifs_key *key, *key1; union ubifs_key *key, *key1;
ubifs_assert(znode->parent); ubifs_assert(c, znode->parent);
ubifs_assert(znode->iip == 0); ubifs_assert(c, znode->iip == 0);
key = &znode->zbranch[0].key; key = &znode->zbranch[0].key;
key1 = &znode->parent->zbranch[0].key; key1 = &znode->parent->zbranch[0].key;
@ -2011,6 +2011,7 @@ static void correct_parent_keys(const struct ubifs_info *c,
/** /**
* insert_zbranch - insert a zbranch into a znode. * insert_zbranch - insert a zbranch into a znode.
* @c: UBIFS file-system description object
* @znode: znode into which to insert * @znode: znode into which to insert
* @zbr: zbranch to insert * @zbr: zbranch to insert
* @n: slot number to insert to * @n: slot number to insert to
@ -2020,12 +2021,12 @@ static void correct_parent_keys(const struct ubifs_info *c,
* zbranch has to be inserted to the @znode->zbranches[]' array at the @n-th * zbranch has to be inserted to the @znode->zbranches[]' array at the @n-th
* slot, zbranches starting from @n have to be moved right. * slot, zbranches starting from @n have to be moved right.
*/ */
static void insert_zbranch(struct ubifs_znode *znode, static void insert_zbranch(struct ubifs_info *c, struct ubifs_znode *znode,
const struct ubifs_zbranch *zbr, int n) const struct ubifs_zbranch *zbr, int n)
{ {
int i; int i;
ubifs_assert(ubifs_zn_dirty(znode)); ubifs_assert(c, ubifs_zn_dirty(znode));
if (znode->level) { if (znode->level) {
for (i = znode->child_cnt; i > n; i--) { for (i = znode->child_cnt; i > n; i--) {
@ -2079,16 +2080,16 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
int i, keep, move, appending = 0; int i, keep, move, appending = 0;
union ubifs_key *key = &zbr->key, *key1; union ubifs_key *key = &zbr->key, *key1;
ubifs_assert(n >= 0 && n <= c->fanout); ubifs_assert(c, n >= 0 && n <= c->fanout);
/* Implement naive insert for now */ /* Implement naive insert for now */
again: again:
zp = znode->parent; zp = znode->parent;
if (znode->child_cnt < c->fanout) { if (znode->child_cnt < c->fanout) {
ubifs_assert(n != c->fanout); ubifs_assert(c, n != c->fanout);
dbg_tnck(key, "inserted at %d level %d, key ", n, znode->level); dbg_tnck(key, "inserted at %d level %d, key ", n, znode->level);
insert_zbranch(znode, zbr, n); insert_zbranch(c, znode, zbr, n);
/* Ensure parent's key is correct */ /* Ensure parent's key is correct */
if (n == 0 && zp && znode->iip == 0) if (n == 0 && zp && znode->iip == 0)
@ -2197,7 +2198,7 @@ do_split:
/* Insert new key and branch */ /* Insert new key and branch */
dbg_tnck(key, "inserting at %d level %d, key ", n, zn->level); dbg_tnck(key, "inserting at %d level %d, key ", n, zn->level);
insert_zbranch(zi, zbr, n); insert_zbranch(c, zi, zbr, n);
/* Insert new znode (produced by spitting) into the parent */ /* Insert new znode (produced by spitting) into the parent */
if (zp) { if (zp) {
@ -2495,8 +2496,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
int i, err; int i, err;
/* Delete without merge for now */ /* Delete without merge for now */
ubifs_assert(znode->level == 0); ubifs_assert(c, znode->level == 0);
ubifs_assert(n >= 0 && n < c->fanout); ubifs_assert(c, n >= 0 && n < c->fanout);
dbg_tnck(&znode->zbranch[n].key, "deleting key "); dbg_tnck(&znode->zbranch[n].key, "deleting key ");
zbr = &znode->zbranch[n]; zbr = &znode->zbranch[n];
@ -2522,8 +2523,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
*/ */
do { do {
ubifs_assert(!ubifs_zn_obsolete(znode)); ubifs_assert(c, !ubifs_zn_obsolete(znode));
ubifs_assert(ubifs_zn_dirty(znode)); ubifs_assert(c, ubifs_zn_dirty(znode));
zp = znode->parent; zp = znode->parent;
n = znode->iip; n = znode->iip;
@ -2545,7 +2546,7 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
/* Remove from znode, entry n - 1 */ /* Remove from znode, entry n - 1 */
znode->child_cnt -= 1; znode->child_cnt -= 1;
ubifs_assert(znode->level != 0); ubifs_assert(c, znode->level != 0);
for (i = n; i < znode->child_cnt; i++) { for (i = n; i < znode->child_cnt; i++) {
znode->zbranch[i] = znode->zbranch[i + 1]; znode->zbranch[i] = znode->zbranch[i + 1];
if (znode->zbranch[i].znode) if (znode->zbranch[i].znode)
@ -2578,8 +2579,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
c->zroot.offs = zbr->offs; c->zroot.offs = zbr->offs;
c->zroot.len = zbr->len; c->zroot.len = zbr->len;
c->zroot.znode = znode; c->zroot.znode = znode;
ubifs_assert(!ubifs_zn_obsolete(zp)); ubifs_assert(c, !ubifs_zn_obsolete(zp));
ubifs_assert(ubifs_zn_dirty(zp)); ubifs_assert(c, ubifs_zn_dirty(zp));
atomic_long_dec(&c->dirty_zn_cnt); atomic_long_dec(&c->dirty_zn_cnt);
if (zp->cnext) { if (zp->cnext) {
@ -2944,7 +2945,7 @@ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,
union ubifs_key *dkey; union ubifs_key *dkey;
dbg_tnck(key, "key "); dbg_tnck(key, "key ");
ubifs_assert(is_hash_key(c, key)); ubifs_assert(c, is_hash_key(c, key));
mutex_lock(&c->tnc_mutex); mutex_lock(&c->tnc_mutex);
err = ubifs_lookup_level0(c, key, &znode, &n); err = ubifs_lookup_level0(c, key, &znode, &n);
@ -3031,7 +3032,7 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
if (!c->cnext) if (!c->cnext)
return; return;
ubifs_assert(c->cmt_state == COMMIT_BROKEN); ubifs_assert(c, c->cmt_state == COMMIT_BROKEN);
cnext = c->cnext; cnext = c->cnext;
do { do {
struct ubifs_znode *znode = cnext; struct ubifs_znode *znode = cnext;
@ -3053,8 +3054,8 @@ void ubifs_tnc_close(struct ubifs_info *c)
long n, freed; long n, freed;
n = atomic_long_read(&c->clean_zn_cnt); n = atomic_long_read(&c->clean_zn_cnt);
freed = ubifs_destroy_tnc_subtree(c->zroot.znode); freed = ubifs_destroy_tnc_subtree(c, c->zroot.znode);
ubifs_assert(freed == n); ubifs_assert(c, freed == n);
atomic_long_sub(n, &ubifs_clean_zn_cnt); atomic_long_sub(n, &ubifs_clean_zn_cnt);
} }
kfree(c->gap_lebs); kfree(c->gap_lebs);
@ -3167,7 +3168,7 @@ static struct ubifs_znode *lookup_znode(struct ubifs_info *c,
struct ubifs_znode *znode, *zn; struct ubifs_znode *znode, *zn;
int n, nn; int n, nn;
ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY); ubifs_assert(c, key_type(c, key) < UBIFS_INVALID_KEY);
/* /*
* The arguments have probably been read off flash, so don't assume * The arguments have probably been read off flash, so don't assume
@ -3206,7 +3207,7 @@ static struct ubifs_znode *lookup_znode(struct ubifs_info *c,
if (IS_ERR(znode)) if (IS_ERR(znode))
return znode; return znode;
ubifs_search_zbranch(c, znode, key, &n); ubifs_search_zbranch(c, znode, key, &n);
ubifs_assert(n >= 0); ubifs_assert(c, n >= 0);
} }
if (znode->level == level + 1) if (znode->level == level + 1)
break; break;
@ -3497,7 +3498,7 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
if (err < 0) if (err < 0)
goto out_unlock; goto out_unlock;
ubifs_assert(err == 0); ubifs_assert(c, err == 0);
key = &znode->zbranch[n].key; key = &znode->zbranch[n].key;
if (!key_in_range(c, key, &from_key, &to_key)) if (!key_in_range(c, key, &from_key, &to_key))
goto out_unlock; goto out_unlock;

View File

@ -87,8 +87,8 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
atomic_long_dec(&c->dirty_zn_cnt); atomic_long_dec(&c->dirty_zn_cnt);
ubifs_assert(ubifs_zn_dirty(znode)); ubifs_assert(c, ubifs_zn_dirty(znode));
ubifs_assert(ubifs_zn_cow(znode)); ubifs_assert(c, ubifs_zn_cow(znode));
/* /*
* Note, unlike 'write_index()' we do not add memory barriers here * Note, unlike 'write_index()' we do not add memory barriers here
@ -115,9 +115,9 @@ static int fill_gap(struct ubifs_info *c, int lnum, int gap_start, int gap_end,
{ {
int len, gap_remains, gap_pos, written, pad_len; int len, gap_remains, gap_pos, written, pad_len;
ubifs_assert((gap_start & 7) == 0); ubifs_assert(c, (gap_start & 7) == 0);
ubifs_assert((gap_end & 7) == 0); ubifs_assert(c, (gap_end & 7) == 0);
ubifs_assert(gap_end >= gap_start); ubifs_assert(c, gap_end >= gap_start);
gap_remains = gap_end - gap_start; gap_remains = gap_end - gap_start;
if (!gap_remains) if (!gap_remains)
@ -131,7 +131,7 @@ static int fill_gap(struct ubifs_info *c, int lnum, int gap_start, int gap_end,
const int alen = ALIGN(len, 8); const int alen = ALIGN(len, 8);
int err; int err;
ubifs_assert(alen <= gap_remains); ubifs_assert(c, alen <= gap_remains);
err = make_idx_node(c, c->ileb_buf + gap_pos, znode, err = make_idx_node(c, c->ileb_buf + gap_pos, znode,
lnum, gap_pos, len); lnum, gap_pos, len);
if (err) if (err)
@ -259,7 +259,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p)
struct ubifs_idx_node *idx; struct ubifs_idx_node *idx;
int in_use, level; int in_use, level;
ubifs_assert(snod->type == UBIFS_IDX_NODE); ubifs_assert(c, snod->type == UBIFS_IDX_NODE);
idx = snod->node; idx = snod->node;
key_read(c, ubifs_idx_key(c, idx), &snod->key); key_read(c, ubifs_idx_key(c, idx), &snod->key);
level = le16_to_cpu(idx->level); level = le16_to_cpu(idx->level);
@ -373,7 +373,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
p = c->gap_lebs; p = c->gap_lebs;
do { do {
ubifs_assert(p < c->gap_lebs + c->lst.idx_lebs); ubifs_assert(c, p < c->gap_lebs + c->lst.idx_lebs);
written = layout_leb_in_gaps(c, p); written = layout_leb_in_gaps(c, p);
if (written < 0) { if (written < 0) {
err = written; err = written;
@ -639,7 +639,7 @@ static int get_znodes_to_commit(struct ubifs_info *c)
} }
cnt += 1; cnt += 1;
while (1) { while (1) {
ubifs_assert(!ubifs_zn_cow(znode)); ubifs_assert(c, !ubifs_zn_cow(znode));
__set_bit(COW_ZNODE, &znode->flags); __set_bit(COW_ZNODE, &znode->flags);
znode->alt = 0; znode->alt = 0;
cnext = find_next_dirty(znode); cnext = find_next_dirty(znode);
@ -652,7 +652,7 @@ static int get_znodes_to_commit(struct ubifs_info *c)
cnt += 1; cnt += 1;
} }
dbg_cmt("committing %d znodes", cnt); dbg_cmt("committing %d znodes", cnt);
ubifs_assert(cnt == atomic_long_read(&c->dirty_zn_cnt)); ubifs_assert(c, cnt == atomic_long_read(&c->dirty_zn_cnt));
return cnt; return cnt;
} }
@ -760,7 +760,7 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot)
err = layout_commit(c, no_space, cnt); err = layout_commit(c, no_space, cnt);
if (err) if (err)
goto out_free; goto out_free;
ubifs_assert(atomic_long_read(&c->dirty_zn_cnt) == 0); ubifs_assert(c, atomic_long_read(&c->dirty_zn_cnt) == 0);
err = free_unused_idx_lebs(c); err = free_unused_idx_lebs(c);
if (err) if (err)
goto out; goto out;
@ -781,7 +781,7 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot)
* budgeting subsystem to assume the index is already committed, * budgeting subsystem to assume the index is already committed,
* even though it is not. * even though it is not.
*/ */
ubifs_assert(c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c)); ubifs_assert(c, c->bi.min_idx_lebs == ubifs_calc_min_idx_lebs(c));
c->bi.old_idx_sz = c->calc_idx_sz; c->bi.old_idx_sz = c->calc_idx_sz;
c->bi.uncommitted_idx = 0; c->bi.uncommitted_idx = 0;
c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c); c->bi.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
@ -887,8 +887,8 @@ static int write_index(struct ubifs_info *c)
/* Grab some stuff from znode while we still can */ /* Grab some stuff from znode while we still can */
cnext = znode->cnext; cnext = znode->cnext;
ubifs_assert(ubifs_zn_dirty(znode)); ubifs_assert(c, ubifs_zn_dirty(znode));
ubifs_assert(ubifs_zn_cow(znode)); ubifs_assert(c, ubifs_zn_cow(znode));
/* /*
* It is important that other threads should see %DIRTY_ZNODE * It is important that other threads should see %DIRTY_ZNODE

View File

@ -31,19 +31,21 @@
/** /**
* ubifs_tnc_levelorder_next - next TNC tree element in levelorder traversal. * ubifs_tnc_levelorder_next - next TNC tree element in levelorder traversal.
* @c: UBIFS file-system description object
* @zr: root of the subtree to traverse * @zr: root of the subtree to traverse
* @znode: previous znode * @znode: previous znode
* *
* This function implements levelorder TNC traversal. The LNC is ignored. * This function implements levelorder TNC traversal. The LNC is ignored.
* Returns the next element or %NULL if @znode is already the last one. * Returns the next element or %NULL if @znode is already the last one.
*/ */
struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr, struct ubifs_znode *ubifs_tnc_levelorder_next(const struct ubifs_info *c,
struct ubifs_znode *zr,
struct ubifs_znode *znode) struct ubifs_znode *znode)
{ {
int level, iip, level_search = 0; int level, iip, level_search = 0;
struct ubifs_znode *zn; struct ubifs_znode *zn;
ubifs_assert(zr); ubifs_assert(c, zr);
if (unlikely(!znode)) if (unlikely(!znode))
return zr; return zr;
@ -58,7 +60,7 @@ struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
iip = znode->iip; iip = znode->iip;
while (1) { while (1) {
ubifs_assert(znode->level <= zr->level); ubifs_assert(c, znode->level <= zr->level);
/* /*
* First walk up until there is a znode with next branch to * First walk up until there is a znode with next branch to
@ -85,7 +87,7 @@ struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
level_search = 1; level_search = 1;
iip = -1; iip = -1;
znode = ubifs_tnc_find_child(zr, 0); znode = ubifs_tnc_find_child(zr, 0);
ubifs_assert(znode); ubifs_assert(c, znode);
} }
/* Switch to the next index */ /* Switch to the next index */
@ -111,7 +113,7 @@ struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
} }
if (zn) { if (zn) {
ubifs_assert(zn->level >= 0); ubifs_assert(c, zn->level >= 0);
return zn; return zn;
} }
} }
@ -140,7 +142,7 @@ int ubifs_search_zbranch(const struct ubifs_info *c,
int uninitialized_var(cmp); int uninitialized_var(cmp);
const struct ubifs_zbranch *zbr = &znode->zbranch[0]; const struct ubifs_zbranch *zbr = &znode->zbranch[0];
ubifs_assert(end > beg); ubifs_assert(c, end > beg);
while (end > beg) { while (end > beg) {
mid = (beg + end) >> 1; mid = (beg + end) >> 1;
@ -158,13 +160,13 @@ int ubifs_search_zbranch(const struct ubifs_info *c,
*n = end - 1; *n = end - 1;
/* The insert point is after *n */ /* The insert point is after *n */
ubifs_assert(*n >= -1 && *n < znode->child_cnt); ubifs_assert(c, *n >= -1 && *n < znode->child_cnt);
if (*n == -1) if (*n == -1)
ubifs_assert(keys_cmp(c, key, &zbr[0].key) < 0); ubifs_assert(c, keys_cmp(c, key, &zbr[0].key) < 0);
else else
ubifs_assert(keys_cmp(c, key, &zbr[*n].key) > 0); ubifs_assert(c, keys_cmp(c, key, &zbr[*n].key) > 0);
if (*n + 1 < znode->child_cnt) if (*n + 1 < znode->child_cnt)
ubifs_assert(keys_cmp(c, key, &zbr[*n + 1].key) < 0); ubifs_assert(c, keys_cmp(c, key, &zbr[*n + 1].key) < 0);
return 0; return 0;
} }
@ -195,16 +197,18 @@ struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode)
/** /**
* ubifs_tnc_postorder_next - next TNC tree element in postorder traversal. * ubifs_tnc_postorder_next - next TNC tree element in postorder traversal.
* @c: UBIFS file-system description object
* @znode: previous znode * @znode: previous znode
* *
* This function implements postorder TNC traversal. The LNC is ignored. * This function implements postorder TNC traversal. The LNC is ignored.
* Returns the next element or %NULL if @znode is already the last one. * Returns the next element or %NULL if @znode is already the last one.
*/ */
struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode) struct ubifs_znode *ubifs_tnc_postorder_next(const struct ubifs_info *c,
struct ubifs_znode *znode)
{ {
struct ubifs_znode *zn; struct ubifs_znode *zn;
ubifs_assert(znode); ubifs_assert(c, znode);
if (unlikely(!znode->parent)) if (unlikely(!znode->parent))
return NULL; return NULL;
@ -220,18 +224,20 @@ struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode)
/** /**
* ubifs_destroy_tnc_subtree - destroy all znodes connected to a subtree. * ubifs_destroy_tnc_subtree - destroy all znodes connected to a subtree.
* @c: UBIFS file-system description object
* @znode: znode defining subtree to destroy * @znode: znode defining subtree to destroy
* *
* This function destroys subtree of the TNC tree. Returns number of clean * This function destroys subtree of the TNC tree. Returns number of clean
* znodes in the subtree. * znodes in the subtree.
*/ */
long ubifs_destroy_tnc_subtree(struct ubifs_znode *znode) long ubifs_destroy_tnc_subtree(const struct ubifs_info *c,
struct ubifs_znode *znode)
{ {
struct ubifs_znode *zn = ubifs_tnc_postorder_first(znode); struct ubifs_znode *zn = ubifs_tnc_postorder_first(znode);
long clean_freed = 0; long clean_freed = 0;
int n; int n;
ubifs_assert(zn); ubifs_assert(c, zn);
while (1) { while (1) {
for (n = 0; n < zn->child_cnt; n++) { for (n = 0; n < zn->child_cnt; n++) {
if (!zn->zbranch[n].znode) if (!zn->zbranch[n].znode)
@ -252,7 +258,7 @@ long ubifs_destroy_tnc_subtree(struct ubifs_znode *znode)
return clean_freed; return clean_freed;
} }
zn = ubifs_tnc_postorder_next(zn); zn = ubifs_tnc_postorder_next(c, zn);
} }
} }
@ -410,7 +416,7 @@ struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,
int err; int err;
struct ubifs_znode *znode; struct ubifs_znode *znode;
ubifs_assert(!zbr->znode); ubifs_assert(c, !zbr->znode);
/* /*
* A slab cache is not presently used for znodes because the znode size * A slab cache is not presently used for znodes because the znode size
* depends on the fanout which is stored in the superblock. * depends on the fanout which is stored in the superblock.
@ -435,7 +441,7 @@ struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,
zbr->znode = znode; zbr->znode = znode;
znode->parent = parent; znode->parent = parent;
znode->time = get_seconds(); znode->time = ktime_get_seconds();
znode->iip = iip; znode->iip = iip;
return znode; return znode;

View File

@ -258,6 +258,18 @@ enum {
LEB_RETAINED, LEB_RETAINED,
}; };
/*
* Action taken upon a failed ubifs_assert().
* @ASSACT_REPORT: just report the failed assertion
* @ASSACT_RO: switch to read-only mode
* @ASSACT_PANIC: call BUG() and possible panic the kernel
*/
enum {
ASSACT_REPORT = 0,
ASSACT_RO,
ASSACT_PANIC,
};
/** /**
* struct ubifs_old_idx - index node obsoleted since last commit start. * struct ubifs_old_idx - index node obsoleted since last commit start.
* @rb: rb-tree node * @rb: rb-tree node
@ -758,7 +770,7 @@ struct ubifs_znode {
struct ubifs_znode *parent; struct ubifs_znode *parent;
struct ubifs_znode *cnext; struct ubifs_znode *cnext;
unsigned long flags; unsigned long flags;
unsigned long time; time64_t time;
int level; int level;
int child_cnt; int child_cnt;
int iip; int iip;
@ -1015,6 +1027,7 @@ struct ubifs_debug_info;
* @bulk_read: enable bulk-reads * @bulk_read: enable bulk-reads
* @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
* @rw_incompat: the media is not R/W compatible * @rw_incompat: the media is not R/W compatible
* @assert_action: action to take when a ubifs_assert() fails
* *
* @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
* @calc_idx_sz * @calc_idx_sz
@ -1256,6 +1269,7 @@ struct ubifs_info {
unsigned int bulk_read:1; unsigned int bulk_read:1;
unsigned int default_compr:2; unsigned int default_compr:2;
unsigned int rw_incompat:1; unsigned int rw_incompat:1;
unsigned int assert_action:2;
struct mutex tnc_mutex; struct mutex tnc_mutex;
struct ubifs_zbranch zroot; struct ubifs_zbranch zroot;
@ -1608,14 +1622,17 @@ int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu);
int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu); int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu);
/* tnc_misc.c */ /* tnc_misc.c */
struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr, struct ubifs_znode *ubifs_tnc_levelorder_next(const struct ubifs_info *c,
struct ubifs_znode *zr,
struct ubifs_znode *znode); struct ubifs_znode *znode);
int ubifs_search_zbranch(const struct ubifs_info *c, int ubifs_search_zbranch(const struct ubifs_info *c,
const struct ubifs_znode *znode, const struct ubifs_znode *znode,
const union ubifs_key *key, int *n); const union ubifs_key *key, int *n);
struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode); struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode);
struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode); struct ubifs_znode *ubifs_tnc_postorder_next(const struct ubifs_info *c,
long ubifs_destroy_tnc_subtree(struct ubifs_znode *zr); struct ubifs_znode *znode);
long ubifs_destroy_tnc_subtree(const struct ubifs_info *c,
struct ubifs_znode *zr);
struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c, struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,
struct ubifs_zbranch *zbr, struct ubifs_zbranch *zbr,
struct ubifs_znode *parent, int iip); struct ubifs_znode *parent, int iip);
@ -1698,7 +1715,7 @@ struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c,
int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip); int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip);
void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty); void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty);
void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode);
uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits); uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, int nrbits);
struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght); struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght);
/* Needed only in debugging code in lpt_commit.c */ /* Needed only in debugging code in lpt_commit.c */
int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
@ -1755,7 +1772,13 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
size_t size, int flags, bool check_lock); size_t size, int flags, bool check_lock);
ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
size_t size); size_t size);
#ifdef CONFIG_UBIFS_FS_XATTR
void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum);
#else
static inline void ubifs_evict_xattr_inode(struct ubifs_info *c,
ino_t xattr_inum) { }
#endif
#ifdef CONFIG_UBIFS_FS_SECURITY #ifdef CONFIG_UBIFS_FS_SECURITY
extern int ubifs_init_security(struct inode *dentry, struct inode *inode, extern int ubifs_init_security(struct inode *dentry, struct inode *inode,
@ -1812,14 +1835,16 @@ static inline int ubifs_encrypt(const struct inode *inode,
unsigned int in_len, unsigned int *out_len, unsigned int in_len, unsigned int *out_len,
int block) int block)
{ {
ubifs_assert(0); struct ubifs_info *c = inode->i_sb->s_fs_info;
ubifs_assert(c, 0);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int ubifs_decrypt(const struct inode *inode, static inline int ubifs_decrypt(const struct inode *inode,
struct ubifs_data_node *dn, struct ubifs_data_node *dn,
unsigned int *out_len, int block) unsigned int *out_len, int block)
{ {
ubifs_assert(0); struct ubifs_info *c = inode->i_sb->s_fs_info;
ubifs_assert(c, 0);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
#else #else

View File

@ -152,6 +152,12 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
ui->data_len = size; ui->data_len = size;
mutex_lock(&host_ui->ui_mutex); mutex_lock(&host_ui->ui_mutex);
if (!host->i_nlink) {
err = -ENOENT;
goto out_noent;
}
host->i_ctime = current_time(host); host->i_ctime = current_time(host);
host_ui->xattr_cnt += 1; host_ui->xattr_cnt += 1;
host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm)); host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
@ -184,6 +190,7 @@ out_cancel:
host_ui->xattr_size -= CALC_XATTR_BYTES(size); host_ui->xattr_size -= CALC_XATTR_BYTES(size);
host_ui->xattr_names -= fname_len(nm); host_ui->xattr_names -= fname_len(nm);
host_ui->flags &= ~UBIFS_CRYPT_FL; host_ui->flags &= ~UBIFS_CRYPT_FL;
out_noent:
mutex_unlock(&host_ui->ui_mutex); mutex_unlock(&host_ui->ui_mutex);
out_free: out_free:
make_bad_inode(inode); make_bad_inode(inode);
@ -216,7 +223,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
struct ubifs_budget_req req = { .dirtied_ino = 2, struct ubifs_budget_req req = { .dirtied_ino = 2,
.dirtied_ino_d = ALIGN(size, 8) + ALIGN(host_ui->data_len, 8) }; .dirtied_ino_d = ALIGN(size, 8) + ALIGN(host_ui->data_len, 8) };
ubifs_assert(ui->data_len == inode->i_size); ubifs_assert(c, ui->data_len == inode->i_size);
err = ubifs_budget_space(c, &req); err = ubifs_budget_space(c, &req);
if (err) if (err)
return err; return err;
@ -235,6 +242,12 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
mutex_unlock(&ui->ui_mutex); mutex_unlock(&ui->ui_mutex);
mutex_lock(&host_ui->ui_mutex); mutex_lock(&host_ui->ui_mutex);
if (!host->i_nlink) {
err = -ENOENT;
goto out_noent;
}
host->i_ctime = current_time(host); host->i_ctime = current_time(host);
host_ui->xattr_size -= CALC_XATTR_BYTES(old_size); host_ui->xattr_size -= CALC_XATTR_BYTES(old_size);
host_ui->xattr_size += CALC_XATTR_BYTES(size); host_ui->xattr_size += CALC_XATTR_BYTES(size);
@ -256,6 +269,7 @@ static int change_xattr(struct ubifs_info *c, struct inode *host,
out_cancel: out_cancel:
host_ui->xattr_size -= CALC_XATTR_BYTES(size); host_ui->xattr_size -= CALC_XATTR_BYTES(size);
host_ui->xattr_size += CALC_XATTR_BYTES(old_size); host_ui->xattr_size += CALC_XATTR_BYTES(old_size);
out_noent:
mutex_unlock(&host_ui->ui_mutex); mutex_unlock(&host_ui->ui_mutex);
make_bad_inode(inode); make_bad_inode(inode);
out_free: out_free:
@ -291,7 +305,7 @@ int ubifs_xattr_set(struct inode *host, const char *name, const void *value,
int err; int err;
if (check_lock) if (check_lock)
ubifs_assert(inode_is_locked(host)); ubifs_assert(c, inode_is_locked(host));
if (size > UBIFS_MAX_INO_DATA) if (size > UBIFS_MAX_INO_DATA)
return -ERANGE; return -ERANGE;
@ -374,8 +388,8 @@ ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf,
} }
ui = ubifs_inode(inode); ui = ubifs_inode(inode);
ubifs_assert(inode->i_size == ui->data_len); ubifs_assert(c, inode->i_size == ui->data_len);
ubifs_assert(ubifs_inode(host)->xattr_size > ui->data_len); ubifs_assert(c, ubifs_inode(host)->xattr_size > ui->data_len);
mutex_lock(&ui->ui_mutex); mutex_lock(&ui->ui_mutex);
if (buf) { if (buf) {
@ -462,7 +476,7 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
return err; return err;
} }
ubifs_assert(written <= size); ubifs_assert(c, written <= size);
return written; return written;
} }
@ -475,13 +489,19 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
struct ubifs_budget_req req = { .dirtied_ino = 2, .mod_dent = 1, struct ubifs_budget_req req = { .dirtied_ino = 2, .mod_dent = 1,
.dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; .dirtied_ino_d = ALIGN(host_ui->data_len, 8) };
ubifs_assert(ui->data_len == inode->i_size); ubifs_assert(c, ui->data_len == inode->i_size);
err = ubifs_budget_space(c, &req); err = ubifs_budget_space(c, &req);
if (err) if (err)
return err; return err;
mutex_lock(&host_ui->ui_mutex); mutex_lock(&host_ui->ui_mutex);
if (!host->i_nlink) {
err = -ENOENT;
goto out_noent;
}
host->i_ctime = current_time(host); host->i_ctime = current_time(host);
host_ui->xattr_cnt -= 1; host_ui->xattr_cnt -= 1;
host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm)); host_ui->xattr_size -= CALC_DENT_SIZE(fname_len(nm));
@ -501,6 +521,7 @@ out_cancel:
host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm)); host_ui->xattr_size += CALC_DENT_SIZE(fname_len(nm));
host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len); host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
host_ui->xattr_names += fname_len(nm); host_ui->xattr_names += fname_len(nm);
out_noent:
mutex_unlock(&host_ui->ui_mutex); mutex_unlock(&host_ui->ui_mutex);
ubifs_release_budget(c, &req); ubifs_release_budget(c, &req);
make_bad_inode(inode); make_bad_inode(inode);
@ -538,7 +559,10 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
union ubifs_key key; union ubifs_key key;
int err; int err;
ubifs_assert(inode_is_locked(host)); ubifs_assert(c, inode_is_locked(host));
if (!host->i_nlink)
return -ENOENT;
if (fname_len(&nm) > UBIFS_MAX_NLEN) if (fname_len(&nm) > UBIFS_MAX_NLEN)
return -ENAMETOOLONG; return -ENAMETOOLONG;
@ -561,7 +585,7 @@ static int ubifs_xattr_remove(struct inode *host, const char *name)
goto out_free; goto out_free;
} }
ubifs_assert(inode->i_nlink == 1); ubifs_assert(c, inode->i_nlink == 1);
clear_nlink(inode); clear_nlink(inode);
err = remove_xattr(c, host, inode, &nm); err = remove_xattr(c, host, inode, &nm);
if (err) if (err)

View File

@ -285,6 +285,20 @@ struct ubi_attach_req {
__s8 padding[10]; __s8 padding[10];
}; };
/*
* UBI volume flags.
*
* @UBI_VOL_SKIP_CRC_CHECK_FLG: skip the CRC check done on a static volume at
* open time. Only valid for static volumes and
* should only be used if the volume user has a
* way to verify data integrity
*/
enum {
UBI_VOL_SKIP_CRC_CHECK_FLG = 0x1,
};
#define UBI_VOL_VALID_FLGS (UBI_VOL_SKIP_CRC_CHECK_FLG)
/** /**
* struct ubi_mkvol_req - volume description data structure used in * struct ubi_mkvol_req - volume description data structure used in
* volume creation requests. * volume creation requests.
@ -292,7 +306,7 @@ struct ubi_attach_req {
* @alignment: volume alignment * @alignment: volume alignment
* @bytes: volume size in bytes * @bytes: volume size in bytes
* @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME)
* @padding1: reserved for future, not used, has to be zeroed * @flags: volume flags (%UBI_VOL_SKIP_CRC_CHECK_FLG)
* @name_len: volume name length * @name_len: volume name length
* @padding2: reserved for future, not used, has to be zeroed * @padding2: reserved for future, not used, has to be zeroed
* @name: volume name * @name: volume name
@ -321,7 +335,7 @@ struct ubi_mkvol_req {
__s32 alignment; __s32 alignment;
__s64 bytes; __s64 bytes;
__s8 vol_type; __s8 vol_type;
__s8 padding1; __u8 flags;
__s16 name_len; __s16 name_len;
__s8 padding2[4]; __s8 padding2[4];
char name[UBI_MAX_VOLUME_NAME + 1]; char name[UBI_MAX_VOLUME_NAME + 1];