mirror of
https://github.com/moparisthebest/pacman
synced 2024-08-13 17:03:46 -04:00
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>
This commit is contained in:
parent
62a2e45b12
commit
d1cc1ef6c3
@ -367,7 +367,8 @@ static int is_dir(const char *path, struct dirent *entry)
|
|||||||
|
|
||||||
static int local_db_populate(pmdb_t *db)
|
static int local_db_populate(pmdb_t *db)
|
||||||
{
|
{
|
||||||
int est_count, count = 0;
|
size_t est_count;
|
||||||
|
int count = 0;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
struct dirent *ent = NULL;
|
struct dirent *ent = NULL;
|
||||||
const char *dbpath;
|
const char *dbpath;
|
||||||
@ -379,17 +380,36 @@ static int local_db_populate(pmdb_t *db)
|
|||||||
|
|
||||||
dbpath = _alpm_db_path(db);
|
dbpath = _alpm_db_path(db);
|
||||||
if(dbpath == NULL) {
|
if(dbpath == NULL) {
|
||||||
return(-1);
|
RET_ERR(PM_ERR_DB_OPEN, -1);
|
||||||
}
|
}
|
||||||
dbdir = opendir(dbpath);
|
dbdir = opendir(dbpath);
|
||||||
if(dbdir == NULL) {
|
if(dbdir == NULL) {
|
||||||
|
if(errno == ENOENT) {
|
||||||
|
/* no database existing yet is not an error */
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
RET_ERR(PM_ERR_DB_OPEN, -1);
|
||||||
|
}
|
||||||
if(fstat(dirfd(dbdir), &buf) != 0) {
|
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 */
|
/* initialize hash at 50% full */
|
||||||
db->pkgcache = _alpm_pkghash_create(est_count * 2);
|
db->pkgcache = _alpm_pkghash_create(est_count * 2);
|
||||||
|
@ -171,7 +171,7 @@ static int sync_db_read(pmdb_t *db, struct archive *archive,
|
|||||||
* Unweighted Avg 2543.39 118.74 190.16 137.93
|
* Unweighted Avg 2543.39 118.74 190.16 137.93
|
||||||
* Average of Avgs 2564.44 124.08 191.06 143.46
|
* Average of Avgs 2564.44 124.08 191.06 143.46
|
||||||
*/
|
*/
|
||||||
static int estimate_package_count(struct stat *st, struct archive *archive)
|
static size_t estimate_package_count(struct stat *st, struct archive *archive)
|
||||||
{
|
{
|
||||||
unsigned int per_package;
|
unsigned int per_package;
|
||||||
|
|
||||||
@ -199,12 +199,13 @@ static int estimate_package_count(struct stat *st, struct archive *archive)
|
|||||||
/* assume it is at least somewhat compressed */
|
/* assume it is at least somewhat compressed */
|
||||||
per_package = 200;
|
per_package = 200;
|
||||||
}
|
}
|
||||||
return((int)(st->st_size / per_package) + 1);
|
return((size_t)(st->st_size / per_package) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sync_db_populate(pmdb_t *db)
|
static int sync_db_populate(pmdb_t *db)
|
||||||
{
|
{
|
||||||
int est_count, count = 0;
|
size_t est_count;
|
||||||
|
int count = 0;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
struct archive *archive;
|
struct archive *archive;
|
||||||
struct archive_entry *entry;
|
struct archive_entry *entry;
|
||||||
@ -227,7 +228,7 @@ static int sync_db_populate(pmdb_t *db)
|
|||||||
archive_read_finish(archive);
|
archive_read_finish(archive);
|
||||||
RET_ERR(PM_ERR_DB_OPEN, 1);
|
RET_ERR(PM_ERR_DB_OPEN, 1);
|
||||||
}
|
}
|
||||||
if(lstat(_alpm_db_path(db), &buf) != 0) {
|
if(stat(_alpm_db_path(db), &buf) != 0) {
|
||||||
RET_ERR(PM_ERR_DB_OPEN, 1);
|
RET_ERR(PM_ERR_DB_OPEN, 1);
|
||||||
}
|
}
|
||||||
est_count = estimate_package_count(&buf, archive);
|
est_count = estimate_package_count(&buf, archive);
|
||||||
|
@ -70,7 +70,7 @@ pmpkghash_t *_alpm_pkghash_create(size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(hash->buckets < size) {
|
if(hash->buckets < size) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("database larger than maximum size"));
|
_alpm_log(PM_LOG_ERROR, _("database larger than maximum size\n"));
|
||||||
free(hash);
|
free(hash);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user