Commit edf3c7a4 authored by Dave Kleikamp's avatar Dave Kleikamp

Add JFS file system

parent a814d16f
......@@ -54,6 +54,7 @@ o binutils 2.9.5.0.25 # ld -v
o util-linux 2.10o # fdformat --version
o modutils 2.4.2 # insmod -V
o e2fsprogs 1.25 # tune2fs
o jfsutils 1.0.14 # fsck.jfs -V
o reiserfsprogs 3.x.0j # reiserfsck 2>&1|grep reiserfsprogs
o pcmcia-cs 3.1.21 # cardmgr -V
o PPP 2.4.0 # pppd --version
......@@ -106,8 +107,8 @@ assembling the 16-bit boot code, removing the need for as86 to compile
your kernel. This change does, however, mean that you need a recent
release of binutils.
System utilities
================
System utililities
==================
Architectural changes
---------------------
......@@ -165,6 +166,16 @@ E2fsprogs
The latest version of e2fsprogs fixes several bugs in fsck and
debugfs. Obviously, it's a good idea to upgrade.
JFSutils
--------
The jfsutils package contains the utilities for the file system.
The following utilities are available:
o fsck.jfs - initiate replay of the transaction log, and check
and repair a JFS formatted partition.
o mkfs.jfs - create a JFS formatted partition.
o other file system utilities are also available in this package.
Reiserfsprogs
-------------
......@@ -303,6 +314,10 @@ E2fsprogs
---------
o <http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.25.tar.gz>
JFSutils
--------
o <http://oss.software.ibm.com/jfs>
Reiserfsprogs
-------------
o <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.0j.tar.gz>
......
......@@ -22,6 +22,8 @@ hpfs.txt
- info and mount options for the OS/2 HPFS.
isofs.txt
- info and mount options for the ISO 9660 (CDROM) filesystem.
jfs.txt
- info and mount options for the JFS filesystem.
ncpfs.txt
- info on Novell Netware(tm) filesystem using NCP protocol.
ntfs.txt
......
IBM's Journaled File System (JFS) for Linux version 1.0.15
Team members
Steve Best sbest@us.ibm.com
Dave Kleikamp shaggy@austin.ibm.com
Barry Arndt barndt@us.ibm.com
Christoph Hellwig hch@caldera.de
Release February 15, 2002 (version 1.0.15)
This is our fifty-third release of IBM's Enterprise JFS technology port to Linux.
Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001,
Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001.
Function and Fixes in drop 53 (1.0.15)
- Fix trap when appending to very large file
- Moving jfs headers into fs/jfs at Linus' request
- Move up to linux-2.5.4
- Fix file size limit on 32-bit (Andi Kleen)
- make changelog more read-able and include only 1.0.0 and above (Christoph Hellwig)
- Don't allocate metadata pages from high memory. JFS keeps them kmapped too long causing deadlock.
- Fix xtree corruption when creating file with >= 64 GB of physically contiguous dasd
- Replace semaphore with struct completion for thread startup/shutdown (Benedikt Spranger)
- cleanup Tx alloc/free (Christoph Hellwig)
- Move up to linux-2.5.3
- thread cleanups (Christoph Hellwig)
- First step toward making tblocks and tlocks dynamically allocated. Intro tid_t and lid_t to
insulate the majority of the code from future changes. Also hide TxBlock and TxLock arrays
by using macros to get from tids and lids to real structures.
- minor list-handling cleanup (Christoph Hellwig)
- Replace altnext and altprev with struct list_head
- Clean up the debugging code and add support for collecting statistics (Christoph Hellwig)
Function and Fixes in drop 52 (1.0.14)
- Fix hang in invalidate_metapages when jfs.o is built as a module
- Fix anon_list removal logic in txLock
Function and Fixes in drop 51 (1.0.13)
- chmod changes on newly created directories are lost after umount (bug 2535)
- Page locking race fixes
- Improve metapage locking
- Fix timing window. Lock page while metapage is active to avoid page going
away before the metadata is released. (Fixed crash during mount/umount testing)
- Make changes for 2.5.2 kernel
- Fix race condition truncating large files
Function and Fixes in drop50 (1.0.12)
- Add O_DIRECT support
- Add support for 2.4.17 kernel
- Make sure COMMIT_STALE gets reset before the inode is unlocked. Fixing
this gets rid of XT_GETPAGE errors
- Remove invalid __exit keyword from metapage_exit and txExit.
- fix assert(log->cqueue.head == NULL by waiting longer
Function and Fixes in drop49 (1.0.11)
- Readdir was not handling multibyte codepages correctly.
- Make mount option parsing more robust.
- Add iocharset mount option.
- Journalling of symlinks incorrect, resulting in logredo failure of -265.
- Add jfsutils information to Changes file
- Improve recoverability of the file system when metadata corruption is detected.
- Fix kernel OOPS when root inode is corrupted
Function and Fixes in drop48 (1.0.10)
- put inodes later on hash queues
- Fix boundary case in xtTruncate
- When invalidating metadata, try to flush the dirty buffers rather than sync them.
- Add another sanity check to avoid trapping when imap is corrupt
- Fix file truncate while removing large file (assert(cmp == 0))
- read_cache_page returns ERR_PTR, not NULL on error
- Add dtSearchNode and dtRelocate
- JFS needs to use generic_file_open & generic_file_llseek
- Remove lazyQwait, etc. It created an unnecessary bottleneck in TxBegin.
Function and Fixes in drop47 (1.0.9)
- Fix data corruption problem when creating files while deleting others. (jitterbug 183)
- Make sure all metadata is written before finalizing the log
- Fix serialization problem in shutdown by setting i_size of directory sooner. (bugzilla #334)
- JFS should quit whining when special files are marked dirty during read-only mount.
- Must always check rc after DT_GETPAGE
- Add diExtendFS
- Removing defconfig form JFS source - not really needed
Function and Fixes in drop46 (1.0.8)
- Synclist was being built backwards causing logredo to quit too early
- jfs_compat.h needs to include module.h
- uncomment EXPORTS_NO_SYMBOLS in super.c
- Minor code cleanup
- xtree of zero-truncated file not being logged
- Fix logging on file truncate
- remove unused metapage fields
Function and Fixes in drop45 (1.0.7)
- cleanup remove IS_KIOBUFIO define.
- cleanup remove TRUNC_NO_TOSS define.
- have jFYI's use the name directly from dentry
- Remove nul _ALLOC and _FREE macros and also make spinlocks static.
- cleanup add externs where needed in the header files
- jfs_write_inode is a bad place to call iput. Also limit warnings.
- More truncate cleanup
- Truncate cleanup
- Add missing statics in jfs_metapage.c
- fsync fixes
- Clean up symlink code - use page_symlink_inode_operations
- unicode handling cleanup
- cleanup replace UniChar with wchar_t
- Get rid of CDLL_* macros - use list.h instead
- 2.4.11-prex mount problem Call new_inode instead of get_empty_inode
- use kernel min/max macros
- Add MODULE_LICENSE stub for older kernels
- IA64/gcc3 fixes
- Log Manager fixes, introduce __SLEEP_COND macro
- Mark superblock dirty when some errors detected (forcing fsck to be run).
- More robust remounting from r/o to r/w.
- Misc. cleanup add static where appropriate
- small cleanup in jfs_umount_rw
- add MODULE_ stuff
- Set *dropped_lock in alloc_metapage
- Get rid of unused log list
- cleanup jfs_imap.c to remove _OLD_STUFF and _NO_MORE_MOUNT_INODE defines
- Log manager cleanup
- Transaction manager cleanup
- correct memory allocations flags
- Better handling of iterative truncation
- Change continue to break, otherwise we don't re-acquire LAZY_LOCK
Function and Fixes in drop44 (1.0.6)
- Create jfs_incore.h which merges linux/jfs_fs.h, linux/jfs_fs_i.h, and jfs_fs_sb.h
- Create a configuration option to handle JFS_DEBUG define
- Fixed a few cases where positive error codes were returned to the VFS.
- Replace jfs_dir_read by generic_read_dir.
- jfs_fsync_inode is only called by jfs_fsync_file, merge the two and rename to jfs_fsync.
- Add a bunch of missing externs.
- jfs_rwlock_lock is unused, nuke it.
- Always use atomic set/test_bit operations to protect jfs_ip->cflag
- Combine jfs_ip->flag with jfs_ip->cflag
- Fixed minor format errors reported by fsck
- cflags should be long so bitops always works correctly
- Use GFP_NOFS for runtime memory allocations
- Support VM changes in 2.4.10 of the kernel
- Remove ifdefs supporting older 2.4 kernels. JFS now requires at least 2.4.3 or 2.4.2-ac2
- Simplify and remove one use of IWRITE_TRYLOCK
- jfs_truncate was not passing tid to xtTruncate
- removed obsolete extent_page workaround
- correct recovery from failed diAlloc call (disk full)
- In write_metapage, don't call commit_write if prepare_write failed
Function and Fixes in drop43 (1.0.5)
- Allow separate allocation of JFS-private superblock/inode data.
- Remove checks in namei.c that are already done by the VFS.
- Remove redundant mutex defines.
- Replace all occurrences of #include <linux/malloc.h> with #include <linux/slab.h>
- Work around race condition in remount -fixes OOPS during shutdown
- Truncate large files incrementally ( affects directories too)
Function and Fixes in drop42 (1.0.4)
- Fixed compiler warnings in the FS when building on 64 bits systems
- Fixed deadlock where jfsCommit hung in hold_metapage
- Fixed problems with remount
- Reserve metapages for jfsCommit thread
- Get rid of buggy invalidate_metapage & use discard_metapage
- Don't hand metapages to jfsIOthread (too many context switches) (jitterbug 125, bugzilla 238)
- Fix error message in jfs_strtoUCS
Function and Fixes in drop41 (1.0.3)
- Patch to move from previous release to latest release needs to update the version number in super.c
- Jitterbug problems (134,140,152) removing files have been fixed
- Set rc=ENOSPC if ialloc fails in jfs_create and jfs_mkdir
- Fixed jfs_txnmgr.c 775! assert
- Fixed jfs_txnmgr.c 884! assert(mp->nohomeok==0)
- Fix hang - prevent tblocks from being exhausted
- Fix oops trying to mount reiserfs
- Fail more gracefully in jfs_imap.c
- Print more information when char2uni fails
- Fix timing problem between Block map and metapage cache - jitterbug 139
- Code Cleanup (removed many ifdef's, obsolete code, ran code through indent) Mostly 2.4 tree
- Split source tree (Now have a separate source tree for 2.2, 2.4, and jfsutils)
Function and Fixes in drop40 (1.0.2)
- Fixed multiple truncate hang
- Fixed hang on unlink a file and sync happening at the same time
- Improved handling of kmalloc error conditions
- Fixed hang in blk_get_queue and SMP deadlock: bh_end_io call generic_make_request
(jitterbug 145 and 146)
- stbl was not set correctly set in dtDelete
- changed trap to printk in dbAllocAG to avoid system hang
Function and Fixes in drop 39 (1.0.1)
- Fixed hang during copying files on 2.2.x series
- Fixed TxLock compile problem
- Fixed to correctly update the number of blocks for directories (this was causing the FS
to show fsck error after compiling mozilla).
- Fixed to prevent old data from being written to disk from the page cache.
Function and Fixes in drop 38 (1.0.0)
- Fixed some general log problems
Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe"
at our web page http://oss.software.ibm.com/jfs/.
IBM's Journaled File System (JFS) for Linux version 1.0.15
Team members
Steve Best sbest@us.ibm.com
Dave Kleikamp shaggy@austin.ibm.com
Barry Arndt barndt@us.ibm.com
Christoph Hellwig hch@caldera.de
Release February 15, 2002 (version 1.0.15)
This is our fifty-third release of IBM's Enterprise JFS technology port to Linux.
Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001,
Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001.
The changelog.jfs file contains detailed information of changes done in each source
code drop.
JFS has a source tree that can be built on 2.4.3 - 2.4.17 and 2.5.4 kernel.org
source trees.
Our current goal on the 2.5.x series of the kernel is to update to the latest
2.5.x version and only support the latest version of this kernel.
This will change when the distros start shipping the 2.5.x series of the kernel.
Our current goal on the 2.4.x series of the kernel is to continue to support
all of the kernels in this series as we do today.
There is an anonymous cvs access available for the JFS tree. The steps below are
what is needed to pull the JFS cvs tree from the oss.software.ibm.com server.
id anoncvs
password anoncvs
To checkout 2.4.x series of the JFS files do the following:
CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
cvs checkout linux24
To checkout 2.5.2 series of the JFS files do the following:
CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
cvs checkout linux25
To checkout the JFS utilities do the following:
CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
cvs checkout jfsutils
The cvs tree contains the latest changes being done to JFS. To receive notification
of commits to the cvs tree, please send e-mail to linuxjfs@us.ibm.com stating that
you would like notifications sent to you.
The jfs-2.4-1.0.15-patch.tar.gz is the easiest way to get the latest file system
source code on your system. There are also patch files that can move your jfs source
code from one release to another. If you have release 1.0.14 and would like to move
to release 1.0.15 the patch file named jfs-2.4-1_0_14-to-1_0_15-patch.gz will do that.
The jfs-2.4-1.0.15-patch.tar.gz file contains a readme and patch files for different
levels of the 2.4 kernel. Please see the README in the jfs-2.4-1.0.15-patch.tar.gz
file for help on applying the two patch files.
The following files in the kernel source tree have been changed so JFS can be built.
The jfs-2.4-1.0.15.tar.gz source tar ball contains each of the files below with
the extension of the kernel level it is associated with. As an example, there are now
four Config.in files named Config.in-2.4.0, Config.in-2.4.5, Config.in-2.4.7 and
Config.in-2.4.17.
If you use the jfs-2.4-1.0.15.tar.gz to build JFS you must rename each of the
kernel files to the file names listed below. The standard kernel from www.kernel.org
is the source of the kernel files that are included in the jfs tar file.
In sub dir fs Config.in, Makefile
In sub dir fs/nls Config.in
In sub dir Documentation Configure.help, Changes
In sub dir Documentation/filesystems 00-INDEX
In sub dir linux MAINTAINERS
Please backup the above files before the JFS tar file is added to the kernel source
tree. All JFS files are located in the include/linux/jfs or fs/jfs sub dirs.
Our development team has used the Linux kernel levels 2.4.3 - 2.4.17 kernels
with gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
for our port so far. A goal of the JFS team is to have JFS run on all architectures
that Linux supports, there is no architecture specific code in JFS. JFS has been run
on the following architectures (x86, PowerPC, Alpha, s/390, ARM) so far.
To make JFS build, during the "make config" step of building the kernel answer y to
the Prompt for development and/or incomplete code/drivers in the Code maturity level
options section. In the Filesystems section use the m for the answer to
JFS filesystem support (experimental) (CONFIG_JFS_FS) [Y/m/n?]
Build in /usr/src/linux with the command:
make modules
make modules_install
If you rebuild jfs.o after having mounted and unmounted a partition, "modprobe -r jfs"
will unload the old module.
For the file system debugging messages are being written to /var/log/messages.
Please see the readme in the utilities package for information about building
the JFS utilities.
JFS TODO list:
Plans for our near term development items
- get defrag capabilities operational in the FS
- get extendfs capabilities operational in the FS
- test EXTENDFS utility, for growing JFS partitions
- test defrag utility, calls file system to defrag the file system.
- add support for block sizes (512,1024,2048)
- add support for logfile on dedicated partition
Longer term work items
- get access control list functionality operational
- get extended attributes functionality operational
- add quota support
Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe"
at our web page http://oss.software.ibm.com/jfs/.
......@@ -852,6 +852,13 @@ L: jffs-dev@axis.com
W: http://sources.redhat.com/jffs2/
S: Maintained
JFS FILESYSTEM
P: Dave Kleikamp
M: shaggy@austin.ibm.com
L: jfs-discussion@oss.software.ibm.com
W: http://oss.software.ibm.com/jfs/
S: Supported
JOYSTICK DRIVER
P: Vojtech Pavlik
M: vojtech@suse.cz
......
......@@ -859,6 +859,25 @@ CONFIG_ADFS_FS_RW
hard drives and ADFS-formatted floppy disks. This is experimental
codes, so if you're unsure, say N.
JFS filesystem support
CONFIG_JFS_FS
This is a port of IBM's Journaled Filesystem . More information is
available in the file Documentation/filesystems/jfs.txt.
If you do not intend to use the JFS filesystem, say N.
JFS Debugging
CONFIG_JFS_DEBUG
If you are experiencing any problems with the JFS filesystem, say
Y here. This will result in additional debugging messages to be
written to the system log. Under normal circumstances, this
results in very little overhead.
JFS Statistics
CONFIG_JFS_STATISTICS
Enabling this option will cause statistics from the JFS file system
to be made available to the user in the /proc/fs/jfs/ directory.
CONFIG_DEVPTS_FS
You should say Y here if you said Y to "Unix98 PTY support" above.
You'll then get a virtual file system which can be mounted on
......
......@@ -54,6 +54,10 @@ tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS
dep_mbool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS
dep_mbool ' Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS
tristate 'JFS filesystem support' CONFIG_JFS_FS
dep_mbool ' JFS debugging' CONFIG_JFS_DEBUG $CONFIG_JFS_FS
dep_mbool ' JFS statistics' CONFIG_JFS_STATISTICS $CONFIG_JFS_FS
tristate 'Minix fs support' CONFIG_MINIX_FS
tristate 'FreeVxFS file system support (VERITAS VxFS(TM) compatible)' CONFIG_VXFS_FS
......
......@@ -67,6 +67,7 @@ subdir-$(CONFIG_ADFS_FS) += adfs
subdir-$(CONFIG_REISERFS_FS) += reiserfs
subdir-$(CONFIG_DEVPTS_FS) += devpts
subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs
subdir-$(CONFIG_JFS_FS) += jfs
obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o
......
#
# Makefile for the Linux JFS 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 (not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile.
O_TARGET := jfs.o
obj-y := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \
jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \
jfs_unicode.o jfs_dtree.o jfs_inode.o \
jfs_extent.o symlink.o jfs_metapage.o \
jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o
obj-m := $(O_TARGET)
EXTRA_CFLAGS += -D_JFS_4K
include $(TOPDIR)/Rules.make
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_ENDIAN24
#define _H_ENDIAN24
/*
* fs/jfs/endian24.h:
*
* Endian conversion for 24-byte data
*
*/
#define __swab24(x) \
({ \
__u32 __x = (x); \
((__u32)( \
((__x & (__u32)0x000000ffUL) << 16) | \
(__x & (__u32)0x0000ff00UL) | \
((__x & (__u32)0x00ff0000UL) >> 16) )); \
})
#if (defined(__KERNEL__) && defined(__LITTLE_ENDIAN)) || (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN))
#define __cpu_to_le24(x) ((__u32)(x))
#define __le24_to_cpu(x) ((__u32)(x))
#else
#define __cpu_to_le24(x) __swab24(x)
#define __le24_to_cpu(x) __swab24(x)
#endif
#ifdef __KERNEL__
#define cpu_to_le24 __cpu_to_le24
#define le24_to_cpu __le24_to_cpu
#endif
#endif /* !_H_ENDIAN24 */
/*
*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
#include <linux/locks.h>
#include "jfs_incore.h"
#include "jfs_txnmgr.h"
#include "jfs_debug.h"
extern int generic_file_open(struct inode *, struct file *);
extern loff_t generic_file_llseek(struct file *, loff_t, int origin);
extern int jfs_commit_inode(struct inode *, int);
int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
{
struct inode *inode = dentry->d_inode;
int rc = 0;
rc = fsync_inode_data_buffers(inode);
if (!(inode->i_state & I_DIRTY))
return rc;
if (datasync || !(inode->i_state & I_DIRTY_DATASYNC))
return rc;
IWRITE_LOCK(inode);
rc |= jfs_commit_inode(inode, 1);
IWRITE_UNLOCK(inode);
return rc ? -EIO : 0;
}
struct file_operations jfs_file_operations = {
open: generic_file_open,
llseek: generic_file_llseek,
write: generic_file_write,
read: generic_file_read,
mmap: generic_file_mmap,
fsync: jfs_fsync,
};
/*
* Guts of jfs_truncate. Called with locks already held. Can be called
* with directory for truncating directory index table.
*/
void jfs_truncate_nolock(struct inode *ip, loff_t length)
{
loff_t newsize;
tid_t tid;
ASSERT(length >= 0);
if (test_cflag(COMMIT_Nolink, ip)) {
xtTruncate(0, ip, length, COMMIT_WMAP);
return;
}
do {
tid = txBegin(ip->i_sb, 0);
newsize = xtTruncate(tid, ip, length,
COMMIT_TRUNCATE | COMMIT_PWMAP);
if (newsize < 0) {
txEnd(tid);
break;
}
ip->i_mtime = ip->i_ctime = CURRENT_TIME;
mark_inode_dirty(ip);
txCommit(tid, 1, &ip, 0);
txEnd(tid);
} while (newsize > length); /* Truncate isn't always atomic */
}
static void jfs_truncate(struct inode *ip)
{
jFYI(1, ("jfs_truncate: size = 0x%lx\n", (ulong) ip->i_size));
IWRITE_LOCK(ip);
jfs_truncate_nolock(ip, ip->i_size);
IWRITE_UNLOCK(ip);
}
struct inode_operations jfs_file_inode_operations = {
truncate: jfs_truncate,
};
/*
*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
#include <linux/locks.h>
#include <linux/slab.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_imap.h"
#include "jfs_extent.h"
#include "jfs_unicode.h"
#include "jfs_debug.h"
extern struct inode_operations jfs_dir_inode_operations;
extern struct inode_operations jfs_file_inode_operations;
extern struct inode_operations jfs_symlink_inode_operations;
extern struct file_operations jfs_dir_operations;
extern struct file_operations jfs_file_operations;
struct address_space_operations jfs_aops;
extern int freeZeroLink(struct inode *);
void jfs_put_inode(struct inode *inode)
{
jFYI(1, ("In jfs_put_inode, inode = 0x%p\n", inode));
}
void jfs_read_inode(struct inode *inode)
{
jFYI(1, ("In jfs_read_inode, inode = 0x%p\n", inode));
if (diRead(inode))
goto bad_inode;
if (S_ISREG(inode->i_mode)) {
inode->i_op = &jfs_file_inode_operations;
inode->i_fop = &jfs_file_operations;
inode->i_mapping->a_ops = &jfs_aops;
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &jfs_dir_inode_operations;
inode->i_fop = &jfs_dir_operations;
inode->i_mapping->a_ops = &jfs_aops;
inode->i_mapping->gfp_mask = GFP_NOFS;
} else if (S_ISLNK(inode->i_mode)) {
if (inode->i_size > IDATASIZE) {
inode->i_op = &page_symlink_inode_operations;
inode->i_mapping->a_ops = &jfs_aops;
} else
inode->i_op = &jfs_symlink_inode_operations;
} else {
init_special_inode(inode, inode->i_mode,
kdev_t_to_nr(inode->i_rdev));
}
return;
bad_inode:
make_bad_inode(inode);
}
/* This define is from fs/open.c */
#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
/*
* Workhorse of both fsync & write_inode
*/
int jfs_commit_inode(struct inode *inode, int wait)
{
int rc = 0;
tid_t tid;
static int noisy = 5;
jFYI(1, ("In jfs_commit_inode, inode = 0x%p\n", inode));
/*
* Don't commit if inode has been committed since last being
* marked dirty, or if it has been deleted.
*/
if (test_cflag(COMMIT_Nolink, inode) ||
!test_cflag(COMMIT_Dirty, inode))
return 0;
if (isReadOnly(inode)) {
/* kernel allows writes to devices on read-only
* partitions and may think inode is dirty
*/
if (!special_file(inode->i_mode) && noisy) {
jERROR(1, ("jfs_commit_inode(0x%p) called on "
"read-only volume\n", inode));
jERROR(1, ("Is remount racy?\n"));
noisy--;
}
return 0;
}
tid = txBegin(inode->i_sb, COMMIT_INODE);
rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
txEnd(tid);
return -rc;
}
void jfs_write_inode(struct inode *inode, int wait)
{
/*
* If COMMIT_DIRTY is not set, the inode isn't really dirty.
* It has been committed since the last change, but was still
* on the dirty inode list
*/
if (test_cflag(COMMIT_Nolink, inode) ||
!test_cflag(COMMIT_Dirty, inode))
return;
IWRITE_LOCK(inode);
if (jfs_commit_inode(inode, wait)) {
jERROR(1, ("jfs_write_inode: jfs_commit_inode failed!\n"));
}
IWRITE_UNLOCK(inode);
}
void jfs_delete_inode(struct inode *inode)
{
jFYI(1, ("In jfs_delete_inode, inode = 0x%p\n", inode));
IWRITE_LOCK(inode);
if (test_cflag(COMMIT_Freewmap, inode))
freeZeroLink(inode);
diFree(inode);
IWRITE_UNLOCK(inode);
clear_inode(inode);
}
void jfs_dirty_inode(struct inode *inode)
{
static int noisy = 5;
if (isReadOnly(inode)) {
if (!special_file(inode->i_mode) && noisy) {
/* kernel allows writes to devices on read-only
* partitions and may try to mark inode dirty
*/
jERROR(1, ("jfs_dirty_inode called on "
"read-only volume\n"));
jERROR(1, ("Is remount racy?\n"));
noisy--;
}
return;
}
set_cflag(COMMIT_Dirty, inode);
}
static int jfs_get_block(struct inode *ip, sector_t lblock,
struct buffer_head *bh_result, int create)
{
s64 lblock64 = lblock;
int no_size_check = 0;
int rc = 0;
int take_locks;
xad_t xad;
s64 xaddr;
int xflag;
s32 xlen;
/*
* If this is a special inode (imap, dmap) or directory,
* the lock should already be taken
*/
take_locks = ((JFS_IP(ip)->fileset != AGGREGATE_I) &&
!S_ISDIR(ip->i_mode));
/*
* Take appropriate lock on inode
*/
if (take_locks) {
if (create)
IWRITE_LOCK(ip);
else
IREAD_LOCK(ip);
}
/*
* A directory's "data" is the inode index table, but i_size is the
* size of the d-tree, so don't check the offset against i_size
*/
if (S_ISDIR(ip->i_mode))
no_size_check = 1;
if ((no_size_check ||
((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size)) &&
(xtLookup
(ip, lblock64, 1, &xflag, &xaddr, &xlen, no_size_check)
== 0) && xlen) {
if (xflag & XAD_NOTRECORDED) {
if (!create)
/*
* Allocated but not recorded, read treats
* this as a hole
*/
goto unlock;
#ifdef _JFS_4K
XADoffset(&xad, lblock64);
XADlength(&xad, xlen);
XADaddress(&xad, xaddr);
#else /* _JFS_4K */
/*
* As long as block size = 4K, this isn't a problem.
* We should mark the whole page not ABNR, but how
* will we know to mark the other blocks BH_New?
*/
BUG();
#endif /* _JFS_4K */
rc = extRecord(ip, &xad);
if (rc)
goto unlock;
bh_result->b_state |= (1UL << BH_New);
}
map_bh(bh_result, ip->i_sb, xaddr);
goto unlock;
}
if (!create)
goto unlock;
/*
* Allocate a new block
*/
#ifdef _JFS_4K
if ((rc =
extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
goto unlock;
rc = extAlloc(ip, 1, lblock64, &xad, FALSE);
if (rc)
goto unlock;
bh_result->b_state |= (1UL << BH_New);
map_bh(bh_result, ip->i_sb, addressXAD(&xad));
#else /* _JFS_4K */
/*
* We need to do whatever it takes to keep all but the last buffers
* in 4K pages - see jfs_write.c
*/
BUG();
#endif /* _JFS_4K */
unlock:
/*
* Release lock on inode
*/
if (take_locks) {
if (create)
IWRITE_UNLOCK(ip);
else
IREAD_UNLOCK(ip);
}
return -rc;
}
static int jfs_writepage(struct page *page)
{
return block_write_full_page(page, jfs_get_block);
}
static int jfs_readpage(struct file *file, struct page *page)
{
return block_read_full_page(page, jfs_get_block);
}
static int jfs_prepare_write(struct file *file,
struct page *page, unsigned from, unsigned to)
{
return block_prepare_write(page, from, to, jfs_get_block);
}
static int jfs_bmap(struct address_space *mapping, long block)
{
return generic_block_bmap(mapping, block, jfs_get_block);
}
static int jfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
unsigned long blocknr, int blocksize)
{
return generic_direct_IO(rw, inode, iobuf, blocknr,
blocksize, jfs_get_block);
}
struct address_space_operations jfs_aops = {
readpage: jfs_readpage,
writepage: jfs_writepage,
sync_page: block_sync_page,
prepare_write: jfs_prepare_write,
commit_write: generic_commit_write,
bmap: jfs_bmap,
direct_IO: jfs_direct_IO,
};
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _H_JFS_BTREE
#define _H_JFS_BTREE
/*
* jfs_btree.h: B+-tree
*
* JFS B+-tree (dtree and xtree) common definitions
*/
/*
* basic btree page - btpage_t
*/
typedef struct {
s64 next; /* 8: right sibling bn */
s64 prev; /* 8: left sibling bn */
u8 flag; /* 1: */
u8 rsrvd[7]; /* 7: type specific */
s64 self; /* 8: self address */
u8 entry[4064]; /* 4064: */
} btpage_t; /* (4096) */
/* btpaget_t flag */
#define BT_TYPE 0x07 /* B+-tree index */
#define BT_ROOT 0x01 /* root page */
#define BT_LEAF 0x02 /* leaf page */
#define BT_INTERNAL 0x04 /* internal page */
#define BT_RIGHTMOST 0x10 /* rightmost page */
#define BT_LEFTMOST 0x20 /* leftmost page */
#define BT_SWAPPED 0x80 /* used by fsck for endian swapping */
/* btorder (in inode) */
#define BT_RANDOM 0x0000
#define BT_SEQUENTIAL 0x0001
#define BT_LOOKUP 0x0010
#define BT_INSERT 0x0020
#define BT_DELETE 0x0040
/*
* btree page buffer cache access
*/
#define BT_IS_ROOT(MP) (((MP)->xflag & COMMIT_PAGE) == 0)
/* get page from buffer page */
#define BT_PAGE(IP, MP, TYPE, ROOT)\
(BT_IS_ROOT(MP) ? (TYPE *)&JFS_IP(IP)->ROOT : (TYPE *)(MP)->data)
/* get the page buffer and the page for specified block address */
#define BT_GETPAGE(IP, BN, MP, TYPE, SIZE, P, RC, ROOT)\
{\
if ((BN) == 0)\
{\
MP = (metapage_t *)&JFS_IP(IP)->bxflag;\
P = (TYPE *)&JFS_IP(IP)->ROOT;\
RC = 0;\
jEVENT(0,("%d BT_GETPAGE returning root\n", __LINE__));\
}\
else\
{\
jEVENT(0,("%d BT_GETPAGE reading block %d\n", __LINE__,\
(int)BN));\
MP = read_metapage((IP), BN, SIZE, 1);\
if (MP) {\
RC = 0;\
P = (MP)->data;\
} else {\
P = NULL;\
jERROR(1,("bread failed!\n"));\
RC = EIO;\
}\
}\
}
#define BT_MARK_DIRTY(MP, IP)\
{\
if (BT_IS_ROOT(MP))\
mark_inode_dirty(IP);\
else\
mark_metapage_dirty(MP);\
}
/* put the page buffer */
#define BT_PUTPAGE(MP)\
{\
if (! BT_IS_ROOT(MP)) \
release_metapage(MP); \
}
/*
* btree traversal stack
*
* record the path traversed during the search;
* top frame record the leaf page/entry selected.
*/
#define MAXTREEHEIGHT 8
typedef struct btframe { /* stack frame */
s64 bn; /* 8: */
s16 index; /* 2: */
s16 lastindex; /* 2: */
struct metapage *mp; /* 4: */
} btframe_t; /* (16) */
typedef struct btstack {
btframe_t *top; /* 4: */
int nsplit; /* 4: */
btframe_t stack[MAXTREEHEIGHT];
} btstack_t;
#define BT_CLR(btstack)\
(btstack)->top = (btstack)->stack
#define BT_PUSH(BTSTACK, BN, INDEX)\
{\
(BTSTACK)->top->bn = BN;\
(BTSTACK)->top->index = INDEX;\
++(BTSTACK)->top;\
assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\
}
#define BT_POP(btstack)\
( (btstack)->top == (btstack)->stack ? NULL : --(btstack)->top )
#define BT_STACK(btstack)\
( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top )
/* retrieve search results */
#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
{\
BN = (LEAF)->bn;\
MP = (LEAF)->mp;\
if (BN)\
P = (TYPE *)MP->data;\
else\
P = (TYPE *)&JFS_IP(IP)->ROOT;\
INDEX = (LEAF)->index;\
}
/* put the page buffer of search */
#define BT_PUTSEARCH(BTSTACK)\
{\
if (! BT_IS_ROOT((BTSTACK)->top->mp))\
release_metapage((BTSTACK)->top->mp);\
}
#endif /* _H_JFS_BTREE */
/*
*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_debug.h"
#ifdef CONFIG_JFS_DEBUG
void dump_mem(char *label, void *data, int length)
{
int i, j;
int *intptr = data;
char *charptr = data;
char buf[10], line[80];
printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length,
data);
for (i = 0; i < length; i += 16) {
line[0] = 0;
for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
sprintf(buf, " %08x", intptr[i / 4 + j]);
strcat(line, buf);
}
buf[0] = ' ';
buf[2] = 0;
for (j = 0; (j < 16) && (i + j < length); j++) {
buf[1] =
isprint(charptr[i + j]) ? charptr[i + j] : '.';
strcat(line, buf);
}
printk("%s\n", line);
}
}
#ifdef CONFIG_PROC_FS
static int loglevel_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len;
len = sprintf(page, "%d\n", jfsloglevel);
len -= off;
*start = page + off;
if (len > count)
len = count;
else
*eof = 1;
if (len < 0)
len = 0;
return len;
}
static int loglevel_write(struct file *file, const char *buffer,
unsigned long count, void *data)
{
char c;
if (get_user(c, buffer))
return -EFAULT;
/* yes, I know this is an ASCIIism. --hch */
if (c < '0' || c > '9')
return -EINVAL;
jfsloglevel = c - '0';
return count;
}
extern read_proc_t jfs_txanchor_read;
#ifdef CONFIG_JFS_STATISTICS
extern read_proc_t jfs_lmstats_read;
extern read_proc_t jfs_xtstat_read;
extern read_proc_t jfs_mpstat_read;
#endif
static struct proc_dir_entry *base;
static struct {
const char *name;
read_proc_t *read_fn;
write_proc_t *write_fn;
} Entries[] = {
{ "TxAnchor", jfs_txanchor_read, },
#ifdef CONFIG_JFS_STATISTICS
{ "lmstats", jfs_lmstats_read, },
{ "xtstat", jfs_xtstat_read, },
{ "mpstat", jfs_mpstat_read, },
#endif
{ "loglevel", loglevel_read, loglevel_write }
};
#define NPROCENT (sizeof(Entries)/sizeof(Entries[0]))
void jfs_proc_init(void)
{
int i;
if (!(base = proc_mkdir("jfs", proc_root_fs)))
return;
base->owner = THIS_MODULE;
for (i = 0; i < NPROCENT; i++) {
struct proc_dir_entry *p;
if ((p = create_proc_entry(Entries[i].name, 0, base))) {
p->read_proc = Entries[i].read_fn;
p->write_proc = Entries[i].write_fn;
}
}
}
void jfs_proc_clean(void)
{
int i;
if (base) {
for (i = 0; i < NPROCENT; i++)
remove_proc_entry(Entries[i].name, base);
remove_proc_entry("jfs", base);
}
}
#endif /* CONFIG_PROC_FS */
#endif /* CONFIG_JFS_DEBUG */
/*
*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _H_JFS_DEBUG
#define _H_JFS_DEBUG
/*
* jfs_debug.h
*
* global debug message, data structure/macro definitions
* under control of CONFIG_JFS_DEBUG, CONFIG_JFS_STATISTICS;
*/
/*
* assert with traditional printf/panic
*/
#ifdef CONFIG_KERNEL_ASSERTS
/* kgdb stuff */
#define assert(p) KERNEL_ASSERT(#p, p)
#else
#define assert(p) {\
if (!(p))\
{\
printk("assert(%s)\n",#p);\
BUG();\
}\
}
#endif
/*
* debug ON
* --------
*/
#ifdef CONFIG_JFS_DEBUG
#define ASSERT(p) assert(p)
/* dump memory contents */
extern void dump_mem(char *label, void *data, int length);
extern int jfsloglevel;
/* information message: e.g., configuration, major event */
#define jFYI(button, prspec) \
do { if (button && jfsloglevel > 1) printk prspec; } while (0)
/* error event message: e.g., i/o error */
extern int jfsERROR;
#define jERROR(button, prspec) \
do { if (button && jfsloglevel > 0) { printk prspec; } } while (0)
/* debug event message: */
#define jEVENT(button,prspec) \
do { if (button) printk prspec; } while (0)
/*
* debug OFF
* ---------
*/
#else /* CONFIG_JFS_DEBUG */
#define dump_mem(label,data,length)
#define ASSERT(p)
#define jEVENT(button,prspec)
#define jERROR(button,prspec)
#define jFYI(button,prspec)
#endif /* CONFIG_JFS_DEBUG */
/*
* statistics
* ----------
*/
#ifdef CONFIG_JFS_STATISTICS
#define INCREMENT(x) ((x)++)
#define DECREMENT(x) ((x)--)
#define HIGHWATERMARK(x,y) ((x) = max((x), (y)))
#else
#define INCREMENT(x)
#define DECREMENT(x)
#define HIGHWATERMARK(x,y)
#endif /* CONFIG_JFS_STATISTICS */
#endif /* _H_JFS_DEBUG */
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _H_JFS_DEFRAGFS
#define _H_JFS_DEFRAGFS
/*
* jfs_defragfs.h
*/
/*
* defragfs parameter list
*/
typedef struct {
uint flag; /* 4: */
u8 dev; /* 1: */
u8 pad[3]; /* 3: */
s32 fileset; /* 4: */
u32 inostamp; /* 4: */
u32 ino; /* 4: */
u32 gen; /* 4: */
s64 xoff; /* 8: */
s64 old_xaddr; /* 8: */
s64 new_xaddr; /* 8: */
s32 xlen; /* 4: */
} defragfs_t; /* (52) */
/* plist flag */
#define DEFRAGFS_SYNC 0x80000000
#define DEFRAGFS_COMMIT 0x40000000
#define DEFRAGFS_RELOCATE 0x10000000
#define INODE_TYPE 0x0000F000 /* IFREG or IFDIR */
#define EXTENT_TYPE 0x000000ff
#define DTPAGE 0x00000001
#define XTPAGE 0x00000002
#define DATAEXT 0x00000004
#define EAEXT 0x00000008
#endif /* _H_JFS_DEFRAGFS */
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _H_JFS_DINODE
#define _H_JFS_DINODE
/*
* jfs_dinode.h: on-disk inode manager
*
*/
#define INODESLOTSIZE 128
#define L2INODESLOTSIZE 7
#define log2INODESIZE 9 /* log2(bytes per dinode) */
/*
* on-disk inode (dinode_t): 512 bytes
*
* note: align 64-bit fields on 8-byte boundary.
*/
struct dinode {
/*
* I. base area (128 bytes)
* ------------------------
*
* define generic/POSIX attributes
*/
u32 di_inostamp; /* 4: stamp to show inode belongs to fileset */
s32 di_fileset; /* 4: fileset number */
u32 di_number; /* 4: inode number, aka file serial number */
u32 di_gen; /* 4: inode generation number */
pxd_t di_ixpxd; /* 8: inode extent descriptor */
s64 di_size; /* 8: size */
s64 di_nblocks; /* 8: number of blocks allocated */
u32 di_nlink; /* 4: number of links to the object */
u32 di_uid; /* 4: user id of owner */
u32 di_gid; /* 4: group id of owner */
u32 di_mode; /* 4: attribute, format and permission */
struct timestruc_t di_atime; /* 8: time last data accessed */
struct timestruc_t di_ctime; /* 8: time last status changed */
struct timestruc_t di_mtime; /* 8: time last data modified */
struct timestruc_t di_otime; /* 8: time created */
dxd_t di_acl; /* 16: acl descriptor */
dxd_t di_ea; /* 16: ea descriptor */
u32 di_next_index; /* 4: Next available dir_table index */
s32 di_acltype; /* 4: Type of ACL */
/*
* Extension Areas.
*
* Historically, the inode was partitioned into 4 128-byte areas,
* the last 3 being defined as unions which could have multiple
* uses. The first 96 bytes had been completely unused until
* an index table was added to the directory. It is now more
* useful to describe the last 3/4 of the inode as a single
* union. We would probably be better off redesigning the
* entire structure from scratch, but we don't want to break
* commonality with OS/2's JFS at this time.
*/
union {
struct {
/*
* This table contains the information needed to
* find a directory entry from a 32-bit index.
* If the index is small enough, the table is inline,
* otherwise, an x-tree root overlays this table
*/
dir_table_slot_t _table[12]; /* 96: inline */
dtroot_t _dtroot; /* 288: dtree root */
} _dir; /* (384) */
#define di_dirtable u._dir._table
#define di_dtroot u._dir._dtroot
#define di_parent di_dtroot.header.idotdot
#define di_DASD di_dtroot.header.DASD
struct {
union {
u8 _data[96]; /* 96: unused */
struct {
void *_imap; /* 4: unused */
u32 _gengen; /* 4: generator */
} _imap;
} _u1; /* 96: */
#define di_gengen u._file._u1._imap._gengen
union {
xtpage_t _xtroot;
struct {
u8 unused[16]; /* 16: */
dxd_t _dxd; /* 16: */
union {
u32 _rdev; /* 4: */
u8 _fastsymlink[128];
} _u;
u8 _inlineea[128];
} _special;
} _u2;
} _file;
#define di_xtroot u._file._u2._xtroot
#define di_dxd u._file._u2._special._dxd
#define di_btroot di_xtroot
#define di_inlinedata u._file._u2._special._u
#define di_rdev u._file._u2._special._u._rdev
#define di_fastsymlink u._file._u2._special._u._fastsymlink
#define di_inlineea u._file._u2._special._inlineea
} u;
};
typedef struct dinode dinode_t;
/* extended mode bits (on-disk inode di_mode) */
#define IFJOURNAL 0x00010000 /* journalled file */
#define ISPARSE 0x00020000 /* sparse file enabled */
#define INLINEEA 0x00040000 /* inline EA area free */
#define ISWAPFILE 0x00800000 /* file open for pager swap space */
/* more extended mode bits: attributes for OS/2 */
#define IREADONLY 0x02000000 /* no write access to file */
#define IARCHIVE 0x40000000 /* file archive bit */
#define ISYSTEM 0x08000000 /* system file */
#define IHIDDEN 0x04000000 /* hidden file */
#define IRASH 0x4E000000 /* mask for changeable attributes */
#define INEWNAME 0x80000000 /* non-8.3 filename format */
#define IDIRECTORY 0x20000000 /* directory (shadow of real bit) */
#define ATTRSHIFT 25 /* bits to shift to move attribute
specification to mode position */
#endif /*_H_JFS_DINODE */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Change History :
*
*/
#ifndef _H_JFS_DTREE
#define _H_JFS_DTREE
/*
* jfs_dtree.h: directory B+-tree manager
*/
#include "jfs_btree.h"
typedef union {
struct {
tid_t tid;
struct inode *ip;
u32 ino;
} leaf;
pxd_t xd;
} ddata_t;
/*
* entry segment/slot
*
* an entry consists of type dependent head/only segment/slot and
* additional segments/slots linked vi next field;
* N.B. last/only segment of entry is terminated by next = -1;
*/
/*
* directory page slot
*/
typedef struct {
s8 next; /* 1: */
s8 cnt; /* 1: */
wchar_t name[15]; /* 30: */
} dtslot_t; /* (32) */
#define DATASLOTSIZE 16
#define L2DATASLOTSIZE 4
#define DTSLOTSIZE 32
#define L2DTSLOTSIZE 5
#define DTSLOTHDRSIZE 2
#define DTSLOTDATASIZE 30
#define DTSLOTDATALEN 15
/*
* internal node entry head/only segment
*/
typedef struct {
pxd_t xd; /* 8: child extent descriptor */
s8 next; /* 1: */
u8 namlen; /* 1: */
wchar_t name[11]; /* 22: 2-byte aligned */
} idtentry_t; /* (32) */
#define DTIHDRSIZE 10
#define DTIHDRDATALEN 11
/* compute number of slots for entry */
#define NDTINTERNAL(klen) ( ((4 + (klen)) + (15 - 1)) / 15 )
/*
* leaf node entry head/only segment
*
* For legacy filesystems, name contains 13 wchars -- no index field
*/
typedef struct {
u32 inumber; /* 4: 4-byte aligned */
s8 next; /* 1: */
u8 namlen; /* 1: */
wchar_t name[11]; /* 22: 2-byte aligned */
u32 index; /* 4: index into dir_table */
} ldtentry_t; /* (32) */
#define DTLHDRSIZE 6
#define DTLHDRDATALEN_LEGACY 13 /* Old (OS/2) format */
#define DTLHDRDATALEN 11
/*
* dir_table used for directory traversal during readdir
*/
/*
* Keep persistent index for directory entries
*/
#define DO_INDEX(INODE) (JFS_SBI((INODE)->i_sb)->mntflag & JFS_DIR_INDEX)
/*
* Maximum entry in inline directory table
*/
#define MAX_INLINE_DIRTABLE_ENTRY 13
typedef struct dir_table_slot {
u8 rsrvd; /* 1: */
u8 flag; /* 1: 0 if free */
u8 slot; /* 1: slot within leaf page of entry */
u8 addr1; /* 1: upper 8 bits of leaf page address */
u32 addr2; /* 4: lower 32 bits of leaf page address -OR-
index of next entry when this entry was deleted */
} dir_table_slot_t; /* (8) */
/*
* flag values
*/
#define DIR_INDEX_VALID 1
#define DIR_INDEX_FREE 0
#define DTSaddress(dir_table_slot, address64)\
{\
(dir_table_slot)->addr1 = ((u64)address64) >> 32;\
(dir_table_slot)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
}
#define addressDTS(dts)\
( ((s64)((dts)->addr1)) << 32 | __le32_to_cpu((dts)->addr2) )
/* compute number of slots for entry */
#define NDTLEAF_LEGACY(klen) ( ((2 + (klen)) + (15 - 1)) / 15 )
#define NDTLEAF NDTINTERNAL
/*
* directory root page (in-line in on-disk inode):
*
* cf. dtpage_t below.
*/
typedef union {
struct {
dasd_t DASD; /* 16: DASD limit/usage info F226941 */
u8 flag; /* 1: */
u8 nextindex; /* 1: next free entry in stbl */
s8 freecnt; /* 1: free count */
s8 freelist; /* 1: freelist header */
u32 idotdot; /* 4: parent inode number */
s8 stbl[8]; /* 8: sorted entry index table */
} header; /* (32) */
dtslot_t slot[9];
} dtroot_t;
#define PARENT(IP) \
(le32_to_cpu(JFS_IP(IP)->i_dtroot.header.idotdot))
#define DTROOTMAXSLOT 9
#define dtEmpty(IP) (JFS_IP(IP)->i_dtroot.header.nextindex == 0)
/*
* directory regular page:
*
* entry slot array of 32 byte slot
*
* sorted entry slot index table (stbl):
* contiguous slots at slot specified by stblindex,
* 1-byte per entry
* 512 byte block: 16 entry tbl (1 slot)
* 1024 byte block: 32 entry tbl (1 slot)
* 2048 byte block: 64 entry tbl (2 slot)
* 4096 byte block: 128 entry tbl (4 slot)
*
* data area:
* 512 byte block: 16 - 2 = 14 slot
* 1024 byte block: 32 - 2 = 30 slot
* 2048 byte block: 64 - 3 = 61 slot
* 4096 byte block: 128 - 5 = 123 slot
*
* N.B. index is 0-based; index fields refer to slot index
* except nextindex which refers to entry index in stbl;
* end of entry stot list or freelist is marked with -1.
*/
typedef union {
struct {
s64 next; /* 8: next sibling */
s64 prev; /* 8: previous sibling */
u8 flag; /* 1: */
u8 nextindex; /* 1: next entry index in stbl */
s8 freecnt; /* 1: */
s8 freelist; /* 1: slot index of head of freelist */
u8 maxslot; /* 1: number of slots in page slot[] */
u8 stblindex; /* 1: slot index of start of stbl */
u8 rsrvd[2]; /* 2: */
pxd_t self; /* 8: self pxd */
} header; /* (32) */
dtslot_t slot[128];
} dtpage_t;
#define DTPAGEMAXSLOT 128
#define DT8THPGNODEBYTES 512
#define DT8THPGNODETSLOTS 1
#define DT8THPGNODESLOTS 16
#define DTQTRPGNODEBYTES 1024
#define DTQTRPGNODETSLOTS 1
#define DTQTRPGNODESLOTS 32
#define DTHALFPGNODEBYTES 2048
#define DTHALFPGNODETSLOTS 2
#define DTHALFPGNODESLOTS 64
#define DTFULLPGNODEBYTES 4096
#define DTFULLPGNODETSLOTS 4
#define DTFULLPGNODESLOTS 128
#define DTENTRYSTART 1
/* get sorted entry table of the page */
#define DT_GETSTBL(p) ( ((p)->header.flag & BT_ROOT) ?\
((dtroot_t *)(p))->header.stbl : \
(s8 *)&(p)->slot[(p)->header.stblindex] )
/*
* Flags for dtSearch
*/
#define JFS_CREATE 1
#define JFS_LOOKUP 2
#define JFS_REMOVE 3
#define JFS_RENAME 4
#define DIRENTSIZ(namlen) \
( (sizeof(struct dirent) - 2*(JFS_NAME_MAX+1) + 2*((namlen)+1) + 3) &~ 3 )
/*
* external declarations
*/
extern void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot);
extern int dtSearch(struct inode *ip, component_t * key,
ino_t * data, btstack_t * btstack, int flag);
extern int dtInsert(tid_t tid, struct inode *ip,
component_t * key, ino_t * ino, btstack_t * btstack);
extern int dtDelete(tid_t tid,
struct inode *ip, component_t * key, ino_t * data, int flag);
extern int dtRelocate(tid_t tid,
struct inode *ip, s64 lmxaddr, pxd_t * opxd, s64 nxaddr);
extern int dtModify(tid_t tid, struct inode *ip,
component_t * key, ino_t * orig_ino, ino_t new_ino, int flag);
extern int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir);
#ifdef _JFS_DEBUG_DTREE
extern int dtDisplayTree(struct inode *ip);
extern int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p);
#endif /* _JFS_DEBUG_DTREE */
#endif /* !_H_JFS_DTREE */
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_EXTENDFS
#define _H_JFS_EXTENDFS
/*
* jfs_extendfs.h
*/
/*
* extendfs parameter list
*/
typedef struct {
u32 flag; /* 4: */
u8 dev; /* 1: */
u8 pad[3]; /* 3: */
s64 LVSize; /* 8: LV size in LV block */
s64 FSSize; /* 8: FS size in LV block */
s32 LogSize; /* 4: inlinelog size in LV block */
} extendfs_t; /* (28) */
/* plist flag */
#define EXTENDFS_QUERY 0x00000001
#endif /* _H_JFS_EXTENDFS */
This diff is collapsed.
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_EXTENT
#define _H_JFS_EXTENT
/* get block allocation allocation hint as location of disk inode */
#define INOHINT(ip) \
(addressPXD(&(JFS_IP(ip)->ixpxd)) + lengthPXD(&(JFS_IP(ip)->ixpxd)) - 1)
extern int extAlloc(struct inode *, s64, s64, xad_t *, boolean_t);
extern int extFill(struct inode *, xad_t *);
extern int extHint(struct inode *, s64, xad_t *);
extern int extRealloc(struct inode *, s64, xad_t *, boolean_t);
extern int extRecord(struct inode *, xad_t *);
#endif /* _H_JFS_EXTENT */
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _H_JFS_FILSYS
#define _H_JFS_FILSYS
/*
* jfs_filsys.h
*
* file system (implementation-dependent) constants
*
* refer to <limits.h> for system wide implementation-dependent constants
*/
/*
* file system option (superblock flag)
*/
/* platform option (conditional compilation) */
#define JFS_AIX 0x80000000 /* AIX support */
/* POSIX name/directory support */
#define JFS_OS2 0x40000000 /* OS/2 support */
/* case-insensitive name/directory support */
#define JFS_DFS 0x20000000 /* DCE DFS LFS support */
#define JFS_LINUX 0x10000000 /* Linux support */
/* case-sensitive name/directory support */
/* directory option */
#define JFS_UNICODE 0x00000001 /* unicode name */
/* commit option */
#define JFS_COMMIT 0x00000f00 /* commit option mask */
#define JFS_GROUPCOMMIT 0x00000100 /* group (of 1) commit */
#define JFS_LAZYCOMMIT 0x00000200 /* lazy commit */
#define JFS_TMPFS 0x00000400 /* temporary file system -
* do not log/commit:
*/
/* log logical volume option */
#define JFS_INLINELOG 0x00000800 /* inline log within file system */
#define JFS_INLINEMOVE 0x00001000 /* inline log being moved */
/* Secondary aggregate inode table */
#define JFS_BAD_SAIT 0x00010000 /* current secondary ait is bad */
/* sparse regular file support */
#define JFS_SPARSE 0x00020000 /* sparse regular file */
/* DASD Limits F226941 */
#define JFS_DASD_ENABLED 0x00040000 /* DASD limits enabled */
#define JFS_DASD_PRIME 0x00080000 /* Prime DASD usage on boot */
/* big endian flag */
#define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */
/* Directory index */
#define JFS_DIR_INDEX 0x00200000 /* Persistant index for */
/* directory entries */
/*
* buffer cache configuration
*/
/* page size */
#ifdef PSIZE
#undef PSIZE
#endif
#define PSIZE 4096 /* page size (in byte) */
#define L2PSIZE 12 /* log2(PSIZE) */
#define POFFSET 4095 /* offset within page */
/* buffer page size */
#define BPSIZE PSIZE
/*
* fs fundamental size
*
* PSIZE >= file system block size >= PBSIZE >= DISIZE
*/
#define PBSIZE 512 /* physical block size (in byte) */
#define L2PBSIZE 9 /* log2(PBSIZE) */
#define DISIZE 512 /* on-disk inode size (in byte) */
#define L2DISIZE 9 /* log2(DISIZE) */
#define IDATASIZE 256 /* inode inline data size */
#define IXATTRSIZE 128 /* inode inline extended attribute size */
#define XTPAGE_SIZE 4096
#define log2_PAGESIZE 12
#define IAG_SIZE 4096
#define IAG_EXTENT_SIZE 4096
#define INOSPERIAG 4096 /* number of disk inodes per iag */
#define L2INOSPERIAG 12 /* l2 number of disk inodes per iag */
#define INOSPEREXT 32 /* number of disk inode per extent */
#define L2INOSPEREXT 5 /* l2 number of disk inode per extent */
#define IXSIZE (DISIZE * INOSPEREXT) /* inode extent size */
#define INOSPERPAGE 8 /* number of disk inodes per 4K page */
#define L2INOSPERPAGE 3 /* log2(INOSPERPAGE) */
#define IAGFREELIST_LWM 64
#define INODE_EXTENT_SIZE IXSIZE /* inode extent size */
#define NUM_INODE_PER_EXTENT INOSPEREXT
#define NUM_INODE_PER_IAG INOSPERIAG
#define MINBLOCKSIZE 512
#define MAXBLOCKSIZE 4096
#define MAXFILESIZE ((s64)1 << 52)
#define JFS_LINK_MAX 65535 /* nlink_t is unsigned short */
/* Minimum number of bytes supported for a JFS partition */
#define MINJFS (0x1000000)
#define MINJFSTEXT "16"
/*
* file system block size -> physical block size
*/
#define LBOFFSET(x) ((x) & (PBSIZE - 1))
#define LBNUMBER(x) ((x) >> L2PBSIZE)
#define LBLK2PBLK(sb,b) ((b) << (sb->s_blocksize_bits - L2PBSIZE))
#define PBLK2LBLK(sb,b) ((b) >> (sb->s_blocksize_bits - L2PBSIZE))
/* size in byte -> last page number */
#define SIZE2PN(size) ( ((s64)((size) - 1)) >> (L2PSIZE) )
/* size in byte -> last file system block number */
#define SIZE2BN(size, l2bsize) ( ((s64)((size) - 1)) >> (l2bsize) )
/*
* fixed physical block address (physical block size = 512 byte)
*
* NOTE: since we can't guarantee a physical block size of 512 bytes the use of
* these macros should be removed and the byte offset macros used instead.
*/
#define SUPER1_B 64 /* primary superblock */
#define AIMAP_B (SUPER1_B + 8) /* 1st extent of aggregate inode map */
#define AITBL_B (AIMAP_B + 16) /*
* 1st extent of aggregate inode table
*/
#define SUPER2_B (AITBL_B + 32) /* 2ndary superblock pbn */
#define BMAP_B (SUPER2_B + 8) /* block allocation map */
/*
* SIZE_OF_SUPER defines the total amount of space reserved on disk for the
* superblock. This is not the same as the superblock structure, since all of
* this space is not currently being used.
*/
#define SIZE_OF_SUPER PSIZE
/*
* SIZE_OF_AG_TABLE defines the amount of space reserved to hold the AG table
*/
#define SIZE_OF_AG_TABLE PSIZE
/*
* SIZE_OF_MAP_PAGE defines the amount of disk space reserved for each page of
* the inode allocation map (to hold iag)
*/
#define SIZE_OF_MAP_PAGE PSIZE
/*
* fixed byte offset address
*/
#define SUPER1_OFF 0x8000 /* primary superblock */
#define AIMAP_OFF (SUPER1_OFF + SIZE_OF_SUPER)
/*
* Control page of aggregate inode map
* followed by 1st extent of map
*/
#define AITBL_OFF (AIMAP_OFF + (SIZE_OF_MAP_PAGE << 1))
/*
* 1st extent of aggregate inode table
*/
#define SUPER2_OFF (AITBL_OFF + INODE_EXTENT_SIZE)
/*
* secondary superblock
*/
#define BMAP_OFF (SUPER2_OFF + SIZE_OF_SUPER)
/*
* block allocation map
*/
/*
* The following macro is used to indicate the number of reserved disk blocks at
* the front of an aggregate, in terms of physical blocks. This value is
* currently defined to be 32K. This turns out to be the same as the primary
* superblock's address, since it directly follows the reserved blocks.
*/
#define AGGR_RSVD_BLOCKS SUPER1_B
/*
* The following macro is used to indicate the number of reserved bytes at the
* front of an aggregate. This value is currently defined to be 32K. This
* turns out to be the same as the primary superblock's byte offset, since it
* directly follows the reserved blocks.
*/
#define AGGR_RSVD_BYTES SUPER1_OFF
/*
* The following macro defines the byte offset for the first inode extent in
* the aggregate inode table. This allows us to find the self inode to find the
* rest of the table. Currently this value is 44K.
*/
#define AGGR_INODE_TABLE_START AITBL_OFF
/*
* fixed reserved inode number
*/
/* aggregate inode */
#define AGGR_RESERVED_I 0 /* aggregate inode (reserved) */
#define AGGREGATE_I 1 /* aggregate inode map inode */
#define BMAP_I 2 /* aggregate block allocation map inode */
#define LOG_I 3 /* aggregate inline log inode */
#define BADBLOCK_I 4 /* aggregate bad block inode */
#define FILESYSTEM_I 16 /* 1st/only fileset inode in ait:
* fileset inode map inode
*/
/* per fileset inode */
#define FILESET_RSVD_I 0 /* fileset inode (reserved) */
#define FILESET_EXT_I 1 /* fileset inode extension */
#define ROOT_I 2 /* fileset root inode */
#define ACL_I 3 /* fileset ACL inode */
#define FILESET_OBJECT_I 4 /* the first fileset inode available for a file
* or directory or link...
*/
#define FIRST_FILESET_INO 16 /* the first aggregate inode which describes
* an inode. (To fsck this is also the first
* inode in part 2 of the agg inode table.)
*/
/*
* directory configuration
*/
#define JFS_NAME_MAX 255
#define JFS_PATH_MAX BPSIZE
/*
* file system state (superblock state)
*/
#define FM_CLEAN 0x00000000 /* file system is unmounted and clean */
#define FM_MOUNT 0x00000001 /* file system is mounted cleanly */
#define FM_DIRTY 0x00000002 /* file system was not unmounted and clean
* when mounted or
* commit failure occurred while being mounted:
* fsck() must be run to repair
*/
#define FM_LOGREDO 0x00000004 /* log based recovery (logredo()) failed:
* fsck() must be run to repair
*/
#define FM_EXTENDFS 0x00000008 /* file system extendfs() in progress */
#endif /* _H_JFS_FILSYS */
This diff is collapsed.
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_IMAP
#define _H_JFS_IMAP
#include "jfs_txnmgr.h"
/*
* jfs_imap.h: disk inode manager
*/
#define EXTSPERIAG 128 /* number of disk inode extent per iag */
#define IMAPBLKNO 0 /* lblkno of dinomap within inode map */
#define SMAPSZ 4 /* number of words per summary map */
#define EXTSPERSUM 32 /* number of extents per summary map entry */
#define L2EXTSPERSUM 5 /* l2 number of extents per summary map */
#define PGSPERIEXT 4 /* number of 4K pages per dinode extent */
#define MAXIAGS ((1<<20)-1) /* maximum number of iags */
#define MAXAG 128 /* maximum number of allocation groups */
#define AMAPSIZE 512 /* bytes in the IAG allocation maps */
#define SMAPSIZE 16 /* bytes in the IAG summary maps */
/* convert inode number to iag number */
#define INOTOIAG(ino) ((ino) >> L2INOSPERIAG)
/* convert iag number to logical block number of the iag page */
#define IAGTOLBLK(iagno,l2nbperpg) (((iagno) + 1) << (l2nbperpg))
/* get the starting block number of the 4K page of an inode extent
* that contains ino.
*/
#define INOPBLK(pxd,ino,l2nbperpg) (addressPXD((pxd)) + \
((((ino) & (INOSPEREXT-1)) >> L2INOSPERPAGE) << (l2nbperpg)))
/*
* inode allocation map:
*
* inode allocation map consists of
* . the inode map control page and
* . inode allocation group pages (per 4096 inodes)
* which are addressed by standard JFS xtree.
*/
/*
* inode allocation group page (per 4096 inodes of an AG)
*/
typedef struct {
s64 agstart; /* 8: starting block of ag */
s32 iagnum; /* 4: inode allocation group number */
s32 inofreefwd; /* 4: ag inode free list forward */
s32 inofreeback; /* 4: ag inode free list back */
s32 extfreefwd; /* 4: ag inode extent free list forward */
s32 extfreeback; /* 4: ag inode extent free list back */
s32 iagfree; /* 4: iag free list */
/* summary map: 1 bit per inode extent */
s32 inosmap[SMAPSZ]; /* 16: sum map of mapwords w/ free inodes;
* note: this indicates free and backed
* inodes, if the extent is not backed the
* value will be 1. if the extent is
* backed but all inodes are being used the
* value will be 1. if the extent is
* backed but at least one of the inodes is
* free the value will be 0.
*/
s32 extsmap[SMAPSZ]; /* 16: sum map of mapwords w/ free extents */
s32 nfreeinos; /* 4: number of free inodes */
s32 nfreeexts; /* 4: number of free extents */
/* (72) */
u8 pad[1976]; /* 1976: pad to 2048 bytes */
/* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */
u32 wmap[EXTSPERIAG]; /* 512: working allocation map */
u32 pmap[EXTSPERIAG]; /* 512: persistent allocation map */
pxd_t inoext[EXTSPERIAG]; /* 1024: inode extent addresses */
} iag_t; /* (4096) */
/*
* per AG control information (in inode map control page)
*/
typedef struct {
s32 inofree; /* 4: free inode list anchor */
s32 extfree; /* 4: free extent list anchor */
s32 numinos; /* 4: number of backed inodes */
s32 numfree; /* 4: number of free inodes */
} iagctl_t; /* (16) */
/*
* per fileset/aggregate inode map control page
*/
typedef struct {
s32 in_freeiag; /* 4: free iag list anchor */
s32 in_nextiag; /* 4: next free iag number */
s32 in_numinos; /* 4: num of backed inodes */
s32 in_numfree; /* 4: num of free backed inodes */
s32 in_nbperiext; /* 4: num of blocks per inode extent */
s32 in_l2nbperiext; /* 4: l2 of in_nbperiext */
s32 in_diskblock; /* 4: for standalone test driver */
s32 in_maxag; /* 4: for standalone test driver */
u8 pad[2016]; /* 2016: pad to 2048 */
iagctl_t in_agctl[MAXAG]; /* 2048: AG control information */
} dinomap_t; /* (4096) */
/*
* In-core inode map control page
*/
typedef struct inomap {
dinomap_t im_imap; /* 4096: inode allocation control */
struct inode *im_ipimap; /* 4: ptr to inode for imap */
struct semaphore im_freelock; /* 4: iag free list lock */
struct semaphore im_aglock[MAXAG]; /* 512: per AG locks */
u32 *im_DBGdimap;
atomic_t im_numinos; /* num of backed inodes */
atomic_t im_numfree; /* num of free backed inodes */
} imap_t;
#define im_freeiag im_imap.in_freeiag
#define im_nextiag im_imap.in_nextiag
#define im_agctl im_imap.in_agctl
#define im_nbperiext im_imap.in_nbperiext
#define im_l2nbperiext im_imap.in_l2nbperiext
/* for standalone testdriver
*/
#define im_diskblock im_imap.in_diskblock
#define im_maxag im_imap.in_maxag
extern int diFree(struct inode *);
extern int diAlloc(struct inode *, boolean_t, struct inode *);
extern int diSync(struct inode *);
/* external references */
extern int diUpdatePMap(struct inode *ipimap, unsigned long inum,
boolean_t is_free, tblock_t * tblk);
#ifdef _STILL_TO_PORT
extern int diExtendFS(inode_t * ipimap, inode_t * ipbmap);
#endif /* _STILL_TO_PORT */
extern int diMount(struct inode *);
extern int diUnmount(struct inode *, int);
extern int diRead(struct inode *);
extern void diClearExtension(struct inode *);
extern struct inode *diReadSpecial(struct super_block *, ino_t);
extern void diWriteSpecial(struct inode *);
extern void diFreeSpecial(struct inode *);
extern int diWrite(tid_t tid, struct inode *);
#endif /* _H_JFS_IMAP */
/*
*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _H_JFS_INCORE
#define _H_JFS_INCORE
#include <linux/slab.h>
#include <asm/bitops.h>
#include "jfs_types.h"
#include "jfs_xtree.h"
#include "jfs_dtree.h"
/*
* JFS magic number
*/
#define JFS_SUPER_MAGIC 0x3153464a /* "JFS1" */
/*
* Due to header ordering problems this can't be in jfs_lock.h
*/
typedef struct jfs_rwlock {
struct rw_semaphore rw_sem;
atomic_t in_use; /* for hacked implementation of trylock */
} jfs_rwlock_t;
/*
* JFS-private inode information
*/
struct jfs_inode_info {
int fileset; /* fileset number (always 16)*/
uint mode2; /* jfs-specific mode */
pxd_t ixpxd; /* inode extent descriptor */
dxd_t acl; /* dxd describing acl */
dxd_t ea; /* dxd describing ea */
time_t otime; /* time created */
uint next_index; /* next available directory entry index */
int acltype; /* Type of ACL */
short btorder; /* access order */
short btindex; /* btpage entry index*/
struct inode *ipimap; /* inode map */
long cflag; /* commit flags */
u16 bxflag; /* xflag of pseudo buffer? */
unchar agno; /* ag number */
unchar pad; /* pad */
lid_t blid; /* lid of pseudo buffer? */
lid_t atlhead; /* anonymous tlock list head */
lid_t atltail; /* anonymous tlock list tail */
struct list_head anon_inode_list; /* inodes having anonymous txns */
struct list_head mp_list; /* metapages in inode's address space */
jfs_rwlock_t rdwrlock; /* read/write lock */
lid_t xtlid; /* lid of xtree lock on directory */
union {
struct {
xtpage_t _xtroot; /* 288: xtree root */
struct inomap *_imap; /* 4: inode map header */
} file;
struct {
dir_table_slot_t _table[12]; /* 96: directory index */
dtroot_t _dtroot; /* 288: dtree root */
} dir;
struct {
unchar _unused[16]; /* 16: */
dxd_t _dxd; /* 16: */
unchar _inline[128]; /* 128: inline symlink */
} link;
} u;
struct inode vfs_inode;
};
#define i_xtroot u.file._xtroot
#define i_imap u.file._imap
#define i_dirtable u.dir._table
#define i_dtroot u.dir._dtroot
#define i_inline u.link._inline
/*
* cflag
*/
enum cflags {
COMMIT_New, /* never committed inode */
COMMIT_Nolink, /* inode committed with zero link count */
COMMIT_Inlineea, /* commit inode inline EA */
COMMIT_Freewmap, /* free WMAP at iClose() */
COMMIT_Dirty, /* Inode is really dirty */
COMMIT_Holdlock, /* Hold the IWRITE_LOCK until commit is done */
COMMIT_Dirtable, /* commit changes to di_dirtable */
COMMIT_Stale, /* data extent is no longer valid */
COMMIT_Synclist, /* metadata pages on group commit synclist */
};
#define set_cflag(flag, ip) set_bit(flag, &(JFS_IP(ip)->cflag))
#define clear_cflag(flag, ip) clear_bit(flag, &(JFS_IP(ip)->cflag))
#define test_cflag(flag, ip) test_bit(flag, &(JFS_IP(ip)->cflag))
#define test_and_clear_cflag(flag, ip) \
test_and_clear_bit(flag, &(JFS_IP(ip)->cflag))
/*
* JFS-private superblock information.
*/
struct jfs_sb_info {
unsigned long mntflag; /* 4: aggregate attributes */
struct inode *ipbmap; /* 4: block map inode */
struct inode *ipaimap; /* 4: aggregate inode map inode */
struct inode *ipaimap2; /* 4: secondary aimap inode */
struct inode *ipimap; /* 4: aggregate inode map inode */
struct jfs_log *log; /* 4: log */
short bsize; /* 2: logical block size */
short l2bsize; /* 2: log2 logical block size */
short nbperpage; /* 2: blocks per page */
short l2nbperpage; /* 2: log2 blocks per page */
short l2niperblk; /* 2: log2 inodes per page */
short reserved; /* 2: log2 inodes per page */
pxd_t logpxd; /* 8: pxd describing log */
pxd_t ait2; /* 8: pxd describing AIT copy */
/* Formerly in ipimap */
uint gengen; /* 4: inode generation generator*/
uint inostamp; /* 4: shows inode belongs to fileset*/
/* Formerly in ipbmap */
struct bmap *bmap; /* 4: incore bmap descriptor */
struct nls_table *nls_tab; /* 4: current codepage */
struct inode *direct_inode; /* 4: inode for physical I/O */
struct address_space *direct_mapping; /* 4: mapping for physical I/O */
uint state; /* 4: mount/recovery state */
};
static inline struct jfs_inode_info *JFS_IP(struct inode *inode)
{
return list_entry(inode, struct jfs_inode_info, vfs_inode);
}
#define JFS_SBI(sb) ((struct jfs_sb_info *)(sb)->u.generic_sbp)
#define isReadOnly(ip) ((JFS_SBI((ip)->i_sb)->log) ? 0 : 1)
#endif /* _H_JFS_INCORE */
/*
*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_imap.h"
#include "jfs_dinode.h"
#include "jfs_debug.h"
/*
* NAME: ialloc()
*
* FUNCTION: Allocate a new inode
*
*/
struct inode *ialloc(struct inode *parent, umode_t mode)
{
struct super_block *sb = parent->i_sb;
struct inode *inode;
struct jfs_inode_info *jfs_inode;
int rc;
inode = new_inode(sb);
if (!inode) {
jERROR(1, ("ialloc: new_inode returned NULL!\n"));
return inode;
}
jfs_inode = JFS_IP(inode);
rc = diAlloc(parent, S_ISDIR(mode), inode);
if (rc) {
jERROR(1, ("ialloc: diAlloc returned %d!\n", rc));
make_bad_inode(inode);
iput(inode);
return NULL;
}
inode->i_uid = current->fsuid;
if (parent->i_mode & S_ISGID) {
inode->i_gid = parent->i_gid;
if (S_ISDIR(mode))
mode |= S_ISGID;
} else
inode->i_gid = current->fsgid;
inode->i_mode = mode;
if (S_ISDIR(mode))
jfs_inode->mode2 = IDIRECTORY | mode;
else
jfs_inode->mode2 = INLINEEA | ISPARSE | mode;
inode->i_blksize = sb->s_blocksize;
inode->i_blocks = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
jfs_inode->otime = inode->i_ctime;
inode->i_version = ++event;
inode->i_generation = JFS_SBI(sb)->gengen++;
jfs_inode->cflag = 0;
set_cflag(COMMIT_New, inode);
/* Zero remaining fields */
memset(&jfs_inode->acl, 0, sizeof(dxd_t));
memset(&jfs_inode->ea, 0, sizeof(dxd_t));
jfs_inode->next_index = 0;
jfs_inode->acltype = 0;
jfs_inode->btorder = 0;
jfs_inode->btindex = 0;
jfs_inode->bxflag = 0;
jfs_inode->blid = 0;
jfs_inode->atlhead = 0;
jfs_inode->atltail = 0;
jfs_inode->xtlid = 0;
jFYI(1, ("ialloc returns inode = 0x%p\n", inode));
return inode;
}
/*
* NAME: iwritelocklist()
*
* FUNCTION: Lock multiple inodes in sorted order to avoid deadlock
*
*/
void iwritelocklist(int n, ...)
{
va_list ilist;
struct inode *sort[4];
struct inode *ip;
int k, m;
va_start(ilist, n);
for (k = 0; k < n; k++)
sort[k] = va_arg(ilist, struct inode *);
va_end(ilist);
/* Bubble sort in descending order */
do {
m = 0;
for (k = 0; k < n; k++)
if ((k + 1) < n
&& sort[k + 1]->i_ino > sort[k]->i_ino) {
ip = sort[k];
sort[k] = sort[k + 1];
sort[k + 1] = ip;
m++;
}
} while (m);
/* Lock them */
for (k = 0; k < n; k++) {
IWRITE_LOCK(sort[k]);
}
}
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_INODE
#define _H_JFS_INODE
extern struct inode *ialloc(struct inode *, umode_t);
#endif /* _H_JFS_INODE */
/*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _H_JFS_LOCK
#define _H_JFS_LOCK
#include <linux/spinlock.h>
#include <linux/sched.h>
/*
* jfs_lock.h
*
* JFS lock definition for globally referenced locks
*/
/* readers/writer lock: thread-thread */
/*
* RW semaphores do not currently have a trylock function. Since the
* implementation varies by platform, I have implemented a platform-independent
* wrapper around the rw_semaphore routines. If this turns out to be the best
* way of avoiding our locking problems, I will push to get a trylock
* implemented in the kernel, but I'd rather find a way to avoid having to
* use it.
*/
#define RDWRLOCK_T jfs_rwlock_t
static inline void RDWRLOCK_INIT(jfs_rwlock_t * Lock)
{
init_rwsem(&Lock->rw_sem);
atomic_set(&Lock->in_use, 0);
}
static inline void READ_LOCK(jfs_rwlock_t * Lock)
{
atomic_inc(&Lock->in_use);
down_read(&Lock->rw_sem);
}
static inline void READ_UNLOCK(jfs_rwlock_t * Lock)
{
up_read(&Lock->rw_sem);
atomic_dec(&Lock->in_use);
}
static inline void WRITE_LOCK(jfs_rwlock_t * Lock)
{
atomic_inc(&Lock->in_use);
down_write(&Lock->rw_sem);
}
static inline int WRITE_TRYLOCK(jfs_rwlock_t * Lock)
{
if (atomic_read(&Lock->in_use))
return 0;
WRITE_LOCK(Lock);
return 1;
}
static inline void WRITE_UNLOCK(jfs_rwlock_t * Lock)
{
up_write(&Lock->rw_sem);
atomic_dec(&Lock->in_use);
}
#define IREAD_LOCK(ip) READ_LOCK(&JFS_IP(ip)->rdwrlock)
#define IREAD_UNLOCK(ip) READ_UNLOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_LOCK(ip) WRITE_LOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_TRYLOCK(ip) WRITE_TRYLOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_UNLOCK(ip) WRITE_UNLOCK(&JFS_IP(ip)->rdwrlock)
#define IWRITE_LOCK_LIST iwritelocklist
extern void iwritelocklist(int, ...);
/*
* Conditional sleep where condition is protected by spinlock
*
* lock_cmd and unlock_cmd take and release the spinlock
*/
#define __SLEEP_COND(wq, cond, lock_cmd, unlock_cmd) \
do { \
DECLARE_WAITQUEUE(__wait, current); \
\
add_wait_queue(&wq, &__wait); \
for (;;) { \
set_current_state(TASK_UNINTERRUPTIBLE);\
if (cond) \
break; \
unlock_cmd; \
schedule(); \
lock_cmd; \
} \
current->state = TASK_RUNNING; \
remove_wait_queue(&wq, &__wait); \
} while (0)
#endif /* _H_JFS_LOCK */
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.
This diff is collapsed.
This diff is collapsed.
/*
*
* Copyright (c) International Business Machines Corp., 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/fs.h>
#include <linux/slab.h>
#include "jfs_types.h"
#include "jfs_filsys.h"
#include "jfs_unicode.h"
#include "jfs_debug.h"
/*
* NAME: jfs_strfromUCS()
*
* FUNCTION: Convert little-endian unicode string to character string
*
*/
int jfs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */
int len, struct nls_table *codepage)
{
int i;
int outlen = 0;
for (i = 0; (i < len) && from[i]; i++) {
int charlen;
charlen =
codepage->uni2char(le16_to_cpu(from[i]), &to[outlen],
NLS_MAX_CHARSET_SIZE);
if (charlen > 0) {
outlen += charlen;
} else {
to[outlen++] = '?';
}
}
to[outlen] = 0;
jEVENT(0, ("jfs_strfromUCS returning %d - '%s'\n", outlen, to));
return outlen;
}
/*
* NAME: jfs_strtoUCS()
*
* FUNCTION: Convert character string to unicode string
*
*/
int jfs_strtoUCS(wchar_t * to,
const char *from, int len, struct nls_table *codepage)
{
int charlen;
int i;
jEVENT(0, ("jfs_strtoUCS - '%s'\n", from));
for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
charlen = codepage->char2uni(from, len, &to[i]);
if (charlen < 1) {
jERROR(1, ("jfs_strtoUCS: char2uni returned %d.\n",
charlen));
jERROR(1, ("charset = %s, char = 0x%x\n",
codepage->charset, (unsigned char) *from));
to[i] = 0x003f; /* a question mark */
charlen = 1;
}
}
jEVENT(0, (" returning %d\n", i));
to[i] = 0;
return i;
}
/*
* NAME: get_UCSname()
*
* FUNCTION: Allocate and translate to unicode string
*
*/
int get_UCSname(component_t * uniName, struct dentry *dentry,
struct nls_table *nls_tab)
{
int length = dentry->d_name.len;
if (length > JFS_NAME_MAX)
return ENAMETOOLONG;
uniName->name =
kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS);
if (uniName->name == NULL)
return ENOSPC;
uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
length, nls_tab);
return 0;
}
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.
......@@ -12,7 +12,7 @@ fi
# msdos and Joliet want NLS
if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \
-o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" \
-o "$CONFIG_SMB_NLS" = "y" ]; then
-o "$CONFIG_SMB_NLS" = "y" -o "$CONFIG_JFS_FS" != "n" ]; then
define_bool CONFIG_NLS y
else
define_bool CONFIG_NLS n
......
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