Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src/sys/ufs/chfs Pull up following revision(s) (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/0b9d164555a3
branches:  netbsd-7
changeset: 798324:0b9d164555a3
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Mon Sep 08 18:57:58 2014 +0000

description:
Pull up following revision(s) (requested by he in ticket #74):
        sys/ufs/chfs/chfs_vnode.c: revision 1.11
        sys/ufs/chfs/chfs_readinode.c: revision 1.9
        sys/ufs/chfs/chfs_scan.c: revision 1.5
        sys/ufs/chfs/chfs_gc.c: revision 1.6
        sys/ufs/chfs/ebh.c: revision 1.4
Plug leak in chfs_scan_eraseblock() of the allocated buffer.
Make sure to release it both on success and failure returns.
OK'ed by ttoth@
Plug memory leak in a corner case in chfs_get_data_nodes().
Plug memory leaks in error returns in chfs_readvnode().
Plug memory leak in error returns and normal operation in
chfs_gcollect_pristine().
Plug memory leak in add_peb_to_free() and add_peb_to_in_use()
in case there's a duplicate in the tree.

diffstat:

 sys/ufs/chfs/chfs_gc.c        |  45 ++++++++++++++++++++----------
 sys/ufs/chfs/chfs_readinode.c |   6 ++-
 sys/ufs/chfs/chfs_scan.c      |  64 ++++++++++++++++++++++--------------------
 sys/ufs/chfs/chfs_vnode.c     |   7 +++-
 sys/ufs/chfs/ebh.c            |  10 ++++--
 5 files changed, 79 insertions(+), 53 deletions(-)

diffs (truncated from 368 to 300 lines):

diff -r 880a3408b956 -r 0b9d164555a3 sys/ufs/chfs/chfs_gc.c
--- a/sys/ufs/chfs/chfs_gc.c    Sun Aug 31 17:27:11 2014 +0000
+++ b/sys/ufs/chfs/chfs_gc.c    Mon Sep 08 18:57:58 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: chfs_gc.c,v 1.5 2013/10/20 17:18:38 christos Exp $     */
+/*     $NetBSD: chfs_gc.c,v 1.5.4.1 2014/09/08 18:57:58 msaitoh Exp $  */
 
 /*-
  * Copyright (c) 2010 Department of Software Engineering,
@@ -726,23 +726,26 @@
        ret = chfs_read_leb(chmp, nref->nref_lnr, data, ofs, totlen, &retlen);
        if (ret) {
                dbg_gc("reading error\n");
-               return ret;
+               goto err_out;
        }
        if (retlen != totlen) {
                dbg_gc("read size error\n");
-               return EIO;
+               ret = EIO;
+               goto err_out;
        }
        nhdr = (struct chfs_flash_node_hdr *)data;
 
        /* Check the header. */
        if (le16toh(nhdr->magic) != CHFS_FS_MAGIC_BITMASK) {
                dbg_gc("node header magic number error\n");
-               return EBADF;
+               ret = EBADF;
+               goto err_out;
        }
        crc = crc32(0, (uint8_t *)nhdr, CHFS_NODE_HDR_SIZE - 4);
        if (crc != le32toh(nhdr->hdr_crc)) {
                dbg_gc("node header crc error\n");
-               return EBADF;
+               ret = EBADF;
+               goto err_out;
        }
 
        /* Read the remaining parts. */
@@ -753,7 +756,8 @@
                crc = crc32(0, (uint8_t *)fvnode, sizeof(struct chfs_flash_vnode) - 4);
                if (crc != le32toh(fvnode->node_crc)) {
                                dbg_gc("vnode crc error\n");
-                               return EBADF;
+                               ret = EBADF;
+                               goto err_out;
                        }
                        break;
         case CHFS_NODETYPE_DIRENT:
@@ -762,12 +766,14 @@
                crc = crc32(0, (uint8_t *)fdirent, sizeof(struct chfs_flash_dirent_node) - 4);
                if (crc != le32toh(fdirent->node_crc)) {
                                dbg_gc("dirent crc error\n");
-                               return EBADF;
+                               ret = EBADF;
+                               goto err_out;
                        }
                crc = crc32(0, fdirent->name, fdirent->nsize);
                if (crc != le32toh(fdirent->name_crc)) {
                                dbg_gc("dirent name crc error\n");
-                               return EBADF;
+                               ret = EBADF;
+                               goto err_out;
                        }
                        break;
         case CHFS_NODETYPE_DATA:
@@ -776,25 +782,29 @@
                crc = crc32(0, (uint8_t *)fdata, sizeof(struct chfs_flash_data_node) - 4);
                if (crc != le32toh(fdata->node_crc)) {
                                dbg_gc("data node crc error\n");
-                               return EBADF;
+                               ret = EBADF;
+                               goto err_out;
                        }
                        break;
         default:
                /* unknown node */
                        if (chvc) {
                                dbg_gc("unknown node have vnode cache\n");
-                               return EBADF;
+                               ret = EBADF;
+                               goto err_out;
                        }
        }
        /* CRC's OK, write node to its new place */
 retry:
        ret = chfs_reserve_space_gc(chmp, totlen);
        if (ret)
-               return ret;
+               goto err_out;
 
        newnref = chfs_alloc_node_ref(chmp->chm_nextblock);
-       if (!newnref)
-               return ENOMEM;
+       if (!newnref) {
+               ret = ENOMEM;
+               goto err_out;
+       }
 
        ofs = chmp->chm_ebh->eb_size - chmp->chm_nextblock->free_size;
        newnref->nref_offset = ofs;
@@ -814,7 +824,8 @@
                chfs_change_size_dirty(chmp, chmp->chm_nextblock, totlen);
                if (retries) {
                        mutex_exit(&chmp->chm_lock_sizes);
-                       return EIO;
+                       ret = EIO;
+                       goto err_out;
                }
 
                /* try again */
@@ -829,7 +840,11 @@
        mutex_enter(&chmp->chm_lock_vnocache);
        chfs_add_vnode_ref_to_vc(chmp, chvc, newnref);
        mutex_exit(&chmp->chm_lock_vnocache);
-       return 0;
+       ret = 0;
+       /* FALLTHROUGH */
+err_out:
+       kmem_free(data, totlen);
+       return ret;
 }
 
 
diff -r 880a3408b956 -r 0b9d164555a3 sys/ufs/chfs/chfs_readinode.c
--- a/sys/ufs/chfs/chfs_readinode.c     Sun Aug 31 17:27:11 2014 +0000
+++ b/sys/ufs/chfs/chfs_readinode.c     Mon Sep 08 18:57:58 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: chfs_readinode.c,v 1.8 2013/10/20 17:18:38 christos Exp $      */
+/*     $NetBSD: chfs_readinode.c,v 1.8.4.1 2014/09/08 18:57:58 msaitoh Exp $   */
 
 /*-
  * Copyright (c) 2010 Department of Software Engineering,
@@ -801,8 +801,10 @@
        buf = kmem_alloc(len, KM_SLEEP);
 
        dnode = kmem_alloc(len, KM_SLEEP);
-       if (!dnode)
+       if (!dnode) {
+               kmem_free(buf, len);
                return ENOMEM;
+       }
 
        nref = chfs_first_valid_data_ref(ip->chvc->dnode);
 
diff -r 880a3408b956 -r 0b9d164555a3 sys/ufs/chfs/chfs_scan.c
--- a/sys/ufs/chfs/chfs_scan.c  Sun Aug 31 17:27:11 2014 +0000
+++ b/sys/ufs/chfs/chfs_scan.c  Mon Sep 08 18:57:58 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: chfs_scan.c,v 1.4 2012/10/19 12:44:39 ttoth Exp $      */
+/*     $NetBSD: chfs_scan.c,v 1.4.12.1 2014/09/08 18:57:58 msaitoh Exp $       */
 
 /*-
  * Copyright (c) 2010 Department of Software Engineering,
@@ -443,15 +443,15 @@
                memset(buf, 0 , CHFS_MAX_NODE_SIZE);
                err = chfs_read_leb(chmp,
                    lnr, buf, ofs, CHFS_NODE_HDR_SIZE, &retlen);
-               if (err) {
-                       return err;
-               }
+               if (err)
+                       goto err_return;
 
                if (retlen != CHFS_NODE_HDR_SIZE) {
                        chfs_err("Error reading node header: "
                            "read: %zu instead of: %zu\n",
                            CHFS_NODE_HDR_SIZE, retlen);
-                       return EIO;
+                       err = EIO;
+                       goto err_return;
                }
 
                /* first we check if the buffer we read is full with 0xff, if yes maybe
@@ -476,9 +476,8 @@
                if (err) {
                        dbg("node hdr error\n");
                        err = chfs_update_eb_dirty(chmp, cheb, 4);
-                       if (err) {
-                               return err;
-                       }
+                       if (err)
+                               goto err_return;
 
                        ofs += 4;
                        continue;
@@ -486,7 +485,8 @@
                ofs += CHFS_NODE_HDR_SIZE;
                if (ofs > chmp->chm_ebh->eb_size) {
                        chfs_err("Second part of node is on the next eraseblock.\n");
-                       return EIO;
+                       err = EIO;
+                       goto err_return;
                }
                switch (le16toh(nhdr->type)) {
                case CHFS_NODETYPE_VNODE:
@@ -496,21 +496,20 @@
                        err = chfs_read_leb(chmp,
                            lnr, buf + CHFS_NODE_HDR_SIZE,
                            ofs, len,  &retlen);
-                       if (err) {
-                               return err;
-                       }
+                       if (err)
+                               goto err_return;
 
                        if (retlen != len) {
                                chfs_err("Error reading vnode: read: %zu instead of: %zu\n",
                                    len, retlen);
-                               return EIO;
+                               err = EIO;
+                               goto err_return;
                        }
                        KASSERT(lnr == cheb->lnr);
                        err = chfs_scan_check_vnode(chmp,
                            cheb, buf, ofs - CHFS_NODE_HDR_SIZE);
-                       if (err) {
-                               return err;
-                       }
+                       if (err)
+                               goto err_return;
 
                        break;
                case CHFS_NODETYPE_DIRENT:
@@ -521,23 +520,22 @@
                        err = chfs_read_leb(chmp,
                            lnr, buf + CHFS_NODE_HDR_SIZE,
                            ofs, len, &retlen);
-                       if (err) {
-                               return err;
-                       }
+                       if (err)
+                               goto err_return;
 
                        if (retlen != len) {
                                chfs_err("Error reading dirent node: read: %zu "
                                    "instead of: %zu\n", len, retlen);
-                               return EIO;
+                               err = EIO;
+                               goto err_return;
                        }
 
                        KASSERT(lnr == cheb->lnr);
 
                        err = chfs_scan_check_dirent_node(chmp,
                            cheb, buf, ofs - CHFS_NODE_HDR_SIZE);
-                       if (err) {
-                               return err;
-                       }
+                       if (err)
+                               goto err_return;
 
                        break;
                case CHFS_NODETYPE_DATA:
@@ -547,20 +545,20 @@
                        err = chfs_read_leb(chmp,
                            lnr, buf + CHFS_NODE_HDR_SIZE,
                            ofs, len, &retlen);
-                       if (err) {
-                               return err;
-                       }
+                       if (err)
+                               goto err_return;
 
                        if (retlen != len) {
                                chfs_err("Error reading data node: read: %zu "
                                    "instead of: %zu\n", len, retlen);
-                               return EIO;
+                               err = EIO;
+                               goto err_return;
                        }
                        KASSERT(lnr == cheb->lnr);
                        err = chfs_scan_check_data_node(chmp,
                            cheb, buf, ofs - CHFS_NODE_HDR_SIZE);
                        if (err)
-                               return err;
+                               goto err_return;
 
                        break;
                case CHFS_NODETYPE_PADDING:
@@ -573,7 +571,7 @@
                        err = chfs_update_eb_dirty(chmp, cheb,
                            le32toh(nhdr->length));
                        if (err)
-                               return err;
+                               goto err_return;
 
                        break;
                default:
@@ -581,7 +579,7 @@
                        err = chfs_update_eb_dirty(chmp, cheb,
                            le32toh(nhdr->length));
                        if (err)
-                               return err;
+                               goto err_return;
 
                        break;
                }
@@ -591,5 +589,9 @@



Home | Main Index | Thread Index | Old Index