Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Christoph Lameter
On Mon, 1 Oct 2007, Andrew Morton wrote:

> Ah.  So the already-dropped
> slub-exploit-page-mobility-to-increase-allocation-order.patch was the
> culprit?

Yes without that patch SLUB will no longer take special action if antifrag 
is around.

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Andrew Morton
On Mon, 1 Oct 2007 14:38:55 -0700 (PDT)
Christoph Lameter <[EMAIL PROTECTED]> wrote:

> On Mon, 1 Oct 2007, Andrew Morton wrote:
> 
> > Do slab and slub use the same underlying page size for each slab?
> 
> SLAB cannot pack objects as dense as SLUB and they have different 
> algorithm to make the choice of order. Thus the number of objects per slab 
> may vary between SLAB and SLUB and therefore also the choice of order to 
> store these objects.
> 
> > Single data point: the CONFIG_SLAB boxes which I have access to here are
> > using order-0 for radix_tree_node, so they won't be failing in the way in
> > which Peter's machine is.
> 
> Upstream SLUB uses order 0 allocations for the radix tree.

OK, that's a relief.

> MM varies 
> because the use of higher order allocs is more loose if the mobility 
> algorithms are found to be active:
> 
> 2.6.23-rc8:
> 
> Name   Objects ObjsizeSpace Slabs/Part/Cpu  O/S O %Fr %Ef 
> Flg\
> radix_tree_node  14281 552 9.9M 2432/948/17 0  38  79

Ah.  So the already-dropped
slub-exploit-page-mobility-to-increase-allocation-order.patch was the
culprit?
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Christoph Lameter
On Mon, 1 Oct 2007, Andrew Morton wrote:

> Do slab and slub use the same underlying page size for each slab?

SLAB cannot pack objects as dense as SLUB and they have different 
algorithm to make the choice of order. Thus the number of objects per slab 
may vary between SLAB and SLUB and therefore also the choice of order to 
store these objects.

> Single data point: the CONFIG_SLAB boxes which I have access to here are
> using order-0 for radix_tree_node, so they won't be failing in the way in
> which Peter's machine is.

Upstream SLUB uses order 0 allocations for the radix tree. MM varies 
because the use of higher order allocs is more loose if the mobility 
algorithms are found to be active:

2.6.23-rc8:

Name   Objects ObjsizeSpace Slabs/Part/Cpu  O/S O %Fr %Ef 
Flg\
radix_tree_node  14281 552 9.9M 2432/948/17 0  38  79

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Andrew Morton
On Mon, 1 Oct 2007 13:55:29 -0700 (PDT)
Christoph Lameter <[EMAIL PROTECTED]> wrote:

> On Sat, 29 Sep 2007, Andrew Morton wrote:
> 
> > > atomic allocations. And with SLUB using higher order pages, atomic !0
> > > order allocations will be very very common.
> > 
> > Oh OK.
> > 
> > I thought we'd already fixed slub so that it didn't do that.  Maybe that
> > fix is in -mm but I don't think so.
> > 
> > Trying to do atomic order-1 allocations on behalf of arbitray slab caches
> > just won't fly - this is a significant degradation in kernel reliability,
> > as you've very easily demonstrated.
> 
> Ummm... SLAB also does order 1 allocations. We have always done them.
> 
> See mm/slab.c
> 
> /*
>  * Do not go above this order unless 0 objects fit into the slab.
>  */
> #define BREAK_GFP_ORDER_HI  1
> #define BREAK_GFP_ORDER_LO  0
> static int slab_break_gfp_order = BREAK_GFP_ORDER_LO;

Do slab and slub use the same underlying page size for each slab?

Single data point: the CONFIG_SLAB boxes which I have access to here are
using order-0 for radix_tree_node, so they won't be failing in the way in
which Peter's machine is.

I've never ever before seen reports of page allocation failures in the
radix-tree node allocation code, and that's the bottom line.  This is just
a drop-dead must-fix show-stopping bug.  We cannot rely upon atomic order-1
allocations succeeding so we cannot use them for radix-tree nodes.  Nor for
lots of other things which we have no chance of identifying.

Peter, is this bug -mm only, or is 2.6.23 similarly failing?
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Christoph Lameter
On Fri, 28 Sep 2007, Mel Gorman wrote:

> Minimally, SLUB by default should continue to use order-0 pages. Peter has
> managed to bust order-1 pages with mem=128MB. Admittedly, it was a really
> hostile workload but the point remains. It was artifically worked around
> with min_free_kbytes (value set based on pageblock_order, could also have
> been artifically worked around by dropping pageblock_order) and he eventually
> caused order-0 failures so the workload is pretty damn hostile to everything.

SLAB default is order 1 so is SLUB default upstream.

SLAB does runtime detection of the amount of memory and configures the max 
order correspondingly:

from mm/slab.c:

/*
 * Fragmentation resistance on low memory - only use bigger
 * page orders on machines with more than 32MB of memory.
 */
if (num_physpages > (32 << 20) >> PAGE_SHIFT)
slab_break_gfp_order = BREAK_GFP_ORDER_HI;


We could duplicate something like that for SLUB.


-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Christoph Lameter
On Sat, 29 Sep 2007, Peter Zijlstra wrote:

> 
> On Fri, 2007-09-28 at 11:20 -0700, Christoph Lameter wrote:
> 
> > Really? That means we can no longer even allocate stacks for forking.
> 
> I think I'm running with 4k stacks...

4k stacks will never fly on an SGI x86_64 NUMA configuration given the 
additional data that may be kept on the stack. We are currently 
considering to go from 8k to 16k (or even 32k) to make things work. So 
having the ability to put the stacks in vmalloc space may be something to 
look at.

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Christoph Lameter
On Sat, 29 Sep 2007, Andrew Morton wrote:

> > atomic allocations. And with SLUB using higher order pages, atomic !0
> > order allocations will be very very common.
> 
> Oh OK.
> 
> I thought we'd already fixed slub so that it didn't do that.  Maybe that
> fix is in -mm but I don't think so.
> 
> Trying to do atomic order-1 allocations on behalf of arbitray slab caches
> just won't fly - this is a significant degradation in kernel reliability,
> as you've very easily demonstrated.

Ummm... SLAB also does order 1 allocations. We have always done them.

See mm/slab.c

/*
 * Do not go above this order unless 0 objects fit into the slab.
 */
#define BREAK_GFP_ORDER_HI  1
#define BREAK_GFP_ORDER_LO  0
static int slab_break_gfp_order = BREAK_GFP_ORDER_LO;

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [15/17] SLUB: Support virtual fallback via SLAB_VFALLBACK

2007-10-01 Thread Christoph Lameter
On Fri, 28 Sep 2007, Nick Piggin wrote:

> I thought it was slower. Have you fixed the performance regression?
> (OK, I read further down that you are still working on it but not confirmed
> yet...)

The problem is with the weird way of Intel testing and communication. 
Every 3-6 month or so they will tell you the system is X% up or down on 
arch Y (and they wont give you details because its somehow secret). And 
then there are conflicting statements by the two or so performance test 
departments. One of them repeatedly assured me that they do not see any 
regressions.

> OK, so long as it isn't going to depend on using higher order pages, that's
> fine. (if they help even further as an optional thing, that's fine too. You
> can turn them on your huge systems and not even bother about adding
> this vmap fallback -- you won't have me to nag you about these
> purely theoretical issues).

Well the vmap fallback is generally useful AFAICT. Higher order 
allocations are common on some of our platforms. Order 1 failures even 
affect essential things like stacks that have nothing to do with SLUB and 
the LBS patchset.


-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 20/30] IGET: Stop JFS from using iget() and read_inode()

2007-10-01 Thread Dave Kleikamp
On Mon, 2007-10-01 at 14:11 +0100, David Howells wrote:
> Stop the JFS filesystem from using iget() and read_inode().  Replace
> jfs_read_inode() with jfs_iget(), and call that instead of iget().
> jfs_iget() then uses iget_locked() directly and returns a proper error code
> instead of an inode in the event of an error.
> 
> jfs_fill_super() returns any error incurred when getting the root inode
> instead of EINVAL.
> 
> Signed-off-by: David Howells <[EMAIL PROTECTED]>

Acked-by: Dave Kleikamp <[EMAIL PROTECTED]>

> ---
> 
>  fs/jfs/inode.c |   20 
>  fs/jfs/jfs_inode.h |2 +-
>  fs/jfs/namei.c |   34 ++
>  fs/jfs/super.c |   15 +--
>  4 files changed, 40 insertions(+), 31 deletions(-)

-- 
David Kleikamp
IBM Linux Technology Center

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/30] IGET: Stop BEFS from using iget() and read_inode()

2007-10-01 Thread Zach Brown



return ERR_PTR(PTR_ERR(inode));

I tend to prefer the latter.


It seems like a pretty noisy way to get a (void *) cast :/.  Maybe a  
function that has the cast but makes sure it's only used for IS_ERR()  
pointers?


/* haha, continuing the fine tradition of terrible names in this  
api..  */

static inline void *PTR_PTR(void *err_ptr) {
BUG_ON(!IS_ERR(err_ptr) || !err_ptr);
return err_ptr;
}

Meh.

- z
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/30] IGET: Stop BEFS from using iget() and read_inode()

2007-10-01 Thread Linus Torvalds


On Mon, 1 Oct 2007, Christoph Hellwig wrote:
> 
> befs_lookup, which the above gem is from, returns a dentry *.

Ahh, ok. Then it actually makes sense. Although I'd prefer it if people 
planned on writing code like that more along the lines of

error = PTR_ERR(inode);
if (IS_ERR(inode)
return ERR_PTR(error);

because let's face it, the compiler can turn this into nice code, and 
humans can read it much better even if it's got an "unnecessary" extra 
variable etc..

Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [patch 2/2] VFS: allow filesystem to override mknod capability checks

2007-10-01 Thread Miklos Szeredi
> On Monday September 24, [EMAIL PROTECTED] wrote:
> > From: Miklos Szeredi <[EMAIL PROTECTED]>
> > 
> > Add a new super block flag, that results in the VFS not checking if
> > the current process has enough privileges to do an mknod().
> > 
> > If this flag is set, all mounts for this super block will have the
> > "nodev" flag implied.
> > 
> > This is needed on filesystems, where an unprivileged user may be able
> > to create a device node, without causing security problems.
> > 
> > One such example is "mountlo" a loopback mount utility implemented
> > with fuse and UML, which runs as an unprivileged userspace process.
> > In this case the user does in fact have the right to create device
> > nodes within the filesystem image, as long as the user has write
> > access to the image.  Since the filesystem is mounted with "nodev",
> > adding device nodes is not a security concern.
> 
> I must admit that I don't feel very comfortable about this.  I wonder
> how many more flags we might be tempted to add to allow
> user-controlled filesystems to do interesting things.  Somehow I doubt
> this will be the last, so we should be very careful allowing it to be
> the first (or is it the second already?)

Or third ;)

Yes, I've always argued, that permission checking needs to be pushed
to the filesystem, since the VFS can't always do a good enough job.

My usual example is sshfs, where it is just impossible to know the
uid/gid mapping between the server and the client.  So any permission
checking based on uid or gid on the client simply can't work, the only
sane thing to do is to delegate the permission checking to the server.
Which works beautifully, since the server is an unprivileged process,
and everything automatically works out.

All the fuse kernel module has to do is to basically define
->permission() to always return success, and let the userspace
filesystem do the permission checking.

This works fine, except a couple of things, like checking the sticky
bit on a directory, and mknod().

> A more concrete comment on the patch:  Is it really necessary to
> introduce IS_MNT_NODEV??  Why not simply test both the flags
> (MS_MKNOD_NOCAP and MNT_NODEV) before allowing the mknod?

Because we need MNT_NODEV on _all_ mounts belonging to a superblock,
not just the one on which mknod was performed on, which would get
really ugly.  This way it's simple: if the MS_MKNOD_NOCAP is specified
for the super block, that implies, that devices can't be opened.

> Do we actually need a new flag?  Would not a combination of MS_NODEV
> and MS_SETUSER achieve the same thing (near enough)?

See above.

> Do you imagine this flag being set as a mount option (-o unprivmknod)
> or does the filesystem set it itself?

I imagine this flag to usually be set by the filesystem itself.  But
it could be a separate mount option.  I guess it could make sense in
some non-fuse cases as well.

> If the latter, maybe this test should be moved down into the
> filesystems ->mknod operation.  Most filesystems get
>  
>   if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
>   return -EPERM;
> 
> at the top of ->mknod.  fuse can do whatever it likes without
> bothering common code.

Yes, that's one of the options, but it would be a huge change, with
nasty security implications for past and future filesystems.

> According to fs.h, we only support 32 fs-independent mount-flags, and
> over half are in use.  I'm not convinced we should spend one on such a
> narrow requirement.

I think there's consensus on the need for a new mount API.  Not just
because the 32 bits for the flags will be exhausted sooner or later
anyway, but the current API is limited in lots of other ways.

Miklos
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/30] IGET: Stop BEFS from using iget() and read_inode()

2007-10-01 Thread Christoph Hellwig
On Mon, Oct 01, 2007 at 10:44:59AM -0700, Linus Torvalds wrote:
> > If you're soliciting opinions, I think I tend to prefer the feel of the
> > code paths after the changes.  I don't know the benefits of the change
> > are worth the risk in unmaintained file systems, though.
> > 
> > > + return ERR_PTR(PTR_ERR(inode));
> > 
> > This caught my eye.  Surely we can do better :).  It seems to happen a
> > few times in the patches, the instance in this patch was the first that
> > I noticed.
> 
> Yeah. The above obviously *should* be the same as
> 
>   return inode;
> 
> apart from a few casts. But if the casts matter, there's something else 
> wrong.

befs_lookup, which the above gem is from, returns a dentry *.

And given either

return (dentry *)inode;

or
return ERR_PTR(PTR_ERR(inode));

I tend to prefer the latter.
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/30] IGET: Stop BEFS from using iget() and read_inode()

2007-10-01 Thread Zach Brown
If you're soliciting opinions, I think I tend to prefer the feel of the
code paths after the changes.  I don't know the benefits of the change
are worth the risk in unmaintained file systems, though.

> + return ERR_PTR(PTR_ERR(inode));

This caught my eye.  Surely we can do better :).  It seems to happen a
few times in the patches, the instance in this patch was the first that
I noticed.

- z
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/30] IGET: Stop BEFS from using iget() and read_inode()

2007-10-01 Thread Linus Torvalds


On Mon, 1 Oct 2007, Zach Brown wrote:
>
> If you're soliciting opinions, I think I tend to prefer the feel of the
> code paths after the changes.  I don't know the benefits of the change
> are worth the risk in unmaintained file systems, though.
> 
> > +   return ERR_PTR(PTR_ERR(inode));
> 
> This caught my eye.  Surely we can do better :).  It seems to happen a
> few times in the patches, the instance in this patch was the first that
> I noticed.

Yeah. The above obviously *should* be the same as

return inode;

apart from a few casts. But if the casts matter, there's something else 
wrong.

Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 30/30] IGET: Remove iget() and the read_inode() super op as being obsolete

2007-10-01 Thread David Howells
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 (iget_failed)
that is to be called to mark an inode as bad, unlock it and release it should
the get routine fail.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 Documentation/filesystems/porting |4 ++--
 Documentation/filesystems/vfs.txt |5 -
 fs/inode.c|   16 
 include/linux/fs.h|4 
 4 files changed, 2 insertions(+), 27 deletions(-)

diff --git a/Documentation/filesystems/porting 
b/Documentation/filesystems/porting
index 3b0fb22..c20eae9 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -34,8 +34,8 @@ FOO_I(inode) (see in-tree filesystems for examples).
 
 Make them ->alloc_inode and ->destroy_inode in your super_operations.
 
-Keep in mind that now you need explicit initialization of private data -
-typically in ->read_inode() and after getting an inode from new_inode().
+Keep in mind that now you need explicit initialization of private data
+typically between calling iget_locked() and calling unlocking the inode.
 
 At some point that will become mandatory.
 
diff --git a/Documentation/filesystems/vfs.txt 
b/Documentation/filesystems/vfs.txt
index 63c7e91..133bc88 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -203,8 +203,6 @@ struct super_operations {
 struct inode *(*alloc_inode)(struct super_block *sb);
 void (*destroy_inode)(struct inode *);
 
-void (*read_inode) (struct inode *);
-
 void (*dirty_inode) (struct inode *);
 int (*write_inode) (struct inode *, int);
 void (*put_inode) (struct inode *);
@@ -242,9 +240,6 @@ or bottom half).
->alloc_inode was defined and simply undoes anything done by
->alloc_inode.
 
-  read_inode: deprecated, do not use.  Use iget_locked() instead of iget() and
-   return a proper error value.
-
   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
diff --git a/fs/inode.c b/fs/inode.c
index f78db20..29f5068 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1427,19 +1427,3 @@ void init_special_inode(struct inode *inode, umode_t 
mode, dev_t rdev)
   mode);
 }
 EXPORT_SYMBOL(init_special_inode);
-
-/*
- * old deprecated inode creator
- */
-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;
-}
-EXPORT_SYMBOL(iget);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dfa07d2..42aabc1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1181,8 +1181,6 @@ struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
 
-   void (*read_inode) (struct inode *) __deprecated;
-  
void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *);
@@ -1618,8 +1616,6 @@ extern struct inode * iget5_locked(struct super_block *, 
unsigned long, int (*te
 extern struct inode * iget_locked(struct super_block *, unsigned long);
 extern void unlock_new_inode(struct inode *);
 
-extern struct inode *iget(struct super_block *sb, unsigned long ino)
-   __deprecated;
 extern void __iget(struct inode * inode);
 extern void iget_failed(struct inode *);
 extern void clear_inode(struct inode *);

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 29/30] IGET: Stop HPPFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the HPPFS filesystem from using iget() and read_inode().  Provide an
hppfs_iget(), and call that instead of iget().  hppfs_iget() then uses
iget_locked() directly and returns a proper error code instead of an inode in
the event of an error.

hppfs_fill_sb_common() returns any error incurred when getting the root inode
instead of EINVAL.

Note that the contents of hppfs_kern.c need to be examined:

 (*) The HPPFS inode retains a pointer to the proc dentry it is shadowing, but
 whilst it does appear to retain a reference to it, it doesn't appear to
 destroy the reference if the inode goes away.

 (*) hppfs_iget() should perhaps subsume init_inode() and hppfs_read_inode().

 (*) It would appear that all hppfs inodes are the same inode because iget()
 was being called with inode number 0, which forms the lookup key.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/hppfs/hppfs_kern.c |   27 ++-
 1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index affb741..a1e1f0f 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -155,6 +155,20 @@ static void hppfs_read_inode(struct inode *ino)
ino->i_blocks = proc_ino->i_blocks;
 }
 
+static struct inode *hppfs_iget(struct super_block *sb)
+{
+   struct inode *inode;
+
+   inode = iget_locked(sb, 0);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (inode->i_state & I_NEW) {
+   hppfs_read_inode(inode);
+   unlock_new_inode(inode);
+   }
+   return inode;
+}
+
 static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
   struct nameidata *nd)
 {
@@ -190,9 +204,11 @@ static struct dentry *hppfs_lookup(struct inode *ino, 
struct dentry *dentry,
if(IS_ERR(proc_dentry))
return(proc_dentry);
 
-   inode = iget(ino->i_sb, 0);
-   if(inode == NULL)
+   inode = hppfs_iget(ino->i_sb);
+   if (IS_ERR(inode)) {
+   err = PTR_ERR(inode);
goto out_dput;
+   }
 
err = init_inode(inode, proc_dentry);
if(err)
@@ -652,7 +668,6 @@ static void hppfs_destroy_inode(struct inode *inode)
 static const struct super_operations hppfs_sbops = {
.alloc_inode= hppfs_alloc_inode,
.destroy_inode  = hppfs_destroy_inode,
-   .read_inode = hppfs_read_inode,
.delete_inode   = hppfs_delete_inode,
.statfs = hppfs_statfs,
 };
@@ -745,9 +760,11 @@ static int hppfs_fill_super(struct super_block *sb, void 
*d, int silent)
sb->s_magic = HPPFS_SUPER_MAGIC;
sb->s_op = &hppfs_sbops;
 
-   root_inode = iget(sb, 0);
-   if(root_inode == NULL)
+   root_inode = hppfs_iget(sb);
+   if (IS_ERR(root_inode)) {
+   err = PTR_ERR(root_inode);
goto out;
+   }
 
err = init_inode(root_inode, proc_sb->s_root);
if(err)

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 27/30] IGET: Stop OPENPROMFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the OPENPROMFS filesystem from using iget() and read_inode().  Replace
openpromfs_read_inode() with openpromfs_iget(), and call that instead of
iget().  openpromfs_iget() then uses iget_locked() directly and returns a
proper error code instead of an inode in the event of an error.

openpromfs_fill_super() returns any error incurred when getting the root inode
instead of ENOMEM (not that it currently incurs any other error).

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/openpromfs/inode.c |   45 ++---
 1 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index dd86be2..09aa822 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -38,6 +38,8 @@ struct op_inode_info {
union op_inode_data u;
 };
 
+static struct inode *openprom_iget(struct super_block *sb, ino_t ino);
+
 static inline struct op_inode_info *OP_I(struct inode *inode)
 {
return container_of(inode, struct op_inode_info, vfs_inode);
@@ -226,10 +228,10 @@ static struct dentry *openpromfs_lookup(struct inode 
*dir, struct dentry *dentry
return ERR_PTR(-ENOENT);
 
 found:
-   inode = iget(dir->i_sb, ino);
+   inode = openprom_iget(dir->i_sb, ino);
mutex_unlock(&op_mutex);
-   if (!inode)
-   return ERR_PTR(-EINVAL);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
ent_oi = OP_I(inode);
ent_oi->type = ent_type;
ent_oi->u = ent_data;
@@ -348,14 +350,23 @@ static void openprom_destroy_inode(struct inode *inode)
kmem_cache_free(op_inode_cachep, OP_I(inode));
 }
 
-static void openprom_read_inode(struct inode * inode)
+static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
 {
-   inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-   if (inode->i_ino == OPENPROM_ROOT_INO) {
-   inode->i_op = &openprom_inode_operations;
-   inode->i_fop = &openprom_operations;
-   inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+   struct inode *inode;
+
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (inode->i_state & I_NEW) {
+   inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+   if (inode->i_ino == OPENPROM_ROOT_INO) {
+   inode->i_op = &openprom_inode_operations;
+   inode->i_fop = &openprom_operations;
+   inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+   }
+   unlock_new_inode(inode);
}
+   return inode;
 }
 
 static int openprom_remount(struct super_block *sb, int *flags, char *data)
@@ -367,7 +378,6 @@ static int openprom_remount(struct super_block *sb, int 
*flags, char *data)
 static const struct super_operations openprom_sops = {
.alloc_inode= openprom_alloc_inode,
.destroy_inode  = openprom_destroy_inode,
-   .read_inode = openprom_read_inode,
.statfs = simple_statfs,
.remount_fs = openprom_remount,
 };
@@ -376,6 +386,7 @@ static int openprom_fill_super(struct super_block *s, void 
*data, int silent)
 {
struct inode *root_inode;
struct op_inode_info *oi;
+   int ret;
 
s->s_flags |= MS_NOATIME;
s->s_blocksize = 1024;
@@ -383,9 +394,11 @@ static int openprom_fill_super(struct super_block *s, void 
*data, int silent)
s->s_magic = OPENPROM_SUPER_MAGIC;
s->s_op = &openprom_sops;
s->s_time_gran = 1;
-   root_inode = iget(s, OPENPROM_ROOT_INO);
-   if (!root_inode)
+   root_inode = openprom_iget(s, OPENPROM_ROOT_INO);
+   if (IS_ERR(root_inode)) {
+   ret = PTR_ERR(root_inode);
goto out_no_root;
+   }
 
oi = OP_I(root_inode);
oi->type = op_inode_node;
@@ -393,13 +406,15 @@ static int openprom_fill_super(struct super_block *s, 
void *data, int silent)
 
s->s_root = d_alloc_root(root_inode);
if (!s->s_root)
-   goto out_no_root;
+   goto out_no_root_dentry;
return 0;
 
+out_no_root_dentry:
+   iput(root_inode);
+   ret = -ENOMEM;
 out_no_root:
printk("openprom_fill_super: get root inode failed\n");
-   iput(root_inode);
-   return -ENOMEM;
+   return ret;
 }
 
 static int openprom_get_sb(struct file_system_type *fs_type,

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 28/30] IGET: Stop HOSTFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the HOSTFS filesystem from using iget() and read_inode().  Provide
hostfs_iget(), and call that instead of iget().  hostfs_iget() then uses
iget_locked() directly and returns a proper error code instead of an inode in
the event of an error.

hostfs_fill_sb_common() returns any error incurred when getting the root inode
instead of EINVAL.

Note that the contents of hostfs_kern.c need to be examined:

 (*) hostfs_iget() should perhaps subsume init_inode() and hostfs_read_inode().

 (*) It would appear that all hostfs inodes are the same inode because iget()
 was being called with inode number 0 - which forms the lookup key.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/hostfs/hostfs_kern.c |   58 ---
 1 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index c778620..c6a456a 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -208,7 +208,7 @@ static char *follow_link(char *link)
return ERR_PTR(n);
 }
 
-static int read_inode(struct inode *ino)
+static int hostfs_read_inode(struct inode *ino)
 {
char *name;
int err = 0;
@@ -238,6 +238,25 @@ static int read_inode(struct inode *ino)
return err;
 }
 
+static struct inode *hostfs_iget(struct super_block *sb)
+{
+   struct inode *inode;
+   long ret;
+
+   inode = iget_locked(sb, 0);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (inode->i_state & I_NEW) {
+   ret = hostfs_read_inode(inode);
+   if (ret < 0) {
+   iget_failed(inode);
+   return ERR_PTR(ret);
+   }
+   unlock_new_inode(inode);
+   }
+   return inode;
+}
+
 int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
 {
/* do_statfs uses struct statfs64 internally, but the linux kernel
@@ -305,17 +324,11 @@ static void hostfs_destroy_inode(struct inode *inode)
kfree(HOSTFS_I(inode));
 }
 
-static void hostfs_read_inode(struct inode *inode)
-{
-   read_inode(inode);
-}
-
 static const struct super_operations hostfs_sbops = {
.alloc_inode= hostfs_alloc_inode,
.drop_inode = generic_delete_inode,
.delete_inode   = hostfs_delete_inode,
.destroy_inode  = hostfs_destroy_inode,
-   .read_inode = hostfs_read_inode,
.statfs = hostfs_statfs,
 };
 
@@ -584,9 +597,11 @@ int hostfs_create(struct inode *dir, struct dentry 
*dentry, int mode,
char *name;
int error, fd;
 
-   error = -ENOMEM;
-   inode = iget(dir->i_sb, 0);
-   if(inode == NULL) goto out;
+   inode = hostfs_iget(dir->i_sb);
+   if (IS_ERR(inode)) {
+   error = PTR_ERR(inode);
+   goto out;
+   }
 
error = init_inode(inode, dentry);
if(error)
@@ -627,10 +642,11 @@ struct dentry *hostfs_lookup(struct inode *ino, struct 
dentry *dentry,
char *name;
int err;
 
-   err = -ENOMEM;
-   inode = iget(ino->i_sb, 0);
-   if(inode == NULL)
+   inode = hostfs_iget(ino->i_sb);
+   if (IS_ERR(inode)) {
+   err = PTR_ERR(inode);
goto out;
+   }
 
err = init_inode(inode, dentry);
if(err)
@@ -748,11 +764,13 @@ int hostfs_mknod(struct inode *dir, struct dentry 
*dentry, int mode, dev_t dev)
 {
struct inode *inode;
char *name;
-   int err = -ENOMEM;
+   int err;
 
-   inode = iget(dir->i_sb, 0);
-   if(inode == NULL)
+   inode = hostfs_iget(dir->i_sb);
+   if (IS_ERR(inode)) {
+   err = PTR_ERR(inode);
goto out;
+   }
 
err = init_inode(inode, dentry);
if(err)
@@ -973,9 +991,11 @@ static int hostfs_fill_sb_common(struct super_block *sb, 
void *d, int silent)
 
sprintf(host_root_path, "%s/%s", root_ino, req_root);
 
-   root_inode = iget(sb, 0);
-   if(root_inode == NULL)
+   root_inode = hostfs_iget(sb);
+   if (IS_ERR(root_inode)) {
+   err = PTR_ERR(root_inode);
goto out_free;
+   }
 
err = init_inode(root_inode, NULL);
if(err)
@@ -991,7 +1011,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, 
void *d, int silent)
if(sb->s_root == NULL)
goto out_put;
 
-   err = read_inode(root_inode);
+   err = hostfs_read_inode(root_inode);
if(err){
/* No iput in this case because the dput does that for us */
dput(sb->s_root);

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 25/30] IGET: Stop the SYSV filesystem from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the SYSV filesystem from using iget() and read_inode().  Replace
sysv_read_inode() with sysv_iget(), and call that instead of iget().
sysv_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/sysv/inode.c |   25 -
 fs/sysv/namei.c |6 +++---
 fs/sysv/super.c |4 ++--
 fs/sysv/sysv.h  |1 +
 4 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 7c4e5d3..9d512a8 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -169,20 +169,27 @@ void sysv_set_inode(struct inode *inode, dev_t rdev)
init_special_inode(inode, inode->i_mode, rdev);
 }
 
-static void sysv_read_inode(struct inode *inode)
+struct inode *sysv_iget(struct super_block *sb, unsigned int ino)
 {
-   struct super_block * sb = inode->i_sb;
struct sysv_sb_info * sbi = SYSV_SB(sb);
struct buffer_head * bh;
struct sysv_inode * raw_inode;
struct sysv_inode_info * si;
-   unsigned int block, ino = inode->i_ino;
+   struct inode *inode;
+   unsigned int block;
 
if (!ino || ino > sbi->s_ninodes) {
printk("Bad inode number on dev %s: %d is out of range\n",
-  inode->i_sb->s_id, ino);
-   goto bad_inode;
+  sb->s_id, ino);
+   return ERR_PTR(-EIO);
}
+
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
raw_inode = sysv_raw_inode(sb, ino, &bh);
if (!raw_inode) {
printk("Major problem: unable to read inode from dev %s\n",
@@ -214,11 +221,12 @@ static void sysv_read_inode(struct inode *inode)
   old_decode_dev(fs32_to_cpu(sbi, si->i_data[0])));
else
sysv_set_inode(inode, 0);
-   return;
+   unlock_new_inode(inode);
+   return inode;
 
 bad_inode:
-   make_bad_inode(inode);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
 }
 
 static struct buffer_head * sysv_update_inode(struct inode * inode)
@@ -328,7 +336,6 @@ static void init_once(void *p, struct kmem_cache *cachep, 
unsigned long flags)
 const struct super_operations sysv_sops = {
.alloc_inode= sysv_alloc_inode,
.destroy_inode  = sysv_destroy_inode,
-   .read_inode = sysv_read_inode,
.write_inode= sysv_write_inode,
.delete_inode   = sysv_delete_inode,
.put_super  = sysv_put_super,
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 6bd850b..599d980 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -53,9 +53,9 @@ static struct dentry *sysv_lookup(struct inode * dir, struct 
dentry * dentry, st
ino = sysv_inode_by_name(dentry);
 
if (ino) {
-   inode = iget(dir->i_sb, ino);
-   if (!inode)
-   return ERR_PTR(-EACCES);
+   inode = sysv_iget(dir->i_sb, ino);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
}
d_add(dentry, inode);
return NULL;
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index 6f9707a..a92d104 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -332,8 +332,8 @@ static int complete_read_super(struct super_block *sb, int 
silent, int size)
sb->s_magic = SYSV_MAGIC_BASE + sbi->s_type;
/* set up enough so that it can read an inode */
sb->s_op = &sysv_sops;
-   root_inode = iget(sb,SYSV_ROOT_INO);
-   if (!root_inode || is_bad_inode(root_inode)) {
+   root_inode = sysv_iget(sb,SYSV_ROOT_INO);
+   if (IS_ERR(root_inode)) {
printk("SysV FS: get root inode failed\n");
return 0;
}
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 5b4fedf..71ebdbc 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -138,6 +138,7 @@ extern unsigned long sysv_count_free_blocks(struct 
super_block *);
 extern void sysv_truncate(struct inode *);
 
 /* inode.c */
+extern struct inode *sysv_iget(struct super_block *, unsigned int);
 extern int sysv_write_inode(struct inode *, int);
 extern int sysv_sync_inode(struct inode *);
 extern int sysv_sync_file(struct file *, struct dentry *, int);

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 26/30] IGET: Stop UFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the UFS filesystem from using iget() and read_inode().  Replace
ufs_read_inode() with ufs_iget(), and call that instead of iget().
ufs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

ufs_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/ufs/inode.c |   34 --
 fs/ufs/namei.c |6 +++---
 fs/ufs/super.c |   14 +-
 include/linux/ufs_fs.h |2 +-
 4 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index f18b791..d7c2d3c 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -698,26 +698,30 @@ static int ufs2_read_inode(struct inode *inode, struct 
ufs2_inode *ufs2_inode)
return 0;
 }
 
-void ufs_read_inode(struct inode * inode)
+struct inode *ufs_iget (struct super_block *sb, unsigned long ino)
 {
-   struct ufs_inode_info *ufsi = UFS_I(inode);
-   struct super_block * sb;
-   struct ufs_sb_private_info * uspi;
+   struct ufs_inode_info *ufsi;
+   struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi;
struct buffer_head * bh;
+   struct inode *inode;
int err;
 
-   UFSD("ENTER, ino %lu\n", inode->i_ino);
-
-   sb = inode->i_sb;
-   uspi = UFS_SB(sb)->s_uspi;
+   UFSD("ENTER, ino %lu\n", ino);
 
-   if (inode->i_ino < UFS_ROOTINO ||
-   inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) {
+   if (ino < UFS_ROOTINO || ino > (uspi->s_ncg * uspi->s_ipg)) {
ufs_warning(sb, "ufs_read_inode", "bad inode number (%lu)\n",
-   inode->i_ino);
-   goto bad_inode;
+   ino);
+   return ERR_PTR(-EIO);
}
 
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   ufsi = UFS_I(inode);
+
bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino));
if (!bh) {
ufs_warning(sb, "ufs_read_inode", "unable to read inode %lu\n",
@@ -749,10 +753,12 @@ void ufs_read_inode(struct inode * inode)
brelse(bh);
 
UFSD("EXIT\n");
-   return;
+   unlock_new_inode(inode);
+   return inode;
 
 bad_inode:
-   make_bad_inode(inode);
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
 }
 
 static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index a059ccd..e40726f 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -57,10 +57,10 @@ static struct dentry *ufs_lookup(struct inode * dir, struct 
dentry *dentry, stru
lock_kernel();
ino = ufs_inode_by_name(dir, dentry);
if (ino) {
-   inode = iget(dir->i_sb, ino);
-   if (!inode) {
+   inode = ufs_iget(dir->i_sb, ino);
+   if (IS_ERR(inode)) {
unlock_kernel();
-   return ERR_PTR(-EACCES);
+   return ERR_PTR(PTR_ERR(inode));
}
}
unlock_kernel();
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 38eb0b7..8e157ab 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -613,6 +613,7 @@ static int ufs_fill_super(struct super_block *sb, void 
*data, int silent)
unsigned block_size, super_block_size;
unsigned flags;
unsigned super_block_offset;
+   int ret = -EINVAL;
 
uspi = NULL;
ubh = NULL;
@@ -1026,12 +1027,16 @@ magic_found:
uspi->s_maxsymlinklen =
fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen);
 
-   inode = iget(sb, UFS_ROOTINO);
-   if (!inode || is_bad_inode(inode))
+   inode = ufs_iget(sb, UFS_ROOTINO);
+   if (IS_ERR(inode)) {
+   ret = PTR_ERR(inode);
goto failed;
+   }
sb->s_root = d_alloc_root(inode);
-   if (!sb->s_root)
+   if (!sb->s_root) {
+   ret = -ENOMEM;
goto dalloc_failed;
+   }
 
ufs_setup_cstotal(sb);
/*
@@ -1053,7 +1058,7 @@ failed:
kfree(sbi);
sb->s_fs_info = NULL;
UFSD("EXIT (FAILED)\n");
-   return -EINVAL;
+   return ret;
 
 failed_nomem:
UFSD("EXIT (NOMEM)\n");
@@ -1264,7 +1269,6 @@ static ssize_t ufs_quota_write(struct super_block *, int, 
const char *, size_t,
 static const struct super_operations ufs_super_ops = {
.alloc_inode= ufs_alloc_inode,
.destroy_inode  = ufs_destroy_inode,
-   .read_inode = ufs_read_inode,
.write_inode= ufs_write_inode,
.delete_inode   = ufs_delete_inode,
.put_super  = ufs_put_super,
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index daeba22..2a61fa3 100644
--- a/include/lin

[PATCH 22/30] IGET: Stop PROCFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the PROCFS filesystem from using iget() and read_inode().  Merge
procfs_read_inode() into procfs_get_inode(), and have that call iget_locked()
instead of iget().

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/proc/inode.c |   60 ++-
 1 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 0e4d37c..7a563c5 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -78,11 +78,6 @@ static void proc_delete_inode(struct inode *inode)
 
 struct vfsmount *proc_mnt;
 
-static void proc_read_inode(struct inode * inode)
-{
-   inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-}
-
 static struct kmem_cache * proc_inode_cachep;
 
 static struct inode *proc_alloc_inode(struct super_block *sb)
@@ -135,7 +130,6 @@ static int proc_remount(struct super_block *sb, int *flags, 
char *data)
 static const struct super_operations proc_sops = {
.alloc_inode= proc_alloc_inode,
.destroy_inode  = proc_destroy_inode,
-   .read_inode = proc_read_inode,
.drop_inode = generic_delete_inode,
.delete_inode   = proc_delete_inode,
.statfs = simple_statfs,
@@ -408,39 +402,41 @@ struct inode *proc_get_inode(struct super_block *sb, 
unsigned int ino,
if (de != NULL && !try_module_get(de->owner))
goto out_mod;
 
-   inode = iget(sb, ino);
+   inode = iget_locked(sb, ino);
if (!inode)
goto out_ino;
-
-   PROC_I(inode)->fd = 0;
-   PROC_I(inode)->pde = de;
-   if (de) {
-   if (de->mode) {
-   inode->i_mode = de->mode;
-   inode->i_uid = de->uid;
-   inode->i_gid = de->gid;
-   }
-   if (de->size)
-   inode->i_size = de->size;
-   if (de->nlink)
-   inode->i_nlink = de->nlink;
-   if (de->proc_iops)
-   inode->i_op = de->proc_iops;
-   if (de->proc_fops) {
-   if (S_ISREG(inode->i_mode)) {
+   if (inode->i_state & I_NEW) {
+   inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+   PROC_I(inode)->fd = 0;
+   PROC_I(inode)->pde = de;
+   if (de) {
+   if (de->mode) {
+   inode->i_mode = de->mode;
+   inode->i_uid = de->uid;
+   inode->i_gid = de->gid;
+   }
+   if (de->size)
+   inode->i_size = de->size;
+   if (de->nlink)
+   inode->i_nlink = de->nlink;
+   if (de->proc_iops)
+   inode->i_op = de->proc_iops;
+   if (de->proc_fops) {
+   if (S_ISREG(inode->i_mode)) {
 #ifdef CONFIG_COMPAT
-   if (!de->proc_fops->compat_ioctl)
-   inode->i_fop =
-   &proc_reg_file_ops_no_compat;
-   else
+   if (!de->proc_fops->compat_ioctl)
+   inode->i_fop =
+   
&proc_reg_file_ops_no_compat;
+   else
 #endif
-   inode->i_fop = &proc_reg_file_ops;
+   inode->i_fop = 
&proc_reg_file_ops;
+   }
+   else
+   inode->i_fop = de->proc_fops;
}
-   else
-   inode->i_fop = de->proc_fops;
}
+   unlock_new_inode(inode);
}
-
return inode;
 
 out_ino:

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 24/30] IGET: Stop ROMFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the ROMFS filesystem from using iget() and read_inode().  Replace
romfs_read_inode() with romfs_iget(), and call that instead of iget().
romfs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

romfs_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/romfs/inode.c |   45 +++--
 1 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index dae7945..5071c9a 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -84,6 +84,8 @@ struct romfs_inode_info {
struct inode vfs_inode;
 };
 
+static struct inode *romfs_iget(struct super_block *, unsigned long);
+
 /* instead of private superblock data */
 static inline unsigned long romfs_maxsize(struct super_block *sb)
 {
@@ -117,7 +119,7 @@ static int romfs_fill_super(struct super_block *s, void 
*data, int silent)
struct buffer_head *bh;
struct romfs_super_block *rsb;
struct inode *root;
-   int sz;
+   int sz, ret = -EINVAL;
 
/* I would parse the options here, but there are none.. :) */
 
@@ -157,10 +159,13 @@ static int romfs_fill_super(struct super_block *s, void 
*data, int silent)
 & ROMFH_MASK;
 
s->s_op = &romfs_ops;
-   root = iget(s, sz);
-   if (!root)
+   root = romfs_iget(s, sz);
+   if (IS_ERR(root)) {
+   ret = PTR_ERR(root);
goto out;
+   }
 
+   ret = -ENOMEM;
s->s_root = d_alloc_root(root);
if (!s->s_root)
goto outiput;
@@ -173,7 +178,7 @@ outiput:
 out:
brelse(bh);
 outnobh:
-   return -EINVAL;
+   return ret;
 }
 
 /* That's simple too. */
@@ -389,8 +394,11 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, 
struct nameidata *nd)
if ((be32_to_cpu(ri.next) & ROMFH_TYPE) == ROMFH_HRD)
offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
 
-   if ((inode = iget(dir->i_sb, offset)))
-   goto outi;
+   inode = romfs_iget(dir->i_sb, offset);
+   if (IS_ERR(inode)) {
+   res = PTR_ERR(inode);
+   goto out;
+   }
 
/*
 * it's a bit funky, _lookup needs to return an error code
@@ -402,7 +410,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, 
struct nameidata *nd)
 */
 
 out0:  inode = NULL;
-outi:  res = 0;
+   res = 0;
d_add (dentry, inode);
 
 out:   unlock_kernel();
@@ -478,20 +486,28 @@ static mode_t romfs_modemap[] =
S_IFBLK+0600, S_IFCHR+0600, S_IFSOCK+0644, S_IFIFO+0644
 };
 
-static void
-romfs_read_inode(struct inode *i)
+static struct inode *
+romfs_iget(struct super_block *sb, unsigned long ino)
 {
-   int nextfh, ino;
+   int nextfh;
struct romfs_inode ri;
+   struct inode *i;
+
+   ino &= ROMFH_MASK;
+   i = iget_locked(sb, ino);
+   if (!i)
+   return ERR_PTR(-ENOMEM);
+   if (!(i->i_state & I_NEW))
+   return i;
 
-   ino = i->i_ino & ROMFH_MASK;
i->i_mode = 0;
 
/* Loop for finding the real hard link */
for(;;) {
if (romfs_copyfrom(i, &ri, ino, ROMFH_SIZE) <= 0) {
-   printk("romfs: read error for inode 0x%x\n", ino);
-   return;
+   printk("romfs: read error for inode 0x%lx\n", ino);
+   iget_failed(i);
+   return ERR_PTR(-EIO);
}
/* XXX: do romfs_checksum here too (with name) */
 
@@ -548,6 +564,8 @@ romfs_read_inode(struct inode *i)
init_special_inode(i, ino,
MKDEV(nextfh>>16,nextfh&0x));
}
+   unlock_new_inode(i);
+   return i;
 }
 
 static struct kmem_cache * romfs_inode_cachep;
@@ -599,7 +617,6 @@ static int romfs_remount(struct super_block *sb, int 
*flags, char *data)
 static const struct super_operations romfs_ops = {
.alloc_inode= romfs_alloc_inode,
.destroy_inode  = romfs_destroy_inode,
-   .read_inode = romfs_read_inode,
.statfs = romfs_statfs,
.remount_fs = romfs_remount,
 };

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 23/30] IGET: Stop QNX4 from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the QNX4 filesystem from using iget() and read_inode().  Replace
qnx4_read_inode() with qnx4_iget(), and call that instead of iget().
qnx4_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

qnx4_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/qnx4/inode.c |   45 ++---
 fs/qnx4/namei.c |8 +---
 include/linux/qnx4_fs.h |1 +
 3 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 1bc8d87..3eba8fe 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -125,7 +125,6 @@ static int qnx4_write_inode(struct inode *inode, int unused)
 static void qnx4_put_super(struct super_block *sb);
 static struct inode *qnx4_alloc_inode(struct super_block *sb);
 static void qnx4_destroy_inode(struct inode *inode);
-static void qnx4_read_inode(struct inode *);
 static int qnx4_remount(struct super_block *sb, int *flags, char *data);
 static int qnx4_statfs(struct dentry *, struct kstatfs *);
 
@@ -133,7 +132,6 @@ static const struct super_operations qnx4_sops =
 {
.alloc_inode= qnx4_alloc_inode,
.destroy_inode  = qnx4_destroy_inode,
-   .read_inode = qnx4_read_inode,
.put_super  = qnx4_put_super,
.statfs = qnx4_statfs,
.remount_fs = qnx4_remount,
@@ -357,6 +355,7 @@ static int qnx4_fill_super(struct super_block *s, void 
*data, int silent)
struct inode *root;
const char *errmsg;
struct qnx4_sb_info *qs;
+   int ret = -EINVAL;
 
qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);
if (!qs)
@@ -396,12 +395,14 @@ static int qnx4_fill_super(struct super_block *s, void 
*data, int silent)
}
 
/* does root not have inode number QNX4_ROOT_INO ?? */
-   root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
-   if (!root) {
+   root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
+   if (IS_ERR(root)) {
printk("qnx4: get inode failed\n");
+   ret = PTR_ERR(root);
goto out;
}
 
+   ret = -ENOMEM;
s->s_root = d_alloc_root(root);
if (s->s_root == NULL)
goto outi;
@@ -417,7 +418,7 @@ static int qnx4_fill_super(struct super_block *s, void 
*data, int silent)
   outnobh:
kfree(qs);
s->s_fs_info = NULL;
-   return -EINVAL;
+   return ret;
 }
 
 static void qnx4_put_super(struct super_block *sb)
@@ -457,29 +458,37 @@ static const struct address_space_operations qnx4_aops = {
.bmap   = qnx4_bmap
 };
 
-static void qnx4_read_inode(struct inode *inode)
+struct inode *qnx4_iget(struct super_block *sb, unsigned long ino)
 {
struct buffer_head *bh;
struct qnx4_inode_entry *raw_inode;
-   int block, ino;
-   struct super_block *sb = inode->i_sb;
-   struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
+   int block;
+   struct qnx4_inode_entry *qnx4_inode;
+   struct inode *inode;
 
-   ino = inode->i_ino;
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   qnx4_inode = qnx4_raw_inode(inode);
inode->i_mode = 0;
 
QNX4DEBUG(("Reading inode : [%d]\n", ino));
if (!ino) {
-   printk("qnx4: bad inode number on dev %s: %d is out of range\n",
+   printk("qnx4: bad inode number on dev %s: %lu is out of 
range\n",
   sb->s_id, ino);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
}
block = ino / QNX4_INODES_PER_BLOCK;
 
if (!(bh = sb_bread(sb, block))) {
printk("qnx4: major problem: unable to read inode from dev "
   "%s\n", sb->s_id);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
}
raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
(ino % QNX4_INODES_PER_BLOCK);
@@ -510,9 +519,15 @@ static void qnx4_read_inode(struct inode *inode)
inode->i_op = &page_symlink_inode_operations;
inode->i_mapping->a_ops = &qnx4_aops;
qnx4_i(inode)->mmu_private = inode->i_size;
-   } else
-   printk("qnx4: bad inode %d on dev %s\n",ino,sb->s_id);
+   } else {
+   printk("qnx4: bad inode %lu on dev %s\n",ino,sb->s_id);
+   iget_failed(inode);
+   brelse(bh);
+   return ERR_PTR(-EIO);
+   }
brelse(bh);
+   unlock_new_inode(inode);
+   return inode;
 }
 
 static struct kmem_cache *qnx4_inode_cachep;
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index 733cdf

[PATCH 21/30] IGET: Stop the MINIX filesystem from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the MINIX filesystem from using iget() and read_inode().  Replace
minix_read_inode() with minix_iget(), and call that instead of iget().
minix_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

minix_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/minix/inode.c |   43 +--
 fs/minix/minix.h |1 +
 fs/minix/namei.c |7 +++
 3 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 43668d7..ee329f8 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -18,7 +18,6 @@
 #include 
 #include 
 
-static void minix_read_inode(struct inode * inode);
 static int minix_write_inode(struct inode * inode, int wait);
 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int minix_remount (struct super_block * sb, int * flags, char * data);
@@ -96,7 +95,6 @@ static void destroy_inodecache(void)
 static const struct super_operations minix_sops = {
.alloc_inode= minix_alloc_inode,
.destroy_inode  = minix_destroy_inode,
-   .read_inode = minix_read_inode,
.write_inode= minix_write_inode,
.delete_inode   = minix_delete_inode,
.put_super  = minix_put_super,
@@ -149,6 +147,7 @@ static int minix_fill_super(struct super_block *s, void 
*data, int silent)
unsigned long i, block;
struct inode *root_inode;
struct minix_sb_info *sbi;
+   int ret = -EINVAL;
 
sbi = kzalloc(sizeof(struct minix_sb_info), GFP_KERNEL);
if (!sbi)
@@ -246,10 +245,13 @@ static int minix_fill_super(struct super_block *s, void 
*data, int silent)
 
/* set up enough so that it can read an inode */
s->s_op = &minix_sops;
-   root_inode = iget(s, MINIX_ROOT_INO);
-   if (!root_inode || is_bad_inode(root_inode))
+   root_inode = minix_iget(s, MINIX_ROOT_INO);
+   if (IS_ERR(root_inode)) {
+   ret = PTR_ERR(root_inode);
goto out_no_root;
+   }
 
+   ret = -ENOMEM;
s->s_root = d_alloc_root(root_inode);
if (!s->s_root)
goto out_iput;
@@ -290,6 +292,7 @@ out_freemap:
goto out_release;
 
 out_no_map:
+   ret = -ENOMEM;
if (!silent)
printk("MINIX-fs: can't allocate map\n");
goto out_release;
@@ -316,7 +319,7 @@ out_bad_sb:
 out:
s->s_fs_info = NULL;
kfree(sbi);
-   return -EINVAL;
+   return ret;
 }
 
 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -394,7 +397,7 @@ void minix_set_inode(struct inode *inode, dev_t rdev)
 /*
  * The minix V1 function to read an inode.
  */
-static void V1_minix_read_inode(struct inode * inode)
+static struct inode *V1_minix_iget(struct inode * inode)
 {
struct buffer_head * bh;
struct minix_inode * raw_inode;
@@ -403,8 +406,8 @@ static void V1_minix_read_inode(struct inode * inode)
 
raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
if (!raw_inode) {
-   make_bad_inode(inode);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
}
inode->i_mode = raw_inode->i_mode;
inode->i_uid = (uid_t)raw_inode->i_uid;
@@ -420,12 +423,14 @@ static void V1_minix_read_inode(struct inode * inode)
minix_inode->u.i1_data[i] = raw_inode->i_zone[i];
minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0]));
brelse(bh);
+   unlock_new_inode(inode);
+   return inode;
 }
 
 /*
  * The minix V2 function to read an inode.
  */
-static void V2_minix_read_inode(struct inode * inode)
+static struct inode *V2_minix_iget(struct inode * inode)
 {
struct buffer_head * bh;
struct minix2_inode * raw_inode;
@@ -434,8 +439,8 @@ static void V2_minix_read_inode(struct inode * inode)
 
raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
if (!raw_inode) {
-   make_bad_inode(inode);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
}
inode->i_mode = raw_inode->i_mode;
inode->i_uid = (uid_t)raw_inode->i_uid;
@@ -453,17 +458,27 @@ static void V2_minix_read_inode(struct inode * inode)
minix_inode->u.i2_data[i] = raw_inode->i_zone[i];
minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0]));
brelse(bh);
+   unlock_new_inode(inode);
+   return inode;
 }
 
 /*
  * The global function to read an inode.
  */
-static void minix_read_inode(struct inode * inode)
+struct inode *minix_iget(struct super_block *sb, unsigned long ino)
 {
+   struct inode *inode;
+
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inod

[PATCH 20/30] IGET: Stop JFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the JFS filesystem from using iget() and read_inode().  Replace
jfs_read_inode() with jfs_iget(), and call that instead of iget().
jfs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

jfs_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/jfs/inode.c |   20 
 fs/jfs/jfs_inode.h |2 +-
 fs/jfs/namei.c |   34 ++
 fs/jfs/super.c |   15 +--
 4 files changed, 40 insertions(+), 31 deletions(-)

diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 3467dde..5081e76 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -31,11 +31,21 @@
 #include "jfs_debug.h"
 
 
-void jfs_read_inode(struct inode *inode)
+struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
 {
-   if (diRead(inode)) {
-   make_bad_inode(inode);
-   return;
+   struct inode *inode;
+   int ret;
+
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   ret = diRead(inode);
+   if (ret < 0) {
+   iget_failed(inode);
+   return ERR_PTR(ret);
}
 
if (S_ISREG(inode->i_mode)) {
@@ -55,6 +65,8 @@ void jfs_read_inode(struct inode *inode)
inode->i_op = &jfs_file_inode_operations;
init_special_inode(inode, inode->i_mode, inode->i_rdev);
}
+   unlock_new_inode(inode);
+   return inode;
 }
 
 /*
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index f0ec72b..71ea106 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -22,7 +22,7 @@ extern struct inode *ialloc(struct inode *, umode_t);
 extern int jfs_fsync(struct file *, struct dentry *, int);
 extern int jfs_ioctl(struct inode *, struct file *,
unsigned int, unsigned long);
-extern void jfs_read_inode(struct inode *);
+extern struct inode *jfs_iget(struct super_block *, unsigned long);
 extern int jfs_commit_inode(struct inode *, int);
 extern int jfs_write_inode(struct inode*, int);
 extern void jfs_delete_inode(struct inode *);
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 932797b..c436c8a 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1461,12 +1461,10 @@ static struct dentry *jfs_lookup(struct inode *dip, 
struct dentry *dentry, struc
}
}
 
-   ip = iget(dip->i_sb, inum);
-   if (ip == NULL || is_bad_inode(ip)) {
+   ip = jfs_iget(dip->i_sb, inum);
+   if (IS_ERR(ip)) {
jfs_err("jfs_lookup: iget failed on inum %d", (uint) inum);
-   if (ip)
-   iput(ip);
-   return ERR_PTR(-EACCES);
+   return ERR_PTR(PTR_ERR(ip));
}
 
dentry = d_splice_alias(ip, dentry);
@@ -1487,12 +1485,11 @@ struct dentry *jfs_get_dentry(struct super_block *sb, 
void *vobjp)
 
if (ino == 0)
return ERR_PTR(-ESTALE);
-   inode = iget(sb, ino);
-   if (inode == NULL)
-   return ERR_PTR(-ENOMEM);
+   inode = jfs_iget(sb, ino);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
 
-   if (is_bad_inode(inode) ||
-   (generation && inode->i_generation != generation)) {
+   if (generation && inode->i_generation != generation) {
result = ERR_PTR(-ESTALE);
goto out_iput;
}
@@ -1518,17 +1515,14 @@ struct dentry *jfs_get_parent(struct dentry *dentry)
 
parent_ino =
le32_to_cpu(JFS_IP(dentry->d_inode)->i_dtroot.header.idotdot);
-   inode = iget(sb, parent_ino);
-   if (inode) {
-   if (is_bad_inode(inode)) {
+   inode = jfs_iget(sb, parent_ino);
+   if (IS_ERR(inode)) {
+   parent = ERR_PTR(PTR_ERR(inode));
+   } else {
+   parent = d_alloc_anon(inode);
+   if (!parent) {
+   parent = ERR_PTR(-ENOMEM);
iput(inode);
-   parent = ERR_PTR(-EACCES);
-   } else {
-   parent = d_alloc_anon(inode);
-   if (!parent) {
-   parent = ERR_PTR(-ENOMEM);
-   iput(inode);
-   }
}
}
 
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 4b372f5..f499634 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -414,7 +414,7 @@ static int jfs_fill_super(struct super_block *sb, void 
*data, int silent)
struct inode *inode;
int rc;
s64 newLVSize = 0;
-   int flag;
+   int flag, ret = -EINVAL;
 
jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
 
@@ -461,8 +461,10 @@ static int jfs_fill_super(struct super_block *sb, void 
*data, int

[PATCH 19/30] IGET: Stop JFFS2 from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the JFFS2 filesystem from using iget() and read_inode().  Replace
jffs2_read_inode() with jffs2_iget(), and call that instead of iget().
jffs2_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

jffs2_do_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/jffs2/dir.c  |6 +++--
 fs/jffs2/fs.c   |   56 ---
 fs/jffs2/os-linux.h |2 +-
 fs/jffs2/super.c|1 -
 4 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index c1dfca3..19d8017 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -101,10 +101,10 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, 
struct dentry *target,
ino = fd->ino;
up(&dir_f->sem);
if (ino) {
-   inode = iget(dir_i->i_sb, ino);
-   if (!inode) {
+   inode = jffs2_iget(dir_i->i_sb, ino);
+   if (IS_ERR(inode)) {
printk(KERN_WARNING "iget() failed for ino #%u\n", ino);
-   return (ERR_PTR(-EIO));
+   return ERR_PTR(PTR_ERR(inode));
}
}
 
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 8bc727b..e8fe629 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -227,16 +227,23 @@ void jffs2_clear_inode (struct inode *inode)
jffs2_do_clear_inode(c, f);
 }
 
-void jffs2_read_inode (struct inode *inode)
+struct inode *jffs2_iget(struct super_block *sb, unsigned long ino)
 {
struct jffs2_inode_info *f;
struct jffs2_sb_info *c;
struct jffs2_raw_inode latest_node;
union jffs2_device_node jdev;
+   struct inode *inode;
dev_t rdev = 0;
int ret;
 
-   D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", 
inode->i_ino));
+   D1(printk(KERN_DEBUG "jffs2_iget(): ino == %lu\n", ino));
+
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
 
f = JFFS2_INODE_INFO(inode);
c = JFFS2_SB_INFO(inode->i_sb);
@@ -247,9 +254,9 @@ void jffs2_read_inode (struct inode *inode)
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
 
if (ret) {
-   make_bad_inode(inode);
up(&f->sem);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(ret);
}
inode->i_mode = jemode_to_cpu(latest_node.mode);
inode->i_uid = je16_to_cpu(latest_node.uid);
@@ -300,19 +307,14 @@ void jffs2_read_inode (struct inode *inode)
if (f->metadata->size != sizeof(jdev.old) &&
f->metadata->size != sizeof(jdev.new)) {
printk(KERN_NOTICE "Device node has strange size %d\n", 
f->metadata->size);
-   up(&f->sem);
-   jffs2_do_clear_inode(c, f);
-   make_bad_inode(inode);
-   return;
+   goto error_io;
}
D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
-   if (jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, 
f->metadata->size) < 0) {
+   ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, 
f->metadata->size);
+   if (ret < 0) {
/* Eep */
printk(KERN_NOTICE "Read device numbers for inode %lu 
failed\n", (unsigned long)inode->i_ino);
-   up(&f->sem);
-   jffs2_do_clear_inode(c, f);
-   make_bad_inode(inode);
-   return;
+   goto error;
}
if (f->metadata->size == sizeof(jdev.old))
rdev = old_decode_dev(je16_to_cpu(jdev.old));
@@ -332,6 +334,16 @@ void jffs2_read_inode (struct inode *inode)
up(&f->sem);
 
D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
+   unlock_new_inode(inode);
+   return inode;
+
+error_io:
+   ret = -EIO;
+error:
+   up(&f->sem);
+   jffs2_do_clear_inode(c, f);
+   iget_failed(inode);
+   return ERR_PTR(ret);
 }
 
 void jffs2_dirty_inode(struct inode *inode)
@@ -511,15 +523,16 @@ int jffs2_do_fill_super(struct super_block *sb, void 
*data, int silent)
if ((ret = jffs2_do_mount_fs(c)))
goto out_inohash;
 
-   ret = -EINVAL;
-
D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
-   root_i = iget(sb, 1);
-   if (is_bad_inode(root_i)) {
+   root_i = jffs2_iget(sb, 1);
+   if (IS_ERR(root_i)) {
D1(printk(KERN_WARNING "get root inode failed\n"));
-   goto out_root_i;
+   ret =

[PATCH 17/30] IGET: Stop HFSPLUS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the HFSPLUS filesystem from using iget() and read_inode().  Replace
hfsplus_read_inode() with hfsplus_iget(), and call that instead of iget().
hfsplus_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

hfsplus_fill_super() returns any error incurred when getting the root inode.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/hfsplus/btree.c  |6 --
 fs/hfsplus/dir.c|6 +++---
 fs/hfsplus/hfsplus_fs.h |3 +++
 fs/hfsplus/super.c  |   44 
 4 files changed, 42 insertions(+), 17 deletions(-)

diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index 050d29c..bb54336 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -22,6 +22,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 
id)
struct hfs_btree *tree;
struct hfs_btree_header_rec *head;
struct address_space *mapping;
+   struct inode *inode;
struct page *page;
unsigned int size;
 
@@ -33,9 +34,10 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 
id)
spin_lock_init(&tree->hash_lock);
tree->sb = sb;
tree->cnid = id;
-   tree->inode = iget(sb, id);
-   if (!tree->inode)
+   inode = hfsplus_iget(sb, id);
+   if (IS_ERR(inode))
goto free_tree;
+   tree->inode = inode;
 
mapping = tree->inode->i_mapping;
page = read_mapping_page(mapping, 0, NULL);
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 1955ee6..edcb3b0 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -97,9 +97,9 @@ again:
goto fail;
}
hfs_find_exit(&fd);
-   inode = iget(dir->i_sb, cnid);
-   if (!inode)
-   return ERR_PTR(-EACCES);
+   inode = hfsplus_iget(dir->i_sb, cnid);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
if (S_ISREG(inode->i_mode))
HFSPLUS_I(inode).dev = linkid;
 out:
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index d9f5eda..d72d0a8 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -345,6 +345,9 @@ int hfsplus_parse_options(char *, struct hfsplus_sb_info *);
 void hfsplus_fill_defaults(struct hfsplus_sb_info *);
 int hfsplus_show_options(struct seq_file *, struct vfsmount *);
 
+/* super.c */
+struct inode *hfsplus_iget(struct super_block *, unsigned long);
+
 /* tables.c */
 extern u16 hfsplus_case_fold_table[];
 extern u16 hfsplus_decompose_table[];
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 7b0f2e5..0b45d97 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -20,11 +20,18 @@ static void hfsplus_destroy_inode(struct inode *inode);
 
 #include "hfsplus_fs.h"
 
-static void hfsplus_read_inode(struct inode *inode)
+struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino)
 {
struct hfs_find_data fd;
struct hfsplus_vh *vhdr;
-   int err;
+   struct inode *inode;
+   long err = -EIO;
+
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
 
INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
init_MUTEX(&HFSPLUS_I(inode).extents_lock);
@@ -41,7 +48,7 @@ static void hfsplus_read_inode(struct inode *inode)
hfs_find_exit(&fd);
if (err)
goto bad_inode;
-   return;
+   goto done;
}
vhdr = HFSPLUS_SB(inode->i_sb).s_vhdr;
switch(inode->i_ino) {
@@ -70,10 +77,14 @@ static void hfsplus_read_inode(struct inode *inode)
goto bad_inode;
}
 
-   return;
+done:
+   unlock_new_inode(inode);
+   return inode;
 
  bad_inode:
make_bad_inode(inode);
+   iput(inode);
+   return ERR_PTR(err);
 }
 
 static int hfsplus_write_inode(struct inode *inode, int unused)
@@ -262,7 +273,6 @@ static int hfsplus_remount(struct super_block *sb, int 
*flags, char *data)
 static const struct super_operations hfsplus_sops = {
.alloc_inode= hfsplus_alloc_inode,
.destroy_inode  = hfsplus_destroy_inode,
-   .read_inode = hfsplus_read_inode,
.write_inode= hfsplus_write_inode,
.clear_inode= hfsplus_clear_inode,
.put_super  = hfsplus_put_super,
@@ -278,7 +288,7 @@ static int hfsplus_fill_super(struct super_block *sb, void 
*data, int silent)
struct hfsplus_sb_info *sbi;
hfsplus_cat_entry entry;
struct hfs_find_data fd;
-   struct inode *root;
+   struct inode *root, *inode;
struct qstr str;
struct nls_table *nls = NULL;
int err = -EINVAL;
@@ -366,18 +376,25 @@ static int hfsplus_fill_super(struct super_block *sb, 
void *data, int silent)
goto cleanup;
}
 
-   HFSPLUS_SB(sb).alloc_f

[PATCH 18/30] IGET: Stop ISOFS from using read_inode()

2007-10-01 Thread David Howells
Stop the ISOFS filesystem from using read_inode().  Make isofs_read_inode()
return an error code, and make isofs_iget() pass it on.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/isofs/inode.c |   25 +
 1 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 043b470..28d990b 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -54,7 +54,7 @@ static void isofs_put_super(struct super_block *sb)
return;
 }
 
-static void isofs_read_inode(struct inode *);
+static int isofs_read_inode(struct inode *);
 static int isofs_statfs (struct dentry *, struct kstatfs *);
 
 static struct kmem_cache *isofs_inode_cachep;
@@ -107,7 +107,6 @@ static int isofs_remount(struct super_block *sb, int 
*flags, char *data)
 static const struct super_operations isofs_sops = {
.alloc_inode= isofs_alloc_inode,
.destroy_inode  = isofs_destroy_inode,
-   .read_inode = isofs_read_inode,
.put_super  = isofs_put_super,
.statfs = isofs_statfs,
.remount_fs = isofs_remount,
@@ -1186,7 +1185,7 @@ out_toomany:
goto out;
 }
 
-static void isofs_read_inode(struct inode *inode)
+static int isofs_read_inode(struct inode *inode)
 {
struct super_block *sb = inode->i_sb;
struct isofs_sb_info *sbi = ISOFS_SB(sb);
@@ -1199,6 +1198,7 @@ static void isofs_read_inode(struct inode *inode)
unsigned int de_len;
unsigned long offset;
struct iso_inode_info *ei = ISOFS_I(inode);
+   int ret = -EIO;
 
block = ei->i_iget5_block;
bh = sb_bread(inode->i_sb, block);
@@ -1216,6 +1216,7 @@ static void isofs_read_inode(struct inode *inode)
tmpde = kmalloc(de_len, GFP_KERNEL);
if (tmpde == NULL) {
printk(KERN_INFO "%s: out of memory\n", __func__);
+   ret = -ENOMEM;
goto fail;
}
memcpy(tmpde, bh->b_data + offset, frag1);
@@ -1259,8 +1260,10 @@ static void isofs_read_inode(struct inode *inode)
 
ei->i_section_size = isonum_733(de->size);
if (de->flags[-high_sierra] & 0x80) {
-   if(isofs_read_level3_size(inode))
+   ret = isofs_read_level3_size(inode);
+   if (ret < 0)
goto fail;
+   ret = -EIO;
} else {
ei->i_next_section_block = 0;
ei->i_next_section_offset = 0;
@@ -1346,16 +1349,16 @@ static void isofs_read_inode(struct inode *inode)
/* XXX - parse_rock_ridge_inode() had already set i_rdev. */
init_special_inode(inode, inode->i_mode, inode->i_rdev);
 
+   ret = 0;
 out:
kfree(tmpde);
if (bh)
brelse(bh);
-   return;
+   return ret;
 
 out_badread:
printk(KERN_WARNING "ISOFS: unable to read i-node block\n");
 fail:
-   make_bad_inode(inode);
goto out;
 }
 
@@ -1394,6 +1397,7 @@ struct inode *isofs_iget(struct super_block *sb,
unsigned long hashval;
struct inode *inode;
struct isofs_iget5_callback_data data;
+   long ret;
 
if (offset >= 1ul << sb->s_blocksize_bits)
return NULL;
@@ -1407,8 +1411,13 @@ struct inode *isofs_iget(struct super_block *sb,
&isofs_iget5_set, &data);
 
if (inode && (inode->i_state & I_NEW)) {
-   sb->s_op->read_inode(inode);
-   unlock_new_inode(inode);
+   ret = isofs_read_inode(inode);
+   if (ret < 0) {
+   iget_failed(inode);
+   inode = ERR_PTR(ret);
+   } else {
+   unlock_new_inode(inode);
+   }
}
 
return inode;

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 15/30] IGET: Stop FreeVXFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the FreeVXFS filesystem from using iget() and read_inode().  Replace
vxfs_read_inode() with vxfs_iget(), and call that instead of iget().
vxfs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

vxfs_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/freevxfs/vxfs_extern.h |2 +-
 fs/freevxfs/vxfs_inode.c  |   45 +
 fs/freevxfs/vxfs_lookup.c |6 +++---
 fs/freevxfs/vxfs_super.c  |   10 +++---
 4 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index 91ccee8..f307694 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -58,7 +58,7 @@ extern struct inode * vxfs_get_fake_inode(struct 
super_block *,
 extern voidvxfs_put_fake_inode(struct inode *);
 extern struct vxfs_inode_info *vxfs_blkiget(struct super_block *, 
u_long, ino_t);
 extern struct vxfs_inode_info *vxfs_stiget(struct super_block *, 
ino_t);
-extern voidvxfs_read_inode(struct inode *);
+extern struct inode *  vxfs_iget(struct super_block *, unsigned long);
 extern voidvxfs_clear_inode(struct inode *);
 
 /* vxfs_lookup.c */
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index d1f7c5b..aefda0e 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -129,7 +129,7 @@ fail:
  * Description:
  *  Search the for inode number @ino in the filesystem
  *  described by @sbp.  Use the specified inode table (@ilistp).
- *  Returns the matching VxFS inode on success, else a NULL pointer.
+ *  Returns the matching VxFS inode on success, else an error code.
  */
 static struct vxfs_inode_info *
 __vxfs_iget(ino_t ino, struct inode *ilistp)
@@ -157,12 +157,12 @@ __vxfs_iget(ino_t ino, struct inode *ilistp)
}
 
printk(KERN_WARNING "vxfs: error on page %p\n", pp);
-   return NULL;
+   return ERR_PTR(PTR_ERR(pp));
 
 fail:
printk(KERN_WARNING "vxfs: unable to read inode %ld\n", (unsigned 
long)ino);
vxfs_put_page(pp);
-   return NULL;
+   return ERR_PTR(-ENOMEM);
 }
 
 /**
@@ -178,7 +178,10 @@ fail:
 struct vxfs_inode_info *
 vxfs_stiget(struct super_block *sbp, ino_t ino)
 {
-return __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist);
+   struct vxfs_inode_info *vip;
+
+vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist);
+   return IS_ERR(vip) ? NULL : vip;
 }
 
 /**
@@ -282,23 +285,32 @@ vxfs_put_fake_inode(struct inode *ip)
 }
 
 /**
- * vxfs_read_inode - fill in inode information
- * @ip:inode pointer to fill
+ * vxfs_iget - get an inode
+ * @sbp:   the superblock to get the inode for
+ * @ino:   the number of the inode to get
  *
  * Description:
- *  vxfs_read_inode reads the disk inode for @ip and fills
- *  in all relevant fields in @ip.
+ *  vxfs_read_inode creates an inode, reads the disk inode for @ino and fills
+ *  in all relevant fields in the new inode.
  */
-void
-vxfs_read_inode(struct inode *ip)
+struct inode *
+vxfs_iget(struct super_block *sbp, ino_t ino)
 {
-   struct super_block  *sbp = ip->i_sb;
struct vxfs_inode_info  *vip;
const struct address_space_operations   *aops;
-   ino_t   ino = ip->i_ino;
-
-   if (!(vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist)))
-   return;
+   struct inode *ip;
+
+   ip = iget_locked(sbp, ino);
+   if (!ip)
+   return ERR_PTR(-ENOMEM);
+   if (!(ip->i_state & I_NEW))
+   return ip;
+
+   vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist);
+   if (IS_ERR(vip)) {
+   iget_failed(ip);
+   return ERR_PTR(PTR_ERR(vip));
+   }
 
vxfs_iinit(ip, vip);
 
@@ -323,7 +335,8 @@ vxfs_read_inode(struct inode *ip)
} else
init_special_inode(ip, ip->i_mode, 
old_decode_dev(vip->vii_rdev));
 
-   return;
+   unlock_new_inode(ip);
+   return ip;
 }
 
 /**
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index bf86e54..5e08418 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -213,10 +213,10 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, struct 
nameidata *nd)
lock_kernel();
ino = vxfs_inode_by_name(dip, dp);
if (ino) {
-   ip = iget(dip->i_sb, ino);
-   if (!ip) {
+   ip = vxfs_iget(dip->i_sb, ino);
+   if (IS_ERR(ip)) {
unlock_kernel();
-   return ERR_PTR(-EACCES);
+   return ERR_PTR(PTR_ERR(ip));
}
}
unlock_kernel();
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 4f95572..1dacda8

[PATCH 16/30] IGET: Stop FUSE from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the FUSE filesystem from using read_inode(), which it doesn't use anyway.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/fuse/inode.c |6 --
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 5448f62..2986654 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -73,11 +73,6 @@ static void fuse_destroy_inode(struct inode *inode)
kmem_cache_free(fuse_inode_cachep, inode);
 }
 
-static void fuse_read_inode(struct inode *inode)
-{
-   /* No op */
-}
-
 void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
  unsigned long nodeid, u64 nlookup)
 {
@@ -452,7 +447,6 @@ static struct inode *get_root_inode(struct super_block *sb, 
unsigned mode)
 static const struct super_operations fuse_super_operations = {
.alloc_inode= fuse_alloc_inode,
.destroy_inode  = fuse_destroy_inode,
-   .read_inode = fuse_read_inode,
.clear_inode= fuse_clear_inode,
.drop_inode = generic_delete_inode,
.remount_fs = fuse_remount_fs,

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 13/30] IGET: Stop EXT4 from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the EXT4 filesystem from using iget() and read_inode().  Replace
ext4_read_inode() with ext4_iget(), and call that instead of iget().
ext4_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

ext4_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/ext4/ialloc.c|   13 +
 fs/ext4/inode.c |   25 +++--
 fs/ext4/namei.c |   25 +++--
 fs/ext4/resize.c|7 +++
 fs/ext4/super.c |   36 
 include/linux/ext4_fs.h |2 +-
 6 files changed, 59 insertions(+), 49 deletions(-)

diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 427f830..8bb63f2 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -682,9 +682,14 @@ struct inode *ext4_orphan_get(struct super_block *sb, 
unsigned long ino)
 * is a valid orphan (no e2fsck run on fs).  Orphans also include
 * inodes that were being truncated, so we can't check i_nlink==0.
 */
-   if (!ext4_test_bit(bit, bitmap_bh->b_data) ||
-   !(inode = iget(sb, ino)) || is_bad_inode(inode) ||
-   NEXT_ORPHAN(inode) > max_ino) {
+   if (ext4_test_bit(bit, bitmap_bh->b_data))
+   goto out;
+
+   inode = ext4_iget(sb, ino);
+   if (IS_ERR(inode))
+   goto out;
+
+   if (NEXT_ORPHAN(inode) > max_ino) {
ext4_warning(sb, __FUNCTION__,
 "bad orphan inode %lu!  e2fsck was run?", ino);
printk(KERN_NOTICE "ext4_test_bit(bit=%d, block=%llu) = %d\n",
@@ -702,7 +707,7 @@ struct inode *ext4_orphan_get(struct super_block *sb, 
unsigned long ino)
if (inode && inode->i_nlink == 0)
inode->i_blocks = 0;
iput(inode);
-   inode = NULL;
+   inode = ERR_PTR(-EIO);
}
 out:
brelse(bitmap_bh);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index a4848e0..c4fb1eb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2595,21 +2595,31 @@ void ext4_get_inode_flags(struct ext4_inode_info *ei)
ei->i_flags |= EXT4_DIRSYNC_FL;
 }
 
-void ext4_read_inode(struct inode * inode)
+struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
 {
struct ext4_iloc iloc;
struct ext4_inode *raw_inode;
-   struct ext4_inode_info *ei = EXT4_I(inode);
+   struct ext4_inode_info *ei;
struct buffer_head *bh;
+   struct inode *inode;
+   long ret;
int block;
 
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   ei = EXT4_I(inode);
 #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
ei->i_acl = EXT4_ACL_NOT_CACHED;
ei->i_default_acl = EXT4_ACL_NOT_CACHED;
 #endif
ei->i_block_alloc_info = NULL;
 
-   if (__ext4_get_inode_loc(inode, &iloc, 0))
+   ret = __ext4_get_inode_loc(inode, &iloc, 0);
+   if (ret < 0)
goto bad_inode;
bh = iloc.bh;
raw_inode = ext4_raw_inode(&iloc);
@@ -2636,6 +2646,7 @@ void ext4_read_inode(struct inode * inode)
!(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) {
/* this inode is deleted */
brelse (bh);
+   ret = -ESTALE;
goto bad_inode;
}
/* The only unlinked inodes we let through here have
@@ -2683,6 +2694,7 @@ void ext4_read_inode(struct inode * inode)
if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
EXT4_INODE_SIZE(inode->i_sb)) {
brelse (bh);
+   ret = -EIO;
goto bad_inode;
}
if (ei->i_extra_isize == 0) {
@@ -2729,11 +2741,12 @@ void ext4_read_inode(struct inode * inode)
}
brelse (iloc.bh);
ext4_set_inode_flags(inode);
-   return;
+   unlock_new_inode(inode);
+   return inode;
 
 bad_inode:
-   make_bad_inode(inode);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(ret);
 }
 
 /*
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 5fdb862..af98d07 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1044,17 +1044,11 @@ static struct dentry *ext4_lookup(struct inode * dir, 
struct dentry *dentry, str
if (!ext4_valid_inum(dir->i_sb, ino)) {
ext4_error(dir->i_sb, "ext4_lookup",
   "bad inode number: %lu", ino);
-   inode = NULL;
-   } else
-   inode = iget(dir->i_sb, ino);
-
-   if (!inode)
return ERR_PTR(-EACCE

[PATCH 14/30] IGET: Stop FAT from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the FAT filesystem from using iget() and read_inode().  Replace
the call to iget() with a call to ilookup().

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/fat/inode.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 4baa5f2..7aa1b5f 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -629,8 +629,6 @@ static const struct super_operations fat_sops = {
.clear_inode= fat_clear_inode,
.remount_fs = fat_remount,
 
-   .read_inode = make_bad_inode,
-
.show_options   = fat_show_options,
 };
 
@@ -667,8 +665,8 @@ static struct dentry *fat_get_dentry(struct super_block 
*sb, void *inump)
struct dentry *result;
__u32 *fh = inump;
 
-   inode = iget(sb, fh[0]);
-   if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
+   inode = ilookup(sb, fh[0]);
+   if (!inode || inode->i_generation != fh[1]) {
if (inode)
iput(inode);
inode = NULL;

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/30] IGET: Stop EXT3 from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the EXT3 filesystem from using iget() and read_inode().  Replace
ext3_read_inode() with ext3_iget(), and call that instead of iget().
ext3_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

ext3_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/ext3/ialloc.c|   15 ++-
 fs/ext3/inode.c |   25 +++--
 fs/ext3/namei.c |   25 +++--
 fs/ext3/resize.c|7 +++
 fs/ext3/super.c |   41 +++--
 include/linux/ext3_fs.h |2 +-
 6 files changed, 63 insertions(+), 52 deletions(-)

diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index e45dbd6..c2f0a0d 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -646,7 +646,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, 
unsigned long ino)
unsigned long block_group;
int bit;
struct buffer_head *bitmap_bh = NULL;
-   struct inode *inode = NULL;
+   struct inode *inode = ERR_PTR(-EIO);
 
/* Error cases - e2fsck has already cleaned up for us */
if (ino > max_ino) {
@@ -668,9 +668,14 @@ struct inode *ext3_orphan_get(struct super_block *sb, 
unsigned long ino)
 * is a valid orphan (no e2fsck run on fs).  Orphans also include
 * inodes that were being truncated, so we can't check i_nlink==0.
 */
-   if (!ext3_test_bit(bit, bitmap_bh->b_data) ||
-   !(inode = iget(sb, ino)) || is_bad_inode(inode) ||
-   NEXT_ORPHAN(inode) > max_ino) {
+   if (ext3_test_bit(bit, bitmap_bh->b_data))
+   goto out;
+
+   inode = ext3_iget(sb, ino);
+   if (IS_ERR(inode))
+   goto out;
+
+   if (NEXT_ORPHAN(inode) > max_ino) {
ext3_warning(sb, __FUNCTION__,
 "bad orphan inode %lu!  e2fsck was run?", ino);
printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
@@ -688,7 +693,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, 
unsigned long ino)
if (inode && inode->i_nlink == 0)
inode->i_blocks = 0;
iput(inode);
-   inode = NULL;
+   inode = ERR_PTR(-EIO);
}
 out:
brelse(bitmap_bh);
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index de4e316..6c74622 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2591,21 +2591,31 @@ void ext3_get_inode_flags(struct ext3_inode_info *ei)
ei->i_flags |= EXT3_DIRSYNC_FL;
 }
 
-void ext3_read_inode(struct inode * inode)
+struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
 {
struct ext3_iloc iloc;
struct ext3_inode *raw_inode;
-   struct ext3_inode_info *ei = EXT3_I(inode);
+   struct ext3_inode_info *ei;
struct buffer_head *bh;
+   struct inode *inode;
+   long ret;
int block;
 
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   ei = EXT3_I(inode);
 #ifdef CONFIG_EXT3_FS_POSIX_ACL
ei->i_acl = EXT3_ACL_NOT_CACHED;
ei->i_default_acl = EXT3_ACL_NOT_CACHED;
 #endif
ei->i_block_alloc_info = NULL;
 
-   if (__ext3_get_inode_loc(inode, &iloc, 0))
+   ret = __ext3_get_inode_loc(inode, &iloc, 0);
+   if (ret < 0)
goto bad_inode;
bh = iloc.bh;
raw_inode = ext3_raw_inode(&iloc);
@@ -2636,6 +2646,7 @@ void ext3_read_inode(struct inode * inode)
!(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) {
/* this inode is deleted */
brelse (bh);
+   ret = -ESTALE;
goto bad_inode;
}
/* The only unlinked inodes we let through here have
@@ -2679,6 +2690,7 @@ void ext3_read_inode(struct inode * inode)
if (EXT3_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
EXT3_INODE_SIZE(inode->i_sb)) {
brelse (bh);
+   ret = -EIO;
goto bad_inode;
}
if (ei->i_extra_isize == 0) {
@@ -2720,11 +2732,12 @@ void ext3_read_inode(struct inode * inode)
}
brelse (iloc.bh);
ext3_set_inode_flags(inode);
-   return;
+   unlock_new_inode(inode);
+   return inode;
 
 bad_inode:
-   make_bad_inode(inode);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(ret);
 }
 
 /*
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index c1fa190..78bfab5 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1046,17 +1046,11 @@ static struct dentry *ext3_lookup(struct inode * dir, 
struct dentry *dentry, str

[PATCH 11/30] IGET: Stop EXT2 from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the EXT2 filesystem from using iget() and read_inode().  Replace
ext2_read_inode() with ext2_iget(), and call that instead of iget().
ext2_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

ext2_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/ext2/ext2.h  |2 +-
 fs/ext2/inode.c |   26 +++---
 fs/ext2/namei.c |   12 ++--
 fs/ext2/super.c |   32 ++--
 4 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 9fd0ec5..85ca3de 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -123,7 +123,7 @@ extern void ext2_check_inodes_bitmap (struct super_block *);
 extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
 
 /* inode.c */
-extern void ext2_read_inode (struct inode *);
+extern struct inode *ext2_iget (struct super_block *, unsigned long);
 extern int ext2_write_inode (struct inode *, int);
 extern void ext2_put_inode (struct inode *);
 extern void ext2_delete_inode (struct inode *);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 0079b2c..d8fb795 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1074,18 +1074,28 @@ void ext2_get_inode_flags(struct ext2_inode_info *ei)
ei->i_flags |= EXT2_DIRSYNC_FL;
 }
 
-void ext2_read_inode (struct inode * inode)
+struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
 {
-   struct ext2_inode_info *ei = EXT2_I(inode);
-   ino_t ino = inode->i_ino;
+   struct ext2_inode_info *ei;
struct buffer_head * bh;
-   struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
+   struct ext2_inode * raw_inode;
+   struct inode *inode;
+   long ret = -EIO;
int n;
 
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   ei = EXT2_I(inode);
 #ifdef CONFIG_EXT2_FS_POSIX_ACL
ei->i_acl = EXT2_ACL_NOT_CACHED;
ei->i_default_acl = EXT2_ACL_NOT_CACHED;
 #endif
+
+   raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
if (IS_ERR(raw_inode))
goto bad_inode;
 
@@ -,6 +1121,7 @@ void ext2_read_inode (struct inode * inode)
if (inode->i_nlink == 0 && (inode->i_mode == 0 || ei->i_dtime)) {
/* this inode is deleted */
brelse (bh);
+   ret = -ESTALE;
goto bad_inode;
}
inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
@@ -1180,11 +1191,12 @@ void ext2_read_inode (struct inode * inode)
}
brelse (bh);
ext2_set_inode_flags(inode);
-   return;
+   unlock_new_inode(inode);
+   return inode;

 bad_inode:
-   make_bad_inode(inode);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(ret);
 }
 
 static int ext2_update_inode(struct inode * inode, int do_sync)
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index e69beed..2dfdeaa 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -63,9 +63,9 @@ static struct dentry *ext2_lookup(struct inode * dir, struct 
dentry *dentry, str
ino = ext2_inode_by_name(dir, dentry);
inode = NULL;
if (ino) {
-   inode = iget(dir->i_sb, ino);
-   if (!inode)
-   return ERR_PTR(-EACCES);
+   inode = ext2_iget(dir->i_sb, ino);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
}
return d_splice_alias(inode, dentry);
 }
@@ -83,10 +83,10 @@ struct dentry *ext2_get_parent(struct dentry *child)
ino = ext2_inode_by_name(child->d_inode, &dotdot);
if (!ino)
return ERR_PTR(-ENOENT);
-   inode = iget(child->d_inode->i_sb, ino);
+   inode = ext2_iget(child->d_inode->i_sb, ino);
 
-   if (!inode)
-   return ERR_PTR(-EACCES);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
parent = d_alloc_anon(inode);
if (!parent) {
iput(inode);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 639a32c..78641e3 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -232,7 +232,6 @@ static ssize_t ext2_quota_write(struct super_block *sb, int 
type, const char *da
 static const struct super_operations ext2_sops = {
.alloc_inode= ext2_alloc_inode,
.destroy_inode  = ext2_destroy_inode,
-   .read_inode = ext2_read_inode,
.write_inode= ext2_write_inode,
.put_inode  = ext2_put_inode,
.delete_inode   = ext2_delete_inode,
@@ -266,11 +265,10 @@ static struct dentry *ext2_get_dentry(struct super_block 
*sb, void *vobjp)
 * it might be "neater" to call ext2_get_inode first and check
 * if the inode is valid.

[PATCH 09/30] IGET: Stop CIFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the CIFS filesystem from using iget() and read_inode().  Replace
cifs_read_inode() with cifs_iget(), and call that instead of iget().
cifs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

cifs_read_super() now returns any error incurred when getting the root inode
instead of ENOMEM.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/cifs/cifsfs.c |8 
 fs/cifs/cifsfs.h |1 +
 fs/cifs/inode.c  |   35 ++-
 3 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index cabb6a5..1cb13f5 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -126,10 +126,11 @@ cifs_read_super(struct super_block *sb, void *data,
 #endif
sb->s_blocksize = CIFS_MAX_MSGSIZE;
sb->s_blocksize_bits = 14;  /* default 2**14 = CIFS_MAX_MSGSIZE */
-   inode = iget(sb, ROOT_I);
+   inode = cifs_iget(sb, ROOT_I);
 
-   if (!inode) {
-   rc = -ENOMEM;
+   if (IS_ERR(inode)) {
+   rc = PTR_ERR(inode);
+   inode = NULL;
goto out_no_root;
}
 
@@ -481,7 +482,6 @@ static int cifs_remount(struct super_block *sb, int *flags, 
char *data)
 }
 
 static const struct super_operations cifs_super_ops = {
-   .read_inode = cifs_read_inode,
.put_super = cifs_put_super,
.statfs = cifs_statfs,
.alloc_inode = cifs_alloc_inode,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index a20de77..74a3190 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -43,6 +43,7 @@ extern void cifs_read_inode(struct inode *);
 
 /* Functions related to inodes */
 extern const struct inode_operations cifs_dir_inode_ops;
+extern struct inode *cifs_iget(struct super_block *, unsigned long);
 extern int cifs_create(struct inode *, struct dentry *, int,
   struct nameidata *);
 extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index dd41677..48966b9 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -576,20 +576,37 @@ int cifs_get_inode_info(struct inode **pinode,
 }
 
 /* gets root inode */
-void cifs_read_inode(struct inode *inode)
+struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
 {
int xid;
struct cifs_sb_info *cifs_sb;
+   struct inode *inode;
+   long ret;
 
-   cifs_sb = CIFS_SB(inode->i_sb);
-   xid = GetXid();
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (inode->i_state & I_NEW) {
+   cifs_sb = CIFS_SB(inode->i_sb);
+   xid = GetXid();
 
-   if (cifs_sb->tcon->unix_ext)
-   cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
-   else
-   cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
-   /* can not call macro FreeXid here since in a void func */
-   _FreeXid(xid);
+   if (cifs_sb->tcon->unix_ext)
+   ret = cifs_get_inode_info_unix(&inode, "", inode->i_sb,
+  xid);
+   else
+   ret = cifs_get_inode_info(&inode, "", NULL, inode->i_sb,
+ xid);
+   /* can not call macro FreeXid here since in a void func */
+   _FreeXid(xid);
+   if (ret < 0) {
+   iget_failed(inode);
+   inode = ERR_PTR(ret);
+   } else {
+   unlock_new_inode(inode);
+   }
+   }
+
+   return inode;
 }
 
 int cifs_unlink(struct inode *inode, struct dentry *direntry)

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/30] IGET: Stop EFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the EFS filesystem from using iget() and read_inode().  Replace
efs_read_inode() with efs_iget(), and call that instead of iget().
efs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

efs_fill_super() returns any error incurred when getting the root inode
instead of EACCES.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/efs/inode.c |   25 +
 fs/efs/namei.c |   23 ---
 fs/efs/super.c |   18 --
 include/linux/efs_fs.h |2 +-
 4 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/fs/efs/inode.c b/fs/efs/inode.c
index 174696f..627c302 100644
--- a/fs/efs/inode.c
+++ b/fs/efs/inode.c
@@ -45,17 +45,26 @@ static inline void extent_copy(efs_extent *src, efs_extent 
*dst) {
return;
 }
 
-void efs_read_inode(struct inode *inode)
+struct inode *efs_iget(struct super_block *super, unsigned long ino)
 {
int i, inode_index;
dev_t device;
u32 rdev;
struct buffer_head *bh;
-   struct efs_sb_info*sb = SUPER_INFO(inode->i_sb);
-   struct efs_inode_info *in = INODE_INFO(inode);
+   struct efs_sb_info*sb = SUPER_INFO(super);
+   struct efs_inode_info *in;
efs_block_t block, offset;
struct efs_dinode *efs_inode;
-  
+   struct inode *inode;
+
+   inode = iget_locked(super, ino);
+   if (IS_ERR(inode))
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   in = INODE_INFO(inode);
+
/*
** EFS layout:
**
@@ -159,13 +168,13 @@ void efs_read_inode(struct inode *inode)
break;
}
 
-   return;
+   unlock_new_inode(inode);
+   return inode;
 
 read_inode_error:
printk(KERN_WARNING "EFS: failed to read inode %lu\n", inode->i_ino);
-   make_bad_inode(inode);
-
-   return;
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
 }
 
 static inline efs_block_t
diff --git a/fs/efs/namei.c b/fs/efs/namei.c
index 5276b19..7ad3694 100644
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -64,9 +64,10 @@ struct dentry *efs_lookup(struct inode *dir, struct dentry 
*dentry, struct namei
lock_kernel();
inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
if (inodenum) {
-   if (!(inode = iget(dir->i_sb, inodenum))) {
+   inode = efs_iget(dir->i_sb, inodenum);
+   if (IS_ERR(inode)) {
unlock_kernel();
-   return ERR_PTR(-EACCES);
+   return ERR_PTR(PTR_ERR(inode));
}
}
unlock_kernel();
@@ -85,12 +86,11 @@ struct dentry *efs_get_dentry(struct super_block *sb, void 
*vobjp)
 
if (ino == 0)
return ERR_PTR(-ESTALE);
-   inode = iget(sb, ino);
-   if (inode == NULL)
-   return ERR_PTR(-ENOMEM);
+   inode = efs_iget(sb, ino);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
 
-   if (is_bad_inode(inode) ||
-   (generation && inode->i_generation != generation)) {
+   if (generation && inode->i_generation != generation) {
result = ERR_PTR(-ESTALE);
goto out_iput;
}
@@ -112,7 +112,7 @@ struct dentry *efs_get_parent(struct dentry *child)
struct dentry *parent;
struct inode *inode;
efs_ino_t ino;
-   int error;
+   long error;
 
lock_kernel();
 
@@ -121,10 +121,11 @@ struct dentry *efs_get_parent(struct dentry *child)
if (!ino)
goto fail;
 
-   error = -EACCES;
-   inode = iget(child->d_inode->i_sb, ino);
-   if (!inode)
+   inode = efs_iget(child->d_inode->i_sb, ino);
+   if (IS_ERR(inode)) {
+   error = PTR_ERR(inode);
goto fail;
+   }
 
error = -ENOMEM;
parent = d_alloc_anon(inode);
diff --git a/fs/efs/super.c b/fs/efs/super.c
index ce4acb8..685279d 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -107,7 +107,6 @@ static int efs_remount(struct super_block *sb, int *flags, 
char *data)
 static const struct super_operations efs_superblock_operations = {
.alloc_inode= efs_alloc_inode,
.destroy_inode  = efs_destroy_inode,
-   .read_inode = efs_read_inode,
.put_super  = efs_put_super,
.statfs = efs_statfs,
.remount_fs = efs_remount,
@@ -246,6 +245,7 @@ static int efs_fill_super(struct super_block *s, void *d, 
int silent)
struct efs_sb_info *sb;
struct buffer_head *bh;
struct inode *root;
+   int ret = -EINVAL;
 
sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL);
if (!sb)
@@ -302,12 +302,18 @@ static int efs_fill_super(struct super_block *s, void *d, 
int silent)
}
s->s_op   = &

[PATCH 07/30] IGET: Stop BEFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the BEFS filesystem from using iget() and read_inode().  Replace
befs_read_inode() with befs_iget(), and call that instead of iget().
befs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

befs_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/befs/linuxvfs.c |   39 +--
 1 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index a451418..a460b28 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -35,7 +35,7 @@ static int befs_get_block(struct inode *, sector_t, struct 
buffer_head *, int);
 static int befs_readpage(struct file *file, struct page *page);
 static sector_t befs_bmap(struct address_space *mapping, sector_t block);
 static struct dentry *befs_lookup(struct inode *, struct dentry *, struct 
nameidata *);
-static void befs_read_inode(struct inode *ino);
+static struct inode *befs_iget(struct super_block *, unsigned long);
 static struct inode *befs_alloc_inode(struct super_block *sb);
 static void befs_destroy_inode(struct inode *inode);
 static int befs_init_inodecache(void);
@@ -52,7 +52,6 @@ static int befs_statfs(struct dentry *, struct kstatfs *);
 static int parse_options(char *, befs_mount_options *);
 
 static const struct super_operations befs_sops = {
-   .read_inode = befs_read_inode,  /* initialize & read inode */
.alloc_inode= befs_alloc_inode, /* allocate a new inode */
.destroy_inode  = befs_destroy_inode, /* deallocate an inode */
.put_super  = befs_put_super,   /* uninit super */
@@ -198,9 +197,9 @@ befs_lookup(struct inode *dir, struct dentry *dentry, 
struct nameidata *nd)
return ERR_PTR(-ENODATA);
}
 
-   inode = iget(dir->i_sb, (ino_t) offset);
-   if (!inode)
-   return ERR_PTR(-EACCES);
+   inode = befs_iget(dir->i_sb, (ino_t) offset);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
 
d_add(dentry, inode);
 
@@ -296,17 +295,23 @@ static void init_once(void * foo, struct kmem_cache * 
cachep, unsigned long flag
inode_init_once(&bi->vfs_inode);
 }
 
-static void
-befs_read_inode(struct inode *inode)
+static struct inode *befs_iget(struct super_block *sb, unsigned long ino)
 {
struct buffer_head *bh = NULL;
befs_inode *raw_inode = NULL;
 
-   struct super_block *sb = inode->i_sb;
befs_sb_info *befs_sb = BEFS_SB(sb);
befs_inode_info *befs_ino = NULL;
+   struct inode *inode;
+   long ret = -EIO;
 
-   befs_debug(sb, "---> befs_read_inode() " "inode = %lu", inode->i_ino);
+   befs_debug(sb, "---> befs_read_inode() " "inode = %lu", ino);
+
+   inode = iget_locked(sb, ino);
+   if (IS_ERR(inode))
+   return inode;
+   if (!(inode->i_state & I_NEW))
+   return inode;
 
befs_ino = BEFS_I(inode);
 
@@ -402,15 +407,16 @@ befs_read_inode(struct inode *inode)
 
brelse(bh);
befs_debug(sb, "<--- befs_read_inode()");
-   return;
+   unlock_new_inode(inode);
+   return inode;
 
   unacquire_bh:
brelse(bh);
 
   unacquire_none:
-   make_bad_inode(inode);
+   iget_failed(inode);
befs_debug(sb, "<--- befs_read_inode() - Bad inode");
-   return;
+   return ERR_PTR(ret);
 }
 
 /* Initialize the inode cache. Called at fs setup.
@@ -752,6 +758,7 @@ befs_fill_super(struct super_block *sb, void *data, int 
silent)
befs_sb_info *befs_sb;
befs_super_block *disk_sb;
struct inode *root;
+   long ret = -EINVAL;
 
const unsigned long sb_block = 0;
const off_t x86_sb_off = 512;
@@ -833,7 +840,11 @@ befs_fill_super(struct super_block *sb, void *data, int 
silent)
/* Set real blocksize of fs */
sb_set_blocksize(sb, (ulong) befs_sb->block_size);
sb->s_op = (struct super_operations *) &befs_sops;
-   root = iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir)));
+   root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir)));
+   if (IS_ERR(root)) {
+   ret = PTR_ERR(root);
+   goto unacquire_priv_sbp;
+   }
sb->s_root = d_alloc_root(root);
if (!sb->s_root) {
iput(root);
@@ -868,7 +879,7 @@ befs_fill_super(struct super_block *sb, void *data, int 
silent)
 
   unacquire_none:
sb->s_fs_info = NULL;
-   return -EINVAL;
+   return ret;
 }
 
 static int

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/30] IGET: Stop BFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the BFS filesystem from using iget() and read_inode().  Replace
bfs_read_inode() with bfs_iget(), and call that instead of iget().
bfs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

bfs_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/bfs/bfs.h   |2 ++
 fs/bfs/dir.c   |6 +++---
 fs/bfs/inode.c |   32 ++--
 3 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h
index 130f6c6..5cf50d4 100644
--- a/fs/bfs/bfs.h
+++ b/fs/bfs/bfs.h
@@ -46,6 +46,8 @@ static inline struct bfs_inode_info *BFS_I(struct inode 
*inode)
 #define printf(format, args...) \
printk(KERN_ERR "BFS-fs: %s(): " format, __FUNCTION__, ## args)
 
+/* inode.c */
+extern struct inode *bfs_iget(struct super_block *sb, unsigned long ino);
 
 /* file.c */
 extern const struct inode_operations bfs_file_inops;
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index 097f149..dfa0246 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -141,10 +141,10 @@ static struct dentry * bfs_lookup(struct inode * dir, 
struct dentry * dentry, st
if (bh) {
unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
brelse(bh);
-   inode = iget(dir->i_sb, ino);
-   if (!inode) {
+   inode = bfs_iget(dir->i_sb, ino);
+   if (IS_ERR(inode)) {
unlock_kernel();
-   return ERR_PTR(-EACCES);
+   return ERR_PTR(PTR_ERR(inode));
}
}
unlock_kernel();
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index f346eb1..76798c9 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -32,25 +32,29 @@ MODULE_LICENSE("GPL");
 
 void dump_imap(const char *prefix, struct super_block * s);
 
-static void bfs_read_inode(struct inode * inode)
+struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
 {
-   unsigned long ino = inode->i_ino;
struct bfs_inode * di;
struct buffer_head * bh;
+   struct inode *inode;
int block, off;
 
+   inode = iget_locked(sb, ino);
+   if (IS_ERR(inode))
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
if (ino < BFS_ROOT_INO || ino > BFS_SB(inode->i_sb)->si_lasti) {
printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino);
-   make_bad_inode(inode);
-   return;
+   goto error;
}
 
block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
bh = sb_bread(inode->i_sb, block);
if (!bh) {
printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id, 
ino);
-   make_bad_inode(inode);
-   return;
+   goto error;
}
 
off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
@@ -85,6 +89,12 @@ static void bfs_read_inode(struct inode * inode)
BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); /* can be 0 so we 
store a copy */
 
brelse(bh);
+   unlock_new_inode(inode);
+   return inode;
+
+error:
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
 }
 
 static int bfs_write_inode(struct inode * inode, int unused)
@@ -271,7 +281,6 @@ static void destroy_inodecache(void)
 static const struct super_operations bfs_sops = {
.alloc_inode= bfs_alloc_inode,
.destroy_inode  = bfs_destroy_inode,
-   .read_inode = bfs_read_inode,
.write_inode= bfs_write_inode,
.delete_inode   = bfs_delete_inode,
.put_super  = bfs_put_super,
@@ -306,6 +315,7 @@ static int bfs_fill_super(struct super_block *s, void 
*data, int silent)
struct inode * inode;
unsigned i, imap_len;
struct bfs_sb_info * info;
+   long ret = -EINVAL;
 
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -340,14 +350,16 @@ static int bfs_fill_super(struct super_block *s, void 
*data, int silent)
set_bit(i, info->si_imap);
 
s->s_op = &bfs_sops;
-   inode = iget(s, BFS_ROOT_INO);
-   if (!inode) {
+   inode = bfs_iget(s, BFS_ROOT_INO);
+   if (IS_ERR(inode)) {
+   ret = PTR_ERR(inode);
kfree(info->si_imap);
goto out;
}
s->s_root = d_alloc_root(inode);
if (!s->s_root) {
iput(inode);
+   ret = -ENOMEM;
kfree(info->si_imap);
goto out;
}
@@ -402,7 +414,7 @@ out:
brelse(bh);
kfree(info);
s->s_fs_info = NULL;
-   return -EINVAL;
+   return ret;
 }
 
 static int bfs_get_sb(struct file_system_type *fs_type,

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED

[PATCH 05/30] IGET: Stop AFFS from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the AFFS filesystem from using iget() and read_inode().  Replace
affs_read_inode() with affs_iget(), and call that instead of iget().
affs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

affs_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/affs/affs.h |2 +-
 fs/affs/amigaffs.c |6 --
 fs/affs/inode.c|   20 +---
 fs/affs/namei.c|7 +++
 fs/affs/super.c|   12 +---
 5 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index 232c694..0bce4ff 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -174,7 +174,7 @@ extern void  affs_put_inode(struct inode 
*inode);
 extern void affs_drop_inode(struct inode *inode);
 extern void affs_delete_inode(struct inode *inode);
 extern void affs_clear_inode(struct inode *inode);
-extern void affs_read_inode(struct inode *inode);
+extern struct inode*affs_iget(struct super_block *sb, unsigned 
long ino);
 extern int  affs_write_inode(struct inode *inode, int);
 extern int  affs_add_entry(struct inode *dir, struct inode 
*inode, struct dentry *dentry, s32 type);
 
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index f4de4b9..8055730 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -170,9 +170,11 @@ affs_remove_link(struct dentry *dentry)
if (!link_bh)
goto done;
 
-   dir = iget(sb, be32_to_cpu(AFFS_TAIL(sb, link_bh)->parent));
-   if (!dir)
+   dir = affs_iget(sb, be32_to_cpu(AFFS_TAIL(sb, 
link_bh)->parent));
+   if (IS_ERR(dir)) {
+   retval = PTR_ERR(dir);
goto done;
+   }
 
affs_lock_dir(dir);
affs_fix_dcache(dentry, link_ino);
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 4609a6c..edea76c 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -15,20 +15,25 @@
 extern const struct inode_operations affs_symlink_inode_operations;
 extern struct timezone sys_tz;
 
-void
-affs_read_inode(struct inode *inode)
+struct inode *affs_iget(struct super_block *sb, unsigned long ino)
 {
-   struct super_block  *sb = inode->i_sb;
struct affs_sb_info *sbi = AFFS_SB(sb);
struct buffer_head  *bh;
struct affs_head*head;
struct affs_tail*tail;
+   struct inode*inode;
u32  block;
u32  size;
u32  prot;
u16  id;
 
-   pr_debug("AFFS: read_inode(%lu)\n",inode->i_ino);
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
+
+   pr_debug("AFFS: affs_iget(%lu)\n",inode->i_ino);
 
block = inode->i_ino;
bh = affs_bread(sb, block);
@@ -154,12 +159,13 @@ affs_read_inode(struct inode *inode)
 sys_tz.tz_minuteswest * 60;
inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 
inode->i_atime.tv_nsec = 0;
affs_brelse(bh);
-   return;
+   unlock_new_inode(inode);
+   return inode;
 
 bad_inode:
-   make_bad_inode(inode);
affs_brelse(bh);
-   return;
+   iget_failed(inode);
+   return ERR_PTR(-EIO);
 }
 
 int
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index a42143c..4c38282 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -223,10 +223,9 @@ affs_lookup(struct inode *dir, struct dentry *dentry, 
struct nameidata *nd)
ino = be32_to_cpu(AFFS_TAIL(sb, bh)->original);
}
affs_brelse(bh);
-   inode = iget(sb, ino);
-   if (!inode) {
-   return ERR_PTR(-EACCES);
-   }
+   inode = affs_iget(sb, ino);
+   if (IS_ERR(inode))
+   return ERR_PTR(PTR_ERR(inode));
}
dentry->d_op = AFFS_SB(sb)->s_flags & SF_INTL ? 
&affs_intl_dentry_operations : &affs_dentry_operations;
d_add(dentry, inode);
diff --git a/fs/affs/super.c b/fs/affs/super.c
index c80191a..f005050 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -113,7 +113,6 @@ static void destroy_inodecache(void)
 static const struct super_operations affs_sops = {
.alloc_inode= affs_alloc_inode,
.destroy_inode  = affs_destroy_inode,
-   .read_inode = affs_read_inode,
.write_inode= affs_write_inode,
.put_inode  = affs_put_inode,
.drop_inode = affs_drop_inode,
@@ -271,6 +270,7 @@ static int affs_fill_super(struct super_blo

[PATCH 06/30] IGET: Stop autofs from using iget() and read_inode()

2007-10-01 Thread David Howells
Stop the autofs filesystem from using iget() and read_inode().  Replace
autofs_read_inode() with autofs_iget(), and call that instead of iget().
autofs_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/autofs/autofs_i.h |1 +
 fs/autofs/inode.c|   27 ++-
 fs/autofs/root.c |   22 ++
 3 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 8b4cca3..901a3e6 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -150,6 +150,7 @@ extern const struct file_operations autofs_root_operations;
 
 int autofs_fill_super(struct super_block *, void *, int);
 void autofs_kill_sb(struct super_block *sb);
+struct inode *autofs_iget(struct super_block *, unsigned long);
 
 /* Queue management functions */
 
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index e7204d7..fc6a15e 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -52,10 +52,7 @@ out_kill_sb:
kill_anon_super(sb);
 }
 
-static void autofs_read_inode(struct inode *inode);
-
 static const struct super_operations autofs_sops = {
-   .read_inode = autofs_read_inode,
.statfs = simple_statfs,
 };
 
@@ -164,7 +161,9 @@ int autofs_fill_super(struct super_block *s, void *data, 
int silent)
s->s_time_gran = 1;
sbi->sb = s;
 
-   root_inode = iget(s, AUTOFS_ROOT_INO);
+   root_inode = autofs_iget(s, AUTOFS_ROOT_INO);
+   if (IS_ERR(root_inode))
+   goto fail_free;
root = d_alloc_root(root_inode);
pipe = NULL;
 
@@ -230,11 +229,17 @@ fail_unlock:
return -EINVAL;
 }
 
-static void autofs_read_inode(struct inode *inode)
+struct inode *autofs_iget(struct super_block *sb, unsigned long ino)
 {
-   ino_t ino = inode->i_ino;
unsigned int n;
-   struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
+   struct autofs_sb_info *sbi = autofs_sbi(sb);
+   struct inode *inode;
+
+   inode = iget_locked(sb, ino);
+   if (!inode)
+   return ERR_PTR(-ENOMEM);
+   if (!(inode->i_state & I_NEW))
+   return inode;
 
/* Initialize to the default case (stub directory) */
 
@@ -250,7 +255,7 @@ static void autofs_read_inode(struct inode *inode)
inode->i_op = &autofs_root_inode_operations;
inode->i_fop = &autofs_root_operations;
inode->i_uid = inode->i_gid = 0; /* Changed in read_super */
-   return;
+   goto done;
} 

inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
@@ -263,7 +268,7 @@ static void autofs_read_inode(struct inode *inode)
n = ino - AUTOFS_FIRST_SYMLINK;
if (n >= AUTOFS_MAX_SYMLINKS || 
!test_bit(n,sbi->symlink_bitmap)) {
printk("autofs: Looking for bad symlink inode %u\n", 
(unsigned int) ino);
-   return;
+   goto done;
}

inode->i_op = &autofs_symlink_inode_operations;
@@ -275,4 +280,8 @@ static void autofs_read_inode(struct inode *inode)
inode->i_size = sl->len;
inode->i_nlink = 1;
}
+
+done:
+   unlock_new_inode(inode);
+   return inode;
 }
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index c148953..3aec567 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -114,8 +114,8 @@ static int try_to_fill_dentry(struct dentry *dentry, struct 
super_block *sb, str
dentry->d_time = (unsigned long) ent;

if (!dentry->d_inode) {
-   inode = iget(sb, ent->ino);
-   if (!inode) {
+   inode = autofs_iget(sb, ent->ino);
+   if (IS_ERR(inode)) {
/* Failed, but leave pending for next time */
return 1;
}
@@ -274,6 +274,7 @@ static int autofs_root_symlink(struct inode *dir, struct 
dentry *dentry, const c
unsigned int n;
int slsize;
struct autofs_symlink *sl;
+   struct inode *inode;
 
DPRINTK(("autofs_root_symlink: %s <- ", symname));
autofs_say(dentry->d_name.name,dentry->d_name.len);
@@ -331,7 +332,12 @@ static int autofs_root_symlink(struct inode *dir, struct 
dentry *dentry, const c
ent->dentry = NULL; /* We don't keep the dentry for symlinks */
 
autofs_hash_insert(dh,ent);
-   d_instantiate(dentry, iget(dir->i_sb,ent->ino));
+
+   inode = autofs_iget(dir->i_sb, ent->ino);
+   if (IS_ERR(inode))
+   return PTR_ERR(inode);
+
+   d_instantiate(dentry, inode);
unlock_kernel();
return 0;
 }
@@ -428,6 +434,7 @@ static int autofs_root_mkdir(struct inode *dir, struct 
dentry *dentry, int mode)
struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb)

[PATCH 04/30] IGET: Mark iget() and read_inode() as being obsolete

2007-10-01 Thread David Howells
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;
}

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 Documentation/filesystems/Exporting |5 -
 Documentation/filesystems/Locking   |3 ---
 Documentation/filesystems/vfs.txt   |   16 +---
 fs/inode.c  |   16 
 include/linux/fs.h  |   16 +++-
 5 files changed, 24 insertions(+), 32 deletions(-)

diff --git a/Documentation/filesystems/Exporting 
b/Documentation/filesystems/Exporting
index 31047e0..22ce3b2 100644
--- a/Documentation/filesystems/Exporting
+++ b/Documentation/filesystems/Exporting
@@ -144,11 +144,6 @@ filesystem:
 decode_fh passes two datums through find_exported_dentry.  One that 
 should be used to identify the target object, and one that can be
 used to identify the object's parent, should that be necessary.
-The default get_dentry function assumes that the datum contains an
-inode number and a generation number, and it attempts to get the
-inode using "iget" and check it's validity by matching the
-generation number.  A filesystem should only depend on the default
-if iget can safely be used this way.
 
 If decode_fh and/or encode_fh are left as NULL, then default
 implementations are used.  These defaults are suitable for ext2 and 
diff --git a/Documentation/filesystems/Locking 
b/Documentation/filesystems/Locking
index f0f8258..d155893 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -90,7 +90,6 @@ of the locking scheme for directory operations.
 prototypes:
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
-   void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int);
void (*put_inode) (struct inode *);
@@ -114,7 +113,6 @@ locking rules:
BKL s_lock  s_umount
 alloc_inode:   no  no  no
 destroy_inode: no
-read_inode:no  (see below)
 dirty_inode:   no  (must not sleep)
 write_inode:   no
 put_inode: no
@@ -133,7 +131,6 @@ show_options:   no  
(vfsmount->sem)
 quota_read: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.
 When called from get_sb_single, it does NOT have the s_umount lock.
 ->quota_read() and ->quota_write() functions are both guaranteed to
diff --git a/Documentation/filesystems/vfs.txt 
b/Documentation/filesystems/vfs.txt
index 045f3e0..63c7e91 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -242,14 +242,8 @@ or bottom half).
->alloc_inode was defined and simply undoes anything done by
->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.
+  read_inode: deprecated, do not use.  Use iget_locked() instead of iget() and
+   return a proper error value.
 
   dirty_inode: this method is called by the VFS to mark an inode dirty.
 

[PATCH 02/30] IGET: Use iget_failed() in AFS

2007-10-01 Thread David Howells
Use iget_failed() in AFS to kill a failed inode.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/afs/inode.c |5 +
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index d196840..ca9b02f 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -196,10 +196,7 @@ struct inode *afs_iget(struct super_block *sb, struct key 
*key,
 
/* failure */
 bad_inode:
-   make_bad_inode(inode);
-   unlock_new_inode(inode);
-   iput(inode);
-
+   iget_failed(inode);
_leave(" = %d [bad]", ret);
return ERR_PTR(ret);
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 03/30] IGET: Use iget_failed() in GFS2

2007-10-01 Thread David Howells
Use iget_failed() in GFS2 to kill a failed inode.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 fs/gfs2/inode.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 34f7bcd..498844f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -185,7 +185,7 @@ fail_put:
ip->i_gl->gl_object = NULL;
gfs2_glock_put(ip->i_gl);
 fail:
-   iput(inode);
+   iget_failed(inode);
return ERR_PTR(error);
 }
 

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/30] IGET: Introduce a function to register iget failure

2007-10-01 Thread David Howells
Introduce a function to register failure in an inode construction path.  This
includes marking the inode under construction as bad, unlocking it and
releasing it.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 Documentation/filesystems/porting |   18 +-
 fs/bad_inode.c|   14 ++
 include/linux/fs.h|1 +
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/Documentation/filesystems/porting 
b/Documentation/filesystems/porting
index dac45c9..3b0fb22 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -184,11 +184,19 @@ just takes the superblock and inode number as arguments 
and does the
 test and set for you.
 
 e.g.
-   inode = iget_locked(sb, ino);
-   if (inode->i_state & I_NEW) {
-   read_inode_from_disk(inode);
-   unlock_new_inode(inode);
-   }
+   inode = iget_locked(sb, ino);
+   if (inode->i_state & I_NEW) {
+   err = read_inode_from_disk(inode);
+   if (err < 0) {
+   iget_failed(inode);
+   return err;
+   }
+   unlock_new_inode(inode);
+   }
+
+Note that if the process of setting up a new inode fails, then iget_failed()
+should be called on the inode to render it dead, and an appropriate error
+should be passed back to the caller.
 
 ---
 [recommended]
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 521ff7c..f1c2ea8 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -359,3 +359,17 @@ int is_bad_inode(struct inode *inode)
 }
 
 EXPORT_SYMBOL(is_bad_inode);
+
+/**
+ * iget_failed - Mark an under-construction inode as dead and release it
+ * @inode: The inode to discard
+ *
+ * Mark an under-construction inode as dead and release it.
+ */
+void iget_failed(struct inode *inode)
+{
+   make_bad_inode(inode);
+   unlock_new_inode(inode);
+   iput(inode);
+}
+EXPORT_SYMBOL(iget_failed);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 16421f6..c24d433 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1631,6 +1631,7 @@ static inline struct inode *iget(struct super_block *sb, 
unsigned long ino)
 }
 
 extern void __iget(struct inode * inode);
+extern void iget_failed(struct inode *);
 extern void clear_inode(struct inode *);
 extern void destroy_inode(struct inode *);
 extern struct inode *new_inode(struct super_block *);

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/30] Remove iget() and read_inode()

2007-10-01 Thread David Howells


Hi Christoph, Al,

Here's a set of patches that remove all calls to iget() and all read_inode()
functions.  They should be removed for two reasons: firstly they don't lend
themselves to good error handling, and secondly their presence is a temptation
for code outside a filesystem to call iget() to access inodes within that
filesystem.

There are a few benefits to this:

 (1) Error handling gets simpler as you can return an error code rather than
 having to call is_bad_inode().

 (2) You can now tell the difference between ENOMEM and EIO occurring in the
 read_inode() path.

 (3) The code should get smaller.  iget() is an inline function that is
 typically called 2-3 times per filesystem that uses it.  By folding the
 iget code into the read_inode code for each filesystem, it eliminates
 some duplication.

A tarball of the patches can be retrieved from:

http://people.redhat.com/~dhowells/iget-remove.tar.bz2


The first patch adds a function, iget_failed() that is a canned piece of code
for killing an inode when the inode construction path fails.

The second and third patches makes AFS and GFS2 use iget_failed() rather than
interpolating the sequence directly.

The fourth patch marks iget() and read_inode() as being deprecated.

The final patch removes iget() and read_inode() completely.

Each of the other patches modify a filesystem that used iget() and read_inode()
to use iget_locked() instead.  The standard procedure was to convert:

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

into:

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 call thingyfs_iget() rather than iget():

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;
}

There were exceptions; most notably it appeared FAT should be calling ilookup()
not iget().

Additionally, HPPFS and HOSTFS (UM-specific filesystems) really need checking:

 hostfs_kern.c:

 (*) hostfs_iget() should perhaps subsume init_inode() and hostfs_read_inode().

 (*) It would appear that all hostfs inodes are the same inode because iget()
 was being called with inode number 0 - which forms the lookup key.

 hppfs_kern.c:

 (*) The HPPFS inode retains a pointer to the proc dentry it is shadowing, but
 whilst it does appear to retain a reference to it, it doesn't appear to
 destroy the reference if the inode goes away.

 (*) hppfs_iget() should perhaps subsume init_inode() and hppfs_read_inode().

 (*) It would appear that all hppfs inodes are the same inode because iget()
 was being called with inode number 0, which forms the lookup key.


David
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html