root/branches/stable/src/client/usrint/posix-pvfs.c @ 9433

Revision 9433, 55.1 KB (checked in by walt, 10 months ago)

modified PVFS-chdir run expand path to fully qualify

Line 
1/*
2 * (C) 2011 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
7/** \file
8 *  \ingroup usrint
9 *
10 *  PVFS2 user interface routines - pvfs version of posix system calls
11 */
12#define USRINT_SOURCE 1
13#include "usrint.h"
14#include <sys/syscall.h>
15#include "posix-ops.h"
16#include "posix-pvfs.h"
17#include "openfile-util.h"
18#include "iocommon.h"
19#include "pvfs-path.h"
20
21#define PVFS_ATTR_DEFAULT_MASK \
22        (PVFS_ATTR_SYS_COMMON_ALL | PVFS_ATTR_SYS_SIZE |\
23         PVFS_ATTR_SYS_BLKSIZE | PVFS_ATTR_SYS_LNK_TARGET)
24
25static mode_t mask_val = 0022; /* implements umask for pvfs library */
26static char pvfs_cwd[PVFS_PATH_MAX];
27
28/* actual implementation of read and write are in these static funcs */
29
30static ssize_t pvfs_prdwr64(int fd,
31                            void *buf,
32                            size_t count,
33                            off64_t offset,
34                            int which);
35
36static ssize_t pvfs_rdwrv(int fd,
37                          const struct iovec *vector,
38                          size_t count,
39                          int which);
40
41static int my_glibc_getcwd(char *buf, unsigned long size)
42{
43    return syscall(SYS_getcwd, buf, size);
44}
45
46/**
47 *  pvfs_open
48 */
49int pvfs_open(const char *path, int flags, ...)
50{
51    va_list ap;
52    int mode;
53    PVFS_hint hints;
54    char *newpath;
55    pvfs_descriptor *pd;
56    debug("pvfs_open: called with %s\n", path);
57
58    if (!path)
59    {
60        errno = EINVAL;
61        return -1;
62    }
63    va_start(ap, flags);
64    if (flags & O_CREAT)
65        mode = va_arg(ap, int);
66    else
67        mode = 0777;
68    if (flags & O_HINTS)
69        hints = va_arg(ap, PVFS_hint);
70    else
71        hints = PVFS_HINT_NULL;
72    va_end(ap);
73
74    /* fully qualify pathname */
75    newpath = PVFS_qualify_path(path);
76    if (!newpath)
77    {
78        return -1;
79    }
80    pd = iocommon_open(newpath, flags, hints, mode, NULL);
81    if (newpath != path)
82    {
83        /* this should only happen if path was not a PVFS_path */
84        PVFS_free_expanded(newpath);
85    }
86    if (!pd)
87    {
88        return -1;
89    }
90    else
91    {
92        return pd->fd;
93    }
94}
95
96/**
97 * pvfs_open64
98 */
99int pvfs_open64(const char *path, int flags, ...)
100{
101    va_list ap;
102    int mode;
103    PVFS_hint hints;
104
105    if (!path)
106    {
107        errno = EINVAL;
108        return -1;
109    }
110    va_start(ap, flags);
111    if (flags & O_CREAT)
112    {
113        mode = va_arg(ap, int);
114    }
115    else
116    {
117        mode = 0777;
118    }
119    if (flags & O_HINTS)
120    {
121        hints = va_arg(ap, PVFS_hint);
122    }
123    else
124    {
125        hints = PVFS_HINT_NULL;
126    }
127    va_end(ap);
128    flags |= O_LARGEFILE;
129    return pvfs_open(path, flags, mode);
130}
131
132/**
133 * pvfs_openat
134 */
135int pvfs_openat(int dirfd, const char *path, int flags, ...)
136{
137    va_list ap;
138    int mode;
139    PVFS_hint hints;
140    pvfs_descriptor *dpd, *fpd;
141
142    if (!path)
143    {
144        errno = EINVAL;
145        return -1;
146    }
147    va_start(ap, flags);
148    if (flags & O_CREAT)
149    {
150        mode = va_arg(ap, int);
151    }
152    else
153    {
154        mode = 0777;
155    }
156    if (flags & O_HINTS)
157    {
158        hints = va_arg(ap, PVFS_hint);
159    }
160    else
161    {
162        hints = PVFS_HINT_NULL;
163    }
164    va_end(ap);
165    if (path[0] == '/' || dirfd == AT_FDCWD)
166    {
167        return pvfs_open(path, flags, mode);
168    }
169    else
170    {
171        if (dirfd < 0)
172        {
173            errno = EBADF;
174            return -1;
175        }
176        dpd = pvfs_find_descriptor(dirfd);
177        if (!dpd)
178        {
179            return -1;
180        }
181        fpd = iocommon_open(path, flags, hints, mode, dpd);
182        if (!fpd)
183        {
184            return -1;
185        }
186        return fpd->fd;
187    }
188}
189
190/**
191 * pvfs_openat64
192 */
193int pvfs_openat64(int dirfd, const char *path, int flags, ...)
194{
195    va_list ap;
196    int mode;
197    PVFS_hint hints;
198
199    if (dirfd < 0)
200    {
201        errno = EBADF;
202        return -1;
203    }
204    va_start(ap, flags);
205    if (flags & O_CREAT)
206    {
207        mode = va_arg(ap, int);
208    }
209    else
210    {
211        mode = 0777;
212    }
213    if (flags & O_HINTS)
214    {
215        hints = va_arg(ap, PVFS_hint);
216    }
217    else
218    {
219        hints = PVFS_HINT_NULL;
220    }
221    va_end(ap);
222    flags |= O_LARGEFILE;
223    return pvfs_openat(dirfd, path, flags, mode);
224}
225
226/**
227 * pvfs_creat wrapper
228 */
229int pvfs_creat(const char *path, mode_t mode, ...)
230{
231    return pvfs_open(path, O_RDWR | O_CREAT | O_EXCL, mode);
232}
233
234/**
235 * pvfs_creat64 wrapper
236 */
237int pvfs_creat64(const char *path, mode_t mode, ...)
238{
239    return pvfs_open64(path, O_RDWR | O_CREAT | O_EXCL, mode);
240}
241
242/**
243 * pvfs_unlink
244 */
245int pvfs_unlink(const char *path)
246{
247    int rc = 0;
248    char *newpath;
249
250    newpath = PVFS_qualify_path(path);
251    if (!newpath)
252    {
253        return -1;
254    }
255    rc = iocommon_unlink(path, NULL);
256    if (newpath != path)
257    {
258        /* This should only happen if path was not a PVFS_path */
259        PVFS_free_expanded(newpath);
260    }
261    return rc;
262}
263
264/**
265 * pvfs_unlinkat
266 */
267int pvfs_unlinkat(int dirfd, const char *path, int flags)
268{
269    int rc;
270    pvfs_descriptor *pd;
271
272    if (path[0] == '/' || dirfd == AT_FDCWD)
273    {
274        rc = iocommon_unlink(path, NULL);
275    }
276    else
277    {
278        if (dirfd < 0)
279        {
280            errno = EBADF;
281            return -1;
282        }       
283        pd = pvfs_find_descriptor(dirfd);
284        if (!pd)
285        {
286            errno = EBADF;
287            return -1;
288        }
289        if (flags & AT_REMOVEDIR)
290        {
291            rc = iocommon_rmdir(path, &pd->s->pvfs_ref);
292        }
293        else
294        {
295            rc = iocommon_unlink(path, &pd->s->pvfs_ref);
296        }
297    }
298    return rc;
299}
300
301/**
302 * pvfs_rename
303 */
304int pvfs_rename(const char *oldpath, const char *newpath)
305{
306    int rc;
307    char *absoldpath, *absnewpath;
308
309    absoldpath = PVFS_qualify_path(oldpath);
310    if (!absoldpath)
311    {
312        return -1;
313    }
314    absnewpath = PVFS_qualify_path(newpath);
315    if (!absnewpath && (oldpath != absoldpath))
316    {
317        /* This should only happen if path was not a PVFS_path */
318        PVFS_free_expanded(absoldpath);
319        return -1;
320    }
321    rc = iocommon_rename(NULL, absoldpath, NULL, absnewpath);
322    if (oldpath != absoldpath)
323    {
324        /* This should only happen if path was not a PVFS_path */
325        PVFS_free_expanded(absoldpath);
326    }
327    if (newpath != absnewpath)
328    {
329        /* This should only happen if path was not a PVFS_path */
330        PVFS_free_expanded(absnewpath);
331    }
332    return rc;
333}
334
335/**
336 * pvfs_renameat
337 */
338int pvfs_renameat(int olddirfd, const char *oldpath,
339                  int newdirfd, const char *newpath)
340{
341    int rc;
342    pvfs_descriptor *pd;
343    PVFS_object_ref *olddirref, *newdirref;
344    char *absoldpath, *absnewpath;
345
346    if (!oldpath || !newpath)
347    {
348        errno = EINVAL;
349        return -1;
350    }
351    if (oldpath[0] == '/' || olddirfd == AT_FDCWD)
352    {
353        olddirref = NULL;
354        absoldpath = PVFS_qualify_path(oldpath);
355        if (!absoldpath)
356        {
357            return -1;
358        }
359    }
360    else
361    {
362        if (olddirfd < 0)
363        {
364            errno = EBADF;
365            return -1;
366        }
367        pd = pvfs_find_descriptor(olddirfd);
368        if (!pd)
369        {
370            errno = EBADF;
371            return -1;
372        }
373        olddirref = &pd->s->pvfs_ref;
374        absoldpath = (char *)oldpath;
375    }
376    if (oldpath[0] == '/' || newdirfd == AT_FDCWD)
377    {
378        newdirref = NULL;
379        absnewpath = PVFS_qualify_path(newpath);
380        if (!absnewpath)
381        {
382            return -1;
383        }
384    }
385    else
386    {
387        if (newdirfd < 0)
388        {
389            errno = EBADF;
390            return -1;
391        }
392        pd = pvfs_find_descriptor(newdirfd);
393        if (!pd)
394        {
395            errno = EBADF;
396            return -1;
397        }
398        newdirref = &pd->s->pvfs_ref;
399        absnewpath = (char *)newpath;
400    }
401    rc = iocommon_rename(olddirref, absoldpath, newdirref, absnewpath);
402    if (oldpath != absoldpath)
403    {
404        /* This should only happen if path was not a PVFS_path */
405        PVFS_free_expanded(absoldpath);
406    }
407    if (newpath != absnewpath)
408    {
409        /* This should only happen if path was not a PVFS_path */
410        PVFS_free_expanded(absnewpath);
411    }
412    return rc;
413}
414
415/**
416 * pvfs_read wrapper
417 */
418ssize_t pvfs_read(int fd, void *buf, size_t count)
419{
420    int rc;
421
422    if (fd < 0)
423    {
424        errno = EBADF;
425        return -1;
426    }
427    pvfs_descriptor *pd = pvfs_find_descriptor(fd);
428    if (!pd)
429    {
430        return -1;
431    }
432    rc = pvfs_prdwr64(fd, buf, count, pd->s->file_pointer, PVFS_IO_READ);
433    if (rc < 0)
434    {
435        return -1;
436    }
437    gen_mutex_lock(&pd->s->lock);
438    pd->s->file_pointer += rc;
439    gen_mutex_unlock(&pd->s->lock);
440    return rc;
441}
442
443/**
444 * pvfs_pread wrapper
445 */
446ssize_t pvfs_pread(int fd, void *buf, size_t count, off_t offset)
447{
448    return pvfs_prdwr64(fd, buf, count, (off64_t) offset, PVFS_IO_READ);
449}
450
451/**
452 * pvfs_readv wrapper
453 */
454ssize_t pvfs_readv(int fd, const struct iovec *vector, int count)
455{
456    return pvfs_rdwrv(fd, vector, count, PVFS_IO_READ);
457}
458
459/**
460 * pvfs_pread64 wrapper
461 */
462ssize_t pvfs_pread64( int fd, void *buf, size_t count, off64_t offset )
463{
464    return pvfs_prdwr64(fd, buf, count, offset, PVFS_IO_READ);
465}
466
467/**
468 * pvfs_write wrapper
469 */
470ssize_t pvfs_write(int fd, const void *buf, size_t count)
471{
472    int rc;
473    off64_t offset;
474
475    if (fd < 0)
476    {
477        errno = EBADF;
478        return -1;
479    }
480    pvfs_descriptor *pd = pvfs_find_descriptor(fd);
481    if (!pd)
482    {
483        return -1;
484    }
485    /* check for append mode */
486    if (pd->s->flags & O_APPEND)
487    {
488        struct stat sbuf;
489        pvfs_fstat(fd, &sbuf);
490        offset = sbuf.st_size;
491    }
492    else
493    {
494        offset = pd->s->file_pointer;
495    }
496    rc = pvfs_prdwr64(fd, (void *)buf, count, offset, PVFS_IO_WRITE);
497    if (rc < 0)
498    {
499        return -1;
500    }
501    gen_mutex_lock(&pd->s->lock);
502    pd->s->file_pointer += rc;
503    gen_mutex_unlock(&pd->s->lock);
504    return rc;
505}
506
507/**
508 * pvfs_pwrite wrapper
509 */
510ssize_t pvfs_pwrite(int fd, const void *buf, size_t count, off_t offset)
511{
512    return pvfs_prdwr64(fd, (void *)buf, count, (off64_t)offset, PVFS_IO_WRITE);
513}
514
515/**
516 * pvfs_writev wrapper
517 */
518ssize_t pvfs_writev(int fd, const struct iovec *vector, int count)
519{
520    return pvfs_rdwrv(fd, vector, count, PVFS_IO_WRITE);
521}
522
523/**
524 * pvfs_pwrite64 wrapper
525 */
526ssize_t pvfs_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
527{
528    return pvfs_prdwr64(fd, (void *)buf, count, offset, PVFS_IO_WRITE);
529}
530
531/**
532 * implements pread and pwrite with 64-bit file pointers
533 */
534static ssize_t pvfs_prdwr64(int fd,
535                            void *buf,
536                            size_t size,
537                            off64_t offset,
538                            int which)
539{
540    int rc;
541    pvfs_descriptor* pd;
542    struct iovec vector[1];
543
544    /* Find the descriptor */
545    pd = pvfs_find_descriptor(fd);
546    if (!pd)
547    {
548        errno = EBADF;
549        return -1;
550    }
551
552    /* Ensure descriptor is used for the correct type of access */
553    if ((which == PVFS_IO_READ &&
554            (O_WRONLY == (pd->s->flags & O_ACCMODE))) ||
555        (which == PVFS_IO_WRITE &&
556            (O_RDONLY == (pd->s->flags & O_ACCMODE))))
557    {
558        errno = EBADF;
559        return -1;
560    }
561
562    /* place contiguous buff and count into an iovec array of length 1 */
563    vector[0].iov_base = buf;
564    vector[0].iov_len = size;
565
566    rc = iocommon_readorwrite(which, pd, offset, 1, vector);
567
568    return rc;
569}
570
571/**
572 * implements readv and writev
573 */
574static ssize_t pvfs_rdwrv(int fd,
575                          const struct iovec *vector,
576                          size_t count,
577                          int which)
578{
579    int rc = 0;
580    pvfs_descriptor* pd;
581    off64_t offset;
582
583    /* Find the descriptor */
584    pd = pvfs_find_descriptor(fd);
585    if(!pd)
586    {
587        return -1;
588    }
589    offset = pd->s->file_pointer;
590
591    /* Ensure descriptor is used for the correct type of access */
592    if ((which == PVFS_IO_READ &&
593            (O_WRONLY == (pd->s->flags & O_ACCMODE))) ||
594        (which == PVFS_IO_WRITE &&
595            (O_RDONLY == (pd->s->flags & O_ACCMODE))))
596    {
597        errno = EBADF;
598        return -1;
599    }
600
601    rc = iocommon_readorwrite(which, pd, offset, count, vector);
602
603    if (rc >= 0)
604    {
605        gen_mutex_lock(&pd->s->lock);
606        pd->s->file_pointer += rc;
607        gen_mutex_unlock(&pd->s->lock);
608    }
609
610    return rc;
611}
612
613/**
614 * pvfs_lseek wrapper
615 */
616off_t pvfs_lseek(int fd, off_t offset, int whence)
617{
618    return (off_t) pvfs_lseek64(fd, (off64_t)offset, whence);
619}
620
621/**
622 * pvfs_lseek64
623 */
624off64_t pvfs_lseek64(int fd, off64_t offset, int whence)
625{
626    pvfs_descriptor* pd;
627
628    if (fd < 0)
629    {
630        errno = EBADF;
631        return -1;
632    }
633    /* Find the descriptor */
634    pd = pvfs_find_descriptor(fd);
635    if (!pd)
636    {
637        errno = EBADF;
638        return -1;
639    }
640
641    iocommon_lseek(pd, offset, 1, whence);
642
643    return pd->s->file_pointer;
644}
645
646/**
647 * pvfs_truncate wrapper
648 */
649int pvfs_truncate(const char *path, off_t length)
650{
651    return pvfs_truncate64(path, (off64_t) length);
652}
653
654/**
655 * pvfs_truncate64
656 */
657int pvfs_truncate64(const char *path, off64_t length)
658{
659    int rc;
660    char *newpath;
661    pvfs_descriptor *pd;
662
663    newpath = PVFS_qualify_path(path);
664    if (!newpath)
665    {
666        errno = EINVAL;
667        return -1;
668    }
669    pd = iocommon_open(newpath, O_WRONLY, PVFS_HINT_NULL, 0 , NULL);
670    if (!pd || (pd->s->fsops == &glibc_ops))
671    {
672        if (!pd)
673        {
674            /* this is an error on open */
675            rc = -1;
676            goto errorout;
677        }
678        /* else this was symlink pointing from PVFS to non PVFS */
679        rc = glibc_ops.truncate(newpath, length);
680        pvfs_close(pd->fd);
681        goto errorout;
682    }
683    rc = iocommon_truncate(pd->s->pvfs_ref, length);
684    pvfs_close(pd->fd);
685
686errorout:
687    if (newpath != path)
688    {
689        /* This should only happen if path was not a PVFS_path */
690        PVFS_free_expanded(newpath);
691    }
692    return rc;
693}
694
695/**
696 * pvfs_allocate wrapper
697 *
698 * This isn't right but we dont' have a syscall to match this.
699 * Best effort is to tuncate to the size, which should guarantee
700 * space is available starting at beginning (let alone offset)
701 * extending to offset+length.
702 *
703 * Our truncate doesn't always allocate blocks either, since
704 * the underlying FS may have a sparse implementation.
705 */
706int pvfs_fallocate(int fd, off_t offset, off_t length)
707{
708    if (offset < 0 || length < 0)
709    {
710        errno = EINVAL;
711        return -1;
712    }
713    /* if (file_size < offset + length)
714     * {
715     */
716    return pvfs_ftruncate64(fd, (off64_t)(offset) + (off64_t)(length));
717}
718
719/**
720 * pvfs_ftruncate wrapper
721 */
722int pvfs_ftruncate(int fd, off_t length)
723{
724    return pvfs_ftruncate64(fd, (off64_t) length);
725}
726
727/**
728 * pvfs_ftruncate64
729 */
730int pvfs_ftruncate64(int fd, off64_t length)
731{
732    pvfs_descriptor *pd;
733   
734    if (fd < 0)
735    {
736        errno = EBADF;
737        return -1;
738    }
739    pd = pvfs_find_descriptor(fd);
740    if (!pd)
741    {
742        return -1;
743    }
744    return iocommon_truncate(pd->s->pvfs_ref, length);
745}
746
747/**
748 * pvfs_close
749 *
750 * TODO: add open/close count to minimize metadata ops
751 * this may only work if we have multi-user caching
752 * which we don't for now
753 */
754int pvfs_close(int fd)
755{
756    int rc = 0;
757    pvfs_descriptor* pd;
758    debug("pvfs_close: called with %d\n", fd);
759
760    if (fd < 0)
761    {
762        errno = EBADF;
763        return -1;
764    }
765    pd = pvfs_find_descriptor(fd);
766    if (!pd)
767    {
768        errno = EBADF;
769        return PVFS_FD_FAILURE;
770    }
771
772    /* flush buffers */
773    if (S_ISREG(pd->s->mode))
774    {
775        rc = iocommon_fsync(pd);
776        if (rc < 0)
777        {
778            return -1;
779        }
780    }
781
782    /* free descriptor */
783    rc = pvfs_free_descriptor(pd->fd);
784    if (rc < 0)
785    {
786        return -1;
787    }
788
789    debug("pvfs_close: returns %d\n", rc);
790    return rc;
791}
792
793/* various flavors of stat */
794/**
795 * pvfs_stat
796 */
797int pvfs_stat(const char *path, struct stat *buf)
798{
799    return pvfs_stat_mask(path, buf, PVFS_ATTR_DEFAULT_MASK);
800}
801
802int pvfs_stat_mask(const char *path, struct stat *buf, uint32_t mask)
803{
804    int rc;
805    char *newpath;
806    pvfs_descriptor *pd;
807
808    newpath = PVFS_qualify_path(path);
809    if (!newpath)
810    {
811        return -1;
812    }
813    pd = iocommon_open(newpath, O_RDONLY, PVFS_HINT_NULL, 0, NULL);
814    if (!pd || (pd->s->fsops == &glibc_ops))
815    {
816        if (!pd)
817        {
818            /* this is an error on open */
819            rc = -1;
820            goto errorout;
821        }
822        /* else this was symlink pointing from PVFS to non PVFS */
823        rc = glibc_ops.stat(newpath, buf);
824        pvfs_close(pd->fd);
825        goto errorout;
826    }
827    mask &= PVFS_ATTR_DEFAULT_MASK;
828    rc = iocommon_stat(pd, buf, mask);
829    pvfs_close(pd->fd);
830
831errorout:
832    if (newpath != path)
833    {
834        /* This should only happen if path was not a PVFS_path */
835        PVFS_free_expanded(newpath);
836    }
837    return rc;
838}
839
840/**
841 * pvfs_stat64
842 */
843int pvfs_stat64(const char *path, struct stat64 *buf)
844{
845    int rc;
846    char *newpath;
847    pvfs_descriptor *pd;
848
849    newpath = PVFS_qualify_path(path);
850    if (!newpath)
851    {
852        return -1;
853    }
854    pd = iocommon_open(newpath, O_RDONLY, PVFS_HINT_NULL, 0, NULL);
855    if (!pd || (pd->s->fsops == &glibc_ops))
856    {
857        if (!pd)
858        {
859            /* this is an error on open */
860            rc = -1;
861            goto errorout;
862        }
863        /* else this was symlink pointing from PVFS to non PVFS */
864        rc = glibc_ops.stat64(newpath, buf);
865        pvfs_close(pd->fd);
866        goto errorout;
867    }
868    rc = iocommon_stat64(pd, buf, PVFS_ATTR_DEFAULT_MASK);
869    pvfs_close(pd->fd);
870
871errorout:
872    if (newpath != path)
873    {
874        /* This should only happen if path was not a PVFS_path */
875        PVFS_free_expanded(newpath);
876    }
877    return rc;
878}
879
880/**
881 * pvfs_fstat
882 */
883int pvfs_fstat(int fd, struct stat *buf)
884{
885    return pvfs_fstat_mask(fd, buf, PVFS_ATTR_DEFAULT_MASK);
886}
887
888int pvfs_fstat_mask(int fd, struct stat *buf, uint32_t mask)
889{
890    pvfs_descriptor *pd;
891
892    if (fd < 0)
893    {
894        errno = EBADF;
895        return -1;
896    }
897    pd = pvfs_find_descriptor(fd);
898    if (!pd)
899    {
900        errno = EBADF;
901        return -1;
902    }
903    mask &= PVFS_ATTR_DEFAULT_MASK;
904    return iocommon_stat(pd, buf, mask);
905}
906
907/**
908 * pvfs_fstat64
909 */
910int pvfs_fstat64(int fd, struct stat64 *buf)
911{
912    pvfs_descriptor *pd;
913
914    if (fd < 0)
915    {
916        errno = EBADF;
917        return -1;
918    }
919    pd = pvfs_find_descriptor(fd);
920    if (!pd)
921    {
922        errno = EBADF;
923        return -1;
924    }
925    return iocommon_stat64(pd, buf, PVFS_ATTR_DEFAULT_MASK);
926}
927
928/**
929 * pvfs_fstatat
930 */
931int pvfs_fstatat(int fd, const char *path, struct stat *buf, int flag)
932{
933    int rc;
934    pvfs_descriptor *pd, *pd2;
935
936    if (path[0] == '/' || fd == AT_FDCWD)
937    {
938        if (flag & AT_SYMLINK_NOFOLLOW)
939        {
940            rc = pvfs_lstat(path, buf);
941        }
942        else
943        {
944            rc = pvfs_stat(path, buf);
945        }
946    }
947    else
948    {
949        int flags = O_RDONLY;
950        if (flag & AT_SYMLINK_NOFOLLOW)
951        {
952            flags |= O_NOFOLLOW;
953        }
954        if (fd < 0)
955        {
956            errno = EBADF;
957            return -1;
958        }
959        pd = pvfs_find_descriptor(fd);
960        if (!pd)
961        {
962            return -1;
963        }
964        pd2 = iocommon_open(path, flags, PVFS_HINT_NULL, 0, pd);
965        if (!pd2)
966        {
967            return -1;
968        }
969        rc = iocommon_stat(pd2, buf, PVFS_ATTR_DEFAULT_MASK);
970        pvfs_close(pd2->fd);
971    }
972    return rc;
973}
974
975/**
976 * pvfs_fstatat64
977 */
978int pvfs_fstatat64(int fd, const char *path, struct stat64 *buf, int flag)
979{
980    int rc;
981    pvfs_descriptor *pd, *pd2;
982
983    if (path[0] == '/' || fd == AT_FDCWD)
984    {
985        if (flag & AT_SYMLINK_NOFOLLOW)
986        {
987            rc = pvfs_lstat64(path, buf);
988        }
989        else
990        {
991            rc = pvfs_stat64(path, buf);
992        }
993    }
994    else
995    {
996        int flags = O_RDONLY;
997        if (flag & AT_SYMLINK_NOFOLLOW)
998        {
999            flags |= O_NOFOLLOW;
1000        }
1001        if (fd < 0)
1002        {
1003            errno = EBADF;
1004            return -1;
1005        }
1006        pd = pvfs_find_descriptor(fd);
1007        if (!pd)
1008        {
1009            errno = EBADF;
1010            return -1;
1011        }
1012        pd2 = iocommon_open(path, flags, PVFS_HINT_NULL, 0, pd);
1013        if (!pd2)
1014        {
1015            return -1;
1016        }
1017        rc = iocommon_stat64(pd2, buf, PVFS_ATTR_DEFAULT_MASK);
1018        pvfs_close(pd2->fd);
1019    }
1020    return rc;
1021}
1022
1023/**
1024 * pvfs_lstat
1025 */
1026int pvfs_lstat(const char *path, struct stat *buf)
1027{
1028    return pvfs_lstat_mask(path, buf, PVFS_ATTR_DEFAULT_MASK);
1029}
1030
1031int pvfs_lstat_mask(const char *path, struct stat *buf, uint32_t mask)
1032{
1033    int rc;
1034    char *newpath;
1035    pvfs_descriptor *pd;
1036
1037    newpath = PVFS_qualify_path(path);
1038    if (!newpath)
1039    {
1040        return -1;
1041    }
1042    pd = iocommon_open(newpath, O_RDONLY|O_NOFOLLOW, PVFS_HINT_NULL, 0, NULL);
1043    if (!pd || (pd->s->fsops == &glibc_ops))
1044    {
1045        if (!pd)
1046        {
1047            /* this is an error on open */
1048            rc = -1;
1049            goto errorout;
1050        }
1051        /* else this was symlink pointing from PVFS to non PVFS */
1052        rc = glibc_ops.lstat(newpath, buf);
1053        pvfs_close(pd->fd);
1054        goto errorout;
1055    }
1056    mask &= PVFS_ATTR_DEFAULT_MASK;
1057    rc = iocommon_stat(pd, buf, mask);
1058    pvfs_close(pd->fd);
1059
1060errorout:
1061    if (newpath != path)
1062    {
1063       /* This should only happen if path was not a PVFS_path */
1064       PVFS_free_expanded(newpath);
1065    }
1066    return rc;
1067}
1068
1069/**
1070 * pvfs_lstat64
1071 */
1072int pvfs_lstat64(const char *path, struct stat64 *buf)
1073{
1074    int rc;
1075    char *newpath;
1076    pvfs_descriptor *pd;
1077
1078    newpath = PVFS_qualify_path(path);
1079    if (!newpath)
1080    {
1081        return -1;
1082    }
1083    pd = iocommon_open(newpath, O_RDONLY|O_NOFOLLOW, PVFS_HINT_NULL, 0, NULL);
1084    if (!pd || (pd->s->fsops == &glibc_ops))
1085    {
1086        if (!pd)
1087        {
1088            /* this is an error on open */
1089            rc = -1;
1090            goto errorout;
1091        }
1092        /* else this was symlink pointing from PVFS to non PVFS */
1093        rc = glibc_ops.lstat64(newpath, buf);
1094        pvfs_close(pd->fd);
1095        goto errorout;
1096    }
1097    rc = iocommon_stat64(pd, buf, PVFS_ATTR_DEFAULT_MASK);
1098    pvfs_close(pd->fd);
1099
1100errorout:
1101    if (newpath != path)
1102    {
1103        /* This should only happen if path was not a PVFS_path */
1104        PVFS_free_expanded(newpath);
1105    }
1106    return rc;
1107}
1108
1109/**
1110 * pvfs_futimesat
1111 */
1112int pvfs_futimesat(int dirfd,
1113                   const char *path,
1114                   const struct timeval times[2])
1115{
1116    int rc = 0;
1117    pvfs_descriptor *pd=NULL, *pd2=NULL;
1118    PVFS_sys_attr attr;
1119
1120    if (dirfd < 0)
1121    {
1122        errno = EBADF;
1123        return -1;
1124    }
1125    pd = pvfs_find_descriptor(dirfd);
1126    if (!pd)
1127    {
1128        return -1;
1129    }
1130    if (path)
1131    {
1132        pd2 = iocommon_open(path, O_RDONLY, PVFS_HINT_NULL, 0, pd);
1133    }
1134    else
1135    {
1136        pd2 = pd; /* allow null path to work */
1137    }
1138    if (!pd2)
1139    {
1140        return -1;
1141    }
1142    memset(&attr, 0, sizeof(attr));
1143    if (!times)
1144    {
1145        struct timeval curtime;
1146        gettimeofday(&curtime, NULL);
1147        attr.atime = curtime.tv_sec;
1148        attr.mtime = curtime.tv_sec;
1149    }
1150    else
1151    {
1152        attr.atime = times[0].tv_sec;
1153        attr.mtime = times[1].tv_sec;
1154    }
1155    attr.mask = PVFS_ATTR_SYS_ATIME | PVFS_ATTR_SYS_MTIME;
1156    rc = iocommon_setattr(pd2->s->pvfs_ref, &attr);
1157    if (path)
1158    {
1159        pvfs_close(pd2->fd);
1160    }
1161    return rc;
1162}
1163
1164int pvfs_utimes(const char *path, const struct timeval times[2])
1165{
1166    return pvfs_futimesat(AT_FDCWD, path, times);
1167}
1168
1169int pvfs_utime(const char *path, const struct utimbuf *buf)
1170{
1171    struct timeval times[2];
1172    times[0].tv_sec = buf->actime;
1173    times[0].tv_usec = 0;
1174    times[1].tv_sec = buf->modtime;
1175    times[1].tv_usec = 0;
1176    return pvfs_futimesat(AT_FDCWD, path, times);
1177}
1178
1179int pvfs_futimes(int fd, const struct timeval times[2])
1180{
1181    int rc = 0;
1182    pvfs_descriptor *pd=NULL;
1183    PVFS_sys_attr attr;
1184
1185    if (fd < 0)
1186    {
1187        errno = EBADF;
1188        return -1;
1189    }
1190    pd = pvfs_find_descriptor(fd);
1191    if (!pd)
1192    {
1193        return -1;
1194    }
1195    memset(&attr, 0, sizeof(attr));
1196    if (!times)
1197    {
1198        struct timeval curtime;
1199        gettimeofday(&curtime, NULL);
1200        attr.atime = curtime.tv_sec;
1201        attr.mtime = curtime.tv_sec;
1202    }
1203    else
1204    {
1205        attr.atime = times[0].tv_sec;
1206        attr.mtime = times[1].tv_sec;
1207    }
1208    attr.mask = PVFS_ATTR_SYS_ATIME | PVFS_ATTR_SYS_MTIME;
1209    rc = iocommon_setattr(pd->s->pvfs_ref, &attr);
1210    pvfs_close(pd->fd);
1211    return rc;
1212}
1213
1214/**
1215 * pvfs_dup
1216 */
1217int pvfs_dup(int oldfd)
1218{
1219    return pvfs_dup_descriptor(oldfd, -1);
1220}
1221
1222/**
1223 * pvfs_dup2
1224 */
1225int pvfs_dup2(int oldfd, int newfd)
1226{
1227    return pvfs_dup_descriptor(oldfd, newfd);
1228}
1229
1230/**
1231 * pvfs_chown
1232 */
1233int pvfs_chown(const char *path, uid_t owner, gid_t group)
1234{
1235    int rc;
1236    char *newpath;
1237    pvfs_descriptor *pd;
1238
1239    newpath = PVFS_qualify_path(path);
1240    if (!newpath)
1241    {
1242        return -1;
1243    }
1244    pd = iocommon_open(newpath, O_RDONLY, PVFS_HINT_NULL, 0, NULL);
1245    if (!pd || (pd->s->fsops == &glibc_ops))
1246    {
1247        if (!pd)
1248        {
1249            /* this is an error on open */
1250            rc = -1;
1251            goto errorout;
1252        }
1253        /* else this was symlink pointing from PVFS to non PVFS */
1254        rc = glibc_ops.chown(newpath, owner, group);
1255        pvfs_close(pd->fd);
1256        goto errorout;
1257    }
1258    rc = iocommon_chown(pd, owner, group);
1259    pvfs_close(pd->fd);
1260
1261errorout:
1262    if (newpath != path)
1263    {
1264        /* This should only happen if path was not a PVFS_path */
1265        PVFS_free_expanded(newpath);
1266    }
1267    return rc;
1268}
1269
1270/**
1271 * pvfs_fchown
1272 */
1273int pvfs_fchown(int fd, uid_t owner, gid_t group)
1274{
1275    pvfs_descriptor *pd;
1276
1277    if (fd < 0)
1278    {
1279        errno = EBADF;
1280        return -1;
1281    }
1282    pd = pvfs_find_descriptor(fd);
1283    if (!pd)
1284    {
1285        errno = EBADF;
1286        return -1;
1287    }
1288    return iocommon_chown(pd, owner, group);
1289}
1290
1291/**
1292 * pvfs_fchownat
1293 */
1294int pvfs_fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag)
1295{
1296    int rc;
1297    pvfs_descriptor *pd, *pd2;
1298
1299    if (path[0] == '/' || fd == AT_FDCWD)
1300    {
1301        if (flag & AT_SYMLINK_NOFOLLOW)
1302        {
1303            rc = pvfs_lchown(path, owner, group);
1304        }
1305        else
1306        {
1307            rc = pvfs_chown(path, owner, group);
1308        }
1309    }
1310    else
1311    {
1312        int flags = O_RDONLY;
1313        if (flag & AT_SYMLINK_NOFOLLOW)
1314        {
1315            flags |= O_NOFOLLOW;
1316        }
1317        if (fd < 0)
1318        {
1319            errno = EBADF;
1320            return -1;
1321        }
1322        pd = pvfs_find_descriptor(fd);
1323        if (!pd)
1324        {
1325            return -1;
1326        }
1327        pd2 = iocommon_open(path, flags, PVFS_HINT_NULL, 0, pd);
1328        if (!pd)
1329        {
1330            return -1;
1331        }
1332        rc = iocommon_chown(pd2, owner, group);
1333        pvfs_close(pd2->fd);
1334    }
1335    return rc;
1336}
1337
1338/**
1339 * pvfs_lchown
1340 */
1341int pvfs_lchown(const char *path, uid_t owner, gid_t group)
1342{
1343    int rc;
1344    char *newpath;
1345    pvfs_descriptor *pd;
1346
1347    newpath = PVFS_qualify_path(path);
1348    if (!newpath)
1349    {
1350        return -1;
1351    }
1352    pd = iocommon_open(newpath, O_RDONLY|O_NOFOLLOW, PVFS_HINT_NULL, 0, NULL);
1353    if (!pd || (pd->s->fsops == &glibc_ops))
1354    {
1355        if (!pd)
1356        {
1357            /* this is an error on open */
1358            rc = -1;
1359            goto errorout;
1360        }
1361        /* else this was symlink pointing from PVFS to non PVFS */
1362        rc = glibc_ops.lchown(newpath, owner, group);
1363        pvfs_close(pd->fd);
1364        goto errorout;
1365    }
1366    rc = iocommon_chown(pd, owner, group);
1367    pvfs_close(pd->fd);
1368
1369errorout:
1370    if (newpath != path)
1371    {
1372        /* This should only happen if path was not a PVFS_path */
1373        PVFS_free_expanded(newpath);
1374    }
1375    return rc;
1376}
1377
1378/**
1379 * pvfs_chmod
1380 */
1381int pvfs_chmod(const char *path, mode_t mode)
1382{
1383    int rc;
1384    char *newpath;
1385    pvfs_descriptor *pd;
1386
1387    newpath = PVFS_qualify_path(path);
1388    if (!newpath)
1389    {
1390        return -1;
1391    }
1392    pd = iocommon_open(newpath, O_RDONLY, PVFS_HINT_NULL, 0, NULL);
1393    if (!pd || (pd->s->fsops == &glibc_ops))
1394    {
1395        if (!pd)
1396        {
1397            /* this is an error on open */
1398            rc = -1;
1399            goto errorout;
1400        }
1401        /* else this was symlink pointing from PVFS to non PVFS */
1402        rc = glibc_ops.chmod(newpath, mode);
1403        pvfs_close(pd->fd);
1404        goto errorout;
1405    }
1406    rc = iocommon_chmod(pd, mode);
1407    pvfs_close(pd->fd);
1408
1409errorout:
1410    if (newpath != path)
1411    {
1412        /* This should only happen if path was not a PVFS_path */
1413        PVFS_free_expanded(newpath);
1414    }
1415    return rc;
1416}
1417
1418/**
1419 * pvfs_fchmod
1420 */
1421int pvfs_fchmod(int fd, mode_t mode)
1422{
1423    pvfs_descriptor *pd;
1424
1425    if (fd < 0)
1426    {
1427        errno = EBADF;
1428        return -1;
1429    }
1430    pd = pvfs_find_descriptor(fd);
1431    if (!pd)
1432    {
1433        errno = EBADF;
1434        return -1;
1435    }
1436    return iocommon_chmod(pd, mode);
1437}
1438
1439/**
1440 * pvfs_fchmodat
1441 */
1442int pvfs_fchmodat(int fd, const char *path, mode_t mode, int flag)
1443{
1444    int rc;
1445    pvfs_descriptor *pd, *pd2;
1446
1447    if (path[0] == '/' || fd == AT_FDCWD)
1448    {
1449        rc = pvfs_chmod(path, mode);
1450    }
1451    else
1452    {
1453        int flags = O_RDONLY;
1454        if (fd < 0)
1455        {
1456            errno = EBADF;
1457            return -1;
1458        }
1459        pd = pvfs_find_descriptor(fd);
1460        if (!pd)
1461        {
1462            return -1;
1463        }
1464        pd2 = iocommon_open(path, flags, PVFS_HINT_NULL, 0, pd);
1465        if (!pd2)
1466        {
1467            return -1;
1468        }
1469        rc = iocommon_chmod(pd2, mode);
1470        pvfs_close(pd2->fd);
1471    }
1472    return rc;
1473}
1474
1475/**
1476 * pvfs_mkdir
1477 */
1478int pvfs_mkdir(const char *path, mode_t mode)
1479{
1480    int rc;
1481    char *newpath;
1482
1483    newpath = PVFS_qualify_path(path);
1484    if (!newpath)
1485    {
1486        return -1;
1487    }
1488    rc = iocommon_make_directory(newpath, (mode & ~mask_val & 0777), NULL);
1489    if (newpath != path)
1490    {
1491        /* This should only happen if path was not a PVFS_path */
1492        PVFS_free_expanded(newpath);
1493    }
1494    return rc;
1495}
1496
1497/**
1498 * pvfs_mkdirat
1499 */
1500int pvfs_mkdirat(int dirfd, const char *path, mode_t mode)
1501{
1502    int rc;
1503    pvfs_descriptor *pd;
1504
1505    if (path[0] == '/' || dirfd == AT_FDCWD)
1506    {
1507        rc = pvfs_mkdir(path, mode);
1508    }
1509    else
1510    {
1511        if (dirfd < 0)
1512        {
1513            errno = EBADF;
1514            return -1;
1515        }
1516        pd = pvfs_find_descriptor(dirfd);
1517        if (!pd)
1518        {
1519            errno = EBADF;
1520            return -1;
1521        }
1522        rc = iocommon_make_directory(path,
1523                                     (mode & ~mask_val & 0777),
1524                                     &pd->s->pvfs_ref);
1525    }
1526    return rc;
1527}
1528
1529/**
1530 * pvfs_rmdir
1531 */
1532int pvfs_rmdir(const char *path)
1533{
1534    int rc;
1535    char *newpath;
1536
1537    newpath = PVFS_qualify_path(path);
1538    if (!newpath)
1539    {
1540        return -1;
1541    }
1542    rc = iocommon_rmdir(newpath, NULL);
1543    if (newpath != path)
1544    {
1545        /* This should only happen if path was not a PVFS_path */
1546        PVFS_free_expanded(newpath);
1547    }
1548    return rc;
1549}
1550
1551/**
1552 * readlink fills buffer with contents of a symbolic link
1553 *
1554 */
1555ssize_t pvfs_readlink(const char *path, char *buf, size_t bufsiz)
1556{
1557    int rc;
1558    char *newpath;
1559    pvfs_descriptor *pd;
1560
1561    newpath = PVFS_qualify_path(path);
1562    if (!newpath)
1563    {
1564        return -1;
1565    }
1566    pd = iocommon_open(newpath, O_RDONLY | O_NOFOLLOW, PVFS_HINT_NULL, 0, NULL);
1567    if (!pd || (pd->s->fsops == &glibc_ops))
1568    {
1569        if (!pd)
1570        {
1571            /* this is an error on open */
1572            rc = -1;
1573            goto errorout;
1574        }
1575        /* else this was symlink pointing from PVFS to non PVFS */
1576        rc = glibc_ops.readlink(newpath, buf, bufsiz);
1577        pvfs_close(pd->fd);
1578        goto errorout;
1579    }
1580    debug("pvfs_readlink mode is %o\n", pd->s->mode);
1581    /* this checks that it is a valid symlink and sets errno if not */
1582    rc = iocommon_readlink(pd, buf, bufsiz);
1583    /* need to close if readlink succeeds or not */
1584    pvfs_close(pd->fd);
1585
1586errorout:
1587    if (newpath != path)
1588    {
1589       /* This should only happen if path was not a PVFS_path */
1590       PVFS_free_expanded(newpath);
1591    }
1592    return rc;
1593}
1594
1595ssize_t pvfs_readlinkat(int fd, const char *path, char *buf, size_t bufsiz)
1596{
1597    int rc;
1598    pvfs_descriptor *pd, *pd2;
1599
1600    if (path[0] == '/' || fd == AT_FDCWD)
1601    {
1602        rc = pvfs_readlink(path, buf, bufsiz);
1603    }
1604    else
1605    {
1606        int flags = O_RDONLY | O_NOFOLLOW;
1607        if (fd < 0)
1608        {
1609            errno = EBADF;
1610            return -1;
1611        }
1612        pd = pvfs_find_descriptor(fd);
1613        if (!pd)
1614        {
1615            return -1;
1616        }
1617        pd2 = iocommon_open(path, flags, PVFS_HINT_NULL, 0, pd);
1618        if(!pd2)
1619        {
1620            return -1;
1621        }
1622        rc = iocommon_readlink(pd2, buf, bufsiz);
1623        pvfs_close(pd2->fd);
1624    }
1625    return rc;
1626}
1627
1628int pvfs_symlink(const char *oldpath, const char *newpath)
1629{
1630    int rc = 0;
1631    char *abspath;
1632    abspath = PVFS_qualify_path(newpath);
1633    if (!abspath)
1634    {
1635        return -1;
1636    }
1637    rc = iocommon_symlink(abspath, oldpath, NULL);
1638    if (abspath != newpath)
1639    {
1640       /* This should only happen if path was not a PVFS_path */
1641       PVFS_free_expanded(abspath);
1642    }
1643    return rc;
1644}
1645
1646int pvfs_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
1647{
1648    pvfs_descriptor *pd;
1649
1650    if (newpath[0] == '/' || newdirfd == AT_FDCWD)
1651    {
1652        return pvfs_symlink(oldpath, newpath);
1653    }
1654    else
1655    {
1656        if (newdirfd < 0)
1657        {
1658            errno = EBADF;
1659            return -1;
1660        }
1661        pd = pvfs_find_descriptor(newdirfd);
1662        if (!pd)
1663        {
1664            errno = EBADF;
1665            return -1;
1666        }
1667    }
1668    return iocommon_symlink(newpath, oldpath, &pd->s->pvfs_ref);
1669}
1670
1671/**
1672 * PVFS does not have hard links
1673 */
1674int pvfs_link(const char *oldpath, const char *newpath)
1675{
1676    fprintf(stderr, "pvfs_link not implemented\n");
1677    errno = ENOSYS;
1678    return -1;
1679}
1680
1681/**
1682 * PVFS does not have hard links
1683 */
1684int pvfs_linkat(int olddirfd, const char *oldpath,
1685                int newdirfd, const char *newpath, int flags)
1686{
1687    fprintf(stderr, "pvfs_linkat not implemented\n");
1688    errno = ENOSYS;
1689    return -1;
1690}
1691
1692/**
1693 * this reads exactly one dirent, count is ignored
1694 */
1695int pvfs_readdir(unsigned int fd, struct dirent *dirp, unsigned int count)
1696{
1697    return pvfs_getdents(fd, dirp, 1);
1698}
1699
1700/**
1701 * this reads multiple dirents, man pages calls last arg count but
1702 * is ambiguous if it is number of records or number of bytes.  latter
1703 * appears to be true so we renmame size.  Returns bytes read.
1704 */
1705int pvfs_getdents(unsigned int fd, struct dirent *dirp, unsigned int size)
1706{
1707    pvfs_descriptor *pd;
1708
1709    if (fd < 0)
1710    {
1711        errno = EBADF;
1712        return -1;
1713    }
1714    pd = pvfs_find_descriptor(fd);
1715    if (!pd)
1716    {
1717        errno = EBADF;
1718        return -1;
1719    }
1720    return iocommon_getdents(pd, dirp, size);
1721}
1722
1723int pvfs_getdents64(unsigned int fd, struct dirent64 *dirp, unsigned int size)
1724{
1725    pvfs_descriptor *pd;
1726
1727    if (fd < 0)
1728    {
1729        errno = EBADF;
1730        return -1;
1731    }
1732    pd = pvfs_find_descriptor(fd);
1733    if (!pd)
1734    {
1735        errno = EBADF;
1736        return -1;
1737    }
1738    return iocommon_getdents64(pd, dirp, size);
1739}
1740
1741int pvfs_access(const char *path, int mode)
1742{
1743    int rc = 0;
1744    char *newpath;
1745    newpath = PVFS_qualify_path(path);
1746    if (!newpath)
1747    {
1748        return -1;
1749    }
1750    rc = iocommon_access(path, mode, 0, NULL);
1751    if (newpath != path)
1752    {
1753        /* This should only happen if path was not a PVFS_path */
1754        PVFS_free_expanded(newpath);
1755    }
1756    return rc;
1757}
1758
1759int pvfs_faccessat(int fd, const char *path, int mode, int flags)
1760{
1761    pvfs_descriptor *pd;
1762
1763    if (path[0] == '/' || fd == AT_FDCWD)
1764    {
1765        return pvfs_access(path, mode);
1766    }
1767    else
1768    {
1769        if (fd < 0)
1770        {
1771            errno = EBADF;
1772            return -1;
1773        }
1774        pd = pvfs_find_descriptor(fd);
1775        if(!pd)
1776        {
1777            errno = EBADF;
1778            return -1;
1779        }
1780    }
1781    return iocommon_access(path, mode, flags, &pd->s->pvfs_ref);
1782}
1783
1784int pvfs_flock(int fd, int op)
1785{
1786    errno = ENOSYS;
1787    fprintf(stderr, "pvfs_flock not implemented\n");
1788    return -1;
1789}
1790
1791int pvfs_fcntl(int fd, int cmd, ...)
1792{
1793    int rc = 0;
1794    va_list ap;
1795    /* long arg; */
1796    struct flock *lock;
1797    pvfs_descriptor *pd;
1798
1799    pd = pvfs_find_descriptor(fd);
1800    if (!pd)
1801    {
1802        errno = EBADF;
1803        rc = -1;
1804        goto errorout;
1805    }
1806    va_start(ap, cmd);
1807    switch (cmd)
1808    {
1809    case F_DUPFD :
1810    case F_GETFD :
1811        rc = pd->fdflags;
1812        break;
1813    case F_SETFD :
1814        pd->fdflags = va_arg(ap, int);
1815        break;
1816    case F_GETFL :
1817        rc = pd->s->flags;
1818        break;
1819    case F_SETFL :
1820        pd->s->flags = va_arg(ap, int);
1821        break;
1822    case F_GETLK :
1823    case F_SETLK :
1824    case F_SETLKW :
1825        lock = va_arg(ap, struct flock *);
1826    case F_GETOWN :
1827    case F_SETOWN :
1828    case F_GETSIG :
1829    case F_SETSIG :
1830    case F_GETLEASE :
1831    case F_SETLEASE :
1832    case F_NOTIFY :
1833    default :
1834        errno = ENOSYS;
1835        fprintf(stderr, "pvfs_fcntl command not implemented\n");
1836        rc = -1;
1837        break;
1838    }
1839    va_end(ap);
1840
1841errorout :
1842    return rc;
1843}
1844
1845/* sync all disk data */
1846void pvfs_sync(void )
1847{
1848    return;
1849}
1850
1851/**
1852 * pvfs_fsync
1853 * sync file, but not dir it is in
1854 * as close as we have for now
1855 */
1856int pvfs_fsync(int fd)
1857{
1858    int rc = 0;
1859    pvfs_descriptor* pd;
1860
1861    debug("pvfs_fsync: called with %d\n", fd);
1862
1863    if (fd < 0)
1864    {
1865        errno = EBADF;
1866        return -1;
1867    }
1868    /* Find the descriptor */
1869    pd = pvfs_find_descriptor(fd);
1870    if (!pd)
1871    {
1872        errno = EBADF;
1873        return -1;
1874    }
1875
1876    /* tell the server to flush data to disk */
1877    rc = iocommon_fsync(pd);
1878    debug("pvfs_fsync: returns %d\n", rc);
1879    return rc;
1880}
1881
1882/* does not sync file metadata */
1883int pvfs_fdatasync(int fd)
1884{
1885    int rc = 0;
1886
1887    rc = pvfs_fsync(fd); /* as close as we have for now */
1888    return rc;
1889}
1890
1891int pvfs_fadvise(int fd, off_t offset, off_t len, int advice)
1892{
1893    return pvfs_fadvise64(fd, (off64_t) offset, (off64_t)len, advice);
1894}
1895
1896/** fadvise implementation
1897 *
1898 * technically this is a hint, so doing nothing is still success
1899 */
1900int pvfs_fadvise64(int fd, off64_t offset, off64_t len, int advice)
1901{
1902    switch (advice)
1903    {
1904    case POSIX_FADV_NORMAL:
1905    case POSIX_FADV_RANDOM:
1906    case POSIX_FADV_SEQUENTIAL:
1907    case POSIX_FADV_WILLNEED:
1908    case POSIX_FADV_DONTNEED:
1909    case POSIX_FADV_NOREUSE:
1910        break;
1911    default:
1912        errno = EINVAL;
1913        return -1;
1914    }
1915    return 0;
1916}
1917
1918int pvfs_statfs(const char *path, struct statfs *buf)
1919{
1920    int rc;
1921    char *newpath;
1922    pvfs_descriptor *pd;
1923
1924    newpath = PVFS_qualify_path(path);
1925    if (!newpath)
1926    {
1927        return -1;
1928    }
1929    pd = iocommon_open(newpath, O_RDONLY, PVFS_HINT_NULL, 0, NULL);
1930    if (!pd || (pd->s->fsops == &glibc_ops))
1931    {
1932        if (!pd)
1933        {
1934            /* this is an error on open */
1935            rc = -1;
1936            goto errorout;
1937        }
1938        /* else this was symlink pointing from PVFS to non PVFS */
1939        rc = glibc_ops.statfs(newpath, buf);
1940        pvfs_close(pd->fd);
1941        goto errorout;
1942    }
1943    rc = iocommon_statfs(pd, buf);
1944    pvfs_close(pd->fd);
1945
1946errorout:
1947    if (newpath != path)
1948    {
1949        /* This should only happen if path was not a PVFS_path */
1950        PVFS_free_expanded(newpath);
1951    }
1952    return rc;
1953}
1954
1955int pvfs_statfs64(const char *path, struct statfs64 *buf)
1956{
1957    int rc;
1958    char *newpath;
1959    pvfs_descriptor *pd;
1960
1961    newpath = PVFS_qualify_path(path);
1962    if (!newpath)
1963    {
1964        return -1;
1965    }
1966    pd = iocommon_open(newpath, O_RDONLY, PVFS_HINT_NULL, 0, NULL);
1967    if (!pd || (pd->s->fsops == &glibc_ops))
1968    {
1969        if (!pd)
1970        {
1971            /* this is an error on open */
1972            rc = -1;
1973            goto errorout;
1974        }
1975        /* else this was symlink pointing from PVFS to non PVFS */
1976        rc = glibc_ops.statfs64(newpath, buf);
1977        pvfs_close(pd->fd);
1978        goto errorout;
1979    }
1980    rc = iocommon_statfs64(pd, buf);
1981    pvfs_close(pd->fd);
1982
1983errorout:
1984    if (newpath != path)
1985    {
1986        /* This should only happen if path was not a PVFS_path */
1987        PVFS_free_expanded(newpath);
1988    }
1989    return rc;
1990}
1991
1992int pvfs_fstatfs(int fd, struct statfs *buf)
1993{
1994    pvfs_descriptor *pd;
1995
1996    if (fd < 0)
1997    {
1998        errno = EBADF;
1999        return -1;
2000    }
2001    pd = pvfs_find_descriptor(fd);
2002    if (!pd)
2003    {
2004        errno = EBADF;
2005        return -1;
2006    }
2007    return iocommon_statfs(pd, buf);
2008}
2009
2010int pvfs_fstatfs64(int fd, struct statfs64 *buf)
2011{
2012    pvfs_descriptor *pd;
2013
2014    if (fd < 0)
2015    {
2016        errno = EBADF;
2017        return -1;
2018    }
2019    pd = pvfs_find_descriptor(fd);
2020    if (!pd)
2021    {
2022        errno = EBADF;
2023        return -1;
2024    }
2025    return iocommon_statfs64(pd, buf);
2026}
2027
2028int pvfs_statvfs(const char *path, struct statvfs *buf)
2029{
2030    int rc = 0;
2031    pvfs_descriptor *pd;
2032    struct statfs buf2;
2033    char *newpath;
2034
2035    newpath = PVFS_qualify_path(path);
2036    if (!newpath)
2037    {
2038        return -1;
2039    }
2040    pd = iocommon_open(newpath, O_RDONLY, PVFS_HINT_NULL, 0, NULL);
2041    if (!pd || (pd->s->fsops == &glibc_ops))
2042    {
2043        if (!pd)
2044        {
2045            /* this is an error on open */
2046            rc = -1;
2047            goto errorout;
2048        }
2049        /* else this was symlink pointing from PVFS to non PVFS */
2050        rc = glibc_ops.statvfs(newpath, buf);
2051        pvfs_close(pd->fd);
2052        goto errorout;
2053    }
2054    rc = iocommon_statfs(pd, &buf2);
2055    pvfs_close(pd->fd);
2056    if (rc < 0)
2057    {
2058        goto errorout;
2059    }
2060    buf->f_bsize = buf2.f_bsize;
2061    /* buf->f_rsize */
2062    buf->f_blocks = buf2.f_blocks;
2063    buf->f_bfree = buf2.f_bfree;
2064    buf->f_bavail = buf2.f_bavail;
2065    buf->f_files = buf2.f_files;
2066    buf->f_ffree = buf2.f_ffree;
2067    /* buf->f_favail */
2068    buf->f_fsid = (unsigned long)buf2.f_fsid.__val[0];
2069    /* buf->f_flag */
2070    buf->f_namemax = buf2.f_namelen;
2071
2072errorout:
2073    if (newpath != path)
2074    {
2075        /* This should only happen if path was not a PVFS_path */
2076        PVFS_free_expanded(newpath);
2077    }
2078    return rc;
2079}
2080
2081int pvfs_fstatvfs(int fd, struct statvfs *buf)
2082{
2083    int rc = 0;
2084    pvfs_descriptor *pd;
2085    struct statfs buf2;
2086
2087    if (fd < 0)
2088    {
2089        errno = EBADF;
2090        return -1;
2091    }
2092    pd = pvfs_find_descriptor(fd);
2093    if (!pd)
2094    {
2095        errno = EBADF;
2096        return -1;
2097    }
2098    rc = iocommon_statfs(pd, &buf2);
2099    if (rc < 0)
2100    {
2101        return -1;
2102    }
2103    buf->f_bsize = buf2.f_bsize;
2104    /* buf->f_rsize */
2105    buf->f_blocks = buf2.f_blocks;
2106    buf->f_bfree = buf2.f_bfree;
2107    buf->f_bavail = buf2.f_bavail;
2108    buf->f_files = buf2.f_files;
2109    buf->f_ffree = buf2.f_ffree;
2110    /* buf->f_favail */
2111    buf->f_fsid = (unsigned long)buf2.f_fsid.__val[0];
2112    /* buf->f_flag */
2113    buf->f_namemax = buf2.f_namelen;
2114    return rc;
2115}
2116
2117int pvfs_mknod(const char *path, mode_t mode, dev_t dev)
2118{
2119    return pvfs_mknodat(AT_FDCWD, path, mode, dev);
2120}
2121
2122int pvfs_mknodat(int dirfd, const char *path, mode_t mode, dev_t dev)
2123{
2124    int fd;
2125    /* int s_type = mode & S_IFMT; */
2126   
2127    switch (dev)
2128    {
2129    case S_IFREG:
2130        fd = pvfs_openat(dirfd, path, O_CREAT|O_EXCL|O_RDONLY, mode & 0x777);
2131        if (fd < 0)
2132        {
2133            return -1;
2134        }
2135        pvfs_close(fd);
2136        break;
2137    case S_IFCHR:
2138    case S_IFBLK:
2139    case S_IFIFO:
2140    case S_IFSOCK:
2141    default:
2142        errno = EINVAL;
2143        return -1;
2144    }
2145    return 0;
2146}
2147
2148ssize_t pvfs_sendfile(int outfd, int infd, off_t *offset, size_t count)
2149{
2150    return pvfs_sendfile64(outfd, infd, (off64_t *)offset, count);
2151}
2152                 
2153ssize_t pvfs_sendfile64(int outfd, int infd, off64_t *offset, size_t count)
2154{
2155    pvfs_descriptor *inpd, *outpd;
2156
2157    inpd = pvfs_find_descriptor(infd);
2158    outpd = pvfs_find_descriptor(outfd);  /* this should be  a socket */
2159    if (!inpd || !outpd)
2160    {
2161        errno = EBADF;
2162        return -1;
2163    }
2164    return iocommon_sendfile(outpd->true_fd, inpd, offset, count);
2165}
2166
2167int pvfs_setxattr(const char *path,
2168                  const char *name,
2169                  const void *value,
2170                  size_t size,
2171                  int flags)
2172{
2173    int fd, rc = 0;
2174
2175    fd = pvfs_open(path, O_RDWR);
2176    if (fd < 0)
2177    {
2178        return fd;
2179    }
2180    rc = pvfs_fsetxattr(fd, name, value, size, flags);
2181    pvfs_close(fd);
2182    return rc;
2183}
2184
2185int pvfs_lsetxattr(const char *path,
2186                   const char *name,
2187                   const void *value,
2188                   size_t size,
2189                   int flags)
2190{
2191    int fd, rc = 0;
2192
2193    fd = pvfs_open(path, O_RDWR | O_NOFOLLOW);
2194    if (fd < 0)
2195    {
2196        return fd;
2197    }
2198    rc = pvfs_fsetxattr(fd, name, value, size, flags);
2199    pvfs_close(fd);
2200    return rc;
2201}
2202
2203int pvfs_fsetxattr(int fd,
2204                   const char *name,
2205                   const void *value,
2206                   size_t size,
2207                   int flags)
2208{
2209    int rc = 0;
2210    pvfs_descriptor *pd;
2211
2212    pd = pvfs_find_descriptor(fd);
2213    if (!pd)
2214    {
2215        errno = EBADF;
2216        return -1;
2217    }
2218    rc = iocommon_seteattr(pd, name, value, size, flags);
2219    return rc;
2220}
2221
2222ssize_t pvfs_getxattr(const char *path,
2223                      const char *name,
2224                      void *value,
2225                      size_t size)
2226{
2227    int fd, rc = 0;
2228
2229    fd = pvfs_open(path, O_RDWR);
2230    if (fd < 0)
2231    {
2232        return fd;
2233    }
2234    rc = pvfs_fgetxattr(fd, name, value, size);
2235    pvfs_close(fd);
2236    return rc;
2237}
2238
2239ssize_t pvfs_lgetxattr(const char *path,
2240                       const char *name,
2241                       void *value,
2242                       size_t size)
2243{
2244    int fd, rc = 0;
2245
2246    fd = pvfs_open(path, O_RDWR | O_NOFOLLOW);
2247    if (fd < 0)
2248    {
2249        return fd;
2250    }
2251    rc = pvfs_fgetxattr(fd, name, value, size);
2252    pvfs_close(fd);
2253    return rc;
2254}
2255
2256ssize_t pvfs_fgetxattr(int fd,
2257                       const char *name,
2258                       void *value,
2259                       size_t size)
2260{
2261    pvfs_descriptor *pd;
2262
2263    pd = pvfs_find_descriptor(fd);
2264    if (!pd)
2265    {
2266        errno = EBADF;
2267        return -1;
2268    }
2269    return iocommon_geteattr(pd, name, value, size);
2270}
2271
2272ssize_t pvfs_listxattr(const char *path,
2273                       char *list,
2274                       size_t size)
2275{
2276    int fd, rc = 0;
2277
2278    fd = pvfs_open(path, O_RDWR);
2279    if (fd < 0)
2280    {
2281        return fd;
2282    }
2283    rc = pvfs_flistxattr(fd, list, size);
2284    pvfs_close(fd);
2285    return rc;
2286}
2287
2288ssize_t pvfs_llistxattr(const char *path,
2289                        char *list,
2290                        size_t size)
2291{
2292    int fd, rc = 0;
2293
2294    fd = pvfs_open(path, O_RDWR | O_NOFOLLOW);
2295    if (fd < 0)
2296    {
2297        return fd;
2298    }
2299    rc = pvfs_flistxattr(fd, list, size);
2300    pvfs_close(fd);
2301    return rc;
2302}
2303
2304ssize_t pvfs_flistxattr(int fd,
2305                        char *list,
2306                        size_t size)
2307{
2308    int retsize, rc = 0;
2309    pvfs_descriptor *pd;
2310
2311    pd = pvfs_find_descriptor(fd);
2312    if (!pd)
2313    {
2314        errno = EBADF;
2315        return -1;
2316    }
2317    rc = iocommon_listeattr(pd, list, size, &retsize);
2318    if (rc < 0)
2319    {
2320        return -1;
2321    }
2322    return retsize;
2323}
2324
2325int pvfs_removexattr(const char *path,
2326                     const char *name)
2327{
2328    int fd, rc = 0;
2329
2330    fd = pvfs_open(path, O_RDWR);
2331    if (fd < 0)
2332    {
2333        return fd;
2334    }
2335    rc = pvfs_fremovexattr(fd, name);
2336    pvfs_close(fd);
2337    return rc;
2338}
2339
2340int pvfs_lremovexattr(const char *path,
2341                      const char *name)
2342{
2343    int fd, rc = 0;
2344
2345    fd = pvfs_open(path, O_RDWR | O_NOFOLLOW);
2346    if (fd < 0)
2347    {
2348        return fd;
2349    }
2350    rc = pvfs_fremovexattr(fd, name);
2351    pvfs_close(fd);
2352    return rc;
2353}
2354
2355int pvfs_fremovexattr(int fd,
2356                      const char *name)
2357{
2358    pvfs_descriptor *pd;
2359
2360    pd = pvfs_find_descriptor(fd);
2361    if (!pd)
2362    {
2363        errno = EBADF;
2364        return -1;
2365    }
2366    return iocommon_deleattr(pd, name);
2367}
2368
2369/* These functions simulate management of the current
2370 * working directory given than the kernel may not
2371 * be aware of PVFS virtual mounts
2372 */
2373int pvfs_cwd_init()
2374{
2375    int rc = 0;
2376    int plen = 0;
2377    char *rv, buf[PVFS_PATH_MAX];
2378    memset(buf, 0, PVFS_PATH_MAX);
2379    memset(pvfs_cwd, 0, PVFS_PATH_MAX);
2380    /* use env to start path - only thing we can depend on
2381     * if the kernel is not aware of PVFS paths
2382     */
2383    rv = getenv("PWD");
2384    if (!rv)
2385    {
2386        /* fall back to the kernel if env has no PWD */
2387        rc = my_glibc_getcwd(buf, PVFS_PATH_MAX);
2388        if (rc < 0)
2389        {
2390            perror("failed to get CWD from kernel");
2391            exit(-1);
2392        }
2393    }
2394    else
2395    {
2396        rv = strncpy(buf, rv, PVFS_PATH_MAX);
2397        if (!rv)
2398        {
2399            perror("string copy failed");
2400            exit(-1);
2401        }
2402    }
2403    rv = PVFS_qualify_path(buf);
2404    /* basic path length check */
2405    plen = strnlen(rv, PVFS_PATH_MAX);
2406    if (plen >= PVFS_PATH_MAX)
2407    {
2408        errno = ENAMETOOLONG;
2409        rc = -1;
2410    }
2411    else
2412    {
2413        strncpy(pvfs_cwd, rv, PVFS_PATH_MAX);
2414    }
2415    PVFS_free_expanded(rv);
2416    return rc;
2417}
2418
2419/**
2420 * pvfs chdir
2421 */
2422int pvfs_chdir(const char *path)
2423{
2424    int rc = 0, plen = 0;
2425    struct stat sbuf;
2426    char *newpath = NULL;
2427
2428    if (!path)
2429    {
2430        errno = EINVAL;
2431        return -1;
2432    }
2433    /* we really need to resolve this to a cannonical path */
2434    /* jump to expand path right away */
2435    newpath = PVFS_expand_path(path);
2436    if (!newpath)
2437    {
2438        return -1;
2439    }
2440    /* basic path length check */
2441    plen = strnlen(newpath, PVFS_PATH_MAX);
2442    if (plen >= PVFS_PATH_MAX)
2443    {
2444        errno = ENAMETOOLONG;
2445        rc = -1;
2446        goto errout;
2447    }
2448    /* if it is a valid path we can stat it and see what it is */
2449    rc = stat(newpath, &sbuf); /* this will get most errors */
2450    if (rc < 0)
2451    {
2452        rc = -1;
2453        goto errout;
2454    }
2455    /* path must be a directory */
2456    if (!S_ISDIR(sbuf.st_mode))
2457    {
2458        errno = ENOTDIR;
2459        rc = -1;
2460        goto errout;
2461    }
2462    /* we will keep a copy and keep one in the environment */
2463    strncpy(pvfs_cwd, newpath, PVFS_PATH_MAX);
2464    setenv("PWD", newpath, 1);
2465
2466errout:
2467    if (newpath != path)
2468    {
2469        /* This should only happen if path was not a PVFS_path */
2470        PVFS_free_expanded(newpath);
2471    }
2472    return rc;
2473}
2474
2475int pvfs_fchdir(int fd)
2476{
2477    int plen;
2478    pvfs_descriptor *pd;
2479
2480    /* path is already opened, make sure it is a dir */
2481    pd = pvfs_find_descriptor(fd);
2482    if (!pd || !S_ISDIR(pd->s->mode) || !pd->s->dpath)
2483    {
2484        errno = EBADF;
2485        return -1;
2486    }
2487    /* basic check for overflow */
2488    plen = strlen(pd->s->dpath);
2489    if (plen > PVFS_PATH_MAX)
2490    {
2491        errno = ENAMETOOLONG;
2492        return -1;
2493    }
2494    /* we will keep a copy and keep one in the environment */
2495    strncpy(pvfs_cwd, pd->s->dpath, PVFS_PATH_MAX);
2496    setenv("PWD", pd->s->dpath, 1);
2497    return 0;
2498}
2499
2500char *pvfs_getcwd(char *buf, size_t size)
2501{
2502    int plen;
2503    plen = strnlen(pvfs_cwd, PVFS_PATH_MAX);
2504    /* implement Linux variation */
2505    if (!buf)
2506    {
2507        int bsize = size ? size : plen + 1;
2508        if (bsize < plen + 1)
2509        {
2510            errno = ERANGE;
2511            return NULL;
2512        }
2513        /* malloc space */
2514        buf = (char *)malloc(bsize);
2515        if (!buf)
2516        {
2517            errno = ENOMEM;
2518            return NULL;
2519        }
2520    }
2521    else
2522    {
2523        if (size == 0)
2524        {
2525            errno = EINVAL;
2526            return NULL;
2527        }
2528        if (size < plen + 1)
2529        {
2530            errno = ERANGE;
2531            return NULL;
2532        }
2533    }
2534    strcpy(buf, pvfs_cwd);
2535    return buf;
2536}
2537
2538char *pvfs_get_current_dir_name(void)
2539{
2540    int plen;
2541    char *buf;
2542    plen = strnlen(pvfs_cwd, PVFS_PATH_MAX);
2543    buf = (char *)malloc(plen + 1);
2544    if (!buf)
2545    {
2546        errno = ENOMEM;
2547        return NULL;
2548    }
2549    strcpy(buf, pvfs_cwd);
2550    return buf;
2551}
2552/*
2553 * This is the no-frills old-fashioned version
2554 * Use at own risk
2555 */
2556char *pvfs_getwd(char *buf)
2557{
2558    if (!buf)
2559    {
2560        errno = EINVAL;
2561        return NULL;
2562    }
2563    strncpy(buf, pvfs_cwd, PVFS_PATH_MAX);
2564    return buf;
2565}
2566
2567
2568/**
2569 * pvfs_umask
2570 *
2571 * Manage a umask ourselves just in case we need to
2572 * Probably the standard version works fine but
2573 * In case we get a problem we have it
2574 */
2575mode_t pvfs_umask(mode_t mask)
2576{
2577    mode_t old_mask = mask_val;
2578    mask_val = mask & 0777;
2579    return old_mask;
2580}
2581
2582mode_t pvfs_getumask(void)
2583{
2584    return mask_val;
2585}
2586
2587int pvfs_getdtablesize(void)
2588{
2589    return pvfs_descriptor_table_size();
2590}
2591
2592/*
2593 * Table of PVFS system call versions for use by posix.c
2594 */
2595posix_ops pvfs_ops =
2596{
2597    .open = pvfs_open,
2598    .open64 = pvfs_open64,
2599    .openat = pvfs_openat,
2600    .openat64 = pvfs_openat64,
2601    .creat = pvfs_creat,
2602    .creat64 = pvfs_creat64,
2603    .unlink = pvfs_unlink,
2604    .unlinkat = pvfs_unlinkat,
2605    .rename = pvfs_rename,
2606    .renameat = pvfs_renameat,
2607    .read = pvfs_read,
2608    .pread = pvfs_pread,
2609    .readv = pvfs_readv,
2610    .pread64 = pvfs_pread64,
2611    .write = pvfs_write,
2612    .pwrite = pvfs_pwrite,
2613    .writev = pvfs_writev,
2614    .pwrite64 = pvfs_pwrite64,
2615    .lseek = pvfs_lseek,
2616    .lseek64 = pvfs_lseek64,
2617    .truncate = pvfs_truncate,
2618    .truncate64 = pvfs_truncate64,
2619    .ftruncate = pvfs_ftruncate,
2620    .ftruncate64 = pvfs_ftruncate64,
2621    .fallocate = pvfs_fallocate,
2622    .close = pvfs_close,
2623    .stat = pvfs_stat,
2624    .stat64 = pvfs_stat64,
2625    .fstat = pvfs_fstat,
2626    .fstat64 = pvfs_fstat64,
2627    .fstatat = pvfs_fstatat,
2628    .fstatat64 = pvfs_fstatat64,
2629    .lstat = pvfs_lstat,
2630    .lstat64 = pvfs_lstat64,
2631    .futimesat = pvfs_futimesat,
2632    .utimes = pvfs_utimes,
2633    .utime = pvfs_utime,
2634    .futimes = pvfs_futimes,
2635    .dup = pvfs_dup,
2636    .dup2 = pvfs_dup2,
2637    .chown = pvfs_chown,
2638    .fchown = pvfs_fchown,
2639    .fchownat = pvfs_fchownat,
2640    .lchown = pvfs_lchown,
2641    .chmod = pvfs_chmod,
2642    .fchmod = pvfs_fchmod,
2643    .fchmodat = pvfs_fchmodat,
2644    .mkdir = pvfs_mkdir,
2645    .mkdirat = pvfs_mkdirat,
2646    .rmdir = pvfs_rmdir,
2647    .readlink = pvfs_readlink,
2648    .readlinkat = pvfs_readlinkat,
2649    .symlink = pvfs_symlink,
2650    .symlinkat = pvfs_symlinkat,
2651    .link = pvfs_link,
2652    .linkat = pvfs_linkat,
2653    .readdir = pvfs_readdir,
2654    .getdents = pvfs_getdents,
2655    .getdents64 = pvfs_getdents64,
2656    .access = pvfs_access,
2657    .faccessat = pvfs_faccessat,
2658    .flock = pvfs_flock,
2659    .fcntl = pvfs_fcntl,
2660    .sync = pvfs_sync,
2661    .fsync = pvfs_fsync,
2662    .fdatasync = pvfs_fdatasync,
2663    .fadvise = pvfs_fadvise,
2664    .fadvise64 = pvfs_fadvise64,
2665    .statfs = statfs,             /* this one is probably special */
2666    .statfs64 = pvfs_statfs64,
2667    .fstatfs = pvfs_fstatfs,
2668    .fstatfs64 = pvfs_fstatfs64,
2669    .statvfs = statvfs,             /* this one is probably special */
2670    .fstatvfs = pvfs_fstatvfs,
2671    .mknod = pvfs_mknod,
2672    .mknodat = pvfs_mknodat,
2673    .sendfile = pvfs_sendfile,
2674    .sendfile64 = pvfs_sendfile64,
2675    .setxattr = pvfs_setxattr,
2676    .lsetxattr = pvfs_lsetxattr,
2677    .fsetxattr = pvfs_fsetxattr,
2678    .getxattr = pvfs_getxattr,
2679    .lgetxattr = pvfs_lgetxattr,
2680    .fgetxattr = pvfs_fgetxattr,
2681    .listxattr = pvfs_listxattr,
2682    .llistxattr = pvfs_llistxattr,
2683    .flistxattr = pvfs_flistxattr,
2684    .removexattr = pvfs_removexattr,
2685    .lremovexattr = pvfs_lremovexattr,
2686    .fremovexattr = pvfs_fremovexattr,
2687    .getdtablesize = pvfs_getdtablesize,
2688    .umask = pvfs_umask,
2689    .getumask = pvfs_getumask,
2690    .mmap = pvfs_mmap,
2691    .munmap = pvfs_munmap,
2692    .msync = pvfs_msync,
2693/* these are defined in acl.c and do not really need */
2694/* a PVFS specific implementation */
2695#if 0
2696    .acl_delete_def_file = pvfs_acl_delete_def_file,
2697    .acl_get_fd = pvfs_acl_get_fd,
2698    .acl_get_file = pvfs_acl_get_file,
2699    .acl_set_fd = pvfs_acl_set_fd,
2700    .acl_set_file = pvfs_acl_set_file,
2701#endif
2702};
2703
2704/*
2705 * Local variables:
2706 *  c-indent-level: 4
2707 *  c-basic-offset: 4
2708 * End:
2709 *
2710 * vim: ts=8 sts=4 sw=4 expandtab
2711 */
2712
Note: See TracBrowser for help on using the browser.