+/*
+ * This unlink wrapper allows the fd_tracker to check if any other
+ * fs_handle references the index before unlinking it. If the relay holds
+ * this file open, it is essential to unlink it through an fs_handle as this
+ * will delay the actual unlink() until all handles have released this file.
+ *
+ * The file is renamed and unlinked once the last handle to its inode has been
+ * released.
+ */
+static
+int unlink_through_handle(const char *path)
+{
+ int ret = 0, close_ret;
+ struct fs_handle *handle;
+ /*
+ * Since this operation is only performed to perform the unlink
+ * through the fs_handle and fd-tracker system, the flag is opened
+ * without the O_CREAT. There is no need to perform the unlink if
+ * the file doesn't already exist.
+ */
+ int flags = O_RDONLY;
+
+ DBG("Unlinking index at %s through a filesystem handle", path);
+ handle = fd_tracker_open_fs_handle(the_fd_tracker, path, flags, NULL);
+ if (!handle) {
+ if (errno == ENOENT) {
+ DBG("File %s does not exist, ignoring unlink", path);
+ }
+ goto end;
+ }
+
+ ret = fs_handle_unlink(handle);
+ close_ret = fs_handle_close(handle);
+ if (close_ret) {
+ ERR("Failed to close handle after performing an unlink operation on a filesystem handle");
+ }
+end:
+ if (ret) {
+ DBG("Unlinking index at %s failed with error code %i", path, ret);
+ }
+ return ret;
+}
+