Exemplo n.º 1
0
/*
 * This routine checks whether a removable media has been changed,
 * and invalidates all buffer-cache-entries in that case. This
 * is a relatively slow routine, so we have to try to minimize using
 * it. Thus it is called only upon a 'mount' or 'open'. This
 * is the best way of combining speed and utility, I think.
 * People changing diskettes in the middle of an operation deserve
 * to loose :-)
 */
int check_disk_change(kdev_t dev)
{
	int i;
	struct file_operations * fops;

	i = MAJOR(dev);
	if (i >= MAX_BLKDEV || (fops = blkdevs[i].fops) == NULL)
		return 0;
	if (fops->check_media_change == NULL)
		return 0;
	if (!fops->check_media_change(dev))
		return 0;

	printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
		kdevname(dev));
	for (i=0 ; i<NR_SUPER ; i++)
		if (super_blocks[i].s_dev == dev)
			put_super(super_blocks[i].s_dev);
	invalidate_inodes(dev);
	invalidate_buffers(dev);

	if (fops->revalidate)
		fops->revalidate(dev);
	return 1;
}
static int mtdblock_ioctl(struct inode * inode, struct file * file,
		      unsigned int cmd, unsigned long arg)
{
	struct mtd_info *mtd;

	mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev));

	if (!mtd) return -EINVAL;

	switch (cmd) {
	case BLKGETSIZE:   /* Return device size */
		return put_user((mtd->size >> 9), (unsigned long *) arg);

#ifdef BLKGETSIZE64
	case BLKGETSIZE64:
		return put_user((u64)mtd->size, (u64 *)arg);
#endif

	case BLKFLSBUF:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
		if(!capable(CAP_SYS_ADMIN))  return -EACCES;
#endif
		fsync_dev(inode->i_rdev);
		invalidate_buffers(inode->i_rdev);
		if (mtd->sync)
			mtd->sync(mtd);
		return 0;

	default:
		return -ENOTTY;
	}
}
Exemplo n.º 3
0
//// 检查磁盘是否更换,如果已更换就使对应高速缓冲区无效。
void
check_disk_change( int dev )
{
	int i;

// 是软盘设备吗?如果不是则退出。
	if( MAJOR( dev ) != 2 )
	{
		return;
	}
// 测试对应软盘是否已更换,如果没有则退出。
	if( !floppy_change( dev & 0x03 ) )
	{
		return;
	}
// 软盘已经更换,所以释放对应设备的i 节点位图和逻辑块位图所占的高速缓冲区;并使该设备的
// i 节点和数据块信息所占的高速缓冲区无效。
	for( i = 0; i < NR_SUPER; i++ )
	{
		if( super_block[i].s_dev == dev )
		{
			put_super( super_block[i].s_dev );
		}
	}
	invalidate_inodes( dev );
	invalidate_buffers( dev );
}
Exemplo n.º 4
0
void ps2mcfs_free_dirent(struct ps2mcfs_dirent *de)
{
	TRACE("ps2mcfs_free_dirent(%s) entries=%d(%d)\n",
	      ps2mcfs_terminate_name(de->name, de->namelen),
	      nents, nfreeents + 1);

	list_del(&de->next);
	list_del(&de->hashlink);

	if (de->flags & PS2MCFS_DIRENT_BMAPPED)
		invalidate_buffers(de->root->dev);

	/*
	 * free file descriptor cache entry
	 */
	ps2mcfs_free_fd(de);

	/*
	 * free path name cache entry
	 */
	ps2mcfs_free_path(de);

	/*
	 * decrement parent's reference count
	 * (it might free the parent entry)
	 */
	if (de->parent)
		ps2mcfs_unref_dirent(de->parent);

	/*
	 * link with free list
	 */
	list_add(&de->next, &free_dirents);
	nfreeents++;
}
Exemplo n.º 5
0
/*
 * This routine checks whether a removable media has been changed,
 * and invalidates all buffer-cache-entries in that case. This
 * is a relatively slow routine, so we have to try to minimize using
 * it. Thus it is called only upon a 'mount' or 'open'. This
 * is the best way of combining speed and utility, I think.
 * People changing diskettes in the middle of an operation deserve
 * to loose :-)
 */
int check_disk_change(kdev_t dev)
{
	int i;
	struct file_operations * fops;
	struct super_block * sb;

	i = MAJOR(dev);
	if (i >= MAX_BLKDEV || (fops = blkdevs[i].fops) == NULL)
		return 0;
	if (fops->check_media_change == NULL)
		return 0;
	if (!fops->check_media_change(dev))
		return 0;

	printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
		bdevname(dev));

	sb = get_super(dev);
	if (sb && invalidate_inodes(sb))
		printk("VFS: busy inodes on changed media.\n");

	invalidate_buffers(dev);

	if (fops->revalidate)
		fops->revalidate(dev);
	return 1;
}
Exemplo n.º 6
0
/*
 * This routine checks whether a floppy has been changed, and
 * invalidates all buffer-cache-entries in that case. This
 * is a relatively slow routine, so we have to try to minimize using
 * it. Thus it is called only upon a 'mount' or 'open'. This
 * is the best way of combining speed and utility, I think.
 * People changing diskettes in the middle of an operation deserve
 * to loose :-)
 *
 * NOTE! Although currently this is only for floppies, the idea is
 * that any additional removable block-device will use this routine,
 * and that mount/open needn't know that floppies/whatever are
 * special.
 */
void check_disk_change(int dev)
{
	int i;
	struct buffer_head * bh;

	switch(MAJOR(dev)){
	case 2: /* floppy disc */
		if (!(bh = getblk(dev,0,1024)))
			return;
		i = floppy_change(bh);
		brelse(bh);
		break;

#if defined(CONFIG_BLK_DEV_SR) && defined(CONFIG_SCSI)
         case 11: /* CDROM */
		i = check_cdrom_media_change(dev, 0);
		if (i) printk("Flushing buffers and inodes for CDROM\n");
		break;
#endif

         default:
		return;
	};

	if (!i)	return;

	for (i=0 ; i<NR_SUPER ; i++)
		if (super_block[i].s_dev == dev)
			put_super(super_block[i].s_dev);
	invalidate_inodes(dev);
	invalidate_buffers(dev);
}
// Load textured_polyhedron from .OFF file
bool
Scene_textured_polyhedron_item::load(std::istream& in)
{
    std::cout<<"LOAD"<<std::endl;
    in >> *poly;
    invalidate_buffers();
    return in && !isEmpty();
}
Exemplo n.º 8
0
/*
 * This routine checks whether a floppy has been changed, and
 * invalidates all buffer-cache-entries in that case. This
 * is a relatively slow routine, so we have to try to minimize using
 * it. Thus it is called only upon a 'mount' or 'open'. This
 * is the best way of combining speed and utility, I think.
 * People changing diskettes in the middle of an operation deserve
 * to loose :-)
 *
 * NOTE! Although currently this is only for floppies, the idea is
 * that any additional removable block-device will use this routine,
 * and that mount/open needn't know that floppies/whatever are
 * special.
 */
void check_disk_change(dev_t dev)
{
	int i;
	struct buffer_head * bh;

	switch(MAJOR(dev)){
	case FLOPPY_MAJOR:
		if (!(bh = getblk(dev,0,1024)))
			return;
		i = floppy_change(bh);
		brelse(bh);
		break;

#if defined(CONFIG_BLK_DEV_SD) && defined(CONFIG_SCSI)
         case SCSI_DISK_MAJOR:
		i = check_scsidisk_media_change(dev, 0);
		break;
#endif

#if defined(CONFIG_BLK_DEV_SR) && defined(CONFIG_SCSI)
	 case SCSI_CDROM_MAJOR:
		i = check_cdrom_media_change(dev, 0);
		break;
#endif

#if defined(CONFIG_CDU31A)
         case CDU31A_CDROM_MAJOR:
		i = check_cdu31a_media_change(dev, 0);
		break;
#endif

#if defined(CONFIG_MCD)
         case MITSUMI_CDROM_MAJOR:
		i = check_mcd_media_change(dev, 0);
		break;
#endif

         default:
		return;
	};

	if (!i)	return;

	printk("VFS: Disk change detected on device %d/%d\n",
					MAJOR(dev), MINOR(dev));
	for (i=0 ; i<NR_SUPER ; i++)
		if (super_blocks[i].s_dev == dev)
			put_super(super_blocks[i].s_dev);
	invalidate_inodes(dev);
	invalidate_buffers(dev);

#if defined(CONFIG_BLK_DEV_SD) && defined(CONFIG_SCSI)
/* This is trickier for a removable hardisk, because we have to invalidate
   all of the partitions that lie on the disk. */
	if (MAJOR(dev) == SCSI_DISK_MAJOR)
		revalidate_scsidisk(dev, 0);
#endif
}
Exemplo n.º 9
0
static void
mcd_release(struct inode * inode, struct file * file)
{   MOD_DEC_USE_COUNT;
    if (!--mcd_open_count) {
        mcd_invalidate_buffers();
        sync_dev(inode->i_rdev);
        invalidate_buffers(inode -> i_rdev);
    }
}
Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(Textured_polyhedron* const p)
    : Scene_item(NbOfVbos,NbOfVaos),poly(p),textureId(-1),smooth_shading(true)
{
    cur_shading=FlatPlusEdges;
    is_selected=false;
    texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255);
    nb_facets = 0;
    nb_lines = 0;
    invalidate_buffers();
}
Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(const Textured_polyhedron& p)
    : Scene_item(5,2), poly(new Textured_polyhedron(p)),textureId(-1),smooth_shading(true)
{
    texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255);
    cur_shading=FlatPlusEdges;
    is_selected=false;
    nb_facets = 0;
    nb_lines = 0;
    invalidate_buffers();
}
Scene_textured_polyhedron_item::Scene_textured_polyhedron_item()
    : Scene_item(NbOfVbos,NbOfVaos),poly(new Textured_polyhedron), textureId(-1)
{
    texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255);
    cur_shading=FlatPlusEdges;
    is_selected=false;
    nb_facets = 0;
    nb_lines = 0;
    invalidate_buffers();
}
Exemplo n.º 13
0
static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
	struct NFTLrecord *nftl;

	nftl = NFTLs[MINOR(inode->i_rdev) / 16];

	if (!nftl) return -EINVAL;

	switch (cmd) {
	case HDIO_GETGEO: {
		struct hd_geometry g;

		g.heads = nftl->heads;
		g.sectors = nftl->sectors;
		g.cylinders = nftl->cylinders;
		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
	}
	case BLKGETSIZE:   /* Return device size */
		if (!arg) return -EINVAL;
		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
                                (long *) arg);
		
	case BLKFLSBUF:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		fsync_dev(inode->i_rdev);
		invalidate_buffers(inode->i_rdev);
		if (nftl->mtd->sync)
			nftl->mtd->sync(nftl->mtd);
		return 0;

	case BLKRRPART:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		if (nftl->usecount > 1) return -EBUSY;
#if LINUX_VERSION_CODE < 0x20328
		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) / 16);
#else
		grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) / 16,
				1<<4, nftl->nr_sects);
#endif
		return 0;

#if (LINUX_VERSION_CODE < 0x20303)		
	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
#else
	case BLKROSET:
	case BLKROGET:
	case BLKSSZGET:
		return blk_ioctl(inode->i_rdev, cmd, arg);
#endif

	default:
		return -EINVAL;
	}
}
Exemplo n.º 14
0
void Scene_combinatorial_map_item::set_next_volume(){
    //Update des vectors faits ici
    ++volume_to_display;
    volume_to_display=volume_to_display%(combinatorial_map().attributes<3>().size()+1);
  are_buffers_filled = false;
  invalidate_buffers();
  Q_EMIT itemChanged();

    if (exportSelectedVolume!=NULL && ( volume_to_display==1 || volume_to_display==0 ) )
        exportSelectedVolume->setEnabled(!exportSelectedVolume->isEnabled());
}
void
Scene_textured_polyhedron_item::
contextual_changed()
{
    prev_shading = cur_shading;
    cur_shading = renderingMode();
    if(prev_shading != cur_shading)
    {
        invalidate_buffers();
    }
}
Exemplo n.º 16
0
int change_root(kdev_t new_root_dev,const char *put_old)
{
	kdev_t old_root_dev;
	struct vfsmount *vfsmnt;
	struct inode *old_root,*old_pwd,*inode;
	unsigned long old_fs;
	int error;

	old_root = current->fs->root;
	old_pwd = current->fs->pwd;
	old_root_dev = ROOT_DEV;
	if (!fs_may_mount(new_root_dev)) {
		printk(KERN_CRIT "New root is busy. Staying in initrd.\n");
		return -EBUSY;
	}
	ROOT_DEV = new_root_dev;
	do_mount_root();
	old_fs = get_fs();
	set_fs(get_ds());
        error = namei(put_old,&inode);
	if (error) inode = NULL;
	set_fs(old_fs);
	if (!error && (inode->i_count != 1 || inode->i_mount)) error = -EBUSY;
	if (!error && !S_ISDIR(inode->i_mode)) error = -ENOTDIR;
	iput(old_root); /* current->fs->root */
	iput(old_pwd); /* current->fs->pwd */
	if (error) {
		int umount_error;

		if (inode) iput(inode);
		printk(KERN_NOTICE "Trying to unmount old root ... ");
		old_root->i_mount = old_root;
			/* does this belong into do_mount_root ? */
		umount_error = do_umount(old_root_dev,1);
		if (umount_error) printk(KERN_ERR "error %d\n",umount_error);
		else {
			printk(KERN_NOTICE "okay\n");
			invalidate_buffers(old_root_dev);
		}
		return umount_error ? error : 0;
	}
	iput(old_root); /* sb->s_covered */
	remove_vfsmnt(old_root_dev);
	vfsmnt = add_vfsmnt(old_root_dev,"old_rootfs",put_old);
	if (!vfsmnt) printk(KERN_CRIT "Trouble: add_vfsmnt failed\n");
	else {
		vfsmnt->mnt_sb = old_root->i_sb;
		vfsmnt->mnt_sb->s_covered = inode;
		vfsmnt->mnt_flags = vfsmnt->mnt_sb->s_flags;
	}
	inode->i_mount = old_root;
	return 0;
}
Exemplo n.º 17
0
Scene_polyhedron_transform_item::Scene_polyhedron_transform_item(const qglviewer::Vec& pos,const Scene_polyhedron_item* poly_item_,const CGAL::Three::Scene_interface*):
    Scene_item(NbOfVbos,NbOfVaos),
    poly_item(poly_item_),
    manipulable(false),
    frame(new ManipulatedFrame()),
    poly(poly_item->polyhedron()),
    center_(pos)

{
    frame->setPosition(pos);
    nb_lines = 0;
    invalidate_buffers();
}
Exemplo n.º 18
0
static void clean_main(struct sb *sb, struct inode *inode)
{
    log_finish(sb);
    log_finish_cycle(sb, 1);
    free_map(inode->map);
    destroy_defer_bfree(&sb->derollup);
    destroy_defer_bfree(&sb->defree);
    tux3_clear_dirty_inode(sb->logmap);
    invalidate_buffers(sb->volmap->map);
    tux3_clear_dirty_inode(sb->volmap);
    put_super(sb);
    tux3_exit_mem();
}
Exemplo n.º 19
0
Scene_polylines_item::Scene_polylines_item() 
    :Scene_item(8,3)
    ,d(new Scene_polylines_item_private())
    ,nbSpheres(0)
{
    setRenderingMode(FlatPlusEdges);
    nb_spheres = 0;
    nb_wire = 0;
    nb_centers = 0;
    nb_lines = 0;
    invalidate_buffers();

}
Exemplo n.º 20
0
static void __exit radimo_cleanup(void)
{
	unregister_blkdev(RADIMO_MAJOR, "radimo");
	del_timer(&radimo_timer);

	invalidate_buffers(MKDEV(RADIMO_MAJOR,0));

	/* remove our request function */
        blk_cleanup_queue(BLK_DEFAULT_QUEUE(RADIMO_MAJOR));
	vfree(radimo_storage);

	MSG(RADIMO_INFO, "unloaded\n");
}	
Exemplo n.º 21
0
/*
 * This routine checks whether a floppy has been changed, and
 * invalidates all buffer-cache-entries in that case. This
 * is a relatively slow routine, so we have to try to minimize using
 * it. Thus it is called only upon a 'mount' or 'open'. This
 * is the best way of combining speed and utility, I think.
 * People changing diskettes in the middle of an operation deserve
 * to loose :-)
 *
 * NOTE! Although currently this is only for floppies, the idea is
 * that any additional removable block-device will use this routine,
 * and that mount/open needn't know that floppies/whatever are
 * special.
 */
void check_disk_change(int dev)
{
    int i;

    if (MAJOR(dev) != 2)
        return;
    if (!floppy_change(dev & 0x03))
        return;
    for (i=0 ; i<NR_SUPER ; i++)
        if (super_block[i].s_dev == dev)
            put_super(super_block[i].s_dev);
    invalidate_inodes(dev);
    invalidate_buffers(dev);
}
Exemplo n.º 22
0
void
Scene_polylines_item::merge(Scene_polylines_item* other_item) {
    if(other_item == 0) return;
    std::copy(other_item->polylines.begin(),
              other_item->polylines.end(),
              std::back_inserter(polylines));
    QVariant other_metadata_variant = other_item->property("polylines metadata");
    if(other_metadata_variant.type() == QVariant::StringList)
    {
        QStringList metadata = property("polylines metadata").toStringList();
        metadata.append(other_metadata_variant.toStringList());
        setProperty("polylines metadata", metadata);
    }
    invalidate_buffers();
}
Exemplo n.º 23
0
bool
Scene_nef_polyhedron_item::load_from_off(std::istream& in)
{
    //   const std::size_t discarded = CGAL::OFF_to_nef_3(in, *nef_poly);
    //   return discarded != 0;

    Exact_polyhedron exact_poly;
    in >> exact_poly;
    *nef_poly = Nef_polyhedron(exact_poly);

    //   Polyhedron poly;
    //   in >> poly;
    //   *nef_poly = Nef_polyhedron(poly);
    invalidate_buffers();
    return (bool) in;
}
static void __exit radimo_cleanup(void)
{
	unregister_blkdev(RADIMO_MAJOR, "radimo");
	del_timer(&radimo_timer);

	invalidate_buffers(MKDEV(RADIMO_MAJOR,0));

	/* remove our request function */
#if LINUX_VERSION_CODE < 0x20320
	blk_dev[RADIMO_MAJOR].request_fn = 0;
#else	
        blk_cleanup_queue(BLK_DEFAULT_QUEUE(RADIMO_MAJOR));
#endif
	vfree(radimo_storage);

	MSG(RADIMO_INFO, "unloaded\n");
}	
Exemplo n.º 25
0
/*
 * This routine checks whether a floppy has been changed, and
 * invalidates all buffer-cache-entries in that case. This
 * is a relatively slow routine, so we have to try to minimize using
 * it. Thus it is called only upon a 'mount' or 'open'. This
 * is the best way of combining speed and utility, I think.
 * People changing diskettes in the middle of an operation deserve
 * to loose :-)
 *
 * NOTE! Although currently this is only for floppies, the idea is
 * that any additional removable block-device will use this routine,
 * and that mount/open needn't know that floppies/whatever are
 * special.
 */
void check_disk_change(int dev)
{
	int i;
	struct buffer_head * bh;

	if (MAJOR(dev) != 2)
		return;
	if (!(bh = getblk(dev,0)))
		return;
	i = floppy_change(bh);
	brelse(bh);
	if (!i)
		return;
	for (i=0 ; i<NR_SUPER ; i++)
		if (super_block[i].s_dev == dev)
			put_super(super_block[i].s_dev);
	invalidate_inodes(dev);
	invalidate_buffers(dev);
}
void radimo_timer_fn(unsigned long data)
{
	MSG(RADIMO_TIMER, "timer expired\n");

	/* only "change media" if device is unused */
	if (MOD_IN_USE) {
		radimo_changed = 0;
	} else {
		/* medium changed, clear storage and */
		MSG(RADIMO_TIMER, "simulating media change\n");
                /* By erasing the first four blocks! */
                memset(radimo_storage, 0, RADIMO_BLOCK_SIZE * 4 ); 
		radimo_changed = 1;
		/* data contains i_rdev */
		fsync_dev(data);
		invalidate_buffers(data);
	}

	/* set it up again */
	radimo_timer.expires = RADIMO_TIMER_DELAY + jiffies;
	add_timer(&radimo_timer);
}
Exemplo n.º 27
0
int sbull_release (struct inode *inode, struct file *filp)
{
    Sbull_Dev *dev = sbull_devices + MINOR(inode->i_rdev);

    spin_lock(&dev->lock);
    dev->usage--;
    /*
     * If the device is closed for the last time, start a timer
     * to release RAM in half a minute. The function and argument
     * for the timer have been setup in sbull_init()
     */
    if (!dev->usage) {
        dev->timer.expires = jiffies + 30 * HZ;
        add_timer(&dev->timer);
        /* but flush it right now */
        fsync_dev(inode->i_rdev);
        invalidate_buffers(inode->i_rdev);
    }
    MOD_DEC_USE_COUNT;
    spin_unlock(&dev->lock);
    return 0;
}
Exemplo n.º 28
0
Arquivo: rd.c Projeto: KP1533TM2/elks
static int rd_ioctl(register struct inode *inode, struct file *file,
		    unsigned int cmd, unsigned int arg)
{
    unsigned long size;
    unsigned int i;
    int j, k, target = DEVICE_NR(inode->i_rdev);

    if (!suser())
	return -EPERM;
    debug2("RD: ioctl %d %s\n", target, (cmd ? "kill" : "make"));
    switch (cmd) {
    case RDCREATE:
	if (rd_info[target].flags && RD_BUSY) {
	    return -EBUSY;
	} else {
	    /* allocate memory */

#if 0
	    rd_info[target].size = 0;
#endif

	    k = -1;
	    for (i = 0; i <= (arg - 1) / ((SEG_SIZE / 1024) * P_SIZE); i++) {
		j = find_free_seg();	/* find free place in queue */
		debug1("RD: ioctl find_free_seg() = %d\n", j);
		if (j == -1) {
		    rd_dealloc(target);
		    return -ENOMEM;
		}
		if (i == 0)
		    rd_info[target].index = j;

		if (i == (arg / ((SEG_SIZE / 1024) * P_SIZE)))
		    /* size in 16 byte pagez = (arg % 64) * 64 */
		    size =
			(arg % ((SEG_SIZE / 1024) * P_SIZE)) *
			((SEG_SIZE / 1024) * P_SIZE);
		else
		    size = SEG_SIZE;

		rd_segment[j].segment = mm_alloc(size);
		if (rd_segment[j].segment == -1) {
		    rd_dealloc(target);
		    return -ENOMEM;
		}
		debug4("RD: ioctl pass: %d, allocated %d pages, rd_segment[%d].segment = 0x%x\n",
		       i, (int) size, j, rd_segment[j].segment);

		/* recalculate int size to reflect size in sectors, not pages */
		size = size / DIVISOR;

		rd_segment[j].seg_size = size;	/* size in sectors */
		debug2("RD: ioctl rd_segment[%d].seg_size = %d sectors\n",
		       j, rd_segment[j].seg_size);
		rd_info[target].size += rd_segment[j].seg_size;	/* size in 512 B blocks */
		size = (long) rd_segment[j].seg_size * SECTOR_SIZE;
		debug1("RD: ioctl size = %ld\n", size);

		/* this terrible hack makes sure fmemset clears whole segment even if size == 64 KB :) */
		if (size != ((long) SEG_SIZE * (long) P_SIZE)) {
		    debug2("RD: ioctl calling fmemset(0, 0x%x, 0, %d) ..\n",
			   rd_segment[j].segment, (int) size);
		    fmemset(0, rd_segment[j].segment, 0, (int) size);	/* clear seg_size * SECTOR_SIZE bytes */
		} else {
		    debug2("RD: ioctl calling fmemset(0, 0x%x, 0, %d) ..\n",
			   rd_segment[j].segment, (int) (size / 2));
		    fmemset(0, rd_segment[j].segment, 0, (int) (size / 2));	/* we could hardcode 32768 instead of size / 2 here */
		    debug3("rd_ioctl(): calling fmemset(%d, 0x%x, 0, %d) ..\n",
			   (int) (size / 2), rd_segment[j].segment,
			   (int) (size / 2));
		    fmemset((size / 2), rd_segment[j].segment, 0,
			    (int) (size / 2));
		}

		if (k != -1)
		    rd_segment[k].next = j;	/* set link to next index */
		k = j;
	    }
	    rd_info[target].flags = RD_BUSY;
	    debug3("RD: ioctl ramdisk %d created, size = %d blocks, index = %d\n",
		 target, rd_info[target].size, rd_info[target].index);
	}
	debug("RD: ioctl about to return 0\n");
	return 0;
    case RDDESTROY:
	if (rd_info[target].flags && RD_BUSY) {
	    invalidate_inodes(inode->i_rdev);
	    invalidate_buffers(inode->i_rdev);
	    rd_dealloc(target);
	    rd_info[target].flags = 0;
	    return 0;
	} else
	    return -EINVAL;
    }
    return -EINVAL;
}
static int radimo_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	unsigned int minor;
	
	if (!inode || !inode->i_rdev) 	
		return -EINVAL;

	minor = MINOR(inode->i_rdev);

	switch (cmd) {

		case BLKFLSBUF: {
			/* flush buffers */
			MSG(RADIMO_IOCTL, "ioctl: BLKFLSBUF\n");
			/* deny all but root */
			if (!capable(CAP_SYS_ADMIN))
				return -EACCES;
			fsync_dev(inode->i_rdev);
			invalidate_buffers(inode->i_rdev);
			break;
		}

         	case BLKGETSIZE: {
			/* return device size */
			MSG(RADIMO_IOCTL, "ioctl: BLKGETSIZE\n");
			if (!arg)
				return -EINVAL;
			return put_user(radimo_size*2, (long *) arg);
		}
		
		case BLKRASET: {
			/* set read ahead value */
			int tmp;
			MSG(RADIMO_IOCTL, "ioctl: BLKRASET\n");
			if (get_user(tmp, (long *)arg))
				return -EINVAL;
			if (tmp > 0xff)
				return -EINVAL;
			read_ahead[RADIMO_MAJOR] = tmp;
			return 0;
		}

		case BLKRAGET: {
			/* return read ahead value */
			MSG(RADIMO_IOCTL, "ioctl: BLKRAGET\n");
			if (!arg)
				return -EINVAL;
			return put_user(read_ahead[RADIMO_MAJOR], (long *)arg);
		}

		case BLKSSZGET: {
			/* return block size */
			MSG(RADIMO_IOCTL, "ioctl: BLKSSZGET\n");
			if (!arg)
				return -EINVAL;
			return put_user(radimo_soft, (long *)arg);
		}

		default: {
			MSG(RADIMO_ERROR, "ioctl wanted %u\n", cmd);
			return -ENOTTY;
		}
	}

	return 0;
}
Exemplo n.º 30
0
static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
	struct NFTLrecord *nftl;
	int p;

	nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS];

	if (!nftl) return -EINVAL;

	switch (cmd) {
	case HDIO_GETGEO: {
		struct hd_geometry g;

		g.heads = nftl->heads;
		g.sectors = nftl->sectors;
		g.cylinders = nftl->cylinders;
		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
	}
	case BLKGETSIZE:   /* Return device size */
		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
                                (unsigned long *) arg);

#ifdef BLKGETSIZE64
	case BLKGETSIZE64:
		return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
                                (u64 *)arg);
#endif

	case BLKFLSBUF:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		fsync_dev(inode->i_rdev);
		invalidate_buffers(inode->i_rdev);
		if (nftl->mtd->sync)
			nftl->mtd->sync(nftl->mtd);
		return 0;

	case BLKRRPART:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		if (nftl->usecount > 1) return -EBUSY;
		/* 
		 * We have to flush all buffers and invalidate caches,
		 * or we won't be able to re-use the partitions,
		 * if there was a change and we don't want to reboot
		 */
		p = (1<<NFTL_PARTN_BITS) - 1;
		while (p-- > 0) {
			kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p);
			if (part_table[p].nr_sects > 0)
				invalidate_device (devp, 1);

			part_table[MINOR(inode->i_dev)+p].start_sect = 0;
			part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
		}
		
#if LINUX_VERSION_CODE < 0x20328
		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS);
#else
		grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS,
				1<<NFTL_PARTN_BITS, nftl->nr_sects);
#endif
		return 0;

#if (LINUX_VERSION_CODE < 0x20303)		
	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
#else
	case BLKROSET:
	case BLKROGET:
	case BLKSSZGET:
		return blk_ioctl(inode->i_rdev, cmd, arg);
#endif

	default:
		return -EINVAL;
	}
}