📄 zlg_fs.c
字号:
{ int num; Disk_RW_Parameter dp; unsigned long flag; int part1, npart, i; num = DEVICE_NR(inode->i_rdev); if (num >= MAX_DISKS) { return -ENODEV; } if (DiskInfo[num] == NULL) { return -ENODEV; } //local_irq_save(flag); ZLG_FS_usage[num]--; if (ZLG_FS_usage[num] == 0) { if (DiskInfo[num]->release != NULL) { DiskInfo[num]->release(inode, filp); } part1 = (num << ZLG_FS_SHIFT); npart = (1 << ZLG_FS_SHIFT) -1; dp.RsvdForLow = DiskInfo[num]->RsvdForLow; DiskInfo[num]->DiakCommand(DISK_CLOSE, &dp); for (i = 0; i <= npart; i++) { fsync_dev(MKDEV(major, part1++)); } } //local_irq_restore(flag); MOD_DEC_USE_COUNT; return 0; } /*********************************************************************************************************
** Function name: zlg_fs_ioctl
** Descriptions: IO control function
** Input:inode: information of device
** filp: pointer of file
** cmd: command
** arg: additive parameter
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-25
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int zlg_fs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ long err, size; struct hd_geometry geo; int num; num = DEVICE_NR(inode->i_rdev); if (num >= MAX_DISKS) { return -ENODEV; } if (DiskInfo[num] == NULL) { return -ENODEV; } switch(cmd) { case BLKGETSIZE: /* Return the device size, expressed in sectors */ if (arg == 0) { return -EINVAL; /* NULL pointer: not valid */ } if(access_ok(VERIFY_WRITE, arg, sizeof(long)) == 0) { return -EFAULT; } size = zlg_fs_gendisk.part[MINOR(inode->i_rdev)].nr_sects; if (copy_to_user((long *) arg, &size, sizeof (long))) { return -EFAULT; } return 0;// case BLKFLSBUF: /* flush */// if (! capable(CAP_SYS_RAWIO)) return -EACCES; /* only root */// fsync_dev(inode->i_rdev);// invalidate_buffers(inode->i_rdev);// return 0;// case BLKRAGET: /* return the readahead value */// err = ! access_ok(VERIFY_WRITE, arg, sizeof(long));// if (err) return -EFAULT;// PUT_USER(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);// return 0;// case BLKRASET: /* set the readahead value */// if (!capable(CAP_SYS_RAWIO)) return -EACCES;// if (arg > 0xff) return -EINVAL; /* limit it */// read_ahead[MAJOR(inode->i_rdev)] = arg;// return 0; case BLKRRPART: /* re-read partition table: can't do it */ return zlg_fs_revalidate(inode->i_rdev); case HDIO_GETGEO: /* * Get geometry: since we are a virtual device, we have to make * up something plausible. So we claim 16 sectors, four heads, * and calculate the corresponding number of cylinders. We set the * start of data at sector four. */ if (access_ok(VERIFY_WRITE, arg, sizeof(geo)) == 0) { return -EFAULT; } size = DiskInfo[num]->SecPerDisk; geo.cylinders = (size & ~0x3f) >> 6; geo.heads = 4; geo.sectors = 16; geo.start = 0; if (copy_to_user((void *) arg, &geo, sizeof(geo))) { return -EFAULT; } return 0; default: /* * For ioctls we don't understand, let the block layer handle them. */ return blk_ioctl(inode->i_rdev, cmd, arg); } return -ENOTTY; /* unknown command */}/*********************************************************************************************************
** Function name: check_zlg_fs_change
** Descriptions:
** Input:dev:
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-25
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int check_zlg_fs_change(kdev_t dev){ int num; Disk_RW_Parameter dp; num = DEVICE_NR(dev); if (num >= MAX_DISKS) { return -ENODEV; } if (DiskInfo[num] == NULL) { return -ENODEV; } dp.RsvdForLow = DiskInfo[num]->RsvdForLow; if (DiskInfo[num]->DiakCommand(DISK_CHECK_CHANGE, &dp) == DISK_TRUE) { return 1; } return 0;}/*********************************************************************************************************
** Function name: zlg_fs_revalidate
** Descriptions: revalidate device
** Input:dev: nformation of device
** Output 0: OK
** 1: not OK
** Created by: Chenmingji
** Created Date: 2005-05-25
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static int zlg_fs_revalidate(kdev_t dev){ int num; unsigned long flag; int part1, npart, i; num = DEVICE_NR(dev); if (num >= MAX_DISKS) { return -ENODEV; } if (DiskInfo[num] == NULL) { return -ENODEV; } if (DiskInfo[num]->get_info == NULL) { return -ENODEV; } DiskInfo[num]->get_info(DiskInfo[num]); part1 = (num << ZLG_FS_SHIFT) + 1; npart = (1 << ZLG_FS_SHIFT) - 1; memset(zlg_fs_gendisk.sizes + part1, 0, npart * sizeof(int)); memset(zlg_fs_gendisk.part + part1, 0, npart * sizeof(struct hd_struct)); //local_irq_save(flag); for (i = 0; i <= npart; i++) { part1++; ZLG_FS_blocksizes[part1] = DiskInfo[num]->BytesPerSec; ZLG_FS_sizes[part1] = (DiskInfo[num]->SecPerDisk * ZLG_FS_blocksizes[num]) / 1024; } zlg_fs_gendisk.part[num << ZLG_FS_SHIFT].nr_sects = DiskInfo[num]->SecPerDisk; register_disk(&zlg_fs_gendisk, dev, 1 << ZLG_FS_SHIFT, &zlg_fs_fops, DiskInfo[num]->SecPerDisk); //local_irq_restore(flag); return 0;}/*********************************************************************************************************
** Function name: zlg_fs_init
** Descriptions: init driver
** Input:none
** Output 0: OK
** other: not OK
** Created by: Chenmingji
** Created Date: 2005-05-25
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int zlg_fs_init(void){ int result, i; result = register_blkdev(MAJOR_NR, DEVICE_NAME, &zlg_fs_fops); if (result < 0) { printk(KERN_ERR DEVICE_NAME ": Unable to get major %d\n", MAJOR_NR ); return(result); } if (MAJOR_NR == 0) { MAJOR_NR = result; /* dynamic */ } zlg_fs_gendisk.major = major;
zlg_fs_gendisk.major_name = DEVICE_NAME;
zlg_fs_gendisk.minor_shift = ZLG_FS_SHIFT;
zlg_fs_gendisk.max_p = 1 << ZLG_FS_SHIFT;
zlg_fs_gendisk.fops = &zlg_fs_fops;
zlg_fs_gendisk.sizes = ZLG_FS_sizes; zlg_fs_gendisk.nr_real = MAX_DISKS; zlg_fs_gendisk.part = part; zlg_fs_gendisk.next = gendisk_head; gendisk_head = &zlg_fs_gendisk; //blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), zlg_fs_queue); blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), zlg_fs_make_request); blk_size[MAJOR_NR] = ZLG_FS_sizes; blksize_size[MAJOR_NR] = ZLG_FS_blocksizes; printk(KERN_INFO DEVICE_NAME ": init OK\n"); return 0; }/*********************************************************************************************************
** Function name: zlg_fs_cleanup
** Descriptions: exit driver
** Input:none
** Output none
** Created by: Chenmingji
** Created Date: 2005-05-25
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void zlg_fs_cleanup(void){ unregister_blkdev(MAJOR_NR, DEVICE_NAME);}/*********************************************************************************************************** End Of File********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -