diff --git a/kmod/src/alloc.c b/kmod/src/alloc.c index 40c33c20..0ceaf3b8 100644 --- a/kmod/src/alloc.c +++ b/kmod/src/alloc.c @@ -857,7 +857,7 @@ static int find_zone_extent(struct super_block *sb, struct scoutfs_alloc_root *r .zone = SCOUTFS_FREE_EXTENT_ORDER_ZONE, }; struct scoutfs_extent found; - struct scoutfs_extent ext; + struct scoutfs_extent ext = {0,}; u64 start; u64 len; int nr; diff --git a/kmod/src/client.c b/kmod/src/client.c index 9706d0b6..cffd2bfa 100644 --- a/kmod/src/client.c +++ b/kmod/src/client.c @@ -435,8 +435,8 @@ static int lookup_mounted_client_item(struct super_block *sb, u64 rid) if (ret == -ENOENT) ret = 0; - kfree(super); out: + kfree(super); return ret; } diff --git a/kmod/src/inode.c b/kmod/src/inode.c index e1ac0e3e..cd6f37bc 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -2188,7 +2188,7 @@ int scoutfs_inode_walk_writeback(struct super_block *sb, bool write) struct scoutfs_inode_info *si; struct scoutfs_inode_info *tmp; struct inode *inode; - int ret; + int ret = 0; spin_lock(&inf->writeback_lock); diff --git a/kmod/src/ioctl.c b/kmod/src/ioctl.c index fea7aae3..a7423362 100644 --- a/kmod/src/ioctl.c +++ b/kmod/src/ioctl.c @@ -954,6 +954,9 @@ static int copy_alloc_detail_to_user(struct super_block *sb, void *arg, if (args->copied == args->nr) return -EOVERFLOW; + /* .type and .pad need clearing */ + memset(&ade, 0, sizeof(struct scoutfs_ioctl_alloc_detail_entry)); + ade.blocks = blocks; ade.id = id; ade.meta = !!meta; @@ -1369,7 +1372,7 @@ static long scoutfs_ioc_get_referring_entries(struct file *file, unsigned long a ent.d_type = bref->d_type; ent.name_len = name_len; - if (copy_to_user(uent, &ent, sizeof(struct scoutfs_ioctl_dirent)) || + if (copy_to_user(uent, &ent, offsetof(struct scoutfs_ioctl_dirent, name[0])) || copy_to_user(&uent->name[0], bref->dent.name, name_len) || put_user('\0', &uent->name[name_len])) { ret = -EFAULT; diff --git a/kmod/src/net.c b/kmod/src/net.c index 380ee637..47a7059f 100644 --- a/kmod/src/net.c +++ b/kmod/src/net.c @@ -1103,9 +1103,15 @@ static void scoutfs_net_listen_worker(struct work_struct *work) conn->notify_down, conn->info_size, conn->req_funcs, "accepted"); + /* + * scoutfs_net_alloc_conn() can fail due to ENOMEM. If this + * is the only thing that does so, there's no harm in trying + * to see if kernel_accept() can get enough memory to try accepting + * a new connection again. If that then fails with ENOMEM, it'll + * shut down the conn anyway. So just retry here. + */ if (!acc_conn) { sock_release(acc_sock); - ret = -ENOMEM; continue; } diff --git a/kmod/src/omap.c b/kmod/src/omap.c index c39dbc9c..4731668b 100644 --- a/kmod/src/omap.c +++ b/kmod/src/omap.c @@ -592,7 +592,7 @@ static int handle_request(struct super_block *sb, struct omap_request *req) ret = 0; out: free_rids(&priv_rids); - if (ret < 0) { + if ((ret < 0) && (req != NULL)) { ret = scoutfs_server_send_omap_response(sb, req->client_rid, req->client_id, NULL, ret); free_req(req); diff --git a/kmod/src/quorum.c b/kmod/src/quorum.c index 7c385448..242804ed 100644 --- a/kmod/src/quorum.c +++ b/kmod/src/quorum.c @@ -1062,7 +1062,7 @@ static char *role_str(int role) [LEADER] = "leader", }; - if (role < 0 || role > ARRAY_SIZE(roles) || !roles[role]) + if (role < 0 || role >= ARRAY_SIZE(roles) || !roles[role]) return "invalid"; return roles[role]; diff --git a/kmod/src/srch.c b/kmod/src/srch.c index a77c5eff..4f08be0c 100644 --- a/kmod/src/srch.c +++ b/kmod/src/srch.c @@ -856,14 +856,14 @@ static int search_sorted_file(struct super_block *sb, if (pos > SCOUTFS_SRCH_BLOCK_SAFE_BYTES) { /* can only be inconsistency :/ */ ret = -EIO; - break; + goto out; } ret = decode_entry(srb->entries + pos, &sre, &prev); if (ret <= 0) { /* can only be inconsistency :/ */ ret = -EIO; - break; + goto out; } pos += ret; prev = sre; @@ -1865,7 +1865,7 @@ static int compact_logs(struct super_block *sb, if (pos > SCOUTFS_SRCH_BLOCK_SAFE_BYTES) { /* can only be inconsistency :/ */ ret = -EIO; - break; + goto out; } ret = decode_entry(srb->entries + pos, sre, &prev); @@ -2301,7 +2301,7 @@ out: scoutfs_inc_counter(sb, srch_compact_error); scoutfs_block_writer_forget_all(sb, &wri); - queue_compact_work(srinf, sc->nr > 0 && ret == 0); + queue_compact_work(srinf, sc != NULL && sc->nr > 0 && ret == 0); kfree(sc); } diff --git a/kmod/src/super.c b/kmod/src/super.c index 16ab2343..3c837160 100644 --- a/kmod/src/super.c +++ b/kmod/src/super.c @@ -512,9 +512,9 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent) sbi = kzalloc(sizeof(struct scoutfs_sb_info), GFP_KERNEL); sb->s_fs_info = sbi; - sbi->sb = sb; if (!sbi) return -ENOMEM; + sbi->sb = sb; ret = assign_random_id(sbi); if (ret < 0)