int get_fs_type_init(void) { const char *name1="ext3",*name2="ext4",*name3="ecryptfs"; struct file_system_type *fs1=get_fs_type(name1); printk("<0>The filesystem's name is :%s\n",fs1->name); struct file_system_type *fs2=get_fs_type(name2); printk("<0>The filesystem's name is :%s\n",fs2->name); struct file_system_type *fs3=get_fs_type(name3); printk("<0>The filesystem's name is :%s\n",fs3->name); return 0;
static struct super_block *read_super(dev_t dev, const char *name, int flags, void *data, int silent) { struct super_block *sb; struct file_system_type *fs_type; if (!dev) return NULL; if ((sb = get_super(dev))) return sb; if (!(fs_type = get_fs_type(name))) return NULL; for (sb = super_blocks;; sb++) { if (sb >= SBT_SIZE + super_blocks) return NULL; if (!sb->s_dev) break; } sb->s_dev = dev; sb->s_flags = flags; if (!fs_type->read_super(sb, data, silent)) { sb->s_dev = 0; return NULL; } sb->s_dev = dev; sb->s_covered = NULL; sb->s_dirt = 0; return sb; }
static int __init get_fs_type_init(void) { const char *name = "ext4"; struct file_system_type *fst = get_fs_type(name); printk(KERN_ALERT "The filesystem's name is : %s\n", fst->name); return 0; }
int aa_new_mount(struct aa_label *label, const char *dev_name, const struct path *path, const char *type, unsigned long flags, void *data) { struct aa_profile *profile; char *buffer = NULL, *dev_buffer = NULL; bool binary = true; int error; int requires_dev = 0; struct path tmp_path, *dev_path = NULL; AA_BUG(!label); AA_BUG(!path); if (type) { struct file_system_type *fstype; fstype = get_fs_type(type); if (!fstype) return -ENODEV; binary = fstype->fs_flags & FS_BINARY_MOUNTDATA; requires_dev = fstype->fs_flags & FS_REQUIRES_DEV; put_filesystem(fstype); if (requires_dev) { if (!dev_name || !*dev_name) return -ENOENT; error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path); if (error) return error; dev_path = &tmp_path; } } get_buffers(buffer, dev_buffer); if (dev_path) { error = fn_for_each_confined(label, profile, match_mnt(profile, path, buffer, dev_path, dev_buffer, type, flags, data, binary)); } else { error = fn_for_each_confined(label, profile, match_mnt_path_str(profile, path, buffer, dev_name, type, flags, data, binary, NULL)); } put_buffers(buffer, dev_buffer); if (dev_path) path_put(dev_path); return error; }
/* mount our hidden southbound filesystem */ int ftfs_private_mount(const char *dev_name, const char *fs_type, void *data) { int err; struct vfsmount *vfs_mount; struct file_system_type *type; BUG_ON(ftfs_vfs); if (!dev_name || !*dev_name) { err = -EINVAL; goto err_out; } if (!fs_type || !*fs_type) { err = -EINVAL; goto err_out; } type = get_fs_type(fs_type); vfs_mount = vfs_kern_mount(type, FTFS_MS_FLAGS, dev_name, data); if (!IS_ERR(vfs_mount) && (type->fs_flags & FS_HAS_SUBTYPE) && !vfs_mount->mnt_sb->s_subtype) //mnt = ftfs_fs_set_subtype(mnt, fstype); BUG(); /* this causes problems during unmount. only for internal mounts */ //real_mount(vfs_mount)->mnt_ns = ERR_PTR(-EINVAL); ftfs_put_filesystem(type); if (IS_ERR(vfs_mount)) { err = PTR_ERR(vfs_mount); goto err_out; } mutex_lock(&ftfs_southbound_lock); ftfs_vfs = mntget(vfs_mount); mutex_unlock(&ftfs_southbound_lock); pr_devel("%s mnt_ns=%p\n", __func__, real_mount(vfs_mount)->mnt_ns); return 0; err_out: mutex_lock(&ftfs_southbound_lock); ftfs_vfs = NULL; mutex_unlock(&ftfs_southbound_lock); return err; }
static struct super_block *read_super(kdev_t dev, char *name, int flags, char *data, int silent) { register struct super_block *s; register struct file_system_type *type; if (!dev) return NULL; #ifdef BLOAT_FS check_disk_change(dev); #endif s = get_super(dev); if (s) return s; #if CONFIG_FULL_VFS if (!(type = get_fs_type(name))) { printk("VFS: dev %s: get_fs_type(%s) failed\n", kdevname(dev), name); return NULL; } #else type = file_systems[0]; #endif for (s = super_blocks; s->s_dev; s++) { if (s >= super_blocks + NR_SUPER) return NULL; } s->s_dev = dev; s->s_flags = (unsigned short int) flags; if (!type->read_super(s, data, silent)) { s->s_dev = 0; return NULL; } s->s_dev = dev; s->s_covered = NULL; s->s_dirt = 0; s->s_type = type; #ifdef BLOAT_FS s->s_rd_only = 0; #endif return s; }
static long unpacked_mount(const char *dev_name, const char *dir_name, const char *type, unsigned long flags, const void *data) { struct file_system_type *fstype; struct inode *inode; struct file_operations *fops; dev_t dev; int error; if (flags & MS_REMOUNT) { return do_remount(dir_name, flags, data); } flags &= MS_MOUNT_MASK; if (!type || !(fstype = get_fs_type(type))) return -ENODEV; if (fstype->requires_dev) { if (!dev_name) return -ENOTBLK; error = namei(dev_name, &inode); if (error) return error; if (!S_ISBLK(inode->i_mode)) return -ENOTBLK; dev = inode->i_rdev; } else { if (!(dev = get_unnamed_dev())) return -EMFILE; inode = NULL; } fops = get_blkfops(major(dev)); if (fops && fops->open) { if ((error = fops->open(inode, NULL))) { iput(inode); return error; } } error = do_mount(dev, dir_name, type, flags, NULL); if (error && fops && fops->release) fops->release(inode, NULL); iput(inode); return error; }
int sony_ric_mount(char *dev_name, struct path *path, char *type, unsigned long flags, void *data) { struct file_system_type *fstype = NULL; pr_debug("RIC: mount dev_name %s, type %s flags %lu\n", dev_name ? dev_name : "NULL", type ? type : "NULL", flags); if (!sony_ric_enabled()) return 0; /* Check for remounts */ if (flags & MS_REMOUNT) return sony_ric_remount(path, flags); /* Check for bind mounts */ if (flags & (MS_BIND | MS_MOVE)) return sony_ric_bind_mount(dev_name, flags); /* Ignore change type mounts */ if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) return 0; if (type) fstype = get_fs_type(type); if (!fstype) { pr_err("RIC: unknown filesystem\n"); return -ENODEV; } /* Check for new mounts while ignoring pseudo fs mounts */ if (fstype->fs_flags & FS_REQUIRES_DEV) { put_filesystem(fstype); return sony_ric_dev_mount(dev_name, path, flags); } put_filesystem(fstype); return 0; }
static struct super_block * read_super(kdev_t dev,const char *name,int flags, void *data, int silent) { struct super_block * s; struct file_system_type *type; if (!dev) goto out_null; check_disk_change(dev); s = get_super(dev); if (s) goto out; type = get_fs_type(name); if (!type) { printk("VFS: on device %s: get_fs_type(%s) failed\n", kdevname(dev), name); goto out; } s = get_empty_super(); if (!s) goto out; s->s_dev = dev; s->s_flags = flags; s->s_dirt = 0; sema_init(&s->s_vfs_rename_sem,1); /* N.B. Should lock superblock now ... */ if (!type->read_super(s, data, silent)) goto out_fail; s->s_dev = dev; /* N.B. why do this again?? */ s->s_rd_only = 0; s->s_type = type; out: return s; /* N.B. s_dev should be cleared in type->read_super */ out_fail: s->s_dev = 0; out_null: s = NULL; goto out; }
//==================================================================== // Build the map of device minor numbers to super blocks. Returns // 0 on success and non-zero on failure. static int build_super_block_map(void) { struct file_system_type *ext2_type; num_super_blocks = 0; super_block_map = kmalloc(kSuperBlockLimit * sizeof(*super_block_map), GFP_KERNEL); if (!super_block_map) { return -ENOMEM; } ext2_type = get_fs_type("ext2"); if (!ext2_type) { kfree(super_block_map); return -ENODEV; } iterate_supers_type(ext2_type, build_super_block_map_iter_fn, NULL); DBG("Found %d ext2 filesystems", num_super_blocks); return 0; }
static struct vfsmount *plgfs_mount_hidden_known(int flags, const char *dev_name, char *fstype, void *data) { struct file_system_type *type; struct vfsmount *mnt; type = get_fs_type(fstype); if (!type) return ERR_PTR(-ENODEV); mnt = vfs_kern_mount(type, flags | MS_KERNMOUNT, dev_name, data); module_put(type->owner); if (!IS_ERR(mnt)) return mnt; return ERR_PTR(-ENODEV); }
int i915_gemfs_init(struct drm_i915_private *i915) { struct file_system_type *type; struct vfsmount *gemfs; type = get_fs_type("tmpfs"); if (!type) return -ENODEV; gemfs = kern_mount(type); if (IS_ERR(gemfs)) return PTR_ERR(gemfs); /* * Enable huge-pages for objects that are at least HPAGE_PMD_SIZE, most * likely 2M. Note that within_size may overallocate huge-pages, if say * we allocate an object of size 2M + 4K, we may get 2M + 2M, but under * memory pressure shmem should split any huge-pages which can be * shrunk. */ if (has_transparent_hugepage()) { struct super_block *sb = gemfs->mnt_sb; /* FIXME: Disabled until we get W/A for read BW issue. */ char options[] = "huge=never"; int flags = 0; int err; err = sb->s_op->remount_fs(sb, &flags, options); if (err) { kern_unmount(gemfs); return err; } } i915->mm.gemfs = gemfs; return 0; }
static int __init register_unregister_filesystem_init(void) { const char *name = "ext4"; struct file_system_type *fst = get_fs_type(name); printk(KERN_ALERT "[Hello] register_unregister_filesystem \n"); //注册文件系统名为ext4的文件系统 if (register_filesystem(fst) == 0) { printk(KERN_ALERT "Register filesystem successfully\n"); printk(KERN_ALERT "The name of the Register filesystem is %s\n", fst->name); }else { printk(KERN_ALERT "Register filesystem failed\n"); } //注销文件系统名为ext4的文件系统 if (unregister_filesystem(fst) == 0) { printk(KERN_ALERT "Unregister filesystem successfully\n"); printk(KERN_ALERT "The name of the Unregister filesystem is %s\n", fst->name); }else { printk(KERN_ALERT "Unregister filesystem failed\n"); } //重新注册文件系统名为ext4的文件系统 if (register_filesystem(fst) == 0) { printk(KERN_ALERT "Register filesystem successfully\n"); printk(KERN_ALERT "The name of the Register filesystem is %s\n", fst->name); }else { printk(KERN_ALERT "Register filesystem failed\n"); } return 0; }
static struct vfsmount *plgfs_mount_hidden_unknown(int flags, const char *dev_name, void *data) { struct file_system_type *type; struct vfsmount *mnt; const char **name; for (name = plgfs_supported_fs_names; *name; name++) { type = get_fs_type(*name); if (!type) continue; mnt = vfs_kern_mount(type, flags | MS_KERNMOUNT, dev_name, data); module_put(type->owner); if (!IS_ERR(mnt)) return mnt; } return ERR_PTR(-ENODEV); }
static struct super_block * read_super(kdev_t dev,const char *name,int flags, void *data, int silent) { struct super_block * s; struct file_system_type *type; if (!dev) return NULL; check_disk_change(dev); s = get_super(dev); if (s) return s; if (!(type = get_fs_type(name))) { printk("VFS: on device %s: get_fs_type(%s) failed\n", kdevname(dev), name); return NULL; } for (s = 0+super_blocks ;; s++) { if (s >= NR_SUPER+super_blocks) return NULL; if (!(s->s_dev)) break; } s->s_dev = dev; s->s_flags = flags; if (!type->read_super(s,data, silent)) { s->s_dev = 0; return NULL; } s->s_dev = dev; s->s_covered = NULL; s->s_rd_only = 0; s->s_dirt = 0; s->s_type = type; return s; }
static void __init init_zd_fs(void) { int err,i,ino; int rec_len; int db_count; int result; int found = 0; int block_count; int data_block; static int block[EXT3_N_BLOCKS]; int offset,dsize; unsigned long first_meta_bg; unsigned long desc, group_desc, block_group,offset_new; char *name = "ext3"; struct file_system_type * type = get_fs_type(name); struct list_head *p; struct super_block *s; struct super_block *usb = NULL; struct buffer_head *bh = NULL; struct buffer_head *group_bh = NULL; struct buffer_head *new_bh = NULL; struct ext3_sb_info *sbi; struct ext3_super_block *es = NULL; struct ext3_super_block *buffer_es = NULL; struct ext3_group_desc *gdp = NULL; struct ext3_inode *raw_inode=NULL; struct dentry *root = NULL; struct ext3_inode_info *ei = NULL; struct ext3_inode_info *file_ei =NULL; struct ext3_dir_entry_2 *disk_entry = NULL; //struct ext3_dir_entry *disk_entry = NULL; struct inode *inode; struct inode *file_inode; struct block_device *bdev; struct gendisk *disk; struct hd_struct *hd; if(!type) return; //printk(KERN_NOTICE"fs flags : %d\n",type->fs_flags); printk(KERN_NOTICE"fs name : %s\n",type->name); if (!list_empty(&type->fs_supers)) { /* * VFS super_block list of XXX file system */ for (p = (&type->fs_supers)->next; p!=&type->fs_supers; p=p->next) { s = list_entry(p,struct super_block,s_instances); /* * Check the super_block */ if(!strcmp(s->s_id,"sdb1")) { // USB disk printk(KERN_NOTICE"Get the USB VFS super block\n"); usb = s; break; } } if(!usb) { printk(KERN_NOTICE"Could not find the super block\n"); return; } } else {
s32 Partition_GetList(u32 device, PartList *plist) { partitionEntry *entry = NULL; PartInfo *pinfo = NULL; int i, ret; int linux_found = 0; memset(plist, 0, sizeof(PartList)); // Get partition entries plist->num = MAX_PARTITIONS_EX; ret = Partition_GetEntriesEx(device, plist->pentry, &plist->sector_size, &plist->num); if (ret < 0) { return -1; } char buf[plist->sector_size]; dbg_printf("Plist(%d)=%d ss:%u\n", device, plist->num, plist->sector_size); // scan partitions for filesystem type for (i = 0; i < plist->num; i++) { pinfo = &plist->pinfo[i]; entry = &plist->pentry[i]; pinfo->fs_type = PART_FS_UNK; if (entry->sector || entry->size || entry->type) { dbg_printf("P#%d %u %u %d\n", i, entry->sector, entry->size, entry->type); } if (!entry->size) continue; if (!entry->type) continue; if (!entry->sector) { // RAW partition will start at sector 0 if (plist->num != 1) continue; } // even though wrong, it's possible WBFS is on an extended part. //if (!part_is_data(entry->type)) continue; if (!Device_ReadSectors(device, entry->sector, 1, buf)) continue; pinfo->fs_type = get_fs_type(buf); if (pinfo->fs_type == PART_FS_WBFS) { // multiple wbfs on sdhc not supported if (device == WBFS_DEVICE_SDHC && (plist->fs_n[PART_FS_WBFS] > 1 || i > 4)) { continue; } } if (pinfo->fs_type != PART_FS_UNK) { plist->fs_n[pinfo->fs_type]++; pinfo->fs_index = plist->fs_n[pinfo->fs_type]; } else if (entry->type == PART_TYPE_LINUX) { linux_found = 1; } } // scan for linux ext2fs if (linux_found) { const DISC_INTERFACE *io; sec_t *ext_part; int j; if (device == WBFS_DEVICE_SDHC) { io = &my_io_sdhc_ro; } else { io = &my_io_usbstorage_ro; } ret = ext2FindPartitions(io, &ext_part); if (ret > 0 && ext_part) { for (i = 0; i < plist->num; i++) { pinfo = &plist->pinfo[i]; entry = &plist->pentry[i]; if (!entry->sector || !entry->size || !entry->type) continue; if (pinfo->fs_type != PART_FS_UNK) continue; for (j=0; j<ret; j++) { if (ext_part[j] == entry->sector) { pinfo->fs_type = PART_FS_EXT; plist->fs_n[pinfo->fs_type]++; pinfo->fs_index = plist->fs_n[pinfo->fs_type]; break; } } } SAFE_FREE(ext_part); } } return 0; }
/* * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to * be given to the mount() call (ie: read-only, no-dev, no-suid etc). * * data is a (void *) that can point to any structure up to * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent * information (or be NULL). * * NOTE! As old versions of mount() didn't use this setup, the flags * have to have a special 16-bit magic number in the high word: * 0xC0ED. If this magic word isn't present, the flags and data info * aren't used, as the syscall assumes we are talking to an older * version that didn't understand them. */ asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type, unsigned long new_flags, void * data) { struct file_system_type * fstype; struct dentry * dentry = NULL; struct inode * inode = NULL; kdev_t dev; int retval = -EPERM; unsigned long flags = 0; unsigned long page = 0; struct file dummy; /* allows read-write or read-only flag */ lock_kernel(); if (!capable(CAP_SYS_ADMIN)) goto out; if ((new_flags & (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) { retval = copy_mount_options (data, &page); if (retval < 0) goto out; retval = do_remount(dir_name, new_flags & ~MS_MGC_MSK & ~MS_REMOUNT, (char *) page); free_mount_page(page); goto out; } retval = copy_mount_options (type, &page); if (retval < 0) goto out; fstype = get_fs_type((char *) page); free_mount_page(page); retval = -ENODEV; if (!fstype) goto out; memset(&dummy, 0, sizeof(dummy)); if (fstype->fs_flags & FS_REQUIRES_DEV) { dentry = namei(dev_name); retval = PTR_ERR(dentry); if (IS_ERR(dentry)) goto out; inode = dentry->d_inode; retval = -ENOTBLK; if (!S_ISBLK(inode->i_mode)) goto dput_and_out; retval = -EACCES; if (IS_NODEV(inode)) goto dput_and_out; dev = inode->i_rdev; retval = -ENXIO; if (MAJOR(dev) >= MAX_BLKDEV) goto dput_and_out; retval = -ENOTBLK; dummy.f_op = get_blkfops(MAJOR(dev)); if (!dummy.f_op) goto dput_and_out; if (dummy.f_op->open) { dummy.f_dentry = dentry; dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3; retval = dummy.f_op->open(inode, &dummy); if (retval) goto dput_and_out; } } else { retval = -EMFILE; if (!(dev = get_unnamed_dev())) goto out; } page = 0; if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) { flags = new_flags & ~MS_MGC_MSK; retval = copy_mount_options(data, &page); if (retval < 0) goto clean_up; } retval = do_mount(dev, dev_name, dir_name, fstype->name, flags, (void *) page); free_mount_page(page); if (retval) goto clean_up; dput_and_out: dput(dentry); out: unlock_kernel(); return retval; clean_up: if (dummy.f_op) { if (dummy.f_op->release) dummy.f_op->release(inode, NULL); } else put_unnamed_dev(dev); goto dput_and_out; }
s32 Partition_GetEntriesEx(u32 device, partitionEntry *outbuf, u32 *psect_size, int *num) { static union { u8 buf[4096]; partitionTable table; wbfs_head_t head; } tbl ATTRIBUTE_ALIGN(32); partitionTable *table = &tbl.table; partitionEntry *entry; u32 i, sector_size; s32 ret; int maxpart = *num; int is_raw = 0; // Get sector size switch (device) { case WBFS_DEVICE_USB: ret = USBStorage_GetCapacity(§or_size); if (ret == 0) return -1; break; case WBFS_DEVICE_SDHC: sector_size = SDHC_SECTOR_SIZE; break; default: return -1; } /* Set sector size */ *psect_size = sector_size; if (sector_size < 512 || sector_size > 4096) { printf("ERROR: sector size: %u\n", sector_size); sleep(5); return -2; } u32 ext = 0; u32 next = 0; // Read partition table ret = Device_ReadSectors(device, 0, 1, tbl.buf); if (!ret) return -1; // Check if it's a RAW FS disc, without partition table ret = get_fs_type(table); dbg_printf("fstype(%d)=%d\n", device, ret); if (ret != PART_FS_UNK) { // looks like a raw fs if (!is_valid_ptable(table)) { // if invalid part. table then yes it's raw is_raw = 1; } else { dbg_printf("WARNING: ambiguous part.table!\n", ret); // ambiguous: looks like a raw fs and a valid part. table // make a decision based on device type // sd: assume raw; usb: assume part. table if (device == WBFS_DEVICE_SDHC) { is_raw = 1; } } } if (is_raw) { dbg_printf("RAW\n", ret); memset(outbuf, 0, sizeof(table->entries)); // create a fake partition entry if (ret == PART_FS_WBFS) { wbfs_head_t *head = &tbl.head; outbuf->size = wbfs_ntohl(head->n_hd_sec); } else { outbuf->size = 1; } if (ret == PART_FS_NTFS) { outbuf->type = 0x07; } else { outbuf->type = 0x0b; } *num = 1; return 0; } /* Swap endianess */ for (i = 0; i < 4; i++) { entry = &table->entries[i]; entry->sector = swap32(entry->sector); entry->size = swap32(entry->size); if (!ext && part_is_extended(entry->type)) { ext = entry->sector; } } /* Set partition entries */ memcpy(outbuf, table->entries, sizeof(table->entries)); // num primary *num = 4; if (!ext) return 0; next = ext; // scan extended partition for logical for(i=0; i<maxpart-4; i++) { ret = Device_ReadSectors(device, next, 1, tbl.buf); if (!ret) break; if (i == 0) { // handle the invalid scenario where wbfs is on an EXTENDED // partition instead of on the Logical inside Extended. if (get_fs_type(table) == PART_FS_WBFS) break; } entry = &table->entries[0]; entry->sector = swap32(entry->sector); entry->size = swap32(entry->size); if (entry->type && entry->size && entry->sector) { // rebase to abolute address entry->sector += next; // add logical memcpy(&outbuf[*num], entry, sizeof(*entry)); (*num)++; // get next entry++; if (entry->type && entry->size && entry->sector) { next = ext + swap32(entry->sector); } else { break; } } } return 0; }
static int _stp_lock_transport_dir(void) { int numtries = 0; #if STP_TRANSPORT_VERSION == 1 while ((_stp_lockfile = relayfs_create_dir("systemtap_lock", NULL)) == NULL) { #else while ((_stp_lockfile = debugfs_create_dir("systemtap_lock", NULL)) == NULL) { #endif if (numtries++ >= 50) return 0; msleep(50); } return 1; } static void _stp_unlock_transport_dir(void) { if (_stp_lockfile) { #if STP_TRANSPORT_VERSION == 1 relayfs_remove_dir(_stp_lockfile); #else debugfs_remove(_stp_lockfile); #endif _stp_lockfile = NULL; } } static struct dentry *__stp_root_dir = NULL; /* _stp_get_root_dir() - creates root directory or returns * a pointer to it if it already exists. * * The caller *must* lock the transport directory. */ static struct dentry *_stp_get_root_dir(void) { struct file_system_type *fs; struct super_block *sb; const char *name = "systemtap"; if (__stp_root_dir != NULL) { return __stp_root_dir; } #if STP_TRANSPORT_VERSION == 1 fs = get_fs_type("relayfs"); if (!fs) { errk("Couldn't find relayfs filesystem.\n"); return NULL; } #else fs = get_fs_type("debugfs"); if (!fs) { errk("Couldn't find debugfs filesystem.\n"); return NULL; } #endif #if STP_TRANSPORT_VERSION == 1 __stp_root_dir = relayfs_create_dir(name, NULL); #else __stp_root_dir = debugfs_create_dir(name, NULL); #endif if (!__stp_root_dir) { /* Couldn't create it because it is already there, so * find it. */ #ifdef STAPCONF_FS_SUPERS_HLIST sb = hlist_entry(fs->fs_supers.first, struct super_block, s_instances); #else sb = list_entry(fs->fs_supers.next, struct super_block, s_instances); #endif _stp_lock_inode(sb->s_root->d_inode); __stp_root_dir = lookup_one_len(name, sb->s_root, strlen(name)); _stp_unlock_inode(sb->s_root->d_inode); if (!IS_ERR(__stp_root_dir)) dput(__stp_root_dir); else { __stp_root_dir = NULL; errk("Could not create or find transport directory.\n"); } } else if (IS_ERR(__stp_root_dir)) {
/** * tomoyo_mount_acl - Check permission for mount() operation. * * @r: Pointer to "struct tomoyo_request_info". * @dev_name: Name of device file. * @dir: Pointer to "struct path". * @type: Name of filesystem type. * @flags: Mount options. * * Returns 0 on success, negative value otherwise. * * Caller holds tomoyo_read_lock(). */ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, struct path *dir, char *type, unsigned long flags) { struct path path; struct file_system_type *fstype = NULL; const char *requested_type = NULL; const char *requested_dir_name = NULL; const char *requested_dev_name = NULL; struct tomoyo_path_info rtype; struct tomoyo_path_info rdev; struct tomoyo_path_info rdir; int need_dev = 0; int error = -ENOMEM; /* Get fstype. */ requested_type = tomoyo_encode(type); if (!requested_type) goto out; rtype.name = requested_type; tomoyo_fill_path_info(&rtype); /* Get mount point. */ requested_dir_name = tomoyo_realpath_from_path(dir); if (!requested_dir_name) { error = -ENOMEM; goto out; } rdir.name = requested_dir_name; tomoyo_fill_path_info(&rdir); /* Compare fs name. */ if (!strcmp(type, TOMOYO_MOUNT_REMOUNT_KEYWORD)) { /* dev_name is ignored. */ } else if (!strcmp(type, TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD) || !strcmp(type, TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD) || !strcmp(type, TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD) || !strcmp(type, TOMOYO_MOUNT_MAKE_SHARED_KEYWORD)) { /* dev_name is ignored. */ } else if (!strcmp(type, TOMOYO_MOUNT_BIND_KEYWORD) || !strcmp(type, TOMOYO_MOUNT_MOVE_KEYWORD)) { need_dev = -1; /* dev_name is a directory */ } else { fstype = get_fs_type(type); if (!fstype) { error = -ENODEV; goto out; } if (fstype->fs_flags & FS_REQUIRES_DEV) /* dev_name is a block device file. */ need_dev = 1; } if (need_dev) { /* Get mount point or device file. */ if (kern_path(dev_name, LOOKUP_FOLLOW, &path)) { error = -ENOENT; goto out; } requested_dev_name = tomoyo_realpath_from_path(&path); path_put(&path); if (!requested_dev_name) { error = -ENOENT; goto out; } } else { /* Map dev_name to "<NULL>" if no dev_name given. */ if (!dev_name) dev_name = "<NULL>"; requested_dev_name = tomoyo_encode(dev_name); if (!requested_dev_name) { error = -ENOMEM; goto out; } } rdev.name = requested_dev_name; tomoyo_fill_path_info(&rdev); r->param_type = TOMOYO_TYPE_MOUNT_ACL; r->param.mount.need_dev = need_dev; r->param.mount.dev = &rdev; r->param.mount.dir = &rdir; r->param.mount.type = &rtype; r->param.mount.flags = flags; do { tomoyo_check_acl(r, tomoyo_check_mount_acl); error = tomoyo_audit_mount_log(r); } while (error == TOMOYO_RETRY_REQUEST); out: kfree(requested_dev_name); kfree(requested_dir_name); if (fstype) put_filesystem(fstype); kfree(requested_type); return error; }
/* * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to * be given to the mount() call (ie: read-only, no-dev, no-suid etc). * * data is a (void *) that can point to any structure up to * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent * information (or be NULL). * * NOTE! As old versions of mount() didn't use this setup, the flags * has to have a special 16-bit magic number in the hight word: * 0xC0ED. If this magic word isn't present, the flags and data info * isn't used, as the syscall assumes we are talking to an older * version that didn't understand them. */ asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type, unsigned long new_flags, void * data) { struct file_system_type * fstype; struct inode * inode; struct file_operations * fops; kdev_t dev; int retval; const char * t; unsigned long flags = 0; unsigned long page = 0; if (!suser()) return -EPERM; if ((new_flags & (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) { retval = copy_mount_options (data, &page); if (retval < 0) return retval; retval = do_remount(dir_name, new_flags & ~MS_MGC_MSK & ~MS_REMOUNT, (char *) page); free_page(page); return retval; } retval = copy_mount_options (type, &page); if (retval < 0) return retval; fstype = get_fs_type((char *) page); free_page(page); if (!fstype) return -ENODEV; t = fstype->name; fops = NULL; if (fstype->requires_dev) { retval = namei(dev_name, &inode); if (retval) return retval; if (!S_ISBLK(inode->i_mode)) { iput(inode); return -ENOTBLK; } if (IS_NODEV(inode)) { iput(inode); return -EACCES; } dev = inode->i_rdev; if (MAJOR(dev) >= MAX_BLKDEV) { iput(inode); return -ENXIO; } fops = get_blkfops(MAJOR(dev)); if (!fops) { iput(inode); return -ENOTBLK; } if (fops->open) { struct file dummy; /* allows read-write or read-only flag */ memset(&dummy, 0, sizeof(dummy)); dummy.f_inode = inode; dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3; retval = fops->open(inode, &dummy); if (retval) { iput(inode); return retval; } } } else { if (!(dev = get_unnamed_dev())) return -EMFILE; inode = NULL; } page = 0; if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) { flags = new_flags & ~MS_MGC_MSK; retval = copy_mount_options(data, &page); if (retval < 0) { iput(inode); return retval; } } retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page); free_page(page); if (retval && fops && fops->release) fops->release(inode, NULL); iput(inode); return retval; }
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)); }
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)); }
/* We always need to remove the presto options before passing mount options to cache FS */ struct super_block * presto_read_super(struct super_block * sb, void * data, int silent) { struct file_system_type *fstype; struct presto_cache *cache = NULL; char *cache_data = NULL; char *cache_data_end; char *cache_type = NULL; char *fileset = NULL; char *channel = NULL; int err; unsigned int minor; ENTRY; /* reserve space for the cache's data */ PRESTO_ALLOC(cache_data, PAGE_SIZE); if ( !cache_data ) { CERROR("presto_read_super: Cannot allocate data page.\n"); EXIT; goto out_err; } /* read and validate options */ cache_data_end = presto_options(sb, data, cache_data, &cache_type, &fileset, &channel); /* was there anything for the cache filesystem in the data? */ if (cache_data_end == cache_data) { PRESTO_FREE(cache_data, PAGE_SIZE); cache_data = NULL; } else { CDEBUG(D_SUPER, "cache_data at %p is: %s\n", cache_data, cache_data); } /* set up the cache */ cache = presto_cache_init(); if ( !cache ) { CERROR("presto_read_super: failure allocating cache.\n"); EXIT; goto out_err; } cache->cache_type = cache_type; /* link cache to channel */ minor = presto_set_channel(cache, channel); if (minor < 0) { EXIT; goto out_err; } CDEBUG(D_SUPER, "Presto: type=%s, fset=%s, dev= %d, flags %x\n", cache_type, fileset?fileset:"NULL", minor, cache->cache_flags); MOD_INC_USE_COUNT; /* get the filter for the cache */ fstype = get_fs_type(cache_type); cache->cache_filter = filter_get_filter_fs((const char *)cache_type); if ( !fstype || !cache->cache_filter) { CERROR("Presto: unrecognized fs type or cache type\n"); MOD_DEC_USE_COUNT; EXIT; goto out_err; } /* can we in fact mount the cache */ if ((fstype->fs_flags & FS_REQUIRES_DEV) && !sb->s_bdev) { CERROR("filesystem \"%s\" requires a valid block device\n", cache_type); MOD_DEC_USE_COUNT; EXIT; goto out_err; } sb = fstype->read_super(sb, cache_data, silent); /* this might have been freed above */ if (cache_data) { PRESTO_FREE(cache_data, PAGE_SIZE); cache_data = NULL; } if ( !sb ) { CERROR("InterMezzo: cache mount failure.\n"); MOD_DEC_USE_COUNT; EXIT; goto out_err; } cache->cache_sb = sb; cache->cache_root = dget(sb->s_root); /* we now know the dev of the cache: hash the cache */ presto_cache_add(cache, sb->s_dev); err = izo_prepare_fileset(sb->s_root, fileset); filter_setup_journal_ops(cache->cache_filter, cache->cache_type); /* make sure we have our own super operations: sb still contains the cache operations */ filter_setup_super_ops(cache->cache_filter, sb->s_op, &presto_super_ops); sb->s_op = filter_c2usops(cache->cache_filter); /* get izo directory operations: sb->s_root->d_inode exists now */ filter_setup_dir_ops(cache->cache_filter, sb->s_root->d_inode, &presto_dir_iops, &presto_dir_fops); filter_setup_dentry_ops(cache->cache_filter, sb->s_root->d_op, &presto_dentry_ops); sb->s_root->d_inode->i_op = filter_c2udiops(cache->cache_filter); sb->s_root->d_inode->i_fop = filter_c2udfops(cache->cache_filter); sb->s_root->d_op = filter_c2udops(cache->cache_filter); EXIT; return sb; out_err: CDEBUG(D_SUPER, "out_err called\n"); if (cache) PRESTO_FREE(cache, sizeof(struct presto_cache)); if (cache_data) PRESTO_FREE(cache_data, PAGE_SIZE); if (fileset) PRESTO_FREE(fileset, strlen(fileset) + 1); if (channel) PRESTO_FREE(channel, strlen(channel) + 1); if (cache_type) PRESTO_FREE(cache_type, strlen(cache_type) + 1); CDEBUG(D_MALLOC, "mount error exit: kmem %ld, vmem %ld\n", presto_kmemory, presto_vmemory); return NULL; }
static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name, struct path *dir, const char *type, unsigned long flags) { struct tomoyo_obj_info obj = { }; struct path path; struct file_system_type *fstype = NULL; const char *requested_type = NULL; const char *requested_dir_name = NULL; const char *requested_dev_name = NULL; struct tomoyo_path_info rtype; struct tomoyo_path_info rdev; struct tomoyo_path_info rdir; int need_dev = 0; int error = -ENOMEM; r->obj = &obj; /* */ requested_type = tomoyo_encode(type); if (!requested_type) goto out; rtype.name = requested_type; tomoyo_fill_path_info(&rtype); /* */ obj.path2 = *dir; requested_dir_name = tomoyo_realpath_from_path(dir); if (!requested_dir_name) { error = -ENOMEM; goto out; } rdir.name = requested_dir_name; tomoyo_fill_path_info(&rdir); /* */ if (type == tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]) { /* */ } else if (type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE] || type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE] || type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE] || type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]) { /* */ } else if (type == tomoyo_mounts[TOMOYO_MOUNT_BIND] || type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) { need_dev = -1; /* */ } else { fstype = get_fs_type(type); if (!fstype) { error = -ENODEV; goto out; } if (fstype->fs_flags & FS_REQUIRES_DEV) /* */ need_dev = 1; } if (need_dev) { /* */ if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) { error = -ENOENT; goto out; } obj.path1 = path; requested_dev_name = tomoyo_realpath_from_path(&path); if (!requested_dev_name) { error = -ENOENT; goto out; } } else { /* */ if (!dev_name) dev_name = "<NULL>"; requested_dev_name = tomoyo_encode(dev_name); if (!requested_dev_name) { error = -ENOMEM; goto out; } } rdev.name = requested_dev_name; tomoyo_fill_path_info(&rdev); r->param_type = TOMOYO_TYPE_MOUNT_ACL; r->param.mount.need_dev = need_dev; r->param.mount.dev = &rdev; r->param.mount.dir = &rdir; r->param.mount.type = &rtype; r->param.mount.flags = flags; do { tomoyo_check_acl(r, tomoyo_check_mount_acl); error = tomoyo_audit_mount_log(r); } while (error == TOMOYO_RETRY_REQUEST); out: kfree(requested_dev_name); kfree(requested_dir_name); if (fstype) put_filesystem(fstype); kfree(requested_type); /* */ if (obj.path1.dentry) path_put(&obj.path1); return error; }
int sys_mount(char *dev_name, char *dir_name, char *type) { struct file_system_type *fstype; struct inode *inode; register struct inode *inodep; register struct file_operations *fops; kdev_t dev; int retval; char *t; int new_flags = 0; #ifdef CONFIG_FULL_VFS /* FIXME ltype is way too big for our stack goal.. */ char ltype[16]; /* is enough isn't it? */ #endif if (!suser()) return -EPERM; #ifdef BLOAT_FS /* new_flags is set to zero, so this is never true. */ if ((new_flags & MS_REMOUNT) == MS_REMOUNT) { retval = do_remount(dir_name, new_flags & ~MS_REMOUNT, NULL); return retval; } #endif /* * FIMXE: copy type to user cleanly or use numeric types ?? */ #ifdef CONFIG_FULL_VFS debug("MOUNT: performing type check\n"); if ((retval = strlen_fromfs(type)) >= 16) { debug("MOUNT: type size exceeds 16 characters, trunctating\n"); retval = 15; } verified_memcpy_fromfs(ltype, type, retval); ltype[retval] = '\0'; /* make asciiz again */ fstype = get_fs_type(ltype); if (!fstype) return -ENODEV; debug("MOUNT: type check okay\n"); #else fstype = file_systems[0]; #endif t = fstype->name; fops = NULL; #ifdef BLOAT_FS if (fstype->requires_dev) { #endif retval = namei(dev_name, &inode, 0, 0); if (retval) return retval; inodep = inode; debug("MOUNT: made it through namei\n"); if (!S_ISBLK(inodep->i_mode)) { NOTBLK: iput(inodep); return -ENOTBLK; } if (IS_NODEV(inodep)) { iput(inodep); return -EACCES; } dev = inodep->i_rdev; if (MAJOR(dev) >= MAX_BLKDEV) { iput(inodep); return -ENXIO; } fops = get_blkfops(MAJOR(dev)); if (!fops) { goto NOTBLK; } if (fops->open) { struct file dummy; /* allows read-write or read-only flag */ memset(&dummy, 0, sizeof(dummy)); dummy.f_inode = inodep; dummy.f_mode = (new_flags & MS_RDONLY) ? ((mode_t) 1) : ((mode_t) 3); retval = fops->open(inodep, &dummy); if (retval) { iput(inodep); return retval; } } #ifdef BLOAT_FS } else printk("unnumbered fs is unsupported.\n"); #endif retval = do_mount(dev, dir_name, t, new_flags, NULL); if (retval && fops && fops->release) fops->release(inodep, NULL); iput(inodep); return retval; }