aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hfsplus/extents.c')
-rw-r--r--fs/hfsplus/extents.c275
1 files changed, 165 insertions, 110 deletions
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index 0022eec63cda..b1991a2a08e0 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -83,37 +83,60 @@ static u32 hfsplus_ext_lastblock(struct hfsplus_extent *ext)
83 return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count); 83 return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count);
84} 84}
85 85
86static void __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) 86static void __hfsplus_ext_write_extent(struct inode *inode,
87 struct hfs_find_data *fd)
87{ 88{
89 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
88 int res; 90 int res;
89 91
90 hfsplus_ext_build_key(fd->search_key, inode->i_ino, HFSPLUS_I(inode).cached_start, 92 WARN_ON(!mutex_is_locked(&hip->extents_lock));
91 HFSPLUS_IS_RSRC(inode) ? HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA); 93
94 hfsplus_ext_build_key(fd->search_key, inode->i_ino, hip->cached_start,
95 HFSPLUS_IS_RSRC(inode) ?
96 HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA);
97
92 res = hfs_brec_find(fd); 98 res = hfs_brec_find(fd);
93 if (HFSPLUS_I(inode).flags & HFSPLUS_FLG_EXT_NEW) { 99 if (hip->extent_state & HFSPLUS_EXT_NEW) {
94 if (res != -ENOENT) 100 if (res != -ENOENT)
95 return; 101 return;
96 hfs_brec_insert(fd, HFSPLUS_I(inode).cached_extents, sizeof(hfsplus_extent_rec)); 102 hfs_brec_insert(fd, hip->cached_extents,
97 HFSPLUS_I(inode).flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW); 103 sizeof(hfsplus_extent_rec));
104 hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
98 } else { 105 } else {
99 if (res) 106 if (res)
100 return; 107 return;
101 hfs_bnode_write(fd->bnode, HFSPLUS_I(inode).cached_extents, fd->entryoffset, fd->entrylength); 108 hfs_bnode_write(fd->bnode, hip->cached_extents,
102 HFSPLUS_I(inode).flags &= ~HFSPLUS_FLG_EXT_DIRTY; 109 fd->entryoffset, fd->entrylength);
110 hip->extent_state &= ~HFSPLUS_EXT_DIRTY;
103 } 111 }
112
113 /*
114 * We can't just use hfsplus_mark_inode_dirty here, because we
115 * also get called from hfsplus_write_inode, which should not
116 * redirty the inode. Instead the callers have to be careful
117 * to explicily mark the inode dirty, too.
118 */
119 set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags);
104} 120}
105 121
106void hfsplus_ext_write_extent(struct inode *inode) 122static void hfsplus_ext_write_extent_locked(struct inode *inode)
107{ 123{
108 if (HFSPLUS_I(inode).flags & HFSPLUS_FLG_EXT_DIRTY) { 124 if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) {
109 struct hfs_find_data fd; 125 struct hfs_find_data fd;
110 126
111 hfs_find_init(HFSPLUS_SB(inode->i_sb).ext_tree, &fd); 127 hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd);
112 __hfsplus_ext_write_extent(inode, &fd); 128 __hfsplus_ext_write_extent(inode, &fd);
113 hfs_find_exit(&fd); 129 hfs_find_exit(&fd);
114 } 130 }
115} 131}
116 132
133void hfsplus_ext_write_extent(struct inode *inode)
134{
135 mutex_lock(&HFSPLUS_I(inode)->extents_lock);
136 hfsplus_ext_write_extent_locked(inode);
137 mutex_unlock(&HFSPLUS_I(inode)->extents_lock);
138}
139
117static inline int __hfsplus_ext_read_extent(struct hfs_find_data *fd, 140static inline int __hfsplus_ext_read_extent(struct hfs_find_data *fd,
118 struct hfsplus_extent *extent, 141 struct hfsplus_extent *extent,
119 u32 cnid, u32 block, u8 type) 142 u32 cnid, u32 block, u8 type)
@@ -130,39 +153,48 @@ static inline int __hfsplus_ext_read_extent(struct hfs_find_data *fd,
130 return -ENOENT; 153 return -ENOENT;
131 if (fd->entrylength != sizeof(hfsplus_extent_rec)) 154 if (fd->entrylength != sizeof(hfsplus_extent_rec))
132 return -EIO; 155 return -EIO;
133 hfs_bnode_read(fd->bnode, extent, fd->entryoffset, sizeof(hfsplus_extent_rec)); 156 hfs_bnode_read(fd->bnode, extent, fd->entryoffset,
157 sizeof(hfsplus_extent_rec));
134 return 0; 158 return 0;
135} 159}
136 160
137static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, struct inode *inode, u32 block) 161static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd,
162 struct inode *inode, u32 block)
138{ 163{
164 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
139 int res; 165 int res;
140 166
141 if (HFSPLUS_I(inode).flags & HFSPLUS_FLG_EXT_DIRTY) 167 WARN_ON(!mutex_is_locked(&hip->extents_lock));
168
169 if (hip->extent_state & HFSPLUS_EXT_DIRTY)
142 __hfsplus_ext_write_extent(inode, fd); 170 __hfsplus_ext_write_extent(inode, fd);
143 171
144 res = __hfsplus_ext_read_extent(fd, HFSPLUS_I(inode).cached_extents, inode->i_ino, 172 res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino,
145 block, HFSPLUS_IS_RSRC(inode) ? HFSPLUS_TYPE_RSRC : HFSPLUS_TYPE_DATA); 173 block, HFSPLUS_IS_RSRC(inode) ?
174 HFSPLUS_TYPE_RSRC :
175 HFSPLUS_TYPE_DATA);
146 if (!res) { 176 if (!res) {
147 HFSPLUS_I(inode).cached_start = be32_to_cpu(fd->key->ext.start_block); 177 hip->cached_start = be32_to_cpu(fd->key->ext.start_block);
148 HFSPLUS_I(inode).cached_blocks = hfsplus_ext_block_count(HFSPLUS_I(inode).cached_extents); 178 hip->cached_blocks =
179 hfsplus_ext_block_count(hip->cached_extents);
149 } else { 180 } else {
150 HFSPLUS_I(inode).cached_start = HFSPLUS_I(inode).cached_blocks = 0; 181 hip->cached_start = hip->cached_blocks = 0;
151 HFSPLUS_I(inode).flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW); 182 hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
152 } 183 }
153 return res; 184 return res;
154} 185}
155 186
156static int hfsplus_ext_read_extent(struct inode *inode, u32 block) 187static int hfsplus_ext_read_extent(struct inode *inode, u32 block)
157{ 188{
189 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
158 struct hfs_find_data fd; 190 struct hfs_find_data fd;
159 int res; 191 int res;
160 192
161 if (block >= HFSPLUS_I(inode).cached_start && 193 if (block >= hip->cached_start &&
162 block < HFSPLUS_I(inode).cached_start + HFSPLUS_I(inode).cached_blocks) 194 block < hip->cached_start + hip->cached_blocks)
163 return 0; 195 return 0;
164 196
165 hfs_find_init(HFSPLUS_SB(inode->i_sb).ext_tree, &fd); 197 hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd);
166 res = __hfsplus_ext_cache_extent(&fd, inode, block); 198 res = __hfsplus_ext_cache_extent(&fd, inode, block);
167 hfs_find_exit(&fd); 199 hfs_find_exit(&fd);
168 return res; 200 return res;
@@ -172,21 +204,22 @@ static int hfsplus_ext_read_extent(struct inode *inode, u32 block)
172int hfsplus_get_block(struct inode *inode, sector_t iblock, 204int hfsplus_get_block(struct inode *inode, sector_t iblock,
173 struct buffer_head *bh_result, int create) 205 struct buffer_head *bh_result, int create)
174{ 206{
175 struct super_block *sb; 207 struct super_block *sb = inode->i_sb;
208 struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
209 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
176 int res = -EIO; 210 int res = -EIO;
177 u32 ablock, dblock, mask; 211 u32 ablock, dblock, mask;
212 int was_dirty = 0;
178 int shift; 213 int shift;
179 214
180 sb = inode->i_sb;
181
182 /* Convert inode block to disk allocation block */ 215 /* Convert inode block to disk allocation block */
183 shift = HFSPLUS_SB(sb).alloc_blksz_shift - sb->s_blocksize_bits; 216 shift = sbi->alloc_blksz_shift - sb->s_blocksize_bits;
184 ablock = iblock >> HFSPLUS_SB(sb).fs_shift; 217 ablock = iblock >> sbi->fs_shift;
185 218
186 if (iblock >= HFSPLUS_I(inode).fs_blocks) { 219 if (iblock >= hip->fs_blocks) {
187 if (iblock > HFSPLUS_I(inode).fs_blocks || !create) 220 if (iblock > hip->fs_blocks || !create)
188 return -EIO; 221 return -EIO;
189 if (ablock >= HFSPLUS_I(inode).alloc_blocks) { 222 if (ablock >= hip->alloc_blocks) {
190 res = hfsplus_file_extend(inode); 223 res = hfsplus_file_extend(inode);
191 if (res) 224 if (res)
192 return res; 225 return res;
@@ -194,36 +227,46 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock,
194 } else 227 } else
195 create = 0; 228 create = 0;
196 229
197 if (ablock < HFSPLUS_I(inode).first_blocks) { 230 if (ablock < hip->first_blocks) {
198 dblock = hfsplus_ext_find_block(HFSPLUS_I(inode).first_extents, ablock); 231 dblock = hfsplus_ext_find_block(hip->first_extents, ablock);
199 goto done; 232 goto done;
200 } 233 }
201 234
202 if (inode->i_ino == HFSPLUS_EXT_CNID) 235 if (inode->i_ino == HFSPLUS_EXT_CNID)
203 return -EIO; 236 return -EIO;
204 237
205 mutex_lock(&HFSPLUS_I(inode).extents_lock); 238 mutex_lock(&hip->extents_lock);
239
240 /*
241 * hfsplus_ext_read_extent will write out a cached extent into
242 * the extents btree. In that case we may have to mark the inode
243 * dirty even for a pure read of an extent here.
244 */
245 was_dirty = (hip->extent_state & HFSPLUS_EXT_DIRTY);
206 res = hfsplus_ext_read_extent(inode, ablock); 246 res = hfsplus_ext_read_extent(inode, ablock);
207 if (!res) { 247 if (res) {
208 dblock = hfsplus_ext_find_block(HFSPLUS_I(inode).cached_extents, ablock - 248 mutex_unlock(&hip->extents_lock);
209 HFSPLUS_I(inode).cached_start);
210 } else {
211 mutex_unlock(&HFSPLUS_I(inode).extents_lock);
212 return -EIO; 249 return -EIO;
213 } 250 }
214 mutex_unlock(&HFSPLUS_I(inode).extents_lock); 251 dblock = hfsplus_ext_find_block(hip->cached_extents,
252 ablock - hip->cached_start);
253 mutex_unlock(&hip->extents_lock);
215 254
216done: 255done:
217 dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n", inode->i_ino, (long long)iblock, dblock); 256 dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n",
218 mask = (1 << HFSPLUS_SB(sb).fs_shift) - 1; 257 inode->i_ino, (long long)iblock, dblock);
219 map_bh(bh_result, sb, (dblock << HFSPLUS_SB(sb).fs_shift) + HFSPLUS_SB(sb).blockoffset + (iblock & mask)); 258 mask = (1 << sbi->fs_shift) - 1;
259 map_bh(bh_result, sb,
260 (dblock << sbi->fs_shift) + sbi->blockoffset +
261 (iblock & mask));
220 if (create) { 262 if (create) {
221 set_buffer_new(bh_result); 263 set_buffer_new(bh_result);
222 HFSPLUS_I(inode).phys_size += sb->s_blocksize; 264 hip->phys_size += sb->s_blocksize;
223 HFSPLUS_I(inode).fs_blocks++; 265 hip->fs_blocks++;
224 inode_add_bytes(inode, sb->s_blocksize); 266 inode_add_bytes(inode, sb->s_blocksize);
225 mark_inode_dirty(inode);
226 } 267 }
268 if (create || was_dirty)
269 mark_inode_dirty(inode);
227 return 0; 270 return 0;
228} 271}
229 272
@@ -306,7 +349,8 @@ found:
306 } 349 }
307} 350}
308 351
309int hfsplus_free_fork(struct super_block *sb, u32 cnid, struct hfsplus_fork_raw *fork, int type) 352int hfsplus_free_fork(struct super_block *sb, u32 cnid,
353 struct hfsplus_fork_raw *fork, int type)
310{ 354{
311 struct hfs_find_data fd; 355 struct hfs_find_data fd;
312 hfsplus_extent_rec ext_entry; 356 hfsplus_extent_rec ext_entry;
@@ -327,7 +371,7 @@ int hfsplus_free_fork(struct super_block *sb, u32 cnid, struct hfsplus_fork_raw
327 if (total_blocks == blocks) 371 if (total_blocks == blocks)
328 return 0; 372 return 0;
329 373
330 hfs_find_init(HFSPLUS_SB(sb).ext_tree, &fd); 374 hfs_find_init(HFSPLUS_SB(sb)->ext_tree, &fd);
331 do { 375 do {
332 res = __hfsplus_ext_read_extent(&fd, ext_entry, cnid, 376 res = __hfsplus_ext_read_extent(&fd, ext_entry, cnid,
333 total_blocks, type); 377 total_blocks, type);
@@ -348,29 +392,34 @@ int hfsplus_free_fork(struct super_block *sb, u32 cnid, struct hfsplus_fork_raw
348int hfsplus_file_extend(struct inode *inode) 392int hfsplus_file_extend(struct inode *inode)
349{ 393{
350 struct super_block *sb = inode->i_sb; 394 struct super_block *sb = inode->i_sb;
395 struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
396 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
351 u32 start, len, goal; 397 u32 start, len, goal;
352 int res; 398 int res;
353 399
354 if (HFSPLUS_SB(sb).alloc_file->i_size * 8 < HFSPLUS_SB(sb).total_blocks - HFSPLUS_SB(sb).free_blocks + 8) { 400 if (sbi->alloc_file->i_size * 8 <
355 // extend alloc file 401 sbi->total_blocks - sbi->free_blocks + 8) {
356 printk(KERN_ERR "hfs: extend alloc file! (%Lu,%u,%u)\n", HFSPLUS_SB(sb).alloc_file->i_size * 8, 402 /* extend alloc file */
357 HFSPLUS_SB(sb).total_blocks, HFSPLUS_SB(sb).free_blocks); 403 printk(KERN_ERR "hfs: extend alloc file! "
404 "(%llu,%u,%u)\n",
405 sbi->alloc_file->i_size * 8,
406 sbi->total_blocks, sbi->free_blocks);
358 return -ENOSPC; 407 return -ENOSPC;
359 } 408 }
360 409
361 mutex_lock(&HFSPLUS_I(inode).extents_lock); 410 mutex_lock(&hip->extents_lock);
362 if (HFSPLUS_I(inode).alloc_blocks == HFSPLUS_I(inode).first_blocks) 411 if (hip->alloc_blocks == hip->first_blocks)
363 goal = hfsplus_ext_lastblock(HFSPLUS_I(inode).first_extents); 412 goal = hfsplus_ext_lastblock(hip->first_extents);
364 else { 413 else {
365 res = hfsplus_ext_read_extent(inode, HFSPLUS_I(inode).alloc_blocks); 414 res = hfsplus_ext_read_extent(inode, hip->alloc_blocks);
366 if (res) 415 if (res)
367 goto out; 416 goto out;
368 goal = hfsplus_ext_lastblock(HFSPLUS_I(inode).cached_extents); 417 goal = hfsplus_ext_lastblock(hip->cached_extents);
369 } 418 }
370 419
371 len = HFSPLUS_I(inode).clump_blocks; 420 len = hip->clump_blocks;
372 start = hfsplus_block_allocate(sb, HFSPLUS_SB(sb).total_blocks, goal, &len); 421 start = hfsplus_block_allocate(sb, sbi->total_blocks, goal, &len);
373 if (start >= HFSPLUS_SB(sb).total_blocks) { 422 if (start >= sbi->total_blocks) {
374 start = hfsplus_block_allocate(sb, goal, 0, &len); 423 start = hfsplus_block_allocate(sb, goal, 0, &len);
375 if (start >= goal) { 424 if (start >= goal) {
376 res = -ENOSPC; 425 res = -ENOSPC;
@@ -379,56 +428,56 @@ int hfsplus_file_extend(struct inode *inode)
379 } 428 }
380 429
381 dprint(DBG_EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); 430 dprint(DBG_EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len);
382 if (HFSPLUS_I(inode).alloc_blocks <= HFSPLUS_I(inode).first_blocks) { 431
383 if (!HFSPLUS_I(inode).first_blocks) { 432 if (hip->alloc_blocks <= hip->first_blocks) {
433 if (!hip->first_blocks) {
384 dprint(DBG_EXTENT, "first extents\n"); 434 dprint(DBG_EXTENT, "first extents\n");
385 /* no extents yet */ 435 /* no extents yet */
386 HFSPLUS_I(inode).first_extents[0].start_block = cpu_to_be32(start); 436 hip->first_extents[0].start_block = cpu_to_be32(start);
387 HFSPLUS_I(inode).first_extents[0].block_count = cpu_to_be32(len); 437 hip->first_extents[0].block_count = cpu_to_be32(len);
388 res = 0; 438 res = 0;
389 } else { 439 } else {
390 /* try to append to extents in inode */ 440 /* try to append to extents in inode */
391 res = hfsplus_add_extent(HFSPLUS_I(inode).first_extents, 441 res = hfsplus_add_extent(hip->first_extents,
392 HFSPLUS_I(inode).alloc_blocks, 442 hip->alloc_blocks,
393 start, len); 443 start, len);
394 if (res == -ENOSPC) 444 if (res == -ENOSPC)
395 goto insert_extent; 445 goto insert_extent;
396 } 446 }
397 if (!res) { 447 if (!res) {
398 hfsplus_dump_extent(HFSPLUS_I(inode).first_extents); 448 hfsplus_dump_extent(hip->first_extents);
399 HFSPLUS_I(inode).first_blocks += len; 449 hip->first_blocks += len;
400 } 450 }
401 } else { 451 } else {
402 res = hfsplus_add_extent(HFSPLUS_I(inode).cached_extents, 452 res = hfsplus_add_extent(hip->cached_extents,
403 HFSPLUS_I(inode).alloc_blocks - 453 hip->alloc_blocks - hip->cached_start,
404 HFSPLUS_I(inode).cached_start,
405 start, len); 454 start, len);
406 if (!res) { 455 if (!res) {
407 hfsplus_dump_extent(HFSPLUS_I(inode).cached_extents); 456 hfsplus_dump_extent(hip->cached_extents);
408 HFSPLUS_I(inode).flags |= HFSPLUS_FLG_EXT_DIRTY; 457 hip->extent_state |= HFSPLUS_EXT_DIRTY;
409 HFSPLUS_I(inode).cached_blocks += len; 458 hip->cached_blocks += len;
410 } else if (res == -ENOSPC) 459 } else if (res == -ENOSPC)
411 goto insert_extent; 460 goto insert_extent;
412 } 461 }
413out: 462out:
414 mutex_unlock(&HFSPLUS_I(inode).extents_lock); 463 mutex_unlock(&hip->extents_lock);
415 if (!res) { 464 if (!res) {
416 HFSPLUS_I(inode).alloc_blocks += len; 465 hip->alloc_blocks += len;
417 mark_inode_dirty(inode); 466 hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY);
418 } 467 }
419 return res; 468 return res;
420 469
421insert_extent: 470insert_extent:
422 dprint(DBG_EXTENT, "insert new extent\n"); 471 dprint(DBG_EXTENT, "insert new extent\n");
423 hfsplus_ext_write_extent(inode); 472 hfsplus_ext_write_extent_locked(inode);
424 473
425 memset(HFSPLUS_I(inode).cached_extents, 0, sizeof(hfsplus_extent_rec)); 474 memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec));
426 HFSPLUS_I(inode).cached_extents[0].start_block = cpu_to_be32(start); 475 hip->cached_extents[0].start_block = cpu_to_be32(start);
427 HFSPLUS_I(inode).cached_extents[0].block_count = cpu_to_be32(len); 476 hip->cached_extents[0].block_count = cpu_to_be32(len);
428 hfsplus_dump_extent(HFSPLUS_I(inode).cached_extents); 477 hfsplus_dump_extent(hip->cached_extents);
429 HFSPLUS_I(inode).flags |= HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW; 478 hip->extent_state |= HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW;
430 HFSPLUS_I(inode).cached_start = HFSPLUS_I(inode).alloc_blocks; 479 hip->cached_start = hip->alloc_blocks;
431 HFSPLUS_I(inode).cached_blocks = len; 480 hip->cached_blocks = len;
432 481
433 res = 0; 482 res = 0;
434 goto out; 483 goto out;
@@ -437,13 +486,16 @@ insert_extent:
437void hfsplus_file_truncate(struct inode *inode) 486void hfsplus_file_truncate(struct inode *inode)
438{ 487{
439 struct super_block *sb = inode->i_sb; 488 struct super_block *sb = inode->i_sb;
489 struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
440 struct hfs_find_data fd; 490 struct hfs_find_data fd;
441 u32 alloc_cnt, blk_cnt, start; 491 u32 alloc_cnt, blk_cnt, start;
442 int res; 492 int res;
443 493
444 dprint(DBG_INODE, "truncate: %lu, %Lu -> %Lu\n", inode->i_ino, 494 dprint(DBG_INODE, "truncate: %lu, %llu -> %llu\n",
445 (long long)HFSPLUS_I(inode).phys_size, inode->i_size); 495 inode->i_ino, (long long)hip->phys_size,
446 if (inode->i_size > HFSPLUS_I(inode).phys_size) { 496 inode->i_size);
497
498 if (inode->i_size > hip->phys_size) {
447 struct address_space *mapping = inode->i_mapping; 499 struct address_space *mapping = inode->i_mapping;
448 struct page *page; 500 struct page *page;
449 void *fsdata; 501 void *fsdata;
@@ -455,52 +507,55 @@ void hfsplus_file_truncate(struct inode *inode)
455 &page, &fsdata); 507 &page, &fsdata);
456 if (res) 508 if (res)
457 return; 509 return;
458 res = pagecache_write_end(NULL, mapping, size, 0, 0, page, fsdata); 510 res = pagecache_write_end(NULL, mapping, size,
511 0, 0, page, fsdata);
459 if (res < 0) 512 if (res < 0)
460 return; 513 return;
461 mark_inode_dirty(inode); 514 mark_inode_dirty(inode);
462 return; 515 return;
463 } else if (inode->i_size == HFSPLUS_I(inode).phys_size) 516 } else if (inode->i_size == hip->phys_size)
464 return; 517 return;
465 518
466 blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift; 519 blk_cnt = (inode->i_size + HFSPLUS_SB(sb)->alloc_blksz - 1) >>
467 alloc_cnt = HFSPLUS_I(inode).alloc_blocks; 520 HFSPLUS_SB(sb)->alloc_blksz_shift;
521 alloc_cnt = hip->alloc_blocks;
468 if (blk_cnt == alloc_cnt) 522 if (blk_cnt == alloc_cnt)
469 goto out; 523 goto out;
470 524
471 mutex_lock(&HFSPLUS_I(inode).extents_lock); 525 mutex_lock(&hip->extents_lock);
472 hfs_find_init(HFSPLUS_SB(sb).ext_tree, &fd); 526 hfs_find_init(HFSPLUS_SB(sb)->ext_tree, &fd);
473 while (1) { 527 while (1) {
474 if (alloc_cnt == HFSPLUS_I(inode).first_blocks) { 528 if (alloc_cnt == hip->first_blocks) {
475 hfsplus_free_extents(sb, HFSPLUS_I(inode).first_extents, 529 hfsplus_free_extents(sb, hip->first_extents,
476 alloc_cnt, alloc_cnt - blk_cnt); 530 alloc_cnt, alloc_cnt - blk_cnt);
477 hfsplus_dump_extent(HFSPLUS_I(inode).first_extents); 531 hfsplus_dump_extent(hip->first_extents);
478 HFSPLUS_I(inode).first_blocks = blk_cnt; 532 hip->first_blocks = blk_cnt;
479 break; 533 break;
480 } 534 }
481 res = __hfsplus_ext_cache_extent(&fd, inode, alloc_cnt); 535 res = __hfsplus_ext_cache_extent(&fd, inode, alloc_cnt);
482 if (res) 536 if (res)
483 break; 537 break;
484 start = HFSPLUS_I(inode).cached_start; 538 start = hip->cached_start;
485 hfsplus_free_extents(sb, HFSPLUS_I(inode).cached_extents, 539 hfsplus_free_extents(sb, hip->cached_extents,
486 alloc_cnt - start, alloc_cnt - blk_cnt); 540 alloc_cnt - start, alloc_cnt - blk_cnt);
487 hfsplus_dump_extent(HFSPLUS_I(inode).cached_extents); 541 hfsplus_dump_extent(hip->cached_extents);
488 if (blk_cnt > start) { 542 if (blk_cnt > start) {
489 HFSPLUS_I(inode).flags |= HFSPLUS_FLG_EXT_DIRTY; 543 hip->extent_state |= HFSPLUS_EXT_DIRTY;
490 break; 544 break;
491 } 545 }
492 alloc_cnt = start; 546 alloc_cnt = start;
493 HFSPLUS_I(inode).cached_start = HFSPLUS_I(inode).cached_blocks = 0; 547 hip->cached_start = hip->cached_blocks = 0;
494 HFSPLUS_I(inode).flags &= ~(HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW); 548 hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
495 hfs_brec_remove(&fd); 549 hfs_brec_remove(&fd);
496 } 550 }
497 hfs_find_exit(&fd); 551 hfs_find_exit(&fd);
498 mutex_unlock(&HFSPLUS_I(inode).extents_lock); 552 mutex_unlock(&hip->extents_lock);
499 553
500 HFSPLUS_I(inode).alloc_blocks = blk_cnt; 554 hip->alloc_blocks = blk_cnt;
501out: 555out:
502 HFSPLUS_I(inode).phys_size = inode->i_size; 556 hip->phys_size = inode->i_size;
503 HFSPLUS_I(inode).fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; 557 hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >>
504 inode_set_bytes(inode, HFSPLUS_I(inode).fs_blocks << sb->s_blocksize_bits); 558 sb->s_blocksize_bits;
505 mark_inode_dirty(inode); 559 inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits);
560 hfsplus_mark_inode_dirty(inode, HFSPLUS_I_ALLOC_DIRTY);
506} 561}