* [PATCH] f2fs: avoid race in between read xattr & write xattr
@ 2017-09-05 9:42 Yunlei He
2017-09-05 12:08 ` Chao Yu
0 siblings, 1 reply; 2+ messages in thread
From: Yunlei He @ 2017-09-05 9:42 UTC (permalink / raw)
To: jaegeuk, yuchao0, linux-f2fs-devel; +Cc: heyunlei, morgan.wang
Thread A: Thread B:
-f2fs_getxattr
-lookup_all_xattrs
-xnid = F2FS_I(inode)->i_xattr_nid;
-f2fs_setxattr
-__f2fs_setxattr
-write_all_xattrs
-truncate_xattr_node
... ...
-write_checkpoint
... ...
-alloc_nid <- nid reuse
-get_node_page
-f2fs_bug_on <- nid != node_footer->nid
It's need a rw_sem to avoid the race
Signed-off-by: Yunlei He <heyunlei@huawei.com>
---
fs/f2fs/f2fs.h | 1 +
fs/f2fs/super.c | 1 +
fs/f2fs/xattr.c | 6 ++++++
3 files changed, 8 insertions(+)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4b99396..e99c1fe 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -589,6 +589,7 @@ struct f2fs_inode_info {
struct extent_tree *extent_tree; /* cached extent_tree entry */
struct rw_semaphore dio_rwsem[2];/* avoid racing between dio and gc */
struct rw_semaphore i_mmap_sem;
+ struct rw_semaphore xattr_sem;
int i_extra_isize; /* size of extra space located in i_addr */
kprojid_t i_projid; /* id for project quota */
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 7730316..03950eb 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -630,6 +630,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
init_rwsem(&fi->dio_rwsem[READ]);
init_rwsem(&fi->dio_rwsem[WRITE]);
init_rwsem(&fi->i_mmap_sem);
+ init_rwsem(&fi->xattr_sem);
#ifdef CONFIG_QUOTA
memset(&fi->i_dquot, 0, sizeof(fi->i_dquot));
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index ef3a372..590fe3a 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -503,7 +503,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
int error = 0;
size_t rest = buffer_size;
+ down_read(&F2FS_I(inode)->xattr_sem);
error = read_all_xattrs(inode, NULL, &base_addr);
+ up_read(&F2FS_I(inode)->xattr_sem);
if (error)
return error;
@@ -573,7 +575,9 @@ static int __f2fs_setxattr(struct inode *inode, int index,
if (size > MAX_VALUE_LEN(inode))
return -E2BIG;
+ down_read(&F2FS_I(inode)->xattr_sem);
error = read_all_xattrs(inode, ipage, &base_addr);
+ up_read(&F2FS_I(inode)->xattr_sem);
if (error)
return error;
@@ -650,7 +654,9 @@ static int __f2fs_setxattr(struct inode *inode, int index,
new_hsize += newsize;
}
+ down_write(&F2FS_I(inode)->xattr_sem);
error = write_all_xattrs(inode, new_hsize, base_addr, ipage);
+ up_write(&F2FS_I(inode)->xattr_sem);
if (error)
goto exit;
--
1.9.1
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] f2fs: avoid race in between read xattr & write xattr
2017-09-05 9:42 [PATCH] f2fs: avoid race in between read xattr & write xattr Yunlei He
@ 2017-09-05 12:08 ` Chao Yu
0 siblings, 0 replies; 2+ messages in thread
From: Chao Yu @ 2017-09-05 12:08 UTC (permalink / raw)
To: Yunlei He, jaegeuk, yuchao0, linux-f2fs-devel; +Cc: morgan.wang
On 2017/9/5 17:42, Yunlei He wrote:
> Thread A: Thread B:
> -f2fs_getxattr
> -lookup_all_xattrs
> -xnid = F2FS_I(inode)->i_xattr_nid;
> -f2fs_setxattr
> -__f2fs_setxattr
> -write_all_xattrs
> -truncate_xattr_node
> ... ...
> -write_checkpoint
> ... ...
> -alloc_nid <- nid reuse
> -get_node_page
> -f2fs_bug_on <- nid != node_footer->nid
>
> It's need a rw_sem to avoid the race
>
> Signed-off-by: Yunlei He <heyunlei@huawei.com>
> ---
> fs/f2fs/f2fs.h | 1 +
> fs/f2fs/super.c | 1 +
> fs/f2fs/xattr.c | 6 ++++++
> 3 files changed, 8 insertions(+)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 4b99396..e99c1fe 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -589,6 +589,7 @@ struct f2fs_inode_info {
> struct extent_tree *extent_tree; /* cached extent_tree entry */
> struct rw_semaphore dio_rwsem[2];/* avoid racing between dio and gc */
> struct rw_semaphore i_mmap_sem;
> + struct rw_semaphore xattr_sem;
i_xattr_sem; /* avoid racing between reading and changing EAs */
>
> int i_extra_isize; /* size of extra space located in i_addr */
> kprojid_t i_projid; /* id for project quota */
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 7730316..03950eb 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -630,6 +630,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
> init_rwsem(&fi->dio_rwsem[READ]);
> init_rwsem(&fi->dio_rwsem[WRITE]);
> init_rwsem(&fi->i_mmap_sem);
> + init_rwsem(&fi->xattr_sem);
>
> #ifdef CONFIG_QUOTA
> memset(&fi->i_dquot, 0, sizeof(fi->i_dquot));
> diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
> index ef3a372..590fe3a 100644
> --- a/fs/f2fs/xattr.c
> +++ b/fs/f2fs/xattr.c
> @@ -503,7 +503,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
> int error = 0;
> size_t rest = buffer_size;
>
> + down_read(&F2FS_I(inode)->xattr_sem);
> error = read_all_xattrs(inode, NULL, &base_addr);
> + up_read(&F2FS_I(inode)->xattr_sem);
> if (error)
> return error;
>
> @@ -573,7 +575,9 @@ static int __f2fs_setxattr(struct inode *inode, int index,
> if (size > MAX_VALUE_LEN(inode))
> return -E2BIG;
>
> + down_read(&F2FS_I(inode)->xattr_sem);
> error = read_all_xattrs(inode, ipage, &base_addr);
> + up_read(&F2FS_I(inode)->xattr_sem);
> if (error)
> return error;
>
> @@ -650,7 +654,9 @@ static int __f2fs_setxattr(struct inode *inode, int index,
> new_hsize += newsize;
> }
>
> + down_write(&F2FS_I(inode)->xattr_sem);
> error = write_all_xattrs(inode, new_hsize, base_addr, ipage);
> + up_write(&F2FS_I(inode)->xattr_sem);
How about avoiding gap between read_all_xattrs and write_all_xattrs in __f2fs_setxattr?
Also needs to cover lookup_all_xattrs.
Thanks,
> if (error)
> goto exit;
>
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-09-05 12:08 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-05 9:42 [PATCH] f2fs: avoid race in between read xattr & write xattr Yunlei He
2017-09-05 12:08 ` Chao Yu
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.