Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146286521
D45517.id139587.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D45517.id139587.diff
View Options
diff --git a/lib/geom/virstor/geom_virstor.c b/lib/geom/virstor/geom_virstor.c
--- a/lib/geom/virstor/geom_virstor.c
+++ b/lib/geom/virstor/geom_virstor.c
@@ -157,8 +157,7 @@
char param[32];
int hardcode, nargs, error;
struct virstor_map_entry *map;
- size_t total_chunks; /* We'll run out of memory if
- this needs to be bigger. */
+ size_t total_chunks, write_max_map_entries;
unsigned int map_chunks; /* Chunks needed by the map (map size). */
size_t map_size; /* In bytes. */
ssize_t written;
@@ -328,25 +327,47 @@
if (fd < 0)
gctl_error(req, "Cannot open provider %s to write map", name);
- /* Do it with calloc because there might be a need to set up chunk flags
- * in the future */
- map = calloc(total_chunks, sizeof(*map));
+ /*
+ * Initialize and write the map. Don't malloc the whole map at once,
+ * in case it's large. Use calloc because there might be a need to set
+ * up chunk flags in the future.
+ */
+ write_max_map_entries = 1024 * 1024 / sizeof(*map);
+ if (write_max_map_entries > total_chunks)
+ write_max_map_entries = total_chunks;
+ map = calloc(write_max_map_entries, sizeof(*map));
if (map == NULL) {
gctl_error(req,
"Out of memory (need %zu bytes for allocation map)",
- map_size);
+ write_max_map_entries * sizeof(*map));
}
-
- written = pwrite(fd, map, map_size, 0);
- free(map);
- if ((size_t)written != map_size) {
- if (verbose) {
- fprintf(stderr, "\nTried to write %zu, written %zd (%s)\n",
- map_size, written, strerror(errno));
+ for (size_t chunk = 0; chunk < total_chunks;
+ chunk += write_max_map_entries) {
+ size_t bytes_to_write, entries_to_write;
+
+ entries_to_write = total_chunks - chunk;
+ if (entries_to_write > write_max_map_entries)
+ entries_to_write = write_max_map_entries;
+ bytes_to_write = entries_to_write * sizeof(*map);
+ for (size_t off = 0; off < bytes_to_write; off += written) {
+ written = write(fd, ((char *)map) + off,
+ bytes_to_write - off);
+ if (written < 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "\nError writing map at offset "
+ "%zu of %zu: %s\n",
+ chunk * sizeof(*map) + off,
+ map_size, strerror(errno));
+ }
+ gctl_error(req,
+ "Error writing out allocation map!");
+ return;
+ }
}
- gctl_error(req, "Error writing out allocation map!");
- return;
}
+ free(map);
+ map = NULL;
close (fd);
if (verbose)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 2, 10:23 AM (21 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29153478
Default Alt Text
D45517.id139587.diff (2 KB)
Attached To
Mode
D45517: virstor: write large maps in chunks during label
Attached
Detach File
Event Timeline
Log In to Comment