示例#1
0
文件: fuse.c 项目: artagnon/phoenixfs
static int phoenixfs_getattr(const char *path, struct stat *stbuf)
{
	struct file_record *fr;
	struct dir_record *dr;
	int rev;

	rev = parse_pathspec(xpath, path);
	build_xpath(openpath, xpath, rev);
	PHOENIXFS_DBG("getattr:: %s %d", openpath, rev);

	/* Try underlying FS */
	if (lstat(openpath, stbuf) < 0) {
		/* Try fstree */
		if (!(dr = find_dr(xpath))) {
			if (!(fr = find_fr(xpath, rev)))
				return -ENOENT;
			else {
				memset(stbuf, 0, sizeof(struct stat));
				fill_stat(stbuf, fr);
				return 0;
			}
		}
		memset(stbuf, 0, sizeof(struct stat));
		stbuf->st_mode = S_IFDIR | 0755;
	}
	return 0;
}
示例#2
0
gsuint gs_mtime ( const char *name ) // modification time of the file as a Unix timestamp
 {
   if ( !fill_stat(name) ) return 0;
   if ( _lstat.st_mtime ) return (gsuint) _lstat.st_mtime;
   if ( _lstat.st_atime ) return (gsuint) _lstat.st_atime;
   return (gsuint) _lstat.st_ctime;
 }
示例#3
0
文件: fuse.c 项目: artagnon/phoenixfs
static int phoenixfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
			off_t offset, struct fuse_file_info *fi)
{
	DIR *dp;
	struct dirent *de;
	struct stat st;
	void *record;
	struct node *iter_root, *iter;
	struct vfile_record *vfr;
	struct dir_record *dr;
	register int i;

	dp = (DIR *) (uintptr_t) fi->fh;

	if (!(de = readdir(dp)))
		return -errno;

	/* Fill directories from backing FS */
	do {
		/* Hide the .git directory, and enumerate only directories */
		if (strcmp(de->d_name, ".git") && de->d_type == DT_DIR) {
			PHOENIXFS_DBG("readdir:: fs: %s", de->d_name);
			if (filler(buf, de->d_name, NULL, 0))
				return -ENOMEM;
		}
	} while ((de = readdir(dp)) != NULL);

	/* Fill files from fstree */
	if (!(dr = find_dr(path)) || !dr->vroot) {
		PHOENIXFS_DBG("readdir:: fstree: blank");
		return 0;
	}
	iter_root = dr->vroot;
	iter = dr->vroot;

	/* Use only the leaves */
	while (!iter->is_leaf)
		iter = iter->pointers[0];

	while (1) {
		for (i = 0; i < iter->num_keys; i++) {
			if (!(record = find(iter_root, iter->keys[i], 0)))
				PHOENIXFS_DBG("readdir:: key listing issue");
			vfr = (struct vfile_record *) record;
			fill_stat(&st, vfr->history[vfr->HEAD]);
			PHOENIXFS_DBG("readdir:: tree fill: %s", (const char *) vfr->name);
			if (filler(buf, (const char *) vfr->name, &st, 0))
				return -ENOMEM;
		}
		if (iter->pointers && iter->pointers[BTREE_ORDER - 1] != NULL)
			iter = iter->pointers[BTREE_ORDER - 1];
		else
			break;
	}
	return 0;
}
示例#4
0
int os_file_stat_fd(int fd, struct os_file_stat *buf, int *pfile_errno)
{
	struct stat sb;

	if (fstat(fd, &sb) == -1) {
		*pfile_errno = errno;
		buf->flags = FILE_FLAG_IS_ERROR;

		return -1;
	}

	fill_stat(buf, &sb);

	return 0;
}
示例#5
0
int os_file_stat(const char *path, struct os_file_stat *buf, int *pfile_errno)
{
	struct stat sb;

	if (stat(path, &sb) == -1) {
		*pfile_errno = errno;
		buf->flags = FILE_FLAG_IS_ERROR;

		return -1;
	}

	fill_stat(buf, &sb);

	return 0;
}
示例#6
0
static
void fill_fd(struct fd *pfd, int flags, const FILINFO *fno)
{
    pfd->isatty = 0;
    pfd->isopen = 1;
    pfd->close = fatfs_close;
    pfd->status_flags = flags;
    pfd->descriptor_flags = 0;
    if (!((fno->fattrib & AM_MASK) & AM_DIR))
    {
        pfd->write = fatfs_write;
        pfd->read = fatfs_read;
    }

    fill_stat(fno, &pfd->stat);
}
示例#7
0
static void serve_getattr(fuse_req_t req, fuse_ino_t fuse_ino, struct fuse_file_info * fi)
{
	Dprintf("%s(ino = %lu)\n", __FUNCTION__, fuse_ino);
	struct stat stbuf;
	int r;

	(void) fi;

	memset(&stbuf, 0, sizeof(stbuf));
	r = fill_stat(reqmount(req), fusecfsino(req, fuse_ino), fuse_ino, &stbuf);
	if (r < 0)
		r = fuse_reply_err(req, -r);
	else
		r = fuse_reply_attr(req, &stbuf, STDTIMEOUT);
	fuse_reply_assert(!r);
}
示例#8
0
static int init_fuse_entry(mount_t * mount, inode_t parent, inode_t cfs_ino, fuse_ino_t fuse_ino, struct fuse_entry_param * e)
{
	int r;

	r = hash_map_insert(mount->parents, (void *) cfs_ino, (void *) parent);
	if (r < 0)
		return r;

	memset(e, 0, sizeof(*e));
	e->ino = fuse_ino;
	e->attr_timeout = STDTIMEOUT;
	e->entry_timeout = STDTIMEOUT;
	r = fill_stat(mount, cfs_ino, e->ino, &e->attr);
	assert(r >= 0);

	return 0;
}
示例#9
0
unsigned long long gs_sizel ( const char* name )
 {
   if ( !fill_stat(name) ) return 0;
   return (unsigned long long)_lstat.st_size;
 }
示例#10
0
gsuint gs_size ( const char* name )
 {
   if ( !fill_stat(name) ) return 0;
   return (gsuint)_lstat.st_size;
 }
示例#11
0
bool gs_isdir ( const char* name )
 {
   if ( !fill_stat(name) ) return false;
   return ( _lstat.st_mode&0170000 )==0040000;
 }
示例#12
0
bool gs_exist ( const char* name )
 {
   return name && *name && fill_stat(name);
 }
示例#13
0
static void serve_setattr(fuse_req_t req, fuse_ino_t fuse_ino, struct stat * attr,
                          int to_set, struct fuse_file_info * fi)
{
	inode_t cfs_ino = fusecfsino(req, fuse_ino);
	int supported = FUSE_SET_ATTR_SIZE;
	bool uid_supported   = feature_supported(reqcfs(req), FSTITCH_FEATURE_UID);
	bool gid_supported   = feature_supported(reqcfs(req), FSTITCH_FEATURE_GID);
	bool perms_supported = feature_supported(reqcfs(req), FSTITCH_FEATURE_UNIX_PERM);
	bool mtime_supported = feature_supported(reqcfs(req), FSTITCH_FEATURE_MTIME);
	bool atime_supported = feature_supported(reqcfs(req), FSTITCH_FEATURE_MTIME);
	struct stat stbuf;
	int r;
	Dprintf("%s(ino = %lu, to_set = %d)\n", __FUNCTION__, fuse_ino, to_set);

	if (uid_supported)
		supported |= FUSE_SET_ATTR_UID;
	if (gid_supported)
		supported |= FUSE_SET_ATTR_GID;
	if (perms_supported)
		supported |= FUSE_SET_ATTR_MODE;
	if (mtime_supported)
		supported |= FUSE_SET_ATTR_MTIME;
	if (atime_supported)
		supported |= FUSE_SET_ATTR_ATIME;

	if (to_set != (to_set & supported))
	{
		r = fuse_reply_err(req, ENOSYS);
		fuse_reply_assert(!r);
		return;
	}

	if (to_set & FUSE_SET_ATTR_SIZE)
	{
		fdesc_t * fdesc;
		uint32_t size;

		size = (uint32_t) attr->st_size;
		assert(size == attr->st_size);
		Dprintf("\tsize = %u\n", size);

		if (fi)
			fdesc = fi_get_fdesc(fi);
		else
		{
			r = CALL(reqcfs(req), open, cfs_ino, 0, &fdesc);
			if (r < 0)
			{
				r = fuse_reply_err(req, -r);
				fuse_reply_assert(!r);
				return;
			}
			fdesc->common->parent = (inode_t) hash_map_find_val(reqmount(req)->parents, (void *) cfs_ino);
			assert(fdesc->common->parent != INODE_NONE);
		}

		r = CALL(reqcfs(req), truncate, fdesc, size);

		if (!fi)
		{
			r = CALL(reqcfs(req), close, fdesc);
			if (r < 0)
			{
				r = fuse_reply_err(req, -r);
				fuse_reply_assert(!r);
				return;
			}
		}

		if (r < 0)
		{
			r = fuse_reply_err(req, -r);
			fuse_reply_assert(!r);
			return;
		}
	}

	fsmetadata_t fsm[5];
	uint32_t nfsm = 0;
	
	if (to_set & FUSE_SET_ATTR_UID)
	{
		fsm[nfsm].fsm_feature = FSTITCH_FEATURE_UID;
		fsm[nfsm].fsm_value.u = attr->st_uid;
		nfsm++;
	}

	if (to_set & FUSE_SET_ATTR_GID)
	{
		fsm[nfsm].fsm_feature = FSTITCH_FEATURE_GID;
		fsm[nfsm].fsm_value.u = attr->st_gid;
		nfsm++;
	}

	if (to_set & FUSE_SET_ATTR_MODE)
	{
		fsm[nfsm].fsm_feature = FSTITCH_FEATURE_UNIX_PERM;
		fsm[nfsm].fsm_value.u = attr->st_mode;
		nfsm++;
	}

	if (to_set & FUSE_SET_ATTR_MTIME)
	{
		fsm[nfsm].fsm_feature = FSTITCH_FEATURE_MTIME;
		fsm[nfsm].fsm_value.u = attr->st_mtime;
		nfsm++;
	}
	
	if (to_set & FUSE_SET_ATTR_ATIME)
	{
		// XXX Why did we use attr->st_mtime here?
		fsm[nfsm].fsm_feature = FSTITCH_FEATURE_ATIME;
		fsm[nfsm].fsm_value.u = attr->st_atime;
		nfsm++;
	}

	if (nfsm > 0) {
		r = CALL(reqcfs(req), set_metadata2, cfs_ino, fsm, nfsm);
		if (r < 0)
		{
			r = fuse_reply_err(req, -r);
			fuse_reply_assert(!r);
			return;
		}
	}

	memset(&stbuf, 0, sizeof(stbuf));
	r = fill_stat(reqmount(req), cfs_ino, fuse_ino, &stbuf);
	if (r < 0)
		r = fuse_reply_err(req, -r);
	else
		r = fuse_reply_attr(req, &stbuf, STDTIMEOUT);
	fuse_reply_assert(!r);
}