mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-02 15:38:01 +07:00
Merge branch 'work.mkdir' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs icache updates from Al Viro: - NFS mkdir/open_by_handle race fix - analogous solution for FUSE, replacing the one currently in mainline - new primitive to be used when discarding halfway set up inodes on failed object creation; gives sane warranties re icache lookups not returning such doomed by still not freed inodes. A bunch of filesystems switched to that animal. - Miklos' fix for last cycle regression in iget5_locked(); -stable will need a slightly different variant, unfortunately. - misc bits and pieces around things icache-related (in adfs and jfs). * 'work.mkdir' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: jfs: don't bother with make_bad_inode() in ialloc() adfs: don't put inodes into icache new helper: inode_fake_hash() vfs: don't evict uninitialized inode jfs: switch to discard_new_inode() ext2: make sure that partially set up inodes won't be returned by ext2_iget() udf: switch to discard_new_inode() ufs: switch to discard_new_inode() btrfs: switch to discard_new_inode() new primitive: discard_new_inode() kill d_instantiate_no_diralias() nfs_instantiate(): prevent multiple aliases for directory inode
This commit is contained in:
commit
0ea97a2d61
@ -287,7 +287,7 @@ adfs_iget(struct super_block *sb, struct object_info *obj)
|
|||||||
ADFS_I(inode)->mmu_private = inode->i_size;
|
ADFS_I(inode)->mmu_private = inode->i_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_inode_hash(inode);
|
inode_fake_hash(inode);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return inode;
|
return inode;
|
||||||
|
@ -291,6 +291,7 @@ static void destroy_inodecache(void)
|
|||||||
static const struct super_operations adfs_sops = {
|
static const struct super_operations adfs_sops = {
|
||||||
.alloc_inode = adfs_alloc_inode,
|
.alloc_inode = adfs_alloc_inode,
|
||||||
.destroy_inode = adfs_destroy_inode,
|
.destroy_inode = adfs_destroy_inode,
|
||||||
|
.drop_inode = generic_delete_inode,
|
||||||
.write_inode = adfs_write_inode,
|
.write_inode = adfs_write_inode,
|
||||||
.put_super = adfs_put_super,
|
.put_super = adfs_put_super,
|
||||||
.statfs = adfs_statfs,
|
.statfs = adfs_statfs,
|
||||||
|
106
fs/btrfs/inode.c
106
fs/btrfs/inode.c
@ -6335,8 +6335,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
|
|||||||
location->type = BTRFS_INODE_ITEM_KEY;
|
location->type = BTRFS_INODE_ITEM_KEY;
|
||||||
|
|
||||||
ret = btrfs_insert_inode_locked(inode);
|
ret = btrfs_insert_inode_locked(inode);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
|
iput(inode);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
path->leave_spinning = 1;
|
path->leave_spinning = 1;
|
||||||
ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems);
|
ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems);
|
||||||
@ -6395,12 +6397,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
|
|||||||
return inode;
|
return inode;
|
||||||
|
|
||||||
fail_unlock:
|
fail_unlock:
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
fail:
|
fail:
|
||||||
if (dir && name)
|
if (dir && name)
|
||||||
BTRFS_I(dir)->index_cnt--;
|
BTRFS_I(dir)->index_cnt--;
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
iput(inode);
|
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6505,7 +6506,6 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
struct btrfs_root *root = BTRFS_I(dir)->root;
|
struct btrfs_root *root = BTRFS_I(dir)->root;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
int err;
|
int err;
|
||||||
int drop_inode = 0;
|
|
||||||
u64 objectid;
|
u64 objectid;
|
||||||
u64 index = 0;
|
u64 index = 0;
|
||||||
|
|
||||||
@ -6527,6 +6527,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
mode, &index);
|
mode, &index);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
|
inode = NULL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6541,31 +6542,24 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
|
|
||||||
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
|
|
||||||
err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode),
|
err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode),
|
||||||
0, index);
|
0, index);
|
||||||
if (err) {
|
if (err)
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
} else {
|
|
||||||
btrfs_update_inode(trans, root, inode);
|
btrfs_update_inode(trans, root, inode);
|
||||||
d_instantiate_new(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
}
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
btrfs_btree_balance_dirty(fs_info);
|
btrfs_btree_balance_dirty(fs_info);
|
||||||
if (drop_inode) {
|
if (err && inode) {
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
iput(inode);
|
discard_new_inode(inode);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
out_unlock_inode:
|
|
||||||
drop_inode = 1;
|
|
||||||
unlock_new_inode(inode);
|
|
||||||
goto out_unlock;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
||||||
@ -6575,7 +6569,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
|||||||
struct btrfs_trans_handle *trans;
|
struct btrfs_trans_handle *trans;
|
||||||
struct btrfs_root *root = BTRFS_I(dir)->root;
|
struct btrfs_root *root = BTRFS_I(dir)->root;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
int drop_inode_on_err = 0;
|
|
||||||
int err;
|
int err;
|
||||||
u64 objectid;
|
u64 objectid;
|
||||||
u64 index = 0;
|
u64 index = 0;
|
||||||
@ -6598,9 +6591,9 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
|||||||
mode, &index);
|
mode, &index);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
|
inode = NULL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
drop_inode_on_err = 1;
|
|
||||||
/*
|
/*
|
||||||
* If the active LSM wants to access the inode during
|
* If the active LSM wants to access the inode during
|
||||||
* d_instantiate it needs these. Smack checks to see
|
* d_instantiate it needs these. Smack checks to see
|
||||||
@ -6613,33 +6606,28 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
|||||||
|
|
||||||
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
|
|
||||||
err = btrfs_update_inode(trans, root, inode);
|
err = btrfs_update_inode(trans, root, inode);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
|
|
||||||
err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode),
|
err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode),
|
||||||
0, index);
|
0, index);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
|
|
||||||
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
|
BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
|
||||||
d_instantiate_new(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
if (err && drop_inode_on_err) {
|
if (err && inode) {
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
iput(inode);
|
discard_new_inode(inode);
|
||||||
}
|
}
|
||||||
btrfs_btree_balance_dirty(fs_info);
|
btrfs_btree_balance_dirty(fs_info);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
out_unlock_inode:
|
|
||||||
unlock_new_inode(inode);
|
|
||||||
goto out_unlock;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
||||||
@ -6748,6 +6736,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
S_IFDIR | mode, &index);
|
S_IFDIR | mode, &index);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
|
inode = NULL;
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6758,34 +6747,30 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
|
|
||||||
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_fail_inode;
|
goto out_fail;
|
||||||
|
|
||||||
btrfs_i_size_write(BTRFS_I(inode), 0);
|
btrfs_i_size_write(BTRFS_I(inode), 0);
|
||||||
err = btrfs_update_inode(trans, root, inode);
|
err = btrfs_update_inode(trans, root, inode);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_fail_inode;
|
goto out_fail;
|
||||||
|
|
||||||
err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),
|
err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode),
|
||||||
dentry->d_name.name,
|
dentry->d_name.name,
|
||||||
dentry->d_name.len, 0, index);
|
dentry->d_name.len, 0, index);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_fail_inode;
|
goto out_fail;
|
||||||
|
|
||||||
d_instantiate_new(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
drop_on_err = 0;
|
drop_on_err = 0;
|
||||||
|
|
||||||
out_fail:
|
out_fail:
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
if (drop_on_err) {
|
if (err && inode) {
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
iput(inode);
|
discard_new_inode(inode);
|
||||||
}
|
}
|
||||||
btrfs_btree_balance_dirty(fs_info);
|
btrfs_btree_balance_dirty(fs_info);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
out_fail_inode:
|
|
||||||
unlock_new_inode(inode);
|
|
||||||
goto out_fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static noinline int uncompress_inline(struct btrfs_path *path,
|
static noinline int uncompress_inline(struct btrfs_path *path,
|
||||||
@ -10115,7 +10100,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|||||||
struct btrfs_key key;
|
struct btrfs_key key;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
int err;
|
int err;
|
||||||
int drop_inode = 0;
|
|
||||||
u64 objectid;
|
u64 objectid;
|
||||||
u64 index = 0;
|
u64 index = 0;
|
||||||
int name_len;
|
int name_len;
|
||||||
@ -10148,6 +10132,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|||||||
objectid, S_IFLNK|S_IRWXUGO, &index);
|
objectid, S_IFLNK|S_IRWXUGO, &index);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
|
inode = NULL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10164,12 +10149,12 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|||||||
|
|
||||||
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
|
|
||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path) {
|
if (!path) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
key.objectid = btrfs_ino(BTRFS_I(inode));
|
key.objectid = btrfs_ino(BTRFS_I(inode));
|
||||||
key.offset = 0;
|
key.offset = 0;
|
||||||
@ -10179,7 +10164,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|||||||
datasize);
|
datasize);
|
||||||
if (err) {
|
if (err) {
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
goto out_unlock_inode;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
leaf = path->nodes[0];
|
leaf = path->nodes[0];
|
||||||
ei = btrfs_item_ptr(leaf, path->slots[0],
|
ei = btrfs_item_ptr(leaf, path->slots[0],
|
||||||
@ -10211,26 +10196,19 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|||||||
if (!err)
|
if (!err)
|
||||||
err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry,
|
err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry,
|
||||||
BTRFS_I(inode), 0, index);
|
BTRFS_I(inode), 0, index);
|
||||||
if (err) {
|
if (err)
|
||||||
drop_inode = 1;
|
goto out_unlock;
|
||||||
goto out_unlock_inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_instantiate_new(dentry, inode);
|
d_instantiate_new(dentry, inode);
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
if (drop_inode) {
|
if (err && inode) {
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
iput(inode);
|
discard_new_inode(inode);
|
||||||
}
|
}
|
||||||
btrfs_btree_balance_dirty(fs_info);
|
btrfs_btree_balance_dirty(fs_info);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
out_unlock_inode:
|
|
||||||
drop_inode = 1;
|
|
||||||
unlock_new_inode(inode);
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
|
static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
|
||||||
@ -10439,14 +10417,14 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
|
|
||||||
ret = btrfs_init_inode_security(trans, inode, dir, NULL);
|
ret = btrfs_init_inode_security(trans, inode, dir, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_inode;
|
goto out;
|
||||||
|
|
||||||
ret = btrfs_update_inode(trans, root, inode);
|
ret = btrfs_update_inode(trans, root, inode);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_inode;
|
goto out;
|
||||||
ret = btrfs_orphan_add(trans, BTRFS_I(inode));
|
ret = btrfs_orphan_add(trans, BTRFS_I(inode));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_inode;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We set number of links to 0 in btrfs_new_inode(), and here we set
|
* We set number of links to 0 in btrfs_new_inode(), and here we set
|
||||||
@ -10456,21 +10434,15 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
* d_tmpfile() -> inode_dec_link_count() -> drop_nlink()
|
* d_tmpfile() -> inode_dec_link_count() -> drop_nlink()
|
||||||
*/
|
*/
|
||||||
set_nlink(inode, 1);
|
set_nlink(inode, 1);
|
||||||
unlock_new_inode(inode);
|
|
||||||
d_tmpfile(dentry, inode);
|
d_tmpfile(dentry, inode);
|
||||||
|
unlock_new_inode(inode);
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
btrfs_end_transaction(trans);
|
btrfs_end_transaction(trans);
|
||||||
if (ret)
|
if (ret && inode)
|
||||||
iput(inode);
|
discard_new_inode(inode);
|
||||||
btrfs_btree_balance_dirty(fs_info);
|
btrfs_btree_balance_dirty(fs_info);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
out_inode:
|
|
||||||
unlock_new_inode(inode);
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((const))
|
__attribute__((const))
|
||||||
|
29
fs/dcache.c
29
fs/dcache.c
@ -1889,40 +1889,13 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode)
|
|||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
__d_instantiate(entry, inode);
|
__d_instantiate(entry, inode);
|
||||||
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(d_instantiate_new);
|
EXPORT_SYMBOL(d_instantiate_new);
|
||||||
|
|
||||||
/**
|
|
||||||
* d_instantiate_no_diralias - instantiate a non-aliased dentry
|
|
||||||
* @entry: dentry to complete
|
|
||||||
* @inode: inode to attach to this dentry
|
|
||||||
*
|
|
||||||
* Fill in inode information in the entry. If a directory alias is found, then
|
|
||||||
* return an error (and drop inode). Together with d_materialise_unique() this
|
|
||||||
* guarantees that a directory inode may never have more than one alias.
|
|
||||||
*/
|
|
||||||
int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode)
|
|
||||||
{
|
|
||||||
BUG_ON(!hlist_unhashed(&entry->d_u.d_alias));
|
|
||||||
|
|
||||||
security_d_instantiate(entry, inode);
|
|
||||||
spin_lock(&inode->i_lock);
|
|
||||||
if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) {
|
|
||||||
spin_unlock(&inode->i_lock);
|
|
||||||
iput(inode);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
__d_instantiate(entry, inode);
|
|
||||||
spin_unlock(&inode->i_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(d_instantiate_no_diralias);
|
|
||||||
|
|
||||||
struct dentry *d_make_root(struct inode *root_inode)
|
struct dentry *d_make_root(struct inode *root_inode)
|
||||||
{
|
{
|
||||||
struct dentry *res = NULL;
|
struct dentry *res = NULL;
|
||||||
|
@ -611,8 +611,7 @@ struct inode *ext2_new_inode(struct inode *dir, umode_t mode,
|
|||||||
dquot_drop(inode);
|
dquot_drop(inode);
|
||||||
inode->i_flags |= S_NOQUOTA;
|
inode->i_flags |= S_NOQUOTA;
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -45,8 +45,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,8 +191,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry,
|
|||||||
|
|
||||||
out_fail:
|
out_fail:
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput (inode);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,8 +259,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
|
|||||||
out_fail:
|
out_fail:
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
out_dir:
|
out_dir:
|
||||||
inode_dec_link_count(dir);
|
inode_dec_link_count(dir);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -539,6 +539,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
|
|||||||
{
|
{
|
||||||
struct fuse_entry_out outarg;
|
struct fuse_entry_out outarg;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
struct dentry *d;
|
||||||
int err;
|
int err;
|
||||||
struct fuse_forget_link *forget;
|
struct fuse_forget_link *forget;
|
||||||
|
|
||||||
@ -570,11 +571,17 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
|
|||||||
}
|
}
|
||||||
kfree(forget);
|
kfree(forget);
|
||||||
|
|
||||||
err = d_instantiate_no_diralias(entry, inode);
|
d_drop(entry);
|
||||||
if (err)
|
d = d_splice_alias(inode, entry);
|
||||||
return err;
|
if (IS_ERR(d))
|
||||||
|
return PTR_ERR(d);
|
||||||
|
|
||||||
fuse_change_entry_timeout(entry, &outarg);
|
if (d) {
|
||||||
|
fuse_change_entry_timeout(d, &outarg);
|
||||||
|
dput(d);
|
||||||
|
} else {
|
||||||
|
fuse_change_entry_timeout(entry, &outarg);
|
||||||
|
}
|
||||||
fuse_invalidate_attr(dir);
|
fuse_invalidate_attr(dir);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -541,7 +541,7 @@ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
|
|||||||
HFS_I(inode)->rsrc_inode = dir;
|
HFS_I(inode)->rsrc_inode = dir;
|
||||||
HFS_I(dir)->rsrc_inode = inode;
|
HFS_I(dir)->rsrc_inode = inode;
|
||||||
igrab(dir);
|
igrab(dir);
|
||||||
hlist_add_fake(&inode->i_hash);
|
inode_fake_hash(inode);
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
dont_mount(dentry);
|
dont_mount(dentry);
|
||||||
out:
|
out:
|
||||||
|
53
fs/inode.c
53
fs/inode.c
@ -804,6 +804,10 @@ static struct inode *find_inode(struct super_block *sb,
|
|||||||
__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 @@ static struct inode *find_inode_fast(struct super_block *sb,
|
|||||||
__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
|
||||||
*
|
*
|
||||||
@ -1029,6 +1050,7 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval,
|
|||||||
{
|
{
|
||||||
struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
|
struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval);
|
||||||
struct inode *old;
|
struct inode *old;
|
||||||
|
bool creating = inode->i_state & I_CREATING;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
spin_lock(&inode_hash_lock);
|
spin_lock(&inode_hash_lock);
|
||||||
@ -1039,6 +1061,8 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval,
|
|||||||
* 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);
|
||||||
@ -1060,6 +1084,8 @@ struct inode *inode_insert5(struct inode *inode, unsigned long hashval,
|
|||||||
inode->i_state |= I_NEW;
|
inode->i_state |= I_NEW;
|
||||||
hlist_add_head(&inode->i_hash, head);
|
hlist_add_head(&inode->i_hash, head);
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
|
if (!creating)
|
||||||
|
inode_sb_list_add(inode);
|
||||||
unlock:
|
unlock:
|
||||||
spin_unlock(&inode_hash_lock);
|
spin_unlock(&inode_hash_lock);
|
||||||
|
|
||||||
@ -1094,12 +1120,13 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
|
|||||||
struct inode *inode = ilookup5(sb, hashval, test, data);
|
struct inode *inode = ilookup5(sb, hashval, test, data);
|
||||||
|
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
struct inode *new = new_inode(sb);
|
struct inode *new = alloc_inode(sb);
|
||||||
|
|
||||||
if (new) {
|
if (new) {
|
||||||
|
new->i_state = 0;
|
||||||
inode = inode_insert5(new, hashval, test, set, data);
|
inode = inode_insert5(new, hashval, test, set, data);
|
||||||
if (unlikely(inode != new))
|
if (unlikely(inode != new))
|
||||||
iput(new);
|
destroy_inode(new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return inode;
|
return inode;
|
||||||
@ -1128,6 +1155,8 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
|||||||
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 +1194,8 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
|||||||
*/
|
*/
|
||||||
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 +1313,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 +1369,8 @@ struct inode *ilookup(struct super_block *sb, unsigned long 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);
|
||||||
@ -1421,12 +1454,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 +1481,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);
|
||||||
|
@ -491,13 +491,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
|
|||||||
/* release the page */
|
/* release the page */
|
||||||
release_metapage(mp);
|
release_metapage(mp);
|
||||||
|
|
||||||
/*
|
inode_fake_hash(ip);
|
||||||
* __mark_inode_dirty expects inodes to be hashed. Since we don't
|
|
||||||
* want special inodes in the fileset inode space, we make them
|
|
||||||
* appear hashed, but do not put on any lists. hlist_del()
|
|
||||||
* will work fine and require no locking.
|
|
||||||
*/
|
|
||||||
hlist_add_fake(&ip->i_hash);
|
|
||||||
|
|
||||||
return (ip);
|
return (ip);
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
|
|||||||
inode = new_inode(sb);
|
inode = new_inode(sb);
|
||||||
if (!inode) {
|
if (!inode) {
|
||||||
jfs_warn("ialloc: new_inode returned NULL!");
|
jfs_warn("ialloc: new_inode returned NULL!");
|
||||||
rc = -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jfs_inode = JFS_IP(inode);
|
jfs_inode = JFS_IP(inode);
|
||||||
@ -70,8 +69,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
|
|||||||
rc = diAlloc(parent, S_ISDIR(mode), inode);
|
rc = diAlloc(parent, S_ISDIR(mode), inode);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
jfs_warn("ialloc: diAlloc returned %d!", rc);
|
jfs_warn("ialloc: diAlloc returned %d!", rc);
|
||||||
if (rc == -EIO)
|
|
||||||
make_bad_inode(inode);
|
|
||||||
goto fail_put;
|
goto fail_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,9 +138,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
|
|||||||
dquot_drop(inode);
|
dquot_drop(inode);
|
||||||
inode->i_flags |= S_NOQUOTA;
|
inode->i_flags |= S_NOQUOTA;
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
|
return ERR_PTR(rc);
|
||||||
|
|
||||||
fail_put:
|
fail_put:
|
||||||
iput(inode);
|
iput(inode);
|
||||||
fail:
|
|
||||||
return ERR_PTR(rc);
|
return ERR_PTR(rc);
|
||||||
}
|
}
|
||||||
|
@ -175,8 +175,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, umode_t mode,
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
free_ea_wmap(ip);
|
free_ea_wmap(ip);
|
||||||
clear_nlink(ip);
|
clear_nlink(ip);
|
||||||
unlock_new_inode(ip);
|
discard_new_inode(ip);
|
||||||
iput(ip);
|
|
||||||
} else {
|
} else {
|
||||||
d_instantiate_new(dentry, ip);
|
d_instantiate_new(dentry, ip);
|
||||||
}
|
}
|
||||||
@ -309,8 +308,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
free_ea_wmap(ip);
|
free_ea_wmap(ip);
|
||||||
clear_nlink(ip);
|
clear_nlink(ip);
|
||||||
unlock_new_inode(ip);
|
discard_new_inode(ip);
|
||||||
iput(ip);
|
|
||||||
} else {
|
} else {
|
||||||
d_instantiate_new(dentry, ip);
|
d_instantiate_new(dentry, ip);
|
||||||
}
|
}
|
||||||
@ -1054,8 +1052,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
free_ea_wmap(ip);
|
free_ea_wmap(ip);
|
||||||
clear_nlink(ip);
|
clear_nlink(ip);
|
||||||
unlock_new_inode(ip);
|
discard_new_inode(ip);
|
||||||
iput(ip);
|
|
||||||
} else {
|
} else {
|
||||||
d_instantiate_new(dentry, ip);
|
d_instantiate_new(dentry, ip);
|
||||||
}
|
}
|
||||||
@ -1441,8 +1438,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||||||
if (rc) {
|
if (rc) {
|
||||||
free_ea_wmap(ip);
|
free_ea_wmap(ip);
|
||||||
clear_nlink(ip);
|
clear_nlink(ip);
|
||||||
unlock_new_inode(ip);
|
discard_new_inode(ip);
|
||||||
iput(ip);
|
|
||||||
} else {
|
} else {
|
||||||
d_instantiate_new(dentry, ip);
|
d_instantiate_new(dentry, ip);
|
||||||
}
|
}
|
||||||
|
@ -581,7 +581,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
inode->i_ino = 0;
|
inode->i_ino = 0;
|
||||||
inode->i_size = i_size_read(sb->s_bdev->bd_inode);
|
inode->i_size = i_size_read(sb->s_bdev->bd_inode);
|
||||||
inode->i_mapping->a_ops = &jfs_metapage_aops;
|
inode->i_mapping->a_ops = &jfs_metapage_aops;
|
||||||
hlist_add_fake(&inode->i_hash);
|
inode_fake_hash(inode);
|
||||||
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
|
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
|
||||||
|
|
||||||
sbi->direct_inode = inode;
|
sbi->direct_inode = inode;
|
||||||
|
@ -1643,6 +1643,7 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
|||||||
struct dentry *parent = dget_parent(dentry);
|
struct dentry *parent = dget_parent(dentry);
|
||||||
struct inode *dir = d_inode(parent);
|
struct inode *dir = d_inode(parent);
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
struct dentry *d;
|
||||||
int error = -EACCES;
|
int error = -EACCES;
|
||||||
|
|
||||||
d_drop(dentry);
|
d_drop(dentry);
|
||||||
@ -1664,10 +1665,12 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
|
|||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
|
inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
|
||||||
error = PTR_ERR(inode);
|
d = d_splice_alias(inode, dentry);
|
||||||
if (IS_ERR(inode))
|
if (IS_ERR(d)) {
|
||||||
|
error = PTR_ERR(d);
|
||||||
goto out_error;
|
goto out_error;
|
||||||
d_add(dentry, inode);
|
}
|
||||||
|
dput(d);
|
||||||
out:
|
out:
|
||||||
dput(parent);
|
dput(parent);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -602,8 +602,7 @@ static int udf_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||||||
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
|
fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
|
||||||
if (unlikely(!fi)) {
|
if (unlikely(!fi)) {
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
|
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
|
||||||
@ -694,8 +693,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
|
fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
|
||||||
if (!fi) {
|
if (!fi) {
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
set_nlink(inode, 2);
|
set_nlink(inode, 2);
|
||||||
@ -713,8 +711,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||||||
if (!fi) {
|
if (!fi) {
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
|
cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
|
||||||
@ -1041,8 +1038,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
|
|||||||
out_no_entry:
|
out_no_entry:
|
||||||
up_write(&iinfo->i_data_sem);
|
up_write(&iinfo->i_data_sem);
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,8 +343,7 @@ struct inode *ufs_new_inode(struct inode *dir, umode_t mode)
|
|||||||
fail_remove_inode:
|
fail_remove_inode:
|
||||||
mutex_unlock(&sbi->s_lock);
|
mutex_unlock(&sbi->s_lock);
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
UFSD("EXIT (FAILED): err %d\n", err);
|
UFSD("EXIT (FAILED): err %d\n", err);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
failed:
|
failed:
|
||||||
|
@ -43,8 +43,7 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +141,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry,
|
|||||||
|
|
||||||
out_fail:
|
out_fail:
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput(inode);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,8 +196,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
|
|||||||
out_fail:
|
out_fail:
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
inode_dec_link_count(inode);
|
inode_dec_link_count(inode);
|
||||||
unlock_new_inode(inode);
|
discard_new_inode(inode);
|
||||||
iput (inode);
|
|
||||||
out_dir:
|
out_dir:
|
||||||
inode_dec_link_count(dir);
|
inode_dec_link_count(dir);
|
||||||
return err;
|
return err;
|
||||||
|
@ -1253,7 +1253,7 @@ xfs_setup_inode(
|
|||||||
|
|
||||||
inode_sb_list_add(inode);
|
inode_sb_list_add(inode);
|
||||||
/* make the inode look hashed for the writeback code */
|
/* make the inode look hashed for the writeback code */
|
||||||
hlist_add_fake(&inode->i_hash);
|
inode_fake_hash(inode);
|
||||||
|
|
||||||
inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid);
|
inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid);
|
||||||
inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid);
|
inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid);
|
||||||
|
@ -227,7 +227,6 @@ extern void d_instantiate(struct dentry *, struct inode *);
|
|||||||
extern void d_instantiate_new(struct dentry *, struct inode *);
|
extern void d_instantiate_new(struct dentry *, struct inode *);
|
||||||
extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
|
extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
|
||||||
extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *);
|
extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *);
|
||||||
extern int d_instantiate_no_diralias(struct dentry *, struct inode *);
|
|
||||||
extern void __d_drop(struct dentry *dentry);
|
extern void __d_drop(struct dentry *dentry);
|
||||||
extern void d_drop(struct dentry *dentry);
|
extern void d_drop(struct dentry *dentry);
|
||||||
extern void d_delete(struct dentry *);
|
extern void d_delete(struct dentry *);
|
||||||
|
@ -687,6 +687,17 @@ static inline int inode_unhashed(struct inode *inode)
|
|||||||
return hlist_unhashed(&inode->i_hash);
|
return hlist_unhashed(&inode->i_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* __mark_inode_dirty expects inodes to be hashed. Since we don't
|
||||||
|
* want special inodes in the fileset inode space, we make them
|
||||||
|
* appear hashed, but do not put on any lists. hlist_del()
|
||||||
|
* will work fine and require no locking.
|
||||||
|
*/
|
||||||
|
static inline void inode_fake_hash(struct inode *inode)
|
||||||
|
{
|
||||||
|
hlist_add_fake(&inode->i_hash);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* inode->i_mutex nesting subclasses for the lock validator:
|
* inode->i_mutex nesting subclasses for the lock validator:
|
||||||
*
|
*
|
||||||
@ -2017,6 +2028,8 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
|
|||||||
* I_OVL_INUSE Used by overlayfs to get exclusive ownership on upper
|
* I_OVL_INUSE Used by overlayfs to get exclusive ownership on upper
|
||||||
* and work dirs among overlayfs mounts.
|
* 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?
|
* Q: What is the difference between I_WILL_FREE and I_FREEING?
|
||||||
*/
|
*/
|
||||||
#define I_DIRTY_SYNC (1 << 0)
|
#define I_DIRTY_SYNC (1 << 0)
|
||||||
@ -2037,7 +2050,8 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
|
|||||||
#define __I_DIRTY_TIME_EXPIRED 12
|
#define __I_DIRTY_TIME_EXPIRED 12
|
||||||
#define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED)
|
#define I_DIRTY_TIME_EXPIRED (1 << __I_DIRTY_TIME_EXPIRED)
|
||||||
#define I_WB_SWITCH (1 << 13)
|
#define I_WB_SWITCH (1 << 13)
|
||||||
#define I_OVL_INUSE (1 << 14)
|
#define I_OVL_INUSE (1 << 14)
|
||||||
|
#define I_CREATING (1 << 15)
|
||||||
|
|
||||||
#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
|
#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
|
||||||
#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
|
#define I_DIRTY (I_DIRTY_INODE | I_DIRTY_PAGES)
|
||||||
@ -2919,6 +2933,7 @@ extern void lockdep_annotate_inode_mutex_key(struct inode *inode);
|
|||||||
static inline void lockdep_annotate_inode_mutex_key(struct inode *inode) { };
|
static inline void lockdep_annotate_inode_mutex_key(struct inode *inode) { };
|
||||||
#endif
|
#endif
|
||||||
extern void unlock_new_inode(struct inode *);
|
extern void unlock_new_inode(struct inode *);
|
||||||
|
extern void discard_new_inode(struct inode *);
|
||||||
extern unsigned int get_next_ino(void);
|
extern unsigned int get_next_ino(void);
|
||||||
extern void evict_inodes(struct super_block *sb);
|
extern void evict_inodes(struct super_block *sb);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user