From: Li Xi Date: Wed, 2 Apr 2014 07:26:59 +0000 (+0800) Subject: LU-4017 quota: add project quota support for Lustre X-Git-Tag: 2.9.56~42 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=792be6ca54810b04bdc4fd4f61e4b05fc701e587 LU-4017 quota: add project quota support for Lustre Thsi patch adds necessary support of project quota, so that OSTs can be mounted successully Signed-off-by: Li Xi Signed-off-by: Wang Shilong Change-Id: I0c56b14b4ebb0b495497d2f05981a03218f686d7 Reviewed-on: https://review.whamcloud.com/23947 Reviewed-by: Niu Yawei Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index b0d90ef..73160ae 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1464,6 +1464,21 @@ block_device_ops_release_return_int, [ ]) ]) # LC_BLKDEV_RELEASE_RETURN_INT +AC_DEFUN([LC_HAVE_PROJECT_QUOTA], [ +LB_CHECK_COMPILE([if get_projid exists], +get_projid, [ + #include +],[ + struct dquot_operations ops; + + ops.get_projid(NULL, NULL); +],[ + AC_DEFINE(HAVE_PROJECT_QUOTA, 1, + [get_projid function exists]) +]) +]) # LC_HAVE_PROJECT_QUOTA + + # # LC_HAVE_SECURITY_DENTRY_INIT_SECURITY # @@ -2401,6 +2416,7 @@ AC_DEFUN([LC_PROG_LINUX], [ LC_BLKDEV_RELEASE_RETURN_INT LC_HAVE_REMOVE_PROC_SUBTREE LC_HAVE_PROC_REMOVE + LC_HAVE_PROJECT_QUOTA LC_HAVE_SECURITY_DENTRY_INIT_SECURITY # 3.11 diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 7e94d97..4394ddd 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -974,6 +974,8 @@ enum obdo_flags { OBD_FL_IDONLY = 0x00000010, /* set in o_flags only adjust obj id*/ OBD_FL_RECREATE_OBJS= 0x00000020, /* recreate missing obj */ OBD_FL_DEBUG_CHECK = 0x00000040, /* echo client/server debug check */ + OBD_FL_NO_PRJQUOTA = 0x00000080, /* the object's project is over + * quota */ OBD_FL_NO_USRQUOTA = 0x00000100, /* the object's owner is over quota */ OBD_FL_NO_GRPQUOTA = 0x00000200, /* the object's group is over quota */ OBD_FL_CREATE_CROW = 0x00000400, /* object should be create on write */ @@ -1160,8 +1162,8 @@ lov_mds_md_max_stripe_count(size_t buf_size, __u32 lmm_magic) #define OBD_MD_FLHANDLE (0x00080000ULL) /* file/lock handle */ #define OBD_MD_FLCKSUM (0x00100000ULL) /* bulk data checksum */ #define OBD_MD_FLQOS (0x00200000ULL) /* quality of service stats */ -/*#define OBD_MD_FLOSCOPQ (0x00400000ULL) osc opaque data, never used */ /* OBD_MD_FLCOOKIE (0x00800000ULL) obsolete in 2.8 */ +#define OBD_MD_FLPRJQUOTA (0x00400000ULL) /* over quota flags sent from ost */ #define OBD_MD_FLGROUP (0x01000000ULL) /* group */ #define OBD_MD_FLFID (0x02000000ULL) /* ->ost write inline fid */ #define OBD_MD_FLEPOCH (0x04000000ULL) /* ->ost write with ioepoch */ @@ -1199,7 +1201,9 @@ lov_mds_md_max_stripe_count(size_t buf_size, __u32 lmm_magic) #define OBD_MD_DEFAULT_MEA (0x0040000000000000ULL) /* default MEA */ #define OBD_MD_FLOSTLAYOUT (0x0080000000000000ULL) /* contain ost_layout */ -#define OBD_MD_FLALLQUOTA (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA) +#define OBD_MD_FLALLQUOTA (OBD_MD_FLUSRQUOTA | \ + OBD_MD_FLGRPQUOTA | \ + OBD_MD_FLPRJQUOTA) #define OBD_MD_FLGETATTR (OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | \ OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \ @@ -1247,8 +1251,11 @@ struct hsm_state_set { * that the client is running low on * space for unstable pages; asking * it to sync quickly */ +#define OBD_BRW_OVER_PRJQUOTA 0x8000 /* Running out of project quota */ -#define OBD_BRW_OVER_ALLQUOTA (OBD_BRW_OVER_USRQUOTA | OBD_BRW_OVER_GRPQUOTA) +#define OBD_BRW_OVER_ALLQUOTA (OBD_BRW_OVER_USRQUOTA | \ + OBD_BRW_OVER_GRPQUOTA | \ + OBD_BRW_OVER_PRJQUOTA) #define OBD_OBJECT_EOF LUSTRE_EOF @@ -1392,6 +1399,7 @@ struct quota_body { enum { LQUOTA_TYPE_USR = 0x00, /* maps to USRQUOTA */ LQUOTA_TYPE_GRP = 0x01, /* maps to GRPQUOTA */ + LQUOTA_TYPE_PRJ = 0x02, /* maps to PRJQUOTA */ LQUOTA_TYPE_MAX }; diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index f1e7fc4..71d5814 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -724,6 +724,8 @@ static inline char *qtype_name(int qtype) return "usr"; case GRPQUOTA: return "grp"; + case PRJQUOTA: + return "project"; } return "unknown"; } diff --git a/lustre/include/lustre_fid.h b/lustre/include/lustre_fid.h index 37baa62..824eb82 100644 --- a/lustre/include/lustre_fid.h +++ b/lustre/include/lustre_fid.h @@ -224,6 +224,7 @@ enum local_oid { OTABLE_IT_OID = 18UL, OSD_LPF_OID = 19UL, REPLY_DATA_OID = 21UL, + ACCT_PROJECT_OID = 22UL, OFD_LAST_GROUP_OID = 4117UL, LLOG_CATALOGS_OID = 4118UL, MGS_CONFIGS_OID = 4119UL, @@ -283,6 +284,7 @@ static inline int fid_oid_is_quota(const struct lu_fid *fid) switch (fid_oid(fid)) { case ACCT_USER_OID: case ACCT_GROUP_OID: + case ACCT_PROJECT_OID: return 1; default: return 0; diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h index 2bb8c20..1a2f2a3 100644 --- a/lustre/include/lustre_quota.h +++ b/lustre/include/lustre_quota.h @@ -227,6 +227,7 @@ struct lquota_trans { #define QUOTA_FL_OVER_USRQUOTA 0x01 #define QUOTA_FL_OVER_GRPQUOTA 0x02 #define QUOTA_FL_SYNC 0x04 +#define QUOTA_FL_OVER_PRJQUOTA 0x08 #define IS_LQUOTA_RES(res) \ (res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA || \ diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index b41b70e..212e279 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -2146,6 +2146,10 @@ static int mdt_quotactl(struct tgt_session_info *tsi) id = nodemap_map_id(nodemap, NODEMAP_UID, NODEMAP_CLIENT_TO_FS, id); break; + case PRJQUOTA: + /* todo: check/map project id */ + id = oqctl->qc_id; + break; default: GOTO(out_nodemap, rc = -EOPNOTSUPP); } diff --git a/lustre/ofd/ofd_io.c b/lustre/ofd/ofd_io.c index 5129ae9..6f2fe7f 100644 --- a/lustre/ofd/ofd_io.c +++ b/lustre/ofd/ofd_io.c @@ -1248,6 +1248,12 @@ int ofd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, else oa->o_flags = OBD_FL_NO_GRPQUOTA; } + if (lnb[0].lnb_flags & OBD_BRW_OVER_PRJQUOTA) { + if (oa->o_valid & OBD_MD_FLFLAGS) + oa->o_flags |= OBD_FL_NO_PRJQUOTA; + else + oa->o_flags = OBD_FL_NO_PRJQUOTA; + } oa->o_valid |= OBD_MD_FLFLAGS; oa->o_valid |= OBD_MD_FLALLQUOTA; diff --git a/lustre/osc/osc_quota.c b/lustre/osc/osc_quota.c index d817953..7dcbbd7 100644 --- a/lustre/osc/osc_quota.c +++ b/lustre/osc/osc_quota.c @@ -73,6 +73,8 @@ static inline u32 md_quota_flag(int qtype) return OBD_MD_FLUSRQUOTA; case GRPQUOTA: return OBD_MD_FLGRPQUOTA; + case PRJQUOTA: + return OBD_MD_FLPRJQUOTA; default: return 0; } @@ -85,6 +87,8 @@ static inline u32 fl_quota_flag(int qtype) return OBD_FL_NO_USRQUOTA; case GRPQUOTA: return OBD_FL_NO_GRPQUOTA; + case PRJQUOTA: + return OBD_FL_NO_PRJQUOTA; default: return 0; } @@ -98,7 +102,7 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], ENTRY; - if ((valid & (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA)) == 0) + if ((valid & (OBD_MD_FLALLQUOTA)) == 0) RETURN(0); for (type = 0; type < LL_MAXQUOTAS; type++) { diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index c6522ae..1d942aa 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -1206,6 +1206,8 @@ static int osd_declare_write_commit(const struct lu_env *env, lnb[0].lnb_flags |= OBD_BRW_OVER_USRQUOTA; if (flags & QUOTA_FL_OVER_GRPQUOTA) lnb[0].lnb_flags |= OBD_BRW_OVER_GRPQUOTA; + if (flags & QUOTA_FL_OVER_PRJQUOTA) + lnb[0].lnb_flags |= OBD_BRW_OVER_PRJQUOTA; RETURN(rc); } diff --git a/lustre/osd-ldiskfs/osd_quota.c b/lustre/osd-ldiskfs/osd_quota.c index e4f531c..6b184fb 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -43,6 +43,8 @@ static inline int fid2type(const struct lu_fid *fid) return USRQUOTA; case ACCT_GROUP_OID: return GRPQUOTA; + case ACCT_PROJECT_OID: + return PRJQUOTA; } LASSERTF(0, "invalid fid for quota type: %u", fid_oid(fid)); @@ -66,10 +68,6 @@ 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[LL_MAXQUOTAS] = { - 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)); @@ -79,7 +77,27 @@ 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 = qf_inums[fid2type(fid)]; + switch (fid2type(fid)) { + case USRQUOTA: + id->oii_ino = + le32_to_cpu(LDISKFS_SB(sb)->s_es->s_usr_quota_inum); + break; + case GRPQUOTA: + id->oii_ino = + le32_to_cpu(LDISKFS_SB(sb)->s_es->s_grp_quota_inum); + break; + case PRJQUOTA: +#ifdef HAVE_PROJECT_QUOTA + if (!LDISKFS_HAS_RO_COMPAT_FEATURE(sb, + LDISKFS_FEATURE_RO_COMPAT_PROJECT)) + RETURN(-ENOTSUPP); + id->oii_ino = + le32_to_cpu(LDISKFS_SB(sb)->s_es->s_prj_quota_inum); + break; +#else + RETURN(-ENOTSUPP); +#endif + } if (!ldiskfs_valid_inum(sb, id->oii_ino)) RETURN(-ENOENT); RETURN(0); diff --git a/lustre/osd-zfs/osd_oi.c b/lustre/osd-zfs/osd_oi.c index bad04a4..87b6681e 100644 --- a/lustre/osd-zfs/osd_oi.c +++ b/lustre/osd-zfs/osd_oi.c @@ -90,6 +90,7 @@ static const struct named_oid oids[] = { { .oid = OFD_HEALTH_CHECK_OID, .name = HEALTH_CHECK }, { .oid = ACCT_USER_OID, .name = "acct_usr_inode" }, { .oid = ACCT_GROUP_OID, .name = "acct_grp_inode" }, + { .oid = ACCT_PROJECT_OID, .name = "acct_prj_inode" }, { .oid = REPLY_DATA_OID, .name = REPLY_DATA }, { .oid = 0 } }; @@ -481,17 +482,24 @@ static inline int fid_is_fs_root(const struct lu_fid *fid) fid_oid(fid) == OSD_FS_ROOT_OID; } -static inline uint64_t osd_oid(struct osd_device *dev, __u32 local_oid) +static inline int osd_oid(struct osd_device *dev, __u32 local_oid, + uint64_t *oid) { switch (local_oid) { case ACCT_USER_OID: - return dev->od_iusr_oid; + *oid = dev->od_iusr_oid; + return 0; case ACCT_GROUP_OID: - return dev->od_igrp_oid; + *oid = dev->od_igrp_oid; + return 0; + case ACCT_PROJECT_OID: + /* TODO: real oid */ + CERROR("unsupported quota oid: %#x\n", local_oid); + return -ENOTSUPP; } LASSERTF(0, "invalid oid: %u for quota type", local_oid); - return dev->od_igrp_oid; + return -ENOTSUPP; } int osd_fid_lookup(const struct lu_env *env, struct osd_device *dev, @@ -507,7 +515,9 @@ int osd_fid_lookup(const struct lu_env *env, struct osd_device *dev, RETURN(-ENOENT); if (unlikely(fid_is_acct(fid))) { - *oid = osd_oid(dev, fid_oid(fid)); + rc = osd_oid(dev, fid_oid(fid), oid); + if (rc) + RETURN(rc); } else if (unlikely(fid_is_fs_root(fid))) { *oid = dev->od_root; } else { diff --git a/lustre/quota/lproc_quota.c b/lustre/quota/lproc_quota.c index 034a269..ecee4a9 100644 --- a/lustre/quota/lproc_quota.c +++ b/lustre/quota/lproc_quota.c @@ -172,6 +172,9 @@ static inline const char *oid2name(__u32 oid) return "usr_accounting"; case ACCT_GROUP_OID: return "grp_accounting"; + case ACCT_PROJECT_OID: + return "prj_accounting"; + break; default: return "unknown_accounting"; } diff --git a/lustre/quota/lquota_internal.h b/lustre/quota/lquota_internal.h index 19a08cb..b7fa192 100644 --- a/lustre/quota/lquota_internal.h +++ b/lustre/quota/lquota_internal.h @@ -39,6 +39,9 @@ static inline char *qtype_name(int qtype) return "usr"; case GRPQUOTA: return "grp"; + case PRJQUOTA: + return "prj"; + break; } return "unknown"; } @@ -58,6 +61,7 @@ static inline char *qtype_name(int qtype) enum lquota_local_oid { LQUOTA_USR_OID = 1UL, /* slave index copy for user quota */ LQUOTA_GRP_OID = 2UL, /* slave index copy for group quota */ + LQUOTA_PRJ_OID = 3UL, /* slave index copy for project quota */ /* all OIDs after this are allocated dynamically by the QMT */ LQUOTA_GENERATED_OID = 4096UL, }; @@ -69,6 +73,8 @@ static inline __u32 qtype2slv_oid(int qtype) return LQUOTA_USR_OID; case GRPQUOTA: return LQUOTA_GRP_OID; + case PRJQUOTA: + return LQUOTA_PRJ_OID; } LASSERTF(0, "invalid quota type: %d", qtype); @@ -311,6 +317,8 @@ static inline int lquota_over_fl(int qtype) return QUOTA_FL_OVER_USRQUOTA; case GRPQUOTA: return QUOTA_FL_OVER_GRPQUOTA; + case PRJQUOTA: + return QUOTA_FL_OVER_PRJQUOTA; } LASSERTF(0, "invalid quota type: %d", qtype); diff --git a/lustre/quota/lquota_lib.c b/lustre/quota/lquota_lib.c index e89da00..382f94d 100644 --- a/lustre/quota/lquota_lib.c +++ b/lustre/quota/lquota_lib.c @@ -61,6 +61,8 @@ static inline __u32 qtype2acct_oid(int qtype) return ACCT_USER_OID; case GRPQUOTA: return ACCT_GROUP_OID; + case PRJQUOTA: + return ACCT_PROJECT_OID; } return ACCT_GROUP_OID; @@ -250,6 +252,8 @@ static inline __u8 qtype2lqtype(int qtype) return LQUOTA_TYPE_USR; case GRPQUOTA: return LQUOTA_TYPE_GRP; + case PRJQUOTA: + return LQUOTA_TYPE_PRJ; } return LQUOTA_TYPE_GRP; @@ -262,6 +266,8 @@ static inline int lqtype2qtype(int lqtype) return USRQUOTA; case LQUOTA_TYPE_GRP: return GRPQUOTA; + case LQUOTA_TYPE_PRJ: + return PRJQUOTA; } return GRPQUOTA; diff --git a/lustre/quota/qsd_lib.c b/lustre/quota/qsd_lib.c index e1749b6..1bf6533 100644 --- a/lustre/quota/qsd_lib.c +++ b/lustre/quota/qsd_lib.c @@ -350,6 +350,8 @@ static const char *qtype2acct_name(int qtype) return "acct_user"; case GRPQUOTA: return "acct_group"; + case PRJQUOTA: + return "acct_project"; } LASSERTF(0, "invalid quota type: %d", qtype); @@ -363,6 +365,8 @@ static const char *qtype2glb_name(int qtype) return "limit_user"; case GRPQUOTA: return "limit_group"; + case PRJQUOTA: + return "limit_project"; } LASSERTF(0, "invalid quota type: %d", qtype);