]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
s390/tape: Move idal allocation to core functions
authorJan Höppner <hoeppner@linux.ibm.com>
Thu, 16 Oct 2025 07:47:16 +0000 (09:47 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Tue, 21 Oct 2025 08:25:55 +0000 (10:25 +0200)
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>
drivers/s390/char/tape.h
drivers/s390/char/tape_char.c
drivers/s390/char/tape_core.c
drivers/s390/char/tape_std.c

index 0596a9758662bbb7480b6cbd334e6b834f08cc92..349fa95dcedb89e786173ae3674cd519f1a1f880 100644 (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 *);
index 3d557b55bda87d2ecb534d87d907f2ea96848661..e229585cfb9eda1b3d1b882156670d816b5e386c 100644 (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;
 
index 6ec812280221aa13394110249313a87d57209d6b..30ace31a3bba498d6f1aa0a20c2ac1aa4368392a 100644 (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)
 {
index e46ffc46f323668ed06957def5f2baab1963acec..29abbc23f9088681b979fa26df31d8c96623eed7 100644 (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;