Esempio n. 1
0
int blkdev_release(struct inode * inode)
{
	struct file_operations *fops = get_blkfops(MAJOR(inode->i_rdev));
	if (fops && fops->release)
		return fops->release(inode,NULL);
	return 0;
}
Esempio n. 2
0
static void putdev(struct inode * inode)
{
	struct file_operations * fops;

	fops = get_blkfops(MAJOR(inode->i_rdev));
	if (fops->release)
		fops->release(inode, NULL);
}
Esempio n. 3
0
File: super.c Progetto: lithoxs/elks
int sys_umount(char *name)
{
    struct inode *inode;
    register struct inode *inodep;
    kdev_t dev;
    int retval;
    struct inode dummy_inode;

    if (!suser())
	return -EPERM;
    retval = namei(name, &inode, 0, 0);
    if (retval) {
	retval = lnamei(name, &inode);
	if (retval)
	    return retval;
    }
    inodep = inode;
    if (S_ISBLK(inodep->i_mode)) {
	dev = inodep->i_rdev;
	if (IS_NODEV(inodep)) {
	    iput(inodep);
	    return -EACCES;
	}
    } else {
	register struct super_block *sb = inodep->i_sb;
	if (!sb || inodep != sb->s_mounted) {
	    iput(inodep);
	    return -EINVAL;
	}
	dev = sb->s_dev;
	iput(inodep);
	memset(&dummy_inode, 0, sizeof(dummy_inode));
	dummy_inode.i_rdev = dev;
	inodep = &dummy_inode;
    }
    if (MAJOR(dev) >= MAX_BLKDEV) {
	iput(inodep);
	return -ENXIO;
    }
    if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
	register struct file_operations *fops;
	fops = get_blkfops(MAJOR(dev));
	if (fops && fops->release)
	    fops->release(inodep, NULL);

#ifdef NOT_YET
	if (MAJOR(dev) == UNNAMED_MAJOR)
	    put_unnamed_dev(dev);
#endif

    }
    if (inodep != &dummy_inode)
	iput(inodep);
    if (retval)
	return retval;
    fsync_dev(dev);
    return 0;
}
Esempio n. 4
0
/*
 * Called every time a block special file is opened
 */
int blkdev_open(struct inode * inode, struct file * filp)
{
	int ret = -ENODEV;
	filp->f_op = get_blkfops(MAJOR(inode->i_rdev));
	if (filp->f_op != NULL){
		ret = 0;
		if (filp->f_op->open != NULL)
			ret = filp->f_op->open(inode,filp);
	}	
	return ret;
}	
Esempio n. 5
0
File: super.c Progetto: drewt/Telos
long sys_umount(const char *name, size_t name_len)
{
	struct inode * inode;
	dev_t dev;
	int retval, error;
	struct inode dummy_inode;
	struct file_operations * fops;

	error = verify_user_string(name, name_len);
	if (error)
		return error;
	//if (!suser())
	//	return -EPERM;
	retval = namei(name,&inode);
	if (retval) {
		retval = lnamei(name,&inode);
		if (retval)
			return retval;
	}
	if (S_ISBLK(inode->i_mode)) {
		dev = inode->i_rdev;
		if (IS_NODEV(inode)) {
			iput(inode);
			return -EACCES;
		}
	} else {
		if (!inode || !inode->i_sb || inode != inode->i_sb->s_mounted) {
			iput(inode);
			return -EINVAL;
		}
		dev = inode->i_sb->s_dev;
		iput(inode);
		memset(&dummy_inode, 0, sizeof(dummy_inode));
		dummy_inode.i_dev = dev;
		inode = &dummy_inode;
	}
	if (major(dev) >= MAX_BLKDEV) {
		iput(inode);
		return -ENXIO;
	}
	if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
		fops = get_blkfops(major(dev));
		if (fops && fops->release)
			fops->release(inode,NULL);
		if (major(dev) == UNNAMED_MAJOR)
			put_unnamed_dev(dev);
	}
	if (inode != &dummy_inode)
		iput(inode);
	if (retval)
		return retval;
	//fsync_dev(dev);
	return 0;
}
Esempio n. 6
0
static unsigned int isofs_get_last_session(kdev_t dev)
{
  struct cdrom_multisession ms_info;
  unsigned int vol_desc_start;
  struct inode inode_fake;
  extern struct file_operations * get_blkfops(unsigned int);
  int i;

  vol_desc_start=0;
  if (get_blkfops(MAJOR(dev))->ioctl!=NULL)
    {
      /* Whoops.  We must save the old FS, since otherwise
       * we would destroy the kernels idea about FS on root
       * mount in read_super... [chexum]
       */
      unsigned long old_fs=get_fs();
      inode_fake.i_rdev=dev;
      ms_info.addr_format=CDROM_LBA;
      set_fs(KERNEL_DS);
      i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake,
				       NULL,
				       CDROMMULTISESSION,
				       (unsigned long) &ms_info);
      set_fs(old_fs);
#if 0 
      printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
      if (i==0)
	{
	  printk("isofs.inode: XA disk: %s\n", ms_info.xa_flag ? "yes":"no");
	  printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
	}
#endif 0
      if (i==0)
#if WE_OBEY_THE_WRITTEN_STANDARDS
        if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
#endif WE_OBEY_THE_WRITTEN_STANDARDS
          vol_desc_start=ms_info.addr.lba;
    }
  return vol_desc_start;
}
Esempio n. 7
0
/*
 * Called every time a block special file is opened
 */
int blkdev_open(struct inode * inode, struct file * filp)
{
	int ret = -ENODEV;

	if (securelevel > 0 && (filp->f_mode & FMODE_WRITE))
		return -EACCES; /* cevans */

	filp->f_op = get_blkfops(MAJOR(inode->i_rdev));
	if (filp->f_op != NULL){
		ret = 0;
		if (filp->f_op->open != NULL)
			ret = filp->f_op->open(inode,filp);
	}	
	return ret;
}	
Esempio n. 8
0
File: super.c Progetto: drewt/Telos
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;
}
Esempio n. 9
0
static int getdev(const char * name, int rdonly, struct inode ** ino)
{
	kdev_t dev;
	struct inode * inode;
	struct file_operations * fops;
	int retval;

	retval = namei(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 -ENODEV;
	}
	if (fops->open) {
		struct file dummy;
		memset(&dummy, 0, sizeof(dummy));
		dummy.f_inode = inode;
		dummy.f_mode = rdonly ? 1 : 3;
		retval = fops->open(inode, &dummy);
		if (retval) {
			iput(inode);
			return retval;
		}
	}
	*ino = inode;
	return 0;
}
Esempio n. 10
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;
}
Esempio n. 11
0
File: super.c Progetto: lithoxs/elks
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;
}
Esempio n. 12
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;
}