linux/fs/nfsd/nfsfh.h
<<
>>
Prefs
   1/* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> */
   2
   3#ifndef _LINUX_NFSD_FH_INT_H
   4#define _LINUX_NFSD_FH_INT_H
   5
   6#include <linux/nfsd/nfsfh.h>
   7
   8enum nfsd_fsid {
   9        FSID_DEV = 0,
  10        FSID_NUM,
  11        FSID_MAJOR_MINOR,
  12        FSID_ENCODE_DEV,
  13        FSID_UUID4_INUM,
  14        FSID_UUID8,
  15        FSID_UUID16,
  16        FSID_UUID16_INUM,
  17};
  18
  19enum fsid_source {
  20        FSIDSOURCE_DEV,
  21        FSIDSOURCE_FSID,
  22        FSIDSOURCE_UUID,
  23};
  24extern enum fsid_source fsid_source(struct svc_fh *fhp);
  25
  26
  27/* This might look a little large to "inline" but in all calls except
  28 * one, 'vers' is constant so moste of the function disappears.
  29 */
  30static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
  31                           u32 fsid, unsigned char *uuid)
  32{
  33        u32 *up;
  34        switch(vers) {
  35        case FSID_DEV:
  36                fsidv[0] = htonl((MAJOR(dev)<<16) |
  37                                 MINOR(dev));
  38                fsidv[1] = ino_t_to_u32(ino);
  39                break;
  40        case FSID_NUM:
  41                fsidv[0] = fsid;
  42                break;
  43        case FSID_MAJOR_MINOR:
  44                fsidv[0] = htonl(MAJOR(dev));
  45                fsidv[1] = htonl(MINOR(dev));
  46                fsidv[2] = ino_t_to_u32(ino);
  47                break;
  48
  49        case FSID_ENCODE_DEV:
  50                fsidv[0] = new_encode_dev(dev);
  51                fsidv[1] = ino_t_to_u32(ino);
  52                break;
  53
  54        case FSID_UUID4_INUM:
  55                /* 4 byte fsid and inode number */
  56                up = (u32*)uuid;
  57                fsidv[0] = ino_t_to_u32(ino);
  58                fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
  59                break;
  60
  61        case FSID_UUID8:
  62                /* 8 byte fsid  */
  63                up = (u32*)uuid;
  64                fsidv[0] = up[0] ^ up[2];
  65                fsidv[1] = up[1] ^ up[3];
  66                break;
  67
  68        case FSID_UUID16:
  69                /* 16 byte fsid - NFSv3+ only */
  70                memcpy(fsidv, uuid, 16);
  71                break;
  72
  73        case FSID_UUID16_INUM:
  74                /* 8 byte inode and 16 byte fsid */
  75                *(u64*)fsidv = (u64)ino;
  76                memcpy(fsidv+2, uuid, 16);
  77                break;
  78        default: BUG();
  79        }
  80}
  81
  82static inline int key_len(int type)
  83{
  84        switch(type) {
  85        case FSID_DEV:          return 8;
  86        case FSID_NUM:          return 4;
  87        case FSID_MAJOR_MINOR:  return 12;
  88        case FSID_ENCODE_DEV:   return 8;
  89        case FSID_UUID4_INUM:   return 8;
  90        case FSID_UUID8:        return 8;
  91        case FSID_UUID16:       return 16;
  92        case FSID_UUID16_INUM:  return 24;
  93        default: return 0;
  94        }
  95}
  96
  97/*
  98 * Shorthand for dprintk()'s
  99 */
 100extern char * SVCFH_fmt(struct svc_fh *fhp);
 101
 102/*
 103 * Function prototypes
 104 */
 105__be32  fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
 106__be32  fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
 107__be32  fh_update(struct svc_fh *);
 108void    fh_put(struct svc_fh *);
 109
 110static __inline__ struct svc_fh *
 111fh_copy(struct svc_fh *dst, struct svc_fh *src)
 112{
 113        WARN_ON(src->fh_dentry || src->fh_locked);
 114                        
 115        *dst = *src;
 116        return dst;
 117}
 118
 119static inline void
 120fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src)
 121{
 122        dst->fh_size = src->fh_size;
 123        memcpy(&dst->fh_base, &src->fh_base, src->fh_size);
 124}
 125
 126static __inline__ struct svc_fh *
 127fh_init(struct svc_fh *fhp, int maxsize)
 128{
 129        memset(fhp, 0, sizeof(*fhp));
 130        fhp->fh_maxsize = maxsize;
 131        return fhp;
 132}
 133
 134#ifdef CONFIG_NFSD_V3
 135/*
 136 * Fill in the pre_op attr for the wcc data
 137 */
 138static inline void
 139fill_pre_wcc(struct svc_fh *fhp)
 140{
 141        struct inode    *inode;
 142
 143        inode = fhp->fh_dentry->d_inode;
 144        if (!fhp->fh_pre_saved) {
 145                fhp->fh_pre_mtime = inode->i_mtime;
 146                fhp->fh_pre_ctime = inode->i_ctime;
 147                fhp->fh_pre_size  = inode->i_size;
 148                fhp->fh_pre_change = inode->i_version;
 149                fhp->fh_pre_saved = 1;
 150        }
 151}
 152
 153extern void fill_post_wcc(struct svc_fh *);
 154#else
 155#define fill_pre_wcc(ignored)
 156#define fill_post_wcc(notused)
 157#endif /* CONFIG_NFSD_V3 */
 158
 159
 160/*
 161 * Lock a file handle/inode
 162 * NOTE: both fh_lock and fh_unlock are done "by hand" in
 163 * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
 164 * so, any changes here should be reflected there.
 165 */
 166
 167static inline void
 168fh_lock_nested(struct svc_fh *fhp, unsigned int subclass)
 169{
 170        struct dentry   *dentry = fhp->fh_dentry;
 171        struct inode    *inode;
 172
 173        BUG_ON(!dentry);
 174
 175        if (fhp->fh_locked) {
 176                printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
 177                        dentry->d_parent->d_name.name, dentry->d_name.name);
 178                return;
 179        }
 180
 181        inode = dentry->d_inode;
 182        mutex_lock_nested(&inode->i_mutex, subclass);
 183        fill_pre_wcc(fhp);
 184        fhp->fh_locked = 1;
 185}
 186
 187static inline void
 188fh_lock(struct svc_fh *fhp)
 189{
 190        fh_lock_nested(fhp, I_MUTEX_NORMAL);
 191}
 192
 193/*
 194 * Unlock a file handle/inode
 195 */
 196static inline void
 197fh_unlock(struct svc_fh *fhp)
 198{
 199        if (fhp->fh_locked) {
 200                fill_post_wcc(fhp);
 201                mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);
 202                fhp->fh_locked = 0;
 203        }
 204}
 205
 206#endif /* _LINUX_NFSD_FH_INT_H */
 207