diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 18:30:29 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 18:30:29 -0500 |
| commit | f4d544ee5720d336a8c64f9fd33efb888c302309 (patch) | |
| tree | 3b4674d46b04fbcfc38677df59c92320f65568dd /fs | |
| parent | 0e2f7b837600979d5b6f174a6ff695b85942e985 (diff) | |
| parent | 44a743f68705c681439f264deb05f8f38e9048d3 (diff) | |
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
* 'for-linus' of git://oss.sgi.com/xfs/xfs:
xfs: Fix error return for fallocate() on XFS
xfs: cleanup dmapi macros in the umount path
xfs: remove incorrect sparse annotation for xfs_iget_cache_miss
xfs: kill the STATIC_INLINE macro
xfs: uninline xfs_get_extsz_hint
xfs: rename xfs_attr_fetch to xfs_attr_get_int
xfs: simplify xfs_buf_get / xfs_buf_read interfaces
xfs: remove IO_ISAIO
xfs: Wrapped journal record corruption on read at recovery
xfs: cleanup data end I/O handlers
xfs: use WRITE_SYNC_PLUG for synchronous writeout
xfs: reset the i_iolock lock class in the reclaim path
xfs: I/O completion handlers must use NOFS allocations
xfs: fix mmap_sem/iolock inversion in xfs_free_eofblocks
xfs: simplify inode teardown
Diffstat (limited to 'fs')
30 files changed, 254 insertions, 321 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 70f989895d15..87813e405cef 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -235,71 +235,36 @@ xfs_setfilesize( | |||
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | /* | 237 | /* |
| 238 | * Buffered IO write completion for delayed allocate extents. | 238 | * IO write completion. |
| 239 | */ | 239 | */ |
| 240 | STATIC void | 240 | STATIC void |
| 241 | xfs_end_bio_delalloc( | 241 | xfs_end_io( |
| 242 | struct work_struct *work) | ||
| 243 | { | ||
| 244 | xfs_ioend_t *ioend = | ||
| 245 | container_of(work, xfs_ioend_t, io_work); | ||
| 246 | |||
| 247 | xfs_setfilesize(ioend); | ||
| 248 | xfs_destroy_ioend(ioend); | ||
| 249 | } | ||
| 250 | |||
| 251 | /* | ||
| 252 | * Buffered IO write completion for regular, written extents. | ||
| 253 | */ | ||
| 254 | STATIC void | ||
| 255 | xfs_end_bio_written( | ||
| 256 | struct work_struct *work) | ||
| 257 | { | ||
| 258 | xfs_ioend_t *ioend = | ||
| 259 | container_of(work, xfs_ioend_t, io_work); | ||
| 260 | |||
| 261 | xfs_setfilesize(ioend); | ||
| 262 | xfs_destroy_ioend(ioend); | ||
| 263 | } | ||
| 264 | |||
| 265 | /* | ||
| 266 | * IO write completion for unwritten extents. | ||
| 267 | * | ||
| 268 | * Issue transactions to convert a buffer range from unwritten | ||
| 269 | * to written extents. | ||
| 270 | */ | ||
| 271 | STATIC void | ||
| 272 | xfs_end_bio_unwritten( | ||
| 273 | struct work_struct *work) | 242 | struct work_struct *work) |
| 274 | { | 243 | { |
| 275 | xfs_ioend_t *ioend = | 244 | xfs_ioend_t *ioend = |
| 276 | container_of(work, xfs_ioend_t, io_work); | 245 | container_of(work, xfs_ioend_t, io_work); |
| 277 | struct xfs_inode *ip = XFS_I(ioend->io_inode); | 246 | struct xfs_inode *ip = XFS_I(ioend->io_inode); |
| 278 | xfs_off_t offset = ioend->io_offset; | ||
| 279 | size_t size = ioend->io_size; | ||
| 280 | |||
| 281 | if (likely(!ioend->io_error)) { | ||
| 282 | if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { | ||
| 283 | int error; | ||
| 284 | error = xfs_iomap_write_unwritten(ip, offset, size); | ||
| 285 | if (error) | ||
| 286 | ioend->io_error = error; | ||
| 287 | } | ||
| 288 | xfs_setfilesize(ioend); | ||
| 289 | } | ||
| 290 | xfs_destroy_ioend(ioend); | ||
| 291 | } | ||
| 292 | 247 | ||
| 293 | /* | 248 | /* |
| 294 | * IO read completion for regular, written extents. | 249 | * For unwritten extents we need to issue transactions to convert a |
| 295 | */ | 250 | * range to normal written extens after the data I/O has finished. |
| 296 | STATIC void | 251 | */ |
| 297 | xfs_end_bio_read( | 252 | if (ioend->io_type == IOMAP_UNWRITTEN && |
| 298 | struct work_struct *work) | 253 | likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) { |
| 299 | { | 254 | int error; |
| 300 | xfs_ioend_t *ioend = | 255 | |
| 301 | container_of(work, xfs_ioend_t, io_work); | 256 | error = xfs_iomap_write_unwritten(ip, ioend->io_offset, |
| 257 | ioend->io_size); | ||
| 258 | if (error) | ||
| 259 | ioend->io_error = error; | ||
| 260 | } | ||
| 302 | 261 | ||
| 262 | /* | ||
| 263 | * We might have to update the on-disk file size after extending | ||
| 264 | * writes. | ||
| 265 | */ | ||
| 266 | if (ioend->io_type != IOMAP_READ) | ||
| 267 | xfs_setfilesize(ioend); | ||
| 303 | xfs_destroy_ioend(ioend); | 268 | xfs_destroy_ioend(ioend); |
| 304 | } | 269 | } |
| 305 | 270 | ||
| @@ -314,10 +279,10 @@ xfs_finish_ioend( | |||
| 314 | int wait) | 279 | int wait) |
| 315 | { | 280 | { |
| 316 | if (atomic_dec_and_test(&ioend->io_remaining)) { | 281 | if (atomic_dec_and_test(&ioend->io_remaining)) { |
| 317 | struct workqueue_struct *wq = xfsdatad_workqueue; | 282 | struct workqueue_struct *wq; |
| 318 | if (ioend->io_work.func == xfs_end_bio_unwritten) | ||
| 319 | wq = xfsconvertd_workqueue; | ||
| 320 | 283 | ||
| 284 | wq = (ioend->io_type == IOMAP_UNWRITTEN) ? | ||
| 285 | xfsconvertd_workqueue : xfsdatad_workqueue; | ||
| 321 | queue_work(wq, &ioend->io_work); | 286 | queue_work(wq, &ioend->io_work); |
| 322 | if (wait) | 287 | if (wait) |
| 323 | flush_workqueue(wq); | 288 | flush_workqueue(wq); |
| @@ -355,15 +320,7 @@ xfs_alloc_ioend( | |||
| 355 | ioend->io_offset = 0; | 320 | ioend->io_offset = 0; |
| 356 | ioend->io_size = 0; | 321 | ioend->io_size = 0; |
| 357 | 322 | ||
| 358 | if (type == IOMAP_UNWRITTEN) | 323 | INIT_WORK(&ioend->io_work, xfs_end_io); |
| 359 | INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); | ||
| 360 | else if (type == IOMAP_DELAY) | ||
| 361 | INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); | ||
| 362 | else if (type == IOMAP_READ) | ||
| 363 | INIT_WORK(&ioend->io_work, xfs_end_bio_read); | ||
| 364 | else | ||
| 365 | INIT_WORK(&ioend->io_work, xfs_end_bio_written); | ||
| 366 | |||
| 367 | return ioend; | 324 | return ioend; |
| 368 | } | 325 | } |
| 369 | 326 | ||
| @@ -380,7 +337,7 @@ xfs_map_blocks( | |||
| 380 | return -xfs_iomap(XFS_I(inode), offset, count, flags, mapp, &nmaps); | 337 | return -xfs_iomap(XFS_I(inode), offset, count, flags, mapp, &nmaps); |
| 381 | } | 338 | } |
| 382 | 339 | ||
| 383 | STATIC_INLINE int | 340 | STATIC int |
| 384 | xfs_iomap_valid( | 341 | xfs_iomap_valid( |
| 385 | xfs_iomap_t *iomapp, | 342 | xfs_iomap_t *iomapp, |
| 386 | loff_t offset) | 343 | loff_t offset) |
| @@ -412,8 +369,9 @@ xfs_end_bio( | |||
| 412 | 369 | ||
| 413 | STATIC void | 370 | STATIC void |
| 414 | xfs_submit_ioend_bio( | 371 | xfs_submit_ioend_bio( |
| 415 | xfs_ioend_t *ioend, | 372 | struct writeback_control *wbc, |
| 416 | struct bio *bio) | 373 | xfs_ioend_t *ioend, |
| 374 | struct bio *bio) | ||
| 417 | { | 375 | { |
| 418 | atomic_inc(&ioend->io_remaining); | 376 | atomic_inc(&ioend->io_remaining); |
| 419 | bio->bi_private = ioend; | 377 | bio->bi_private = ioend; |
| @@ -426,7 +384,8 @@ xfs_submit_ioend_bio( | |||
| 426 | if (xfs_ioend_new_eof(ioend)) | 384 | if (xfs_ioend_new_eof(ioend)) |
| 427 | xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); | 385 | xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode)); |
| 428 | 386 | ||
| 429 | submit_bio(WRITE, bio); | 387 | submit_bio(wbc->sync_mode == WB_SYNC_ALL ? |
| 388 | WRITE_SYNC_PLUG : WRITE, bio); | ||
| 430 | ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); | 389 | ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); |
| 431 | bio_put(bio); | 390 | bio_put(bio); |
| 432 | } | 391 | } |
| @@ -505,6 +464,7 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh) | |||
| 505 | */ | 464 | */ |
| 506 | STATIC void | 465 | STATIC void |
| 507 | xfs_submit_ioend( | 466 | xfs_submit_ioend( |
| 467 | struct writeback_control *wbc, | ||
| 508 | xfs_ioend_t *ioend) | 468 | xfs_ioend_t *ioend) |
| 509 | { | 469 | { |
| 510 | xfs_ioend_t *head = ioend; | 470 | xfs_ioend_t *head = ioend; |
| @@ -533,19 +493,19 @@ xfs_submit_ioend( | |||
| 533 | retry: | 493 | retry: |
| 534 | bio = xfs_alloc_ioend_bio(bh); | 494 | bio = xfs_alloc_ioend_bio(bh); |
| 535 | } else if (bh->b_blocknr != lastblock + 1) { | 495 | } else if (bh->b_blocknr != lastblock + 1) { |
| 536 | xfs_submit_ioend_bio(ioend, bio); | 496 | xfs_submit_ioend_bio(wbc, ioend, bio); |
| 537 | goto retry; | 497 | goto retry; |
| 538 | } | 498 | } |
| 539 | 499 | ||
| 540 | if (bio_add_buffer(bio, bh) != bh->b_size) { | 500 | if (bio_add_buffer(bio, bh) != bh->b_size) { |
| 541 | xfs_submit_ioend_bio(ioend, bio); | 501 | xfs_submit_ioend_bio(wbc, ioend, bio); |
| 542 | goto retry; | 502 | goto retry; |
| 543 | } | 503 | } |
| 544 | 504 | ||
| 545 | lastblock = bh->b_blocknr; | 505 | lastblock = bh->b_blocknr; |
| 546 | } | 506 | } |
| 547 | if (bio) | 507 | if (bio) |
| 548 | xfs_submit_ioend_bio(ioend, bio); | 508 | xfs_submit_ioend_bio(wbc, ioend, bio); |
| 549 | xfs_finish_ioend(ioend, 0); | 509 | xfs_finish_ioend(ioend, 0); |
| 550 | } while ((ioend = next) != NULL); | 510 | } while ((ioend = next) != NULL); |
| 551 | } | 511 | } |
| @@ -1191,7 +1151,7 @@ xfs_page_state_convert( | |||
| 1191 | } | 1151 | } |
| 1192 | 1152 | ||
| 1193 | if (iohead) | 1153 | if (iohead) |
| 1194 | xfs_submit_ioend(iohead); | 1154 | xfs_submit_ioend(wbc, iohead); |
| 1195 | 1155 | ||
| 1196 | return page_dirty; | 1156 | return page_dirty; |
| 1197 | 1157 | ||
| @@ -1528,7 +1488,7 @@ xfs_end_io_direct( | |||
| 1528 | * didn't map an unwritten extent so switch it's completion | 1488 | * didn't map an unwritten extent so switch it's completion |
| 1529 | * handler. | 1489 | * handler. |
| 1530 | */ | 1490 | */ |
| 1531 | INIT_WORK(&ioend->io_work, xfs_end_bio_written); | 1491 | ioend->io_type = IOMAP_NEW; |
| 1532 | xfs_finish_ioend(ioend, 0); | 1492 | xfs_finish_ioend(ioend, 0); |
| 1533 | } | 1493 | } |
| 1534 | 1494 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 965df1227d64..4ddc973aea7a 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
| @@ -149,7 +149,7 @@ page_region_mask( | |||
| 149 | return mask; | 149 | return mask; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | STATIC_INLINE void | 152 | STATIC void |
| 153 | set_page_region( | 153 | set_page_region( |
| 154 | struct page *page, | 154 | struct page *page, |
| 155 | size_t offset, | 155 | size_t offset, |
| @@ -161,7 +161,7 @@ set_page_region( | |||
| 161 | SetPageUptodate(page); | 161 | SetPageUptodate(page); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | STATIC_INLINE int | 164 | STATIC int |
| 165 | test_page_region( | 165 | test_page_region( |
| 166 | struct page *page, | 166 | struct page *page, |
| 167 | size_t offset, | 167 | size_t offset, |
| @@ -582,7 +582,7 @@ found: | |||
| 582 | * although backing storage may not be. | 582 | * although backing storage may not be. |
| 583 | */ | 583 | */ |
| 584 | xfs_buf_t * | 584 | xfs_buf_t * |
| 585 | xfs_buf_get_flags( | 585 | xfs_buf_get( |
| 586 | xfs_buftarg_t *target,/* target for buffer */ | 586 | xfs_buftarg_t *target,/* target for buffer */ |
| 587 | xfs_off_t ioff, /* starting offset of range */ | 587 | xfs_off_t ioff, /* starting offset of range */ |
| 588 | size_t isize, /* length of range */ | 588 | size_t isize, /* length of range */ |
| @@ -661,7 +661,7 @@ _xfs_buf_read( | |||
| 661 | } | 661 | } |
| 662 | 662 | ||
| 663 | xfs_buf_t * | 663 | xfs_buf_t * |
| 664 | xfs_buf_read_flags( | 664 | xfs_buf_read( |
| 665 | xfs_buftarg_t *target, | 665 | xfs_buftarg_t *target, |
| 666 | xfs_off_t ioff, | 666 | xfs_off_t ioff, |
| 667 | size_t isize, | 667 | size_t isize, |
| @@ -671,7 +671,7 @@ xfs_buf_read_flags( | |||
| 671 | 671 | ||
| 672 | flags |= XBF_READ; | 672 | flags |= XBF_READ; |
| 673 | 673 | ||
| 674 | bp = xfs_buf_get_flags(target, ioff, isize, flags); | 674 | bp = xfs_buf_get(target, ioff, isize, flags); |
| 675 | if (bp) { | 675 | if (bp) { |
| 676 | if (!XFS_BUF_ISDONE(bp)) { | 676 | if (!XFS_BUF_ISDONE(bp)) { |
| 677 | XB_TRACE(bp, "read", (unsigned long)flags); | 677 | XB_TRACE(bp, "read", (unsigned long)flags); |
| @@ -718,7 +718,7 @@ xfs_buf_readahead( | |||
| 718 | return; | 718 | return; |
| 719 | 719 | ||
| 720 | flags |= (XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD); | 720 | flags |= (XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD); |
| 721 | xfs_buf_read_flags(target, ioff, isize, flags); | 721 | xfs_buf_read(target, ioff, isize, flags); |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | xfs_buf_t * | 724 | xfs_buf_t * |
| @@ -1113,7 +1113,7 @@ xfs_bdwrite( | |||
| 1113 | xfs_buf_delwri_queue(bp, 1); | 1113 | xfs_buf_delwri_queue(bp, 1); |
| 1114 | } | 1114 | } |
| 1115 | 1115 | ||
| 1116 | STATIC_INLINE void | 1116 | STATIC void |
| 1117 | _xfs_buf_ioend( | 1117 | _xfs_buf_ioend( |
| 1118 | xfs_buf_t *bp, | 1118 | xfs_buf_t *bp, |
| 1119 | int schedule) | 1119 | int schedule) |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 9b4d666ad31f..5f07dd91c5fa 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
| @@ -186,15 +186,10 @@ extern xfs_buf_t *_xfs_buf_find(xfs_buftarg_t *, xfs_off_t, size_t, | |||
| 186 | #define xfs_incore(buftarg,blkno,len,lockit) \ | 186 | #define xfs_incore(buftarg,blkno,len,lockit) \ |
| 187 | _xfs_buf_find(buftarg, blkno ,len, lockit, NULL) | 187 | _xfs_buf_find(buftarg, blkno ,len, lockit, NULL) |
| 188 | 188 | ||
| 189 | extern xfs_buf_t *xfs_buf_get_flags(xfs_buftarg_t *, xfs_off_t, size_t, | 189 | extern xfs_buf_t *xfs_buf_get(xfs_buftarg_t *, xfs_off_t, size_t, |
| 190 | xfs_buf_flags_t); | 190 | xfs_buf_flags_t); |
| 191 | #define xfs_buf_get(target, blkno, len, flags) \ | 191 | extern xfs_buf_t *xfs_buf_read(xfs_buftarg_t *, xfs_off_t, size_t, |
| 192 | xfs_buf_get_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED) | ||
| 193 | |||
| 194 | extern xfs_buf_t *xfs_buf_read_flags(xfs_buftarg_t *, xfs_off_t, size_t, | ||
| 195 | xfs_buf_flags_t); | 192 | xfs_buf_flags_t); |
| 196 | #define xfs_buf_read(target, blkno, len, flags) \ | ||
| 197 | xfs_buf_read_flags((target), (blkno), (len), XBF_LOCK | XBF_MAPPED) | ||
| 198 | 193 | ||
| 199 | extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *); | 194 | extern xfs_buf_t *xfs_buf_get_empty(size_t, xfs_buftarg_t *); |
| 200 | extern xfs_buf_t *xfs_buf_get_noaddr(size_t, xfs_buftarg_t *); | 195 | extern xfs_buf_t *xfs_buf_get_noaddr(size_t, xfs_buftarg_t *); |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index eff61e2732af..e4caeb28ce2e 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -52,7 +52,7 @@ xfs_file_aio_read( | |||
| 52 | loff_t pos) | 52 | loff_t pos) |
| 53 | { | 53 | { |
| 54 | struct file *file = iocb->ki_filp; | 54 | struct file *file = iocb->ki_filp; |
| 55 | int ioflags = IO_ISAIO; | 55 | int ioflags = 0; |
| 56 | 56 | ||
| 57 | BUG_ON(iocb->ki_pos != pos); | 57 | BUG_ON(iocb->ki_pos != pos); |
| 58 | if (unlikely(file->f_flags & O_DIRECT)) | 58 | if (unlikely(file->f_flags & O_DIRECT)) |
| @@ -71,7 +71,7 @@ xfs_file_aio_write( | |||
| 71 | loff_t pos) | 71 | loff_t pos) |
| 72 | { | 72 | { |
| 73 | struct file *file = iocb->ki_filp; | 73 | struct file *file = iocb->ki_filp; |
| 74 | int ioflags = IO_ISAIO; | 74 | int ioflags = 0; |
| 75 | 75 | ||
| 76 | BUG_ON(iocb->ki_pos != pos); | 76 | BUG_ON(iocb->ki_pos != pos); |
| 77 | if (unlikely(file->f_flags & O_DIRECT)) | 77 | if (unlikely(file->f_flags & O_DIRECT)) |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index cd42ef78f6b5..1f3b4b8f7dd4 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -573,8 +573,8 @@ xfs_vn_fallocate( | |||
| 573 | bf.l_len = len; | 573 | bf.l_len = len; |
| 574 | 574 | ||
| 575 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 575 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
| 576 | error = xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, | 576 | error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf, |
| 577 | 0, XFS_ATTR_NOLOCK); | 577 | 0, XFS_ATTR_NOLOCK); |
| 578 | if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && | 578 | if (!error && !(mode & FALLOC_FL_KEEP_SIZE) && |
| 579 | offset + len > i_size_read(inode)) | 579 | offset + len > i_size_read(inode)) |
| 580 | new_size = offset + len; | 580 | new_size = offset + len; |
| @@ -585,7 +585,7 @@ xfs_vn_fallocate( | |||
| 585 | 585 | ||
| 586 | iattr.ia_valid = ATTR_SIZE; | 586 | iattr.ia_valid = ATTR_SIZE; |
| 587 | iattr.ia_size = new_size; | 587 | iattr.ia_size = new_size; |
| 588 | error = xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); | 588 | error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); |
| 589 | } | 589 | } |
| 590 | 590 | ||
| 591 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 591 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 072050f8d346..78dbfcd5eec2 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
| @@ -255,8 +255,6 @@ xfs_read( | |||
| 255 | 255 | ||
| 256 | iocb->ki_pos = *offset; | 256 | iocb->ki_pos = *offset; |
| 257 | ret = generic_file_aio_read(iocb, iovp, segs, *offset); | 257 | ret = generic_file_aio_read(iocb, iovp, segs, *offset); |
| 258 | if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO)) | ||
| 259 | ret = wait_on_sync_kiocb(iocb); | ||
| 260 | if (ret > 0) | 258 | if (ret > 0) |
| 261 | XFS_STATS_ADD(xs_read_bytes, ret); | 259 | XFS_STATS_ADD(xs_read_bytes, ret); |
| 262 | 260 | ||
| @@ -774,9 +772,6 @@ write_retry: | |||
| 774 | 772 | ||
| 775 | current->backing_dev_info = NULL; | 773 | current->backing_dev_info = NULL; |
| 776 | 774 | ||
| 777 | if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO)) | ||
| 778 | ret = wait_on_sync_kiocb(iocb); | ||
| 779 | |||
| 780 | isize = i_size_read(inode); | 775 | isize = i_size_read(inode); |
| 781 | if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize)) | 776 | if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize)) |
| 782 | *offset = isize; | 777 | *offset = isize; |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 18a4b8e11df2..1bfb0e980193 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -930,13 +930,39 @@ xfs_fs_alloc_inode( | |||
| 930 | */ | 930 | */ |
| 931 | STATIC void | 931 | STATIC void |
| 932 | xfs_fs_destroy_inode( | 932 | xfs_fs_destroy_inode( |
| 933 | struct inode *inode) | 933 | struct inode *inode) |
| 934 | { | 934 | { |
| 935 | xfs_inode_t *ip = XFS_I(inode); | 935 | struct xfs_inode *ip = XFS_I(inode); |
| 936 | |||
| 937 | xfs_itrace_entry(ip); | ||
| 936 | 938 | ||
| 937 | XFS_STATS_INC(vn_reclaim); | 939 | XFS_STATS_INC(vn_reclaim); |
| 938 | if (xfs_reclaim(ip)) | 940 | |
| 939 | panic("%s: cannot reclaim 0x%p\n", __func__, inode); | 941 | /* bad inode, get out here ASAP */ |
| 942 | if (is_bad_inode(inode)) | ||
| 943 | goto out_reclaim; | ||
| 944 | |||
| 945 | xfs_ioend_wait(ip); | ||
| 946 | |||
| 947 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | ||
| 948 | |||
| 949 | /* | ||
| 950 | * We should never get here with one of the reclaim flags already set. | ||
| 951 | */ | ||
| 952 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | ||
| 953 | ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); | ||
| 954 | |||
| 955 | /* | ||
| 956 | * If we have nothing to flush with this inode then complete the | ||
| 957 | * teardown now, otherwise delay the flush operation. | ||
| 958 | */ | ||
| 959 | if (!xfs_inode_clean(ip)) { | ||
| 960 | xfs_inode_set_reclaim_tag(ip); | ||
| 961 | return; | ||
| 962 | } | ||
| 963 | |||
| 964 | out_reclaim: | ||
| 965 | xfs_ireclaim(ip); | ||
| 940 | } | 966 | } |
| 941 | 967 | ||
| 942 | /* | 968 | /* |
| @@ -973,7 +999,6 @@ xfs_fs_inode_init_once( | |||
| 973 | 999 | ||
| 974 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | 1000 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, |
| 975 | "xfsino", ip->i_ino); | 1001 | "xfsino", ip->i_ino); |
| 976 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
| 977 | } | 1002 | } |
| 978 | 1003 | ||
| 979 | /* | 1004 | /* |
| @@ -1075,6 +1100,20 @@ xfs_fs_clear_inode( | |||
| 1075 | XFS_STATS_INC(vn_remove); | 1100 | XFS_STATS_INC(vn_remove); |
| 1076 | XFS_STATS_DEC(vn_active); | 1101 | XFS_STATS_DEC(vn_active); |
| 1077 | 1102 | ||
| 1103 | /* | ||
| 1104 | * The iolock is used by the file system to coordinate reads, | ||
| 1105 | * writes, and block truncates. Up to this point the lock | ||
| 1106 | * protected concurrent accesses by users of the inode. But | ||
| 1107 | * from here forward we're doing some final processing of the | ||
| 1108 | * inode because we're done with it, and although we reuse the | ||
| 1109 | * iolock for protection it is really a distinct lock class | ||
| 1110 | * (in the lockdep sense) from before. To keep lockdep happy | ||
| 1111 | * (and basically indicate what we are doing), we explicitly | ||
| 1112 | * re-init the iolock here. | ||
| 1113 | */ | ||
| 1114 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | ||
| 1115 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
| 1116 | |||
| 1078 | xfs_inactive(ip); | 1117 | xfs_inactive(ip); |
| 1079 | } | 1118 | } |
| 1080 | 1119 | ||
| @@ -1092,8 +1131,6 @@ xfs_fs_put_super( | |||
| 1092 | struct super_block *sb) | 1131 | struct super_block *sb) |
| 1093 | { | 1132 | { |
| 1094 | struct xfs_mount *mp = XFS_M(sb); | 1133 | struct xfs_mount *mp = XFS_M(sb); |
| 1095 | struct xfs_inode *rip = mp->m_rootip; | ||
| 1096 | int unmount_event_flags = 0; | ||
| 1097 | 1134 | ||
| 1098 | xfs_syncd_stop(mp); | 1135 | xfs_syncd_stop(mp); |
| 1099 | 1136 | ||
| @@ -1109,20 +1146,7 @@ xfs_fs_put_super( | |||
| 1109 | xfs_sync_attr(mp, 0); | 1146 | xfs_sync_attr(mp, 0); |
| 1110 | } | 1147 | } |
| 1111 | 1148 | ||
| 1112 | #ifdef HAVE_DMAPI | 1149 | XFS_SEND_PREUNMOUNT(mp); |
| 1113 | if (mp->m_flags & XFS_MOUNT_DMAPI) { | ||
| 1114 | unmount_event_flags = | ||
| 1115 | (mp->m_dmevmask & (1 << DM_EVENT_UNMOUNT)) ? | ||
| 1116 | 0 : DM_FLAGS_UNWANTED; | ||
| 1117 | /* | ||
| 1118 | * Ignore error from dmapi here, first unmount is not allowed | ||
| 1119 | * to fail anyway, and second we wouldn't want to fail a | ||
| 1120 | * unmount because of dmapi. | ||
| 1121 | */ | ||
| 1122 | XFS_SEND_PREUNMOUNT(mp, rip, DM_RIGHT_NULL, rip, DM_RIGHT_NULL, | ||
| 1123 | NULL, NULL, 0, 0, unmount_event_flags); | ||
| 1124 | } | ||
| 1125 | #endif | ||
| 1126 | 1150 | ||
| 1127 | /* | 1151 | /* |
| 1128 | * Blow away any referenced inode in the filestreams cache. | 1152 | * Blow away any referenced inode in the filestreams cache. |
| @@ -1133,10 +1157,7 @@ xfs_fs_put_super( | |||
| 1133 | 1157 | ||
| 1134 | XFS_bflush(mp->m_ddev_targp); | 1158 | XFS_bflush(mp->m_ddev_targp); |
| 1135 | 1159 | ||
| 1136 | if (mp->m_flags & XFS_MOUNT_DMAPI) { | 1160 | XFS_SEND_UNMOUNT(mp); |
| 1137 | XFS_SEND_UNMOUNT(mp, rip, DM_RIGHT_NULL, 0, 0, | ||
| 1138 | unmount_event_flags); | ||
| 1139 | } | ||
| 1140 | 1161 | ||
| 1141 | xfs_unmountfs(mp); | 1162 | xfs_unmountfs(mp); |
| 1142 | xfs_freesb(mp); | 1163 | xfs_freesb(mp); |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 961df0a22c78..d895a3a960f5 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
| @@ -663,10 +663,9 @@ xfs_syncd_stop( | |||
| 663 | kthread_stop(mp->m_sync_task); | 663 | kthread_stop(mp->m_sync_task); |
| 664 | } | 664 | } |
| 665 | 665 | ||
| 666 | int | 666 | STATIC int |
| 667 | xfs_reclaim_inode( | 667 | xfs_reclaim_inode( |
| 668 | xfs_inode_t *ip, | 668 | xfs_inode_t *ip, |
| 669 | int locked, | ||
| 670 | int sync_mode) | 669 | int sync_mode) |
| 671 | { | 670 | { |
| 672 | xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); | 671 | xfs_perag_t *pag = xfs_get_perag(ip->i_mount, ip->i_ino); |
| @@ -682,10 +681,6 @@ xfs_reclaim_inode( | |||
| 682 | !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) { | 681 | !__xfs_iflags_test(ip, XFS_IRECLAIMABLE)) { |
| 683 | spin_unlock(&ip->i_flags_lock); | 682 | spin_unlock(&ip->i_flags_lock); |
| 684 | write_unlock(&pag->pag_ici_lock); | 683 | write_unlock(&pag->pag_ici_lock); |
| 685 | if (locked) { | ||
| 686 | xfs_ifunlock(ip); | ||
| 687 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 688 | } | ||
| 689 | return -EAGAIN; | 684 | return -EAGAIN; |
| 690 | } | 685 | } |
| 691 | __xfs_iflags_set(ip, XFS_IRECLAIM); | 686 | __xfs_iflags_set(ip, XFS_IRECLAIM); |
| @@ -704,10 +699,8 @@ xfs_reclaim_inode( | |||
| 704 | * We get the flush lock regardless, though, just to make sure | 699 | * We get the flush lock regardless, though, just to make sure |
| 705 | * we don't free it while it is being flushed. | 700 | * we don't free it while it is being flushed. |
| 706 | */ | 701 | */ |
| 707 | if (!locked) { | 702 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| 708 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 703 | xfs_iflock(ip); |
| 709 | xfs_iflock(ip); | ||
| 710 | } | ||
| 711 | 704 | ||
| 712 | /* | 705 | /* |
| 713 | * In the case of a forced shutdown we rely on xfs_iflush() to | 706 | * In the case of a forced shutdown we rely on xfs_iflush() to |
| @@ -778,7 +771,7 @@ xfs_reclaim_inode_now( | |||
| 778 | } | 771 | } |
| 779 | read_unlock(&pag->pag_ici_lock); | 772 | read_unlock(&pag->pag_ici_lock); |
| 780 | 773 | ||
| 781 | return xfs_reclaim_inode(ip, 0, flags); | 774 | return xfs_reclaim_inode(ip, flags); |
| 782 | } | 775 | } |
| 783 | 776 | ||
| 784 | int | 777 | int |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index 27920eb7a820..a500b4d91835 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
| @@ -44,7 +44,6 @@ void xfs_quiesce_attr(struct xfs_mount *mp); | |||
| 44 | 44 | ||
| 45 | void xfs_flush_inodes(struct xfs_inode *ip); | 45 | void xfs_flush_inodes(struct xfs_inode *ip); |
| 46 | 46 | ||
| 47 | int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode); | ||
| 48 | int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); | 47 | int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); |
| 49 | 48 | ||
| 50 | void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); | 49 | void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index ad7fbead4c97..00cabf5354d2 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
| @@ -36,7 +36,6 @@ struct attrlist_cursor_kern; | |||
| 36 | /* | 36 | /* |
| 37 | * Flags for read/write calls - same values as IRIX | 37 | * Flags for read/write calls - same values as IRIX |
| 38 | */ | 38 | */ |
| 39 | #define IO_ISAIO 0x00001 /* don't wait for completion */ | ||
| 40 | #define IO_ISDIRECT 0x00004 /* bypass page cache */ | 39 | #define IO_ISDIRECT 0x00004 /* bypass page cache */ |
| 41 | #define IO_INVIS 0x00020 /* don't update inode timestamps */ | 40 | #define IO_INVIS 0x00020 /* don't update inode timestamps */ |
| 42 | 41 | ||
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h index 6f4fd37c67af..d2d20462fd4f 100644 --- a/fs/xfs/support/debug.h +++ b/fs/xfs/support/debug.h | |||
| @@ -41,10 +41,6 @@ extern void assfail(char *expr, char *f, int l); | |||
| 41 | # define STATIC static noinline | 41 | # define STATIC static noinline |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #ifndef STATIC_INLINE | ||
| 45 | # define STATIC_INLINE static inline | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #else /* DEBUG */ | 44 | #else /* DEBUG */ |
| 49 | 45 | ||
| 50 | #define ASSERT(expr) \ | 46 | #define ASSERT(expr) \ |
| @@ -54,19 +50,5 @@ extern void assfail(char *expr, char *f, int l); | |||
| 54 | # define STATIC noinline | 50 | # define STATIC noinline |
| 55 | #endif | 51 | #endif |
| 56 | 52 | ||
| 57 | /* | ||
| 58 | * We stop inlining of inline functions in debug mode. | ||
| 59 | * Unfortunately, this means static inline in header files | ||
| 60 | * get multiple definitions, so they need to remain static. | ||
| 61 | * This then gives tonnes of warnings about unused but defined | ||
| 62 | * functions, so we need to add the unused attribute to prevent | ||
| 63 | * these spurious warnings. | ||
| 64 | */ | ||
| 65 | #ifndef STATIC_INLINE | ||
| 66 | # define STATIC_INLINE static __attribute__ ((unused)) noinline | ||
| 67 | #endif | ||
| 68 | |||
| 69 | #endif /* DEBUG */ | 53 | #endif /* DEBUG */ |
| 70 | |||
| 71 | |||
| 72 | #endif /* __XFS_SUPPORT_DEBUG_H__ */ | 54 | #endif /* __XFS_SUPPORT_DEBUG_H__ */ |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 4ece1906bd41..8fe6f6b78a4a 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
| @@ -123,9 +123,13 @@ xfs_inode_hasattr( | |||
| 123 | * Overall external interface routines. | 123 | * Overall external interface routines. |
| 124 | *========================================================================*/ | 124 | *========================================================================*/ |
| 125 | 125 | ||
| 126 | int | 126 | STATIC int |
| 127 | xfs_attr_fetch(xfs_inode_t *ip, struct xfs_name *name, | 127 | xfs_attr_get_int( |
| 128 | char *value, int *valuelenp, int flags) | 128 | struct xfs_inode *ip, |
| 129 | struct xfs_name *name, | ||
| 130 | char *value, | ||
| 131 | int *valuelenp, | ||
| 132 | int flags) | ||
| 129 | { | 133 | { |
| 130 | xfs_da_args_t args; | 134 | xfs_da_args_t args; |
| 131 | int error; | 135 | int error; |
| @@ -188,7 +192,7 @@ xfs_attr_get( | |||
| 188 | return error; | 192 | return error; |
| 189 | 193 | ||
| 190 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 194 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
| 191 | error = xfs_attr_fetch(ip, &xname, value, valuelenp, flags); | 195 | error = xfs_attr_get_int(ip, &xname, value, valuelenp, flags); |
| 192 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 196 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
| 193 | return(error); | 197 | return(error); |
| 194 | } | 198 | } |
| @@ -2143,8 +2147,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) | |||
| 2143 | dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), | 2147 | dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock), |
| 2144 | blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); | 2148 | blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount); |
| 2145 | 2149 | ||
| 2146 | bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno, blkcnt, | 2150 | bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, |
| 2147 | XFS_BUF_LOCK | XBF_DONT_BLOCK); | 2151 | XFS_BUF_LOCK | XBF_DONT_BLOCK); |
| 2148 | ASSERT(bp); | 2152 | ASSERT(bp); |
| 2149 | ASSERT(!XFS_BUF_GETERROR(bp)); | 2153 | ASSERT(!XFS_BUF_GETERROR(bp)); |
| 2150 | 2154 | ||
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index fb3b2a68b9b9..12f0be3a73d4 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h | |||
| @@ -131,7 +131,6 @@ typedef struct xfs_attr_list_context { | |||
| 131 | */ | 131 | */ |
| 132 | int xfs_attr_calc_size(struct xfs_inode *, int, int, int *); | 132 | int xfs_attr_calc_size(struct xfs_inode *, int, int, int *); |
| 133 | int xfs_attr_inactive(struct xfs_inode *dp); | 133 | int xfs_attr_inactive(struct xfs_inode *dp); |
| 134 | int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); | ||
| 135 | int xfs_attr_rmtval_get(struct xfs_da_args *args); | 134 | int xfs_attr_rmtval_get(struct xfs_da_args *args); |
| 136 | int xfs_attr_list_int(struct xfs_attr_list_context *); | 135 | int xfs_attr_list_int(struct xfs_attr_list_context *); |
| 137 | 136 | ||
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index afdc8911637d..0b687351293f 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
| @@ -98,7 +98,7 @@ STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); | |||
| 98 | * If namespace bits don't match return 0. | 98 | * If namespace bits don't match return 0. |
| 99 | * If all match then return 1. | 99 | * If all match then return 1. |
| 100 | */ | 100 | */ |
| 101 | STATIC_INLINE int | 101 | STATIC int |
| 102 | xfs_attr_namesp_match(int arg_flags, int ondisk_flags) | 102 | xfs_attr_namesp_match(int arg_flags, int ondisk_flags) |
| 103 | { | 103 | { |
| 104 | return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); | 104 | return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index eb7b702d0690..6f5ccede63f9 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
| @@ -98,8 +98,7 @@ xfs_bmdr_to_bmbt( | |||
| 98 | * This code must be in sync with the routines xfs_bmbt_get_startoff, | 98 | * This code must be in sync with the routines xfs_bmbt_get_startoff, |
| 99 | * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. | 99 | * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. |
| 100 | */ | 100 | */ |
| 101 | 101 | STATIC void | |
| 102 | STATIC_INLINE void | ||
| 103 | __xfs_bmbt_get_all( | 102 | __xfs_bmbt_get_all( |
| 104 | __uint64_t l0, | 103 | __uint64_t l0, |
| 105 | __uint64_t l1, | 104 | __uint64_t l1, |
diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h index f655f7dc334c..4aba67c5f64f 100644 --- a/fs/xfs/xfs_filestream.h +++ b/fs/xfs/xfs_filestream.h | |||
| @@ -79,7 +79,7 @@ extern ktrace_t *xfs_filestreams_trace_buf; | |||
| 79 | * the cache that reference per-ag array elements that have since been | 79 | * the cache that reference per-ag array elements that have since been |
| 80 | * reallocated. | 80 | * reallocated. |
| 81 | */ | 81 | */ |
| 82 | STATIC_INLINE int | 82 | static inline int |
| 83 | xfs_filestream_peek_ag( | 83 | xfs_filestream_peek_ag( |
| 84 | xfs_mount_t *mp, | 84 | xfs_mount_t *mp, |
| 85 | xfs_agnumber_t agno) | 85 | xfs_agnumber_t agno) |
| @@ -87,7 +87,7 @@ xfs_filestream_peek_ag( | |||
| 87 | return atomic_read(&mp->m_perag[agno].pagf_fstrms); | 87 | return atomic_read(&mp->m_perag[agno].pagf_fstrms); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | STATIC_INLINE int | 90 | static inline int |
| 91 | xfs_filestream_get_ag( | 91 | xfs_filestream_get_ag( |
| 92 | xfs_mount_t *mp, | 92 | xfs_mount_t *mp, |
| 93 | xfs_agnumber_t agno) | 93 | xfs_agnumber_t agno) |
| @@ -95,7 +95,7 @@ xfs_filestream_get_ag( | |||
| 95 | return atomic_inc_return(&mp->m_perag[agno].pagf_fstrms); | 95 | return atomic_inc_return(&mp->m_perag[agno].pagf_fstrms); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | STATIC_INLINE int | 98 | static inline int |
| 99 | xfs_filestream_put_ag( | 99 | xfs_filestream_put_ag( |
| 100 | xfs_mount_t *mp, | 100 | xfs_mount_t *mp, |
| 101 | xfs_agnumber_t agno) | 101 | xfs_agnumber_t agno) |
| @@ -122,7 +122,7 @@ int xfs_filestream_new_ag(struct xfs_bmalloca *ap, xfs_agnumber_t *agp); | |||
| 122 | 122 | ||
| 123 | 123 | ||
| 124 | /* filestreams for the inode? */ | 124 | /* filestreams for the inode? */ |
| 125 | STATIC_INLINE int | 125 | static inline int |
| 126 | xfs_inode_is_filestream( | 126 | xfs_inode_is_filestream( |
| 127 | struct xfs_inode *ip) | 127 | struct xfs_inode *ip) |
| 128 | { | 128 | { |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 2d0b3e1da9e6..36079aa91344 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
| @@ -201,8 +201,8 @@ xfs_growfs_data_private( | |||
| 201 | * AG freelist header block | 201 | * AG freelist header block |
| 202 | */ | 202 | */ |
| 203 | bp = xfs_buf_get(mp->m_ddev_targp, | 203 | bp = xfs_buf_get(mp->m_ddev_targp, |
| 204 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), | 204 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), |
| 205 | XFS_FSS_TO_BB(mp, 1), 0); | 205 | XFS_FSS_TO_BB(mp, 1), XBF_LOCK | XBF_MAPPED); |
| 206 | agf = XFS_BUF_TO_AGF(bp); | 206 | agf = XFS_BUF_TO_AGF(bp); |
| 207 | memset(agf, 0, mp->m_sb.sb_sectsize); | 207 | memset(agf, 0, mp->m_sb.sb_sectsize); |
| 208 | agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); | 208 | agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); |
| @@ -233,8 +233,8 @@ xfs_growfs_data_private( | |||
| 233 | * AG inode header block | 233 | * AG inode header block |
| 234 | */ | 234 | */ |
| 235 | bp = xfs_buf_get(mp->m_ddev_targp, | 235 | bp = xfs_buf_get(mp->m_ddev_targp, |
| 236 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), | 236 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), |
| 237 | XFS_FSS_TO_BB(mp, 1), 0); | 237 | XFS_FSS_TO_BB(mp, 1), XBF_LOCK | XBF_MAPPED); |
| 238 | agi = XFS_BUF_TO_AGI(bp); | 238 | agi = XFS_BUF_TO_AGI(bp); |
| 239 | memset(agi, 0, mp->m_sb.sb_sectsize); | 239 | memset(agi, 0, mp->m_sb.sb_sectsize); |
| 240 | agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); | 240 | agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); |
| @@ -257,8 +257,9 @@ xfs_growfs_data_private( | |||
| 257 | * BNO btree root block | 257 | * BNO btree root block |
| 258 | */ | 258 | */ |
| 259 | bp = xfs_buf_get(mp->m_ddev_targp, | 259 | bp = xfs_buf_get(mp->m_ddev_targp, |
| 260 | XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), | 260 | XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), |
| 261 | BTOBB(mp->m_sb.sb_blocksize), 0); | 261 | BTOBB(mp->m_sb.sb_blocksize), |
| 262 | XBF_LOCK | XBF_MAPPED); | ||
| 262 | block = XFS_BUF_TO_BLOCK(bp); | 263 | block = XFS_BUF_TO_BLOCK(bp); |
| 263 | memset(block, 0, mp->m_sb.sb_blocksize); | 264 | memset(block, 0, mp->m_sb.sb_blocksize); |
| 264 | block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC); | 265 | block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC); |
| @@ -278,8 +279,9 @@ xfs_growfs_data_private( | |||
| 278 | * CNT btree root block | 279 | * CNT btree root block |
| 279 | */ | 280 | */ |
| 280 | bp = xfs_buf_get(mp->m_ddev_targp, | 281 | bp = xfs_buf_get(mp->m_ddev_targp, |
| 281 | XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), | 282 | XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), |
| 282 | BTOBB(mp->m_sb.sb_blocksize), 0); | 283 | BTOBB(mp->m_sb.sb_blocksize), |
| 284 | XBF_LOCK | XBF_MAPPED); | ||
| 283 | block = XFS_BUF_TO_BLOCK(bp); | 285 | block = XFS_BUF_TO_BLOCK(bp); |
| 284 | memset(block, 0, mp->m_sb.sb_blocksize); | 286 | memset(block, 0, mp->m_sb.sb_blocksize); |
| 285 | block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC); | 287 | block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC); |
| @@ -300,8 +302,9 @@ xfs_growfs_data_private( | |||
| 300 | * INO btree root block | 302 | * INO btree root block |
| 301 | */ | 303 | */ |
| 302 | bp = xfs_buf_get(mp->m_ddev_targp, | 304 | bp = xfs_buf_get(mp->m_ddev_targp, |
| 303 | XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), | 305 | XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), |
| 304 | BTOBB(mp->m_sb.sb_blocksize), 0); | 306 | BTOBB(mp->m_sb.sb_blocksize), |
| 307 | XBF_LOCK | XBF_MAPPED); | ||
| 305 | block = XFS_BUF_TO_BLOCK(bp); | 308 | block = XFS_BUF_TO_BLOCK(bp); |
| 306 | memset(block, 0, mp->m_sb.sb_blocksize); | 309 | memset(block, 0, mp->m_sb.sb_blocksize); |
| 307 | block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); | 310 | block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC); |
| @@ -611,7 +614,7 @@ xfs_fs_log_dummy( | |||
| 611 | xfs_inode_t *ip; | 614 | xfs_inode_t *ip; |
| 612 | int error; | 615 | int error; |
| 613 | 616 | ||
| 614 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); | 617 | tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); |
| 615 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); | 618 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); |
| 616 | if (error) { | 619 | if (error) { |
| 617 | xfs_trans_cancel(tp, 0); | 620 | xfs_trans_cancel(tp, 0); |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 0785797db828..cb907ba69c4c 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
| @@ -425,7 +425,7 @@ xfs_ialloc_ag_alloc( | |||
| 425 | return 0; | 425 | return 0; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | STATIC_INLINE xfs_agnumber_t | 428 | STATIC xfs_agnumber_t |
| 429 | xfs_ialloc_next_ag( | 429 | xfs_ialloc_next_ag( |
| 430 | xfs_mount_t *mp) | 430 | xfs_mount_t *mp) |
| 431 | { | 431 | { |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 80e526489be5..073bb4a26b19 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -73,6 +73,9 @@ xfs_inode_alloc( | |||
| 73 | ASSERT(atomic_read(&ip->i_pincount) == 0); | 73 | ASSERT(atomic_read(&ip->i_pincount) == 0); |
| 74 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | 74 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); |
| 75 | ASSERT(completion_done(&ip->i_flush)); | 75 | ASSERT(completion_done(&ip->i_flush)); |
| 76 | ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); | ||
| 77 | |||
| 78 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
| 76 | 79 | ||
| 77 | /* initialise the xfs inode */ | 80 | /* initialise the xfs inode */ |
| 78 | ip->i_ino = ino; | 81 | ip->i_ino = ino; |
| @@ -290,7 +293,7 @@ xfs_iget_cache_miss( | |||
| 290 | struct xfs_inode **ipp, | 293 | struct xfs_inode **ipp, |
| 291 | xfs_daddr_t bno, | 294 | xfs_daddr_t bno, |
| 292 | int flags, | 295 | int flags, |
| 293 | int lock_flags) __releases(pag->pag_ici_lock) | 296 | int lock_flags) |
| 294 | { | 297 | { |
| 295 | struct xfs_inode *ip; | 298 | struct xfs_inode *ip; |
| 296 | int error; | 299 | int error; |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 67ae5555a30a..7294abce6ef2 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
| @@ -860,8 +860,15 @@ xfs_iomap_write_unwritten( | |||
| 860 | * set up a transaction to convert the range of extents | 860 | * set up a transaction to convert the range of extents |
| 861 | * from unwritten to real. Do allocations in a loop until | 861 | * from unwritten to real. Do allocations in a loop until |
| 862 | * we have covered the range passed in. | 862 | * we have covered the range passed in. |
| 863 | * | ||
| 864 | * Note that we open code the transaction allocation here | ||
| 865 | * to pass KM_NOFS--we can't risk to recursing back into | ||
| 866 | * the filesystem here as we might be asked to write out | ||
| 867 | * the same inode that we complete here and might deadlock | ||
| 868 | * on the iolock. | ||
| 863 | */ | 869 | */ |
| 864 | tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); | 870 | xfs_wait_for_freeze(mp, SB_FREEZE_TRANS); |
| 871 | tp = _xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE, KM_NOFS); | ||
| 865 | tp->t_flags |= XFS_TRANS_RESERVE; | 872 | tp->t_flags |= XFS_TRANS_RESERVE; |
| 866 | error = xfs_trans_reserve(tp, resblks, | 873 | error = xfs_trans_reserve(tp, resblks, |
| 867 | XFS_WRITE_LOG_RES(mp), 0, | 874 | XFS_WRITE_LOG_RES(mp), 0, |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index fb17f8226b09..1ec98ed914d4 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -2206,6 +2206,7 @@ xlog_recover_do_buffer_trans( | |||
| 2206 | xfs_daddr_t blkno; | 2206 | xfs_daddr_t blkno; |
| 2207 | int len; | 2207 | int len; |
| 2208 | ushort flags; | 2208 | ushort flags; |
| 2209 | uint buf_flags; | ||
| 2209 | 2210 | ||
| 2210 | buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr; | 2211 | buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr; |
| 2211 | 2212 | ||
| @@ -2246,12 +2247,11 @@ xlog_recover_do_buffer_trans( | |||
| 2246 | } | 2247 | } |
| 2247 | 2248 | ||
| 2248 | mp = log->l_mp; | 2249 | mp = log->l_mp; |
| 2249 | if (flags & XFS_BLI_INODE_BUF) { | 2250 | buf_flags = XFS_BUF_LOCK; |
| 2250 | bp = xfs_buf_read_flags(mp->m_ddev_targp, blkno, len, | 2251 | if (!(flags & XFS_BLI_INODE_BUF)) |
| 2251 | XFS_BUF_LOCK); | 2252 | buf_flags |= XFS_BUF_MAPPED; |
| 2252 | } else { | 2253 | |
| 2253 | bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, 0); | 2254 | bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags); |
| 2254 | } | ||
| 2255 | if (XFS_BUF_ISERROR(bp)) { | 2255 | if (XFS_BUF_ISERROR(bp)) { |
| 2256 | xfs_ioerror_alert("xlog_recover_do..(read#1)", log->l_mp, | 2256 | xfs_ioerror_alert("xlog_recover_do..(read#1)", log->l_mp, |
| 2257 | bp, blkno); | 2257 | bp, blkno); |
| @@ -2350,8 +2350,8 @@ xlog_recover_do_inode_trans( | |||
| 2350 | goto error; | 2350 | goto error; |
| 2351 | } | 2351 | } |
| 2352 | 2352 | ||
| 2353 | bp = xfs_buf_read_flags(mp->m_ddev_targp, in_f->ilf_blkno, | 2353 | bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, |
| 2354 | in_f->ilf_len, XFS_BUF_LOCK); | 2354 | XFS_BUF_LOCK); |
| 2355 | if (XFS_BUF_ISERROR(bp)) { | 2355 | if (XFS_BUF_ISERROR(bp)) { |
| 2356 | xfs_ioerror_alert("xlog_recover_do..(read#2)", mp, | 2356 | xfs_ioerror_alert("xlog_recover_do..(read#2)", mp, |
| 2357 | bp, in_f->ilf_blkno); | 2357 | bp, in_f->ilf_blkno); |
| @@ -3517,7 +3517,7 @@ xlog_do_recovery_pass( | |||
| 3517 | { | 3517 | { |
| 3518 | xlog_rec_header_t *rhead; | 3518 | xlog_rec_header_t *rhead; |
| 3519 | xfs_daddr_t blk_no; | 3519 | xfs_daddr_t blk_no; |
| 3520 | xfs_caddr_t bufaddr, offset; | 3520 | xfs_caddr_t offset; |
| 3521 | xfs_buf_t *hbp, *dbp; | 3521 | xfs_buf_t *hbp, *dbp; |
| 3522 | int error = 0, h_size; | 3522 | int error = 0, h_size; |
| 3523 | int bblks, split_bblks; | 3523 | int bblks, split_bblks; |
| @@ -3610,7 +3610,7 @@ xlog_do_recovery_pass( | |||
| 3610 | /* | 3610 | /* |
| 3611 | * Check for header wrapping around physical end-of-log | 3611 | * Check for header wrapping around physical end-of-log |
| 3612 | */ | 3612 | */ |
| 3613 | offset = NULL; | 3613 | offset = XFS_BUF_PTR(hbp); |
| 3614 | split_hblks = 0; | 3614 | split_hblks = 0; |
| 3615 | wrapped_hblks = 0; | 3615 | wrapped_hblks = 0; |
| 3616 | if (blk_no + hblks <= log->l_logBBsize) { | 3616 | if (blk_no + hblks <= log->l_logBBsize) { |
| @@ -3646,9 +3646,8 @@ xlog_do_recovery_pass( | |||
| 3646 | * - order is important. | 3646 | * - order is important. |
| 3647 | */ | 3647 | */ |
| 3648 | wrapped_hblks = hblks - split_hblks; | 3648 | wrapped_hblks = hblks - split_hblks; |
| 3649 | bufaddr = XFS_BUF_PTR(hbp); | ||
| 3650 | error = XFS_BUF_SET_PTR(hbp, | 3649 | error = XFS_BUF_SET_PTR(hbp, |
| 3651 | bufaddr + BBTOB(split_hblks), | 3650 | offset + BBTOB(split_hblks), |
| 3652 | BBTOB(hblks - split_hblks)); | 3651 | BBTOB(hblks - split_hblks)); |
| 3653 | if (error) | 3652 | if (error) |
| 3654 | goto bread_err2; | 3653 | goto bread_err2; |
| @@ -3658,14 +3657,10 @@ xlog_do_recovery_pass( | |||
| 3658 | if (error) | 3657 | if (error) |
| 3659 | goto bread_err2; | 3658 | goto bread_err2; |
| 3660 | 3659 | ||
| 3661 | error = XFS_BUF_SET_PTR(hbp, bufaddr, | 3660 | error = XFS_BUF_SET_PTR(hbp, offset, |
| 3662 | BBTOB(hblks)); | 3661 | BBTOB(hblks)); |
| 3663 | if (error) | 3662 | if (error) |
| 3664 | goto bread_err2; | 3663 | goto bread_err2; |
| 3665 | |||
| 3666 | if (!offset) | ||
| 3667 | offset = xlog_align(log, 0, | ||
| 3668 | wrapped_hblks, hbp); | ||
| 3669 | } | 3664 | } |
| 3670 | rhead = (xlog_rec_header_t *)offset; | 3665 | rhead = (xlog_rec_header_t *)offset; |
| 3671 | error = xlog_valid_rec_header(log, rhead, | 3666 | error = xlog_valid_rec_header(log, rhead, |
| @@ -3685,7 +3680,7 @@ xlog_do_recovery_pass( | |||
| 3685 | } else { | 3680 | } else { |
| 3686 | /* This log record is split across the | 3681 | /* This log record is split across the |
| 3687 | * physical end of log */ | 3682 | * physical end of log */ |
| 3688 | offset = NULL; | 3683 | offset = XFS_BUF_PTR(dbp); |
| 3689 | split_bblks = 0; | 3684 | split_bblks = 0; |
| 3690 | if (blk_no != log->l_logBBsize) { | 3685 | if (blk_no != log->l_logBBsize) { |
| 3691 | /* some data is before the physical | 3686 | /* some data is before the physical |
| @@ -3714,9 +3709,8 @@ xlog_do_recovery_pass( | |||
| 3714 | * _first_, then the log start (LR header end) | 3709 | * _first_, then the log start (LR header end) |
| 3715 | * - order is important. | 3710 | * - order is important. |
| 3716 | */ | 3711 | */ |
| 3717 | bufaddr = XFS_BUF_PTR(dbp); | ||
| 3718 | error = XFS_BUF_SET_PTR(dbp, | 3712 | error = XFS_BUF_SET_PTR(dbp, |
| 3719 | bufaddr + BBTOB(split_bblks), | 3713 | offset + BBTOB(split_bblks), |
| 3720 | BBTOB(bblks - split_bblks)); | 3714 | BBTOB(bblks - split_bblks)); |
| 3721 | if (error) | 3715 | if (error) |
| 3722 | goto bread_err2; | 3716 | goto bread_err2; |
| @@ -3727,13 +3721,9 @@ xlog_do_recovery_pass( | |||
| 3727 | if (error) | 3721 | if (error) |
| 3728 | goto bread_err2; | 3722 | goto bread_err2; |
| 3729 | 3723 | ||
| 3730 | error = XFS_BUF_SET_PTR(dbp, bufaddr, h_size); | 3724 | error = XFS_BUF_SET_PTR(dbp, offset, h_size); |
| 3731 | if (error) | 3725 | if (error) |
| 3732 | goto bread_err2; | 3726 | goto bread_err2; |
| 3733 | |||
| 3734 | if (!offset) | ||
| 3735 | offset = xlog_align(log, wrapped_hblks, | ||
| 3736 | bblks - split_bblks, dbp); | ||
| 3737 | } | 3727 | } |
| 3738 | xlog_unpack_data(rhead, offset, log); | 3728 | xlog_unpack_data(rhead, offset, log); |
| 3739 | if ((error = xlog_recover_process_data(log, rhash, | 3729 | if ((error = xlog_recover_process_data(log, rhash, |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 8b6c9e807efb..66a888a9ad6f 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
| @@ -583,8 +583,8 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
| 583 | sector_size = xfs_getsize_buftarg(mp->m_ddev_targp); | 583 | sector_size = xfs_getsize_buftarg(mp->m_ddev_targp); |
| 584 | extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED; | 584 | extra_flags = XFS_BUF_LOCK | XFS_BUF_MANAGE | XFS_BUF_MAPPED; |
| 585 | 585 | ||
| 586 | bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR, | 586 | bp = xfs_buf_read(mp->m_ddev_targp, XFS_SB_DADDR, BTOBB(sector_size), |
| 587 | BTOBB(sector_size), extra_flags); | 587 | extra_flags); |
| 588 | if (!bp || XFS_BUF_ISERROR(bp)) { | 588 | if (!bp || XFS_BUF_ISERROR(bp)) { |
| 589 | xfs_fs_mount_cmn_err(flags, "SB read failed"); | 589 | xfs_fs_mount_cmn_err(flags, "SB read failed"); |
| 590 | error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; | 590 | error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; |
| @@ -624,8 +624,8 @@ xfs_readsb(xfs_mount_t *mp, int flags) | |||
| 624 | XFS_BUF_UNMANAGE(bp); | 624 | XFS_BUF_UNMANAGE(bp); |
| 625 | xfs_buf_relse(bp); | 625 | xfs_buf_relse(bp); |
| 626 | sector_size = mp->m_sb.sb_sectsize; | 626 | sector_size = mp->m_sb.sb_sectsize; |
| 627 | bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR, | 627 | bp = xfs_buf_read(mp->m_ddev_targp, XFS_SB_DADDR, |
| 628 | BTOBB(sector_size), extra_flags); | 628 | BTOBB(sector_size), extra_flags); |
| 629 | if (!bp || XFS_BUF_ISERROR(bp)) { | 629 | if (!bp || XFS_BUF_ISERROR(bp)) { |
| 630 | xfs_fs_mount_cmn_err(flags, "SB re-read failed"); | 630 | xfs_fs_mount_cmn_err(flags, "SB re-read failed"); |
| 631 | error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; | 631 | error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; |
| @@ -1471,7 +1471,7 @@ xfs_log_sbcount( | |||
| 1471 | if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) | 1471 | if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) |
| 1472 | return 0; | 1472 | return 0; |
| 1473 | 1473 | ||
| 1474 | tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT); | 1474 | tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP); |
| 1475 | error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, | 1475 | error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, |
| 1476 | XFS_DEFAULT_LOG_COUNT); | 1476 | XFS_DEFAULT_LOG_COUNT); |
| 1477 | if (error) { | 1477 | if (error) { |
| @@ -2123,7 +2123,7 @@ xfs_icsb_destroy_counters( | |||
| 2123 | mutex_destroy(&mp->m_icsb_mutex); | 2123 | mutex_destroy(&mp->m_icsb_mutex); |
| 2124 | } | 2124 | } |
| 2125 | 2125 | ||
| 2126 | STATIC_INLINE void | 2126 | STATIC void |
| 2127 | xfs_icsb_lock_cntr( | 2127 | xfs_icsb_lock_cntr( |
| 2128 | xfs_icsb_cnts_t *icsbp) | 2128 | xfs_icsb_cnts_t *icsbp) |
| 2129 | { | 2129 | { |
| @@ -2132,7 +2132,7 @@ xfs_icsb_lock_cntr( | |||
| 2132 | } | 2132 | } |
| 2133 | } | 2133 | } |
| 2134 | 2134 | ||
| 2135 | STATIC_INLINE void | 2135 | STATIC void |
| 2136 | xfs_icsb_unlock_cntr( | 2136 | xfs_icsb_unlock_cntr( |
| 2137 | xfs_icsb_cnts_t *icsbp) | 2137 | xfs_icsb_cnts_t *icsbp) |
| 2138 | { | 2138 | { |
| @@ -2140,7 +2140,7 @@ xfs_icsb_unlock_cntr( | |||
| 2140 | } | 2140 | } |
| 2141 | 2141 | ||
| 2142 | 2142 | ||
| 2143 | STATIC_INLINE void | 2143 | STATIC void |
| 2144 | xfs_icsb_lock_all_counters( | 2144 | xfs_icsb_lock_all_counters( |
| 2145 | xfs_mount_t *mp) | 2145 | xfs_mount_t *mp) |
| 2146 | { | 2146 | { |
| @@ -2153,7 +2153,7 @@ xfs_icsb_lock_all_counters( | |||
| 2153 | } | 2153 | } |
| 2154 | } | 2154 | } |
| 2155 | 2155 | ||
| 2156 | STATIC_INLINE void | 2156 | STATIC void |
| 2157 | xfs_icsb_unlock_all_counters( | 2157 | xfs_icsb_unlock_all_counters( |
| 2158 | xfs_mount_t *mp) | 2158 | xfs_mount_t *mp) |
| 2159 | { | 2159 | { |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index a6c023bc0fb2..1df7e4502967 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
| @@ -93,6 +93,9 @@ typedef struct xfs_dmops { | |||
| 93 | xfs_send_unmount_t xfs_send_unmount; | 93 | xfs_send_unmount_t xfs_send_unmount; |
| 94 | } xfs_dmops_t; | 94 | } xfs_dmops_t; |
| 95 | 95 | ||
| 96 | #define XFS_DMAPI_UNMOUNT_FLAGS(mp) \ | ||
| 97 | (((mp)->m_dmevmask & (1 << DM_EVENT_UNMOUNT)) ? 0 : DM_FLAGS_UNWANTED) | ||
| 98 | |||
| 96 | #define XFS_SEND_DATA(mp, ev,ip,off,len,fl,lock) \ | 99 | #define XFS_SEND_DATA(mp, ev,ip,off,len,fl,lock) \ |
| 97 | (*(mp)->m_dm_ops->xfs_send_data)(ev,ip,off,len,fl,lock) | 100 | (*(mp)->m_dm_ops->xfs_send_data)(ev,ip,off,len,fl,lock) |
| 98 | #define XFS_SEND_MMAP(mp, vma,fl) \ | 101 | #define XFS_SEND_MMAP(mp, vma,fl) \ |
| @@ -101,12 +104,24 @@ typedef struct xfs_dmops { | |||
| 101 | (*(mp)->m_dm_ops->xfs_send_destroy)(ip,right) | 104 | (*(mp)->m_dm_ops->xfs_send_destroy)(ip,right) |
| 102 | #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ | 105 | #define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ |
| 103 | (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) | 106 | (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl) |
| 104 | #define XFS_SEND_PREUNMOUNT(mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) \ | ||
| 105 | (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT,mp,b1,r1,b2,r2,n1,n2,mode,rval,fl) | ||
| 106 | #define XFS_SEND_MOUNT(mp,right,path,name) \ | 107 | #define XFS_SEND_MOUNT(mp,right,path,name) \ |
| 107 | (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name) | 108 | (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name) |
| 108 | #define XFS_SEND_UNMOUNT(mp, ip,right,mode,rval,fl) \ | 109 | #define XFS_SEND_PREUNMOUNT(mp) \ |
| 109 | (*(mp)->m_dm_ops->xfs_send_unmount)(mp,ip,right,mode,rval,fl) | 110 | do { \ |
| 111 | if (mp->m_flags & XFS_MOUNT_DMAPI) { \ | ||
| 112 | (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT, mp, \ | ||
| 113 | (mp)->m_rootip, DM_RIGHT_NULL, \ | ||
| 114 | (mp)->m_rootip, DM_RIGHT_NULL, \ | ||
| 115 | NULL, NULL, 0, 0, XFS_DMAPI_UNMOUNT_FLAGS(mp)); \ | ||
| 116 | } \ | ||
| 117 | } while (0) | ||
| 118 | #define XFS_SEND_UNMOUNT(mp) \ | ||
| 119 | do { \ | ||
| 120 | if (mp->m_flags & XFS_MOUNT_DMAPI) { \ | ||
| 121 | (*(mp)->m_dm_ops->xfs_send_unmount)(mp, (mp)->m_rootip, \ | ||
| 122 | DM_RIGHT_NULL, 0, 0, XFS_DMAPI_UNMOUNT_FLAGS(mp)); \ | ||
| 123 | } \ | ||
| 124 | } while (0) | ||
| 110 | 125 | ||
| 111 | 126 | ||
| 112 | #ifdef HAVE_PERCPU_SB | 127 | #ifdef HAVE_PERCPU_SB |
| @@ -387,13 +402,13 @@ xfs_put_perag(struct xfs_mount *mp, xfs_perag_t *pag) | |||
| 387 | * Per-cpu superblock locking functions | 402 | * Per-cpu superblock locking functions |
| 388 | */ | 403 | */ |
| 389 | #ifdef HAVE_PERCPU_SB | 404 | #ifdef HAVE_PERCPU_SB |
| 390 | STATIC_INLINE void | 405 | static inline void |
| 391 | xfs_icsb_lock(xfs_mount_t *mp) | 406 | xfs_icsb_lock(xfs_mount_t *mp) |
| 392 | { | 407 | { |
| 393 | mutex_lock(&mp->m_icsb_mutex); | 408 | mutex_lock(&mp->m_icsb_mutex); |
| 394 | } | 409 | } |
| 395 | 410 | ||
| 396 | STATIC_INLINE void | 411 | static inline void |
| 397 | xfs_icsb_unlock(xfs_mount_t *mp) | 412 | xfs_icsb_unlock(xfs_mount_t *mp) |
| 398 | { | 413 | { |
| 399 | mutex_unlock(&mp->m_icsb_mutex); | 414 | mutex_unlock(&mp->m_icsb_mutex); |
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index 3f816ad7ff19..4c199d18f850 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.c | |||
| @@ -277,10 +277,10 @@ xfs_read_buf( | |||
| 277 | xfs_buf_t *bp; | 277 | xfs_buf_t *bp; |
| 278 | int error; | 278 | int error; |
| 279 | 279 | ||
| 280 | if (flags) | 280 | if (!flags) |
| 281 | bp = xfs_buf_read_flags(target, blkno, len, flags); | 281 | flags = XBF_LOCK | XBF_MAPPED; |
| 282 | else | 282 | |
| 283 | bp = xfs_buf_read(target, blkno, len, flags); | 283 | bp = xfs_buf_read(target, blkno, len, flags); |
| 284 | if (!bp) | 284 | if (!bp) |
| 285 | return XFS_ERROR(EIO); | 285 | return XFS_ERROR(EIO); |
| 286 | error = XFS_BUF_GETERROR(bp); | 286 | error = XFS_BUF_GETERROR(bp); |
| @@ -336,3 +336,25 @@ xfs_bwrite( | |||
| 336 | } | 336 | } |
| 337 | return (error); | 337 | return (error); |
| 338 | } | 338 | } |
| 339 | |||
| 340 | /* | ||
| 341 | * helper function to extract extent size hint from inode | ||
| 342 | */ | ||
| 343 | xfs_extlen_t | ||
| 344 | xfs_get_extsz_hint( | ||
| 345 | struct xfs_inode *ip) | ||
| 346 | { | ||
| 347 | xfs_extlen_t extsz; | ||
| 348 | |||
| 349 | if (unlikely(XFS_IS_REALTIME_INODE(ip))) { | ||
| 350 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
| 351 | ? ip->i_d.di_extsize | ||
| 352 | : ip->i_mount->m_sb.sb_rextsize; | ||
| 353 | ASSERT(extsz); | ||
| 354 | } else { | ||
| 355 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
| 356 | ? ip->i_d.di_extsize : 0; | ||
| 357 | } | ||
| 358 | |||
| 359 | return extsz; | ||
| 360 | } | ||
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index f5e4874c37d8..571f2174435c 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h | |||
| @@ -37,34 +37,6 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | /* | 39 | /* |
| 40 | * Flags for xfs_free_eofblocks | ||
| 41 | */ | ||
| 42 | #define XFS_FREE_EOF_LOCK (1<<0) | ||
| 43 | #define XFS_FREE_EOF_NOLOCK (1<<1) | ||
| 44 | |||
| 45 | |||
| 46 | /* | ||
| 47 | * helper function to extract extent size hint from inode | ||
| 48 | */ | ||
| 49 | STATIC_INLINE xfs_extlen_t | ||
| 50 | xfs_get_extsz_hint( | ||
| 51 | xfs_inode_t *ip) | ||
| 52 | { | ||
| 53 | xfs_extlen_t extsz; | ||
| 54 | |||
| 55 | if (unlikely(XFS_IS_REALTIME_INODE(ip))) { | ||
| 56 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
| 57 | ? ip->i_d.di_extsize | ||
| 58 | : ip->i_mount->m_sb.sb_rextsize; | ||
| 59 | ASSERT(extsz); | ||
| 60 | } else { | ||
| 61 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
| 62 | ? ip->i_d.di_extsize : 0; | ||
| 63 | } | ||
| 64 | return extsz; | ||
| 65 | } | ||
| 66 | |||
| 67 | /* | ||
| 68 | * Prototypes for functions in xfs_rw.c. | 40 | * Prototypes for functions in xfs_rw.c. |
| 69 | */ | 41 | */ |
| 70 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); | 42 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); |
| @@ -76,5 +48,6 @@ extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp, | |||
| 76 | struct xfs_buf **bpp); | 48 | struct xfs_buf **bpp); |
| 77 | extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp, | 49 | extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp, |
| 78 | xfs_buf_t *bp, xfs_daddr_t blkno); | 50 | xfs_buf_t *bp, xfs_daddr_t blkno); |
| 51 | extern xfs_extlen_t xfs_get_extsz_hint(struct xfs_inode *ip); | ||
| 79 | 52 | ||
| 80 | #endif /* __XFS_RW_H__ */ | 53 | #endif /* __XFS_RW_H__ */ |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 66b849358e62..237badcbac3b 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
| @@ -236,19 +236,20 @@ xfs_trans_alloc( | |||
| 236 | uint type) | 236 | uint type) |
| 237 | { | 237 | { |
| 238 | xfs_wait_for_freeze(mp, SB_FREEZE_TRANS); | 238 | xfs_wait_for_freeze(mp, SB_FREEZE_TRANS); |
| 239 | return _xfs_trans_alloc(mp, type); | 239 | return _xfs_trans_alloc(mp, type, KM_SLEEP); |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | xfs_trans_t * | 242 | xfs_trans_t * |
| 243 | _xfs_trans_alloc( | 243 | _xfs_trans_alloc( |
| 244 | xfs_mount_t *mp, | 244 | xfs_mount_t *mp, |
| 245 | uint type) | 245 | uint type, |
| 246 | uint memflags) | ||
| 246 | { | 247 | { |
| 247 | xfs_trans_t *tp; | 248 | xfs_trans_t *tp; |
| 248 | 249 | ||
| 249 | atomic_inc(&mp->m_active_trans); | 250 | atomic_inc(&mp->m_active_trans); |
| 250 | 251 | ||
| 251 | tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP); | 252 | tp = kmem_zone_zalloc(xfs_trans_zone, memflags); |
| 252 | tp->t_magic = XFS_TRANS_MAGIC; | 253 | tp->t_magic = XFS_TRANS_MAGIC; |
| 253 | tp->t_type = type; | 254 | tp->t_type = type; |
| 254 | tp->t_mountp = mp; | 255 | tp->t_mountp = mp; |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index ed47fc77759c..a0574f593f52 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
| @@ -924,7 +924,7 @@ typedef struct xfs_trans { | |||
| 924 | * XFS transaction mechanism exported interfaces. | 924 | * XFS transaction mechanism exported interfaces. |
| 925 | */ | 925 | */ |
| 926 | xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); | 926 | xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); |
| 927 | xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint); | 927 | xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, uint); |
| 928 | xfs_trans_t *xfs_trans_dup(xfs_trans_t *); | 928 | xfs_trans_t *xfs_trans_dup(xfs_trans_t *); |
| 929 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, | 929 | int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, |
| 930 | uint, uint); | 930 | uint, uint); |
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 218829e6a152..03a1f701fea8 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
| @@ -79,11 +79,8 @@ xfs_trans_get_buf(xfs_trans_t *tp, | |||
| 79 | /* | 79 | /* |
| 80 | * Default to a normal get_buf() call if the tp is NULL. | 80 | * Default to a normal get_buf() call if the tp is NULL. |
| 81 | */ | 81 | */ |
| 82 | if (tp == NULL) { | 82 | if (tp == NULL) |
| 83 | bp = xfs_buf_get_flags(target_dev, blkno, len, | 83 | return xfs_buf_get(target_dev, blkno, len, flags | BUF_BUSY); |
| 84 | flags | BUF_BUSY); | ||
| 85 | return(bp); | ||
| 86 | } | ||
| 87 | 84 | ||
| 88 | /* | 85 | /* |
| 89 | * If we find the buffer in the cache with this transaction | 86 | * If we find the buffer in the cache with this transaction |
| @@ -129,7 +126,7 @@ xfs_trans_get_buf(xfs_trans_t *tp, | |||
| 129 | * easily deadlock with our current transaction as well as cause | 126 | * easily deadlock with our current transaction as well as cause |
| 130 | * us to run out of stack space. | 127 | * us to run out of stack space. |
| 131 | */ | 128 | */ |
| 132 | bp = xfs_buf_get_flags(target_dev, blkno, len, flags | BUF_BUSY); | 129 | bp = xfs_buf_get(target_dev, blkno, len, flags | BUF_BUSY); |
| 133 | if (bp == NULL) { | 130 | if (bp == NULL) { |
| 134 | return NULL; | 131 | return NULL; |
| 135 | } | 132 | } |
| @@ -302,7 +299,7 @@ xfs_trans_read_buf( | |||
| 302 | * Default to a normal get_buf() call if the tp is NULL. | 299 | * Default to a normal get_buf() call if the tp is NULL. |
| 303 | */ | 300 | */ |
| 304 | if (tp == NULL) { | 301 | if (tp == NULL) { |
| 305 | bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY); | 302 | bp = xfs_buf_read(target, blkno, len, flags | BUF_BUSY); |
| 306 | if (!bp) | 303 | if (!bp) |
| 307 | return (flags & XFS_BUF_TRYLOCK) ? | 304 | return (flags & XFS_BUF_TRYLOCK) ? |
| 308 | EAGAIN : XFS_ERROR(ENOMEM); | 305 | EAGAIN : XFS_ERROR(ENOMEM); |
| @@ -398,7 +395,7 @@ xfs_trans_read_buf( | |||
| 398 | * easily deadlock with our current transaction as well as cause | 395 | * easily deadlock with our current transaction as well as cause |
| 399 | * us to run out of stack space. | 396 | * us to run out of stack space. |
| 400 | */ | 397 | */ |
| 401 | bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY); | 398 | bp = xfs_buf_read(target, blkno, len, flags | BUF_BUSY); |
| 402 | if (bp == NULL) { | 399 | if (bp == NULL) { |
| 403 | *bpp = NULL; | 400 | *bpp = NULL; |
| 404 | return 0; | 401 | return 0; |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index b572f7e840e0..578f3f59b789 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -538,9 +538,8 @@ xfs_readlink_bmap( | |||
| 538 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); | 538 | d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock); |
| 539 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); | 539 | byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); |
| 540 | 540 | ||
| 541 | bp = xfs_buf_read_flags(mp->m_ddev_targp, d, BTOBB(byte_cnt), | 541 | bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), |
| 542 | XBF_LOCK | XBF_MAPPED | | 542 | XBF_LOCK | XBF_MAPPED | XBF_DONT_BLOCK); |
| 543 | XBF_DONT_BLOCK); | ||
| 544 | error = XFS_BUF_GETERROR(bp); | 543 | error = XFS_BUF_GETERROR(bp); |
| 545 | if (error) { | 544 | if (error) { |
| 546 | xfs_ioerror_alert("xfs_readlink", | 545 | xfs_ioerror_alert("xfs_readlink", |
| @@ -709,6 +708,11 @@ xfs_fsync( | |||
| 709 | } | 708 | } |
| 710 | 709 | ||
| 711 | /* | 710 | /* |
| 711 | * Flags for xfs_free_eofblocks | ||
| 712 | */ | ||
| 713 | #define XFS_FREE_EOF_TRYLOCK (1<<0) | ||
| 714 | |||
| 715 | /* | ||
| 712 | * This is called by xfs_inactive to free any blocks beyond eof | 716 | * This is called by xfs_inactive to free any blocks beyond eof |
| 713 | * when the link count isn't zero and by xfs_dm_punch_hole() when | 717 | * when the link count isn't zero and by xfs_dm_punch_hole() when |
| 714 | * punching a hole to EOF. | 718 | * punching a hole to EOF. |
| @@ -726,7 +730,6 @@ xfs_free_eofblocks( | |||
| 726 | xfs_filblks_t map_len; | 730 | xfs_filblks_t map_len; |
| 727 | int nimaps; | 731 | int nimaps; |
| 728 | xfs_bmbt_irec_t imap; | 732 | xfs_bmbt_irec_t imap; |
| 729 | int use_iolock = (flags & XFS_FREE_EOF_LOCK); | ||
| 730 | 733 | ||
| 731 | /* | 734 | /* |
| 732 | * Figure out if there are any blocks beyond the end | 735 | * Figure out if there are any blocks beyond the end |
| @@ -768,14 +771,19 @@ xfs_free_eofblocks( | |||
| 768 | * cache and we can't | 771 | * cache and we can't |
| 769 | * do that within a transaction. | 772 | * do that within a transaction. |
| 770 | */ | 773 | */ |
| 771 | if (use_iolock) | 774 | if (flags & XFS_FREE_EOF_TRYLOCK) { |
| 775 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { | ||
| 776 | xfs_trans_cancel(tp, 0); | ||
| 777 | return 0; | ||
| 778 | } | ||
| 779 | } else { | ||
| 772 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 780 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
| 781 | } | ||
| 773 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, | 782 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, |
| 774 | ip->i_size); | 783 | ip->i_size); |
| 775 | if (error) { | 784 | if (error) { |
| 776 | xfs_trans_cancel(tp, 0); | 785 | xfs_trans_cancel(tp, 0); |
| 777 | if (use_iolock) | 786 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
| 778 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
| 779 | return error; | 787 | return error; |
| 780 | } | 788 | } |
| 781 | 789 | ||
| @@ -812,8 +820,7 @@ xfs_free_eofblocks( | |||
| 812 | error = xfs_trans_commit(tp, | 820 | error = xfs_trans_commit(tp, |
| 813 | XFS_TRANS_RELEASE_LOG_RES); | 821 | XFS_TRANS_RELEASE_LOG_RES); |
| 814 | } | 822 | } |
| 815 | xfs_iunlock(ip, (use_iolock ? (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL) | 823 | xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL); |
| 816 | : XFS_ILOCK_EXCL)); | ||
| 817 | } | 824 | } |
| 818 | return error; | 825 | return error; |
| 819 | } | 826 | } |
| @@ -1113,7 +1120,17 @@ xfs_release( | |||
| 1113 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && | 1120 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && |
| 1114 | (!(ip->i_d.di_flags & | 1121 | (!(ip->i_d.di_flags & |
| 1115 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { | 1122 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { |
| 1116 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); | 1123 | |
| 1124 | /* | ||
| 1125 | * If we can't get the iolock just skip truncating | ||
| 1126 | * the blocks past EOF because we could deadlock | ||
| 1127 | * with the mmap_sem otherwise. We'll get another | ||
| 1128 | * chance to drop them once the last reference to | ||
| 1129 | * the inode is dropped, so we'll never leak blocks | ||
| 1130 | * permanently. | ||
| 1131 | */ | ||
| 1132 | error = xfs_free_eofblocks(mp, ip, | ||
| 1133 | XFS_FREE_EOF_TRYLOCK); | ||
| 1117 | if (error) | 1134 | if (error) |
| 1118 | return error; | 1135 | return error; |
| 1119 | } | 1136 | } |
| @@ -1184,7 +1201,7 @@ xfs_inactive( | |||
| 1184 | (!(ip->i_d.di_flags & | 1201 | (!(ip->i_d.di_flags & |
| 1185 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || | 1202 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || |
| 1186 | (ip->i_delayed_blks != 0)))) { | 1203 | (ip->i_delayed_blks != 0)))) { |
| 1187 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); | 1204 | error = xfs_free_eofblocks(mp, ip, 0); |
| 1188 | if (error) | 1205 | if (error) |
| 1189 | return VN_INACTIVE_CACHE; | 1206 | return VN_INACTIVE_CACHE; |
| 1190 | } | 1207 | } |
| @@ -2456,46 +2473,6 @@ xfs_set_dmattrs( | |||
| 2456 | return error; | 2473 | return error; |
| 2457 | } | 2474 | } |
| 2458 | 2475 | ||
| 2459 | int | ||
| 2460 | xfs_reclaim( | ||
| 2461 | xfs_inode_t *ip) | ||
| 2462 | { | ||
| 2463 | |||
| 2464 | xfs_itrace_entry(ip); | ||
| 2465 | |||
| 2466 | ASSERT(!VN_MAPPED(VFS_I(ip))); | ||
| 2467 | |||
| 2468 | /* bad inode, get out here ASAP */ | ||
| 2469 | if (is_bad_inode(VFS_I(ip))) { | ||
| 2470 | xfs_ireclaim(ip); | ||
| 2471 | return 0; | ||
| 2472 | } | ||
| 2473 | |||
| 2474 | xfs_ioend_wait(ip); | ||
| 2475 | |||
| 2476 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); | ||
| 2477 | |||
| 2478 | /* | ||
| 2479 | * If we have nothing to flush with this inode then complete the | ||
| 2480 | * teardown now, otherwise break the link between the xfs inode and the | ||
| 2481 | * linux inode and clean up the xfs inode later. This avoids flushing | ||
| 2482 | * the inode to disk during the delete operation itself. | ||
| 2483 | * | ||
| 2484 | * When breaking the link, we need to set the XFS_IRECLAIMABLE flag | ||
| 2485 | * first to ensure that xfs_iunpin() will never see an xfs inode | ||
| 2486 | * that has a linux inode being reclaimed. Synchronisation is provided | ||
| 2487 | * by the i_flags_lock. | ||
| 2488 | */ | ||
| 2489 | if (!ip->i_update_core && (ip->i_itemp == NULL)) { | ||
| 2490 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 2491 | xfs_iflock(ip); | ||
| 2492 | xfs_iflags_set(ip, XFS_IRECLAIMABLE); | ||
| 2493 | return xfs_reclaim_inode(ip, 1, XFS_IFLUSH_DELWRI_ELSE_SYNC); | ||
| 2494 | } | ||
| 2495 | xfs_inode_set_reclaim_tag(ip); | ||
| 2496 | return 0; | ||
| 2497 | } | ||
| 2498 | |||
| 2499 | /* | 2476 | /* |
| 2500 | * xfs_alloc_file_space() | 2477 | * xfs_alloc_file_space() |
| 2501 | * This routine allocates disk space for the given file. | 2478 | * This routine allocates disk space for the given file. |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index a9e102de71a1..167a467403a5 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
| @@ -38,7 +38,6 @@ int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, | |||
| 38 | const char *target_path, mode_t mode, struct xfs_inode **ipp, | 38 | const char *target_path, mode_t mode, struct xfs_inode **ipp, |
| 39 | cred_t *credp); | 39 | cred_t *credp); |
| 40 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); | 40 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); |
| 41 | int xfs_reclaim(struct xfs_inode *ip); | ||
| 42 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, | 41 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, |
| 43 | xfs_flock64_t *bf, xfs_off_t offset, int attr_flags); | 42 | xfs_flock64_t *bf, xfs_off_t offset, int attr_flags); |
| 44 | int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name, | 43 | int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name, |
