From e112326805a50ee2016faf0971660122471f7c04 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Apr 2014 12:17:25 +0900 Subject: f2fs: clean up long variable names This patch includes simple clean-ups to reduce unnecessary long variable names. Signed-off-by: Jaegeuk Kim --- fs/f2fs/xattr.c | 86 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) (limited to 'fs/f2fs/xattr.c') diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 503c2451131..1de057d9e7a 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -26,7 +26,7 @@ #include "xattr.h" static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, - size_t list_size, const char *name, size_t name_len, int type) + size_t list_size, const char *name, size_t len, int type) { struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); int total_len, prefix_len = 0; @@ -53,11 +53,11 @@ static size_t f2fs_xattr_generic_list(struct dentry *dentry, char *list, return -EINVAL; } - total_len = prefix_len + name_len + 1; + total_len = prefix_len + len + 1; if (list && total_len <= list_size) { memcpy(list, prefix, prefix_len); - memcpy(list + prefix_len, name, name_len); - list[prefix_len + name_len] = '\0'; + memcpy(list + prefix_len, name, len); + list[prefix_len + len] = '\0'; } return total_len; } @@ -112,7 +112,7 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, } static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list, - size_t list_size, const char *name, size_t name_len, int type) + size_t list_size, const char *name, size_t len, int type) { const char *xname = F2FS_SYSTEM_ADVISE_PREFIX; size_t size; @@ -155,9 +155,10 @@ static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name, } #ifdef CONFIG_F2FS_FS_SECURITY -static int __f2fs_setxattr(struct inode *inode, int name_index, - const char *name, const void *value, size_t value_len, +static int __f2fs_setxattr(struct inode *inode, int index, + const char *name, const void *value, size_t size, struct page *ipage); + static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array, void *page) { @@ -241,26 +242,26 @@ const struct xattr_handler *f2fs_xattr_handlers[] = { NULL, }; -static inline const struct xattr_handler *f2fs_xattr_handler(int name_index) +static inline const struct xattr_handler *f2fs_xattr_handler(int index) { const struct xattr_handler *handler = NULL; - if (name_index > 0 && name_index < ARRAY_SIZE(f2fs_xattr_handler_map)) - handler = f2fs_xattr_handler_map[name_index]; + if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map)) + handler = f2fs_xattr_handler_map[index]; return handler; } -static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int name_index, - size_t name_len, const char *name) +static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int index, + size_t len, const char *name) { struct f2fs_xattr_entry *entry; list_for_each_xattr(entry, base_addr) { - if (entry->e_name_index != name_index) + if (entry->e_name_index != index) continue; - if (entry->e_name_len != name_len) + if (entry->e_name_len != len) continue; - if (!memcmp(entry->e_name, name, name_len)) + if (!memcmp(entry->e_name, name, len)) break; } return entry; @@ -396,42 +397,43 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize, return 0; } -int f2fs_getxattr(struct inode *inode, int name_index, const char *name, +int f2fs_getxattr(struct inode *inode, int index, const char *name, void *buffer, size_t buffer_size) { struct f2fs_xattr_entry *entry; void *base_addr; int error = 0; - size_t value_len, name_len; + size_t size, len; if (name == NULL) return -EINVAL; - name_len = strlen(name); - if (name_len > F2FS_NAME_LEN) + + len = strlen(name); + if (len > F2FS_NAME_LEN) return -ERANGE; base_addr = read_all_xattrs(inode, NULL); if (!base_addr) return -ENOMEM; - entry = __find_xattr(base_addr, name_index, name_len, name); + entry = __find_xattr(base_addr, index, len, name); if (IS_XATTR_LAST_ENTRY(entry)) { error = -ENODATA; goto cleanup; } - value_len = le16_to_cpu(entry->e_value_size); + size = le16_to_cpu(entry->e_value_size); - if (buffer && value_len > buffer_size) { + if (buffer && size > buffer_size) { error = -ERANGE; goto cleanup; } if (buffer) { char *pval = entry->e_name + entry->e_name_len; - memcpy(buffer, pval, value_len); + memcpy(buffer, pval, size); } - error = value_len; + error = size; cleanup: kzfree(base_addr); @@ -475,15 +477,15 @@ cleanup: return error; } -static int __f2fs_setxattr(struct inode *inode, int name_index, - const char *name, const void *value, size_t value_len, +static int __f2fs_setxattr(struct inode *inode, int index, + const char *name, const void *value, size_t size, struct page *ipage) { struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_xattr_entry *here, *last; void *base_addr; int found, newsize; - size_t name_len; + size_t len; __u32 new_hsize; int error = -ENOMEM; @@ -491,11 +493,11 @@ static int __f2fs_setxattr(struct inode *inode, int name_index, return -EINVAL; if (value == NULL) - value_len = 0; + size = 0; - name_len = strlen(name); + len = strlen(name); - if (name_len > F2FS_NAME_LEN || value_len > MAX_VALUE_LEN(inode)) + if (len > F2FS_NAME_LEN || size > MAX_VALUE_LEN(inode)) return -ERANGE; base_addr = read_all_xattrs(inode, ipage); @@ -503,7 +505,7 @@ static int __f2fs_setxattr(struct inode *inode, int name_index, goto exit; /* find entry with wanted name. */ - here = __find_xattr(base_addr, name_index, name_len, name); + here = __find_xattr(base_addr, index, len, name); found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1; last = here; @@ -511,8 +513,7 @@ static int __f2fs_setxattr(struct inode *inode, int name_index, while (!IS_XATTR_LAST_ENTRY(last)) last = XATTR_NEXT_ENTRY(last); - newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + - name_len + value_len); + newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + len + size); /* 1. Check space */ if (value) { @@ -555,12 +556,12 @@ static int __f2fs_setxattr(struct inode *inode, int name_index, * We just write new entry. */ memset(last, 0, newsize); - last->e_name_index = name_index; - last->e_name_len = name_len; - memcpy(last->e_name, name, name_len); - pval = last->e_name + name_len; - memcpy(pval, value, value_len); - last->e_value_size = cpu_to_le16(value_len); + last->e_name_index = index; + last->e_name_len = len; + memcpy(last->e_name, name, len); + pval = last->e_name + len; + memcpy(pval, value, size); + last->e_value_size = cpu_to_le16(size); new_hsize += newsize; } @@ -583,8 +584,9 @@ exit: return error; } -int f2fs_setxattr(struct inode *inode, int name_index, const char *name, - const void *value, size_t value_len, struct page *ipage) +int f2fs_setxattr(struct inode *inode, int index, const char *name, + const void *value, size_t size, + struct page *ipage) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); int err; @@ -594,7 +596,7 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name, f2fs_lock_op(sbi); /* protect xattr_ver */ down_write(&F2FS_I(inode)->i_sem); - err = __f2fs_setxattr(inode, name_index, name, value, value_len, ipage); + err = __f2fs_setxattr(inode, index, name, value, size, ipage); up_write(&F2FS_I(inode)->i_sem); f2fs_unlock_op(sbi); -- cgit v1.2.3-70-g09d2 From c02745ef684f9a6f98f30388ed048ee460db5483 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Apr 2014 12:23:14 +0900 Subject: f2fs: pass flags field to setxattr functions This patch passes the "flags" field to the low level setxattr functions to use XATTR_REPLACE in the following patches. Signed-off-by: Jaegeuk Kim --- fs/f2fs/acl.c | 2 +- fs/f2fs/xattr.c | 13 +++++++------ fs/f2fs/xattr.h | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'fs/f2fs/xattr.c') diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index e93e4ec7d16..dbe2141d10a 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -240,7 +240,7 @@ static int __f2fs_set_acl(struct inode *inode, int type, } } - error = f2fs_setxattr(inode, name_index, "", value, size, ipage); + error = f2fs_setxattr(inode, name_index, "", value, size, ipage, 0); kfree(value); if (!error) diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 1de057d9e7a..bbe9c2badf5 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -108,7 +108,8 @@ static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name, if (strcmp(name, "") == 0) return -EINVAL; - return f2fs_setxattr(dentry->d_inode, type, name, value, size, NULL); + return f2fs_setxattr(dentry->d_inode, type, name, + value, size, NULL, flags); } static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list, @@ -157,7 +158,7 @@ static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name, #ifdef CONFIG_F2FS_FS_SECURITY static int __f2fs_setxattr(struct inode *inode, int index, const char *name, const void *value, size_t size, - struct page *ipage); + struct page *ipage, int); static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array, void *page) @@ -168,7 +169,7 @@ static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array, 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); + xattr->value_len, (struct page *)page, 0); if (err < 0) break; } @@ -479,7 +480,7 @@ cleanup: static int __f2fs_setxattr(struct inode *inode, int index, const char *name, const void *value, size_t size, - struct page *ipage) + struct page *ipage, int flags) { struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_xattr_entry *here, *last; @@ -586,7 +587,7 @@ exit: int f2fs_setxattr(struct inode *inode, int index, const char *name, const void *value, size_t size, - struct page *ipage) + struct page *ipage, int flags) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); int err; @@ -596,7 +597,7 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, f2fs_lock_op(sbi); /* protect xattr_ver */ down_write(&F2FS_I(inode)->i_sem); - err = __f2fs_setxattr(inode, index, name, value, size, ipage); + err = __f2fs_setxattr(inode, index, name, value, size, ipage, flags); up_write(&F2FS_I(inode)->i_sem); f2fs_unlock_op(sbi); diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h index 79bc2bb32ae..34ab7dbcf5e 100644 --- a/fs/f2fs/xattr.h +++ b/fs/f2fs/xattr.h @@ -114,14 +114,14 @@ 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 *); + const void *, size_t, struct page *, int); extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t); extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t); #else #define f2fs_xattr_handlers NULL static inline int f2fs_setxattr(struct inode *inode, int index, - const char *name, const void *value, size_t size) + const char *name, const void *value, size_t size, int flags) { return -EOPNOTSUPP; } -- cgit v1.2.3-70-g09d2 From 916decbf3913ccdc68f0228e001a6d270cf5682e Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 23 Apr 2014 12:28:18 +0900 Subject: f2fs: return errors right after checking them This patch adds two error conditions early in the setxattr operations. Signed-off-by: Jaegeuk Kim --- fs/f2fs/xattr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'fs/f2fs/xattr.c') diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index bbe9c2badf5..6073f9f8841 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -509,8 +509,16 @@ static int __f2fs_setxattr(struct inode *inode, int index, here = __find_xattr(base_addr, index, len, name); found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1; - last = here; + if ((flags & XATTR_REPLACE) && !found) { + error = -ENODATA; + goto exit; + } else if ((flags & XATTR_CREATE) && found) { + error = -EEXIST; + goto exit; + } + + last = here; while (!IS_XATTR_LAST_ENTRY(last)) last = XATTR_NEXT_ENTRY(last); -- cgit v1.2.3-70-g09d2 From 54b591dfda1f5ab0bc2a9ce1bee5364110168777 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Tue, 29 Apr 2014 17:28:32 +0900 Subject: f2fs: split grab_cache_page and wait_on_page_writeback for node pages This patch splits grab_cache_page_write_begin into grab_cache_page and wait_on_page_writeback for node pages. This patch intends to enhance the latency to get node pages by alleviating unnecessary wait_on_page_writeback. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 2 ++ fs/f2fs/inline.c | 6 ++++++ fs/f2fs/node.c | 8 ++++---- fs/f2fs/node.h | 2 +- fs/f2fs/xattr.c | 3 +++ 5 files changed, 16 insertions(+), 5 deletions(-) (limited to 'fs/f2fs/xattr.c') diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 3581c2bde21..c3f148555c3 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -268,6 +268,8 @@ static void init_dent_inode(const struct qstr *name, struct page *ipage) { struct f2fs_inode *ri; + f2fs_wait_on_page_writeback(ipage, NODE); + /* copy name info. to this inode page */ ri = F2FS_INODE(ipage); ri->i_namelen = cpu_to_le32(name->len); diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index d215dbb09f0..8bf34f052f6 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -156,6 +156,7 @@ int f2fs_write_inline_data(struct inode *inode, return err; ipage = dn.inode_page; + f2fs_wait_on_page_writeback(ipage, NODE); zero_user_segment(ipage, INLINE_DATA_OFFSET, INLINE_DATA_OFFSET + MAX_INLINE_DATA); src_addr = kmap(page); @@ -188,6 +189,8 @@ void truncate_inline_data(struct inode *inode, u64 from) if (IS_ERR(ipage)) return; + f2fs_wait_on_page_writeback(ipage, NODE); + zero_user_segment(ipage, INLINE_DATA_OFFSET + from, INLINE_DATA_OFFSET + MAX_INLINE_DATA); set_page_dirty(ipage); @@ -218,6 +221,8 @@ process_inline: ipage = get_node_page(sbi, inode->i_ino); f2fs_bug_on(IS_ERR(ipage)); + f2fs_wait_on_page_writeback(ipage, NODE); + src_addr = inline_data_addr(npage); dst_addr = inline_data_addr(ipage); memcpy(dst_addr, src_addr, MAX_INLINE_DATA); @@ -229,6 +234,7 @@ process_inline: if (f2fs_has_inline_data(inode)) { ipage = get_node_page(sbi, inode->i_ino); f2fs_bug_on(IS_ERR(ipage)); + f2fs_wait_on_page_writeback(ipage, NODE); zero_user_segment(ipage, INLINE_DATA_OFFSET, INLINE_DATA_OFFSET + MAX_INLINE_DATA); clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 2803ef6cf53..059aaf5dda2 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -853,8 +853,7 @@ struct page *new_node_page(struct dnode_of_data *dn, if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC))) return ERR_PTR(-EPERM); - page = grab_cache_page_write_begin(NODE_MAPPING(sbi), - dn->nid, AOP_FLAG_NOFS); + page = grab_cache_page(NODE_MAPPING(sbi), dn->nid); if (!page) return ERR_PTR(-ENOMEM); @@ -871,6 +870,7 @@ struct page *new_node_page(struct dnode_of_data *dn, new_ni.ino = dn->inode->i_ino; set_node_addr(sbi, &new_ni, NEW_ADDR, false); + f2fs_wait_on_page_writeback(page, NODE); fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true); set_cold_node(dn->inode, page); SetPageUptodate(page); @@ -950,8 +950,7 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid) struct page *page; int err; repeat: - page = grab_cache_page_write_begin(NODE_MAPPING(sbi), - nid, AOP_FLAG_NOFS); + page = grab_cache_page(NODE_MAPPING(sbi), nid); if (!page) return ERR_PTR(-ENOMEM); @@ -1562,6 +1561,7 @@ static void recover_inline_xattr(struct inode *inode, struct page *page) src_addr = inline_xattr_addr(page); inline_size = inline_xattr_size(inode); + f2fs_wait_on_page_writeback(ipage, NODE); memcpy(dst_addr, src_addr, inline_size); update_inode(inode, ipage); diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index a076c88bdca..4ee29d506f8 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -272,7 +272,7 @@ static inline void set_nid(struct page *p, int off, nid_t nid, bool i) { struct f2fs_node *rn = F2FS_NODE(p); - wait_on_page_writeback(p); + f2fs_wait_on_page_writeback(p, NODE); if (i) rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid); diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 6073f9f8841..1f546b4b6b6 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -349,6 +349,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize, if (ipage) { inline_addr = inline_xattr_addr(ipage); + f2fs_wait_on_page_writeback(ipage, NODE); } else { page = get_node_page(sbi, inode->i_ino); if (IS_ERR(page)) { @@ -356,6 +357,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize, return PTR_ERR(page); } inline_addr = inline_xattr_addr(page); + f2fs_wait_on_page_writeback(page, NODE); } memcpy(inline_addr, txattr_addr, inline_size); f2fs_put_page(page, 1); @@ -376,6 +378,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize, return PTR_ERR(xpage); } f2fs_bug_on(new_nid); + f2fs_wait_on_page_writeback(xpage, NODE); } else { struct dnode_of_data dn; set_new_dnode(&dn, inode, NULL, NULL, new_nid); -- cgit v1.2.3-70-g09d2 From d631abdac9d541d282a1461b5aeae70aa3866e9f Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Sun, 1 Jun 2014 23:24:30 +0900 Subject: f2fs: fix recursive lock by f2fs_setxattr This patch should resolve the following recursive lock. [] call_rwsem_down_write_failed+0x13/0x20 [] f2fs_setxattr+0x5c/0xa0 [f2fs] [] __f2fs_set_acl+0x1b9/0x340 [f2fs] [] f2fs_init_acl+0x4a/0xcb [f2fs] [] __f2fs_add_link+0x26e/0x780 [f2fs] [] f2fs_mkdir+0xb8/0x150 [f2fs] [] vfs_mkdir+0xb7/0x160 [] SyS_mkdir+0xab/0xe0 [] tracesys+0xe1/0xe6 [] 0xffffffffffffffff The call path indicates: - f2fs_add_link : down_write(&fi->i_sem); - init_inode_metadata - f2fs_init_acl - __f2fs_set_acl - f2fs_setxattr : down_write(&fi->i_sem); Here we should not call f2fs_setxattr, but __f2fs_setxattr. But __f2fs_setxattr is a static function in xattr.c, so that I found the other generic approach to use f2fs_setxattr. In f2fs_setxattr, the page pointer is only given from init_inode_metadata. So, this patch adds this condition to avoid this in f2fs_setxattr. Signed-off-by: Jaegeuk Kim --- fs/f2fs/xattr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'fs/f2fs/xattr.c') diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 1f546b4b6b6..8bea941ee30 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -156,10 +156,6 @@ static int f2fs_xattr_advise_set(struct dentry *dentry, const char *name, } #ifdef CONFIG_F2FS_FS_SECURITY -static int __f2fs_setxattr(struct inode *inode, int index, - const char *name, const void *value, size_t size, - struct page *ipage, int); - static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array, void *page) { @@ -167,7 +163,7 @@ static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array, int err = 0; for (xattr = xattr_array; xattr->name != NULL; xattr++) { - err = __f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY, + err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY, xattr->name, xattr->value, xattr->value_len, (struct page *)page, 0); if (err < 0) @@ -603,6 +599,10 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); int err; + /* this case is only from init_inode_metadata */ + if (ipage) + return __f2fs_setxattr(inode, index, name, value, + size, ipage, flags); f2fs_balance_fs(sbi); f2fs_lock_op(sbi); -- cgit v1.2.3-70-g09d2