nfs-ganesha 1.4

pnfs_common.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (C) 2011 Linux Box Corporation
00004  * Author: Adam C. Emerson
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 3 of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  *
00020  * ---------------------------------------
00021  */
00022 
00032 #ifndef _FSAL_PNFS_COMMON_H
00033 #define _FSAL_PNFS_COMMON_H
00034 
00035 #include <stdint.h>
00036 #include "nfs4.h"
00037 
00038 /* The next 3 line are mandatory for proper autotools based management */
00039 #ifdef HAVE_CONFIG_H
00040 #include "config.h"
00041 #endif                          /* HAVE_CONFIG_H */
00042 
00043 #ifdef _USE_NFS4_1
00044 
00045 #ifndef false
00046 #define false 0
00047 #endif
00048 
00049 #ifndef true
00050 #define true 1
00051 #endif
00052 
00053 /******************************************************
00054  *               Basic in-memory types
00055  ******************************************************/
00056 
00065 struct pnfs_segment {
00067      layoutiomode4 io_mode;
00069      offset4 offset;
00071      length4 length;
00072 };
00073 
00078 struct pnfs_deviceid {
00082      uint64_t export_id;
00084      uint64_t devid;
00085 };
00086 
00087 
00088 
00089 /******************************************************
00090  *               Utility functions for ranges
00091  ******************************************************/
00092 
00102 static inline bool_t pnfs_segments_overlap(struct pnfs_segment segment1,
00103                                            struct pnfs_segment segmenta)
00104 {
00105      if (!(segment1.io_mode & segmenta.io_mode)) {
00106           return FALSE;
00107      } else if ((segment1.length == 0) || (segmenta.length == 0)) {
00108           return FALSE;
00109      } else if (segment1.offset < segmenta.offset) {
00110           if (segment1.length == NFS4_UINT64_MAX) {
00111                return TRUE;
00112           } else if (segment1.offset + segment1.length < segmenta.offset) {
00113                return FALSE;
00114           } else {
00115                return TRUE;
00116           }
00117      } else if (segmenta.offset < segment1.offset) {
00118           if (segmenta.length == NFS4_UINT64_MAX) {
00119                return TRUE;
00120           } else if ((segmenta.offset + segmenta.length)
00121                      < segment1.offset) {
00122                return FALSE;
00123           } else {
00124                return TRUE;
00125           }
00126      } else {
00127           return TRUE;
00128      }
00129 }
00130 
00142 static inline bool_t pnfs_segment_contains(struct pnfs_segment segment1,
00143                                            struct pnfs_segment segment2)
00144 {
00145      if (!(segment1.io_mode & segment2.io_mode)) {
00146           return FALSE;
00147      } else if (segment1.length == 0) {
00148           return FALSE;
00149      } else if (segment1.offset <= segment2.offset) {
00150           if (segment1.length == NFS4_UINT64_MAX) {
00151                return TRUE;
00152           } else if (segment2.length == NFS4_UINT64_MAX) {
00153                return FALSE;
00154           } else if ((segment2.offset + segment2.length) <=
00155                      (segment1.offset + segment1.length)) {
00156                return TRUE;
00157           } else {
00158                return FALSE;
00159           }
00160      } else {
00161           return FALSE;
00162      }
00163 }
00164 
00183 static inline struct pnfs_segment
00184 pnfs_segment_difference(struct pnfs_segment minuend,
00185                         struct pnfs_segment subtrahend)
00186 {
00187      if (!(minuend.io_mode & subtrahend.io_mode)) {
00188           return minuend;
00189      } else if (pnfs_segment_contains(subtrahend, minuend)) {
00190           struct pnfs_segment null = {
00191                .io_mode = minuend.io_mode,
00192                .offset = 0,
00193                .length = 0
00194           };
00195           return null;
00196      } else if (!(pnfs_segments_overlap(minuend, subtrahend))) {
00197           return minuend;
00198      } else if (minuend.offset <= subtrahend.offset) {
00199           if (minuend.length == NFS4_UINT64_MAX) {
00200                if (subtrahend.length == NFS4_UINT64_MAX) {
00201                     struct pnfs_segment difference = {
00202                          .io_mode = minuend.io_mode,
00203                          .offset = minuend.offset,
00204                          .length = subtrahend.offset - minuend.offset
00205                     };
00206                     return difference;
00207                } else {
00208                     return minuend;
00209                }
00210           } else {
00211                if ((minuend.length + minuend.offset) >
00212                    (subtrahend.length + subtrahend.offset)) {
00213                     return minuend;
00214                } else {
00215                     struct pnfs_segment difference = {
00216                          .io_mode = minuend.io_mode,
00217                          .offset = minuend.offset,
00218                          .length = minuend.offset - subtrahend.offset
00219                     };
00220                     return difference;
00221                }
00222           }
00223      } else {
00224           struct pnfs_segment difference = {
00225                .io_mode = minuend.io_mode,
00226                .offset = subtrahend.offset + subtrahend.length - 1,
00227                .length = minuend.length
00228           };
00229           return difference;
00230      }
00231 }
00232 
00233 /******************************************************
00234  *    Common functions for every pNFS implementation
00235  ******************************************************/
00236 
00237 /******************************************************
00238  *            Convenience XDR functions
00239  ******************************************************/
00240 
00241 fsal_boolean_t xdr_fsal_deviceid(XDR *xdrs, struct pnfs_deviceid *deviceid);
00242 
00243 nfsstat4 FSAL_encode_ipv4_netaddr(XDR *xdrs,
00244                                   uint16_t proto,
00245                                   uint32_t addr,
00246                                   uint16_t port);
00247 
00248 nfsstat4 posix2nfs4_error(int posix_errorcode);
00249 #endif /* _USE_NFS4_1 */
00250 
00251 #endif /* _FSAL_PNFS_COMMON_H */