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

Commit 5d5c5dca authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ext2, ext3, quota fixes from Jan Kara:
 "Fix three regressions caused by user namespace conversions (ext2,
  ext3, quota) and minor ext3 fix and cleanup."

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  quota: Silence warning about PRJQUOTA not being handled in need_print_warning()
  ext3: fix return values on parse_options() failure
  ext2: fix return values on parse_options() failure
  ext3: ext3_bread usage audit
  ext3: fix possible non-initialized variable on htree_dirblock_to_tree()
parents ecb2ecd9 6c29c50f
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -469,7 +469,7 @@ static int parse_options(char *options, struct super_block *sb)
			uid = make_kuid(current_user_ns(), option);
			uid = make_kuid(current_user_ns(), option);
			if (!uid_valid(uid)) {
			if (!uid_valid(uid)) {
				ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option);
				ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option);
				return -1;
				return 0;


			}
			}
			sbi->s_resuid = uid;
			sbi->s_resuid = uid;
@@ -480,7 +480,7 @@ static int parse_options(char *options, struct super_block *sb)
			gid = make_kgid(current_user_ns(), option);
			gid = make_kgid(current_user_ns(), option);
			if (!gid_valid(gid)) {
			if (!gid_valid(gid)) {
				ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option);
				ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option);
				return -1;
				return 0;
			}
			}
			sbi->s_resgid = gid;
			sbi->s_resgid = gid;
			break;
			break;
+21 −19
Original line number Original line Diff line number Diff line
@@ -46,8 +46,7 @@ static struct buffer_head *ext3_append(handle_t *handle,


	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;


	bh = ext3_bread(handle, inode, *block, 1, err);
	if ((bh = ext3_dir_bread(handle, inode, *block, 1, err))) {
	if (bh) {
		inode->i_size += inode->i_sb->s_blocksize;
		inode->i_size += inode->i_sb->s_blocksize;
		EXT3_I(inode)->i_disksize = inode->i_size;
		EXT3_I(inode)->i_disksize = inode->i_size;
		*err = ext3_journal_get_write_access(handle, bh);
		*err = ext3_journal_get_write_access(handle, bh);
@@ -339,8 +338,10 @@ dx_probe(struct qstr *entry, struct inode *dir,
	u32 hash;
	u32 hash;


	frame->bh = NULL;
	frame->bh = NULL;
	if (!(bh = ext3_bread (NULL,dir, 0, 0, err)))
	if (!(bh = ext3_dir_bread(NULL, dir, 0, 0, err))) {
		*err = ERR_BAD_DX_DIR;
		goto fail;
		goto fail;
	}
	root = (struct dx_root *) bh->b_data;
	root = (struct dx_root *) bh->b_data;
	if (root->info.hash_version != DX_HASH_TEA &&
	if (root->info.hash_version != DX_HASH_TEA &&
	    root->info.hash_version != DX_HASH_HALF_MD4 &&
	    root->info.hash_version != DX_HASH_HALF_MD4 &&
@@ -436,8 +437,10 @@ dx_probe(struct qstr *entry, struct inode *dir,
		frame->entries = entries;
		frame->entries = entries;
		frame->at = at;
		frame->at = at;
		if (!indirect--) return frame;
		if (!indirect--) return frame;
		if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
		if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(at), 0, err))) {
			*err = ERR_BAD_DX_DIR;
			goto fail2;
			goto fail2;
		}
		at = entries = ((struct dx_node *) bh->b_data)->entries;
		at = entries = ((struct dx_node *) bh->b_data)->entries;
		if (dx_get_limit(entries) != dx_node_limit (dir)) {
		if (dx_get_limit(entries) != dx_node_limit (dir)) {
			ext3_warning(dir->i_sb, __func__,
			ext3_warning(dir->i_sb, __func__,
@@ -535,7 +538,7 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash,
	 * block so no check is necessary
	 * block so no check is necessary
	 */
	 */
	while (num_frames--) {
	while (num_frames--) {
		if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at),
		if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(p->at),
					  0, &err)))
					  0, &err)))
			return err; /* Failure */
			return err; /* Failure */
		p++;
		p++;
@@ -559,10 +562,11 @@ static int htree_dirblock_to_tree(struct file *dir_file,
{
{
	struct buffer_head *bh;
	struct buffer_head *bh;
	struct ext3_dir_entry_2 *de, *top;
	struct ext3_dir_entry_2 *de, *top;
	int err, count = 0;
	int err = 0, count = 0;


	dxtrace(printk("In htree dirblock_to_tree: block %d\n", block));
	dxtrace(printk("In htree dirblock_to_tree: block %d\n", block));
	if (!(bh = ext3_bread (NULL, dir, block, 0, &err)))

	if (!(bh = ext3_dir_bread(NULL, dir, block, 0, &err)))
		return err;
		return err;


	de = (struct ext3_dir_entry_2 *) bh->b_data;
	de = (struct ext3_dir_entry_2 *) bh->b_data;
@@ -976,7 +980,7 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir,
		return NULL;
		return NULL;
	do {
	do {
		block = dx_get_block(frame->at);
		block = dx_get_block(frame->at);
		if (!(bh = ext3_bread (NULL,dir, block, 0, err)))
		if (!(bh = ext3_dir_bread (NULL, dir, block, 0, err)))
			goto errout;
			goto errout;


		retval = search_dirblock(bh, dir, entry,
		retval = search_dirblock(bh, dir, entry,
@@ -1458,9 +1462,9 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
	}
	}
	blocks = dir->i_size >> sb->s_blocksize_bits;
	blocks = dir->i_size >> sb->s_blocksize_bits;
	for (block = 0; block < blocks; block++) {
	for (block = 0; block < blocks; block++) {
		bh = ext3_bread(handle, dir, block, 0, &retval);
		if (!(bh = ext3_dir_bread(handle, dir, block, 0, &retval)))
		if(!bh)
			return retval;
			return retval;

		retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
		retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
		if (retval != -ENOSPC)
		if (retval != -ENOSPC)
			return retval;
			return retval;
@@ -1500,7 +1504,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
	entries = frame->entries;
	entries = frame->entries;
	at = frame->at;
	at = frame->at;


	if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
	if (!(bh = ext3_dir_bread(handle, dir, dx_get_block(frame->at), 0, &err)))
		goto cleanup;
		goto cleanup;


	BUFFER_TRACE(bh, "get_write_access");
	BUFFER_TRACE(bh, "get_write_access");
@@ -1790,8 +1794,7 @@ retry:
	inode->i_op = &ext3_dir_inode_operations;
	inode->i_op = &ext3_dir_inode_operations;
	inode->i_fop = &ext3_dir_operations;
	inode->i_fop = &ext3_dir_operations;
	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
	inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
	dir_block = ext3_bread (handle, inode, 0, 1, &err);
	if (!(dir_block = ext3_dir_bread(handle, inode, 0, 1, &err)))
	if (!dir_block)
		goto out_clear_inode;
		goto out_clear_inode;


	BUFFER_TRACE(dir_block, "get_write_access");
	BUFFER_TRACE(dir_block, "get_write_access");
@@ -1859,7 +1862,7 @@ static int empty_dir (struct inode * inode)


	sb = inode->i_sb;
	sb = inode->i_sb;
	if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) ||
	if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) ||
	    !(bh = ext3_bread (NULL, inode, 0, 0, &err))) {
	    !(bh = ext3_dir_bread(NULL, inode, 0, 0, &err))) {
		if (err)
		if (err)
			ext3_error(inode->i_sb, __func__,
			ext3_error(inode->i_sb, __func__,
				   "error %d reading directory #%lu offset 0",
				   "error %d reading directory #%lu offset 0",
@@ -1890,9 +1893,8 @@ static int empty_dir (struct inode * inode)
			(void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
			(void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
			err = 0;
			err = 0;
			brelse (bh);
			brelse (bh);
			bh = ext3_bread (NULL, inode,
			if (!(bh = ext3_dir_bread (NULL, inode,
				offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err);
				offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err))) {
			if (!bh) {
				if (err)
				if (err)
					ext3_error(sb, __func__,
					ext3_error(sb, __func__,
						   "error %d reading directory"
						   "error %d reading directory"
@@ -2388,7 +2390,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
				goto end_rename;
				goto end_rename;
		}
		}
		retval = -EIO;
		retval = -EIO;
		dir_bh = ext3_bread (handle, old_inode, 0, 0, &retval);
		dir_bh = ext3_dir_bread(handle, old_inode, 0, 0, &retval);
		if (!dir_bh)
		if (!dir_bh)
			goto end_rename;
			goto end_rename;
		if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
		if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
+19 −0
Original line number Original line Diff line number Diff line
@@ -6,3 +6,22 @@
*/
*/


extern struct dentry *ext3_get_parent(struct dentry *child);
extern struct dentry *ext3_get_parent(struct dentry *child);

static inline struct buffer_head *ext3_dir_bread(handle_t *handle,
						 struct inode *inode,
						 int block, int create,
						 int *err)
{
	struct buffer_head *bh;

	bh = ext3_bread(handle, inode, block, create, err);

	if (!bh && !(*err)) {
		*err = -EIO;
		ext3_error(inode->i_sb, __func__,
			   "Directory hole detected on inode %lu\n",
			   inode->i_ino);
		return NULL;
	}
	return bh;
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -1001,7 +1001,7 @@ static int parse_options (char *options, struct super_block *sb,
			uid = make_kuid(current_user_ns(), option);
			uid = make_kuid(current_user_ns(), option);
			if (!uid_valid(uid)) {
			if (!uid_valid(uid)) {
				ext3_msg(sb, KERN_ERR, "Invalid uid value %d", option);
				ext3_msg(sb, KERN_ERR, "Invalid uid value %d", option);
				return -1;
				return 0;


			}
			}
			sbi->s_resuid = uid;
			sbi->s_resuid = uid;
@@ -1012,7 +1012,7 @@ static int parse_options (char *options, struct super_block *sb,
			gid = make_kgid(current_user_ns(), option);
			gid = make_kgid(current_user_ns(), option);
			if (!gid_valid(gid)) {
			if (!gid_valid(gid)) {
				ext3_msg(sb, KERN_ERR, "Invalid gid value %d", option);
				ext3_msg(sb, KERN_ERR, "Invalid gid value %d", option);
				return -1;
				return 0;
			}
			}
			sbi->s_resgid = gid;
			sbi->s_resgid = gid;
			break;
			break;
+2 −0
Original line number Original line Diff line number Diff line
@@ -1160,6 +1160,8 @@ static int need_print_warning(struct dquot_warn *warn)
			return uid_eq(current_fsuid(), warn->w_dq_id.uid);
			return uid_eq(current_fsuid(), warn->w_dq_id.uid);
		case GRPQUOTA:
		case GRPQUOTA:
			return in_group_p(warn->w_dq_id.gid);
			return in_group_p(warn->w_dq_id.gid);
		case PRJQUOTA:	/* Never taken... Just make gcc happy */
			return 0;
	}
	}
	return 0;
	return 0;
}
}