static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct cdrom_read_audio __user *cdread_audio; struct compat_cdrom_read_audio __user *cdread_audio32; __u32 data; void __user *datap; cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio)); cdread_audio32 = compat_ptr(arg); if (copy_in_user(&cdread_audio->addr, &cdread_audio32->addr, (sizeof(*cdread_audio32) - sizeof(compat_caddr_t)))) return -EFAULT; if (get_user(data, &cdread_audio32->buf)) return -EFAULT; datap = compat_ptr(data); if (put_user(datap, &cdread_audio->buf)) return -EFAULT; return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cdread_audio); }
static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct cdrom_generic_command __user *cgc; struct compat_cdrom_generic_command __user *cgc32; u32 data; unsigned char dir; int itmp; cgc = compat_alloc_user_space(sizeof(*cgc)); cgc32 = compat_ptr(arg); if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) || get_user(data, &cgc32->buffer) || put_user(compat_ptr(data), &cgc->buffer) || copy_in_user(&cgc->buflen, &cgc32->buflen, (sizeof(unsigned int) + sizeof(int))) || get_user(data, &cgc32->sense) || put_user(compat_ptr(data), &cgc->sense) || get_user(dir, &cgc32->data_direction) || put_user(dir, &cgc->data_direction) || get_user(itmp, &cgc32->quiet) || put_user(itmp, &cgc->quiet) || get_user(itmp, &cgc32->timeout) || put_user(itmp, &cgc->timeout) || get_user(data, &cgc32->reserved[0]) || put_user(compat_ptr(data), &cgc->reserved[0])) return -EFAULT; return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc); }
int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync) { int err; struct super_block *sb = file->f_dentry->d_sb; struct block_device *bdev = sb->s_bdev; if (!file->f_op || !file->f_op->fsync) return -EINVAL; err = file->f_op->fsync(file, start, end, datasync); if(err) return err; /* *2013.09.30: fix the bug that system cannot start up when storage *device is emmc, ioctl chanel only for nand flash */ if (bdev != NULL && MAJOR(bdev->bd_dev) == NFTL_MAJOR) err = __blkdev_driver_ioctl(bdev, O_RDONLY, BLKFLSBUF, 0); return err; }
static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); unsigned long kval; unsigned int __user *uvp; int error; set_fs(KERNEL_DS); error = __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)(&kval)); set_fs(old_fs); if (error == 0) { uvp = compat_ptr(arg); if (put_user(kval, uvp)) error = -EFAULT; } return error; }
static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); void *karg = NULL; unsigned int kcmd = 0; int i, err; for (i = 0; i < NR_FD_IOCTL_TRANS; i++) if (cmd == fd_ioctl_trans_table[i].cmd32) { kcmd = fd_ioctl_trans_table[i].cmd; break; } if (!kcmd) return -EINVAL; switch (cmd) { case FDSETPRM32: case FDDEFPRM32: case FDGETPRM32: { compat_uptr_t name; struct compat_floppy_struct __user *uf; struct floppy_struct *f; uf = compat_ptr(arg); f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETPRM32) break; err = __get_user(f->size, &uf->size); err |= __get_user(f->sect, &uf->sect); err |= __get_user(f->head, &uf->head); err |= __get_user(f->track, &uf->track); err |= __get_user(f->stretch, &uf->stretch); err |= __get_user(f->gap, &uf->gap); err |= __get_user(f->rate, &uf->rate); err |= __get_user(f->spec1, &uf->spec1); err |= __get_user(f->fmt_gap, &uf->fmt_gap); err |= __get_user(name, &uf->name); f->name = compat_ptr(name); if (err) { err = -EFAULT; goto out; } break; } case FDSETDRVPRM32: case FDGETDRVPRM32: { struct compat_floppy_drive_params __user *uf; struct floppy_drive_params *f; uf = compat_ptr(arg); f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL); if (!karg) return -ENOMEM; if (cmd == FDGETDRVPRM32) break; err = __get_user(f->cmos, &uf->cmos); err |= __get_user(f->max_dtr, &uf->max_dtr); err |= __get_user(f->hlt, &uf->hlt); err |= __get_user(f->hut, &uf->hut); err |= __get_user(f->srt, &uf->srt); err |= __get_user(f->spinup, &uf->spinup); err |= __get_user(f->spindown, &uf->spindown); err |= __get_user(f->spindown_offset, &uf->spindown_offset); err |= __get_user(f->select_delay, &uf->select_delay); err |= __get_user(f->rps, &uf->rps); err |= __get_user(f->tracks, &uf->tracks); err |= __get_user(f->timeout, &uf->timeout); err |= __get_user(f->interleave_sect, &uf->interleave_sect); err |= __copy_from_user(&f->max_errors, &uf->max_errors, sizeof(f->max_errors)); err |= __get_user(f->flags, &uf->flags); err |= __get_user(f->read_track, &uf->read_track); err |= __copy_from_user(f->autodetect, uf->autodetect, sizeof(f->autodetect)); err |= __get_user(f->checkfreq, &uf->checkfreq); err |= __get_user(f->native_format, &uf->native_format); if (err) { err = -EFAULT; goto out; } break; } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDGETFDCSTAT32: karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL); if (!karg) return -ENOMEM; break; case FDWERRORGET32: karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL); if (!karg) return -ENOMEM; break; default: return -EINVAL; } set_fs(KERNEL_DS); err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg); set_fs(old_fs); if (err) goto out; switch (cmd) { case FDGETPRM32: { struct floppy_struct *f = karg; struct compat_floppy_struct __user *uf = compat_ptr(arg); err = __put_user(f->size, &uf->size); err |= __put_user(f->sect, &uf->sect); err |= __put_user(f->head, &uf->head); err |= __put_user(f->track, &uf->track); err |= __put_user(f->stretch, &uf->stretch); err |= __put_user(f->gap, &uf->gap); err |= __put_user(f->rate, &uf->rate); err |= __put_user(f->spec1, &uf->spec1); err |= __put_user(f->fmt_gap, &uf->fmt_gap); err |= __put_user((u64)f->name, (compat_caddr_t __user *)&uf->name); break; } case FDGETDRVPRM32: { struct compat_floppy_drive_params __user *uf; struct floppy_drive_params *f = karg; uf = compat_ptr(arg); err = __put_user(f->cmos, &uf->cmos); err |= __put_user(f->max_dtr, &uf->max_dtr); err |= __put_user(f->hlt, &uf->hlt); err |= __put_user(f->hut, &uf->hut); err |= __put_user(f->srt, &uf->srt); err |= __put_user(f->spinup, &uf->spinup); err |= __put_user(f->spindown, &uf->spindown); err |= __put_user(f->spindown_offset, &uf->spindown_offset); err |= __put_user(f->select_delay, &uf->select_delay); err |= __put_user(f->rps, &uf->rps); err |= __put_user(f->tracks, &uf->tracks); err |= __put_user(f->timeout, &uf->timeout); err |= __put_user(f->interleave_sect, &uf->interleave_sect); err |= __copy_to_user(&uf->max_errors, &f->max_errors, sizeof(f->max_errors)); err |= __put_user(f->flags, &uf->flags); err |= __put_user(f->read_track, &uf->read_track); err |= __copy_to_user(uf->autodetect, f->autodetect, sizeof(f->autodetect)); err |= __put_user(f->checkfreq, &uf->checkfreq); err |= __put_user(f->native_format, &uf->native_format); break; } case FDGETDRVSTAT32: case FDPOLLDRVSTAT32: { struct compat_floppy_drive_struct __user *uf; struct floppy_drive_struct *f = karg; uf = compat_ptr(arg); err = __put_user(f->flags, &uf->flags); err |= __put_user(f->spinup_date, &uf->spinup_date); err |= __put_user(f->select_date, &uf->select_date); err |= __put_user(f->first_read_date, &uf->first_read_date); err |= __put_user(f->probed_format, &uf->probed_format); err |= __put_user(f->track, &uf->track); err |= __put_user(f->maxblock, &uf->maxblock); err |= __put_user(f->maxtrack, &uf->maxtrack); err |= __put_user(f->generation, &uf->generation); err |= __put_user(f->keep_data, &uf->keep_data); err |= __put_user(f->fd_ref, &uf->fd_ref); err |= __put_user(f->fd_device, &uf->fd_device); err |= __put_user(f->last_checked, &uf->last_checked); err |= __put_user((u64)f->dmabuf, &uf->dmabuf); err |= __put_user((u64)f->bufblocks, &uf->bufblocks); break; } case FDGETFDCSTAT32: { struct compat_floppy_fdc_state __user *uf; struct floppy_fdc_state *f = karg; uf = compat_ptr(arg); err = __put_user(f->spec1, &uf->spec1); err |= __put_user(f->spec2, &uf->spec2); err |= __put_user(f->dtr, &uf->dtr); err |= __put_user(f->version, &uf->version); err |= __put_user(f->dor, &uf->dor); err |= __put_user(f->address, &uf->address); err |= __copy_to_user((char __user *)&uf->address + sizeof(uf->address), (char *)&f->address + sizeof(f->address), sizeof(int)); err |= __put_user(f->driver_version, &uf->driver_version); err |= __copy_to_user(uf->track, f->track, sizeof(f->track)); break; } case FDWERRORGET32: { struct compat_floppy_write_errors __user *uf; struct floppy_write_errors *f = karg; uf = compat_ptr(arg); err = __put_user(f->write_errors, &uf->write_errors); err |= __put_user(f->first_error_sector, &uf->first_error_sector); err |= __put_user(f->first_error_generation, &uf->first_error_generation); err |= __put_user(f->last_error_sector, &uf->last_error_sector); err |= __put_user(f->last_error_generation, &uf->last_error_generation); err |= __put_user(f->badness, &uf->badness); break; } default: break; } if (err) err = -EFAULT; out: kfree(karg); return err; }