Add missing patches (centralize-proc-functions and make-proc-generic)
[ext4-patch-queue.git] / ext4-online-defrag-for-relevant-files.patch
blobe0fdf2608f413098a927aa2d81820d66852bb8db
1 ext4: online defrag-- Defragmentation for the relevant files (-r mode)
3 From: Akira Fujita <a-fujita@rs.jp.nec.com>
5 Relevant file fragmentation could be solved by moving
6 the files under the specified directory close together with
7 the block containing the directory data.
9 Signed-off-by: Akira Fujita <a-fujita@rs.jp.nec.com>
10 Signed-off-by: Takashi Sato <t-sato@yk.jp.nec.com>
11 ---
12 fs/ext4/defrag.c | 48 +++++++++++++++++++++++++++++++++++-------------
13 fs/ext4/ext4.h | 4 +++-
14 fs/ext4/inode.c | 2 +-
15 fs/ext4/ioctl.c | 1 +
16 4 files changed, 40 insertions(+), 15 deletions(-)
18 Index: linux-2.6.26-rc9/fs/ext4/defrag.c
19 ===================================================================
20 --- linux-2.6.26-rc9.orig/fs/ext4/defrag.c 2008-07-11 16:05:19.000000000 -0700
21 +++ linux-2.6.26-rc9/fs/ext4/defrag.c 2008-07-11 16:05:19.000000000 -0700
22 @@ -95,13 +95,26 @@ int ext4_defrag_ioctl(struct inode *inod
24 int err = 0;
26 - if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) {
27 + if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL ||
28 + cmd == EXT4_IOC_FIBMAP)) {
29 printk(KERN_ERR "ext4 defrag: ino[%lu] is not extents "
30 "based file\n", inode->i_ino);
31 return -EOPNOTSUPP;
34 - if (cmd == EXT4_IOC_DEFRAG) {
35 + if (cmd == EXT4_IOC_FIBMAP) {
36 + ext4_fsblk_t __user *p = (ext4_fsblk_t __user *)arg;
37 + ext4_fsblk_t block = 0;
38 + struct address_space *mapping = filp->f_mapping;
40 + if (copy_from_user(&block, (ext4_fsblk_t __user *)arg,
41 + sizeof(block)))
42 + return -EFAULT;
44 + block = ext4_bmap(mapping, block);
46 + return put_user(block, p);
47 + } else if (cmd == EXT4_IOC_DEFRAG) {
48 struct ext4_ext_defrag_data defrag;
49 struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
51 @@ -127,7 +140,7 @@ int ext4_defrag_ioctl(struct inode *inod
54 err = ext4_defrag(filp, defrag.start_offset,
55 - defrag.defrag_size);
56 + defrag.defrag_size, defrag.goal);
59 return err;
60 @@ -745,6 +758,7 @@ out:
61 * @dest_path: indicating the temporary inode's extent
62 * @req_blocks: contiguous blocks count we need
63 * @iblock: target file offset
64 + * @goal: goal offset
67 static void
68 @@ -752,7 +766,8 @@ ext4_defrag_fill_ar(struct inode *org_in
69 struct ext4_allocation_request *ar,
70 struct ext4_ext_path *org_path,
71 struct ext4_ext_path *dest_path,
72 - ext4_fsblk_t req_blocks, ext4_lblk_t iblock)
73 + ext4_fsblk_t req_blocks, ext4_lblk_t iblock,
74 + ext4_fsblk_t goal)
76 ar->inode = dest_inode;
77 ar->len = req_blocks;
78 @@ -764,7 +779,10 @@ ext4_defrag_fill_ar(struct inode *org_in
79 ar->lright = 0;
80 ar->pright = 0;
82 - ar->goal = ext4_ext_find_goal(dest_inode, dest_path, iblock);
83 + if (goal)
84 + ar->goal = goal;
85 + else
86 + ar->goal = ext4_ext_find_goal(dest_inode, dest_path, iblock);
89 /**
90 @@ -939,6 +957,7 @@ out:
91 * original extent tree
92 * @tar_end: the last block number of the allocated blocks
93 * @sum_tmp: the extents count in the allocated blocks
94 + * @goal: block offset for allocaton
97 * This function returns the values as below.
98 @@ -949,7 +968,7 @@ out:
99 static int
100 ext4_defrag_comp_ext_count(struct inode *org_inode,
101 struct ext4_ext_path *org_path, ext4_lblk_t tar_end,
102 - int sum_tmp)
103 + int sum_tmp, ext4_fsblk_t goal)
105 struct ext4_extent *ext = NULL;
106 int depth = ext_depth(org_inode);
107 @@ -973,7 +992,7 @@ ext4_defrag_comp_ext_count(struct inode
108 * Fail if goal is not set and the fragmentation
109 * is not improved.
111 - if (sum_org == sum_tmp) {
112 + if (sum_org == sum_tmp && !goal) {
113 /* Not improved */
114 ret = 1;
115 } else if (sum_org < sum_tmp) {
116 @@ -1004,6 +1023,7 @@ ext4_defrag_comp_ext_count(struct inode
117 * @tar_start: starting offset to allocate in blocks
118 * @tar_blocks: the number of blocks to allocate
119 * @iblock: file related offset
120 + * @goal: block offset for allocaton
123 * This function returns the value as below:
124 @@ -1014,7 +1034,8 @@ ext4_defrag_comp_ext_count(struct inode
125 static int
126 ext4_defrag_new_extent_tree(struct inode *org_inode, struct inode *tmp_inode,
127 struct ext4_ext_path *org_path, ext4_lblk_t tar_start,
128 - ext4_lblk_t tar_blocks, ext4_lblk_t iblock)
129 + ext4_lblk_t tar_blocks, ext4_lblk_t iblock,
130 + ext4_fsblk_t goal)
132 handle_t *handle;
133 struct ext4_extent_header *eh = NULL;
134 @@ -1040,7 +1061,7 @@ ext4_defrag_new_extent_tree(struct inode
136 /* Fill struct ext4_allocation_request with necessary info */
137 ext4_defrag_fill_ar(org_inode, tmp_inode, &ar, org_path,
138 - dest_path, tar_blocks, iblock);
139 + dest_path, tar_blocks, iblock, goal);
141 handle = ext4_journal_start(tmp_inode, 0);
142 if (IS_ERR(handle)) {
143 @@ -1072,7 +1093,7 @@ ext4_defrag_new_extent_tree(struct inode
146 ret = ext4_defrag_comp_ext_count(org_inode, org_path, tar_end,
147 - sum_tmp);
148 + sum_tmp, goal);
150 out:
151 if (ret < 0 || ret == 1) {
152 @@ -1202,13 +1223,14 @@ out:
153 * @filp: pointer to file
154 * @block_start: starting offset to defrag in blocks
155 * @defrag_size: size of defrag in blocks
156 + * @goal: block offset for allocation
158 * This function returns the number of blocks if succeed, otherwise
159 * returns error value.
162 ext4_defrag(struct file *filp, ext4_lblk_t block_start,
163 - ext4_lblk_t defrag_size)
164 + ext4_lblk_t defrag_size, ext4_fsblk_t goal)
166 struct inode *org_inode = filp->f_dentry->d_inode, *tmp_inode = NULL;
167 struct ext4_ext_path *org_path = NULL, *holecheck_path = NULL;
168 @@ -1327,14 +1349,14 @@ ext4_defrag(struct file *filp, ext4_lblk
171 /* Found an isolated block */
172 - if (seq_extents == 1) {
173 + if (seq_extents == 1 && !goal) {
174 seq_start = le32_to_cpu(ext_cur->ee_block);
175 goto CLEANUP;
178 ret = ext4_defrag_new_extent_tree(org_inode, tmp_inode,
179 org_path, seq_start, seq_blocks,
180 - block_start);
181 + block_start, goal);
183 if (ret < 0) {
184 break;
185 Index: linux-2.6.26-rc9/fs/ext4/ext4.h
186 ===================================================================
187 --- linux-2.6.26-rc9.orig/fs/ext4/ext4.h 2008-07-11 16:05:18.000000000 -0700
188 +++ linux-2.6.26-rc9/fs/ext4/ext4.h 2008-07-11 16:05:19.000000000 -0700
189 @@ -302,6 +302,7 @@ struct ext4_new_group_data {
190 #define EXT4_IOC_MIGRATE _IO('f', 9)
191 /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
192 #define EXT4_IOC_DEFRAG _IOW('f', 15, struct ext4_ext_defrag_data)
193 +#define EXT4_IOC_FIBMAP _IOW('f', 16, ext4_fsblk_t)
196 * ioctl commands in 32 bit emulation
197 @@ -1021,6 +1022,7 @@ extern int ext4_htree_store_dirent(struc
198 __u32 minor_hash,
199 struct ext4_dir_entry_2 *dirent);
200 extern void ext4_htree_free_dir_info(struct dir_private_info *p);
201 +extern sector_t ext4_bmap(struct address_space *mapping, sector_t block);
203 /* fsync.c */
204 extern int ext4_sync_file (struct file *, struct dentry *, int);
205 @@ -1144,7 +1146,7 @@ extern void ext4_inode_table_set(struct
206 extern int ext4_ext_journal_restart(handle_t *handle, int needed);
207 /* defrag.c */
208 extern int ext4_defrag(struct file *filp, ext4_lblk_t block_start,
209 - ext4_lblk_t defrag_size);
210 + ext4_lblk_t defrag_size, ext4_fsblk_t goal);
211 extern int ext4_defrag_ioctl(struct inode *, struct file *, unsigned int,
212 unsigned long);
214 Index: linux-2.6.26-rc9/fs/ext4/inode.c
215 ===================================================================
216 --- linux-2.6.26-rc9.orig/fs/ext4/inode.c 2008-07-11 16:05:18.000000000 -0700
217 +++ linux-2.6.26-rc9/fs/ext4/inode.c 2008-07-11 16:05:19.000000000 -0700
218 @@ -2396,7 +2396,7 @@ out:
219 * So, if we see any bmap calls here on a modified, data-journaled file,
220 * take extra steps to flush any blocks which might be in the cache.
222 -static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
223 +sector_t ext4_bmap(struct address_space *mapping, sector_t block)
225 struct inode *inode = mapping->host;
226 journal_t *journal;
227 Index: linux-2.6.26-rc9/fs/ext4/ioctl.c
228 ===================================================================
229 --- linux-2.6.26-rc9.orig/fs/ext4/ioctl.c 2008-07-11 16:05:18.000000000 -0700
230 +++ linux-2.6.26-rc9/fs/ext4/ioctl.c 2008-07-11 16:05:19.000000000 -0700
231 @@ -241,6 +241,7 @@ setversion_out:
233 return err;
235 + case EXT4_IOC_FIBMAP:
236 case EXT4_IOC_DEFRAG: {
237 return ext4_defrag_ioctl(inode, filp, cmd, arg);