File lazystatfs.diff of Package rpm

--- ./configure.ac.orig	2009-11-20 10:52:42.000000000 +0000
+++ ./configure.ac	2009-11-20 10:53:56.000000000 +0000
@@ -672,25 +672,25 @@ dnl
 found_struct_statfs=no
 
 if test X$found_struct_statfs = Xno ; then
-dnl Solaris 2.6+ wants to use statvfs
+dnl first try including sys/vfs.h
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#include <sys/statvfs.h> ]], [[struct statvfs sfs;]])],[AC_MSG_RESULT(in sys/statvfs.h)
-	AC_DEFINE(STATFS_IN_SYS_STATVFS, 1,
-		[statfs in <sys/statvfs.h> (for solaris 2.6+ systems)])
+#include <sys/vfs.h> ]], [[struct statfs sfs;]])],[AC_MSG_RESULT(in sys/vfs.h)
+	AC_DEFINE(STATFS_IN_SYS_VFS, 1, [statfs in <sys/vfs.h> (for linux systems)])
 	found_struct_statfs=yes],[])
 fi
 
 if test X$found_struct_statfs = Xno ; then
-dnl first try including sys/vfs.h
+dnl Solaris 2.6+ wants to use statvfs
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
-#include <sys/vfs.h> ]], [[struct statfs sfs;]])],[AC_MSG_RESULT(in sys/vfs.h)
-	AC_DEFINE(STATFS_IN_SYS_VFS, 1, [statfs in <sys/vfs.h> (for linux systems)])
+#include <sys/statvfs.h> ]], [[struct statvfs sfs;]])],[AC_MSG_RESULT(in sys/statvfs.h)
+	AC_DEFINE(STATFS_IN_SYS_STATVFS, 1,
+		[statfs in <sys/statvfs.h> (for solaris 2.6+ systems)])
 	found_struct_statfs=yes],[])
 fi
 
--- ./lib/rpmts.c.orig	2009-11-20 10:52:41.000000000 +0000
+++ ./lib/rpmts.c	2009-11-20 11:11:58.000000000 +0000
@@ -1215,81 +1215,101 @@ rpmdb rpmtsGetRdb(rpmts ts)
 
 int rpmtsInitDSI(const rpmts ts)
 {
-    rpmDiskSpaceInfo dsi;
-    struct stat sb;
-    int rc;
-    int i;
-
     if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_DISKSPACE)
 	return 0;
-
-    rpmMessage(RPMMESS_DEBUG, _("mounted filesystems:\n"));
-    rpmMessage(RPMMESS_DEBUG,
-	_("    i        dev    bsize       bavail       iavail mount point\n"));
-
-    rc = rpmGetFilesystemList(&ts->filesystems, &ts->filesystemCount);
-    if (rc || ts->filesystems == NULL || ts->filesystemCount <= 0)
-	return rc;
-
-    /* Get available space on mounted file systems. */
-
     ts->dsi = _free(ts->dsi);
-    ts->dsi = xcalloc((ts->filesystemCount + 1), sizeof(*ts->dsi));
+    ts->dsi = xcalloc(1, sizeof(*ts->dsi));
+    return 0;
+}
 
-    dsi = ts->dsi;
+static rpmDiskSpaceInfo rpmtsCreateDSI(const rpmts ts, dev_t dev, const char *dirName, int count)
+{
+    rpmDiskSpaceInfo dsi;
+    struct stat sb;
+    int rc;
 
-    if (dsi != NULL)
-    for (i = 0; (i < ts->filesystemCount) && dsi; i++, dsi++) {
 #if STATFS_IN_SYS_STATVFS
-	struct statvfs sfb;
-	memset(&sfb, 0, sizeof(sfb));
-	rc = statvfs(ts->filesystems[i], &sfb);
+    struct statvfs sfb;
+    memset(&sfb, 0, sizeof(sfb));
+    rc = statvfs(dirName, &sfb);
 #else
-	struct statfs sfb;
-	memset(&sfb, 0, sizeof(sfb));
+    struct statfs sfb;
+    memset(&sfb, 0, sizeof(sfb));
 #  if STAT_STATFS4
 /* This platform has the 4-argument version of the statfs call.  The last two
  * should be the size of struct statfs and 0, respectively.  The 0 is the
  * filesystem type, and is always 0 when statfs is called on a mounted
  * filesystem, as we're doing.
  */
-	rc = statfs(ts->filesystems[i], &sfb, sizeof(sfb), 0);
+    rc = statfs(dirName, &sfb, sizeof(sfb), 0);
 #  else
-	rc = statfs(ts->filesystems[i], &sfb);
+    rc = statfs(dirName, &sfb);
 #  endif
 #endif
-	if (rc)
-	    break;
+    if (rc)
+	return NULL;
 
-	rc = stat(ts->filesystems[i], &sb);
-	if (rc)
-	    break;
-	dsi->dev = sb.st_dev;
+    rc = stat(dirName, &sb);
+    if (rc)
+	return NULL;
+    if (sb.st_dev != dev)
+	return NULL;
 
-	dsi->bsize = sfb.f_bsize;
-	dsi->bneeded = 0;
-	dsi->ineeded = 0;
+    ts->dsi = xrealloc(ts->dsi, (count + 2) * sizeof(*ts->dsi));
+    dsi = ts->dsi + count;
+    memset(dsi, 0, 2 * sizeof(*dsi));
+    dsi->dev = dev;
+    dsi->bsize = sfb.f_bsize;
+    if (!dsi->bsize)
+	dsi->bsize = 512;	/* we need a bsize */
+    dsi->bneeded = 0;
+    dsi->ineeded = 0;
 #ifdef STATFS_HAS_F_BAVAIL
-	dsi->bavail = sfb.f_bavail;
+    dsi->bavail = sfb.f_bavail;
 #else
 /* FIXME: the statfs struct doesn't have a member to tell how many blocks are
  * available for non-superusers.  f_blocks - f_bfree is probably too big, but
  * it's about all we can do.
  */
-	dsi->bavail = sfb.f_blocks - sfb.f_bfree;
+    dsi->bavail = sfb.f_blocks - sfb.f_bfree;
 #endif
-	/* XXX Avoid FAT and other file systems that have not inodes. */
-	dsi->iavail = !(sfb.f_ffree == 0 && sfb.f_files == 0)
-				? sfb.f_ffree : -1;
-	rpmMessage(RPMMESS_DEBUG, _("%5d 0x%08x %8u %12ld %12ld %s\n"),
-		i, (unsigned) dsi->dev, (unsigned) dsi->bsize,
-		(signed long) dsi->bavail, (signed long) dsi->iavail,
-		ts->filesystems[i]);
+    /* XXX Avoid FAT and other file systems that have not inodes. */
+    dsi->iavail = !(sfb.f_ffree == 0 && sfb.f_files == 0)
+			    ? sfb.f_ffree : -1;
+
+    return dsi;
+}
+
+static void rpmtsFindDSIMount(const rpmts ts, rpmDiskSpaceInfo dsi)
+{
+    int i;
+    struct stat sb;
+
+    /* must leave chroot for this */
+    if (rpmtsChrootDone(ts)) {
+	chroot(".");
+    }
+    if (!ts->filesystemCount)
+	rpmGetFilesystemList(&ts->filesystems, &ts->filesystemCount);
+    for (i = 0; i < ts->filesystemCount; i++) {
+	if (stat(ts->filesystems[i], &sb))
+	    continue;
+	if (sb.st_dev == dsi->dev) {
+	    dsi->mntPoint = ts->filesystems[i];
+	    break;
+	}
+    }
+    if (i == ts->filesystemCount) {
+	/* file system not found, create something to display */
+	dsi->mntPoint = xmalloc(20);
+	sprintf(dsi->mntPoint, "dev 0x%08x", (unsigned)dsi->dev);
+    }
+    if (rpmtsChrootDone(ts)) {
+	chroot(ts->rootDir);
     }
-    return rc;
 }
 
-void rpmtsUpdateDSI(const rpmts ts, dev_t dev,
+void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,
 		uint_32 fileSize, uint_32 prevSize, uint_32 fixupSize,
 		fileAction action)
 {
@@ -1300,8 +1320,10 @@ void rpmtsUpdateDSI(const rpmts ts, dev_
     if (dsi) {
 	while (dsi->bsize && dsi->dev != dev)
 	    dsi++;
-	if (dsi->bsize == 0)
-	    dsi = NULL;
+	if (dsi->bsize == 0) {
+	    /* create new entry */
+	    dsi = rpmtsCreateDSI(ts, dev, dirName, dsi - ts->dsi);
+	}
     }
     if (dsi == NULL)
 	return;
@@ -1344,32 +1366,32 @@ void rpmtsCheckDSIProblems(const rpmts t
     rpmDiskSpaceInfo dsi;
     rpmps ps;
     int fc;
-    int i;
-
-    if (ts->filesystems == NULL || ts->filesystemCount <= 0)
-	return;
 
     dsi = ts->dsi;
-    if (dsi == NULL)
+    if (dsi == NULL || !dsi->bsize)
 	return;
     fc = rpmfiFC( rpmteFI(te, RPMTAG_BASENAMES) );
     if (fc <= 0)
 	return;
 
     ps = rpmtsProblems(ts);
-    for (i = 0; i < ts->filesystemCount; i++, dsi++) {
+    for (; dsi->bsize; dsi++) {
 
 	if (dsi->bavail >= 0 && adj_fs_blocks(dsi->bneeded) > dsi->bavail) {
+	    if (!dsi->mntPoint)
+		rpmtsFindDSIMount(ts, dsi);
 	    rpmpsAppend(ps, RPMPROB_DISKSPACE,
 			rpmteNEVRA(te), rpmteKey(te),
-			ts->filesystems[i], NULL, NULL,
+			dsi->mntPoint, NULL, NULL,
  	   (adj_fs_blocks(dsi->bneeded)) * dsi->bsize);
 	}
 
 	if (dsi->iavail >= 0 && adj_fs_blocks(dsi->ineeded) > dsi->iavail) {
+	    if (!dsi->mntPoint)
+		rpmtsFindDSIMount(ts, dsi);
 	    rpmpsAppend(ps, RPMPROB_DISKNODES,
 			rpmteNEVRA(te), rpmteKey(te),
-			ts->filesystems[i], NULL, NULL,
+			dsi->mntPoint, NULL, NULL,
  	    (adj_fs_blocks(dsi->ineeded)));
 	}
     }
--- ./lib/rpmts.h.orig	2009-11-20 10:52:41.000000000 +0000
+++ ./lib/rpmts.h	2009-11-20 11:06:17.000000000 +0000
@@ -201,6 +201,7 @@ typedef	/*@abstract@*/ struct diskspaceI
 /** \ingroup rpmts
  */
 struct diskspaceInfo_s {
+    const char *mntPoint;	/*!< File system mount point */
     dev_t dev;			/*!< File system device number. */
     signed long bneeded;	/*!< No. of blocks needed. */
     signed long ineeded;	/*!< No. of inodes needed. */
@@ -876,7 +877,7 @@ int rpmtsInitDSI(const rpmts ts)
  * @param fixupSize	size difference (if
  * @param action	file disposition
  */
-void rpmtsUpdateDSI(const rpmts ts, dev_t dev,
+void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,
 		uint_32 fileSize, uint_32 prevSize, uint_32 fixupSize,
 		fileAction action)
 	/*@modifies ts @*/;
--- ./lib/transaction.c.orig	2009-11-20 10:52:42.000000000 +0000
+++ ./lib/transaction.c	2009-11-20 11:06:54.000000000 +0000
@@ -663,7 +663,7 @@ assert(otherFi != NULL);
 /*@=boundswrite@*/
 
 	/* Update disk space info for a file. */
-	rpmtsUpdateDSI(ts, fiFps->entry->dev, rpmfiFSize(fi),
+	rpmtsUpdateDSI(ts, fiFps->entry->dev, fiFps->entry->dirName, rpmfiFSize(fi),
 		fi->replacedSizes[i], fixupSize, fi->actions[i]);
 
     }