@@ -1299,32 +1299,27 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
12991299 * However, if we didn't have a callback promise outstanding, or it was
13001300 * outstanding on a different server, then it won't break it either...
13011301 */
1302- int afs_dir_remove_link (struct dentry * dentry , struct key * key ,
1303- unsigned long d_version_before ,
1304- unsigned long d_version_after )
1302+ static int afs_dir_remove_link (struct afs_vnode * dvnode , struct dentry * dentry ,
1303+ struct key * key )
13051304{
1306- bool dir_valid ;
13071305 int ret = 0 ;
13081306
1309- /* There were no intervening changes on the server if the version
1310- * number we got back was incremented by exactly 1.
1311- */
1312- dir_valid = (d_version_after == d_version_before + 1 );
1313-
13141307 if (d_really_is_positive (dentry )) {
13151308 struct afs_vnode * vnode = AFS_FS_I (d_inode (dentry ));
13161309
13171310 if (test_bit (AFS_VNODE_DELETED , & vnode -> flags )) {
13181311 /* Already done */
1319- } else if (dir_valid ) {
1312+ } else if (test_bit (AFS_VNODE_DIR_VALID , & dvnode -> flags )) {
1313+ write_seqlock (& vnode -> cb_lock );
13201314 drop_nlink (& vnode -> vfs_inode );
13211315 if (vnode -> vfs_inode .i_nlink == 0 ) {
13221316 set_bit (AFS_VNODE_DELETED , & vnode -> flags );
1323- clear_bit ( AFS_VNODE_CB_PROMISED , & vnode -> flags );
1317+ __afs_break_callback ( vnode );
13241318 }
1319+ write_sequnlock (& vnode -> cb_lock );
13251320 ret = 0 ;
13261321 } else {
1327- clear_bit ( AFS_VNODE_CB_PROMISED , & vnode -> flags );
1322+ afs_break_callback ( vnode );
13281323
13291324 if (test_bit (AFS_VNODE_DELETED , & vnode -> flags ))
13301325 kdebug ("AFS_VNODE_DELETED" );
@@ -1348,7 +1343,6 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
13481343 struct afs_status_cb * scb ;
13491344 struct afs_vnode * dvnode = AFS_FS_I (dir ), * vnode = NULL ;
13501345 struct key * key ;
1351- unsigned long d_version = (unsigned long )dentry -> d_fsdata ;
13521346 bool need_rehash = false;
13531347 int ret ;
13541348
@@ -1395,20 +1389,16 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
13951389 ret = - ERESTARTSYS ;
13961390 if (afs_begin_vnode_operation (& fc , dvnode , key , true)) {
13971391 afs_dataversion_t data_version = dvnode -> status .data_version + 1 ;
1392+ afs_dataversion_t data_version_2 = vnode -> status .data_version ;
13981393
13991394 while (afs_select_fileserver (& fc )) {
14001395 fc .cb_break = afs_calc_vnode_cb_break (dvnode );
1396+ fc .cb_break_2 = afs_calc_vnode_cb_break (vnode );
14011397
14021398 if (test_bit (AFS_SERVER_FL_IS_YFS , & fc .cbi -> server -> flags ) &&
14031399 !test_bit (AFS_SERVER_FL_NO_RM2 , & fc .cbi -> server -> flags )) {
14041400 yfs_fs_remove_file2 (& fc , vnode , dentry -> d_name .name ,
14051401 & scb [0 ], & scb [1 ]);
1406- if (fc .ac .error == 0 &&
1407- scb [1 ].status .abort_code == VNOVNODE ) {
1408- set_bit (AFS_VNODE_DELETED , & vnode -> flags );
1409- afs_break_callback (vnode );
1410- }
1411-
14121402 if (fc .ac .error != - ECONNABORTED ||
14131403 fc .ac .abort_code != RXGEN_OPCODE )
14141404 continue ;
@@ -1420,11 +1410,11 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
14201410
14211411 afs_vnode_commit_status (& fc , dvnode , fc .cb_break ,
14221412 & data_version , & scb [0 ]);
1413+ afs_vnode_commit_status (& fc , vnode , fc .cb_break_2 ,
1414+ & data_version_2 , & scb [1 ]);
14231415 ret = afs_end_vnode_operation (& fc );
1424- if (ret == 0 )
1425- ret = afs_dir_remove_link (
1426- dentry , key , d_version ,
1427- (unsigned long )dvnode -> status .data_version );
1416+ if (ret == 0 && !(scb [1 ].have_status || scb [1 ].have_error ))
1417+ ret = afs_dir_remove_link (dvnode , dentry , key );
14281418 if (ret == 0 &&
14291419 test_bit (AFS_VNODE_DIR_VALID , & dvnode -> flags ))
14301420 afs_edit_dir_remove (dvnode , & dentry -> d_name ,
0 commit comments