summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2013-09-16 14:18:53 -0400
committerAnand Avati <avati@redhat.com>2013-09-17 11:22:01 -0700
commita5b74203589f1c06d86d50fb56940571bfc13e20 (patch)
tree3e61d536d2f44667b6d2ea0acc8da1a5c5d8ae25
parentac2317aee9013aa0235318f8a4c808b3598d03b9 (diff)
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 <bfoster@redhat.com> Reviewed-on: http://review.gluster.org/5946 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
-rwxr-xr-xtests/basic/file-snapshot.t1
-rw-r--r--xlators/features/qemu-block/src/qemu-block.c58
2 files changed, 59 insertions, 0 deletions
diff --git a/tests/basic/file-snapshot.t b/tests/basic/file-snapshot.t
index 93726f4b85d..36908192bac 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 c171f16f4f8..81afb95e169 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,
};