/*************************************************************************** * * Copyright (C) 2001 International Business Machines * All rights reserved. * * This file is part of the GPFS mmfslinux kernel module. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *************************************************************************** */ /* @(#)78 1.2 src/avs/fs/mmfs/ts/kernext/gpl-linux/tscalls.c, mmfs, avs_rgpfs24, rgpfs24s007a 10/27/06 16:48:13 */ /* * Portability layer equivalent of ts/util/tscalls.c * Includes a subset of the libgpfs interfaces that GPFS has provided * in open-source form. * * Contents: * gpfs_getacl * gpfs_putacl * gpfs_set_share * gpfs_set_lease * gpfs_get_lease */ #include #include #include #include #define F_SETLEASE 1024 #define F_GETLEASE 1025 #include #include /* open-source segment of gpfs.h */ #include #define IOCTL_FATTR 53 #define IOCTL_GETACL 56 #define IOCTL_PUTACL 57 #define IOCTL_SHARE 112 #define IOCTL_LEASE 113 struct ioArgs { long arg1; long arg2; long arg3; long arg4; long arg5; }; /*------------------------------------------------------------------------- * NAME: gpfs_getacl * * FUNCTION: Interface to read GPFS ACLs * * Returns: 0 Successful * -1 Failure * * Errno: ENOSYS function not available *-------------------------------------------------------------------------*/ int gpfs_getacl(char *pathname, int flags, void *aclP) { int rc; int fd; struct ioArgs io; fd = open(GPFS_DEVNAME, O_RDONLY); if (fd < 0) { rc = -1; errno = ENOSYS; goto xerror; } /* Retrieve the ACL from GPFS */ io.arg1 = (long)pathname; io.arg2 = (long)flags; io.arg3 = (long)aclP; rc = ioctl(fd, IOCTL_GETACL, &io); xerror: if (fd >= 0) close(fd); return rc; } /*------------------------------------------------------------------------- * NAME: gpfs_putacl * * FUNCTION: Interface to store GPFS ACLs * * Returns: 0 Successful * -1 Failure * * Errno: ENOSYS function not available *-------------------------------------------------------------------------*/ int gpfs_putacl(char *pathname, int flags, void *aclP) { int rc; int fd; struct ioArgs io; fd = open(GPFS_DEVNAME, O_RDONLY); if (fd < 0) { rc = -1; errno = ENOSYS; goto xerror; } /* Store the ACL into GPFS */ io.arg1 = (long)pathname; io.arg2 = (long)flags; io.arg3 = (long)aclP; rc = ioctl(fd, IOCTL_PUTACL, &io); xerror: if (fd >= 0) close(fd); return rc; } /*------------------------------------------------------------------------- * NAME: gpfs_set_share * * FUNCTION: Samba interface to GPFS OpenLks * Called from the Samba daemon to reserve a share * * INPUT: object_fd : file descriptor of the object to share * share: modes being requested * deny : modes to deny * OUTPUT: None * * Returns: 0 Successful * -1 Failure * Errno: ENOENT File not found * EACCES Share mode not granted *-------------------------------------------------------------------------*/ int gpfs_set_share(int object_fd, unsigned int share, unsigned int deny) { int rc; int fd; struct ioArgs io; fd = open(GPFS_DEVNAME, O_RDONLY); if (fd < 0) { rc = -1; errno = ENOSYS; goto xerror; } /* Request the share from GPFS */ io.arg1 = (long)object_fd; io.arg2 = (long)share; io.arg3 = (long)deny; rc = ioctl(fd, IOCTL_SHARE, &io); xerror: if (fd >= 0) close(fd); return rc; } /*------------------------------------------------------------------------- * NAME: gpfs_set_lease * * FUNCTION: Samba interface to GPFS OpLks * Called from the Samba daemon to obtain a lease * * INPUT: object_fd : file descriptor of the object to lease * leaseType: mode being requested * OUTPUT: None * * Returns: 0 Successful * -1 Failure * Errno: EACCES Lease not granted * ENOENT File not found *-------------------------------------------------------------------------*/ int gpfs_set_lease(int object_fd, unsigned int leaseType) { int rc = 0; int fd; int lrc, serrno; struct ioArgs io; fd = open(GPFS_DEVNAME, O_RDONLY); if (fd < 0) { rc = -1; errno = ENOSYS; goto xerror; } /* Queue Linux structures required for break notification */ rc = CXI_REGISTER_LEASE(object_fd, leaseType); if (rc) return rc; /* Request the lease from GPFS */ io.arg1 = (long)object_fd; io.arg2 = (long)leaseType; io.arg3 = (long)NULL; io.arg4 = (long)NULL; rc = ioctl(fd, IOCTL_LEASE, &io); if (rc && (leaseType != GPFS_LEASE_NONE)) { serrno = errno; /* Dequeue Linux structures */ lrc = CXI_REGISTER_LEASE(object_fd, GPFS_LEASE_NONE); errno = serrno; } xerror: if (fd >= 0) close(fd); return rc; } /*------------------------------------------------------------------------- * NAME: gpfs_get_lease * * FUNCTION: Samba interface to GPFS OpLks * Called from the Samba daemon to query leases held * * INPUT: object_fd : file descriptor of the leased object * OUTPUT: None * * Returns: GPFS_LEASE_READ * GPFS_LEASE_WRITE * GPFS_LEASE_NONE * -1 Failure * * Errno: ENOENT File not found * EINVAL *-------------------------------------------------------------------------*/ int gpfs_get_lease(int object_fd) { int rc = 0; CXI_GET_LEASE_HELD(object_fd, rc); if (rc<0) { errno = -rc; rc = -1; } return rc; } /*------------------------------------------------------------------------- * NAME: gpfs_prealloc() * Preallocate disk storage for the file handle that has * already been opened for writing, starting at the specified * starting offset and covering at least the number of bytes * requested. Allocations are rounded to block boundaries * (block size can be found using fstat() in st_blksize.) * Any existing data already in the file will not be modified. * Any read of the preallocated blocks will return zeros. * * FUNCTION: * Returns: 0 Successful * -1 Failure * * Errno: ENOSYS No prealloc service available * EBADF Bad file handle * EINVAL Not a GPFS file * EINVAL Not a regular file * EINVAL StartOffset or BytesToPrealloc < 0 * EACCES File not opened for writing * EDQUOT Quota exceeded * ENOSPC Not enough space on disk *-------------------------------------------------------------------------*/ int gpfs_prealloc(int FileHandle, gpfs_off64_t StartOffset, gpfs_off64_t BytesToTransfer) { int rc; int fd; struct ioArgs io; struct filePreallocation preAlloc = {0,0,0}; fd = open(GPFS_DEVNAME, O_RDONLY); if (fd < 0) { rc = -1; errno = ENOSYS; goto xerror; } /* Construct the filePreallocation structure */ preAlloc.size = BytesToTransfer; preAlloc.offset = StartOffset; preAlloc.flags = 0; /* Store the ACL into GPFS */ io.arg1 = (long)FileHandle; io.arg2 = (long)PREALLOCATE_FILE; io.arg3 = (long)&preAlloc; io.arg4 = (long)NULL; rc = ioctl(fd, IOCTL_FATTR, &io); xerror: if (fd >= 0) close(fd); return rc; } /* --------- end of gpfs_prealloc() -------------- */