nfs-ganesha 1.4

nfs4_op_putfh.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  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 <assert.h>
00050 #include "HashData.h"
00051 #include "HashTable.h"
00052 #include "log.h"
00053 #include "ganesha_rpc.h"
00054 #include "nfs23.h"
00055 #include "nfs4.h"
00056 #include "mount.h"
00057 #include "nfs_core.h"
00058 #include "cache_inode.h"
00059 #include "nfs_exports.h"
00060 #include "nfs_creds.h"
00061 #include "nfs_proto_functions.h"
00062 #include "nfs_tools.h"
00063 #include "nfs_proto_tools.h"
00064 
00065 #define arg_PUTFH4 op->nfs_argop4_u.opputfh
00066 #define res_PUTFH4 resp->nfs_resop4_u.opputfh
00067 
00085 int nfs4_op_putfh(struct nfs_argop4 *op, compound_data_t * data, struct nfs_resop4 *resp)
00086 {
00087   char __attribute__ ((__unused__)) funcname[] = "nfs4_op_putfh";
00088 
00089   int                rc;
00090   fsal_attrib_list_t attr;
00091 
00092 
00093   resp->resop = NFS4_OP_PUTFH;
00094   res_PUTFH4.status = NFS4_OK;
00095 
00096   /* If no currentFH were set, allocate one */
00097   if(data->currentFH.nfs_fh4_len == 0)
00098     {
00099       res_PUTFH4.status = nfs4_AllocateFH(&(data->currentFH));
00100       if(res_PUTFH4.status != NFS4_OK)
00101         return res_PUTFH4.status;
00102     }
00103 
00104   /* The same is to be done with mounted_on_FH */
00105   if(data->mounted_on_FH.nfs_fh4_len == 0)
00106     {
00107       res_PUTFH4.status = nfs4_AllocateFH(&(data->mounted_on_FH));
00108       if(res_PUTFH4.status != NFS4_OK)
00109         return res_PUTFH4.status;
00110     }
00111 
00112   /* Copy the filehandle from the reply structure */
00113   data->currentFH.nfs_fh4_len = arg_PUTFH4.object.nfs_fh4_len;
00114   data->mounted_on_FH.nfs_fh4_len = arg_PUTFH4.object.nfs_fh4_len;
00115 
00116   /* Put the data in place */
00117   memcpy(data->currentFH.nfs_fh4_val, arg_PUTFH4.object.nfs_fh4_val,
00118          arg_PUTFH4.object.nfs_fh4_len);
00119   memcpy(data->mounted_on_FH.nfs_fh4_val, arg_PUTFH4.object.nfs_fh4_val,
00120          arg_PUTFH4.object.nfs_fh4_len);
00121 
00122   LogHandleNFS4("NFS4_OP_PUTFH CURRENT FH: ", &arg_PUTFH4.object);
00123 
00124   /* If the filehandle is not pseudo fs file handle, get the entry
00125    * related to it, otherwise use fake values */
00126   if(nfs4_Is_Fh_Pseudo(&(data->currentFH)))
00127     {
00128         if (data->current_entry) {
00129             cache_inode_put(data->current_entry);
00130         }
00131         data->current_entry = NULL;
00132         data->current_filetype = DIRECTORY;
00133         data->pexport = NULL; /* No exportlist is related to pseudo fs */
00134     }
00135   else
00136     {
00137       /* If data->exportp is null, a junction from pseudo fs was
00138          traversed, credp and exportp have to be updated */
00139       if(data->pexport == NULL)
00140         {
00141           res_PUTFH4.status = nfs4_SetCompoundExport(data);
00142           if(res_PUTFH4.status != NFS4_OK)
00143             return res_PUTFH4.status;
00144         }
00145 
00146       if (nfs_export_check_security(data->reqp, data->pexport) == FALSE)
00147         {
00148           res_PUTFH4.status = NFS4ERR_PERM;
00149           return res_PUTFH4.status;
00150         }
00151 
00152 #ifdef _PNFS_DS
00153       /* As usual, protect existing refcounts */
00154       if (data->current_entry) {
00155           cache_inode_put(data->current_entry);
00156           data->current_entry = NULL;
00157           data->current_filetype = UNASSIGNED;
00158       }
00159       /* The export and fsalid should be updated, but DS handles
00160          don't support metdata operations.  Thus, we can't call into
00161          Cache_inode to populate the metadata cache. */
00162       if(nfs4_Is_Fh_DSHandle(&data->currentFH))
00163         {
00164           data->current_entry = NULL;
00165           data->current_filetype = REGULAR_FILE;
00166         }
00167       else
00168 #endif /* _PNFS_DS */
00169         {
00170           if (data->current_entry)
00171             cache_inode_put(data->current_entry);
00172           /* Build the pentry.  Refcount +1. */
00173           if((data->current_entry = nfs_FhandleToCache(NFS_V4,
00174                                                        NULL,
00175                                                        NULL,
00176                                                        &(data->currentFH),
00177                                                        NULL,
00178                                                        NULL,
00179                                                        &(res_PUTFH4.status),
00180                                                        &attr,
00181                                                        data->pcontext,
00182                                                        &rc)) == NULL)
00183             {
00184               return res_PUTFH4.status;
00185             }
00186           /* Extract the filetype */
00187           data->current_filetype = cache_inode_fsal_type_convert(attr.type);
00188         }
00189     }
00190 
00191   return NFS4_OK;
00192 }                               /* nfs4_op_putfh */
00193 
00204 void nfs4_op_putfh_Free(PUTFH4res * resp)
00205 {
00206   /* Nothing to be freed */
00207   return;
00208 }                               /* nfs4_op_create_Free */