lkml.org 
[lkml]   [2008]   [Dec]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 22/45] ocfs2: move new inode allocation out of the transaction
    Date
    From: Tiger Yang <tiger.yang@oracle.com>

    Move out inode allocation from ocfs2_mknod_locked() because
    vfs_dq_init() must be called outside of a transaction.

    Signed-off-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Tiger Yang <tiger.yang@oracle.com>
    Signed-off-by: Mark Fasheh <mfasheh@suse.com>
    ---
    fs/ocfs2/namei.c | 108 ++++++++++++++++++++++++++++++++----------------------
    1 files changed, 64 insertions(+), 44 deletions(-)

    diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
    index f4967e6..e9118fc 100644
    --- a/fs/ocfs2/namei.c
    +++ b/fs/ocfs2/namei.c
    @@ -66,12 +66,12 @@

    static int ocfs2_mknod_locked(struct ocfs2_super *osb,
    struct inode *dir,
    - struct dentry *dentry, int mode,
    + struct inode *inode,
    + struct dentry *dentry,
    dev_t dev,
    struct buffer_head **new_fe_bh,
    struct buffer_head *parent_fe_bh,
    handle_t *handle,
    - struct inode **ret_inode,
    struct ocfs2_alloc_context *inode_ac);

    static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
    @@ -186,6 +186,34 @@ bail:
    return ret;
    }

    +static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode)
    +{
    + struct inode *inode;
    +
    + inode = new_inode(dir->i_sb);
    + if (!inode) {
    + mlog(ML_ERROR, "new_inode failed!\n");
    + return NULL;
    + }
    +
    + /* populate as many fields early on as possible - many of
    + * these are used by the support functions here and in
    + * callers. */
    + if (S_ISDIR(mode))
    + inode->i_nlink = 2;
    + else
    + inode->i_nlink = 1;
    + inode->i_uid = current->fsuid;
    + if (dir->i_mode & S_ISGID) {
    + inode->i_gid = dir->i_gid;
    + if (S_ISDIR(mode))
    + mode |= S_ISGID;
    + } else
    + inode->i_gid = current->fsgid;
    + inode->i_mode = mode;
    + return inode;
    +}
    +
    static int ocfs2_mknod(struct inode *dir,
    struct dentry *dentry,
    int mode,
    @@ -250,6 +278,13 @@ static int ocfs2_mknod(struct inode *dir,
    goto leave;
    }

    + inode = ocfs2_get_init_inode(dir, mode);
    + if (!inode) {
    + status = -ENOMEM;
    + mlog_errno(status);
    + goto leave;
    + }
    +
    /* Reserve a cluster if creating an extent based directory. */
    if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
    status = ocfs2_reserve_clusters(osb, 1, &data_ac);
    @@ -269,9 +304,9 @@ static int ocfs2_mknod(struct inode *dir,
    }

    /* do the real work now. */
    - status = ocfs2_mknod_locked(osb, dir, dentry, mode, dev,
    + status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev,
    &new_fe_bh, parent_fe_bh, handle,
    - &inode, inode_ac);
    + inode_ac);
    if (status < 0) {
    mlog_errno(status);
    goto leave;
    @@ -332,8 +367,10 @@ leave:
    brelse(de_bh);
    brelse(parent_fe_bh);

    - if ((status < 0) && inode)
    + if ((status < 0) && inode) {
    + clear_nlink(inode);
    iput(inode);
    + }

    if (inode_ac)
    ocfs2_free_alloc_context(inode_ac);
    @@ -348,12 +385,12 @@ leave:

    static int ocfs2_mknod_locked(struct ocfs2_super *osb,
    struct inode *dir,
    - struct dentry *dentry, int mode,
    + struct inode *inode,
    + struct dentry *dentry,
    dev_t dev,
    struct buffer_head **new_fe_bh,
    struct buffer_head *parent_fe_bh,
    handle_t *handle,
    - struct inode **ret_inode,
    struct ocfs2_alloc_context *inode_ac)
    {
    int status = 0;
    @@ -361,14 +398,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
    struct ocfs2_extent_list *fel;
    u64 fe_blkno = 0;
    u16 suballoc_bit;
    - struct inode *inode = NULL;

    - mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
    - (unsigned long)dev, dentry->d_name.len,
    + mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
    + inode->i_mode, (unsigned long)dev, dentry->d_name.len,
    dentry->d_name.name);

    *new_fe_bh = NULL;
    - *ret_inode = NULL;

    status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit,
    &fe_blkno);
    @@ -377,23 +412,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
    goto leave;
    }

    - inode = new_inode(dir->i_sb);
    - if (!inode) {
    - status = -ENOMEM;
    - mlog(ML_ERROR, "new_inode failed!\n");
    - goto leave;
    - }
    -
    /* populate as many fields early on as possible - many of
    * these are used by the support functions here and in
    * callers. */
    inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
    OCFS2_I(inode)->ip_blkno = fe_blkno;
    - if (S_ISDIR(mode))
    - inode->i_nlink = 2;
    - else
    - inode->i_nlink = 1;
    - inode->i_mode = mode;
    spin_lock(&osb->osb_lock);
    inode->i_generation = osb->s_next_generation++;
    spin_unlock(&osb->osb_lock);
    @@ -421,17 +444,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
    fe->i_blkno = cpu_to_le64(fe_blkno);
    fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
    fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
    - fe->i_uid = cpu_to_le32(current->fsuid);
    - if (dir->i_mode & S_ISGID) {
    - fe->i_gid = cpu_to_le32(dir->i_gid);
    - if (S_ISDIR(mode))
    - mode |= S_ISGID;
    - } else
    - fe->i_gid = cpu_to_le32(current->fsgid);
    - fe->i_mode = cpu_to_le16(mode);
    - if (S_ISCHR(mode) || S_ISBLK(mode))
    + fe->i_uid = cpu_to_le32(inode->i_uid);
    + fe->i_gid = cpu_to_le32(inode->i_gid);
    + fe->i_mode = cpu_to_le16(inode->i_mode);
    + if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
    fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
    -
    fe->i_links_count = cpu_to_le16(inode->i_nlink);

    fe->i_last_eb_blk = 0;
    @@ -446,7 +463,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
    /*
    * If supported, directories start with inline data.
    */
    - if (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) {
    + if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
    u16 feat = le16_to_cpu(fe->i_dyn_features);

    fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
    @@ -484,17 +501,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
    status = 0; /* error in ocfs2_create_new_inode_locks is not
    * critical */

    - *ret_inode = inode;
    leave:
    if (status < 0) {
    if (*new_fe_bh) {
    brelse(*new_fe_bh);
    *new_fe_bh = NULL;
    }
    - if (inode) {
    - clear_nlink(inode);
    - iput(inode);
    - }
    }

    mlog_exit(status);
    @@ -1542,6 +1554,13 @@ static int ocfs2_symlink(struct inode *dir,
    goto bail;
    }

    + inode = ocfs2_get_init_inode(dir, S_IFLNK | S_IRWXUGO);
    + if (!inode) {
    + status = -ENOMEM;
    + mlog_errno(status);
    + goto bail;
    + }
    +
    /* don't reserve bitmap space for fast symlinks. */
    if (l > ocfs2_fast_symlink_chars(sb)) {
    status = ocfs2_reserve_clusters(osb, 1, &data_ac);
    @@ -1560,10 +1579,9 @@ static int ocfs2_symlink(struct inode *dir,
    goto bail;
    }

    - status = ocfs2_mknod_locked(osb, dir, dentry,
    - S_IFLNK | S_IRWXUGO, 0,
    - &new_fe_bh, parent_fe_bh, handle,
    - &inode, inode_ac);
    + status = ocfs2_mknod_locked(osb, dir, inode, dentry,
    + 0, &new_fe_bh, parent_fe_bh, handle,
    + inode_ac);
    if (status < 0) {
    mlog_errno(status);
    goto bail;
    @@ -1644,8 +1662,10 @@ bail:
    ocfs2_free_alloc_context(inode_ac);
    if (data_ac)
    ocfs2_free_alloc_context(data_ac);
    - if ((status < 0) && inode)
    + if ((status < 0) && inode) {
    + clear_nlink(inode);
    iput(inode);
    + }

    mlog_exit(status);

    --
    1.5.6


    \
     
     \ /
      Last update: 2008-12-19 23:05    [W:0.036 / U:31.780 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site