nfs-ganesha 1.4

cache_inode_setattr.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 License
00011  * as published by the Free Software Foundation; either version 3 of
00012  * the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful, but
00015  * 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                          /* _SOLARIS */
00045 
00046 #include "log.h"
00047 #include "HashData.h"
00048 #include "HashTable.h"
00049 #include "fsal.h"
00050 #include "cache_inode.h"
00051 #include "nfs4_acls.h"
00052 
00053 #include <unistd.h>
00054 #include <sys/types.h>
00055 #include <sys/param.h>
00056 #include <time.h>
00057 #include <pthread.h>
00058 #include <assert.h>
00059 
00074 cache_inode_status_t
00075 cache_inode_setattr(cache_entry_t *entry,
00076                     fsal_attrib_list_t *attr,
00077                     fsal_op_context_t *context,
00078                     cache_inode_status_t *status)
00079 {
00080      fsal_status_t fsal_status = {0, 0};
00081 #ifdef _USE_NFS4_ACL
00082      fsal_acl_t *saved_acl = NULL;
00083      fsal_acl_status_t acl_status = 0;
00084 #endif /* _USE_NFS4_ACL */
00085 
00086      if ((entry->type == UNASSIGNED) ||
00087          (entry->type == RECYCLED)) {
00088           LogCrit(COMPONENT_CACHE_INODE,
00089                   "WARNING: unknown source entry type: type=%d, "
00090                   "line %d in file %s", entry->type, __LINE__, __FILE__);
00091           *status = CACHE_INODE_BAD_TYPE;
00092           goto out;
00093      }
00094 
00095      if ((attr->asked_attributes & FSAL_ATTR_SIZE) &&
00096          (entry->type != REGULAR_FILE)) {
00097           LogMajor(COMPONENT_CACHE_INODE,
00098                    "Attempt to truncate non-regular file: type=%d",
00099                    entry->type);
00100           *status = CACHE_INODE_BAD_TYPE;
00101      }
00102 
00103      pthread_rwlock_wrlock(&entry->attr_lock);
00104      if (attr->asked_attributes & FSAL_ATTR_SIZE) {
00105           fsal_status = FSAL_truncate(&entry->handle,
00106                                       context, attr->filesize,
00107                                       NULL, NULL);
00108           if (FSAL_IS_ERROR(fsal_status)) {
00109                *status = cache_inode_error_convert(fsal_status);
00110                if (fsal_status.major == ERR_FSAL_STALE) {
00111                     cache_inode_kill_entry(entry);
00112                }
00113                goto unlock;
00114           }
00115      }
00116 
00117 #ifdef _USE_NFS4_ACL
00118      saved_acl = entry->attributes.acl;
00119 #endif /* _USE_NFS4_ACL */
00120      fsal_status = FSAL_setattrs(&entry->handle, context, attr,
00121                                  &entry->attributes);
00122      if (FSAL_IS_ERROR(fsal_status)) {
00123           *status = cache_inode_error_convert(fsal_status);
00124           if (fsal_status.major == ERR_FSAL_STALE) {
00125                cache_inode_kill_entry(entry);
00126           }
00127           goto unlock;
00128      } else {
00129 #ifdef _USE_NFS4_ACL
00130           /* Decrement refcount on saved ACL */
00131          nfs4_acl_release_entry(saved_acl, &acl_status);
00132          if (acl_status != NFS_V4_ACL_SUCCESS) {
00133               LogCrit(COMPONENT_CACHE_INODE,
00134                       "Failed to release old acl, status=%d",
00135                       acl_status);
00136          }
00137 #endif /* _USE_NFS4_ACL */
00138      }
00139      cache_inode_fixup_md(entry);
00140 
00141      /* Copy the complete set of new attributes out. */
00142 
00143      *attr = entry->attributes;
00144 
00145      *status = CACHE_INODE_SUCCESS;
00146 
00147 unlock:
00148      pthread_rwlock_unlock(&entry->attr_lock);
00149 
00150 out:
00151 
00152      return *status;
00153 } /* cache_inode_setattr */