Welcome to Soft32 Linux Forums!
FAQFAQ    SearchSearch      ProfileProfile    Private MessagesPrivate Messages   Log inLog in

[PATCH] Use FIEMAP to sort .list files before scanning

 
   Soft32 Home -> Linux -> PacKaGe RSS
Next:  Accepted tegaki-recognize 0.3-1 (source all)  
Author Message
Morten Hustveit

External


Since: Mar 19, 2009
Posts: 2



(Msg. 1) Posted: Tue Nov 03, 2009 11:20 am
Post subject: [PATCH] Use FIEMAP to sort .list files before scanning
Archived from groups: linux>debian>maint>dpkg (more info?)

This is a revision of an earlier patch, based on comments from Guillem Jover:

http://lists.debian.org/debian-dpkg/2009/10/msg00003.html

When running dpkg from a cold cache on a system where /var/lib/dpkg/info/ lies
on a harddisk, a lot of time is spent waiting for seeks between (typically)
thousands of files. This patch changes the behavior of
ensure_allinstfiles_available, so that it accesses the packages in the order of
their .list files' physical locations on the harddisk, greatly reducing
drive head movements.

The performance improvement is around 330% on my system: reinstalling a simple
package takes 8 seconds instead of 27 seconds. I dropped the caches before
each run, and did 10 runs with consistent results. The performance is
identical to the previous patch using FIBMAP.
---
configure.ac | 2 +-
src/filesdb.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
src/main.h | 1 +
3 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2272eb0..54cdb6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,7 +79,7 @@ fi
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stddef.h error.h locale.h libintl.h kvm.h \
- sys/cdefs.h sys/syscall.h])
+ sys/cdefs.h sys/syscall.h linux/fiemap.h])
DPKG_CHECK_DEFINE(TIOCNOTTY, [sys/ioctl.h])

# Checks for typedefs, structures, and compiler characteristics.
diff --git a/src/filesdb.c b/src/filesdb.c
index 0cc0791..a2eda65 100644
--- a/src/filesdb.c
+++ b/src/filesdb.c
@@ -26,6 +26,12 @@
#include <sys/types.h>
#include <sys/stat.h>

+#if HAVE_LINUX_FIEMAP_H
+#include <linux/fiemap.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+#endif
+
#include <assert.h>
#include <errno.h>
#include <string.h>
@@ -40,6 +46,7 @@
#include <dpkg/dpkg-db.h>
#include <dpkg/path.h>
#include <dpkg/buffer.h>
+#include <dpkg/pkg-array.h>
#include <dpkg/progress.h>

#include "filesdb.h"
@@ -60,6 +67,7 @@ ensure_package_clientdata(struct pkginfo *pkg)
pkg->clientdata->fileslistvalid = 0;
pkg->clientdata->files = NULL;
pkg->clientdata->trigprocdeferred = NULL;
+ pkg->clientdata->listfile_phys_offset = 0;
}

void note_must_reread_files_inpackage(struct pkginfo *pkg) {
@@ -254,10 +262,29 @@ ensure_packagefiles_available(struct pkginfo *pkg)
pkg->clientdata->fileslistvalid= 1;
}

+#if HAVE_LINUX_FIEMAP_H
+int
+pkg_sorter_by_listfile_phys_offset(const void *a, const void *b) {
+ struct pkginfo *const *lhs = a;
+ struct pkginfo *const *rhs = b;
+
+ /* We can't simply subtract, because the difference may be greater than INT_MAX.
+ */
+ if((*lhs)->clientdata->listfile_phys_offset < (*rhs)->clientdata->listfile_phys_offset)
+ return -1;
+ else
+ return 1;
+}
+#endif
+
void ensure_allinstfiles_available(void) {
- struct pkgiterator *it;
struct pkginfo *pkg;
struct progress progress;
+ struct pkg_array array;
+ int i;
+#if HAVE_LINUX_FIEMAP_H
+ int blocksize;
+#endif

if (allpackagesdone) return;
if (saidread<2) {
@@ -267,14 +294,56 @@ void ensure_allinstfiles_available(void) {
progress_init(&progress, _("(Reading database ... "), max);
}

- it= iterpkgstart();
- while ((pkg = iterpkgnext(it)) != NULL) {
+ pkg_array_init_from_db(&array);
+
+ /* Sort packages by the physical location of their list files, so that
+ * scanning them later will minimize disk drive head movements.
+ */
+#if HAVE_LINUX_FIEMAP_H
+ for (i = 0; i < array.n_pkgs; i++) {
+ pkg = array.pkgs[i];
+ if(!pkg->clientdata->listfile_phys_offset
+ && pkg->status != stat_notinstalled) {
+ struct {
+ struct fiemap fiemap;
+ struct fiemap_extent extent;
+ } fm;
+ const char *listfile;
+ int fd;
+
+ pkg->clientdata->listfile_phys_offset = -1;
+
+ listfile= pkgadminfile(pkg, LISTFILE);
+
+ if(-1 == (fd= open(listfile, O_RDONLY)))
+ continue;
+
+ if(!blocksize && -1 == ioctl(fd, FIGETBSZ, &blocksize))
+ break;
+
+ memset(&fm, 0, sizeof(fm));
+ fm.fiemap.fm_start = 0;
+ fm.fiemap.fm_length = blocksize;
+ fm.fiemap.fm_flags = 0;
+ fm.fiemap.fm_extent_count = 1;
+
+ if(-1 != ioctl(fd, FS_IOC_FIEMAP, (unsigned long) &fm))
+ pkg->clientdata->listfile_phys_offset = fm.fiemap.fm_extents[0].fe_physical;
+
+ close(fd);
+ }
+ }
+ pkg_array_sort(&array, pkg_sorter_by_listfile_phys_offset);
+#endif
+
+ for (i = 0; i < array.n_pkgs; i++) {
+ pkg = array.pkgs[i];
ensure_packagefiles_available(pkg);

if (saidread == 1)
progress_step(&progress);
}
- iterpkgend(it);
+
allpackagesdone= 1;

if (saidread==1) {
diff --git a/src/main.h b/src/main.h
index cbcc2df..eefabff 100644
--- a/src/main.h
+++ b/src/main.h
@@ -46,6 +46,7 @@ struct perpackagestate {

/* Non-NULL iff in trigproc.c:deferred. */
struct pkg_list *trigprocdeferred;
+ off_t listfile_phys_offset;
};

enum action {
--
1.6.4.3


--
To UNSUBSCRIBE, email to debian-dpkg-REQUEST RemoveThis @lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster RemoveThis @lists.debian.org
Back to top
Login to vote
Display posts from previous:   
Related Topics:
[PATCH] slob: reduce list scanning - The version of SLOB in -mm always scans its free list from the beginning, which results in small allocations and free..

header files that are (sort of) referenced - based on that last response, i'm curious about which header files are technically "unreferenced" in the sourc...

[PATCH] Remove suggestion that Kconfig files can use "requ.. - Remove the note in the documentation that suggests people can use "requires" for dependencies in Kconfig file...

[PATCH] pci quirks: Sort out the VIA mess once and for all.. - Perform the VIA fixup only on the devices on the V-Link on the VIA bridges that have it, and nowhere else. Doing this....

[PATCH] AF_RXRPC: Sort out MTU handling - Sort out the MTU determination and handling in AF_RXRPC: (1) If it's present, parse the additional information..

2.4 Q: list of open files per inode? - How can a device driver go over the list of all the files that are open on a specific inode instance? I'd like to..
       Soft32 Home -> Linux -> PacKaGe All times are: Pacific Time (US & Canada) (change)
Page 1 of 1

 
You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Categories:
 Windows
  Linux
 Mac
 PDA


[ Contact us | Terms of Service/Privacy Policy ]