xfs_iomap.c revision 153323
1/* 2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 59 21 * Temple Place - Suite 330, Boston MA 02111-1307, USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ 31 */ 32 33#include "xfs.h" 34 35#include "xfs_fs.h" 36#include "xfs_inum.h" 37#include "xfs_log.h" 38#include "xfs_trans.h" 39#include "xfs_sb.h" 40#include "xfs_ag.h" 41#include "xfs_dir.h" 42#include "xfs_dir2.h" 43#include "xfs_alloc.h" 44#include "xfs_dmapi.h" 45#include "xfs_quota.h" 46#include "xfs_mount.h" 47#include "xfs_alloc_btree.h" 48#include "xfs_bmap_btree.h" 49#include "xfs_ialloc_btree.h" 50#include "xfs_btree.h" 51#include "xfs_ialloc.h" 52#include "xfs_attr_sf.h" 53#include "xfs_dir_sf.h" 54#include "xfs_dir2_sf.h" 55#include "xfs_dinode.h" 56#include "xfs_inode.h" 57#include "xfs_bmap.h" 58#include "xfs_bit.h" 59#include "xfs_rtalloc.h" 60#include "xfs_error.h" 61#include "xfs_itable.h" 62#include "xfs_rw.h" 63#include "xfs_acl.h" 64#include "xfs_cap.h" 65#include "xfs_mac.h" 66#include "xfs_attr.h" 67#include "xfs_buf_item.h" 68#include "xfs_trans_space.h" 69#include "xfs_utils.h" 70#include "xfs_iomap.h" 71 72#if defined(XFS_RW_TRACE) 73void 74xfs_iomap_enter_trace( 75 int tag, 76 xfs_iocore_t *io, 77 xfs_off_t offset, 78 ssize_t count) 79{ 80 xfs_inode_t *ip = XFS_IO_INODE(io); 81 82 if (!ip->i_rwtrace) 83 return; 84 85 ktrace_enter(ip->i_rwtrace, 86 (void *)((unsigned long)tag), 87 (void *)ip, 88 (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), 89 (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), 90 (void *)((unsigned long)((offset >> 32) & 0xffffffff)), 91 (void *)((unsigned long)(offset & 0xffffffff)), 92 (void *)((unsigned long)count), 93 (void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)), 94 (void *)((unsigned long)(io->io_new_size & 0xffffffff)), 95 (void *)NULL, 96 (void *)NULL, 97 (void *)NULL, 98 (void *)NULL, 99 (void *)NULL, 100 (void *)NULL, 101 (void *)NULL); 102} 103 104void 105xfs_iomap_map_trace( 106 int tag, 107 xfs_iocore_t *io, 108 xfs_off_t offset, 109 ssize_t count, 110 xfs_iomap_t *iomapp, 111 xfs_bmbt_irec_t *imapp, 112 int flags) 113{ 114 xfs_inode_t *ip = XFS_IO_INODE(io); 115 116 if (!ip->i_rwtrace) 117 return; 118 119 ktrace_enter(ip->i_rwtrace, 120 (void *)((unsigned long)tag), 121 (void *)ip, 122 (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), 123 (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), 124 (void *)((unsigned long)((offset >> 32) & 0xffffffff)), 125 (void *)((unsigned long)(offset & 0xffffffff)), 126 (void *)((unsigned long)count), 127 (void *)((unsigned long)flags), 128 (void *)((unsigned long)((iomapp->iomap_offset >> 32) & 0xffffffff)), 129 (void *)((unsigned long)(iomapp->iomap_offset & 0xffffffff)), 130 (void *)((unsigned long)(iomapp->iomap_delta)), 131 (void *)((unsigned long)(iomapp->iomap_bsize)), 132 (void *)((unsigned long)(iomapp->iomap_bn)), 133 (void *)(__psint_t)(imapp->br_startoff), 134 (void *)((unsigned long)(imapp->br_blockcount)), 135 (void *)(__psint_t)(imapp->br_startblock)); 136} 137#else 138#define xfs_iomap_enter_trace(tag, io, offset, count) 139#define xfs_iomap_map_trace(tag, io, offset, count, iomapp, imapp, flags) 140#endif 141 142#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \ 143 << mp->m_writeio_log) 144#define XFS_STRAT_WRITE_IMAPS 2 145#define XFS_WRITE_IMAPS XFS_BMAP_MAX_NMAP 146 147STATIC int 148xfs_imap_to_bmap( 149 xfs_iocore_t *io, 150 xfs_off_t offset, 151 xfs_bmbt_irec_t *imap, 152 xfs_iomap_t *iomapp, 153 int imaps, /* Number of imap entries */ 154 int iomaps, /* Number of iomap entries */ 155 int flags) 156{ 157 xfs_mount_t *mp; 158 xfs_fsize_t nisize; 159 int pbm; 160 xfs_fsblock_t start_block; 161 162 mp = io->io_mount; 163 nisize = XFS_SIZE(mp, io); 164 if (io->io_new_size > nisize) 165 nisize = io->io_new_size; 166 167 for (pbm = 0; imaps && pbm < iomaps; imaps--, iomapp++, imap++, pbm++) { 168 iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ? 169 mp->m_rtdev_targp : mp->m_ddev_targp; 170 iomapp->iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); 171 iomapp->iomap_delta = offset - iomapp->iomap_offset; 172 iomapp->iomap_bsize = XFS_FSB_TO_B(mp, imap->br_blockcount); 173 iomapp->iomap_flags = flags; 174 175 start_block = imap->br_startblock; 176 if (start_block == HOLESTARTBLOCK) { 177 iomapp->iomap_bn = IOMAP_DADDR_NULL; 178 iomapp->iomap_flags = IOMAP_HOLE; 179 } else if (start_block == DELAYSTARTBLOCK) { 180 iomapp->iomap_bn = IOMAP_DADDR_NULL; 181 iomapp->iomap_flags = IOMAP_DELAY; 182 } else { 183 iomapp->iomap_bn = XFS_FSB_TO_DB_IO(io, start_block); 184 if (ISUNWRITTEN(imap)) 185 iomapp->iomap_flags |= IOMAP_UNWRITTEN; 186 } 187 188 if ((iomapp->iomap_offset + iomapp->iomap_bsize) >= nisize) { 189 iomapp->iomap_flags |= IOMAP_EOF; 190 } 191 192 offset += iomapp->iomap_bsize - iomapp->iomap_delta; 193 } 194 return pbm; /* Return the number filled */ 195} 196 197int 198xfs_iomap( 199 xfs_iocore_t *io, 200 xfs_off_t offset, 201 ssize_t count, 202 int flags, 203 xfs_iomap_t *iomapp, 204 int *niomaps) 205{ 206 xfs_mount_t *mp = io->io_mount; 207 xfs_fileoff_t offset_fsb, end_fsb; 208 int error = 0; 209 int lockmode = 0; 210 xfs_bmbt_irec_t imap; 211 int nimaps = 1; 212 int bmapi_flags = 0; 213 int iomap_flags = 0; 214 215 if (XFS_FORCED_SHUTDOWN(mp)) 216 return XFS_ERROR(EIO); 217 218 switch (flags & 219 (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE | 220 BMAPI_UNWRITTEN | BMAPI_DEVICE)) { 221 case BMAPI_READ: 222 xfs_iomap_enter_trace(XFS_IOMAP_READ_ENTER, io, offset, count); 223 lockmode = XFS_LCK_MAP_SHARED(mp, io); 224 bmapi_flags = XFS_BMAPI_ENTIRE; 225 if (flags & BMAPI_IGNSTATE) 226 bmapi_flags |= XFS_BMAPI_IGSTATE; 227 break; 228 case BMAPI_WRITE: 229 xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, io, offset, count); 230 lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR; 231 bmapi_flags = 0; 232 XFS_ILOCK(mp, io, lockmode); 233 break; 234 case BMAPI_ALLOCATE: 235 xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, io, offset, count); 236 lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD; 237 bmapi_flags = XFS_BMAPI_ENTIRE; 238 /* Attempt non-blocking lock */ 239 if (flags & BMAPI_TRYLOCK) { 240 if (!XFS_ILOCK_NOWAIT(mp, io, lockmode)) 241 return XFS_ERROR(EAGAIN); 242 } else { 243 XFS_ILOCK(mp, io, lockmode); 244 } 245 break; 246 case BMAPI_UNWRITTEN: 247 goto phase2; 248 case BMAPI_DEVICE: 249 lockmode = XFS_LCK_MAP_SHARED(mp, io); 250 iomapp->iomap_target = io->io_flags & XFS_IOCORE_RT ? 251 mp->m_rtdev_targp : mp->m_ddev_targp; 252 error = 0; 253 *niomaps = 1; 254 goto out; 255 default: 256 panic("unrecognized bmapi flags"); 257 } 258 259 ASSERT(offset <= mp->m_maxioffset); 260 if ((xfs_fsize_t)offset + count > mp->m_maxioffset) 261 count = mp->m_maxioffset - offset; 262 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); 263 offset_fsb = XFS_B_TO_FSBT(mp, offset); 264 265 error = XFS_BMAPI(mp, NULL, io, offset_fsb, 266 (xfs_filblks_t)(end_fsb - offset_fsb), 267 bmapi_flags, NULL, 0, &imap, 268 &nimaps, NULL); 269 270 if (error) 271 goto out; 272 273phase2: 274 switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) { 275 case BMAPI_WRITE: 276 /* If we found an extent, return it */ 277 if (nimaps && (imap.br_startblock != HOLESTARTBLOCK)) { 278 xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, 279 offset, count, iomapp, &imap, flags); 280 break; 281 } 282 283 if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) { 284 error = XFS_IOMAP_WRITE_DIRECT(mp, io, offset, 285 count, flags, &imap, &nimaps, nimaps); 286 } else { 287 error = XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, 288 flags, &imap, &nimaps); 289 } 290 if (!error) { 291 xfs_iomap_map_trace(XFS_IOMAP_ALLOC_MAP, io, 292 offset, count, iomapp, &imap, flags); 293 } 294 iomap_flags = IOMAP_NEW; 295 break; 296 case BMAPI_ALLOCATE: 297 /* If we found an extent, return it */ 298 XFS_IUNLOCK(mp, io, lockmode); 299 lockmode = 0; 300 301 if (nimaps && !ISNULLSTARTBLOCK(imap.br_startblock)) { 302 xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, 303 offset, count, iomapp, &imap, flags); 304 break; 305 } 306 307 error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps); 308 break; 309 case BMAPI_UNWRITTEN: 310 lockmode = 0; 311 error = XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count); 312 nimaps = 0; 313 break; 314 } 315 316 if (nimaps) { 317 *niomaps = xfs_imap_to_bmap(io, offset, &imap, 318 iomapp, nimaps, *niomaps, iomap_flags); 319 } else if (niomaps) { 320 *niomaps = 0; 321 } 322 323out: 324 if (lockmode) 325 XFS_IUNLOCK(mp, io, lockmode); 326 return XFS_ERROR(error); 327} 328 329STATIC int 330xfs_flush_space( 331 xfs_inode_t *ip, 332 int *fsynced, 333 int *ioflags) 334{ 335 switch (*fsynced) { 336 case 0: 337 if (ip->i_delayed_blks) { 338 xfs_iunlock(ip, XFS_ILOCK_EXCL); 339 xfs_flush_inode(ip); 340 xfs_ilock(ip, XFS_ILOCK_EXCL); 341 *fsynced = 1; 342 } else { 343 *ioflags |= BMAPI_SYNC; 344 *fsynced = 2; 345 } 346 return 0; 347 case 1: 348 *fsynced = 2; 349 *ioflags |= BMAPI_SYNC; 350 return 0; 351 case 2: 352 xfs_iunlock(ip, XFS_ILOCK_EXCL); 353 xfs_flush_device(ip); 354 xfs_ilock(ip, XFS_ILOCK_EXCL); 355 *fsynced = 3; 356 return 0; 357 } 358 return 1; 359} 360 361int 362xfs_iomap_write_direct( 363 xfs_inode_t *ip, 364 xfs_off_t offset, 365 size_t count, 366 int flags, 367 xfs_bmbt_irec_t *ret_imap, 368 int *nmaps, 369 int found) 370{ 371 xfs_mount_t *mp = ip->i_mount; 372 xfs_iocore_t *io = &ip->i_iocore; 373 xfs_fileoff_t offset_fsb; 374 xfs_fileoff_t last_fsb; 375 xfs_filblks_t count_fsb; 376 xfs_fsize_t isize; 377 xfs_fsblock_t firstfsb; 378 int nimaps, maps; 379 int error; 380 int bmapi_flag; 381 int rt; 382 xfs_trans_t *tp; 383 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; 384 xfs_bmap_free_t free_list; 385 int aeof; 386 xfs_filblks_t datablocks; 387 int committed; 388 int numrtextents; 389 uint resblks; 390 391 /* 392 * Make sure that the dquots are there. This doesn't hold 393 * the ilock across a disk read. 394 */ 395 error = XFS_QM_DQATTACH(ip->i_mount, ip, XFS_QMOPT_ILOCKED); 396 if (error) 397 return XFS_ERROR(error); 398 399 maps = min(XFS_WRITE_IMAPS, *nmaps); 400 nimaps = maps; 401 402 isize = ip->i_d.di_size; 403 aeof = (offset + count) > isize; 404 405 if (io->io_new_size > isize) 406 isize = io->io_new_size; 407 408 offset_fsb = XFS_B_TO_FSBT(mp, offset); 409 last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); 410 count_fsb = last_fsb - offset_fsb; 411 if (found && (ret_imap->br_startblock == HOLESTARTBLOCK)) { 412 xfs_fileoff_t map_last_fsb; 413 414 map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; 415 416 if (map_last_fsb < last_fsb) { 417 last_fsb = map_last_fsb; 418 count_fsb = last_fsb - offset_fsb; 419 } 420 ASSERT(count_fsb > 0); 421 } 422 423 /* 424 * determine if reserving space on 425 * the data or realtime partition. 426 */ 427 if ((rt = XFS_IS_REALTIME_INODE(ip))) { 428 int sbrtextsize, iprtextsize; 429 430 sbrtextsize = mp->m_sb.sb_rextsize; 431 iprtextsize = 432 ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize; 433 numrtextents = (count_fsb + iprtextsize - 1); 434 do_div(numrtextents, sbrtextsize); 435 datablocks = 0; 436 } else { 437 datablocks = count_fsb; 438 numrtextents = 0; 439 } 440 441 /* 442 * allocate and setup the transaction 443 */ 444 xfs_iunlock(ip, XFS_ILOCK_EXCL); 445 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); 446 447 resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); 448 449 error = xfs_trans_reserve(tp, resblks, 450 XFS_WRITE_LOG_RES(mp), numrtextents, 451 XFS_TRANS_PERM_LOG_RES, 452 XFS_WRITE_LOG_COUNT); 453 454 /* 455 * check for running out of space 456 */ 457 if (error) 458 /* 459 * Free the transaction structure. 460 */ 461 xfs_trans_cancel(tp, 0); 462 463 xfs_ilock(ip, XFS_ILOCK_EXCL); 464 465 if (error) 466 goto error_out; /* Don't return in above if .. trans .., 467 need lock to return */ 468 469 if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) { 470 error = (EDQUOT); 471 goto error1; 472 } 473 nimaps = 1; 474 475 bmapi_flag = XFS_BMAPI_WRITE; 476 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 477 xfs_trans_ihold(tp, ip); 478 479 if (!(flags & BMAPI_MMAP) && (offset < ip->i_d.di_size || rt)) 480 bmapi_flag |= XFS_BMAPI_PREALLOC; 481 482 /* 483 * issue the bmapi() call to allocate the blocks 484 */ 485 XFS_BMAP_INIT(&free_list, &firstfsb); 486 imapp = &imap[0]; 487 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 488 bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); 489 if (error) { 490 goto error0; 491 } 492 493 /* 494 * complete the transaction 495 */ 496 497 error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); 498 if (error) { 499 goto error0; 500 } 501 502 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 503 if (error) { 504 goto error_out; 505 } 506 507 /* copy any maps to caller's array and return any error. */ 508 if (nimaps == 0) { 509 error = (ENOSPC); 510 goto error_out; 511 } 512 513 *ret_imap = imap[0]; 514 *nmaps = 1; 515 return 0; 516 517 error0: /* Cancel bmap, unlock inode, and cancel trans */ 518 xfs_bmap_cancel(&free_list); 519 520 error1: /* Just cancel transaction */ 521 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); 522 *nmaps = 0; /* nothing set-up here */ 523 524error_out: 525 return XFS_ERROR(error); 526} 527 528int 529xfs_iomap_write_delay( 530 xfs_inode_t *ip, 531 xfs_off_t offset, 532 size_t count, 533 int ioflag, 534 xfs_bmbt_irec_t *ret_imap, 535 int *nmaps) 536{ 537 xfs_mount_t *mp = ip->i_mount; 538 xfs_iocore_t *io = &ip->i_iocore; 539 xfs_fileoff_t offset_fsb; 540 xfs_fileoff_t last_fsb; 541 xfs_fsize_t isize; 542 xfs_fsblock_t firstblock; 543 int nimaps; 544 int error; 545 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; 546 int aeof; 547 int fsynced = 0; 548 549 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); 550 551 /* 552 * Make sure that the dquots are there. This doesn't hold 553 * the ilock across a disk read. 554 */ 555 556 error = XFS_QM_DQATTACH(mp, ip, XFS_QMOPT_ILOCKED); 557 if (error) 558 return XFS_ERROR(error); 559 560retry: 561 isize = ip->i_d.di_size; 562 if (io->io_new_size > isize) { 563 isize = io->io_new_size; 564 } 565 566 aeof = 0; 567 offset_fsb = XFS_B_TO_FSBT(mp, offset); 568 last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); 569 /* 570 * If the caller is doing a write at the end of the file, 571 * then extend the allocation (and the buffer used for the write) 572 * out to the file system's write iosize. We clean up any extra 573 * space left over when the file is closed in xfs_inactive(). 574 * 575 * We don't bother with this for sync writes, because we need 576 * to minimize the amount we write for good performance. 577 */ 578 if (!(ioflag & BMAPI_SYNC) && ((offset + count) > ip->i_d.di_size)) { 579 xfs_off_t aligned_offset; 580 unsigned int iosize; 581 xfs_fileoff_t ioalign; 582 583 iosize = mp->m_writeio_blocks; 584 aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1)); 585 ioalign = XFS_B_TO_FSBT(mp, aligned_offset); 586 last_fsb = ioalign + iosize; 587 aeof = 1; 588 } 589 590 nimaps = XFS_WRITE_IMAPS; 591 firstblock = NULLFSBLOCK; 592 593 /* 594 * roundup the allocation request to m_dalign boundary if file size 595 * is greater that 512K and we are allocating past the allocation eof 596 */ 597 if (mp->m_dalign && (isize >= mp->m_dalign) && aeof) { 598 int eof; 599 xfs_fileoff_t new_last_fsb; 600 new_last_fsb = roundup_64(last_fsb, mp->m_dalign); 601 error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof); 602 if (error) { 603 return error; 604 } 605 if (eof) { 606 last_fsb = new_last_fsb; 607 } 608 } 609 610 error = xfs_bmapi(NULL, ip, offset_fsb, 611 (xfs_filblks_t)(last_fsb - offset_fsb), 612 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | 613 XFS_BMAPI_ENTIRE, &firstblock, 1, imap, 614 &nimaps, NULL); 615 /* 616 * This can be EDQUOT, if nimaps == 0 617 */ 618 if (error && (error != ENOSPC)) { 619 return XFS_ERROR(error); 620 } 621 /* 622 * If bmapi returned us nothing, and if we didn't get back EDQUOT, 623 * then we must have run out of space. 624 */ 625 if (nimaps == 0) { 626 xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, 627 io, offset, count); 628 if (xfs_flush_space(ip, &fsynced, &ioflag)) 629 return XFS_ERROR(ENOSPC); 630 631 error = 0; 632 goto retry; 633 } 634 635 *ret_imap = imap[0]; 636 *nmaps = 1; 637 return 0; 638} 639 640/* 641 * Pass in a delayed allocate extent, convert it to real extents; 642 * return to the caller the extent we create which maps on top of 643 * the originating callers request. 644 * 645 * Called without a lock on the inode. 646 */ 647int 648xfs_iomap_write_allocate( 649 xfs_inode_t *ip, 650 xfs_bmbt_irec_t *map, 651 int *retmap) 652{ 653 xfs_mount_t *mp = ip->i_mount; 654 xfs_fileoff_t offset_fsb, last_block; 655 xfs_fileoff_t end_fsb, map_start_fsb; 656 xfs_fsblock_t first_block; 657 xfs_bmap_free_t free_list; 658 xfs_filblks_t count_fsb; 659 xfs_bmbt_irec_t imap[XFS_STRAT_WRITE_IMAPS]; 660 xfs_trans_t *tp; 661 int i, nimaps, committed; 662 int error = 0; 663 int nres; 664 665 *retmap = 0; 666 667 /* 668 * Make sure that the dquots are there. 669 */ 670 if ((error = XFS_QM_DQATTACH(mp, ip, 0))) 671 return XFS_ERROR(error); 672 673 offset_fsb = map->br_startoff; 674 count_fsb = map->br_blockcount; 675 map_start_fsb = offset_fsb; 676 677 XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); 678 679 while (count_fsb != 0) { 680 /* 681 * Set up a transaction with which to allocate the 682 * backing store for the file. Do allocations in a 683 * loop until we get some space in the range we are 684 * interested in. The other space that might be allocated 685 * is in the delayed allocation extent on which we sit 686 * but before our buffer starts. 687 */ 688 689 nimaps = 0; 690 while (nimaps == 0) { 691 tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); 692 nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); 693 error = xfs_trans_reserve(tp, nres, 694 XFS_WRITE_LOG_RES(mp), 695 0, XFS_TRANS_PERM_LOG_RES, 696 XFS_WRITE_LOG_COUNT); 697 if (error == ENOSPC) { 698 error = xfs_trans_reserve(tp, 0, 699 XFS_WRITE_LOG_RES(mp), 700 0, 701 XFS_TRANS_PERM_LOG_RES, 702 XFS_WRITE_LOG_COUNT); 703 } 704 if (error) { 705 xfs_trans_cancel(tp, 0); 706 return XFS_ERROR(error); 707 } 708 xfs_ilock(ip, XFS_ILOCK_EXCL); 709 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 710 xfs_trans_ihold(tp, ip); 711 712 XFS_BMAP_INIT(&free_list, &first_block); 713 714 nimaps = XFS_STRAT_WRITE_IMAPS; 715 /* 716 * Ensure we don't go beyond eof - it is possible 717 * the extents changed since we did the read call, 718 * we dropped the ilock in the interim. 719 */ 720 721 end_fsb = XFS_B_TO_FSB(mp, ip->i_d.di_size); 722 xfs_bmap_last_offset(NULL, ip, &last_block, 723 XFS_DATA_FORK); 724 last_block = XFS_FILEOFF_MAX(last_block, end_fsb); 725 if ((map_start_fsb + count_fsb) > last_block) { 726 count_fsb = last_block - map_start_fsb; 727 if (count_fsb == 0) { 728 error = EAGAIN; 729 goto trans_cancel; 730 } 731 } 732 733 /* Go get the actual blocks */ 734 error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, 735 XFS_BMAPI_WRITE, &first_block, 1, 736 imap, &nimaps, &free_list); 737 if (error) 738 goto trans_cancel; 739 740 error = xfs_bmap_finish(&tp, &free_list, 741 first_block, &committed); 742 if (error) 743 goto trans_cancel; 744 745 error = xfs_trans_commit(tp, 746 XFS_TRANS_RELEASE_LOG_RES, NULL); 747 if (error) 748 goto error0; 749 750 xfs_iunlock(ip, XFS_ILOCK_EXCL); 751 } 752 753 /* 754 * See if we were able to allocate an extent that 755 * covers at least part of the callers request 756 */ 757 758 for (i = 0; i < nimaps; i++) { 759 if ((map->br_startoff >= imap[i].br_startoff) && 760 (map->br_startoff < (imap[i].br_startoff + 761 imap[i].br_blockcount))) { 762 *map = imap[i]; 763 *retmap = 1; 764 XFS_STATS_INC(xs_xstrat_quick); 765 return 0; 766 } 767 count_fsb -= imap[i].br_blockcount; 768 } 769 770 /* So far we have not mapped the requested part of the 771 * file, just surrounding data, try again. 772 */ 773 nimaps--; 774 offset_fsb = imap[nimaps].br_startoff + 775 imap[nimaps].br_blockcount; 776 map_start_fsb = offset_fsb; 777 } 778 779trans_cancel: 780 xfs_bmap_cancel(&free_list); 781 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); 782error0: 783 xfs_iunlock(ip, XFS_ILOCK_EXCL); 784 return XFS_ERROR(error); 785} 786 787int 788xfs_iomap_write_unwritten( 789 xfs_inode_t *ip, 790 xfs_off_t offset, 791 size_t count) 792{ 793 xfs_mount_t *mp = ip->i_mount; 794 xfs_trans_t *tp; 795 xfs_fileoff_t offset_fsb; 796 xfs_filblks_t count_fsb; 797 xfs_filblks_t numblks_fsb; 798 xfs_bmbt_irec_t imap; 799 int committed; 800 int error; 801 int nres; 802 int nimaps; 803 xfs_fsblock_t firstfsb; 804 xfs_bmap_free_t free_list; 805 806 xfs_iomap_enter_trace(XFS_IOMAP_UNWRITTEN, 807 &ip->i_iocore, offset, count); 808 809 offset_fsb = XFS_B_TO_FSBT(mp, offset); 810 count_fsb = XFS_B_TO_FSB(mp, count); 811 812 do { 813 nres = XFS_DIOSTRAT_SPACE_RES(mp, 0); 814 815 /* 816 * set up a transaction to convert the range of extents 817 * from unwritten to real. Do allocations in a loop until 818 * we have covered the range passed in. 819 */ 820 821 tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); 822 error = xfs_trans_reserve(tp, nres, 823 XFS_WRITE_LOG_RES(mp), 0, 824 XFS_TRANS_PERM_LOG_RES, 825 XFS_WRITE_LOG_COUNT); 826 if (error) { 827 xfs_trans_cancel(tp, 0); 828 goto error0; 829 } 830 831 xfs_ilock(ip, XFS_ILOCK_EXCL); 832 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 833 xfs_trans_ihold(tp, ip); 834 835 /* 836 * Modify the unwritten extent state of the buffer. 837 */ 838 XFS_BMAP_INIT(&free_list, &firstfsb); 839 nimaps = 1; 840 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 841 XFS_BMAPI_WRITE, &firstfsb, 842 1, &imap, &nimaps, &free_list); 843 if (error) 844 goto error_on_bmapi_transaction; 845 846 error = xfs_bmap_finish(&(tp), &(free_list), 847 firstfsb, &committed); 848 if (error) 849 goto error_on_bmapi_transaction; 850 851 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 852 xfs_iunlock(ip, XFS_ILOCK_EXCL); 853 if (error) 854 goto error0; 855 856 if ((numblks_fsb = imap.br_blockcount) == 0) { 857 /* 858 * The numblks_fsb value should always get 859 * smaller, otherwise the loop is stuck. 860 */ 861 ASSERT(imap.br_blockcount); 862 break; 863 } 864 offset_fsb += numblks_fsb; 865 count_fsb -= numblks_fsb; 866 } while (count_fsb > 0); 867 868 return 0; 869 870error_on_bmapi_transaction: 871 xfs_bmap_cancel(&free_list); 872 xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); 873 xfs_iunlock(ip, XFS_ILOCK_EXCL); 874error0: 875 return XFS_ERROR(error); 876} 877