On 07/10, Chao Yu wrote:
> syzbot reports deadlock bug as below:
> 
> -> #1 (&fi->i_sem){+.+.}-{3:3}:
>        down_write+0x3a/0x50 kernel/locking/rwsem.c:1573
>        f2fs_down_write fs/f2fs/f2fs.h:2133 [inline]
>        f2fs_add_inline_entry+0x3a8/0x760 fs/f2fs/inline.c:644
>        f2fs_add_dentry+0xba/0x1e0 fs/f2fs/dir.c:784
>        f2fs_do_add_link+0x21e/0x340 fs/f2fs/dir.c:827
>        f2fs_add_link fs/f2fs/f2fs.h:3554 [inline]
>        f2fs_create+0x32c/0x530 fs/f2fs/namei.c:377
>        lookup_open fs/namei.c:3492 [inline]
>        open_last_lookups fs/namei.c:3560 [inline]
>        path_openat+0x13e7/0x3180 fs/namei.c:3790
>        do_filp_open+0x234/0x490 fs/namei.c:3820
>        do_sys_openat2+0x13e/0x1d0 fs/open.c:1407
>        do_sys_open fs/open.c:1422 [inline]
>        __do_sys_open fs/open.c:1430 [inline]
>        __se_sys_open fs/open.c:1426 [inline]
>        __x64_sys_open+0x225/0x270 fs/open.c:1426
>        do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>        do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>        entry_SYSCALL_64_after_hwframe+0x63/0xcd
> 
> -> #0 (&fi->i_xattr_sem){.+.+}-{3:3}:
>        check_prev_add kernel/locking/lockdep.c:3142 [inline]
>        check_prevs_add kernel/locking/lockdep.c:3261 [inline]
>        validate_chain kernel/locking/lockdep.c:3876 [inline]
>        __lock_acquire+0x39ff/0x7f70 kernel/locking/lockdep.c:5144
>        lock_acquire+0x1e3/0x520 kernel/locking/lockdep.c:5761
>        down_read+0x47/0x2f0 kernel/locking/rwsem.c:1520
>        f2fs_down_read fs/f2fs/f2fs.h:2108 [inline]
>        f2fs_getxattr+0xb8/0x1460 fs/f2fs/xattr.c:532
>        __f2fs_get_acl+0x52/0x8e0 fs/f2fs/acl.c:179
>        f2fs_acl_create fs/f2fs/acl.c:377 [inline]
>        f2fs_init_acl+0xd7/0x9a0 fs/f2fs/acl.c:420
>        f2fs_init_inode_metadata+0x824/0x1190 fs/f2fs/dir.c:558
>        f2fs_do_tmpfile+0x34/0x170 fs/f2fs/dir.c:839
>        __f2fs_tmpfile+0x1f9/0x380 fs/f2fs/namei.c:884
>        f2fs_ioc_start_atomic_write+0x4a3/0x9e0 fs/f2fs/file.c:2099
>        __f2fs_ioctl+0x1b5c/0xb770
>        vfs_ioctl fs/ioctl.c:51 [inline]
>        __do_sys_ioctl fs/ioctl.c:870 [inline]
>        __se_sys_ioctl+0xf8/0x170 fs/ioctl.c:856
>        do_syscall_x64 arch/x86/entry/common.c:50 [inline]
>        do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
>        entry_SYSCALL_64_after_hwframe+0x63/0xcd
> 
> The root cause is as below reversed lock order:
> - f2fs_create
>  - f2fs_add_dentry
>   - f2fs_down_write(&F2FS_I(dir)->i_xattr_sem)
>                                               - f2fs_ioc_start_atomic_write
>                                                - __f2fs_tmpfile
>                                                 - f2fs_do_tmpfile
>                                                  - 
> f2fs_down_write(&F2FS_I(inode)->i_sem)
>                                                  - f2fs_init_inode_metadata
>                                                   - f2fs_init_acl
>                                                    - __f2fs_get_acl
>                                                     - f2fs_getxattr
>                                                      - 
> f2fs_down_read(&F2FS_I(dir)->i_xattr_sem)
>   - f2fs_add_inline_entry
>    - f2fs_down_write(&F2FS_I(inode)->i_sem)

How is it possible to get two inode are identical?

> 
> We can break the dependency of deadlock by below change:
> - use i_sem to keep order of {get,set}xattr instead of i_xattr_sem
> - keep below lock order in inode operation to avoid deadlock:
>  dir->i_sem -> inode->i_sem
>  dir->i_sem -> dpage_lock
> 
> Fixes: 5eda1ad1aaff ("f2fs: fix deadlock in i_xattr_sem and inode page lock")
> Reported-by: [email protected]
> Closes: 
> https://lore.kernel.org/linux-f2fs-devel/[email protected]
> Signed-off-by: Chao Yu <[email protected]>
> ---
>  fs/f2fs/acl.c    | 36 +++++++++++++++++++-----------------
>  fs/f2fs/acl.h    |  4 ++--
>  fs/f2fs/dir.c    | 22 ++++++++++++++++------
>  fs/f2fs/f2fs.h   |  1 -
>  fs/f2fs/super.c  |  5 ++---
>  fs/f2fs/verity.c |  5 +++--
>  fs/f2fs/xattr.c  | 37 +++++++++++++++++++++----------------
>  fs/f2fs/xattr.h  | 19 +++++++++++++------
>  8 files changed, 76 insertions(+), 53 deletions(-)
> 
> diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
> index ec2aeccb69a3..af58b38e953c 100644
> --- a/fs/f2fs/acl.c
> +++ b/fs/f2fs/acl.c
> @@ -166,7 +166,7 @@ static void *f2fs_acl_to_disk(struct f2fs_sb_info *sbi,
>  }
>  
>  static struct posix_acl *__f2fs_get_acl(struct inode *inode, int type,
> -                                             struct page *dpage)
> +                                             struct page *dpage, bool locked)
>  {
>       int name_index = F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT;
>       void *value = NULL;
> @@ -176,13 +176,13 @@ static struct posix_acl *__f2fs_get_acl(struct inode 
> *inode, int type,
>       if (type == ACL_TYPE_ACCESS)
>               name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
>  
> -     retval = f2fs_getxattr(inode, name_index, "", NULL, 0, dpage);
> +     retval = f2fs_getxattr(inode, name_index, "", NULL, 0, dpage, locked);
>       if (retval > 0) {
>               value = f2fs_kmalloc(F2FS_I_SB(inode), retval, GFP_F2FS_ZERO);
>               if (!value)
>                       return ERR_PTR(-ENOMEM);
>               retval = f2fs_getxattr(inode, name_index, "", value,
> -                                                     retval, dpage);
> +                                                     retval, dpage, locked);
>       }
>  
>       if (retval > 0)
> @@ -201,7 +201,7 @@ struct posix_acl *f2fs_get_acl(struct inode *inode, int 
> type, bool rcu)
>       if (rcu)
>               return ERR_PTR(-ECHILD);
>  
> -     return __f2fs_get_acl(inode, type, NULL);
> +     return __f2fs_get_acl(inode, type, NULL, false);
>  }
>  
>  static int f2fs_acl_update_mode(struct mnt_idmap *idmap,
> @@ -226,9 +226,9 @@ static int f2fs_acl_update_mode(struct mnt_idmap *idmap,
>       return 0;
>  }
>  
> -static int __f2fs_set_acl(struct mnt_idmap *idmap,
> -                     struct inode *inode, int type,
> -                     struct posix_acl *acl, struct page *ipage)
> +static int __f2fs_set_acl(struct mnt_idmap *idmap, struct inode *inode,
> +                                     int type, struct posix_acl *acl,
> +                                     struct page *ipage, bool locked)
>  {
>       int name_index;
>       void *value = NULL;
> @@ -266,7 +266,8 @@ static int __f2fs_set_acl(struct mnt_idmap *idmap,
>               }
>       }
>  
> -     error = f2fs_setxattr(inode, name_index, "", value, size, ipage, 0);
> +     error = f2fs_setxattr(inode, name_index, "", value, size,
> +                                             ipage, 0, locked);
>  
>       kfree(value);
>       if (!error)
> @@ -284,7 +285,7 @@ int f2fs_set_acl(struct mnt_idmap *idmap, struct dentry 
> *dentry,
>       if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
>               return -EIO;
>  
> -     return __f2fs_set_acl(idmap, inode, type, acl, NULL);
> +     return __f2fs_set_acl(idmap, inode, type, acl, NULL, false);
>  }
>  
>  /*
> @@ -362,7 +363,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, 
> umode_t *mode_p)
>  
>  static int f2fs_acl_create(struct inode *dir, umode_t *mode,
>               struct posix_acl **default_acl, struct posix_acl **acl,
> -             struct page *dpage)
> +             struct page *dpage, bool locked)
>  {
>       struct posix_acl *p;
>       struct posix_acl *clone;
> @@ -374,7 +375,7 @@ static int f2fs_acl_create(struct inode *dir, umode_t 
> *mode,
>       if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
>               return 0;
>  
> -     p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage);
> +     p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage, locked);
>       if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
>               *mode &= ~current_umask();
>               return 0;
> @@ -412,28 +413,29 @@ static int f2fs_acl_create(struct inode *dir, umode_t 
> *mode,
>  }
>  
>  int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage,
> -                                                     struct page *dpage)
> +                                             struct page *dpage, bool locked)
>  {
>       struct posix_acl *default_acl = NULL, *acl = NULL;
>       int error;
>  
> -     error = f2fs_acl_create(dir, &inode->i_mode, &default_acl, &acl, dpage);
> +     error = f2fs_acl_create(dir, &inode->i_mode, &default_acl, &acl,
> +                                                     dpage, locked);
>       if (error)
>               return error;
>  
>       f2fs_mark_inode_dirty_sync(inode, true);
>  
>       if (default_acl) {
> -             error = __f2fs_set_acl(NULL, inode, ACL_TYPE_DEFAULT, 
> default_acl,
> -                                    ipage);
> +             error = __f2fs_set_acl(NULL, inode, ACL_TYPE_DEFAULT,
> +                                     default_acl, ipage, locked);
>               posix_acl_release(default_acl);
>       } else {
>               inode->i_default_acl = NULL;
>       }
>       if (acl) {
>               if (!error)
> -                     error = __f2fs_set_acl(NULL, inode, ACL_TYPE_ACCESS, 
> acl,
> -                                            ipage);
> +                     error = __f2fs_set_acl(NULL, inode, ACL_TYPE_ACCESS,
> +                                                     acl, ipage, locked);
>               posix_acl_release(acl);
>       } else {
>               inode->i_acl = NULL;
> diff --git a/fs/f2fs/acl.h b/fs/f2fs/acl.h
> index 94ebfbfbdc6f..9c14b6f549c6 100644
> --- a/fs/f2fs/acl.h
> +++ b/fs/f2fs/acl.h
> @@ -37,13 +37,13 @@ extern struct posix_acl *f2fs_get_acl(struct inode *, 
> int, bool);
>  extern int f2fs_set_acl(struct mnt_idmap *, struct dentry *,
>                       struct posix_acl *, int);
>  extern int f2fs_init_acl(struct inode *, struct inode *, struct page *,
> -                                                     struct page *);
> +                                                     struct page *, bool);
>  #else
>  #define f2fs_get_acl NULL
>  #define f2fs_set_acl NULL
>  
>  static inline int f2fs_init_acl(struct inode *inode, struct inode *dir,
> -                             struct page *ipage, struct page *dpage)
> +                     struct page *ipage, struct page *dpage, bool locked)
>  {
>       return 0;
>  }
> diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
> index d635c58cf5a3..4b5c62e18d67 100644
> --- a/fs/f2fs/dir.c
> +++ b/fs/f2fs/dir.c
> @@ -540,6 +540,8 @@ struct page *f2fs_init_inode_metadata(struct inode 
> *inode, struct inode *dir,
>       int err;
>  
>       if (is_inode_flag_set(inode, FI_NEW_INODE)) {
> +             struct f2fs_xattr_arg xarg;
> +
>               page = f2fs_new_inode_page(inode);
>               if (IS_ERR(page))
>                       return page;
> @@ -555,12 +557,16 @@ struct page *f2fs_init_inode_metadata(struct inode 
> *inode, struct inode *dir,
>                       put_page(page);
>               }
>  
> -             err = f2fs_init_acl(inode, dir, page, dpage);
> +             err = f2fs_init_acl(inode, dir, page, dpage, true);
>               if (err)
>                       goto put_error;
>  
> +             xarg.page = page;
> +             xarg.locked = true;
> +
>               err = f2fs_init_security(inode, dir,
> -                                      fname ? fname->usr_fname : NULL, page);
> +                                      fname ? fname->usr_fname : NULL,
> +                                      &xarg);
>               if (err)
>                       goto put_error;
>  
> @@ -775,18 +781,20 @@ int f2fs_add_dentry(struct inode *dir, const struct 
> f2fs_filename *fname,
>  {
>       int err = -EAGAIN;
>  
> +     f2fs_down_read(&F2FS_I(dir)->i_sem);
> +
>       if (f2fs_has_inline_dentry(dir)) {
>               /*
> -              * Should get i_xattr_sem to keep the lock order:
> -              * i_xattr_sem -> inode_page lock used by f2fs_setxattr.
> +              * Should get i_sem to keep the lock order:
> +              * i_sem -> inode_page lock used by f2fs_setxattr.
>                */
> -             f2fs_down_read(&F2FS_I(dir)->i_xattr_sem);
>               err = f2fs_add_inline_entry(dir, fname, inode, ino, mode);
> -             f2fs_up_read(&F2FS_I(dir)->i_xattr_sem);
>       }
>       if (err == -EAGAIN)
>               err = f2fs_add_regular_entry(dir, fname, inode, ino, mode);
>  
> +     f2fs_up_read(&F2FS_I(dir)->i_sem);
> +
>       f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
>       return err;
>  }
> @@ -835,6 +843,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode 
> *dir)
>       struct page *page;
>       int err = 0;
>  
> +     f2fs_down_write(&F2FS_I(dir)->i_sem);
>       f2fs_down_write(&F2FS_I(inode)->i_sem);
>       page = f2fs_init_inode_metadata(inode, dir, NULL, NULL);
>       if (IS_ERR(page)) {
> @@ -847,6 +856,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode 
> *dir)
>       f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
>  fail:
>       f2fs_up_write(&F2FS_I(inode)->i_sem);
> +     f2fs_up_write(&F2FS_I(dir)->i_sem);
>       return err;
>  }
>  
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index c7cb2177b252..60ec032be48d 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -838,7 +838,6 @@ struct f2fs_inode_info {
>  
>       /* avoid racing between foreground op and gc */
>       struct f2fs_rwsem i_gc_rwsem[2];
> -     struct f2fs_rwsem 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 ca31163da00a..c72fda24cffd 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -1418,7 +1418,6 @@ static struct inode *f2fs_alloc_inode(struct 
> super_block *sb)
>       INIT_LIST_HEAD(&fi->gdirty_list);
>       init_f2fs_rwsem(&fi->i_gc_rwsem[READ]);
>       init_f2fs_rwsem(&fi->i_gc_rwsem[WRITE]);
> -     init_f2fs_rwsem(&fi->i_xattr_sem);
>  
>       /* Will be used by directory only */
>       fi->i_dir_level = F2FS_SB(sb)->dir_level;
> @@ -3163,7 +3162,7 @@ static int f2fs_get_context(struct inode *inode, void 
> *ctx, size_t len)
>  {
>       return f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
>                               F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
> -                             ctx, len, NULL);
> +                             ctx, len, NULL, false);
>  }
>  
>  static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
> @@ -3183,7 +3182,7 @@ static int f2fs_set_context(struct inode *inode, const 
> void *ctx, size_t len,
>  
>       return f2fs_setxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
>                               F2FS_XATTR_NAME_ENCRYPTION_CONTEXT,
> -                             ctx, len, fs_data, XATTR_CREATE);
> +                             ctx, len, fs_data, XATTR_CREATE, true);
>  }
>  
>  static const union fscrypt_policy *f2fs_get_dummy_policy(struct super_block 
> *sb)
> diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
> index 4fc95f353a7a..e181528b1f26 100644
> --- a/fs/f2fs/verity.c
> +++ b/fs/f2fs/verity.c
> @@ -181,7 +181,7 @@ static int f2fs_end_enable_verity(struct file *filp, 
> const void *desc,
>       /* Set the verity xattr. */
>       err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_VERITY,
>                           F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc),
> -                         NULL, XATTR_CREATE);
> +                         NULL, XATTR_CREATE, false);
>       if (err)
>               goto cleanup;
>  
> @@ -226,7 +226,8 @@ static int f2fs_get_verity_descriptor(struct inode 
> *inode, void *buf,
>  
>       /* Get the descriptor location */
>       res = f2fs_getxattr(inode, F2FS_XATTR_INDEX_VERITY,
> -                         F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc), NULL);
> +                         F2FS_XATTR_NAME_VERITY, &dloc, sizeof(dloc),
> +                         NULL, false);
>       if (res < 0 && res != -ERANGE)
>               return res;
>       if (res != sizeof(dloc) || dloc.version != 
> cpu_to_le32(F2FS_VERIFY_VER)) {
> diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
> index 476b186b90a6..a6a611f8a771 100644
> --- a/fs/f2fs/xattr.c
> +++ b/fs/f2fs/xattr.c
> @@ -61,7 +61,7 @@ static int f2fs_xattr_generic_get(const struct 
> xattr_handler *handler,
>               return -EINVAL;
>       }
>       return f2fs_getxattr(inode, handler->flags, name,
> -                          buffer, size, NULL);
> +                          buffer, size, NULL, false);
>  }
>  
>  static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
> @@ -84,7 +84,7 @@ static int f2fs_xattr_generic_set(const struct 
> xattr_handler *handler,
>               return -EINVAL;
>       }
>       return f2fs_setxattr(inode, handler->flags, name,
> -                                     value, size, NULL, flags);
> +                                     value, size, NULL, flags, false);
>  }
>  
>  static bool f2fs_xattr_user_list(struct dentry *dentry)
> @@ -136,15 +136,16 @@ static int f2fs_xattr_advise_set(const struct 
> xattr_handler *handler,
>  
>  #ifdef CONFIG_F2FS_FS_SECURITY
>  static int f2fs_initxattrs(struct inode *inode, const struct xattr 
> *xattr_array,
> -             void *page)
> +                                                             void *fs_data)
>  {
> +     struct f2fs_xattr_arg *xarg = (struct f2fs_xattr_arg *)fs_data;
>       const struct xattr *xattr;
>       int err = 0;
>  
>       for (xattr = xattr_array; xattr->name != NULL; xattr++) {
>               err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY,
>                               xattr->name, xattr->value,
> -                             xattr->value_len, (struct page *)page, 0);
> +                             xattr->value_len, xarg->page, 0, xarg->locked);
>               if (err < 0)
>                       break;
>       }
> @@ -152,10 +153,11 @@ static int f2fs_initxattrs(struct inode *inode, const 
> struct xattr *xattr_array,
>  }
>  
>  int f2fs_init_security(struct inode *inode, struct inode *dir,
> -                             const struct qstr *qstr, struct page *ipage)
> +                             const struct qstr *qstr,
> +                             struct f2fs_xattr_arg *xarg)
>  {
>       return security_inode_init_security(inode, dir, qstr,
> -                             &f2fs_initxattrs, ipage);
> +                             &f2fs_initxattrs, xarg);
>  }
>  #endif
>  
> @@ -512,7 +514,8 @@ static inline int write_all_xattrs(struct inode *inode, 
> __u32 hsize,
>  }
>  
>  int f2fs_getxattr(struct inode *inode, int index, const char *name,
> -             void *buffer, size_t buffer_size, struct page *ipage)
> +                             void *buffer, size_t buffer_size,
> +                             struct page *ipage, bool locked)
>  {
>       struct f2fs_xattr_entry *entry = NULL;
>       int error;
> @@ -528,12 +531,12 @@ int f2fs_getxattr(struct inode *inode, int index, const 
> char *name,
>       if (len > F2FS_NAME_LEN)
>               return -ERANGE;
>  
> -     if (!ipage)
> -             f2fs_down_read(&F2FS_I(inode)->i_xattr_sem);
> +     if (!locked)
> +             f2fs_down_read(&F2FS_I(inode)->i_sem);
>       error = lookup_all_xattrs(inode, ipage, index, len, name,
>                               &entry, &base_addr, &base_size, &is_inline);
> -     if (!ipage)
> -             f2fs_up_read(&F2FS_I(inode)->i_xattr_sem);
> +     if (!locked)
> +             f2fs_up_read(&F2FS_I(inode)->i_sem);
>       if (error)
>               return error;
>  
> @@ -567,9 +570,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char 
> *buffer, size_t buffer_size)
>       int error;
>       size_t rest = buffer_size;
>  
> -     f2fs_down_read(&F2FS_I(inode)->i_xattr_sem);
> +     f2fs_down_read(&F2FS_I(inode)->i_sem);
>       error = read_all_xattrs(inode, NULL, &base_addr);
> -     f2fs_up_read(&F2FS_I(inode)->i_xattr_sem);
> +     f2fs_up_read(&F2FS_I(inode)->i_sem);
>       if (error)
>               return error;
>  
> @@ -775,7 +778,7 @@ static int __f2fs_setxattr(struct inode *inode, int index,
>  
>  int f2fs_setxattr(struct inode *inode, int index, const char *name,
>                               const void *value, size_t size,
> -                             struct page *ipage, int flags)
> +                             struct page *ipage, int flags, bool locked)
>  {
>       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
>       int err;
> @@ -796,9 +799,11 @@ int f2fs_setxattr(struct inode *inode, int index, const 
> char *name,
>       f2fs_balance_fs(sbi, true);
>  
>       f2fs_lock_op(sbi);
> -     f2fs_down_write(&F2FS_I(inode)->i_xattr_sem);
> +     if (!locked)
> +             f2fs_down_write(&F2FS_I(inode)->i_sem);
>       err = __f2fs_setxattr(inode, index, name, value, size, ipage, flags);
> -     f2fs_up_write(&F2FS_I(inode)->i_xattr_sem);
> +     if (!locked)
> +             f2fs_up_write(&F2FS_I(inode)->i_sem);
>       f2fs_unlock_op(sbi);
>  
>       f2fs_update_time(sbi, REQ_TIME);
> diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h
> index b1811c392e6f..170e4a49af31 100644
> --- a/fs/f2fs/xattr.h
> +++ b/fs/f2fs/xattr.h
> @@ -52,6 +52,11 @@ struct f2fs_xattr_entry {
>       char    e_name[];      /* attribute name */
>  };
>  
> +struct f2fs_xattr_arg {
> +     struct page *page;      /* inode page */
> +     bool locked;            /* indicate i_sem is locked */
> +};
> +
>  #define XATTR_HDR(ptr)               ((struct f2fs_xattr_header *)(ptr))
>  #define XATTR_ENTRY(ptr)     ((struct f2fs_xattr_entry *)(ptr))
>  #define XATTR_FIRST_ENTRY(ptr)       (XATTR_ENTRY(XATTR_HDR(ptr) + 1))
> @@ -128,9 +133,9 @@ extern const struct xattr_handler 
> f2fs_xattr_security_handler;
>  extern const struct xattr_handler *f2fs_xattr_handlers[];
>  
>  extern int f2fs_setxattr(struct inode *, int, const char *,
> -                             const void *, size_t, struct page *, int);
> +                             const void *, size_t, struct page *, int, bool);
>  extern int f2fs_getxattr(struct inode *, int, const char *, void *,
> -                                             size_t, struct page *);
> +                                     size_t, struct page *, bool locked);
>  extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t);
>  extern int f2fs_init_xattr_caches(struct f2fs_sb_info *);
>  extern void f2fs_destroy_xattr_caches(struct f2fs_sb_info *);
> @@ -140,13 +145,13 @@ extern void f2fs_destroy_xattr_caches(struct 
> f2fs_sb_info *);
>  #define f2fs_listxattr               NULL
>  static inline int f2fs_setxattr(struct inode *inode, int index,
>               const char *name, const void *value, size_t size,
> -             struct page *page, int flags)
> +             struct page *page, int flags, bool locked)
>  {
>       return -EOPNOTSUPP;
>  }
>  static inline int f2fs_getxattr(struct inode *inode, int index,
>                       const char *name, void *buffer,
> -                     size_t buffer_size, struct page *dpage)
> +                     size_t buffer_size, struct page *dpage, bool locked)
>  {
>       return -EOPNOTSUPP;
>  }
> @@ -156,10 +161,12 @@ static inline void f2fs_destroy_xattr_caches(struct 
> f2fs_sb_info *sbi) { }
>  
>  #ifdef CONFIG_F2FS_FS_SECURITY
>  extern int f2fs_init_security(struct inode *, struct inode *,
> -                             const struct qstr *, struct page *);
> +                                     const struct qstr *,
> +                                     struct f2fs_xattr_arg *xarg);
>  #else
>  static inline int f2fs_init_security(struct inode *inode, struct inode *dir,
> -                             const struct qstr *qstr, struct page *ipage)
> +                                     const struct qstr *qstr,
> +                                     struct f2fs_xattr_arg *xarg)
>  {
>       return 0;
>  }
> -- 
> 2.40.1


_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to