Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
* 'linux-next' of git://git.infradead.org/ubifs-2.6: (32 commits) MAINTAINERS: change e-mail of Adrian Hunter UBIFS: fix master node recovery UBIFS: improve power cut emulation testing UBIFS: rename recovery testing variables UBIFS: remove custom list of superblocks UBIFS: stop re-defining UBI operations UBIFS: switch to I/O helpers UBIFS: switch to ubifs_leb_write UBIFS: switch to ubifs_leb_read UBIFS: introduce more I/O helpers UBIFS: always print stacktrace when switching to R/O mode UBIFS: remove unused and unneeded debugging function UBIFS: add global debugfs knobs UBIFS: introduce debugfs helpers UBIFS: re-arrange debugging code a bit UBIFS: be more informative in failure mode UBIFS: switch self-check knobs to debugfs UBIFS: lessen amount of debugging check types UBIFS: introduce helper functions for debugging checks and tests UBIFS: amend debugging inode size check function prototype ...
This commit is contained in:
commit
59a7ac1211
|
@ -111,34 +111,6 @@ The following is an example of the kernel boot arguments to attach mtd0
|
||||||
to UBI and mount volume "rootfs":
|
to UBI and mount volume "rootfs":
|
||||||
ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs
|
ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs
|
||||||
|
|
||||||
|
|
||||||
Module Parameters for Debugging
|
|
||||||
===============================
|
|
||||||
|
|
||||||
When UBIFS has been compiled with debugging enabled, there are 2 module
|
|
||||||
parameters that are available to control aspects of testing and debugging.
|
|
||||||
|
|
||||||
debug_chks Selects extra checks that UBIFS can do while running:
|
|
||||||
|
|
||||||
Check Flag value
|
|
||||||
|
|
||||||
General checks 1
|
|
||||||
Check Tree Node Cache (TNC) 2
|
|
||||||
Check indexing tree size 4
|
|
||||||
Check orphan area 8
|
|
||||||
Check old indexing tree 16
|
|
||||||
Check LEB properties (lprops) 32
|
|
||||||
Check leaf nodes and inodes 64
|
|
||||||
|
|
||||||
debug_tsts Selects a mode of testing, as follows:
|
|
||||||
|
|
||||||
Test mode Flag value
|
|
||||||
|
|
||||||
Failure mode for recovery testing 4
|
|
||||||
|
|
||||||
For example, set debug_chks to 3 to enable general and TNC checks.
|
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
List of maintainers and how to submit kernel changes
|
List of maintainers and how to submit kernel changes
|
||||||
|
|
||||||
Please try to follow the guidelines below. This will make things
|
Please try to follow the guidelines below. This will make things
|
||||||
|
@ -6321,7 +6322,7 @@ F: drivers/scsi/u14-34f.c
|
||||||
|
|
||||||
UBI FILE SYSTEM (UBIFS)
|
UBI FILE SYSTEM (UBIFS)
|
||||||
M: Artem Bityutskiy <dedekind1@gmail.com>
|
M: Artem Bityutskiy <dedekind1@gmail.com>
|
||||||
M: Adrian Hunter <adrian.hunter@nokia.com>
|
M: Adrian Hunter <adrian.hunter@intel.com>
|
||||||
L: linux-mtd@lists.infradead.org
|
L: linux-mtd@lists.infradead.org
|
||||||
T: git git://git.infradead.org/ubifs-2.6.git
|
T: git git://git.infradead.org/ubifs-2.6.git
|
||||||
W: http://www.linux-mtd.infradead.org/doc/ubifs.html
|
W: http://www.linux-mtd.infradead.org/doc/ubifs.html
|
||||||
|
|
|
@ -78,7 +78,7 @@ static int nothing_to_commit(struct ubifs_info *c)
|
||||||
* If the root TNC node is dirty, we definitely have something to
|
* If the root TNC node is dirty, we definitely have something to
|
||||||
* commit.
|
* commit.
|
||||||
*/
|
*/
|
||||||
if (c->zroot.znode && test_bit(DIRTY_ZNODE, &c->zroot.znode->flags))
|
if (c->zroot.znode && ubifs_zn_dirty(c->zroot.znode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -418,7 +418,7 @@ int ubifs_run_commit(struct ubifs_info *c)
|
||||||
|
|
||||||
spin_lock(&c->cs_lock);
|
spin_lock(&c->cs_lock);
|
||||||
if (c->cmt_state == COMMIT_BROKEN) {
|
if (c->cmt_state == COMMIT_BROKEN) {
|
||||||
err = -EINVAL;
|
err = -EROFS;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +444,7 @@ int ubifs_run_commit(struct ubifs_info *c)
|
||||||
* re-check it.
|
* re-check it.
|
||||||
*/
|
*/
|
||||||
if (c->cmt_state == COMMIT_BROKEN) {
|
if (c->cmt_state == COMMIT_BROKEN) {
|
||||||
err = -EINVAL;
|
err = -EROFS;
|
||||||
goto out_cmt_unlock;
|
goto out_cmt_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,7 +576,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
|
||||||
struct idx_node *i;
|
struct idx_node *i;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX))
|
if (!dbg_is_chk_index(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&list);
|
INIT_LIST_HEAD(&list);
|
||||||
|
|
780
fs/ubifs/debug.c
780
fs/ubifs/debug.c
File diff suppressed because it is too large
Load Diff
237
fs/ubifs/debug.h
237
fs/ubifs/debug.h
|
@ -31,18 +31,25 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
|
||||||
|
|
||||||
#ifdef CONFIG_UBIFS_FS_DEBUG
|
#ifdef CONFIG_UBIFS_FS_DEBUG
|
||||||
|
|
||||||
#include <linux/random.h>
|
/*
|
||||||
|
* The UBIFS debugfs directory name pattern and maximum name length (3 for "ubi"
|
||||||
|
* + 1 for "_" and plus 2x2 for 2 UBI numbers and 1 for the trailing zero byte.
|
||||||
|
*/
|
||||||
|
#define UBIFS_DFS_DIR_NAME "ubi%d_%d"
|
||||||
|
#define UBIFS_DFS_DIR_LEN (3 + 1 + 2*2 + 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ubifs_debug_info - per-FS debugging information.
|
* ubifs_debug_info - per-FS debugging information.
|
||||||
* @old_zroot: old index root - used by 'dbg_check_old_index()'
|
* @old_zroot: old index root - used by 'dbg_check_old_index()'
|
||||||
* @old_zroot_level: old index root level - used by 'dbg_check_old_index()'
|
* @old_zroot_level: old index root level - used by 'dbg_check_old_index()'
|
||||||
* @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()'
|
* @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()'
|
||||||
* @failure_mode: failure mode for recovery testing
|
*
|
||||||
* @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
|
* @pc_happened: non-zero if an emulated power cut happened
|
||||||
* @fail_timeout: time in jiffies when delay of failure mode expires
|
* @pc_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
|
||||||
* @fail_cnt: current number of calls to failure mode I/O functions
|
* @pc_timeout: time in jiffies when delay of failure mode expires
|
||||||
* @fail_cnt_max: number of calls by which to delay failure mode
|
* @pc_cnt: current number of calls to failure mode I/O functions
|
||||||
|
* @pc_cnt_max: number of calls by which to delay failure mode
|
||||||
|
*
|
||||||
* @chk_lpt_sz: used by LPT tree size checker
|
* @chk_lpt_sz: used by LPT tree size checker
|
||||||
* @chk_lpt_sz2: used by LPT tree size checker
|
* @chk_lpt_sz2: used by LPT tree size checker
|
||||||
* @chk_lpt_wastage: used by LPT tree size checker
|
* @chk_lpt_wastage: used by LPT tree size checker
|
||||||
|
@ -56,21 +63,36 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
|
||||||
* @saved_free: saved amount of free space
|
* @saved_free: saved amount of free space
|
||||||
* @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt
|
* @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt
|
||||||
*
|
*
|
||||||
|
* @chk_gen: if general extra checks are enabled
|
||||||
|
* @chk_index: if index xtra checks are enabled
|
||||||
|
* @chk_orph: if orphans extra checks are enabled
|
||||||
|
* @chk_lprops: if lprops extra checks are enabled
|
||||||
|
* @chk_fs: if UBIFS contents extra checks are enabled
|
||||||
|
* @tst_rcvry: if UBIFS recovery testing mode enabled
|
||||||
|
*
|
||||||
* @dfs_dir_name: name of debugfs directory containing this file-system's files
|
* @dfs_dir_name: name of debugfs directory containing this file-system's files
|
||||||
* @dfs_dir: direntry object of the file-system debugfs directory
|
* @dfs_dir: direntry object of the file-system debugfs directory
|
||||||
* @dfs_dump_lprops: "dump lprops" debugfs knob
|
* @dfs_dump_lprops: "dump lprops" debugfs knob
|
||||||
* @dfs_dump_budg: "dump budgeting information" debugfs knob
|
* @dfs_dump_budg: "dump budgeting information" debugfs knob
|
||||||
* @dfs_dump_tnc: "dump TNC" debugfs knob
|
* @dfs_dump_tnc: "dump TNC" debugfs knob
|
||||||
|
* @dfs_chk_gen: debugfs knob to enable UBIFS general extra checks
|
||||||
|
* @dfs_chk_index: debugfs knob to enable UBIFS index extra checks
|
||||||
|
* @dfs_chk_orph: debugfs knob to enable UBIFS orphans extra checks
|
||||||
|
* @dfs_chk_lprops: debugfs knob to enable UBIFS LEP properties extra checks
|
||||||
|
* @dfs_chk_fs: debugfs knob to enable UBIFS contents extra checks
|
||||||
|
* @dfs_tst_rcvry: debugfs knob to enable UBIFS recovery testing
|
||||||
*/
|
*/
|
||||||
struct ubifs_debug_info {
|
struct ubifs_debug_info {
|
||||||
struct ubifs_zbranch old_zroot;
|
struct ubifs_zbranch old_zroot;
|
||||||
int old_zroot_level;
|
int old_zroot_level;
|
||||||
unsigned long long old_zroot_sqnum;
|
unsigned long long old_zroot_sqnum;
|
||||||
int failure_mode;
|
|
||||||
int fail_delay;
|
int pc_happened;
|
||||||
unsigned long fail_timeout;
|
int pc_delay;
|
||||||
unsigned int fail_cnt;
|
unsigned long pc_timeout;
|
||||||
unsigned int fail_cnt_max;
|
unsigned int pc_cnt;
|
||||||
|
unsigned int pc_cnt_max;
|
||||||
|
|
||||||
long long chk_lpt_sz;
|
long long chk_lpt_sz;
|
||||||
long long chk_lpt_sz2;
|
long long chk_lpt_sz2;
|
||||||
long long chk_lpt_wastage;
|
long long chk_lpt_wastage;
|
||||||
|
@ -84,11 +106,43 @@ struct ubifs_debug_info {
|
||||||
long long saved_free;
|
long long saved_free;
|
||||||
int saved_idx_gc_cnt;
|
int saved_idx_gc_cnt;
|
||||||
|
|
||||||
char dfs_dir_name[100];
|
unsigned int chk_gen:1;
|
||||||
|
unsigned int chk_index:1;
|
||||||
|
unsigned int chk_orph:1;
|
||||||
|
unsigned int chk_lprops:1;
|
||||||
|
unsigned int chk_fs:1;
|
||||||
|
unsigned int tst_rcvry:1;
|
||||||
|
|
||||||
|
char dfs_dir_name[UBIFS_DFS_DIR_LEN + 1];
|
||||||
struct dentry *dfs_dir;
|
struct dentry *dfs_dir;
|
||||||
struct dentry *dfs_dump_lprops;
|
struct dentry *dfs_dump_lprops;
|
||||||
struct dentry *dfs_dump_budg;
|
struct dentry *dfs_dump_budg;
|
||||||
struct dentry *dfs_dump_tnc;
|
struct dentry *dfs_dump_tnc;
|
||||||
|
struct dentry *dfs_chk_gen;
|
||||||
|
struct dentry *dfs_chk_index;
|
||||||
|
struct dentry *dfs_chk_orph;
|
||||||
|
struct dentry *dfs_chk_lprops;
|
||||||
|
struct dentry *dfs_chk_fs;
|
||||||
|
struct dentry *dfs_tst_rcvry;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ubifs_global_debug_info - global (not per-FS) UBIFS debugging information.
|
||||||
|
*
|
||||||
|
* @chk_gen: if general extra checks are enabled
|
||||||
|
* @chk_index: if index xtra checks are enabled
|
||||||
|
* @chk_orph: if orphans extra checks are enabled
|
||||||
|
* @chk_lprops: if lprops extra checks are enabled
|
||||||
|
* @chk_fs: if UBIFS contents extra checks are enabled
|
||||||
|
* @tst_rcvry: if UBIFS recovery testing mode enabled
|
||||||
|
*/
|
||||||
|
struct ubifs_global_debug_info {
|
||||||
|
unsigned int chk_gen:1;
|
||||||
|
unsigned int chk_index:1;
|
||||||
|
unsigned int chk_orph:1;
|
||||||
|
unsigned int chk_lprops:1;
|
||||||
|
unsigned int chk_fs:1;
|
||||||
|
unsigned int tst_rcvry:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ubifs_assert(expr) do { \
|
#define ubifs_assert(expr) do { \
|
||||||
|
@ -127,6 +181,8 @@ const char *dbg_key_str1(const struct ubifs_info *c,
|
||||||
#define DBGKEY(key) dbg_key_str0(c, (key))
|
#define DBGKEY(key) dbg_key_str0(c, (key))
|
||||||
#define DBGKEY1(key) dbg_key_str1(c, (key))
|
#define DBGKEY1(key) dbg_key_str1(c, (key))
|
||||||
|
|
||||||
|
extern spinlock_t dbg_lock;
|
||||||
|
|
||||||
#define ubifs_dbg_msg(type, fmt, ...) do { \
|
#define ubifs_dbg_msg(type, fmt, ...) do { \
|
||||||
spin_lock(&dbg_lock); \
|
spin_lock(&dbg_lock); \
|
||||||
pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \
|
pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \
|
||||||
|
@ -162,41 +218,36 @@ const char *dbg_key_str1(const struct ubifs_info *c,
|
||||||
/* Additional recovery messages */
|
/* Additional recovery messages */
|
||||||
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__)
|
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/*
|
extern struct ubifs_global_debug_info ubifs_dbg;
|
||||||
* Debugging check flags.
|
|
||||||
*
|
|
||||||
* UBIFS_CHK_GEN: general checks
|
|
||||||
* UBIFS_CHK_TNC: check TNC
|
|
||||||
* UBIFS_CHK_IDX_SZ: check index size
|
|
||||||
* UBIFS_CHK_ORPH: check orphans
|
|
||||||
* UBIFS_CHK_OLD_IDX: check the old index
|
|
||||||
* UBIFS_CHK_LPROPS: check lprops
|
|
||||||
* UBIFS_CHK_FS: check the file-system
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
UBIFS_CHK_GEN = 0x1,
|
|
||||||
UBIFS_CHK_TNC = 0x2,
|
|
||||||
UBIFS_CHK_IDX_SZ = 0x4,
|
|
||||||
UBIFS_CHK_ORPH = 0x8,
|
|
||||||
UBIFS_CHK_OLD_IDX = 0x10,
|
|
||||||
UBIFS_CHK_LPROPS = 0x20,
|
|
||||||
UBIFS_CHK_FS = 0x40,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
static inline int dbg_is_chk_gen(const struct ubifs_info *c)
|
||||||
* Special testing flags.
|
{
|
||||||
*
|
return !!(ubifs_dbg.chk_gen || c->dbg->chk_gen);
|
||||||
* UBIFS_TST_RCVRY: failure mode for recovery testing
|
}
|
||||||
*/
|
static inline int dbg_is_chk_index(const struct ubifs_info *c)
|
||||||
enum {
|
{
|
||||||
UBIFS_TST_RCVRY = 0x4,
|
return !!(ubifs_dbg.chk_index || c->dbg->chk_index);
|
||||||
};
|
}
|
||||||
|
static inline int dbg_is_chk_orph(const struct ubifs_info *c)
|
||||||
extern spinlock_t dbg_lock;
|
{
|
||||||
|
return !!(ubifs_dbg.chk_orph || c->dbg->chk_orph);
|
||||||
extern unsigned int ubifs_msg_flags;
|
}
|
||||||
extern unsigned int ubifs_chk_flags;
|
static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
|
||||||
extern unsigned int ubifs_tst_flags;
|
{
|
||||||
|
return !!(ubifs_dbg.chk_lprops || c->dbg->chk_lprops);
|
||||||
|
}
|
||||||
|
static inline int dbg_is_chk_fs(const struct ubifs_info *c)
|
||||||
|
{
|
||||||
|
return !!(ubifs_dbg.chk_fs || c->dbg->chk_fs);
|
||||||
|
}
|
||||||
|
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
|
||||||
|
{
|
||||||
|
return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry);
|
||||||
|
}
|
||||||
|
static inline int dbg_is_power_cut(const struct ubifs_info *c)
|
||||||
|
{
|
||||||
|
return !!c->dbg->pc_happened;
|
||||||
|
}
|
||||||
|
|
||||||
int ubifs_debugging_init(struct ubifs_info *c);
|
int ubifs_debugging_init(struct ubifs_info *c);
|
||||||
void ubifs_debugging_exit(struct ubifs_info *c);
|
void ubifs_debugging_exit(struct ubifs_info *c);
|
||||||
|
@ -207,7 +258,7 @@ const char *dbg_cstate(int cmt_state);
|
||||||
const char *dbg_jhead(int jhead);
|
const char *dbg_jhead(int jhead);
|
||||||
const char *dbg_get_key_dump(const struct ubifs_info *c,
|
const char *dbg_get_key_dump(const struct ubifs_info *c,
|
||||||
const union ubifs_key *key);
|
const union ubifs_key *key);
|
||||||
void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode);
|
void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode);
|
||||||
void dbg_dump_node(const struct ubifs_info *c, const void *node);
|
void dbg_dump_node(const struct ubifs_info *c, const void *node);
|
||||||
void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum,
|
void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum,
|
||||||
int offs);
|
int offs);
|
||||||
|
@ -240,8 +291,8 @@ int dbg_check_cats(struct ubifs_info *c);
|
||||||
int dbg_check_ltab(struct ubifs_info *c);
|
int dbg_check_ltab(struct ubifs_info *c);
|
||||||
int dbg_chk_lpt_free_spc(struct ubifs_info *c);
|
int dbg_chk_lpt_free_spc(struct ubifs_info *c);
|
||||||
int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len);
|
int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len);
|
||||||
int dbg_check_synced_i_size(struct inode *inode);
|
int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode);
|
||||||
int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir);
|
int dbg_check_dir(struct ubifs_info *c, const struct inode *dir);
|
||||||
int dbg_check_tnc(struct ubifs_info *c, int extra);
|
int dbg_check_tnc(struct ubifs_info *c, int extra);
|
||||||
int dbg_check_idx_size(struct ubifs_info *c, long long idx_size);
|
int dbg_check_idx_size(struct ubifs_info *c, long long idx_size);
|
||||||
int dbg_check_filesystem(struct ubifs_info *c);
|
int dbg_check_filesystem(struct ubifs_info *c);
|
||||||
|
@ -254,54 +305,12 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
|
||||||
int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
|
int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
|
||||||
int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
|
int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
|
||||||
|
|
||||||
/* Force the use of in-the-gaps method for testing */
|
int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
|
||||||
static inline int dbg_force_in_the_gaps_enabled(void)
|
|
||||||
{
|
|
||||||
return ubifs_chk_flags & UBIFS_CHK_GEN;
|
|
||||||
}
|
|
||||||
int dbg_force_in_the_gaps(void);
|
|
||||||
|
|
||||||
/* Failure mode for recovery testing */
|
|
||||||
#define dbg_failure_mode (ubifs_tst_flags & UBIFS_TST_RCVRY)
|
|
||||||
|
|
||||||
#ifndef UBIFS_DBG_PRESERVE_UBI
|
|
||||||
#define ubi_leb_read dbg_leb_read
|
|
||||||
#define ubi_leb_write dbg_leb_write
|
|
||||||
#define ubi_leb_change dbg_leb_change
|
|
||||||
#define ubi_leb_erase dbg_leb_erase
|
|
||||||
#define ubi_leb_unmap dbg_leb_unmap
|
|
||||||
#define ubi_is_mapped dbg_is_mapped
|
|
||||||
#define ubi_leb_map dbg_leb_map
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
|
|
||||||
int len, int check);
|
|
||||||
int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
|
|
||||||
int offset, int len, int dtype);
|
|
||||||
int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
|
|
||||||
int len, int dtype);
|
int len, int dtype);
|
||||||
int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum);
|
int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
|
||||||
int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum);
|
int dtype);
|
||||||
int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum);
|
int dbg_leb_unmap(struct ubifs_info *c, int lnum);
|
||||||
int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype);
|
int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype);
|
||||||
|
|
||||||
static inline int dbg_read(struct ubi_volume_desc *desc, int lnum, char *buf,
|
|
||||||
int offset, int len)
|
|
||||||
{
|
|
||||||
return dbg_leb_read(desc, lnum, buf, offset, len, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int dbg_write(struct ubi_volume_desc *desc, int lnum,
|
|
||||||
const void *buf, int offset, int len)
|
|
||||||
{
|
|
||||||
return dbg_leb_write(desc, lnum, buf, offset, len, UBI_UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
|
|
||||||
const void *buf, int len)
|
|
||||||
{
|
|
||||||
return dbg_leb_change(desc, lnum, buf, len, UBI_UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Debugfs-related stuff */
|
/* Debugfs-related stuff */
|
||||||
int dbg_debugfs_init(void);
|
int dbg_debugfs_init(void);
|
||||||
|
@ -313,7 +322,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
|
||||||
|
|
||||||
/* Use "if (0)" to make compiler check arguments even if debugging is off */
|
/* Use "if (0)" to make compiler check arguments even if debugging is off */
|
||||||
#define ubifs_assert(expr) do { \
|
#define ubifs_assert(expr) do { \
|
||||||
if (0 && (expr)) \
|
if (0) \
|
||||||
printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
|
printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
|
||||||
__func__, __LINE__, current->pid); \
|
__func__, __LINE__, current->pid); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -323,6 +332,9 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
|
||||||
ubifs_err(fmt, ##__VA_ARGS__); \
|
ubifs_err(fmt, ##__VA_ARGS__); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define DBGKEY(key) ((char *)(key))
|
||||||
|
#define DBGKEY1(key) ((char *)(key))
|
||||||
|
|
||||||
#define ubifs_dbg_msg(fmt, ...) do { \
|
#define ubifs_dbg_msg(fmt, ...) do { \
|
||||||
if (0) \
|
if (0) \
|
||||||
pr_debug(fmt "\n", ##__VA_ARGS__); \
|
pr_debug(fmt "\n", ##__VA_ARGS__); \
|
||||||
|
@ -346,9 +358,6 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
|
||||||
#define dbg_scan(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
|
#define dbg_scan(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
|
||||||
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
|
#define dbg_rcvry(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define DBGKEY(key) ((char *)(key))
|
|
||||||
#define DBGKEY1(key) ((char *)(key))
|
|
||||||
|
|
||||||
static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; }
|
static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; }
|
||||||
static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; }
|
static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; }
|
||||||
static inline const char *dbg_ntype(int type) { return ""; }
|
static inline const char *dbg_ntype(int type) { return ""; }
|
||||||
|
@ -357,7 +366,7 @@ static inline const char *dbg_jhead(int jhead) { return ""; }
|
||||||
static inline const char *
|
static inline const char *
|
||||||
dbg_get_key_dump(const struct ubifs_info *c,
|
dbg_get_key_dump(const struct ubifs_info *c,
|
||||||
const union ubifs_key *key) { return ""; }
|
const union ubifs_key *key) { return ""; }
|
||||||
static inline void dbg_dump_inode(const struct ubifs_info *c,
|
static inline void dbg_dump_inode(struct ubifs_info *c,
|
||||||
const struct inode *inode) { return; }
|
const struct inode *inode) { return; }
|
||||||
static inline void dbg_dump_node(const struct ubifs_info *c,
|
static inline void dbg_dump_node(const struct ubifs_info *c,
|
||||||
const void *node) { return; }
|
const void *node) { return; }
|
||||||
|
@ -409,8 +418,10 @@ static inline int dbg_check_ltab(struct ubifs_info *c) { return 0; }
|
||||||
static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; }
|
static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; }
|
||||||
static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
|
static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
|
||||||
int action, int len) { return 0; }
|
int action, int len) { return 0; }
|
||||||
static inline int dbg_check_synced_i_size(struct inode *inode) { return 0; }
|
static inline int
|
||||||
static inline int dbg_check_dir_size(struct ubifs_info *c,
|
dbg_check_synced_i_size(const struct ubifs_info *c,
|
||||||
|
struct inode *inode) { return 0; }
|
||||||
|
static inline int dbg_check_dir(struct ubifs_info *c,
|
||||||
const struct inode *dir) { return 0; }
|
const struct inode *dir) { return 0; }
|
||||||
static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; }
|
static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; }
|
||||||
static inline int dbg_check_idx_size(struct ubifs_info *c,
|
static inline int dbg_check_idx_size(struct ubifs_info *c,
|
||||||
|
@ -431,9 +442,23 @@ static inline int
|
||||||
dbg_check_nondata_nodes_order(struct ubifs_info *c,
|
dbg_check_nondata_nodes_order(struct ubifs_info *c,
|
||||||
struct list_head *head) { return 0; }
|
struct list_head *head) { return 0; }
|
||||||
|
|
||||||
static inline int dbg_force_in_the_gaps(void) { return 0; }
|
static inline int dbg_leb_write(struct ubifs_info *c, int lnum,
|
||||||
#define dbg_force_in_the_gaps_enabled() 0
|
const void *buf, int offset,
|
||||||
#define dbg_failure_mode 0
|
int len, int dtype) { return 0; }
|
||||||
|
static inline int dbg_leb_change(struct ubifs_info *c, int lnum,
|
||||||
|
const void *buf, int len,
|
||||||
|
int dtype) { return 0; }
|
||||||
|
static inline int dbg_leb_unmap(struct ubifs_info *c, int lnum) { return 0; }
|
||||||
|
static inline int dbg_leb_map(struct ubifs_info *c, int lnum,
|
||||||
|
int dtype) { return 0; }
|
||||||
|
|
||||||
|
static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
|
||||||
|
static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
|
||||||
|
static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; }
|
||||||
|
static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; }
|
||||||
|
static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; }
|
||||||
|
static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; }
|
||||||
|
static inline int dbg_is_power_cut(const struct ubifs_info *c) { return 0; }
|
||||||
|
|
||||||
static inline int dbg_debugfs_init(void) { return 0; }
|
static inline int dbg_debugfs_init(void) { return 0; }
|
||||||
static inline void dbg_debugfs_exit(void) { return; }
|
static inline void dbg_debugfs_exit(void) { return; }
|
||||||
|
|
|
@ -102,7 +102,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
|
||||||
* UBIFS has to fully control "clean <-> dirty" transitions of inodes
|
* UBIFS has to fully control "clean <-> dirty" transitions of inodes
|
||||||
* to make budgeting work.
|
* to make budgeting work.
|
||||||
*/
|
*/
|
||||||
inode->i_flags |= (S_NOCMTIME);
|
inode->i_flags |= S_NOCMTIME;
|
||||||
|
|
||||||
inode_init_owner(inode, dir, mode);
|
inode_init_owner(inode, dir, mode);
|
||||||
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
inode->i_mtime = inode->i_atime = inode->i_ctime =
|
||||||
|
@ -172,9 +172,11 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
|
||||||
|
|
||||||
#ifdef CONFIG_UBIFS_FS_DEBUG
|
#ifdef CONFIG_UBIFS_FS_DEBUG
|
||||||
|
|
||||||
static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm)
|
static int dbg_check_name(const struct ubifs_info *c,
|
||||||
|
const struct ubifs_dent_node *dent,
|
||||||
|
const struct qstr *nm)
|
||||||
{
|
{
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
|
if (!dbg_is_chk_gen(c))
|
||||||
return 0;
|
return 0;
|
||||||
if (le16_to_cpu(dent->nlen) != nm->len)
|
if (le16_to_cpu(dent->nlen) != nm->len)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -185,7 +187,7 @@ static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define dbg_check_name(dent, nm) 0
|
#define dbg_check_name(c, dent, nm) 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -219,7 +221,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbg_check_name(dent, &dentry->d_name)) {
|
if (dbg_check_name(c, dent, &dentry->d_name)) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -522,7 +524,7 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
|
||||||
ubifs_assert(mutex_is_locked(&dir->i_mutex));
|
ubifs_assert(mutex_is_locked(&dir->i_mutex));
|
||||||
ubifs_assert(mutex_is_locked(&inode->i_mutex));
|
ubifs_assert(mutex_is_locked(&inode->i_mutex));
|
||||||
|
|
||||||
err = dbg_check_synced_i_size(inode);
|
err = dbg_check_synced_i_size(c, inode);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -577,7 +579,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
|
||||||
inode->i_nlink, dir->i_ino);
|
inode->i_nlink, dir->i_ino);
|
||||||
ubifs_assert(mutex_is_locked(&dir->i_mutex));
|
ubifs_assert(mutex_is_locked(&dir->i_mutex));
|
||||||
ubifs_assert(mutex_is_locked(&inode->i_mutex));
|
ubifs_assert(mutex_is_locked(&inode->i_mutex));
|
||||||
err = dbg_check_synced_i_size(inode);
|
err = dbg_check_synced_i_size(c, inode);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
@ -1263,7 +1263,7 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = dbg_check_synced_i_size(inode);
|
err = dbg_check_synced_i_size(c, inode);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
158
fs/ubifs/io.c
158
fs/ubifs/io.c
|
@ -86,8 +86,125 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
|
||||||
c->no_chk_data_crc = 0;
|
c->no_chk_data_crc = 0;
|
||||||
c->vfs_sb->s_flags |= MS_RDONLY;
|
c->vfs_sb->s_flags |= MS_RDONLY;
|
||||||
ubifs_warn("switched to read-only mode, error %d", err);
|
ubifs_warn("switched to read-only mode, error %d", err);
|
||||||
|
dump_stack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Below are simple wrappers over UBI I/O functions which include some
|
||||||
|
* additional checks and UBIFS debugging stuff. See corresponding UBI function
|
||||||
|
* for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
|
||||||
|
int len, int even_ebadmsg)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = ubi_read(c->ubi, lnum, buf, offs, len);
|
||||||
|
/*
|
||||||
|
* In case of %-EBADMSG print the error message only if the
|
||||||
|
* @even_ebadmsg is true.
|
||||||
|
*/
|
||||||
|
if (err && (err != -EBADMSG || even_ebadmsg)) {
|
||||||
|
ubifs_err("reading %d bytes from LEB %d:%d failed, error %d",
|
||||||
|
len, lnum, offs, err);
|
||||||
dbg_dump_stack();
|
dbg_dump_stack();
|
||||||
}
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
|
||||||
|
int len, int dtype)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
ubifs_assert(!c->ro_media && !c->ro_mount);
|
||||||
|
if (c->ro_error)
|
||||||
|
return -EROFS;
|
||||||
|
if (!dbg_is_tst_rcvry(c))
|
||||||
|
err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
|
||||||
|
else
|
||||||
|
err = dbg_leb_write(c, lnum, buf, offs, len, dtype);
|
||||||
|
if (err) {
|
||||||
|
ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
|
||||||
|
len, lnum, offs, err);
|
||||||
|
ubifs_ro_mode(c, err);
|
||||||
|
dbg_dump_stack();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
|
||||||
|
int dtype)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
ubifs_assert(!c->ro_media && !c->ro_mount);
|
||||||
|
if (c->ro_error)
|
||||||
|
return -EROFS;
|
||||||
|
if (!dbg_is_tst_rcvry(c))
|
||||||
|
err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
|
||||||
|
else
|
||||||
|
err = dbg_leb_change(c, lnum, buf, len, dtype);
|
||||||
|
if (err) {
|
||||||
|
ubifs_err("changing %d bytes in LEB %d failed, error %d",
|
||||||
|
len, lnum, err);
|
||||||
|
ubifs_ro_mode(c, err);
|
||||||
|
dbg_dump_stack();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
ubifs_assert(!c->ro_media && !c->ro_mount);
|
||||||
|
if (c->ro_error)
|
||||||
|
return -EROFS;
|
||||||
|
if (!dbg_is_tst_rcvry(c))
|
||||||
|
err = ubi_leb_unmap(c->ubi, lnum);
|
||||||
|
else
|
||||||
|
err = dbg_leb_unmap(c, lnum);
|
||||||
|
if (err) {
|
||||||
|
ubifs_err("unmap LEB %d failed, error %d", lnum, err);
|
||||||
|
ubifs_ro_mode(c, err);
|
||||||
|
dbg_dump_stack();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
ubifs_assert(!c->ro_media && !c->ro_mount);
|
||||||
|
if (c->ro_error)
|
||||||
|
return -EROFS;
|
||||||
|
if (!dbg_is_tst_rcvry(c))
|
||||||
|
err = ubi_leb_map(c->ubi, lnum, dtype);
|
||||||
|
else
|
||||||
|
err = dbg_leb_map(c, lnum, dtype);
|
||||||
|
if (err) {
|
||||||
|
ubifs_err("mapping LEB %d failed, error %d", lnum, err);
|
||||||
|
ubifs_ro_mode(c, err);
|
||||||
|
dbg_dump_stack();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = ubi_is_mapped(c->ubi, lnum);
|
||||||
|
if (err < 0) {
|
||||||
|
ubifs_err("ubi_is_mapped failed for LEB %d, error %d",
|
||||||
|
lnum, err);
|
||||||
|
dbg_dump_stack();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -406,14 +523,10 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
|
||||||
dirt = sync_len - wbuf->used;
|
dirt = sync_len - wbuf->used;
|
||||||
if (dirt)
|
if (dirt)
|
||||||
ubifs_pad(c, wbuf->buf + wbuf->used, dirt);
|
ubifs_pad(c, wbuf->buf + wbuf->used, dirt);
|
||||||
err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs,
|
err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs, sync_len,
|
||||||
sync_len, wbuf->dtype);
|
wbuf->dtype);
|
||||||
if (err) {
|
if (err)
|
||||||
ubifs_err("cannot write %d bytes to LEB %d:%d",
|
|
||||||
sync_len, wbuf->lnum, wbuf->offs);
|
|
||||||
dbg_dump_stack();
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock(&wbuf->lock);
|
spin_lock(&wbuf->lock);
|
||||||
wbuf->offs += sync_len;
|
wbuf->offs += sync_len;
|
||||||
|
@ -605,7 +718,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
|
||||||
if (aligned_len == wbuf->avail) {
|
if (aligned_len == wbuf->avail) {
|
||||||
dbg_io("flush jhead %s wbuf to LEB %d:%d",
|
dbg_io("flush jhead %s wbuf to LEB %d:%d",
|
||||||
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
|
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
|
||||||
err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf,
|
err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf,
|
||||||
wbuf->offs, wbuf->size,
|
wbuf->offs, wbuf->size,
|
||||||
wbuf->dtype);
|
wbuf->dtype);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -642,7 +755,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
|
||||||
dbg_io("flush jhead %s wbuf to LEB %d:%d",
|
dbg_io("flush jhead %s wbuf to LEB %d:%d",
|
||||||
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
|
dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
|
||||||
memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail);
|
memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail);
|
||||||
err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs,
|
err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs,
|
||||||
wbuf->size, wbuf->dtype);
|
wbuf->size, wbuf->dtype);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -661,7 +774,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
|
||||||
*/
|
*/
|
||||||
dbg_io("write %d bytes to LEB %d:%d",
|
dbg_io("write %d bytes to LEB %d:%d",
|
||||||
wbuf->size, wbuf->lnum, wbuf->offs);
|
wbuf->size, wbuf->lnum, wbuf->offs);
|
||||||
err = ubi_leb_write(c->ubi, wbuf->lnum, buf, wbuf->offs,
|
err = ubifs_leb_write(c, wbuf->lnum, buf, wbuf->offs,
|
||||||
wbuf->size, wbuf->dtype);
|
wbuf->size, wbuf->dtype);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -683,7 +796,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
|
||||||
n <<= c->max_write_shift;
|
n <<= c->max_write_shift;
|
||||||
dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum,
|
dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum,
|
||||||
wbuf->offs);
|
wbuf->offs);
|
||||||
err = ubi_leb_write(c->ubi, wbuf->lnum, buf + written,
|
err = ubifs_leb_write(c, wbuf->lnum, buf + written,
|
||||||
wbuf->offs, n, wbuf->dtype);
|
wbuf->offs, n, wbuf->dtype);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -766,13 +879,9 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
|
|
||||||
ubifs_prepare_node(c, buf, len, 1);
|
ubifs_prepare_node(c, buf, len, 1);
|
||||||
err = ubi_leb_write(c->ubi, lnum, buf, offs, buf_len, dtype);
|
err = ubifs_leb_write(c, lnum, buf, offs, buf_len, dtype);
|
||||||
if (err) {
|
if (err)
|
||||||
ubifs_err("cannot write %d bytes to LEB %d:%d, error %d",
|
|
||||||
buf_len, lnum, offs, err);
|
|
||||||
dbg_dump_node(c, buf);
|
dbg_dump_node(c, buf);
|
||||||
dbg_dump_stack();
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -824,14 +933,10 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
|
||||||
|
|
||||||
if (rlen > 0) {
|
if (rlen > 0) {
|
||||||
/* Read everything that goes before write-buffer */
|
/* Read everything that goes before write-buffer */
|
||||||
err = ubi_read(c->ubi, lnum, buf, offs, rlen);
|
err = ubifs_leb_read(c, lnum, buf, offs, rlen, 0);
|
||||||
if (err && err != -EBADMSG) {
|
if (err && err != -EBADMSG)
|
||||||
ubifs_err("failed to read node %d from LEB %d:%d, "
|
|
||||||
"error %d", type, lnum, offs, err);
|
|
||||||
dbg_dump_stack();
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (type != ch->node_type) {
|
if (type != ch->node_type) {
|
||||||
ubifs_err("bad node type (%d but expected %d)",
|
ubifs_err("bad node type (%d but expected %d)",
|
||||||
|
@ -885,12 +990,9 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
|
||||||
ubifs_assert(!(offs & 7) && offs < c->leb_size);
|
ubifs_assert(!(offs & 7) && offs < c->leb_size);
|
||||||
ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
|
ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
|
||||||
|
|
||||||
err = ubi_read(c->ubi, lnum, buf, offs, len);
|
err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
|
||||||
if (err && err != -EBADMSG) {
|
if (err && err != -EBADMSG)
|
||||||
ubifs_err("cannot read node %d from LEB %d:%d, error %d",
|
|
||||||
type, lnum, offs, err);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
if (type != ch->node_type) {
|
if (type != ch->node_type) {
|
||||||
ubifs_err("bad node type (%d but expected %d)",
|
ubifs_err("bad node type (%d but expected %d)",
|
||||||
|
|
|
@ -262,7 +262,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
|
||||||
* an unclean reboot, because the target LEB might have been
|
* an unclean reboot, because the target LEB might have been
|
||||||
* unmapped, but not yet physically erased.
|
* unmapped, but not yet physically erased.
|
||||||
*/
|
*/
|
||||||
err = ubi_leb_map(c->ubi, bud->lnum, UBI_SHORTTERM);
|
err = ubifs_leb_map(c, bud->lnum, UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
@ -283,8 +283,6 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
if (err != -EAGAIN)
|
|
||||||
ubifs_ro_mode(c, err);
|
|
||||||
mutex_unlock(&c->log_mutex);
|
mutex_unlock(&c->log_mutex);
|
||||||
kfree(ref);
|
kfree(ref);
|
||||||
kfree(bud);
|
kfree(bud);
|
||||||
|
@ -752,7 +750,7 @@ static int dbg_check_bud_bytes(struct ubifs_info *c)
|
||||||
struct ubifs_bud *bud;
|
struct ubifs_bud *bud;
|
||||||
long long bud_bytes = 0;
|
long long bud_bytes = 0;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
|
if (!dbg_is_chk_gen(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spin_lock(&c->buds_lock);
|
spin_lock(&c->buds_lock);
|
||||||
|
|
|
@ -504,7 +504,7 @@ static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops)
|
||||||
pnode = (struct ubifs_pnode *)container_of(lprops - pos,
|
pnode = (struct ubifs_pnode *)container_of(lprops - pos,
|
||||||
struct ubifs_pnode,
|
struct ubifs_pnode,
|
||||||
lprops[0]);
|
lprops[0]);
|
||||||
return !test_bit(COW_ZNODE, &pnode->flags) &&
|
return !test_bit(COW_CNODE, &pnode->flags) &&
|
||||||
test_bit(DIRTY_CNODE, &pnode->flags);
|
test_bit(DIRTY_CNODE, &pnode->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,7 +860,7 @@ int dbg_check_cats(struct ubifs_info *c)
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
int i, cat;
|
int i, cat;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS)))
|
if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
list_for_each_entry(lprops, &c->empty_list, list) {
|
list_for_each_entry(lprops, &c->empty_list, list) {
|
||||||
|
@ -958,7 +958,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
|
||||||
{
|
{
|
||||||
int i = 0, j, err = 0;
|
int i = 0, j, err = 0;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS)))
|
if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < heap->cnt; i++) {
|
for (i = 0; i < heap->cnt; i++) {
|
||||||
|
@ -1262,7 +1262,7 @@ int dbg_check_lprops(struct ubifs_info *c)
|
||||||
int i, err;
|
int i, err;
|
||||||
struct ubifs_lp_stats lst;
|
struct ubifs_lp_stats lst;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
|
if (!dbg_is_chk_lprops(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -701,7 +701,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
|
||||||
alen = ALIGN(len, c->min_io_size);
|
alen = ALIGN(len, c->min_io_size);
|
||||||
set_ltab(c, lnum, c->leb_size - alen, alen - len);
|
set_ltab(c, lnum, c->leb_size - alen, alen - len);
|
||||||
memset(p, 0xff, alen - len);
|
memset(p, 0xff, alen - len);
|
||||||
err = ubi_leb_change(c->ubi, lnum++, buf, alen,
|
err = ubifs_leb_change(c, lnum++, buf, alen,
|
||||||
UBI_SHORTTERM);
|
UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -732,7 +732,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
|
||||||
set_ltab(c, lnum, c->leb_size - alen,
|
set_ltab(c, lnum, c->leb_size - alen,
|
||||||
alen - len);
|
alen - len);
|
||||||
memset(p, 0xff, alen - len);
|
memset(p, 0xff, alen - len);
|
||||||
err = ubi_leb_change(c->ubi, lnum++, buf, alen,
|
err = ubifs_leb_change(c, lnum++, buf, alen,
|
||||||
UBI_SHORTTERM);
|
UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -780,7 +780,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
|
||||||
alen = ALIGN(len, c->min_io_size);
|
alen = ALIGN(len, c->min_io_size);
|
||||||
set_ltab(c, lnum, c->leb_size - alen, alen - len);
|
set_ltab(c, lnum, c->leb_size - alen, alen - len);
|
||||||
memset(p, 0xff, alen - len);
|
memset(p, 0xff, alen - len);
|
||||||
err = ubi_leb_change(c->ubi, lnum++, buf, alen,
|
err = ubifs_leb_change(c, lnum++, buf, alen,
|
||||||
UBI_SHORTTERM);
|
UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -806,7 +806,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
|
||||||
alen = ALIGN(len, c->min_io_size);
|
alen = ALIGN(len, c->min_io_size);
|
||||||
set_ltab(c, lnum, c->leb_size - alen, alen - len);
|
set_ltab(c, lnum, c->leb_size - alen, alen - len);
|
||||||
memset(p, 0xff, alen - len);
|
memset(p, 0xff, alen - len);
|
||||||
err = ubi_leb_change(c->ubi, lnum++, buf, alen, UBI_SHORTTERM);
|
err = ubifs_leb_change(c, lnum++, buf, alen, UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
p = buf;
|
p = buf;
|
||||||
|
@ -826,7 +826,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
|
||||||
|
|
||||||
/* Write remaining buffer */
|
/* Write remaining buffer */
|
||||||
memset(p, 0xff, alen - len);
|
memset(p, 0xff, alen - len);
|
||||||
err = ubi_leb_change(c->ubi, lnum, buf, alen, UBI_SHORTTERM);
|
err = ubifs_leb_change(c, lnum, buf, alen, UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -1222,7 +1222,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
|
||||||
if (c->big_lpt)
|
if (c->big_lpt)
|
||||||
nnode->num = calc_nnode_num_from_parent(c, parent, iip);
|
nnode->num = calc_nnode_num_from_parent(c, parent, iip);
|
||||||
} else {
|
} else {
|
||||||
err = ubi_read(c->ubi, lnum, buf, offs, c->nnode_sz);
|
err = ubifs_leb_read(c, lnum, buf, offs, c->nnode_sz, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
err = ubifs_unpack_nnode(c, buf, nnode);
|
err = ubifs_unpack_nnode(c, buf, nnode);
|
||||||
|
@ -1247,6 +1247,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs);
|
ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs);
|
||||||
|
dbg_dump_stack();
|
||||||
kfree(nnode);
|
kfree(nnode);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1290,7 +1291,7 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
|
||||||
lprops->flags = ubifs_categorize_lprops(c, lprops);
|
lprops->flags = ubifs_categorize_lprops(c, lprops);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = ubi_read(c->ubi, lnum, buf, offs, c->pnode_sz);
|
err = ubifs_leb_read(c, lnum, buf, offs, c->pnode_sz, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
err = unpack_pnode(c, buf, pnode);
|
err = unpack_pnode(c, buf, pnode);
|
||||||
|
@ -1312,6 +1313,7 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
|
||||||
out:
|
out:
|
||||||
ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs);
|
ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs);
|
||||||
dbg_dump_pnode(c, pnode, parent, iip);
|
dbg_dump_pnode(c, pnode, parent, iip);
|
||||||
|
dbg_dump_stack();
|
||||||
dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
|
dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
|
||||||
kfree(pnode);
|
kfree(pnode);
|
||||||
return err;
|
return err;
|
||||||
|
@ -1331,7 +1333,7 @@ static int read_ltab(struct ubifs_info *c)
|
||||||
buf = vmalloc(c->ltab_sz);
|
buf = vmalloc(c->ltab_sz);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
err = ubi_read(c->ubi, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz);
|
err = ubifs_leb_read(c, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
err = unpack_ltab(c, buf);
|
err = unpack_ltab(c, buf);
|
||||||
|
@ -1354,7 +1356,8 @@ static int read_lsave(struct ubifs_info *c)
|
||||||
buf = vmalloc(c->lsave_sz);
|
buf = vmalloc(c->lsave_sz);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
err = ubi_read(c->ubi, c->lsave_lnum, buf, c->lsave_offs, c->lsave_sz);
|
err = ubifs_leb_read(c, c->lsave_lnum, buf, c->lsave_offs,
|
||||||
|
c->lsave_sz, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
err = unpack_lsave(c, buf);
|
err = unpack_lsave(c, buf);
|
||||||
|
@ -1814,8 +1817,8 @@ static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c,
|
||||||
if (c->big_lpt)
|
if (c->big_lpt)
|
||||||
nnode->num = calc_nnode_num_from_parent(c, parent, iip);
|
nnode->num = calc_nnode_num_from_parent(c, parent, iip);
|
||||||
} else {
|
} else {
|
||||||
err = ubi_read(c->ubi, branch->lnum, buf, branch->offs,
|
err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
|
||||||
c->nnode_sz);
|
c->nnode_sz, 1);
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
err = ubifs_unpack_nnode(c, buf, nnode);
|
err = ubifs_unpack_nnode(c, buf, nnode);
|
||||||
|
@ -1883,8 +1886,8 @@ static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,
|
||||||
ubifs_assert(branch->lnum >= c->lpt_first &&
|
ubifs_assert(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(branch->offs >= 0 && branch->offs < c->leb_size);
|
||||||
err = ubi_read(c->ubi, branch->lnum, buf, branch->offs,
|
err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
|
||||||
c->pnode_sz);
|
c->pnode_sz, 1);
|
||||||
if (err)
|
if (err)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
err = unpack_pnode(c, buf, pnode);
|
err = unpack_pnode(c, buf, pnode);
|
||||||
|
@ -2224,7 +2227,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
|
||||||
struct ubifs_cnode *cn;
|
struct ubifs_cnode *cn;
|
||||||
int num, iip = 0, err;
|
int num, iip = 0, err;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
|
if (!dbg_is_chk_lprops(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (cnode) {
|
while (cnode) {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <linux/crc16.h>
|
#include <linux/crc16.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/random.h>
|
||||||
#include "ubifs.h"
|
#include "ubifs.h"
|
||||||
|
|
||||||
#ifdef CONFIG_UBIFS_FS_DEBUG
|
#ifdef CONFIG_UBIFS_FS_DEBUG
|
||||||
|
@ -116,8 +117,8 @@ static int get_cnodes_to_commit(struct ubifs_info *c)
|
||||||
return 0;
|
return 0;
|
||||||
cnt += 1;
|
cnt += 1;
|
||||||
while (1) {
|
while (1) {
|
||||||
ubifs_assert(!test_bit(COW_ZNODE, &cnode->flags));
|
ubifs_assert(!test_bit(COW_CNODE, &cnode->flags));
|
||||||
__set_bit(COW_ZNODE, &cnode->flags);
|
__set_bit(COW_CNODE, &cnode->flags);
|
||||||
cnext = next_dirty_cnode(cnode);
|
cnext = next_dirty_cnode(cnode);
|
||||||
if (!cnext) {
|
if (!cnext) {
|
||||||
cnode->cnext = c->lpt_cnext;
|
cnode->cnext = c->lpt_cnext;
|
||||||
|
@ -465,7 +466,7 @@ static int write_cnodes(struct ubifs_info *c)
|
||||||
*/
|
*/
|
||||||
clear_bit(DIRTY_CNODE, &cnode->flags);
|
clear_bit(DIRTY_CNODE, &cnode->flags);
|
||||||
smp_mb__before_clear_bit();
|
smp_mb__before_clear_bit();
|
||||||
clear_bit(COW_ZNODE, &cnode->flags);
|
clear_bit(COW_CNODE, &cnode->flags);
|
||||||
smp_mb__after_clear_bit();
|
smp_mb__after_clear_bit();
|
||||||
offs += len;
|
offs += len;
|
||||||
dbg_chk_lpt_sz(c, 1, len);
|
dbg_chk_lpt_sz(c, 1, len);
|
||||||
|
@ -1160,11 +1161,11 @@ static int lpt_gc_lnum(struct ubifs_info *c, int lnum)
|
||||||
void *buf = c->lpt_buf;
|
void *buf = c->lpt_buf;
|
||||||
|
|
||||||
dbg_lp("LEB %d", lnum);
|
dbg_lp("LEB %d", lnum);
|
||||||
err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size);
|
|
||||||
if (err) {
|
err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
|
||||||
ubifs_err("cannot read LEB %d, error %d", lnum, err);
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!is_a_node(c, buf, len)) {
|
if (!is_a_node(c, buf, len)) {
|
||||||
int pad_len;
|
int pad_len;
|
||||||
|
@ -1640,7 +1641,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
|
||||||
int ret;
|
int ret;
|
||||||
void *buf, *p;
|
void *buf, *p;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
|
if (!dbg_is_chk_lprops(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
|
buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
|
||||||
|
@ -1650,11 +1651,11 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_lp("LEB %d", lnum);
|
dbg_lp("LEB %d", lnum);
|
||||||
err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size);
|
|
||||||
if (err) {
|
err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
|
||||||
dbg_msg("ubi_read failed, LEB %d, error %d", lnum, err);
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!is_a_node(c, p, len)) {
|
if (!is_a_node(c, p, len)) {
|
||||||
int i, pad_len;
|
int i, pad_len;
|
||||||
|
@ -1711,7 +1712,7 @@ int dbg_check_ltab(struct ubifs_info *c)
|
||||||
{
|
{
|
||||||
int lnum, err, i, cnt;
|
int lnum, err, i, cnt;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
|
if (!dbg_is_chk_lprops(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Bring the entire tree into memory */
|
/* Bring the entire tree into memory */
|
||||||
|
@ -1754,7 +1755,7 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c)
|
||||||
long long free = 0;
|
long long free = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
|
if (!dbg_is_chk_lprops(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < c->lpt_lebs; i++) {
|
for (i = 0; i < c->lpt_lebs; i++) {
|
||||||
|
@ -1796,7 +1797,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
|
||||||
long long chk_lpt_sz, lpt_sz;
|
long long chk_lpt_sz, lpt_sz;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS))
|
if (!dbg_is_chk_lprops(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
@ -1901,11 +1902,10 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size);
|
err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
|
||||||
if (err) {
|
if (err)
|
||||||
ubifs_err("cannot read LEB %d, error %d", lnum, err);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
while (1) {
|
while (1) {
|
||||||
offs = c->leb_size - len;
|
offs = c->leb_size - len;
|
||||||
if (!is_a_node(c, p, len)) {
|
if (!is_a_node(c, p, len)) {
|
||||||
|
@ -2019,7 +2019,7 @@ static int dbg_populate_lsave(struct ubifs_info *c)
|
||||||
struct ubifs_lpt_heap *heap;
|
struct ubifs_lpt_heap *heap;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
|
if (!dbg_is_chk_gen(c))
|
||||||
return 0;
|
return 0;
|
||||||
if (random32() & 3)
|
if (random32() & 3)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
103
fs/ubifs/misc.h
103
fs/ubifs/misc.h
|
@ -38,6 +38,29 @@ static inline int ubifs_zn_dirty(const struct ubifs_znode *znode)
|
||||||
return !!test_bit(DIRTY_ZNODE, &znode->flags);
|
return !!test_bit(DIRTY_ZNODE, &znode->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ubifs_zn_obsolete - check if znode is obsolete.
|
||||||
|
* @znode: znode to check
|
||||||
|
*
|
||||||
|
* This helper function returns %1 if @znode is obsolete and %0 otherwise.
|
||||||
|
*/
|
||||||
|
static inline int ubifs_zn_obsolete(const struct ubifs_znode *znode)
|
||||||
|
{
|
||||||
|
return !!test_bit(OBSOLETE_ZNODE, &znode->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ubifs_zn_cow - check if znode has to be copied on write.
|
||||||
|
* @znode: znode to check
|
||||||
|
*
|
||||||
|
* This helper function returns %1 if @znode is has COW flag set and %0
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
static inline int ubifs_zn_cow(const struct ubifs_znode *znode)
|
||||||
|
{
|
||||||
|
return !!test_bit(COW_ZNODE, &znode->flags);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ubifs_wake_up_bgt - wake up background thread.
|
* ubifs_wake_up_bgt - wake up background thread.
|
||||||
* @c: UBIFS file-system description object
|
* @c: UBIFS file-system description object
|
||||||
|
@ -121,86 +144,6 @@ static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ubifs_leb_unmap - unmap an LEB.
|
|
||||||
* @c: UBIFS file-system description object
|
|
||||||
* @lnum: LEB number to unmap
|
|
||||||
*
|
|
||||||
* This function returns %0 on success and a negative error code on failure.
|
|
||||||
*/
|
|
||||||
static inline int ubifs_leb_unmap(const struct ubifs_info *c, int lnum)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ubifs_assert(!c->ro_media && !c->ro_mount);
|
|
||||||
if (c->ro_error)
|
|
||||||
return -EROFS;
|
|
||||||
err = ubi_leb_unmap(c->ubi, lnum);
|
|
||||||
if (err) {
|
|
||||||
ubifs_err("unmap LEB %d failed, error %d", lnum, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ubifs_leb_write - write to a LEB.
|
|
||||||
* @c: UBIFS file-system description object
|
|
||||||
* @lnum: LEB number to write
|
|
||||||
* @buf: buffer to write from
|
|
||||||
* @offs: offset within LEB to write to
|
|
||||||
* @len: length to write
|
|
||||||
* @dtype: data type
|
|
||||||
*
|
|
||||||
* This function returns %0 on success and a negative error code on failure.
|
|
||||||
*/
|
|
||||||
static inline int ubifs_leb_write(const struct ubifs_info *c, int lnum,
|
|
||||||
const void *buf, int offs, int len, int dtype)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ubifs_assert(!c->ro_media && !c->ro_mount);
|
|
||||||
if (c->ro_error)
|
|
||||||
return -EROFS;
|
|
||||||
err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
|
|
||||||
if (err) {
|
|
||||||
ubifs_err("writing %d bytes at %d:%d, error %d",
|
|
||||||
len, lnum, offs, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ubifs_leb_change - atomic LEB change.
|
|
||||||
* @c: UBIFS file-system description object
|
|
||||||
* @lnum: LEB number to write
|
|
||||||
* @buf: buffer to write from
|
|
||||||
* @len: length to write
|
|
||||||
* @dtype: data type
|
|
||||||
*
|
|
||||||
* This function returns %0 on success and a negative error code on failure.
|
|
||||||
*/
|
|
||||||
static inline int ubifs_leb_change(const struct ubifs_info *c, int lnum,
|
|
||||||
const void *buf, int len, int dtype)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
ubifs_assert(!c->ro_media && !c->ro_mount);
|
|
||||||
if (c->ro_error)
|
|
||||||
return -EROFS;
|
|
||||||
err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
|
|
||||||
if (err) {
|
|
||||||
ubifs_err("changing %d bytes in LEB %d, error %d",
|
|
||||||
len, lnum, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ubifs_encode_dev - encode device node IDs.
|
* ubifs_encode_dev - encode device node IDs.
|
||||||
* @dev: UBIFS device node information
|
* @dev: UBIFS device node information
|
||||||
|
|
|
@ -929,7 +929,7 @@ static int dbg_check_orphans(struct ubifs_info *c)
|
||||||
struct check_info ci;
|
struct check_info ci;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_ORPH))
|
if (!dbg_is_chk_orph(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ci.last_ino = 0;
|
ci.last_ino = 0;
|
||||||
|
|
|
@ -117,7 +117,7 @@ static int get_master_node(const struct ubifs_info *c, int lnum, void **pbuf,
|
||||||
if (!sbuf)
|
if (!sbuf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
err = ubi_read(c->ubi, lnum, sbuf, 0, c->leb_size);
|
err = ubifs_leb_read(c, lnum, sbuf, 0, c->leb_size, 0);
|
||||||
if (err && err != -EBADMSG)
|
if (err && err != -EBADMSG)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
@ -213,10 +213,10 @@ static int write_rcvrd_mst_node(struct ubifs_info *c,
|
||||||
mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY);
|
mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY);
|
||||||
|
|
||||||
ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1);
|
ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1);
|
||||||
err = ubi_leb_change(c->ubi, lnum, mst, sz, UBI_SHORTTERM);
|
err = ubifs_leb_change(c, lnum, mst, sz, UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
err = ubi_leb_change(c->ubi, lnum + 1, mst, sz, UBI_SHORTTERM);
|
err = ubifs_leb_change(c, lnum + 1, mst, sz, UBI_SHORTTERM);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
out:
|
out:
|
||||||
|
@ -274,7 +274,8 @@ int ubifs_recover_master_node(struct ubifs_info *c)
|
||||||
if (cor1)
|
if (cor1)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
mst = mst1;
|
mst = mst1;
|
||||||
} else if (offs1 == 0 && offs2 + sz >= c->leb_size) {
|
} else if (offs1 == 0 &&
|
||||||
|
c->leb_size - offs2 - sz < sz) {
|
||||||
/* 1st LEB was unmapped and written, 2nd not */
|
/* 1st LEB was unmapped and written, 2nd not */
|
||||||
if (cor1)
|
if (cor1)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
|
@ -539,8 +540,8 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
|
||||||
int len = ALIGN(endpt, c->min_io_size);
|
int len = ALIGN(endpt, c->min_io_size);
|
||||||
|
|
||||||
if (start) {
|
if (start) {
|
||||||
err = ubi_read(c->ubi, lnum, sleb->buf, 0,
|
err = ubifs_leb_read(c, lnum, sleb->buf, 0,
|
||||||
start);
|
start, 1);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -554,7 +555,7 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
|
||||||
ubifs_pad(c, buf, pad_len);
|
ubifs_pad(c, buf, pad_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = ubi_leb_change(c->ubi, lnum, sleb->buf, len,
|
err = ubifs_leb_change(c, lnum, sleb->buf, len,
|
||||||
UBI_UNKNOWN);
|
UBI_UNKNOWN);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -819,7 +820,8 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (c->leb_size - offs < UBIFS_CS_NODE_SZ)
|
if (c->leb_size - offs < UBIFS_CS_NODE_SZ)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
err = ubi_read(c->ubi, lnum, (void *)cs_node, offs, UBIFS_CS_NODE_SZ);
|
err = ubifs_leb_read(c, lnum, (void *)cs_node, offs,
|
||||||
|
UBIFS_CS_NODE_SZ, 0);
|
||||||
if (err && err != -EBADMSG)
|
if (err && err != -EBADMSG)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0);
|
ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0);
|
||||||
|
@ -919,8 +921,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
|
||||||
*
|
*
|
||||||
* This function returns %0 on success and a negative error code on failure.
|
* This function returns %0 on success and a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
static int recover_head(const struct ubifs_info *c, int lnum, int offs,
|
static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
|
||||||
void *sbuf)
|
|
||||||
{
|
{
|
||||||
int len = c->max_write_size, err;
|
int len = c->max_write_size, err;
|
||||||
|
|
||||||
|
@ -931,15 +932,15 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Read at the head location and check it is empty flash */
|
/* Read at the head location and check it is empty flash */
|
||||||
err = ubi_read(c->ubi, lnum, sbuf, offs, len);
|
err = ubifs_leb_read(c, lnum, sbuf, offs, len, 1);
|
||||||
if (err || !is_empty(sbuf, len)) {
|
if (err || !is_empty(sbuf, len)) {
|
||||||
dbg_rcvry("cleaning head at %d:%d", lnum, offs);
|
dbg_rcvry("cleaning head at %d:%d", lnum, offs);
|
||||||
if (offs == 0)
|
if (offs == 0)
|
||||||
return ubifs_leb_unmap(c, lnum);
|
return ubifs_leb_unmap(c, lnum);
|
||||||
err = ubi_read(c->ubi, lnum, sbuf, 0, offs);
|
err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
return ubi_leb_change(c->ubi, lnum, sbuf, offs, UBI_UNKNOWN);
|
return ubifs_leb_change(c, lnum, sbuf, offs, UBI_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -962,7 +963,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs,
|
||||||
*
|
*
|
||||||
* This function returns %0 on success and a negative error code on failure.
|
* This function returns %0 on success and a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf)
|
int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -993,7 +994,7 @@ int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf)
|
||||||
*
|
*
|
||||||
* This function returns %0 on success and a negative error code on failure.
|
* This function returns %0 on success and a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
static int clean_an_unclean_leb(const struct ubifs_info *c,
|
static int clean_an_unclean_leb(struct ubifs_info *c,
|
||||||
struct ubifs_unclean_leb *ucleb, void *sbuf)
|
struct ubifs_unclean_leb *ucleb, void *sbuf)
|
||||||
{
|
{
|
||||||
int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1;
|
int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1;
|
||||||
|
@ -1009,7 +1010,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ubi_read(c->ubi, lnum, buf, offs, len);
|
err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
|
||||||
if (err && err != -EBADMSG)
|
if (err && err != -EBADMSG)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -1069,7 +1070,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write back the LEB atomically */
|
/* Write back the LEB atomically */
|
||||||
err = ubi_leb_change(c->ubi, lnum, sbuf, len, UBI_UNKNOWN);
|
err = ubifs_leb_change(c, lnum, sbuf, len, UBI_UNKNOWN);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -1089,7 +1090,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
|
||||||
*
|
*
|
||||||
* This function returns %0 on success and a negative error code on failure.
|
* This function returns %0 on success and a negative error code on failure.
|
||||||
*/
|
*/
|
||||||
int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf)
|
int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf)
|
||||||
{
|
{
|
||||||
dbg_rcvry("recovery");
|
dbg_rcvry("recovery");
|
||||||
while (!list_empty(&c->unclean_leb_list)) {
|
while (!list_empty(&c->unclean_leb_list)) {
|
||||||
|
@ -1454,7 +1455,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
|
||||||
if (i_size >= e->d_size)
|
if (i_size >= e->d_size)
|
||||||
return 0;
|
return 0;
|
||||||
/* Read the LEB */
|
/* Read the LEB */
|
||||||
err = ubi_read(c->ubi, lnum, c->sbuf, 0, c->leb_size);
|
err = ubifs_leb_read(c, lnum, c->sbuf, 0, c->leb_size, 1);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
/* Change the size field and recalculate the CRC */
|
/* Change the size field and recalculate the CRC */
|
||||||
|
@ -1470,7 +1471,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
|
||||||
len -= 1;
|
len -= 1;
|
||||||
len = ALIGN(len + 1, c->min_io_size);
|
len = ALIGN(len + 1, c->min_io_size);
|
||||||
/* Atomically write the fixed LEB back again */
|
/* Atomically write the fixed LEB back again */
|
||||||
err = ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN);
|
err = ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
dbg_rcvry("inode %lu at %d:%d size %lld -> %lld",
|
dbg_rcvry("inode %lu at %d:%d size %lld -> %lld",
|
||||||
|
|
|
@ -523,8 +523,7 @@ static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud)
|
||||||
if (!list_is_last(&next->list, &jh->buds_list))
|
if (!list_is_last(&next->list, &jh->buds_list))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err = ubi_read(c->ubi, next->lnum, (char *)&data,
|
err = ubifs_leb_read(c, next->lnum, (char *)&data, next->start, 4, 1);
|
||||||
next->start, 4);
|
|
||||||
if (err)
|
if (err)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -674,15 +674,15 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
dbg_mnt("unmap empty LEB %d", lnum);
|
dbg_mnt("unmap empty LEB %d", lnum);
|
||||||
return ubi_leb_unmap(c->ubi, lnum);
|
return ubifs_leb_unmap(c, lnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_mnt("fixup LEB %d, data len %d", lnum, len);
|
dbg_mnt("fixup LEB %d, data len %d", lnum, len);
|
||||||
err = ubi_read(c->ubi, lnum, c->sbuf, 0, len);
|
err = ubifs_leb_read(c, lnum, c->sbuf, 0, len, 1);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN);
|
return ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -148,7 +148,7 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum,
|
||||||
INIT_LIST_HEAD(&sleb->nodes);
|
INIT_LIST_HEAD(&sleb->nodes);
|
||||||
sleb->buf = sbuf;
|
sleb->buf = sbuf;
|
||||||
|
|
||||||
err = ubi_read(c->ubi, lnum, sbuf + offs, offs, c->leb_size - offs);
|
err = ubifs_leb_read(c, lnum, sbuf + offs, offs, c->leb_size - offs, 0);
|
||||||
if (err && err != -EBADMSG) {
|
if (err && err != -EBADMSG) {
|
||||||
ubifs_err("cannot read %d bytes from LEB %d:%d,"
|
ubifs_err("cannot read %d bytes from LEB %d:%d,"
|
||||||
" error %d", c->leb_size - offs, lnum, offs, err);
|
" error %d", c->leb_size - offs, lnum, offs, err);
|
||||||
|
@ -240,7 +240,7 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
ubifs_err("corruption at LEB %d:%d", lnum, offs);
|
ubifs_err("corruption at LEB %d:%d", lnum, offs);
|
||||||
if (dbg_failure_mode)
|
if (dbg_is_tst_rcvry(c))
|
||||||
return;
|
return;
|
||||||
len = c->leb_size - offs;
|
len = c->leb_size - offs;
|
||||||
if (len > 8192)
|
if (len > 8192)
|
||||||
|
|
|
@ -85,7 +85,7 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
|
||||||
if (ui->data_len < 0 || ui->data_len > UBIFS_MAX_INO_DATA)
|
if (ui->data_len < 0 || ui->data_len > UBIFS_MAX_INO_DATA)
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
if (ui->xattr && (inode->i_mode & S_IFMT) != S_IFREG)
|
if (ui->xattr && !S_ISREG(inode->i_mode))
|
||||||
return 5;
|
return 5;
|
||||||
|
|
||||||
if (!ubifs_compr_present(ui->compr_type)) {
|
if (!ubifs_compr_present(ui->compr_type)) {
|
||||||
|
@ -94,7 +94,7 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
|
||||||
ubifs_compr_name(ui->compr_type));
|
ubifs_compr_name(ui->compr_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dbg_check_dir_size(c, inode);
|
err = dbg_check_dir(c, inode);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,7 +914,7 @@ static int check_volume_empty(struct ubifs_info *c)
|
||||||
|
|
||||||
c->empty = 1;
|
c->empty = 1;
|
||||||
for (lnum = 0; lnum < c->leb_cnt; lnum++) {
|
for (lnum = 0; lnum < c->leb_cnt; lnum++) {
|
||||||
err = ubi_is_mapped(c->ubi, lnum);
|
err = ubifs_is_mapped(c, lnum);
|
||||||
if (unlikely(err < 0))
|
if (unlikely(err < 0))
|
||||||
return err;
|
return err;
|
||||||
if (err == 1) {
|
if (err == 1) {
|
||||||
|
|
|
@ -223,7 +223,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(!test_bit(OBSOLETE_ZNODE, &znode->flags));
|
ubifs_assert(!ubifs_zn_obsolete(znode));
|
||||||
__set_bit(OBSOLETE_ZNODE, &znode->flags);
|
__set_bit(OBSOLETE_ZNODE, &znode->flags);
|
||||||
|
|
||||||
if (znode->level != 0) {
|
if (znode->level != 0) {
|
||||||
|
@ -271,7 +271,7 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,
|
||||||
struct ubifs_znode *zn;
|
struct ubifs_znode *zn;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!test_bit(COW_ZNODE, &znode->flags)) {
|
if (!ubifs_zn_cow(znode)) {
|
||||||
/* znode is not being committed */
|
/* znode is not being committed */
|
||||||
if (!test_and_set_bit(DIRTY_ZNODE, &znode->flags)) {
|
if (!test_and_set_bit(DIRTY_ZNODE, &znode->flags)) {
|
||||||
atomic_long_inc(&c->dirty_zn_cnt);
|
atomic_long_inc(&c->dirty_zn_cnt);
|
||||||
|
@ -462,7 +462,7 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
err = ubi_read(c->ubi, lnum, buf, offs, len);
|
err = ubifs_leb_read(c, lnum, buf, offs, len, 1);
|
||||||
if (err) {
|
if (err) {
|
||||||
ubifs_err("cannot read node type %d from LEB %d:%d, error %d",
|
ubifs_err("cannot read node type %d from LEB %d:%d, error %d",
|
||||||
type, lnum, offs, err);
|
type, lnum, offs, err);
|
||||||
|
@ -1666,7 +1666,7 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
|
||||||
if (!overlap) {
|
if (!overlap) {
|
||||||
/* We may safely unlock the write-buffer and read the data */
|
/* We may safely unlock the write-buffer and read the data */
|
||||||
spin_unlock(&wbuf->lock);
|
spin_unlock(&wbuf->lock);
|
||||||
return ubi_read(c->ubi, lnum, buf, offs, len);
|
return ubifs_leb_read(c, lnum, buf, offs, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't read under wbuf */
|
/* Don't read under wbuf */
|
||||||
|
@ -1680,7 +1680,7 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
|
||||||
|
|
||||||
if (rlen > 0)
|
if (rlen > 0)
|
||||||
/* Read everything that goes before write-buffer */
|
/* Read everything that goes before write-buffer */
|
||||||
return ubi_read(c->ubi, lnum, buf, offs, rlen);
|
return ubifs_leb_read(c, lnum, buf, offs, rlen, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1767,7 +1767,7 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu)
|
||||||
if (wbuf)
|
if (wbuf)
|
||||||
err = read_wbuf(wbuf, bu->buf, len, lnum, offs);
|
err = read_wbuf(wbuf, bu->buf, len, lnum, offs);
|
||||||
else
|
else
|
||||||
err = ubi_read(c->ubi, lnum, bu->buf, offs, len);
|
err = ubifs_leb_read(c, lnum, bu->buf, offs, len, 0);
|
||||||
|
|
||||||
/* Check for a race with GC */
|
/* Check for a race with GC */
|
||||||
if (maybe_leb_gced(c, lnum, bu->gc_seq))
|
if (maybe_leb_gced(c, lnum, bu->gc_seq))
|
||||||
|
@ -2423,7 +2423,7 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ubifs_assert(!test_bit(OBSOLETE_ZNODE, &znode->flags));
|
ubifs_assert(!ubifs_zn_obsolete(znode));
|
||||||
ubifs_assert(ubifs_zn_dirty(znode));
|
ubifs_assert(ubifs_zn_dirty(znode));
|
||||||
|
|
||||||
zp = znode->parent;
|
zp = znode->parent;
|
||||||
|
@ -2479,9 +2479,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(!test_bit(OBSOLETE_ZNODE,
|
ubifs_assert(!ubifs_zn_obsolete(zp));
|
||||||
&zp->flags));
|
ubifs_assert(ubifs_zn_dirty(zp));
|
||||||
ubifs_assert(test_bit(DIRTY_ZNODE, &zp->flags));
|
|
||||||
atomic_long_dec(&c->dirty_zn_cnt);
|
atomic_long_dec(&c->dirty_zn_cnt);
|
||||||
|
|
||||||
if (zp->cnext) {
|
if (zp->cnext) {
|
||||||
|
@ -2865,7 +2864,7 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
|
||||||
struct ubifs_znode *znode = cnext;
|
struct ubifs_znode *znode = cnext;
|
||||||
|
|
||||||
cnext = cnext->cnext;
|
cnext = cnext->cnext;
|
||||||
if (test_bit(OBSOLETE_ZNODE, &znode->flags))
|
if (ubifs_zn_obsolete(znode))
|
||||||
kfree(znode);
|
kfree(znode);
|
||||||
} while (cnext && cnext != c->cnext);
|
} while (cnext && cnext != c->cnext);
|
||||||
}
|
}
|
||||||
|
@ -3301,7 +3300,7 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
|
||||||
|
|
||||||
if (!S_ISREG(inode->i_mode))
|
if (!S_ISREG(inode->i_mode))
|
||||||
return 0;
|
return 0;
|
||||||
if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
|
if (!dbg_is_chk_gen(c))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
|
block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
|
||||||
|
@ -3337,9 +3336,10 @@ out_dump:
|
||||||
ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
|
ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
|
||||||
"(data key %s)", (unsigned long)inode->i_ino, size,
|
"(data key %s)", (unsigned long)inode->i_ino, size,
|
||||||
((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
|
((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
|
||||||
|
mutex_unlock(&c->tnc_mutex);
|
||||||
dbg_dump_inode(c, inode);
|
dbg_dump_inode(c, inode);
|
||||||
dbg_dump_stack();
|
dbg_dump_stack();
|
||||||
err = -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&c->tnc_mutex);
|
mutex_unlock(&c->tnc_mutex);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
/* This file implements TNC functions for committing */
|
/* This file implements TNC functions for committing */
|
||||||
|
|
||||||
|
#include <linux/random.h>
|
||||||
#include "ubifs.h"
|
#include "ubifs.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,8 +88,12 @@ 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(ubifs_zn_dirty(znode));
|
||||||
ubifs_assert(test_bit(COW_ZNODE, &znode->flags));
|
ubifs_assert(ubifs_zn_cow(znode));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note, unlike 'write_index()' we do not add memory barriers here
|
||||||
|
* because this function is called with @c->tnc_mutex locked.
|
||||||
|
*/
|
||||||
__clear_bit(DIRTY_ZNODE, &znode->flags);
|
__clear_bit(DIRTY_ZNODE, &znode->flags);
|
||||||
__clear_bit(COW_ZNODE, &znode->flags);
|
__clear_bit(COW_ZNODE, &znode->flags);
|
||||||
|
|
||||||
|
@ -377,7 +382,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
|
||||||
c->gap_lebs = NULL;
|
c->gap_lebs = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (dbg_force_in_the_gaps_enabled()) {
|
if (!dbg_is_chk_index(c)) {
|
||||||
/*
|
/*
|
||||||
* Do not print scary warnings if the debugging
|
* Do not print scary warnings if the debugging
|
||||||
* option which forces in-the-gaps is enabled.
|
* option which forces in-the-gaps is enabled.
|
||||||
|
@ -491,25 +496,6 @@ static int layout_in_empty_space(struct ubifs_info *c)
|
||||||
else
|
else
|
||||||
next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
|
next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
|
||||||
|
|
||||||
if (c->min_io_size == 1) {
|
|
||||||
buf_offs += ALIGN(len, 8);
|
|
||||||
if (next_len) {
|
|
||||||
if (buf_offs + next_len <= c->leb_size)
|
|
||||||
continue;
|
|
||||||
err = ubifs_update_one_lp(c, lnum, 0,
|
|
||||||
c->leb_size - buf_offs, 0, 0);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
lnum = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
err = ubifs_update_one_lp(c, lnum,
|
|
||||||
c->leb_size - buf_offs, 0, 0, 0);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update buffer positions */
|
/* Update buffer positions */
|
||||||
wlen = used + len;
|
wlen = used + len;
|
||||||
used += ALIGN(len, 8);
|
used += ALIGN(len, 8);
|
||||||
|
@ -658,7 +644,7 @@ static int get_znodes_to_commit(struct ubifs_info *c)
|
||||||
}
|
}
|
||||||
cnt += 1;
|
cnt += 1;
|
||||||
while (1) {
|
while (1) {
|
||||||
ubifs_assert(!test_bit(COW_ZNODE, &znode->flags));
|
ubifs_assert(!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);
|
||||||
|
@ -704,7 +690,7 @@ static int alloc_idx_lebs(struct ubifs_info *c, int cnt)
|
||||||
c->ilebs[c->ileb_cnt++] = lnum;
|
c->ilebs[c->ileb_cnt++] = lnum;
|
||||||
dbg_cmt("LEB %d", lnum);
|
dbg_cmt("LEB %d", lnum);
|
||||||
}
|
}
|
||||||
if (dbg_force_in_the_gaps())
|
if (dbg_is_chk_index(c) && !(random32() & 7))
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -830,7 +816,7 @@ static int write_index(struct ubifs_info *c)
|
||||||
struct ubifs_idx_node *idx;
|
struct ubifs_idx_node *idx;
|
||||||
struct ubifs_znode *znode, *cnext;
|
struct ubifs_znode *znode, *cnext;
|
||||||
int i, lnum, offs, len, next_len, buf_len, buf_offs, used;
|
int i, lnum, offs, len, next_len, buf_len, buf_offs, used;
|
||||||
int avail, wlen, err, lnum_pos = 0;
|
int avail, wlen, err, lnum_pos = 0, blen, nxt_offs;
|
||||||
|
|
||||||
cnext = c->enext;
|
cnext = c->enext;
|
||||||
if (!cnext)
|
if (!cnext)
|
||||||
|
@ -907,7 +893,7 @@ static int write_index(struct ubifs_info *c)
|
||||||
cnext = znode->cnext;
|
cnext = znode->cnext;
|
||||||
|
|
||||||
ubifs_assert(ubifs_zn_dirty(znode));
|
ubifs_assert(ubifs_zn_dirty(znode));
|
||||||
ubifs_assert(test_bit(COW_ZNODE, &znode->flags));
|
ubifs_assert(ubifs_zn_cow(znode));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is important that other threads should see %DIRTY_ZNODE
|
* It is important that other threads should see %DIRTY_ZNODE
|
||||||
|
@ -922,6 +908,28 @@ static int write_index(struct ubifs_info *c)
|
||||||
clear_bit(COW_ZNODE, &znode->flags);
|
clear_bit(COW_ZNODE, &znode->flags);
|
||||||
smp_mb__after_clear_bit();
|
smp_mb__after_clear_bit();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have marked the znode as clean but have not updated the
|
||||||
|
* @c->clean_zn_cnt counter. If this znode becomes dirty again
|
||||||
|
* before 'free_obsolete_znodes()' is called, then
|
||||||
|
* @c->clean_zn_cnt will be decremented before it gets
|
||||||
|
* incremented (resulting in 2 decrements for the same znode).
|
||||||
|
* This means that @c->clean_zn_cnt may become negative for a
|
||||||
|
* while.
|
||||||
|
*
|
||||||
|
* Q: why we cannot increment @c->clean_zn_cnt?
|
||||||
|
* A: because we do not have the @c->tnc_mutex locked, and the
|
||||||
|
* following code would be racy and buggy:
|
||||||
|
*
|
||||||
|
* if (!ubifs_zn_obsolete(znode)) {
|
||||||
|
* atomic_long_inc(&c->clean_zn_cnt);
|
||||||
|
* atomic_long_inc(&ubifs_clean_zn_cnt);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Thus, we just delay the @c->clean_zn_cnt update until we
|
||||||
|
* have the mutex locked.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Do not access znode from this point on */
|
/* Do not access znode from this point on */
|
||||||
|
|
||||||
/* Update buffer positions */
|
/* Update buffer positions */
|
||||||
|
@ -938,31 +946,7 @@ static int write_index(struct ubifs_info *c)
|
||||||
else
|
else
|
||||||
next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
|
next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
|
||||||
|
|
||||||
if (c->min_io_size == 1) {
|
nxt_offs = buf_offs + used + next_len;
|
||||||
/*
|
|
||||||
* Write the prepared index node immediately if there is
|
|
||||||
* no minimum IO size
|
|
||||||
*/
|
|
||||||
err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs,
|
|
||||||
wlen, UBI_SHORTTERM);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
buf_offs += ALIGN(wlen, 8);
|
|
||||||
if (next_len) {
|
|
||||||
used = 0;
|
|
||||||
avail = buf_len;
|
|
||||||
if (buf_offs + next_len > c->leb_size) {
|
|
||||||
err = ubifs_update_one_lp(c, lnum,
|
|
||||||
LPROPS_NC, 0, 0, LPROPS_TAKEN);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
lnum = -1;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int blen, nxt_offs = buf_offs + used + next_len;
|
|
||||||
|
|
||||||
if (next_len && nxt_offs <= c->leb_size) {
|
if (next_len && nxt_offs <= c->leb_size) {
|
||||||
if (avail > 0)
|
if (avail > 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -973,19 +957,17 @@ static int write_index(struct ubifs_info *c)
|
||||||
blen = ALIGN(wlen, c->min_io_size);
|
blen = ALIGN(wlen, c->min_io_size);
|
||||||
ubifs_pad(c, c->cbuf + wlen, blen - wlen);
|
ubifs_pad(c, c->cbuf + wlen, blen - wlen);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* The buffer is full or there are no more znodes
|
/* The buffer is full or there are no more znodes to do */
|
||||||
* to do
|
err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, blen,
|
||||||
*/
|
UBI_SHORTTERM);
|
||||||
err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs,
|
|
||||||
blen, UBI_SHORTTERM);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
buf_offs += blen;
|
buf_offs += blen;
|
||||||
if (next_len) {
|
if (next_len) {
|
||||||
if (nxt_offs > c->leb_size) {
|
if (nxt_offs > c->leb_size) {
|
||||||
err = ubifs_update_one_lp(c, lnum,
|
err = ubifs_update_one_lp(c, lnum, LPROPS_NC, 0,
|
||||||
LPROPS_NC, 0, 0, LPROPS_TAKEN);
|
0, LPROPS_TAKEN);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
lnum = -1;
|
lnum = -1;
|
||||||
|
@ -997,7 +979,6 @@ static int write_index(struct ubifs_info *c)
|
||||||
memmove(c->cbuf, c->cbuf + blen, used);
|
memmove(c->cbuf, c->cbuf + blen, used);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,7 +1010,7 @@ static void free_obsolete_znodes(struct ubifs_info *c)
|
||||||
do {
|
do {
|
||||||
znode = cnext;
|
znode = cnext;
|
||||||
cnext = znode->cnext;
|
cnext = znode->cnext;
|
||||||
if (test_bit(OBSOLETE_ZNODE, &znode->flags))
|
if (ubifs_zn_obsolete(znode))
|
||||||
kfree(znode);
|
kfree(znode);
|
||||||
else {
|
else {
|
||||||
znode->cnext = NULL;
|
znode->cnext = NULL;
|
||||||
|
|
|
@ -230,14 +230,14 @@ enum {
|
||||||
* LPT cnode flag bits.
|
* LPT cnode flag bits.
|
||||||
*
|
*
|
||||||
* DIRTY_CNODE: cnode is dirty
|
* DIRTY_CNODE: cnode is dirty
|
||||||
* COW_CNODE: cnode is being committed and must be copied before writing
|
|
||||||
* OBSOLETE_CNODE: cnode is being committed and has been copied (or deleted),
|
* OBSOLETE_CNODE: cnode is being committed and has been copied (or deleted),
|
||||||
* so it can (and must) be freed when the commit is finished
|
* so it can (and must) be freed when the commit is finished
|
||||||
|
* COW_CNODE: cnode is being committed and must be copied before writing
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
DIRTY_CNODE = 0,
|
DIRTY_CNODE = 0,
|
||||||
COW_CNODE = 1,
|
OBSOLETE_CNODE = 1,
|
||||||
OBSOLETE_CNODE = 2,
|
COW_CNODE = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1468,6 +1468,15 @@ extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
|
||||||
|
|
||||||
/* io.c */
|
/* io.c */
|
||||||
void ubifs_ro_mode(struct ubifs_info *c, int err);
|
void ubifs_ro_mode(struct ubifs_info *c, int err);
|
||||||
|
int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
|
||||||
|
int len, int even_ebadmsg);
|
||||||
|
int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
|
||||||
|
int len, int dtype);
|
||||||
|
int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
|
||||||
|
int dtype);
|
||||||
|
int ubifs_leb_unmap(struct ubifs_info *c, int lnum);
|
||||||
|
int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype);
|
||||||
|
int ubifs_is_mapped(const struct ubifs_info *c, int lnum);
|
||||||
int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
|
int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
|
||||||
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
|
int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
|
||||||
int dtype);
|
int dtype);
|
||||||
|
@ -1747,8 +1756,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
|
||||||
int offs, void *sbuf, int jhead);
|
int offs, void *sbuf, int jhead);
|
||||||
struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
|
struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
|
||||||
int offs, void *sbuf);
|
int offs, void *sbuf);
|
||||||
int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf);
|
int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf);
|
||||||
int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf);
|
int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf);
|
||||||
int ubifs_rcvry_gc_commit(struct ubifs_info *c);
|
int ubifs_rcvry_gc_commit(struct ubifs_info *c);
|
||||||
int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,
|
int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,
|
||||||
int deletion, loff_t new_size);
|
int deletion, loff_t new_size);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user