X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fscsi%2Fst.c;h=c2bb53e3d941faee5d29f5902ac757093102d772;hb=04489eeb02a40bc15029886cef7285ada3ab0de6;hp=6e5a5bb3131150012d24c3a8ac0fab668af289ef;hpb=53ffe3b440aa85af6fc4eda09b2d44bcdd312d4d;p=linux-2.6 diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 6e5a5bb313..c2bb53e3d9 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static const char *verstr = "20080224"; +static const char *verstr = "20080504"; #include @@ -38,6 +38,7 @@ static const char *verstr = "20080224"; #include #include #include +#include #include #include @@ -630,7 +631,7 @@ static int cross_eof(struct scsi_tape * STp, int forward) /* Flush the write buffer (never need to write if variable blocksize). */ static int st_flush_write_buffer(struct scsi_tape * STp) { - int offset, transfer, blks; + int transfer, blks; int result; unsigned char cmd[MAX_COMMAND_SIZE]; struct st_request *SRpnt; @@ -643,14 +644,10 @@ static int st_flush_write_buffer(struct scsi_tape * STp) result = 0; if (STp->dirty == 1) { - offset = (STp->buffer)->buffer_bytes; - transfer = ((offset + STp->block_size - 1) / - STp->block_size) * STp->block_size; + transfer = STp->buffer->buffer_bytes; DEBC(printk(ST_DEB_MSG "%s: Flushing %d bytes.\n", tape_name(STp), transfer)); - memset((STp->buffer)->b_data + offset, 0, transfer - offset); - memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = WRITE_6; cmd[1] = 1; @@ -1113,7 +1110,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) } - /* Open the device. Needs to be called with BKL only because of incrementing the SCSI host + /* Open the device. Needs to take the BKL only because of incrementing the SCSI host module count. */ static int st_open(struct inode *inode, struct file *filp) { @@ -1123,6 +1120,7 @@ static int st_open(struct inode *inode, struct file *filp) int dev = TAPE_NR(inode); char *name; + lock_kernel(); /* * We really want to do nonseekable_open(inode, filp); here, but some * versions of tar incorrectly call lseek on tapes and bail out if that @@ -1130,8 +1128,10 @@ static int st_open(struct inode *inode, struct file *filp) */ filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); - if (!(STp = scsi_tape_get(dev))) + if (!(STp = scsi_tape_get(dev))) { + unlock_kernel(); return -ENXIO; + } write_lock(&st_dev_arr_lock); filp->private_data = STp; @@ -1140,6 +1140,7 @@ static int st_open(struct inode *inode, struct file *filp) if (STp->in_use) { write_unlock(&st_dev_arr_lock); scsi_tape_put(STp); + unlock_kernel(); DEB( printk(ST_DEB_MSG "%s: Device already in use.\n", name); ) return (-EBUSY); } @@ -1188,12 +1189,14 @@ static int st_open(struct inode *inode, struct file *filp) retval = (-EIO); goto err_out; } + unlock_kernel(); return 0; err_out: normalize_buffer(STp->buffer); STp->in_use = 0; scsi_tape_put(STp); + unlock_kernel(); return retval; } @@ -1663,6 +1666,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) if (undone <= do_count) { /* Only data from this write is not written */ count += undone; + b_point -= undone; do_count -= undone; if (STp->block_size) blks = (transfer - undone) / STp->block_size;