Commit 947b10ae0aeda89fc066a7470fdba55f72b0b8fc
1 parent
b0c3844d8a
Exists in
master
and in
39 other branches
nilfs2: fix regression of garbage collection ioctl
On 2.6.37-rc1, garbage collection ioctl of nilfs was broken due to the commit 263d90cefc7d82a0 ("nilfs2: remove own inode hash used for GC"), and leading to filesystem corruption. The patch doesn't queue gc-inodes for log writer if they are reused through the vfs inode cache. Here, gc-inode is the inode which buffers blocks to be relocated on GC. That patch queues gc-inodes in nilfs_init_gcinode() function, but this function is not called when they don't have I_NEW flag. Thus, some of live blocks are wrongly overrode without being moved to new logs. This resolves the problem by moving the gc-inode queueing to an outer function to ensure it's done right. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Showing 2 changed files with 12 additions and 9 deletions Side-by-side Diff
fs/nilfs2/gcinode.c
... | ... | @@ -176,7 +176,6 @@ |
176 | 176 | int nilfs_init_gcinode(struct inode *inode) |
177 | 177 | { |
178 | 178 | struct nilfs_inode_info *ii = NILFS_I(inode); |
179 | - struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; | |
180 | 179 | |
181 | 180 | inode->i_mode = S_IFREG; |
182 | 181 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); |
... | ... | @@ -185,14 +184,6 @@ |
185 | 184 | |
186 | 185 | ii->i_flags = 0; |
187 | 186 | nilfs_bmap_init_gc(ii->i_bmap); |
188 | - | |
189 | - /* | |
190 | - * Add the inode to GC inode list. Garbage Collection | |
191 | - * is serialized and no two processes manipulate the | |
192 | - * list simultaneously. | |
193 | - */ | |
194 | - igrab(inode); | |
195 | - list_add(&NILFS_I(inode)->i_dirty, &nilfs->ns_gc_inodes); | |
196 | 187 | |
197 | 188 | return 0; |
198 | 189 | } |
fs/nilfs2/ioctl.c
... | ... | @@ -337,6 +337,7 @@ |
337 | 337 | struct nilfs_argv *argv, void *buf) |
338 | 338 | { |
339 | 339 | size_t nmembs = argv->v_nmembs; |
340 | + struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; | |
340 | 341 | struct inode *inode; |
341 | 342 | struct nilfs_vdesc *vdesc; |
342 | 343 | struct buffer_head *bh, *n; |
... | ... | @@ -353,6 +354,17 @@ |
353 | 354 | ret = PTR_ERR(inode); |
354 | 355 | goto failed; |
355 | 356 | } |
357 | + if (list_empty(&NILFS_I(inode)->i_dirty)) { | |
358 | + /* | |
359 | + * Add the inode to GC inode list. Garbage Collection | |
360 | + * is serialized and no two processes manipulate the | |
361 | + * list simultaneously. | |
362 | + */ | |
363 | + igrab(inode); | |
364 | + list_add(&NILFS_I(inode)->i_dirty, | |
365 | + &nilfs->ns_gc_inodes); | |
366 | + } | |
367 | + | |
356 | 368 | do { |
357 | 369 | ret = nilfs_ioctl_move_inode_block(inode, vdesc, |
358 | 370 | &buffers); |