if (p->ref && p->type != type)
                return -EBUSY;
 
-       if (p->ref == -1 || (p->ref && filp->f_flags & O_EXCL))
+       if (p->ref == -1 || (p->ref && filp->f_mode & FMODE_EXCL))
                return -EBUSY;
 
-       if (filp->f_flags & O_EXCL)
+       if (filp->f_mode & FMODE_EXCL)
                p->ref = -1;
        else
                p->ref++;
 
        p->type = type;
 
-       if (filp->f_flags & O_NDELAY)
+       if (filp->f_mode & FMODE_NDELAY)
                return 0;
 
        if (filp->f_mode & (FMODE_READ|FMODE_WRITE)) {
 
 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                    unsigned long param)
 {
-#define FD_IOCTL_ALLOWED ((filp) && (filp)->private_data)
+#define FD_IOCTL_ALLOWED ((filp) && (filp)->f_mode & (FMODE_WRITE|FMODE_WRITE_IOCTL))
 #define OUT(c,x) case c: outparam = (const char *) (x); break
 #define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
 
        int res = -EBUSY;
        char *tmp;
 
-       filp->private_data = (void *)0;
        mutex_lock(&open_lock);
        old_dev = UDRS->fd_device;
        if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
                USETF(FD_VERIFY);
        }
 
-       if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
+       if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_mode & FMODE_EXCL)))
                goto out2;
 
-       if (filp->f_flags & O_EXCL)
+       if (filp->f_mode & FMODE_EXCL)
                UDRS->fd_ref = -1;
        else
                UDRS->fd_ref++;
                        buffer_track = -1;
        }
 
-       /* Allow ioctls if we have write-permissions even if read-only open.
-        * Needed so that programs such as fdrawcmd still can work on write
-        * protected disks */
-       if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
-               filp->private_data = (void *)8;
-
        if (UFDCS->rawcmd == 1)
                UFDCS->rawcmd = 2;
 
-       if (!(filp->f_flags & O_NDELAY)) {
+       if (!(filp->f_mode & FMODE_NDELAY)) {
                if (filp->f_mode & (FMODE_READ|FMODE_WRITE)) {
                        UDRS->last_checked = 0;
                        check_disk_change(inode->i_bdev);
 
                swim3_action(fs, SETMFM);
                swim3_select(fs, RELAX);
 
-       } else if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
+       } else if (fs->ref_count == -1 || filp->f_mode & FMODE_EXCL)
                return -EBUSY;
 
-       if (err == 0 && (filp->f_flags & O_NDELAY) == 0
+       if (err == 0 && (filp->f_mode & FMODE_NDELAY) == 0
            && (filp->f_mode & (FMODE_READ|FMODE_WRITE))) {
                check_disk_change(inode->i_bdev);
                if (fs->ejected)
                return err;
        }
 
-       if (filp->f_flags & O_EXCL)
+       if (filp->f_mode & FMODE_EXCL)
                fs->ref_count = -1;
        else
                ++fs->ref_count;
 
         * under some pretty murky conditions (a failure of READ CAPACITY).
         * We may need it one day.
         */
-       if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) {
+       if (lun->removable && lun->changed && !(filp->f_mode & FMODE_NDELAY)) {
                rc = -ENOMEDIUM;
                goto err_open;
        }
 
        /* if this was a O_NONBLOCK open and we should honor the flags,
         * do a quick open without drive/disc integrity checks. */
        cdi->use_count++;
-       if ((fp->f_flags & O_NONBLOCK) && (cdi->options & CDO_USE_FFLAGS)) {
+       if ((fp->f_mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) {
                ret = cdi->ops->open(cdi, 1);
        } else {
                ret = open_for_data(cdi);
        }
 
        opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
-               !(fp && fp->f_flags & O_NONBLOCK);
+               !(fp && fp->f_mode & FMODE_NDELAY);
 
        /*
         * flush cache on last write release
 
                 * unreadable disk, so that we can get the format capacity
                 * of the drive or begin the format - Sam
                 */
-               if (ret && (filp->f_flags & O_NDELAY) == 0) {
+               if (ret && (filp->f_mode & FMODE_NDELAY) == 0) {
                        ret = -EIO;
                        goto out_put_idkp;
                }
 
         */
        retval = -ENOMEDIUM;
        if (sdev->removable && !sdkp->media_present &&
-           !(filp->f_flags & O_NDELAY))
+           !(filp->f_mode & FMODE_NDELAY))
                goto error_out;
 
        /*
 
                return ret;
        }
 
+       if (file->f_flags & O_NDELAY)
+               file->f_mode |= FMODE_NDELAY;
+       if (file->f_flags & O_EXCL)
+               file->f_mode |= FMODE_EXCL;
+       if ((file->f_flags & O_ACCMODE) == 3)
+               file->f_mode |= FMODE_WRITE_IOCTL;
+
        ret = -ENXIO;
        file->f_mapping = bdev->bd_inode->i_mapping;
 
 
    behavior for cross-node execution/opening_for_writing of files */
 #define FMODE_EXEC     ((__force fmode_t)16)
 
+#define FMODE_NDELAY   ((__force fmode_t)32)
+#define FMODE_EXCL     ((__force fmode_t)64)
+#define FMODE_WRITE_IOCTL      ((__force fmode_t)128)
+
 #define RW_MASK                1
 #define RWA_MASK       2
 #define READ 0