handle = NULL;
GOTO(out_free_msg, rc);
}
- rc = vfs_unlink(pending_dir, dchild);
+
+ if (S_ISDIR(inode->i_mode)) {
+ rc = vfs_rmdir(pending_dir, dchild);
+ } else {
+ rc = vfs_unlink(pending_dir, dchild);
+ }
if (rc)
CERROR("error %d unlinking orphan %*s from PENDING directory\n",
rc, dchild->d_name.len, dchild->d_name.name);
+#define _GNU_SOURCE /* pull in O_DIRECTORY in bits/fcntl.h */
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
"Usage: %s filename command-sequence\n"
" command-sequence items:\n"
" d mkdir\n"
+" D open(O_DIRECTORY)\n"
" o open(O_RDONLY)\n"
" O open(O_CREAT|O_RDWR)\n"
" u unlink\n"
exit(1);
}
break;
+ case 'D':
+ if (open(fname, O_DIRECTORY) == -1) {
+ perror("open(O_DIRECTORY)");
+ exit(1);
+ }
+ break;
case 'm':
if (mknod(fname, S_IFREG | 0644, 0) == -1) {
perror("mknod(S_IFREG|0644, 0)");
fail_abort mds
kill -USR1 $pid
[ -e $DIR/$tfile ] && return 1
- sleep 3
- # wait for commitment of removal
+ sync
return 0
}
run_test 34 "abort recovery before client does replay (test mds_cleanup_orphans)"
}
run_test 36 "don't resend cancel"
+# b=2368
+# directory orphans can't be unlinked from PENDING directory
+test_37() {
+ rmdir $DIR/$tfile 2>/dev/null
+ multiop $DIR/$tfile dD_c &
+ pid=$!
+ # give multiop a chance to open
+ sleep 1
+ rmdir $DIR/$tfile
+
+ replay_barrier mds
+ # clear the dmesg buffer so we only see errors from this recovery
+ dmesg -c >/dev/null
+ fail_abort mds
+ kill -USR1 $pid
+ dmesg | grep "mds_unlink_orphan.*error .* unlinking orphan" && return 1
+ sync
+ return 0
+}
+run_test 37 "abort recovery before client does replay (test mds_cleanup_orphans for directories)"
+
equals_msg test complete, cleaning up
$CLEANUP