|
@@ -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
|
|
|
|
+ *
|
|
|
|
+ * 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().
|
|
*
|
|
*
|
|
- * We no longer cache the sb_flags in i_flags - see fs.h
|
|
|
|
- * -- rmk@arm.uk.linux.org
|
|
|
|
|
|
+ * 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;
|
|
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
|
|
|
|
- * 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;
|
|
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.
|
|
@@ -1113,100 +1154,32 @@ struct inode *igrab(struct inode *inode)
|
|
EXPORT_SYMBOL(igrab);
|
|
EXPORT_SYMBOL(igrab);
|
|
|
|
|
|
/**
|
|
/**
|
|
- * ifind - internal function, you want ilookup5() or iget5().
|
|
|
|
|
|
+ * 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
|
|
- * @head: the head of the list to search
|
|
|
|
|
|
+ * @hashval: hash value (usually inode number) to search for
|
|
* @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
|
|
- * @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.
|
|
|
|
*
|
|
*
|
|
|
|
+ * 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
|
|
* If the inode is in the cache, the inode is returned with an incremented
|
|
* reference count.
|
|
* 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.
|
|
*/
|
|
*/
|
|
-static struct inode *ifind(struct super_block *sb,
|
|
|
|
- struct hlist_head *head, int (*test)(struct inode *, void *),
|
|
|
|
- void *data, const int wait)
|
|
|
|
|
|
+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;
|
|
struct inode *inode;
|
|
|
|
|
|
spin_lock(&inode_hash_lock);
|
|
spin_lock(&inode_hash_lock);
|
|
inode = find_inode(sb, head, test, data);
|
|
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);
|
|
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
|
|
|
|
- * @hashval: hash value (usually inode number) to search for
|
|
|
|
- * @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 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.
|
|
|
|
- *
|
|
|
|
- * Otherwise NULL is returned.
|
|
|
|
- *
|
|
|
|
- * 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);
|
|
|
|
|
|
|
|
- return ifind(sb, head, test, data, 0);
|
|
|
|
|
|
+ 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
|
|
|
|
- * @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.
|
|
* 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,92 +1216,23 @@ 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.
|
|
|
|
- * 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 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);
|
|
-
|
|
|
|
- return ifind_fast(sb, head, ino);
|
|
|
|
-}
|
|
|
|
-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;
|
|
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;
|
|
|
|
|
|
+ spin_lock(&inode_hash_lock);
|
|
|
|
+ inode = find_inode_fast(sb, head, ino);
|
|
|
|
+ spin_unlock(&inode_hash_lock);
|
|
|
|
|
|
- inode = ifind_fast(sb, head, ino);
|
|
|
|
if (inode)
|
|
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);
|
|
|
|
|
|
+ wait_on_inode(inode);
|
|
|
|
+ return inode;
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(iget_locked);
|
|
|
|
|
|
+EXPORT_SYMBOL(ilookup);
|
|
|
|
|
|
int insert_inode_locked(struct inode *inode)
|
|
int insert_inode_locked(struct inode *inode)
|
|
{
|
|
{
|