summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/nfs3.h
blob: f1b89fe17a870f5987d072116b381e1e9c492f3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/*
  Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
  This file is part of GlusterFS.

  This file is licensed to you under your choice of the GNU Lesser
  General Public License, version 3 or any later version (LGPLv3 or
  later), or the GNU General Public License, version 2 (GPLv2), in all
  cases as published by the Free Software Foundation.
*/

#ifndef _NFS3_H_
#define _NFS3_H_

#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif

#include "rpcsvc.h"
#include "dict.h"
#include "xlator.h"
#include "iobuf.h"
#include "nfs.h"
#include "nfs3-fh.h"
#include "nfs-common.h"
#include "xdr-nfs3.h"
#include "mem-pool.h"
#include "nlm4.h"
#include "acl3-xdr.h"
#include "acl3.h"
#include <sys/statvfs.h>

#define GF_NFS3                 GF_NFS"-nfsv3"

#define GF_NFS3_DEFAULT_MEMFACTOR       15
#define GF_NFS3_IOBPOOL_MULT            GF_NFS_CONCURRENT_OPS_MULT
#define GF_NFS3_CLTABLE_BUCKETS_MULT    2
#define GF_NFS3_FDTABLE_BUCKETS_MULT    2


/* Static values used for FSINFO
 * To change the maximum rsize and wsize supported by the NFS client, adjust
 * GF_NFS3_FILE_IO_SIZE_MAX. The Gluster NFS server defaults to 1MB(1048576)
 * (same as kernel NFS server). For slower network, rsize/wsize can be trimmed
 * to 16/32/64-KB. rsize and wsize can be tuned through nfs.read-size and
 * nfs.write-size respectively.
 *
 * NB: For Kernel-NFS, NFS_MAX_FILE_IO_SIZE is 1048576U (1MB).
 */
#define GF_NFS3_FILE_IO_SIZE_MAX     (1  * GF_UNIT_MB) /* 1048576 */
#define GF_NFS3_FILE_IO_SIZE_MIN     (4  * GF_UNIT_KB) /* 4096 */

#define GF_NFS3_FILE_IO_SIZE_DEF     GF_NFS3_FILE_IO_SIZE_MAX

#define GF_NFS3_RTMAX          GF_NFS3_FILE_IO_SIZE_MAX
#define GF_NFS3_RTMIN          GF_NFS3_FILE_IO_SIZE_MIN
#define GF_NFS3_RTPREF         GF_NFS3_FILE_IO_SIZE_DEF
#define GF_NFS3_RTMULT         GF_NFS3_FILE_IO_SIZE_MIN

#define GF_NFS3_WTMAX          GF_NFS3_FILE_IO_SIZE_MAX
#define GF_NFS3_WTMIN          GF_NFS3_FILE_IO_SIZE_MIN
#define GF_NFS3_WTPREF         GF_NFS3_FILE_IO_SIZE_DEF
#define GF_NFS3_WTMULT         GF_NFS3_FILE_IO_SIZE_MIN

/* This can be tuned through nfs.readdir-size */
#define GF_NFS3_DTMAX          GF_NFS3_FILE_IO_SIZE_MAX
#define GF_NFS3_DTMIN          GF_NFS3_FILE_IO_SIZE_MIN
#define GF_NFS3_DTPREF         GF_NFS3_FILE_IO_SIZE_DEF

#define GF_NFS3_MAXFILESIZE    (1 * GF_UNIT_PB)

#define GF_NFS3_IO_SIZE        4096 /* 4-KB */
#define GF_NFS3_IO_SHIFT       12   /* 2^12 = 4KB */

/* FIXME: Handle time resolutions */
#define GF_NFS3_TIMEDELTA_SECS     {1,0}
#define GF_NFS3_TIMEDELTA_NSECS    {0,1}
#define GF_NFS3_TIMEDELTA_MSECS    {0,1000000}

#define GF_NFS3_FS_PROP    (FSF3_LINK | FSF3_SYMLINK | FSF3_HOMOGENEOUS | FSF3_CANSETTIME)

#define GF_NFS3_DIRFD_VALID        1
#define GF_NFS3_DIRFD_INVALID      0

#define GF_NFS3_VOLACCESS_RW    1
#define GF_NFS3_VOLACCESS_RO    2


#define GF_NFS3_FDCACHE_SIZE    512
/* This should probably be moved to a more generic layer so that if needed
 * different versions of NFS protocol can use the same thing.
 */
struct nfs3_fd_entry {
        fd_t                    *cachedfd;
        struct list_head        list;
};

/* Per subvolume nfs3 specific state */
struct nfs3_export {
        struct list_head        explist;
        xlator_t                *subvol;
        uuid_t                  volumeid;
        int                     access;
        int                     trusted_sync;
        int                     trusted_write;
        int                     rootlookedup;
};

#define GF_NFS3_DEFAULT_VOLACCESS       (GF_NFS3_VOLACCESS_RW)

/* The NFSv3 protocol state */
typedef struct nfs3_state {

        /* The NFS xlator pointer. The NFS xlator can be running
         * multiple versions of the NFS protocol.
         */
        xlator_t                *nfsx;

        /* The iob pool from which memory allocations are made for receiving
         * and sending network messages.
         */
        struct iobuf_pool       *iobpool;

        /* List of child subvolumes for the NFSv3 protocol.
         * Right now, is simply referring to the list of children in nfsx above.
         */
        xlator_list_t           *exportslist;

        struct list_head        exports;
        /* Mempool for allocations of struct nfs3_local */
        struct mem_pool         *localpool;

        /* Server start-up timestamp, currently used for write verifier. */
        uint64_t                serverstart;

        /* NFSv3 Protocol configurables */
        uint64_t                readsize;
        uint64_t                writesize;
        uint64_t                readdirsize;

        /* Size of the iobufs used, depends on the sizes of the three params
         * above.
         */
        uint64_t                iobsize;

        struct list_head        fdlru;
        gf_lock_t               fdlrulock;
        int                     fdcount;
        uint32_t                occ_logger;
} nfs3_state_t;

typedef enum nfs3_lookup_type {
        GF_NFS3_REVALIDATE = 1,
        GF_NFS3_FRESH,
} nfs3_lookup_type_t;

typedef union args_ {
        nlm4_stat nlm4_stat;
        nlm4_holder nlm4_holder;
        nlm4_lock nlm4_lock;
        nlm4_share nlm4_share;
        nlm4_testrply nlm4_testrply;
        nlm4_testres nlm4_testres;
        nlm4_testargs nlm4_testargs;
        nlm4_res nlm4_res;
        nlm4_lockargs nlm4_lockargs;
        nlm4_cancargs nlm4_cancargs;
        nlm4_unlockargs nlm4_unlockargs;
        nlm4_shareargs nlm4_shareargs;
        nlm4_shareres nlm4_shareres;
        nlm4_freeallargs nlm4_freeallargs;
        getaclargs getaclargs;
        setaclargs setaclargs;
        getaclreply getaclreply;
        setaclreply setaclreply;
} args;


typedef int (*nfs3_resume_fn_t) (void *cs);
/* Structure used to communicate state between a fop and its callback.
 * Not all members are used at all times. Usage is fop and NFS request
 * dependent.
 *
 * I wish we could have a smaller structure for communicating state
 * between callers and callbacks. It could be broken into smaller parts
 * but I feel that will lead to a proliferation of types/structures and then
 * we'll just be tracking down which structure is used by which fop, not
 * to mention that having one type allows me to used a single mem-pool.
 * Imagine the chaos if we need a mem-pool for each one of those sub-structures.
 */
struct nfs3_local {
        rpcsvc_request_t        *req;
        xlator_t                *vol;
        nfs3_resume_fn_t        resume_fn;
        xlator_t                *nfsx;
        struct nfs3_state       *nfs3state;

        /* The list hook to attach this call state to the inode's queue till
         * the opening of the fd on the inode completes.
         */
        struct list_head        openwait_q;

        /* Per-NFSv3 Op state */
        struct nfs3_fh          parent;
        struct nfs3_fh          fh;
        fd_t                    *fd;
        uint32_t                accessbits;
        int                     operrno;
        count3                  dircount;
        count3                  maxcount;
        struct statvfs          fsstat;
        gf_dirent_t             entries;
        struct iatt             stbuf;
        struct iatt             preparent;
        struct iatt             postparent;
        int32_t                 setattr_valid;
        nfstime3                timestamp;
        loc_t                   oploc;
        int                     writetype;
        count3                  datacount;
        offset3                 dataoffset;
        struct iobuf            *iob;
        struct iobref           *iobref;
        createmode3             createmode;
        uint64_t                cookieverf;
        int                     sattrguardcheck;
        char                    *pathname;
        ftype3                  mknodtype;
        specdata3               devnums;
        cookie3                 cookie;
        struct iovec            datavec;
        mode_t                  mode;

        /* NFSv3 FH resolver state */
        int                     hardresolved;
        struct nfs3_fh          resolvefh;
        loc_t                   resolvedloc;
        int                     resolve_ret;
        int                     resolve_errno;
        int                     hashidx;
        fd_t                    *resolve_dir_fd;
        char                    *resolventry;
        nfs3_lookup_type_t      lookuptype;
        gf_dirent_t             *hashmatch;
        gf_dirent_t             *entrymatch;
        off_t                   lastentryoffset;
        struct flock            flock;
        args                    args;
        nlm4_lkowner_t          lkowner;
        char                    cookiebytes[1024];
        struct nfs3_fh          lockfh;
        int                     monitor;
        rpc_transport_t         *trans;
        call_frame_t            *frame;

        /* ACL */
        aclentry                aclentry[NFS_ACL_MAX_ENTRIES];
        aclentry                daclentry[NFS_ACL_MAX_ENTRIES];
        int                     aclcount;
        char                    aclxattr[NFS_ACL_MAX_ENTRIES*8 + 4];
        int                     daclcount;
        char                    daclxattr[NFS_ACL_MAX_ENTRIES*8 + 4];
};

#define nfs3_is_revalidate_lookup(cst) ((cst)->lookuptype == GF_NFS3_REVALIDATE)
#define nfs3_lookup_op(cst) (rpcsvc_request_procnum(cst->req) == NFS3_LOOKUP)
#define nfs3_create_op(cst) (rpcsvc_request_procnum(cst->req) == NFS3_CREATE)
#define nfs3_create_exclusive_op(cst) ((cst)->createmode == EXCLUSIVE)

typedef struct nfs3_local nfs3_call_state_t;

/* Queue of ops waiting for open fop to return. */
struct inode_op_queue {
        struct list_head        opq;
        pthread_mutex_t         qlock;
};

extern rpcsvc_program_t *
nfs3svc_init (xlator_t *nfsx);

extern int
nfs3_reconfigure_state (xlator_t *nfsx, dict_t *options);

extern uint64_t
nfs3_request_xlator_deviceid (rpcsvc_request_t *req);

#endif