diff --git a/Kconfig b/Kconfig index df3719a4..62381dda 100644 --- a/Kconfig +++ b/Kconfig @@ -99,6 +99,25 @@ config MARS_MIN_SPACE ---help--- Normally ON. Switch off only for EXPERIMENTS! +config MARS_MIN_SPACE_BASE + int "free space in /mars/ (hard limit in gigabytes)" + depends on MARS && MARS_MIN_SPACE + default 8 + ---help--- + when this limit is exceeded, all write requests to /mars/ + will stop. This affects not only write IO to /dev/mars/*, + but also logfile transfers etc. + In order to retain full operations, you _need_ to implement + your own monitoring which _must_ warn you long before this + hard limit catches you. + +config MARS_MIN_SPACE_PERCENT + int "free space in /mars/ (hard limit in percent)" + depends on MARS && MARS_MIN_SPACE + default 0 + ---help--- + this limit is in addition to CONFIG_MARS_MIN_SPACE_BASE. + config MARS_PREFER_SIO bool "prefer sio bricks instead of aio" depends on MARS diff --git a/sy_old/mars_light.c b/sy_old/mars_light.c index ce049d41..14e4f3f6 100644 --- a/sy_old/mars_light.c +++ b/sy_old/mars_light.c @@ -119,11 +119,10 @@ struct light_class { //#define COPY_APPEND_MODE 1 // FIXME: does not work yet #define COPY_PRIO MARS_PRIO_LOW -#define MIN_SPACE (1024 * 1024 * 8) // 8 GB #ifdef CONFIG_MARS_MIN_SPACE -#define EXHAUSTED(x) ((x) <= MIN_SPACE) +#define EXHAUSTED(x,max) ((x) <= ((max) / 100 * CONFIG_MARS_MIN_SPACE_PERCENT + CONFIG_MARS_MIN_SPACE_BASE * 1024 * 1024)) #else -#define EXHAUSTED(x) (false) +#define EXHAUSTED(x,max) (false) #endif static @@ -498,6 +497,7 @@ struct mars_rotate { struct mars_dent *prev_log; struct mars_dent *next_log; struct if_brick *if_brick; + loff_t total_space; loff_t remaining_space; loff_t copy_end_pos; loff_t start_pos; @@ -1597,7 +1597,7 @@ int make_log_init(void *buf, struct mars_dent *dent) rot->max_sequence = 0; rot->has_error = false; - rot->remaining_space = mars_remaining_space(parent_path); + mars_remaining_space(parent_path, &rot->total_space, &rot->remaining_space); /* Fetch the replay status symlink. * It must exist, and its value will control everything. @@ -3428,8 +3428,8 @@ static int light_thread(void *data) _global.global_power.button = !kthread_should_stop(); _make_alivelink("alive", _global.global_power.button); - _global.remaining_space = mars_remaining_space("/mars"); - exhausted = EXHAUSTED(_global.remaining_space); + mars_remaining_space("/mars", &_global.total_space, &_global.remaining_space); + exhausted = EXHAUSTED(_global.remaining_space, _global.total_space); _global.exhausted = exhausted; _make_alivelink("exhausted", exhausted); if (exhausted) diff --git a/sy_old/strategy.h b/sy_old/strategy.h index 0b38385d..ca9ffcc2 100644 --- a/sy_old/strategy.h +++ b/sy_old/strategy.h @@ -53,6 +53,7 @@ struct mars_global { struct list_head brick_anchor; struct list_head server_anchor; wait_queue_head_t main_event; + loff_t total_space; loff_t remaining_space; int global_version; volatile bool main_trigger; @@ -121,7 +122,7 @@ extern int mars_symlink(const char *oldpath, const char *newpath, const struct t extern int mars_rename(const char *oldpath, const char *newpath); extern int mars_chmod(const char *path, mode_t mode); extern int mars_lchown(const char *path, uid_t uid); -extern loff_t mars_remaining_space(const char *fspath); +extern void mars_remaining_space(const char *fspath, loff_t *total, loff_t *remaining); ///////////////////////////////////////////////////////////////////////// diff --git a/sy_old/sy_generic.c b/sy_old/sy_generic.c index 7d2745a8..c7879c60 100644 --- a/sy_old/sy_generic.c +++ b/sy_old/sy_generic.c @@ -186,11 +186,31 @@ int mars_lchown(const char *path, uid_t uid) } EXPORT_SYMBOL_GPL(mars_lchown); -loff_t mars_remaining_space(const char *fspath) +loff_t _compute_space(struct kstatfs *kstatfs, loff_t raw_val) +{ + int fsize = kstatfs->f_frsize; + if (fsize <= 0) + fsize = kstatfs->f_bsize; + + MARS_INF("fsize = %d raw_val = %lld\n", fsize, raw_val); + // illegal values? cannot do anything.... + if (fsize <= 0) + return 0; + + // prevent intermediate integer overflows + if (fsize <= 1024) + return raw_val / (1024 / fsize); + + return raw_val * (fsize / 1024); +} + +void mars_remaining_space(const char *fspath, loff_t *total, loff_t *remaining) { struct path path = {}; struct kstatfs kstatfs = {}; - loff_t res; + int res; + + *total = *remaining = 0; res = user_path_at(AT_FDCWD, fspath, 0, &path); if (unlikely(res < 0)) { @@ -208,16 +228,12 @@ loff_t mars_remaining_space(const char *fspath) goto done; } - /* It seems that most filesystems use KB rather - * than blocks as base unit. - */ - //res = (loff_t)kstatfs.f_bavail; - res = (loff_t)kstatfs.f_bfree; + *total = _compute_space(&kstatfs, kstatfs.f_blocks); + *remaining = _compute_space(&kstatfs, kstatfs.f_bfree); done: path_put(&path); -err: - return res; +err: ; } EXPORT_SYMBOL_GPL(mars_remaining_space);