X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fosd-ldiskfs%2Fosd_quota.c;h=a56f89011feef4749582d39e7455504eb3bc42c0;hb=d6f104f056a5ec6e82e19f12f6faefa0d3ca10a9;hp=8dbe02badee81873769c3d2bce19a3b67dba1f7d;hpb=3ff4a0744c229e0199bc7d93db9221c3bfb1f846;p=fs%2Flustre-release.git diff --git a/lustre/osd-ldiskfs/osd_quota.c b/lustre/osd-ldiskfs/osd_quota.c index 8dbe02b..a56f890 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -21,14 +21,14 @@ * GPL HEADER END */ /* - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2012, 2013, Intel Corporation. * Use is subject to license terms. * * Author: Johann Lombardi * Author: Niu Yawei */ -#include +#include #include "osd_internal.h" /** @@ -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,27 +104,44 @@ 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); int rc; +#ifdef HAVE_DQUOT_KQID + struct kqid qid; +#endif ENTRY; memset((void *)dqblk, 0, sizeof(struct obd_dqblk)); +#ifdef HAVE_DQUOT_KQID + qid = make_kqid(&init_user_ns, obj2type(dtobj), id); + rc = sb->s_qcop->get_dqblk(sb, qid, dqblk); +#else rc = sb->s_qcop->get_dqblk(sb, obj2type(dtobj), (qid_t) id, dqblk); +#endif 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); } #define QUOTA_IT_READ_ERROR(it, rc) \ CERROR("%s: Error while trying to read quota information, " \ "failed with %d\n", \ - it->oiq_obj->oo_dt.do_lu.lo_dev->ld_obd->obd_name, rc); \ + osd_dev(it->oiq_obj->oo_dt.do_lu.lo_dev)->od_svname, rc); \ /** * Initialize osd Iterator for given osd index object. @@ -149,7 +170,7 @@ static struct dt_it *osd_it_acct_init(const struct lu_env *env, memset(it, 0, sizeof(*it)); lu_object_get(lo); it->oiq_obj = obj; - CFS_INIT_LIST_HEAD(&it->oiq_list); + INIT_LIST_HEAD(&it->oiq_list); /* LUSTRE_DQTREEOFF is the initial offset where the tree can be found */ it->oiq_blk[0] = LUSTRE_DQTREEOFF; @@ -173,8 +194,8 @@ static void osd_it_acct_fini(const struct lu_env *env, struct dt_it *di) lu_object_put(env, &it->oiq_obj->oo_dt.do_lu); - cfs_list_for_each_entry_safe(leaf, tmp, &it->oiq_list, oql_link) { - cfs_list_del_init(&leaf->oql_link); + list_for_each_entry_safe(leaf, tmp, &it->oiq_list, oql_link) { + list_del_init(&leaf->oql_link); OBD_FREE_PTR(leaf); } EXIT; @@ -241,9 +262,9 @@ static int osd_it_add_processed(struct osd_it_quota *it, int depth) OBD_ALLOC_PTR(leaf); if (leaf == NULL) RETURN(-ENOMEM); - CFS_INIT_LIST_HEAD(&leaf->oql_link); + INIT_LIST_HEAD(&leaf->oql_link); leaf->oql_blk = it->oiq_blk[depth]; - cfs_list_add_tail(&leaf->oql_link, &it->oiq_list); + list_add_tail(&leaf->oql_link, &it->oiq_list); RETURN(0); } @@ -511,8 +532,9 @@ int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh, RETURN(-EOVERFLOW); } - oh->ot_credits += (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); @@ -722,63 +744,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) @@ -828,7 +793,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; @@ -865,7 +830,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: @@ -889,6 +854,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) { @@ -898,8 +865,15 @@ 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; + struct lu_buf *lb = &osd_oti_get(env)->oti_buf; 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); @@ -924,7 +898,9 @@ static int truncate_quota_index(const struct lu_env *env, struct dt_object *dt, inode = osd_dt_obj(dt)->oo_inode; LASSERT(inode); - rc = dt_declare_record_write(env, dt, inode->i_sb->s_blocksize * 2, 0, th); + /* iam_lfix_create() writes two blocks at the beginning */ + lb->lb_len = osd_sb(osd)->s_blocksize * 2; + rc = dt_declare_record_write(env, dt, lb, 0, th); if (rc) GOTO(out, rc); @@ -958,11 +934,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; @@ -982,16 +965,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) { @@ -1000,7 +979,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 = false, converted = false; int rc; ENTRY; @@ -1085,7 +1064,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 */ @@ -1102,11 +1081,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,