diff options
| -rw-r--r-- | fs/ceph/caps.c | 19 | ||||
| -rw-r--r-- | fs/ceph/snap.c | 2 | ||||
| -rw-r--r-- | fs/ceph/super.h | 3 |
3 files changed, 18 insertions, 6 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 9fbe9019155c..b01c316a8148 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
| @@ -1195,10 +1195,14 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
| 1195 | * asynchronously back to the MDS once sync writes complete and dirty | 1195 | * asynchronously back to the MDS once sync writes complete and dirty |
| 1196 | * data is written out. | 1196 | * data is written out. |
| 1197 | * | 1197 | * |
| 1198 | * Unless @again is true, skip cap_snaps that were already sent to | ||
| 1199 | * the MDS (i.e., during this session). | ||
| 1200 | * | ||
| 1198 | * Called under i_lock. Takes s_mutex as needed. | 1201 | * Called under i_lock. Takes s_mutex as needed. |
| 1199 | */ | 1202 | */ |
| 1200 | void __ceph_flush_snaps(struct ceph_inode_info *ci, | 1203 | void __ceph_flush_snaps(struct ceph_inode_info *ci, |
| 1201 | struct ceph_mds_session **psession) | 1204 | struct ceph_mds_session **psession, |
| 1205 | int again) | ||
| 1202 | __releases(ci->vfs_inode->i_lock) | 1206 | __releases(ci->vfs_inode->i_lock) |
| 1203 | __acquires(ci->vfs_inode->i_lock) | 1207 | __acquires(ci->vfs_inode->i_lock) |
| 1204 | { | 1208 | { |
| @@ -1240,6 +1244,13 @@ retry: | |||
| 1240 | dout("no auth cap (migrating?), doing nothing\n"); | 1244 | dout("no auth cap (migrating?), doing nothing\n"); |
| 1241 | goto out; | 1245 | goto out; |
| 1242 | } | 1246 | } |
| 1247 | |||
| 1248 | /* only flush each capsnap once */ | ||
| 1249 | if (!again && !list_empty(&capsnap->flushing_item)) { | ||
| 1250 | dout("already flushed %p, skipping\n", capsnap); | ||
| 1251 | continue; | ||
| 1252 | } | ||
| 1253 | |||
| 1243 | mds = ci->i_auth_cap->session->s_mds; | 1254 | mds = ci->i_auth_cap->session->s_mds; |
| 1244 | mseq = ci->i_auth_cap->mseq; | 1255 | mseq = ci->i_auth_cap->mseq; |
| 1245 | 1256 | ||
| @@ -1314,7 +1325,7 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) | |||
| 1314 | struct inode *inode = &ci->vfs_inode; | 1325 | struct inode *inode = &ci->vfs_inode; |
| 1315 | 1326 | ||
| 1316 | spin_lock(&inode->i_lock); | 1327 | spin_lock(&inode->i_lock); |
| 1317 | __ceph_flush_snaps(ci, NULL); | 1328 | __ceph_flush_snaps(ci, NULL, 0); |
| 1318 | spin_unlock(&inode->i_lock); | 1329 | spin_unlock(&inode->i_lock); |
| 1319 | } | 1330 | } |
| 1320 | 1331 | ||
| @@ -1477,7 +1488,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
| 1477 | 1488 | ||
| 1478 | /* flush snaps first time around only */ | 1489 | /* flush snaps first time around only */ |
| 1479 | if (!list_empty(&ci->i_cap_snaps)) | 1490 | if (!list_empty(&ci->i_cap_snaps)) |
| 1480 | __ceph_flush_snaps(ci, &session); | 1491 | __ceph_flush_snaps(ci, &session, 0); |
| 1481 | goto retry_locked; | 1492 | goto retry_locked; |
| 1482 | retry: | 1493 | retry: |
| 1483 | spin_lock(&inode->i_lock); | 1494 | spin_lock(&inode->i_lock); |
| @@ -1894,7 +1905,7 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc, | |||
| 1894 | if (cap && cap->session == session) { | 1905 | if (cap && cap->session == session) { |
| 1895 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, | 1906 | dout("kick_flushing_caps %p cap %p capsnap %p\n", inode, |
| 1896 | cap, capsnap); | 1907 | cap, capsnap); |
| 1897 | __ceph_flush_snaps(ci, &session); | 1908 | __ceph_flush_snaps(ci, &session, 1); |
| 1898 | } else { | 1909 | } else { |
| 1899 | pr_err("%p auth cap %p not mds%d ???\n", inode, | 1910 | pr_err("%p auth cap %p not mds%d ???\n", inode, |
| 1900 | cap, session->s_mds); | 1911 | cap, session->s_mds); |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 9e6eef14b7df..190b6c4a6f2b 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
| @@ -717,7 +717,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc) | |||
| 717 | igrab(inode); | 717 | igrab(inode); |
| 718 | spin_unlock(&mdsc->snap_flush_lock); | 718 | spin_unlock(&mdsc->snap_flush_lock); |
| 719 | spin_lock(&inode->i_lock); | 719 | spin_lock(&inode->i_lock); |
| 720 | __ceph_flush_snaps(ci, &session); | 720 | __ceph_flush_snaps(ci, &session, 0); |
| 721 | spin_unlock(&inode->i_lock); | 721 | spin_unlock(&inode->i_lock); |
| 722 | iput(inode); | 722 | iput(inode); |
| 723 | spin_lock(&mdsc->snap_flush_lock); | 723 | spin_lock(&mdsc->snap_flush_lock); |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index c80bfbe27b05..b87638e84c4b 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
| @@ -828,7 +828,8 @@ extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); | |||
| 828 | extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, | 828 | extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, |
| 829 | struct ceph_snap_context *snapc); | 829 | struct ceph_snap_context *snapc); |
| 830 | extern void __ceph_flush_snaps(struct ceph_inode_info *ci, | 830 | extern void __ceph_flush_snaps(struct ceph_inode_info *ci, |
| 831 | struct ceph_mds_session **psession); | 831 | struct ceph_mds_session **psession, |
| 832 | int again); | ||
| 832 | extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, | 833 | extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, |
| 833 | struct ceph_mds_session *session); | 834 | struct ceph_mds_session *session); |
| 834 | extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); | 835 | extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); |
