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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs

Pull overlayfs fixes from Miklos Szeredi:
"This contains two regression fixes: one for the xattr API update and
one for using the mounter's creds in file creation in overlayfs.

There's also a fix for a bug in handling hard linked AF_UNIX sockets
that's been there from day one. This fix is overlayfs only despite
the fact that it touches code outside the overlay filesystem: d_real()
is an identity function for all except overlay dentries"

* 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
ovl: fix uid/gid when creating over whiteout
ovl: xattr filter fix
af_unix: fix hard linked sockets on overlay
vfs: add d_real_inode() helper

+32 -25
+11 -2
fs/overlayfs/dir.c
··· 405 405 err = ovl_create_upper(dentry, inode, &stat, link, hardlink); 406 406 } else { 407 407 const struct cred *old_cred; 408 + struct cred *override_cred; 408 409 409 410 old_cred = ovl_override_creds(dentry->d_sb); 410 411 411 - err = ovl_create_over_whiteout(dentry, inode, &stat, link, 412 - hardlink); 412 + err = -ENOMEM; 413 + override_cred = prepare_creds(); 414 + if (override_cred) { 415 + override_cred->fsuid = old_cred->fsuid; 416 + override_cred->fsgid = old_cred->fsgid; 417 + put_cred(override_creds(override_cred)); 418 + put_cred(override_cred); 413 419 420 + err = ovl_create_over_whiteout(dentry, inode, &stat, 421 + link, hardlink); 422 + } 414 423 revert_creds(old_cred); 415 424 } 416 425
+6 -20
fs/overlayfs/inode.c
··· 238 238 return err; 239 239 } 240 240 241 - static bool ovl_need_xattr_filter(struct dentry *dentry, 242 - enum ovl_path_type type) 243 - { 244 - if ((type & (__OVL_PATH_PURE | __OVL_PATH_UPPER)) == __OVL_PATH_UPPER) 245 - return S_ISDIR(dentry->d_inode->i_mode); 246 - else 247 - return false; 248 - } 249 - 250 241 ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, 251 242 const char *name, void *value, size_t size) 252 243 { 253 - struct path realpath; 254 - enum ovl_path_type type = ovl_path_real(dentry, &realpath); 244 + struct dentry *realdentry = ovl_dentry_real(dentry); 255 245 256 - if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) 246 + if (ovl_is_private_xattr(name)) 257 247 return -ENODATA; 258 248 259 - return vfs_getxattr(realpath.dentry, name, value, size); 249 + return vfs_getxattr(realdentry, name, value, size); 260 250 } 261 251 262 252 ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) 263 253 { 264 - struct path realpath; 265 - enum ovl_path_type type = ovl_path_real(dentry, &realpath); 254 + struct dentry *realdentry = ovl_dentry_real(dentry); 266 255 ssize_t res; 267 256 int off; 268 257 269 - res = vfs_listxattr(realpath.dentry, list, size); 258 + res = vfs_listxattr(realdentry, list, size); 270 259 if (res <= 0 || size == 0) 271 - return res; 272 - 273 - if (!ovl_need_xattr_filter(dentry, type)) 274 260 return res; 275 261 276 262 /* filter out private xattrs */ ··· 288 302 goto out; 289 303 290 304 err = -ENODATA; 291 - if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name)) 305 + if (ovl_is_private_xattr(name)) 292 306 goto out_drop_write; 293 307 294 308 if (!OVL_TYPE_UPPER(type)) {
+12
include/linux/dcache.h
··· 575 575 return inode; 576 576 } 577 577 578 + /** 579 + * d_real_inode - Return the real inode 580 + * @dentry: The dentry to query 581 + * 582 + * If dentry is on an union/overlay, then return the underlying, real inode. 583 + * Otherwise return d_inode(). 584 + */ 585 + static inline struct inode *d_real_inode(struct dentry *dentry) 586 + { 587 + return d_backing_inode(d_real(dentry)); 588 + } 589 + 578 590 579 591 #endif /* __LINUX_DCACHE_H */
+3 -3
net/unix/af_unix.c
··· 315 315 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { 316 316 struct dentry *dentry = unix_sk(s)->path.dentry; 317 317 318 - if (dentry && d_backing_inode(dentry) == i) { 318 + if (dentry && d_real_inode(dentry) == i) { 319 319 sock_hold(s); 320 320 goto found; 321 321 } ··· 911 911 err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path); 912 912 if (err) 913 913 goto fail; 914 - inode = d_backing_inode(path.dentry); 914 + inode = d_real_inode(path.dentry); 915 915 err = inode_permission(inode, MAY_WRITE); 916 916 if (err) 917 917 goto put_fail; ··· 1048 1048 goto out_up; 1049 1049 } 1050 1050 addr->hash = UNIX_HASH_SIZE; 1051 - hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1); 1051 + hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1); 1052 1052 spin_lock(&unix_table_lock); 1053 1053 u->path = u_path; 1054 1054 list = &unix_socket_table[hash];