xref: /linux/fs/quota/quota_tree.c (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *	vfsv0 quota IO operations on file
4  */
5 
6 #include <linux/errno.h>
7 #include <linux/fs.h>
8 #include <linux/mount.h>
9 #include <linux/dqblk_v2.h>
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/quotaops.h>
15 
16 #include <asm/byteorder.h>
17 
18 #include "quota_tree.h"
19 
20 MODULE_AUTHOR("Jan Kara");
21 MODULE_DESCRIPTION("Quota trie support");
22 MODULE_LICENSE("GPL");
23 
24 /*
25  * Maximum quota tree depth we support. Only to limit recursion when working
26  * with the tree.
27  */
28 #define MAX_QTREE_DEPTH 6
29 
30 #define __QUOTA_QT_PARANOIA
31 
__get_index(struct qtree_mem_dqinfo * info,qid_t id,int depth)32 static int __get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth)
33 {
34 	unsigned int epb = info->dqi_usable_bs >> 2;
35 
36 	depth = info->dqi_qtree_depth - depth - 1;
37 	while (depth--)
38 		id /= epb;
39 	return id % epb;
40 }
41 
get_index(struct qtree_mem_dqinfo * info,struct kqid qid,int depth)42 static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
43 {
44 	qid_t id = from_kqid(&init_user_ns, qid);
45 
46 	return __get_index(info, id, depth);
47 }
48 
49 /* Number of entries in one blocks */
qtree_dqstr_in_blk(struct qtree_mem_dqinfo * info)50 static int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info)
51 {
52 	return (info->dqi_usable_bs - sizeof(struct qt_disk_dqdbheader))
53 	       / info->dqi_entry_size;
54 }
55 
read_blk(struct qtree_mem_dqinfo * info,uint blk,char * buf)56 static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
57 {
58 	struct super_block *sb = info->dqi_sb;
59 
60 	memset(buf, 0, info->dqi_usable_bs);
61 	return sb->s_op->quota_read(sb, info->dqi_type, buf,
62 	       info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits);
63 }
64 
write_blk(struct qtree_mem_dqinfo * info,uint blk,char * buf)65 static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
66 {
67 	struct super_block *sb = info->dqi_sb;
68 	ssize_t ret;
69 
70 	ret = sb->s_op->quota_write(sb, info->dqi_type, buf,
71 	       info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits);
72 	if (ret != info->dqi_usable_bs) {
73 		quota_error(sb, "dquota write failed");
74 		if (ret >= 0)
75 			ret = -EIO;
76 	}
77 	return ret;
78 }
79 
do_check_range(struct super_block * sb,const char * val_name,uint val,uint min_val,uint max_val)80 static inline int do_check_range(struct super_block *sb, const char *val_name,
81 				 uint val, uint min_val, uint max_val)
82 {
83 	if (val < min_val || val > max_val) {
84 		quota_error(sb, "Getting %s %u out of range %u-%u",
85 			    val_name, val, min_val, max_val);
86 		return -EUCLEAN;
87 	}
88 
89 	return 0;
90 }
91 
check_dquot_block_header(struct qtree_mem_dqinfo * info,struct qt_disk_dqdbheader * dh)92 static int check_dquot_block_header(struct qtree_mem_dqinfo *info,
93 				    struct qt_disk_dqdbheader *dh)
94 {
95 	int err = 0;
96 
97 	err = do_check_range(info->dqi_sb, "dqdh_next_free",
98 			     le32_to_cpu(dh->dqdh_next_free), 0,
99 			     info->dqi_blocks - 1);
100 	if (err)
101 		return err;
102 	err = do_check_range(info->dqi_sb, "dqdh_prev_free",
103 			     le32_to_cpu(dh->dqdh_prev_free), 0,
104 			     info->dqi_blocks - 1);
105 	if (err)
106 		return err;
107 	err = do_check_range(info->dqi_sb, "dqdh_entries",
108 			     le16_to_cpu(dh->dqdh_entries), 0,
109 			     qtree_dqstr_in_blk(info));
110 
111 	return err;
112 }
113 
114 /* Remove empty block from list and return it */
get_free_dqblk(struct qtree_mem_dqinfo * info)115 static int get_free_dqblk(struct qtree_mem_dqinfo *info)
116 {
117 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
118 	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
119 	int ret, blk;
120 
121 	if (!buf)
122 		return -ENOMEM;
123 	if (info->dqi_free_blk) {
124 		blk = info->dqi_free_blk;
125 		ret = read_blk(info, blk, buf);
126 		if (ret < 0)
127 			goto out_buf;
128 		ret = check_dquot_block_header(info, dh);
129 		if (ret)
130 			goto out_buf;
131 		info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
132 	}
133 	else {
134 		memset(buf, 0, info->dqi_usable_bs);
135 		/* Assure block allocation... */
136 		ret = write_blk(info, info->dqi_blocks, buf);
137 		if (ret < 0)
138 			goto out_buf;
139 		blk = info->dqi_blocks++;
140 	}
141 	mark_info_dirty(info->dqi_sb, info->dqi_type);
142 	ret = blk;
143 out_buf:
144 	kfree(buf);
145 	return ret;
146 }
147 
148 /* Insert empty block to the list */
put_free_dqblk(struct qtree_mem_dqinfo * info,char * buf,uint blk)149 static int put_free_dqblk(struct qtree_mem_dqinfo *info, char *buf, uint blk)
150 {
151 	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
152 	int err;
153 
154 	dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk);
155 	dh->dqdh_prev_free = cpu_to_le32(0);
156 	dh->dqdh_entries = cpu_to_le16(0);
157 	err = write_blk(info, blk, buf);
158 	if (err < 0)
159 		return err;
160 	info->dqi_free_blk = blk;
161 	mark_info_dirty(info->dqi_sb, info->dqi_type);
162 	return 0;
163 }
164 
165 /* Remove given block from the list of blocks with free entries */
remove_free_dqentry(struct qtree_mem_dqinfo * info,char * buf,uint blk)166 static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
167 			       uint blk)
168 {
169 	char *tmpbuf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
170 	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
171 	uint nextblk = le32_to_cpu(dh->dqdh_next_free);
172 	uint prevblk = le32_to_cpu(dh->dqdh_prev_free);
173 	int err;
174 
175 	if (!tmpbuf)
176 		return -ENOMEM;
177 	if (nextblk) {
178 		err = read_blk(info, nextblk, tmpbuf);
179 		if (err < 0)
180 			goto out_buf;
181 		((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
182 							dh->dqdh_prev_free;
183 		err = write_blk(info, nextblk, tmpbuf);
184 		if (err < 0)
185 			goto out_buf;
186 	}
187 	if (prevblk) {
188 		err = read_blk(info, prevblk, tmpbuf);
189 		if (err < 0)
190 			goto out_buf;
191 		((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_next_free =
192 							dh->dqdh_next_free;
193 		err = write_blk(info, prevblk, tmpbuf);
194 		if (err < 0)
195 			goto out_buf;
196 	} else {
197 		info->dqi_free_entry = nextblk;
198 		mark_info_dirty(info->dqi_sb, info->dqi_type);
199 	}
200 	kfree(tmpbuf);
201 	dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
202 	/* No matter whether write succeeds block is out of list */
203 	if (write_blk(info, blk, buf) < 0)
204 		quota_error(info->dqi_sb, "Can't write block (%u) "
205 			    "with free entries", blk);
206 	return 0;
207 out_buf:
208 	kfree(tmpbuf);
209 	return err;
210 }
211 
212 /* Insert given block to the beginning of list with free entries */
insert_free_dqentry(struct qtree_mem_dqinfo * info,char * buf,uint blk)213 static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
214 			       uint blk)
215 {
216 	char *tmpbuf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
217 	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
218 	int err;
219 
220 	if (!tmpbuf)
221 		return -ENOMEM;
222 	dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry);
223 	dh->dqdh_prev_free = cpu_to_le32(0);
224 	err = write_blk(info, blk, buf);
225 	if (err < 0)
226 		goto out_buf;
227 	if (info->dqi_free_entry) {
228 		err = read_blk(info, info->dqi_free_entry, tmpbuf);
229 		if (err < 0)
230 			goto out_buf;
231 		((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
232 							cpu_to_le32(blk);
233 		err = write_blk(info, info->dqi_free_entry, tmpbuf);
234 		if (err < 0)
235 			goto out_buf;
236 	}
237 	kfree(tmpbuf);
238 	info->dqi_free_entry = blk;
239 	mark_info_dirty(info->dqi_sb, info->dqi_type);
240 	return 0;
241 out_buf:
242 	kfree(tmpbuf);
243 	return err;
244 }
245 
246 /* Is the entry in the block free? */
qtree_entry_unused(struct qtree_mem_dqinfo * info,char * disk)247 int qtree_entry_unused(struct qtree_mem_dqinfo *info, char *disk)
248 {
249 	int i;
250 
251 	for (i = 0; i < info->dqi_entry_size; i++)
252 		if (disk[i])
253 			return 0;
254 	return 1;
255 }
256 EXPORT_SYMBOL(qtree_entry_unused);
257 
258 /* Find space for dquot */
find_free_dqentry(struct qtree_mem_dqinfo * info,struct dquot * dquot,int * err)259 static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
260 			      struct dquot *dquot, int *err)
261 {
262 	uint blk, i;
263 	struct qt_disk_dqdbheader *dh;
264 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
265 	char *ddquot;
266 
267 	*err = 0;
268 	if (!buf) {
269 		*err = -ENOMEM;
270 		return 0;
271 	}
272 	dh = (struct qt_disk_dqdbheader *)buf;
273 	if (info->dqi_free_entry) {
274 		blk = info->dqi_free_entry;
275 		*err = read_blk(info, blk, buf);
276 		if (*err < 0)
277 			goto out_buf;
278 		*err = check_dquot_block_header(info, dh);
279 		if (*err)
280 			goto out_buf;
281 	} else {
282 		blk = get_free_dqblk(info);
283 		if ((int)blk < 0) {
284 			*err = blk;
285 			kfree(buf);
286 			return 0;
287 		}
288 		memset(buf, 0, info->dqi_usable_bs);
289 		/* This is enough as the block is already zeroed and the entry
290 		 * list is empty... */
291 		info->dqi_free_entry = blk;
292 		mark_info_dirty(dquot->dq_sb, dquot->dq_id.type);
293 	}
294 	/* Block will be full? */
295 	if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) {
296 		*err = remove_free_dqentry(info, buf, blk);
297 		if (*err < 0) {
298 			quota_error(dquot->dq_sb, "Can't remove block (%u) "
299 				    "from entry free list", blk);
300 			goto out_buf;
301 		}
302 	}
303 	le16_add_cpu(&dh->dqdh_entries, 1);
304 	/* Find free structure in block */
305 	ddquot = buf + sizeof(struct qt_disk_dqdbheader);
306 	for (i = 0; i < qtree_dqstr_in_blk(info); i++) {
307 		if (qtree_entry_unused(info, ddquot))
308 			break;
309 		ddquot += info->dqi_entry_size;
310 	}
311 #ifdef __QUOTA_QT_PARANOIA
312 	if (i == qtree_dqstr_in_blk(info)) {
313 		quota_error(dquot->dq_sb, "Data block full but it shouldn't");
314 		*err = -EIO;
315 		goto out_buf;
316 	}
317 #endif
318 	*err = write_blk(info, blk, buf);
319 	if (*err < 0) {
320 		quota_error(dquot->dq_sb, "Can't write quota data block %u",
321 			    blk);
322 		goto out_buf;
323 	}
324 	dquot->dq_off = ((loff_t)blk << info->dqi_blocksize_bits) +
325 			sizeof(struct qt_disk_dqdbheader) +
326 			i * info->dqi_entry_size;
327 	kfree(buf);
328 	return blk;
329 out_buf:
330 	kfree(buf);
331 	return 0;
332 }
333 
334 /* Insert reference to structure into the trie */
do_insert_tree(struct qtree_mem_dqinfo * info,struct dquot * dquot,uint * blks,int depth)335 static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
336 			  uint *blks, int depth)
337 {
338 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
339 	int ret = 0, newson = 0, newact = 0;
340 	__le32 *ref;
341 	uint newblk;
342 	int i;
343 
344 	if (!buf)
345 		return -ENOMEM;
346 	if (!blks[depth]) {
347 		ret = get_free_dqblk(info);
348 		if (ret < 0)
349 			goto out_buf;
350 		for (i = 0; i < depth; i++)
351 			if (ret == blks[i]) {
352 				quota_error(dquot->dq_sb,
353 					"Free block already used in tree: block %u",
354 					ret);
355 				ret = -EIO;
356 				goto out_buf;
357 			}
358 		blks[depth] = ret;
359 		memset(buf, 0, info->dqi_usable_bs);
360 		newact = 1;
361 	} else {
362 		ret = read_blk(info, blks[depth], buf);
363 		if (ret < 0) {
364 			quota_error(dquot->dq_sb, "Can't read tree quota "
365 				    "block %u", blks[depth]);
366 			goto out_buf;
367 		}
368 	}
369 	ref = (__le32 *)buf;
370 	newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
371 	ret = do_check_range(dquot->dq_sb, "block", newblk, 0,
372 			     info->dqi_blocks - 1);
373 	if (ret)
374 		goto out_buf;
375 	if (!newblk) {
376 		newson = 1;
377 	} else {
378 		for (i = 0; i <= depth; i++)
379 			if (newblk == blks[i]) {
380 				quota_error(dquot->dq_sb,
381 					"Cycle in quota tree detected: block %u index %u",
382 					blks[depth],
383 					get_index(info, dquot->dq_id, depth));
384 				ret = -EIO;
385 				goto out_buf;
386 			}
387 	}
388 	blks[depth + 1] = newblk;
389 	if (depth == info->dqi_qtree_depth - 1) {
390 #ifdef __QUOTA_QT_PARANOIA
391 		if (newblk) {
392 			quota_error(dquot->dq_sb, "Inserting already present "
393 				    "quota entry (block %u)",
394 				    le32_to_cpu(ref[get_index(info,
395 						dquot->dq_id, depth)]));
396 			ret = -EIO;
397 			goto out_buf;
398 		}
399 #endif
400 		blks[depth + 1] = find_free_dqentry(info, dquot, &ret);
401 	} else {
402 		ret = do_insert_tree(info, dquot, blks, depth + 1);
403 	}
404 	if (newson && ret >= 0) {
405 		ref[get_index(info, dquot->dq_id, depth)] =
406 						cpu_to_le32(blks[depth + 1]);
407 		ret = write_blk(info, blks[depth], buf);
408 	} else if (newact && ret < 0) {
409 		put_free_dqblk(info, buf, blks[depth]);
410 	}
411 out_buf:
412 	kfree(buf);
413 	return ret;
414 }
415 
416 /* Wrapper for inserting quota structure into tree */
dq_insert_tree(struct qtree_mem_dqinfo * info,struct dquot * dquot)417 static inline int dq_insert_tree(struct qtree_mem_dqinfo *info,
418 				 struct dquot *dquot)
419 {
420 	uint blks[MAX_QTREE_DEPTH] = { QT_TREEOFF };
421 
422 #ifdef __QUOTA_QT_PARANOIA
423 	if (info->dqi_blocks <= QT_TREEOFF) {
424 		quota_error(dquot->dq_sb, "Quota tree root isn't allocated!");
425 		return -EIO;
426 	}
427 #endif
428 	if (info->dqi_qtree_depth >= MAX_QTREE_DEPTH) {
429 		quota_error(dquot->dq_sb, "Quota tree depth too big!");
430 		return -EIO;
431 	}
432 	return do_insert_tree(info, dquot, blks, 0);
433 }
434 
435 /*
436  * We don't have to be afraid of deadlocks as we never have quotas on quota
437  * files...
438  */
qtree_write_dquot(struct qtree_mem_dqinfo * info,struct dquot * dquot)439 int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
440 {
441 	int type = dquot->dq_id.type;
442 	struct super_block *sb = dquot->dq_sb;
443 	ssize_t ret;
444 	char *ddquot = kmalloc(info->dqi_entry_size, GFP_KERNEL);
445 
446 	if (!ddquot)
447 		return -ENOMEM;
448 
449 	/* dq_off is guarded by dqio_sem */
450 	if (!dquot->dq_off) {
451 		ret = dq_insert_tree(info, dquot);
452 		if (ret < 0) {
453 			quota_error(sb, "Error %zd occurred while creating "
454 				    "quota", ret);
455 			kfree(ddquot);
456 			return ret;
457 		}
458 	}
459 	spin_lock(&dquot->dq_dqb_lock);
460 	info->dqi_ops->mem2disk_dqblk(ddquot, dquot);
461 	spin_unlock(&dquot->dq_dqb_lock);
462 	ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size,
463 				    dquot->dq_off);
464 	if (ret != info->dqi_entry_size) {
465 		quota_error(sb, "dquota write failed");
466 		if (ret >= 0)
467 			ret = -ENOSPC;
468 	} else {
469 		ret = 0;
470 	}
471 	dqstats_inc(DQST_WRITES);
472 	kfree(ddquot);
473 
474 	return ret;
475 }
476 EXPORT_SYMBOL(qtree_write_dquot);
477 
478 /* Free dquot entry in data block */
free_dqentry(struct qtree_mem_dqinfo * info,struct dquot * dquot,uint blk)479 static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
480 			uint blk)
481 {
482 	struct qt_disk_dqdbheader *dh;
483 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
484 	int ret = 0;
485 
486 	if (!buf)
487 		return -ENOMEM;
488 	if (dquot->dq_off >> info->dqi_blocksize_bits != blk) {
489 		quota_error(dquot->dq_sb, "Quota structure has offset to "
490 			"other block (%u) than it should (%u)", blk,
491 			(uint)(dquot->dq_off >> info->dqi_blocksize_bits));
492 		ret = -EIO;
493 		goto out_buf;
494 	}
495 	ret = read_blk(info, blk, buf);
496 	if (ret < 0) {
497 		quota_error(dquot->dq_sb, "Can't read quota data block %u",
498 			    blk);
499 		goto out_buf;
500 	}
501 	dh = (struct qt_disk_dqdbheader *)buf;
502 	ret = check_dquot_block_header(info, dh);
503 	if (ret)
504 		goto out_buf;
505 	le16_add_cpu(&dh->dqdh_entries, -1);
506 	if (!le16_to_cpu(dh->dqdh_entries)) {	/* Block got free? */
507 		ret = remove_free_dqentry(info, buf, blk);
508 		if (ret >= 0)
509 			ret = put_free_dqblk(info, buf, blk);
510 		if (ret < 0) {
511 			quota_error(dquot->dq_sb, "Can't move quota data block "
512 				    "(%u) to free list", blk);
513 			goto out_buf;
514 		}
515 	} else {
516 		memset(buf +
517 		       (dquot->dq_off & ((1 << info->dqi_blocksize_bits) - 1)),
518 		       0, info->dqi_entry_size);
519 		if (le16_to_cpu(dh->dqdh_entries) ==
520 		    qtree_dqstr_in_blk(info) - 1) {
521 			/* Insert will write block itself */
522 			ret = insert_free_dqentry(info, buf, blk);
523 			if (ret < 0) {
524 				quota_error(dquot->dq_sb, "Can't insert quota "
525 				    "data block (%u) to free entry list", blk);
526 				goto out_buf;
527 			}
528 		} else {
529 			ret = write_blk(info, blk, buf);
530 			if (ret < 0) {
531 				quota_error(dquot->dq_sb, "Can't write quota "
532 					    "data block %u", blk);
533 				goto out_buf;
534 			}
535 		}
536 	}
537 	dquot->dq_off = 0;	/* Quota is now unattached */
538 out_buf:
539 	kfree(buf);
540 	return ret;
541 }
542 
543 /* Remove reference to dquot from tree */
remove_tree(struct qtree_mem_dqinfo * info,struct dquot * dquot,uint * blks,int depth)544 static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
545 		       uint *blks, int depth)
546 {
547 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
548 	int ret = 0;
549 	uint newblk;
550 	__le32 *ref = (__le32 *)buf;
551 	int i;
552 
553 	if (!buf)
554 		return -ENOMEM;
555 	ret = read_blk(info, blks[depth], buf);
556 	if (ret < 0) {
557 		quota_error(dquot->dq_sb, "Can't read quota data block %u",
558 			    blks[depth]);
559 		goto out_buf;
560 	}
561 	newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
562 	ret = do_check_range(dquot->dq_sb, "block", newblk, QT_TREEOFF,
563 			     info->dqi_blocks - 1);
564 	if (ret)
565 		goto out_buf;
566 
567 	for (i = 0; i <= depth; i++)
568 		if (newblk == blks[i]) {
569 			quota_error(dquot->dq_sb,
570 				"Cycle in quota tree detected: block %u index %u",
571 				blks[depth],
572 				get_index(info, dquot->dq_id, depth));
573 			ret = -EIO;
574 			goto out_buf;
575 		}
576 	if (depth == info->dqi_qtree_depth - 1) {
577 		ret = free_dqentry(info, dquot, newblk);
578 		blks[depth + 1] = 0;
579 	} else {
580 		blks[depth + 1] = newblk;
581 		ret = remove_tree(info, dquot, blks, depth + 1);
582 	}
583 	if (ret >= 0 && !blks[depth + 1]) {
584 		ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0);
585 		/* Block got empty? */
586 		for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++)
587 			;
588 		/* Don't put the root block into the free block list */
589 		if (i == (info->dqi_usable_bs >> 2)
590 		    && blks[depth] != QT_TREEOFF) {
591 			put_free_dqblk(info, buf, blks[depth]);
592 			blks[depth] = 0;
593 		} else {
594 			ret = write_blk(info, blks[depth], buf);
595 			if (ret < 0)
596 				quota_error(dquot->dq_sb,
597 					    "Can't write quota tree block %u",
598 					    blks[depth]);
599 		}
600 	}
601 out_buf:
602 	kfree(buf);
603 	return ret;
604 }
605 
606 /* Delete dquot from tree */
qtree_delete_dquot(struct qtree_mem_dqinfo * info,struct dquot * dquot)607 int qtree_delete_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
608 {
609 	uint blks[MAX_QTREE_DEPTH] = { QT_TREEOFF };
610 
611 	if (!dquot->dq_off)	/* Even not allocated? */
612 		return 0;
613 	if (info->dqi_qtree_depth >= MAX_QTREE_DEPTH) {
614 		quota_error(dquot->dq_sb, "Quota tree depth too big!");
615 		return -EIO;
616 	}
617 	return remove_tree(info, dquot, blks, 0);
618 }
619 EXPORT_SYMBOL(qtree_delete_dquot);
620 
621 /* Find entry in block */
find_block_dqentry(struct qtree_mem_dqinfo * info,struct dquot * dquot,uint blk)622 static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
623 				 struct dquot *dquot, uint blk)
624 {
625 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
626 	loff_t ret = 0;
627 	int i;
628 	char *ddquot;
629 
630 	if (!buf)
631 		return -ENOMEM;
632 	ret = read_blk(info, blk, buf);
633 	if (ret < 0) {
634 		quota_error(dquot->dq_sb, "Can't read quota tree "
635 			    "block %u", blk);
636 		goto out_buf;
637 	}
638 	ddquot = buf + sizeof(struct qt_disk_dqdbheader);
639 	for (i = 0; i < qtree_dqstr_in_blk(info); i++) {
640 		if (info->dqi_ops->is_id(ddquot, dquot))
641 			break;
642 		ddquot += info->dqi_entry_size;
643 	}
644 	if (i == qtree_dqstr_in_blk(info)) {
645 		quota_error(dquot->dq_sb,
646 			    "Quota for id %u referenced but not present",
647 			    from_kqid(&init_user_ns, dquot->dq_id));
648 		ret = -EIO;
649 		goto out_buf;
650 	} else {
651 		ret = ((loff_t)blk << info->dqi_blocksize_bits) + sizeof(struct
652 		  qt_disk_dqdbheader) + i * info->dqi_entry_size;
653 	}
654 out_buf:
655 	kfree(buf);
656 	return ret;
657 }
658 
659 /* Find entry for given id in the tree */
find_tree_dqentry(struct qtree_mem_dqinfo * info,struct dquot * dquot,uint * blks,int depth)660 static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
661 				struct dquot *dquot, uint *blks, int depth)
662 {
663 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
664 	loff_t ret = 0;
665 	__le32 *ref = (__le32 *)buf;
666 	uint blk;
667 	int i;
668 
669 	if (!buf)
670 		return -ENOMEM;
671 	ret = read_blk(info, blks[depth], buf);
672 	if (ret < 0) {
673 		quota_error(dquot->dq_sb, "Can't read quota tree block %u",
674 			    blks[depth]);
675 		goto out_buf;
676 	}
677 	ret = 0;
678 	blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
679 	if (!blk)	/* No reference? */
680 		goto out_buf;
681 	ret = do_check_range(dquot->dq_sb, "block", blk, QT_TREEOFF,
682 			     info->dqi_blocks - 1);
683 	if (ret)
684 		goto out_buf;
685 
686 	/* Check for cycles in the tree */
687 	for (i = 0; i <= depth; i++)
688 		if (blk == blks[i]) {
689 			quota_error(dquot->dq_sb,
690 				"Cycle in quota tree detected: block %u index %u",
691 				blks[depth],
692 				get_index(info, dquot->dq_id, depth));
693 			ret = -EIO;
694 			goto out_buf;
695 		}
696 	blks[depth + 1] = blk;
697 	if (depth < info->dqi_qtree_depth - 1)
698 		ret = find_tree_dqentry(info, dquot, blks, depth + 1);
699 	else
700 		ret = find_block_dqentry(info, dquot, blk);
701 out_buf:
702 	kfree(buf);
703 	return ret;
704 }
705 
706 /* Find entry for given id in the tree - wrapper function */
find_dqentry(struct qtree_mem_dqinfo * info,struct dquot * dquot)707 static inline loff_t find_dqentry(struct qtree_mem_dqinfo *info,
708 				  struct dquot *dquot)
709 {
710 	uint blks[MAX_QTREE_DEPTH] = { QT_TREEOFF };
711 
712 	if (info->dqi_qtree_depth >= MAX_QTREE_DEPTH) {
713 		quota_error(dquot->dq_sb, "Quota tree depth too big!");
714 		return -EIO;
715 	}
716 	return find_tree_dqentry(info, dquot, blks, 0);
717 }
718 
qtree_read_dquot(struct qtree_mem_dqinfo * info,struct dquot * dquot)719 int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
720 {
721 	int type = dquot->dq_id.type;
722 	struct super_block *sb = dquot->dq_sb;
723 	loff_t offset;
724 	char *ddquot;
725 	int ret = 0;
726 
727 #ifdef __QUOTA_QT_PARANOIA
728 	/* Invalidated quota? */
729 	if (!sb_dqopt(dquot->dq_sb)->files[type]) {
730 		quota_error(sb, "Quota invalidated while reading!");
731 		return -EIO;
732 	}
733 #endif
734 	/* Do we know offset of the dquot entry in the quota file? */
735 	if (!dquot->dq_off) {
736 		offset = find_dqentry(info, dquot);
737 		if (offset <= 0) {	/* Entry not present? */
738 			if (offset < 0)
739 				quota_error(sb,"Can't read quota structure "
740 					    "for id %u",
741 					    from_kqid(&init_user_ns,
742 						      dquot->dq_id));
743 			dquot->dq_off = 0;
744 			set_bit(DQ_FAKE_B, &dquot->dq_flags);
745 			memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
746 			ret = offset;
747 			goto out;
748 		}
749 		dquot->dq_off = offset;
750 	}
751 	ddquot = kmalloc(info->dqi_entry_size, GFP_KERNEL);
752 	if (!ddquot)
753 		return -ENOMEM;
754 	ret = sb->s_op->quota_read(sb, type, ddquot, info->dqi_entry_size,
755 				   dquot->dq_off);
756 	if (ret != info->dqi_entry_size) {
757 		if (ret >= 0)
758 			ret = -EIO;
759 		quota_error(sb, "Error while reading quota structure for id %u",
760 			    from_kqid(&init_user_ns, dquot->dq_id));
761 		set_bit(DQ_FAKE_B, &dquot->dq_flags);
762 		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
763 		kfree(ddquot);
764 		goto out;
765 	}
766 	spin_lock(&dquot->dq_dqb_lock);
767 	info->dqi_ops->disk2mem_dqblk(dquot, ddquot);
768 	if (!dquot->dq_dqb.dqb_bhardlimit &&
769 	    !dquot->dq_dqb.dqb_bsoftlimit &&
770 	    !dquot->dq_dqb.dqb_ihardlimit &&
771 	    !dquot->dq_dqb.dqb_isoftlimit)
772 		set_bit(DQ_FAKE_B, &dquot->dq_flags);
773 	spin_unlock(&dquot->dq_dqb_lock);
774 	kfree(ddquot);
775 out:
776 	dqstats_inc(DQST_READS);
777 	return ret;
778 }
779 EXPORT_SYMBOL(qtree_read_dquot);
780 
781 /* Check whether dquot should not be deleted. We know we are
782  * the only one operating on dquot (thanks to dq_lock) */
qtree_release_dquot(struct qtree_mem_dqinfo * info,struct dquot * dquot)783 int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
784 {
785 	if (test_bit(DQ_FAKE_B, &dquot->dq_flags) &&
786 	    !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))
787 		return qtree_delete_dquot(info, dquot);
788 	return 0;
789 }
790 EXPORT_SYMBOL(qtree_release_dquot);
791 
find_next_id(struct qtree_mem_dqinfo * info,qid_t * id,unsigned int blk,int depth)792 static int find_next_id(struct qtree_mem_dqinfo *info, qid_t *id,
793 			unsigned int blk, int depth)
794 {
795 	char *buf = kmalloc(info->dqi_usable_bs, GFP_KERNEL);
796 	__le32 *ref = (__le32 *)buf;
797 	ssize_t ret;
798 	unsigned int epb = info->dqi_usable_bs >> 2;
799 	unsigned int level_inc = 1;
800 	int i;
801 
802 	if (!buf)
803 		return -ENOMEM;
804 
805 	for (i = depth; i < info->dqi_qtree_depth - 1; i++)
806 		level_inc *= epb;
807 
808 	ret = read_blk(info, blk, buf);
809 	if (ret < 0) {
810 		quota_error(info->dqi_sb,
811 			    "Can't read quota tree block %u", blk);
812 		goto out_buf;
813 	}
814 	for (i = __get_index(info, *id, depth); i < epb; i++) {
815 		uint blk_no = le32_to_cpu(ref[i]);
816 
817 		if (blk_no == 0) {
818 			*id += level_inc;
819 			continue;
820 		}
821 		ret = do_check_range(info->dqi_sb, "block", blk_no, 0,
822 				     info->dqi_blocks - 1);
823 		if (ret)
824 			goto out_buf;
825 		if (depth == info->dqi_qtree_depth - 1) {
826 			ret = 0;
827 			goto out_buf;
828 		}
829 		ret = find_next_id(info, id, blk_no, depth + 1);
830 		if (ret != -ENOENT)
831 			break;
832 	}
833 	if (i == epb) {
834 		ret = -ENOENT;
835 		goto out_buf;
836 	}
837 out_buf:
838 	kfree(buf);
839 	return ret;
840 }
841 
qtree_get_next_id(struct qtree_mem_dqinfo * info,struct kqid * qid)842 int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid)
843 {
844 	qid_t id = from_kqid(&init_user_ns, *qid);
845 	int ret;
846 
847 	ret = find_next_id(info, &id, QT_TREEOFF, 0);
848 	if (ret < 0)
849 		return ret;
850 	*qid = make_kqid(&init_user_ns, qid->type, id);
851 	return 0;
852 }
853 EXPORT_SYMBOL(qtree_get_next_id);
854