hammer2 - Fix improper bzero length in rename code master
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 20 Aug 2017 06:00:03 +0000 (23:00 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 20 Aug 2017 06:03:13 +0000 (23:03 -0700)
* When renaming to a long filename the data buffer is sized according
  to chain->bytes.  sizeof(chain->data->buf) is too much.  Fix the
  bzero.

* Fixes a panic.

sys/vfs/hammer2/hammer2_inode.c
sys/vfs/hammer2/hammer2_xops.c

index 36a88e6..44d0402 100644 (file)
@@ -1344,6 +1344,11 @@ hammer2_inode_xop_mkdirent(hammer2_thread_t *thr, hammer2_xop_t *arg)
                                     data_len,
                                     xop->head.mtid, 0, 0);
        if (error == 0) {
+               /*
+                * WARNING: chain->data->buf is sized to chain->bytes,
+                *          do not use sizeof(chain->data->buf), which
+                *          will be much larger.
+                */
                hammer2_chain_modify(chain, xop->head.mtid, 0, 0);
 
                chain->bref.embed.dirent = xop->dirent;
index e74d5a1..6c19f26 100644 (file)
@@ -602,6 +602,10 @@ hammer2_xop_nrename(hammer2_thread_t *thr, hammer2_xop_t *arg)
                }
                if (chain->bref.type == HAMMER2_BREF_TYPE_DIRENT) {
                        if (xop->head.name2_len <= sizeof(chain->bref.check.buf)) {
+                               /*
+                                * Remove any related data buffer, we can
+                                * embed the filename in the bref itself.
+                                */
                                hammer2_chain_resize(chain, xop->head.mtid, 0,
                                                     0, 0);
                                hammer2_chain_modify(chain, xop->head.mtid,
@@ -611,13 +615,19 @@ hammer2_xop_nrename(hammer2_thread_t *thr, hammer2_xop_t *arg)
                                bcopy(xop->head.name2, chain->bref.check.buf,
                                      xop->head.name2_len);
                        } else {
+                               /*
+                                * Associate a data buffer with the bref.
+                                * Zero it for consistency.  Note that the
+                                * data buffer is not 64KB so use chain->bytes
+                                * instead of sizeof().
+                                */
                                hammer2_chain_resize(chain, xop->head.mtid, 0,
                                     hammer2_getradix(HAMMER2_ALLOC_MIN), 0);
                                hammer2_chain_modify(chain, xop->head.mtid,
                                                     0, 0);
-                               bzero(chain->data->buf,
-                                     sizeof(chain->data->buf));
-                               bcopy(xop->head.name2, chain->data->buf,
+                               bzero(chain->data->buf, chain->bytes);
+                               bcopy(xop->head.name2,
+                                     chain->data->buf,
                                      xop->head.name2_len);
                        }
                        chain->bref.embed.dirent.namlen = xop->head.name2_len;