コード例 #1
0
//Call after setting disk.h's 'disk_size'
superblock_t minifile_initialize(superblock_t sblock){
	int i;
	inode_t root_inode;
	inode_t first_inode;
	block_t first_block;

	if(DEBUG) printf("minifile_initialize starting...\n");
	//CREATE SUPERBLOCK
	sblock = (superblock_t) malloc(sizeof(struct superblock));
	sblock->data.disk_size = disk_size;
	sblock->data.magic_number = 19540119;
	
	//SET UP INODES AND BLOCKS
	sblock->data.inode_queue_FREE = queue_new();
	sblock->data.inode_queue_ACTIVE = queue_new();
	sblock->data.block_queue_FREE = queue_new();
	sblock->data.block_queue_ACTIVE = queue_new();

	if(DEBUG) printf("inode nad block queues created. Their lengths are: %d %d %d %d\n",
		queue_length(sblock->data.inode_queue_FREE),queue_length(sblock->data.inode_queue_ACTIVE),
		queue_length(sblock->data.block_queue_FREE),queue_length(sblock->data.block_queue_ACTIVE));

	root_inode = create_inode(0);
	first_inode = create_inode(1);
	queue_append(sblock->data.inode_queue_ACTIVE,(any_t)root_inode);
	queue_append(sblock->data.inode_queue_FREE,(any_t)first_inode);

	for(i=2;i<(0.1*disk_size);i++){
		queue_append(sblock->data.inode_queue_FREE,(any_t)create_inode(i));
	}

	first_block = (block_t) malloc(sizeof(struct block));
	queue_append(sblock->data.block_queue_FREE,(any_t)first_block);
	for(i=1;i<(0.9*disk_size-1);i++){
		queue_append(sblock->data.block_queue_FREE,(any_t)create_block(i));
	}

	if(DEBUG) printf("inode and block queues created. Their lengths are: %d %d %d %d\n",
		queue_length(sblock->data.inode_queue_FREE),queue_length(sblock->data.inode_queue_ACTIVE),
		queue_length(sblock->data.block_queue_FREE),queue_length(sblock->data.block_queue_ACTIVE));

	//FINISH SETTING UP SUPERBLOCK
	sblock->data.root_inode = root_inode;

	//RETURN SUPERBLOCK
	return sblock;
}
コード例 #2
0
unsigned int 
create_ifile(enum file_type_e type) 
{
    unsigned int inumber; 

    inumber = create_inode(type);
    ffatal(inumber, "unable to create inode"); 

    return inumber; 
}
コード例 #3
0
void assign_inode(struct cdfs_entry_struct *entry)
{

    entry->inode=create_inode();

    if ( entry->inode ) {

        entry->inode->alias=entry;

    }

}
コード例 #4
0
ファイル: fsys_ntfs.c プロジェクト: belenix/belenixold
/* Get an inode's information and store the inode in the cache
 * The inode may become invalid after the next call to this function.
 * Nofile: allow internal inodes */
static int
get_inode(long long inode,pinode *inodep,int nofile)
{
    int i,freeone,oldest;
    unsigned ksusage;
    static unsigned curusage=1;
    static char *mftentry=NULL;
    pinode xinode;
    /* Space for the MFT entry */
    if(!mftentry)
    {
        mftentry=malloc(mftentsize);
        if(!mftentry) return 5;
    }
    /* Look if the inode is in the cache;
     * if no, look for unused cache entries
     * and find the oldest cache entry */
    for(i=oldest=0,freeone=-1,ksusage=0;i<MAXINODEBUF;i++)
    {
        if(!inodes[i]) freeone=i;
        else if(inodes[i]->inode==inode)
        {
            inodes[i]->lastusage=curusage++;
            *inodep=inodes[i];
            if(inodes[i]->ftype<0 && !nofile) return 5;
            return 0;
        }
        else if(inodes[i]->lastusage<ksusage || !ksusage)
        {
            ksusage=inodes[i]->lastusage;
            oldest=i;
        }
    }
    /* Which entry to use ? */
    if(freeone<0) freeone=oldest;
    /* Read the inode's MFT entry */
    i=read_attribute(mft_inode,0x80,inode*mftentsize,mftentry,mftentsize,0);
    if(i<0) return -i;
    if(i!=mftentsize) return 5;
    if(do_fixups(mftentry,mftentsize)) return 5;
    xinode=create_inode(inode,mftentry,nofile);
    if(!xinode) return 5;
    xinode->lastusage=curusage++;
    if(inodes[freeone])
    {
        free(inodes[freeone]->curidx);
        free(inodes[freeone]->treedata);
        free(inodes[freeone]);
    }
    *inodep=inodes[freeone]=xinode;
    return 0;
}
コード例 #5
0
ファイル: fatfs.c プロジェクト: htchiang/zeke
int fatfs_mknod(vnode_t * dir, const char * name, int mode, void * specinfo,
                vnode_t ** result)
{
    struct fatfs_inode * indir = get_inode_of_vnode(dir);
    struct fatfs_inode * res = NULL;
    char * in_fpath;
    int err;

#ifdef configFATFS_DEBUG
    KERROR(KERROR_DEBUG,
           "fatfs_mknod(dir %p, name \"%s\", mode %u, specinfo %p, result %p)\n",
           dir, name, mode, specinfo, result);
#endif

    if (!S_ISDIR(dir->vn_mode))
        return -ENOTDIR;

    if ((mode & S_IFMT) != S_IFREG)
        return -ENOTSUP; /* FAT only suports regular files. */

    if (specinfo)
        return -EINVAL; /* specinfo not supported. */

    in_fpath = format_fpath(indir, name);
    if (!in_fpath)
        return -ENOMEM;

    err = create_inode(&res, get_ffsb_of_sb(dir->sb), in_fpath,
                       hash32_str(in_fpath, 0), O_CREAT);
    if (err) {
        kfree(in_fpath);
        return fresult2errno(err);
    }

    if (result)
        *result = &res->in_vnode;
    fatfs_chmod(&res->in_vnode, mode);

#ifdef configFATFS_DEBUG
    KERROR(KERROR_DEBUG, "mkdod() ok\n");
#endif

    return 0;
}
コード例 #6
0
ファイル: fatfs.c プロジェクト: htchiang/zeke
static vnode_t * create_root(struct fatfs_sb * fatfs_sb)
{
    char * rootpath;
    long vn_hash;
    struct fatfs_inode * in;
    int err;

    rootpath = kzalloc(2);
    if (!rootpath)
        return NULL;

    vn_hash = hash32_str(rootpath, 0);
    err = create_inode(&in, fatfs_sb, rootpath, vn_hash,
                       O_DIRECTORY | O_RDWR);
    if (err) {
        KERROR(KERROR_ERR, "Failed to init a root vnode for fatfs (%d)\n", err);
        return NULL;
    }

    in->in_fpath = rootpath;

    vrefset(&in->in_vnode, 1);
    return &in->in_vnode;
}
コード例 #7
0
ファイル: overlay.c プロジェクト: neremin/fuse-workspace
static void overlay_mknod(fuse_req_t req, struct inode_struct *pinode, struct name_struct *xname, struct call_info_struct *call_info, mode_t mode, dev_t rdev)
{
    struct resource_struct *resource=call_info->object->resource;
    struct localfile_struct *localfile=(struct localfile_struct *) resource->data;
    struct pathinfo_struct *pathinfo=&call_info->pathinfo;
    unsigned int len0=pathinfo->len - call_info->relpath, len1=localfile->pathinfo.len;
    char path[len0 + len1 + 1];
    struct entry_struct *entry=NULL, *parent=pinode->alias;
    struct inode_struct *inode;


    memcpy(path, localfile->pathinfo.path, len1);

    if (len0>0) {

	memcpy(path+len1, pathinfo->path + call_info->relpath, len0);
	len1+=len0;

    }

    path[len1]='\0';

    entry=create_entry(parent, xname);
    inode=create_inode();

    if (entry && inode) {
	struct entry_struct *result=NULL;
	unsigned int error=0;

	entry->inode=inode;
	inode->alias=entry;

	result=insert_entry(entry, &error, _ENTRY_FLAG_TEMP);

	if (result==entry) {
	    uid_t uid_keep=setfsuid(call_info->uid);
	    gid_t gid_keep=setfsgid(call_info->gid);
	    mode_t umask_keep=umask(call_info->umask);

	    mode = (mode & ~call_info->umask);

	    if (mknod(path, mode, rdev)==0) {
    		struct fuse_entry_param e;

		adjust_pathmax(call_info->pathinfo.len);
		add_inode_hashtable(inode, increase_inodes_workspace, (void *) call_info->workspace_mount);

		/* here complete the insert ?? */

		inode->mode=mode;

		inode->nlink=1;
		inode->uid=call_info->uid;
		inode->gid=call_info->gid;
		inode->nlookup=1;

		inode->rdev=rdev;
		inode->size=0;

		get_current_time(&inode->mtim);
		memcpy(&inode->ctim, &inode->mtim, sizeof(struct timespec));

		memset(&e, 0, sizeof(e));

		e.ino = inode->ino;
		e.generation = 1;

		e.attr.st_ino = e.ino;
		e.attr.st_mode = inode->mode;
		e.attr.st_nlink = inode->nlink;
		e.attr.st_dev = 0;
		e.attr.st_uid=inode->uid;
		e.attr.st_gid=inode->gid;
		e.attr.st_size=inode->size;
		e.attr.st_rdev=inode->rdev;

		memcpy(&e.attr.st_mtim, &inode->mtim, sizeof(struct timespec));
		memcpy(&e.attr.st_ctim, &inode->mtim, sizeof(struct timespec));
		memcpy(&e.attr.st_atim, &inode->mtim, sizeof(struct timespec));

		e.attr_timeout = fs_options.attr_timeout;
		e.entry_timeout = fs_options.entry_timeout;

		e.attr.st_blksize=4096;
		e.attr.st_blocks=0;

    		fuse_reply_entry(req, &e);

	    } else {
		unsigned int error_delete=0;

		error=errno;

		remove_entry(entry, &error_delete);

		destroy_entry(entry);
		entry=NULL;

		free(inode);
		inode=NULL;

		fuse_reply_err(req, error);

	    }

	    uid_keep=setfsuid(uid_keep);
	    gid_keep=setfsgid(gid_keep);
	    umask_keep=umask(umask_keep);

	} else {

	    destroy_entry(entry);
	    entry=NULL;

	    free(inode);
	    inode=NULL;

	    if (error==0) error=EEXIST;

	    fuse_reply_err(req, error);

	}

    } else {

	if (entry) {

	    destroy_entry(entry);
	    entry=NULL;

	}

	if (inode) {

	    free(inode);
	    inode=NULL;

	}

	fuse_reply_err(req, ENOMEM);

    }

}
コード例 #8
0
ファイル: overlay.c プロジェクト: neremin/fuse-workspace
static void overlay_lookup_noncached(fuse_req_t req, struct inode_struct *pinode, struct name_struct *xname, struct call_info_struct *call_info)
{
    struct resource_struct *resource=call_info->object->resource;
    struct localfile_struct *localfile=(struct localfile_struct *) resource->data;
    struct pathinfo_struct *pathinfo=&call_info->pathinfo;
    unsigned int len0=pathinfo->len - call_info->relpath, len1=localfile->pathinfo.len;
    char path[len0 + len1 + 1];
    struct stat st;

    memcpy(path, localfile->pathinfo.path, len1);

    if (len0>0) {

	memcpy(path+len1, pathinfo->path + call_info->relpath, len0);
	len1+=len0;

    }

    path[len1]='\0';

    memset(&st, 0, sizeof(struct stat));

    logoutput("overlayfs_lookup_cached, path %s", path);

    if (lstat(path, &st)==-1) {

	fuse_reply_err(req, ENOENT);

    } else {
	struct entry_struct *entry=NULL, *parent=pinode->alias;
	struct inode_struct *inode;

	entry=create_entry(parent, xname);
	inode=create_inode();

	if (entry && inode) {
	    struct fuse_entry_param e;
	    unsigned int error=0;

	    add_inode_hashtable(inode, increase_inodes_workspace, (void *) call_info->workspace_mount);
	    insert_entry(entry, &error, 0);

	    adjust_pathmax(call_info->pathinfo.len);

	    e.ino = inode->ino;
	    e.generation = 1;
	    e.attr_timeout = fs_options.attr_timeout;
	    e.entry_timeout = fs_options.entry_timeout;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = st.st_mode;
	    e.attr.st_nlink = st.st_nlink;
	    e.attr.st_uid = st.st_uid;
	    e.attr.st_gid = st.st_gid;
	    e.attr.st_rdev = st.st_rdev;
	    e.attr.st_atim.tv_sec = st.st_atim.tv_sec;
	    e.attr.st_atim.tv_nsec = st.st_atim.tv_nsec;
	    e.attr.st_mtim.tv_sec = st.st_mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = st.st_mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = st.st_ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = st.st_ctim.tv_nsec;

	    e.attr.st_blksize=4096;
	    e.attr.st_blocks=0;

	    inode->mode=st.st_mode;
	    inode->nlink=st.st_nlink;
	    inode->uid=st.st_uid;
	    inode->gid=st.st_gid;

	    inode->rdev=st.st_rdev;

	    if (S_ISDIR(st.st_mode)) {

		e.attr.st_size = 0;

	    } else {

		inode->size=st.st_size;
		e.attr.st_size = st.st_size;

	    }

	    inode->mtim.tv_sec=st.st_mtim.tv_sec;
	    inode->mtim.tv_nsec=st.st_mtim.tv_nsec;

	    inode->ctim.tv_sec=st.st_ctim.tv_sec;
	    inode->ctim.tv_nsec=st.st_ctim.tv_nsec;

	    fuse_reply_entry(req, &e);

	} else {

	    /* not enough memory to allocate entry and/or inode */

	    if (entry) {

		destroy_entry(entry);
		entry=NULL;

	    }

	    if (inode) {

		free(inode);
		inode=NULL;

	    }

	    fuse_reply_err(req, ENOMEM);

	}

    }

    free_path_pathinfo(&call_info->pathinfo);

}
コード例 #9
0
ファイル: overlay.c プロジェクト: neremin/fuse-workspace
static void overlay_readdirplus_full(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    struct fuse_entry_param e;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct overlay_readdir_struct *overlay_readdir=(struct overlay_readdir_struct *)dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    unsigned char dtype;
    struct name_struct xname={NULL, 0, 0};
    int res=0;

    memset(&e, 0, sizeof(struct fuse_entry_param));

    e.generation = 1;
    e.attr_timeout = fs_options.attr_timeout;
    e.entry_timeout = fs_options.entry_timeout;

    e.attr.st_blksize=4096;
    e.attr.st_blocks=0;

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

    	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = 0;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotname;

	    inode->nlookup++;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if ( ! dh->parent->parent ) {

		inode=dh->parent->inode;

	    } else {

		inode=dh->parent->parent->inode;

	    }

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = 0;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotdotname;

	    inode->nlookup++;

    	} else {

	    if (! dh->entry) {

		readdir:

		res=get_direntry(overlay_readdir, &xname, &dtype, &error);

		if (res<=0) {

		    if (res==-1) {

			free(buff);
			unlock_directory(directory, _DIRECTORY_LOCK_EXCL);
			goto error;

		    }

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		if (fstatat(overlay_readdir->fd, xname.name, &e.attr, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT)==-1) {

		    goto readdir;

		}

		logoutput("overlayfs_readdirplus_real_full: read %s", xname.name);

		xname.len=strlen(xname.name);
		calculate_nameindex(&xname);

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {

			memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));
			inode->mode=DTTOIF(dtype);

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		    e.attr.st_ino=inode->ino;
		    e.ino=inode->ino;
		    e.attr.st_rdev = inode->rdev;
		    e.attr.st_dev = 0;
		    name=entry->name.name;

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		name=entry->name.name;
		dh->entry=entry;

		inode->mode = e.attr.st_mode;
		inode->nlink = e.attr.st_nlink;
		inode->uid = e.attr.st_uid;
		inode->gid = e.attr.st_gid;
		inode->rdev = e.attr.st_rdev;

		inode->mtim.tv_sec = e.attr.st_mtim.tv_sec;
		inode->mtim.tv_nsec = e.attr.st_mtim.tv_nsec;
		inode->ctim.tv_sec = e.attr.st_ctim.tv_sec;
		inode->ctim.tv_nsec = e.attr.st_ctim.tv_nsec;

		if (S_ISDIR(e.attr.st_mode)) {

		    e.attr.st_size=0;

		} else {

		    inode->size=e.attr.st_size;

		}

	    } else {

		entry=dh->entry;
		inode=entry->inode;
		name=entry->name.name;

		e.attr.st_mode = inode->mode;
		e.attr.st_nlink = inode->nlink;
		e.attr.st_uid = inode->uid;
		e.attr.st_gid = inode->gid;
		e.attr.st_rdev = inode->rdev;

		if (S_ISDIR(inode->mode)) {

		    e.attr.st_size = 0;

		} else {

		    e.attr.st_size = inode->size;

		}

		e.attr.st_atim.tv_sec = 0;
		e.attr.st_atim.tv_nsec = 0;
		e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
		e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
		e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
		e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

		inode->nlookup++;

	    }

	    e.ino = inode->ino;
	    e.attr.st_ino = e.ino;

	}

    	dirent_size=fuse_add_direntry_plus(req, buff+pos, size-pos, name, &e, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset=offset+1;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
コード例 #10
0
ファイル: overlay.c プロジェクト: neremin/fuse-workspace
static void overlay_readdir_full(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    struct stat st;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct overlay_readdir_struct *overlay_readdir=(struct overlay_readdir_struct *)dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    struct name_struct xname={NULL, 0, 0};
    unsigned char dtype=0;
    int res;

    memset(&st, 0, sizeof(struct stat));

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

    	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

    	    st.st_ino = inode->ino;
	    st.st_mode = S_IFDIR;
	    name = (char *) dotname;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if ( ! dh->parent->parent ) {

		inode=dh->parent->inode;
	    	st.st_ino = inode->ino;

	    } else {
		struct entry_struct *parent=dh->parent->parent;

		inode=parent->inode;
	    	st.st_ino=inode->ino;

	    }

	    st.st_mode = S_IFDIR;
	    name = (char *) dotdotname;

    	} else {

	    if (! dh->entry) {

		readdir:

		res=get_direntry(overlay_readdir, &xname, &dtype, &error);

		if (res<=0) {

		    if (res==-1) {

			free(buff);
			unlock_directory(directory, _DIRECTORY_LOCK_EXCL);
			goto error;

		    }

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		xname.len=strlen(xname.name);
		calculate_nameindex(&xname);

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {

			entry->inode->mode=DTTOIF(dtype);

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		    st.st_mode=entry->inode->mode;
		    st.st_ino=entry->inode->ino;
		    name=entry->name.name;

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		dh->entry=entry;

	    } else {

		entry=dh->entry;

		st.st_ino=entry->inode->ino;
		st.st_mode=entry->inode->mode;
		name=entry->name.name;

	    }

	}

    	dirent_size=fuse_add_direntry(req, buff+pos, size-pos, name, &st, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset = offset + 1;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
コード例 #11
0
ファイル: fatfs.c プロジェクト: htchiang/zeke
/**
 * Lookup for a vnode (file/dir) in FatFs.
 * First lookup form vfs_hash and if not found then read it from ff which will
 * probably read it via devfs interface. After the vnode has been created it
 * will be added to the vfs hashmap. In ff terminology all files and directories
 * that are in hashmap are also open on a file/dir handle, thus we'll have to
 * make sure we don't have too many vnodes in cache that have no references, to
 * avoid hitting any ff hard limits.
 */
static int fatfs_lookup(vnode_t * dir, const char * name, vnode_t ** result)
{
    struct fatfs_inode * indir = get_inode_of_vnode(dir);
    struct fatfs_sb * sb = get_ffsb_of_sb(dir->sb);
    char * in_fpath;
    long vn_hash;
    struct vnode * vn = NULL;
    int err, retval = 0;

    KASSERT(dir != NULL, "dir must be set");

    /* Format full path */
    in_fpath = format_fpath(indir, name);
    if (!in_fpath)
        return -ENOMEM;

    /*
     * Emulate . and ..
     */
    if (name[0] == '.' && name[1] != '.') {
#ifdef configFATFS_DEBUG
        KERROR(KERROR_DEBUG, "Lookup emulating \".\"\n");
#endif
        (void)vref(dir);
        *result = dir;

        kfree(in_fpath);
        return 0;
    } else if (name[0] == '.' && name[1] == '.' && name[2] != '.') {
#ifdef configFATFS_DEBUG
        KERROR(KERROR_DEBUG, "Lookup emulating \"..\"\n");
#endif
        if (VN_IS_FSROOT(dir)) {
            *result = dir->sb->mountpoint;

            kfree(in_fpath);
            return -EDOM;
        } else {
            size_t i = strlenn(in_fpath, NAME_MAX) - 4;

            while (in_fpath[i] != '/') {
                i--;
            }
            in_fpath[i] = '\0';
        }
    }

    /*
     * Lookup from vfs_hash
     */
    vn_hash = hash32_str(in_fpath, 0);
    err = vfs_hash_get(
            dir->sb,        /* FS superblock */
            vn_hash,        /* Hash */
            &vn,            /* Retval */
            fatfs_vncmp,    /* Comparator */
            in_fpath        /* Compared fpath */
          );
    if (err) {
        retval = -EIO;
        goto fail;
    }
    if (vn) { /* found it in vfs_hash */
#ifdef configFATFS_DEBUG
        KERROR(KERROR_DEBUG, "vn found in vfs_hash (%p)\n", vn);
#endif

        *result = vn;
        retval = 0;
    } else { /* not cached */
        struct fatfs_inode * in;

#ifdef configFATFS_DEBUG
        KERROR(KERROR_DEBUG, "vn not in vfs_hash\n");
#endif

        /*
         * Create a inode and fetch data from the device.
         * This also vrefs.
         */
        err = create_inode(&in, sb, in_fpath, vn_hash, O_RDWR);
        if (err) {
            retval = err;
            goto fail;
        }

        in_fpath = NULL; /* shall not be freed. */
        *result = &in->in_vnode;
        retval = 0;
    }

fail:
    kfree(in_fpath);
    return retval;
}
コード例 #12
0
static void workspace_nfs_mknod(fuse_req_t req, struct inode_struct *pinode, struct name_struct *xname, struct call_info_struct *call_info, mode_t mode, dev_t rdev)
{
    struct resource_struct *resource=call_info->object->resource;
    struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data;
    struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data;
    char *path=call_info->pathinfo.path + call_info->relpath;
    struct entry_struct *entry=NULL, *parent=pinode->alias;
    struct inode_struct *inode;

    logoutput("workspace_nfs_mknod, path %s", path);

    entry=create_entry(parent, xname);
    inode=create_inode();

    if (entry && inode) {
	int result=0;

	inode->alias=entry;
	entry->inode=inode;

        pthread_mutex_lock(&nfs_export->mutex);

	result=nfs_mknod(nfs_ctx, path, mode, rdev);

	pthread_mutex_unlock(&nfs_export->mutex);

	if (result==0) {
	    struct fuse_entry_param e;
	    unsigned int error=0;
	    struct stat st;

	    memset(&st, 0, sizeof(struct stat));

	    add_inode_hashtable(inode, increase_inodes_workspace, (void *) call_info->object->workspace_mount);
	    insert_entry(entry, &error, 0);

	    adjust_pathmax(call_info->pathinfo.len);

	    pthread_mutex_lock(&nfs_export->mutex);

	    nfs_chmod(nfs_ctx, path, mode);
	    nfs_stat(nfs_ctx, path, &st);

	    pthread_mutex_unlock(&nfs_export->mutex);

	    inode->nlookup=1;
	    inode->mode=st.st_mode;
	    inode->nlink=st.st_nlink;
	    inode->uid=st.st_uid;
	    inode->gid=st.st_gid;

	    inode->rdev=st.st_rdev;
	    inode->size=st.st_size;

	    inode->mtim.tv_sec=st.st_mtim.tv_sec;
	    inode->mtim.tv_nsec=st.st_mtim.tv_nsec;

	    inode->ctim.tv_sec=st.st_ctim.tv_sec;
	    inode->ctim.tv_nsec=st.st_ctim.tv_nsec;

	    e.ino = inode->ino;
	    e.generation = 1;
	    e.attr_timeout = fs_options.attr_timeout;
	    e.entry_timeout = fs_options.entry_timeout;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = st.st_mode;
	    e.attr.st_nlink = st.st_nlink;
	    e.attr.st_uid = st.st_uid;
	    e.attr.st_gid = st.st_gid;
	    e.attr.st_rdev = st.st_rdev;
	    e.attr.st_atim.tv_sec = st.st_atim.tv_sec;
	    e.attr.st_atim.tv_nsec = st.st_atim.tv_nsec;
	    e.attr.st_mtim.tv_sec = st.st_mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = st.st_mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = st.st_ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = st.st_ctim.tv_nsec;

	    e.attr.st_blksize=_DEFAULT_BLOCKSIZE;

	    if (inode->size % e.attr.st_blksize == 0) {

		e.attr.st_blocks=inode->size / e.attr.st_blksize;

	    } else {

		e.attr.st_blocks=1 + inode->size / e.attr.st_blksize;

	    }

	    fuse_reply_entry(req, &e);

	} else {

	    /* error nfs create */

	    destroy_entry(entry);
	    free(inode);

	    fuse_reply_err(req, abs(result));

	}

    } else {

	/* not enough memory to allocate entry and/or inode */

	if (entry) {

	    destroy_entry(entry);
	    entry=NULL;

	}

	if (inode) {

	    free(inode);
	    inode=NULL;

	}

	fuse_reply_err(req, ENOMEM);

    }

    free_path_pathinfo(&call_info->pathinfo);

}
コード例 #13
0
static void workspace_nfs_readdirplus_simple(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    struct resource_struct *resource=dh->object->resource;
    struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data;
    struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data;
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    struct fuse_entry_param e;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct nfsdir *dir=(struct nfsdir *) dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    struct name_struct xname={NULL, 0, 0};

    memset(&e, 0, sizeof(struct fuse_entry_param));

    e.generation = 1;
    e.attr_timeout = fs_options.attr_timeout;
    e.entry_timeout = fs_options.entry_timeout;

    e.attr.st_blksize=_DEFAULT_BLOCKSIZE;

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

    	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = inode->size;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotname;

	    inode->nlookup++;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if ( ! dh->parent->parent ) {

		inode=dh->parent->inode;

	    } else {

		inode=dh->parent->parent->inode;

	    }

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = inode->size;
	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    name = (char *) dotdotname;

	    inode->nlookup++;

    	} else {

	    if (! dh->entry) {
		struct nfsdirent *de;

		readdir:

	        pthread_mutex_lock(&nfs_export->mutex);

		de=nfs_readdir(nfs_ctx, dir);

	        pthread_mutex_unlock(&nfs_export->mutex);

		if (de) {

		    if (strcmp(de->name, ".")==0 || strcmp(de->name, "..")==0) continue;

		    xname.name=de->name;
		    xname.len=strlen(xname.name);
		    calculate_nameindex(&xname);

		} else {

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {
			struct workspace_object_struct *export_object=NULL;

			inode->mode = translate_libnfs_type(de->type);
			inode->mode |= de->mode;

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));

			inode->nlookup++;
			inode->nlink=2;
			inode->uid=0; /* ?? */
			inode->gid=0; /* ?? */
			inode->size=de->size;

			/* struct timeval convert to timespec */

			inode->mtim.tv_sec=de->mtime.tv_sec;
			inode->mtim.tv_nsec=1000 * de->mtime.tv_usec;

			inode->ctim.tv_sec=de->ctime.tv_sec;
			inode->ctim.tv_nsec=1000 * de->ctime.tv_usec;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    memcpy(&entry->synctime, &dh->synctime, sizeof(struct timespec));

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		name=entry->name.name;
		dh->entry=entry;


	    } else {

		entry=dh->entry;

		inode=entry->inode;
		name=entry->name.name;

	    }

	    e.ino = inode->ino;

	    e.attr.st_ino = e.ino;
	    e.attr.st_mode = inode->mode;
	    e.attr.st_nlink = inode->nlink;
	    e.attr.st_uid = inode->uid;
	    e.attr.st_gid = inode->gid;
	    e.attr.st_rdev = inode->rdev;
	    e.attr.st_size = inode->size;

	    e.attr.st_atim.tv_sec = 0;
	    e.attr.st_atim.tv_nsec = 0;
	    e.attr.st_mtim.tv_sec = inode->mtim.tv_sec;
	    e.attr.st_mtim.tv_nsec = inode->mtim.tv_nsec;
	    e.attr.st_ctim.tv_sec = inode->ctim.tv_sec;
	    e.attr.st_ctim.tv_nsec = inode->ctim.tv_nsec;

	    if (inode->size % e.attr.st_blksize == 0) {

		e.attr.st_blocks=inode->size / e.attr.st_blksize;

	    } else {

		e.attr.st_blocks=1 + inode->size / e.attr.st_blksize;

	    }

	}

    	dirent_size=fuse_add_direntry_plus(req, buff+pos, size-pos, name, &e, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset=offset;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
コード例 #14
0
static void workspace_nfs_readdir_simple(fuse_req_t req, size_t size, off_t offset, struct workspace_dh_struct *dh)
{
    struct resource_struct *resource=dh->object->resource;
    struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data;
    struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data;
    unsigned int error=0;
    char *buff=NULL;
    size_t pos=0;
    size_t dirent_size;
    char *name=NULL;
    struct directory_struct *directory=dh->directory;
    struct nfsdir *dir=(struct nfsdir *) dh->handle.data;
    struct entry_struct *entry, *result;
    struct inode_struct *inode;
    struct name_struct xname={NULL, 0, 0};
    struct stat st;

    memset(&st, 0, sizeof(struct stat));

    buff=malloc(size);

    if (! buff) {

	error=ENOMEM;
	goto error;

    }

    if (lock_directory(directory, _DIRECTORY_LOCK_EXCL)==-1) {

	free(buff);
	buff=NULL;
	error=EAGAIN;
	goto error;

    }

    while (pos<size) {

	if (offset==0) {

	    inode=dh->parent->inode;

    	    /* the . entry */

    	    st.st_ino = inode->ino;
	    st.st_mode = S_IFDIR;
	    name = (char *) dotname;

    	} else if (offset==1) {

    	    /* the .. entry */

	    if (! dh->parent->parent ) {

		inode=dh->parent->inode;
	    	st.st_ino = inode->ino;

	    } else {
		struct entry_struct *parent=dh->parent->parent;

		inode=parent->inode;
	    	st.st_ino=inode->ino;

	    }

	    st.st_mode = S_IFDIR;
	    name = (char *) dotdotname;

    	} else {

	    if (! dh->entry) {
		struct nfsdirent *de;

		readdir:

		pthread_mutex_lock(&nfs_export->mutex);

		de=nfs_readdir(nfs_ctx, dir);

	        pthread_mutex_unlock(&nfs_export->mutex);

		if (de) {

		    if (strcmp(de->name, ".")==0 || strcmp(de->name, "..")==0) continue;

		    xname.name=de->name;
		    xname.len=strlen(xname.name);
		    calculate_nameindex(&xname);

		} else {

		    dh->mode |= _WORKSPACE_READDIR_MODE_FINISH;
		    break;

		}

		error=0;

		entry=create_entry(dh->parent, &xname);
		inode=create_inode();

		if (entry && inode) {

		    result=insert_entry_batch(directory, entry, &error, 0);

		    if (result==entry) {
			struct workspace_object_struct *export_object=NULL;

			inode->mode = translate_libnfs_type(de->type);
			inode->mode |= de->mode;

			add_inode_hashtable(inode, increase_inodes_workspace, (void *) dh->object->workspace_mount);

			inode->alias=entry;
			entry->inode=inode;

			adjust_pathmax(dh->pathinfo.len + 1 + xname.len);

		    } else {

			if (error==EEXIST) {

			    destroy_entry(entry);
			    entry=result;

			    free(inode);
			    inode=entry->inode;

			} else {

			    free(buff);
			    destroy_entry(entry);
			    free(inode);

			    goto error;

			}

		    }

		    st.st_mode=entry->inode->mode;
		    st.st_ino=entry->inode->ino;
		    name=entry->name.name;

		} else {

		    if (entry) {

			destroy_entry(entry);
			entry=NULL;

		    }

		    if (inode) {

			free(inode);
			inode=NULL;

		    }

		    error=ENOMEM;
		    free(buff);

		    goto error;

		}

		dh->entry=entry;

	    } else {

		st.st_ino=dh->entry->inode->ino;
		st.st_mode=dh->entry->inode->mode;
		name=dh->entry->name.name;

	    }

	}

    	dirent_size=fuse_add_direntry(req, buff+pos, size-pos, name, &st, offset+1);

	if (pos + dirent_size > size) {

	    dh->offset = offset + 1;
	    break;

	}

	/* increase counter and clear the various fields */

	dh->entry=NULL; /* forget current entry to force readdir */
	offset++;
	pos += dirent_size;

    }

    unlock_directory(directory, _DIRECTORY_LOCK_EXCL);

    fuse_reply_buf(req, buff, pos);

    free(buff);
    buff=NULL;

    return;

    error:

    fuse_reply_err(req, error);

}
コード例 #15
0
ファイル: fsys_ntfs.c プロジェクト: belenix/belenixold
/* Initialize the NTFS access */
int
ntfs_initialize(long long offset, int partmode, int dosnames)
{
    unsigned char sec[512],*mftfirst;
    unsigned u,u2;
    long long ll;
    void *pold;

    /* Check for a partition table */
    part_offset = offset;
    llseek(dskhandle, part_offset, SEEK_SET);
    read(dskhandle, sec, 512);
    if(partmode == 2) partmode = memcmp(&(sec[3]),"NTFS    ",8)?1:0;
    if(partmode)
    {
        part_offset+=getlittle32(sec,0x1C6)*512;
        llseek(dskhandle,part_offset,SEEK_SET);
        read(dskhandle,sec,512);
    }
    /* Is it really NTFS ? */
    if(memcmp(&(sec[3]),"NTFS    ",8))
    {
        fprintf(stderr,"This is not an NTFS disk/image.\n");
        return (1);
    }
    usedosnames=dosnames;
    sectlen=sec[11]+0x100*sec[12];
    clustlen=sec[13]*sectlen;
    ll=getlittle64(sec,0x28);
    mftclust=getlittle64(sec,0x30);
    if(ll>0x7FFFFFFF) disksize=0x7FFFFFFF;
    else disksize=(unsigned)ll;
    /* Now get the data MFT entry for the MFT itself */
    llseek(dskhandle,part_offset+clustlen*mftclust,SEEK_SET);
    mftfirst=malloc(clustlen);
    if(!mftfirst)
    {
        fprintf(stderr,"Memory problem.\n");
        return (1);
    }
    read(dskhandle,mftfirst,clustlen);
    mftentsize=getlittle32(mftfirst,0x1C);
    if(mftentsize>clustlen)
    {
        pold=mftfirst;
        mftfirst=realloc(mftfirst,mftentsize);
        if(!mftfirst)
        {
            free(pold);
            fprintf(stderr,"Memory problem.\n");
            return (1);
        }
        read(dskhandle,mftfirst+clustlen,mftentsize-clustlen);
    }
    if(do_fixups(mftfirst,mftentsize))
    {
        free(mftfirst);
        fprintf(stderr,"Error: MFT seems to be damaged.\n");
        return (1);
    }
    mft_inode=create_inode(0,mftfirst,0);
    if(!mft_inode)
    {
        fprintf(stderr,"Error: Couldn\'t get the MFT inode.\n");
        return (1);
    }
    free(mftfirst);
    /* Initialize the cache */
    for(u=0;u<MAXCLUSTBUF;u++)
    {
        clusters[u].lastusage=0;
        clusters[u].cluster=-2ll;
        clusters[u].data=malloc(clustlen);
        if(!clusters[u].data)
        {
            for(u2=0;u2<u;u2++) free(clusters[u2].data);
            free(mft_inode);
            fprintf(stderr,"Not enough memory.");
            return (1);
        }
    }
    for(u=0;u<MAXINODEBUF;u++) inodes[u]=NULL;
    return 0;
}