nfs-ganesha 1.4

fsal_xattrs.c

Go to the documentation of this file.
00001 
00009 #ifdef HAVE_CONFIG_H
00010 #include "config.h"
00011 #endif
00012 
00013 #include "fsal.h"
00014 #include "fsal_internal.h"
00015 #include "fsal_convert.h"
00016 
00017 #include <string.h>
00018 
00019 /* generic definitions for extended attributes */
00020 
00021 #define XATTR_FOR_FILE     0x00000001
00022 #define XATTR_FOR_DIR      0x00000002
00023 #define XATTR_FOR_SYMLINK  0x00000004
00024 #define XATTR_FOR_ALL      0x0000000F
00025 #define XATTR_RO           0x00000100
00026 #define XATTR_RW           0x00000200
00027 
00028 /* function for getting an attribute value */
00029 
00030 typedef int (*xattr_getfunc_t) (fsal_handle_t *,        /* object handle */
00031                                 fsal_op_context_t *,    /* context */
00032                                 caddr_t,        /* output buff */
00033                                 size_t, /* output buff size */
00034                                 size_t *);      /* output size */
00035 
00036 typedef int (*xattr_setfunc_t) (fsal_handle_t *,        /* object handle */
00037                                 fsal_op_context_t *,    /* context */
00038                                 caddr_t,        /* input buff */
00039                                 size_t, /* input size */
00040                                 int);   /* creation flag */
00041 
00042 typedef int (*xattr_printfunc_t) (caddr_t,      /* Input buffer */
00043                                   size_t,       /* Input size   */
00044                                   caddr_t,      /* Output (ASCII) buffer */
00045                                   size_t *);    /* Output size */
00046 
00047 typedef struct fsal_xattr_def__
00048 {
00049   char xattr_name[FSAL_MAX_NAME_LEN];
00050   xattr_getfunc_t get_func;
00051   xattr_setfunc_t set_func;
00052   xattr_printfunc_t print_func;
00053   int flags;
00054 } fsal_xattr_def_t;
00055 
00056 /*
00057  * DEFINE HERE YOUR GET/SET FUNCTIONS
00058  */
00059 
00060 int get_void_attr(fsal_handle_t * p_objecthandle,       /* IN */
00061                   fsal_op_context_t * p_context,        /* IN */
00062                   caddr_t buffer_addr,  /* IN/OUT */
00063                   size_t buffer_size,   /* IN */
00064                   size_t * p_output_size)       /* OUT */
00065 {
00066   if(!p_objecthandle || !p_context || !p_output_size)
00067     return ERR_FSAL_FAULT;
00068 
00069   snprintf((char *)buffer_addr, buffer_size, "Hello World !");
00070 
00071   *p_output_size = strlen((char *)buffer_addr) + 1;
00072 
00073   return 0;
00074 
00075 }
00076 
00077 /* DEFINE HERE YOUR ATTRIBUTES LIST */
00078 
00079 static fsal_xattr_def_t xattr_list[] = {
00080   {"hello_world", get_void_attr, NULL, NULL, XATTR_FOR_ALL | XATTR_RO}
00081 };
00082 
00083 #define XATTR_COUNT 1
00084 
00085 /* YOUR SHOULD NOT HAVE TO MODIFY THE FOLLOWING FUNCTIONS */
00086 
00087 /* test if an object has a given attribute */
00088 int do_match_type(int xattr_flag, fsal_nodetype_t obj_type)
00089 {
00090   switch (obj_type)
00091     {
00092     case FSAL_TYPE_FILE:
00093       return ((xattr_flag & XATTR_FOR_FILE) == XATTR_FOR_FILE);
00094 
00095     case FSAL_TYPE_DIR:
00096       return ((xattr_flag & XATTR_FOR_DIR) == XATTR_FOR_DIR);
00097 
00098     case FSAL_TYPE_LNK:
00099       return ((xattr_flag & XATTR_FOR_SYMLINK) == XATTR_FOR_SYMLINK);
00100 
00101     default:
00102       return ((xattr_flag & XATTR_FOR_ALL) == XATTR_FOR_ALL);
00103     }
00104 }
00105 
00106 static int file_attributes_to_xattr_attrs(fsal_attrib_list_t * file_attrs,
00107                                           fsal_attrib_list_t * p_xattr_attrs,
00108                                           unsigned int attr_index)
00109 {
00110 
00111   /* supported attributes are:
00112    * - owner (same as the objet)
00113    * - group (same as the objet)
00114    * - type FSAL_TYPE_XATTR
00115    * - fileid (attr index ? or (fileid^((index+1)<<24)) )
00116    * - mode (config & file)
00117    * - atime, mtime, ctime = these of the object ?
00118    * - size=1block, used=1block
00119    * - rdev=0
00120    * - nlink=1
00121    */
00122   fsal_attrib_mask_t supported = FSAL_ATTR_SUPPATTR | FSAL_ATTR_MODE | FSAL_ATTR_FILEID
00123       | FSAL_ATTR_TYPE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP
00124       | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_CTIME
00125       | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_SIZE
00126       | FSAL_ATTR_SPACEUSED | FSAL_ATTR_NUMLINKS | FSAL_ATTR_RAWDEV | FSAL_ATTR_FSID;
00127   fsal_attrib_mask_t unsupp;
00128 
00129   /* only those supported by filesystem */
00130   supported &= global_fs_info.supported_attrs;
00131 
00132   if(p_xattr_attrs->asked_attributes == 0)
00133     {
00134       p_xattr_attrs->asked_attributes = supported;
00135 
00136       LogCrit(COMPONENT_FSAL,
00137               "Error: p_xattr_attrs->asked_attributes was 0 in %s() line %d, file %s",
00138               __FUNCTION__, __LINE__, __FILE__);
00139     }
00140 
00141   unsupp = p_xattr_attrs->asked_attributes & (~supported);
00142 
00143   if(unsupp)
00144     {
00145       LogDebug(COMPONENT_FSAL,
00146                "Asking for unsupported attributes in %s(): %#llX removing it from asked attributes",
00147                __FUNCTION__, unsupp);
00148 
00149       p_xattr_attrs->asked_attributes &= (~unsupp);
00150     }
00151 
00152   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SUPPATTR)
00153     p_xattr_attrs->supported_attributes = supported;
00154 
00155   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE)
00156     {
00157       p_xattr_attrs->mode = file_attrs->mode & global_fs_info.xattr_access_rights;
00158       if(xattr_list[attr_index].flags & XATTR_RO)
00159         p_xattr_attrs->mode &= ~(0222);
00160     }
00161 
00162   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FILEID)
00163     {
00164       unsigned int i;
00165       unsigned long hash = attr_index + 1;
00166       char *str = (char *)&file_attrs->fileid;
00167 
00168       for(i = 0; i < sizeof(p_xattr_attrs->fileid); i++, str++)
00169         {
00170           hash = (hash << 5) - hash + (unsigned long)(*str);
00171         }
00172       p_xattr_attrs->fileid = hash;
00173     }
00174 
00175   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_TYPE)
00176     p_xattr_attrs->type = FSAL_TYPE_XATTR;
00177 
00178   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER)
00179     p_xattr_attrs->owner = file_attrs->owner;
00180 
00181   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_GROUP)
00182     p_xattr_attrs->group = file_attrs->group;
00183 
00184   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_ATIME)
00185     p_xattr_attrs->atime = file_attrs->atime;
00186 
00187   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_MTIME)
00188     p_xattr_attrs->mtime = file_attrs->mtime;
00189 
00190   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CTIME)
00191     p_xattr_attrs->ctime = file_attrs->ctime;
00192 
00193   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CREATION)
00194     p_xattr_attrs->creation = file_attrs->creation;
00195 
00196   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_CHGTIME)
00197     {
00198       p_xattr_attrs->chgtime = file_attrs->chgtime;
00199       p_xattr_attrs->change = (uint64_t) p_xattr_attrs->chgtime.seconds;
00200     }
00201 
00202   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SIZE)
00203     p_xattr_attrs->filesize = DEV_BSIZE;
00204 
00205   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_SPACEUSED)
00206     p_xattr_attrs->spaceused = DEV_BSIZE;
00207 
00208   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_NUMLINKS)
00209     p_xattr_attrs->numlinks = 1;
00210 
00211   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_RAWDEV)
00212     {
00213       p_xattr_attrs->rawdev.major = 0;
00214       p_xattr_attrs->rawdev.minor = 0;
00215     }
00216 
00217   if(p_xattr_attrs->asked_attributes & FSAL_ATTR_FSID)
00218     {
00219       p_xattr_attrs->fsid = file_attrs->fsid;
00220     }
00221 
00222   /* if mode==0, then owner is set to root and mode is set to 0600 */
00223   if((p_xattr_attrs->asked_attributes & FSAL_ATTR_OWNER)
00224      && (p_xattr_attrs->asked_attributes & FSAL_ATTR_MODE) && (p_xattr_attrs->mode == 0))
00225     {
00226       p_xattr_attrs->owner = 0;
00227       p_xattr_attrs->mode = 0600;
00228       if(xattr_list[attr_index].flags & XATTR_RO)
00229         p_xattr_attrs->mode &= ~(0200);
00230     }
00231 
00232   return 0;
00233 
00234 }
00235 
00244 fsal_status_t FSAL_GetXAttrAttrs(fsal_handle_t * p_objecthandle,        /* IN */
00245                                  fsal_op_context_t * p_context, /* IN */
00246                                  unsigned int xattr_id, /* IN */
00247                                  fsal_attrib_list_t * p_attrs
00249     )
00250 {
00251   int rc;
00252   char buff[MAXNAMLEN];
00253   fsal_status_t st;
00254   fsal_attrib_list_t file_attrs;
00255 
00256   /* sanity checks */
00257   if(!p_objecthandle || !p_context || !p_attrs)
00258     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrAttrs);
00259 
00260   /* object attributes we want to retrieve from parent */
00261   file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER
00262       | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME
00263       | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID;
00264 
00265   /* don't retrieve attributes not asked */
00266 
00267   file_attrs.asked_attributes &= p_attrs->asked_attributes;
00268 
00269   st = FSAL_getattrs(p_objecthandle, p_context, &file_attrs);
00270 
00271   if(FSAL_IS_ERROR(st))
00272     Return(st.major, st.minor, INDEX_FSAL_GetXAttrAttrs);
00273 
00274   if((rc = file_attributes_to_xattr_attrs(&file_attrs, p_attrs, xattr_id)))
00275     {
00276       Return(ERR_FSAL_INVAL, rc, INDEX_FSAL_GetXAttrAttrs);
00277     }
00278 
00279   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrAttrs);
00280 
00281 }                               /* FSAL_GetXAttrAttrs */
00282 
00295 fsal_status_t FSAL_ListXAttrs(fsal_handle_t * p_objecthandle,   /* IN */
00296                               unsigned int argcookie,      /* IN */
00297                               fsal_op_context_t * p_context,    /* IN */
00298                               fsal_xattrent_t * xattrs_tab,     /* IN/OUT */
00299                               unsigned int xattrs_tabsize,      /* IN */
00300                               unsigned int *p_nb_returned,      /* OUT */
00301                               int *end_of_list  /* OUT */
00302     )
00303 {
00304   unsigned int index;
00305   unsigned int out_index;
00306   fsal_status_t st;
00307   fsal_attrib_list_t file_attrs;
00308   unsigned int cookie = argcookie ;
00309 
00310   /* sanity checks */
00311   if(!p_objecthandle || !p_context || !xattrs_tab || !p_nb_returned || !end_of_list)
00312     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_ListXAttrs);
00313 
00314   /* Deal with special cookie */
00315   if( argcookie == FSAL_XATTR_RW_COOKIE ) cookie = XATTR_COUNT ;
00316 
00317   /* object attributes we want to retrieve from parent */
00318   file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER
00319       | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME
00320       | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID;
00321 
00322   /* don't retrieve unsuipported attributes */
00323   file_attrs.asked_attributes &= global_fs_info.supported_attrs;
00324 
00325   st = FSAL_getattrs(p_objecthandle, p_context, &file_attrs);
00326 
00327   if(FSAL_IS_ERROR(st))
00328     Return(st.major, st.minor, INDEX_FSAL_ListXAttrs);
00329 
00330   for(index = cookie, out_index = 0;
00331       index < XATTR_COUNT && out_index < xattrs_tabsize; index++)
00332     {
00333       if(do_match_type(xattr_list[index].flags, p_objecthandle->object_type_reminder))
00334         {
00335           /* fills an xattr entry */
00336           xattrs_tab[out_index].xattr_id = index;
00337           FSAL_str2name(xattr_list[index].xattr_name, FSAL_MAX_NAME_LEN,
00338                         &xattrs_tab[out_index].xattr_name);
00339           xattrs_tab[out_index].xattr_cookie = index + 1;
00340 
00341           /* set asked attributes (all supported) */
00342           xattrs_tab[out_index].attributes.asked_attributes =
00343               global_fs_info.supported_attrs;
00344 
00345           if(file_attributes_to_xattr_attrs
00346              (&file_attrs, &xattrs_tab[out_index].attributes, index))
00347             {
00348               /* set error flag */
00349               xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR;
00350             }
00351 
00352           /* next output slot */
00353           out_index++;
00354         }
00355     }
00356 
00357   *p_nb_returned = out_index;
00358   *end_of_list = (index == XATTR_COUNT);
00359 
00360   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs);
00361 
00362 }
00363 
00374 fsal_status_t FSAL_GetXAttrValueById(fsal_handle_t * p_objecthandle,    /* IN */
00375                                      unsigned int xattr_id,     /* IN */
00376                                      fsal_op_context_t * p_context,     /* IN */
00377                                      caddr_t buffer_addr,       /* IN/OUT */
00378                                      size_t buffer_size,        /* IN */
00379                                      size_t * p_output_size     /* OUT */
00380     )
00381 {
00382   int rc;
00383 
00384   /* sanity checks */
00385   if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr)
00386     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue);
00387 
00388   /* check that this index match the type of entry */
00389   if(xattr_id >= XATTR_COUNT
00390      || !do_match_type(xattr_list[xattr_id].flags, p_objecthandle->object_type_reminder))
00391     {
00392       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrValue);
00393     }
00394 
00395   /* get the value */
00396   rc = xattr_list[xattr_id].get_func(p_objecthandle,
00397                                      p_context, buffer_addr, buffer_size, p_output_size);
00398 
00399   Return(rc, 0, INDEX_FSAL_GetXAttrValue);
00400 
00401 }
00402 
00412 fsal_status_t FSAL_GetXAttrIdByName(fsal_handle_t * p_objecthandle,     /* IN */
00413                                     const fsal_name_t * xattr_name,     /* IN */
00414                                     fsal_op_context_t * p_context,      /* IN */
00415                                     unsigned int *pxattr_id     /* OUT */
00416     )
00417 {
00418   unsigned int index;
00419   int found = FALSE;
00420 
00421   /* sanity checks */
00422   if(!p_objecthandle || !xattr_name)
00423     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue);
00424 
00425   for(index = 0; index < XATTR_COUNT; index++)
00426     {
00427       if(do_match_type(xattr_list[index].flags, p_objecthandle->object_type_reminder)
00428          && !strcmp(xattr_list[index].xattr_name, xattr_name->name))
00429         {
00430           found = TRUE;
00431           break;
00432         }
00433     }
00434 
00435   if(found)
00436     {
00437       *pxattr_id = index;
00438       Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue);
00439     }
00440   else
00441     Return(ERR_FSAL_NOENT, ENOENT, INDEX_FSAL_GetXAttrValue);
00442 }                               /* FSAL_GetXAttrIdByName */
00443 
00454 fsal_status_t FSAL_GetXAttrValueByName(fsal_handle_t * p_objecthandle,  /* IN */
00455                                        const fsal_name_t * xattr_name,  /* IN */
00456                                        fsal_op_context_t * p_context,   /* IN */
00457                                        caddr_t buffer_addr,     /* IN/OUT */
00458                                        size_t buffer_size,      /* IN */
00459                                        size_t * p_output_size   /* OUT */
00460     )
00461 {
00462   unsigned int index;
00463 
00464   /* sanity checks */
00465   if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr || !xattr_name)
00466     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue);
00467 
00468   /* look for this name */
00469 
00470   for(index = 0; index < XATTR_COUNT; index++)
00471     {
00472       if(do_match_type(xattr_list[index].flags, p_objecthandle->object_type_reminder)
00473          && !strcmp(xattr_list[index].xattr_name, xattr_name->name))
00474         {
00475 
00476           return FSAL_GetXAttrValueById(p_objecthandle, index, p_context, buffer_addr,
00477                                         buffer_size, p_output_size);
00478 
00479         }
00480     }
00481 
00482   /* not found */
00483   Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue);
00484 
00485 }
00486 
00487 fsal_status_t FSAL_SetXAttrValue(fsal_handle_t * p_objecthandle,        /* IN */
00488                                  const fsal_name_t * xattr_name,        /* IN */
00489                                  fsal_op_context_t * p_context, /* IN */
00490                                  caddr_t buffer_addr,   /* IN */
00491                                  size_t buffer_size,    /* IN */
00492                                  int create     /* IN */
00493     )
00494 {
00495   Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue);
00496 }
00497 
00498 fsal_status_t FSAL_SetXAttrValueById(fsal_handle_t * p_objecthandle,    /* IN */
00499                                      unsigned int xattr_id,     /* IN */
00500                                      fsal_op_context_t * p_context,     /* IN */
00501                                      caddr_t buffer_addr,       /* IN */
00502                                      size_t buffer_size /* IN */
00503     )
00504 {
00505   Return(ERR_FSAL_PERM, 0, INDEX_FSAL_SetXAttrValue);
00506 }
00507 
00515 fsal_status_t FSAL_RemoveXAttrById(fsal_handle_t * p_objecthandle,      /* IN */
00516                                    fsal_op_context_t * p_context,       /* IN */
00517                                    unsigned int xattr_id)       /* IN */
00518 {
00519   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00520 }                               /* FSAL_RemoveXAttrById */
00521 
00529 fsal_status_t FSAL_RemoveXAttrByName(fsal_handle_t * p_objecthandle,    /* IN */
00530                                      fsal_op_context_t * p_context,     /* IN */
00531                                      const fsal_name_t * xattr_name)    /* IN */
00532 {
00533   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00534 }                               /* FSAL_RemoveXAttrById */
00535 
00536 int FSAL_GetXattrOffsetSetable( void )
00537 {
00538   return XATTR_COUNT ;
00539 }