kdbus: porting to 4.14
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 11 Sep 2019 13:34:33 +0000 (15:34 +0200)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Fri, 26 Mar 2021 21:29:07 +0000 (22:29 +0100)
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 227b96f8f61872b480c91ef2aca22ba51ffe7cd3..2d21802ba1ec6facdc8230f2a1f681f333acecdd 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 a67f825bdeaf02fb7e76187750ed28417db79e18..bb49ed6ba8333a7dd298becd57c4456f1edca082 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 ac9f760c150dd6c387e51ab3b6675dac947c4344..e2fdcde550ec0d803d3b018b6ba816bded793525 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 44e7a20de9c24a06bbb4355889d5eed02423aa8f..cef90cd08953f4075608c2e033fdac233eaef84b 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 09c480924b9e72984f4d9b1bf5296a2c6708b2a0..e368b7354424973da947b54c2cdeadd2aabcf93c 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 66b9325f03d0703bcf501ce98cc42e9685ebec2b..8aef83d1b3f12887e728b729d58771e8de008a6c 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 106ec26f2882ec854aaead7a40af7f20cc7ba780..2f93d6029d01597441a25af437e72c69a0abfc36 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 bf44ca3f12b6f3532297f949b03626dc62b0a6cc..13a229611511fb68051983d494979920ffb81593 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 f2618e15e78db6903a518126752606ecf8bd58e1..e463919ef986fac2aa4d1476971015ec0a1ad16e 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 63ccd55713c7f6c1960105a2f870b4af92efe019..fb1a88ac66f63630e5792e0b92c522c165a62201 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 529716669fe717f11173a0900fb5a05f151df631..cf1403bbb971e8d9ef5ac27b4adb776a34f1e405 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 bd601c038b86f67e47fff54ae2dfe4eeab5fc3a6..06c5c3a5b30f140bd6fd6c4d7ecaffd07bba7794 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/