summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorRobert Yang <liezhi.yang@windriver.com>2014-03-07 01:59:30 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-03-07 14:45:23 +0000
commitb489b945bd7718092185ccbcc32de4abcead8132 (patch)
tree0a5ef2b9a8f94c569adeead07f908641a5554345 /meta
parent90749060f02c930764dc4c7ebc4c1421334663bf (diff)
downloadpoky-b489b945bd7718092185ccbcc32de4abcead8132.tar.gz
e2fsprogs: mke2fs: handle hardlinks
Create the inode and save the native inode number when we meet the hard link (st_nlink > 1) at the first time, use ext2fs_link() to link the name to the target inode number when we meet the same native inode number again. This algorithm is referred from the genext2fs. [YOCTO #4083] (From OE-Core rev: 174ec622bdc00fc26392704fdadeac2c067a33f6) Signed-off-by: Robert Yang <liezhi.yang@windriver.com> Reviewed-by: Darren Hart <dvhart@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-devtools/e2fsprogs/e2fsprogs/0009-misc-create_inode.c-handle-hardlinks.patch210
1 files changed, 210 insertions, 0 deletions
diff --git a/meta/recipes-devtools/e2fsprogs/e2fsprogs/0009-misc-create_inode.c-handle-hardlinks.patch b/meta/recipes-devtools/e2fsprogs/e2fsprogs/0009-misc-create_inode.c-handle-hardlinks.patch
new file mode 100644
index 0000000000..a330ee45a5
--- /dev/null
+++ b/meta/recipes-devtools/e2fsprogs/e2fsprogs/0009-misc-create_inode.c-handle-hardlinks.patch
@@ -0,0 +1,210 @@
1From d83dc950b3ec1fbde33b23d42c5154091a74f4d9 Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Mon, 23 Dec 2013 03:44:03 -0500
4Subject: [PATCH 09/11] misc/create_inode.c: handle hardlinks
5
6Create the inode and save the native inode number when we meet the hard
7link (st_nlink > 1) at the first time, use ext2fs_link() to link the
8name to the target inode number when we meet the same native inode
9number again.
10
11This algorithm is referred from the genext2fs.
12
13Upstream-Status: Backport
14
15Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
16Reviewed-by: Darren Hart <dvhart@linux.intel.com>
17---
18 misc/create_inode.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
19 misc/create_inode.h | 18 +++++++++++
20 misc/mke2fs.c | 12 +++++++
21 3 files changed, 118 insertions(+)
22
23diff --git a/misc/create_inode.c b/misc/create_inode.c
24index aad7354..763504d 100644
25--- a/misc/create_inode.c
26+++ b/misc/create_inode.c
27@@ -18,6 +18,44 @@
28 #define S_BLKSIZE 512
29 #endif
30
31+/* For saving the hard links */
32+int hdlink_cnt = HDLINK_CNT;
33+
34+/* Link an inode number to a directory */
35+static errcode_t add_link(ext2_ino_t parent_ino, ext2_ino_t ino, const char *name)
36+{
37+ struct ext2_inode inode;
38+ errcode_t retval;
39+
40+ retval = ext2fs_read_inode(current_fs, ino, &inode);
41+ if (retval) {
42+ com_err(__func__, retval, "while reading inode %u", ino);
43+ return retval;
44+ }
45+
46+ retval = ext2fs_link(current_fs, parent_ino, name, ino, inode.i_flags);
47+ if (retval == EXT2_ET_DIR_NO_SPACE) {
48+ retval = ext2fs_expand_dir(current_fs, parent_ino);
49+ if (retval) {
50+ com_err(__func__, retval, "while expanding directory");
51+ return retval;
52+ }
53+ retval = ext2fs_link(current_fs, parent_ino, name, ino, inode.i_flags);
54+ }
55+ if (retval) {
56+ com_err(__func__, retval, "while linking %s", name);
57+ return retval;
58+ }
59+
60+ inode.i_links_count++;
61+
62+ retval = ext2fs_write_inode(current_fs, ino, &inode);
63+ if (retval)
64+ com_err(__func__, retval, "while writing inode %u", ino);
65+
66+ return retval;
67+}
68+
69 /* Fill the uid, gid, mode and time for the inode */
70 static void fill_inode(struct ext2_inode *inode, struct stat *st)
71 {
72@@ -278,6 +316,17 @@ fail:
73 return retval;
74 }
75
76+int is_hardlink(ext2_ino_t ino)
77+{
78+ int i;
79+
80+ for(i = 0; i < hdlinks.count; i++) {
81+ if(hdlinks.hdl[i].src_ino == ino)
82+ return i;
83+ }
84+ return -1;
85+}
86+
87 /* Copy the native file to the fs */
88 errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
89 {
90@@ -388,9 +437,11 @@ errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
91 struct dirent *dent;
92 struct stat st;
93 char ln_target[PATH_MAX];
94+ unsigned int save_inode;
95 ext2_ino_t ino;
96 errcode_t retval;
97 int read_cnt;
98+ int hdlink;
99
100 root = EXT2_ROOT_INO;
101
102@@ -412,6 +463,22 @@ errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
103 lstat(dent->d_name, &st);
104 name = dent->d_name;
105
106+ /* Check for hardlinks */
107+ save_inode = 0;
108+ if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) && st.st_nlink > 1) {
109+ hdlink = is_hardlink(st.st_ino);
110+ if (hdlink >= 0) {
111+ retval = add_link(parent_ino,
112+ hdlinks.hdl[hdlink].dst_ino, name);
113+ if (retval) {
114+ com_err(__func__, retval, "while linking %s", name);
115+ return retval;
116+ }
117+ continue;
118+ } else
119+ save_inode = 1;
120+ }
121+
122 switch(st.st_mode & S_IFMT) {
123 case S_IFCHR:
124 case S_IFBLK:
125@@ -480,6 +547,27 @@ errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
126 _("while setting inode for \"%s\""), name);
127 return retval;
128 }
129+
130+ /* Save the hardlink ino */
131+ if (save_inode) {
132+ /*
133+ * Check whether need more memory, and we don't need
134+ * free() since the lifespan will be over after the fs
135+ * populated.
136+ */
137+ if (hdlinks.count == hdlink_cnt) {
138+ if ((hdlinks.hdl = realloc (hdlinks.hdl,
139+ (hdlink_cnt + HDLINK_CNT) *
140+ sizeof (struct hdlink_s))) == NULL) {
141+ com_err(name, errno, "Not enough memory");
142+ return errno;
143+ }
144+ hdlink_cnt += HDLINK_CNT;
145+ }
146+ hdlinks.hdl[hdlinks.count].src_ino = st.st_ino;
147+ hdlinks.hdl[hdlinks.count].dst_ino = ino;
148+ hdlinks.count++;
149+ }
150 }
151 closedir(dh);
152 return retval;
153diff --git a/misc/create_inode.h b/misc/create_inode.h
154index 9fc97fa..2b6d429 100644
155--- a/misc/create_inode.h
156+++ b/misc/create_inode.h
157@@ -6,9 +6,27 @@
158 #include "ext2fs/ext2fs.h"
159 #include "nls-enable.h"
160
161+struct hdlink_s
162+{
163+ ext2_ino_t src_ino;
164+ ext2_ino_t dst_ino;
165+};
166+
167+struct hdlinks_s
168+{
169+ int count;
170+ struct hdlink_s *hdl;
171+};
172+
173+struct hdlinks_s hdlinks;
174+
175 ext2_filsys current_fs;
176 ext2_ino_t root;
177
178+/* For saving the hard links */
179+#define HDLINK_CNT 4
180+extern int hdlink_cnt;
181+
182 /* For populating the filesystem */
183 extern errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir);
184 extern errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st);
185diff --git a/misc/mke2fs.c b/misc/mke2fs.c
186index 578b62d..a63f0b7 100644
187--- a/misc/mke2fs.c
188+++ b/misc/mke2fs.c
189@@ -2730,6 +2730,18 @@ no_journal:
190 if (!quiet)
191 printf("%s", _("Copying files into the device: "));
192
193+ /*
194+ * Allocate memory for the hardlinks, we don't need free()
195+ * since the lifespan will be over after the fs populated.
196+ */
197+ if ((hdlinks.hdl = (struct hdlink_s *)
198+ malloc(hdlink_cnt * sizeof(struct hdlink_s))) == NULL) {
199+ fprintf(stderr, "%s", _("\nNot enough memory\n"));
200+ retval = ext2fs_close(fs);
201+ return retval;
202+ }
203+
204+ hdlinks.count = 0;
205 current_fs = fs;
206 root = EXT2_ROOT_INO;
207 retval = populate_fs(root, root_dir);
208--
2091.7.10.4
210