forked from Minki/linux
f2fs: should cover i_xattr_nid with its xattr node page lock
Previously, f2fs_setxattr assigns i_xattr_nid in the inode page inconsistently. The scenario is: = Thread 1 = = Thread 2 = = fi->i_xattr_nid = = on-disk nid = f2fs_setxattr 0 0 new_node_page X 0 sync_inode_page X X checkpoint X X -. grab_cache_page X X | --> allocate a new xattr node block or -ENOSPC <----------------' At this moment, the checkpoint stores inconsistent data where the inode has i_xattr_nid but actual xattr node block is not allocated yet. So, we should assign the real i_xattr_nid only after its xattr node block is allocated. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
This commit is contained in:
parent
9c02740c01
commit
479bd73ac4
@ -851,6 +851,9 @@ struct page *new_node_page(struct dnode_of_data *dn,
|
||||
SetPageUptodate(page);
|
||||
set_page_dirty(page);
|
||||
|
||||
if (ofs == XATTR_NODE_OFFSET)
|
||||
F2FS_I(dn->inode)->i_xattr_nid = dn->nid;
|
||||
|
||||
dn->node_page = page;
|
||||
if (ipage)
|
||||
update_inode(dn->inode, ipage);
|
||||
|
@ -378,23 +378,23 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
|
||||
if (!fi->i_xattr_nid) {
|
||||
/* Allocate new attribute block */
|
||||
struct dnode_of_data dn;
|
||||
nid_t new_nid;
|
||||
|
||||
if (!alloc_nid(sbi, &fi->i_xattr_nid)) {
|
||||
if (!alloc_nid(sbi, &new_nid)) {
|
||||
error = -ENOSPC;
|
||||
goto exit;
|
||||
}
|
||||
set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
|
||||
set_new_dnode(&dn, inode, NULL, NULL, new_nid);
|
||||
mark_inode_dirty(inode);
|
||||
|
||||
page = new_node_page(&dn, XATTR_NODE_OFFSET, ipage);
|
||||
if (IS_ERR(page)) {
|
||||
alloc_nid_failed(sbi, fi->i_xattr_nid);
|
||||
fi->i_xattr_nid = 0;
|
||||
alloc_nid_failed(sbi, new_nid);
|
||||
error = PTR_ERR(page);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
alloc_nid_done(sbi, fi->i_xattr_nid);
|
||||
alloc_nid_done(sbi, new_nid);
|
||||
base_addr = page_address(page);
|
||||
header = XATTR_HDR(base_addr);
|
||||
header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
|
||||
|
Loading…
Reference in New Issue
Block a user