diff options
author | Theodore Ts'o <tytso@mit.edu> | 2015-02-02 00:37:01 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-02-05 02:45:00 -0500 |
commit | fe032c422c5ba562ba9c2d316f55e258e03259c6 (patch) | |
tree | 83fb3e7bde52805f447c5f1d8ae42f46462db1c6 /fs/inode.c | |
parent | 0ae45f63d4ef8d8eeec49c7d8b44a1775fff13e8 (diff) |
vfs: add find_inode_nowait() function
Add a new function find_inode_nowait() which is an even more general
version of ilookup5_nowait(). It is designed for callers which need
very fine grained control over when the function is allowed to block
or increment the inode's reference count.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/fs/inode.c b/fs/inode.c index 4feb85cc125f..740cba79c2b9 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1284,6 +1284,56 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino) | |||
1284 | } | 1284 | } |
1285 | EXPORT_SYMBOL(ilookup); | 1285 | EXPORT_SYMBOL(ilookup); |
1286 | 1286 | ||
1287 | /** | ||
1288 | * find_inode_nowait - find an inode in the inode cache | ||
1289 | * @sb: super block of file system to search | ||
1290 | * @hashval: hash value (usually inode number) to search for | ||
1291 | * @match: callback used for comparisons between inodes | ||
1292 | * @data: opaque data pointer to pass to @match | ||
1293 | * | ||
1294 | * Search for the inode specified by @hashval and @data in the inode | ||
1295 | * cache, where the helper function @match will return 0 if the inode | ||
1296 | * does not match, 1 if the inode does match, and -1 if the search | ||
1297 | * should be stopped. The @match function must be responsible for | ||
1298 | * taking the i_lock spin_lock and checking i_state for an inode being | ||
1299 | * freed or being initialized, and incrementing the reference count | ||
1300 | * before returning 1. It also must not sleep, since it is called with | ||
1301 | * the inode_hash_lock spinlock held. | ||
1302 | * | ||
1303 | * This is a even more generalized version of ilookup5() when the | ||
1304 | * function must never block --- find_inode() can block in | ||
1305 | * __wait_on_freeing_inode() --- or when the caller can not increment | ||
1306 | * the reference count because the resulting iput() might cause an | ||
1307 | * inode eviction. The tradeoff is that the @match funtion must be | ||
1308 | * very carefully implemented. | ||
1309 | */ | ||
1310 | struct inode *find_inode_nowait(struct super_block *sb, | ||
1311 | unsigned long hashval, | ||
1312 | int (*match)(struct inode *, unsigned long, | ||
1313 | void *), | ||
1314 | void *data) | ||
1315 | { | ||
1316 | struct hlist_head *head = inode_hashtable + hash(sb, hashval); | ||
1317 | struct inode *inode, *ret_inode = NULL; | ||
1318 | int mval; | ||
1319 | |||
1320 | spin_lock(&inode_hash_lock); | ||
1321 | hlist_for_each_entry(inode, head, i_hash) { | ||
1322 | if (inode->i_sb != sb) | ||
1323 | continue; | ||
1324 | mval = match(inode, hashval, data); | ||
1325 | if (mval == 0) | ||
1326 | continue; | ||
1327 | if (mval == 1) | ||
1328 | ret_inode = inode; | ||
1329 | goto out; | ||
1330 | } | ||
1331 | out: | ||
1332 | spin_unlock(&inode_hash_lock); | ||
1333 | return ret_inode; | ||
1334 | } | ||
1335 | EXPORT_SYMBOL(find_inode_nowait); | ||
1336 | |||
1287 | int insert_inode_locked(struct inode *inode) | 1337 | int insert_inode_locked(struct inode *inode) |
1288 | { | 1338 | { |
1289 | struct super_block *sb = inode->i_sb; | 1339 | struct super_block *sb = inode->i_sb; |