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 "nfs23.h" 00054 #include "nfs4.h" 00055 #include "mount.h" 00056 #include "nfs_core.h" 00057 #include "cache_inode.h" 00058 #include "nfs_exports.h" 00059 #include "nfs_creds.h" 00060 #include "nfs_proto_tools.h" 00061 #include "nfs_proto_functions.h" 00062 #include "nfs_file_handle.h" 00063 #include "nfs_tools.h" 00064 #ifdef _PNFS_MDS 00065 #include "fsal_pnfs.h" 00066 #endif /* _PNFS_MDS */ 00067 00084 #define arg_GETDEVICELIST4 op->nfs_argop4_u.opgetdevicelist 00085 #define res_GETDEVICELIST4 resp->nfs_resop4_u.opgetdevicelist 00086 00087 int nfs41_op_getdevicelist(struct nfs_argop4 *op, 00088 compound_data_t *data, 00089 struct nfs_resop4 *resp) 00090 { 00091 char __attribute__ ((__unused__)) funcname[] = "nfs41_op_getdevicelist"; 00092 #ifdef _PNFS_MDS 00093 /* NFS4 return code */ 00094 nfsstat4 nfs_status = 0; 00095 /* Return from cache_inode functions */ 00096 cache_inode_status_t cache_status = 0; 00097 /* Input paramaters of FSAL function */ 00098 struct fsal_getdevicelist_arg arg; 00099 /* Input/output and output parameters of FSAL function */ 00100 struct fsal_getdevicelist_res res; 00101 /* FSAL file handle */ 00102 fsal_handle_t *handle = NULL; 00103 /* Iterator for populating deviceid list */ 00104 size_t i = 0; 00105 #endif /* _PNFS_MDS */ 00106 00107 resp->resop = NFS4_OP_GETDEVICELIST; 00108 00109 #ifdef _PNFS_MDS 00110 if ((nfs_status = nfs4_sanity_check_FH(data, 0)) 00111 != NFS4_OK) { 00112 goto out; 00113 } 00114 00115 /* Filesystems that don't support pNFS have no deviceids. */ 00116 00117 if (!nfs4_pnfs_supported(data->pexport)) { 00118 nfs_status = NFS4_OK; 00119 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4.gdlr_cookie 00120 = 0; 00121 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4 00122 .gdlr_deviceid_list.gdlr_deviceid_list_val = NULL; 00123 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4 00124 .gdlr_deviceid_list.gdlr_deviceid_list_len = 0; 00125 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4.gdlr_eof 00126 = 1; 00127 goto out; 00128 } 00129 00130 handle = cache_inode_get_fsal_handle(data->current_entry, 00131 &cache_status); 00132 00133 if (cache_status != CACHE_INODE_SUCCESS) { 00134 nfs_status = nfs4_Errno(cache_status); 00135 goto out; 00136 } 00137 00138 memset(&arg, 0, sizeof(struct fsal_getdevicelist_arg)); 00139 memset(&res, 0, sizeof(struct fsal_getdevicelist_res)); 00140 00141 arg.export_id = data->pexport->id; 00142 arg.type = arg_GETDEVICELIST4.gdla_layout_type; 00143 00144 res.cookie = arg_GETDEVICELIST4.gdla_cookie; 00145 memcpy(&res.cookieverf, arg_GETDEVICELIST4.gdla_cookieverf, 00146 NFS4_VERIFIER_SIZE); 00147 res.count = arg_GETDEVICELIST4.gdla_maxdevices; 00148 res.devids = gsh_calloc(res.count, sizeof(uint64_t)); 00149 00150 if (res.devids == NULL) { 00151 nfs_status = NFS4ERR_SERVERFAULT; 00152 goto out; 00153 } 00154 00155 /* 00156 * XXX This assumes a single FSAL and must be changed after the 00157 * XXX Lieb Rearchitecture. The MDS function structure 00158 * XXX associated with the current filehandle should be used. 00159 */ 00160 00161 if ((nfs_status 00162 = fsal_mdsfunctions.getdevicelist(handle, 00163 data->pcontext, 00164 &arg, 00165 &res)) 00166 != NFS4_OK) { 00167 goto out; 00168 } 00169 00170 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4.gdlr_cookie 00171 = res.cookie; 00172 memcpy(res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4.gdlr_cookieverf, 00173 res.cookieverf, NFS4_VERIFIER_SIZE); 00174 00175 if ((res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4 00176 .gdlr_deviceid_list.gdlr_deviceid_list_val 00177 = gsh_malloc(res.count * sizeof(deviceid4))) == NULL) { 00178 nfs_status = NFS4ERR_SERVERFAULT; 00179 goto out; 00180 } 00181 00182 for (i = 0; i < res.count; i++) { 00183 *(uint64_t*) 00184 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4 00185 .gdlr_deviceid_list.gdlr_deviceid_list_val[i] 00186 = nfs_htonl64(data->pexport->id); 00187 *(uint64_t*) 00188 (res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4 00189 .gdlr_deviceid_list.gdlr_deviceid_list_val[i] + 00190 sizeof(uint64_t)) 00191 = nfs_htonl64(res.devids[i]); 00192 } 00193 00194 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4 00195 .gdlr_deviceid_list.gdlr_deviceid_list_len = res.count; 00196 res_GETDEVICELIST4.GETDEVICELIST4res_u.gdlr_resok4.gdlr_eof 00197 = res.eof; 00198 00199 nfs_status = NFS4_OK; 00200 00201 out: 00202 00203 gsh_free(res.devids); 00204 00205 res_GETDEVICELIST4.gdlr_status = nfs_status; 00206 #else /* !_PNFS_MDS */ 00207 res_GETDEVICELIST4.gdlr_status = NFS4ERR_NOTSUPP; 00208 #endif /* !_PNFS_MDS */ 00209 return res_GETDEVICELIST4.gdlr_status; 00210 } /* nfs41_op_getdevicelist */ 00211 00222 void nfs41_op_getdevicelist_Free(GETDEVICELIST4res * resp) 00223 { 00224 #ifdef _PNFS_MDS 00225 if (resp->gdlr_status == NFS4_OK) { 00226 gsh_free(resp->GETDEVICELIST4res_u.gdlr_resok4 00227 .gdlr_deviceid_list.gdlr_deviceid_list_val); 00228 } 00229 #endif /* _PNFS_MDS */ 00230 return; 00231 } /* nfs41_op_getdevicelist_Free */