1/* $NetBSD: ulfs_quota2_subr.c,v 1.7 2023/08/24 14:56:03 andvar Exp $ */ 2/* from NetBSD: quota2_subr.c,v 1.5 2012/02/05 14:19:04 dholland Exp */ 3 4/*- 5 * Copyright (c) 2010, 2011 Manuel Bouyer 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> 31__KERNEL_RCSID(0, "$NetBSD: ulfs_quota2_subr.c,v 1.7 2023/08/24 14:56:03 andvar Exp $"); 32 33#include <sys/param.h> 34#include <sys/time.h> 35 36#include <ufs/lfs/lfs.h> 37#include <ufs/lfs/lfs_extern.h> 38#include <ufs/lfs/ulfs_inode.h> 39#include <ufs/lfs/ulfs_dinode.h> 40#include <ufs/lfs/ulfs_bswap.h> 41#include <ufs/lfs/ulfs_quota2.h> 42 43#ifndef _KERNEL 44#include <string.h> 45#endif 46 47void 48lfsquota2_addfreeq2e(struct quota2_header *q2h, void *bp, uint64_t baseoff, 49 uint64_t bsize, int ns) 50{ 51 uint64_t blkoff = baseoff % bsize; 52 int i, nq2e; 53 struct quota2_entry *q2e; 54 55 q2e = (void *)((char *)bp + blkoff); 56 nq2e = (bsize - blkoff) / sizeof(*q2e); 57 for (i = 0; i < nq2e; i++) { 58 q2e[i].q2e_next = q2h->q2h_free; 59 q2h->q2h_free = ulfs_rw64(i * sizeof(*q2e) + baseoff, ns); 60 } 61} 62 63void 64lfsquota2_create_blk0(uint64_t bsize, void *bp, int q2h_hash_shift, int type, 65 int ns) 66{ 67 struct quota2_header *q2h; 68 const int quota2_hash_size = 1 << q2h_hash_shift; 69 const int quota2_full_header_size = sizeof(struct quota2_header) + 70 sizeof(q2h->q2h_entries[0]) * quota2_hash_size; 71 int i; 72 73 memset(bp, 0, bsize); 74 q2h = bp; 75 q2h->q2h_magic_number = ulfs_rw32(Q2_HEAD_MAGIC, ns); 76 q2h->q2h_type = type; 77 q2h->q2h_hash_shift = q2h_hash_shift; 78 q2h->q2h_hash_size = ulfs_rw16(quota2_hash_size, ns); 79 /* setup default entry: unlimited, 7 days grace */ 80 for (i = 0; i < N_QL; i++) { 81 q2h->q2h_defentry.q2e_val[i].q2v_hardlimit = 82 q2h->q2h_defentry.q2e_val[i].q2v_softlimit = 83 ulfs_rw64(UQUAD_MAX, ns); 84 q2h->q2h_defentry.q2e_val[i].q2v_grace = 85 ulfs_rw64(7ULL * 24ULL * 3600ULL, ns); 86 } 87 88 /* first quota entry, after the hash table */ 89 lfsquota2_addfreeq2e(q2h, bp, quota2_full_header_size, bsize, ns); 90} 91 92void 93lfsquota2_ulfs_rwq2v(const struct quota2_val *s, struct quota2_val *d, int needswap) 94{ 95 d->q2v_hardlimit = ulfs_rw64(s->q2v_hardlimit, needswap); 96 d->q2v_softlimit = ulfs_rw64(s->q2v_softlimit, needswap); 97 d->q2v_cur = ulfs_rw64(s->q2v_cur, needswap); 98 d->q2v_time = ulfs_rw64(s->q2v_time, needswap); 99 d->q2v_grace = ulfs_rw64(s->q2v_grace, needswap); 100} 101 102void 103lfsquota2_ulfs_rwq2e(const struct quota2_entry *s, struct quota2_entry *d, 104int needswap) 105{ 106 lfsquota2_ulfs_rwq2v(&s->q2e_val[QL_BLOCK], &d->q2e_val[QL_BLOCK], 107 needswap); 108 lfsquota2_ulfs_rwq2v(&s->q2e_val[QL_FILE], &d->q2e_val[QL_FILE], 109 needswap); 110 d->q2e_uid = ulfs_rw32(s->q2e_uid, needswap); 111} 112 113int 114lfsquota_check_limit(uint64_t cur, uint64_t change, uint64_t soft, uint64_t hard, 115 time_t expire, time_t now) 116{ 117 if (cur + change > hard) { 118 if (cur <= soft) 119 return (QL_F_CROSS | QL_S_DENY_HARD); 120 return QL_S_DENY_HARD; 121 } else if (cur + change > soft) { 122 if (cur <= soft) 123 return (QL_F_CROSS | QL_S_ALLOW_SOFT); 124 if (now > expire) { 125 return QL_S_DENY_GRACE; 126 } 127 return QL_S_ALLOW_SOFT; 128 } 129 return QL_S_ALLOW_OK; 130} 131