From 45c1f367a1379cb7adf9e2ed79c1221913eaf2e2 Mon Sep 17 00:00:00 2001 From: fanyong <fanyong> Date: Tue, 1 Jul 2008 02:06:00 +0000 Subject: [PATCH] Branch HEAD b=15797 i=huanghua i=vitaly Misc fix for updating file {a/m/c}time as following policy: 1) Lustre file "{a/m/c}time" should base on client-side clock, including all the file operations. 2) All the client-side clocks should be synchronized. It is no matter whether the server-side clocks are synchronized with client-side ones or not. 3) File "ctime" is increased only. 4) File "{a,m}time" are increased only, except "utime()" operation can change them backwards. --- lustre/cmm/cmm_object.c | 15 +-- lustre/cmm/cmm_split.c | 2 +- lustre/include/lu_object.h | 1 + lustre/include/lustre/lustre_idl.h | 5 +- lustre/include/md_object.h | 14 +-- lustre/liblustre/super.c | 2 +- lustre/llite/llite_lib.c | 2 +- lustre/mdc/mdc_lib.c | 2 + lustre/mdc/mdc_request.c | 5 +- lustre/mdd/mdd_dir.c | 29 ++--- lustre/mdd/mdd_internal.h | 22 ++-- lustre/mdd/mdd_object.c | 166 +++++++++++++++++++++-------- lustre/mdt/mdt_lib.c | 11 +- lustre/mdt/mdt_xattr.c | 19 ++-- lustre/osd/osd_handler.c | 34 ++++-- 15 files changed, 228 insertions(+), 101 deletions(-) diff --git a/lustre/cmm/cmm_object.c b/lustre/cmm/cmm_object.c index e6212dc6d6..3cb6962f02 100644 --- a/lustre/cmm/cmm_object.c +++ b/lustre/cmm/cmm_object.c @@ -258,21 +258,21 @@ static int cml_xattr_list(const struct lu_env *env, struct md_object *mo, } static int cml_xattr_set(const struct lu_env *env, struct md_object *mo, - const struct lu_buf *buf, - const char *name, int fl) + const struct lu_buf *buf, const char *name, + int fl, const struct lu_attr *la) { int rc; ENTRY; - rc = mo_xattr_set(env, md_object_next(mo), buf, name, fl); + rc = mo_xattr_set(env, md_object_next(mo), buf, name, fl, la); RETURN(rc); } static int cml_xattr_del(const struct lu_env *env, struct md_object *mo, - const char *name) + const char *name, const struct lu_attr *la) { int rc; ENTRY; - rc = mo_xattr_del(env, md_object_next(mo), name); + rc = mo_xattr_del(env, md_object_next(mo), name, la); RETURN(rc); } @@ -877,13 +877,14 @@ static int cmr_xattr_list(const struct lu_env *env, struct md_object *mo, } static int cmr_xattr_set(const struct lu_env *env, struct md_object *mo, - const struct lu_buf *buf, const char *name, int fl) + const struct lu_buf *buf, const char *name, + int fl, const struct lu_attr *la) { return -EFAULT; } static int cmr_xattr_del(const struct lu_env *env, struct md_object *mo, - const char *name) + const char *name, const struct lu_attr *la) { return -EFAULT; } diff --git a/lustre/cmm/cmm_split.c b/lustre/cmm/cmm_split.c index 42ca592a8d..6893ab3dbd 100644 --- a/lustre/cmm/cmm_split.c +++ b/lustre/cmm/cmm_split.c @@ -707,7 +707,7 @@ int cmm_split_dir(const struct lu_env *env, struct md_object *mo) LASSERT(ma->ma_valid & MA_LMV); buf = cmm_buf_get(env, ma->ma_lmv, ma->ma_lmv_size); rc = mo_xattr_set(env, md_object_next(mo), buf, - MDS_LMV_MD_NAME, 0); + MDS_LMV_MD_NAME, 0, NULL); if (rc) { CERROR("Can't set MEA to master dir, " "rc %d\n", rc); GOTO(cleanup, rc); diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index cf83ef1913..378a8fc96c 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -356,6 +356,7 @@ enum la_valid { LA_NLINK = 1 << 10, LA_RDEV = 1 << 11, LA_BLKSIZE = 1 << 12, + LA_TRUNC = 1 << 13, }; struct lu_attr { diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 0273ab1880..9d4913f768 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1295,6 +1295,9 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa); #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_TRUNC 0x10000ULL /* = 65536 */ + +#define ATTR_TRUNC MDS_ATTR_TRUNC #ifndef FMODE_READ #define FMODE_READ 00000001 @@ -1544,7 +1547,7 @@ struct mdt_rec_setxattr { __u32 sx_padding_2; __u32 sx_padding_3; __u64 sx_valid; - __u64 sx_padding_4; + __u64 sx_time; __u64 sx_padding_5; __u64 sx_padding_6; __u64 sx_padding_7; diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index 432cf0d858..bc677599e6 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -186,10 +186,10 @@ struct md_object_operations { int (*moo_xattr_set)(const struct lu_env *env, struct md_object *obj, const struct lu_buf *buf, const char *name, - int fl); + int fl, const struct lu_attr *la); int (*moo_xattr_del)(const struct lu_env *env, struct md_object *obj, - const char *name); + const char *name, const struct lu_attr *la); int (*moo_readpage)(const struct lu_env *env, struct md_object *obj, const struct lu_rdpg *rdpg); @@ -452,20 +452,22 @@ static inline int mo_xattr_get(const struct lu_env *env, static inline int mo_xattr_del(const struct lu_env *env, struct md_object *m, - const char *name) + const char *name, + const struct lu_attr *la) { LASSERT(m->mo_ops->moo_xattr_del); - return m->mo_ops->moo_xattr_del(env, m, name); + return m->mo_ops->moo_xattr_del(env, m, name, la); } static inline int mo_xattr_set(const struct lu_env *env, struct md_object *m, const struct lu_buf *buf, const char *name, - int flags) + int flags, + const struct lu_attr *la) { LASSERT(m->mo_ops->moo_xattr_set); - return m->mo_ops->moo_xattr_set(env, m, buf, name, flags); + return m->mo_ops->moo_xattr_set(env, m, buf, name, flags, la); } static inline int mo_xattr_list(const struct lu_env *env, diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 42d6b4e156..48d5efa8a4 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -730,7 +730,7 @@ int llu_setattr_raw(struct inode *inode, struct iattr *attr) RETURN(-EFBIG); } - attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; + attr->ia_valid |= ATTR_MTIME | ATTR_CTIME | ATTR_TRUNC; } /* We mark all of the fields "set" so MDS/OST does not re-set them */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 76104a93cc..0d2e1cab9d 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1404,7 +1404,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) RETURN(-EFBIG); } - attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; + attr->ia_valid |= ATTR_MTIME | ATTR_CTIME | ATTR_TRUNC; } /* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */ diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index a6bc50f3bc..4d7cdf261d 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -274,6 +274,8 @@ static inline __u64 attr_pack(unsigned int ia_valid) { sa_valid |= MDS_ATTR_FROM_OPEN; if (ia_valid & ATTR_BLOCKS) sa_valid |= MDS_ATTR_BLOCKS; + if (ia_valid & ATTR_TRUNC) + sa_valid |= MDS_ATTR_TRUNC; if (ia_valid & MDS_OPEN_OWNEROVERRIDE) /* NFSD hack (see bug 5781) */ sa_valid |= MDS_OPEN_OWNEROVERRIDE; diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 7148cf9401..cb4b12da78 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -364,9 +364,10 @@ static int mdc_xattr_common(struct obd_export *exp,const struct req_format *fmt, rec->sx_fsgid = current->fsgid; rec->sx_cap = current->cap_effective; rec->sx_suppgid1 = suppgid; - rec->sx_suppgid1 = -1; + rec->sx_suppgid2 = -1; rec->sx_fid = *fid; - rec->sx_valid = valid; + rec->sx_valid = valid | OBD_MD_FLCTIME; + rec->sx_time = cfs_time_current_sec(); rec->sx_size = output_size; rec->sx_flags = flags; diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index c90f83ba01..ba4b1e3c7a 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -558,12 +558,12 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_tobj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_tobj, la, handle, 0); if (rc) GOTO(out_unlock, rc); la->la_valid = LA_CTIME; - rc = mdd_attr_set_internal(env, mdd_sobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_sobj, la, handle, 0); EXIT; out_unlock: mdd_write_unlock(env, mdd_sobj); @@ -666,12 +666,12 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_pobj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_pobj, la, handle, 0); if (rc) GOTO(cleanup, rc); la->la_valid = LA_CTIME; - rc = mdd_attr_set_internal(env, mdd_cobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_cobj, la, handle, 0); if (rc) GOTO(cleanup, rc); @@ -753,7 +753,8 @@ static int mdd_name_insert(const struct lu_env *env, if (ma->ma_attr.la_valid & LA_CTIME) { la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_obj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_obj, la, + handle, 0); } EXIT; out_unlock: @@ -825,7 +826,8 @@ static int mdd_name_remove(const struct lu_env *env, if (ma->ma_attr.la_valid & LA_CTIME) { la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_obj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_obj, la, + handle, 0); } EXIT; out_unlock: @@ -910,7 +912,7 @@ static int mdd_rename_tgt(const struct lu_env *env, la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_tpobj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_tpobj, la, handle, 0); if (rc) GOTO(cleanup, rc); @@ -927,7 +929,7 @@ static int mdd_rename_tgt(const struct lu_env *env, mdo_ref_del(env, mdd_tobj, handle); la->la_valid = LA_CTIME; - rc = mdd_attr_set_internal(env, mdd_tobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0); if (rc) GOTO(cleanup, rc); @@ -1361,7 +1363,7 @@ static int mdd_create(const struct lu_env *env, *la = ma->ma_attr; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_pobj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_pobj, la, handle, 0); if (rc) GOTO(cleanup, rc); @@ -1568,7 +1570,8 @@ static int mdd_rename(const struct lu_env *env, /* XXX: mdd_sobj must be local one if it is NOT NULL. */ if (mdd_sobj) { la->la_valid = LA_CTIME; - rc = mdd_attr_set_internal_locked(env, mdd_sobj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_sobj, la, + handle, 0); if (rc) GOTO(cleanup, rc); } @@ -1587,7 +1590,7 @@ static int mdd_rename(const struct lu_env *env, mdo_ref_del(env, mdd_tobj, handle); la->la_valid = LA_CTIME; - rc = mdd_attr_set_internal(env, mdd_tobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0); if (rc) GOTO(cleanup, rc); @@ -1598,13 +1601,13 @@ static int mdd_rename(const struct lu_env *env, } la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_spobj, la, handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_spobj, la, handle, 0); if (rc) GOTO(cleanup, rc); if (mdd_spobj != mdd_tpobj) { la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_set_internal_locked(env, mdd_tpobj, la, + rc = mdd_attr_check_set_internal_locked(env, mdd_tpobj, la, handle, 0); } diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index db71b9a66f..e77e84f472 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -153,9 +153,16 @@ int mdd_get_md_locked(const struct lu_env *env, struct mdd_object *obj, void *md, int *md_size, const char *name); int mdd_la_get(const struct lu_env *env, struct mdd_object *obj, struct lu_attr *la, struct lustre_capa *capa); -int mdd_attr_set_internal(const struct lu_env *env, struct mdd_object *o, - const struct lu_attr *attr, struct thandle *handle, - const int needacl); +int mdd_attr_set_internal(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr, + struct thandle *handle, + int needacl); +int mdd_attr_check_set_internal(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr, + struct thandle *handle, + int needacl); int mdd_object_kill(const struct lu_env *env, struct mdd_object *obj, struct md_attr *ma); int mdd_iattr_get(const struct lu_env *env, struct mdd_object *mdd_obj, @@ -166,10 +173,11 @@ int mdd_attr_get_internal_locked(const struct lu_env *env, int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p, struct mdd_object *c, struct md_attr *ma, struct thandle *handle); -int mdd_attr_set_internal_locked(const struct lu_env *env, - struct mdd_object *o, - const struct lu_attr *attr, - struct thandle *handle, const int needacl); +int mdd_attr_check_set_internal_locked(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr, + struct thandle *handle, + int needacl); int mdd_lmm_get_locked(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma); /* mdd_lock.c */ diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index a177f05d25..83e4a3822e 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -510,10 +510,33 @@ int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p, RETURN(rc); } +static inline int mdd_attr_check(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr) +{ + struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la; + int rc; + ENTRY; + + if (attr->la_valid & LA_CTIME) { + rc = mdd_la_get(env, obj, tmp_la, BYPASS_CAPA); + if (rc) + RETURN(rc); -int mdd_attr_set_internal(const struct lu_env *env, struct mdd_object *obj, - const struct lu_attr *attr, struct thandle *handle, - const int needacl) + if (attr->la_ctime < tmp_la->la_ctime) + attr->la_valid &= ~(LA_MTIME | LA_CTIME); + else if (attr->la_valid == LA_CTIME && + attr->la_ctime == tmp_la->la_ctime) + attr->la_valid &= ~LA_CTIME; + } + RETURN(0); +} + +int mdd_attr_set_internal(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr, + struct thandle *handle, + int needacl) { int rc; ENTRY; @@ -526,10 +549,29 @@ int mdd_attr_set_internal(const struct lu_env *env, struct mdd_object *obj, RETURN(rc); } -int mdd_attr_set_internal_locked(const struct lu_env *env, - struct mdd_object *o, - const struct lu_attr *attr, - struct thandle *handle, int needacl) +int mdd_attr_check_set_internal(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr, + struct thandle *handle, + int needacl) +{ + int rc; + ENTRY; + + rc = mdd_attr_check(env, obj, attr); + if (rc) + RETURN(rc); + + if (attr->la_valid) + rc = mdd_attr_set_internal(env, obj, attr, handle, needacl); + RETURN(rc); +} + +static int mdd_attr_set_internal_locked(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr, + struct thandle *handle, + int needacl) { int rc; ENTRY; @@ -537,12 +579,31 @@ int mdd_attr_set_internal_locked(const struct lu_env *env, needacl = needacl && (attr->la_valid & LA_MODE); if (needacl) - mdd_write_lock(env, o); + mdd_write_lock(env, obj); - rc = mdd_attr_set_internal(env, o, attr, handle, needacl); + rc = mdd_attr_set_internal(env, obj, attr, handle, needacl); if (needacl) - mdd_write_unlock(env, o); + mdd_write_unlock(env, obj); + RETURN(rc); +} + +int mdd_attr_check_set_internal_locked(const struct lu_env *env, + struct mdd_object *obj, + struct lu_attr *attr, + struct thandle *handle, + int needacl) +{ + int rc; + ENTRY; + + rc = mdd_attr_check(env, obj, attr); + if (rc) + RETURN(rc); + + if (attr->la_valid) + rc = mdd_attr_set_internal_locked(env, obj, attr, handle, + needacl); RETURN(rc); } @@ -588,16 +649,18 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, if (la->la_valid & (LA_NLINK | LA_RDEV | LA_BLKSIZE)) RETURN(-EPERM); + rc = mdd_la_get(env, obj, tmp_la, BYPASS_CAPA); + if (rc) + RETURN(rc); + /* This is only for set ctime when rename's source is on remote MDS. */ if (unlikely(la->la_valid == LA_CTIME)) { rc = mdd_may_delete(env, NULL, obj, (struct md_attr *)ma, 1, 0); + if (rc == 0 && la->la_ctime <= tmp_la->la_ctime) + la->la_valid &= ~LA_CTIME; RETURN(rc); } - rc = mdd_la_get(env, obj, tmp_la, BYPASS_CAPA); - if (rc) - RETURN(rc); - if (la->la_valid == LA_ATIME) { /* This is atime only set for read atime update on close. */ if (la->la_atime <= tmp_la->la_atime + @@ -726,16 +789,10 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, } } - /* For truncate (or setsize), we should have MAY_WRITE perm */ - if (la->la_valid & (LA_SIZE | LA_BLOCKS)) { - if (!((la->la_valid & MDS_OPEN_OWNEROVERRIDE) && - (uc->mu_fsuid == tmp_la->la_uid)) && - !(ma->ma_attr_flags & MDS_PERM_BYPASS)) { - rc = mdd_permission_internal_locked(env, obj, tmp_la, - MAY_WRITE); - if (rc) - RETURN(rc); - } + if (la->la_valid & (LA_SIZE | LA_BLOCKS) && + !(la->la_valid & LA_TRUNC)) { + /* For "Size-on-MDS" case, the MAY_WRITE perm + * has been checked when file open. */ /* For the "Size-on-MDS" setattr update, merge coming * attributes with the set in the inode. BUG 10641 */ @@ -748,11 +805,25 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, if ((la->la_valid & LA_CTIME) && (la->la_ctime <= tmp_la->la_ctime)) la->la_valid &= ~(LA_MTIME | LA_CTIME); - } else if (la->la_valid & LA_CTIME) { - /* The pure setattr, it has the priority over what is already - * set, do not drop it if ctime is equal. */ - if (la->la_ctime < tmp_la->la_ctime) - la->la_valid &= ~(LA_ATIME | LA_MTIME | LA_CTIME); + } else { + if (la->la_valid & LA_TRUNC) { + /* For truncate, we should have MAY_WRITE perm. */ + if (!((la->la_valid & MDS_OPEN_OWNEROVERRIDE) && + (uc->mu_fsuid == tmp_la->la_uid)) && + !(ma->ma_attr_flags & MDS_PERM_BYPASS)) { + rc = mdd_permission_internal_locked(env, obj, + tmp_la, MAY_WRITE); + if (rc) + RETURN(rc); + } + } + if (la->la_valid & LA_CTIME) { + /* The pure setattr, it has the priority over what is + * already set, do not drop it if ctime is equal. */ + if (la->la_ctime < tmp_la->la_ctime) + la->la_valid &= ~(LA_ATIME | LA_MTIME | + LA_CTIME); + } } RETURN(0); @@ -881,7 +952,8 @@ static int mdd_xattr_sanity_check(const struct lu_env *env, } static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, - const struct lu_buf *buf, const char *name, int fl) + const struct lu_buf *buf, const char *name, + int fl, const struct lu_attr *la) { struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; struct mdd_object *mdd_obj = md2mdd_obj(obj); @@ -899,13 +971,13 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, if (IS_ERR(handle)) RETURN(PTR_ERR(handle)); - rc = mdd_xattr_set_txn(env, md2mdd_obj(obj), buf, name, - fl, handle); - if (rc == 0) { - la_copy->la_ctime = cfs_time_current_sec(); + rc = mdd_xattr_set_txn(env, mdd_obj, buf, name, fl, handle); + if (rc == 0 && likely(la != NULL)) { + LASSERT(la->la_valid & LA_CTIME); + la_copy->la_ctime = la->la_ctime; la_copy->la_valid = LA_CTIME; - rc = mdd_attr_set_internal_locked(env, mdd_obj, la_copy, - handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_obj, la_copy, + handle, 0); } mdd_trans_stop(env, mdd, rc, handle); @@ -913,7 +985,7 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, } int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, - const char *name) + const char *name, const struct lu_attr *la) { struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; struct mdd_object *mdd_obj = md2mdd_obj(obj); @@ -932,14 +1004,15 @@ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, RETURN(PTR_ERR(handle)); mdd_write_lock(env, mdd_obj); - rc = mdo_xattr_del(env, md2mdd_obj(obj), name, handle, + rc = mdo_xattr_del(env, mdd_obj, name, handle, mdd_object_capa(env, mdd_obj)); mdd_write_unlock(env, mdd_obj); - if (rc == 0) { - la_copy->la_ctime = cfs_time_current_sec(); + if (rc == 0 && likely(la != NULL)) { + LASSERT(la->la_valid & LA_CTIME); + la_copy->la_ctime = la->la_ctime; la_copy->la_valid = LA_CTIME; - rc = mdd_attr_set_internal_locked(env, mdd_obj, la_copy, - handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_obj, la_copy, + handle, 0); } mdd_trans_stop(env, mdd, rc, handle); @@ -992,7 +1065,7 @@ static int mdd_ref_del(const struct lu_env *env, struct md_object *obj, la_copy->la_ctime = ma->ma_attr.la_ctime; la_copy->la_valid = LA_CTIME; - rc = mdd_attr_set_internal(env, mdd_obj, la_copy, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_obj, la_copy, handle, 0); if (rc) GOTO(cleanup, rc); @@ -1071,7 +1144,8 @@ static int mdd_object_create(const struct lu_env *env, if (rc) GOTO(unlock, rc); - rc = mdd_attr_set_internal(env, mdd_obj, &ma->ma_attr, handle, 0); + rc = mdd_attr_set_internal(env, mdd_obj, &ma->ma_attr, + handle, 0); } else { #ifdef CONFIG_FS_POSIX_ACL if (spec->sp_cr_flags & MDS_CREATE_RMT_ACL) { @@ -1130,8 +1204,8 @@ static int mdd_ref_add(const struct lu_env *env, struct md_object *obj, la_copy->la_ctime = ma->ma_attr.la_ctime; la_copy->la_valid = LA_CTIME; - rc = mdd_attr_set_internal_locked(env, mdd_obj, la_copy, - handle, 0); + rc = mdd_attr_check_set_internal_locked(env, mdd_obj, la_copy, + handle, 0); } mdd_trans_stop(env, mdd, 0, handle); diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 0d36467884..85ce484ec0 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -630,6 +630,8 @@ static inline unsigned int attr_unpack(__u64 sa_valid) { ia_valid |= ATTR_FROM_OPEN; if (sa_valid & MDS_ATTR_BLOCKS) ia_valid |= ATTR_BLOCKS; + if (sa_valid & MDS_ATTR_TRUNC) + ia_valid |= ATTR_TRUNC; if (sa_valid & MDS_OPEN_OWNEROVERRIDE) ia_valid |= MDS_OPEN_OWNEROVERRIDE; return ia_valid; @@ -667,6 +669,9 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr, if (in & ATTR_ATTR_FLAG) out |= LA_FLAGS; + if (in & ATTR_TRUNC) + out |= LA_TRUNC; + if (in & MDS_OPEN_OWNEROVERRIDE) out |= MDS_OPEN_OWNEROVERRIDE; @@ -674,7 +679,7 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr, in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_BLOCKS| ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN| ATTR_ATIME_SET|ATTR_CTIME_SET|ATTR_MTIME_SET| - ATTR_ATTR_FLAG|ATTR_RAW|MDS_OPEN_OWNEROVERRIDE); + ATTR_ATTR_FLAG|ATTR_RAW|ATTR_TRUNC|MDS_OPEN_OWNEROVERRIDE); if (in != 0) CERROR("Unknown attr bits: %#llx\n", in); return out; @@ -1138,11 +1143,13 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) uc->mu_fsuid = rec->sx_fsuid; uc->mu_fsgid = rec->sx_fsgid; uc->mu_cap = rec->sx_cap; - uc->mu_suppgids[0] = uc->mu_suppgids[1] = -1; + uc->mu_suppgids[0] = rec->sx_suppgid1; + uc->mu_suppgids[1] = -1; rr->rr_opcode = rec->sx_opcode; rr->rr_fid1 = &rec->sx_fid; attr->la_valid = rec->sx_valid; + attr->la_ctime = rec->sx_time; attr->la_size = rec->sx_size; attr->la_flags = rec->sx_flags; diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c index 83ecc742f9..c1eae8d2d2 100644 --- a/lustre/mdt/mdt_xattr.c +++ b/lustre/mdt/mdt_xattr.c @@ -59,7 +59,7 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) RETURN(-ENOMEM); /* Determine how many bytes we need */ - if ((valid & OBD_MD_FLXATTR) == OBD_MD_FLXATTR) { + if (valid & OBD_MD_FLXATTR) { xattr_name = req_capsule_client_get(pill, &RMF_NAME); if (!xattr_name) RETURN(-EFAULT); @@ -71,7 +71,7 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) size = mo_xattr_get(info->mti_env, mdt_object_child(info->mti_object), &LU_BUF_NULL, xattr_name); - } else if ((valid & OBD_MD_FLXATTRLS) == OBD_MD_FLXATTRLS) { + } else if (valid & OBD_MD_FLXATTRLS) { size = mo_xattr_list(info->mti_env, mdt_object_child(info->mti_object), &LU_BUF_NULL); @@ -330,8 +330,15 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, if (IS_ERR(obj)) GOTO(out, rc = PTR_ERR(obj)); + if (unlikely(!(valid & OBD_MD_FLCTIME))) { + CWARN("client miss to set OBD_MD_FLCTIME when " + "setxattr: [object "DFID"] [valid %llu]\n", + PFID(rr->rr_fid1), valid); + attr->la_ctime = cfs_time_current_sec(); + } + attr->la_valid = LA_CTIME; child = mdt_object_child(obj); - if ((valid & OBD_MD_FLXATTR) == OBD_MD_FLXATTR) { + if (valid & OBD_MD_FLXATTR) { char * xattr; if (!req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) { @@ -368,10 +375,10 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, buf->lb_buf = xattr; buf->lb_len = xattr_len; - rc = mo_xattr_set(env, child, buf, xattr_name, flags); + rc = mo_xattr_set(env, child, buf, xattr_name, flags, attr); } - } else if ((valid & OBD_MD_FLXATTRRM) == OBD_MD_FLXATTRRM) { - rc = mo_xattr_del(env, child, xattr_name); + } else if (valid & OBD_MD_FLXATTRRM) { + rc = mo_xattr_del(env, child, xattr_name, attr); } else { CDEBUG(D_INFO, "valid bits: "LPX64"\n", valid); rc = -EINVAL; diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c index 25df3a4667..fe067c365d 100644 --- a/lustre/osd/osd_handler.c +++ b/lustre/osd/osd_handler.c @@ -1366,12 +1366,12 @@ static int osd_xattr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, const char *name, int fl, struct thandle *handle, struct lustre_capa *capa) { - int fs_flags; - struct osd_object *obj = osd_dt_obj(dt); struct inode *inode = obj->oo_inode; struct osd_thread_info *info = osd_oti_get(env); struct dentry *dentry = &info->oti_dentry; + struct timespec *t = &info->oti_time; + int fs_flags = 0, rc; LASSERT(dt_object_exists(dt)); LASSERT(inode->i_op != NULL && inode->i_op->setxattr != NULL); @@ -1381,17 +1381,24 @@ static int osd_xattr_set(const struct lu_env *env, struct dt_object *dt, if (osd_object_auth(env, dt, capa, CAPA_OPC_META_WRITE)) return -EACCES; - dentry->d_inode = inode; - - fs_flags = 0; if (fl & LU_XATTR_REPLACE) fs_flags |= XATTR_REPLACE; if (fl & LU_XATTR_CREATE) fs_flags |= XATTR_CREATE; - return inode->i_op->setxattr(dentry, name, - buf->lb_buf, buf->lb_len, fs_flags); + dentry->d_inode = inode; + *t = inode->i_ctime; + rc = inode->i_op->setxattr(dentry, name, + buf->lb_buf, buf->lb_len, fs_flags); + if (likely(rc == 0)) { + /* ctime should not be updated with server-side time. */ + spin_lock(&obj->oo_guard); + inode->i_ctime = *t; + spin_unlock(&obj->oo_guard); + mark_inode_dirty(inode); + } + return rc; } /* @@ -1431,6 +1438,8 @@ static int osd_xattr_del(const struct lu_env *env, struct inode *inode = obj->oo_inode; struct osd_thread_info *info = osd_oti_get(env); struct dentry *dentry = &info->oti_dentry; + struct timespec *t = &info->oti_time; + int rc; LASSERT(dt_object_exists(dt)); LASSERT(inode->i_op != NULL && inode->i_op->removexattr != NULL); @@ -1441,7 +1450,16 @@ static int osd_xattr_del(const struct lu_env *env, return -EACCES; dentry->d_inode = inode; - return inode->i_op->removexattr(dentry, name); + *t = inode->i_ctime; + rc = inode->i_op->removexattr(dentry, name); + if (likely(rc == 0)) { + /* ctime should not be updated with server-side time. */ + spin_lock(&obj->oo_guard); + inode->i_ctime = *t; + spin_unlock(&obj->oo_guard); + mark_inode_dirty(inode); + } + return rc; } static struct obd_capa *osd_capa_get(const struct lu_env *env, -- GitLab