util: add function to extend anonymous shared memory
authorSimo Sorce <idra@samba.org>
Sun, 14 Aug 2011 22:10:53 +0000 (18:10 -0400)
committerSimo Sorce <idra@samba.org>
Mon, 15 Aug 2011 00:19:02 +0000 (20:19 -0400)
lib/util/util.c
lib/util/util.h

index 2d1d83036d36b85faf82e6e4b2951695f93bc59d..b700f372c732a1c2bdde35697bc37c89aaad8388 100644 (file)
@@ -1073,6 +1073,70 @@ void *anonymous_shared_allocate(size_t orig_bufsz)
        return ptr;
 }
 
+void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove)
+{
+#ifdef HAVE_MREMAP
+       void *buf;
+       size_t pagesz = getpagesize();
+       size_t pagecnt;
+       size_t bufsz;
+       struct anonymous_shared_header *hdr;
+       int flags = 0;
+
+       if (ptr == NULL) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       hdr = (struct anonymous_shared_header *)ptr;
+       hdr--;
+       if (hdr->u.length > (new_size + sizeof(*hdr))) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       bufsz = new_size + sizeof(*hdr);
+
+       /* round up to full pages */
+       pagecnt = bufsz / pagesz;
+       if (bufsz % pagesz) {
+               pagecnt += 1;
+       }
+       bufsz = pagesz * pagecnt;
+
+       if (new_size >= bufsz) {
+               /* integer wrap */
+               errno = ENOSPC;
+               return NULL;
+       }
+
+       if (bufsz <= hdr->u.length) {
+               return ptr;
+       }
+
+       if (maymove) {
+               flags = MREMAP_MAYMOVE;
+       }
+
+       buf = mremap(hdr, hdr->u.length, bufsz, flags);
+
+       if (buf == MAP_FAILED) {
+               errno = ENOSPC;
+               return NULL;
+       }
+
+       hdr = (struct anonymous_shared_header *)buf;
+       hdr->u.length = bufsz;
+
+       ptr = (void *)(&hdr[1]);
+
+       return ptr;
+#else
+       errno = ENOSPC;
+       return NULL;
+#endif
+}
+
 void anonymous_shared_free(void *ptr)
 {
        struct anonymous_shared_header *hdr;
index 7f0de26781bda2ad73478300f05711bfc8a0f5ce..0102feaddfe54e9906b3dbe7669929f9101fbe64 100644 (file)
@@ -852,6 +852,7 @@ bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
  * Allocate anonymous shared memory of the given size
  */
 void *anonymous_shared_allocate(size_t bufsz);
+void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove);
 void anonymous_shared_free(void *ptr);
 
 /*