])
]) # LC_BLKDEV_RELEASE_RETURN_INT
+AC_DEFUN([LC_HAVE_PROJECT_QUOTA], [
+LB_CHECK_COMPILE([if get_projid exists],
+get_projid, [
+ #include <linux/quota.h>
+],[
+ 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
#
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
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 */
#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 */
#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 | \
* 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
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
};
return "usr";
case GRPQUOTA:
return "grp";
+ case PRJQUOTA:
+ return "project";
}
return "unknown";
}
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,
switch (fid_oid(fid)) {
case ACCT_USER_OID:
case ACCT_GROUP_OID:
+ case ACCT_PROJECT_OID:
return 1;
default:
return 0;
#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 || \
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);
}
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;
return OBD_MD_FLUSRQUOTA;
case GRPQUOTA:
return OBD_MD_FLGRPQUOTA;
+ case PRJQUOTA:
+ return OBD_MD_FLPRJQUOTA;
default:
return 0;
}
return OBD_FL_NO_USRQUOTA;
case GRPQUOTA:
return OBD_FL_NO_GRPQUOTA;
+ case PRJQUOTA:
+ return OBD_FL_NO_PRJQUOTA;
default:
return 0;
}
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++) {
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);
}
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));
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));
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);
{ .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 }
};
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,
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 {
return "usr_accounting";
case ACCT_GROUP_OID:
return "grp_accounting";
+ case ACCT_PROJECT_OID:
+ return "prj_accounting";
+ break;
default:
return "unknown_accounting";
}
return "usr";
case GRPQUOTA:
return "grp";
+ case PRJQUOTA:
+ return "prj";
+ break;
}
return "unknown";
}
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,
};
return LQUOTA_USR_OID;
case GRPQUOTA:
return LQUOTA_GRP_OID;
+ case PRJQUOTA:
+ return LQUOTA_PRJ_OID;
}
LASSERTF(0, "invalid quota type: %d", 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);
return ACCT_USER_OID;
case GRPQUOTA:
return ACCT_GROUP_OID;
+ case PRJQUOTA:
+ return ACCT_PROJECT_OID;
}
return ACCT_GROUP_OID;
return LQUOTA_TYPE_USR;
case GRPQUOTA:
return LQUOTA_TYPE_GRP;
+ case PRJQUOTA:
+ return LQUOTA_TYPE_PRJ;
}
return LQUOTA_TYPE_GRP;
return USRQUOTA;
case LQUOTA_TYPE_GRP:
return GRPQUOTA;
+ case LQUOTA_TYPE_PRJ:
+ return PRJQUOTA;
}
return GRPQUOTA;
return "acct_user";
case GRPQUOTA:
return "acct_group";
+ case PRJQUOTA:
+ return "acct_project";
}
LASSERTF(0, "invalid quota type: %d", qtype);
return "limit_user";
case GRPQUOTA:
return "limit_group";
+ case PRJQUOTA:
+ return "limit_project";
}
LASSERTF(0, "invalid quota type: %d", qtype);