nfs-ganesha 1.4

9p_setattr.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2011)
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 
00035 #ifdef HAVE_CONFIG_H
00036 #include "config.h"
00037 #endif
00038 
00039 #ifdef _SOLARIS
00040 #include "solaris_port.h"
00041 #endif
00042 
00043 #include <stdio.h>
00044 #include <string.h>
00045 #include <pthread.h>
00046 #include <sys/stat.h>
00047 #include "nfs_core.h"
00048 #include "log.h"
00049 #include "cache_inode.h"
00050 #include "fsal.h"
00051 #include "9p.h"
00052 
00053 int _9p_setattr( _9p_request_data_t * preq9p, 
00054                   void  * pworker_data,
00055                   u32 * plenout, 
00056                   char * preply)
00057 {
00058   char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ;
00059 
00060   u16  * msgtag     = NULL ;
00061   u32  * fid        = NULL ;
00062   u32  * valid      = NULL ;
00063   u32  * mode       = NULL ;
00064   u32  * uid        = NULL ;
00065   u32  * gid        = NULL ;
00066   u64  * size       = NULL ;
00067   u64  * atime_sec  = NULL ;
00068   u64  * atime_nsec = NULL ;
00069   u64  * mtime_sec  = NULL ;
00070   u64  * mtime_nsec = NULL ;
00071 
00072   _9p_fid_t * pfid = NULL ;
00073 
00074   fsal_attrib_list_t    fsalattr ;
00075   cache_inode_status_t  cache_status ;
00076   fsal_attrib_list_t     parent_attr;
00077 
00078   struct timeval t;
00079 
00080   if ( !preq9p || !pworker_data || !plenout || !preply )
00081    return -1 ;
00082 
00083   /* Get data */
00084   _9p_getptr( cursor, msgtag, u16 ) ; 
00085   _9p_getptr( cursor, fid,    u32 ) ; 
00086 
00087   _9p_getptr( cursor, valid,      u32 ) ;
00088   _9p_getptr( cursor, mode,       u32 ) ;
00089   _9p_getptr( cursor, uid,        u32 ) ;
00090   _9p_getptr( cursor, gid,        u32 ) ;
00091   _9p_getptr( cursor, size,       u64 ) ;
00092   _9p_getptr( cursor, atime_sec,  u64 ) ;
00093   _9p_getptr( cursor, atime_nsec, u64 ) ;
00094   _9p_getptr( cursor, mtime_sec,  u64 ) ;
00095   _9p_getptr( cursor, mtime_nsec, u64 ) ;
00096 
00097   LogDebug( COMPONENT_9P, "TSETATTR: tag=%u fid=%u mode=0%o uid=%u gid=%u size=%"PRIu64" atime=(%llu|%llu) mtime=(%llu|%llu)",
00098             (u32)*msgtag, *fid, *mode, *uid, *gid, *size,  (unsigned long long)*atime_sec, (unsigned long long)*atime_nsec, 
00099             (unsigned long long)*mtime_sec, (unsigned long long)*mtime_nsec  ) ;
00100 
00101   if( *fid >= _9P_FID_PER_CONN )
00102    return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ;
00103 
00104   pfid = &preq9p->pconn->fids[*fid] ;
00105 
00106   /* If a "time" change is required, but not with the "_set" suffix, use gettimeofday */
00107   if( *valid & (_9P_SETATTR_ATIME|_9P_SETATTR_CTIME|_9P_SETATTR_MTIME) )
00108    {
00109      if( gettimeofday( &t, NULL ) == -1 )
00110        {
00111          LogMajor( COMPONENT_9P, "TSETATTR: tag=%u fid=%u ERROR !! gettimeofday returned -1 with errno=%u",
00112                    (u32)*msgtag, *fid, errno ) ;
00113          return _9p_rerror( preq9p, msgtag, errno, plenout, preply ) ;
00114        }
00115    }
00116 
00117   /* Let's do the job */
00118   memset( (char *)&fsalattr, 0, sizeof( fsalattr ) ) ;
00119   memset(&parent_attr, 0, sizeof(parent_attr));
00120 
00121   if( *valid & _9P_SETATTR_MODE )
00122    {
00123       fsalattr.asked_attributes |= FSAL_ATTR_MODE ;
00124       fsalattr.mode = *mode ;
00125    }
00126 
00127   if( *valid & _9P_SETATTR_UID )
00128    {
00129       fsalattr.asked_attributes |= FSAL_ATTR_OWNER ;
00130       fsalattr.owner = *uid ;
00131    }
00132 
00133   if( *valid & _9P_SETATTR_GID )
00134    {
00135       fsalattr.asked_attributes |= FSAL_ATTR_GROUP ;
00136       fsalattr.group = *gid ;
00137    }
00138 
00139   if( *valid & _9P_SETATTR_SIZE )
00140    {
00141       fsalattr.asked_attributes |= FSAL_ATTR_SIZE ;
00142       fsalattr.filesize = *size ;
00143    }
00144 
00145   if( *valid & _9P_SETATTR_ATIME )
00146    {
00147       fsalattr.asked_attributes |= FSAL_ATTR_ATIME ;
00148       fsalattr.atime.seconds  = t.tv_sec ;
00149       fsalattr.atime.nseconds = t.tv_usec * 1000 ;
00150    }
00151 
00152   if( *valid & _9P_SETATTR_MTIME )
00153    {
00154       fsalattr.asked_attributes |= FSAL_ATTR_MTIME ;
00155       fsalattr.mtime.seconds  = t.tv_sec ;
00156       fsalattr.mtime.nseconds = t.tv_usec * 1000 ;
00157    }
00158 
00159   if( *valid & _9P_SETATTR_CTIME )
00160    {
00161       fsalattr.asked_attributes |= FSAL_ATTR_CTIME ;
00162       fsalattr.ctime.seconds  = t.tv_sec ;
00163       fsalattr.ctime.nseconds = t.tv_usec * 1000 ;
00164    }
00165 
00166   if( *valid & _9P_SETATTR_ATIME_SET )
00167    {
00168       fsalattr.asked_attributes |= FSAL_ATTR_ATIME ;
00169       fsalattr.atime.seconds  = *atime_sec ;
00170       fsalattr.atime.nseconds = *atime_nsec ;
00171    }
00172 
00173   if( *valid & _9P_SETATTR_MTIME_SET )
00174    {
00175       fsalattr.asked_attributes |= FSAL_ATTR_MTIME ;
00176       fsalattr.mtime.seconds  = *mtime_sec ;
00177       fsalattr.mtime.nseconds = *mtime_nsec ;
00178    }
00179 
00180   /* Set size if needed */
00181   if( *valid & _9P_SETATTR_SIZE )
00182     {
00183       if((cache_status = cache_inode_truncate( pfid->pentry,
00184                                                *size,
00185                                                &parent_attr,
00186                                                &pfid->fsal_op_context,
00187                                                &cache_status)) != CACHE_INODE_SUCCESS)
00188         return _9p_rerror( preq9p, msgtag, _9p_tools_errno( cache_status ), plenout, preply ) ;
00189     }
00190 
00191   /* Now set the attr */ 
00192   if( cache_inode_setattr( pfid->pentry,
00193                            &fsalattr,
00194                            &pfid->fsal_op_context,
00195                            &cache_status ) != CACHE_INODE_SUCCESS )
00196         return _9p_rerror( preq9p, msgtag, _9p_tools_errno( cache_status ), plenout, preply ) ;
00197 
00198    /* Build the reply */
00199   _9p_setinitptr( cursor, preply, _9P_RSETATTR ) ;
00200   _9p_setptr( cursor, msgtag, u16 ) ;
00201 
00202   _9p_setendptr( cursor, preply ) ;
00203   _9p_checkbound( cursor, preply, plenout ) ;
00204 
00205   return 1 ;
00206 }
00207