Exemple #1
0
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;
Exemple #2
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;
}
Exemple #4
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;
}
Exemple #5
0
/* 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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
0
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;
}
Exemple #9
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;
}
Exemple #10
0
//====================================================================
// 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;
}
Exemple #11
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);
}
Exemple #12
0
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;
}
Exemple #14
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);
}
Exemple #15
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)
		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;
}
Exemple #16
0
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
    {
Exemple #17
0
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;
}
Exemple #18
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;
}
Exemple #19
0
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(&sector_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;
}
Exemple #20
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)) {
Exemple #21
0
/**
 * 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;
}
Exemple #22
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
 * 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;
}
Exemple #23
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));
}
Exemple #24
0
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;
}
Exemple #27
0
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;
}