diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
commit | 86464aed71025541805e7b1515541aee89879e33 (patch) | |
tree | e01a457a4912a8553bc65524aa3125d51f29f810 /fs/sysv | |
parent | 88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff) |
Merge with Linux 2.2.1.
Diffstat (limited to 'fs/sysv')
-rw-r--r-- | fs/sysv/CHANGES | 25 | ||||
-rw-r--r-- | fs/sysv/inode.c | 18 | ||||
-rw-r--r-- | fs/sysv/namei.c | 63 |
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) |