diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/balloc.c | 5 | ||||
-rw-r--r-- | fs/ext2/dir.c | 14 | ||||
-rw-r--r-- | fs/ext2/file.c | 1 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 6 | ||||
-rw-r--r-- | fs/ext2/namei.c | 38 | ||||
-rw-r--r-- | fs/ext2/super.c | 12 | ||||
-rw-r--r-- | fs/ext2/symlink.c | 57 |
7 files changed, 34 insertions, 99 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 171de1cf5..4d2b561ee 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -291,6 +291,7 @@ int ext2_new_block (const struct inode * inode, unsigned long goal, printk ("ext2_new_block: nonexistent device"); return 0; } +retry: lock_super (sb); es = sb->u.ext2_sb.s_es; if (le32_to_cpu(es->s_free_blocks_count) <= le32_to_cpu(es->s_r_blocks_count) && @@ -298,6 +299,8 @@ int ext2_new_block (const struct inode * inode, unsigned long goal, (sb->u.ext2_sb.s_resgid == 0 || !in_group_p (sb->u.ext2_sb.s_resgid)))) { unlock_super (sb); + if(sb->s_ibasket && free_ibasket(sb)) + goto retry; return 0; } @@ -389,6 +392,8 @@ repeat: } if (k >= sb->u.ext2_sb.s_groups_count) { unlock_super (sb); + if(sb->s_ibasket && free_ibasket(sb)) + goto retry; return 0; } bitmap_nr = load_block_bitmap (sb, i); diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index fce6fc4c8..d9b1957e3 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -65,7 +65,6 @@ struct inode_operations ext2_dir_inode_operations = { ext2_mknod, /* mknod */ ext2_rename, /* rename */ NULL, /* readlink */ - NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ @@ -194,12 +193,13 @@ revalidate: * currently swapped out. So, use a * version stamp to detect whether or * not the directory has been modified - * during the copy operation. */ - unsigned long version; - dcache_add(inode, de->name, le16_to_cpu(de->name_len), - le32_to_cpu(de->inode)); - version = inode->i_version; - error = filldir(dirent, de->name, le16_to_cpu(de->name_len), filp->f_pos, le32_to_cpu(de->inode)); + * during the copy operation. + */ + unsigned long version = inode->i_version; + + error = filldir(dirent, de->name, + le16_to_cpu(de->name_len), + filp->f_pos, le32_to_cpu(de->inode)); if (error) break; if (version != inode->i_version) diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 274dc31fd..1627f5cee 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -72,7 +72,6 @@ struct inode_operations ext2_file_inode_operations = { NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ - NULL, /* follow_link */ generic_readpage, /* readpage */ NULL, /* writepage */ ext2_bmap, /* bmap */ diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 16751329e..a486679f9 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -171,9 +171,9 @@ void ext2_free_inode (struct inode * inode) printk ("ext2_free_inode: inode has no device\n"); return; } - if (inode->i_count > 1) { + if (atomic_read(&inode->i_count) > 1) { printk ("ext2_free_inode: inode has count=%d\n", - inode->i_count); + atomic_read(&inode->i_count)); return; } if (inode->i_nlink) { @@ -404,7 +404,7 @@ repeat: sb->s_dirt = 1; inode->i_mode = mode; inode->i_sb = sb; - inode->i_count = 1; + atomic_set(&inode->i_count, 1); inode->i_nlink = 1; inode->i_dev = sb->s_dev; inode->i_uid = current->fsuid; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 39716678a..421393581 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -172,27 +172,12 @@ int ext2_lookup (struct inode * dir, const char * name, int len, iput (dir); return -ENAMETOOLONG; } - if (dcache_lookup(dir, name, len, &ino)) { - if (!ino) { - iput(dir); - return -ENOENT; - } - if (!(*result = iget (dir->i_sb, ino))) { - iput (dir); - return -EACCES; - } - iput (dir); - return 0; - } ino = dir->i_version; if (!(bh = ext2_find_entry (dir, name, len, &de))) { - if (ino == dir->i_version) - dcache_add(dir, name, len, 0); iput (dir); return -ENOENT; } ino = le32_to_cpu(de->inode); - dcache_add(dir, name, len, ino); brelse (bh); if (!(*result = iget (dir->i_sb, ino))) { iput (dir); @@ -391,7 +376,6 @@ int ext2_create (struct inode * dir,const char * name, int len, int mode, } de->inode = cpu_to_le32(inode->i_ino); dir->i_version = ++event; - dcache_add(dir, de->name, le16_to_cpu(de->name_len), le32_to_cpu(de->inode)); mark_buffer_dirty(bh, 1); if (IS_SYNC(dir)) { ll_rw_block (WRITE, 1, &bh); @@ -460,7 +444,6 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode, } de->inode = cpu_to_le32(inode->i_ino); dir->i_version = ++event; - dcache_add(dir, de->name, le16_to_cpu(de->name_len), le32_to_cpu(de->inode)); mark_buffer_dirty(bh, 1); if (IS_SYNC(dir)) { ll_rw_block (WRITE, 1, &bh); @@ -538,7 +521,6 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode) } de->inode = cpu_to_le32(inode->i_ino); dir->i_version = ++event; - dcache_add(dir, de->name, le16_to_cpu(de->name_len), le32_to_cpu(de->inode)); mark_buffer_dirty(bh, 1); if (IS_SYNC(dir)) { ll_rw_block (WRITE, 1, &bh); @@ -662,7 +644,7 @@ repeat: else if (le32_to_cpu(de->inode) != inode->i_ino) retval = -ENOENT; else { - if (inode->i_count > 1) { + if (atomic_read(&inode->i_count) > 1) { /* * Are we deleting the last instance of a busy directory? * Better clean up if so. @@ -836,7 +818,6 @@ int ext2_symlink (struct inode * dir, const char * name, int len, } de->inode = cpu_to_le32(inode->i_ino); dir->i_version = ++event; - dcache_add(dir, de->name, le16_to_cpu(de->name_len), le32_to_cpu(de->inode)); mark_buffer_dirty(bh, 1); if (IS_SYNC(dir)) { ll_rw_block (WRITE, 1, &bh); @@ -885,7 +866,6 @@ int ext2_link (struct inode * oldinode, struct inode * dir, } de->inode = cpu_to_le32(oldinode->i_ino); dir->i_version = ++event; - dcache_add(dir, de->name, le16_to_cpu(de->name_len), le32_to_cpu(de->inode)); mark_buffer_dirty(bh, 1); if (IS_SYNC(dir)) { ll_rw_block (WRITE, 1, &bh); @@ -905,7 +885,7 @@ static int subdir (struct inode * new_inode, struct inode * old_inode) int ino; int result; - new_inode->i_count++; + atomic_inc(&new_inode->i_count); result = 0; for (;;) { if (new_inode == old_inode) { @@ -945,8 +925,7 @@ static int subdir (struct inode * new_inode, struct inode * old_inode) */ static int do_ext2_rename (struct inode * old_dir, const char * old_name, int old_len, struct inode * new_dir, - const char * new_name, int new_len, - int must_be_dir) + const char * new_name, int new_len) { struct inode * old_inode, * new_inode; struct buffer_head * old_bh, * new_bh, * dir_bh; @@ -981,8 +960,6 @@ start_up: old_inode = __iget (old_dir->i_sb, le32_to_cpu(old_de->inode), 0); /* don't cross mnt-points */ if (!old_inode) goto end_rename; - if (must_be_dir && !S_ISDIR(old_inode->i_mode)) - goto end_rename; retval = -EPERM; if ((old_dir->i_mode & S_ISVTX) && current->fsuid != old_inode->i_uid && @@ -1016,7 +993,7 @@ start_up: if (!empty_dir (new_inode)) goto end_rename; retval = -EBUSY; - if (new_inode->i_count > 1) + if (atomic_read(&new_inode->i_count) > 1) goto end_rename; } retval = -EPERM; @@ -1059,7 +1036,6 @@ start_up: * ok, that's it */ new_de->inode = le32_to_cpu(old_inode->i_ino); - dcache_add(new_dir, new_de->name, le16_to_cpu(new_de->name_len), le32_to_cpu(new_de->inode)); retval = ext2_delete_entry (old_de, old_bh); if (retval == -ENOENT) goto try_again; @@ -1075,7 +1051,6 @@ start_up: old_dir->i_dirt = 1; if (dir_bh) { PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino); - dcache_add(old_inode, "..", 2, new_dir->i_ino); mark_buffer_dirty(dir_bh, 1); old_dir->i_nlink--; old_dir->i_dirt = 1; @@ -1123,8 +1098,7 @@ end_rename: * on the same file system */ int ext2_rename (struct inode * old_dir, const char * old_name, int old_len, - struct inode * new_dir, const char * new_name, int new_len, - int must_be_dir) + struct inode * new_dir, const char * new_name, int new_len) { int result; @@ -1132,7 +1106,7 @@ int ext2_rename (struct inode * old_dir, const char * old_name, int old_len, sleep_on (&old_dir->i_sb->u.ext2_sb.s_rename_wait); old_dir->i_sb->u.ext2_sb.s_rename_lock = 1; result = do_ext2_rename (old_dir, old_name, old_len, new_dir, - new_name, new_len, must_be_dir); + new_name, new_len); old_dir->i_sb->u.ext2_sb.s_rename_lock = 0; wake_up (&old_dir->i_sb->u.ext2_sb.s_rename_wait); return result; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 5885e3067..635a45692 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -319,6 +319,13 @@ static void ext2_setup_super (struct super_block * sb, ext2_check_inodes_bitmap (sb); } } +#if 0 /* ibasket's still have unresolved bugs... -DaveM */ + + /* [T. Schoebel-Theuer] This limit should be maintained on disk. + * This is just provisionary. + */ + sb->s_ibasket_max = 100; +#endif } static int ext2_check_descriptors (struct super_block * sb) @@ -728,7 +735,10 @@ int ext2_remount (struct super_block * sb, int * flags, char * data) } static struct file_system_type ext2_fs_type = { - ext2_read_super, "ext2", 1, NULL + "ext2", + FS_REQUIRES_DEV /* | FS_IBASKET */, /* ibaskets have unresolved bugs */ + ext2_read_super, + NULL }; __initfunc(int init_ext2_fs(void)) diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 31f8276b0..4d5a5cada 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c @@ -25,8 +25,6 @@ #include <linux/stat.h> static int ext2_readlink (struct inode *, char *, int); -static int ext2_follow_link (struct inode *, struct inode *, int, int, - struct inode **); /* * symlinks can't do much... @@ -43,7 +41,6 @@ struct inode_operations ext2_symlink_inode_operations = { NULL, /* mknod */ NULL, /* rename */ ext2_readlink, /* readlink */ - ext2_follow_link, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ @@ -52,70 +49,20 @@ struct inode_operations ext2_symlink_inode_operations = { NULL /* smap */ }; -static int ext2_follow_link(struct inode * dir, struct inode * inode, - int flag, int mode, struct inode ** res_inode) -{ - int error; - struct buffer_head * bh = NULL; - char * link; - - *res_inode = NULL; - if (!dir) { - dir = current->fs->root; - dir->i_count++; - } - if (!inode) { - iput (dir); - return -ENOENT; - } - if (!S_ISLNK(inode->i_mode)) { - iput (dir); - *res_inode = inode; - return 0; - } - if (current->link_count > 5) { - iput (dir); - iput (inode); - return -ELOOP; - } - if (inode->i_blocks) { - if (!(bh = ext2_bread (inode, 0, 0, &error))) { - iput (dir); - iput (inode); - return -EIO; - } - link = bh->b_data; - } else - link = (char *) inode->u.ext2_i.i_data; - if (DO_UPDATE_ATIME(inode)) { - inode->i_atime = CURRENT_TIME; - inode->i_dirt = 1; - } - current->link_count++; - error = open_namei (link, flag, mode, res_inode, dir); - current->link_count--; - iput (inode); - if (bh) - brelse (bh); - return error; -} - static int ext2_readlink (struct inode * inode, char * buffer, int buflen) { struct buffer_head * bh = NULL; char * link; int i, err; - if (!S_ISLNK(inode->i_mode)) { - iput (inode); - return -EINVAL; - } if (buflen > inode->i_sb->s_blocksize - 1) buflen = inode->i_sb->s_blocksize - 1; if (inode->i_blocks) { bh = ext2_bread (inode, 0, 0, &err); if (!bh) { iput (inode); + if(err < 0) /* indicate type of error */ + return err; return 0; } link = bh->b_data; |