forked from Minki/linux
fs: simplify iget & friends
Merge get_new_inode/get_new_inode_fast into iget5_locked/iget_locked as those were the only callers. Remove the internal ifind/ifind_fast helpers - ifind_fast only had a single caller, and ifind had two callers wanting it to do different things. Also clean up the comments in this area to focus on information important to a developer trying to use it, instead of overloading them with implementation details. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
0f1b1fd86f
commit
0b2d0724e2
268
fs/inode.c
268
fs/inode.c
@ -931,20 +931,42 @@ void unlock_new_inode(struct inode *inode)
|
||||
}
|
||||
EXPORT_SYMBOL(unlock_new_inode);
|
||||
|
||||
/*
|
||||
* This is called without the inode hash lock held.. Be careful.
|
||||
/**
|
||||
* iget5_locked - obtain an inode from a mounted file system
|
||||
* @sb: super block of file system
|
||||
* @hashval: hash value (usually inode number) to get
|
||||
* @test: callback used for comparisons between inodes
|
||||
* @set: callback used to initialize a new struct inode
|
||||
* @data: opaque data pointer to pass to @test and @set
|
||||
*
|
||||
* We no longer cache the sb_flags in i_flags - see fs.h
|
||||
* -- rmk@arm.uk.linux.org
|
||||
* Search for the inode specified by @hashval and @data in the inode cache,
|
||||
* and if present it is return it with an increased reference count. This is
|
||||
* a generalized version of iget_locked() for file systems where the inode
|
||||
* number is not sufficient for unique identification of an inode.
|
||||
*
|
||||
* If the inode is not in cache, allocate a new inode and return it locked,
|
||||
* hashed, and with the I_NEW flag set. The file system gets to fill it in
|
||||
* before unlocking it via unlock_new_inode().
|
||||
*
|
||||
* Note both @test and @set are called with the inode_hash_lock held, so can't
|
||||
* sleep.
|
||||
*/
|
||||
static struct inode *get_new_inode(struct super_block *sb,
|
||||
struct hlist_head *head,
|
||||
int (*test)(struct inode *, void *),
|
||||
int (*set)(struct inode *, void *),
|
||||
void *data)
|
||||
struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
|
||||
int (*test)(struct inode *, void *),
|
||||
int (*set)(struct inode *, void *), void *data)
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
||||
struct inode *inode;
|
||||
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode(sb, head, test, data);
|
||||
spin_unlock(&inode_hash_lock);
|
||||
|
||||
if (inode) {
|
||||
wait_on_inode(inode);
|
||||
return inode;
|
||||
}
|
||||
|
||||
inode = alloc_inode(sb);
|
||||
if (inode) {
|
||||
struct inode *old;
|
||||
@ -986,16 +1008,34 @@ set_failed:
|
||||
destroy_inode(inode);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(iget5_locked);
|
||||
|
||||
/*
|
||||
* get_new_inode_fast is the fast path version of get_new_inode, see the
|
||||
* comment at iget_locked for details.
|
||||
/**
|
||||
* iget_locked - obtain an inode from a mounted file system
|
||||
* @sb: super block of file system
|
||||
* @ino: inode number to get
|
||||
*
|
||||
* Search for the inode specified by @ino in the inode cache and if present
|
||||
* return it with an increased reference count. This is for file systems
|
||||
* where the inode number is sufficient for unique identification of an inode.
|
||||
*
|
||||
* If the inode is not in cache, allocate a new inode and return it locked,
|
||||
* hashed, and with the I_NEW flag set. The file system gets to fill it in
|
||||
* before unlocking it via unlock_new_inode().
|
||||
*/
|
||||
static struct inode *get_new_inode_fast(struct super_block *sb,
|
||||
struct hlist_head *head, unsigned long ino)
|
||||
struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, ino);
|
||||
struct inode *inode;
|
||||
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode_fast(sb, head, ino);
|
||||
spin_unlock(&inode_hash_lock);
|
||||
if (inode) {
|
||||
wait_on_inode(inode);
|
||||
return inode;
|
||||
}
|
||||
|
||||
inode = alloc_inode(sb);
|
||||
if (inode) {
|
||||
struct inode *old;
|
||||
@ -1030,6 +1070,7 @@ static struct inode *get_new_inode_fast(struct super_block *sb,
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
EXPORT_SYMBOL(iget_locked);
|
||||
|
||||
/*
|
||||
* search the inode cache for a matching inode number.
|
||||
@ -1112,74 +1153,6 @@ struct inode *igrab(struct inode *inode)
|
||||
}
|
||||
EXPORT_SYMBOL(igrab);
|
||||
|
||||
/**
|
||||
* ifind - internal function, you want ilookup5() or iget5().
|
||||
* @sb: super block of file system to search
|
||||
* @head: the head of the list to search
|
||||
* @test: callback used for comparisons between inodes
|
||||
* @data: opaque data pointer to pass to @test
|
||||
* @wait: if true wait for the inode to be unlocked, if false do not
|
||||
*
|
||||
* ifind() searches for the inode specified by @data in the inode
|
||||
* cache. This is a generalized version of ifind_fast() for file systems where
|
||||
* the inode number is not sufficient for unique identification of an inode.
|
||||
*
|
||||
* If the inode is in the cache, the inode is returned with an incremented
|
||||
* reference count.
|
||||
*
|
||||
* Otherwise NULL is returned.
|
||||
*
|
||||
* Note, @test is called with the inode_hash_lock held, so can't sleep.
|
||||
*/
|
||||
static struct inode *ifind(struct super_block *sb,
|
||||
struct hlist_head *head, int (*test)(struct inode *, void *),
|
||||
void *data, const int wait)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode(sb, head, test, data);
|
||||
if (inode) {
|
||||
spin_unlock(&inode_hash_lock);
|
||||
if (likely(wait))
|
||||
wait_on_inode(inode);
|
||||
return inode;
|
||||
}
|
||||
spin_unlock(&inode_hash_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ifind_fast - internal function, you want ilookup() or iget().
|
||||
* @sb: super block of file system to search
|
||||
* @head: head of the list to search
|
||||
* @ino: inode number to search for
|
||||
*
|
||||
* ifind_fast() searches for the inode @ino in the inode cache. This is for
|
||||
* file systems where the inode number is sufficient for unique identification
|
||||
* of an inode.
|
||||
*
|
||||
* If the inode is in the cache, the inode is returned with an incremented
|
||||
* reference count.
|
||||
*
|
||||
* Otherwise NULL is returned.
|
||||
*/
|
||||
static struct inode *ifind_fast(struct super_block *sb,
|
||||
struct hlist_head *head, unsigned long ino)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode_fast(sb, head, ino);
|
||||
if (inode) {
|
||||
spin_unlock(&inode_hash_lock);
|
||||
wait_on_inode(inode);
|
||||
return inode;
|
||||
}
|
||||
spin_unlock(&inode_hash_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ilookup5_nowait - search for an inode in the inode cache
|
||||
* @sb: super block of file system to search
|
||||
@ -1187,26 +1160,26 @@ static struct inode *ifind_fast(struct super_block *sb,
|
||||
* @test: callback used for comparisons between inodes
|
||||
* @data: opaque data pointer to pass to @test
|
||||
*
|
||||
* ilookup5() uses ifind() to search for the inode specified by @hashval and
|
||||
* @data in the inode cache. This is a generalized version of ilookup() for
|
||||
* file systems where the inode number is not sufficient for unique
|
||||
* identification of an inode.
|
||||
*
|
||||
* Search for the inode specified by @hashval and @data in the inode cache.
|
||||
* If the inode is in the cache, the inode is returned with an incremented
|
||||
* reference count. Note, the inode lock is not waited upon so you have to be
|
||||
* very careful what you do with the returned inode. You probably should be
|
||||
* using ilookup5() instead.
|
||||
* reference count.
|
||||
*
|
||||
* Otherwise NULL is returned.
|
||||
* Note: I_NEW is not waited upon so you have to be very careful what you do
|
||||
* with the returned inode. You probably should be using ilookup5() instead.
|
||||
*
|
||||
* Note, @test is called with the inode_hash_lock held, so can't sleep.
|
||||
* Note: @test is called with the inode_hash_lock held, so can't sleep.
|
||||
*/
|
||||
struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
|
||||
int (*test)(struct inode *, void *), void *data)
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
||||
struct inode *inode;
|
||||
|
||||
return ifind(sb, head, test, data, 0);
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode(sb, head, test, data);
|
||||
spin_unlock(&inode_hash_lock);
|
||||
|
||||
return inode;
|
||||
}
|
||||
EXPORT_SYMBOL(ilookup5_nowait);
|
||||
|
||||
@ -1217,24 +1190,24 @@ EXPORT_SYMBOL(ilookup5_nowait);
|
||||
* @test: callback used for comparisons between inodes
|
||||
* @data: opaque data pointer to pass to @test
|
||||
*
|
||||
* ilookup5() uses ifind() to search for the inode specified by @hashval and
|
||||
* @data in the inode cache. This is a generalized version of ilookup() for
|
||||
* file systems where the inode number is not sufficient for unique
|
||||
* identification of an inode.
|
||||
*
|
||||
* If the inode is in the cache, the inode lock is waited upon and the inode is
|
||||
* Search for the inode specified by @hashval and @data in the inode cache,
|
||||
* and if the inode is in the cache, return the inode with an incremented
|
||||
* reference count. Waits on I_NEW before returning the inode.
|
||||
* returned with an incremented reference count.
|
||||
*
|
||||
* Otherwise NULL is returned.
|
||||
* This is a generalized version of ilookup() for file systems where the
|
||||
* inode number is not sufficient for unique identification of an inode.
|
||||
*
|
||||
* Note, @test is called with the inode_hash_lock held, so can't sleep.
|
||||
* Note: @test is called with the inode_hash_lock held, so can't sleep.
|
||||
*/
|
||||
struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
|
||||
int (*test)(struct inode *, void *), void *data)
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
||||
struct inode *inode = ilookup5_nowait(sb, hashval, test, data);
|
||||
|
||||
return ifind(sb, head, test, data, 1);
|
||||
if (inode)
|
||||
wait_on_inode(inode);
|
||||
return inode;
|
||||
}
|
||||
EXPORT_SYMBOL(ilookup5);
|
||||
|
||||
@ -1243,93 +1216,24 @@ EXPORT_SYMBOL(ilookup5);
|
||||
* @sb: super block of file system to search
|
||||
* @ino: inode number to search for
|
||||
*
|
||||
* ilookup() uses ifind_fast() to search for the inode @ino in the inode cache.
|
||||
* This is for file systems where the inode number is sufficient for unique
|
||||
* identification of an inode.
|
||||
*
|
||||
* If the inode is in the cache, the inode is returned with an incremented
|
||||
* reference count.
|
||||
*
|
||||
* Otherwise NULL is returned.
|
||||
* Search for the inode @ino in the inode cache, and if the inode is in the
|
||||
* cache, the inode is returned with an incremented reference count.
|
||||
*/
|
||||
struct inode *ilookup(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, ino);
|
||||
struct inode *inode;
|
||||
|
||||
return ifind_fast(sb, head, ino);
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode_fast(sb, head, ino);
|
||||
spin_unlock(&inode_hash_lock);
|
||||
|
||||
if (inode)
|
||||
wait_on_inode(inode);
|
||||
return inode;
|
||||
}
|
||||
EXPORT_SYMBOL(ilookup);
|
||||
|
||||
/**
|
||||
* iget5_locked - obtain an inode from a mounted file system
|
||||
* @sb: super block of file system
|
||||
* @hashval: hash value (usually inode number) to get
|
||||
* @test: callback used for comparisons between inodes
|
||||
* @set: callback used to initialize a new struct inode
|
||||
* @data: opaque data pointer to pass to @test and @set
|
||||
*
|
||||
* iget5_locked() uses ifind() to search for the inode specified by @hashval
|
||||
* and @data in the inode cache and if present it is returned with an increased
|
||||
* reference count. This is a generalized version of iget_locked() for file
|
||||
* systems where the inode number is not sufficient for unique identification
|
||||
* of an inode.
|
||||
*
|
||||
* If the inode is not in cache, get_new_inode() is called to allocate a new
|
||||
* inode and this is returned locked, hashed, and with the I_NEW flag set. The
|
||||
* file system gets to fill it in before unlocking it via unlock_new_inode().
|
||||
*
|
||||
* Note both @test and @set are called with the inode_hash_lock held, so can't
|
||||
* sleep.
|
||||
*/
|
||||
struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
|
||||
int (*test)(struct inode *, void *),
|
||||
int (*set)(struct inode *, void *), void *data)
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
||||
struct inode *inode;
|
||||
|
||||
inode = ifind(sb, head, test, data, 1);
|
||||
if (inode)
|
||||
return inode;
|
||||
/*
|
||||
* get_new_inode() will do the right thing, re-trying the search
|
||||
* in case it had to block at any point.
|
||||
*/
|
||||
return get_new_inode(sb, head, test, set, data);
|
||||
}
|
||||
EXPORT_SYMBOL(iget5_locked);
|
||||
|
||||
/**
|
||||
* iget_locked - obtain an inode from a mounted file system
|
||||
* @sb: super block of file system
|
||||
* @ino: inode number to get
|
||||
*
|
||||
* iget_locked() uses ifind_fast() to search for the inode specified by @ino in
|
||||
* the inode cache and if present it is returned with an increased reference
|
||||
* count. This is for file systems where the inode number is sufficient for
|
||||
* unique identification of an inode.
|
||||
*
|
||||
* If the inode is not in cache, get_new_inode_fast() is called to allocate a
|
||||
* new inode and this is returned locked, hashed, and with the I_NEW flag set.
|
||||
* The file system gets to fill it in before unlocking it via
|
||||
* unlock_new_inode().
|
||||
*/
|
||||
struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, ino);
|
||||
struct inode *inode;
|
||||
|
||||
inode = ifind_fast(sb, head, ino);
|
||||
if (inode)
|
||||
return inode;
|
||||
/*
|
||||
* get_new_inode_fast() will do the right thing, re-trying the search
|
||||
* in case it had to block at any point.
|
||||
*/
|
||||
return get_new_inode_fast(sb, head, ino);
|
||||
}
|
||||
EXPORT_SYMBOL(iget_locked);
|
||||
|
||||
int insert_inode_locked(struct inode *inode)
|
||||
{
|
||||
struct super_block *sb = inode->i_sb;
|
||||
|
Loading…
Reference in New Issue
Block a user