[PATCH] compat: introduce stat_to_kilobytes

Subsystems: kernel build + files below scripts/ (unless maintained elsewhere), the rest

STALE3710d

5 messages, 3 authors, 2016-06-15 · open the first message on its own page

[PATCH] compat: introduce stat_to_kilobytes

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:45:10

Some platforms do not have st_blocks member in "struct stat"; mingw
already emulates it by rounding it up to closest 512-byte blocks (even
though it could overcount when a file has holes).

The reason to use the member is only to figure out how many kilobytes the
file occupies on-disk, so give a helper in git-compat-util.h to help these
platforms.

Signed-off-by: Junio C Hamano <redacted>
---

 * I suspect you may be better off building on top of something like
   this.

   The comment before "struct mingw_stat" suggests that the only reason
   this compatiblity definition exists is to add st_blocks member, so I
   suspect we could remove the definition and simplify the compatibility
   layer a lot more, but I do not know MinGW, so I am CC'ing j6t here.

 Makefile                |    4 ++++
 builtin-count-objects.c |    4 ++--
 compat/mingw.c          |    8 --------
 compat/mingw.h          |    1 -
 git-compat-util.h       |    6 ++++++
 5 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/Makefile b/Makefile
index 53ab4b5..8f69f16 100644
--- a/Makefile
+++ b/Makefile
@@ -124,6 +124,9 @@ all::
 # Define USE_STDEV below if you want git to care about the underlying device
 # change being considered an inode change from the update-index perspective.
 #
+# Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks
+# field that counts the on-disk footprint in 512-byte blocks.
+#
 # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
 #
 # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
@@ -749,6 +752,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_SVN_TESTS = YesPlease
 	NO_PERL_MAKEMAKER = YesPlease
 	NO_POSIX_ONLY_PROGRAMS = YesPlease
+	NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
 	COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat
 	COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
 	COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
diff --git a/builtin-count-objects.c b/builtin-count-objects.c
index 91b5487..07ab0a0 100644
--- a/builtin-count-objects.c
+++ b/builtin-count-objects.c
@@ -43,7 +43,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
 			if (lstat(path, &st) || !S_ISREG(st.st_mode))
 				bad = 1;
 			else
-				(*loose_size) += xsize_t(st.st_blocks);
+				(*loose_size) += xsize_t(stat_to_kilobytes(st));
 		}
 		if (bad) {
 			if (verbose) {
@@ -115,7 +115,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
 			num_pack++;
 		}
 		printf("count: %lu\n", loose);
-		printf("size: %lu\n", loose_size / 2);
+		printf("size: %lu\n", loose_size);
 		printf("in-pack: %lu\n", packed);
 		printf("packs: %lu\n", num_pack);
 		printf("prune-packable: %lu\n", packed_loose);
diff --git a/compat/mingw.c b/compat/mingw.c
index 772cad5..798fb61 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -31,11 +31,6 @@ static inline time_t filetime_to_time_t(const FILETIME *ft)
 	return (time_t)winTime;
 }
 
-static inline size_t size_to_blocks(size_t s)
-{
-	return (s+511)/512;
-}
-
 extern int _getdrive( void );
 /* We keep the do_lstat code in a separate function to avoid recursion.
  * When a path ends with a slash, the stat will fail with ENOENT. In
@@ -59,7 +54,6 @@ static int do_lstat(const char *file_name, struct stat *buf)
 		buf->st_uid = 0;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
-		buf->st_blocks = size_to_blocks(buf->st_size);
 		buf->st_dev = _getdrive() - 1;
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
@@ -142,7 +136,6 @@ int mingw_fstat(int fd, struct mingw_stat *buf)
 		buf->st_uid = st.st_uid;
 		buf->st_mode = st.st_mode;
 		buf->st_size = st.st_size;
-		buf->st_blocks = size_to_blocks(buf->st_size);
 		buf->st_dev = st.st_dev;
 		buf->st_atime = st.st_atime;
 		buf->st_mtime = st.st_mtime;
@@ -164,7 +157,6 @@ int mingw_fstat(int fd, struct mingw_stat *buf)
 		buf->st_uid = 0;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
-		buf->st_blocks = size_to_blocks(buf->st_size);
 		buf->st_dev = _getdrive() - 1;
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
diff --git a/compat/mingw.h b/compat/mingw.h
index a52e657..1472d59 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -169,7 +169,6 @@ struct mingw_stat {
 	time_t st_mtime, st_atime, st_ctime;
 	unsigned st_dev, st_ino, st_uid, st_gid;
 	size_t st_size;
-	size_t st_blocks;
 };
 int mingw_lstat(const char *file_name, struct mingw_stat *buf);
 int mingw_fstat(int fd, struct mingw_stat *buf);
diff --git a/git-compat-util.h b/git-compat-util.h
index cf89cdf..8ef3a72 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -192,6 +192,12 @@ extern int git_munmap(void *start, size_t length);
 
 #endif /* NO_MMAP */
 
+#ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
+#define stat_to_kilobytes(st) ((((st).st_size+511) / 512) / 2)
+#else
+#define stat_to_kilobytes(st) ((st).st_blocks / 2)
+#endif
+
 #define DEFAULT_PACKED_GIT_LIMIT \
 	((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
 
-- 
1.6.0.rc3.22.g053f

Re: [PATCH] compat: introduce stat_to_kilobytes

From: Andreas Färber <hidden>
Date: 2016-06-15 22:45:10

Am 17.08.2008 um 11:47 schrieb Junio C Hamano:
Some platforms do not have st_blocks member in "struct stat"; mingw
already emulates it by rounding it up to closest 512-byte blocks (even
though it could overcount when a file has holes).

The reason to use the member is only to figure out how many  
kilobytes the
file occupies on-disk, so give a helper in git-compat-util.h to help  
these
platforms.

Signed-off-by: Junio C Hamano <redacted>
---

* I suspect you may be better off building on top of something like
  this.

  The comment before "struct mingw_stat" suggests that the only reason
  this compatiblity definition exists is to add st_blocks member, so I
  suspect we could remove the definition and simplify the  
compatibility
  layer a lot more, but I do not know MinGW, so I am CC'ing j6t here.
[...]
quoted hunk
diff --git a/Makefile b/Makefile
index 53ab4b5..8f69f16 100644
--- a/Makefile
+++ b/Makefile
@@ -124,6 +124,9 @@ all::
# Define USE_STDEV below if you want git to care about the  
underlying device
# change being considered an inode change from the update-index  
perspective.
#
+# Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have  
st_blocks
+# field that counts the on-disk footprint in 512-byte blocks.
+#
# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
#
# Define DOCBOOK_XSL_172 if you want to format man pages with  
DocBook XSL v1.72.
@@ -749,6 +752,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
	NO_SVN_TESTS = YesPlease
	NO_PERL_MAKEMAKER = YesPlease
	NO_POSIX_ONLY_PROGRAMS = YesPlease
+	NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
	COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat
	COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
	COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
What's missing in this one is the translation from Makefile variable  
to preprocessor define:

ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
	BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT
endif

for this to work:
quoted hunk
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -192,6 +192,12 @@ extern int git_munmap(void *start, size_t  
length);

#endif /* NO_MMAP */

+#ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
+#define stat_to_kilobytes(st) ((((st).st_size+511) / 512) / 2)
+#else
+#define stat_to_kilobytes(st) ((st).st_blocks / 2)
+#endif
+
#define DEFAULT_PACKED_GIT_LIMIT \
	((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
Andreas

[PATCH 1/2] compat: introduce stat_to_kilobytes

From: Johannes Sixt <hidden>
Date: 2016-06-15 22:45:10

From: Junio C Hamano <redacted>

Some platforms do not have st_blocks member in "struct stat"; mingw
already emulates it by rounding it up to closest 512-byte blocks (even
though it could overcount when a file has holes).

The reason to use the member is only to figure out how many kilobytes the
file occupies on-disk, so give a helper in git-compat-util.h to help these
platforms.

Signed-off-by: Junio C Hamano <redacted>
Acked-by: Johannes Sixt <redacted>
---
On Sonntag, 17. August 2008, Junio C Hamano wrote:
   The comment before "struct mingw_stat" suggests that the only reason
   this compatiblity definition exists is to add st_blocks member, so I
   suspect we could remove the definition and simplify the compatibility
   layer a lot more, but I do not know MinGW, so I am CC'ing j6t here.
Makes sense. Here it is again, with the Makefile fixup noted by Andreas.

But notice that we now underestimated the size of loose objects more than
we did previously because we now round down individual sizes; previously
we rounded down only the total size.

 Makefile                |    7 +++++++
 builtin-count-objects.c |    4 ++--
 compat/mingw.c          |    8 --------
 compat/mingw.h          |    1 -
 git-compat-util.h       |    6 ++++++
 5 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/Makefile b/Makefile
index 979fcf8..7095b1f 100644
--- a/Makefile
+++ b/Makefile
@@ -124,6 +124,9 @@ all::
 # Define USE_STDEV below if you want git to care about the underlying device
 # change being considered an inode change from the update-index perspective.
 #
+# Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks
+# field that counts the on-disk footprint in 512-byte blocks.
+#
 # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
 #
 # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
@@ -749,6 +752,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
 	NO_SVN_TESTS = YesPlease
 	NO_PERL_MAKEMAKER = YesPlease
 	NO_POSIX_ONLY_PROGRAMS = YesPlease
+	NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
 	COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat
 	COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
 	COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
@@ -863,6 +867,9 @@ endif
 ifdef NO_D_INO_IN_DIRENT
 	BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT
 endif
+ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
+	BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT
+endif
 ifdef NO_C99_FORMAT
 	BASIC_CFLAGS += -DNO_C99_FORMAT
 endif
diff --git a/builtin-count-objects.c b/builtin-count-objects.c
index 91b5487..07ab0a0 100644
--- a/builtin-count-objects.c
+++ b/builtin-count-objects.c
@@ -43,7 +43,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
 			if (lstat(path, &st) || !S_ISREG(st.st_mode))
 				bad = 1;
 			else
-				(*loose_size) += xsize_t(st.st_blocks);
+				(*loose_size) += xsize_t(stat_to_kilobytes(st));
 		}
 		if (bad) {
 			if (verbose) {
@@ -115,7 +115,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
 			num_pack++;
 		}
 		printf("count: %lu\n", loose);
-		printf("size: %lu\n", loose_size / 2);
+		printf("size: %lu\n", loose_size);
 		printf("in-pack: %lu\n", packed);
 		printf("packs: %lu\n", num_pack);
 		printf("prune-packable: %lu\n", packed_loose);
diff --git a/compat/mingw.c b/compat/mingw.c
index 772cad5..798fb61 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -31,11 +31,6 @@ static inline time_t filetime_to_time_t(const FILETIME *ft)
 	return (time_t)winTime;
 }
 
-static inline size_t size_to_blocks(size_t s)
-{
-	return (s+511)/512;
-}
-
 extern int _getdrive( void );
 /* We keep the do_lstat code in a separate function to avoid recursion.
  * When a path ends with a slash, the stat will fail with ENOENT. In
@@ -59,7 +54,6 @@ static int do_lstat(const char *file_name, struct stat *buf)
 		buf->st_uid = 0;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not 
a stat64 */
-		buf->st_blocks = size_to_blocks(buf->st_size);
 		buf->st_dev = _getdrive() - 1;
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
@@ -142,7 +136,6 @@ int mingw_fstat(int fd, struct mingw_stat *buf)
 		buf->st_uid = st.st_uid;
 		buf->st_mode = st.st_mode;
 		buf->st_size = st.st_size;
-		buf->st_blocks = size_to_blocks(buf->st_size);
 		buf->st_dev = st.st_dev;
 		buf->st_atime = st.st_atime;
 		buf->st_mtime = st.st_mtime;
@@ -164,7 +157,6 @@ int mingw_fstat(int fd, struct mingw_stat *buf)
 		buf->st_uid = 0;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not 
a stat64 */
-		buf->st_blocks = size_to_blocks(buf->st_size);
 		buf->st_dev = _getdrive() - 1;
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
diff --git a/compat/mingw.h b/compat/mingw.h
index a52e657..1472d59 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -169,7 +169,6 @@ struct mingw_stat {
 	time_t st_mtime, st_atime, st_ctime;
 	unsigned st_dev, st_ino, st_uid, st_gid;
 	size_t st_size;
-	size_t st_blocks;
 };
 int mingw_lstat(const char *file_name, struct mingw_stat *buf);
 int mingw_fstat(int fd, struct mingw_stat *buf);
diff --git a/git-compat-util.h b/git-compat-util.h
index a843444..d6b9a43 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -193,6 +193,12 @@ extern int git_munmap(void *start, size_t length);
 
 #endif /* NO_MMAP */
 
+#ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
+#define stat_to_kilobytes(st) ((((st).st_size+511) / 512) / 2)
+#else
+#define stat_to_kilobytes(st) ((st).st_blocks / 2)
+#endif
+
 #define DEFAULT_PACKED_GIT_LIMIT \
 	((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
 
-- 
1.6.0.rc2.4.g07fd3

[PATCH 2/2] Revert "Windows: Use a customized struct stat that also has the st_blocks member."

From: Johannes Sixt <hidden>
Date: 2016-06-15 22:45:10

This reverts commit fc2ded5b08e071beed974117c0148781b1acc94a.

Signed-off-by: Johannes Sixt <redacted>
---
And this is the follow-up to revert to the regular struct stat on MinGW.

BTW, do we sign-off reverts?

 compat/mingw.c |   28 ++++++++--------------------
 compat/mingw.h |   15 +++------------
 2 files changed, 11 insertions(+), 32 deletions(-)
diff --git a/compat/mingw.c b/compat/mingw.c
index 798fb61..ccfa2a0 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -52,9 +52,10 @@ static int do_lstat(const char *file_name, struct stat *buf)
 		buf->st_ino = 0;
 		buf->st_gid = 0;
 		buf->st_uid = 0;
+		buf->st_nlink = 1;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not 
a stat64 */
-		buf->st_dev = _getdrive() - 1;
+		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
 		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
@@ -88,7 +89,7 @@ static int do_lstat(const char *file_name, struct stat *buf)
  * complete. Note that Git stat()s are redirected to mingw_lstat()
  * too, since Windows doesn't really handle symlinks that well.
  */
-int mingw_lstat(const char *file_name, struct mingw_stat *buf)
+int mingw_lstat(const char *file_name, struct stat *buf)
 {
 	int namelen;
 	static char alt_name[PATH_MAX];
@@ -116,8 +117,7 @@ int mingw_lstat(const char *file_name, struct mingw_stat *buf)
 }
 
 #undef fstat
-#undef stat
-int mingw_fstat(int fd, struct mingw_stat *buf)
+int mingw_fstat(int fd, struct stat *buf)
 {
 	HANDLE fh = (HANDLE)_get_osfhandle(fd);
 	BY_HANDLE_FILE_INFORMATION fdata;
@@ -127,21 +127,8 @@ int mingw_fstat(int fd, struct mingw_stat *buf)
 		return -1;
 	}
 	/* direct non-file handles to MS's fstat() */
-	if (GetFileType(fh) != FILE_TYPE_DISK) {
-		struct stat st;
-		if (fstat(fd, &st))
-			return -1;
-		buf->st_ino = st.st_ino;
-		buf->st_gid = st.st_gid;
-		buf->st_uid = st.st_uid;
-		buf->st_mode = st.st_mode;
-		buf->st_size = st.st_size;
-		buf->st_dev = st.st_dev;
-		buf->st_atime = st.st_atime;
-		buf->st_mtime = st.st_mtime;
-		buf->st_ctime = st.st_ctime;
-		return 0;
-	}
+	if (GetFileType(fh) != FILE_TYPE_DISK)
+		return fstat(fd, buf);
 
 	if (GetFileInformationByHandle(fh, &fdata)) {
 		int fMode = S_IREAD;
@@ -155,9 +142,10 @@ int mingw_fstat(int fd, struct mingw_stat *buf)
 		buf->st_ino = 0;
 		buf->st_gid = 0;
 		buf->st_uid = 0;
+		buf->st_nlink = 1;
 		buf->st_mode = fMode;
 		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not 
a stat64 */
-		buf->st_dev = _getdrive() - 1;
+		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
 		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
 		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
 		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
diff --git a/compat/mingw.h b/compat/mingw.h
index 1472d59..4f275cb 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -162,21 +162,12 @@ int mingw_rename(const char*, const char*);
 
 /* Use mingw_lstat() instead of lstat()/stat() and
  * mingw_fstat() instead of fstat() on Windows.
- * struct stat is redefined because it lacks the st_blocks member.
  */
-struct mingw_stat {
-	unsigned st_mode;
-	time_t st_mtime, st_atime, st_ctime;
-	unsigned st_dev, st_ino, st_uid, st_gid;
-	size_t st_size;
-};
-int mingw_lstat(const char *file_name, struct mingw_stat *buf);
-int mingw_fstat(int fd, struct mingw_stat *buf);
+int mingw_lstat(const char *file_name, struct stat *buf);
+int mingw_fstat(int fd, struct stat *buf);
 #define fstat mingw_fstat
 #define lstat mingw_lstat
-#define stat mingw_stat
-static inline int mingw_stat(const char *file_name, struct mingw_stat *buf)
-{ return mingw_lstat(file_name, buf); }
+#define stat(x,y) mingw_lstat(x,y)
 
 int mingw_utime(const char *file_name, const struct utimbuf *times);
 #define utime mingw_utime
-- 
1.6.0.rc2.4.g07fd3

Re: [PATCH 1/2] compat: introduce stat_to_kilobytes

From: Andreas Färber <hidden>
Date: 2016-06-15 22:45:11

Am 18.08.2008 um 21:57 schrieb Johannes Sixt:
From: Junio C Hamano <redacted>

Some platforms do not have st_blocks member in "struct stat"; mingw
already emulates it by rounding it up to closest 512-byte blocks (even
though it could overcount when a file has holes).

The reason to use the member is only to figure out how many  
kilobytes the
file occupies on-disk, so give a helper in git-compat-util.h to help  
these
platforms.

Signed-off-by: Junio C Hamano <redacted>
Acked-by: Johannes Sixt <redacted>
---
On Sonntag, 17. August 2008, Junio C Hamano wrote:
quoted
  The comment before "struct mingw_stat" suggests that the only  
reason
  this compatiblity definition exists is to add st_blocks member,  
so I
  suspect we could remove the definition and simplify the  
compatibility
  layer a lot more, but I do not know MinGW, so I am CC'ing j6t here.
Makes sense. Here it is again, with the Makefile fixup noted by  
Andreas.
I have tested this on Haiku, compiles okay and simplifies my patches.

Thanks,
Andreas
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help