diff --git a/lustre/cmm/cmm_object.c b/lustre/cmm/cmm_object.c index 3cb6962f02d7f8ffe34c37d2bd1d421769d7a8aa..cb61d3b574a5ddfde2a446a1f6104f95685d7552 100644 --- a/lustre/cmm/cmm_object.c +++ b/lustre/cmm/cmm_object.c @@ -259,20 +259,20 @@ 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_attr *la) + int fl) { int rc; ENTRY; - rc = mo_xattr_set(env, md_object_next(mo), buf, name, fl, la); + rc = mo_xattr_set(env, md_object_next(mo), buf, name, fl); RETURN(rc); } static int cml_xattr_del(const struct lu_env *env, struct md_object *mo, - const char *name, const struct lu_attr *la) + const char *name) { int rc; ENTRY; - rc = mo_xattr_del(env, md_object_next(mo), name, la); + rc = mo_xattr_del(env, md_object_next(mo), name); RETURN(rc); } @@ -878,13 +878,13 @@ 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_attr *la) + int fl) { return -EFAULT; } static int cmr_xattr_del(const struct lu_env *env, struct md_object *mo, - const char *name, const struct lu_attr *la) + const char *name) { return -EFAULT; } diff --git a/lustre/cmm/cmm_split.c b/lustre/cmm/cmm_split.c index 6893ab3dbda71efc2498d2af1d696b168f88e767..42ca592a8d5b0376cde55f8f9c4be6be4dfa4399 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, NULL); + MDS_LMV_MD_NAME, 0); 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 6a74131fbf45f9f6f31fd89634d82fed6f4f66f2..3b000e0703a0c75ddcdb3a858126b60e4c80e15c 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -355,7 +355,6 @@ 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 82270b71b02728c2780144f7bff5f5de4dd1a63b..2770087fa07bd5830982b490834a6f5c064f852d 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1302,9 +1302,6 @@ 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 @@ -1360,7 +1357,8 @@ enum { MDS_CHECK_SPLIT = 1 << 0, MDS_CROSS_REF = 1 << 1, MDS_VTX_BYPASS = 1 << 2, - MDS_PERM_BYPASS = 1 << 3 + MDS_PERM_BYPASS = 1 << 3, + MDS_SOM = 1 << 4 }; struct mds_rec_join { diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index bc677599e6425bf98c3e57d85a3fcb5d0369241a..432cf0d858f2b022fc98142530f3ebb43fb80cdf 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, const struct lu_attr *la); + int fl); int (*moo_xattr_del)(const struct lu_env *env, struct md_object *obj, - const char *name, const struct lu_attr *la); + const char *name); int (*moo_readpage)(const struct lu_env *env, struct md_object *obj, const struct lu_rdpg *rdpg); @@ -452,22 +452,20 @@ 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 struct lu_attr *la) + const char *name) { LASSERT(m->mo_ops->moo_xattr_del); - return m->mo_ops->moo_xattr_del(env, m, name, la); + return m->mo_ops->moo_xattr_del(env, m, name); } 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, - const struct lu_attr *la) + int flags) { LASSERT(m->mo_ops->moo_xattr_set); - return m->mo_ops->moo_xattr_set(env, m, buf, name, flags, la); + return m->mo_ops->moo_xattr_set(env, m, buf, name, flags); } static inline int mo_xattr_list(const struct lu_env *env, diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 57893609e68b64639e0b047c5c98706071c102af..8525b927c651ed94500310922e83a56b79031f26 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_TRUNC; + attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; } /* 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 63a52b5e57cfb88d961a3e95da8fe83e7756aeb9..c82e8354ba29f373eb2601eaafdbed98bee1025c 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1408,7 +1408,7 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) RETURN(-EFBIG); } - attr->ia_valid |= ATTR_MTIME | ATTR_CTIME | ATTR_TRUNC; + attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; } /* 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 4d7cdf261dfaaca6bc7ec4bfba2e2aa73c7e7f24..a6bc50f3bcc650dbadeb0af6c3887dead78f1232 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -274,8 +274,6 @@ 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/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index ec6f727151f94efd78e818f95eb087e5b333603f..ca302fb17cf689c92299bbf4f7a5923d31f16649 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -513,6 +513,9 @@ int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p, RETURN(rc); } +/** + * Make sure the ctime is increased only. + */ static inline int mdd_attr_check(const struct lu_env *env, struct mdd_object *obj, struct lu_attr *attr) @@ -580,12 +583,9 @@ static int mdd_attr_set_internal_locked(const struct lu_env *env, ENTRY; needacl = needacl && (attr->la_valid & LA_MODE); - if (needacl) mdd_write_lock(env, obj); - rc = mdd_attr_set_internal(env, obj, attr, handle, needacl); - if (needacl) mdd_write_unlock(env, obj); RETURN(rc); @@ -600,13 +600,12 @@ int mdd_attr_check_set_internal_locked(const struct lu_env *env, 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); + needacl = needacl && (attr->la_valid & LA_MODE); + if (needacl) + mdd_write_lock(env, obj); + rc = mdd_attr_check_set_internal(env, obj, attr, handle, needacl); + if (needacl) + mdd_write_unlock(env, obj); RETURN(rc); } @@ -656,9 +655,12 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, 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 (la->la_valid == LA_CTIME) { + if (!(ma->ma_attr_flags & MDS_PERM_BYPASS)) + /* This is only for set ctime when rename's source is + * on remote MDS. */ + 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); @@ -715,10 +717,8 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, /* Make sure a caller can chmod. */ if (la->la_valid & LA_MODE) { - /* - * Bypass la_vaild == LA_MODE, - * this is for changing file with SUID or SGID. - */ + /* Bypass la_vaild == LA_MODE, + * this is for changing file with SUID or SGID. */ if ((la->la_valid & ~LA_MODE) && (uc->mu_fsuid != tmp_la->la_uid) && !mdd_capable(uc, CAP_FOWNER)) @@ -747,8 +747,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, !mdd_capable(uc, CAP_CHOWN)) RETURN(-EPERM); - /* - * If the user or group of a non-directory has been + /* If the user or group of a non-directory has been * changed by a non-root user, remove the setuid bit. * 19981026 David C Niemi <niemi@tux.org> * @@ -756,8 +755,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, * to avoid some races. This is the behavior we had in * 2.0. The check for non-root was definitely wrong * for 2.2 anyway, as it should have been using - * CAP_FSETID rather than fsuid -- 19990830 SD. - */ + * CAP_FSETID rather than fsuid -- 19990830 SD. */ if (((tmp_la->la_mode & S_ISUID) == S_ISUID) && !S_ISDIR(tmp_la->la_mode)) { la->la_mode &= ~S_ISUID; @@ -775,16 +773,14 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, !mdd_capable(uc, CAP_CHOWN)) RETURN(-EPERM); - /* - * Likewise, if the user or group of a non-directory + /* Likewise, if the user or group of a non-directory * has been changed by a non-root user, remove the * setgid bit UNLESS there is no group execute bit * (this would be a file marked for mandatory * locking). 19981026 David C Niemi <niemi@tux.org> * * Removed the fsuid check (see the comment above) -- - * 19990830 SD. - */ + * 19990830 SD. */ if (((tmp_la->la_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) && !S_ISDIR(tmp_la->la_mode)) { la->la_mode &= ~S_ISGID; @@ -792,11 +788,13 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, } } - 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 both Size-on-MDS case and truncate case, + * "la->la_valid & (LA_SIZE | LA_BLOCKS)" are ture. + * We distinguish them by "ma->ma_attr_flags & MDS_SOM". + * For SOM case, it is true, the MAY_WRITE perm has been checked + * when open, no need check again. For truncate case, it is false, + * the MAY_WRITE perm should be checked here. */ + if (ma->ma_attr_flags & MDS_SOM) { /* For the "Size-on-MDS" setattr update, merge coming * attributes with the set in the inode. BUG 10641 */ if ((la->la_valid & LA_ATIME) && @@ -809,9 +807,8 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, (la->la_ctime <= tmp_la->la_ctime)) la->la_valid &= ~(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) && + if (la->la_valid & (LA_SIZE | LA_BLOCKS)) { + if (!((ma->ma_attr_flags & MDS_OPEN_OWNEROVERRIDE) && (uc->mu_fsuid == tmp_la->la_uid)) && !(ma->ma_attr_flags & MDS_PERM_BYPASS)) { rc = mdd_permission_internal_locked(env, obj, @@ -954,11 +951,14 @@ static int mdd_xattr_sanity_check(const struct lu_env *env, RETURN(rc); } +/** + * The caller should guarantee to update the object ctime + * after xattr_set if needed. + */ 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_attr *la) + int fl) { - struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; struct mdd_object *mdd_obj = md2mdd_obj(obj); struct mdd_device *mdd = mdo2mdd(obj); struct thandle *handle; @@ -975,22 +975,18 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, RETURN(PTR_ERR(handle)); 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_check_set_internal_locked(env, mdd_obj, la_copy, - handle, 0); - } mdd_trans_stop(env, mdd, rc, handle); RETURN(rc); } +/** + * The caller should guarantee to update the object ctime + * after xattr_set if needed. + */ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, - const char *name, const struct lu_attr *la) + const char *name) { - struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; struct mdd_object *mdd_obj = md2mdd_obj(obj); struct mdd_device *mdd = mdo2mdd(obj); struct thandle *handle; @@ -1010,14 +1006,6 @@ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, rc = mdo_xattr_del(env, mdd_obj, name, handle, mdd_object_capa(env, mdd_obj)); mdd_write_unlock(env, mdd_obj); - 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_check_set_internal_locked(env, mdd_obj, la_copy, - handle, 0); - } - mdd_trans_stop(env, mdd, rc, handle); RETURN(rc); diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 85ce484ec03e268f87493ca44d5677be0cfe6d51..a4b4bcef379691dbe36fb89af276723d46b31c1d 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -630,8 +630,6 @@ 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; @@ -669,17 +667,14 @@ 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; + ma->ma_attr_flags |= MDS_OPEN_OWNEROVERRIDE; /*XXX need ATTR_RAW?*/ 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|ATTR_TRUNC|MDS_OPEN_OWNEROVERRIDE); + ATTR_ATTR_FLAG|ATTR_RAW|MDS_OPEN_OWNEROVERRIDE); if (in != 0) CERROR("Unknown attr bits: %#llx\n", in); return out; diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index b71a9e8c83c688eccb0d56918a971316ce653c0c..9648d4551fac8dbc12bb463fb1f89ce647f6ba0c 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -194,7 +194,7 @@ static int mdt_sizeonmds_update(struct mdt_thread_info *info, * and "close", maybe someone has changed the file mode * or flags, or the file created mode do not permit wirte, * and so on. Just set MDS_PERM_BYPASS for all the cases. */ - info->mti_attr.ma_attr_flags |= MDS_PERM_BYPASS; + info->mti_attr.ma_attr_flags |= MDS_PERM_BYPASS | MDS_SOM; info->mti_attr.ma_attr.la_valid &= LA_SIZE | LA_BLOCKS | LA_ATIME | LA_MTIME | LA_CTIME; RETURN(mdt_attr_set(info, o, 0)); diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index fb9f7eba6d3ffeb48277475f79cb545b3fc362cb..0eb52a01c52ec66b95064cc56778d80108dc5402 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -332,6 +332,9 @@ static int mdt_reint_setattr(struct mdt_thread_info *info, repbody->handle.cookie = mfd->mfd_handle.h_cookie; } + if (info->mti_epoch && (info->mti_epoch->flags & MF_SOM_CHANGE)) + ma->ma_attr_flags |= MDS_PERM_BYPASS | MDS_SOM; + rc = mdt_attr_set(info, mo, rr->rr_flags); if (rc) GOTO(out_put, rc); diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c index c1eae8d2d22f7e9723dd02ecb8862587ddf4a2aa..271d49774a4050484fcddfd0c869d7f5503d8b16 100644 --- a/lustre/mdt/mdt_xattr.c +++ b/lustre/mdt/mdt_xattr.c @@ -270,6 +270,7 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, const struct lu_env *env = info->mti_env; struct lu_buf *buf = &info->mti_buf; struct mdt_reint_record *rr = &info->mti_rr; + struct md_attr *ma = &info->mti_attr; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_object *obj; struct md_object *child; @@ -375,10 +376,20 @@ 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, attr); + rc = mo_xattr_set(env, child, buf, xattr_name, flags); + /* update ctime after xattr changed */ + if (rc == 0) { + ma->ma_attr_flags |= MDS_PERM_BYPASS; + mo_attr_set(env, child, ma); + } } } else if (valid & OBD_MD_FLXATTRRM) { - rc = mo_xattr_del(env, child, xattr_name, attr); + rc = mo_xattr_del(env, child, xattr_name); + /* update ctime after xattr changed */ + if (rc == 0) { + ma->ma_attr_flags |= MDS_PERM_BYPASS; + mo_attr_set(env, child, ma); + } } else { CDEBUG(D_INFO, "valid bits: "LPX64"\n", valid); rc = -EINVAL;