summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillem Jover <guillem@debian.org>2018-06-02 16:05:32 +0200
committerGuillem Jover <guillem@debian.org>2018-08-30 03:14:08 +0200
commit93424411d3b840f1a88a42b97b226e34b193e81b (patch)
tree3161ee71ae1c0fb209f53a7df91f9fe0e3cd7aed
parent5a678bf493de3630cb2dd58e8d124a86c74568ab (diff)
downloaddpkg-93424411d3b840f1a88a42b97b226e34b193e81b.tar.gz
libdpkg: Switch to a new tiny struct to track file ondisk identity
We only need the device and inode numbers for a given file to be able to compare them for identity. Avoid storing the entire struct stat which is rather fat.
-rw-r--r--debian/changelog2
-rw-r--r--lib/dpkg/fsys-hash.c4
-rw-r--r--lib/dpkg/fsys.h10
-rw-r--r--src/unpack.c20
4 files changed, 25 insertions, 11 deletions
diff --git a/debian/changelog b/debian/changelog
index 4fa07bb48..a3ab57e77 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -187,6 +187,8 @@ dpkg (1.19.1) UNRELEASED; urgency=medium
- libdpkg: Simplify pkg_files_blank() by using a pointer to pointer to
track the previous entry.
- libdpkg: Factor out package files handling into its own module.
+ - libdpkg: Switch to a new tiny struct to track file on-disk identity.
+ This should reduce the run-time memory used.
* Build system:
- Set distribution tarball format to ustar, instead of default v7 format.
- Mark PO4A and POD2MAN as precious variables.
diff --git a/lib/dpkg/fsys-hash.c b/lib/dpkg/fsys-hash.c
index 54d0d57b7..15d9669b4 100644
--- a/lib/dpkg/fsys-hash.c
+++ b/lib/dpkg/fsys-hash.c
@@ -51,7 +51,7 @@ filesdbinit(void)
fnn->flags = 0;
fnn->oldhash = NULL;
fnn->newhash = EMPTYHASHFLAG;
- fnn->filestat = NULL;
+ fnn->file_ondisk_id = NULL;
}
}
}
@@ -117,7 +117,7 @@ findnamenode(const char *name, enum fnnflags flags)
newnode->statoverride = NULL;
newnode->oldhash = NULL;
newnode->newhash = EMPTYHASHFLAG;
- newnode->filestat = NULL;
+ newnode->file_ondisk_id = NULL;
newnode->trig_interested = NULL;
*pointerp = newnode;
nfiles++;
diff --git a/lib/dpkg/fsys.h b/lib/dpkg/fsys.h
index 7d63b04e6..8a2efbffa 100644
--- a/lib/dpkg/fsys.h
+++ b/lib/dpkg/fsys.h
@@ -77,6 +77,14 @@ enum filenamenode_flags {
fnnf_filtered = DPKG_BIT(9),
};
+/**
+ * Stores information to uniquely identify an on-disk file.
+ */
+struct file_ondisk_id {
+ dev_t id_dev;
+ ino_t id_ino;
+};
+
struct filenamenode {
struct filenamenode *next;
const char *name;
@@ -105,7 +113,7 @@ struct filenamenode {
/** Valid iff the file was unpacked and hashed on this run. */
const char *newhash;
- struct stat *filestat;
+ struct file_ondisk_id *file_ondisk_id;
};
/**
diff --git a/src/unpack.c b/src/unpack.c
index 827211d63..cae756222 100644
--- a/src/unpack.c
+++ b/src/unpack.c
@@ -608,7 +608,7 @@ pkg_remove_old_files(struct pkginfo *pkg,
} else {
struct fileinlist *sameas = NULL;
struct fileinlist *cfile;
- static struct stat empty_stat;
+ static struct file_ondisk_id empty_ondisk_id;
struct varbuf cfilename = VARBUF_INIT;
/*
@@ -637,7 +637,7 @@ pkg_remove_old_files(struct pkginfo *pkg,
if (cfile->namenode->flags & fnnf_filtered)
continue;
- if (!cfile->namenode->filestat) {
+ if (cfile->namenode->file_ondisk_id == NULL) {
struct stat tmp_stat;
varbuf_reset(&cfilename);
@@ -646,22 +646,26 @@ pkg_remove_old_files(struct pkginfo *pkg,
varbuf_end_str(&cfilename);
if (lstat(cfilename.buf, &tmp_stat) == 0) {
- cfile->namenode->filestat = nfmalloc(sizeof(struct stat));
- memcpy(cfile->namenode->filestat, &tmp_stat, sizeof(struct stat));
+ struct file_ondisk_id *file_ondisk_id;
+
+ file_ondisk_id = nfmalloc(sizeof(*file_ondisk_id));
+ file_ondisk_id->id_dev = tmp_stat.st_dev;
+ file_ondisk_id->id_ino = tmp_stat.st_ino;
+ cfile->namenode->file_ondisk_id = file_ondisk_id;
} else {
if (!(errno == ENOENT || errno == ELOOP || errno == ENOTDIR))
ohshite(_("unable to stat other new file '%.250s'"),
cfile->namenode->name);
- cfile->namenode->filestat = &empty_stat;
+ cfile->namenode->file_ondisk_id = &empty_ondisk_id;
continue;
}
}
- if (cfile->namenode->filestat == &empty_stat)
+ if (cfile->namenode->file_ondisk_id == &empty_ondisk_id)
continue;
- if (oldfs.st_dev == cfile->namenode->filestat->st_dev &&
- oldfs.st_ino == cfile->namenode->filestat->st_ino) {
+ if (oldfs.st_dev == cfile->namenode->file_ondisk_id->id_dev &&
+ oldfs.st_ino == cfile->namenode->file_ondisk_id->id_ino) {
if (sameas)
warning(_("old file '%.250s' is the same as several new files! "
"(both '%.250s' and '%.250s')"), fnamevb.buf,