/* * 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; } }
//// 检查磁盘是否更换,如果已更换就使对应高速缓冲区无效。 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 ); }
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++; }
/* * 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; }
/* * 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(); }
/* * 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 }
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(); }
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; } }
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(); } }
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; }
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(); }
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(); }
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(); }
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"); }
/* * 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); }
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(); }
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"); }
/* * 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); }
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; }
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; }
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; } }