nfs-ganesha 1.4

nfs4_op_restorefh.c

Go to the documentation of this file.
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 */