overlayfs fixes for 5.6-rc6

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQSQHSd0lITzzeNWNm3h3BK/laaZPAUCXmufyAAKCRDh3BK/laaZ
 POXNAQDmkgiy41nUQZ3LxtGKstsgVuzFhqBq+erinBPcF1r9mQEA/xJp4uc2Q8NO
 JKZZHyWFLtAN8gGNYTCli4vrm1LoKQc=
 =JV3K
 -----END PGP SIGNATURE-----

Merge tag 'ovl-fixes-5.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs

Pull overlayfs fixes from Miklos Szeredi:
 "Fix three bugs introduced in this cycle"

* tag 'ovl-fixes-5.6-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
  ovl: fix lockdep warning for async write
  ovl: fix some xino configurations
  ovl: fix lock in ovl_llseek()
This commit is contained in:
Linus Torvalds 2020-03-13 15:17:21 -07:00
commit 2af82177af
5 changed files with 23 additions and 4 deletions

View File

@ -93,6 +93,7 @@ config OVERLAY_FS_XINO_AUTO
bool "Overlayfs: auto enable inode number mapping" bool "Overlayfs: auto enable inode number mapping"
default n default n
depends on OVERLAY_FS depends on OVERLAY_FS
depends on 64BIT
help help
If this config option is enabled then overlay filesystems will use If this config option is enabled then overlay filesystems will use
unused high bits in undelying filesystem inode numbers to map all unused high bits in undelying filesystem inode numbers to map all

View File

@ -244,6 +244,9 @@ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)
if (iocb->ki_flags & IOCB_WRITE) { if (iocb->ki_flags & IOCB_WRITE) {
struct inode *inode = file_inode(orig_iocb->ki_filp); struct inode *inode = file_inode(orig_iocb->ki_filp);
/* Actually acquired in ovl_write_iter() */
__sb_writers_acquired(file_inode(iocb->ki_filp)->i_sb,
SB_FREEZE_WRITE);
file_end_write(iocb->ki_filp); file_end_write(iocb->ki_filp);
ovl_copyattr(ovl_inode_real(inode), inode); ovl_copyattr(ovl_inode_real(inode), inode);
} }
@ -346,6 +349,9 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
goto out; goto out;
file_start_write(real.file); file_start_write(real.file);
/* Pacify lockdep, same trick as done in aio_write() */
__sb_writers_release(file_inode(real.file)->i_sb,
SB_FREEZE_WRITE);
aio_req->fd = real; aio_req->fd = real;
real.flags = 0; real.flags = 0;
aio_req->orig_iocb = iocb; aio_req->orig_iocb = iocb;

View File

@ -318,7 +318,12 @@ static inline unsigned int ovl_xino_bits(struct super_block *sb)
return ovl_same_dev(sb) ? OVL_FS(sb)->xino_mode : 0; return ovl_same_dev(sb) ? OVL_FS(sb)->xino_mode : 0;
} }
static inline int ovl_inode_lock(struct inode *inode) static inline void ovl_inode_lock(struct inode *inode)
{
mutex_lock(&OVL_I(inode)->lock);
}
static inline int ovl_inode_lock_interruptible(struct inode *inode)
{ {
return mutex_lock_interruptible(&OVL_I(inode)->lock); return mutex_lock_interruptible(&OVL_I(inode)->lock);
} }

View File

@ -1411,6 +1411,8 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
if (ofs->config.xino == OVL_XINO_ON) if (ofs->config.xino == OVL_XINO_ON)
pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n"); pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n");
ofs->xino_mode = 0; ofs->xino_mode = 0;
} else if (ofs->config.xino == OVL_XINO_OFF) {
ofs->xino_mode = -1;
} else if (ofs->config.xino == OVL_XINO_ON && ofs->xino_mode < 0) { } else if (ofs->config.xino == OVL_XINO_ON && ofs->xino_mode < 0) {
/* /*
* This is a roundup of number of bits needed for encoding * This is a roundup of number of bits needed for encoding
@ -1623,8 +1625,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
sb->s_stack_depth = 0; sb->s_stack_depth = 0;
sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_maxbytes = MAX_LFS_FILESIZE;
/* Assume underlaying fs uses 32bit inodes unless proven otherwise */ /* Assume underlaying fs uses 32bit inodes unless proven otherwise */
if (ofs->config.xino != OVL_XINO_OFF) if (ofs->config.xino != OVL_XINO_OFF) {
ofs->xino_mode = BITS_PER_LONG - 32; ofs->xino_mode = BITS_PER_LONG - 32;
if (!ofs->xino_mode) {
pr_warn("xino not supported on 32bit kernel, falling back to xino=off.\n");
ofs->config.xino = OVL_XINO_OFF;
}
}
/* alloc/destroy_inode needed for setting up traps in inode cache */ /* alloc/destroy_inode needed for setting up traps in inode cache */
sb->s_op = &ovl_super_operations; sb->s_op = &ovl_super_operations;

View File

@ -509,7 +509,7 @@ int ovl_copy_up_start(struct dentry *dentry, int flags)
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
int err; int err;
err = ovl_inode_lock(inode); err = ovl_inode_lock_interruptible(inode);
if (!err && ovl_already_copied_up_locked(dentry, flags)) { if (!err && ovl_already_copied_up_locked(dentry, flags)) {
err = 1; /* Already copied up */ err = 1; /* Already copied up */
ovl_inode_unlock(inode); ovl_inode_unlock(inode);
@ -764,7 +764,7 @@ int ovl_nlink_start(struct dentry *dentry)
return err; return err;
} }
err = ovl_inode_lock(inode); err = ovl_inode_lock_interruptible(inode);
if (err) if (err)
return err; return err;