Message ID | 20190805180621.24769-1-kamal@canonical.com |
---|---|
State | New |
Headers | show |
Series | Fix crash on overlay fs | expand |
Oops, please insert when applying: BugLink: https://bugs.launchpad.net/bugs/1838982 -Kamal On Mon, Aug 05, 2019 at 11:06:21AM -0700, Kamal Mostafa wrote: > This reverts commit a5b1d6edcceaccbad1f964641992f820794fdfae. > > This patch is not required for Ubuntu Bionic's 4.15 kernel. > > Signed-off-by: Kamal Mostafa <kamal@canonical.com> > --- > fs/dcache.c | 2 +- > fs/inode.c | 47 ++++------------------------------------------ > include/linux/fs.h | 6 +----- > 3 files changed, 6 insertions(+), 49 deletions(-) > > diff --git a/fs/dcache.c b/fs/dcache.c > index 082353d1390e..f8cb3e31f694 100644 > --- a/fs/dcache.c > +++ b/fs/dcache.c > @@ -1901,7 +1901,7 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode) > spin_lock(&inode->i_lock); > __d_instantiate(entry, inode); > WARN_ON(!(inode->i_state & I_NEW)); > - inode->i_state &= ~I_NEW & ~I_CREATING; > + inode->i_state &= ~I_NEW; > smp_mb(); > wake_up_bit(&inode->i_state, __I_NEW); > spin_unlock(&inode->i_lock); > diff --git a/fs/inode.c b/fs/inode.c > index 9975b38edb32..7de7df08fe48 100644 > --- a/fs/inode.c > +++ b/fs/inode.c > @@ -800,10 +800,6 @@ static struct inode *find_inode(struct super_block *sb, > __wait_on_freeing_inode(inode); > goto repeat; > } > - if (unlikely(inode->i_state & I_CREATING)) { > - spin_unlock(&inode->i_lock); > - return ERR_PTR(-ESTALE); > - } > __iget(inode); > spin_unlock(&inode->i_lock); > return inode; > @@ -831,10 +827,6 @@ static struct inode *find_inode_fast(struct super_block *sb, > __wait_on_freeing_inode(inode); > goto repeat; > } > - if (unlikely(inode->i_state & I_CREATING)) { > - spin_unlock(&inode->i_lock); > - return ERR_PTR(-ESTALE); > - } > __iget(inode); > spin_unlock(&inode->i_lock); > return inode; > @@ -961,18 +953,6 @@ EXPORT_SYMBOL(lockdep_annotate_inode_mutex_key); > * inode and wake up anyone waiting for the inode to finish initialisation. > */ > void unlock_new_inode(struct inode *inode) > -{ > - lockdep_annotate_inode_mutex_key(inode); > - spin_lock(&inode->i_lock); > - WARN_ON(!(inode->i_state & I_NEW)); > - inode->i_state &= ~I_NEW & ~I_CREATING; > - smp_mb(); > - wake_up_bit(&inode->i_state, __I_NEW); > - spin_unlock(&inode->i_lock); > -} > -EXPORT_SYMBOL(unlock_new_inode); > - > -void discard_new_inode(struct inode *inode) > { > lockdep_annotate_inode_mutex_key(inode); > spin_lock(&inode->i_lock); > @@ -981,9 +961,8 @@ void discard_new_inode(struct inode *inode) > smp_mb(); > wake_up_bit(&inode->i_state, __I_NEW); > spin_unlock(&inode->i_lock); > - iput(inode); > } > -EXPORT_SYMBOL(discard_new_inode); > +EXPORT_SYMBOL(unlock_new_inode); > > /** > * lock_two_nondirectories - take two i_mutexes on non-directory objects > @@ -1129,8 +1108,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) > inode = find_inode_fast(sb, head, ino); > spin_unlock(&inode_hash_lock); > if (inode) { > - if (IS_ERR(inode)) > - return NULL; > wait_on_inode(inode); > if (unlikely(inode_unhashed(inode))) { > iput(inode); > @@ -1168,8 +1145,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) > */ > spin_unlock(&inode_hash_lock); > destroy_inode(inode); > - if (IS_ERR(old)) > - return NULL; > inode = old; > wait_on_inode(inode); > if (unlikely(inode_unhashed(inode))) { > @@ -1287,7 +1262,7 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, > inode = find_inode(sb, head, test, data); > spin_unlock(&inode_hash_lock); > > - return IS_ERR(inode) ? NULL : inode; > + return inode; > } > EXPORT_SYMBOL(ilookup5_nowait); > > @@ -1315,8 +1290,6 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval, > again: > inode = ilookup5_nowait(sb, hashval, test, data); > if (inode) { > - if (IS_ERR(inode)) > - return NULL; > wait_on_inode(inode); > if (unlikely(inode_unhashed(inode))) { > iput(inode); > @@ -1428,17 +1401,12 @@ int insert_inode_locked(struct inode *inode) > } > if (likely(!old)) { > spin_lock(&inode->i_lock); > - inode->i_state |= I_NEW | I_CREATING; > + inode->i_state |= I_NEW; > hlist_add_head(&inode->i_hash, head); > spin_unlock(&inode->i_lock); > spin_unlock(&inode_hash_lock); > return 0; > } > - if (unlikely(old->i_state & I_CREATING)) { > - spin_unlock(&old->i_lock); > - spin_unlock(&inode_hash_lock); > - return -EBUSY; > - } > __iget(old); > spin_unlock(&old->i_lock); > spin_unlock(&inode_hash_lock); > @@ -1458,8 +1426,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, > struct super_block *sb = inode->i_sb; > struct hlist_head *head = inode_hashtable + hash(sb, hashval); > > - inode->i_state |= I_CREATING; > - > while (1) { > struct inode *old = NULL; > > @@ -1478,17 +1444,12 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, > } > if (likely(!old)) { > spin_lock(&inode->i_lock); > - inode->i_state |= I_NEW | I_CREATING; > + inode->i_state |= I_NEW; > hlist_add_head(&inode->i_hash, head); > spin_unlock(&inode->i_lock); > spin_unlock(&inode_hash_lock); > return 0; > } > - if (unlikely(old->i_state & I_CREATING)) { > - spin_unlock(&old->i_lock); > - spin_unlock(&inode_hash_lock); > - return -EBUSY; > - } > __iget(old); > spin_unlock(&old->i_lock); > spin_unlock(&inode_hash_lock); > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 8fb719804555..5ea3f59eeb1a 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -2001,8 +2001,6 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) > * I_OVL_INUSE Used by overlayfs to get exclusive ownership on upper > * and work dirs among overlayfs mounts. > * > - * I_CREATING New object's inode in the middle of setting up. > - * > * Q: What is the difference between I_WILL_FREE and I_FREEING? > */ > #define I_DIRTY_SYNC (1 << 0) > @@ -2023,8 +2021,7 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) > #define __I_DIRTY_TIME_EXPIRED 12 > #define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED) > #define I_WB_SWITCH (1 << 13) > -#define I_OVL_INUSE (1 << 14) > -#define I_CREATING (1 << 15) > +#define I_OVL_INUSE (1 << 14) > > #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) > #define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME) > @@ -2902,7 +2899,6 @@ extern void lockdep_annotate_inode_mutex_key(struct inode *inode); > static inline void lockdep_annotate_inode_mutex_key(struct inode *inode) { }; > #endif > extern void unlock_new_inode(struct inode *); > -extern void discard_new_inode(struct inode *); > extern unsigned int get_next_ino(void); > extern void evict_inodes(struct super_block *sb); > > -- > 2.17.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
On 05.08.19 20:06, Kamal Mostafa wrote: > This reverts commit a5b1d6edcceaccbad1f964641992f820794fdfae. > > This patch is not required for Ubuntu Bionic's 4.15 kernel. > > Signed-off-by: Kamal Mostafa <kamal@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- Since this is what I tested. Will add BugLink on commit > fs/dcache.c | 2 +- > fs/inode.c | 47 ++++------------------------------------------ > include/linux/fs.h | 6 +----- > 3 files changed, 6 insertions(+), 49 deletions(-) > > diff --git a/fs/dcache.c b/fs/dcache.c > index 082353d1390e..f8cb3e31f694 100644 > --- a/fs/dcache.c > +++ b/fs/dcache.c > @@ -1901,7 +1901,7 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode) > spin_lock(&inode->i_lock); > __d_instantiate(entry, inode); > WARN_ON(!(inode->i_state & I_NEW)); > - inode->i_state &= ~I_NEW & ~I_CREATING; > + inode->i_state &= ~I_NEW; > smp_mb(); > wake_up_bit(&inode->i_state, __I_NEW); > spin_unlock(&inode->i_lock); > diff --git a/fs/inode.c b/fs/inode.c > index 9975b38edb32..7de7df08fe48 100644 > --- a/fs/inode.c > +++ b/fs/inode.c > @@ -800,10 +800,6 @@ static struct inode *find_inode(struct super_block *sb, > __wait_on_freeing_inode(inode); > goto repeat; > } > - if (unlikely(inode->i_state & I_CREATING)) { > - spin_unlock(&inode->i_lock); > - return ERR_PTR(-ESTALE); > - } > __iget(inode); > spin_unlock(&inode->i_lock); > return inode; > @@ -831,10 +827,6 @@ static struct inode *find_inode_fast(struct super_block *sb, > __wait_on_freeing_inode(inode); > goto repeat; > } > - if (unlikely(inode->i_state & I_CREATING)) { > - spin_unlock(&inode->i_lock); > - return ERR_PTR(-ESTALE); > - } > __iget(inode); > spin_unlock(&inode->i_lock); > return inode; > @@ -961,18 +953,6 @@ EXPORT_SYMBOL(lockdep_annotate_inode_mutex_key); > * inode and wake up anyone waiting for the inode to finish initialisation. > */ > void unlock_new_inode(struct inode *inode) > -{ > - lockdep_annotate_inode_mutex_key(inode); > - spin_lock(&inode->i_lock); > - WARN_ON(!(inode->i_state & I_NEW)); > - inode->i_state &= ~I_NEW & ~I_CREATING; > - smp_mb(); > - wake_up_bit(&inode->i_state, __I_NEW); > - spin_unlock(&inode->i_lock); > -} > -EXPORT_SYMBOL(unlock_new_inode); > - > -void discard_new_inode(struct inode *inode) > { > lockdep_annotate_inode_mutex_key(inode); > spin_lock(&inode->i_lock); > @@ -981,9 +961,8 @@ void discard_new_inode(struct inode *inode) > smp_mb(); > wake_up_bit(&inode->i_state, __I_NEW); > spin_unlock(&inode->i_lock); > - iput(inode); > } > -EXPORT_SYMBOL(discard_new_inode); > +EXPORT_SYMBOL(unlock_new_inode); > > /** > * lock_two_nondirectories - take two i_mutexes on non-directory objects > @@ -1129,8 +1108,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) > inode = find_inode_fast(sb, head, ino); > spin_unlock(&inode_hash_lock); > if (inode) { > - if (IS_ERR(inode)) > - return NULL; > wait_on_inode(inode); > if (unlikely(inode_unhashed(inode))) { > iput(inode); > @@ -1168,8 +1145,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) > */ > spin_unlock(&inode_hash_lock); > destroy_inode(inode); > - if (IS_ERR(old)) > - return NULL; > inode = old; > wait_on_inode(inode); > if (unlikely(inode_unhashed(inode))) { > @@ -1287,7 +1262,7 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, > inode = find_inode(sb, head, test, data); > spin_unlock(&inode_hash_lock); > > - return IS_ERR(inode) ? NULL : inode; > + return inode; > } > EXPORT_SYMBOL(ilookup5_nowait); > > @@ -1315,8 +1290,6 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval, > again: > inode = ilookup5_nowait(sb, hashval, test, data); > if (inode) { > - if (IS_ERR(inode)) > - return NULL; > wait_on_inode(inode); > if (unlikely(inode_unhashed(inode))) { > iput(inode); > @@ -1428,17 +1401,12 @@ int insert_inode_locked(struct inode *inode) > } > if (likely(!old)) { > spin_lock(&inode->i_lock); > - inode->i_state |= I_NEW | I_CREATING; > + inode->i_state |= I_NEW; > hlist_add_head(&inode->i_hash, head); > spin_unlock(&inode->i_lock); > spin_unlock(&inode_hash_lock); > return 0; > } > - if (unlikely(old->i_state & I_CREATING)) { > - spin_unlock(&old->i_lock); > - spin_unlock(&inode_hash_lock); > - return -EBUSY; > - } > __iget(old); > spin_unlock(&old->i_lock); > spin_unlock(&inode_hash_lock); > @@ -1458,8 +1426,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, > struct super_block *sb = inode->i_sb; > struct hlist_head *head = inode_hashtable + hash(sb, hashval); > > - inode->i_state |= I_CREATING; > - > while (1) { > struct inode *old = NULL; > > @@ -1478,17 +1444,12 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, > } > if (likely(!old)) { > spin_lock(&inode->i_lock); > - inode->i_state |= I_NEW | I_CREATING; > + inode->i_state |= I_NEW; > hlist_add_head(&inode->i_hash, head); > spin_unlock(&inode->i_lock); > spin_unlock(&inode_hash_lock); > return 0; > } > - if (unlikely(old->i_state & I_CREATING)) { > - spin_unlock(&old->i_lock); > - spin_unlock(&inode_hash_lock); > - return -EBUSY; > - } > __iget(old); > spin_unlock(&old->i_lock); > spin_unlock(&inode_hash_lock); > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 8fb719804555..5ea3f59eeb1a 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -2001,8 +2001,6 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) > * I_OVL_INUSE Used by overlayfs to get exclusive ownership on upper > * and work dirs among overlayfs mounts. > * > - * I_CREATING New object's inode in the middle of setting up. > - * > * Q: What is the difference between I_WILL_FREE and I_FREEING? > */ > #define I_DIRTY_SYNC (1 << 0) > @@ -2023,8 +2021,7 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) > #define __I_DIRTY_TIME_EXPIRED 12 > #define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED) > #define I_WB_SWITCH (1 << 13) > -#define I_OVL_INUSE (1 << 14) > -#define I_CREATING (1 << 15) > +#define I_OVL_INUSE (1 << 14) > > #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) > #define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME) > @@ -2902,7 +2899,6 @@ extern void lockdep_annotate_inode_mutex_key(struct inode *inode); > static inline void lockdep_annotate_inode_mutex_key(struct inode *inode) { }; > #endif > extern void unlock_new_inode(struct inode *); > -extern void discard_new_inode(struct inode *); > extern unsigned int get_next_ino(void); > extern void evict_inodes(struct super_block *sb); > >
diff --git a/fs/dcache.c b/fs/dcache.c index 082353d1390e..f8cb3e31f694 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1901,7 +1901,7 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode) spin_lock(&inode->i_lock); __d_instantiate(entry, inode); WARN_ON(!(inode->i_state & I_NEW)); - inode->i_state &= ~I_NEW & ~I_CREATING; + inode->i_state &= ~I_NEW; smp_mb(); wake_up_bit(&inode->i_state, __I_NEW); spin_unlock(&inode->i_lock); diff --git a/fs/inode.c b/fs/inode.c index 9975b38edb32..7de7df08fe48 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -800,10 +800,6 @@ static struct inode *find_inode(struct super_block *sb, __wait_on_freeing_inode(inode); goto repeat; } - if (unlikely(inode->i_state & I_CREATING)) { - spin_unlock(&inode->i_lock); - return ERR_PTR(-ESTALE); - } __iget(inode); spin_unlock(&inode->i_lock); return inode; @@ -831,10 +827,6 @@ static struct inode *find_inode_fast(struct super_block *sb, __wait_on_freeing_inode(inode); goto repeat; } - if (unlikely(inode->i_state & I_CREATING)) { - spin_unlock(&inode->i_lock); - return ERR_PTR(-ESTALE); - } __iget(inode); spin_unlock(&inode->i_lock); return inode; @@ -961,18 +953,6 @@ EXPORT_SYMBOL(lockdep_annotate_inode_mutex_key); * inode and wake up anyone waiting for the inode to finish initialisation. */ void unlock_new_inode(struct inode *inode) -{ - lockdep_annotate_inode_mutex_key(inode); - spin_lock(&inode->i_lock); - WARN_ON(!(inode->i_state & I_NEW)); - inode->i_state &= ~I_NEW & ~I_CREATING; - smp_mb(); - wake_up_bit(&inode->i_state, __I_NEW); - spin_unlock(&inode->i_lock); -} -EXPORT_SYMBOL(unlock_new_inode); - -void discard_new_inode(struct inode *inode) { lockdep_annotate_inode_mutex_key(inode); spin_lock(&inode->i_lock); @@ -981,9 +961,8 @@ void discard_new_inode(struct inode *inode) smp_mb(); wake_up_bit(&inode->i_state, __I_NEW); spin_unlock(&inode->i_lock); - iput(inode); } -EXPORT_SYMBOL(discard_new_inode); +EXPORT_SYMBOL(unlock_new_inode); /** * lock_two_nondirectories - take two i_mutexes on non-directory objects @@ -1129,8 +1108,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) inode = find_inode_fast(sb, head, ino); spin_unlock(&inode_hash_lock); if (inode) { - if (IS_ERR(inode)) - return NULL; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { iput(inode); @@ -1168,8 +1145,6 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino) */ spin_unlock(&inode_hash_lock); destroy_inode(inode); - if (IS_ERR(old)) - return NULL; inode = old; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { @@ -1287,7 +1262,7 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, inode = find_inode(sb, head, test, data); spin_unlock(&inode_hash_lock); - return IS_ERR(inode) ? NULL : inode; + return inode; } EXPORT_SYMBOL(ilookup5_nowait); @@ -1315,8 +1290,6 @@ struct inode *ilookup5(struct super_block *sb, unsigned long hashval, again: inode = ilookup5_nowait(sb, hashval, test, data); if (inode) { - if (IS_ERR(inode)) - return NULL; wait_on_inode(inode); if (unlikely(inode_unhashed(inode))) { iput(inode); @@ -1428,17 +1401,12 @@ int insert_inode_locked(struct inode *inode) } if (likely(!old)) { spin_lock(&inode->i_lock); - inode->i_state |= I_NEW | I_CREATING; + inode->i_state |= I_NEW; hlist_add_head(&inode->i_hash, head); spin_unlock(&inode->i_lock); spin_unlock(&inode_hash_lock); return 0; } - if (unlikely(old->i_state & I_CREATING)) { - spin_unlock(&old->i_lock); - spin_unlock(&inode_hash_lock); - return -EBUSY; - } __iget(old); spin_unlock(&old->i_lock); spin_unlock(&inode_hash_lock); @@ -1458,8 +1426,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, struct super_block *sb = inode->i_sb; struct hlist_head *head = inode_hashtable + hash(sb, hashval); - inode->i_state |= I_CREATING; - while (1) { struct inode *old = NULL; @@ -1478,17 +1444,12 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, } if (likely(!old)) { spin_lock(&inode->i_lock); - inode->i_state |= I_NEW | I_CREATING; + inode->i_state |= I_NEW; hlist_add_head(&inode->i_hash, head); spin_unlock(&inode->i_lock); spin_unlock(&inode_hash_lock); return 0; } - if (unlikely(old->i_state & I_CREATING)) { - spin_unlock(&old->i_lock); - spin_unlock(&inode_hash_lock); - return -EBUSY; - } __iget(old); spin_unlock(&old->i_lock); spin_unlock(&inode_hash_lock); diff --git a/include/linux/fs.h b/include/linux/fs.h index 8fb719804555..5ea3f59eeb1a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2001,8 +2001,6 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) * I_OVL_INUSE Used by overlayfs to get exclusive ownership on upper * and work dirs among overlayfs mounts. * - * I_CREATING New object's inode in the middle of setting up. - * * Q: What is the difference between I_WILL_FREE and I_FREEING? */ #define I_DIRTY_SYNC (1 << 0) @@ -2023,8 +2021,7 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) #define __I_DIRTY_TIME_EXPIRED 12 #define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED) #define I_WB_SWITCH (1 << 13) -#define I_OVL_INUSE (1 << 14) -#define I_CREATING (1 << 15) +#define I_OVL_INUSE (1 << 14) #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) #define I_DIRTY_ALL (I_DIRTY | I_DIRTY_TIME) @@ -2902,7 +2899,6 @@ extern void lockdep_annotate_inode_mutex_key(struct inode *inode); static inline void lockdep_annotate_inode_mutex_key(struct inode *inode) { }; #endif extern void unlock_new_inode(struct inode *); -extern void discard_new_inode(struct inode *); extern unsigned int get_next_ino(void); extern void evict_inodes(struct super_block *sb);
This reverts commit a5b1d6edcceaccbad1f964641992f820794fdfae. This patch is not required for Ubuntu Bionic's 4.15 kernel. Signed-off-by: Kamal Mostafa <kamal@canonical.com> --- fs/dcache.c | 2 +- fs/inode.c | 47 ++++------------------------------------------ include/linux/fs.h | 6 +----- 3 files changed, 6 insertions(+), 49 deletions(-)