// 同步文件块 static int sfs_sync(struct fs *fs) { struct sfs_fs *sfs = fsop_info(fs, sfs); lock_sfs_fs(sfs); // 应该是用信号量锁定这个玩意 { list_entry_t *list = &(sfs->inode_list), *le = list; while ((le = list_next(le)) != list) { struct sfs_inode *sin = le2sin(le, inode_link); vop_fsync(info2node(sin, sfs_inode)); } } unlock_sfs_fs(sfs); int ret; if (sfs->super_dirty) { sfs->super_dirty = 0; if ((ret = sfs_sync_super(sfs)) != 0) { sfs->super_dirty = 1; return ret; } if ((ret = sfs_sync_freemap(sfs)) != 0) { sfs->super_dirty = 1; return ret; } } return 0; }
static int sfs_sync(struct fs *fs) { struct sfs_fs *sfs = fsop_info(fs, sfs); lock_sfs_fs(sfs); /* * Get the sfs_fs from the generic abstract fs. * * Note that the abstract struct fs, which is all the VFS * layer knows about, is actually a member of struct sfs_fs. * The pointer in the struct fs points back to the top of the * struct sfs_fs - essentially the same object. This can be a * little confusing at first. * * The following diagram may help: * * struct sfs_fs <-----------------\ * : | * : sfs_absfs (struct fs) | <------\ * : : | | * : : various members | | * : : | | * : : fs_info(__sfs_info) ---/ | * : : ...|... * : . VFS . * : . layer . * : other members ....... * : * : * * This construct is repeated with inodes and devices and other * similar things all over the place in ucore, so taking the * time to straighten it out in your mind is worthwhile. */ { list_entry_t *list = &(sfs->inode_list), *le = list; while ((le = list_next(le)) != list) { struct sfs_inode *sin = le2sin(le, inode_link); vop_fsync(info2node(sin, sfs_inode)); } } unlock_sfs_fs(sfs); int ret; if (sfs->super_dirty) { sfs->super_dirty = 0; /* If the superblock needs to be written, write it. */ if ((ret = sfs_sync_super(sfs)) != 0) { sfs->super_dirty = 1; return ret; } /* If the free block map needs to be written, write it. */ if ((ret = sfs_sync_freemap(sfs)) != 0) { sfs->super_dirty = 1; return ret; } } return 0; }
static int sfs_sync(struct fs *fs) { // debug // int u; // kprintf("--- %d ---\n", 1); // for (u = _initrd_begin; u < _initrd_end; ++u) { // kprintf("%02x ", *((char *)u)); // } // kprintf("\n"); struct sfs_fs *sfs = fsop_info(fs, sfs); lock_sfs_fs(sfs); { list_entry_t *list = &(sfs->inode_list), *le = list; while ((le = list_next(le)) != list) { struct sfs_inode *sin = le2sin(le, inode_link); vop_fsync(info2node(sin, sfs_inode)); } } unlock_sfs_fs(sfs); // kprintf("--- %d ---\n", 2); // for (u = _initrd_begin; u < _initrd_end; ++u) { // kprintf("%02x ", *((char *)u)); // } // kprintf("\n"); int ret; if (sfs->super_dirty) { sfs->super_dirty = 0; if ((ret = sfs_sync_super(sfs)) != 0) { sfs->super_dirty = 1; return ret; } if ((ret = sfs_sync_freemap(sfs)) != 0) { sfs->super_dirty = 1; return ret; } } // kprintf("--- %d ---\n", 3); // for (u = _initrd_begin; u < _initrd_end; ++u) { // kprintf("%02x ", *((char *)u)); // } // kprintf("\n"); swapper_all_block_sync(); return 0; }
static int sfs_fsync(struct inode *node) { struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs); struct sfs_inode *sin = vop_info(node, sfs_inode); int ret = 0; // if (sfs->super_dirty) { // lock_sfs_fs(sfs); // if (sfs->super_dirty) { // sfs->super_dirty = 0; // if ((ret = sfs_wbuf(sfs, sfs->freemap, sizeof(uint32_t) * 400, 1, 0)) != 0) { // // sfs_wbuf(struct sfs_fs *sfs, void *buf, size_t len, uint32_t blkno, off_t offset) // sfs->super_dirty = 1; // } // } // unlock_sfs_fs(sfs); // } if (sfs->super_dirty) { sfs_sync_super(sfs); sfs_sync_freemap(sfs); swapper_block_changed(0); } int secno = -1; if (sin->dirty) { lock_sin(sin); { if (sin->dirty) { sin->dirty = 0; if ((ret = sfs_wbuf(sfs, sin->din, sizeof(struct sfs_disk_inode), sin->ino, 0)) != 0) { sin->dirty = 1; } } } // int secno = 0; // kprintf("in %s: sin->din is %d sin->ino is %d\n", __func__, sin->din, sin->ino); int tmp_din = sin->ino; while (tmp_din >= 0) { secno += 1; // start from `-1` tmp_din -= 32; } unlock_sin(sin); } // kprintf("secno is %d sfs->super_dirty is %s\n", secno, sfs->super_dirty ? "true" : "false"); // assert((secno < 0 && !sfs->super_dirty) || (secno >= 0 && sfs->super_dirty)); if (secno != 0) { // kprintf("sync is secno %d\n", secno); if (sfs->super_dirty) { sfs->super_dirty = 0; swapper_block_sync(0); } if (secno > 0) { swapper_block_sync(secno); } } if (secno == 0) { swapper_block_sync(0); } swapper_block_real_sync(); // kprintf("super->unused_blocks is %d\n", sfs->super.unused_blocks); // uint16_t *begin = (uint16_t *)_initrd_begin; // int item = 0; // for (item = 0; item < 4000; ++item) { // kprintf("0x%04x ", begin[item]); // } // kprintf("in %s: %d is %s and addr. of sfs is 0x%08x addr. of freemap is 0x%08x\n", // __func__, 436, sfs_block_inuse(sfs, 436)?"used":"free", sfs, sfs->freemap); return ret; }