Always use 64-bit ino_t and dev_t internally, so that we can detect
authorMartin Pool <mbp@samba.org>
Fri, 11 Jan 2002 08:25:32 +0000 (08:25 +0000)
committerMartin Pool <mbp@samba.org>
Fri, 11 Jan 2002 08:25:32 +0000 (08:25 +0000)
hardlinks if coming from a larger platform.  Add heaps of comments
explaining why this is so.

batch.c
flist.c
options.c
receiver.c
rsync.h

diff --git a/batch.c b/batch.c
index 0a8b1cf61f13c898e7e0654406f3868fe031249b..4074e05b8c69e5099b5392a1dd40b9f41f9149d9 100644 (file)
--- 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 fcc6a53a4a1cc081e8e0eab40b4d96b0006ff336..2bc20697ceaee1efeca42972beb16e18af73debc 100644 (file)
--- 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
index 770393aa32b7808501b33804dea7ff624a9f7c60..b79dffecaf4f1a742ba01872b63839cb29c04762 100644 (file)
--- 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");
index 2f679b17d0b3a8122ee54d0f1a89feffb2f57ffa..a574ea63a3b591836f31e44a9c823d85c1b95fb9 100644 (file)
@@ -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 7d1ab3830133fb62de595a1a784987e9b629f5d6..d030d4b91cec2ddb063da3ff4d837f7e8875956c 100644 (file)
--- 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;