static int hf_lustre_mdt_rec_setattr_sa_attr_flags = -1;
static int hf_lustre_mdt_rec_setattr_sa_mode = -1;
static int hf_lustre_mdt_rec_setattr_sa_padding_2 = -1;
-static int hf_lustre_mdt_rec_setattr_sa_padding_3 = -1;
+static int hf_lustre_mdt_rec_setattr_sa_projid = -1;
static int hf_lustre_mdt_rec_setattr_sa_padding_4 = -1;
static int hf_lustre_mdt_rec_setattr_sa_padding_5 = -1;
/* IDL: uint32 sa_attr_flags; */
/* IDL: uint32 sa_mode; */
/* IDL: uint32 sa_padding_2; */
-/* IDL: uint32 sa_padding_3; */
+/* IDL: uint32 sa_projid; */
/* IDL: uint32 sa_padding_4; */
/* IDL: uint32 sa_padding_5; */
/* IDL: } */
}
static int
-lustre_dissect_element_mdt_rec_setattr_sa_padding_3(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_)
+lustre_dissect_element_mdt_rec_setattr_sa_projid(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_)
{
- offset=dissect_uint32(tvb, offset, pinfo, tree, hf_lustre_mdt_rec_setattr_sa_padding_3);
+ offset=dissect_uint32(tvb, offset, pinfo, tree, hf_lustre_mdt_rec_setattr_sa_projid);
return offset;
}
offset=lustre_dissect_element_mdt_rec_setattr_sa_padding_2(tvb, offset, pinfo, tree);
- offset=lustre_dissect_element_mdt_rec_setattr_sa_padding_3(tvb, offset, pinfo, tree);
+ offset=lustre_dissect_element_mdt_rec_setattr_sa_projid(tvb, offset, pinfo, tree);
offset=lustre_dissect_element_mdt_rec_setattr_sa_padding_4(tvb, offset, pinfo, tree);
{ "Sa Mode", "lustre.mdt_rec_setattr.sa_mode", FT_UINT32, BASE_OCT, NULL, 0, "", HFILL }},
{ &hf_lustre_mdt_rec_setattr_sa_padding_2,
{ "Sa Padding 2", "lustre.mdt_rec_setattr.sa_padding_2", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
- { &hf_lustre_mdt_rec_setattr_sa_padding_3,
- { "Sa Padding 3", "lustre.mdt_rec_setattr.sa_padding_3", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
+ { &hf_lustre_mdt_rec_setattr_sa_projid,
+ { "Sa Padding 3", "lustre.mdt_rec_setattr.sa_projid", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_lustre_mdt_rec_setattr_sa_padding_4,
{ "Sa Padding 4", "lustre.mdt_rec_setattr.sa_padding_4", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_lustre_mdt_rec_setattr_sa_padding_5,
/* nlink of the directory */
__u64 cat_nlink;
+
+ /* Project identifier for quota purpose. */
+ __u32 cat_projid;
};
/**
CAT_CTIME = 1 << 5,
CAT_BLOCKS = 1 << 6,
CAT_UID = 1 << 7,
- CAT_GID = 1 << 8
+ CAT_GID = 1 << 8,
+ CAT_PROJID = 1 << 9
};
/**
__u32 sa_attr_flags;
__u32 sa_mode;
__u32 sa_bias; /* some operation flags */
- __u32 sa_padding_3;
+ __u32 sa_projid;
__u32 sa_padding_4;
__u32 sa_padding_5;
};
* Should be removed as soon as system header is updated.
*/
#undef LL_MAXQUOTAS
-#define LL_MAXQUOTAS 2
+#define LL_MAXQUOTAS 3
#undef INITQFNAMES
#define INITQFNAMES { \
"user", /* USRQUOTA */ \
#define LL_IOC_GETPARENT _IOWR('f', 249, struct getparent)
#define LL_IOC_LADVISE _IOR('f', 250, struct llapi_lu_ladvise)
+#ifdef FS_IOC_FSGETXATTR
+#define LL_IOC_FSGETXATTR FS_IOC_FSGETXATTR
+#define LL_IOC_FSSETXATTR FS_IOC_FSSETXATTR
+#else
+/*
+ * Structure for FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR.
+*/
+struct fsxattr {
+ __u32 fsx_xflags; /* xflags field value (get/set) */
+ __u32 fsx_extsize; /* extsize field value (get/set)*/
+ __u32 fsx_nextents; /* nextents field value (get) */
+ __u32 fsx_projid; /* project identifier (get/set) */
+ unsigned char fsx_pad[12];
+};
+#define LL_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
+#define LL_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
+#endif
+
+
/* Lease types for use as arg and return of LL_IOC_{GET,SET}_LEASE ioctl. */
enum ll_lease_type {
LL_LEASE_RDLCK = 0x1,
#include <lustre/lustre_user.h>
#ifndef LL_MAXQUOTAS
-#define LL_MAXQUOTAS 2
+#define LL_MAXQUOTAS 3
#endif
extern bool liblustreapi_initialized;
#endif
#ifndef LL_MAXQUOTAS
-#define LL_MAXQUOTAS 2
+#define LL_MAXQUOTAS 3
#endif
struct lquota_id_info;
/* default stripe offset */
__u32 op_default_stripe_offset;
+ __u32 op_projid;
};
struct md_callback {
RETURN(rc);
}
+ case LL_IOC_FSGETXATTR:
+ case LL_IOC_FSSETXATTR:
+ RETURN(ll_ioctl_projid(inode, cmd, arg));
default:
RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp, 0, NULL,
(void __user *)arg));
RETURN(rc);
}
+int ll_ioctl_projid(struct inode *inode, unsigned int cmd,
+ unsigned long arg)
+{
+ int rc = 0;
+ struct fsxattr *fsxattr;
+ int alloc_size = sizeof(*fsxattr);
+
+ switch (cmd) {
+ case LL_IOC_FSGETXATTR: {
+ OBD_ALLOC_PTR(fsxattr);
+ if (fsxattr == NULL)
+ RETURN(-ENOMEM);
+
+ if (copy_from_user(fsxattr,
+ (const struct fsxattr __user *)arg,
+ alloc_size))
+ GOTO(out_fsxattr, rc = -EFAULT);
+
+ fsxattr->fsx_projid = ll_i2info(inode)->lli_projid;
+ if (copy_to_user((struct fsxattr __user *)arg,
+ fsxattr, alloc_size))
+ GOTO(out_fsxattr, rc = -EFAULT);
+out_fsxattr:
+ OBD_FREE(fsxattr, alloc_size);
+ RETURN(rc);
+ }
+
+ case LL_IOC_FSSETXATTR: {
+ struct md_op_data *op_data;
+ struct ptlrpc_request *req = NULL;
+
+ /* only root could change project ID */
+ if (!cfs_capable(CFS_CAP_SYS_ADMIN))
+ RETURN(-EPERM);
+
+ op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+ LUSTRE_OPC_ANY, NULL);
+ if (IS_ERR(op_data))
+ RETURN(PTR_ERR(op_data));
+
+ OBD_ALLOC_PTR(fsxattr);
+ if (fsxattr == NULL)
+ GOTO(out_fsxattr1, rc = -ENOMEM);
+
+ if (copy_from_user(fsxattr,
+ (const struct fsxattr __user *)arg,
+ alloc_size))
+ GOTO(out_fsxattr1, rc = -EFAULT);
+
+ op_data->op_projid = fsxattr->fsx_projid;
+ op_data->op_attr.ia_valid |= MDS_ATTR_PROJID;
+ rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data, NULL,
+ 0, &req);
+ ptlrpc_req_finished(req);
+
+out_fsxattr1:
+ ll_finish_md_op_data(op_data);
+ OBD_FREE(fsxattr, alloc_size);
+ RETURN(rc);
+ }
+ default:
+ LASSERT(0);
+ }
+
+ RETURN(rc);
+}
+
static long
ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
OBD_FREE(ladvise_hdr, alloc_size);
RETURN(rc);
}
+ case LL_IOC_FSGETXATTR:
+ case LL_IOC_FSSETXATTR:
+ RETURN(ll_ioctl_projid(inode, cmd, arg));
default: {
int err;
int ll_inode_permission(struct inode *inode, int mask);
# endif
#endif
+int ll_ioctl_projid(struct inode *inode, unsigned int cmd,
+ unsigned long arg);
int ll_lov_setstripe_ea_info(struct inode *inode, struct file *file,
__u64 flags, struct lov_user_md *lum,
!(attr->ia_valid & ATTR_KILL_SGID))
attr->ia_valid |= ATTR_KILL_SGID;
+ /* avoid polluted from ATTR_TIMES_SET, projid is not
+ * expected to be setted here */
+ if (attr->ia_valid & MDS_ATTR_PROJID)
+ attr->ia_valid &= ~MDS_ATTR_PROJID;
+
return ll_setattr_raw(de, attr, false);
}
attr->cat_blocks = inode->i_blocks;
attr->cat_uid = from_kuid(&init_user_ns, inode->i_uid);
attr->cat_gid = from_kgid(&init_user_ns, inode->i_gid);
+ attr->cat_projid = ll_i2info(inode)->lli_projid;
/* KMS is not known by this layer */
return 0; /* layers below have to fill in the rest */
}
inode->i_ctime.tv_sec = attr->cat_ctime;
if (0 && valid & CAT_SIZE)
i_size_write(inode, attr->cat_size);
+ if (valid & CAT_PROJID)
+ ll_i2info(inode)->lli_projid = attr->cat_projid;
/* not currently necessary */
- if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE))
+ if (0 && valid & (CAT_UID|CAT_GID|CAT_SIZE|CAT_PROJID))
mark_inode_dirty(inode);
return 0;
}
if (ia_valid & MDS_OPEN_OWNEROVERRIDE)
/* NFSD hack (see bug 5781) */
sa_valid |= MDS_OPEN_OWNEROVERRIDE;
+ if (ia_valid & MDS_ATTR_PROJID)
+ sa_valid |= MDS_ATTR_PROJID;
return sa_valid;
}
rec->sa_mode = op_data->op_attr.ia_mode;
rec->sa_uid = from_kuid(&init_user_ns, op_data->op_attr.ia_uid);
rec->sa_gid = from_kgid(&init_user_ns, op_data->op_attr.ia_gid);
+ rec->sa_projid = op_data->op_projid;
rec->sa_size = op_data->op_attr.ia_size;
rec->sa_blocks = op_data->op_attr_blocks;
rec->sa_atime = LTIME_S(op_data->op_attr.ia_atime);
NODEMAP_CLIENT_TO_FS, rec->sa_uid);
la->la_gid = nodemap_map_id(nodemap, NODEMAP_GID,
NODEMAP_CLIENT_TO_FS, rec->sa_gid);
+ la->la_projid = rec->sa_projid;
nodemap_putref(nodemap);
la->la_size = rec->sa_size;
qid[USRQUOTA] = attr->cat_uid;
qid[GRPQUOTA] = attr->cat_gid;
+ qid[PRJQUOTA] = attr->cat_projid;
if (rc == 0 && osc_quota_chkdq(cli, qid) == NO_QUOTA)
rc = -EDQUOT;
if (rc)
RETURN(-EPROTO);
}
- /* set/clear over quota flag for a uid/gid */
+ /* set/clear over quota flag for a uid/gid/projid */
if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE &&
body->oa.o_valid & (OBD_MD_FLALLQUOTA)) {
unsigned qid[LL_MAXQUOTAS] =
- {body->oa.o_uid, body->oa.o_gid};
+ { body->oa.o_uid, body->oa.o_gid,
+ body->oa.o_projid };
- CDEBUG(D_QUOTA, "setdq for [%u %u] with valid %#llx, flags %x\n",
- body->oa.o_uid, body->oa.o_gid, body->oa.o_valid,
- body->oa.o_flags);
+ CDEBUG(D_QUOTA, "setdq for [%u %u %u] with valid %#llx, flags %x\n",
+ body->oa.o_uid, body->oa.o_gid, body->oa.o_projid,
+ body->oa.o_valid, body->oa.o_flags);
osc_quota_setdq(cli, qid, body->oa.o_valid, body->oa.o_flags);
}
qi->lqi_id.qid_uid = gid;
qsd_op_adjust(env, qsd, &qi->lqi_id, GRPQUOTA);
+
+ qi->lqi_id.qid_uid = i_projid_read(inode);
+ qsd_op_adjust(env, qsd, &qi->lqi_id, PRJQUOTA);
}
}
}
}
LINVRNT(osd_invariant(obj));
- if (result == 0 && feat == &dt_quota_glb_features &&
- fid_seq(lu_object_fid(&dt->do_lu)) == FID_SEQ_QUOTA_GLB)
- result = osd_quota_migration(env, dt);
-
return result;
}
const struct dt_rec *rec,
union lquota_rec *quota_rec);
void osd_quota_unpack(struct osd_object *obj, const struct dt_rec *rec);
-int osd_quota_migration(const struct lu_env *env, struct dt_object *dt);
#ifndef HAVE_I_UID_READ
static inline uid_t i_uid_read(const struct inode *inode)
/* and now project quota */
qi->lqi_id.qid_gid = projid;
- qi->lqi_type = PRJQUOTA; /* false now */
- rcp = osd_declare_qid(env, oh, qi, obj, false, flags);
+ qi->lqi_type = PRJQUOTA;
+ rcp = osd_declare_qid(env, oh, qi, obj, true, flags);
if (force && (rcp == -EDQUOT || rcp == -EINPROGRESS))
/* as before, ignore EDQUOT & EINPROGRESS for root */
RETURN(0);
}
-
-int osd_quota_migration(const struct lu_env *env, struct dt_object *dt)
-{
- struct osd_thread_info *oti = osd_oti_get(env);
- struct osd_device *osd = osd_obj2dev(osd_dt_obj(dt));
- struct dt_object *root, *parent = NULL, *admin = NULL;
- dt_obj_version_t version;
- char *fname, *fnames[] = {ADMIN_USR, ADMIN_GRP};
- int rc, i;
- ENTRY;
-
- /* not newly created global index */
- version = dt_version_get(env, dt);
- if (version != 0)
- RETURN(0);
-
- /* locate root */
- rc = dt_root_get(env, &osd->od_dt_dev, &oti->oti_fid);
- if (rc) {
- CERROR("%s: Can't get root FID, rc:%d\n", osd->od_svname, rc);
- RETURN(rc);
- }
-
- root = dt_locate(env, &osd->od_dt_dev, &oti->oti_fid);
- if (IS_ERR(root)) {
- CERROR("%s: Failed to locate root "DFID", rc:%ld\n",
- osd->od_svname, PFID(&oti->oti_fid), PTR_ERR(root));
- RETURN(PTR_ERR(root));
- }
-
- /* locate /OBJECTS */
- rc = dt_lookup_dir(env, root, OBJECTS, &oti->oti_fid);
- if (rc == -ENOENT) {
- GOTO(out, rc = 0);
- } else if (rc) {
- CERROR("%s: Failed to lookup %s, rc:%d\n",
- osd->od_svname, OBJECTS, rc);
- GOTO(out, rc);
- }
-
- parent = dt_locate(env, &osd->od_dt_dev, &oti->oti_fid);
- if (IS_ERR(parent)) {
- CERROR("%s: Failed to locate %s "DFID", rc:%ld\n",
- osd->od_svname, OBJECTS, PFID(&oti->oti_fid),
- PTR_ERR(parent));
- GOTO(out, rc = PTR_ERR(parent));
- }
-
- /* locate quota admin files */
- for (i = 0; i < 2; i++) {
- fname = fnames[i];
- rc = dt_lookup_dir(env, parent, fname, &oti->oti_fid);
- if (rc == -ENOENT) {
- rc = 0;
- continue;
- } else if (rc) {
- CERROR("%s: Failed to lookup %s, rc:%d\n",
- osd->od_svname, fname, rc);
- GOTO(out, rc);
- }
-
- admin = dt_locate(env, &osd->od_dt_dev, &oti->oti_fid);
- if (IS_ERR(admin)) {
- CERROR("%s: Failed to locate %s "DFID", rc:%d\n",
- osd->od_svname, fname, PFID(&oti->oti_fid), rc);
- GOTO(out, rc = PTR_ERR(admin));
- }
-
- if (!dt_object_exists(admin)) {
- CERROR("%s: Old admin file %s doesn't exist, but is "
- "still referenced in parent directory.\n",
- osd->od_svname, fname);
- dt_object_put(env, admin);
- GOTO(out, rc = -ENOENT);
- }
-
- LCONSOLE_WARN("%s: Detected old quota admin file(%s)! If you "
- "want to keep the old quota limits settings, "
- "please upgrade to lower version(2.5) first to "
- "convert them into new format.\n",
- osd->od_svname, fname);
-
- dt_object_put(env, admin);
- GOTO(out, rc = -EINVAL);
- }
-out:
- if (parent && !IS_ERR(parent))
- dt_object_put(env, parent);
- dt_object_put(env, root);
- RETURN(rc);
-}
la->la_valid |= LA_GID;
}
if (attr->la_valid & LA_PROJID) {
- la->la_gid = attr->la_projid;
+ la->la_projid = attr->la_projid;
la->la_valid |= LA_PROJID;
}
spin_unlock(&o->opo_lock);
(long long)(int)offsetof(struct mdt_rec_setattr, sa_bias));
LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias) == 4, "found %lld\n",
(long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias));
- LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_3) == 124, "found %lld\n",
- (long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_3));
- LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3));
+ LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_projid) == 124, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_rec_setattr, sa_projid));
+ LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid));
LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_4) == 128, "found %lld\n",
(long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_4));
LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_4) == 4, "found %lld\n",
read_unlock(&qsd->qsd_lock);
if (skip)
continue;
- if (qsd->qsd_acct_failed) {
- LCONSOLE_ERROR("%s: can't enable quota "
- "enforcement since space "
- "accounting isn't functional. "
- "Please run tunefs.lustre "
- "--quota on an unmounted "
- "filesystem if not done already"
- "\n", qsd->qsd_svname);
- continue;
- }
for (type = USRQUOTA; type < LL_MAXQUOTAS; type++) {
qqi = qsd->qsd_type_array[type];
+ if (qqi->qqi_acct_failed) {
+ LCONSOLE_ERROR("%s: can't enable quota "
+ "enforcement since space "
+ "accounting isn't functional. "
+ "Please run tunefs.lustre "
+ "--quota on an unmounted "
+ "filesystem if not done already"
+ "\n", qsd->qsd_svname);
+ continue;
+ }
qsd_start_reint_thread(qqi);
}
}
* or - the user/group is root
* or - quota accounting isn't enabled */
if (!qsd_type_enabled(qsd, qi->lqi_type) || qi->lqi_id.qid_uid == 0 ||
- qsd->qsd_acct_failed)
+ (qsd->qsd_type_array[qi->lqi_type])->qqi_acct_failed)
RETURN(0);
LASSERTF(trans->lqt_id_cnt <= QUOTA_MAX_TRANSIDS, "id_cnt=%d\n",
* enforced here (via procfs) */
int qsd_timeout;
- unsigned long qsd_is_md:1, /* managing quota for mdt */
- qsd_started:1, /* instance is now started */
- qsd_prepared:1, /* qsd_prepare() successfully
+ unsigned long qsd_is_md:1, /* managing quota for mdt */
+ qsd_started:1, /* instance is now started */
+ qsd_prepared:1, /* qsd_prepare() successfully
* called */
- qsd_exp_valid:1,/* qsd_exp is now valid */
- qsd_stopping:1, /* qsd_instance is stopping */
- qsd_acct_failed:1; /* failed to set up acct
- * for one quota type */
+ qsd_exp_valid:1,/* qsd_exp is now valid */
+ qsd_stopping:1; /* qsd_instance is stopping */
+
};
/*
/* Various flags representing the current state of the slave for this
* quota type. */
- unsigned long qqi_glb_uptodate:1, /* global index uptodate
+ unsigned long qqi_glb_uptodate:1, /* global index uptodate
with master */
- qqi_slv_uptodate:1, /* slave index uptodate
+ qqi_slv_uptodate:1, /* slave index uptodate
with master */
- qqi_reint:1; /* in reintegration or not */
+ qqi_reint:1, /* in reintegration or not */
+ qqi_acct_failed:1; /* failed to setup acct */
/* A list of references to this instance, for debugging */
struct lu_ref qqi_reference;
qsd->qsd_svname, qtype_name(qtype),
PTR_ERR(qqi->qqi_acct_obj));
qqi->qqi_acct_obj = NULL;
- qsd->qsd_acct_failed = true;
+ qqi->qqi_acct_failed = true;
}
/* open global index copy */
for (qtype = USRQUOTA; qtype < LL_MAXQUOTAS; qtype++) {
struct qsd_qtype_info *qqi = qsd->qsd_type_array[qtype];
- if (qsd_type_enabled(qsd, qtype) && qsd->qsd_acct_failed) {
+ if (qsd_type_enabled(qsd, qtype) &&
+ qqi->qqi_acct_failed) {
LCONSOLE_ERROR("%s: can't enable quota enforcement "
"since space accounting isn't functional"
". Please run tunefs.lustre --quota on "
if (!qsd_type_enabled(qsd, qqi->qqi_qtype))
RETURN(0);
- if (qsd->qsd_acct_failed)
+ if (qqi->qqi_acct_failed)
/* no space accounting support, can't enable enforcement */
RETURN(0);
job_pending = true;
}
- if (qsd->qsd_acct_failed) {
- /* don't bother kicking off reintegration if space accounting
- * failed to be enabled */
- write_unlock(&qsd->qsd_lock);
- return job_pending;
- }
-
for (qtype = USRQUOTA; qtype < LL_MAXQUOTAS; qtype++) {
struct qsd_qtype_info *qqi = qsd->qsd_type_array[qtype];
+ /* don't bother kicking off reintegration if space accounting
+ * failed to be enabled */
+ if (qqi->qqi_acct_failed)
+ continue;
+
if (!qsd_type_enabled(qsd, qtype))
continue;
return 0
}
+enable_project_quota() {
+ stopall || error "failed to stopall (1)"
+
+ for num in $(seq $MDSCOUNT); do
+ do_facet mds$num $TUNE2FS -O project $(mdsdevname $num) ||
+ error "tune2fs $(mdsdevname $num) failed"
+ done
+
+ for i in $(seq $OSTCOUNT); do
+ do_facet ost$num $TUNE2FS -O project $(ostdevname $num) ||
+ error "tune2fs $(ostdevname $num) failed"
+ done
+
+ mount
+ setupall
+}
+
+disable_project_quota() {
+ stopall || error "failed to stopall (1)"
+
+ for num in $(seq $MDSCOUNT); do
+ do_facet mds$num $TUNE2FS -Q ^prj $(mdsdevname $num) ||
+ error "tune2fs $(mdsdevname $num) failed"
+ done
+
+ for i in $(seq $OSTCOUNT); do
+ do_facet ost$num $TUNE2FS -Q ^prj $(ostdevname $num) ||
+ error "tune2fs $(ostdevname $num) failed"
+ done
+
+ mount
+ setupall
+}
+
setup_quota_test() {
wait_delete_completed
echo "Creating test directory"
}
run_test 38 "Quota accounting iterator doesn't skip id entries"
+test_39() {
+ [ "$(facet_fstype $singlemds)" != "ldiskfs" ] &&
+ skip "only for ldiskfs mdt" && return 0
+
+ [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.10) ] &&
+ skip "Old server doesn't support project quota." && return
+
+ man lsattr | grep -i project ||
+ skip "old e2fsprogs dosen't support project quota" &&
+ return 0
+
+ enable_project_quota
+
+ local TESTFILE="$DIR/project"
+ touch $TESTFILE
+ projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
+ [ $projectid -ne 0 ] &&
+ error "Project id should be 0 not $projectid"
+ chattr -p 1024 $TESTFILE
+ projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
+ [ $projectid -ne 1024 ] &&
+ error "Project id should be 1024 not $projectid"
+
+ stopall || error "failed to stopall (1)"
+ mount
+ setupall
+ projectid=$(lsattr -p $TESTFILE | awk '{print $1}')
+ [ $projectid -ne 1024 ] &&
+ error "Project id should be 1024 not $projectid"
+
+ disable_project_quota
+ cleanup_quota_test
+}
+run_test 39 "Project ID interface works correctly"
+
quota_fini()
{
do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"
CHECK_MEMBER(mdt_rec_setattr, sa_attr_flags);
CHECK_MEMBER(mdt_rec_setattr, sa_mode);
CHECK_MEMBER(mdt_rec_setattr, sa_bias);
- CHECK_MEMBER(mdt_rec_setattr, sa_padding_3);
+ CHECK_MEMBER(mdt_rec_setattr, sa_projid);
CHECK_MEMBER(mdt_rec_setattr, sa_padding_4);
CHECK_MEMBER(mdt_rec_setattr, sa_padding_5);
}
(long long)(int)offsetof(struct mdt_rec_setattr, sa_bias));
LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias) == 4, "found %lld\n",
(long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_bias));
- LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_3) == 124, "found %lld\n",
- (long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_3));
- LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3) == 4, "found %lld\n",
- (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_3));
+ LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_projid) == 124, "found %lld\n",
+ (long long)(int)offsetof(struct mdt_rec_setattr, sa_projid));
+ LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct mdt_rec_setattr *)0)->sa_projid));
LASSERTF((int)offsetof(struct mdt_rec_setattr, sa_padding_4) == 128, "found %lld\n",
(long long)(int)offsetof(struct mdt_rec_setattr, sa_padding_4));
LASSERTF((int)sizeof(((struct mdt_rec_setattr *)0)->sa_padding_4) == 4, "found %lld\n",