Lines Matching +full:depth +full:-
1 // SPDX-License-Identifier: GPL-2.0-only
26 static int __get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth) in __get_index() argument
28 unsigned int epb = info->dqi_usable_bs >> 2; in __get_index()
30 depth = info->dqi_qtree_depth - depth - 1; in __get_index()
31 while (depth--) in __get_index()
36 static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth) in get_index() argument
40 return __get_index(info, id, depth); in get_index()
46 return (info->dqi_usable_bs - sizeof(struct qt_disk_dqdbheader)) in qtree_dqstr_in_blk()
47 / info->dqi_entry_size; in qtree_dqstr_in_blk()
61 struct super_block *sb = info->dqi_sb; in read_blk()
63 memset(buf, 0, info->dqi_usable_bs); in read_blk()
64 return sb->s_op->quota_read(sb, info->dqi_type, buf, in read_blk()
65 info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits); in read_blk()
70 struct super_block *sb = info->dqi_sb; in write_blk()
73 ret = sb->s_op->quota_write(sb, info->dqi_type, buf, in write_blk()
74 info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits); in write_blk()
75 if (ret != info->dqi_usable_bs) { in write_blk()
78 ret = -EIO; in write_blk()
86 char *buf = getdqbuf(info->dqi_usable_bs); in get_free_dqblk()
91 return -ENOMEM; in get_free_dqblk()
92 if (info->dqi_free_blk) { in get_free_dqblk()
93 blk = info->dqi_free_blk; in get_free_dqblk()
97 info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free); in get_free_dqblk()
100 memset(buf, 0, info->dqi_usable_bs); in get_free_dqblk()
102 ret = write_blk(info, info->dqi_blocks, buf); in get_free_dqblk()
105 blk = info->dqi_blocks++; in get_free_dqblk()
107 mark_info_dirty(info->dqi_sb, info->dqi_type); in get_free_dqblk()
120 dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk); in put_free_dqblk()
121 dh->dqdh_prev_free = cpu_to_le32(0); in put_free_dqblk()
122 dh->dqdh_entries = cpu_to_le16(0); in put_free_dqblk()
126 info->dqi_free_blk = blk; in put_free_dqblk()
127 mark_info_dirty(info->dqi_sb, info->dqi_type); in put_free_dqblk()
135 char *tmpbuf = getdqbuf(info->dqi_usable_bs); in remove_free_dqentry()
137 uint nextblk = le32_to_cpu(dh->dqdh_next_free); in remove_free_dqentry()
138 uint prevblk = le32_to_cpu(dh->dqdh_prev_free); in remove_free_dqentry()
142 return -ENOMEM; in remove_free_dqentry()
147 ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = in remove_free_dqentry()
148 dh->dqdh_prev_free; in remove_free_dqentry()
157 ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_next_free = in remove_free_dqentry()
158 dh->dqdh_next_free; in remove_free_dqentry()
163 info->dqi_free_entry = nextblk; in remove_free_dqentry()
164 mark_info_dirty(info->dqi_sb, info->dqi_type); in remove_free_dqentry()
167 dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); in remove_free_dqentry()
170 quota_error(info->dqi_sb, "Can't write block (%u) " in remove_free_dqentry()
182 char *tmpbuf = getdqbuf(info->dqi_usable_bs); in insert_free_dqentry()
187 return -ENOMEM; in insert_free_dqentry()
188 dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry); in insert_free_dqentry()
189 dh->dqdh_prev_free = cpu_to_le32(0); in insert_free_dqentry()
193 if (info->dqi_free_entry) { in insert_free_dqentry()
194 err = read_blk(info, info->dqi_free_entry, tmpbuf); in insert_free_dqentry()
197 ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = in insert_free_dqentry()
199 err = write_blk(info, info->dqi_free_entry, tmpbuf); in insert_free_dqentry()
204 info->dqi_free_entry = blk; in insert_free_dqentry()
205 mark_info_dirty(info->dqi_sb, info->dqi_type); in insert_free_dqentry()
217 for (i = 0; i < info->dqi_entry_size; i++) in qtree_entry_unused()
230 char *buf = getdqbuf(info->dqi_usable_bs); in find_free_dqentry()
235 *err = -ENOMEM; in find_free_dqentry()
239 if (info->dqi_free_entry) { in find_free_dqentry()
240 blk = info->dqi_free_entry; in find_free_dqentry()
251 memset(buf, 0, info->dqi_usable_bs); in find_free_dqentry()
254 info->dqi_free_entry = blk; in find_free_dqentry()
255 mark_info_dirty(dquot->dq_sb, dquot->dq_id.type); in find_free_dqentry()
258 if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { in find_free_dqentry()
261 quota_error(dquot->dq_sb, "Can't remove block (%u) " in find_free_dqentry()
266 le16_add_cpu(&dh->dqdh_entries, 1); in find_free_dqentry()
272 ddquot += info->dqi_entry_size; in find_free_dqentry()
276 quota_error(dquot->dq_sb, "Data block full but it shouldn't"); in find_free_dqentry()
277 *err = -EIO; in find_free_dqentry()
283 quota_error(dquot->dq_sb, "Can't write quota data block %u", in find_free_dqentry()
287 dquot->dq_off = ((loff_t)blk << info->dqi_blocksize_bits) + in find_free_dqentry()
289 i * info->dqi_entry_size; in find_free_dqentry()
299 uint *treeblk, int depth) in do_insert_tree() argument
301 char *buf = getdqbuf(info->dqi_usable_bs); in do_insert_tree()
307 return -ENOMEM; in do_insert_tree()
313 memset(buf, 0, info->dqi_usable_bs); in do_insert_tree()
318 quota_error(dquot->dq_sb, "Can't read tree quota " in do_insert_tree()
324 newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); in do_insert_tree()
327 if (depth == info->dqi_qtree_depth - 1) { in do_insert_tree()
330 quota_error(dquot->dq_sb, "Inserting already present " in do_insert_tree()
333 dquot->dq_id, depth)])); in do_insert_tree()
334 ret = -EIO; in do_insert_tree()
340 ret = do_insert_tree(info, dquot, &newblk, depth+1); in do_insert_tree()
343 ref[get_index(info, dquot->dq_id, depth)] = in do_insert_tree()
361 if (info->dqi_blocks <= QT_TREEOFF) { in dq_insert_tree()
362 quota_error(dquot->dq_sb, "Quota tree root isn't allocated!"); in dq_insert_tree()
363 return -EIO; in dq_insert_tree()
375 int type = dquot->dq_id.type; in qtree_write_dquot()
376 struct super_block *sb = dquot->dq_sb; in qtree_write_dquot()
378 char *ddquot = getdqbuf(info->dqi_entry_size); in qtree_write_dquot()
381 return -ENOMEM; in qtree_write_dquot()
384 if (!dquot->dq_off) { in qtree_write_dquot()
393 spin_lock(&dquot->dq_dqb_lock); in qtree_write_dquot()
394 info->dqi_ops->mem2disk_dqblk(ddquot, dquot); in qtree_write_dquot()
395 spin_unlock(&dquot->dq_dqb_lock); in qtree_write_dquot()
396 ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, in qtree_write_dquot()
397 dquot->dq_off); in qtree_write_dquot()
398 if (ret != info->dqi_entry_size) { in qtree_write_dquot()
401 ret = -ENOSPC; in qtree_write_dquot()
417 char *buf = getdqbuf(info->dqi_usable_bs); in free_dqentry()
421 return -ENOMEM; in free_dqentry()
422 if (dquot->dq_off >> info->dqi_blocksize_bits != blk) { in free_dqentry()
423 quota_error(dquot->dq_sb, "Quota structure has offset to " in free_dqentry()
425 (uint)(dquot->dq_off >> info->dqi_blocksize_bits)); in free_dqentry()
426 ret = -EIO; in free_dqentry()
431 quota_error(dquot->dq_sb, "Can't read quota data block %u", in free_dqentry()
436 le16_add_cpu(&dh->dqdh_entries, -1); in free_dqentry()
437 if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */ in free_dqentry()
442 quota_error(dquot->dq_sb, "Can't move quota data block " in free_dqentry()
448 (dquot->dq_off & ((1 << info->dqi_blocksize_bits) - 1)), in free_dqentry()
449 0, info->dqi_entry_size); in free_dqentry()
450 if (le16_to_cpu(dh->dqdh_entries) == in free_dqentry()
451 qtree_dqstr_in_blk(info) - 1) { in free_dqentry()
455 quota_error(dquot->dq_sb, "Can't insert quota " in free_dqentry()
462 quota_error(dquot->dq_sb, "Can't write quota " in free_dqentry()
468 dquot->dq_off = 0; /* Quota is now unattached */ in free_dqentry()
476 uint *blk, int depth) in remove_tree() argument
478 char *buf = getdqbuf(info->dqi_usable_bs); in remove_tree()
484 return -ENOMEM; in remove_tree()
487 quota_error(dquot->dq_sb, "Can't read quota data block %u", in remove_tree()
491 newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); in remove_tree()
492 if (newblk < QT_TREEOFF || newblk >= info->dqi_blocks) { in remove_tree()
493 quota_error(dquot->dq_sb, "Getting block too big (%u >= %u)", in remove_tree()
494 newblk, info->dqi_blocks); in remove_tree()
495 ret = -EUCLEAN; in remove_tree()
499 if (depth == info->dqi_qtree_depth - 1) { in remove_tree()
503 ret = remove_tree(info, dquot, &newblk, depth+1); in remove_tree()
507 ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0); in remove_tree()
509 for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++) in remove_tree()
512 if (i == (info->dqi_usable_bs >> 2) in remove_tree()
519 quota_error(dquot->dq_sb, in remove_tree()
534 if (!dquot->dq_off) /* Even not allocated? */ in qtree_delete_dquot()
544 char *buf = getdqbuf(info->dqi_usable_bs); in find_block_dqentry()
550 return -ENOMEM; in find_block_dqentry()
553 quota_error(dquot->dq_sb, "Can't read quota tree " in find_block_dqentry()
559 if (info->dqi_ops->is_id(ddquot, dquot)) in find_block_dqentry()
561 ddquot += info->dqi_entry_size; in find_block_dqentry()
564 quota_error(dquot->dq_sb, in find_block_dqentry()
566 from_kqid(&init_user_ns, dquot->dq_id)); in find_block_dqentry()
567 ret = -EIO; in find_block_dqentry()
570 ret = ((loff_t)blk << info->dqi_blocksize_bits) + sizeof(struct in find_block_dqentry()
571 qt_disk_dqdbheader) + i * info->dqi_entry_size; in find_block_dqentry()
580 struct dquot *dquot, uint blk, int depth) in find_tree_dqentry() argument
582 char *buf = getdqbuf(info->dqi_usable_bs); in find_tree_dqentry()
587 return -ENOMEM; in find_tree_dqentry()
590 quota_error(dquot->dq_sb, "Can't read quota tree block %u", in find_tree_dqentry()
595 blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); in find_tree_dqentry()
598 if (blk < QT_TREEOFF || blk >= info->dqi_blocks) { in find_tree_dqentry()
599 quota_error(dquot->dq_sb, "Getting block too big (%u >= %u)", in find_tree_dqentry()
600 blk, info->dqi_blocks); in find_tree_dqentry()
601 ret = -EUCLEAN; in find_tree_dqentry()
605 if (depth < info->dqi_qtree_depth - 1) in find_tree_dqentry()
606 ret = find_tree_dqentry(info, dquot, blk, depth+1); in find_tree_dqentry()
614 /* Find entry for given id in the tree - wrapper function */
623 int type = dquot->dq_id.type; in qtree_read_dquot()
624 struct super_block *sb = dquot->dq_sb; in qtree_read_dquot()
631 if (!sb_dqopt(dquot->dq_sb)->files[type]) { in qtree_read_dquot()
633 return -EIO; in qtree_read_dquot()
637 if (!dquot->dq_off) { in qtree_read_dquot()
644 dquot->dq_id)); in qtree_read_dquot()
645 dquot->dq_off = 0; in qtree_read_dquot()
646 set_bit(DQ_FAKE_B, &dquot->dq_flags); in qtree_read_dquot()
647 memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); in qtree_read_dquot()
651 dquot->dq_off = offset; in qtree_read_dquot()
653 ddquot = getdqbuf(info->dqi_entry_size); in qtree_read_dquot()
655 return -ENOMEM; in qtree_read_dquot()
656 ret = sb->s_op->quota_read(sb, type, ddquot, info->dqi_entry_size, in qtree_read_dquot()
657 dquot->dq_off); in qtree_read_dquot()
658 if (ret != info->dqi_entry_size) { in qtree_read_dquot()
660 ret = -EIO; in qtree_read_dquot()
662 from_kqid(&init_user_ns, dquot->dq_id)); in qtree_read_dquot()
663 set_bit(DQ_FAKE_B, &dquot->dq_flags); in qtree_read_dquot()
664 memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); in qtree_read_dquot()
668 spin_lock(&dquot->dq_dqb_lock); in qtree_read_dquot()
669 info->dqi_ops->disk2mem_dqblk(dquot, ddquot); in qtree_read_dquot()
670 if (!dquot->dq_dqb.dqb_bhardlimit && in qtree_read_dquot()
671 !dquot->dq_dqb.dqb_bsoftlimit && in qtree_read_dquot()
672 !dquot->dq_dqb.dqb_ihardlimit && in qtree_read_dquot()
673 !dquot->dq_dqb.dqb_isoftlimit) in qtree_read_dquot()
674 set_bit(DQ_FAKE_B, &dquot->dq_flags); in qtree_read_dquot()
675 spin_unlock(&dquot->dq_dqb_lock); in qtree_read_dquot()
687 if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && in qtree_release_dquot()
688 !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) in qtree_release_dquot()
695 unsigned int blk, int depth) in find_next_id() argument
697 char *buf = getdqbuf(info->dqi_usable_bs); in find_next_id()
700 unsigned int epb = info->dqi_usable_bs >> 2; in find_next_id()
705 return -ENOMEM; in find_next_id()
707 for (i = depth; i < info->dqi_qtree_depth - 1; i++) in find_next_id()
712 quota_error(info->dqi_sb, in find_next_id()
716 for (i = __get_index(info, *id, depth); i < epb; i++) { in find_next_id()
721 if (depth == info->dqi_qtree_depth - 1) { in find_next_id()
725 ret = find_next_id(info, id, le32_to_cpu(ref[i]), depth + 1); in find_next_id()
726 if (ret != -ENOENT) in find_next_id()
730 ret = -ENOENT; in find_next_id()
746 *qid = make_kqid(&init_user_ns, qid->type, id); in qtree_get_next_id()