|
@@ -804,6 +804,10 @@ repeat:
|
|
__wait_on_freeing_inode(inode);
|
|
__wait_on_freeing_inode(inode);
|
|
goto repeat;
|
|
goto repeat;
|
|
}
|
|
}
|
|
|
|
+ if (unlikely(inode->i_state & I_CREATING)) {
|
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
|
+ return ERR_PTR(-ESTALE);
|
|
|
|
+ }
|
|
__iget(inode);
|
|
__iget(inode);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
return inode;
|
|
return inode;
|
|
@@ -831,6 +835,10 @@ repeat:
|
|
__wait_on_freeing_inode(inode);
|
|
__wait_on_freeing_inode(inode);
|
|
goto repeat;
|
|
goto repeat;
|
|
}
|
|
}
|
|
|
|
+ if (unlikely(inode->i_state & I_CREATING)) {
|
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
|
+ return ERR_PTR(-ESTALE);
|
|
|
|
+ }
|
|
__iget(inode);
|
|
__iget(inode);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
return inode;
|
|
return inode;
|
|
@@ -961,13 +969,26 @@ void unlock_new_inode(struct inode *inode)
|
|
lockdep_annotate_inode_mutex_key(inode);
|
|
lockdep_annotate_inode_mutex_key(inode);
|
|
spin_lock(&inode->i_lock);
|
|
spin_lock(&inode->i_lock);
|
|
WARN_ON(!(inode->i_state & I_NEW));
|
|
WARN_ON(!(inode->i_state & I_NEW));
|
|
- inode->i_state &= ~I_NEW;
|
|
|
|
|
|
+ inode->i_state &= ~I_NEW & ~I_CREATING;
|
|
smp_mb();
|
|
smp_mb();
|
|
wake_up_bit(&inode->i_state, __I_NEW);
|
|
wake_up_bit(&inode->i_state, __I_NEW);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(unlock_new_inode);
|
|
EXPORT_SYMBOL(unlock_new_inode);
|
|
|
|
|
|
|
|
+void discard_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;
|
|
|
|
+ smp_mb();
|
|
|
|
+ wake_up_bit(&inode->i_state, __I_NEW);
|
|
|
|
+ spin_unlock(&inode->i_lock);
|
|
|
|
+ iput(inode);
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(discard_new_inode);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* lock_two_nondirectories - take two i_mutexes on non-directory objects
|
|
* lock_two_nondirectories - take two i_mutexes on non-directory objects
|
|
*
|
|
*
|
|
@@ -1039,6 +1060,8 @@ again:
|
|
* Use the old inode instead of the preallocated one.
|
|
* Use the old inode instead of the preallocated one.
|
|
*/
|
|
*/
|
|
spin_unlock(&inode_hash_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
|
|
+ if (IS_ERR(old))
|
|
|
|
+ return NULL;
|
|
wait_on_inode(old);
|
|
wait_on_inode(old);
|
|
if (unlikely(inode_unhashed(old))) {
|
|
if (unlikely(inode_unhashed(old))) {
|
|
iput(old);
|
|
iput(old);
|
|
@@ -1128,6 +1151,8 @@ again:
|
|
inode = find_inode_fast(sb, head, ino);
|
|
inode = find_inode_fast(sb, head, ino);
|
|
spin_unlock(&inode_hash_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
if (inode) {
|
|
if (inode) {
|
|
|
|
+ if (IS_ERR(inode))
|
|
|
|
+ return NULL;
|
|
wait_on_inode(inode);
|
|
wait_on_inode(inode);
|
|
if (unlikely(inode_unhashed(inode))) {
|
|
if (unlikely(inode_unhashed(inode))) {
|
|
iput(inode);
|
|
iput(inode);
|
|
@@ -1165,6 +1190,8 @@ again:
|
|
*/
|
|
*/
|
|
spin_unlock(&inode_hash_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
destroy_inode(inode);
|
|
destroy_inode(inode);
|
|
|
|
+ if (IS_ERR(old))
|
|
|
|
+ return NULL;
|
|
inode = old;
|
|
inode = old;
|
|
wait_on_inode(inode);
|
|
wait_on_inode(inode);
|
|
if (unlikely(inode_unhashed(inode))) {
|
|
if (unlikely(inode_unhashed(inode))) {
|
|
@@ -1282,7 +1309,7 @@ struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
|
|
inode = find_inode(sb, head, test, data);
|
|
inode = find_inode(sb, head, test, data);
|
|
spin_unlock(&inode_hash_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
|
|
|
|
- return inode;
|
|
|
|
|
|
+ return IS_ERR(inode) ? NULL : inode;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(ilookup5_nowait);
|
|
EXPORT_SYMBOL(ilookup5_nowait);
|
|
|
|
|
|
@@ -1338,6 +1365,8 @@ again:
|
|
spin_unlock(&inode_hash_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
|
|
|
|
if (inode) {
|
|
if (inode) {
|
|
|
|
+ if (IS_ERR(inode))
|
|
|
|
+ return NULL;
|
|
wait_on_inode(inode);
|
|
wait_on_inode(inode);
|
|
if (unlikely(inode_unhashed(inode))) {
|
|
if (unlikely(inode_unhashed(inode))) {
|
|
iput(inode);
|
|
iput(inode);
|
|
@@ -1421,12 +1450,17 @@ int insert_inode_locked(struct inode *inode)
|
|
}
|
|
}
|
|
if (likely(!old)) {
|
|
if (likely(!old)) {
|
|
spin_lock(&inode->i_lock);
|
|
spin_lock(&inode->i_lock);
|
|
- inode->i_state |= I_NEW;
|
|
|
|
|
|
+ inode->i_state |= I_NEW | I_CREATING;
|
|
hlist_add_head(&inode->i_hash, head);
|
|
hlist_add_head(&inode->i_hash, head);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode->i_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
+ if (unlikely(old->i_state & I_CREATING)) {
|
|
|
|
+ spin_unlock(&old->i_lock);
|
|
|
|
+ spin_unlock(&inode_hash_lock);
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
__iget(old);
|
|
__iget(old);
|
|
spin_unlock(&old->i_lock);
|
|
spin_unlock(&old->i_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
spin_unlock(&inode_hash_lock);
|
|
@@ -1443,7 +1477,10 @@ EXPORT_SYMBOL(insert_inode_locked);
|
|
int insert_inode_locked4(struct inode *inode, unsigned long hashval,
|
|
int insert_inode_locked4(struct inode *inode, unsigned long hashval,
|
|
int (*test)(struct inode *, void *), void *data)
|
|
int (*test)(struct inode *, void *), void *data)
|
|
{
|
|
{
|
|
- struct inode *old = inode_insert5(inode, hashval, test, NULL, data);
|
|
|
|
|
|
+ struct inode *old;
|
|
|
|
+
|
|
|
|
+ inode->i_state |= I_CREATING;
|
|
|
|
+ old = inode_insert5(inode, hashval, test, NULL, data);
|
|
|
|
|
|
if (old != inode) {
|
|
if (old != inode) {
|
|
iput(old);
|
|
iput(old);
|