|
@@ -297,7 +297,18 @@ static int nilfs_ioctl_move_inode_block(struct inode *inode,
|
|
(unsigned long long)vdesc->vd_vblocknr);
|
|
(unsigned long long)vdesc->vd_vblocknr);
|
|
return ret;
|
|
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);
|
|
list_add_tail(&bh->b_assoc_buffers, buffers);
|
|
return 0;
|
|
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) {
|
|
list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
|
|
ret = nilfs_gccache_wait_and_mark_dirty(bh);
|
|
ret = nilfs_gccache_wait_and_mark_dirty(bh);
|
|
if (unlikely(ret < 0)) {
|
|
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;
|
|
goto failed;
|
|
}
|
|
}
|
|
list_del_init(&bh->b_assoc_buffers);
|
|
list_del_init(&bh->b_assoc_buffers);
|
|
- bh->b_private = NULL;
|
|
|
|
brelse(bh);
|
|
brelse(bh);
|
|
}
|
|
}
|
|
return nmembs;
|
|
return nmembs;
|
|
@@ -360,7 +357,6 @@ static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
|
|
failed:
|
|
failed:
|
|
list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
|
|
list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
|
|
list_del_init(&bh->b_assoc_buffers);
|
|
list_del_init(&bh->b_assoc_buffers);
|
|
- bh->b_private = NULL;
|
|
|
|
brelse(bh);
|
|
brelse(bh);
|
|
}
|
|
}
|
|
return ret;
|
|
return ret;
|
|
@@ -471,7 +467,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
failed:
|
|
failed:
|
|
- nilfs_remove_all_gcinode(nilfs);
|
|
|
|
printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
|
|
printk(KERN_ERR "NILFS: GC failed during preparation: %s: err=%d\n",
|
|
msg, ret);
|
|
msg, ret);
|
|
return ret;
|
|
return ret;
|
|
@@ -560,6 +555,8 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
|
|
else
|
|
else
|
|
ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
|
|
ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
|
|
|
|
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ nilfs_remove_all_gcinode(nilfs);
|
|
clear_nilfs_gc_running(nilfs);
|
|
clear_nilfs_gc_running(nilfs);
|
|
|
|
|
|
out_free:
|
|
out_free:
|