Update ino_path for the large cursor

Previously we could iterate over backref items with a small u64.  Now we
need a larger opaque buffer.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-02-03 13:34:38 -08:00
parent 16da3c182a
commit 02993a2dd7
2 changed files with 61 additions and 5 deletions

View File

@@ -18,7 +18,8 @@ static int ino_path_cmd(int argc, char **argv)
{
struct scoutfs_ioctl_ino_path args;
char *endptr = NULL;
char *path;
char *path = NULL;
char *curs = NULL;
u64 ino;
int ret;
int fd;
@@ -51,9 +52,18 @@ static int ino_path_cmd(int argc, char **argv)
goto out;
}
curs = calloc(1, SCOUTFS_IOC_INO_PATH_CURSOR_BYTES);
if (!curs) {
fprintf(stderr, "couldn't allocate %ld byte cursor\n",
SCOUTFS_IOC_INO_PATH_CURSOR_BYTES);
ret = -ENOMEM;
goto out;
}
args.ino = ino;
args.ctr = 0;
args.cursor_ptr = (intptr_t)curs;
args.path_ptr = (intptr_t)path;
args.cursor_bytes = SCOUTFS_IOC_INO_PATH_CURSOR_BYTES;
args.path_bytes = PATH_MAX;
do {
ret = ioctl(fd, SCOUTFS_IOC_INO_PATH, &args);
@@ -68,6 +78,7 @@ static int ino_path_cmd(int argc, char **argv)
}
out:
free(path);
free(curs);
close(fd);
return ret;
};

View File

@@ -1,6 +1,8 @@
#ifndef _SCOUTFS_IOCTL_H_
#define _SCOUTFS_IOCTL_H_
#include "format.h"
/* XXX I have no idea how these are chosen. */
#define SCOUTFS_IOCTL_MAGIC 's'
@@ -24,18 +26,61 @@ struct scoutfs_ioctl_inodes_since {
#define SCOUTFS_IOC_INODES_SINCE _IOW(SCOUTFS_IOCTL_MAGIC, 1, \
struct scoutfs_ioctl_inodes_since)
/* returns bytes of path buffer set starting at _off, including null */
/*
* Fill the path buffer with the next path to the target inode. An
* iteration cursor is stored in the cursor buffer which advances
* through the paths to the inode at each call.
*
* @ino: The target ino that we're finding paths to. Constant across
* all the calls that make up an iteration over all the inode's paths.
*
* @cursor_ptr: A pointer to the buffer that will hold the iteration
* cursor. It must be initialized to 0 before iterating. Each call
* modifies it to skip past the result of that call.
*
* @cusur_bytes: The length of the cursor buffer. Must be
* SCOUTFS_IOC_INO_PATH_CURSOR_BYTES.
*
* @path_ptr: The buffer to store each found path.
*
* @path_bytes: The size of the buffer that will the found path
* including null termination. (PATH_MAX is a solid choice.)
*
* This only walks back through full hard links. None of the returned
* paths will reflect symlinks to components in the path.
*
* This doesn't ensure that the caller has permissions to traverse the
* returned paths to the inode. It requires CAP_DAC_READ_SEARCH which
* bypasses permissions checking.
*
* ENAMETOOLONG is returned when the next path found from the cursor
* doesn't fit in the path buffer.
*
* This call is not serialized with any modification (create, rename,
* unlink) of the path components. It will return all the paths that
* were stable both before and after the call. It may or may not return
* paths which are created or unlinked during the call.
*
* The number of bytes in the path, including the null terminator, are
* returned when a path is found. 0 is returned when there are no more
* paths to the link to the inode from the cursor.
*/
struct scoutfs_ioctl_ino_path {
__u64 ino;
__u64 ctr; /* init to 0, set to next */
__u64 cursor_ptr;
__u64 path_ptr;
__u16 path_bytes; /* total buffer space, including null term */
__u16 cursor_bytes;
__u16 path_bytes;
} __packed;
#define SCOUTFS_IOC_INO_PATH_CURSOR_BYTES \
(sizeof(u64) + SCOUTFS_NAME_LEN + 1)
/* Get a single path from the root to the given inode number */
#define SCOUTFS_IOC_INO_PATH _IOW(SCOUTFS_IOCTL_MAGIC, 2, \
struct scoutfs_ioctl_ino_path)
/* XXX might as well include a seq? 0 for current behaviour? */
struct scoutfs_ioctl_find_xattr {
__u64 first_ino;