Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fuse: fix inode initialization race

Fix a race between fuse_iget() and fuse_reverse_inval_inode() where
invalidation can arrive while an inode is being initialized, causing
the invalidation to be lost.
By keeping the inode state I_NEW as long as the attributes are not valid
the invalidation can wait until the inode is fully initialized.

Suggested-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Horst Birthelmer <hbirthelmer@ddn.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

authored by

Horst Birthelmer and committed by
Miklos Szeredi
aff12041 204aa22a

+5 -2
+5 -2
fs/fuse/inode.c
··· 470 470 struct inode *inode; 471 471 struct fuse_inode *fi; 472 472 struct fuse_conn *fc = get_fuse_conn_super(sb); 473 + bool is_new_inode = false; 473 474 474 475 /* 475 476 * Auto mount points get their node id from the submount root, which is ··· 506 505 if (!inode) 507 506 return NULL; 508 507 509 - if ((inode_state_read_once(inode) & I_NEW)) { 508 + is_new_inode = inode_state_read_once(inode) & I_NEW; 509 + if (is_new_inode) { 510 510 inode->i_flags |= S_NOATIME; 511 511 if (!fc->writeback_cache || !S_ISREG(attr->mode)) 512 512 inode->i_flags |= S_NOCMTIME; 513 513 inode->i_generation = generation; 514 514 fuse_init_inode(inode, attr, fc); 515 - unlock_new_inode(inode); 516 515 } else if (fuse_stale_inode(inode, generation, attr)) { 517 516 /* nodeid was reused, any I/O on the old inode should fail */ 518 517 fuse_make_bad(inode); ··· 529 528 done: 530 529 fuse_change_attributes_i(inode, attr, NULL, attr_valid, attr_version, 531 530 evict_ctr); 531 + if (is_new_inode) 532 + unlock_new_inode(inode); 532 533 return inode; 533 534 } 534 535