From 5b287edfa31070eed303d24ec7899139aa52c913 Mon Sep 17 00:00:00 2001 From: Johan Ekenberg Date: Wed, 1 May 2024 17:19:00 +0200 Subject: [PATCH] Fix issue #27: Failed setting gracetime (generic): Invalid argument --- src/linux/linux_quota.h | 19 +++++++++++++++++++ src/linux/quota.c | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/src/linux/linux_quota.h b/src/linux/linux_quota.h index 747aea7..bc4dc23 100644 --- a/src/linux/linux_quota.h +++ b/src/linux/linux_quota.h @@ -95,6 +95,25 @@ struct old_mem_dqinfo { unsigned int dqi_free_entry; }; +/* According to 'man quotactl' these are defined in sys/quota.h + but that seems to not always be the case */ +#ifndef IIF_BGRACE +#define IIF_BGRACE 1 +#endif + +#ifndef IIF_IGRACE +#define IIF_IGRACE 2 +#endif + +#ifndef IIF_FLAGS +#define IIF_FLAGS 4 +#endif + +#ifndef IIF_ALL +#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS) +#endif + + /* The generic diskinfo-struct: */ struct if_dqinfo { u_int64_t dqi_bgrace; diff --git a/src/linux/quota.c b/src/linux/quota.c index 5286a3f..4a141e3 100644 --- a/src/linux/quota.c +++ b/src/linux/quota.c @@ -382,14 +382,21 @@ static int generic_quota_set(quota_t *myquota) { /* update quotainfo (global gracetimes) */ if (myquota->_do_set_global_block_gracetime || myquota->_do_set_global_inode_gracetime) { struct if_dqinfo *foo = ((struct if_dqinfo *) myquota->_generic_quotainfo); + u_int32_t old_dqi_valid = foo->dqi_valid; // Save now, restore later + if (myquota->_do_set_global_block_gracetime) { + output_debug(">> set global block gracetime"); foo->dqi_bgrace = myquota->block_grace; + foo->dqi_valid = IIF_BGRACE; } if (myquota->_do_set_global_inode_gracetime) { + output_debug(">> set global inode gracetime"); foo->dqi_igrace = myquota->inode_grace; + foo->dqi_valid = IIF_IGRACE; } retval = quotactl(QCMD(Q_SETINFO, myquota->_id_type), myquota->_qfile, myquota->_id, (caddr_t) myquota->_generic_quotainfo); + foo->dqi_valid = old_dqi_valid; // restore if (retval < 0) { output_error("Failed setting gracetime (generic): %s", strerror(errno)); return 0;