@@ -106,7 +106,8 @@ static int sg_add(struct device *, struct class_interface *);
106
106
static void sg_remove (struct device * , struct class_interface * );
107
107
108
108
static DEFINE_IDR (sg_index_idr );
109
- static DEFINE_RWLOCK (sg_index_lock );
109
+ static DEFINE_RWLOCK (sg_index_lock ); /* Also used to lock
110
+ file descriptor list for device */
110
111
111
112
static struct class_interface sg_interface = {
112
113
.add_dev = sg_add ,
@@ -143,7 +144,8 @@ typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */
143
144
} Sg_request ;
144
145
145
146
typedef struct sg_fd { /* holds the state of a file descriptor */
146
- struct list_head sfd_siblings ; /* protected by sfd_lock of device */
147
+ /* sfd_siblings is protected by sg_index_lock */
148
+ struct list_head sfd_siblings ;
147
149
struct sg_device * parentdp ; /* owning device */
148
150
wait_queue_head_t read_wait ; /* queue read until command done */
149
151
rwlock_t rq_list_lock ; /* protect access to list in req_arr */
@@ -168,7 +170,7 @@ typedef struct sg_device { /* holds the state of each scsi generic device */
168
170
struct scsi_device * device ;
169
171
int sg_tablesize ; /* adapter's max scatter-gather table size */
170
172
u32 index ; /* device index number */
171
- spinlock_t sfd_lock ; /* protect file descriptor list for device */
173
+ /* sfds is protected by sg_index_lock */
172
174
struct list_head sfds ;
173
175
struct rw_semaphore o_sem ; /* exclude open should hold this rwsem */
174
176
volatile char detached ; /* 0->attached, 1->detached pending removal */
@@ -225,9 +227,9 @@ static int sfds_list_empty(Sg_device *sdp)
225
227
unsigned long flags ;
226
228
int ret ;
227
229
228
- spin_lock_irqsave ( & sdp -> sfd_lock , flags );
230
+ read_lock_irqsave ( & sg_index_lock , flags );
229
231
ret = list_empty (& sdp -> sfds );
230
- spin_unlock_irqrestore ( & sdp -> sfd_lock , flags );
232
+ read_unlock_irqrestore ( & sg_index_lock , flags );
231
233
return ret ;
232
234
}
233
235
@@ -1391,7 +1393,6 @@ static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
1391
1393
disk -> first_minor = k ;
1392
1394
sdp -> disk = disk ;
1393
1395
sdp -> device = scsidp ;
1394
- spin_lock_init (& sdp -> sfd_lock );
1395
1396
INIT_LIST_HEAD (& sdp -> sfds );
1396
1397
init_rwsem (& sdp -> o_sem );
1397
1398
sdp -> sg_tablesize = queue_max_segments (q );
@@ -1526,13 +1527,11 @@ static void sg_remove(struct device *cl_dev, struct class_interface *cl_intf)
1526
1527
1527
1528
/* Need a write lock to set sdp->detached. */
1528
1529
write_lock_irqsave (& sg_index_lock , iflags );
1529
- spin_lock (& sdp -> sfd_lock );
1530
1530
sdp -> detached = 1 ;
1531
1531
list_for_each_entry (sfp , & sdp -> sfds , sfd_siblings ) {
1532
1532
wake_up_interruptible (& sfp -> read_wait );
1533
1533
kill_fasync (& sfp -> async_qp , SIGPOLL , POLL_HUP );
1534
1534
}
1535
- spin_unlock (& sdp -> sfd_lock );
1536
1535
write_unlock_irqrestore (& sg_index_lock , iflags );
1537
1536
1538
1537
sysfs_remove_link (& scsidp -> sdev_gendev .kobj , "generic" );
@@ -2057,13 +2056,13 @@ sg_add_sfp(Sg_device * sdp, int dev)
2057
2056
sfp -> cmd_q = SG_DEF_COMMAND_Q ;
2058
2057
sfp -> keep_orphan = SG_DEF_KEEP_ORPHAN ;
2059
2058
sfp -> parentdp = sdp ;
2060
- spin_lock_irqsave ( & sdp -> sfd_lock , iflags );
2059
+ write_lock_irqsave ( & sg_index_lock , iflags );
2061
2060
if (sdp -> detached ) {
2062
- spin_unlock_irqrestore ( & sdp -> sfd_lock , iflags );
2061
+ write_unlock_irqrestore ( & sg_index_lock , iflags );
2063
2062
return ERR_PTR (- ENODEV );
2064
2063
}
2065
2064
list_add_tail (& sfp -> sfd_siblings , & sdp -> sfds );
2066
- spin_unlock_irqrestore ( & sdp -> sfd_lock , iflags );
2065
+ write_unlock_irqrestore ( & sg_index_lock , iflags );
2067
2066
SCSI_LOG_TIMEOUT (3 , printk ("sg_add_sfp: sfp=0x%p\n" , sfp ));
2068
2067
if (unlikely (sg_big_buff != def_reserved_size ))
2069
2068
sg_big_buff = def_reserved_size ;
@@ -2110,12 +2109,11 @@ static void sg_remove_sfp_usercontext(struct work_struct *work)
2110
2109
static void sg_remove_sfp (struct kref * kref )
2111
2110
{
2112
2111
struct sg_fd * sfp = container_of (kref , struct sg_fd , f_ref );
2113
- struct sg_device * sdp = sfp -> parentdp ;
2114
2112
unsigned long iflags ;
2115
2113
2116
- spin_lock_irqsave ( & sdp -> sfd_lock , iflags );
2114
+ write_lock_irqsave ( & sg_index_lock , iflags );
2117
2115
list_del (& sfp -> sfd_siblings );
2118
- spin_unlock_irqrestore ( & sdp -> sfd_lock , iflags );
2116
+ write_unlock_irqrestore ( & sg_index_lock , iflags );
2119
2117
2120
2118
INIT_WORK (& sfp -> ew .work , sg_remove_sfp_usercontext );
2121
2119
schedule_work (& sfp -> ew .work );
@@ -2502,7 +2500,7 @@ static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v)
2502
2500
return 0 ;
2503
2501
}
2504
2502
2505
- /* must be called while holding sg_index_lock and sfd_lock */
2503
+ /* must be called while holding sg_index_lock */
2506
2504
static void sg_proc_debug_helper (struct seq_file * s , Sg_device * sdp )
2507
2505
{
2508
2506
int k , m , new_interface , blen , usg ;
@@ -2587,26 +2585,22 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v)
2587
2585
2588
2586
read_lock_irqsave (& sg_index_lock , iflags );
2589
2587
sdp = it ? sg_lookup_dev (it -> index ) : NULL ;
2590
- if (sdp ) {
2591
- spin_lock (& sdp -> sfd_lock );
2592
- if (!list_empty (& sdp -> sfds )) {
2593
- struct scsi_device * scsidp = sdp -> device ;
2588
+ if (sdp && !list_empty (& sdp -> sfds )) {
2589
+ struct scsi_device * scsidp = sdp -> device ;
2594
2590
2595
- seq_printf (s , " >>> device=%s " , sdp -> disk -> disk_name );
2596
- if (sdp -> detached )
2597
- seq_printf (s , "detached pending close " );
2598
- else
2599
- seq_printf
2600
- (s , "scsi%d chan=%d id=%d lun=%d em=%d" ,
2601
- scsidp -> host -> host_no ,
2602
- scsidp -> channel , scsidp -> id ,
2603
- scsidp -> lun ,
2604
- scsidp -> host -> hostt -> emulated );
2605
- seq_printf (s , " sg_tablesize=%d excl=%d\n" ,
2606
- sdp -> sg_tablesize , sdp -> exclude );
2607
- sg_proc_debug_helper (s , sdp );
2608
- }
2609
- spin_unlock (& sdp -> sfd_lock );
2591
+ seq_printf (s , " >>> device=%s " , sdp -> disk -> disk_name );
2592
+ if (sdp -> detached )
2593
+ seq_printf (s , "detached pending close " );
2594
+ else
2595
+ seq_printf
2596
+ (s , "scsi%d chan=%d id=%d lun=%d em=%d" ,
2597
+ scsidp -> host -> host_no ,
2598
+ scsidp -> channel , scsidp -> id ,
2599
+ scsidp -> lun ,
2600
+ scsidp -> host -> hostt -> emulated );
2601
+ seq_printf (s , " sg_tablesize=%d excl=%d\n" ,
2602
+ sdp -> sg_tablesize , sdp -> exclude );
2603
+ sg_proc_debug_helper (s , sdp );
2610
2604
}
2611
2605
read_unlock_irqrestore (& sg_index_lock , iflags );
2612
2606
return 0 ;
0 commit comments