nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright (C) 2010, The Linux Box Corporation 00005 * Contributor : Adam C. Emerson <aemerson@linuxbox.com> 00006 * 00007 * Some 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 */ 00028 00035 #ifdef HAVE_CONFIG_H 00036 #include "config.h" 00037 #endif 00038 00039 #include "fsal.h" 00040 #include "fsal_internal.h" 00041 #include "fsal_convert.h" 00042 #include <string.h> 00043 00068 fsal_status_t CEPHFSAL_opendir(fsal_handle_t * exthandle, 00069 fsal_op_context_t * extcontext, 00070 fsal_dir_t * extdescriptor, 00071 fsal_attrib_list_t * dir_attributes) 00072 { 00073 cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle; 00074 cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext; 00075 cephfsal_dir_t* descriptor = (cephfsal_dir_t*) extdescriptor; 00076 fsal_status_t status; 00077 int rc; 00078 int uid = FSAL_OP_CONTEXT_TO_UID(context); 00079 int gid = FSAL_OP_CONTEXT_TO_GID(context); 00080 struct ceph_dir_result *dh; 00081 00082 /* sanity checks 00083 * note : dir_attributes is optional. 00084 */ 00085 if(!handle || !context || !descriptor) 00086 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir); 00087 00088 TakeTokenFSCall(); 00089 /* XXX ceph_ll_opendir has void in the interface, but Client::ll_opendir 00090 * is using dir_result_t. */ 00091 rc = ceph_ll_opendir(context->export_context->cmount, VINODE(handle), 00092 (void *) &dh, uid, gid); 00093 ReleaseTokenFSCall(); 00094 00095 if (rc < 0) 00096 Return(posix2fsal_error(rc), 0, INDEX_FSAL_opendir); 00097 00098 descriptor->dh = dh; 00099 descriptor->vi = VINODE(handle); 00100 descriptor->ctx = *context; 00101 00102 if(dir_attributes) 00103 { 00104 status = CEPHFSAL_getattrs(exthandle, extcontext, dir_attributes); 00105 00106 if(FSAL_IS_ERROR(status)) 00107 { 00108 FSAL_CLEAR_MASK(dir_attributes->asked_attributes); 00109 FSAL_SET_MASK(dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00110 } 00111 } 00112 00113 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir); 00114 } 00115 00151 fsal_status_t CEPHFSAL_readdir(fsal_dir_t *extdescriptor, 00152 fsal_cookie_t extstart, 00153 fsal_attrib_mask_t attrmask, 00154 fsal_mdsize_t buffersize, 00155 fsal_dirent_t *dirents, 00156 fsal_cookie_t *extend, 00157 fsal_count_t *count, 00158 fsal_boolean_t *end_of_dir) 00159 { 00160 int rc = 0; 00161 fsal_status_t status; 00162 struct dirent de; 00163 cephfsal_dir_t* descriptor = (cephfsal_dir_t*) extdescriptor; 00164 struct ceph_mount_info *cmount = descriptor->ctx.export_context->cmount; 00165 00166 loff_t start = ((cephfsal_cookie_t*) extstart.data)->cookie; 00167 loff_t* end = &((cephfsal_cookie_t*) extend->data)->cookie; 00168 unsigned int max_entries = buffersize / sizeof(fsal_dirent_t); 00169 00170 /* sanity checks */ 00171 00172 if(!descriptor || !dirents || !end || !count || !end_of_dir) 00173 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); 00174 00175 *end_of_dir = FALSE; 00176 *count = 0; 00177 00178 TakeTokenFSCall(); 00179 00180 (void) ceph_seekdir(cmount, DH(descriptor), start); 00181 00182 while ((*count <= max_entries) && !(*end_of_dir)) { 00183 struct stat st; 00184 00185 memset(&dirents[*count], sizeof(fsal_dirent_t), 0); 00186 memset(&de, sizeof(struct dirent), 0); 00187 memset(&st, sizeof(struct stat), 0); 00188 int stmask = 0; 00189 00190 TakeTokenFSCall(); 00191 rc = ceph_readdirplus_r(cmount, DH(descriptor), &de, &st, &stmask); 00192 if (rc < 0) /* Error */ 00193 Return(posix2fsal_error(rc), 0, INDEX_FSAL_readdir); 00194 else if (rc == 1) { 00195 /* Got a dirent */ 00196 cephfsal_handle_t* entryhandle 00197 = (cephfsal_handle_t*) &(dirents[*count].handle.data); 00198 cephfsal_cookie_t* entrycookie 00199 = (cephfsal_cookie_t*) &(dirents[*count].cookie); 00200 /* skip . and .. */ 00201 if(!strcmp(de.d_name, ".") || !strcmp(de.d_name, "..")) 00202 continue; 00203 00204 entryhandle->data.vi.ino.val = st.st_ino; 00205 entryhandle->data.vi.snapid.val = st.st_dev; 00206 00207 status = FSAL_str2name(de.d_name, FSAL_MAX_NAME_LEN, 00208 &(dirents[*count].name)); 00209 if(FSAL_IS_ERROR(status)) 00210 ReturnStatus(status, INDEX_FSAL_readdir); 00211 00212 entrycookie->data.cookie = ceph_telldir(cmount, DH(descriptor)); 00213 dirents[*count].attributes.asked_attributes = attrmask; 00214 00215 status = 00216 posix2fsal_attributes(&st, 00217 &(dirents[*count].attributes)); 00218 if(FSAL_IS_ERROR(status)) { 00219 FSAL_CLEAR_MASK(dirents[*count].attributes 00220 .asked_attributes); 00221 FSAL_SET_MASK(dirents[*count].attributes.asked_attributes, 00222 FSAL_ATTR_RDATTR_ERR); 00223 } 00224 if (*count != 0) { 00225 dirents[(*count)-1].nextentry = &(dirents[*count]); 00226 } 00227 (*count)++; 00228 } else if (rc == 0) /* EOF */ 00229 *end_of_dir = TRUE; 00230 else{ 00231 /* Can't happen */ 00232 abort(); 00233 } 00234 } /* while */ 00235 00236 (*end) = ceph_telldir(cmount, DH(descriptor)); 00237 00238 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); 00239 } 00240 00254 fsal_status_t CEPHFSAL_closedir(fsal_dir_t * extdescriptor) 00255 { 00256 cephfsal_dir_t* descriptor = (cephfsal_dir_t*) extdescriptor; 00257 struct ceph_mount_info *cmount = descriptor->ctx.export_context->cmount; 00258 int rc = 0; 00259 00260 /* sanity checks */ 00261 if(!descriptor) 00262 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_closedir); 00263 00264 TakeTokenFSCall(); 00265 rc = ceph_ll_releasedir(cmount, DH(descriptor)); 00266 ReleaseTokenFSCall(); 00267 00268 if (rc < 0) 00269 Return(posix2fsal_error(rc), 0, INDEX_FSAL_closedir); 00270 00271 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_closedir); 00272 }