aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);