summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
Diffstat (limited to 'xlators')
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c129
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c213
-rw-r--r--xlators/cluster/afr/src/afr.c57
-rw-r--r--xlators/cluster/afr/src/afr.h17
-rw-r--r--xlators/debug/io-stats/src/io-stats.c68
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c322
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in8
-rw-r--r--xlators/performance/Makefile.am2
-rw-r--r--xlators/performance/quick-read/Makefile.am3
-rw-r--r--xlators/performance/quick-read/src/Makefile.am14
-rw-r--r--xlators/performance/quick-read/src/quick-read.c2235
-rw-r--r--xlators/performance/quick-read/src/quick-read.h78
-rw-r--r--xlators/protocol/server/src/server-protocol.c6
13 files changed, 2932 insertions, 220 deletions
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index b07ac3c48..88a3ded5e 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -78,6 +78,7 @@ afr_create_unwind (call_frame_t *frame, xlator_t *this)
{
call_frame_t *main_frame = NULL;
afr_local_t *local = NULL;
+ struct stat *unwind_buf = NULL;
local = frame->local;
@@ -91,10 +92,16 @@ afr_create_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ if (local->cont.create.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.create.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.create.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
local->cont.create.fd,
local->cont.create.inode,
- &local->cont.create.buf);
+ unwind_buf);
}
return 0;
@@ -155,13 +162,7 @@ afr_create_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (child_index == local->read_child_index) {
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
+ local->cont.create.read_child_buf = *buf;
}
local->cont.create.inode = inode;
@@ -321,6 +322,8 @@ afr_mknod_unwind (call_frame_t *frame, xlator_t *this)
call_frame_t *main_frame = NULL;
afr_local_t *local = NULL;
+ struct stat *unwind_buf = NULL;
+
local = frame->local;
LOCK (&frame->lock);
@@ -333,9 +336,15 @@ afr_mknod_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ if (local->cont.mknod.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.mknod.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.mknod.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
local->cont.mknod.inode,
- &local->cont.mknod.buf);
+ unwind_buf);
}
return 0;
@@ -383,13 +392,7 @@ afr_mknod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (child_index == local->read_child_index) {
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
+ local->cont.mknod.read_child_buf = *buf;
}
local->cont.mknod.inode = inode;
@@ -545,6 +548,8 @@ afr_mkdir_unwind (call_frame_t *frame, xlator_t *this)
call_frame_t *main_frame = NULL;
afr_local_t *local = NULL;
+ struct stat *unwind_buf = NULL;
+
local = frame->local;
LOCK (&frame->lock);
@@ -557,9 +562,15 @@ afr_mkdir_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ if (local->cont.mkdir.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.mkdir.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.mkdir.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
local->cont.mkdir.inode,
- &local->cont.mkdir.buf);
+ unwind_buf);
}
return 0;
@@ -606,13 +617,7 @@ afr_mkdir_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (child_index == local->read_child_index) {
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
+ local->cont.mkdir.read_child_buf = *buf;
}
local->cont.mkdir.inode = inode;
@@ -769,6 +774,8 @@ afr_link_unwind (call_frame_t *frame, xlator_t *this)
call_frame_t *main_frame = NULL;
afr_local_t *local = NULL;
+ struct stat *unwind_buf = NULL;
+
local = frame->local;
LOCK (&frame->lock);
@@ -783,9 +790,15 @@ afr_link_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.link.buf.st_ino = local->cont.link.ino;
+ if (local->cont.link.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.link.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.link.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
local->cont.link.inode,
- &local->cont.link.buf);
+ unwind_buf);
}
return 0;
@@ -832,13 +845,7 @@ afr_link_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (child_index == local->read_child_index) {
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
+ local->cont.link.read_child_buf = *buf;
}
local->cont.link.inode = inode;
@@ -994,7 +1001,9 @@ afr_symlink_unwind (call_frame_t *frame, xlator_t *this)
{
call_frame_t *main_frame = NULL;
afr_local_t *local = NULL;
-
+
+ struct stat *unwind_buf = NULL;
+
local = frame->local;
LOCK (&frame->lock);
@@ -1007,9 +1016,15 @@ afr_symlink_unwind (call_frame_t *frame, xlator_t *this)
UNLOCK (&frame->lock);
if (main_frame) {
+ if (local->cont.symlink.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.symlink.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.symlink.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
local->cont.symlink.inode,
- &local->cont.symlink.buf);
+ unwind_buf);
}
return 0;
@@ -1056,13 +1071,7 @@ afr_symlink_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (child_index == local->read_child_index) {
- if (priv->read_child >= 0) {
- afr_set_read_child (this, inode,
- priv->read_child);
- } else {
- afr_set_read_child (this, inode,
- local->read_child_index);
- }
+ local->cont.symlink.read_child_buf = *buf;
}
local->cont.symlink.inode = inode;
@@ -1219,6 +1228,8 @@ afr_rename_unwind (call_frame_t *frame, xlator_t *this)
call_frame_t *main_frame = NULL;
afr_local_t *local = NULL;
+ struct stat *unwind_buf = NULL;
+
local = frame->local;
LOCK (&frame->lock);
@@ -1233,8 +1244,14 @@ afr_rename_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.rename.buf.st_ino = local->cont.rename.ino;
+ if (local->cont.rename.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.rename.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.rename.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.rename.buf);
+ unwind_buf);
}
return 0;
@@ -1261,17 +1278,23 @@ afr_rename_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
- if ((op_ret != -1) && (local->success_count == 0)) {
- local->op_ret = op_ret;
+ if (op_ret != -1) {
+ if (local->success_count == 0) {
+ local->op_ret = op_ret;
- if (buf) {
- local->cont.rename.buf = *buf;
- local->cont.rename.buf.st_ino =
- afr_itransform (buf->st_ino, priv->child_count,
- child_index);
- }
- local->success_count++;
- }
+ if (buf) {
+ local->cont.rename.buf = *buf;
+ local->cont.rename.buf.st_ino =
+ afr_itransform (buf->st_ino, priv->child_count,
+ child_index);
+ }
+ local->success_count++;
+ }
+
+ if (child_index == local->read_child_index) {
+ local->cont.rename.read_child_buf = *buf;
+ }
+ }
local->op_errno = op_errno;
}
@@ -1379,6 +1402,8 @@ afr_rename (call_frame_t *frame, xlator_t *this,
loc_copy (&local->loc, oldloc);
loc_copy (&local->newloc, newloc);
+ local->read_child_index = afr_read_child (this, oldloc->inode);
+
local->cont.rename.ino = oldloc->inode->ino;
local->transaction.fop = afr_rename_wind;
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
index 57fdf20d5..1c1a9b034 100644
--- a/xlators/cluster/afr/src/afr-inode-write.c
+++ b/xlators/cluster/afr/src/afr-inode-write.c
@@ -58,6 +58,8 @@ afr_chmod_unwind (call_frame_t *frame, xlator_t *this)
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat * unwind_buf = NULL;
+
local = frame->local;
priv = this->private;
@@ -71,8 +73,15 @@ afr_chmod_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.chmod.buf.st_ino = local->cont.chmod.ino;
+
+ if (local->cont.chmod.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.chmod.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.chmod.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.chmod.buf);
+ unwind_buf);
}
return 0;
}
@@ -88,12 +97,19 @@ afr_chmod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int call_count = -1;
int child_index = (long) cookie;
int need_unwind = 0;
+ int read_child = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->loc.inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -102,9 +118,15 @@ afr_chmod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.chmod.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.chmod.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
@@ -251,6 +273,7 @@ afr_fchmod_unwind (call_frame_t *frame, xlator_t *this)
afr_local_t * local = NULL;
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat *unwind_buf = NULL;
local = frame->local;
priv = this->private;
@@ -265,8 +288,15 @@ afr_fchmod_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.fchmod.buf.st_ino = local->cont.fchmod.ino;
+
+ if (local->cont.fchmod.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.fchmod.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.fchmod.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.fchmod.buf);
+ unwind_buf);
}
return 0;
}
@@ -282,12 +312,19 @@ afr_fchmod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int call_count = -1;
int child_index = (long) cookie;
int need_unwind = 0;
+ int read_child = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->fd->inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -296,9 +333,15 @@ afr_fchmod_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.fchmod.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.fchmod.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
@@ -445,6 +488,8 @@ afr_chown_unwind (call_frame_t *frame, xlator_t *this)
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat * unwind_buf = NULL;
+
local = frame->local;
priv = this->private;
@@ -458,8 +503,15 @@ afr_chown_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.chown.buf.st_ino = local->cont.chown.ino;
+
+ if (local->cont.chown.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.chown.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.chown.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.chown.buf);
+ unwind_buf);
}
return 0;
}
@@ -475,12 +527,19 @@ afr_chown_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int call_count = -1;
int child_index = (long) cookie;
int need_unwind = 0;
+ int read_child = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->loc.inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -489,9 +548,15 @@ afr_chown_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.chown.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.chown.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
@@ -642,6 +707,8 @@ afr_fchown_unwind (call_frame_t *frame, xlator_t *this)
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat * unwind_buf = NULL;
+
local = frame->local;
priv = this->private;
@@ -655,8 +722,15 @@ afr_fchown_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.fchown.buf.st_ino = local->cont.fchown.ino;
+
+ if (local->cont.fchown.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.fchown.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.fchown.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.fchown.buf);
+ unwind_buf);
}
return 0;
}
@@ -672,12 +746,19 @@ afr_fchown_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int call_count = -1;
int child_index = (long) cookie;
int need_unwind = 0;
+ int read_child = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->fd->inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -686,9 +767,15 @@ afr_fchown_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.fchown.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.fchown.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
@@ -838,6 +925,8 @@ afr_writev_unwind (call_frame_t *frame, xlator_t *this)
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat * unwind_buf = NULL;
+
local = frame->local;
priv = this->private;
@@ -851,8 +940,15 @@ afr_writev_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.writev.buf.st_ino = local->cont.writev.ino;
+
+ if (local->cont.writev.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.writev.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.writev.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.writev.buf);
+ unwind_buf);
}
return 0;
}
@@ -868,12 +964,19 @@ afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int child_index = (long) cookie;
int call_count = -1;
int need_unwind = 0;
+ int read_child = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->fd->inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -882,9 +985,15 @@ afr_writev_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.writev.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.writev.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
@@ -1049,6 +1158,8 @@ afr_truncate_unwind (call_frame_t *frame, xlator_t *this)
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat * unwind_buf = NULL;
+
local = frame->local;
priv = this->private;
@@ -1062,9 +1173,18 @@ afr_truncate_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.truncate.buf.st_ino = local->cont.truncate.ino;
- AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.truncate.buf);
- }
+
+ if (local->cont.truncate.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.truncate.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.truncate.buf;
+ }
+
+ AFR_STACK_UNWIND (main_frame, local->op_ret,
+ local->op_errno,
+ unwind_buf);
+ }
+
return 0;
}
@@ -1077,14 +1197,21 @@ afr_truncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
afr_private_t * priv = NULL;
int child_index = (long) cookie;
+ int read_child = 0;
int call_count = -1;
int need_unwind = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->loc.inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -1093,9 +1220,15 @@ afr_truncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.truncate.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.truncate.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
@@ -1247,6 +1380,8 @@ afr_ftruncate_unwind (call_frame_t *frame, xlator_t *this)
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat * unwind_buf = NULL;
+
local = frame->local;
priv = this->private;
@@ -1260,8 +1395,15 @@ afr_ftruncate_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.ftruncate.buf.st_ino = local->cont.ftruncate.ino;
+
+ if (local->cont.ftruncate.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.ftruncate.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.ftruncate.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.ftruncate.buf);
+ unwind_buf);
}
return 0;
}
@@ -1277,12 +1419,19 @@ afr_ftruncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int child_index = (long) cookie;
int call_count = -1;
int need_unwind = 0;
+ int read_child = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->fd->inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -1291,9 +1440,15 @@ afr_ftruncate_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.ftruncate.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.ftruncate.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
@@ -1444,6 +1599,8 @@ afr_utimens_unwind (call_frame_t *frame, xlator_t *this)
afr_private_t * priv = NULL;
call_frame_t *main_frame = NULL;
+ struct stat * unwind_buf = NULL;
+
local = frame->local;
priv = this->private;
@@ -1457,8 +1614,15 @@ afr_utimens_unwind (call_frame_t *frame, xlator_t *this)
if (main_frame) {
local->cont.utimens.buf.st_ino = local->cont.utimens.ino;
+
+ if (local->cont.utimens.read_child_buf.st_ino) {
+ unwind_buf = &local->cont.utimens.read_child_buf;
+ } else {
+ unwind_buf = &local->cont.utimens.buf;
+ }
+
AFR_STACK_UNWIND (main_frame, local->op_ret, local->op_errno,
- &local->cont.utimens.buf);
+ unwind_buf);
}
return 0;
}
@@ -1474,12 +1638,19 @@ afr_utimens_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int child_index = (long) cookie;
int call_count = -1;
int need_unwind = 1;
+ int read_child = 0;
local = frame->local;
priv = this->private;
+ read_child = afr_read_child (this, local->loc.inode);
+
LOCK (&frame->lock);
{
+ if (child_index == read_child) {
+ local->read_child_returned = _gf_true;
+ }
+
if (afr_fop_failed (op_ret, op_errno))
afr_transaction_fop_failed (frame, this, child_index);
@@ -1488,9 +1659,15 @@ afr_utimens_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local->op_ret = op_ret;
local->cont.utimens.buf = *buf;
}
+
+ if (child_index == read_child) {
+ local->cont.utimens.read_child_buf = *buf;
+ }
+
local->success_count++;
- if (local->success_count == priv->wait_count) {
+ if ((local->success_count >= priv->wait_count)
+ && local->read_child_returned) {
need_unwind = 1;
}
}
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c
index 31c81ffd4..33aa16157 100644
--- a/xlators/cluster/afr/src/afr.c
+++ b/xlators/cluster/afr/src/afr.c
@@ -62,7 +62,9 @@ afr_is_split_brain (xlator_t *this, inode_t *inode)
uint64_t ctx = 0;
uint64_t split_brain = 0;
-
+
+ VALIDATE_OR_GOTO (inode, out);
+
LOCK (&inode->lock);
{
ret = __inode_ctx_get (inode, this, &ctx);
@@ -75,6 +77,7 @@ afr_is_split_brain (xlator_t *this, inode_t *inode)
unlock:
UNLOCK (&inode->lock);
+out:
return split_brain;
}
@@ -85,6 +88,8 @@ afr_set_split_brain (xlator_t *this, inode_t *inode, int32_t split_brain)
uint64_t ctx = 0;
int ret = 0;
+ VALIDATE_OR_GOTO (inode, out);
+
LOCK (&inode->lock);
{
ret = __inode_ctx_get (inode, this, &ctx);
@@ -99,6 +104,8 @@ afr_set_split_brain (xlator_t *this, inode_t *inode, int32_t split_brain)
__inode_ctx_put (inode, this, ctx);
}
UNLOCK (&inode->lock);
+out:
+ return;
}
@@ -109,7 +116,9 @@ afr_read_child (xlator_t *this, inode_t *inode)
uint64_t ctx = 0;
uint64_t read_child = 0;
-
+
+ VALIDATE_OR_GOTO (inode, out);
+
LOCK (&inode->lock);
{
ret = __inode_ctx_get (inode, this, &ctx);
@@ -122,6 +131,7 @@ afr_read_child (xlator_t *this, inode_t *inode)
unlock:
UNLOCK (&inode->lock);
+out:
return read_child;
}
@@ -132,6 +142,8 @@ afr_set_read_child (xlator_t *this, inode_t *inode, int32_t read_child)
uint64_t ctx = 0;
int ret = 0;
+ VALIDATE_OR_GOTO (inode, out);
+
LOCK (&inode->lock);
{
ret = __inode_ctx_get (inode, this, &ctx);
@@ -146,6 +158,9 @@ afr_set_read_child (xlator_t *this, inode_t *inode, int32_t read_child)
__inode_ctx_put (inode, this, ctx);
}
UNLOCK (&inode->lock);
+
+out:
+ return;
}
@@ -486,6 +501,16 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie,
&open_fd_count);
local->open_fd_count += open_fd_count;
+
+ first_up_child = afr_first_up_child (priv);
+
+ if (child_index == first_up_child) {
+ local->cont.lookup.ino =
+ afr_itransform (buf->st_ino,
+ priv->child_count,
+ first_up_child);
+ }
+
/* in case of revalidate, we need to send stat of the
* child whose stat was sent during the first lookup.
* (so that time stamp does not vary with revalidate.
@@ -540,15 +565,6 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie,
local->need_data_self_heal = 1;
}
- first_up_child = afr_first_up_child (priv);
-
- if (child_index == first_up_child) {
- local->cont.lookup.buf.st_ino =
- afr_itransform (buf->st_ino,
- priv->child_count,
- first_up_child);
- }
-
if (child_index == local->read_child_index) {
/*
@@ -587,11 +603,15 @@ unlock:
call_count = afr_frame_return (frame);
if (call_count == 0) {
+ if (local->cont.lookup.ino) {
+ local->cont.lookup.buf.st_ino = local->cont.lookup.ino;
+ }
+
if (local->op_ret == 0) {
/* KLUDGE: assuming DHT will not itransform in
revalidate */
if (local->cont.lookup.inode->ino)
- lookup_buf->st_ino =
+ local->cont.lookup.buf.st_ino =
local->cont.lookup.inode->ino;
}
@@ -722,6 +742,9 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)
uint64_t ctx;
afr_fd_ctx_t * fd_ctx = NULL;
+ VALIDATE_OR_GOTO (this->private, out);
+ VALIDATE_OR_GOTO (fd, out);
+
priv = this->private;
LOCK (&fd->lock);
@@ -729,7 +752,7 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)
ret = __fd_ctx_get (fd, this, &ctx);
if (ret == 0)
- goto out;
+ goto unlock;
fd_ctx = CALLOC (1, sizeof (afr_fd_ctx_t));
if (!fd_ctx) {
@@ -737,7 +760,7 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)
"Out of memory");
op_ret = -ENOMEM;
- goto out;
+ goto unlock;
}
fd_ctx->child_failed = CALLOC (sizeof (*fd_ctx->child_failed),
@@ -748,7 +771,7 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)
"Out of memory");
op_ret = -ENOMEM;
- goto out;
+ goto unlock;
}
ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
@@ -756,9 +779,9 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)
op_ret = ret;
}
}
-out:
+unlock:
UNLOCK (&fd->lock);
-
+out:
return ret;
}
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 2871bfc47..87ef26333 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -145,6 +145,7 @@ typedef struct _afr_local {
unsigned int govinda_gOvinda;
unsigned int read_child_index;
+ unsigned char read_child_returned;
pid_t saved_pid;
@@ -182,6 +183,8 @@ typedef struct _afr_local {
struct {
inode_t *inode;
struct stat buf;
+ struct stat read_child_buf;
+ ino_t ino;
dict_t *xattr;
} lookup;
@@ -267,12 +270,14 @@ typedef struct _afr_local {
ino_t ino;
mode_t mode;
struct stat buf;
+ struct stat read_child_buf;
} chmod;
struct {
ino_t ino;
mode_t mode;
struct stat buf;
+ struct stat read_child_buf;
} fchmod;
struct {
@@ -280,6 +285,7 @@ typedef struct _afr_local {
uid_t uid;
gid_t gid;
struct stat buf;
+ struct stat read_child_buf;
} chown;
struct {
@@ -287,11 +293,13 @@ typedef struct _afr_local {
uid_t uid;
gid_t gid;
struct stat buf;
+ struct stat read_child_buf;
} fchown;
struct {
ino_t ino;
struct stat buf;
+ struct stat read_child_buf;
int32_t op_ret;
@@ -305,18 +313,21 @@ typedef struct _afr_local {
ino_t ino;
off_t offset;
struct stat buf;
+ struct stat read_child_buf;
} truncate;
struct {
ino_t ino;
off_t offset;
struct stat buf;
+ struct stat read_child_buf;
} ftruncate;
struct {
ino_t ino;
struct timespec tv[2];
struct stat buf;
+ struct stat read_child_buf;
} utimens;
struct {
@@ -337,6 +348,7 @@ typedef struct _afr_local {
mode_t mode;
inode_t *inode;
struct stat buf;
+ struct stat read_child_buf;
} create;
struct {
@@ -345,6 +357,7 @@ typedef struct _afr_local {
mode_t mode;
inode_t *inode;
struct stat buf;
+ struct stat read_child_buf;
} mknod;
struct {
@@ -352,6 +365,7 @@ typedef struct _afr_local {
int32_t mode;
inode_t *inode;
struct stat buf;
+ struct stat read_child_buf;
} mkdir;
struct {
@@ -367,18 +381,21 @@ typedef struct _afr_local {
struct {
ino_t ino;
struct stat buf;
+ struct stat read_child_buf;
} rename;
struct {
ino_t ino;
inode_t *inode;
struct stat buf;
+ struct stat read_child_buf;
} link;
struct {
ino_t ino;
inode_t *inode;
struct stat buf;
+ struct stat read_child_buf;
char *linkpath;
} symlink;
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
index 2a46f4d78..c07685017 100644
--- a/xlators/debug/io-stats/src/io-stats.c
+++ b/xlators/debug/io-stats/src/io-stats.c
@@ -43,6 +43,22 @@ do { \
UNLOCK (&((io_stats_private_t *)this->private)->lock); \
} while (0)
+struct io_stats_io_count {
+ size_t size;
+ int64_t hits;
+};
+typedef enum {
+ GF_IO_STAT_BLK_SIZE_1K,
+ GF_IO_STAT_BLK_SIZE_2K,
+ GF_IO_STAT_BLK_SIZE_4K,
+ GF_IO_STAT_BLK_SIZE_8K,
+ GF_IO_STAT_BLK_SIZE_16K,
+ GF_IO_STAT_BLK_SIZE_32K,
+ GF_IO_STAT_BLK_SIZE_64K,
+ GF_IO_STAT_BLK_SIZE_128K,
+ GF_IO_STAT_BLK_SIZE_MAX,
+} gf_io_stat_blk_t;
+
struct io_stats_private {
gf_lock_t lock;
struct {
@@ -50,6 +66,8 @@ struct io_stats_private {
int enabled;
uint32_t hits;
} fop_records[GF_FOP_MAXVALUE];
+ struct io_stats_io_count read[GF_IO_STAT_BLK_SIZE_MAX + 1];
+ struct io_stats_io_count write[GF_IO_STAT_BLK_SIZE_MAX + 1];
};
typedef struct io_stats_private io_stats_private_t;
@@ -102,6 +120,20 @@ io_stats_readv_cbk (call_frame_t *frame,
struct stat *buf,
struct iobref *iobref)
{
+ int i = 0;
+ io_stats_private_t *priv = NULL;
+
+ priv = this->private;
+
+ if (op_ret > 0) {
+ for (i=0; i < GF_IO_STAT_BLK_SIZE_MAX; i++) {
+ if (priv->read[i].size > iov_length (vector, count)) {
+ break;
+ }
+ }
+ priv->read[i].hits++;
+ }
+
STACK_UNWIND (frame, op_ret, op_errno, vector, count, buf, iobref);
return 0;
}
@@ -966,8 +998,20 @@ io_stats_writev (call_frame_t *frame,
off_t offset,
struct iobref *iobref)
{
+ int i = 0;
+ io_stats_private_t *priv = NULL;
+
+ priv = this->private;
+
BUMP_HIT(WRITE);
+ for (i=0; i < GF_IO_STAT_BLK_SIZE_MAX; i++) {
+ if (priv->write[i].size > iov_length (vector, count)) {
+ break;
+ }
+ }
+ priv->write[i].hits++;
+
STACK_WIND (frame,
io_stats_writev_cbk,
FIRST_CHILD(this),
@@ -1386,6 +1430,8 @@ init (xlator_t *this)
dict_t *options = this->options;
char *includes = NULL, *excludes = NULL;
io_stats_private_t *priv = NULL;
+ size_t size = 0;
+ int i = 0;
if (!this)
return -1;
@@ -1406,18 +1452,15 @@ init (xlator_t *this)
includes = data_to_str (dict_get (options, "include-ops"));
excludes = data_to_str (dict_get (options, "exclude-ops"));
- {
- int i;
- for (i = 0; i < GF_FOP_MAXVALUE; i++) {
- priv->fop_records[i].name = gf_fop_list[i];
- priv->fop_records[i].enabled = 1;
- }
+ for (i = 0; i < GF_FOP_MAXVALUE; i++) {
+ priv->fop_records[i].name = gf_fop_list[i];
+ priv->fop_records[i].enabled = 1;
}
if (includes && excludes) {
- gf_log (this->name,
- GF_LOG_ERROR,
- "must specify only one of 'include-ops' and 'exclude-ops'");
+ gf_log (this->name, GF_LOG_ERROR,
+ "must specify only one of 'include-ops' and "
+ "'exclude-ops'");
return -1;
}
if (includes)
@@ -1428,6 +1471,13 @@ init (xlator_t *this)
LOCK_INIT (&priv->lock);
/* Set this translator's inode table pointer to child node's pointer. */
+ size = GF_UNIT_KB;
+ for (i=0; i < GF_IO_STAT_BLK_SIZE_MAX; i++) {
+ priv->read[i].size = size;
+ priv->write[i].size = size;
+ size *= 2;
+ }
+
this->itable = FIRST_CHILD (this)->itable;
this->private = priv;
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index ff68123df..efc8ea54d 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -84,11 +84,29 @@ typedef struct fuse_private fuse_private_t;
#define FUSE_FOP(state, ret, op_num, fop, args ...) \
do { \
- call_frame_t *frame = get_call_frame_for_req (state, 1); \
- xlator_t *xl = frame->this->children ? \
+ call_frame_t *frame = NULL; \
+ xlator_t *xl = NULL; \
+ \
+ frame = get_call_frame_for_req (state, 1); \
+ if (!frame) { \
+ /* This is not completely clean, as some \
+ * earlier allocations might remain unfreed \
+ * if we return at this point, but still \
+ * better than trying to go on with a NULL \
+ * frame ... \
+ */ \
+ gf_log ("glusterfs-fuse", \
+ GF_LOG_ERROR, \
+ "FUSE message unique %"PRIu64":" \
+ " frame allocation failed", \
+ req_callid (state->req)); \
+ free_state (state); \
+ return; \
+ } \
+ xl = frame->this->children ? \
frame->this->children->xlator : NULL; \
frame->root->state = state; \
- frame->root->op = op_num; \
+ frame->root->op = op_num; \
STACK_WIND (frame, ret, xl, xl->fops->fop, args); \
} while (0)
@@ -96,6 +114,23 @@ typedef struct fuse_private fuse_private_t;
(((_errno == ENOENT) || (_errno == ESTALE))? \
GF_LOG_DEBUG)
+#define STATE_FROM_REQ(req, state) \
+ do { \
+ state = state_from_req (req); \
+ if (!state) { \
+ gf_log ("glusterfs-fuse", \
+ GF_LOG_ERROR, \
+ "FUSE message unique %"PRIu64":" \
+ " state allocation failed", \
+ req_callid (req)); \
+ \
+ fuse_reply_err (req, ENOMEM); \
+ \
+ return; \
+ } \
+ } while (0)
+
+
typedef struct {
void *pool;
xlator_t *this;
@@ -194,6 +229,8 @@ get_call_frame_for_req (fuse_state_t *state, char d)
priv = this->private;
frame = create_frame (this, pool);
+ if (!frame)
+ return NULL;
if (req) {
ctx = fuse_req_ctx (req);
@@ -418,13 +455,13 @@ fuse_lookup (fuse_req_t req, fuse_ino_t par, const char *name)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": LOOKUP %"PRId64"/%s (fuse_loc_fill() failed)",
+ "%"PRIu64": LOOKUP %"PRId64"/%s (fuse_loc_fill() failed)",
req_callid (req), (ino_t)par, name);
free_state (state);
fuse_reply_err (req, ENOENT);
@@ -433,7 +470,7 @@ fuse_lookup (fuse_req_t req, fuse_ino_t par, const char *name)
if (!state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": LOOKUP %s", req_callid (req),
+ "%"PRIu64": LOOKUP %s", req_callid (req),
state->loc.path);
state->loc.inode = inode_new (state->itable);
@@ -441,7 +478,7 @@ fuse_lookup (fuse_req_t req, fuse_ino_t par, const char *name)
state->is_revalidate = -1;
} else {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": LOOKUP %s(%"PRId64")", req_callid (req),
+ "%"PRIu64": LOOKUP %s(%"PRId64")", req_callid (req),
state->loc.path, state->loc.inode->ino);
state->is_revalidate = 1;
}
@@ -457,15 +494,16 @@ static void
fuse_forget (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup)
{
inode_t *fuse_inode;
- fuse_state_t *state;
+ xlator_t *this = NULL;
+
+ this = fuse_req_userdata (req);
if (ino == 1) {
fuse_reply_none (req);
return;
}
- state = state_from_req (req);
- fuse_inode = inode_search (state->itable, ino, NULL);
+ fuse_inode = inode_search (this->itable, ino, NULL);
if (fuse_inode) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"got forget on inode (%lu)", ino);
@@ -476,7 +514,6 @@ fuse_forget (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup)
"got forget, but inode (%lu) not found", ino);
}
- free_state (state);
fuse_reply_none (req);
}
@@ -528,13 +565,13 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
fd_t *fd = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
if (ino == 1) {
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": GETATTR %"PRId64" (fuse_loc_fill() failed)",
+ "%"PRIu64": GETATTR %"PRId64" (fuse_loc_fill() failed)",
req_callid (req), (ino_t)ino);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -557,7 +594,7 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
if (!state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": GETATTR %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
+ "%"PRIu64": GETATTR %"PRId64" (%s) (fuse_loc_fill() returned NULL inode)",
req_callid (req), (int64_t)ino, state->loc.path);
fuse_reply_err (req, ENOENT);
return;
@@ -571,7 +608,7 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
*/
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": GETATTR %"PRId64" (fuse_loc_fill() failed)",
+ "%"PRIu64": GETATTR %"PRId64" (fuse_loc_fill() failed)",
req_callid (req), (ino_t)ino);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -579,7 +616,7 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": GETATTR %"PRId64" (%s)",
+ "%"PRIu64": GETATTR %"PRId64" (%s)",
req_callid (req), (int64_t)ino, state->loc.path);
@@ -588,7 +625,7 @@ fuse_getattr (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
} else {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": FGETATTR %"PRId64" (%s/%p)",
+ "%"PRIu64": FGETATTR %"PRId64" (%s/%p)",
req_callid (req), (int64_t)ino, state->loc.path, fd);
FUSE_FOP (state,fuse_attr_cbk, GF_FOP_FSTAT,
@@ -615,7 +652,8 @@ fuse_fd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fi.flags = state->flags;
if (!S_ISDIR (fd->inode->st_mode)) {
- if ((fi.flags & 3) && priv->direct_io_mode)
+ if (((fi.flags & O_ACCMODE) != O_RDONLY) &&
+ priv->direct_io_mode)
fi.direct_io = 1;
}
@@ -655,7 +693,7 @@ do_chmod (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
fd_t *fd = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
if (fi) {
fd = FI_TO_FD (fi);
state->fd = fd;
@@ -663,7 +701,7 @@ do_chmod (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if (fd) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": FCHMOD %p", req_callid (req), fd);
+ "%"PRIu64": FCHMOD %p", req_callid (req), fd);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FCHMOD,
fchmod, fd, attr->st_mode);
@@ -673,7 +711,7 @@ do_chmod (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": CHMOD %"PRId64" (%s) (fuse_loc_fill() failed)",
+ "%"PRIu64": CHMOD %"PRId64" (%s) (fuse_loc_fill() failed)",
req_callid (req), (int64_t)ino,
state->loc.path);
fuse_reply_err (req, ENOENT);
@@ -683,7 +721,7 @@ do_chmod (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": CHMOD %s", req_callid (req),
+ "%"PRIu64": CHMOD %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_CHMOD,
@@ -704,7 +742,7 @@ do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
uid = (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
gid = (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
if (fi) {
fd = FI_TO_FD (fi);
@@ -713,7 +751,7 @@ do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if (fd) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": FCHOWN %p", req_callid (req), fd);
+ "%"PRIu64": FCHOWN %p", req_callid (req), fd);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FCHOWN,
fchown, fd, uid, gid);
@@ -722,7 +760,7 @@ do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": CHOWN %"PRId64" (%s) (fuse_loc_fill() failed)",
+ "%"PRIu64": CHOWN %"PRId64" (%s) (fuse_loc_fill() failed)",
req_callid (req), (int64_t)ino,
state->loc.path);
fuse_reply_err (req, ENOENT);
@@ -731,7 +769,7 @@ do_chown (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": CHOWN %s", req_callid (req),
+ "%"PRIu64": CHOWN %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_CHOWN,
@@ -748,7 +786,7 @@ do_truncate (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
fd_t *fd = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
if (fi) {
fd = FI_TO_FD (fi);
@@ -757,7 +795,7 @@ do_truncate (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if (fd) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": FTRUNCATE %p/%"PRId64, req_callid (req),
+ "%"PRIu64": FTRUNCATE %p/%"PRId64, req_callid (req),
fd, attr->st_size);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_FTRUNCATE,
@@ -767,7 +805,7 @@ do_truncate (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": TRUNCATE %s/%"PRId64" (fuse_loc_fill() failed)",
+ "%"PRIu64": TRUNCATE %s/%"PRId64" (fuse_loc_fill() failed)",
req_callid (req), state->loc.path,
attr->st_size);
fuse_reply_err (req, ENOENT);
@@ -776,7 +814,7 @@ do_truncate (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": TRUNCATE %s/%"PRId64"(%lu)",
+ "%"PRIu64": TRUNCATE %s/%"PRId64"(%lu)",
req_callid (req),
state->loc.path, attr->st_size, ino);
@@ -800,12 +838,12 @@ do_utimes (fuse_req_t req, fuse_ino_t ino, struct stat *attr)
tv[1].tv_sec = attr->st_mtime;
tv[1].tv_nsec = ST_ATIM_NSEC (attr);
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": UTIMENS %s (fuse_loc_fill() failed)",
+ "%"PRIu64": UTIMENS %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -813,7 +851,7 @@ do_utimes (fuse_req_t req, fuse_ino_t ino, struct stat *attr)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": UTIMENS (%lu)%s", req_callid (req),
+ "%"PRIu64": UTIMENS (%lu)%s", req_callid (req),
ino, state->loc.path);
FUSE_FOP (state, fuse_attr_cbk, GF_FOP_UTIMENS,
@@ -936,13 +974,13 @@ fuse_access (fuse_req_t req, fuse_ino_t ino, int mask)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": ACCESS %"PRId64" (%s) (fuse_loc_fill() failed)",
+ "%"PRIu64": ACCESS %"PRId64" (%s) (fuse_loc_fill() failed)",
req_callid (req), (int64_t)ino, state->loc.path);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -950,7 +988,7 @@ fuse_access (fuse_req_t req, fuse_ino_t ino, int mask)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64" ACCESS %s/%lu mask=%d", req_callid (req),
+ "%"PRIu64" ACCESS %s/%lu mask=%d", req_callid (req),
state->loc.path, ino, mask);
FUSE_FOP (state, fuse_err_cbk,
@@ -1000,12 +1038,12 @@ fuse_readlink (fuse_req_t req, fuse_ino_t ino)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64" READLINK %s/%"PRId64" (fuse_loc_fill() returned NULL inode)",
+ "%"PRIu64" READLINK %s/%"PRId64" (fuse_loc_fill() returned NULL inode)",
req_callid (req), state->loc.path,
state->loc.inode->ino);
fuse_reply_err (req, ENOENT);
@@ -1014,7 +1052,7 @@ fuse_readlink (fuse_req_t req, fuse_ino_t ino)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64" READLINK %s/%"PRId64, req_callid (req),
+ "%"PRIu64" READLINK %s/%"PRId64, req_callid (req),
state->loc.path, state->loc.inode->ino);
FUSE_FOP (state, fuse_readlink_cbk, GF_FOP_READLINK,
@@ -1031,11 +1069,11 @@ fuse_mknod (fuse_req_t req, fuse_ino_t par, const char *name,
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64" MKNOD %s (fuse_loc_fill() failed)",
+ "%"PRIu64" MKNOD %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -1045,7 +1083,7 @@ fuse_mknod (fuse_req_t req, fuse_ino_t par, const char *name,
state->loc.inode = inode_new (state->itable);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": MKNOD %s", req_callid (req),
+ "%"PRIu64": MKNOD %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_entry_cbk, GF_FOP_MKNOD,
@@ -1061,11 +1099,11 @@ fuse_mkdir (fuse_req_t req, fuse_ino_t par, const char *name, mode_t mode)
fuse_state_t *state;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64" MKDIR %s (fuse_loc_fill() failed)",
+ "%"PRIu64" MKDIR %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -1075,7 +1113,7 @@ fuse_mkdir (fuse_req_t req, fuse_ino_t par, const char *name, mode_t mode)
state->loc.inode = inode_new (state->itable);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": MKDIR %s", req_callid (req),
+ "%"PRIu64": MKDIR %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_entry_cbk, GF_FOP_MKDIR,
@@ -1091,14 +1129,14 @@ fuse_unlink (fuse_req_t req, fuse_ino_t par, const char *name)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": UNLINK %s (fuse_loc_fill() returned NULL inode)",
+ "%"PRIu64": UNLINK %s (fuse_loc_fill() returned NULL inode)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -1106,7 +1144,7 @@ fuse_unlink (fuse_req_t req, fuse_ino_t par, const char *name)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": UNLINK %s", req_callid (req),
+ "%"PRIu64": UNLINK %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_UNLINK,
@@ -1122,12 +1160,12 @@ fuse_rmdir (fuse_req_t req, fuse_ino_t par, const char *name)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": RMDIR %s (fuse_loc_fill() failed)",
+ "%"PRIu64": RMDIR %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -1135,7 +1173,7 @@ fuse_rmdir (fuse_req_t req, fuse_ino_t par, const char *name)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": RMDIR %s", req_callid (req),
+ "%"PRIu64": RMDIR %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_unlink_cbk, GF_FOP_RMDIR,
@@ -1152,11 +1190,11 @@ fuse_symlink (fuse_req_t req, const char *linkname, fuse_ino_t par,
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64" SYMLINK %s -> %s (fuse_loc_fill() failed)",
+ "%"PRIu64" SYMLINK %s -> %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path, linkname);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -1166,7 +1204,7 @@ fuse_symlink (fuse_req_t req, const char *linkname, fuse_ino_t par,
state->loc.inode = inode_new (state->itable);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": SYMLINK %s -> %s", req_callid (req),
+ "%"PRIu64": SYMLINK %s -> %s", req_callid (req),
state->loc.path, linkname);
FUSE_FOP (state, fuse_entry_cbk, GF_FOP_SYMLINK,
@@ -1228,13 +1266,13 @@ fuse_rename (fuse_req_t req, fuse_ino_t oldpar, const char *oldname,
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, oldpar, oldname);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "for %s %"PRId64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
+ "for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
state->loc.path, req_callid (req), state->loc.path,
state->loc2.path);
@@ -1246,7 +1284,7 @@ fuse_rename (fuse_req_t req, fuse_ino_t oldpar, const char *oldname,
ret = fuse_loc_fill (&state->loc2, state, 0, newpar, newname);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "for %s %"PRId64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
+ "for %s %"PRIu64": RENAME `%s' -> `%s' (fuse_loc_fill() failed)",
state->loc.path, req_callid (req), state->loc.path,
state->loc2.path);
@@ -1256,7 +1294,7 @@ fuse_rename (fuse_req_t req, fuse_ino_t oldpar, const char *oldname,
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
+ "%"PRIu64": RENAME `%s (%"PRId64")' -> `%s (%"PRId64")'",
req_callid (req), state->loc.path, state->loc.ino,
state->loc2.path, state->loc2.ino);
@@ -1273,15 +1311,16 @@ fuse_link (fuse_req_t req, fuse_ino_t ino, fuse_ino_t par, const char *name)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
- ret = fuse_loc_fill (&state->loc2, state, ino, 0, NULL);
+ if (ret == 0)
+ ret = fuse_loc_fill (&state->loc2, state, ino, 0, NULL);
if ((state->loc2.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "fuse_loc_fill() failed for %s %"PRId64": LINK %s %s",
+ "fuse_loc_fill() failed for %s %"PRIu64": LINK %s %s",
state->loc2.path, req_callid (req),
state->loc2.path, state->loc.path);
fuse_reply_err (req, ENOENT);
@@ -1291,7 +1330,7 @@ fuse_link (fuse_req_t req, fuse_ino_t ino, fuse_ino_t par, const char *name)
state->loc.inode = inode_ref (state->loc2.inode);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": LINK() %s (%"PRId64") -> %s (%"PRId64")",
+ "%"PRIu64": LINK() %s (%"PRId64") -> %s (%"PRId64")",
req_callid (req), state->loc2.path, state->loc2.ino,
state->loc.path, state->loc.ino);
@@ -1321,7 +1360,8 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
fi.fh = (unsigned long) fd;
- if ((fi.flags & 3) && priv->direct_io_mode)
+ if (((fi.flags & O_ACCMODE) != O_RDONLY)
+ && priv->direct_io_mode)
fi.direct_io = 1;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
@@ -1361,7 +1401,7 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fd_bind (fd);
} else {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": %s => -1 (%s)", req_callid (req),
+ "%"PRIu64": %s => -1 (%s)", req_callid (req),
state->loc.path, strerror (op_errno));
fuse_reply_err (req, op_errno);
}
@@ -1381,13 +1421,13 @@ fuse_create (fuse_req_t req, fuse_ino_t par, const char *name,
fd_t *fd = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->flags = fi->flags;
ret = fuse_loc_fill (&state->loc, state, 0, par, name);
if (ret < 0) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64" CREATE %s (fuse_loc_fill() failed)",
+ "%"PRIu64" CREATE %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
free_state (state);
@@ -1401,7 +1441,7 @@ fuse_create (fuse_req_t req, fuse_ino_t par, const char *name,
fd->flags = state->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": CREATE %s", req_callid (req),
+ "%"PRIu64": CREATE %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_create_cbk, GF_FOP_CREATE,
@@ -1418,14 +1458,14 @@ fuse_open (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
fd_t *fd = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->flags = fi->flags;
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": OPEN %s (fuse_loc_fill() failed)",
+ "%"PRIu64": OPEN %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
@@ -1438,7 +1478,7 @@ fuse_open (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
fd->flags = fi->flags;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": OPEN %s", req_callid (req),
+ "%"PRIu64": OPEN %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPEN,
@@ -1493,7 +1533,7 @@ fuse_readv (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->size = size;
state->off = off;
@@ -1501,7 +1541,7 @@ fuse_readv (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": READ (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ "%"PRIu64": READ (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
req_callid (req), fd, size, off);
FUSE_FOP (state, fuse_readv_cbk, GF_FOP_READ,
@@ -1554,7 +1594,7 @@ fuse_write (fuse_req_t req, fuse_ino_t ino, const char *buf,
struct iobref *iobref = NULL;
struct iobuf *iobuf = NULL;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->size = size;
state->off = off;
fd = FI_TO_FD (fi);
@@ -1563,10 +1603,18 @@ fuse_write (fuse_req_t req, fuse_ino_t ino, const char *buf,
vector.iov_len = size;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": WRITE (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ "%"PRIu64": WRITE (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
req_callid (req), fd, size, off);
iobref = iobref_new ();
+ if (!iobref) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "%"PRIu64": WRITE iobref allocation failed",
+ req_callid (req));
+
+ free_state (state);
+ return;
+ }
iobuf = ((fuse_private_t *) (state->this->private))->iobuf;
iobref_add (iobref, iobuf);
@@ -1584,12 +1632,12 @@ fuse_flush (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
fd = FI_TO_FD (fi);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": FLUSH %p", req_callid (req), fd);
+ "%"PRIu64": FLUSH %p", req_callid (req), fd);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FLUSH,
flush, fd);
@@ -1603,11 +1651,11 @@ fuse_release (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
fuse_state_t *state = NULL;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->fd = FI_TO_FD (fi);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": RELEASE %p", req_callid (req), state->fd);
+ "%"PRIu64": RELEASE %p", req_callid (req), state->fd);
fd_unref (state->fd);
@@ -1625,12 +1673,12 @@ fuse_fsync (fuse_req_t req, fuse_ino_t ino, int datasync,
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
fd = FI_TO_FD (fi);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": FSYNC %p", req_callid (req), fd);
+ "%"PRIu64": FSYNC %p", req_callid (req), fd);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNC,
fsync, fd, datasync);
@@ -1646,12 +1694,12 @@ fuse_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
fd_t *fd = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": OPENDIR %s (fuse_loc_fill() failed)",
+ "%"PRIu64": OPENDIR %s (fuse_loc_fill() failed)",
req_callid (req), state->loc.path);
fuse_reply_err (req, ENOENT);
@@ -1663,7 +1711,7 @@ fuse_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": OPENDIR %s", req_callid (req),
+ "%"PRIu64": OPENDIR %s", req_callid (req),
state->loc.path);
FUSE_FOP (state, fuse_fd_cbk, GF_FOP_OPENDIR,
@@ -1708,7 +1756,7 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
"%"PRId64": READDIR => -1 (%s)", frame->root->unique,
strerror (ENOMEM));
- fuse_reply_err (req, -ENOMEM);
+ fuse_reply_err (req, ENOMEM);
goto out;
}
@@ -1741,14 +1789,14 @@ fuse_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
fuse_state_t *state = NULL;
fd_t *fd = NULL;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->size = size;
state->off = off;
fd = FI_TO_FD (fi);
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": READDIR (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ "%"PRIu64": READDIR (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
req_callid (req), fd, size, off);
FUSE_FOP (state, fuse_readdir_cbk, GF_FOP_READDIR,
@@ -1761,11 +1809,11 @@ fuse_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
{
fuse_state_t *state = NULL;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->fd = FI_TO_FD (fi);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": RELEASEDIR %p", req_callid (req), state->fd);
+ "%"PRIu64": RELEASEDIR %p", req_callid (req), state->fd);
fd_unref (state->fd);
@@ -1786,7 +1834,7 @@ fuse_fsyncdir (fuse_req_t req, fuse_ino_t ino, int datasync,
fd = FI_TO_FD (fi);
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->fd = fd;
FUSE_FOP (state, fuse_err_cbk, GF_FOP_FSYNCDIR,
@@ -1855,12 +1903,12 @@ fuse_statfs (fuse_req_t req, fuse_ino_t ino)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, 1, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": STATFS (fuse_loc_fill() fail)",
+ "%"PRIu64": STATFS (fuse_loc_fill() fail)",
req_callid (req));
fuse_reply_err (req, ENOENT);
@@ -1869,7 +1917,7 @@ fuse_statfs (fuse_req_t req, fuse_ino_t ino)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": STATFS", req_callid (req));
+ "%"PRIu64": STATFS", req_callid (req));
FUSE_FOP (state, fuse_statfs_cbk, GF_FOP_STATFS,
statfs, &state->loc);
@@ -1891,13 +1939,13 @@ fuse_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name,
}
#endif
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->size = size;
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": SETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
+ "%"PRIu64": SETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
req_callid (req),
state->loc.path, (int64_t)ino, name);
@@ -1907,6 +1955,14 @@ fuse_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name,
}
state->dict = get_new_dict ();
+ if (!state->dict) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "%"PRIu64": SETXATTR dict allocation failed",
+ req_callid (req));
+
+ free_state (state);
+ return;
+ }
dict_value = memdup (value, size);
dict_set (state->dict, (char *)name,
@@ -1914,7 +1970,7 @@ fuse_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name,
dict_ref (state->dict);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": SETXATTR %s/%"PRId64" (%s)", req_callid (req),
+ "%"PRIu64": SETXATTR %s/%"PRId64" (%s)", req_callid (req),
state->loc.path, (int64_t)ino, name);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_SETXATTR,
@@ -2030,6 +2086,9 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
} else if (!strcmp (state->name, "user.glusterfs-booster-path")) {
fuse_reply_xattr_buf (state, req, state->loc.path,
strlen (state->loc.path) + 1);
+ } else if (!strcmp (state->name, "user.glusterfs-booster-mount")) {
+ fuse_reply_xattr_buf (state, req, priv->mount_point,
+ strlen(priv->mount_point) + 1);
} else {
fuse_reply_err (req, ENODATA);
} /* if(value_data)...else */
@@ -2106,7 +2165,7 @@ fuse_getxattr (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
}
#endif
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->size = size;
state->name = strdup (name);
@@ -2114,7 +2173,7 @@ fuse_getxattr (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": GETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
+ "%"PRIu64": GETXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
req_callid (req), state->loc.path, (int64_t)ino, name);
fuse_reply_err (req, ENOENT);
@@ -2123,7 +2182,7 @@ fuse_getxattr (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": GETXATTR %s/%"PRId64" (%s)", req_callid (req),
+ "%"PRIu64": GETXATTR %s/%"PRId64" (%s)", req_callid (req),
state->loc.path, (int64_t)ino, name);
FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
@@ -2139,13 +2198,13 @@ fuse_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->size = size;
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
- "%"PRId64": LISTXATTR %s/%"PRId64" (fuse_loc_fill() failed)",
+ "%"PRIu64": LISTXATTR %s/%"PRId64" (fuse_loc_fill() failed)",
req_callid (req), state->loc.path, (int64_t)ino);
fuse_reply_err (req, ENOENT);
@@ -2154,7 +2213,7 @@ fuse_listxattr (fuse_req_t req, fuse_ino_t ino, size_t size)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": LISTXATTR %s/%"PRId64, req_callid (req),
+ "%"PRIu64": LISTXATTR %s/%"PRId64, req_callid (req),
state->loc.path, (int64_t)ino);
FUSE_FOP (state, fuse_xattr_cbk, GF_FOP_GETXATTR,
@@ -2171,12 +2230,12 @@ fuse_removexattr (fuse_req_t req, fuse_ino_t ino, const char *name)
fuse_state_t *state = NULL;
int32_t ret = -1;
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
ret = fuse_loc_fill (&state->loc, state, ino, 0, NULL);
if ((state->loc.inode == NULL) ||
(ret < 0)) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
- "%"PRId64": REMOVEXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
+ "%"PRIu64": REMOVEXATTR %s/%"PRId64" (%s) (fuse_loc_fill() failed)",
req_callid (req), state->loc.path, (int64_t)ino, name);
fuse_reply_err (req, ENOENT);
@@ -2185,7 +2244,7 @@ fuse_removexattr (fuse_req_t req, fuse_ino_t ino, const char *name)
}
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": REMOVEXATTR %s/%"PRId64" (%s)", req_callid (req),
+ "%"PRIu64": REMOVEXATTR %s/%"PRId64" (%s)", req_callid (req),
state->loc.path, (int64_t)ino, name);
FUSE_FOP (state, fuse_err_cbk, GF_FOP_REMOVEXATTR,
@@ -2241,12 +2300,12 @@ fuse_getlk (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
fd_t *fd = NULL;
fd = FI_TO_FD (fi);
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->req = req;
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": GETLK %p", req_callid (req), fd);
+ "%"PRIu64": GETLK %p", req_callid (req), fd);
FUSE_FOP (state, fuse_getlk_cbk, GF_FOP_LK,
lk, fd, F_GETLK, lock);
@@ -2300,12 +2359,12 @@ fuse_setlk (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
fd_t *fd = NULL;
fd = FI_TO_FD (fi);
- state = state_from_req (req);
+ STATE_FROM_REQ (req, state);
state->req = req;
state->fd = fd;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRId64": SETLK %p (sleep=%d)", req_callid (req), fd,
+ "%"PRIu64": SETLK %p (sleep=%d)", req_callid (req), fd,
sleep);
FUSE_FOP (state, fuse_setlk_cbk, GF_FOP_LK,
@@ -2475,8 +2534,10 @@ fuse_thread_proc (void *data)
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"fuse_chan_receive() returned -1 (%d)", errno);
}
- if (errno == ENODEV)
+ if (errno == ENODEV) {
+ iobuf_unref (iobuf);
break;
+ }
continue;
}
@@ -2591,6 +2652,7 @@ init (xlator_t *this_xl)
fuse_private_t *priv = NULL;
struct stat stbuf = {0,};
struct fuse_args args = FUSE_ARGS_INIT (0, NULL);
+ int xl_name_allocated = 0;
if (this_xl == NULL)
return -1;
@@ -2602,7 +2664,13 @@ init (xlator_t *this_xl)
if (this_xl->name == NULL) {
this_xl->name = strdup ("fuse");
- ERR_ABORT (this_xl->name);
+ if (!this_xl->name) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
+
+ goto cleanup_exit;
+ }
+ xl_name_allocated = 1;
}
fsname = this_xl->ctx->cmd_args.volume_file;
@@ -2653,12 +2721,22 @@ init (xlator_t *this_xl)
#endif /* LINUX */
#endif /* ! DARWIN_OS */
- if (ret == -1)
- ERR_ABORT (NULL);
+ if (ret == -1) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
+
+ goto cleanup_exit;
+ }
priv = CALLOC (1, sizeof (*priv));
- ERR_ABORT (priv);
+ if (!priv) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
+
+ goto cleanup_exit;
+ }
this_xl->private = (void *) priv;
+ priv->mount_point = NULL;
/* get options from option dictionary */
ret = dict_get_str (options, ZR_MOUNTPOINT_OPT, &value_string);
@@ -2694,7 +2772,12 @@ init (xlator_t *this_xl)
goto cleanup_exit;
}
priv->mount_point = strdup (value_string);
- ERR_ABORT (priv->mount_point);
+ if (!priv->mount_point) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
+
+ goto cleanup_exit;
+ }
ret = dict_get_double (options, "attribute-timeout",
&priv->attribute_timeout);
@@ -2720,6 +2803,14 @@ init (xlator_t *this_xl)
&priv->strict_volfile_check);
}
+ this_xl->itable = inode_table_new (0, this_xl);
+ if (!this_xl->itable) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "Out of memory");
+
+ goto cleanup_exit;
+ }
+
priv->ch = fuse_mount (priv->mount_point, &args);
if (priv->ch == NULL) {
if (errno == ENOTCONN) {
@@ -2797,12 +2888,13 @@ init (xlator_t *this_xl)
this_xl->ctx->top = this_xl;
priv->first_call = 2;
- this_xl->itable = inode_table_new (0, this_xl);
return 0;
umount_exit:
fuse_unmount (priv->mount_point, priv->ch);
cleanup_exit:
+ if (xl_name_allocated)
+ FREE (this_xl->name);
fuse_opt_free_args (&args);
FREE (fsname_opt);
if (priv)
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index 954032620..0bf8efd9d 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -16,7 +16,7 @@
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
-function _init ()
+_init ()
{
# log level definitions
LOG_NONE=NONE;
@@ -34,7 +34,7 @@ function _init ()
cmd_line=$(echo "@sbindir@/glusterfs");
}
-function start_glusterfs ()
+start_glusterfs ()
{
if [ -n "$log_level_str" ]; then
case "$log_level_str" in
@@ -115,7 +115,7 @@ function start_glusterfs ()
exec $cmd_line;
}
-function usage ()
+usage ()
{
echo "Usage: mount.glusterfs <volumeserver>:<volumeid/volumeport> -o <options> <mountpoint>
@@ -127,7 +127,7 @@ mount.glusterfs --version"
}
-function main ()
+main ()
{
helper=$(echo "$@" | sed -n 's/.*\--[ ]*\([^ ]*\).*/\1/p');
diff --git a/xlators/performance/Makefile.am b/xlators/performance/Makefile.am
index f7504bbe8..6b5facca5 100644
--- a/xlators/performance/Makefile.am
+++ b/xlators/performance/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = write-behind read-ahead io-threads io-cache symlink-cache
+SUBDIRS = write-behind read-ahead io-threads io-cache symlink-cache quick-read
CLEANFILES =
diff --git a/xlators/performance/quick-read/Makefile.am b/xlators/performance/quick-read/Makefile.am
new file mode 100644
index 000000000..d471a3f92
--- /dev/null
+++ b/xlators/performance/quick-read/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+CLEANFILES =
diff --git a/xlators/performance/quick-read/src/Makefile.am b/xlators/performance/quick-read/src/Makefile.am
new file mode 100644
index 000000000..644f27e3f
--- /dev/null
+++ b/xlators/performance/quick-read/src/Makefile.am
@@ -0,0 +1,14 @@
+xlator_LTLIBRARIES = quick-read.la
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
+
+quick_read_la_LDFLAGS = -module -avoidversion
+
+quick_read_la_SOURCES = quick-read.c
+quick_read_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
+
+noinst_HEADERS = quick-read.h
+
+AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
+ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
+
+CLEANFILES =
diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c
new file mode 100644
index 000000000..7bc912e3d
--- /dev/null
+++ b/xlators/performance/quick-read/src/quick-read.c
@@ -0,0 +1,2235 @@
+/*
+ Copyright (c) 2009-2010 Z RESEARCH, Inc. <http://www.zresearch.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "quick-read.h"
+
+int32_t
+qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset);
+
+
+static void
+qr_loc_wipe (loc_t *loc)
+{
+ if (loc == NULL) {
+ goto out;
+ }
+
+ if (loc->path) {
+ FREE (loc->path);
+ loc->path = NULL;
+ }
+
+ if (loc->inode) {
+ inode_unref (loc->inode);
+ loc->inode = NULL;
+ }
+
+ if (loc->parent) {
+ inode_unref (loc->parent);
+ loc->parent = NULL;
+ }
+
+out:
+ return;
+}
+
+
+static int32_t
+qr_loc_fill (loc_t *loc, inode_t *inode, char *path)
+{
+ int32_t ret = -1;
+ char *parent = NULL;
+
+ if ((loc == NULL) || (inode == NULL) || (path == NULL)) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ loc->inode = inode_ref (inode);
+ loc->path = strdup (path);
+ loc->ino = inode->ino;
+
+ parent = strdup (path);
+ if (parent == NULL) {
+ ret = -1;
+ goto out;
+ }
+
+ parent = dirname (parent);
+
+ loc->parent = inode_from_path (inode->table, parent);
+ if (loc->parent == NULL) {
+ ret = -1;
+ errno = EINVAL;
+ goto out;
+ }
+
+ loc->name = strrchr (loc->path, '/');
+ ret = 0;
+out:
+ if (ret == -1) {
+ qr_loc_wipe (loc);
+
+ }
+
+ if (parent) {
+ FREE (parent);
+ }
+
+ return ret;
+}
+
+
+void
+qr_resume_pending_ops (qr_fd_ctx_t *qr_fd_ctx)
+{
+ struct list_head waiting_ops;
+ call_stub_t *stub = NULL, *tmp = NULL;
+
+ if (qr_fd_ctx == NULL) {
+ goto out;
+ }
+
+ INIT_LIST_HEAD (&waiting_ops);
+
+ LOCK (&qr_fd_ctx->lock);
+ {
+ list_splice_init (&qr_fd_ctx->waiting_ops,
+ &waiting_ops);
+ }
+ UNLOCK (&qr_fd_ctx->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:
+ return;
+}
+
+
+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,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct stat *buf, dict_t *dict)
+{
+ data_t *content = NULL;
+ qr_file_t *qr_file = NULL;
+ uint64_t value = 0;
+ int ret = -1;
+ qr_conf_t *conf = NULL;
+
+ if ((op_ret == -1) || (dict == NULL)) {
+ goto out;
+ }
+
+ conf = this->private;
+
+ content = dict_get (dict, GLUSTERFS_CONTENT_KEY);
+ if (content == NULL) {
+ goto out;
+ }
+
+ if (buf->st_size > conf->max_file_size) {
+ goto out;
+ }
+
+ if (S_ISDIR (buf->st_mode)) {
+ goto out;
+ }
+
+ ret = inode_ctx_get (inode, this, &value);
+ if (ret == -1) {
+ qr_file = CALLOC (1, sizeof (*qr_file));
+ if (qr_file == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ LOCK_INIT (&qr_file->lock);
+ inode_ctx_put (inode, this, (uint64_t)(long)qr_file);
+ } else {
+ qr_file = (qr_file_t *)(long)value;
+ if (qr_file == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+ }
+
+ LOCK (&qr_file->lock);
+ {
+ if (qr_file->xattr) {
+ dict_unref (qr_file->xattr);
+ qr_file->xattr = NULL;
+ }
+
+ qr_file->xattr = dict_ref (dict);
+ qr_file->stbuf = *buf;
+ gettimeofday (&qr_file->tv, NULL);
+ }
+ UNLOCK (&qr_file->lock);
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, inode, buf, dict);
+ return 0;
+}
+
+
+int32_t
+qr_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)
+{
+ qr_conf_t *conf = NULL;
+ dict_t *new_req_dict = NULL;
+ int32_t op_ret = -1, op_errno = -1;
+ data_t *content = NULL;
+ uint64_t requested_size = 0, size = 0;
+
+ conf = this->private;
+ if (conf == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ if ((xattr_req == NULL) && (conf->max_file_size > 0)) {
+ new_req_dict = xattr_req = dict_new ();
+ if (xattr_req == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
+ }
+
+ if (xattr_req) {
+ content = dict_get (xattr_req, GLUSTERFS_CONTENT_KEY);
+ if (content) {
+ requested_size = data_to_uint64 (content);
+ }
+ }
+
+ if (((conf->max_file_size > 0) && (content == NULL))
+ || (conf->max_file_size != requested_size)) {
+ size = (conf->max_file_size > requested_size) ?
+ conf->max_file_size : requested_size;
+
+ op_ret = dict_set (xattr_req, GLUSTERFS_CONTENT_KEY,
+ data_from_uint64 (size));
+ if (op_ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto unwind;
+ }
+ }
+
+ STACK_WIND (frame, qr_lookup_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lookup, loc, xattr_req);
+
+ if (new_req_dict) {
+ dict_unref (new_req_dict);
+ }
+
+ return 0;
+
+unwind:
+ STACK_UNWIND (frame, op_ret, op_errno, NULL, NULL, NULL);
+
+ if (new_req_dict) {
+ dict_unref (new_req_dict);
+ }
+
+ return 0;
+}
+
+
+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;
+}
+
+
+static inline char
+qr_time_elapsed (struct timeval *now, struct timeval *then)
+{
+ return now->tv_sec - then->tv_sec;
+}
+
+
+static inline char
+qr_need_validation (qr_conf_t *conf, qr_file_t *file)
+{
+ struct timeval now = {0, };
+ char need_validation = 0;
+
+ gettimeofday (&now, NULL);
+
+ if (qr_time_elapsed (&now, &file->tv) >= conf->cache_timeout)
+ need_validation = 1;
+
+ return need_validation;
+}
+
+
+static int32_t
+qr_validate_cache_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ qr_file_t *qr_file = NULL;
+ qr_local_t *local = NULL;
+ uint64_t value = 0;
+ int32_t ret = 0;
+
+ if (op_ret == -1) {
+ goto unwind;
+ }
+
+ local = frame->local;
+ if ((local == NULL) || ((local->fd) == NULL)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ ret = inode_ctx_get (local->fd->inode, this, &value);
+ if (ret == -1) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ qr_file = (qr_file_t *)(long) value;
+ if (qr_file == NULL) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto unwind;
+ }
+
+ LOCK (&qr_file->lock);
+ {
+ if (qr_file->stbuf.st_mtime != buf->st_mtime) {
+ dict_unref (qr_file->xattr);
+ qr_file->xattr = NULL;
+ }
+
+ gettimeofday (&qr_file->tv, NULL);
+ }
+ UNLOCK (&qr_file->lock);
+
+ frame->local = NULL;
+
+ call_resume (local->stub);
+
+ FREE (local);
+ return 0;
+
+unwind:
+ /* this is actually unwind of readv */
+ STACK_UNWIND (frame, op_ret, op_errno, NULL, -1, NULL, NULL);
+ return 0;
+}
+
+
+int32_t
+qr_validate_cache_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ STACK_WIND (frame, qr_validate_cache_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ return 0;
+}
+
+
+int
+qr_validate_cache (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ call_stub_t *stub)
+{
+ int ret = -1;
+ int flags = 0;
+ uint64_t value = 0;
+ loc_t loc = {0, };
+ char *path = NULL;
+ qr_local_t *local = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ call_stub_t *validate_stub = NULL;
+ char need_open = 0, can_wind = 0;
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ goto out;
+ }
+
+ local->fd = fd;
+ local->stub = stub;
+ frame->local = local;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ validate_stub = fop_fstat_stub (frame,
+ qr_validate_cache_helper,
+ fd);
+ if (validate_stub == NULL) {
+ ret = -1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&validate_stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+
+ if (ret == -1) {
+ goto out;
+ }
+ } else {
+ can_wind = 1;
+ }
+
+ if (need_open) {
+ ret = qr_loc_fill (&loc, fd->inode, path);
+ if (ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open,
+ &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_validate_cache_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
+int32_t
+qr_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct iovec *vector, int32_t count,
+ struct stat *stbuf, struct iobref *iobref)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, vector, count, stbuf, iobref);
+ return 0;
+}
+
+
+int32_t
+qr_readv_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ STACK_WIND (frame, qr_readv_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readv, fd, size, offset);
+ return 0;
+}
+
+
+int32_t
+qr_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
+ off_t offset)
+{
+ qr_file_t *file = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ uint64_t value = 0;
+ int count = -1, flags = 0, i = 0;
+ char content_cached = 0, need_validation = 0;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+ struct iobuf *iobuf = NULL;
+ struct iobref *iobref = NULL;
+ struct stat stbuf = {0, };
+ data_t *content = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ call_stub_t *stub = NULL;
+ loc_t loc = {0, };
+ qr_conf_t *conf = NULL;
+ struct iovec *vector = NULL;
+ char *path = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ off_t start = 0, end = 0;
+ size_t len = 0;
+
+ op_ret = 0;
+ conf = this->private;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ ret = inode_ctx_get (fd->inode, this, &value);
+ if (ret == 0) {
+ file = (qr_file_t *)(long)value;
+ if (file) {
+ LOCK (&file->lock);
+ {
+ if (file->xattr){
+ if (qr_need_validation (conf,file)) {
+ need_validation = 1;
+ goto unlock;
+ }
+
+ content = dict_get (file->xattr,
+ GLUSTERFS_CONTENT_KEY);
+
+ content_cached = 1;
+ if (offset > content->len) {
+ op_ret = 0;
+ end = content->len;
+ } else {
+ if ((offset + size)
+ > content->len) {
+ op_ret = content->len - offset;
+ end = content->len;
+ } else {
+ op_ret = size;
+ end = offset + size;
+ }
+ }
+
+ ctx = glusterfs_ctx_get ();
+ count = (op_ret / ctx->page_size) + 1;
+ vector = CALLOC (count,
+ sizeof (*vector));
+ if (vector == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ goto unlock;
+ }
+
+ iobref = iobref_new ();
+ if (iobref == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ goto unlock;
+ }
+
+ for (i = 0; i < count; i++) {
+ iobuf = iobuf_get (this->ctx->iobuf_pool);
+ if (iobuf == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ goto unlock;
+ }
+
+ start = offset + ctx->page_size * i;
+ if (start > end) {
+ len = 0;
+ } else {
+ len = (ctx->page_size
+ > (end - start))
+ ? (end - start)
+ : ctx->page_size;
+
+ memcpy (iobuf->ptr,
+ content->data + start,
+ len);
+ }
+
+ iobref_add (iobref, iobuf);
+ iobuf_unref (iobuf);
+
+ vector[i].iov_base = iobuf->ptr;
+ vector[i].iov_len = len;
+ }
+
+ stbuf = file->stbuf;
+ }
+ }
+ unlock:
+ UNLOCK (&file->lock);
+ }
+ }
+
+out:
+ if (content_cached || need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, vector, count, &stbuf,
+ iobref);
+
+ } else if (need_validation) {
+ stub = fop_readv_stub (frame, qr_readv, fd, size, offset);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ op_ret = qr_validate_cache (frame, this, fd, stub);
+ if (op_ret == -1) {
+ need_unwind = 1;
+ op_errno = errno;
+ call_stub_destroy (stub);
+ goto out;
+ }
+ } else {
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_readv_stub (frame,
+ qr_readv_helper,
+ fd, size,
+ offset);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto fdctx_unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ fdctx_unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+
+ if (op_ret == -1) {
+ need_unwind = 1;
+ goto out;
+ }
+ } else {
+ can_wind = 1;
+ }
+
+ if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open,
+ &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_readv_cbk,
+ FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->readv, fd, size,
+ offset);
+ }
+
+ }
+
+ if (vector) {
+ FREE (vector);
+ }
+
+ if (iobref) {
+ iobref_unref (iobref);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *stbuf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, stbuf);
+ return 0;
+}
+
+
+int32_t
+qr_writev_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ struct iovec *vector, int32_t count, off_t off,
+ struct iobref *iobref)
+{
+ STACK_WIND (frame, qr_writev_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->writev, fd, vector, count, off,
+ iobref);
+ return 0;
+}
+
+
+int32_t
+qr_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
+ int32_t count, off_t off, struct iobref *iobref)
+{
+ uint64_t value = 0;
+ int flags = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_file_t *qr_file = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t op_ret = -1, op_errno = -1, ret = -1;
+ char can_wind = 0, need_unwind = 0, need_open = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ 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);
+ {
+ if (qr_file->xattr) {
+ dict_unref (qr_file->xattr);
+ qr_file->xattr = NULL;
+ }
+ }
+ UNLOCK (&qr_file->lock);
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_writev_stub (frame, qr_writev_helper,
+ fd, vector, count, off,
+ iobref);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_writev_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->writev, fd, vector, count,
+ off, iobref);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+
+int32_t
+qr_fstat_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ STACK_WIND (frame, qr_fstat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ return 0;
+}
+
+
+int32_t
+qr_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+ uint64_t value = 0;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ call_stub_t *stub = NULL;
+ loc_t loc = {0, };
+ char *path = NULL;
+ int flags = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fstat_stub (frame, qr_fstat_helper,
+ fd);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_fstat_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fstat, fd);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+static int32_t
+qr_fchown_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+
+int32_t
+qr_fchown_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, uid_t uid,
+ gid_t gid)
+{
+ STACK_WIND (frame, qr_fchown_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fchown, fd, uid, gid);
+ return 0;
+}
+
+
+int32_t
+qr_fchown (call_frame_t *frame, xlator_t *this, fd_t *fd, uid_t uid, gid_t gid)
+{
+ uint64_t value = 0;
+ int flags = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fchown_stub (frame, qr_fchown_helper,
+ fd, uid, gid);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_fchown_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fchown, fd, uid, gid);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_fchmod_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+
+int32_t
+qr_fchmod_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, mode_t mode)
+{
+ STACK_WIND(frame, qr_fchmod_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fchmod, fd, mode);
+ return 0;
+}
+
+
+int32_t
+qr_fchmod (call_frame_t *frame, xlator_t *this, fd_t *fd, mode_t mode)
+{
+ uint64_t value = 0;
+ int flags = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fchmod_stub (frame, qr_fchmod_helper,
+ fd, mode);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_fchmod_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fchmod, fd, mode);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+qr_fsetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, int32_t flags)
+{
+ STACK_WIND (frame, qr_fsetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetxattr, fd, dict, flags);
+ return 0;
+}
+
+
+int32_t
+qr_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
+ int32_t flags)
+{
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ int open_flags = 0;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ open_flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fsetxattr_stub (frame,
+ qr_fsetxattr_helper,
+ fd, dict, flags);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_fsetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsetxattr, fd, dict,
+ flags);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, open_flags,
+ fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *dict)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, dict);
+ return 0;
+}
+
+
+int32_t
+qr_fgetxattr_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name)
+{
+ STACK_WIND (frame, qr_fgetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fgetxattr, fd, name);
+ return 0;
+}
+
+
+int32_t
+qr_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ /*
+ * FIXME: Can quick-read use the extended attributes stored in the
+ * cache? this needs to be discussed.
+ */
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fgetxattr_stub (frame,
+ qr_fgetxattr_helper,
+ fd, name);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_fgetxattr_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fgetxattr, fd, name);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+qr_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ STACK_WIND (frame, qr_flush_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->flush, fd);
+ return 0;
+}
+
+
+int32_t
+qr_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else if (qr_fd_ctx->open_in_transit) {
+ stub = fop_flush_stub (frame, qr_flush_helper,
+ fd);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ } else {
+ op_ret = 0;
+ need_unwind = 1;
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ op_ret = 0;
+ need_unwind = 1;
+ }
+
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_flush_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->flush, fd);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_fentrylk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+int32_t
+qr_fentrylk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, const char *basename, entrylk_cmd cmd,
+ entrylk_type type)
+{
+ STACK_WIND(frame, qr_fentrylk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fentrylk, volume, fd, basename,
+ cmd, type);
+ return 0;
+}
+
+
+int32_t
+qr_fentrylk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
+ const char *basename, entrylk_cmd cmd, entrylk_type type)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fentrylk_stub (frame,
+ qr_fentrylk_helper,
+ volume, fd, basename,
+ cmd, type);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_fentrylk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fentrylk, volume, fd,
+ basename, cmd, type);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_finodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno)
+
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+qr_finodelk_helper (call_frame_t *frame, xlator_t *this, const char *volume,
+ fd_t *fd, int32_t cmd, struct flock *lock)
+{
+ STACK_WIND (frame, qr_finodelk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->finodelk, volume, fd, cmd, lock);
+ return 0;
+}
+
+
+int32_t
+qr_finodelk (call_frame_t *frame, xlator_t *this, const char *volume, fd_t *fd,
+ int32_t cmd, struct flock *lock)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_finodelk_stub (frame,
+ qr_finodelk_helper,
+ volume, fd, cmd,
+ lock);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_finodelk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->finodelk, volume, fd,
+ cmd, lock);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno)
+{
+ STACK_UNWIND (frame, op_ret, op_errno);
+ return 0;
+}
+
+
+int32_t
+qr_fsync_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+{
+ STACK_WIND (frame, qr_fsync_cbk, FIRST_CHILD (this),
+ FIRST_CHILD(this)->fops->fsync, fd, flags);
+ return 0;
+}
+
+int32_t
+qr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t flags)
+{
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ int open_flags = 0;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ open_flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_fsync_stub (frame, qr_fsync_helper,
+ fd, flags);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_fsync_cbk, FIRST_CHILD (this),
+ FIRST_CHILD (this)->fops->fsync, fd, flags);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, open_flags,
+ fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct stat *buf)
+{
+ int32_t ret = 0;
+ uint64_t value = 0;
+ qr_file_t *qr_file = NULL;
+ qr_local_t *local = NULL;
+
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ local = frame->local;
+ if ((local == NULL) || (local->fd == NULL)
+ || (local->fd->inode == NULL)) {
+ op_ret = -1;
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ ret = inode_ctx_get (local->fd->inode, this, &value);
+ if (ret == 0) {
+ qr_file = (qr_file_t *)(long) value;
+
+ if (qr_file) {
+ LOCK (&qr_file->lock);
+ {
+ if (qr_file->stbuf.st_size != buf->st_size) {
+ dict_unref (qr_file->xattr);
+ qr_file->xattr = NULL;
+ }
+ }
+ UNLOCK (&qr_file->lock);
+ }
+ }
+
+out:
+ STACK_UNWIND (frame, op_ret, op_errno, buf);
+ return 0;
+}
+
+
+int32_t
+qr_ftruncate_helper (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ off_t offset)
+{
+ STACK_WIND (frame, qr_ftruncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ return 0;
+}
+
+
+int32_t
+qr_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_local_t *local = NULL;
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ local = CALLOC (1, sizeof (*local));
+ if (local == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ goto out;
+ }
+
+ local->fd = fd;
+ frame->local = local;
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_ftruncate_stub (frame,
+ qr_ftruncate_helper,
+ fd, offset);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_ftruncate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->ftruncate, fd, offset);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
+ int32_t op_errno, struct flock *lock)
+{
+ STACK_UNWIND (frame, op_ret, op_errno, lock);
+ return 0;
+}
+
+
+int32_t
+qr_lk_helper (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct flock *lock)
+{
+ STACK_WIND (frame, qr_lk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
+
+ return 0;
+}
+
+
+int32_t
+qr_lk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd,
+ struct flock *lock)
+{
+ int flags = 0;
+ uint64_t value = 0;
+ call_stub_t *stub = NULL;
+ char *path = NULL;
+ loc_t loc = {0, };
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = -1, op_ret = -1, op_errno = -1;
+ char need_open = 0, can_wind = 0, need_unwind = 0;
+
+ ret = fd_ctx_get (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long)value;
+ }
+
+ if (qr_fd_ctx) {
+ LOCK (&qr_fd_ctx->lock);
+ {
+ path = qr_fd_ctx->path;
+ flags = qr_fd_ctx->flags;
+
+ if (!(qr_fd_ctx->opened
+ || qr_fd_ctx->open_in_transit)) {
+ need_open = 1;
+ qr_fd_ctx->open_in_transit = 1;
+ }
+
+ if (qr_fd_ctx->opened) {
+ can_wind = 1;
+ } else {
+ stub = fop_lk_stub (frame, qr_lk_helper, fd,
+ cmd, lock);
+ if (stub == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ need_unwind = 1;
+ qr_fd_ctx->open_in_transit = 0;
+ goto unlock;
+ }
+
+ list_add_tail (&stub->list,
+ &qr_fd_ctx->waiting_ops);
+ }
+ }
+ unlock:
+ UNLOCK (&qr_fd_ctx->lock);
+ } else {
+ can_wind = 1;
+ }
+
+out:
+ if (need_unwind) {
+ STACK_UNWIND (frame, op_ret, op_errno, NULL);
+ } else if (can_wind) {
+ STACK_WIND (frame, qr_lk_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->lk, fd, cmd, lock);
+ } else if (need_open) {
+ op_ret = qr_loc_fill (&loc, fd->inode, path);
+ if (op_ret == -1) {
+ qr_resume_pending_ops (qr_fd_ctx);
+ goto out;
+ }
+
+ STACK_WIND (frame, qr_open_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->open, &loc, flags, fd);
+
+ qr_loc_wipe (&loc);
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_release (xlator_t *this, fd_t *fd)
+{
+ qr_fd_ctx_t *qr_fd_ctx = NULL;
+ int32_t ret = 0;
+ uint64_t value = 0;
+
+ ret = fd_ctx_del (fd, this, &value);
+ if (ret == 0) {
+ qr_fd_ctx = (qr_fd_ctx_t *)(long) value;
+ if (qr_fd_ctx) {
+ qr_fd_ctx_free (qr_fd_ctx);
+ }
+ }
+
+ return 0;
+}
+
+
+int32_t
+qr_forget (xlator_t *this, inode_t *inode)
+{
+ qr_file_t *qr_file = NULL;
+ uint64_t value = 0;
+ int32_t ret = -1;
+
+ ret = inode_ctx_del (inode, this, &value);
+ if (ret == 0) {
+ qr_file = (qr_file_t *)(long) value;
+ if (qr_file) {
+ LOCK (&qr_file->lock);
+ {
+ if (qr_file->xattr) {
+ dict_unref (qr_file->xattr);
+ qr_file->xattr = NULL;
+ }
+ }
+ UNLOCK (&qr_file->lock);
+ }
+
+ FREE (qr_file);
+ }
+
+ return 0;
+}
+
+
+int32_t
+init (xlator_t *this)
+{
+ char *str = NULL;
+ int32_t ret = -1;
+ qr_conf_t *conf = NULL;
+
+ if (!this->children || this->children->next) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "FATAL: volume (%s) not configured with exactly one "
+ "child", this->name);
+ return -1;
+ }
+
+ if (!this->parents) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "dangling volume. check volfile ");
+ }
+
+ conf = CALLOC (1, sizeof (*conf));
+ if (conf == NULL) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_get_str (this->options, "max-file-size",
+ &str);
+ if (ret == 0) {
+ ret = gf_string2bytesize (str, &conf->max_file_size);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid number format \"%s\" of \"option "
+ "max-file-size\"",
+ str);
+ ret = -1;
+ goto out;
+ }
+ }
+
+ conf->cache_timeout = -1;
+ ret = dict_get_str (this->options, "cache-timeout", &str);
+ if (ret == 0) {
+ ret = gf_string2uint_base10 (str,
+ (unsigned int *)&conf->cache_timeout);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid cache-timeout value %s", str);
+ ret = -1;
+ goto out;
+ }
+ }
+
+ this->private = conf;
+out:
+ if ((ret == -1) && conf) {
+ FREE (conf);
+ }
+
+ return ret;
+}
+
+
+void
+fini (xlator_t *this)
+{
+ return;
+}
+
+
+struct xlator_fops fops = {
+ .lookup = qr_lookup,
+ .open = qr_open,
+ .readv = qr_readv,
+ .writev = qr_writev,
+ .fstat = qr_fstat,
+ .fchown = qr_fchown,
+ .fchmod = qr_fchmod,
+ .fsetxattr = qr_fsetxattr,
+ .fgetxattr = qr_fgetxattr,
+ .flush = qr_flush,
+ .fentrylk = qr_fentrylk,
+ .finodelk = qr_finodelk,
+ .fsync = qr_fsync,
+ .ftruncate = qr_ftruncate,
+ .lk = qr_lk,
+};
+
+
+struct xlator_mops mops = {
+};
+
+
+struct xlator_cbks cbks = {
+ .forget = qr_forget,
+ .release = qr_release,
+};
+
+struct volume_options options[] = {
+ { .key = {"cache-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .min = 1,
+ .max = 60
+ },
+ { .key = {"max-file-size"},
+ .type = GF_OPTION_TYPE_SIZET,
+ .min = 0,
+ .max = 1 * GF_UNIT_MB
+ },
+};
diff --git a/xlators/performance/quick-read/src/quick-read.h b/xlators/performance/quick-read/src/quick-read.h
new file mode 100644
index 000000000..32bebac48
--- /dev/null
+++ b/xlators/performance/quick-read/src/quick-read.h
@@ -0,0 +1,78 @@
+/*
+ Copyright (c) 2009-2010 Z RESEARCH, Inc. <http://www.zresearch.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __QUICK_READ_H
+#define __QUICK_READ_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glusterfs.h"
+#include "logging.h"
+#include "dict.h"
+#include "xlator.h"
+#include "list.h"
+#include "compat.h"
+#include "compat-errno.h"
+#include "common-utils.h"
+#include "call-stub.h"
+#include "defaults.h"
+#include <libgen.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#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;
+ struct timeval tv;
+ gf_lock_t lock;
+};
+typedef struct qr_file qr_file_t;
+
+struct qr_conf {
+ uint64_t max_file_size;
+ int32_t cache_timeout;
+};
+typedef struct qr_conf qr_conf_t;
+
+#endif /* #ifndef __QUICK_READ_H */
diff --git a/xlators/protocol/server/src/server-protocol.c b/xlators/protocol/server/src/server-protocol.c
index f0dd2e88e..7862ea47b 100644
--- a/xlators/protocol/server/src/server-protocol.c
+++ b/xlators/protocol/server/src/server-protocol.c
@@ -5627,8 +5627,7 @@ server_inodelk (call_frame_t *frame, xlator_t *bound_xl,
state->volume, &state->loc,
state->cmd, &state->flock);
- if ((state->loc.parent == NULL) ||
- (state->loc.inode == NULL)) {
+ if (state->loc.inode == NULL) {
do_path_lookup (inodelk_stub, &(state->loc));
} else {
call_resume (inodelk_stub);
@@ -5786,8 +5785,7 @@ server_entrylk (call_frame_t *frame, xlator_t *bound_xl,
state->volume, &state->loc,
state->name, state->cmd, state->type);
- if (((state->loc.parent == NULL) && IS_NOT_ROOT(pathlen)) ||
- (state->loc.inode == NULL)) {
+ if (state->loc.inode == NULL) {
do_path_lookup (entrylk_stub, &(state->loc));
} else {
call_resume (entrylk_stub);