hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/scsi/sg.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * History:
34 * Started: Aug 9 by Lawrence Foard (entropy@world.std.com),
....@@ -8,12 +9,6 @@
89 * Copyright (C) 1992 Lawrence Foard
910 * Version 2 and 3 extensions to driver:
1011 * Copyright (C) 1998 - 2014 Douglas Gilbert
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation; either version 2, or (at your option)
15
- * any later version.
16
- *
1712 */
1813
1914 static int sg_version_num = 30536; /* 2 digits for each component */
....@@ -195,7 +190,7 @@
195190 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
196191 static Sg_fd *sg_add_sfp(Sg_device * sdp);
197192 static void sg_remove_sfp(struct kref *);
198
-static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id);
193
+static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy);
199194 static Sg_request *sg_add_request(Sg_fd * sfp);
200195 static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
201196 static Sg_device *sg_get_dev(int dev);
....@@ -410,6 +405,38 @@
410405 return 0;
411406 }
412407
408
+static int get_sg_io_pack_id(int *pack_id, void __user *buf, size_t count)
409
+{
410
+ struct sg_header __user *old_hdr = buf;
411
+ int reply_len;
412
+
413
+ if (count >= SZ_SG_HEADER) {
414
+ /* negative reply_len means v3 format, otherwise v1/v2 */
415
+ if (get_user(reply_len, &old_hdr->reply_len))
416
+ return -EFAULT;
417
+
418
+ if (reply_len >= 0)
419
+ return get_user(*pack_id, &old_hdr->pack_id);
420
+
421
+ if (in_compat_syscall() &&
422
+ count >= sizeof(struct compat_sg_io_hdr)) {
423
+ struct compat_sg_io_hdr __user *hp = buf;
424
+
425
+ return get_user(*pack_id, &hp->pack_id);
426
+ }
427
+
428
+ if (count >= sizeof(struct sg_io_hdr)) {
429
+ struct sg_io_hdr __user *hp = buf;
430
+
431
+ return get_user(*pack_id, &hp->pack_id);
432
+ }
433
+ }
434
+
435
+ /* no valid header was passed, so ignore the pack_id */
436
+ *pack_id = -1;
437
+ return 0;
438
+}
439
+
413440 static ssize_t
414441 sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
415442 {
....@@ -417,9 +444,10 @@
417444 Sg_fd *sfp;
418445 Sg_request *srp;
419446 int req_pack_id = -1;
447
+ bool busy;
420448 sg_io_hdr_t *hp;
421
- struct sg_header *old_hdr = NULL;
422
- int retval = 0;
449
+ struct sg_header *old_hdr;
450
+ int retval;
423451
424452 /*
425453 * This could cause a response to be stranded. Close the associated
....@@ -434,72 +462,30 @@
434462 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
435463 "sg_read: count=%d\n", (int) count));
436464
437
- if (!access_ok(VERIFY_WRITE, buf, count))
438
- return -EFAULT;
439
- if (sfp->force_packid && (count >= SZ_SG_HEADER)) {
440
- old_hdr = kmalloc(SZ_SG_HEADER, GFP_KERNEL);
441
- if (!old_hdr)
442
- return -ENOMEM;
443
- if (__copy_from_user(old_hdr, buf, SZ_SG_HEADER)) {
444
- retval = -EFAULT;
445
- goto free_old_hdr;
446
- }
447
- if (old_hdr->reply_len < 0) {
448
- if (count >= SZ_SG_IO_HDR) {
449
- sg_io_hdr_t *new_hdr;
450
- new_hdr = kmalloc(SZ_SG_IO_HDR, GFP_KERNEL);
451
- if (!new_hdr) {
452
- retval = -ENOMEM;
453
- goto free_old_hdr;
454
- }
455
- retval =__copy_from_user
456
- (new_hdr, buf, SZ_SG_IO_HDR);
457
- req_pack_id = new_hdr->pack_id;
458
- kfree(new_hdr);
459
- if (retval) {
460
- retval = -EFAULT;
461
- goto free_old_hdr;
462
- }
463
- }
464
- } else
465
- req_pack_id = old_hdr->pack_id;
466
- }
467
- srp = sg_get_rq_mark(sfp, req_pack_id);
465
+ if (sfp->force_packid)
466
+ retval = get_sg_io_pack_id(&req_pack_id, buf, count);
467
+ if (retval)
468
+ return retval;
469
+
470
+ srp = sg_get_rq_mark(sfp, req_pack_id, &busy);
468471 if (!srp) { /* now wait on packet to arrive */
469
- if (atomic_read(&sdp->detaching)) {
470
- retval = -ENODEV;
471
- goto free_old_hdr;
472
- }
473
- if (filp->f_flags & O_NONBLOCK) {
474
- retval = -EAGAIN;
475
- goto free_old_hdr;
476
- }
472
+ if (filp->f_flags & O_NONBLOCK)
473
+ return -EAGAIN;
477474 retval = wait_event_interruptible(sfp->read_wait,
478
- (atomic_read(&sdp->detaching) ||
479
- (srp = sg_get_rq_mark(sfp, req_pack_id))));
480
- if (atomic_read(&sdp->detaching)) {
481
- retval = -ENODEV;
482
- goto free_old_hdr;
483
- }
484
- if (retval) {
485
- /* -ERESTARTSYS as signal hit process */
486
- goto free_old_hdr;
487
- }
475
+ ((srp = sg_get_rq_mark(sfp, req_pack_id, &busy)) ||
476
+ (!busy && atomic_read(&sdp->detaching))));
477
+ if (!srp)
478
+ /* signal or detaching */
479
+ return retval ? retval : -ENODEV;
488480 }
489
- if (srp->header.interface_id != '\0') {
490
- retval = sg_new_read(sfp, buf, count, srp);
491
- goto free_old_hdr;
492
- }
481
+ if (srp->header.interface_id != '\0')
482
+ return sg_new_read(sfp, buf, count, srp);
493483
494484 hp = &srp->header;
495
- if (old_hdr == NULL) {
496
- old_hdr = kmalloc(SZ_SG_HEADER, GFP_KERNEL);
497
- if (! old_hdr) {
498
- retval = -ENOMEM;
499
- goto free_old_hdr;
500
- }
501
- }
502
- memset(old_hdr, 0, SZ_SG_HEADER);
485
+ old_hdr = kzalloc(SZ_SG_HEADER, GFP_KERNEL);
486
+ if (!old_hdr)
487
+ return -ENOMEM;
488
+
503489 old_hdr->reply_len = (int) hp->timeout;
504490 old_hdr->pack_len = old_hdr->reply_len; /* old, strange behaviour */
505491 old_hdr->pack_id = hp->pack_id;
....@@ -543,7 +529,7 @@
543529
544530 /* Now copy the result back to the user buffer. */
545531 if (count >= SZ_SG_HEADER) {
546
- if (__copy_to_user(buf, old_hdr, SZ_SG_HEADER)) {
532
+ if (copy_to_user(buf, old_hdr, SZ_SG_HEADER)) {
547533 retval = -EFAULT;
548534 goto free_old_hdr;
549535 }
....@@ -573,7 +559,12 @@
573559 int err = 0, err2;
574560 int len;
575561
576
- if (count < SZ_SG_IO_HDR) {
562
+ if (in_compat_syscall()) {
563
+ if (count < sizeof(struct compat_sg_io_hdr)) {
564
+ err = -EINVAL;
565
+ goto err_out;
566
+ }
567
+ } else if (count < SZ_SG_IO_HDR) {
577568 err = -EINVAL;
578569 goto err_out;
579570 }
....@@ -594,10 +585,7 @@
594585 }
595586 if (hp->masked_status || hp->host_status || hp->driver_status)
596587 hp->info |= SG_INFO_CHECK;
597
- if (copy_to_user(buf, hp, SZ_SG_IO_HDR)) {
598
- err = -EFAULT;
599
- goto err_out;
600
- }
588
+ err = put_sg_io_hdr(hp, buf);
601589 err_out:
602590 err2 = sg_finish_rem_req(srp);
603591 sg_remove_request(sfp, srp);
....@@ -632,11 +620,9 @@
632620 scsi_block_when_processing_errors(sdp->device)))
633621 return -ENXIO;
634622
635
- if (!access_ok(VERIFY_READ, buf, count))
636
- return -EFAULT; /* protects following copy_from_user()s + get_user()s */
637623 if (count < SZ_SG_HEADER)
638624 return -EIO;
639
- if (__copy_from_user(&old_hdr, buf, SZ_SG_HEADER))
625
+ if (copy_from_user(&old_hdr, buf, SZ_SG_HEADER))
640626 return -EFAULT;
641627 blocking = !(filp->f_flags & O_NONBLOCK);
642628 if (old_hdr.reply_len < 0)
....@@ -645,13 +631,15 @@
645631 if (count < (SZ_SG_HEADER + 6))
646632 return -EIO; /* The minimum scsi command length is 6 bytes. */
647633
634
+ buf += SZ_SG_HEADER;
635
+ if (get_user(opcode, buf))
636
+ return -EFAULT;
637
+
648638 if (!(srp = sg_add_request(sfp))) {
649639 SCSI_LOG_TIMEOUT(1, sg_printk(KERN_INFO, sdp,
650640 "sg_write: queue full\n"));
651641 return -EDOM;
652642 }
653
- buf += SZ_SG_HEADER;
654
- __get_user(opcode, buf);
655643 mutex_lock(&sfp->f_mutex);
656644 if (sfp->next_cmd_len > 0) {
657645 cmd_size = sfp->next_cmd_len;
....@@ -694,7 +682,7 @@
694682 hp->flags = input_size; /* structure abuse ... */
695683 hp->pack_id = old_hdr.pack_id;
696684 hp->usr_ptr = NULL;
697
- if (__copy_from_user(cmnd, buf, cmd_size)) {
685
+ if (copy_from_user(cmnd, buf, cmd_size)) {
698686 sg_remove_request(sfp, srp);
699687 return -EFAULT;
700688 }
....@@ -731,8 +719,6 @@
731719
732720 if (count < SZ_SG_IO_HDR)
733721 return -EINVAL;
734
- if (!access_ok(VERIFY_READ, buf, count))
735
- return -EFAULT; /* protects following copy_from_user()s + get_user()s */
736722
737723 sfp->cmd_q = 1; /* when sg_io_hdr seen, set command queuing on */
738724 if (!(srp = sg_add_request(sfp))) {
....@@ -742,7 +728,7 @@
742728 }
743729 srp->sg_io_owned = sg_io_owned;
744730 hp = &srp->header;
745
- if (__copy_from_user(hp, buf, SZ_SG_IO_HDR)) {
731
+ if (get_sg_io_hdr(hp, buf)) {
746732 sg_remove_request(sfp, srp);
747733 return -EFAULT;
748734 }
....@@ -770,11 +756,7 @@
770756 sg_remove_request(sfp, srp);
771757 return -EMSGSIZE;
772758 }
773
- if (!access_ok(VERIFY_READ, hp->cmdp, hp->cmd_len)) {
774
- sg_remove_request(sfp, srp);
775
- return -EFAULT; /* protects following copy_from_user()s + get_user()s */
776
- }
777
- if (__copy_from_user(cmnd, hp->cmdp, hp->cmd_len)) {
759
+ if (copy_from_user(cmnd, hp->cmdp, hp->cmd_len)) {
778760 sg_remove_request(sfp, srp);
779761 return -EFAULT;
780762 }
....@@ -826,7 +808,7 @@
826808 if (atomic_read(&sdp->detaching)) {
827809 if (srp->bio) {
828810 scsi_req_free_cmd(scsi_req(srp->rq));
829
- blk_end_request_all(srp->rq, BLK_STS_IOERR);
811
+ blk_put_request(srp->rq);
830812 srp->rq = NULL;
831813 }
832814
....@@ -842,11 +824,7 @@
842824 else
843825 at_head = 1;
844826
845
- if (likely(!sdp->device->timeout_override))
846
- srp->rq->timeout = timeout;
847
- else
848
- srp->rq->timeout = sdp->device->timeout_override;
849
-
827
+ srp->rq->timeout = timeout;
850828 kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
851829 blk_execute_rq_nowait(sdp->device->request_queue, sdp->disk,
852830 srp->rq, at_head, sg_rq_end_io);
....@@ -906,19 +884,41 @@
906884 }
907885 }
908886
909
-static long
910
-sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
887
+#ifdef CONFIG_COMPAT
888
+struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
889
+ char req_state;
890
+ char orphan;
891
+ char sg_io_owned;
892
+ char problem;
893
+ int pack_id;
894
+ compat_uptr_t usr_ptr;
895
+ unsigned int duration;
896
+ int unused;
897
+};
898
+
899
+static int put_compat_request_table(struct compat_sg_req_info __user *o,
900
+ struct sg_req_info *rinfo)
911901 {
912
- void __user *p = (void __user *)arg;
902
+ int i;
903
+ for (i = 0; i < SG_MAX_QUEUE; i++) {
904
+ if (copy_to_user(o + i, rinfo + i, offsetof(sg_req_info_t, usr_ptr)) ||
905
+ put_user((uintptr_t)rinfo[i].usr_ptr, &o[i].usr_ptr) ||
906
+ put_user(rinfo[i].duration, &o[i].duration) ||
907
+ put_user(rinfo[i].unused, &o[i].unused))
908
+ return -EFAULT;
909
+ }
910
+ return 0;
911
+}
912
+#endif
913
+
914
+static long
915
+sg_ioctl_common(struct file *filp, Sg_device *sdp, Sg_fd *sfp,
916
+ unsigned int cmd_in, void __user *p)
917
+{
913918 int __user *ip = p;
914919 int result, val, read_only;
915
- Sg_device *sdp;
916
- Sg_fd *sfp;
917920 Sg_request *srp;
918921 unsigned long iflags;
919
-
920
- if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
921
- return -ENXIO;
922922
923923 SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
924924 "sg_ioctl: cmd=0x%x\n", (int) cmd_in));
....@@ -930,16 +930,12 @@
930930 return -ENODEV;
931931 if (!scsi_block_when_processing_errors(sdp->device))
932932 return -ENXIO;
933
- if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
934
- return -EFAULT;
935933 result = sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
936934 1, read_only, 1, &srp);
937935 if (result < 0)
938936 return result;
939937 result = wait_event_interruptible(sfp->read_wait,
940
- (srp_done(sfp, srp) || atomic_read(&sdp->detaching)));
941
- if (atomic_read(&sdp->detaching))
942
- return -ENODEV;
938
+ srp_done(sfp, srp));
943939 write_lock_irq(&sfp->rq_list_lock);
944940 if (srp->done) {
945941 srp->done = 2;
....@@ -976,26 +972,21 @@
976972 case SG_GET_LOW_DMA:
977973 return put_user((int) sdp->device->host->unchecked_isa_dma, ip);
978974 case SG_GET_SCSI_ID:
979
- if (!access_ok(VERIFY_WRITE, p, sizeof (sg_scsi_id_t)))
980
- return -EFAULT;
981
- else {
982
- sg_scsi_id_t __user *sg_idp = p;
975
+ {
976
+ sg_scsi_id_t v;
983977
984978 if (atomic_read(&sdp->detaching))
985979 return -ENODEV;
986
- __put_user((int) sdp->device->host->host_no,
987
- &sg_idp->host_no);
988
- __put_user((int) sdp->device->channel,
989
- &sg_idp->channel);
990
- __put_user((int) sdp->device->id, &sg_idp->scsi_id);
991
- __put_user((int) sdp->device->lun, &sg_idp->lun);
992
- __put_user((int) sdp->device->type, &sg_idp->scsi_type);
993
- __put_user((short) sdp->device->host->cmd_per_lun,
994
- &sg_idp->h_cmd_per_lun);
995
- __put_user((short) sdp->device->queue_depth,
996
- &sg_idp->d_queue_depth);
997
- __put_user(0, &sg_idp->unused[0]);
998
- __put_user(0, &sg_idp->unused[1]);
980
+ memset(&v, 0, sizeof(v));
981
+ v.host_no = sdp->device->host->host_no;
982
+ v.channel = sdp->device->channel;
983
+ v.scsi_id = sdp->device->id;
984
+ v.lun = sdp->device->lun;
985
+ v.scsi_type = sdp->device->type;
986
+ v.h_cmd_per_lun = sdp->device->host->cmd_per_lun;
987
+ v.d_queue_depth = sdp->device->queue_depth;
988
+ if (copy_to_user(p, &v, sizeof(sg_scsi_id_t)))
989
+ return -EFAULT;
999990 return 0;
1000991 }
1001992 case SG_SET_FORCE_PACK_ID:
....@@ -1005,20 +996,16 @@
1005996 sfp->force_packid = val ? 1 : 0;
1006997 return 0;
1007998 case SG_GET_PACK_ID:
1008
- if (!access_ok(VERIFY_WRITE, ip, sizeof (int)))
1009
- return -EFAULT;
1010999 read_lock_irqsave(&sfp->rq_list_lock, iflags);
10111000 list_for_each_entry(srp, &sfp->rq_list, entry) {
10121001 if ((1 == srp->done) && (!srp->sg_io_owned)) {
10131002 read_unlock_irqrestore(&sfp->rq_list_lock,
10141003 iflags);
1015
- __put_user(srp->header.pack_id, ip);
1016
- return 0;
1004
+ return put_user(srp->header.pack_id, ip);
10171005 }
10181006 }
10191007 read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
1020
- __put_user(-1, ip);
1021
- return 0;
1008
+ return put_user(-1, ip);
10221009 case SG_GET_NUM_WAITING:
10231010 read_lock_irqsave(&sfp->rq_list_lock, iflags);
10241011 val = 0;
....@@ -1086,9 +1073,7 @@
10861073 val = (sdp->device ? 1 : 0);
10871074 return put_user(val, ip);
10881075 case SG_GET_REQUEST_TABLE:
1089
- if (!access_ok(VERIFY_WRITE, p, SZ_SG_REQ_INFO * SG_MAX_QUEUE))
1090
- return -EFAULT;
1091
- else {
1076
+ {
10921077 sg_req_info_t *rinfo;
10931078
10941079 rinfo = kcalloc(SG_MAX_QUEUE, SZ_SG_REQ_INFO,
....@@ -1098,8 +1083,13 @@
10981083 read_lock_irqsave(&sfp->rq_list_lock, iflags);
10991084 sg_fill_request_table(sfp, rinfo);
11001085 read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
1101
- result = __copy_to_user(p, rinfo,
1102
- SZ_SG_REQ_INFO * SG_MAX_QUEUE);
1086
+ #ifdef CONFIG_COMPAT
1087
+ if (in_compat_syscall())
1088
+ result = put_compat_request_table(p, rinfo);
1089
+ else
1090
+ #endif
1091
+ result = copy_to_user(p, rinfo,
1092
+ SZ_SG_REQ_INFO * SG_MAX_QUEUE);
11031093 result = result ? -EFAULT : 0;
11041094 kfree(rinfo);
11051095 return result;
....@@ -1150,29 +1140,44 @@
11501140 cmd_in, filp->f_flags & O_NDELAY);
11511141 if (result)
11521142 return result;
1143
+
1144
+ return -ENOIOCTLCMD;
1145
+}
1146
+
1147
+static long
1148
+sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
1149
+{
1150
+ void __user *p = (void __user *)arg;
1151
+ Sg_device *sdp;
1152
+ Sg_fd *sfp;
1153
+ int ret;
1154
+
1155
+ if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
1156
+ return -ENXIO;
1157
+
1158
+ ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p);
1159
+ if (ret != -ENOIOCTLCMD)
1160
+ return ret;
1161
+
11531162 return scsi_ioctl(sdp->device, cmd_in, p);
11541163 }
11551164
11561165 #ifdef CONFIG_COMPAT
11571166 static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
11581167 {
1168
+ void __user *p = compat_ptr(arg);
11591169 Sg_device *sdp;
11601170 Sg_fd *sfp;
1161
- struct scsi_device *sdev;
1171
+ int ret;
11621172
11631173 if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
11641174 return -ENXIO;
11651175
1166
- sdev = sdp->device;
1167
- if (sdev->host->hostt->compat_ioctl) {
1168
- int ret;
1169
-
1170
- ret = sdev->host->hostt->compat_ioctl(sdev, cmd_in, (void __user *)arg);
1171
-
1176
+ ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p);
1177
+ if (ret != -ENOIOCTLCMD)
11721178 return ret;
1173
- }
1174
-
1175
- return -ENOIOCTLCMD;
1179
+
1180
+ return scsi_compat_ioctl(sdp->device, cmd_in, p);
11761181 }
11771182 #endif
11781183
....@@ -1398,7 +1403,7 @@
13981403 */
13991404 srp->rq = NULL;
14001405 scsi_req_free_cmd(scsi_req(rq));
1401
- __blk_put_request(rq->q, rq);
1406
+ blk_put_request(rq);
14021407
14031408 write_lock_irqsave(&sfp->rq_list_lock, iflags);
14041409 if (unlikely(srp->orphan)) {
....@@ -1997,12 +2002,12 @@
19972002 num = 1 << (PAGE_SHIFT + schp->page_order);
19982003 for (k = 0; k < schp->k_use_sg && schp->pages[k]; k++) {
19992004 if (num > num_read_xfer) {
2000
- if (__copy_to_user(outp, page_address(schp->pages[k]),
2005
+ if (copy_to_user(outp, page_address(schp->pages[k]),
20012006 num_read_xfer))
20022007 return -EFAULT;
20032008 break;
20042009 } else {
2005
- if (__copy_to_user(outp, page_address(schp->pages[k]),
2010
+ if (copy_to_user(outp, page_address(schp->pages[k]),
20062011 num))
20072012 return -EFAULT;
20082013 num_read_xfer -= num;
....@@ -2083,19 +2088,28 @@
20832088 }
20842089
20852090 static Sg_request *
2086
-sg_get_rq_mark(Sg_fd * sfp, int pack_id)
2091
+sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy)
20872092 {
20882093 Sg_request *resp;
20892094 unsigned long iflags;
20902095
2096
+ *busy = false;
20912097 write_lock_irqsave(&sfp->rq_list_lock, iflags);
20922098 list_for_each_entry(resp, &sfp->rq_list, entry) {
2093
- /* look for requests that are ready + not SG_IO owned */
2094
- if ((1 == resp->done) && (!resp->sg_io_owned) &&
2099
+ /* look for requests that are not SG_IO owned */
2100
+ if ((!resp->sg_io_owned) &&
20952101 ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
2096
- resp->done = 2; /* guard against other readers */
2097
- write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
2098
- return resp;
2102
+ switch (resp->done) {
2103
+ case 0: /* request active */
2104
+ *busy = true;
2105
+ break;
2106
+ case 1: /* request done; response ready to return */
2107
+ resp->done = 2; /* guard against other readers */
2108
+ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
2109
+ return resp;
2110
+ case 2: /* response already being returned */
2111
+ break;
2112
+ }
20992113 }
21002114 }
21012115 write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
....@@ -2149,6 +2163,15 @@
21492163 res = 1;
21502164 }
21512165 write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
2166
+
2167
+ /*
2168
+ * If the device is detaching, wakeup any readers in case we just
2169
+ * removed the last response, which would leave nothing for them to
2170
+ * return other than -ENODEV.
2171
+ */
2172
+ if (unlikely(atomic_read(&sfp->parentdp->detaching)))
2173
+ wake_up_interruptible_all(&sfp->read_wait);
2174
+
21522175 return res;
21532176 }
21542177
....@@ -2309,25 +2332,23 @@
23092332 static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
23102333 static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
23112334 size_t count, loff_t *off);
2312
-static const struct file_operations adio_fops = {
2313
- .owner = THIS_MODULE,
2314
- .open = sg_proc_single_open_adio,
2315
- .read = seq_read,
2316
- .llseek = seq_lseek,
2317
- .write = sg_proc_write_adio,
2318
- .release = single_release,
2335
+static const struct proc_ops adio_proc_ops = {
2336
+ .proc_open = sg_proc_single_open_adio,
2337
+ .proc_read = seq_read,
2338
+ .proc_lseek = seq_lseek,
2339
+ .proc_write = sg_proc_write_adio,
2340
+ .proc_release = single_release,
23192341 };
23202342
23212343 static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
23222344 static ssize_t sg_proc_write_dressz(struct file *filp,
23232345 const char __user *buffer, size_t count, loff_t *off);
2324
-static const struct file_operations dressz_fops = {
2325
- .owner = THIS_MODULE,
2326
- .open = sg_proc_single_open_dressz,
2327
- .read = seq_read,
2328
- .llseek = seq_lseek,
2329
- .write = sg_proc_write_dressz,
2330
- .release = single_release,
2346
+static const struct proc_ops dressz_proc_ops = {
2347
+ .proc_open = sg_proc_single_open_dressz,
2348
+ .proc_read = seq_read,
2349
+ .proc_lseek = seq_lseek,
2350
+ .proc_write = sg_proc_write_dressz,
2351
+ .proc_release = single_release,
23312352 };
23322353
23332354 static int sg_proc_seq_show_version(struct seq_file *s, void *v);
....@@ -2368,9 +2389,9 @@
23682389 if (!p)
23692390 return 1;
23702391
2371
- proc_create("allow_dio", S_IRUGO | S_IWUSR, p, &adio_fops);
2392
+ proc_create("allow_dio", S_IRUGO | S_IWUSR, p, &adio_proc_ops);
23722393 proc_create_seq("debug", S_IRUGO, p, &debug_seq_ops);
2373
- proc_create("def_reserved_size", S_IRUGO | S_IWUSR, p, &dressz_fops);
2394
+ proc_create("def_reserved_size", S_IRUGO | S_IWUSR, p, &dressz_proc_ops);
23742395 proc_create_single("device_hdr", S_IRUGO, p, sg_proc_seq_show_devhdr);
23752396 proc_create_seq("devices", S_IRUGO, p, &dev_seq_ops);
23762397 proc_create_seq("device_strs", S_IRUGO, p, &devstrs_seq_ops);