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_MMAP_RA_FLUSH)
  77                        return "OP_MMAP_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        }
 101        return "OP_UNKNOWN?";
 102}
 103
 104void orangefs_new_tag(struct orangefs_kernel_op_s *op)
 105{
 106        spin_lock(&next_tag_value_lock);
 107        op->tag = next_tag_value++;
 108        if (next_tag_value == 0)
 109                next_tag_value = 100;
 110        spin_unlock(&next_tag_value_lock);
 111}
 112
 113struct orangefs_kernel_op_s *op_alloc(__s32 type)
 114{
 115        struct orangefs_kernel_op_s *new_op = NULL;
 116
 117        new_op = kmem_cache_zalloc(op_cache, GFP_KERNEL);
 118        if (new_op) {
 119                INIT_LIST_HEAD(&new_op->list);
 120                spin_lock_init(&new_op->lock);
 121                init_completion(&new_op->waitq);
 122
 123                new_op->upcall.type = ORANGEFS_VFS_OP_INVALID;
 124                new_op->downcall.type = ORANGEFS_VFS_OP_INVALID;
 125                new_op->downcall.status = -1;
 126
 127                new_op->op_state = OP_VFS_STATE_UNKNOWN;
 128
 129                /* initialize the op specific tag and upcall credentials */
 130                orangefs_new_tag(new_op);
 131                new_op->upcall.type = type;
 132                new_op->attempts = 0;
 133                gossip_debug(GOSSIP_CACHE_DEBUG,
 134                             "Alloced OP (%p: %llu %s)\n",
 135                             new_op,
 136                             llu(new_op->tag),
 137                             get_opname_string(new_op));
 138
 139                new_op->upcall.uid = from_kuid(current_user_ns(),
 140                                               current_fsuid());
 141
 142                new_op->upcall.gid = from_kgid(current_user_ns(),
 143                                               current_fsgid());
 144        } else {
 145                gossip_err("op_alloc: kmem_cache_zalloc failed!\n");
 146        }
 147        return new_op;
 148}
 149
 150void op_release(struct orangefs_kernel_op_s *orangefs_op)
 151{
 152        if (orangefs_op) {
 153                gossip_debug(GOSSIP_CACHE_DEBUG,
 154                             "Releasing OP (%p: %llu)\n",
 155                             orangefs_op,
 156                             llu(orangefs_op->tag));
 157                kmem_cache_free(op_cache, orangefs_op);
 158        } else {
 159                gossip_err("NULL pointer in op_release\n");
 160        }
 161}
 162