Commit 2af82177 authored by Linus Torvalds's avatar Linus Torvalds

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()
parents 78511edc c8536804
...@@ -93,6 +93,7 @@ config OVERLAY_FS_XINO_AUTO ...@@ -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
......
...@@ -244,6 +244,9 @@ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req) ...@@ -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) ...@@ -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;
......
...@@ -318,7 +318,12 @@ static inline unsigned int ovl_xino_bits(struct super_block *sb) ...@@ -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);
} }
......
...@@ -1411,6 +1411,8 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs, ...@@ -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) ...@@ -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;
......
...@@ -509,7 +509,7 @@ int ovl_copy_up_start(struct dentry *dentry, int flags) ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment