cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

quota_tree.c (18997B)


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