Line data Source code
1 : /*
2 : Bacula® - The Network Backup Solution
3 :
4 : Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
5 :
6 : The main author of Bacula is Kern Sibbald, with contributions from
7 : many others, a complete list can be found in the file AUTHORS.
8 : This program is Free Software; you can redistribute it and/or
9 : modify it under the terms of version three of the GNU Affero General Public
10 : License as published by the Free Software Foundation and included
11 : in the file LICENSE.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU Affero General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : Bacula® is a registered trademark of Kern Sibbald.
24 : The licensor of Bacula is the Free Software Foundation Europe
25 : (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 : Switzerland, email:ftf@fsfeurope.org.
27 : */
28 : /*
29 : Code extracted from findlib from bacula-5.0.3, and
30 : heavily modified. Therefore, I have retained the bacula copyright notice.
31 :
32 : Graham Keeling, 2015.
33 : */
34 :
35 : #include "burp.h"
36 : #include "handy.h"
37 : #include "linkhash.h"
38 :
39 : // List of all hard linked files found.
40 : struct f_link **linkhash=NULL;
41 :
42 : #define LINK_HASHTABLE_BITS 16
43 : #define LINK_HASHTABLE_SIZE (1<<LINK_HASHTABLE_BITS)
44 : #define LINK_HASHTABLE_MASK (LINK_HASHTABLE_SIZE-1)
45 :
46 16 : int linkhash_init(void)
47 : {
48 16 : if(!(linkhash=(struct f_link **)calloc_w(1,
49 : LINK_HASHTABLE_SIZE*sizeof(*linkhash), __func__)))
50 : return -1;
51 16 : return 0;
52 : }
53 :
54 16 : void linkhash_free(void)
55 : {
56 : int i;
57 : struct f_link *lp;
58 : struct f_link *lc;
59 :
60 16 : if(!linkhash) return;
61 :
62 1048576 : for(i=0; i<LINK_HASHTABLE_SIZE; i++)
63 : {
64 : // Free up list of hard linked files.
65 1048576 : lp=linkhash[i];
66 2097154 : while(lp)
67 : {
68 2 : lc=lp;
69 2 : lp=lp->next;
70 : if(lc)
71 : {
72 2 : free_w(&lc->name);
73 2 : free_v((void **)&lc);
74 : }
75 : }
76 1048576 : linkhash[i]=NULL;
77 : }
78 16 : free_v((void **)&linkhash);
79 : }
80 :
81 : static inline int get_hash(struct stat *statp)
82 : {
83 5 : int hash=statp->st_dev;
84 5 : uint64_t i=statp->st_ino;
85 5 : hash ^= i;
86 5 : i >>= 16;
87 5 : hash ^= i;
88 5 : i >>= 16;
89 5 : hash ^= i;
90 5 : i >>= 16;
91 5 : hash ^= i;
92 5 : return hash & LINK_HASHTABLE_MASK;
93 : }
94 :
95 5 : struct f_link *linkhash_search(struct stat *statp, struct f_link ***bucket)
96 : {
97 : struct f_link *lp;
98 10 : *bucket=&linkhash[get_hash(statp)];
99 5 : for(lp=**bucket; lp; lp=lp->next)
100 2 : if(lp->ino==(ino_t)statp->st_ino
101 2 : && lp->dev==(dev_t)statp->st_dev)
102 : return lp;
103 : return NULL;
104 : }
105 :
106 2 : int linkhash_add(char *fname, struct stat *statp, struct f_link **bucket)
107 : {
108 : struct f_link *new_fl;
109 2 : if(!(new_fl=(struct f_link *)malloc_w(sizeof(struct f_link), __func__))
110 2 : || !(new_fl->name=strdup_w(fname, __func__)))
111 : return -1;
112 2 : new_fl->ino=statp->st_ino;
113 2 : new_fl->dev=statp->st_dev;
114 2 : new_fl->next=*bucket;
115 2 : *bucket=new_fl;
116 2 : return 0;
117 : }
|