root/branches/as-branch/src/server/io.sm @ 7826

Revision 7826, 19.5 KB (checked in by sson, 4 years ago)

Used PINT_sm_frame(smcb->parent_smcb, 0) to refer parent smcbs in pipeline.sm.
Removed possible double free() in io.sm.

Line 
1/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
7/*
8 *  PVFS2 server state machine for driving I/O operations (read and write).
9 */
10
11#include <string.h>
12#include <assert.h>
13#include <stdlib.h> /* sson */
14
15#include "server-config.h"
16#include "pvfs2-server.h"
17#include "pvfs2-attr.h"
18#include "pvfs2-request.h"
19#include "pint-distribution.h"
20#include "pint-request.h"
21#include "pvfs2-internal.h"
22#include "pint-segpool.h"
23
24#define NUM_OF_PARALLEL_SMS 1
25#define BUFFER_SIZE (256*1024) /* 256KB */
26
27%%
28
29machine pvfs2_io_sm
30{
31    state prelude
32    {
33        jump pvfs2_prelude_sm;
34        success => send_positive_ack;
35        default => send_negative_ack;
36    }
37
38    state send_positive_ack
39    {
40        run io_send_ack;
41        success => start_pipelining;
42        default => release;
43    }
44
45    state send_negative_ack
46    {
47        run io_send_ack;
48        default => release;
49    }
50
51    state start_pipelining
52    {
53        pjmp start_pipelining_sm
54        {
55            success => pvfs2_pipeline_sm;
56        }
57        success => cleanup_pipeline;
58    }
59
60    state cleanup_pipeline
61    {
62        run cleanup_pipeline_sm;
63        success => send_completion_ack;
64        default => release;
65    }
66
67    state send_completion_ack
68    {
69        run io_send_completion_ack;
70        default => release;
71    }
72
73    state release
74    {
75        run io_release;
76        default => cleanup;
77    }
78
79    state cleanup
80    {
81        run io_cleanup;
82        default => terminate;
83    }
84}
85
86%%
87
88/*
89 * Function: io_send_ack()
90 *
91 * Params:   server_op *s_op,
92 *           job_status_s* js_p
93 *
94 * Pre:      error code has been set in job status for us to
95 *           report to client
96 *
97 * Post:     response has been sent to client
98 *           
99 * Returns:  int
100 *
101 * Synopsis: fills in a response to the I/O request, encodes it,
102 *           and sends it to the client via BMI.  Note that it may
103 *           send either positive or negative acknowledgements.
104 *           
105 */
106static int io_send_ack(
107        struct PINT_smcb *smcb, job_status_s *js_p)
108{
109    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
110    int err = -PVFS_EIO;
111    job_id_t tmp_id;
112    struct server_configuration_s *user_opts = get_server_config_struct();
113       
114    /* this is where we report the file size to the client before
115     * starting the I/O transfer, or else report an error if we
116     * failed to get the size, or failed for permission reasons
117     */
118    s_op->resp.status = js_p->error_code;
119    s_op->resp.u.io.bstream_size = s_op->ds_attr.u.datafile.b_size;
120
121    err = PINT_encode(&s_op->resp, PINT_ENCODE_RESP, &(s_op->encoded),
122                      s_op->addr, s_op->decoded.enc_type);
123
124    gossip_debug(GOSSIP_IO_DEBUG, "%s: error=%d\n", __func__, err);
125    if (err < 0)
126    {
127        gossip_lerr("Server: IO SM: PINT_encode() failure.\n");
128        js_p->error_code = err;
129        return SM_ACTION_COMPLETE;
130    }
131
132    err = job_bmi_send_list(
133        s_op->addr, s_op->encoded.buffer_list, s_op->encoded.size_list,
134        s_op->encoded.list_count, s_op->encoded.total_size,
135        s_op->tag, s_op->encoded.buffer_type, 0, smcb, 0, js_p,
136        &tmp_id, server_job_context, user_opts->server_job_bmi_timeout,
137        s_op->req->hints);
138
139    return err;
140}
141
142/*
143 * Function: start_pipelining_sm()
144 *
145 * Params:   server_op *s_op,
146 *           job_status_s* js_p
147 *
148 * Pre:      all of the previous steps have succeeded, so that we
149 *           are ready to actually perform the I/O
150 *
151 * Post:     I/O has been carried out
152 *           
153 * Returns:  int
154 *
155 * Synopsis: this is the most important part of the state machine.
156 *           we setup the multiple read/write state machines
157 *           to carry out the data transfer
158 *           
159 */
160static PINT_sm_action start_pipelining_sm(
161        struct PINT_smcb *smcb, job_status_s *js_p)
162{
163    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
164    struct server_configuration_s *user_opts = get_server_config_struct();
165    struct filesystem_configuration_s *fs_config;
166    struct PINT_server_op *pipeline_op;
167    int i, ret, dfile_index;
168    PINT_segpool_handle_t seg_handle;
169
170    s_op->u.io.parallel_sms = 0;
171    s_op->u.io.total_transferred = 0;
172
173    /* we still have the file size stored in the response structure
174     * that we sent in the previous state, other details come from
175     * request
176     */
177    s_op->u.io.file_data.fsize = s_op->resp.u.io.bstream_size;
178    s_op->u.io.file_data.dist = s_op->req->u.io.io_dist;
179    s_op->u.io.file_data.server_nr = s_op->req->u.io.server_nr;
180    s_op->u.io.file_data.server_ct = s_op->req->u.io.server_ct;
181
182    /* on writes, we allow the bstream to be extended at EOF */
183    if (s_op->req->u.io.io_type == PVFS_IO_WRITE)
184    {
185        gossip_debug(GOSSIP_IO_DEBUG, "%s: issuing pipelining to "
186                     "write data.\n", __func__);
187        s_op->u.io.file_data.extend_flag = 1;
188    }
189    else
190    {
191        gossip_debug(GOSSIP_IO_DEBUG, "%s: issuing pipelining to "
192                     "read data.\n", __func__);
193        s_op->u.io.file_data.extend_flag = 0;
194    }
195
196    s_op->u.io.file_req = s_op->req->u.io.file_req;
197    s_op->u.io.file_req_offset = s_op->req->u.io.file_req_offset;
198    s_op->u.io.mem_req = NULL;
199    s_op->u.io.aggregate_size = s_op->req->u.io.aggregate_size;
200    gossip_debug(GOSSIP_IO_DEBUG, "%s: tag=%d\n", __func__, s_op->tag);
201    s_op->u.io.user_ptr = NULL;
202    s_op->u.io.op = s_op->req->u.io.op; /* AS: operation */
203    s_op->u.io.datatype = s_op->req->u.io.datatype; /* AS: dtype */
204    s_op->u.io.dfile_array  = s_op->req->u.io.dfile_array; /* AD: dfile_array */
205   
206    gossip_debug(GOSSIP_IO_DEBUG, "server_ct=%d\n", s_op->req->u.io.server_ct);
207    gossip_debug(GOSSIP_IO_DEBUG, "fs_id=%d\n", s_op->req->u.io.fs_id);
208    for(i=0; i<s_op->req->u.io.server_ct; i++) {
209        gossip_debug(GOSSIP_IO_DEBUG, "dfile_array[%d]=%llu\n", i,
210                     llu(s_op->u.io.dfile_array[i]));
211        if(s_op->u.io.dfile_array[i] == s_op->req->u.io.handle) {
212            dfile_index = i;
213            gossip_debug(GOSSIP_IO_DEBUG, "dfile_index=%d\n", i);
214        }
215    }
216
217    fs_config = PINT_config_find_fs_id(user_opts, s_op->req->u.io.fs_id);
218    if(fs_config)
219    {
220        /* pick up any buffer settings overrides from fs conf */
221        s_op->u.io.buffer_size = fs_config->fp_buffer_size;
222        //s_op->u.io.num_of_buffers = fs_config->fp_buffers_per_flow;
223        s_op->u.io.num_of_buffers = NUM_OF_PARALLEL_SMS; /* FIXME */
224    }
225
226    gossip_debug(GOSSIP_IO_DEBUG, "%s: fsize: %lld, "
227                 "server_nr: %d, server_ct: %d\n", __func__,
228        lld(s_op->u.io.file_data.fsize),
229        (int)s_op->u.io.file_data.server_nr,
230        (int)s_op->u.io.file_data.server_ct);
231
232    gossip_debug(GOSSIP_IO_DEBUG, "      file_req_offset: %lld, "
233        "aggregate_size: %lld, handle: %llu\n",
234        lld(s_op->u.io.file_req_offset),
235        lld(s_op->u.io.aggregate_size),
236        llu(s_op->req->u.io.handle));
237
238    /* setup the request processing states */
239    gossip_debug(GOSSIP_IO_DEBUG, "%s: aggregate_size=%lld\n", __func__,
240                 lld(s_op->u.io.aggregate_size));
241    gossip_debug(GOSSIP_IO_DEBUG, "%s: file_data.fsize=%lld\n", __func__,
242                 lld(s_op->u.io.file_data.fsize));
243
244    if(s_op->u.io.buffer_size < 1)
245        s_op->u.io.buffer_size = BUFFER_SIZE;
246    if(s_op->u.io.num_of_buffers < 1)
247        s_op->u.io.num_of_buffers = NUM_OF_PARALLEL_SMS;
248
249#if 0
250    /* figure out if the fs config has trove data sync turned on or off
251         */
252    server_config = get_server_config_struct();
253    if(!server_config) {
254        js_p->error_code = -PVFS_EINVAL;
255        return SM_ACTION_COMPLETE;
256    }
257   
258    fs_config = PINT_config_find_fs_id(server_config,
259                                       s_op->u.pipeline.fs_id);
260    if(!fs_config) {
261        gossip_err("%s: Failed to get filesystem "
262                   "config from fs_id of: %d\n", __func__,
263                   s_op->u.pipeline.fs_id);
264        js_p->error_code = -PVFS_EINVAL;
265        return SM_ACTION_COMPLETE;
266    }
267#endif
268
269    PINT_segpool_unit_id id[s_op->u.io.num_of_buffers];
270
271    PINT_dist_lookup(s_op->u.io.file_data.dist);
272    ret = PINT_segpool_init(s_op->u.io.mem_req,
273                            s_op->u.io.file_req,
274                            s_op->u.io.file_data.fsize,
275                            s_op->u.io.file_req_offset,
276                            s_op->u.io.aggregate_size,
277                            s_op->u.io.file_data.server_nr,
278                            s_op->u.io.file_data.server_ct,
279                            s_op->u.io.file_data.dist, /* dist */
280                            (s_op->req->u.io.io_type == PVFS_IO_READ ?
281                             PINT_SP_SERVER_READ: PINT_SP_SERVER_WRITE),
282                            &seg_handle);
283
284    s_op->u.io.seg_handle = seg_handle;
285    gen_mutex_init(&s_op->u.io.mutex); /* FIXME: */
286    for(i=0; i<s_op->u.io.num_of_buffers; i++) {
287        PINT_segpool_register(seg_handle, &id[i]);
288        pipeline_op = malloc(sizeof(*pipeline_op));
289        memset(pipeline_op, 0, sizeof(*pipeline_op));
290
291        pipeline_op->u.pipeline.address = s_op->addr;
292        pipeline_op->u.pipeline.handle = s_op->req->u.io.handle;
293        pipeline_op->u.pipeline.fs_id = s_op->req->u.io.fs_id;
294
295        pipeline_op->u.pipeline.seg_handle = seg_handle;
296        pipeline_op->u.pipeline.id = id[i];
297        //pipeline_op->u.pipeline.parent = s_op;
298        pipeline_op->u.pipeline.hints = s_op->req->hints;
299        pipeline_op->u.pipeline.tag = s_op->tag;
300        pipeline_op->u.pipeline.buffer_size = BUFFER_SIZE;
301        pipeline_op->u.pipeline.io_type = s_op->req->u.io.io_type;
302
303        pipeline_op->u.pipeline.dfile_index = dfile_index;
304        pipeline_op->u.pipeline.dfile_count = s_op->u.io.file_data.server_ct;
305        pipeline_op->u.pipeline.dist = s_op->u.io.file_data.dist;
306
307        /* figure out if the fs config has trove data sync turned on or off
308         */
309        pipeline_op->u.pipeline.trove_sync_flag =
310            (fs_config->trove_sync_data ? TROVE_SYNC : 0);
311       
312        if(s_op->req->u.io.io_type == PVFS_IO_READ) {
313            if(!pipeline_op->u.pipeline.buffer) {
314                /* if the buffer has not been used, allocate a buffer */
315                pipeline_op->u.pipeline.buffer =
316                    BMI_memalloc(pipeline_op->u.pipeline.address,
317                                 pipeline_op->u.pipeline.buffer_size,
318                                 BMI_SEND);
319                /* TODO: error handling */
320                assert(pipeline_op->u.pipeline.buffer);
321            }
322
323            gossip_debug(GOSSIP_IO_DEBUG, "smcb->base_frame=%d, frame_count=%d\n", smcb->base_frame, smcb->frame_count);
324            ret = PINT_sm_push_frame(smcb, 0, pipeline_op);
325            gossip_debug(GOSSIP_IO_DEBUG, "smcb->base_frame=%d, frame_count=%d\n", smcb->base_frame, smcb->frame_count);
326            if(ret < 0) {
327                js_p->error_code = -PVFS_ENOMEM;
328                gossip_debug(GOSSIP_IO_DEBUG, "io: failed to setup nested sm for handle: %llu\n",
329                             llu(s_op->req->u.io.handle));
330                return SM_ACTION_COMPLETE;
331            }
332            s_op->u.io.parallel_sms++;
333            gossip_debug(GOSSIP_IO_DEBUG, "%s: parallel_sms=%d\n",
334                         __func__, s_op->u.io.parallel_sms);
335        }
336        else if(s_op->req->u.io.io_type == PVFS_IO_WRITE) {
337            if(!pipeline_op->u.pipeline.buffer){
338                /* if the buffer has not been used, allocate a buffer */
339                pipeline_op->u.pipeline.buffer =
340                    BMI_memalloc(pipeline_op->u.pipeline.address,
341                                 pipeline_op->u.pipeline.buffer_size,
342                                 BMI_RECV);
343                /* TODO: error handling */
344                assert(pipeline_op->u.pipeline.buffer);
345            }
346
347            gossip_debug(GOSSIP_IO_DEBUG, "smcb->base_frame=%d, frame_count=%d\n", smcb->base_frame, smcb->frame_count);
348            ret = PINT_sm_push_frame(smcb, 0, pipeline_op);
349            if(ret < 0) {
350                js_p->error_code = -PVFS_ENOMEM;
351                gossip_debug(GOSSIP_IO_DEBUG, "io: failed to setup nested sm for handle: %llu\n",
352                             llu(s_op->req->u.io.handle));
353                return SM_ACTION_COMPLETE;
354            }
355            gossip_debug(GOSSIP_IO_DEBUG, "smcb->base_frame=%d, frame_count=%d\n", smcb->base_frame, smcb->frame_count);
356            s_op->u.io.parallel_sms++;
357            gossip_debug(GOSSIP_IO_DEBUG, "%s: parallel_sms=%d\n",
358                         __func__, s_op->u.io.parallel_sms);
359        }
360    }
361
362    js_p->error_code = 0;
363    return SM_ACTION_COMPLETE;
364}
365
366static PINT_sm_action cleanup_pipeline_sm(struct PINT_smcb *smcb,
367                                          job_status_s *js_p)
368{
369    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
370    int i;
371    struct PINT_server_op *pipeline_op;
372    int task_id;
373    int remaining;
374    PVFS_error tmp_err;
375
376    for(i=0; i<s_op->u.io.parallel_sms; i++)
377    {
378        pipeline_op = PINT_sm_pop_frame(smcb, &task_id, &tmp_err,
379            &remaining);
380        gossip_debug(GOSSIP_SERVER_DEBUG,
381                     "io: nested sm returned error code: %d\n", tmp_err);
382        if(pipeline_op->u.pipeline.buffer) {
383            if(s_op->req->u.io.io_type == PVFS_IO_READ) {
384                BMI_memfree(pipeline_op->u.pipeline.address,
385                            pipeline_op->u.pipeline.buffer,
386                            s_op->u.io.buffer_size, BMI_SEND);
387            }
388            else if(s_op->req->u.io.io_type == PVFS_IO_WRITE) {
389                BMI_memfree(pipeline_op->u.pipeline.address,
390                            pipeline_op->u.pipeline.buffer,
391                            s_op->u.io.buffer_size, BMI_RECV);
392            }
393        }
394        free(pipeline_op);
395    }
396
397    js_p->error_code = 0;
398    return SM_ACTION_COMPLETE;
399}
400
401                                         
402/*
403 * Function: io_release()
404 *
405 * Params:   server_op *b,
406 *           job_status_s* js_p
407 *
408 * Pre:      we are done with all steps necessary to service
409 *           request
410 *
411 * Post:     operation has been released from the scheduler
412 *
413 * Returns:  int
414 *
415 * Synopsis: releases the operation from the scheduler
416 */
417static PINT_sm_action io_release(
418        struct PINT_smcb *smcb, job_status_s *js_p)
419{
420    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
421    int ret = 0;
422    job_id_t i;
423
424    /*
425      tell the scheduler that we are done with this operation (if it
426      was scheduled in the first place)
427    */
428    ret = job_req_sched_release(
429        s_op->scheduled_id, smcb, 0, js_p, &i, server_job_context);
430    return ret;
431}
432
433/*
434 * Function: io_cleanup()
435 *
436 * Params:   server_op *b,
437 *           job_status_s* js_p
438 *
439 * Pre:      all jobs done, simply need to clean up
440 *
441 * Post:     everything is free
442 *
443 * Returns:  int
444 *
445 * Synopsis: free up any buffers associated with the operation,
446 *           including any encoded or decoded protocol structures
447 */
448static PINT_sm_action io_cleanup(
449        struct PINT_smcb *smcb, job_status_s *js_p)
450{
451    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
452    char status_string[64] = {0};
453
454    PVFS_strerror_r(s_op->resp.status, status_string, 64);
455    PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, "finish (%s)\n", status_string);
456
457    if (s_op->u.io.seg_handle) {
458        gossip_debug(GOSSIP_IO_DEBUG, "%s: freeing seg_handle\n", __func__);
459        PINT_segpool_destroy(s_op->u.io.seg_handle);
460    }
461#if 0
462    if(s_op->u.io.tmp_buffer)
463        free(s_op->u.io.tmp_buffer); /* FIXME */
464#endif
465    gen_mutex_destroy(&s_op->u.io.mutex); /* FIXME: */
466
467    /* let go of our encoded response buffer, if we appear to have
468     * made one
469     */
470    if (s_op->encoded.total_size)
471    {
472        PINT_encode_release(&s_op->encoded, PINT_ENCODE_RESP);
473    }
474
475    return(server_state_machine_complete(smcb));
476}
477
478/*
479 * Function: io_send_completion_ack()
480 *
481 * Params:   server_op *s_op,
482 *           job_status_s* js_p
483 *
484 * Pre:      IO is completed so that we can report its status
485 *
486 * Post:     if this is a write, response has been sent to client
487 *           if this is a read, do nothing
488 *           
489 * Returns:  int
490 *
491 * Synopsis: fills in a response to the I/O request, encodes it,
492 *           and sends it to the client via BMI.  Note that it may
493 *           send either positive or negative acknowledgements.
494 *           
495 */
496static PINT_sm_action io_send_completion_ack(
497        struct PINT_smcb *smcb, job_status_s *js_p)
498{
499    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
500    int err = -PVFS_EIO;
501    job_id_t tmp_id;
502    struct server_configuration_s *user_opts = get_server_config_struct();
503
504    gossip_debug(GOSSIP_IO_DEBUG, "%s: s_op->u.io.parallel_sms=%d\n",
505                 __func__, s_op->u.io.parallel_sms);
506    /* we only send this trailing ack if we are working on a write
507     * operation; otherwise just cut out early
508     */
509    if (s_op->req->u.io.io_type == PVFS_IO_READ)
510    {
511        /* normal READ (i.e., without op and datatype) */
512        if(s_op->req->u.io.op == 0) { /* AS */
513            gossip_debug(GOSSIP_IO_DEBUG, "%s: normal READ\n", __func__);
514            js_p->error_code = 0;
515            return SM_ACTION_COMPLETE;
516        }
517        gossip_debug(GOSSIP_IO_DEBUG, "%s: IO_READ with op\n", __func__);
518    }
519
520    /* release encoding of the first ack that we sent */
521    PINT_encode_release(&s_op->encoded, PINT_ENCODE_RESP);
522
523    /* zero size for safety */
524    s_op->encoded.total_size = 0;
525
526    if(s_op->req->u.io.io_type == PVFS_IO_READ) { /* AS */
527        switch(s_op->req->u.io.datatype) {
528        case (int)0x4c000405: /* MPI_INT */
529            s_op->encoded.total_size = sizeof(int); /* FIXME */
530            break;
531        case (int)0x4c00080b:
532            s_op->encoded.total_size = sizeof(double); /* FIXME */
533            break;
534        default:
535            break;
536        }
537    }
538
539    /*
540      fill in response -- status field is the only generic one we
541      should have to set
542    */
543    if(s_op->req->u.io.op != 0 && s_op->req->u.io.io_type == PVFS_IO_READ) /* AS */
544        s_op->resp.op = PVFS_SERV_READ_COMPLETION;  /* AS: read with op */
545    else
546        s_op->resp.op = PVFS_SERV_WRITE_COMPLETION;  /* not IO */
547    s_op->resp.status = js_p->error_code;
548    if(s_op->req->u.io.io_type == PVFS_IO_READ) { /* AS: read with op */
549        s_op->resp.u.read_completion.total_completed =
550            s_op->u.io.total_transferred;
551        gossip_debug(GOSSIP_IO_DEBUG, "total_transferred=%lld\n", lld(s_op->u.io.total_transferred)); /* AS */
552        switch(s_op->req->u.io.datatype) {
553        case (int)0x4c000405: /* MPI_INT */
554            {
555                int *tmp;
556                tmp = s_op->u.io.tmp_buffer;
557                gossip_debug(GOSSIP_IO_DEBUG, "io_send_completion_ack(), result (INT) to send=%d, s_op->resp.u.read_completion.total_completed=%lld\n", *tmp, lld(s_op->resp.u.read_completion.total_completed));
558                s_op->resp.u.read_completion.result.buffer_sz = sizeof(int);
559                s_op->resp.u.read_completion.result.buffer = s_op->u.io.tmp_buffer;
560                break;
561            }
562        case (int)0x4c00080b:
563            {
564                double *tmp;
565                tmp = s_op->u.io.tmp_buffer;
566                gossip_debug(GOSSIP_IO_DEBUG, "io_send_completion_ack(), result (DOUBLE) to send=%lf, s_op->resp.u.read_completion.total_completed=%lld\n", *tmp, lld(s_op->resp.u.read_completion.total_completed));
567                s_op->resp.u.read_completion.result.buffer_sz = sizeof(double);
568                s_op->resp.u.read_completion.result.buffer = s_op->u.io.tmp_buffer;
569                break;
570            }
571        }
572    }
573    else /* AS */
574        s_op->resp.u.write_completion.total_completed =
575            s_op->u.io.total_transferred; /* AS */
576
577    gossip_debug(GOSSIP_IO_DEBUG, "%s: total_transferred=%lld\n", __func__,
578    lld(s_op->u.io.total_transferred)); err = PINT_encode(
579        &s_op->resp, PINT_ENCODE_RESP, &(s_op->encoded),
580        s_op->addr, s_op->decoded.enc_type);
581
582    gossip_debug(GOSSIP_IO_DEBUG, "%s: err=%d\n", __func__, err); // err = 0
583    if (err < 0)
584    {
585        gossip_lerr("Server: IO SM: PINT_encode() failure.\n");
586        js_p->error_code = err;
587        return SM_ACTION_COMPLETE;
588    }
589
590    err = job_bmi_send_list(
591        s_op->addr, s_op->encoded.buffer_list, s_op->encoded.size_list,
592        s_op->encoded.list_count, s_op->encoded.total_size, s_op->tag,
593        s_op->encoded.buffer_type, 0, smcb, 0, js_p, &tmp_id,
594        server_job_context, user_opts->server_job_bmi_timeout,
595        s_op->req->hints);
596
597    gossip_debug(GOSSIP_IO_DEBUG, "%s: err=%d\n", __func__, err); // err = 1
598
599    return err;
600}
601
602static enum PINT_server_req_access_type PINT_server_req_access_io(
603    struct PVFS_server_req *req)
604{
605    if(req->u.io.io_type == PVFS_IO_READ)
606    {
607        return PINT_SERVER_REQ_READONLY;
608    }
609    return PINT_SERVER_REQ_MODIFY;
610}
611
612PINT_GET_OBJECT_REF_DEFINE(io);
613
614struct PINT_server_req_params pvfs2_io_params =
615{
616    .string_name = "io",
617    .perm = PINT_SERVER_CHECK_NONE,
618    .access_type = PINT_server_req_access_io,
619    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
620    .get_object_ref = PINT_get_object_ref_io,
621    .state_machine = &pvfs2_io_sm,
622};
623
624/*
625 * Local variables:
626 *  mode: c
627 *  c-indent-level: 4
628 *  c-basic-offset: 4
629 * End:
630 *
631 * vim: ft=c ts=8 sts=4 sw=4 expandtab
632 */
Note: See TracBrowser for help on using the browser.