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

Merge tag 'ovl-update-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs

Pull overlayfs update from Miklos Szeredi:
"Just bug fixes in this small update"

* tag 'ovl-update-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
ovl: relax WARN_ON() for overlapping layers use case
ovl: check the capability before cred overridden
ovl: do not generate duplicate fsnotify events for "fake" path
ovl: support stacked SEEK_HOLE/SEEK_DATA
ovl: fix missing upper fs freeze protection on copy up for ioctl

+113 -33
+3 -3
fs/overlayfs/copy_up.c
··· 909 909 return true; 910 910 } 911 911 912 - int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags) 912 + int ovl_maybe_copy_up(struct dentry *dentry, int flags) 913 913 { 914 914 int err = 0; 915 915 916 - if (ovl_open_need_copy_up(dentry, file_flags)) { 916 + if (ovl_open_need_copy_up(dentry, flags)) { 917 917 err = ovl_want_write(dentry); 918 918 if (!err) { 919 - err = ovl_copy_up_flags(dentry, file_flags); 919 + err = ovl_copy_up_flags(dentry, flags); 920 920 ovl_drop_write(dentry); 921 921 } 922 922 }
+1 -1
fs/overlayfs/dir.c
··· 260 260 * hashed directory inode aliases. 261 261 */ 262 262 inode = ovl_get_inode(dentry->d_sb, &oip); 263 - if (WARN_ON(IS_ERR(inode))) 263 + if (IS_ERR(inode)) 264 264 return PTR_ERR(inode); 265 265 } else { 266 266 WARN_ON(ovl_inode_real(inode) != d_inode(newdentry));
+106 -27
fs/overlayfs/file.c
··· 11 11 #include <linux/mount.h> 12 12 #include <linux/xattr.h> 13 13 #include <linux/uio.h> 14 + #include <linux/uaccess.h> 14 15 #include "overlayfs.h" 15 16 16 17 static char ovl_whatisit(struct inode *inode, struct inode *realinode) ··· 30 29 struct inode *inode = file_inode(file); 31 30 struct file *realfile; 32 31 const struct cred *old_cred; 32 + int flags = file->f_flags | O_NOATIME | FMODE_NONOTIFY; 33 33 34 34 old_cred = ovl_override_creds(inode->i_sb); 35 - realfile = open_with_fake_path(&file->f_path, file->f_flags | O_NOATIME, 36 - realinode, current_cred()); 35 + realfile = open_with_fake_path(&file->f_path, flags, realinode, 36 + current_cred()); 37 37 revert_creds(old_cred); 38 38 39 39 pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n", ··· 52 50 int err; 53 51 54 52 /* No atime modificaton on underlying */ 55 - flags |= O_NOATIME; 53 + flags |= O_NOATIME | FMODE_NONOTIFY; 56 54 57 55 /* If some flag changed that cannot be changed then something's amiss */ 58 56 if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK)) ··· 118 116 119 117 static int ovl_open(struct inode *inode, struct file *file) 120 118 { 121 - struct dentry *dentry = file_dentry(file); 122 119 struct file *realfile; 123 120 int err; 124 121 125 - err = ovl_open_maybe_copy_up(dentry, file->f_flags); 122 + err = ovl_maybe_copy_up(file_dentry(file), file->f_flags); 126 123 if (err) 127 124 return err; 128 125 ··· 146 145 147 146 static loff_t ovl_llseek(struct file *file, loff_t offset, int whence) 148 147 { 149 - struct inode *realinode = ovl_inode_real(file_inode(file)); 148 + struct inode *inode = file_inode(file); 149 + struct fd real; 150 + const struct cred *old_cred; 151 + ssize_t ret; 150 152 151 - return generic_file_llseek_size(file, offset, whence, 152 - realinode->i_sb->s_maxbytes, 153 - i_size_read(realinode)); 153 + /* 154 + * The two special cases below do not need to involve real fs, 155 + * so we can optimizing concurrent callers. 156 + */ 157 + if (offset == 0) { 158 + if (whence == SEEK_CUR) 159 + return file->f_pos; 160 + 161 + if (whence == SEEK_SET) 162 + return vfs_setpos(file, 0, 0); 163 + } 164 + 165 + ret = ovl_real_fdget(file, &real); 166 + if (ret) 167 + return ret; 168 + 169 + /* 170 + * Overlay file f_pos is the master copy that is preserved 171 + * through copy up and modified on read/write, but only real 172 + * fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose 173 + * limitations that are more strict than ->s_maxbytes for specific 174 + * files, so we use the real file to perform seeks. 175 + */ 176 + inode_lock(inode); 177 + real.file->f_pos = file->f_pos; 178 + 179 + old_cred = ovl_override_creds(inode->i_sb); 180 + ret = vfs_llseek(real.file, offset, whence); 181 + revert_creds(old_cred); 182 + 183 + file->f_pos = real.file->f_pos; 184 + inode_unlock(inode); 185 + 186 + fdput(real); 187 + 188 + return ret; 154 189 } 155 190 156 191 static void ovl_file_accessed(struct file *file) ··· 409 372 return ret; 410 373 } 411 374 412 - static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 375 + static unsigned int ovl_get_inode_flags(struct inode *inode) 376 + { 377 + unsigned int flags = READ_ONCE(inode->i_flags); 378 + unsigned int ovl_iflags = 0; 379 + 380 + if (flags & S_SYNC) 381 + ovl_iflags |= FS_SYNC_FL; 382 + if (flags & S_APPEND) 383 + ovl_iflags |= FS_APPEND_FL; 384 + if (flags & S_IMMUTABLE) 385 + ovl_iflags |= FS_IMMUTABLE_FL; 386 + if (flags & S_NOATIME) 387 + ovl_iflags |= FS_NOATIME_FL; 388 + 389 + return ovl_iflags; 390 + } 391 + 392 + static long ovl_ioctl_set_flags(struct file *file, unsigned long arg) 413 393 { 414 394 long ret; 415 395 struct inode *inode = file_inode(file); 396 + unsigned int flags; 397 + unsigned int old_flags; 398 + 399 + if (!inode_owner_or_capable(inode)) 400 + return -EACCES; 401 + 402 + if (get_user(flags, (int __user *) arg)) 403 + return -EFAULT; 404 + 405 + ret = mnt_want_write_file(file); 406 + if (ret) 407 + return ret; 408 + 409 + inode_lock(inode); 410 + 411 + /* Check the capability before cred override */ 412 + ret = -EPERM; 413 + old_flags = ovl_get_inode_flags(inode); 414 + if (((flags ^ old_flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) && 415 + !capable(CAP_LINUX_IMMUTABLE)) 416 + goto unlock; 417 + 418 + ret = ovl_maybe_copy_up(file_dentry(file), O_WRONLY); 419 + if (ret) 420 + goto unlock; 421 + 422 + ret = ovl_real_ioctl(file, FS_IOC_SETFLAGS, arg); 423 + 424 + ovl_copyflags(ovl_inode_real(inode), inode); 425 + unlock: 426 + inode_unlock(inode); 427 + 428 + mnt_drop_write_file(file); 429 + 430 + return ret; 431 + 432 + } 433 + 434 + static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 435 + { 436 + long ret; 416 437 417 438 switch (cmd) { 418 439 case FS_IOC_GETFLAGS: ··· 478 383 break; 479 384 480 385 case FS_IOC_SETFLAGS: 481 - if (!inode_owner_or_capable(inode)) 482 - return -EACCES; 483 - 484 - ret = mnt_want_write_file(file); 485 - if (ret) 486 - return ret; 487 - 488 - ret = ovl_copy_up_with_data(file_dentry(file)); 489 - if (!ret) { 490 - ret = ovl_real_ioctl(file, cmd, arg); 491 - 492 - inode_lock(inode); 493 - ovl_copyflags(ovl_inode_real(inode), inode); 494 - inode_unlock(inode); 495 - } 496 - 497 - mnt_drop_write_file(file); 386 + ret = ovl_ioctl_set_flags(file, arg); 498 387 break; 499 388 500 389 default:
+2 -1
fs/overlayfs/inode.c
··· 832 832 int fsid = bylower ? oip->lowerpath->layer->fsid : 0; 833 833 bool is_dir, metacopy = false; 834 834 unsigned long ino = 0; 835 - int err = -ENOMEM; 835 + int err = oip->newinode ? -EEXIST : -ENOMEM; 836 836 837 837 if (!realinode) 838 838 realinode = d_inode(lowerdentry); ··· 917 917 return inode; 918 918 919 919 out_err: 920 + pr_warn_ratelimited("overlayfs: failed to get inode (%i)\n", err); 920 921 inode = ERR_PTR(err); 921 922 goto out; 922 923 }
+1 -1
fs/overlayfs/overlayfs.h
··· 421 421 int ovl_copy_up(struct dentry *dentry); 422 422 int ovl_copy_up_with_data(struct dentry *dentry); 423 423 int ovl_copy_up_flags(struct dentry *dentry, int flags); 424 - int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); 424 + int ovl_maybe_copy_up(struct dentry *dentry, int flags); 425 425 int ovl_copy_xattr(struct dentry *old, struct dentry *new); 426 426 int ovl_set_attr(struct dentry *upper, struct kstat *stat); 427 427 struct ovl_fh *ovl_encode_real_fh(struct dentry *real, bool is_upper);