summaryrefslogtreecommitdiffstats
path: root/xlators/performance/quick-read
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@zresearch.com>2009-07-09 00:26:00 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-07-16 00:37:44 -0700
commiteaac497bfe4dd95a5d5ea34bf59c16bf946960e9 (patch)
tree8a521e9d49c0984ac33a7c1d2b1d5928c4c9b1d0 /xlators/performance/quick-read
parent06f02a48e0632469a7fd3ab1d7b5364a0de82d91 (diff)
quick-read: implement qr_open
- The file is opened actually only if it is not cached already in lookup. This adds responsibility for fops operating on fds to make sure that a valid fd actually opened on a file is used to complete the fop. Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
Diffstat (limited to 'xlators/performance/quick-read')
-rw-r--r--xlators/performance/quick-read/src/quick-read.c201
-rw-r--r--xlators/performance/quick-read/src/quick-read.h18
2 files changed, 219 insertions, 0 deletions
diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c
index 0e1ef147b..959d4baf0 100644
--- a/xlators/performance/quick-read/src/quick-read.c
+++ b/xlators/performance/quick-read/src/quick-read.c
@@ -19,6 +19,23 @@
#include "quick-read.h"
+
+static void
+qr_fd_ctx_free (qr_fd_ctx_t *qr_fd_ctx)
+{
+ if (qr_fd_ctx == NULL) {
+ goto out;
+ }
+
+ assert (list_empty (&qr_fd_ctx->waiting_ops));
+
+ FREE (qr_fd_ctx->path);
+ FREE (qr_fd_ctx);
+
+out:
+ return;
+}
+
int32_t
qr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
@@ -156,6 +173,189 @@ unwind:
}
+int32_t
+qr_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, fd_t *fd)
+{
+ uint64_t value = 0;
+ int32_t ret = -1;
+ struct list_head waiting_ops;
+ qr_local_t *local = NULL;
+ qr_file_t *qr_file = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ call_stub_t *stub = NULL, *tmp = NULL;
+
+ local = frame->local;
+ INIT_LIST_HEAD (&waiting_ops);
+
+ ret = fd_ctx_get (fd, this, &value);
+ if ((ret == -1) && (op_ret != -1)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ if (value) {
+ qr_fd_ctx = (qr_fd_ctx_t *) (long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ qr_fd_ctx->open_in_transit = 0;
+
+ if (op_ret == 0) {
+ qr_fd_ctx->opened = 1;
+ }
+ list_splice_init (&qr_fd_ctx->waiting_ops,
+ &waiting_ops);
+ }
+ UNLOCK (&qr_fd_ctx->lock);
+
+ if (local && local->is_open
+ && ((local->open_flags & O_TRUNC) == O_TRUNC)) {
+ ret = inode_ctx_get (fd->inode, this, &value);
+ if (ret == 0) {
+ qr_file = (qr_file_t *)(long) value;
+
+ if (qr_file) {
+ LOCK (&qr_file->lock);
+ {
+ dict_unref (qr_file->xattr);
+ qr_file->xattr = NULL;
+ }
+ UNLOCK (&qr_file->lock);
+ }
+ }
+ }
+
+ if (!list_empty (&waiting_ops)) {
+ list_for_each_entry_safe (stub, tmp, &waiting_ops,
+ list) {
+ list_del_init (&stub->list);
+ call_resume (stub);
+ }
+ }
+ }
+out:
+ if (local && local->is_open) {
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ fd_t *fd)
+{
+ qr_file_t *qr_file = NULL;
+ int32_t ret = -1;
+ uint64_t filep = 0;
+ char content_cached = 0;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t op_ret = -1, op_errno = -1;
+ qr_local_t *local = NULL;
+ qr_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ qr_fd_ctx = CALLOC (1, sizeof (*qr_fd_ctx));
+ if (qr_fd_ctx == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
+
+ LOCK_INIT (&qr_fd_ctx->lock);
+ INIT_LIST_HEAD (&qr_fd_ctx->waiting_ops);
+
+ qr_fd_ctx->path = strdup (loc->path);
+ qr_fd_ctx->flags = flags;
+
+ ret = fd_ctx_set (fd, this, (uint64_t)(long)qr_fd_ctx);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
+
+ local->is_open = 1;
+ local->open_flags = flags;
+ frame->local = local;
+ local = NULL;
+
+ ret = inode_ctx_get (fd->inode, this, &filep);
+ if (ret == 0) {
+ qr_file = (qr_file_t *)(long) filep;
+ if (qr_file) {
+ LOCK (&qr_file->lock);
+ {
+ if (qr_file->xattr) {
+ content_cached = 1;
+ }
+ }
+ UNLOCK (&qr_file->lock);
+ }
+ }
+
+ if (content_cached && ((flags & O_DIRECTORY) == O_DIRECTORY)) {
+ op_ret = -1;
+ op_errno = ENOTDIR;
+ qr_fd_ctx = NULL;
+ goto unwind;
+ }
+
+ if (!content_cached || ((flags & O_WRONLY) == O_WRONLY)
+ || ((flags & O_TRUNC) == O_TRUNC)) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ /*
+ * we need not set this flag, since open is not yet
+ * unwounded.
+ */
+
+ qr_fd_ctx->open_in_transit = 1;
+ }
+ UNLOCK (&qr_fd_ctx->lock);
+ goto wind;
+ } else {
+ op_ret = 0;
+ op_errno = 0;
+ goto unwind;
+ }
+
+unwind:
+ if (op_ret == -1) {
+ if (qr_fd_ctx != NULL) {
+ qr_fd_ctx_free (qr_fd_ctx);
+ }
+
+ if (local != NULL) {
+ FREE (local);
+ }
+ }
+
+ STACK_UNWIND (frame, op_ret, op_errno, fd);
+ return 0;
+
+wind:
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, loc, flags, fd);
+ return 0;
+}
+
+
int32_t
init (xlator_t *this)
{
@@ -229,6 +429,7 @@ fini (xlator_t *this)
struct xlator_fops fops = {
.lookup = qr_lookup,
+ .open = qr_open,
};
diff --git a/xlators/performance/quick-read/src/quick-read.h b/xlators/performance/quick-read/src/quick-read.h
index 44db76243..32bebac48 100644
--- a/xlators/performance/quick-read/src/quick-read.h
+++ b/xlators/performance/quick-read/src/quick-read.h
@@ -43,6 +43,24 @@
#define GLUSTERFS_CONTENT_KEY "glusterfs.content"
+struct qr_fd_ctx {
+ char opened;
+ char open_in_transit;
+ char *path;
+ int flags;
+ struct list_head waiting_ops;
+ gf_lock_t lock;
+};
+typedef struct qr_fd_ctx qr_fd_ctx_t;
+
+struct qr_local {
+ char is_open;
+ fd_t *fd;
+ int open_flags;
+ call_stub_t *stub;
+};
+typedef struct qr_local qr_local_t;
+
struct qr_file {
dict_t *xattr;
struct stat stbuf;