Ocfs2: Handle deletion of reflinked oprhan inodes correctly.
authorTristan Ye <tristan.ye@oracle.com>
Fri, 19 Mar 2010 01:21:10 +0000 (09:21 +0800)
committerJoel Becker <joel.becker@oracle.com>
Wed, 24 Mar 2010 01:22:55 +0000 (18:22 -0700)
commitb54c2ca475fa7d7450a45b6d778dae9dbe0bcbfe
treea67f530a3f426d756a0383f8dc11b5928810d0f5
parent3939fda4b389993caf8741df5739b3e49f33a263
Ocfs2: Handle deletion of reflinked oprhan inodes correctly.

The rule is that all inodes in the orphan dir have ORPHANED_FL,
otherwise we treated it as an ERROR.  This rule works well except
for some rare cases of reflink operation:

http://oss.oracle.com/bugzilla/show_bug.cgi?id=1215

The problem is caused by how reflink and our orphan_scan thread
interact.

 * The orphan scan pulls the orphans into a queue first, then runs the
   queue at a later time.  We only hold the orphan_dir's lock
   during scanning.

 * Reflink create a oprhaned target in orphan_dir as its first step.
   It removes the target and clears the flag as the final step.
   These two steps take the orphan_dir's lock, but it is not held for
   the duration.

Based on the above semantics, a reflink inode can be moved out of the
orphan dir and have its ORPHANED_FL cleared before the queue of orphans
is run.  This leads to a ERROR in ocfs2_query_wipde_inode().

This patch teaches ocfs2_query_wipe_inode() to detect previously
orphaned reflink targets.  If a reflink fails or a crash occurs during
the relfink operation, the inode will retain ORPHANED_FL and will be
properly wiped.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
fs/ocfs2/inode.c