Implement FLUSH command and honour FUA flag
I changed the request struct to break the 32 bits reserved for the request type into two. The first part of this is used for the flags (such as FUA), and the second part for the command type. Previously we'd masked the top two bytes, thus ignoring any flags.
This commit is contained in:
@@ -308,7 +308,7 @@ void client_write_init( struct client * client, uint64_t size )
|
||||
init.magic = INIT_MAGIC;
|
||||
init.size = size;
|
||||
// TODO actually implement these flags!
|
||||
init.flags = NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA;
|
||||
init.flags = FLAG_HAS_FLAGS | FLAG_SEND_FLUSH | FLAG_SEND_FUA;
|
||||
// memset( init.reserved, 0, 124 );
|
||||
|
||||
nbd_h2r_init( &init, &init_raw );
|
||||
@@ -385,8 +385,8 @@ int client_request_needs_reply( struct client * client,
|
||||
}
|
||||
|
||||
debug(
|
||||
"request type=%"PRIu32", from=%"PRIu64", len=%"PRIu32", handle=0x%08X",
|
||||
request.type, request.from, request.len, request.handle
|
||||
"request type=%"PRIu16", flags=%"PRIu16", from=%"PRIu64", len=%"PRIu32", handle=0x%08X",
|
||||
request.type, request.flags, request.from, request.len, request.handle
|
||||
);
|
||||
|
||||
/* check it's not out of range */
|
||||
@@ -413,7 +413,8 @@ int client_request_needs_reply( struct client * client,
|
||||
debug("request disconnect");
|
||||
client->disconnect = 1;
|
||||
return 0;
|
||||
|
||||
case REQUEST_FLUSH:
|
||||
break;
|
||||
default:
|
||||
fatal("Unknown request 0x%08X", request.type);
|
||||
}
|
||||
@@ -474,7 +475,8 @@ void client_reply_to_write( struct client* client, struct nbd_request request )
|
||||
bitset_set_range(client->serve->allocation_map, request.from, request.len);
|
||||
}
|
||||
|
||||
if (1) /* not sure whether this is necessary... */
|
||||
// Only flush if FUA is set
|
||||
if (request.flags & CMD_FLAG_FUA)
|
||||
{
|
||||
/* multiple of 4K page size */
|
||||
uint64_t from_rounded = request.from & (!0xfff);
|
||||
@@ -490,6 +492,17 @@ void client_reply_to_write( struct client* client, struct nbd_request request )
|
||||
client_write_reply( client, &request, 0);
|
||||
}
|
||||
|
||||
void client_reply_to_flush( struct client* client, struct nbd_request request )
|
||||
{
|
||||
debug("request flush from=%"PRIu64", len=%"PRIu32", handle=0x%08X", request.from, request.len, request.handle);
|
||||
|
||||
ERROR_IF_NEGATIVE(
|
||||
fsync(client->fileno),
|
||||
"flush failed"
|
||||
);
|
||||
|
||||
client_write_reply( client, &request, 0);
|
||||
}
|
||||
|
||||
void client_reply( struct client* client, struct nbd_request request )
|
||||
{
|
||||
@@ -500,6 +513,9 @@ void client_reply( struct client* client, struct nbd_request request )
|
||||
case REQUEST_WRITE:
|
||||
client_reply_to_write( client, request );
|
||||
break;
|
||||
case REQUEST_FLUSH:
|
||||
client_reply_to_flush( client, request );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user