From 244b2c5ca8b14627e4a17755e5922221e121c771 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 09 Oct 2024 06:15:07 +0000
Subject: [PATCH] change system file
---
kernel/drivers/scsi/st.c | 114 ++++++++++++++++++++++++++++++++------------------------
1 files changed, 65 insertions(+), 49 deletions(-)
diff --git a/kernel/drivers/scsi/st.c b/kernel/drivers/scsi/st.c
index 5078db7..19bc8c9 100644
--- a/kernel/drivers/scsi/st.c
+++ b/kernel/drivers/scsi/st.c
@@ -1,6 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
SCSI Tape Driver for Linux version 1.1 and newer. See the accompanying
- file Documentation/scsi/st.txt for more information.
+ file Documentation/scsi/st.rst for more information.
History:
Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
@@ -21,6 +22,7 @@
#include <linux/module.h>
+#include <linux/compat.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched/signal.h>
@@ -43,6 +45,7 @@
#include <linux/uaccess.h>
#include <asm/dma.h>
+#include <asm/unaligned.h>
#include <scsi/scsi.h>
#include <scsi/scsi_dbg.h>
@@ -169,7 +172,7 @@
/* Remove mode bits and auto-rewind bit (7) */
#define TAPE_NR(x) ( ((iminor(x) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
- (iminor(x) & ~(-1 << ST_MODE_SHIFT)) )
+ (iminor(x) & ((1 << ST_MODE_SHIFT)-1)))
#define TAPE_MODE(x) ((iminor(x) & ST_MODE_MASK) >> ST_MODE_SHIFT)
/* Construct the minor number from the device (d), mode (m), and non-rewind (n) data */
@@ -227,7 +230,6 @@
-#include "osst_detect.h"
#ifndef SIGS_FROM_OSST
#define SIGS_FROM_OSST \
{"OnStream", "SC-", "", "osst"}, \
@@ -337,12 +339,14 @@
switch (sense[0] & 0x7f) {
case 0x71:
s->deferred = 1;
+ fallthrough;
case 0x70:
s->fixed_format = 1;
s->flags = sense[2] & 0xe0;
break;
case 0x73:
s->deferred = 1;
+ fallthrough;
case 0x72:
s->fixed_format = 0;
ucp = scsi_sense_desc_find(sense, SCSI_SENSE_BUFFERSIZE, 4);
@@ -530,7 +534,7 @@
complete(SRpnt->waiting);
blk_rq_unmap_user(tmp);
- __blk_put_request(req->q, req);
+ blk_put_request(req);
}
static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
@@ -1453,7 +1457,6 @@
accessing this tape. */
static int st_release(struct inode *inode, struct file *filp)
{
- int result = 0;
struct scsi_tape *STp = filp->private_data;
if (STp->door_locked == ST_LOCKED_AUTO)
@@ -1466,9 +1469,9 @@
scsi_autopm_put_device(STp->device);
scsi_tape_put(STp);
- return result;
+ return 0;
}
-
+
/* The checks common to both reading and writing */
static ssize_t rw_checks(struct scsi_tape *STp, struct file *filp, size_t count)
{
@@ -2677,8 +2680,7 @@
if (!debugging)
return;
- sc = cmd[2] & 0x80 ? 0xff000000 : 0;
- sc |= (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
+ sc = sign_extend32(get_unaligned_be24(&cmd[2]), 23);
if (direction)
sc = -sc;
st_printk(ST_DEB_MSG, STp, "Spacing tape %s over %d %s.\n",
@@ -2721,6 +2723,7 @@
switch (cmd_in) {
case MTFSFM:
chg_eof = 0; /* Changed from the FSF after this */
+ fallthrough;
case MTFSF:
cmd[0] = SPACE;
cmd[1] = 0x01; /* Space FileMarks */
@@ -2735,6 +2738,7 @@
break;
case MTBSFM:
chg_eof = 0; /* Changed from the FSF after this */
+ fallthrough;
case MTBSF:
cmd[0] = SPACE;
cmd[1] = 0x01; /* Space FileMarks */
@@ -3496,7 +3500,7 @@
/* The ioctl command */
-static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
+static long st_ioctl_common(struct file *file, unsigned int cmd_in, void __user *p)
{
int i, cmd_nr, cmd_type, bt;
int retval = 0;
@@ -3504,7 +3508,6 @@
struct scsi_tape *STp = file->private_data;
struct st_modedef *STm;
struct st_partstat *STps;
- void __user *p = (void __user *)arg;
if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
@@ -3796,14 +3799,11 @@
if (STp->cleaning_req)
mt_status.mt_gstat |= GMT_CLN(0xffffffff);
- i = copy_to_user(p, &mt_status, sizeof(struct mtget));
- if (i) {
- retval = (-EFAULT);
+ retval = put_user_mtget(p, &mt_status);
+ if (retval)
goto out;
- }
STp->recover_reg = 0; /* Clear after read */
- retval = 0;
goto out;
} /* End of MTIOCGET */
if (cmd_type == _IOC_TYPE(MTIOCPOS) && cmd_nr == _IOC_NR(MTIOCPOS)) {
@@ -3817,16 +3817,24 @@
goto out;
}
mt_pos.mt_blkno = blk;
- i = copy_to_user(p, &mt_pos, sizeof(struct mtpos));
- if (i)
- retval = (-EFAULT);
+ retval = put_user_mtpos(p, &mt_pos);
goto out;
}
mutex_unlock(&STp->lock);
switch (cmd_in) {
+ case SCSI_IOCTL_STOP_UNIT:
+ /* unload */
+ retval = scsi_ioctl(STp->device, cmd_in, p);
+ if (!retval) {
+ STp->rew_at_close = 0;
+ STp->ready = ST_NO_TAPE;
+ }
+ return retval;
+
case SCSI_IOCTL_GET_IDLUN:
case SCSI_IOCTL_GET_BUS_NUMBER:
break;
+
default:
if ((cmd_in == SG_IO ||
cmd_in == SCSI_IOCTL_SEND_COMMAND ||
@@ -3840,30 +3848,46 @@
return i;
break;
}
- retval = scsi_ioctl(STp->device, cmd_in, p);
- if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
- STp->rew_at_close = 0;
- STp->ready = ST_NO_TAPE;
- }
- return retval;
+ return -ENOTTY;
out:
mutex_unlock(&STp->lock);
return retval;
}
-#ifdef CONFIG_COMPAT
-static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
{
+ void __user *p = (void __user *)arg;
struct scsi_tape *STp = file->private_data;
- struct scsi_device *sdev = STp->device;
- int ret = -ENOIOCTLCMD;
- if (sdev->host->hostt->compat_ioctl) {
+ int ret;
- ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
+ ret = st_ioctl_common(file, cmd_in, p);
+ if (ret != -ENOTTY)
+ return ret;
+ return scsi_ioctl(STp->device, cmd_in, p);
+}
+
+#ifdef CONFIG_COMPAT
+static long st_compat_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
+{
+ void __user *p = compat_ptr(arg);
+ struct scsi_tape *STp = file->private_data;
+ int ret;
+
+ /* argument conversion is handled using put_user_mtpos/put_user_mtget */
+ switch (cmd_in) {
+ case MTIOCPOS32:
+ return st_ioctl_common(file, MTIOCPOS, p);
+ case MTIOCGET32:
+ return st_ioctl_common(file, MTIOCGET, p);
}
- return ret;
+
+ ret = st_ioctl_common(file, cmd_in, p);
+ if (ret != -ENOTTY)
+ return ret;
+
+ return scsi_compat_ioctl(STp->device, cmd_in, p);
}
#endif
@@ -4262,9 +4286,10 @@
if (SDp->type != TYPE_TAPE)
return -ENODEV;
if ((stp = st_incompatible(SDp))) {
- sdev_printk(KERN_INFO, SDp, "Found incompatible tape\n");
sdev_printk(KERN_INFO, SDp,
- "st: The suggested driver is %s.\n", stp);
+ "OnStream tapes are no longer supported;\n");
+ sdev_printk(KERN_INFO, SDp,
+ "please mail to linux-scsi@vger.kernel.org.\n");
return -ENODEV;
}
@@ -4896,7 +4921,7 @@
unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
unsigned long start = uaddr >> PAGE_SHIFT;
const int nr_pages = end - start;
- int res, i, j;
+ int res, i;
struct page **pages;
struct rq_map_data *mdata = &STbp->map_data;
@@ -4918,7 +4943,8 @@
/* Try to fault in all of the necessary pages */
/* rw==READ means read from drive, write into memory area */
- res = get_user_pages_fast(uaddr, nr_pages, rw == READ, pages);
+ res = pin_user_pages_fast(uaddr, nr_pages, rw == READ ? FOLL_WRITE : 0,
+ pages);
/* Errors and no page mapped should return here */
if (res < nr_pages)
@@ -4937,8 +4963,7 @@
return nr_pages;
out_unmap:
if (res > 0) {
- for (j=0; j < res; j++)
- put_page(pages[j]);
+ unpin_user_pages(pages, res);
res = 0;
}
kfree(pages);
@@ -4950,18 +4975,9 @@
static int sgl_unmap_user_pages(struct st_buffer *STbp,
const unsigned int nr_pages, int dirtied)
{
- int i;
+ /* FIXME: cache flush missing for rw==READ */
+ unpin_user_pages_dirty_lock(STbp->mapped_pages, nr_pages, dirtied);
- for (i=0; i < nr_pages; i++) {
- struct page *page = STbp->mapped_pages[i];
-
- if (dirtied)
- SetPageDirty(page);
- /* FIXME: cache flush missing for rw==READ
- * FIXME: call the correct reference counting function
- */
- put_page(page);
- }
kfree(STbp->mapped_pages);
STbp->mapped_pages = NULL;
--
Gitblit v1.6.2