diff options
-rw-r--r-- | fs/ceph/mds_client.c | 11 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 2 |
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); |
1872 | out_err: | 1883 | out_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 | ||