diff options
Diffstat (limited to 'lib/libalpm')
-rw-r--r-- | lib/libalpm/diskspace.c | 53 | ||||
-rw-r--r-- | lib/libalpm/diskspace.h | 7 |
2 files changed, 47 insertions, 13 deletions
diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c index 405bcd43..8fc4d9b0 100644 --- a/lib/libalpm/diskspace.c +++ b/lib/libalpm/diskspace.c @@ -69,22 +69,25 @@ static void mount_point_list_free(alpm_list_t *mount_points) FREELIST(mount_points); } -#if defined(HAVE_GETMNTENT) static int mount_point_load_fsinfo(alpm_handle_t *handle, alpm_mountpoint_t *mountpoint) { +#if defined(HAVE_GETMNTENT) /* grab the filesystem usage */ if(statvfs(mountpoint->mount_dir, &(mountpoint->fsp)) != 0) { _alpm_log(handle, ALPM_LOG_WARNING, _("could not get filesystem information for %s: %s\n"), mountpoint->mount_dir, strerror(errno)); + mountpoint->fsinfo_loaded = MOUNT_FSINFO_FAIL; return -1; } + _alpm_log(handle, ALPM_LOG_DEBUG, "loading fsinfo for %s\n", mountpoint->mount_dir); mountpoint->read_only = mountpoint->fsp.f_flag & ST_RDONLY; + mountpoint->fsinfo_loaded = MOUNT_FSINFO_LOADED; +#endif return 0; } -#endif static alpm_list_t *mount_point_list(alpm_handle_t *handle) { @@ -106,11 +109,6 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle) CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir = strdup(mnt->mnt_dir); mp->mount_dir_len = strlen(mp->mount_dir); - if(mount_point_load_fsinfo(handle, mp) < 0) { - free(mp->mount_dir); - free(mp); - continue; - } mount_points = alpm_list_add(mount_points, mp); } @@ -132,11 +130,6 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle) CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir = strdup(mnt->mnt_mountp); mp->mount_dir_len = strlen(mp->mount_dir); - if(mount_point_load_fsinfo(handle, mp) < 0) { - free(mp->mount_dir); - free(mp); - continue; - } mount_points = alpm_list_add(mount_points, mp); } @@ -169,6 +162,9 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle) mp->read_only = fsp->f_flags & MNT_RDONLY; #endif + /* we don't support lazy loading on this platform */ + mp->fsinfo_loaded = MOUNT_FSINFO_LOADED; + mount_points = alpm_list_add(mount_points, mp); } #endif @@ -177,7 +173,7 @@ static alpm_list_t *mount_point_list(alpm_handle_t *handle) mount_point_cmp); for(ptr = mount_points; ptr != NULL; ptr = ptr->next) { mp = ptr->data; - _alpm_log(handle, ALPM_LOG_DEBUG, "mountpoint: %s\n", mp->mount_dir); + _alpm_log(handle, ALPM_LOG_DEBUG, "discovered mountpoint: %s\n", mp->mount_dir); } return mount_points; } @@ -245,6 +241,18 @@ static int calculate_removed_size(alpm_handle_t *handle, continue; } + /* don't check a mount that we know we can't stat */ + if(mp && mp->fsinfo_loaded == MOUNT_FSINFO_FAIL) { + continue; + } + + /* lazy load filesystem info */ + if(mp->fsinfo_loaded == MOUNT_FSINFO_UNLOADED) { + if(mount_point_load_fsinfo(handle, mp) < 0) { + continue; + } + } + /* the addition of (divisor - 1) performs ceil() with integer division */ remove_size = (st.st_size + mp->fsp.f_bsize - 1) / mp->fsp.f_bsize; mp->blocks_needed -= remove_size; @@ -292,6 +300,18 @@ static int calculate_installed_size(alpm_handle_t *handle, continue; } + /* don't check a mount that we know we can't stat */ + if(mp && mp->fsinfo_loaded == MOUNT_FSINFO_FAIL) { + continue; + } + + /* lazy load filesystem info */ + if(mp->fsinfo_loaded == MOUNT_FSINFO_UNLOADED) { + if(mount_point_load_fsinfo(handle, mp) < 0) { + continue; + } + } + /* the addition of (divisor - 1) performs ceil() with integer division */ install_size = (file->size + mp->fsp.f_bsize - 1) / mp->fsp.f_bsize; mp->blocks_needed += install_size; @@ -352,6 +372,13 @@ int _alpm_check_downloadspace(alpm_handle_t *handle, const char *cachedir, goto finish; } + if(cachedir_mp->fsinfo_loaded == MOUNT_FSINFO_UNLOADED) { + if(mount_point_load_fsinfo(handle, cachedir_mp)) { + error = 1; + goto finish; + } + } + /* there's no need to check for a R/O mounted filesystem here, as * _alpm_filecache_setup will never give us a non-writable directory */ diff --git a/lib/libalpm/diskspace.h b/lib/libalpm/diskspace.h index a54aa5e3..591d9337 100644 --- a/lib/libalpm/diskspace.h +++ b/lib/libalpm/diskspace.h @@ -37,6 +37,12 @@ enum mount_used_level { USED_INSTALL = (1 << 1), }; +enum mount_fsinfo { + MOUNT_FSINFO_UNLOADED = 0, + MOUNT_FSINFO_LOADED, + MOUNT_FSINFO_FAIL, +}; + typedef struct __alpm_mountpoint_t { /* mount point information */ char *mount_dir; @@ -46,6 +52,7 @@ typedef struct __alpm_mountpoint_t { blkcnt_t max_blocks_needed; enum mount_used_level used; int read_only; + enum mount_fsinfo fsinfo_loaded; FSSTATSTYPE fsp; } alpm_mountpoint_t; |