+2004-07-29 Miklos Szeredi <miklos@szeredi.hu>
+
+ * Add fuse_invalidate() to library API
+
2004-07-26 Miklos Szeredi <miklos@szeredi.hu>
* Check permissions in setattr if 'default_permissions' flag is
static int hello_read(const char *path, char *buf, size_t size, off_t offset)
{
+ size_t len;
if(strcmp(path, hello_path) != 0)
return -ENOENT;
- memcpy(buf, hello_str + offset, size);
+ len = strlen(hello_str);
+ if (offset < len) {
+ if (offset + size > len)
+ size = len - offset;
+ memcpy(buf, hello_str + offset, size);
+ } else
+ size = 0;
+
return size;
}
*/
struct fuse *fuse_get(void);
+/**
+ * Invalidate cached data of a file.
+ *
+ * Useful if the 'kernel_cache' mount option is given, since in that
+ * case the cache is not invalidated on file open.
+ *
+ * @return 0 on success or -errno on failure
+ */
+int fuse_invalidate(struct fuse *f, const char *path);
+
/* ----------------------------------------------------------- *
* More detailed API *
* ----------------------------------------------------------- */
struct inode *inode = ilookup(fc->sb, uh->ino);
if (!inode)
return -ENOENT;
+ fuse_sync_inode(inode);
invalidate_inode_pages(inode->i_mapping);
iput(inode);
return 0;
int err = -ENOENT;
if (inode) {
if (INO_FI(inode)) {
+ fuse_sync_inode(inode);
invalidate_inode_pages(inode);
err = 0;
}
return -EINVAL;
}
- if (copy_from_user(&uh, buf, sizeof(struct fuse_out_header)))
+ if (copy_from_user(&uh, buf, sizeof(struct fuse_user_header)))
return -EFAULT;
switch (uh.opcode) {
return node;
}
+static int path_lookup(struct fuse *f, const char *path, fino_t *inop)
+{
+ fino_t ino;
+ int err;
+ char *s;
+ char *name;
+ char *tmp = strdup(path);
+ if (!tmp)
+ return -ENOMEM;
+
+ pthread_mutex_lock(&f->lock);
+ ino = FUSE_ROOT_INO;
+ err = 0;
+ for (s = tmp; (name = strsep(&s, "/")) != NULL; ) {
+ if (name[0]) {
+ struct node *node = __lookup_node(f, ino, name);
+ if (node == NULL) {
+ err = -ENOENT;
+ break;
+ }
+ ino = node->ino;
+ }
+ }
+ pthread_mutex_unlock(&f->lock);
+ free(tmp);
+ if (!err)
+ *inop = ino;
+
+ return err;
+}
+
static char *add_name(char *buf, char *s, const char *name)
{
size_t len = strlen(name);
}
}
+int fuse_invalidate(struct fuse *f, const char *path)
+{
+ int res;
+ int err;
+ fino_t ino;
+ struct fuse_user_header h;
+
+ err = path_lookup(f, path, &ino);
+ if (err) {
+ if (err == -ENOENT)
+ return 0;
+ else
+ return err;
+ }
+
+ memset(&h, 0, sizeof(struct fuse_user_header));
+ h.opcode = FUSE_INVALIDATE;
+ h.ino = ino;
+
+ if ((f->flags & FUSE_DEBUG)) {
+ printf("INVALIDATE ino: %li\n", ino);
+ fflush(stdout);
+ }
+
+ res = write(f->fd, &h, sizeof(struct fuse_user_header));
+ if (res == -1) {
+ if (errno != ENOENT) {
+ perror("fuse: writing device");
+ return -errno;
+ }
+ }
+ return 0;
+}
+
void fuse_exit(struct fuse *f)
{
f->exited = 1;