From e34c133ec6053025124416a3861f9f4c4f7fd772 Mon Sep 17 00:00:00 2001 From: Dees_Troy Date: Wed, 6 Feb 2013 19:13:00 +0000 Subject: Add write buffer for tar writes update fuse to 2.9.2 catch return from unlink so that we don't print error messages when things work Change-Id: I1115039a0fa5d9d73f78ef1abd79755d7ffd9d96 --- fuse/include/fuse_lowlevel.h | 288 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 274 insertions(+), 14 deletions(-) (limited to 'fuse/include/fuse_lowlevel.h') diff --git a/fuse/include/fuse_lowlevel.h b/fuse/include/fuse_lowlevel.h index f1cfeb954..36cf26ddf 100644 --- a/fuse/include/fuse_lowlevel.h +++ b/fuse/include/fuse_lowlevel.h @@ -77,9 +77,16 @@ struct fuse_entry_param { /** Generation number for this entry. * - * The ino/generation pair should be unique for the filesystem's - * lifetime. It must be non-zero, otherwise FUSE will treat it as an - * error. + * If the file system will be exported over NFS, the + * ino/generation pairs need to be unique over the file + * system's lifetime (rather than just the mount time). So if + * the file system reuses an inode after it has been deleted, + * it must assign a new, previously unused generation number + * to the inode at the same time. + * + * The generation must be non-zero, otherwise FUSE will treat + * it as an error. + * */ unsigned long generation; @@ -114,6 +121,11 @@ struct fuse_ctx { mode_t umask; }; +struct fuse_forget_data { + uint64_t ino; + uint64_t nlookup; +}; + /* 'to_set' flags in setattr */ #define FUSE_SET_ATTR_MODE (1 << 0) #define FUSE_SET_ATTR_UID (1 << 1) @@ -188,18 +200,31 @@ struct fuse_lowlevel_ops { /** * Forget about an inode * - * The nlookup parameter indicates the number of lookups - * previously performed on this inode. + * This function is called when the kernel removes an inode + * from its internal caches. * - * If the filesystem implements inode lifetimes, it is recommended - * that inodes acquire a single reference on each lookup, and lose - * nlookup references on each forget. + * The inode's lookup count increases by one for every call to + * fuse_reply_entry and fuse_reply_create. The nlookup parameter + * indicates by how much the lookup count should be decreased. * - * The filesystem may ignore forget calls, if the inodes don't - * need to have a limited lifetime. + * Inodes with a non-zero lookup count may receive request from + * the kernel even after calls to unlink, rmdir or (when + * overwriting an existing file) rename. Filesystems must handle + * such requests properly and it is recommended to defer removal + * of the inode until the lookup count reaches zero. Calls to + * unlink, remdir or rename will be followed closely by forget + * unless the file or directory is open, in which case the + * kernel issues forget only after the release or releasedir + * calls. * - * On unmount it is not guaranteed, that all referenced inodes - * will receive a forget message. + * Note that if a file system will be exported over NFS the + * inodes lifetime must extend even beyond forget. See the + * generation field in struct fuse_entry_param above. + * + * On unmount the lookup count for all inodes implicitly drops + * to zero. It is not guaranteed that the file system will + * receive corresponding forget messages for the affected + * inodes. * * Valid replies: * fuse_reply_none @@ -303,6 +328,11 @@ struct fuse_lowlevel_ops { /** * Remove a file * + * If the file's inode's lookup count is non-zero, the file + * system is expected to postpone any removal of the inode + * until the lookup count reaches zero (see description of the + * forget function). + * * Valid replies: * fuse_reply_err * @@ -315,6 +345,11 @@ struct fuse_lowlevel_ops { /** * Remove a directory * + * If the directory's inode's lookup count is non-zero, the + * file system is expected to postpone any removal of the + * inode until the lookup count reaches zero (see description + * of the forget function). + * * Valid replies: * fuse_reply_err * @@ -340,6 +375,12 @@ struct fuse_lowlevel_ops { const char *name); /** Rename a file + * + * If the target exists it should be atomically replaced. If + * the target's inode's lookup count is non-zero, the file + * system is expected to postpone any removal of the inode + * until the lookup count reaches zero (see description of the + * forget function). * * Valid replies: * fuse_reply_err @@ -412,6 +453,7 @@ struct fuse_lowlevel_ops { * Valid replies: * fuse_reply_buf * fuse_reply_iov + * fuse_reply_data * fuse_reply_err * * @param req request handle @@ -561,6 +603,7 @@ struct fuse_lowlevel_ops { * * Valid replies: * fuse_reply_buf + * fuse_reply_data * fuse_reply_err * * @param req request handle @@ -646,6 +689,7 @@ struct fuse_lowlevel_ops { * * Valid replies: * fuse_reply_buf + * fuse_reply_data * fuse_reply_xattr * fuse_reply_err * @@ -672,6 +716,7 @@ struct fuse_lowlevel_ops { * * Valid replies: * fuse_reply_buf + * fuse_reply_data * fuse_reply_xattr * fuse_reply_err * @@ -787,7 +832,7 @@ struct fuse_lowlevel_ops { * @param req request handle * @param ino the inode number * @param fi file information - * @param lock the region/type to test + * @param lock the region/type to set * @param sleep locking operation may sleep */ void (*setlk) (fuse_req_t req, fuse_ino_t ino, @@ -873,6 +918,104 @@ struct fuse_lowlevel_ops { */ void (*poll) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi, struct fuse_pollhandle *ph); + + /** + * Write data made available in a buffer + * + * This is a more generic version of the ->write() method. If + * FUSE_CAP_SPLICE_READ is set in fuse_conn_info.want and the + * kernel supports splicing from the fuse device, then the + * data will be made available in pipe for supporting zero + * copy data transfer. + * + * Introduced in version 2.9 + * + * Valid replies: + * fuse_reply_write + * fuse_reply_err + * + * @param req request handle + * @param ino the inode number + * @param bufv buffer containing the data + * @param off offset to write to + * @param fi file information + */ + void (*write_buf) (fuse_req_t req, fuse_ino_t ino, + struct fuse_bufvec *bufv, off64_t off, + struct fuse_file_info *fi); + + /** + * Callback function for the retrieve request + * + * Introduced in version 2.9 + * + * Valid replies: + * fuse_reply_none + * + * @param req request handle + * @param cookie user data supplied to fuse_lowlevel_notify_retrieve() + * @param ino the inode number supplied to fuse_lowlevel_notify_retrieve() + * @param offset the offset supplied to fuse_lowlevel_notify_retrieve() + * @param bufv the buffer containing the returned data + */ + void (*retrieve_reply) (fuse_req_t req, void *cookie, fuse_ino_t ino, + off64_t offset, struct fuse_bufvec *bufv); + + /** + * Forget about multiple inodes + * + * See description of the forget function for more + * information. + * + * Introduced in version 2.9 + * + * Valid replies: + * fuse_reply_none + * + * @param req request handle + */ + void (*forget_multi) (fuse_req_t req, size_t count, + struct fuse_forget_data *forgets); + + /** + * Acquire, modify or release a BSD file lock + * + * Note: if the locking methods are not implemented, the kernel + * will still allow file locking to work locally. Hence these are + * only interesting for network filesystems and similar. + * + * Introduced in version 2.9 + * + * Valid replies: + * fuse_reply_err + * + * @param req request handle + * @param ino the inode number + * @param fi file information + * @param op the locking operation, see flock(2) + */ + void (*flock) (fuse_req_t req, fuse_ino_t ino, + struct fuse_file_info *fi, int op); + + /** + * Allocate requested space. If this function returns success then + * subsequent writes to the specified range shall not fail due to the lack + * of free space on the file system storage media. + * + * Introduced in version 2.9 + * + * Valid replies: + * fuse_reply_err + * + * @param req request handle + * @param ino the inode number + * @param offset starting point for allocated region + * @param length size of allocated region + * @param mode determines the operation to be performed on the given range, + * see fallocate(2) + */ + void (*fallocate) (fuse_req_t req, fuse_ino_t ino, int mode, + off64_t offset, off64_t length, struct fuse_file_info *fi); }; /** @@ -906,6 +1049,9 @@ void fuse_reply_none(fuse_req_t req); * Possible requests: * lookup, mknod, mkdir, symlink, link * + * Side effects: + * increments the lookup count on success + * * @param req request handle * @param e the entry parameters * @return zero for success, -errno for failure to send reply @@ -921,6 +1067,9 @@ int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e); * Possible requests: * create * + * Side effects: + * increments the lookup count on success + * * @param req request handle * @param e the entry parameters * @param fi file information @@ -995,6 +1144,20 @@ int fuse_reply_write(fuse_req_t req, size_t count); */ int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size); +/** + * Reply with data copied/moved from buffer(s) + * + * Possible requests: + * read, readdir, getxattr, listxattr + * + * @param req request handle + * @param bufv buffer vector + * @param flags flags controlling the copy + * @return zero for success, -errno for failure to send reply + */ +int fuse_reply_data(fuse_req_t req, struct fuse_bufvec *bufv, + enum fuse_buf_copy_flags flags); + /** * Reply with data vector * @@ -1042,7 +1205,7 @@ int fuse_reply_xattr(fuse_req_t req, size_t count); * @param lock the lock information * @return zero for success, -errno for failure to send reply */ -int fuse_reply_lock(fuse_req_t req, struct flock *lock); +int fuse_reply_lock(fuse_req_t req, const struct flock *lock); /** * Reply with block index @@ -1181,6 +1344,75 @@ int fuse_lowlevel_notify_inval_inode(struct fuse_chan *ch, fuse_ino_t ino, int fuse_lowlevel_notify_inval_entry(struct fuse_chan *ch, fuse_ino_t parent, const char *name, size_t namelen); +/** + * Notify to invalidate parent attributes and delete the dentry matching + * parent/name if the dentry's inode number matches child (otherwise it + * will invalidate the matching dentry). + * + * @param ch the channel through which to send the notification + * @param parent inode number + * @param child inode number + * @param name file name + * @param namelen strlen() of file name + * @return zero for success, -errno for failure + */ +int fuse_lowlevel_notify_delete(struct fuse_chan *ch, + fuse_ino_t parent, fuse_ino_t child, + const char *name, size_t namelen); + +/** + * Store data to the kernel buffers + * + * Synchronously store data in the kernel buffers belonging to the + * given inode. The stored data is marked up-to-date (no read will be + * performed against it, unless it's invalidated or evicted from the + * cache). + * + * If the stored data overflows the current file size, then the size + * is extended, similarly to a write(2) on the filesystem. + * + * If this function returns an error, then the store wasn't fully + * completed, but it may have been partially completed. + * + * @param ch the channel through which to send the invalidation + * @param ino the inode number + * @param offset the starting offset into the file to store to + * @param bufv buffer vector + * @param flags flags controlling the copy + * @return zero for success, -errno for failure + */ +int fuse_lowlevel_notify_store(struct fuse_chan *ch, fuse_ino_t ino, + off64_t offset, struct fuse_bufvec *bufv, + enum fuse_buf_copy_flags flags); +/** + * Retrieve data from the kernel buffers + * + * Retrieve data in the kernel buffers belonging to the given inode. + * If successful then the retrieve_reply() method will be called with + * the returned data. + * + * Only present pages are returned in the retrieve reply. Retrieving + * stops when it finds a non-present page and only data prior to that is + * returned. + * + * If this function returns an error, then the retrieve will not be + * completed and no reply will be sent. + * + * This function doesn't change the dirty state of pages in the kernel + * buffer. For dirty pages the write() method will be called + * regardless of having been retrieved previously. + * + * @param ch the channel through which to send the invalidation + * @param ino the inode number + * @param size the number of bytes to retrieve + * @param offset the starting offset into the file to retrieve from + * @param cookie user data to supply to the reply callback + * @return zero for success, -errno for failure + */ +int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, fuse_ino_t ino, + size_t size, off64_t offset, void *cookie); + + /* ----------------------------------------------------------- * * Utility functions * * ----------------------------------------------------------- */ @@ -1376,6 +1608,34 @@ struct fuse_chan *fuse_session_next_chan(struct fuse_session *se, void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, struct fuse_chan *ch); +/** + * Process a raw request supplied in a generic buffer + * + * This is a more generic version of fuse_session_process(). The + * fuse_buf may contain a memory buffer or a pipe file descriptor. + * + * @param se the session + * @param buf the fuse_buf containing the request + * @param ch channel on which the request was received + */ +void fuse_session_process_buf(struct fuse_session *se, + const struct fuse_buf *buf, struct fuse_chan *ch); + +/** + * Receive a raw request supplied in a generic buffer + * + * This is a more generic version of fuse_chan_recv(). The fuse_buf + * supplied to this function contains a suitably allocated memory + * buffer. This may be overwritten with a file descriptor buffer. + * + * @param se the session + * @param buf the fuse_buf to store the request in + * @param chp pointer to the channel + * @return the actual size of the raw request, or -errno on error + */ +int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf, + struct fuse_chan **chp); + /** * Destroy a session * -- cgit v1.2.3