From: Wang Shilong Date: Mon, 27 Mar 2017 05:43:30 +0000 (+0800) Subject: LU-4017 quota: add setting/getting project id function X-Git-Tag: 2.9.56~38 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=39f63cf54c624d89439b5b473035c1afe35e10fa LU-4017 quota: add setting/getting project id function Extend Attr RPC to support project ID attribute, new ioctl is introduced to get/set project id, it is kept same ioctl number as VFS, you could use: lsattr -p chattr -p Redefine LL_MAXQUOTAS as 3, change @qsd_acct_failed into qqi, otherwise osd-zfs could not use USR/GRP quota normally. Remove osd_quota_migration(), it only output some messages in case upgrading from 1.8 which give us extra efforts for project quota, remove it indead. also fix a typo bug in osp_attr_set(). Change-Id: I4b537be9efa29fda730592b6d5e41c6b60fb6c0d Signed-off-by: Wang Shilong Reviewed-on: https://review.whamcloud.com/26202 Reviewed-by: Oleg Drokin Tested-by: Oleg Drokin --- diff --git a/lustre/contrib/wireshark/packet-lustre.c b/lustre/contrib/wireshark/packet-lustre.c index bfd2b6c..65ca314 100644 --- a/lustre/contrib/wireshark/packet-lustre.c +++ b/lustre/contrib/wireshark/packet-lustre.c @@ -549,7 +549,7 @@ static int hf_lustre_mdt_rec_setattr_sa_ctime = -1; 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; @@ -3198,7 +3198,7 @@ lustre_dissect_struct_mdt_body(tvbuff_t *tvb _U_, int offset _U_, /* 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: } */ @@ -3393,9 +3393,9 @@ lustre_dissect_element_mdt_rec_setattr_sa_padding_2(tvbuff_t *tvb _U_, int offse } 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; } @@ -3479,7 +3479,7 @@ lustre_dissect_struct_mdt_rec_setattr(tvbuff_t *tvb _U_, int offset _U_, packet_ 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); @@ -9909,8 +9909,8 @@ void proto_register_dcerpc_lustre(void) { "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, diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 655e6b1..dba3ef3 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -166,6 +166,9 @@ struct cl_attr { /* nlink of the directory */ __u64 cat_nlink; + + /* Project identifier for quota purpose. */ + __u32 cat_projid; }; /** @@ -179,7 +182,8 @@ enum cl_attr_valid { CAT_CTIME = 1 << 5, CAT_BLOCKS = 1 << 6, CAT_UID = 1 << 7, - CAT_GID = 1 << 8 + CAT_GID = 1 << 8, + CAT_PROJID = 1 << 9 }; /** diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 12a9251..3afa428 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1744,7 +1744,7 @@ struct mdt_rec_setattr { __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; }; diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 71d5814..eb90190 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -65,7 +65,7 @@ * 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 */ \ @@ -362,6 +362,25 @@ struct ll_futimes_3 { #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, diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index e8d895a..886409d 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -43,7 +43,7 @@ #include #ifndef LL_MAXQUOTAS -#define LL_MAXQUOTAS 2 +#define LL_MAXQUOTAS 3 #endif extern bool liblustreapi_initialized; diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h index 1a2f2a3..ab28b24 100644 --- a/lustre/include/lustre_quota.h +++ b/lustre/include/lustre_quota.h @@ -48,7 +48,7 @@ #endif #ifndef LL_MAXQUOTAS -#define LL_MAXQUOTAS 2 +#define LL_MAXQUOTAS 3 #endif struct lquota_id_info; diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 868a7aa..afeaed8 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -836,6 +836,7 @@ struct md_op_data { /* default stripe offset */ __u32 op_default_stripe_offset; + __u32 op_projid; }; struct md_callback { diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index c6a59cd..578e610 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -1756,6 +1756,9 @@ migrate_free: 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)); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 68ac435..180f288 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -2338,6 +2338,73 @@ static int ll_ladvise(struct inode *inode, struct file *file, __u64 flags, 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) { @@ -2733,6 +2800,9 @@ out_ladvise: 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; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 8aac073..c8432b1 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -816,6 +816,8 @@ int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd); 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, diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 5cb81f9..bbf5c3e 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1675,6 +1675,11 @@ int ll_setattr(struct dentry *de, struct iattr *attr) !(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); } diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index cc3ea89..8904e45 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -100,6 +100,7 @@ static int vvp_attr_get(const struct lu_env *env, struct cl_object *obj, 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 */ } @@ -121,8 +122,10 @@ static int vvp_attr_update(const struct lu_env *env, struct cl_object *obj, 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; } diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 3ab2029..5c2acf8 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -318,6 +318,8 @@ static inline __u64 attr_pack(unsigned int ia_valid) { 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; } @@ -335,6 +337,7 @@ static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec, 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); diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 95f16d8..965d73e 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -928,6 +928,7 @@ static int mdt_setattr_unpack_rec(struct mdt_thread_info *info) 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; diff --git a/lustre/osc/osc_cache.c b/lustre/osc/osc_cache.c index c417c10..96d13ca 100644 --- a/lustre/osc/osc_cache.c +++ b/lustre/osc/osc_cache.c @@ -2420,6 +2420,7 @@ int osc_queue_async_io(const struct lu_env *env, struct cl_io *io, 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) diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 114b6ce..d2086a1 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1384,15 +1384,16 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int 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); } diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 1bb8fa3..2af1a52 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -1955,6 +1955,9 @@ static void osd_object_delete(const struct lu_env *env, struct lu_object *l) 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); } } } @@ -4352,10 +4355,6 @@ static int osd_index_try(const struct lu_env *env, struct dt_object *dt, } 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; } diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index eb7a72e..c495687 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -750,7 +750,6 @@ const struct dt_rec *osd_quota_pack(struct osd_object *obj, 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) diff --git a/lustre/osd-ldiskfs/osd_quota.c b/lustre/osd-ldiskfs/osd_quota.c index 4f62122..90e8ad6 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -661,8 +661,8 @@ int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid, /* 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 */ @@ -677,94 +677,3 @@ int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid, 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); -} diff --git a/lustre/osp/osp_object.c b/lustre/osp/osp_object.c index 2145285..fc823e3 100644 --- a/lustre/osp/osp_object.c +++ b/lustre/osp/osp_object.c @@ -681,7 +681,7 @@ static int osp_attr_set(const struct lu_env *env, struct dt_object *dt, 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); diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 55fda60..00058a9 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -2445,10 +2445,10 @@ void lustre_assert_wire_constants(void) (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", diff --git a/lustre/quota/qsd_config.c b/lustre/quota/qsd_config.c index 06e566e..4fc3a4d 100644 --- a/lustre/quota/qsd_config.c +++ b/lustre/quota/qsd_config.c @@ -187,19 +187,19 @@ int qsd_process_config(struct lustre_cfg *lcfg) 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); } } diff --git a/lustre/quota/qsd_handler.c b/lustre/quota/qsd_handler.c index b38a111..e2fdd35 100644 --- a/lustre/quota/qsd_handler.c +++ b/lustre/quota/qsd_handler.c @@ -856,7 +856,7 @@ int qsd_op_begin(const struct lu_env *env, struct qsd_instance *qsd, * 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", diff --git a/lustre/quota/qsd_internal.h b/lustre/quota/qsd_internal.h index 9b1d6b2..488602c 100644 --- a/lustre/quota/qsd_internal.h +++ b/lustre/quota/qsd_internal.h @@ -107,14 +107,13 @@ struct qsd_instance { * 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 */ + }; /* @@ -169,11 +168,12 @@ struct qsd_qtype_info { /* 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; diff --git a/lustre/quota/qsd_lib.c b/lustre/quota/qsd_lib.c index 1bf6533..7ab8648 100644 --- a/lustre/quota/qsd_lib.c +++ b/lustre/quota/qsd_lib.c @@ -426,7 +426,7 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, 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 */ @@ -740,7 +740,8 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) 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 " diff --git a/lustre/quota/qsd_reint.c b/lustre/quota/qsd_reint.c index b355eb8..6e805df 100644 --- a/lustre/quota/qsd_reint.c +++ b/lustre/quota/qsd_reint.c @@ -638,7 +638,7 @@ int qsd_start_reint_thread(struct qsd_qtype_info *qqi) 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); diff --git a/lustre/quota/qsd_writeback.c b/lustre/quota/qsd_writeback.c index 9b12c2c..628c661 100644 --- a/lustre/quota/qsd_writeback.c +++ b/lustre/quota/qsd_writeback.c @@ -388,16 +388,14 @@ static bool qsd_job_pending(struct qsd_instance *qsd, struct list_head *upd, 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; diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 439488d..258422d 100755 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -285,6 +285,40 @@ wait_ost_reint() { 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" @@ -2384,6 +2418,41 @@ test_38() { } 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" diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index d114d67..46b0571 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -1125,7 +1125,7 @@ check_mdt_rec_setattr(void) 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); } diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index bd26057..172d127 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -2463,10 +2463,10 @@ void lustre_assert_wire_constants(void) (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",