Skip to content

Commit

Permalink
ocfs2: fix clusters leak in ocfs2_defrag_extent()
Browse files Browse the repository at this point in the history
ocfs2_defrag_extent() might leak allocated clusters.  When the file
system has insufficient space, the number of claimed clusters might be
less than the caller wants.  If that happens, the original code might
directly commit the transaction without returning clusters.

This patch is based on code in ocfs2_add_clusters_in_btree().

[[email protected]: include localalloc.h, reduce scope of data_ac]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Larry Chen <[email protected]>
Reviewed-by: Andrew Morton <[email protected]>
Cc: Mark Fasheh <[email protected]>
Cc: Joel Becker <[email protected]>
Cc: Junxiao Bi <[email protected]>
Cc: Joseph Qi <[email protected]>
Cc: Changwei Ge <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Larry Chen authored and torvalds committed Nov 3, 2018
1 parent 3a3d1e5 commit 6194ae4
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions fs/ocfs2/move_extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "ocfs2_ioctl.h"

#include "alloc.h"
#include "localalloc.h"
#include "aops.h"
#include "dlmglue.h"
#include "extent_map.h"
Expand Down Expand Up @@ -233,6 +234,7 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
struct ocfs2_refcount_tree *ref_tree = NULL;
u32 new_phys_cpos, new_len;
u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
int need_free = 0;

if ((ext_flags & OCFS2_EXT_REFCOUNTED) && *len) {
BUG_ON(!ocfs2_is_refcount_inode(inode));
Expand Down Expand Up @@ -308,6 +310,7 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
if (!partial) {
context->range->me_flags &= ~OCFS2_MOVE_EXT_FL_COMPLETE;
ret = -ENOSPC;
need_free = 1;
goto out_commit;
}
}
Expand All @@ -332,6 +335,20 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
mlog_errno(ret);

out_commit:
if (need_free && context->data_ac) {
struct ocfs2_alloc_context *data_ac = context->data_ac;

if (context->data_ac->ac_which == OCFS2_AC_USE_LOCAL)
ocfs2_free_local_alloc_bits(osb, handle, data_ac,
new_phys_cpos, new_len);
else
ocfs2_free_clusters(handle,
data_ac->ac_inode,
data_ac->ac_bh,
ocfs2_clusters_to_blocks(osb->sb, new_phys_cpos),
new_len);
}

ocfs2_commit_trans(osb, handle);

out_unlock_mutex:
Expand Down

0 comments on commit 6194ae4

Please sign in to comment.