@@ -1632,8 +1632,8 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
16321632 * Caller must hold session s_mutex.
16331633 */
16341634int ceph_iterate_session_caps (struct ceph_mds_session * session ,
1635- int (* cb )(struct inode * , struct ceph_cap * ,
1636- void * ), void * arg )
1635+ int (* cb )(struct inode * , int mds , void * ) ,
1636+ void * arg )
16371637{
16381638 struct list_head * p ;
16391639 struct ceph_cap * cap ;
@@ -1645,13 +1645,16 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
16451645 spin_lock (& session -> s_cap_lock );
16461646 p = session -> s_caps .next ;
16471647 while (p != & session -> s_caps ) {
1648+ int mds ;
1649+
16481650 cap = list_entry (p , struct ceph_cap , session_caps );
16491651 inode = igrab (& cap -> ci -> netfs .inode );
16501652 if (!inode ) {
16511653 p = p -> next ;
16521654 continue ;
16531655 }
16541656 session -> s_cap_iterator = cap ;
1657+ mds = cap -> mds ;
16551658 spin_unlock (& session -> s_cap_lock );
16561659
16571660 if (last_inode ) {
@@ -1663,7 +1666,7 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
16631666 old_cap = NULL ;
16641667 }
16651668
1666- ret = cb (inode , cap , arg );
1669+ ret = cb (inode , mds , arg );
16671670 last_inode = inode ;
16681671
16691672 spin_lock (& session -> s_cap_lock );
@@ -1696,20 +1699,25 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session,
16961699 return ret ;
16971700}
16981701
1699- static int remove_session_caps_cb (struct inode * inode , struct ceph_cap * cap ,
1700- void * arg )
1702+ static int remove_session_caps_cb (struct inode * inode , int mds , void * arg )
17011703{
17021704 struct ceph_inode_info * ci = ceph_inode (inode );
17031705 bool invalidate = false;
1704- int iputs ;
1706+ struct ceph_cap * cap ;
1707+ int iputs = 0 ;
17051708
1706- dout ("removing cap %p, ci is %p, inode is %p\n" ,
1707- cap , ci , & ci -> netfs .inode );
17081709 spin_lock (& ci -> i_ceph_lock );
1709- iputs = ceph_purge_inode_cap (inode , cap , & invalidate );
1710+ cap = __get_cap_for_mds (ci , mds );
1711+ if (cap ) {
1712+ dout (" removing cap %p, ci is %p, inode is %p\n" ,
1713+ cap , ci , & ci -> netfs .inode );
1714+
1715+ iputs = ceph_purge_inode_cap (inode , cap , & invalidate );
1716+ }
17101717 spin_unlock (& ci -> i_ceph_lock );
17111718
1712- wake_up_all (& ci -> i_cap_wq );
1719+ if (cap )
1720+ wake_up_all (& ci -> i_cap_wq );
17131721 if (invalidate )
17141722 ceph_queue_invalidate (inode );
17151723 while (iputs -- )
@@ -1780,8 +1788,7 @@ enum {
17801788 *
17811789 * caller must hold s_mutex.
17821790 */
1783- static int wake_up_session_cb (struct inode * inode , struct ceph_cap * cap ,
1784- void * arg )
1791+ static int wake_up_session_cb (struct inode * inode , int mds , void * arg )
17851792{
17861793 struct ceph_inode_info * ci = ceph_inode (inode );
17871794 unsigned long ev = (unsigned long )arg ;
@@ -1792,12 +1799,14 @@ static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
17921799 ci -> i_requested_max_size = 0 ;
17931800 spin_unlock (& ci -> i_ceph_lock );
17941801 } else if (ev == RENEWCAPS ) {
1795- if (cap -> cap_gen < atomic_read (& cap -> session -> s_cap_gen )) {
1796- /* mds did not re-issue stale cap */
1797- spin_lock (& ci -> i_ceph_lock );
1802+ struct ceph_cap * cap ;
1803+
1804+ spin_lock (& ci -> i_ceph_lock );
1805+ cap = __get_cap_for_mds (ci , mds );
1806+ /* mds did not re-issue stale cap */
1807+ if (cap && cap -> cap_gen < atomic_read (& cap -> session -> s_cap_gen ))
17981808 cap -> issued = cap -> implemented = CEPH_CAP_PIN ;
1799- spin_unlock (& ci -> i_ceph_lock );
1800- }
1809+ spin_unlock (& ci -> i_ceph_lock );
18011810 } else if (ev == FORCE_RO ) {
18021811 }
18031812 wake_up_all (& ci -> i_cap_wq );
@@ -1959,16 +1968,22 @@ static bool drop_negative_children(struct dentry *dentry)
19591968 * Yes, this is a bit sloppy. Our only real goal here is to respond to
19601969 * memory pressure from the MDS, though, so it needn't be perfect.
19611970 */
1962- static int trim_caps_cb (struct inode * inode , struct ceph_cap * cap , void * arg )
1971+ static int trim_caps_cb (struct inode * inode , int mds , void * arg )
19631972{
19641973 int * remaining = arg ;
19651974 struct ceph_inode_info * ci = ceph_inode (inode );
19661975 int used , wanted , oissued , mine ;
1976+ struct ceph_cap * cap ;
19671977
19681978 if (* remaining <= 0 )
19691979 return -1 ;
19701980
19711981 spin_lock (& ci -> i_ceph_lock );
1982+ cap = __get_cap_for_mds (ci , mds );
1983+ if (!cap ) {
1984+ spin_unlock (& ci -> i_ceph_lock );
1985+ return 0 ;
1986+ }
19721987 mine = cap -> issued | cap -> implemented ;
19731988 used = __ceph_caps_used (ci );
19741989 wanted = __ceph_caps_file_wanted (ci );
@@ -2555,6 +2570,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session,
25552570 u64 ino1 = 0 , ino2 = 0 ;
25562571 int pathlen1 = 0 , pathlen2 = 0 ;
25572572 bool freepath1 = false, freepath2 = false;
2573+ struct dentry * old_dentry = NULL ;
25582574 int len ;
25592575 u16 releases ;
25602576 void * p , * end ;
@@ -2572,7 +2588,10 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session,
25722588 }
25732589
25742590 /* If r_old_dentry is set, then assume that its parent is locked */
2575- ret = set_request_path_attr (NULL , req -> r_old_dentry ,
2591+ if (req -> r_old_dentry &&
2592+ !(req -> r_old_dentry -> d_flags & DCACHE_DISCONNECTED ))
2593+ old_dentry = req -> r_old_dentry ;
2594+ ret = set_request_path_attr (NULL , old_dentry ,
25762595 req -> r_old_dentry_dir ,
25772596 req -> r_path2 , req -> r_ino2 .ino ,
25782597 & path2 , & pathlen2 , & ino2 , & freepath2 , true);
@@ -3911,26 +3930,22 @@ static struct dentry* d_find_primary(struct inode *inode)
39113930/*
39123931 * Encode information about a cap for a reconnect with the MDS.
39133932 */
3914- static int reconnect_caps_cb (struct inode * inode , struct ceph_cap * cap ,
3915- void * arg )
3933+ static int reconnect_caps_cb (struct inode * inode , int mds , void * arg )
39163934{
39173935 union {
39183936 struct ceph_mds_cap_reconnect v2 ;
39193937 struct ceph_mds_cap_reconnect_v1 v1 ;
39203938 } rec ;
3921- struct ceph_inode_info * ci = cap -> ci ;
3939+ struct ceph_inode_info * ci = ceph_inode ( inode ) ;
39223940 struct ceph_reconnect_state * recon_state = arg ;
39233941 struct ceph_pagelist * pagelist = recon_state -> pagelist ;
39243942 struct dentry * dentry ;
3943+ struct ceph_cap * cap ;
39253944 char * path ;
3926- int pathlen = 0 , err ;
3945+ int pathlen = 0 , err = 0 ;
39273946 u64 pathbase ;
39283947 u64 snap_follows ;
39293948
3930- dout (" adding %p ino %llx.%llx cap %p %lld %s\n" ,
3931- inode , ceph_vinop (inode ), cap , cap -> cap_id ,
3932- ceph_cap_string (cap -> issued ));
3933-
39343949 dentry = d_find_primary (inode );
39353950 if (dentry ) {
39363951 /* set pathbase to parent dir when msg_version >= 2 */
@@ -3947,6 +3962,15 @@ static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
39473962 }
39483963
39493964 spin_lock (& ci -> i_ceph_lock );
3965+ cap = __get_cap_for_mds (ci , mds );
3966+ if (!cap ) {
3967+ spin_unlock (& ci -> i_ceph_lock );
3968+ goto out_err ;
3969+ }
3970+ dout (" adding %p ino %llx.%llx cap %p %lld %s\n" ,
3971+ inode , ceph_vinop (inode ), cap , cap -> cap_id ,
3972+ ceph_cap_string (cap -> issued ));
3973+
39503974 cap -> seq = 0 ; /* reset cap seq */
39513975 cap -> issue_seq = 0 ; /* and issue_seq */
39523976 cap -> mseq = 0 ; /* and migrate_seq */
0 commit comments