int sfs_wblock(struct sfs_fs *sfs, void *data, u_int32_t block) { struct uio ku; SFSUIO(&ku, data, block, UIO_WRITE); return sfs_rwblock(sfs, &ku); }
int sfs_rblock(struct sfs_fs *sfs, void *data, uint32_t block) { struct iovec iov; struct uio ku; SFSUIO(&iov, &ku, data, block, UIO_READ); return sfs_rwblock(sfs, &ku); }
/* * Read a block. */ int sfs_readblock(struct fs *fs, daddr_t block, void *data, size_t len) { struct sfs_fs *sfs = fs->fs_data; struct iovec iov; struct uio ku; KASSERT(len == SFS_BLOCKSIZE); SFSUIO(&iov, &ku, data, block, UIO_READ); return sfs_rwblock(sfs, &ku); }
/* * Write a block. */ int sfs_writeblock(struct fs *fs, daddr_t block, void *fsbufdata, void *data, size_t len) { struct sfs_fs *sfs = fs->fs_data; struct iovec iov; struct uio ku; bool isjournal; int result; struct b_fsdata* b_fsdata = (struct b_fsdata*)fsbufdata; KASSERT(len == SFS_BLOCKSIZE); isjournal = sfs_block_is_journal(sfs, block); //kprintf("Writeblock metadata: %p\n", fsbufdata); if (isjournal) { /* * We're writing a journal buffer; the journal must be * written in order, so all earlier journal buffers * must be written first. * * One might think that a good and simple way to flush * the journal in order is to have each journal buffer * record that the previous journal buffer must be * written out before it. Then writing a journal * buffer will come here to write the previous one, * which will come here to write the previous one, and * so on until we get to the first remaining unwritten * journal buffer. This doesn't work: it runs off the * kernel stack. Also, it's likely to deadlock. * * Instead, we use special-case logic in the journal * code for this situation. */ //kprintf("Writing journal blocks\n"); result = sfs_jphys_flushforjournalblock(sfs, block); if (result) { return result; } } else if (b_fsdata != NULL) { //kprintf("\n\nBuffer %p is being written", b_fsdata->buf); // This is a standard non-journal block // Enforce write-ahead logging. Flush up to the most recent lsn to touch // this buffer KASSERT(b_fsdata->newest_lsn != 0); //kprintf("FLUSH (daddr %d): lsn %lld", b_fsdata->diskblock, b_fsdata->newest_lsn); sfs_jphys_flush(sfs, b_fsdata->newest_lsn); //kprintf("...Done.\n\n"); b_fsdata->newest_lsn = 0; b_fsdata->oldest_lsn = 0; } SFSUIO(&iov, &ku, data, block, UIO_WRITE); result = sfs_rwblock(sfs, &ku); if (result) { return result; } if (isjournal) { sfs_wrote_journal_block(sfs, block); } return 0; }