aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2011-10-24 08:47:58 -0400
committerDavid Sterba <dsterba@suse.cz>2011-10-24 08:47:58 -0400
commita81d3b1ba2f5faae28ba7a092c7598673fa02ac2 (patch)
tree8301fefcd9f3d45be9d0030456a86bca5b9ff061 /fs/btrfs/ioctl.c
parentafd582ac8f10382002a72b4d17d9c2db328ed8b8 (diff)
parentf9d9ef62cd3ecbd6cbb7957a253c1e81f69d5586 (diff)
Merge branch 'hotfixes-20111024/josef/for-chris' into btrfs-next-stable
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 877727b28d88..33aae13cc74b 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -282,6 +282,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
282 struct fstrim_range range; 282 struct fstrim_range range;
283 u64 minlen = ULLONG_MAX; 283 u64 minlen = ULLONG_MAX;
284 u64 num_devices = 0; 284 u64 num_devices = 0;
285 u64 total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
285 int ret; 286 int ret;
286 287
287 if (!capable(CAP_SYS_ADMIN)) 288 if (!capable(CAP_SYS_ADMIN))
@@ -300,12 +301,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
300 } 301 }
301 } 302 }
302 rcu_read_unlock(); 303 rcu_read_unlock();
304
303 if (!num_devices) 305 if (!num_devices)
304 return -EOPNOTSUPP; 306 return -EOPNOTSUPP;
305
306 if (copy_from_user(&range, arg, sizeof(range))) 307 if (copy_from_user(&range, arg, sizeof(range)))
307 return -EFAULT; 308 return -EFAULT;
309 if (range.start > total_bytes)
310 return -EINVAL;
308 311
312 range.len = min(range.len, total_bytes - range.start);
309 range.minlen = max(range.minlen, minlen); 313 range.minlen = max(range.minlen, minlen);
310 ret = btrfs_trim_fs(root, &range); 314 ret = btrfs_trim_fs(root, &range);
311 if (ret < 0) 315 if (ret < 0)
@@ -765,7 +769,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
765 int ret = 1; 769 int ret = 1;
766 770
767 /* 771 /*
768 * make sure that once we start defragging and extent, we keep on 772 * make sure that once we start defragging an extent, we keep on
769 * defragging it 773 * defragging it
770 */ 774 */
771 if (start < *defrag_end) 775 if (start < *defrag_end)
@@ -810,7 +814,6 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
810 * extent will force at least part of that big extent to be defragged. 814 * extent will force at least part of that big extent to be defragged.
811 */ 815 */
812 if (ret) { 816 if (ret) {
813 *last_len += len;
814 *defrag_end = extent_map_end(em); 817 *defrag_end = extent_map_end(em);
815 } else { 818 } else {
816 *last_len = 0; 819 *last_len = 0;
@@ -978,18 +981,20 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
978 struct btrfs_super_block *disk_super; 981 struct btrfs_super_block *disk_super;
979 struct file_ra_state *ra = NULL; 982 struct file_ra_state *ra = NULL;
980 unsigned long last_index; 983 unsigned long last_index;
984 u64 isize = i_size_read(inode);
981 u64 features; 985 u64 features;
982 u64 last_len = 0; 986 u64 last_len = 0;
983 u64 skip = 0; 987 u64 skip = 0;
984 u64 defrag_end = 0; 988 u64 defrag_end = 0;
985 u64 newer_off = range->start; 989 u64 newer_off = range->start;
986 int newer_left = 0;
987 unsigned long i; 990 unsigned long i;
991 unsigned long ra_index = 0;
988 int ret; 992 int ret;
989 int defrag_count = 0; 993 int defrag_count = 0;
990 int compress_type = BTRFS_COMPRESS_ZLIB; 994 int compress_type = BTRFS_COMPRESS_ZLIB;
991 int extent_thresh = range->extent_thresh; 995 int extent_thresh = range->extent_thresh;
992 int newer_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT; 996 int max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
997 int cluster = max_cluster;
993 u64 new_align = ~((u64)128 * 1024 - 1); 998 u64 new_align = ~((u64)128 * 1024 - 1);
994 struct page **pages = NULL; 999 struct page **pages = NULL;
995 1000
@@ -1003,7 +1008,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1003 compress_type = range->compress_type; 1008 compress_type = range->compress_type;
1004 } 1009 }
1005 1010
1006 if (inode->i_size == 0) 1011 if (isize == 0)
1007 return 0; 1012 return 0;
1008 1013
1009 /* 1014 /*
@@ -1019,7 +1024,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1019 ra = &file->f_ra; 1024 ra = &file->f_ra;
1020 } 1025 }
1021 1026
1022 pages = kmalloc(sizeof(struct page *) * newer_cluster, 1027 pages = kmalloc(sizeof(struct page *) * max_cluster,
1023 GFP_NOFS); 1028 GFP_NOFS);
1024 if (!pages) { 1029 if (!pages) {
1025 ret = -ENOMEM; 1030 ret = -ENOMEM;
@@ -1028,10 +1033,10 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1028 1033
1029 /* find the last page to defrag */ 1034 /* find the last page to defrag */
1030 if (range->start + range->len > range->start) { 1035 if (range->start + range->len > range->start) {
1031 last_index = min_t(u64, inode->i_size - 1, 1036 last_index = min_t(u64, isize - 1,
1032 range->start + range->len - 1) >> PAGE_CACHE_SHIFT; 1037 range->start + range->len - 1) >> PAGE_CACHE_SHIFT;
1033 } else { 1038 } else {
1034 last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT; 1039 last_index = (isize - 1) >> PAGE_CACHE_SHIFT;
1035 } 1040 }
1036 1041
1037 if (newer_than) { 1042 if (newer_than) {
@@ -1044,14 +1049,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1044 * the extents in the file evenly spaced 1049 * the extents in the file evenly spaced
1045 */ 1050 */
1046 i = (newer_off & new_align) >> PAGE_CACHE_SHIFT; 1051 i = (newer_off & new_align) >> PAGE_CACHE_SHIFT;
1047 newer_left = newer_cluster;
1048 } else 1052 } else
1049 goto out_ra; 1053 goto out_ra;
1050 } else { 1054 } else {
1051 i = range->start >> PAGE_CACHE_SHIFT; 1055 i = range->start >> PAGE_CACHE_SHIFT;
1052 } 1056 }
1053 if (!max_to_defrag) 1057 if (!max_to_defrag)
1054 max_to_defrag = last_index - 1; 1058 max_to_defrag = last_index;
1055 1059
1056 /* 1060 /*
1057 * make writeback starts from i, so the defrag range can be 1061 * make writeback starts from i, so the defrag range can be
@@ -1085,18 +1089,31 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1085 i = max(i + 1, next); 1089 i = max(i + 1, next);
1086 continue; 1090 continue;
1087 } 1091 }
1092
1093 if (!newer_than) {
1094 cluster = (PAGE_CACHE_ALIGN(defrag_end) >>
1095 PAGE_CACHE_SHIFT) - i;
1096 cluster = min(cluster, max_cluster);
1097 } else {
1098 cluster = max_cluster;
1099 }
1100
1088 if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) 1101 if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
1089 BTRFS_I(inode)->force_compress = compress_type; 1102 BTRFS_I(inode)->force_compress = compress_type;
1090 1103
1091 btrfs_force_ra(inode->i_mapping, ra, file, i, newer_cluster); 1104 if (i + cluster > ra_index) {
1105 ra_index = max(i, ra_index);
1106 btrfs_force_ra(inode->i_mapping, ra, file, ra_index,
1107 cluster);
1108 ra_index += max_cluster;
1109 }
1092 1110
1093 ret = cluster_pages_for_defrag(inode, pages, i, newer_cluster); 1111 ret = cluster_pages_for_defrag(inode, pages, i, cluster);
1094 if (ret < 0) 1112 if (ret < 0)
1095 goto out_ra; 1113 goto out_ra;
1096 1114
1097 defrag_count += ret; 1115 defrag_count += ret;
1098 balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret); 1116 balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret);
1099 i += ret;
1100 1117
1101 if (newer_than) { 1118 if (newer_than) {
1102 if (newer_off == (u64)-1) 1119 if (newer_off == (u64)-1)
@@ -1111,12 +1128,17 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1111 if (!ret) { 1128 if (!ret) {
1112 range->start = newer_off; 1129 range->start = newer_off;
1113 i = (newer_off & new_align) >> PAGE_CACHE_SHIFT; 1130 i = (newer_off & new_align) >> PAGE_CACHE_SHIFT;
1114 newer_left = newer_cluster;
1115 } else { 1131 } else {
1116 break; 1132 break;
1117 } 1133 }
1118 } else { 1134 } else {
1119 i++; 1135 if (ret > 0) {
1136 i += ret;
1137 last_len += ret << PAGE_CACHE_SHIFT;
1138 } else {
1139 i++;
1140 last_len = 0;
1141 }
1120 } 1142 }
1121 } 1143 }
1122 1144
@@ -1149,9 +1171,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1149 btrfs_set_super_incompat_flags(disk_super, features); 1171 btrfs_set_super_incompat_flags(disk_super, features);
1150 } 1172 }
1151 1173
1152 if (!file) 1174 ret = defrag_count;
1153 kfree(ra);
1154 return defrag_count;
1155 1175
1156out_ra: 1176out_ra:
1157 if (!file) 1177 if (!file)