Commit 83d17827a7a61fdd10f1ad628cc7b2004aa796a9

Authored by Ryusuke Konishi
Committed by Greg Kroah-Hartman
1 parent 53575aa5ba

nilfs2: fix the nilfs_iget() vs. nilfs_new_inode() races

commit 705304a863cc41585508c0f476f6d3ec28cf7e00 upstream.

Same story as in commit 41080b5a2401 ("nfsd race fixes: ext2") (similar
ext2 fix) except that nilfs2 needs to use insert_inode_locked4() instead
of insert_inode_locked() and a bug of a check for dead inodes needs to
be fixed.

If nilfs_iget() is called from nfsd after nilfs_new_inode() calls
insert_inode_locked4(), nilfs_iget() will wait for unlock_new_inode() at
the end of nilfs_mkdir()/nilfs_create()/etc to unlock the inode.

If nilfs_iget() is called before nilfs_new_inode() calls
insert_inode_locked4(), it will create an in-core inode and read its
data from the on-disk inode.  But, nilfs_iget() will find i_nlink equals
zero and fail at nilfs_read_inode_common(), which will lead it to call
iget_failed() and cleanly fail.

However, this sanity check doesn't work as expected for reused on-disk
inodes because they leave a non-zero value in i_mode field and it
hinders the test of i_nlink.  This patch also fixes the issue by
removing the test on i_mode that nilfs2 doesn't need.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 2 changed files with 36 additions and 11 deletions Side-by-side Diff

... ... @@ -49,6 +49,8 @@
49 49 int for_gc;
50 50 };
51 51  
  52 +static int nilfs_iget_test(struct inode *inode, void *opaque);
  53 +
52 54 void nilfs_inode_add_blocks(struct inode *inode, int n)
53 55 {
54 56 struct nilfs_root *root = NILFS_I(inode)->i_root;
... ... @@ -348,6 +350,17 @@
348 350 .is_partially_uptodate = block_is_partially_uptodate,
349 351 };
350 352  
  353 +static int nilfs_insert_inode_locked(struct inode *inode,
  354 + struct nilfs_root *root,
  355 + unsigned long ino)
  356 +{
  357 + struct nilfs_iget_args args = {
  358 + .ino = ino, .root = root, .cno = 0, .for_gc = 0
  359 + };
  360 +
  361 + return insert_inode_locked4(inode, ino, nilfs_iget_test, &args);
  362 +}
  363 +
351 364 struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)
352 365 {
353 366 struct super_block *sb = dir->i_sb;
... ... @@ -383,7 +396,7 @@
383 396 if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {
384 397 err = nilfs_bmap_read(ii->i_bmap, NULL);
385 398 if (err < 0)
386   - goto failed_bmap;
  399 + goto failed_after_creation;
387 400  
388 401 set_bit(NILFS_I_BMAP, &ii->i_state);
389 402 /* No lock is needed; iget() ensures it. */
390 403  
391 404  
392 405  
393 406  
... ... @@ -399,21 +412,24 @@
399 412 spin_lock(&nilfs->ns_next_gen_lock);
400 413 inode->i_generation = nilfs->ns_next_generation++;
401 414 spin_unlock(&nilfs->ns_next_gen_lock);
402   - insert_inode_hash(inode);
  415 + if (nilfs_insert_inode_locked(inode, root, ino) < 0) {
  416 + err = -EIO;
  417 + goto failed_after_creation;
  418 + }
403 419  
404 420 err = nilfs_init_acl(inode, dir);
405 421 if (unlikely(err))
406   - goto failed_acl; /* never occur. When supporting
  422 + goto failed_after_creation; /* never occur. When supporting
407 423 nilfs_init_acl(), proper cancellation of
408 424 above jobs should be considered */
409 425  
410 426 return inode;
411 427  
412   - failed_acl:
413   - failed_bmap:
  428 + failed_after_creation:
414 429 clear_nlink(inode);
  430 + unlock_new_inode(inode);
415 431 iput(inode); /* raw_inode will be deleted through
416   - generic_delete_inode() */
  432 + nilfs_evict_inode() */
417 433 goto failed;
418 434  
419 435 failed_ifile_create_inode:
... ... @@ -461,8 +477,8 @@
461 477 inode->i_atime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
462 478 inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec);
463 479 inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
464   - if (inode->i_nlink == 0 && inode->i_mode == 0)
465   - return -EINVAL; /* this inode is deleted */
  480 + if (inode->i_nlink == 0)
  481 + return -ESTALE; /* this inode is deleted */
466 482  
467 483 inode->i_blocks = le64_to_cpu(raw_inode->i_blocks);
468 484 ii->i_flags = le32_to_cpu(raw_inode->i_flags);
... ... @@ -51,9 +51,11 @@
51 51 int err = nilfs_add_link(dentry, inode);
52 52 if (!err) {
53 53 d_instantiate(dentry, inode);
  54 + unlock_new_inode(inode);
54 55 return 0;
55 56 }
56 57 inode_dec_link_count(inode);
  58 + unlock_new_inode(inode);
57 59 iput(inode);
58 60 return err;
59 61 }
... ... @@ -182,6 +184,7 @@
182 184 out_fail:
183 185 drop_nlink(inode);
184 186 nilfs_mark_inode_dirty(inode);
  187 + unlock_new_inode(inode);
185 188 iput(inode);
186 189 goto out;
187 190 }
188 191  
189 192  
... ... @@ -201,11 +204,15 @@
201 204 inode_inc_link_count(inode);
202 205 ihold(inode);
203 206  
204   - err = nilfs_add_nondir(dentry, inode);
205   - if (!err)
  207 + err = nilfs_add_link(dentry, inode);
  208 + if (!err) {
  209 + d_instantiate(dentry, inode);
206 210 err = nilfs_transaction_commit(dir->i_sb);
207   - else
  211 + } else {
  212 + inode_dec_link_count(inode);
  213 + iput(inode);
208 214 nilfs_transaction_abort(dir->i_sb);
  215 + }
209 216  
210 217 return err;
211 218 }
... ... @@ -243,6 +250,7 @@
243 250  
244 251 nilfs_mark_inode_dirty(inode);
245 252 d_instantiate(dentry, inode);
  253 + unlock_new_inode(inode);
246 254 out:
247 255 if (!err)
248 256 err = nilfs_transaction_commit(dir->i_sb);
... ... @@ -255,6 +263,7 @@
255 263 drop_nlink(inode);
256 264 drop_nlink(inode);
257 265 nilfs_mark_inode_dirty(inode);
  266 + unlock_new_inode(inode);
258 267 iput(inode);
259 268 out_dir:
260 269 drop_nlink(dir);