summaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-17 13:25:08 +0000
commit59223edaa18759982db0a8aced0e77457d10c68e (patch)
tree89354903b01fa0a447bffeefe00df3044495db2e /fs/ext2
parentdb7d4daea91e105e3859cf461d7e53b9b77454b2 (diff)
Merge with Linux 2.3.6. Sorry, this isn't tested on silicon, I don't
have a MIPS box at hand.
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/ialloc.c17
-rw-r--r--fs/ext2/inode.c20
-rw-r--r--fs/ext2/ioctl.c4
-rw-r--r--fs/ext2/namei.c87
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/ext2/symlink.c1
-rw-r--r--fs/ext2/truncate.c9
7 files changed, 46 insertions, 94 deletions
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 7a7629e58..f6a5ecfc6 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -268,21 +268,6 @@ error_return:
}
/*
- * This function increments the inode version number
- *
- * This may be used one day by the NFS server
- */
-static void inc_inode_version (struct inode * inode,
- struct ext2_group_desc *gdp,
- int mode)
-{
- inode->u.ext2_i.i_version++;
- mark_inode_dirty(inode);
-
- return;
-}
-
-/*
* There are two policies for allocating an inode. If the new inode is
* a directory, then a forward search is made for a block group with both
* free space and a low directory-to-inode ratio; if that fails, then of
@@ -493,8 +478,8 @@ repeat:
if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
inode->i_flags |= MS_SYNCHRONOUS;
insert_inode_hash(inode);
+ inode->i_generation++;
mark_inode_dirty(inode);
- inc_inode_version (inode, gdp, mode);
unlock_super (sb);
if(DQUOT_ALLOC_INODE(sb, inode)) {
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 8bd5c9684..693964a80 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -562,22 +562,18 @@ void ext2_read_inode (struct inode * inode)
<< 32;
#endif
}
- inode->u.ext2_i.i_version = le32_to_cpu(raw_inode->i_version);
+ inode->i_generation = le32_to_cpu(raw_inode->i_generation);
inode->u.ext2_i.i_block_group = block_group;
inode->u.ext2_i.i_next_alloc_block = 0;
inode->u.ext2_i.i_next_alloc_goal = 0;
if (inode->u.ext2_i.i_prealloc_count)
ext2_error (inode->i_sb, "ext2_read_inode",
"New inode has non-zero prealloc count!");
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- inode->i_rdev = to_kdev_t(le32_to_cpu(raw_inode->i_block[0]));
- else if (S_ISLNK(inode->i_mode) && !inode->i_blocks)
+ if (S_ISLNK(inode->i_mode) && !inode->i_blocks)
for (block = 0; block < EXT2_N_BLOCKS; block++)
inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
else for (block = 0; block < EXT2_N_BLOCKS; block++)
inode->u.ext2_i.i_data[block] = le32_to_cpu(raw_inode->i_block[block]);
- brelse (bh);
- inode->i_op = NULL;
if (inode->i_ino == EXT2_ACL_IDX_INO ||
inode->i_ino == EXT2_ACL_DATA_INO)
/* Nothing to do */ ;
@@ -587,12 +583,10 @@ void ext2_read_inode (struct inode * inode)
inode->i_op = &ext2_dir_inode_operations;
else if (S_ISLNK(inode->i_mode))
inode->i_op = &ext2_symlink_inode_operations;
- else if (S_ISCHR(inode->i_mode))
- inode->i_op = &chrdev_inode_operations;
- else if (S_ISBLK(inode->i_mode))
- inode->i_op = &blkdev_inode_operations;
- else if (S_ISFIFO(inode->i_mode))
- init_fifo(inode);
+ else
+ init_special_inode(inode, inode->i_mode,
+ le32_to_cpu(raw_inode->i_block[0]));
+ brelse (bh);
inode->i_attr_flags = 0;
if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL) {
inode->i_attr_flags |= ATTR_FLAG_SYNCRONOUS;
@@ -692,7 +686,7 @@ static int ext2_update_inode(struct inode * inode, int do_sync)
raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32);
#endif
}
- raw_inode->i_version = cpu_to_le32(inode->u.ext2_i.i_version);
+ raw_inode->i_generation = cpu_to_le32(inode->i_generation);
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
else if (S_ISLNK(inode->i_mode) && !inode->i_blocks)
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 3b58bc822..ec21b0c4e 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -69,13 +69,13 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
mark_inode_dirty(inode);
return 0;
case EXT2_IOC_GETVERSION:
- return put_user(inode->u.ext2_i.i_version, (int *) arg);
+ return put_user(inode->i_generation, (int *) arg);
case EXT2_IOC_SETVERSION:
if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
return -EPERM;
if (IS_RDONLY(inode))
return -EROFS;
- if (get_user(inode->u.ext2_i.i_version, (int *) arg))
+ if (get_user(inode->i_generation, (int *) arg))
return -EFAULT;
inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode);
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 7a309fa77..885929f70 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -347,6 +347,25 @@ static int ext2_delete_entry (struct ext2_dir_entry_2 * dir,
return -ENOENT;
}
+static inline void ext2_set_de_type(struct super_block *sb,
+ struct ext2_dir_entry_2 *de,
+ umode_t mode) {
+ if (!EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
+ return;
+ if (S_ISCHR(mode))
+ de->file_type = EXT2_FT_CHRDEV;
+ else if (S_ISBLK(mode))
+ de->file_type = EXT2_FT_BLKDEV;
+ else if (S_ISFIFO(mode))
+ de->file_type = EXT2_FT_FIFO;
+ else if (S_ISLNK(mode))
+ de->file_type = EXT2_FT_SYMLINK;
+ else if (S_ISREG(mode))
+ de->file_type = EXT2_FT_REG_FILE;
+ else if (S_ISDIR(mode))
+ de->file_type = EXT2_FT_DIR;
+}
+
/*
* By the time this is called, we already have created
* the directory cache entry for the new file, but it
@@ -380,9 +399,7 @@ int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
return err;
}
de->inode = cpu_to_le32(inode->i_ino);
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_REG_FILE;
+ ext2_set_de_type(dir->i_sb, de, S_IFREG);
dir->i_version = ++event;
mark_buffer_dirty(bh, 1);
if (IS_SYNC(dir)) {
@@ -406,36 +423,13 @@ int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
goto out;
inode->i_uid = current->fsuid;
- inode->i_mode = mode;
- inode->i_op = NULL;
+ init_special_inode(inode, mode, rdev);
bh = ext2_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
if (!bh)
goto out_no_entry;
de->inode = cpu_to_le32(inode->i_ino);
dir->i_version = ++event;
- if (S_ISREG(inode->i_mode)) {
- inode->i_op = &ext2_file_inode_operations;
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_REG_FILE;
- } else if (S_ISCHR(inode->i_mode)) {
- inode->i_op = &chrdev_inode_operations;
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_CHRDEV;
- } else if (S_ISBLK(inode->i_mode)) {
- inode->i_op = &blkdev_inode_operations;
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_BLKDEV;
- } else if (S_ISFIFO(inode->i_mode)) {
- init_fifo(inode);
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_FIFO;
- }
- if (S_ISBLK(mode) || S_ISCHR(mode))
- inode->i_rdev = to_kdev_t(rdev);
+ ext2_set_de_type(dir->i_sb, de, inode->i_mode);
mark_inode_dirty(inode);
mark_buffer_dirty(bh, 1);
if (IS_SYNC(dir)) {
@@ -486,21 +480,17 @@ int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
de->name_len = 1;
de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
strcpy (de->name, ".");
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_DIR;
+ ext2_set_de_type(dir->i_sb, de, S_IFDIR);
de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
de->inode = cpu_to_le32(dir->i_ino);
de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize - EXT2_DIR_REC_LEN(1));
de->name_len = 2;
strcpy (de->name, "..");
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_DIR;
+ ext2_set_de_type(dir->i_sb, de, S_IFDIR);
inode->i_nlink = 2;
mark_buffer_dirty(dir_block, 1);
brelse (dir_block);
- inode->i_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX) & ~current->fs->umask);
+ inode->i_mode = S_IFDIR | mode;
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
mark_inode_dirty(inode);
@@ -508,9 +498,7 @@ int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (!bh)
goto out_no_entry;
de->inode = cpu_to_le32(inode->i_ino);
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_DIR;
+ ext2_set_de_type(dir->i_sb, de, S_IFDIR);
dir->i_version = ++event;
mark_buffer_dirty(bh, 1);
if (IS_SYNC(dir)) {
@@ -744,9 +732,7 @@ int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symnam
if (!bh)
goto out_no_entry;
de->inode = cpu_to_le32(inode->i_ino);
- if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE))
- de->file_type = EXT2_FT_SYMLINK;
+ ext2_set_de_type(dir->i_sb, de, S_IFLNK);
dir->i_version = ++event;
mark_buffer_dirty(bh, 1);
if (IS_SYNC(dir)) {
@@ -785,21 +771,7 @@ int ext2_link (struct dentry * old_dentry,
return err;
de->inode = cpu_to_le32(inode->i_ino);
- if (EXT2_HAS_INCOMPAT_FEATURE(inode->i_sb,
- EXT2_FEATURE_INCOMPAT_FILETYPE)) {
- if (S_ISREG(inode->i_mode))
- de->file_type = EXT2_FT_REG_FILE;
- else if (S_ISDIR(inode->i_mode))
- de->file_type = EXT2_FT_DIR;
- else if (S_ISLNK(inode->i_mode))
- de->file_type = EXT2_FT_SYMLINK;
- else if (S_ISCHR(inode->i_mode))
- de->file_type = EXT2_FT_CHRDEV;
- else if (S_ISBLK(inode->i_mode))
- de->file_type = EXT2_FT_BLKDEV;
- else if (S_ISFIFO(inode->i_mode))
- de->file_type = EXT2_FT_FIFO;
- }
+ ext2_set_de_type(dir->i_sb, de, inode->i_mode);
dir->i_version = ++event;
mark_buffer_dirty(bh, 1);
if (IS_SYNC(dir)) {
@@ -869,7 +841,8 @@ int ext2_rename (struct inode * old_dir, struct dentry *old_dentry,
if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
goto end_rename;
retval = -EMLINK;
- if (!new_inode && new_dir->i_nlink >= EXT2_LINK_MAX)
+ if (!new_inode && new_dir!=old_dir &&
+ new_dir->i_nlink >= EXT2_LINK_MAX)
goto end_rename;
}
if (!new_bh) {
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index b7c08a009..758da8ff0 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -629,7 +629,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data,
*/
sb->s_dev = dev;
sb->s_op = &ext2_sops;
- sb->s_root = d_alloc_root(iget(sb, EXT2_ROOT_INO), NULL);
+ sb->s_root = d_alloc_root(iget(sb, EXT2_ROOT_INO));
if (!sb->s_root) {
sb->s_dev = 0;
for (i = 0; i < db_count; i++)
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index f01224b68..826cb4176 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -102,7 +102,6 @@ static int ext2_readlink (struct dentry * dentry, char * buffer, int buflen)
i++;
if (copy_to_user(buffer, link, i))
i = -EFAULT;
- UPDATE_ATIME(inode);
if (bh)
brelse (bh);
return i;
diff --git a/fs/ext2/truncate.c b/fs/ext2/truncate.c
index b393fd28a..84eacf87d 100644
--- a/fs/ext2/truncate.c
+++ b/fs/ext2/truncate.c
@@ -384,7 +384,7 @@ static int trunc_tindirect (struct inode * inode)
void ext2_truncate (struct inode * inode)
{
- int err, offset, retry;
+ int err, offset;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
@@ -393,7 +393,7 @@ void ext2_truncate (struct inode * inode)
return;
ext2_discard_prealloc(inode);
while (1) {
- retry = trunc_direct(inode);
+ int retry = trunc_direct(inode);
retry |= trunc_indirect (inode,
EXT2_IND_BLOCK,
(u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK],
@@ -407,8 +407,9 @@ void ext2_truncate (struct inode * inode)
break;
if (IS_SYNC(inode) && (inode->i_state & I_DIRTY))
ext2_sync_inode (inode);
- current->counter = 0;
- schedule ();
+ run_task_queue(&tq_disk);
+ current->policy |= SCHED_YIELD;
+ schedule();
}
/*
* If the file is not being truncated to a block boundary, the