Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
liblongpath-rsync
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
liblongpath
liblongpath-rsync
Commits
1d5cda22
Commit
1d5cda22
authored
Jan 12, 2004
by
Wayne Davison
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated to perform a much more efficient hlink algorithm that doesn't
require any binary searching of hlink data.
parent
fe70ad26
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
74 additions
and
84 deletions
+74
-84
hlink.c
hlink.c
+74
-84
No files found.
hlink.c
View file @
1d5cda22
...
@@ -40,6 +40,46 @@ static int hlink_compare(struct file_struct **file1, struct file_struct **file2)
...
@@ -40,6 +40,46 @@ static int hlink_compare(struct file_struct **file1, struct file_struct **file2)
static
struct
file_struct
**
hlink_list
;
static
struct
file_struct
**
hlink_list
;
static
int
hlink_count
;
static
int
hlink_count
;
#define LINKED(p1,p2) ((p1)->F_DEV == (p2)->F_DEV \
&& (p1)->F_INODE == (p2)->F_INODE)
/* Analyze the data in the hlink_list[], remove items that aren't multiply
* linked, and replace the dev+inode data with the head+next linked list. */
static
void
link_idev_data
(
void
)
{
struct
file_struct
*
head
;
int
from
,
to
,
start
;
for
(
from
=
to
=
0
;
from
<
hlink_count
;
from
++
)
{
start
=
from
;
head
=
hlink_list
[
start
];
while
(
from
<
hlink_count
-
1
&&
LINKED
(
hlink_list
[
from
],
hlink_list
[
from
+
1
]))
{
hlink_list
[
from
]
->
F_HEAD
=
head
;
hlink_list
[
from
]
->
F_NEXT
=
hlink_list
[
from
+
1
];
from
++
;
}
if
(
from
>
start
)
{
hlink_list
[
from
]
->
F_HEAD
=
head
;
hlink_list
[
from
]
->
F_NEXT
=
NULL
;
hlink_list
[
to
++
]
=
head
;
}
else
{
free
((
char
*
)
head
->
link_u
.
idev
);
head
->
link_u
.
idev
=
NULL
;
}
}
if
(
!
to
)
{
free
(
hlink_list
);
hlink_list
=
NULL
;
}
else
{
hlink_count
=
to
;
if
(
!
(
hlink_list
=
realloc_array
(
hlink_list
,
struct
file_struct
*
,
hlink_count
)))
out_of_memory
(
"init_hard_links"
);
}
}
#endif
#endif
void
init_hard_links
(
struct
file_list
*
flist
)
void
init_hard_links
(
struct
file_list
*
flist
)
...
@@ -56,10 +96,6 @@ void init_hard_links(struct file_list *flist)
...
@@ -56,10 +96,6 @@ void init_hard_links(struct file_list *flist)
if
(
!
(
hlink_list
=
new_array
(
struct
file_struct
*
,
flist
->
count
)))
if
(
!
(
hlink_list
=
new_array
(
struct
file_struct
*
,
flist
->
count
)))
out_of_memory
(
"init_hard_links"
);
out_of_memory
(
"init_hard_links"
);
/* we'll want to restore the memcpy when we purge the
* hlink list after the sort.
* memcpy(hlink_list, flist->files, sizeof(hlink_list[0]) * flist->count);
*/
hlink_count
=
0
;
hlink_count
=
0
;
for
(
i
=
0
;
i
<
flist
->
count
;
i
++
)
{
for
(
i
=
0
;
i
<
flist
->
count
;
i
++
)
{
if
(
flist
->
files
[
i
]
->
link_u
.
idev
)
if
(
flist
->
files
[
i
]
->
link_u
.
idev
)
...
@@ -72,88 +108,21 @@ void init_hard_links(struct file_list *flist)
...
@@ -72,88 +108,21 @@ void init_hard_links(struct file_list *flist)
if
(
!
hlink_count
)
{
if
(
!
hlink_count
)
{
free
(
hlink_list
);
free
(
hlink_list
);
hlink_list
=
NULL
;
hlink_list
=
NULL
;
}
else
if
(
!
(
hlink_list
=
realloc_array
(
hlink_list
,
}
else
struct
file_struct
*
,
hlink_count
)))
link_idev_data
();
out_of_memory
(
"init_hard_links"
);
#endif
}
/* check if a file should be skipped because it is the same as an
earlier hard link */
int
check_hard_link
(
struct
file_struct
*
file
)
{
#if SUPPORT_HARD_LINKS
int
low
=
0
,
high
=
hlink_count
-
1
;
int
ret
=
0
;
if
(
!
hlink_list
||
!
file
->
link_u
.
idev
)
return
0
;
while
(
low
!=
high
)
{
int
mid
=
(
low
+
high
)
/
2
;
ret
=
hlink_compare
(
&
hlink_list
[
mid
],
&
file
);
if
(
ret
==
0
)
{
low
=
mid
;
break
;
}
if
(
ret
>
0
)
high
=
mid
;
else
low
=
mid
+
1
;
}
/* Check if we ended up finding the file struct or not. */
if
(
hlink_compare
(
&
hlink_list
[
low
],
&
file
)
!=
0
)
return
0
;
/* Now check if the previous item shares the current one's device
* and inode. If so, we're not the "master", so return 1. */
if
(
low
>
0
&&
file
->
F_DEV
==
hlink_list
[
low
-
1
]
->
F_DEV
&&
file
->
F_INODE
==
hlink_list
[
low
-
1
]
->
F_INODE
)
{
if
(
verbose
>=
2
)
{
rprintf
(
FINFO
,
"check_hard_link:
\"
%s
\"
is a hard link to file %d,
\"
%s
\"\n
"
,
f_name
(
file
),
low
-
1
,
f_name
(
hlink_list
[
low
-
1
]));
}
return
1
;
}
#endif
#endif
return
0
;
}
}
#if SUPPORT_HARD_LINKS
#if SUPPORT_HARD_LINKS
static
void
hard_link_one
(
int
i
)
static
void
hard_link_one
(
char
*
hlink1
,
char
*
hlink2
)
{
{
STRUCT_STAT
st1
,
st2
;
if
(
do_link
(
hlink1
,
hlink2
))
{
char
*
hlink2
,
*
hlink1
=
f_name
(
hlink_list
[
i
-
1
]);
if
(
verbose
>
0
)
{
rprintf
(
FINFO
,
"link %s => %s failed: %s
\n
"
,
if
(
link_stat
(
hlink1
,
&
st1
)
!=
0
)
hlink2
,
hlink1
,
strerror
(
errno
));
return
;
hlink2
=
f_name
(
hlink_list
[
i
]);
if
(
link_stat
(
hlink2
,
&
st2
)
!=
0
)
{
if
(
do_link
(
hlink1
,
hlink2
))
{
if
(
verbose
>
0
)
{
rprintf
(
FINFO
,
"link %s => %s : %s
\n
"
,
hlink2
,
hlink1
,
strerror
(
errno
));
}
return
;
}
}
else
{
if
(
st2
.
st_dev
==
st1
.
st_dev
&&
st2
.
st_ino
==
st1
.
st_ino
)
return
;
if
(
robust_unlink
(
hlink2
)
||
do_link
(
hlink1
,
hlink2
))
{
if
(
verbose
>
0
)
{
rprintf
(
FINFO
,
"link %s => %s : %s
\n
"
,
hlink2
,
hlink1
,
strerror
(
errno
));
}
return
;
}
}
}
}
if
(
verbose
>
0
)
else
if
(
verbose
>
0
)
rprintf
(
FINFO
,
"%s => %s
\n
"
,
hlink2
,
hlink1
);
rprintf
(
FINFO
,
"%s => %s
\n
"
,
hlink2
,
hlink1
);
}
}
#endif
#endif
...
@@ -167,16 +136,37 @@ static void hard_link_one(int i)
...
@@ -167,16 +136,37 @@ static void hard_link_one(int i)
void
do_hard_links
(
void
)
void
do_hard_links
(
void
)
{
{
#if SUPPORT_HARD_LINKS
#if SUPPORT_HARD_LINKS
struct
file_struct
*
file
;
char
fbuf
[
MAXPATHLEN
];
char
*
hlink1
,
*
hlink2
;
STRUCT_STAT
st1
,
st2
;
int
i
;
int
i
;
if
(
!
hlink_list
)
if
(
!
hlink_list
)
return
;
return
;
for
(
i
=
1
;
i
<
hlink_count
;
i
++
)
{
for
(
i
=
0
;
i
<
hlink_count
;
i
++
)
{
if
(
hlink_list
[
i
]
->
basename
&&
hlink_list
[
i
-
1
]
->
basename
&&
file
=
hlink_list
[
i
];
hlink_list
[
i
]
->
F_DEV
==
hlink_list
[
i
-
1
]
->
F_DEV
&&
hlink1
=
f_name_to
(
file
,
fbuf
,
sizeof
fbuf
);
hlink_list
[
i
]
->
F_INODE
==
hlink_list
[
i
-
1
]
->
F_INODE
)
{
if
(
link_stat
(
hlink1
,
&
st1
)
!=
0
)
hard_link_one
(
i
);
continue
;
while
((
file
=
file
->
F_NEXT
)
!=
NULL
)
{
hlink2
=
f_name
(
file
);
if
(
link_stat
(
hlink2
,
&
st2
)
==
0
)
{
if
(
st2
.
st_dev
==
st1
.
st_dev
&&
st2
.
st_ino
==
st1
.
st_ino
)
continue
;
if
(
robust_unlink
(
hlink2
))
{
if
(
verbose
>
0
)
{
rprintf
(
FINFO
,
"unlink %s failed: %s
\n
"
,
full_fname
(
hlink2
),
strerror
(
errno
));
}
continue
;
}
}
hard_link_one
(
hlink1
,
hlink2
);
}
}
}
}
#endif
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment