aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorGravatar Feng Shuo <steve.shuo.feng@gmail.com>2013-01-04 16:23:31 +0800
committerGravatar Miklos Szeredi <mszeredi@suse.cz>2013-02-07 14:58:50 +0100
commitf448ac69d1791f4b5c1ce2771624e261cb1797b4 (patch)
tree4c8348915460af579afab632b87887d17d561377 /include
parent914871b20a901e3e1e981c92bc42b1c93b7ab81b (diff)
libfuse: add readdirplus support in fuse_lowlevel_ops
This patch implements readdirplus support in FUSE usersapce. It adds a new fuse lowlevel operations fuse_lowleve_ops::readdir_plus, corespoding mount options and helper functions to maintain buffer. [From: Eric Wong <normalperson@yhbt.net>] This makes our terminology consistent with NFS and our kernel module, as well as reducing user/developer confusion in the command-line. Note: I'm keeping "fuse_add_direntry_plus" since that is less standardized in its use than "readdirplus" for now. Signed-off-by: Feng Shuo <steve.shuo.feng@gmail.com>
Diffstat (limited to 'include')
-rw-r--r--include/fuse_common.h1
-rw-r--r--include/fuse_kernel.h17
-rw-r--r--include/fuse_lowlevel.h54
3 files changed, 71 insertions, 1 deletions
diff --git a/include/fuse_common.h b/include/fuse_common.h
index 58458ab..c8a2409 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -112,6 +112,7 @@ struct fuse_file_info {
#define FUSE_CAP_FLOCK_LOCKS (1 << 10)
#define FUSE_CAP_IOCTL_DIR (1 << 11)
#define FUSE_CAP_AUTO_INVAL_DATA (1 << 12)
+#define FUSE_CAP_READDIRPLUS (1 << 13)
/**
* Ioctl flags
diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h
index df8e9b9..28fefbb 100644
--- a/include/fuse_kernel.h
+++ b/include/fuse_kernel.h
@@ -86,6 +86,9 @@
*
* 7.20
* - add FUSE_AUTO_INVAL_DATA
+ *
+ * 7.21
+ * - add FUSE_READDIRPLUS
*/
#ifndef _LINUX_FUSE_H
@@ -126,7 +129,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 20
+#define FUSE_KERNEL_MINOR_VERSION 21
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -228,6 +231,7 @@ struct fuse_file_lock {
#define FUSE_FLOCK_LOCKS (1 << 10)
#define FUSE_HAS_IOCTL_DIR (1 << 11)
#define FUSE_AUTO_INVAL_DATA (1 << 12)
+#define FUSE_DO_READDIRPLUS (1 << 13)
/**
* CUSE INIT request/reply flags
@@ -334,6 +338,7 @@ enum fuse_opcode {
FUSE_NOTIFY_REPLY = 41,
FUSE_BATCH_FORGET = 42,
FUSE_FALLOCATE = 43,
+ FUSE_READDIRPLUS = 44,
/* CUSE specific operations */
CUSE_INIT = 4096,
@@ -665,6 +670,16 @@ struct fuse_dirent {
#define FUSE_DIRENT_SIZE(d) \
FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+struct fuse_direntplus {
+ struct fuse_entry_out entry_out;
+ struct fuse_dirent dirent;
+};
+
+#define FUSE_NAME_OFFSET_DIRENTPLUS \
+ offsetof(struct fuse_direntplus, dirent.name)
+#define FUSE_DIRENTPLUS_SIZE(d) \
+ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen)
+
struct fuse_notify_inval_inode_out {
__u64 ino;
__s64 off;
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 9a24bcc..22c2e5a 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -1016,6 +1016,32 @@ struct fuse_lowlevel_ops {
*/
void (*fallocate) (fuse_req_t req, fuse_ino_t ino, int mode,
off_t offset, off_t length, struct fuse_file_info *fi);
+
+ /**
+ * Read directory with attributes
+ *
+ * Send a buffer filled using fuse_add_direntry_plus(), with size not
+ * exceeding the requested size. Send an empty buffer on end of
+ * stream.
+ *
+ * fi->fh will contain the value set by the opendir method, or
+ * will be undefined if the opendir method didn't set any value.
+ *
+ * Introduced in version 3.0
+ *
+ * Valid replies:
+ * fuse_reply_buf
+ * fuse_reply_data
+ * fuse_reply_err
+ *
+ * @param req request handle
+ * @param ino the inode number
+ * @param size maximum number of bytes to send
+ * @param off offset to continue reading the directory stream
+ * @param fi file information
+ */
+ void (*readdirplus) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
+ struct fuse_file_info *fi);
};
/**
@@ -1252,6 +1278,34 @@ size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
off_t off);
/**
+ * Add a directory entry to the buffer with the attributes
+ *
+ * Buffer needs to be large enough to hold the entry. If it's not,
+ * then the entry is not filled in but the size of the entry is still
+ * returned. The caller can check this by comparing the bufsize
+ * parameter with the returned entry size. If the entry size is
+ * larger than the buffer size, the operation failed.
+ *
+ * From the 'stbuf' argument the st_ino field and bits 12-15 of the
+ * st_mode field are used. The other fields are ignored.
+ *
+ * Note: offsets do not necessarily represent physical offsets, and
+ * could be any marker, that enables the implementation to find a
+ * specific point in the directory stream.
+ *
+ * @param req request handle
+ * @param buf the point where the new entry will be added to the buffer
+ * @param bufsize remaining size of the buffer
+ * @param name the name of the entry
+ * @param e the directory entry
+ * @param off the offset of the next entry
+ * @return the space needed for the entry
+ */
+size_t fuse_add_direntry_plus(fuse_req_t req, char *buf, size_t bufsize,
+ const char *name,
+ const struct fuse_entry_param *e, off_t off);
+
+/**
* Reply to ask for data fetch and output buffer preparation. ioctl
* will be retried with the specified input data fetched and output
* buffer prepared.