lkml.org 
[lkml]   [2017]   [Jun]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Tracking struct inode * rather than the inode number eliminates the
    repeated ext4_xattr_inode_iget() call later. The second call cannot
    fail in practice but still requires explanation when it wants to ignore
    the return value. Avoid the trouble and make things simple.

    Signed-off-by: Tahsin Erdogan <tahsin@google.com>
    ---
    fs/ext4/ext4.h | 6 ++--
    fs/ext4/inode.c | 8 ++---
    fs/ext4/xattr.c | 93 ++++++++++++++++++++++++++++-----------------------------
    fs/ext4/xattr.h | 5 ++--
    4 files changed, 53 insertions(+), 59 deletions(-)

    diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
    index 2cdd6070e348..603edb5ff304 100644
    --- a/fs/ext4/ext4.h
    +++ b/fs/ext4/ext4.h
    @@ -2232,9 +2232,9 @@ struct mmpd_data {
    # define ATTRIB_NORET __attribute__((noreturn))
    # define NORET_AND noreturn,

    -struct ext4_xattr_ino_array {
    - unsigned int xia_count; /* # of used item in the array */
    - unsigned int xia_inodes[0];
    +struct ext4_xattr_inode_array {
    + unsigned int count; /* # of used items in the array */
    + struct inode *inodes[0];
    };
    /* bitmap.c */
    extern unsigned int ext4_count_free(char *bitmap, unsigned numchars);
    diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
    index d095bf7ad390..8ee20b586567 100644
    --- a/fs/ext4/inode.c
    +++ b/fs/ext4/inode.c
    @@ -188,7 +188,7 @@ void ext4_evict_inode(struct inode *inode)
    handle_t *handle;
    int err;
    int extra_credits = 3;
    - struct ext4_xattr_ino_array *lea_ino_array = NULL;
    + struct ext4_xattr_inode_array *ea_inode_array = NULL;

    trace_ext4_evict_inode(inode);

    @@ -257,7 +257,7 @@ void ext4_evict_inode(struct inode *inode)
    /*
    * Delete xattr inode before deleting the main inode.
    */
    - err = ext4_xattr_delete_inode(handle, inode, &lea_ino_array);
    + err = ext4_xattr_delete_inode(handle, inode, &ea_inode_array);
    if (err) {
    ext4_warning(inode->i_sb,
    "couldn't delete inode's xattr (err %d)", err);
    @@ -345,9 +345,7 @@ void ext4_evict_inode(struct inode *inode)

    ext4_journal_stop(handle);
    sb_end_intwrite(inode->i_sb);
    -
    - if (lea_ino_array != NULL)
    - ext4_xattr_inode_array_free(inode, lea_ino_array);
    + ext4_xattr_inode_array_free(ea_inode_array);
    return;
    no_delete:
    ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
    diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
    index fd017faaf221..c09fcffb0878 100644
    --- a/fs/ext4/xattr.c
    +++ b/fs/ext4/xattr.c
    @@ -1942,44 +1942,44 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,

    #define EIA_INCR 16 /* must be 2^n */
    #define EIA_MASK (EIA_INCR - 1)
    -/* Add the large xattr @ino into @lea_ino_array for later deletion.
    - * If @lea_ino_array is new or full it will be grown and the old
    +/* Add the large xattr @inode into @ea_inode_array for later deletion.
    + * If @ea_inode_array is new or full it will be grown and the old
    * contents copied over.
    */
    static int
    -ext4_expand_ino_array(struct ext4_xattr_ino_array **lea_ino_array, __u32 ino)
    +ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array,
    + struct inode *inode)
    {
    - if (*lea_ino_array == NULL) {
    + if (*ea_inode_array == NULL) {
    /*
    * Start with 15 inodes, so it fits into a power-of-two size.
    - * If *lea_ino_array is NULL, this is essentially offsetof()
    + * If *ea_inode_array is NULL, this is essentially offsetof()
    */
    - (*lea_ino_array) =
    - kmalloc(offsetof(struct ext4_xattr_ino_array,
    - xia_inodes[EIA_MASK]),
    + (*ea_inode_array) =
    + kmalloc(offsetof(struct ext4_xattr_inode_array,
    + inodes[EIA_MASK]),
    GFP_NOFS);
    - if (*lea_ino_array == NULL)
    + if (*ea_inode_array == NULL)
    return -ENOMEM;
    - (*lea_ino_array)->xia_count = 0;
    - } else if (((*lea_ino_array)->xia_count & EIA_MASK) == EIA_MASK) {
    + (*ea_inode_array)->count = 0;
    + } else if (((*ea_inode_array)->count & EIA_MASK) == EIA_MASK) {
    /* expand the array once all 15 + n * 16 slots are full */
    - struct ext4_xattr_ino_array *new_array = NULL;
    - int count = (*lea_ino_array)->xia_count;
    + struct ext4_xattr_inode_array *new_array = NULL;
    + int count = (*ea_inode_array)->count;

    /* if new_array is NULL, this is essentially offsetof() */
    new_array = kmalloc(
    - offsetof(struct ext4_xattr_ino_array,
    - xia_inodes[count + EIA_INCR]),
    + offsetof(struct ext4_xattr_inode_array,
    + inodes[count + EIA_INCR]),
    GFP_NOFS);
    if (new_array == NULL)
    return -ENOMEM;
    - memcpy(new_array, *lea_ino_array,
    - offsetof(struct ext4_xattr_ino_array,
    - xia_inodes[count]));
    - kfree(*lea_ino_array);
    - *lea_ino_array = new_array;
    + memcpy(new_array, *ea_inode_array,
    + offsetof(struct ext4_xattr_inode_array, inodes[count]));
    + kfree(*ea_inode_array);
    + *ea_inode_array = new_array;
    }
    - (*lea_ino_array)->xia_inodes[(*lea_ino_array)->xia_count++] = ino;
    + (*ea_inode_array)->inodes[(*ea_inode_array)->count++] = inode;
    return 0;
    }

    @@ -1987,16 +1987,16 @@ ext4_expand_ino_array(struct ext4_xattr_ino_array **lea_ino_array, __u32 ino)
    * Add xattr inode to orphan list
    */
    static int
    -ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
    - int credits, struct ext4_xattr_ino_array *lea_ino_array)
    +ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode, int credits,
    + struct ext4_xattr_inode_array *ea_inode_array)
    {
    - struct inode *ea_inode;
    int idx = 0, error = 0;
    + struct inode *ea_inode;

    - if (lea_ino_array == NULL)
    + if (ea_inode_array == NULL)
    return 0;

    - for (; idx < lea_ino_array->xia_count; ++idx) {
    + for (; idx < ea_inode_array->count; ++idx) {
    if (!ext4_handle_has_enough_credits(handle, credits)) {
    error = ext4_journal_extend(handle, credits);
    if (error > 0)
    @@ -2009,10 +2009,7 @@ ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
    return error;
    }
    }
    - error = ext4_xattr_inode_iget(inode,
    - lea_ino_array->xia_inodes[idx], &ea_inode);
    - if (error)
    - continue;
    + ea_inode = ea_inode_array->inodes[idx];
    inode_lock(ea_inode);
    ext4_orphan_add(handle, ea_inode);
    inode_unlock(ea_inode);
    @@ -2034,13 +2031,14 @@ ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
    */
    int
    ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
    - struct ext4_xattr_ino_array **lea_ino_array)
    + struct ext4_xattr_inode_array **ea_inode_array)
    {
    struct buffer_head *bh = NULL;
    struct ext4_xattr_ibody_header *header;
    struct ext4_inode *raw_inode;
    struct ext4_iloc iloc;
    struct ext4_xattr_entry *entry;
    + struct inode *ea_inode;
    unsigned int ea_ino;
    int credits = 3, error = 0;

    @@ -2057,8 +2055,12 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
    if (!entry->e_value_inum)
    continue;
    ea_ino = le32_to_cpu(entry->e_value_inum);
    - error = ext4_expand_ino_array(lea_ino_array, ea_ino);
    + error = ext4_xattr_inode_iget(inode, ea_ino, &ea_inode);
    + if (error)
    + continue;
    + error = ext4_expand_inode_array(ea_inode_array, ea_inode);
    if (error) {
    + iput(ea_inode);
    brelse(iloc.bh);
    goto cleanup;
    }
    @@ -2070,7 +2072,7 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
    if (!EXT4_I(inode)->i_file_acl) {
    /* add xattr inode to orphan list */
    error = ext4_xattr_inode_orphan_add(handle, inode, credits,
    - *lea_ino_array);
    + *ea_inode_array);
    goto cleanup;
    }
    bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
    @@ -2093,7 +2095,10 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
    if (!entry->e_value_inum)
    continue;
    ea_ino = le32_to_cpu(entry->e_value_inum);
    - error = ext4_expand_ino_array(lea_ino_array, ea_ino);
    + error = ext4_xattr_inode_iget(inode, ea_ino, &ea_inode);
    + if (error)
    + continue;
    + error = ext4_expand_inode_array(ea_inode_array, ea_inode);
    if (error)
    goto cleanup;
    entry->e_value_inum = 0;
    @@ -2101,7 +2106,7 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,

    /* add xattr inode to orphan list */
    error = ext4_xattr_inode_orphan_add(handle, inode, credits,
    - *lea_ino_array);
    + *ea_inode_array);
    if (error)
    goto cleanup;

    @@ -2128,28 +2133,20 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
    return error;
    }

    -void
    -ext4_xattr_inode_array_free(struct inode *inode,
    - struct ext4_xattr_ino_array *lea_ino_array)
    +void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *ea_inode_array)
    {
    struct inode *ea_inode;
    int idx = 0;
    - int err;

    - if (lea_ino_array == NULL)
    + if (ea_inode_array == NULL)
    return;

    - for (; idx < lea_ino_array->xia_count; ++idx) {
    - err = ext4_xattr_inode_iget(inode,
    - lea_ino_array->xia_inodes[idx], &ea_inode);
    - if (err)
    - continue;
    - /* for inode's i_count get from ext4_xattr_delete_inode */
    - iput(ea_inode);
    + for (; idx < ea_inode_array->count; ++idx) {
    + ea_inode = ea_inode_array->inodes[idx];
    clear_nlink(ea_inode);
    iput(ea_inode);
    }
    - kfree(lea_ino_array);
    + kfree(ea_inode_array);
    }

    /*
    diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
    index e82c5fe36a26..323eba54f72f 100644
    --- a/fs/ext4/xattr.h
    +++ b/fs/ext4/xattr.h
    @@ -164,9 +164,8 @@ extern int ext4_xattr_set_credits(struct inode *inode, size_t value_len);

    extern int ext4_xattr_inode_unlink(struct inode *inode, unsigned long ea_ino);
    extern int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
    - struct ext4_xattr_ino_array **array);
    -extern void ext4_xattr_inode_array_free(struct inode *inode,
    - struct ext4_xattr_ino_array *array);
    + struct ext4_xattr_inode_array **array);
    +extern void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *array);

    extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
    struct ext4_inode *raw_inode, handle_t *handle);
    --
    2.13.1.611.g7e3b11ae1-goog
    \
     
     \ /
      Last update: 2017-06-22 19:58    [W:4.125 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site