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

Commit b7b69c7e authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryusuke/nilfs2:
  nilfs2: fix missing cleanup of gc cache on error cases
  nilfs2: fix kernel oops in error case of nilfs_ioctl_move_blocks
parents 1ce55238 c083234f
Loading
Loading
Loading
Loading
+15 −18
Original line number Diff line number Diff line
@@ -297,7 +297,18 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode,
			       (unsigned long long)vdesc->vd_vblocknr);
		return ret;
	}
	bh->b_private = vdesc;
	if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
		printk(KERN_CRIT "%s: conflicting %s buffer: ino=%llu, "
		       "cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu\n",
		       __func__, vdesc->vd_flags ? "node" : "data",
		       (unsigned long long)vdesc->vd_ino,
		       (unsigned long long)vdesc->vd_cno,
		       (unsigned long long)vdesc->vd_offset,
		       (unsigned long long)vdesc->vd_blocknr,
		       (unsigned long long)vdesc->vd_vblocknr);
		brelse(bh);
		return -EEXIST;
	}
	list_add_tail(&bh->b_assoc_buffers, buffers);
	return 0;
}
@@ -335,24 +346,10 @@ static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
	list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
		ret = nilfs_gccache_wait_and_mark_dirty(bh);
		if (unlikely(ret < 0)) {
			if (ret == -EEXIST) {
				vdesc = bh->b_private;
				printk(KERN_CRIT
				       "%s: conflicting %s buffer: "
				       "ino=%llu, cno=%llu, offset=%llu, "
				       "blocknr=%llu, vblocknr=%llu\n",
				       __func__,
				       vdesc->vd_flags ? "node" : "data",
				       (unsigned long long)vdesc->vd_ino,
				       (unsigned long long)vdesc->vd_cno,
				       (unsigned long long)vdesc->vd_offset,
				       (unsigned long long)vdesc->vd_blocknr,
				       (unsigned long long)vdesc->vd_vblocknr);
			}
			WARN_ON(ret == -EEXIST);
			goto failed;
		}
		list_del_init(&bh->b_assoc_buffers);
		bh->b_private = NULL;
		brelse(bh);
	}
	return nmembs;
@@ -360,7 +357,6 @@ static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
 failed:
	list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
		list_del_init(&bh->b_assoc_buffers);
		bh->b_private = NULL;
		brelse(bh);
	}
	return ret;
@@ -471,7 +467,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
	return 0;

 failed:
	nilfs_remove_all_gcinode(nilfs);
	printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
	       msg, ret);
	return ret;
@@ -560,6 +555,8 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
	else
		ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);

	if (ret < 0)
		nilfs_remove_all_gcinode(nilfs);
	clear_nilfs_gc_running(nilfs);

 out_free: