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 00022 * 02110-1301 USA 00023 * 00024 * --------------------------------------- 00025 */ 00026 00038 #ifdef HAVE_CONFIG_H 00039 #include "config.h" 00040 #endif 00041 00042 #ifdef _SOLARIS 00043 #include "solaris_port.h" 00044 #endif 00045 00046 #include <stdio.h> 00047 #include <string.h> 00048 #include <pthread.h> 00049 #include <fcntl.h> 00050 #include <sys/file.h> /* for having FNDELAY */ 00051 #include "HashData.h" 00052 #include "HashTable.h" 00053 #include "log.h" 00054 #include "ganesha_rpc.h" 00055 #include "nfs23.h" 00056 #include "nfs4.h" 00057 #include "mount.h" 00058 #include "nfs_core.h" 00059 #include "cache_inode.h" 00060 #include "cache_inode_lru.h" 00061 #include "nfs_exports.h" 00062 #include "nfs_creds.h" 00063 #include "nfs_proto_functions.h" 00064 #include "nfs_tools.h" 00065 #include "nfs_file_handle.h" 00066 00086 #define arg_RESTOREFH op->nfs_argop4_u.oprestorefh 00087 #define res_RESTOREFH resp->nfs_resop4_u.oprestorefh 00088 00089 int nfs4_op_restorefh(struct nfs_argop4 *op, 00090 compound_data_t * data, struct nfs_resop4 *resp) 00091 { 00092 char __attribute__ ((__unused__)) funcname[] = "nfs4_op_restorefh"; 00093 00094 /* First of all, set the reply to zero to make sure it contains no 00095 parasite information */ 00096 memset(resp, 0, sizeof(struct nfs_resop4)); 00097 00098 resp->resop = NFS4_OP_RESTOREFH; 00099 res_RESTOREFH.status = NFS4_OK; 00100 00101 /* If there is no currentFH, teh return an error */ 00102 if(nfs4_Is_Fh_Empty(&(data->savedFH))) 00103 { 00104 /* There is no current FH, return NFS4ERR_RESTOREFH (cg RFC3530, 00105 page 202) */ 00106 res_RESTOREFH.status = NFS4ERR_RESTOREFH; 00107 return res_RESTOREFH.status; 00108 } 00109 00110 /* If the filehandle is invalid */ 00111 if(nfs4_Is_Fh_Invalid(&(data->savedFH))) 00112 { 00113 res_RESTOREFH.status = NFS4ERR_BADHANDLE; 00114 return res_RESTOREFH.status; 00115 } 00116 00117 /* Tests if the Filehandle is expired (for volatile filehandle) */ 00118 if(nfs4_Is_Fh_Expired(&(data->savedFH))) 00119 { 00120 res_RESTOREFH.status = NFS4ERR_FHEXPIRED; 00121 return res_RESTOREFH.status; 00122 } 00123 00124 /* If data->exportp is null, a junction from pseudo fs was 00125 traversed, credp and exportp have to be updated */ 00126 if(data->pexport == NULL) 00127 { 00128 res_RESTOREFH.status = nfs4_SetCompoundExport(data); 00129 if(res_RESTOREFH.status != NFS4_OK) 00130 { 00131 LogCrit(COMPONENT_NFS_V4, 00132 "Error %d in nfs4_SetCompoundExport", res_RESTOREFH.status); 00133 return res_RESTOREFH.status; 00134 } 00135 } 00136 00137 /* Copy the data from current FH to saved FH */ 00138 memcpy(data->currentFH.nfs_fh4_val, 00139 data->savedFH.nfs_fh4_val, 00140 data->savedFH.nfs_fh4_len); 00141 00142 data->currentFH.nfs_fh4_len = data->savedFH.nfs_fh4_len; 00143 00144 /* If current and saved entry are identical, get no references and 00145 make no changes. */ 00146 00147 if (data->current_entry == data->saved_entry) { 00148 goto out; 00149 } 00150 00151 if (data->current_entry) { 00152 cache_inode_put(data->current_entry); 00153 data->current_entry = NULL; 00154 } 00155 00156 data->current_entry = data->saved_entry; 00157 data->current_filetype = data->saved_filetype; 00158 00159 /* Take another reference. As of now the filehandle is both saved 00160 and current and both must be counted. Protect in case of 00161 pseudofs handle. */ 00162 00163 if (data->current_entry) { 00164 if (cache_inode_lru_ref(data->current_entry, 00165 LRU_FLAG_NONE) != CACHE_INODE_SUCCESS) { 00166 resp->nfs_resop4_u.opgetfh.status = NFS4ERR_STALE; 00167 data->current_entry = NULL; 00168 return resp->nfs_resop4_u.opgetfh.status; 00169 } 00170 } 00171 00172 out: 00173 00174 if(isFullDebug(COMPONENT_NFS_V4)) 00175 { 00176 char str[LEN_FH_STR]; 00177 sprint_fhandle4(str, &data->currentFH); 00178 LogFullDebug(COMPONENT_NFS_V4, 00179 "RESTORE FH: Current FH %s", str); 00180 } 00181 00182 00183 return NFS4_OK; 00184 } /* nfs4_op_restorefh */ 00185 00196 void nfs4_op_restorefh_Free(RESTOREFH4res * resp) 00197 { 00198 /* Nothing to be done */ 00199 return; 00200 } /* nfs4_op_restorefh_Free */