nfs-ganesha 1.4

fsal_xattrs.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright (C) 2010 The Linux Box, Inc.
00005  * Contributor : Adam C. Emerson <aemerson@linuxbox.com>
00006  *
00007  * Portions copyright CEA/DAM/DIF  (2008)
00008  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00009  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00010  *
00011  *
00012  * This program is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 3 of the License, or (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public
00023  * License along with this library; if not, write to the Free Software
00024  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00025  *
00026  * -------------
00027  */
00033 #ifdef HAVE_CONFIG_H
00034 #include "config.h"
00035 #endif
00036 
00037 #include "fsal.h"
00038 #include "fsal_internal.h"
00039 #include "fsal_convert.h"
00040 
00041 #include <string.h>
00042 #include <alloca.h>
00043 #include <fcntl.h>
00044 
00053 fsal_status_t CEPHFSAL_GetXAttrAttrs(fsal_handle_t * exthandle,
00054                                      fsal_op_context_t * extcontext,
00055                                      unsigned int xattr_id,
00056                                      fsal_attrib_list_t * attrs)
00057 {
00058   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00059   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00060   int rc = 0;
00061   fsal_status_t status;
00062   fsal_attrib_list_t file_attrs;
00063   fsal_attrib_mask_t na_supported=
00064     (FSAL_ATTR_SUPPATTR | FSAL_ATTR_TYPE  | FSAL_ATTR_SIZE  |
00065      FSAL_ATTR_FSID     | FSAL_ATTR_MODE  | FSAL_ATTR_OWNER |
00066      FSAL_ATTR_GROUP    | FSAL_ATTR_CHGTIME);
00067   fsal_attrib_mask_t fa_wanted=
00068     (FSAL_ATTR_FSID  | FSAL_ATTR_MODE  | FSAL_ATTR_OWNER |
00069      FSAL_ATTR_GROUP | FSAL_ATTR_CHGTIME);
00070   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00071   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00072   int len;
00073 
00074   /* sanity checks */
00075   if(!handle || !context || !attrs)
00076     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrAttrs);
00077 
00078   /* Check that asked attributes are supported */
00079 
00080   if(attrs->asked_attributes & ~(na_supported))
00081     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrAttrs);
00082 
00083   /* object attributes we want to retrieve from parent */
00084   file_attrs.asked_attributes = fa_wanted;
00085 
00086   /* don't retrieve attributes not asked */
00087 
00088   file_attrs.asked_attributes &= attrs->asked_attributes;
00089 
00090   status = CEPHFSAL_getattrs(exthandle, extcontext, attrs);
00091 
00092   if(FSAL_IS_ERROR(status))
00093     ReturnStatus(status, INDEX_FSAL_GetXAttrAttrs);
00094 
00095   /* We support a subset of the attributes of files */
00096 
00097   if (attrs->asked_attributes & FSAL_ATTR_SUPPATTR)
00098     file_attrs.supported_attributes=na_supported;
00099 
00100   /* Attributes are attributes */
00101 
00102   if (attrs->asked_attributes & FSAL_ATTR_TYPE)
00103     file_attrs.type = FSAL_TYPE_XATTR;
00104 
00105   /* Attributes are not executable */
00106 
00107   if (attrs->asked_attributes & FSAL_ATTR_MODE)
00108     file_attrs.mode = file_attrs.mode & ~(S_IXUSR | S_IXGRP | S_IXOTH);
00109 
00110   /* Length */
00111 
00112   if (attrs->asked_attributes & FSAL_ATTR_SIZE)
00113     {
00114         len = ceph_ll_lenxattr_by_idx(context->export_context->cmount,
00115                                       VINODE(handle), xattr_id, uid, gid);
00116         if (len < 0)
00117             Return(ERR_FSAL_INVAL, rc, INDEX_FSAL_GetXAttrAttrs);
00118         file_attrs.filesize = len;
00119     }
00120 
00121   *attrs = file_attrs;
00122 
00123   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrAttrs);
00124 }                               /* FSAL_GetXAttrAttrs */
00125 
00138 fsal_status_t CEPHFSAL_ListXAttrs(fsal_handle_t * exthandle,
00139                                   unsigned int cookie,
00140                                   fsal_op_context_t * extcontext,
00141                                   fsal_xattrent_t * xattrs_tab,
00142                                   unsigned int xattrs_tabsize,
00143                                   unsigned int *p_nb_returned,
00144                                   int *end_of_list)
00145 {
00146   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00147   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00148   fsal_status_t status;
00149   fsal_attrib_list_t attr_attrs;
00150   fsal_attrib_mask_t fa_wanted=
00151     (FSAL_ATTR_FSID  | FSAL_ATTR_MODE  | FSAL_ATTR_OWNER |
00152      FSAL_ATTR_GROUP | FSAL_ATTR_CHGTIME);
00153   fsal_attrib_mask_t na_supported=
00154     (FSAL_ATTR_SUPPATTR | FSAL_ATTR_TYPE  | FSAL_ATTR_SIZE  |
00155      FSAL_ATTR_FSID     | FSAL_ATTR_MODE  | FSAL_ATTR_OWNER |
00156      FSAL_ATTR_GROUP    | FSAL_ATTR_CHGTIME);
00157   char* names;
00158   int rc;
00159   int lcookie=cookie;
00160   int uid=FSAL_OP_CONTEXT_TO_UID(context);
00161   int gid=FSAL_OP_CONTEXT_TO_GID(context);
00162   int idx;
00163   char *ptr;
00164 
00165   names = alloca(sizeof(fsal_xattrent_t) * xattrs_tabsize);
00166 
00167   ptr = names;
00168 
00169   /* sanity checks */
00170   if(!handle|| !context || !xattrs_tab || !p_nb_returned || !end_of_list)
00171     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_ListXAttrs);
00172 
00173   /* Retrieve attributes that should be inherited from the file */
00174 
00175   attr_attrs.asked_attributes = fa_wanted;
00176   status = CEPHFSAL_getattrs(exthandle, extcontext, &attr_attrs);
00177   if(FSAL_IS_ERROR(status))
00178     ReturnStatus(status, INDEX_FSAL_GetXAttrAttrs);
00179 
00180   /* We support a subset of the attributes of files */
00181 
00182   attr_attrs.supported_attributes = na_supported;
00183 
00184   /* Attributes are attributes */
00185 
00186   attr_attrs.type = FSAL_TYPE_XATTR;
00187 
00188   /* Attributes are not executable */
00189 
00190   attr_attrs.mode = attr_attrs.mode & ~(S_IXUSR | S_IXGRP | S_IXOTH);
00191 
00192   rc = ceph_ll_listxattr_chunks(context->export_context->cmount,
00193                                 VINODE(handle), names,
00194                                 sizeof(fsal_xattrent_t) * xattrs_tabsize,
00195                                 &lcookie, end_of_list, uid, gid);
00196 
00197   if (rc < 0)
00198     Return(posix2fsal_error(rc), 0, INDEX_FSAL_open);
00199 
00200   for(idx=0; idx <= rc && idx <= xattrs_tabsize; idx++)
00201     {
00202       xattrs_tab[idx].xattr_id=idx;
00203       FSAL_str2name(ptr, FSAL_MAX_NAME_LEN,
00204                     &(xattrs_tab[idx].xattr_name));
00205       xattrs_tab[idx].xattr_cookie = idx+1;
00206       ptr += strlen(ptr);
00207       attr_attrs.filesize = ((uint64_t) *ptr);
00208       ptr += sizeof(uint64_t);
00209       xattrs_tab[idx].attributes = attr_attrs;
00210     }
00211 
00212   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs);
00213 }
00214 
00225 fsal_status_t CEPHFSAL_GetXAttrValueById(fsal_handle_t * exthandle,
00226                                          unsigned int xattr_id,
00227                                          fsal_op_context_t * extcontext,
00228                                          caddr_t buffer_addr,
00229                                          size_t buffer_size,
00230                                          size_t * p_output_size)
00231 {
00232   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00233   cephfsal_op_context_t* context = (cephfsal_op_context_t*) context;
00234   int len = 0;
00235   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00236   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00237 
00238   /* sanity checks */
00239   if(!handle || !context || !p_output_size || !buffer_addr)
00240     ReturnCode(ERR_FSAL_FAULT, 0);
00241 
00242   ceph_ll_getxattr_by_idx(context->export_context->cmount,
00243                           VINODE(handle), xattr_id, buffer_addr,
00244                           buffer_size, uid, gid);
00245 
00246   if (len < 0)
00247     ReturnCode(posix2fsal_error(len), 0);
00248 
00249   *p_output_size=len;
00250 
00251   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue);
00252 }
00253 
00263 fsal_status_t CEPHFSAL_GetXAttrIdByName(fsal_handle_t * exthandle,
00264                                         const fsal_name_t * xattr_name,
00265                                         fsal_op_context_t * extcontext,
00266                                         unsigned int *pxattr_id)
00267 {
00268   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00269   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00270   int index;
00271   char name[FSAL_MAX_NAME_LEN];
00272   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00273   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00274 
00275   FSAL_name2str((fsal_name_t *) xattr_name, name, FSAL_MAX_NAME_LEN);
00276 
00277   /* sanity checks */
00278   if(!handle || !xattr_name)
00279     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue);
00280 
00281   index = ceph_ll_getxattridx(context->export_context->cmount,
00282                               VINODE(handle), name,
00283                               uid, gid);
00284   if (index < 0)
00285     ReturnCode(posix2fsal_error(index), 0);
00286 
00287   else
00288     *pxattr_id = index;
00289 
00290   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue);
00291 }
00292 
00303 fsal_status_t CEPHFSAL_GetXAttrValueByName(fsal_handle_t * exthandle,
00304                                            const fsal_name_t * xattr_name,
00305                                            fsal_op_context_t * extcontext,
00306                                            caddr_t buffer_addr,
00307                                            size_t buffer_size,
00308                                            size_t * p_output_size)
00309 {
00310   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00311   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00312   int len;
00313   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00314   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00315   char name[FSAL_MAX_NAME_LEN];
00316 
00317   FSAL_name2str((fsal_name_t*) xattr_name, name, FSAL_MAX_NAME_LEN);
00318 
00319   /* sanity checks */
00320   if(!handle || !context || !p_output_size || !buffer_addr || !xattr_name)
00321     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue);
00322 
00323   len = ceph_ll_getxattr(context->export_context->cmount,
00324                          VINODE(handle), name,
00325                          buffer_addr, buffer_size,
00326                          uid, gid);
00327   if (len < 0)
00328     ReturnCode(posix2fsal_error(len), 0);
00329 
00330 
00331   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue);
00332 }
00333 
00334 fsal_status_t CEPHFSAL_SetXAttrValue(fsal_handle_t * exthandle,
00335                                      const fsal_name_t * xattr_name,
00336                                      fsal_op_context_t * extcontext,
00337                                      caddr_t buffer_addr,
00338                                      size_t buffer_size,
00339                                      int create)
00340 {
00341   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00342   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00343   int rc;
00344   char name[FSAL_MAX_NAME_LEN];
00345   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00346   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00347 
00348   FSAL_name2str((fsal_name_t *) xattr_name, name, FSAL_MAX_NAME_LEN);
00349 
00350   rc = ceph_ll_setxattr(context->export_context->cmount,
00351                         VINODE(handle), name,
00352                         buffer_addr, buffer_size,
00353                         create ? O_CREAT : 0,
00354                         uid, gid);
00355 
00356 
00357   if (rc < 0)
00358     Return(posix2fsal_error(rc), 0, INDEX_FSAL_SetXAttrValue);
00359 
00360   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue);
00361 }
00362 
00363 fsal_status_t CEPHFSAL_SetXAttrValueById(fsal_handle_t * exthandle,
00364                                          unsigned int xattr_id,
00365                                          fsal_op_context_t * extcontext,
00366                                          caddr_t buffer_addr,
00367                                          size_t buffer_size)
00368 {
00369   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00370   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00371   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00372   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00373 
00374   ceph_ll_setxattr_by_idx(context->export_context->cmount,
00375                           VINODE(handle), xattr_id,
00376                           buffer_addr, buffer_size, 0, uid, gid);
00377 
00378   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00379 }
00380 
00388 fsal_status_t CEPHFSAL_RemoveXAttrById(fsal_handle_t * exthandle,
00389                                        fsal_op_context_t * extcontext,
00390                                        unsigned int xattr_id)
00391 {
00392   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00393   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00394   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00395   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00396   int rc;
00397 
00398   rc = ceph_ll_removexattr_by_idx(context->export_context->cmount,
00399                                   VINODE(handle), xattr_id, uid, gid);
00400   if(rc < 0)
00401     ReturnCode(posix2fsal_error(rc), 0);
00402 
00403   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00404 }
00405 
00413 fsal_status_t CEPHFSAL_RemoveXAttrByName(fsal_handle_t * exthandle,
00414                                          fsal_op_context_t * extcontext,
00415                                          const fsal_name_t * xattr_name)
00416 {
00417   cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
00418   cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
00419   int rc;
00420   int uid = FSAL_OP_CONTEXT_TO_UID(context);
00421   int gid = FSAL_OP_CONTEXT_TO_GID(context);
00422   char name[FSAL_MAX_NAME_LEN];
00423 
00424   FSAL_name2str((fsal_name_t *)xattr_name, name, FSAL_MAX_NAME_LEN);
00425 
00426   rc = ceph_ll_removexattr(context->export_context->cmount,
00427                            VINODE(handle), name, uid, gid);
00428 
00429   if(rc < 0)
00430     ReturnCode(posix2fsal_error(rc), 0);
00431 
00432   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00433 }