Commit 17c19e02 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.112pre1

parent 5662673d
......@@ -1488,6 +1488,76 @@ CONFIG_FB
If you want to play with it, say Y here and to the driver for your
graphics board, below. If unsure, say N.
Acorn VIDC support
CONFIG_FB_ACORN
This is the frame buffer device driver for the Acorn VIDC graphics
chipset.
Apollo frame buffer device
CONFIG_FB_APOLLO
This is the frame buffer device driver for the monochrome graphics
hardware found in some Apollo workstations.
Amiga native chipset support
CONFIG_FB_AMIGA
This is the frame buffer device driver for the builtin graphics
chipset found in Amigas.
Amiga OCS chipset support
CONFIG_FB_AMIGA_OCS
This enables support for the original Agnus and Denise video chips,
found in the Amiga 1000 and most A500's and A2000's. If you intend
to run Linux on any of these systems, say Y; otherwise say N.
Amiga ECS chipset support
CONFIG_FB_AMIGA_ECS
This enables support for the Enhanced Chip Set, found in later
A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
you intend to run Linux on any of these systems, say Y; otherwise
say N.
Amiga AGA chipset support
CONFIG_FB_AMIGA_AGA
This enables support for the Advanced Graphics Architecture (also
known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
and CD32. If you intend to run Linux on any of these systems, say Y;
otherwise say N.
Amiga CyberVision support
CONFIG_FB_CYBER
This enables support for the Cybervision 64 graphics card from Phase5.
Please note that its use is not all that intuitive (i.e. if you have
any questions, be sure to ask!). Say N unless you have a Cybervision
64 or plan to get one before you next recompile the kernel.
Please note that this driver DOES NOT support the Cybervision 64 3D
card, as they use incompatible video chips.
Amiga CyberVision3D support (EXPERIMENTAL)
CONFIG_FB_VIRGE
This enables support for the Cybervision 64/3D graphics card from Phase5.
Please note that its use is not all that intuitive (i.e. if you have
any questions, be sure to ask!). Say N unless you have a Cybervision
64/3D or plan to get one before you next recompile the kernel.
Please note that this driver DOES NOT support the older Cybervision 64
card, as they use incompatible video chips.
Amiga RetinaZ3 support (EXPERIMENTAL)
CONFIG_FB_RETINAZ3
This enables support for the Retina Z3 graphics card. Say N unless you
have a Retina Z3 or plan to get one before you next recompile the kernel.
Amiga CLgen driver (EXPERIMENTAL)
CONFIG_FB_CLGEN
This enables support for Cirrus Logic GD542x/543x based boards on Amiga:
SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. Say N
unless you have such a graphics board or plan to get one before you next
recompile the kernel.
Atari native chipset support
CONFIG_FB_ATARI
This is the frame buffer device driver for the builtin graphics
chipset found in Ataris.
Open Firmware frame buffer device support
CONFIG_FB_OF
Say Y if you want support with Open Firmware for your graphics board.
......@@ -1500,6 +1570,31 @@ ATI Mach64 display support
CONFIG_FB_ATY
This driver supports graphics boards with the ATI Mach64 chips.
PowerMac "control" frame buffer device support
CONFIG_FB_CONTROL
This driver supports a frame buffer for the graphics adapter in the
Power Macintosh 7300 and others.
PowerMac "platinum" frame buffer device support
CONFIG_FB_PLATINUM
This driver supports a frame buffer for the "platinum" graphics adapter
in some Power Macintoshes.
Chips 65550 display support
CONFIG_FB_CT65550
This is the frame buffer device driver for the Chips & Technologies
65550 graphics chip in PowerBooks.
Mac frame buffer device
CONFIG_FB_MAC
This is the frame buffer device driver for the graphics hardware in
m68k Macintoshes.
HP300 frame buffer device
CONFIG_FB_HP300
This is the frame buffer device driver for the Topcat graphics
hardware found in HP300 workstations.
VGA chipset support (text only)
CONFIG_FB_VGA
This is the frame buffer device driver for generic VGA chips. This
......@@ -1530,38 +1625,143 @@ CONFIG_FB_MDA
If unsure, say N.
###
### Somebody please explain the following options
###
# Virtual Frame Buffer support (ONLY FOR TESTING!)
# CONFIG_FB_VIRTUAL
#
# Advanced low level driver options
# CONFIG_FBCON_ADVANCED
#
# Monochrome support
# CONFIG_FBCON_MFB
#
# 2 bpp packed pixels support
# CONFIG_FBCON_CFB2
#
# 4 bpp packed pixels support
# CONFIG_FBCON_CFB4
#
# 8 bpp packed pixels support
# CONFIG_FBCON_CFB8
#
# 16 bpp packed pixels support
# CONFIG_FBCON_CFB16
#
# 24 bpp packed pixels support
# CONFIG_FBCON_CFB24
#
# 32 bpp packed pixels support
# CONFIG_FBCON_CFB32
#
# VGA characters/attributes support
# CONFIG_FBCON_VGA
SBUS and UPA framebuffers
CONFIG_FB_SBUS
Say Y if you want support for SBUS or UPA based frame buffer device.
Creator/Creator3D support
CONFIG_FB_CREATOR
This is the frame buffer device driver for the Creator and Creator3D
graphics boards.
CGsix (GX,TurboGX) support
CONFIG_FB_CGSIX
This is the frame buffer device driver for the CGsix (GX, TurboGX)
frame buffer.
BWtwo support
CONFIG_FB_BWTWO
This is the frame buffer device driver for the BWtwo frame buffer.
CGthree support
CONFIG_FB_CGTHREE
This is the frame buffer device driver for the CGthree frame buffer.
TCX (SS4/SS5 only) support
CONFIG_FB_TCX
This is the frame buffer device driver for the TCX 24/8bit frame buffer.
Virtual Frame Buffer support (ONLY FOR TESTING!)
CONFIG_FB_VIRTUAL
This is a `virtual' frame buffer device. It operates on a chunk of
unswapable kernel memory instead of on the memory of a graphics board.
This means you cannot see any output sent to this frame buffer device,
while it does consume precious memory. The main use of this frame
buffer device is testing and debugging the frame buffer subsystem. Do
NOT enable it for normal systems! To protect the innocent, it has to
be enabled explicitly on boot time using the kernel option `video=vfb:'.
This driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want).
The module will be called vfb.o. If you want to compile it as
a module, say M here and read Documentation/modules.txt.
If unsure, say N.
Advanced low level driver options
CONFIG_FBCON_ADVANCED
The frame buffer console uses character drawing routines that are
tailored to the specific organization of pixels in the memory of your
graphics hardware. These are called the low level frame buffer console
drivers. Note that they are used for text console output only; they are
NOT needed for graphical applications.
If you do not enable this option, the needed low level drivers are
automatically enabled, depending on what frame buffer devices you
selected. This is recommended for most users.
If you enable this option, you have more fine-grained control over which
low level drivers are enabled. You can e.g. leave out low level drivers
for color depths you do not intend to use for text consoles.
Low level frame buffer console drivers can be modules ( = code which
can be inserted and removed from the running kernel whenever you want).
The modules will be called fbcon-*.o. If you want to compile (some of)
them as modules, read Documentation/modules.txt.
If unsure, say N.
Monochrome support
CONFIG_FBCON_MFB
This is the low level frame buffer console driver for monochrome
(2 colors) packed pixels.
2 bpp packed pixels support
CONFIG_FBCON_CFB2
This is the low level frame buffer console driver for 2 bits per pixel
(4 colors) packed pixels.
4 bpp packed pixels support
CONFIG_FBCON_CFB4
This is the low level frame buffer console driver for 4 bits per pixel
(16 colors) packed pixels.
8 bpp packed pixels support
CONFIG_FBCON_CFB8
This is the low level frame buffer console driver for 8 bits per pixel
(256 colors) packed pixels.
16 bpp packed pixels support
CONFIG_FBCON_CFB16
This is the low level frame buffer console driver for 15 or 16 bits
per pixel (32K or 64K colors, also known as `hicolor') packed pixels.
24 bpp packed pixels support
CONFIG_FBCON_CFB24
This is the low level frame buffer console driver for 24 bits per
pixel (16M colors, also known as `truecolor') packed pixels. It is
NOT for `sparse' 32 bits per pixel mode.
32 bpp packed pixels support
CONFIG_FBCON_CFB32
This is the low level frame buffer console driver for 32 bits per pixel
(16M colors, also known as `truecolor') sparse packed pixels.
Amiga bitplanes support
CONFIG_FBCON_AFB
This is the low level frame buffer console driver for 1 to 8 bitplanes
(2 to 256 colors) on Amiga.
Amiga interleaved bitplanes support
CONFIG_FBCON_ILBM
This is the low level frame buffer console driver for 1 to 8
interleaved bitplanes (2 to 256 colors) on Amiga.
Atari interleaved bitplanes (2 planes) support
CONFIG_FBCON_IPLAN2P2
This is the low level frame buffer console driver for 2 interleaved
bitplanes (4 colors) on Atari.
Atari interleaved bitplanes (4 planes) support
CONFIG_FBCON_IPLAN2P4
This is the low level frame buffer console driver for 4 interleaved
bitplanes (16 colors) on Atari.
Atari interleaved bitplanes (8 planes) support
CONFIG_FBCON_IPLAN2P8
This is the low level frame buffer console driver for 8 interleaved
bitplanes (256 colors) on Atari.
Mac variable bpp packed pixels support
CONFIG_FBCON_MAC
This is the low level frame buffer console driver for 1/2/4/8/16/32
bits per pixel packed pixels on Mac. It supports variable fontwidths
for low resolution screens.
VGA characters/attributes support
CONFIG_FBCON_VGA
This is the low level frame buffer console driver for VGA text mode, as
used by vgafb.
Parallel-port support
CONFIG_PARPORT
......
VERSION = 2
PATCHLEVEL = 1
SUBLEVEL = 111
SUBLEVEL = 112
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
......@@ -298,7 +298,7 @@ modules_install:
cd modules; \
MODULES=""; \
inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \
mkdir -p $$MODLIB/$$2; cp -p $$These $$MODLIB/$$2; \
mkdir -p $$MODLIB/$$2; cp $$These $$MODLIB/$$2; \
echo Installing modules under $$MODLIB/$$2; \
}; \
\
......
......@@ -43,6 +43,7 @@
#include <linux/errno.h>
#include <linux/genhd.h>
#include <linux/malloc.h>
#include <linux/cdrom.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
......@@ -1141,6 +1142,17 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
idefloppy_pc_t pc;
if (cmd == CDROMEJECT) {
if (drive->usage > 1)
return -EBUSY;
idefloppy_create_prevent_cmd (&pc, 0);
(void) idefloppy_queue_pc_tail (drive, &pc);
idefloppy_create_start_stop_cmd (&pc, 2);
(void) idefloppy_queue_pc_tail (drive, &pc);
return 0;
}
return -EIO;
}
......
......@@ -1525,6 +1525,7 @@ int ide_revalidate_disk(kdev_t i_rdev)
if (sb)
invalidate_inodes(sb);
invalidate_buffers (devp);
set_blocksize(devp, 1024);
}
drive->part[p].start_sect = 0;
drive->part[p].nr_sects = 0;
......
......@@ -37,7 +37,6 @@
* int espserial_init(void);
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
......
......@@ -772,7 +772,7 @@ int idescsi_queue (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
rq->cmd = IDESCSI_PC_RQ;
spin_unlock(&io_request_lock);
(void) ide_do_drive_cmd (drive, rq, ide_end);
spin_lock(&io_request_lock);
spin_lock_irq(&io_request_lock);
return 0;
abort:
if (pc) kfree (pc);
......
......@@ -750,6 +750,7 @@ int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun,
case TYPE_MOD:
case TYPE_PROCESSOR:
case TYPE_SCANNER:
case TYPE_MEDIUM_CHANGER:
SDpnt->writeable = 1;
break;
case TYPE_WORM:
......
......@@ -24,7 +24,6 @@
*
********************************************************************/
#include <linux/config.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < 0x020101
# define LINUX20
......
......@@ -30,6 +30,8 @@
#ifndef __MSND_CLASSIC_H
#define __MSND_CLASSIC_H
#include <linux/config.h>
#define DSP_NUMIO 0x10
#define HP_MEMM 0x08
......
......@@ -30,6 +30,8 @@
#ifndef __MSND_PINNACLE_H
#define __MSND_PINNACLE_H
#include <linux/config.h>
#define DSP_NUMIO 0x08
#define HP_DSPR 0x04
......
......@@ -66,7 +66,7 @@ tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
if [ "$CONFIG_AFFS_FS" != "n" ]; then
define_bool CONFIG_AMIGA_PARTITION y
fi
tristate 'UFS filesystem support (read only)' CONFIG_UFS_FS
tristate 'UFS filesystem support' CONFIG_UFS_FS
if [ "$CONFIG_UFS_FS" != "n" ]; then
bool 'BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL
bool 'SMD disklabel (Sun partition tables) support' CONFIG_SMD_DISKLABEL
......
......@@ -8,8 +8,8 @@
# Note 2! The CFLAGS definitions are now in the main makefile.
O_TARGET := ufs.o
O_OBJS := ufs_dir.o ufs_file.o ufs_inode.o ufs_namei.o \
ufs_super.o ufs_symlink.o ufs_swab.o
O_OBJS := acl.o balloc.o cylinder.o dir.o file.o ialloc.o inode.o \
namei.o super.o symlink.o truncate.o util.o
M_OBJS := $(O_TARGET)
include $(TOPDIR)/Rules.make
/*
* linux/fs/ufs/acl.c
*
* Copyright (C) 1998
* Daniel Pirkl <daniel.pirkl@email.cz>
* Charles Uiversity, Faculty of Mathematics and Physics
*
* from
*
* linux/fs/ext2/acl.c
*
* Copyright (C) 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
* Laboratoire MASI - Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*/
/*
* This file will contain the Access Control Lists management for the
* second extended file system.
*/
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/sched.h>
#include <linux/stat.h>
/*
* ufs_permission ()
*
* Check for access rights
*/
int ufs_permission (struct inode * inode, int mask)
{
unsigned short mode = inode->i_mode;
/*
* Nobody gets write access to a file on a readonly-fs
*/
if ((mask & S_IWOTH) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
IS_RDONLY(inode))
return -EROFS;
/*
* Nobody gets write access to an immutable file
*/
if ((mask & S_IWOTH) && IS_IMMUTABLE(inode))
return -EACCES;
/*
* If no ACL, checks using the file mode
*/
else if (current->fsuid == inode->i_uid)
mode >>= 6;
else if (in_group_p (inode->i_gid))
mode >>= 3;
/*
* Access is always granted for root. We now check last,
* though, for BSD process accounting correctness
*/
if (((mode & mask & S_IRWXO) == mask) || fsuser())
return 0;
else
return -EACCES;
}
This diff is collapsed.
/*
* linux/fs/ufs/cylinder.c
*
* Copyright (C) 1998
* Daniel Pirkl <daniel.pirkl@email.cz>
* Charles University, Faculty of Mathematics and Physics
*
* ext2 - inode (block) bitmap caching inspired
*/
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/locks.h>
#include <asm/bitops.h>
#include <asm/byteorder.h>
#include "swab.h"
#include "util.h"
#undef UFS_CYLINDER_DEBUG
#undef UFS_CYLINDER_DEBUG_MORE
#ifdef UFS_CYLINDER_DEBUG
#define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
#else
#define UFSD(x)
#endif
/*
* Read cylinder group into cache. The memory space for ufs_cg_private_info
* structure is already allocated during ufs_read_super.
*/
static void ufs_read_cylinder (struct super_block * sb,
unsigned cgno, unsigned bitmap_nr)
{
struct ufs_sb_private_info * uspi;
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
unsigned i, j;
unsigned swab;
UFSD(("ENTER, cgno %u, bitmap_nr %u\n", cgno, bitmap_nr))
swab = sb->u.ufs_sb.s_swab;
uspi = sb->u.ufs_sb.s_uspi;
ucpi = sb->u.ufs_sb.s_ucpi[bitmap_nr];
ucg = (struct ufs_cylinder_group *)sb->u.ufs_sb.s_ucg[cgno]->b_data;
#ifdef UFS_CYLINDER_DEBUG_MORE
ufs_print_cylinder_stuff (ucg, swab);
#endif
UCPI_UBH->fragment = ufs_cgcmin(cgno);
UCPI_UBH->count = uspi->s_cgsize >> sb->s_blocksize_bits;
/*
* We have already the first fragment of cylinder group block in buffer
*/
UCPI_UBH->bh[0] = sb->u.ufs_sb.s_ucg[cgno];
for (i = 1; i < UCPI_UBH->count; i++)
if (!(UCPI_UBH->bh[i] = bread (sb->s_dev, UCPI_UBH->fragment + i, sb->s_blocksize)))
goto failed;
sb->u.ufs_sb.s_cgno[bitmap_nr] = cgno;
ucpi->c_cgx = SWAB32(ucg->cg_cgx);
ucpi->c_ncyl = SWAB16(ucg->cg_ncyl);
ucpi->c_niblk = SWAB16(ucg->cg_niblk);
ucpi->c_ndblk = SWAB32(ucg->cg_ndblk);
ucpi->c_rotor = SWAB32(ucg->cg_rotor);
ucpi->c_frotor = SWAB32(ucg->cg_frotor);
ucpi->c_irotor = SWAB32(ucg->cg_irotor);
ucpi->c_btotoff = SWAB32(ucg->cg_btotoff);
ucpi->c_boff = SWAB32(ucg->cg_boff);
ucpi->c_iusedoff = SWAB32(ucg->cg_iusedoff);
ucpi->c_freeoff = SWAB32(ucg->cg_freeoff);
ucpi->c_nextfreeoff = SWAB32(ucg->cg_nextfreeoff);
UFSD(("EXIT\n"))
return;
failed:
for (j = 1; j < i; j++)
brelse (sb->u.ufs_sb.s_ucg[j]);
sb->u.ufs_sb.s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
ufs_error (sb, "ufs_read_cylinder", "can't read cylinder group block %u", cgno);
}
/*
* Remove cylinder group from cache, does'n release memory
* allocated for cylinder group (this is done at ufs_put_super only).
*/
void ufs_put_cylinder (struct super_block * sb, unsigned bitmap_nr)
{
struct ufs_sb_private_info * uspi;
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
unsigned i;
unsigned swab;
UFSD(("ENTER, bitmap_nr %u\n", bitmap_nr))
swab = sb->u.ufs_sb.s_swab;
uspi = sb->u.ufs_sb.s_uspi;
if (sb->u.ufs_sb.s_cgno[bitmap_nr] == UFS_CGNO_EMPTY) {
UFSD(("EXIT\n"))
return;
}
ucpi = sb->u.ufs_sb.s_ucpi[bitmap_nr];
ucg = ubh_get_ucg(UCPI_UBH);
if (uspi->s_ncg > UFS_MAX_GROUP_LOADED && bitmap_nr >= sb->u.ufs_sb.s_cg_loaded) {
ufs_panic (sb, "ufs_put_cylinder", "internal error");
return;
}
/*
* rotor is not so important data, so we put it to disk
* at the end of working with cylinder
*/
ucg->cg_rotor = SWAB32(ucpi->c_rotor);
ucg->cg_frotor = SWAB32(ucpi->c_frotor);
ucg->cg_irotor = SWAB32(ucpi->c_irotor);
ubh_mark_buffer_dirty (UCPI_UBH, 1);
for (i = 1; i < UCPI_UBH->count; i++) {
brelse (UCPI_UBH->bh[i]);
}
sb->u.ufs_sb.s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
UFSD(("EXIT\n"))
}
/*
* Find cylinder group in cache and return it as pointer.
* If cylinder group is not in cache, we will load it from disk.
*
* The cache is managed by LRU alghoritm.
*/
struct ufs_cg_private_info * ufs_load_cylinder (
struct super_block * sb, unsigned cgno)
{
struct ufs_sb_private_info * uspi;
struct ufs_cg_private_info * ucpi;
unsigned cg, i, j;
UFSD(("ENTER, cgno %u\n", cgno))
uspi = sb->u.ufs_sb.s_uspi;
if (cgno >= uspi->s_ncg) {
ufs_panic (sb, "ufs_load_cylinder", "internal error, high number of cg");
return NULL;
}
/*
* Cylinder group number cg it in cache and it was last used
*/
if (sb->u.ufs_sb.s_cgno[0] == cgno) {
UFSD(("EXIT\n"))
return sb->u.ufs_sb.s_ucpi[0];
}
/*
* Number of cylinder groups is not higher than UFS_MAX_GROUP_LOADED
*/
if (uspi->s_ncg <= UFS_MAX_GROUP_LOADED) {
if (sb->u.ufs_sb.s_cgno[cgno] != UFS_CGNO_EMPTY) {
if (sb->u.ufs_sb.s_cgno[cgno] != cgno) {
ufs_panic (sb, "ufs_load_cylinder", "internal error, wrog number of cg in cache");
UFSD(("EXIT (FAILED)\n"))
return NULL;
}
else {
UFSD(("EXIT\n"))
return sb->u.ufs_sb.s_ucpi[cgno];
}
} else {
ufs_read_cylinder (sb, cgno, cgno);
UFSD(("EXIT\n"))
return sb->u.ufs_sb.s_ucpi[cgno];
}
}
/*
* Cylinder group number cg is in cache but it was not last used,
* we will move to the first position
*/
for (i = 0; i < sb->u.ufs_sb.s_cg_loaded && sb->u.ufs_sb.s_cgno[i] != cgno; i++);
if (i < sb->u.ufs_sb.s_cg_loaded && sb->u.ufs_sb.s_cgno[i] == cgno) {
cg = sb->u.ufs_sb.s_cgno[i];
ucpi = sb->u.ufs_sb.s_ucpi[i];
for (j = i; j > 0; j--) {
sb->u.ufs_sb.s_cgno[j] = sb->u.ufs_sb.s_cgno[j-1];
sb->u.ufs_sb.s_ucpi[j] = sb->u.ufs_sb.s_ucpi[j-1];
}
sb->u.ufs_sb.s_cgno[0] = cg;
sb->u.ufs_sb.s_ucpi[0] = ucpi;
/*
* Cylinder group number cg is not in cache, we will read it from disk
* and put it to the first possition
*/
} else {
if (sb->u.ufs_sb.s_cg_loaded < UFS_MAX_GROUP_LOADED)
sb->u.ufs_sb.s_cg_loaded++;
else
ufs_put_cylinder (sb, UFS_MAX_GROUP_LOADED-1);
for (j = sb->u.ufs_sb.s_cg_loaded - 1; j > 0; j--) {
sb->u.ufs_sb.s_cgno[j] = sb->u.ufs_sb.s_cgno[j-1];
sb->u.ufs_sb.s_ucpi[j] = sb->u.ufs_sb.s_ucpi[j-1];
}
ufs_read_cylinder (sb, cgno, 0);
}
UFSD(("EXIT\n"))
return sb->u.ufs_sb.s_ucpi[0];
}
......@@ -11,11 +11,22 @@
* 4.4BSD (FreeBSD) support added on February 1st 1998 by
* Niels Kristian Bech Jensen <nkbj@image.dk> partially based
* on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
*
* write support by Daniel Pirkl <daniel.pirkl@email.cz> 1998
*/
#include <linux/fs.h>
#include "ufs_swab.h"
#include "swab.h"
#include "util.h"
#undef UFS_DIR_DEBUG
#ifdef UFS_DIR_DEBUG
#define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
#else
#define UFSD(x)
#endif
/*
* This is blatantly stolen from ext2fs
......@@ -28,10 +39,11 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
unsigned long offset, lblk, blk;
int i, stored;
struct buffer_head * bh;
struct ufs_direct * de;
struct ufs_dir_entry * de;
struct super_block * sb;
int de_reclen;
__u32 flags;
unsigned flags, swab;
/* Isn't that already done in the upper layer???
* the VFS layer really needs some explicit documentation!
......@@ -40,13 +52,10 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
return -EBADF;
sb = inode->i_sb;
swab = sb->u.ufs_sb.s_swab;
flags = sb->u.ufs_sb.s_flags;
if (flags & UFS_DEBUG) {
printk("ufs_readdir: ino %lu f_pos %lu\n",
inode->i_ino, (unsigned long) filp->f_pos);
ufs_print_inode(inode);
}
UFSD(("ENTER, ino %lu f_pos %lu\n", inode->i_ino, (unsigned long) filp->f_pos))
stored = 0;
bh = NULL;
......@@ -73,8 +82,7 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
* to make sure. */
if (filp->f_version != inode->i_version) {
for (i = 0; i < sb->s_blocksize && i < offset; ) {
de = (struct ufs_direct *)
(bh->b_data + i);
de = (struct ufs_dir_entry *)(bh->b_data + i);
/* It's too expensive to do a full
* dirent test each time round this
* loop, but we do have to test at
......@@ -94,9 +102,9 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
while (!error && filp->f_pos < inode->i_size
&& offset < sb->s_blocksize) {
de = (struct ufs_direct *) (bh->b_data + offset);
de = (struct ufs_dir_entry *) (bh->b_data + offset);
/* XXX - put in a real ufs_check_dir_entry() */
if ((de->d_reclen == 0) || (NAMLEN(de) == 0)) {
if ((de->d_reclen == 0) || (ufs_namlen(de) == 0)) {
/* SWAB16() was unneeded -- compare to 0 */
filp->f_pos = (filp->f_pos &
(sb->s_blocksize - 1)) +
......@@ -128,11 +136,9 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
* during the copy operation. */
unsigned long version = inode->i_version;
if (flags & UFS_DEBUG) {
printk("ufs_readdir: filldir(%s,%u)\n",
de->d_name, SWAB32(de->d_ino));
}
error = filldir(dirent, de->d_name, NAMLEN(de),
UFSD(("filldir(%s,%u)\n", de->d_name, SWAB32(de->d_ino)))
UFSD(("namlen %u\n", ufs_namlen(de)))
error = filldir(dirent, de->d_name, ufs_namlen(de),
filp->f_pos, SWAB32(de->d_ino));
if (error)
break;
......@@ -145,15 +151,45 @@ ufs_readdir (struct file * filp, void * dirent, filldir_t filldir)
offset = 0;
brelse (bh);
}
#if 0 /* XXX */
if (!IS_RDONLY(inode)) {
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
}
#endif /* XXX */
UPDATE_ATIME(inode);
return 0;
}
int ufs_check_dir_entry (const char * function, struct inode * dir,
struct ufs_dir_entry * de, struct buffer_head * bh,
unsigned long offset)
{
struct super_block * sb;
const char * error_msg;
unsigned flags, swab;
sb = dir->i_sb;
flags = sb->u.ufs_sb.s_flags;
swab = sb->u.ufs_sb.s_swab;
error_msg = NULL;
if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(1))
error_msg = "reclen is smaller than minimal";
else if (SWAB16(de->d_reclen) % 4 != 0)
error_msg = "reclen % 4 != 0";
else if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(ufs_namlen(de)))
error_msg = "reclen is too small for namlen";
else if (dir && ((char *) de - bh->b_data) + SWAB16(de->d_reclen) >
dir->i_sb->s_blocksize)
error_msg = "directory entry across blocks";
else if (dir && SWAB32(de->d_ino) > (sb->u.ufs_sb.s_uspi->s_ipg * sb->u.ufs_sb.s_uspi->s_ncg))
error_msg = "inode out of bounds";
if (error_msg != NULL)
ufs_error (sb, function, "bad entry in directory #%lu, size %lu: %s - "
"offset=%lu, inode=%lu, reclen=%d, namlen=%d",
dir->i_ino, dir->i_size, error_msg, offset,
(unsigned long) SWAB32(de->d_ino),
SWAB16(de->d_reclen), ufs_namlen(de));
return (error_msg == NULL ? 1 : 0);
}
static struct file_operations ufs_dir_operations = {
NULL, /* lseek */
NULL, /* read */
......@@ -172,20 +208,21 @@ static struct file_operations ufs_dir_operations = {
struct inode_operations ufs_dir_inode_operations = {
&ufs_dir_operations, /* default directory file operations */
NULL, /* create */
ufs_create, /* create */
ufs_lookup, /* lookup */
NULL, /* link */
NULL, /* unlink */
NULL, /* symlink */
NULL, /* mkdir */
NULL, /* rmdir */
NULL, /* mknod */
NULL, /* rename */
ufs_link, /* link */
ufs_unlink, /* unlink */
ufs_symlink, /* symlink */
ufs_mkdir, /* mkdir */
ufs_rmdir, /* rmdir */
ufs_mknod, /* mknod */
ufs_rename, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* bmap */
NULL, /* truncate */
NULL, /* permission */
ufs_bmap, /* bmap */
ufs_truncate, /* truncate */
ufs_permission, /* permission */
NULL, /* smap */
};
/*
* linux/fs/ufs/file.c
*
* Copyright (C) 1998
* Daniel Pirkl <daniel.pirkl@email.cz>
* Charles University, Faculty of Mathematics and Physics
*
* from
*
* linux/fs/ext2/file.c
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
* Laboratoire MASI - Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* from
*
* linux/fs/minix/file.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* ext2 fs regular file handling primitives
*/
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/locks.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#define NBUF 32
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#include <linux/fs.h>
#include <linux/ufs_fs.h>
static long long ufs_file_lseek(struct file *, long long, int);
static ssize_t ufs_file_write (struct file *, const char *, size_t, loff_t *);
static int ufs_release_file (struct inode *, struct file *);
/*
* We have mostly NULL's here: the current defaults are ok for
* the ufs filesystem.
*/
static struct file_operations ufs_file_operations = {
ufs_file_lseek, /* lseek */
generic_file_read, /* read */
ufs_file_write, /* write */
NULL, /* readdir - bad */
NULL, /* poll - default */
NULL, /* ioctl */
generic_file_mmap, /* mmap */
NULL, /* no special open is needed */
ufs_release_file, /* release */
NULL, /* fsync */
NULL, /* fasync */
NULL, /* check_media_change */
NULL /* revalidate */
};
struct inode_operations ufs_file_inode_operations = {
&ufs_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 */
ufs_bmap, /* bmap */
ufs_truncate, /* truncate */
NULL, /* permission */
NULL /* smap */
};
/*
* Make sure the offset never goes beyond the 32-bit mark..
*/
static long long ufs_file_lseek(
struct file *file,
long long offset,
int origin )
{
long long retval;
struct inode *inode = file->f_dentry->d_inode;
switch (origin) {
case 2:
offset += inode->i_size;
break;
case 1:
offset += file->f_pos;
}
retval = -EINVAL;
/* make sure the offset fits in 32 bits */
if (((unsigned long long) offset >> 32) == 0) {
if (offset != file->f_pos) {
file->f_pos = offset;
file->f_reada = 0;
file->f_version = ++event;
}
retval = offset;
}
return retval;
}
static inline void remove_suid(struct inode *inode)
{
unsigned int mode;
/* set S_IGID if S_IXGRP is set, and always set S_ISUID */
mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
/* was any of the uid bits set? */
mode &= inode->i_mode;
if (mode && !suser()) {
inode->i_mode &= ~mode;
mark_inode_dirty(inode);
}
}
static ssize_t ufs_file_write (
struct file * filp,
const char * buf,
size_t count,
loff_t *ppos )
{
struct inode * inode = filp->f_dentry->d_inode;
__u32 pos;
long block;
int offset;
int written, c;
struct buffer_head * bh, *bufferlist[NBUF];
struct super_block * sb;
int err;
int i,buffercount,write_error;
/* POSIX: mtime/ctime may not change for 0 count */
if (!count)
return 0;
write_error = buffercount = 0;
if (!inode)
return -EINVAL;
sb = inode->i_sb;
if (sb->s_flags & MS_RDONLY)
/*
* This fs has been automatically remounted ro because of errors
*/
return -ENOSPC;
if (!S_ISREG(inode->i_mode)) {
ufs_warning (sb, "ufs_file_write", "mode = %07o",
inode->i_mode);
return -EINVAL;
}
remove_suid(inode);
if (filp->f_flags & O_APPEND)
pos = inode->i_size;
else {
pos = *ppos;
if (pos != *ppos)
return -EINVAL;
}
/* Check for overflow.. */
if (pos > (__u32) (pos + count)) {
count = ~pos; /* == 0xFFFFFFFF - pos */
if (!count)
return -EFBIG;
}
/*
* If a file has been opened in synchronous mode, we have to ensure
* that meta-data will also be written synchronously. Thus, we
* set the i_osync field. This field is tested by the allocation
* routines.
*/
if (filp->f_flags & O_SYNC)
inode->u.ufs_i.i_osync++;
block = pos >> sb->s_blocksize_bits;
offset = pos & (sb->s_blocksize - 1);
c = sb->s_blocksize - offset;
written = 0;
do {
bh = ufs_getfrag (inode, block, 1, &err);
if (!bh) {
if (!written)
written = err;
break;
}
if (c > count)
c = count;
if (c != sb->s_blocksize && !buffer_uptodate(bh)) {
ll_rw_block (READ, 1, &bh);
wait_on_buffer (bh);
if (!buffer_uptodate(bh)) {
brelse (bh);
if (!written)
written = -EIO;
break;
}
}
c -= copy_from_user (bh->b_data + offset, buf, c);
if (!c) {
brelse(bh);
if (!written)
written = -EFAULT;
break;
}
update_vm_cache(inode, pos, bh->b_data + offset, c);
pos += c;
written += c;
buf += c;
count -= c;
mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 0);
if (filp->f_flags & O_SYNC)
bufferlist[buffercount++] = bh;
else
brelse(bh);
if (buffercount == NBUF){
ll_rw_block(WRITE, buffercount, bufferlist);
for(i=0; i<buffercount; i++){
wait_on_buffer(bufferlist[i]);
if (!buffer_uptodate(bufferlist[i]))
write_error=1;
brelse(bufferlist[i]);
}
buffercount=0;
}
if (write_error)
break;
block++;
offset = 0;
c = sb->s_blocksize;
} while (count);
if (buffercount){
ll_rw_block(WRITE, buffercount, bufferlist);
for (i=0; i<buffercount; i++){
wait_on_buffer(bufferlist[i]);
if (!buffer_uptodate(bufferlist[i]))
write_error=1;
brelse(bufferlist[i]);
}
}
if (pos > inode->i_size)
inode->i_size = pos;
if (filp->f_flags & O_SYNC)
inode->u.ufs_i.i_osync--;
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
*ppos = pos;
mark_inode_dirty(inode);
return written;
}
/*
* Called when an inode is released. Note that this is different
* from ufs_open: open gets called at every open, but release
* gets called only when /all/ the files are closed.
*/
static int ufs_release_file (struct inode * inode, struct file * filp)
{
return 0;
}
/*
* linux/fs/ufs/ialloc.c
*
* Copyright (c) 1998
* Daniel Pirkl <daniel.pirkl@email.cz>
* Charles University, Faculty of Mathematics and Physics
*
* from
*
* linux/fs/ext2/ialloc.c
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
* Laboratoire MASI - Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* BSD ufs-inspired inode and directory allocation by
* Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
* Big-endian to little-endian byte-swapping/bitmaps by
* David S. Miller (davem@caip.rutgers.edu), 1995
*/
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/locks.h>
#include <linux/quotaops.h>
#include <asm/bitops.h>
#include <asm/byteorder.h>
#include "swab.h"
#include "util.h"
#undef UFS_IALLOC_DEBUG
#undef UFS_IALLOC_DEBUG_MORE
#ifdef UFS_IALLOC_DEBUG
#define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
#else
#define UFSD(x)
#endif
#ifdef UFS_IALLOC_DEBUG_MORE
#define UFSDM \
ufs_print_cylinder_stuff (ucg, swab); \
printk("inode: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nifree), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nifree), SWAB32(ucg->cg_cs.cs_nifree)); \
printk("block: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nbfree), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nbfree), SWAB32(ucg->cg_cs.cs_nbfree)); \
printk("fragment: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_nffree), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_nffree), SWAB32(ucg->cg_cs.cs_nffree)); \
printk("ndir: total %u, fs %u, cg %u\n", SWAB32(usb1->fs_cstotal.cs_ndir), SWAB32(sb->fs_cs(ucpi->c_cgx).cs_ndir), SWAB32(ucg->cg_cs.cs_ndir));
#else
#define UFSDM
#endif
/*
* NOTE! When we get the inode, we're the only people
* that have access to it, and as such there are no
* race conditions we have to worry about. The inode
* is not on the hash-lists, and it cannot be reached
* through the filesystem because the directory entry
* has been deleted earlier.
*
* HOWEVER: we must make sure that we get no aliases,
* which means that we have to call "clear_inode()"
* _before_ we mark the inode not in use in the inode
* bitmaps. Otherwise a newly created file might use
* the same inode number (not actually the same pointer
* though), and then we'd have two inodes sharing the
* same inode number and space on the harddisk.
*/
void ufs_free_inode (struct inode * inode)
{
struct super_block * sb;
struct ufs_sb_private_info * uspi;
struct ufs_super_block_first * usb1;
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
int is_directory;
unsigned ino, cg, bit;
unsigned swab;
UFSD(("ENTER, ino %lu\n", inode->i_ino))
if (!inode)
return;
sb = inode->i_sb;
swab = sb->u.ufs_sb.s_swab;
uspi = sb->u.ufs_sb.s_uspi;
usb1 = ubh_get_usb_first(USPI_UBH);
if (inode->i_count > 1) {
ufs_warning(sb, "ufs_free_inode", "inode has count=%d\n", inode->i_count);
return;
}
if (inode->i_nlink) {
ufs_warning(sb, "ufs_free_inode", "inode has nlink=%d\n", inode->i_nlink);
return;
}
ino = inode->i_ino;
lock_super (sb);
if (!((ino > 1) && (ino < (uspi->s_ncg * uspi->s_ipg )))) {
ufs_warning(sb, "ufs_free_inode", "reserved inode or nonexistent inode %u\n", ino);
unlock_super (sb);
return;
}
cg = ufs_inotocg (ino);
bit = ufs_inotocgoff (ino);
ucpi = ufs_load_cylinder (sb, cg);
if (!ucpi) {
unlock_super (sb);
return;
}
ucg = ubh_get_ucg(UCPI_UBH);
if (!ufs_cg_chkmagic(ucg))
ufs_panic (sb, "ufs_free_fragments", "internal error, bad cg magic number");
UFSDM
ucg->cg_time = SWAB32(CURRENT_TIME);
is_directory = S_ISDIR(inode->i_mode);
DQUOT_FREE_INODE(sb, inode);
clear_inode (inode);
if (ubh_isclr (UCPI_UBH, ucpi->c_iusedoff, bit))
ufs_error(sb, "ufs_free_inode", "bit already cleared for inode %u", ino);
else {
ubh_clrbit (UCPI_UBH, ucpi->c_iusedoff, bit);
if (ino < ucpi->c_irotor)
ucpi->c_irotor = ino;
INC_SWAB32(ucg->cg_cs.cs_nifree);
INC_SWAB32(usb1->fs_cstotal.cs_nifree);
INC_SWAB32(sb->fs_cs(cg).cs_nifree);
if (is_directory) {
DEC_SWAB32(ucg->cg_cs.cs_ndir);
DEC_SWAB32(usb1->fs_cstotal.cs_ndir);
DEC_SWAB32(sb->fs_cs(cg).cs_ndir);
}
}
ubh_mark_buffer_dirty (USPI_UBH, 1);
ubh_mark_buffer_dirty (UCPI_UBH, 1);
if (sb->s_flags & MS_SYNCHRONOUS) {
ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **) &ucpi);
ubh_wait_on_buffer (UCPI_UBH);
}
UFSDM
sb->s_dirt = 1;
unlock_super (sb);
UFSD(("EXIT\n"))
}
/*
* There are two policies for allocating an inode. If the new inode is
* a directory, then a forward search is made for a block group with both
* free space and a low directory-to-inode ratio; if that fails, then of
* the groups with above-average free space, that group with the fewest
* directories already is chosen.
*
* For other inodes, search forward from the parent directory\'s block
* group to find a free inode.
*/
struct inode * ufs_new_inode (const struct inode * dir, int mode, int * err )
{
struct super_block * sb;
struct ufs_sb_private_info * uspi;
struct ufs_super_block_first * usb1;
struct ufs_cg_private_info * ucpi;
struct ufs_cylinder_group * ucg;
struct inode * inode;
unsigned cg, bit, i, j, start;
unsigned swab;
UFSD(("ENTER\n"))
/* Cannot create files in a deleted directory */
if (!dir || !dir->i_nlink) {
*err = -EPERM;
return NULL;
}
inode = get_empty_inode ();
if (!inode) {
*err = -ENOMEM;
return NULL;
}
sb = dir->i_sb;
swab = sb->u.ufs_sb.s_swab;
uspi = sb->u.ufs_sb.s_uspi;
usb1 = ubh_get_usb_first(USPI_UBH);
inode->i_sb = sb;
inode->i_flags = sb->s_flags;
lock_super (sb);
*err = -ENOSPC;
/*
* Try to place the inode in its parent directory
*/
i = ufs_inotocg(dir->i_ino);
if (SWAB32(sb->fs_cs(i).cs_nifree)) {
cg = i;
goto cg_found;
}
/*
* Use a quadratic hash to find a group with a free inode
*/
for ( j = 1; j < uspi->s_ncg; j <<= 1 ) {
i += j;
if (i >= uspi->s_ncg)
i -= uspi->s_ncg;
if (SWAB32(sb->fs_cs(i).cs_nifree)) {
cg = i;
goto cg_found;
}
}
/*
* That failed: try linear search for a free inode
*/
i = ufs_inotocg(dir->i_ino) + 1;
for (j = 2; j < uspi->s_ncg; j++) {
i++;
if (i >= uspi->s_ncg)
i = 0;
if (SWAB32(sb->fs_cs(i).cs_nifree)) {
cg = i;
goto cg_found;
}
}
goto failed;
cg_found:
ucpi = ufs_load_cylinder (sb, cg);
if (!ucpi)
goto failed;
ucg = ubh_get_ucg(UCPI_UBH);
if (!ufs_cg_chkmagic(ucg))
ufs_panic (sb, "ufs_new_inode", "internal error, bad cg magic number");
UFSDM
start = ucpi->c_irotor;
bit = ubh_find_next_zero_bit (UCPI_UBH, ucpi->c_iusedoff, uspi->s_ipg, start);
if (!(bit < uspi->s_ipg)) {
bit = ubh_find_first_zero_bit (UCPI_UBH, ucpi->c_iusedoff, start);
if (!(bit < start)) {
ufs_error (sb, "ufs_new_inode",
"cylinder group %u corrupted - error in inode bitmap\n", cg);
goto failed;
}
}
UFSD(("start = %u, bit = %u, ipg = %u\n", start, bit, uspi->s_ipg))
if (ubh_isclr (UCPI_UBH, ucpi->c_iusedoff, bit))
ubh_setbit (UCPI_UBH, ucpi->c_iusedoff, bit);
else {
ufs_panic (sb, "ufs_new_inode", "internal error");
goto failed;
}
DEC_SWAB32(ucg->cg_cs.cs_nifree);
DEC_SWAB32(usb1->fs_cstotal.cs_nifree);
DEC_SWAB32(sb->fs_cs(cg).cs_nifree);
if (S_ISDIR(mode)) {
INC_SWAB32(ucg->cg_cs.cs_ndir);
INC_SWAB32(usb1->fs_cstotal.cs_ndir);
INC_SWAB32(sb->fs_cs(cg).cs_ndir);
}
ubh_mark_buffer_dirty (USPI_UBH, 1);
ubh_mark_buffer_dirty (UCPI_UBH, 1);
if (sb->s_flags & MS_SYNCHRONOUS) {
ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **) &ucpi);
ubh_wait_on_buffer (UCPI_UBH);
}
sb->s_dirt = 1;
inode->i_mode = mode;
inode->i_sb = sb;
inode->i_nlink = 1;
inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
if (test_opt (sb, GRPID))
inode->i_gid = dir->i_gid;
else if (dir->i_mode & S_ISGID) {
inode->i_gid = dir->i_gid;
if (S_ISDIR(mode))
mode |= S_ISGID;
} else
inode->i_gid = current->fsgid;
inode->i_ino = cg * uspi->s_ipg + bit;
inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */
inode->i_blocks = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
inode->u.ufs_i.i_flags = dir->u.ufs_i.i_flags;
inode->u.ufs_i.i_uid = inode->i_uid;
inode->u.ufs_i.i_gid = inode->i_gid;
inode->u.ufs_i.i_lastfrag = 0;
inode->i_op = NULL;
insert_inode_hash(inode);
mark_inode_dirty(inode);
UFSDM
unlock_super (sb);
if(DQUOT_ALLOC_INODE(sb, inode)) {
sb->dq_op->drop(inode);
inode->i_nlink = 0;
iput(inode);
*err = -EDQUOT;
return NULL;
}
UFSD(("allocating inode %lu\n", inode->i_ino))
*err = 0;
UFSD(("EXIT\n"))
return inode;
failed:
unlock_super (sb);
iput (inode);
UFSD(("EXIT (FAILED)\n"))
return NULL;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* linux/fs/ufs/ufs_swab.h
*
* Copyright (C) 1997 Francois-Rene Rideau <rideau@ens.fr>
* Copyright (C) 1998 Jakub Jelinek <jj@ultra.linux.cz>
*/
#ifndef _UFS_SWAB_H
#define _UFS_SWAB_H
/*
* Notes:
* HERE WE ASSUME EITHER BIG OR LITTLE ENDIAN UFSes
* in case there are ufs implementations that have strange bytesexes,
* you'll need to modify code here as well as in ufs_super.c and ufs_fs.h
* to support them.
*/
#include <linux/ufs_fs.h>
#include <asm/byteorder.h>
/*
* These are only valid inside ufs routines,
* after swab has been initialized to sb->u.ufs_sb.s_swab
*/
#define SWAB16(x) ufs_swab16(swab,x)
#define SWAB32(x) ufs_swab32(swab,x)
#define SWAB64(x) ufs_swab64(swab,x)
/*
* We often use swabing, when we want to increment/decrement some value, so these
* macros might become handy and increase readability. (Daniel)
*/
#define INC_SWAB16(x) x=ufs_swab16_add(swab,x,1)
#define INC_SWAB32(x) x=ufs_swab32_add(swab,x,1)
#define INC_SWAB64(x) x=ufs_swab64_add(swab,x,1)
#define DEC_SWAB16(x) x=ufs_swab16_add(swab,x,-1)
#define DEC_SWAB32(x) x=ufs_swab32_add(swab,x,-1)
#define DEC_SWAB64(x) x=ufs_swab64_add(swab,x,-1)
#define ADD_SWAB16(x,y) x=ufs_swab16_add(swab,x,y)
#define ADD_SWAB32(x,y) x=ufs_swab32_add(swab,x,y)
#define ADD_SWAB64(x,y) x=ufs_swab64_add(swab,x,y)
#define SUB_SWAB16(x,y) x=ufs_swab16_add(swab,x,-(y))
#define SUB_SWAB32(x,y) x=ufs_swab32_add(swab,x,-(y))
#define SUB_SWAB64(x,y) x=ufs_swab64_add(swab,x,-(y))
#ifndef __PDP_ENDIAN
extern __inline__ __const__ __u16 ufs_swab16(unsigned swab, __u16 x) {
if (swab)
return swab16(x);
else
return x;
}
extern __inline__ __const__ __u32 ufs_swab32(unsigned swab, __u32 x) {
if (swab)
return swab32(x);
else
return x;
}
extern __inline__ __const__ __u64 ufs_swab64(unsigned swab, __u64 x) {
if (swab)
return swab64(x);
else
return x;
}
extern __inline__ __const__ __u16 ufs_swab16_add(unsigned swab, __u16 x, __u16 y) {
if (swab)
return swab16(swab16(x)+y);
else
return x + y;
}
extern __inline__ __const__ __u32 ufs_swab32_add(unsigned swab, __u32 x, __u32 y) {
if (swab)
return swab32(swab32(x)+y);
else
return x + y;
}
extern __inline__ __const__ __u64 ufs_swab64_add(unsigned swab, __u64 x, __u64 y) {
if (swab)
return swab64(swab64(x)+y);
else
return x + y;
}
#else /* __PDP_ENDIAN */
extern __inline__ __const__ __u16 ufs_swab16(unsigned swab, __u16 x) {
if (swab & UFS_LITTLE_ENDIAN)
return le16_to_cpu(x);
else
return be16_to_cpu(x);
}
extern __inline__ __const__ __u32 ufs_swab32(unsigned swab, __u32 x) {
if (swab & UFS_LITTLE_ENDIAN)
return le32_to_cpu(x);
else
return be32_to_cpu(x);
}
extern __inline__ __const__ __u64 ufs_swab64(unsigned swab, __u64 x) {
if (swab & UFS_LITTLE_ENDIAN)
return le64_to_cpu(x);
else
return be64_to_cpu(x);
}
extern __inline__ __const__ __u16 ufs_swab16_add(unsigned swab, __u16 x, __u16 y) {
return ufs_swab16(swab, ufs_swab16(swab, x) + y);
}
extern __inline__ __const__ __u32 ufs_swab32_add(unsigned swab, __u32 x, __u32 y) {
return ufs_swab32(swab, ufs_swab32(swab, x) + y);
}
extern __inline__ __const__ __u64 ufs_swab64_add(unsigned swab, __u64 x, __u64 y) {
return ufs_swab64(swab, ufs_swab64(swab, x) + y);
}
#endif /* __PDP_ENDIAN */
#endif /* _UFS_SWAB_H */
This diff is collapsed.
This diff is collapsed.
/*
* linux/fs/ufs/ufs_file.c
*
* Copyright (C) 1996
* Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
* Laboratory for Computer Science Research Computing Facility
* Rutgers, The State University of New Jersey
*
* $Id: ufs_file.c,v 1.9 1997/07/17 02:24:13 davem Exp $
*
*/
#include <linux/fs.h>
#include <linux/ufs_fs.h>
static struct file_operations ufs_file_operations = {
NULL, /* lseek */
generic_file_read, /* read */
NULL, /* write */
NULL, /* readdir */
NULL, /* select */
NULL, /* ioctl */
generic_file_mmap, /* mmap */
NULL, /* open */
NULL, /* release */
file_fsync, /* fsync */
NULL, /* fasync */
NULL, /* check_media_change */
NULL, /* revalidate */
};
struct inode_operations ufs_file_inode_operations = {
&ufs_file_operations, /* default directory 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 */
ufs_bmap, /* bmap */
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -19,10 +19,6 @@
#include <linux/config.h>
#include <asm/processor.h>
#ifdef CONFIG_MTRR
# include <asm/mtrr.h>
#endif
#define CONFIG_BUGi386
__initfunc(static void no_halt(char *s, int *ints))
......@@ -333,7 +329,4 @@ __initfunc(static void check_bugs(void))
check_amd_k6();
check_pentium_f00f();
system_utsname.machine[1] = '0' + boot_cpu_data.x86;
#if defined(CONFIG_MTRR)
mtrr_init ();
#endif
}
......@@ -12,6 +12,7 @@
#include <linux/config.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/posix_types.h>
#include <linux/nfsd/const.h>
#include <linux/nfsd/export.h>
#include <linux/nfsd/nfsfh.h>
......@@ -54,29 +55,29 @@ struct nfsctl_client {
struct nfsctl_export {
char ex_client[NFSCLNT_IDMAX+1];
char ex_path[NFS_MAXPATHLEN+1];
dev_t ex_dev;
ino_t ex_ino;
__kernel_dev_t ex_dev;
__kernel_ino_t ex_ino;
int ex_flags;
uid_t ex_anon_uid;
gid_t ex_anon_gid;
__kernel_uid_t ex_anon_uid;
__kernel_gid_t ex_anon_gid;
};
/* UGIDUPDATE */
struct nfsctl_uidmap {
char * ug_ident;
uid_t ug_uidbase;
__kernel_uid_t ug_uidbase;
int ug_uidlen;
uid_t * ug_udimap;
uid_t ug_gidbase;
__kernel_uid_t * ug_udimap;
__kernel_gid_t ug_gidbase;
int ug_gidlen;
gid_t * ug_gdimap;
__kernel_gid_t * ug_gdimap;
};
/* GETFH */
struct nfsctl_fhparm {
struct sockaddr gf_addr;
dev_t gf_dev;
ino_t gf_ino;
__kernel_dev_t gf_dev;
__kernel_ino_t gf_ino;
int gf_version;
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -532,6 +532,7 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags)
error = blkdev_open(swap_dentry->d_inode, &filp);
if (error)
goto bad_swap_2;
set_blocksize(p->swap_device, PAGE_SIZE);
error = -ENODEV;
if (!p->swap_device ||
(blk_size[MAJOR(p->swap_device)] &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment