sfs_vnode.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780
  1. /*
  2. * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  3. * The President and Fellows of Harvard College.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. /*
  30. * SFS filesystem
  31. *
  32. * File-level (vnode) interface routines.
  33. */
  34. #include <types.h>
  35. #include <kern/errno.h>
  36. #include <kern/fcntl.h>
  37. #include <stat.h>
  38. #include <lib.h>
  39. #include <array.h>
  40. #include <bitmap.h>
  41. #include <uio.h>
  42. #include <synch.h>
  43. #include <vfs.h>
  44. #include <device.h>
  45. #include <sfs.h>
  46. /* At bottom of file */
  47. static int sfs_loadvnode(struct sfs_fs *sfs, uint32_t ino, int type,
  48. struct sfs_vnode **ret);
  49. ////////////////////////////////////////////////////////////
  50. //
  51. // Simple stuff
  52. /* Zero out a disk block. */
  53. static
  54. int
  55. sfs_clearblock(struct sfs_fs *sfs, uint32_t block)
  56. {
  57. /* static -> automatically initialized to zero */
  58. static char zeros[SFS_BLOCKSIZE];
  59. return sfs_wblock(sfs, zeros, block);
  60. }
  61. /* Write an on-disk inode structure back out to disk. */
  62. static
  63. int
  64. sfs_sync_inode(struct sfs_vnode *sv)
  65. {
  66. if (sv->sv_dirty) {
  67. struct sfs_fs *sfs = sv->sv_v.vn_fs->fs_data;
  68. int result = sfs_wblock(sfs, &sv->sv_i, sv->sv_ino);
  69. if (result) {
  70. return result;
  71. }
  72. sv->sv_dirty = false;
  73. }
  74. return 0;
  75. }
  76. ////////////////////////////////////////////////////////////
  77. //
  78. // Space allocation
  79. /*
  80. * Allocate a block.
  81. */
  82. static
  83. int
  84. sfs_balloc(struct sfs_fs *sfs, uint32_t *diskblock)
  85. {
  86. int result;
  87. result = bitmap_alloc(sfs->sfs_freemap, diskblock);
  88. if (result) {
  89. return result;
  90. }
  91. sfs->sfs_freemapdirty = true;
  92. if (*diskblock >= sfs->sfs_super.sp_nblocks) {
  93. panic("sfs: balloc: invalid block %u\n", *diskblock);
  94. }
  95. /* Clear block before returning it */
  96. return sfs_clearblock(sfs, *diskblock);
  97. }
  98. /*
  99. * Free a block.
  100. */
  101. static
  102. void
  103. sfs_bfree(struct sfs_fs *sfs, uint32_t diskblock)
  104. {
  105. bitmap_unmark(sfs->sfs_freemap, diskblock);
  106. sfs->sfs_freemapdirty = true;
  107. }
  108. /*
  109. * Check if a block is in use.
  110. */
  111. static
  112. int
  113. sfs_bused(struct sfs_fs *sfs, uint32_t diskblock)
  114. {
  115. if (diskblock >= sfs->sfs_super.sp_nblocks) {
  116. panic("sfs: sfs_bused called on out of range block %u\n",
  117. diskblock);
  118. }
  119. return bitmap_isset(sfs->sfs_freemap, diskblock);
  120. }
  121. ////////////////////////////////////////////////////////////
  122. //
  123. // Block mapping/inode maintenance
  124. /*
  125. * Look up the disk block number (from 0 up to the number of blocks on
  126. * the disk) given a file and the logical block number within that
  127. * file. If DOALLOC is set, and no such block exists, one will be
  128. * allocated.
  129. */
  130. static
  131. int
  132. sfs_bmap(struct sfs_vnode *sv, uint32_t fileblock, int doalloc,
  133. uint32_t *diskblock)
  134. {
  135. /*
  136. * I/O buffer for handling indirect blocks.
  137. *
  138. * Note: in real life (and when you've done the fs assignment)
  139. * you would get space from the disk buffer cache for this,
  140. * not use a static area.
  141. */
  142. static uint32_t idbuf[SFS_DBPERIDB];
  143. struct sfs_fs *sfs = sv->sv_v.vn_fs->fs_data;
  144. uint32_t block;
  145. uint32_t idblock;
  146. uint32_t idnum, idoff;
  147. int result;
  148. KASSERT(sizeof(idbuf)==SFS_BLOCKSIZE);
  149. /*
  150. * If the block we want is one of the direct blocks...
  151. */
  152. if (fileblock < SFS_NDIRECT) {
  153. /*
  154. * Get the block number
  155. */
  156. block = sv->sv_i.sfi_direct[fileblock];
  157. /*
  158. * Do we need to allocate?
  159. */
  160. if (block==0 && doalloc) {
  161. result = sfs_balloc(sfs, &block);
  162. if (result) {
  163. return result;
  164. }
  165. /* Remember what we allocated; mark inode dirty */
  166. sv->sv_i.sfi_direct[fileblock] = block;
  167. sv->sv_dirty = true;
  168. }
  169. /*
  170. * Hand back the block
  171. */
  172. if (block != 0 && !sfs_bused(sfs, block)) {
  173. panic("sfs: Data block %u (block %u of file %u) "
  174. "marked free\n", block, fileblock, sv->sv_ino);
  175. }
  176. *diskblock = block;
  177. return 0;
  178. }
  179. /*
  180. * It's not a direct block; it must be in the indirect block.
  181. * Subtract off the number of direct blocks, so FILEBLOCK is
  182. * now the offset into the indirect block space.
  183. */
  184. fileblock -= SFS_NDIRECT;
  185. /* Get the indirect block number and offset w/i that indirect block */
  186. idnum = fileblock / SFS_DBPERIDB;
  187. idoff = fileblock % SFS_DBPERIDB;
  188. /*
  189. * We only have one indirect block. If the offset we were asked for
  190. * is too large, we can't handle it, so fail.
  191. */
  192. if (idnum > 0) {
  193. return EFBIG;
  194. }
  195. /* Get the disk block number of the indirect block. */
  196. idblock = sv->sv_i.sfi_indirect;
  197. if (idblock==0 && !doalloc) {
  198. /*
  199. * There's no indirect block allocated. We weren't
  200. * asked to allocate anything, so pretend the indirect
  201. * block was filled with all zeros.
  202. */
  203. *diskblock = 0;
  204. return 0;
  205. }
  206. else if (idblock==0) {
  207. /*
  208. * There's no indirect block allocated, but we need to
  209. * allocate a block whose number needs to be stored in
  210. * the indirect block. Thus, we need to allocate an
  211. * indirect block.
  212. */
  213. result = sfs_balloc(sfs, &idblock);
  214. if (result) {
  215. return result;
  216. }
  217. /* Remember the block we just allocated */
  218. sv->sv_i.sfi_indirect = idblock;
  219. /* Mark the inode dirty */
  220. sv->sv_dirty = true;
  221. /* Clear the indirect block buffer */
  222. bzero(idbuf, sizeof(idbuf));
  223. }
  224. else {
  225. /*
  226. * We already have an indirect block allocated; load it.
  227. */
  228. result = sfs_rblock(sfs, idbuf, idblock);
  229. if (result) {
  230. return result;
  231. }
  232. }
  233. /* Get the block out of the indirect block buffer */
  234. block = idbuf[idoff];
  235. /* If there's no block there, allocate one */
  236. if (block==0 && doalloc) {
  237. result = sfs_balloc(sfs, &block);
  238. if (result) {
  239. return result;
  240. }
  241. /* Remember the block we allocated */
  242. idbuf[idoff] = block;
  243. /* The indirect block is now dirty; write it back */
  244. result = sfs_wblock(sfs, idbuf, idblock);
  245. if (result) {
  246. return result;
  247. }
  248. }
  249. /* Hand back the result and return. */
  250. if (block != 0 && !sfs_bused(sfs, block)) {
  251. panic("sfs: Data block %u (block %u of file %u) marked free\n",
  252. block, fileblock, sv->sv_ino);
  253. }
  254. *diskblock = block;
  255. return 0;
  256. }
  257. ////////////////////////////////////////////////////////////
  258. //
  259. // File-level I/O
  260. /*
  261. * Do I/O to a block of a file that doesn't cover the whole block. We
  262. * need to read in the original block first, even if we're writing, so
  263. * we don't clobber the portion of the block we're not intending to
  264. * write over.
  265. *
  266. * skipstart is the number of bytes to skip past at the beginning of
  267. * the sector; len is the number of bytes to actually read or write.
  268. * uio is the area to do the I/O into.
  269. */
  270. static
  271. int
  272. sfs_partialio(struct sfs_vnode *sv, struct uio *uio,
  273. uint32_t skipstart, uint32_t len)
  274. {
  275. /*
  276. * I/O buffer for handling partial sectors.
  277. *
  278. * Note: in real life (and when you've done the fs assignment)
  279. * you would get space from the disk buffer cache for this,
  280. * not use a static area.
  281. */
  282. static char iobuf[SFS_BLOCKSIZE];
  283. struct sfs_fs *sfs = sv->sv_v.vn_fs->fs_data;
  284. uint32_t diskblock;
  285. uint32_t fileblock;
  286. int result;
  287. /* Allocate missing blocks if and only if we're writing */
  288. int doalloc = (uio->uio_rw==UIO_WRITE);
  289. KASSERT(skipstart + len <= SFS_BLOCKSIZE);
  290. /* Compute the block offset of this block in the file */
  291. fileblock = uio->uio_offset / SFS_BLOCKSIZE;
  292. /* Get the disk block number */
  293. result = sfs_bmap(sv, fileblock, doalloc, &diskblock);
  294. if (result) {
  295. return result;
  296. }
  297. if (diskblock == 0) {
  298. /*
  299. * There was no block mapped at this point in the file.
  300. * Zero the buffer.
  301. */
  302. KASSERT(uio->uio_rw == UIO_READ);
  303. bzero(iobuf, sizeof(iobuf));
  304. }
  305. else {
  306. /*
  307. * Read the block.
  308. */
  309. result = sfs_rblock(sfs, iobuf, diskblock);
  310. if (result) {
  311. return result;
  312. }
  313. }
  314. /*
  315. * Now perform the requested operation into/out of the buffer.
  316. */
  317. result = uiomove(iobuf+skipstart, len, uio);
  318. if (result) {
  319. return result;
  320. }
  321. /*
  322. * If it was a write, write back the modified block.
  323. */
  324. if (uio->uio_rw == UIO_WRITE) {
  325. result = sfs_wblock(sfs, iobuf, diskblock);
  326. if (result) {
  327. return result;
  328. }
  329. }
  330. return 0;
  331. }
  332. /*
  333. * Do I/O (either read or write) of a single whole block.
  334. */
  335. static
  336. int
  337. sfs_blockio(struct sfs_vnode *sv, struct uio *uio)
  338. {
  339. struct sfs_fs *sfs = sv->sv_v.vn_fs->fs_data;
  340. uint32_t diskblock;
  341. uint32_t fileblock;
  342. int result;
  343. int doalloc = (uio->uio_rw==UIO_WRITE);
  344. off_t saveoff;
  345. off_t diskoff;
  346. off_t saveres;
  347. off_t diskres;
  348. /* Get the block number within the file */
  349. fileblock = uio->uio_offset / SFS_BLOCKSIZE;
  350. /* Look up the disk block number */
  351. result = sfs_bmap(sv, fileblock, doalloc, &diskblock);
  352. if (result) {
  353. return result;
  354. }
  355. if (diskblock == 0) {
  356. /*
  357. * No block - fill with zeros.
  358. *
  359. * We must be reading, or sfs_bmap would have
  360. * allocated a block for us.
  361. */
  362. KASSERT(uio->uio_rw == UIO_READ);
  363. return uiomovezeros(SFS_BLOCKSIZE, uio);
  364. }
  365. /*
  366. * Do the I/O directly to the uio region. Save the uio_offset,
  367. * and substitute one that makes sense to the device.
  368. */
  369. saveoff = uio->uio_offset;
  370. diskoff = diskblock * SFS_BLOCKSIZE;
  371. uio->uio_offset = diskoff;
  372. /*
  373. * Temporarily set the residue to be one block size.
  374. */
  375. KASSERT(uio->uio_resid >= SFS_BLOCKSIZE);
  376. saveres = uio->uio_resid;
  377. diskres = SFS_BLOCKSIZE;
  378. uio->uio_resid = diskres;
  379. result = sfs_rwblock(sfs, uio);
  380. /*
  381. * Now, restore the original uio_offset and uio_resid and update
  382. * them by the amount of I/O done.
  383. */
  384. uio->uio_offset = (uio->uio_offset - diskoff) + saveoff;
  385. uio->uio_resid = (uio->uio_resid - diskres) + saveres;
  386. return result;
  387. }
  388. /*
  389. * Do I/O of a whole region of data, whether or not it's block-aligned.
  390. */
  391. static
  392. int
  393. sfs_io(struct sfs_vnode *sv, struct uio *uio)
  394. {
  395. uint32_t blkoff;
  396. uint32_t nblocks, i;
  397. int result = 0;
  398. uint32_t extraresid = 0;
  399. /*
  400. * If reading, check for EOF. If we can read a partial area,
  401. * remember how much extra there was in EXTRARESID so we can
  402. * add it back to uio_resid at the end.
  403. */
  404. if (uio->uio_rw == UIO_READ) {
  405. off_t size = sv->sv_i.sfi_size;
  406. off_t endpos = uio->uio_offset + uio->uio_resid;
  407. if (uio->uio_offset >= size) {
  408. /* At or past EOF - just return */
  409. return 0;
  410. }
  411. if (endpos > size) {
  412. extraresid = endpos - size;
  413. KASSERT(uio->uio_resid > extraresid);
  414. uio->uio_resid -= extraresid;
  415. }
  416. }
  417. /*
  418. * First, do any leading partial block.
  419. */
  420. blkoff = uio->uio_offset % SFS_BLOCKSIZE;
  421. if (blkoff != 0) {
  422. /* Number of bytes at beginning of block to skip */
  423. uint32_t skip = blkoff;
  424. /* Number of bytes to read/write after that point */
  425. uint32_t len = SFS_BLOCKSIZE - blkoff;
  426. /* ...which might be less than the rest of the block */
  427. if (len > uio->uio_resid) {
  428. len = uio->uio_resid;
  429. }
  430. /* Call sfs_partialio() to do it. */
  431. result = sfs_partialio(sv, uio, skip, len);
  432. if (result) {
  433. goto out;
  434. }
  435. }
  436. /* If we're done, quit. */
  437. if (uio->uio_resid==0) {
  438. goto out;
  439. }
  440. /*
  441. * Now we should be block-aligned. Do the remaining whole blocks.
  442. */
  443. KASSERT(uio->uio_offset % SFS_BLOCKSIZE == 0);
  444. nblocks = uio->uio_resid / SFS_BLOCKSIZE;
  445. for (i=0; i<nblocks; i++) {
  446. result = sfs_blockio(sv, uio);
  447. if (result) {
  448. goto out;
  449. }
  450. }
  451. /*
  452. * Now do any remaining partial block at the end.
  453. */
  454. KASSERT(uio->uio_resid < SFS_BLOCKSIZE);
  455. if (uio->uio_resid > 0) {
  456. result = sfs_partialio(sv, uio, 0, uio->uio_resid);
  457. if (result) {
  458. goto out;
  459. }
  460. }
  461. out:
  462. /* If writing, adjust file length */
  463. if (uio->uio_rw == UIO_WRITE &&
  464. uio->uio_offset > (off_t)sv->sv_i.sfi_size) {
  465. sv->sv_i.sfi_size = uio->uio_offset;
  466. sv->sv_dirty = true;
  467. }
  468. /* Add in any extra amount we couldn't read because of EOF */
  469. uio->uio_resid += extraresid;
  470. /* Done */
  471. return result;
  472. }
  473. ////////////////////////////////////////////////////////////
  474. //
  475. // Directory I/O
  476. /*
  477. * Read the directory entry out of slot SLOT of a directory vnode.
  478. * The "slot" is the index of the directory entry, starting at 0.
  479. */
  480. static
  481. int
  482. sfs_readdir(struct sfs_vnode *sv, struct sfs_dir *sd, int slot)
  483. {
  484. struct iovec iov;
  485. struct uio ku;
  486. off_t actualpos;
  487. int result;
  488. /* Compute the actual position in the directory to read. */
  489. actualpos = slot * sizeof(struct sfs_dir);
  490. /* Set up a uio to do the read */
  491. uio_kinit(&iov, &ku, sd, sizeof(struct sfs_dir), actualpos, UIO_READ);
  492. /* do it */
  493. result = sfs_io(sv, &ku);
  494. if (result) {
  495. return result;
  496. }
  497. /* We should not hit EOF in the middle of a directory entry */
  498. if (ku.uio_resid > 0) {
  499. panic("sfs: readdir: Short entry (inode %u)\n", sv->sv_ino);
  500. }
  501. /* Done */
  502. return 0;
  503. }
  504. /*
  505. * Write (overwrite) the directory entry in slot SLOT of a directory
  506. * vnode.
  507. */
  508. static
  509. int
  510. sfs_writedir(struct sfs_vnode *sv, struct sfs_dir *sd, int slot)
  511. {
  512. struct iovec iov;
  513. struct uio ku;
  514. off_t actualpos;
  515. int result;
  516. /* Compute the actual position in the directory. */
  517. KASSERT(slot>=0);
  518. actualpos = slot * sizeof(struct sfs_dir);
  519. /* Set up a uio to do the write */
  520. uio_kinit(&iov, &ku, sd, sizeof(struct sfs_dir), actualpos, UIO_WRITE);
  521. /* do it */
  522. result = sfs_io(sv, &ku);
  523. if (result) {
  524. return result;
  525. }
  526. /* Should not end up with a partial entry! */
  527. if (ku.uio_resid > 0) {
  528. panic("sfs: writedir: Short write (ino %u)\n", sv->sv_ino);
  529. }
  530. /* Done */
  531. return 0;
  532. }
  533. /*
  534. * Compute the number of entries in a directory.
  535. * This actually computes the number of existing slots, and does not
  536. * account for empty slots.
  537. */
  538. static
  539. int
  540. sfs_dir_nentries(struct sfs_vnode *sv)
  541. {
  542. off_t size;
  543. KASSERT(sv->sv_i.sfi_type == SFS_TYPE_DIR);
  544. size = sv->sv_i.sfi_size;
  545. if (size % sizeof(struct sfs_dir) != 0) {
  546. panic("sfs: directory %u: Invalid size %llu\n",
  547. sv->sv_ino, size);
  548. }
  549. return size / sizeof(struct sfs_dir);
  550. }
  551. /*
  552. * Search a directory for a particular filename in a directory, and
  553. * return its inode number, its slot, and/or the slot number of an
  554. * empty directory slot if one is found.
  555. */
  556. static
  557. int
  558. sfs_dir_findname(struct sfs_vnode *sv, const char *name,
  559. uint32_t *ino, int *slot, int *emptyslot)
  560. {
  561. struct sfs_dir tsd;
  562. int found = 0;
  563. int nentries = sfs_dir_nentries(sv);
  564. int i, result;
  565. /* For each slot... */
  566. for (i=0; i<nentries; i++) {
  567. /* Read the entry from that slot */
  568. result = sfs_readdir(sv, &tsd, i);
  569. if (result) {
  570. return result;
  571. }
  572. if (tsd.sfd_ino == SFS_NOINO) {
  573. /* Free slot - report it back if one was requested */
  574. if (emptyslot != NULL) {
  575. *emptyslot = i;
  576. }
  577. }
  578. else {
  579. /* Ensure null termination, just in case */
  580. tsd.sfd_name[sizeof(tsd.sfd_name)-1] = 0;
  581. if (!strcmp(tsd.sfd_name, name)) {
  582. /* Each name may legally appear only once... */
  583. KASSERT(found==0);
  584. found = 1;
  585. if (slot != NULL) {
  586. *slot = i;
  587. }
  588. if (ino != NULL) {
  589. *ino = tsd.sfd_ino;
  590. }
  591. }
  592. }
  593. }
  594. return found ? 0 : ENOENT;
  595. }
  596. /*
  597. * Create a link in a directory to the specified inode by number, with
  598. * the specified name, and optionally hand back the slot.
  599. */
  600. static
  601. int
  602. sfs_dir_link(struct sfs_vnode *sv, const char *name, uint32_t ino, int *slot)
  603. {
  604. int emptyslot = -1;
  605. int result;
  606. struct sfs_dir sd;
  607. /* Look up the name. We want to make sure it *doesn't* exist. */
  608. result = sfs_dir_findname(sv, name, NULL, NULL, &emptyslot);
  609. if (result!=0 && result!=ENOENT) {
  610. return result;
  611. }
  612. if (result==0) {
  613. return EEXIST;
  614. }
  615. if (strlen(name)+1 > sizeof(sd.sfd_name)) {
  616. return ENAMETOOLONG;
  617. }
  618. /* If we didn't get an empty slot, add the entry at the end. */
  619. if (emptyslot < 0) {
  620. emptyslot = sfs_dir_nentries(sv);
  621. }
  622. /* Set up the entry. */
  623. bzero(&sd, sizeof(sd));
  624. sd.sfd_ino = ino;
  625. strcpy(sd.sfd_name, name);
  626. /* Hand back the slot, if so requested. */
  627. if (slot) {
  628. *slot = emptyslot;
  629. }
  630. /* Write the entry. */
  631. return sfs_writedir(sv, &sd, emptyslot);
  632. }
  633. /*
  634. * Unlink a name in a directory, by slot number.
  635. */
  636. static
  637. int
  638. sfs_dir_unlink(struct sfs_vnode *sv, int slot)
  639. {
  640. struct sfs_dir sd;
  641. /* Initialize a suitable directory entry... */
  642. bzero(&sd, sizeof(sd));
  643. sd.sfd_ino = SFS_NOINO;
  644. /* ... and write it */
  645. return sfs_writedir(sv, &sd, slot);
  646. }
  647. /*
  648. * Look for a name in a directory and hand back a vnode for the
  649. * file, if there is one.
  650. */
  651. static
  652. int
  653. sfs_lookonce(struct sfs_vnode *sv, const char *name,
  654. struct sfs_vnode **ret,
  655. int *slot)
  656. {
  657. struct sfs_fs *sfs = sv->sv_v.vn_fs->fs_data;
  658. uint32_t ino;
  659. int result;
  660. result = sfs_dir_findname(sv, name, &ino, slot, NULL);
  661. if (result) {
  662. return result;
  663. }
  664. result = sfs_loadvnode(sfs, ino, SFS_TYPE_INVAL, ret);
  665. if (result) {
  666. return result;
  667. }
  668. if ((*ret)->sv_i.sfi_linkcount == 0) {
  669. panic("sfs: Link count of file %u found in dir %u is 0\n",
  670. (*ret)->sv_ino, sv->sv_ino);
  671. }
  672. return 0;
  673. }
  674. ////////////////////////////////////////////////////////////
  675. //
  676. // Object creation
  677. /*
  678. * Create a new filesystem object and hand back its vnode.
  679. */
  680. static
  681. int
  682. sfs_makeobj(struct sfs_fs *sfs, int type, struct sfs_vnode **ret)
  683. {
  684. uint32_t ino;
  685. int result;
  686. /*
  687. * First, get an inode. (Each inode is a block, and the inode
  688. * number is the block number, so just get a block.)
  689. */
  690. result = sfs_balloc(sfs, &ino);
  691. if (result) {
  692. return result;
  693. }
  694. /*
  695. * Now load a vnode for it.
  696. */
  697. return sfs_loadvnode(sfs, ino, type, ret);
  698. }
  699. ////////////////////////////////////////////////////////////
  700. //
  701. // Vnode ops
  702. /*
  703. * This is called on *each* open().
  704. */
  705. static
  706. int
  707. sfs_open(struct vnode *v, int openflags)
  708. {
  709. /*
  710. * At this level we do not need to handle O_CREAT, O_EXCL, or O_TRUNC.
  711. * We *would* need to handle O_APPEND, but we don't support it.
  712. *
  713. * Any of O_RDONLY, O_WRONLY, and O_RDWR are valid, so we don't need
  714. * to check that either.
  715. */
  716. if (openflags & O_APPEND) {
  717. return EUNIMP;
  718. }
  719. (void)v;
  720. return 0;
  721. }
  722. /*
  723. * This is called on *each* open() of a directory.
  724. * Directories may only be open for read.
  725. */
  726. static
  727. int
  728. sfs_opendir(struct vnode *v, int openflags)
  729. {
  730. switch (openflags & O_ACCMODE) {
  731. case O_RDONLY:
  732. break;
  733. case O_WRONLY:
  734. case O_RDWR:
  735. default:
  736. return EISDIR;
  737. }
  738. if (openflags & O_APPEND) {
  739. return EISDIR;
  740. }
  741. (void)v;
  742. return 0;
  743. }
  744. /*
  745. * Called on the *last* close().
  746. *
  747. * This function should attempt to avoid returning errors, as handling
  748. * them usefully is often not possible.
  749. */
  750. static
  751. int
  752. sfs_close(struct vnode *v)
  753. {
  754. /* Sync it. */
  755. return VOP_FSYNC(v);
  756. }
  757. /*
  758. * Called when the vnode refcount (in-memory usage count) hits zero.
  759. *
  760. * This function should try to avoid returning errors other than EBUSY.
  761. */
  762. static
  763. int
  764. sfs_reclaim(struct vnode *v)
  765. {
  766. struct sfs_vnode *sv = v->vn_data;
  767. struct sfs_fs *sfs = v->vn_fs->fs_data;
  768. unsigned ix, i, num;
  769. int result;
  770. vfs_biglock_acquire();
  771. /*
  772. * Make sure someone else hasn't picked up the vnode since the
  773. * decision was made to reclaim it. (You must also synchronize
  774. * this with sfs_loadvnode.)
  775. */
  776. if (v->vn_refcount != 1) {
  777. /* consume the reference VOP_DECREF gave us */
  778. KASSERT(v->vn_refcount>1);
  779. v->vn_refcount--;
  780. vfs_biglock_release();
  781. return EBUSY;
  782. }
  783. /* If there are no on-disk references to the file either, erase it. */
  784. if (sv->sv_i.sfi_linkcount==0) {
  785. result = VOP_TRUNCATE(&sv->sv_v, 0);
  786. if (result) {
  787. vfs_biglock_release();
  788. return result;
  789. }
  790. }
  791. /* Sync the inode to disk */
  792. result = sfs_sync_inode(sv);
  793. if (result) {
  794. vfs_biglock_release();
  795. return result;
  796. }
  797. /* If there are no on-disk references, discard the inode */
  798. if (sv->sv_i.sfi_linkcount==0) {
  799. sfs_bfree(sfs, sv->sv_ino);
  800. }
  801. /* Remove the vnode structure from the table in the struct sfs_fs. */
  802. num = vnodearray_num(sfs->sfs_vnodes);
  803. ix = num;
  804. for (i=0; i<num; i++) {
  805. struct vnode *v2 = vnodearray_get(sfs->sfs_vnodes, i);
  806. struct sfs_vnode *sv2 = v2->vn_data;
  807. if (sv2 == sv) {
  808. ix = i;
  809. break;
  810. }
  811. }
  812. if (ix == num) {
  813. panic("sfs: reclaim vnode %u not in vnode pool\n",
  814. sv->sv_ino);
  815. }
  816. vnodearray_remove(sfs->sfs_vnodes, ix);
  817. VOP_CLEANUP(&sv->sv_v);
  818. vfs_biglock_release();
  819. /* Release the storage for the vnode structure itself. */
  820. kfree(sv);
  821. /* Done */
  822. return 0;
  823. }
  824. /*
  825. * Called for read(). sfs_io() does the work.
  826. */
  827. static
  828. int
  829. sfs_read(struct vnode *v, struct uio *uio)
  830. {
  831. struct sfs_vnode *sv = v->vn_data;
  832. int result;
  833. KASSERT(uio->uio_rw==UIO_READ);
  834. vfs_biglock_acquire();
  835. result = sfs_io(sv, uio);
  836. vfs_biglock_release();
  837. return result;
  838. }
  839. /*
  840. * Called for write(). sfs_io() does the work.
  841. */
  842. static
  843. int
  844. sfs_write(struct vnode *v, struct uio *uio)
  845. {
  846. struct sfs_vnode *sv = v->vn_data;
  847. int result;
  848. KASSERT(uio->uio_rw==UIO_WRITE);
  849. vfs_biglock_acquire();
  850. result = sfs_io(sv, uio);
  851. vfs_biglock_release();
  852. return result;
  853. }
  854. /*
  855. * Called for ioctl()
  856. */
  857. static
  858. int
  859. sfs_ioctl(struct vnode *v, int op, userptr_t data)
  860. {
  861. /*
  862. * No ioctls.
  863. */
  864. (void)v;
  865. (void)op;
  866. (void)data;
  867. return EINVAL;
  868. }
  869. /*
  870. * Called for stat/fstat/lstat.
  871. */
  872. static
  873. int
  874. sfs_stat(struct vnode *v, struct stat *statbuf)
  875. {
  876. struct sfs_vnode *sv = v->vn_data;
  877. int result;
  878. /* Fill in the stat structure */
  879. bzero(statbuf, sizeof(struct stat));
  880. result = VOP_GETTYPE(v, &statbuf->st_mode);
  881. if (result) {
  882. return result;
  883. }
  884. statbuf->st_size = sv->sv_i.sfi_size;
  885. /* We don't support these yet; you get to implement them */
  886. statbuf->st_nlink = 0;
  887. statbuf->st_blocks = 0;
  888. /* Fill in other field as desired/possible... */
  889. return 0;
  890. }
  891. /*
  892. * Return the type of the file (types as per kern/stat.h)
  893. */
  894. static
  895. int
  896. sfs_gettype(struct vnode *v, uint32_t *ret)
  897. {
  898. struct sfs_vnode *sv = v->vn_data;
  899. vfs_biglock_acquire();
  900. switch (sv->sv_i.sfi_type) {
  901. case SFS_TYPE_FILE:
  902. *ret = S_IFREG;
  903. vfs_biglock_release();
  904. return 0;
  905. case SFS_TYPE_DIR:
  906. *ret = S_IFDIR;
  907. vfs_biglock_release();
  908. return 0;
  909. }
  910. panic("sfs: gettype: Invalid inode type (inode %u, type %u)\n",
  911. sv->sv_ino, sv->sv_i.sfi_type);
  912. return EINVAL;
  913. }
  914. /*
  915. * Check for legal seeks on files. Allow anything non-negative.
  916. * We could conceivably, here, prohibit seeking past the maximum
  917. * file size our inode structure can support, but we don't - few
  918. * people ever bother to check lseek() for failure and having
  919. * read() or write() fail is sufficient.
  920. */
  921. static
  922. int
  923. sfs_tryseek(struct vnode *v, off_t pos)
  924. {
  925. if (pos<0) {
  926. return EINVAL;
  927. }
  928. /* Allow anything else */
  929. (void)v;
  930. return 0;
  931. }
  932. /*
  933. * Called for fsync(), and also on filesystem unmount, global sync(),
  934. * and some other cases.
  935. */
  936. static
  937. int
  938. sfs_fsync(struct vnode *v)
  939. {
  940. struct sfs_vnode *sv = v->vn_data;
  941. int result;
  942. vfs_biglock_acquire();
  943. result = sfs_sync_inode(sv);
  944. vfs_biglock_release();
  945. return result;
  946. }
  947. /*
  948. * Called for mmap().
  949. */
  950. static
  951. int
  952. sfs_mmap(struct vnode *v /* add stuff as needed */)
  953. {
  954. (void)v;
  955. return EUNIMP;
  956. }
  957. /*
  958. * Called for ftruncate() and from sfs_reclaim.
  959. */
  960. static
  961. int
  962. sfs_truncate(struct vnode *v, off_t len)
  963. {
  964. /*
  965. * I/O buffer for handling the indirect block.
  966. *
  967. * Note: in real life (and when you've done the fs assignment)
  968. * you would get space from the disk buffer cache for this,
  969. * not use a static area.
  970. */
  971. static uint32_t idbuf[SFS_DBPERIDB];
  972. struct sfs_vnode *sv = v->vn_data;
  973. struct sfs_fs *sfs = sv->sv_v.vn_fs->fs_data;
  974. /* Length in blocks (divide rounding up) */
  975. uint32_t blocklen = DIVROUNDUP(len, SFS_BLOCKSIZE);
  976. uint32_t i, j, block;
  977. uint32_t idblock, baseblock, highblock;
  978. int result;
  979. int hasnonzero, iddirty;
  980. KASSERT(sizeof(idbuf)==SFS_BLOCKSIZE);
  981. vfs_biglock_acquire();
  982. /*
  983. * Go through the direct blocks. Discard any that are
  984. * past the limit we're truncating to.
  985. */
  986. for (i=0; i<SFS_NDIRECT; i++) {
  987. block = sv->sv_i.sfi_direct[i];
  988. if (i >= blocklen && block != 0) {
  989. sfs_bfree(sfs, block);
  990. sv->sv_i.sfi_direct[i] = 0;
  991. sv->sv_dirty = true;
  992. }
  993. }
  994. /* Indirect block number */
  995. idblock = sv->sv_i.sfi_indirect;
  996. /* The lowest block in the indirect block */
  997. baseblock = SFS_NDIRECT;
  998. /* The highest block in the indirect block */
  999. highblock = baseblock + SFS_DBPERIDB - 1;
  1000. if (blocklen < highblock && idblock != 0) {
  1001. /* We're past the proposed EOF; may need to free stuff */
  1002. /* Read the indirect block */
  1003. result = sfs_rblock(sfs, idbuf, idblock);
  1004. if (result) {
  1005. vfs_biglock_release();
  1006. return result;
  1007. }
  1008. hasnonzero = 0;
  1009. iddirty = 0;
  1010. for (j=0; j<SFS_DBPERIDB; j++) {
  1011. /* Discard any blocks that are past the new EOF */
  1012. if (blocklen < baseblock+j && idbuf[j] != 0) {
  1013. sfs_bfree(sfs, idbuf[j]);
  1014. idbuf[j] = 0;
  1015. iddirty = 1;
  1016. }
  1017. /* Remember if we see any nonzero blocks in here */
  1018. if (idbuf[j]!=0) {
  1019. hasnonzero=1;
  1020. }
  1021. }
  1022. if (!hasnonzero) {
  1023. /* The whole indirect block is empty now; free it */
  1024. sfs_bfree(sfs, idblock);
  1025. sv->sv_i.sfi_indirect = 0;
  1026. sv->sv_dirty = true;
  1027. }
  1028. else if (iddirty) {
  1029. /* The indirect block is dirty; write it back */
  1030. result = sfs_wblock(sfs, idbuf, idblock);
  1031. if (result) {
  1032. vfs_biglock_release();
  1033. return result;
  1034. }
  1035. }
  1036. }
  1037. /* Set the file size */
  1038. sv->sv_i.sfi_size = len;
  1039. /* Mark the inode dirty */
  1040. sv->sv_dirty = true;
  1041. vfs_biglock_release();
  1042. return 0;
  1043. }
  1044. /*
  1045. * Get the full pathname for a file. This only needs to work on directories.
  1046. * Since we don't support subdirectories, assume it's the root directory
  1047. * and hand back the empty string. (The VFS layer takes care of the
  1048. * device name, leading slash, etc.)
  1049. */
  1050. static
  1051. int
  1052. sfs_namefile(struct vnode *vv, struct uio *uio)
  1053. {
  1054. struct sfs_vnode *sv = vv->vn_data;
  1055. KASSERT(sv->sv_ino == SFS_ROOT_LOCATION);
  1056. /* send back the empty string - just return */
  1057. (void)uio;
  1058. return 0;
  1059. }
  1060. /*
  1061. * Create a file. If EXCL is set, insist that the filename not already
  1062. * exist; otherwise, if it already exists, just open it.
  1063. */
  1064. static
  1065. int
  1066. sfs_creat(struct vnode *v, const char *name, bool excl, mode_t mode,
  1067. struct vnode **ret)
  1068. {
  1069. struct sfs_fs *sfs = v->vn_fs->fs_data;
  1070. struct sfs_vnode *sv = v->vn_data;
  1071. struct sfs_vnode *newguy;
  1072. uint32_t ino;
  1073. int result;
  1074. vfs_biglock_acquire();
  1075. /* Look up the name */
  1076. result = sfs_dir_findname(sv, name, &ino, NULL, NULL);
  1077. if (result!=0 && result!=ENOENT) {
  1078. vfs_biglock_release();
  1079. return result;
  1080. }
  1081. /* If it exists and we didn't want it to, fail */
  1082. if (result==0 && excl) {
  1083. vfs_biglock_release();
  1084. return EEXIST;
  1085. }
  1086. if (result==0) {
  1087. /* We got a file; load its vnode and return */
  1088. result = sfs_loadvnode(sfs, ino, SFS_TYPE_INVAL, &newguy);
  1089. if (result) {
  1090. vfs_biglock_release();
  1091. return result;
  1092. }
  1093. *ret = &newguy->sv_v;
  1094. vfs_biglock_release();
  1095. return 0;
  1096. }
  1097. /* Didn't exist - create it */
  1098. result = sfs_makeobj(sfs, SFS_TYPE_FILE, &newguy);
  1099. if (result) {
  1100. vfs_biglock_release();
  1101. return result;
  1102. }
  1103. /* We don't currently support file permissions; ignore MODE */
  1104. (void)mode;
  1105. /* Link it into the directory */
  1106. result = sfs_dir_link(sv, name, newguy->sv_ino, NULL);
  1107. if (result) {
  1108. VOP_DECREF(&newguy->sv_v);
  1109. vfs_biglock_release();
  1110. return result;
  1111. }
  1112. /* Update the linkcount of the new file */
  1113. newguy->sv_i.sfi_linkcount++;
  1114. /* and consequently mark it dirty. */
  1115. newguy->sv_dirty = true;
  1116. *ret = &newguy->sv_v;
  1117. vfs_biglock_release();
  1118. return 0;
  1119. }
  1120. /*
  1121. * Make a hard link to a file.
  1122. * The VFS layer should prevent this being called unless both
  1123. * vnodes are ours.
  1124. */
  1125. static
  1126. int
  1127. sfs_link(struct vnode *dir, const char *name, struct vnode *file)
  1128. {
  1129. struct sfs_vnode *sv = dir->vn_data;
  1130. struct sfs_vnode *f = file->vn_data;
  1131. int result;
  1132. KASSERT(file->vn_fs == dir->vn_fs);
  1133. vfs_biglock_acquire();
  1134. /* Just create a link */
  1135. result = sfs_dir_link(sv, name, f->sv_ino, NULL);
  1136. if (result) {
  1137. vfs_biglock_release();
  1138. return result;
  1139. }
  1140. /* and update the link count, marking the inode dirty */
  1141. f->sv_i.sfi_linkcount++;
  1142. f->sv_dirty = true;
  1143. vfs_biglock_release();
  1144. return 0;
  1145. }
  1146. /*
  1147. * Delete a file.
  1148. */
  1149. static
  1150. int
  1151. sfs_remove(struct vnode *dir, const char *name)
  1152. {
  1153. struct sfs_vnode *sv = dir->vn_data;
  1154. struct sfs_vnode *victim;
  1155. int slot;
  1156. int result;
  1157. vfs_biglock_acquire();
  1158. /* Look for the file and fetch a vnode for it. */
  1159. result = sfs_lookonce(sv, name, &victim, &slot);
  1160. if (result) {
  1161. vfs_biglock_release();
  1162. return result;
  1163. }
  1164. /* Erase its directory entry. */
  1165. result = sfs_dir_unlink(sv, slot);
  1166. if (result==0) {
  1167. /* If we succeeded, decrement the link count. */
  1168. KASSERT(victim->sv_i.sfi_linkcount > 0);
  1169. victim->sv_i.sfi_linkcount--;
  1170. victim->sv_dirty = true;
  1171. }
  1172. /* Discard the reference that sfs_lookonce got us */
  1173. VOP_DECREF(&victim->sv_v);
  1174. vfs_biglock_release();
  1175. return result;
  1176. }
  1177. /*
  1178. * Rename a file.
  1179. *
  1180. * Since we don't support subdirectories, assumes that the two
  1181. * directories passed are the same.
  1182. */
  1183. static
  1184. int
  1185. sfs_rename(struct vnode *d1, const char *n1,
  1186. struct vnode *d2, const char *n2)
  1187. {
  1188. struct sfs_vnode *sv = d1->vn_data;
  1189. struct sfs_vnode *g1;
  1190. int slot1, slot2;
  1191. int result, result2;
  1192. vfs_biglock_acquire();
  1193. KASSERT(d1==d2);
  1194. KASSERT(sv->sv_ino == SFS_ROOT_LOCATION);
  1195. /* Look up the old name of the file and get its inode and slot number*/
  1196. result = sfs_lookonce(sv, n1, &g1, &slot1);
  1197. if (result) {
  1198. vfs_biglock_release();
  1199. return result;
  1200. }
  1201. /* We don't support subdirectories */
  1202. KASSERT(g1->sv_i.sfi_type == SFS_TYPE_FILE);
  1203. /*
  1204. * Link it under the new name.
  1205. *
  1206. * We could theoretically just overwrite the original
  1207. * directory entry, except that we need to check to make sure
  1208. * the new name doesn't already exist; might as well use the
  1209. * existing link routine.
  1210. */
  1211. result = sfs_dir_link(sv, n2, g1->sv_ino, &slot2);
  1212. if (result) {
  1213. goto puke;
  1214. }
  1215. /* Increment the link count, and mark inode dirty */
  1216. g1->sv_i.sfi_linkcount++;
  1217. g1->sv_dirty = true;
  1218. /* Unlink the old slot */
  1219. result = sfs_dir_unlink(sv, slot1);
  1220. if (result) {
  1221. goto puke_harder;
  1222. }
  1223. /*
  1224. * Decrement the link count again, and mark the inode dirty again,
  1225. * in case it's been synced behind our back.
  1226. */
  1227. KASSERT(g1->sv_i.sfi_linkcount>0);
  1228. g1->sv_i.sfi_linkcount--;
  1229. g1->sv_dirty = true;
  1230. /* Let go of the reference to g1 */
  1231. VOP_DECREF(&g1->sv_v);
  1232. vfs_biglock_release();
  1233. return 0;
  1234. puke_harder:
  1235. /*
  1236. * Error recovery: try to undo what we already did
  1237. */
  1238. result2 = sfs_dir_unlink(sv, slot2);
  1239. if (result2) {
  1240. kprintf("sfs: rename: %s\n", strerror(result));
  1241. kprintf("sfs: rename: while cleaning up: %s\n",
  1242. strerror(result2));
  1243. panic("sfs: rename: Cannot recover\n");
  1244. }
  1245. g1->sv_i.sfi_linkcount--;
  1246. puke:
  1247. /* Let go of the reference to g1 */
  1248. VOP_DECREF(&g1->sv_v);
  1249. vfs_biglock_release();
  1250. return result;
  1251. }
  1252. /*
  1253. * lookparent returns the last path component as a string and the
  1254. * directory it's in as a vnode.
  1255. *
  1256. * Since we don't support subdirectories, this is very easy -
  1257. * return the root dir and copy the path.
  1258. */
  1259. static
  1260. int
  1261. sfs_lookparent(struct vnode *v, char *path, struct vnode **ret,
  1262. char *buf, size_t buflen)
  1263. {
  1264. struct sfs_vnode *sv = v->vn_data;
  1265. vfs_biglock_acquire();
  1266. if (sv->sv_i.sfi_type != SFS_TYPE_DIR) {
  1267. vfs_biglock_release();
  1268. return ENOTDIR;
  1269. }
  1270. if (strlen(path)+1 > buflen) {
  1271. vfs_biglock_release();
  1272. return ENAMETOOLONG;
  1273. }
  1274. strcpy(buf, path);
  1275. VOP_INCREF(&sv->sv_v);
  1276. *ret = &sv->sv_v;
  1277. vfs_biglock_release();
  1278. return 0;
  1279. }
  1280. /*
  1281. * Lookup gets a vnode for a pathname.
  1282. *
  1283. * Since we don't support subdirectories, it's easy - just look up the
  1284. * name.
  1285. */
  1286. static
  1287. int
  1288. sfs_lookup(struct vnode *v, char *path, struct vnode **ret)
  1289. {
  1290. struct sfs_vnode *sv = v->vn_data;
  1291. struct sfs_vnode *final;
  1292. int result;
  1293. vfs_biglock_acquire();
  1294. if (sv->sv_i.sfi_type != SFS_TYPE_DIR) {
  1295. vfs_biglock_release();
  1296. return ENOTDIR;
  1297. }
  1298. result = sfs_lookonce(sv, path, &final, NULL);
  1299. if (result) {
  1300. vfs_biglock_release();
  1301. return result;
  1302. }
  1303. *ret = &final->sv_v;
  1304. vfs_biglock_release();
  1305. return 0;
  1306. }
  1307. //////////////////////////////////////////////////
  1308. static
  1309. int
  1310. sfs_notdir(void)
  1311. {
  1312. return ENOTDIR;
  1313. }
  1314. static
  1315. int
  1316. sfs_isdir(void)
  1317. {
  1318. return EISDIR;
  1319. }
  1320. static
  1321. int
  1322. sfs_unimp(void)
  1323. {
  1324. return EUNIMP;
  1325. }
  1326. /*
  1327. * Casting through void * prevents warnings.
  1328. * All of the vnode ops return int, and it's ok to cast functions that
  1329. * take args to functions that take no args.
  1330. */
  1331. #define ISDIR ((void *)sfs_isdir)
  1332. #define NOTDIR ((void *)sfs_notdir)
  1333. #define UNIMP ((void *)sfs_unimp)
  1334. /*
  1335. * Function table for sfs files.
  1336. */
  1337. static const struct vnode_ops sfs_fileops = {
  1338. VOP_MAGIC, /* mark this a valid vnode ops table */
  1339. sfs_open,
  1340. sfs_close,
  1341. sfs_reclaim,
  1342. sfs_read,
  1343. NOTDIR, /* readlink */
  1344. NOTDIR, /* getdirentry */
  1345. sfs_write,
  1346. sfs_ioctl,
  1347. sfs_stat,
  1348. sfs_gettype,
  1349. sfs_tryseek,
  1350. sfs_fsync,
  1351. sfs_mmap,
  1352. sfs_truncate,
  1353. NOTDIR, /* namefile */
  1354. NOTDIR, /* creat */
  1355. NOTDIR, /* symlink */
  1356. NOTDIR, /* mkdir */
  1357. NOTDIR, /* link */
  1358. NOTDIR, /* remove */
  1359. NOTDIR, /* rmdir */
  1360. NOTDIR, /* rename */
  1361. NOTDIR, /* lookup */
  1362. NOTDIR, /* lookparent */
  1363. };
  1364. /*
  1365. * Function table for the sfs directory.
  1366. */
  1367. static const struct vnode_ops sfs_dirops = {
  1368. VOP_MAGIC, /* mark this a valid vnode ops table */
  1369. sfs_opendir,
  1370. sfs_close,
  1371. sfs_reclaim,
  1372. ISDIR, /* read */
  1373. ISDIR, /* readlink */
  1374. UNIMP, /* getdirentry */
  1375. ISDIR, /* write */
  1376. sfs_ioctl,
  1377. sfs_stat,
  1378. sfs_gettype,
  1379. UNIMP, /* tryseek */
  1380. sfs_fsync,
  1381. ISDIR, /* mmap */
  1382. ISDIR, /* truncate */
  1383. sfs_namefile,
  1384. sfs_creat,
  1385. UNIMP, /* symlink */
  1386. UNIMP, /* mkdir */
  1387. sfs_link,
  1388. sfs_remove,
  1389. UNIMP, /* rmdir */
  1390. sfs_rename,
  1391. sfs_lookup,
  1392. sfs_lookparent,
  1393. };
  1394. /*
  1395. * Function to load a inode into memory as a vnode, or dig up one
  1396. * that's already resident.
  1397. */
  1398. static
  1399. int
  1400. sfs_loadvnode(struct sfs_fs *sfs, uint32_t ino, int forcetype,
  1401. struct sfs_vnode **ret)
  1402. {
  1403. struct vnode *v;
  1404. struct sfs_vnode *sv;
  1405. const struct vnode_ops *ops = NULL;
  1406. unsigned i, num;
  1407. int result;
  1408. /* Look in the vnodes table */
  1409. num = vnodearray_num(sfs->sfs_vnodes);
  1410. /* Linear search. Is this too slow? You decide. */
  1411. for (i=0; i<num; i++) {
  1412. v = vnodearray_get(sfs->sfs_vnodes, i);
  1413. sv = v->vn_data;
  1414. /* Every inode in memory must be in an allocated block */
  1415. if (!sfs_bused(sfs, sv->sv_ino)) {
  1416. panic("sfs: Found inode %u in unallocated block\n",
  1417. sv->sv_ino);
  1418. }
  1419. if (sv->sv_ino==ino) {
  1420. /* Found */
  1421. /* May only be set when creating new objects */
  1422. KASSERT(forcetype==SFS_TYPE_INVAL);
  1423. VOP_INCREF(&sv->sv_v);
  1424. *ret = sv;
  1425. return 0;
  1426. }
  1427. }
  1428. /* Didn't have it loaded; load it */
  1429. sv = kmalloc(sizeof(struct sfs_vnode));
  1430. if (sv==NULL) {
  1431. return ENOMEM;
  1432. }
  1433. /* Must be in an allocated block */
  1434. if (!sfs_bused(sfs, ino)) {
  1435. panic("sfs: Tried to load inode %u from unallocated block\n",
  1436. ino);
  1437. }
  1438. /* Read the block the inode is in */
  1439. result = sfs_rblock(sfs, &sv->sv_i, ino);
  1440. if (result) {
  1441. kfree(sv);
  1442. return result;
  1443. }
  1444. /* Not dirty yet */
  1445. sv->sv_dirty = false;
  1446. /*
  1447. * FORCETYPE is set if we're creating a new file, because the
  1448. * block on disk will have been zeroed out and thus the type
  1449. * recorded there will be SFS_TYPE_INVAL.
  1450. */
  1451. if (forcetype != SFS_TYPE_INVAL) {
  1452. KASSERT(sv->sv_i.sfi_type == SFS_TYPE_INVAL);
  1453. sv->sv_i.sfi_type = forcetype;
  1454. sv->sv_dirty = true;
  1455. }
  1456. /*
  1457. * Choose the function table based on the object type.
  1458. */
  1459. switch (sv->sv_i.sfi_type) {
  1460. case SFS_TYPE_FILE:
  1461. ops = &sfs_fileops;
  1462. break;
  1463. case SFS_TYPE_DIR:
  1464. ops = &sfs_dirops;
  1465. break;
  1466. default:
  1467. panic("sfs: loadvnode: Invalid inode type "
  1468. "(inode %u, type %u)\n",
  1469. ino, sv->sv_i.sfi_type);
  1470. }
  1471. /* Call the common vnode initializer */
  1472. result = VOP_INIT(&sv->sv_v, ops, &sfs->sfs_absfs, sv);
  1473. if (result) {
  1474. kfree(sv);
  1475. return result;
  1476. }
  1477. /* Set the other fields in our vnode structure */
  1478. sv->sv_ino = ino;
  1479. /* Add it to our table */
  1480. result = vnodearray_add(sfs->sfs_vnodes, &sv->sv_v, NULL);
  1481. if (result) {
  1482. VOP_CLEANUP(&sv->sv_v);
  1483. kfree(sv);
  1484. return result;
  1485. }
  1486. /* Hand it back */
  1487. *ret = sv;
  1488. return 0;
  1489. }
  1490. /*
  1491. * Get vnode for the root of the filesystem.
  1492. * The root vnode is always found in block 1 (SFS_ROOT_LOCATION).
  1493. */
  1494. struct vnode *
  1495. sfs_getroot(struct fs *fs)
  1496. {
  1497. struct sfs_fs *sfs = fs->fs_data;
  1498. struct sfs_vnode *sv;
  1499. int result;
  1500. vfs_biglock_acquire();
  1501. result = sfs_loadvnode(sfs, SFS_ROOT_LOCATION, SFS_TYPE_INVAL, &sv);
  1502. if (result) {
  1503. panic("sfs: getroot: Cannot load root vnode\n");
  1504. }
  1505. vfs_biglock_release();
  1506. return &sv->sv_v;
  1507. }