@@ -1188,11 +1188,11 @@ void ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
1188
1188
1189
1189
lockdep_assert_held (& ci -> i_ceph_lock );
1190
1190
1191
- fsc = ceph_sb_to_client ( ci -> vfs_inode . i_sb );
1191
+ fsc = ceph_inode_to_client ( & ci -> vfs_inode );
1192
1192
WARN_ON_ONCE (ci -> i_auth_cap == cap &&
1193
1193
!list_empty (& ci -> i_dirty_item ) &&
1194
1194
!fsc -> blocklisted &&
1195
- READ_ONCE ( fsc -> mount_state ) != CEPH_MOUNT_SHUTDOWN );
1195
+ ! ceph_inode_is_shutdown ( & ci -> vfs_inode ) );
1196
1196
1197
1197
__ceph_remove_cap (cap , queue_release );
1198
1198
}
@@ -1968,8 +1968,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
1968
1968
}
1969
1969
}
1970
1970
1971
- dout ("check_caps %p file_want %s used %s dirty %s flushing %s"
1972
- " issued %s revoking %s retain %s %s%s\n" , inode ,
1971
+ dout ("check_caps %llx.%llx file_want %s used %s dirty %s flushing %s"
1972
+ " issued %s revoking %s retain %s %s%s\n" , ceph_vinop ( inode ) ,
1973
1973
ceph_cap_string (file_wanted ),
1974
1974
ceph_cap_string (used ), ceph_cap_string (ci -> i_dirty_caps ),
1975
1975
ceph_cap_string (ci -> i_flushing_caps ),
@@ -1990,7 +1990,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
1990
1990
(revoking & (CEPH_CAP_FILE_CACHE |
1991
1991
CEPH_CAP_FILE_LAZYIO )) && /* or revoking cache */
1992
1992
!tried_invalidate ) {
1993
- dout ("check_caps trying to invalidate on %p\n" , inode );
1993
+ dout ("check_caps trying to invalidate on %llx.%llx\n" ,
1994
+ ceph_vinop (inode ));
1994
1995
if (try_nonblocking_invalidate (inode ) < 0 ) {
1995
1996
dout ("check_caps queuing invalidate\n" );
1996
1997
queue_invalidate = true;
@@ -2629,9 +2630,9 @@ void ceph_take_cap_refs(struct ceph_inode_info *ci, int got,
2629
2630
*
2630
2631
* Returns 0 if caps were not able to be acquired (yet), 1 if succeed,
2631
2632
* or a negative error code. There are 3 speical error codes:
2632
- * -EAGAIN: need to sleep but non-blocking is specified
2633
- * -EFBIG: ask caller to call check_max_size() and try again.
2634
- * -ESTALE : ask caller to call ceph_renew_caps() and try again.
2633
+ * -EAGAIN: need to sleep but non-blocking is specified
2634
+ * -EFBIG: ask caller to call check_max_size() and try again.
2635
+ * -EUCLEAN : ask caller to call ceph_renew_caps() and try again.
2635
2636
*/
2636
2637
enum {
2637
2638
/* first 8 bits are reserved for CEPH_FILE_MODE_FOO */
@@ -2679,7 +2680,7 @@ static int try_get_cap_refs(struct inode *inode, int need, int want,
2679
2680
dout ("get_cap_refs %p endoff %llu > maxsize %llu\n" ,
2680
2681
inode , endoff , ci -> i_max_size );
2681
2682
if (endoff > ci -> i_requested_max_size )
2682
- ret = ci -> i_auth_cap ? - EFBIG : - ESTALE ;
2683
+ ret = ci -> i_auth_cap ? - EFBIG : - EUCLEAN ;
2683
2684
goto out_unlock ;
2684
2685
}
2685
2686
/*
@@ -2749,17 +2750,17 @@ static int try_get_cap_refs(struct inode *inode, int need, int want,
2749
2750
goto out_unlock ;
2750
2751
}
2751
2752
2752
- if (READ_ONCE ( mdsc -> fsc -> mount_state ) >= CEPH_MOUNT_SHUTDOWN ) {
2753
- dout ("get_cap_refs %p forced umount \n" , inode );
2754
- ret = - EIO ;
2753
+ if (ceph_inode_is_shutdown ( inode ) ) {
2754
+ dout ("get_cap_refs %p inode is shutdown \n" , inode );
2755
+ ret = - ESTALE ;
2755
2756
goto out_unlock ;
2756
2757
}
2757
2758
mds_wanted = __ceph_caps_mds_wanted (ci , false);
2758
2759
if (need & ~mds_wanted ) {
2759
2760
dout ("get_cap_refs %p need %s > mds_wanted %s\n" ,
2760
2761
inode , ceph_cap_string (need ),
2761
2762
ceph_cap_string (mds_wanted ));
2762
- ret = - ESTALE ;
2763
+ ret = - EUCLEAN ;
2763
2764
goto out_unlock ;
2764
2765
}
2765
2766
@@ -2843,7 +2844,7 @@ int ceph_try_get_caps(struct inode *inode, int need, int want,
2843
2844
2844
2845
ret = try_get_cap_refs (inode , need , want , 0 , flags , got );
2845
2846
/* three special error codes */
2846
- if (ret == - EAGAIN || ret == - EFBIG || ret == - ESTALE )
2847
+ if (ret == - EAGAIN || ret == - EFBIG || ret == - EUCLEAN )
2847
2848
ret = 0 ;
2848
2849
return ret ;
2849
2850
}
@@ -2926,7 +2927,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got
2926
2927
}
2927
2928
2928
2929
if (ret < 0 ) {
2929
- if (ret == - EFBIG || ret == - ESTALE ) {
2930
+ if (ret == - EFBIG || ret == - EUCLEAN ) {
2930
2931
int ret2 = ceph_wait_on_async_create (inode );
2931
2932
if (ret2 < 0 )
2932
2933
return ret2 ;
@@ -2935,7 +2936,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got
2935
2936
check_max_size (inode , endoff );
2936
2937
continue ;
2937
2938
}
2938
- if (ret == - ESTALE ) {
2939
+ if (ret == - EUCLEAN ) {
2939
2940
/* session was killed, try renew caps */
2940
2941
ret = ceph_renew_caps (inode , flags );
2941
2942
if (ret == 0 )
@@ -4315,7 +4316,7 @@ static void flush_dirty_session_caps(struct ceph_mds_session *s)
4315
4316
i_dirty_item );
4316
4317
inode = & ci -> vfs_inode ;
4317
4318
ihold (inode );
4318
- dout ("flush_dirty_caps %p \n" , inode );
4319
+ dout ("flush_dirty_caps %llx.%llx \n" , ceph_vinop ( inode ) );
4319
4320
spin_unlock (& mdsc -> cap_dirty_lock );
4320
4321
ceph_check_caps (ci , CHECK_CAPS_FLUSH , NULL );
4321
4322
iput (inode );
@@ -4560,3 +4561,119 @@ int ceph_encode_dentry_release(void **p, struct dentry *dentry,
4560
4561
spin_unlock (& dentry -> d_lock );
4561
4562
return ret ;
4562
4563
}
4564
+
4565
+ static int remove_capsnaps (struct ceph_mds_client * mdsc , struct inode * inode )
4566
+ {
4567
+ struct ceph_inode_info * ci = ceph_inode (inode );
4568
+ struct ceph_cap_snap * capsnap ;
4569
+ int capsnap_release = 0 ;
4570
+
4571
+ lockdep_assert_held (& ci -> i_ceph_lock );
4572
+
4573
+ dout ("removing capsnaps, ci is %p, inode is %p\n" , ci , inode );
4574
+
4575
+ while (!list_empty (& ci -> i_cap_snaps )) {
4576
+ capsnap = list_first_entry (& ci -> i_cap_snaps ,
4577
+ struct ceph_cap_snap , ci_item );
4578
+ __ceph_remove_capsnap (inode , capsnap , NULL , NULL );
4579
+ ceph_put_snap_context (capsnap -> context );
4580
+ ceph_put_cap_snap (capsnap );
4581
+ capsnap_release ++ ;
4582
+ }
4583
+ wake_up_all (& ci -> i_cap_wq );
4584
+ wake_up_all (& mdsc -> cap_flushing_wq );
4585
+ return capsnap_release ;
4586
+ }
4587
+
4588
+ int ceph_purge_inode_cap (struct inode * inode , struct ceph_cap * cap , bool * invalidate )
4589
+ {
4590
+ struct ceph_fs_client * fsc = ceph_inode_to_client (inode );
4591
+ struct ceph_mds_client * mdsc = fsc -> mdsc ;
4592
+ struct ceph_inode_info * ci = ceph_inode (inode );
4593
+ bool is_auth ;
4594
+ bool dirty_dropped = false;
4595
+ int iputs = 0 ;
4596
+
4597
+ lockdep_assert_held (& ci -> i_ceph_lock );
4598
+
4599
+ dout ("removing cap %p, ci is %p, inode is %p\n" ,
4600
+ cap , ci , & ci -> vfs_inode );
4601
+
4602
+ is_auth = (cap == ci -> i_auth_cap );
4603
+ __ceph_remove_cap (cap , false);
4604
+ if (is_auth ) {
4605
+ struct ceph_cap_flush * cf ;
4606
+
4607
+ if (ceph_inode_is_shutdown (inode )) {
4608
+ if (inode -> i_data .nrpages > 0 )
4609
+ * invalidate = true;
4610
+ if (ci -> i_wrbuffer_ref > 0 )
4611
+ mapping_set_error (& inode -> i_data , - EIO );
4612
+ }
4613
+
4614
+ spin_lock (& mdsc -> cap_dirty_lock );
4615
+
4616
+ /* trash all of the cap flushes for this inode */
4617
+ while (!list_empty (& ci -> i_cap_flush_list )) {
4618
+ cf = list_first_entry (& ci -> i_cap_flush_list ,
4619
+ struct ceph_cap_flush , i_list );
4620
+ list_del_init (& cf -> g_list );
4621
+ list_del_init (& cf -> i_list );
4622
+ if (!cf -> is_capsnap )
4623
+ ceph_free_cap_flush (cf );
4624
+ }
4625
+
4626
+ if (!list_empty (& ci -> i_dirty_item )) {
4627
+ pr_warn_ratelimited (
4628
+ " dropping dirty %s state for %p %lld\n" ,
4629
+ ceph_cap_string (ci -> i_dirty_caps ),
4630
+ inode , ceph_ino (inode ));
4631
+ ci -> i_dirty_caps = 0 ;
4632
+ list_del_init (& ci -> i_dirty_item );
4633
+ dirty_dropped = true;
4634
+ }
4635
+ if (!list_empty (& ci -> i_flushing_item )) {
4636
+ pr_warn_ratelimited (
4637
+ " dropping dirty+flushing %s state for %p %lld\n" ,
4638
+ ceph_cap_string (ci -> i_flushing_caps ),
4639
+ inode , ceph_ino (inode ));
4640
+ ci -> i_flushing_caps = 0 ;
4641
+ list_del_init (& ci -> i_flushing_item );
4642
+ mdsc -> num_cap_flushing -- ;
4643
+ dirty_dropped = true;
4644
+ }
4645
+ spin_unlock (& mdsc -> cap_dirty_lock );
4646
+
4647
+ if (dirty_dropped ) {
4648
+ mapping_set_error (inode -> i_mapping , - EIO );
4649
+
4650
+ if (ci -> i_wrbuffer_ref_head == 0 &&
4651
+ ci -> i_wr_ref == 0 &&
4652
+ ci -> i_dirty_caps == 0 &&
4653
+ ci -> i_flushing_caps == 0 ) {
4654
+ ceph_put_snap_context (ci -> i_head_snapc );
4655
+ ci -> i_head_snapc = NULL ;
4656
+ }
4657
+ }
4658
+
4659
+ if (atomic_read (& ci -> i_filelock_ref ) > 0 ) {
4660
+ /* make further file lock syscall return -EIO */
4661
+ ci -> i_ceph_flags |= CEPH_I_ERROR_FILELOCK ;
4662
+ pr_warn_ratelimited (" dropping file locks for %p %lld\n" ,
4663
+ inode , ceph_ino (inode ));
4664
+ }
4665
+
4666
+ if (!ci -> i_dirty_caps && ci -> i_prealloc_cap_flush ) {
4667
+ cf = ci -> i_prealloc_cap_flush ;
4668
+ ci -> i_prealloc_cap_flush = NULL ;
4669
+ if (!cf -> is_capsnap )
4670
+ ceph_free_cap_flush (cf );
4671
+ }
4672
+
4673
+ if (!list_empty (& ci -> i_cap_snaps ))
4674
+ iputs = remove_capsnaps (mdsc , inode );
4675
+ }
4676
+ if (dirty_dropped )
4677
+ ++ iputs ;
4678
+ return iputs ;
4679
+ }
0 commit comments