From 97fbb61dbe261a389897779ae376cfc3808442cf Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Sun, 9 Apr 2017 03:02:01 -0400 Subject: [PATCH] LU-4017 quota: add project id support This patch is infrastrcuture change for Lustre project quota, project ID is considered as file attribute like UID/GID, MDS will return back project id to client upon open/getattr. Extend llog_setattr64_rec_v2 to be able to store project ID, upgrade from old format could be handled properly, if you want to downgrade again, need to make sure llog have been handled completely. Change-Id: Id7d27188f22169d6cffb74ea8b792ad4b133ef1d Signed-off-by: Wang Shilong Signed-off-by: Oleg Drokin Reviewed-on: https://review.whamcloud.com/25812 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Li Xi Reviewed-by: Niu Yawei --- lustre/include/lu_object.h | 3 + lustre/include/lustre/lustre_idl.h | 34 ++++-- lustre/include/obd.h | 1 + lustre/llite/llite_internal.h | 2 + lustre/llite/llite_lib.c | 2 + lustre/llite/vvp_object.c | 4 +- lustre/lod/lod_object.c | 16 +-- lustre/mdt/mdt_handler.c | 6 ++ lustre/mdt/mdt_lib.c | 4 +- lustre/mdt/mdt_reint.c | 7 +- lustre/obdclass/linux/linux-obdo.c | 8 ++ lustre/obdclass/llog_swab.c | 11 +- lustre/obdclass/obdo.c | 7 ++ lustre/ofd/ofd_dev.c | 4 +- lustre/ofd/ofd_internal.h | 2 +- lustre/ofd/ofd_io.c | 14 +-- lustre/ofd/ofd_obd.c | 2 +- lustre/ofd/ofd_objects.c | 25 +++-- lustre/osd-ldiskfs/osd_handler.c | 205 +++++++++++++++++++------------------ lustre/osd-ldiskfs/osd_internal.h | 45 ++++++-- lustre/osd-ldiskfs/osd_io.c | 12 ++- lustre/osd-ldiskfs/osd_quota.c | 24 ++++- lustre/osp/osp_internal.h | 2 +- lustre/osp/osp_object.c | 10 +- lustre/osp/osp_sync.c | 18 +++- lustre/ptlrpc/pack_generic.c | 4 +- lustre/ptlrpc/wiretest.c | 34 ++++-- lustre/utils/obd.c | 4 +- lustre/utils/wirecheck.c | 6 +- lustre/utils/wiretest.c | 32 ++++-- 30 files changed, 363 insertions(+), 185 deletions(-) diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index 24a8f7a..7f4849f 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -422,6 +422,8 @@ struct lu_attr { __u32 la_blksize; /** real device */ __u32 la_rdev; + /** project id */ + __u32 la_projid; /** * valid bits * @@ -447,6 +449,7 @@ enum la_valid { LA_BLKSIZE = 1 << 12, LA_KILL_SUID = 1 << 13, LA_KILL_SGID = 1 << 14, + LA_PROJID = 1 << 15, }; /** diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 4394ddd..12a9251 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1200,16 +1200,18 @@ 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_FLPROJID (0x0100000000000000ULL) /* project ID */ #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 | \ - OBD_MD_FLMODE | OBD_MD_FLTYPE | OBD_MD_FLUID | \ - OBD_MD_FLGID | OBD_MD_FLFLAGS | OBD_MD_FLNLINK | \ - OBD_MD_FLGENER | OBD_MD_FLRDEV | OBD_MD_FLGROUP) + OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \ + OBD_MD_FLMODE | OBD_MD_FLTYPE | OBD_MD_FLUID | \ + OBD_MD_FLGID | OBD_MD_FLFLAGS | OBD_MD_FLNLINK | \ + OBD_MD_FLGENER | OBD_MD_FLRDEV | OBD_MD_FLGROUP | \ + OBD_MD_FLPROJID) #define OBD_MD_FLXATTRALL (OBD_MD_FLXATTR | OBD_MD_FLXATTRLS) @@ -1697,8 +1699,8 @@ struct mdt_body { __u32 mbo_unused3; /* was max_cookiesize until 2.8 */ __u32 mbo_uid_h; /* high 32-bits of uid, for FUID */ __u32 mbo_gid_h; /* high 32-bits of gid, for FUID */ - __u32 mbo_padding_5; /* also fix lustre_swab_mdt_body */ - __u64 mbo_padding_6; + __u32 mbo_projid; + __u64 mbo_padding_6; /* also fix lustre_swab_mdt_body */ __u64 mbo_padding_7; __u64 mbo_padding_8; __u64 mbo_padding_9; @@ -1769,6 +1771,7 @@ struct mdt_rec_setattr { #define MDS_ATTR_CTIME_SET 0x2000ULL /* = 8192 */ #define MDS_ATTR_FROM_OPEN 0x4000ULL /* = 16384, called from open path, ie O_TRUNC */ #define MDS_ATTR_BLOCKS 0x8000ULL /* = 32768 */ +#define MDS_ATTR_PROJID 0x10000ULL /* = 65536 */ #ifndef FMODE_READ #define FMODE_READ 00000001 @@ -2617,6 +2620,22 @@ struct llog_setattr64_rec { struct llog_rec_tail lsr_tail; } __attribute__((packed)); +/* Extended to support project quota */ +struct llog_setattr64_rec_v2 { + struct llog_rec_hdr lsr_hdr; + struct ost_id lsr_oi; + __u32 lsr_uid; + __u32 lsr_uid_h; + __u32 lsr_gid; + __u32 lsr_gid_h; + __u64 lsr_valid; + __u32 lsr_projid; + __u32 lsr_padding1; + __u64 lsr_padding2; + __u64 lsr_padding3; + struct llog_rec_tail lsr_tail; +} __attribute__((packed)); + struct llog_size_change_rec { struct llog_rec_hdr lsc_hdr; struct ll_fid lsc_fid; @@ -2858,7 +2877,8 @@ struct obdo { * each stripe. * brw: grant space consumed on * the client for the write */ - __u64 o_padding_4; + __u32 o_projid; + __u32 o_padding_4; __u64 o_padding_5; __u64 o_padding_6; }; diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 42bcb3d..868a7aa 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1127,6 +1127,7 @@ static inline struct md_open_data *obd_mod_alloc(void) void obdo_from_inode(struct obdo *dst, struct inode *src, u64 valid); void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent); +void obdo_set_o_projid(struct obdo *dst, u32 projid); /* return 1 if client should be resend request */ static inline int client_should_resend(int resend, struct client_obd *cli) diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 8426ad2..8aac073 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -227,6 +227,8 @@ struct ll_inode_info { __u32 lli_layout_gen; spinlock_t lli_layout_lock; + __u32 lli_projid; /* project id */ + struct rw_semaphore lli_xattrs_list_rwsem; struct mutex lli_xattrs_enq_lock; struct list_head lli_xattrs; /* ll_xattr_entry->xe_list */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index fe9bcdc..5cb81f9 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1857,6 +1857,8 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) inode->i_uid = make_kuid(&init_user_ns, body->mbo_uid); if (body->mbo_valid & OBD_MD_FLGID) inode->i_gid = make_kgid(&init_user_ns, body->mbo_gid); + if (body->mbo_valid & OBD_MD_FLPROJID) + lli->lli_projid = body->mbo_projid; if (body->mbo_valid & OBD_MD_FLFLAGS) inode->i_flags = ll_ext_to_inode_flags(body->mbo_flags); if (body->mbo_valid & OBD_MD_FLNLINK) diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index eeb1771..cc3ea89 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -200,9 +200,11 @@ static void vvp_req_attr_set(const struct lu_env *env, struct cl_object *obj, oa = attr->cra_oa; inode = vvp_object_inode(obj); - if (attr->cra_type == CRT_WRITE) + if (attr->cra_type == CRT_WRITE) { valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLUID | OBD_MD_FLGID; + obdo_set_o_projid(oa, ll_i2info(inode)->lli_projid); + } obdo_from_inode(oa, inode, valid_flags & attr->cra_flags); obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid); if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_INVALID_PFID)) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index b955a44..06656be 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -1131,20 +1131,20 @@ static int lod_declare_attr_set(const struct lu_env *env, RETURN(rc); /* osp_declare_attr_set() ignores all attributes other than - * UID, GID, and size, and osp_attr_set() ignores all but UID - * and GID. Declaration of size attr setting happens through - * lod_declare_init_size(), and not through this function. + * UID, GID, PID, and size, and osp_attr_set() ignores all but + * UID, GID and PID. Declaration of size attr setting happens + * through lod_declare_init_size(), and not through this function. * Therefore we need not load striping unless ownership is * changing. This should save memory and (we hope) speed up * rename(). */ if (!S_ISDIR(dt->do_lu.lo_header->loh_attr)) { - if (!(attr->la_valid & (LA_UID | LA_GID))) + if (!(attr->la_valid & (LA_UID | LA_GID | LA_PROJID))) RETURN(rc); if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_OWNER)) RETURN(0); } else { - if (!(attr->la_valid & (LA_UID | LA_GID | LA_MODE | + if (!(attr->la_valid & (LA_UID | LA_GID | LA_PROJID | LA_MODE | LA_ATIME | LA_MTIME | LA_CTIME | LA_FLAGS))) RETURN(rc); @@ -1238,13 +1238,13 @@ static int lod_attr_set(const struct lu_env *env, RETURN(rc); if (!S_ISDIR(dt->do_lu.lo_header->loh_attr)) { - if (!(attr->la_valid & (LA_UID | LA_GID))) + if (!(attr->la_valid & (LA_UID | LA_GID | LA_PROJID))) RETURN(rc); if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_BAD_OWNER)) RETURN(0); } else { - if (!(attr->la_valid & (LA_UID | LA_GID | LA_MODE | + if (!(attr->la_valid & (LA_UID | LA_GID | LA_MODE | LA_PROJID | LA_ATIME | LA_MTIME | LA_CTIME | LA_FLAGS))) RETURN(rc); @@ -2912,7 +2912,7 @@ static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt, RETURN(rc); attr->la_valid = LA_ATIME | LA_MTIME | LA_CTIME | - LA_MODE | LA_UID | LA_GID | LA_TYPE; + LA_MODE | LA_UID | LA_GID | LA_TYPE | LA_PROJID; dof->dof_type = DFT_DIR; rc = lod_prep_lmv_md(env, dt, &lmv_buf); diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 212e279..4c0a59b 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -593,6 +593,12 @@ void mdt_pack_attr2body(struct mdt_thread_info *info, struct mdt_body *b, b->mbo_valid |= OBD_MD_FLGID; } + if (attr->la_valid & LA_PROJID) { + /* TODO, nodemap for project id */ + b->mbo_projid = attr->la_projid; + b->mbo_valid |= OBD_MD_FLPROJID; + } + b->mbo_mode = attr->la_mode; if (attr->la_valid & LA_MODE) b->mbo_valid |= OBD_MD_FLMODE; diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 0590fd4..95f16d8 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -807,6 +807,8 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr, out |= LA_KILL_SUID; if (in & MDS_ATTR_KILL_SGID) out |= LA_KILL_SGID; + if (in & MDS_ATTR_PROJID) + out |= LA_PROJID; if (in & MDS_ATTR_FROM_OPEN) rr->rr_flags |= MRF_OPEN_TRUNC; @@ -815,7 +817,7 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr, if (in & MDS_ATTR_FORCE) ma->ma_attr_flags |= MDS_PERM_BYPASS; - in &= ~(MDS_ATTR_MODE | MDS_ATTR_UID | MDS_ATTR_GID | + in &= ~(MDS_ATTR_MODE | MDS_ATTR_UID | MDS_ATTR_GID | MDS_ATTR_PROJID | MDS_ATTR_ATIME | MDS_ATTR_MTIME | MDS_ATTR_CTIME | MDS_ATTR_ATIME_SET | MDS_ATTR_CTIME_SET | MDS_ATTR_MTIME_SET | MDS_ATTR_SIZE | MDS_ATTR_BLOCKS | MDS_ATTR_ATTR_FLAG | diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 5418dc6..72a2497 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -595,7 +595,8 @@ static int mdt_attr_set(struct mdt_thread_info *info, struct mdt_object *mo, struct md_attr *ma) { struct mdt_lock_handle *lh; - int do_vbr = ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID|LA_FLAGS); + int do_vbr = ma->ma_attr.la_valid & + (LA_MODE|LA_UID|LA_GID|LA_PROJID|LA_FLAGS); __u64 lockpart = MDS_INODELOCK_UPDATE; struct ldlm_enqueue_info *einfo = &info->mti_einfo; struct lu_fid *s0_fid = &info->mti_tmp_fid1; @@ -648,13 +649,13 @@ static int mdt_attr_set(struct mdt_thread_info *info, struct mdt_object *mo, } /* Ensure constant striping during chown(). See LU-2789. */ - if (ma->ma_attr.la_valid & (LA_UID|LA_GID)) + if (ma->ma_attr.la_valid & (LA_UID|LA_GID|LA_PROJID)) mutex_lock(&mo->mot_lov_mutex); /* all attrs are packed into mti_attr in unpack_setattr */ rc = mo_attr_set(info->mti_env, mdt_object_child(mo), ma); - if (ma->ma_attr.la_valid & (LA_UID|LA_GID)) + if (ma->ma_attr.la_valid & (LA_UID|LA_GID|LA_PROJID)) mutex_unlock(&mo->mot_lov_mutex); if (rc != 0) diff --git a/lustre/obdclass/linux/linux-obdo.c b/lustre/obdclass/linux/linux-obdo.c index 4ce7bb1..5f8e2b5 100644 --- a/lustre/obdclass/linux/linux-obdo.c +++ b/lustre/obdclass/linux/linux-obdo.c @@ -87,6 +87,10 @@ void obdo_from_la(struct obdo *dst, const struct lu_attr *la, u64 valid) dst->o_gid = la->la_gid; newvalid |= OBD_MD_FLGID; } + if (valid & LA_PROJID) { + dst->o_projid = la->la_projid; + newvalid |= OBD_MD_FLPROJID; + } if (valid & LA_FLAGS) { dst->o_flags = la->la_flags; newvalid |= OBD_MD_FLFLAGS; @@ -140,6 +144,10 @@ void la_from_obdo(struct lu_attr *dst, const struct obdo *obdo, u64 valid) dst->la_gid = obdo->o_gid; newvalid |= LA_GID; } + if (valid & OBD_MD_FLPROJID) { + dst->la_projid = obdo->o_projid; + newvalid |= LA_PROJID; + } if (valid & OBD_MD_FLFLAGS) { dst->la_flags = obdo->o_flags; newvalid |= LA_FLAGS; diff --git a/lustre/obdclass/llog_swab.c b/lustre/obdclass/llog_swab.c index aab189d..3e62c57 100644 --- a/lustre/obdclass/llog_swab.c +++ b/lustre/obdclass/llog_swab.c @@ -246,7 +246,16 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec) __swab32s(&lsr->lsr_gid); __swab32s(&lsr->lsr_gid_h); __swab64s(&lsr->lsr_valid); - tail = &lsr->lsr_tail; + + if (rec->lrh_len > sizeof(struct llog_setattr64_rec)) { + struct llog_setattr64_rec_v2 *lsr2 = + (struct llog_setattr64_rec_v2 *)rec; + + __swab32s(&lsr2->lsr_projid); + tail = &lsr2->lsr_tail; + } else { + tail = &lsr->lsr_tail; + } break; } case OBD_CFG_REC: diff --git a/lustre/obdclass/obdo.c b/lustre/obdclass/obdo.c index 08e74a8..73075da 100644 --- a/lustre/obdclass/obdo.c +++ b/lustre/obdclass/obdo.c @@ -55,6 +55,13 @@ void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent) } EXPORT_SYMBOL(obdo_set_parent_fid); +void obdo_set_o_projid(struct obdo *dst, u32 projid) +{ + dst->o_projid = projid; + dst->o_valid |= OBD_MD_FLPROJID; +} +EXPORT_SYMBOL(obdo_set_o_projid); + /* WARNING: the file systems must take care not to tinker with attributes they don't manage (such as blocks). */ void obdo_from_inode(struct obdo *dst, struct inode *src, u64 valid) diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index f6de981..2f91b17 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -1323,7 +1323,7 @@ static int ofd_getattr_hdl(struct tgt_session_info *tsi) __u64 curr_version; obdo_from_la(&repbody->oa, &fti->fti_attr, - OFD_VALID_FLAGS | LA_UID | LA_GID); + OFD_VALID_FLAGS | LA_UID | LA_GID | LA_PROJID); /* Store object version in reply */ curr_version = dt_version_get(tsi->tsi_env, @@ -1418,7 +1418,7 @@ static int ofd_setattr_hdl(struct tgt_session_info *tsi) GOTO(out_put, rc); obdo_from_la(&repbody->oa, &fti->fti_attr, - OFD_VALID_FLAGS | LA_UID | LA_GID); + OFD_VALID_FLAGS | LA_UID | LA_GID | LA_PROJID); ofd_counter_incr(tsi->tsi_exp, LPROC_OFD_STATS_SETATTR, tsi->tsi_jobid, 1); diff --git a/lustre/ofd/ofd_internal.h b/lustre/ofd/ofd_internal.h index ab477fb..6f1ed7f 100644 --- a/lustre/ofd/ofd_internal.h +++ b/lustre/ofd/ofd_internal.h @@ -413,7 +413,7 @@ int ofd_object_punch(const struct lu_env *env, struct ofd_object *fo, int ofd_object_destroy(const struct lu_env *, struct ofd_object *, int); int ofd_attr_get(const struct lu_env *env, struct ofd_object *fo, struct lu_attr *la); -int ofd_attr_handle_ugid(const struct lu_env *env, struct ofd_object *fo, +int ofd_attr_handle_id(const struct lu_env *env, struct ofd_object *fo, struct lu_attr *la, int is_setattr); static inline diff --git a/lustre/ofd/ofd_io.c b/lustre/ofd/ofd_io.c index 6f2fe7f..dcd6c96 100644 --- a/lustre/ofd/ofd_io.c +++ b/lustre/ofd/ofd_io.c @@ -833,9 +833,9 @@ ofd_write_attr_set(const struct lu_env *env, struct ofd_device *ofd, dt_obj = ofd_object_child(ofd_obj); LASSERT(dt_obj != NULL); - la->la_valid &= LA_UID | LA_GID; + la->la_valid &= LA_UID | LA_GID | LA_PROJID; - rc = ofd_attr_handle_ugid(env, ofd_obj, la, 0 /* !is_setattr */); + rc = ofd_attr_handle_id(env, ofd_obj, la, 0 /* !is_setattr */); if (rc != 0) GOTO(out, rc); @@ -881,7 +881,7 @@ ofd_write_attr_set(const struct lu_env *env, struct ofd_device *ofd, if (rc) GOTO(out_tx, rc); - /* set uid/gid */ + /* set uid/gid/pid */ if (la->la_valid) { rc = dt_attr_set(env, dt_obj, la, th); if (rc) @@ -1209,7 +1209,7 @@ int ofd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, * to be changed to ofd_fmd_get() to create the fmd if it * doesn't already exist so we can store the reservation handle * there. */ - valid = OBD_MD_FLUID | OBD_MD_FLGID; + valid = OBD_MD_FLUID | OBD_MD_FLGID | OBD_MD_FLPROJID; fmd = ofd_fmd_find(exp, fid); if (!fmd || fmd->fmd_mactime_xid < info->fti_xid) valid |= OBD_MD_FLATIME | OBD_MD_FLMTIME | @@ -1227,9 +1227,11 @@ int ofd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, oa->o_grant_used, old_rc); if (rc == 0) obdo_from_la(oa, &info->fti_attr, - OFD_VALID_FLAGS | LA_GID | LA_UID); + OFD_VALID_FLAGS | LA_GID | LA_UID | + LA_PROJID); else - obdo_from_la(oa, &info->fti_attr, LA_GID | LA_UID); + obdo_from_la(oa, &info->fti_attr, LA_GID | LA_UID | + LA_PROJID); /* don't report overquota flag if we failed before reaching * commit */ diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index 35173aa..8cf8e2a 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -1212,7 +1212,7 @@ static int ofd_echo_getattr(const struct lu_env *env, struct obd_export *exp, __u64 curr_version; obdo_from_la(oa, &info->fti_attr, - OFD_VALID_FLAGS | LA_UID | LA_GID); + OFD_VALID_FLAGS | LA_UID | LA_GID | LA_PROJID); /* Store object version in reply */ curr_version = dt_version_get(env, ofd_object_child(fo)); diff --git a/lustre/ofd/ofd_objects.c b/lustre/ofd/ofd_objects.c index f838e23..1799970 100644 --- a/lustre/ofd/ofd_objects.c +++ b/lustre/ofd/ofd_objects.c @@ -410,9 +410,9 @@ out: * * If the object still has SUID+SGID bits set, meaning that it was precreated * by the MDT before it was assigned to any file, (see ofd_precreate_objects()) - * then we will accept the UID+GID if sent by the client for initializing the - * ownership of this object. We only allow this to happen once (so clear these - * bits) and later only allow setattr. + * then we will accept the UID/GID/PROJID if sent by the client for initializing + * the ownership of this object. We only allow this to happen once (so clear + * these bits) and later only allow setattr. * * \param[in] env execution environment * \param[in] fo OFD object @@ -422,7 +422,7 @@ out: * \retval 0 if successful * \retval negative value on error */ -int ofd_attr_handle_ugid(const struct lu_env *env, struct ofd_object *fo, +int ofd_attr_handle_id(const struct lu_env *env, struct ofd_object *fo, struct lu_attr *la, int is_setattr) { struct ofd_thread_info *info = ofd_info(env); @@ -432,7 +432,8 @@ int ofd_attr_handle_ugid(const struct lu_env *env, struct ofd_object *fo, ENTRY; - if (!(la->la_valid & LA_UID) && !(la->la_valid & LA_GID)) + if (!(la->la_valid & LA_UID) && !(la->la_valid & LA_GID) && + !(la->la_valid & LA_PROJID)) RETURN(0); rc = dt_attr_get(env, ofd_object_child(fo), ln); @@ -441,13 +442,19 @@ int ofd_attr_handle_ugid(const struct lu_env *env, struct ofd_object *fo, LASSERT(ln->la_valid & LA_MODE); + /* + * Only allow setattr to change UID/GID/PROJID, if + * SUID+SGID is not set which means this is not + * initialization of this objects. + */ if (!is_setattr) { if (!(ln->la_mode & S_ISUID)) - la->la_valid &= ~LA_UID; + la->la_valid &= ~(LA_UID | LA_PROJID); if (!(ln->la_mode & S_ISGID)) - la->la_valid &= ~LA_GID; + la->la_valid &= ~(LA_GID | LA_PROJID); } + /* Initialize ownership of this object, clear SUID+SGID bits*/ if ((la->la_valid & LA_UID) && (ln->la_mode & S_ISUID)) mask |= S_ISUID; if ((la->la_valid & LA_GID) && (ln->la_mode & S_ISGID)) @@ -507,7 +514,7 @@ int ofd_attr_set(const struct lu_env *env, struct ofd_object *fo, if (rc) GOTO(unlock, rc); - rc = ofd_attr_handle_ugid(env, fo, la, 1 /* is_setattr */); + rc = ofd_attr_handle_id(env, fo, la, 1 /* is_setattr */); if (rc != 0) GOTO(unlock, rc); @@ -633,7 +640,7 @@ int ofd_object_punch(const struct lu_env *env, struct ofd_object *fo, if (rc) GOTO(unlock, rc); - rc = ofd_attr_handle_ugid(env, fo, la, 0 /* !is_setattr */); + rc = ofd_attr_handle_id(env, fo, la, 0 /* !is_setattr */); if (rc != 0) GOTO(unlock, rc); diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 8266ac3..1bb8fa3 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2358,8 +2358,8 @@ static void osd_inode_getattr(const struct lu_env *env, { attr->la_valid |= LA_ATIME | LA_MTIME | LA_CTIME | LA_MODE | LA_SIZE | LA_BLOCKS | LA_UID | LA_GID | - LA_FLAGS | LA_NLINK | LA_RDEV | LA_BLKSIZE | - LA_TYPE; + LA_PROJID | LA_FLAGS | LA_NLINK | LA_RDEV | + LA_BLKSIZE | LA_TYPE; attr->la_atime = LTIME_S(inode->i_atime); attr->la_mtime = LTIME_S(inode->i_mtime); @@ -2369,6 +2369,7 @@ static void osd_inode_getattr(const struct lu_env *env, attr->la_blocks = inode->i_blocks; attr->la_uid = i_uid_read(inode); attr->la_gid = i_gid_read(inode); + attr->la_projid = i_projid_read(inode); attr->la_flags = ll_inode_to_ext_flags(inode->i_flags); attr->la_nlink = inode->i_nlink; attr->la_rdev = inode->i_rdev; @@ -2399,6 +2400,65 @@ static int osd_attr_get(const struct lu_env *env, return 0; } +static int osd_declare_attr_qid(const struct lu_env *env, + struct osd_object *obj, + struct osd_thandle *oh, long long bspace, + qid_t old_id, qid_t new_id, bool enforce, + unsigned type) +{ + int rc; + struct osd_thread_info *info = osd_oti_get(env); + struct lquota_id_info *qi = &info->oti_qi; + + qi->lqi_type = type; + /* inode accounting */ + qi->lqi_is_blk = false; + + /* one more inode for the new id ... */ + qi->lqi_id.qid_uid = new_id; + qi->lqi_space = 1; + /* Reserve credits for the new id */ + rc = osd_declare_qid(env, oh, qi, NULL, enforce, NULL); + if (rc == -EDQUOT || rc == -EINPROGRESS) + rc = 0; + if (rc) + RETURN(rc); + + /* and one less inode for the current id */ + qi->lqi_id.qid_uid = old_id; + qi->lqi_space = -1; + rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); + if (rc == -EDQUOT || rc == -EINPROGRESS) + rc = 0; + if (rc) + RETURN(rc); + + /* block accounting */ + qi->lqi_is_blk = true; + + /* more blocks for the new uid ... */ + qi->lqi_id.qid_uid = new_id; + qi->lqi_space = bspace; + /* + * Credits for the new uid has been reserved, re-use "obj" + * to save credit reservation. + */ + rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); + if (rc == -EDQUOT || rc == -EINPROGRESS) + rc = 0; + if (rc) + RETURN(rc); + + /* and finally less blocks for the current uid */ + qi->lqi_id.qid_uid = old_id; + qi->lqi_space = -bspace; + rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); + if (rc == -EDQUOT || rc == -EINPROGRESS) + rc = 0; + + RETURN(rc); +} + static int osd_declare_attr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_attr *attr, @@ -2406,8 +2466,6 @@ static int osd_declare_attr_set(const struct lu_env *env, { struct osd_thandle *oh; struct osd_object *obj; - struct osd_thread_info *info = osd_oti_get(env); - struct lquota_id_info *qi = &info->oti_qi; qid_t uid; qid_t gid; long long bspace; @@ -2446,103 +2504,33 @@ static int osd_declare_attr_set(const struct lu_env *env, if (attr->la_valid & LA_UID || attr->la_valid & LA_GID) { /* USERQUOTA */ uid = i_uid_read(obj->oo_inode); - qi->lqi_type = USRQUOTA; enforce = (attr->la_valid & LA_UID) && (attr->la_uid != uid); - /* inode accounting */ - qi->lqi_is_blk = false; - - /* one more inode for the new uid ... */ - qi->lqi_id.qid_uid = attr->la_uid; - qi->lqi_space = 1; - /* Reserve credits for the new uid */ - rc = osd_declare_qid(env, oh, qi, NULL, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; + rc = osd_declare_attr_qid(env, obj, oh, bspace, uid, + attr->la_uid, enforce, USRQUOTA); if (rc) RETURN(rc); - /* and one less inode for the current uid */ - qi->lqi_id.qid_uid = uid; - qi->lqi_space = -1; - rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; - if (rc) - RETURN(rc); - - /* block accounting */ - qi->lqi_is_blk = true; - - /* more blocks for the new uid ... */ - qi->lqi_id.qid_uid = attr->la_uid; - qi->lqi_space = bspace; - /* - * Credits for the new uid has been reserved, re-use "obj" - * to save credit reservation. - */ - rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; - if (rc) - RETURN(rc); - - /* and finally less blocks for the current uid */ - qi->lqi_id.qid_uid = uid; - qi->lqi_space = -bspace; - rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; - if (rc) - RETURN(rc); - - /* GROUP QUOTA */ gid = i_gid_read(obj->oo_inode); - qi->lqi_type = GRPQUOTA; enforce = (attr->la_valid & LA_GID) && (attr->la_gid != gid); - - /* inode accounting */ - qi->lqi_is_blk = false; - - /* one more inode for the new gid ... */ - qi->lqi_id.qid_gid = attr->la_gid; - qi->lqi_space = 1; - rc = osd_declare_qid(env, oh, qi, NULL, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; + rc = osd_declare_attr_qid(env, obj, oh, bspace, + i_gid_read(obj->oo_inode), attr->la_gid, + enforce, GRPQUOTA); if (rc) RETURN(rc); - /* and one less inode for the current gid */ - qi->lqi_id.qid_gid = gid; - qi->lqi_space = -1; - rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; - if (rc) - RETURN(rc); - - /* block accounting */ - qi->lqi_is_blk = true; - - /* more blocks for the new gid ... */ - qi->lqi_id.qid_gid = attr->la_gid; - qi->lqi_space = bspace; - rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; - if (rc) - RETURN(rc); - - /* and finally less blocks for the current gid */ - qi->lqi_id.qid_gid = gid; - qi->lqi_space = -bspace; - rc = osd_declare_qid(env, oh, qi, obj, enforce, NULL); - if (rc == -EDQUOT || rc == -EINPROGRESS) - rc = 0; + } +#ifdef HAVE_PROJECT_QUOTA + if (attr->la_valid & LA_PROJID) { + __u32 projid = i_projid_read(obj->oo_inode); + enforce = (attr->la_valid & LA_PROJID) && + (attr->la_projid != projid); + rc = osd_declare_attr_qid(env, obj, oh, bspace, + (qid_t)projid, (qid_t)attr->la_projid, + enforce, PRJQUOTA); if (rc) RETURN(rc); } - +#endif RETURN(rc); } @@ -2580,6 +2568,8 @@ static int osd_inode_setattr(const struct lu_env *env, i_uid_write(inode, attr->la_uid); if (bits & LA_GID) i_gid_write(inode, attr->la_gid); + if (bits & LA_PROJID) + i_projid_write(inode, attr->la_projid); if (bits & LA_NLINK) set_nlink(inode, attr->la_nlink); if (bits & LA_RDEV) @@ -2595,10 +2585,11 @@ static int osd_inode_setattr(const struct lu_env *env, static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr) { + int rc; + if ((attr->la_valid & LA_UID && attr->la_uid != i_uid_read(inode)) || (attr->la_valid & LA_GID && attr->la_gid != i_gid_read(inode))) { struct iattr iattr; - int rc; ll_vfs_dq_init(inode); iattr.ia_valid = 0; @@ -2617,6 +2608,20 @@ static int osd_quota_transfer(struct inode *inode, const struct lu_attr *attr) return rc; } } + +#ifdef HAVE_PROJECT_QUOTA + /* Handle project id Transfer here properly */ + if (attr->la_valid & LA_PROJID && attr->la_projid != + i_projid_read(inode)) { + rc = __ldiskfs_ioctl_setproject(inode, attr->la_projid); + if (rc) { + CERROR("%s: quota transfer failed: rc = %d. Is quota " + "enforcement enabled on the ldiskfs " + "filesystem?\n", inode->i_sb->s_id, rc); + return rc; + } + } +#endif return 0; } @@ -3102,8 +3107,9 @@ static int osd_declare_object_create(const struct lu_env *env, if (!attr) RETURN(0); - rc = osd_declare_inode_qid(env, attr->la_uid, attr->la_gid, 1, oh, - osd_dt_obj(dt), false, NULL, false); + rc = osd_declare_inode_qid(env, attr->la_uid, attr->la_gid, + attr->la_projid, 1, oh, osd_dt_obj(dt), + false, NULL, false); if (rc != 0) RETURN(rc); @@ -3181,12 +3187,14 @@ static int osd_declare_object_destroy(const struct lu_env *env, osd_dto_credits_noquota[DTO_INDEX_DELETE] + 3); /* one less inode */ rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode), - -1, oh, obj, false, NULL, false); + i_projid_read(inode), -1, oh, obj, false, + NULL, false); if (rc) RETURN(rc); /* data to be truncated */ rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode), - 0, oh, obj, true, NULL, false); + i_projid_read(inode), 0, oh, obj, true, + NULL, false); if (rc) RETURN(rc); @@ -4527,7 +4535,8 @@ static int osd_index_declare_ea_delete(const struct lu_env *env, RETURN(-ENOENT); rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode), - 0, oh, osd_dt_obj(dt), true, NULL, false); + i_projid_read(inode), 0, oh, osd_dt_obj(dt), + true, NULL, false); RETURN(rc); } @@ -5410,8 +5419,10 @@ static int osd_index_declare_ea_insert(const struct lu_env *env, * calculate how many blocks will be consumed by this index * insert */ rc = osd_declare_inode_qid(env, i_uid_read(inode), - i_gid_read(inode), 0, oh, - osd_dt_obj(dt), true, NULL, false); + i_gid_read(inode), + i_projid_read(inode), 0, + oh, osd_dt_obj(dt), true, + NULL, false); } RETURN(rc); diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index dba78c1..eb7a72e 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -90,6 +90,11 @@ extern struct kmem_cache *dynlock_cachep; #define OSD_STATFS_RESERVED (1ULL << 23) /* 8MB */ #define OSD_STATFS_RESERVED_SHIFT (7) /* reserve 0.78% of all space */ +/* check if ldiskfs support project quota */ +#ifndef LDISKFS_IOC_FSSETXATTR +#undef HAVE_PROJECT_QUOTA +#endif + struct osd_directory { struct iam_container od_container; struct iam_descr od_descr; @@ -316,16 +321,17 @@ enum osd_full_scrub_ratio { #define FULL_SCRUB_THRESHOLD_RATE_DEFAULT 60 -/* There are at most 10 uid/gids are affected in a transaction, and +/* There are at most 15 uid/gid/projids are affected in a transaction, and * that's rename case: - * - 2 for source parent uid & gid; - * - 2 for source child uid & gid ('..' entry update when child is directory); - * - 2 for target parent uid & gid; - * - 2 for target child uid & gid (if the target child exists); - * - 2 for root uid & gid (last_rcvd, llog, etc); + * - 3 for source parent uid & gid & projid; + * - 3 for source child uid & gid & projid ('..' entry update when + * child is directory); + * - 3 for target parent uid & gid & projid; + * - 3 for target child uid & gid & projid(if the target child exists); + * - 3 for root uid & gid(last_rcvd, llog, etc); * */ -#define OSD_MAX_UGID_CNT 10 +#define OSD_MAX_UGID_CNT 15 enum osd_op_type { OSD_OT_ATTR_SET = 0, @@ -737,7 +743,7 @@ int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh, struct lquota_id_info *qi, struct osd_object *obj, bool enforce, int *flags); int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid, - long long space, struct osd_thandle *oh, + __u32 projid, long long space, struct osd_thandle *oh, struct osd_object *obj, bool is_blk, int *flags, bool force); const struct dt_rec *osd_quota_pack(struct osd_object *obj, @@ -768,6 +774,29 @@ static inline void i_gid_write(struct inode *inode, gid_t gid) } #endif +#ifdef HAVE_PROJECT_QUOTA +static inline __u32 i_projid_read(struct inode *inode) +{ + return (__u32)from_kprojid(&init_user_ns, LDISKFS_I(inode)->i_projid); +} + +static inline void i_projid_write(struct inode *inode, __u32 projid) +{ + kprojid_t kprojid; + kprojid = make_kprojid(&init_user_ns, (projid_t)projid); + LDISKFS_I(inode)->i_projid = kprojid; +} +#else +static inline uid_t i_projid_read(struct inode *inode) +{ + return 0; +} +static inline void i_projid_write(struct inode *inode, __u32 projid) +{ + return; +} +#endif + #ifdef HAVE_LDISKFS_INFO_JINODE # define osd_attach_jinode(inode) ldiskfs_inode_attach_jinode(inode) #else /* HAVE_LDISKFS_INFO_JINODE */ diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 1d942aa..cffb6c6 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -1196,8 +1196,8 @@ static int osd_declare_write_commit(const struct lu_env *env, lnb[0].lnb_flags &= ~OBD_BRW_OVER_ALLQUOTA; rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode), - quota_space, oh, osd_dt_obj(dt), true, - &flags, ignore_quota); + i_projid_read(inode), quota_space, oh, + osd_dt_obj(dt), true, &flags, ignore_quota); /* we need only to store the overquota flags in the first lnb for * now, once we support multiple objects BRW, this code needs be @@ -1633,8 +1633,9 @@ out: * objects, so always set the lqi_space as 0. */ if (inode != NULL) rc = osd_declare_inode_qid(env, i_uid_read(inode), - i_gid_read(inode), 0, oh, obj, true, - NULL, false); + i_gid_read(inode), + i_projid_read(inode), 0, + oh, obj, true, NULL, false); RETURN(rc); } @@ -1808,7 +1809,8 @@ static int osd_declare_punch(const struct lu_env *env, struct dt_object *dt, LASSERT(inode); rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode), - 0, oh, osd_dt_obj(dt), true, NULL, false); + i_projid_read(inode), 0, oh, osd_dt_obj(dt), + true, NULL, false); RETURN(rc); } diff --git a/lustre/osd-ldiskfs/osd_quota.c b/lustre/osd-ldiskfs/osd_quota.c index 6b184fb..4f62122 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -621,13 +621,13 @@ int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh, * \retval -ve - failure */ int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid, - long long space, struct osd_thandle *oh, + __u32 projid, long long space, struct osd_thandle *oh, struct osd_object *obj, bool is_blk, int *flags, bool force) { struct osd_thread_info *info = osd_oti_get(env); struct lquota_id_info *qi = &info->oti_qi; - int rcu, rcg; /* user & group rc */ + int rcu, rcg, rcp; /* user & group & project rc */ ENTRY; /* let's start with user quota */ @@ -656,8 +656,26 @@ int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid, if (force && (rcg == -EDQUOT || rcg == -EINPROGRESS)) /* as before, ignore EDQUOT & EINPROGRESS for root */ rcg = 0; + if (rcg && (rcg != -EDQUOT || flags == NULL)) + RETURN(rcg); - RETURN(rcu ? rcu : rcg); + /* 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); + + if (force && (rcp == -EDQUOT || rcp == -EINPROGRESS)) + /* as before, ignore EDQUOT & EINPROGRESS for root */ + rcp = 0; + + if (rcu) + RETURN(rcu); + if (rcg) + RETURN(rcg); + if (rcp) + RETURN(rcp); + + RETURN(0); } int osd_quota_migration(const struct lu_env *env, struct dt_object *dt) diff --git a/lustre/osp/osp_internal.h b/lustre/osp/osp_internal.h index cca2f6c..9d3a650 100644 --- a/lustre/osp/osp_internal.h +++ b/lustre/osp/osp_internal.h @@ -333,7 +333,7 @@ struct osp_thread_info { union { struct llog_rec_hdr osi_hdr; struct llog_unlink64_rec osi_unlink; - struct llog_setattr64_rec osi_setattr; + struct llog_setattr64_rec_v2 osi_setattr; struct llog_gen_rec osi_gen; }; struct llog_cookie osi_cookie; diff --git a/lustre/osp/osp_object.c b/lustre/osp/osp_object.c index a5b69d1..2145285 100644 --- a/lustre/osp/osp_object.c +++ b/lustre/osp/osp_object.c @@ -612,7 +612,7 @@ static int osp_declare_attr_set(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } - if (!(attr->la_valid & (LA_UID | LA_GID))) + if (!(attr->la_valid & (LA_UID | LA_GID | LA_PROJID))) RETURN(0); /* track all UID/GID changes via llog */ @@ -649,8 +649,8 @@ static int osp_attr_set(const struct lu_env *env, struct dt_object *dt, int rc = 0; ENTRY; - /* we're interested in uid/gid changes only */ - if (!(attr->la_valid & (LA_UID | LA_GID))) + /* we're interested in uid/gid/projid changes only */ + if (!(attr->la_valid & (LA_UID | LA_GID | LA_PROJID))) RETURN(0); if (!is_only_remote_trans(th)) { @@ -680,6 +680,10 @@ static int osp_attr_set(const struct lu_env *env, struct dt_object *dt, la->la_gid = attr->la_gid; la->la_valid |= LA_GID; } + if (attr->la_valid & LA_PROJID) { + la->la_gid = attr->la_projid; + la->la_valid |= LA_PROJID; + } spin_unlock(&o->opo_lock); } diff --git a/lustre/osp/osp_sync.c b/lustre/osp/osp_sync.c index 4f777e8..f54b7be 100644 --- a/lustre/osp/osp_sync.c +++ b/lustre/osp/osp_sync.c @@ -333,7 +333,7 @@ int osp_sync_declare_add(const struct lu_env *env, struct osp_object *o, osi->osi_hdr.lrh_len = sizeof(struct llog_unlink64_rec); break; case MDS_SETATTR64_REC: - osi->osi_hdr.lrh_len = sizeof(struct llog_setattr64_rec); + osi->osi_hdr.lrh_len = sizeof(struct llog_setattr64_rec_v2); break; default: LBUG(); @@ -409,9 +409,11 @@ static int osp_sync_add_rec(const struct lu_env *env, struct osp_device *d, LASSERT(attr); osi->osi_setattr.lsr_uid = attr->la_uid; osi->osi_setattr.lsr_gid = attr->la_gid; + osi->osi_setattr.lsr_projid = attr->la_projid; osi->osi_setattr.lsr_valid = ((attr->la_valid & LA_UID) ? OBD_MD_FLUID : 0) | - ((attr->la_valid & LA_GID) ? OBD_MD_FLGID : 0); + ((attr->la_valid & LA_GID) ? OBD_MD_FLGID : 0) | + ((attr->la_valid & LA_PROJID) ? OBD_MD_FLPROJID : 0); break; default: LBUG(); @@ -715,11 +717,13 @@ static int osp_sync_new_setattr_job(struct osp_device *d, if (OBD_FAIL_CHECK(OBD_FAIL_OSP_CHECK_INVALID_REC)) RETURN(1); - /* lsr_valid can only be 0 or have OBD_MD_{FLUID,FLGID} set, + + /* lsr_valid can only be 0 or HAVE OBD_MD_{FLUID, FLGID, FLPROJID} set, * so no bits other than these should be set. */ - if ((rec->lsr_valid & ~(OBD_MD_FLUID | OBD_MD_FLGID)) != 0) { + if ((rec->lsr_valid & ~(OBD_MD_FLUID | OBD_MD_FLGID | + OBD_MD_FLPROJID)) != 0) { CERROR("%s: invalid setattr record, lsr_valid:%llu\n", - d->opd_obd->obd_name, rec->lsr_valid); + d->opd_obd->obd_name, rec->lsr_valid); /* return 1 on invalid record */ RETURN(1); } @@ -734,6 +738,10 @@ static int osp_sync_new_setattr_job(struct osp_device *d, body->oa.o_uid = rec->lsr_uid; body->oa.o_gid = rec->lsr_gid; body->oa.o_valid = OBD_MD_FLGROUP | OBD_MD_FLID; + if (h->lrh_len > sizeof(struct llog_setattr64_rec)) + body->oa.o_projid = ((struct llog_setattr64_rec_v2 *) + rec)->lsr_projid; + /* old setattr record (prior 2.6.0) doesn't have 'valid' stored, * we assume that both UID and GID are valid in that case. */ if (rec->lsr_valid == 0) diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 7642894..5cf1793 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -1734,6 +1734,7 @@ void lustre_swab_obdo (struct obdo *o) __swab32s (&o->o_uid_h); __swab32s (&o->o_gid_h); __swab64s (&o->o_data_version); + __swab32s(&o->o_projid); CLASSERT(offsetof(typeof(*o), o_padding_4) != 0); CLASSERT(offsetof(typeof(*o), o_padding_5) != 0); CLASSERT(offsetof(typeof(*o), o_padding_6) != 0); @@ -1886,7 +1887,8 @@ void lustre_swab_mdt_body (struct mdt_body *b) CLASSERT(offsetof(typeof(*b), mbo_unused3) != 0); __swab32s(&b->mbo_uid_h); __swab32s(&b->mbo_gid_h); - CLASSERT(offsetof(typeof(*b), mbo_padding_5) != 0); + __swab32s(&b->mbo_projid); + CLASSERT(offsetof(typeof(*b), mbo_padding_6) != 0); } void lustre_swab_mdt_ioepoch(struct mdt_ioepoch *b) diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 6dc2f3d..55fda60 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -252,6 +252,9 @@ void lustre_assert_wire_constants(void) (long long)MDS_ATTR_FROM_OPEN); LASSERTF(MDS_ATTR_BLOCKS == 0x0000000000008000ULL, "found 0x%.16llxULL\n", (long long)MDS_ATTR_BLOCKS); + + LASSERTF(MDS_ATTR_PROJID == 0x0000000000010000ULL, "found 0x%.16llxULL\n", + (long long)MDS_ATTR_PROJID); LASSERTF(FLD_QUERY == 900, "found %lld\n", (long long)FLD_QUERY); LASSERTF(FLD_READ == 901, "found %lld\n", @@ -1374,9 +1377,13 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obdo, o_data_version)); LASSERTF((int)sizeof(((struct obdo *)0)->o_data_version) == 8, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_data_version)); - LASSERTF((int)offsetof(struct obdo, o_padding_4) == 184, "found %lld\n", + LASSERTF((int)offsetof(struct obdo, o_projid) == 184, "found %lld\n", + (long long)(int)offsetof(struct obdo, o_projid)); + LASSERTF((int)sizeof(((struct obdo *)0)->o_projid) == 4, "found %lld\n", + (long long)(int)sizeof(((struct obdo *)0)->o_projid)); + LASSERTF((int)offsetof(struct obdo, o_padding_4) == 188, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_4)); - LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 8, "found %lld\n", + LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 4, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_padding_4)); LASSERTF((int)offsetof(struct obdo, o_padding_5) == 192, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_5)); @@ -1476,6 +1483,9 @@ void lustre_assert_wire_constants(void) OBD_MD_DEFAULT_MEA); LASSERTF(OBD_MD_FLOSTLAYOUT == (0x0080000000000000ULL), "found 0x%.16llxULL\n", OBD_MD_FLOSTLAYOUT); + + LASSERTF(OBD_MD_FLPROJID == (0x0100000000000000ULL), "found 0x%.16llxULL\n", + OBD_MD_FLPROJID); CLASSERT(OBD_FL_INLINEDATA == 0x00000001); CLASSERT(OBD_FL_OBDMDEXISTS == 0x00000002); CLASSERT(OBD_FL_DELORPHAN == 0x00000004); @@ -2229,10 +2239,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mdt_body, mbo_gid_h)); LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_gid_h) == 4, "found %lld\n", (long long)(int)sizeof(((struct mdt_body *)0)->mbo_gid_h)); - LASSERTF((int)offsetof(struct mdt_body, mbo_padding_5) == 172, "found %lld\n", - (long long)(int)offsetof(struct mdt_body, mbo_padding_5)); - LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_5) == 4, "found %lld\n", - (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_5)); + LASSERTF((int)offsetof(struct mdt_body, mbo_projid) == 172, "found %lld\n", + (long long)(int)offsetof(struct mdt_body, mbo_projid)); + LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_projid) == 4, "found %lld\n", + (long long)(int)sizeof(((struct mdt_body *)0)->mbo_projid)); LASSERTF((int)offsetof(struct mdt_body, mbo_padding_6) == 176, "found %lld\n", (long long)(int)offsetof(struct mdt_body, mbo_padding_6)); LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_6) == 8, "found %lld\n", @@ -3693,10 +3703,14 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct llog_setattr64_rec, lsr_valid)); LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_valid) == 8, "found %lld\n", (long long)(int)sizeof(((struct llog_setattr64_rec *)0)->lsr_valid)); - LASSERTF((int)offsetof(struct llog_setattr64_rec, lsr_tail) == 56, "found %lld\n", - (long long)(int)offsetof(struct llog_setattr64_rec, lsr_tail)); - LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_tail) == 8, "found %lld\n", - (long long)(int)sizeof(((struct llog_setattr64_rec *)0)->lsr_tail)); + LASSERTF((int)offsetof(struct llog_setattr64_rec_v2, lsr_projid) == 56, "found %lld\n", + (long long)(int)offsetof(struct llog_setattr64_rec_v2, lsr_projid)); + LASSERTF((int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_projid) == 4, "found %lld\n", + (long long)(int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_projid)); + LASSERTF((int)offsetof(struct llog_setattr64_rec_v2, lsr_tail) == 80, "found %lld\n", + (long long)(int)offsetof(struct llog_setattr64_rec_v2, lsr_tail)); + LASSERTF((int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_tail) == 8, "found %lld\n", + (long long)(int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_tail)); /* Checks for struct llog_size_change_rec */ LASSERTF((int)sizeof(struct llog_size_change_rec) == 64, "found %lld\n", diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 8ce8fe0..4bfb0ca 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -1497,9 +1497,11 @@ int jt_obd_create(int argc, char **argv) ostid_set_id(&data.ioc_obdo1.o_oi, base_id); data.ioc_obdo1.o_uid = 0; data.ioc_obdo1.o_gid = 0; + data.ioc_obdo1.o_projid = 0; data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE | OBD_MD_FLID | OBD_MD_FLUID | - OBD_MD_FLGID | OBD_MD_FLGROUP; + OBD_MD_FLGID | OBD_MD_FLGROUP | + OBD_MD_FLPROJID; memset(buf, 0, sizeof(rawbuf)); rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 3b87d73..d114d67 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -643,6 +643,7 @@ check_obdo(void) CHECK_MEMBER(obdo, o_uid_h); CHECK_MEMBER(obdo, o_gid_h); CHECK_MEMBER(obdo, o_data_version); + CHECK_MEMBER(obdo, o_projid); CHECK_MEMBER(obdo, o_padding_4); CHECK_MEMBER(obdo, o_padding_5); CHECK_MEMBER(obdo, o_padding_6); @@ -692,6 +693,7 @@ check_obdo(void) CHECK_DEFINE_64X(OBD_MD_CLOSE_INTENT_EXECED); CHECK_DEFINE_64X(OBD_MD_DEFAULT_MEA); CHECK_DEFINE_64X(OBD_MD_FLOSTLAYOUT); + CHECK_DEFINE_64X(OBD_MD_FLPROJID); CHECK_CVALUE_X(OBD_FL_INLINEDATA); CHECK_CVALUE_X(OBD_FL_OBDMDEXISTS); @@ -1036,7 +1038,7 @@ check_mdt_body(void) CHECK_MEMBER(mdt_body, mbo_unused3); CHECK_MEMBER(mdt_body, mbo_uid_h); CHECK_MEMBER(mdt_body, mbo_gid_h); - CHECK_MEMBER(mdt_body, mbo_padding_5); + CHECK_MEMBER(mdt_body, mbo_projid); CHECK_MEMBER(mdt_body, mbo_padding_6); CHECK_MEMBER(mdt_body, mbo_padding_7); CHECK_MEMBER(mdt_body, mbo_padding_8); @@ -1655,6 +1657,7 @@ check_llog_setattr64_rec(void) CHECK_MEMBER(llog_setattr64_rec, lsr_gid_h); CHECK_MEMBER(llog_setattr64_rec, lsr_valid); CHECK_MEMBER(llog_setattr64_rec, lsr_tail); + CHECK_MEMBER(llog_setattr64_rec_v2, lsr_projid); } static void @@ -2631,6 +2634,7 @@ main(int argc, char **argv) CHECK_VALUE_64X(MDS_ATTR_CTIME_SET); CHECK_VALUE_64X(MDS_ATTR_FROM_OPEN); CHECK_VALUE_64X(MDS_ATTR_BLOCKS); + CHECK_VALUE_64X(MDS_ATTR_PROJID); CHECK_VALUE(FLD_QUERY); CHECK_VALUE(FLD_READ); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 8346c56..bd26057 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -272,6 +272,8 @@ void lustre_assert_wire_constants(void) (long long)MDS_ATTR_FROM_OPEN); LASSERTF(MDS_ATTR_BLOCKS == 0x0000000000008000ULL, "found 0x%.16llxULL\n", (long long)MDS_ATTR_BLOCKS); + LASSERTF(MDS_ATTR_PROJID == 0x0000000000010000ULL, "found 0x%.16llxULL\n", + (long long)MDS_ATTR_PROJID); LASSERTF(FLD_QUERY == 900, "found %lld\n", (long long)FLD_QUERY); LASSERTF(FLD_READ == 901, "found %lld\n", @@ -1394,9 +1396,13 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct obdo, o_data_version)); LASSERTF((int)sizeof(((struct obdo *)0)->o_data_version) == 8, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_data_version)); - LASSERTF((int)offsetof(struct obdo, o_padding_4) == 184, "found %lld\n", + LASSERTF((int)offsetof(struct obdo, o_projid) == 184, "found %lld\n", + (long long)(int)offsetof(struct obdo, o_projid)); + LASSERTF((int)sizeof(((struct obdo *)0)->o_projid) == 4, "found %lld\n", + (long long)(int)sizeof(((struct obdo *)0)->o_projid)); + LASSERTF((int)offsetof(struct obdo, o_padding_4) == 188, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_4)); - LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 8, "found %lld\n", + LASSERTF((int)sizeof(((struct obdo *)0)->o_padding_4) == 4, "found %lld\n", (long long)(int)sizeof(((struct obdo *)0)->o_padding_4)); LASSERTF((int)offsetof(struct obdo, o_padding_5) == 192, "found %lld\n", (long long)(int)offsetof(struct obdo, o_padding_5)); @@ -1496,6 +1502,8 @@ void lustre_assert_wire_constants(void) OBD_MD_DEFAULT_MEA); LASSERTF(OBD_MD_FLOSTLAYOUT == (0x0080000000000000ULL), "found 0x%.16llxULL\n", OBD_MD_FLOSTLAYOUT); + LASSERTF(OBD_MD_FLPROJID == (0x0100000000000000ULL), "found 0x%.16llxULL\n", + OBD_MD_FLPROJID); CLASSERT(OBD_FL_INLINEDATA == 0x00000001); CLASSERT(OBD_FL_OBDMDEXISTS == 0x00000002); CLASSERT(OBD_FL_DELORPHAN == 0x00000004); @@ -2249,10 +2257,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mdt_body, mbo_gid_h)); LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_gid_h) == 4, "found %lld\n", (long long)(int)sizeof(((struct mdt_body *)0)->mbo_gid_h)); - LASSERTF((int)offsetof(struct mdt_body, mbo_padding_5) == 172, "found %lld\n", - (long long)(int)offsetof(struct mdt_body, mbo_padding_5)); - LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_5) == 4, "found %lld\n", - (long long)(int)sizeof(((struct mdt_body *)0)->mbo_padding_5)); + LASSERTF((int)offsetof(struct mdt_body, mbo_projid) == 172, "found %lld\n", + (long long)(int)offsetof(struct mdt_body, mbo_projid)); + LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_projid) == 4, "found %lld\n", + (long long)(int)sizeof(((struct mdt_body *)0)->mbo_projid)); LASSERTF((int)offsetof(struct mdt_body, mbo_padding_6) == 176, "found %lld\n", (long long)(int)offsetof(struct mdt_body, mbo_padding_6)); LASSERTF((int)sizeof(((struct mdt_body *)0)->mbo_padding_6) == 8, "found %lld\n", @@ -3713,10 +3721,14 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct llog_setattr64_rec, lsr_valid)); LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_valid) == 8, "found %lld\n", (long long)(int)sizeof(((struct llog_setattr64_rec *)0)->lsr_valid)); - LASSERTF((int)offsetof(struct llog_setattr64_rec, lsr_tail) == 56, "found %lld\n", - (long long)(int)offsetof(struct llog_setattr64_rec, lsr_tail)); - LASSERTF((int)sizeof(((struct llog_setattr64_rec *)0)->lsr_tail) == 8, "found %lld\n", - (long long)(int)sizeof(((struct llog_setattr64_rec *)0)->lsr_tail)); + LASSERTF((int)offsetof(struct llog_setattr64_rec_v2, lsr_projid) == 56, "found %lld\n", + (long long)(int)offsetof(struct llog_setattr64_rec_v2, lsr_projid)); + LASSERTF((int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_projid) == 4, "found %lld\n", + (long long)(int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_projid)); + LASSERTF((int)offsetof(struct llog_setattr64_rec_v2, lsr_tail) == 80, "found %lld\n", + (long long)(int)offsetof(struct llog_setattr64_rec_v2, lsr_tail)); + LASSERTF((int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_tail) == 8, "found %lld\n", + (long long)(int)sizeof(((struct llog_setattr64_rec_v2 *)0)->lsr_tail)); /* Checks for struct llog_size_change_rec */ LASSERTF((int)sizeof(struct llog_size_change_rec) == 64, "found %lld\n", -- 1.8.3.1