From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- release/src/linux/linux/scripts/squashfs/sort.c | 227 ++++++++++-------------- 1 file changed, 90 insertions(+), 137 deletions(-) (limited to 'release/src/linux/linux/scripts/squashfs/sort.c') diff --git a/release/src/linux/linux/scripts/squashfs/sort.c b/release/src/linux/linux/scripts/squashfs/sort.c index b5371280..c30093fa 100644 --- a/release/src/linux/linux/scripts/squashfs/sort.c +++ b/release/src/linux/linux/scripts/squashfs/sort.c @@ -1,7 +1,8 @@ /* * Create a squashfs filesystem. This is a highly compressed read only filesystem. * - * Copyright (c) 2002, 2003, 2004 Phillip Lougher + * Copyright (c) 2002, 2003, 2004, 2005 + * Phillip Lougher * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,20 +35,32 @@ #include #include +#include "global.h" +#include "sort.h" #ifdef SQUASHFS_TRACE -#define TRACE(s, args...) printf("mksquashfs: "s, ## args) +#define TRACE(s, args...) do { \ + printf("mksquashfs: "s, ## args); \ + } while(0) #else #define TRACE(s, args...) #endif -#define INFO(s, args...) if(!silent) printf("mksquashfs: "s, ## args) -#define ERROR(s, args...) fprintf(stderr, s, ## args) -#define EXIT_MKSQUASHFS() exit(1) -#define BAD_ERROR(s, args...) {\ - fprintf(stderr, "FATAL ERROR:" s, ##args);\ - EXIT_MKSQUASHFS();\ - } +#define INFO(s, args...) do { \ + if(!silent) printf("mksquashfs: "s, ## args); \ + } while(0) +#define ERROR(s, args...) do { \ + fprintf(stderr, s, ## args); \ + } while(0) +#define EXIT_MKSQUASHFS() do { \ + exit(1); \ + } while(0) +#define BAD_ERROR(s, args...) do {\ + fprintf(stderr, "FATAL ERROR:" s, ##args);\ + EXIT_MKSQUASHFS();\ + } while(0); + +int mkisofs_style = -1; struct sort_info { dev_t st_dev; @@ -59,66 +72,17 @@ struct sort_info { struct sort_info *sort_info_list[65536]; struct priority_entry { - char *filename; - long long size; - ino_t st_ino; - dev_t st_dev; + struct dir_ent *dir; struct priority_entry *next; }; struct priority_entry *priority_list[65536]; -struct sorted_inode_entry { - squashfs_inode inode; - ino_t st_ino; - dev_t st_dev; - struct sorted_inode_entry *next; -}; - -struct sorted_inode_entry *sorted_inode_list[65536]; - extern int silent; -extern int excluded(char *filename, struct stat *buf); -extern squashfs_inode write_file(char *filename, long long size, int *c_size); - - -int add_to_sorted_inode_list(squashfs_inode inode, dev_t st_dev, ino_t st_ino) -{ - int hash = st_ino & 0xffff; - struct sorted_inode_entry *new_sorted_inode_entry; - - if((new_sorted_inode_entry = malloc(sizeof(struct sorted_inode_entry))) == NULL) { - ERROR("Out of memory allocating sorted inode entry\n"); - return FALSE; - } - - new_sorted_inode_entry->inode = inode; - new_sorted_inode_entry->st_ino = st_ino; - new_sorted_inode_entry->st_dev = st_dev; - new_sorted_inode_entry->next = sorted_inode_list[hash]; - sorted_inode_list[hash] = new_sorted_inode_entry; - - return TRUE; -} - - -squashfs_inode get_sorted_inode(struct stat *buf) -{ - int hash = buf->st_ino & 0xffff; - struct sorted_inode_entry *sorted_inode_entry; - - for(sorted_inode_entry = sorted_inode_list[hash]; sorted_inode_entry; sorted_inode_entry = sorted_inode_entry->next) - if(buf->st_ino == sorted_inode_entry->st_ino && buf->st_dev == sorted_inode_entry->st_dev) - break; - - if(sorted_inode_entry) - return sorted_inode_entry->inode; - else - return (squashfs_inode) 0; -} +extern squashfs_inode write_file(squashfs_inode *inode, struct dir_ent *dir_ent, long long size, int *c_size); -int add_priority_list(char *filename, struct stat *buf, int priority) +int add_priority_list(struct dir_ent *dir, int priority) { struct priority_entry *new_priority_entry; @@ -128,10 +92,7 @@ int add_priority_list(char *filename, struct stat *buf, int priority) return FALSE; } - new_priority_entry->filename = strdup(filename); - new_priority_entry->size = buf->st_size; - new_priority_entry->st_dev = buf->st_dev; - new_priority_entry->st_ino = buf->st_ino; + new_priority_entry->dir = dir;; new_priority_entry->next = priority_list[priority]; priority_list[priority] = new_priority_entry; return TRUE; @@ -168,8 +129,8 @@ int get_priority(char *filename, struct stat *buf, int priority) } int add_sort_list(char *path, int priority, int source, char *source_path[]) { - int i; - char buffer[4096], filename[4096]; + int i, n; + char filename[4096]; struct stat buf; TRACE("add_sort_list: filename %s, priority %d\n", path, priority); @@ -177,71 +138,73 @@ int add_sort_list(char *path, int priority, int source, char *source_path[]) path[strlen(path) - 2] = '\0'; TRACE("add_sort_list: filename %s, priority %d\n", path, priority); - if(path[0] == '/' || strncmp(path, "./", 2) == 0 || strncmp(path, "../", 3) == 0) { - if(lstat(path, &buf) == -1) { - sprintf(buffer, "Cannot stat sort_list dir/file %s, ignoring", path); - perror(buffer); - return TRUE; - } - TRACE("adding filename %s, priority %d, st_dev %Lx, st_ino %Lx\n", path, priority, buf.st_dev, buf.st_ino); +re_read: + if(path[0] == '/' || strncmp(path, "./", 2) == 0 || strncmp(path, "../", 3) == 0 || mkisofs_style == 1) { + if(lstat(path, &buf) == -1) + goto error; + TRACE("adding filename %s, priority %d, st_dev %llx, st_ino %llx\n", path, priority, buf.st_dev, buf.st_ino); ADD_ENTRY(buf, priority); return TRUE; } - for(i = 0; i < source; i++) { + for(i = 0, n = 0; i < source; i++) { strcat(strcat(strcpy(filename, source_path[i]), "/"), path); if(lstat(filename, &buf) == -1) { - if(!(errno == ENOENT || errno == ENOTDIR)) { - sprintf(buffer, "Cannot stat sort_list dir/file %s, ignoring", filename); - perror(buffer); - } + if(!(errno == ENOENT || errno == ENOTDIR)) + goto error; continue; } ADD_ENTRY(buf, priority); + n ++; } - return TRUE; + + if(n == 0 && mkisofs_style == -1 && lstat(path, &buf) != -1) { + ERROR("WARNING: Mkisofs style sortlist detected! This is supported but please\n"); + ERROR("convert to mksquashfs style sortlist! A sortlist entry "); + ERROR("should be\neither absolute (starting with "); + ERROR("'/') start with './' or '../' (taken to be\nrelative to $PWD), otherwise it "); + ERROR("is assumed the entry is relative to one\nof the source directories, i.e. with "); + ERROR("\"mksquashfs test test.sqsh\",\nthe sortlist "); + ERROR("entry \"file\" is assumed to be inside the directory test.\n\n"); + mkisofs_style = 1; + goto re_read; + } + + mkisofs_style = 0; + + if(n == 1) + return TRUE; + if(n > 1) + BAD_ERROR(" Ambiguous sortlist entry \"%s\"\n\nIt maps to more than one source entry! Please use an absolute path.\n", path); + +error: + fprintf(stderr, "Cannot stat sortlist entry \"%s\"\n", path); + fprintf(stderr, "This is probably because you're using the wrong file\n"); + fprintf(stderr, "path relative to the source directories\n"); + return FALSE; } -void generate_file_priorities(char *pathname, int priority, struct stat *buf) +void generate_file_priorities(struct dir_info *dir, int priority, struct stat *buf) { - char filename[8192]; - DIR *linuxdir; - struct dirent *d_name; - - priority = get_priority(pathname, buf, priority); - - if((linuxdir = opendir(pathname)) == NULL) { - ERROR("Could not open %s, skipping...\n", pathname); - return; - } - - while((d_name = readdir(linuxdir)) != NULL) { - if(strcmp(d_name->d_name, ".") == 0 || strcmp(d_name->d_name, "..") == 0) - continue; - strcat(strcat(strcpy(filename, pathname), "/"), d_name->d_name); + priority = get_priority(dir->pathname, buf, priority); - if(lstat(filename, buf) == -1) { - char buffer[8192]; - sprintf(buffer, "Cannot stat dir/file %s, ignoring", filename); - perror(buffer); - continue; - } - - if(excluded(filename, buf)) + while(dir->current_count < dir->count) { + struct dir_ent *dir_ent = dir->list[dir->current_count++]; + struct stat *buf = &dir_ent->inode->buf; + if(dir_ent->data) continue; switch(buf->st_mode & S_IFMT) { case S_IFREG: - add_priority_list(filename, buf, get_priority(filename, buf, priority)); + add_priority_list(dir_ent, get_priority(dir_ent->pathname, buf, priority)); break; case S_IFDIR: - generate_file_priorities(filename, priority, buf); + generate_file_priorities(dir_ent->dir, priority, buf); break; } } - - closedir(linuxdir); + dir->current_count = 0; } @@ -265,40 +228,30 @@ int read_sort_file(char *filename, int source, char *source_path[]) } -void sort_files_and_write(int source, char *source_path[]) +void sort_files_and_write(struct dir_info *dir) { - struct stat buf; - int i, c_size; + int i; struct priority_entry *entry; squashfs_inode inode; + int duplicate_file; - for(i = 0; i < source; i++) { - if(lstat(source_path[i], &buf) == -1) { - char buffer[8192]; - sprintf(buffer, "Cannot stat dir/file %s, ignoring", source_path[i]); - perror(buffer); - continue; - } - - if(excluded(source_path[i], &buf)) - continue; - - switch(buf.st_mode & S_IFMT) { - case S_IFREG: - add_priority_list(source_path[i], &buf, get_priority(source_path[i], &buf, 0)); - break; - case S_IFDIR: - generate_file_priorities(source_path[i], 0, &buf); - break; - } - } + generate_file_priorities(dir, 0, &dir->dir_ent->inode->buf); - for(i = 0; i < 65536; i++) + for(i = 65535; i >= 0; i--) for(entry = priority_list[i]; entry; entry = entry->next) { - TRACE("%d: %s\n", i - 32768, entry->filename); - inode = write_file(entry->filename, entry->size, &c_size); - INFO("file %s, size %d bytes, inode 0x%Lx\n", entry->filename, c_size, inode); - INFO("\t%.2f%% of uncompressed file size (%Ld bytes)\n", ((float) c_size / entry->size) * 100.0, entry->size); - add_to_sorted_inode_list(inode, entry->st_dev, entry->st_ino); + TRACE("%d: %s\n", i - 32768, entry->dir->pathname); + if(entry->dir->inode->inode == SQUASHFS_INVALID_BLK) { + if(write_file(&inode, entry->dir, entry->dir->inode->buf.st_size, + &duplicate_file)) { + INFO("file %s, uncompressed size %lld bytes %s\n", + entry->dir->pathname, + entry->dir->inode->buf.st_size, + duplicate_file ? "DUPLICATE" : ""); + entry->dir->inode->inode = inode; + entry->dir->inode->type = SQUASHFS_FILE_TYPE; + } + } else + INFO("file %s, uncompressed size %lld bytes LINK\n", + entry->dir->pathname, entry->dir->inode->buf.st_size); } } -- cgit v1.2.3-54-g00ecf