|
@@ -558,6 +558,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
|
|
|
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
|
|
|
if (IS_ERR(handle)) {
|
|
|
status = PTR_ERR(handle);
|
|
|
+ handle = NULL;
|
|
|
mlog_errno(status);
|
|
|
goto out;
|
|
|
}
|
|
@@ -639,11 +640,13 @@ static int ocfs2_remove_inode(struct inode *inode,
|
|
|
goto bail_unlock;
|
|
|
}
|
|
|
|
|
|
- status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
|
|
|
- orphan_dir_bh);
|
|
|
- if (status < 0) {
|
|
|
- mlog_errno(status);
|
|
|
- goto bail_commit;
|
|
|
+ if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
|
|
|
+ status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
|
|
|
+ orphan_dir_bh);
|
|
|
+ if (status < 0) {
|
|
|
+ mlog_errno(status);
|
|
|
+ goto bail_commit;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* set the inodes dtime */
|
|
@@ -722,38 +725,39 @@ static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb,
|
|
|
static int ocfs2_wipe_inode(struct inode *inode,
|
|
|
struct buffer_head *di_bh)
|
|
|
{
|
|
|
- int status, orphaned_slot;
|
|
|
+ int status, orphaned_slot = -1;
|
|
|
struct inode *orphan_dir_inode = NULL;
|
|
|
struct buffer_head *orphan_dir_bh = NULL;
|
|
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
|
|
- struct ocfs2_dinode *di;
|
|
|
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
|
|
|
|
|
|
- di = (struct ocfs2_dinode *) di_bh->b_data;
|
|
|
- orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
|
|
|
+ if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
|
|
|
+ orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
|
|
|
|
|
|
- status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
|
|
|
- if (status)
|
|
|
- return status;
|
|
|
+ status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
|
|
|
+ if (status)
|
|
|
+ return status;
|
|
|
|
|
|
- orphan_dir_inode = ocfs2_get_system_file_inode(osb,
|
|
|
- ORPHAN_DIR_SYSTEM_INODE,
|
|
|
- orphaned_slot);
|
|
|
- if (!orphan_dir_inode) {
|
|
|
- status = -EEXIST;
|
|
|
- mlog_errno(status);
|
|
|
- goto bail;
|
|
|
- }
|
|
|
+ orphan_dir_inode = ocfs2_get_system_file_inode(osb,
|
|
|
+ ORPHAN_DIR_SYSTEM_INODE,
|
|
|
+ orphaned_slot);
|
|
|
+ if (!orphan_dir_inode) {
|
|
|
+ status = -EEXIST;
|
|
|
+ mlog_errno(status);
|
|
|
+ goto bail;
|
|
|
+ }
|
|
|
|
|
|
- /* Lock the orphan dir. The lock will be held for the entire
|
|
|
- * delete_inode operation. We do this now to avoid races with
|
|
|
- * recovery completion on other nodes. */
|
|
|
- mutex_lock(&orphan_dir_inode->i_mutex);
|
|
|
- status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
|
|
|
- if (status < 0) {
|
|
|
- mutex_unlock(&orphan_dir_inode->i_mutex);
|
|
|
+ /* Lock the orphan dir. The lock will be held for the entire
|
|
|
+ * delete_inode operation. We do this now to avoid races with
|
|
|
+ * recovery completion on other nodes. */
|
|
|
+ mutex_lock(&orphan_dir_inode->i_mutex);
|
|
|
+ status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
|
|
|
+ if (status < 0) {
|
|
|
+ mutex_unlock(&orphan_dir_inode->i_mutex);
|
|
|
|
|
|
- mlog_errno(status);
|
|
|
- goto bail;
|
|
|
+ mlog_errno(status);
|
|
|
+ goto bail;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* we do this while holding the orphan dir lock because we
|
|
@@ -794,6 +798,9 @@ static int ocfs2_wipe_inode(struct inode *inode,
|
|
|
mlog_errno(status);
|
|
|
|
|
|
bail_unlock_dir:
|
|
|
+ if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)
|
|
|
+ return status;
|
|
|
+
|
|
|
ocfs2_inode_unlock(orphan_dir_inode, 1);
|
|
|
mutex_unlock(&orphan_dir_inode->i_mutex);
|
|
|
brelse(orphan_dir_bh);
|
|
@@ -889,7 +896,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
|
|
|
|
|
|
/* Do some basic inode verification... */
|
|
|
di = (struct ocfs2_dinode *) di_bh->b_data;
|
|
|
- if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
|
|
|
+ if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) &&
|
|
|
+ !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
|
|
|
/*
|
|
|
* Inodes in the orphan dir must have ORPHANED_FL. The only
|
|
|
* inodes that come back out of the orphan dir are reflink
|