summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-23 15:58:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-23 15:58:04 -0700
commit6f7948f566bf423ddf5ff58dc0198afcf37c0b64 (patch)
treef6a361d71d971626a27487d32c1379371f2e369b
parentb39d7efc11b93d9150d99a731db26fd36e2facd2 (diff)
parent99a24e02ccf6604e3020cf9e2c7a042b6ebb655f (diff)
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 ...
-rw-r--r--drivers/mtd/ubi/cdev.c11
-rw-r--r--drivers/mtd/ubi/kapi.c2
-rw-r--r--drivers/mtd/ubi/ubi-media.h6
-rw-r--r--drivers/mtd/ubi/ubi.h4
-rw-r--r--drivers/mtd/ubi/vmt.c12
-rw-r--r--drivers/mtd/ubi/vtbl.c23
-rw-r--r--fs/ubifs/Kconfig15
-rw-r--r--fs/ubifs/Makefile3
-rw-r--r--fs/ubifs/budget.c68
-rw-r--r--fs/ubifs/commit.c8
-rw-r--r--fs/ubifs/crypto.c4
-rw-r--r--fs/ubifs/debug.c42
-rw-r--r--fs/ubifs/debug.h14
-rw-r--r--fs/ubifs/dir.c42
-rw-r--r--fs/ubifs/file.c62
-rw-r--r--fs/ubifs/file.h0
-rw-r--r--fs/ubifs/find.c59
-rw-r--r--fs/ubifs/gc.c66
-rw-r--r--fs/ubifs/io.c97
-rw-r--r--fs/ubifs/journal.c72
-rw-r--r--fs/ubifs/key.h14
-rw-r--r--fs/ubifs/log.c12
-rw-r--r--fs/ubifs/lprops.c94
-rw-r--r--fs/ubifs/lpt.c112
-rw-r--r--fs/ubifs/lpt_commit.c50
-rw-r--r--fs/ubifs/master.c2
-rw-r--r--fs/ubifs/misc.c11
-rw-r--r--fs/ubifs/misc.h16
-rw-r--r--fs/ubifs/orphan.c26
-rw-r--r--fs/ubifs/recovery.c14
-rw-r--r--fs/ubifs/replay.c13
-rw-r--r--fs/ubifs/sb.c18
-rw-r--r--fs/ubifs/scan.c2
-rw-r--r--fs/ubifs/shrinker.c12
-rw-r--r--fs/ubifs/super.c76
-rw-r--r--fs/ubifs/tnc.c111
-rw-r--r--fs/ubifs/tnc_commit.c28
-rw-r--r--fs/ubifs/tnc_misc.c40
-rw-r--r--fs/ubifs/ubifs.h39
-rw-r--r--fs/ubifs/xattr.c40
-rw-r--r--include/uapi/mtd/ubi-user.h18
41 files changed, 787 insertions, 571 deletions
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 45c329694a5e..22547d7a84ea 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -367,6 +367,10 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
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);
if (err < 0)
return err;
@@ -622,6 +626,13 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
req->vol_type != UBI_STATIC_VOLUME)
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)
goto bad;
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index d4b2e8744498..e9e9ecbcedcc 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -202,7 +202,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode)
desc->mode = mode;
mutex_lock(&ubi->ckvol_mutex);
- if (!vol->checked) {
+ if (!vol->checked && !vol->skip_check) {
/* This is the first open - check the volume */
err = ubi_check_volume(ubi, vol_id);
if (err < 0) {
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h
index 195ff8ca8211..b5fe8f82281b 100644
--- a/drivers/mtd/ubi/ubi-media.h
+++ b/drivers/mtd/ubi/ubi-media.h
@@ -45,6 +45,11 @@ enum {
* Volume flags used in the volume table record.
*
* @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
* table. UBI automatically re-sizes the volume which has this flag and makes
@@ -76,6 +81,7 @@ enum {
*/
enum {
UBI_VTBL_AUTORESIZE_FLG = 0x01,
+ UBI_VTBL_SKIP_CRC_CHECK_FLG = 0x02,
};
/*
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index f5ba97c46160..d47b9e436e67 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -327,6 +327,9 @@ struct ubi_eba_leb_desc {
* atomic LEB change
*
* @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
* @corrupted: %1 if the volume is corrupted (static volumes only)
* @upd_marker: %1 if the update marker is set for this volume
@@ -374,6 +377,7 @@ struct ubi_volume {
void *upd_buf;
struct ubi_eba_table *eba_tbl;
+ unsigned int skip_check:1;
unsigned int checked:1;
unsigned int corrupted:1;
unsigned int upd_marker:1;
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 0be516780e92..729588b94e41 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -174,6 +174,9 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
vol->dev.class = &ubi_class;
vol->dev.groups = volume_dev_groups;
+ if (req->flags & UBI_VOL_SKIP_CRC_CHECK_FLG)
+ vol->skip_check = 1;
+
spin_lock(&ubi->volumes_lock);
if (vol_id == UBI_VOL_NUM_AUTO) {
/* 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;
else
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);
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");
goto fail;
}
+
+ if (vol->skip_check) {
+ ubi_err(ubi, "bad skip_check");
+ goto fail;
+ }
} else {
if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
ubi_err(ubi, "bad used_ebs");
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 94d7a865b135..1bc82154bb18 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -560,6 +560,9 @@ static int init_volumes(struct ubi_device *ubi,
vol->name[vol->name_len] = '\0';
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) {
/* Auto re-size flag may be set only for one volume */
if (ubi->autoresize_vol_id != -1) {
@@ -579,6 +582,16 @@ static int init_volumes(struct ubi_device *ubi,
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
* 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;
vol->used_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 */
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 83a961bf7280..bbc78549be4c 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -51,9 +51,20 @@ config UBIFS_ATIME_SUPPORT
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
bool "UBIFS Encryption"
- depends on UBIFS_FS && BLOCK
+ depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
select FS_ENCRYPTION
default n
help
@@ -64,7 +75,7 @@ config UBIFS_FS_ENCRYPTION
config UBIFS_FS_SECURITY
bool "UBIFS Security Labels"
- depends on UBIFS_FS
+ depends on UBIFS_FS && UBIFS_FS_XATTR
default y
help
Security labels provide an access control facility to support Linux
diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index 9758f709c736..6197d7e539e4 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -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 += 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 += 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-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o
+ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 11a11b32a2a9..7ef22baf9d15 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -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;
- ubifs_assert(req->new_page <= 1);
- ubifs_assert(req->dirtied_page <= 1);
- ubifs_assert(req->new_dent <= 1);
- ubifs_assert(req->mod_dent <= 1);
- ubifs_assert(req->new_ino <= 1);
- ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA);
- ubifs_assert(req->dirtied_ino <= 4);
- ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
- ubifs_assert(!(req->new_ino_d & 7));
- ubifs_assert(!(req->dirtied_ino_d & 7));
+ ubifs_assert(c, req->new_page <= 1);
+ ubifs_assert(c, req->dirtied_page <= 1);
+ ubifs_assert(c, req->new_dent <= 1);
+ ubifs_assert(c, req->mod_dent <= 1);
+ ubifs_assert(c, req->new_ino <= 1);
+ ubifs_assert(c, req->new_ino_d <= UBIFS_MAX_INO_DATA);
+ ubifs_assert(c, req->dirtied_ino <= 4);
+ ubifs_assert(c, req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
+ ubifs_assert(c, !(req->new_ino_d & 7));
+ ubifs_assert(c, !(req->dirtied_ino_d & 7));
data_growth = calc_data_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:
spin_lock(&c->space_lock);
- ubifs_assert(c->bi.idx_growth >= 0);
- ubifs_assert(c->bi.data_growth >= 0);
- ubifs_assert(c->bi.dd_growth >= 0);
+ ubifs_assert(c, c->bi.idx_growth >= 0);
+ ubifs_assert(c, c->bi.data_growth >= 0);
+ ubifs_assert(c, c->bi.dd_growth >= 0);
if (unlikely(c->bi.nospace) && (c->bi.nospace_rp || !can_use_rp(c))) {
dbg_budg("no space");
@@ -526,20 +526,20 @@ again:
*/
void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req)
{
- ubifs_assert(req->new_page <= 1);
- ubifs_assert(req->dirtied_page <= 1);
- ubifs_assert(req->new_dent <= 1);
- ubifs_assert(req->mod_dent <= 1);
- ubifs_assert(req->new_ino <= 1);
- ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA);
- ubifs_assert(req->dirtied_ino <= 4);
- ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
- ubifs_assert(!(req->new_ino_d & 7));
- ubifs_assert(!(req->dirtied_ino_d & 7));
+ ubifs_assert(c, req->new_page <= 1);
+ ubifs_assert(c, req->dirtied_page <= 1);
+ ubifs_assert(c, req->new_dent <= 1);
+ ubifs_assert(c, req->mod_dent <= 1);
+ ubifs_assert(c, req->new_ino <= 1);
+ ubifs_assert(c, req->new_ino_d <= UBIFS_MAX_INO_DATA);
+ ubifs_assert(c, req->dirtied_ino <= 4);
+ ubifs_assert(c, req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4);
+ ubifs_assert(c, !(req->new_ino_d & 7));
+ ubifs_assert(c, !(req->dirtied_ino_d & 7));
if (!req->recalculate) {
- ubifs_assert(req->idx_growth >= 0);
- ubifs_assert(req->data_growth >= 0);
- ubifs_assert(req->dd_growth >= 0);
+ ubifs_assert(c, req->idx_growth >= 0);
+ ubifs_assert(c, req->data_growth >= 0);
+ ubifs_assert(c, req->dd_growth >= 0);
}
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.min_idx_lebs = ubifs_calc_min_idx_lebs(c);
- ubifs_assert(c->bi.idx_growth >= 0);
- ubifs_assert(c->bi.data_growth >= 0);
- ubifs_assert(c->bi.dd_growth >= 0);
- ubifs_assert(c->bi.min_idx_lebs < c->main_lebs);
- ubifs_assert(!(c->bi.idx_growth & 7));
- ubifs_assert(!(c->bi.data_growth & 7));
- ubifs_assert(!(c->bi.dd_growth & 7));
+ ubifs_assert(c, c->bi.idx_growth >= 0);
+ ubifs_assert(c, c->bi.data_growth >= 0);
+ ubifs_assert(c, c->bi.dd_growth >= 0);
+ ubifs_assert(c, c->bi.min_idx_lebs < c->main_lebs);
+ ubifs_assert(c, !(c->bi.idx_growth & 7));
+ ubifs_assert(c, !(c->bi.data_growth & 7));
+ ubifs_assert(c, !(c->bi.dd_growth & 7));
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;
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;
available = ubifs_calc_available(c, c->bi.min_idx_lebs);
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 63f56619991d..591f2c7a48f0 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -91,9 +91,9 @@ static int nothing_to_commit(struct ubifs_info *c)
if (c->nroot && test_bit(DIRTY_CNODE, &c->nroot->flags))
return 0;
- ubifs_assert(atomic_long_read(&c->dirty_zn_cnt) == 0);
- ubifs_assert(c->dirty_pn_cnt == 0);
- ubifs_assert(c->dirty_nn_cnt == 0);
+ ubifs_assert(c, atomic_long_read(&c->dirty_zn_cnt) == 0);
+ ubifs_assert(c, c->dirty_pn_cnt == 0);
+ ubifs_assert(c, c->dirty_nn_cnt == 0);
return 1;
}
@@ -113,7 +113,7 @@ static int do_commit(struct ubifs_info *c)
struct ubifs_lp_stats lst;
dbg_cmt("start");
- ubifs_assert(!c->ro_media && !c->ro_mount);
+ ubifs_assert(c, !c->ro_media && !c->ro_mount);
if (c->ro_error) {
err = -EROFS;
diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c
index 55c508fe8131..4aaedf2d7f44 100644
--- a/fs/ubifs/crypto.c
+++ b/fs/ubifs/crypto.c
@@ -32,7 +32,7 @@ int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
struct page *ret;
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);
/* pad to full block cipher length */
@@ -63,7 +63,7 @@ int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
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,
offset_in_page(&dn->data), block);
if (err) {
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 7cd8a7b95299..564e330d05b1 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -134,7 +134,7 @@ const char *dbg_snprintf_key(const struct ubifs_info *c,
}
} else
len -= snprintf(p, len, "bad key format %d", c->key_fmt);
- ubifs_assert(len > 0);
+ ubifs_assert(c, len > 0);
return p;
}
@@ -276,7 +276,7 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode)
return;
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);
while (1) {
@@ -931,7 +931,7 @@ void ubifs_dump_tnc(struct ubifs_info *c)
pr_err("\n");
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;
pr_err("== Level %d ==\n", level);
while (znode) {
@@ -940,7 +940,7 @@ void ubifs_dump_tnc(struct ubifs_info *c)
pr_err("== Level %d ==\n", level);
}
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);
}
@@ -1183,7 +1183,7 @@ static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1,
union ubifs_key key;
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);
if (!dent1)
return -ENOMEM;
@@ -1479,7 +1479,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
if (!dbg_is_chk_index(c))
return 0;
- ubifs_assert(mutex_is_locked(&c->tnc_mutex));
+ ubifs_assert(c, mutex_is_locked(&c->tnc_mutex));
if (!c->zroot.znode)
return 0;
@@ -1505,7 +1505,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
}
prev = znode;
- znode = ubifs_tnc_postorder_next(znode);
+ znode = ubifs_tnc_postorder_next(c, znode);
if (!znode)
break;
@@ -2036,7 +2036,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
long long blk_offs;
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
@@ -2066,7 +2066,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
struct ubifs_dent_node *dent = node;
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);
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;
- ubifs_assert(dbg_is_tst_rcvry(c));
+ ubifs_assert(c, dbg_is_tst_rcvry(c));
if (!d->pc_cnt) {
/* First call - decide delay to the power cut */
@@ -3081,6 +3081,28 @@ void dbg_debugfs_exit(void)
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.
* @c: UBIFS file-system description object
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index e03d5179769a..64c6977c189b 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -148,19 +148,21 @@ struct ubifs_global_debug_info {
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))) { \
- pr_crit("UBIFS assert failed in %s at %u (pid %d)\n", \
- __func__, __LINE__, current->pid); \
- dump_stack(); \
+ ubifs_assert_failed((struct ubifs_info *)c, #expr, __FILE__, \
+ __LINE__); \
} \
} while (0)
#define ubifs_assert_cmt_locked(c) do { \
if (unlikely(down_write_trylock(&(c)->commit_sem))) { \
up_write(&(c)->commit_sem); \
- pr_crit("commit lock is not locked!\n"); \
- ubifs_assert(0); \
+ ubifs_err(c, "commit lock is not locked!\n"); \
+ ubifs_assert(c, 0); \
} \
} while (0)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 9da224d4f2da..5767b373a8ff 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -240,8 +240,8 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
}
if (nm.hash) {
- ubifs_assert(fname_len(&nm) == 0);
- ubifs_assert(fname_name(&nm) == NULL);
+ ubifs_assert(c, fname_len(&nm) == 0);
+ ubifs_assert(c, fname_name(&nm) == NULL);
dent_key_init_hash(c, &key, dir->i_ino, nm.hash);
err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash);
} else {
@@ -404,7 +404,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
if (whiteout) {
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);
@@ -421,7 +421,7 @@ static int do_tmpfile(struct inode *dir, struct dentry *dentry,
} else {
d_tmpfile(dentry, inode);
}
- ubifs_assert(ui->dirty);
+ ubifs_assert(c, ui->dirty);
instantiated = 1;
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 ".." */
if (ctx->pos < 2) {
- ubifs_assert(!file->private_data);
+ ubifs_assert(c, !file->private_data);
if (!dir_emit_dots(file, ctx)) {
if (encrypted)
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",
(unsigned long long)le64_to_cpu(dent->inum),
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);
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",
dentry, inode->i_ino,
inode->i_nlink, dir->i_ino);
- ubifs_assert(inode_is_locked(dir));
- ubifs_assert(inode_is_locked(inode));
+ ubifs_assert(c, inode_is_locked(dir));
+ ubifs_assert(c, inode_is_locked(inode));
err = fscrypt_prepare_link(old_dentry, dir, dentry);
if (err)
@@ -804,8 +804,8 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
sz_change = CALC_DENT_SIZE(fname_len(&nm));
- ubifs_assert(inode_is_locked(dir));
- ubifs_assert(inode_is_locked(inode));
+ ubifs_assert(c, inode_is_locked(dir));
+ ubifs_assert(c, inode_is_locked(inode));
err = dbg_check_synced_i_size(c, inode);
if (err)
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,
inode->i_ino, dir->i_ino);
- ubifs_assert(inode_is_locked(dir));
- ubifs_assert(inode_is_locked(inode));
+ ubifs_assert(c, inode_is_locked(dir));
+ ubifs_assert(c, inode_is_locked(inode));
err = ubifs_check_dir_empty(d_inode(dentry));
if (err)
return err;
@@ -1123,8 +1123,7 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
struct ubifs_inode *ui;
struct ubifs_inode *dir_ui = ubifs_inode(dir);
struct ubifs_info *c = dir->i_sb->s_fs_info;
- int err, len = strlen(symname);
- int sz_change = CALC_DENT_SIZE(len);
+ int err, sz_change, len = strlen(symname);
struct fscrypt_str disk_link;
struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1,
.new_ino_d = ALIGN(len, 8),
@@ -1151,6 +1150,8 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
if (err)
goto out_budg;
+ sz_change = CALC_DENT_SIZE(fname_len(&nm));
+
inode = ubifs_new_inode(c, dir, S_IFLNK | S_IRWXUGO);
if (IS_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);
if (unlink)
- ubifs_assert(inode_is_locked(new_inode));
+ ubifs_assert(c, inode_is_locked(new_inode));
if (unlink && is_dir) {
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->data = dev;
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);
@@ -1508,7 +1509,7 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
int err;
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);
if (err)
@@ -1555,12 +1556,13 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned int flags)
{
int err;
+ struct ubifs_info *c = old_dir->i_sb->s_fs_info;
if (flags & ~(RENAME_NOREPLACE | RENAME_WHITEOUT | RENAME_EXCHANGE))
return -EINVAL;
- ubifs_assert(inode_is_locked(old_dir));
- ubifs_assert(inode_is_locked(new_dir));
+ ubifs_assert(c, inode_is_locked(old_dir));
+ ubifs_assert(c, inode_is_locked(new_dir));
err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
flags);
@@ -1647,7 +1649,9 @@ const struct inode_operations ubifs_dir_inode_operations = {
.rename = ubifs_rename,
.setattr = ubifs_setattr,
.getattr = ubifs_getattr,
+#ifdef CONFIG_UBIFS_FS_XATTR
.listxattr = ubifs_listxattr,
+#endif
#ifdef CONFIG_UBIFS_ATIME_SUPPORT
.update_time = ubifs_update_time,
#endif