From 27cfca1ec98e91261b1a5355d10a8996464b63af Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 17 Mar 1998 22:05:47 +0000 Subject: Look Ma' what I found on my harddisk ... o New faster syscalls for 2.1.x, too o Upgrade to 2.1.89. Don't try to run this. It's flaky as hell. But feel free to debug ... --- fs/sysv/.cvsignore | 1 + fs/sysv/CHANGES | 20 ++++++ fs/sysv/INTRO | 3 +- fs/sysv/inode.c | 186 +++++++++++++++++++++++++++-------------------------- fs/sysv/namei.c | 84 +++++++++--------------- fs/sysv/symlink.c | 11 ++-- 6 files changed, 156 insertions(+), 149 deletions(-) create mode 100644 fs/sysv/CHANGES (limited to 'fs/sysv') diff --git a/fs/sysv/.cvsignore b/fs/sysv/.cvsignore index 4671378ae..857dd22e9 100644 --- a/fs/sysv/.cvsignore +++ b/fs/sysv/.cvsignore @@ -1 +1,2 @@ .depend +.*.flags diff --git a/fs/sysv/CHANGES b/fs/sysv/CHANGES new file mode 100644 index 000000000..d41e6977c --- /dev/null +++ b/fs/sysv/CHANGES @@ -0,0 +1,20 @@ +Mon Dec 15 1997 Krzysztof G. Baranowski + * namei.c: struct sysv_dir_inode_operations updated to use dentries. + +Fri Jan 23 1998 Krzysztof G. Baranowski + * inode.c: corrected 1 track offset setting (in sb->sv_block_base). + Originally it was overriden (by setting to zero) + in detected_[xenix,sysv4,sysv2,coherent]. Thanks + to Andrzej Krzysztofowicz + for identifying the problem. + +Tue Jan 27 1998 Krzysztof G. Baranowski + * inode.c: added 2048-byte block support to SystemV FS. + Merged detected_bs[512,1024,2048]() into one function: + void detected_bs (u_char type, struct super_block *sb). + Thanks to Andrzej Krzysztofowicz + for the patch. + +Wed Feb 4 1998 Krzysztof G. Baranowski + * namei.c: removed static subdir(); is_subdir() from dcache.c + is used instead. Cosmetic changes. diff --git a/fs/sysv/INTRO b/fs/sysv/INTRO index 9e53cb317..de4e4d17c 100644 --- a/fs/sysv/INTRO +++ b/fs/sysv/INTRO @@ -18,7 +18,7 @@ These filesystems are rather similar. Here is a comparison with Minix FS: * Size of a block or zone (data allocation unit on disk) - Minix FS 1024 - Xenix FS 1024 (also 512 ??) - - SystemV FS 1024 (also 512) + - SystemV FS 1024 (also 512 and 2048) - Coherent FS 512 * General layout: all have one boot block, one super block and @@ -180,4 +180,3 @@ and not the disk driver's notion of "block". Bruno Haible - diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index d84a9524f..25dbe55df 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c @@ -20,7 +20,6 @@ * the superblock. */ -#include #include #include @@ -34,6 +33,27 @@ #include +#if 0 +void sysv_print_inode(struct inode * inode) +{ + printk("ino %lu mode 0%6.6o lk %d uid %d gid %d" + " sz %lu blks %lu cnt %u\n", + inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid, + inode->i_gid, inode->i_size, inode->i_blocks, inode->i_count); + printk(" db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx" + " 0x%lx 0x%lx>\n", + inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1], + inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3], + inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5], + inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7], + inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]); + printk(" ib <0x%lx 0x%lx 0x%lx>\n", + inode->u.sysv_i.i_data[10], + inode->u.sysv_i.i_data[11], + inode->u.sysv_i.i_data[12]); +} +#endif + void sysv_put_inode(struct inode *inode) { if (inode->i_nlink) @@ -65,58 +85,35 @@ static struct super_operations sysv_sops = { * the time stamp is not < 01-01-1980. */ -static void detected_bs512 (struct super_block *sb) -{ - sb->sv_block_size = 512; - sb->sv_block_size_1 = 512-1; - sb->sv_block_size_bits = 9; - sb->sv_block_size_ratio = 2; - sb->sv_block_size_ratio_bits = 1; - sb->sv_inodes_per_block = 512/64; - sb->sv_inodes_per_block_1 = 512/64-1; - sb->sv_inodes_per_block_bits = 9-6; +static void detected_bs (u_char type, struct super_block *sb) +{ + u_char n_bits = type+8; + int bsize = 1 << n_bits; + int bsize_4 = bsize >> 2; + + sb->sv_block_size = bsize; + sb->sv_block_size_1 = bsize-1; + sb->sv_block_size_bits = n_bits; + sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0; + sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0; + sb->sv_inodes_per_block = bsize >> 6; + sb->sv_inodes_per_block_1 = (bsize >> 6)-1; + sb->sv_inodes_per_block_bits = n_bits-6; sb->sv_toobig_block = 10 + - (sb->sv_ind_per_block = 512/4) + - (sb->sv_ind_per_block_2 = (512/4)*(512/4)) + - (sb->sv_ind_per_block_3 = (512/4)*(512/4)*(512/4)); - sb->sv_ind_per_block_1 = 512/4-1; - sb->sv_ind_per_block_2_1 = (512/4)*(512/4)-1; + (sb->sv_ind_per_block = bsize_4) + + (sb->sv_ind_per_block_2 = bsize_4*bsize_4) + + (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4); + sb->sv_ind_per_block_1 = bsize_4-1; + sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1; sb->sv_ind_per_block_2_bits = 2 * - (sb->sv_ind_per_block_bits = 9-2); - sb->sv_ind_per_block_block_size_1 = (512/4)*512-1; - sb->sv_ind_per_block_block_size_bits = (9-2)+9; - sb->sv_ind_per_block_2_block_size_1 = (512/4)*(512/4)*512-1; - sb->sv_ind_per_block_2_block_size_bits = (9-2)+(9-2)+9; - sb->sv_ind0_size = 10 * 512; - sb->sv_ind1_size = (10 + (512/4))* 512; - sb->sv_ind2_size = (10 + (512/4) + (512/4)*(512/4)) * 512; -} - -static void detected_bs1024 (struct super_block *sb) -{ - sb->sv_block_size = 1024; - sb->sv_block_size_1 = 1024-1; - sb->sv_block_size_bits = 10; - sb->sv_block_size_ratio = 1; - sb->sv_block_size_ratio_bits = 0; - sb->sv_inodes_per_block = 1024/64; - sb->sv_inodes_per_block_1 = 1024/64-1; - sb->sv_inodes_per_block_bits = 10-6; - sb->sv_toobig_block = 10 + - (sb->sv_ind_per_block = 1024/4) + - (sb->sv_ind_per_block_2 = (1024/4)*(1024/4)) + - (sb->sv_ind_per_block_3 = (1024/4)*(1024/4)*(1024/4)); - sb->sv_ind_per_block_1 = 1024/4-1; - sb->sv_ind_per_block_2_1 = (1024/4)*(1024/4)-1; - sb->sv_ind_per_block_2_bits = 2 * - (sb->sv_ind_per_block_bits = 10-2); - sb->sv_ind_per_block_block_size_1 = (1024/4)*1024-1; - sb->sv_ind_per_block_block_size_bits = (10-2)+10; - sb->sv_ind_per_block_2_block_size_1 = (1024/4)*(1024/4)*1024-1; - sb->sv_ind_per_block_2_block_size_bits = (10-2)+(10-2)+10; - sb->sv_ind0_size = 10 * 1024; - sb->sv_ind1_size = (10 + (1024/4))* 1024; - sb->sv_ind2_size = (10 + (1024/4) + (1024/4)*(1024/4)) * 1024; + (sb->sv_ind_per_block_bits = n_bits-2); + sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1; + sb->sv_ind_per_block_block_size_bits = 2*n_bits-2; + sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1; + sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4; + sb->sv_ind0_size = 10 * bsize; + sb->sv_ind1_size = (10 + bsize_4)* bsize; + sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize; } static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh) @@ -126,11 +123,9 @@ static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh) sbd = (struct xenix_super_block *) bh->b_data; if (sbd->s_magic != 0x2b5544) return NULL; - switch (sbd->s_type) { - case 1: detected_bs512(sb); break; - case 2: detected_bs1024(sb); break; - default: return NULL; - } + if (sbd->s_type > 2 || sbd->s_type < 1) + return NULL; + detected_bs(sbd->s_type, sb); sb->sv_type = FSTYPE_XENIX; return "Xenix"; } @@ -139,8 +134,8 @@ static struct super_block * detected_xenix (struct super_block *sb, struct buffe struct xenix_super_block * sbd1; struct xenix_super_block * sbd2; - if (sb->sv_block_size == BLOCK_SIZE) - /* block size = 1024, so bh1 = bh2 */ + if (sb->sv_block_size >= BLOCK_SIZE) + /* block size >= 1024, so bh1 = bh2 */ sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data; else { /* block size = 512, so bh1 != bh2 */ @@ -168,7 +163,6 @@ static struct super_block * detected_xenix (struct super_block *sb, struct buffe sb->sv_sb_flc_blocks = &sbd1->s_free[0]; sb->sv_sb_total_free_blocks = &sbd2->s_tfree; sb->sv_sb_time = &sbd2->s_time; - sb->sv_block_base = 0; sb->sv_firstinodezone = 2; sb->sv_firstdatazone = sbd1->s_isize; sb->sv_nzones = sbd1->s_fsize; @@ -185,11 +179,9 @@ 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; - switch (sbd->s_type) { - case 1: detected_bs512(sb); break; - case 2: detected_bs1024(sb); break; - default: return NULL; - } + if (sbd->s_type > 3 || sbd->s_type < 1) + return NULL; + detected_bs(sbd->s_type, sb); sb->sv_type = FSTYPE_SYSV4; return "SystemV"; } @@ -197,7 +189,7 @@ static struct super_block * detected_sysv4 (struct super_block *sb, struct buffe { struct sysv4_super_block * sbd; - if (sb->sv_block_size == BLOCK_SIZE) + if (sb->sv_block_size >= BLOCK_SIZE) sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2); else { sbd = (struct sysv4_super_block *) bh->b_data; @@ -226,7 +218,6 @@ static struct super_block * detected_sysv4 (struct super_block *sb, struct buffe sb->sv_sb_total_free_blocks = &sbd->s_tfree; sb->sv_sb_time = &sbd->s_time; sb->sv_sb_state = &sbd->s_state; - sb->sv_block_base = 0; sb->sv_firstinodezone = 2; sb->sv_firstdatazone = sbd->s_isize; sb->sv_nzones = sbd->s_fsize; @@ -243,11 +234,9 @@ static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh) return NULL; if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */ return NULL; - switch (sbd->s_type) { - case 1: detected_bs512(sb); break; - case 2: detected_bs1024(sb); break; - default: return NULL; - } + if (sbd->s_type > 3 || sbd->s_type < 1) + return NULL; + detected_bs(sbd->s_type, sb); sb->sv_type = FSTYPE_SYSV2; return "SystemV Release 2"; } @@ -255,7 +244,7 @@ static struct super_block * detected_sysv2 (struct super_block *sb, struct buffe { struct sysv2_super_block * sbd; - if (sb->sv_block_size == BLOCK_SIZE) + if (sb->sv_block_size >= BLOCK_SIZE) sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2); else { sbd = (struct sysv2_super_block *) bh->b_data; @@ -284,7 +273,6 @@ static struct super_block * detected_sysv2 (struct super_block *sb, struct buffe sb->sv_sb_total_free_blocks = &sbd->s_tfree; sb->sv_sb_time = &sbd->s_time; sb->sv_sb_state = &sbd->s_state; - sb->sv_block_base = 0; sb->sv_firstinodezone = 2; sb->sv_firstdatazone = sbd->s_isize; sb->sv_nzones = sbd->s_fsize; @@ -300,7 +288,7 @@ static const char* detect_coherent (struct super_block *sb, struct buffer_head * if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6)) || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6))) return NULL; - detected_bs512(sb); + detected_bs(1, sb); sb->sv_type = FSTYPE_COH; return "Coherent"; } @@ -331,7 +319,6 @@ static struct super_block * detected_coherent (struct super_block *sb, struct bu sb->sv_sb_flc_blocks = &sbd->s_free[0]; sb->sv_sb_total_free_blocks = &sbd->s_tfree; sb->sv_sb_time = &sbd->s_time; - sb->sv_block_base = 0; sb->sv_firstinodezone = 2; sb->sv_firstdatazone = sbd->s_isize; sb->sv_nzones = from_coh_ulong(sbd->s_fsize); @@ -346,7 +333,8 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, const char *found; kdev_t dev = sb->s_dev; struct inode *root_inode; - + unsigned long blocknr; + if (1024 != sizeof (struct xenix_super_block)) panic("Xenix FS: bad super-block size"); if ((512 != sizeof (struct sysv4_super_block)) @@ -359,6 +347,7 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, MOD_INC_USE_COUNT; lock_super(sb); set_blocksize(dev,BLOCK_SIZE); + sb->sv_block_base = 0; /* Try to read Xenix superblock */ if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) { @@ -379,22 +368,29 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, } /* Try to recognize SystemV superblock */ /* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */ + /* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */ + /* Maybe we should also check the device geometry ? */ { static int offsets[] = { 9, 15, 18, }; int i; for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++) if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) { /* Try to recognize SystemV superblock */ if ((found = detect_sysv4(sb,bh)) != NULL) { - sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits; + if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2)) + goto bad_shift; + sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits; goto ok; } if ((found = detect_sysv2(sb,bh)) != NULL) { - sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits; + if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2)) + goto bad_shift; + sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits; goto ok; } brelse(bh); } } + bad_shift: sb->s_dev = 0; unlock_super(sb); if (!silent) @@ -405,7 +401,14 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, return NULL; ok: - if (sb->sv_block_size == BLOCK_SIZE) { + if (sb->sv_block_size >= BLOCK_SIZE) { + if (sb->sv_block_size != BLOCK_SIZE) { + brelse(bh); + set_blocksize(dev, sb->sv_block_size); + blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits; + if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL) + goto bad_superblock; + } switch (sb->sv_type) { case FSTYPE_XENIX: if (!detected_xenix(sb,bh,bh)) @@ -419,19 +422,21 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data, if (!detected_sysv2(sb,bh)) goto bad_superblock; break; - default: - bad_superblock: - brelse(bh); - sb->s_dev = 0; - unlock_super(sb); - printk("SysV FS: cannot read superblock in 1024 byte mode\n"); - goto failed; + default: goto bad_superblock; + goto superblock_ok; + bad_superblock: + brelse(bh); + sb->s_dev = 0; + unlock_super(sb); + printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size); + goto failed; + superblock_ok: } } else { - /* Switch to another block size. Unfortunately, we have to - release the 1 KB block bh and read it in two parts again. */ + /* Switch to 512 block size. Unfortunately, we have to + release the block bh and read it again. */ struct buffer_head *bh1, *bh2; - unsigned long blocknr = bh->b_blocknr << sb->sv_block_size_ratio_bits; + unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits; brelse(bh); set_blocksize(dev,sb->sv_block_size); @@ -873,8 +878,9 @@ void sysv_read_inode(struct inode * inode) } /* To avoid inconsistencies between inodes in memory and inodes on disk. */ -extern int sysv_notify_change(struct inode *inode, struct iattr *attr) +int sysv_notify_change(struct dentry *dentry, struct iattr *attr) { + struct inode *inode = dentry->d_inode; int error; if ((error = inode_change_ok(inode, attr)) != 0) diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index ff3d7c7af..270cfe637 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -9,12 +9,8 @@ * * sysv/namei.c * Copyright (C) 1993 Bruno Haible - * - * - * Revised: 15 Dec 1997 by Krzysztof G. Baranowski - * Driver updated to use dentries. */ - + #include #include @@ -51,7 +47,7 @@ static int sysv_match(int len, const char * name, struct sysv_dir_entry * de) /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ if (!len && (de->name[0]=='.') && (de->name[1]=='\0')) return 1; - return namecompare(len,SYSV_NAMELEN,name,de->name); + return namecompare(len, SYSV_NAMELEN, name, de->name); } /* @@ -82,7 +78,7 @@ static struct buffer_head * sysv_find_entry(struct inode * dir, pos = block = offset = 0; while (pos < dir->i_size) { if (!bh) { - bh = sysv_file_bread(dir,block,0); + bh = sysv_file_bread(dir, block, 0); if (!bh) { /* offset = 0; */ block++; pos += sb->sv_block_size; @@ -121,7 +117,7 @@ int sysv_lookup(struct inode * dir, struct dentry * dentry) if (bh) { int ino = de->inode; brelse(bh); - inode = iget(dir->i_sb,ino); + inode = iget(dir->i_sb, ino); if (!inode) return -EACCES; @@ -167,7 +163,7 @@ static int sysv_add_entry(struct inode * dir, pos = block = offset = 0; while (1) { if (!bh) { - bh = sysv_file_bread(dir,block,1); + bh = sysv_file_bread(dir, block, 1); if (!bh) return -ENOSPC; } @@ -218,7 +214,7 @@ int sysv_create(struct inode * dir, struct dentry * dentry, int mode) inode->i_op = &sysv_file_inode_operations; inode->i_mode = mode; mark_inode_dirty(inode); - error = sysv_add_entry(dir,dentry->d_name.name, + error = sysv_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de); if (error) { inode->i_nlink--; @@ -242,8 +238,8 @@ int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev) if (!dir) return -ENOENT; - bh = sysv_find_entry(dir,dentry->d_name.name, - dentry->d_name.len,&de); + bh = sysv_find_entry(dir, dentry->d_name.name, + dentry->d_name.len, &de); if (bh) { brelse(bh); return -EEXIST; @@ -272,7 +268,8 @@ int sysv_mknod(struct inode * dir, struct dentry * dentry, int mode, int rdev) if (S_ISBLK(mode) || S_ISCHR(mode)) inode->i_rdev = to_kdev_t(rdev); mark_inode_dirty(inode); - error = sysv_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de); + error = sysv_add_entry(dir, dentry->d_name.name, + dentry->d_name.len, &bh, &de); if (error) { inode->i_nlink--; mark_inode_dirty(inode); @@ -363,7 +360,7 @@ static int empty_dir(struct inode * inode) goto bad_dir; if (inode->i_size < pos) goto bad_dir; - bh = sysv_file_bread(inode,0,0); + bh = sysv_file_bread(inode, 0, 0); if (!bh) goto bad_dir; de = (struct sysv_dir_entry *) (bh->b_data + 0*SYSV_DIRSIZE); @@ -375,7 +372,7 @@ static int empty_dir(struct inode * inode) sb = inode->i_sb; while (pos < inode->i_size) { if (!bh) { - bh = sysv_file_bread(inode,block,0); + bh = sysv_file_bread(inode, block, 0); if (!bh) { /* offset = 0; */ block++; pos += sb->sv_block_size; @@ -420,9 +417,9 @@ int sysv_rmdir(struct inode * dir, struct dentry * dentry) retval = -EPERM; inode = dentry->d_inode; - if ((dir->i_mode & S_ISVTX) && !fsuser() && + if ((dir->i_mode & S_ISVTX) && current->fsuid != inode->i_uid && - current->fsuid != dir->i_uid) + current->fsuid != dir->i_uid && !fsuser()) goto end_rmdir; if (inode->i_dev != dir->i_dev) goto end_rmdir; @@ -445,7 +442,7 @@ int sysv_rmdir(struct inode * dir, struct dentry * dentry) goto end_rmdir; } if (inode->i_nlink != 2) - printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink); + printk("empty directory has nlink!=2 (%d)\n", inode->i_nlink); de->inode = 0; mark_buffer_dirty(bh, 1); inode->i_nlink=0; @@ -485,9 +482,9 @@ repeat: schedule(); goto repeat; } - if ((dir->i_mode & S_ISVTX) && !fsuser() && + if ((dir->i_mode & S_ISVTX) && current->fsuid != inode->i_uid && - current->fsuid != dir->i_uid) + current->fsuid != dir->i_uid && !fsuser()) goto end_unlink; if (de->inode != inode->i_ino) { retval = -ENOENT; @@ -495,8 +492,7 @@ repeat: } if (!inode->i_nlink) { printk("Deleting nonexistent file (%s:%lu), %d\n", - kdevname(inode->i_dev), - inode->i_ino, inode->i_nlink); + kdevname(inode->i_dev), inode->i_ino, inode->i_nlink); inode->i_nlink=1; } de->inode = 0; @@ -530,7 +526,7 @@ int sysv_symlink(struct inode * dir, struct dentry * dentry, inode->i_mode = S_IFLNK | 0777; inode->i_op = &sysv_symlink_inode_operations; - name_block = sysv_file_bread(inode,0,1); + name_block = sysv_file_bread(inode, 0, 1); if (!name_block) { inode->i_nlink--; mark_inode_dirty(inode); @@ -571,9 +567,10 @@ int sysv_symlink(struct inode * dir, struct dentry * dentry, return 0; } -int sysv_link(struct inode * oldinode, struct inode * dir, +int sysv_link(struct dentry * old_dentry, struct inode * dir, struct dentry * dentry) { + struct inode *oldinode = old_dentry->d_inode; int error; struct sysv_dir_entry * de; struct buffer_head * bh; @@ -606,25 +603,6 @@ int sysv_link(struct inode * oldinode, struct inode * dir, return 0; } -/* return 1 if `new' is a subdir of `old' on the same device */ -static int subdir(struct dentry * new_dentry, struct dentry * old_dentry) -{ - int result = 0; - - for (;;) { - if (new_dentry != old_dentry) { - struct dentry * parent = new_dentry->d_parent; - if (parent == new_dentry) - break; - new_dentry = parent; - continue; - } - result = 1; - break; - } - return result; -} - #define PARENT_INO(buffer) \ (((struct sysv_dir_entry *) ((buffer) + 1*SYSV_DIRSIZE))->inode) @@ -656,20 +634,20 @@ try_again: start_up: old_inode = new_inode = NULL; old_bh = new_bh = dir_bh = NULL; - old_bh = sysv_find_entry(old_dir,old_dentry->d_name.name, - old_dentry->d_name.len,&old_de); + old_bh = sysv_find_entry(old_dir, old_dentry->d_name.name, + old_dentry->d_name.len, &old_de); retval = -ENOENT; if (!old_bh) goto end_rename; - old_inode = old_dentry->d_inode;/* don't cross mnt-points */ + 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 && !fsuser()) 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); + new_bh = sysv_find_entry(new_dir, new_dentry->d_name.name, + new_dentry->d_name.len, &new_de); if (new_bh) { if (!new_inode) { brelse(new_bh); @@ -685,7 +663,7 @@ start_up: if (!S_ISDIR(old_inode->i_mode)) goto end_rename; retval = -EINVAL; - if (subdir(new_dentry, old_dentry)) + if (is_subdir(new_dentry, old_dentry)) goto end_rename; retval = -ENOTEMPTY; if (!empty_dir(new_inode)) @@ -704,10 +682,10 @@ start_up: if (new_inode && !S_ISDIR(new_inode->i_mode)) goto end_rename; retval = -EINVAL; - if (subdir(new_dentry, old_dentry)) + if (is_subdir(new_dentry, old_dentry)) goto end_rename; retval = -EIO; - dir_bh = sysv_file_bread(old_inode,0,0); + dir_bh = sysv_file_bread(old_inode, 0, 0); if (!dir_bh) goto end_rename; if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino) @@ -717,8 +695,8 @@ start_up: goto end_rename; } if (!new_bh) { - retval = sysv_add_entry(new_dir,new_dentry->d_name.name, - new_dentry->d_name.len,&new_bh,&new_de); + retval = sysv_add_entry(new_dir, new_dentry->d_name.name, + new_dentry->d_name.len, &new_bh, &new_de); if (retval) goto end_rename; } diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c index d76c3fa66..2ce56e390 100644 --- a/fs/sysv/symlink.c +++ b/fs/sysv/symlink.c @@ -20,8 +20,8 @@ #include -static int sysv_readlink(struct inode *, char *, int); -static struct dentry *sysv_follow_link(struct inode *, struct dentry *); +static int sysv_readlink(struct dentry *, char *, int); +static struct dentry *sysv_follow_link(struct dentry *, struct dentry *); /* * symlinks can't do much... @@ -46,8 +46,10 @@ struct inode_operations sysv_symlink_inode_operations = { NULL /* permission */ }; -static struct dentry *sysv_follow_link(struct inode * inode, struct dentry * base) +static struct dentry *sysv_follow_link(struct dentry * dentry, + struct dentry * base) { + struct inode *inode = dentry->d_inode; struct buffer_head * bh; bh = sysv_file_bread(inode, 0, 0); @@ -61,8 +63,9 @@ static struct dentry *sysv_follow_link(struct inode * inode, struct dentry * bas return base; } -static int sysv_readlink(struct inode * inode, char * buffer, int buflen) +static int sysv_readlink(struct dentry * dentry, char * buffer, int buflen) { + struct inode *inode = dentry->d_inode; struct buffer_head * bh; char * bh_data; int i; -- cgit v1.2.3