Commit ef5cc2fd authored by Christoph Hellwig's avatar Christoph Hellwig

Import XFS CVS from 10092002

parent ed245b59
...@@ -56,6 +56,7 @@ o modutils 2.4.2 # insmod -V ...@@ -56,6 +56,7 @@ o modutils 2.4.2 # insmod -V
o e2fsprogs 1.25 # tune2fs o e2fsprogs 1.25 # tune2fs
o jfsutils 1.0.14 # fsck.jfs -V o jfsutils 1.0.14 # fsck.jfs -V
o reiserfsprogs 3.x.1b # reiserfsck 2>&1|grep reiserfsprogs o reiserfsprogs 3.x.1b # reiserfsck 2>&1|grep reiserfsprogs
o xfsprogs 2.1.0 # xfs_db -V
o pcmcia-cs 3.1.21 # cardmgr -V o pcmcia-cs 3.1.21 # cardmgr -V
o PPP 2.4.0 # pppd --version o PPP 2.4.0 # pppd --version
o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
...@@ -182,6 +183,17 @@ The reiserfsprogs package should be used for reiserfs-3.6.x ...@@ -182,6 +183,17 @@ The reiserfsprogs package should be used for reiserfs-3.6.x
versions of mkreiserfs, resize_reiserfs, debugreiserfs and versions of mkreiserfs, resize_reiserfs, debugreiserfs and
reiserfsck. These utils work on both i386 and alpha platforms. reiserfsck. These utils work on both i386 and alpha platforms.
Xfsprogs
--------
The latest version of xfsprogs contains mkfs.xfs, xfs_db, and the
xfs_repair utilities, among others, for the XFS filesystem. It is
architecture independent and any version from 2.0.0 onward should
work correctly with this version of the XFS kernel code. For the new
(v2) log format that has better support for stripe-size aligning on
LVM and MD devices at least xfsprogs 2.1.0 is needed.
Pcmcia-cs Pcmcia-cs
--------- ---------
...@@ -316,6 +328,10 @@ Reiserfsprogs ...@@ -316,6 +328,10 @@ Reiserfsprogs
------------- -------------
o <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz> o <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
Xfsprogs
--------
o <ftp://oss.sgi.com/projects/xfs/download/cmd_tars/xfsprogs-2.1.0.src.tar.gz>
LVM toolset LVM toolset
----------- -----------
o <http://www.sistina.com/lvm/> o <http://www.sistina.com/lvm/>
......
...@@ -46,3 +46,5 @@ vfat.txt ...@@ -46,3 +46,5 @@ vfat.txt
- info on using the VFAT filesystem used in Windows NT and Windows 95 - info on using the VFAT filesystem used in Windows NT and Windows 95
vfs.txt vfs.txt
- Overview of the Virtual File System - Overview of the Virtual File System
xfs.txt
- info and mount options for the XFS filesystem.
The SGI XFS Filesystem
======================
XFS is a high performance journaling filesystem which originated
on the SGI IRIX platform. It is completely multi-threaded, can
support large files and large filesystems, extended attributes,
variable block sizes, is extent based, and makes extensive use of
Btrees (directories, extents, free space) to aid both performance
and scalability.
Refer to the documentation at http://oss.sgi.com/projects/xfs/
for further details. This implementation is on-disk compatible
with the IRIX version of XFS.
Options
=======
When mounting an XFS filesystem, the following options are accepted.
biosize=size
Sets the preferred buffered I/O size (default size is 64K).
"size" must be expressed as the logarithm (base2) of the
desired I/O size.
Valid values for this option are 14 through 16, inclusive
(i.e. 16K, 32K, and 64K bytes). On machines with a 4K
pagesize, 13 (8K bytes) is also a valid size.
The preferred buffered I/O size can also be altered on an
individual file basis using the ioctl(2) system call.
dmapi/xdsm
Enable the DMAPI (Data Management API) event callouts.
irixsgid
Do not inherit the ISGID bit on subdirectories of ISGID
directories, if the process creating the subdirectory
is not a member of the parent directory group ID.
This matches IRIX behavior.
logbufs=value
Set the number of in-memory log buffers. Valid numbers range
from 2-8 inclusive.
The default value is 8 buffers for filesystems with a
blocksize of 64K, 4 buffers for filesystems with a blocksize
of 32K, 3 buffers for filesystems with a blocksize of 16K
and 2 buffers for all other configurations. Increasing the
number of buffers may increase performance on some workloads
at the cost of the memory used for the additional log buffers
and their associated control structures.
logbsize=value
Set the size of each in-memory log buffer.
Size may be specified in bytes, or in kilobytes with a "k" suffix.
Valid sizes for version 1 and version 2 logs are 16384 (16k) and
32768 (32k). Valid sizes for version 2 logs also include
65536 (64k), 131072 (128k) and 262144 (256k).
The default value for machines with more than 32MB of memory
is 32768, machines with less memory use 16384 by default.
logdev=device and rtdev=device
Use an external log (metadata journal) and/or real-time device.
An XFS filesystem has up to three parts: a data section, a log
section, and a real-time section. The real-time section is
optional, and the log section can be separate from the data
section or contained within it.
noalign
Data allocations will not be aligned at stripe unit boundaries.
noatime
Access timestamps are not updated when a file is read.
norecovery
The filesystem will be mounted without running log recovery.
If the filesystem was not cleanly unmounted, it is likely to
be inconsistent when mounted in "norecovery" mode.
Some files or directories may not be accessible because of this.
Filesystems mounted "norecovery" must be mounted read-only or
the mount will fail.
osyncisosync
Make O_SYNC writes implement true O_SYNC. WITHOUT this option,
Linux XFS behaves as if an "osyncisdsync" option is used,
which will make writes to files opened with the O_SYNC flag set
behave as if the O_DSYNC flag had been used instead.
This can result in better performance without compromising
data safety.
However if this option is not in effect, timestamp updates from
O_SYNC writes can be lost if the system crashes.
If timestamp updates are critical, use the osyncisosync option.
quota/usrquota/uqnoenforce
User disk quota accounting enabled, and limits (optionally)
enforced.
grpquota/gqnoenforce
Group disk quota accounting enabled and limits (optionally)
enforced.
sunit=value and swidth=value
Used to specify the stripe unit and width for a RAID device or
a stripe volume. "value" must be specified in 512-byte block
units.
If this option is not specified and the filesystem was made on
a stripe volume or the stripe width or unit were specified for
the RAID device at mkfs time, then the mount system call will
restore the value from the superblock. For filesystems that
are made directly on RAID devices, these options can be used
to override the information in the superblock if the underlying
disk layout changes after the filesystem has been created.
The "swidth" option is required if the "sunit" option has been
specified, and must be a multiple of the "sunit" value.
nouuid
Don't check for double mounted file systems using the file system uuid.
This is useful to mount LVM snapshot volumes.
...@@ -1912,6 +1912,14 @@ M: eis@baty.hanse.de ...@@ -1912,6 +1912,14 @@ M: eis@baty.hanse.de
L: linux-x25@vger.kernel.org L: linux-x25@vger.kernel.org
S: Maintained S: Maintained
XFS FILESYSTEM
P: Silicon Graphics Inc
M: owner-xfs@oss.sgi.com
M: lord@sgi.com
L: linux-xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
S: Supported
X86 3-LEVEL PAGING (PAE) SUPPORT X86 3-LEVEL PAGING (PAE) SUPPORT
P: Ingo Molnar P: Ingo Molnar
M: mingo@redhat.com M: mingo@redhat.com
......
...@@ -1036,3 +1036,50 @@ CONFIG_NCPFS_NLS ...@@ -1036,3 +1036,50 @@ CONFIG_NCPFS_NLS
To select codepages and I/O charsets use ncpfs-2.2.0.13 or newer. To select codepages and I/O charsets use ncpfs-2.2.0.13 or newer.
CONFIG_XFS_FS
XFS is a high performance journaling filesystem which originated
on the SGI IRIX platform. It is completely multi-threaded, can
support large files and large filesystems, extended attributes,
variable block sizes, is extent based, and makes extensive use of
Btrees (directories, extents, free space) to aid both performance
and scalability.
Refer to the documentation at <http://oss.sgi.com/projects/xfs/>
for complete details. This implementation is on-disk compatible
with the IRIX version of XFS.
If you want to compile this file system as a module ( = code which
can be inserted in and removed from the running kernel whenever you
want), say M here and read <file:Documentation/modules.txt>. The
module will be called xfs.o. Be aware, however, that if the file
system of your root partition is compiled as a module, you'll need
to use an initial ramdisk (initrd) to boot.
CONFIG_XFS_QUOTA
If you say Y here, you will be able to set limits for disk usage on
a per user and/or a per group basis under XFS. XFS considers quota
information as filesystem metadata and uses journaling to provide a
higher level guarantee of consistency. The on-disk data format for
quota is also compatible with the IRIX version of XFS, allowing a
filesystem to be migrated between Linux and IRIX without any need
for conversion.
If unsure, say N. More comprehensive documentation can be found in
README.quota in the xfsprogs package. XFS quota can be used either
with or without the generic quota support enabled (CONFIG_QUOTA) -
they are completely independent subsystems.
CONFIG_XFS_RT
If you say Y here you will be able to mount and use XFS filesystems
which contain a realtime subvolume. The realtime subvolume is a
separate area of disk space where only file data is stored. The
realtime subvolume is designed to provide very deterministic
data rates suitable for media streaming applications.
See the xfs man page in section 5 for a bit more information.
This feature is unsupported at this time, is not yet fully
functional, and may cause serious problems.
If unsure, say N.
...@@ -101,6 +101,13 @@ dep_mbool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW $CONFIG_UDF_FS $CONFIG ...@@ -101,6 +101,13 @@ dep_mbool ' UDF write support (DANGEROUS)' CONFIG_UDF_RW $CONFIG_UDF_FS $CONFIG
tristate 'UFS file system support (read only)' CONFIG_UFS_FS tristate 'UFS file system support (read only)' CONFIG_UFS_FS
dep_mbool ' UFS file system write support (DANGEROUS)' CONFIG_UFS_FS_WRITE $CONFIG_UFS_FS $CONFIG_EXPERIMENTAL dep_mbool ' UFS file system write support (DANGEROUS)' CONFIG_UFS_FS_WRITE $CONFIG_UFS_FS $CONFIG_EXPERIMENTAL
tristate 'XFS filesystem support' CONFIG_XFS_FS
dep_mbool ' Realtime support (EXPERIMENTAL)' CONFIG_XFS_RT $CONFIG_XFS_FS $CONFIG_EXPERIMENTAL
dep_mbool ' Quota support' CONFIG_XFS_QUOTA $CONFIG_XFS_FS
if [ "$CONFIG_XFS_QUOTA" = "y" ]; then
define_bool CONFIG_QUOTACTL y
fi
if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment mainmenu_option next_comment
......
...@@ -84,5 +84,6 @@ obj-$(CONFIG_ADFS_FS) += adfs/ ...@@ -84,5 +84,6 @@ obj-$(CONFIG_ADFS_FS) += adfs/
obj-$(CONFIG_REISERFS_FS) += reiserfs/ obj-$(CONFIG_REISERFS_FS) += reiserfs/
obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/ obj-$(CONFIG_SUN_OPENPROMFS) += openpromfs/
obj-$(CONFIG_JFS_FS) += jfs/ obj-$(CONFIG_JFS_FS) += jfs/
obj-$(CONFIG_XFS_FS) += xfs/
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
#
# Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Further, this software is distributed without any warranty that it is
# free of the rightful claim of any third person regarding infringement
# or the like. Any license provided herein, whether implied or
# otherwise, applies only to this software file. Patent licenses, if
# any, provided herein do not apply to combinations of this program with
# other software, or any other product whatsoever.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston MA 02111-1307, USA.
#
# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
# Mountain View, CA 94043, or:
#
# http://www.sgi.com
#
# For further information regarding this notice, see:
#
# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
#
# Makefile for XFS on Linux.
#
# we also have source in the subdirectories..
vpath %.c = . linux pagebuf support
# This needs -I. because everything does #include <xfs.h> instead of "xfs.h".
# The code is wrong, local files should be included using "xfs.h", not <xfs.h>
# but I am not going to change every file at the moment.
EXTRA_CFLAGS += -I. -funsigned-char
ifeq ($(CONFIG_XFS_DEBUG),y)
EXTRA_CFLAGS += -g -DSTATIC="" -DDEBUG -DXFSDEBUG
endif
ifeq ($(CONFIG_PAGEBUF_DEBUG),y)
EXTRA_CFLAGS += -DPAGEBUF_TRACE
endif
export-objs := page_buf.o ktrace.o xfs_globals.o
obj-$(CONFIG_XFS_FS) += xfs.o
xfs-obj-$(CONFIG_XFS_RT) += xfs_rtalloc.o
xfs-obj-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
xfs_dquot_item.o \
xfs_trans_dquot.o \
xfs_qm_syscalls.o \
xfs_qm.o
xfs-obj-$(CONFIG_FS_POSIX_ACL) += xfs_acl.o
xfs-obj-$(CONFIG_FS_POSIX_CAP) += xfs_cap.o
xfs-obj-$(CONFIG_FS_POSIX_MAC) += xfs_mac.o
xfs-obj-$(CONFIG_PROC_FS) += xfs_stats.o
xfs-obj-$(CONFIG_SYSCTL) += xfs_sysctl.o
xfs-objs += $(xfs-obj-y) \
xfs_alloc.o \
xfs_alloc_btree.o \
xfs_attr.o \
xfs_attr_fetch.o \
xfs_attr_leaf.o \
xfs_bit.o \
xfs_bmap.o \
xfs_bmap_btree.o \
xfs_btree.o \
xfs_buf_item.o \
xfs_da_btree.o \
xfs_dir.o \
xfs_dir2.o \
xfs_dir2_block.o \
xfs_dir2_data.o \
xfs_dir2_leaf.o \
xfs_dir2_node.o \
xfs_dir2_sf.o \
xfs_dir2_trace.o \
xfs_dir_leaf.o \
xfs_error.o \
xfs_extfree_item.o \
xfs_fsops.o \
xfs_ialloc.o \
xfs_ialloc_btree.o \
xfs_iget.o \
xfs_inode.o \
xfs_inode_item.o \
xfs_iocore.o \
xfs_itable.o \
xfs_dfrag.o \
xfs_log.o \
xfs_log_recover.o \
xfs_macros.o \
xfs_mount.o \
xfs_rename.o \
xfs_trans.o \
xfs_trans_ail.o \
xfs_trans_buf.o \
xfs_trans_extfree.o \
xfs_trans_inode.o \
xfs_trans_item.o \
xfs_utils.o \
xfs_vfsops.o \
xfs_vnodeops.o \
xfs_rw.o
# Objects in pagebuf/
xfs-objs += page_buf.o \
page_buf_locking.o
# Objects in linux/
xfs-objs += xfs_aops.o \
xfs_behavior.o \
xfs_file.o \
xfs_fs_subr.o \
xfs_globals.o \
xfs_ioctl.o \
xfs_iops.o \
xfs_lrw.o \
xfs_super.o \
xfs_vnode.o
# Objects in support/
xfs-objs += debug.o \
kmem.o \
ktrace.o \
move.o \
mrlock.o \
qsort.o \
uuid.o
# If both xfs and kdb modules are built in then xfsidbg is built in. If xfs is
# a module and kdb modules are being compiled then xfsidbg must be a module, to
# follow xfs. If xfs is built in then xfsidbg tracks the kdb module state.
# This must come after the main xfs code so xfs initialises before xfsidbg.
# KAO
ifneq ($(CONFIG_KDB_MODULES),)
ifeq ($(CONFIG_XFS_FS),y)
obj-$(CONFIG_KDB_MODULES) += xfsidbg.o
else
obj-$(CONFIG_XFS_FS) += xfsidbg.o
endif
endif
CFLAGS_xfsidbg.o += -I $(TOPDIR)/arch/$(ARCH)/kdb
include $(TOPDIR)/Rules.make
This diff is collapsed.
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*
*/
/*
* Source file used to associate/disassociate behaviors with virtualized
* objects. See behavior.h for more information about behaviors, etc.
*
* The implementation is split between functions in this file and macros
* in behavior.h.
*/
#include <xfs.h>
kmem_zone_t *bhv_global_zone;
/*
* Global initialization function called out of main.
*/
void
bhv_global_init(void)
{
/*
* Initialize a behavior zone used by subsystems using behaviors
* but without any private data. In the UNIKERNEL case, this zone
* is used only for behaviors that are not yet isolated to a single
* cell. The only such user is in pshm.c in which a dummy vnode is
* obtained in support of vce avoidance logic.
*/
bhv_global_zone = kmem_zone_init(sizeof(bhv_desc_t), "bhv_global_zone");
}
/*
* Remove a behavior descriptor from a position in a behavior chain;
* the postition is guaranteed not to be the first position.
* Should only be called by the bhv_remove() macro.
*
* The act of modifying the chain is done atomically w.r.t. ops-in-progress
* (see comment at top of behavior.h for more info on synchronization).
*/
void
bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
{
bhv_desc_t *curdesc, *prev;
ASSERT(bhp->bh_first != NULL);
ASSERT(bhp->bh_first->bd_next != NULL);
prev = bhp->bh_first;
for (curdesc = bhp->bh_first->bd_next;
curdesc != NULL;
curdesc = curdesc->bd_next) {
if (curdesc == bdp)
break; /* found it */
prev = curdesc;
}
ASSERT(curdesc == bdp);
prev->bd_next = bdp->bd_next; /* remove from after prev */
/* atomic wrt oip's */
}
/*
* Look for a specific ops vector on the specified behavior chain.
* Return the associated behavior descriptor. Or NULL, if not found.
*/
bhv_desc_t *
bhv_lookup(bhv_head_t *bhp, void *ops)
{
bhv_desc_t *curdesc;
for (curdesc = bhp->bh_first;
curdesc != NULL;
curdesc = curdesc->bd_next) {
if (curdesc->bd_ops == ops)
return curdesc;
}
return NULL;
}
/*
* Look for a specific ops vector on the specified behavior chain.
* Return the associated behavior descriptor. Or NULL, if not found.
*
* The caller has not read locked the behavior chain, so acquire the
* lock before traversing the chain.
*/
bhv_desc_t *
bhv_lookup_unlocked(bhv_head_t *bhp, void *ops)
{
bhv_desc_t *bdp;
BHV_READ_LOCK(bhp);
bdp = bhv_lookup(bhp, ops);
BHV_READ_UNLOCK(bhp);
return bdp;
}
/*
* Return the base behavior in the chain, or NULL if the chain
* is empty.
*
* The caller has not read locked the behavior chain, so acquire the
* lock before traversing the chain.
*/
bhv_desc_t *
bhv_base_unlocked(bhv_head_t *bhp)
{
bhv_desc_t *curdesc;
BHV_READ_LOCK(bhp);
for (curdesc = bhp->bh_first;
curdesc != NULL;
curdesc = curdesc->bd_next) {
if (curdesc->bd_next == NULL) {
BHV_READ_UNLOCK(bhp);
return curdesc;
}
}
BHV_READ_UNLOCK(bhp);
return NULL;
}
#define BHVMAGIC (void *)0xf00d
/* ARGSUSED */
void
bhv_head_init(
bhv_head_t *bhp,
char *name)
{
bhp->bh_first = NULL;
bhp->bh_lockp = BHVMAGIC;
}
/* ARGSUSED */
void
bhv_head_reinit(
bhv_head_t *bhp)
{
ASSERT(bhp->bh_first == NULL);
ASSERT(bhp->bh_lockp == BHVMAGIC);
}
void
bhv_insert_initial(
bhv_head_t *bhp,
bhv_desc_t *bdp)
{
ASSERT(bhp->bh_first == NULL);
ASSERT(bhp->bh_lockp == BHVMAGIC);
(bhp)->bh_first = bdp;
}
void
bhv_head_destroy(
bhv_head_t *bhp)
{
ASSERT(bhp->bh_first == NULL);
ASSERT(bhp->bh_lockp == BHVMAGIC);
bhp->bh_lockp = NULL;
}
/*
* Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_BEHAVIOR_H__
#define __XFS_BEHAVIOR_H__
/*
* Header file used to associate behaviors with virtualized objects.
*
* A virtualized object is an internal, virtualized representation of
* OS entities such as persistent files, processes, or sockets. Examples
* of virtualized objects include vnodes, vprocs, and vsockets. Often
* a virtualized object is referred to simply as an "object."
*
* A behavior is essentially an implementation layer associated with
* an object. Multiple behaviors for an object are chained together,
* the order of chaining determining the order of invocation. Each
* behavior of a given object implements the same set of interfaces
* (e.g., the VOP interfaces).
*
* Behaviors may be dynamically inserted into an object's behavior chain,
* such that the addition is transparent to consumers that already have
* references to the object. Typically, a given behavior will be inserted
* at a particular location in the behavior chain. Insertion of new
* behaviors is synchronized with operations-in-progress (oip's) so that
* the oip's always see a consistent view of the chain.
*
* The term "interpostion" is used to refer to the act of inserting
* a behavior such that it interposes on (i.e., is inserted in front
* of) a particular other behavior. A key example of this is when a
* system implementing distributed single system image wishes to
* interpose a distribution layer (providing distributed coherency)
* in front of an object that is otherwise only accessed locally.
*
* Note that the traditional vnode/inode combination is simply a virtualized
* object that has exactly one associated behavior.
*
* Behavior synchronization is logic which is necessary under certain
* circumstances that there is no conflict between ongoing operations
* traversing the behavior chain and those dunamically modifying the
* behavior chain. Because behavior synchronization adds extra overhead
* to virtual operation invocation, we want to restrict, as much as
* we can, the requirement for this extra code, to those situations
* in which it is truly necessary.
*
* Behavior synchronization is needed whenever there's at least one class
* of object in the system for which:
* 1) multiple behaviors for a given object are supported,
* -- AND --
* 2a) insertion of a new behavior can happen dynamically at any time during
* the life of an active object,
* -- AND --
* 3a) insertion of a new behavior needs to synchronize with existing
* ops-in-progress.
* -- OR --
* 3b) multiple different behaviors can be dynamically inserted at
* any time during the life of an active object
* -- OR --
* 3c) removal of a behavior can occur at any time during the life of
* an active object.
* -- OR --
* 2b) removal of a behavior can occur at any time during the life of an
* active object
*
*/
typedef void bhv_head_lock_t;
/*
* Behavior head. Head of the chain of behaviors.
* Contained within each virtualized object data structure.
*/
typedef struct bhv_head {
struct bhv_desc *bh_first; /* first behavior in chain */
bhv_head_lock_t *bh_lockp; /* pointer to lock info struct */
} bhv_head_t;
/*
* Behavior descriptor. Descriptor associated with each behavior.
* Contained within the behavior's private data structure.
*/
typedef struct bhv_desc {
void *bd_pdata; /* private data for this behavior */
void *bd_vobj; /* virtual object associated with */
void *bd_ops; /* ops for this behavior */
struct bhv_desc *bd_next; /* next behavior in chain */
} bhv_desc_t;
/*
* Behavior identity field. A behavior's identity determines the position
* where it lives within a behavior chain, and it's always the first field
* of the behavior's ops vector. The optional id field further identifies the
* subsystem responsible for the behavior.
*/
typedef struct bhv_identity {
__u16 bi_id; /* owning subsystem id */
__u16 bi_position; /* position in chain */
} bhv_identity_t;
typedef bhv_identity_t bhv_position_t;
#define BHV_IDENTITY_INIT(id,pos) {id, pos}
#define BHV_IDENTITY_INIT_POSITION(pos) BHV_IDENTITY_INIT(0, pos)
/*
* Define boundaries of position values.
*/
#define BHV_POSITION_INVALID 0 /* invalid position number */
#define BHV_POSITION_BASE 1 /* base (last) implementation layer */
#define BHV_POSITION_TOP 63 /* top (first) implementation layer */
/*
* Plumbing macros.
*/
#define BHV_HEAD_FIRST(bhp) (ASSERT((bhp)->bh_first), (bhp)->bh_first)
#define BHV_NEXT(bdp) (ASSERT((bdp)->bd_next), (bdp)->bd_next)
#define BHV_NEXTNULL(bdp) ((bdp)->bd_next)
#define BHV_VOBJ(bdp) (ASSERT((bdp)->bd_vobj), (bdp)->bd_vobj)
#define BHV_VOBJNULL(bdp) ((bdp)->bd_vobj)
#define BHV_PDATA(bdp) (bdp)->bd_pdata
#define BHV_OPS(bdp) (bdp)->bd_ops
#define BHV_IDENTITY(bdp) ((bhv_identity_t *)(bdp)->bd_ops)
#define BHV_POSITION(bdp) (BHV_IDENTITY(bdp)->bi_position)
#define BHV_READ_LOCK(bhp)
#define BHV_READ_UNLOCK(bhp)
#define BHV_NOT_READ_LOCKED(bhp) 1
#define BHV_IS_WRITE_LOCKED(bhp) 1
#define BHV_NOT_WRITE_LOCKED(bhp) 1
extern void bhv_head_init(bhv_head_t *, char *);
extern void bhv_head_destroy(bhv_head_t *);
extern void bhv_head_reinit(bhv_head_t *);
extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
/*
* Initialize a new behavior descriptor.
* Arguments:
* bdp - pointer to behavior descriptor
* pdata - pointer to behavior's private data
* vobj - pointer to associated virtual object
* ops - pointer to ops for this behavior
*/
#define bhv_desc_init(bdp, pdata, vobj, ops) \
{ \
(bdp)->bd_pdata = pdata; \
(bdp)->bd_vobj = vobj; \
(bdp)->bd_ops = ops; \
(bdp)->bd_next = NULL; \
}
#define BHV_DESC_INIT(so,A,B) bhv_desc_init(&(so->so_bhv),so,A,B)
/*
* Remove a behavior descriptor from a behavior chain.
*/
#define bhv_remove(bhp, bdp) \
{ \
if ((bhp)->bh_first == (bdp)) { \
/* \
* Remove from front of chain. \
* Atomic wrt oip's. \
*/ \
(bhp)->bh_first = (bdp)->bd_next; \
} else { \
/* remove from non-front of chain */ \
bhv_remove_not_first(bhp, bdp); \
} \
(bdp)->bd_vobj = NULL; \
}
/*
* Behavior module prototypes.
*/
extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops);
extern bhv_desc_t * bhv_lookup_unlocked(bhv_head_t *bhp, void *ops);
extern bhv_desc_t * bhv_base_unlocked(bhv_head_t *bhp);
#endif /* __XFS_BEHAVIOR_H__ */
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_CRED_H__
#define __XFS_CRED_H__
/*
* Credentials
*/
typedef struct cred {
/* EMPTY */
} cred_t;
extern struct cred *sys_cred;
/* this is a hack.. (assums sys_cred is the only cred_t in the system) */
static __inline int capable_cred(cred_t *cr, int cid)
{
return (cr == sys_cred) ? 1 : capable(cid);
}
#endif /* __XFS_CRED_H__ */
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <xfs.h>
#include <linux/dcache.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/mman.h> /* for PROT_WRITE */
static struct vm_operations_struct linvfs_file_vm_ops;
STATIC ssize_t
linvfs_read(
struct file *filp,
char *buf,
size_t size,
loff_t *offset)
{
vnode_t *vp;
int error;
vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
ASSERT(vp);
VOP_READ(vp, filp, buf, size, offset, NULL, error);
return(error);
}
STATIC ssize_t
linvfs_write(
struct file *file,
const char *buf,
size_t count,
loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode;
loff_t pos;
vnode_t *vp;
int err; /* Use negative errors in this f'n */
if ((ssize_t) count < 0)
return -EINVAL;
if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
pos = *ppos;
err = -EINVAL;
if (pos < 0)
goto out;
err = file->f_error;
if (err) {
file->f_error = 0;
goto out;
}
vp = LINVFS_GET_VP(inode);
ASSERT(vp);
/* We allow multiple direct writers in, there is no
* potential call to vmtruncate in that path.
*/
if (!(file->f_flags & O_DIRECT))
down(&inode->i_sem);
VOP_WRITE(vp, file, buf, count, &pos, NULL, err);
*ppos = pos;
if (!(file->f_flags & O_DIRECT))
up(&inode->i_sem);
out:
return(err);
}
STATIC int
linvfs_open(
struct inode *inode,
struct file *filp)
{
vnode_t *vp = LINVFS_GET_VP(inode);
int error;
if (!(filp->f_flags & O_LARGEFILE) && inode->i_size > MAX_NON_LFS)
return -EFBIG;
ASSERT(vp);
VOP_OPEN(vp, NULL, error);
return -error;
}
STATIC int
linvfs_release(
struct inode *inode,
struct file *filp)
{
vnode_t *vp = LINVFS_GET_VP(inode);
int error = 0;
if (vp)
VOP_RELEASE(vp, error);
return -error;
}
STATIC int
linvfs_fsync(
struct file *filp,
struct dentry *dentry,
int datasync)
{
struct inode *inode = dentry->d_inode;
vnode_t *vp = LINVFS_GET_VP(inode);
int error;
int flags = FSYNC_WAIT;
if (datasync)
flags |= FSYNC_DATA;
ASSERT(vp);
VOP_FSYNC(vp, flags, NULL, (off_t)0, (off_t)-1, error);
return -error;
}
/*
* linvfs_readdir maps to VOP_READDIR().
* We need to build a uio, cred, ...
*/
#define nextdp(dp) ((struct xfs_dirent *)((char *)(dp) + (dp)->d_reclen))
STATIC int
linvfs_readdir(
struct file *filp,
void *dirent,
filldir_t filldir)
{
int error = 0;
vnode_t *vp;
uio_t uio;
iovec_t iov;
int eof = 0;
caddr_t read_buf;
int namelen, size = 0;
size_t rlen = PAGE_CACHE_SIZE << 2;
off_t start_offset;
xfs_dirent_t *dbp = NULL;
vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
ASSERT(vp);
/* Try fairly hard to get memory */
do {
if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL)))
break;
rlen >>= 1;
} while (rlen >= 1024);
if (read_buf == NULL)
return -ENOMEM;
uio.uio_iov = &iov;
uio.uio_fmode = filp->f_mode;
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_offset = filp->f_pos;
while (!eof) {
uio.uio_resid = iov.iov_len = rlen;
iov.iov_base = read_buf;
uio.uio_iovcnt = 1;
start_offset = uio.uio_offset;
VOP_READDIR(vp, &uio, NULL, &eof, error);
if ((uio.uio_offset == start_offset) || error) {
size = 0;
break;
}
size = rlen - uio.uio_resid;
dbp = (xfs_dirent_t *)read_buf;
while (size > 0) {
namelen = strlen(dbp->d_name);
if (filldir(dirent, dbp->d_name, namelen,
(loff_t) dbp->d_off,
(ino_t) dbp->d_ino,
DT_UNKNOWN)) {
goto done;
}
size -= dbp->d_reclen;
dbp = nextdp(dbp);
}
}
done:
if (!error) {
if (size == 0)
filp->f_pos = uio.uio_offset;
else if (dbp)
filp->f_pos = dbp->d_off;
}
kfree(read_buf);
return -error;
}
STATIC int
linvfs_file_mmap(
struct file *filp,
struct vm_area_struct *vma)
{
struct inode *ip = filp->f_dentry->d_inode;
vnode_t *vp = LINVFS_GET_VP(ip);
vattr_t va = { .va_mask = AT_UPDATIME };
int error;
if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
error = -xfs_dm_send_mmap_event(vma, 0);
if (error)
return error;
}
vma->vm_ops = &linvfs_file_vm_ops;
VOP_SETATTR(vp, &va, AT_UPDATIME, NULL, error);
UPDATE_ATIME(ip);
return 0;
}
STATIC int
linvfs_ioctl(
struct inode *inode,
struct file *filp,
unsigned int cmd,
unsigned long arg)
{
int error;
vnode_t *vp = LINVFS_GET_VP(inode);
ASSERT(vp);
VOP_IOCTL(vp, inode, filp, cmd, arg, error);
VMODIFY(vp);
/* NOTE: some of the ioctl's return positive #'s as a
* byte count indicating success, such as
* readlink_by_handle. So we don't "sign flip"
* like most other routines. This means true
* errors need to be returned as a negative value.
*/
return error;
}
#ifdef HAVE_VMOP_MPROTECT
STATIC int
linvfs_mprotect(
struct vm_area_struct *vma,
unsigned int newflags)
{
vnode_t *vp = LINVFS_GET_VP(vma->vm_file->f_dentry->d_inode);
int error = 0;
if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
if ((vma->vm_flags & VM_MAYSHARE) &&
(newflags & PROT_WRITE) && !(vma->vm_flags & PROT_WRITE)){
error = xfs_dm_send_mmap_event(vma, VM_WRITE);
}
}
return error;
}
#endif /* HAVE_VMOP_MPROTECT */
struct file_operations linvfs_file_operations = {
.llseek = generic_file_llseek,
.read = linvfs_read,
.write = linvfs_write,
.ioctl = linvfs_ioctl,
.mmap = linvfs_file_mmap,
.open = linvfs_open,
.release = linvfs_release,
.fsync = linvfs_fsync,
};
struct file_operations linvfs_dir_operations = {
.read = generic_read_dir,
.readdir = linvfs_readdir,
.ioctl = linvfs_ioctl,
.fsync = linvfs_fsync,
};
static struct vm_operations_struct linvfs_file_vm_ops = {
.nopage = filemap_nopage,
#ifdef HAVE_VMOP_MPROTECT
.mprotect = linvfs_mprotect,
#endif
};
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <xfs.h>
/*
* Implementation for VFS_DOUNMOUNT.
*/
int
fs_dounmount(
bhv_desc_t *bdp,
int flags,
vnode_t *rootvp,
cred_t *cr)
{
struct vfs *vfsp = bhvtovfs(bdp);
bhv_desc_t *fbdp = vfsp->vfs_fbhv;
int error;
/*
* Wait for sync to finish and lock vfsp. This also sets the
* VFS_OFFLINE flag. Once we do this we can give up reference
* the root vnode which we hold to avoid the another unmount
* ripping the vfs out from under us before we get to lock it.
* The VFS_DOUNMOUNT calling convention is that the reference
* on the rot vnode is released whether the call succeeds or
* fails.
*/
if (rootvp)
VN_RELE(rootvp);
/*
* Now invoke SYNC and UNMOUNT ops, using the PVFS versions is
* OK since we already have a behavior lock as a result of
* being in VFS_DOUNMOUNT. It is necessary to do things this
* way since using the VFS versions would cause us to get the
* behavior lock twice which can cause deadlock as well as
* making the coding of vfs relocation unnecessarilty difficult
* by making relocations invoked by unmount occur in a different
* environment than those invoked by mount-update.
*/
PVFS_SYNC(fbdp, SYNC_ATTR|SYNC_DELWRI, cr, error);
if (error == 0)
PVFS_UNMOUNT(fbdp, flags, cr, error);
return error;
}
/*
* Stub for no-op vnode operations that return error status.
*/
int
fs_noerr()
{
return 0;
}
/*
* Operation unsupported under this file system.
*/
int
fs_nosys()
{
return ENOSYS;
}
/*
* Stub for inactive, strategy, and read/write lock/unlock. Does nothing.
*/
/* ARGSUSED */
void
fs_noval()
{
}
/*
* vnode pcache layer for vnode_tosspages.
* 'last' parameter unused but left in for IRIX compatibility
*/
void
fs_tosspages(
bhv_desc_t *bdp,
xfs_off_t first,
xfs_off_t last,
int fiopt)
{
vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = LINVFS_GET_IP(vp);
if (VN_CACHED(vp))
truncate_inode_pages(ip->i_mapping, first);
}
/*
* vnode pcache layer for vnode_flushinval_pages.
* 'last' parameter unused but left in for IRIX compatibility
*/
void
fs_flushinval_pages(
bhv_desc_t *bdp,
xfs_off_t first,
xfs_off_t last,
int fiopt)
{
vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = LINVFS_GET_IP(vp);
if (VN_CACHED(vp)) {
filemap_fdatawait(ip->i_mapping);
filemap_fdatawrite(ip->i_mapping);
filemap_fdatawait(ip->i_mapping);
truncate_inode_pages(ip->i_mapping, first);
}
}
/*
* vnode pcache layer for vnode_flush_pages.
* 'last' parameter unused but left in for IRIX compatibility
*/
int
fs_flush_pages(
bhv_desc_t *bdp,
xfs_off_t first,
xfs_off_t last,
uint64_t flags,
int fiopt)
{
vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = LINVFS_GET_IP(vp);
if (VN_CACHED(vp)) {
filemap_fdatawait(ip->i_mapping);
filemap_fdatawrite(ip->i_mapping);
filemap_fdatawait(ip->i_mapping);
}
return 0;
}
/*
* Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_SUBR_H__
#define __XFS_SUBR_H__
/*
* Utilities shared among file system implementations.
*/
struct cred;
extern int fs_noerr(void);
extern int fs_nosys(void);
extern int fs_nodev(void);
extern void fs_noval(void);
extern int fs_dounmount(bhv_desc_t *, int, vnode_t *, struct cred *);
extern void fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
extern void fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
extern int fs_flush_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, uint64_t, int);
#endif /* __XFS_FS_SUBR_H__ */
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
/*
* This file contains globals needed by XFS that were normally defined
* somewhere else in IRIX.
*/
#include <xfs.h>
uint64_t xfs_panic_mask; /* set to cause more panics */
unsigned long xfs_physmem;
/*
* restricted_chown = 1 bsd style chown(2), only super-user can give away files
* restricted_chown = 0 sysV style chown(2), non super-user can give away files
*/
int restricted_chown = 1;
/*
* Used to serialize atomicIncWithWrap.
*/
spinlock_t Atomic_spin = SPIN_LOCK_UNLOCKED;
/*
* Global system credential structure.
*/
cred_t sys_cred_val, *sys_cred = &sys_cred_val;
/*
* The global quota manager. There is only one of these for the entire
* system, _not_ one per file system. XQM keeps track of the overall
* quota functionality, including maintaining the freelist and hash
* tables of dquots.
*/
struct xfs_qm *xfs_Gqm;
mutex_t xfs_Gqm_lock;
/* Export XFS symbols used by xfsidbg */
EXPORT_SYMBOL(xfs_Gqm);
EXPORT_SYMBOL(xfs_next_bit);
EXPORT_SYMBOL(xfs_contig_bits);
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_GLOBALS_H__
#define __XFS_GLOBALS_H__
/*
* This file declares globals needed by XFS that were normally defined
* somewhere else in IRIX.
*/
extern uint64_t xfs_panic_mask; /* set to cause more panics */
extern int restricted_chown;
extern unsigned long xfs_physmem;
extern struct cred *sys_cred;
extern struct xfs_qm *xfs_Gqm;
extern mutex_t xfs_Gqm_lock;
#endif /* __XFS_GLOBALS_H__ */
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_IOPS_H__
#define __XFS_IOPS_H__
/*
* Extended system attributes.
* So far only POSIX ACLs are supported, but this will need to
* grow in time (capabilities, mandatory access control, etc).
*/
#define XFS_SYSTEM_NAMESPACE SYSTEM_POSIXACL
/*
* Define a table of the namespaces XFS supports
*/
typedef int (*xattr_exists_t)(vnode_t *);
typedef struct xattr_namespace {
char *name;
unsigned int namelen;
xattr_exists_t exists;
} xattr_namespace_t;
#define SYSTEM_NAMES 0
#define ROOT_NAMES 1
#define USER_NAMES 2
extern struct xattr_namespace *xfs_namespaces;
extern struct inode_operations linvfs_file_inode_operations;
extern struct inode_operations linvfs_dir_inode_operations;
extern struct inode_operations linvfs_symlink_inode_operations;
extern struct file_operations linvfs_file_operations;
extern struct file_operations linvfs_dir_operations;
extern struct address_space_operations linvfs_aops;
extern int linvfs_revalidate_core(struct inode *, int);
extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
#endif /* __XFS_IOPS_H__ */
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_LINUX__
#define __XFS_LINUX__
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/file.h>
#include <linux/swap.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/major.h>
#include <linux/root_dev.h>
#include <asm/page.h>
#include <asm/div64.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
#include <linux/xfs_behavior.h>
#include <linux/xfs_vfs.h>
#include <linux/xfs_cred.h>
#include <linux/xfs_vnode.h>
#include <linux/xfs_stats.h>
#include <linux/xfs_sysctl.h>
#include <linux/xfs_iops.h>
#include <linux/xfs_super.h>
#include <linux/xfs_globals.h>
#include <linux/xfs_fs_subr.h>
#include <pagebuf/page_buf.h>
#ifndef STATIC
#define STATIC static
#endif
typedef struct xfs_dirent { /* data from readdir() */
xfs_ino_t d_ino; /* inode number of entry */
xfs_off_t d_off; /* offset of disk directory entry */
unsigned short d_reclen; /* length of this record */
char d_name[1]; /* name of file */
} xfs_dirent_t;
#define DIRENTBASESIZE (((xfs_dirent_t *)0)->d_name - (char *)0)
#define DIRENTSIZE(namelen) \
((DIRENTBASESIZE + (namelen) + \
sizeof(xfs_off_t)) & ~(sizeof(xfs_off_t) - 1))
#define NBPP PAGE_SIZE
#define DPPSHFT (PAGE_SHIFT - 9)
#define NDPP (1 << (PAGE_SHIFT - 9))
#define dtop(DD) (((DD) + NDPP - 1) >> DPPSHFT)
#define dtopt(DD) ((DD) >> DPPSHFT)
#define dpoff(DD) ((DD) & (NDPP-1))
#define NBBY 8 /* number of bits per byte */
#define NBPC PAGE_SIZE /* Number of bytes per click */
#define BPCSHIFT PAGE_SHIFT /* LOG2(NBPC) if exact */
/*
* Size of block device i/o is parameterized here.
* Currently the system supports page-sized i/o.
*/
#define BLKDEV_IOSHIFT BPCSHIFT
#define BLKDEV_IOSIZE (1<<BLKDEV_IOSHIFT)
/* number of BB's per block device block */
#define BLKDEV_BB BTOBB(BLKDEV_IOSIZE)
/* bytes to clicks */
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
#define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
#define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT)
#define io_btoc(x) (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT)
#define io_btoct(x) ((__psunsigned_t)(x)>>IO_BPCSHIFT)
/* off_t bytes to clicks */
#define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
#define offtoct(x) ((xfs_off_t)(x)>>BPCSHIFT)
/* clicks to off_t bytes */
#define ctooff(x) ((xfs_off_t)(x)<<BPCSHIFT)
/* clicks to bytes */
#define ctob(x) ((__psunsigned_t)(x)<<BPCSHIFT)
#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
#define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT)
#define io_ctob(x) ((__psunsigned_t)(x)<<IO_BPCSHIFT)
/* bytes to clicks */
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
#ifndef CELL_CAPABLE
#define FSC_NOTIFY_NAME_CHANGED(vp)
#endif
#ifndef ENOATTR
#define ENOATTR ENODATA /* Attribute not found */
#endif
/* Note: EWRONGFS never visible outside the kernel */
#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
/*
* XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
* return codes out of its known range in errno.
* XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
* conflict with any code we use already or any code a driver may use)
* XXX Some options (currently we do #2):
* 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
* 2/ 990 ["Unknown error 990"]
* 3/ EUCLEAN ["Structure needs cleaning"]
* 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
*/
#define EFSCORRUPTED 990 /* Filesystem is corrupted */
#define SYNCHRONIZE() barrier()
#define lbolt jiffies
#define rootdev ROOT_DEV
#define __return_address __builtin_return_address(0)
#define LONGLONG_MAX 9223372036854775807LL /* max "long long int" */
#define nopkg() ( ENOSYS )
/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
/* we may well need to fine-tune this if it ever becomes an issue. */
#define DQUOT_MAX_HEURISTIC 1024 /* NR_DQUOTS */
#define ndquot DQUOT_MAX_HEURISTIC
/* IRIX uses the current size of the name cache to guess a good value */
/* - this isn't the same but is a good enough starting point for now. */
#define DQUOT_HASH_HEURISTIC files_stat.nr_files
/* IRIX inodes maintain the project ID also, zero this field on Linux */
#define DEFAULT_PROJID 0
#define dfltprid DEFAULT_PROJID
#define MAXNAMELEN 256
#define MAXPATHLEN 1024
#define FINVIS 0x0100 /* don't update timestamps - XFS */
#define MIN(a,b) (min(a,b))
#define MAX(a,b) (max(a,b))
#define howmany(x, y) (((x)+((y)-1))/(y))
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
/* Move the kernel do_div definition off to one side */
#if defined __i386__
/* For ia32 we need to pull some tricks to get past various versions
* of the compiler which do not like us using do_div in the middle
* of large functions.
*/
static inline __u32 xfs_do_div(void *a, __u32 b, int n)
{
__u32 mod;
switch (n) {
case 4:
mod = *(__u32 *)a % b;
*(__u32 *)a = *(__u32 *)a / b;
return mod;
case 8:
{
unsigned long __upper, __low, __high, __mod;
__u64 c = *(__u64 *)a;
__upper = __high = c >> 32;
__low = c;
if (__high) {
__upper = __high % (b);
__high = __high / (b);
}
asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper));
asm("":"=A" (c):"a" (__low),"d" (__high));
*(__u64 *)a = c;
return __mod;
}
}
/* NOTREACHED */
return 0;
}
/* Side effect free 64 bit mod operation */
static inline __u32 xfs_do_mod(void *a, __u32 b, int n)
{
switch (n) {
case 4:
return *(__u32 *)a % b;
case 8:
{
unsigned long __upper, __low, __high, __mod;
__u64 c = *(__u64 *)a;
__upper = __high = c >> 32;
__low = c;
if (__high) {
__upper = __high % (b);
__high = __high / (b);
}
asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper));
asm("":"=A" (c):"a" (__low),"d" (__high));
return __mod;
}
}
/* NOTREACHED */
return 0;
}
#else
static inline __u32 xfs_do_div(void *a, __u32 b, int n)
{
__u32 mod;
switch (n) {
case 4:
mod = *(__u32 *)a % b;
*(__u32 *)a = *(__u32 *)a / b;
return mod;
case 8:
mod = do_div(*(__u64 *)a, b);
return mod;
}
/* NOTREACHED */
return 0;
}
/* Side effect free 64 bit mod operation */
static inline __u32 xfs_do_mod(void *a, __u32 b, int n)
{
switch (n) {
case 4:
return *(__u32 *)a % b;
case 8:
{
__u64 c = *(__u64 *)a;
return do_div(c, b);
}
}
/* NOTREACHED */
return 0;
}
#endif
#undef do_div
#define do_div(a, b) xfs_do_div(&(a), (b), sizeof(a))
#define do_mod(a, b) xfs_do_mod(&(a), (b), sizeof(a))
static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y)
{
x += y - 1;
do_div(x, y);
return(x * y);
}
#endif /* __XFS_LINUX__ */
This diff is collapsed.
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_LRW_H__
#define __XFS_LRW_H__
#define XFS_IOMAP_READ_ENTER 3
/*
* Maximum count of bmaps used by read and write paths.
*/
#define XFS_MAX_RW_NBMAPS 4
extern int xfs_bmap (bhv_desc_t *, xfs_off_t, ssize_t, int, struct cred *, pb_bmap_t *, int *);
extern int xfs_strategy (bhv_desc_t *, xfs_off_t, ssize_t, int, struct cred *, pb_bmap_t *, int *);
extern int xfsbdstrat (struct xfs_mount *, struct xfs_buf *);
extern int xfs_bdstrat_cb (struct xfs_buf *);
extern int xfs_zero_eof (vnode_t *, struct xfs_iocore *, xfs_off_t,
xfs_fsize_t, xfs_fsize_t, struct pm *);
extern ssize_t xfs_read (
struct bhv_desc *bdp,
struct file *file,
char *buf,
size_t size,
loff_t *offset,
struct cred *credp);
extern ssize_t xfs_write (
struct bhv_desc *bdp,
struct file *file,
const char *buf,
size_t size,
loff_t *offset,
struct cred *credp);
extern int xfs_recover_read_only (xlog_t *);
extern int xfs_quotacheck_read_only (xfs_mount_t *);
extern void XFS_log_write_unmount_ro (bhv_desc_t *);
#define XFS_FSB_TO_DB_IO(io,fsb) \
(((io)->io_flags & XFS_IOCORE_RT) ? \
XFS_FSB_TO_BB((io)->io_mount, (fsb)) : \
XFS_FSB_TO_DADDR((io)->io_mount, (fsb)))
#endif /* __XFS_LRW_H__ */
/*
* Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <xfs.h>
#include <linux/proc_fs.h>
static int
xfs_read_xfsstats(char *buffer, char **start, off_t offset,
int count, int *eof, void *data)
{
int i, j, len;
static struct xstats_entry {
char *desc;
int endpoint;
} xstats[] = {
{ "extent_alloc", XFSSTAT_END_EXTENT_ALLOC },
{ "abt", XFSSTAT_END_ALLOC_BTREE },
{ "blk_map", XFSSTAT_END_BLOCK_MAPPING },
{ "bmbt", XFSSTAT_END_BLOCK_MAP_BTREE },
{ "dir", XFSSTAT_END_DIRECTORY_OPS },
{ "trans", XFSSTAT_END_TRANSACTIONS },
{ "ig", XFSSTAT_END_INODE_OPS },
{ "log", XFSSTAT_END_LOG_OPS },
{ "push_ail", XFSSTAT_END_TAIL_PUSHING },
{ "xstrat", XFSSTAT_END_WRITE_CONVERT },
{ "rw", XFSSTAT_END_READ_WRITE_OPS },
{ "attr", XFSSTAT_END_ATTRIBUTE_OPS },
{ "qm", XFSSTAT_END_QUOTA_OPS },
{ "icluster", XFSSTAT_END_INODE_CLUSTER },
{ "vnodes", XFSSTAT_END_VNODE_OPS },
};
for (i=j=len = 0; i < sizeof(xstats)/sizeof(struct xstats_entry); i++) {
len += sprintf(buffer + len, xstats[i].desc);
/* inner loop does each group */
while (j < xstats[i].endpoint) {
len += sprintf(buffer + len, " %u",
*(((__u32*)&xfsstats) + j));
j++;
}
buffer[len++] = '\n';
}
/* extra precision counters */
len += sprintf(buffer + len, "xpc %Lu %Lu %Lu\n",
xfsstats.xs_xstrat_bytes,
xfsstats.xs_write_bytes,
xfsstats.xs_read_bytes);
if (offset >= len) {
*start = buffer;
*eof = 1;
return 0;
}
*start = buffer + offset;
if ((len -= offset) > count)
return count;
*eof = 1;
return len;
}
static int
xfs_read_xfsquota(char *buffer, char **start, off_t offset,
int count, int *eof, void *data)
{
int len;
/* maximum; incore; ratio free to inuse; freelist */
len = sprintf(buffer, "%d\t%d\t%d\t%u\n",
ndquot,
xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
xfs_Gqm? xfs_Gqm->qm_dqfreelist.qh_nelems : 0);
if (offset >= len) {
*start = buffer;
*eof = 1;
return 0;
}
*start = buffer + offset;
if ((len -= offset) > count)
return count;
*eof = 1;
return len;
}
void
xfs_init_procfs(void)
{
if (!proc_mkdir("fs/xfs", 0))
return;
create_proc_read_entry("fs/xfs/stat", 0, 0, xfs_read_xfsstats, NULL);
create_proc_read_entry("fs/xfs/xqm", 0, 0, xfs_read_xfsquota, NULL);
}
void
xfs_cleanup_procfs(void)
{
remove_proc_entry("fs/xfs/stat", NULL);
remove_proc_entry("fs/xfs/xqm", NULL);
remove_proc_entry("fs/xfs", NULL);
}
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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