d1681e
From a9310d6e4c9990020ff76f5b815bc99b5703f17e Mon Sep 17 00:00:00 2001
d1681e
From: Sanoj Unnikrishnan <sunnikri@redhat.com>
d1681e
Date: Wed, 8 Nov 2017 16:18:56 +0530
d1681e
Subject: [PATCH 123/128] quota: fixes issue in quota.conf when setting large
d1681e
 number of limits
d1681e
d1681e
Problem: It was not possible to configure more than 7712 quota limits.
d1681e
This was because a stack buffer of size 131072 was used to read from
d1681e
quota.conf file. In the new format of quota.conf file each gfid entry
d1681e
takes 17bytes (16byte gfid + 1 byte type). So, the buf_size was not a
d1681e
multiple of gfid entry size and as per code this was considered as
d1681e
corruption.
d1681e
d1681e
Solution: make buf size a multiple of gfid entry size
d1681e
d1681e
> Change-Id: Id036225505a47a4f6fa515a572ee7b0c958f30ed
d1681e
> BUG: 1510940
d1681e
> Patch: https://review.gluster.org/#/c/18695/
d1681e
d1681e
BUG: 1511766
d1681e
Change-Id: Id036225505a47a4f6fa515a572ee7b0c958f30ed
d1681e
Signed-off-by: Sanoj Unnikrishnan <sunnikri@redhat.com>
d1681e
Reviewed-on: https://code.engineering.redhat.com/gerrit/124647
d1681e
Tested-by: RHGS Build Bot <nigelb@redhat.com>
d1681e
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
d1681e
---
d1681e
 xlators/mgmt/glusterd/src/glusterd-quota.c | 45 ++++++++++++++++++++++--------
d1681e
 1 file changed, 33 insertions(+), 12 deletions(-)
d1681e
d1681e
diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c
d1681e
index fc34042..1c3a801 100644
d1681e
--- a/xlators/mgmt/glusterd/src/glusterd-quota.c
d1681e
+++ b/xlators/mgmt/glusterd/src/glusterd-quota.c
d1681e
@@ -907,24 +907,31 @@ out:
d1681e
 }
d1681e
 
d1681e
 /* The function glusterd_copy_to_tmp_file() reads the "remaining" bytes from
d1681e
- * the source fd and writes them to destination fd, at the rate of 128K bytes
d1681e
- * of read+write at a time.
d1681e
+ * the source fd and writes them to destination fd, at the rate of 1000 entries
d1681e
+ * a time (qconf_line_sz is the size of an entry)
d1681e
  */
d1681e
 
d1681e
 static int
d1681e
-glusterd_copy_to_tmp_file (int src_fd, int dst_fd)
d1681e
+glusterd_copy_to_tmp_file (int src_fd, int dst_fd, int qconf_line_sz)
d1681e
 {
d1681e
         int            ret         = 0;
d1681e
-        size_t         entry_sz    = 131072;
d1681e
         ssize_t        bytes_read  = 0;
d1681e
-        unsigned char  buf[131072] = {0,};
d1681e
         xlator_t      *this        = NULL;
d1681e
+        unsigned char  *buf        = 0;
d1681e
+        int            buf_sz      = qconf_line_sz * 1000;
d1681e
 
d1681e
         this = THIS;
d1681e
         GF_ASSERT (this);
d1681e
+        GF_ASSERT (buf_sz > 0);
d1681e
 
d1681e
-        while ((bytes_read = sys_read (src_fd, (void *)&buf, entry_sz)) > 0) {
d1681e
-                if (bytes_read % 16 != 0) {
d1681e
+        buf = GF_CALLOC(buf_sz, 1, gf_common_mt_char);
d1681e
+        if (!buf) {
d1681e
+                ret = -1;
d1681e
+                goto out;
d1681e
+        }
d1681e
+
d1681e
+        while ((bytes_read = sys_read (src_fd, buf, buf_sz)) > 0) {
d1681e
+                if (bytes_read % qconf_line_sz != 0) {
d1681e
                         gf_msg (this->name, GF_LOG_ERROR, 0,
d1681e
                                 GD_MSG_QUOTA_CONF_CORRUPT, "quota.conf "
d1681e
                                 "corrupted");
d1681e
@@ -942,6 +949,8 @@ glusterd_copy_to_tmp_file (int src_fd, int dst_fd)
d1681e
         ret = 0;
d1681e
 
d1681e
 out:
d1681e
+        if (buf)
d1681e
+                GF_FREE(buf);
d1681e
         return ret;
d1681e
 }
d1681e
 
d1681e
@@ -1034,7 +1043,6 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,
d1681e
         int                conf_fd               = -1;
d1681e
         ssize_t            bytes_read            = 0;
d1681e
         size_t             bytes_to_write        = 0;
d1681e
-        unsigned char      buf[131072]           = {0,};
d1681e
         uuid_t             gfid                  = {0,};
d1681e
         xlator_t          *this                  = NULL;
d1681e
         gf_boolean_t       found                 = _gf_false;
d1681e
@@ -1045,6 +1053,8 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,
d1681e
         float              version               = 0.0f;
d1681e
         char               type                  = 0;
d1681e
         int                quota_conf_line_sz    = 16;
d1681e
+        unsigned char      *buf                  = 0;
d1681e
+        int                buf_sz                = 0;
d1681e
 
d1681e
         this = THIS;
d1681e
         GF_ASSERT (this);
d1681e
@@ -1098,6 +1108,14 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,
d1681e
         if (conf->op_version >= GD_OP_VERSION_3_7_0)
d1681e
                 quota_conf_line_sz++;
d1681e
 
d1681e
+        buf_sz = quota_conf_line_sz * 1000;
d1681e
+
d1681e
+        buf = GF_CALLOC(buf_sz, 1, gf_common_mt_char);
d1681e
+        if (!buf) {
d1681e
+                ret = -1;
d1681e
+                goto out;
d1681e
+        }
d1681e
+
d1681e
         fd = gf_store_mkstemp (volinfo->quota_conf_shandle);
d1681e
         if (fd < 0) {
d1681e
                 ret = -1;
d1681e
@@ -1129,7 +1147,7 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,
d1681e
                 type = GF_QUOTA_CONF_TYPE_USAGE;
d1681e
 
d1681e
         for (;;) {
d1681e
-                bytes_read = sys_read (conf_fd, (void *)&buf, sizeof (buf));
d1681e
+                bytes_read = sys_read (conf_fd, buf, buf_sz);
d1681e
                 if (bytes_read <= 0) {
d1681e
                         /*The flag @is_first_read is TRUE when the loop is
d1681e
                          * entered, and is set to false if the first read
d1681e
@@ -1166,7 +1184,8 @@ glusterd_store_quota_config (glusterd_volinfo_t *volinfo, char *path,
d1681e
                  * Else continue with the search.
d1681e
                  */
d1681e
                 if (found) {
d1681e
-                        ret = glusterd_copy_to_tmp_file (conf_fd, fd);
d1681e
+                        ret = glusterd_copy_to_tmp_file (conf_fd, fd,
d1681e
+                                                         quota_conf_line_sz);
d1681e
                         if (ret)
d1681e
                                 goto out;
d1681e
                         break;
d1681e
@@ -1238,6 +1257,9 @@ out:
d1681e
                 sys_close (conf_fd);
d1681e
         }
d1681e
 
d1681e
+        if (buf)
d1681e
+                GF_FREE(buf);
d1681e
+
d1681e
         if (ret && (fd > 0)) {
d1681e
                 gf_store_unlink_tmppath (volinfo->quota_conf_shandle);
d1681e
         } else if (!ret && GF_QUOTA_OPTION_TYPE_UPGRADE != opcode) {
d1681e
@@ -1260,8 +1282,7 @@ out:
d1681e
                                         "store quota version and cksum");
d1681e
                 }
d1681e
         }
d1681e
-
d1681e
-        return ret;
d1681e
+       return ret;
d1681e
 }
d1681e
 
d1681e
 int32_t
d1681e
-- 
d1681e
1.8.3.1
d1681e