// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2017 Omnibond Systems, L.L.C. */ #include "protocol.h" #include "orangefs-kernel.h" #include "orangefs-bufmap.h" struct orangefs_dir_part { … }; struct orangefs_dir { … }; #define PART_SHIFT … #define PART_SIZE … #define PART_MASK … /* * There can be up to 512 directory entries. Each entry is encoded as * follows: * 4 bytes: string size (n) * n bytes: string * 1 byte: trailing zero * padding to 8 bytes * 16 bytes: khandle * padding to 8 bytes * * The trailer_buf starts with a struct orangefs_readdir_response_s * which must be skipped to get to the directory data. * * The data which is received from the userspace daemon is termed a * part and is stored in a linked list in case more than one part is * needed for a large directory. * * The position pointer (ctx->pos) encodes the part and offset on which * to begin reading at. Bits above PART_SHIFT encode the part and bits * below PART_SHIFT encode the offset. Parts are stored in a linked * list which grows as data is received from the server. The overhead * associated with managing the list is presumed to be small compared to * the overhead of communicating with the server. * * As data is received from the server, it is placed at the end of the * part list. Data is parsed from the current position as it is needed. * When data is determined to be corrupt, it is either because the * userspace component has sent back corrupt data or because the file * pointer has been moved to an invalid location. Since the two cannot * be differentiated, return EIO. * * Part zero is synthesized to contains `.' and `..'. Part one is the * first part of the part list. */ static int do_readdir(struct orangefs_dir *od, struct inode *inode, struct orangefs_kernel_op_s *op) { … } static int parse_readdir(struct orangefs_dir *od, struct orangefs_kernel_op_s *op) { … } static int orangefs_dir_more(struct orangefs_dir *od, struct inode *inode) { … } static int fill_from_part(struct orangefs_dir_part *part, struct dir_context *ctx) { … } static int orangefs_dir_fill(struct orangefs_dir *od, struct dir_context *ctx) { … } static loff_t orangefs_dir_llseek(struct file *file, loff_t offset, int whence) { … } static int orangefs_dir_iterate(struct file *file, struct dir_context *ctx) { … } static int orangefs_dir_open(struct inode *inode, struct file *file) { … } static int orangefs_dir_release(struct inode *inode, struct file *file) { … } const struct file_operations orangefs_dir_operations = …;