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; }
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; }
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; }
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; }
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; }
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); }
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); }
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; }
unsigned long long gs_sizel ( const char* name ) { if ( !fill_stat(name) ) return 0; return (unsigned long long)_lstat.st_size; }
gsuint gs_size ( const char* name ) { if ( !fill_stat(name) ) return 0; return (gsuint)_lstat.st_size; }
bool gs_isdir ( const char* name ) { if ( !fill_stat(name) ) return false; return ( _lstat.st_mode&0170000 )==0040000; }
bool gs_exist ( const char* name ) { return name && *name && fill_stat(name); }
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); }