Init implementation of IsoFileSrc.

Ecma119Image, defined for first time in this commit, is the context for image 
written. It keeps the low level objects needed during image written.

IsoFileSrc is the low level object that takes care about the info needed to
write file contents to image. It takes care about reading from Stream in 2K
block chunks. To prevent the same file be written twice to image, we keep in
Ecma119Image a search tree, indexed by the triple key (fs, device, inode) that
uniquelly identifies a source.
This commit is contained in:
Vreixo Formoso 2007-12-15 13:13:49 +01:00
parent dd83f85d09
commit 7b241176fb
6 changed files with 247 additions and 88 deletions

View File

@ -28,7 +28,10 @@ src_libisofs_la_SOURCES = \
src/stream.h \ src/stream.h \
src/stream.c \ src/stream.c \
src/util.h \ src/util.h \
src/util.c src/util.c \
src/filesrc.h \
src/filesrc.c \
src/ecma119.h
libinclude_HEADERS = \ libinclude_HEADERS = \
src/libisofs.h src/libisofs.h

23
src/ecma119.h Normal file
View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2007 Vreixo Formoso
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See COPYING file for details.
*/
#ifndef LIBISO_ECMA119_H_
#define LIBISO_ECMA119_H_
typedef struct ecma119_image Ecma119Image;
struct ecma119_image {
unsigned int iso_level:2;
/* tree of files sources */
void *file_srcs;
int file_count;
};
#endif /*LIBISO_ECMA119_H_*/

101
src/filesrc.c Normal file
View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2007 Vreixo Formoso
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See COPYING file for details.
*/
#include "filesrc.h"
#include "error.h"
#include "node.h"
#include <stdlib.h>
#include <search.h>
static
int comp_iso_file_src(const void *n1, const void *n2)
{
const IsoFileSrc *f1, *f2;
f1 = (const IsoFileSrc *)n1;
f2 = (const IsoFileSrc *)n2;
if (f1->fs_id < f2->fs_id) {
return -1;
} else if (f1->fs_id > f2->fs_id) {
return 1;
} else {
/* files belong to the same fs */
if (f1->dev_id > f2->dev_id) {
return -1;
} else if (f1->dev_id < f2->dev_id) {
return 1;
} else {
/* files belong to same device in same fs */
return f1->ino_id - f2->ino_id;
}
}
}
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
{
int res;
IsoStream *stream;
IsoFileSrc *fsrc;
unsigned int fs_id;
dev_t dev_id;
ino_t ino_id;
off_t size;
if (img == NULL || file == NULL || src == NULL) {
return ISO_NULL_POINTER;
}
stream = file->stream;
res = stream->get_id(stream, &fs_id, &dev_id, &ino_id);
if (res < 0) {
return res;
} else if (res == 0) {
// TODO this corresponds to Stream that cannot provide a valid id
// Not implemented for now
return ISO_ERROR;
} else {
IsoFileSrc *inserted;
size = stream->get_size(stream);
if (size == (off_t)-1) {
return ISO_FILE_ERROR;
}
fsrc = malloc(sizeof(IsoFileSrc));
if (fsrc == NULL) {
return ISO_MEM_ERROR;
}
/* fill key and other atts */
fsrc->fs_id = fs_id;
fsrc->dev_id = dev_id;
fsrc->ino_id = ino_id;
fsrc->prev_img = file->msblock ? 1 : 0;
fsrc->block = file->msblock;
fsrc->size = size;
fsrc->sort_weight = file->sort_weight;
fsrc->stream = file->stream;
/* insert the filesrc in the tree */
inserted = tsearch(fsrc, img->file_srcs, comp_iso_file_src);
if (inserted == NULL) {
free(fsrc);
return ISO_MEM_ERROR;
} else if (inserted == fsrc) {
/* the file was inserted */
img->file_count++;
} else {
/* the file was already on the tree */
free(fsrc);
}
*src = inserted;
}
return ISO_SUCCESS;
}

View File

@ -8,93 +8,87 @@
#ifndef LIBISO_FILESRC_H_ #ifndef LIBISO_FILESRC_H_
#define LIBISO_FILESRC_H_ #define LIBISO_FILESRC_H_
/* #include "libisofs.h"
* FIXME definitions here shouldn't be used for now!!! #include "stream.h"
#include "ecma119.h"
#include <stdint.h>
typedef struct Iso_File_Src IsoFileSrc;
struct Iso_File_Src {
/* key */
unsigned int fs_id;
dev_t dev_id;
ino_t ino_id;
unsigned int prev_img:1; /**< if the file comes from a previous image */
off_t size; /**< size of this file */
uint32_t block; /**< Block where this file will be written on image */
int sort_weight;
IsoStream *stream;
};
/**
* Create a new IsoFileSrc to get data from a specific IsoFile.
* *
* The IsoFileSrc will be cached in a tree to prevent the same file for
* being written several times to image. If you call again this function
* with a node that refers to the same source file, the previously
* created one will be returned. No new IsoFileSrc is created in that case.
*
* @param img
* The image where this file is to be written
* @param file
* The IsoNode we want to write
* @param src
* Will be filled with a pointer to the IsoFileSrc
* @return
* 1 on success, < 0 on error
*/ */
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src);
// TODO not implemented
int iso_file_src_open(IsoFileSrc *file);
/* // TODO not implemented
* Definitions of streams. int iso_file_src_close(IsoFileSrc *file);
/**
* TODO define propertly this comment
* TODO not implemented
*
* Read a block (2048 bytes) from the IsoFileSrc.
*
* This function should always read the full 2048 bytes, blocking if
* needed. When it reaches EOF, the buf is filled with 0's, if needed.
* Note that the EOF is not reported in that call, but in the next call.
* I.e., when the EOF is reported you can be sure that the function
* has not written anything to the buffer. If the file size is a multiple
* of block size, i.e N*2048, the read_block reports the EOF just when
* reading the N+1 block.
*
* Note that EOF refers to the original size as reported by get_size.
* If the underlying source size has changed, this function should take
* care of this, truncating the file, or filling the buffer with 0s. I.e.
* this function return 0 (EOF) only when get_size() bytes have been
* readed.
*
* On an I/O error, or a file smaller than the expected size, this
* function returns a [specific error code], and the buffer is filled
* with 0s. Subsequent calls will still return an error code and fill
* buffer with 0's, until EOF (as defined above) is reached, and then
* the function will return 0.
*
* Note that if the current size is larger than expected, you don't get
* any error on reading.
*
* @param buf
* Buffer where data fill be copied, with at least 2048 bytes.
* @return
* 1 sucess, 0 EOF, < 0 error (buf is filled with 0's)
*/ */
int iso_file_src_read_block(IsoFileSrc *file, void *buf);
/*
* Some functions here will be moved to libisofs.h when we expose
* Streams.
*/
//typedef struct Iso_Stream IsoStream;
//
//struct Iso_Stream
//{
// /**
// * Opens the stream.
// *
// * @return
// * 1 on success, < 0 on error, 2 file is smaller than expect,
// * 3 file is larger than expected (2 and 3 are not errors, they're
// * handled by read_block, see there. Moreover, IsooStream
// * implementations doesn't need to check that)
// */
// int (*open)(IsoStream *stream);
//
// /**
// * Close the Stream.
// * @return 1 on success, < 0 on error
// */
// int (*close)(IsoStream *stream);
//
// /**
// * Get the size (in bytes) of the stream. This function must return
// * always the same size, even if the underlying source file has changed.
// */
// off_t (*get_size)(IsoStream *stream);
//
// /**
// * Read a block (2048 bytes) from the stream.
// *
// * This function should always read the full 2048 bytes, blocking if
// * needed. When it reaches EOF, the buf is filled with 0's, if needed.
// * Note that the EOF is not reported in that call, but in the next call.
// * I.e., when the EOF is reported you can be sure that the function
// * has not written anything to the buffer. If the file size is a multiple
// * of block size, i.e N*2048, the read_block reports the EOF just when
// * reading the N+1 block.
// *
// * Note that EOF refers to the original size as reported by get_size.
// * If the underlying source size has changed, this function should take
// * care of this, truncating the file, or filling the buffer with 0s. I.e.
// * this function return 0 (EOF) only when get_size() bytes have been
// * readed.
// *
// * On an I/O error, or a file smaller than the expected size, this
// * function returns a [specific error code], and the buffer is filled
// * with 0s. Subsequent calls will still return an error code and fill
// * buffer with 0's, until EOF (as defined above) is reached, and then
// * the function will return 0.
// *
// * Note that if the current size is larger than expected, you don't get
// * any error on reading.
// *
// * @param buf
// * Buffer where data fill be copied, with at least 2048 bytes.
// * @return
// * 1 sucess, 0 EOF, < 0 error (buf is filled with 0's)
// */
// int (*read_block)(IsoStream *stream, void *buf);
//
// /**
// * Whether this Stram can be read several times, with the same results.
// * For example, a regular file is repeatable, you can read it as many
// * times as you want. However, a pipe isn't.
// *
// * This function doesn't take into account if the file has been modified
// * between the two reads.
// */
// int (*is_repeatable)(IsoStream *stream);
//
// int refcount;
// void *data;
//}
#endif /*LIBISO_FILESRC_H_*/ #endif /*LIBISO_FILESRC_H_*/

35
src/image_writer.h Normal file
View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2007 Vreixo Formoso
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See COPYING file for details.
*/
#ifndef LIBISO_IMAGE_WRITER_H_
#define LIBISO_IMAGE_WRITER_H_
struct Iso_Writer_State
{
};
struct Iso_Image_Writer
{
//init()
//compute_dir_structure()
//write_vol_desc
//
//free
void *data;
Ecma119Image *image;
};
#endif /*LIBISO_IMAGE_WRITER_H_*/

View File

@ -104,14 +104,17 @@ int fsrc_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
} }
src = (IsoFileSource*)stream->data; src = (IsoFileSource*)stream->data;
fs = src->get_filesystem(src);
*fs_id = fs->get_id(fs);
if (fs_id == 0) {
return 0;
}
result = src->stat(src, &info); result = src->stat(src, &info);
if (result < 0) { if (result < 0) {
return result; return result;
} }
fs = src->get_filesystem(src);
*fs_id = fs->get_id(fs);
*dev_id = info.st_dev; *dev_id = info.st_dev;
*ino_id = info.st_ino; *ino_id = info.st_ino;
return ISO_SUCCESS; return ISO_SUCCESS;