aboutsummaryrefslogtreecommitdiff
path: root/fs/ext2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-09-21 10:18:14 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-09-21 10:18:14 -0400
commit91fa47964165a42401fbc1f41caa63ab78564305 (patch)
tree8f4ffdcbdedd845563630c3bcacd9407c75ccb52 /fs/ext2
parent56965536b8056f57830219efbba4b85218d96d6c (diff)
parente478bec0ba0a83a48a0f6982934b6de079e7e6b3 (diff)
Merge branch 'master' into gfs2
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/balloc.c1
-rw-r--r--fs/ext2/ialloc.c1
-rw-r--r--fs/ext2/super.c41
3 files changed, 39 insertions, 4 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index d4870432ecf..b1981d0e95a 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -539,7 +539,6 @@ unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars)
#endif /* EXT2FS_DEBUG */
-/* Superblock must be locked */
unsigned long ext2_count_free_blocks (struct super_block * sb)
{
struct ext2_group_desc * desc;
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index de85c61c58c..695f69ccf90 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -637,7 +637,6 @@ fail:
return ERR_PTR(err);
}
-/* Superblock must be locked */
unsigned long ext2_count_free_inodes (struct super_block * sb)
{
struct ext2_group_desc *desc;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 681dea8f953..4286ff6330b 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -251,6 +251,44 @@ static struct super_operations ext2_sops = {
#endif
};
+static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
+{
+ __u32 *objp = vobjp;
+ unsigned long ino = objp[0];
+ __u32 generation = objp[1];
+ struct inode *inode;
+ struct dentry *result;
+
+ if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO)
+ return ERR_PTR(-ESTALE);
+ if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count))
+ return ERR_PTR(-ESTALE);
+
+ /* iget isn't really right if the inode is currently unallocated!!
+ * ext2_read_inode currently does appropriate checks, but
+ * it might be "neater" to call ext2_get_inode first and check
+ * if the inode is valid.....
+ */
+ inode = iget(sb, ino);
+ if (inode == NULL)
+ return ERR_PTR(-ENOMEM);
+ if (is_bad_inode(inode) ||
+ (generation && inode->i_generation != generation)) {
+ /* we didn't find the right inode.. */
+ iput(inode);
+ return ERR_PTR(-ESTALE);
+ }
+ /* now to find a dentry.
+ * If possible, get a well-connected one
+ */
+ result = d_alloc_anon(inode);
+ if (!result) {
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ return result;
+}
+
/* Yes, most of these are left as NULL!!
* A NULL value implies the default, which works with ext2-like file
* systems, but can be improved upon.
@@ -258,6 +296,7 @@ static struct super_operations ext2_sops = {
*/
static struct export_operations ext2_export_ops = {
.get_parent = ext2_get_parent,
+ .get_dentry = ext2_get_dentry,
};
static unsigned long get_sb_block(void **data)
@@ -1044,7 +1083,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
unsigned long overhead;
int i;
- lock_super(sb);
if (test_opt (sb, MINIX_DF))
overhead = 0;
else {
@@ -1085,7 +1123,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count);
buf->f_ffree = ext2_count_free_inodes (sb);
buf->f_namelen = EXT2_NAME_LEN;
- unlock_super(sb);
return 0;
}