diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-23 15:58:04 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-23 15:58:04 -0700 |
commit | 6f7948f566bf423ddf5ff58dc0198afcf37c0b64 (patch) | |
tree | f6a361d71d971626a27487d32c1379371f2e369b | |
parent | b39d7efc11b93d9150d99a731db26fd36e2facd2 (diff) | |
parent | 99a24e02ccf6604e3020cf9e2c7a042b6ebb655f (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
...
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 |