linux/fs/orangefs/orangefs-kernel.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * (C) 2001 Clemson University and The University of Chicago
   4 *
   5 * See COPYING in top-level directory.
   6 */
   7
   8/*
   9 *  The ORANGEFS Linux kernel support allows ORANGEFS volumes to be mounted and
  10 *  accessed through the Linux VFS (i.e. using standard I/O system calls).
  11 *  This support is only needed on clients that wish to mount the file system.
  12 *
  13 */
  14
  15/*
  16 *  Declarations and macros for the ORANGEFS Linux kernel support.
  17 */
  18
  19#ifndef __ORANGEFSKERNEL_H
  20#define __ORANGEFSKERNEL_H
  21
  22#include <linux/kernel.h>
  23#include <linux/moduleparam.h>
  24#include <linux/statfs.h>
  25#include <linux/backing-dev.h>
  26#include <linux/device.h>
  27#include <linux/mpage.h>
  28#include <linux/namei.h>
  29#include <linux/errno.h>
  30#include <linux/init.h>
  31#include <linux/module.h>
  32#include <linux/slab.h>
  33#include <linux/types.h>
  34#include <linux/fs.h>
  35#include <linux/vmalloc.h>
  36
  37#include <linux/aio.h>
  38#include <linux/posix_acl.h>
  39#include <linux/posix_acl_xattr.h>
  40#include <linux/compat.h>
  41#include <linux/mount.h>
  42#include <linux/uaccess.h>
  43#include <linux/atomic.h>
  44#include <linux/uio.h>
  45#include <linux/sched/signal.h>
  46#include <linux/mm.h>
  47#include <linux/wait.h>
  48#include <linux/dcache.h>
  49#include <linux/pagemap.h>
  50#include <linux/poll.h>
  51#include <linux/rwsem.h>
  52#include <linux/xattr.h>
  53#include <linux/exportfs.h>
  54
  55#include <asm/unaligned.h>
  56
  57#include "orangefs-dev-proto.h"
  58
  59#define ORANGEFS_DEFAULT_OP_TIMEOUT_SECS       20
  60
  61#define ORANGEFS_BUFMAP_WAIT_TIMEOUT_SECS   30
  62
  63#define ORANGEFS_DEFAULT_SLOT_TIMEOUT_SECS     900      /* 15 minutes */
  64
  65#define ORANGEFS_REQDEVICE_NAME          "pvfs2-req"
  66
  67#define ORANGEFS_DEVREQ_MAGIC             0x20030529
  68#define ORANGEFS_PURGE_RETRY_COUNT     0x00000005
  69
  70#define MAX_DEV_REQ_UPSIZE (2 * sizeof(__s32) +   \
  71sizeof(__u64) + sizeof(struct orangefs_upcall_s))
  72#define MAX_DEV_REQ_DOWNSIZE (2 * sizeof(__s32) + \
  73sizeof(__u64) + sizeof(struct orangefs_downcall_s))
  74
  75/*
  76 * valid orangefs kernel operation states
  77 *
  78 * unknown  - op was just initialized
  79 * waiting  - op is on request_list (upward bound)
  80 * inprogr  - op is in progress (waiting for downcall)
  81 * serviced - op has matching downcall; ok
  82 * purged   - op has to start a timer since client-core
  83 *            exited uncleanly before servicing op
  84 * given up - submitter has given up waiting for it
  85 */
  86enum orangefs_vfs_op_states {
  87        OP_VFS_STATE_UNKNOWN = 0,
  88        OP_VFS_STATE_WAITING = 1,
  89        OP_VFS_STATE_INPROGR = 2,
  90        OP_VFS_STATE_SERVICED = 4,
  91        OP_VFS_STATE_PURGED = 8,
  92        OP_VFS_STATE_GIVEN_UP = 16,
  93};
  94
  95/*
  96 * orangefs kernel memory related flags
  97 */
  98
  99#if (defined CONFIG_DEBUG_SLAB)
 100#define ORANGEFS_CACHE_CREATE_FLAGS SLAB_RED_ZONE
 101#else
 102#define ORANGEFS_CACHE_CREATE_FLAGS 0
 103#endif
 104
 105extern int orangefs_init_acl(struct inode *inode, struct inode *dir);
 106extern const struct xattr_handler *orangefs_xattr_handlers[];
 107
 108extern struct posix_acl *orangefs_get_acl(struct inode *inode, int type);
 109extern int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
 110
 111/*
 112 * orangefs data structures
 113 */
 114struct orangefs_kernel_op_s {
 115        enum orangefs_vfs_op_states op_state;
 116        __u64 tag;
 117
 118        /*
 119         * Set uses_shared_memory to non zero if this operation uses
 120         * shared memory. If true, then a retry on the op must also
 121         * get a new shared memory buffer and re-populate it.
 122         * Cancels don't care - it only matters for service_operation()
 123         * retry logics and cancels don't go through it anymore. It
 124         * safely stays non-zero when we use it as slot_to_free.
 125         */
 126        union {
 127                int uses_shared_memory;
 128                int slot_to_free;
 129        };
 130
 131        struct orangefs_upcall_s upcall;
 132        struct orangefs_downcall_s downcall;
 133
 134        struct completion waitq;
 135        spinlock_t lock;
 136
 137        int attempts;
 138
 139        struct list_head list;
 140};
 141
 142#define set_op_state_waiting(op)     ((op)->op_state = OP_VFS_STATE_WAITING)
 143#define set_op_state_inprogress(op)  ((op)->op_state = OP_VFS_STATE_INPROGR)
 144#define set_op_state_given_up(op)  ((op)->op_state = OP_VFS_STATE_GIVEN_UP)
 145static inline void set_op_state_serviced(struct orangefs_kernel_op_s *op)
 146{
 147        op->op_state = OP_VFS_STATE_SERVICED;
 148        complete(&op->waitq);
 149}
 150
 151#define op_state_waiting(op)     ((op)->op_state & OP_VFS_STATE_WAITING)
 152#define op_state_in_progress(op) ((op)->op_state & OP_VFS_STATE_INPROGR)
 153#define op_state_serviced(op)    ((op)->op_state & OP_VFS_STATE_SERVICED)
 154#define op_state_purged(op)      ((op)->op_state & OP_VFS_STATE_PURGED)
 155#define op_state_given_up(op)    ((op)->op_state & OP_VFS_STATE_GIVEN_UP)
 156#define op_is_cancel(op)         ((op)->upcall.type == ORANGEFS_VFS_OP_CANCEL)
 157
 158void op_release(struct orangefs_kernel_op_s *op);
 159
 160extern void orangefs_bufmap_put(int);
 161static inline void put_cancel(struct orangefs_kernel_op_s *op)
 162{
 163        orangefs_bufmap_put(op->slot_to_free);
 164        op_release(op);
 165}
 166
 167static inline void set_op_state_purged(struct orangefs_kernel_op_s *op)
 168{
 169        spin_lock(&op->lock);
 170        if (unlikely(op_is_cancel(op))) {
 171                list_del_init(&op->list);
 172                spin_unlock(&op->lock);
 173                put_cancel(op);
 174        } else {
 175                op->op_state |= OP_VFS_STATE_PURGED;
 176                complete(&op->waitq);
 177                spin_unlock(&op->lock);
 178        }
 179}
 180
 181/* per inode private orangefs info */
 182struct orangefs_inode_s {
 183        struct orangefs_object_kref refn;
 184        char link_target[ORANGEFS_NAME_MAX];
 185        /*
 186         * Reading/Writing Extended attributes need to acquire the appropriate
 187         * reader/writer semaphore on the orangefs_inode_s structure.
 188         */
 189        struct rw_semaphore xattr_sem;
 190
 191        struct inode vfs_inode;
 192        sector_t last_failed_block_index_read;
 193
 194        unsigned long getattr_time;
 195        u32 getattr_mask;
 196};
 197
 198/* per superblock private orangefs info */
 199struct orangefs_sb_info_s {
 200        struct orangefs_khandle root_khandle;
 201        __s32 fs_id;
 202        int id;
 203        int flags;
 204#define ORANGEFS_OPT_INTR       0x01
 205#define ORANGEFS_OPT_LOCAL_LOCK 0x02
 206        char devname[ORANGEFS_MAX_SERVER_ADDR_LEN];
 207        struct super_block *sb;
 208        int mount_pending;
 209        int no_list;
 210        struct list_head list;
 211};
 212
 213struct orangefs_stats {
 214        unsigned long cache_hits;
 215        unsigned long cache_misses;
 216        unsigned long reads;
 217        unsigned long writes;
 218};
 219
 220extern struct orangefs_stats orangefs_stats;
 221
 222/*
 223 * NOTE: See Documentation/filesystems/porting for information
 224 * on implementing FOO_I and properly accessing fs private data
 225 */
 226static inline struct orangefs_inode_s *ORANGEFS_I(struct inode *inode)
 227{
 228        return container_of(inode, struct orangefs_inode_s, vfs_inode);
 229}
 230
 231static inline struct orangefs_sb_info_s *ORANGEFS_SB(struct super_block *sb)
 232{
 233        return (struct orangefs_sb_info_s *) sb->s_fs_info;
 234}
 235
 236/* ino_t descends from "unsigned long", 8 bytes, 64 bits. */
 237static inline ino_t orangefs_khandle_to_ino(struct orangefs_khandle *khandle)
 238{
 239        union {
 240                unsigned char u[8];
 241                __u64 ino;
 242        } ihandle;
 243
 244        ihandle.u[0] = khandle->u[0] ^ khandle->u[4];
 245        ihandle.u[1] = khandle->u[1] ^ khandle->u[5];
 246        ihandle.u[2] = khandle->u[2] ^ khandle->u[6];
 247        ihandle.u[3] = khandle->u[3] ^ khandle->u[7];
 248        ihandle.u[4] = khandle->u[12] ^ khandle->u[8];
 249        ihandle.u[5] = khandle->u[13] ^ khandle->u[9];
 250        ihandle.u[6] = khandle->u[14] ^ khandle->u[10];
 251        ihandle.u[7] = khandle->u[15] ^ khandle->u[11];
 252
 253        return ihandle.ino;
 254}
 255
 256static inline struct orangefs_khandle *get_khandle_from_ino(struct inode *inode)
 257{
 258        return &(ORANGEFS_I(inode)->refn.khandle);
 259}
 260
 261static inline int is_root_handle(struct inode *inode)
 262{
 263        gossip_debug(GOSSIP_DCACHE_DEBUG,
 264                     "%s: root handle: %pU, this handle: %pU:\n",
 265                     __func__,
 266                     &ORANGEFS_SB(inode->i_sb)->root_khandle,
 267                     get_khandle_from_ino(inode));
 268
 269        if (ORANGEFS_khandle_cmp(&(ORANGEFS_SB(inode->i_sb)->root_khandle),
 270                             get_khandle_from_ino(inode)))
 271                return 0;
 272        else
 273                return 1;
 274}
 275
 276static inline int match_handle(struct orangefs_khandle resp_handle,
 277                               struct inode *inode)
 278{
 279        gossip_debug(GOSSIP_DCACHE_DEBUG,
 280                     "%s: one handle: %pU, another handle:%pU:\n",
 281                     __func__,
 282                     &resp_handle,
 283                     get_khandle_from_ino(inode));
 284
 285        if (ORANGEFS_khandle_cmp(&resp_handle, get_khandle_from_ino(inode)))
 286                return 0;
 287        else
 288                return 1;
 289}
 290
 291/*
 292 * defined in orangefs-cache.c
 293 */
 294int op_cache_initialize(void);
 295int op_cache_finalize(void);
 296struct orangefs_kernel_op_s *op_alloc(__s32 type);
 297void orangefs_new_tag(struct orangefs_kernel_op_s *op);
 298char *get_opname_string(struct orangefs_kernel_op_s *new_op);
 299
 300int orangefs_inode_cache_initialize(void);
 301int orangefs_inode_cache_finalize(void);
 302
 303/*
 304 * defined in orangefs-mod.c
 305 */
 306void purge_inprogress_ops(void);
 307
 308/*
 309 * defined in waitqueue.c
 310 */
 311void purge_waiting_ops(void);
 312
 313/*
 314 * defined in super.c
 315 */
 316extern uint64_t orangefs_features;
 317
 318struct dentry *orangefs_mount(struct file_system_type *fst,
 319                           int flags,
 320                           const char *devname,
 321                           void *data);
 322
 323void orangefs_kill_sb(struct super_block *sb);
 324int orangefs_remount(struct orangefs_sb_info_s *);
 325
 326int fsid_key_table_initialize(void);
 327void fsid_key_table_finalize(void);
 328
 329/*
 330 * defined in inode.c
 331 */
 332struct inode *orangefs_new_inode(struct super_block *sb,
 333                              struct inode *dir,
 334                              int mode,
 335                              dev_t dev,
 336                              struct orangefs_object_kref *ref);
 337
 338int orangefs_setattr(struct dentry *dentry, struct iattr *iattr);
 339
 340int orangefs_getattr(const struct path *path, struct kstat *stat,
 341                     u32 request_mask, unsigned int flags);
 342
 343int orangefs_permission(struct inode *inode, int mask);
 344
 345int orangefs_update_time(struct inode *, struct timespec64 *, int);
 346
 347/*
 348 * defined in xattr.c
 349 */
 350ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size);
 351
 352/*
 353 * defined in namei.c
 354 */
 355struct inode *orangefs_iget(struct super_block *sb,
 356                         struct orangefs_object_kref *ref);
 357
 358ssize_t orangefs_inode_read(struct inode *inode,
 359                            struct iov_iter *iter,
 360                            loff_t *offset,
 361                            loff_t readahead_size);
 362
 363/*
 364 * defined in devorangefs-req.c
 365 */
 366extern uint32_t orangefs_userspace_version;
 367
 368int orangefs_dev_init(void);
 369void orangefs_dev_cleanup(void);
 370int is_daemon_in_service(void);
 371bool __is_daemon_in_service(void);
 372
 373/*
 374 * defined in orangefs-utils.c
 375 */
 376__s32 fsid_of_op(struct orangefs_kernel_op_s *op);
 377
 378ssize_t orangefs_inode_getxattr(struct inode *inode,
 379                             const char *name,
 380                             void *buffer,
 381                             size_t size);
 382
 383int orangefs_inode_setxattr(struct inode *inode,
 384                         const char *name,
 385                         const void *value,
 386                         size_t size,
 387                         int flags);
 388
 389int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
 390    u32 request_mask);
 391
 392int orangefs_inode_check_changed(struct inode *inode);
 393
 394int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr);
 395
 396bool orangefs_cancel_op_in_progress(struct orangefs_kernel_op_s *op);
 397
 398int orangefs_normalize_to_errno(__s32 error_code);
 399
 400extern struct mutex orangefs_request_mutex;
 401extern int op_timeout_secs;
 402extern int slot_timeout_secs;
 403extern int orangefs_dcache_timeout_msecs;
 404extern int orangefs_getattr_timeout_msecs;
 405extern struct list_head orangefs_superblocks;
 406extern spinlock_t orangefs_superblocks_lock;
 407extern struct list_head orangefs_request_list;
 408extern spinlock_t orangefs_request_list_lock;
 409extern wait_queue_head_t orangefs_request_list_waitq;
 410extern struct list_head *orangefs_htable_ops_in_progress;
 411extern spinlock_t orangefs_htable_ops_in_progress_lock;
 412extern int hash_table_size;
 413
 414extern const struct file_operations orangefs_file_operations;
 415extern const struct inode_operations orangefs_symlink_inode_operations;
 416extern const struct inode_operations orangefs_dir_inode_operations;
 417extern const struct file_operations orangefs_dir_operations;
 418extern const struct dentry_operations orangefs_dentry_operations;
 419
 420/*
 421 * misc convenience macros
 422 */
 423
 424#define ORANGEFS_OP_INTERRUPTIBLE 1   /* service_operation() is interruptible */
 425#define ORANGEFS_OP_PRIORITY      2   /* service_operation() is high priority */
 426#define ORANGEFS_OP_CANCELLATION  4   /* this is a cancellation */
 427#define ORANGEFS_OP_NO_MUTEX      8   /* don't acquire request_mutex */
 428#define ORANGEFS_OP_ASYNC         16  /* Queue it, but don't wait */
 429
 430int service_operation(struct orangefs_kernel_op_s *op,
 431                      const char *op_name,
 432                      int flags);
 433
 434#define get_interruptible_flag(inode) \
 435        ((ORANGEFS_SB(inode->i_sb)->flags & ORANGEFS_OPT_INTR) ? \
 436                ORANGEFS_OP_INTERRUPTIBLE : 0)
 437
 438#define fill_default_sys_attrs(sys_attr, type, mode)                    \
 439do {                                                                    \
 440        sys_attr.owner = from_kuid(&init_user_ns, current_fsuid()); \
 441        sys_attr.group = from_kgid(&init_user_ns, current_fsgid()); \
 442        sys_attr.perms = ORANGEFS_util_translate_mode(mode);            \
 443        sys_attr.mtime = 0;                                             \
 444        sys_attr.atime = 0;                                             \
 445        sys_attr.ctime = 0;                                             \
 446        sys_attr.mask = ORANGEFS_ATTR_SYS_ALL_SETABLE;                  \
 447} while (0)
 448
 449static inline void orangefs_set_timeout(struct dentry *dentry)
 450{
 451        unsigned long time = jiffies + orangefs_dcache_timeout_msecs*HZ/1000;
 452
 453        dentry->d_fsdata = (void *) time;
 454}
 455
 456#endif /* __ORANGEFSKERNEL_H */
 457