mirror of
https://github.com/Stichting-MINIX-Research-Foundation/u-boot.git
synced 2025-09-08 03:23:32 -04:00
Merge branch 'master' of git://git.denx.de/u-boot-ubi
This commit is contained in:
commit
f61f59da0f
@ -42,6 +42,11 @@ struct selected_dev {
|
|||||||
|
|
||||||
static struct selected_dev ubi_dev;
|
static struct selected_dev ubi_dev;
|
||||||
|
|
||||||
|
#ifdef CONFIG_CMD_UBIFS
|
||||||
|
int ubifs_is_mounted(void);
|
||||||
|
void cmd_ubifs_umount(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void ubi_dump_vol_info(const struct ubi_volume *vol)
|
static void ubi_dump_vol_info(const struct ubi_volume *vol)
|
||||||
{
|
{
|
||||||
ubi_msg("volume information dump:");
|
ubi_msg("volume information dump:");
|
||||||
@ -472,6 +477,16 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
return cmd_usage(cmdtp);
|
return cmd_usage(cmdtp);
|
||||||
|
|
||||||
|
#ifdef CONFIG_CMD_UBIFS
|
||||||
|
/*
|
||||||
|
* Automatically unmount UBIFS partition when user
|
||||||
|
* changes the UBI device. Otherwise the following
|
||||||
|
* UBIFS commands will crash.
|
||||||
|
*/
|
||||||
|
if (ubifs_is_mounted())
|
||||||
|
cmd_ubifs_umount();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* todo: get dev number for NAND... */
|
/* todo: get dev number for NAND... */
|
||||||
ubi_dev.nr = 0;
|
ubi_dev.nr = 0;
|
||||||
|
|
||||||
|
@ -33,12 +33,17 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
|
|
||||||
|
#include "../fs/ubifs/ubifs.h"
|
||||||
|
|
||||||
static int ubifs_initialized;
|
static int ubifs_initialized;
|
||||||
static int ubifs_mounted;
|
static int ubifs_mounted;
|
||||||
|
|
||||||
|
extern struct super_block *ubifs_sb;
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
int ubifs_init(void);
|
int ubifs_init(void);
|
||||||
int ubifs_mount(char *vol_name);
|
int ubifs_mount(char *vol_name);
|
||||||
|
void ubifs_umount(struct ubifs_info *c);
|
||||||
int ubifs_ls(char *dir_name);
|
int ubifs_ls(char *dir_name);
|
||||||
int ubifs_load(char *filename, u32 addr, u32 size);
|
int ubifs_load(char *filename, u32 addr, u32 size);
|
||||||
|
|
||||||
@ -67,13 +72,47 @@ int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ubifs_is_mounted(void)
|
||||||
|
{
|
||||||
|
return ubifs_mounted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_ubifs_umount(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ubifs_sb) {
|
||||||
|
printf("Unmounting UBIFS volume %s!\n",
|
||||||
|
((struct ubifs_info *)(ubifs_sb->s_fs_info))->vi.name);
|
||||||
|
ubifs_umount(ubifs_sb->s_fs_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
ubifs_sb = NULL;
|
||||||
|
ubifs_mounted = 0;
|
||||||
|
ubifs_initialized = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_ubifs_umount(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
|
{
|
||||||
|
if (argc != 1)
|
||||||
|
return cmd_usage(cmdtp);
|
||||||
|
|
||||||
|
if (ubifs_initialized == 0) {
|
||||||
|
printf("No UBIFS volume mounted!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_ubifs_umount();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
char *filename = "/";
|
char *filename = "/";
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!ubifs_mounted) {
|
if (!ubifs_mounted) {
|
||||||
printf("UBIFS not mounted, use ubifs mount to mount volume first!\n");
|
printf("UBIFS not mounted, use ubifsmount to mount volume first!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +170,12 @@ U_BOOT_CMD(
|
|||||||
" - mount 'volume-name' volume"
|
" - mount 'volume-name' volume"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
U_BOOT_CMD(
|
||||||
|
ubifsumount, 1, 0, do_ubifs_umount,
|
||||||
|
"unmount UBIFS volume",
|
||||||
|
" - unmount current volume"
|
||||||
|
);
|
||||||
|
|
||||||
U_BOOT_CMD(
|
U_BOOT_CMD(
|
||||||
ubifsls, 2, 0, do_ubifs_ls,
|
ubifsls, 2, 0, do_ubifs_ls,
|
||||||
"list files in a directory",
|
"list files in a directory",
|
||||||
|
@ -824,7 +824,7 @@ out_free:
|
|||||||
* through mounting (error path cleanup function). So it has to make sure the
|
* through mounting (error path cleanup function). So it has to make sure the
|
||||||
* resource was actually allocated before freeing it.
|
* resource was actually allocated before freeing it.
|
||||||
*/
|
*/
|
||||||
static void ubifs_umount(struct ubifs_info *c)
|
void ubifs_umount(struct ubifs_info *c)
|
||||||
{
|
{
|
||||||
dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num,
|
dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num,
|
||||||
c->vi.vol_id);
|
c->vi.vol_id);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2006-2008 Nokia Corporation.
|
* Copyright (C) 2006-2008 Nokia Corporation.
|
||||||
*
|
*
|
||||||
* (C) Copyright 2008-2009
|
* (C) Copyright 2008-2010
|
||||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@ -384,6 +384,7 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
|
|||||||
unsigned long root_inum = 1;
|
unsigned long root_inum = 1;
|
||||||
unsigned long inum;
|
unsigned long inum;
|
||||||
int symlink_count = 0; /* Don't allow symlink recursion */
|
int symlink_count = 0; /* Don't allow symlink recursion */
|
||||||
|
char link_name[64];
|
||||||
|
|
||||||
strcpy(fpath, filename);
|
strcpy(fpath, filename);
|
||||||
|
|
||||||
@ -420,7 +421,6 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
|
|||||||
ui = ubifs_inode(inode);
|
ui = ubifs_inode(inode);
|
||||||
|
|
||||||
if ((inode->i_mode & S_IFMT) == S_IFLNK) {
|
if ((inode->i_mode & S_IFMT) == S_IFLNK) {
|
||||||
char link_name[64];
|
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
/* We have some sort of symlink recursion, bail out */
|
/* We have some sort of symlink recursion, bail out */
|
||||||
@ -567,7 +567,8 @@ dump:
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_readpage(struct ubifs_info *c, struct inode *inode, struct page *page)
|
static int do_readpage(struct ubifs_info *c, struct inode *inode,
|
||||||
|
struct page *page, int last_block_size)
|
||||||
{
|
{
|
||||||
void *addr;
|
void *addr;
|
||||||
int err = 0, i;
|
int err = 0, i;
|
||||||
@ -601,17 +602,54 @@ static int do_readpage(struct ubifs_info *c, struct inode *inode, struct page *p
|
|||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
memset(addr, 0, UBIFS_BLOCK_SIZE);
|
memset(addr, 0, UBIFS_BLOCK_SIZE);
|
||||||
} else {
|
} else {
|
||||||
ret = read_block(inode, addr, block, dn);
|
/*
|
||||||
if (ret) {
|
* Reading last block? Make sure to not write beyond
|
||||||
err = ret;
|
* the requested size in the destination buffer.
|
||||||
if (err != -ENOENT)
|
*/
|
||||||
break;
|
if (((block + 1) == beyond) || last_block_size) {
|
||||||
} else if (block + 1 == beyond) {
|
void *buff;
|
||||||
int dlen = le32_to_cpu(dn->size);
|
int dlen;
|
||||||
int ilen = i_size & (UBIFS_BLOCK_SIZE - 1);
|
|
||||||
|
|
||||||
if (ilen && ilen < dlen)
|
/*
|
||||||
memset(addr + ilen, 0, dlen - ilen);
|
* We need to buffer the data locally for the
|
||||||
|
* last block. This is to not pad the
|
||||||
|
* destination area to a multiple of
|
||||||
|
* UBIFS_BLOCK_SIZE.
|
||||||
|
*/
|
||||||
|
buff = malloc(UBIFS_BLOCK_SIZE);
|
||||||
|
if (!buff) {
|
||||||
|
printf("%s: Error, malloc fails!\n",
|
||||||
|
__func__);
|
||||||
|
err = -ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read block-size into temp buffer */
|
||||||
|
ret = read_block(inode, buff, block, dn);
|
||||||
|
if (ret) {
|
||||||
|
err = ret;
|
||||||
|
if (err != -ENOENT) {
|
||||||
|
free(buff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_block_size)
|
||||||
|
dlen = last_block_size;
|
||||||
|
else
|
||||||
|
dlen = le32_to_cpu(dn->size);
|
||||||
|
|
||||||
|
/* Now copy required size back to dest */
|
||||||
|
memcpy(addr, buff, dlen);
|
||||||
|
|
||||||
|
free(buff);
|
||||||
|
} else {
|
||||||
|
ret = read_block(inode, addr, block, dn);
|
||||||
|
if (ret) {
|
||||||
|
err = ret;
|
||||||
|
if (err != -ENOENT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (++i >= UBIFS_BLOCKS_PER_PAGE)
|
if (++i >= UBIFS_BLOCKS_PER_PAGE)
|
||||||
@ -649,6 +687,7 @@ int ubifs_load(char *filename, u32 addr, u32 size)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
int i;
|
int i;
|
||||||
int count;
|
int count;
|
||||||
|
int last_block_size = 0;
|
||||||
|
|
||||||
c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
|
c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY);
|
||||||
/* ubifs_findfile will resolve symlinks, so we know that we get
|
/* ubifs_findfile will resolve symlinks, so we know that we get
|
||||||
@ -684,7 +723,13 @@ int ubifs_load(char *filename, u32 addr, u32 size)
|
|||||||
page.index = 0;
|
page.index = 0;
|
||||||
page.inode = inode;
|
page.inode = inode;
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
err = do_readpage(c, inode, &page);
|
/*
|
||||||
|
* Make sure to not read beyond the requested size
|
||||||
|
*/
|
||||||
|
if (((i + 1) == count) && (size < inode->i_size))
|
||||||
|
last_block_size = size - (i * PAGE_SIZE);
|
||||||
|
|
||||||
|
err = do_readpage(c, inode, &page, last_block_size);
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user