Whamcloud - gitweb
Add journal wrapping calls to all of the mds_reint operations. We also
authoradilger <adilger>
Thu, 4 Apr 2002 09:25:29 +0000 (09:25 +0000)
committeradilger <adilger>
Thu, 4 Apr 2002 09:25:29 +0000 (09:25 +0000)
use the mds_fs_setattr method to change the fields in the inode, as this
will properly mark the inode dirty and ensure it is written to disk.

This fixes the problem of updates to the MDS inode not being written to
disk because the dentry and inode are being discarded too quickly.

The journal wrapping of all reint operations will make the addition of
calls to atomically update last recieved trivial, so it is time well spent.

lustre/include/linux/lustre_mds.h
lustre/mds/handler.c
lustre/mds/mds_ext2.c
lustre/mds/mds_ext3.c
lustre/mds/mds_reint.c

index 101d249..692aebc 100644 (file)
@@ -112,7 +112,7 @@ int mdc_create_client(char *uuid, struct ptlrpc_client *cl);
 struct mds_fs_operations {
         void   *(* fs_start)(struct inode *inode, int op);
         int     (* fs_commit)(struct inode *inode, void *handle);
-        int     (* fs_setattr)(struct inode *inode, void *handle,
+        int     (* fs_setattr)(struct dentry *dentry, void *handle,
                                struct iattr *iattr);
         int     (* fs_set_objid)(struct inode *inode, void *handle, obd_id id);
         void    (* fs_get_objid)(struct inode *inode, obd_id *id);
@@ -122,8 +122,13 @@ struct mds_fs_operations {
         void    (* cl_delete_inode)(struct inode *inode);
 };
 
-#define MDS_FSOP_UNLINK           1
-#define MDS_FSOP_RMDIR            2
+#define MDS_FSOP_UNLINK         1
+#define MDS_FSOP_RMDIR          2
+#define MDS_FSOP_RENAME         3
+#define MDS_FSOP_CREATE         4
+#define MDS_FSOP_MKDIR          5
+#define MDS_FSOP_SYMLINK        6
+#define MDS_FSOP_MKNOD          7
 
 static inline void *mds_fs_start(struct mds_obd *mds, struct inode *inode,
                                  int op)
@@ -137,10 +142,10 @@ static inline int mds_fs_commit(struct mds_obd *mds, struct inode *inode,
         return mds->mds_fsops->fs_commit(inode, handle);
 }
 
-static inline int mds_fs_setattr(struct mds_obd *mds, struct inode *inode,
+static inline int mds_fs_setattr(struct mds_obd *mds, struct dentry *dentry,
                                  void *handle, struct iattr *iattr)
 {
-        return mds->mds_fsops->fs_setattr(inode, handle, iattr);
+        return mds->mds_fsops->fs_setattr(dentry, handle, iattr);
 }
 
 static inline int mds_fs_set_objid(struct mds_obd *mds, struct inode *inode,
index 46fb5b8..e0df185 100644 (file)
@@ -459,6 +459,8 @@ static int mds_prep(struct obd_device *obddev)
         push_ctxt(&saved, &mds->mds_ctxt);
         err = simple_mkdir(current->fs->pwd, "ROOT", 0700);
         err = simple_mkdir(current->fs->pwd, "FH", 0700);
+        pop_ctxt(&saved);
+
         /*
          * Replace the client filesystem delete_inode method with our own,
          * so that we can clear the object ID before the inode is deleted.
@@ -491,7 +493,7 @@ static int mds_setup(struct obd_device *obddev, obd_count len, void *buf)
         struct obd_ioctl_data* data = buf;
         struct mds_obd *mds = &obddev->u.mds;
         struct vfsmount *mnt;
-        int err;
+        int err = 0;
         ENTRY;
 
 #ifdef CONFIG_DEV_RDONLY
index 883295d..c03e867 100644 (file)
@@ -21,7 +21,7 @@
 
 static void *mds_ext2_start(struct inode *inode, int nblocks)
 {
-        return 0;
+        return (void *)1;
 }
 
 static int mds_ext2_stop(struct inode *inode, void *handle)
@@ -29,9 +29,11 @@ static int mds_ext2_stop(struct inode *inode, void *handle)
         return 0;
 }
 
-static int mds_ext2_setattr(struct inode *inode, void *handle,
+static int mds_ext2_setattr(struct dentry *dentry, void *handle,
                             struct iattr *iattr)
 {
+        struct inode *inode = dentry->d_inode;
+
         /* a _really_ horrible hack to avoid removing the data stored
            in the block pointers; this data is the object id
            this will go into an extended attribute at some point.
@@ -49,7 +51,10 @@ static int mds_ext2_setattr(struct inode *inode, void *handle,
                 }
         }
 
-        return 0;
+        if (inode->i_op->setattr)
+                return inode->i_op->setattr(dentry, iattr);
+        else
+                return inode_setattr(inode, iattr);
 }
 
 /*
index 6a9cd50..a52ae51 100644 (file)
  * We don't currently need any additional blocks for rmdir and
  * unlink transactions because we are storing the OST oa_id inside
  * the inode (which we will be changing anyways as part of this
- * transaction).  When we store the oa_id in an EA (which may be
- * in an external block) we need to increase nblocks by 1.
+ * transaction).
  */
 static void *mds_ext3_start(struct inode *inode, int op)
 {
-        int nblocks = 0;
+        /* For updates to the last recieved file */
+        int nblocks = EXT3_DATA_TRANS_BLOCKS;
 
         switch(op) {
         case MDS_FSOP_RMDIR:
-        case MDS_FSOP_UNLINK:   nblocks = EXT3_DELETE_TRANS_BLOCKS; break;
+        case MDS_FSOP_UNLINK:
+                nblocks += EXT3_DELETE_TRANS_BLOCKS; break;
+        case MDS_FSOP_RENAME:
+                nblocks += EXT3_DATA_TRANS_BLOCKS;
+        case MDS_FSOP_CREATE:
+                // FIXME: when we store oa_id in an EA we need more blocks
+                // nblocks += 0;
+        case MDS_FSOP_MKDIR:
+        case MDS_FSOP_SYMLINK:
+                /* Create new directory or symlink (more data blocks) */
+                nblocks += 2;
+        case MDS_FSOP_MKNOD:
+                /* Change parent directory + setattr on new inode */
+                nblocks += EXT3_DATA_TRANS_BLOCKS + 3;
         }
 
         return journal_start(EXT3_JOURNAL(inode), nblocks);
@@ -45,9 +58,11 @@ static int mds_ext3_commit(struct inode *inode, void *handle)
         return journal_stop((handle_t *)handle);
 }
 
-static int mds_ext3_setattr(struct inode *inode, void *handle,
+static int mds_ext3_setattr(struct dentry *dentry, void *handle,
                             struct iattr *iattr)
 {
+        struct inode *inode = dentry->d_inode;
+
         /* a _really_ horrible hack to avoid removing the data stored
            in the block pointers; this data is the object id
            this will go into an extended attribute at some point.
@@ -72,12 +87,18 @@ static int mds_ext3_setattr(struct inode *inode, void *handle,
                 }
         }
 
-        return 0;
+        if (inode->i_op->setattr)
+                return inode->i_op->setattr(dentry, iattr);
+        else
+                return inode_setattr(inode, iattr);
 }
 
 /*
  * FIXME: nasty hack - store the object id in the first two
  *        direct block spots.  This should be done with EAs...
+ *        Note also that this does not currently mark the inode
+ *        dirty (it currently is used with other operations that
+ *        subsequently also mark the inode dirty).
  */
 #define EXT3_OBJID_FL   0x40000000
 static int mds_ext3_set_objid(struct inode *inode, void *handle, obd_id id)
index 64e721e..1d1cd59 100644 (file)
@@ -40,9 +40,8 @@ extern struct ptlrpc_request *mds_prep_req(int size, int opcode, int namelen, ch
 
 static int mds_reint_setattr(struct mds_update_record *rec, struct ptlrpc_request *req)
 {
-        struct dentry *de;
-        struct inode *inode;
         struct mds_obd *mds = &req->rq_obd->u.mds;
+        struct dentry *de;
 
         de = mds_fid2dentry(mds, rec->ur_fid1, NULL);
         if (IS_ERR(de) || OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_SETATTR)) {
@@ -50,17 +49,12 @@ static int mds_reint_setattr(struct mds_update_record *rec, struct ptlrpc_reques
                 RETURN(0);
         }
 
-        inode = de->d_inode;
-        CDEBUG(D_INODE, "ino %ld\n", inode->i_ino);
+        CDEBUG(D_INODE, "ino %ld\n", de->d_inode->i_ino);
 
-        mds_fs_setattr(mds, inode, NULL, &rec->ur_iattr);
+        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE,
+                       de->d_inode->i_sb->s_dev);
 
-        OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_SETATTR_WRITE, inode->i_sb->s_dev);
-
-        if (inode->i_op->setattr)
-                req->rq_rephdr->status = inode->i_op->setattr(de, &rec->ur_iattr);
-        else
-                req->rq_rephdr->status = inode_setattr(inode, &rec->ur_iattr);
+        req->rq_rephdr->status = mds_fs_setattr(mds, de, NULL, &rec->ur_iattr);
 
         l_dput(de);
         RETURN(0);
@@ -75,6 +69,7 @@ static int mds_reint_create(struct mds_update_record *rec,
         struct mds_obd *mds = &req->rq_obd->u.mds;
         struct dentry *dchild = NULL;
         struct inode *dir;
+        void *handle;
         int rc = 0;
         ENTRY;
 
@@ -104,16 +99,25 @@ static int mds_reint_create(struct mds_update_record *rec,
 
         switch (type) {
         case S_IFREG: {
+                handle = mds_fs_start(mds, dir, MDS_FSOP_CREATE);
+                if (!handle)
+                        GOTO(out_reint_create, PTR_ERR(handle));
                 rc = vfs_create(dir, dchild, rec->ur_mode);
                 EXIT;
                 break;
         }
         case S_IFDIR: {
+                handle = mds_fs_start(mds, dir, MDS_FSOP_MKDIR);
+                if (!handle)
+                        GOTO(out_reint_create, PTR_ERR(handle));
                 rc = vfs_mkdir(dir, dchild, rec->ur_mode);
                 EXIT;
                 break;
         }
         case S_IFLNK: {
+                handle = mds_fs_start(mds, dir, MDS_FSOP_SYMLINK);
+                if (!handle)
+                        GOTO(out_reint_create, PTR_ERR(handle));
                 rc = vfs_symlink(dir, dchild, rec->ur_tgt);
                 EXIT;
                 break;
@@ -123,28 +127,47 @@ static int mds_reint_create(struct mds_update_record *rec,
         case S_IFIFO:
         case S_IFSOCK: {
                 int rdev = rec->ur_id;
+                handle = mds_fs_start(mds, dir, MDS_FSOP_MKNOD);
+                if (!handle)
+                        GOTO(out_reint_create, PTR_ERR(handle));
                 rc = vfs_mknod(dir, dchild, rec->ur_mode, rdev);
                 EXIT;
                 break;
         }
         }
 
-        if (!rc) {
-                if (type == S_IFREG)
-                        rc = mds_fs_set_objid(mds, dchild->d_inode,
-                                              NULL, rec->ur_id);
-                dchild->d_inode->i_atime = rec->ur_time;
-                dchild->d_inode->i_ctime = rec->ur_time;
-                dchild->d_inode->i_mtime = rec->ur_time;
-                dchild->d_inode->i_uid = rec->ur_uid;
-                dchild->d_inode->i_gid = rec->ur_gid;
-                rep->ino = dchild->d_inode->i_ino;
-                rep->generation = dchild->d_inode->i_generation;
-        } else {
+        if (rc) {
                 CERROR("error during create: %d\n", rc);
                 LBUG();
+                GOTO(out_reint_commit, rc);
+        } else {
+                struct iattr iattr;
+                struct inode *inode = dchild->d_inode;
+
+                if (type == S_IFREG) {
+                        rc = mds_fs_set_objid(mds, inode, handle, rec->ur_id);
+                        if (rc)
+                                CERROR("error setting objid for %ld\n",
+                                       inode->i_ino);
+                }
+
+                iattr.ia_atime = rec->ur_time;
+                iattr.ia_ctime = rec->ur_time;
+                iattr.ia_mtime = rec->ur_time;
+                iattr.ia_uid = rec->ur_uid;
+                iattr.ia_gid = rec->ur_gid;
+                iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_ATIME |
+                                 ATTR_MTIME | ATTR_CTIME;
+
+                rc = mds_fs_setattr(mds, dchild, handle, &iattr);
+
+                rep->ino = inode->i_ino;
+                rep->generation = inode->i_generation;
         }
 
+out_reint_commit:
+        rc = mds_fs_commit(mds, dir, handle);
+
 out_reint_create:
         req->rq_rephdr->status = rc;
         l_dput(dchild);