s390/tape: Move idal allocation to core functions
Currently tapechar_check_idalbuffer() is part of tape_char.c and is used to ensure the idal buffer is big enough for the requested I/O and reallocates a new one if required. The same is done in tape_std.c when a fixed block size is set using the mtsetblk command. This is essentially duplicate code. The allocation of the buffer that is required for I/O can be considered core functionality. Move the idal buffer allocation to tape_core.c, make it generally available, and reduce code duplication. Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com> Reviewed-by: Jens Remus <jremus@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
committed by
Heiko Carstens
parent
e039400f75
commit
a5e2ca22c1
@@ -234,6 +234,7 @@ struct tape_device {
|
||||
/* Externals from tape_core.c */
|
||||
extern struct tape_request *tape_alloc_request(int cplength, int datasize);
|
||||
extern void tape_free_request(struct tape_request *);
|
||||
extern int tape_check_idalbuffer(struct tape_device *device, size_t size);
|
||||
extern int tape_do_io(struct tape_device *, struct tape_request *);
|
||||
extern int tape_do_io_async(struct tape_device *, struct tape_request *);
|
||||
extern int tape_do_io_interruptible(struct tape_device *, struct tape_request *);
|
||||
|
||||
@@ -93,33 +93,6 @@ tapechar_cleanup_device(struct tape_device *device)
|
||||
device->nt = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
|
||||
{
|
||||
struct idal_buffer *new;
|
||||
|
||||
if (device->char_data.idal_buf != NULL &&
|
||||
device->char_data.idal_buf->size == block_size)
|
||||
return 0;
|
||||
|
||||
if (block_size > MAX_BLOCKSIZE) {
|
||||
DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n",
|
||||
block_size, MAX_BLOCKSIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The current idal buffer is not correct. Allocate a new one. */
|
||||
new = idal_buffer_alloc(block_size, 0);
|
||||
if (IS_ERR(new))
|
||||
return -ENOMEM;
|
||||
|
||||
if (device->char_data.idal_buf != NULL)
|
||||
idal_buffer_free(device->char_data.idal_buf);
|
||||
|
||||
device->char_data.idal_buf = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tape device read function
|
||||
@@ -156,7 +129,7 @@ tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
|
||||
block_size = count;
|
||||
}
|
||||
|
||||
rc = tapechar_check_idalbuffer(device, block_size);
|
||||
rc = tape_check_idalbuffer(device, block_size);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -208,7 +181,7 @@ tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t
|
||||
nblocks = 1;
|
||||
}
|
||||
|
||||
rc = tapechar_check_idalbuffer(device, block_size);
|
||||
rc = tape_check_idalbuffer(device, block_size);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
||||
@@ -726,6 +726,34 @@ tape_free_request (struct tape_request * request)
|
||||
kfree(request);
|
||||
}
|
||||
|
||||
int
|
||||
tape_check_idalbuffer(struct tape_device *device, size_t size)
|
||||
{
|
||||
struct idal_buffer *new;
|
||||
|
||||
if (device->char_data.idal_buf != NULL &&
|
||||
device->char_data.idal_buf->size == size)
|
||||
return 0;
|
||||
|
||||
if (size > MAX_BLOCKSIZE) {
|
||||
DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n",
|
||||
size, MAX_BLOCKSIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The current idal buffer is not correct. Allocate a new one. */
|
||||
new = idal_buffer_alloc(size, 0);
|
||||
if (IS_ERR(new))
|
||||
return -ENOMEM;
|
||||
|
||||
if (device->char_data.idal_buf != NULL)
|
||||
idal_buffer_free(device->char_data.idal_buf);
|
||||
|
||||
device->char_data.idal_buf = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__tape_start_io(struct tape_device *device, struct tape_request *request)
|
||||
{
|
||||
|
||||
@@ -212,7 +212,7 @@ tape_std_mtload(struct tape_device *device, int count)
|
||||
int
|
||||
tape_std_mtsetblk(struct tape_device *device, int count)
|
||||
{
|
||||
struct idal_buffer *new;
|
||||
int rc;
|
||||
|
||||
DBF_LH(6, "tape_std_mtsetblk(%d)\n", count);
|
||||
if (count <= 0) {
|
||||
@@ -224,26 +224,12 @@ tape_std_mtsetblk(struct tape_device *device, int count)
|
||||
device->char_data.block_size = 0;
|
||||
return 0;
|
||||
}
|
||||
if (device->char_data.idal_buf != NULL &&
|
||||
device->char_data.idal_buf->size == count)
|
||||
/* We already have a idal buffer of that size. */
|
||||
return 0;
|
||||
|
||||
if (count > MAX_BLOCKSIZE) {
|
||||
DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
|
||||
count, MAX_BLOCKSIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = tape_check_idalbuffer(device, count);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Allocate a new idal buffer. */
|
||||
new = idal_buffer_alloc(count, 0);
|
||||
if (IS_ERR(new))
|
||||
return -ENOMEM;
|
||||
if (device->char_data.idal_buf != NULL)
|
||||
idal_buffer_free(device->char_data.idal_buf);
|
||||
device->char_data.idal_buf = new;
|
||||
device->char_data.block_size = count;
|
||||
|
||||
DBF_LH(6, "new blocksize is %d\n", device->char_data.block_size);
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user