fsal_status_t WRAP_GPFSFSAL_symlink(fsal_handle_t * p_parent_directory_handle, /* IN */ fsal_name_t * p_linkname, /* IN */ fsal_path_t * p_linkcontent, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_accessmode_t accessmode, /* IN (ignored) */ fsal_handle_t * p_link_handle, /* OUT */ fsal_attrib_list_t * p_link_attributes /* [ IN/OUT ] */ ) { return GPFSFSAL_symlink((gpfsfsal_handle_t *) p_parent_directory_handle, p_linkname, p_linkcontent, (gpfsfsal_op_context_t *) p_context, accessmode, (gpfsfsal_handle_t *) p_link_handle, p_link_attributes); }
/** makesymlink * Note that we do not set mode bits on symlinks for Linux/POSIX * They are not really settable in the kernel and are not checked * anyway (default is 0777) because open uses that target's mode */ static fsal_status_t makesymlink(struct fsal_obj_handle *dir_hdl, const char *name, const char *link_path, struct attrlist *attr_in, struct fsal_obj_handle **handle, struct attrlist *attrs_out) { fsal_status_t status; struct gpfs_fsal_obj_handle *hdl; struct gpfs_file_handle *fh = alloca(sizeof(struct gpfs_file_handle)); /* Use a separate attrlist to getch the actual attributes into */ struct attrlist attrib; *handle = NULL; /* poison it first */ if (!dir_hdl->obj_ops.handle_is(dir_hdl, DIRECTORY)) { LogCrit(COMPONENT_FSAL, "Parent handle is not a directory. hdl = 0x%p", dir_hdl); return fsalstat(ERR_FSAL_NOTDIR, 0); } memset(fh, 0, sizeof(struct gpfs_file_handle)); fh->handle_size = GPFS_MAX_FH_SIZE; fsal_prepare_attrs(&attrib, ATTR_GPFS_ALLOC_HANDLE); if (attrs_out != NULL) attrib.mask |= attrs_out->mask; status = GPFSFSAL_symlink(dir_hdl, name, link_path, op_ctx, attr_in->mode, fh, &attrib); if (FSAL_IS_ERROR(status)) return status; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, dir_hdl->fs, &attrib, link_path, op_ctx->fsal_export); if (attrs_out != NULL) { /* Copy the attributes to caller, passing ACL ref. */ fsal_copy_attrs(attrs_out, &attrib, true); } else { /* Done with the attrs */ fsal_release_attrs(&attrib); } *handle = &hdl->obj_handle; /* We handled the mode above. */ FSAL_UNSET_MASK(attr_in->mask, ATTR_MODE); if (attr_in->mask) { /* Now per support_ex API, if there are any other attributes * set, go ahead and get them set now. */ status = (*handle)->obj_ops.setattr2(*handle, false, NULL, attr_in); if (FSAL_IS_ERROR(status)) { /* Release the handle we just allocated. */ LogFullDebug(COMPONENT_FSAL, "setattr2 status=%s", fsal_err_txt(status)); (*handle)->obj_ops.release(*handle); *handle = NULL; } } else { status = fsalstat(ERR_FSAL_NO_ERROR, 0); if (attrs_out != NULL) { /* Make sure ATTR_RDATTR_ERR is cleared on success. */ attrs_out->mask &= ~ATTR_RDATTR_ERR; } } FSAL_SET_MASK(attr_in->mask, ATTR_MODE); return status; }