feat: add file to directory
This commit is contained in:
parent
7043ece1c3
commit
806b71237e
|
@ -49,10 +49,7 @@ bget(int fd, uint32_t blocknum)
|
||||||
}
|
}
|
||||||
|
|
||||||
buff = (struct stpdfs_buffer *)malloc(sizeof(struct stpdfs_buffer));
|
buff = (struct stpdfs_buffer *)malloc(sizeof(struct stpdfs_buffer));
|
||||||
if (buff == NULL)
|
if (buff == NULL) return (NULL);
|
||||||
{
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
buff->next = head;
|
buff->next = head;
|
||||||
buff->blocknum = blocknum;
|
buff->blocknum = blocknum;
|
||||||
|
@ -113,8 +110,9 @@ stpdfs_brelse(struct stpdfs_buffer *buff)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(buff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -30,7 +30,13 @@ stpdfs_file_close(struct stpdfs_file *f)
|
||||||
struct stpdfs_file *tmp;
|
struct stpdfs_file *tmp;
|
||||||
|
|
||||||
f->refcount--;
|
f->refcount--;
|
||||||
if (f->refcount <= 0)
|
if (f->refcount > 0) return;
|
||||||
|
|
||||||
|
if (f == head)
|
||||||
|
{
|
||||||
|
head = f->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
for (tmp = head; tmp != NULL; tmp = tmp->next)
|
for (tmp = head; tmp != NULL; tmp = tmp->next)
|
||||||
{
|
{
|
||||||
|
@ -40,6 +46,7 @@ stpdfs_file_close(struct stpdfs_file *f)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(f);
|
free(f);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "stpdfs.h"
|
|
||||||
#include "stupidfs.h"
|
#include "stupidfs.h"
|
||||||
|
#include <stdlib.h>
|
||||||
#include <libstpdfs/stpdfs.h>
|
#include <libstpdfs/stpdfs.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -10,44 +10,39 @@
|
||||||
#define INODE_CACHE 50
|
#define INODE_CACHE 50
|
||||||
#define IBLOCK(x) (x / STPDFS_INODES_PER_BLOCK + 2)
|
#define IBLOCK(x) (x / STPDFS_INODES_PER_BLOCK + 2)
|
||||||
|
|
||||||
static struct stpdfs_inode_info icache[INODE_CACHE] = {0};
|
static struct stpdfs_inode_info *head;
|
||||||
|
|
||||||
struct stpdfs_inode_info *
|
struct stpdfs_inode_info *
|
||||||
stpdfs_inode_get(struct stpdfs_super_info *sbi, uint32_t inum)
|
stpdfs_inode_get(struct stpdfs_super_info *sbi, uint32_t inum)
|
||||||
{
|
{
|
||||||
struct stpdfs_inode_info *empty;
|
struct stpdfs_inode_info *ip;
|
||||||
struct stpdfs_buffer *buff;
|
struct stpdfs_buffer *buff;
|
||||||
struct stpdfs_inode *dinode;
|
struct stpdfs_inode *dinode;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
empty = NULL;
|
for (ip = head; ip != NULL; ip = ip->next)
|
||||||
for (idx = 0; idx < INODE_CACHE; idx++)
|
|
||||||
{
|
{
|
||||||
if (icache[idx].refcount > 0 && icache[idx].inum == inum)
|
if (ip->inum == inum)
|
||||||
{
|
{
|
||||||
icache[idx].refcount++;
|
ip->refcount++;
|
||||||
return (&icache[idx]);
|
return (ip);
|
||||||
}
|
|
||||||
|
|
||||||
if (empty == NULL && icache[idx].refcount == 0)
|
|
||||||
{
|
|
||||||
empty = &icache[idx];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty == NULL) return (NULL);
|
ip = (struct stpdfs_inode_info *)malloc(sizeof(struct stpdfs_inode_info));
|
||||||
|
if (ip == NULL) return (NULL);
|
||||||
|
|
||||||
empty->sbi = sbi;
|
ip->sbi = sbi;
|
||||||
empty->inum = inum;
|
ip->inum = inum;
|
||||||
empty->refcount = 1;
|
ip->refcount = 1;
|
||||||
|
|
||||||
empty->valid = 1;
|
ip->valid = 1;
|
||||||
buff = stpdfs_bread(sbi->fd, IBLOCK(inum));
|
buff = stpdfs_bread(sbi->fd, IBLOCK(inum));
|
||||||
dinode = (struct stpdfs_inode *)buff->data + inum % STPDFS_INODES_PER_BLOCK;
|
dinode = (struct stpdfs_inode *)buff->data + inum % STPDFS_INODES_PER_BLOCK;
|
||||||
memcpy(&empty->inode, dinode, sizeof(struct stpdfs_inode));
|
memcpy(&ip->inode, dinode, sizeof(struct stpdfs_inode));
|
||||||
stpdfs_brelse(buff);
|
stpdfs_brelse(buff);
|
||||||
|
|
||||||
return (empty);
|
return (ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stpdfs_inode_info *
|
struct stpdfs_inode_info *
|
||||||
|
@ -63,6 +58,7 @@ stpdfs_inode_alloc(struct stpdfs_super_info *sbi)
|
||||||
dinode = (struct stpdfs_inode *)buff->data + inum % STPDFS_INODES_PER_BLOCK;
|
dinode = (struct stpdfs_inode *)buff->data + inum % STPDFS_INODES_PER_BLOCK;
|
||||||
if ((dinode->flags & STPDFS_INO_FLAG_ALOC) == 0)
|
if ((dinode->flags & STPDFS_INO_FLAG_ALOC) == 0)
|
||||||
{
|
{
|
||||||
|
memset(dinode, 0, sizeof(struct stpdfs_inode));
|
||||||
dinode->flags = STPDFS_INO_FLAG_ALOC;
|
dinode->flags = STPDFS_INO_FLAG_ALOC;
|
||||||
stpdfs_bwrite(buff);
|
stpdfs_bwrite(buff);
|
||||||
stpdfs_brelse(buff);
|
stpdfs_brelse(buff);
|
||||||
|
@ -89,8 +85,8 @@ stpdfs_inode_update(struct stpdfs_inode_info *ip)
|
||||||
stpdfs_brelse(buff);
|
stpdfs_brelse(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
stpdfs_inode_bmap(struct stpdfs_inode_info *ip, uint32_t blocknum)
|
bmap(struct stpdfs_inode_info *ip, uint32_t blocknum)
|
||||||
{
|
{
|
||||||
uint32_t *addrs;
|
uint32_t *addrs;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
|
@ -127,12 +123,6 @@ stpdfs_inode_bmap(struct stpdfs_inode_info *ip, uint32_t blocknum)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
stpdfs_inode_trunc(struct stpdfs_inode_info *ip)
|
|
||||||
{
|
|
||||||
(void)ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
stpdfs_inode_read(struct stpdfs_inode_info *ip, uint8_t *dest, size_t offset, size_t size)
|
stpdfs_inode_read(struct stpdfs_inode_info *ip, uint8_t *dest, size_t offset, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -149,7 +139,7 @@ stpdfs_inode_read(struct stpdfs_inode_info *ip, uint8_t *dest, size_t offset, si
|
||||||
total = 0;
|
total = 0;
|
||||||
while (total < size)
|
while (total < size)
|
||||||
{
|
{
|
||||||
zone = stpdfs_inode_bmap(ip, offset/STPDFS_BLOCK_SIZE);
|
zone = bmap(ip, offset/STPDFS_BLOCK_SIZE);
|
||||||
if (zone == 0) return (total);
|
if (zone == 0) return (total);
|
||||||
|
|
||||||
buff = stpdfs_bread(ip->sbi->fd, zone);
|
buff = stpdfs_bread(ip->sbi->fd, zone);
|
||||||
|
@ -182,7 +172,7 @@ stpdfs_inode_write(struct stpdfs_inode_info *ip, const uint8_t *src, size_t offs
|
||||||
total = 0;
|
total = 0;
|
||||||
while (total < size)
|
while (total < size)
|
||||||
{
|
{
|
||||||
zone = stpdfs_inode_bmap(ip, offset/STPDFS_BLOCK_SIZE);
|
zone = bmap(ip, offset/STPDFS_BLOCK_SIZE);
|
||||||
if (zone == 0) break;
|
if (zone == 0) break;
|
||||||
|
|
||||||
buff = stpdfs_bread(ip->sbi->fd, zone);
|
buff = stpdfs_bread(ip->sbi->fd, zone);
|
||||||
|
@ -227,7 +217,7 @@ stpdfs_dirlookup(struct stpdfs_inode_info *dp, const char *name, size_t *offset)
|
||||||
|
|
||||||
if (strncmp(name, dirent.filename, STPDFS_NAME_MAX))
|
if (strncmp(name, dirent.filename, STPDFS_NAME_MAX))
|
||||||
{
|
{
|
||||||
*offset = idx;
|
if (offset) *offset = idx;
|
||||||
return (stpdfs_inode_get(dp->sbi, dirent.inode));
|
return (stpdfs_inode_get(dp->sbi, dirent.inode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +228,24 @@ stpdfs_dirlookup(struct stpdfs_inode_info *dp, const char *name, size_t *offset)
|
||||||
int
|
int
|
||||||
stpdfs_dirlink(struct stpdfs_inode_info *dp, const char *name, uint32_t inum)
|
stpdfs_dirlink(struct stpdfs_inode_info *dp, const char *name, uint32_t inum)
|
||||||
{
|
{
|
||||||
|
struct stpdfs_inode_info *ip;
|
||||||
|
|
||||||
|
ip = stpdfs_dirlookup(dp, name, 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
stpdfs_create(struct stpdfs_inode_info *dp, struct stpdfs_dirent *dirent, uint16_t mode)
|
||||||
|
{
|
||||||
|
struct stpdfs_inode_info *ip;
|
||||||
|
struct stpdfs_buffer *buff;
|
||||||
|
uint32_t blocknum;
|
||||||
|
|
||||||
|
ip = stpdfs_inode_alloc(dp->sbi);
|
||||||
|
ip->inode.mode = mode;
|
||||||
|
dirent->inode = ip->inum;
|
||||||
|
stpdfs_inode_write(dp, (uint8_t *)dirent, dp->inode.size, STPDFS_DIRENT_SIZE);
|
||||||
|
stpdfs_inode_update(ip);
|
||||||
|
stpdfs_inode_update(dp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ struct stpdfs_inode_info {
|
||||||
struct stpdfs_super_info *sbi;
|
struct stpdfs_super_info *sbi;
|
||||||
|
|
||||||
struct stpdfs_inode inode;
|
struct stpdfs_inode inode;
|
||||||
|
|
||||||
|
struct stpdfs_inode_info *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stpdfs_file {
|
struct stpdfs_file {
|
||||||
|
@ -61,5 +63,5 @@ int stpdfs_free_block(int fd, struct stpdfs_sb *sb, uint32_t blocknum);
|
||||||
|
|
||||||
struct stpdfs_inode_info *stpdfs_inode_get(struct stpdfs_super_info *sbi, uint32_t inum);
|
struct stpdfs_inode_info *stpdfs_inode_get(struct stpdfs_super_info *sbi, uint32_t inum);
|
||||||
int stpdfs_inode_read(struct stpdfs_inode_info *ip, uint8_t *dest, size_t offset, size_t size);
|
int stpdfs_inode_read(struct stpdfs_inode_info *ip, uint8_t *dest, size_t offset, size_t size);
|
||||||
|
int stpdfs_create(struct stpdfs_inode_info *dp, struct stpdfs_dirent *dirent, uint16_t mode);
|
||||||
#endif /* !STPDFS_H */
|
#endif /* !STPDFS_H */
|
|
@ -1,5 +1,7 @@
|
||||||
|
#include "stupidfs.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
@ -9,16 +11,110 @@
|
||||||
#ifdef HAVE_GETOPT_H
|
#ifdef HAVE_GETOPT_H
|
||||||
# include <getopt.h>
|
# include <getopt.h>
|
||||||
#endif /* HAVE_GETOPT_H */
|
#endif /* HAVE_GETOPT_H */
|
||||||
|
#include <libstpdfs/stpdfs.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_OPTION
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"image", required_argument, 0, 'i'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
#endif /* HAVE_STRUCT_OPTION */
|
||||||
|
|
||||||
|
static char *dest = NULL;
|
||||||
|
static char *src = NULL;
|
||||||
|
static char *image = NULL;
|
||||||
|
|
||||||
|
extern char *prg_name;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(int retval)
|
||||||
{
|
{
|
||||||
|
if (retval == EXIT_FAILURE)
|
||||||
|
{
|
||||||
|
printf("Try '%s copy -h' for more informations.\n", prg_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Usage: %s copy -i /dev/name source [dest]\n", prg_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
do_copy(void)
|
||||||
|
{
|
||||||
|
struct stpdfs_super_info sbi;
|
||||||
|
struct stpdfs_inode_info *ip;
|
||||||
|
struct stpdfs_dirent dirent;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
stat(src, &st);
|
||||||
|
strcpy(dirent.filename, dest);
|
||||||
|
if (stpdfs_super_open(&sbi, image))
|
||||||
|
{
|
||||||
|
return (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = stpdfs_inode_get(&sbi, STPDFS_ROOTINO);
|
||||||
|
|
||||||
|
stpdfs_create(ip, &dirent, st.st_mode);
|
||||||
|
|
||||||
|
stpdfs_super_kill(&sbi);
|
||||||
|
|
||||||
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
copy(int argc, char **argv)
|
copy(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int idx;
|
||||||
|
int c;
|
||||||
|
|
||||||
return (EXIT_SUCCESS);
|
#if defined(HAVE_GETOPT_LONG) && defined(HAVE_STRUCT_OPTION)
|
||||||
|
while ((c = getopt_long(argc, argv, "hi:", long_options, &idx)) != EOF)
|
||||||
|
#else
|
||||||
|
while ((c = getopt(argc, argv, "hi:")) != EOF)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
usage(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
image = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image == NULL)
|
||||||
|
{
|
||||||
|
return (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind < argc)
|
||||||
|
{
|
||||||
|
src = argv[optind++];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usage(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind < argc)
|
||||||
|
{
|
||||||
|
dest = argv[optind];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest == NULL)
|
||||||
|
{
|
||||||
|
dest = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (do_copy());
|
||||||
}
|
}
|
|
@ -24,10 +24,21 @@ static struct option long_options[] = {
|
||||||
static char *path = "/";
|
static char *path = "/";
|
||||||
static char *image = NULL;
|
static char *image = NULL;
|
||||||
|
|
||||||
|
extern char *prg_name;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(int retval)
|
usage(int retval)
|
||||||
{
|
{
|
||||||
|
if (retval == EXIT_FAILURE)
|
||||||
|
{
|
||||||
|
printf("Try '%s ls -h' for more informations.\n", prg_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Usage: %s copy -i /dev/name [path]\n", prg_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct command commands[] = {
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *prg_name;
|
const char *prg_name;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(int retval)
|
usage(int retval)
|
||||||
|
|
Loading…
Reference in a new issue