diff options
author | 2014-10-03 18:38:28 +0000 | |
---|---|---|
committer | 2014-10-03 17:34:36 -0500 | |
commit | ee00f63d0ffee405de95562f4b88cb92a7b3a033 (patch) | |
tree | 45f1c8361174aeab2798d8bd60b10b7f6e12f294 | |
parent | 85f1c9edd95bb0f02b4705f4a6397409ad6eb82d (diff) | |
download | pseudo-ee00f63d0ffee405de95562f4b88cb92a7b3a033.tar.gz pseudo-ee00f63d0ffee405de95562f4b88cb92a7b3a033.tar.bz2 pseudo-ee00f63d0ffee405de95562f4b88cb92a7b3a033.zip |
Possibly fix strange corruptions
Trying to track down problems which sometimes result in files showing
up as nameless files, producing clashes later. Looks like there were two
issues; one is we were creating links for files that we'd already
found by inode. The other is that rename was sending bogus LINK messages
in some cases. Also simplified the find_file_dev path to extract the
path as part of the initial operation, since there wasn't any case where
that wasn't being done immediately afterwards.
-rw-r--r-- | ChangeLog.txt | 7 | ||||
-rw-r--r-- | ports/unix/guts/rename.c | 6 | ||||
-rw-r--r-- | pseudo.c | 21 | ||||
-rw-r--r-- | pseudo_db.c | 10 | ||||
-rw-r--r-- | pseudo_db.h | 2 |
5 files changed, 36 insertions, 10 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index 48a3261..edb85b1 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,13 @@ 2014-10-03: * (seebs) in fact, suppress a lot of sanity checks entirely for did_unlink. + * (seebs) merge get_file_path functionality into find_file_dev, + since you never call find_file_dev unless you want to do that. + * (seebs) If a file is in the database by inode but not path, + don't try to create a new link for it. + * (seebs) when renaming, the link of the "old" file name should be + contingent on whether *it* was in the database, not whether + the *new* name was in the database. Whoops. 2014-10-02: * (seebs) use sqlite3_bind_int64 for inodes. diff --git a/ports/unix/guts/rename.c b/ports/unix/guts/rename.c index ad28293..b8ee8b0 100644 --- a/ports/unix/guts/rename.c +++ b/ports/unix/guts/rename.c @@ -11,6 +11,7 @@ int oldrc, newrc; int save_errno; int old_db_entry = 0; + int may_unlinked = 0; pseudo_debug(PDBGF_OP, "rename: %s->%s\n", oldpath ? oldpath : "<nil>", @@ -32,10 +33,13 @@ /* as with unlink, we have to mark that the file may get deleted */ msg = pseudo_client_op(OP_MAY_UNLINK, 0, -1, -1, newpath, newrc ? NULL : &newbuf); if (msg && msg->result == RESULT_SUCCEED) + may_unlinked = 1; + msg = pseudo_client_op(OP_STAT, 0, -1, -1, oldpath, oldrc ? NULL : &oldbuf); + if (msg && msg->result == RESULT_SUCCEED) old_db_entry = 1; rc = real_rename(oldpath, newpath); save_errno = errno; - if (old_db_entry) { + if (may_unlinked) { if (rc == -1) { /* since we failed, that wasn't really unlinked -- put * it back. @@ -571,6 +571,9 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon found_ino = 1; /* note: we have to avoid freeing this later */ path_by_ino = msg->path; + if (msg->op == OP_LINK) { + pseudo_debug(PDBGF_FILE, "[matches existing link]"); + } } } @@ -589,9 +592,8 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon } /* search on original inode -- in case of mismatch */ if (msg->dev && msg->ino) { - if (!pdb_find_file_dev(&by_ino, &row)) { + if (!pdb_find_file_dev(&by_ino, &row, &path_by_ino)) { found_ino = 1; - path_by_ino = pdb_get_file_path(&by_ino); } } } @@ -820,8 +822,11 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon /* just in case find_file_path screwed up the msg */ msg->mode = msg_header.mode; } - /* if the path is not known, link it */ - if (!found_path) { + /* if we've never seen the file at all before, link it. + * If we have it in the db by inode, but not by name, + * it got fixed during the sanity checks. + */ + if (!found_path && !found_ino) { pseudo_debug(PDBGF_FILE, "(new) "); pdb_link_file(msg, NULL); } @@ -847,8 +852,12 @@ pseudo_op(pseudo_msg_t *msg, const char *program, const char *tag, char **respon msg->uid = msg_header.uid; msg->gid = msg_header.gid; } - /* if the path is not known, link it */ - if (!found_path) { + /* if we've never seen the file at all before, link it. + * If we have it in the db by inode, but not by name, + * it got fixed during the sanity checks. + */ + if (!found_path && !found_ino) { + pseudo_debug(PDBGF_FILE, "(new) "); pdb_link_file(msg, NULL); } break; diff --git a/pseudo_db.c b/pseudo_db.c index bbc71f0..f60f0ab 100644 --- a/pseudo_db.c +++ b/pseudo_db.c @@ -1401,7 +1401,7 @@ pdb_link_file(pseudo_msg_t *msg, long long *row) { sqlite3_bind_int(insert, 5, msg->gid); sqlite3_bind_int(insert, 6, msg->mode); sqlite3_bind_int(insert, 7, msg->rdev); - pseudo_debug(PDBGF_DB, "linking %s: dev %llu, ino %llu, mode %o, owner %d\n", + pseudo_debug(PDBGF_DB | PDBGF_FILE, "linking %s: dev %llu, ino %llu, mode %o, owner %d\n", (msg->pathlen ? msg->path : "<nil> (as NAMELESS FILE)"), (unsigned long long) msg->dev, (unsigned long long) msg->ino, (int) msg->mode, msg->uid); @@ -2113,7 +2113,7 @@ pdb_get_file_path(pseudo_msg_t *msg) { /* find file using dev/inode as key */ int -pdb_find_file_dev(pseudo_msg_t *msg, long long *row) { +pdb_find_file_dev(pseudo_msg_t *msg, long long *row, char **path) { static sqlite3_stmt *select; int rc; char *sql = "SELECT * FROM files WHERE dev = ? AND ino = ?;"; @@ -2145,6 +2145,12 @@ pdb_find_file_dev(pseudo_msg_t *msg, long long *row) { msg->mode = (unsigned long) sqlite3_column_int64(select, 6); msg->rdev = (unsigned long) sqlite3_column_int64(select, 7); msg->deleting = (int) sqlite3_column_int64(select, 8); + /* stash path */ + if (path) { + *path = strdup((char *) sqlite3_column_text(select, 1)); + pseudo_debug(PDBGF_FILE, "find_file_dev: path %s\n", + *path ? *path : "<nil>"); + } rc = 0; break; case SQLITE_DONE: diff --git a/pseudo_db.h b/pseudo_db.h index a8d9676..07c547b 100644 --- a/pseudo_db.h +++ b/pseudo_db.h @@ -53,7 +53,7 @@ extern int pdb_rename_file(const char *oldpath, pseudo_msg_t *msg); extern int pdb_renumber_all(dev_t from, dev_t to); extern int pdb_find_file_exact(pseudo_msg_t *msg, long long *row); extern int pdb_find_file_path(pseudo_msg_t *msg, long long *row); -extern int pdb_find_file_dev(pseudo_msg_t *msg, long long *row); +extern int pdb_find_file_dev(pseudo_msg_t *msg, long long *row, char **path); extern int pdb_find_file_ino(pseudo_msg_t *msg, long long *row); extern char *pdb_get_file_path(pseudo_msg_t *msg); extern int pdb_get_xattr(long long file_id, char **value, size_t *len); |