1 // SPDX-License-Identifier: GPL-2.0-only
3 * In memory quota format relies on quota infrastructure to store dquot
4 * information for us. While conventional quota formats for file systems
5 * with persistent storage can load quota information into dquot from the
6 * storage on-demand and hence quota dquot shrinker can free any dquot
7 * that is not currently being used, it must be avoided here. Otherwise we
8 * can lose valuable information, user provided limits, because there is
9 * no persistent storage to load the information from afterwards.
11 * One information that in-memory quota format needs to keep track of is
12 * a sorted list of ids for each quota type. This is done by utilizing
13 * an rb tree which root is stored in mem_dqinfo->dqi_priv for each quota
16 * This format can be used to support quota on file system without persistent
17 * storage such as tmpfs.
19 * Author: Lukas Czerner <lczerner@redhat.com>
20 * Carlos Maiolino <cmaiolino@redhat.com>
22 * Copyright (C) 2023 Red Hat, Inc.
24 #include <linux/errno.h>
26 #include <linux/mount.h>
27 #include <linux/kernel.h>
28 #include <linux/init.h>
29 #include <linux/module.h>
30 #include <linux/slab.h>
31 #include <linux/rbtree.h>
32 #include <linux/shmem_fs.h>
34 #include <linux/quotaops.h>
35 #include <linux/quota.h>
37 #ifdef CONFIG_TMPFS_QUOTA
40 * The following constants define the amount of time given a user
41 * before the soft limits are treated as hard limits (usually resulting
42 * in an allocation failure). The timer is started when the user crosses
43 * their soft limit, it is reset when they go below their soft limit.
45 #define SHMEM_MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
46 #define SHMEM_MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
57 static int shmem_check_quota_file(struct super_block
*sb
, int type
)
59 /* There is no real quota file, nothing to do */
64 * There is no real quota file. Just allocate rb_root for quota ids and
67 static int shmem_read_file_info(struct super_block
*sb
, int type
)
69 struct quota_info
*dqopt
= sb_dqopt(sb
);
70 struct mem_dqinfo
*info
= &dqopt
->info
[type
];
72 info
->dqi_priv
= kzalloc(sizeof(struct rb_root
), GFP_NOFS
);
76 info
->dqi_max_spc_limit
= SHMEM_QUOTA_MAX_SPC_LIMIT
;
77 info
->dqi_max_ino_limit
= SHMEM_QUOTA_MAX_INO_LIMIT
;
79 info
->dqi_bgrace
= SHMEM_MAX_DQ_TIME
;
80 info
->dqi_igrace
= SHMEM_MAX_IQ_TIME
;
86 static int shmem_write_file_info(struct super_block
*sb
, int type
)
88 /* There is no real quota file, nothing to do */
93 * Free all the quota_id entries in the rb tree and rb_root.
95 static int shmem_free_file_info(struct super_block
*sb
, int type
)
97 struct mem_dqinfo
*info
= &sb_dqopt(sb
)->info
[type
];
98 struct rb_root
*root
= info
->dqi_priv
;
99 struct quota_id
*entry
;
100 struct rb_node
*node
;
102 info
->dqi_priv
= NULL
;
103 node
= rb_first(root
);
105 entry
= rb_entry(node
, struct quota_id
, node
);
106 node
= rb_next(&entry
->node
);
108 rb_erase(&entry
->node
, root
);
116 static int shmem_get_next_id(struct super_block
*sb
, struct kqid
*qid
)
118 struct mem_dqinfo
*info
= sb_dqinfo(sb
, qid
->type
);
119 struct rb_node
*node
= ((struct rb_root
*)info
->dqi_priv
)->rb_node
;
120 qid_t id
= from_kqid(&init_user_ns
, *qid
);
121 struct quota_info
*dqopt
= sb_dqopt(sb
);
122 struct quota_id
*entry
= NULL
;
125 if (!sb_has_quota_active(sb
, qid
->type
))
128 down_read(&dqopt
->dqio_sem
);
130 entry
= rb_entry(node
, struct quota_id
, node
);
133 node
= node
->rb_left
;
134 else if (id
> entry
->id
)
135 node
= node
->rb_right
;
145 if (id
> entry
->id
) {
146 node
= rb_next(&entry
->node
);
151 entry
= rb_entry(node
, struct quota_id
, node
);
155 *qid
= make_kqid(&init_user_ns
, qid
->type
, entry
->id
);
157 up_read(&dqopt
->dqio_sem
);
162 * Load dquot with limits from existing entry, or create the new entry if
165 static int shmem_acquire_dquot(struct dquot
*dquot
)
167 struct mem_dqinfo
*info
= sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
);
168 struct rb_node
**n
= &((struct rb_root
*)info
->dqi_priv
)->rb_node
;
169 struct shmem_sb_info
*sbinfo
= dquot
->dq_sb
->s_fs_info
;
170 struct rb_node
*parent
= NULL
, *new_node
= NULL
;
171 struct quota_id
*new_entry
, *entry
;
172 qid_t id
= from_kqid(&init_user_ns
, dquot
->dq_id
);
173 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
176 mutex_lock(&dquot
->dq_lock
);
178 down_write(&dqopt
->dqio_sem
);
181 entry
= rb_entry(parent
, struct quota_id
, node
);
185 else if (id
> entry
->id
)
191 /* We don't have entry for this id yet, create it */
192 new_entry
= kzalloc(sizeof(struct quota_id
), GFP_NOFS
);
199 if (dquot
->dq_id
.type
== USRQUOTA
) {
200 new_entry
->bhardlimit
= sbinfo
->qlimits
.usrquota_bhardlimit
;
201 new_entry
->ihardlimit
= sbinfo
->qlimits
.usrquota_ihardlimit
;
202 } else if (dquot
->dq_id
.type
== GRPQUOTA
) {
203 new_entry
->bhardlimit
= sbinfo
->qlimits
.grpquota_bhardlimit
;
204 new_entry
->ihardlimit
= sbinfo
->qlimits
.grpquota_ihardlimit
;
207 new_node
= &new_entry
->node
;
208 rb_link_node(new_node
, parent
, n
);
209 rb_insert_color(new_node
, (struct rb_root
*)info
->dqi_priv
);
213 /* Load the stored limits from the tree */
214 spin_lock(&dquot
->dq_dqb_lock
);
215 dquot
->dq_dqb
.dqb_bhardlimit
= entry
->bhardlimit
;
216 dquot
->dq_dqb
.dqb_bsoftlimit
= entry
->bsoftlimit
;
217 dquot
->dq_dqb
.dqb_ihardlimit
= entry
->ihardlimit
;
218 dquot
->dq_dqb
.dqb_isoftlimit
= entry
->isoftlimit
;
220 if (!dquot
->dq_dqb
.dqb_bhardlimit
&&
221 !dquot
->dq_dqb
.dqb_bsoftlimit
&&
222 !dquot
->dq_dqb
.dqb_ihardlimit
&&
223 !dquot
->dq_dqb
.dqb_isoftlimit
)
224 set_bit(DQ_FAKE_B
, &dquot
->dq_flags
);
225 spin_unlock(&dquot
->dq_dqb_lock
);
227 /* Make sure flags update is visible after dquot has been filled */
228 smp_mb__before_atomic();
229 set_bit(DQ_ACTIVE_B
, &dquot
->dq_flags
);
231 up_write(&dqopt
->dqio_sem
);
232 mutex_unlock(&dquot
->dq_lock
);
236 static bool shmem_is_empty_dquot(struct dquot
*dquot
)
238 struct shmem_sb_info
*sbinfo
= dquot
->dq_sb
->s_fs_info
;
242 if (dquot
->dq_id
.type
== USRQUOTA
) {
243 bhardlimit
= sbinfo
->qlimits
.usrquota_bhardlimit
;
244 ihardlimit
= sbinfo
->qlimits
.usrquota_ihardlimit
;
245 } else if (dquot
->dq_id
.type
== GRPQUOTA
) {
246 bhardlimit
= sbinfo
->qlimits
.grpquota_bhardlimit
;
247 ihardlimit
= sbinfo
->qlimits
.grpquota_ihardlimit
;
250 if (test_bit(DQ_FAKE_B
, &dquot
->dq_flags
) ||
251 (dquot
->dq_dqb
.dqb_curspace
== 0 &&
252 dquot
->dq_dqb
.dqb_curinodes
== 0 &&
253 dquot
->dq_dqb
.dqb_bhardlimit
== bhardlimit
&&
254 dquot
->dq_dqb
.dqb_ihardlimit
== ihardlimit
))
260 * Store limits from dquot in the tree unless it's fake. If it is fake
261 * remove the id from the tree since there is no useful information in
264 static int shmem_release_dquot(struct dquot
*dquot
)
266 struct mem_dqinfo
*info
= sb_dqinfo(dquot
->dq_sb
, dquot
->dq_id
.type
);
267 struct rb_node
*node
= ((struct rb_root
*)info
->dqi_priv
)->rb_node
;
268 qid_t id
= from_kqid(&init_user_ns
, dquot
->dq_id
);
269 struct quota_info
*dqopt
= sb_dqopt(dquot
->dq_sb
);
270 struct quota_id
*entry
= NULL
;
272 mutex_lock(&dquot
->dq_lock
);
273 /* Check whether we are not racing with some other dqget() */
274 if (dquot_is_busy(dquot
))
277 down_write(&dqopt
->dqio_sem
);
279 entry
= rb_entry(node
, struct quota_id
, node
);
282 node
= node
->rb_left
;
283 else if (id
> entry
->id
)
284 node
= node
->rb_right
;
289 /* We should always find the entry in the rb tree */
290 WARN_ONCE(1, "quota id %u from dquot %p, not in rb tree!\n", id
, dquot
);
291 up_write(&dqopt
->dqio_sem
);
292 mutex_unlock(&dquot
->dq_lock
);
296 if (shmem_is_empty_dquot(dquot
)) {
297 /* Remove entry from the tree */
298 rb_erase(&entry
->node
, info
->dqi_priv
);
301 /* Store the limits in the tree */
302 spin_lock(&dquot
->dq_dqb_lock
);
303 entry
->bhardlimit
= dquot
->dq_dqb
.dqb_bhardlimit
;
304 entry
->bsoftlimit
= dquot
->dq_dqb
.dqb_bsoftlimit
;
305 entry
->ihardlimit
= dquot
->dq_dqb
.dqb_ihardlimit
;
306 entry
->isoftlimit
= dquot
->dq_dqb
.dqb_isoftlimit
;
307 spin_unlock(&dquot
->dq_dqb_lock
);
310 clear_bit(DQ_ACTIVE_B
, &dquot
->dq_flags
);
311 up_write(&dqopt
->dqio_sem
);
314 mutex_unlock(&dquot
->dq_lock
);
318 static int shmem_mark_dquot_dirty(struct dquot
*dquot
)
323 static int shmem_dquot_write_info(struct super_block
*sb
, int type
)
328 static const struct quota_format_ops shmem_format_ops
= {
329 .check_quota_file
= shmem_check_quota_file
,
330 .read_file_info
= shmem_read_file_info
,
331 .write_file_info
= shmem_write_file_info
,
332 .free_file_info
= shmem_free_file_info
,
335 struct quota_format_type shmem_quota_format
= {
336 .qf_fmt_id
= QFMT_SHMEM
,
337 .qf_ops
= &shmem_format_ops
,
338 .qf_owner
= THIS_MODULE
341 const struct dquot_operations shmem_quota_operations
= {
342 .acquire_dquot
= shmem_acquire_dquot
,
343 .release_dquot
= shmem_release_dquot
,
344 .alloc_dquot
= dquot_alloc
,
345 .destroy_dquot
= dquot_destroy
,
346 .write_info
= shmem_dquot_write_info
,
347 .mark_dirty
= shmem_mark_dquot_dirty
,
348 .get_next_id
= shmem_get_next_id
,
350 #endif /* CONFIG_TMPFS_QUOTA */