X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_quota.c;h=39059f080d08e5816a631de59e44f908f2774b50;hb=413b6c2e365cf3ff986611e20dd77186ed25a3ac;hp=2bf0b5dfca0ba059e4d6366e229a2dbe9f44bbec;hpb=1f14f0da5098e9ad2fec1fa283659f48b8f827a7;p=fs%2Flustre-release.git diff --git a/lustre/osd-ldiskfs/osd_quota.c b/lustre/osd-ldiskfs/osd_quota.c index 2bf0b5d..39059f0 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -21,7 +21,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2012, Intel Corporation. * Use is subject to license terms. * * Author: Johann Lombardi @@ -65,6 +65,10 @@ int osd_acct_obj_lookup(struct osd_thread_info *info, struct osd_device *osd, 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)); @@ -74,7 +78,7 @@ int osd_acct_obj_lookup(struct osd_thread_info *info, struct osd_device *osd, 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); @@ -100,7 +104,11 @@ static int osd_acct_index_lookup(const struct lu_env *env, 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); @@ -112,8 +120,13 @@ static int osd_acct_index_lookup(const struct lu_env *env, 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); } @@ -511,9 +524,9 @@ int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh, 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); @@ -723,63 +736,6 @@ const struct dt_index_operations osd_admin_index_ops = { } }; -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) @@ -829,7 +785,7 @@ static int convert_quota_file(const struct lu_env *env, 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; @@ -866,7 +822,7 @@ static int convert_quota_file(const struct lu_env *env, 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: @@ -890,6 +846,8 @@ out: 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) { @@ -899,8 +857,14 @@ static int truncate_quota_index(const struct lu_env *env, struct dt_object *dt, 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); @@ -959,11 +923,18 @@ out_lock: 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; @@ -983,16 +954,12 @@ static int set_quota_index_version(const struct lu_env *env, 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) { @@ -1001,7 +968,7 @@ int osd_quota_migration(const struct lu_env *env, struct dt_object *dt, struct dt_object *root, *parent = NULL, *admin = NULL; dt_obj_version_t version; char *fname; - bool isblk; + bool isblk, converted = false; int rc; ENTRY; @@ -1086,7 +1053,7 @@ int osd_quota_migration(const struct lu_env *env, struct dt_object *dt, 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 */ @@ -1103,11 +1070,28 @@ int osd_quota_migration(const struct lu_env *env, struct dt_object *dt, 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,