summaryrefslogtreecommitdiffstats
path: root/xlators/features
diff options
context:
space:
mode:
authorJeff Darcy <jdarcy@redhat.com>2014-01-21 13:49:08 +0000
committerJeff Darcy <jdarcy@redhat.com>2014-01-21 13:49:08 +0000
commit6bcbf03b5aa4448832645a29ec2bc4b2fc5f2eaf (patch)
tree750f73a40aa62c20d66a2532fef6fd158cebb9c4 /xlators/features
parent0225d7bc712609232d592d48116ec771cd97c2cf (diff)
parent17c4fb2d04f84b5632983866e8bddfbd7d77a054 (diff)
Merge branch 'upstream'
Conflicts: api/src/glfs-fops.c api/src/glfs-handleops.c Change-Id: I6811674cc4ec4be6fa6e4cdebb4bc428194bebd8
Diffstat (limited to 'xlators/features')
-rw-r--r--xlators/features/changelog/lib/src/Makefile.am2
-rw-r--r--xlators/features/locks/src/posix.c3
-rw-r--r--xlators/features/marker/src/marker.c143
-rw-r--r--xlators/features/qemu-block/src/bdrv-xlator.c15
-rw-r--r--xlators/features/qemu-block/src/qb-coroutines.c15
-rw-r--r--xlators/features/quota/src/quota.c105
-rw-r--r--xlators/features/quota/src/quota.h3
7 files changed, 243 insertions, 43 deletions
diff --git a/xlators/features/changelog/lib/src/Makefile.am b/xlators/features/changelog/lib/src/Makefile.am
index fbaaea628..775f026cf 100644
--- a/xlators/features/changelog/lib/src/Makefile.am
+++ b/xlators/features/changelog/lib/src/Makefile.am
@@ -9,7 +9,7 @@ libgfchangelog_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 -fpic \
libgfchangelog_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(GF_GLUSTERFS_LIBS)
-libgfchangelog_la_LDFLAGS = $(GF_LDFLAGS)
+libgfchangelog_la_LDFLAGS = $(GF_LDFLAGS) -version-info $(LIBGFCHANGELOG_LT_VERSION)
libgfchangelogdir = $(includedir)/glusterfs/gfchangelog
lib_LTLIBRARIES = libgfchangelog.la
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c
index fce0d509f..2db327687 100644
--- a/xlators/features/locks/src/posix.c
+++ b/xlators/features/locks/src/posix.c
@@ -552,7 +552,8 @@ fetch_pathinfo (xlator_t *this, inode_t *inode, int32_t *op_errno,
ret = syncop_getxattr (FIRST_CHILD(this), &loc, &dict,
GF_XATTR_PATHINFO_KEY);
if (ret < 0) {
- *op_errno = errno;
+ *op_errno = -ret;
+ ret = -1;
goto out;
}
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
index 280d43ae3..d6b6dd358 100644
--- a/xlators/features/marker/src/marker.c
+++ b/xlators/features/marker/src/marker.c
@@ -21,6 +21,7 @@
#include "marker-quota-helper.h"
#include "marker-common.h"
#include "byte-order.h"
+#include "syncop.h"
#define _GF_UID_GID_CHANGED 1
@@ -2153,16 +2154,150 @@ out:
return 0;
}
+int
+remove_quota_keys (dict_t *dict, char *k, data_t *v, void *data)
+{
+ call_frame_t *frame = data;
+ marker_local_t *local = frame->local;
+ xlator_t *this = frame->this;
+ int ret = -1;
+
+ ret = syncop_removexattr (FIRST_CHILD (this), &local->loc, k);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "%s: Failed to remove "
+ "extended attribute: %s", local->loc.path, k);
+ return -1;
+ }
+ return 0;
+}
+
+int
+quota_xattr_cleaner_cbk (int ret, call_frame_t *frame, void *args)
+{
+ dict_t *xdata = args;
+ int op_ret = -1;
+ int op_errno = 0;
+ marker_local_t *local = NULL;
+
+ local = frame->local;
+ frame->local = NULL;
+
+ op_ret = (ret < 0)? -1: 0;
+ op_errno = -ret;
+
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, xdata);
+ marker_local_unref (local);
+ return ret;
+}
+
+int
+quota_xattr_cleaner (void *args)
+{
+ struct synctask *task = NULL;
+ call_frame_t *frame = NULL;
+ xlator_t *this = NULL;
+ marker_local_t *local = NULL;
+ dict_t *xdata = NULL;
+ int ret = -1;
+
+ task = synctask_get ();
+ if (!task)
+ goto out;
+
+ frame = task->frame;
+ this = frame->this;
+ local = frame->local;
+
+ ret = syncop_listxattr (FIRST_CHILD(this), &local->loc, &xdata);
+ if (ret == -1) {
+ ret = -errno;
+ goto out;
+ }
+
+ ret = dict_foreach_fnmatch (xdata, "trusted.glusterfs.quota.*",
+ remove_quota_keys, frame);
+ if (ret == -1) {
+ ret = -errno;
+ goto out;
+ }
+ ret = dict_foreach_fnmatch (xdata, PGFID_XATTR_KEY_PREFIX"*",
+ remove_quota_keys, frame);
+ if (ret == -1) {
+ ret = -errno;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (xdata)
+ dict_unref (xdata);
+
+ return ret;
+}
+
+int
+marker_do_xattr_cleanup (call_frame_t *frame, xlator_t *this, dict_t *xdata,
+ loc_t *loc)
+{
+ int ret = -1;
+ marker_local_t *local = NULL;
+
+ local = mem_get0 (this->local_pool);
+ if (!local)
+ goto out;
+
+ MARKER_INIT_LOCAL (frame, local);
+
+ loc_copy (&local->loc, loc);
+ ret = synctask_new (this->ctx->env, quota_xattr_cleaner,
+ quota_xattr_cleaner_cbk, frame, xdata);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to create synctask "
+ "for cleaning up quota extended attributes");
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (ret) {
+ frame->local = NULL;
+ STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM, xdata);
+ marker_local_unref (local);
+ }
+ return ret;
+}
+
+static inline gf_boolean_t
+marker_xattr_cleanup_cmd (dict_t *dict)
+{
+ return (dict_get (dict, VIRTUAL_QUOTA_XATTR_CLEANUP_KEY) != NULL);
+}
+
int32_t
marker_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
int32_t flags, dict_t *xdata)
{
- int32_t ret = 0;
- marker_local_t *local = NULL;
- marker_conf_t *priv = NULL;
+ int32_t ret = 0;
+ marker_local_t *local = NULL;
+ marker_conf_t *priv = NULL;
+ int op_errno = ENOMEM;
priv = this->private;
+ if (marker_xattr_cleanup_cmd (dict)) {
+ if (frame->root->uid != 0 || frame->root->gid != 0) {
+ op_errno = EPERM;
+ ret = -1;
+ goto err;
+ }
+
+ /* The following function does the cleanup and then unwinds the
+ * corresponding call*/
+ loc_path (loc, NULL);
+ marker_do_xattr_cleanup (frame, this, xdata, loc);
+ return 0;
+ }
+
if (priv->feature_enabled == 0)
goto wind;
@@ -2183,7 +2318,7 @@ wind:
FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
return 0;
err:
- STACK_UNWIND_STRICT (setxattr, frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno, NULL);
return 0;
}
diff --git a/xlators/features/qemu-block/src/bdrv-xlator.c b/xlators/features/qemu-block/src/bdrv-xlator.c
index 106c59775..aaf028cfe 100644
--- a/xlators/features/qemu-block/src/bdrv-xlator.c
+++ b/xlators/features/qemu-block/src/bdrv-xlator.c
@@ -109,7 +109,7 @@ qemu_gluster_open (BlockDriverState *bs, QDict *options, int bdrv_flags)
NULL);
if (ret) {
loc_wipe(&loc);
- return -errno;
+ return ret;
}
s->inode = inode_ref(loc.inode);
@@ -153,7 +153,7 @@ qemu_gluster_create (const char *filename, QEMUOptionParameter *options)
ret = syncop_fstat (FIRST_CHILD(THIS), fd, &stat);
if (ret) {
fd_unref (fd);
- return -errno;
+ return ret;
}
if (stat.ia_size) {
@@ -166,7 +166,7 @@ qemu_gluster_create (const char *filename, QEMUOptionParameter *options)
ret = syncop_ftruncate (FIRST_CHILD(THIS), fd, total_size);
if (ret) {
fd_unref (fd);
- return -errno;
+ return ret;
}
}
@@ -196,10 +196,8 @@ qemu_gluster_co_readv (BlockDriverState *bs, int64_t sector_num, int nb_sectors,
ret = syncop_readv (FIRST_CHILD(THIS), fd, size, offset, 0,
&iov, &count, &iobref);
- if (ret < 0) {
- ret = -errno;
+ if (ret < 0)
goto out;
- }
iov_copy (qiov->iov, qiov->niov, iov, count); /* *choke!* */
@@ -249,8 +247,6 @@ qemu_gluster_co_writev (BlockDriverState *bs, int64_t sector_num, int nb_sectors
iov.iov_len = size;
ret = syncop_writev (FIRST_CHILD(THIS), fd, &iov, 1, offset, iobref, 0);
- if (ret < 0)
- ret = -errno;
out:
if (iobuf)
@@ -306,9 +302,6 @@ qemu_gluster_truncate (BlockDriverState *bs, int64_t offset)
fd_unref (fd);
- if (ret < 0)
- return ret;
-
return ret;
}
diff --git a/xlators/features/qemu-block/src/qb-coroutines.c b/xlators/features/qemu-block/src/qb-coroutines.c
index 7c52adb21..974312f12 100644
--- a/xlators/features/qemu-block/src/qb-coroutines.c
+++ b/xlators/features/qemu-block/src/qb-coroutines.c
@@ -86,7 +86,7 @@ qb_format_and_resume (void *opaque)
GF_FREE(qb_inode->backing_fname);
if (ret) {
loc_wipe(&loc);
- ret = errno;
+ ret = -ret;
goto err;
}
@@ -150,11 +150,10 @@ qb_format_and_resume (void *opaque)
ret = syncop_fsetxattr (FIRST_CHILD(THIS), fd, xattr, 0);
if (ret) {
- ret = errno;
gf_log (frame->this->name, GF_LOG_ERROR,
"failed to setxattr for %s",
uuid_utoa (inode->gfid));
- QB_STUB_UNWIND (stub, -1, ret);
+ QB_STUB_UNWIND (stub, -1, -ret);
fd_unref (fd);
dict_unref (xattr);
return 0;
@@ -476,7 +475,10 @@ qb_co_truncate (void *opaque)
}
}
- syncop_fstat (FIRST_CHILD(this), local->fd, &stub->args_cbk.prestat);
+ ret = syncop_fstat (FIRST_CHILD(this), local->fd,
+ &stub->args_cbk.prestat);
+ if (ret < 0)
+ goto out;
stub->args_cbk.prestat.ia_size = qb_inode->size;
ret = bdrv_truncate (qb_inode->bs, stub->args.offset);
@@ -487,7 +489,10 @@ qb_co_truncate (void *opaque)
qb_inode->size = offset;
- syncop_fstat (FIRST_CHILD(this), local->fd, &stub->args_cbk.poststat);
+ ret = syncop_fstat (FIRST_CHILD(this), local->fd,
+ &stub->args_cbk.poststat);
+ if (ret < 0)
+ goto out;
stub->args_cbk.poststat.ia_size = qb_inode->size;
qb_update_size_xattr (this, local->fd, qb_inode->fmt, qb_inode->size);
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c
index a531ab123..5cbd9f02d 100644
--- a/xlators/features/quota/src/quota.c
+++ b/xlators/features/quota/src/quota.c
@@ -879,8 +879,7 @@ quota_fill_inodectx (xlator_t *this, inode_t *inode, dict_t *dict,
ctx = (quota_inode_ctx_t *)(unsigned long)value;
if ((((ctx == NULL) || (ctx->hard_lim == hard_lim))
- && (hard_lim < 0) && !((IA_ISREG (buf->ia_type))
- || (IA_ISLNK (buf->ia_type))))) {
+ && (hard_lim < 0) && !QUOTA_REG_OR_LNK_FILE (buf->ia_type))) {
ret = 0;
goto out;
}
@@ -902,7 +901,7 @@ quota_fill_inodectx (xlator_t *this, inode_t *inode, dict_t *dict,
ctx->buf = *buf;
- if (!(IA_ISREG (buf->ia_type) || IA_ISLNK (buf->ia_type))) {
+ if (!QUOTA_REG_OR_LNK_FILE (buf->ia_type)) {
goto unlock;
}
@@ -1869,8 +1868,7 @@ quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto out;
}
- if (IA_ISREG (local->oldloc.inode->ia_type)
- || IA_ISLNK (local->oldloc.inode->ia_type)) {
+ if (QUOTA_REG_OR_LNK_FILE (local->oldloc.inode->ia_type)) {
size = buf->ia_blocks * 512;
}
@@ -1881,8 +1879,7 @@ quota_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
size);
}
- if (!(IA_ISREG (local->oldloc.inode->ia_type)
- || IA_ISLNK (local->oldloc.inode->ia_type))) {
+ if (!QUOTA_REG_OR_LNK_FILE (local->oldloc.inode->ia_type)) {
goto out;
}
@@ -1997,6 +1994,46 @@ unwind:
}
+static int32_t
+quota_rename_get_size_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, inode_t *inode,
+ struct iatt *buf, dict_t *xdata,
+ struct iatt *postparent)
+{
+ quota_local_t *local = NULL;
+ int32_t ret = 0;
+ int64_t *size = 0;
+
+ GF_ASSERT (frame);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR ("quota", this, out, op_errno,
+ EINVAL);
+ GF_VALIDATE_OR_GOTO_WITH_ERROR (this->name, xdata, out, op_errno,
+ EINVAL);
+ local = frame->local;
+ GF_ASSERT (local);
+ local->link_count = 1;
+
+ if (op_ret < 0)
+ goto out;
+
+
+ ret = dict_get_bin (xdata, QUOTA_SIZE_KEY, (void **) &size);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "size key not present in dict");
+ op_errno = EINVAL;
+ goto out;
+ }
+ local->delta = ntoh64 (*size);
+ quota_check_limit (frame, local->newloc.parent, this,
+ NULL, NULL);
+ return 0;
+
+out:
+ quota_handle_validate_error (local, -1, op_errno);
+ return 0;
+}
+
int32_t
quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
loc_t *newloc, dict_t *xdata)
@@ -2039,8 +2076,7 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
local->link_count = 1;
local->stub = stub;
- if (IA_ISREG (oldloc->inode->ia_type)
- || IA_ISLNK (oldloc->inode->ia_type)) {
+ if (QUOTA_REG_OR_LNK_FILE (oldloc->inode->ia_type)) {
ret = quota_inode_ctx_get (oldloc->inode, this, &ctx, 0);
if (ctx == NULL) {
gf_log (this->name, GF_LOG_WARNING,
@@ -2050,11 +2086,32 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
oldloc->inode ? uuid_utoa (oldloc->inode->gfid)
: "0");
local->delta = 0;
+
} else {
- local->delta = ctx->buf.ia_blocks * 512;
+
+ /* FIXME: We need to account for the size occupied by this
+ * inode on the target directory. To avoid double
+ * accounting, we need to modify enforcer to perform
+ * quota_check_limit only uptil the least common ancestor
+ * directory inode*/
+
+ /* FIXME: The following code assumes that regular files and
+ *linkfiles are present, in their entirety, in a single
+ brick. This *assumption is invalid in the case of
+ stripe.*/
+
+ local->delta = ctx->buf.ia_blocks * 512;
}
- } else {
- local->delta = 0;
+
+ } else if (IA_ISDIR (oldloc->inode->ia_type)) {
+ ret = quota_validate (frame, oldloc->inode, this,
+ quota_rename_get_size_cbk);
+ if (ret){
+ op_errno = -ret;
+ goto err;
+ }
+
+ return 0;
}
quota_check_limit (frame, newloc->parent, this, NULL, NULL);
@@ -3461,13 +3518,13 @@ quota_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (ctx->hard_lim <= 0) {
inode_ctx_get (inode->table->root, this, &value);
ctx = (quota_inode_ctx_t *)(unsigned long) value;
- if (!ctx)
+ if (!ctx || ctx->hard_lim < 0)
goto unwind;
}
- usage = (ctx->size) / buf->f_bsize;
+ { /* statfs is adjusted in this code block */
+ usage = (ctx->size) / buf->f_bsize;
- if (ctx->hard_lim > 0) {
blocks = ctx->hard_lim / buf->f_bsize;
buf->f_blocks = blocks;
@@ -3935,7 +3992,7 @@ wind:
/* Logs if
* i. Usage crossed soft limit
-* ii. Usage above soft limit and alert-time timed out
+* ii. Usage above soft limit and alert-time elapsed
*/
void
quota_log_usage (xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode,
@@ -3943,39 +4000,45 @@ quota_log_usage (xlator_t *this, quota_inode_ctx_t *ctx, inode_t *inode,
{
struct timeval cur_time = {0,};
char *usage_str = NULL;
+ char size_str[32] = {0};
char *path = NULL;
int64_t cur_size = 0;
quota_priv_t *priv = NULL;
priv = this->private;
- cur_size = ctx->size + delta;
if ((ctx->soft_lim <= 0) || (timerisset (&ctx->prev_log) &&
!quota_timeout (&ctx->prev_log,
priv->log_timeout))) {
return;
}
- gettimeofday (&cur_time, NULL);
- ctx->prev_log = cur_time;
+ cur_size = ctx->size + delta;
usage_str = gf_uint64_2human_readable (cur_size);
+ if (!usage_str) {
+ snprintf (size_str, sizeof (size_str), "%"PRId64, cur_size);
+ usage_str = (char*) size_str;
+ }
inode_path (inode, NULL, &path);
if (!path)
path = uuid_utoa (inode->gfid);
+ gettimeofday (&cur_time, NULL);
/* Usage crossed/reached soft limit */
if (DID_REACH_LIMIT (ctx->soft_lim, ctx->size, cur_size)) {
gf_log (this->name, GF_LOG_ALERT, "Usage crossed "
"soft limit: %s used by %s", usage_str, path);
+ ctx->prev_log = cur_time;
}
/* Usage is above soft limit */
else if (cur_size > ctx->soft_lim){
gf_log (this->name, GF_LOG_ALERT, "Usage is above "
"soft limit: %s used by %s", usage_str, path);
+ ctx->prev_log = cur_time;
}
- if (usage_str)
- GF_FREE (usage_str);
+
+ GF_FREE (usage_str);
}
int32_t
diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h
index 96c19e77e..02bc0d8b6 100644
--- a/xlators/features/quota/src/quota.h
+++ b/xlators/features/quota/src/quota.h
@@ -130,6 +130,9 @@
goto label; \
} while (0)
+#define QUOTA_REG_OR_LNK_FILE(ia_type) \
+ (IA_ISREG (ia_type) || IA_ISLNK (ia_type))
+
struct quota_dentry {