[pacman-dev] [PATCH 1/5] diskspace: add _alpm_check_downloadspace()

Dave Reisner d at falconindy.com
Sun Oct 16 14:59:13 EDT 2011


This function determines if the given cachedir has at least the given
amount of free space on it. This will be later used in the sync code to
preemptively halt downloads.

Signed-off-by: Dave Reisner <dreisner at archlinux.org>
---
 lib/libalpm/diskspace.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/libalpm/diskspace.h |    2 +
 2 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c
index 9dedbe1..d376444 100644
--- a/lib/libalpm/diskspace.c
+++ b/lib/libalpm/diskspace.c
@@ -253,6 +253,60 @@ static int check_mountpoint(alpm_handle_t *handle, alpm_mountpoint_t *mp)
 	return 0;
 }
 
+int _alpm_check_downloadspace(alpm_handle_t *handle, const char *cachedir,
+		size_t num_files, off_t *file_sizes)
+{
+	alpm_list_t *i, *mount_points;
+	alpm_mountpoint_t *cachedir_mp;
+	fsblkcnt_t blocks_needed = 0;
+	size_t j;
+	int error = 0;
+
+	mount_points = mount_point_list(handle);
+	if(mount_points == NULL) {
+		_alpm_log(handle, ALPM_LOG_ERROR, _("could not determine filesystem mount points\n"));
+		return -1;
+	}
+
+	cachedir_mp = match_mount_point(mount_points, cachedir);
+	if(cachedir == NULL) {
+		_alpm_log(handle, ALPM_LOG_ERROR, _("could not determine cachedir mount point %s\n"),
+				cachedir);
+		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-writeable directory */
+
+	/* round up the size of each file to the nearest block and accumulate */
+	for(j = 0; j < num_files; j++) {
+		blocks_needed += (file_sizes[j] + cachedir_mp->fsp.f_bsize + 1) /
+			cachedir_mp->fsp.f_bsize;
+	}
+
+	if(cachedir_mp->fsp.f_bfree < blocks_needed) {
+		_alpm_log(handle, ALPM_LOG_ERROR,
+				_("Partition %s too full: %jd blocks needed, %jd blocks free\n"),
+				cachedir_mp->mount_dir, (intmax_t)blocks_needed,
+				(uintmax_t)cachedir_mp->fsp.f_bfree);
+		error = 1;
+	}
+
+finish:
+	for(i = mount_points; i; i = i->next) {
+		alpm_mountpoint_t *data = i->data;
+		FREE(data->mount_dir);
+	}
+	FREELIST(mount_points);
+
+	if(error) {
+		RET_ERR(handle, ALPM_ERR_DISK_SPACE, -1);
+	}
+
+	return 0;
+}
+
 int _alpm_check_diskspace(alpm_handle_t *handle)
 {
 	alpm_list_t *mount_points, *i;
diff --git a/lib/libalpm/diskspace.h b/lib/libalpm/diskspace.h
index 5944bb1..a613e23 100644
--- a/lib/libalpm/diskspace.h
+++ b/lib/libalpm/diskspace.h
@@ -50,6 +50,8 @@ typedef struct __alpm_mountpoint_t {
 } alpm_mountpoint_t;
 
 int _alpm_check_diskspace(alpm_handle_t *handle);
+int _alpm_check_downloadspace(alpm_handle_t *handle, const char *cachedir,
+		size_t num_files, off_t *file_sizes);
 
 #endif /* _ALPM_DISKSPACE_H */
 
-- 
1.7.7



More information about the pacman-dev mailing list