linux/fs/orangefs/orangefs-cache.c
<<
>>
Prefs
   1/*
   2 * (C) 2001 Clemson University and The University of Chicago
   3 *
   4 * See COPYING in top-level directory.
   5 */
   6
   7#include "protocol.h"
   8#include "orangefs-kernel.h"
   9
  10/* tags assigned to kernel upcall operations */
  11static __u64 next_tag_value;
  12static DEFINE_SPINLOCK(next_tag_value_lock);
  13
  14/* the orangefs memory caches */
  15
  16/* a cache for orangefs upcall/downcall operations */
  17static struct kmem_cache *op_cache;
  18
  19int op_cache_initialize(void)
  20{
  21        op_cache = kmem_cache_create("orangefs_op_cache",
  22                                     sizeof(struct orangefs_kernel_op_s),
  23                                     0,
  24                                     ORANGEFS_CACHE_CREATE_FLAGS,
  25                                     NULL);
  26
  27        if (!op_cache) {
  28                gossip_err("Cannot create orangefs_op_cache\n");
  29                return -ENOMEM;
  30        }
  31
  32        /* initialize our atomic tag counter */
  33        spin_lock(&next_tag_value_lock);
  34        next_tag_value = 100;
  35        spin_unlock(&next_tag_value_lock);
  36        return 0;
  37}
  38
  39int op_cache_finalize(void)
  40{
  41        kmem_cache_destroy(op_cache);
  42        return 0;
  43}
  44
  45char *get_opname_string(struct orangefs_kernel_op_s *new_op)
  46{
  47        if (new_op) {
  48                __s32 type = new_op->upcall.type;
  49
  50                if (type == ORANGEFS_VFS_OP_FILE_IO)
  51                        return "OP_FILE_IO";
  52                else if (type == ORANGEFS_VFS_OP_LOOKUP)
  53                        return "OP_LOOKUP";
  54                else if (type == ORANGEFS_VFS_OP_CREATE)
  55                        return "OP_CREATE";
  56                else if (type == ORANGEFS_VFS_OP_GETATTR)
  57                        return "OP_GETATTR";
  58                else if (type == ORANGEFS_VFS_OP_REMOVE)
  59                        return "OP_REMOVE";
  60                else if (type == ORANGEFS_VFS_OP_MKDIR)
  61                        return "OP_MKDIR";
  62                else if (type == ORANGEFS_VFS_OP_READDIR)
  63                        return "OP_READDIR";
  64                else if (type == ORANGEFS_VFS_OP_READDIRPLUS)
  65                        return "OP_READDIRPLUS";
  66                else if (type == ORANGEFS_VFS_OP_SETATTR)
  67                        return "OP_SETATTR";
  68                else if (type == ORANGEFS_VFS_OP_SYMLINK)
  69                        return "OP_SYMLINK";
  70                else if (type == ORANGEFS_VFS_OP_RENAME)
  71                        return "OP_RENAME";
  72                else if (type == ORANGEFS_VFS_OP_STATFS)
  73                        return "OP_STATFS";
  74                else if (type == ORANGEFS_VFS_OP_TRUNCATE)
  75                        return "OP_TRUNCATE";
  76                else if (type == ORANGEFS_VFS_OP_RA_FLUSH)
  77                        return "OP_RA_FLUSH";
  78                else if (type == ORANGEFS_VFS_OP_FS_MOUNT)
  79                        return "OP_FS_MOUNT";
  80                else if (type == ORANGEFS_VFS_OP_FS_UMOUNT)
  81                        return "OP_FS_UMOUNT";
  82                else if (type == ORANGEFS_VFS_OP_GETXATTR)
  83                        return "OP_GETXATTR";
  84                else if (type == ORANGEFS_VFS_OP_SETXATTR)
  85                        return "OP_SETXATTR";
  86                else if (type == ORANGEFS_VFS_OP_LISTXATTR)
  87                        return "OP_LISTXATTR";
  88                else if (type == ORANGEFS_VFS_OP_REMOVEXATTR)
  89                        return "OP_REMOVEXATTR";
  90                else if (type == ORANGEFS_VFS_OP_PARAM)
  91                        return "OP_PARAM";
  92                else if (type == ORANGEFS_VFS_OP_PERF_COUNT)
  93                        return "OP_PERF_COUNT";
  94                else if (type == ORANGEFS_VFS_OP_CANCEL)
  95                        return "OP_CANCEL";
  96                else if (type == ORANGEFS_VFS_OP_FSYNC)
  97                        return "OP_FSYNC";
  98                else if (type == ORANGEFS_VFS_OP_FSKEY)
  99                        return "OP_FSKEY";
 100                else if (type == ORANGEFS_VFS_OP_FEATURES)
 101                        return "OP_FEATURES";
 102        }
 103        return "OP_UNKNOWN?";
 104}
 105
 106void orangefs_new_tag(struct orangefs_kernel_op_s *op)
 107{
 108        spin_lock(&next_tag_value_lock);
 109        op->tag = next_tag_value++;
 110        if (next_tag_value == 0)
 111                next_tag_value = 100;
 112        spin_unlock(&next_tag_value_lock);
 113}
 114
 115struct orangefs_kernel_op_s *op_alloc(__s32 type)
 116{
 117        struct orangefs_kernel_op_s *new_op = NULL;
 118
 119        new_op = kmem_cache_zalloc(op_cache, GFP_KERNEL);
 120        if (new_op) {
 121                INIT_LIST_HEAD(&new_op->list);
 122                spin_lock_init(&new_op->lock);
 123                init_completion(&new_op->waitq);
 124
 125                new_op->upcall.type = ORANGEFS_VFS_OP_INVALID;
 126                new_op->downcall.type = ORANGEFS_VFS_OP_INVALID;
 127                new_op->downcall.status = -1;
 128
 129                new_op->op_state = OP_VFS_STATE_UNKNOWN;
 130
 131                /* initialize the op specific tag and upcall credentials */
 132                orangefs_new_tag(new_op);
 133                new_op->upcall.type = type;
 134                new_op->attempts = 0;
 135                gossip_debug(GOSSIP_CACHE_DEBUG,
 136                             "Alloced OP (%p: %llu %s)\n",
 137                             new_op,
 138                             llu(new_op->tag),
 139                             get_opname_string(new_op));
 140
 141                new_op->upcall.uid = from_kuid(&init_user_ns,
 142                                               current_fsuid());
 143
 144                new_op->upcall.gid = from_kgid(&init_user_ns,
 145                                               current_fsgid());
 146        } else {
 147                gossip_err("op_alloc: kmem_cache_zalloc failed!\n");
 148        }
 149        return new_op;
 150}
 151
 152void op_release(struct orangefs_kernel_op_s *orangefs_op)
 153{
 154        if (orangefs_op) {
 155                gossip_debug(GOSSIP_CACHE_DEBUG,
 156                             "Releasing OP (%p: %llu)\n",
 157                             orangefs_op,
 158                             llu(orangefs_op->tag));
 159                kmem_cache_free(op_cache, orangefs_op);
 160        } else {
 161                gossip_err("NULL pointer in op_release\n");
 162        }
 163}
 164