summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrishnan Parthasarathi <kparthas@redhat.com>2013-10-28 19:14:49 +0530
committerVijay Bellur <vbellur@redhat.com>2014-02-05 23:05:59 -0800
commitf0fac871dc32f0d3756c84c22b7f9b0a6b3daec5 (patch)
treef3ac346750ea6d481b41ca0a4941b31562311099
parentaf29cc47197f71b66f5a4f2dc6cca573a78bbdce (diff)
quota: get directory size before enforcing quota on rename
Backport of http://review.gluster.org/6155 BUG: 1023974 Change-Id: Icb4bca8c4a5fa9b14855478e69b1315f2e9a3c3d Signed-off-by: Krishnan Parthasarathi <kparthas@redhat.com> Reviewed-on: http://review.gluster.org/6887 Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r--xlators/features/quota/src/quota.c81
-rw-r--r--xlators/features/quota/src/quota.h3
2 files changed, 72 insertions, 12 deletions
diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c
index 5f5a8398a..655135963 100644
--- a/xlators/features/quota/src/quota.c
+++ b/xlators/features/quota/src/quota.c
@@ -980,8 +980,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;
}
@@ -1003,7 +1002,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;
}
@@ -1881,13 +1880,11 @@ 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;
}
- 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;
}
@@ -2001,6 +1998,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)
@@ -2047,8 +2084,7 @@ quota_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc,
}
UNLOCK (&local->lock);
- 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,
@@ -2058,11 +2094,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);
diff --git a/xlators/features/quota/src/quota.h b/xlators/features/quota/src/quota.h
index 82ba90513..84c3257fe 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 {