growfs.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672
  1. /*-
  2. * SPDX-License-Identifier: BSD-4-Clause
  3. *
  4. * Copyright (c) 1980, 1989, 1993 The Regents of the University of California.
  5. * Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz
  6. * Copyright (c) 2012 The FreeBSD Foundation
  7. * All rights reserved.
  8. *
  9. * This code is derived from software contributed to Berkeley by
  10. * Christoph Herrmann and Thomas-Henning von Kamptz, Munich and Frankfurt.
  11. *
  12. * Portions of this software were developed by Edward Tomasz Napierala
  13. * under sponsorship from the FreeBSD Foundation.
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions
  17. * are met:
  18. * 1. Redistributions of source code must retain the above copyright
  19. * notice, this list of conditions and the following disclaimer.
  20. * 2. Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in the
  22. * documentation and/or other materials provided with the distribution.
  23. * 3. All advertising materials mentioning features or use of this software
  24. * must display the following acknowledgment:
  25. * This product includes software developed by the University of
  26. * California, Berkeley and its contributors, as well as Christoph
  27. * Herrmann and Thomas-Henning von Kamptz.
  28. * 4. Neither the name of the University nor the names of its contributors
  29. * may be used to endorse or promote products derived from this software
  30. * without specific prior written permission.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  33. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  36. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  40. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  41. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  42. * SUCH DAMAGE.
  43. *
  44. * $TSHeader: src/sbin/growfs/growfs.c,v 1.5 2000/12/12 19:31:00 tomsoft Exp $
  45. *
  46. */
  47. #include <sys/param.h>
  48. #include <sys/ioctl.h>
  49. #include <sys/stat.h>
  50. #include <sys/disk.h>
  51. #include <sys/ucred.h>
  52. #include <sys/mount.h>
  53. #include <stdio.h>
  54. #include <paths.h>
  55. #include <ctype.h>
  56. #include <err.h>
  57. #include <errno.h>
  58. #include <fcntl.h>
  59. #include <fstab.h>
  60. #include <inttypes.h>
  61. #include <limits.h>
  62. #include <mntopts.h>
  63. #include <paths.h>
  64. #include <stdlib.h>
  65. #include <stdint.h>
  66. #include <string.h>
  67. #include <time.h>
  68. #include <unistd.h>
  69. #include <ufs/ufs/dinode.h>
  70. #include <ufs/ffs/fs.h>
  71. #include <libutil.h>
  72. #include <libufs.h>
  73. #include "debug.h"
  74. #ifdef FS_DEBUG
  75. int _dbg_lvl_ = (DL_INFO); /* DL_TRC */
  76. #endif /* FS_DEBUG */
  77. static union {
  78. struct fs fs;
  79. char pad[SBLOCKSIZE];
  80. } fsun1, fsun2;
  81. #define sblock fsun1.fs /* the new superblock */
  82. #define osblock fsun2.fs /* the old superblock */
  83. static union {
  84. struct cg cg;
  85. char pad[MAXBSIZE];
  86. } cgun1, cgun2;
  87. #define acg cgun1.cg /* a cylinder cgroup (new) */
  88. #define aocg cgun2.cg /* an old cylinder group */
  89. static struct csum *fscs; /* cylinder summary */
  90. static void growfs(int, int, unsigned int);
  91. static void rdfs(ufs2_daddr_t, size_t, void *, int);
  92. static void wtfs(ufs2_daddr_t, size_t, void *, int, unsigned int);
  93. static int charsperline(void);
  94. static void usage(void);
  95. static int isblock(struct fs *, unsigned char *, int);
  96. static void clrblock(struct fs *, unsigned char *, int);
  97. static void setblock(struct fs *, unsigned char *, int);
  98. static void initcg(int, time_t, int, unsigned int);
  99. static void updjcg(int, time_t, int, int, unsigned int);
  100. static void updcsloc(time_t, int, int, unsigned int);
  101. static void frag_adjust(ufs2_daddr_t, int);
  102. static void updclst(int);
  103. static void cgckhash(struct cg *);
  104. /*
  105. * Here we actually start growing the file system. We basically read the
  106. * cylinder summary from the first cylinder group as we want to update
  107. * this on the fly during our various operations. First we handle the
  108. * changes in the former last cylinder group. Afterwards we create all new
  109. * cylinder groups. Now we handle the cylinder group containing the
  110. * cylinder summary which might result in a relocation of the whole
  111. * structure. In the end we write back the updated cylinder summary, the
  112. * new superblock, and slightly patched versions of the super block
  113. * copies.
  114. */
  115. static void
  116. growfs(int fsi, int fso, unsigned int Nflag)
  117. {
  118. DBG_FUNC("growfs")
  119. time_t modtime;
  120. uint cylno;
  121. int i, j, width;
  122. char tmpbuf[100];
  123. DBG_ENTER;
  124. time(&modtime);
  125. /*
  126. * Get the cylinder summary into the memory.
  127. */
  128. fscs = (struct csum *)calloc((size_t)1, (size_t)sblock.fs_cssize);
  129. if (fscs == NULL)
  130. errx(3, "calloc failed");
  131. memcpy(fscs, osblock.fs_csp, osblock.fs_cssize);
  132. free(osblock.fs_csp);
  133. osblock.fs_csp = NULL;
  134. sblock.fs_csp = fscs;
  135. #ifdef FS_DEBUG
  136. {
  137. struct csum *dbg_csp;
  138. u_int32_t dbg_csc;
  139. char dbg_line[80];
  140. dbg_csp = fscs;
  141. for (dbg_csc = 0; dbg_csc < osblock.fs_ncg; dbg_csc++) {
  142. snprintf(dbg_line, sizeof(dbg_line),
  143. "%d. old csum in old location", dbg_csc);
  144. DBG_DUMP_CSUM(&osblock, dbg_line, dbg_csp++);
  145. }
  146. }
  147. #endif /* FS_DEBUG */
  148. DBG_PRINT0("fscs read\n");
  149. /*
  150. * Do all needed changes in the former last cylinder group.
  151. */
  152. updjcg(osblock.fs_ncg - 1, modtime, fsi, fso, Nflag);
  153. /*
  154. * Dump out summary information about file system.
  155. */
  156. #ifdef FS_DEBUG
  157. #define B2MBFACTOR (1 / (1024.0 * 1024.0))
  158. printf("growfs: %.1fMB (%jd sectors) block size %d, fragment size %d\n",
  159. (float)sblock.fs_size * sblock.fs_fsize * B2MBFACTOR,
  160. (intmax_t)fsbtodb(&sblock, sblock.fs_size), sblock.fs_bsize,
  161. sblock.fs_fsize);
  162. printf("\tusing %d cylinder groups of %.2fMB, %d blks, %d inodes.\n",
  163. sblock.fs_ncg, (float)sblock.fs_fpg * sblock.fs_fsize * B2MBFACTOR,
  164. sblock.fs_fpg / sblock.fs_frag, sblock.fs_ipg);
  165. if (sblock.fs_flags & FS_DOSOFTDEP)
  166. printf("\twith soft updates\n");
  167. #undef B2MBFACTOR
  168. #endif /* FS_DEBUG */
  169. /*
  170. * Now build the cylinders group blocks and
  171. * then print out indices of cylinder groups.
  172. */
  173. printf("super-block backups (for fsck_ffs -b #) at:\n");
  174. i = 0;
  175. width = charsperline();
  176. /*
  177. * Iterate for only the new cylinder groups.
  178. */
  179. for (cylno = osblock.fs_ncg; cylno < sblock.fs_ncg; cylno++) {
  180. initcg(cylno, modtime, fso, Nflag);
  181. j = sprintf(tmpbuf, " %jd%s",
  182. (intmax_t)fsbtodb(&sblock, cgsblock(&sblock, cylno)),
  183. cylno < (sblock.fs_ncg - 1) ? "," : "" );
  184. if (i + j >= width) {
  185. printf("\n");
  186. i = 0;
  187. }
  188. i += j;
  189. printf("%s", tmpbuf);
  190. fflush(stdout);
  191. }
  192. printf("\n");
  193. /*
  194. * Do all needed changes in the first cylinder group.
  195. * allocate blocks in new location
  196. */
  197. updcsloc(modtime, fsi, fso, Nflag);
  198. /*
  199. * Clean up the dynamic fields in our superblock.
  200. *
  201. * XXX
  202. * The following fields are currently distributed from the superblock
  203. * to the copies:
  204. * fs_minfree
  205. * fs_rotdelay
  206. * fs_maxcontig
  207. * fs_maxbpg
  208. * fs_minfree,
  209. * fs_optim
  210. * fs_flags
  211. *
  212. * We probably should rather change the summary for the cylinder group
  213. * statistics here to the value of what would be in there, if the file
  214. * system were created initially with the new size. Therefore we still
  215. * need to find an easy way of calculating that.
  216. * Possibly we can try to read the first superblock copy and apply the
  217. * "diffed" stats between the old and new superblock by still copying
  218. * certain parameters onto that.
  219. */
  220. sblock.fs_time = modtime;
  221. sblock.fs_fmod = 0;
  222. sblock.fs_clean = 1;
  223. sblock.fs_ronly = 0;
  224. sblock.fs_cgrotor = 0;
  225. sblock.fs_state = 0;
  226. memset((void *)&sblock.fs_fsmnt, 0, sizeof(sblock.fs_fsmnt));
  227. /*
  228. * Now write the new superblock, its summary information,
  229. * and all the alternates back to disk.
  230. */
  231. if (!Nflag && sbput(fso, &sblock, sblock.fs_ncg) != 0)
  232. errc(3, EIO, "could not write updated superblock");
  233. DBG_PRINT0("fscs written\n");
  234. #ifdef FS_DEBUG
  235. {
  236. struct csum *dbg_csp;
  237. u_int32_t dbg_csc;
  238. char dbg_line[80];
  239. dbg_csp = fscs;
  240. for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) {
  241. snprintf(dbg_line, sizeof(dbg_line),
  242. "%d. new csum in new location", dbg_csc);
  243. DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++);
  244. }
  245. }
  246. #endif /* FS_DEBUG */
  247. DBG_PRINT0("sblock written\n");
  248. DBG_DUMP_FS(&sblock, "new initial sblock");
  249. DBG_PRINT0("sblock copies written\n");
  250. DBG_DUMP_FS(&sblock, "new other sblocks");
  251. DBG_LEAVE;
  252. return;
  253. }
  254. /*
  255. * This creates a new cylinder group structure, for more details please see
  256. * the source of newfs(8), as this function is taken over almost unchanged.
  257. * As this is never called for the first cylinder group, the special
  258. * provisions for that case are removed here.
  259. */
  260. static void
  261. initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
  262. {
  263. DBG_FUNC("initcg")
  264. static caddr_t iobuf;
  265. static long iobufsize;
  266. long blkno, start;
  267. ino_t ino;
  268. ufs2_daddr_t i, cbase, dmax;
  269. struct ufs1_dinode *dp1;
  270. struct ufs2_dinode *dp2;
  271. struct csum *cs;
  272. uint j, d, dupper, dlower;
  273. if (iobuf == NULL) {
  274. iobufsize = 2 * sblock.fs_bsize;
  275. if ((iobuf = malloc(iobufsize)) == NULL)
  276. errx(37, "panic: cannot allocate I/O buffer");
  277. memset(iobuf, '\0', iobufsize);
  278. }
  279. /*
  280. * Determine block bounds for cylinder group.
  281. * Allow space for super block summary information in first
  282. * cylinder group.
  283. */
  284. cbase = cgbase(&sblock, cylno);
  285. dmax = cbase + sblock.fs_fpg;
  286. if (dmax > sblock.fs_size)
  287. dmax = sblock.fs_size;
  288. dlower = cgsblock(&sblock, cylno) - cbase;
  289. dupper = cgdmin(&sblock, cylno) - cbase;
  290. if (cylno == 0) /* XXX fscs may be relocated */
  291. dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
  292. cs = &fscs[cylno];
  293. memset(&acg, 0, sblock.fs_cgsize);
  294. acg.cg_time = modtime;
  295. acg.cg_magic = CG_MAGIC;
  296. acg.cg_cgx = cylno;
  297. acg.cg_niblk = sblock.fs_ipg;
  298. acg.cg_initediblk = MIN(sblock.fs_ipg, 2 * INOPB(&sblock));
  299. acg.cg_ndblk = dmax - cbase;
  300. if (sblock.fs_contigsumsize > 0)
  301. acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
  302. start = sizeof(acg);
  303. if (sblock.fs_magic == FS_UFS2_MAGIC) {
  304. acg.cg_iusedoff = start;
  305. } else {
  306. acg.cg_old_ncyl = sblock.fs_old_cpg;
  307. acg.cg_old_time = acg.cg_time;
  308. acg.cg_time = 0;
  309. acg.cg_old_niblk = acg.cg_niblk;
  310. acg.cg_niblk = 0;
  311. acg.cg_initediblk = 0;
  312. acg.cg_old_btotoff = start;
  313. acg.cg_old_boff = acg.cg_old_btotoff +
  314. sblock.fs_old_cpg * sizeof(int32_t);
  315. acg.cg_iusedoff = acg.cg_old_boff +
  316. sblock.fs_old_cpg * sizeof(u_int16_t);
  317. }
  318. acg.cg_freeoff = acg.cg_iusedoff + howmany(sblock.fs_ipg, CHAR_BIT);
  319. acg.cg_nextfreeoff = acg.cg_freeoff + howmany(sblock.fs_fpg, CHAR_BIT);
  320. if (sblock.fs_contigsumsize > 0) {
  321. acg.cg_clustersumoff =
  322. roundup(acg.cg_nextfreeoff, sizeof(u_int32_t));
  323. acg.cg_clustersumoff -= sizeof(u_int32_t);
  324. acg.cg_clusteroff = acg.cg_clustersumoff +
  325. (sblock.fs_contigsumsize + 1) * sizeof(u_int32_t);
  326. acg.cg_nextfreeoff = acg.cg_clusteroff +
  327. howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
  328. }
  329. if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) {
  330. /*
  331. * This should never happen as we would have had that panic
  332. * already on file system creation
  333. */
  334. errx(37, "panic: cylinder group too big");
  335. }
  336. acg.cg_cs.cs_nifree += sblock.fs_ipg;
  337. if (cylno == 0)
  338. for (ino = 0; ino < UFS_ROOTINO; ino++) {
  339. setbit(cg_inosused(&acg), ino);
  340. acg.cg_cs.cs_nifree--;
  341. }
  342. /*
  343. * Initialize the initial inode blocks.
  344. */
  345. dp1 = (struct ufs1_dinode *)(void *)iobuf;
  346. dp2 = (struct ufs2_dinode *)(void *)iobuf;
  347. for (i = 0; i < acg.cg_initediblk; i++) {
  348. if (sblock.fs_magic == FS_UFS1_MAGIC) {
  349. dp1->di_gen = arc4random();
  350. dp1++;
  351. } else {
  352. dp2->di_gen = arc4random();
  353. dp2++;
  354. }
  355. }
  356. wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno)), iobufsize, iobuf,
  357. fso, Nflag);
  358. /*
  359. * For the old file system, we have to initialize all the inodes.
  360. */
  361. if (sblock.fs_magic == FS_UFS1_MAGIC &&
  362. sblock.fs_ipg > 2 * INOPB(&sblock)) {
  363. for (i = 2 * sblock.fs_frag;
  364. i < sblock.fs_ipg / INOPF(&sblock);
  365. i += sblock.fs_frag) {
  366. dp1 = (struct ufs1_dinode *)(void *)iobuf;
  367. for (j = 0; j < INOPB(&sblock); j++) {
  368. dp1->di_gen = arc4random();
  369. dp1++;
  370. }
  371. wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i),
  372. sblock.fs_bsize, iobuf, fso, Nflag);
  373. }
  374. }
  375. if (cylno > 0) {
  376. /*
  377. * In cylno 0, beginning space is reserved
  378. * for boot and super blocks.
  379. */
  380. for (d = 0; d < dlower; d += sblock.fs_frag) {
  381. blkno = d / sblock.fs_frag;
  382. setblock(&sblock, cg_blksfree(&acg), blkno);
  383. if (sblock.fs_contigsumsize > 0)
  384. setbit(cg_clustersfree(&acg), blkno);
  385. acg.cg_cs.cs_nbfree++;
  386. }
  387. sblock.fs_dsize += dlower;
  388. }
  389. sblock.fs_dsize += acg.cg_ndblk - dupper;
  390. sblock.fs_old_dsize = sblock.fs_dsize;
  391. if ((i = dupper % sblock.fs_frag)) {
  392. acg.cg_frsum[sblock.fs_frag - i]++;
  393. for (d = dupper + sblock.fs_frag - i; dupper < d; dupper++) {
  394. setbit(cg_blksfree(&acg), dupper);
  395. acg.cg_cs.cs_nffree++;
  396. }
  397. }
  398. for (d = dupper; d + sblock.fs_frag <= acg.cg_ndblk;
  399. d += sblock.fs_frag) {
  400. blkno = d / sblock.fs_frag;
  401. setblock(&sblock, cg_blksfree(&acg), blkno);
  402. if (sblock.fs_contigsumsize > 0)
  403. setbit(cg_clustersfree(&acg), blkno);
  404. acg.cg_cs.cs_nbfree++;
  405. }
  406. if (d < acg.cg_ndblk) {
  407. acg.cg_frsum[acg.cg_ndblk - d]++;
  408. for (; d < acg.cg_ndblk; d++) {
  409. setbit(cg_blksfree(&acg), d);
  410. acg.cg_cs.cs_nffree++;
  411. }
  412. }
  413. if (sblock.fs_contigsumsize > 0) {
  414. int32_t *sump = cg_clustersum(&acg);
  415. u_char *mapp = cg_clustersfree(&acg);
  416. int map = *mapp++;
  417. int bit = 1;
  418. int run = 0;
  419. for (i = 0; i < acg.cg_nclusterblks; i++) {
  420. if ((map & bit) != 0)
  421. run++;
  422. else if (run != 0) {
  423. if (run > sblock.fs_contigsumsize)
  424. run = sblock.fs_contigsumsize;
  425. sump[run]++;
  426. run = 0;
  427. }
  428. if ((i & (CHAR_BIT - 1)) != CHAR_BIT - 1)
  429. bit <<= 1;
  430. else {
  431. map = *mapp++;
  432. bit = 1;
  433. }
  434. }
  435. if (run != 0) {
  436. if (run > sblock.fs_contigsumsize)
  437. run = sblock.fs_contigsumsize;
  438. sump[run]++;
  439. }
  440. }
  441. sblock.fs_cstotal.cs_ndir += acg.cg_cs.cs_ndir;
  442. sblock.fs_cstotal.cs_nffree += acg.cg_cs.cs_nffree;
  443. sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree;
  444. sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree;
  445. *cs = acg.cg_cs;
  446. cgckhash(&acg);
  447. wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, &acg,
  448. fso, Nflag);
  449. DBG_DUMP_CG(&sblock, "new cg", &acg);
  450. DBG_LEAVE;
  451. return;
  452. }
  453. /*
  454. * Here we add or subtract (sign +1/-1) the available fragments in a given
  455. * block to or from the fragment statistics. By subtracting before and adding
  456. * after an operation on the free frag map we can easy update the fragment
  457. * statistic, which seems to be otherwise a rather complex operation.
  458. */
  459. static void
  460. frag_adjust(ufs2_daddr_t frag, int sign)
  461. {
  462. DBG_FUNC("frag_adjust")
  463. int fragsize;
  464. int f;
  465. DBG_ENTER;
  466. fragsize = 0;
  467. /*
  468. * Here frag only needs to point to any fragment in the block we want
  469. * to examine.
  470. */
  471. for (f = rounddown(frag, sblock.fs_frag);
  472. f < roundup(frag + 1, sblock.fs_frag); f++) {
  473. /*
  474. * Count contiguous free fragments.
  475. */
  476. if (isset(cg_blksfree(&acg), f)) {
  477. fragsize++;
  478. } else {
  479. if (fragsize && fragsize < sblock.fs_frag) {
  480. /*
  481. * We found something in between.
  482. */
  483. acg.cg_frsum[fragsize] += sign;
  484. DBG_PRINT2("frag_adjust [%d]+=%d\n",
  485. fragsize, sign);
  486. }
  487. fragsize = 0;
  488. }
  489. }
  490. if (fragsize && fragsize < sblock.fs_frag) {
  491. /*
  492. * We found something.
  493. */
  494. acg.cg_frsum[fragsize] += sign;
  495. DBG_PRINT2("frag_adjust [%d]+=%d\n", fragsize, sign);
  496. }
  497. DBG_PRINT2("frag_adjust [[%d]]+=%d\n", fragsize, sign);
  498. DBG_LEAVE;
  499. return;
  500. }
  501. /*
  502. * Here we do all needed work for the former last cylinder group. It has to be
  503. * changed in any case, even if the file system ended exactly on the end of
  504. * this group, as there is some slightly inconsistent handling of the number
  505. * of cylinders in the cylinder group. We start again by reading the cylinder
  506. * group from disk. If the last block was not fully available, we first handle
  507. * the missing fragments, then we handle all new full blocks in that file
  508. * system and finally we handle the new last fragmented block in the file
  509. * system. We again have to handle the fragment statistics rotational layout
  510. * tables and cluster summary during all those operations.
  511. */
  512. static void
  513. updjcg(int cylno, time_t modtime, int fsi, int fso, unsigned int Nflag)
  514. {
  515. DBG_FUNC("updjcg")
  516. ufs2_daddr_t cbase, dmax;
  517. struct csum *cs;
  518. int i, k;
  519. int j = 0;
  520. DBG_ENTER;
  521. /*
  522. * Read the former last (joining) cylinder group from disk, and make
  523. * a copy.
  524. */
  525. rdfs(fsbtodb(&osblock, cgtod(&osblock, cylno)),
  526. (size_t)osblock.fs_cgsize, (void *)&aocg, fsi);
  527. DBG_PRINT0("jcg read\n");
  528. DBG_DUMP_CG(&sblock, "old joining cg", &aocg);
  529. memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
  530. /*
  531. * If the cylinder group had already its new final size almost
  532. * nothing is to be done ... except:
  533. * For some reason the value of cg_ncyl in the last cylinder group has
  534. * to be zero instead of fs_cpg. As this is now no longer the last
  535. * cylinder group we have to change that value now to fs_cpg.
  536. */
  537. if (cgbase(&osblock, cylno + 1) == osblock.fs_size) {
  538. if (sblock.fs_magic == FS_UFS1_MAGIC)
  539. acg.cg_old_ncyl = sblock.fs_old_cpg;
  540. cgckhash(&acg);
  541. wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
  542. (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
  543. DBG_PRINT0("jcg written\n");
  544. DBG_DUMP_CG(&sblock, "new joining cg", &acg);
  545. DBG_LEAVE;
  546. return;
  547. }
  548. /*
  549. * Set up some variables needed later.
  550. */
  551. cbase = cgbase(&sblock, cylno);
  552. dmax = cbase + sblock.fs_fpg;
  553. if (dmax > sblock.fs_size)
  554. dmax = sblock.fs_size;
  555. /*
  556. * Set pointer to the cylinder summary for our cylinder group.
  557. */
  558. cs = fscs + cylno;
  559. /*
  560. * Touch the cylinder group, update all fields in the cylinder group as
  561. * needed, update the free space in the superblock.
  562. */
  563. acg.cg_time = modtime;
  564. if ((unsigned)cylno == sblock.fs_ncg - 1) {
  565. /*
  566. * This is still the last cylinder group.
  567. */
  568. if (sblock.fs_magic == FS_UFS1_MAGIC)
  569. acg.cg_old_ncyl =
  570. sblock.fs_old_ncyl % sblock.fs_old_cpg;
  571. } else {
  572. acg.cg_old_ncyl = sblock.fs_old_cpg;
  573. }
  574. DBG_PRINT2("jcg dbg: %d %u", cylno, sblock.fs_ncg);
  575. #ifdef FS_DEBUG
  576. if (sblock.fs_magic == FS_UFS1_MAGIC)
  577. DBG_PRINT2("%d %u", acg.cg_old_ncyl, sblock.fs_old_cpg);
  578. #endif
  579. DBG_PRINT0("\n");
  580. acg.cg_ndblk = dmax - cbase;
  581. sblock.fs_dsize += acg.cg_ndblk - aocg.cg_ndblk;
  582. sblock.fs_old_dsize = sblock.fs_dsize;
  583. if (sblock.fs_contigsumsize > 0)
  584. acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
  585. /*
  586. * Now we have to update the free fragment bitmap for our new free
  587. * space. There again we have to handle the fragmentation and also
  588. * the rotational layout tables and the cluster summary. This is
  589. * also done per fragment for the first new block if the old file
  590. * system end was not on a block boundary, per fragment for the new
  591. * last block if the new file system end is not on a block boundary,
  592. * and per block for all space in between.
  593. *
  594. * Handle the first new block here if it was partially available
  595. * before.
  596. */
  597. if (osblock.fs_size % sblock.fs_frag) {
  598. if (roundup(osblock.fs_size, sblock.fs_frag) <=
  599. sblock.fs_size) {
  600. /*
  601. * The new space is enough to fill at least this
  602. * block
  603. */
  604. j = 0;
  605. for (i = roundup(osblock.fs_size - cbase,
  606. sblock.fs_frag) - 1; i >= osblock.fs_size - cbase;
  607. i--) {
  608. setbit(cg_blksfree(&acg), i);
  609. acg.cg_cs.cs_nffree++;
  610. j++;
  611. }
  612. /*
  613. * Check if the fragment just created could join an
  614. * already existing fragment at the former end of the
  615. * file system.
  616. */
  617. if (isblock(&sblock, cg_blksfree(&acg),
  618. ((osblock.fs_size - cgbase(&sblock, cylno)) /
  619. sblock.fs_frag))) {
  620. /*
  621. * The block is now completely available.
  622. */
  623. DBG_PRINT0("block was\n");
  624. acg.cg_frsum[osblock.fs_size % sblock.fs_frag]--;
  625. acg.cg_cs.cs_nbfree++;
  626. acg.cg_cs.cs_nffree -= sblock.fs_frag;
  627. k = rounddown(osblock.fs_size - cbase,
  628. sblock.fs_frag);
  629. updclst((osblock.fs_size - cbase) /
  630. sblock.fs_frag);
  631. } else {
  632. /*
  633. * Lets rejoin a possible partially grown
  634. * fragment.
  635. */
  636. k = 0;
  637. while (isset(cg_blksfree(&acg), i) &&
  638. (i >= rounddown(osblock.fs_size - cbase,
  639. sblock.fs_frag))) {
  640. i--;
  641. k++;
  642. }
  643. if (k)
  644. acg.cg_frsum[k]--;
  645. acg.cg_frsum[k + j]++;
  646. }
  647. } else {
  648. /*
  649. * We only grow by some fragments within this last
  650. * block.
  651. */
  652. for (i = sblock.fs_size - cbase - 1;
  653. i >= osblock.fs_size - cbase; i--) {
  654. setbit(cg_blksfree(&acg), i);
  655. acg.cg_cs.cs_nffree++;
  656. j++;
  657. }
  658. /*
  659. * Lets rejoin a possible partially grown fragment.
  660. */
  661. k = 0;
  662. while (isset(cg_blksfree(&acg), i) &&
  663. (i >= rounddown(osblock.fs_size - cbase,
  664. sblock.fs_frag))) {
  665. i--;
  666. k++;
  667. }
  668. if (k)
  669. acg.cg_frsum[k]--;
  670. acg.cg_frsum[k + j]++;
  671. }
  672. }
  673. /*
  674. * Handle all new complete blocks here.
  675. */
  676. for (i = roundup(osblock.fs_size - cbase, sblock.fs_frag);
  677. i + sblock.fs_frag <= dmax - cbase; /* XXX <= or only < ? */
  678. i += sblock.fs_frag) {
  679. j = i / sblock.fs_frag;
  680. setblock(&sblock, cg_blksfree(&acg), j);
  681. updclst(j);
  682. acg.cg_cs.cs_nbfree++;
  683. }
  684. /*
  685. * Handle the last new block if there are still some new fragments left.
  686. * Here we don't have to bother about the cluster summary or the even
  687. * the rotational layout table.
  688. */
  689. if (i < (dmax - cbase)) {
  690. acg.cg_frsum[dmax - cbase - i]++;
  691. for (; i < dmax - cbase; i++) {
  692. setbit(cg_blksfree(&acg), i);
  693. acg.cg_cs.cs_nffree++;
  694. }
  695. }
  696. sblock.fs_cstotal.cs_nffree +=
  697. (acg.cg_cs.cs_nffree - aocg.cg_cs.cs_nffree);
  698. sblock.fs_cstotal.cs_nbfree +=
  699. (acg.cg_cs.cs_nbfree - aocg.cg_cs.cs_nbfree);
  700. /*
  701. * The following statistics are not changed here:
  702. * sblock.fs_cstotal.cs_ndir
  703. * sblock.fs_cstotal.cs_nifree
  704. * As the statistics for this cylinder group are ready, copy it to
  705. * the summary information array.
  706. */
  707. *cs = acg.cg_cs;
  708. /*
  709. * Write the updated "joining" cylinder group back to disk.
  710. */
  711. cgckhash(&acg);
  712. wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), (size_t)sblock.fs_cgsize,
  713. (void *)&acg, fso, Nflag);
  714. DBG_PRINT0("jcg written\n");
  715. DBG_DUMP_CG(&sblock, "new joining cg", &acg);
  716. DBG_LEAVE;
  717. return;
  718. }
  719. /*
  720. * Here we update the location of the cylinder summary. We have two possible
  721. * ways of growing the cylinder summary:
  722. * (1) We can try to grow the summary in the current location, and relocate
  723. * possibly used blocks within the current cylinder group.
  724. * (2) Alternatively we can relocate the whole cylinder summary to the first
  725. * new completely empty cylinder group. Once the cylinder summary is no
  726. * longer in the beginning of the first cylinder group you should never
  727. * use a version of fsck which is not aware of the possibility to have
  728. * this structure in a non standard place.
  729. * Option (2) is considered to be less intrusive to the structure of the file-
  730. * system, so that's the one being used.
  731. */
  732. static void
  733. updcsloc(time_t modtime, int fsi, int fso, unsigned int Nflag)
  734. {
  735. DBG_FUNC("updcsloc")
  736. struct csum *cs;
  737. int ocscg, ncscg;
  738. ufs2_daddr_t d;
  739. int lcs = 0;
  740. int block;
  741. DBG_ENTER;
  742. if (howmany(sblock.fs_cssize, sblock.fs_fsize) ==
  743. howmany(osblock.fs_cssize, osblock.fs_fsize)) {
  744. /*
  745. * No new fragment needed.
  746. */
  747. DBG_LEAVE;
  748. return;
  749. }
  750. /* Adjust fs_dsize by added summary blocks */
  751. sblock.fs_dsize -= howmany(sblock.fs_cssize, sblock.fs_fsize) -
  752. howmany(osblock.fs_cssize, osblock.fs_fsize);
  753. sblock.fs_old_dsize = sblock.fs_dsize;
  754. ocscg = dtog(&osblock, osblock.fs_csaddr);
  755. cs = fscs + ocscg;
  756. /*
  757. * Read original cylinder group from disk, and make a copy.
  758. * XXX If Nflag is set in some very rare cases we now miss
  759. * some changes done in updjcg by reading the unmodified
  760. * block from disk.
  761. */
  762. rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)),
  763. (size_t)osblock.fs_cgsize, (void *)&aocg, fsi);
  764. DBG_PRINT0("oscg read\n");
  765. DBG_DUMP_CG(&sblock, "old summary cg", &aocg);
  766. memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
  767. /*
  768. * Touch the cylinder group, set up local variables needed later
  769. * and update the superblock.
  770. */
  771. acg.cg_time = modtime;
  772. /*
  773. * XXX In the case of having active snapshots we may need much more
  774. * blocks for the copy on write. We need each block twice, and
  775. * also up to 8*3 blocks for indirect blocks for all possible
  776. * references.
  777. */
  778. /*
  779. * There is not enough space in the old cylinder group to
  780. * relocate all blocks as needed, so we relocate the whole
  781. * cylinder group summary to a new group. We try to use the
  782. * first complete new cylinder group just created. Within the
  783. * cylinder group we align the area immediately after the
  784. * cylinder group information location in order to be as
  785. * close as possible to the original implementation of ffs.
  786. *
  787. * First we have to make sure we'll find enough space in the
  788. * new cylinder group. If not, then we currently give up.
  789. * We start with freeing everything which was used by the
  790. * fragments of the old cylinder summary in the current group.
  791. * Now we write back the group meta data, read in the needed
  792. * meta data from the new cylinder group, and start allocating
  793. * within that group. Here we can assume, the group to be
  794. * completely empty. Which makes the handling of fragments and
  795. * clusters a lot easier.
  796. */
  797. DBG_TRC;
  798. if (sblock.fs_ncg - osblock.fs_ncg < 2)
  799. errx(2, "panic: not enough space");
  800. /*
  801. * Point "d" to the first fragment not used by the cylinder
  802. * summary.
  803. */
  804. d = osblock.fs_csaddr + (osblock.fs_cssize / osblock.fs_fsize);
  805. /*
  806. * Set up last cluster size ("lcs") already here. Calculate
  807. * the size for the trailing cluster just behind where "d"
  808. * points to.
  809. */
  810. if (sblock.fs_contigsumsize > 0) {
  811. for (block = howmany(d % sblock.fs_fpg, sblock.fs_frag),
  812. lcs = 0; lcs < sblock.fs_contigsumsize; block++, lcs++) {
  813. if (isclr(cg_clustersfree(&acg), block))
  814. break;
  815. }
  816. }
  817. /*
  818. * Point "d" to the last frag used by the cylinder summary.
  819. */
  820. d--;
  821. DBG_PRINT1("d=%jd\n", (intmax_t)d);
  822. if ((d + 1) % sblock.fs_frag) {
  823. /*
  824. * The end of the cylinder summary is not a complete
  825. * block.
  826. */
  827. DBG_TRC;
  828. frag_adjust(d % sblock.fs_fpg, -1);
  829. for (; (d + 1) % sblock.fs_frag; d--) {
  830. DBG_PRINT1("d=%jd\n", (intmax_t)d);
  831. setbit(cg_blksfree(&acg), d % sblock.fs_fpg);
  832. acg.cg_cs.cs_nffree++;
  833. sblock.fs_cstotal.cs_nffree++;
  834. }
  835. /*
  836. * Point "d" to the last fragment of the last
  837. * (incomplete) block of the cylinder summary.
  838. */
  839. d++;
  840. frag_adjust(d % sblock.fs_fpg, 1);
  841. if (isblock(&sblock, cg_blksfree(&acg),
  842. (d % sblock.fs_fpg) / sblock.fs_frag)) {
  843. DBG_PRINT1("d=%jd\n", (intmax_t)d);
  844. acg.cg_cs.cs_nffree -= sblock.fs_frag;
  845. acg.cg_cs.cs_nbfree++;
  846. sblock.fs_cstotal.cs_nffree -= sblock.fs_frag;
  847. sblock.fs_cstotal.cs_nbfree++;
  848. if (sblock.fs_contigsumsize > 0) {
  849. setbit(cg_clustersfree(&acg),
  850. (d % sblock.fs_fpg) / sblock.fs_frag);
  851. if (lcs < sblock.fs_contigsumsize) {
  852. if (lcs)
  853. cg_clustersum(&acg)[lcs]--;
  854. lcs++;
  855. cg_clustersum(&acg)[lcs]++;
  856. }
  857. }
  858. }
  859. /*
  860. * Point "d" to the first fragment of the block before
  861. * the last incomplete block.
  862. */
  863. d--;
  864. }
  865. DBG_PRINT1("d=%jd\n", (intmax_t)d);
  866. for (d = rounddown(d, sblock.fs_frag); d >= osblock.fs_csaddr;
  867. d -= sblock.fs_frag) {
  868. DBG_TRC;
  869. DBG_PRINT1("d=%jd\n", (intmax_t)d);
  870. setblock(&sblock, cg_blksfree(&acg),
  871. (d % sblock.fs_fpg) / sblock.fs_frag);
  872. acg.cg_cs.cs_nbfree++;
  873. sblock.fs_cstotal.cs_nbfree++;
  874. if (sblock.fs_contigsumsize > 0) {
  875. setbit(cg_clustersfree(&acg),
  876. (d % sblock.fs_fpg) / sblock.fs_frag);
  877. /*
  878. * The last cluster size is already set up.
  879. */
  880. if (lcs < sblock.fs_contigsumsize) {
  881. if (lcs)
  882. cg_clustersum(&acg)[lcs]--;
  883. lcs++;
  884. cg_clustersum(&acg)[lcs]++;
  885. }
  886. }
  887. }
  888. *cs = acg.cg_cs;
  889. /*
  890. * Now write the former cylinder group containing the cylinder
  891. * summary back to disk.
  892. */
  893. cgckhash(&acg);
  894. wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)),
  895. (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
  896. DBG_PRINT0("oscg written\n");
  897. DBG_DUMP_CG(&sblock, "old summary cg", &acg);
  898. /*
  899. * Find the beginning of the new cylinder group containing the
  900. * cylinder summary.
  901. */
  902. sblock.fs_csaddr = cgdmin(&sblock, osblock.fs_ncg);
  903. ncscg = dtog(&sblock, sblock.fs_csaddr);
  904. cs = fscs + ncscg;
  905. /*
  906. * If Nflag is specified, we would now read random data instead
  907. * of an empty cg structure from disk. So we can't simulate that
  908. * part for now.
  909. */
  910. if (Nflag) {
  911. DBG_PRINT0("nscg update skipped\n");
  912. DBG_LEAVE;
  913. return;
  914. }
  915. /*
  916. * Read the future cylinder group containing the cylinder
  917. * summary from disk, and make a copy.
  918. */
  919. rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
  920. (size_t)sblock.fs_cgsize, (void *)&aocg, fsi);
  921. DBG_PRINT0("nscg read\n");
  922. DBG_DUMP_CG(&sblock, "new summary cg", &aocg);
  923. memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
  924. /*
  925. * Allocate all complete blocks used by the new cylinder
  926. * summary.
  927. */
  928. for (d = sblock.fs_csaddr; d + sblock.fs_frag <=
  929. sblock.fs_csaddr + (sblock.fs_cssize / sblock.fs_fsize);
  930. d += sblock.fs_frag) {
  931. clrblock(&sblock, cg_blksfree(&acg),
  932. (d % sblock.fs_fpg) / sblock.fs_frag);
  933. acg.cg_cs.cs_nbfree--;
  934. sblock.fs_cstotal.cs_nbfree--;
  935. if (sblock.fs_contigsumsize > 0) {
  936. clrbit(cg_clustersfree(&acg),
  937. (d % sblock.fs_fpg) / sblock.fs_frag);
  938. }
  939. }
  940. /*
  941. * Allocate all fragments used by the cylinder summary in the
  942. * last block.
  943. */
  944. if (d < sblock.fs_csaddr + (sblock.fs_cssize / sblock.fs_fsize)) {
  945. for (; d - sblock.fs_csaddr <
  946. sblock.fs_cssize/sblock.fs_fsize; d++) {
  947. clrbit(cg_blksfree(&acg), d % sblock.fs_fpg);
  948. acg.cg_cs.cs_nffree--;
  949. sblock.fs_cstotal.cs_nffree--;
  950. }
  951. acg.cg_cs.cs_nbfree--;
  952. acg.cg_cs.cs_nffree += sblock.fs_frag;
  953. sblock.fs_cstotal.cs_nbfree--;
  954. sblock.fs_cstotal.cs_nffree += sblock.fs_frag;
  955. if (sblock.fs_contigsumsize > 0)
  956. clrbit(cg_clustersfree(&acg),
  957. (d % sblock.fs_fpg) / sblock.fs_frag);
  958. frag_adjust(d % sblock.fs_fpg, 1);
  959. }
  960. /*
  961. * XXX Handle the cluster statistics here in the case this
  962. * cylinder group is now almost full, and the remaining
  963. * space is less then the maximum cluster size. This is
  964. * probably not needed, as you would hardly find a file
  965. * system which has only MAXCSBUFS+FS_MAXCONTIG of free
  966. * space right behind the cylinder group information in
  967. * any new cylinder group.
  968. */
  969. /*
  970. * Update our statistics in the cylinder summary.
  971. */
  972. *cs = acg.cg_cs;
  973. /*
  974. * Write the new cylinder group containing the cylinder summary
  975. * back to disk.
  976. */
  977. cgckhash(&acg);
  978. wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
  979. (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag);
  980. DBG_PRINT0("nscg written\n");
  981. DBG_DUMP_CG(&sblock, "new summary cg", &acg);
  982. DBG_LEAVE;
  983. return;
  984. }
  985. /*
  986. * Here we read some block(s) from disk.
  987. */
  988. static void
  989. rdfs(ufs2_daddr_t bno, size_t size, void *bf, int fsi)
  990. {
  991. DBG_FUNC("rdfs")
  992. ssize_t n;
  993. DBG_ENTER;
  994. if (bno < 0)
  995. err(32, "rdfs: attempting to read negative block number");
  996. if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0)
  997. err(33, "rdfs: seek error: %jd", (intmax_t)bno);
  998. n = read(fsi, bf, size);
  999. if (n != (ssize_t)size)
  1000. err(34, "rdfs: read error: %jd", (intmax_t)bno);
  1001. DBG_LEAVE;
  1002. return;
  1003. }
  1004. /*
  1005. * Here we write some block(s) to disk.
  1006. */
  1007. static void
  1008. wtfs(ufs2_daddr_t bno, size_t size, void *bf, int fso, unsigned int Nflag)
  1009. {
  1010. DBG_FUNC("wtfs")
  1011. ssize_t n;
  1012. DBG_ENTER;
  1013. if (Nflag) {
  1014. DBG_LEAVE;
  1015. return;
  1016. }
  1017. if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0)
  1018. err(35, "wtfs: seek error: %ld", (long)bno);
  1019. n = write(fso, bf, size);
  1020. if (n != (ssize_t)size)
  1021. err(36, "wtfs: write error: %ld", (long)bno);
  1022. DBG_LEAVE;
  1023. return;
  1024. }
  1025. /*
  1026. * Here we check if all frags of a block are free. For more details again
  1027. * please see the source of newfs(8), as this function is taken over almost
  1028. * unchanged.
  1029. */
  1030. static int
  1031. isblock(struct fs *fs, unsigned char *cp, int h)
  1032. {
  1033. DBG_FUNC("isblock")
  1034. unsigned char mask;
  1035. DBG_ENTER;
  1036. switch (fs->fs_frag) {
  1037. case 8:
  1038. DBG_LEAVE;
  1039. return (cp[h] == 0xff);
  1040. case 4:
  1041. mask = 0x0f << ((h & 0x1) << 2);
  1042. DBG_LEAVE;
  1043. return ((cp[h >> 1] & mask) == mask);
  1044. case 2:
  1045. mask = 0x03 << ((h & 0x3) << 1);
  1046. DBG_LEAVE;
  1047. return ((cp[h >> 2] & mask) == mask);
  1048. case 1:
  1049. mask = 0x01 << (h & 0x7);
  1050. DBG_LEAVE;
  1051. return ((cp[h >> 3] & mask) == mask);
  1052. default:
  1053. fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
  1054. DBG_LEAVE;
  1055. return (0);
  1056. }
  1057. }
  1058. /*
  1059. * Here we allocate a complete block in the block map. For more details again
  1060. * please see the source of newfs(8), as this function is taken over almost
  1061. * unchanged.
  1062. */
  1063. static void
  1064. clrblock(struct fs *fs, unsigned char *cp, int h)
  1065. {
  1066. DBG_FUNC("clrblock")
  1067. DBG_ENTER;
  1068. switch ((fs)->fs_frag) {
  1069. case 8:
  1070. cp[h] = 0;
  1071. break;
  1072. case 4:
  1073. cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
  1074. break;
  1075. case 2:
  1076. cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
  1077. break;
  1078. case 1:
  1079. cp[h >> 3] &= ~(0x01 << (h & 0x7));
  1080. break;
  1081. default:
  1082. warnx("clrblock bad fs_frag %d", fs->fs_frag);
  1083. break;
  1084. }
  1085. DBG_LEAVE;
  1086. return;
  1087. }
  1088. /*
  1089. * Here we free a complete block in the free block map. For more details again
  1090. * please see the source of newfs(8), as this function is taken over almost
  1091. * unchanged.
  1092. */
  1093. static void
  1094. setblock(struct fs *fs, unsigned char *cp, int h)
  1095. {
  1096. DBG_FUNC("setblock")
  1097. DBG_ENTER;
  1098. switch (fs->fs_frag) {
  1099. case 8:
  1100. cp[h] = 0xff;
  1101. break;
  1102. case 4:
  1103. cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
  1104. break;
  1105. case 2:
  1106. cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
  1107. break;
  1108. case 1:
  1109. cp[h >> 3] |= (0x01 << (h & 0x7));
  1110. break;
  1111. default:
  1112. warnx("setblock bad fs_frag %d", fs->fs_frag);
  1113. break;
  1114. }
  1115. DBG_LEAVE;
  1116. return;
  1117. }
  1118. /*
  1119. * Figure out how many lines our current terminal has. For more details again
  1120. * please see the source of newfs(8), as this function is taken over almost
  1121. * unchanged.
  1122. */
  1123. static int
  1124. charsperline(void)
  1125. {
  1126. DBG_FUNC("charsperline")
  1127. int columns;
  1128. char *cp;
  1129. struct winsize ws;
  1130. DBG_ENTER;
  1131. columns = 0;
  1132. if (ioctl(0, TIOCGWINSZ, &ws) != -1)
  1133. columns = ws.ws_col;
  1134. if (columns == 0 && (cp = getenv("COLUMNS")))
  1135. columns = atoi(cp);
  1136. if (columns == 0)
  1137. columns = 80; /* last resort */
  1138. DBG_LEAVE;
  1139. return (columns);
  1140. }
  1141. static int
  1142. is_dev(const char *name)
  1143. {
  1144. struct stat devstat;
  1145. if (stat(name, &devstat) != 0)
  1146. return (0);
  1147. if (!S_ISCHR(devstat.st_mode))
  1148. return (0);
  1149. return (1);
  1150. }
  1151. static const char *
  1152. getdev(const char *name, struct statfs *statfsp)
  1153. {
  1154. static char device[MAXPATHLEN];
  1155. const char *cp;
  1156. if (is_dev(name))
  1157. return (name);
  1158. cp = strrchr(name, '/');
  1159. if (cp == NULL) {
  1160. snprintf(device, sizeof(device), "%s%s", _PATH_DEV, name);
  1161. if (is_dev(device))
  1162. return (device);
  1163. }
  1164. if (statfsp != NULL)
  1165. return (statfsp->f_mntfromname);
  1166. return (NULL);
  1167. }
  1168. /*
  1169. * growfs(8) is a utility which allows to increase the size of an existing
  1170. * ufs file system. Currently this can only be done on unmounted file system.
  1171. * It recognizes some command line options to specify the new desired size,
  1172. * and it does some basic checkings. The old file system size is determined
  1173. * and after some more checks like we can really access the new last block
  1174. * on the disk etc. we calculate the new parameters for the superblock. After
  1175. * having done this we just call growfs() which will do the work.
  1176. * We still have to provide support for snapshots. Therefore we first have to
  1177. * understand what data structures are always replicated in the snapshot on
  1178. * creation, for all other blocks we touch during our procedure, we have to
  1179. * keep the old blocks unchanged somewhere available for the snapshots. If we
  1180. * are lucky, then we only have to handle our blocks to be relocated in that
  1181. * way.
  1182. * Also we have to consider in what order we actually update the critical
  1183. * data structures of the file system to make sure, that in case of a disaster
  1184. * fsck(8) is still able to restore any lost data.
  1185. * The foreseen last step then will be to provide for growing even mounted
  1186. * file systems. There we have to extend the mount() system call to provide
  1187. * userland access to the file system locking facility.
  1188. */
  1189. int
  1190. main(int argc, char **argv)
  1191. {
  1192. DBG_FUNC("main")
  1193. struct fs *fs;
  1194. const char *device;
  1195. struct statfs *statfsp;
  1196. uint64_t size = 0;
  1197. off_t mediasize;
  1198. int error, j, fsi, fso, ch, ret, Nflag = 0, yflag = 0;
  1199. char *p, reply[5], oldsizebuf[6], newsizebuf[6];
  1200. void *testbuf;
  1201. DBG_ENTER;
  1202. while ((ch = getopt(argc, argv, "Ns:vy")) != -1) {
  1203. switch(ch) {
  1204. case 'N':
  1205. Nflag = 1;
  1206. break;
  1207. case 's':
  1208. size = (off_t)strtoumax(optarg, &p, 0);
  1209. if (p == NULL || *p == '\0')
  1210. size *= DEV_BSIZE;
  1211. else if (*p == 'b' || *p == 'B')
  1212. ; /* do nothing */
  1213. else if (*p == 'k' || *p == 'K')
  1214. size <<= 10;
  1215. else if (*p == 'm' || *p == 'M')
  1216. size <<= 20;
  1217. else if (*p == 'g' || *p == 'G')
  1218. size <<= 30;
  1219. else if (*p == 't' || *p == 'T') {
  1220. size <<= 30;
  1221. size <<= 10;
  1222. } else
  1223. errx(2, "unknown suffix on -s argument");
  1224. break;
  1225. case 'v': /* for compatibility to newfs */
  1226. break;
  1227. case 'y':
  1228. yflag = 1;
  1229. break;
  1230. case '?':
  1231. /* FALLTHROUGH */
  1232. default:
  1233. usage();
  1234. }
  1235. }
  1236. argc -= optind;
  1237. argv += optind;
  1238. if (argc != 1)
  1239. usage();
  1240. /*
  1241. * Now try to guess the device name.
  1242. */
  1243. statfsp = getmntpoint(*argv);
  1244. device = getdev(*argv, statfsp);
  1245. if (device == NULL)
  1246. errx(2, "cannot find special device for %s", *argv);
  1247. fsi = open(device, O_RDONLY);
  1248. if (fsi < 0)
  1249. err(3, "%s", device);
  1250. /*
  1251. * Try to guess the slice size if not specified.
  1252. */
  1253. if (ioctl(fsi, DIOCGMEDIASIZE, &mediasize) == -1)
  1254. err(3,"DIOCGMEDIASIZE");
  1255. /*
  1256. * Check if that partition is suitable for growing a file system.
  1257. */
  1258. if (mediasize < 1)
  1259. errx(2, "partition is unavailable");
  1260. /*
  1261. * Read the current superblock, and take a backup.
  1262. */
  1263. if ((ret = sbget(fsi, &fs, UFS_STDSB, 0)) != 0) {
  1264. switch (ret) {
  1265. case ENOENT:
  1266. errx(2, "superblock not recognized");
  1267. default:
  1268. errc(3, ret, "unable to read superblock");
  1269. }
  1270. }
  1271. /*
  1272. * Check for filesystem that was unclean at mount time.
  1273. */
  1274. if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) != 0)
  1275. errx(2, "%s is not clean - run fsck.\n", *argv);
  1276. memcpy(&osblock, fs, fs->fs_sbsize);
  1277. free(fs);
  1278. memcpy((void *)&fsun1, (void *)&fsun2, osblock.fs_sbsize);
  1279. DBG_OPEN("/tmp/growfs.debug"); /* already here we need a superblock */
  1280. DBG_DUMP_FS(&sblock, "old sblock");
  1281. /*
  1282. * Determine size to grow to. Default to the device size.
  1283. */
  1284. if (size == 0)
  1285. size = mediasize;
  1286. else {
  1287. if (size > (uint64_t)mediasize) {
  1288. humanize_number(oldsizebuf, sizeof(oldsizebuf), size,
  1289. "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  1290. humanize_number(newsizebuf, sizeof(newsizebuf),
  1291. mediasize,
  1292. "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  1293. errx(2, "requested size %s is larger "
  1294. "than the available %s", oldsizebuf, newsizebuf);
  1295. }
  1296. }
  1297. /*
  1298. * Make sure the new size is a multiple of fs_fsize; /dev/ufssuspend
  1299. * only supports fragment-aligned IO requests.
  1300. */
  1301. size -= size % osblock.fs_fsize;
  1302. if (size <= (uint64_t)(osblock.fs_size * osblock.fs_fsize)) {
  1303. humanize_number(oldsizebuf, sizeof(oldsizebuf),
  1304. osblock.fs_size * osblock.fs_fsize,
  1305. "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  1306. humanize_number(newsizebuf, sizeof(newsizebuf), size,
  1307. "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  1308. if (size == (uint64_t)(osblock.fs_size * osblock.fs_fsize))
  1309. errx(0, "requested size %s is equal to the current "
  1310. "filesystem size %s", newsizebuf, oldsizebuf);
  1311. errx(2, "requested size %s is smaller than the current "
  1312. "filesystem size %s", newsizebuf, oldsizebuf);
  1313. }
  1314. sblock.fs_old_size = sblock.fs_size =
  1315. dbtofsb(&osblock, size / DEV_BSIZE);
  1316. sblock.fs_providersize = dbtofsb(&osblock, mediasize / DEV_BSIZE);
  1317. /*
  1318. * Are we really growing?
  1319. */
  1320. if (osblock.fs_size >= sblock.fs_size) {
  1321. errx(3, "we are not growing (%jd->%jd)",
  1322. (intmax_t)osblock.fs_size, (intmax_t)sblock.fs_size);
  1323. }
  1324. /*
  1325. * Check if we find an active snapshot.
  1326. */
  1327. if (yflag == 0) {
  1328. for (j = 0; j < FSMAXSNAP; j++) {
  1329. if (sblock.fs_snapinum[j]) {
  1330. errx(2, "active snapshot found in file system; "
  1331. "please remove all snapshots before "
  1332. "using growfs");
  1333. }
  1334. if (!sblock.fs_snapinum[j]) /* list is dense */
  1335. break;
  1336. }
  1337. }
  1338. if (yflag == 0 && Nflag == 0) {
  1339. if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0)
  1340. printf("Device is mounted read-write; resizing will "
  1341. "result in temporary write suspension for %s.\n",
  1342. statfsp->f_mntonname);
  1343. printf("It's strongly recommended to make a backup "
  1344. "before growing the file system.\n"
  1345. "OK to grow filesystem on %s", device);
  1346. if (statfsp != NULL)
  1347. printf(", mounted on %s,", statfsp->f_mntonname);
  1348. humanize_number(oldsizebuf, sizeof(oldsizebuf),
  1349. osblock.fs_size * osblock.fs_fsize,
  1350. "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  1351. humanize_number(newsizebuf, sizeof(newsizebuf),
  1352. sblock.fs_size * sblock.fs_fsize,
  1353. "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  1354. printf(" from %s to %s? [yes/no] ", oldsizebuf, newsizebuf);
  1355. fflush(stdout);
  1356. fgets(reply, (int)sizeof(reply), stdin);
  1357. if (strcasecmp(reply, "yes\n")){
  1358. printf("Response other than \"yes\"; aborting\n");
  1359. exit(0);
  1360. }
  1361. }
  1362. /*
  1363. * Try to access our device for writing. If it's not mounted,
  1364. * or mounted read-only, simply open it; otherwise, use UFS
  1365. * suspension mechanism.
  1366. */
  1367. if (Nflag) {
  1368. fso = -1;
  1369. } else {
  1370. if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) {
  1371. fso = open(_PATH_UFSSUSPEND, O_RDWR);
  1372. if (fso == -1)
  1373. err(3, "unable to open %s", _PATH_UFSSUSPEND);
  1374. error = ioctl(fso, UFSSUSPEND, &statfsp->f_fsid);
  1375. if (error != 0)
  1376. err(3, "UFSSUSPEND");
  1377. } else {
  1378. fso = open(device, O_WRONLY);
  1379. if (fso < 0)
  1380. err(3, "%s", device);
  1381. }
  1382. }
  1383. /*
  1384. * Try to access our new last block in the file system.
  1385. */
  1386. testbuf = malloc(sblock.fs_fsize);
  1387. if (testbuf == NULL)
  1388. err(3, "malloc");
  1389. rdfs((ufs2_daddr_t)((size - sblock.fs_fsize) / DEV_BSIZE),
  1390. sblock.fs_fsize, testbuf, fsi);
  1391. wtfs((ufs2_daddr_t)((size - sblock.fs_fsize) / DEV_BSIZE),
  1392. sblock.fs_fsize, testbuf, fso, Nflag);
  1393. free(testbuf);
  1394. /*
  1395. * Now calculate new superblock values and check for reasonable
  1396. * bound for new file system size:
  1397. * fs_size: is derived from user input
  1398. * fs_dsize: should get updated in the routines creating or
  1399. * updating the cylinder groups on the fly
  1400. * fs_cstotal: should get updated in the routines creating or
  1401. * updating the cylinder groups
  1402. */
  1403. /*
  1404. * Update the number of cylinders and cylinder groups in the file system.
  1405. */
  1406. if (sblock.fs_magic == FS_UFS1_MAGIC) {
  1407. sblock.fs_old_ncyl =
  1408. sblock.fs_size * sblock.fs_old_nspf / sblock.fs_old_spc;
  1409. if (sblock.fs_size * sblock.fs_old_nspf >
  1410. sblock.fs_old_ncyl * sblock.fs_old_spc)
  1411. sblock.fs_old_ncyl++;
  1412. }
  1413. sblock.fs_ncg = howmany(sblock.fs_size, sblock.fs_fpg);
  1414. /*
  1415. * Allocate last cylinder group only if there is enough room
  1416. * for at least one data block.
  1417. */
  1418. if (sblock.fs_size % sblock.fs_fpg != 0 &&
  1419. sblock.fs_size <= cgdmin(&sblock, sblock.fs_ncg - 1)) {
  1420. humanize_number(oldsizebuf, sizeof(oldsizebuf),
  1421. (sblock.fs_size % sblock.fs_fpg) * sblock.fs_fsize,
  1422. "B", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
  1423. warnx("no room to allocate last cylinder group; "
  1424. "leaving %s unused", oldsizebuf);
  1425. sblock.fs_ncg--;
  1426. if (sblock.fs_magic == FS_UFS1_MAGIC)
  1427. sblock.fs_old_ncyl = sblock.fs_ncg * sblock.fs_old_cpg;
  1428. sblock.fs_old_size = sblock.fs_size =
  1429. sblock.fs_ncg * sblock.fs_fpg;
  1430. }
  1431. /*
  1432. * Update the space for the cylinder group summary information in the
  1433. * respective cylinder group data area.
  1434. */
  1435. sblock.fs_cssize =
  1436. fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum));
  1437. if (osblock.fs_size >= sblock.fs_size)
  1438. errx(3, "not enough new space");
  1439. DBG_PRINT0("sblock calculated\n");
  1440. /*
  1441. * Ok, everything prepared, so now let's do the tricks.
  1442. */
  1443. growfs(fsi, fso, Nflag);
  1444. close(fsi);
  1445. if (fso > -1) {
  1446. if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) == 0) {
  1447. error = ioctl(fso, UFSRESUME);
  1448. if (error != 0)
  1449. err(3, "UFSRESUME");
  1450. }
  1451. error = close(fso);
  1452. if (error != 0)
  1453. err(3, "close");
  1454. if (statfsp != NULL && (statfsp->f_flags & MNT_RDONLY) != 0 &&
  1455. chkdoreload(statfsp, warn) != 0)
  1456. exit(9);
  1457. }
  1458. DBG_CLOSE;
  1459. DBG_LEAVE;
  1460. return (0);
  1461. }
  1462. /*
  1463. * Dump a line of usage.
  1464. */
  1465. static void
  1466. usage(void)
  1467. {
  1468. DBG_FUNC("usage")
  1469. DBG_ENTER;
  1470. fprintf(stderr, "usage: growfs [-Ny] [-s size] special | filesystem\n");
  1471. DBG_LEAVE;
  1472. exit(1);
  1473. }
  1474. /*
  1475. * This updates most parameters and the bitmap related to cluster. We have to
  1476. * assume that sblock, osblock, acg are set up.
  1477. */
  1478. static void
  1479. updclst(int block)
  1480. {
  1481. DBG_FUNC("updclst")
  1482. static int lcs = 0;
  1483. DBG_ENTER;
  1484. if (sblock.fs_contigsumsize < 1) /* no clustering */
  1485. return;
  1486. /*
  1487. * update cluster allocation map
  1488. */
  1489. setbit(cg_clustersfree(&acg), block);
  1490. /*
  1491. * update cluster summary table
  1492. */
  1493. if (!lcs) {
  1494. /*
  1495. * calculate size for the trailing cluster
  1496. */
  1497. for (block--; lcs < sblock.fs_contigsumsize; block--, lcs++ ) {
  1498. if (isclr(cg_clustersfree(&acg), block))
  1499. break;
  1500. }
  1501. }
  1502. if (lcs < sblock.fs_contigsumsize) {
  1503. if (lcs)
  1504. cg_clustersum(&acg)[lcs]--;
  1505. lcs++;
  1506. cg_clustersum(&acg)[lcs]++;
  1507. }
  1508. DBG_LEAVE;
  1509. return;
  1510. }
  1511. /*
  1512. * Calculate the check-hash of the cylinder group.
  1513. */
  1514. static void
  1515. cgckhash(struct cg *cgp)
  1516. {
  1517. if ((sblock.fs_metackhash & CK_CYLGRP) == 0)
  1518. return;
  1519. cgp->cg_ckhash = 0;
  1520. cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
  1521. }