|
From: Vasanth R. <rag...@gm...> - 2011-05-09 15:10:43
|
Hello Ravi,
I am resending the code at your request :
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
#include <fcntl.h>
#include<fuse.h>
#define BLOCK_SIZE 32767
#define MAX 32000
#ifdef linux
/* For pread()/pwrite() */
#define _XOPEN_SOURCE 500
#endif
typedef struct node {
char *entry_name;
struct stat entry_stat;
off_t entry_start;
int num_children;
struct node **children;
} mynode;
mynode *root=NULL;
int file_names_index;
struct stat entry_stat_array[MAX];
int stat_index=0;
char root_name[MAX][FILENAME_MAX];
int fd_tree;
struct stat stat_entry;
int save_children_entry(mynode *node, const char *entry,int fd) {
int num_children;
int i;
int path_len;
int rc;
char temp[FILENAME_MAX];
strcpy(temp,"./");
strcat(temp,entry);
file_names_index = 0 ;
memset(root_name,0,sizeof(root_name));
//char file_names[MAX][FILENAME_MAX];
if(!node)return 1;
//Check for name match
if (!strcmp(temp,node->entry_name)) {
//check for file
if(S_ISREG(node->entry_stat.st_mode)) {
printf("Entry is a file\n");
return 2;
}
path_len=strlen(node->entry_name);
num_children = node->num_children;
for(i=0;i<num_children;i++)
{
strcpy(root_name[i],node->children[i]->entry_name+path_len+1);
file_names_index ++;
entry_stat_array[i]=node->children[i]->entry_stat;
stat_index ++;
//array++;
}
return 0;
}
//Check children
for (i=1;i<node->num_children+1;++i)
{
rc = save_children_entry(node->children[i-1],entry,fd);
if((2 == rc) || (0 == rc)) return rc;
}
return 1;
}
int return_stat_entry(mynode *node, const char *entry,int fd) {
int num_children;
int i;
int path_len;
int rc;
char *temp = (char *)malloc(sizeof(char) * strlen(entry) + 3);
if(!node)return 1;
memset(&stat_entry,0,sizeof(stat_entry));
strcpy(temp,"./");
strcat(temp,entry);
printf("temp path is %s\n",temp);
//Check for name match
if (strcmp(temp,node->entry_name) == 0) {
stat_entry = node->entry_stat;
return 0;
}
//Check children
for (i = 0; i<node->num_children; i++)
// for (i=1;i<node->num_children+1;++i)
{
rc = return_stat_entry(node->children[i], entry, fd);
if (0 == rc)
return rc;
}
return 1;
}
int return_file_type(mynode *node, const char *entry) {
int num_children;
int i;
int path_len;
int rc;
// memset(&stat_entry,0,sizeof(stat_entry));
if(!node)return -1;
//Check for name match
if (!strcmp(entry,node->entry_name)) {
//check for file
if(S_ISREG(node->entry_stat.st_mode)) {
// printf("Entry is a file\n");
return 0;
}
else if(S_ISDIR(node->entry_stat.st_mode)) {
return 1;
}
}
//Check children
for (i=1;i<node->num_children+1;++i)
{
rc = return_file_type(node->children[i-1],entry);
if((1 == rc) || (0 == rc)) return rc;
}
return -1;
}
int return_file_size(mynode *node, const char *entry) {
int num_children;
int i;
size_t rc;
// memset(&stat_entry,0,sizeof(stat_entry));
if(!node)return -1;
//Check for name match
if (!strcmp(entry,node->entry_name)) {
return (node->entry_stat.st_size);
}
//Check children
for (i=1;i<node->num_children+1;++i)
{
rc = return_file_size(node->children[i-1],entry);
if(-1 != rc) return rc;
}
return -1;
}
//preorder traversal of tree
int print_entry(mynode *node, const char *entry,int fd,int temp_fd) {
int i;
int rc;
char buffer[BLOCK_SIZE];
off_t tot_read,num_read,num_written;
off_t block_size;
if(!node) return 1;
printf("entering the print entry function..........\n");
printf("temp passed to print_entry is %s\n",entry);
//Check for name match
if (!strcmp(entry,node->entry_name)) {
//Check if dir
if(S_ISDIR(node->entry_stat.st_mode)) {
printf("Entry is a directory\n");
return 2; }
block_size = BLOCK_SIZE;
if(block_size > node->entry_stat.st_size)
block_size = node->entry_stat.st_size;
//Print contents
rc = lseek(fd,node->entry_start,SEEK_SET);
if(-1 == rc) {
printf("Error %d seeking to start of data\n",errno);
exit(1);
}
tot_read = 0;
do {
num_read = 0;
do {
rc = read(fd,buffer+num_read,block_size -
num_read);
//Eof
if(!rc) break;
if(-1 == rc) {
printf("Error %d reading
file",errno);
exit(1);
}
num_read += rc;
} while (num_read < block_size);
num_written = 0;
do {
printf("writing into temp fd\n");
rc =
write(temp_fd,buffer+num_written,num_read - num_written);
if(-1 == rc) {
printf("Error %d printing
output",errno);
exit(1); }
num_written += rc;
} while (num_written < num_read);
tot_read += num_read;
} while (tot_read < node->entry_stat.st_size);
return 0;
}
//Check children
for (i=1;i<node->num_children+1;++i)
{
rc = print_entry(node->children[i-1],entry,fd,temp_fd);
printf("returning from print_entry..");
if((2 == rc) || (0 == rc)) return rc;
}
return 1;
}
mynode *create_tree(off_t off, int fd)
{
char *buf;
char *node_buf;
char len_buf[2];
short size,name_len;
short num_children;
int i;
int rc;
mynode *node;
int num_read;
//Allocate node
node = (struct node *) malloc (sizeof (struct node));
/* Data format
1) node size - 2 bytes
2) entry name length - 2 bytes
3) entry name - no of bytes given by previous field
4) entry stat - sizeof(struct stat) bytes
5) entry start - sizeof(off_t) bytes
6) int num children - 2 bytes (this has limit of about 32000 but
that should be ok)
*/
//Seek to offset
rc = lseek(fd,off,SEEK_SET);
//read node size
num_read = 0;
do {
rc = read(fd,len_buf + num_read,sizeof(short) - num_read);
if(!rc) {
printf("EOF reached while reading node size\n");
exit(1);
}
if(-1 == rc) {
printf("Error %d reading node size\n",errno);
exit(1);
}
num_read += rc;
} while (num_read < sizeof(short));
memcpy(&size,len_buf,sizeof(short));
if(size <=0) {
printf("Invalid size %d\n",size);
exit(1);
}
//allocate node buffer
node_buf = (char *) malloc(size);
num_read = 0;
//read node
do {
rc = read(fd,node_buf + num_read,size - num_read);
if(!rc) {
printf("EOF reached while reading node\n");
exit(1);
}
if(-1 == rc) {
printf("Error %d reading node\n",errno);
exit(1);
}
num_read += rc;
} while (num_read < size);
buf = node_buf;
//entry name length
memcpy(&name_len,buf,sizeof(short));
if(name_len <= 0) {
printf("Invalid name len %d\n",size);
exit(1);
}
buf += sizeof(short);
//entry name
node->entry_name = malloc(name_len+1);
memcpy(node->entry_name,buf,name_len);
node->entry_name[name_len] = 0;
buf += name_len;
//etnry attr
memcpy(&node->entry_stat,buf,sizeof(struct stat));
buf += sizeof(struct stat);
//start offset
memcpy(&node->entry_start,buf,sizeof(off_t));
buf += sizeof(off_t);
//Num children
memcpy(&num_children,buf,sizeof(short));
if(num_children < 0) {
printf("Invalid name len %d\n",size);
exit(1);
}
buf += sizeof(short);
node->num_children = num_children;
//Allocate child pointers
node->children = (mynode **)malloc(sizeof(mynode *) * num_children);
//Allocate children
for(i = 1; i< num_children + 1;i++)
{
memcpy(&off,buf,sizeof(off_t));
node->children[i-1] = create_tree(off,fd);
buf += sizeof(off_t);
}
free(node_buf);
return node;
}
static int mytar_getattr(const char *path,struct stat *stbuf)
{
int file_type ;
char temp[FILENAME_MAX];
strcpy(temp,".");
memset(stbuf, 0, sizeof(struct stat));
if ((strcmp(path,"/")) == 0)
{
file_type = 1;
}
else {
strcat(temp,path);
puts(temp);
file_type = return_file_type(root,temp);
if(file_type == -1) { printf("I told you so !\n");}
}
if(file_type == 1)
{
stbuf->st_uid = getuid();
stbuf->st_gid = getgid();
stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL);
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
stbuf->st_dev=0;
}
else if (file_type == 0)
{
stbuf->st_uid = getuid();
stbuf->st_gid = getgid();
stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL);
stbuf->st_mode = S_IFREG | 0755;
stbuf->st_nlink = 2;
stbuf->st_dev=0;
}
else {
printf("file type erroring out....\n");
stbuf->st_uid = getuid();
stbuf->st_gid = getgid();
stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL);
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
stbuf->st_dev=0;
}
return 0;
}
static int mytar_readdir(const char *path, void *buf, fuse_fill_dir_t
filler,
off_t offset, struct fuse_file_info *fi)
{
char root_entry[FILENAME_MAX];
char temp_entry[FILENAME_MAX];
strcpy(temp_entry,"/");
strcat(temp_entry,root->entry_name+2);
if ((strcmp(path,"/")) == 0)
{
filler(buf,root->entry_name +2 ,NULL,0);
}
else {
//strcpy(root_entry,root->entry_name+2);
//printf("root name is %s..............\n",root->entry_name);
//if((strcmp(root_entry,root->entry_name+2)) != 0)
//strcpy(root_entry,root->entry_name+2);
//if((strcmp(path,temp_entry)) != 0)
strcpy(root_entry,path+1);
int i,rc;
printf("root entry is %s!!!!!!!\n",root_entry);
rc = save_children_entry(root,root_entry,fd_tree);
if(rc)
printf("Entry not found\n");
else {
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
for(i=0; i<file_names_index; i++)
{
puts(path);
// printf("rootname is %s ",root_name[i]);
filler(buf,root_name[i],&entry_stat_array[i], 0);
//filler(buf,root_name[i],NULL, 0);
}
} }
//if((strcmp(path,"/")) == 0)
//{
// char root_entry[FILENAME_MAX];
// strcpy(root_entry,root->entry_name);
// filler(buf,root->entry_name,NULL,0);
//}
return 0;
}
static int mytar_read(const char *path, char *read_buf, size_t size, off_t
offset,
struct fuse_file_info *fi)
{
char temp[FILENAME_MAX];
strcpy(temp,".");
strcat(temp,path);
puts(path);
char *temp_buf;
int temp_fd,rc,res;
size_t temp_size;
printf("in mytar_read before open..............\n");
temp_fd = open("temp_file",O_RDWR|O_CREAT,0777);
if(-1 == temp_fd) {
printf("Error %d opening file\n",errno);
exit(1); }
printf("in mytar_read after open..............\n");
temp_size = return_file_size(root,temp);
if(-1 == temp_size)
printf("error returning file size in read...\n");
temp_buf =(char *) malloc(temp_size);
printf("allocating buffer and calling print entry..\n");
rc = print_entry(root,temp,fd_tree,temp_fd);
if(1 == rc)
printf("error in reading in mytar_read\n");
else if (2 == rc)
printf("argument specified is a directory in mytar_read \n");
printf("Returned from print_entry in mytar read .........\n");
res = pread(temp_fd,temp_buf,temp_size,offset);
printf("value of res is %d\n",res);
if (res == -1)
res = -errno;
close(temp_fd);
memcpy(read_buf,temp_buf,temp_size);
//remove("temp_file");
printf("printing the contents of buf %s\n ",read_buf);
// memcpy(buf,temp_buf, size);
printf("the offset is %jd\n",offset);
printf("the size is %zu\n",size);
printf("temp size is %zu\n",temp_size);
printf("the size of res is %d\n",res);
return temp_size ;
}
static int mytar_open(const char *path, struct fuse_file_info *fi)
{
return 0;
}
static int mytar_access(const char *path, int mask)
{
return 0;
}
static int mytar_release(const char *path, struct fuse_file_info *fi)
{
/* Just a stub. This method is optional and can safely be left
unimplemented */
// (void) path;
// (void) fi;
return 0;
}
static struct fuse_operations mytar_oper = {
.getattr = mytar_getattr,
.readdir = mytar_readdir,
.access = mytar_access,
.read = mytar_read,
// .open = mytar_open,
.release = mytar_release,
};
int main(int argc, char *argv[])
{
int rc;
char buf[100];
int num_read;
int i;
off_t root_off;
off_t off;
/*
if (argv[1] == NULL)
{
printf("no arguments");
return 1;
}
*/
//Open tar file
fd_tree = open("disk_image_file",O_RDONLY);
if(-1 == fd_tree) {
printf("Error %d opening file\n",errno);
exit(1);
}
//get root node offset
num_read = 0;
do
{
rc = read(fd_tree,buf+num_read,sizeof(off_t) - num_read);
if(-1 == rc)
{
printf("Error loading due to %d\n",errno);
exit(1);
}
num_read += rc;
} while (num_read < sizeof(off_t));
memcpy(&off,buf,sizeof(off_t));
//Create the tree
root = create_tree(off,fd_tree);
printf("ROOT ENTRY STAT\n");
printf("ROOT ENTRY UID %d\n", root->entry_stat.st_uid);
printf("ROOT ENTRY GID %d\n", root->entry_stat.st_gid);
//printf("ROOT ENTRY DEV %d\n", root->entry_stat.st_dev);
root->entry_stat.st_dev = 0;
printf("ROOT ENTRY NAME %s\n", root->entry_name);
printf("ROOT ENTRY MODE/TYPE %d\n", root->entry_stat.st_mode);
//Print tree
//rc = print_entry(root,argv[1],fd_tree);
return fuse_main(argc,argv, &mytar_oper, NULL);
//puts(root->entry_name);
}
Thanks,
Vas
On Mon, May 9, 2011 at 3:09 AM, Sven Utcke <sve...@gm...> wrote:
> Hello Vasanth,
>
> > The problem is when I try to perform the fuse read operation, I am
> > unable to read any contents from a specific file.So, whenever I get
> > a read request for a specific file, I scan through my image file and
> > return the appropriate contents to be read. I store this contents on
> > a temporary buffer, and I do a memcpy operation, from this temporary
> > buffer into buf, which is the character pointer passed as a argument
> > to the fuse read () function. I am also returning the size of the
> > buffer.
>
> Sounds workable.
>
> > I am however unable to view file contents when I type "cat
> > <filename> ". However in the debugging console of fuse, I am able
> > to see these contents when I am printing the buffer buf from within
> > the fuse read function.
>
> Hmm. Do you have any code for us too? Kind of hard to guess just
> where the error is. Or you could run your code through valgrind (as
> this sounds like a memory error)
>
> Sven
> --
> _ ___ ___ ___ The dCache File System
> __| |/ __|| __|/ __| An archive file-system for PB of data
> / _` | (__ | _| \__ \ http://www.desy.de/~utcke/Data/
> \__,_|\___||_| |___/ http://www.dr-utcke.de/
>
>
> ------------------------------------------------------------------------------
> WhatsUp Gold - Download Free Network Management Software
> The most intuitive, comprehensive, and cost-effective network
> management toolset available today. Delivers lowest initial
> acquisition cost and overall TCO of any competing solution.
> http://p.sf.net/sfu/whatsupgold-sd
> _______________________________________________
> fuse-devel mailing list
> fus...@li...
> https://lists.sourceforge.net/lists/listinfo/fuse-devel
>
|