nfs-ganesha 1.4
|
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 */