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