[PATCH 2/4] map_loose_object_1: attempt to handle ENOMEM from mmap

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

 



This benefits unprivileged users who lack permissions to raise
the `sys.vm.max_map_count' sysctl and/or RLIMIT_DATA resource
limit.

Multi-threaded callers to map_loose_object_1 (e.g. "git grep")
appear to guard against thread-safety problems.  Other
multi-core aware pieces of code (e.g. parallel-checkout) uses
child processes

Forcing a call to unuse_one_window() once before xmmap_gently()
revealed no test suite failures:

	--- a/object-file.c
	+++ b/object-file.c
	@@ -1197,6 +1197,7 @@ static void *map_loose_object_1(struct repository *r, const char *path,
					return NULL;
				}
				do {
	+				unuse_one_window(NULL);
					map = xmmap_gently(NULL, *size, PROT_READ,
							MAP_PRIVATE, fd, 0);
				} while (map == MAP_FAILED && errno == ENOMEM

Signed-off-by: Eric Wong <e@xxxxxxxxx>
---
 object-file.c | 8 +++++++-
 packfile.c    | 2 +-
 packfile.h    | 2 ++
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/object-file.c b/object-file.c
index f233b440b2..4c043f1f3c 100644
--- a/object-file.c
+++ b/object-file.c
@@ -1196,7 +1196,13 @@ static void *map_loose_object_1(struct repository *r, const char *path,
 				close(fd);
 				return NULL;
 			}
-			map = xmmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0);
+			do {
+				map = xmmap_gently(NULL, *size, PROT_READ,
+						MAP_PRIVATE, fd, 0);
+			} while (map == MAP_FAILED && errno == ENOMEM
+				&& unuse_one_window(NULL));
+			if (map == MAP_FAILED)
+				die_errno("%s cannot be mapped", path);
 		}
 		close(fd);
 	}
diff --git a/packfile.c b/packfile.c
index a0da790fb4..4bc7fa0f36 100644
--- a/packfile.c
+++ b/packfile.c
@@ -265,7 +265,7 @@ static void scan_windows(struct packed_git *p,
 	}
 }
 
-static int unuse_one_window(struct packed_git *current)
+int unuse_one_window(struct packed_git *current)
 {
 	struct packed_git *p, *lru_p = NULL;
 	struct pack_window *lru_w = NULL, *lru_l = NULL;
diff --git a/packfile.h b/packfile.h
index 3ae117a8ae..da9a061e30 100644
--- a/packfile.h
+++ b/packfile.h
@@ -196,4 +196,6 @@ int is_promisor_object(const struct object_id *oid);
 int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
 	     size_t idx_size, struct packed_git *p);
 
+int unuse_one_window(struct packed_git *);
+
 #endif



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux