[Ocfs2-devel] [PATCH V3] ocfs2: need rollback when journal_access failed in ocfs2_orphan_add()
Jeff Liu
jeff.liu at oracle.com
Tue Jul 2 21:48:05 PDT 2013
On 07/03/2013 05:26 AM, Andrew Morton wrote:
> On Fri, 28 Jun 2013 14:50:59 +0800 Younger Liu <younger.liu at huawei.com> wrote:
>
>> While adding a file into orphan dir in ocfs2_orphan_add(),
>> it calls __ocfs2_add_entry() before ocfs2_journal_access_di().
>> If ocfs2_journal_access_di() failed, the file is added into
>> orphan dir, and orphan dir dinode updated, but file dinode
>> has not been updated.
>> Accordingly, the data is not consistent between file dinode
>> and orphan dir.
>>
>> So, need to call ocfs2_journal_access_di() before __ocfs2_add_entry(),
>> and if ocfs2_journal_access_di() failed, orphan_fe and
>> orphan_dir_inode->i_nlink need rollback.
>>
>> This bug is introduced by commits 3939fda4.
>>
>> Compared with the PATCH V2, this patch cleans up mlog_errno(status)
>> which was called two times for the same error.
>>
>
> Folks, could we please get this one reviewed?
At least, this fix looks good to me.
Thanks,
-Jeff
>
> From: Younger Liu <younger.liu at huawei.com>
> Subject: ocfs2: need rollback when journal_access failed in ocfs2_orphan_add()
>
> While adding a file into orphan dir in ocfs2_orphan_add(), it calls
> __ocfs2_add_entry() before ocfs2_journal_access_di(). If
> ocfs2_journal_access_di() failed, the file is added into orphan dir, and
> orphan dir dinode updated, but file dinode has not been updated.
> Accordingly, the data is not consistent between file dinode and orphan
> dir.
>
> So, need to call ocfs2_journal_access_di() before __ocfs2_add_entry(), and
> if ocfs2_journal_access_di() failed, orphan_fe and
> orphan_dir_inode->i_nlink need rollback.
>
> This bug was added by 3939fda4 ("Ocfs2: Journaling i_flags and
> i_orphaned_slot when adding inode to orphan dir.").
>
> Signed-off-by: Younger Liu <younger.liu at huawei.com>
> Cc: Jie Liu <jeff.liu at oracle.com>
> Cc: Sunil Mushran <sunil.mushran at gmail.com>
> Cc: Mark Fasheh <mfasheh at suse.com>
> Cc: Joel Becker <jlbec at evilplan.org>
> Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
> ---
>
> fs/ocfs2/namei.c | 41 +++++++++++++++++++++++------------------
> 1 file changed, 23 insertions(+), 18 deletions(-)
>
> diff -puN fs/ocfs2/namei.c~ocfs2-need-rollback-when-journal_access-failed-in-ocfs2_orphan_add fs/ocfs2/namei.c
> --- a/fs/ocfs2/namei.c~ocfs2-need-rollback-when-journal_access-failed-in-ocfs2_orphan_add
> +++ a/fs/ocfs2/namei.c
> @@ -2012,6 +2012,21 @@ static int ocfs2_orphan_add(struct ocfs2
> goto leave;
> }
>
> + /*
> + * We're going to journal the change of i_flags and i_orphaned_slot.
> + * It's safe anyway, though some callers may duplicate the journaling.
> + * Journaling within the func just make the logic look more
> + * straightforward.
> + */
> + status = ocfs2_journal_access_di(handle,
> + INODE_CACHE(inode),
> + fe_bh,
> + OCFS2_JOURNAL_ACCESS_WRITE);
> + if (status < 0) {
> + mlog_errno(status);
> + goto leave;
> + }
> +
> /* we're a cluster, and nlink can change on disk from
> * underneath us... */
> orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
> @@ -2026,22 +2041,7 @@ static int ocfs2_orphan_add(struct ocfs2
> orphan_dir_bh, lookup);
> if (status < 0) {
> mlog_errno(status);
> - goto leave;
> - }
> -
> - /*
> - * We're going to journal the change of i_flags and i_orphaned_slot.
> - * It's safe anyway, though some callers may duplicate the journaling.
> - * Journaling within the func just make the logic look more
> - * straightforward.
> - */
> - status = ocfs2_journal_access_di(handle,
> - INODE_CACHE(inode),
> - fe_bh,
> - OCFS2_JOURNAL_ACCESS_WRITE);
> - if (status < 0) {
> - mlog_errno(status);
> - goto leave;
> + goto rollback;
> }
>
> fe->i_flags |= cpu_to_le32(OCFS2_ORPHANED_FL);
> @@ -2057,11 +2057,16 @@ static int ocfs2_orphan_add(struct ocfs2
> trace_ocfs2_orphan_add_end((unsigned long long)OCFS2_I(inode)->ip_blkno,
> osb->slot_num);
>
> +rollback:
> + if (status < 0) {
> + if (S_ISDIR(inode->i_mode))
> + ocfs2_add_links_count(orphan_fe, -1);
> + set_nlink(orphan_dir_inode, ocfs2_read_links_count(orphan_fe));
> + }
> +
> leave:
> brelse(orphan_dir_bh);
>
> - if (status)
> - mlog_errno(status);
> return status;
> }
>
> _
>
More information about the Ocfs2-devel
mailing list