root/branches/asyncio/src/client/usrint/pxfs.c @ 9428

Revision 9428, 15.4 KB (checked in by sdsnyde, 10 months ago)

fixed small bug fixes in the aio-open state machine. pxfs_open(64) and pxfs_creat(64) have been tested and are working

Line 
1/*
2 * (C) 2011 Clemson University
3 *
4 * See COPYING in top-level directory.
5 */
6
7/** \file
8 *  \ingroup usrint
9 *
10 *  PXFS user interface routines
11 */
12
13#include "pxfs.h"
14
15/* actual implementations of the read/write functions */
16
17static int pxfs_rdwr64(int fd,
18                       void *buf,
19                       size_t size,
20                       off64_t offset,
21                       ssize_t *bcnt,
22                       pxfs_cb cb,
23                       void *cdat,
24                       int which,
25                       int advance_fp);
26
27static int pxfs_rdwrv(int fd,
28                      const struct iovec *vector,
29                      int count,
30                      ssize_t *bcnt,
31                      pxfs_cb  cb,
32                      void *cdat,
33                      int which);
34
35/**
36 *
37 **/
38
39/**
40 * pxfs_open
41 */
42extern int pxfs_open(const char *path, int flags, int *fd,
43                     pxfs_cb cb, void *cdat, ...)
44{
45    int rc;
46    va_list ap;
47    char *newpath;
48    struct pvfs_aiocb *open_acb = NULL;
49
50    if (!path || !fd)
51    {
52        errno = EINVAL;
53        return -1;
54    }
55
56    newpath = pvfs_qualify_path(path);
57    if (!newpath)
58    {
59        return -1;
60    }
61    if (newpath == path)
62    {
63        newpath = malloc(strlen(path) + 1);
64        if (!newpath)
65        {
66            errno = ENOMEM;
67            return -1;
68        }
69        strcpy(newpath, path);
70    }
71
72    /* alloc a pvfs_cb for use with aio_open */
73    open_acb = malloc(sizeof(struct pvfs_aiocb));
74    if (!open_acb)
75    {
76        errno = ENOMEM;
77        return -1;
78    }
79    memset(open_acb, 0, sizeof(struct pvfs_aiocb));
80
81    va_start(ap, cdat);
82    if (flags & O_CREAT)
83        open_acb->u.open.mode = va_arg(ap, int);
84    else
85        open_acb->u.open.mode = 0777;
86    if (flags & O_HINTS)
87        open_acb->u.open.file_creation_param = va_arg(ap, PVFS_hint);
88    else
89        open_acb->u.open.file_creation_param = PVFS_HINT_NULL;
90    va_end(ap);
91
92    rc = split_pathname(newpath, 0, &(open_acb->u.open.directory),
93                        &(open_acb->u.open.filename));
94    if (rc < 0)
95    {
96        return -1;
97    }   
98
99    open_acb->hints = PVFS_HINT_NULL;
100    open_acb->op_code = PVFS_AIO_OPEN_OP;
101    open_acb->u.open.path = newpath;
102    open_acb->u.open.flags = flags;
103    open_acb->u.open.pdir = NULL;
104    open_acb->u.open.fd = fd;
105    open_acb->call_back_fn = cb;
106    open_acb->call_back_dat = cdat;
107
108    aiocommon_submit_op(open_acb);
109
110    if (newpath != path)
111    {
112        free(newpath);
113    }
114
115    return 0;
116}
117
118/**
119 * pxfs_open64
120 */
121extern int pxfs_open64(const char *path, int flags, int *fd,
122                       pxfs_cb cb, void *cdat, ...)
123{
124    va_list ap;
125    int mode;
126    PVFS_hint hints;
127
128    if (!path || !fd)
129    {
130        errno = EINVAL;
131        return -1;
132    }
133    va_start(ap, cdat);
134    if (flags & O_CREAT)
135        mode = va_arg(ap, int);
136    else
137        mode = 0777;
138    if (flags & O_HINTS)
139        hints = va_arg(ap, PVFS_hint);
140    else
141        hints = PVFS_HINT_NULL;
142    va_end(ap);
143    flags |= O_LARGEFILE;
144
145    return pxfs_open(path, flags, fd, cb, cdat, mode);
146}
147
148/*
149extern int pxfs_openat(int dirfd, const char *path, int flags, int *fd,
150                       pxfs_cb cb, void *cdat, ...)
151{
152    return 0;
153}
154
155extern int pxfs_openat64(int dirfd, const char *path, int flags, int *fd,
156                         pxfs_cb cb, void *cdat, ...)
157{
158    va_list ap;
159    int mode;
160    PVFS_hint hints;
161
162    if (dirfd < 0)
163    {
164        errno = EBADF;
165        return -1;
166    }
167   
168    if (!path || !fd)
169    {
170        errno = EINVAL;
171        return -1;
172    }
173    va_start(ap, cdat);
174    if (flags & O_CREAT)
175        mode = va_arg(ap, int);
176    else
177        mode = 0777;
178    if (flags & O_HINTS)
179        hints = va_arg(ap, PVFS_hint);
180    else
181        hints = PVFS_HINT_NULL;
182    va_end(ap);
183    flags |= O_LARGEFILE;
184
185    return pxfs_openat(dirfd, path, flags, fd, cb, cdat, mode);
186}
187*/
188
189/**
190 * pxfs_creat
191 */
192extern int pxfs_creat(const char *path, mode_t mode, int *fd,
193                      pxfs_cb cb, void *cdat, ...)
194{
195    return pxfs_open(path, O_RDWR | O_CREAT | O_EXCL, fd, cb, cdat, mode);
196}
197
198/**
199 * pxfs_creat64
200 */
201extern int pxfs_creat64(const char *path, mode_t mode, int *fd,
202                        pxfs_cb cb, void *cdat, ...)
203{
204    return pxfs_open64(path, O_RDWR | O_CREAT | O_EXCL, fd, cb, cdat, mode);
205}
206
207/*
208extern int pxfs_unlink (const char *path, pxfs_cb cb, void *cdat);
209
210extern int pxfs_unlinkat (int dirfd, const char *path, int flags,
211                          pxfs_cb cb, void *cdat);
212*/
213
214/**
215 * pxfs_rename
216 */
217extern int pxfs_rename(const char *oldpath, const char *newpath,
218                       pxfs_cb cb, void *cdat)
219{
220    int rc;
221    char *abs_oldpath, *abs_newpath;
222    struct pvfs_aiocb *rename_acb = NULL;
223
224    if (!oldpath | !newpath)
225    {
226        errno = EINVAL;
227        return -1;
228    }
229
230    rename_acb = malloc(sizeof(struct pvfs_aiocb));
231    if (!rename_acb)
232    {
233        errno = ENOMEM;
234        return -1;
235    }
236    memset(rename_acb, 0, sizeof(struct pvfs_aiocb));
237   
238    abs_oldpath = pvfs_qualify_path(oldpath);
239    if (!abs_oldpath)
240    {
241        return -1;
242    }
243
244    abs_newpath = pvfs_qualify_path(newpath);
245    if (!abs_newpath)
246    {
247        return -1;
248    }
249
250    rc = split_pathname(abs_oldpath, 0, &(rename_acb->u.rename.olddir),
251                        &(rename_acb->u.rename.oldname));
252    if (rc < 0)
253    {
254        return -1;
255    }
256   
257    rc = split_pathname(abs_newpath, 0, &(rename_acb->u.rename.newdir),
258                        &(rename_acb->u.rename.newname));
259    if (rc < 0)
260    {
261        return -1;
262    }
263
264    rename_acb->hints = PVFS_HINT_NULL;
265    rename_acb->op_code = PVFS_AIO_RENAME_OP;
266    rename_acb->u.rename.oldpdir = NULL;
267    rename_acb->u.rename.newpdir = NULL;
268    rename_acb->call_back_fn = cb;
269    rename_acb->call_back_dat = cdat;
270
271    aiocommon_submit_op(rename_acb);
272
273    if (abs_oldpath != oldpath)
274    {
275        free(abs_oldpath);
276    }
277    if (abs_newpath != newpath)
278    {
279        free(abs_newpath);
280    }
281
282    return 0;
283}
284
285/*
286extern int pxfs_renameat(int olddirfd, const char *oldpath, int newdirfd,
287                         const char *newpath, pxfs_cb cb, void *cdat)
288{
289}
290*/
291
292extern int pxfs_read(int fd, const void *buf, size_t count, ssize_t *bcnt,
293                     pxfs_cb cb, void *cdat)
294{
295    pvfs_descriptor *pd = NULL;
296
297    if (fd < 0)
298    {
299        errno = EBADF;
300        return -1;
301    }
302
303    pd = pvfs_find_descriptor(fd);
304    if (!pd)
305    {
306        errno = EBADF;
307        return -1;
308    }   
309
310    return pxfs_rdwr64(fd, (void *)buf, count, pd->s->file_pointer, bcnt,
311                        cb, cdat, PVFS_IO_READ, 1);
312}
313
314extern int pxfs_pread(int fd, const void *buf, size_t count, off_t offset,
315                      ssize_t *bcnt, pxfs_cb cb, void *cdat)
316{
317    return pxfs_rdwr64(fd, (void *)buf, count, (off64_t)offset, bcnt,
318                        cb, cdat, PVFS_IO_READ, 0);
319}
320
321extern int pxfs_readv(int fd, const struct iovec *vector, int count,
322                      ssize_t *bcnt, pxfs_cb cb, void *cdat)
323{
324    return pxfs_rdwrv(fd, vector, count, bcnt, cb, cdat, PVFS_IO_READ);
325}
326
327extern int pxfs_pread64(int fd, const void *buf, size_t count, off64_t offset,
328                        ssize_t *bcnt, pxfs_cb cb, void *cdat)
329{
330    return pxfs_rdwr64(fd, (void *)buf, count, offset, bcnt, cb,
331                       cdat, PVFS_IO_READ, 0);
332}
333
334extern int pxfs_write(int fd, const void *buf, size_t count, ssize_t *bcnt,
335                      pxfs_cb cb, void *cdat)
336{
337    pvfs_descriptor *pd = NULL;
338
339    if (fd < 0)
340    {
341        errno = EBADF;
342        return -1;
343    }
344
345    pd = pvfs_find_descriptor(fd);
346    if (!pd)
347    {
348        errno = EBADF;
349        return -1;
350    }
351    /* check for append mode */
352    if (pd->s->flags & O_APPEND)
353    {
354        /* WHAT */
355        return 0;
356    }
357    else
358    {
359        return pxfs_rdwr64(fd, (void *)buf, count, pd->s->file_pointer, bcnt,
360                           cb, cdat, PVFS_IO_WRITE, 0);
361    }
362}
363
364extern int pxfs_pwrite(int fd, const void *buf, size_t count, off_t offset,
365                       ssize_t *bcnt, pxfs_cb cb, void *cdat)
366{
367    return pxfs_rdwr64(fd, (void *)buf, count, (off64_t)offset, bcnt,
368                        cb, cdat, PVFS_IO_WRITE, 0);
369}
370
371extern int pxfs_writev(int fd, const struct iovec *vector, int count,
372                       ssize_t *bcnt , pxfs_cb cb, void *cdat)
373{
374    return pxfs_rdwrv(fd, vector, count, bcnt, cb, cdat, PVFS_IO_WRITE);
375}
376
377extern int pxfs_pwrite64(int fd, const void *buf, size_t count,
378                         off64_t offset, ssize_t *bcnt,
379                         pxfs_cb cb, void *cdat)
380{
381    return pxfs_rdwr64(fd, (void *)buf, count, offset, bcnt, cb,
382                       cdat, PVFS_IO_WRITE, 0);
383}
384
385static int pxfs_rdwr64(int fd,
386                       void *buf,
387                       size_t size,
388                       off64_t offset,
389                       ssize_t *bcnt,
390                       pxfs_cb cb,
391                       void *cdat,
392                       int which,
393                       int advance_fp)
394{
395    pvfs_descriptor *pd;
396    struct pvfs_aiocb *io_acb = NULL;
397
398    if (fd < 0)
399    {
400        errno = EBADF;
401        return -1;
402    }
403
404    if (!buf || !bcnt)
405    {
406        errno = EINVAL;
407        return -1;
408    }
409
410    pd = pvfs_find_descriptor(fd);
411    if (!pd)
412    {
413        errno = EBADF;
414        return -1;
415    }
416
417    /* Ensure descriptor is used for the correct type of access */
418    if ((which == PVFS_IO_READ &&
419            (O_WRONLY == (pd->s->flags & O_ACCMODE))) ||
420        (which == PVFS_IO_WRITE &&
421            (O_RDONLY == (pd->s->flags & O_ACCMODE))))
422    {
423        errno = EBADF;
424        return -1;
425    }
426
427    io_acb = malloc(sizeof(struct pvfs_aiocb));
428    if (!io_acb)
429    {
430        errno = ENOMEM;
431        return -1;
432    }
433    memset(io_acb, 0, sizeof(struct pvfs_aiocb));
434
435    io_acb->u.io.vector = malloc(sizeof(struct iovec));
436    if(!(io_acb->u.io.vector))
437    {
438        errno = -ENOMEM;
439        return -1;
440    }
441
442    io_acb->hints = PVFS_HINT_NULL;
443    io_acb->op_code = PVFS_AIO_IO_OP;
444    io_acb->u.io.vector->iov_len = size;
445    io_acb->u.io.vector->iov_base = (void *)buf;
446    io_acb->u.io.pd = pd;
447    io_acb->u.io.which = which;
448    io_acb->u.io.advance_fp = advance_fp;
449    io_acb->u.io.offset = offset;
450    io_acb->u.io.bcnt = bcnt;
451    io_acb->call_back_fn = cb;
452    io_acb->call_back_dat = cdat;
453
454    aiocommon_submit_op(io_acb);
455
456    return 0;
457}
458
459static int pxfs_rdwrv(int fd,
460                      const struct iovec *vector,
461                      int count,
462                      ssize_t *bcnt,
463                      pxfs_cb  cb,
464                      void *cdat,
465                      int which)
466
467{
468    pvfs_descriptor *pd;
469    struct pvfs_aiocb *io_acb = NULL;
470
471    if (fd < 0)
472    {
473        errno = EBADF;
474        return -1;
475    }
476
477    if (!vector || !bcnt)
478    {
479        errno = EINVAL;
480        return -1;
481    }
482
483    /* find the descriptor */
484    pd = pvfs_find_descriptor(fd);
485    if (!pd)
486    {
487        errno = EBADF;
488        return -1;
489    }   
490
491    /* Ensure descriptor is used for the correct type of access */
492    if ((which == PVFS_IO_READ &&
493            (O_WRONLY == (pd->s->flags & O_ACCMODE))) ||
494        (which == PVFS_IO_WRITE &&
495            (O_RDONLY == (pd->s->flags & O_ACCMODE))))
496    {
497        errno = EBADF;
498        return -1;
499    }
500
501    io_acb = malloc(sizeof(struct pvfs_aiocb));
502    if (!io_acb)
503    {
504        errno = ENOMEM;
505        return -1;
506    }
507    memset(io_acb, 0, sizeof(struct pvfs_aiocb));
508
509    io_acb->hints = PVFS_HINT_NULL;
510    io_acb->op_code = PVFS_AIO_IOV_OP;
511    io_acb->u.io.vector = (struct iovec *)vector;
512    io_acb->u.io.count = count;
513    io_acb->u.io.pd = pd;
514    io_acb->u.io.which = which;
515    io_acb->u.io.offset = pd->s->file_pointer;
516    io_acb->u.io.bcnt = bcnt;
517    io_acb->call_back_fn = cb;
518    io_acb->call_back_dat = cdat;
519
520    aiocommon_submit_op(io_acb);
521
522    return 0;
523}
524/*
525extern int pxfs_truncate(const char *path, off_t length,
526                         pxfs_cb cb, void *cdat);
527
528extern int pxfs_truncate64 (const char *path, off64_t length,
529                            pxfs_cb cb, void *cdat);
530
531extern int pxfs_fallocate(int fd, off_t offset, off_t length,
532                          pxfs_cb cb, void *cdat);
533*/
534
535//extern int pxfs_ftruncate (int fd, off_t length, pxfs_cb cb, void *cdat);
536
537//extern int pxfs_ftruncate64 (int fd, off64_t length, pxfs_cb cb, void *cdat);
538
539/*
540extern int pxfs_close( int fd , pxfs_cb cb, void *cdat);
541
542extern int pxfs_flush(int fd, pxfs_cb cb, void *cdat);
543
544extern int pxfs_stat(const char *path, struct stat *buf,
545                     pxfs_cb cb, void *cdat);
546
547extern int pxfs_stat64(const char *path, struct stat64 *buf,
548                       pxfs_cb cb, void *cdat);
549
550extern int pxfs_stat_mask(const char *path, struct stat *buf,
551                          uint32_t mask, pxfs_cb cb, void *cdat);
552*/
553
554/**
555 * pxfs_fstat
556 */
557extern int pxfs_fstat(int fd, struct stat *buf, pxfs_cb cb, void *cdat)
558{
559    return pxfs_fstat_mask(fd, buf, PVFS_ATTR_DEFAULT_MASK, cb, cdat);
560}
561
562/**
563 * pxfs_fstat64
564 */
565extern int pxfs_fstat64(int fd, struct stat64 *buf, pxfs_cb cb, void *cdat)
566{
567    pvfs_descriptor *pd;   
568    struct pvfs_aiocb *stat_acb = NULL;
569
570    if (fd < 0)
571    {
572        errno = EBADF;
573        return -1;
574    }
575    if (!buf)
576    {
577        errno = EINVAL;
578        return -1;
579    }
580    pd = pvfs_find_descriptor(fd);
581    if (!pd || pd->is_in_use != PVFS_FS)
582    {
583        errno = EBADF;
584        return -1;
585    }
586
587    stat_acb = malloc(sizeof(struct pvfs_aiocb));
588    if (!stat_acb)
589    {
590        errno = ENOMEM;
591        return -1;
592    }
593    memset(stat_acb, 0, sizeof(struct pvfs_aiocb));
594
595    stat_acb->hints = PVFS_HINT_NULL;
596    stat_acb->op_code = PVFS_AIO_STAT64_OP;
597    stat_acb->u.stat.pd = pd;
598    stat_acb->u.stat.buf = (void *)buf;
599    stat_acb->u.stat.mask = PVFS_ATTR_DEFAULT_MASK;
600    stat_acb->call_back_fn = cb;
601    stat_acb->call_back_dat = cdat;
602
603    aiocommon_submit_op(stat_acb);
604
605    return 0;
606}
607
608/*
609extern int pxfs_fstatat(int fd, const char *path, struct stat *buf,
610                        int flag, pxfs_cb cb, void *cdat);
611
612extern int pxfs_fstatat64(int fd, const char *path, struct stat64 *buf,
613                          int flag, pxfs_cb cb, void *cdat);
614*/
615
616/**
617 * pxfs_fstat_mask
618 */
619extern int pxfs_fstat_mask(int fd, struct stat *buf, uint32_t mask,
620                           pxfs_cb cb, void *cdat)
621{
622    pvfs_descriptor *pd;
623    struct pvfs_aiocb *stat_acb = NULL;
624   
625    if (fd < 0)
626    {
627        errno = EBADF;
628        return -1;
629    }
630    if (!buf)
631    {
632        errno = EINVAL;
633        return -1;
634    }
635    pd = pvfs_find_descriptor(fd);
636    if (!pd || pd->is_in_use != PVFS_FS)
637    {
638        errno = EBADF;
639        return -1;
640    }
641
642    mask &= PVFS_ATTR_DEFAULT_MASK;
643
644    stat_acb = malloc(sizeof(struct pvfs_aiocb));
645    if (!stat_acb)
646    {
647        errno = ENOMEM;
648        return -1;
649    }
650    memset(stat_acb, 0, sizeof(struct pvfs_aiocb));
651
652    stat_acb->hints = PVFS_HINT_NULL;
653    stat_acb->op_code = PVFS_AIO_STAT_OP;
654    stat_acb->u.stat.pd = pd;
655    stat_acb->u.stat.buf = (void *)buf;
656    stat_acb->u.stat.mask = mask;
657    stat_acb->call_back_fn = cb;
658    stat_acb->call_back_dat = cdat;
659
660    aiocommon_submit_op(stat_acb);
661
662    return 0;   
663}
664
665/*
666extern int pxfs_lstat(const char *path, struct stat *buf,
667                      pxfs_cb cb, void *cdat);
668
669extern int pxfs_lstat64(const char *path, struct stat64 *buf,
670                        pxfs_cb cb, void *cdat);
671
672extern int pxfs_lstat_mask(const char *path, struct stat *buf, uint32_t mask,
673                           pxfs_cb cb, void *cdat);
674*/
675
676/*
677 * Local variables:
678 *  c-indent-level: 4
679 *  c-basic-offset: 4
680 * End:
681 *
682 * vim: ts=8 sts=4 sw=4 expandtab
683 */
Note: See TracBrowser for help on using the browser.