lkml.org 
[lkml]   [2005]   [Jan]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RESEND][PATCH 5/9] Ext3: extended attribute sharing fixes and in-inode EAs
    Ext3: factor our common xattr code; unnecessary lock

    The ext3_xattr_set_handle2 and ext3_xattr_delete_inode functions contain
    duplicate code to decrease the reference count of an xattr block. Move
    this to a separate function.

    Also we know we have exclusive access to the inode in
    ext3_xattr_delete_inode; there is no need to grab the xattr_sem lock.

    Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

    Index: linux-2.6.10/fs/ext3/xattr.c
    ===================================================================
    --- linux-2.6.10.orig/fs/ext3/xattr.c
    +++ linux-2.6.10/fs/ext3/xattr.c
    @@ -356,6 +356,41 @@ static void ext3_xattr_update_super_bloc
    }

    /*
    + * Release the xattr block BH: If the reference count is > 1, decrement
    + * it; otherwise free the block.
    + */
    +static void
    +ext3_xattr_release_block(handle_t *handle, struct inode *inode,
    + struct buffer_head *bh)
    +{
    + struct mb_cache_entry *ce = NULL;
    +
    + ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr);
    + if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
    + ea_bdebug(bh, "freeing");
    + if (ce)
    + mb_cache_entry_free(ce);
    + ext3_free_blocks(handle, inode, bh->b_blocknr, 1);
    + get_bh(bh);
    + ext3_forget(handle, 1, inode, bh, bh->b_blocknr);
    + } else {
    + if (ext3_journal_get_write_access(handle, bh) == 0) {
    + lock_buffer(bh);
    + HDR(bh)->h_refcount = cpu_to_le32(
    + le32_to_cpu(HDR(bh)->h_refcount) - 1);
    + ext3_journal_dirty_metadata(handle, bh);
    + if (IS_SYNC(inode))
    + handle->h_sync = 1;
    + DQUOT_FREE_BLOCK(inode, 1);
    + unlock_buffer(bh);
    + ea_bdebug(bh, "refcount now=%d",
    + le32_to_cpu(HDR(bh)->h_refcount) - 1);
    + }
    + if (ce)
    + mb_cache_entry_release(ce);
    + }
    +}
    +/*
    * ext3_xattr_set_handle()
    *
    * Create, replace or remove an extended attribute for this inode. Buffer
    @@ -733,37 +768,8 @@ getblk_failed:
    /*
    * If there was an old block, and we are no longer using it,
    * release the old block.
    - */
    - ce = mb_cache_entry_get(ext3_xattr_cache, old_bh->b_bdev,
    - old_bh->b_blocknr);
    - if (HDR(old_bh)->h_refcount == cpu_to_le32(1)) {
    - /* Free the old block. */
    - ea_bdebug(old_bh, "freeing");
    - ext3_free_blocks(handle, inode, old_bh->b_blocknr, 1);
    -
    - /* ext3_forget() calls bforget() for us, but we
    - let our caller release old_bh, so we need to
    - duplicate the handle before. */
    - get_bh(old_bh);
    - ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr);
    - if (ce) {
    - mb_cache_entry_free(ce);
    - ce = NULL;
    - }
    - } else {
    - error = ext3_journal_get_write_access(handle, old_bh);
    - if (error)
    - goto cleanup;
    - /* Decrement the refcount only. */
    - lock_buffer(old_bh);
    - HDR(old_bh)->h_refcount = cpu_to_le32(
    - le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
    - DQUOT_FREE_BLOCK(inode, 1);
    - ext3_journal_dirty_metadata(handle, old_bh);
    - ea_bdebug(old_bh, "refcount now=%d",
    - le32_to_cpu(HDR(old_bh)->h_refcount));
    - unlock_buffer(old_bh);
    - }
    + */
    + ext3_xattr_release_block(handle, inode, old_bh);
    }

    cleanup:
    @@ -813,13 +819,13 @@ retry:
    * ext3_xattr_delete_inode()
    *
    * Free extended attribute resources associated with this inode. This
    - * is called immediately before an inode is freed.
    + * is called immediately before an inode is freed. We have exclusive
    + * access to the inode.
    */
    void
    ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
    {
    struct buffer_head *bh = NULL;
    - struct mb_cache_entry *ce = NULL;

    down_write(&EXT3_I(inode)->xattr_sem);
    if (!EXT3_I(inode)->i_file_acl)
    @@ -838,33 +844,10 @@ ext3_xattr_delete_inode(handle_t *handle
    EXT3_I(inode)->i_file_acl);
    goto cleanup;
    }
    - ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_bdev, bh->b_blocknr);
    - if (HDR(bh)->h_refcount == cpu_to_le32(1)) {
    - if (ce) {
    - mb_cache_entry_free(ce);
    - ce = NULL;
    - }
    - ext3_free_blocks(handle, inode, EXT3_I(inode)->i_file_acl, 1);
    - get_bh(bh);
    - ext3_forget(handle, 1, inode, bh, EXT3_I(inode)->i_file_acl);
    - } else {
    - if (ext3_journal_get_write_access(handle, bh) != 0)
    - goto cleanup;
    - lock_buffer(bh);
    - HDR(bh)->h_refcount = cpu_to_le32(
    - le32_to_cpu(HDR(bh)->h_refcount) - 1);
    - ext3_journal_dirty_metadata(handle, bh);
    - if (IS_SYNC(inode))
    - handle->h_sync = 1;
    - DQUOT_FREE_BLOCK(inode, 1);
    - unlock_buffer(bh);
    - }
    - ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);
    + ext3_xattr_release_block(handle, inode, bh);
    EXT3_I(inode)->i_file_acl = 0;

    cleanup:
    - if (ce)
    - mb_cache_entry_release(ce);
    brelse(bh);
    up_write(&EXT3_I(inode)->xattr_sem);
    }
    --
    Andreas Gruenbacher <agruen@suse.de>
    SUSE Labs, SUSE LINUX PRODUCTS GMBH
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:09    [W:0.038 / U:0.348 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site