* GPL HEADER END
*/
/*
- * Copyright (c) 2011, 2012, Whamcloud, Inc.
+ * Copyright (c) 2012, Intel Corporation.
* Use is subject to license terms.
*
* Author: Johann Lombardi <johann@whamcloud.com>
const struct lu_fid *fid, struct osd_inode_id *id)
{
struct super_block *sb = osd_sb(osd);
+ unsigned long qf_inums[2] = {
+ le32_to_cpu(LDISKFS_SB(sb)->s_es->s_usr_quota_inum),
+ le32_to_cpu(LDISKFS_SB(sb)->s_es->s_grp_quota_inum)
+ };
ENTRY;
LASSERT(fid_is_acct(fid));
RETURN(-ENOENT);
id->oii_gen = OSD_OII_NOGEN;
- id->oii_ino = LDISKFS_SB(sb)->s_qf_inums[fid2type(fid)];
+ id->oii_ino = qf_inums[fid2type(fid)];
if (!ldiskfs_valid_inum(sb, id->oii_ino))
RETURN(-ENOENT);
RETURN(0);
struct lustre_capa *capa)
{
struct osd_thread_info *info = osd_oti_get(env);
+#ifdef HAVE_DQUOT_FS_DISK_QUOTA
+ struct fs_disk_quota *dqblk = &info->oti_fdq;
+#else
struct if_dqblk *dqblk = &info->oti_dqblk;
+#endif
struct super_block *sb = osd_sb(osd_obj2dev(osd_dt_obj(dtobj)));
struct lquota_acct_rec *rec = (struct lquota_acct_rec *)dtrec;
__u64 id = *((__u64 *)dtkey);
rc = sb->s_qcop->get_dqblk(sb, obj2type(dtobj), (qid_t) id, dqblk);
if (rc)
RETURN(rc);
+#ifdef HAVE_DQUOT_FS_DISK_QUOTA
+ rec->bspace = dqblk->d_bcount;
+ rec->ispace = dqblk->d_icount;
+#else
rec->bspace = dqblk->dqb_curspace;
rec->ispace = dqblk->dqb_curinodes;
+#endif
RETURN(+1);
}
RETURN(-EOVERFLOW);
}
- OSD_DECLARE_OP(oh, quota,
- (allocated || qi->lqi_id.qid_uid == 0) ?
- 1 : LDISKFS_QUOTA_INIT_BLOCKS(osd_sb(dev)));
+ osd_trans_declare_op(env, oh, OSD_OT_QUOTA,
+ (allocated || qi->lqi_id.qid_uid == 0) ?
+ 1: LDISKFS_QUOTA_INIT_BLOCKS(osd_sb(dev)));
oh->ot_id_array[i] = qi->lqi_id.qid_uid;
osd_qid_set_type(oh, i, qi->lqi_type);
}
};
-static int write_quota_rec(const struct lu_env *env, struct dt_object *dt,
- __u64 id, struct lquota_glb_rec *rec)
-{
- struct osd_device *osd = osd_obj2dev(osd_dt_obj(dt));
- struct thandle *th;
- struct dt_key *key = (struct dt_key *)&id;
- int rc;
- ENTRY;
-
- th = dt_trans_create(env, &osd->od_dt_dev);
- if (IS_ERR(th))
- RETURN(PTR_ERR(th));
-
- /* the entry with 0 key can always be found in IAM file. */
- if (id == 0) {
- rc = dt_declare_delete(env, dt, key, th);
- if (rc)
- GOTO(out, rc);
- }
-
- rc = dt_declare_insert(env, dt, (struct dt_rec *)rec, key, th);
- if (rc)
- GOTO(out, rc);
-
- rc = dt_trans_start_local(env, &osd->od_dt_dev, th);
- if (rc)
- GOTO(out, rc);
-
- dt_write_lock(env, dt, 0);
-
- if (id == 0) {
- struct lquota_glb_rec *tmp;
-
- OBD_ALLOC_PTR(tmp);
- if (tmp == NULL)
- GOTO(out_lock, rc = -ENOMEM);
-
- rc = dt_lookup(env, dt, (struct dt_rec *)tmp, key,
- BYPASS_CAPA);
-
- OBD_FREE_PTR(tmp);
- if (rc == 0) {
- rc = dt_delete(env, dt, key, th, BYPASS_CAPA);
- if (rc)
- GOTO(out_lock, rc);
- }
- rc = 0;
- }
-
- rc = dt_insert(env, dt, (struct dt_rec *)rec, key, th, BYPASS_CAPA, 1);
-out_lock:
- dt_write_unlock(env, dt);
-out:
- dt_trans_stop(env, &osd->od_dt_dev, th);
- RETURN(rc);
-}
-
static int convert_quota_file(const struct lu_env *env,
struct dt_object *old, struct dt_object *new,
bool isblk)
grace = isblk ? dqinfo->dqi_bgrace : dqinfo->dqi_igrace;
if (grace != 0) {
glb_rec->qbr_time = grace;
- rc = write_quota_rec(env, new, 0, glb_rec);
+ rc = lquota_disk_write_glb(env, new, 0, glb_rec);
if (rc)
GOTO(out, rc);
glb_rec->qbr_time = 0;
glb_rec->qbr_softlimit = isblk ? dqblk->dqb_bsoftlimit :
dqblk->dqb_isoftlimit;
- rc = write_quota_rec(env, new, *((__u64 *)key), glb_rec);
+ rc = lquota_disk_write_glb(env, new, *((__u64 *)key), glb_rec);
if (rc)
GOTO(out_it, rc);
next:
return rc;
}
+/* Nobdy else can access the global index now, it's safe to truncate and
+ * reinitialize it */
static int truncate_quota_index(const struct lu_env *env, struct dt_object *dt,
const struct dt_index_features *feat)
{
struct osd_thandle *oth;
struct inode *inode;
int rc;
+ struct iam_container *bag = &(osd_dt_obj(dt))->oo_dir->od_container;
ENTRY;
+ LASSERT(bag->ic_root_bh != NULL);
+ iam_container_fini(bag);
+
+ LASSERT(fid_seq(lu_object_fid(&dt->do_lu)) == FID_SEQ_QUOTA_GLB);
+
OBD_ALLOC_PTR(attr);
if (attr == NULL)
RETURN(-ENOMEM);
out:
dt_trans_stop(env, &osd->od_dt_dev, th);
OBD_FREE_PTR(attr);
+
+ if (rc == 0) {
+ rc = iam_container_setup(bag);
+ if (rc != 0)
+ iam_container_fini(bag);
+ }
RETURN(rc);
}
static int set_quota_index_version(const struct lu_env *env,
- struct dt_object *dt)
+ struct dt_object *dt,
+ dt_obj_version_t version)
{
struct osd_device *osd = osd_obj2dev(osd_dt_obj(dt));
struct thandle *th;
GOTO(out, rc);
th->th_sync = 1;
- dt_version_set(env, dt, 1, th);
+ dt_version_set(env, dt, version, th);
out:
dt_trans_stop(env, &osd->od_dt_dev, th);
RETURN(rc);
}
-#define OBJECTS "OBJECTS"
-#define ADMIN_USR "admin_quotafile_v2.usr"
-#define ADMIN_GRP "admin_quotafile_v2.grp"
-
int osd_quota_migration(const struct lu_env *env, struct dt_object *dt,
const struct dt_index_features *feat)
{
struct dt_object *root, *parent = NULL, *admin = NULL;
dt_obj_version_t version;
char *fname;
- bool isblk;
+ bool isblk, converted = false;
int rc;
ENTRY;
if (rc) {
CERROR("%s: Failed to truncate the quota index "DFID", rc:%d\n",
osd->od_svname, PFID(lu_object_fid(&dt->do_lu)), rc);
- RETURN(rc);
+ GOTO(out, rc);
}
/* set up indexing operations for the admin file */
if (rc)
CERROR("%s: Migrate old admin quota file(%s) failed, rc:%d\n",
osd->od_svname, fname, rc);
+ converted = true;
out:
- /* bump index version to 1, so the migration will be skipped
- * next time. */
+ /* if no migration happen, we need to set the default grace time. */
+ if (!converted && rc == 0) {
+ struct lquota_glb_rec *rec = &oti->oti_quota_rec.lqr_glb_rec;
+
+ rec->qbr_hardlimit = 0;
+ rec->qbr_softlimit = 0;
+ rec->qbr_granted = 0;
+ rec->qbr_time = isblk ? MAX_DQ_TIME : MAX_IQ_TIME;
+
+ rc = lquota_disk_write_glb(env, dt, 0, rec);
+ if (rc)
+ CERROR("%s: Failed to set default grace time for "
+ "index("DFID"), rc:%d\n", osd->od_svname,
+ PFID(lu_object_fid(&dt->do_lu)), rc);
+ }
+
+ /* bump index version to 1 (or 2 if migration happened), so the
+ * migration will be skipped next time. */
if (rc == 0) {
- rc = set_quota_index_version(env , dt);
+ rc = set_quota_index_version(env , dt, converted ? 2 : 1);
if (rc)
CERROR("%s: Failed to set quota index("DFID") "
"version, rc:%d\n", osd->od_svname,