Skip to content

Commit

Permalink
Handling of flag(ZVOL_OP_FLAG_READ_METADATA) for reading metadata for…
Browse files Browse the repository at this point in the history
… read command (openzfs#64)


Signed-off-by: mayank <[email protected]>
  • Loading branch information
mynktl authored and Jan Kryl committed Jun 26, 2018
1 parent 3029a67 commit e10f259
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 12 deletions.
14 changes: 11 additions & 3 deletions cmd/zrepl/data_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,22 @@ uzfs_zvol_worker(void *arg)
int rc = 0;
int write = 0;
boolean_t rebuild_cmd_req;
boolean_t read_metadata;

zio_cmd = (zvol_io_cmd_t *)arg;
hdr = &zio_cmd->hdr;
zinfo = zio_cmd->zv;
zvol_state = zinfo->zv;
rebuild_cmd_req = hdr->flags & ZVOL_OP_FLAG_REBUILD;
read_metadata = hdr->flags & ZVOL_OP_FLAG_READ_METADATA;

/*
* If zvol hasn't passed rebuild phase or if read
* is meant for rebuild then we need the metadata
* is meant for rebuild or if target has asked for metadata
* then we need the metadata
*/
if (!rebuild_cmd_req && ZVOL_IS_REBUILDED(zvol_state)) {
if ((!rebuild_cmd_req && ZVOL_IS_REBUILDED(zvol_state)) &&
!read_metadata) {
metadata_desc = NULL;
zio_cmd->metadata_desc = NULL;
} else {
Expand Down Expand Up @@ -361,7 +365,11 @@ uzfs_zvol_rebuild_dw_replica(void *arg)
hdr.opcode = ZVOL_OPCODE_REBUILD_STEP;
hdr.checkpointed_io_seq = checkpointed_ionum;
hdr.offset = offset;
hdr.len = ZVOL_REBUILD_STEP_SIZE;
if ((offset + ZVOL_REBUILD_STEP_SIZE) >
ZVOL_VOLUME_SIZE(zvol_state))
hdr.len = ZVOL_VOLUME_SIZE(zvol_state) - offset;
else
hdr.len = ZVOL_REBUILD_STEP_SIZE;
rc = uzfs_zvol_socket_write(sfd, (char *)&hdr, sizeof (hdr));
if (rc != 0) {
LOG_ERRNO("Socket write failed");
Expand Down
4 changes: 2 additions & 2 deletions cmd/zrepl/zrepl.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,8 @@ uzfs_zvol_rebuild_scanner(void *arg)
uzfs_zvol_rebuild_scanner_callback,
rebuild_req_offset, rebuild_req_len, &warg);
if (rc != 0) {
LOG_ERR("Rebuild scanning failed on zvol %s",
zinfo->name);
LOG_ERR("Rebuild scanning failed on zvol %s "
"err(%d)", zinfo->name, rc);
}
bzero(&hdr, sizeof (hdr));
hdr.status = ZVOL_OP_STATUS_OK;
Expand Down
3 changes: 2 additions & 1 deletion include/zrepl_prot.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ extern "C" {
#define MAX_IP_LEN 64
#define TARGET_PORT 6060

#define ZVOL_OP_FLAG_REBUILD 0x01
#define ZVOL_OP_FLAG_REBUILD 0x01
#define ZVOL_OP_FLAG_READ_METADATA 0x02

enum zvol_op_code {
// Used to obtain info about a zvol on mgmt connection
Expand Down
1 change: 1 addition & 0 deletions tests/cbtest/gtest/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/test_uzfs
/test_zrepl_prot
/test_zfs
55 changes: 49 additions & 6 deletions tests/cbtest/gtest/test_zrepl_prot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static void write_data(int data_fd, int &ioseq, void *buf, size_t offset,
* left to the caller.
*/
static void read_data_start(int data_fd, int &ioseq, size_t offset, int len,
zvol_io_hdr_t *hdr_inp, bool rebuild_flag=false) {
zvol_io_hdr_t *hdr_inp, int flags = 0) {
zvol_io_hdr_t hdr_out;
int rc;

Expand All @@ -208,7 +208,7 @@ static void read_data_start(int data_fd, int &ioseq, size_t offset, int len,
hdr_out.io_seq = ++ioseq;
hdr_out.offset = offset;
hdr_out.len = len;
hdr_out.flags = (rebuild_flag) ? ZVOL_OP_FLAG_REBUILD : 0;
hdr_out.flags = flags;

rc = write(data_fd, &hdr_out, sizeof (hdr_out));
ASSERT_EQ(rc, sizeof (hdr_out));
Expand Down Expand Up @@ -974,8 +974,8 @@ TEST_F(ZreplDataTest, WriteInvalidLength) {
}

/*
* Metadata ionum should be returned only when zvol is degraded (rebuild
* not finished) or when explicitly requested by ZVOL_OP_FLAG_REBUILD flag.
* Metadata ionum should be returned when zvol is degraded (rebuild
* not finished) or when requested by ZVOL_OP_FLAG_REBUILD flag.
*/
TEST_F(ZreplDataTest, RebuildFlag) {
zvol_io_hdr_t hdr_in, hdr_out;
Expand All @@ -1000,7 +1000,7 @@ TEST_F(ZreplDataTest, RebuildFlag) {
get_zvol_status(m_zvol_name1, m_ioseq1, m_control_fd1, ZVOL_STATUS_HEALTHY, ZVOL_REBUILDING_DONE);

/* read the block without rebuild flag */
read_data_start(m_data_fd1, m_ioseq1, 0, sizeof (buf), &hdr_in, false);
read_data_start(m_data_fd1, m_ioseq1, 0, sizeof (buf), &hdr_in, 0);
ASSERT_EQ(hdr_in.status, ZVOL_OP_STATUS_OK);
ASSERT_EQ(hdr_in.len, sizeof (read_hdr) + sizeof (buf));
rc = read(m_data_fd1, &read_hdr, sizeof (read_hdr));
Expand All @@ -1013,7 +1013,50 @@ TEST_F(ZreplDataTest, RebuildFlag) {
ASSERT_EQ(rc, sizeof (buf));

/* read the block with rebuild flag */
read_data_start(m_data_fd1, m_ioseq1, 0, sizeof (buf), &hdr_in, true);
read_data_start(m_data_fd1, m_ioseq1, 0, sizeof (buf), &hdr_in, ZVOL_OP_FLAG_REBUILD);
ASSERT_EQ(hdr_in.status, ZVOL_OP_STATUS_OK);
ASSERT_EQ(hdr_in.len, sizeof (read_hdr) + sizeof (buf));
rc = read(m_data_fd1, &read_hdr, sizeof (read_hdr));
ASSERT_ERRNO("read", rc >= 0);
ASSERT_EQ(rc, sizeof (read_hdr));
ASSERT_EQ(read_hdr.io_num, 654);
ASSERT_EQ(read_hdr.len, sizeof (buf));
rc = read(m_data_fd1, buf, sizeof (buf));
ASSERT_ERRNO("read", rc >= 0);
ASSERT_EQ(rc, sizeof (buf));
}

/*
* Metadata ionum should be returned when requested by
* ZVOL_OP_FLAG_READ_METADATA flag.
*/
TEST_F(ZreplDataTest, ReadMetaDataFlag) {
zvol_io_hdr_t hdr_in, hdr_out;
struct zvol_io_rw_hdr read_hdr;
struct zvol_io_rw_hdr write_hdr;
struct zrepl_status_ack status;
struct mgmt_ack mgmt_ack;
char buf[4096];
int rc;

/* write a data block with known ionum */
write_data_and_verify_resp(m_data_fd1, m_ioseq1, 0, 654);

/* read the block without ZVOL_OP_FLAG_READ_METADATA flag */
read_data_start(m_data_fd1, m_ioseq1, 0, sizeof (buf), &hdr_in, 0);
ASSERT_EQ(hdr_in.status, ZVOL_OP_STATUS_OK);
ASSERT_EQ(hdr_in.len, sizeof (read_hdr) + sizeof (buf));
rc = read(m_data_fd1, &read_hdr, sizeof (read_hdr));
ASSERT_ERRNO("read", rc >= 0);
ASSERT_EQ(rc, sizeof (read_hdr));
ASSERT_EQ(read_hdr.io_num, 0);
ASSERT_EQ(read_hdr.len, sizeof (buf));
rc = read(m_data_fd1, buf, sizeof (buf));
ASSERT_ERRNO("read", rc >= 0);
ASSERT_EQ(rc, sizeof (buf));

/* read the block with ZVOL_OP_FLAG_READ_METADATA flag */
read_data_start(m_data_fd1, m_ioseq1, 0, sizeof (buf), &hdr_in, ZVOL_OP_FLAG_READ_METADATA);
ASSERT_EQ(hdr_in.status, ZVOL_OP_STATUS_OK);
ASSERT_EQ(hdr_in.len, sizeof (read_hdr) + sizeof (buf));
rc = read(m_data_fd1, &read_hdr, sizeof (read_hdr));
Expand Down

0 comments on commit e10f259

Please sign in to comment.