aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/mds_client.c11
-rw-r--r--fs/ceph/mds_client.h2
2 files changed, 13 insertions, 0 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index b3b19f05b821..c0568fe3c0ba 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1181,6 +1181,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
1181 if (!req) 1181 if (!req)
1182 return ERR_PTR(-ENOMEM); 1182 return ERR_PTR(-ENOMEM);
1183 1183
1184 mutex_init(&req->r_fill_mutex);
1184 req->r_started = jiffies; 1185 req->r_started = jiffies;
1185 req->r_resend_mds = -1; 1186 req->r_resend_mds = -1;
1186 INIT_LIST_HEAD(&req->r_unsafe_dir_item); 1187 INIT_LIST_HEAD(&req->r_unsafe_dir_item);
@@ -1715,8 +1716,16 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
1715 err = le32_to_cpu(req->r_reply_info.head->result); 1716 err = le32_to_cpu(req->r_reply_info.head->result);
1716 } else if (err < 0) { 1717 } else if (err < 0) {
1717 dout("aborted request %lld with %d\n", req->r_tid, err); 1718 dout("aborted request %lld with %d\n", req->r_tid, err);
1719
1720 /*
1721 * ensure we aren't running concurrently with
1722 * ceph_fill_trace or ceph_readdir_prepopulate, which
1723 * rely on locks (dir mutex) held by our caller.
1724 */
1725 mutex_lock(&req->r_fill_mutex);
1718 req->r_err = err; 1726 req->r_err = err;
1719 req->r_aborted = true; 1727 req->r_aborted = true;
1728 mutex_unlock(&req->r_fill_mutex);
1720 1729
1721 if (req->r_locked_dir && 1730 if (req->r_locked_dir &&
1722 (req->r_op & CEPH_MDS_OP_WRITE)) { 1731 (req->r_op & CEPH_MDS_OP_WRITE)) {
@@ -1861,12 +1870,14 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
1861 } 1870 }
1862 1871
1863 /* insert trace into our cache */ 1872 /* insert trace into our cache */
1873 mutex_lock(&req->r_fill_mutex);
1864 err = ceph_fill_trace(mdsc->client->sb, req, req->r_session); 1874 err = ceph_fill_trace(mdsc->client->sb, req, req->r_session);
1865 if (err == 0) { 1875 if (err == 0) {
1866 if (result == 0 && rinfo->dir_nr) 1876 if (result == 0 && rinfo->dir_nr)
1867 ceph_readdir_prepopulate(req, req->r_session); 1877 ceph_readdir_prepopulate(req, req->r_session);
1868 ceph_unreserve_caps(&req->r_caps_reservation); 1878 ceph_unreserve_caps(&req->r_caps_reservation);
1869 } 1879 }
1880 mutex_unlock(&req->r_fill_mutex);
1870 1881
1871 up_read(&mdsc->snap_rwsem); 1882 up_read(&mdsc->snap_rwsem);
1872out_err: 1883out_err:
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 0b1dd10be39a..141a265bda75 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -165,6 +165,8 @@ struct ceph_mds_request {
165 struct inode *r_locked_dir; /* dir (if any) i_mutex locked by vfs */ 165 struct inode *r_locked_dir; /* dir (if any) i_mutex locked by vfs */
166 struct inode *r_target_inode; /* resulting inode */ 166 struct inode *r_target_inode; /* resulting inode */
167 167
168 struct mutex r_fill_mutex;
169
168 union ceph_mds_request_args r_args; 170 union ceph_mds_request_args r_args;
169 int r_fmode; /* file mode, if expecting cap */ 171 int r_fmode; /* file mode, if expecting cap */
170 172