X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=fs%2Ffs.c;h=2b815b1db0fed61086a27528aa5bc9a28efa05c8;hb=c5f1d005f51783a5b34d6164ab66289eb1f4a45b;hp=d8a4ced4698ec97b2b6c5e7d11959b94f6545dee;hpb=88c7a0a8c2ce6b503ff5d5509effb2a9f844993e;p=thirdparty%2Fu-boot.git diff --git a/fs/fs.c b/fs/fs.c index d8a4ced4698..2b815b1db0f 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -3,34 +3,51 @@ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. */ +#define LOG_CATEGORY LOGC_CORE + +#include #include +#include #include #include #include +#include +#include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include #include +#include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; static struct blk_desc *fs_dev_desc; static int fs_dev_part; -static disk_partition_t fs_partition; +static struct disk_partition fs_partition; static int fs_type = FS_TYPE_ANY; +void fs_set_type(int type) +{ + fs_type = type; +} + static inline int fs_probe_unsupported(struct blk_desc *fs_dev_desc, - disk_partition_t *fs_partition) + struct disk_partition *fs_partition) { - printf("** Unrecognized filesystem type **\n"); + log_debug("Unrecognized filesystem type\n"); return -1; } @@ -55,6 +72,9 @@ static int fs_ls_generic(const char *dirname) if (dent->type == FS_DT_DIR) { printf(" %s/\n", dent->name); ndirs++; + } else if (dent->type == FS_DT_LNK) { + printf(" %s\n", dent->name); + nfiles++; } else { printf(" %8lld %s\n", dent->size, dent->name); nfiles++; @@ -135,7 +155,7 @@ struct fstype_info { */ bool null_dev_desc_ok; int (*probe)(struct blk_desc *fs_dev_desc, - disk_partition_t *fs_partition); + struct disk_partition *fs_partition); int (*ls)(const char *dirname); int (*exists)(const char *filename); int (*size)(const char *filename, loff_t *size); @@ -165,7 +185,7 @@ struct fstype_info { }; static struct fstype_info fstypes[] = { -#ifdef CONFIG_FS_FAT +#if CONFIG_IS_ENABLED(FS_FAT) { .fstype = FS_TYPE_FAT, .name = "fat", @@ -185,7 +205,7 @@ static struct fstype_info fstypes[] = { .unlink = fs_unlink_unsupported, .mkdir = fs_mkdir_unsupported, #endif - .uuid = fs_uuid_unsupported, + .uuid = fat_uuid, .opendir = fat_opendir, .readdir = fat_readdir, .closedir = fat_closedir, @@ -236,6 +256,26 @@ static struct fstype_info fstypes[] = { .ln = fs_ln_unsupported, }, #endif +#ifdef CONFIG_SEMIHOSTING + { + .fstype = FS_TYPE_SEMIHOSTING, + .name = "semihosting", + .null_dev_desc_ok = true, + .probe = smh_fs_set_blk_dev, + .close = fs_close_unsupported, + .ls = fs_ls_unsupported, + .exists = fs_exists_unsupported, + .size = smh_fs_size, + .read = smh_fs_read, + .write = smh_fs_write, + .uuid = fs_uuid_unsupported, + .opendir = fs_opendir_unsupported, + .unlink = fs_unlink_unsupported, + .mkdir = fs_mkdir_unsupported, + .ln = fs_ln_unsupported, + }, +#endif +#ifndef CONFIG_SPL_BUILD #ifdef CONFIG_CMD_UBIFS { .fstype = FS_TYPE_UBIFS, @@ -255,6 +295,8 @@ static struct fstype_info fstypes[] = { .ln = fs_ln_unsupported, }, #endif +#endif +#ifndef CONFIG_SPL_BUILD #ifdef CONFIG_FS_BTRFS { .fstype = FS_TYPE_BTRFS, @@ -273,6 +315,49 @@ static struct fstype_info fstypes[] = { .mkdir = fs_mkdir_unsupported, .ln = fs_ln_unsupported, }, +#endif +#endif +#if CONFIG_IS_ENABLED(FS_SQUASHFS) + { + .fstype = FS_TYPE_SQUASHFS, + .name = "squashfs", + .null_dev_desc_ok = false, + .probe = sqfs_probe, + .opendir = sqfs_opendir, + .readdir = sqfs_readdir, + .ls = fs_ls_generic, + .read = sqfs_read, + .size = sqfs_size, + .close = sqfs_close, + .closedir = sqfs_closedir, + .exists = sqfs_exists, + .uuid = fs_uuid_unsupported, + .write = fs_write_unsupported, + .ln = fs_ln_unsupported, + .unlink = fs_unlink_unsupported, + .mkdir = fs_mkdir_unsupported, + }, +#endif +#if IS_ENABLED(CONFIG_FS_EROFS) + { + .fstype = FS_TYPE_EROFS, + .name = "erofs", + .null_dev_desc_ok = false, + .probe = erofs_probe, + .opendir = erofs_opendir, + .readdir = erofs_readdir, + .ls = fs_ls_generic, + .read = erofs_read, + .size = erofs_size, + .close = erofs_close, + .closedir = erofs_closedir, + .exists = erofs_exists, + .uuid = fs_uuid_unsupported, + .write = fs_write_unsupported, + .ln = fs_ln_unsupported, + .unlink = fs_unlink_unsupported, + .mkdir = fs_mkdir_unsupported, + }, #endif { .fstype = FS_TYPE_ANY, @@ -307,6 +392,19 @@ static struct fstype_info *fs_get_info(int fstype) return info; } +/** + * fs_get_type() - Get type of current filesystem + * + * Return: filesystem type + * + * Returns filesystem type representing the current filesystem, or + * FS_TYPE_ANY for any unrecognised filesystem. + */ +int fs_get_type(void) +{ + return fs_type; +} + /** * fs_get_type_name() - Get type of current filesystem * @@ -341,8 +439,8 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype) } #endif - part = blk_get_device_part_str(ifname, dev_part_str, &fs_dev_desc, - &fs_partition, 1); + part = part_get_info_by_dev_and_name_or_num(ifname, dev_part_str, &fs_dev_desc, + &fs_partition, 1); if (part < 0) return -1; @@ -389,7 +487,7 @@ int fs_set_blk_dev_with_part(struct blk_desc *desc, int part) return -1; } -static void fs_close(void) +void fs_close(void) { struct fstype_info *info = fs_get_info(fs_type); @@ -413,7 +511,6 @@ int fs_ls(const char *dirname) ret = info->ls(dirname); - fs_type = FS_TYPE_ANY; fs_close(); return ret; @@ -475,7 +572,7 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, if (lmb_alloc_addr(&lmb, addr, read_len) == addr) return 0; - printf("** Reading file would overwrite reserved memory **\n"); + log_err("** Reading file would overwrite reserved memory **\n"); return -ENOSPC; } #endif @@ -505,7 +602,7 @@ static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len, /* If we requested a specific number of bytes, check we got it */ if (ret == 0 && len && *actread != len) - debug("** %s shorter than offset + len **\n", filename); + log_debug("** %s shorter than offset + len **\n", filename); fs_close(); return ret; @@ -529,7 +626,7 @@ int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len, unmap_sysmem(buf); if (ret < 0 && len != *actwrite) { - printf("** Unable to write file %s **\n", filename); + log_err("** Unable to write file %s **\n", filename); ret = -1; } fs_close(); @@ -597,7 +694,6 @@ int fs_unlink(const char *filename) ret = info->unlink(filename); - fs_type = FS_TYPE_ANY; fs_close(); return ret; @@ -611,7 +707,6 @@ int fs_mkdir(const char *dirname) ret = info->mkdir(dirname); - fs_type = FS_TYPE_ANY; fs_close(); return ret; @@ -625,7 +720,7 @@ int fs_ln(const char *fname, const char *target) ret = info->ln(fname, target); if (ret < 0) { - printf("** Unable to create link %s -> %s **\n", fname, target); + log_err("** Unable to create link %s -> %s **\n", fname, target); ret = -1; } fs_close(); @@ -633,8 +728,8 @@ int fs_ln(const char *fname, const char *target) return ret; } -int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], - int fstype) +int do_size(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], + int fstype) { loff_t size; @@ -652,8 +747,8 @@ int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return 0; } -int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], - int fstype) +int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], + int fstype) { unsigned long addr; const char *addr_str; @@ -670,17 +765,19 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], if (argc > 7) return CMD_RET_USAGE; - if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype)) + if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype)) { + log_err("Can't set block device\n"); return 1; + } if (argc >= 4) { - addr = simple_strtoul(argv[3], &ep, 16); + addr = hextoul(argv[3], &ep); if (ep == argv[3] || *ep != '\0') return CMD_RET_USAGE; } else { addr_str = env_get("loadaddr"); if (addr_str != NULL) - addr = simple_strtoul(addr_str, NULL, 16); + addr = hextoul(addr_str, NULL); else addr = CONFIG_SYS_LOAD_ADDR; } @@ -694,23 +791,26 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], } } if (argc >= 6) - bytes = simple_strtoul(argv[5], NULL, 16); + bytes = hextoul(argv[5], NULL); else bytes = 0; if (argc >= 7) - pos = simple_strtoul(argv[6], NULL, 16); + pos = hextoul(argv[6], NULL); else pos = 0; -#ifdef CONFIG_CMD_BOOTEFI - efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "", - (argc > 4) ? argv[4] : ""); -#endif time = get_timer(0); ret = _fs_read(filename, addr, pos, bytes, 1, &len_read); time = get_timer(time); - if (ret < 0) + if (ret < 0) { + log_err("Failed to load '%s'\n", filename); return 1; + } + + if (IS_ENABLED(CONFIG_CMD_BOOTEFI)) + efi_set_bootdev(argv[1], (argc > 2) ? argv[2] : "", + (argc > 4) ? argv[4] : "", map_sysmem(addr, 0), + len_read); printf("%llu bytes read in %lu ms", len_read, time); if (time > 0) { @@ -726,8 +826,8 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return 0; } -int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], - int fstype) +int do_ls(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], + int fstype) { if (argc < 2) return CMD_RET_USAGE; @@ -752,8 +852,8 @@ int file_exists(const char *dev_type, const char *dev_part, const char *file, return fs_exists(file); } -int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], - int fstype) +int do_save(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], + int fstype) { unsigned long addr; const char *filename; @@ -769,11 +869,11 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], if (fs_set_blk_dev(argv[1], argv[2], fstype)) return 1; - addr = simple_strtoul(argv[3], NULL, 16); + addr = hextoul(argv[3], NULL); filename = argv[4]; - bytes = simple_strtoul(argv[5], NULL, 16); + bytes = hextoul(argv[5], NULL); if (argc >= 7) - pos = simple_strtoul(argv[6], NULL, 16); + pos = hextoul(argv[6], NULL); else pos = 0; @@ -794,8 +894,8 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return 0; } -int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], - int fstype) +int do_fs_uuid(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], + int fstype) { int ret; char uuid[37]; @@ -819,7 +919,7 @@ int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return CMD_RET_SUCCESS; } -int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int do_fs_type(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct fstype_info *info; @@ -841,7 +941,7 @@ int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_SUCCESS; } -int do_rm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], +int do_rm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int fstype) { if (argc != 4) @@ -856,7 +956,7 @@ int do_rm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return 0; } -int do_mkdir(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], +int do_mkdir(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int fstype) { int ret; @@ -869,14 +969,14 @@ int do_mkdir(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], ret = fs_mkdir(argv[3]); if (ret) { - printf("** Unable to create a directory \"%s\" **\n", argv[3]); + log_err("** Unable to create a directory \"%s\" **\n", argv[3]); return 1; } return 0; } -int do_ln(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], +int do_ln(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int fstype) { if (argc != 5) @@ -890,3 +990,79 @@ int do_ln(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], return 0; } + +int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + struct fstype_info *drv = fstypes; + const int n_ents = ARRAY_SIZE(fstypes); + struct fstype_info *entry; + int i = 0; + + puts("Supported filesystems"); + for (entry = drv; entry != drv + n_ents; entry++) { + if (entry->fstype != FS_TYPE_ANY) { + printf("%c %s", i ? ',' : ':', entry->name); + i++; + } + } + if (!i) + puts(": "); + puts("\n"); + return CMD_RET_SUCCESS; +} + +int fs_read_alloc(const char *fname, ulong size, uint align, void **bufp) +{ + loff_t bytes_read; + ulong addr; + char *buf; + int ret; + + buf = memalign(align, size + 1); + if (!buf) + return log_msg_ret("buf", -ENOMEM); + addr = map_to_sysmem(buf); + + ret = fs_read(fname, addr, 0, size, &bytes_read); + if (ret) { + free(buf); + return log_msg_ret("read", ret); + } + if (size != bytes_read) + return log_msg_ret("bread", -EIO); + buf[size] = '\0'; + + *bufp = buf; + + return 0; +} + +int fs_load_alloc(const char *ifname, const char *dev_part_str, + const char *fname, ulong max_size, ulong align, void **bufp, + ulong *sizep) +{ + loff_t size; + void *buf; + int ret; + + if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY)) + return log_msg_ret("set", -ENOMEDIUM); + + ret = fs_size(fname, &size); + if (ret) + return log_msg_ret("sz", -ENOENT); + + if (size >= (max_size ?: SZ_1G)) + return log_msg_ret("sz", -E2BIG); + + if (fs_set_blk_dev(ifname, dev_part_str, FS_TYPE_ANY)) + return log_msg_ret("set", -ENOMEDIUM); + + ret = fs_read_alloc(fname, size, align, &buf); + if (ret) + return log_msg_ret("al", ret); + *sizep = size; + *bufp = buf; + + return 0; +}