summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/nfs-fops.h
blob: 8b12777d7b4c4b26369161ccf540566c86aad8f0 (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
/*
  Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
  This file is part of GlusterFS.

  GlusterFS is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published
  by the Free Software Foundation; either version 3 of the License,
  or (at your option) any later version.

  GlusterFS is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see
  <http://www.gnu.org/licenses/>.
*/

#ifndef _NFS_FOPS_H_
#define _NFS_FOPS_H_

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

#include "dict.h"
#include "xlator.h"
#include "iobuf.h"
#include "call-stub.h"
#include "stack.h"
#include "nfs.h"
#include "nfs-common.h"
#include <semaphore.h>

/* This structure used to communicate state between a fop and its callback.
 * The problem is, when we're calling a fop in the nfs op handler, the callback
 * is the NFS protocol's callback and we have to perform all GlusterFS
 * inode, inode table, fd_ts and fd table operations in the NFS callback. That
 * approach soon gets extremely complicated and confusing because, then we have
 * to try and separate in our heads which source lines in those callbacks are
 * required for serving the NFS op and which ones are needed for satisfying
 * GlusterFS requirements. This structure allows us avoid performing GlusterFS
 * state maintenance operations inside the fops layer itself. Now, before
 * we call the callback registered by the NFS operation, a hidden fops-layer
 * specific callback is called which performs the state maintenance and then
 * calls the NFS callback.
 *
 * These are allocated from a mem-pool stored in the nfs xlator's state.
 * i.e. struct nfs_state.
 * That is initiated in nfs_init_subvolumes in nfs.c.
 */
struct nfs_fop_local {
        /* The local sent along by the user of the fop. */
        void            *proglocal;

        /* The address of the callback supplied by the user. After our
         * callback is executed this one is called.
         * The exact cast destination of this pointer will depend on the
         * fop that is being called.
         */
        void            *progcbk;

        /* Used only for write requests. */
        struct iobref   *iobref;

        inode_t         *parent;
        inode_t         *newparent;
        inode_t         *inode;

        /* Set to 1 by nfs-inodes layer, which uses this to decide whether to
         * link the newly allocated inode into the itable, in case the fop was
         * successful.
         */
        int             newinode;

        /* Used by nfs-fops layer in order to determine whether to funge the
         * ino in a dir's stbuf. This funging of root ino is needed to ensure
         * that the root ino remains 1 even when the NFS server has been
         * restarted. Note that in distribute, a fresh lookup and a revalidate
         * on the root inode returns two different inode numbers and this we
         * need to handle by ourself.
         */
        int             rootinode;

        /* This member is used to determine whether the new parent of a file
         * being renamed is the root directory. If yes, the ino is funged.
         */
        int             newrootinode;
        int             newrootparentinode;

        /* Determines whether to funge the ino in the post and pre parent
         * stbufs for a file/dir where the parent directory could be the root
         * dir. Needed here because of the same reason as above.
         */
        int             rootparentinode;

        char            path[NFS_NAME_MAX];
        char            newpath[NFS_NAME_MAX];
};

extern struct nfs_fop_local *
nfs_fop_local_init (xlator_t *xl);

extern void
nfs_fop_local_wipe (xlator_t *xl, struct nfs_fop_local *l);

#define xlator_top_private(xl)  ((struct nfs_state *)((xlator_t *)(xl)->ctx->top)->private)

#define prog_data_to_nfl(xla, nflocal, fram, pcbk, plocal)              \
        do {                                                            \
                nflocal = nfs_fop_local_init (xla);                     \
                if (nflocal) {                                          \
                        nflocal->proglocal = plocal;                    \
                        nflocal->progcbk = pcbk;                        \
                        if (fram)                                       \
                                ((call_frame_t *)fram)->local = nflocal;                \
                }                                                       \
        } while (0)                                                     \



#define nfl_to_prog_data(xla, nflocal, pcbk, fram)                      \
        do {                                                            \
                nflocal = fram->local;                                  \
                fram->local = nflocal->proglocal;                       \
                pcbk = nflocal->progcbk;                                \
                nfs_fop_local_wipe (xla, nflocal);                      \
        } while (0)                                                     \

#define nfs_fop_handle_local_init(fram, xla, nfloc, cbck,prgloc,retval,lab) \
        do {                                                                \
                prog_data_to_nfl (xla, nfloc, fram, cbck, prgloc);          \
                if (!nfloc) {                                               \
                        gf_log (GF_NFS,GF_LOG_ERROR,"Failed to init local");\
                        retval = -ENOMEM;                                   \
                        goto lab;                                           \
                }                                                           \
        } while (0)                                                         \

extern int
nfs_fop_fstat (xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
               fop_stat_cbk_t cbk, void *local);

extern int
nfs_fop_readdirp (xlator_t *xl, nfs_user_t *nfu, fd_t *dirfd,
                  size_t bufsize, off_t offset, fop_readdir_cbk_t cbk,
                  void *local);
extern int
nfs_fop_lookup (xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
                fop_lookup_cbk_t cbk, void *local);

extern int
nfs_fop_create (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, int flags,
                mode_t mode, fd_t *fd, fop_create_cbk_t cbk, void *local);
extern int
nfs_fop_flush (xlator_t *xl, nfs_user_t *nfu, fd_t *fd,
               fop_flush_cbk_t cbk, void *local);

extern int
nfs_fop_mkdir (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, mode_t mode,
               fop_mkdir_cbk_t cbk, void *local);

extern int
nfs_fop_truncate (xlator_t *xl, nfs_user_t *nfu, loc_t *loc, off_t offset,
                  fop_truncate_cbk_t cbk, void *local);

extern int
nfs_fop_read (xlator_t *xl, nfs_user_t *nfu, fd_t *fd, size_t size,
              off_t offset, fop_readv_cbk_t cbk, void *local);

extern int
nfs_fop_fsync (xlator_t *xl, nfs_user_t *nfu, fd_t *fd, int32_t datasync,
               fop_fsync_cbk_t cbk, void *local);

extern int
nfs_fop_write (xlator_t *xl, nfs_user_t *nfu, fd_t *fd, struct iobuf *srciob,
               struct iovec *vector, int32_t count, off_t offset,
               fop_writev_cbk_t cbk, void *local);

extern int
nfs_fop_open (xlator_t *xl, nfs_user_t *nfu, loc_t *loc, int32_t flags,
              fd_t *fd, int32_t wbflags, fop_open_cbk_t cbk, void *local);

extern int
nfs_fop_rename (xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc,
                loc_t *newloc, fop_rename_cbk_t cbk, void *local);

extern int
nfs_fop_link (xlator_t *xl, nfs_user_t *nfu, loc_t *oldloc, loc_t *newloc,
              fop_link_cbk_t cbk, void *local);

extern int
nfs_fop_unlink (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
                fop_unlink_cbk_t cbk, void *local);

extern int
nfs_fop_rmdir (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
               fop_rmdir_cbk_t cbk, void *local);

extern int
nfs_fop_mknod (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, mode_t mode,
               dev_t dev, fop_mknod_cbk_t cbk, void *local);

extern int
nfs_fop_readlink (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
                  size_t size, fop_readlink_cbk_t cbk, void *local);

extern int
nfs_fop_symlink (xlator_t *xl, nfs_user_t *nfu, char *target,
                 loc_t *pathloc, fop_symlink_cbk_t cbk, void *local);

extern int
nfs_fop_setattr (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
                 struct iatt *buf, int32_t valid, fop_setattr_cbk_t cbk,
                 void *local);

extern int
nfs_fop_statfs (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,
                fop_statfs_cbk_t cbk, void *local);

extern int
nfs_fop_opendir (xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc,fd_t *dirfd,
                 fop_opendir_cbk_t cbk, void *local);

extern int
nfs_fop_stat (xlator_t *xl, nfs_user_t *nfu, loc_t *loc,
              fop_stat_cbk_t cbk, void *local);

/* Synchronous equivalents of some of the fops above.
 */

/* sfl = sync fop local
 * Structure used to turn async fops into sync calls for certain NFS ops
 * that need blocking operations.
 */
typedef struct nfs_syncfop {
        sem_t           replysig;
        call_stub_t     *replystub;
} nfs_syncfop_t;

extern nfs_syncfop_t *
nfs_syncfop_init ();

extern call_stub_t *
nfs_syncfop_wait (nfs_syncfop_t *s);

extern void
nfs_syncfop_notify (nfs_syncfop_t *s);

extern call_stub_t *
nfs_fop_lookup_sync (xlator_t *xl, nfs_user_t *nfu, loc_t *loc);

extern call_stub_t *
nfs_fop_readdirp_sync (xlator_t *fopxl, nfs_user_t *nfu, fd_t *dirfd,
                       off_t offset, size_t bufsize);

#endif