Ocfs2/move_extents: Set several trivial constraints for threshold.
authorTristan Ye <tristan.ye@oracle.com>
Wed, 25 May 2011 06:45:41 +0000 (14:45 +0800)
committerTristan Ye <tristan.ye@oracle.com>
Wed, 25 May 2011 07:17:13 +0000 (15:17 +0800)
The threshold should be greater than clustersize and less than i_size.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
fs/ocfs2/move_extents.c

index efc509b3af1ff45cc8747a0bcd6e3078d91dcdf0..4c5488468c14823b4fee4bd036be0211a5b99c18 100644 (file)
@@ -220,6 +220,9 @@ out:
 /*
  * Using one journal handle to guarantee the data consistency in case
  * crash happens anywhere.
+ *
+ *  XXX: defrag can end up with finishing partial extent as requested,
+ * due to not enough contiguous clusters can be found in allocator.
  */
 static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
                               u32 cpos, u32 phys_cpos, u32 *len, int ext_flags)
@@ -876,9 +879,11 @@ static int __ocfs2_move_extents_range(struct buffer_head *di_bh,
        else
                len_to_move = 0;
 
-       if (do_defrag)
+       if (do_defrag) {
                defrag_thresh = range->me_threshold >> osb->s_clustersize_bits;
-       else
+               if (defrag_thresh <= 1)
+                       goto done;
+       } else
                new_phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb,
                                                         range->me_goal);
 
@@ -950,6 +955,7 @@ next:
                len_to_move -= alloc_size;
        }
 
+done:
        range->me_flags |= OCFS2_MOVE_EXT_FL_COMPLETE;
 
 out:
@@ -1098,13 +1104,17 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
 
        if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
                context->auto_defrag = 1;
+               /*
+                * ok, the default theshold for the defragmentation
+                * is 1M, since our maximum clustersize was 1M also.
+                * any thought?
+                */
                if (!range.me_threshold)
-                       /*
-                        * ok, the default theshold for the defragmentation
-                        * is 1M, since our maximum clustersize was 1M also.
-                        * any thought?
-                        */
                        range.me_threshold = 1024 * 1024;
+
+               if (range.me_threshold > i_size_read(inode))
+                       range.me_threshold = i_size_read(inode);
+
                if (range.me_flags & OCFS2_MOVE_EXT_FL_PART_DEFRAG)
                        context->partial = 1;
        } else {