Author: tsoome
Date: Sat Oct 26 18:29:02 2019
New Revision: 354119
URL: https://svnweb.freebsd.org/changeset/base/354119

Log:
  loader: rs_alloc() may return NULL
  
  rs_alloc() in zfs reader code may return NULL, so we need to check the return 
value and error out if needed.
  MFC after:    1 week

Modified:
  head/stand/libsa/zfs/zfsimpl.c

Modified: head/stand/libsa/zfs/zfsimpl.c
==============================================================================
--- head/stand/libsa/zfs/zfsimpl.c      Sat Oct 26 18:22:52 2019        
(r354118)
+++ head/stand/libsa/zfs/zfsimpl.c      Sat Oct 26 18:29:02 2019        
(r354119)
@@ -840,12 +840,17 @@ vdev_indirect_remap(vdev_t *vd, uint64_t offset, uint6
        list_t stack;
        spa_t *spa = vd->spa;
        zio_t *zio = arg;
+       remap_segment_t *rs;
 
        list_create(&stack, sizeof (remap_segment_t),
            offsetof(remap_segment_t, rs_node));
 
-       for (remap_segment_t *rs = rs_alloc(vd, offset, asize, 0);
-           rs != NULL; rs = list_remove_head(&stack)) {
+       rs = rs_alloc(vd, offset, asize, 0);
+       if (rs == NULL) {
+               printf("vdev_indirect_remap: out of memory.\n");
+               zio->io_error = ENOMEM;
+       }
+       for ( ; rs != NULL; rs = list_remove_head(&stack)) {
                vdev_t *v = rs->rs_vd;
                uint64_t num_entries = 0;
                /* vdev_indirect_mapping_t *vim = v->v_mapping; */
@@ -853,6 +858,9 @@ vdev_indirect_remap(vdev_t *vd, uint64_t offset, uint6
                    vdev_indirect_mapping_duplicate_adjacent_entries(v,
                    rs->rs_offset, rs->rs_asize, &num_entries);
 
+               if (num_entries == 0)
+                       zio->io_error = ENOMEM;
+
                for (uint64_t i = 0; i < num_entries; i++) {
                        vdev_indirect_mapping_entry_phys_t *m = &mapping[i];
                        uint64_t size = DVA_GET_ASIZE(&m->vimep_dst);
@@ -865,9 +873,18 @@ vdev_indirect_remap(vdev_t *vd, uint64_t offset, uint6
                        vdev_t *dst_v = vdev_lookup_top(spa, dst_vdev);
 
                        if (dst_v->v_read == vdev_indirect_read) {
-                               list_insert_head(&stack,
-                                   rs_alloc(dst_v, dst_offset + inner_offset,
-                                   inner_size, rs->rs_split_offset));
+                               remap_segment_t *o;
+
+                               o = rs_alloc(dst_v, dst_offset + inner_offset,
+                                   inner_size, rs->rs_split_offset);
+                               if (o == NULL) {
+                                       printf("vdev_indirect_remap: "
+                                           "out of memory.\n");
+                                       zio->io_error = ENOMEM;
+                                       break;
+                               }
+
+                               list_insert_head(&stack, o);
                        }
                        vdev_indirect_gather_splits(rs->rs_split_offset, dst_v,
                            dst_offset + inner_offset,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to