diff options
Diffstat (limited to 'pseudo_db.c')
-rw-r--r-- | pseudo_db.c | 94 |
1 files changed, 88 insertions, 6 deletions
diff --git a/pseudo_db.c b/pseudo_db.c index 62f2322..245f4e6 100644 --- a/pseudo_db.c +++ b/pseudo_db.c @@ -1392,12 +1392,12 @@ pdb_update_file_path(pseudo_msg_t *msg) { return rc != SQLITE_DONE; } -/* mark a file for pending deletion */ +/* mark a file for pending deletion by a given client */ int -pdb_may_unlink_file(pseudo_msg_t *msg) { +pdb_may_unlink_file(pseudo_msg_t *msg, int deleting) { static sqlite3_stmt *mark_file; int rc, exact; - char *sql_mark_file = "UPDATE files SET deleting = 1 WHERE path = ?;"; + char *sql_mark_file = "UPDATE files SET deleting = ? WHERE path = ?;"; if (!file_db && get_db(&file_db)) { pseudo_diag("database error.\n"); @@ -1414,7 +1414,8 @@ pdb_may_unlink_file(pseudo_msg_t *msg) { return 1; } if (msg->pathlen) { - sqlite3_bind_text(mark_file, 1, msg->path, -1, SQLITE_STATIC); + sqlite3_bind_int(mark_file, 1, deleting); + sqlite3_bind_text(mark_file, 2, msg->path, -1, SQLITE_STATIC); } else { pseudo_debug(1, "cannot mark a file for pending deletion without a path."); return 1; @@ -1473,11 +1474,48 @@ pdb_cancel_unlink_file(pseudo_msg_t *msg) { return rc != SQLITE_DONE; } +/* delete all files attached to a given cookie; + * used for database fixup passes. + */ +int +pdb_did_unlink_files(int deleting) { + static sqlite3_stmt *delete_exact; + int rc, exact; + char *sql_delete_exact = "DELETE FROM files WHERE deleting = ?;"; + + if (!file_db && get_db(&file_db)) { + pseudo_diag("database error.\n"); + return 0; + } + if (!delete_exact) { + rc = sqlite3_prepare_v2(file_db, sql_delete_exact, strlen(sql_delete_exact), &delete_exact, NULL); + if (rc) { + dberr(file_db, "couldn't prepare DELETE statement"); + return 1; + } + } + if (deleting == 0) { + pseudo_diag("did_unlink_files: deleting must be non-zero.\n"); + return 0; + } + sqlite3_bind_int(delete_exact, 1, deleting); + rc = sqlite3_step(delete_exact); + if (rc != SQLITE_DONE) { + dberr(file_db, "cleanup of files marked for deletion may have failed"); + } + exact = sqlite3_changes(file_db); + pseudo_debug(3, "(exact %d)\n", exact); + sqlite3_reset(delete_exact); + sqlite3_clear_bindings(delete_exact); + return rc != SQLITE_DONE; +} + +/* confirm deletion of a specific file by a given client */ int -pdb_did_unlink_file(char *path) { +pdb_did_unlink_file(char *path, int deleting) { static sqlite3_stmt *delete_exact; int rc, exact; - char *sql_delete_exact = "DELETE FROM files WHERE path = ? AND deleting = 1;"; + char *sql_delete_exact = "DELETE FROM files WHERE path = ? AND deleting = ?;"; if (!file_db && get_db(&file_db)) { pseudo_diag("database error.\n"); @@ -1495,6 +1533,7 @@ pdb_did_unlink_file(char *path) { return 1; } sqlite3_bind_text(delete_exact, 1, path, -1, SQLITE_STATIC); + sqlite3_bind_int(delete_exact, 2, deleting); rc = sqlite3_step(delete_exact); if (rc != SQLITE_DONE) { dberr(file_db, "cleanup of file marked for deletion may have failed"); @@ -1659,6 +1698,49 @@ pdb_rename_file(const char *oldpath, pseudo_msg_t *msg) { return rc != SQLITE_DONE; } +/* renumber device only. + * this is used if the filesystem moves to a new device, without changing + * inode allocations. + */ +int +pdb_renumber_all(dev_t from, dev_t to) { + static sqlite3_stmt *update; + int rc; + char *sql = "UPDATE files " + " SET dev = ? " + " WHERE dev = ?;"; + + if (!file_db && get_db(&file_db)) { + pseudo_diag("database error.\n"); + return 0; + } + if (!update) { + rc = sqlite3_prepare_v2(file_db, sql, strlen(sql), &update, NULL); + if (rc) { + dberr(file_db, "couldn't prepare UPDATE statement"); + return 1; + } + } + rc = sqlite3_bind_int(update, 1, to); + if (rc) { + dberr(file_db, "error binding device numbers to update"); + } + rc = sqlite3_bind_int(update, 2, from); + if (rc) { + dberr(file_db, "error binding device numbers to update"); + } + + rc = sqlite3_step(update); + if (rc != SQLITE_DONE) { + dberr(file_db, "update may have failed: rc %d", rc); + } + sqlite3_reset(update); + sqlite3_clear_bindings(update); + pseudo_debug(2, "updating device dev %llu to %llu\n", + (unsigned long long) from, (unsigned long long) to); + return rc != SQLITE_DONE; +} + /* change dev/inode for a given path -- used only by RENAME for now. */ int |