/** * FSAL_lookup : * Looks up for an object into a directory. * * Note : if parent handle and filename are NULL, * this retrieves root's handle. * * \param parent_directory_handle (input) * Handle of the parent directory to search the object in. * \param filename (input) * The name of the object to find. * \param p_context (input) * Authentication context for the operation (user,...). * \param object_handle (output) * The handle of the object corresponding to filename. * \param object_attributes (optional input/output) * Pointer to the attributes of the object we found. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * It can be NULL (increases performances). * * \return - ERR_FSAL_NO_ERROR, if no error. * - Another error code else. * */ fsal_status_t PTFSAL_lookup(const struct req_op_context *p_context, struct fsal_obj_handle *parent, const char *p_filename, struct attrlist *p_object_attr, ptfsal_handle_t *fh) { fsal_status_t status; int parent_fd; struct attrlist *parent_dir_attrs; fsi_stat_struct buffstat; int rc; struct pt_fsal_obj_handle *parent_hdl; FSI_TRACE(FSI_DEBUG, "Begin##################################\n"); if (p_filename != NULL) FSI_TRACE(FSI_DEBUG, "FSI - fsal_lookup file [%s]\n", p_filename); if (parent != NULL) FSI_TRACE(FSI_DEBUG, "FSI - fsal_lookup parent dir\n"); if (!parent || !p_filename) return fsalstat(ERR_FSAL_FAULT, 0); parent_hdl = container_of(parent, struct pt_fsal_obj_handle, obj_handle); parent_dir_attrs = &parent_hdl->obj_handle.attributes; /* get directory metadata */ parent_dir_attrs->mask = p_context->fsal_export->exp_ops. fs_supported_attrs(p_context->fsal_export); status = fsal_internal_handle2fd_at(p_context, parent_hdl, &parent_fd, O_RDONLY); if (FSAL_IS_ERROR(status)) return status; FSI_TRACE(FSI_DEBUG, "FSI - lookup parent directory type = %d\n", parent_dir_attrs->type); /* Be careful about junction crossing, symlinks, hardlinks,... */ switch (parent_dir_attrs->type) { case DIRECTORY: /* OK */ break; case REGULAR_FILE: case SYMBOLIC_LINK: /* not a directory */ pt_close(parent); return fsalstat(ERR_FSAL_NOTDIR, 0); default: return fsalstat(ERR_FSAL_SERVERFAULT, 0); } /* get file handle, it it exists */ /* This might be a race, but it's the best we can currently do */ rc = ptfsal_stat_by_parent_name(p_context, parent_hdl, p_filename, &buffstat); if (rc < 0) { ptfsal_closedir_fd(p_context, p_context->fsal_export, parent_fd); return fsalstat(ERR_FSAL_NOENT, errno); } memset(fh->data.handle.f_handle, 0, sizeof(fh->data.handle.f_handle)); memcpy(&fh->data.handle.f_handle, &buffstat.st_persistentHandle.handle, FSI_CCL_PERSISTENT_HANDLE_N_BYTES); fh->data.handle.handle_size = FSI_CCL_PERSISTENT_HANDLE_N_BYTES; fh->data.handle.handle_key_size = OPENHANDLE_KEY_LEN; fh->data.handle.handle_version = OPENHANDLE_VERSION; fh->data.handle.handle_type = posix2fsal_type(buffstat.st_mode); /* get object attributes */ if (p_object_attr) { p_object_attr->mask = p_context->fsal_export->exp_ops. fs_supported_attrs(p_context->fsal_export); status = PTFSAL_getattrs(p_context->fsal_export, p_context, fh, p_object_attr); if (FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_object_attr->mask); FSAL_SET_MASK(p_object_attr->mask, ATTR_RDATTR_ERR); } } ptfsal_closedir_fd(p_context, p_context->fsal_export, parent_fd); FSI_TRACE(FSI_DEBUG, "End##################################\n"); /* lookup complete ! */ return fsalstat(ERR_FSAL_NO_ERROR, 0); }
/** * FSAL_unlink: * Remove a filesystem object . * * \param dir_hdl (input): * Handle of the parent directory of the object to be deleted. * \param p_object_name (input): * Name of the object to be removed. * \param p_context (input): * Authentication context for the operation (user,...). * \param p_parentdir_attributes (optionnal input/output): * Post operation attributes of the parent directory. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * May be NULL. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - Another error code if an error occured. */ fsal_status_t PTFSAL_unlink(struct fsal_obj_handle *dir_hdl, /* IN */ const char *p_object_name, /* IN */ const struct req_op_context *p_context, /* IN */ struct attrlist *p_parent_attributes) { /* IN/OUT */ fsal_status_t status; int rc, errsv; fsi_stat_struct buffstat; struct pt_fsal_obj_handle *pt_hdl; /* sanity checks. */ if (!dir_hdl || !p_context || !p_object_name) return fsalstat(ERR_FSAL_FAULT, 0); pt_hdl = container_of(dir_hdl, struct pt_fsal_obj_handle, obj_handle); FSI_TRACE(FSI_DEBUG, "FSI - PTFSAL_unlink [%s] entry\n", p_object_name); /* build the child path */ FSI_TRACE(FSI_DEBUG, "FSI - PTFSAL_unlink [%s] build child path\n", p_object_name); /* get file metadata */ rc = ptfsal_stat_by_parent_name(p_context, pt_hdl, p_object_name, &buffstat); if (rc) { FSI_TRACE(FSI_DEBUG, "FSI - PTFSAL_unlink stat [%s] rc %d\n", p_object_name, rc); return fsalstat(posix2fsal_error(errno), errno); } /****************************** * DELETE FROM THE FILESYSTEM * ******************************/ /* If the object to delete is a directory, use 'rmdir' to delete * the object else use 'unlink' */ if (S_ISDIR(buffstat.st_mode)) { FSI_TRACE(FSI_DEBUG, "Deleting directory %s", p_object_name); rc = ptfsal_rmdir(p_context, pt_hdl, p_object_name); } else { FSI_TRACE(FSI_DEBUG, "Deleting file %s", p_object_name); rc = ptfsal_unlink(p_context, pt_hdl, p_object_name); } if (rc) { errsv = errno; return fsalstat(posix2fsal_error(errsv), errsv); } /*********************** * FILL THE ATTRIBUTES * ***********************/ if (p_parent_attributes) { status = PTFSAL_getattrs(p_context->fsal_export, p_context, pt_hdl->handle, p_parent_attributes); if (FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_parent_attributes->mask); FSAL_SET_MASK(p_parent_attributes->mask, ATTR_RDATTR_ERR); } } /* OK */ return fsalstat(ERR_FSAL_NO_ERROR, 0); }