diff options
| -rw-r--r-- | include/fstree.h | 5 | ||||
| -rw-r--r-- | lib/common/src/writer/serialize_fstree.c | 3 | ||||
| -rw-r--r-- | lib/fstree/src/hardlink.c | 13 | ||||
| -rw-r--r-- | lib/fstree/src/post_process.c | 25 | 
4 files changed, 25 insertions, 21 deletions
| diff --git a/include/fstree.h b/include/fstree.h index 72cbc29..d08ccae 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -18,9 +18,6 @@  #include "io/istream.h"  #include "compat.h" -#define FSTREE_MODE_HARD_LINK (0) -#define FSTREE_MODE_HARD_LINK_RESOLVED (1) -  typedef struct fstree_defaults_t fstree_defaults_t;  typedef struct tree_node_t tree_node_t;  typedef struct fstree_t fstree_t; @@ -28,6 +25,8 @@ typedef struct fstree_t fstree_t;  enum {  	FLAG_DIR_CREATED_IMPLICITLY = 0x01,  	FLAG_FILE_ALREADY_MATCHED = 0x02, +	FLAG_LINK_IS_HARD = 0x04, +	FLAG_LINK_RESOVED = 0x08,  };  /* A node in a file system tree */ diff --git a/lib/common/src/writer/serialize_fstree.c b/lib/common/src/writer/serialize_fstree.c index 7ecd850..b5151f3 100644 --- a/lib/common/src/writer/serialize_fstree.c +++ b/lib/common/src/writer/serialize_fstree.c @@ -35,6 +35,7 @@ static sqfs_inode_generic_t *tree_node_to_inode(tree_node_t *node)  		inode->data.ipc.nlink = node->link_count;  		break;  	case S_IFLNK: +		assert(!(node->flags & FLAG_LINK_IS_HARD));  		inode->base.type = SQFS_INODE_SLINK;  		inode->data.slink.nlink = node->link_count;  		inode->data.slink.target_size = extra; @@ -71,7 +72,7 @@ static sqfs_inode_generic_t *write_dir_entries(const char *filename,  		goto fail;  	for (it = node->data.children; it != NULL; it = it->next) { -		if (it->mode == FSTREE_MODE_HARD_LINK_RESOLVED) { +		if (S_ISLNK(it->mode) && (it->flags & FLAG_LINK_IS_HARD)) {  			tgt = it->data.target_node;  		} else {  			tgt = it; diff --git a/lib/fstree/src/hardlink.c b/lib/fstree/src/hardlink.c index 81636c7..b6467e2 100644 --- a/lib/fstree/src/hardlink.c +++ b/lib/fstree/src/hardlink.c @@ -18,16 +18,17 @@ static int resolve_link(fstree_t *fs, tree_node_t *node)  	tree_node_t *start = node;  	for (;;) { -		if (node->mode == FSTREE_MODE_HARD_LINK_RESOLVED) { +		if (!S_ISLNK(node->mode) || !(node->flags & FLAG_LINK_IS_HARD)) +			break; + +		if (node->flags & FLAG_LINK_RESOVED) {  			node = node->data.target_node; -		} else if (node->mode == FSTREE_MODE_HARD_LINK) { +		} else {  			node = fstree_get_node_by_path(fs, fs->root,  						       node->data.target,  						       false, false);  			if (node == NULL)  				return -1; -		} else { -			break;  		}  		if (node == start) { @@ -46,7 +47,7 @@ static int resolve_link(fstree_t *fs, tree_node_t *node)  		return -1;  	} -	start->mode = FSTREE_MODE_HARD_LINK_RESOLVED; +	start->flags |= FLAG_LINK_RESOVED;  	start->data.target_node = node;  	node->link_count++; @@ -70,7 +71,7 @@ tree_node_t *fstree_add_hard_link(fstree_t *fs, const char *path,  			return NULL;  		} -		n->mode = FSTREE_MODE_HARD_LINK; +		n->flags |= FLAG_LINK_IS_HARD;  	}  	n->next_by_type = fs->links_unresolved; diff --git a/lib/fstree/src/post_process.c b/lib/fstree/src/post_process.c index f8bc0f7..c5a15a3 100644 --- a/lib/fstree/src/post_process.c +++ b/lib/fstree/src/post_process.c @@ -35,18 +35,19 @@ static int alloc_inode_num_dfs(fstree_t *fs, tree_node_t *root)  	}  	for (it = root->data.children; it != NULL; it = it->next) { -		if (it->mode != FSTREE_MODE_HARD_LINK_RESOLVED) { -			if (SZ_ADD_OV(fs->unique_inode_count, 1, &inum)) -				goto fail_ov; +		if (S_ISLNK(it->mode) && (it->flags & FLAG_LINK_IS_HARD)) +			continue; -			if ((sizeof(size_t) > sizeof(sqfs_u32)) && -			    inum > 0x0FFFFFFFFUL) { -				goto fail_ov; -			} +		if (SZ_ADD_OV(fs->unique_inode_count, 1, &inum)) +			goto fail_ov; -			it->inode_num = (sqfs_u32)inum; -			fs->unique_inode_count = inum; +		if ((sizeof(size_t) > sizeof(sqfs_u32)) && +		    inum > 0x0FFFFFFFFUL) { +			goto fail_ov;  		} + +		it->inode_num = (sqfs_u32)inum; +		fs->unique_inode_count = inum;  	}  	return 0; @@ -87,7 +88,7 @@ static tree_node_t *file_list_dfs(tree_node_t *n)  static void map_inodes_dfs(fstree_t *fs, tree_node_t *n)  { -	if (n->mode == FSTREE_MODE_HARD_LINK_RESOLVED) +	if (S_ISLNK(n->mode) && (n->flags & FLAG_LINK_IS_HARD))  		return;  	fs->inodes[n->inode_num - 1] = n; @@ -110,7 +111,9 @@ static void reorder_hard_links(fstree_t *fs)  		it = fs->inodes[i]->data.children;  		for (; it != NULL; it = it->next) { -			if (it->mode != FSTREE_MODE_HARD_LINK_RESOLVED) +			if (!S_ISLNK(it->mode)) +				continue; +			if (!(it->flags & FLAG_LINK_IS_HARD))  				continue;  			tgt = it->data.target_node; | 
