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

ovl: don't use a temp buf for encoding real fh

We can allocate maximum fh size and encode into it directly.

Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

authored by

Amir Goldstein and committed by
Miklos Szeredi
ec7bbb53 cbe7fba8

+16 -21
+16 -21
fs/overlayfs/copy_up.c
··· 227 227 struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper) 228 228 { 229 229 struct ovl_fh *fh; 230 - int fh_type, fh_len, dwords; 231 - void *buf; 230 + int fh_type, dwords; 232 231 int buflen = MAX_HANDLE_SZ; 233 232 uuid_t *uuid = &real->d_sb->s_uuid; 233 + int err; 234 234 235 - buf = kmalloc(buflen, GFP_KERNEL); 236 - if (!buf) 235 + /* Make sure the real fid stays 32bit aligned */ 236 + BUILD_BUG_ON(OVL_FH_FID_OFFSET % 4); 237 + BUILD_BUG_ON(MAX_HANDLE_SZ + OVL_FH_FID_OFFSET > 255); 238 + 239 + fh = kzalloc(buflen + OVL_FH_FID_OFFSET, GFP_KERNEL); 240 + if (!fh) 237 241 return ERR_PTR(-ENOMEM); 238 242 239 243 /* ··· 246 242 * the price or reconnecting the dentry. 247 243 */ 248 244 dwords = buflen >> 2; 249 - fh_type = exportfs_encode_fh(real, buf, &dwords, 0); 245 + fh_type = exportfs_encode_fh(real, (void *)fh->fb.fid, &dwords, 0); 250 246 buflen = (dwords << 2); 251 247 252 - fh = ERR_PTR(-EIO); 248 + err = -EIO; 253 249 if (WARN_ON(fh_type < 0) || 254 250 WARN_ON(buflen > MAX_HANDLE_SZ) || 255 251 WARN_ON(fh_type == FILEID_INVALID)) 256 - goto out; 257 - 258 - /* Make sure the real fid stays 32bit aligned */ 259 - BUILD_BUG_ON(OVL_FH_FID_OFFSET % 4); 260 - BUILD_BUG_ON(MAX_HANDLE_SZ + OVL_FH_FID_OFFSET > 255); 261 - fh_len = OVL_FH_FID_OFFSET + buflen; 262 - fh = kzalloc(fh_len, GFP_KERNEL); 263 - if (!fh) { 264 - fh = ERR_PTR(-ENOMEM); 265 - goto out; 266 - } 252 + goto out_err; 267 253 268 254 fh->fb.version = OVL_FH_VERSION; 269 255 fh->fb.magic = OVL_FH_MAGIC; ··· 267 273 */ 268 274 if (is_upper) 269 275 fh->fb.flags |= OVL_FH_FLAG_PATH_UPPER; 270 - fh->fb.len = fh_len - OVL_FH_WIRE_OFFSET; 276 + fh->fb.len = sizeof(fh->fb) + buflen; 271 277 fh->fb.uuid = *uuid; 272 - memcpy(fh->fb.fid, buf, buflen); 273 278 274 - out: 275 - kfree(buf); 276 279 return fh; 280 + 281 + out_err: 282 + kfree(fh); 283 + return ERR_PTR(err); 277 284 } 278 285 279 286 int ovl_set_origin(struct dentry *dentry, struct dentry *lower,