ffs_balloc.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. /*-
  2. * Copyright (c) 2002 Networks Associates Technology, Inc.
  3. * All rights reserved.
  4. *
  5. * This software was developed for the FreeBSD Project by Marshall
  6. * Kirk McKusick and Network Associates Laboratories, the Security
  7. * Research Division of Network Associates, Inc. under DARPA/SPAWAR
  8. * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
  9. * research program
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  21. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  24. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * Copyright (c) 1982, 1986, 1989, 1993
  33. * The Regents of the University of California. All rights reserved.
  34. *
  35. * Redistribution and use in source and binary forms, with or without
  36. * modification, are permitted provided that the following conditions
  37. * are met:
  38. * 1. Redistributions of source code must retain the above copyright
  39. * notice, this list of conditions and the following disclaimer.
  40. * 2. Redistributions in binary form must reproduce the above copyright
  41. * notice, this list of conditions and the following disclaimer in the
  42. * documentation and/or other materials provided with the distribution.
  43. * 3. Neither the name of the University nor the names of its contributors
  44. * may be used to endorse or promote products derived from this software
  45. * without specific prior written permission.
  46. *
  47. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  48. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  51. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  52. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  53. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  54. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  55. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  56. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  57. * SUCH DAMAGE.
  58. *
  59. * @(#)ffs_balloc.c 8.8 (Berkeley) 6/16/95
  60. */
  61. #include "u.h"
  62. #include "port/lib.h"
  63. #include "mem.h"
  64. #include "dat.h"
  65. #include "fns.h"
  66. #include <ufs/libufsdat.h>
  67. #include <ufs/freebsd_util.h>
  68. #include "ufs_harvey.h"
  69. //#include <ufs/ufs/quota.h>
  70. //#include <ufs/ufs/inode.h>
  71. //#include <ufs/ufs/ufs_extern.h>
  72. //#include <ufs/ufs/extattr.h>
  73. //#include <ufs/ufs/ufsmount.h>
  74. //#include <ufs/ffs/fs.h>
  75. //#include <ufs/ffs/ffs_extern.h>
  76. /*
  77. * Balloc defines the structure of file system storage
  78. * by allocating the physical blocks on a device given
  79. * the inode and the logical block number in a file.
  80. * This is the allocation strategy for UFS2. Above is
  81. * the allocation strategy for UFS1.
  82. */
  83. int
  84. ffs_balloc_ufs2(vnode *vp, off_t startoffset, int size,
  85. Ucred *cred, int flags, Buf **bpp)
  86. {
  87. int error = 0;
  88. print("HARVEY TODO: %s\n", __func__);
  89. #if 0
  90. struct inode *ip;
  91. struct ufs2_dinode *dp;
  92. ufs_lbn_t lbn, lastlbn;
  93. struct fs *fs;
  94. struct buf *bp, *nbp;
  95. struct ufsmount *ump;
  96. struct indir indirs[UFS_NIADDR + 2];
  97. ufs2_daddr_t nb, newb, *bap, pref;
  98. ufs2_daddr_t *allocib, *blkp, *allocblk, allociblk[UFS_NIADDR + 1];
  99. ufs2_daddr_t *lbns_remfree, lbns[UFS_NIADDR + 1];
  100. int deallocated, osize, nsize, num, i, error;
  101. int unwindidx = -1;
  102. int saved_inbdflush;
  103. static struct timeval lastfail;
  104. static int curfail;
  105. int gbflags, reclaimed;
  106. ip = VTOI(vp);
  107. dp = ip->i_din2;
  108. fs = ITOFS(ip);
  109. ump = ITOUMP(ip);
  110. lbn = lblkno(fs, startoffset);
  111. size = blkoff(fs, startoffset) + size;
  112. reclaimed = 0;
  113. if (size > fs->fs_bsize)
  114. panic("ffs_balloc_ufs2: blk too big");
  115. *bpp = nil;
  116. if (lbn < 0)
  117. return (EFBIG);
  118. gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0;
  119. if (DOINGSOFTDEP(vp))
  120. softdep_prealloc(vp, MNT_WAIT);
  121. /*
  122. * Check for allocating external data.
  123. */
  124. if (flags & IO_EXT) {
  125. if (lbn >= UFS_NXADDR)
  126. return (EFBIG);
  127. /*
  128. * If the next write will extend the data into a new block,
  129. * and the data is currently composed of a fragment
  130. * this fragment has to be extended to be a full block.
  131. */
  132. lastlbn = lblkno(fs, dp->di_extsize);
  133. if (lastlbn < lbn) {
  134. nb = lastlbn;
  135. osize = sblksize(fs, dp->di_extsize, nb);
  136. if (osize < fs->fs_bsize && osize > 0) {
  137. UFS_LOCK(ump);
  138. error = ffs_realloccg(ip, -1 - nb,
  139. dp->di_extb[nb],
  140. ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
  141. &dp->di_extb[0]), osize,
  142. (int)fs->fs_bsize, flags, cred, &bp);
  143. if (error)
  144. return (error);
  145. if (DOINGSOFTDEP(vp))
  146. softdep_setup_allocext(ip, nb,
  147. dbtofsb(fs, bp->b_blkno),
  148. dp->di_extb[nb],
  149. fs->fs_bsize, osize, bp);
  150. dp->di_extsize = smalllblktosize(fs, nb + 1);
  151. dp->di_extb[nb] = dbtofsb(fs, bp->b_blkno);
  152. bp->b_xflags |= BX_ALTDATA;
  153. ip->i_flag |= IN_CHANGE;
  154. if (flags & IO_SYNC)
  155. bwrite(bp);
  156. else
  157. bawrite(bp);
  158. }
  159. }
  160. /*
  161. * All blocks are direct blocks
  162. */
  163. if (flags & BA_METAONLY)
  164. panic("ffs_balloc_ufs2: BA_METAONLY for ext block");
  165. nb = dp->di_extb[lbn];
  166. if (nb != 0 && dp->di_extsize >= smalllblktosize(fs, lbn + 1)) {
  167. error = bread_gb(vp, -1 - lbn, fs->fs_bsize, NOCRED,
  168. gbflags, &bp);
  169. if (error) {
  170. brelse(bp);
  171. return (error);
  172. }
  173. bp->b_blkno = fsbtodb(fs, nb);
  174. bp->b_xflags |= BX_ALTDATA;
  175. *bpp = bp;
  176. return (0);
  177. }
  178. if (nb != 0) {
  179. /*
  180. * Consider need to reallocate a fragment.
  181. */
  182. osize = fragroundup(fs, blkoff(fs, dp->di_extsize));
  183. nsize = fragroundup(fs, size);
  184. if (nsize <= osize) {
  185. error = bread_gb(vp, -1 - lbn, osize, NOCRED,
  186. gbflags, &bp);
  187. if (error) {
  188. brelse(bp);
  189. return (error);
  190. }
  191. bp->b_blkno = fsbtodb(fs, nb);
  192. bp->b_xflags |= BX_ALTDATA;
  193. } else {
  194. UFS_LOCK(ump);
  195. error = ffs_realloccg(ip, -1 - lbn,
  196. dp->di_extb[lbn],
  197. ffs_blkpref_ufs2(ip, lbn, (int)lbn,
  198. &dp->di_extb[0]), osize, nsize, flags,
  199. cred, &bp);
  200. if (error)
  201. return (error);
  202. bp->b_xflags |= BX_ALTDATA;
  203. if (DOINGSOFTDEP(vp))
  204. softdep_setup_allocext(ip, lbn,
  205. dbtofsb(fs, bp->b_blkno), nb,
  206. nsize, osize, bp);
  207. }
  208. } else {
  209. if (dp->di_extsize < smalllblktosize(fs, lbn + 1))
  210. nsize = fragroundup(fs, size);
  211. else
  212. nsize = fs->fs_bsize;
  213. UFS_LOCK(ump);
  214. error = ffs_alloc(ip, lbn,
  215. ffs_blkpref_ufs2(ip, lbn, (int)lbn, &dp->di_extb[0]),
  216. nsize, flags, cred, &newb);
  217. if (error)
  218. return (error);
  219. bp = getblk(vp, -1 - lbn, nsize, 0, 0, gbflags);
  220. bp->b_blkno = fsbtodb(fs, newb);
  221. bp->b_xflags |= BX_ALTDATA;
  222. if (flags & BA_CLRBUF)
  223. vfs_bio_clrbuf(bp);
  224. if (DOINGSOFTDEP(vp))
  225. softdep_setup_allocext(ip, lbn, newb, 0,
  226. nsize, 0, bp);
  227. }
  228. dp->di_extb[lbn] = dbtofsb(fs, bp->b_blkno);
  229. ip->i_flag |= IN_CHANGE;
  230. *bpp = bp;
  231. return (0);
  232. }
  233. /*
  234. * If the next write will extend the file into a new block,
  235. * and the file is currently composed of a fragment
  236. * this fragment has to be extended to be a full block.
  237. */
  238. lastlbn = lblkno(fs, ip->i_size);
  239. if (lastlbn < UFS_NDADDR && lastlbn < lbn) {
  240. nb = lastlbn;
  241. osize = blksize(fs, ip, nb);
  242. if (osize < fs->fs_bsize && osize > 0) {
  243. UFS_LOCK(ump);
  244. error = ffs_realloccg(ip, nb, dp->di_db[nb],
  245. ffs_blkpref_ufs2(ip, lastlbn, (int)nb,
  246. &dp->di_db[0]), osize, (int)fs->fs_bsize,
  247. flags, cred, &bp);
  248. if (error)
  249. return (error);
  250. if (DOINGSOFTDEP(vp))
  251. softdep_setup_allocdirect(ip, nb,
  252. dbtofsb(fs, bp->b_blkno),
  253. dp->di_db[nb],
  254. fs->fs_bsize, osize, bp);
  255. ip->i_size = smalllblktosize(fs, nb + 1);
  256. dp->di_size = ip->i_size;
  257. dp->di_db[nb] = dbtofsb(fs, bp->b_blkno);
  258. ip->i_flag |= IN_CHANGE | IN_UPDATE;
  259. if (flags & IO_SYNC)
  260. bwrite(bp);
  261. else
  262. bawrite(bp);
  263. }
  264. }
  265. /*
  266. * The first UFS_NDADDR blocks are direct blocks
  267. */
  268. if (lbn < UFS_NDADDR) {
  269. if (flags & BA_METAONLY)
  270. panic("ffs_balloc_ufs2: BA_METAONLY for direct block");
  271. nb = dp->di_db[lbn];
  272. if (nb != 0 && ip->i_size >= smalllblktosize(fs, lbn + 1)) {
  273. error = bread_gb(vp, lbn, fs->fs_bsize, NOCRED,
  274. gbflags, &bp);
  275. if (error) {
  276. brelse(bp);
  277. return (error);
  278. }
  279. bp->b_blkno = fsbtodb(fs, nb);
  280. *bpp = bp;
  281. return (0);
  282. }
  283. if (nb != 0) {
  284. /*
  285. * Consider need to reallocate a fragment.
  286. */
  287. osize = fragroundup(fs, blkoff(fs, ip->i_size));
  288. nsize = fragroundup(fs, size);
  289. if (nsize <= osize) {
  290. error = bread_gb(vp, lbn, osize, NOCRED,
  291. gbflags, &bp);
  292. if (error) {
  293. brelse(bp);
  294. return (error);
  295. }
  296. bp->b_blkno = fsbtodb(fs, nb);
  297. } else {
  298. UFS_LOCK(ump);
  299. error = ffs_realloccg(ip, lbn, dp->di_db[lbn],
  300. ffs_blkpref_ufs2(ip, lbn, (int)lbn,
  301. &dp->di_db[0]), osize, nsize, flags,
  302. cred, &bp);
  303. if (error)
  304. return (error);
  305. if (DOINGSOFTDEP(vp))
  306. softdep_setup_allocdirect(ip, lbn,
  307. dbtofsb(fs, bp->b_blkno), nb,
  308. nsize, osize, bp);
  309. }
  310. } else {
  311. if (ip->i_size < smalllblktosize(fs, lbn + 1))
  312. nsize = fragroundup(fs, size);
  313. else
  314. nsize = fs->fs_bsize;
  315. UFS_LOCK(ump);
  316. error = ffs_alloc(ip, lbn,
  317. ffs_blkpref_ufs2(ip, lbn, (int)lbn,
  318. &dp->di_db[0]), nsize, flags, cred, &newb);
  319. if (error)
  320. return (error);
  321. bp = getblk(vp, lbn, nsize, 0, 0, gbflags);
  322. bp->b_blkno = fsbtodb(fs, newb);
  323. if (flags & BA_CLRBUF)
  324. vfs_bio_clrbuf(bp);
  325. if (DOINGSOFTDEP(vp))
  326. softdep_setup_allocdirect(ip, lbn, newb, 0,
  327. nsize, 0, bp);
  328. }
  329. dp->di_db[lbn] = dbtofsb(fs, bp->b_blkno);
  330. ip->i_flag |= IN_CHANGE | IN_UPDATE;
  331. *bpp = bp;
  332. return (0);
  333. }
  334. /*
  335. * Determine the number of levels of indirection.
  336. */
  337. pref = 0;
  338. if ((error = ufs_getlbns(vp, lbn, indirs, &num)) != 0)
  339. return(error);
  340. #ifdef INVARIANTS
  341. if (num < 1)
  342. panic ("ffs_balloc_ufs2: ufs_getlbns returned indirect block");
  343. #endif
  344. saved_inbdflush = curthread_pflags_set(TDP_INBDFLUSH);
  345. /*
  346. * Fetch the first indirect block allocating if necessary.
  347. */
  348. --num;
  349. nb = dp->di_ib[indirs[0].in_off];
  350. allocib = nil;
  351. allocblk = allociblk;
  352. lbns_remfree = lbns;
  353. if (nb == 0) {
  354. UFS_LOCK(ump);
  355. pref = ffs_blkpref_ufs2(ip, lbn, -indirs[0].in_off - 1,
  356. (ufs2_daddr_t *)0);
  357. if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
  358. flags, cred, &newb)) != 0) {
  359. curthread_pflags_restore(saved_inbdflush);
  360. return (error);
  361. }
  362. pref = newb + fs->fs_frag;
  363. nb = newb;
  364. MPASS(allocblk < allociblk + nitems(allociblk));
  365. MPASS(lbns_remfree < lbns + nitems(lbns));
  366. *allocblk++ = nb;
  367. *lbns_remfree++ = indirs[1].in_lbn;
  368. bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0,
  369. GB_UNMAPPED);
  370. bp->b_blkno = fsbtodb(fs, nb);
  371. vfs_bio_clrbuf(bp);
  372. if (DOINGSOFTDEP(vp)) {
  373. softdep_setup_allocdirect(ip,
  374. UFS_NDADDR + indirs[0].in_off, newb, 0,
  375. fs->fs_bsize, 0, bp);
  376. bdwrite(bp);
  377. } else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) {
  378. if (bp->b_bufsize == fs->fs_bsize)
  379. bp->b_flags |= B_CLUSTEROK;
  380. bdwrite(bp);
  381. } else {
  382. if ((error = bwrite(bp)) != 0)
  383. goto fail;
  384. }
  385. allocib = &dp->di_ib[indirs[0].in_off];
  386. *allocib = nb;
  387. ip->i_flag |= IN_CHANGE | IN_UPDATE;
  388. }
  389. /*
  390. * Fetch through the indirect blocks, allocating as necessary.
  391. */
  392. retry:
  393. for (i = 1;;) {
  394. error = bread(vp,
  395. indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
  396. if (error) {
  397. brelse(bp);
  398. goto fail;
  399. }
  400. bap = (ufs2_daddr_t *)bp->b_data;
  401. nb = bap[indirs[i].in_off];
  402. if (i == num)
  403. break;
  404. i += 1;
  405. if (nb != 0) {
  406. bqrelse(bp);
  407. continue;
  408. }
  409. UFS_LOCK(ump);
  410. /*
  411. * If parent indirect has just been allocated, try to cluster
  412. * immediately following it.
  413. */
  414. if (pref == 0)
  415. pref = ffs_blkpref_ufs2(ip, lbn, i - num - 1,
  416. (ufs2_daddr_t *)0);
  417. if ((error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
  418. flags | IO_BUFLOCKED, cred, &newb)) != 0) {
  419. brelse(bp);
  420. if (DOINGSOFTDEP(vp) && ++reclaimed == 1) {
  421. UFS_LOCK(ump);
  422. softdep_request_cleanup(fs, vp, cred,
  423. FLUSH_BLOCKS_WAIT);
  424. UFS_UNLOCK(ump);
  425. goto retry;
  426. }
  427. if (ppsratecheck(&lastfail, &curfail, 1)) {
  428. ffs_fserr(fs, ip->i_number, "filesystem full");
  429. uprintf("\n%s: write failed, filesystem "
  430. "is full\n", fs->fs_fsmnt);
  431. }
  432. goto fail;
  433. }
  434. pref = newb + fs->fs_frag;
  435. nb = newb;
  436. MPASS(allocblk < allociblk + nitems(allociblk));
  437. MPASS(lbns_remfree < lbns + nitems(lbns));
  438. *allocblk++ = nb;
  439. *lbns_remfree++ = indirs[i].in_lbn;
  440. nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0,
  441. GB_UNMAPPED);
  442. nbp->b_blkno = fsbtodb(fs, nb);
  443. vfs_bio_clrbuf(nbp);
  444. if (DOINGSOFTDEP(vp)) {
  445. softdep_setup_allocindir_meta(nbp, ip, bp,
  446. indirs[i - 1].in_off, nb);
  447. bdwrite(nbp);
  448. } else if ((flags & IO_SYNC) == 0 && DOINGASYNC(vp)) {
  449. if (nbp->b_bufsize == fs->fs_bsize)
  450. nbp->b_flags |= B_CLUSTEROK;
  451. bdwrite(nbp);
  452. } else {
  453. if ((error = bwrite(nbp)) != 0) {
  454. brelse(bp);
  455. goto fail;
  456. }
  457. }
  458. bap[indirs[i - 1].in_off] = nb;
  459. if (allocib == nil && unwindidx < 0)
  460. unwindidx = i - 1;
  461. /*
  462. * If required, write synchronously, otherwise use
  463. * delayed write.
  464. */
  465. if (flags & IO_SYNC) {
  466. bwrite(bp);
  467. } else {
  468. if (bp->b_bufsize == fs->fs_bsize)
  469. bp->b_flags |= B_CLUSTEROK;
  470. bdwrite(bp);
  471. }
  472. }
  473. /*
  474. * If asked only for the indirect block, then return it.
  475. */
  476. if (flags & BA_METAONLY) {
  477. curthread_pflags_restore(saved_inbdflush);
  478. *bpp = bp;
  479. return (0);
  480. }
  481. /*
  482. * Get the data block, allocating if necessary.
  483. */
  484. if (nb == 0) {
  485. UFS_LOCK(ump);
  486. /*
  487. * If allocating metadata at the front of the cylinder
  488. * group and parent indirect block has just been allocated,
  489. * then cluster next to it if it is the first indirect in
  490. * the file. Otherwise it has been allocated in the metadata
  491. * area, so we want to find our own place out in the data area.
  492. */
  493. if (pref == 0 || (lbn > UFS_NDADDR && fs->fs_metaspace != 0))
  494. pref = ffs_blkpref_ufs2(ip, lbn, indirs[i].in_off,
  495. &bap[0]);
  496. error = ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize,
  497. flags | IO_BUFLOCKED, cred, &newb);
  498. if (error) {
  499. brelse(bp);
  500. if (DOINGSOFTDEP(vp) && ++reclaimed == 1) {
  501. UFS_LOCK(ump);
  502. softdep_request_cleanup(fs, vp, cred,
  503. FLUSH_BLOCKS_WAIT);
  504. UFS_UNLOCK(ump);
  505. goto retry;
  506. }
  507. if (ppsratecheck(&lastfail, &curfail, 1)) {
  508. ffs_fserr(fs, ip->i_number, "filesystem full");
  509. uprintf("\n%s: write failed, filesystem "
  510. "is full\n", fs->fs_fsmnt);
  511. }
  512. goto fail;
  513. }
  514. nb = newb;
  515. MPASS(allocblk < allociblk + nitems(allociblk));
  516. MPASS(lbns_remfree < lbns + nitems(lbns));
  517. *allocblk++ = nb;
  518. *lbns_remfree++ = lbn;
  519. nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, gbflags);
  520. nbp->b_blkno = fsbtodb(fs, nb);
  521. if (flags & BA_CLRBUF)
  522. vfs_bio_clrbuf(nbp);
  523. if (DOINGSOFTDEP(vp))
  524. softdep_setup_allocindir_page(ip, lbn, bp,
  525. indirs[i].in_off, nb, 0, nbp);
  526. bap[indirs[i].in_off] = nb;
  527. /*
  528. * If required, write synchronously, otherwise use
  529. * delayed write.
  530. */
  531. if (flags & IO_SYNC) {
  532. bwrite(bp);
  533. } else {
  534. if (bp->b_bufsize == fs->fs_bsize)
  535. bp->b_flags |= B_CLUSTEROK;
  536. bdwrite(bp);
  537. }
  538. curthread_pflags_restore(saved_inbdflush);
  539. *bpp = nbp;
  540. return (0);
  541. }
  542. brelse(bp);
  543. /*
  544. * If requested clear invalid portions of the buffer. If we
  545. * have to do a read-before-write (typical if BA_CLRBUF is set),
  546. * try to do some read-ahead in the sequential case to reduce
  547. * the number of I/O transactions.
  548. */
  549. if (flags & BA_CLRBUF) {
  550. int seqcount = (flags & BA_SEQMASK) >> BA_SEQSHIFT;
  551. if (seqcount != 0 &&
  552. (vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0 &&
  553. !(vm_page_count_severe() || buf_dirty_count_severe())) {
  554. error = cluster_read(vp, ip->i_size, lbn,
  555. (int)fs->fs_bsize, NOCRED,
  556. MAXBSIZE, seqcount, gbflags, &nbp);
  557. } else {
  558. error = bread_gb(vp, lbn, (int)fs->fs_bsize,
  559. NOCRED, gbflags, &nbp);
  560. }
  561. if (error) {
  562. brelse(nbp);
  563. goto fail;
  564. }
  565. } else {
  566. nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, gbflags);
  567. nbp->b_blkno = fsbtodb(fs, nb);
  568. }
  569. curthread_pflags_restore(saved_inbdflush);
  570. *bpp = nbp;
  571. return (0);
  572. fail:
  573. curthread_pflags_restore(saved_inbdflush);
  574. /*
  575. * If we have failed to allocate any blocks, simply return the error.
  576. * This is the usual case and avoids the need to fsync the file.
  577. */
  578. if (allocblk == allociblk && allocib == nil && unwindidx == -1)
  579. return (error);
  580. /*
  581. * If we have failed part way through block allocation, we
  582. * have to deallocate any indirect blocks that we have allocated.
  583. * We have to fsync the file before we start to get rid of all
  584. * of its dependencies so that we do not leave them dangling.
  585. * We have to sync it at the end so that the soft updates code
  586. * does not find any untracked changes. Although this is really
  587. * slow, running out of disk space is not expected to be a common
  588. * occurrence. The error return from fsync is ignored as we already
  589. * have an error to return to the user.
  590. *
  591. * XXX Still have to journal the free below
  592. */
  593. (void) ffs_syncvnode(vp, MNT_WAIT, 0);
  594. for (deallocated = 0, blkp = allociblk, lbns_remfree = lbns;
  595. blkp < allocblk; blkp++, lbns_remfree++) {
  596. /*
  597. * We shall not leave the freed blocks on the vnode
  598. * buffer object lists.
  599. */
  600. bp = getblk(vp, *lbns_remfree, fs->fs_bsize, 0, 0,
  601. GB_NOCREAT | GB_UNMAPPED);
  602. if (bp != nil) {
  603. KASSERT(bp->b_blkno == fsbtodb(fs, *blkp),
  604. ("mismatch2 l %jd %jd b %ju %ju",
  605. (intmax_t)bp->b_lblkno, (uintmax_t)*lbns_remfree,
  606. (uintmax_t)bp->b_blkno,
  607. (uintmax_t)fsbtodb(fs, *blkp)));
  608. bp->b_flags |= B_INVAL | B_RELBUF | B_NOCACHE;
  609. bp->b_flags &= ~(B_ASYNC | B_CACHE);
  610. brelse(bp);
  611. }
  612. deallocated += fs->fs_bsize;
  613. }
  614. if (allocib != nil) {
  615. *allocib = 0;
  616. } else if (unwindidx >= 0) {
  617. int r;
  618. r = bread(vp, indirs[unwindidx].in_lbn,
  619. (int)fs->fs_bsize, NOCRED, &bp);
  620. if (r) {
  621. panic("Could not unwind indirect block, error %d", r);
  622. brelse(bp);
  623. } else {
  624. bap = (ufs2_daddr_t *)bp->b_data;
  625. bap[indirs[unwindidx].in_off] = 0;
  626. if (flags & IO_SYNC) {
  627. bwrite(bp);
  628. } else {
  629. if (bp->b_bufsize == fs->fs_bsize)
  630. bp->b_flags |= B_CLUSTEROK;
  631. bdwrite(bp);
  632. }
  633. }
  634. }
  635. if (deallocated) {
  636. #ifdef QUOTA
  637. /*
  638. * Restore user's disk quota because allocation failed.
  639. */
  640. (void) chkdq(ip, -btodb(deallocated), cred, FORCE);
  641. #endif
  642. dp->di_blocks -= btodb(deallocated);
  643. ip->i_flag |= IN_CHANGE | IN_UPDATE;
  644. }
  645. (void) ffs_syncvnode(vp, MNT_WAIT, 0);
  646. /*
  647. * After the buffers are invalidated and on-disk pointers are
  648. * cleared, free the blocks.
  649. */
  650. for (blkp = allociblk; blkp < allocblk; blkp++) {
  651. #ifdef INVARIANTS
  652. if (blkp == allociblk)
  653. lbns_remfree = lbns;
  654. bp = getblk(vp, *lbns_remfree, fs->fs_bsize, 0, 0,
  655. GB_NOCREAT | GB_UNMAPPED);
  656. if (bp != nil) {
  657. panic("zombie2 %jd %ju %ju",
  658. (intmax_t)bp->b_lblkno, (uintmax_t)bp->b_blkno,
  659. (uintmax_t)fsbtodb(fs, *blkp));
  660. }
  661. lbns_remfree++;
  662. #endif
  663. ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize,
  664. ip->i_number, vp->v_type, nil);
  665. }
  666. #endif // 0
  667. return (error);
  668. }