Whamcloud - gitweb
Branch HEAD
authorfanyong <fanyong>
Tue, 15 Jul 2008 02:33:55 +0000 (02:33 +0000)
committerfanyong <fanyong>
Tue, 15 Jul 2008 02:33:55 +0000 (02:33 +0000)
b=15797
i=Nikita
i=Vitaly

(1)Replace "la->la_valid" with "ma->ma_attr_flags" to pass
   "MDS_OPEN_OWNEROVERRIDE".
(2)Drop "lu_attr" parameter for xattr_{set,del} method.
   The caller should guarantee to update the object ctime.
(3)MDT can detect whether the "setattr" is SOM case or
   truncate case, it is unnecessary to pass special flag
   ("MDS_ATTR_TRUNC") from client to MDT for truncate case.

13 files changed:
lustre/cmm/cmm_object.c
lustre/cmm/cmm_split.c
lustre/include/lu_object.h
lustre/include/lustre/lustre_idl.h
lustre/include/md_object.h
lustre/liblustre/super.c
lustre/llite/llite_lib.c
lustre/mdc/mdc_lib.c
lustre/mdd/mdd_object.c
lustre/mdt/mdt_lib.c
lustre/mdt/mdt_open.c
lustre/mdt/mdt_reint.c
lustre/mdt/mdt_xattr.c

index 3cb6962..cb61d3b 100644 (file)
@@ -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;
 }
index 6893ab3..42ca592 100644 (file)
@@ -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);
index 6a74131..3b000e0 100644 (file)
@@ -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 {
index 82270b7..2770087 100644 (file)
@@ -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 {
index bc67759..432cf0d 100644 (file)
@@ -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,
index 5789360..8525b92 100644 (file)
@@ -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 */
index 63a52b5..c82e835 100644 (file)
@@ -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) */
index 4d7cdf2..a6bc50f 100644 (file)
@@ -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;
index ec6f727..ca302fb 100644 (file)
@@ -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);
index 85ce484..a4b4bce 100644 (file)
@@ -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;
index b71a9e8..9648d45 100644 (file)
@@ -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));
index fb9f7eb..0eb52a0 100644 (file)
@@ -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);
index c1eae8d..271d497 100644 (file)
@@ -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;