mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
new helper: ihold()
Clones an existing reference to inode; caller must already hold one. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
646ec4615c
commit
7de9c6ee3e
@ -1789,9 +1789,10 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
|
||||
kfree(st);
|
||||
} else {
|
||||
/* Caching disabled. No need to get upto date stat info.
|
||||
* This dentry will be released immediately. So, just i_count++
|
||||
* This dentry will be released immediately. So, just hold the
|
||||
* inode
|
||||
*/
|
||||
atomic_inc(&old_dentry->d_inode->i_count);
|
||||
ihold(old_dentry->d_inode);
|
||||
}
|
||||
|
||||
dentry->d_op = old_dentry->d_op;
|
||||
|
@ -388,7 +388,7 @@ affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s3
|
||||
affs_adjust_checksum(inode_bh, block - be32_to_cpu(chain));
|
||||
mark_buffer_dirty_inode(inode_bh, inode);
|
||||
inode->i_nlink = 2;
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
}
|
||||
affs_fix_checksum(sb, bh);
|
||||
mark_buffer_dirty_inode(bh, inode);
|
||||
|
@ -1045,7 +1045,7 @@ static int afs_link(struct dentry *from, struct inode *dir,
|
||||
if (ret < 0)
|
||||
goto link_error;
|
||||
|
||||
atomic_inc(&vnode->vfs_inode.i_count);
|
||||
ihold(&vnode->vfs_inode);
|
||||
d_instantiate(dentry, &vnode->vfs_inode);
|
||||
key_put(key);
|
||||
_leave(" = 0");
|
||||
|
5
fs/aio.c
5
fs/aio.c
@ -1553,10 +1553,9 @@ static void aio_batch_add(struct address_space *mapping,
|
||||
*
|
||||
* When we're called, we always have a reference
|
||||
* on the file, so we must always have a reference
|
||||
* on the inode, so igrab must always just
|
||||
* bump the count and move on.
|
||||
* on the inode, so ihold() is safe here.
|
||||
*/
|
||||
atomic_inc(&mapping->host->i_count);
|
||||
ihold(mapping->host);
|
||||
abe->mapping = mapping;
|
||||
hlist_add_head(&abe->list, &batch_hash[bucket]);
|
||||
return;
|
||||
|
@ -111,10 +111,9 @@ struct file *anon_inode_getfile(const char *name,
|
||||
path.mnt = mntget(anon_inode_mnt);
|
||||
/*
|
||||
* We know the anon_inode inode count is always greater than zero,
|
||||
* so we can avoid doing an igrab() and we can use an open-coded
|
||||
* atomic_inc().
|
||||
* so ihold() is safe.
|
||||
*/
|
||||
atomic_inc(&anon_inode_inode->i_count);
|
||||
ihold(anon_inode_inode);
|
||||
|
||||
path.dentry->d_op = &anon_inodefs_dentry_operations;
|
||||
d_instantiate(path.dentry, anon_inode_inode);
|
||||
|
@ -176,7 +176,7 @@ static int bfs_link(struct dentry *old, struct inode *dir,
|
||||
inc_nlink(inode);
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
mark_inode_dirty(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
d_instantiate(new, inode);
|
||||
mutex_unlock(&info->bfs_lock);
|
||||
return 0;
|
||||
|
@ -550,7 +550,7 @@ EXPORT_SYMBOL(bdget);
|
||||
*/
|
||||
struct block_device *bdgrab(struct block_device *bdev)
|
||||
{
|
||||
atomic_inc(&bdev->bd_inode->i_count);
|
||||
ihold(bdev->bd_inode);
|
||||
return bdev;
|
||||
}
|
||||
|
||||
@ -580,7 +580,7 @@ static struct block_device *bd_acquire(struct inode *inode)
|
||||
spin_lock(&bdev_lock);
|
||||
bdev = inode->i_bdev;
|
||||
if (bdev) {
|
||||
atomic_inc(&bdev->bd_inode->i_count);
|
||||
ihold(bdev->bd_inode);
|
||||
spin_unlock(&bdev_lock);
|
||||
return bdev;
|
||||
}
|
||||
@ -591,12 +591,12 @@ static struct block_device *bd_acquire(struct inode *inode)
|
||||
spin_lock(&bdev_lock);
|
||||
if (!inode->i_bdev) {
|
||||
/*
|
||||
* We take an additional bd_inode->i_count for inode,
|
||||
* We take an additional reference to bd_inode,
|
||||
* and it's released in clear_inode() of inode.
|
||||
* So, we can access it via ->i_mapping always
|
||||
* without igrab().
|
||||
*/
|
||||
atomic_inc(&bdev->bd_inode->i_count);
|
||||
ihold(bdev->bd_inode);
|
||||
inode->i_bdev = bdev;
|
||||
inode->i_mapping = bdev->bd_inode->i_mapping;
|
||||
list_add(&inode->i_devices, &bdev->bd_inodes);
|
||||
|
@ -4758,7 +4758,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
}
|
||||
|
||||
btrfs_set_trans_block_group(trans, dir);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
err = btrfs_add_nondir(trans, dentry, inode, 1, index);
|
||||
|
||||
|
@ -276,7 +276,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
|
||||
}
|
||||
|
||||
coda_dir_update_mtime(dir_inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
d_instantiate(de, inode);
|
||||
inc_nlink(inode);
|
||||
return 0;
|
||||
|
@ -153,7 +153,7 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
|
||||
inode->i_ctime = CURRENT_TIME;
|
||||
inode_inc_link_count(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
return exofs_add_nondir(dentry, inode);
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
|
||||
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode_inc_link_count(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
err = ext2_add_link(dentry, inode);
|
||||
if (!err) {
|
||||
|
@ -2260,7 +2260,7 @@ static int ext3_link (struct dentry * old_dentry,
|
||||
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inc_nlink(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
err = ext3_add_entry(handle, dentry, inode);
|
||||
if (!err) {
|
||||
|
@ -2312,7 +2312,7 @@ static int ext4_link(struct dentry *old_dentry,
|
||||
|
||||
inode->i_ctime = ext4_current_time(inode);
|
||||
ext4_inc_count(handle, inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
err = ext4_add_entry(handle, dentry, inode);
|
||||
if (!err) {
|
||||
|
@ -255,7 +255,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
|
||||
gfs2_holder_uninit(ghs);
|
||||
gfs2_holder_uninit(ghs + 1);
|
||||
if (!error) {
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
mark_inode_dirty(inode);
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir,
|
||||
|
||||
inc_nlink(inode);
|
||||
hfsplus_instantiate(dst_dentry, inode, cnid);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
mark_inode_dirty(inode);
|
||||
sbi->file_count++;
|
||||
|
@ -320,6 +320,15 @@ void __iget(struct inode *inode)
|
||||
atomic_inc(&inode->i_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* get additional reference to inode; caller must already hold one.
|
||||
*/
|
||||
void ihold(struct inode *inode)
|
||||
{
|
||||
WARN_ON(atomic_inc_return(&inode->i_count) < 2);
|
||||
}
|
||||
EXPORT_SYMBOL(ihold);
|
||||
|
||||
static void inode_lru_list_add(struct inode *inode)
|
||||
{
|
||||
if (list_empty(&inode->i_list)) {
|
||||
|
@ -289,7 +289,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
|
||||
mutex_unlock(&f->sem);
|
||||
d_instantiate(dentry, old_dentry->d_inode);
|
||||
dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
|
||||
atomic_inc(&old_dentry->d_inode->i_count);
|
||||
ihold(old_dentry->d_inode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -864,7 +864,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
|
||||
printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret);
|
||||
/* Might as well let the VFS know */
|
||||
d_instantiate(new_dentry, old_dentry->d_inode);
|
||||
atomic_inc(&old_dentry->d_inode->i_count);
|
||||
ihold(old_dentry->d_inode);
|
||||
new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1279,7 +1279,7 @@ int txCommit(tid_t tid, /* transaction identifier */
|
||||
* lazy commit thread finishes processing
|
||||
*/
|
||||
if (tblk->xflag & COMMIT_DELETE) {
|
||||
atomic_inc(&tblk->u.ip->i_count);
|
||||
ihold(tblk->u.ip);
|
||||
/*
|
||||
* Avoid a rare deadlock
|
||||
*
|
||||
|
@ -839,7 +839,7 @@ static int jfs_link(struct dentry *old_dentry,
|
||||
ip->i_ctime = CURRENT_TIME;
|
||||
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
|
||||
mark_inode_dirty(dir);
|
||||
atomic_inc(&ip->i_count);
|
||||
ihold(ip);
|
||||
|
||||
iplist[0] = ip;
|
||||
iplist[1] = dir;
|
||||
|
@ -255,7 +255,7 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den
|
||||
|
||||
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
|
||||
inc_nlink(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
dget(dentry);
|
||||
d_instantiate(dentry, inode);
|
||||
return 0;
|
||||
|
@ -569,7 +569,7 @@ static int logfs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
return -EMLINK;
|
||||
|
||||
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
inode->i_nlink++;
|
||||
mark_inode_dirty_sync(inode);
|
||||
|
||||
|
@ -101,7 +101,7 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
|
||||
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode_inc_link_count(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
return add_nondir(dentry, inode);
|
||||
}
|
||||
|
||||
|
@ -2285,7 +2285,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
|
||||
goto slashes;
|
||||
inode = dentry->d_inode;
|
||||
if (inode)
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
error = mnt_want_write(nd.path.mnt);
|
||||
if (error)
|
||||
goto exit2;
|
||||
|
@ -1580,7 +1580,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
|
||||
d_drop(dentry);
|
||||
error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
|
||||
if (error == 0) {
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
d_add(dentry, inode);
|
||||
}
|
||||
return error;
|
||||
|
@ -54,8 +54,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
|
||||
iput(inode);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Circumvent igrab(): we know the inode is not being freed */
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
/*
|
||||
* Ensure that this dentry is invisible to d_find_alias().
|
||||
* Otherwise, it may be spliced into the tree by
|
||||
|
@ -207,7 +207,7 @@ static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
|
||||
inode->i_ctime = CURRENT_TIME;
|
||||
inode_inc_link_count(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
err = nilfs_add_nondir(dentry, inode);
|
||||
if (!err)
|
||||
|
@ -2911,8 +2911,8 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
|
||||
goto unl_upcase_iput_tmp_ino_err_out_now;
|
||||
}
|
||||
if ((sb->s_root = d_alloc_root(vol->root_ino))) {
|
||||
/* We increment i_count simulating an ntfs_iget(). */
|
||||
atomic_inc(&vol->root_ino->i_count);
|
||||
/* We grab a reference, simulating an ntfs_iget(). */
|
||||
ihold(vol->root_ino);
|
||||
ntfs_debug("Exiting, status successful.");
|
||||
/* Release the default upcase if it has no users. */
|
||||
mutex_lock(&ntfs_lock);
|
||||
|
@ -742,7 +742,7 @@ static int ocfs2_link(struct dentry *old_dentry,
|
||||
goto out_commit;
|
||||
}
|
||||
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
dentry->d_op = &ocfs2_dentry_ops;
|
||||
d_instantiate(dentry, inode);
|
||||
|
||||
|
@ -1156,7 +1156,7 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
reiserfs_update_sd(&th, inode);
|
||||
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
retval = journal_end(&th, dir->i_sb, jbegin_count);
|
||||
reiserfs_write_unlock(dir->i_sb);
|
||||
|
@ -126,7 +126,7 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
|
||||
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode_inc_link_count(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
return add_nondir(dentry, inode);
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
|
||||
|
||||
lock_2_inodes(dir, inode);
|
||||
inc_nlink(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
inode->i_ctime = ubifs_current_time(inode);
|
||||
dir->i_size += sz_change;
|
||||
dir_ui->ui_size = dir->i_size;
|
||||
|
@ -1101,7 +1101,7 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
|
||||
inc_nlink(inode);
|
||||
inode->i_ctime = current_fs_time(inode->i_sb);
|
||||
mark_inode_dirty(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
unlock_kernel();
|
||||
|
||||
|
@ -180,7 +180,7 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
|
||||
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode_inc_link_count(inode);
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
|
||||
error = ufs_add_nondir(dentry, inode);
|
||||
unlock_kernel();
|
||||
|
@ -317,7 +317,7 @@ xfs_vn_link(
|
||||
if (unlikely(error))
|
||||
return -error;
|
||||
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
d_instantiate(dentry, inode);
|
||||
return 0;
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ void xfs_mark_inode_dirty_sync(xfs_inode_t *);
|
||||
#define IHOLD(ip) \
|
||||
do { \
|
||||
ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \
|
||||
atomic_inc(&(VFS_I(ip)->i_count)); \
|
||||
ihold(VFS_I(ip)); \
|
||||
trace_xfs_ihold(ip, _THIS_IP_); \
|
||||
} while (0)
|
||||
|
||||
|
@ -2171,6 +2171,7 @@ extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin);
|
||||
|
||||
extern int inode_init_always(struct super_block *, struct inode *);
|
||||
extern void inode_init_once(struct inode *);
|
||||
extern void ihold(struct inode * inode);
|
||||
extern void iput(struct inode *);
|
||||
extern struct inode * igrab(struct inode *);
|
||||
extern ino_t iunique(struct super_block *, ino_t);
|
||||
|
@ -769,7 +769,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
|
||||
|
||||
inode = dentry->d_inode;
|
||||
if (inode)
|
||||
atomic_inc(&inode->i_count);
|
||||
ihold(inode);
|
||||
err = mnt_want_write(ipc_ns->mq_mnt);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
@ -169,7 +169,7 @@ static void get_futex_key_refs(union futex_key *key)
|
||||
|
||||
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
|
||||
case FUT_OFF_INODE:
|
||||
atomic_inc(&key->shared.inode->i_count);
|
||||
ihold(key->shared.inode);
|
||||
break;
|
||||
case FUT_OFF_MMSHARED:
|
||||
atomic_inc(&key->private.mm->mm_count);
|
||||
|
@ -1903,7 +1903,7 @@ static int shmem_link(struct dentry *old_dentry, struct inode *dir, struct dentr
|
||||
dir->i_size += BOGO_DIRENT_SIZE;
|
||||
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
|
||||
inc_nlink(inode);
|
||||
atomic_inc(&inode->i_count); /* New dentry reference */
|
||||
ihold(inode); /* New dentry reference */
|
||||
dget(dentry); /* Extra pinning count for the created dentry */
|
||||
d_instantiate(dentry, inode);
|
||||
out:
|
||||
|
@ -377,7 +377,7 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
|
||||
&socket_file_ops);
|
||||
if (unlikely(!file)) {
|
||||
/* drop dentry, keep inode */
|
||||
atomic_inc(&path.dentry->d_inode->i_count);
|
||||
ihold(path.dentry->d_inode);
|
||||
path_put(&path);
|
||||
put_unused_fd(fd);
|
||||
return -ENFILE;
|
||||
|
Loading…
Reference in New Issue
Block a user