Unverified Commit c76d53de authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!9168 UBIFS: fixes a series of issues that caused by power cut

Merge Pull Request from: @ci-robot 
 
PR sync from: Wang Zhaolong <wangzhaolong1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/Y67CN3VMW5M5OI7GFOVJEGQX2NMQEVGL/ 
Yang Li (1):
  ubifs: Fix some kernel-doc comments

Zheng Yongjun (1):
  ubifs: Fix spelling mistakes

Zhihao Cheng (8):
  ubifs: Fix unattached xattr inode if powercut happens after deleting
  ubifs: Don't add xattr inode into orphan area
  ubifs: Remove insert_dead_orphan from replaying orphan process
  ubifs: Fix adding orphan entry twice for the same inode
  ubifs: Move ui->data initialization after initializing security
  ubifs: Fix space leak when powercut happens in linking tmpfile
  ubifs: Fix unattached inode when powercut happens in creating
  ubifs: dbg_orphan_check: Fix missed key type checking


-- 
2.34.3
 
https://gitee.com/openeuler/kernel/issues/I9MWEQ 
 
Link:https://gitee.com/openeuler/kernel/pulls/9168

 

Reviewed-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 53f0a815 b35c31e4
Loading
Loading
Loading
Loading
+53 −36
Original line number Diff line number Diff line
@@ -71,8 +71,13 @@ static int inherit_flags(const struct inode *dir, umode_t mode)
 * @is_xattr: whether the inode is xattr inode
 *
 * This function finds an unused inode number, allocates new inode and
 * initializes it. Returns new inode in case of success and an error code in
 * case of failure.
 * initializes it. Non-xattr new inode may be written with xattrs(selinux/
 * encryption) before writing dentry, which could cause inconsistent problem
 * when powercut happens between two operations. To deal with it, non-xattr
 * new inode is initialized with zero-nlink and added into orphan list, caller
 * should make sure that inode is relinked later, and make sure that orphan
 * removing and journal writing into an committing atomic operation. Returns
 * new inode in case of success and an error code in case of failure.
 */
struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
			      umode_t mode, bool is_xattr)
@@ -164,9 +169,25 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
	ui->creat_sqnum = ++c->max_sqnum;
	spin_unlock(&c->cnt_lock);

	if (!is_xattr) {
		set_nlink(inode, 0);
		err = ubifs_add_orphan(c, inode->i_ino);
		if (err) {
			ubifs_err(c, "ubifs_add_orphan failed: %i", err);
			goto out_iput;
		}
		down_read(&c->commit_sem);
		ui->del_cmtno = c->cmt_no;
		up_read(&c->commit_sem);
	}

	if (encrypted) {
		err = fscrypt_set_context(inode, NULL);
		if (err) {
			if (!is_xattr) {
				set_nlink(inode, 1);
				ubifs_delete_orphan(c, inode->i_ino);
			}
			ubifs_err(c, "fscrypt_set_context failed: %i", err);
			goto out_iput;
		}
@@ -321,11 +342,12 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
	if (err)
		goto out_inode;

	set_nlink(inode, 1);
	mutex_lock(&dir_ui->ui_mutex);
	dir->i_size += sz_change;
	dir_ui->ui_size = dir->i_size;
	dir->i_mtime = dir->i_ctime = inode->i_ctime;
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1);
	if (err)
		goto out_cancel;
	mutex_unlock(&dir_ui->ui_mutex);
@@ -340,8 +362,8 @@ static int ubifs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
	dir->i_size -= sz_change;
	dir_ui->ui_size = dir->i_size;
	mutex_unlock(&dir_ui->ui_mutex);
	set_nlink(inode, 0);
out_inode:
	make_bad_inode(inode);
	iput(inode);
out_fname:
	fscrypt_free_filename(&nm);
@@ -386,7 +408,6 @@ static struct inode *create_whiteout(struct inode *dir, struct dentry *dentry)
	return inode;

out_inode:
	make_bad_inode(inode);
	iput(inode);
out_free:
	ubifs_err(c, "cannot create whiteout file, error %d", err);
@@ -469,6 +490,7 @@ static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry,
	if (err)
		goto out_inode;

	set_nlink(inode, 1);
	mutex_lock(&ui->ui_mutex);
	insert_inode_hash(inode);
	d_tmpfile(dentry, inode);
@@ -478,7 +500,7 @@ static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry,
	mutex_unlock(&ui->ui_mutex);

	lock_2_inodes(dir, inode);
	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 1);
	if (err)
		goto out_cancel;
	unlock_2_inodes(dir, inode);
@@ -491,7 +513,6 @@ static int ubifs_tmpfile(struct inode *dir, struct dentry *dentry,
out_cancel:
	unlock_2_inodes(dir, inode);
out_inode:
	make_bad_inode(inode);
	if (!instantiated)
		iput(inode);
out_budg:
@@ -759,17 +780,13 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,

	lock_2_inodes(dir, inode);

	/* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */
	if (inode->i_nlink == 0)
		ubifs_delete_orphan(c, inode->i_ino);

	inc_nlink(inode);
	ihold(inode);
	inode->i_ctime = current_time(inode);
	dir->i_size += sz_change;
	dir_ui->ui_size = dir->i_size;
	dir->i_mtime = dir->i_ctime = inode->i_ctime;
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0, inode->i_nlink == 1);
	if (err)
		goto out_cancel;
	unlock_2_inodes(dir, inode);
@@ -783,8 +800,6 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
	dir->i_size -= sz_change;
	dir_ui->ui_size = dir->i_size;
	drop_nlink(inode);
	if (inode->i_nlink == 0)
		ubifs_add_orphan(c, inode->i_ino);
	unlock_2_inodes(dir, inode);
	ubifs_release_budget(c, &req);
	iput(inode);
@@ -843,7 +858,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
	dir->i_size -= sz_change;
	dir_ui->ui_size = dir->i_size;
	dir->i_mtime = dir->i_ctime = inode->i_ctime;
	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 0);
	if (err)
		goto out_cancel;
	unlock_2_inodes(dir, inode);
@@ -946,7 +961,7 @@ static int ubifs_rmdir(struct inode *dir, struct dentry *dentry)
	dir->i_size -= sz_change;
	dir_ui->ui_size = dir->i_size;
	dir->i_mtime = dir->i_ctime = inode->i_ctime;
	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 1, 0, 0);
	if (err)
		goto out_cancel;
	unlock_2_inodes(dir, inode);
@@ -1012,6 +1027,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	if (err)
		goto out_inode;

	set_nlink(inode, 1);
	mutex_lock(&dir_ui->ui_mutex);
	insert_inode_hash(inode);
	inc_nlink(inode);
@@ -1019,7 +1035,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	dir->i_size += sz_change;
	dir_ui->ui_size = dir->i_size;
	dir->i_mtime = dir->i_ctime = inode->i_ctime;
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1);
	if (err) {
		ubifs_err(c, "cannot create directory, error %d", err);
		goto out_cancel;
@@ -1036,8 +1052,8 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	dir_ui->ui_size = dir->i_size;
	drop_nlink(dir);
	mutex_unlock(&dir_ui->ui_mutex);
	set_nlink(inode, 0);
out_inode:
	make_bad_inode(inode);
	iput(inode);
out_fname:
	fscrypt_free_filename(&nm);
@@ -1096,21 +1112,24 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
		goto out_fname;
	}

	err = ubifs_init_security(dir, inode, &dentry->d_name);
	if (err) {
		kfree(dev);
		goto out_inode;
	}

	init_special_inode(inode, inode->i_mode, rdev);
	inode->i_size = ubifs_inode(inode)->ui_size = devlen;
	ui = ubifs_inode(inode);
	ui->data = dev;
	ui->data_len = devlen;

	err = ubifs_init_security(dir, inode, &dentry->d_name);
	if (err)
		goto out_inode;
	set_nlink(inode, 1);

	mutex_lock(&dir_ui->ui_mutex);
	dir->i_size += sz_change;
	dir_ui->ui_size = dir->i_size;
	dir->i_mtime = dir->i_ctime = inode->i_ctime;
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1);
	if (err)
		goto out_cancel;
	mutex_unlock(&dir_ui->ui_mutex);
@@ -1125,8 +1144,8 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry,
	dir->i_size -= sz_change;
	dir_ui->ui_size = dir->i_size;
	mutex_unlock(&dir_ui->ui_mutex);
	set_nlink(inode, 0);
out_inode:
	make_bad_inode(inode);
	iput(inode);
out_fname:
	fscrypt_free_filename(&nm);
@@ -1177,6 +1196,10 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
		goto out_fname;
	}

	err = ubifs_init_security(dir, inode, &dentry->d_name);
	if (err)
		goto out_inode;

	ui = ubifs_inode(inode);
	ui->data = kmalloc(disk_link.len, GFP_NOFS);
	if (!ui->data) {
@@ -1201,16 +1224,13 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
	 */
	ui->data_len = disk_link.len - 1;
	inode->i_size = ubifs_inode(inode)->ui_size = disk_link.len - 1;

	err = ubifs_init_security(dir, inode, &dentry->d_name);
	if (err)
		goto out_inode;
	set_nlink(inode, 1);

	mutex_lock(&dir_ui->ui_mutex);
	dir->i_size += sz_change;
	dir_ui->ui_size = dir->i_size;
	dir->i_mtime = dir->i_ctime = inode->i_ctime;
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0);
	err = ubifs_jnl_update(c, dir, &nm, inode, 0, 0, 1);
	if (err)
		goto out_cancel;
	mutex_unlock(&dir_ui->ui_mutex);
@@ -1224,10 +1244,10 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry,
	dir->i_size -= sz_change;
	dir_ui->ui_size = dir->i_size;
	mutex_unlock(&dir_ui->ui_mutex);
	set_nlink(inode, 0);
out_inode:
	/* Free inode->i_link before inode is marked as bad. */
	fscrypt_free_inode(inode);
	make_bad_inode(inode);
	iput(inode);
out_fname:
	fscrypt_free_filename(&nm);
@@ -1396,14 +1416,10 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
		 */
		err = ubifs_budget_space(c, &wht_req);
		if (err) {
			/*
			 * Whiteout inode can not be written on flash by
			 * ubifs_jnl_write_inode(), because it's neither
			 * dirty nor zero-nlink.
			 */
			iput(whiteout);
			goto out_release;
		}
		set_nlink(whiteout, 1);

		/* Add the old_dentry size to the old_dir size. */
		old_sz -= CALC_DENT_SIZE(fname_len(&old_nm));
@@ -1486,7 +1502,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
	}

	err = ubifs_jnl_rename(c, old_dir, old_inode, &old_nm, new_dir,
			       new_inode, &new_nm, whiteout, sync);
			       new_inode, &new_nm, whiteout, sync, !!whiteout);
	if (err)
		goto out_cancel;

@@ -1539,6 +1555,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
	unlock_4_inodes(old_dir, new_dir, new_inode, whiteout);
	if (whiteout) {
		ubifs_release_budget(c, &wht_req);
		set_nlink(whiteout, 0);
		iput(whiteout);
	}
out_release:
+18 −6
Original line number Diff line number Diff line
@@ -643,6 +643,7 @@ static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent)
 * @inode: inode to update
 * @deletion: indicates a directory entry deletion i.e unlink or rmdir
 * @xent: non-zero if the directory entry is an extended attribute entry
 * @in_orphan: indicates whether the @inode is in orphan list
 *
 * This function updates an inode by writing a directory entry (or extended
 * attribute entry), the inode itself, and the parent directory inode (or the
@@ -664,7 +665,7 @@ static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent)
 */
int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
		     const struct fscrypt_name *nm, const struct inode *inode,
		     int deletion, int xent)
		     int deletion, int xent, int in_orphan)
{
	int err, dlen, ilen, len, lnum, ino_offs, dent_offs, orphan_added = 0;
	int aligned_dlen, aligned_ilen, sync = IS_DIRSYNC(dir);
@@ -750,7 +751,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
	if (err)
		goto out_release;

	if (last_reference) {
	if (last_reference && !in_orphan) {
		err = ubifs_add_orphan(c, inode->i_ino);
		if (err) {
			release_head(c, BASEHD);
@@ -806,6 +807,9 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
	if (err)
		goto out_ro;

	if (in_orphan && inode->i_nlink)
		ubifs_delete_orphan(c, inode->i_ino);

	finish_reservation(c);
	spin_lock(&ui->ui_lock);
	ui->synced_i_size = ui->ui_size;
@@ -1328,10 +1332,15 @@ int ubifs_jnl_xrename(struct ubifs_info *c, const struct inode *fst_dir,
 * ubifs_jnl_rename - rename a directory entry.
 * @c: UBIFS file-system description object
 * @old_dir: parent inode of directory entry to rename
 * @old_dentry: directory entry to rename
 * @old_inode: directory entry's inode to rename
 * @old_nm: name of the old directory entry to rename
 * @new_dir: parent inode of directory entry to rename
 * @new_dentry: new directory entry (or directory entry to replace)
 * @new_inode: new directory entry's inode (or directory entry's inode to
 *		replace)
 * @new_nm: new name of the new directory entry
 * @whiteout: whiteout inode
 * @sync: non-zero if the write-buffer has to be synchronized
 * @delete_orphan: indicates an orphan entry deletion for @whiteout
 *
 * This function implements the re-name operation which may involve writing up
 * to 4 inodes(new inode, whiteout inode, old and new parent directory inodes)
@@ -1344,7 +1353,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
		     const struct inode *new_dir,
		     const struct inode *new_inode,
		     const struct fscrypt_name *new_nm,
		     const struct inode *whiteout, int sync)
		     const struct inode *whiteout, int sync, int delete_orphan)
{
	void *p;
	union ubifs_key key;
@@ -1561,6 +1570,9 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
			goto out_ro;
	}

	if (delete_orphan)
		ubifs_delete_orphan(c, whiteout->i_ino);

	finish_reservation(c);
	if (new_inode) {
		mark_inode_clean(c, new_ui);
@@ -1595,7 +1607,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,
/**
 * truncate_data_node - re-compress/encrypt a truncated data node.
 * @c: UBIFS file-system description object
 * @inode: inode which referes to the data node
 * @inode: inode which refers to the data node
 * @block: data block number
 * @dn: data node to re-compress
 * @new_len: new length
+25 −130
Original line number Diff line number Diff line
@@ -42,24 +42,30 @@

static int dbg_check_orphans(struct ubifs_info *c);

static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum,
				       struct ubifs_orphan *parent_orphan)
/**
 * ubifs_add_orphan - add an orphan.
 * @c: UBIFS file-system description object
 * @inum: orphan inode number
 *
 * Add an orphan. This function is called when an inodes link count drops to
 * zero.
 */
int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
{
	struct ubifs_orphan *orphan, *o;
	struct rb_node **p, *parent = NULL;

	orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS);
	if (!orphan)
		return ERR_PTR(-ENOMEM);
		return -ENOMEM;
	orphan->inum = inum;
	orphan->new = 1;
	INIT_LIST_HEAD(&orphan->child_list);

	spin_lock(&c->orphan_lock);
	if (c->tot_orphans >= c->max_orphans) {
		spin_unlock(&c->orphan_lock);
		kfree(orphan);
		return ERR_PTR(-ENFILE);
		return -ENFILE;
	}
	p = &c->orph_tree.rb_node;
	while (*p) {
@@ -73,7 +79,7 @@ static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum,
			ubifs_err(c, "orphaned twice");
			spin_unlock(&c->orphan_lock);
			kfree(orphan);
			return ERR_PTR(-EINVAL);
			return -EINVAL;
		}
	}
	c->tot_orphans += 1;
@@ -83,14 +89,9 @@ static struct ubifs_orphan *orphan_add(struct ubifs_info *c, ino_t inum,
	list_add_tail(&orphan->list, &c->orph_list);
	list_add_tail(&orphan->new_list, &c->orph_new);

	if (parent_orphan) {
		list_add_tail(&orphan->child_list,
			      &parent_orphan->child_list);
	}

	spin_unlock(&c->orphan_lock);
	dbg_gen("ino %lu", (unsigned long)inum);
	return orphan;
	return 0;
}

static struct ubifs_orphan *lookup_orphan(struct ubifs_info *c, ino_t inum)
@@ -135,6 +136,7 @@ static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)

	if (orph->cmt) {
		orph->del = 1;
		rb_erase(&orph->rb, &c->orph_tree);
		orph->dnext = c->orph_dnext;
		c->orph_dnext = orph;
		dbg_gen("delete later ino %lu", (unsigned long)orph->inum);
@@ -144,59 +146,6 @@ static void orphan_delete(struct ubifs_info *c, struct ubifs_orphan *orph)
	__orphan_drop(c, orph);
}

/**
 * ubifs_add_orphan - add an orphan.
 * @c: UBIFS file-system description object
 * @inum: orphan inode number
 *
 * Add an orphan. This function is called when an inodes link count drops to
 * zero.
 */
int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
{
	int err = 0;
	ino_t xattr_inum;
	union ubifs_key key;
	struct ubifs_dent_node *xent, *pxent = NULL;
	struct fscrypt_name nm = {0};
	struct ubifs_orphan *xattr_orphan;
	struct ubifs_orphan *orphan;

	orphan = orphan_add(c, inum, NULL);
	if (IS_ERR(orphan))
		return PTR_ERR(orphan);

	lowest_xent_key(c, &key, inum);
	while (1) {
		xent = ubifs_tnc_next_ent(c, &key, &nm);
		if (IS_ERR(xent)) {
			err = PTR_ERR(xent);
			if (err == -ENOENT)
				break;
			kfree(pxent);
			return err;
		}

		fname_name(&nm) = xent->name;
		fname_len(&nm) = le16_to_cpu(xent->nlen);
		xattr_inum = le64_to_cpu(xent->inum);

		xattr_orphan = orphan_add(c, xattr_inum, orphan);
		if (IS_ERR(xattr_orphan)) {
			kfree(pxent);
			kfree(xent);
			return PTR_ERR(xattr_orphan);
		}

		kfree(pxent);
		pxent = xent;
		key_read(c, &xent->key, &key);
	}
	kfree(pxent);

	return 0;
}

/**
 * ubifs_delete_orphan - delete an orphan.
 * @c: UBIFS file-system description object
@@ -206,7 +155,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum)
 */
void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
{
	struct ubifs_orphan *orph, *child_orph, *tmp_o;
	struct ubifs_orphan *orph;

	spin_lock(&c->orphan_lock);

@@ -219,11 +168,6 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum)
		return;
	}

	list_for_each_entry_safe(child_orph, tmp_o, &orph->child_list, child_list) {
		list_del(&child_orph->child_list);
		orphan_delete(c, child_orph);
	}
	
	orphan_delete(c, orph);

	spin_unlock(&c->orphan_lock);
@@ -518,7 +462,6 @@ static void erase_deleted(struct ubifs_info *c)
		dnext = orphan->dnext;
		ubifs_assert(c, !orphan->new);
		ubifs_assert(c, orphan->del);
		rb_erase(&orphan->rb, &c->orph_tree);
		list_del(&orphan->list);
		c->tot_orphans -= 1;
		dbg_gen("deleting orphan ino %lu", (unsigned long)orphan->inum);
@@ -570,51 +513,6 @@ int ubifs_clear_orphans(struct ubifs_info *c)
	return 0;
}

/**
 * insert_dead_orphan - insert an orphan.
 * @c: UBIFS file-system description object
 * @inum: orphan inode number
 *
 * This function is a helper to the 'do_kill_orphans()' function. The orphan
 * must be kept until the next commit, so it is added to the rb-tree and the
 * deletion list.
 */
static int insert_dead_orphan(struct ubifs_info *c, ino_t inum)
{
	struct ubifs_orphan *orphan, *o;
	struct rb_node **p, *parent = NULL;

	orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_KERNEL);
	if (!orphan)
		return -ENOMEM;
	orphan->inum = inum;

	p = &c->orph_tree.rb_node;
	while (*p) {
		parent = *p;
		o = rb_entry(parent, struct ubifs_orphan, rb);
		if (inum < o->inum)
			p = &(*p)->rb_left;
		else if (inum > o->inum)
			p = &(*p)->rb_right;
		else {
			/* Already added - no problem */
			kfree(orphan);
			return 0;
		}
	}
	c->tot_orphans += 1;
	rb_link_node(&orphan->rb, parent, p);
	rb_insert_color(&orphan->rb, &c->orph_tree);
	list_add_tail(&orphan->list, &c->orph_list);
	orphan->del = 1;
	orphan->dnext = c->orph_dnext;
	c->orph_dnext = orphan;
	dbg_mnt("ino %lu, new %d, tot %d", (unsigned long)inum,
		c->new_orphans, c->tot_orphans);
	return 0;
}

/**
 * do_kill_orphans - remove orphan inodes from the index.
 * @c: UBIFS file-system description object
@@ -691,12 +589,12 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,

		n = (le32_to_cpu(orph->ch.len) - UBIFS_ORPH_NODE_SZ) >> 3;
		for (i = 0; i < n; i++) {
			union ubifs_key key1, key2;
			union ubifs_key key;

			inum = le64_to_cpu(orph->inos[i]);

			ino_key_init(c, &key1, inum);
			err = ubifs_tnc_lookup(c, &key1, ino);
			ino_key_init(c, &key, inum);
			err = ubifs_tnc_lookup(c, &key, ino);
			if (err && err != -ENOENT)
				goto out_free;

@@ -708,17 +606,10 @@ static int do_kill_orphans(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
				dbg_rcvry("deleting orphaned inode %lu",
					  (unsigned long)inum);

				lowest_ino_key(c, &key1, inum);
				highest_ino_key(c, &key2, inum);

				err = ubifs_tnc_remove_range(c, &key1, &key2);
				err = ubifs_tnc_remove_ino(c, inum);
				if (err)
					goto out_ro;
			}

			err = insert_dead_orphan(c, inum);
			if (err)
				goto out_free;
		}

		*last_cmt_no = cmt_no;
@@ -925,8 +816,12 @@ static int dbg_orphan_check(struct ubifs_info *c, struct ubifs_zbranch *zbr,

	inum = key_inum(c, &zbr->key);
	if (inum != ci->last_ino) {
		/* Lowest node type is the inode node, so it comes first */
		if (key_type(c, &zbr->key) != UBIFS_INO_KEY)
		/*
		 * Lowest node type is the inode node or xattr entry(when
		 * selinux/encryption is enabled), so it comes first
		 */
		if (key_type(c, &zbr->key) != UBIFS_INO_KEY &&
		    key_type(c, &zbr->key) != UBIFS_XENT_KEY)
			ubifs_err(c, "found orphan node ino %lu, type %d",
				  (unsigned long)inum, key_type(c, &zbr->key));
		ci->last_ino = inum;
+1 −1
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ static int apply_replay_entry(struct ubifs_info *c, struct replay_entry *r)
 * @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
 * entries @a and @b by comparing their sequence number.  Returns %1 if @a has
 * greater sequence number and %-1 otherwise.
 */
static int replay_entries_cmp(void *priv, const struct list_head *a,
+1 −1
Original line number Diff line number Diff line
@@ -2069,7 +2069,7 @@ const struct super_operations ubifs_super_operations = {
 * @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 path. However, UBIFS may also be mounted without any
 * character device node using one of the following methods:
 *
 * o ubiX_Y    - mount UBI device number X, volume Y;
Loading