Whamcloud - gitweb
Branch: b_new_cmd
authorwangdi <wangdi>
Sun, 13 Aug 2006 17:36:07 +0000 (17:36 +0000)
committerwangdi <wangdi>
Sun, 13 Aug 2006 17:36:07 +0000 (17:36 +0000)
1) add ma_need to indicate which field it need when it call the lower layer
2) reorganize mdd setattr/getattr code.
3) fix some problems in set/get md.
4) prepare the reply buffer for close.
5) some other fixes and cleanup

13 files changed:
lustre/include/lustre_mds.h
lustre/include/md_object.h
lustre/mdd/mdd_handler.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_lov.c
lustre/mds/mds_internal.h
lustre/mds/mds_log.c
lustre/mds/mds_reint.c
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lib.c
lustre/mdt/mdt_open.c
lustre/mdt/mdt_reint.c

index 00ba485..33a90ee 100644 (file)
@@ -90,6 +90,9 @@ int mds_log_op_unlink(struct obd_device *obd, struct inode *inode,
 int mds_log_op_setattr(struct obd_device *obd, struct inode *inode,
                       struct lov_mds_md *lmm, int lmm_size,
                       struct llog_cookie *logcookies, int cookies_size);
+int mds_osc_setattr_async(struct obd_device *obd, __u32 uid, __u32 gid,
+                          struct lov_mds_md *lmm, int lmm_size,
+                          struct llog_cookie *logcookies, __u64 id, __u32 gen);
 
 /* ioctls for trying requests */
 #define IOC_REQUEST_TYPE                   'f'
index 18a2053..242993b 100644 (file)
@@ -54,13 +54,24 @@ enum ma_valid {
 };
 
 struct md_attr {
-        __u64                   ma_valid;
+        __u64                   ma_valid;  
+        __u64                   ma_need;  
+        __u64                   ma_attr_flags;
         struct lu_attr          ma_attr;
         struct lov_mds_md      *ma_lmm;
         int                     ma_lmm_size;
         struct llog_cookie     *ma_cookie;
         int                     ma_cookie_size;
 };
+
+enum md_attr_flags {
+        MD_ATIME_SET      = 1 << 0,
+        MD_MTIME_SET      = 1 << 1,
+        MD_CTIME_SET      = 1 << 2,
+        MD_ATTR_FLAG      = 1 << 3, 
+        MD_ATTR_RAW       = 1 << 4
+};
+
 /* additional parameters for create */
 struct md_create_spec {
         union {
index 70bc64a..796b834 100644 (file)
@@ -50,10 +50,6 @@ static struct thandle* mdd_trans_start(const struct lu_context *ctxt,
 static void mdd_trans_stop(const struct lu_context *ctxt,
                            struct mdd_device *mdd, struct thandle *handle);
 static struct dt_object* mdd_object_child(struct mdd_object *o);
-static void mdd_lock(const struct lu_context *ctx,
-                     struct mdd_object *obj, enum dt_lock_mode mode);
-static void mdd_unlock(const struct lu_context *ctx,
-                       struct mdd_object *obj, enum dt_lock_mode mode);
 static void __mdd_ref_add(const struct lu_context *ctxt, struct mdd_object *obj,
                           struct thandle *handle);
 static void __mdd_ref_del(const struct lu_context *ctxt, struct mdd_object *obj,
@@ -152,11 +148,6 @@ static inline void mdd_object_put(const struct lu_context *ctxt,
         lu_object_put(ctxt, &o->mod_obj.mo_lu);
 }
 
-static umode_t mdd_object_type(const struct mdd_object *obj)
-{
-        return lu_object_attr(&obj->mod_obj.mo_lu);
-}
-
 static void mdd_set_dead_obj(struct mdd_object *obj)
 {
         if (obj)
@@ -216,66 +207,65 @@ static int mdd_may_delete(const struct lu_context *ctxt,
         RETURN(rc);
 }
 
-static int __mdd_attr_get(const struct lu_context *ctxt,
-                          struct mdd_object *obj, struct md_attr *ma)
+static int __mdd_lmm_get(const struct lu_context *ctxt,
+                         struct mdd_object *obj, struct md_attr *ma)
 {
-        struct dt_object  *next;
-        int                rc;
-
-        ENTRY;
-
-        LASSERT(lu_object_exists(ctxt, mdd2lu_obj(obj)));
+        int rc;
 
-        next = mdd_object_child(obj);
-        rc = next->do_ops->do_attr_get(ctxt, next, &ma->ma_attr);
-        if (rc == 0) {
-                LASSERT((ma->ma_attr.la_mode & S_IFMT) ==
-                        (lu_object_attr(mdd2lu_obj(obj)) & S_IFMT));
-                ma->ma_valid = MA_INODE;
+        LASSERT(ma->ma_lmm != NULL && ma->ma_lmm_size > 0);
+        rc = mdd_get_md(ctxt, obj, ma->ma_lmm, &ma->ma_lmm_size, 0);
+        if (rc > 0) {
+                ma->ma_valid |= MA_LOV;
+                rc = 0;
         }
-
         RETURN(rc);
 }
 
-static int __mdd_lov_get(const struct lu_context *ctxt,
-                         struct mdd_object *obj, struct md_attr *ma)
+static int mdd_attr_get_internal (const struct lu_context *ctxt,
+                                  struct mdd_object *mdd_obj, 
+                                  struct md_attr *ma, int need_locked)
 {
         struct dt_object  *next;
-        int                rc = 0;
-
+        int rc = 0;
         ENTRY;
 
-        next = mdd_object_child(obj);
-        if ((S_ISREG(ma->ma_attr.la_mode) || S_ISDIR(ma->ma_attr.la_mode))
-            && ma->ma_lmm != 0 && ma->ma_lmm_size > 0) {
-                rc = mdd_get_md(ctxt, &obj->mod_obj,
-                                ma->ma_lmm, &ma->ma_lmm_size);
-                if (rc > 0) {
-                        ma->ma_valid |= MA_LOV;
-                        rc = 0;
-                }
+        if (need_locked)
+                mdd_lock(ctxt, mdd_obj, DT_READ_LOCK);
+        if (ma->ma_need & MA_INODE) {
+                next = mdd_object_child(mdd_obj);
+                rc = next->do_ops->do_attr_get(ctxt, next, &ma->ma_attr);
+                if (rc)
+                        GOTO(out, rc);
+                ma->ma_valid = MA_INODE;
         }
 
+        if (ma->ma_need & MA_LOV) {
+                 if ((S_ISREG(ma->ma_attr.la_mode)
+                     || S_ISDIR(ma->ma_attr.la_mode))) {
+                        rc = __mdd_lmm_get(ctxt, mdd_obj, ma);
+                 }
+        }
+out:
+        CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64"\n",
+                        rc, ma->ma_valid);
+        if (need_locked)
+                mdd_unlock(ctxt, mdd_obj, DT_READ_LOCK);
         RETURN(rc);
 }
-
+        
 static int mdd_attr_get(const struct lu_context *ctxt,
                         struct md_object *obj, struct md_attr *ma)
 {
         struct mdd_object *mdd_obj = md2mdd_obj(obj);
-        struct dt_object  *next;
         int                rc;
 
         ENTRY;
 
-        next = mdd_object_child(mdd_obj);
-        rc = __mdd_attr_get(ctxt, mdd_obj, ma);
-        if (rc == 0) {
-                /* get LOV EA also */
-                rc = __mdd_lov_get(ctxt, mdd_obj, ma);
-        }
-        CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64"\n",
-                        rc, ma->ma_valid);
+        LASSERT(lu_object_exists(ctxt, &obj->mo_lu));
+
+        mdd_lock(ctxt, mdd_obj, DT_READ_LOCK);
+        rc = mdd_attr_get_internal(ctxt, mdd_obj, ma, 0);
+        mdd_unlock(ctxt, mdd_obj, DT_READ_LOCK);
         RETURN(rc);
 }
 
@@ -501,16 +491,16 @@ static struct lu_object_operations mdd_lu_obj_ops = {
        .loo_object_exists  = mdd_object_exists,
 };
 
-static void mdd_lock(const struct lu_context *ctxt,
-                     struct mdd_object *obj, enum dt_lock_mode mode)
+void mdd_lock(const struct lu_context *ctxt, struct mdd_object *obj, 
+              enum dt_lock_mode mode)
 {
         struct dt_object  *next = mdd_object_child(obj);
 
         next->do_ops->do_lock(ctxt, next, mode);
 }
 
-static void mdd_unlock(const struct lu_context *ctxt,
-                       struct mdd_object *obj, enum dt_lock_mode mode)
+void mdd_unlock(const struct lu_context *ctxt, struct mdd_object *obj, 
+                enum dt_lock_mode mode)
 {
         struct dt_object  *next = mdd_object_child(obj);
 
@@ -580,11 +570,118 @@ static int __mdd_xattr_set(const struct lu_context *ctxt, struct mdd_object *o,
                            int fl, struct thandle *handle)
 {
         struct dt_object *next;
-
+        int rc = 0;
+        
         LASSERT(lu_object_exists(ctxt, mdd2lu_obj(o)));
         next = mdd_object_child(o);
-        return next->do_ops->do_xattr_set(ctxt, next, buf, buf_len, name, fl,
-                                          handle);
+        if (buf && buf_len > 0) {
+                rc = next->do_ops->do_xattr_set(ctxt, next, buf, buf_len, name, 
+                                                0, handle);
+        }else if (buf == NULL && buf_len == 0) {
+                rc = next->do_ops->do_xattr_del(ctxt, next, name, handle);
+        }
+        RETURN(rc);
+}
+/* this gives the same functionality as the code between
+ * sys_chmod and inode_setattr
+ * chown_common and inode_setattr
+ * utimes and inode_setattr
+ * This API is ported from mds_fix_attr but remove some unnecesssary stuff.
+ * and port to 
+ */
+int mdd_fix_attr(const struct lu_context *ctxt, struct mdd_object *obj,
+                 const struct md_attr *ma)
+{
+        time_t now = CURRENT_SECONDS;
+        struct lu_attr *la = (struct lu_attr *)&ma->ma_attr;
+        struct lu_attr *tmp_la = &mdd_ctx_info(ctxt)->mti_la;
+        struct dt_object *next = mdd_object_child(obj);
+        int rc = 0;
+        ENTRY;
+
+        rc = next->do_ops->do_attr_get(ctxt, next, tmp_la);
+        if (rc)
+                RETURN(rc);
+
+        if (!(ma->ma_attr_flags & ATTR_CTIME_SET))
+                la->la_ctime = now;
+        
+        if (!(ma->ma_attr_flags & ATTR_ATIME_SET))
+                la->la_atime = now;
+        if (!(ma->ma_attr_flags & ATTR_MTIME_SET))
+                la->la_mtime = now;
+
+        /*XXX Check permission */
+#if 0
+        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+                RETURN((attr->ia_valid & ~ATTR_ATTR_FLAG) ? -EPERM : 0);
+
+        /* times */
+        if ((ia_valid & (ATTR_MTIME|ATTR_ATIME)) == (ATTR_MTIME|ATTR_ATIME)) {
+                if (current->fsuid != inode->i_uid &&
+                    (error = ll_permission(inode, MAY_WRITE, NULL)) != 0)
+                        RETURN(error);
+        }
+        if (ia_valid & ATTR_SIZE &&
+            /* NFSD hack for open(O_CREAT|O_TRUNC)=mknod+truncate (bug 5781) */
+            !(rec->ur_uc.luc_fsuid == inode->i_uid &&
+              ia_valid & MDS_OPEN_OWNEROVERRIDE)) {
+                if ((error = ll_permission(inode, MAY_WRITE, NULL)) != 0)
+                        RETURN(error);
+        }
+#endif
+
+        if (la->la_valid & (LA_UID | LA_GID)) {
+                /* chown */
+
+                rc = -EPERM;
+
+                if (la->la_uid == (uid_t) -1)
+                        la->la_uid = tmp_la->la_uid;
+                if (la->la_gid == (gid_t) -1)
+                        la->la_gid = tmp_la->la_gid;
+                if (!(la->la_valid & ATTR_MODE))
+                        la->la_mode = tmp_la->la_mode;
+                /*
+                 * 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>
+                 *
+                 * Changed this to apply to all users, including root,
+                 * 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.
+                 */
+                if ((tmp_la->la_mode & S_ISUID) == S_ISUID &&
+                    !S_ISDIR(tmp_la->la_mode)) {
+                        la->la_mode &= ~S_ISUID;
+                        la->la_valid |= LA_MODE;
+                }
+                /*
+                 * 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.
+                 */
+                if (((tmp_la->la_mode & (S_ISGID | S_IXGRP)) ==
+                     (S_ISGID | S_IXGRP)) && !S_ISDIR(tmp_la->la_mode)) {
+                        la->la_mode &= ~S_ISGID;
+                        la->la_valid |= ATTR_MODE;
+                }
+        } else if (la->la_valid & LA_MODE) {
+                int mode = la->la_mode;
+                /* chmod */
+                if (la->la_mode == (umode_t)-1)
+                        mode = tmp_la->la_mode;
+                la->la_mode =
+                        (mode & S_IALLUGO) | (tmp_la->la_mode & ~S_IALLUGO);
+        }
+        RETURN(rc);
 }
 
 
@@ -595,43 +692,82 @@ static int mdd_attr_set(const struct lu_context *ctxt,
         struct mdd_object *mdd_obj = md2mdd_obj(obj);
         struct mdd_device *mdd = mdo2mdd(obj);
         struct thandle *handle;
-        int  rc;
+        struct lov_mds_md *lmm = NULL;
+        int  rc = 0, lmm_size = 0, max_size;
         ENTRY;
 
         mdd_txn_param_build(ctxt, &MDD_TXN_ATTR_SET);
         handle = mdd_trans_start(ctxt, mdd);
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
+        /*TODO: add lock here*/
+        /* start a log jounal handle if needed */
+        if (S_ISREG(mdd_object_type(mdd_obj)) &&
+            ma->ma_attr.la_valid & (LA_UID | LA_GID)) {
+                mdd_lov_mdsize(ctxt, mdd, &max_size);
+                OBD_ALLOC(lmm, max_size);
+                if (lmm == NULL)
+                        GOTO(cleanup, rc = -ENOMEM);
+                
+                rc = mdd_get_md(ctxt, mdd_obj, lmm, &lmm_size, 1);
+                
+                if (rc < 0)
+                        GOTO(cleanup, rc);
+        }
 
-        mdd_lock(ctxt, mdd_obj, DT_WRITE_LOCK);
-
-        rc = mdd_attr_set_internal(ctxt, mdd_obj, &ma->ma_attr, handle);
-        if (rc == 0 && (ma->ma_valid & MA_LOV)) {
-                /* set LOV ea now */
-                rc = __mdd_xattr_set(ctxt, mdd_obj,
-                                     ma->ma_lmm, ma->ma_lmm_size,
-                                     XATTR_NAME_LOV, 0, handle);
+        if (ma->ma_attr.la_valid & (ATTR_MTIME | ATTR_CTIME))
+                CDEBUG(D_INODE, "setting mtime "LPU64", ctime "LPU64"\n",
+                       ma->ma_attr.la_mtime, ma->ma_attr.la_ctime);
+        
+        rc = mdd_fix_attr(ctxt, mdd_obj, ma);
+        if (rc)
+                GOTO(cleanup, rc);
+        if (ma->ma_attr_flags & MD_ATTR_FLAG) {  /* ioctl */
+                rc = -ENOTSUPP;
+        } else if (ma->ma_attr.la_valid) {            /* setattr */
+                mdd_lock(ctxt, mdd_obj, DT_WRITE_LOCK);
+                rc = mdd_attr_set_internal(ctxt, mdd_obj, &ma->ma_attr, handle);
+                mdd_unlock(ctxt, mdd_obj, DT_WRITE_LOCK);
+
+                /* journal chown/chgrp in llog, just like unlink */
+                if (rc == 0 && lmm_size){
+                        /*TODO set_attr llog */
+                }
         }
-        /* XXX: llog cancel cookie? */
 
-        mdd_unlock(ctxt, mdd_obj, DT_WRITE_LOCK);
+        if (rc == 0 && ma->ma_valid & MA_LOV) {
+                if ((S_ISREG(mdd_object_type(mdd_obj)) || 
+                             S_ISDIR(mdd_object_type(mdd_obj)))) {
+                        /*TODO check permission*/
+                        rc = mdd_lov_set_md(ctxt, NULL, mdd_obj, ma->ma_lmm,
+                                            ma->ma_lmm_size, handle, 1);
+                }
+        
+        }
+cleanup:
         mdd_trans_stop(ctxt, mdd, handle);
-
+        if (rc == 0 && lmm_size) {
+                /*set obd attr, if needed*/
+                rc = mdd_lov_setattr_async(ctxt, mdd_obj, lmm, lmm_size);
+        }
+        if (lmm != NULL) {
+                OBD_FREE(lmm, max_size);
+        }
+        
         RETURN(rc);
 }
 
-int mdd_xattr_set_txn(const struct lu_context *ctxt, struct md_object *obj,
+int mdd_xattr_set_txn(const struct lu_context *ctxt, struct mdd_object *obj,
                       const void *buf, int buf_len, const char *name, int fl,
                       struct thandle *handle)
 {
-        struct mdd_object *mdd_obj = md2mdd_obj(obj);
         int  rc;
         ENTRY;
 
-        mdd_lock(ctxt, mdd_obj, DT_WRITE_LOCK);
-        rc = __mdd_xattr_set(ctxt, mdd_obj, buf, buf_len, name,
+        mdd_lock(ctxt, obj, DT_WRITE_LOCK);
+        rc = __mdd_xattr_set(ctxt, obj, buf, buf_len, name,
                              fl, handle);
-        mdd_unlock(ctxt, mdd_obj, DT_WRITE_LOCK);
+        mdd_unlock(ctxt, obj, DT_WRITE_LOCK);
 
         RETURN(rc);
 }
@@ -649,7 +785,8 @@ static int mdd_xattr_set(const struct lu_context *ctxt, struct md_object *obj,
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
-        rc = mdd_xattr_set_txn(ctxt, obj, buf, buf_len, name, fl, handle);
+        rc = mdd_xattr_set_txn(ctxt, md2mdd_obj(obj), buf, buf_len, name, 
+                               fl, handle);
 
         mdd_trans_stop(ctxt, mdd, handle);
 
@@ -818,20 +955,17 @@ static int __mdd_finish_unlink(const struct lu_context *ctxt,
 {
         int rc;
         ENTRY;
-        rc = __mdd_attr_get(ctxt, obj, ma);
+        rc = mdd_attr_get_internal(ctxt, obj, ma, 0);
         if (rc)
                 RETURN(rc);
 
         if (atomic_read(&obj->mod_count) == 0 &&
-            ma->ma_attr.la_nlink == 0) {
-                rc = __mdd_lov_get(ctxt, obj, ma);
-                if (rc) {
-                        CERROR("Can't get LOV attr during unlink()\n");
-                }
-                if(S_ISREG(ma->ma_attr.la_mode) && 
-                   ma->ma_valid & MA_LOV)
+            ma->ma_attr.la_nlink == 0 && S_ISREG(mdd_object_type(obj))) {
+                rc = __mdd_lmm_get(ctxt, obj, ma);
+                if(S_ISREG(ma->ma_attr.la_mode) && ma->ma_valid & MA_LOV)
                         rc = mdd_unlink_log(ctxt, mdo2mdd(&obj->mod_obj),
-                                            obj, ma);                
+                                    obj, ma);                
         }
         RETURN(rc);
 }
@@ -893,6 +1027,9 @@ static int mdd_unlink(const struct lu_context *ctxt, struct md_object *pobj,
                 /* unlink dotdot */
                 __mdd_ref_del(ctxt, mdd_pobj, handle);
         }
+        rc = mdd_attr_get_internal(ctxt, mdd_cobj, ma, 0);
+        if (rc)
+                GOTO(cleanup, rc);
         
         rc = __mdd_finish_unlink(ctxt, mdd_cobj, ma);
 
@@ -1083,8 +1220,12 @@ static int mdd_rename(const struct lu_context *ctxt, struct md_object *src_pobj,
                 __mdd_ref_del(ctxt, mdd_tobj, handle);
                 if (S_ISDIR(mdd_object_type(mdd_tobj)))
                         __mdd_ref_del(ctxt, mdd_tpobj, handle);
-                else 
-                        rc = mdd_attr_get(ctxt, tobj, ma);
+                else {
+                        rc = mdd_attr_get_internal(ctxt, mdd_tobj, ma, 0);
+                        if (rc)
+                                GOTO(cleanup, rc);
+                }
+                
                 mdd_set_dead_obj(mdd_tobj);
         }
 cleanup:
@@ -1182,18 +1323,21 @@ static int mdd_create_data(const struct lu_context *ctxt,
         int                rc;
         ENTRY;
 
+        rc = mdd_lov_create(ctxt, mdd, mdd_pobj, son, &lmm, &lmm_size, spec,
+                            attr);
+        if (rc)
+                RETURN(rc);
+
         mdd_txn_param_build(ctxt, &MDD_TXN_CREATE_DATA);
         handle = mdd_trans_start(ctxt, mdd);
         if (IS_ERR(handle))
                 RETURN(PTR_ERR(handle));
 
-        rc = mdd_lov_create(ctxt, mdd, mdd_pobj, son, &lmm, &lmm_size, spec, 
-                            attr);
         if (rc == 0) {
-                rc = mdd_lov_set_md(ctxt, pobj, cobj, lmm,
-                                    lmm_size, attr, handle);
+                rc = mdd_lov_set_md(ctxt, mdd_pobj, son, lmm, lmm_size, 
+                                    handle, 0);
                 if (rc == 0)
-                        rc = mdd_attr_get(ctxt, cobj, ma);
+                        rc = mdd_attr_get_internal(ctxt, son, ma, 1);
         }
 
         mdd_trans_stop(ctxt, mdd, handle);
@@ -1349,7 +1493,7 @@ static int mdd_create(const struct lu_context *ctxt, struct md_object *pobj,
                 GOTO(cleanup, rc);
 
         inserted = 1;
-        rc = mdd_lov_set_md(ctxt, pobj, child, lmm, lmm_size, attr, handle);
+        rc = mdd_lov_set_md(ctxt, mdd_pobj, son, lmm, lmm_size, handle, 0);
         if (rc) {
                 CERROR("error on stripe info copy %d \n", rc);
                 GOTO(cleanup, rc);
@@ -1369,7 +1513,7 @@ static int mdd_create(const struct lu_context *ctxt, struct md_object *pobj,
                         rc = -EFAULT;
         }
         /* return attr back */
-        mdd_attr_get(ctxt, child, ma);
+        rc = mdd_attr_get_internal(ctxt, son, ma, 1);
 cleanup:
         if (rc && created) {
                 int rc2 = 0;
@@ -1410,10 +1554,13 @@ static int mdd_object_create(const struct lu_context *ctxt,
 /* XXX: parent fid is needed here
         rc = __mdd_object_initialize(ctxt, mdo, son, ma, handle);
 */
-        mdd_attr_get(ctxt, obj, ma);
+        if (rc)
+                GOTO(out, rc);
 
-        mdd_trans_stop(ctxt, mdd, handle);
+        rc = mdd_attr_get_internal(ctxt, md2mdd_obj(obj), ma, 1);
 
+        mdd_trans_stop(ctxt, mdd, handle);
+out:
         RETURN(rc);
 }
 /* partial operation */
@@ -1613,6 +1760,7 @@ static int mdd_ref_del(const struct lu_context *ctxt, struct md_object *obj,
         }
 
         __mdd_ref_del(ctxt, mdd_obj, handle);
+
         if (S_ISDIR(lu_object_attr(&obj->mo_lu))) {
                 /* unlink dot */
                 __mdd_ref_del(ctxt, mdd_obj, handle);
index 1969a1f..fd69c1b 100644 (file)
@@ -63,27 +63,36 @@ struct mdd_thread_info {
 
 int mdd_init_obd(const struct lu_context *ctxt, struct mdd_device *mdd,
                  char *dev);
-int mdd_xattr_set_txn(const struct lu_context *ctxt, struct md_object *obj,
+int mdd_xattr_set_txn(const struct lu_context *ctxt, struct mdd_object *obj,
                       const void *buf, int buf_len, const char *name, int fl,
                       struct thandle *txn);
-int mdd_lov_set_md(const struct lu_context *ctxt, struct md_object *pobj,
-                   struct md_object *child, struct lov_mds_md *lmm,
-                   int lmm_size, struct lu_attr *la, struct thandle *handle);
+int mdd_lov_set_md(const struct lu_context *ctxt, struct mdd_object *pobj,
+                   struct mdd_object *child, struct lov_mds_md *lmm,
+                   int lmm_size, struct thandle *handle, int set_stripe);
 int mdd_lov_create(const struct lu_context *ctxt, struct mdd_device *mdd,
                    struct mdd_object *parent, struct mdd_object *child,
                    struct lov_mds_md **lmm, int *lmm_size,
                    const struct md_create_spec *spec, struct lu_attr *la);
 
-int mdd_get_md(const struct lu_context *ctxt, struct md_object *obj,
-               void *md, int *md_size);
+int mdd_get_md(const struct lu_context *ctxt, struct mdd_object *obj,
+               void *md, int *md_size, int need_locked);
 int mdd_unlink_log(const struct lu_context *ctxt, struct mdd_device *mdd,
                    struct mdd_object *mdd_cobj, struct md_attr *ma);
 
 int mdd_attr_set_internal(const struct lu_context *ctxt, struct mdd_object *o,
                           const struct lu_attr *attr, struct thandle *handle);
+int mdd_get_cookie_size(const struct lu_context *ctxt, struct mdd_device *mdd,
+                        struct lov_mds_md *lmm);
+
+int mdd_lov_setattr_async(const struct lu_context *ctxt, struct mdd_object *obj,
+                          struct lov_mds_md *lmm, int lmm_size);
 
 struct mdd_thread_info *mdd_ctx_info(const struct lu_context *ctx);
 
+void mdd_lock(const struct lu_context *ctxt, struct mdd_object *obj, 
+              enum dt_lock_mode mode);
+void mdd_unlock(const struct lu_context *ctxt, struct mdd_object *obj, 
+                enum dt_lock_mode mode);
 extern struct lu_device_operations mdd_lu_ops;
 static inline int lu_device_is_mdd(struct lu_device *d)
 {
@@ -142,6 +151,11 @@ static inline const struct lu_fid *mdo2fid(const struct mdd_object *obj)
         return lu_object_fid(&obj->mod_obj.mo_lu);
 }
 
+static inline umode_t mdd_object_type(const struct mdd_object *obj)
+{
+        return lu_object_attr(&obj->mod_obj.mo_lu);
+}
+
 int mdd_lov_mdsize(const struct lu_context *ctxt, struct mdd_device *mdd,
                    int *md_size);
 int mdd_lov_cookiesize(const struct lu_context *ctxt, struct mdd_device *mdd,
index 647f881..d7b29a4 100644 (file)
@@ -268,14 +268,16 @@ lcfg_cleanup:
         RETURN(rc);
 }
 
-int mdd_get_md(const struct lu_context *ctxt, struct md_object *obj,
-               void *md, int *md_size)
+int mdd_get_md(const struct lu_context *ctxt, struct mdd_object *obj,
+               void *md, int *md_size, int need_locked)
 {
         struct dt_object *next;
         int rc = 0;
         ENTRY;
 
-        next = mdd_object_child(md2mdd_obj(obj));
+        if (need_locked)
+                mdd_lock(ctxt, obj, DT_READ_LOCK);
+        next = mdd_object_child(obj);
         rc = next->do_ops->do_xattr_get(ctxt, next, md, *md_size,
                                         MDS_LOV_MD_NAME);
         /*
@@ -292,50 +294,101 @@ int mdd_get_md(const struct lu_context *ctxt, struct md_object *obj,
                 *md_size = rc;
         }
 
+        if (need_locked)
+                mdd_unlock(ctxt, obj, DT_READ_LOCK);
+
         RETURN (rc);
 }
 
-int mdd_lov_set_md(const struct lu_context *ctxt, struct md_object *pobj,
-                   struct md_object *child, struct lov_mds_md *lmmp,
-                   int lmm_size, struct lu_attr *la, struct thandle *handle)
+static int mdd_lov_set_stripe_md(const struct lu_context *ctxt,
+                                 struct mdd_object *obj, struct lov_mds_md *lmmp,
+                                 int lmm_size, struct thandle *handle)
 {
-        struct lu_attr *tmp_la = &mdd_ctx_info(ctxt)->mti_la;
+        struct mdd_device       *mdd = mdo2mdd(&obj->mod_obj);
+        struct obd_device       *obd = mdd2_obd(mdd);
+        struct obd_export       *lov_exp = obd->u.mds.mds_osc_exp;
+        struct lov_stripe_md    *lsm = NULL;
+        int rc;
+        ENTRY;
+        
+        LASSERT(S_ISDIR(mdd_object_type(obj)) && S_ISREG(mdd_object_type(obj)));
+
+        rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE, lov_exp, 0, &lsm, lmmp);
+        if (rc)
+                RETURN(rc);
+        obd_free_memmd(lov_exp, &lsm);
+
+        rc = mdd_xattr_set_txn(ctxt, obj, lmmp, lmm_size, MDS_LOV_MD_NAME, 0, 
+                               handle);
+        
+        CDEBUG(D_INFO, "set lov ea of "DFID" rc %d \n", PFID(mdo2fid(obj)), rc);
+        RETURN(rc);
+}
+                
+static int mdd_lov_set_dir_md(const struct lu_context *ctxt, 
+                              struct mdd_object *obj, struct lov_mds_md *lmmp,
+                              int lmm_size, struct thandle *handle)
+{
+        struct lov_user_md *lum = NULL;
         int rc = 0;
         ENTRY;
 
-        LASSERT(la->la_valid & LA_MODE);
-        if (S_ISREG(la->la_mode) && lmm_size > 0) {
-                LASSERT(lmmp != NULL);
-                rc = mdd_xattr_set_txn(ctxt, child, lmmp, lmm_size,
-                                       MDS_LOV_MD_NAME, 0, handle);
-                if (rc) {
-                        CERROR("error on set stripe info: rc = %d\n", rc);
-                        RETURN(rc);
-                }
-                if (la->la_valid & LA_BLKSIZE) {
-                        tmp_la->la_valid = LA_BLKSIZE;
-                        tmp_la->la_blksize = la->la_blksize;
-                        rc = mdd_attr_set_internal(ctxt, md2mdd_obj(child), tmp_la,
-                                              handle);
+        /*TODO check permission*/
+        LASSERT(S_ISDIR(mdd_object_type(obj)));
+        lum = (struct lov_user_md*)lmmp;
+
+        /* if { size, offset, count } = { 0, -1, 0 } (i.e. all default
+         * values specified) then delete default striping from dir. */
+        if ((lum->lmm_stripe_size == 0 && lum->lmm_stripe_count == 0 && 
+             lum->lmm_stripe_offset == (typeof(lum->lmm_stripe_offset))(-1)) ||
+             /* lmm_stripe_size == -1 is deprecated in 1.4.6 */
+             lum->lmm_stripe_size == (typeof(lum->lmm_stripe_size))(-1)){
+                rc = mdd_xattr_set_txn(ctxt, obj, NULL, 0, MDS_LOV_MD_NAME, 0, 
+                                       handle);
+                CDEBUG(D_INFO, "delete lov ea of "DFID" rc %d \n",
+                                PFID(mdo2fid(obj)), rc);
+        } else {
+                rc = mdd_lov_set_stripe_md(ctxt, obj, lmmp, lmm_size, handle); 
+        }
+        RETURN(rc);
+}
+        
+int mdd_lov_set_md(const struct lu_context *ctxt, struct mdd_object *pobj,
+                   struct mdd_object *child, struct lov_mds_md *lmmp,
+                   int lmm_size, struct thandle *handle, int set_stripe)
+{
+        int rc = 0;
+        ENTRY;
+
+        if (S_ISREG(mdd_object_type(child)) && lmm_size > 0) {
+                if (set_stripe) {
+                        rc = mdd_lov_set_stripe_md(ctxt, child, lmmp, lmm_size,
+                                                   handle);
+                } else {
+                        rc = mdd_xattr_set_txn(ctxt, child, lmmp, lmm_size,
+                                               MDS_LOV_MD_NAME, 0, handle);
                 }
-        } else  if (S_ISDIR(la->la_mode)) {
-                struct lov_mds_md *lmm = &mdd_ctx_info(ctxt)->mti_lmm;
-                int size = sizeof(lmm);
-                rc = mdd_get_md(ctxt, pobj, &lmm, &size);
-                if (rc > 0) {
-                        rc = mdd_xattr_set_txn(ctxt, child, lmm, size,
-                                               /*
-                                                * Flags are 0: we don't care
-                                                * whether attribute exists
-                                                * already.
-                                                */
+        } else  if (S_ISDIR(mdd_object_type(child))) {
+                if (lmmp == NULL && lmm_size == 0) {
+                        struct lov_mds_md *lmm = &mdd_ctx_info(ctxt)->mti_lmm;
+                        int size = sizeof(lmm);
+                        /*Get parent dir stripe and set*/
+                        rc = mdd_get_md(ctxt, pobj, &lmm, &size, 0);
+                        if (rc > 0) {
+                                rc = mdd_xattr_set_txn(ctxt, child, lmm, size,
                                                MDS_LOV_MD_NAME, 0, handle);
-                        if (rc)
-                                CERROR("error on copy stripe info: rc = %d\n",
-                                        rc);
+                                if (rc)
+                                        CERROR("error on copy stripe info: rc = %d\n",
+                                                rc);
+                        }
+                } else {
+                       LASSERT(lmmp != NULL && lmm_size > 0);
+                        /*delete lmm*/
+                       rc = mdd_lov_set_dir_md(ctxt, child, lmmp, lmm_size, handle);
                 }
         }
-
+        CDEBUG(D_INFO, "Set lov md %p size %d for fid "DFID" rc%d/n",
+                        lmmp, lmm_size, PFID(mdo2fid(child)), rc);
         RETURN(rc);
 }
 
@@ -439,8 +492,8 @@ int mdd_lov_create(const struct lu_context *ctxt, struct mdd_device *mdd,
                         if (__lmm == NULL)
                                 GOTO(out_oa, rc = -ENOMEM);
 
-                        rc = mdd_get_md(ctxt, &parent->mod_obj, __lmm,
-                                        &returned_lmm_size);
+                        rc = mdd_get_md(ctxt, parent, __lmm,
+                                        &returned_lmm_size, 1);
                         if (rc > 0)
                                 rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE,
                                                    lov_exp, 0, &lsm, __lmm);
@@ -479,7 +532,7 @@ int mdd_lov_create(const struct lu_context *ctxt, struct mdd_device *mdd,
                  * by filter_fid, but can not see what is the usages. So just 
                  * pack o_seq o_ver here, maybe fix it after this cycle*/
                 oa->o_fid = lu_object_fid(mdd2lu_obj(child))->f_seq;
-                oa->o_generation = lu_object_fid(mdd2lu_obj(child))->f_ver;
+                oa->o_generation = lu_object_fid(mdd2lu_obj(child))->f_oid;
                 oa->o_valid |= OBD_MD_FLFID | OBD_MD_FLGENER;
 
                 rc = obd_setattr(lov_exp, oa, lsm, NULL);
@@ -523,6 +576,27 @@ int mdd_unlink_log(const struct lu_context *ctxt, struct mdd_device *mdd,
         }
         return 0;
 }
+int mdd_lov_setattr_async(const struct lu_context *ctxt, struct mdd_object *obj,
+                          struct lov_mds_md *lmm, int lmm_size)
+{
+        struct mdd_device       *mdd = mdo2mdd(&obj->mod_obj);
+        struct obd_device       *obd = mdd2_obd(mdd);
+        struct lu_attr          *tmp_la = &mdd_ctx_info(ctxt)->mti_la;
+        struct dt_object        *next = mdd_object_child(obj);
+        __u32  seq  = lu_object_fid(mdd2lu_obj(obj))->f_seq;
+        __u32  oid  = lu_object_fid(mdd2lu_obj(obj))->f_oid;
+        int rc = 0;
+        ENTRY;
+
+        rc = next->do_ops->do_attr_get(ctxt, next, tmp_la);
+        if (rc)
+                RETURN(rc);
+
+        rc = mds_osc_setattr_async(obd, tmp_la->la_uid, tmp_la->la_gid, lmm,
+                                   lmm_size, NULL, seq, oid);
+
+        RETURN(rc);
+}
 
 int mdd_lov_mdsize(const struct lu_context *ctxt, struct mdd_device *mdd,
                    int *md_size)
index 0952e43..f6acec3 100644 (file)
@@ -137,9 +137,6 @@ int mds_get_parent_child_locked(struct obd_device *obd, struct mds_obd *mds,
                                 __u64 child_lockpart);
 int mds_lock_new_child(struct obd_device *obd, struct inode *inode,
                        struct lustre_handle *child_lockh);
-int mds_osc_setattr_async(struct obd_device *obd, struct inode *inode,
-                          struct lov_mds_md *lmm, int lmm_size,
-                          struct llog_cookie *logcookies, struct ll_fid *fid);
 
 int mds_get_parents_children_locked(struct obd_device *obd,
                                     struct mds_obd *mds,
index a736954..a3351ef 100644 (file)
@@ -166,6 +166,7 @@ int mds_log_op_setattr(struct obd_device *obd, struct inode *inode,
         obd_free_memmd(mds->mds_osc_exp, &lsm);
         RETURN(rc);
 }
+EXPORT_SYMBOL(mds_log_op_setattr);
 
 static struct llog_operations mds_ost_orig_logops = {
         lop_add:        mds_llog_origin_add,
index 02ad8b7..96bb8b4 100644 (file)
@@ -390,9 +390,9 @@ static void reconstruct_reint_setattr(struct mds_update_record *rec,
         l_dput(de);
 }
 
-int mds_osc_setattr_async(struct obd_device *obd, struct inode *inode,
+int mds_osc_setattr_async(struct obd_device *obd, __u32 uid, __u32 gid,
                           struct lov_mds_md *lmm, int lmm_size,
-                          struct llog_cookie *logcookies, struct ll_fid *fid)
+                          struct llog_cookie *logcookies, __u64 id, __u32 gen)
 {
         struct mds_obd *mds = &obd->u.mds;
         struct lov_stripe_md *lsm = NULL;
@@ -413,7 +413,7 @@ int mds_osc_setattr_async(struct obd_device *obd, struct inode *inode,
 
         rc = obd_unpackmd(mds->mds_osc_exp, &lsm, lmm, lmm_size);
         if (rc < 0) {
-                CERROR("Error unpack md %p for inode %lu\n", lmm, inode->i_ino);
+                CERROR("Error unpack md %p for inode "LPU64"\n", lmm, id);
                 GOTO(out, rc);
         }
 
@@ -425,17 +425,16 @@ int mds_osc_setattr_async(struct obd_device *obd, struct inode *inode,
 
         /* then fill oa */
         oa->o_id = lsm->lsm_object_id;
-        oa->o_uid = inode->i_uid;
-        oa->o_gid = inode->i_gid;
+        oa->o_uid = uid;
+        oa->o_gid = gid;
         oa->o_valid = OBD_MD_FLID | OBD_MD_FLUID | OBD_MD_FLGID;
         if (logcookies) {
                 oa->o_valid |= OBD_MD_FLCOOKIE;
                 oti.oti_logcookies = logcookies;
         }
 
-        LASSERT(fid != NULL);
-        oa->o_fid = fid->id;
-        oa->o_generation = fid->generation;
+        oa->o_fid = id;
+        oa->o_generation = gen;
         oa->o_valid |= OBD_MD_FLFID | OBD_MD_FLGENER;
 
         /* do setattr from mds to ost asynchronously */
@@ -449,6 +448,7 @@ out:
         obdo_free(oa);
         RETURN(rc);
 }
+EXPORT_SYMBOL(mds_osc_setattr_async);
 
 /* In the raw-setattr case, we lock the child inode.
  * In the write-back case or if being called from open, the client holds a lock
@@ -644,8 +644,9 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
         err = mds_finish_transno(mds, inode, handle, req, rc, 0);
         /* do mds to ost setattr if needed */
         if (!rc && !err && lmm_size)
-                mds_osc_setattr_async(obd, inode, lmm, lmm_size,
-                                      logcookies, rec->ur_fid1);
+                mds_osc_setattr_async(obd, inode->i_ino, inode->i_generation, lmm, 
+                                      lmm_size, logcookies, rec->ur_fid1->id,
+                                      rec->ur_fid1->generation);
 
         switch (cleanup_phase) {
         case 2:
index 6f9ea7a..2b9f4b0 100644 (file)
@@ -233,7 +233,8 @@ static int mdt_getattr_internal(struct mdt_thread_info *info,
         ma->ma_lmm = req_capsule_server_get(pill, &RMF_MDT_MD);
         ma->ma_lmm_size = req_capsule_get_size(pill, &RMF_MDT_MD, RCL_SERVER);
 
-        rc = mo_attr_get(ctxt, next, &info->mti_attr);
+        ma->ma_need = MA_INODE | MA_LOV;
+        rc = mo_attr_get(ctxt, next, ma);
         if (rc == -EREMOTE) {
                 /* This object is located on remote node.*/
                 repbody->fid1 = *mdt_object_fid(o);
@@ -733,6 +734,7 @@ static int mdt_sync(struct mdt_thread_info *info)
                                 const struct lu_fid *fid;
                                 next = mdt_object_child(info->mti_object);
                                 fid = mdt_object_fid(info->mti_object);
+                                info->mti_attr.ma_need = MA_INODE;
                                 rc = mo_attr_get(info->mti_ctxt,
                                                  next, &info->mti_attr);
                                 if (rc == 0) {
@@ -2870,7 +2872,7 @@ DEF_MDT_HNDL_F(HABEO_CORPUS,              GETXATTR,     mdt_getxattr),
 DEF_MDT_HNDL_F(0           |HABEO_REFERO, STATFS,       mdt_statfs),
 DEF_MDT_HNDL_F(0                        |MUTABOR,
                                           REINT,        mdt_reint),
-DEF_MDT_HNDL_F(HABEO_CORPUS|HABEO_REFERO, CLOSE,        mdt_close),
+DEF_MDT_HNDL_F(HABEO_CORPUS             , CLOSE,        mdt_close),
 DEF_MDT_HNDL_0(0,                         DONE_WRITING, mdt_done_writing),
 DEF_MDT_HNDL_F(0           |HABEO_REFERO, PIN,          mdt_pin),
 DEF_MDT_HNDL_0(0,                         SYNC,         mdt_sync),
index 4590d12..975bd11 100644 (file)
@@ -188,7 +188,7 @@ struct mdt_reint_record {
 };
 
 enum mdt_reint_flag {
-        MRF_SETATTR_LOCKED = 1 << 0
+        MRF_SETATTR_LOCKED = 1 << 0,
 };
 
 enum {
index 6d9a8aa..8d08e09 100644 (file)
@@ -129,7 +129,8 @@ int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo,
         RETURN(0);
 }
 
-static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr)
+static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr,
+                                  struct md_attr *ma)
 {
         __u64 out;
 
@@ -152,8 +153,25 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr)
         if (in & ATTR_FROM_OPEN)
                 rr->rr_flags |= MRF_SETATTR_LOCKED;
 
+        if (in & ATTR_ATIME_SET)
+                ma->ma_attr_flags |= MD_ATIME_SET;
+
+        if (in & ATTR_CTIME_SET)
+                ma->ma_attr_flags |= MD_CTIME_SET;
+
+        if (in & ATTR_MTIME_SET)
+                ma->ma_attr_flags |= MD_MTIME_SET;
+
+        if (in & ATTR_ATTR_FLAG)
+                ma->ma_attr_flags |= MD_ATTR_FLAG;
+
+        if (in & ATTR_RAW)
+                ma->ma_attr_flags |= MD_ATTR_RAW;
+
         in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|
-                ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN);
+                ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN|
+                ATTR_ATIME_SET|ATTR_CTIME_SET|ATTR_MTIME_SET|
+                ATTR_ATTR_FLAG|ATTR_RAW);
         if (in != 0)
                 CERROR("Unknown attr bits: %#llx\n", in);
         return out;
@@ -174,7 +192,7 @@ static int mdt_setattr_unpack(struct mdt_thread_info *info)
                 RETURN(-EFAULT);
 
         rr->rr_fid1 = &rec->sa_fid;
-        la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr);
+        la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr, ma);
         la->la_mode  = rec->sa_mode;
         la->la_uid   = rec->sa_uid;
         la->la_gid   = rec->sa_gid;
index 0fe38f1..86ab3a4 100644 (file)
@@ -72,8 +72,8 @@ static void mdt_mfd_free(struct mdt_file_data *mfd)
         OBD_FREE_PTR(mfd);
 }
 
-static int mdt_create_data_obj(struct mdt_thread_info *info,
-                              struct mdt_object *p, struct mdt_object *o)
+static int mdt_create_data(struct mdt_thread_info *info,
+                           struct mdt_object *p, struct mdt_object *o)
 {
         struct md_attr   *ma = &info->mti_attr;
         /* XXX: md_create_spec using should be made clear
@@ -81,6 +81,7 @@ static int mdt_create_data_obj(struct mdt_thread_info *info,
          */
         struct md_create_spec *spec = &info->mti_spec;
 
+        ma->ma_need = MA_INODE | MA_LOV;
         return mdo_create_data(info->mti_ctxt, mdt_object_child(p),
                                mdt_object_child(o), spec, ma);
 }
@@ -187,6 +188,7 @@ static int mdt_mfd_open(struct mdt_thread_info *info,
 
         if (!created) {
                 /* we have to get attr & lov ea for this object*/
+                ma->ma_need = MA_INODE | MA_LOV;
                 rc = mo_attr_get(info->mti_ctxt, mdt_object_child(o), ma);
                 if (rc)
                         RETURN(rc);
@@ -229,7 +231,7 @@ static int mdt_mfd_open(struct mdt_thread_info *info,
                                                        &RMF_MDT_MD,
                                                        RCL_SERVER);
                 LASSERT(p != NULL);
-                rc = mdt_create_data_obj(info, p, o);
+                rc = mdt_create_data(info, p, o);
                 if (rc)
                         RETURN(rc);
         }
@@ -327,6 +329,7 @@ int mdt_open_by_fid(struct mdt_thread_info* info, const struct lu_fid *fid,
                 } else {
                         rc = -ENOENT;
                         if (flags & MDS_OPEN_CREAT) {
+                                info->mti_attr.ma_need = MA_INODE | MA_LOV;
                                 rc = mo_object_create(info->mti_ctxt,
                                                       mdt_object_child(o),
                                                       &info->mti_spec,
@@ -439,6 +442,7 @@ int mdt_reint_open(struct mdt_thread_info *info)
 
         if (result == -ENOENT) {
                 /* not found and with MDS_OPEN_CREAT: let's create it */
+                ma->ma_need = MA_INODE | MA_LOV;
                 result = mdo_create(info->mti_ctxt,
                                     mdt_object_child(parent),
                                     rr->rr_name,
@@ -458,6 +462,7 @@ int mdt_reint_open(struct mdt_thread_info *info)
 
 finish_open:
         if (result != 0 && created) {
+                ma->ma_need = 0;
                 int rc2 = mdo_unlink(info->mti_ctxt, mdt_object_child(parent),
                                      mdt_object_child(child), rr->rr_name,
                                      &info->mti_attr);
@@ -499,6 +504,14 @@ int mdt_close(struct mdt_thread_info *info)
         int rc;
         ENTRY;
 
+        req_capsule_set_size(&info->mti_pill, &RMF_MDT_MD, RCL_SERVER,
+                             info->mti_mdt->mdt_max_mdsize);
+        req_capsule_set_size(&info->mti_pill, &RMF_LOGCOOKIES, RCL_SERVER,
+                             info->mti_mdt->mdt_max_cookiesize);
+        rc = req_capsule_pack(&info->mti_pill);
+        if (rc)
+                RETURN(rc);
+
         med = &mdt_info_req(info)->rq_export->exp_mdt_data;
 
         spin_lock(&med->med_open_lock);
@@ -519,6 +532,13 @@ int mdt_close(struct mdt_thread_info *info)
                 ma->ma_lmm_size = req_capsule_get_size(&info->mti_pill,
                                                        &RMF_MDT_MD,
                                                        RCL_SERVER);
+                
+                ma->ma_cookie = req_capsule_server_get(&info->mti_pill,
+                                                    &RMF_LOGCOOKIES);
+                ma->ma_cookie_size = req_capsule_get_size(&info->mti_pill,
+                                                       &RMF_LOGCOOKIES,
+                                                       RCL_SERVER);
+                ma->ma_need = MA_INODE;
                 o = mfd->mfd_object;
                 mdt_mfd_close(info->mti_ctxt, info->mti_mdt, mfd, ma);
                 rc = mdt_handle_last_unlink(info, o, ma);
index 291b49c..5e7e485 100644 (file)
@@ -63,6 +63,7 @@ static int mdt_md_create(struct mdt_thread_info *info)
         if (!IS_ERR(child)) {
                 struct md_object *next = mdt_object_child(parent);
 
+                ma->ma_need = MA_INODE;
                 rc = mdo_create(info->mti_ctxt, next, rr->rr_name,
                                 mdt_object_child(child), &info->mti_spec,
                                 /* rr->rr_tgt, NULL, 0, */
@@ -96,6 +97,7 @@ static int mdt_md_mkobj(struct mdt_thread_info *info)
         if (!IS_ERR(o)) {
                 struct md_object *next = mdt_object_child(o);
 
+                ma->ma_need = MA_INODE | MA_LOV;
                 rc = mo_object_create(info->mti_ctxt, next,
                                       &info->mti_spec, ma);
                 if (rc == 0) {
@@ -163,6 +165,7 @@ static int mdt_reint_setattr(struct mdt_thread_info *info)
         if (rc != 0)
                 GOTO(out_unlock, rc);
 
+        info->mti_attr.ma_need = MA_INODE;
         rc = mo_attr_get(info->mti_ctxt, next, &info->mti_attr);
         if (rc != 0)
                 GOTO(out_unlock, rc);
@@ -290,11 +293,15 @@ static int mdt_reint_unlink(struct mdt_thread_info *info)
         if (!ma->ma_lmm || !ma->ma_cookie)
                 GOTO(out_unlock_parent, rc = -EINVAL);
 
+        /*Now we can only make sure we need MA_INODE, in mdd layer,
+         *will check whether need MA_LOV and MA_COOKIE*/
+        ma->ma_need = MA_INODE;
         rc = mdo_unlink(info->mti_ctxt, mdt_object_child(mp),
                         mdt_object_child(mc), rr->rr_name, ma);
         if (rc)
                 GOTO(out_unlock_child, rc);
 
+        
         rc = mdt_handle_last_unlink(info, mc, ma);
 
         GOTO(out_unlock_child, rc);
@@ -537,11 +544,12 @@ static int mdt_reint_rename(struct mdt_thread_info *info)
         if (!ma->ma_lmm || !ma->ma_cookie)
                 GOTO(out_unlock_new, rc = -EINVAL);
 
+        ma->ma_need = MA_INODE | MA_LOV | MA_COOKIE;
         rc = mdo_rename(info->mti_ctxt, mdt_object_child(msrcdir),
                         mdt_object_child(mtgtdir), old_fid,
                         rr->rr_name, mnew ? mdt_object_child(mnew): NULL,
                         rr->rr_tgt, ma);
-        /*TODO: handle tgt object*/
+        /*TODO: handle last link of tgt object*/
 
 out_unlock_new:
         if (mnew) {