Use 1 R/W spinlock
parent
403c0a5df6
commit
ba21f509c2
38
sftl.c
38
sftl.c
|
@ -163,56 +163,62 @@ static void sftl_make_request(struct request_queue *q, struct bio *bio)
|
|||
}
|
||||
else
|
||||
{
|
||||
// R/W locking using 1 R/W spinlock and 1 event.
|
||||
//
|
||||
// Reading:
|
||||
// * Take read lock
|
||||
// * Check if requested cluster is mapped into buffer
|
||||
// * If yes:
|
||||
// ** Read from the buffer
|
||||
// * If no:
|
||||
// ** Initiate block read operation
|
||||
// * Unlock
|
||||
//
|
||||
// Writing:
|
||||
// (Start):
|
||||
// * Take write lock on buffer
|
||||
// * Take write lock
|
||||
// * Check for free space in buffer
|
||||
// * If sufficient:
|
||||
// ** Take write lock on translation maps so readers won't get them partially modified
|
||||
// ** Write current bio into buffer
|
||||
// ** Modify translation maps
|
||||
// ** Unlock translation maps
|
||||
// * If insufficient:
|
||||
// ** Check flush flag (no need for atomic/etc as already within buffer lock)
|
||||
// ** (Insufficient) Check flush flag (no need for atomic/etc as already within buffer lock)
|
||||
// ** If someone is already flushing:
|
||||
// *** Unlock buffer
|
||||
// *** Unlock
|
||||
// *** Wait until flushing ends using an event
|
||||
// *** Goto (Start)
|
||||
// ** If no one is flushing yet:
|
||||
// *** Set flush flag
|
||||
// *** Remember current bio and initiate (Flush) operation
|
||||
// * Unlock buffer
|
||||
// * Unlock
|
||||
//
|
||||
// After (Flush) operation ends:
|
||||
// * Take write lock on the buffer (writers are already blocked, this is to block readers)
|
||||
// * Take write lock (writers are already blocked, this is to block readers)
|
||||
// * Clear buffer
|
||||
// * If the free sequence pointer can be moved without cleaning:
|
||||
// ** Move pointer
|
||||
// ** Perform own remembered write operation
|
||||
// ** Unset flush flag
|
||||
// ** Unlock buffer
|
||||
// ** Unlock
|
||||
// ** Wake up waiting writers
|
||||
// * If not:
|
||||
// ** Initiate cleaning process
|
||||
// ** Unlock buffer
|
||||
// ** Unlock
|
||||
//
|
||||
// After cleaning operation ends:
|
||||
// * Take write lock on translation maps
|
||||
// * Take write lock
|
||||
// * Modify translation maps
|
||||
// * Unlock translation maps
|
||||
// * Take write lock on the buffer
|
||||
// * Move free sequence pointer
|
||||
// * If there are no more pending cleaning operations:
|
||||
// ** Perform own remembered write operation:
|
||||
// *** Take write lock on translation maps so readers won't get them partially modified
|
||||
// *** Write current bio into buffer
|
||||
// *** Modify translation maps
|
||||
// *** Unlock translation maps
|
||||
// ** Unset flush flag
|
||||
// ** Unlock buffer
|
||||
// ** Unlock
|
||||
// ** Wake up waiting writers
|
||||
// * Else:
|
||||
// ** Initiate next cleaning operation
|
||||
// ** Unlock buffer
|
||||
// ** Unlock
|
||||
struct sftl_map *buf_map = (struct sftl_map *)(sftl->buf + seg_clust*clust_sz) + sftl->buf_size;
|
||||
char *buffer = __bio_kmap_atomic(bio, 0, KM_USER0);
|
||||
memcpy(sftl->buf + clust_sz*sftl->buf_size, buffer, clust_sz);
|
||||
|
|
Loading…
Reference in New Issue