diff options
author | Jeff Darcy <jdarcy@redhat.com> | 2014-01-21 13:49:08 +0000 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2014-01-21 13:49:08 +0000 |
commit | 6bcbf03b5aa4448832645a29ec2bc4b2fc5f2eaf (patch) | |
tree | 750f73a40aa62c20d66a2532fef6fd158cebb9c4 /xlators/features | |
parent | 0225d7bc712609232d592d48116ec771cd97c2cf (diff) | |
parent | 17c4fb2d04f84b5632983866e8bddfbd7d77a054 (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.am | 2 | ||||
-rw-r--r-- | xlators/features/locks/src/posix.c | 3 | ||||
-rw-r--r-- | xlators/features/marker/src/marker.c | 143 | ||||
-rw-r--r-- | xlators/features/qemu-block/src/bdrv-xlator.c | 15 | ||||
-rw-r--r-- | xlators/features/qemu-block/src/qb-coroutines.c | 15 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.c | 105 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.h | 3 |
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 { |