X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Flinux%2Flinux-module.c;h=8b114d2948f1bda36227b3c531b85d71f2f95328;hb=1ab4b0239bbd75b4c05f36b8d2cf04fb371b10c2;hp=5c850870eac47b368d3ec3308539f7506de68a85;hpb=cdaeb287ec52b54aab62ff465518c9d98ee3736b;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/linux/linux-module.c b/lustre/obdclass/linux/linux-module.c index 5c85087..8b114d2 100644 --- a/lustre/obdclass/linux/linux-module.c +++ b/lustre/obdclass/linux/linux-module.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Whamcloud, Inc. + * Copyright (c) 2011, 2012, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -42,10 +42,6 @@ #define DEBUG_SUBSYSTEM S_CLASS -#ifdef __KERNEL__ -#ifndef AUTOCONF_INCLUDED -#include /* for CONFIG_PROC_FS */ -#endif #include #include #include @@ -65,39 +61,32 @@ #include #include #include -#include #include #include #include -#include #include -#else -# include -#endif #include #include #include #include #include +#include #include #include -#ifdef __KERNEL__ int proc_version; /* buffer MUST be at least the size of obd_ioctl_hdr */ -int obd_ioctl_getdata(char **buf, int *len, void *arg) +int obd_ioctl_getdata(char **buf, int *len, void __user *arg) { - struct obd_ioctl_hdr hdr; - struct obd_ioctl_data *data; - int err; - int offset = 0; - ENTRY; + struct obd_ioctl_hdr hdr; + struct obd_ioctl_data *data; + int offset = 0; + ENTRY; - err = cfs_copy_from_user(&hdr, (void *)arg, sizeof(hdr)); - if ( err ) - RETURN(err); + if (copy_from_user(&hdr, arg, sizeof(hdr))) + RETURN(-EFAULT); if (hdr.ioc_version != OBD_IOCTL_VERSION) { CERROR("Version mismatch kernel (%x) vs application (%x)\n", @@ -129,11 +118,10 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg) *len = hdr.ioc_len; data = (struct obd_ioctl_data *)*buf; - err = cfs_copy_from_user(*buf, (void *)arg, hdr.ioc_len); - if ( err ) { - OBD_FREE_LARGE(*buf, hdr.ioc_len); - RETURN(err); - } + if (copy_from_user(*buf, arg, hdr.ioc_len)) { + OBD_FREE_LARGE(*buf, hdr.ioc_len); + RETURN(-EFAULT); + } if (obd_ioctl_is_invalid(data)) { CERROR("ioctl not correctly formatted\n"); @@ -156,43 +144,39 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg) offset += cfs_size_round(data->ioc_inllen3); } - if (data->ioc_inllen4) { - data->ioc_inlbuf4 = &data->ioc_bulk[0] + offset; - } + if (data->ioc_inllen4) + data->ioc_inlbuf4 = &data->ioc_bulk[0] + offset; - EXIT; - return 0; + RETURN(0); } +EXPORT_SYMBOL(obd_ioctl_getdata); -int obd_ioctl_popdata(void *arg, void *data, int len) +int obd_ioctl_popdata(void __user *arg, void *data, int len) { - int err; + int err; + ENTRY; - err = cfs_copy_to_user(arg, data, len); - if (err) - err = -EFAULT; - return err; + err = copy_to_user(arg, data, len) ? -EFAULT : 0; + RETURN(err); } - -EXPORT_SYMBOL(obd_ioctl_getdata); EXPORT_SYMBOL(obd_ioctl_popdata); /* opening /dev/obd */ static int obd_class_open(struct inode * inode, struct file * file) { - ENTRY; + ENTRY; - PORTAL_MODULE_USE; - RETURN(0); + try_module_get(THIS_MODULE); + RETURN(0); } /* closing /dev/obd */ static int obd_class_release(struct inode * inode, struct file * file) { - ENTRY; + ENTRY; - PORTAL_MODULE_UNUSE; - RETURN(0); + module_put(THIS_MODULE); + RETURN(0); } /* to control /dev/obd */ @@ -222,127 +206,128 @@ static struct file_operations obd_psdev_fops = { }; /* modules setup */ -cfs_psdev_t obd_psdev = { +struct miscdevice obd_psdev = { .minor = OBD_DEV_MINOR, .name = OBD_DEV_NAME, .fops = &obd_psdev_fops, }; -#endif #ifdef LPROCFS -int obd_proc_read_version(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int obd_proc_version_seq_show(struct seq_file *m, void *v) { - *eof = 1; - return snprintf(page, count, "lustre: %s\nkernel: %s\nbuild: %s\n", - LUSTRE_VERSION_STRING, "patchless_client", - BUILD_VERSION); + return seq_printf(m, "lustre: %s\nkernel: %s\nbuild: %s\n", + LUSTRE_VERSION_STRING, "patchless_client", + BUILD_VERSION); } +LPROC_SEQ_FOPS_RO(obd_proc_version); -int obd_proc_read_pinger(char *page, char **start, off_t off, int count, - int *eof, void *data) +static int obd_proc_pinger_seq_show(struct seq_file *m, void *v) { - *eof = 1; - return snprintf(page, count, "%s\n", + return seq_printf(m, "%s\n", #ifdef ENABLE_PINGER - "on" + "on" #else - "off" + "off" #endif - ); + ); } +LPROC_SEQ_FOPS_RO(obd_proc_pinger); /** * Check all obd devices health * - * \param page - * \param start - * \param off - * \param count - * \param eof - * \param data - * proc read function parameters, please refer to kernel - * code fs/proc/generic.c proc_file_read() + * \param seq_file * \param data [in] unused * - * \retval number of characters printed + * \retval number of characters printed if healthy */ -static int obd_proc_read_health(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int obd_proc_health_seq_show(struct seq_file *m, void *data) { - int rc = 0, i; - *eof = 1; - - if (libcfs_catastrophe) - rc += snprintf(page + rc, count - rc, "LBUG\n"); - - cfs_read_lock(&obd_dev_lock); - for (i = 0; i < class_devno_max(); i++) { - struct obd_device *obd; - - obd = class_num2obd(i); - if (obd == NULL || !obd->obd_attached || !obd->obd_set_up) - continue; - - LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC); - if (obd->obd_stopping) - continue; - - class_incref(obd, __FUNCTION__, cfs_current()); - cfs_read_unlock(&obd_dev_lock); - - if (obd_health_check(NULL, obd)) { - rc += snprintf(page + rc, count - rc, - "device %s reported unhealthy\n", - obd->obd_name); - } - class_decref(obd, __FUNCTION__, cfs_current()); - cfs_read_lock(&obd_dev_lock); - } - cfs_read_unlock(&obd_dev_lock); - - if (rc == 0) - return snprintf(page, count, "healthy\n"); - - rc += snprintf(page + rc, count - rc, "NOT HEALTHY\n"); - return rc; + bool healthy = true; + int i; + + if (libcfs_catastrophe) + seq_printf(m, "LBUG\n"); + + read_lock(&obd_dev_lock); + for (i = 0; i < class_devno_max(); i++) { + struct obd_device *obd; + + obd = class_num2obd(i); + if (obd == NULL || !obd->obd_attached || !obd->obd_set_up) + continue; + + LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC); + if (obd->obd_stopping) + continue; + + class_incref(obd, __FUNCTION__, current); + read_unlock(&obd_dev_lock); + + if (obd_health_check(NULL, obd)) { + seq_printf(m, "device %s reported unhealthy\n", + obd->obd_name); + healthy = false; + } + class_decref(obd, __FUNCTION__, current); + read_lock(&obd_dev_lock); + } + read_unlock(&obd_dev_lock); + + if (healthy) + return seq_printf(m, "healthy\n"); + + seq_printf(m, "NOT HEALTHY\n"); + return 0; } +LPROC_SEQ_FOPS_RO(obd_proc_health); -static int obd_proc_rd_jobid_var(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int obd_proc_jobid_var_seq_show(struct seq_file *m, void *v) { - return snprintf(page, count, "%s\n", obd_jobid_var); + return seq_printf(m, "%s\n", obd_jobid_var); } -static int obd_proc_wr_jobid_var(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t +obd_proc_jobid_var_seq_write(struct file *file, const char __user *buffer, + size_t count, loff_t *off) { if (!count || count > JOBSTATS_JOBID_VAR_MAX_LEN) return -EINVAL; memset(obd_jobid_var, 0, JOBSTATS_JOBID_VAR_MAX_LEN + 1); + + /* This might leave the var invalid on error, which is probably fine.*/ + if (copy_from_user(obd_jobid_var, buffer, count)) + return -EFAULT; + /* Trim the trailing '\n' if any */ - memcpy(obd_jobid_var, buffer, count - (buffer[count - 1] == '\n')); + if (obd_jobid_var[count - 1] == '\n') + obd_jobid_var[count - 1] = 0; + return count; } +LPROC_SEQ_FOPS(obd_proc_jobid_var); /* Root for /proc/fs/lustre */ struct proc_dir_entry *proc_lustre_root = NULL; - -struct lprocfs_vars lprocfs_base[] = { - { "version", obd_proc_read_version, NULL, NULL }, - { "pinger", obd_proc_read_pinger, NULL, NULL }, - { "health_check", obd_proc_read_health, NULL, NULL }, - { "jobid_var", obd_proc_rd_jobid_var, - obd_proc_wr_jobid_var, NULL }, +EXPORT_SYMBOL(proc_lustre_root); + +struct lprocfs_seq_vars lprocfs_base[] = { + { .name = "version", + .fops = &obd_proc_version_fops }, + { .name = "pinger", + .fops = &obd_proc_pinger_fops }, + { .name = "health_check", + .fops = &obd_proc_health_fops }, + { .name = "jobid_var", + .fops = &obd_proc_jobid_var_fops}, { 0 } }; #else #define lprocfs_base NULL #endif /* LPROCFS */ -#ifdef __KERNEL__ static void *obd_device_list_seq_start(struct seq_file *p, loff_t *pos) { if (*pos >= class_devno_max()) @@ -388,7 +373,7 @@ static int obd_device_list_seq_show(struct seq_file *p, void *v) return seq_printf(p, "%3d %s %s %s %s %d\n", (int)index, status, obd->obd_type->typ_name, obd->obd_name, obd->obd_uuid.uuid, - cfs_atomic_read(&obd->obd_refcount)); + atomic_read(&obd->obd_refcount)); } struct seq_operations obd_device_list_sops = { @@ -400,17 +385,15 @@ struct seq_operations obd_device_list_sops = { static int obd_device_list_open(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(inode); - struct seq_file *seq; - int rc = seq_open(file, &obd_device_list_sops); - - if (rc) - return rc; + struct seq_file *seq; + int rc = seq_open(file, &obd_device_list_sops); - seq = file->private_data; - seq->private = dp->data; + if (rc) + return rc; - return 0; + seq = file->private_data; + seq->private = PDE_DATA(inode); + return 0; } struct file_operations obd_device_list_fops = { @@ -420,28 +403,40 @@ struct file_operations obd_device_list_fops = { .llseek = seq_lseek, .release = seq_release, }; -#endif int class_procfs_init(void) { -#ifdef __KERNEL__ - int rc; - ENTRY; + struct proc_dir_entry *entry; + int rc; + ENTRY; - obd_sysctl_init(); - proc_lustre_root = lprocfs_register("fs/lustre", NULL, - lprocfs_base, NULL); - rc = lprocfs_seq_create(proc_lustre_root, "devices", 0444, - &obd_device_list_fops, NULL); - if (rc) - CERROR("error adding /proc/fs/lustre/devices file\n"); -#else - ENTRY; -#endif - RETURN(0); + obd_sysctl_init(); + + entry = lprocfs_seq_register("fs/lustre", NULL, lprocfs_base, NULL); + if (IS_ERR(entry)) { + rc = PTR_ERR(entry); + CERROR("cannot create '/proc/fs/lustre': rc = %d\n", rc); + RETURN(rc); + } + + proc_lustre_root = entry; + + rc = lprocfs_seq_create(proc_lustre_root, "devices", 0444, + &obd_device_list_fops, NULL); + if (rc < 0) { + CERROR("cannot create '/proc/fs/lustre/devices': rc = %d\n", + rc); + GOTO(out_proc, rc); + } + + RETURN(rc); + +out_proc: + lprocfs_remove(&proc_lustre_root); + + RETURN(rc); } -#ifdef __KERNEL__ int class_procfs_clean(void) { ENTRY; @@ -450,4 +445,3 @@ int class_procfs_clean(void) } RETURN(0); } -#endif