diff --git a/ChangeLog b/ChangeLog index 11eb34a..4131e10 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,11 @@ ChangeLog for davfs2 -------------------- +2014-06-22 Werner Baumann (werner.baumann@onlinehome.de) + * webdav.c, webdav.h, kernel_interface.c, + mount_davfs.c, cache.c, cache.h: + Remove USERINFO, fix stat, remove update_stat. + 2014-06-20 Werner Baumann (werner.baumann@onlinehome.de) * cache.c, cache.h, mount_davfs.c: Pass parameter got_sigterm by reference. diff --git a/src/cache.c b/src/cache.c index 0b919e6..4db418a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -33,6 +33,9 @@ #include #endif #include +#ifdef HAVE_STDINT_H +#include +#endif #include #ifdef HAVE_STDLIB_H #include @@ -346,15 +349,6 @@ update_node(dav_node *node, dav_props *props); static void update_path(dav_node *node, const char *src_path, const char *dst_path); -static inline void -update_stat(off_t size, int sign) -{ - if (!fs_stat->utime) return; - fs_stat->bfree += sign * (size / fs_stat->bsize); - fs_stat->bavail = fs_stat->bfree; - fs_stat->ffree = fs_stat->bfree; -} - /* Get information about node. */ static int @@ -622,16 +616,10 @@ dav_init_cache(const dav_args *args, const char *mpoint) fs_stat = (dav_stat *) xmalloc(sizeof(dav_stat)); fs_stat->blocks = 0x65B9AA; - fs_stat->bfree = 0x32DCD5; fs_stat->bavail = 0x32DCD5; - fs_stat->files = 0; - fs_stat->ffree = 666666; - struct stat cache_st; - if (stat(cache_dir, &cache_st) == 0) { - fs_stat->bsize = cache_st.st_blksize; - } else { - fs_stat->bsize = 4096; - } + fs_stat->n_nodes = 0; + fs_stat->ffree = fs_stat->bavail / 4; + fs_stat->bsize = 4096; fs_stat->namelen = 256; fs_stat->utime = 0; @@ -744,7 +732,7 @@ dav_tidy_cache(void) if (debug) { syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "tidy: %i of %lli nodes changed", nchanged, - (long long int) fs_stat->files); + (long long int) fs_stat->n_nodes); syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "cache-size: %llu MiBytes.", (unsigned long long int) (cache_size + 0x80000) / 0x100000); } @@ -759,7 +747,7 @@ dav_tidy_cache(void) minimize_tree(root); if (debug) syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), - "minimize_tree: %llu nodes remaining", fs_stat->files); + "minimize_tree: %llu nodes remaining", fs_stat->n_nodes); } static dav_node_list_item *item = NULL; @@ -862,10 +850,9 @@ dav_close(dav_node *node, int fd, int flags, pid_t pid, pid_t pgid) return 0; } - update_stat(node->size, 1); attr_from_cache_file(node); set_upload_time(node); - update_stat(node->size, -1); + fs_stat->utime = 0; if (delay_upload == 0 && (is_dirty(node) || is_created(node)) && !is_open_write(node) && !is_backup(node)) { @@ -1208,7 +1195,7 @@ dav_remove(dav_node *parent, const char *name, uid_t uid) if (ret) return ret; - update_stat(node->size, 1); + fs_stat->utime = 0; remove_from_tree(node); remove_from_changed(node); if (is_open(node)) { @@ -1458,16 +1445,20 @@ dav_stat * dav_statfs(void) { if (time(NULL) > (fs_stat->utime + retry)) { - off64_t total = 0; - off64_t used = 0; - if (dav_quota(root->path, &total, &used) == 0) { - fs_stat->blocks = total / fs_stat->bsize; - fs_stat->bfree = fs_stat->blocks - (used / fs_stat->bsize) - 1; - fs_stat->bavail = fs_stat->bfree; - fs_stat->ffree = fs_stat->bfree; + uint64_t available = 0; + uint64_t used = 0; + if (dav_quota(root->path, &available, &used) == 0) { + fs_stat->bavail = available / fs_stat->bsize; + fs_stat->ffree = fs_stat->bavail / 4; + if (used > 0) { + fs_stat->blocks = fs_stat->bavail + (used / fs_stat->bsize); + } else { + fs_stat->blocks = fs_stat->bavail + (fs_stat->n_nodes * 4); + } fs_stat->utime = time(NULL); } } + fs_stat->files = fs_stat->ffree + fs_stat->n_nodes; return fs_stat; } @@ -1708,7 +1699,7 @@ delete_node(dav_node *node) free(tofree); } free(node); - fs_stat->files--; + fs_stat->n_nodes--; } @@ -1987,7 +1978,7 @@ new_node(dav_node *parent, mode_t mode) if (debug) syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG), "new node: %p->%p", node->parent, node); - fs_stat->files++; + fs_stat->n_nodes++; if (next_minimize == 0) next_minimize = node->atime + file_refresh; diff --git a/src/cache.h b/src/cache.h index 882d548..9a781ce 100644 --- a/src/cache.h +++ b/src/cache.h @@ -141,17 +141,14 @@ struct dav_node_item { /* Returned by dav_statfs(). */ typedef struct dav_stat dav_stat; struct dav_stat { - off64_t blocks; - off64_t bfree; - off64_t bavail; - off64_t files; - off64_t ffree; + uint64_t blocks; + uint64_t bavail; + uint64_t files; + uint64_t ffree; + uint64_t n_nodes; off_t bsize; off_t namelen; - time_t utime; /* Time when last updated with data from the server. - must When 0 this structure contains fake data, - that not be changed when a file is changed or - deleted. */ + time_t utime; }; diff --git a/src/kernel_interface.c b/src/kernel_interface.c index dca77f0..3962d1a 100644 --- a/src/kernel_interface.c +++ b/src/kernel_interface.c @@ -1063,19 +1063,10 @@ fuse_stat(void) return sizeof(struct fuse_out_header); } - int nblocks = (buf_size - sizeof(struct fuse_in_header) - - sizeof(struct fuse_write_in) - 4095) / st->bsize; - if (nblocks > 1) { - out->st.blocks = st->blocks / nblocks; - out->st.bfree = st->bfree / nblocks; - out->st.bavail = st->bavail / nblocks; - out->st.bsize = st->bsize * nblocks; - } else { - out->st.blocks = st->blocks; - out->st.bfree = st->bfree; - out->st.bavail = st->bavail; - out->st.bsize = st->bsize; - } + out->st.blocks = st->blocks; + out->st.bfree = st->bavail; + out->st.bavail = st->bavail; + out->st.bsize = st->bsize; out->st.files = st->files; out->st.ffree = st->ffree; out->st.namelen = st->namelen; @@ -1216,7 +1207,6 @@ set_attr(struct fuse_attr *attr, const dav_node *node) attr->uid = node->uid; attr->gid = node->gid; attr->rdev = 0; -/* TODO: set blocksize */ - attr->blksize = 0; + attr->blksize = buf_size - 1024; attr->padding = 0; } diff --git a/src/mount_davfs.c b/src/mount_davfs.c index 91e717a..b6772bd 100644 --- a/src/mount_davfs.c +++ b/src/mount_davfs.c @@ -42,6 +42,9 @@ #endif #include #include +#ifdef HAVE_STDINT_H +#include +#endif #include #ifdef HAVE_STDLIB_H #include diff --git a/src/webdav.c b/src/webdav.c index 51781dc..cfbd8e9 100644 --- a/src/webdav.c +++ b/src/webdav.c @@ -37,6 +37,9 @@ #ifdef HAVE_LIMITS_H #include #endif +#ifdef HAVE_STDINT_H +#include +#endif #include #ifdef HAVE_STDLIB_H #include @@ -103,8 +106,8 @@ typedef struct { typedef struct { int error; - off64_t total; /* Total amount of available bytes. */ - off64_t used; /* Used bytes. */ + uint64_t available; /* Amount of available bytes (quota - used. */ + uint64_t used; /* Used bytes. */ } quota_context; @@ -309,9 +312,6 @@ prop_result(void *userdata, const ne_uri *uri, const ne_prop_result_set *set); static void quota_result(void *userdata, const ne_uri *uri, const ne_prop_result_set *set); -static int -quota_reader(void *userdata, const char *block, size_t length); - static int ssl_verify(void *userdata, int failures, const ne_ssl_certificate *cert); @@ -1056,7 +1056,7 @@ dav_put(const char *path, const char *cache_path, int *exists, time_t *expire, int -dav_quota(const char *path, off64_t *total, off64_t *used) +dav_quota(const char *path, uint64_t *available, uint64_t *used) { int ret; if (!initialized) { @@ -1065,14 +1065,13 @@ dav_quota(const char *path, off64_t *total, off64_t *used) } static int use_rfc = 1; - static int use_userinfo = 1; - if (!use_rfc && !use_userinfo) + if (!use_rfc) return EIO; quota_context ctx; ctx.error = 0; - ctx.total = 0; + ctx.available = 0; ctx.used = 0; ret = EIO; char *spath = ne_path_escape(path); @@ -1091,24 +1090,8 @@ dav_quota(const char *path, off64_t *total, off64_t *used) } } - if (ret && use_userinfo) { - ctx.error = 0; - ne_request *req = ne_request_create(session, "USERINFO", spath); - ne_add_response_body_reader(req, ne_accept_2xx, quota_reader, &ctx); - ret = ne_request_dispatch(req); - ret = get_error(ret, "USERINFO"); - ne_request_destroy(req); - - if (!ret) { - if (ctx.error) - ret = EIO; - } else if (ret != EAGAIN) { - use_userinfo = 0; - } - } - if (!ret) { - *total = ctx.total; + *available = ctx.available; *used = ctx.used; } @@ -1771,36 +1754,6 @@ prop_result(void *userdata, const ne_uri *uri, const ne_prop_result_set *set) } -static int -quota_reader(void *userdata, const char *block, size_t length) -{ - if (length < 1) return 0; - quota_context *ctx = (quota_context *) userdata; - - char *quota = strndup(block, length); - if (!quota) { - ctx->error = 1; - return 0; - } - - char *number = strtok(quota, ","); - if (number) { - ctx->total = strtoull(number, NULL, 10); - } else { - ctx->error = 1; - free(quota); - return 0; - } - - number = strtok(NULL, ","); - if (number) - ctx->used = strtoull(number, NULL, 10); - - free(quota); - return 0; -} - - /* Reads available and used bytes from set and stores them in userdata. */ static void @@ -1812,7 +1765,7 @@ quota_result(void *userdata, const ne_uri *uri, const ne_prop_result_set *set) const char *data = ne_propset_value(set, "a_names[AVAILABLE]); if (data) { - ctx->total = strtoull(data, NULL, 10); + ctx->available = strtoull(data, NULL, 10); } else { const ne_status *st = ne_propset_status(set, "a_names[AVAILABLE]); if (st && st->klass == 4) { @@ -1826,8 +1779,6 @@ quota_result(void *userdata, const ne_uri *uri, const ne_prop_result_set *set) data = ne_propset_value(set, "a_names[USED]); if (data) ctx->used = strtoull(data, NULL, 10); - - ctx->total += ctx->used; } diff --git a/src/webdav.h b/src/webdav.h index 890eba2..293d9a9 100644 --- a/src/webdav.h +++ b/src/webdav.h @@ -236,12 +236,11 @@ dav_put(const char *path, const char *cache_path, int *exists, time_t *expire, char **etag, time_t *mtime); /* Makes a PROPFIND request for path to get quota information (RFC 4331) - and places them in total and used. - toatal is the sum of quota-available-bytes and quota-used-bytes. - If quota information is not - available, an error is returned and available and used are not changed. */ + and places them in available and used. + If quota information is not available, an error is returned and + available and used are not changed. */ int -dav_quota(const char *path, off_t *total, off_t *used); +dav_quota(const char *path, uint64_t *available, uint64_t *used); /* Tells webdav that no more terminal is available, so errors can only