summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/be_local.c
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-02-15 23:56:44 +0100
committerDan McGee <dan@archlinux.org>2011-02-15 23:58:08 +0100
commitd1cc1ef6c31dc193adcf48a9aea4a95830c7ae56 (patch)
treea0808496f537757e32cfc25b0bd83c14a98a6fb0 /lib/libalpm/be_local.c
parent62a2e45b12f746c098523782fb5889793ef59687 (diff)
downloadpacman-d1cc1ef6c31dc193adcf48a9aea4a95830c7ae56.tar.gz
pacman-d1cc1ef6c31dc193adcf48a9aea4a95830c7ae56.tar.xz
Fix some database size estimation problems
* Use stat() and not lstat(); we don't care for the size of the symlink if it is one, we want the size of the reference file. * FS#22896, fix local database estimation on platforms that don't abide by the nlink assumption for number of children. * Fix a missing newline on an error message. Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'lib/libalpm/be_local.c')
-rw-r--r--lib/libalpm/be_local.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index 58582705..c1e86a63 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -367,7 +367,8 @@ static int is_dir(const char *path, struct dirent *entry)
static int local_db_populate(pmdb_t *db)
{
- int est_count, count = 0;
+ size_t est_count;
+ int count = 0;
struct stat buf;
struct dirent *ent = NULL;
const char *dbpath;
@@ -379,17 +380,36 @@ static int local_db_populate(pmdb_t *db)
dbpath = _alpm_db_path(db);
if(dbpath == NULL) {
- return(-1);
+ RET_ERR(PM_ERR_DB_OPEN, -1);
}
dbdir = opendir(dbpath);
if(dbdir == NULL) {
- return(0);
+ if(errno == ENOENT) {
+ /* no database existing yet is not an error */
+ return(0);
+ }
+ RET_ERR(PM_ERR_DB_OPEN, -1);
}
if(fstat(dirfd(dbdir), &buf) != 0) {
- return(0);
+ RET_ERR(PM_ERR_DB_OPEN, -1);
+ }
+ if(buf.st_nlink >= 2) {
+ est_count = buf.st_nlink;
+ } else {
+ /* Some filesystems don't subscribe to the two-implicit links school of
+ * thought, e.g. BTRFS, HFS+. See
+ * http://kerneltrap.org/mailarchive/linux-btrfs/2010/1/23/6723483/thread
+ */
+ est_count = 0;
+ while((ent = readdir(dbdir)) != NULL) {
+ est_count++;
+ }
+ rewinddir(dbdir);
+ }
+ if(est_count >= 2) {
+ /* subtract the two extra pointers to get # of children */
+ est_count -= 2;
}
- /* subtract the two always-there pointers to get # of children */
- est_count = (int)buf.st_nlink - 2;
/* initialize hash at 50% full */
db->pkgcache = _alpm_pkghash_create(est_count * 2);