summaryrefslogtreecommitdiffstats
path: root/fs/sysv
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/sysv
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/sysv')
-rw-r--r--fs/sysv/CHANGES5
-rw-r--r--fs/sysv/inode.c14
-rw-r--r--fs/sysv/namei.c88
3 files changed, 25 insertions, 82 deletions
diff --git a/fs/sysv/CHANGES b/fs/sysv/CHANGES
index 94507925c..3cbcd7b9d 100644
--- a/fs/sysv/CHANGES
+++ b/fs/sysv/CHANGES
@@ -53,3 +53,8 @@ Sun, 21 Mar 1999 AV
_inode()'s job.
* ialloc.c: (sysv_free_inode):
Fixed race.
+
+Sun, 30 Apr 1999 AV
+ * namei.c (sysv_mknod):
+ Removed dead code (S_IFREG case is now passed to
+ ->create() by VFS).
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index f58560996..f8d508c3d 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -503,7 +503,7 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
sb->s_dev = dev;
sb->s_op = &sysv_sops;
root_inode = iget(sb,SYSV_ROOT_INO);
- sb->s_root = d_alloc_root(root_inode, NULL);
+ sb->s_root = d_alloc_root(root_inode);
if (!sb->s_root) {
printk("SysV FS: get root inode failed\n");
sysv_put_super(sb);
@@ -882,7 +882,7 @@ void sysv_read_inode(struct inode * inode)
}
inode->i_blocks = inode->i_blksize = 0;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- inode->i_rdev = to_kdev_t(raw_inode->i_a.i_rdev);
+ ;
else
if (sb->sv_convert)
for (block = 0; block < 10+1+1+1; block++)
@@ -892,19 +892,15 @@ void sysv_read_inode(struct inode * inode)
for (block = 0; block < 10+1+1+1; block++)
inode->u.sysv_i.i_data[block] =
read3byte(&raw_inode->i_a.i_addb[3*block]);
- brelse(bh);
if (S_ISREG(inode->i_mode))
inode->i_op = &sysv_file_inode_operations;
else if (S_ISDIR(inode->i_mode))
inode->i_op = &sysv_dir_inode_operations;
else if (S_ISLNK(inode->i_mode))
inode->i_op = &sysv_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,raw_inode->i_a.i_rdev);
+ brelse(bh);
}
/* To avoid inconsistencies between inodes in memory and inodes on disk. */
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 8cea266a8..e27ac8d83 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -144,8 +144,6 @@ static int sysv_add_entry(struct inode * dir,
*res_buf = NULL;
*res_dir = NULL;
- if (!dir)
- return -ENOENT;
sb = dir->i_sb;
if (namelen > SYSV_NAMELEN) {
if (sb->sv_truncate)
@@ -240,18 +238,7 @@ int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
if (!inode)
return -ENOSPC;
inode->i_uid = current->fsuid;
- inode->i_mode = mode;
- inode->i_op = NULL;
- if (S_ISREG(inode->i_mode))
- inode->i_op = &sysv_file_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);
- if (S_ISBLK(mode) || S_ISCHR(mode))
- inode->i_rdev = to_kdev_t(rdev);
+ init_special_inode(inode, mode, rdev);
mark_inode_dirty(inode);
error = sysv_add_entry(dir, dentry->d_name.name,
dentry->d_name.len, &bh, &de);
@@ -304,7 +291,7 @@ int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
inode->i_nlink = 2;
mark_buffer_dirty(dir_block, 1);
brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
+ inode->i_mode = S_IFDIR | mode;
if (dir->i_mode & S_ISGID)
inode->i_mode |= S_ISGID;
mark_inode_dirty(inode);
@@ -334,8 +321,6 @@ static int empty_dir(struct inode * inode)
struct buffer_head * bh;
struct sysv_dir_entry * de;
- if (!inode)
- return 1;
block = 0;
bh = NULL;
pos = offset = 2*SYSV_DIRSIZE;
@@ -391,22 +376,16 @@ int sysv_rmdir(struct inode * dir, struct dentry * dentry)
struct buffer_head * bh;
struct sysv_dir_entry * de;
- inode = NULL;
- bh = sysv_find_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &de);
+ inode = dentry->d_inode;
+ bh = sysv_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
retval = -ENOENT;
- if (!bh)
+ if (!bh || de->inode != inode->i_ino)
goto end_rmdir;
- inode = dentry->d_inode;
if (!empty_dir(inode)) {
retval = -ENOTEMPTY;
goto end_rmdir;
}
- if (de->inode != inode->i_ino) {
- retval = -ENOENT;
- goto end_rmdir;
- }
if (!list_empty(&dentry->d_hash)) {
retval = -EBUSY;
goto end_rmdir;
@@ -416,9 +395,9 @@ int sysv_rmdir(struct inode * dir, struct dentry * dentry)
de->inode = 0;
mark_buffer_dirty(bh, 1);
inode->i_nlink=0;
- mark_inode_dirty(inode);
dir->i_nlink--;
inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+ mark_inode_dirty(inode);
mark_inode_dirty(dir);
d_delete(dentry);
retval = 0;
@@ -434,26 +413,11 @@ int sysv_unlink(struct inode * dir, struct dentry * dentry)
struct buffer_head * bh;
struct sysv_dir_entry * de;
-repeat:
retval = -ENOENT;
- inode = NULL;
- bh = sysv_find_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &de);
- if (!bh)
- goto end_unlink;
inode = dentry->d_inode;
-
- retval = -EPERM;
- if (de->inode != inode->i_ino) {
- brelse(bh);
- current->counter = 0;
- schedule();
- goto repeat;
- }
- if (de->inode != inode->i_ino) {
- retval = -ENOENT;
+ bh = sysv_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
+ if (!bh || de->inode != inode->i_ino)
goto end_unlink;
- }
if (!inode->i_nlink) {
printk("Deleting nonexistent file (%s:%lu), %d\n",
kdevname(inode->i_dev), inode->i_ino, inode->i_nlink);
@@ -572,12 +536,6 @@ int sysv_link(struct dentry * old_dentry, struct inode * dir,
(((struct sysv_dir_entry *) ((buffer) + 1*SYSV_DIRSIZE))->inode)
/*
- * rename uses retrying to avoid race-conditions: at least they should be minimal.
- * it tries to allocate all the blocks, then sanity-checks, and if the sanity-
- * checks fail, it tries to restart itself again. Very practical - no changes
- * are done until we know everything works ok.. and then all the changes can be
- * done in one fell swoop when we have claimed all the buffers needed.
- *
* Anybody can rename anything with this: the permission checks are left to the
* higher-level routines.
*/
@@ -589,24 +547,15 @@ int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
struct sysv_dir_entry * old_de, * new_de;
int retval;
- goto start_up;
-try_again:
- brelse(old_bh);
- brelse(new_bh);
- brelse(dir_bh);
- current->counter = 0;
- schedule();
-start_up:
- old_inode = new_inode = NULL;
- old_bh = new_bh = dir_bh = NULL;
+ old_inode = old_dentry->d_inode;
+ new_inode = new_dentry->d_inode;
+ new_bh = dir_bh = NULL;
old_bh = sysv_find_entry(old_dir, old_dentry->d_name.name,
old_dentry->d_name.len, &old_de);
retval = -ENOENT;
- if (!old_bh)
+ if (!old_bh || old_de->inode != old_inode->i_ino)
goto end_rename;
- old_inode = old_dentry->d_inode; /* don't cross mnt-points */
retval = -EPERM;
- new_inode = new_dentry->d_inode;
new_bh = sysv_find_entry(new_dir, new_dentry->d_name.name,
new_dentry->d_name.len, &new_de);
if (new_bh) {
@@ -628,7 +577,8 @@ start_up:
if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
goto end_rename;
retval = -EMLINK;
- if (!new_inode && new_dir->i_nlink >= new_dir->i_sb->sv_link_max)
+ if (!new_inode && new_dir != old_dir &&
+ new_dir->i_nlink >= new_dir->i_sb->sv_link_max)
goto end_rename;
}
if (!new_bh) {
@@ -637,16 +587,8 @@ start_up:
if (retval)
goto end_rename;
}
-/* sanity checking before doing the rename - avoid races */
- if (new_inode && (new_de->inode != new_inode->i_ino))
- goto try_again;
- if (new_de->inode && !new_inode)
- goto try_again;
- if (old_de->inode != old_inode->i_ino)
- goto try_again;
-/* ok, that's it */
- old_de->inode = 0;
new_de->inode = old_inode->i_ino;
+ old_de->inode = 0;
old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(old_dir);
new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;