summaryrefslogtreecommitdiff
path: root/rquota_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'rquota_server.c')
-rw-r--r--rquota_server.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/rquota_server.c b/rquota_server.c
index 0e83689..3293de7 100644
--- a/rquota_server.c
+++ b/rquota_server.c
@@ -91,17 +91,41 @@ static inline void servnet2utildqblk(struct util_dqblk *u, sq_dqblk * n)
u->dqb_itime = 0;
}
+/* XDR transports 32b variables exactly. Find smallest needed shift to fit
+ * 64b variable into into 32 bits and to preserve precision as high as
+ * possible. */
+static int find_block_shift(qsize_t hard, qsize_t soft, qsize_t cur)
+{
+ int shift;
+ qsize_t value = hard;
+
+ if (value < soft)
+ value = soft;
+ if (value < cur)
+ value = cur;
+ value >>= 32 + QUOTABLOCK_BITS;
+ for (shift = QUOTABLOCK_BITS; value; shift++)
+ value >>= 1;
+
+ return shift;
+}
+
static inline void servutil2netdqblk(struct rquota *n, struct util_dqblk *u)
{
time_t now;
+ int shift;
- time(&now);
- n->rq_bhardlimit = (u->dqb_bhardlimit << QUOTABLOCK_BITS) >> RPC_DQBLK_SIZE_BITS;
- n->rq_bsoftlimit = (u->dqb_bsoftlimit << QUOTABLOCK_BITS) >> RPC_DQBLK_SIZE_BITS;
+ shift = find_block_shift(u->dqb_bhardlimit, u->dqb_bsoftlimit,
+ u->dqb_curspace);
+ n->rq_bsize = 1 << shift;
+ n->rq_bhardlimit = (u->dqb_bhardlimit << QUOTABLOCK_BITS) >> shift;
+ n->rq_bsoftlimit = (u->dqb_bsoftlimit << QUOTABLOCK_BITS) >> shift;
n->rq_fhardlimit = u->dqb_ihardlimit;
n->rq_fsoftlimit = u->dqb_isoftlimit;
- n->rq_curblocks = (u->dqb_curspace + RPC_DQBLK_SIZE - 1) >> RPC_DQBLK_SIZE_BITS;
+ n->rq_curblocks = (u->dqb_curspace + n->rq_bsize - 1) >> shift;
n->rq_curfiles = u->dqb_curinodes;
+
+ time(&now);
if (u->dqb_btime)
n->rq_btimeleft = u->dqb_btime - now;
else
@@ -258,7 +282,6 @@ getquota_rslt *getquotainfo(int lflags, caddr_t * argp, struct svc_req * rqstp)
}
result.status = Q_NOQUOTA;
- result.getquota_rslt_u.gqr_rquota.rq_bsize = RPC_DQBLK_SIZE;
if (init_mounts_scan(1, &pathp, MS_QUIET | MS_NO_MNTPOINT | MS_NFS_ALL | ((flags & FL_AUTOFS) ? 0 : MS_NO_AUTOFS)) < 0)
goto out;