Commit 8e3bda08 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6

* 'linux-next' of git://git.infradead.org/ubifs-2.6: (33 commits)
  UBIFS: add more useful debugging prints
  UBIFS: print debugging messages properly
  UBIFS: fix numerous spelling mistakes
  UBIFS: allow mounting when short of space
  UBIFS: fix writing uncompressed files
  UBIFS: fix checkpatch.pl warnings
  UBIFS: fix sparse warnings
  UBIFS: simplify make_free_space
  UBIFS: do not lie about used blocks
  UBIFS: restore budg_uncommitted_idx
  UBIFS: always commit on unmount
  UBIFS: use ubi_sync
  UBIFS: always commit in sync_fs
  UBIFS: fix file-system synchronization
  UBIFS: fix constants initialization
  UBIFS: avoid unnecessary calculations
  UBIFS: re-calculate min_idx_size after the commit
  UBIFS: use nicer 64-bit math
  UBIFS: fix available blocks count
  UBIFS: various comment improvements and fixes
  ...
parents 574c3fda 8e5033ad
......@@ -95,6 +95,9 @@ no_chk_data_crc skip checking of CRCs on data nodes in order to
of this option is that corruption of the contents
of a file can go unnoticed.
chk_data_crc (*) do not skip checking CRCs on data nodes
compr=none override default compressor and set it to "none"
compr=lzo override default compressor and set it to "lzo"
compr=zlib override default compressor and set it to "zlib"
Quick usage instructions
......
This diff is collapsed.
......@@ -470,12 +470,12 @@ int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot)
{
struct ubifs_idx_node *idx;
int lnum, offs, len, err = 0;
struct ubifs_debug_info *d = c->dbg;
c->old_zroot = *zroot;
lnum = c->old_zroot.lnum;
offs = c->old_zroot.offs;
len = c->old_zroot.len;
d->old_zroot = *zroot;
lnum = d->old_zroot.lnum;
offs = d->old_zroot.offs;
len = d->old_zroot.len;
idx = kmalloc(c->max_idx_node_sz, GFP_NOFS);
if (!idx)
......@@ -485,8 +485,8 @@ int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot)
if (err)
goto out;
c->old_zroot_level = le16_to_cpu(idx->level);
c->old_zroot_sqnum = le64_to_cpu(idx->ch.sqnum);
d->old_zroot_level = le16_to_cpu(idx->level);
d->old_zroot_sqnum = le64_to_cpu(idx->ch.sqnum);
out:
kfree(idx);
return err;
......@@ -509,6 +509,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
{
int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt;
int first = 1, iip;
struct ubifs_debug_info *d = c->dbg;
union ubifs_key lower_key, upper_key, l_key, u_key;
unsigned long long uninitialized_var(last_sqnum);
struct ubifs_idx_node *idx;
......@@ -525,9 +526,9 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
UBIFS_IDX_NODE_SZ;
/* Start at the old zroot */
lnum = c->old_zroot.lnum;
offs = c->old_zroot.offs;
len = c->old_zroot.len;
lnum = d->old_zroot.lnum;
offs = d->old_zroot.offs;
len = d->old_zroot.len;
iip = 0;
/*
......@@ -560,11 +561,11 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
if (first) {
first = 0;
/* Check root level and sqnum */
if (le16_to_cpu(idx->level) != c->old_zroot_level) {
if (le16_to_cpu(idx->level) != d->old_zroot_level) {
err = 2;
goto out_dump;
}
if (le64_to_cpu(idx->ch.sqnum) != c->old_zroot_sqnum) {
if (le64_to_cpu(idx->ch.sqnum) != d->old_zroot_sqnum) {
err = 3;
goto out_dump;
}
......
......@@ -33,7 +33,7 @@
/* Fake description object for the "none" compressor */
static struct ubifs_compressor none_compr = {
.compr_type = UBIFS_COMPR_NONE,
.name = "no compression",
.name = "none",
.capi_name = "",
};
......@@ -43,13 +43,13 @@ static DEFINE_MUTEX(lzo_mutex);
static struct ubifs_compressor lzo_compr = {
.compr_type = UBIFS_COMPR_LZO,
.comp_mutex = &lzo_mutex,
.name = "LZO",
.name = "lzo",
.capi_name = "lzo",
};
#else
static struct ubifs_compressor lzo_compr = {
.compr_type = UBIFS_COMPR_LZO,
.name = "LZO",
.name = "lzo",
};
#endif
......@@ -108,7 +108,7 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
if (compr->comp_mutex)
mutex_lock(compr->comp_mutex);
err = crypto_comp_compress(compr->cc, in_buf, in_len, out_buf,
out_len);
(unsigned int *)out_len);
if (compr->comp_mutex)
mutex_unlock(compr->comp_mutex);
if (unlikely(err)) {
......@@ -119,10 +119,10 @@ void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
}
/*
* Presently, we just require that compression results in less data,
* rather than any defined minimum compression ratio or amount.
* If the data compressed only slightly, it is better to leave it
* uncompressed to improve read speed.
*/
if (ALIGN(*out_len, 8) >= ALIGN(in_len, 8))
if (in_len - *out_len < UBIFS_MIN_COMPRESS_DIFF)
goto no_compr;
return;
......@@ -172,7 +172,7 @@ int ubifs_decompress(const void *in_buf, int in_len, void *out_buf,
if (compr->decomp_mutex)
mutex_lock(compr->decomp_mutex);
err = crypto_comp_decompress(compr->cc, in_buf, in_len, out_buf,
out_len);
(unsigned int *)out_len);
if (compr->decomp_mutex)
mutex_unlock(compr->decomp_mutex);
if (err)
......@@ -244,7 +244,7 @@ int __init ubifs_compressors_init(void)
/**
* ubifs_compressors_exit - de-initialize UBIFS compressors.
*/
void __exit ubifs_compressors_exit(void)
void ubifs_compressors_exit(void)
{
compr_exit(&lzo_compr);
compr_exit(&zlib_compr);
......
This diff is collapsed.
......@@ -25,7 +25,56 @@
#ifdef CONFIG_UBIFS_FS_DEBUG
#define UBIFS_DBG(op) op
/**
* ubifs_debug_info - per-FS debugging information.
* @buf: a buffer of LEB size, used for various purposes
* @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_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
* @fail_timeout: time in jiffies when delay of failure mode expires
* @fail_cnt: current number of calls to failure mode I/O functions
* @fail_cnt_max: number of calls by which to delay failure mode
* @chk_lpt_sz: 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_lebs: used by LPT tree size checker
* @new_nhead_offs: used by LPT tree size checker
* @new_ihead_lnum: used by debugging to check ihead_lnum
* @new_ihead_offs: used by debugging to check ihead_offs
*
* debugfs_dir_name: name of debugfs directory containing this file-system's
* files
* debugfs_dir: direntry object of the file-system debugfs directory
* dump_lprops: "dump lprops" debugfs knob
* dump_budg: "dump budgeting information" debugfs knob
* dump_tnc: "dump TNC" debugfs knob
*/
struct ubifs_debug_info {
void *buf;
struct ubifs_zbranch old_zroot;
int old_zroot_level;
unsigned long long old_zroot_sqnum;
int failure_mode;
int fail_delay;
unsigned long fail_timeout;
unsigned int fail_cnt;
unsigned int fail_cnt_max;
long long chk_lpt_sz;
long long chk_lpt_sz2;
long long chk_lpt_wastage;
int chk_lpt_lebs;
int new_nhead_offs;
int new_ihead_lnum;
int new_ihead_offs;
char debugfs_dir_name[100];
struct dentry *debugfs_dir;
struct dentry *dump_lprops;
struct dentry *dump_budg;
struct dentry *dump_tnc;
};
#define ubifs_assert(expr) do { \
if (unlikely(!(expr))) { \
......@@ -211,14 +260,18 @@ extern unsigned int ubifs_msg_flags;
extern unsigned int ubifs_chk_flags;
extern unsigned int ubifs_tst_flags;
/* Dump functions */
int ubifs_debugging_init(struct ubifs_info *c);
void ubifs_debugging_exit(struct ubifs_info *c);
/* Dump functions */
const char *dbg_ntype(int type);
const char *dbg_cstate(int cmt_state);
const char *dbg_get_key_dump(const struct ubifs_info *c,
const union ubifs_key *key);
void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode);
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,
int offs);
void dbg_dump_budget_req(const struct ubifs_budget_req *req);
void dbg_dump_lstats(const struct ubifs_lp_stats *lst);
void dbg_dump_budg(struct ubifs_info *c);
......@@ -233,9 +286,9 @@ void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
struct ubifs_nnode *parent, int iip);
void dbg_dump_tnc(struct ubifs_info *c);
void dbg_dump_index(struct ubifs_info *c);
void dbg_dump_lpt_lebs(const struct ubifs_info *c);
/* Checking helper functions */
typedef int (*dbg_leaf_callback)(struct ubifs_info *c,
struct ubifs_zbranch *zbr, void *priv);
typedef int (*dbg_znode_callback)(struct ubifs_info *c,
......@@ -274,9 +327,6 @@ int dbg_force_in_the_gaps(void);
#define dbg_failure_mode (ubifs_tst_flags & UBIFS_TST_RCVRY)
void dbg_failure_mode_registration(struct ubifs_info *c);
void dbg_failure_mode_deregistration(struct ubifs_info *c);
#ifndef UBIFS_DBG_PRESERVE_UBI
#define ubi_leb_read dbg_leb_read
......@@ -318,9 +368,13 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
return dbg_leb_change(desc, lnum, buf, len, UBI_UNKNOWN);
}
#else /* !CONFIG_UBIFS_FS_DEBUG */
/* Debugfs-related stuff */
int dbg_debugfs_init(void);
void dbg_debugfs_exit(void);
int dbg_debugfs_init_fs(struct ubifs_info *c);
void dbg_debugfs_exit_fs(struct ubifs_info *c);
#define UBIFS_DBG(op)
#else /* !CONFIG_UBIFS_FS_DEBUG */
/* Use "if (0)" to make compiler check arguments even if debugging is off */
#define ubifs_assert(expr) do { \
......@@ -360,23 +414,28 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
#define DBGKEY(key) ((char *)(key))
#define DBGKEY1(key) ((char *)(key))
#define dbg_ntype(type) ""
#define dbg_cstate(cmt_state) ""
#define dbg_get_key_dump(c, key) ({})
#define dbg_dump_inode(c, inode) ({})
#define dbg_dump_node(c, node) ({})
#define dbg_dump_budget_req(req) ({})
#define dbg_dump_lstats(lst) ({})
#define dbg_dump_budg(c) ({})
#define dbg_dump_lprop(c, lp) ({})
#define dbg_dump_lprops(c) ({})
#define dbg_dump_lpt_info(c) ({})
#define dbg_dump_leb(c, lnum) ({})
#define dbg_dump_znode(c, znode) ({})
#define dbg_dump_heap(c, heap, cat) ({})
#define dbg_dump_pnode(c, pnode, parent, iip) ({})
#define dbg_dump_tnc(c) ({})
#define dbg_dump_index(c) ({})
#define ubifs_debugging_init(c) 0
#define ubifs_debugging_exit(c) ({})
#define dbg_ntype(type) ""
#define dbg_cstate(cmt_state) ""
#define dbg_get_key_dump(c, key) ({})
#define dbg_dump_inode(c, inode) ({})
#define dbg_dump_node(c, node) ({})
#define dbg_dump_lpt_node(c, node, lnum, offs) ({})
#define dbg_dump_budget_req(req) ({})
#define dbg_dump_lstats(lst) ({})
#define dbg_dump_budg(c) ({})
#define dbg_dump_lprop(c, lp) ({})
#define dbg_dump_lprops(c) ({})
#define dbg_dump_lpt_info(c) ({})
#define dbg_dump_leb(c, lnum) ({})
#define dbg_dump_znode(c, znode) ({})
#define dbg_dump_heap(c, heap, cat) ({})
#define dbg_dump_pnode(c, pnode, parent, iip) ({})
#define dbg_dump_tnc(c) ({})
#define dbg_dump_index(c) ({})
#define dbg_dump_lpt_lebs(c) ({})
#define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0
#define dbg_old_index_check_init(c, zroot) 0
......@@ -396,9 +455,11 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
#define dbg_force_in_the_gaps_enabled 0
#define dbg_force_in_the_gaps() 0
#define dbg_failure_mode 0
#define dbg_failure_mode_registration(c) ({})
#define dbg_failure_mode_deregistration(c) ({})
#endif /* !CONFIG_UBIFS_FS_DEBUG */
#define dbg_debugfs_init() 0
#define dbg_debugfs_exit()
#define dbg_debugfs_init_fs(c) 0
#define dbg_debugfs_exit_fs(c) 0
#endif /* !CONFIG_UBIFS_FS_DEBUG */
#endif /* !__UBIFS_DEBUG_H__ */
......@@ -72,8 +72,8 @@ static int read_block(struct inode *inode, void *addr, unsigned int block,
return err;
}
ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_inode(inode)->creat_sqnum);
ubifs_assert(le64_to_cpu(dn->ch.sqnum) >
ubifs_inode(inode)->creat_sqnum);
len = le32_to_cpu(dn->size);
if (len <= 0 || len > UBIFS_BLOCK_SIZE)
goto dump;
......@@ -254,7 +254,7 @@ static int write_begin_slow(struct address_space *mapping,
}
if (!PageUptodate(page)) {
if (!(pos & PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE)
if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE)
SetPageChecked(page);
else {
err = do_readpage(page);
......@@ -444,7 +444,7 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
if (!PageUptodate(page)) {
/* The page is not loaded from the flash */
if (!(pos & PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE)
if (!(pos & ~PAGE_CACHE_MASK) && len == PAGE_CACHE_SIZE)
/*
* We change whole page so no need to load it. But we
* have to set the @PG_checked flag to make the further
......
......@@ -154,6 +154,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case FS_IOC_GETFLAGS:
flags = ubifs2ioctl(ubifs_inode(inode)->flags);
dbg_gen("get flags: %#x, i_flags %#x", flags, inode->i_flags);
return put_user(flags, (int __user *) arg);
case FS_IOC_SETFLAGS: {
......@@ -176,6 +177,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
err = mnt_want_write(file->f_path.mnt);
if (err)
return err;
dbg_gen("set flags: %#x, i_flags %#x", flags, inode->i_flags);
err = setflags(inode, flags);
mnt_drop_write(file->f_path.mnt);
return err;
......
......@@ -704,7 +704,7 @@ int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,
data->size = cpu_to_le32(len);
zero_data_node_unused(data);
if (!(ui->flags && UBIFS_COMPR_FL))
if (!(ui->flags & UBIFS_COMPR_FL))
/* Compression is disabled for this inode */
compr_type = UBIFS_COMPR_NONE;
else
......@@ -1220,7 +1220,7 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,
data_key_init(c, &key, inum, blk);
bit = old_size & (UBIFS_BLOCK_SIZE - 1);
blk = (old_size >> UBIFS_BLOCK_SHIFT) - (bit ? 0: 1);
blk = (old_size >> UBIFS_BLOCK_SHIFT) - (bit ? 0 : 1);
data_key_init(c, &to_key, inum, blk);
err = ubifs_tnc_remove_range(c, &key, &to_key);
......
......@@ -37,6 +37,22 @@
#ifndef __UBIFS_KEY_H__
#define __UBIFS_KEY_H__
/**
* key_mask_hash - mask a valid hash value.
* @val: value to be masked
*
* We use hash values as offset in directories, so values %0 and %1 are
* reserved for "." and "..". %2 is reserved for "end of readdir" marker. This
* function makes sure the reserved values are not used.
*/
static inline uint32_t key_mask_hash(uint32_t hash)
{
hash &= UBIFS_S_KEY_HASH_MASK;
if (unlikely(hash <= 2))
hash += 3;
return hash;
}
/**
* key_r5_hash - R5 hash function (borrowed from reiserfs).
* @s: direntry name
......@@ -54,16 +70,7 @@ static inline uint32_t key_r5_hash(const char *s, int len)
str++;
}
a &= UBIFS_S_KEY_HASH_MASK;
/*
* We use hash values as offset in directories, so values %0 and %1 are
* reserved for "." and "..". %2 is reserved for "end of readdir"
* marker.
*/
if (unlikely(a >= 0 && a <= 2))
a += 3;
return a;
return key_mask_hash(a);
}
/**
......@@ -77,10 +84,7 @@ static inline uint32_t key_test_hash(const char *str, int len)
len = min_t(uint32_t, len, 4);
memcpy(&a, str, len);
a &= UBIFS_S_KEY_HASH_MASK;
if (unlikely(a >= 0 && a <= 2))
a += 3;
return a;
return key_mask_hash(a);
}
/**
......
......@@ -520,13 +520,13 @@ static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops)
* @flags: new flags
* @idx_gc_cnt: change to the count of idx_gc list
*
* This function changes LEB properties. This function does not change a LEB
* property (@free, @dirty or @flag) if the value passed is %LPROPS_NC.
* This function changes LEB properties (@free, @dirty or @flag). However, the
* property which has the %LPROPS_NC value is not changed. Returns a pointer to
* the updated LEB properties on success and a negative error code on failure.
*
* This function returns a pointer to the updated LEB properties on success
* and a negative error code on failure. N.B. the LEB properties may have had to
* be copied (due to COW) and consequently the pointer returned may not be the
* same as the pointer passed.
* Note, the LEB properties may have had to be copied (due to COW) and
* consequently the pointer returned may not be the same as the pointer
* passed.
*/
const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
const struct ubifs_lprops *lp,
......@@ -1088,7 +1088,7 @@ static int scan_check_cb(struct ubifs_info *c,
}
}
sleb = ubifs_scan(c, lnum, 0, c->dbg_buf);
sleb = ubifs_scan(c, lnum, 0, c->dbg->buf);
if (IS_ERR(sleb)) {
/*
* After an unclean unmount, empty and freeable LEBs
......
......@@ -36,15 +36,16 @@
* can be written into a single eraseblock. In that case, garbage collection
* consists of just writing the whole table, which therefore makes all other
* eraseblocks reusable. In the case of the big model, dirty eraseblocks are
* selected for garbage collection, which consists are marking the nodes in
* selected for garbage collection, which consists of marking the clean nodes in
* that LEB as dirty, and then only the dirty nodes are written out. Also, in
* the case of the big model, a table of LEB numbers is saved so that the entire
* LPT does not to be scanned looking for empty eraseblocks when UBIFS is first
* mounted.
*/
#include <linux/crc16.h>
#include "ubifs.h"
#include <linux/crc16.h>
#include <linux/math64.h>
/**
* do_calc_lpt_geom - calculate sizes for the LPT area.
......@@ -135,15 +136,13 @@ static void do_calc_lpt_geom(struct ubifs_info *c)
int ubifs_calc_lpt_geom(struct ubifs_info *c)
{
int lebs_needed;
uint64_t sz;
long long sz;
do_calc_lpt_geom(c);
/* Verify that lpt_lebs is big enough */
sz = c->lpt_sz * 2; /* Must have at least 2 times the size */
sz += c->leb_size - 1;
do_div(sz, c->leb_size);
lebs_needed = sz;
lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size);
if (lebs_needed > c->lpt_lebs) {
ubifs_err("too few LPT LEBs");
return -EINVAL;
......@@ -156,7 +155,6 @@ int ubifs_calc_lpt_geom(struct ubifs_info *c)
}
c->check_lpt_free = c->big_lpt;
return 0;
}
......@@ -176,7 +174,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
int *big_lpt)
{
int i, lebs_needed;
uint64_t sz;
long long sz;
/* Start by assuming the minimum number of LPT LEBs */
c->lpt_lebs = UBIFS_MIN_LPT_LEBS;
......@@ -203,9 +201,7 @@ static int calc_dflt_lpt_geom(struct ubifs_info *c, int *main_lebs,
/* Now check there are enough LPT LEBs */
for (i = 0; i < 64 ; i++) {
sz = c->lpt_sz * 4; /* Allow 4 times the size */
sz += c->leb_size - 1;
do_div(sz, c->leb_size);
lebs_needed = sz;
lebs_needed = div_u64(sz + c->leb_size - 1, c->leb_size);
if (lebs_needed > c->lpt_lebs) {
/* Not enough LPT LEBs so try again with more */
c->lpt_lebs = lebs_needed;
......@@ -558,7 +554,7 @@ static int calc_nnode_num(int row, int col)
* This function calculates and returns the nnode number based on the parent's
* nnode number and the index in parent.
*/
static int calc_nnode_num_from_parent(struct ubifs_info *c,
static int calc_nnode_num_from_parent(const struct ubifs_info *c,
struct ubifs_nnode *parent, int iip)
{
int num, shft;
......@@ -583,7 +579,7 @@ static int calc_nnode_num_from_parent(struct ubifs_info *c,
* This function calculates and returns the pnode number based on the parent's
* nnode number and the index in parent.
*/
static int calc_pnode_num_from_parent(struct ubifs_info *c,
static int calc_pnode_num_from_parent(const struct ubifs_info *c,
struct ubifs_nnode *parent, int iip)
{
int i, n = c->lpt_hght - 1, pnum = parent->num, num = 0;
......@@ -966,7 +962,7 @@ static int check_lpt_type(uint8_t **addr, int *pos, int type)
*
* This function returns %0 on success and a negative error code on failure.
*/
static int unpack_pnode(struct ubifs_info *c, void *buf,
static int unpack_pnode(const struct ubifs_info *c, void *buf,
struct ubifs_pnode *pnode)
{
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
......@@ -996,15 +992,15 @@ static int unpack_pnode(struct ubifs_info *c, void *buf,
}
/**
* unpack_nnode - unpack a nnode.
* ubifs_unpack_nnode - unpack a nnode.
* @c: UBIFS file-system description object
* @buf: buffer containing packed nnode to unpack
* @nnode: nnode structure to fill
*
* This function returns %0 on success and a negative error code on failure.
*/
static int unpack_nnode(struct ubifs_info *c, void *buf,
struct ubifs_nnode *nnode)
int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
struct ubifs_nnode *nnode)
{
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int i, pos = 0, err;
......@@ -1036,7 +1032,7 @@ static int unpack_nnode(struct ubifs_info *c, void *buf,
*
* This function returns %0 on success and a negative error code on failure.
*/
static int unpack_ltab(struct ubifs_info *c, void *buf)
static int unpack_ltab(const struct ubifs_info *c, void *buf)
{
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int i, pos = 0, err;
......@@ -1068,7 +1064,7 @@ static int unpack_ltab(struct ubifs_info *c, void *buf)
*
* This function returns %0 on success and a negative error code on failure.
*/
static int unpack_lsave(struct ubifs_info *c, void *buf)
static int unpack_lsave(const struct ubifs_info *c, void *buf)
{
uint8_t *addr = buf + UBIFS_LPT_CRC_BYTES;
int i, pos = 0, err;
......@@ -1096,7 +1092,7 @@ static int unpack_lsave(struct ubifs_info *c, void *buf)
*
* This function returns %0 on success and a negative error code on failure.
*/
static int validate_nnode(struct ubifs_info *c, struct ubifs_nnode *nnode,
static int validate_nnode(const struct ubifs_info *c, struct ubifs_nnode *nnode,
struct ubifs_nnode *parent, int iip)
{
int i, lvl, max_offs;
......@@ -1140,7 +1136,7 @@ static int validate_nnode(struct ubifs_info *c, struct ubifs_nnode *nnode,
*
* This function returns %0 on success and a negative error code on failure.
*/
static int validate_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
static int validate_pnode(const struct ubifs_info *c, struct ubifs_pnode *pnode,
struct ubifs_nnode *parent, int iip)
{
int i;
......@@ -1174,7 +1170,8 @@ static int validate_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
* This function calculates the LEB numbers for the LEB properties it contains
* based on the pnode number.
*/
static void set_pnode_lnum(struct ubifs_info *c, struct ubifs_pnode *pnode)
static void set_pnode_lnum(const struct ubifs_info *c,
struct ubifs_pnode *pnode)
{
int i, lnum;
......@@ -1227,7 +1224,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
err = ubi_read(c->ubi, lnum, buf, offs, c->nnode_sz);
if (err)
goto out;
err = unpack_nnode(c, buf, nnode);
err = ubifs_unpack_nnode(c, buf, nnode);
if (err)
goto out;
}
......@@ -1816,7 +1813,7 @@ static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c,
c->nnode_sz);
if (err)
return ERR_PTR(err);
err = unpack_nnode(c, buf, nnode);
err = ubifs_unpack_nnode(c, buf, nnode);
if (err)
return ERR_PTR(err);
}
......
This diff is collapsed.
......@@ -899,7 +899,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci)
for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) {
struct ubifs_scan_leb *sleb;
sleb = ubifs_scan(c, lnum, 0, c->dbg_buf);
sleb = ubifs_scan(c, lnum, 0, c->dbg->buf);
if (IS_ERR(sleb)) {
err = PTR_ERR(sleb);
break;
......
......@@ -144,7 +144,7 @@ static int set_bud_lprops(struct ubifs_info *c, struct replay_entry *r)
/*
* If the replay order was perfect the dirty space would now be
* zero. The order is not perfect because the the journal heads
* race with eachother. This is not a problem but is does mean
* race with each other. This is not a problem but is does mean
* that the dirty space may temporarily exceed c->leb_size
* during the replay.
*/
......@@ -656,7 +656,7 @@ static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead,
* @dirty: amount of dirty space from padding and deletion nodes
*
* This function inserts a reference node to the replay tree and returns zero
* in case of success ort a negative error code in case of failure.
* in case of success or a negative error code in case of failure.
*/
static int insert_ref_node(struct ubifs_info *c, int lnum, int offs,
unsigned long long sqnum, int free, int dirty)
......@@ -883,7 +883,7 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
* This means that we reached end of log and now
* look to the older log data, which was already
* committed but the eraseblock was not erased (UBIFS
* only unmaps it). So this basically means we have to
* only un-maps it). So this basically means we have to
* exit with "end of log" code.
*/
err = 1;
......@@ -1062,6 +1062,15 @@ int ubifs_replay_journal(struct ubifs_info *c)
if (err)
goto out;
/*
* UBIFS budgeting calculations use @c->budg_uncommitted_idx variable
* to roughly estimate index growth. Things like @c->min_idx_lebs
* depend on it. This means we have to initialize it to make sure
* budgeting works properly.
*/
c->budg_uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt);
c->budg_uncommitted_idx *= c->max_idx_node_sz;
ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery);
dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, "
"highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum,
......
......@@ -28,6 +28,7 @@
#include "ubifs.h"
#include <linux/random.h>
#include <linux/math64.h>
/*
* Default journal size in logical eraseblocks as a percent of total
......@@ -80,7 +81,7 @@ static int create_default_filesystem(struct ubifs_info *c)
int err, tmp, jnl_lebs, log_lebs, max_buds, main_lebs, main_first;
int lpt_lebs, lpt_first, orph_lebs, big_lpt, ino_waste, sup_flags = 0;
int min_leb_cnt = UBIFS_MIN_LEB_CNT;
uint64_t tmp64, main_bytes;
long long tmp64, main_bytes;
__le64 tmp_le64;
/* Some functions called from here depend on the @c->key_len filed */
......@@ -160,7 +161,7 @@ static int create_default_filesystem(struct ubifs_info *c)
if (!sup)
return -ENOMEM;
tmp64 = (uint64_t)max_buds * c->leb_size;
tmp64 = (long long)max_buds * c->leb_size;
if (big_lpt)
sup_flags |= UBIFS_FLG_BIGLPT;
......@@ -179,14 +180,16 @@ static int create_default_filesystem(struct ubifs_info *c)
sup->fanout = cpu_to_le32(DEFAULT_FANOUT);
sup->lsave_cnt = cpu_to_le32(c->lsave_cnt);
sup->fmt_version = cpu_to_le32(UBIFS_FORMAT_VERSION);
sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO);
sup->time_gran = cpu_to_le32(DEFAULT_TIME_GRAN);
if (c->mount_opts.override_compr)
sup->default_compr = cpu_to_le16(c->mount_opts.compr_type);
else
sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO);
generate_random_uuid(sup->uuid);
main_bytes = (uint64_t)main_lebs * c->leb_size;
tmp64 = main_bytes * DEFAULT_RP_PERCENT;
do_div(tmp64, 100);
main_bytes = (long long)main_lebs * c->leb_size;
tmp64 = div_u64(main_bytes * DEFAULT_RP_PERCENT, 100);
if (tmp64 > DEFAULT_MAX_RP_SIZE)
tmp64 = DEFAULT_MAX_RP_SIZE;
sup->rp_size = cpu_to_le64(tmp64);
......@@ -582,16 +585,15 @@ int ubifs_read_superblock(struct ubifs_info *c)
c->jhead_cnt = le32_to_cpu(sup->jhead_cnt) + NONDATA_JHEADS_CNT;
c->fanout = le32_to_cpu(sup->fanout);
c->lsave_cnt = le32_to_cpu(sup->lsave_cnt);
c->default_compr = le16_to_cpu(sup->default_compr);
c->rp_size = le64_to_cpu(sup->rp_size);
c->rp_uid = le32_to_cpu(sup->rp_uid);
c->rp_gid = le32_to_cpu(sup->rp_gid);
sup_flags = le32_to_cpu(sup->flags);
if (!c->mount_opts.override_compr)
c->default_compr = le16_to_cpu(sup->default_compr);
c->vfs_sb->s_time_gran = le32_to_cpu(sup->time_gran);
memcpy(&c->uuid, &sup->uuid, 16);
c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT);
/* Automatically increase file system size to the maximum size */
......
This diff is collapsed.
......@@ -2245,12 +2245,11 @@ int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key,
if (found) {
/* Ensure the znode is dirtied */
if (znode->cnext || !ubifs_zn_dirty(znode)) {
znode = dirty_cow_bottom_up(c,
znode);
if (IS_ERR(znode)) {
err = PTR_ERR(znode);
goto out_unlock;
}
znode = dirty_cow_bottom_up(c, znode);
if (IS_ERR(znode)) {
err = PTR_ERR(znode);
goto out_unlock;
}
}
zbr = &znode->zbranch[n];
lnc_free(zbr);
......@@ -2317,11 +2316,11 @@ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key,
/* Ensure the znode is dirtied */
if (znode->cnext || !ubifs_zn_dirty(znode)) {
znode = dirty_cow_bottom_up(c, znode);
if (IS_ERR(znode)) {
err = PTR_ERR(znode);
goto out_unlock;
}
znode = dirty_cow_bottom_up(c, znode);
if (IS_ERR(znode)) {
err = PTR_ERR(znode);
goto out_unlock;
}
}
if (found == 1) {
......@@ -2627,11 +2626,11 @@ int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key,
/* Ensure the znode is dirtied */
if (znode->cnext || !ubifs_zn_dirty(znode)) {
znode = dirty_cow_bottom_up(c, znode);
if (IS_ERR(znode)) {
err = PTR_ERR(znode);
goto out_unlock;
}
znode = dirty_cow_bottom_up(c, znode);
if (IS_ERR(znode)) {
err = PTR_ERR(znode);
goto out_unlock;
}
}
/* Remove all keys in range except the first */
......
......@@ -553,8 +553,8 @@ static int layout_in_empty_space(struct ubifs_info *c)
}
#ifdef CONFIG_UBIFS_FS_DEBUG
c->new_ihead_lnum = lnum;
c->new_ihead_offs = buf_offs;
c->dbg->new_ihead_lnum = lnum;
c->dbg->new_ihead_offs = buf_offs;
#endif
return 0;
......@@ -802,8 +802,10 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot)
* budgeting subsystem to assume the index is already committed,
* even though it is not.
*/
ubifs_assert(c->min_idx_lebs == ubifs_calc_min_idx_lebs(c));
c->old_idx_sz = c->calc_idx_sz;
c->budg_uncommitted_idx = 0;
c->min_idx_lebs = ubifs_calc_min_idx_lebs(c);
spin_unlock(&c->space_lock);
mutex_unlock(&c->tnc_mutex);
......@@ -1002,7 +1004,8 @@ static int write_index(struct ubifs_info *c)
}
#ifdef CONFIG_UBIFS_FS_DEBUG
if (lnum != c->new_ihead_lnum || buf_offs != c->new_ihead_offs) {
if (lnum != c->dbg->new_ihead_lnum ||
buf_offs != c->dbg->new_ihead_offs) {
ubifs_err("inconsistent ihead");
return -EINVAL;
}
......
......@@ -51,6 +51,13 @@
*/
#define UBIFS_MIN_COMPR_LEN 128
/*
* If compressed data length is less than %UBIFS_MIN_COMPRESS_DIFF bytes
* shorter than uncompressed data length, UBIFS preferes to leave this data
* node uncompress, because it'll be read faster.
*/
#define UBIFS_MIN_COMPRESS_DIFF 64
/* Root inode number */
#define UBIFS_ROOT_INO 1
......
......@@ -63,6 +63,14 @@
#define SQNUM_WARN_WATERMARK 0xFFFFFFFF00000000ULL
#define SQNUM_WATERMARK 0xFFFFFFFFFF000000ULL
/*
* Minimum amount of LEBs reserved for the index. At present the index needs at
* least 2 LEBs: one for the index head and one for in-the-gaps method (which
* currently does not cater for the index head and so excludes it from
* consideration).
*/
#define MIN_INDEX_LEBS 2
/* Minimum amount of data UBIFS writes to the flash */
#define MIN_WRITE_SZ (UBIFS_DATA_NODE_SZ + 8)
......@@ -386,12 +394,12 @@ struct ubifs_inode {
unsigned int dirty:1;
unsigned int xattr:1;
unsigned int bulk_read:1;
unsigned int compr_type:2;
struct mutex ui_mutex;
spinlock_t ui_lock;
loff_t synced_i_size;
loff_t ui_size;
int flags;
int compr_type;
pgoff_t last_page_read;
pgoff_t read_in_a_row;
int data_len;
......@@ -419,7 +427,7 @@ struct ubifs_unclean_leb {
*
* LPROPS_UNCAT: not categorized
* LPROPS_DIRTY: dirty > 0, not index
* LPROPS_DIRTY_IDX: dirty + free > UBIFS_CH_SZ and index
* LPROPS_DIRTY_IDX: dirty + free > @c->min_idx_node_sze and index
* LPROPS_FREE: free > 0, not empty, not index
* LPROPS_HEAP_CNT: number of heaps used for storing categorized LEBs
* LPROPS_EMPTY: LEB is empty, not taken
......@@ -473,8 +481,8 @@ struct ubifs_lprops {
struct ubifs_lpt_lprops {
int free;
int dirty;
unsigned tgc : 1;
unsigned cmt : 1;
unsigned tgc:1;
unsigned cmt:1;
};
/**
......@@ -482,24 +490,26 @@ struct ubifs_lpt_lprops {
* @empty_lebs: number of empty LEBs
* @taken_empty_lebs: number of taken LEBs
* @idx_lebs: number of indexing LEBs
* @total_free: total free space in bytes
* @total_dirty: total dirty space in bytes
* @total_used: total used space in bytes (includes only data LEBs)
* @total_dead: total dead space in bytes (includes only data LEBs)
* @total_dark: total dark space in bytes (includes only data LEBs)
* @total_free: total free space in bytes (includes all LEBs)
* @total_dirty: total dirty space in bytes (includes all LEBs)
* @total_used: total used space in bytes (does not include index LEBs)
* @total_dead: total dead space in bytes (does not include index LEBs)
* @total_dark: total dark space in bytes (does not include index LEBs)
*
* The @taken_empty_lebs field counts the LEBs that are in the transient state
* of having been "taken" for use but not yet written to. @taken_empty_lebs is
* needed to account correctly for @gc_lnum, otherwise @empty_lebs could be
* used by itself (in which case 'unused_lebs' would be a better name). In the
* case of @gc_lnum, it is "taken" at mount time or whenever a LEB is retained
* by GC, but unlike other empty LEBs that are "taken", it may not be written
* straight away (i.e. before the next commit start or unmount), so either
* @gc_lnum must be specially accounted for, or the current approach followed
* i.e. count it under @taken_empty_lebs.
*
* N.B. total_dirty and total_used are different to other total_* fields,
* because they account _all_ LEBs, not just data LEBs.
* @empty_lebs includes @taken_empty_lebs.
*
* 'taken_empty_lebs' counts the LEBs that are in the transient state of having
* been 'taken' for use but not yet written to. 'taken_empty_lebs' is needed
* to account correctly for gc_lnum, otherwise 'empty_lebs' could be used
* by itself (in which case 'unused_lebs' would be a better name). In the case
* of gc_lnum, it is 'taken' at mount time or whenever a LEB is retained by GC,
* but unlike other empty LEBs that are 'taken', it may not be written straight
* away (i.e. before the next commit start or unmount), so either gc_lnum must
* be specially accounted for, or the current approach followed i.e. count it
* under 'taken_empty_lebs'.
* @total_used, @total_dead and @total_dark fields do not account indexing
* LEBs.
*/
struct ubifs_lp_stats {
int empty_lebs;
......@@ -893,15 +903,25 @@ struct ubifs_orphan {
/**
* struct ubifs_mount_opts - UBIFS-specific mount options information.
* @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast)
* @bulk_read: enable bulk-reads
* @chk_data_crc: check CRCs when reading data nodes
* @bulk_read: enable/disable bulk-reads (%0 default, %1 disabe, %2 enable)
* @chk_data_crc: enable/disable CRC data checking when reading data nodes
* (%0 default, %1 disabe, %2 enable)
* @override_compr: override default compressor (%0 - do not override and use
* superblock compressor, %1 - override and use compressor
* specified in @compr_type)
* @compr_type: compressor type to override the superblock compressor with
* (%UBIFS_COMPR_NONE, etc)
*/
struct ubifs_mount_opts {
unsigned int unmount_mode:2;
unsigned int bulk_read:2;
unsigned int chk_data_crc:2;
unsigned int override_compr:1;
unsigned int compr_type:2;
};
struct ubifs_debug_info;
/**
* struct ubifs_info - UBIFS file-system description data structure
* (per-superblock).
......@@ -946,6 +966,7 @@ struct ubifs_mount_opts {
* @no_chk_data_crc: do not check CRCs when reading data nodes (except during
* recovery)
* @bulk_read: enable bulk-reads
* @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
*
* @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
* @calc_idx_sz
......@@ -963,8 +984,6 @@ struct ubifs_mount_opts {
* @ileb_nxt: next pre-allocated index LEBs
* @old_idx: tree of index nodes obsoleted since the last commit start
* @bottom_up_buf: a buffer which is used by 'dirty_cow_bottom_up()' in tnc.c
* @new_ihead_lnum: used by debugging to check ihead_lnum
* @new_ihead_offs: used by debugging to check ihead_offs
*
* @mst_node: master node
* @mst_offs: offset of valid master node
......@@ -986,7 +1005,6 @@ struct ubifs_mount_opts {
* @main_lebs: count of LEBs in the main area
* @main_first: first LEB of the main area
* @main_bytes: main area size in bytes
* @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc)
*
* @key_hash_type: type of the key hash
* @key_hash: direntry key hash function
......@@ -1149,15 +1167,7 @@ struct ubifs_mount_opts {
* @always_chk_crc: always check CRCs (while mounting and remounting rw)
* @mount_opts: UBIFS-specific mount options
*
* @dbg_buf: a buffer of LEB size used for debugging purposes
* @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_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
* @fail_timeout: time in jiffies when delay of failure mode expires
* @fail_cnt: current number of calls to failure mode I/O functions
* @fail_cnt_max: number of calls by which to delay failure mode
* @dbg: debugging-related information
*/
struct ubifs_info {
struct super_block *vfs_sb;
......@@ -1196,6 +1206,7 @@ struct ubifs_info {
unsigned int big_lpt:1;
unsigned int no_chk_data_crc:1;
unsigned int bulk_read:1;
unsigned int default_compr:2;
struct mutex tnc_mutex;
struct ubifs_zbranch zroot;
......@@ -1212,10 +1223,6 @@ struct ubifs_info {
int ileb_nxt;
struct rb_root old_idx;
int *bottom_up_buf;
#ifdef CONFIG_UBIFS_FS_DEBUG
int new_ihead_lnum;
int new_ihead_offs;
#endif
struct ubifs_mst_node *mst_node;
int mst_offs;
......@@ -1237,7 +1244,6 @@ struct ubifs_info {
int main_lebs;
int main_first;
long long main_bytes;
int default_compr;
uint8_t key_hash_type;
uint32_t (*key_hash)(const char *str, int len);
......@@ -1315,8 +1321,8 @@ struct ubifs_info {
void *sbuf;
struct list_head idx_gc;
int idx_gc_cnt;
volatile int gc_seq;
volatile int gced_lnum;
int gc_seq;
int gced_lnum;
struct list_head infos_list;
struct mutex umount_mutex;
......@@ -1391,21 +1397,7 @@ struct ubifs_info {
struct ubifs_mount_opts mount_opts;
#ifdef CONFIG_UBIFS_FS_DEBUG
void *dbg_buf;
struct ubifs_zbranch old_zroot;
int old_zroot_level;
unsigned long long old_zroot_sqnum;
int failure_mode;
int fail_delay;
unsigned long fail_timeout;
unsigned int fail_cnt;
unsigned int fail_cnt_max;
long long chk_lpt_sz;
long long chk_lpt_sz2;
long long chk_lpt_wastage;
int chk_lpt_lebs;
int new_nhead_lnum;
int new_nhead_offs;
struct ubifs_debug_info *dbg;
#endif
};
......@@ -1505,7 +1497,7 @@ void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode,
long long ubifs_get_free_space(struct ubifs_info *c);
int ubifs_calc_min_idx_lebs(struct ubifs_info *c);
void ubifs_convert_page_budget(struct ubifs_info *c);
long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free);
long long ubifs_reported_space(const struct ubifs_info *c, long long free);
long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs);
/* find.c */
......@@ -1639,6 +1631,9 @@ void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty);
void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode);
uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits);
struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght);
/* Needed only in debugging code in lpt_commit.c */
int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,
struct ubifs_nnode *nnode);
/* lpt_commit.c */
int ubifs_lpt_start_commit(struct ubifs_info *c);
......@@ -1714,7 +1709,7 @@ long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
/* compressor.c */
int __init ubifs_compressors_init(void);
void __exit ubifs_compressors_exit(void);
void ubifs_compressors_exit(void);
void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
int *compr_type);
int ubifs_decompress(const void *buf, int len, void *out, int *out_len,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment