summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pool <mbp@samba.org>2002-01-11 08:25:32 +0000
committerMartin Pool <mbp@samba.org>2002-01-11 08:25:32 +0000
commit6abd193fe3f8e7b986c388e7642adc08516e8279 (patch)
tree2cdc5595b1d8d8bc62cf7077e10b06a5e0b60237
parent362099a51230fd80c6d54ef6f0e72927529c8dfb (diff)
downloadrsync-6abd193fe3f8e7b986c388e7642adc08516e8279.tar.gz
rsync-6abd193fe3f8e7b986c388e7642adc08516e8279.tar.bz2
rsync-6abd193fe3f8e7b986c388e7642adc08516e8279.zip
Always use 64-bit ino_t and dev_t internally, so that we can detect
hardlinks if coming from a larger platform. Add heaps of comments explaining why this is so.
-rw-r--r--batch.c8
-rw-r--r--flist.c4
-rw-r--r--options.c4
-rw-r--r--receiver.c4
-rw-r--r--rsync.h40
5 files changed, 41 insertions, 19 deletions
diff --git a/batch.c b/batch.c
index 0a8b1cf6..4074e05b 100644
--- a/batch.c
+++ b/batch.c
@@ -88,8 +88,8 @@ void write_batch_flist_info(int flist_count, struct file_struct **fptr)
sizeof(time_t) +
sizeof(OFF_T) +
sizeof(mode_t) +
- sizeof(INO_T) +
- (2 * sizeof(dev_t)) + sizeof(uid_t) + sizeof(gid_t);
+ sizeof(INO64_T) +
+ (2 * sizeof(DEV64_T)) + sizeof(uid_t) + sizeof(gid_t);
fdb_open = 1;
fdb_close = 0;
@@ -289,8 +289,8 @@ void read_batch_flist_info(struct file_struct **fptr)
read_batch_flist_file((char *) &file->modtime, sizeof(time_t));
read_batch_flist_file((char *) &file->length, sizeof(OFF_T));
read_batch_flist_file((char *) &file->mode, sizeof(mode_t));
- read_batch_flist_file((char *) &file->inode, sizeof(INO_T));
- read_batch_flist_file((char *) &file->dev, sizeof(dev_t));
+ read_batch_flist_file((char *) &file->inode, sizeof(INO64_T));
+ read_batch_flist_file((char *) &file->dev, sizeof(DEV64_T));
read_batch_flist_file((char *) &file->rdev, sizeof(dev_t));
read_batch_flist_file((char *) &file->uid, sizeof(uid_t));
read_batch_flist_file((char *) &file->gid, sizeof(gid_t));
diff --git a/flist.c b/flist.c
index fcc6a53a..2bc20697 100644
--- a/flist.c
+++ b/flist.c
@@ -310,8 +310,8 @@ static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
write_int(f,(int)file->inode);
} else {
/* 64-bit dev_t and ino_t */
- write_longint(f, (int64) file->dev);
- write_longint(f, (int64) file->inode);
+ write_longint(f, file->dev);
+ write_longint(f, file->inode);
}
}
#endif
diff --git a/options.c b/options.c
index 770393aa..b79dffec 100644
--- a/options.c
+++ b/options.c
@@ -153,9 +153,9 @@ static void print_rsync_version(enum logcode f)
/* Note that this field may not have type ino_t. It depends
* on the complicated interaction between largefile feature
* macros. */
- rprintf(f, " %d-bit inums, %d-bit INO_T\n",
+ rprintf(f, " %d-bit system inums, %d-bit internal inums\n",
(int) (sizeof(dumstat->st_ino) * 8),
- (int) (sizeof(INO_T) * 8));
+ (int) (sizeof(INO64_T) * 8));
#ifdef NO_INT64
rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
diff --git a/receiver.c b/receiver.c
index 2f679b17..a574ea63 100644
--- a/receiver.c
+++ b/receiver.c
@@ -38,8 +38,8 @@ extern int make_backups;
extern char *backup_suffix;
static struct delete_list {
- dev_t dev;
- INO_T inode;
+ DEV64_T dev;
+ INO64_T inode;
} *delete_list;
static int dlist_len, dlist_alloc_len;
diff --git a/rsync.h b/rsync.h
index 7d1ab383..d030d4b9 100644
--- a/rsync.h
+++ b/rsync.h
@@ -272,12 +272,30 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#define NO_INT64
#endif
-/* We want to manipulate 64-bit inums. On some systems
- * STRUCT_STAT.st_ino can be bigger than an ino_t depending on the
- * combination of largefile feature macros. Rather than try to guess,
- * we just internally store them in the largest know type. Hopefully
- * it's enough. */
-#define INO_T int64
+/* Starting from protocol version 26, we always use 64-bit
+ * ino_t and dev_t internally, even if this platform does not
+ * allow files to have 64-bit inums. That's because the
+ * receiver needs to find duplicate (dev,ino) tuples to detect
+ * hardlinks, and it might have files coming from a platform
+ * that has 64-bit inums.
+ *
+ * The only exception is if we're on a platform with no 64-bit type at
+ * all.
+ *
+ * Because we use read_longint() to get these off the wire, if you
+ * transfer devices or hardlinks with dev or inum > 2**32 to a machine
+ * with no 64-bit types then you will get an overflow error. Probably
+ * not many people have that combination of machines, and you can
+ * avoid it by not preserving hardlinks or not transferring device
+ * nodes. It's not clear that any other behaviour is better.
+ *
+ * Note that if you transfer devices from a 64-bit-devt machine (say,
+ * Solaris) to a 32-bit-devt machine (say, Linux-2.2/x86) then the
+ * device numbers will be truncated. But it's a kind of silly thing
+ * to do anyhow.
+ */
+#define INO64_T int64
+#define DEV64_T int64
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@@ -308,9 +326,13 @@ struct file_struct {
time_t modtime;
OFF_T length;
mode_t mode;
- INO_T inode;
- dev_t dev;
- dev_t rdev;
+
+ INO64_T inode;
+ /** Device this file lives upon */
+ DEV64_T dev;
+
+ /** If this is a device node, the device number. */
+ DEV64_T rdev;
uid_t uid;
gid_t gid;
char *basename;