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

Commit ed146f65 authored by Akilesh Kailash's avatar Akilesh Kailash Committed by Paul Lawrence
Browse files

ANDROID: Incremental fs: Fix minor bugs



1: Invoke kunmap(page) in error path
2: Validate NULL checks at few places in the code.
3: path_put() should not be invoked if path entry is null.
   Although path_put() checks for NULL condition internally,
   caller should gracefully handle it.

Bug: 161565969
Test: kernel selftest - incfs_test, incfs_perf

Signed-off-by: default avatarAkilesh Kailash <akailash@google.com>
Change-Id: Ie4dfaaba4b09f4798d492f8a25dd9dcc8da89e51
parent 883c150c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -933,7 +933,7 @@ ssize_t incfs_read_data_file_block(struct mem_range dst, struct file *f,
	struct data_file_block block = {};
	struct data_file *df = get_incfs_data_file(f);

	if (!dst.data || !df)
	if (!dst.data || !df || !tmp.data)
		return -EFAULT;

	if (tmp.len < 2 * INCFS_DATA_FILE_BLOCK_SIZE)
+44 −6
Original line number Diff line number Diff line
@@ -470,6 +470,9 @@ static ssize_t pending_reads_read(struct file *f, char __user *buf, size_t len,
	ssize_t result = 0;
	int i = 0;

	if (!mi)
		return -EFAULT;

	if (!incfs_fresh_pending_reads_exist(mi, last_known_read_sn))
		return 0;

@@ -798,13 +801,17 @@ static int read_single_page(struct file *f, struct page *page)
	ssize_t read_result = 0;
	struct data_file *df = get_incfs_data_file(f);
	int result = 0;
	void *page_start = kmap(page);
	void *page_start;
	int block_index;
	int timeout_ms;

	if (!df)
	if (!df) {
		SetPageError(page);
		unlock_page(page);
		return -EBADF;
	}

	page_start = kmap(page);
	offset = page_offset(page);
	block_index = offset / INCFS_DATA_FILE_BLOCK_SIZE;
	size = df->df_size;
@@ -816,6 +823,10 @@ static int read_single_page(struct file *f, struct page *page)
		};

		tmp.data = (u8 *)__get_free_pages(GFP_NOFS, get_order(tmp.len));
		if (!tmp.data) {
			read_result = -ENOMEM;
			goto err;
		}
		bytes_to_read = min_t(loff_t, size - offset, PAGE_SIZE);
		read_result = incfs_read_data_file_block(
			range(page_start, bytes_to_read), f, block_index,
@@ -827,6 +838,7 @@ static int read_single_page(struct file *f, struct page *page)
		read_result = 0;
	}

err:
	if (read_result < 0)
		result = read_result;
	else if (read_result < PAGE_SIZE)
@@ -1506,6 +1518,9 @@ static struct dentry *dir_lookup(struct inode *dir_inode, struct dentry *dentry,
			range((u8 *)dentry->d_name.name, dentry->d_name.len);
	int err = 0;

	if (!mi || !dir_info || !dir_info->n_backing_inode)
		return ERR_PTR(-EBADF);

	if (d_inode(mi->mi_backing_dir_path.dentry) ==
		dir_info->n_backing_inode) {
		/* We do lookup in the FS root. Show pseudo files. */
@@ -1621,7 +1636,7 @@ static int dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)

	if (!backing_dentry) {
		err = -EBADF;
		goto out;
		goto path_err;
	}

	if (backing_dentry->d_parent == mi->mi_index_dir) {
@@ -1653,6 +1668,8 @@ static int dir_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	if (d_really_is_negative(dentry))
		d_drop(dentry);
	path_put(&backing_path);

path_err:
	mutex_unlock(&mi->mi_dir_struct_mutex);
	if (err)
		pr_debug("incfs: %s err:%d\n", __func__, err);
@@ -1708,6 +1725,9 @@ static int dir_unlink(struct inode *dir, struct dentry *dentry)
	struct kstat stat;
	int err = 0;

	if (!mi)
		return -EBADF;

	err = mutex_lock_interruptible(&mi->mi_dir_struct_mutex);
	if (err)
		return err;
@@ -1715,7 +1735,7 @@ static int dir_unlink(struct inode *dir, struct dentry *dentry)
	get_incfs_backing_path(dentry, &backing_path);
	if (!backing_path.dentry) {
		err = -EBADF;
		goto out;
		goto path_err;
	}

	if (backing_path.dentry->d_parent == mi->mi_index_dir) {
@@ -1743,6 +1763,7 @@ static int dir_unlink(struct inode *dir, struct dentry *dentry)
	d_drop(dentry);
out:
	path_put(&backing_path);
path_err:
	if (err)
		pr_debug("incfs: %s err:%d\n", __func__, err);
	mutex_unlock(&mi->mi_dir_struct_mutex);
@@ -1757,6 +1778,9 @@ static int dir_link(struct dentry *old_dentry, struct inode *dir,
	struct path backing_new_path = {};
	int error = 0;

	if (!mi)
		return -EBADF;

	error = mutex_lock_interruptible(&mi->mi_dir_struct_mutex);
	if (error)
		return error;
@@ -1803,6 +1827,9 @@ static int dir_rmdir(struct inode *dir, struct dentry *dentry)
	struct path backing_path = {};
	int err = 0;

	if (!mi)
		return -EBADF;

	err = mutex_lock_interruptible(&mi->mi_dir_struct_mutex);
	if (err)
		return err;
@@ -1810,7 +1837,7 @@ static int dir_rmdir(struct inode *dir, struct dentry *dentry)
	get_incfs_backing_path(dentry, &backing_path);
	if (!backing_path.dentry) {
		err = -EBADF;
		goto out;
		goto path_err;
	}

	if (backing_path.dentry == mi->mi_index_dir) {
@@ -1824,6 +1851,8 @@ static int dir_rmdir(struct inode *dir, struct dentry *dentry)
		d_drop(dentry);
out:
	path_put(&backing_path);

path_err:
	if (err)
		pr_debug("incfs: %s err:%d\n", __func__, err);
	mutex_unlock(&mi->mi_dir_struct_mutex);
@@ -1907,7 +1936,14 @@ static int file_open(struct inode *inode, struct file *file)
	struct path backing_path = {};
	int err = 0;

	if (!mi)
		return -EBADF;

	get_incfs_backing_path(file->f_path.dentry, &backing_path);

	if (!backing_path.dentry)
		return -EBADF;

	backing_file = dentry_open(
		&backing_path, O_RDWR | O_NOATIME | O_LARGEFILE, mi->mi_owner);
	path_put(&backing_path);
@@ -1969,8 +2005,10 @@ static int dentry_revalidate(struct dentry *d, unsigned int flags)

	get_incfs_backing_path(d, &backing_path);
	backing_dentry = backing_path.dentry;
	if (!backing_dentry)
	if (!backing_dentry) {
		result = -EBADF;
		goto out;
	}

	if (d_inode(backing_dentry) != binode) {
		/*