Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ff93abc authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'upstream-4.9-rc2' of git://git.infradead.org/linux-ubifs

Pull UBI[FS] fixes from Richard Weinberger:
 "This contains fixes for issues in both UBI and UBIFS:

   - Fallout from the merge window, refactoring UBI code introduced some
     issues.

   - Fixes for an UBIFS readdir bug which can cause getdents() to busy
     loop for ever and a bug in the UBIFS xattr code"

* tag 'upstream-4.9-rc2' of git://git.infradead.org/linux-ubifs:
  ubifs: Abort readdir upon error
  UBI: Fix crash in try_recover_peb()
  ubi: fix swapped arguments to call to ubi_alloc_aeb
  ubifs: Fix xattr_names length in exit paths
  ubifs: Rename ubifs_rename2
parents c761923c c83ed4c9
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -741,6 +741,7 @@ static int try_recover_peb(struct ubi_volume *vol, int pnum, int lnum,
		goto out_put;
		goto out_put;
	}
	}


	vid_hdr = ubi_get_vid_hdr(vidb);
	ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC);
	ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC);


	mutex_lock(&ubi->buf_mutex);
	mutex_lock(&ubi->buf_mutex);
+1 −1
Original line number Original line Diff line number Diff line
@@ -287,7 +287,7 @@ static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,


		/* new_aeb is newer */
		/* new_aeb is newer */
		if (cmp_res & 1) {
		if (cmp_res & 1) {
			victim = ubi_alloc_aeb(ai, aeb->ec, aeb->pnum);
			victim = ubi_alloc_aeb(ai, aeb->pnum, aeb->ec);
			if (!victim)
			if (!victim)
				return -ENOMEM;
				return -ENOMEM;


+9 −11
Original line number Original line Diff line number Diff line
@@ -439,7 +439,7 @@ static unsigned int vfs_dent_type(uint8_t type)
 */
 */
static int ubifs_readdir(struct file *file, struct dir_context *ctx)
static int ubifs_readdir(struct file *file, struct dir_context *ctx)
{
{
	int err;
	int err = 0;
	struct qstr nm;
	struct qstr nm;
	union ubifs_key key;
	union ubifs_key key;
	struct ubifs_dent_node *dent;
	struct ubifs_dent_node *dent;
@@ -541,14 +541,12 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
	kfree(file->private_data);
	kfree(file->private_data);
	file->private_data = NULL;
	file->private_data = NULL;


	if (err != -ENOENT) {
	if (err != -ENOENT)
		ubifs_err(c, "cannot find next direntry, error %d", err);
		ubifs_err(c, "cannot find next direntry, error %d", err);
		return err;
	}


	/* 2 is a special value indicating that there are no more direntries */
	/* 2 is a special value indicating that there are no more direntries */
	ctx->pos = 2;
	ctx->pos = 2;
	return 0;
	return err;
}
}


/* Free saved readdir() state when the directory is closed */
/* Free saved readdir() state when the directory is closed */
@@ -1060,7 +1058,7 @@ static void unlock_4_inodes(struct inode *inode1, struct inode *inode2,
	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
	mutex_unlock(&ubifs_inode(inode1)->ui_mutex);
}
}


static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
static int do_rename(struct inode *old_dir, struct dentry *old_dentry,
		     struct inode *new_dir, struct dentry *new_dentry,
		     struct inode *new_dir, struct dentry *new_dentry,
		     unsigned int flags)
		     unsigned int flags)
{
{
@@ -1323,7 +1321,7 @@ static int ubifs_xrename(struct inode *old_dir, struct dentry *old_dentry,
	return err;
	return err;
}
}


static int ubifs_rename2(struct inode *old_dir, struct dentry *old_dentry,
static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
			struct inode *new_dir, struct dentry *new_dentry,
			struct inode *new_dir, struct dentry *new_dentry,
			unsigned int flags)
			unsigned int flags)
{
{
@@ -1336,7 +1334,7 @@ static int ubifs_rename2(struct inode *old_dir, struct dentry *old_dentry,
	if (flags & RENAME_EXCHANGE)
	if (flags & RENAME_EXCHANGE)
		return ubifs_xrename(old_dir, old_dentry, new_dir, new_dentry);
		return ubifs_xrename(old_dir, old_dentry, new_dir, new_dentry);


	return ubifs_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
	return do_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
}
}


int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
@@ -1387,7 +1385,7 @@ const struct inode_operations ubifs_dir_inode_operations = {
	.mkdir       = ubifs_mkdir,
	.mkdir       = ubifs_mkdir,
	.rmdir       = ubifs_rmdir,
	.rmdir       = ubifs_rmdir,
	.mknod       = ubifs_mknod,
	.mknod       = ubifs_mknod,
	.rename      = ubifs_rename2,
	.rename      = ubifs_rename,
	.setattr     = ubifs_setattr,
	.setattr     = ubifs_setattr,
	.getattr     = ubifs_getattr,
	.getattr     = ubifs_getattr,
	.listxattr   = ubifs_listxattr,
	.listxattr   = ubifs_listxattr,
+2 −0
Original line number Original line Diff line number Diff line
@@ -172,6 +172,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
	host_ui->xattr_cnt -= 1;
	host_ui->xattr_cnt -= 1;
	host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
	host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
	host_ui->xattr_size -= CALC_XATTR_BYTES(size);
	host_ui->xattr_size -= CALC_XATTR_BYTES(size);
	host_ui->xattr_names -= nm->len;
	mutex_unlock(&host_ui->ui_mutex);
	mutex_unlock(&host_ui->ui_mutex);
out_free:
out_free:
	make_bad_inode(inode);
	make_bad_inode(inode);
@@ -478,6 +479,7 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host,
	host_ui->xattr_cnt += 1;
	host_ui->xattr_cnt += 1;
	host_ui->xattr_size += CALC_DENT_SIZE(nm->len);
	host_ui->xattr_size += CALC_DENT_SIZE(nm->len);
	host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
	host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
	host_ui->xattr_names += nm->len;
	mutex_unlock(&host_ui->ui_mutex);
	mutex_unlock(&host_ui->ui_mutex);
	ubifs_release_budget(c, &req);
	ubifs_release_budget(c, &req);
	make_bad_inode(inode);
	make_bad_inode(inode);