nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=4:tabstop=4: 00003 */ 00004 00013 #ifdef HAVE_CONFIG_H 00014 #include "config.h" 00015 #endif 00016 00017 #include <string.h> 00018 #include "fsal.h" 00019 #include "fsal_internal.h" 00020 #include "fsal_convert.h" 00021 00049 fsal_status_t LUSTREFSAL_lookup(fsal_handle_t * p_parent_directory_handle, /* IN */ 00050 fsal_name_t * p_filename, /* IN */ 00051 fsal_op_context_t * p_context, /* IN */ 00052 fsal_handle_t * p_object_handle, /* OUT */ 00053 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00054 ) 00055 { 00056 int rc, errsv; 00057 fsal_status_t status; 00058 struct stat buffstat; 00059 fsal_path_t pathfsal; 00060 00061 /* sanity checks 00062 * note : object_attributes is optionnal 00063 * parent_directory_handle may be null for getting FS root. 00064 */ 00065 if(!p_object_handle || !p_context) 00066 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00067 00068 /* filename AND parent handle are NULL => lookup "/" */ 00069 if((p_parent_directory_handle && !p_filename) 00070 || (!p_parent_directory_handle && p_filename)) 00071 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); 00072 00073 /* get information about root */ 00074 if(!p_parent_directory_handle) 00075 { 00076 /* get handle for the mount point */ 00077 FSAL_str2path(((lustrefsal_op_context_t *)p_context)->export_context->mount_point, 00078 ((lustrefsal_op_context_t *)p_context)->export_context->mnt_len, &pathfsal); 00079 TakeTokenFSCall(); 00080 status = fsal_internal_Path2Handle(p_context, &pathfsal, p_object_handle); 00081 ReleaseTokenFSCall(); 00082 00083 if(FSAL_IS_ERROR(status)) 00084 ReturnStatus(status, INDEX_FSAL_lookup); 00085 00086 /* get attributes, if asked */ 00087 if(p_object_attributes) 00088 { 00089 status = LUSTREFSAL_getattrs(p_object_handle, p_context, p_object_attributes); 00090 if(FSAL_IS_ERROR(status)) 00091 { 00092 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00093 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00094 } 00095 } 00096 /* Done */ 00097 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00098 } 00099 00100 /* retrieve directory attributes */ 00101 00102 status = fsal_internal_Handle2FidPath(p_context, p_parent_directory_handle, &pathfsal); 00103 if(FSAL_IS_ERROR(status)) 00104 ReturnStatus(status, INDEX_FSAL_lookup); 00105 00106 /* get directory metadata */ 00107 TakeTokenFSCall(); 00108 rc = lstat(pathfsal.path, &buffstat); 00109 errsv = errno; 00110 ReleaseTokenFSCall(); 00111 00112 if(rc) 00113 { 00114 if(errsv == ENOENT) 00115 Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_lookup); 00116 else 00117 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup); 00118 } 00119 00120 /* Be careful about junction crossing, symlinks, hardlinks,... */ 00121 switch (posix2fsal_type(buffstat.st_mode)) 00122 { 00123 case FSAL_TYPE_DIR: 00124 // OK 00125 break; 00126 00127 case FSAL_TYPE_JUNCTION: 00128 // This is a junction 00129 Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); 00130 00131 case FSAL_TYPE_FILE: 00132 case FSAL_TYPE_LNK: 00133 case FSAL_TYPE_XATTR: 00134 // not a directory 00135 Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); 00136 00137 default: 00138 Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); 00139 } 00140 00141 LogFullDebug(COMPONENT_FSAL, "lookup of %s/%s\n", 00142 pathfsal.path, p_filename->name); 00143 00144 /* check rights to enter into the directory */ 00145 status = fsal_internal_testAccess(p_context, FSAL_X_OK, &buffstat, NULL); 00146 if(FSAL_IS_ERROR(status)) 00147 ReturnStatus(status, INDEX_FSAL_lookup); 00148 00149 status = fsal_internal_appendNameToPath(&pathfsal, p_filename); 00150 if(FSAL_IS_ERROR(status)) 00151 ReturnStatus(status, INDEX_FSAL_lookup); 00152 00153 /* get file handle, it it exists */ 00154 TakeTokenFSCall(); 00155 status = fsal_internal_Path2Handle(p_context, &pathfsal, p_object_handle); 00156 ReleaseTokenFSCall(); 00157 if(FSAL_IS_ERROR(status)) 00158 ReturnStatus(status, INDEX_FSAL_lookup); 00159 00160 /* get object attributes */ 00161 if(p_object_attributes) 00162 { 00163 status = LUSTREFSAL_getattrs(p_object_handle, p_context, p_object_attributes); 00164 if(FSAL_IS_ERROR(status)) 00165 { 00166 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00167 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00168 } 00169 } 00170 00171 /* lookup complete ! */ 00172 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); 00173 00174 } 00175 00198 fsal_status_t LUSTREFSAL_lookupPath(fsal_path_t * p_path, /* IN */ 00199 fsal_op_context_t * p_context, /* IN */ 00200 fsal_handle_t * object_handle, /* OUT */ 00201 fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ 00202 ) 00203 { 00204 fsal_status_t status; 00205 00206 /* sanity checks 00207 * note : object_attributes is optionnal. 00208 */ 00209 00210 if(!object_handle || !p_context || !p_path) 00211 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath); 00212 00213 /* test whether the path begins with a slash */ 00214 00215 if(p_path->path[0] != '/') 00216 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath); 00217 00218 /* directly call the lookup function */ 00219 00220 status = fsal_internal_Path2Handle(p_context, p_path, object_handle); 00221 if(FSAL_IS_ERROR(status)) 00222 ReturnStatus(status, INDEX_FSAL_lookupPath); 00223 00224 /* get object attributes */ 00225 if(p_object_attributes) 00226 { 00227 status = LUSTREFSAL_getattrs(object_handle, p_context, p_object_attributes); 00228 if(FSAL_IS_ERROR(status)) 00229 { 00230 FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); 00231 FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00232 } 00233 } 00234 00235 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath); 00236 00237 } 00238 00262 fsal_status_t LUSTREFSAL_lookupJunction(fsal_handle_t * p_junction_handle, /* IN */ 00263 fsal_op_context_t * p_context, /* IN */ 00264 fsal_handle_t * p_fsoot_handle, /* OUT */ 00265 fsal_attrib_list_t * p_fsroot_attributes /* [ IN/OUT ] */ 00266 ) 00267 { 00268 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction); 00269 }