aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c91
1 files changed, 46 insertions, 45 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 5323c330bbf3..1f72b00447c4 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -569,7 +569,8 @@ retry:
569 list_add_tail(&cap->session_caps, &session->s_caps); 569 list_add_tail(&cap->session_caps, &session->s_caps);
570 session->s_nr_caps++; 570 session->s_nr_caps++;
571 spin_unlock(&session->s_cap_lock); 571 spin_unlock(&session->s_cap_lock);
572 } 572 } else if (new_cap)
573 ceph_put_cap(mdsc, new_cap);
573 574
574 if (!ci->i_snap_realm) { 575 if (!ci->i_snap_realm) {
575 /* 576 /*
@@ -819,7 +820,7 @@ int __ceph_caps_used(struct ceph_inode_info *ci)
819 used |= CEPH_CAP_FILE_CACHE; 820 used |= CEPH_CAP_FILE_CACHE;
820 if (ci->i_wr_ref) 821 if (ci->i_wr_ref)
821 used |= CEPH_CAP_FILE_WR; 822 used |= CEPH_CAP_FILE_WR;
822 if (ci->i_wrbuffer_ref) 823 if (ci->i_wb_ref || ci->i_wrbuffer_ref)
823 used |= CEPH_CAP_FILE_BUFFER; 824 used |= CEPH_CAP_FILE_BUFFER;
824 return used; 825 return used;
825} 826}
@@ -1331,10 +1332,11 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci)
1331} 1332}
1332 1333
1333/* 1334/*
1334 * Mark caps dirty. If inode is newly dirty, add to the global dirty 1335 * Mark caps dirty. If inode is newly dirty, return the dirty flags.
1335 * list. 1336 * Caller is then responsible for calling __mark_inode_dirty with the
1337 * returned flags value.
1336 */ 1338 */
1337void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) 1339int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
1338{ 1340{
1339 struct ceph_mds_client *mdsc = 1341 struct ceph_mds_client *mdsc =
1340 ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc; 1342 ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc;
@@ -1357,7 +1359,7 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
1357 list_add(&ci->i_dirty_item, &mdsc->cap_dirty); 1359 list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
1358 spin_unlock(&mdsc->cap_dirty_lock); 1360 spin_unlock(&mdsc->cap_dirty_lock);
1359 if (ci->i_flushing_caps == 0) { 1361 if (ci->i_flushing_caps == 0) {
1360 igrab(inode); 1362 ihold(inode);
1361 dirty |= I_DIRTY_SYNC; 1363 dirty |= I_DIRTY_SYNC;
1362 } 1364 }
1363 } 1365 }
@@ -1365,9 +1367,8 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
1365 if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && 1367 if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) &&
1366 (mask & CEPH_CAP_FILE_BUFFER)) 1368 (mask & CEPH_CAP_FILE_BUFFER))
1367 dirty |= I_DIRTY_DATASYNC; 1369 dirty |= I_DIRTY_DATASYNC;
1368 if (dirty)
1369 __mark_inode_dirty(inode, dirty);
1370 __cap_delay_requeue(mdsc, ci); 1370 __cap_delay_requeue(mdsc, ci);
1371 return dirty;
1371} 1372}
1372 1373
1373/* 1374/*
@@ -1990,11 +1991,11 @@ static void __take_cap_refs(struct ceph_inode_info *ci, int got)
1990 if (got & CEPH_CAP_FILE_WR) 1991 if (got & CEPH_CAP_FILE_WR)
1991 ci->i_wr_ref++; 1992 ci->i_wr_ref++;
1992 if (got & CEPH_CAP_FILE_BUFFER) { 1993 if (got & CEPH_CAP_FILE_BUFFER) {
1993 if (ci->i_wrbuffer_ref == 0) 1994 if (ci->i_wb_ref == 0)
1994 igrab(&ci->vfs_inode); 1995 ihold(&ci->vfs_inode);
1995 ci->i_wrbuffer_ref++; 1996 ci->i_wb_ref++;
1996 dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n", 1997 dout("__take_cap_refs %p wb %d -> %d (?)\n",
1997 &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref); 1998 &ci->vfs_inode, ci->i_wb_ref-1, ci->i_wb_ref);
1998 } 1999 }
1999} 2000}
2000 2001
@@ -2169,12 +2170,12 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
2169 if (--ci->i_rdcache_ref == 0) 2170 if (--ci->i_rdcache_ref == 0)
2170 last++; 2171 last++;
2171 if (had & CEPH_CAP_FILE_BUFFER) { 2172 if (had & CEPH_CAP_FILE_BUFFER) {
2172 if (--ci->i_wrbuffer_ref == 0) { 2173 if (--ci->i_wb_ref == 0) {
2173 last++; 2174 last++;
2174 put++; 2175 put++;
2175 } 2176 }
2176 dout("put_cap_refs %p wrbuffer %d -> %d (?)\n", 2177 dout("put_cap_refs %p wb %d -> %d (?)\n",
2177 inode, ci->i_wrbuffer_ref+1, ci->i_wrbuffer_ref); 2178 inode, ci->i_wb_ref+1, ci->i_wb_ref);
2178 } 2179 }
2179 if (had & CEPH_CAP_FILE_WR) 2180 if (had & CEPH_CAP_FILE_WR)
2180 if (--ci->i_wr_ref == 0) { 2181 if (--ci->i_wr_ref == 0) {
@@ -2634,6 +2635,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
2634 struct ceph_mds_session *session, 2635 struct ceph_mds_session *session,
2635 int *open_target_sessions) 2636 int *open_target_sessions)
2636{ 2637{
2638 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
2637 struct ceph_inode_info *ci = ceph_inode(inode); 2639 struct ceph_inode_info *ci = ceph_inode(inode);
2638 int mds = session->s_mds; 2640 int mds = session->s_mds;
2639 unsigned mseq = le32_to_cpu(ex->migrate_seq); 2641 unsigned mseq = le32_to_cpu(ex->migrate_seq);
@@ -2670,6 +2672,19 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
2670 * export targets, so that we get the matching IMPORT 2672 * export targets, so that we get the matching IMPORT
2671 */ 2673 */
2672 *open_target_sessions = 1; 2674 *open_target_sessions = 1;
2675
2676 /*
2677 * we can't flush dirty caps that we've seen the
2678 * EXPORT but no IMPORT for
2679 */
2680 spin_lock(&mdsc->cap_dirty_lock);
2681 if (!list_empty(&ci->i_dirty_item)) {
2682 dout(" moving %p to cap_dirty_migrating\n",
2683 inode);
2684 list_move(&ci->i_dirty_item,
2685 &mdsc->cap_dirty_migrating);
2686 }
2687 spin_unlock(&mdsc->cap_dirty_lock);
2673 } 2688 }
2674 __ceph_remove_cap(cap); 2689 __ceph_remove_cap(cap);
2675 } 2690 }
@@ -2707,6 +2722,13 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
2707 ci->i_cap_exporting_issued = 0; 2722 ci->i_cap_exporting_issued = 0;
2708 ci->i_cap_exporting_mseq = 0; 2723 ci->i_cap_exporting_mseq = 0;
2709 ci->i_cap_exporting_mds = -1; 2724 ci->i_cap_exporting_mds = -1;
2725
2726 spin_lock(&mdsc->cap_dirty_lock);
2727 if (!list_empty(&ci->i_dirty_item)) {
2728 dout(" moving %p back to cap_dirty\n", inode);
2729 list_move(&ci->i_dirty_item, &mdsc->cap_dirty);
2730 }
2731 spin_unlock(&mdsc->cap_dirty_lock);
2710 } else { 2732 } else {
2711 dout("handle_cap_import inode %p ci %p mds%d mseq %d\n", 2733 dout("handle_cap_import inode %p ci %p mds%d mseq %d\n",
2712 inode, ci, mds, mseq); 2734 inode, ci, mds, mseq);
@@ -2910,38 +2932,16 @@ void ceph_check_delayed_caps(struct ceph_mds_client *mdsc)
2910 */ 2932 */
2911void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc) 2933void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
2912{ 2934{
2913 struct ceph_inode_info *ci, *nci = NULL; 2935 struct ceph_inode_info *ci;
2914 struct inode *inode, *ninode = NULL; 2936 struct inode *inode;
2915 struct list_head *p, *n;
2916 2937
2917 dout("flush_dirty_caps\n"); 2938 dout("flush_dirty_caps\n");
2918 spin_lock(&mdsc->cap_dirty_lock); 2939 spin_lock(&mdsc->cap_dirty_lock);
2919 list_for_each_safe(p, n, &mdsc->cap_dirty) { 2940 while (!list_empty(&mdsc->cap_dirty)) {
2920 if (nci) { 2941 ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info,
2921 ci = nci; 2942 i_dirty_item);
2922 inode = ninode; 2943 inode = igrab(&ci->vfs_inode);
2923 ci->i_ceph_flags &= ~CEPH_I_NOFLUSH; 2944 dout("flush_dirty_caps %p\n", inode);
2924 dout("flush_dirty_caps inode %p (was next inode)\n",
2925 inode);
2926 } else {
2927 ci = list_entry(p, struct ceph_inode_info,
2928 i_dirty_item);
2929 inode = igrab(&ci->vfs_inode);
2930 BUG_ON(!inode);
2931 dout("flush_dirty_caps inode %p\n", inode);
2932 }
2933 if (n != &mdsc->cap_dirty) {
2934 nci = list_entry(n, struct ceph_inode_info,
2935 i_dirty_item);
2936 ninode = igrab(&nci->vfs_inode);
2937 BUG_ON(!ninode);
2938 nci->i_ceph_flags |= CEPH_I_NOFLUSH;
2939 dout("flush_dirty_caps next inode %p, noflush\n",
2940 ninode);
2941 } else {
2942 nci = NULL;
2943 ninode = NULL;
2944 }
2945 spin_unlock(&mdsc->cap_dirty_lock); 2945 spin_unlock(&mdsc->cap_dirty_lock);
2946 if (inode) { 2946 if (inode) {
2947 ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, 2947 ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH,
@@ -2951,6 +2951,7 @@ void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc)
2951 spin_lock(&mdsc->cap_dirty_lock); 2951 spin_lock(&mdsc->cap_dirty_lock);
2952 } 2952 }
2953 spin_unlock(&mdsc->cap_dirty_lock); 2953 spin_unlock(&mdsc->cap_dirty_lock);
2954 dout("flush_dirty_caps done\n");
2954} 2955}
2955 2956
2956/* 2957/*