nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 00005 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00006 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 * --------------------------------------- 00024 */ 00025 00036 #ifdef HAVE_CONFIG_H 00037 #include "config.h" 00038 #endif 00039 00040 #ifdef _SOLARIS 00041 #include "solaris_port.h" 00042 #endif 00043 00044 #include <stdio.h> 00045 #include <string.h> 00046 #include <pthread.h> 00047 #include <fcntl.h> 00048 #include <sys/file.h> /* for having FNDELAY */ 00049 #include "HashData.h" 00050 #include "HashTable.h" 00051 #include "log.h" 00052 #include "ganesha_rpc.h" 00053 #include "nfs4.h" 00054 #include "nfs_core.h" 00055 #include "cache_inode.h" 00056 #include "nfs_exports.h" 00057 #include "nfs_creds.h" 00058 #include "nfs_proto_tools.h" 00059 #include "nfs_proto_functions.h" 00060 #include "nfs_file_handle.h" 00061 #include "nfs_tools.h" 00062 #ifdef _PNFS_MDS 00063 #include "fsal_pnfs.h" 00064 #endif /* _PNFS_MDS */ 00065 #include "nfs_proto_functions.h" 00066 #include "nfs_file_handle.h" 00067 #include "nfs_tools.h" 00068 00085 #define arg_GETDEVICEINFO4 op->nfs_argop4_u.opgetdeviceinfo 00086 #define res_GETDEVICEINFO4 resp->nfs_resop4_u.opgetdeviceinfo 00087 00088 int nfs41_op_getdeviceinfo(struct nfs_argop4 *op, 00089 compound_data_t *data, 00090 struct nfs_resop4 *resp) 00091 { 00092 char __attribute__ ((__unused__)) funcname[] = "nfs41_op_getdeviceinfo"; 00093 #ifdef _PNFS_MDS 00094 /* The separated deviceid passed to the FSAL */ 00095 struct pnfs_deviceid deviceid = {0, 0}; 00096 /* NFS4 return code */ 00097 nfsstat4 nfs_status = 0; 00098 /* XDR stream into which the FSAl shall encode the da_addr_body */ 00099 XDR da_addr_body; 00100 /* The position before any bytes are sent to the stream */ 00101 size_t da_beginning = 0; 00102 /* The total length of the XDR-encoded da_addr_body */ 00103 size_t da_length = 0; 00104 /* Address of the buffer that backs the stream */ 00105 char* da_buffer = NULL; 00106 /* The space necessary to hold one response */ 00107 count4 mincount = 0; 00108 /* The FSAL's requested size for the da_addr_body opaque */ 00109 size_t da_addr_size = 0; 00110 /* Pointer to the export appropriate to this deviceid */ 00111 exportlist_t *export = NULL; 00112 #endif /* _PNFS_MDS */ 00113 00114 resp->resop = NFS4_OP_GETDEVICEINFO; 00115 00116 #ifdef _PNFS_MDS 00117 00118 /* Disassemble and fix byte order of the deviceid halves. Do 00119 memcpy then byte swap to avoid potential problems with 00120 unaligned/misaligned access. */ 00121 00122 memcpy(&deviceid.export_id, arg_GETDEVICEINFO4.gdia_device_id, 00123 sizeof(uint64_t)); 00124 deviceid.export_id = nfs_ntohl64(deviceid.export_id); 00125 00126 memcpy(&deviceid.devid, 00127 arg_GETDEVICEINFO4.gdia_device_id + sizeof(uint64_t), 00128 sizeof(uint64_t)); 00129 deviceid.devid = nfs_ntohl64(deviceid.export_id); 00130 00131 /* Check that we have space */ 00132 00133 export = nfs_Get_export_by_id(data->pfullexportlist, 00134 deviceid.export_id); 00135 00136 if (export == NULL) { 00137 nfs_status = NFS4ERR_NOENT; 00138 goto out; 00139 } 00140 00141 if (!nfs4_pnfs_supported(export)) { 00142 nfs_status = NFS4ERR_NOENT; 00143 goto out; 00144 } 00145 00146 da_addr_size = (export->FS_export_context.fe_static_fs_info 00147 ->dsaddr_buffer_size); 00148 00149 if (da_addr_size == 0) { 00150 LogCrit(COMPONENT_PNFS, 00151 "The FSAL must specify a non-zero dsaddr_buffer_size " 00152 "in its fsal_staticfsinfo_t"); 00153 nfs_status = NFS4ERR_SERVERFAULT; 00154 goto out; 00155 } 00156 00157 mincount = sizeof(uint32_t) /* Count for the empty bitmap */ + 00158 sizeof(layouttype4) /* Type in the device_addr4 */ + 00159 sizeof(uint32_t) /* Number of bytes in da_addr_body */ + 00160 da_addr_size; /* The FSAL's requested size of the 00161 da_addr_body opaque */ 00162 00163 if (arg_GETDEVICEINFO4.gdia_maxcount < mincount) { 00164 nfs_status = NFS4ERR_TOOSMALL; 00165 res_GETDEVICEINFO4.GETDEVICEINFO4res_u.gdir_mincount 00166 = mincount; 00167 goto out; 00168 } 00169 00170 /* Set up the device_addr4 and get stream for FSAL to write into */ 00171 00172 res_GETDEVICEINFO4.GETDEVICEINFO4res_u.gdir_resok4 00173 .gdir_device_addr.da_layout_type 00174 = arg_GETDEVICEINFO4.gdia_layout_type; 00175 00176 if ((da_buffer = gsh_malloc(da_addr_size)) == NULL) { 00177 nfs_status = NFS4ERR_SERVERFAULT; 00178 goto out; 00179 } 00180 00181 xdrmem_create(&da_addr_body, 00182 da_buffer, 00183 da_addr_size, 00184 XDR_ENCODE); 00185 da_beginning = xdr_getpos(&da_addr_body); 00186 00187 /* 00188 * XXX This assumes a single FSAL and must be changed after the 00189 * XXX Lieb Rearchitecture. The MDS function structure must be 00190 * XXX looked up, using the export_id stored in the high quad of 00191 * XXX the deviceid. 00192 */ 00193 00194 nfs_status 00195 = (fsal_mdsfunctions 00196 .getdeviceinfo)(data->pcontext, 00197 &da_addr_body, 00198 arg_GETDEVICEINFO4.gdia_layout_type, 00199 &deviceid); 00200 00201 da_length = xdr_getpos(&da_addr_body) - da_beginning; 00202 xdr_destroy(&da_addr_body); 00203 00204 if (nfs_status != NFS4_OK) { 00205 goto out; 00206 } 00207 00208 res_GETDEVICEINFO4.GETDEVICEINFO4res_u.gdir_resok4 00209 .gdir_notification.bitmap4_len = 0; 00210 res_GETDEVICEINFO4.GETDEVICEINFO4res_u.gdir_resok4 00211 .gdir_notification.bitmap4_val = NULL; 00212 00213 res_GETDEVICEINFO4.GETDEVICEINFO4res_u.gdir_resok4 00214 .gdir_device_addr.da_addr_body.da_addr_body_len 00215 = da_length; 00216 res_GETDEVICEINFO4.GETDEVICEINFO4res_u.gdir_resok4 00217 .gdir_device_addr.da_addr_body.da_addr_body_val 00218 = da_buffer; 00219 00220 nfs_status = NFS4_OK; 00221 00222 out: 00223 00224 if ((nfs_status != NFS4_OK) && 00225 da_buffer) { 00226 gsh_free(da_buffer); 00227 } 00228 00229 res_GETDEVICEINFO4.gdir_status = nfs_status; 00230 #else /* !_PNFS_MDS */ 00231 res_GETDEVICEINFO4.gdir_status = NFS4ERR_NOTSUPP; 00232 #endif /* !_PNFS_MDS */ 00233 return res_GETDEVICEINFO4.gdir_status; 00234 } /* nfs41_op_getdeviceinfo */ 00235 00246 void nfs41_op_getdeviceinfo_Free(GETDEVICEINFO4res * resp) 00247 { 00248 #ifdef _PNFS_MDS 00249 if (resp->gdir_status == NFS4_OK) { 00250 if (resp->GETDEVICEINFO4res_u.gdir_resok4.gdir_device_addr 00251 .da_addr_body.da_addr_body_val != NULL) { 00252 gsh_free(resp->GETDEVICEINFO4res_u.gdir_resok4 00253 .gdir_device_addr.da_addr_body.da_addr_body_val); 00254 } 00255 } 00256 #endif /* _PNFS_MDS */ 00257 return; 00258 } /* nfs41_op_getdeviceinfo_Free */