1
1

Clip directory sizes to fit in a signed 64bit integer

This mostly avoids the issue of getting negative sizes. It's still
possible to get a negative size after refresh or deletion, I'll get to
that in a bit.
Этот коммит содержится в:
Yorhel 2012-11-22 13:33:32 +01:00
родитель 2bc1b3e479
Коммит ad84603bee
5 изменённых файлов: 15 добавлений и 4 удалений

Просмотреть файл

@ -276,6 +276,10 @@ links, and will thus be scanned and counted multiple times.
Some minor glitches may appear when displaying filenames that contain multibyte Some minor glitches may appear when displaying filenames that contain multibyte
or multicolumn characters. or multicolumn characters.
All sizes are internally represented as a signed 64bit integer. If you have a
directory larger than 8 EiB minus one byte, ncdu will clip its size to 8 EiB
minus one byte.
Please report any other bugs you may find at the bug tracker, which can be Please report any other bugs you may find at the bug tracker, which can be
found on the web site at http://dev.yorhel.nl/ncdu found on the web site at http://dev.yorhel.nl/ncdu

Просмотреть файл

@ -84,8 +84,8 @@ static void hlink_check(struct dir *d) {
if(pt==par) if(pt==par)
i=0; i=0;
if(i) { if(i) {
par->size += d->size; par->size = adds64(par->size, d->size);
par->asize += d->asize; par->asize = adds64(par->size, d->asize);
} }
} }
} }

Просмотреть файл

@ -29,6 +29,7 @@
#include "config.h" #include "config.h"
#include <stdio.h> #include <stdio.h>
#include <stddef.h> #include <stddef.h>
#include <limits.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>

Просмотреть файл

@ -287,8 +287,8 @@ struct dir *getroot(struct dir *d) {
void addparentstats(struct dir *d, int64_t size, int64_t asize, int items) { void addparentstats(struct dir *d, int64_t size, int64_t asize, int items) {
while(d) { while(d) {
d->size += size; d->size = adds64(d->size, size);
d->asize += asize; d->asize = adds64(d->asize, asize);
d->items += items; d->items += items;
d = d->parent; d = d->parent;
} }

Просмотреть файл

@ -81,6 +81,12 @@ char *getpath(struct dir *);
/* returns the root element of the given dir struct */ /* returns the root element of the given dir struct */
struct dir *getroot(struct dir *); struct dir *getroot(struct dir *);
/* Add two positive signed 64-bit integers. Returns INT64_MAX if the result
* would overflow.
* I use uint64_t's to detect the overflow, as (a + b < 0) relies on undefined
* behaviour, and (INT64_MAX - b >= a) didn't work for some reason. */
#define adds64(a, b) ((uint64_t)(a) + (uint64_t)(b) > (uint64_t)INT64_MAX ? INT64_MAX : (a)+(b))
/* Adds a value to the size, asize and items fields of *d and its parents */ /* Adds a value to the size, asize and items fields of *d and its parents */
void addparentstats(struct dir *, int64_t, int64_t, int); void addparentstats(struct dir *, int64_t, int64_t, int);