static int fill_create_process_event( struct debug_event *event, const void *arg ) { struct process *debugger = event->debugger->process; struct thread *thread = event->sender; struct process *process = thread->process; struct process_dll *exe_module = get_process_exe_module( process ); const client_ptr_t *entry = arg; obj_handle_t handle; /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */ if (!(handle = alloc_handle( debugger, process, PROCESS_ALL_ACCESS, 0 ))) return 0; event->data.create_process.process = handle; /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */ if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 ))) { close_handle( debugger, event->data.create_process.process ); return 0; } event->data.create_process.thread = handle; event->data.create_process.file = 0; event->data.create_process.teb = thread->teb; event->data.create_process.base = exe_module->base; event->data.create_process.start = *entry; event->data.create_process.dbg_offset = exe_module->dbg_offset; event->data.create_process.dbg_size = exe_module->dbg_size; event->data.create_process.name = exe_module->name; event->data.create_process.unicode = 1; if (exe_module->mapping) /* the doc says write access too, but this doesn't seem a good idea */ event->data.create_process.file = open_mapping_file( debugger, exe_module->mapping, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE ); return 1; }
Registration::Registration() : _handle(alloc_handle()), _default_eid(core::BundleCore::local), _no_more_bundles(false), _persistent(false), _detached(false), _expiry(0), _filter_fragments(true) { _default_eid.setApplication(_handle); }
/****************************************************************************** * new_object * * Allocates a new object of size cbSize on the current process's heap. * Initializes the object header using the destructor and dwType params. * Allocates a handle to the object in the handle table pointed to by lpTable. * Returns a pointer to the created object in ppObject. * Returns a handle to the created object. * * PARAMS * lpTable [I] Pointer to the handle table, from which a handle is to be * allocated. * cbSize [I] Size of the object to be allocated in bytes. * dwType [I] Object type; will be copied to the object header. * destructor [I] Function pointer to a destructor function. Will be called * once the object's reference count gets zero. * ppObject [O] Pointer to a pointer variable, where a pointer to the newly * created object will be stored. You may set this to NULL. * * RETURNS * INVALID_HANDLE_VALUE, if something went wrong. * a handle to the new object, if successful. */ unsigned int new_object(HANDLETABLE *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, OBJECTHDR **ppObject) { OBJECTHDR *pObject; unsigned int hObject; if (ppObject) *ppObject = NULL; pObject = HeapAlloc(GetProcessHeap(), 0, cbSize); if (!pObject) return (unsigned int)INVALID_HANDLE_VALUE; pObject->dwType = dwType; pObject->refcount = 0; pObject->destructor = destructor; if (!alloc_handle(lpTable, pObject, &hObject)) HeapFree(GetProcessHeap(), 0, pObject); else if (ppObject) *ppObject = pObject; return hObject; }
/* lookup * deprecated NULL parent && NULL path implies root handle */ static fsal_status_t lookup(struct fsal_obj_handle *parent, const char *path, struct fsal_obj_handle **handle, struct attrlist *attrs_out) { fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval = 0; fsal_status_t status; struct gpfs_fsal_obj_handle *hdl; struct attrlist attrib; struct gpfs_file_handle *fh = alloca(sizeof(struct gpfs_file_handle)); struct fsal_filesystem *fs; *handle = NULL; /* poison it first */ fs = parent->fs; if (!path) return fsalstat(ERR_FSAL_FAULT, 0); memset(fh, 0, sizeof(struct gpfs_file_handle)); fh->handle_size = GPFS_MAX_FH_SIZE; if (!parent->obj_ops.handle_is(parent, DIRECTORY)) { LogCrit(COMPONENT_FSAL, "Parent handle is not a directory. hdl = 0x%p", parent); return fsalstat(ERR_FSAL_NOTDIR, 0); } if (parent->fsal != parent->fs->fsal) { LogDebug(COMPONENT_FSAL, "FSAL %s operation for handle belonging to FSAL %s, return EXDEV", parent->fsal->name, parent->fs->fsal->name); retval = EXDEV; goto hdlerr; } fsal_prepare_attrs(&attrib, ATTR_GPFS_ALLOC_HANDLE); if (attrs_out != NULL) attrib.mask |= attrs_out->mask; status = GPFSFSAL_lookup(op_ctx, parent, path, &attrib, fh, &fs); if (FSAL_IS_ERROR(status)) return status; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, fs, &attrib, NULL, 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; return fsalstat(ERR_FSAL_NO_ERROR, 0); hdlerr: fsal_error = posix2fsal_error(retval); return fsalstat(fsal_error, retval); }
TC_HANDLE_T TC_INIT(const char *tablename) { TC_HANDLE_T h; STRUCT_GETINFO info; unsigned int i; int tmp; socklen_t s; iptc_fn = TC_INIT; if (sockfd != -1) close(sockfd); sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW); if (sockfd < 0) return NULL; s = sizeof(info); if (strlen(tablename) >= TABLE_MAXNAMELEN) { errno = EINVAL; return NULL; } strcpy(info.name, tablename); if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) return NULL; if ((h = alloc_handle(info.name, info.size, info.num_entries)) == NULL) return NULL; /* Too hard --RR */ #if 0 sprintf(pathname, "%s/%s", IPT_LIB_DIR, info.name); dynlib = dlopen(pathname, RTLD_NOW); if (!dynlib) { errno = ENOENT; return NULL; } h->hooknames = dlsym(dynlib, "hooknames"); if (!h->hooknames) { errno = ENOENT; return NULL; } #else h->hooknames = hooknames; #endif /* Initialize current state */ h->info = info; h->new_number = h->info.num_entries; for (i = 0; i < h->info.num_entries; i++) h->counter_map[i] = ((struct counter_map){COUNTER_MAP_NORMAL_MAP, i});
static int fill_create_thread_event( struct debug_event *event, void *arg ) { struct process *debugger = event->debugger->process; struct thread *thread = event->sender; obj_handle_t handle; /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */ if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 ))) return 0; event->data.info.create_thread.handle = handle; event->data.info.create_thread.teb = thread->teb; event->data.info.create_thread.start = arg; return 1; }
static fsal_status_t makenode(struct fsal_obj_handle *dir_hdl, const char *name, object_file_type_t nodetype, /* IN */ fsal_dev_t *dev, /* IN */ struct attrlist *attrib, struct fsal_obj_handle **handle) { fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval = 0; fsal_status_t status; struct pt_fsal_obj_handle *hdl; ptfsal_handle_t *dir_fh = NULL; ptfsal_handle_t *fh = alloca(sizeof(ptfsal_handle_t)); *handle = NULL; /* poison it */ if (!dir_hdl->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(ptfsal_handle_t)); fh->data.handle.handle_size = FSI_CCL_PERSISTENT_HANDLE_N_BYTES; attrib->mask = op_ctx->fsal_export->ops->fs_supported_attrs(op_ctx->fsal_export); status = PTFSAL_mknode(dir_hdl, name, op_ctx, attrib->mode, nodetype, dev, fh, attrib); if (FSAL_IS_ERROR(status)) return status; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, attrib, NULL, dir_fh, NULL, op_ctx->fsal_export); if (hdl == NULL) { retval = ENOMEM; goto nodeerr; } *handle = &hdl->obj_handle; return fsalstat(ERR_FSAL_NO_ERROR, 0); nodeerr: fsal_error = posix2fsal_error(retval); return fsalstat(fsal_error, retval); }
static int fill_load_dll_event( struct debug_event *event, void *arg ) { struct process *debugger = event->debugger->process; struct process_dll *dll = arg; obj_handle_t handle = 0; if (dll->file && !(handle = alloc_handle( debugger, dll->file, GENERIC_READ, 0 ))) return 0; event->data.info.load_dll.handle = handle; event->data.info.load_dll.base = dll->base; event->data.info.load_dll.dbg_offset = dll->dbg_offset; event->data.info.load_dll.dbg_size = dll->dbg_size; event->data.info.load_dll.name = dll->name; event->data.info.load_dll.unicode = 1; return 1; }
/* * Call this to do a TLS accept on a sockbuf. * Everything else is the same as with tls_connect. */ int ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg ) { int err; tls_session *ssl = NULL; if ( HAS_TLS( sb )) { ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl ); } else { ssl = alloc_handle( ctx_arg, 1 ); if ( ssl == NULL ) return -1; #ifdef LDAP_DEBUG ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" ); #endif ber_sockbuf_add_io( sb, tls_imp->ti_sbio, LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl ); } err = tls_imp->ti_session_accept( ssl ); #ifdef HAVE_WINSOCK errno = WSAGetLastError(); #endif if ( err < 0 ) { if ( update_flags( sb, ssl, err )) return 1; if ( DebugTest( LDAP_DEBUG_ANY ) ) { char buf[256], *msg; msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) ); Debug( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n", msg ? msg : "(unknown)", 0, 0 ); } ber_sockbuf_remove_io( sb, tls_imp->ti_sbio, LBER_SBIOD_LEVEL_TRANSPORT ); #ifdef LDAP_DEBUG ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_TRANSPORT ); #endif return -1; } return 0; }
/* duplicate a handle */ obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst, unsigned int access, unsigned int attr, unsigned int options ) { obj_handle_t res; struct handle_entry *entry; unsigned int src_access; struct object *obj = get_handle_obj( src, src_handle, 0, NULL ); if (!obj) return 0; if ((entry = get_handle( src, src_handle ))) src_access = entry->access; else /* pseudo-handle, give it full access */ src_access = obj->ops->map_access( obj, GENERIC_ALL ); src_access &= ~RESERVED_ALL; if (options & DUP_HANDLE_SAME_ACCESS) access = src_access; else access = obj->ops->map_access( obj, access ) & ~RESERVED_ALL; /* asking for the more access rights than src_access? */ if (access & ~src_access) { if (options & DUP_HANDLE_MAKE_GLOBAL) res = alloc_global_handle( obj, access ); else res = alloc_handle( dst, obj, access, attr ); } else { if (options & DUP_HANDLE_MAKE_GLOBAL) res = alloc_global_handle_no_access_check( obj, access ); else if ((options & DUP_HANDLE_CLOSE_SOURCE) && src == dst && entry && !(entry->access & RESERVED_CLOSE_PROTECT)) { if (attr & OBJ_INHERIT) access |= RESERVED_INHERIT; entry->access = access; res = src_handle; } else res = alloc_handle_entry( dst, obj, access, attr ); } release_object( obj ); return res; }
/* queue an irp to the device */ static obj_handle_t queue_irp( struct device_file *file, struct irp_call *irp, const async_data_t *async_data, int blocking ) { obj_handle_t handle = 0; if (blocking && !(handle = alloc_handle( current->process, irp, SYNCHRONIZE, 0 ))) return 0; if (!(irp->async = fd_queue_async( file->fd, async_data, ASYNC_TYPE_WAIT ))) { if (handle) close_handle( current->process, handle ); return 0; } irp->user_arg = async_data->arg; add_irp_to_queue( file, irp, current ); set_error( STATUS_PENDING ); return handle; }
/* create * create a regular file and set its attributes */ fsal_status_t create(struct fsal_obj_handle *dir_hdl, const char *name, struct attrlist *attr_in, struct fsal_obj_handle **handle, struct attrlist *attrs_out) { struct gpfs_fsal_obj_handle *hdl; fsal_status_t status; /* Use a separate attrlist to getch the actual attributes into */ struct attrlist attrib; struct gpfs_file_handle *fh = alloca(sizeof(struct gpfs_file_handle)); *handle = NULL; /* poison it */ 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_create(dir_hdl, name, 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, NULL, 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; return fsalstat(ERR_FSAL_NO_ERROR, 0); }
/****************************************************************************** * copy_handle * * Copies a handle. Increments the reference count of the object referenced * by the handle. * * PARAMS * lpTable [I] Pointer to the handle table, which holds the handle to be copied. * handle [I] The handle to be copied. * copy [O] Pointer to a handle variable, where the copied handle is put. * * RETURNS * non zero, if successful * zero, if not successful (invalid handle or out of memory) */ int copy_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy) { OBJECTHDR *pObject; int ret; TRACE("(lpTable=%p, handle=%ld, copy=%p)\n", lpTable, handle, copy); EnterCriticalSection(&lpTable->mutex); if (!lookup_handle(lpTable, handle, dwType, &pObject)) { *copy = (HCRYPTKEY)INVALID_HANDLE_VALUE; LeaveCriticalSection(&lpTable->mutex); return 0; } ret = alloc_handle(lpTable, pObject, copy); LeaveCriticalSection(&lpTable->mutex); return ret; }
/****************************************************************************** * copy_handle * * Copies a handle. Increments the reference count of the object referenced * by the handle. * * PARAMS * lpTable [I] Pointer to the handle table, which holds the handle to be copied. * handle [I] The handle to be copied. * copy [O] Pointer to a handle variable, where the copied handle is put. * * RETURNS * non zero, if successful * zero, if not successful (invalid handle or out of memory) */ int copy_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, unsigned int *copy) { OBJECTHDR *pObject; int ret; TRACE("(lpTable=%p, handle=%d, copy=%p)\n", lpTable, handle, copy); EnterCriticalSection(&lpTable->mutex); if (!lookup_handle(lpTable, handle, dwType, &pObject)) { *copy = (unsigned int)INVALID_HANDLE_VALUE; LeaveCriticalSection(&lpTable->mutex); return 0; } ret = alloc_handle(lpTable, pObject, copy); LeaveCriticalSection(&lpTable->mutex); return ret; }
int sqlcli( int aArg1 ) { SQLRETURN rc; SQLHENV env; // Environment Handle SQLHDBC dbc; // Connection Handle int conn_flag; env = SQL_NULL_HENV; dbc = SQL_NULL_HDBC; conn_flag = 0; /* allocate handle */ rc = alloc_handle(env, dbc); if ( rc != SQL_SUCCESS ) { free_handle(env, dbc, conn_flag); exit(1); } /* Connect to Altibase Server */ rc = db_connect(dbc, conn_flag); if ( rc != SQL_SUCCESS ) { free_handle(env, dbc, conn_flag); exit(1); } /* select data */ rc = execute_select(dbc); if ( rc != SQL_SUCCESS ) { free_handle(env, dbc, conn_flag); exit(1); } /* disconnect, free handles */ free_handle(env, dbc, conn_flag); }
static fsal_status_t pt_lookup(struct fsal_obj_handle *parent, const char *path, struct fsal_obj_handle **handle) { fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval = 0; fsal_status_t status; struct pt_fsal_obj_handle *hdl; struct attrlist attrib; ptfsal_handle_t *fh = alloca(sizeof(ptfsal_handle_t)); *handle = NULL; /* poison it first */ if (!path) return fsalstat(ERR_FSAL_FAULT, 0); memset(fh, 0, sizeof(ptfsal_handle_t)); fh->data.handle.handle_size = FSI_CCL_PERSISTENT_HANDLE_N_BYTES; if (!parent->ops->handle_is(parent, DIRECTORY)) { LogCrit(COMPONENT_FSAL, "Parent handle is not a directory. hdl = 0x%p", parent); return fsalstat(ERR_FSAL_NOTDIR, 0); } attrib.mask = parent->attributes.mask; status = PTFSAL_lookup(op_ctx, parent, path, &attrib, fh); if (FSAL_IS_ERROR(status)) return status; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, &attrib, NULL, NULL, NULL, op_ctx->fsal_export); if (hdl == NULL) { retval = ENOMEM; goto hdlerr; } *handle = &hdl->obj_handle; return fsalstat(ERR_FSAL_NO_ERROR, 0); hdlerr: fsal_error = posix2fsal_error(retval); return fsalstat(fsal_error, retval); }
static inline int make_file_safe(struct vfs_fsal_obj_handle *dir_hdl, const struct req_op_context *opctx, int dir_fd, const char *name, mode_t unix_mode, uid_t user, gid_t group, struct vfs_fsal_obj_handle **hdl) { int retval; struct stat stat; vfs_file_handle_t *fh; vfs_alloc_handle(fh); retval = fchownat(dir_fd, name, user, group, AT_SYMLINK_NOFOLLOW); if (retval < 0) goto fileerr; /* now that it is owned properly, set accessible mode */ retval = fchmodat(dir_fd, name, unix_mode, 0); if (retval < 0) goto fileerr; retval = vfs_name_to_handle(dir_fd, dir_hdl->obj_handle.fs, name, fh); if (retval < 0) goto fileerr; retval = fstatat(dir_fd, name, &stat, AT_SYMLINK_NOFOLLOW); if (retval < 0) goto fileerr; /* allocate an obj_handle and fill it up */ *hdl = alloc_handle(dir_fd, fh, dir_hdl->obj_handle.fs, &stat, dir_hdl->handle, name, opctx->fsal_export); if (*hdl == NULL) return ENOMEM; return 0; fileerr: retval = errno; return retval; }
static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, int blocking, const void *data, data_size_t size ) { struct device *device = get_fd_user( fd ); struct ioctl_call *ioctl; obj_handle_t handle; if (!device->manager) /* it has been deleted */ { set_error( STATUS_FILE_DELETED ); return 0; } if (!(ioctl = create_ioctl( device, code, data, size, get_reply_max_size() ))) return 0; ioctl->thread = (struct thread *)grab_object( current ); ioctl->user_arg = async_data->arg; if (!(handle = alloc_handle( current->process, ioctl, SYNCHRONIZE, 0 ))) { release_object( ioctl ); return 0; } if (!(ioctl->async = fd_queue_async( device->fd, async_data, ASYNC_TYPE_WAIT ))) { close_handle( current->process, handle ); release_object( ioctl ); return 0; } list_add_tail( &device->requests, &ioctl->dev_entry ); list_add_tail( &device->manager->requests, &ioctl->mgr_entry ); if (list_head( &device->manager->requests ) == &ioctl->mgr_entry) /* first one */ wake_up( &device->manager->obj, 0 ); /* don't release ioctl since it is now queued in the device */ set_error( STATUS_PENDING ); return handle; }
/* open a new handle to an existing object */ obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned int access, const struct object_ops *ops, const struct unicode_str *name, unsigned int attributes ) { obj_handle_t handle = 0; struct directory *root = NULL; struct object *obj; if (name->len >= 65534) { set_error( STATUS_OBJECT_NAME_INVALID ); return 0; } if (parent && !(root = get_directory_obj( process, parent, 0 ))) return 0; if ((obj = open_object_dir( root, name, attributes, ops ))) { handle = alloc_handle( process, obj, access, attributes ); release_object( obj ); } if (root) release_object( root ); return handle; }
fsal_status_t vfs_open2(struct fsal_obj_handle *obj_hdl, struct state_t *state, fsal_openflags_t openflags, enum fsal_create_mode createmode, const char *name, struct attrlist *attrib_set, fsal_verifier_t verifier, struct fsal_obj_handle **new_obj, struct attrlist *attrs_out, bool *caller_perm_check) { int posix_flags = 0; int fd, dir_fd; int retval = 0; mode_t unix_mode; fsal_status_t status = {0, 0}; struct vfs_fd *my_fd = NULL; struct vfs_fsal_obj_handle *myself, *hdl = NULL; struct stat stat; vfs_file_handle_t *fh = NULL; bool truncated; bool created = false; if (state != NULL) my_fd = (struct vfs_fd *)(state + 1); myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle); LogAttrlist(COMPONENT_FSAL, NIV_FULL_DEBUG, "attrib_set ", attrib_set, false); fsal2posix_openflags(openflags, &posix_flags); truncated = (posix_flags & O_TRUNC) != 0; LogFullDebug(COMPONENT_FSAL, truncated ? "Truncate" : "No truncate"); if (createmode >= FSAL_EXCLUSIVE) { /* Now fixup attrs for verifier if exclusive create */ set_common_verifier(attrib_set, verifier); } if (name == NULL) { /* This is an open by handle */ struct vfs_fsal_obj_handle *myself; myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle); if (obj_hdl->fsal != obj_hdl->fs->fsal) { LogDebug(COMPONENT_FSAL, "FSAL %s operation for handle belonging to FSAL %s, return EXDEV", obj_hdl->fsal->name, obj_hdl->fs->fsal->name); return fsalstat(posix2fsal_error(EXDEV), EXDEV); } if (state != NULL) { /* Prepare to take the share reservation, but only if we * are called with a valid state (if state is NULL the * caller is a stateless create such as NFS v3 CREATE). */ /* This can block over an I/O operation. */ PTHREAD_RWLOCK_wrlock(&obj_hdl->lock); /* Check share reservation conflicts. */ status = check_share_conflict(&myself->u.file.share, openflags, false); if (FSAL_IS_ERROR(status)) { PTHREAD_RWLOCK_unlock(&obj_hdl->lock); return status; } /* Take the share reservation now by updating the * counters. */ update_share_counters(&myself->u.file.share, FSAL_O_CLOSED, openflags); PTHREAD_RWLOCK_unlock(&obj_hdl->lock); } else { /* We need to use the global fd to continue, and take * the lock to protect it. */ my_fd = &hdl->u.file.fd; PTHREAD_RWLOCK_wrlock(&obj_hdl->lock); } status = vfs_open_my_fd(myself, openflags, posix_flags, my_fd); if (FSAL_IS_ERROR(status)) { if (state == NULL) { /* Release the lock taken above, and return * since there is nothing to undo. */ PTHREAD_RWLOCK_unlock(&obj_hdl->lock); return status; } else { /* Error - need to release the share */ goto undo_share; } } if (createmode >= FSAL_EXCLUSIVE || truncated) { /* Refresh the attributes */ struct stat stat; retval = fstat(my_fd->fd, &stat); if (retval == 0) { LogFullDebug(COMPONENT_FSAL, "New size = %" PRIx64, stat.st_size); } else { if (errno == EBADF) errno = ESTALE; status = fsalstat(posix2fsal_error(errno), errno); } /* Now check verifier for exclusive, but not for * FSAL_EXCLUSIVE_9P. */ if (!FSAL_IS_ERROR(status) && createmode >= FSAL_EXCLUSIVE && createmode != FSAL_EXCLUSIVE_9P && !check_verifier_stat(&stat, verifier)) { /* Verifier didn't match, return EEXIST */ status = fsalstat(posix2fsal_error(EEXIST), EEXIST); } } if (state == NULL) { /* If no state, release the lock taken above and return * status. */ PTHREAD_RWLOCK_unlock(&obj_hdl->lock); return status; } if (!FSAL_IS_ERROR(status)) { /* Return success. */ return status; } (void) vfs_close_my_fd(my_fd); undo_share: /* Can only get here with state not NULL and an error */ /* On error we need to release our share reservation * and undo the update of the share counters. * This can block over an I/O operation. */ PTHREAD_RWLOCK_wrlock(&obj_hdl->lock); update_share_counters(&myself->u.file.share, openflags, FSAL_O_CLOSED); PTHREAD_RWLOCK_unlock(&obj_hdl->lock); return status; } /* In this path where we are opening by name, we can't check share * reservation yet since we don't have an object_handle yet. If we * indeed create the object handle (there is no race with another * open by name), then there CAN NOT be a share conflict, otherwise * the share conflict will be resolved when the object handles are * merged. */ #ifdef ENABLE_VFS_DEBUG_ACL if (createmode != FSAL_NO_CREATE) { /* Need to ammend attributes for inherited ACL, these will be * set later. We also need to test for permission to create * since there might be an ACL. */ struct attrlist attrs; fsal_accessflags_t access_type; access_type = FSAL_MODE_MASK_SET(FSAL_W_OK) | FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE); status = obj_hdl->obj_ops.test_access(obj_hdl, access_type, NULL, NULL, false); if (FSAL_IS_ERROR(status)) return status; fsal_prepare_attrs(&attrs, ATTR_ACL); status = obj_hdl->obj_ops.getattrs(obj_hdl, &attrs); if (FSAL_IS_ERROR(status)) return status; status.major = fsal_inherit_acls(attrib_set, attrs.acl, FSAL_ACE_FLAG_FILE_INHERIT); /* Done with the attrs */ fsal_release_attrs(&attrs); if (FSAL_IS_ERROR(status)) return status; } #endif /* ENABLE_VFS_DEBUG_ACL */ if (createmode != FSAL_NO_CREATE) { /* Now add in O_CREAT and O_EXCL. */ posix_flags |= O_CREAT; /* And if we are at least FSAL_GUARDED, do an O_EXCL create. */ if (createmode >= FSAL_GUARDED) posix_flags |= O_EXCL; /* Fetch the mode attribute to use in the openat system call. */ unix_mode = fsal2unix_mode(attrib_set->mode) & ~op_ctx->fsal_export->exp_ops.fs_umask(op_ctx->fsal_export); /* Don't set the mode if we later set the attributes */ FSAL_UNSET_MASK(attrib_set->mask, ATTR_MODE); } if (createmode == FSAL_UNCHECKED && (attrib_set->mask != 0)) { /* If we have FSAL_UNCHECKED and want to set more attributes * than the mode, we attempt an O_EXCL create first, if that * succeeds, then we will be allowed to set the additional * attributes, otherwise, we don't know we created the file * and this can NOT set the attributes. */ posix_flags |= O_EXCL; } dir_fd = vfs_fsal_open(myself, O_PATH | O_NOACCESS, &status.major); if (dir_fd < 0) return fsalstat(status.major, -dir_fd); /** @todo: not sure what this accomplishes... */ retval = vfs_stat_by_handle(dir_fd, &stat); if (retval < 0) { retval = errno; status = fsalstat(posix2fsal_error(retval), retval); goto direrr; } /* Become the user because we are creating an object in this dir. */ if (createmode != FSAL_NO_CREATE) fsal_set_credentials(op_ctx->creds); if ((posix_flags & O_CREAT) != 0) fd = openat(dir_fd, name, posix_flags, unix_mode); else fd = openat(dir_fd, name, posix_flags); if (fd == -1 && errno == EEXIST && createmode == FSAL_UNCHECKED) { /* We tried to create O_EXCL to set attributes and failed. * Remove O_EXCL and retry. We still try O_CREAT again just in * case file disappears out from under us. * * Note that because we have dropped O_EXCL, later on we will * not assume we created the file, and thus will not set * additional attributes. We don't need to separately track * the condition of not wanting to set attributes. */ posix_flags &= ~O_EXCL; fd = openat(dir_fd, name, posix_flags, unix_mode); } /* Preserve errno */ retval = errno; /* If we were creating, restore credentials now. */ if (createmode != FSAL_NO_CREATE) fsal_restore_ganesha_credentials(); if (fd < 0) { status = fsalstat(posix2fsal_error(retval), retval); goto direrr; } /* Remember if we were responsible for creating the file. * Note that in an UNCHECKED retry we MIGHT have re-created the * file and won't remember that. Oh well, so in that rare case we * leak a partially created file if we have a subsequent error in here. * Also notify caller to do permission check if we DID NOT create the * file. Note it IS possible in the case of a race between an UNCHECKED * open and an external unlink, we did create the file, but we will * still force a permission check. Of course that permission check * SHOULD succeed since we also won't set the mode the caller requested * and the default file create permissions SHOULD allow the owner * read/write. */ created = (posix_flags & O_EXCL) != 0; *caller_perm_check = !created; vfs_alloc_handle(fh); retval = vfs_name_to_handle(dir_fd, obj_hdl->fs, name, fh); if (retval < 0) { retval = errno; status = fsalstat(posix2fsal_error(retval), retval); goto fileerr; } retval = fstat(fd, &stat); if (retval < 0) { retval = errno; status = fsalstat(posix2fsal_error(retval), retval); goto fileerr; } /* allocate an obj_handle and fill it up */ hdl = alloc_handle(dir_fd, fh, obj_hdl->fs, &stat, myself->handle, name, op_ctx->fsal_export); if (hdl == NULL) { status = fsalstat(posix2fsal_error(ENOMEM), ENOMEM); goto fileerr; } /* If we didn't have a state above, use the global fd. At this point, * since we just created the global fd, no one else can have a * reference to it, and thus we can mamnipulate unlocked which is * handy since we can then call setattr2 which WILL take the lock * without a double locking deadlock. */ if (my_fd == NULL) my_fd = &hdl->u.file.fd; my_fd->fd = fd; my_fd->openflags = openflags; *new_obj = &hdl->obj_handle; if (created && attrib_set->mask != 0) { /* Set attributes using our newly opened file descriptor as the * share_fd if there are any left to set (mode and truncate * have already been handled). * * Note that we only set the attributes if we were responsible * for creating the file and we have attributes to set. * * Note if we have ENABLE_VFS_DEBUG_ACL an inherited ACL might * be part of the attributes we are setting here. */ status = (*new_obj)->obj_ops.setattr2(*new_obj, false, state, attrib_set); if (FSAL_IS_ERROR(status)) { /* Release the handle we just allocated. */ (*new_obj)->obj_ops.release(*new_obj); *new_obj = NULL; goto fileerr; } if (attrs_out != NULL) { status = (*new_obj)->obj_ops.getattrs(*new_obj, attrs_out); if (FSAL_IS_ERROR(status) && (attrs_out->mask & ATTR_RDATTR_ERR) == 0) { /* Get attributes failed and caller expected * to get the attributes. Otherwise continue * with attrs_out indicating ATTR_RDATTR_ERR. */ goto fileerr; } } } else if (attrs_out != NULL) { /* Since we haven't set any attributes other than what was set * on create (if we even created), just use the stat results * we used to create the fsal_obj_handle. */ posix2fsal_attributes(&stat, attrs_out); /* Make sure ATTR_RDATTR_ERR is cleared on success. */ attrs_out->mask &= ~ATTR_RDATTR_ERR; } close(dir_fd); if (state != NULL) { /* Prepare to take the share reservation, but only if we are * called with a valid state (if state is NULL the caller is * a stateless create such as NFS v3 CREATE). */ /* This can block over an I/O operation. */ PTHREAD_RWLOCK_wrlock(&(*new_obj)->lock); /* Take the share reservation now by updating the counters. */ update_share_counters(&hdl->u.file.share, FSAL_O_CLOSED, openflags); PTHREAD_RWLOCK_unlock(&(*new_obj)->lock); } return fsalstat(ERR_FSAL_NO_ERROR, 0); fileerr: close(fd); /* Delete the file if we actually created it. */ if (created) unlinkat(dir_fd, name, 0); direrr: close(dir_fd); return fsalstat(posix2fsal_error(retval), retval); }
static fsal_status_t lookup(struct fsal_obj_handle *parent, const char *path, struct fsal_obj_handle **handle) { struct vfs_fsal_obj_handle *parent_hdl, *hdl; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval, dirfd; struct stat stat; vfs_file_handle_t *fh = NULL; vfs_alloc_handle(fh); fsal_dev_t dev; struct fsal_filesystem *fs; bool xfsal = false; *handle = NULL; /* poison it first */ parent_hdl = container_of(parent, struct vfs_fsal_obj_handle, obj_handle); if (!parent->obj_ops.handle_is(parent, DIRECTORY)) { LogCrit(COMPONENT_FSAL, "Parent handle is not a directory. hdl = 0x%p", parent); return fsalstat(ERR_FSAL_NOTDIR, 0); } if (parent->fsal != parent->fs->fsal) { LogDebug(COMPONENT_FSAL, "FSAL %s operation for handle belonging to FSAL %s, return EXDEV", parent->fsal->name, parent->fs->fsal != NULL ? parent->fs->fsal->name : "(none)"); retval = EXDEV; goto hdlerr; } fs = parent->fs; dirfd = vfs_fsal_open(parent_hdl, O_PATH | O_NOACCESS, &fsal_error); if (dirfd < 0) return fsalstat(fsal_error, -dirfd); retval = fstatat(dirfd, path, &stat, AT_SYMLINK_NOFOLLOW); if (retval < 0) { retval = errno; goto direrr; } dev = posix2fsal_devt(stat.st_dev); if ((dev.minor != parent_hdl->dev.minor) || (dev.major != parent_hdl->dev.major)) { /* XDEV */ fs = lookup_dev(&dev); if (fs == NULL) { LogDebug(COMPONENT_FSAL, "Lookup of %s crosses filesystem boundary to " "unknown file system dev=%"PRIu64".%"PRIu64, path, dev.major, dev.minor); retval = EXDEV; goto direrr; } if (fs->fsal != parent->fsal) { xfsal = true; LogDebug(COMPONENT_FSAL, "Lookup of %s crosses filesystem boundary to file system %s into FSAL %s", path, fs->path, fs->fsal != NULL ? fs->fsal->name : "(none)"); } else { LogDebug(COMPONENT_FSAL, "Lookup of %s crosses filesystem boundary to file system %s", path, fs->path); } } if (xfsal || vfs_name_to_handle(dirfd, fs, path, fh) < 0) { retval = errno; if (((retval == ENOTTY) || (retval == EOPNOTSUPP) || (retval == ENOTSUP) || xfsal) && (fs != parent->fs)) { /* Crossed device into territory not handled by * this FSAL (XFS or VFS). Need to invent a handle. * The made up handle will be JUST the fsid, we * do not expect to see the handle on the wire, and * this handle will not be valid for any form of this * FSAL. */ LogDebug(COMPONENT_FSAL, "vfs_name_to_handle %s, inventing FSAL %s handle for FSAL %s filesystem %s", xfsal ? "skipped" : "failed", parent->fsal->name, fs->fsal != NULL ? fs->fsal->name : "(none)", path); retval = vfs_encode_dummy_handle(fh, fs); if (retval < 0) { retval = errno; goto direrr; } retval = 0; } else { /* Some other error */ goto direrr; } } /* allocate an obj_handle and fill it up */ hdl = alloc_handle(dirfd, fh, fs, &stat, parent_hdl->handle, path, op_ctx->fsal_export); close(dirfd); if (hdl == NULL) { retval = ENOMEM; goto hdlerr; } *handle = &hdl->obj_handle; return fsalstat(ERR_FSAL_NO_ERROR, 0); direrr: close(dirfd); hdlerr: fsal_error = posix2fsal_error(retval); return fsalstat(fsal_error, retval); }
fsal_status_t vfs_create_handle(struct fsal_export *exp_hdl, struct gsh_buffdesc *hdl_desc, struct fsal_obj_handle **handle) { fsal_status_t status; struct vfs_fsal_obj_handle *hdl; struct stat obj_stat; vfs_file_handle_t *fh = NULL; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval = 0; int fd; int flags = O_PATH | O_NOACCESS | O_NOFOLLOW; struct fsal_filesystem *fs; bool dummy; vfs_alloc_handle(fh); *handle = NULL; /* poison it first */ status = vfs_check_handle(exp_hdl, hdl_desc, &fs, fh, &dummy); if (FSAL_IS_ERROR(status)) return status; if (dummy) { /* We don't need fd here, just stat the fs->path */ fd = -1; retval = stat(fs->path, &obj_stat); } else { fd = vfs_open_by_handle(fs->private, fh, flags, &fsal_error); if (fd < 0) { retval = -fd; goto errout; } retval = vfs_stat_by_handle(fd, fh, &obj_stat, flags); } /* Test the result of stat */ if (retval != 0) { retval = errno; LogDebug(COMPONENT_FSAL, "%s failed with %s", dummy ? "stat" : "vfs_stat_by_handle", strerror(retval)); fsal_error = posix2fsal_error(retval); if (fd >= 0) close(fd); goto errout; } hdl = alloc_handle(fd, fh, fs, &obj_stat, NULL, "", exp_hdl); if (fd >= 0) close(fd); if (hdl == NULL) { LogDebug(COMPONENT_FSAL, "Could not allocate handle"); fsal_error = ERR_FSAL_NOMEM; goto errout; } *handle = &hdl->obj_handle; errout: return fsalstat(fsal_error, retval); }
static fsal_status_t makedir(struct fsal_obj_handle *dir_hdl, const char *name, struct attrlist *attrib, struct fsal_obj_handle **handle) { struct vfs_fsal_obj_handle *myself, *hdl; int dir_fd; struct stat stat; mode_t unix_mode; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval = 0; int flags = O_PATH | O_NOACCESS; vfs_file_handle_t *fh = NULL; vfs_alloc_handle(fh); LogDebug(COMPONENT_FSAL, "create %s", name); *handle = NULL; /* poison it */ 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); } myself = container_of(dir_hdl, struct vfs_fsal_obj_handle, obj_handle); if (dir_hdl->fsal != dir_hdl->fs->fsal) { LogDebug(COMPONENT_FSAL, "FSAL %s operation for handle belonging to FSAL %s, return EXDEV", dir_hdl->fsal->name, dir_hdl->fs->fsal != NULL ? dir_hdl->fs->fsal->name : "(none)"); retval = EXDEV; goto hdlerr; } unix_mode = fsal2unix_mode(attrib->mode) & ~op_ctx->fsal_export->exp_ops.fs_umask(op_ctx->fsal_export); dir_fd = vfs_fsal_open(myself, flags, &fsal_error); if (dir_fd < 0) return fsalstat(fsal_error, -dir_fd); retval = vfs_stat_by_handle(dir_fd, myself->handle, &stat, flags); if (retval < 0) { retval = errno; goto direrr; } /* Become the user because we are creating an object in this dir. */ fsal_set_credentials(op_ctx->creds); retval = mkdirat(dir_fd, name, unix_mode); if (retval < 0) { retval = errno; fsal_restore_ganesha_credentials(); goto direrr; } fsal_restore_ganesha_credentials(); retval = vfs_name_to_handle(dir_fd, dir_hdl->fs, name, fh); if (retval < 0) { retval = errno; goto fileerr; } retval = fstatat(dir_fd, name, &stat, AT_SYMLINK_NOFOLLOW); if (retval < 0) { retval = errno; goto fileerr; } /* allocate an obj_handle and fill it up */ hdl = alloc_handle(dir_fd, fh, dir_hdl->fs, &stat, myself->handle, name, op_ctx->fsal_export); if (hdl == NULL) { retval = ENOMEM; goto fileerr; } *handle = &hdl->obj_handle; close(dir_fd); return fsalstat(ERR_FSAL_NO_ERROR, 0); fileerr: unlinkat(dir_fd, name, 0); direrr: close(dir_fd); hdlerr: fsal_error = posix2fsal_error(retval); return fsalstat(fsal_error, retval); }
static int ldap_int_tls_connect( LDAP *ld, LDAPConn *conn ) { Sockbuf *sb = conn->lconn_sb; int err; tls_session *ssl = NULL; if ( HAS_TLS( sb )) { ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl ); } else { struct ldapoptions *lo; tls_ctx *ctx; ctx = ld->ld_options.ldo_tls_ctx; ssl = alloc_handle( ctx, 0 ); if ( ssl == NULL ) return -1; #ifdef LDAP_DEBUG ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" ); #endif ber_sockbuf_add_io( sb, tls_imp->ti_sbio, LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl ); lo = LDAP_INT_GLOBAL_OPT(); if( ctx == NULL ) { ctx = lo->ldo_tls_ctx; ld->ld_options.ldo_tls_ctx = ctx; tls_ctx_ref( ctx ); } if ( ld->ld_options.ldo_tls_connect_cb ) ld->ld_options.ldo_tls_connect_cb( ld, ssl, ctx, ld->ld_options.ldo_tls_connect_arg ); if ( lo && lo->ldo_tls_connect_cb && lo->ldo_tls_connect_cb != ld->ld_options.ldo_tls_connect_cb ) lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg ); } err = tls_imp->ti_session_connect( ld, ssl ); #ifdef HAVE_WINSOCK errno = WSAGetLastError(); #endif if ( err < 0 ) { char buf[256], *msg; if ( update_flags( sb, ssl, err )) { return 1; } msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) ); if ( msg ) { if ( ld->ld_error ) { LDAP_FREE( ld->ld_error ); } ld->ld_error = LDAP_STRDUP( msg ); #ifdef HAVE_EBCDIC if ( ld->ld_error ) __etoa(ld->ld_error); #endif } Debug( LDAP_DEBUG_ANY,"TLS: can't connect: %s.\n", ld->ld_error ? ld->ld_error : "" ,0,0); ber_sockbuf_remove_io( sb, tls_imp->ti_sbio, LBER_SBIOD_LEVEL_TRANSPORT ); #ifdef LDAP_DEBUG ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug, LBER_SBIOD_LEVEL_TRANSPORT ); #endif return -1; } return 0; }
static fsal_status_t makesymlink(struct fsal_obj_handle *dir_hdl, const char *name, const char *link_path, struct attrlist *attrib, struct fsal_obj_handle **handle) { struct vfs_fsal_obj_handle *myself, *hdl; int dir_fd = -1; struct stat stat; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int retval = 0; int flags = O_PATH | O_NOACCESS; vfs_file_handle_t *fh = NULL; vfs_alloc_handle(fh); LogDebug(COMPONENT_FSAL, "create %s", name); *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); } myself = container_of(dir_hdl, struct vfs_fsal_obj_handle, obj_handle); if (dir_hdl->fsal != dir_hdl->fs->fsal) { LogDebug(COMPONENT_FSAL, "FSAL %s operation for handle belonging to FSAL %s, return EXDEV", dir_hdl->fsal->name, dir_hdl->fs->fsal != NULL ? dir_hdl->fs->fsal->name : "(none)"); retval = EXDEV; goto hdlerr; } dir_fd = vfs_fsal_open(myself, flags, &fsal_error); if (dir_fd < 0) return fsalstat(fsal_error, -dir_fd); flags |= O_NOFOLLOW; /* BSD needs O_NOFOLLOW for * fhopen() of symlinks */ retval = vfs_stat_by_handle(dir_fd, myself->handle, &stat, flags); if (retval < 0) { retval = errno; goto direrr; } /* Become the user because we are creating an object in this dir. */ fsal_set_credentials(op_ctx->creds); retval = symlinkat(link_path, dir_fd, name); if (retval < 0) { retval = errno; fsal_restore_ganesha_credentials(); goto direrr; } fsal_restore_ganesha_credentials(); retval = vfs_name_to_handle(dir_fd, dir_hdl->fs, name, fh); if (retval < 0) { retval = errno; goto linkerr; } /* now get attributes info, * being careful to get the link, not the target */ retval = fstatat(dir_fd, name, &stat, AT_SYMLINK_NOFOLLOW); if (retval < 0) { retval = errno; goto linkerr; } /* allocate an obj_handle and fill it up */ hdl = alloc_handle(dir_fd, fh, dir_hdl->fs, &stat, NULL, name, op_ctx->fsal_export); if (hdl == NULL) { retval = ENOMEM; goto linkerr; } *handle = &hdl->obj_handle; close(dir_fd); return fsalstat(ERR_FSAL_NO_ERROR, 0); linkerr: unlinkat(dir_fd, name, 0); direrr: close(dir_fd); hdlerr: if (retval == ENOENT) fsal_error = ERR_FSAL_STALE; else fsal_error = posix2fsal_error(retval); return fsalstat(fsal_error, retval); }
/* lookup * deprecated NULL parent && NULL path implies root handle */ static fsal_status_t lustre_lookup(struct fsal_obj_handle *parent, const char *path, struct fsal_obj_handle **handle) { struct lustre_fsal_obj_handle *parent_hdl, *hdl; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int rc; struct stat stat; char *link_content = NULL; struct lustre_file_handle *dir_hdl = NULL; const char *sock_name = NULL; ssize_t retlink; char fidpath[MAXPATHLEN]; char link_buff[PATH_MAX+1]; struct lustre_file_handle *fh = alloca(sizeof(struct lustre_file_handle)); struct fsal_filesystem *fs; *handle = NULL; /* poison it first */ fs = parent->fs; if (!path) return fsalstat(ERR_FSAL_FAULT, 0); memset(fh, 0, sizeof(struct lustre_file_handle)); parent_hdl = container_of(parent, struct lustre_fsal_obj_handle, obj_handle); if (!parent->ops->handle_is(parent, DIRECTORY)) { LogCrit(COMPONENT_FSAL, "Parent handle is not a directory. hdl = 0x%p", parent); return fsalstat(ERR_FSAL_NOTDIR, 0); } if (parent->fsal != parent->fs->fsal) { LogDebug(COMPONENT_FSAL, "FSAL %s operation for handle belonging to FSAL %s, return EXDEV", parent->fsal->name, parent->fs->fsal->name); rc = EXDEV; return fsalstat(posix2fsal_error(rc), rc); } rc = lustre_name_to_handle_at(fs->path, parent_hdl->handle, path, fh, 0); if (rc < 0) { rc = errno; fsal_error = posix2fsal_error(rc); goto errout; } lustre_handle_to_path(fs->path, fh, fidpath); rc = lstat(fidpath, &stat); if (rc < 0) { rc = errno; fsal_error = posix2fsal_error(rc); goto errout; } if (S_ISLNK(stat.st_mode)) { /* I could lazy eval this... */ retlink = readlink(fidpath, link_buff, PATH_MAX); if (retlink < 0 || retlink == PATH_MAX) { rc = errno; if (retlink == PATH_MAX) rc = ENAMETOOLONG; fsal_error = posix2fsal_error(rc); goto errout; } link_buff[retlink] = '\0'; link_content = &link_buff[0]; } else if (S_ISSOCK(stat.st_mode)) { dir_hdl = parent_hdl->handle; sock_name = path; } /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, fs, &stat, link_content, dir_hdl, sock_name, op_ctx->fsal_export); if (hdl != NULL) { *handle = &hdl->obj_handle; } else { fsal_error = ERR_FSAL_NOMEM; *handle = NULL; /* poison it */ goto errout; } return fsalstat(ERR_FSAL_NO_ERROR, 0); errout: return fsalstat(fsal_error, rc); }
static fsal_status_t lustre_makedir(struct fsal_obj_handle *dir_hdl, const char *name, struct attrlist *attrib, struct fsal_obj_handle **handle) { struct lustre_fsal_obj_handle *myself, *hdl; char dirpath[MAXPATHLEN]; char newpath[MAXPATHLEN]; struct stat stat; mode_t unix_mode; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int rc = 0; struct lustre_file_handle *fh = alloca(sizeof(struct lustre_file_handle)); *handle = NULL; /* poison it */ if (!dir_hdl->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 lustre_file_handle)); myself = container_of(dir_hdl, struct lustre_fsal_obj_handle, obj_handle); unix_mode = fsal2unix_mode(attrib->mode) & ~op_ctx->fsal_export->ops->fs_umask(op_ctx->fsal_export); lustre_handle_to_path(dir_hdl->fs->path, myself->handle, dirpath); rc = lstat(dirpath, &stat); if (rc < 0) { rc = errno; goto direrr; } /* create it with no access because we are root when we do this */ snprintf(newpath, MAXPATHLEN, "%s/%s", dirpath, name); rc = CRED_WRAP(op_ctx->creds, int, mkdir, newpath, unix_mode); if (rc < 0) { rc = errno; goto direrr; } rc = get_stat_by_handle_at(dir_hdl->fs->path, myself->handle, name, fh, &stat); if (rc < 0) goto fileerr; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, dir_hdl->fs, &stat, NULL, NULL, NULL, op_ctx->fsal_export); if (hdl != NULL) { *handle = &hdl->obj_handle; } else { fsal_error = ERR_FSAL_NOMEM; goto errout; } return fsalstat(ERR_FSAL_NO_ERROR, 0); direrr: rc = errno; fsal_error = posix2fsal_error(rc); return fsalstat(fsal_error, rc); fileerr: fsal_error = posix2fsal_error(rc); rmdir(newpath); /* remove the evidence on errors */ errout: return fsalstat(fsal_error, rc); }
static fsal_status_t lustre_makenode(struct fsal_obj_handle *dir_hdl, const char *name, object_file_type_t nodetype, /* IN */ fsal_dev_t *dev, /* IN */ struct attrlist *attrib, struct fsal_obj_handle **handle) { struct lustre_fsal_obj_handle *myself, *hdl; char dirpath[MAXPATHLEN]; char newpath[MAXPATHLEN]; struct stat stat; mode_t unix_mode; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int rc = 0; dev_t unix_dev = 0; struct lustre_file_handle *dir_fh = NULL; const char *sock_name = NULL; struct lustre_file_handle *fh = alloca(sizeof(struct lustre_file_handle)); *handle = NULL; /* poison it */ if (!dir_hdl->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 lustre_file_handle)); myself = container_of(dir_hdl, struct lustre_fsal_obj_handle, obj_handle); unix_mode = fsal2unix_mode(attrib->mode) & ~op_ctx->fsal_export->ops->fs_umask(op_ctx->fsal_export); switch (nodetype) { case BLOCK_FILE: if (!dev) { fsal_error = ERR_FSAL_FAULT; goto errout; } unix_dev = CRED_WRAP(op_ctx->creds, dev_t, makedev, dev->major, dev->minor); break; case CHARACTER_FILE: if (!dev) { fsal_error = ERR_FSAL_FAULT; goto errout; } unix_dev = CRED_WRAP(op_ctx->creds, dev_t, makedev, dev->major, dev->minor); break; case FIFO_FILE: break; case SOCKET_FILE: dir_fh = myself->handle; sock_name = name; break; default: LogMajor(COMPONENT_FSAL, "Invalid node type in FSAL_mknode: %d", nodetype); fsal_error = ERR_FSAL_INVAL; goto errout; } lustre_handle_to_path(dir_hdl->fs->path, myself->handle, dirpath); rc = lstat(dirpath, &stat); if (rc < 0) { rc = errno; goto errout; } /* create it with no access because we are root when we do this */ snprintf(newpath, MAXPATHLEN, "%s/%s", dirpath, name); rc = CRED_WRAP(op_ctx->creds, int, mknod, newpath, unix_mode, unix_dev); if (rc < 0) { rc = errno; goto direrr; } rc = get_stat_by_handle_at(dir_hdl->fs->path, myself->handle, name, fh, &stat); if (rc < 0) goto direrr; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, dir_hdl->fs, &stat, NULL, dir_fh, sock_name, op_ctx->fsal_export); if (hdl == NULL) { fsal_error = ERR_FSAL_NOMEM; goto unlinkout; } *handle = &hdl->obj_handle; return fsalstat(ERR_FSAL_NO_ERROR, 0); direrr: fsal_error = posix2fsal_error(rc); unlinkout: unlink(newpath); errout: return fsalstat(fsal_error, rc); }
static fsal_status_t lustre_makesymlink(struct fsal_obj_handle *dir_hdl, const char *name, const char *link_path, struct attrlist *attrib, struct fsal_obj_handle **handle) { struct lustre_fsal_obj_handle *myself, *hdl; char dirpath[MAXPATHLEN]; char newpath[MAXPATHLEN]; struct stat stat; fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR; int rc = 0; uid_t user; gid_t group; struct lustre_file_handle *fh = alloca(sizeof(struct lustre_file_handle)); *handle = NULL; /* poison it first */ if (!dir_hdl->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 lustre_file_handle)); myself = container_of(dir_hdl, struct lustre_fsal_obj_handle, obj_handle); user = attrib->owner; group = attrib->group; lustre_handle_to_path(dir_hdl->fs->path, myself->handle, dirpath); rc = lstat(dirpath, &stat); if (rc < 0) goto direrr; if (stat.st_mode & S_ISGID) { /*setgid bit on dir propagates dir group owner */ group = -1; } /* create it with no access because we are root when we do this */ snprintf(newpath, MAXPATHLEN, "%s/%s", dirpath, name); rc = CRED_WRAP(op_ctx->creds, int, symlink, link_path, newpath); if (rc < 0) goto direrr; /* do this all by hand because we can't use fchmodat on symlinks... */ rc = lchown(newpath, user, group); if (rc < 0) goto linkerr; rc = lustre_name_to_handle_at(dir_hdl->fs->path, myself->handle, name, fh, 0); if (rc < 0) goto linkerr; /* now get attributes info, being careful * to get the link, not the target */ rc = lstat(newpath, &stat); if (rc < 0) goto linkerr; /* allocate an obj_handle and fill it up */ hdl = alloc_handle(fh, dir_hdl->fs, &stat, link_path, NULL, NULL, op_ctx->fsal_export); if (hdl == NULL) { rc = ENOMEM; goto errout; } *handle = &hdl->obj_handle; return fsalstat(ERR_FSAL_NO_ERROR, 0); linkerr: rc = errno; unlink(newpath); goto errout; direrr: rc = errno; errout: if (rc == ENOENT) fsal_error = ERR_FSAL_STALE; else fsal_error = posix2fsal_error(rc); return fsalstat(fsal_error, rc); }
static long stm_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) #endif { struct stm_v4l2_handles *handle = file->private_data; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) unsigned int minor = iminor(inode); #else unsigned minor = iminor(file->f_dentry->d_inode); #endif int ret = 0; int type = -1,index = -1; int n; switch (cmd) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) case VIDIOC_RESERVED: //_IO ('V', 1) case VIDIOC_G_MPEGCOMP: //_IOR ('V', 6, struct v4l2_mpeg_compression) case VIDIOC_S_MPEGCOMP: //_IOW ('V', 7, struct v4l2_mpeg_compression) case VIDIOC_G_PRIORITY: //_IOR ('V', 67, enum v4l2_priority) case VIDIOC_S_PRIORITY: //_IOW ('V', 68, enum v4l2_priority) case VIDIOC_G_SLICED_VBI_CAP: //_IOR ('V', 69, struct v4l2_sliced_vbi_cap) case VIDIOC_G_MODULATOR: //_IOWR ('V', 54, struct v4l2_modulator) case VIDIOC_S_MODULATOR: //_IOW ('V', 55, struct v4l2_modulator) case VIDIOC_G_FREQUENCY: //_IOWR ('V', 56, struct v4l2_frequency) case VIDIOC_S_FREQUENCY: //_IOW ('V', 57, struct v4l2_frequency) case VIDIOC_G_TUNER: //_IOWR ('V', 29, struct v4l2_tuner) case VIDIOC_S_TUNER: //_IOW ('V', 30, struct v4l2_tuner) case VIDIOC_G_JPEGCOMP: //_IOR ('V', 61, struct v4l2_jpegcompression) case VIDIOC_S_JPEGCOMP: //_IOW ('V', 62, struct v4l2_jpegcompression) default: debug_msg("IOCTL is not implemented\n"); ret = -ENODEV;// TIMPLEMENTED; break; #endif // video ioctls case VIDIOC_QUERYCAP: //_IOR ('V', 0, struct v4l2_capability) { struct v4l2_capability *b = arg; //debug_msg("v4l2_ioctl - VIDIOC_QUERYCAP\n"); strcpy(b->driver, "stm_v4l2"); strcpy(b->card, "STMicroelectronics CE Device"); strcpy(b->bus_info,""); b->version = LINUX_VERSION_CODE; b->capabilities = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; return 0; } // audio input ioctls case VIDIOC_G_AUDIO: //_IOR ('V', 33, struct v4l2_audio) case VIDIOC_S_AUDIO: //_IOW ('V', 34, struct v4l2_audio) case VIDIOC_ENUMAUDIO: //_IOWR ('V', 65, struct v4l2_audio) { struct v4l2_audio *audio = arg; type = STM_V4L2_AUDIO_INPUT; if (audio) index = audio->index; else ret = -EINVAL; } break; // audio output ioctls case VIDIOC_ENUMAUDOUT: //_IOWR ('V', 66, struct v4l2_audioout) case VIDIOC_G_AUDOUT: //_IOR ('V', 49, struct v4l2_audioout) case VIDIOC_S_AUDOUT: //_IOW ('V', 50, struct v4l2_audioout) { struct v4l2_audio *audio = arg; type = STM_V4L2_AUDIO_OUTPUT; if (audio) index = audio->index; else ret = -EINVAL; } break; // video input ioctls case VIDIOC_ENUMINPUT: //_IOWR ('V', 26, struct v4l2_input) { struct v4l2_input *input = arg; type = STM_V4L2_VIDEO_INPUT; if (input) index = input->index; else ret = -EINVAL; } break; case VIDIOC_G_INPUT: //_IOR ('V', 38, int) case VIDIOC_S_INPUT: //_IOWR ('V', 39, int) { int *input = arg; type = STM_V4L2_VIDEO_INPUT; if (arg) index = *input; else ret = -EINVAL; } break; case VIDIOC_G_FBUF: //_IOR ('V', 10, struct v4l2_framebuffer) case VIDIOC_S_FBUF: //_IOW ('V', 11, struct v4l2_framebuffer) case VIDIOC_OVERLAY: //_IOW ('V', 14, int) type = STM_V4L2_VIDEO_INPUT; break; // these are for inputs only, read the spec... case VIDIOC_G_STD: //_IOR ('V', 23, v4l2_std_id) case VIDIOC_S_STD: //_IOW ('V', 24, v4l2_std_id) type = STM_V4L2_VIDEO_INPUT; break; // video output ioctls case VIDIOC_G_OUTPUT: //_IOR ('V', 46, int) case VIDIOC_S_OUTPUT: //_IOWR ('V', 47, int) { int *input = arg; type = STM_V4L2_VIDEO_OUTPUT; if (arg) index = *input; else ret = -EINVAL; } break; case VIDIOC_ENUMOUTPUT: //_IOWR ('V', 48, struct v4l2_output) { struct v4l2_output *output = arg; type = STM_V4L2_VIDEO_OUTPUT; if (output) index = output->index; else ret = -EINVAL; } break; case VIDIOC_G_FMT: //_IOWR ('V', 4, struct v4l2_format) case VIDIOC_S_FMT: //_IOWR ('V', 5, struct v4l2_format) case VIDIOC_TRY_FMT: //_IOWR ('V', 64, struct v4l2_format) { struct v4l2_format *format = arg; if (format) { if (format->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; // this needs to be generic, and probably a way to allocate from video or system memory // remember buffers can be allocated for input or output, for the moment we will pass to the driver case VIDIOC_REQBUFS: //_IOWR ('V', 8, struct v4l2_requestbuffers) { struct v4l2_requestbuffers *rb = arg; if (rb) { if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; case VIDIOC_QUERYBUF: //_IOWR ('V', 9, struct v4l2_buffer) case VIDIOC_QBUF: //_IOWR ('V', 15, struct v4l2_buffer) case VIDIOC_DQBUF: //_IOWR ('V', 17, struct v4l2_buffer) { struct v4l2_buffer *buffer = arg; if (buffer) { if (buffer->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; case VIDIOC_G_PARM: //_IOWR ('V', 21, struct v4l2_streamparm) case VIDIOC_S_PARM: //_IOWR ('V', 22, struct v4l2_streamparm) { struct v4l2_streamparm *param = arg; if (param) { if (param->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; case VIDIOC_CROPCAP: //_IOWR ('V', 58, struct v4l2_cropcap) { struct v4l2_cropcap *cropcap = arg; if (cropcap) { if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; case VIDIOC_G_CROP: //_IOWR ('V', 59, struct v4l2_crop) case VIDIOC_S_CROP: //_IOW ('V', 60, struct v4l2_crop) { struct v4l2_crop *crop = arg; if (crop) { // what should we do about BUF_TYPE_PRIVATE if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || crop->type == V4L2_BUF_TYPE_PRIVATE) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; // can be input or output but why not audio????? case VIDIOC_STREAMON: //_IOW ('V', 18, int) case VIDIOC_STREAMOFF: //_IOW ('V', 19, int) { int *v4ltype = arg; if (v4ltype) { if (*v4ltype == V4L2_BUF_TYPE_VIDEO_OUTPUT) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; // Driver independent // however we need to get the correct ones case VIDIOC_ENUM_FMT: //_IOWR ('V', 2, struct v4l2_fmtdesc) { struct v4l2_fmtdesc *crop = arg; if (crop) { if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) type = STM_V4L2_VIDEO_OUTPUT; else type = STM_V4L2_VIDEO_INPUT; } else ret = -EINVAL; } break; // These should be driver independent the stmvout modules does not // comply with the spec... case VIDIOC_ENUMSTD: //_IOWR ('V', 25, struct v4l2_standard) case VIDIOC_QUERYSTD: //_IOR ('V', 63, v4l2_std_id) type = STM_V4L2_VIDEO_OUTPUT; break; // control ioctls case VIDIOC_G_CTRL: //_IOWR ('V', 27, struct v4l2_control) case VIDIOC_S_CTRL: //_IOWR ('V', 28, struct v4l2_control) case VIDIOC_QUERYCTRL: //_IOWR ('V', 36, struct v4l2_queryctrl) case VIDIOC_QUERYMENU: //_IOWR ('V', 37, struct v4l2_querymenu) { // cheat a little we know id is always first one struct v4l2_control *control = arg; if (arg) index = control->id; else ret = -EINVAL; type = STM_V4L2_VIDEO_INPUT; } break; }; // Cool now we have all the information we need. // first if we got an error lets just return that if (ret) return ret; // If it is a control let's deal with that if (type==STM_V4L2_MAX_TYPES) { for (n=0;n<number_drivers;n++) if (index >= drivers[n].control_start_index[minor] && index < (drivers[n].control_start_index[minor] + drivers[n].number_controls[minor])) { struct v4l2_control *control = arg; control->id -= drivers[n].control_start_index[minor]; ret = drivers[n].ioctl(handle,&drivers[n],minor,drivers[n].type,file,cmd,arg); control->id += drivers[n].control_start_index[minor]; return ret; } return -EINVAL; } // if no handle, then we need to get one // or there would be no handle for a specified type if (!handle || (handle && type != -1 && handle->v4l2type[type].driver == NULL)) { if (!handle) handle = alloc_handle(); for (n=0;n<number_drivers;n++) { if (type == -1 || type == drivers[n].type) { ret = drivers[n].ioctl(handle,&drivers[n],minor,drivers[n].type,file,cmd,arg); if (handle->v4l2type[drivers[n].type].handle) { if (ret) printk("%s: BUG ON... can't set a handle and return an error\n",__FUNCTION__); handle->v4l2type[drivers[n].type].driver = &drivers[n]; handle->device = minor; printk("%s: Assigning handle %x to device %d\n",__FUNCTION__,(unsigned int)handle,minor); file->private_data = handle; return ret; } // Not sure if this is safe but if the driver didn't return a problem then assume // it was an enum or something that didn't need to be associated (allocated is too strong a word) if (!ret) { if (!file->private_data) memset(handle,0,sizeof(struct stm_v4l2_handles)); return ret; } } } // Nothing worked so clear the handle and go again if (!file->private_data) memset(handle,0,sizeof(struct stm_v4l2_handles)); return -ENODEV; } // Ok if type != -1 and handle[type].driver->ioctl and handle[type].handle, just call it if (type != -1) { if (handle->v4l2type[type].driver) { return handle->v4l2type[type].driver->ioctl(handle,handle->v4l2type[type].driver,minor,type,file,cmd,arg); } else { return -ENODEV; } } for (n=0;n<STM_V4L2_MAX_TYPES;n++) if (handle->v4l2type[n].driver) if (!handle->v4l2type[n].driver->ioctl(handle,handle->v4l2type[n].driver,minor,n,file,cmd,arg)) return 0; return -ENODEV; }