diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index acfb8c2a5549e2893b2a3df7490deaf5b22f730c..08d2243a20ca264faf5228557c224f90ed600a06 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -21,6 +21,7 @@ tbd         Cluster File Systems, Inc. <info@clusterfs.com>
 	- protect MDS inode fsdata with stronger locking (2313)
 	- better error messages when a client is rejected during recovery (1505)
 	- avoid cancelling locks which were never granted, after failure (2330)
+	- fix i_sem/journal inversion in mds_client_add (2333)
        * miscellania
 	- allow configurable automake binary, for testing new versions
 	- small update to the lfs documentation
diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c
index f0f7552734d7078a106b7c4ef75f834ecbe9c336..77317189804c5a7b98e518d27b73917a07ee1aef 100644
--- a/lustre/mds/mds_fs.c
+++ b/lustre/mds/mds_fs.c
@@ -101,39 +101,11 @@ int mds_client_add(struct obd_device *obd, struct mds_obd *mds,
                 struct obd_run_ctxt saved;
                 loff_t off = med->med_off;
                 struct file *file = mds->mds_rcvd_filp;
-                void *handle;
-                int rc, err;
+                int rc;
 
                 push_ctxt(&saved, &obd->obd_ctxt, NULL);
-                /* We need to start a transaction here first, to avoid a
-                 * possible ordering deadlock on last_rcvd->i_sem and the
-                 * journal lock. In most places we start the journal handle
-                 * first (because we do compound transactions), and then
-                 * later do the write into last_rcvd, which gets i_sem.
-                 *
-                 * Without this transaction, clients connecting at the same
-                 * time other MDS operations are ongoing get last_rcvd->i_sem
-                 * first (in generic_file_write()) and start the journal
-                 * transaction afterwards, and can deadlock with other ops.
-                 *
-                 * We use FSFILT_OP_SETATTR because it is smallest, but all
-                 * ops include enough space for the last_rcvd update so we
-                 * could use any of them, or maybe an FSFILT_OP_NONE is best?
-                 */
-                handle = fsfilt_start(obd, file->f_dentry->d_inode,
-                                      FSFILT_OP_SETATTR, NULL);
-                if (IS_ERR(handle)) {
-                        rc = PTR_ERR(handle);
-                        CERROR("unable to start transaction: rc %d\n", rc);
-                } else {
-                        rc = fsfilt_write_record(obd, file, med->med_mcd,
-                                                 sizeof(*med->med_mcd),
-                                                 &off, 1);
-                        err = fsfilt_commit(obd, file->f_dentry->d_inode,
-                                            handle, 1);
-                        if (rc == 0)
-                                rc = err;
-                }
+                rc = fsfilt_write_record(obd, file, med->med_mcd,
+                                         sizeof(*med->med_mcd), &off, 1);
                 pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
                 if (rc)
@@ -175,9 +147,8 @@ int mds_client_free(struct obd_export *exp, int clear_client)
         if (clear_client) {
                 memset(&zero_mcd, 0, sizeof zero_mcd);
                 push_ctxt(&saved, &obd->obd_ctxt, NULL);
-                rc = fsfilt_write_record(obd, mds->mds_rcvd_filp,
-                                              &zero_mcd, sizeof(zero_mcd),
-                                              &med->med_off, 1);
+                rc = fsfilt_write_record(obd, mds->mds_rcvd_filp, &zero_mcd,
+                                         sizeof(zero_mcd), &med->med_off, 1);
                 pop_ctxt(&saved, &obd->obd_ctxt, NULL);
 
                 CDEBUG(rc == 0 ? D_INFO : D_ERROR,