xfs_iomap.c 26 KB

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