1 This attempts to accomplish some per-file memory-savings by moving the
2 uid+gid items out of the file-list (since their values are common to
3 multiple file-list entries) and replacing them with an index to an
6 This only saves 4 bytes per file (not counting the overhead of the array).
8 This probably needs a hashing algorithm to be added if the uid+gid list
9 gets to be really large.
13 @@ -60,6 +60,7 @@ extern int protocol_version;
14 extern int sanitize_paths;
15 extern const char *io_write_phase;
16 extern struct stats stats;
17 +extern struct id_pair *id_pairs;
18 extern struct file_list *the_file_list;
20 extern char curr_dir[MAXPATHLEN];
21 @@ -363,14 +364,14 @@ static void send_file_entry(struct file_
23 } else if (protocol_version < 28)
25 - if (file->uid == uid)
26 + if (id_pairs[file->id_ndx].uid == uid)
27 flags |= XMIT_SAME_UID;
30 - if (file->gid == gid)
31 + uid = id_pairs[file->id_ndx].uid;
32 + if (id_pairs[file->id_ndx].gid == gid)
33 flags |= XMIT_SAME_GID;
36 + gid = id_pairs[file->id_ndx].gid;
37 if (file->modtime == modtime)
38 flags |= XMIT_SAME_TIME;
40 @@ -623,8 +624,7 @@ static struct file_struct *receive_file_
41 file->modtime = modtime;
42 file->length = file_length;
46 + file->id_ndx = id_pair(uid, gid);
49 file->dirname = lastdir = bp;
50 @@ -875,8 +875,7 @@ struct file_struct *make_file(char *fnam
51 file->modtime = st.st_mtime;
52 file->length = st.st_size;
53 file->mode = st.st_mode;
54 - file->uid = st.st_uid;
55 - file->gid = st.st_gid;
56 + file->id_ndx = id_pair(st.st_uid, st.st_gid);
58 #ifdef SUPPORT_HARD_LINKS
59 if (flist && flist->hlink_pool) {
60 @@ -944,8 +943,7 @@ struct file_struct *make_file(char *fnam
61 file->modtime = st2.st_mtime;
62 file->length = st2.st_size;
63 file->mode = st2.st_mode;
64 - file->uid = st2.st_uid;
65 - file->gid = st2.st_gid;
66 + file->id_ndx = id_pair(st2.st_uid, st2.st_gid);
69 file->mode = save_mode;
70 @@ -1389,7 +1387,7 @@ struct file_list *recv_file_list(int f)
71 clean_flist(flist, relative_paths, 1);
74 - recv_uid_list(f, flist);
77 /* Recv the io_error flag */
78 if (lp_ignore_errors(module_id) || ignore_errors)
79 @@ -1705,13 +1703,15 @@ static void output_flist(struct file_lis
81 for (i = 0; i < flist->count; i++) {
82 file = flist->files[i];
83 - if ((am_root || am_sender) && preserve_uid)
84 - sprintf(uidbuf, " uid=%ld", (long)file->uid);
86 + if ((am_root || am_sender) && preserve_uid) {
87 + sprintf(uidbuf, " uid=%ld",
88 + (long)id_pairs[file->id_ndx].uid);
91 - if (preserve_gid && file->gid != GID_NONE)
92 - sprintf(gidbuf, " gid=%ld", (long)file->gid);
94 + if (preserve_gid && id_pairs[file->id_ndx].gid != GID_NONE) {
95 + sprintf(gidbuf, " gid=%ld",
96 + (long)id_pairs[file->id_ndx].gid);
100 sprintf(depthbuf, "%d", file->dir.depth);
103 @@ -91,6 +91,7 @@ extern dev_t filesystem_dev;
104 extern char *backup_dir;
105 extern char *backup_suffix;
106 extern int backup_suffix_len;
107 +extern struct id_pair *id_pairs;
108 extern struct file_list *the_file_list;
109 extern struct filter_list_struct server_filter_list;
111 @@ -326,10 +327,12 @@ int unchanged_attrs(struct file_struct *
112 && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
115 - if (am_root && preserve_uid && st->st_uid != file->uid)
116 + if (am_root && preserve_uid
117 + && st->st_uid != id_pairs[file->id_ndx].uid)
120 - if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
121 + if (preserve_gid && id_pairs[file->id_ndx].gid != GID_NONE
122 + && st->st_gid != id_pairs[file->id_ndx].gid)
126 @@ -342,6 +345,8 @@ void itemize(struct file_struct *file, i
127 int keep_time = !preserve_times ? 0
128 : S_ISDIR(file->mode) ? !omit_dir_times
129 : !S_ISLNK(file->mode);
130 + uid_t uid = id_pairs[file->id_ndx].uid;
131 + gid_t gid = id_pairs[file->id_ndx].gid;
133 if (S_ISREG(file->mode) && file->length != st->st_size)
134 iflags |= ITEM_REPORT_SIZE;
135 @@ -351,10 +356,10 @@ void itemize(struct file_struct *file, i
136 iflags |= ITEM_REPORT_TIME;
137 if ((file->mode & CHMOD_BITS) != (st->st_mode & CHMOD_BITS))
138 iflags |= ITEM_REPORT_PERMS;
139 - if (preserve_uid && am_root && file->uid != st->st_uid)
140 + if (preserve_uid && am_root && uid != st->st_uid)
141 iflags |= ITEM_REPORT_OWNER;
142 - if (preserve_gid && file->gid != GID_NONE
143 - && st->st_gid != file->gid)
144 + if (preserve_gid && gid != GID_NONE
145 + && st->st_gid != gid)
146 iflags |= ITEM_REPORT_GROUP;
148 iflags |= ITEM_IS_NEW;
151 @@ -48,6 +48,7 @@ extern int daemon_log_format_has_o_or_i;
152 extern mode_t orig_umask;
153 extern char *auth_user;
154 extern char *log_format;
155 +extern struct id_pair *id_pairs;
156 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
157 extern iconv_t ic_chck;
159 @@ -480,16 +481,16 @@ static void log_formatted(enum logcode c
161 strlcat(fmt, "ld", sizeof fmt);
162 snprintf(buf2, sizeof buf2, fmt,
164 + (long)id_pairs[file->id_ndx].uid);
168 - if (file->gid == GID_NONE)
169 + if (id_pairs[file->id_ndx].gid == GID_NONE)
172 strlcat(fmt, "ld", sizeof fmt);
173 snprintf(buf2, sizeof buf2, fmt,
175 + (long)id_pairs[file->id_ndx].gid);
181 @@ -50,6 +50,7 @@ extern int keep_dirlinks;
182 extern int make_backups;
183 extern mode_t orig_umask;
184 extern struct stats stats;
185 +extern struct id_pair *id_pairs;
186 extern struct chmod_mode_struct *daemon_chmod_modes;
188 #if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
189 @@ -128,6 +129,8 @@ int set_file_attrs(char *fname, struct f
192 int change_uid, change_gid;
198 @@ -160,9 +163,11 @@ int set_file_attrs(char *fname, struct f
202 - change_uid = am_root && preserve_uid && st->st_uid != file->uid;
203 - change_gid = preserve_gid && file->gid != GID_NONE
204 - && st->st_gid != file->gid;
205 + uid = id_pairs[file->id_ndx].uid;
206 + gid = id_pairs[file->id_ndx].gid;
207 + change_uid = am_root && preserve_uid && st->st_uid != uid;
208 + change_gid = preserve_gid && gid != GID_NONE
209 + && st->st_gid != gid;
210 #if !defined HAVE_LCHOWN && !defined CHOWN_MODIFIES_SYMLINK
211 if (S_ISLNK(st->st_mode))
213 @@ -174,18 +179,18 @@ int set_file_attrs(char *fname, struct f
215 "set uid of %s from %ld to %ld\n",
217 - (long)st->st_uid, (long)file->uid);
218 + (long)st->st_uid, (long)uid);
222 "set gid of %s from %ld to %ld\n",
224 - (long)st->st_gid, (long)file->gid);
225 + (long)st->st_gid, (long)gid);
229 - change_uid ? file->uid : st->st_uid,
230 - change_gid ? file->gid : st->st_gid) != 0) {
231 + change_uid ? uid : st->st_uid,
232 + change_gid ? gid : st->st_gid) != 0) {
233 /* shouldn't have attempted to change uid or gid
234 * unless have the privilege */
235 rsyserr(FERROR, errno, "%s %s failed",
238 @@ -493,6 +493,11 @@ struct hlink {
247 #define F_DEV link_u.idev->dev
248 #define F_INODE link_u.idev->inode
250 @@ -517,8 +522,7 @@ struct file_struct {
258 uchar flags; /* this item MUST remain last */
262 @@ -37,6 +37,8 @@ extern int preserve_gid;
263 extern int numeric_ids;
266 +struct id_pair *id_pairs;
271 @@ -46,6 +48,8 @@ struct idlist {
272 static struct idlist *uidlist;
273 static struct idlist *gidlist;
275 +static int pair_cnt = 0, pair_alloc = 0;
277 static struct idlist *add_to_list(struct idlist **root, int id, char *name,
280 @@ -307,7 +311,7 @@ void send_uid_list(int f)
282 /* recv a complete uid/gid mapping from the peer and map the uid/gid
283 * in the file list to local names */
284 -void recv_uid_list(int f, struct file_list *flist)
285 +void recv_uid_list(int f)
289 @@ -338,11 +342,40 @@ void recv_uid_list(int f, struct file_li
291 /* Now convert all the uids/gids from sender values to our values. */
292 if (am_root && preserve_uid && !numeric_ids) {
293 - for (i = 0; i < flist->count; i++)
294 - flist->files[i]->uid = match_uid(flist->files[i]->uid);
295 + for (i = 0; i < pair_cnt; i++)
296 + id_pairs[i].uid = match_uid(id_pairs[i].uid);
298 if (preserve_gid && (!am_root || !numeric_ids)) {
299 - for (i = 0; i < flist->count; i++)
300 - flist->files[i]->gid = match_gid(flist->files[i]->gid);
301 + for (i = 0; i < pair_cnt; i++)
302 + id_pairs[i].gid = match_gid(id_pairs[i].gid);
306 +int id_pair(uid_t uid, gid_t gid)
312 + /* We start our search where we left off because
313 + * the IDs usually come in clumps. */
315 + if (uid == id_pairs[j].uid && gid == id_pairs[j].gid)
317 + if (++j == pair_cnt)
319 + } while (j != start);
322 + if (pair_cnt == pair_alloc) {
324 + id_pairs = realloc_array(id_pairs, struct id_pair,
329 + id_pairs[j].uid = uid;
330 + id_pairs[j].gid = gid;