summaryrefslogtreecommitdiffstats
path: root/fs/xiafs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xiafs')
-rw-r--r--fs/xiafs/Makefile14
-rw-r--r--fs/xiafs/bitmap.c389
-rw-r--r--fs/xiafs/dir.c131
-rw-r--r--fs/xiafs/file.c256
-rw-r--r--fs/xiafs/fsync.c159
-rw-r--r--fs/xiafs/inode.c540
-rw-r--r--fs/xiafs/namei.c854
-rw-r--r--fs/xiafs/symlink.c120
-rw-r--r--fs/xiafs/truncate.c197
-rw-r--r--fs/xiafs/xiafs_mac.h32
10 files changed, 0 insertions, 2692 deletions
diff --git a/fs/xiafs/Makefile b/fs/xiafs/Makefile
deleted file mode 100644
index e596cc559..000000000
--- a/fs/xiafs/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Makefile for the XIAFS filesystem routines.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
-O_TARGET := xiafs.o
-O_OBJS := bitmap.o truncate.o namei.o inode.o file.o dir.o symlink.o fsync.o
-M_OBJS := $(O_TARGET)
-
-include $(TOPDIR)/Rules.make
diff --git a/fs/xiafs/bitmap.c b/fs/xiafs/bitmap.c
deleted file mode 100644
index 15028ce85..000000000
--- a/fs/xiafs/bitmap.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * linux/fs/xiafs/bitmap.c
- *
- * Copyright (C) Q. Frank Xia, 1993.
- *
- * Based on Linus' minix/bitmap.c
- * Copyright (C) Linus Torvalds, 1991, 1992.
- *
- * This software may be redistributed per Linux Copyright.
- */
-
-/* bitmap.c contains the code that handles the inode and block bitmaps */
-
-#include <linux/sched.h>
-#include <linux/locks.h>
-#include <linux/xia_fs.h>
-#include <linux/stat.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/bitops.h>
-
-#include "xiafs_mac.h"
-
-
-char internal_error_message[]="XIA-FS: internal error %s %d\n";
-
-static int find_first_zero(struct buffer_head *bh, int start_bit, int end_bit)
-{
- /* This routine searches first 0 bit from (start_bit) to (end_bit-1).
- * If found the bit is set to 1 and the bit # is returned, otherwise,
- * -1 is returned. Race condition is avoid by using "btsl" and
- * "goto repeat". ---Frank.
- */
-
- int end, i, j, tmp;
- u_long *bmap;
-
- bmap=(u_long *)bh->b_data;
- end = end_bit >> 5;
-
-repeat:
- i=start_bit >> 5;
- if ( (tmp=(~bmap[i]) & (0xffffffff << (start_bit & 31))) )
- goto zone_found;
- while (++i < end)
- if (~bmap[i]) {
- tmp=~bmap[i];
- goto zone_found;
- }
- if ( !(tmp=~bmap[i] & ((1 << (end_bit & 31)) -1)) )
- return -1;
-zone_found:
- for (j=0; j < 32; j++)
- if (tmp & (1 << j))
- break;
- if (set_bit(j,bmap+i)) {
- start_bit=j + (i << 5) + 1;
- goto repeat;
- }
- mark_buffer_dirty(bh, 1);
- return j + (i << 5);
-}
-
-static void clear_buf(struct buffer_head * bh)
-{
- register int i;
- register long * lp;
-
- lp=(long *)bh->b_data;
- for (i= bh->b_size >> 2; i-- > 0; )
- *lp++=0;
-}
-
-static void que(struct buffer_head * bmap[], int bznr[], int pos)
-{
- struct buffer_head * tbh;
- int tmp;
- int i;
-
- tbh=bmap[pos];
- tmp=bznr[pos];
- for (i=pos; i > 0; i--) {
- bmap[i]=bmap[i-1];
- bznr[i]=bznr[i-1];
- }
- bmap[0]=tbh;
- bznr[0]=tmp;
-}
-
-#define get_imap_zone(sb, bit_nr, not_que) \
- get__map_zone((sb), (sb)->u.xiafs_sb.s_imap_buf, \
- (sb)->u.xiafs_sb.s_imap_iznr, \
- (sb)->u.xiafs_sb.s_imap_cached, 1, \
- (sb)->u.xiafs_sb.s_imap_zones, _XIAFS_IMAP_SLOTS, \
- bit_nr, not_que)
-
-#define get_zmap_zone(sb, bit_nr, not_que) \
- get__map_zone((sb), (sb)->u.xiafs_sb.s_zmap_buf, \
- (sb)->u.xiafs_sb.s_zmap_zznr, \
- (sb)->u.xiafs_sb.s_zmap_cached, \
- 1+(sb)->u.xiafs_sb.s_imap_zones, \
- (sb)->u.xiafs_sb.s_zmap_zones, _XIAFS_ZMAP_SLOTS, \
- bit_nr, not_que)
-
-static struct buffer_head *
-get__map_zone(struct super_block *sb, struct buffer_head * bmap_buf[],
- int bznr[], u_char cache, int first_zone,
- int bmap_zones, int slots, u_long bit_nr, int * not_que)
-{
- struct buffer_head * tmp_bh;
- int z_nr, i;
-
- z_nr = bit_nr >> XIAFS_BITS_PER_Z_BITS(sb);
- if (z_nr >= bmap_zones) {
- printk("XIA-FS: bad inode/zone number (%s %d)\n", WHERE_ERR);
- return NULL;
- }
- if (!cache)
- return bmap_buf[z_nr];
- lock_super(sb);
- for (i=0; i < slots; i++)
- if (bznr[i]==z_nr)
- break;
- if (i < slots) { /* cache hit */
- if (not_que) {
- *not_que=i;
- return bmap_buf[i];
- } else {
- que(bmap_buf, bznr, i);
- return bmap_buf[0];
- }
- }
- tmp_bh=bread(sb->s_dev, z_nr+first_zone, XIAFS_ZSIZE(sb)); /* cache not hit */
- if (!tmp_bh) {
- printk("XIA-FS: read bitmap failed (%s %d)\n", WHERE_ERR);
- unlock_super(sb);
- return NULL;
- }
- brelse(bmap_buf[slots-1]);
- bmap_buf[slots-1]=tmp_bh;
- bznr[slots-1]=z_nr;
- if (not_que)
- *not_que=slots-1;
- else
- que(bmap_buf, bznr, slots-1);
- return tmp_bh;
-}
-
-#define xiafs_unlock_super(sb, cache) if (cache) unlock_super(sb);
-
-#define get_free_ibit(sb, prev_bit) \
- get_free__bit(sb, sb->u.xiafs_sb.s_imap_buf, \
- sb->u.xiafs_sb.s_imap_iznr, \
- sb->u.xiafs_sb.s_imap_cached, \
- 1, sb->u.xiafs_sb.s_imap_zones, \
- _XIAFS_IMAP_SLOTS, prev_bit);
-
-#define get_free_zbit(sb, prev_bit) \
- get_free__bit(sb, sb->u.xiafs_sb.s_zmap_buf, \
- sb->u.xiafs_sb.s_zmap_zznr, \
- sb->u.xiafs_sb.s_zmap_cached, \
- 1 + sb->u.xiafs_sb.s_imap_zones, \
- sb->u.xiafs_sb.s_zmap_zones, \
- _XIAFS_ZMAP_SLOTS, prev_bit);
-
-static u_long
-get_free__bit(struct super_block *sb, struct buffer_head * bmap_buf[],
- int bznr[], u_char cache, int first_zone, int bmap_zones,
- int slots, u_long prev_bit)
-{
- struct buffer_head * bh;
- int not_done=0;
- u_long pos, start_bit, end_bit, total_bits;
- int z_nr, tmp;
-
- total_bits=bmap_zones << XIAFS_BITS_PER_Z_BITS(sb);
- if (prev_bit >= total_bits)
- prev_bit=0;
- pos=prev_bit+1;
- end_bit=XIAFS_BITS_PER_Z(sb);
-
- do {
- if (pos >= total_bits)
- pos=0;
- if (!not_done) { /* first time */
- not_done=1;
- start_bit= pos & (end_bit-1);
- } else
- start_bit=0;
- if ( pos < prev_bit && pos+end_bit >= prev_bit) { /* last time */
- not_done=0;
- end_bit=prev_bit & (end_bit-1); /* only here end_bit modified */
- }
- bh = get__map_zone(sb, bmap_buf, bznr, cache, first_zone,
- bmap_zones, slots, pos, &z_nr);
- if (!bh)
- return 0;
- tmp=find_first_zero(bh, start_bit, end_bit);
- if (tmp >= 0)
- break;
- xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
- pos=(pos & ~(end_bit-1))+end_bit;
- } while (not_done);
-
- if (tmp < 0)
- return 0;
- if (cache)
- que(bmap_buf, bznr, z_nr);
- xiafs_unlock_super(sb, cache);
- return (pos & ~(XIAFS_BITS_PER_Z(sb)-1))+tmp;
-}
-
-void xiafs_free_zone(struct super_block * sb, int d_addr)
-{
- struct buffer_head * bh;
- unsigned int bit, offset;
-
- if (!sb) {
- printk(INTERN_ERR);
- return;
- }
- if (d_addr < sb->u.xiafs_sb.s_firstdatazone ||
- d_addr >= sb->u.xiafs_sb.s_nzones) {
- printk("XIA-FS: bad zone number (%s %d)\n", WHERE_ERR);
- return;
- }
- bh = get_hash_table(sb->s_dev, d_addr, XIAFS_ZSIZE(sb));
- if (bh)
- mark_buffer_clean(bh);
- brelse(bh);
- bit=d_addr - sb->u.xiafs_sb.s_firstdatazone + 1;
- bh = get_zmap_zone(sb, bit, NULL);
- if (!bh)
- return;
- offset = bit & (XIAFS_BITS_PER_Z(sb) -1);
- if (!clear_bit(offset, bh->b_data))
- printk("XIA-FS: dev %s"
- " block bit %u (0x%x) already cleared (%s %d)\n",
- kdevname(sb->s_dev), bit, bit, WHERE_ERR);
- mark_buffer_dirty(bh, 1);
- xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
-}
-
-int xiafs_new_zone(struct super_block * sb, u_long prev_addr)
-{
- struct buffer_head * bh;
- int prev_znr, tmp;
-
- if (!sb) {
- printk(INTERN_ERR);
- return 0;
- }
- if (prev_addr < sb->u.xiafs_sb.s_firstdatazone ||
- prev_addr >= sb->u.xiafs_sb.s_nzones) {
- prev_addr=sb->u.xiafs_sb.s_firstdatazone;
- }
- prev_znr=prev_addr-sb->u.xiafs_sb.s_firstdatazone+1;
- tmp=get_free_zbit(sb, prev_znr);
- if (!tmp)
- return 0;
- tmp += sb->u.xiafs_sb.s_firstdatazone -1;
- if (!(bh = getblk(sb->s_dev, tmp, XIAFS_ZSIZE(sb)))) {
- printk("XIA-FS: I/O error (%s %d)\n", WHERE_ERR);
- return 0;
- }
- if (bh->b_count != 1) {
- printk(INTERN_ERR);
- return 0;
- }
- clear_buf(bh);
- mark_buffer_uptodate(bh, 1);
- mark_buffer_dirty(bh, 1);
- brelse(bh);
- return tmp;
-}
-
-void xiafs_free_inode(struct inode * inode)
-{
- struct buffer_head * bh;
- struct super_block * sb;
- unsigned long ino;
-
- if (!inode)
- return;
- if (!inode->i_dev || inode->i_count!=1
- || inode->i_nlink || !inode->i_sb || inode->i_ino < 3
- || inode->i_ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
- printk("XIA-FS: bad inode (%s %d)\n", WHERE_ERR);
- return;
- }
- sb = inode->i_sb;
- ino = inode->i_ino;
- bh = get_imap_zone(sb, ino, NULL);
- if (!bh)
- return;
- clear_inode(inode);
- if (!clear_bit(ino & (XIAFS_BITS_PER_Z(sb)-1), bh->b_data))
- printk("XIA-FS: dev %s"
- "inode bit %ld (0x%lx) already cleared (%s %d)\n",
- kdevname(inode->i_dev), ino, ino, WHERE_ERR);
- mark_buffer_dirty(bh, 1);
- xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached);
-}
-
-struct inode * xiafs_new_inode(struct inode * dir)
-{
- struct super_block * sb;
- struct inode * inode;
- ino_t tmp;
-
- sb = dir->i_sb;
- if (!dir || !(inode = get_empty_inode()))
- return NULL;
- inode->i_sb = sb;
- inode->i_flags = inode->i_sb->s_flags;
-
- tmp=get_free_ibit(sb, dir->i_ino);
- if (!tmp) {
- iput(inode);
- return NULL;
- }
- inode->i_count = 1;
- inode->i_nlink = 1;
- inode->i_dev = sb->s_dev;
- inode->i_uid = current->fsuid;
- inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
- inode->i_dirt = 1;
- inode->i_ino = tmp;
- inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
- inode->i_op = NULL;
- inode->i_blocks = 0;
- inode->i_blksize = XIAFS_ZSIZE(inode->i_sb);
- insert_inode_hash(inode);
- return inode;
-}
-
-static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
-
-static u_long count_zone(struct buffer_head * bh)
-{
- int i, tmp;
- u_long sum;
-
- sum=0;
- for (i=bh->b_size; i-- > 0; ) {
- tmp=bh->b_data[i];
- sum += nibblemap[tmp & 0xf] + nibblemap[(tmp & 0xff) >> 4];
- }
- return sum;
-}
-
-unsigned long xiafs_count_free_inodes(struct super_block *sb)
-{
- struct buffer_head * bh;
- int izones, i, not_que;
- u_long sum;
-
- sum=0;
- izones=sb->u.xiafs_sb.s_imap_zones;
- for (i=0; i < izones; i++) {
- bh=get_imap_zone(sb, i << XIAFS_BITS_PER_Z_BITS(sb), &not_que);
- if (bh) {
- sum += count_zone(bh);
- xiafs_unlock_super(sb, sb->u.xiafs_sb.s_imap_cached);
- }
- }
- i=izones << XIAFS_BITS_PER_Z_BITS(sb);
- return i - sum;
-}
-
-unsigned long xiafs_count_free_zones(struct super_block *sb)
-{
- struct buffer_head * bh;
- int zzones, i, not_que;
- u_long sum;
-
- sum=0;
- zzones=sb->u.xiafs_sb.s_zmap_zones;
- for (i=0; i < zzones; i++) {
- bh=get_zmap_zone(sb, i << XIAFS_BITS_PER_Z_BITS(sb), &not_que);
- if (bh) {
- sum += count_zone(bh);
- xiafs_unlock_super(sb, sb->u.xiafs_sb.s_zmap_cached);
- }
- }
- i=zzones << XIAFS_BITS_PER_Z_BITS(sb);
- return i - sum;
-}
diff --git a/fs/xiafs/dir.c b/fs/xiafs/dir.c
deleted file mode 100644
index 856d3cdcd..000000000
--- a/fs/xiafs/dir.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * linux/fs/xiafs/dir.c
- *
- * Copyright (C) Q. Frank Xia, 1993.
- *
- * Based on Linus' minix/dir.c
- * Copyright (C) Linus Torvalds, 1991, 1992.
- *
- * This software may be redistributed per Linux Copyright.
- */
-
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/xia_fs.h>
-#include <linux/stat.h>
-
-#include <asm/uaccess.h>
-
-#include "xiafs_mac.h"
-
-static long xiafs_dir_read(struct inode *, struct file *, char *, unsigned long);
-static int xiafs_readdir(struct inode *, struct file *, void *, filldir_t);
-
-static struct file_operations xiafs_dir_operations = {
- NULL, /* lseek - default */
- xiafs_dir_read, /* read */
- NULL, /* write - bad */
- xiafs_readdir, /* readdir */
- NULL, /* select - default */
- NULL, /* ioctl - default */
- NULL, /* mmap */
- NULL, /* no special open code */
- NULL, /* no special release code */
- file_fsync /* default fsync */
-};
-
-/*
- * directories can handle most operations...
- */
-struct inode_operations xiafs_dir_inode_operations = {
- &xiafs_dir_operations, /* default directory file-ops */
- xiafs_create, /* create */
- xiafs_lookup, /* lookup */
- xiafs_link, /* link */
- xiafs_unlink, /* unlink */
- xiafs_symlink, /* symlink */
- xiafs_mkdir, /* mkdir */
- xiafs_rmdir, /* rmdir */
- xiafs_mknod, /* mknod */
- xiafs_rename, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* bmap */
- xiafs_truncate, /* truncate */
- NULL /* permission */
-};
-
-static long xiafs_dir_read(struct inode * inode, struct file * filp,
- char * buf, unsigned long count)
-{
- return -EISDIR;
-}
-
-static int xiafs_readdir(struct inode * inode, struct file * filp,
- void * dirent, filldir_t filldir)
-{
- u_int offset, i;
- struct buffer_head * bh;
- struct xiafs_direct * de;
-
- if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode))
- return -EBADF;
- if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb) - 1) )
- return -EBADF;
- while (filp->f_pos < inode->i_size) {
- offset = filp->f_pos & (XIAFS_ZSIZE(inode->i_sb) - 1);
- bh = xiafs_bread(inode, filp->f_pos >> XIAFS_ZSIZE_BITS(inode->i_sb),0);
- if (!bh) {
- filp->f_pos += XIAFS_ZSIZE(inode->i_sb)-offset;
- continue;
- }
- for (i = 0; i < XIAFS_ZSIZE(inode->i_sb) && i < offset; ) {
- de = (struct xiafs_direct *) (bh->b_data + i);
- if (!de->d_rec_len)
- break;
- i += de->d_rec_len;
- }
- offset = i;
- de = (struct xiafs_direct *) (offset + bh->b_data);
-
- while (offset < XIAFS_ZSIZE(inode->i_sb) && filp->f_pos < inode->i_size) {
- if (de->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes ||
- de->d_rec_len < 12 ||
- (char *)de+de->d_rec_len > XIAFS_ZSIZE(inode->i_sb)+bh->b_data ||
- de->d_name_len < 1 || de->d_name_len + 8 > de->d_rec_len ||
- de->d_name_len > _XIAFS_NAME_LEN ||
- de->d_name[de->d_name_len] ) {
- printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR);
- brelse(bh);
- return 0;
- }
- if (de->d_ino) {
- if (!IS_RDONLY (inode)) {
- inode->i_atime=CURRENT_TIME;
- inode->i_dirt=1;
- }
- if (filldir(dirent, de->d_name, de->d_name_len, filp->f_pos, de->d_ino) < 0) {
- brelse(bh);
- return 0;
- }
- }
- offset += de->d_rec_len;
- filp->f_pos += de->d_rec_len;
- de = (struct xiafs_direct *) (offset + bh->b_data);
- }
- brelse(bh);
- if (offset > XIAFS_ZSIZE(inode->i_sb)) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- return 0;
- }
- }
- if (!IS_RDONLY (inode)) {
- inode->i_atime=CURRENT_TIME;
- inode->i_dirt=1;
- }
- return 0;
-}
diff --git a/fs/xiafs/file.c b/fs/xiafs/file.c
deleted file mode 100644
index 822b4b520..000000000
--- a/fs/xiafs/file.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * linux/fs/xiafs/file.c
- *
- * Copyright (C) Q. Frank Xia, 1993.
- *
- * Based on Linus' minix/file.c
- * Copyright (C) Linus Torvalds, 1991, 1992.
- *
- * This software may be redistributed per Linux Copyright.
- */
-
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/xia_fs.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/locks.h>
-#include <linux/pagemap.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include "xiafs_mac.h"
-
-#define NBUF 32
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-static long xiafs_file_read(struct inode *, struct file *, char *, unsigned long);
-static long xiafs_file_write(struct inode *, struct file *, const char *, unsigned long);
-
-/*
- * We have mostly NULL's here: the current defaults are ok for
- * the xiafs filesystem.
- */
-static struct file_operations xiafs_file_operations = {
- NULL, /* lseek - default */
- xiafs_file_read, /* read */
- xiafs_file_write, /* write */
- NULL, /* readdir - bad */
- NULL, /* select - default */
- NULL, /* ioctl - default */
- generic_file_mmap, /* mmap */
- NULL, /* no special open is needed */
- NULL, /* release */
- xiafs_sync_file /* fsync */
-};
-
-struct inode_operations xiafs_file_inode_operations = {
- &xiafs_file_operations, /* default file operations */
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- generic_readpage, /* readpage */
- NULL, /* writepage */
- xiafs_bmap, /* bmap */
- xiafs_truncate, /* truncate */
- NULL /* permission */
-};
-
-static long
-xiafs_file_read(struct inode * inode, struct file * filp, char * buf, unsigned long count)
-{
- int read, left, chars;
- int zone_nr, zones, f_zones, offset;
- int bhrequest, uptodate;
- struct buffer_head ** bhb, ** bhe;
- struct buffer_head * bhreq[NBUF];
- struct buffer_head * buflist[NBUF];
-
- if (!inode) {
- printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR);
- return -EINVAL;
- }
- if (!S_ISREG(inode->i_mode)) {
- printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR);
- return -EINVAL;
- }
- offset = filp->f_pos;
- left = inode->i_size - offset;
- if (left > count)
- left = count;
- if (left <= 0)
- return 0;
- read = 0;
- zone_nr = offset >> XIAFS_ZSIZE_BITS(inode->i_sb);
- offset &= XIAFS_ZSIZE(inode->i_sb) -1 ;
- f_zones =(inode->i_size+XIAFS_ZSIZE(inode->i_sb)-1)>>XIAFS_ZSIZE_BITS(inode->i_sb);
- zones = (left+offset+XIAFS_ZSIZE(inode->i_sb)-1) >> XIAFS_ZSIZE_BITS(inode->i_sb);
- bhb = bhe = buflist;
- if (filp->f_reada) {
- if(zones < read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb)))
- zones = read_ahead[MAJOR(inode->i_dev)] >> (1+XIAFS_ZSHIFT(inode->i_sb));
- if (zone_nr + zones > f_zones)
- zones = f_zones - zone_nr;
- }
-
- /* 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 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.
-
- This routine is optimized to make maximum use of the various
- buffers and caches. */
-
- do {
- bhrequest = 0;
- uptodate = 1;
- while (zones--) {
- *bhb = xiafs_getblk(inode, zone_nr++, 0);
- if (*bhb && !buffer_uptodate(*bhb)) {
- uptodate = 0;
- bhreq[bhrequest++] = *bhb;
- }
-
- if (++bhb == &buflist[NBUF])
- bhb = buflist;
-
- /* If the block we have on hand is uptodate, go ahead
- and complete processing. */
- if (uptodate)
- break;
- if (bhb == bhe)
- break;
- }
-
- /* Now request them all */
- if (bhrequest)
- ll_rw_block(READ, bhrequest, bhreq);
-
- do { /* Finish off all I/O that has actually completed */
- if (*bhe) {
- wait_on_buffer(*bhe);
- if (!buffer_uptodate(*bhe)) { /* read error? */
- brelse(*bhe);
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- left = 0;
- break;
- }
- }
- if (left < XIAFS_ZSIZE(inode->i_sb) - offset)
- chars = left;
- else
- chars = XIAFS_ZSIZE(inode->i_sb) - offset;
- filp->f_pos += chars;
- left -= chars;
- read += chars;
- if (*bhe) {
- copy_to_user(buf,offset+(*bhe)->b_data,chars);
- brelse(*bhe);
- buf += chars;
- } else {
- while (chars-->0)
- put_user(0,buf++);
- }
- offset = 0;
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
- } while (left > 0);
-
-/* Release the read-ahead blocks */
- while (bhe != bhb) {
- brelse(*bhe);
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- };
- if (!read)
- return -EIO;
- filp->f_reada = 1;
- if (!IS_RDONLY (inode)) {
- inode->i_atime = CURRENT_TIME;
- inode->i_dirt = 1;
- }
- return read;
-}
-
-static long
-xiafs_file_write(struct inode * inode, struct file * filp, const char * buf, unsigned long count)
-{
- off_t pos;
- int written, c;
- struct buffer_head * bh;
- char * cp;
-
- if (!inode) {
- printk("XIA-FS: inode = NULL (%s %d)\n", WHERE_ERR);
- return -EINVAL;
- }
- if (!S_ISREG(inode->i_mode)) {
- printk("XIA-FS: mode != regular (%s %d)\n", WHERE_ERR);
- return -EINVAL;
- }
-/*
- * ok, append may not work when many processes are writing at the same time
- * but so what. That way leads to madness anyway.
- */
- if (filp->f_flags & O_APPEND)
- pos = inode->i_size;
- else
- pos = filp->f_pos;
- written = 0;
- while (written < count) {
- bh = xiafs_getblk(inode, pos >> XIAFS_ZSIZE_BITS(inode->i_sb), 1);
- if (!bh) {
- if (!written)
- written = -ENOSPC;
- break;
- }
- c = XIAFS_ZSIZE(inode->i_sb) - (pos & (XIAFS_ZSIZE(inode->i_sb) - 1));
- if (c > count-written)
- c = count-written;
- if (c != XIAFS_ZSIZE(inode->i_sb) && !buffer_uptodate(bh)) {
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- if (!buffer_uptodate(bh)) {
- brelse(bh);
- if (!written)
- written = -EIO;
- break;
- }
- }
- cp = (pos & (XIAFS_ZSIZE(inode->i_sb)-1)) + bh->b_data;
- copy_from_user(cp,buf,c);
- update_vm_cache(inode,pos,cp,c);
- pos += c;
- if (pos > inode->i_size) {
- inode->i_size = pos;
- inode->i_dirt = 1;
- }
- written += c;
- buf += c;
- mark_buffer_uptodate(bh, 1);
- mark_buffer_dirty(bh, 0);
- brelse(bh);
- }
- inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- filp->f_pos = pos;
- inode->i_dirt = 1;
-
- return written;
-}
diff --git a/fs/xiafs/fsync.c b/fs/xiafs/fsync.c
deleted file mode 100644
index f491e3d8e..000000000
--- a/fs/xiafs/fsync.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * linux/fs/xiafs/fsync.c
- *
- * Changes Copyright (C) 1993 Stephen Tweedie (sct@dcs.ed.ac.uk)
- * from
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * xiafs fsync primitive
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/locks.h>
-
-#include <linux/fs.h>
-#include <linux/xia_fs.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include "xiafs_mac.h"
-
-
-#define blocksize (XIAFS_ZSIZE(inode->i_sb))
-#define addr_per_block (XIAFS_ADDRS_PER_Z(inode->i_sb))
-
-static int sync_block (struct inode * inode, unsigned long * block, int wait)
-{
- struct buffer_head * bh;
- int tmp;
-
- if (!*block)
- return 0;
- tmp = *block;
- bh = get_hash_table(inode->i_dev, *block, blocksize);
- if (!bh)
- return 0;
- if (*block != tmp) {
- brelse (bh);
- return 1;
- }
- if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
- brelse(bh);
- return -1;
- }
- if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
- {
- brelse(bh);
- return 0;
- }
- ll_rw_block(WRITE, 1, &bh);
- bh->b_count--;
- return 0;
-}
-
-static int sync_iblock (struct inode * inode, unsigned long * iblock,
- struct buffer_head **bh, int wait)
-{
- int rc, tmp;
-
- *bh = NULL;
- tmp = *iblock;
- if (!tmp)
- return 0;
- rc = sync_block (inode, iblock, wait);
- if (rc)
- return rc;
- *bh = bread(inode->i_dev, tmp, blocksize);
- if (tmp != *iblock) {
- brelse(*bh);
- *bh = NULL;
- return 1;
- }
- if (!*bh)
- return -1;
- return 0;
-}
-
-
-static int sync_direct(struct inode *inode, int wait)
-{
- int i;
- int rc, err = 0;
-
- for (i = 0; i < 8; i++) {
- rc = sync_block (inode, inode->u.ext_i.i_data + i, wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- return err;
-}
-
-static int sync_indirect(struct inode *inode, unsigned long *iblock, int wait)
-{
- int i;
- struct buffer_head * ind_bh;
- int rc, err = 0;
-
- rc = sync_iblock (inode, iblock, &ind_bh, wait);
- if (rc || !ind_bh)
- return rc;
-
- for (i = 0; i < addr_per_block; i++) {
- rc = sync_block (inode,
- ((unsigned long *) ind_bh->b_data) + i,
- wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- brelse(ind_bh);
- return err;
-}
-
-static int sync_dindirect(struct inode *inode, unsigned long *diblock,
- int wait)
-{
- int i;
- struct buffer_head * dind_bh;
- int rc, err = 0;
-
- rc = sync_iblock (inode, diblock, &dind_bh, wait);
- if (rc || !dind_bh)
- return rc;
-
- for (i = 0; i < addr_per_block; i++) {
- rc = sync_indirect (inode,
- ((unsigned long *) dind_bh->b_data) + i,
- wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- brelse(dind_bh);
- return err;
-}
-
-int xiafs_sync_file(struct inode * inode, struct file * file)
-{
- int wait, err = 0;
-
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))
- return -EINVAL;
- for (wait=0; wait<=1; wait++)
- {
- err |= sync_direct(inode, wait);
- err |= sync_indirect(inode, &inode->u.xiafs_i.i_ind_zone, wait);
- err |= sync_dindirect(inode, &inode->u.xiafs_i.i_dind_zone, wait);
- }
- err |= xiafs_sync_inode (inode);
- return (err < 0) ? -EIO : 0;
-}
diff --git a/fs/xiafs/inode.c b/fs/xiafs/inode.c
deleted file mode 100644
index 48b31e972..000000000
--- a/fs/xiafs/inode.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * linux/fs/xiafs/inode.c
- *
- * Copyright (C) Q. Frank Xia, 1993.
- *
- * Based on Linus' minix/inode.c
- * Copyright (C) Linus Torvalds, 1991, 1992.
- *
- * This software may be redistributed per Linux Copyright.
- */
-
-#include <linux/module.h>
-
-#include <linux/sched.h>
-#include <linux/xia_fs.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/locks.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include "xiafs_mac.h"
-
-static u_long random_nr;
-
-void xiafs_put_inode(struct inode *inode)
-{
- if (inode->i_nlink)
- return;
- inode->i_size = 0;
- xiafs_truncate(inode);
- xiafs_free_inode(inode);
-}
-
-void xiafs_put_super(struct super_block *sb)
-{
- int i;
-
- lock_super(sb);
- sb->s_dev = 0;
- for(i = 0 ; i < _XIAFS_IMAP_SLOTS ; i++)
- brelse(sb->u.xiafs_sb.s_imap_buf[i]);
- for(i = 0 ; i < _XIAFS_ZMAP_SLOTS ; i++)
- brelse(sb->u.xiafs_sb.s_zmap_buf[i]);
- unlock_super(sb);
- MOD_DEC_USE_COUNT;
-}
-
-static struct super_operations xiafs_sops = {
- xiafs_read_inode,
- NULL,
- xiafs_write_inode,
- xiafs_put_inode,
- xiafs_put_super,
- NULL,
- xiafs_statfs,
- NULL
-};
-
-struct super_block *xiafs_read_super(struct super_block *s, void *data,
- int silent)
-{
- struct buffer_head *bh;
- struct xiafs_super_block *sp;
- int i, z;
- kdev_t dev;
-
- MOD_INC_USE_COUNT;
- dev = s->s_dev;
- lock_super(s);
-
- set_blocksize(dev, BLOCK_SIZE);
-
- if (!(bh = bread(dev, 0, BLOCK_SIZE))) {
- s->s_dev = 0;
- unlock_super(s);
- printk("XIA-FS: read super_block failed (%s %d)\n", WHERE_ERR);
- MOD_DEC_USE_COUNT;
- return NULL;
- }
- sp = (struct xiafs_super_block *) bh->b_data;
- s->s_magic = sp->s_magic;
- if (s->s_magic != _XIAFS_SUPER_MAGIC) {
- s->s_dev = 0;
- unlock_super(s);
- brelse(bh);
- if (!silent)
- printk("VFS: Can't find a xiafs filesystem on dev "
- "%s.\n", kdevname(dev));
- MOD_DEC_USE_COUNT;
- return NULL;
- }
- s->s_blocksize = sp->s_zone_size;
- s->s_blocksize_bits = 10 + sp->s_zone_shift;
- if (s->s_blocksize != BLOCK_SIZE &&
- (s->s_blocksize == 1024 || s->s_blocksize == 2048 ||
- s->s_blocksize == 4096)) {
- brelse(bh);
- set_blocksize(dev, s->s_blocksize);
- bh = bread (dev, 0, s->s_blocksize);
- if(!bh) {
- MOD_DEC_USE_COUNT;
- return NULL;
- }
- sp = (struct xiafs_super_block *) (((char *)bh->b_data) + BLOCK_SIZE) ;
- };
- s->u.xiafs_sb.s_nzones = sp->s_nzones;
- s->u.xiafs_sb.s_ninodes = sp->s_ninodes;
- s->u.xiafs_sb.s_ndatazones = sp->s_ndatazones;
- s->u.xiafs_sb.s_imap_zones = sp->s_imap_zones;
- s->u.xiafs_sb.s_zmap_zones = sp->s_zmap_zones;
- s->u.xiafs_sb.s_firstdatazone = sp->s_firstdatazone;
- s->u.xiafs_sb.s_zone_shift = sp->s_zone_shift;
- s->u.xiafs_sb.s_max_size = sp->s_max_size;
- brelse(bh);
- for (i=0;i < _XIAFS_IMAP_SLOTS;i++) {
- s->u.xiafs_sb.s_imap_buf[i] = NULL;
- s->u.xiafs_sb.s_imap_iznr[i] = -1;
- }
- for (i=0;i < _XIAFS_ZMAP_SLOTS;i++) {
- s->u.xiafs_sb.s_zmap_buf[i] = NULL;
- s->u.xiafs_sb.s_zmap_zznr[i] = -1;
- }
- z=1;
- if ( s->u.xiafs_sb.s_imap_zones > _XIAFS_IMAP_SLOTS )
- s->u.xiafs_sb.s_imap_cached=1;
- else {
- s->u.xiafs_sb.s_imap_cached=0;
- for (i=0 ; i < s->u.xiafs_sb.s_imap_zones ; i++) {
- if (!(s->u.xiafs_sb.s_imap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s))))
- goto xiafs_read_super_fail;
- s->u.xiafs_sb.s_imap_iznr[i]=i;
- }
- }
- if ( s->u.xiafs_sb.s_zmap_zones > _XIAFS_ZMAP_SLOTS )
- s->u.xiafs_sb.s_zmap_cached=1;
- else {
- s->u.xiafs_sb.s_zmap_cached=0;
- for (i=0 ; i < s->u.xiafs_sb.s_zmap_zones ; i++) {
- if (!(s->u.xiafs_sb.s_zmap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s))))
- goto xiafs_read_super_fail;
- s->u.xiafs_sb.s_zmap_zznr[i]=i;
- }
- }
- /* set up enough so that it can read an inode */
- s->s_dev = dev;
- s->s_op = &xiafs_sops;
- s->s_mounted = iget(s, _XIAFS_ROOT_INO);
- if (!s->s_mounted)
- goto xiafs_read_super_fail;
- unlock_super(s);
- random_nr=CURRENT_TIME;
- return s;
-
-xiafs_read_super_fail:
- for(i=0; i < _XIAFS_IMAP_SLOTS; i++)
- brelse(s->u.xiafs_sb.s_imap_buf[i]);
- for(i=0; i < _XIAFS_ZMAP_SLOTS; i++)
- brelse(s->u.xiafs_sb.s_zmap_buf[i]);
- s->s_dev = 0;
- unlock_super(s);
- printk("XIA-FS: read bitmaps failed (%s %d)\n", WHERE_ERR);
- MOD_DEC_USE_COUNT;
- return NULL;
-}
-
-void xiafs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
-{
- struct statfs tmp;
-
- tmp.f_type = _XIAFS_SUPER_MAGIC;
- tmp.f_bsize = XIAFS_ZSIZE(sb);
- tmp.f_blocks = sb->u.xiafs_sb.s_ndatazones;
- tmp.f_bfree = xiafs_count_free_zones(sb);
- tmp.f_bavail = tmp.f_bfree;
- tmp.f_files = sb->u.xiafs_sb.s_ninodes;
- tmp.f_ffree = xiafs_count_free_inodes(sb);
- tmp.f_namelen = _XIAFS_NAME_LEN;
- copy_to_user(buf, &tmp, bufsiz);
-}
-
-static int zone_bmap(struct buffer_head * bh, int nr)
-{
- int tmp;
-
- if (!bh)
- return 0;
- tmp = ((u_long *) bh->b_data)[nr];
- brelse(bh);
- return tmp;
-}
-
-int xiafs_bmap(struct inode * inode,int zone)
-{
- int i;
-
- if (zone < 0) {
- printk("XIA-FS: block < 0 (%s %d)\n", WHERE_ERR);
- return 0;
- }
- if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
- printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
- return 0;
- }
- if (!IS_RDONLY (inode)) {
- inode->i_atime = CURRENT_TIME;
- inode->i_dirt = 1;
- }
- if (zone < 8)
- return inode->u.xiafs_i.i_zone[zone];
- zone -= 8;
- if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
- i = inode->u.xiafs_i.i_ind_zone;
- if (i)
- i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)), zone);
- return i;
- }
- zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
- i = inode->u.xiafs_i.i_dind_zone;
- if (i)
- i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)),
- zone >> XIAFS_ADDRS_PER_Z_BITS(inode->i_sb));
- if (i)
- i= zone_bmap(bread(inode->i_dev,i, XIAFS_ZSIZE(inode->i_sb)),
- zone & (XIAFS_ADDRS_PER_Z(inode->i_sb)-1));
- return i;
-}
-
-static u_long get_prev_addr(struct inode * inode, int zone)
-{
- u_long tmp;
-
- if (zone > 0)
- while (--zone >= 0) /* only files with holes suffer */
- if ((tmp=xiafs_bmap(inode, zone)))
- return tmp;
- random_nr=(random_nr+23)%inode->i_sb->u.xiafs_sb.s_ndatazones;
- return random_nr + inode->i_sb->u.xiafs_sb.s_firstdatazone;
-}
-
-static struct buffer_head *
-dt_getblk(struct inode * inode, u_long *lp, int create, u_long prev_addr)
-{
- int tmp;
- struct buffer_head * result;
-
-repeat:
- if ((tmp=*lp)) {
- result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (tmp == *lp)
- return result;
- brelse(result);
- goto repeat;
- }
- if (!create)
- return NULL;
- tmp = xiafs_new_zone(inode->i_sb, prev_addr);
- if (!tmp)
- return NULL;
- result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (*lp) {
- xiafs_free_zone(inode->i_sb, tmp);
- brelse(result);
- goto repeat;
- }
- *lp = tmp;
- inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
- return result;
-}
-
-static struct buffer_head *
-indt_getblk(struct inode * inode, struct buffer_head * bh,
- int nr, int create, u_long prev_addr)
-{
- int tmp;
- u_long *lp;
- struct buffer_head * result;
-
- if (!bh)
- return NULL;
- if (!buffer_uptodate(bh)) {
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- if (!buffer_uptodate(bh)) {
- brelse(bh);
- return NULL;
- }
- }
- lp = nr + (u_long *) bh->b_data;
-repeat:
- if ((tmp=*lp)) {
- result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (tmp == *lp) {
- brelse(bh);
- return result;
- }
- brelse(result);
- goto repeat;
- }
- if (!create) {
- brelse(bh);
- return NULL;
- }
- tmp = xiafs_new_zone(inode->i_sb, prev_addr);
- if (!tmp) {
- brelse(bh);
- return NULL;
- }
- result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (*lp) {
- xiafs_free_zone(inode->i_sb, tmp);
- brelse(result);
- goto repeat;
- }
- *lp = tmp;
- inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
- mark_buffer_dirty(bh, 1);
- brelse(bh);
- return result;
-}
-
-struct buffer_head * xiafs_getblk(struct inode * inode, int zone, int create)
-{
- struct buffer_head * bh;
- u_long prev_addr=0;
-
- if (zone<0) {
- printk("XIA-FS: zone < 0 (%s %d)\n", WHERE_ERR);
- return NULL;
- }
- if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
- if (!create)
- printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
- return NULL;
- }
- if (create)
- prev_addr=get_prev_addr(inode, zone);
- if (zone < 8)
- return dt_getblk(inode, zone+inode->u.xiafs_i.i_zone, create, prev_addr);
- zone -= 8;
- if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
- bh = dt_getblk(inode, &(inode->u.xiafs_i.i_ind_zone), create, prev_addr);
- bh = indt_getblk(inode, bh, zone, create, prev_addr);
- return bh;
- }
- zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
- bh = dt_getblk(inode, &(inode->u.xiafs_i.i_dind_zone), create, prev_addr);
- bh = indt_getblk(inode, bh, zone>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb),
- create, prev_addr);
- bh = indt_getblk(inode, bh, zone&(XIAFS_ADDRS_PER_Z(inode->i_sb)-1),
- create, prev_addr);
- return bh;
-}
-
-struct buffer_head * xiafs_bread(struct inode * inode, int zone, int create)
-{
- struct buffer_head * bh;
-
- bh = xiafs_getblk(inode, zone, create);
- if (!bh || buffer_uptodate(bh))
- return bh;
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- if (buffer_uptodate(bh))
- return bh;
- brelse(bh);
- return NULL;
-}
-
-void xiafs_read_inode(struct inode * inode)
-{
- struct buffer_head * bh;
- struct xiafs_inode * raw_inode;
- int zone;
- ino_t ino;
-
- ino = inode->i_ino;
- inode->i_op = NULL;
- inode->i_mode=0;
- if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
- printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
- return;
- }
- zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
- inode->i_sb->u.xiafs_sb.s_zmap_zones +
- (ino-1)/ XIAFS_INODES_PER_Z(inode->i_sb);
- if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
- printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
- return;
- }
- raw_inode = ((struct xiafs_inode *) bh->b_data) +
- ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) - 1));
- inode->i_mode = raw_inode->i_mode;
- inode->i_uid = raw_inode->i_uid;
- inode->i_gid = raw_inode->i_gid;
- inode->i_nlink = raw_inode->i_nlinks;
- inode->i_size = raw_inode->i_size;
- inode->i_mtime = raw_inode->i_mtime;
- inode->i_atime = raw_inode->i_atime;
- inode->i_ctime = raw_inode->i_ctime;
- inode->i_blksize = XIAFS_ZSIZE(inode->i_sb);
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
- inode->i_blocks=0;
- inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]);
- } else {
- XIAFS_GET_BLOCKS(raw_inode, inode->i_blocks);
- for (zone = 0; zone < 8; zone++)
- inode->u.xiafs_i.i_zone[zone] = raw_inode->i_zone[zone] & 0xffffff;
- inode->u.xiafs_i.i_ind_zone = raw_inode->i_ind_zone & 0xffffff;
- inode->u.xiafs_i.i_dind_zone = raw_inode->i_dind_zone & 0xffffff;
- }
- brelse(bh);
- if (S_ISREG(inode->i_mode))
- inode->i_op = &xiafs_file_inode_operations;
- else if (S_ISDIR(inode->i_mode))
- inode->i_op = &xiafs_dir_inode_operations;
- else if (S_ISLNK(inode->i_mode))
- inode->i_op = &xiafs_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);
-}
-
-static struct buffer_head * xiafs_update_inode(struct inode * inode)
-{
- struct buffer_head * bh;
- struct xiafs_inode * raw_inode;
- int zone;
- ino_t ino;
-
- if (IS_RDONLY (inode)) {
- printk("XIA-FS: write_inode on a read-only filesystem (%s %d)\n", WHERE_ERR);
- inode->i_dirt = 0;
- return 0;
- }
-
- ino = inode->i_ino;
- if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
- printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
- inode->i_dirt=0;
- return 0;
- }
- zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
- inode->i_sb->u.xiafs_sb.s_zmap_zones +
- (ino-1) / XIAFS_INODES_PER_Z(inode->i_sb);
- if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
- printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
- inode->i_dirt=0;
- return 0;
- }
- raw_inode = ((struct xiafs_inode *)bh->b_data) +
- ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) -1));
- raw_inode->i_mode = inode->i_mode;
- raw_inode->i_uid = inode->i_uid;
- raw_inode->i_gid = inode->i_gid;
- raw_inode->i_nlinks = inode->i_nlink;
- raw_inode->i_size = inode->i_size;
- raw_inode->i_atime = inode->i_atime;
- raw_inode->i_ctime = inode->i_ctime;
- raw_inode->i_mtime = inode->i_mtime;
- if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
- raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
- else {
- XIAFS_PUT_BLOCKS(raw_inode, inode->i_blocks);
- for (zone = 0; zone < 8; zone++)
- raw_inode->i_zone[zone] = (raw_inode->i_zone[zone] & 0xff000000)
- | (inode->u.xiafs_i.i_zone[zone] & 0xffffff);
- raw_inode->i_ind_zone = (raw_inode->i_ind_zone & 0xff000000)
- | (inode->u.xiafs_i.i_ind_zone & 0xffffff);
- raw_inode->i_dind_zone = (raw_inode->i_dind_zone & 0xff000000)
- | (inode->u.xiafs_i.i_dind_zone & 0xffffff);
- }
- inode->i_dirt=0;
- mark_buffer_dirty(bh, 1);
- return bh;
-}
-
-
-void xiafs_write_inode(struct inode * inode)
-{
- struct buffer_head * bh;
- bh = xiafs_update_inode(inode);
- brelse (bh);
-}
-
-int xiafs_sync_inode (struct inode *inode)
-{
- int err = 0;
- struct buffer_head *bh;
-
- bh = xiafs_update_inode(inode);
- if (bh && buffer_dirty(bh))
- {
- ll_rw_block(WRITE, 1, &bh);
- wait_on_buffer(bh);
- if (buffer_req(bh) && !buffer_uptodate(bh))
- {
- printk ("IO error syncing xiafs inode [%s:%lu]\n",
- kdevname(inode->i_dev), inode->i_ino);
- err = -1;
- }
- }
- else if (!bh)
- err = -1;
- brelse (bh);
- return err;
-}
-
-/* Every kernel module contains stuff like this. */
-
-static struct file_system_type xiafs_fs_type = {
- xiafs_read_super, "xiafs", 1, NULL
-};
-
-int init_xiafs_fs(void)
-{
- return register_filesystem(&xiafs_fs_type);
-}
-
-#ifdef MODULE
-int init_module(void)
-{
- int status;
-
- if ((status = init_xiafs_fs()) == 0)
- register_symtab(0);
- return status;
-}
-
-void cleanup_module(void)
-{
- unregister_filesystem(&xiafs_fs_type);
-}
-
-#endif
diff --git a/fs/xiafs/namei.c b/fs/xiafs/namei.c
deleted file mode 100644
index b23c4bf71..000000000
--- a/fs/xiafs/namei.c
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Linux/fs/xiafs/namei.c
- *
- * Copyright (C) Q. Frank Xia, 1993.
- *
- * Based on Linus' minix/namei.c
- * Copyright (C) Linus Torvalds, 1991, 1992.
- *
- * This software may be redistributed per Linux Copyright.
- */
-
-#include <linux/sched.h>
-#include <linux/xia_fs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
-
-#include <asm/uaccess.h>
-
-#include "xiafs_mac.h"
-
-#define RNDUP4(x) ((3+(u_long)(x)) & ~3)
-/*
- * ok, we cannot use strncmp, as the name is not in our data space.
- * Thus we'll have to use xiafs_match. No big problem. Match also makes
- * some sanity tests.
- *
- * NOTE! unlike strncmp, xiafs_match returns 1 for success, 0 for failure.
- */
-static int xiafs_match(int len, const char * name, struct xiafs_direct * dep)
-{
- int i;
-
- if (!dep || !dep->d_ino || len > _XIAFS_NAME_LEN)
- return 0;
- /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
- if (!len && (dep->d_name[0]=='.') && (dep->d_name[1]=='\0'))
- return 1;
- if (len != dep->d_name_len)
- return 0;
- for (i=0; i < len; i++)
- if (*name++ != dep->d_name[i])
- return 0;
- return 1;
-}
-
-/*
- * xiafs_find_entry()
- *
- * finds an entry in the specified directory with the wanted name. It
- * returns the cache buffer in which the entry was found, and the entry
- * itself (as a parameter - res_dir). It does NOT read the inode of the
- * entry - you'll have to do that yourself if you want to.
- */
-static struct buffer_head *
-xiafs_find_entry(struct inode * inode, const char * name, int namelen,
- struct xiafs_direct ** res_dir, struct xiafs_direct ** res_pre)
-{
- int i, zones, pos;
- struct buffer_head * bh;
- struct xiafs_direct * dep, * dep_pre;
-
- *res_dir = NULL;
- if (!inode)
- return NULL;
- if (namelen > _XIAFS_NAME_LEN)
- return NULL;
-
- if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb) - 1)) {
- printk("XIA-FS: bad dir size (%s %d)\n", WHERE_ERR);
- return NULL;
- }
- zones=inode->i_size >> XIAFS_ZSIZE_BITS(inode->i_sb);
- for (i=0; i < zones; i++ ) {
- bh = xiafs_bread(inode, i, 0);
- if (!bh)
- continue;
- dep_pre=dep=(struct xiafs_direct *)bh->b_data;
- if (!i && (dep->d_rec_len != 12 || !dep->d_ino ||
- dep->d_name_len != 1 || strcmp(dep->d_name, "."))) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- brelse(bh);
- return NULL;
- }
- pos = 0;
- while ( pos < XIAFS_ZSIZE(inode->i_sb) ) {
- if (dep->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes ||
- dep->d_rec_len < 12 ||
- dep->d_rec_len+(char *)dep > bh->b_data+XIAFS_ZSIZE(inode->i_sb) ||
- dep->d_name_len + 8 > dep->d_rec_len || dep->d_name_len <= 0 ||
- dep->d_name[dep->d_name_len] ) {
- brelse(bh);
- return NULL;
- }
- if (xiafs_match(namelen, name, dep)) {
- *res_dir=dep;
- if (res_pre)
- *res_pre=dep_pre;
- return bh;
- }
- pos += dep->d_rec_len;
- dep_pre=dep;
- dep=(struct xiafs_direct *)(bh->b_data + pos);
- }
- brelse(bh);
- if (pos > XIAFS_ZSIZE(inode->i_sb)) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- return NULL;
- }
- }
- return NULL;
-}
-
-int xiafs_lookup(struct inode * dir, const char * name, int len,
- struct inode ** result)
-{
- int ino;
- struct xiafs_direct * dep;
- struct buffer_head * bh;
-
- *result = NULL;
- if (!dir)
- return -ENOENT;
- if (!S_ISDIR(dir->i_mode)) {
- iput(dir);
- return -ENOENT;
- }
- if (!(bh = xiafs_find_entry(dir, name, len, &dep, NULL))) {
- iput(dir);
- return -ENOENT;
- }
- ino = dep->d_ino;
- brelse(bh);
- if (!(*result = iget(dir->i_sb, ino))) {
- iput(dir);
- return -EACCES;
- }
- iput(dir);
- return 0;
-}
-
-/*
- * xiafs_add_entry()
- *
- * adds a file entry to the specified directory, using the same
- * semantics as xiafs_find_entry(). It returns NULL if it failed.
- *
- * NOTE!! The inode part of 'de' is left at 0 - which means you
- * may not sleep between calling this and putting something into
- * the entry, as someone else might have used it while you slept.
- */
-static struct buffer_head * xiafs_add_entry(struct inode * dir,
- const char * name, int namelen, struct xiafs_direct ** res_dir,
- struct xiafs_direct ** res_pre)
-{
- int i, pos, offset;
- struct buffer_head * bh;
- struct xiafs_direct * de, * de_pre;
-
- *res_dir = NULL;
- if (!dir || !namelen || namelen > _XIAFS_NAME_LEN)
- return NULL;
-
- if (dir->i_size & (XIAFS_ZSIZE(dir->i_sb) - 1)) {
- printk("XIA-FS: bad dir size (%s %d)\n", WHERE_ERR);
- return NULL;
- }
- pos=0;
- for ( ; ; ) {
- bh = xiafs_bread(dir, pos >> XIAFS_ZSIZE_BITS(dir->i_sb), pos ? 1:0);
- if (!bh)
- return NULL;
- de_pre=de=(struct xiafs_direct *)bh->b_data;
- if (!pos) {
- if (de->d_rec_len != 12 || !de->d_ino || de->d_name_len != 1 ||
- strcmp(de->d_name, ".")) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- brelse(bh);
- return NULL;
- }
- offset = 12;
- de_pre=de=(struct xiafs_direct *)(bh->b_data+12);
- } else
- offset = 0;
- while (offset < XIAFS_ZSIZE(dir->i_sb)) {
- if (pos >= dir->i_size) {
- de->d_ino=0;
- de->d_name_len=0;
- de->d_name[0]=0;
- de->d_rec_len=XIAFS_ZSIZE(dir->i_sb);
- dir->i_size += XIAFS_ZSIZE(dir->i_sb);
- dir->i_dirt = 1;
- } else {
- if (de->d_ino > dir->i_sb->u.xiafs_sb.s_ninodes ||
- de->d_rec_len < 12 ||
- (char *)de+de->d_rec_len > bh->b_data+XIAFS_ZSIZE(dir->i_sb) ||
- de->d_name_len + 8 > de->d_rec_len ||
- de->d_name[de->d_name_len]) {
- printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR);
- brelse(bh);
- return NULL;
- }
- if (de->d_ino &&
- RNDUP4(de->d_name_len)+RNDUP4(namelen)+16<=de->d_rec_len) {
- i=RNDUP4(de->d_name_len)+8;
- de_pre=de;
- de=(struct xiafs_direct *)(i+(u_char *)de_pre);
- de->d_ino=0;
- de->d_rec_len=de_pre->d_rec_len-i;
- de_pre->d_rec_len=i;
- }
- }
- if (!de->d_ino && RNDUP4(namelen)+8 <= de->d_rec_len) {
- /*
- * XXX all times should be set by caller upon successful
- * completion.
- */
- dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- dir->i_dirt = 1;
- memcpy(de->d_name, name, namelen);
- de->d_name[namelen]=0;
- de->d_name_len=namelen;
- mark_buffer_dirty(bh, 1);
- *res_dir = de;
- if (res_pre)
- *res_pre = de_pre;
- return bh;
- }
- offset+=de->d_rec_len;
- de_pre=de;
- de=(struct xiafs_direct *)(bh->b_data+offset);
- }
- brelse(bh);
- if (offset > XIAFS_ZSIZE(dir->i_sb)) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- return NULL;
- }
- pos+=XIAFS_ZSIZE(dir->i_sb);
- }
- return NULL;
-}
-
-int xiafs_create(struct inode * dir, const char * name, int len, int mode,
- struct inode ** result)
-{
- struct inode * inode;
- struct buffer_head * bh;
- struct xiafs_direct * de;
-
- *result = NULL;
- if (!dir)
- return -ENOENT;
- inode = xiafs_new_inode(dir);
- if (!inode) {
- iput(dir);
- return -ENOSPC;
- }
- inode->i_op = &xiafs_file_inode_operations;
- inode->i_mode = mode;
- inode->i_dirt = 1;
- bh = xiafs_add_entry(dir, name, len, &de, NULL);
- if (!bh) {
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput(inode);
- iput(dir);
- return -ENOSPC;
- }
- de->d_ino = inode->i_ino;
- mark_buffer_dirty(bh, 1);
- brelse(bh);
- iput(dir);
- *result = inode;
- return 0;
-}
-
-int xiafs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev)
-{
- struct inode * inode;
- struct buffer_head * bh;
- struct xiafs_direct * de;
-
- if (!dir)
- return -ENOENT;
- bh = xiafs_find_entry(dir,name,len,&de, NULL);
- if (bh) {
- brelse(bh);
- iput(dir);
- return -EEXIST;
- }
- inode = xiafs_new_inode(dir);
- if (!inode) {
- iput(dir);
- return -ENOSPC;
- }
- inode->i_uid = current->fsuid;
- inode->i_mode = mode;
- inode->i_op = NULL;
- if (S_ISREG(inode->i_mode))
- inode->i_op = &xiafs_file_inode_operations;
- else if (S_ISDIR(inode->i_mode)) {
- inode->i_op = &xiafs_dir_inode_operations;
- if (dir->i_mode & S_ISGID)
- inode->i_mode |= S_ISGID;
- }
- else if (S_ISLNK(inode->i_mode))
- inode->i_op = &xiafs_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);
- if (S_ISBLK(mode) || S_ISCHR(mode))
- inode->i_rdev = to_kdev_t(rdev);
- inode->i_atime = inode->i_ctime = inode->i_atime = CURRENT_TIME;
- inode->i_dirt = 1;
- bh = xiafs_add_entry(dir, name, len, &de, NULL);
- if (!bh) {
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput(inode);
- iput(dir);
- return -ENOSPC;
- }
- de->d_ino = inode->i_ino;
- mark_buffer_dirty(bh, 1);
- brelse(bh);
- iput(dir);
- iput(inode);
- return 0;
-}
-
-int xiafs_mkdir(struct inode * dir, const char * name, int len, int mode)
-{
- struct inode * inode;
- struct buffer_head * bh, *dir_block;
- struct xiafs_direct * de;
-
- bh = xiafs_find_entry(dir,name,len,&de, NULL);
- if (bh) {
- brelse(bh);
- iput(dir);
- return -EEXIST;
- }
- if (dir->i_nlink > 64000) {
- iput(dir);
- return -EMLINK;
- }
- inode = xiafs_new_inode(dir);
- if (!inode) {
- iput(dir);
- return -ENOSPC;
- }
- inode->i_op = &xiafs_dir_inode_operations;
- inode->i_size = XIAFS_ZSIZE(dir->i_sb);
- inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- inode->i_dirt = 1;
- dir_block = xiafs_bread(inode,0,1);
- if (!dir_block) {
- iput(dir);
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput(inode);
- return -ENOSPC;
- }
- de = (struct xiafs_direct *) dir_block->b_data;
- de->d_ino=inode->i_ino;
- strcpy(de->d_name,".");
- de->d_name_len=1;
- de->d_rec_len=12;
- de =(struct xiafs_direct *)(12 + dir_block->b_data);
- de->d_ino = dir->i_ino;
- strcpy(de->d_name,"..");
- de->d_name_len=2;
- de->d_rec_len=XIAFS_ZSIZE(dir->i_sb)-12;
- inode->i_nlink = 2;
- mark_buffer_dirty(dir_block, 1);
- brelse(dir_block);
- inode->i_mode = S_IFDIR | (mode & S_IRWXUGO & ~current->fs->umask);
- if (dir->i_mode & S_ISGID)
- inode->i_mode |= S_ISGID;
- inode->i_dirt = 1;
- bh = xiafs_add_entry(dir, name, len, &de, NULL);
- if (!bh) {
- iput(dir);
- inode->i_nlink=0;
- iput(inode);
- return -ENOSPC;
- }
- de->d_ino = inode->i_ino;
- mark_buffer_dirty(bh, 1);
- dir->i_nlink++;
- dir->i_dirt = 1;
- iput(dir);
- iput(inode);
- brelse(bh);
- return 0;
-}
-
-/*
- * routine to check that the specified directory is empty (for rmdir)
- */
-static int empty_dir(struct inode * inode)
-{
- int i, zones, offset;
- struct buffer_head * bh;
- struct xiafs_direct * de;
-
- if (inode->i_size & (XIAFS_ZSIZE(inode->i_sb)-1) ) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- return 1;
- }
-
- zones=inode->i_size >> XIAFS_ZSIZE_BITS(inode->i_sb);
- for (i=0; i < zones; i++) {
- bh = xiafs_bread(inode, i, 0);
- if (!i) {
- if (!bh) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- return 1;
- }
- de=(struct xiafs_direct *)bh->b_data;
- if (de->d_ino != inode->i_ino || strcmp(".", de->d_name) ||
- de->d_rec_len != 12 ) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- brelse(bh);
- return 1;
- }
- de=(struct xiafs_direct *)(12 + bh->b_data);
- if (!de->d_ino || strcmp("..", de->d_name)) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- brelse(bh);
- return 1;
- }
- offset=de->d_rec_len+12;
- }
- else
- offset = 0;
- if (!bh)
- continue;
- while (offset < XIAFS_ZSIZE(inode->i_sb)) {
- de=(struct xiafs_direct *)(bh->b_data+offset);
- if (de->d_ino > inode->i_sb->u.xiafs_sb.s_ninodes ||
- de->d_rec_len < 12 ||
- (char *)de+de->d_rec_len > bh->b_data+XIAFS_ZSIZE(inode->i_sb) ||
- de->d_name_len + 8 > de->d_rec_len ||
- de->d_name[de->d_name_len]) {
- printk("XIA-FS: bad directory (%s %d)\n", WHERE_ERR);
- brelse(bh);
- return 1;
- }
- if (de->d_ino) {
- brelse(bh);
- return 0;
- }
- offset+=de->d_rec_len;
- }
- brelse(bh);
- }
- return 1;
-}
-
-static void xiafs_rm_entry(struct xiafs_direct *de, struct xiafs_direct * de_pre)
-{
- if (de==de_pre) {
- de->d_ino=0;
- return;
- }
- while (de_pre->d_rec_len+(u_char *)de_pre < (u_char *)de) {
- if (de_pre->d_rec_len < 12) {
- printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR);
- return;
- }
- de_pre=(struct xiafs_direct *)(de_pre->d_rec_len+(u_char *)de_pre);
- }
- if (de_pre->d_rec_len+(u_char *)de_pre > (u_char *)de) {
- printk("XIA-FS: bad directory entry (%s %d)\n", WHERE_ERR);
- return;
- }
- de_pre->d_rec_len+=de->d_rec_len;
-}
-
-int xiafs_rmdir(struct inode * dir, const char * name, int len)
-{
- int retval;
- struct inode * inode;
- struct buffer_head * bh;
- struct xiafs_direct * de, * de_pre;
-
- inode = NULL;
- bh = xiafs_find_entry(dir, name, len, &de, &de_pre);
- retval = -ENOENT;
- if (!bh)
- goto end_rmdir;
- retval = -EPERM;
- if (!(inode = iget(dir->i_sb, de->d_ino)))
- goto end_rmdir;
- if ((dir->i_mode & S_ISVTX) && !fsuser() &&
- current->fsuid != inode->i_uid &&
- current->fsuid != dir->i_uid)
- 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;
- }
- if (inode->i_count > 1) {
- retval = -EBUSY;
- goto end_rmdir;
- }
- if (inode->i_nlink != 2)
- printk("XIA-FS: empty directory has nlink!=2 (%s %d)\n", WHERE_ERR);
- xiafs_rm_entry(de, de_pre);
- mark_buffer_dirty(bh, 1);
- inode->i_nlink=0;
- inode->i_dirt=1;
- dir->i_nlink--;
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- dir->i_dirt=1;
- retval = 0;
-end_rmdir:
- iput(dir);
- iput(inode);
- brelse(bh);
- return retval;
-}
-
-int xiafs_unlink(struct inode * dir, const char * name, int len)
-{
- int retval;
- struct inode * inode;
- struct buffer_head * bh;
- struct xiafs_direct * de, * de_pre;
-
-repeat:
- retval = -ENOENT;
- inode = NULL;
- bh = xiafs_find_entry(dir, name, len, &de, &de_pre);
- if (!bh)
- goto end_unlink;
- if (!(inode = iget(dir->i_sb, de->d_ino)))
- goto end_unlink;
- retval = -EPERM;
- if (S_ISDIR(inode->i_mode))
- goto end_unlink;
- if (de->d_ino != inode->i_ino) {
- iput(inode);
- brelse(bh);
- current->counter = 0;
- schedule();
- goto repeat;
- }
- if ((dir->i_mode & S_ISVTX) && !fsuser() &&
- current->fsuid != inode->i_uid &&
- current->fsuid != dir->i_uid)
- goto end_unlink;
- if (!inode->i_nlink) {
- printk("XIA-FS: Deleting nonexistent file (%s %d)\n", WHERE_ERR);
- inode->i_nlink=1;
- }
- xiafs_rm_entry(de, de_pre);
- mark_buffer_dirty(bh, 1);
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- dir->i_dirt = 1;
- inode->i_nlink--;
- inode->i_dirt = 1;
- retval = 0;
-end_unlink:
- brelse(bh);
- iput(inode);
- iput(dir);
- return retval;
-}
-
-int xiafs_symlink(struct inode * dir, const char * name,
- int len, const char * symname)
-{
- struct xiafs_direct * de;
- struct inode * inode = NULL;
- struct buffer_head * bh = NULL, * name_block = NULL;
- int i;
- char c;
-
- bh = xiafs_find_entry(dir,name,len, &de, NULL);
- if (bh) {
- brelse(bh);
- iput(dir);
- return -EEXIST;
- }
- if (!(inode = xiafs_new_inode(dir))) {
- iput(dir);
- return -ENOSPC;
- }
- inode->i_mode = S_IFLNK | S_IRWXUGO;
- inode->i_op = &xiafs_symlink_inode_operations;
- name_block = xiafs_bread(inode,0,1);
- if (!name_block) {
- iput(dir);
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput(inode);
- return -ENOSPC;
- }
- for (i = 0; i < BLOCK_SIZE-1 && (c=*symname++); i++)
- name_block->b_data[i] = c;
- name_block->b_data[i] = 0;
- mark_buffer_dirty(name_block, 1);
- brelse(name_block);
- inode->i_size = i;
- inode->i_dirt = 1;
- bh = xiafs_add_entry(dir, name, len, &de, NULL);
- if (!bh) {
- inode->i_nlink--;
- inode->i_dirt = 1;
- iput(inode);
- iput(dir);
- return -ENOSPC;
- }
- de->d_ino = inode->i_ino;
- mark_buffer_dirty(bh, 1);
- brelse(bh);
- iput(dir);
- iput(inode);
- return 0;
-}
-
-int xiafs_link(struct inode * oldinode, struct inode * dir,
- const char * name, int len)
-{
- struct xiafs_direct * de;
- struct buffer_head * bh;
-
- if (S_ISDIR(oldinode->i_mode)) {
- iput(oldinode);
- iput(dir);
- return -EPERM;
- }
- if (oldinode->i_nlink > 64000) {
- iput(oldinode);
- iput(dir);
- return -EMLINK;
- }
- bh = xiafs_find_entry(dir, name, len, &de, NULL);
- if (bh) {
- brelse(bh);
- iput(dir);
- iput(oldinode);
- return -EEXIST;
- }
- bh = xiafs_add_entry(dir, name, len, &de, NULL);
- if (!bh) {
- iput(dir);
- iput(oldinode);
- return -ENOSPC;
- }
- de->d_ino = oldinode->i_ino;
- mark_buffer_dirty(bh, 1);
- brelse(bh);
- iput(dir);
- oldinode->i_nlink++;
- oldinode->i_ctime = CURRENT_TIME;
- oldinode->i_dirt = 1;
- iput(oldinode);
- return 0;
-}
-
-static int subdir(struct inode * new_inode, struct inode * old_inode)
-{
- int ino;
- int result;
-
- new_inode->i_count++;
- result = 0;
- for (;;) {
- if (new_inode == old_inode) {
- result = 1;
- break;
- }
- if (new_inode->i_dev != old_inode->i_dev)
- break;
- ino = new_inode->i_ino;
- if (xiafs_lookup(new_inode,"..",2,&new_inode))
- break;
- if (new_inode->i_ino == ino)
- break;
- }
- iput(new_inode);
- return result;
-}
-
-#define PARENT_INO(buffer) \
- (((struct xiafs_direct *) ((u_char *)(buffer) + 12))->d_ino)
-
-/*
- * rename uses retry 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.
- */
-static int do_xiafs_rename(struct inode * old_dir, const char * old_name,
- int old_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;
- struct xiafs_direct * old_de, * old_de_pre, * new_de, * new_de_pre;
- int retval;
-
-try_again:
- old_inode = new_inode = NULL;
- old_bh = new_bh = dir_bh = NULL;
- old_bh = xiafs_find_entry(old_dir, old_name, old_len, &old_de, &old_de_pre);
- retval = -ENOENT;
- if (!old_bh)
- goto end_rename;
- old_inode = __iget(old_dir->i_sb, old_de->d_ino, 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 &&
- current->fsuid != old_dir->i_uid && !fsuser())
- goto end_rename;
- new_bh = xiafs_find_entry(new_dir, new_name, new_len, &new_de, NULL);
- if (new_bh) {
- new_inode = __iget(new_dir->i_sb, new_de->d_ino, 0);
- if (!new_inode) {
- brelse(new_bh);
- new_bh = NULL;
- }
- }
- if (new_inode == old_inode) {
- retval = 0;
- goto end_rename;
- }
- if (new_inode && S_ISDIR(new_inode->i_mode)) {
- retval = -EEXIST;
- 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 && !fsuser())
- goto end_rename;
- if (S_ISDIR(old_inode->i_mode)) {
- retval = -EEXIST;
- if (new_bh)
- goto end_rename;
- if ((retval = permission(old_inode, MAY_WRITE)) != 0)
- goto end_rename;
- retval = -EINVAL;
- if (subdir(new_dir, old_inode))
- goto end_rename;
- retval = -EIO;
- dir_bh = xiafs_bread(old_inode,0,0);
- if (!dir_bh)
- goto end_rename;
- if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
- goto end_rename;
- retval = -EMLINK;
- if (new_dir->i_nlink > 64000)
- goto end_rename;
- }
- if (!new_bh)
- new_bh = xiafs_add_entry(new_dir, new_name, new_len, &new_de, &new_de_pre);
- retval = -ENOSPC;
- if (!new_bh)
- goto end_rename;
- /* sanity checking */
- if ( (new_inode && (new_de->d_ino != new_inode->i_ino))
- || (new_de->d_ino && !new_inode)
- || (old_de->d_ino != old_inode->i_ino)) {
- xiafs_rm_entry(new_de, new_de_pre);
- brelse(old_bh);
- brelse(new_bh);
- brelse(dir_bh);
- iput(old_inode);
- iput(new_inode);
- current->counter=0;
- schedule();
- goto try_again;
- }
- xiafs_rm_entry(old_de, old_de_pre);
- new_de->d_ino = old_inode->i_ino;
- if (new_inode) {
- new_inode->i_nlink--;
- new_inode->i_dirt = 1;
- }
- mark_buffer_dirty(old_bh, 1);
- mark_buffer_dirty(new_bh, 1);
- if (dir_bh) {
- PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
- mark_buffer_dirty(dir_bh, 1);
- old_dir->i_nlink--;
- new_dir->i_nlink++;
- old_dir->i_dirt = 1;
- new_dir->i_dirt = 1;
- }
- retval = 0;
-end_rename:
- brelse(dir_bh);
- brelse(old_bh);
- brelse(new_bh);
- iput(old_inode);
- iput(new_inode);
- iput(old_dir);
- iput(new_dir);
- return retval;
-}
-
-/*
- * Ok, rename also locks out other renames, as they can change the parent of
- * a directory, and we don't want any races. Other races are checked for by
- * "do_rename()", which restarts if there are inconsistencies.
- *
- * Note that there is no race between different filesystems: it's only within
- * the same device that races occur: many renames can happen at once, as long
- * as they are on different partitions.
- */
-int xiafs_rename(struct inode * old_dir, const char * old_name, int old_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;
- int result;
-
- while (lock)
- sleep_on(&wait);
- lock = 1;
- result = do_xiafs_rename(old_dir, old_name, old_len,
- new_dir, new_name, new_len,
- must_be_dir);
- lock = 0;
- wake_up(&wait);
- return result;
-}
diff --git a/fs/xiafs/symlink.c b/fs/xiafs/symlink.c
deleted file mode 100644
index 1803ae457..000000000
--- a/fs/xiafs/symlink.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * linux/fs/xiafs/symlink.c
- *
- * Copyright (C) Q. Frank Xia, 1993.
- *
- * Based on Linus' minix/symlink.c
- * Copyright (C) Linus Torvalds, 1991, 1992.
- *
- * This software may be redistributed per Linux Copyright.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/xia_fs.h>
-#include <linux/stat.h>
-
-#include <asm/uaccess.h>
-
-static int
-xiafs_readlink(struct inode *, char *, int);
-
-static int
-xiafs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
-
-/*
- * symlinks can't do much...
- */
-struct inode_operations xiafs_symlink_inode_operations = {
- NULL, /* no file-operations */
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- xiafs_readlink, /* readlink */
- xiafs_follow_link, /* follow_link */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* bmap */
- NULL, /* truncate */
- NULL /* permission */
-};
-
-static int xiafs_readlink(struct inode * inode, char * buffer, int buflen)
-{
- struct buffer_head * bh;
- int i;
- char c;
-
- if (!S_ISLNK(inode->i_mode)) {
- iput(inode);
- return -EINVAL;
- }
- if (buflen > BLOCK_SIZE)
- buflen = BLOCK_SIZE;
- bh = xiafs_bread(inode, 0, 0);
- if (!IS_RDONLY (inode)) {
- inode->i_atime=CURRENT_TIME;
- inode->i_dirt=1;
- }
- iput(inode);
- if (!bh)
- return 0;
- for (i=0; i < buflen && (c=bh->b_data[i]); i++)
- put_user(c, buffer++);
- if (i < buflen-1)
- put_user('\0', buffer);
- brelse(bh);
- return i;
-}
-
-static int xiafs_follow_link(struct inode * dir, struct inode * inode,
- int flag, int mode, struct inode ** res_inode)
-{
- int error;
- struct buffer_head * bh;
-
- *res_inode = NULL;
- if (!dir) {
- dir = current->fs->root;
- dir->i_count++;
- }
- if (!inode) {
- iput(dir);
- return -ENOENT;
- }
- if (!S_ISLNK(inode->i_mode)) {
- iput(dir);
- *res_inode = inode;
- return 0;
- }
- if (!IS_RDONLY (inode)) {
- inode->i_atime=CURRENT_TIME;
- inode->i_dirt=1;
- }
- if (current->link_count > 5) {
- iput(inode);
- iput(dir);
- return -ELOOP;
- }
- if (!(bh = xiafs_bread(inode, 0, 0))) {
- iput(inode);
- iput(dir);
- return -EIO;
- }
- iput(inode);
- current->link_count++;
- error = open_namei(bh->b_data,flag,mode,res_inode,dir);
- current->link_count--;
- brelse(bh);
- return error;
-}
-
-
-
diff --git a/fs/xiafs/truncate.c b/fs/xiafs/truncate.c
deleted file mode 100644
index bdb9d39be..000000000
--- a/fs/xiafs/truncate.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * linux/fs/xiafs/truncate.c
- *
- * Copyright (C) Q. Frank Xia, 1993.
- *
- * Based on Linus' minix/truncate.c
- * Copyright (C) Linus Torvalds, 1991, 1992.
- *
- * This software may be redistributed per Linux Copyright.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/xia_fs.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-
-#include "xiafs_mac.h"
-
-/*
- * Linus' comment:
- *
- * Truncate has the most races in the whole filesystem: coding it is
- * a pain in the a**. Especially as I don't do any locking...
- *
- * The code may look a bit weird, but that's just because I've tried to
- * handle things like file-size changes in a somewhat graceful manner.
- * Anyway, truncating a file at the same time somebody else writes to it
- * is likely to result in pretty weird behaviour...
- *
- * The new code handles normal truncates (size = 0) as well as the more
- * general case (size = XXX). I hope.
- */
-
-#define DT_ZONE ((inode->i_size + XIAFS_ZSIZE(inode->i_sb) - 1) \
- >> XIAFS_ZSIZE_BITS(inode->i_sb) )
-
-static int trunc_direct(struct inode * inode)
-{
- u_long * lp;
- struct buffer_head * bh;
- int i, tmp;
- int retry = 0;
-
-repeat:
- for (i = DT_ZONE ; i < 8 ; i++) {
- if (i < DT_ZONE)
- goto repeat;
- lp=i + inode->u.xiafs_i.i_zone;
- if (!(tmp = *lp))
- continue;
- bh = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (i < DT_ZONE) {
- brelse(bh);
- goto repeat;
- }
- if ((bh && bh->b_count != 1) || tmp != *lp)
- retry = 1;
- else {
- *lp = 0;
- inode->i_dirt = 1;
- inode->i_blocks-=2 << XIAFS_ZSHIFT(inode->i_sb);
- xiafs_free_zone(inode->i_sb, tmp);
- }
- brelse(bh);
- }
- return retry;
-}
-
-static int trunc_indirect(struct inode * inode, int addr_off, u_long * lp)
-{
-
-#define INDT_ZONE (DT_ZONE - addr_off)
-
- struct buffer_head * bh, * ind_bh;
- int i, tmp;
- u_long * indp;
- int retry = 0;
-
- if ( !(tmp=*lp) )
- return 0;
- ind_bh = bread(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (tmp != *lp) {
- brelse(ind_bh);
- return 1;
- }
- if (!ind_bh) {
- *lp = 0;
- return 0;
- }
-repeat:
- for (i = INDT_ZONE<0?0:INDT_ZONE; i < XIAFS_ADDRS_PER_Z(inode->i_sb); i++) {
- if (i < INDT_ZONE)
- goto repeat;
- indp = i+(u_long *) ind_bh->b_data;
- if (!(tmp=*indp))
- continue;
- bh = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (i < INDT_ZONE) {
- brelse(bh);
- goto repeat;
- }
- if ((bh && bh->b_count != 1) || tmp != *indp)
- retry = 1;
- else {
- *indp = 0;
- mark_buffer_dirty(ind_bh, 1);
- inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb);
- xiafs_free_zone(inode->i_sb, tmp);
- }
- brelse(bh);
- }
- indp = (u_long *) ind_bh->b_data;
- for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*indp++); i++) ;
- if (i >= XIAFS_ADDRS_PER_Z(inode->i_sb)) {
- if (ind_bh->b_count != 1)
- retry = 1;
- else {
- tmp = *lp;
- *lp = 0;
- inode->i_blocks-= 2 << XIAFS_ZSHIFT(inode->i_sb);
- xiafs_free_zone(inode->i_sb, tmp);
- }
- }
- brelse(ind_bh);
- return retry;
-}
-
-static int trunc_dindirect(struct inode * inode)
-{
-
-#define DINDT_ZONE \
- ((DT_ZONE-XIAFS_ADDRS_PER_Z(inode->i_sb)-8)>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb))
-
- int i, tmp;
- struct buffer_head * dind_bh;
- u_long * dindp, * lp;
- int retry = 0;
-
- lp = &(inode->u.xiafs_i.i_dind_zone);
- if (!(tmp = *lp))
- return 0;
- dind_bh = bread(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
- if (tmp != *lp) {
- brelse(dind_bh);
- return 1;
- }
- if (!dind_bh) {
- *lp = 0;
- return 0;
- }
-repeat:
- for (i=DINDT_ZONE<0?0:DINDT_ZONE ; i < XIAFS_ADDRS_PER_Z(inode->i_sb) ; i ++) {
- if (i < DINDT_ZONE)
- goto repeat;
- dindp = i+(u_long *) dind_bh->b_data;
- retry |= trunc_indirect(inode,
- 8+((1+i)<<XIAFS_ADDRS_PER_Z_BITS(inode->i_sb)),
- dindp);
- mark_buffer_dirty(dind_bh, 1);
- }
- dindp = (u_long *) dind_bh->b_data;
- for (i = 0; i < XIAFS_ADDRS_PER_Z(inode->i_sb) && !(*dindp++); i++);
- if (i >= XIAFS_ADDRS_PER_Z(inode->i_sb)) {
- if (dind_bh->b_count != 1)
- retry = 1;
- else {
- tmp = *lp;
- *lp = 0;
- inode->i_dirt = 1;
- inode->i_blocks-=2 << XIAFS_ZSHIFT(inode->i_sb);
- xiafs_free_zone(inode->i_sb, tmp);
- }
- }
- brelse(dind_bh);
- return retry;
-}
-
-void xiafs_truncate(struct inode * inode)
-{
- int retry;
-
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))
- return;
- while (1) {
- retry = trunc_direct(inode);
- retry |= trunc_indirect(inode, 8, &(inode->u.xiafs_i.i_ind_zone));
- retry |= trunc_dindirect(inode);
- if (!retry)
- break;
- current->counter = 0;
- schedule();
- }
- inode->i_ctime = inode->i_mtime = CURRENT_TIME;
- inode->i_dirt = 1;
-}
diff --git a/fs/xiafs/xiafs_mac.h b/fs/xiafs/xiafs_mac.h
deleted file mode 100644
index 05af6e42a..000000000
--- a/fs/xiafs/xiafs_mac.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * linux/fs/xiafs/xiafs_mac.h
- *
- * Copyright (C) Q. Frank Xia, 1993.
- */
-
-extern char internal_error_message[];
-#define INTERN_ERR internal_error_message, __FILE__, __LINE__
-#define WHERE_ERR __FILE__, __LINE__
-
-#define XIAFS_ZSHIFT(sp) ((sp)->u.xiafs_sb.s_zone_shift)
-#define XIAFS_ZSIZE(sp) (BLOCK_SIZE << XIAFS_ZSHIFT(sp))
-#define XIAFS_ZSIZE_BITS(sp) (BLOCK_SIZE_BITS + XIAFS_ZSHIFT(sp))
-#define XIAFS_ADDRS_PER_Z(sp) (BLOCK_SIZE >> (2 - XIAFS_ZSHIFT(sp)))
-#define XIAFS_ADDRS_PER_Z_BITS(sp) (BLOCK_SIZE_BITS - 2 + XIAFS_ZSHIFT(sp))
-#define XIAFS_BITS_PER_Z(sp) (BLOCK_SIZE << (3 + XIAFS_ZSHIFT(sp)))
-#define XIAFS_BITS_PER_Z_BITS(sp) (BLOCK_SIZE_BITS + 3 + XIAFS_ZSHIFT(sp))
-#define XIAFS_INODES_PER_Z(sp) (_XIAFS_INODES_PER_BLOCK << XIAFS_ZSHIFT(sp))
-
-/* Use the most significant bytes of zone pointers to store block counter. */
-/* This is ugly, but it works. Note, We have another 7 bytes for "expansion". */
-
-#define XIAFS_GET_BLOCKS(row_ip, blocks) \
- blocks=((((row_ip)->i_zone[0] >> 24) & 0xff )|\
- (((row_ip)->i_zone[1] >> 16) & 0xff00 )|\
- (((row_ip)->i_zone[2] >> 8) & 0xff0000 ) )
-
-/* XIAFS_PUT_BLOCKS should be called before saving zone pointers */
-#define XIAFS_PUT_BLOCKS(row_ip, blocks) \
- (row_ip)->i_zone[2]=((blocks)<< 8) & 0xff000000;\
- (row_ip)->i_zone[1]=((blocks)<<16) & 0xff000000;\
- (row_ip)->i_zone[0]=((blocks)<<24) & 0xff000000