Commit 12debc42 authored by David Howells's avatar David Howells Committed by Linus Torvalds

iget: remove iget() and the read_inode() super op as being obsolete

Remove the old iget() call and the read_inode() superblock operation it uses
as these are really obsolete, and the use of read_inode() does not produce
proper error handling (no distinction between ENOMEM and EIO when marking an
inode bad).

Furthermore, this removes the temptation to use iget() to find an inode by
number in a filesystem from code outside that filesystem.

iget_locked() should be used instead.  A new function is added in an earlier
patch (iget_failed) that is to be called to mark an inode as bad, unlock it
and release it should the get routine fail.  Mark iget() and read_inode() as
being obsolete and remove references to them from the documentation.

Typically a filesystem will be modified such that the read_inode function
becomes an internal iget function, for example the following:

	void thingyfs_read_inode(struct inode *inode)
	{
		...
	}

would be changed into something like:

	struct inode *thingyfs_iget(struct super_block *sp, unsigned long ino)
	{
		struct inode *inode;
		int ret;

		inode = iget_locked(sb, ino);
		if (!inode)
			return ERR_PTR(-ENOMEM);
		if (!(inode->i_state & I_NEW))
			return inode;

		...
		unlock_new_inode(inode);
		return inode;
	error:
		iget_failed(inode);
		return ERR_PTR(ret);
	}

and then thingyfs_iget() would be called rather than iget(), for example:

	ret = -EINVAL;
	inode = iget(sb, ino);
	if (!inode || is_bad_inode(inode))
		goto error;

becomes:

	inode = thingyfs_iget(sb, ino);
	if (IS_ERR(inode)) {
		ret = PTR_ERR(inode);
		goto error;
	}

Note that is_bad_inode() does not need to be called.  The error returned by
thingyfs_iget() should render it unnecessary.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 755aedc1
...@@ -90,7 +90,6 @@ of the locking scheme for directory operations. ...@@ -90,7 +90,6 @@ of the locking scheme for directory operations.
prototypes: prototypes:
struct inode *(*alloc_inode)(struct super_block *sb); struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *); void (*destroy_inode)(struct inode *);
void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *); void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int); int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *); void (*put_inode) (struct inode *);
...@@ -114,7 +113,6 @@ locking rules: ...@@ -114,7 +113,6 @@ locking rules:
BKL s_lock s_umount BKL s_lock s_umount
alloc_inode: no no no alloc_inode: no no no
destroy_inode: no destroy_inode: no
read_inode: no (see below)
dirty_inode: no (must not sleep) dirty_inode: no (must not sleep)
write_inode: no write_inode: no
put_inode: no put_inode: no
...@@ -133,7 +131,6 @@ show_options: no (vfsmount->sem) ...@@ -133,7 +131,6 @@ show_options: no (vfsmount->sem)
quota_read: no no no (see below) quota_read: no no no (see below)
quota_write: no no no (see below) quota_write: no no no (see below)
->read_inode() is not a method - it's a callback used in iget().
->remount_fs() will have the s_umount lock if it's already mounted. ->remount_fs() will have the s_umount lock if it's already mounted.
When called from get_sb_single, it does NOT have the s_umount lock. When called from get_sb_single, it does NOT have the s_umount lock.
->quota_read() and ->quota_write() functions are both guaranteed to ->quota_read() and ->quota_write() functions are both guaranteed to
......
...@@ -34,8 +34,8 @@ FOO_I(inode) (see in-tree filesystems for examples). ...@@ -34,8 +34,8 @@ FOO_I(inode) (see in-tree filesystems for examples).
Make them ->alloc_inode and ->destroy_inode in your super_operations. Make them ->alloc_inode and ->destroy_inode in your super_operations.
Keep in mind that now you need explicit initialization of private data - Keep in mind that now you need explicit initialization of private data
typically in ->read_inode() and after getting an inode from new_inode(). typically between calling iget_locked() and unlocking the inode.
At some point that will become mandatory. At some point that will become mandatory.
...@@ -173,10 +173,10 @@ should be a non-blocking function that initializes those parts of a ...@@ -173,10 +173,10 @@ should be a non-blocking function that initializes those parts of a
newly created inode to allow the test function to succeed. 'data' is newly created inode to allow the test function to succeed. 'data' is
passed as an opaque value to both test and set functions. passed as an opaque value to both test and set functions.
When the inode has been created by iget5_locked(), it will be returned with When the inode has been created by iget5_locked(), it will be returned with the
the I_NEW flag set and will still be locked. read_inode has not been I_NEW flag set and will still be locked. The filesystem then needs to finalize
called so the file system still has to finalize the initialization. Once the initialization. Once the inode is initialized it must be unlocked by
the inode is initialized it must be unlocked by calling unlock_new_inode(). calling unlock_new_inode().
The filesystem is responsible for setting (and possibly testing) i_ino The filesystem is responsible for setting (and possibly testing) i_ino
when appropriate. There is also a simpler iget_locked function that when appropriate. There is also a simpler iget_locked function that
......
...@@ -203,8 +203,6 @@ struct super_operations { ...@@ -203,8 +203,6 @@ struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb); struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *); void (*destroy_inode)(struct inode *);
void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *); void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int); int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *); void (*put_inode) (struct inode *);
...@@ -242,15 +240,6 @@ or bottom half). ...@@ -242,15 +240,6 @@ or bottom half).
->alloc_inode was defined and simply undoes anything done by ->alloc_inode was defined and simply undoes anything done by
->alloc_inode. ->alloc_inode.
read_inode: this method is called to read a specific inode from the
mounted filesystem. The i_ino member in the struct inode is
initialized by the VFS to indicate which inode to read. Other
members are filled in by this method.
You can set this to NULL and use iget5_locked() instead of iget()
to read inodes. This is necessary for filesystems for which the
inode number is not sufficient to identify an inode.
dirty_inode: this method is called by the VFS to mark an inode dirty. dirty_inode: this method is called by the VFS to mark an inode dirty.
write_inode: this method is called when the VFS needs to write an write_inode: this method is called when the VFS needs to write an
...@@ -308,9 +297,9 @@ or bottom half). ...@@ -308,9 +297,9 @@ or bottom half).
quota_write: called by the VFS to write to filesystem quota file. quota_write: called by the VFS to write to filesystem quota file.
The read_inode() method is responsible for filling in the "i_op" Whoever sets up the inode is responsible for filling in the "i_op" field. This
field. This is a pointer to a "struct inode_operations" which is a pointer to a "struct inode_operations" which describes the methods that
describes the methods that can be performed on individual inodes. can be performed on individual inodes.
The Inode Object The Inode Object
......
...@@ -928,8 +928,6 @@ EXPORT_SYMBOL(ilookup); ...@@ -928,8 +928,6 @@ EXPORT_SYMBOL(ilookup);
* @set: callback used to initialize a new struct inode * @set: callback used to initialize a new struct inode
* @data: opaque data pointer to pass to @test and @set * @data: opaque data pointer to pass to @test and @set
* *
* This is iget() without the read_inode() portion of get_new_inode().
*
* iget5_locked() uses ifind() to search for the inode specified by @hashval * 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 * 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 * reference count. This is a generalized version of iget_locked() for file
...@@ -966,8 +964,6 @@ EXPORT_SYMBOL(iget5_locked); ...@@ -966,8 +964,6 @@ EXPORT_SYMBOL(iget5_locked);
* @sb: super block of file system * @sb: super block of file system
* @ino: inode number to get * @ino: inode number to get
* *
* This is iget() without the read_inode() portion of get_new_inode_fast().
*
* iget_locked() uses ifind_fast() to search for the inode specified by @ino in * 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 * 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 * count. This is for file systems where the inode number is sufficient for
......
...@@ -1241,8 +1241,6 @@ struct super_operations { ...@@ -1241,8 +1241,6 @@ struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb); struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *); void (*destroy_inode)(struct inode *);
void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *); void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int); int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *); void (*put_inode) (struct inode *);
...@@ -1767,18 +1765,6 @@ extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*te ...@@ -1767,18 +1765,6 @@ extern struct inode * iget5_locked(struct super_block *, unsigned long, int (*te
extern struct inode * iget_locked(struct super_block *, unsigned long); extern struct inode * iget_locked(struct super_block *, unsigned long);
extern void unlock_new_inode(struct inode *); extern void unlock_new_inode(struct inode *);
static inline struct inode *iget(struct super_block *sb, unsigned long ino)
{
struct inode *inode = iget_locked(sb, ino);
if (inode && (inode->i_state & I_NEW)) {
sb->s_op->read_inode(inode);
unlock_new_inode(inode);
}
return inode;
}
extern void __iget(struct inode * inode); extern void __iget(struct inode * inode);
extern void iget_failed(struct inode *); extern void iget_failed(struct inode *);
extern void clear_inode(struct inode *); extern void clear_inode(struct inode *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment