// mount 挂载sfs文件系统 static int sfs_do_mount(struct device *dev, struct fs **fs_store) { static_assert(SFS_BLKSIZE >= sizeof(struct sfs_super)); static_assert(SFS_BLKSIZE >= sizeof(struct sfs_disk_inode)); static_assert(SFS_BLKSIZE >= sizeof(struct sfs_disk_entry)); if (dev->d_blocksize != SFS_BLKSIZE) { return -E_NA_DEV; } /* allocate fs structure */ struct fs *fs; // 我要稍微说一下这里的sfs,alloc_fs以及fsop_info只是一个宏而已,展开之后就做了一系列的替换 // 所以sfs只是字符而已,不要大惊小怪 if ((fs = alloc_fs(sfs)) == NULL) { // 首先是分配一个fs结构,并且指定了类型 return -E_NO_MEM; } struct sfs_fs *sfs = fsop_info(fs, sfs); // 得到fs里面的__sfs_info结构的指针 sfs->dev = dev; // sfs主要是用于记录文件系统的一些信息 int ret = -E_NO_MEM; void *sfs_buffer; if ((sfs->sfs_buffer = sfs_buffer = kmalloc(SFS_BLKSIZE)) == NULL) { // 分配buffer goto failed_cleanup_fs; } /* load and check superblock */ // 加载和检查超级块 if ((ret = sfs_init_read(dev, SFS_BLKN_SUPER, sfs_buffer)) != 0) { goto failed_cleanup_sfs_buffer; } // 第一个扇区的东西就是超级块吗? ret = -E_INVAL; struct sfs_super *super = sfs_buffer; if (super->magic != SFS_MAGIC) { cprintf("sfs: wrong magic in superblock. (%08x should be %08x).\n", super->magic, SFS_MAGIC); goto failed_cleanup_sfs_buffer; } if (super->blocks > dev->d_blocks) { cprintf("sfs: fs has %u blocks, device has %u blocks.\n", super->blocks, dev->d_blocks); goto failed_cleanup_sfs_buffer; } super->info[SFS_MAX_INFO_LEN] = '\0'; sfs->super = *super; // 记录下超级块的信息 ret = -E_NO_MEM; uint32_t i; /* alloc and initialize hash list */ // 分配和初始化hash list list_entry_t *hash_list; if ((sfs->hash_list = hash_list = kmalloc(sizeof(list_entry_t) * SFS_HLIST_SIZE)) == NULL) { goto failed_cleanup_sfs_buffer; } for (i = 0; i < SFS_HLIST_SIZE; i ++) { // 为什么要分配那么多的hash_list? list_init(hash_list + i); // 都需要初始化 } /* load and check freemap */ // 加载和检查freemap struct bitmap *freemap; uint32_t freemap_size_nbits = sfs_freemap_bits(super); if ((sfs->freemap = freemap = bitmap_create(freemap_size_nbits)) == NULL) { goto failed_cleanup_hash_list; } uint32_t freemap_size_nblks = sfs_freemap_blocks(super); if ((ret = sfs_init_freemap(dev, freemap, SFS_BLKN_FREEMAP, freemap_size_nblks, sfs_buffer)) != 0) { goto failed_cleanup_freemap; } uint32_t blocks = sfs->super.blocks, unused_blocks = 0; for (i = 0; i < freemap_size_nbits; i ++) { if (bitmap_test(freemap, i)) { unused_blocks ++; } } assert(unused_blocks == sfs->super.unused_blocks); /* and other fields */ sfs->super_dirty = 0; sem_init(&(sfs->fs_sem), 1); sem_init(&(sfs->io_sem), 1); sem_init(&(sfs->mutex_sem), 1); list_init(&(sfs->inode_list)); cprintf("sfs: mount: '%s' (%d/%d/%d)\n", sfs->super.info, blocks - unused_blocks, unused_blocks, blocks); /* link addr of sync/get_root/unmount/cleanup funciton fs's function pointers*/ fs->fs_sync = sfs_sync; fs->fs_get_root = sfs_get_root; fs->fs_unmount = sfs_unmount; fs->fs_cleanup = sfs_cleanup; *fs_store = fs; return 0; failed_cleanup_freemap: bitmap_destroy(freemap); failed_cleanup_hash_list: kfree(hash_list); failed_cleanup_sfs_buffer: kfree(sfs_buffer); failed_cleanup_fs: kfree(fs); return ret; }
static int sfs_do_mount(struct device *dev, struct fs **fs_store) { /* * Make sure SFS on-disk structures aren't messed up */ static_assert(SFS_BLKSIZE >= sizeof(struct sfs_super)); static_assert(SFS_BLKSIZE >= sizeof(struct sfs_disk_inode)); static_assert(SFS_BLKSIZE >= sizeof(struct sfs_disk_entry)); /* * We can't mount on devices with the wrong sector size. * * (Note: for all intents and purposes here, "sector" and * "block" are interchangeable terms. Technically a filesystem * block may be composed of several hardware sectors, but we * don't do that in sfs.) */ if (dev->d_blocksize != SFS_BLKSIZE) { return -E_NA_DEV; } /* allocate fs structure */ struct fs *fs; if ((fs = alloc_fs(sfs)) == NULL) { return -E_NO_MEM; } /* get sfs from fs.fs_info.__sfs_info */ struct sfs_fs *sfs = fsop_info(fs, sfs); sfs->dev = dev; int ret = -E_NO_MEM; void *sfs_buffer; if ((sfs->sfs_buffer = sfs_buffer = kmalloc(SFS_BLKSIZE)) == NULL) { goto failed_cleanup_fs; } /* load and check sfs's superblock */ if ((ret = sfs_init_read(dev, SFS_BLKN_SUPER, sfs_buffer)) != 0) { goto failed_cleanup_sfs_buffer; } ret = -E_INVAL; struct sfs_super *super = sfs_buffer; /* Make some simple sanity checks */ if (super->magic != SFS_MAGIC) { cprintf("sfs: wrong magic in superblock. (%08x should be %08x).\n", super->magic, SFS_MAGIC); goto failed_cleanup_sfs_buffer; } if (super->blocks > dev->d_blocks) { cprintf("sfs: fs has %u blocks, device has %u blocks.\n", super->blocks, dev->d_blocks); goto failed_cleanup_sfs_buffer; } super->info[SFS_MAX_INFO_LEN] = '\0'; sfs->super = *super; ret = -E_NO_MEM; uint32_t i; /* alloc and initialize hash list */ list_entry_t *hash_list; if ((sfs->hash_list = hash_list = kmalloc(sizeof(list_entry_t) * SFS_HLIST_SIZE)) == NULL) { goto failed_cleanup_sfs_buffer; } for (i = 0; i < SFS_HLIST_SIZE; i ++) { list_init(hash_list + i); } /* load and check freemap (free space bitmap in disk) */ struct bitmap *freemap; uint32_t freemap_size_nbits = sfs_freemap_bits(super); if ((sfs->freemap = freemap = bitmap_create(freemap_size_nbits)) == NULL) { goto failed_cleanup_hash_list; } uint32_t freemap_size_nblks = sfs_freemap_blocks(super); if ((ret = sfs_init_freemap(dev, freemap, SFS_BLKN_FREEMAP, freemap_size_nblks, sfs_buffer)) != 0) { goto failed_cleanup_freemap; } uint32_t blocks = sfs->super.blocks, unused_blocks = 0; for (i = 0; i < freemap_size_nbits; i ++) { if (bitmap_test(freemap, i)) { unused_blocks ++; } } assert(unused_blocks == sfs->super.unused_blocks); /* and other fields */ sfs->super_dirty = 0; sem_init(&(sfs->fs_sem), 1); sem_init(&(sfs->io_sem), 1); sem_init(&(sfs->mutex_sem), 1); list_init(&(sfs->inode_list)); cprintf("sfs: mount: '%s' (%d/%d/%d)\n", sfs->super.info, blocks - unused_blocks, unused_blocks, blocks); /* Set up abstract fs calls */ fs->fs_sync = sfs_sync; fs->fs_get_root = sfs_get_root; fs->fs_unmount = sfs_unmount; fs->fs_cleanup = sfs_cleanup; *fs_store = fs; return 0; failed_cleanup_freemap: bitmap_destroy(freemap); failed_cleanup_hash_list: kfree(hash_list); failed_cleanup_sfs_buffer: kfree(sfs_buffer); failed_cleanup_fs: kfree(fs); return ret; }
static int sfs_do_mount(struct device *dev, struct fs **fs_store) { static_assert(SFS_BLKSIZE >= sizeof(struct sfs_super)); static_assert(SFS_BLKSIZE >= sizeof(struct sfs_disk_inode)); static_assert(SFS_BLKSIZE >= sizeof(struct sfs_disk_entry)); if (dev->d_blocksize != SFS_BLKSIZE) { return -E_NA_DEV; } /* allocate fs structure */ struct fs *fs; if ((fs = alloc_fs(sfs)) == NULL) { return -E_NO_MEM; } struct sfs_fs *sfs = fsop_info(fs, sfs); sfs->dev = dev; int ret = -E_NO_MEM; void *sfs_buffer; if ((sfs->sfs_buffer = sfs_buffer = kmalloc(SFS_BLKSIZE)) == NULL) { goto failed_cleanup_fs; } /* load and check superblock */ if ((ret = sfs_init_read(dev, SFS_BLKN_SUPER, sfs_buffer)) != 0) { goto failed_cleanup_sfs_buffer; } ret = -E_INVAL; struct sfs_super *super = sfs_buffer; if (super->magic != SFS_MAGIC) { kprintf("sfs: wrong magic in superblock. (%08x should be %08x).\n", super->magic, SFS_MAGIC); goto failed_cleanup_sfs_buffer; } if (super->blocks > dev->d_blocks) { kprintf("sfs: fs has %u blocks, device has %u blocks.\n", super->blocks, dev->d_blocks); goto failed_cleanup_sfs_buffer; } super->info[SFS_MAX_INFO_LEN] = '\0'; sfs->super = *super; ret = -E_NO_MEM; uint32_t i; /* alloc and initialize hash list */ list_entry_t *hash_list; if ((sfs->hash_list = hash_list = kmalloc(sizeof(list_entry_t) * SFS_HLIST_SIZE)) == NULL) { goto failed_cleanup_sfs_buffer; } for (i = 0; i < SFS_HLIST_SIZE; i ++) { list_init(hash_list + i); } /* load and check freemap */ struct bitmap *freemap; uint32_t freemap_size_nbits = sfs_freemap_bits(super); if ((sfs->freemap = freemap = bitmap_create(freemap_size_nbits)) == NULL) { goto failed_cleanup_hash_list; } uint32_t freemap_size_nblks = sfs_freemap_blocks(super); if ((ret = sfs_init_freemap(dev, freemap, SFS_BLKN_FREEMAP, freemap_size_nblks, sfs_buffer)) != 0) { goto failed_cleanup_freemap; } uint32_t blocks = sfs->super.blocks, unused_blocks = 0; for (i = 0; i < freemap_size_nbits; i ++) { if (bitmap_test(freemap, i)) { unused_blocks ++; } } kprintf("unused_blocks is %d and super->unused_blocks is %d", \ unused_blocks, sfs->super.unused_blocks); // while (1); assert(unused_blocks == sfs->super.unused_blocks); /* and other fields */ sfs->super_dirty = 0; sem_init(&(sfs->fs_sem), 1); sem_init(&(sfs->io_sem), 1); sem_init(&(sfs->mutex_sem), 1); list_init(&(sfs->inode_list)); kprintf("sfs: mount: '%s' (%d/%d/%d)\n", sfs->super.info, blocks - unused_blocks, unused_blocks, blocks); fs->fs_sync = sfs_sync; fs->fs_get_root = sfs_get_root; fs->fs_unmount = sfs_unmount; fs->fs_cleanup = sfs_cleanup; *fs_store = fs; return 0; failed_cleanup_freemap: bitmap_destroy(freemap); failed_cleanup_hash_list: kfree(hash_list); failed_cleanup_sfs_buffer: kfree(sfs_buffer); failed_cleanup_fs: kfree(fs); return ret; }