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:
committed by
Al Viro
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);
|
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
|
* Search for the inode specified by @hashval and @data in the inode cache,
|
||||||
* -- rmk@arm.uk.linux.org
|
* 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 inode *iget5_locked(struct super_block *sb, unsigned long hashval,
|
||||||
struct hlist_head *head,
|
int (*test)(struct inode *, void *),
|
||||||
int (*test)(struct inode *, void *),
|
int (*set)(struct inode *, void *), void *data)
|
||||||
int (*set)(struct inode *, void *),
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
|
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
||||||
struct inode *inode;
|
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);
|
inode = alloc_inode(sb);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
struct inode *old;
|
struct inode *old;
|
||||||
@@ -986,16 +1008,34 @@ set_failed:
|
|||||||
destroy_inode(inode);
|
destroy_inode(inode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(iget5_locked);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* get_new_inode_fast is the fast path version of get_new_inode, see the
|
* iget_locked - obtain an inode from a mounted file system
|
||||||
* comment at iget_locked for details.
|
* @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 inode *iget_locked(struct super_block *sb, unsigned long ino)
|
||||||
struct hlist_head *head, unsigned long ino)
|
|
||||||
{
|
{
|
||||||
|
struct hlist_head *head = inode_hashtable + hash(sb, ino);
|
||||||
struct inode *inode;
|
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);
|
inode = alloc_inode(sb);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
struct inode *old;
|
struct inode *old;
|
||||||
@@ -1030,6 +1070,7 @@ static struct inode *get_new_inode_fast(struct super_block *sb,
|
|||||||
}
|
}
|
||||||
return inode;
|
return inode;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(iget_locked);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* search the inode cache for a matching inode number.
|
* search the inode cache for a matching inode number.
|
||||||
@@ -1112,74 +1153,6 @@ struct inode *igrab(struct inode *inode)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(igrab);
|
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
|
* ilookup5_nowait - search for an inode in the inode cache
|
||||||
* @sb: super block of file system to search
|
* @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
|
* @test: callback used for comparisons between inodes
|
||||||
* @data: opaque data pointer to pass to @test
|
* @data: opaque data pointer to pass to @test
|
||||||
*
|
*
|
||||||
* ilookup5() uses ifind() to search for the inode specified by @hashval and
|
* Search for the inode specified by @hashval and @data in the inode cache.
|
||||||
* @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 is returned with an incremented
|
* 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
|
* reference count.
|
||||||
* very careful what you do with the returned inode. You probably should be
|
|
||||||
* using ilookup5() instead.
|
|
||||||
*
|
*
|
||||||
* 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,
|
struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
|
||||||
int (*test)(struct inode *, void *), void *data)
|
int (*test)(struct inode *, void *), void *data)
|
||||||
{
|
{
|
||||||
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
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);
|
EXPORT_SYMBOL(ilookup5_nowait);
|
||||||
|
|
||||||
@@ -1217,24 +1190,24 @@ EXPORT_SYMBOL(ilookup5_nowait);
|
|||||||
* @test: callback used for comparisons between inodes
|
* @test: callback used for comparisons between inodes
|
||||||
* @data: opaque data pointer to pass to @test
|
* @data: opaque data pointer to pass to @test
|
||||||
*
|
*
|
||||||
* ilookup5() uses ifind() to search for the inode specified by @hashval and
|
* Search for the inode specified by @hashval and @data in the inode cache,
|
||||||
* @data in the inode cache. This is a generalized version of ilookup() for
|
* and if the inode is in the cache, return the inode with an incremented
|
||||||
* file systems where the inode number is not sufficient for unique
|
* reference count. Waits on I_NEW before returning the inode.
|
||||||
* identification of an inode.
|
|
||||||
*
|
|
||||||
* If the inode is in the cache, the inode lock is waited upon and the inode is
|
|
||||||
* returned with an incremented reference count.
|
* 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,
|
struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
|
||||||
int (*test)(struct inode *, void *), void *data)
|
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);
|
EXPORT_SYMBOL(ilookup5);
|
||||||
|
|
||||||
@@ -1243,93 +1216,24 @@ EXPORT_SYMBOL(ilookup5);
|
|||||||
* @sb: super block of file system to search
|
* @sb: super block of file system to search
|
||||||
* @ino: inode number to search for
|
* @ino: inode number to search for
|
||||||
*
|
*
|
||||||
* ilookup() uses ifind_fast() to search for the inode @ino in the inode cache.
|
* Search for the inode @ino in the inode cache, and if the inode is in the
|
||||||
* This is for file systems where the inode number is sufficient for unique
|
* cache, the inode is returned with an incremented reference count.
|
||||||
* identification of an inode.
|
|
||||||
*
|
|
||||||
* If the inode is in the cache, the inode is returned with an incremented
|
|
||||||
* reference count.
|
|
||||||
*
|
|
||||||
* Otherwise NULL is returned.
|
|
||||||
*/
|
*/
|
||||||
struct inode *ilookup(struct super_block *sb, unsigned long ino)
|
struct inode *ilookup(struct super_block *sb, unsigned long ino)
|
||||||
{
|
{
|
||||||
struct hlist_head *head = inode_hashtable + hash(sb, 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);
|
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)
|
int insert_inode_locked(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
|
Reference in New Issue
Block a user