関数 | |
static int | hlink_compare (int *int1, int *int2) |
static void | link_idev_data (void) |
void | init_hard_links (void) |
static int | maybe_hard_link (struct file_struct *file, int ndx, char *fname, int statret, STRUCT_STAT *st, char *toname, STRUCT_STAT *to_st, int itemizing, enum logcode code) |
int | hard_link_check (struct file_struct *file, int ndx, char *fname, int statret, STRUCT_STAT *st, int itemizing, enum logcode code, int skip) |
int | hard_link_one (struct file_struct *file, int ndx, char *fname, int statret, STRUCT_STAT *st, char *toname, int terse, int itemizing, enum logcode code) |
void | hard_link_cluster (struct file_struct *file, int master, int itemizing, enum logcode code) |
変数 | |
int | verbose |
int | link_dest |
int | make_backups |
int | log_format_has_i |
char * | basis_dir [] |
file_list * | the_file_list |
static int * | hlink_list |
static int | hlink_count |
static int hlink_compare | ( | int * | int1, | |
int * | int2 | |||
) | [static] |
参照先 f_name_cmp().
参照元 init_hard_links().
00040 { 00041 struct file_struct *f1 = FPTR(*int1); 00042 struct file_struct *f2 = FPTR(*int2); 00043 00044 if (f1->F_DEV != f2->F_DEV) 00045 return (int) (f1->F_DEV > f2->F_DEV ? 1 : -1); 00046 00047 if (f1->F_INODE != f2->F_INODE) 00048 return (int) (f1->F_INODE > f2->F_INODE ? 1 : -1); 00049 00050 return f_name_cmp(f1, f2); 00051 }
static void link_idev_data | ( | void | ) | [static] |
参照先 hlink_count・hlink_list・file_list::hlink_pool・file_struct::link_u・out_of_memory()・pool_create()・pool_destroy()・pool_free()・the_file_list.
参照元 init_hard_links().
00059 { 00060 int cur, from, to, start; 00061 00062 alloc_pool_t hlink_pool; 00063 alloc_pool_t idev_pool = the_file_list->hlink_pool; 00064 00065 hlink_pool = pool_create(128 * 1024, sizeof (struct hlink), 00066 out_of_memory, POOL_INTERN); 00067 00068 for (from = to = 0; from < hlink_count; from++) { 00069 start = from; 00070 while (1) { 00071 cur = hlink_list[from]; 00072 if (from == hlink_count-1 00073 || !LINKED(cur, hlink_list[from+1])) 00074 break; 00075 pool_free(idev_pool, 0, FPTR(cur)->link_u.idev); 00076 FPTR(cur)->link_u.links = pool_talloc(hlink_pool, 00077 struct hlink, 1, "hlink_list"); 00078 00079 FPTR(cur)->F_HLINDEX = to; 00080 FPTR(cur)->F_NEXT = hlink_list[++from]; 00081 } 00082 pool_free(idev_pool, 0, FPTR(cur)->link_u.idev); 00083 if (from > start) { 00084 int head = hlink_list[start]; 00085 FPTR(cur)->link_u.links = pool_talloc(hlink_pool, 00086 struct hlink, 1, "hlink_list"); 00087 00088 FPTR(head)->flags |= FLAG_HLINK_TOL; 00089 FPTR(cur)->F_HLINDEX = to; 00090 FPTR(cur)->F_NEXT = head; 00091 FPTR(cur)->flags |= FLAG_HLINK_EOL; 00092 hlink_list[to++] = head; 00093 } else 00094 FPTR(cur)->link_u.links = NULL; 00095 } 00096 00097 if (!to) { 00098 free(hlink_list); 00099 hlink_list = NULL; 00100 pool_destroy(hlink_pool); 00101 hlink_pool = NULL; 00102 } else { 00103 hlink_count = to; 00104 hlink_list = realloc_array(hlink_list, int, hlink_count); 00105 if (!hlink_list) 00106 out_of_memory("init_hard_links"); 00107 } 00108 the_file_list->hlink_pool = hlink_pool; 00109 pool_destroy(idev_pool); 00110 }
void init_hard_links | ( | void | ) |
参照先 file_list::count・hlink_compare()・hlink_count・hlink_list・link_idev_data()・file_struct::link_u・out_of_memory()・the_file_list.
参照元 do_recv().
00114 { 00115 #ifdef SUPPORT_HARD_LINKS 00116 int i; 00117 00118 if (hlink_list) 00119 free(hlink_list); 00120 00121 if (!(hlink_list = new_array(int, the_file_list->count))) 00122 out_of_memory("init_hard_links"); 00123 00124 hlink_count = 0; 00125 for (i = 0; i < the_file_list->count; i++) { 00126 if (FPTR(i)->link_u.idev) 00127 hlink_list[hlink_count++] = i; 00128 } 00129 00130 qsort(hlink_list, hlink_count, 00131 sizeof hlink_list[0], (int (*)()) hlink_compare); 00132 00133 if (!hlink_count) { 00134 free(hlink_list); 00135 hlink_list = NULL; 00136 } else 00137 link_idev_data(); 00138 #endif 00139 }
static int maybe_hard_link | ( | struct file_struct * | file, | |
int | ndx, | |||
char * | fname, | |||
int | statret, | |||
STRUCT_STAT * | st, | |||
char * | toname, | |||
STRUCT_STAT * | to_st, | |||
int | itemizing, | |||
enum logcode | code | |||
) | [static] |
参照先 errno・FERROR・full_fname()・hard_link_one()・itemize()・make_backup()・make_backups・robust_unlink()・rsyserr().
参照元 hard_link_check()・hard_link_cluster().
00146 { 00147 if (statret == 0) { 00148 if (st->st_dev == to_st->st_dev 00149 && st->st_ino == to_st->st_ino) { 00150 if (itemizing) { 00151 itemize(file, ndx, statret, st, 00152 ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 00153 0, ""); 00154 } 00155 return 0; 00156 } 00157 if (make_backups) { 00158 if (!make_backup(fname)) 00159 return -1; 00160 } else if (robust_unlink(fname)) { 00161 rsyserr(FERROR, errno, "unlink %s failed", 00162 full_fname(fname)); 00163 return -1; 00164 } 00165 } 00166 return hard_link_one(file, ndx, fname, statret, st, toname, 00167 0, itemizing, code); 00168 }
int hard_link_check | ( | struct file_struct * | file, | |
int | ndx, | |||
char * | fname, | |||
int | statret, | |||
STRUCT_STAT * | st, | |||
int | itemizing, | |||
enum logcode | code, | |||
int | skip | |||
) |
参照先 basis_dir・errno・f_name()・FERROR・FINFO・file_struct::flags・full_fname()・hlink_list・link_dest・link_stat()・log_format_has_i・maybe_hard_link()・pathjoin()・rprintf()・rsyserr()・unchanged_attrs()・unchanged_file()・verbose.
参照元 recv_generator().
00174 { 00175 #ifdef SUPPORT_HARD_LINKS 00176 int head; 00177 if (skip && !(file->flags & FLAG_HLINK_EOL)) 00178 head = hlink_list[file->F_HLINDEX] = file->F_NEXT; 00179 else 00180 head = hlink_list[file->F_HLINDEX]; 00181 if (ndx != head) { 00182 struct file_struct *head_file = FPTR(head); 00183 if (!log_format_has_i && verbose > 1) { 00184 rprintf(FINFO, "\"%s\" is a hard link\n", 00185 f_name(file, NULL)); 00186 } 00187 if (head_file->F_HLINDEX == FINISHED_LINK) { 00188 STRUCT_STAT st2, st3; 00189 char *toname = f_name(head_file, NULL); 00190 if (link_stat(toname, &st2, 0) < 0) { 00191 rsyserr(FERROR, errno, "stat %s failed", 00192 full_fname(toname)); 00193 return -1; 00194 } 00195 if (statret < 0 && basis_dir[0] != NULL) { 00196 char cmpbuf[MAXPATHLEN]; 00197 int j = 0; 00198 do { 00199 pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname); 00200 if (link_stat(cmpbuf, &st3, 0) < 0) 00201 continue; 00202 if (link_dest) { 00203 if (st2.st_dev != st3.st_dev 00204 || st2.st_ino != st3.st_ino) 00205 continue; 00206 statret = 1; 00207 st = &st3; 00208 if (verbose < 2 || !log_format_has_i) 00209 itemizing = code = 0; 00210 break; 00211 } 00212 if (!unchanged_file(cmpbuf, file, &st3)) 00213 continue; 00214 statret = 1; 00215 st = &st3; 00216 if (unchanged_attrs(file, &st3)) 00217 break; 00218 } while (basis_dir[++j] != NULL); 00219 } 00220 maybe_hard_link(file, ndx, fname, statret, st, 00221 toname, &st2, itemizing, code); 00222 file->F_HLINDEX = FINISHED_LINK; 00223 } else 00224 file->F_HLINDEX = SKIPPED_LINK; 00225 return 1; 00226 } 00227 #endif 00228 return 0; 00229 }
int hard_link_one | ( | struct file_struct * | file, | |
int | ndx, | |||
char * | fname, | |||
int | statret, | |||
STRUCT_STAT * | st, | |||
char * | toname, | |||
int | terse, | |||
int | itemizing, | |||
enum logcode | code | |||
) |
参照先 do_link()・errno・FERROR・FINFO・full_fname()・itemize()・rprintf()・rsyserr()・verbose.
参照元 maybe_hard_link()・try_dests_reg().
00235 { 00236 if (do_link(toname, fname)) { 00237 if (terse) { 00238 if (!verbose) 00239 return -1; 00240 code = FINFO; 00241 } else 00242 code = FERROR; 00243 rsyserr(code, errno, "link %s => %s failed", 00244 full_fname(fname), toname); 00245 return -1; 00246 } 00247 00248 if (itemizing) { 00249 itemize(file, ndx, statret, st, 00250 ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0, 00251 terse ? "" : toname); 00252 } 00253 if (code && verbose && !terse) 00254 rprintf(code, "%s => %s\n", fname, toname); 00255 return 0; 00256 }
void hard_link_cluster | ( | struct file_struct * | file, | |
int | master, | |||
int | itemizing, | |||
enum logcode | code | |||
) |
参照先 f_name()・file_struct::flags・link_stat()・maybe_hard_link().
参照元 check_for_finished_hlinks()・recv_generator()・try_dests_non()・try_dests_reg().
00262 { 00263 #ifdef SUPPORT_HARD_LINKS 00264 char hlink1[MAXPATHLEN]; 00265 char *hlink2; 00266 STRUCT_STAT st1, st2; 00267 int statret, ndx = master; 00268 00269 file->F_HLINDEX = FINISHED_LINK; 00270 if (link_stat(f_name(file, hlink1), &st1, 0) < 0) 00271 return; 00272 if (!(file->flags & FLAG_HLINK_TOL)) { 00273 while (!(file->flags & FLAG_HLINK_EOL)) { 00274 ndx = file->F_NEXT; 00275 file = FPTR(ndx); 00276 } 00277 } 00278 do { 00279 ndx = file->F_NEXT; 00280 file = FPTR(ndx); 00281 if (file->F_HLINDEX != SKIPPED_LINK) 00282 continue; 00283 hlink2 = f_name(file, NULL); 00284 statret = link_stat(hlink2, &st2, 0); 00285 maybe_hard_link(file, ndx, hlink2, statret, &st2, 00286 hlink1, &st1, itemizing, code); 00287 file->F_HLINDEX = FINISHED_LINK; 00288 } while (!(file->flags & FLAG_HLINK_EOL)); 00289 #endif 00290 }
int make_backups |
int log_format_has_i |
struct file_list* the_file_list |
int* hlink_list [static] |
int hlink_count [static] |