@@ -142,6 +142,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
142
142
struct sg_device * parentdp ; /* owning device */
143
143
wait_queue_head_t read_wait ; /* queue read until command done */
144
144
rwlock_t rq_list_lock ; /* protect access to list in req_arr */
145
+ struct mutex f_mutex ; /* protect against changes in this fd */
145
146
int timeout ; /* defaults to SG_DEFAULT_TIMEOUT */
146
147
int timeout_user ; /* defaults to SG_DEFAULT_TIMEOUT_USER */
147
148
Sg_scatter_hold reserve ; /* buffer held for this file descriptor */
@@ -153,6 +154,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
153
154
unsigned char next_cmd_len ; /* 0: automatic, >0: use on next write() */
154
155
char keep_orphan ; /* 0 -> drop orphan (def), 1 -> keep for read() */
155
156
char mmap_called ; /* 0 -> mmap() never called on this fd */
157
+ char res_in_use ; /* 1 -> 'reserve' array in use */
156
158
struct kref f_ref ;
157
159
struct execute_work ew ;
158
160
} Sg_fd ;
@@ -196,7 +198,6 @@ static void sg_remove_sfp(struct kref *);
196
198
static Sg_request * sg_get_rq_mark (Sg_fd * sfp , int pack_id );
197
199
static Sg_request * sg_add_request (Sg_fd * sfp );
198
200
static int sg_remove_request (Sg_fd * sfp , Sg_request * srp );
199
- static int sg_res_in_use (Sg_fd * sfp );
200
201
static Sg_device * sg_get_dev (int dev );
201
202
static void sg_device_destroy (struct kref * kref );
202
203
@@ -612,6 +613,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
612
613
}
613
614
buf += SZ_SG_HEADER ;
614
615
__get_user (opcode , buf );
616
+ mutex_lock (& sfp -> f_mutex );
615
617
if (sfp -> next_cmd_len > 0 ) {
616
618
cmd_size = sfp -> next_cmd_len ;
617
619
sfp -> next_cmd_len = 0 ; /* reset so only this write() effected */
@@ -620,6 +622,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
620
622
if ((opcode >= 0xc0 ) && old_hdr .twelve_byte )
621
623
cmd_size = 12 ;
622
624
}
625
+ mutex_unlock (& sfp -> f_mutex );
623
626
SCSI_LOG_TIMEOUT (4 , sg_printk (KERN_INFO , sdp ,
624
627
"sg_write: scsi opcode=0x%02x, cmd_size=%d\n" , (int ) opcode , cmd_size ));
625
628
/* Determine buffer size. */
@@ -719,7 +722,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
719
722
sg_remove_request (sfp , srp );
720
723
return - EINVAL ; /* either MMAP_IO or DIRECT_IO (not both) */
721
724
}
722
- if (sg_res_in_use ( sfp ) ) {
725
+ if (sfp -> res_in_use ) {
723
726
sg_remove_request (sfp , srp );
724
727
return - EBUSY ; /* reserve buffer already being used */
725
728
}
@@ -953,12 +956,18 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
953
956
return - EINVAL ;
954
957
val = min_t (int , val ,
955
958
max_sectors_bytes (sdp -> device -> request_queue ));
959
+ mutex_lock (& sfp -> f_mutex );
956
960
if (val != sfp -> reserve .bufflen ) {
957
- if (sg_res_in_use (sfp ) || sfp -> mmap_called )
961
+ if (sfp -> mmap_called ||
962
+ sfp -> res_in_use ) {
963
+ mutex_unlock (& sfp -> f_mutex );
958
964
return - EBUSY ;
965
+ }
966
+
959
967
sg_remove_scat (sfp , & sfp -> reserve );
960
968
sg_build_reserve (sfp , val );
961
969
}
970
+ mutex_unlock (& sfp -> f_mutex );
962
971
return 0 ;
963
972
case SG_GET_RESERVED_SIZE :
964
973
val = min_t (int , sfp -> reserve .bufflen ,
@@ -1718,13 +1727,22 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
1718
1727
md = & map_data ;
1719
1728
1720
1729
if (md ) {
1721
- if (!sg_res_in_use (sfp ) && dxfer_len <= rsv_schp -> bufflen )
1730
+ mutex_lock (& sfp -> f_mutex );
1731
+ if (dxfer_len <= rsv_schp -> bufflen &&
1732
+ !sfp -> res_in_use ) {
1733
+ sfp -> res_in_use = 1 ;
1722
1734
sg_link_reserve (sfp , srp , dxfer_len );
1723
- else {
1735
+ } else if ((hp -> flags & SG_FLAG_MMAP_IO ) && sfp -> res_in_use ) {
1736
+ mutex_unlock (& sfp -> f_mutex );
1737
+ return - EBUSY ;
1738
+ } else {
1724
1739
res = sg_build_indirect (req_schp , sfp , dxfer_len );
1725
- if (res )
1740
+ if (res ) {
1741
+ mutex_unlock (& sfp -> f_mutex );
1726
1742
return res ;
1743
+ }
1727
1744
}
1745
+ mutex_unlock (& sfp -> f_mutex );
1728
1746
1729
1747
md -> pages = req_schp -> pages ;
1730
1748
md -> page_order = req_schp -> page_order ;
@@ -2125,6 +2143,7 @@ sg_add_sfp(Sg_device * sdp)
2125
2143
rwlock_init (& sfp -> rq_list_lock );
2126
2144
2127
2145
kref_init (& sfp -> f_ref );
2146
+ mutex_init (& sfp -> f_mutex );
2128
2147
sfp -> timeout = SG_DEFAULT_TIMEOUT ;
2129
2148
sfp -> timeout_user = SG_DEFAULT_TIMEOUT_USER ;
2130
2149
sfp -> force_packid = SG_DEF_FORCE_PACK_ID ;
@@ -2198,20 +2217,6 @@ sg_remove_sfp(struct kref *kref)
2198
2217
schedule_work (& sfp -> ew .work );
2199
2218
}
2200
2219
2201
- static int
2202
- sg_res_in_use (Sg_fd * sfp )
2203
- {
2204
- const Sg_request * srp ;
2205
- unsigned long iflags ;
2206
-
2207
- read_lock_irqsave (& sfp -> rq_list_lock , iflags );
2208
- for (srp = sfp -> headrp ; srp ; srp = srp -> nextrp )
2209
- if (srp -> res_used )
2210
- break ;
2211
- read_unlock_irqrestore (& sfp -> rq_list_lock , iflags );
2212
- return srp ? 1 : 0 ;
2213
- }
2214
-
2215
2220
#ifdef CONFIG_SCSI_PROC_FS
2216
2221
static int
2217
2222
sg_idr_max_id (int id , void * p , void * data )
0 commit comments