void mount_root(void) { register struct file_system_type **fs_type; register struct super_block *sb; struct inode *inode, d_inode; struct file filp; int retval; retry_floppy: memset(&filp, 0, sizeof(filp)); filp.f_inode = &d_inode; filp.f_mode = ((root_mountflags & MS_RDONLY) ? 1 : 3); memset(&d_inode, 0, sizeof(d_inode)); d_inode.i_rdev = ROOT_DEV; retval = blkdev_open(&d_inode, &filp); if (retval == -EROFS) { root_mountflags |= MS_RDONLY; filp.f_mode = 1; retval = blkdev_open(&d_inode, &filp); } for (fs_type = &file_systems[0]; *fs_type; fs_type++) { struct file_system_type *fp = *fs_type; if (retval) break; #ifdef BLOAT_FS if (!fp->requires_dev) continue; #endif sb = read_super(ROOT_DEV, fp->name, root_mountflags, NULL, 1); if (sb) { inode = sb->s_mounted; /* NOTE! it is logically used 4 times, not 1 */ inode->i_count += 3; sb->s_covered = inode; sb->s_flags = (unsigned short int) root_mountflags; current->fs.pwd = current->fs.root = inode; printk("VFS: Mounted root (%s filesystem)%s.\n", fp->name, (sb->s_flags & MS_RDONLY) ? " readonly" : ""); return; } } #ifdef CONFIG_BLK_DEV_BIOS if (ROOT_DEV == 0x0380) { if (filp.f_op->release) filp.f_op->release(&d_inode, &filp); else printk("Release not defined\n"); printk("VFS: Insert root floppy and press ENTER\n"); wait_for_keypress(); goto retry_floppy; } #endif panic("VFS: Unable to mount root fs on %s\n", kdevname(ROOT_DEV)); }
int main( int argc, char **argv) { int rc = 0; int c; int debug_wait; HFILE device_handle; int32 phys_block_size; if( argc != 2 ) { printf("usage: validfs <fs device> ...\n"); exit(1); } rc = ujfs_open_device(argv[1], &device_handle, &phys_block_size, READONLY); if( rc != 0 ) { printf("open of device %s failed.\n", argv[1] ); exit(1); } rc = read_super( device_handle ); if( rc != 0 ) { printf("Failed reading superblock.\n"); exit(rc); } rc = validfs( device_handle ); if( rc == 0 && error == 0 ) { printf("XJFS filesystem %s looks GOOD!\n", argv[1]); } ujfs_close(device_handle); exit(rc); }
/* * do_mount() does the actual mounting after sys_mount has done the ugly * parameter parsing. When enough time has gone by, and everything uses the * new mount() parameters, sys_mount() can then be cleaned up. * * We cannot mount a filesystem if it has active, used, or dirty inodes. * We also have to flush all inode-data for this device, as the new mount * might need new info. */ static int do_mount(dev_t dev, const char * dir, const char * type, int flags, void * data) { struct inode *dir_i; struct super_block *sb; int error; error = namei(dir, &dir_i); if (error) return error; if (dir_i->i_count != 1 || dir_i->i_mount) { iput(dir_i); return -EBUSY; } if (!S_ISDIR(dir_i->i_mode)) { iput(dir_i); return -EPERM; } //if (!fs_may_mount(dev)) { // iput(dir_i); // return -EBUSY; //} sb = read_super(dev, type, flags, data, 0); if (!sb || sb->s_covered) { iput(dir_i); return -EBUSY; } sb->s_covered = dir_i; dir_i->i_mount = sb->s_mounted; return 0; // we don't iput(dir_i) - see umount }
int fs_init(dev_t dev) { fs_dev->f_op = dev_operations(dev); read_super(); cache_init(); /* register sys calls */ SCALL_REGISTER(3, sys_read); SCALL_REGISTER(4, sys_write); SCALL_REGISTER(5, fs_open); SCALL_REGISTER(6, fs_close); SCALL_REGISTER(10, fs_unlink); SCALL_REGISTER(12, fs_chdir); SCALL_REGISTER(19, sys_lseek); SCALL_REGISTER(38, fs_rename); SCALL_REGISTER(39, fs_mkdir); SCALL_REGISTER(40, fs_rmdir); SCALL_REGISTER(141, fs_getdents); SCALL_REGISTER(200, sys_flush); /* register fs device */ dev_register(DEV_FS, &ops); return OK; }
static void test_fs(int start) { struct cramfs_inode *root; root = read_super(); umask(0); euid = geteuid(); stream.next_in = NULL; stream.avail_in = 0; inflateInit(&stream); expand_fs(extract_dir, root); inflateEnd(&stream); if (start_data != ~0UL) { if (start_data < (sizeof(struct cramfs_super) + start)) errx(FSCK_EX_UNCORRECTED, _("directory data start (%lu) < sizeof(struct cramfs_super) + start (%zu)"), start_data, sizeof(struct cramfs_super) + start); if (end_dir != start_data) errx(FSCK_EX_UNCORRECTED, _("directory data end (%lu) != file data start (%lu)"), end_dir, start_data); } if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) if (end_data > super.size) errx(FSCK_EX_UNCORRECTED, _("invalid file data offset")); iput(root); /* free(root) */ }
int do_mount(kdev_t dev, char *dir, char *type, int flags, char *data) { struct inode *dir_i; register struct inode *dirp; register struct super_block *sb; int error; if ((error = namei(dir, &dir_i, IS_DIR, 0))) return error; dirp = dir_i; if ((dirp->i_count != 1 || dirp->i_mount) || (!fs_may_mount(dev)) ) { goto BUSY; } sb = read_super(dev, type, flags, data, 0); if (!sb) { iput(dirp); return -EINVAL; } if (sb->s_covered) { BUSY: iput(dirp); return -EBUSY; } sb->s_covered = dirp; dirp->i_mount = sb->s_mounted; return 0; /* we don't iput(dir_i) - see umount */ }
/*===========================================================================* * fs_readsuper_o * *===========================================================================*/ PUBLIC int fs_readsuper_o() { /* This function reads the superblock of the partition, gets the root inode * and sends back the details of them. Note, that the FS process does not * know the index of the vmnt object which refers to it, whenever the pathname * lookup leaves a partition an ELEAVEMOUNT error is transferred back * so that the VFS knows that it has to find the vnode on which this FS * process' partition is mounted on. */ struct super_block *xp; struct inode *root_ip; int r = OK; phys_bytes ph; fs_dev = fs_m_in.REQ_DEV; /* Map the driver endpoint for this major */ driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = fs_m_in.REQ_DRIVER_E; boottime = fs_m_in.REQ_BOOTTIME; vfs_slink_storage = fs_m_in.REQ_SLINK_STORAGE; /* Fill in the super block. */ superblock.s_dev = fs_dev; /* read_super() needs to know which dev */ r = read_super(&superblock); /* Is it recognized as a Minix filesystem? */ if (r != OK) { superblock.s_dev = NO_DEV; return(r); } set_blocksize(superblock.s_block_size); /* Get the root inode of the mounted file system. */ root_ip = NIL_INODE; /* if 'r' not OK, make sure this is defined */ if (r == OK) { if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NIL_INODE) r = err_code; } if (root_ip != NIL_INODE && root_ip->i_mode == 0) { put_inode(root_ip); r = EINVAL; } if (r != OK) return r; superblock.s_rd_only = fs_m_in.REQ_READONLY; superblock.s_is_root = fs_m_in.REQ_ISROOT; /* Root inode properties */ fs_m_out.RES_INODE_NR = root_ip->i_num; fs_m_out.RES_MODE = root_ip->i_mode; fs_m_out.RES_FILE_SIZE = root_ip->i_size; /* Partition properties */ fs_m_out.RES_MAXSIZE = superblock.s_max_size; fs_m_out.RES_BLOCKSIZE = superblock.s_block_size; return r; }
int orig_do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data) { #endif struct dentry * dir_d; struct super_block * sb; struct vfsmount *vfsmnt; int error; error = -EACCES; if (!(flags & MS_RDONLY) && dev && is_read_only(dev)) goto out; /* * Do the lookup first to force automounting. */ dir_d = namei(dir_name); error = PTR_ERR(dir_d); if (IS_ERR(dir_d)) goto out; down(&mount_sem); error = -ENOTDIR; if (!S_ISDIR(dir_d->d_inode->i_mode)) goto dput_and_out; error = -EBUSY; if (dir_d->d_covers != dir_d) goto dput_and_out; /* * Note: If the superblock already exists, * read_super just does a get_super(). */ error = -EINVAL; sb = read_super(dev, type, flags, data, 0); if (!sb) goto dput_and_out; /* * We may have slept while reading the super block, * so we check afterwards whether it's safe to mount. */ error = -EBUSY; if (!fs_may_mount(dev)) goto dput_and_out; error = -ENOMEM; vfsmnt = add_vfsmnt(sb, dev_name, dir_name); if (vfsmnt) { d_mount(dget(dir_d), sb->s_root); error = 0; } dput_and_out: dput(dir_d); up(&mount_sem); out: return error; }
void mount_root(void) { struct super_block *sb; struct inode *inode; memset(super_blocks, 0, sizeof(super_blocks)); if (!(sb = read_super(ROOT_DEV, ROOT_FS, root_mountflags, NULL, 1))) panic("VFS: unable to mount root"); root_inode = inode = sb->s_mounted; inode->i_count += 3; sb->s_covered = inode; }
int main(int argc, char **argv) { FILE *boot, *img; char boot_buf[512]; short buf2[512]; short blocks[256]; struct inode inode; int i = 0; if (argc != 3) { fprintf(stderr, "install-boot boot.bin dev_name\n"); exit(0); } boot = fopen(argv[1], "rb"); if (boot == NULL) { fprintf(stderr, "File Open Error:%s", argv[3]); exit(0); } img = fopen(argv[2], "r+"); if (img == NULL) { fprintf(stderr, "File Open Error:%s", argv[1]); exit(0); } fread(boot_buf, 512, 1, boot); fclose(boot); read_super(img); read_inode(img, 1, &inode); look_up(img, &inode, "boot"); look_up(img, &inode, "kernel"); memset(blocks, 0, 512); for (i = 0; i < 7; i++) blocks[i] = inode.i_zone[i]; read_block(img, inode.i_zone[7], (char*) buf2); while (i * 1024 < inode.i_size) { blocks[i] = buf2[i - 7]; i++; } fseek(img, 0, 0); fwrite(boot_buf, 1, 512, img); fwrite(blocks, 1, 512, img); fclose(img); }
// Initialize the file system void fs_init(void) { static_assert(sizeof(struct File) == 256); // Find a JOS disk. Use the second IDE disk (number 1) if available. if (ide_probe_disk1()) ide_set_disk(1); else ide_set_disk(0); read_super(); check_write_block(); read_bitmap(); }
/*===========================================================================* * fs_inodewalker * *===========================================================================*/ int fs_inodewalker() { /* Get the list of blocks in use by the system from the inode bitmap */ printf("Inode Walker\n"); printf("Getting super node from device %llu ...\n", fs_dev); type = IMAP; sb = get_super(fs_dev); read_super(sb); lsuper(); init_global(); imap_disk = alloc_bitmap(N_IMAP); printf("Loading inode bitmap from disk ...\n"); get_bitmap(imap_disk, IMAP); printf(" done.\n"); sleep(3); int *list_inodes = get_list_used(imap_disk, IMAP); free_bitmap(imap_disk); return 0; }
int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data) { struct inode * dir_i; struct super_block * sb; struct vfsmount *vfsmnt; int error; if (!(flags & MS_RDONLY) && dev && is_read_only(dev)) return -EACCES; /*flags |= MS_RDONLY;*/ error = namei(dir_name, &dir_i); if (error) return error; if (dir_i->i_count != 1 || dir_i->i_mount) { iput(dir_i); return -EBUSY; } if (!S_ISDIR(dir_i->i_mode)) { iput(dir_i); return -ENOTDIR; } if (!fs_may_mount(dev)) { iput(dir_i); return -EBUSY; } sb = read_super(dev,type,flags,data,0); if (!sb) { iput(dir_i); return -EINVAL; } if (sb->s_covered) { iput(dir_i); return -EBUSY; } vfsmnt = add_vfsmnt(dev, dev_name, dir_name); if (vfsmnt) { vfsmnt->mnt_sb = sb; vfsmnt->mnt_flags = flags; } sb->s_covered = dir_i; dir_i->i_mount = sb->s_mounted; return 0; /* we don't iput(dir_i) - see umount */ }
/*===========================================================================* * fs_zonewalker * *===========================================================================*/ int fs_zonewalker() { /* Get the list of blocks used by the system from the zone bitmap */ printf("Zone Walkder\n"); printf("Getting super node from device %llu ...\n", fs_dev); type = ZMAP; sb = get_super(fs_dev); read_super(sb); lsuper(); sleep(3); init_global(); zmap_disk = alloc_bitmap(N_ZMAP); printf("Loading zone bitmap from disk ...\n"); get_bitmap(zmap_disk, ZMAP); printf(" done.\n\n"); sleep(3); //print_bitmap(zmap_disk); int* list = get_list_used(zmap_disk, ZMAP); free_bitmap(zmap_disk); return 0; }
fs_context* mount(io_backend* ctx) { if (!ctx) { log().error("ffsp::mount(): invalid io backend"); return nullptr; } auto fs = std::make_unique<fs_context>(); fs->io_ctx = ctx; if ( !read_super(*fs) || !read_eb_usage(*fs) || !read_ino_map(*fs)) { log().critical("ffsp::mount(): failed to read data from super erase block"); return nullptr; } if (!read_cl_occupancy(*fs)) { log().critical("ffsp::mount(): failed to read cluster occupancy data"); return nullptr; } fs->summary_cache = summary_cache_init(*fs); fs->inode_cache = inode_cache_init(*fs); fs->gcinfo = gcinfo_init(*fs); size_t ino_bitmask_size = fs->nino / 8; fs->ino_status_map = new uint32_t[ino_bitmask_size / sizeof(uint32_t)]; memset(fs->ino_status_map, 0, ino_bitmask_size); fs->buf = new char[fs->erasesize]; return fs.release(); }
/*===========================================================================* * fs_readsuper * *===========================================================================*/ PUBLIC int fs_readsuper() { /* This function reads the superblock of the partition, gets the root inode * and sends back the details of them. Note, that the FS process does not * know the index of the vmnt object which refers to it, whenever the pathname * lookup leaves a partition an ELEAVEMOUNT error is transferred back * so that the VFS knows that it has to find the vnode on which this FS * process' partition is mounted on. */ struct inode *root_ip; cp_grant_id_t label_gid; size_t label_len; int r = OK; int readonly, isroot; u32_t mask; fs_dev = fs_m_in.REQ_DEV; label_gid = fs_m_in.REQ_GRANT; label_len = fs_m_in.REQ_PATH_LEN; readonly = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0; isroot = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0; if (label_len > sizeof(fs_dev_label)) return(EINVAL); r = sys_safecopyfrom(fs_m_in.m_source, label_gid, 0, (vir_bytes)fs_dev_label, label_len, D); if (r != OK) { printf("%s:%d fs_readsuper: safecopyfrom failed: %d\n", __FILE__, __LINE__, r); return(EINVAL); } /* Map the driver label for this major. */ bdev_driver(fs_dev, fs_dev_label); /* Open the device the file system lives on. */ if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) { return(EINVAL); } /* Fill in the super block. */ STATICINIT(superblock, 1); if (!superblock) panic("Can't allocate memory for superblock."); superblock->s_dev = fs_dev; /* read_super() needs to know which dev */ r = read_super(superblock); /* Is it recognized as a Minix filesystem? */ if (r != OK) { superblock->s_dev = NO_DEV; bdev_close(fs_dev); return(r); } if (superblock->s_rev_level != EXT2_GOOD_OLD_REV) { struct super_block *sp = superblock; /* just shorter name */ mask = ~SUPPORTED_INCOMPAT_FEATURES; if (HAS_INCOMPAT_FEATURE(sp, mask)) { if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_COMPRESSION & mask)) printf("ext2: fs compression is not supported by server\n"); if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_FILETYPE & mask)) printf("ext2: fs in dir filetype is not supported by server\n"); if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_RECOVER & mask)) printf("ext2: fs recovery is not supported by server\n"); if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_JOURNAL_DEV & mask)) printf("ext2: fs journal dev is not supported by server\n"); if (HAS_INCOMPAT_FEATURE(sp, INCOMPAT_META_BG & mask)) printf("ext2: fs meta bg is not supported by server\n"); return(EINVAL); } mask = ~SUPPORTED_RO_COMPAT_FEATURES; if (HAS_RO_COMPAT_FEATURE(sp, mask)) { if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_SPARSE_SUPER & mask)) { printf("ext2: sparse super is not supported by server, \ remount read-only\n"); } if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_LARGE_FILE & mask)) { printf("ext2: large files are not supported by server, \ remount read-only\n"); } if (HAS_RO_COMPAT_FEATURE(sp, RO_COMPAT_BTREE_DIR & mask)) { printf("ext2: dir's btree is not supported by server, \ remount read-only\n"); } return(EINVAL); } } if (superblock->s_state == EXT2_ERROR_FS) { printf("ext2: filesystem wasn't cleanly unmounted previous time\n"); superblock->s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } set_blocksize(superblock->s_block_size, superblock->s_blocks_count, superblock->s_free_blocks_count, major(fs_dev)); /* Get the root inode of the mounted file system. */ if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL) { printf("ext2: couldn't get root inode\n"); superblock->s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } if (root_ip != NULL && root_ip->i_mode == 0) { printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__); put_inode(root_ip); superblock->s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } if (root_ip != NULL && (root_ip->i_mode & I_TYPE) != I_DIRECTORY) { printf("%s:%d root inode has wrong type, it's not a DIR\n", __FILE__, __LINE__); put_inode(root_ip); superblock->s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } superblock->s_rd_only = readonly; superblock->s_is_root = isroot; if (!readonly) { superblock->s_state = EXT2_ERROR_FS; superblock->s_mnt_count++; superblock->s_mtime = clock_time(); write_super(superblock); /* Commit info, we just set above */ } /* Root inode properties */ fs_m_out.RES_INODE_NR = root_ip->i_num; fs_m_out.RES_MODE = root_ip->i_mode; fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size; fs_m_out.RES_UID = root_ip->i_uid; fs_m_out.RES_GID = root_ip->i_gid; fs_m_out.RES_CONREQS = 1; /* We can handle only 1 request at a time */ return(r); }
static void do_mount_root(void) { struct file_system_type * fs_type; struct super_block * sb; struct vfsmount *vfsmnt; struct inode * inode, d_inode; struct file filp; int retval; #ifdef CONFIG_ROOT_NFS if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) if (nfs_root_init(nfs_root_name, nfs_root_addrs) < 0) { printk(KERN_ERR "Root-NFS: Unable to contact NFS " "server for root fs, using /dev/fd0 instead\n"); ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0); } if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { ROOT_DEV = 0; if ((fs_type = get_fs_type("nfs"))) { sb = &super_blocks[0]; while (sb->s_dev) sb++; sb->s_dev = get_unnamed_dev(); sb->s_flags = root_mountflags & ~MS_RDONLY; if (nfs_root_mount(sb) >= 0) { inode = sb->s_mounted; inode->i_count += 3 ; sb->s_covered = inode; sb->s_rd_only = 0; sb->s_dirt = 0; sb->s_type = fs_type; current->fs->pwd = inode; current->fs->root = inode; ROOT_DEV = sb->s_dev; printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n"); vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/"); if (!vfsmnt) panic("VFS: add_vfsmnt failed for NFS root.\n"); vfsmnt->mnt_sb = sb; vfsmnt->mnt_flags = sb->s_flags; return; } sb->s_dev = 0; } if (!ROOT_DEV) { printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0); } } #endif #ifdef CONFIG_BLK_DEV_FD if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { floppy_eject(); printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n"); wait_for_keypress(); } #endif memset(&filp, 0, sizeof(filp)); memset(&d_inode, 0, sizeof(d_inode)); d_inode.i_rdev = ROOT_DEV; filp.f_inode = &d_inode; if ( root_mountflags & MS_RDONLY) filp.f_mode = 1; /* read only */ else filp.f_mode = 3; /* read write */ retval = blkdev_open(&d_inode, &filp); if (retval == -EROFS) { root_mountflags |= MS_RDONLY; filp.f_mode = 1; retval = blkdev_open(&d_inode, &filp); } if (retval) /* * Allow the user to distinguish between failed open * and bad superblock on root device. */ printk("VFS: Cannot open root device %s\n", kdevname(ROOT_DEV)); else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) { if (!fs_type->requires_dev) continue; sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1); if (sb) { inode = sb->s_mounted; inode->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */ sb->s_covered = inode; sb->s_flags = root_mountflags; current->fs->pwd = inode; current->fs->root = inode; printk ("VFS: Mounted root (%s filesystem)%s.\n", fs_type->name, (sb->s_flags & MS_RDONLY) ? " readonly" : ""); vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/"); if (!vfsmnt) panic("VFS: add_vfsmnt failed for root fs"); vfsmnt->mnt_sb = sb; vfsmnt->mnt_flags = root_mountflags; return; } } panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV)); }
int main(int argc, char **argv) { void *buf; size_t length; struct stat st; unsigned long crc_old, crc_new; #ifdef INCLUDE_FS_TESTS struct cramfs_inode *root; #endif /* INCLUDE_FS_TESTS */ int c; /* for getopt */ int start = 0; if (argc) progname = argv[0]; /* command line options */ while ((c = getopt(argc, argv, "hx:v")) != EOF) { switch (c) { case 'h': usage(0); case 'x': #ifdef INCLUDE_FS_TESTS opt_extract = 1; extract_dir = malloc(strlen(optarg) + 1); strcpy(extract_dir, optarg); break; #else /* not INCLUDE_FS_TESTS */ fprintf(stderr, "%s: compiled without -x support\n", progname); exit(16); #endif /* not INCLUDE_FS_TESTS */ case 'v': opt_verbose++; break; } } if ((argc - optind) != 1) usage(16); filename = argv[optind]; /* find the physical size of the file or block device */ if (lstat(filename, &st) < 0) { perror(filename); exit(8); } fd = open(filename, O_RDONLY); if (fd < 0) { perror(filename); exit(8); } if (S_ISBLK(st.st_mode)) { if (ioctl(fd, BLKGETSIZE, &length) < 0) { fprintf(stderr, "%s: warning--unable to determine filesystem size \n", filename); exit(4); } length = length * 512; } else if (S_ISREG(st.st_mode)) { length = st.st_size; } else { fprintf(stderr, "%s is not a block device or file\n", filename); exit(8); } if (length < sizeof(struct cramfs_super)) { fprintf(stderr, "%s: invalid cramfs--file length too short\n", filename); exit(4); } if (S_ISBLK(st.st_mode)) { /* nasty because mmap of block devices fails */ buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); read(fd, buf, length); } else { /* nice and easy */ buf = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); } /* XXX - this could be cleaner... */ if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) { start = 0; super = (struct cramfs_super *) buf; } else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) && ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC))) { start = PAD_SIZE; super = (struct cramfs_super *) (buf + PAD_SIZE); } else { fprintf(stderr, "%s: invalid cramfs--wrong magic\n", filename); exit(4); } if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) { /* length test */ if (length < super->size) { fprintf(stderr, "%s: invalid cramfs--file length too short\n", filename); exit(4); } else if (length > super->size) { fprintf(stderr, "%s: warning--file length too long, padded image?\n", filename); } /* CRC test */ crc_old = super->fsid.crc; super->fsid.crc = crc32(0L, Z_NULL, 0); crc_new = crc32(0L, Z_NULL, 0); crc_new = crc32(crc_new, (unsigned char *) buf+start, super->size - start); if (crc_new != crc_old) { fprintf(stderr, "%s: invalid cramfs--crc error\n", filename); exit(4); } } else { fprintf(stderr, "%s: warning--old cramfs image, no CRC\n", filename); } #ifdef INCLUDE_FS_TESTS super = (struct cramfs_super *) malloc(sizeof(struct cramfs_super)); if (((struct cramfs_super *) buf)->magic == CRAMFS_MAGIC) { memcpy(super, buf, sizeof(struct cramfs_super)); } else if (length >= (PAD_SIZE + sizeof(struct cramfs_super)) && ((((struct cramfs_super *) (buf + PAD_SIZE))->magic == CRAMFS_MAGIC))) { memcpy(super, (buf + PAD_SIZE), sizeof(struct cramfs_super)); } munmap(buf, length); /* file format test, uses fake "blocked" accesses */ root = read_super(); umask(0); euid = geteuid(); if (!root) { fprintf(stderr, "%s: invalid cramfs--bad superblock\n", filename); exit(4); } stream.next_in = NULL; stream.avail_in = 0; inflateInit(&stream); if (!extract_dir) { extract_dir = "root"; } expand_fs(strlen(extract_dir), extract_dir, root); inflateEnd(&stream); if (start_data != 1 << 28 && end_inode != start_data) { fprintf(stderr, "%s: invalid cramfs--directory data end (%ld) != file data start (%ld)\n", filename, end_inode, start_data); exit(4); } if (super->flags & CRAMFS_FLAG_FSID_VERSION_2) { if (end_data > super->size) { fprintf(stderr, "%s: invalid cramfs--invalid file data offset\n", filename); exit(4); } } #endif /* INCLUDE_FS_TESTS */ exit(0); }
void __init mount_root(void) { struct file_system_type * fs_type; struct super_block * sb; struct vfsmount *vfsmnt; struct inode * d_inode = NULL; struct file filp; int retval; #ifdef CONFIG_ROOT_NFS if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { ROOT_DEV = 0; if ((fs_type = get_fs_type("nfs"))) { sb = get_empty_super(); /* "can't fail" */ sb->s_dev = get_unnamed_dev(); sb->s_flags = root_mountflags; sema_init(&sb->s_vfs_rename_sem,1); vfsmnt = add_vfsmnt(sb, "/dev/root", "/"); if (vfsmnt) { if (nfs_root_mount(sb) >= 0) { sb->s_dirt = 0; sb->s_type = fs_type; current->fs->root = dget(sb->s_root); current->fs->pwd = dget(sb->s_root); ROOT_DEV = sb->s_dev; printk (KERN_NOTICE "VFS: Mounted root (NFS filesystem)%s.\n", (sb->s_flags & MS_RDONLY) ? " readonly" : ""); return; } remove_vfsmnt(sb->s_dev); } put_unnamed_dev(sb->s_dev); sb->s_dev = 0; } if (!ROOT_DEV) { printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0); } } #endif #ifdef CONFIG_BLK_DEV_FD if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; #endif floppy_eject(); #ifndef CONFIG_BLK_DEV_RAM printk(KERN_NOTICE "(Warning, this kernel has no ramdisk support)\n"); #else /* rd_doload is 2 for a dual initrd/ramload setup */ if(rd_doload==2) rd_load_secondary(); else #endif { printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n"); wait_for_keypress(); } } #endif memset(&filp, 0, sizeof(filp)); d_inode = get_empty_inode(); d_inode->i_rdev = ROOT_DEV; filp.f_dentry = NULL; if ( root_mountflags & MS_RDONLY) filp.f_mode = 1; /* read only */ else filp.f_mode = 3; /* read write */ retval = blkdev_open(d_inode, &filp); if (retval == -EROFS) { root_mountflags |= MS_RDONLY; filp.f_mode = 1; retval = blkdev_open(d_inode, &filp); } iput(d_inode); if (retval) /* * Allow the user to distinguish between failed open * and bad superblock on root device. */ printk("VFS: Cannot open root device %s\n", kdevname(ROOT_DEV)); else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) { if (!(fs_type->fs_flags & FS_REQUIRES_DEV)) continue; sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,root_mount_data,1); if (sb) { sb->s_flags = root_mountflags; current->fs->root = dget(sb->s_root); current->fs->pwd = dget(sb->s_root); printk ("VFS: Mounted root (%s filesystem)%s.\n", fs_type->name, (sb->s_flags & MS_RDONLY) ? " readonly" : ""); vfsmnt = add_vfsmnt(sb, "/dev/root", "/"); if (vfsmnt) return; panic("VFS: add_vfsmnt failed for root fs"); } } #ifdef CONFIG_EMPEG_DISPLAY display_bootfail(); #endif panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV)); }
int guess_filesystem(int start_session) { int ret = 0; read_super(start_session); #undef _DEBUG #ifdef _DEBUG /* buffer is defined */ if (is_cdi()) printf("CD-I, "); if (is_cd_rtos()) printf("CD-RTOS, "); if (is_isofs()) printf("ISOFS, "); if (is_hs()) printf("HS, "); if (is_bridge()) printf("BRIDGE, "); if (is_xa()) printf("XA, "); if (is_cdtv()) printf("CDTV, "); puts(""); #endif /* filesystem */ if (is_cdi() && is_cd_rtos() && !is_bridge() && !is_xa()) { return FS_INTERACTIVE; } else { /* read sector 0 ONLY, when NO greenbook CD-I !!!! */ read_super2(start_session); #ifdef _DEBUG /* buffer2 is defined */ if (is_photocd()) printf("PHOTO CD, "); if (is_hfs()) printf("HFS, "); if (is_ext2()) printf("EXT2 FS, "); puts(""); #endif if (is_hs()) ret |= FS_HIGH_SIERRA; else if (is_isofs()) { if (is_cd_rtos() && is_bridge()) ret = FS_ISO_9660_INTERACTIVE; else if (is_hfs()) ret = FS_ISO_HFS; else ret = FS_ISO_9660; isofs_size = get_size(); read_super4(start_session); #ifdef _DEBUG /* buffer4 is defined */ if (is_bootable()) printf("BOOTABLE, "); puts(""); #endif if (is_bootable()) ret |= BOOTABLE; if (is_bridge() && is_xa() && is_isofs() && is_cd_rtos()) { read_super5(start_session); #ifdef _DEBUG /* buffer5 is defined */ if (is_video_cdi()) printf("VIDEO-CDI, "); puts(""); #endif if (is_video_cdi()) ret |= VIDEOCDI; } } else if (is_hfs()) ret |= FS_HFS; else if (is_ext2()) ret |= FS_EXT2; else { read_super3(start_session); #ifdef _DEBUG /* buffer3 is defined */ if (is_ufs()) printf("UFS, "); puts(""); #endif if (is_ufs()) ret |= FS_UFS; else ret |= FS_UNKNOWN; } } /* other checks */ if (is_xa()) ret |= XA; if (is_photocd()) ret |= PHOTO_CD; if (is_cdtv()) ret |= CDTV; return ret; }
/*===========================================================================* * fs_readsuper * *===========================================================================*/ PUBLIC int fs_readsuper() { /* This function reads the superblock of the partition, gets the root inode * and sends back the details of them. Note, that the FS process does not * know the index of the vmnt object which refers to it, whenever the pathname * lookup leaves a partition an ELEAVEMOUNT error is transferred back * so that the VFS knows that it has to find the vnode on which this FS * process' partition is mounted on. */ struct inode *root_ip; cp_grant_id_t label_gid; size_t label_len; int r; int readonly, isroot; fs_dev = (dev_t) fs_m_in.REQ_DEV; label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT; label_len = (size_t) fs_m_in.REQ_PATH_LEN; readonly = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0; isroot = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0; if (label_len > sizeof(fs_dev_label)) return(EINVAL); r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0, (vir_bytes) fs_dev_label, label_len, D); if (r != OK) { printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r); return(EINVAL); } /* Map the driver label for this major. */ bdev_driver(fs_dev, fs_dev_label); /* Open the device the file system lives on. */ if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) { return(EINVAL); } /* Fill in the super block. */ superblock.s_dev = fs_dev; /* read_super() needs to know which dev */ r = read_super(&superblock); /* Is it recognized as a Minix filesystem? */ if (r != OK) { superblock.s_dev = NO_DEV; bdev_close(fs_dev); return(r); } /* Remember whether we were mounted cleanly so we know what to * do at unmount time */ if(superblock.s_flags & MFSFLAG_CLEAN) cleanmount = 1; /* clean check: if rw and not clean, switch to readonly */ if(!(superblock.s_flags & MFSFLAG_CLEAN) && !readonly) { if(bdev_close(fs_dev) != OK) panic("couldn't bdev_close after found unclean FS"); readonly = 1; if (bdev_open(fs_dev, R_BIT) != OK) { panic("couldn't bdev_open after found unclean FS"); return(EINVAL); } printf("MFS: WARNING: FS 0x%x unclean, mounting readonly\n", fs_dev); } set_blocksize(&superblock); /* Get the root inode of the mounted file system. */ if( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL) { printf("MFS: couldn't get root inode\n"); superblock.s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } if(root_ip->i_mode == 0) { printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__); put_inode(root_ip); superblock.s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } superblock.s_rd_only = readonly; superblock.s_is_root = isroot; /* Root inode properties */ fs_m_out.RES_INODE_NR = root_ip->i_num; fs_m_out.RES_MODE = root_ip->i_mode; fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size; fs_m_out.RES_UID = root_ip->i_uid; fs_m_out.RES_GID = root_ip->i_gid; fs_m_out.RES_CONREQS = 1; /* We can handle only 1 request at a time */ /* Mark it dirty */ if(!superblock.s_rd_only) { superblock.s_flags &= ~MFSFLAG_CLEAN; if(write_super(&superblock) != OK) panic("mounting: couldn't write dirty superblock"); } return(r); }
/*===========================================================================* * cdprobe * *===========================================================================*/ PUBLIC int cdprobe(void) { #define CD_SECTOR 2048 #define AT_MAJOR 3 #define AT_MINORS 4 int i, minors[AT_MINORS] = { 0, 5, 10, 15 }, dev = 0, found = 0; char pvd[CD_SECTOR]; printf("\nLooking for boot CD. This may take a minute.\n" "Please ignore any error messages.\n\n"); for(i = 0; i < AT_MINORS && !found; i++) { struct super_block probe_super; int r, minor; dev = (AT_MAJOR << MAJOR) | minors[i]; /* Open device readonly. (This fails if the device * is also writable, which a CD isn't.) */ if ((r = dev_open(dev, FS_PROC_NR, RO_BIT)) != OK) { continue; } if ((r = dev_io(DEV_READ, dev, FS_PROC_NR, pvd, 16*CD_SECTOR, sizeof(pvd), 0)) != sizeof(pvd)) { dev_close(dev); continue; } dev_close(dev); /* Check PVD ID. */ if (pvd[0] != 1 || pvd[1] != 'C' || pvd[2] != 'D' || pvd[3] != '0' || pvd[4] != '0' || pvd[5] != '1' || pvd[6] != 1 || strncmp(pvd + 40, "MINIX", 5)) { continue; } /* 3. Both c0dXp1 and p2 should have a superblock. */ for(minor = minors[i]+2; minor <= minors[i]+3; minor++) { dev = (AT_MAJOR << MAJOR) | minor; if ((r = dev_open(dev, FS_PROC_NR, R_BIT)) != OK) { break; } probe_super.s_dev = dev; r = read_super(&probe_super); dev_close(dev); if (r != OK) { break; } } if (minor > minors[i]+3) { /* Success? Then set dev to p1. */ dev = (AT_MAJOR << MAJOR) | (minors[i]+2); found = 1; break; } } if (!found) return NO_DEV; return dev; }
/*===========================================================================* * fs_readsuper * *===========================================================================*/ PUBLIC int fs_readsuper() { /* This function reads the superblock of the partition, gets the root inode * and sends back the details of them. Note, that the FS process does not * know the index of the vmnt object which refers to it, whenever the pathname * lookup leaves a partition an ELEAVEMOUNT error is transferred back * so that the VFS knows that it has to find the vnode on which this FS * process' partition is mounted on. */ struct inode *root_ip; cp_grant_id_t label_gid; size_t label_len; int r; endpoint_t driver_e; int readonly, isroot; fs_dev = (dev_t) fs_m_in.REQ_DEV; label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT; label_len = (size_t) fs_m_in.REQ_PATH_LEN; readonly = (fs_m_in.REQ_FLAGS & REQ_RDONLY) ? 1 : 0; isroot = (fs_m_in.REQ_FLAGS & REQ_ISROOT) ? 1 : 0; if (label_len > sizeof(fs_dev_label)) return(EINVAL); r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0, (vir_bytes) fs_dev_label, label_len, D); if (r != OK) { printf("MFS %s:%d safecopyfrom failed: %d\n", __FILE__, __LINE__, r); return(EINVAL); } r = ds_retrieve_label_endpt(fs_dev_label, &driver_e); if (r != OK) { printf("MFS %s:%d ds_retrieve_label_endpt failed for '%s': %d\n", __FILE__, __LINE__, fs_dev_label, r); return(EINVAL); } /* Map the driver endpoint for this major */ bdev_driver(fs_dev, driver_e); /* Open the device the file system lives on. */ if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) { return(EINVAL); } /* Fill in the super block. */ superblock.s_dev = fs_dev; /* read_super() needs to know which dev */ r = read_super(&superblock); /* Is it recognized as a Minix filesystem? */ if (r != OK) { superblock.s_dev = NO_DEV; bdev_close(fs_dev); return(r); } set_blocksize(&superblock); /* Get the root inode of the mounted file system. */ if( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL) { printf("MFS: couldn't get root inode\n"); superblock.s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } if(root_ip->i_mode == 0) { printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__); put_inode(root_ip); superblock.s_dev = NO_DEV; bdev_close(fs_dev); return(EINVAL); } superblock.s_rd_only = readonly; superblock.s_is_root = isroot; /* Root inode properties */ fs_m_out.RES_INODE_NR = root_ip->i_num; fs_m_out.RES_MODE = root_ip->i_mode; fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size; fs_m_out.RES_UID = root_ip->i_uid; fs_m_out.RES_GID = root_ip->i_gid; fs_m_out.RES_CONREQS = 1; /* We can handle only 1 request at a time */ return(r); }
/*===========================================================================* * do_mount * *===========================================================================*/ PUBLIC int do_mount() { /* Perform the mount(name, mfile, rd_only) system call. */ register struct inode *rip, *root_ip; struct super_block *xp, *sp; dev_t dev; mode_t bits; int rdir, mdir; /* TRUE iff {root|mount} file is dir */ int i, r, found; struct fproc *tfp; /* Only the super-user may do MOUNT. */ if (!super_user) return(EPERM); /* If 'name' is not for a block special file, return error. */ if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code); if ( (dev = name_to_dev(user_path)) == NO_DEV) return(err_code); /* Scan super block table to see if dev already mounted & find a free slot.*/ sp = NIL_SUPER; found = FALSE; for (xp = &super_block[0]; xp < &super_block[NR_SUPERS]; xp++) { if (xp->s_dev == dev) { /* is it mounted already? */ found = TRUE; sp= xp; break; } if (xp->s_dev == NO_DEV) sp = xp; /* record free slot */ } if (found) { printf( "do_mount: s_imount = 0x%x (%x, %d), s_isup = 0x%x (%x, %d), fp_rootdir = 0x%x\n", xp->s_imount, xp->s_imount->i_dev, xp->s_imount->i_num, xp->s_isup, xp->s_isup->i_dev, xp->s_isup->i_num, fproc[FS_PROC_NR].fp_rootdir); /* It is possible that we have an old root lying around that * needs to be remounted. */ if (xp->s_imount != xp->s_isup || xp->s_isup == fproc[FS_PROC_NR].fp_rootdir) { /* Normally, s_imount refers to the mount point. For a root * filesystem, s_imount is equal to the root inode. We assume * that the root of FS is always the real root. If the two * inodes are different or if the root of FS is equal two the * root of the filesystem we found, we found a filesystem that * is in use. */ return(EBUSY); /* already mounted */ } if (root_dev == xp->s_dev) { panic("fs", "inconsistency remounting old root", NO_NUM); } /* Now get the inode of the file to be mounted on. */ if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) { return(err_code); } if ( (rip = eat_path(user_path)) == NIL_INODE) { return(err_code); } r = OK; /* It may not be special. */ bits = rip->i_mode & I_TYPE; if (bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL) r = ENOTDIR; /* Get the root inode of the mounted file system. */ root_ip= sp->s_isup; /* File types of 'rip' and 'root_ip' may not conflict. */ if (r == OK) { mdir = ((rip->i_mode & I_TYPE) == I_DIRECTORY); /* TRUE iff dir */ rdir = ((root_ip->i_mode & I_TYPE) == I_DIRECTORY); if (!mdir && rdir) r = EISDIR; } /* If error, return the mount point. */ if (r != OK) { put_inode(rip); return(r); } /* Nothing else can go wrong. Perform the mount. */ rip->i_mount = I_MOUNT; /* this bit says the inode is * mounted on */ put_inode(sp->s_imount); sp->s_imount = rip; sp->s_rd_only = m_in.rd_only; allow_newroot= 0; /* The root is now fixed */ return(OK); } if (sp == NIL_SUPER) return(ENFILE); /* no super block available */ /* Open the device the file system lives on. */ if (dev_open(dev, who_e, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK) return(EINVAL); /* Make the cache forget about blocks it has open on the filesystem */ (void) do_sync(); invalidate(dev); /* Fill in the super block. */ sp->s_dev = dev; /* read_super() needs to know which dev */ r = read_super(sp); /* Is it recognized as a Minix filesystem? */ if (r != OK) { dev_close(dev); sp->s_dev = NO_DEV; return(r); } /* Now get the inode of the file to be mounted on. */ if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) { dev_close(dev); sp->s_dev = NO_DEV; return(err_code); } if (strcmp(user_path, "/") == 0 && allow_newroot) { printf("Replacing root\n"); /* Get the root inode of the mounted file system. */ if ( (root_ip = get_inode(dev, ROOT_INODE)) == NIL_INODE) r = err_code; if (root_ip != NIL_INODE && root_ip->i_mode == 0) { r = EINVAL; } /* If error, return the super block and both inodes; release the * maps. */ if (r != OK) { put_inode(root_ip); (void) do_sync(); invalidate(dev); dev_close(dev); sp->s_dev = NO_DEV; return(r); } /* Nothing else can go wrong. Perform the mount. */ sp->s_imount = root_ip; dup_inode(root_ip); sp->s_isup = root_ip; sp->s_rd_only = m_in.rd_only; root_dev= dev; /* Replace all root and working directories */ for (i= 0, tfp= fproc; i<NR_PROCS; i++, tfp++) { if (tfp->fp_pid == PID_FREE) continue; if (tfp->fp_rootdir == NULL) panic("fs", "do_mount: null rootdir", i); put_inode(tfp->fp_rootdir); dup_inode(root_ip); tfp->fp_rootdir= root_ip; if (tfp->fp_workdir == NULL) panic("fs", "do_mount: null workdir", i); put_inode(tfp->fp_workdir); dup_inode(root_ip); tfp->fp_workdir= root_ip; } /* Leave the old filesystem lying around. */ return(OK); } if ( (rip = eat_path(user_path)) == NIL_INODE) { dev_close(dev); sp->s_dev = NO_DEV; return(err_code); } /* It may not be busy. */ r = OK; if (rip->i_count > 1) r = EBUSY; /* It may not be special. */ bits = rip->i_mode & I_TYPE; if (bits == I_BLOCK_SPECIAL || bits == I_CHAR_SPECIAL) r = ENOTDIR; /* Get the root inode of the mounted file system. */ root_ip = NIL_INODE; /* if 'r' not OK, make sure this is defined */ if (r == OK) { if ( (root_ip = get_inode(dev, ROOT_INODE)) == NIL_INODE) r = err_code; } if (root_ip != NIL_INODE && root_ip->i_mode == 0) { r = EINVAL; } /* File types of 'rip' and 'root_ip' may not conflict. */ if (r == OK) { mdir = ((rip->i_mode & I_TYPE) == I_DIRECTORY); /* TRUE iff dir */ rdir = ((root_ip->i_mode & I_TYPE) == I_DIRECTORY); if (!mdir && rdir) r = EISDIR; } /* If error, return the super block and both inodes; release the maps. */ if (r != OK) { put_inode(rip); put_inode(root_ip); (void) do_sync(); invalidate(dev); dev_close(dev); sp->s_dev = NO_DEV; return(r); } /* Nothing else can go wrong. Perform the mount. */ rip->i_mount = I_MOUNT; /* this bit says the inode is mounted on */ sp->s_imount = rip; sp->s_isup = root_ip; sp->s_rd_only = m_in.rd_only; allow_newroot= 0; /* The root is now fixed */ return(OK); }
/*===========================================================================* * fs_readsuper_s * *===========================================================================*/ PUBLIC int fs_readsuper_s() { /* This function reads the superblock of the partition, gets the root inode * and sends back the details of them. Note, that the FS process does not * know the index of the vmnt object which refers to it, whenever the pathname * lookup leaves a partition an ELEAVEMOUNT error is transferred back * so that the VFS knows that it has to find the vnode on which this FS * process' partition is mounted on. */ struct super_block *xp; struct inode *root_ip; cp_grant_id_t label_gid; size_t label_len; int r = OK; unsigned long tasknr; endpoint_t driver_e; fs_dev = fs_m_in.REQ_DEV; label_gid= fs_m_in.REQ_GRANT2; label_len= fs_m_in.REQ_PATH_LEN; if (label_len > sizeof(fs_dev_label)) { printf("mfs:fs_readsuper: label too long\n"); return EINVAL; } r= sys_safecopyfrom(fs_m_in.m_source, label_gid, 0, (vir_bytes)fs_dev_label, label_len, D); if (r != OK) { printf("mfs:fs_readsuper: safecopyfrom failed: %d\n", r); return EINVAL; } r= ds_retrieve_u32(fs_dev_label, &tasknr); if (r != OK) { printf("mfs:fs_readsuper: ds_retrieve_u32 failed for '%s': %d\n", fs_dev_label, r); return EINVAL; } driver_e= tasknr; /* Map the driver endpoint for this major */ driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = driver_e; use_getuptime2= TRUE; /* Should be removed with old * getuptime call. */ vfs_slink_storage = (char *)0xdeadbeef; /* Should be removed together * with old lookup code. */; /* Open the device the file system lives on. */ if (dev_open(driver_e, fs_dev, driver_e, fs_m_in.REQ_READONLY ? R_BIT : (R_BIT|W_BIT)) != OK) { return(EINVAL); } /* Fill in the super block. */ superblock.s_dev = fs_dev; /* read_super() needs to know which dev */ r = read_super(&superblock); /* Is it recognized as a Minix filesystem? */ if (r != OK) { superblock.s_dev = NO_DEV; dev_close(driver_e, fs_dev); return(r); } set_blocksize(superblock.s_block_size); /* Get the root inode of the mounted file system. */ if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NIL_INODE) { printf("MFS: couldn't get root inode?!\n"); superblock.s_dev = NO_DEV; dev_close(driver_e, fs_dev); return EINVAL; } if (root_ip != NIL_INODE && root_ip->i_mode == 0) { printf("MFS: zero mode for root inode?!\n"); put_inode(root_ip); superblock.s_dev = NO_DEV; dev_close(driver_e, fs_dev); return EINVAL; } superblock.s_rd_only = fs_m_in.REQ_READONLY; superblock.s_is_root = fs_m_in.REQ_ISROOT; /* Root inode properties */ fs_m_out.RES_INODE_NR = root_ip->i_num; fs_m_out.RES_MODE = root_ip->i_mode; fs_m_out.RES_FILE_SIZE = root_ip->i_size; fs_m_out.RES_UID = root_ip->i_uid; fs_m_out.RES_GID = root_ip->i_gid; return r; }
int grsIntFrag() { printf("\n======================================================\n"); printf("\n System Call Invoked : grsIntFrag \n"); struct super_block* sp; unsigned int in_numbs[100] = {0}; struct inode *rip; block_t start_block; /* first bit block */ block_t block; bit_t map_bits; /* how many bits are there in the bit map? */ short bit_blocks; /* how many blocks are there in the bit map? */ bit_t origin = 1; /* number of bit to start searching at */ int c = 0, n = 0, d = 0, count =0, j=0, frag_cnt =0 , scale =0; unsigned word, bcount; struct buf *bp; bitchunk_t *wptr, *wlim, k; bit_t i, b; sp = get_super(fs_dev); c = read_super(sp); printf("The block sz currently in use : %d\n",sp->s_block_size); if(sp->s_log_zone_size == 0) { printf("One block/zone on this filesystem. So no external fragmentation\n"); return 0; } start_block = START_BLOCK; map_bits = (bit_t) (sp->s_ninodes + 1); bit_blocks = sp->s_imap_blocks; /* Locate the starting place. */ block = (block_t) (origin / FS_BITS_PER_BLOCK(sp->s_block_size)); word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS; bcount = bit_blocks; while(bcount > 0) { bp = get_block(sp->s_dev, start_block + block, NORMAL); assert(bp); wlim = &bp->b_bitmap[FS_BITMAP_CHUNKS(sp->s_block_size)]; /* Iterate over the words in block. */ for (wptr = &bp->b_bitmap[word]; wptr < wlim; wptr++) { /* Does this word contain a free bit? */ if (*wptr == (bitchunk_t) 0) continue; k = (bitchunk_t) conv4(sp->s_native, (int) *wptr); for (i = 0; i < 8*sizeof(k); ++i) { /* Bit number from the start of the bit map. */ b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size)) + (wptr - &bp->b_bitmap[0]) * FS_BITCHUNK_BITS + i; /* Don't count bits beyond the end of the map. */ if (b >= map_bits) { break; } if ((k & (1 << i)) == 1) { in_numbs[n++] = b; } } if (b >= map_bits) break; } ++block; word = 0; --bcount; } for(n=0;in_numbs[n]!=0;n++) { rip = get_inode(fs_dev, in_numbs[n]); scale = rip->i_sp->s_log_zone_size; for(j=0;j<7;j++) { b = (block_t)rip->i_zone[7] << scale; bp = get_block(rip->i_dev,b,NORMAL); count = (rip->i_sp->s_block_size)/32; for(d=0;d<count;d++) { if(bp->b_v1_ind[d] == NO_ZONE) { frag_cnt = get_internal_frag(bp->b_v1_ind[d],scale); } } } } print_internal_frag_report(); return 0; printf("\n======================================================\n"); }