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:
Jan Höppner
2025-10-16 09:47:16 +02:00
committed by Heiko Carstens
parent e039400f75
commit a5e2ca22c1
4 changed files with 35 additions and 47 deletions

View File

@@ -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 *);

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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;