]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/staging/lustre/lustre/libcfs/module.c
Merge remote-tracking branch 'staging/staging-next'
[karo-tx-linux.git] / drivers / staging / lustre / lustre / libcfs / module.c
index 329d78ce272d4416309be0fde6f85cf654ab7c5a..611607ab92dbceaf68ec8b35187c39cd221c6994 100644 (file)
@@ -68,142 +68,16 @@ MODULE_LICENSE("GPL");
 
 static struct dentry *lnet_debugfs_root;
 
-static void kportal_memhog_free(struct libcfs_device_userstate *ldu)
-{
-       struct page **level0p = &ldu->ldu_memhog_root_page;
-       struct page **level1p;
-       struct page **level2p;
-       int        count1;
-       int        count2;
-
-       if (*level0p != NULL) {
-
-               level1p = (struct page **)page_address(*level0p);
-               count1 = 0;
-
-               while (count1 < PAGE_CACHE_SIZE/sizeof(struct page *) &&
-                      *level1p != NULL) {
-
-                       level2p = (struct page **)page_address(*level1p);
-                       count2 = 0;
-
-                       while (count2 < PAGE_CACHE_SIZE/sizeof(struct page *) &&
-                              *level2p != NULL) {
-
-                               __free_page(*level2p);
-                               ldu->ldu_memhog_pages--;
-                               level2p++;
-                               count2++;
-                       }
-
-                       __free_page(*level1p);
-                       ldu->ldu_memhog_pages--;
-                       level1p++;
-                       count1++;
-               }
-
-               __free_page(*level0p);
-               ldu->ldu_memhog_pages--;
-
-               *level0p = NULL;
-       }
-
-       LASSERT(ldu->ldu_memhog_pages == 0);
-}
-
-static int kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
-                    gfp_t flags)
-{
-       struct page **level0p;
-       struct page **level1p;
-       struct page **level2p;
-       int        count1;
-       int        count2;
-
-       LASSERT(ldu->ldu_memhog_pages == 0);
-       LASSERT(ldu->ldu_memhog_root_page == NULL);
-
-       if (npages < 0)
-               return -EINVAL;
-
-       if (npages == 0)
-               return 0;
-
-       level0p = &ldu->ldu_memhog_root_page;
-       *level0p = alloc_page(flags);
-       if (*level0p == NULL)
-               return -ENOMEM;
-       ldu->ldu_memhog_pages++;
-
-       level1p = (struct page **)page_address(*level0p);
-       count1 = 0;
-       memset(level1p, 0, PAGE_CACHE_SIZE);
-
-       while (ldu->ldu_memhog_pages < npages &&
-              count1 < PAGE_CACHE_SIZE/sizeof(struct page *)) {
-
-               if (cfs_signal_pending())
-                       return -EINTR;
-
-               *level1p = alloc_page(flags);
-               if (*level1p == NULL)
-                       return -ENOMEM;
-               ldu->ldu_memhog_pages++;
-
-               level2p = (struct page **)page_address(*level1p);
-               count2 = 0;
-               memset(level2p, 0, PAGE_CACHE_SIZE);
-
-               while (ldu->ldu_memhog_pages < npages &&
-                      count2 < PAGE_CACHE_SIZE/sizeof(struct page *)) {
-
-                       if (cfs_signal_pending())
-                               return -EINTR;
-
-                       *level2p = alloc_page(flags);
-                       if (*level2p == NULL)
-                               return -ENOMEM;
-                       ldu->ldu_memhog_pages++;
-
-                       level2p++;
-                       count2++;
-               }
-
-               level1p++;
-               count1++;
-       }
-
-       return 0;
-}
-
 /* called when opening /dev/device */
 static int libcfs_psdev_open(unsigned long flags, void *args)
 {
-       struct libcfs_device_userstate *ldu;
-
        try_module_get(THIS_MODULE);
-
-       LIBCFS_ALLOC(ldu, sizeof(*ldu));
-       if (ldu != NULL) {
-               ldu->ldu_memhog_pages = 0;
-               ldu->ldu_memhog_root_page = NULL;
-       }
-       *(struct libcfs_device_userstate **)args = ldu;
-
        return 0;
 }
 
 /* called when closing /dev/device */
 static int libcfs_psdev_release(unsigned long flags, void *args)
 {
-       struct libcfs_device_userstate *ldu;
-
-       ldu = (struct libcfs_device_userstate *)args;
-       if (ldu != NULL) {
-               kportal_memhog_free(ldu);
-               LIBCFS_FREE(ldu, sizeof(*ldu));
-       }
-
        module_put(THIS_MODULE);
        return 0;
 }
@@ -242,7 +116,7 @@ int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)
 EXPORT_SYMBOL(libcfs_deregister_ioctl);
 
 static int libcfs_ioctl_int(struct cfs_psdev_file *pfile, unsigned long cmd,
-                           void *arg, struct libcfs_ioctl_data *data)
+                           void __user *arg, struct libcfs_ioctl_data *data)
 {
        int err = -EINVAL;
 
@@ -260,19 +134,6 @@ static int libcfs_ioctl_int(struct cfs_psdev_file *pfile, unsigned long cmd,
                        return -EINVAL;
                libcfs_debug_mark_buffer(data->ioc_inlbuf1);
                return 0;
-       case IOC_LIBCFS_MEMHOG:
-               if (pfile->private_data == NULL) {
-                       err = -EINVAL;
-               } else {
-                       kportal_memhog_free(pfile->private_data);
-                       /* XXX The ioc_flags is not GFP flags now, need to be fixed */
-                       err = kportal_memhog_alloc(pfile->private_data,
-                                                  data->ioc_count,
-                                                  data->ioc_flags);
-                       if (err != 0)
-                               kportal_memhog_free(pfile->private_data);
-               }
-               break;
 
        default: {
                struct libcfs_ioctl_handler *hand;
@@ -296,7 +157,8 @@ static int libcfs_ioctl_int(struct cfs_psdev_file *pfile, unsigned long cmd,
        return err;
 }
 
-static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd, void *arg)
+static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd,
+                       void __user *arg)
 {
        char    *buf;
        struct libcfs_ioctl_data *data;
@@ -640,18 +502,39 @@ static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
        return error;
 }
 
-static const struct file_operations lnet_debugfs_file_operations = {
+static const struct file_operations lnet_debugfs_file_operations_rw = {
        .open           = simple_open,
        .read           = lnet_debugfs_read,
        .write          = lnet_debugfs_write,
        .llseek         = default_llseek,
 };
 
+static const struct file_operations lnet_debugfs_file_operations_ro = {
+       .open           = simple_open,
+       .read           = lnet_debugfs_read,
+       .llseek         = default_llseek,
+};
+
+static const struct file_operations lnet_debugfs_file_operations_wo = {
+       .open           = simple_open,
+       .write          = lnet_debugfs_write,
+       .llseek         = default_llseek,
+};
+
+static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
+{
+       if (!(mode & S_IWUGO))
+               return &lnet_debugfs_file_operations_ro;
+
+       if (!(mode & S_IRUGO))
+               return &lnet_debugfs_file_operations_wo;
+
+       return &lnet_debugfs_file_operations_rw;
+}
+
 void lustre_insert_debugfs(struct ctl_table *table,
                           const struct lnet_debugfs_symlink_def *symlinks)
 {
-       struct dentry *entry;
-
        if (lnet_debugfs_root == NULL)
                lnet_debugfs_root = debugfs_create_dir("lnet", NULL);
 
@@ -659,15 +542,17 @@ void lustre_insert_debugfs(struct ctl_table *table,
        if (IS_ERR_OR_NULL(lnet_debugfs_root))
                return;
 
+       /* We don't save the dentry returned in next two calls, because
+        * we don't call debugfs_remove() but rather remove_recursive()
+        */
        for (; table->procname; table++)
-               entry = debugfs_create_file(table->procname, table->mode,
-                                           lnet_debugfs_root, table,
-                                           &lnet_debugfs_file_operations);
+               debugfs_create_file(table->procname, table->mode,
+                                   lnet_debugfs_root, table,
+                                   lnet_debugfs_fops_select(table->mode));
 
        for (; symlinks && symlinks->name; symlinks++)
-               entry = debugfs_create_symlink(symlinks->name,
-                                              lnet_debugfs_root,
-                                              symlinks->target);
+               debugfs_create_symlink(symlinks->name, lnet_debugfs_root,
+                                      symlinks->target);
 
 }
 EXPORT_SYMBOL_GPL(lustre_insert_debugfs);