Skip to content

Commit 6194ae4

Browse files
Larry Chentorvalds
authored andcommitted
ocfs2: fix clusters leak in ocfs2_defrag_extent()
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]>
1 parent 3a3d1e5 commit 6194ae4

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

fs/ocfs2/move_extents.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "ocfs2_ioctl.h"
2626

2727
#include "alloc.h"
28+
#include "localalloc.h"
2829
#include "aops.h"
2930
#include "dlmglue.h"
3031
#include "extent_map.h"
@@ -233,6 +234,7 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
233234
struct ocfs2_refcount_tree *ref_tree = NULL;
234235
u32 new_phys_cpos, new_len;
235236
u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
237+
int need_free = 0;
236238

237239
if ((ext_flags & OCFS2_EXT_REFCOUNTED) && *len) {
238240
BUG_ON(!ocfs2_is_refcount_inode(inode));
@@ -308,6 +310,7 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
308310
if (!partial) {
309311
context->range->me_flags &= ~OCFS2_MOVE_EXT_FL_COMPLETE;
310312
ret = -ENOSPC;
313+
need_free = 1;
311314
goto out_commit;
312315
}
313316
}
@@ -332,6 +335,20 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
332335
mlog_errno(ret);
333336

334337
out_commit:
338+
if (need_free && context->data_ac) {
339+
struct ocfs2_alloc_context *data_ac = context->data_ac;
340+
341+
if (context->data_ac->ac_which == OCFS2_AC_USE_LOCAL)
342+
ocfs2_free_local_alloc_bits(osb, handle, data_ac,
343+
new_phys_cpos, new_len);
344+
else
345+
ocfs2_free_clusters(handle,
346+
data_ac->ac_inode,
347+
data_ac->ac_bh,
348+
ocfs2_clusters_to_blocks(osb->sb, new_phys_cpos),
349+
new_len);
350+
}
351+
335352
ocfs2_commit_trans(osb, handle);
336353

337354
out_unlock_mutex:

0 commit comments

Comments
 (0)