/* This is normally the Oops function. */ void die_if_kernel(const char *str, struct pt_regs *regs, long err) { if (user_mode(regs)) return; #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY /* * This printout might take too long and could trigger * the watchdog normally. If NICE_DOGGY is set, simply * stop the watchdog during the printout. */ stop_watchdog(); #endif oops_enter(); handle_BUG(regs); pr_err("Linux %s %s\n", utsname()->release, utsname()->version); pr_err("%s: %04lx\n", str, err & 0xffff); show_registers(regs); oops_exit(); oops_in_progress = 0; pr_err("\n"); /* Flush mtdoops. */ #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY reset_watchdog(); #endif do_exit(SIGSEGV); }
long sys_olduname(struct oldold_utsname __user * name) { long error; if (!name) return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; down_read(&uts_sem); error = __copy_to_user(&name->sysname, &utsname()->sysname, __OLD_UTS_LEN); error |= __put_user(0, name->sysname + __OLD_UTS_LEN); error |= __copy_to_user(&name->nodename, &utsname()->nodename, __OLD_UTS_LEN); error |= __put_user(0, name->nodename + __OLD_UTS_LEN); error |= __copy_to_user(&name->release, &utsname()->release, __OLD_UTS_LEN); error |= __put_user(0, name->release + __OLD_UTS_LEN); error |= __copy_to_user(&name->version, &utsname()->version, __OLD_UTS_LEN); error |= __put_user(0, name->version + __OLD_UTS_LEN); error |= __copy_to_user(&name->machine, &utsname()->machine, __OLD_UTS_LEN); error |= __put_user(0, name->machine + __OLD_UTS_LEN); up_read(&uts_sem); error = error ? -EFAULT : 0; return error; }
static int version_proc_show(struct seq_file *m, void *v) { seq_printf(m, linux_proc_banner, utsname()->sysname, utsname()->release, utsname()->version); return 0; }
static void version_set_default(void) { m_len = snprintf(m_current_version, MAX_VERSION_STRING_LENGTH, "%s version %s %s\n", utsname()->sysname, utsname()->release, utsname()->version); }
static int version_proc_show(struct seq_file *m, void *v) { #if 1 /* add to show kernel version */ seq_printf(m, "%s\n",linux_banner); seq_printf(m, "Kernel %s (%s - %s)\n",CONFIG_KERNEL_VERSION,__DATE__,__TIME__); #else seq_printf(m, linux_proc_banner, utsname()->sysname, utsname()->release, utsname()->version); #endif return 0; }
asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2) { struct sol_uname __user *v = A(buf); int err; switch (which) { case 0: /* old uname */ /* Let's cheat */ err = set_utsfield(v->sysname, "SunOS", 1, 0); down_read(&uts_sem); err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1); up_read(&uts_sem); err |= set_utsfield(v->release, "2.6", 0, 0); err |= set_utsfield(v->version, "Generic", 0, 0); err |= set_utsfield(v->machine, machine(), 0, 0); return (err ? -EFAULT : 0); case 2: /* ustat */ return -ENOSYS; case 3: /* fusers */ return -ENOSYS; default: return -ENOSYS; } }
/* * Prepare the NFS data structure and parse all options. */ static int __init root_nfs_name(char *name) { static char buf[NFS_MAXPATHLEN] __initdata; char *cp; /* Set some default values */ memset(&nfs_data, 0, sizeof(nfs_data)); nfs_port = -1; nfs_data.version = NFS_MOUNT_VERSION; nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */ nfs_data.rsize = NFS_DEF_FILE_IO_SIZE; nfs_data.wsize = NFS_DEF_FILE_IO_SIZE; nfs_data.acregmin = NFS_DEF_ACREGMIN; nfs_data.acregmax = NFS_DEF_ACREGMAX; nfs_data.acdirmin = NFS_DEF_ACDIRMIN; nfs_data.acdirmax = NFS_DEF_ACDIRMAX; strcpy(buf, NFS_ROOT); /* Process options received from the remote server */ root_nfs_parse(root_server_path, buf); /* Override them by options set on kernel command-line */ root_nfs_parse(name, buf); cp = utsname()->nodename; if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) { printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n"); return -1; } sprintf(nfs_export_path, buf, cp); return 1; }
asmlinkage long sys_gethostname(char __user *name, int len) { int i, errno; if (len < 0) return -EINVAL; down_read(&uts_sem); i = 1 + strlen(utsname()->nodename); if (i > len) i = len; errno = 0; if (copy_to_user(name, utsname()->nodename, i)) errno = -EFAULT; up_read(&uts_sem); return errno; }
/* TODO: intern string firstly */ static int kplib_arch(ktap_state_t *ks) { ktap_str_t *ts = kp_str_newz(ks, utsname()->machine); if (unlikely(!ts)) return -1; set_string(ks->top, ts); incr_top(ks); return 1; }
asmlinkage long sys_newuname(struct new_utsname __user * name) { int errno = 0; down_read(&uts_sem); if (copy_to_user(name, utsname(), sizeof *name)) errno = -EFAULT; up_read(&uts_sem); return errno; }
asmlinkage long sys_sethostname(char __user *name, int len) { int errno; char tmp[__NEW_UTS_LEN]; if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (len < 0 || len > __NEW_UTS_LEN) return -EINVAL; down_write(&uts_sem); errno = -EFAULT; if (!copy_from_user(tmp, name, len)) { memcpy(utsname()->nodename, tmp, len); utsname()->nodename[len] = 0; errno = 0; } up_write(&uts_sem); return errno; }
asmlinkage int sunos_uname(struct sunos_utsname __user *name) { int ret; down_read(&uts_sem); ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], sizeof(name->sname) - 1); ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0], sizeof(name->nname) - 1); ret |= put_user('\0', &name->nname[8]); ret |= copy_to_user(&name->rel[0], &utsname()->release[0], sizeof(name->rel) - 1); ret |= copy_to_user(&name->ver[0], &utsname()->version[0], sizeof(name->ver) - 1); ret |= copy_to_user(&name->mach[0], &utsname()->machine[0], sizeof(name->mach) - 1); up_read(&uts_sem); return (ret ? -EFAULT : 0); }
void spa_history_log_version(spa_t *spa, const char *operation) { utsname_t *u = utsname(); spa_history_log_internal(spa, operation, NULL, "pool version %llu; software version %llu/%d; uts %s %s %s %s", (u_longlong_t)spa_version(spa), SPA_VERSION, ZPL_VERSION, u->nodename, u->release, u->version, u->machine); }
asmlinkage long sys_uname(struct new_utsname __user * name) { int err; down_read(&uts_sem); err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); return err ? -EFAULT : 0; }
long sys_uname(struct old_utsname __user * name) { long err; if (!name) return -EFAULT; down_read(&uts_sem); err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; }
/* TODO: intern string firstly */ static int kplib_kernel_v(ktap_state_t *ks) { ktap_str_t *ts = kp_str_newz(ks, utsname()->release); if (unlikely(!ts)) return -1; set_string(ks->top, ts); incr_top(ks); return 1; }
/* TODO: Are these put_user calls OK? Should they pass an int? * (I copied it from sys_i386.c like this.) */ static int hpux_uname(struct hpux_utsname __user *name) { int error; if (!name) return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct hpux_utsname))) return -EFAULT; down_read(&uts_sem); error = __copy_to_user(&name->sysname, &utsname()->sysname, HPUX_UTSLEN - 1); error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1); error |= __copy_to_user(&name->nodename, &utsname()->nodename, HPUX_UTSLEN - 1); error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1); error |= __copy_to_user(&name->release, &utsname()->release, HPUX_UTSLEN - 1); error |= __put_user(0, name->release + HPUX_UTSLEN - 1); error |= __copy_to_user(&name->version, &utsname()->version, HPUX_UTSLEN - 1); error |= __put_user(0, name->version + HPUX_UTSLEN - 1); error |= __copy_to_user(&name->machine, &utsname()->machine, HPUX_UTSLEN - 1); error |= __put_user(0, name->machine + HPUX_UTSLEN - 1); up_read(&uts_sem); /* HP-UX utsname has no domainname field. */ /* TODO: Implement idnumber!!! */ #if 0 error |= __put_user(0,name->idnumber); error |= __put_user(0,name->idnumber+HPUX_SNLEN-1); #endif error = error ? -EFAULT : 0; return error; }
static int v9fs_file_getlock(struct file *filp, struct file_lock *fl) { struct p9_getlock glock; struct p9_fid *fid; int res = 0; fid = filp->private_data; BUG_ON(fid == NULL); posix_test_lock(filp, fl); /* * if we have a conflicting lock locally, no need to validate * with server */ if (fl->fl_type != F_UNLCK) return res; /* convert posix lock to p9 tgetlock args */ memset(&glock, 0, sizeof(glock)); glock.type = P9_LOCK_TYPE_UNLCK; glock.start = fl->fl_start; if (fl->fl_end == OFFSET_MAX) glock.length = 0; else glock.length = fl->fl_end - fl->fl_start + 1; glock.proc_id = fl->fl_pid; glock.client_id = utsname()->nodename; res = p9_client_getlock_dotl(fid, &glock); if (res < 0) return res; /* map 9p lock type to os lock type */ switch (glock.type) { case P9_LOCK_TYPE_RDLCK: fl->fl_type = F_RDLCK; break; case P9_LOCK_TYPE_WRLCK: fl->fl_type = F_WRLCK; break; case P9_LOCK_TYPE_UNLCK: fl->fl_type = F_UNLCK; break; } if (glock.type != P9_LOCK_TYPE_UNLCK) { fl->fl_start = glock.start; if (glock.length == 0) fl->fl_end = OFFSET_MAX; else fl->fl_end = glock.start + glock.length - 1; fl->fl_pid = glock.proc_id; } return res; }
int hpux_getdomainname(char __user *name, int len) { int nlen; int err = -EFAULT; down_read(&uts_sem); nlen = strlen(utsname()->domainname) + 1; if (nlen < len) len = nlen; if(len > __NEW_UTS_LEN) goto done; if(copy_to_user(name, utsname()->domainname, len)) goto done; err = 0; done: up_read(&uts_sem); return err; }
asmlinkage int sys_getdomainname(char __user *name, int len) { int nlen, err; if (len < 0) return -EINVAL; down_read(&uts_sem); nlen = strlen(utsname()->domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; if (!copy_to_user(name, utsname()->domainname, nlen)) err = 0; out: up_read(&uts_sem); return err; }
/* TODO: better use MAC addresses (or motherboard IDs where available). * Or, at least, some checks for MAC addresses should be recorded / added. * When the nodename is misconfigured, data might be scrambled. * MAC addresses should be more secure. * In ideal case, further checks should be added to prohibit accidental * name clashes. */ char *my_id(void) { struct new_utsname *u; if (!id) { //down_read(&uts_sem); // FIXME: this is currenty not EXPORTed from the kernel! u = utsname(); if (u) { id = brick_strdup(u->nodename); } //up_read(&uts_sem); } return id; }
int data_init(void) { /* print information and return an error */ printk("arch Size: char short int long ptr long-long " " u8 u16 u32 u64\n"); printk("%-12s %3i %3i %3i %3i %3i %3i " "%3i %3i %3i %3i\n", utsname()->machine, (int)sizeof(char), (int)sizeof(short), (int)sizeof(int), (int)sizeof(long), (int)sizeof(void *), (int)sizeof(long long), (int)sizeof(__u8), (int)sizeof(__u16), (int)sizeof(__u32), (int)sizeof(__u64)); return -ENODEV; }
asmlinkage int solaris_utsname(u32 buf) { struct sol_utsname __user *v = A(buf); int err; /* Why should we not lie a bit? */ down_read(&uts_sem); err = set_utsfield(v->sysname, "SunOS", 0, 0); err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1); err |= set_utsfield(v->release, "5.6", 0, 0); err |= set_utsfield(v->version, "Generic", 0, 0); err |= set_utsfield(v->machine, machine(), 0, 0); up_read(&uts_sem); return (err ? -EFAULT : 0); }
asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) { char *p, *q, *r; char buffer[256]; int len; /* Again, we cheat :)) */ switch (cmd) { case SI_SYSNAME: r = "SunOS"; break; case SI_HOSTNAME: r = buffer + 256; down_read(&uts_sem); for (p = utsname()->nodename, q = buffer; q < r && *p && *p != '.'; *q++ = *p++); up_read(&uts_sem); *q = 0; r = buffer; break; case SI_RELEASE: r = "5.6"; break; case SI_MACHINE: r = machine(); break; case SI_ARCHITECTURE: r = "sparc"; break; case SI_HW_PROVIDER: r = "Sun_Microsystems"; break; case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break; case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break; case SI_SRPC_DOMAIN: r = ""; break; case SI_VERSION: r = "Generic"; break; default: return -EINVAL; } len = strlen(r) + 1; if (count < len) { if (copy_to_user(A(buf), r, count - 1) || __put_user(0, (char __user *)A(buf) + count - 1)) return -EFAULT; } else { if (copy_to_user(A(buf), r, len)) return -EFAULT; } return len; }
static int data_init(void) { sys_uts = utsname(); /* print information and return an error */ printk("arch Align: char short int long ptr long-long " " u8 u16 u32 u64\n"); printk("%-12s %3i %3i %3i %3i %3i %3i " "%3i %3i %3i %3i\n", sys_uts->machine, /* note that gcc can subtract void * values, but it's not ansi */ (int)((void *)(&c.t) - (void *)&c), (int)((void *)(&s.t) - (void *)&s), (int)((void *)(&i.t) - (void *)&i), (int)((void *)(&l.t) - (void *)&l), (int)((void *)(&p.t) - (void *)&p), (int)((void *)(&ll.t) - (void *)&ll), (int)((void *)(&u1b.t) - (void *)&u1b), (int)((void *)(&u2b.t) - (void *)&u2b), (int)((void *)(&u4b.t) - (void *)&u4b), (int)((void *)(&u8b.t) - (void *)&u8b)); // return err so module is automatically unloaded return -ENODEV; }
static int __init hello_init(void) { int i; struct new_utsname *name; name = utsname(); do_gettimeofday(&tv_init); pr_alert("Version sysname %s, " "nodename %s, " "release %s, " "version %s, " "machine %s, " "domainname %s\n", name->sysname, name->nodename, name->release, name->version, name->machine, name->domainname); for (i = 0; i < howmany; i++) pr_alert("%d/%d Test %s\n", i, howmany, message); return 0; }
int init_module(void) { struct cred credstruct; struct vm_area_struct vmastruct; struct dentry dentrystruct; struct file filestruct; struct thread_info threadinfostruct; struct files_struct filesstruct; /* mind the extra 's' :-P */ struct fdtable fdtablestruct; struct vfsmount vfsmountstruct; struct task_struct *ts_p; struct cred *cs_p; struct mm_struct *mms_p; struct vm_area_struct *vma_p; struct dentry *ds_p; struct file *fs_p; struct fdtable *fdt_p; struct thread_info *ti_p; struct files_struct *fss_p; struct vfsmount *vfsmnt_p; ts_p = &init_task; cs_p = &credstruct; mms_p = init_task.mm; vma_p = &vmastruct; ds_p = &dentrystruct; fs_p = &filestruct; ti_p = &threadinfostruct; fss_p = &filesstruct; fdt_p = &fdtablestruct; vfsmnt_p = &vfsmountstruct; printk(KERN_INFO "--KERNELINFO-BEGIN--\n"); printk(KERN_INFO "name = %s %s\n", utsname()->version, utsname()->machine); printk(KERN_INFO "task.size = %zu\n", sizeof(init_task)); printk(KERN_INFO "#task.init_addr = 0x%08lX\n", (unsigned long)ts_p); printk(KERN_INFO "task.init_addr = %lu\n", (unsigned long)ts_p); PRINT_OFFSET(ti_p, task, "task"); PRINT_OFFSET(ts_p, tasks, "task"); PRINT_OFFSET(ts_p, pid, "task"); PRINT_OFFSET(ts_p, tgid, "task"); PRINT_OFFSET(ts_p, group_leader, "task"); PRINT_OFFSET(ts_p, thread_group, "task"); PRINT_OFFSET(ts_p, real_parent, "task"); PRINT_OFFSET(ts_p, parent, "task"); PRINT_OFFSET(ts_p, mm, "task"); PRINT_OFFSET(ts_p, stack, "task"); PRINT_OFFSET(ts_p, real_cred, "task"); PRINT_OFFSET(ts_p, cred, "task"); PRINT_OFFSET(ts_p, comm, "task"); printk(KERN_INFO "task.comm_size = %zu\n", sizeof(ts_p->comm)); PRINT_OFFSET(ts_p, files, "task"); PRINT_OFFSET(cs_p, uid, "cred"); PRINT_OFFSET(cs_p, gid, "cred"); PRINT_OFFSET(cs_p, euid, "cred"); PRINT_OFFSET(cs_p, egid, "cred"); PRINT_OFFSET(mms_p, mmap, "mm"); PRINT_OFFSET(mms_p, pgd, "mm"); PRINT_OFFSET(mms_p, arg_start, "mm"); PRINT_OFFSET(mms_p, start_brk, "mm"); PRINT_OFFSET(mms_p, brk, "mm"); PRINT_OFFSET(mms_p, start_stack, "mm"); PRINT_OFFSET(vma_p, vm_mm, "vma"); PRINT_OFFSET(vma_p, vm_start, "vma"); PRINT_OFFSET(vma_p, vm_end, "vma"); PRINT_OFFSET(vma_p, vm_next, "vma"); PRINT_OFFSET(vma_p, vm_flags, "vma"); /* used in reading OsiModules */ PRINT_OFFSET(vma_p, vm_file, "vma"); PRINT_OFFSET(fs_p, f_path.dentry, "fs"); PRINT_OFFSET(fs_p, f_path.mnt, "fs"); PRINT_OFFSET(fs_p, f_pos, "fs"); PRINT_OFFSET(vfsmnt_p, mnt_parent, "fs"); PRINT_OFFSET(vfsmnt_p, mnt_mountpoint, "fs"); PRINT_OFFSET(vfsmnt_p, mnt_root, "fs"); /* XXX: We don't use this anywhere. Marked for removal. */ /* used in reading FDs */ PRINT_OFFSET(fss_p, fdt, "fs"); PRINT_OFFSET(fss_p, fdtab, "fs"); PRINT_OFFSET(fdt_p, fd, "fs"); PRINT_OFFSET(ds_p, d_name, "fs"); PRINT_OFFSET(ds_p, d_iname, "fs"); PRINT_OFFSET(ds_p, d_parent, "fs"); printk(KERN_INFO "---KERNELINFO-END---\n"); /* Return a failure. We only want to print the info. */ return -1; }
/* format_corename will inspect the pattern parameter, and output a * name into corename, which must have space for at least * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. */ static int format_corename(struct core_name *cn, struct coredump_params *cprm) { const struct cred *cred = current_cred(); const char *pat_ptr = core_pattern; int ispipe = (*pat_ptr == '|'); int pid_in_pattern = 0; int err = 0; cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count); cn->corename = kmalloc(cn->size, GFP_KERNEL); cn->used = 0; if (!cn->corename) return -ENOMEM; /* Repeat as long as we have more pattern to process and more output space */ while (*pat_ptr) { if (*pat_ptr != '%') { if (*pat_ptr == 0) goto out; err = cn_printf(cn, "%c", *pat_ptr++); } else { switch (*++pat_ptr) { /* single % at the end, drop that */ case 0: goto out; /* Double percent, output one percent */ case '%': err = cn_printf(cn, "%c", '%'); break; /* pid */ case 'p': pid_in_pattern = 1; err = cn_printf(cn, "%d", task_tgid_vnr(current)); break; /* uid */ case 'u': err = cn_printf(cn, "%d", cred->uid); break; /* gid */ case 'g': err = cn_printf(cn, "%d", cred->gid); break; case 'd': err = cn_printf(cn, "%d", __get_dumpable(cprm->mm_flags)); break; /* signal that caused the coredump */ case 's': err = cn_printf(cn, "%ld", cprm->siginfo->si_signo); break; /* UNIX time of coredump */ case 't': { struct timeval tv; do_gettimeofday(&tv); err = cn_printf(cn, "%lu", tv.tv_sec); break; } /* hostname */ case 'h': { char *namestart = cn->corename + cn->used; down_read(&uts_sem); err = cn_printf(cn, "%s", utsname()->nodename); up_read(&uts_sem); cn_escape(namestart); break; } /* executable */ case 'e': { char *commstart = cn->corename + cn->used; err = cn_printf(cn, "%s", current->comm); cn_escape(commstart); break; } case 'E': err = cn_print_exe_file(cn); break; /* core limit size */ case 'c': err = cn_printf(cn, "%lu", rlimit(RLIMIT_CORE)); break; default: break; } ++pat_ptr; } if (err) return err; } /* Backward compatibility with core_uses_pid: * * If core_pattern does not include a %p (as is the default) * and core_uses_pid is set, then .%pid will be appended to * the filename. Do not do this for piped commands. */ if (!ispipe && !pid_in_pattern && core_uses_pid) { err = cn_printf(cn, ".%d", task_tgid_vnr(current)); if (err) return err; } out: return ispipe; }
/* * Generate the pool's configuration based on the current in-core state. * * We infer whether to generate a complete config or just one top-level config * based on whether vd is the root vdev. */ nvlist_t * spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) { nvlist_t *config, *nvroot; vdev_t *rvd = spa->spa_root_vdev; unsigned long hostid = 0; boolean_t locked = B_FALSE; uint64_t split_guid; char *pool_name; if (vd == NULL) { vd = rvd; locked = B_TRUE; spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER); } ASSERT(spa_config_held(spa, SCL_CONFIG | SCL_STATE, RW_READER) == (SCL_CONFIG | SCL_STATE)); /* * If txg is -1, report the current value of spa->spa_config_txg. */ if (txg == -1ULL) txg = spa->spa_config_txg; /* * Originally, users had to handle spa namespace collisions by either * exporting the already imported pool or by specifying a new name for * the pool with a conflicting name. In the case of root pools from * virtual guests, neither approach to collision resolution is * reasonable. This is addressed by extending the new name syntax with * an option to specify that the new name is temporary. When specified, * ZFS_IMPORT_TEMP_NAME will be set in spa->spa_import_flags to tell us * to use the previous name, which we do below. */ if (spa->spa_import_flags & ZFS_IMPORT_TEMP_NAME) { VERIFY0(nvlist_lookup_string(spa->spa_config, ZPOOL_CONFIG_POOL_NAME, &pool_name)); } else pool_name = spa_name(spa); VERIFY(nvlist_alloc(&config, NV_UNIQUE_NAME, KM_SLEEP) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_VERSION, spa_version(spa)) == 0); VERIFY(nvlist_add_string(config, ZPOOL_CONFIG_POOL_NAME, pool_name) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_STATE, spa_state(spa)) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_TXG, txg) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_POOL_GUID, spa_guid(spa)) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_ERRATA, spa->spa_errata) == 0); VERIFY(spa->spa_comment == NULL || nvlist_add_string(config, ZPOOL_CONFIG_COMMENT, spa->spa_comment) == 0); #ifdef _KERNEL hostid = zone_get_hostid(NULL); #else /* _KERNEL */ /* * We're emulating the system's hostid in userland, so we can't use * zone_get_hostid(). */ (void) ddi_strtoul(hw_serial, NULL, 10, &hostid); #endif /* _KERNEL */ if (hostid != 0) { VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, hostid) == 0); } VERIFY0(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, utsname()->nodename)); if (vd != rvd) { VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_TOP_GUID, vd->vdev_top->vdev_guid) == 0); VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_GUID, vd->vdev_guid) == 0); if (vd->vdev_isspare) VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_IS_SPARE, 1ULL) == 0); if (vd->vdev_islog) VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_IS_LOG, 1ULL) == 0); vd = vd->vdev_top; /* label contains top config */ } else { /* * Only add the (potentially large) split information * in the mos config, and not in the vdev labels */ if (spa->spa_config_splitting != NULL) VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_SPLIT, spa->spa_config_splitting) == 0); } /* * Add the top-level config. We even add this on pools which * don't support holes in the namespace. */ vdev_top_config_generate(spa, config); /* * If we're splitting, record the original pool's guid. */ if (spa->spa_config_splitting != NULL && nvlist_lookup_uint64(spa->spa_config_splitting, ZPOOL_CONFIG_SPLIT_GUID, &split_guid) == 0) { VERIFY(nvlist_add_uint64(config, ZPOOL_CONFIG_SPLIT_GUID, split_guid) == 0); } nvroot = vdev_config_generate(spa, vd, getstats, 0); VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0); nvlist_free(nvroot); /* * Store what's necessary for reading the MOS in the label. */ VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_FEATURES_FOR_READ, spa->spa_label_features) == 0); if (getstats && spa_load_state(spa) == SPA_LOAD_NONE) { ddt_histogram_t *ddh; ddt_stat_t *dds; ddt_object_t *ddo; ddh = kmem_zalloc(sizeof (ddt_histogram_t), KM_SLEEP); ddt_get_dedup_histogram(spa, ddh); VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_DDT_HISTOGRAM, (uint64_t *)ddh, sizeof (*ddh) / sizeof (uint64_t)) == 0); kmem_free(ddh, sizeof (ddt_histogram_t)); ddo = kmem_zalloc(sizeof (ddt_object_t), KM_SLEEP); ddt_get_dedup_object_stats(spa, ddo); VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_DDT_OBJ_STATS, (uint64_t *)ddo, sizeof (*ddo) / sizeof (uint64_t)) == 0); kmem_free(ddo, sizeof (ddt_object_t)); dds = kmem_zalloc(sizeof (ddt_stat_t), KM_SLEEP); ddt_get_dedup_stats(spa, dds); VERIFY(nvlist_add_uint64_array(config, ZPOOL_CONFIG_DDT_STATS, (uint64_t *)dds, sizeof (*dds) / sizeof (uint64_t)) == 0); kmem_free(dds, sizeof (ddt_stat_t)); } if (locked) spa_config_exit(spa, SCL_CONFIG | SCL_STATE, FTAG); return (config); }
static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) { struct p9_flock flock; struct p9_fid *fid; uint8_t status; int res = 0; unsigned char fl_type; fid = filp->private_data; BUG_ON(fid == NULL); if ((fl->fl_flags & FL_POSIX) != FL_POSIX) BUG(); res = posix_lock_file_wait(filp, fl); if (res < 0) goto out; /* convert posix lock to p9 tlock args */ memset(&flock, 0, sizeof(flock)); /* map the lock type */ switch (fl->fl_type) { case F_RDLCK: flock.type = P9_LOCK_TYPE_RDLCK; break; case F_WRLCK: flock.type = P9_LOCK_TYPE_WRLCK; break; case F_UNLCK: flock.type = P9_LOCK_TYPE_UNLCK; break; } flock.start = fl->fl_start; if (fl->fl_end == OFFSET_MAX) flock.length = 0; else flock.length = fl->fl_end - fl->fl_start + 1; flock.proc_id = fl->fl_pid; flock.client_id = utsname()->nodename; if (IS_SETLKW(cmd)) flock.flags = P9_LOCK_FLAGS_BLOCK; /* * if its a blocked request and we get P9_LOCK_BLOCKED as the status * for lock request, keep on trying */ for (;;) { res = p9_client_lock_dotl(fid, &flock, &status); if (res < 0) break; if (status != P9_LOCK_BLOCKED) break; if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd)) break; schedule_timeout_interruptible(P9_LOCK_TIMEOUT); } /* map 9p status to VFS status */ switch (status) { case P9_LOCK_SUCCESS: res = 0; break; case P9_LOCK_BLOCKED: res = -EAGAIN; break; case P9_LOCK_ERROR: case P9_LOCK_GRACE: res = -ENOLCK; break; default: BUG(); } /* * incase server returned error for lock request, revert * it locally */ if (res < 0 && fl->fl_type != F_UNLCK) { fl_type = fl->fl_type; fl->fl_type = F_UNLCK; res = posix_lock_file_wait(filp, fl); fl->fl_type = fl_type; } out: return res; }