static bool cache_file_valid(struct file *f) { char *cp; int result; struct stat st; if(!cache_valid(f)) return false; if(!cache_file_exists(f)) return false; cp = cache_path(f); result = stat(cp, &st); free(cp); if(result != 0) return false; if(f->st->st_mtime > st.st_mtime) return false; return true; }
static int stormfs_chmod(const char *path, mode_t mode) { int result; struct file *f; struct stat st; DEBUG("chmod: %s\n", path); if((result = valid_path(path)) != 0) return result; if((result = stormfs_getattr(path, &st)) != 0) return result; st.st_mode = mode; st.st_ctime = time(NULL); st.st_mtime = time(NULL); if((result = proxy_chmod(path, &st)) != 0) return result; f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_mode = mode; f->st->st_ctime = st.st_ctime; f->st->st_mtime = st.st_mtime; cache_touch(f); pthread_mutex_unlock(&f->lock); } return result; }
static int stormfs_utimens(const char *path, const struct timespec ts[2]) { int result; struct file *f; struct stat st; DEBUG("utimens: %s\n", path); if((result = valid_path(path)) != 0) return result; if((result = stormfs_getattr(path, &st)) != 0) return result; st.st_mtime = ts[1].tv_sec; if((result = proxy_utimens(path, &st)) != 0) return result; f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_mtime = st.st_mtime; cache_touch(f); pthread_mutex_unlock(&f->lock); } return result; }
NSAPI_PUBLIC int dns_cache_valid(dns_cache_entry_t *entry) { time_t now; now = ft_time(); if (now > (time_t)(entry->last_access + dns_expire_time)) return -1; return cache_valid(dns_cache, (cache_entry_t *)entry); }
static int stormfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { struct file *f; DEBUG("write: %s\n", path); f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_size += size; cache_touch(f); pthread_mutex_unlock(&f->lock); } return pwrite(fi->fh, buf, size, offset); }
int stormfs_getattr(const char *path, struct stat *stbuf) { int result; struct file *f = NULL; DEBUG("getattr: %s\n", path); if((result = valid_path(path)) != 0) return result; if(strcmp(path, "/") == 0) { stbuf->st_mode = stormfs.root_mode | S_IFDIR; return 0; } f = cache_get(path); if(cache_valid(f) && f->st != NULL) { memcpy(stbuf, f->st, sizeof(struct stat)); return 0; } if((result = proxy_getattr(path, stbuf)) != 0) return result; stbuf->st_nlink = 1; if(S_ISREG(stbuf->st_mode)) stbuf->st_blocks = get_blocks(stbuf->st_size); pthread_mutex_lock(&f->lock); if(f->st == NULL) f->st = g_new0(struct stat, 1); memcpy(f->st, stbuf, sizeof(struct stat)); cache_touch(f); pthread_mutex_unlock(&f->lock); return 0; }
static int parse_arguments(struct project_cache *pc, int argc, char *argv[]) { if (argc < 2) die("needed atleast one argument. Use -h for usage.\n"); for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { fprintf(stderr, "%s", init_usage); exit(0); } } if (argv[1][0] != '-' && !name_set) { set_project_name(&pc->pd, argv[1]); name_set = 1; } for (int i = 1; i < argc; i++) parse_single_argument(pc, i, argv); if (!cache_valid(pc)) { fatal("error specify a project name.\n"); return -1; } return 0; }
static int stormfs_chown(const char *path, uid_t uid, gid_t gid) { int result = 0; struct file *f; struct stat st; DEBUG("chown: %s\n", path); if((result = valid_path(path)) != 0) return result; if((result = stormfs_getattr(path, &st)) != 0) return result; st.st_uid = uid; st.st_gid = gid; st.st_ctime = time(NULL); st.st_mtime = time(NULL); if((result = proxy_chown(path, &st)) != 0) return result; f = cache_get(path); if(cache_valid(f) && f->st != NULL) { pthread_mutex_lock(&f->lock); f->st->st_uid = uid; f->st->st_gid = gid; f->st->st_ctime = st.st_ctime; f->st->st_mtime = st.st_mtime; cache_touch(f); pthread_mutex_unlock(&f->lock); } return result; }
static int stormfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { int result; struct file *dir; GList *files = NULL, *head = NULL, *next = NULL; DEBUG("readdir: %s\n", path); if((result = valid_path(path)) != 0) return result; filler(buf, ".", 0, 0); filler(buf, "..", 0, 0); dir = cache_get(path); if(cache_valid(dir) && dir->dir != NULL) { pthread_mutex_lock(&dir->lock); head = g_list_first(dir->dir); while(head != NULL) { next = head->next; struct file *f = head->data; filler(buf, (char *) f->name, f->st, 0); head = next; } pthread_mutex_unlock(&dir->lock); return 0; } if((result = proxy_readdir(path, &files)) != 0) return result; result = proxy_getattr_multi(path, files); pthread_mutex_lock(&dir->lock); head = g_list_first(files); while(head != NULL) { next = head->next; // FIXME: list_bucket is using the same structure (file) as // the cache which makes the code below confusing. struct file *file = head->data; char *fullpath = get_path(path, file->name); struct file *f = cache_get(fullpath); free(fullpath); pthread_mutex_lock(&f->lock); if(f->st == NULL) f->st = g_new0(struct stat, 1); memcpy(f->st, file->st, sizeof(struct stat)); f->st->st_nlink = 1; cache_touch(f); pthread_mutex_unlock(&f->lock); filler(buf, (char *) f->name, f->st, 0); dir->dir = g_list_append(dir->dir, f); head = next; } pthread_mutex_unlock(&dir->lock); free_files(files); return result; }