* GPL HEADER END
*/
/*
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ * Copyright (c) 2012, Intel Corporation.
* Use is subject to license terms.
*
* Lustre administrative quota format.
/**
* Read the \a blk into \a buf.
- *
- * TODO Will support enforcement quota later.
*/
static ssize_t quota_read_blk(const struct lu_env *env,
struct osd_object *obj,
ENTRY;
memset(buf, 0, LUSTRE_DQBLKSIZE);
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0)
+ /* type is set as -1 when reading old admin quota file */
+ if (type != USRQUOTA && type != GRPQUOTA) {
+ struct lu_buf lu_buffer;
+ loff_t pos;
+
+ lu_buffer.lb_buf = buf;
+ lu_buffer.lb_len = LUSTRE_DQBLKSIZE;
+ pos = blk << LUSTRE_DQBLKSIZE_BITS;
+
+ ret = dt_record_read(env, &obj->oo_dt, &lu_buffer, &pos);
+
+ if (ret == 0)
+ ret = LUSTRE_DQBLKSIZE;
+ else if (ret == -EBADR || ret == -EFAULT)
+ ret = 0;
+ RETURN(ret);
+ }
+#else
+#warning "remove old quota compatibility code"
+#endif
+
ret = sb->s_op->quota_read(sb, type, buf, LUSTRE_DQBLKSIZE,
blk << LUSTRE_DQBLKSIZE_BITS);
sizeof(struct lustre_disk_dqdbheader) + i * dqblk_sz;
if (it) {
- it->oiq_blk[LUSTRE_DQTREEDEPTH - 1] = blk;
+ it->oiq_blk[LUSTRE_DQTREEDEPTH] = blk;
it->oiq_offset = ret;
it->oiq_id = dqid;
+ it->oiq_index[LUSTRE_DQTREEDEPTH] = i;
} else {
ret = 0;
}
if (!buf)
RETURN(-ENOMEM);
- ret = quota_read_blk(env, obj, 0, blk, buf);
+ ret = quota_read_blk(env, obj, type, blk, buf);
if (ret < 0) {
CERROR("Can't read quota tree block %u.\n", blk);
GOTO(out_buf, ret);
else
ret = find_block_dqentry(env, obj, type, dqid, blk, it);
- if (it && ret > 0) /* Entry found */
- it->oiq_blk[depth] = blk;
+ if (it && ret > 0) {
+ it->oiq_blk[depth + 1] = blk;
+ it->oiq_index[depth] = GETIDINDEX(dqid, depth);
+ }
+
out_buf:
freedqbuf(buf);
RETURN(ret);
int type, uint blk, uint index,
struct osd_it_quota *it)
{
- dqbuf_t buf = getdqbuf();
+ dqbuf_t buf;
loff_t ret = 0;
struct lustre_disk_dqdbheader *dqhead;
int i, dqblk_sz;
struct lustre_disk_dqblk_v2 *ddquot;
-
+ struct osd_quota_leaf *leaf;
ENTRY;
+ /* check if the leaf block has been processed before */
+ cfs_list_for_each_entry(leaf, &it->oiq_list, oql_link) {
+ if (leaf->oql_blk == blk)
+ RETURN(1);
+ }
+
+ buf = getdqbuf();
dqhead = (struct lustre_disk_dqdbheader *)buf;
dqblk_sz = sizeof(struct lustre_disk_dqblk_v2);
if (!buf)
(char *)&ddquot[i], dqblk_sz))
continue;
- it->oiq_blk[LUSTRE_DQTREEDEPTH - 1] = blk;
+ it->oiq_blk[LUSTRE_DQTREEDEPTH] = blk;
it->oiq_id = le32_to_cpu(ddquot[i].dqb_id);
it->oiq_offset = (blk << LUSTRE_DQBLKSIZE_BITS) +
sizeof(struct lustre_disk_dqdbheader) +
i * dqblk_sz;
+ it->oiq_index[LUSTRE_DQTREEDEPTH] = i;
ret = 0;
break;
}
ret = walk_block_dqentry(env, obj, type, blk, 0, it);
}
- if (ret == 0) /* Entry found */
- it->oiq_blk[depth] = blk;
+ if (ret == 0) { /* Entry found */
+ it->oiq_blk[depth + 1] = blk;
+ it->oiq_index[depth] = index;
+ }
+
out_buf:
freedqbuf(buf);
RETURN(ret);