diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile index b8f47e7..7d376da 100644 --- a/fs/ubifs/Makefile +++ b/fs/ubifs/Makefile @@ -1,4 +1,4 @@ obj-y += ubifs.o io.o super.o sb.o master.o -obj-y += lpt_commit.o scan.o dir.o +obj-y += scan.o dir.o misc.o obj-y += tnc.o tnc_misc.o debug.o crc16.o obj-y += log.o recovery.o replay.o diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 3077339..4e3f328 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -19,7 +30,6 @@ #include #include "ubifs.h" - static const char *get_key_fmt(int fmt) { switch (fmt) { @@ -60,6 +70,10 @@ } } +/* + * removed in barebox +static const char *get_dent_type(int type) + */ const char *dbg_snprintf_key(const struct ubifs_info *c, const union ubifs_key *key, char *buffer, int len) @@ -96,7 +110,7 @@ } } else len -= snprintf(p, len, "bad key format %d", c->key_fmt); - ubifs_assert(len > 0); + ubifs_assert(c, len > 0); return p; } @@ -195,6 +209,7 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode) { + /* removed in barebox */ } void ubifs_dump_node(const struct ubifs_info *c, const void *node) @@ -363,7 +378,8 @@ pr_err("(bad name length, not printing, bad or corrupted node)"); else { for (i = 0; i < nlen && dent->name[i]; i++) - pr_cont("%c", dent->name[i]); + pr_cont("%c", isprint(dent->name[i]) ? + dent->name[i] : '?'); } pr_cont("\n"); @@ -444,171 +460,310 @@ spin_unlock(&dbg_lock); } -void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi) -{ -} +/* + * removed in barebox +void ubifs_dump_budget_req(const struct ubifs_budget_req *req) + */ +/* + * removed in barebox +void ubifs_dump_lstats(const struct ubifs_lp_stats *lst) + */ + +/* + * removed in barebox +void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi) + */ + +/* + * removed in barebox +void ubifs_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp) + */ + +/* + * removed in barebox +void ubifs_dump_lprops(struct ubifs_info *c) + */ + +/* + * removed in barebox +void ubifs_dump_lpt_info(struct ubifs_info *c) + */ + +/* + * removed in barebox void ubifs_dump_sleb(const struct ubifs_info *c, const struct ubifs_scan_leb *sleb, int offs) -{ - struct ubifs_scan_node *snod; + */ - pr_err("(pid %d) start dumping scanned data from LEB %d:%d\n", - 0, sleb->lnum, offs); - - list_for_each_entry(snod, &sleb->nodes, list) { - cond_resched(); - pr_err("Dumping node at LEB %d:%d len %d\n", - sleb->lnum, snod->offs, snod->len); - ubifs_dump_node(c, snod->node); - } -} - +/* + * removed in barebox void ubifs_dump_leb(const struct ubifs_info *c, int lnum) -{ - struct ubifs_scan_leb *sleb; - struct ubifs_scan_node *snod; - void *buf; + */ - pr_err("(pid %d) start dumping LEB %d\n", 0, lnum); - - buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); - if (!buf) { - ubifs_err(c, "cannot allocate memory for dumping LEB %d", lnum); - return; - } - - sleb = ubifs_scan(c, lnum, 0, buf, 0); - if (IS_ERR(sleb)) { - ubifs_err(c, "scan error %d", (int)PTR_ERR(sleb)); - goto out; - } - - pr_err("LEB %d has %d nodes ending at %d\n", lnum, - sleb->nodes_cnt, sleb->endpt); - - list_for_each_entry(snod, &sleb->nodes, list) { - cond_resched(); - pr_err("Dumping node at LEB %d:%d len %d\n", lnum, - snod->offs, snod->len); - ubifs_dump_node(c, snod->node); - } - - pr_err("(pid %d) finish dumping LEB %d\n", 0, lnum); - ubifs_scan_destroy(sleb); - -out: - vfree(buf); - return; -} - +/* + * removed in barebox void ubifs_dump_znode(const struct ubifs_info *c, const struct ubifs_znode *znode) -{ - int n; - const struct ubifs_zbranch *zbr; - char key_buf[DBG_KEY_BUF_LEN]; + */ - spin_lock(&dbg_lock); - if (znode->parent) - zbr = &znode->parent->zbranch[znode->iip]; - else - zbr = &c->zroot; - pr_err("znode %p, LEB %d:%d len %d parent %p iip %d level %d child_cnt %d flags %lx\n", - znode, zbr->lnum, zbr->offs, zbr->len, znode->parent, znode->iip, - znode->level, znode->child_cnt, znode->flags); +/* + * removed in barebox +void ubifs_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat) + */ - if (znode->child_cnt <= 0 || znode->child_cnt > c->fanout) { - spin_unlock(&dbg_lock); - return; - } +/* + * removed in barebox +void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, + struct ubifs_nnode *parent, int iip) + */ - pr_err("zbranches:\n"); - for (n = 0; n < znode->child_cnt; n++) { - zbr = &znode->zbranch[n]; - if (znode->level > 0) - pr_err("\t%d: znode %p LEB %d:%d len %d key %s\n", - n, zbr->znode, zbr->lnum, zbr->offs, zbr->len, - dbg_snprintf_key(c, &zbr->key, key_buf, - DBG_KEY_BUF_LEN)); - else - pr_err("\t%d: LNC %p LEB %d:%d len %d key %s\n", - n, zbr->znode, zbr->lnum, zbr->offs, zbr->len, - dbg_snprintf_key(c, &zbr->key, key_buf, - DBG_KEY_BUF_LEN)); - } - spin_unlock(&dbg_lock); -} - +/* + * removed in barebox void ubifs_dump_tnc(struct ubifs_info *c) -{ - struct ubifs_znode *znode; - int level; + */ - pr_err("\n"); - pr_err("(pid %d) start dumping TNC tree\n", 0); - znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); - level = znode->level; - pr_err("== Level %d ==\n", level); - while (znode) { - if (level != znode->level) { - level = znode->level; - pr_err("== Level %d ==\n", level); - } - ubifs_dump_znode(c, znode); - znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode); - } - pr_err("(pid %d) finish dumping TNC tree\n", 0); -} +/* + * removed in barebox static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode, void *priv) -{ - ubifs_dump_znode(c, znode); - return 0; -} - -/** - * ubifs_dump_index - dump the on-flash index. - * @c: UBIFS file-system description object - * - * This function dumps whole UBIFS indexing B-tree, unlike 'ubifs_dump_tnc()' - * which dumps only in-memory znodes and does not read znodes which from flash. */ + +/* + * removed in barebox void ubifs_dump_index(struct ubifs_info *c) -{ - dbg_walk_index(c, NULL, dump_znode, NULL); -} + */ +/* + * removed in barebox +void dbg_save_space_info(struct ubifs_info *c) + */ +/* + * removed in barebox +int dbg_check_space_info(struct ubifs_info *c) + */ + +/* + * removed in barebox +int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode) + */ + +/* + * removed in barebox int dbg_check_dir(struct ubifs_info *c, const struct inode *dir) -{ - return 0; -} + */ -void dbg_debugfs_exit_fs(struct ubifs_info *c) -{ - return; -} +/* + * removed in barebox +static int dbg_check_key_order(struct ubifs_info *c, struct ubifs_zbranch *zbr1, + struct ubifs_zbranch *zbr2) + */ -int ubifs_debugging_init(struct ubifs_info *c) -{ - return 0; -} -void ubifs_debugging_exit(struct ubifs_info *c) -{ -} -int dbg_check_filesystem(struct ubifs_info *c) -{ - return 0; -} -int dbg_debugfs_init_fs(struct ubifs_info *c) -{ - return 0; -} +/* + * removed in barebox +static int dbg_check_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr) + */ int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; } + +/* + * removed in barebox +int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, + dbg_znode_callback znode_cb, void *priv) + */ + +/* + * removed in barebox +static int add_size(struct ubifs_info *c, struct ubifs_znode *znode, void *priv) + */ + +/* + * removed in barebox +int dbg_check_idx_size(struct ubifs_info *c, long long idx_size) + */ + +/* + * removed in barebox +static struct fsck_inode *add_inode(struct ubifs_info *c, + struct fsck_data *fsckd, + struct ubifs_ino_node *ino) + */ + +/* + * removed in barebox +static struct fsck_inode *search_inode(struct fsck_data *fsckd, ino_t inum) + */ + +/* + * removed in barebox +static struct fsck_inode *read_add_inode(struct ubifs_info *c, + struct fsck_data *fsckd, ino_t inum) + */ + +/* + * removed in barebox +static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *priv) + */ + +/* + * removed in barebox +static void free_inodes(struct fsck_data *fsckd) + */ + + +/* + * removed in barebox +static int check_inodes(struct ubifs_info *c, struct fsck_data *fsckd) + */ + +/* + * removed in barebox +int dbg_check_filesystem(struct ubifs_info *c) + */ + +/* + * removed in barebox +int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head) + */ + +/* + * removed in barebox +int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head) + */ + +/* + * removed in barebox +static inline int chance(unsigned int n, unsigned int out_of) + */ + +/* + * removed in barebox +static int power_cut_emulated(struct ubifs_info *c, int lnum, int write) + */ + +/* + * removed in barebox +static int corrupt_data(const struct ubifs_info *c, const void *buf, + unsigned int len) + */ + +/* + * removed in barebox + int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, + int offs, int len) + */ + +/* + * removed in barebox +int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, + int len) + */ + +/* + * removed in barebox +int dbg_leb_unmap(struct ubifs_info *c, int lnum) + */ + +/* + * removed in barebox +int dbg_leb_map(struct ubifs_info *c, int lnum) + */ + +/* + * removed in barebox +static int dfs_file_open(struct inode *inode, struct file *file) + */ + +/* + * removed in barebox +static int provide_user_output(int val, char __user *u, size_t count, + loff_t *ppos) + */ + +/* + * removed in barebox +static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count, + loff_t *ppos) + */ + +/* + * removed in barebox +static int interpret_user_input(const char __user *u, size_t count) + */ + +/* + * removed in barebox +static ssize_t dfs_file_write(struct file *file, const char __user *u, + size_t count, loff_t *ppos) + */ + +/* + * removed in barebox +int dbg_debugfs_init_fs(struct ubifs_info *c) + */ + +/* + * removed in barebox +void dbg_debugfs_exit_fs(struct ubifs_info *c) + */ + +/* + * removed in barebox +static ssize_t dfs_global_file_read(struct file *file, char __user *u, + size_t count, loff_t *ppos) + */ + +/* + * removed in barebox +static ssize_t dfs_global_file_write(struct file *file, const char __user *u, + size_t count, loff_t *ppos) + */ + +/* + * removed in barebox +int dbg_debugfs_init(void) + */ + +/* + * removed in barebox +void dbg_debugfs_exit(void) + */ + +void ubifs_assert_failed(struct ubifs_info *c, const char *expr, + const char *file, int line) +{ + ubifs_err(c, "UBIFS assert failed: %s, in %s:%u", expr, file, line); + + switch (c->assert_action) { + case ASSACT_PANIC: + BUG(); + break; + + case ASSACT_RO: + ubifs_ro_mode(c, -EINVAL); + break; + + case ASSACT_REPORT: + default: + dump_stack(); + break; + + } +} + +/* + * removed in barebox +int ubifs_debugging_init(struct ubifs_info *c) + */ + +/* + * removed in barebox +void ubifs_debugging_exit(struct ubifs_info *c) + */ diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 9afb16d..a1df068 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -137,41 +148,34 @@ unsigned int tst_rcvry:1; }; -#define ubifs_assert(expr) do { \ - if (0 && unlikely(!(expr))) { \ - pr_crit("UBIFS assert failed in %s at %u\n", \ - __func__, __LINE__); \ - dump_stack(); \ +void ubifs_assert_failed(struct ubifs_info *c, const char *expr, + const char *file, int line); + +#define ubifs_assert(c, expr) do { \ + if (unlikely(!(expr))) { \ + ubifs_assert_failed((struct ubifs_info *)c, #expr, __FILE__, \ + __LINE__); \ } \ } while (0) #define ubifs_assert_cmt_locked(c) do { \ if (unlikely(down_write_trylock(&(c)->commit_sem))) { \ up_write(&(c)->commit_sem); \ - pr_crit("commit lock is not locked!\n"); \ - ubifs_assert(0); \ + ubifs_err(c, "commit lock is not locked!\n"); \ + ubifs_assert(c, 0); \ } \ } while (0) #define ubifs_dbg_msg(type, fmt, ...) \ - pr_debug("UBIFS DBG " type ": " fmt "\n", \ - ##__VA_ARGS__) + pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__) #define DBG_KEY_BUF_LEN 48 -#if defined CONFIG_MTD_DEBUG #define ubifs_dbg_msg_key(type, key, fmt, ...) do { \ char __tmp_key_buf[DBG_KEY_BUF_LEN]; \ pr_debug("UBIFS DBG " type ": " fmt "%s\n", \ ##__VA_ARGS__, \ dbg_snprintf_key(c, key, __tmp_key_buf, DBG_KEY_BUF_LEN)); \ } while (0) -#else -#define ubifs_dbg_msg_key(type, key, fmt, ...) do { \ - pr_debug("UBIFS DBG\n"); \ -} while (0) - -#endif - /* General messages */ #define dbg_gen(fmt, ...) ubifs_dbg_msg("gen", fmt, ##__VA_ARGS__) @@ -206,39 +210,47 @@ /* Additional recovery messages */ #define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__) +extern struct ubifs_global_debug_info ubifs_dbg; + static inline int dbg_is_chk_gen(const struct ubifs_info *c) { + /* not present in barebox */ return 0; } static inline int dbg_is_chk_index(const struct ubifs_info *c) { + /* not present in barebox */ return 0; } static inline int dbg_is_chk_orph(const struct ubifs_info *c) { + /* not present in barebox */ return 0; } static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { + /* not present in barebox */ return 0; } static inline int dbg_is_chk_fs(const struct ubifs_info *c) { + /* not present in barebox */ return 0; } static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { + /* not present in barebox */ return 0; } static inline int dbg_is_power_cut(const struct ubifs_info *c) { + /* not present in barebox */ return 0; } 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); diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 8c230da..a16546e 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -42,15 +42,26 @@ #include "ubifs.h" +/* + * removed in barebox +static int inherit_flags(const struct inode *dir, umode_t mode) + */ + +/* + * removed in barebox +struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, + umode_t mode) + */ + static int dbg_check_name(const struct ubifs_info *c, const struct ubifs_dent_node *dent, - const struct qstr *nm) + const struct fscrypt_name *nm) { if (!dbg_is_chk_gen(c)) return 0; - if (le16_to_cpu(dent->nlen) != nm->len) + if (le16_to_cpu(dent->nlen) != fname_len(nm)) return -EINVAL; - if (memcmp(dent->name, nm->name, nm->len)) + if (memcmp(dent->name, fname_name(nm), fname_len(nm))) return -EINVAL; return 0; } @@ -61,32 +72,52 @@ int err; union ubifs_key key; struct inode *inode = NULL; - struct ubifs_dent_node *dent; + struct ubifs_dent_node *dent = NULL; struct ubifs_info *c = dir->i_sb->s_fs_info; + struct fscrypt_name nm; dbg_gen("'%pd' in dir ino %lu", dentry, dir->i_ino); - if (dentry->d_name.len > UBIFS_MAX_NLEN) - return ERR_PTR(-ENAMETOOLONG); + err = fscrypt_prepare_lookup(dir, dentry, flags); + if (err) + return ERR_PTR(err); - dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); - if (!dent) - return ERR_PTR(-ENOMEM); + err = fscrypt_setup_filename(dir, &dentry->d_name, 1, &nm); + if (err) + return ERR_PTR(err); - dent_key_init(c, &key, dir->i_ino, &dentry->d_name); - - err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name); - if (err) { - if (err == -ENOENT) { - dbg_gen("not found"); - goto done; - } - goto out; + if (fname_len(&nm) > UBIFS_MAX_NLEN) { + inode = ERR_PTR(-ENAMETOOLONG); + goto done; } - if (dbg_check_name(c, dent, &dentry->d_name)) { - err = -EINVAL; - goto out; + dent = kmalloc(UBIFS_MAX_DENT_NODE_SZ, GFP_NOFS); + if (!dent) { + inode = ERR_PTR(-ENOMEM); + goto done; + } + + if (nm.hash) { + ubifs_assert(c, fname_len(&nm) == 0); + ubifs_assert(c, fname_name(&nm) == NULL); + dent_key_init_hash(c, &key, dir->i_ino, nm.hash); + err = ubifs_tnc_lookup_dh(c, &key, dent, nm.minor_hash); + } else { + dent_key_init(c, &key, dir->i_ino, &nm); + err = ubifs_tnc_lookup_nm(c, &key, dent, &nm); + } + + if (err) { + if (err == -ENOENT) + dbg_gen("not found"); + else + inode = ERR_PTR(err); + goto done; + } + + if (dbg_check_name(c, dent, &nm)) { + inode = ERR_PTR(-EINVAL); + goto done; } inode = ubifs_iget(dir->i_sb, le64_to_cpu(dent->inum)); @@ -97,25 +128,45 @@ */ err = PTR_ERR(inode); ubifs_err(c, "dead directory entry '%pd', error %d", - dentry, err); + dentry, err); ubifs_ro_mode(c, err); - goto out; + goto done; + } + + if (ubifs_crypt_is_encrypted(dir) && + (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && + !fscrypt_has_permitted_context(dir, inode)) { + ubifs_warn(c, "Inconsistent encryption contexts: %lu/%lu", + dir->i_ino, inode->i_ino); + iput(inode); + inode = ERR_PTR(-EPERM); } done: kfree(dent); - /* - * Note, d_splice_alias() would be required instead if we supported - * NFS. - */ + fscrypt_free_filename(&nm); d_add(dentry, inode); return NULL; - -out: - kfree(dent); - return ERR_PTR(err); } +/* + * removed in barebox +static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode, + bool excl) + */ + +/* + * removed in barebox +static int do_tmpfile(struct inode *dir, struct dentry *dentry, + umode_t mode, struct inode **whiteout) + */ + +/* + * removed in barebox +static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry, + umode_t mode) + */ + /** * vfs_dent_type - get VFS directory entry type. * @type: UBIFS directory entry type @@ -165,13 +216,14 @@ */ static int ubifs_readdir(struct file *file, struct dir_context *ctx) { - int err = 0; - struct qstr nm; + int fstr_real_len = 0, err = 0; + struct fscrypt_name nm; + struct fscrypt_str fstr = {0}; union ubifs_key key; struct ubifs_dent_node *dent; - struct dentry *dentry = file->f_path.dentry; - struct inode *dir = d_inode(dentry); + struct inode *dir = file_inode(file); struct ubifs_info *c = dir->i_sb->s_fs_info; + bool encrypted = ubifs_crypt_is_encrypted(dir); dbg_gen("dir ino %lu, f_pos %#llx", dir->i_ino, ctx->pos); @@ -182,6 +234,18 @@ */ return 0; + if (encrypted) { + err = fscrypt_get_encryption_info(dir); + if (err && err != -ENOKEY) + return err; + + err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, &fstr); + if (err) + return err; + + fstr_real_len = fstr.len; + } + if (file->f_version == 0) { /* * The file was seek'ed, which means that @file->private_data @@ -202,12 +266,16 @@ /* File positions 0 and 1 correspond to "." and ".." */ if (ctx->pos < 2) { - ubifs_assert(!file->private_data); - dir_emit_dots(file, ctx); + ubifs_assert(c, !file->private_data); + if (!dir_emit_dots(file, ctx)) { + if (encrypted) + fscrypt_fname_free_buffer(&fstr); + return 0; + } /* Find the first entry in TNC and save it */ lowest_dent_key(c, &key, dir->i_ino); - nm.name = NULL; + fname_len(&nm) = 0; dent = ubifs_tnc_next_ent(c, &key, &nm); if (IS_ERR(dent)) { err = PTR_ERR(dent); @@ -225,7 +293,7 @@ * Find the entry corresponding to @ctx->pos or the closest one. */ dent_key_init_hash(c, &key, dir->i_ino, ctx->pos); - nm.name = NULL; + fname_len(&nm) = 0; dent = ubifs_tnc_next_ent(c, &key, &nm); if (IS_ERR(dent)) { err = PTR_ERR(dent); @@ -236,20 +304,39 @@ } while (1) { - dbg_gen("feed '%s', ino %llu, new f_pos %#x", - dent->name, (unsigned long long)le64_to_cpu(dent->inum), + dbg_gen("ino %llu, new f_pos %#x", + (unsigned long long)le64_to_cpu(dent->inum), key_hash_flash(c, &dent->key)); - ubifs_assert(le64_to_cpu(dent->ch.sqnum) > + ubifs_assert(c, le64_to_cpu(dent->ch.sqnum) > ubifs_inode(dir)->creat_sqnum); - nm.len = le16_to_cpu(dent->nlen); - dir_emit(ctx, dent->name, nm.len, + fname_len(&nm) = le16_to_cpu(dent->nlen); + fname_name(&nm) = dent->name; + + if (encrypted) { + fstr.len = fstr_real_len; + + err = fscrypt_fname_disk_to_usr(dir, key_hash_flash(c, + &dent->key), + le32_to_cpu(dent->cookie), + &nm.disk_name, &fstr); + if (err) + goto out; + } else { + fstr.len = fname_len(&nm); + fstr.name = fname_name(&nm); + } + + if (!dir_emit(ctx, fstr.name, fstr.len, le64_to_cpu(dent->inum), - vfs_dent_type(dent->type)); + vfs_dent_type(dent->type))) { + if (encrypted) + fscrypt_fname_free_buffer(&fstr); + return 0; + } /* Switch to the next entry */ key_read(c, &dent->key, &key); - nm.name = dent->name; dent = ubifs_tnc_next_ent(c, &key, &nm); if (IS_ERR(dent)) { err = PTR_ERR(dent); @@ -266,6 +353,9 @@ kfree(file->private_data); file->private_data = NULL; + if (encrypted) + fscrypt_fname_free_buffer(&fstr); + if (err != -ENOENT) ubifs_err(c, "cannot find next direntry, error %d", err); else @@ -282,10 +372,132 @@ return err; } +/* + * removed in barebox +static int ubifs_dir_release(struct inode *dir, struct file *file) + */ + +/* + * removed in barebox +static void lock_2_inodes(struct inode *inode1, struct inode *inode2) + */ + +/* + * removed in barebox +static void unlock_2_inodes(struct inode *inode1, struct inode *inode2) + */ + +/* + * removed in barebox +static int ubifs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *dentry) + */ + +/* + * removed in barebox +static int ubifs_unlink(struct inode *dir, struct dentry *dentry) + */ + +/* + * removed in barebox +int ubifs_check_dir_empty(struct inode *dir) + */ + +/* + * removed in barebox +static int ubifs_rmdir(struct inode *dir, struct dentry *dentry) + */ + +/* + * removed in barebox +static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) + */ + +/* + * removed in barebox +static int ubifs_mknod(struct inode *dir, struct dentry *dentry, + umode_t mode, dev_t rdev) + */ + +/* + * removed in barebox +static int ubifs_symlink(struct inode *dir, struct dentry *dentry, + const char *symname) + */ + +/* + * removed in barebox +static void lock_4_inodes(struct inode *inode1, struct inode *inode2, + struct inode *inode3, struct inode *inode4) + */ + +/* + * removed in barebox +static void unlock_4_inodes(struct inode *inode1, struct inode *inode2, + struct inode *inode3, struct inode *inode4) + */ + +/* + * removed in barebox +static int do_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) + */ + +/* + * removed in barebox +static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) + */ + +/* + * removed in barebox +static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) + */ + +/* + * removed in barebox +int ubifs_getattr(const struct path *path, struct kstat *stat, + u32 request_mask, unsigned int flags) + */ + +/* + * removed in barebox +static int ubifs_dir_open(struct inode *dir, struct file *file) + */ + const struct inode_operations ubifs_dir_inode_operations = { .lookup = ubifs_lookup, + .create = NULL, /* not present in barebox */ + .link = NULL, /* not present in barebox */ + .symlink = NULL, /* not present in barebox */ + .unlink = NULL, /* not present in barebox */ + .mkdir = NULL, /* not present in barebox */ + .rmdir = NULL, /* not present in barebox */ +/* .mknod = NULL, not present in barebox */ + .rename = NULL, /* not present in barebox */ +/* .setattr = NULL, not present in barebox */ +/* .getattr = NULL, not present in barebox */ +#ifdef CONFIG_UBIFS_FS_XATTR + .listxattr = NULL, /* not present in barebox */ +#endif +#ifdef CONFIG_UBIFS_ATIME_SUPPORT + .update_time = NULL, /* not present in barebox */ +#endif +/* .tmpfile = NULL, not present in barebox */ }; const struct file_operations ubifs_dir_operations = { - .iterate = ubifs_readdir, +/* .llseek = NULL, not present in barebox */ +/* .release = NULL, not present in barebox */ + .read = NULL, /* not present in barebox */ + .iterate = ubifs_readdir, +/* .fsync = NULL, not present in barebox */ +/* .unlocked_ioctl = NULL, not present in barebox */ +/* .open = NULL, not present in barebox */ +#ifdef CONFIG_COMPAT + .compat_ioctl = NULL, /* not present in barebox */ +#endif }; diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 08d4e20..0d5fd58 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c @@ -4,7 +4,18 @@ * Copyright (C) 2006-2008 Nokia Corporation. * Copyright (C) 2006, 2007 University of Szeged, Hungary * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -72,7 +83,7 @@ if (!c->ro_error) { c->ro_error = 1; c->no_chk_data_crc = 0; - c->vfs_sb->s_flags |= MS_RDONLY; + c->vfs_sb->s_flags |= SB_RDONLY; ubifs_warn(c, "switched to read-only mode, error %d", err); dump_stack(); } @@ -102,6 +113,27 @@ return err; } +/* + * removed in barebox +int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, + int len) + */ + +/* + * removed in barebox +int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len) + */ + +/* + * removed in barebox +int ubifs_leb_unmap(struct ubifs_info *c, int lnum) + */ + +/* + * removed in barebox +int ubifs_leb_map(struct ubifs_info *c, int lnum) + */ + int ubifs_is_mapped(const struct ubifs_info *c, int lnum) { int err; @@ -150,8 +182,8 @@ uint32_t crc, node_crc, magic; const struct ubifs_ch *ch = buf; - ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); - ubifs_assert(!(offs & 7) && offs < c->leb_size); + ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0); + ubifs_assert(c, !(offs & 7) && offs < c->leb_size); magic = le32_to_cpu(ch->magic); if (magic != UBIFS_NODE_MAGIC) { @@ -228,7 +260,7 @@ { uint32_t crc; - ubifs_assert(pad >= 0 && !(pad & 7)); + ubifs_assert(c, pad >= 0 && !(pad & 7)); if (pad >= UBIFS_PAD_NODE_SZ) { struct ubifs_ch *ch = buf; @@ -250,6 +282,68 @@ memset(buf, UBIFS_PADDING_BYTE, pad); } +/* + * removed in barebox +static unsigned long long next_sqnum(struct ubifs_info *c) + */ + +/* + * removed in barebox +void ubifs_prepare_node(struct ubifs_info *c, void *node, int len, int pad) + */ + +/* + * removed in barebox +void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last) + */ + +/* + * removed in barebox +static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer) + */ + +/* + * removed in barebox +static void new_wbuf_timer_nolock(struct ubifs_info *c, struct ubifs_wbuf *wbuf) + */ + +/* + * removed in barebox +static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) + */ + +/* + * removed in barebox +int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) + */ + +/* + * removed in barebox +int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs) + */ + +/* + * removed in barebox +int ubifs_bg_wbufs_sync(struct ubifs_info *c) + */ + +/* + * removed in barebox +int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) + */ + +/* + * removed in barebox +int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, + int offs) + */ + +/* + * removed in barebox +int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, + int lnum, int offs) + */ + /** * ubifs_read_node - read node. * @c: UBIFS file-system description object @@ -270,10 +364,10 @@ struct ubifs_ch *ch = buf; dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); - ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); - ubifs_assert(len >= UBIFS_CH_SZ && offs + len <= c->leb_size); - ubifs_assert(!(offs & 7) && offs < c->leb_size); - ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); + ubifs_assert(c, lnum >= 0 && lnum < c->leb_cnt && offs >= 0); + ubifs_assert(c, len >= UBIFS_CH_SZ && offs + len <= c->leb_size); + ubifs_assert(c, !(offs & 7) && offs < c->leb_size); + ubifs_assert(c, type >= 0 && type < UBIFS_NODE_TYPES_CNT); err = ubifs_leb_read(c, lnum, buf, offs, len, 0); if (err && err != -EBADMSG) @@ -349,5 +443,22 @@ wbuf->c = c; wbuf->next_ino = 0; + /* hrtimer not needed in barebox */ + return 0; } + +/* + * removed in barebox +void ubifs_wbuf_add_ino_nolock(struct ubifs_wbuf *wbuf, ino_t inum) + */ + +/* + * removed in barebox +static int wbuf_has_ino(struct ubifs_wbuf *wbuf, ino_t inum) + */ + +/* + * removed in barebox +int ubifs_sync_wbufs_by_inode(struct ubifs_info *c, struct inode *inode) + */ diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h index b5c4884..2feff6c 100644 --- a/fs/ubifs/key.h +++ b/fs/ubifs/key.h @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -23,6 +34,12 @@ * node. We use "r5" hash borrowed from reiserfs. */ +/* + * Lot's of the key helpers require a struct ubifs_info *c as the first parameter. + * But we are not using it at all currently. That's designed for future extensions of + * different c->key_format. But right now, there is only one key type, UBIFS_SIMPLE_KEY_FMT. + */ + #ifndef __UBIFS_KEY_H__ #define __UBIFS_KEY_H__ @@ -52,7 +69,7 @@ uint32_t a = 0; const signed char *str = (const signed char *)s; - while (*str) { + while (len--) { a += *str << 4; a += *str >> 4; a *= 11; @@ -136,15 +153,16 @@ * @c: UBIFS file-system description object * @key: key to initialize * @inum: parent inode number - * @nm: direntry name and length + * @nm: direntry name and length. Not a string when encrypted! */ static inline void dent_key_init(const struct ubifs_info *c, union ubifs_key *key, ino_t inum, - const struct qstr *nm) + const struct fscrypt_name *nm) { - uint32_t hash = c->key_hash(nm->name, nm->len); + uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); - ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); + ubifs_assert(c, !nm->hash && !nm->minor_hash); key->u32[0] = inum; key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); } @@ -161,7 +179,7 @@ union ubifs_key *key, ino_t inum, uint32_t hash) { - ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); key->u32[0] = inum; key->u32[1] = hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS); } @@ -174,12 +192,13 @@ * @nm: direntry name and length */ static inline void dent_key_init_flash(const struct ubifs_info *c, void *k, - ino_t inum, const struct qstr *nm) + ino_t inum, + const struct fscrypt_name *nm) { union ubifs_key *key = k; - uint32_t hash = c->key_hash(nm->name, nm->len); + uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); - ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); key->j32[0] = cpu_to_le32(inum); key->j32[1] = cpu_to_le32(hash | (UBIFS_DENT_KEY << UBIFS_S_KEY_HASH_BITS)); @@ -208,11 +227,11 @@ */ static inline void xent_key_init(const struct ubifs_info *c, union ubifs_key *key, ino_t inum, - const struct qstr *nm) + const struct fscrypt_name *nm) { - uint32_t hash = c->key_hash(nm->name, nm->len); + uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); - ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); key->u32[0] = inum; key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS); } @@ -225,12 +244,12 @@ * @nm: extended attribute entry name and length */ static inline void xent_key_init_flash(const struct ubifs_info *c, void *k, - ino_t inum, const struct qstr *nm) + ino_t inum, const struct fscrypt_name *nm) { union ubifs_key *key = k; - uint32_t hash = c->key_hash(nm->name, nm->len); + uint32_t hash = c->key_hash(fname_name(nm), fname_len(nm)); - ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK)); + ubifs_assert(c, !(hash & ~UBIFS_S_KEY_HASH_MASK)); key->j32[0] = cpu_to_le32(inum); key->j32[1] = cpu_to_le32(hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS)); @@ -261,7 +280,7 @@ union ubifs_key *key, ino_t inum, unsigned int block) { - ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK)); + ubifs_assert(c, !(block & ~UBIFS_S_KEY_BLOCK_MASK)); key->u32[0] = inum; key->u32[1] = block | (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS); } diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c index db83f56..7a12cfd 100644 --- a/fs/ubifs/log.c +++ b/fs/ubifs/log.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -16,9 +27,6 @@ * journal. */ -#ifdef __UBOOT__ -#include -#endif #include "ubifs.h" /** @@ -51,6 +59,16 @@ return NULL; } +/* + * removed in barebox +struct ubifs_wbuf *ubifs_get_wbuf(struct ubifs_info *c, int lnum) + */ + +/* + * removed in barebox +static inline long long empty_log_bytes(const struct ubifs_info *c) + */ + /** * ubifs_add_bud - add bud LEB to the tree of buds and its journal head list. * @c: UBIFS file-system description object @@ -67,7 +85,7 @@ while (*p) { parent = *p; b = rb_entry(parent, struct ubifs_bud, rb); - ubifs_assert(bud->lnum != b->lnum); + ubifs_assert(c, bud->lnum != b->lnum); if (bud->lnum < b->lnum) p = &(*p)->rb_left; else @@ -80,7 +98,7 @@ jhead = &c->jheads[bud->jhead]; list_add_tail(&bud->list, &jhead->buds_list); } else - ubifs_assert(c->replaying && c->ro_mount); + ubifs_assert(c, c->replaying && c->ro_mount); /* * Note, although this is a new bud, we anyway account this space now, @@ -94,3 +112,54 @@ bud->start, dbg_jhead(bud->jhead), c->bud_bytes); spin_unlock(&c->buds_lock); } + +/* + * removed in barebox +int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) + */ + +/* + * removed in barebox +static void remove_buds(struct ubifs_info *c) + */ + +/* + * removed in barebox +int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) + */ + +/* + * removed in barebox +int ubifs_log_end_commit(struct ubifs_info *c, int ltail_lnum) + */ + +/* + * removed in barebox +int ubifs_log_post_commit(struct ubifs_info *c, int old_ltail_lnum) + */ + +/* + * removed in barebox +static int done_already(struct rb_root *done_tree, int lnum) + */ + +/* + * removed in barebox +static void destroy_done_tree(struct rb_root *done_tree) + */ + +/* + * removed in barebox +static int add_node(struct ubifs_info *c, void *buf, int *lnum, int *offs, + void *node) + */ + +/* + * removed in barebox +int ubifs_consolidate_log(struct ubifs_info *c) + */ + +/* + * removed in barebox +static int dbg_check_bud_bytes(struct ubifs_info *c) + */ diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c index 7e7d645..d4fb901 100644 --- a/fs/ubifs/lpt_commit.c +++ b/fs/ubifs/lpt_commit.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Adrian Hunter * Artem Bityutskiy (Битюцкий Артём) @@ -17,3 +28,259 @@ #include #include "crc16.h" #include "ubifs.h" + +/* + * removed in barebox +static struct ubifs_cnode *first_dirty_cnode(const struct ubifs_info *c, struct ubifs_nnode *nnode) + */ + +/* + * removed in barebox +static struct ubifs_cnode *next_dirty_cnode(const struct ubifs_info *c, struct ubifs_cnode *cnode) + */ + +/* + * removed in barebox +static int get_cnodes_to_commit(struct ubifs_info *c) + */ + +/* + * removed in barebox +static void upd_ltab(struct ubifs_info *c, int lnum, int free, int dirty) + */ + +/* + * removed in barebox +static int alloc_lpt_leb(struct ubifs_info *c, int *lnum) + */ + +/* + * removed in barebox +static int layout_cnodes(struct ubifs_info *c) + */ + +/* + * removed in barebox +static int realloc_lpt_leb(struct ubifs_info *c, int *lnum) + */ + +/* + * removed in barebox +static int write_cnodes(struct ubifs_info *c) + */ + +/* + * removed in barebox +static struct ubifs_pnode *next_pnode_to_dirty(struct ubifs_info *c, + struct ubifs_pnode *pnode) + */ + +/* + * removed in barebox +static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i) + */ + +/* + * removed in barebox +static void add_pnode_dirt(struct ubifs_info *c, struct ubifs_pnode *pnode) + */ + +/* + * removed in barebox +static void do_make_pnode_dirty(struct ubifs_info *c, struct ubifs_pnode *pnode) + */ + +/* + * removed in barebox +static int make_tree_dirty(struct ubifs_info *c) + */ + +/* + * removed in barebox +static int need_write_all(struct ubifs_info *c) + */ + +/* + * removed in barebox +static void lpt_tgc_start(struct ubifs_info *c) + */ + +/* + * removed in barebox +static int lpt_tgc_end(struct ubifs_info *c) + */ + +/* + * removed in barebox +static void populate_lsave(struct ubifs_info *c) + */ + +/* + * removed in barebox +static struct ubifs_nnode *nnode_lookup(struct ubifs_info *c, int i) + */ + +/* + * removed in barebox +static int make_nnode_dirty(struct ubifs_info *c, int node_num, int lnum, + int offs) + */ + +/* + * removed in barebox +static int make_pnode_dirty(struct ubifs_info *c, int node_num, int lnum, + int offs) + */ + +/* + * removed in barebox +static int make_ltab_dirty(struct ubifs_info *c, int lnum, int offs) + */ + +/* + * removed in barebox +static int make_lsave_dirty(struct ubifs_info *c, int lnum, int offs) + */ + +/* + * removed in barebox +static int make_node_dirty(struct ubifs_info *c, int node_type, int node_num, + int lnum, int offs) + */ + +/* + * removed in barebox +static int get_lpt_node_len(const struct ubifs_info *c, int node_type) + */ + +/* + * removed in barebox +static int get_pad_len(const struct ubifs_info *c, uint8_t *buf, int len) + */ + +/* + * removed in barebox +static int get_lpt_node_type(const struct ubifs_info *c, uint8_t *buf, + int *node_num) + */ + +/* + * removed in barebox +static int is_a_node(const struct ubifs_info *c, uint8_t *buf, int len) + */ + +/* + * removed in barebox +static int lpt_gc_lnum(struct ubifs_info *c, int lnum) + */ + +/* + * removed in barebox +static int lpt_gc(struct ubifs_info *c) + */ + +/* + * removed in barebox +int ubifs_lpt_start_commit(struct ubifs_info *c) + */ + +/* + * removed in barebox +static void free_obsolete_cnodes(struct ubifs_info *c) + */ + +/* + * removed in barebox +int ubifs_lpt_end_commit(struct ubifs_info *c) + */ + +/* + * removed in barebox +int ubifs_lpt_post_commit(struct ubifs_info *c) + */ + +/* + * removed in barebox +static struct ubifs_nnode *first_nnode(struct ubifs_info *c, int *hght) + */ + +/* + * removed in barebox +static struct ubifs_nnode *next_nnode(struct ubifs_info *c, + struct ubifs_nnode *nnode, int *hght) + */ + +/* + * removed in barebox +void ubifs_lpt_free(struct ubifs_info *c, int wr_only) + */ + +/* + * Everything below is related to debugging. + */ + +/* + * removed in barebox +static int dbg_is_all_ff(uint8_t *buf, int len) + */ + +/* + * removed in barebox +static int dbg_is_nnode_dirty(struct ubifs_info *c, int lnum, int offs) + */ + +/* + * removed in barebox +static int dbg_is_pnode_dirty(struct ubifs_info *c, int lnum, int offs) + */ + +/* + * removed in barebox +static int dbg_is_ltab_dirty(struct ubifs_info *c, int lnum, int offs) + */ + +/* + * removed in barebox +static int dbg_is_lsave_dirty(struct ubifs_info *c, int lnum, int offs) + */ + +/* + * removed in barebox +static int dbg_is_node_dirty(struct ubifs_info *c, int node_type, int lnum, + int offs) +*/ + +/* + * removed in barebox +static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum) + */ + +/* + * removed in barebox +int dbg_check_ltab(struct ubifs_info *c) + */ + +/* + * removed in barebox +int dbg_chk_lpt_free_spc(struct ubifs_info *c) + */ + +/* + * removed in barebox +int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len) + */ + +/* + * removed in barebox +static void dump_lpt_leb(const struct ubifs_info *c, int lnum) + */ + +/* + * removed in barebox +void ubifs_dump_lpt_lebs(const struct ubifs_info *c) + */ + +/* + * removed in barebox +static int dbg_populate_lsave(struct ubifs_info *c) + */ diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c index 3bf37c2..40b49b6 100644 --- a/fs/ubifs/master.c +++ b/fs/ubifs/master.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -12,7 +23,6 @@ /* This file implements reading and writing the master node */ #include "ubifs.h" -#include /** * scan_for_master - search the valid master node. @@ -333,7 +343,10 @@ if (err) return err; - return err; } +/* + * removed in barebox +int ubifs_write_master(struct ubifs_info *c) + */ diff --git a/fs/ubifs/misc.c b/fs/ubifs/misc.c new file mode 100644 index 0000000..51afb3d --- /dev/null +++ b/fs/ubifs/misc.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "ubifs.h" + +/* Normal UBIFS messages */ +void ubifs_msg(const struct ubifs_info *c, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_notice("UBIFS (ubi%d:%d): %pV\n", + c->vi.ubi_num, c->vi.vol_id, &vaf); + + va_end(args); +} \ + +/* UBIFS error messages */ +void ubifs_err(const struct ubifs_info *c, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_err("UBIFS error (ubi%d:%d): %ps: %pV\n", + c->vi.ubi_num, c->vi.vol_id, + __builtin_return_address(0), + &vaf); + + va_end(args); +} \ + +/* UBIFS warning messages */ +void ubifs_warn(const struct ubifs_info *c, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_warn("UBIFS warning (ubi%d:%d): %ps: %pV\n", + c->vi.ubi_num, c->vi.vol_id, + __builtin_return_address(0), + &vaf); + + va_end(args); +} + +static char *assert_names[] = { + [ASSACT_REPORT] = "report", + [ASSACT_RO] = "read-only", + [ASSACT_PANIC] = "panic", +}; + +const char *ubifs_assert_action_name(struct ubifs_info *c) +{ + return assert_names[c->assert_action]; +} diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h index 4822dd3..77429be 100644 --- a/fs/ubifs/misc.h +++ b/fs/ubifs/misc.h @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -94,25 +105,27 @@ /** * ubifs_compr_present - check if compressor was compiled in. * @compr_type: compressor type to check + * @c: the UBIFS file-system description object * * This function returns %1 of compressor of type @compr_type is present, and * %0 if not. */ -static inline int ubifs_compr_present(int compr_type) +static inline int ubifs_compr_present(struct ubifs_info *c, int compr_type) { - ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); + ubifs_assert(c, compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); return !!ubifs_compressors[compr_type]->capi_name; } /** * ubifs_compr_name - get compressor name string by its type. * @compr_type: compressor type + * @c: the UBIFS file-system description object * * This function returns compressor type string. */ -static inline const char *ubifs_compr_name(int compr_type) +static inline const char *ubifs_compr_name(struct ubifs_info *c, int compr_type) { - ubifs_assert(compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); + ubifs_assert(c, compr_type >= 0 && compr_type < UBIFS_COMPR_TYPES_CNT); return ubifs_compressors[compr_type]->name; } @@ -133,6 +146,10 @@ return err; } +/* + * removed in barebox +static inline int ubifs_encode_dev(union ubifs_dev_desc *dev, dev_t rdev) + */ /** * ubifs_add_dirt - add dirty space to LEB properties. @@ -145,6 +162,7 @@ */ static inline int ubifs_add_dirt(struct ubifs_info *c, int lnum, int dirty) { + /* removed in barebox */ return 0; } @@ -159,6 +177,7 @@ */ static inline int ubifs_return_leb(struct ubifs_info *c, int lnum) { + /* removed in barebox */ return 0; } @@ -195,13 +214,9 @@ static inline void *ubifs_idx_key(const struct ubifs_info *c, const struct ubifs_idx_node *idx) { - struct ubifs_branch *tmp; - - tmp = (struct ubifs_branch *)idx->branches; - return (void *)tmp->key; + return (void *)((struct ubifs_branch *)idx->branches)->key; } - /** * ubifs_tnc_lookup - look up a file-system node. * @c: UBIFS file-system description object @@ -240,8 +255,8 @@ */ static inline void ubifs_release_lprops(struct ubifs_info *c) { - ubifs_assert(mutex_is_locked(&c->lp_mutex)); - ubifs_assert(c->lst.empty_lebs >= 0 && + ubifs_assert(c, mutex_is_locked(&c->lp_mutex)); + ubifs_assert(c, c->lst.empty_lebs >= 0 && c->lst.empty_lebs <= c->main_lebs); mutex_unlock(&c->lp_mutex); } @@ -263,4 +278,6 @@ return lnum; } +const char *ubifs_assert_action_name(struct ubifs_info *c); + #endif /* __UBIFS_MISC_H__ */ diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 5b3902b..fac83f8 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Adrian Hunter * Artem Bityutskiy (Битюцкий Артём) @@ -182,6 +193,12 @@ return err; } +/* + * removed in barebox +static int write_rcvrd_mst_node(struct ubifs_info *c, + struct ubifs_mst_node *mst) + */ + /** * ubifs_recover_master_node - recover the master node. * @c: UBIFS file-system description object @@ -302,6 +319,9 @@ * dirty. */ c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY); + } else { + /* Write the recovered master node */ + /* not done in barebox */ } vfree(buf2); @@ -326,6 +346,11 @@ return err; } +/* + * removed in barebox +int ubifs_write_rcvrd_mst_node(struct ubifs_info *c) + */ + /** * is_last_write - determine if an offset was in the last write to a LEB. * @c: UBIFS file-system description object @@ -369,10 +394,9 @@ { int empty_offs, pad_len; - lnum = lnum; dbg_rcvry("cleaning corruption at %d:%d", lnum, *offs); - ubifs_assert(!(*offs & 7)); + ubifs_assert(c, !(*offs & 7)); empty_offs = ALIGN(*offs, c->min_io_size); pad_len = empty_offs - *offs; ubifs_pad(c, *buf, pad_len); @@ -453,6 +477,9 @@ ucleb->lnum = lnum; ucleb->endpt = endpt; list_add_tail(&ucleb->list, &c->unclean_leb_list); + } else { + /* Write the fixed LEB back to flash */ + /* not done in barebox */ } return 0; } @@ -539,7 +566,7 @@ if (IS_ERR(sleb)) return sleb; - ubifs_assert(len >= 8); + ubifs_assert(c, len >= 8); while (len >= 8) { dbg_scan("look at LEB %d:%d (%d bytes left)", lnum, offs, len); @@ -683,7 +710,7 @@ corrupted_rescan: /* Re-scan the corrupted data with verbose messages */ ubifs_err(c, "corruption %d", ret); - ubifs_scan_a_node(c, buf, len, lnum, offs, 1); + ubifs_scan_a_node(c, buf, len, lnum, offs, 0); corrupted: ubifs_scanned_corruption(c, lnum, offs, buf); err = -EUCLEAN; @@ -804,10 +831,36 @@ return ubifs_recover_leb(c, lnum, offs, sbuf, -1); } +/* + * removed in barebox +static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf) + */ + +/* + * removed in barebox +int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf) + */ + +/* + * removed in barebox +static int clean_an_unclean_leb(struct ubifs_info *c, + struct ubifs_unclean_leb *ucleb, void *sbuf) + */ + +/* + * removed in barebox +int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf) + */ + +/* + * removed in barebox +static int grab_empty_leb(struct ubifs_info *c) + */ + +/* + * removed in barebox int ubifs_rcvry_gc_commit(struct ubifs_info *c) -{ - return 0; -} + */ /** * struct size_entry - inode size information for recovery. @@ -911,8 +964,7 @@ struct size_entry *e, *n; rbtree_postorder_for_each_entry_safe(e, n, &c->size_tree, rb) { - if (e->inode) - iput(e->inode); + iput(e->inode); kfree(e); } @@ -987,6 +1039,10 @@ return 0; } +/* + * removed in barebox +static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e) + */ /** * ubifs_recover_size - recover inode size. @@ -1034,7 +1090,7 @@ struct inode *inode; struct ubifs_inode *ui; - ubifs_assert(!e->inode); + ubifs_assert(c, !e->inode); inode = ubifs_iget(c->vfs_sb, e->inum); if (IS_ERR(inode)) @@ -1053,6 +1109,9 @@ continue; } iput(inode); + } else { + /* Fix the size in place */ + /* Not done in barebox */ } } diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 19d0bf1..9eb24b0 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Adrian Hunter * Artem Bityutskiy (Битюцкий Артём) @@ -21,9 +32,7 @@ * larger is the journal, the more memory its index may consume. */ -#include #include "ubifs.h" -#include #include /** @@ -52,7 +61,7 @@ struct list_head list; union ubifs_key key; union { - struct qstr nm; + struct fscrypt_name nm; struct { loff_t old_size; loff_t new_size; @@ -76,6 +85,16 @@ int dirty; }; +/* + * removed in barebox +static int set_bud_lprops(struct ubifs_info *c, struct bud_entry *b) + */ + +/* + * removed in barebox +static int set_buds_lprops(struct ubifs_info *c) + */ + /** * trun_remove_range - apply a replay entry for a truncation to the TNC. * @c: UBIFS file-system description object @@ -117,9 +136,6 @@ dbg_mntk(&r->key, "LEB %d:%d len %d deletion %d sqnum %llu key ", r->lnum, r->offs, r->len, r->deletion, r->sqnum); - /* Set c->replay_sqnum to help deal with dangling branches. */ - c->replay_sqnum = r->sqnum; - if (is_hash_key(c, &r->key)) { if (r->deletion) err = ubifs_tnc_remove_nm(c, &r->key, &r->nm); @@ -161,7 +177,7 @@ * replay_entries_cmp - compare 2 replay entries. * @priv: UBIFS file-system description object * @a: first replay entry - * @a: second replay entry + * @b: second replay entry * * This is a comparios function for 'list_sort()' which compares 2 replay * entries @a and @b by comparing their sequence numer. Returns %1 if @a has @@ -170,6 +186,7 @@ static int replay_entries_cmp(void *priv, struct list_head *a, struct list_head *b) { + struct ubifs_info *c = priv; struct replay_entry *ra, *rb; cond_resched(); @@ -178,7 +195,7 @@ ra = list_entry(a, struct replay_entry, list); rb = list_entry(b, struct replay_entry, list); - ubifs_assert(ra->sqnum != rb->sqnum); + ubifs_assert(c, ra->sqnum != rb->sqnum); if (ra->sqnum > rb->sqnum) return 1; return -1; @@ -221,7 +238,7 @@ list_for_each_entry_safe(r, tmp, &c->replay_list, list) { if (is_hash_key(c, &r->key)) - kfree(r->nm.name); + kfree(fname_name(&r->nm)); list_del(&r->list); kfree(r); } @@ -324,10 +341,10 @@ r->deletion = !!deletion; r->sqnum = sqnum; key_copy(c, key, &r->key); - r->nm.len = nlen; + fname_len(&r->nm) = nlen; memcpy(nbuf, name, nlen); nbuf[nlen] = '\0'; - r->nm.name = nbuf; + fname_name(&r->nm) = nbuf; list_add_tail(&r->list, &c->replay_list); return 0; @@ -350,7 +367,7 @@ if (le32_to_cpu(dent->ch.len) != nlen + UBIFS_DENT_NODE_SZ + 1 || dent->type >= UBIFS_ITYPES_CNT || nlen > UBIFS_MAX_NLEN || dent->name[nlen] != 0 || - strnlen(dent->name, nlen) != nlen || + (key_type == UBIFS_XENT_KEY && strnlen(dent->name, nlen) != nlen) || le64_to_cpu(dent->inum) > MAX_INUM) { ubifs_err(c, "bad %s node", key_type == UBIFS_DENT_KEY ? "directory entry" : "extended attribute entry"); @@ -565,9 +582,9 @@ goto out; } - ubifs_assert(ubifs_search_bud(c, lnum)); - ubifs_assert(sleb->endpt - offs >= used); - ubifs_assert(sleb->endpt % c->min_io_size == 0); + ubifs_assert(c, ubifs_search_bud(c, lnum)); + ubifs_assert(c, sleb->endpt - offs >= used); + ubifs_assert(c, sleb->endpt % c->min_io_size == 0); b->dirty = sleb->endpt - offs - used; b->free = c->leb_size - sleb->endpt; @@ -603,7 +620,7 @@ if (err) return err; - ubifs_assert(b->sqnum > prev_sqnum); + ubifs_assert(c, b->sqnum > prev_sqnum); prev_sqnum = b->sqnum; } @@ -856,6 +873,11 @@ return -EINVAL; } +/* + * removed in barebox +static int take_ihead(struct ubifs_info *c) + */ + /** * ubifs_replay_journal - replay journal. * @c: UBIFS file-system description object @@ -870,6 +892,9 @@ BUILD_BUG_ON(UBIFS_TRUN_KEY > 5); + /* Update the status of the index head in lprops to 'taken' */ + /* Not done in barebox */ + dbg_mnt("start replaying the journal"); c->replaying = 1; lnum = c->ltail_lnum = c->lhead_lnum; @@ -885,7 +910,7 @@ * The head of the log must always start with the * "commit start" node on a properly formatted UBIFS. * But we found no nodes at all, which means that - * someting went wrong and we cannot proceed mounting + * something went wrong and we cannot proceed mounting * the file-system. */ ubifs_err(c, "no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted", @@ -905,6 +930,8 @@ if (err) goto out; + /* set_buds_lprops Not done in barebox */ + /* * UBIFS budgeting calculations use @c->bi.uncommitted_idx variable * to roughly estimate index growth. Things like @c->bi.min_idx_lebs @@ -914,7 +941,7 @@ c->bi.uncommitted_idx = atomic_long_read(&c->dirty_zn_cnt); c->bi.uncommitted_idx *= c->max_idx_node_sz; - ubifs_assert(c->bud_bytes <= c->max_bud_bytes || c->need_recovery); + ubifs_assert(c, c->bud_bytes <= c->max_bud_bytes || c->need_recovery); dbg_mnt("finished, log head LEB %d:%d, max_sqnum %llu, highest_inum %lu", c->lhead_lnum, c->lhead_offs, c->max_sqnum, (unsigned long)c->highest_inum); diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index f7051c9..48bfb24 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -52,6 +63,10 @@ /* Default time granularity in nanoseconds */ #define DEFAULT_TIME_GRAN 1000000000 +/* + * removed in barebox +static int create_default_filesystem(struct ubifs_info *c) + */ /** * validate_sb - validate superblock node. @@ -179,6 +194,16 @@ goto failed; } + if (!c->double_hash && c->fmt_version >= 5) { + err = 16; + goto failed; + } + + if (c->encrypted && c->fmt_version < 5) { + err = 17; + goto failed; + } + return 0; failed: @@ -214,6 +239,11 @@ return sup; } +/* + * removed in barebox +int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup) + */ + /** * ubifs_read_superblock - read superblock. * @c: UBIFS file-system description object @@ -228,8 +258,8 @@ struct ubifs_sb_node *sup; if (c->empty) { - printf("No UBIFS filesystem found!\n"); - return -1; + ubifs_err(c, "No UBIFS filesystem found\n"); + return -EINVAL; } sup = ubifs_read_sb_node(c); @@ -244,7 +274,7 @@ * due to the unavailability of time-travelling equipment. */ if (c->fmt_version > UBIFS_FORMAT_VERSION) { - ubifs_assert(!c->ro_media || c->ro_mount); + ubifs_assert(c, !c->ro_media || c->ro_mount); if (!c->ro_mount || c->ro_compat_version > UBIFS_RO_COMPAT_VERSION) { ubifs_err(c, "on-flash format version is w%d/r%d, but software only supports up to version w%d/r%d", @@ -308,8 +338,6 @@ c->fanout = le32_to_cpu(sup->fanout); c->lsave_cnt = le32_to_cpu(sup->lsave_cnt); 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); @@ -318,6 +346,24 @@ memcpy(&c->uuid, &sup->uuid, 16); c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT); c->space_fixup = !!(sup_flags & UBIFS_FLG_SPACE_FIXUP); + c->double_hash = !!(sup_flags & UBIFS_FLG_DOUBLE_HASH); + c->encrypted = !!(sup_flags & UBIFS_FLG_ENCRYPTION); + + if ((sup_flags & ~UBIFS_FLG_MASK) != 0) { + ubifs_err(c, "Unknown feature flags found: %#x", + sup_flags & ~UBIFS_FLG_MASK); + err = -EINVAL; + goto out; + } + +#ifndef CONFIG_UBIFS_FS_ENCRYPTION + if (c->encrypted) { + ubifs_err(c, "file system contains encrypted files but UBIFS" + " was built without crypto support."); + err = -EINVAL; + goto out; + } +#endif /* Automatically increase file system size to the maximum size */ c->old_leb_cnt = c->leb_cnt; @@ -326,6 +372,9 @@ if (c->ro_mount) dbg_mnt("Auto resizing (ro) from %d LEBs to %d LEBs", c->old_leb_cnt, c->leb_cnt); + else { + /* Auto resizing not done in barebox */ + } } c->log_bytes = (long long)c->log_lebs * c->leb_size; @@ -343,3 +392,23 @@ kfree(sup); return err; } + +/* + * removed in barebox +static int fixup_leb(struct ubifs_info *c, int lnum, int len) + */ + +/* + * removed in barebox +static int fixup_free_space(struct ubifs_info *c) + */ + +/* + * removed in barebox +int ubifs_fixup_free_space(struct ubifs_info *c) + */ + +/* + * removed in barebox +int ubifs_enable_encryption(struct ubifs_info *c) + */ diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index 1d4bdf6..ea88926 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Adrian Hunter * Artem Bityutskiy (Битюцкий Артём) @@ -16,7 +27,6 @@ * debugging functions. */ -#include #include "ubifs.h" /** @@ -165,9 +175,8 @@ void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, int lnum, int offs) { - lnum = lnum; dbg_scan("stop scanning LEB %d at offset %d", lnum, offs); - ubifs_assert(offs % c->min_io_size == 0); + ubifs_assert(c, offs % c->min_io_size == 0); sleb->endpt = ALIGN(offs, c->min_io_size); } diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index f5ddfc6..2fe2f3f 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -15,7 +26,6 @@ * corresponding subsystems, but most of it is here. */ - #include #include #include @@ -58,8 +68,10 @@ #define UBIFS_KMALLOC_OK (128*1024) /* Slab cache for UBIFS inodes */ -struct kmem_cache *ubifs_inode_slab; +static struct kmem_cache *ubifs_inode_slab; +/* UBIFS TNC shrinker description */ +/* No shrinker in barebox */ /** * validate_inode - validate inode. @@ -96,12 +108,12 @@ if (ui->xattr && !S_ISREG(inode->i_mode)) return 5; - if (!ubifs_compr_present(ui->compr_type)) { + if (!ubifs_compr_present(c, ui->compr_type)) { ubifs_warn(c, "inode %lu uses '%s' compression, but it was not compiled in", - inode->i_ino, ubifs_compr_name(ui->compr_type)); + inode->i_ino, ubifs_compr_name(c, ui->compr_type)); } - err = dbg_check_dir(c, inode); + err = 0; return err; } @@ -138,7 +150,10 @@ if (err) goto out_ino; - inode->i_flags |= (S_NOCMTIME | S_NOATIME); + inode->i_flags |= S_NOCMTIME; +#ifndef CONFIG_UBIFS_ATIME_SUPPORT + inode->i_flags |= S_NOATIME; +#endif set_nlink(inode, le32_to_cpu(ino->nlink)); i_uid_write(inode, le32_to_cpu(ino->uid)); i_gid_write(inode, le32_to_cpu(ino->gid)); @@ -168,6 +183,7 @@ switch (inode->i_mode & S_IFMT) { case S_IFREG: + /* no address operations in barebox */ inode->i_op = &ubifs_file_inode_operations; inode->i_fop = &ubifs_file_operations; if (ui->xattr) { @@ -206,6 +222,12 @@ ((char *)ui->data)[ui->data_len] = '\0'; inode->i_link = ui->data; break; + case S_IFBLK: + case S_IFCHR: + case S_IFSOCK: + case S_IFIFO: + /* No special files in barebox */ + break; default: err = 15; goto out_invalid; @@ -243,6 +265,11 @@ return &ui->vfs_inode; }; +/* + * removed in barebox +static void ubifs_i_callback(struct rcu_head *head) + */ + static void ubifs_destroy_inode(struct inode *inode) { struct ubifs_inode *ui = ubifs_inode(inode); @@ -251,6 +278,35 @@ kfree(ui); } +/* + * removed in barebox +static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc) + */ + +/* + * removed in barebox +static void ubifs_evict_inode(struct inode *inode) + */ + +/* + * removed in barebox +static void ubifs_dirty_inode(struct inode *inode, int flags) + */ + +/* + * removed in barebox +static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf) + */ + +/* + * removed in barebox +static int ubifs_show_options(struct seq_file *s, struct dentry *root) + */ + +/* + * removed in barebox +static int ubifs_sync_fs(struct super_block *sb, int wait) + */ /** * init_constants_early - initialize UBIFS constants. @@ -288,19 +344,19 @@ c->max_write_shift = fls(c->max_write_size) - 1; if (c->leb_size < UBIFS_MIN_LEB_SZ) { - ubifs_err(c, "too small LEBs (%d bytes), min. is %d bytes", - c->leb_size, UBIFS_MIN_LEB_SZ); + ubifs_errc(c, "too small LEBs (%d bytes), min. is %d bytes", + c->leb_size, UBIFS_MIN_LEB_SZ); return -EINVAL; } if (c->leb_cnt < UBIFS_MIN_LEB_CNT) { - ubifs_err(c, "too few LEBs (%d), min. is %d", - c->leb_cnt, UBIFS_MIN_LEB_CNT); + ubifs_errc(c, "too few LEBs (%d), min. is %d", + c->leb_cnt, UBIFS_MIN_LEB_CNT); return -EINVAL; } if (!is_power_of_2(c->min_io_size)) { - ubifs_err(c, "bad min. I/O size %d", c->min_io_size); + ubifs_errc(c, "bad min. I/O size %d", c->min_io_size); return -EINVAL; } @@ -311,8 +367,8 @@ if (c->max_write_size < c->min_io_size || c->max_write_size % c->min_io_size || !is_power_of_2(c->max_write_size)) { - ubifs_err(c, "bad write buffer size %d for %d min. I/O unit", - c->max_write_size, c->min_io_size); + ubifs_errc(c, "bad write buffer size %d for %d min. I/O unit", + c->max_write_size, c->min_io_size); return -EINVAL; } @@ -388,6 +444,11 @@ } /* + * removed in barebox +static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad) + */ + +/* * init_constants_sb - initialize UBIFS constants. * @c: UBIFS file-system description object * @@ -469,11 +530,23 @@ if (c->max_bud_bytes < tmp64 + c->leb_size) c->max_bud_bytes = tmp64 + c->leb_size; + /* No lpt in barebox */ + /* Initialize effective LEB size used in budgeting calculations */ c->idx_leb_size = c->leb_size - c->max_idx_node_sz; return 0; } +/* + * removed in barebox +static void init_constants_master(struct ubifs_info *c) + */ + +/* + * removed in barebox +static int take_gc_lnum(struct ubifs_info *c) + */ + /** * alloc_wbufs - allocate write-buffers. * @c: UBIFS file-system description object @@ -529,6 +602,11 @@ } } +/* + * removed in barebox +static void free_orphans(struct ubifs_info *c) + */ + /** * free_buds - free per-bud objects. * @c: UBIFS file-system description object @@ -570,6 +648,17 @@ return 0; } +/* + * removed in barebox +static int parse_standard_option(const char *option) +*/ + +/* + * removed in barebox +static int ubifs_parse_options(struct ubifs_info *c, char *options, + int is_remount) + */ + /** * destroy_journal - destroy journal data structures. * @c: UBIFS file-system description object @@ -599,6 +688,16 @@ free_buds(c); } +/* + * removed in barebox +static void bu_init(struct ubifs_info *c) + */ + +/* + * removed in barebox +static int check_free_space(struct ubifs_info *c) + */ + /** * mount_ubifs - mount UBIFS file-system. * @c: UBIFS file-system description object @@ -612,17 +711,16 @@ long long x, y; size_t sz; + /* Always readonly in barebox */ c->ro_mount = true; - /* Suppress error messages while probing if MS_SILENT is set */ - c->probing = !!(c->vfs_sb->s_flags & MS_SILENT); + /* Suppress error messages while probing if SB_SILENT is set */ + c->probing = !!(c->vfs_sb->s_flags & SB_SILENT); err = init_constants_early(c); if (err) return err; - err = ubifs_debugging_init(c); - if (err) - return err; + /* No debugging in barebox, use Kernel to debug */ err = check_volume_empty(c); if (err) @@ -651,7 +749,8 @@ * never exceed 64. */ err = -ENOMEM; - c->bottom_up_buf = kmalloc(BOTTOM_UP_HEIGHT * sizeof(int), GFP_KERNEL); + c->bottom_up_buf = kmalloc_array(BOTTOM_UP_HEIGHT, sizeof(int), + GFP_KERNEL); if (!c->bottom_up_buf) goto out_free; @@ -672,9 +771,9 @@ * Make sure the compressor which is set as default in the superblock * or overridden by mount options is actually compiled in. */ - if (!ubifs_compr_present(c->default_compr)) { + if (!ubifs_compr_present(c, c->default_compr)) { ubifs_err(c, "'compressor \"%s\" is not compiled in", - ubifs_compr_name(c->default_compr)); + ubifs_compr_name(c, c->default_compr)); err = -ENOTSUPP; goto out_free; } @@ -728,18 +827,12 @@ * the journal head LEBs may also be accounted as * "empty taken" if they are empty. */ - ubifs_assert(c->lst.taken_empty_lebs > 0); + ubifs_assert(c, c->lst.taken_empty_lebs > 0); } + } else { + /* c->lst.taken_empty_lebs is always 0 in ro implementation */ } - err = dbg_check_filesystem(c); - if (err) - goto out_infos; - - err = dbg_debugfs_init_fs(c); - if (err) - goto out_infos; - c->mounting = 0; ubifs_msg(c, "UBIFS: mounted UBI device %d, volume %d, name \"%s\"%s", @@ -760,7 +853,7 @@ UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION, c->uuid, c->big_lpt ? ", big LPT model" : ", small LPT model"); - dbg_gen("default compressor: %s", ubifs_compr_name(c->default_compr)); + dbg_gen("default compressor: %s", ubifs_compr_name(c, c->default_compr)); dbg_gen("data journal heads: %d", c->jhead_cnt - NONDATA_JHEADS_CNT); dbg_gen("log LEBs: %d (%d - %d)", @@ -808,10 +901,6 @@ return 0; -out_infos: - spin_lock(&ubifs_infos_lock); - list_del(&c->infos_list); - spin_unlock(&ubifs_infos_lock); out_orphans: out_journal: destroy_journal(c); @@ -829,7 +918,6 @@ vfree(c->ileb_buf); vfree(c->sbuf); kfree(c->bottom_up_buf); - ubifs_debugging_exit(c); return err; } @@ -847,7 +935,6 @@ dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num, c->vi.vol_id); - dbg_debugfs_exit_fs(c); spin_lock(&ubifs_infos_lock); list_del(&c->infos_list); spin_unlock(&ubifs_infos_lock); @@ -862,32 +949,36 @@ vfree(c->ileb_buf); vfree(c->sbuf); kfree(c->bottom_up_buf); - ubifs_debugging_exit(c); } +/* + * removed in barebox +static int ubifs_remount_rw(struct ubifs_info *c) + */ + +/* + * removed in barebox +static void ubifs_remount_ro(struct ubifs_info *c) + */ + +/* + * removed in barebox +static void ubifs_put_super(struct super_block *sb) + */ + +/* + * removed in barebox +static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) + */ + const struct super_operations ubifs_super_operations = { .alloc_inode = ubifs_alloc_inode, .destroy_inode = ubifs_destroy_inode, }; -/** - * open_ubi - parse UBI device name string and open the UBI device. - * @name: UBI volume name - * @mode: UBI volume open mode - * - * The primary method of mounting UBIFS is by specifying the UBI volume - * character device node path. However, UBIFS may also be mounted withoug any - * character device node using one of the following methods: - * - * o ubiX_Y - mount UBI device number X, volume Y; - * o ubiY - mount UBI device number 0, volume Y; - * o ubiX:NAME - mount UBI device X, volume with name NAME; - * o ubi:NAME - mount UBI device 0, volume with name NAME. - * - * Alternative '!' separator may be used instead of ':' (because some shells - * like busybox may interpret ':' as an NFS host name separator). This function - * returns UBI volume description object in case of success and a negative - * error code in case of failure. +/* + * removed in barebox +static struct ubi_volume_desc *open_ubi(const char *name, int mode) */ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi) @@ -926,6 +1017,7 @@ INIT_LIST_HEAD(&c->orph_list); INIT_LIST_HEAD(&c->orph_new); c->no_chk_data_crc = 1; + c->assert_action = ASSACT_RO; c->highest_inum = UBIFS_FIRST_INO; c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; @@ -943,6 +1035,7 @@ int err; c->vfs_sb = sb; + sb->s_fs_info = c; sb->s_magic = UBIFS_SUPER_MAGIC; sb->s_blocksize = UBIFS_BLOCK_SIZE; @@ -951,11 +1044,17 @@ if (c->max_inode_sz > MAX_LFS_FILESIZE) sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; sb->s_op = &ubifs_super_operations; +#ifdef CONFIG_UBIFS_FS_XATTR + sb->s_xattr = ubifs_xattr_handlers; +#endif +#ifdef CONFIG_UBIFS_FS_ENCRYPTION + sb->s_cop = &ubifs_crypt_operations; +#endif mutex_lock(&c->umount_mutex); err = mount_ubifs(c); if (err) { - ubifs_assert(err < 0); + ubifs_assert(c, err < 0); goto out_unlock; } @@ -979,10 +1078,32 @@ ubifs_umount(c); out_unlock: mutex_unlock(&c->umount_mutex); + return err; } /* + * removed in barebox +static int sb_test(struct super_block *sb, void *data) + */ + +/* + * removed in barebox +static int sb_set(struct super_block *sb, void *data) + */ + +/* + * removed in barebox +static struct dentry *ubifs_mount(struct file_system_type *fs_type, int flags, + const char *name, void *data) + */ + +/* + * removed in barebox +static void kill_ubifs_super(struct super_block *s) + */ + +/* * Inode slab cache constructor. */ static void inode_slab_ctor(void *obj) @@ -1041,12 +1162,12 @@ BUILD_BUG_ON(UBIFS_COMPR_TYPES_CNT > 4); /* - * We require that PAGE_CACHE_SIZE is greater-than-or-equal-to + * We require that PAGE_SIZE is greater-than-or-equal-to * UBIFS_BLOCK_SIZE. It is assumed that both are powers of 2. */ - if (PAGE_CACHE_SIZE < UBIFS_BLOCK_SIZE) { - pr_err("UBIFS error (pid %d): VFS page cache size is %u bytes, but UBIFS requires at least 4096 bytes", - 0, (unsigned int)PAGE_CACHE_SIZE); + if (PAGE_SIZE < UBIFS_BLOCK_SIZE) { + pr_err("UBIFS error: VFS page cache size is %u bytes, but UBIFS requires at least 4096 bytes", + (unsigned int)PAGE_SIZE); return -EINVAL; } @@ -1070,7 +1191,6 @@ /* late_initcall to let compressors initialize first */ late_initcall(ubifs_init); - int ubifs_get_super(struct device_d *dev, struct ubi_volume_desc *ubi, int silent) { struct fs_device_d *fsdev = dev_to_fs_device(dev); @@ -1085,12 +1205,11 @@ sb->s_fs_info = c; strncpy(sb->s_id, dev->name, sizeof(sb->s_id)); - /* Re-open the UBI device in read-write mode */ c->ubi = ubi; err = ubifs_fill_super(sb, NULL, silent); if (err) { - ubifs_assert(err < 0); + ubifs_assert(c, err < 0); goto out; } sb->s_dev = c->vi.cdev; @@ -1100,3 +1219,8 @@ kfree(c); return err; } + +/* + * removed in barebox +static void __exit ubifs_exit(void) + */ diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 0f93051..191785c 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Adrian Hunter * Artem Bityutskiy (Битюцкий Артём) @@ -23,6 +34,11 @@ #include #include "ubifs.h" +static int try_read_node(const struct ubifs_info *c, void *buf, int type, + int len, int lnum, int offs); +static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_zbranch *zbr, void *node); + /* * Returned codes of 'matches_name()' and 'fallible_matches_name()' functions. * @NAME_LESS: name corresponding to the first argument is less than second @@ -175,6 +191,17 @@ c->old_idx = RB_ROOT; } +/* + * removed in barebox +static struct ubifs_znode *copy_znode(struct ubifs_info *c, + struct ubifs_znode *znode) + */ + +/* + * removed in barebox +static int add_idx_dirt(struct ubifs_info *c, int lnum, int dirt) + */ + /** * dirty_cow_znode - ensure a znode is not being committed. * @c: UBIFS file-system description object @@ -185,6 +212,7 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr) { + /* No cow in barebox, just return original node */ return zbr->znode; } @@ -215,9 +243,9 @@ void *lnc_node; const struct ubifs_dent_node *dent = node; - ubifs_assert(!zbr->leaf); - ubifs_assert(zbr->len != 0); - ubifs_assert(is_hash_key(c, &zbr->key)); + ubifs_assert(c, !zbr->leaf); + ubifs_assert(c, zbr->len != 0); + ubifs_assert(c, is_hash_key(c, &zbr->key)); err = ubifs_validate_entry(c, dent); if (err) { @@ -249,8 +277,8 @@ { int err; - ubifs_assert(!zbr->leaf); - ubifs_assert(zbr->len != 0); + ubifs_assert(c, !zbr->leaf); + ubifs_assert(c, zbr->len != 0); err = ubifs_validate_entry(c, node); if (err) { @@ -277,7 +305,7 @@ } /** - * tnc_read_node_nm - read a "hashed" leaf node. + * tnc_read_hashed_node - read a "hashed" leaf node. * @c: UBIFS file-system description object * @zbr: key and position of the node * @node: node is returned here @@ -287,21 +315,33 @@ * added to LNC. Returns zero in case of success or a negative negative error * code in case of failure. */ -static int tnc_read_node_nm(struct ubifs_info *c, struct ubifs_zbranch *zbr, - void *node) +static int tnc_read_hashed_node(struct ubifs_info *c, struct ubifs_zbranch *zbr, + void *node) { int err; - ubifs_assert(is_hash_key(c, &zbr->key)); + ubifs_assert(c, is_hash_key(c, &zbr->key)); if (zbr->leaf) { /* Read from the leaf node cache */ - ubifs_assert(zbr->len != 0); + ubifs_assert(c, zbr->len != 0); memcpy(node, zbr->leaf, zbr->len); return 0; } - err = ubifs_tnc_read_node(c, zbr, node); + if (c->replaying) { + err = fallible_read_node(c, &zbr->key, zbr, node); + /* + * When the node was not found, return -ENOENT, 0 otherwise. + * Negative return codes stay as-is. + */ + if (err == 0) + err = -ENOENT; + else if (err == 1) + err = 0; + } else { + err = ubifs_tnc_read_node(c, zbr, node); + } if (err) return err; @@ -418,7 +458,7 @@ * of failure, a negative error code is returned. */ static int matches_name(struct ubifs_info *c, struct ubifs_zbranch *zbr, - const struct qstr *nm) + const struct fscrypt_name *nm) { struct ubifs_dent_node *dent; int nlen, err; @@ -441,11 +481,11 @@ dent = zbr->leaf; nlen = le16_to_cpu(dent->nlen); - err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len)); + err = memcmp(dent->name, fname_name(nm), min_t(int, nlen, fname_len(nm))); if (err == 0) { - if (nlen == nm->len) + if (nlen == fname_len(nm)) return NAME_MATCHES; - else if (nlen < nm->len) + else if (nlen < fname_len(nm)) return NAME_LESS; else return NAME_GREATER; @@ -588,7 +628,7 @@ */ static int resolve_collision(struct ubifs_info *c, const union ubifs_key *key, struct ubifs_znode **zn, int *n, - const struct qstr *nm) + const struct fscrypt_name *nm) { int err; @@ -603,7 +643,7 @@ while (1) { err = tnc_prev(c, zn, n); if (err == -ENOENT) { - ubifs_assert(*n == 0); + ubifs_assert(c, *n == 0); *n = -1; return 0; } @@ -643,12 +683,12 @@ err = tnc_next(c, zn, n); if (err) { /* Should be impossible */ - ubifs_assert(0); + ubifs_assert(c, 0); if (err == -ENOENT) err = -EINVAL; return err; } - ubifs_assert(*n == 0); + ubifs_assert(c, *n == 0); *n = -1; } return 0; @@ -660,7 +700,7 @@ return 0; if (err == NAME_MATCHES) return 1; - ubifs_assert(err == NAME_GREATER); + ubifs_assert(c, err == NAME_GREATER); } } else { int nn = *n; @@ -684,7 +724,7 @@ *n = nn; if (err == NAME_MATCHES) return 1; - ubifs_assert(err == NAME_LESS); + ubifs_assert(c, err == NAME_LESS); } } } @@ -706,7 +746,7 @@ */ static int fallible_matches_name(struct ubifs_info *c, struct ubifs_zbranch *zbr, - const struct qstr *nm) + const struct fscrypt_name *nm) { struct ubifs_dent_node *dent; int nlen, err; @@ -725,7 +765,7 @@ err = NOT_ON_MEDIA; goto out_free; } - ubifs_assert(err == 1); + ubifs_assert(c, err == 1); err = lnc_add_directly(c, zbr, dent); if (err) @@ -734,11 +774,11 @@ dent = zbr->leaf; nlen = le16_to_cpu(dent->nlen); - err = memcmp(dent->name, nm->name, min_t(int, nlen, nm->len)); + err = memcmp(dent->name, fname_name(nm), min_t(int, nlen, fname_len(nm))); if (err == 0) { - if (nlen == nm->len) + if (nlen == fname_len(nm)) return NAME_MATCHES; - else if (nlen < nm->len) + else if (nlen < fname_len(nm)) return NAME_LESS; else return NAME_GREATER; @@ -777,7 +817,8 @@ static int fallible_resolve_collision(struct ubifs_info *c, const union ubifs_key *key, struct ubifs_znode **zn, int *n, - const struct qstr *nm, int adding) + const struct fscrypt_name *nm, + int adding) { struct ubifs_znode *o_znode = NULL, *znode = *zn; int uninitialized_var(o_n), err, cmp, unsure = 0, nn = *n; @@ -804,7 +845,7 @@ while (1) { err = tnc_prev(c, zn, n); if (err == -ENOENT) { - ubifs_assert(*n == 0); + ubifs_assert(c, *n == 0); *n = -1; break; } @@ -816,12 +857,12 @@ err = tnc_next(c, zn, n); if (err) { /* Should be impossible */ - ubifs_assert(0); + ubifs_assert(c, 0); if (err == -ENOENT) err = -EINVAL; return err; } - ubifs_assert(*n == 0); + ubifs_assert(c, *n == 0); *n = -1; } break; @@ -885,6 +926,25 @@ return 1; } +/* + * removed in barebox +static int matches_position(struct ubifs_zbranch *zbr, int lnum, int offs) + */ + +/* + * removed in barebox +static int resolve_collision_directly(struct ubifs_info *c, + const union ubifs_key *key, + struct ubifs_znode **zn, int *n, + int lnum, int offs) + */ + +/* + * removed in barebox +static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c, + struct ubifs_znode *znode) + */ + /** * ubifs_lookup_level0 - search for zero-level znode. * @c: UBIFS file-system description object @@ -912,10 +972,9 @@ { int err, exact; struct ubifs_znode *znode; - unsigned long time = get_seconds(); dbg_tnck(key, "search key "); - ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY); + ubifs_assert(c, key_type(c, key) < UBIFS_INVALID_KEY); znode = c->zroot.znode; if (unlikely(!znode)) { @@ -924,8 +983,6 @@ return PTR_ERR(znode); } - znode->time = time; - while (1) { struct ubifs_zbranch *zbr; @@ -939,7 +996,6 @@ zbr = &znode->zbranch[*n]; if (zbr->znode) { - znode->time = time; znode = zbr->znode; continue; } @@ -1048,7 +1104,6 @@ { int err, exact; struct ubifs_znode *znode; - unsigned long time = get_seconds(); dbg_tnck(key, "search and dirty key "); @@ -1063,8 +1118,6 @@ if (IS_ERR(znode)) return PTR_ERR(znode); - znode->time = time; - while (1) { struct ubifs_zbranch *zbr; @@ -1078,7 +1131,6 @@ zbr = &znode->zbranch[*n]; if (zbr->znode) { - znode->time = time; znode = dirty_cow_znode(c, zbr); if (IS_ERR(znode)) return PTR_ERR(znode); @@ -1135,7 +1187,7 @@ */ static int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1) { - /* No garbage collection in the read-only U-Boot implementation */ + /* No GC in barebox */ return 0; } @@ -1179,7 +1231,7 @@ * In this case the leaf node cache gets used, so we pass the * address of the zbranch and keep the mutex locked */ - err = tnc_read_node_nm(c, zt, node); + err = tnc_read_hashed_node(c, zt, node); goto out; } if (safely) { @@ -1207,6 +1259,28 @@ return err; } +/* + * removed in barebox +int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu) + */ + +/* + * removed in barebox +static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum, + int offs) + */ + +/* + * removed in barebox +static int validate_data_node(struct ubifs_info *c, void *buf, + struct ubifs_zbranch *zbr) + */ + +/* + * removed in barebox +int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu) + */ + /** * do_lookup_nm- look up a "hashed" node. * @c: UBIFS file-system description object @@ -1214,19 +1288,19 @@ * @node: the node is returned here * @nm: node name * - * This function look up and reads a node which contains name hash in the key. + * This function looks up and reads a node which contains name hash in the key. * Since the hash may have collisions, there may be many nodes with the same * key, so we have to sequentially look to all of them until the needed one is * found. This function returns zero in case of success, %-ENOENT if the node * was not found, and a negative error code in case of failure. */ static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, - void *node, const struct qstr *nm) + void *node, const struct fscrypt_name *nm) { int found, n, err; struct ubifs_znode *znode; - dbg_tnck(key, "name '%.*s' key ", nm->len, nm->name); + dbg_tnck(key, "key "); mutex_lock(&c->tnc_mutex); found = ubifs_lookup_level0(c, key, &znode, &n); if (!found) { @@ -1237,7 +1311,7 @@ goto out_unlock; } - ubifs_assert(n >= 0); + ubifs_assert(c, n >= 0); err = resolve_collision(c, key, &znode, &n, nm); dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); @@ -1248,7 +1322,7 @@ goto out_unlock; } - err = tnc_read_node_nm(c, &znode->zbranch[n], node); + err = tnc_read_hashed_node(c, &znode->zbranch[n], node); out_unlock: mutex_unlock(&c->tnc_mutex); @@ -1262,14 +1336,14 @@ * @node: the node is returned here * @nm: node name * - * This function look up and reads a node which contains name hash in the key. + * This function looks up and reads a node which contains name hash in the key. * Since the hash may have collisions, there may be many nodes with the same * key, so we have to sequentially look to all of them until the needed one is * found. This function returns zero in case of success, %-ENOENT if the node * was not found, and a negative error code in case of failure. */ int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, - void *node, const struct qstr *nm) + void *node, const struct fscrypt_name *nm) { int err, len; const struct ubifs_dent_node *dent = node; @@ -1283,16 +1357,115 @@ return err; len = le16_to_cpu(dent->nlen); - if (nm->len == len && !memcmp(dent->name, nm->name, len)) + if (fname_len(nm) == len && !memcmp(dent->name, fname_name(nm), len)) return 0; /* * Unluckily, there are hash collisions and we have to iterate over * them look at each direntry with colliding name hash sequentially. */ + return do_lookup_nm(c, key, node, nm); } +static int search_dh_cookie(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_dent_node *dent, uint32_t cookie, + struct ubifs_znode **zn, int *n) +{ + int err; + struct ubifs_znode *znode = *zn; + struct ubifs_zbranch *zbr; + union ubifs_key *dkey; + + for (;;) { + zbr = &znode->zbranch[*n]; + dkey = &zbr->key; + + if (key_inum(c, dkey) != key_inum(c, key) || + key_type(c, dkey) != key_type(c, key)) { + return -ENOENT; + } + + err = tnc_read_hashed_node(c, zbr, dent); + if (err) + return err; + + if (key_hash(c, key) == key_hash(c, dkey) && + le32_to_cpu(dent->cookie) == cookie) { + *zn = znode; + return 0; + } + + err = tnc_next(c, &znode, n); + if (err) + return err; + } +} + +static int do_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, + struct ubifs_dent_node *dent, uint32_t cookie) +{ + int n, err; + struct ubifs_znode *znode; + union ubifs_key start_key; + + ubifs_assert(c, is_hash_key(c, key)); + + lowest_dent_key(c, &start_key, key_inum(c, key)); + + mutex_lock(&c->tnc_mutex); + err = ubifs_lookup_level0(c, &start_key, &znode, &n); + if (unlikely(err < 0)) + goto out_unlock; + + err = search_dh_cookie(c, key, dent, cookie, &znode, &n); + +out_unlock: + mutex_unlock(&c->tnc_mutex); + return err; +} + +/** + * ubifs_tnc_lookup_dh - look up a "double hashed" node. + * @c: UBIFS file-system description object + * @key: node key to lookup + * @node: the node is returned here + * @cookie: node cookie for collision resolution + * + * This function looks up and reads a node which contains name hash in the key. + * Since the hash may have collisions, there may be many nodes with the same + * key, so we have to sequentially look to all of them until the needed one + * with the same cookie value is found. + * This function returns zero in case of success, %-ENOENT if the node + * was not found, and a negative error code in case of failure. + */ +int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, + void *node, uint32_t cookie) +{ + int err; + const struct ubifs_dent_node *dent = node; + + if (!c->double_hash) + return -EOPNOTSUPP; + + /* + * We assume that in most of the cases there are no name collisions and + * 'ubifs_tnc_lookup()' returns us the right direntry. + */ + err = ubifs_tnc_lookup(c, key, node); + if (err) + return err; + + if (le32_to_cpu(dent->cookie) == cookie) + return 0; + + /* + * Unluckily, there are hash collisions and we have to iterate over + * them look at each direntry with colliding name hash sequentially. + */ + return do_lookup_dh(c, key, node, cookie); +} + /** * correct_parent_keys - correct parent znodes' keys. * @c: UBIFS file-system description object @@ -1307,8 +1480,8 @@ { union ubifs_key *key, *key1; - ubifs_assert(znode->parent); - ubifs_assert(znode->iip == 0); + ubifs_assert(c, znode->parent); + ubifs_assert(c, znode->iip == 0); key = &znode->zbranch[0].key; key1 = &znode->parent->zbranch[0].key; @@ -1325,6 +1498,7 @@ /** * insert_zbranch - insert a zbranch into a znode. + * @c: UBIFS file-system description object * @znode: znode into which to insert * @zbr: zbranch to insert * @n: slot number to insert to @@ -1334,11 +1508,13 @@ * zbranch has to be inserted to the @znode->zbranches[]' array at the @n-th * slot, zbranches starting from @n have to be moved right. */ -static void insert_zbranch(struct ubifs_znode *znode, +static void insert_zbranch(struct ubifs_info *c, struct ubifs_znode *znode, const struct ubifs_zbranch *zbr, int n) { int i; + /* znode is never dirty in barebox ro implementation */ + if (znode->level) { for (i = znode->child_cnt; i > n; i--) { znode->zbranch[i] = znode->zbranch[i - 1]; @@ -1391,16 +1567,16 @@ int i, keep, move, appending = 0; union ubifs_key *key = &zbr->key, *key1; - ubifs_assert(n >= 0 && n <= c->fanout); + ubifs_assert(c, n >= 0 && n <= c->fanout); /* Implement naive insert for now */ again: zp = znode->parent; if (znode->child_cnt < c->fanout) { - ubifs_assert(n != c->fanout); + ubifs_assert(c, n != c->fanout); dbg_tnck(key, "inserted at %d level %d, key ", n, znode->level); - insert_zbranch(znode, zbr, n); + insert_zbranch(c, znode, zbr, n); /* Ensure parent's key is correct */ if (n == 0 && zp && znode->iip == 0) @@ -1509,7 +1685,7 @@ /* Insert new key and branch */ dbg_tnck(key, "inserting at %d level %d, key ", n, zn->level); - insert_zbranch(zi, zbr, n); + insert_zbranch(c, zi, zbr, n); /* Insert new znode (produced by spitting) into the parent */ if (zp) { @@ -1611,6 +1787,12 @@ return err; } +/* + * removed in barebox +int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, + int old_lnum, int old_offs, int lnum, int offs, int len) + */ + /** * ubifs_tnc_add_nm - add a "hashed" node to TNC. * @c: UBIFS file-system description object @@ -1624,14 +1806,14 @@ * may have collisions, like directory entry keys. */ int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, - int lnum, int offs, int len, const struct qstr *nm) + int lnum, int offs, int len, + const struct fscrypt_name *nm) { int found, n, err = 0; struct ubifs_znode *znode; mutex_lock(&c->tnc_mutex); - dbg_tnck(key, "LEB %d:%d, name '%.*s', key ", - lnum, offs, nm->len, nm->name); + dbg_tnck(key, "LEB %d:%d, key ", lnum, offs); found = lookup_level0_dirty(c, key, &znode, &n); if (found < 0) { err = found; @@ -1680,7 +1862,7 @@ * by passing 'ubifs_tnc_remove_nm()' the same key but * an unmatchable name. */ - struct qstr noname = { .name = "" }; + struct fscrypt_name noname = { .disk_name = { .name = "", .len = 1 } }; err = dbg_check_tnc(c, 0); mutex_unlock(&c->tnc_mutex); @@ -1713,8 +1895,8 @@ int i, err; /* Delete without merge for now */ - ubifs_assert(znode->level == 0); - ubifs_assert(n >= 0 && n < c->fanout); + ubifs_assert(c, znode->level == 0); + ubifs_assert(c, n >= 0 && n < c->fanout); dbg_tnck(&znode->zbranch[n].key, "deleting key "); zbr = &znode->zbranch[n]; @@ -1740,8 +1922,8 @@ */ do { - ubifs_assert(!ubifs_zn_obsolete(znode)); - ubifs_assert(ubifs_zn_dirty(znode)); + ubifs_assert(c, !ubifs_zn_obsolete(znode)); + ubifs_assert(c, ubifs_zn_dirty(znode)); zp = znode->parent; n = znode->iip; @@ -1763,7 +1945,7 @@ /* Remove from znode, entry n - 1 */ znode->child_cnt -= 1; - ubifs_assert(znode->level != 0); + ubifs_assert(c, znode->level != 0); for (i = n; i < znode->child_cnt; i++) { znode->zbranch[i] = znode->zbranch[i + 1]; if (znode->zbranch[i].znode) @@ -1796,8 +1978,8 @@ c->zroot.offs = zbr->offs; c->zroot.len = zbr->len; c->zroot.znode = znode; - ubifs_assert(!ubifs_zn_obsolete(zp)); - ubifs_assert(ubifs_zn_dirty(zp)); + ubifs_assert(c, !ubifs_zn_obsolete(zp)); + ubifs_assert(c, ubifs_zn_dirty(zp)); atomic_long_dec(&c->dirty_zn_cnt); if (zp->cnext) { @@ -1850,13 +2032,13 @@ * Returns %0 on success or negative error code on failure. */ int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, - const struct qstr *nm) + const struct fscrypt_name *nm) { int n, err; struct ubifs_znode *znode; mutex_lock(&c->tnc_mutex); - dbg_tnck(key, "%.*s, key ", nm->len, nm->name); + dbg_tnck(key, "key "); err = lookup_level0_dirty(c, key, &znode, &n); if (err < 0) goto out_unlock; @@ -1870,8 +2052,9 @@ dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); if (err < 0) goto out_unlock; - if (err) + if (err) { err = tnc_delete(c, znode, n); + } } out_unlock: @@ -1881,6 +2064,12 @@ return err; } +/* + * removed in barebox +int ubifs_tnc_remove_dh(struct ubifs_info *c, const union ubifs_key *key, + uint32_t cookie) + */ + /** * key_in_range - determine if a key falls within a range of keys. * @c: UBIFS file-system description object @@ -1987,7 +2176,7 @@ { union ubifs_key key1, key2; struct ubifs_dent_node *xent, *pxent = NULL; - struct qstr nm = { .name = NULL }; + struct fscrypt_name nm = {0}; dbg_tnc("ino %lu", (unsigned long)inum); @@ -2012,8 +2201,10 @@ dbg_tnc("xent '%s', ino %lu", xent->name, (unsigned long)xattr_inum); - nm.name = xent->name; - nm.len = le16_to_cpu(xent->nlen); + ubifs_evict_xattr_inode(c, xattr_inum); + + fname_name(&nm) = xent->name; + fname_len(&nm) = le16_to_cpu(xent->nlen); err = ubifs_tnc_remove_nm(c, &key1, &nm); if (err) { kfree(xent); @@ -2065,7 +2256,7 @@ */ struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, union ubifs_key *key, - const struct qstr *nm) + const struct fscrypt_name *nm) { int n, err, type = key_type(c, key); struct ubifs_znode *znode; @@ -2073,18 +2264,22 @@ struct ubifs_zbranch *zbr; union ubifs_key *dkey; - dbg_tnck(key, "%s ", nm->name ? (char *)nm->name : "(lowest)"); - ubifs_assert(is_hash_key(c, key)); + dbg_tnck(key, "key "); + ubifs_assert(c, is_hash_key(c, key)); mutex_lock(&c->tnc_mutex); err = ubifs_lookup_level0(c, key, &znode, &n); if (unlikely(err < 0)) goto out_unlock; - if (nm->name) { + if (fname_len(nm) > 0) { if (err) { /* Handle collisions */ - err = resolve_collision(c, key, &znode, &n, nm); + if (c->replaying) + err = fallible_resolve_collision(c, key, &znode, &n, + nm, 0); + else + err = resolve_collision(c, key, &znode, &n, nm); dbg_tnc("rc returned %d, znode %p, n %d", err, znode, n); if (unlikely(err < 0)) @@ -2131,7 +2326,7 @@ goto out_free; } - err = tnc_read_node_nm(c, zbr, dent); + err = tnc_read_hashed_node(c, zbr, dent); if (unlikely(err)) goto out_free; @@ -2157,7 +2352,7 @@ if (!c->cnext) return; - ubifs_assert(c->cmt_state == COMMIT_BROKEN); + ubifs_assert(c, c->cmt_state == COMMIT_BROKEN); cnext = c->cnext; do { struct ubifs_znode *znode = cnext; @@ -2179,11 +2374,60 @@ long n, freed; n = atomic_long_read(&c->clean_zn_cnt); - freed = ubifs_destroy_tnc_subtree(c->zroot.znode); - ubifs_assert(freed == n); + freed = ubifs_destroy_tnc_subtree(c, c->zroot.znode); + ubifs_assert(c, freed == n); atomic_long_sub(n, &ubifs_clean_zn_cnt); } kfree(c->gap_lebs); kfree(c->ilebs); destroy_old_idx(c); } + +/* + * removed in barebox +static struct ubifs_znode *left_znode(struct ubifs_info *c, + struct ubifs_znode *znode) + */ + +/* + * removed in barebox +static struct ubifs_znode *right_znode(struct ubifs_info *c, + struct ubifs_znode *znode) + */ + +/* + * removed in barebox +static struct ubifs_znode *lookup_znode(struct ubifs_info *c, + union ubifs_key *key, int level, + int lnum, int offs) + */ + +/* + * removed in barebox +int is_idx_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs) + */ + +/* + * removed in barebox +static int is_leaf_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, + int lnum, int offs) + */ + +/* + * removed in barebox +int ubifs_tnc_has_node(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs, int is_idx) + */ + +/* + * removed in barebox +int ubifs_dirty_idx_node(struct ubifs_info *c, union ubifs_key *key, int level, + int lnum, int offs) + */ + +/* + * removed in barebox +int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, + loff_t size) + */ diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c index 1619d08..3106c9d 100644 --- a/fs/ubifs/tnc_misc.c +++ b/fs/ubifs/tnc_misc.c @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Adrian Hunter * Artem Bityutskiy (Битюцкий Артём) @@ -16,24 +27,25 @@ * putting it all in one file would make that file too big and unreadable. */ -#include #include "ubifs.h" /** * ubifs_tnc_levelorder_next - next TNC tree element in levelorder traversal. + * @c: UBIFS file-system description object * @zr: root of the subtree to traverse * @znode: previous znode * * This function implements levelorder TNC traversal. The LNC is ignored. * Returns the next element or %NULL if @znode is already the last one. */ -struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr, +struct ubifs_znode *ubifs_tnc_levelorder_next(const struct ubifs_info *c, + struct ubifs_znode *zr, struct ubifs_znode *znode) { int level, iip, level_search = 0; struct ubifs_znode *zn; - ubifs_assert(zr); + ubifs_assert(c, zr); if (unlikely(!znode)) return zr; @@ -48,7 +60,7 @@ iip = znode->iip; while (1) { - ubifs_assert(znode->level <= zr->level); + ubifs_assert(c, znode->level <= zr->level); /* * First walk up until there is a znode with next branch to @@ -75,7 +87,7 @@ level_search = 1; iip = -1; znode = ubifs_tnc_find_child(zr, 0); - ubifs_assert(znode); + ubifs_assert(c, znode); } /* Switch to the next index */ @@ -101,7 +113,7 @@ } if (zn) { - ubifs_assert(zn->level >= 0); + ubifs_assert(c, zn->level >= 0); return zn; } } @@ -130,7 +142,7 @@ int uninitialized_var(cmp); const struct ubifs_zbranch *zbr = &znode->zbranch[0]; - ubifs_assert(end > beg); + ubifs_assert(c, end > beg); while (end > beg) { mid = (beg + end) >> 1; @@ -148,13 +160,13 @@ *n = end - 1; /* The insert point is after *n */ - ubifs_assert(*n >= -1 && *n < znode->child_cnt); + ubifs_assert(c, *n >= -1 && *n < znode->child_cnt); if (*n == -1) - ubifs_assert(keys_cmp(c, key, &zbr[0].key) < 0); + ubifs_assert(c, keys_cmp(c, key, &zbr[0].key) < 0); else - ubifs_assert(keys_cmp(c, key, &zbr[*n].key) > 0); + ubifs_assert(c, keys_cmp(c, key, &zbr[*n].key) > 0); if (*n + 1 < znode->child_cnt) - ubifs_assert(keys_cmp(c, key, &zbr[*n + 1].key) < 0); + ubifs_assert(c, keys_cmp(c, key, &zbr[*n + 1].key) < 0); return 0; } @@ -185,16 +197,18 @@ /** * ubifs_tnc_postorder_next - next TNC tree element in postorder traversal. + * @c: UBIFS file-system description object * @znode: previous znode * * This function implements postorder TNC traversal. The LNC is ignored. * Returns the next element or %NULL if @znode is already the last one. */ -struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode) +struct ubifs_znode *ubifs_tnc_postorder_next(const struct ubifs_info *c, + struct ubifs_znode *znode) { struct ubifs_znode *zn; - ubifs_assert(znode); + ubifs_assert(c, znode); if (unlikely(!znode->parent)) return NULL; @@ -210,18 +224,20 @@ /** * ubifs_destroy_tnc_subtree - destroy all znodes connected to a subtree. + * @c: UBIFS file-system description object * @znode: znode defining subtree to destroy * * This function destroys subtree of the TNC tree. Returns number of clean * znodes in the subtree. */ -long ubifs_destroy_tnc_subtree(struct ubifs_znode *znode) +long ubifs_destroy_tnc_subtree(const struct ubifs_info *c, + struct ubifs_znode *znode) { struct ubifs_znode *zn = ubifs_tnc_postorder_first(znode); long clean_freed = 0; int n; - ubifs_assert(zn); + ubifs_assert(c, zn); while (1) { for (n = 0; n < zn->child_cnt; n++) { if (!zn->zbranch[n].znode) @@ -242,7 +258,7 @@ return clean_freed; } - zn = ubifs_tnc_postorder_next(zn); + zn = ubifs_tnc_postorder_next(c, zn); } } @@ -400,7 +416,7 @@ int err; struct ubifs_znode *znode; - ubifs_assert(!zbr->znode); + ubifs_assert(c, !zbr->znode); /* * A slab cache is not presently used for znodes because the znode size * depends on the fanout which is stored in the superblock. @@ -425,7 +441,6 @@ zbr->znode = znode; znode->parent = parent; - znode->time = get_seconds(); znode->iip = iip; return znode; @@ -453,7 +468,6 @@ err = ubifs_read_node(c, node, type, zbr->len, zbr->lnum, zbr->offs); - if (err) { dbg_tnck(key, "key "); return err; diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index 3462249..e8c23c9 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h @@ -3,7 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -35,7 +46,7 @@ * UBIFS went into mainline kernel with format version 4. The older formats * were development formats. */ -#define UBIFS_FORMAT_VERSION 4 +#define UBIFS_FORMAT_VERSION 5 /* * Read-only compatibility version. If the UBIFS format is changed, older UBIFS @@ -290,6 +301,13 @@ #define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ /* + * xattr name of UBIFS encryption context, we don't use a prefix + * nor a long name to not waste space on the flash. + */ +#define UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT "c" + + +/* * On-flash inode flags. * * UBIFS_COMPR_FL: use compression for this inode @@ -298,6 +316,7 @@ * UBIFS_APPEND_FL: writes to the inode may only append data * UBIFS_DIRSYNC_FL: I/O on this directory inode has to be synchronous * UBIFS_XATTR_FL: this inode is the inode for an extended attribute value + * UBIFS_CRYPT_FL: use encryption for this inode * * Note, these are on-flash flags which correspond to ioctl flags * (@FS_COMPR_FL, etc). They have the same values now, but generally, do not @@ -310,6 +329,7 @@ UBIFS_APPEND_FL = 0x08, UBIFS_DIRSYNC_FL = 0x10, UBIFS_XATTR_FL = 0x20, + UBIFS_CRYPT_FL = 0x40, }; /* Inode flag bits used by UBIFS */ @@ -398,12 +418,19 @@ * * UBIFS_FLG_BIGLPT: if "big" LPT model is used if set * UBIFS_FLG_SPACE_FIXUP: first-mount "fixup" of free space within LEBs needed + * UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to + * support 64bit cookies for lookups by hash + * UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files */ enum { UBIFS_FLG_BIGLPT = 0x02, UBIFS_FLG_SPACE_FIXUP = 0x04, + UBIFS_FLG_DOUBLE_HASH = 0x08, + UBIFS_FLG_ENCRYPTION = 0x10, }; +#define UBIFS_FLG_MASK (UBIFS_FLG_BIGLPT|UBIFS_FLG_SPACE_FIXUP|UBIFS_FLG_DOUBLE_HASH|UBIFS_FLG_ENCRYPTION) + /** * struct ubifs_ch - common header node. * @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC) @@ -510,7 +537,8 @@ * @padding1: reserved for future, zeroes * @type: type of the target inode (%UBIFS_ITYPE_REG, %UBIFS_ITYPE_DIR, etc) * @nlen: name length - * @padding2: reserved for future, zeroes + * @cookie: A 32bits random number, used to construct a 64bits + * identifier. * @name: zero-terminated name * * Note, do not forget to amend 'zero_dent_node_unused()' function when @@ -523,8 +551,8 @@ __u8 padding1; __u8 type; __le16 nlen; - __u8 padding2[4]; /* Watch 'zero_dent_node_unused()' if changing! */ - char name[]; + __le32 cookie; + __u8 name[]; } __packed; /** @@ -533,18 +561,16 @@ * @key: node key * @size: uncompressed data size in bytes * @compr_type: compression type (%UBIFS_COMPR_NONE, %UBIFS_COMPR_LZO, etc) - * @padding: reserved for future, zeroes + * @compr_size: compressed data size in bytes, only valid when data is encrypted * @data: data * - * Note, do not forget to amend 'zero_data_node_unused()' function when - * changing the padding fields. */ struct ubifs_data_node { struct ubifs_ch ch; __u8 key[UBIFS_MAX_KEY_LEN]; __le32 size; __le16 compr_type; - __u8 padding[2]; /* Watch 'zero_data_node_unused()' if changing! */ + __le16 compr_size; __u8 data[]; } __packed; @@ -731,7 +757,7 @@ __le32 lnum; __le32 offs; __le32 len; - char key[]; + __u8 key[]; } __packed; /** @@ -745,7 +771,7 @@ struct ubifs_ch ch; __le16 child_cnt; __le16 level; - char branches[]; + __u8 branches[]; } __packed; /** diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 9961273..11fb318 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -23,6 +23,8 @@ #include +struct task_struct *current; + struct ubifs_priv { struct cdev *cdev; struct ubi_volume_desc *ubi; @@ -262,7 +264,7 @@ return err; } - ubifs_assert(le64_to_cpu(dn->ch.sqnum) > ubifs_inode(inode)->creat_sqnum); + ubifs_assert(c, le64_to_cpu(dn->ch.sqnum) > ubifs_inode(inode)->creat_sqnum); len = le32_to_cpu(dn->size); if (len <= 0 || len > UBIFS_BLOCK_SIZE) diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index b3ad054..900cc31 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -3,10 +3,18 @@ * * Copyright (C) 2006-2008 Nokia Corporation * - * (C) Copyright 2008-2009 - * Stefan Roese, DENX Software Engineering, sr@denx.de. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. * - * SPDX-License-Identifier: GPL-2.0+ + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -20,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -29,59 +38,29 @@ #include #include #include + +#define __FS_HAS_ENCRYPTION 0 +#include + #include "ubifs-media.h" #define crc32(seed, data, length) crc32_no_comp(seed, (unsigned char const *)data, length) -struct file; struct iattr; struct kstat; -struct page; /* uapi/linux/limits.h */ #define XATTR_LIST_MAX 65536 /* size of extended attribute namelist (64k) */ -/* - * get_seconds() not really needed in the read-only implmentation - */ -#define get_seconds() 0 - -/* debug.c */ - /* Version of this UBIFS implementation */ #define UBIFS_VERSION 1 -/* Normal UBIFS messages */ -#define ubifs_msg(c, fmt, ...) \ - pr_notice("UBIFS (ubi%d:%d): " fmt "\n", \ - (c)->vi.ubi_num, (c)->vi.vol_id, ##__VA_ARGS__) -/* UBIFS error messages */ -#define ubifs_err(c, fmt, ...) \ - pr_err("UBIFS error (ubi%d:%d pid %d): %s: " fmt "\n", \ - (c)->vi.ubi_num, (c)->vi.vol_id, 0, \ - __func__, ##__VA_ARGS__) -/* UBIFS warning messages */ -#define ubifs_warn(c, fmt, ...) \ - pr_warn("UBIFS warning (ubi%d:%d pid %d): %s: " fmt "\n", \ - (c)->vi.ubi_num, (c)->vi.vol_id, 0, \ - __func__, ##__VA_ARGS__) - -/* - * A variant of 'ubifs_err()' which takes the UBIFS file-sytem description - * object as an argument. - */ -#define ubifs_errc(c, fmt, ...) \ - do { \ - if (!(c)->probing) \ - ubifs_err(c, fmt, ##__VA_ARGS__); \ - } while (0) - /* UBIFS file system VFS magic number */ #define UBIFS_SUPER_MAGIC 0x24051905 /* Number of UBIFS blocks per VFS page */ -#define UBIFS_BLOCKS_PER_PAGE (PAGE_CACHE_SIZE / UBIFS_BLOCK_SIZE) -#define UBIFS_BLOCKS_PER_PAGE_SHIFT (PAGE_CACHE_SHIFT - UBIFS_BLOCK_SHIFT) +#define UBIFS_BLOCKS_PER_PAGE (PAGE_SIZE / UBIFS_BLOCK_SIZE) +#define UBIFS_BLOCKS_PER_PAGE_SHIFT (PAGE_SHIFT - UBIFS_BLOCK_SHIFT) /* "File system end of life" sequence number watermark */ #define SQNUM_WARN_WATERMARK 0xFFFFFFFF00000000ULL @@ -116,10 +95,6 @@ */ #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" -/* Write-buffer synchronization timeout interval in seconds */ -#define WBUF_TIMEOUT_SOFTLIMIT 3 -#define WBUF_TIMEOUT_HARDLIMIT 5 - /* Maximum possible inode number (only 32-bit inodes are supported now) */ #define MAX_INUM 0xFFFFFFFF @@ -171,6 +146,12 @@ */ #define WORST_COMPR_FACTOR 2 +#ifdef CONFIG_UBIFS_FS_ENCRYPTION +#define UBIFS_CIPHER_BLOCK_SIZE FS_CRYPTO_BLOCK_SIZE +#else +#define UBIFS_CIPHER_BLOCK_SIZE 0 +#endif + /* * How much memory is needed for a buffer where we compress a data node. */ @@ -190,6 +171,7 @@ WB_MUTEX_1 = 0, WB_MUTEX_2 = 1, WB_MUTEX_3 = 2, + WB_MUTEX_4 = 3, }; /* @@ -283,6 +265,18 @@ LEB_RETAINED, }; +/* + * Action taken upon a failed ubifs_assert(). + * @ASSACT_REPORT: just report the failed assertion + * @ASSACT_RO: switch to read-only mode + * @ASSACT_PANIC: call BUG() and possible panic the kernel + */ +enum { + ASSACT_REPORT = 0, + ASSACT_RO, + ASSACT_PANIC, +}; + /** * struct ubifs_old_idx - index node obsoleted since last commit start. * @rb: rb-tree node @@ -677,9 +671,6 @@ * @io_mutex: serializes write-buffer I/O * @lock: serializes @buf, @lnum, @offs, @avail, @used, @next_ino and @inodes * fields - * @softlimit: soft write-buffer timeout interval - * @delta: hard and soft timeouts delta (the timer expire interval is @softlimit - * and @softlimit + @delta) * @timer: write-buffer timer * @no_timer: non-zero if this write-buffer does not have a timer * @need_sync: non-zero if the timer expired and the wbuf needs sync'ing @@ -708,9 +699,6 @@ int (*sync_callback)(struct ubifs_info *c, int lnum, int free, int pad); struct mutex io_mutex; spinlock_t lock; -// ktime_t softlimit; -// unsigned long long delta; -// struct hrtimer timer; unsigned int no_timer:1; unsigned int need_sync:1; int next_ino; @@ -788,7 +776,6 @@ struct ubifs_znode *parent; struct ubifs_znode *cnext; unsigned long flags; - unsigned long time; int level; int child_cnt; int iip; @@ -870,9 +857,9 @@ * @mod_dent: non-zero if the operation removes or modifies an existing * directory entry * @new_ino: non-zero if the operation adds a new inode - * @new_ino_d: now much data newly created inode contains + * @new_ino_d: how much data newly created inode contains * @dirtied_ino: how many inodes the operation makes dirty - * @dirtied_ino_d: now much data dirtied inode contains + * @dirtied_ino_d: how much data dirtied inode contains * @idx_growth: how much the index will supposedly grow * @data_growth: how much new data the operation will supposedly add * @dd_growth: how much data that makes other data dirty the operation will @@ -1003,7 +990,6 @@ * struct ubifs_info - UBIFS file-system description data structure * (per-superblock). * @vfs_sb: VFS @struct super_block object - * @bdi: backing device info object to make VFS happy and disable read-ahead * * @highest_inum: highest used inode number * @max_sqnum: current global sequence number @@ -1041,11 +1027,14 @@ * * @big_lpt: flag that LPT is too big to write whole during commit * @space_fixup: flag indicating that free space in LEBs needs to be cleaned up + * @double_hash: flag indicating that we can do lookups by hash + * @encrypted: flag indicating that this file system contains encrypted files * @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) * @rw_incompat: the media is not R/W compatible + * @assert_action: action to take when a ubifs_assert() fails * * @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and * @calc_idx_sz @@ -1232,12 +1221,11 @@ * @need_recovery: %1 if the file-system needs recovery * @replaying: %1 during journal replay * @mounting: %1 while mounting - * @probing: %1 while attempting to mount if MS_SILENT mount flag is set + * @probing: %1 while attempting to mount if SB_SILENT mount flag is set * @remounting_rw: %1 while re-mounting from R/O mode to R/W mode * @replay_list: temporary list used during journal replay * @replay_buds: list of buds to replay * @cs_sqnum: sequence number of first node in the log (commit start node) - * @replay_sqnum: sequence number of node currently being replayed * @unclean_leb_list: LEBs to recover when re-mounting R/O mounted FS to R/W * mode * @rcvrd_mst_node: recovered master node to write when re-mounting R/O mounted @@ -1249,6 +1237,7 @@ */ struct ubifs_info { struct super_block *vfs_sb; + ino_t highest_inum; unsigned long long max_sqnum; unsigned long long cmt_no; @@ -1281,10 +1270,13 @@ unsigned int big_lpt:1; unsigned int space_fixup:1; + unsigned int double_hash:1; + unsigned int encrypted:1; unsigned int no_chk_data_crc:1; unsigned int bulk_read:1; unsigned int default_compr:2; unsigned int rw_incompat:1; + unsigned int assert_action:2; struct mutex tnc_mutex; struct ubifs_zbranch zroot; @@ -1466,28 +1458,25 @@ struct list_head replay_list; struct list_head replay_buds; unsigned long long cs_sqnum; - unsigned long long replay_sqnum; struct list_head unclean_leb_list; struct ubifs_mst_node *rcvrd_mst_node; struct rb_root size_tree; struct ubifs_mount_opts mount_opts; struct device_d *dev; + struct ubifs_debug_info *dbg; }; extern struct list_head ubifs_infos; extern spinlock_t ubifs_infos_lock; extern atomic_long_t ubifs_clean_zn_cnt; -extern struct kmem_cache *ubifs_inode_slab; extern const struct super_operations ubifs_super_operations; -extern const struct xattr_handler *ubifs_xattr_handlers[]; extern const struct address_space_operations ubifs_file_address_operations; extern const struct file_operations ubifs_file_operations; extern const struct inode_operations ubifs_file_inode_operations; extern const struct file_operations ubifs_dir_operations; extern const struct inode_operations ubifs_dir_inode_operations; extern const struct inode_operations ubifs_symlink_inode_operations; -extern struct backing_dev_info ubifs_backing_dev_info; extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; /* io.c */ @@ -1548,20 +1537,29 @@ /* journal.c */ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, - const struct qstr *nm, const struct inode *inode, + const struct fscrypt_name *nm, const struct inode *inode, int deletion, int xent); int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, const union ubifs_key *key, const void *buf, int len); int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode); int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode); +int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir, + const struct inode *fst_inode, + const struct fscrypt_name *fst_nm, + const struct inode *snd_dir, + const struct inode *snd_inode, + const struct fscrypt_name *snd_nm, int sync); int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, - const struct dentry *old_dentry, + const struct inode *old_inode, + const struct fscrypt_name *old_nm, const struct inode *new_dir, - const struct dentry *new_dentry, int sync); + const struct inode *new_inode, + const struct fscrypt_name *new_nm, + const struct inode *whiteout, int sync); int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, loff_t old_size, loff_t new_size); int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, - const struct inode *inode, const struct qstr *nm); + const struct inode *inode, const struct fscrypt_name *nm); int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode1, const struct inode *inode2); @@ -1596,7 +1594,9 @@ int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key, struct ubifs_znode **zn, int *n); int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key, - void *node, const struct qstr *nm); + void *node, const struct fscrypt_name *nm); +int ubifs_tnc_lookup_dh(struct ubifs_info *c, const union ubifs_key *key, + void *node, uint32_t secondary_hash); int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key, void *node, int *lnum, int *offs); int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum, @@ -1604,16 +1604,18 @@ int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key, int old_lnum, int old_offs, int lnum, int offs, int len); int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key, - int lnum, int offs, int len, const struct qstr *nm); + int lnum, int offs, int len, const struct fscrypt_name *nm); int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key); int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key, - const struct qstr *nm); + const struct fscrypt_name *nm); +int ubifs_tnc_remove_dh(struct ubifs_info *c, const union ubifs_key *key, + uint32_t cookie); int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key, union ubifs_key *to_key); int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum); struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c, union ubifs_key *key, - const struct qstr *nm); + const struct fscrypt_name *nm); void ubifs_tnc_close(struct ubifs_info *c); int ubifs_tnc_has_node(struct ubifs_info *c, union ubifs_key *key, int level, int lnum, int offs, int is_idx); @@ -1628,14 +1630,17 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu); /* tnc_misc.c */ -struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr, +struct ubifs_znode *ubifs_tnc_levelorder_next(const struct ubifs_info *c, + struct ubifs_znode *zr, struct ubifs_znode *znode); int ubifs_search_zbranch(const struct ubifs_info *c, const struct ubifs_znode *znode, const union ubifs_key *key, int *n); struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode); -struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode); -long ubifs_destroy_tnc_subtree(struct ubifs_znode *zr); +struct ubifs_znode *ubifs_tnc_postorder_next(const struct ubifs_info *c, + struct ubifs_znode *znode); +long ubifs_destroy_tnc_subtree(const struct ubifs_info *c, + struct ubifs_znode *zr); struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c, struct ubifs_zbranch *zbr, struct ubifs_znode *parent, int iip); @@ -1646,7 +1651,6 @@ int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot); int ubifs_tnc_end_commit(struct ubifs_info *c); - /* commit.c */ int ubifs_bg_thread(void *info); void ubifs_commit_required(struct ubifs_info *c); @@ -1665,6 +1669,7 @@ struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c); int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup); int ubifs_fixup_free_space(struct ubifs_info *c); +int ubifs_enable_encryption(struct ubifs_info *c); /* replay.c */ int ubifs_validate_entry(struct ubifs_info *c, @@ -1712,7 +1717,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip); void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty); void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode); -uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits); +uint32_t ubifs_unpack_bits(const struct ubifs_info *c, uint8_t **addr, int *pos, int nrbits); struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght); /* Needed only in debugging code in lpt_commit.c */ int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf, @@ -1751,26 +1756,46 @@ /* file.c */ int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync); int ubifs_setattr(struct dentry *dentry, struct iattr *attr); +#ifdef CONFIG_UBIFS_ATIME_SUPPORT +int ubifs_update_time(struct inode *inode, struct timespec64 *time, int flags); +#endif /* dir.c */ -struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, +struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir, umode_t mode); -int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat); +int ubifs_getattr(const struct path *path, struct kstat *stat, + u32 request_mask, unsigned int flags); +int ubifs_check_dir_empty(struct inode *dir); /* xattr.c */ -int ubifs_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, - size_t size); +extern const struct xattr_handler *ubifs_xattr_handlers[]; ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size); -int ubifs_removexattr(struct dentry *dentry, const char *name); -int ubifs_init_security(struct inode *dentry, struct inode *inode, +int ubifs_xattr_set(struct inode *host, const char *name, const void *value, + size_t size, int flags, bool check_lock); +ssize_t ubifs_xattr_get(struct inode *host, const char *name, void *buf, + size_t size); + +#ifdef CONFIG_UBIFS_FS_XATTR +void ubifs_evict_xattr_inode(struct ubifs_info *c, ino_t xattr_inum); +#else +static inline void ubifs_evict_xattr_inode(struct ubifs_info *c, + ino_t xattr_inum) { } +#endif + +#ifdef CONFIG_UBIFS_FS_SECURITY +extern int ubifs_init_security(struct inode *dentry, struct inode *inode, const struct qstr *qstr); +#else +static inline int ubifs_init_security(struct inode *dentry, + struct inode *inode, const struct qstr *qstr) +{ + return 0; +} +#endif + /* super.c */ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum); -int ubifs_iput(struct inode *inode); /* recovery.c */ int ubifs_recover_master_node(struct ubifs_info *c); @@ -1806,7 +1831,61 @@ #include "misc.h" #include "key.h" +/* barebox specific */ void ubifs_umount(struct ubifs_info *c); +/* barebox specific */ int ubifs_get_super(struct device_d *dev, struct ubi_volume_desc *ubi, int silent); +#ifndef CONFIG_UBIFS_FS_ENCRYPTION +static inline int ubifs_encrypt(const struct inode *inode, + struct ubifs_data_node *dn, + unsigned int in_len, unsigned int *out_len, + int block) +{ + struct ubifs_info *c = inode->i_sb->s_fs_info; + ubifs_assert(c, 0); + return -EOPNOTSUPP; +} +static inline int ubifs_decrypt(const struct inode *inode, + struct ubifs_data_node *dn, + unsigned int *out_len, int block) +{ + struct ubifs_info *c = inode->i_sb->s_fs_info; + ubifs_assert(c, 0); + return -EOPNOTSUPP; +} +#else +/* crypto.c */ +int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn, + unsigned int in_len, unsigned int *out_len, int block); +int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn, + unsigned int *out_len, int block); +#endif + +extern const struct fscrypt_operations ubifs_crypt_operations; + +static inline bool ubifs_crypt_is_encrypted(const struct inode *inode) +{ + const struct ubifs_inode *ui = ubifs_inode(inode); + + return ui->flags & UBIFS_CRYPT_FL; +} + +/* Normal UBIFS messages */ +__printf(2, 3) +void ubifs_msg(const struct ubifs_info *c, const char *fmt, ...); +__printf(2, 3) +void ubifs_err(const struct ubifs_info *c, const char *fmt, ...); +__printf(2, 3) +void ubifs_warn(const struct ubifs_info *c, const char *fmt, ...); +/* + * A conditional variant of 'ubifs_err()' which doesn't output anything + * if probing (ie. SB_SILENT set). + */ +#define ubifs_errc(c, fmt, ...) \ +do { \ + if (!(c)->probing) \ + ubifs_err(c, fmt, ##__VA_ARGS__); \ +} while (0) + #endif /* !__UBIFS_H__ */