Commit 947b10ae0aeda89fc066a7470fdba55f72b0b8fc

Authored by Ryusuke Konishi
1 parent b0c3844d8a

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

... ... @@ -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 }
... ... @@ -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);