summaryrefslogtreecommitdiffstats
path: root/fs/sysv
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-02-15 02:15:32 +0000
commit86464aed71025541805e7b1515541aee89879e33 (patch)
treee01a457a4912a8553bc65524aa3125d51f29f810 /fs/sysv
parent88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff)
Merge with Linux 2.2.1.
Diffstat (limited to 'fs/sysv')
-rw-r--r--fs/sysv/CHANGES25
-rw-r--r--fs/sysv/inode.c18
-rw-r--r--fs/sysv/namei.c63
3 files changed, 53 insertions, 53 deletions
diff --git a/fs/sysv/CHANGES b/fs/sysv/CHANGES
index 293af7534..4dbff5b56 100644
--- a/fs/sysv/CHANGES
+++ b/fs/sysv/CHANGES
@@ -18,3 +18,28 @@ Tue Jan 27 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl>
Wed Feb 4 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl>
* namei.c: removed static subdir(); is_subdir() from dcache.c
is used instead. Cosmetic changes.
+
+Thu Dec 3 1998 Al Viro (viro@math.psu.edu)
+ * namei.c (sysv_rmdir):
+ Bugectomy: old check for victim being busy
+ (inode->i_count) wasn't replaced (with checking
+ dentry->d_count) and escaped Linus in the last round
+ of changes. Shot and buried.
+
+Wed Dec 9 1998 AV
+ * namei.c (do_sysv_rename):
+ Fixed incorrect check for other owners + race.
+ Removed checks that went to VFS.
+ * namei.c (sysv_unlink):
+ Removed checks that went to VFS.
+
+Thu Dec 10 1998 AV
+ * namei.c (do_mknod):
+ Removed dead code - mknod is never asked to
+ create a symlink or directory. Incidentially,
+ it wouldn't do it right if it would be called.
+
+Sat Dec 26 1998 KGB
+ * inode.c (detect_sysv4):
+ Added detection of expanded s_type field (0x10,
+ 0x20 and 0x30). Forced read-only access in this case.
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index f2cf52087..d5af68176 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -15,6 +15,7 @@
*
* sysv/inode.c
* Copyright (C) 1993 Bruno Haible
+ * Copyright (C) 1997, 1998 Krzysztof G. Baranowski
*
* This file contains code for allocating/freeing inodes and for read/writing
* the superblock.
@@ -179,12 +180,25 @@ static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh)
return NULL;
if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
return NULL;
- if (sbd->s_type > 3 || sbd->s_type < 1)
+ if ((sbd->s_type > 3 || sbd->s_type < 1) && (sbd->s_type > 0x30 || sbd->s_type < 0x10))
return NULL;
- detected_bs(sbd->s_type, sb);
+
+ /* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
+ 0x20 or 0x30 indicates that symbolic links and the 14-character
+ filename limit is gone. Due to lack of information about this
+ feature read-only mode seems to be a reasonable approach... -KGB */
+
+ if (sbd->s_type >= 0x10) {
+ printk("SysV FS: can't handle long file names on %s, "
+ "forcing read-only mode.\n", kdevname(sb->s_dev));
+ sb->s_flags |= MS_RDONLY;
+ }
+
+ detected_bs(sbd->s_type >= 0x10 ? (sbd->s_type >> 4) : sbd->s_type, sb);
sb->sv_type = FSTYPE_SYSV4;
return "SystemV";
}
+
static struct super_block * detected_sysv4 (struct super_block *sb, struct buffer_head *bh)
{
struct sysv4_super_block * sbd;
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index fdae5c38c..1ae336647 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -9,6 +9,7 @@
*
* sysv/namei.c
* Copyright (C) 1993 Bruno Haible
+ * Copyright (C) 1997, 1998 Krzysztof G. Baranowski
*/
@@ -254,13 +255,6 @@ int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev)
inode->i_op = NULL;
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;
- if (dir->i_mode & S_ISGID)
- inode->i_mode |= S_ISGID;
- }
- 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))
@@ -416,21 +410,8 @@ int sysv_rmdir(struct inode * dir, struct dentry * dentry)
retval = -ENOENT;
if (!bh)
goto end_rmdir;
- retval = -EPERM;
inode = dentry->d_inode;
- if ((dir->i_mode & S_ISVTX) &&
- current->fsuid != inode->i_uid &&
- current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
- goto end_rmdir;
- if (inode->i_dev != dir->i_dev)
- goto end_rmdir;
- if (inode == dir) /* we may not delete ".", but "../dir" is ok */
- goto end_rmdir;
- if (!S_ISDIR(inode->i_mode)) {
- retval = -ENOTDIR;
- goto end_rmdir;
- }
if (!empty_dir(inode)) {
retval = -ENOTEMPTY;
goto end_rmdir;
@@ -439,7 +420,7 @@ int sysv_rmdir(struct inode * dir, struct dentry * dentry)
retval = -ENOENT;
goto end_rmdir;
}
- if (inode->i_count > 1) {
+ if (!list_empty(&dentry->d_hash)) {
retval = -EBUSY;
goto end_rmdir;
}
@@ -482,10 +463,6 @@ repeat:
schedule();
goto repeat;
}
- if ((dir->i_mode & S_ISVTX) &&
- current->fsuid != inode->i_uid &&
- current->fsuid != dir->i_uid && !capable(CAP_FOWNER))
- goto end_unlink;
if (de->inode != inode->i_ino) {
retval = -ENOENT;
goto end_unlink;
@@ -641,10 +618,6 @@ start_up:
goto end_rename;
old_inode = old_dentry->d_inode; /* don't cross mnt-points */
retval = -EPERM;
- if ((old_dir->i_mode & S_ISVTX) &&
- current->fsuid != old_inode->i_uid &&
- current->fsuid != old_dir->i_uid && !capable(CAP_FOWNER))
- goto end_rename;
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);
@@ -658,32 +631,20 @@ start_up:
retval = 0;
goto end_rename;
}
- if (new_inode && S_ISDIR(new_inode->i_mode)) {
- retval = -EISDIR;
- if (!S_ISDIR(old_inode->i_mode))
- goto end_rename;
- retval = -EINVAL;
- if (is_subdir(new_dentry, old_dentry))
- goto end_rename;
- retval = -ENOTEMPTY;
- if (!empty_dir(new_inode))
- goto end_rename;
- retval = -EBUSY;
- if (new_inode->i_count > 1)
- goto end_rename;
- }
- retval = -EPERM;
- if (new_inode && (new_dir->i_mode & S_ISVTX) &&
- current->fsuid != new_inode->i_uid &&
- current->fsuid != new_dir->i_uid && !capable(CAP_FOWNER))
- goto end_rename;
if (S_ISDIR(old_inode->i_mode)) {
- retval = -ENOTDIR;
- if (new_inode && !S_ISDIR(new_inode->i_mode))
- goto end_rename;
retval = -EINVAL;
if (is_subdir(new_dentry, old_dentry))
goto end_rename;
+ if (new_inode) {
+ if (new_dentry->d_count > 1)
+ shrink_dcache_parent(new_dentry);
+ retval = -EBUSY;
+ if (new_dentry->d_count > 1)
+ goto end_rename;
+ retval = -ENOTEMPTY;
+ if (!empty_dir(new_inode))
+ goto end_rename;
+ }
retval = -EIO;
dir_bh = sysv_file_bread(old_inode, 0, 0);
if (!dir_bh)