summaryrefslogtreecommitdiffstats
path: root/fs/sysv
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
committer <ralf@linux-mips.org>1997-01-07 02:33:00 +0000
commitbeb116954b9b7f3bb56412b2494b562f02b864b1 (patch)
tree120e997879884e1b9d93b265221b939d2ef1ade1 /fs/sysv
parent908d4681a1dc3792ecafbe64265783a86c4cccb6 (diff)
Import of Linux/MIPS 2.1.14
Diffstat (limited to 'fs/sysv')
-rw-r--r--fs/sysv/Makefile29
-rw-r--r--fs/sysv/README37
-rw-r--r--fs/sysv/balloc.c12
-rw-r--r--fs/sysv/dir.c20
-rw-r--r--fs/sysv/file.c46
-rw-r--r--fs/sysv/fsync.c8
-rw-r--r--fs/sysv/ialloc.c7
-rw-r--r--fs/sysv/inode.c98
-rw-r--r--fs/sysv/mmap.c85
-rw-r--r--fs/sysv/namei.c23
-rw-r--r--fs/sysv/symlink.c12
-rw-r--r--fs/sysv/truncate.c14
12 files changed, 127 insertions, 264 deletions
diff --git a/fs/sysv/Makefile b/fs/sysv/Makefile
index 4ef1cddcd..b5801e994 100644
--- a/fs/sysv/Makefile
+++ b/fs/sysv/Makefile
@@ -7,28 +7,9 @@
#
# Note 2! The CFLAGS definitions are now in the main makefile...
-.c.s:
- $(CC) $(CFLAGS) -S $<
-.c.o:
- $(CC) $(CFLAGS) -c $<
-.s.o:
- $(AS) -o $*.o $<
+O_TARGET := sysv.o
+O_OBJS := ialloc.o balloc.o inode.o file.o dir.o symlink.o namei.o \
+ fsync.o truncate.o
+M_OBJS := $(O_TARGET)
-OBJS= ialloc.o balloc.o inode.o file.o dir.o symlink.o namei.o \
- fsync.o truncate.o
-
-sysv.o: $(OBJS)
- $(LD) -r -o sysv.o $(OBJS)
-
-modules: sysv.o
- ln -sf ../fs/sysv/sysv.o $(TOPDIR)/modules
-
-dep:
- $(CPP) -M *.c > .depend
-
-#
-# include a dependency file if one exists
-#
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
+include $(TOPDIR)/Rules.make
diff --git a/fs/sysv/README b/fs/sysv/README
deleted file mode 100644
index d318eb64b..000000000
--- a/fs/sysv/README
+++ /dev/null
@@ -1,37 +0,0 @@
-This is the implementation of the SystemV/Coherent filesystem for Linux.
-It implements all of
- - Xenix FS,
- - SystemV/386 FS,
- - Coherent FS.
-
-This is version beta 4.
-
-To install:
-* Answer the 'System V and Coherent filesystem support' question with 'y'
- when configuring the kernel.
-* To mount a disk or a partition, use
- mount [-r] -t sysv device mountpoint
- The file system type names
- -t sysv
- -t xenix
- -t coherent
- may be used interchangeably, but the last two will eventually disappear.
-
-Bugs in the present implementation:
-- Coherent FS:
- - The "free list interleave" n:m is currently ignored.
- - Only file systems with no filesystem name and no pack name are recognized.
- (See Coherent "man mkfs" for a description of these features.)
-- SystemV Release 2 FS:
- The superblock is only searched in the blocks 9, 15, 18, which corresponds to the
- beginning of track 1 on floppy disks. No support for this FS on hard disk yet.
-
-
-Please report any bugs and suggestions to
- Bruno Haible <haible@ma2s2.mathematik.uni-karlsruhde.de> or
- Pascal Haible <haible@izfm.uni-stuttgart.de> .
-
-
-Bruno Haible
-<haible@ma2s2.mathematik.uni-karlsruhe.de>
-
diff --git a/fs/sysv/balloc.c b/fs/sysv/balloc.c
index eddbb0bea..5fa82929b 100644
--- a/fs/sysv/balloc.c
+++ b/fs/sysv/balloc.c
@@ -19,10 +19,6 @@
* This file contains code for allocating/freeing blocks.
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
@@ -88,7 +84,7 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
*flc_count = *sb->sv_sb_flc_count; /* = sb->sv_flc_size */
memcpy(flc_blocks, sb->sv_sb_flc_blocks, *flc_count * sizeof(sysv_zone_t));
mark_buffer_dirty(bh, 1);
- bh->b_uptodate = 1;
+ mark_buffer_uptodate(bh, 1);
brelse(bh);
*sb->sv_sb_flc_count = 0;
} else
@@ -105,14 +101,14 @@ void sysv_free_block(struct super_block * sb, unsigned int block)
memset(bh->b_data, 0, sb->sv_block_size);
/* this implies ((struct ..._freelist_chunk *) bh->b_data)->flc_count = 0; */
mark_buffer_dirty(bh, 1);
- bh->b_uptodate = 1;
+ mark_buffer_uptodate(bh, 1);
brelse(bh);
/* still *sb->sv_sb_flc_count = 0 */
} else {
/* Throw away block's contents */
bh = sv_get_hash_table(sb, sb->s_dev, block);
if (bh)
- bh->b_dirt = 0;
+ mark_buffer_clean(bh);
brelse(bh);
}
if (sb->sv_convert)
@@ -212,7 +208,7 @@ int sysv_new_block(struct super_block * sb)
}
memset(bh->b_data, 0, sb->sv_block_size);
mark_buffer_dirty(bh, 1);
- bh->b_uptodate = 1;
+ mark_buffer_uptodate(bh, 1);
brelse(bh);
if (sb->sv_convert)
*sb->sv_sb_total_free_blocks =
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index cfd85993e..52515b4f9 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -13,18 +13,16 @@
* SystemV/Coherent directory handling functions
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/segment.h>
-
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/stat.h>
+#include <linux/string.h>
+
+#include <asm/uaccess.h>
-static int sysv_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
+static long sysv_dir_read(struct inode * inode, struct file * filp,
+ char * buf, unsigned long count)
{
return -EISDIR;
}
@@ -60,6 +58,8 @@ struct inode_operations sysv_dir_inode_operations = {
sysv_rename, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
NULL, /* bmap */
sysv_truncate, /* truncate */
NULL /* permission */
@@ -95,8 +95,10 @@ static int sysv_readdir(struct inode * inode, struct file * filp,
memcpy(&sde, de, sizeof(struct sysv_dir_entry));
if (sde.inode > inode->i_sb->sv_ninodes)
- printk("sysv_readdir: Bad inode number on dev 0x%04x, ino %ld, offset 0x%04lx: %d is out of range\n",
- inode->i_dev, inode->i_ino, (off_t) filp->f_pos, sde.inode);
+ printk("sysv_readdir: Bad inode number on dev "
+ "%s, ino %ld, offset 0x%04lx: %d is out of range\n",
+ kdevname(inode->i_dev),
+ inode->i_ino, (off_t) filp->f_pos, sde.inode);
i = strnlen(sde.name, SYSV_NAMELEN);
if (filldir(dirent, sde.name, i, filp->f_pos, sde.inode) < 0) {
diff --git a/fs/sysv/file.c b/fs/sysv/file.c
index f098af6b6..6029051d8 100644
--- a/fs/sysv/file.c
+++ b/fs/sysv/file.c
@@ -13,12 +13,6 @@
* SystemV/Coherent regular file handling primitives
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/segment.h>
-
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
@@ -27,6 +21,9 @@
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/locks.h>
+#include <linux/pagemap.h>
+
+#include <asm/uaccess.h>
#define NBUF 32
@@ -36,7 +33,7 @@
#include <linux/fs.h>
#include <linux/sysv_fs.h>
-static int sysv_file_write(struct inode *, struct file *, char *, int);
+static long sysv_file_write(struct inode *, struct file *, const char *, unsigned long);
/*
* We have mostly NULL's here: the current defaults are ok for
@@ -49,7 +46,7 @@ static struct file_operations sysv_file_operations = {
NULL, /* readdir - bad */
NULL, /* select - default */
NULL, /* ioctl - default */
- generic_mmap, /* mmap */
+ generic_file_mmap, /* mmap */
NULL, /* no special open is needed */
NULL, /* release */
sysv_sync_file /* fsync */
@@ -68,12 +65,15 @@ struct inode_operations sysv_file_inode_operations = {
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
+ generic_readpage, /* readpage */
+ NULL, /* writepage */
sysv_bmap, /* bmap */
sysv_truncate, /* truncate */
NULL /* permission */
};
-int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int count)
+long sysv_file_read(struct inode * inode, struct file * filp,
+ char * buf, unsigned long count)
{
struct super_block * sb = inode->i_sb;
int read,left,chars;
@@ -115,9 +115,9 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
blocks = size - block;
}
- /* We do this in a two stage process. We first try and request
+ /* We do this in a two stage process. We first try to request
as many blocks as we can, then we wait for the first one to
- complete, and then we try and wrap up as many as are actually
+ complete, and then we try to wrap up as many as are actually
done. This routine is rather generic, in that it can be used
in a filesystem by substituting the appropriate function in
for getblk.
@@ -132,7 +132,7 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
while (blocks) {
--blocks;
*bhb = sysv_getblk(inode, block++, 0);
- if (*bhb && !(*bhb)->b_uptodate) {
+ if (*bhb && !buffer_uptodate(*bhb)) {
uptodate = 0;
bhreq[bhrequest++] = *bhb;
}
@@ -155,7 +155,7 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
do { /* Finish off all I/O that has actually completed */
if (*bhe) {
wait_on_buffer(*bhe);
- if (!(*bhe)->b_uptodate) { /* read error? */
+ if (!buffer_uptodate(*bhe)) { /* read error? */
brelse(*bhe);
if (++bhe == &buflist[NBUF])
bhe = buflist;
@@ -171,17 +171,17 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
left -= chars;
read += chars;
if (*bhe) {
- memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
+ copy_to_user(buf,offset+(*bhe)->b_data,chars);
brelse(*bhe);
buf += chars;
} else {
while (chars-- > 0)
- put_fs_byte(0,buf++);
+ put_user(0,buf++);
}
offset = 0;
if (++bhe == &buflist[NBUF])
bhe = buflist;
- } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
+ } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
} while (left > 0);
/* Release the read-ahead blocks */
@@ -200,7 +200,8 @@ int sysv_file_read(struct inode * inode, struct file * filp, char * buf, int cou
return read;
}
-static int sysv_file_write(struct inode * inode, struct file * filp, char * buf, int count)
+static long sysv_file_write(struct inode * inode, struct file * filp,
+ const char * buf, unsigned long count)
{
struct super_block * sb = inode->i_sb;
off_t pos;
@@ -238,27 +239,28 @@ static int sysv_file_write(struct inode * inode, struct file * filp, char * buf,
c = sb->sv_block_size - (pos & sb->sv_block_size_1);
if (c > count-written)
c = count-written;
- if (c != sb->sv_block_size && !bh->b_uptodate) {
+ if (c != sb->sv_block_size && !buffer_uptodate(bh)) {
ll_rw_block(READ, 1, &bh);
wait_on_buffer(bh);
- if (!bh->b_uptodate) {
+ if (!buffer_uptodate(bh)) {
brelse(bh);
if (!written)
written = -EIO;
break;
}
}
- /* now either c==sb->sv_block_size or bh->b_uptodate */
+ /* now either c==sb->sv_block_size or buffer_uptodate(bh) */
p = (pos & sb->sv_block_size_1) + bh->b_data;
+ copy_from_user(p, buf, c);
+ update_vm_cache(inode, pos, p, c);
pos += c;
if (pos > inode->i_size) {
inode->i_size = pos;
inode->i_dirt = 1;
}
written += c;
- memcpy_fromfs(p,buf,c);
buf += c;
- bh->b_uptodate = 1;
+ mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 0);
brelse(bh);
}
diff --git a/fs/sysv/fsync.c b/fs/sysv/fsync.c
index af1218fca..df3b948df 100644
--- a/fs/sysv/fsync.c
+++ b/fs/sysv/fsync.c
@@ -14,10 +14,6 @@
* SystemV/Coherent fsync primitive
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
#include <linux/errno.h>
#include <linux/stat.h>
@@ -49,11 +45,11 @@ static int sync_block (struct inode * inode, unsigned long * blockp, int convert
brelse (bh);
return 1;
}
- if (wait && bh->b_req && !bh->b_uptodate) {
+ if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
brelse(bh);
return -1;
}
- if (wait || !bh->b_uptodate || !bh->b_dirt) {
+ if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
brelse(bh);
return 0;
}
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c
index 98883c22c..85ba640d1 100644
--- a/fs/sysv/ialloc.c
+++ b/fs/sysv/ialloc.c
@@ -19,10 +19,6 @@
* This file contains code for allocating/freeing inodes.
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -84,7 +80,8 @@ void sysv_free_inode(struct inode * inode)
return;
}
if (!(bh = sv_bread(sb, inode->i_dev, sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits)))) {
- printk("sysv_free_inode: unable to read inode block on device %d/%d\n",MAJOR(inode->i_dev),MINOR(inode->i_dev));
+ printk("sysv_free_inode: unable to read inode block on device "
+ "%s\n", kdevname(inode->i_dev));
clear_inode(inode);
return;
}
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 4aa0932cb..4e14cb35e 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -20,13 +20,7 @@
* the superblock.
*/
-#ifdef MODULE
#include <linux/module.h>
-#include <linux/version.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -36,7 +30,7 @@
#include <linux/string.h>
#include <linux/locks.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
void sysv_put_inode(struct inode *inode)
{
@@ -347,7 +341,7 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
{
struct buffer_head *bh;
const char *found;
- int dev = sb->s_dev;
+ kdev_t dev = sb->s_dev;
if (1024 != sizeof (struct xenix_super_block))
panic("Xenix FS: bad super-block size");
@@ -397,10 +391,11 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
brelse(bh);
}
}
- sb->s_dev=0;
+ sb->s_dev = 0;
unlock_super(sb);
if (!silent)
- printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device %d/%d\n",MAJOR(dev),MINOR(dev));
+ printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "
+ "%s\n", kdevname(dev));
failed:
MOD_DEC_USE_COUNT;
return NULL;
@@ -477,7 +472,8 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
}
sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
if (!silent)
- printk("VFS: Found a %s FS (block size = %d) on device %d/%d\n",found,sb->sv_block_size,MAJOR(dev),MINOR(dev));
+ printk("VFS: Found a %s FS (block size = %d) on device %s\n",
+ found, sb->sv_block_size, kdevname(dev));
sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type;
/* The buffer code now supports block size 512 as well as 1024. */
sb->s_blocksize = sb->sv_block_size;
@@ -502,7 +498,7 @@ struct super_block *sysv_read_super(struct super_block *sb,void *data,
void sysv_write_super (struct super_block *sb)
{
lock_super(sb);
- if (sb->sv_bh1->b_dirt || sb->sv_bh2->b_dirt) {
+ if (buffer_dirty(sb->sv_bh1) || buffer_dirty(sb->sv_bh2)) {
/* If we are going to write out the super block,
then attach current time stamp.
But if the filesystem was marked clean, keep it clean. */
@@ -540,15 +536,16 @@ void sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
{
struct statfs tmp;
- tmp.f_type = sb->s_magic;
- tmp.f_bsize = sb->sv_block_size;
- tmp.f_blocks = sb->sv_ndatazones;
- tmp.f_bfree = sysv_count_free_blocks(sb);
- tmp.f_bavail = tmp.f_bfree;
- tmp.f_files = sb->sv_ninodes;
- tmp.f_ffree = sysv_count_free_inodes(sb);
+ tmp.f_type = sb->s_magic; /* type of filesystem */
+ tmp.f_bsize = sb->sv_block_size; /* block size */
+ tmp.f_blocks = sb->sv_ndatazones; /* total data blocks in file system */
+ tmp.f_bfree = sysv_count_free_blocks(sb); /* free blocks in fs */
+ tmp.f_bavail = tmp.f_bfree; /* free blocks available to non-superuser */
+ tmp.f_files = sb->sv_ninodes; /* total file nodes in file system */
+ tmp.f_ffree = sysv_count_free_inodes(sb); /* free file nodes in fs */
tmp.f_namelen = SYSV_NAMELEN;
- memcpy_tofs(buf, &tmp, bufsiz);
+ /* Don't know what value to put in tmp.f_fsid */ /* file system id */
+ copy_to_user(buf, &tmp, bufsiz);
}
@@ -682,10 +679,10 @@ static struct buffer_head * block_getblk(struct inode * inode,
if (!bh)
return NULL;
- if (!bh->b_uptodate) {
+ if (!buffer_uptodate(bh)) {
ll_rw_block(READ, 1, &bh);
wait_on_buffer(bh);
- if (!bh->b_uptodate) {
+ if (!buffer_uptodate(bh)) {
brelse(bh);
return NULL;
}
@@ -764,11 +761,11 @@ struct buffer_head * sysv_file_bread(struct inode * inode, int block, int create
struct buffer_head * bh;
bh = sysv_getblk(inode,block,create);
- if (!bh || bh->b_uptodate)
+ if (!bh || buffer_uptodate(bh))
return bh;
ll_rw_block(READ, 1, &bh);
wait_on_buffer(bh);
- if (bh->b_uptodate)
+ if (buffer_uptodate(bh))
return bh;
brelse(bh);
return NULL;
@@ -811,14 +808,16 @@ void sysv_read_inode(struct inode * inode)
inode->i_op = NULL;
inode->i_mode = 0;
if (!ino || ino > sb->sv_ninodes) {
- printk("Bad inode number on dev 0x%04x: %d is out of range\n",
- inode->i_dev, ino);
+ printk("Bad inode number on dev %s"
+ ": %d is out of range\n",
+ kdevname(inode->i_dev), ino);
return;
}
block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
if (!(bh = sv_bread(sb,inode->i_dev,block))) {
- printk("Major problem: unable to read inode from dev 0x%04x\n",
- inode->i_dev);
+ printk("Major problem: unable to read inode from dev "
+ "%s\n",
+ kdevname(inode->i_dev));
return;
}
raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
@@ -843,7 +842,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 = raw_inode->i_a.i_rdev;
+ 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++)
@@ -896,8 +895,9 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
ino = inode->i_ino;
if (!ino || ino > sb->sv_ninodes) {
- printk("Bad inode number on dev 0x%04x: %d is out of range\n",
- inode->i_dev, ino);
+ printk("Bad inode number on dev %s"
+ ": %d is out of range\n",
+ kdevname(inode->i_dev), ino);
inode->i_dirt = 0;
return 0;
}
@@ -927,7 +927,7 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
raw_inode->i_ctime = inode->i_ctime;
}
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- raw_inode->i_a.i_rdev = inode->i_rdev; /* write 2 or 3 bytes ?? */
+ raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev); /* write 2 or 3 bytes ?? */
else
if (sb->sv_convert)
for (block = 0; block < 10+1+1+1; block++)
@@ -953,13 +953,14 @@ int sysv_sync_inode(struct inode * inode)
struct buffer_head *bh;
bh = sysv_update_inode(inode);
- if (bh && bh->b_dirt) {
+ if (bh && buffer_dirty(bh)) {
ll_rw_block(WRITE, 1, &bh);
wait_on_buffer(bh);
- if (bh->b_req && !bh->b_uptodate)
+ if (buffer_req(bh) && !buffer_uptodate(bh))
{
- printk ("IO error syncing sysv inode [%04x:%08lx]\n",
- inode->i_dev, inode->i_ino);
+ printk ("IO error syncing sysv inode ["
+ "%s:%08lx]\n",
+ kdevname(inode->i_dev), inode->i_ino);
err = -1;
}
}
@@ -969,26 +970,34 @@ int sysv_sync_inode(struct inode * inode)
return err;
}
-#ifdef MODULE
-
/* Every kernel module contains stuff like this. */
-char kernel_version[] = UTS_RELEASE;
-
static struct file_system_type sysv_fs_type[3] = {
{sysv_read_super, "xenix", 1, NULL},
{sysv_read_super, "sysv", 1, NULL},
{sysv_read_super, "coherent", 1, NULL}
};
-int init_module(void)
+int init_sysv_fs(void)
{
int i;
+ int ouch;
- for (i = 0; i < 3; i++)
- register_filesystem(&sysv_fs_type[i]);
+ for (i = 0; i < 3; i++) {
+ if ((ouch = register_filesystem(&sysv_fs_type[i])) != 0)
+ return ouch;
+ }
+ return ouch;
+}
- return 0;
+#ifdef MODULE
+int init_module(void)
+{
+ int status;
+
+ if ((status = init_sysv_fs()) == 0)
+ register_symtab(0);
+ return status;
}
void cleanup_module(void)
@@ -996,6 +1005,7 @@ void cleanup_module(void)
int i;
for (i = 0; i < 3; i++)
+ /* No error message if this breaks... that's OK... */
unregister_filesystem(&sysv_fs_type[i]);
}
diff --git a/fs/sysv/mmap.c b/fs/sysv/mmap.c
deleted file mode 100644
index 3ec3867a9..000000000
--- a/fs/sysv/mmap.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * linux/fs/sysv/mmap.c
- *
- * mm/memory.c, mm/mmap.c
- * Copyright (C) 1991, 1992, 1993 Linus Torvalds
- *
- * nfs/mmap.c
- * Copyright (C) 1993 Jon Tombs
- *
- * fs/msdos/mmap.c
- * Copyright (C) 1994 Jacques Gelinas
- *
- * fs/sysv/mmap.c
- * Copyright (C) 1994 Bruno Haible
- *
- * SystemV/Coherent mmap handling
- */
-
-#include <asm/segment.h>
-
-#include <linux/fs.h>
-#include <linux/sysv_fs.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/malloc.h>
-
-/*
- * Fill in the supplied page for mmap
- */
-static unsigned long sysv_file_mmap_nopage (struct vm_area_struct * area,
- unsigned long address, unsigned long page, int no_share)
-{
- int remaining, count, old_fs;
- struct file filp;
-
- address &= PAGE_MASK;
- /* prepare a file pointer */
- filp.f_pos = address - area->vm_start + area->vm_offset;
- filp.f_reada = 0;
- remaining = area->vm_end - address;
- if (remaining > PAGE_SIZE)
- remaining = PAGE_SIZE;
- /* read from the file. page is in kernel space, not user space. */
- old_fs = get_fs(); set_fs(get_ds());
- count = sysv_file_read (area->vm_inode, &filp, (char *)page, remaining);
- set_fs(old_fs);
- if (count < 0)
- count = 0; /* do nothing on I/O error ?? */
- else
- remaining -= count;
- if (remaining > 0)
- memset((char *)page + count, 0, remaining);
- return page;
-}
-
-static struct vm_operations_struct sysv_file_mmap = {
- NULL, /* open */
- NULL, /* close */
- sysv_file_mmap_nopage, /* nopage */
- NULL, /* wppage */
- NULL, /* share */
- NULL, /* unmap */
-};
-
-int sysv_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
-{
- if (vma->vm_page_prot & PAGE_RW) /* only PAGE_COW or read-only supported right now */
- return -EINVAL;
- if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
- return -EINVAL;
- if (!inode->i_sb || !S_ISREG(inode->i_mode))
- return -EACCES;
- if (!IS_RDONLY(inode)) {
- inode->i_atime = CURRENT_TIME;
- inode->i_dirt = 1;
- }
-
- vma->vm_inode = inode;
- inode->i_count++;
- vma->vm_ops = &sysv_file_mmap;
- return 0;
-}
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 8d245d38e..735d158d4 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -11,10 +11,6 @@
* Copyright (C) 1993 Bruno Haible
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/fs.h>
@@ -279,7 +275,7 @@ int sysv_mknod(struct inode * dir, const char * name, int len, int mode, int rde
else if (S_ISFIFO(inode->i_mode))
init_fifo(inode);
if (S_ISBLK(mode) || S_ISCHR(mode))
- inode->i_rdev = rdev;
+ inode->i_rdev = to_kdev_t(rdev);
inode->i_dirt = 1;
error = sysv_add_entry(dir, name, len, &bh, &de);
if (error) {
@@ -418,7 +414,8 @@ static int empty_dir(struct inode * inode)
return 1;
bad_dir:
brelse(bh);
- printk("Bad directory on device %04x\n",inode->i_dev);
+ printk("Bad directory on device %s\n",
+ kdevname(inode->i_dev));
return 1;
}
@@ -512,8 +509,9 @@ repeat:
goto end_unlink;
}
if (!inode->i_nlink) {
- printk("Deleting nonexistent file (%04x:%lu), %d\n",
- inode->i_dev,inode->i_ino,inode->i_nlink);
+ printk("Deleting nonexistent file (%s:%lu), %d\n",
+ kdevname(inode->i_dev),
+ inode->i_ino, inode->i_nlink);
inode->i_nlink=1;
}
de->inode = 0;
@@ -670,7 +668,7 @@ static int subdir(struct inode * new_inode, struct inode * old_inode)
* higher-level routines.
*/
static int do_sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
- struct inode * new_dir, const char * new_name, int new_len)
+ struct inode * new_dir, const char * new_name, int new_len, int must_be_dir)
{
struct inode * old_inode, * new_inode;
struct buffer_head * old_bh, * new_bh, * dir_bh;
@@ -696,6 +694,8 @@ start_up:
old_inode = __iget(old_dir->i_sb, old_de->inode, 0); /* don't cross mnt-points */
if (!old_inode)
goto end_rename;
+ if (must_be_dir && !S_ISDIR(old_inode->i_mode))
+ goto end_rename;
retval = -EPERM;
if ((old_dir->i_mode & S_ISVTX) &&
current->fsuid != old_inode->i_uid &&
@@ -810,7 +810,8 @@ end_rename:
* as they are on different partitions.
*/
int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
- struct inode * new_dir, const char * new_name, int new_len)
+ struct inode * new_dir, const char * new_name, int new_len,
+ int must_be_dir)
{
static struct wait_queue * wait = NULL;
static int lock = 0;
@@ -820,7 +821,7 @@ int sysv_rename(struct inode * old_dir, const char * old_name, int old_len,
sleep_on(&wait);
lock = 1;
result = do_sysv_rename(old_dir, old_name, old_len,
- new_dir, new_name, new_len);
+ new_dir, new_name, new_len, must_be_dir);
lock = 0;
wake_up(&wait);
return result;
diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c
index c4e7d5bf5..9a33d9fab 100644
--- a/fs/sysv/symlink.c
+++ b/fs/sysv/symlink.c
@@ -13,17 +13,13 @@
* SystemV/Coherent symlink handling code
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/segment.h>
-
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sysv_fs.h>
#include <linux/stat.h>
+#include <asm/uaccess.h>
+
static int sysv_readlink(struct inode *, char *, int);
static int sysv_follow_link(struct inode *, struct inode *, int, int, struct inode **);
@@ -43,6 +39,8 @@ struct inode_operations sysv_symlink_inode_operations = {
NULL, /* rename */
sysv_readlink, /* readlink */
sysv_follow_link, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
NULL, /* bmap */
NULL, /* truncate */
NULL /* permission */
@@ -107,7 +105,7 @@ static int sysv_readlink(struct inode * inode, char * buffer, int buflen)
i = 0;
while (i<buflen && (c = bh_data[i])) {
i++;
- put_fs_byte(c,buffer++);
+ put_user(c,buffer++);
}
brelse(bh);
return i;
diff --git a/fs/sysv/truncate.c b/fs/sysv/truncate.c
index 6de370ebd..0eeb10d30 100644
--- a/fs/sysv/truncate.c
+++ b/fs/sysv/truncate.c
@@ -11,10 +11,6 @@
* Copyright (C) 1993 Bruno Haible
*/
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
@@ -175,13 +171,16 @@ static int trunc_dindirect(struct inode * inode, unsigned long offset, unsigned
else
i = (inode->i_size - offset + sb->sv_ind_per_block_block_size_1) >> sb->sv_ind_per_block_block_size_bits;
for (; i < sb->sv_ind_per_block; i++) {
+ unsigned char dirty = 0;
ind = ((sysv_zone_t *) indbh->b_data) + i;
block = tmp = *ind;
if (sb->sv_convert)
block = from_coh_ulong(block);
if (!block)
continue;
- retry |= trunc_indirect(inode,offset+(i<<sb->sv_ind_per_block_bits),ind,sb->sv_convert,&indbh->b_dirt);
+ retry |= trunc_indirect(inode,offset+(i<<sb->sv_ind_per_block_bits),ind,sb->sv_convert,&dirty);
+ if (dirty)
+ mark_buffer_dirty(indbh, 1);
}
for (i = 0; i < sb->sv_ind_per_block; i++)
if (((sysv_zone_t *) indbh->b_data)[i])
@@ -229,13 +228,16 @@ static int trunc_tindirect(struct inode * inode, unsigned long offset, unsigned
else
i = (inode->i_size - offset + sb->sv_ind_per_block_2_block_size_1) >> sb->sv_ind_per_block_2_block_size_bits;
for (; i < sb->sv_ind_per_block; i++) {
+ unsigned char dirty = 0;
ind = ((sysv_zone_t *) indbh->b_data) + i;
block = tmp = *ind;
if (sb->sv_convert)
block = from_coh_ulong(block);
if (!block)
continue;
- retry |= trunc_dindirect(inode,offset+(i<<sb->sv_ind_per_block_2_bits),ind,sb->sv_convert,&indbh->b_dirt);
+ retry |= trunc_dindirect(inode,offset+(i<<sb->sv_ind_per_block_2_bits),ind,sb->sv_convert,&dirty);
+ if (dirty)
+ mark_buffer_dirty(indbh, 1);
}
for (i = 0; i < sb->sv_ind_per_block; i++)
if (((sysv_zone_t *) indbh->b_data)[i])