kdbus: porting to 4.14 30/256230/1
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 11 Sep 2019 13:34:33 +0000 (15:34 +0200)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Wed, 31 Mar 2021 06:05:09 +0000 (08:05 +0200)
This commit makes kdbus driver working with kernel 4.14.
It also enabled compilation of the driver if enabled in config.

The list of changes needed to make it compile with kernel 4.14:
- Add missing includes for <linux/cred.h>
- put inode_lock()/inode_unlock() in place of explicit mutex locking
- replace CURRENT_TIME with proper call to current_time()
- replace PAGE_CACHE_* with PAGE_*
- replace GFP_TEMPORARY with GFP_KERNEL
- use kvecs for kernel memory, iovec for user memory instead of only iovec
  for both
- fix usage of task_cgroup_path()
- replace GROUP_AT usage with 'gid' field dereference
- add 0 as an argument to init_name_hash
- add 0 as flags as an argument to vfs_iter_write
- replace __vfs_read with kernel_read to allow compilation into module

Change-Id: Ifed3a6d3a37082a900a64316af1c8a21ab30e84e
Origin: commit:846051292431cc81adb852c2b0cbbfddac4a3d48
Signed-off-by: Adrian Szyndela <adrian.s@samsung.com>
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
12 files changed:
ipc/Makefile
ipc/kdbus/bus.c
ipc/kdbus/domain.c
ipc/kdbus/endpoint.c
ipc/kdbus/fs.c
ipc/kdbus/message.c
ipc/kdbus/metadata.c
ipc/kdbus/names.c
ipc/kdbus/policy.c
ipc/kdbus/pool.c
ipc/kdbus/util.h
samples/Makefile

index 227b96f..2d21802 100644 (file)
@@ -9,4 +9,4 @@ obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
 obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o
 obj-$(CONFIG_IPC_NS) += namespace.o
 obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
-#obj-$(CONFIG_KDBUS) += kdbus/
+obj-$(CONFIG_KDBUS) += kdbus/
index a67f825..bb49ed6 100644 (file)
@@ -12,6 +12,7 @@
  * your option) any later version.
  */
 
+#include <linux/cred.h>
 #include <linux/fs.h>
 #include <linux/hashtable.h>
 #include <linux/init.h>
index ac9f760..e2fdcde 100644 (file)
@@ -12,6 +12,7 @@
  * your option) any later version.
  */
 
+#include <linux/cred.h>
 #include <linux/fs.h>
 #include <linux/idr.h>
 #include <linux/init.h>
index 44e7a20..cef90cd 100644 (file)
@@ -12,6 +12,7 @@
  * your option) any later version.
  */
 
+#include <linux/cred.h>
 #include <linux/fs.h>
 #include <linux/idr.h>
 #include <linux/init.h>
index 09c4809..e368b73 100644 (file)
@@ -126,9 +126,9 @@ static loff_t fs_dir_fop_llseek(struct file *file, loff_t offset, int whence)
        loff_t ret;
 
        /* protect f_off against fop_iterate */
-       mutex_lock(&inode->i_mutex);
+       inode_lock(inode);
        ret = generic_file_llseek(file, offset, whence);
-       mutex_unlock(&inode->i_mutex);
+       inode_unlock(inode);
 
        return ret;
 }
@@ -203,7 +203,7 @@ static struct inode *fs_inode_get(struct super_block *sb,
        inode->i_private = kdbus_node_ref(node);
        inode->i_mapping->a_ops = &empty_aops;
        inode->i_mode = node->mode & S_IALLUGO;
-       inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+       inode->i_atime = inode->i_ctime = inode->i_mtime = current_time(inode);
        inode->i_uid = node->uid;
        inode->i_gid = node->gid;
 
@@ -280,8 +280,8 @@ static int fs_super_fill(struct super_block *sb)
        struct inode *inode;
        int ret;
 
-       sb->s_blocksize = PAGE_CACHE_SIZE;
-       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+       sb->s_blocksize = PAGE_SIZE;
+       sb->s_blocksize_bits = PAGE_SHIFT;
        sb->s_magic = KDBUS_SUPER_MAGIC;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        sb->s_op = &fs_super_sops;
index 66b9325..8aef83d 100644 (file)
@@ -139,7 +139,7 @@ int kdbus_gaps_install(struct kdbus_gaps *gaps, struct kdbus_pool_slice *slice,
                return 0;
        }
 
-       fds = kmalloc_array(n_fds, sizeof(*fds), GFP_TEMPORARY);
+       fds = kmalloc_array(n_fds, sizeof(*fds), GFP_KERNEL);
        n_fds = 0;
        if (!fds)
                return -ENOMEM;
@@ -306,7 +306,7 @@ static int kdbus_msg_examine(struct kdbus_msg *msg, struct kdbus_bus *bus,
 
        if (msg->flags & KDBUS_MSG_EXPECT_REPLY) {
                /* if you expect a reply, you must specify a timeout */
-               if (msg->timeout_ns == 0)
+               if (msg->timeout_ns == 0 || !msg->cookie)
                        return -EINVAL;
                /* signals cannot have replies */
                if (msg->flags & KDBUS_MSG_SIGNAL)
@@ -660,7 +660,7 @@ static struct kdbus_staging *kdbus_staging_new(struct kdbus_bus *bus,
        n_parts += reserved_parts;
 
        staging = kzalloc(sizeof(*staging) + n_parts * sizeof(*staging->parts) +
-                         msg_extra_size, GFP_TEMPORARY);
+                         msg_extra_size, GFP_KERNEL);
        if (!staging)
                return ERR_PTR(-ENOMEM);
 
@@ -883,6 +883,7 @@ struct kdbus_pool_slice *kdbus_staging_emit(struct kdbus_staging *staging,
        struct iovec *v;
        u64 attach, msg_size;
        int ret;
+       size_t kvec_parts_count, size_before_payload = 0;
 
        /*
         * Step 1:
@@ -951,6 +952,8 @@ struct kdbus_pool_slice *kdbus_staging_emit(struct kdbus_staging *staging,
                ++v;
        }
 
+       kvec_parts_count = v - staging->parts;
+
        /* ... payload iovecs are already filled in ... */
 
        /* compute overall size and fill in padding after payload */
@@ -1013,11 +1016,30 @@ struct kdbus_pool_slice *kdbus_staging_emit(struct kdbus_staging *staging,
 
        WARN_ON(kdbus_pool_slice_size(slice) != size);
 
-       ret = kdbus_pool_slice_copy_iovec(slice, 0, staging->parts,
-                                         staging->n_parts, size);
+       {
+               ulong count_parts;
+               for (count_parts = 0; count_parts < kvec_parts_count; count_parts++)
+                       size_before_payload += staging->parts[count_parts].iov_len;
+       }
+
+       ret = kdbus_pool_slice_copy_kvec(slice, 0, (struct kvec *)staging->parts,
+                       kvec_parts_count, size_before_payload);
        if (ret < 0)
                goto error;
 
+       for (; kvec_parts_count < staging->n_parts; kvec_parts_count++) {
+               struct iovec *part = &staging->parts[kvec_parts_count];
+               if (part->iov_base != zeros)
+                       ret = kdbus_pool_slice_copy_iovec(slice, size_before_payload,
+                                       part, 1, part->iov_len);
+               else
+                       ret = kdbus_pool_slice_copy_kvec(slice, size_before_payload,
+                                       (struct kvec *)&part, 1, part->iov_len);
+               if (ret < 0)
+                       goto error;
+               size_before_payload += part->iov_len;
+       }
+
        /* all done, return slice to caller */
        goto exit;
 
index 106ec26..2f93d60 100644 (file)
@@ -262,15 +262,13 @@ static int kdbus_meta_proc_collect_cgroup(struct kdbus_meta_proc *mp)
 {
 #ifdef CONFIG_CGROUPS
        void *page;
-       char *s;
 
-       page = (void *)__get_free_page(GFP_TEMPORARY);
+       page = (void *)__get_free_page(GFP_KERNEL);
        if (!page)
                return -ENOMEM;
 
-       s = task_cgroup_path(current, page, PAGE_SIZE);
-       if (s) {
-               mp->cgroup = kstrdup(s, GFP_KERNEL);
+       if (task_cgroup_path(current, page, PAGE_SIZE) < PAGE_SIZE) {
+               mp->cgroup = kstrdup(page, GFP_KERNEL);
                if (!mp->cgroup) {
                        free_page((unsigned long)page);
                        return -ENOMEM;
@@ -965,8 +963,7 @@ static size_t kdbus_meta_write(struct kdbus_meta_staging *staging, void *mem,
                item = kdbus_write_head(&items, KDBUS_ITEM_AUXGROUPS,
                                        info->ngroups * sizeof(u64));
                for (i = 0; i < info->ngroups; ++i)
-                       item->data64[i] = from_kgid_munged(user_ns,
-                                                          GROUP_AT(info, i));
+                       item->data64[i] = from_kgid_munged(user_ns, info->gid[i]);
        }
 
        if (staging->mp && (staging->mask & KDBUS_ATTACH_TID_COMM))
@@ -1113,7 +1110,7 @@ int kdbus_meta_emit(struct kdbus_meta_proc *mp,
 
                get_fs_root(current->fs, &p);
                if (path_equal(&p, &conn->root_path)) {
-                       staging.exe = (void *)__get_free_page(GFP_TEMPORARY);
+                       staging.exe = (void *)__get_free_page(GFP_KERNEL);
                        if (!staging.exe) {
                                path_put(&p);
                                ret = -ENOMEM;
index bf44ca3..13a2296 100644 (file)
@@ -12,6 +12,7 @@
  * your option) any later version.
  */
 
+#include <linux/cred.h>
 #include <linux/ctype.h>
 #include <linux/fs.h>
 #include <linux/hash.h>
index f2618e1..e463919 100644 (file)
@@ -12,6 +12,7 @@
  * your option) any later version.
  */
 
+#include <linux/cred.h>
 #include <linux/dcache.h>
 #include <linux/fs.h>
 #include <linux/init.h>
@@ -83,7 +84,7 @@ static void kdbus_policy_entry_free(struct kdbus_policy_db_entry *e)
 
 static unsigned int kdbus_strnhash(const char *str, size_t len)
 {
-       unsigned long hash = init_name_hash();
+       unsigned long hash = init_name_hash(0);
 
        while (len--)
                hash = partial_name_hash(*str++, hash);
@@ -192,7 +193,7 @@ int kdbus_policy_query_unlocked(struct kdbus_policy_db *db,
                        }
 
                        for (i = 0; i < cred->group_info->ngroups; i++) {
-                               kgid_t gid = GROUP_AT(cred->group_info, i);
+                               kgid_t gid = cred->group_info->gid[i];
 
                                if (gid_eq(gid, a->gid)) {
                                        highest = a->access;
index 63ccd55..fb1a88a 100644 (file)
@@ -587,7 +587,7 @@ kdbus_pool_slice_copy_iovec(const struct kdbus_pool_slice *slice, loff_t off,
 
        off += slice->off;
        iov_iter_init(&iter, WRITE, iov, iov_len, total_len);
-       len = vfs_iter_write(slice->pool->f, &iter, &off);
+       len = vfs_iter_write(slice->pool->f, &iter, &off, 0);
 
        return (len >= 0 && len != total_len) ? -EFAULT : len;
 }
@@ -620,7 +620,7 @@ ssize_t kdbus_pool_slice_copy_kvec(const struct kdbus_pool_slice *slice,
 
        old_fs = get_fs();
        set_fs(get_ds());
-       len = vfs_iter_write(slice->pool->f, &iter, &off);
+       len = vfs_iter_write(slice->pool->f, &iter, &off, 0);
        set_fs(old_fs);
 
        return (len >= 0 && len != total_len) ? -EFAULT : len;
@@ -651,7 +651,7 @@ int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
            WARN_ON(slice_src->free || slice_dst->free))
                return -EINVAL;
 
-       mutex_lock(&i_dst->i_mutex);
+       inode_lock(i_dst);
        old_fs = get_fs();
        set_fs(get_ds());
        while (len > 0) {
@@ -663,9 +663,9 @@ int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
                void *fsdata;
                long status;
 
-               page_off = off_dst & (PAGE_CACHE_SIZE - 1);
+               page_off = off_dst & (PAGE_SIZE - 1);
                copy_len = min_t(unsigned long,
-                                PAGE_CACHE_SIZE - page_off, len);
+                                PAGE_SIZE - page_off, len);
 
                status = aops->write_begin(f_dst, mapping_dst, off_dst,
                                           copy_len, 0, &page, &fsdata);
@@ -675,7 +675,7 @@ int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
                }
 
                kaddr = (char __force __user *)kmap(page) + page_off;
-               n_read = __vfs_read(f_src, kaddr, copy_len, &off_src);
+               n_read = kernel_read(f_src, kaddr, copy_len, &off_src);
                kunmap(page);
                mark_page_accessed(page);
                flush_dcache_page(page);
@@ -696,7 +696,7 @@ int kdbus_pool_slice_copy(const struct kdbus_pool_slice *slice_dst,
                len -= copy_len;
        }
        set_fs(old_fs);
-       mutex_unlock(&i_dst->i_mutex);
+       inode_unlock(i_dst);
 
        return ret;
 }
index 5297166..cf1403b 100644 (file)
@@ -51,7 +51,7 @@
  */
 static inline unsigned int kdbus_strhash(const char *str)
 {
-       unsigned long hash = init_name_hash();
+       unsigned long hash = init_name_hash(0);
 
        while (*str)
                hash = partial_name_hash(*str++, hash);
index bd601c0..06c5c3a 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)  += kobject/ kprobes/ trace_events/ livepatch/ \
-                          hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
+                          hw_breakpoint/ kfifo/ kdb/ kdbus/ hidraw/ rpmsg/ seccomp/ \
                           configfs/ connector/ v4l/ trace_printk/ \
                           vfio-mdev/ statx/ qmi/