From a5b74203589f1c06d86d50fb56940571bfc13e20 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 16 Sep 2013 14:18:53 -0400 Subject: qemu-block: support readdirp Support the readdirp fop in qemu-block to ensure that image files are handled correctly when readdirp is enabled. E.g., without readdirp support, incorrect stat data for formatted files can be reported back (and cached) via the client. BUG: 986775 Change-Id: Ibc4bd0b42548953ebe30832f3d853bb68095f0ac Signed-off-by: Brian Foster Reviewed-on: http://review.gluster.org/5946 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- tests/basic/file-snapshot.t | 1 + xlators/features/qemu-block/src/qemu-block.c | 58 ++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tests/basic/file-snapshot.t b/tests/basic/file-snapshot.t index 93726f4b8..36908192b 100755 --- a/tests/basic/file-snapshot.t +++ b/tests/basic/file-snapshot.t @@ -27,6 +27,7 @@ TEST touch $M0/big-file; TEST setfattr -n trusted.glusterfs.block-format -v qcow2:10GB $M0/big-file; +TEST ls -al $M0 # test readdirplus TEST [ `stat -c '%s' $M0/big-file` = 10737418240 ] echo 'ABCDEFGHIJ' > $M0/data-file1 diff --git a/xlators/features/qemu-block/src/qemu-block.c b/xlators/features/qemu-block/src/qemu-block.c index c171f16f4..81afb95e1 100644 --- a/xlators/features/qemu-block/src/qemu-block.c +++ b/xlators/features/qemu-block/src/qemu-block.c @@ -651,6 +651,63 @@ enomem: return 0; } +static int32_t +qb_readdirp_cbk(call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, gf_dirent_t *entries, + dict_t *xdata) +{ + qb_conf_t *conf = this->private; + gf_dirent_t *entry; + char *format; + + list_for_each_entry(entry, &entries->list, list) { + if (!entry->inode || !entry->dict) + continue; + + format = NULL; + if (dict_get_str(entry->dict, conf->qb_xattr_key, &format)) + continue; + + if (!format) { + qb_inode_cleanup(this, entry->inode, 1); + continue; + } + + if (qb_format_extract(this, format, entry->inode)) + continue; + + qb_iatt_fixup(this, entry->inode, &entry->d_stat); + } + + STACK_UNWIND_STRICT(readdirp, frame, op_ret, op_errno, entries, xdata); + return 0; +} + +static int32_t +qb_readdirp(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, + off_t off, dict_t *xdata) +{ + qb_conf_t *conf = this->private; + + xdata = xdata ? dict_ref(xdata) : dict_new(); + if (!xdata) + goto enomem; + + if (dict_set_int32 (xdata, conf->qb_xattr_key, 0)) + goto enomem; + + STACK_WIND(frame, qb_readdirp_cbk, FIRST_CHILD(this), + FIRST_CHILD(this)->fops->readdirp, fd, size, off, xdata); + + dict_unref(xdata); + return 0; + +enomem: + QB_STACK_UNWIND(readdirp, frame, -1, ENOMEM, NULL, NULL); + if (xdata) + dict_unref(xdata); + return 0; +} int qb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset, @@ -1005,6 +1062,7 @@ struct xlator_fops fops = { .getxattr = qb_getxattr, .fgetxattr = qb_fgetxattr */ + .readdirp = qb_readdirp, }; -- cgit