diff options
Diffstat (limited to 'fs/ufs')
-rw-r--r-- | fs/ufs/balloc.c | 86 | ||||
-rw-r--r-- | fs/ufs/ialloc.c | 5 | ||||
-rw-r--r-- | fs/ufs/inode.c | 36 | ||||
-rw-r--r-- | fs/ufs/truncate.c | 38 |
4 files changed, 103 insertions, 62 deletions
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index bcc44084e004..841ac25fd950 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -244,62 +244,87 @@ failed: | |||
244 | * We can come here from ufs_writepage or ufs_prepare_write, | 244 | * We can come here from ufs_writepage or ufs_prepare_write, |
245 | * locked_page is argument of these functions, so we already lock it. | 245 | * locked_page is argument of these functions, so we already lock it. |
246 | */ | 246 | */ |
247 | static void ufs_change_blocknr(struct inode *inode, unsigned int beg, | 247 | static void ufs_change_blocknr(struct inode *inode, sector_t beg, |
248 | unsigned int count, unsigned int oldb, | 248 | unsigned int count, sector_t oldb, |
249 | unsigned int newb, struct page *locked_page) | 249 | sector_t newb, struct page *locked_page) |
250 | { | 250 | { |
251 | const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1; | 251 | const unsigned blks_per_page = |
252 | 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
253 | const unsigned mask = blks_per_page - 1; | ||
252 | struct address_space * const mapping = inode->i_mapping; | 254 | struct address_space * const mapping = inode->i_mapping; |
253 | pgoff_t index, cur_index; | 255 | pgoff_t index, cur_index, last_index; |
254 | unsigned end, pos, j; | 256 | unsigned pos, j, lblock; |
257 | sector_t end, i; | ||
255 | struct page *page; | 258 | struct page *page; |
256 | struct buffer_head *head, *bh; | 259 | struct buffer_head *head, *bh; |
257 | 260 | ||
258 | UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", | 261 | UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu\n", |
259 | inode->i_ino, count, oldb, newb); | 262 | inode->i_ino, count, |
263 | (unsigned long long)oldb, (unsigned long long)newb); | ||
260 | 264 | ||
261 | BUG_ON(!locked_page); | 265 | BUG_ON(!locked_page); |
262 | BUG_ON(!PageLocked(locked_page)); | 266 | BUG_ON(!PageLocked(locked_page)); |
263 | 267 | ||
264 | cur_index = locked_page->index; | 268 | cur_index = locked_page->index; |
265 | 269 | end = count + beg; | |
266 | for (end = count + beg; beg < end; beg = (beg | mask) + 1) { | 270 | last_index = end >> (PAGE_CACHE_SHIFT - inode->i_blkbits); |
267 | index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits); | 271 | for (i = beg; i < end; i = (i | mask) + 1) { |
272 | index = i >> (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
268 | 273 | ||
269 | if (likely(cur_index != index)) { | 274 | if (likely(cur_index != index)) { |
270 | page = ufs_get_locked_page(mapping, index); | 275 | page = ufs_get_locked_page(mapping, index); |
271 | if (!page || IS_ERR(page)) /* it was truncated or EIO */ | 276 | if (!page)/* it was truncated */ |
277 | continue; | ||
278 | if (IS_ERR(page)) {/* or EIO */ | ||
279 | ufs_error(inode->i_sb, __FUNCTION__, | ||
280 | "read of page %llu failed\n", | ||
281 | (unsigned long long)index); | ||
272 | continue; | 282 | continue; |
283 | } | ||
273 | } else | 284 | } else |
274 | page = locked_page; | 285 | page = locked_page; |
275 | 286 | ||
276 | head = page_buffers(page); | 287 | head = page_buffers(page); |
277 | bh = head; | 288 | bh = head; |
278 | pos = beg & mask; | 289 | pos = i & mask; |
279 | for (j = 0; j < pos; ++j) | 290 | for (j = 0; j < pos; ++j) |
280 | bh = bh->b_this_page; | 291 | bh = bh->b_this_page; |
281 | j = 0; | 292 | |
293 | |||
294 | if (unlikely(index == last_index)) | ||
295 | lblock = end & mask; | ||
296 | else | ||
297 | lblock = blks_per_page; | ||
298 | |||
282 | do { | 299 | do { |
283 | if (buffer_mapped(bh)) { | 300 | if (j >= lblock) |
284 | pos = bh->b_blocknr - oldb; | 301 | break; |
285 | if (pos < count) { | 302 | pos = (i - beg) + j; |
286 | UFSD(" change from %llu to %llu\n", | 303 | |
287 | (unsigned long long)pos + oldb, | 304 | if (!buffer_mapped(bh)) |
288 | (unsigned long long)pos + newb); | 305 | map_bh(bh, inode->i_sb, oldb + pos); |
289 | bh->b_blocknr = newb + pos; | 306 | if (!buffer_uptodate(bh)) { |
290 | unmap_underlying_metadata(bh->b_bdev, | 307 | ll_rw_block(READ, 1, &bh); |
291 | bh->b_blocknr); | 308 | wait_on_buffer(bh); |
292 | mark_buffer_dirty(bh); | 309 | if (!buffer_uptodate(bh)) { |
293 | ++j; | 310 | ufs_error(inode->i_sb, __FUNCTION__, |
311 | "read of block failed\n"); | ||
312 | break; | ||
294 | } | 313 | } |
295 | } | 314 | } |
296 | 315 | ||
316 | UFSD(" change from %llu to %llu, pos %u\n", | ||
317 | (unsigned long long)pos + oldb, | ||
318 | (unsigned long long)pos + newb, pos); | ||
319 | |||
320 | bh->b_blocknr = newb + pos; | ||
321 | unmap_underlying_metadata(bh->b_bdev, | ||
322 | bh->b_blocknr); | ||
323 | mark_buffer_dirty(bh); | ||
324 | ++j; | ||
297 | bh = bh->b_this_page; | 325 | bh = bh->b_this_page; |
298 | } while (bh != head); | 326 | } while (bh != head); |
299 | 327 | ||
300 | if (j) | ||
301 | set_page_dirty(page); | ||
302 | |||
303 | if (likely(cur_index != index)) | 328 | if (likely(cur_index != index)) |
304 | ufs_put_locked_page(page); | 329 | ufs_put_locked_page(page); |
305 | } | 330 | } |
@@ -457,8 +482,9 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
457 | if (result) { | 482 | if (result) { |
458 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | 483 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, |
459 | locked_page != NULL); | 484 | locked_page != NULL); |
460 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, | 485 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, |
461 | result, locked_page); | 486 | uspi->s_sbbase + tmp, |
487 | uspi->s_sbbase + result, locked_page); | ||
462 | ufs_cpu_to_data_ptr(sb, p, result); | 488 | ufs_cpu_to_data_ptr(sb, p, result); |
463 | *err = 0; | 489 | *err = 0; |
464 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 490 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index b868878009b6..c28a8b6f2feb 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -343,9 +343,8 @@ cg_found: | |||
343 | lock_buffer(bh); | 343 | lock_buffer(bh); |
344 | ufs2_inode = (struct ufs2_inode *)bh->b_data; | 344 | ufs2_inode = (struct ufs2_inode *)bh->b_data; |
345 | ufs2_inode += ufs_inotofsbo(inode->i_ino); | 345 | ufs2_inode += ufs_inotofsbo(inode->i_ino); |
346 | ufs2_inode->ui_birthtime.tv_sec = | 346 | ufs2_inode->ui_birthtime = cpu_to_fs64(sb, CURRENT_TIME.tv_sec); |
347 | cpu_to_fs32(sb, CURRENT_TIME_SEC.tv_sec); | 347 | ufs2_inode->ui_birthnsec = cpu_to_fs32(sb, CURRENT_TIME.tv_nsec); |
348 | ufs2_inode->ui_birthtime.tv_usec = 0; | ||
349 | mark_buffer_dirty(bh); | 348 | mark_buffer_dirty(bh); |
350 | unlock_buffer(bh); | 349 | unlock_buffer(bh); |
351 | if (sb->s_flags & MS_SYNCHRONOUS) | 350 | if (sb->s_flags & MS_SYNCHRONOUS) |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index fb34ad03e224..013d7afe7cde 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -212,7 +212,7 @@ repeat: | |||
212 | brelse (result); | 212 | brelse (result); |
213 | goto repeat; | 213 | goto repeat; |
214 | } else { | 214 | } else { |
215 | *phys = tmp + blockoff; | 215 | *phys = uspi->s_sbbase + tmp + blockoff; |
216 | return NULL; | 216 | return NULL; |
217 | } | 217 | } |
218 | } | 218 | } |
@@ -282,9 +282,9 @@ repeat: | |||
282 | } | 282 | } |
283 | 283 | ||
284 | if (!phys) { | 284 | if (!phys) { |
285 | result = sb_getblk(sb, tmp + blockoff); | 285 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
286 | } else { | 286 | } else { |
287 | *phys = tmp + blockoff; | 287 | *phys = uspi->s_sbbase + tmp + blockoff; |
288 | result = NULL; | 288 | result = NULL; |
289 | *err = 0; | 289 | *err = 0; |
290 | *new = 1; | 290 | *new = 1; |
@@ -368,7 +368,7 @@ repeat: | |||
368 | brelse (result); | 368 | brelse (result); |
369 | goto repeat; | 369 | goto repeat; |
370 | } else { | 370 | } else { |
371 | *phys = tmp + blockoff; | 371 | *phys = uspi->s_sbbase + tmp + blockoff; |
372 | goto out; | 372 | goto out; |
373 | } | 373 | } |
374 | } | 374 | } |
@@ -389,9 +389,9 @@ repeat: | |||
389 | 389 | ||
390 | 390 | ||
391 | if (!phys) { | 391 | if (!phys) { |
392 | result = sb_getblk(sb, tmp + blockoff); | 392 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
393 | } else { | 393 | } else { |
394 | *phys = tmp + blockoff; | 394 | *phys = uspi->s_sbbase + tmp + blockoff; |
395 | *new = 1; | 395 | *new = 1; |
396 | } | 396 | } |
397 | 397 | ||
@@ -668,12 +668,12 @@ static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) | |||
668 | inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); | 668 | inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); |
669 | 669 | ||
670 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); | 670 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); |
671 | inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_atime.tv_sec); | 671 | inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime); |
672 | inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_ctime.tv_sec); | 672 | inode->i_ctime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_ctime); |
673 | inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_mtime.tv_sec); | 673 | inode->i_mtime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_mtime); |
674 | inode->i_mtime.tv_nsec = 0; | 674 | inode->i_atime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_atimensec); |
675 | inode->i_atime.tv_nsec = 0; | 675 | inode->i_ctime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_ctimensec); |
676 | inode->i_ctime.tv_nsec = 0; | 676 | inode->i_mtime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_mtimensec); |
677 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); | 677 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); |
678 | inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); | 678 | inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); |
679 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); | 679 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); |
@@ -803,12 +803,12 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode) | |||
803 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); | 803 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); |
804 | 804 | ||
805 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); | 805 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); |
806 | ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec); | 806 | ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec); |
807 | ufs_inode->ui_atime.tv_usec = 0; | 807 | ufs_inode->ui_atimensec = cpu_to_fs32(sb, inode->i_atime.tv_nsec); |
808 | ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec); | 808 | ufs_inode->ui_ctime = cpu_to_fs64(sb, inode->i_ctime.tv_sec); |
809 | ufs_inode->ui_ctime.tv_usec = 0; | 809 | ufs_inode->ui_ctimensec = cpu_to_fs32(sb, inode->i_ctime.tv_nsec); |
810 | ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec); | 810 | ufs_inode->ui_mtime = cpu_to_fs64(sb, inode->i_mtime.tv_sec); |
811 | ufs_inode->ui_mtime.tv_usec = 0; | 811 | ufs_inode->ui_mtimensec = cpu_to_fs32(sb, inode->i_mtime.tv_nsec); |
812 | 812 | ||
813 | ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); | 813 | ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); |
814 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); | 814 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 749581fa7729..79c54c85fb58 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -74,7 +74,7 @@ static int ufs_trunc_direct(struct inode *inode) | |||
74 | unsigned i, tmp; | 74 | unsigned i, tmp; |
75 | int retry; | 75 | int retry; |
76 | 76 | ||
77 | UFSD("ENTER\n"); | 77 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
78 | 78 | ||
79 | sb = inode->i_sb; | 79 | sb = inode->i_sb; |
80 | uspi = UFS_SB(sb)->s_uspi; | 80 | uspi = UFS_SB(sb)->s_uspi; |
@@ -96,8 +96,8 @@ static int ufs_trunc_direct(struct inode *inode) | |||
96 | block2 = ufs_fragstoblks (frag3); | 96 | block2 = ufs_fragstoblks (frag3); |
97 | } | 97 | } |
98 | 98 | ||
99 | UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu," | 99 | UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu," |
100 | " frag4 %llu\n", | 100 | " frag3 %llu, frag4 %llu\n", inode->i_ino, |
101 | (unsigned long long)frag1, (unsigned long long)frag2, | 101 | (unsigned long long)frag1, (unsigned long long)frag2, |
102 | (unsigned long long)block1, (unsigned long long)block2, | 102 | (unsigned long long)block1, (unsigned long long)block2, |
103 | (unsigned long long)frag3, (unsigned long long)frag4); | 103 | (unsigned long long)frag3, (unsigned long long)frag4); |
@@ -163,7 +163,7 @@ next1: | |||
163 | mark_inode_dirty(inode); | 163 | mark_inode_dirty(inode); |
164 | next3: | 164 | next3: |
165 | 165 | ||
166 | UFSD("EXIT\n"); | 166 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
167 | return retry; | 167 | return retry; |
168 | } | 168 | } |
169 | 169 | ||
@@ -248,7 +248,7 @@ static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p) | |||
248 | } | 248 | } |
249 | ubh_brelse (ind_ubh); | 249 | ubh_brelse (ind_ubh); |
250 | 250 | ||
251 | UFSD("EXIT\n"); | 251 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
252 | 252 | ||
253 | return retry; | 253 | return retry; |
254 | } | 254 | } |
@@ -262,7 +262,7 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) | |||
262 | void *dind; | 262 | void *dind; |
263 | int retry = 0; | 263 | int retry = 0; |
264 | 264 | ||
265 | UFSD("ENTER\n"); | 265 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
266 | 266 | ||
267 | sb = inode->i_sb; | 267 | sb = inode->i_sb; |
268 | uspi = UFS_SB(sb)->s_uspi; | 268 | uspi = UFS_SB(sb)->s_uspi; |
@@ -312,7 +312,7 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) | |||
312 | } | 312 | } |
313 | ubh_brelse (dind_bh); | 313 | ubh_brelse (dind_bh); |
314 | 314 | ||
315 | UFSD("EXIT\n"); | 315 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
316 | 316 | ||
317 | return retry; | 317 | return retry; |
318 | } | 318 | } |
@@ -327,7 +327,7 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
327 | void *tind, *p; | 327 | void *tind, *p; |
328 | int retry; | 328 | int retry; |
329 | 329 | ||
330 | UFSD("ENTER\n"); | 330 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
331 | 331 | ||
332 | retry = 0; | 332 | retry = 0; |
333 | 333 | ||
@@ -348,7 +348,7 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
348 | } | 348 | } |
349 | 349 | ||
350 | for (i = tindirect_block ; i < uspi->s_apb ; i++) { | 350 | for (i = tindirect_block ; i < uspi->s_apb ; i++) { |
351 | tind = ubh_get_addr32 (tind_bh, i); | 351 | tind = ubh_get_data_ptr(uspi, tind_bh, i); |
352 | retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + | 352 | retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + |
353 | uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); | 353 | uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); |
354 | ubh_mark_buffer_dirty(tind_bh); | 354 | ubh_mark_buffer_dirty(tind_bh); |
@@ -372,19 +372,21 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
372 | } | 372 | } |
373 | ubh_brelse (tind_bh); | 373 | ubh_brelse (tind_bh); |
374 | 374 | ||
375 | UFSD("EXIT\n"); | 375 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
376 | return retry; | 376 | return retry; |
377 | } | 377 | } |
378 | 378 | ||
379 | static int ufs_alloc_lastblock(struct inode *inode) | 379 | static int ufs_alloc_lastblock(struct inode *inode) |
380 | { | 380 | { |
381 | int err = 0; | 381 | int err = 0; |
382 | struct super_block *sb = inode->i_sb; | ||
382 | struct address_space *mapping = inode->i_mapping; | 383 | struct address_space *mapping = inode->i_mapping; |
383 | struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; | 384 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
384 | unsigned i, end; | 385 | unsigned i, end; |
385 | sector_t lastfrag; | 386 | sector_t lastfrag; |
386 | struct page *lastpage; | 387 | struct page *lastpage; |
387 | struct buffer_head *bh; | 388 | struct buffer_head *bh; |
389 | u64 phys64; | ||
388 | 390 | ||
389 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; | 391 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; |
390 | 392 | ||
@@ -424,6 +426,20 @@ static int ufs_alloc_lastblock(struct inode *inode) | |||
424 | set_page_dirty(lastpage); | 426 | set_page_dirty(lastpage); |
425 | } | 427 | } |
426 | 428 | ||
429 | if (lastfrag >= UFS_IND_FRAGMENT) { | ||
430 | end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1; | ||
431 | phys64 = bh->b_blocknr + 1; | ||
432 | for (i = 0; i < end; ++i) { | ||
433 | bh = sb_getblk(sb, i + phys64); | ||
434 | lock_buffer(bh); | ||
435 | memset(bh->b_data, 0, sb->s_blocksize); | ||
436 | set_buffer_uptodate(bh); | ||
437 | mark_buffer_dirty(bh); | ||
438 | unlock_buffer(bh); | ||
439 | sync_dirty_buffer(bh); | ||
440 | brelse(bh); | ||
441 | } | ||
442 | } | ||
427 | out_unlock: | 443 | out_unlock: |
428 | ufs_put_locked_page(lastpage); | 444 | ufs_put_locked_page(lastpage); |
429 | out: | 445 | out: |