]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ocfs2: clear links count in ocfs2_mknod() if an error occurs
authorWangyan <wangyan122@huawei.com>
Thu, 31 Dec 2020 22:03:54 +0000 (22:03 +0000)
committerJohannes Weiner <hannes@cmpxchg.org>
Thu, 31 Dec 2020 22:03:54 +0000 (22:03 +0000)
In this condition, the inode can not be wiped when error happened.
ocfs2_mkdir()
  ->ocfs2_mknod()
    ->ocfs2_mknod_locked()
      ->__ocfs2_mknod_locked()
        ->ocfs2_set_links_count() // i_links_count is 2
    -> ... // an error accrue, goto roll_back or leave.
    ->ocfs2_commit_trans()
    ->iput(inode)
      ->evict()
        ->ocfs2_evict_inode()
          ->ocfs2_delete_inode()
            ->ocfs2_inode_lock()
              ->ocfs2_inode_lock_update()
                ->ocfs2_refresh_inode()
                  ->set_nlink();    // inode->i_nlink is 2 now.
            /* if wipe is 0, it will goto bail_unlock_inode */
            ->ocfs2_query_inode_wipe()
              ->if (inode->i_nlink) return; // wipe is 0.
            /* inode can not be wiped */
            ->ocfs2_wipe_inode()
So, we need clear links before the transaction committed.

Link: http://lkml.kernel.org/r/d8147c41-fb2b-bdf7-b660-1f3c8448c33f@huawei.com
Signed-off-by: Yan Wang <wangyan122@huawei.com>
Reviewed-by: Jun Piao <piaojun@huawei.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <jiangqi903@gmail.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
fs/ocfs2/namei.c

index 2a237ab00453c4648f467048ee133d97ebb68f62..9feaea57b6b74f21898193123d0902474e564620 100644 (file)
@@ -453,8 +453,12 @@ roll_back:
 leave:
        if (status < 0 && did_quota_inode)
                dquot_free_inode(inode);
-       if (handle)
+       if (handle) {
+               if (status < 0 && new_fe_bh != NULL)
+                       ocfs2_set_links_count((struct ocfs2_dinode *)
+                                       new_fe_bh->b_data, 0);
                ocfs2_commit_trans(osb, handle);
+       }
 
        ocfs2_inode_unlock(dir, 1);
        if (did_block_signals)
@@ -598,6 +602,8 @@ static int __ocfs2_mknod_locked(struct inode *dir,
 leave:
        if (status < 0) {
                if (*new_fe_bh) {
+                       if (fe)
+                               ocfs2_set_links_count(fe, 0);
                        brelse(*new_fe_bh);
                        *new_fe_bh = NULL;
                }
@@ -2023,8 +2029,12 @@ bail:
                                        ocfs2_clusters_to_bytes(osb->sb, 1));
        if (status < 0 && did_quota_inode)
                dquot_free_inode(inode);
-       if (handle)
+       if (handle) {
+               if (status < 0 && new_fe_bh != NULL)
+                       ocfs2_set_links_count((struct ocfs2_dinode *)
+                                       new_fe_bh->b_data, 0);
                ocfs2_commit_trans(osb, handle);
+       }
 
        ocfs2_inode_unlock(dir, 1);
        if (did_block_signals)