Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nvdimm: Clean up __nd_ioctl() and remove gotos

Utilize scoped based resource management to clean up the code and
and remove gotos for the __nd_ioctl() function.

Change allocation of 'buf' to use kvzalloc() in order to use
vmalloc() memory when needed and also zero out the allocated
memory.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>

authored by

Dave Jiang and committed by
Ira Weiny
88506435 0020839b

+22 -43
+22 -43
drivers/nvdimm/bus.c
··· 5 5 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 6 6 #include <linux/libnvdimm.h> 7 7 #include <linux/sched/mm.h> 8 - #include <linux/vmalloc.h> 8 + #include <linux/slab.h> 9 9 #include <linux/uaccess.h> 10 10 #include <linux/module.h> 11 11 #include <linux/blkdev.h> ··· 1029 1029 unsigned int cmd = _IOC_NR(ioctl_cmd); 1030 1030 struct device *dev = &nvdimm_bus->dev; 1031 1031 void __user *p = (void __user *) arg; 1032 - char *out_env = NULL, *in_env = NULL; 1033 1032 const char *cmd_name, *dimm_name; 1034 1033 u32 in_len = 0, out_len = 0; 1035 1034 unsigned int func = cmd; 1036 1035 unsigned long cmd_mask; 1037 1036 struct nd_cmd_pkg pkg; 1038 1037 int rc, i, cmd_rc; 1039 - void *buf = NULL; 1040 1038 u64 buf_len = 0; 1041 1039 1042 1040 if (nvdimm) { ··· 1093 1095 } 1094 1096 1095 1097 /* process an input envelope */ 1096 - in_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); 1098 + char *in_env __free(kfree) = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); 1097 1099 if (!in_env) 1098 1100 return -ENOMEM; 1099 1101 for (i = 0; i < desc->in_num; i++) { ··· 1103 1105 if (in_size == UINT_MAX) { 1104 1106 dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n", 1105 1107 __func__, dimm_name, cmd_name, i); 1106 - rc = -ENXIO; 1107 - goto out; 1108 + return -ENXIO; 1108 1109 } 1109 1110 if (in_len < ND_CMD_MAX_ENVELOPE) 1110 1111 copy = min_t(u32, ND_CMD_MAX_ENVELOPE - in_len, in_size); 1111 1112 else 1112 1113 copy = 0; 1113 - if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) { 1114 - rc = -EFAULT; 1115 - goto out; 1116 - } 1114 + if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) 1115 + return -EFAULT; 1117 1116 in_len += in_size; 1118 1117 } 1119 1118 ··· 1122 1127 } 1123 1128 1124 1129 /* process an output envelope */ 1125 - out_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); 1126 - if (!out_env) { 1127 - rc = -ENOMEM; 1128 - goto out; 1129 - } 1130 + char *out_env __free(kfree) = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL); 1131 + if (!out_env) 1132 + return -ENOMEM; 1130 1133 1131 1134 for (i = 0; i < desc->out_num; i++) { 1132 1135 u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, ··· 1134 1141 if (out_size == UINT_MAX) { 1135 1142 dev_dbg(dev, "%s unknown output size cmd: %s field: %d\n", 1136 1143 dimm_name, cmd_name, i); 1137 - rc = -EFAULT; 1138 - goto out; 1144 + return -EFAULT; 1139 1145 } 1140 1146 if (out_len < ND_CMD_MAX_ENVELOPE) 1141 1147 copy = min_t(u32, ND_CMD_MAX_ENVELOPE - out_len, out_size); ··· 1142 1150 copy = 0; 1143 1151 if (copy && copy_from_user(&out_env[out_len], 1144 1152 p + in_len + out_len, copy)) { 1145 - rc = -EFAULT; 1146 - goto out; 1153 + return -EFAULT; 1147 1154 } 1148 1155 out_len += out_size; 1149 1156 } ··· 1151 1160 if (buf_len > ND_IOCTL_MAX_BUFLEN) { 1152 1161 dev_dbg(dev, "%s cmd: %s buf_len: %llu > %d\n", dimm_name, 1153 1162 cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN); 1154 - rc = -EINVAL; 1155 - goto out; 1163 + return -EINVAL; 1156 1164 } 1157 1165 1158 - buf = vmalloc(buf_len); 1159 - if (!buf) { 1160 - rc = -ENOMEM; 1161 - goto out; 1162 - } 1166 + void *buf __free(kvfree) = kvzalloc(buf_len, GFP_KERNEL); 1167 + if (!buf) 1168 + return -ENOMEM; 1163 1169 1164 - if (copy_from_user(buf, p, buf_len)) { 1165 - rc = -EFAULT; 1166 - goto out; 1167 - } 1170 + if (copy_from_user(buf, p, buf_len)) 1171 + return -EFAULT; 1168 1172 1169 - device_lock(dev); 1170 - nvdimm_bus_lock(dev); 1173 + guard(device)(dev); 1174 + guard(nvdimm_bus)(dev); 1171 1175 rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf); 1172 1176 if (rc) 1173 - goto out_unlock; 1177 + return rc; 1174 1178 1175 1179 rc = nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len, &cmd_rc); 1176 1180 if (rc < 0) 1177 - goto out_unlock; 1181 + return rc; 1178 1182 1179 1183 if (!nvdimm && cmd == ND_CMD_CLEAR_ERROR && cmd_rc >= 0) { 1180 1184 struct nd_cmd_clear_error *clear_err = buf; ··· 1179 1193 } 1180 1194 1181 1195 if (copy_to_user(p, buf, buf_len)) 1182 - rc = -EFAULT; 1196 + return -EFAULT; 1183 1197 1184 - out_unlock: 1185 - nvdimm_bus_unlock(dev); 1186 - device_unlock(dev); 1187 - out: 1188 - kfree(in_env); 1189 - kfree(out_env); 1190 - vfree(buf); 1191 - return rc; 1198 + return 0; 1192 1199 } 1193 1200 1194 1201 enum nd_ioctl_mode {