aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2014-10-03 18:38:28 +0000
committerPeter Seebach <peter.seebach@windriver.com>2014-10-03 17:34:36 -0500
commitee00f63d0ffee405de95562f4b88cb92a7b3a033 (patch)
tree45f1c8361174aeab2798d8bd60b10b7f6e12f294
parent85f1c9edd95bb0f02b4705f4a6397409ad6eb82d (diff)
downloadpseudo-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.txt7
-rw-r--r--ports/unix/guts/rename.c6
-rw-r--r--pseudo.c21
-rw-r--r--pseudo_db.c10
-rw-r--r--pseudo_db.h2
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.
diff --git a/pseudo.c b/pseudo.c
index f719eee..2b33b05 100644
--- a/pseudo.c
+++ b/pseudo.c
@@ -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);