Merge git://oss.sgi.com:8090/xfs-2.6

* git://oss.sgi.com:8090/xfs-2.6: (43 commits)
  [XFS] Remove files from the build that are now unused.
  [XFS] Fix a Makefile issue related to exports.o handling.
  [XFS] Remove version 1 directory code.	Never functioned on Linux, just
  [XFS] Map EFSCORRUPTED to an actual error code, not just a made up one
  [XFS] Kill direct access to ->count in valusema(); all we ever use it for
  [XFS] Remove unneeded conditional code on NFS export interface related
  [XFS] Remove an incorrect use of unlikely() on a relatively likely code
  [XFS] Push some common code out of write path into core XFS code for
  [XFS] Remove unnecessary local from open_exec dmapi path.
  [XFS] Minor XFS documentation updates.
  [XFS] Fix broken const use inside local suffix_strtoul routine.
  [XFS] Fix nused counter.  It's currently getting set to -1 rather than
  [XFS] Fix mismerge of the fs_writable cleanup patch causing a freeze/thaw
  [XFS] Fix up debug code so that bulkstat wont generate thousands of
  [XFS] Remove unused parameter from di2xflags routine.
  [XFS] Cleanup a missed porting conversion, and freezing.
  [XFS] Resolve a namespace collision on remaining vtypes for FreeBSD
  [XFS] Resolve a namespace collision on vnode/vnodeops for FreeBSD porters.
  [XFS] Resolve a namespace collision on vfs/vfsops for FreeBSD porters.
  [XFS] statvfs component of directory/project quota support, code
  ...
This commit is contained in:
Linus Torvalds 2006-06-21 18:10:19 -07:00
Родитель 43104f1da8 98174e4697
Коммит 52ab3f3dc7
109 изменённых файлов: 2317 добавлений и 6262 удалений

Просмотреть файл

@ -3191,7 +3191,7 @@ XFS FILESYSTEM
P: Silicon Graphics Inc
M: xfs-masters@oss.sgi.com
M: nathans@sgi.com
L: linux-xfs@oss.sgi.com
L: xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
S: Supported

Просмотреть файл

@ -1,6 +1,5 @@
config XFS_FS
tristate "XFS filesystem support"
select EXPORTFS if NFSD!=n
help
XFS is a high performance journaling filesystem which originated
on the SGI IRIX platform. It is completely multi-threaded, can
@ -18,11 +17,6 @@ config XFS_FS
system of your root partition is compiled as a module, you'll need
to use an initial ramdisk (initrd) to boot.
config XFS_EXPORT
bool
depends on XFS_FS && EXPORTFS
default y
config XFS_QUOTA
bool "XFS Quota support"
depends on XFS_FS
@ -65,18 +59,19 @@ config XFS_POSIX_ACL
If you don't know what Access Control Lists are, say N.
config XFS_RT
bool "XFS Realtime support (EXPERIMENTAL)"
depends on XFS_FS && EXPERIMENTAL
bool "XFS Realtime subvolume support"
depends on XFS_FS
help
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.
which contain a realtime subvolume. The realtime subvolume is a
separate area of disk space where only file data is stored. It was
originally designed to provide deterministic data rates suitable
for media streaming applications, but is also useful as a generic
mechanism for ensuring data and metadata/log I/Os are completely
separated. Regular file I/Os are isolated to a separate device
from all other requests, and this can be done quite transparently
to applications via the inherit-realtime directory inode flag.
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.
See the xfs man page in section 5 for additional information.
If unsure, say N.

Просмотреть файл

@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o
xfs-y += xfs_alloc.o \
@ -73,14 +72,12 @@ xfs-y += xfs_alloc.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_dir_leaf.o \
xfs_error.o \
xfs_extfree_item.o \
xfs_fsops.o \
@ -117,6 +114,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
kmem.o \
xfs_aops.o \
xfs_buf.o \
xfs_export.o \
xfs_file.o \
xfs_fs_subr.o \
xfs_globals.o \

Просмотреть файл

@ -22,42 +22,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
/*
* Process flags handling
*/
#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO)
#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
#define PFLAGS_SET_NOIO() do { \
current->flags |= PF_NOIO; \
} while (0)
#define PFLAGS_CLEAR_NOIO() do { \
current->flags &= ~PF_NOIO; \
} while (0)
/* these could be nested, so we save state */
#define PFLAGS_SET_FSTRANS(STATEP) do { \
*(STATEP) = current->flags; \
current->flags |= PF_FSTRANS; \
} while (0)
#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
*(STATEP) = current->flags; \
current->flags &= ~PF_FSTRANS; \
} while (0)
/* Restore the PF_FSTRANS state to what was saved in STATEP */
#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
current->flags = ((current->flags & ~PF_FSTRANS) | \
(*(STATEP) & PF_FSTRANS)); \
} while (0)
#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
*(NSTATEP) = *(OSTATEP); \
} while (0)
/*
* General memory allocation interfaces
*/
@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags)
lflags = GFP_ATOMIC | __GFP_NOWARN;
} else {
lflags = GFP_KERNEL | __GFP_NOWARN;
if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
lflags &= ~__GFP_FS;
}
return lflags;

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -28,7 +28,7 @@ typedef struct {
} mrlock_t;
#define mrinit(mrp, name) \
( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) )
do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
#define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
#define mrfree(mrp) do { } while (0)
#define mraccess(mrp) mraccessf(mrp, 0)

Просмотреть файл

@ -34,20 +34,21 @@ typedef struct semaphore sema_t;
#define initnsema(sp, val, name) sema_init(sp, val)
#define psema(sp, b) down(sp)
#define vsema(sp) up(sp)
#define valusema(sp) (atomic_read(&(sp)->count))
#define freesema(sema)
#define freesema(sema) do { } while (0)
static inline int issemalocked(sema_t *sp)
{
return down_trylock(sp) || (up(sp), 0);
}
/*
* Map cpsema (try to get the sema) to down_trylock. We need to switch
* the return values since cpsema returns 1 (acquired) 0 (failed) and
* down_trylock returns the reverse 0 (acquired) 1 (failed).
*/
#define cpsema(sp) (down_trylock(sp) ? 0 : 1)
/*
* Didn't do cvsema(sp). Not sure how to map this to up/down/...
* It does a vsema if the values is < 0 other wise nothing.
*/
static inline int cpsema(sema_t *sp)
{
return down_trylock(sp) ? 0 : 1;
}
#endif /* __XFS_SUPPORT_SEMA_H__ */

Просмотреть файл

@ -21,7 +21,6 @@
#include "xfs_inum.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_trans.h"
#include "xfs_dmapi.h"
@ -29,7 +28,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -76,7 +74,7 @@ xfs_page_trace(
int mask)
{
xfs_inode_t *ip;
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
loff_t isize = i_size_read(inode);
loff_t offset = page_offset(page);
int delalloc = -1, unmapped = -1, unwritten = -1;
@ -136,9 +134,10 @@ xfs_destroy_ioend(
for (bh = ioend->io_buffer_head; bh; bh = next) {
next = bh->b_private;
bh->b_end_io(bh, ioend->io_uptodate);
bh->b_end_io(bh, !ioend->io_error);
}
if (unlikely(ioend->io_error))
vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
vn_iowake(ioend->io_vnode);
mempool_free(ioend, xfs_ioend_pool);
}
@ -180,13 +179,12 @@ xfs_end_bio_unwritten(
void *data)
{
xfs_ioend_t *ioend = data;
vnode_t *vp = ioend->io_vnode;
bhv_vnode_t *vp = ioend->io_vnode;
xfs_off_t offset = ioend->io_offset;
size_t size = ioend->io_size;
int error;
if (ioend->io_uptodate)
VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error);
if (likely(!ioend->io_error))
bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
xfs_destroy_ioend(ioend);
}
@ -211,7 +209,7 @@ xfs_alloc_ioend(
* all the I/O from calling the completion routine too early.
*/
atomic_set(&ioend->io_remaining, 1);
ioend->io_uptodate = 1; /* cleared if any I/O fails */
ioend->io_error = 0;
ioend->io_list = NULL;
ioend->io_type = type;
ioend->io_vnode = vn_from_inode(inode);
@ -239,10 +237,10 @@ xfs_map_blocks(
xfs_iomap_t *mapp,
int flags)
{
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
int error, nmaps = 1;
VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error);
error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps);
if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
VMODIFY(vp);
return -error;
@ -271,16 +269,14 @@ xfs_end_bio(
if (bio->bi_size)
return 1;
ASSERT(ioend);
ASSERT(atomic_read(&bio->bi_cnt) >= 1);
ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
/* Toss bio and pass work off to an xfsdatad thread */
if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
ioend->io_uptodate = 0;
bio->bi_private = NULL;
bio->bi_end_io = NULL;
bio_put(bio);
xfs_finish_ioend(ioend);
return 0;
}
@ -1127,7 +1123,7 @@ xfs_vm_writepage(
* then mark the page dirty again and leave the page
* as is.
*/
if (PFLAGS_TEST_FSTRANS() && need_trans)
if (current_test_flags(PF_FSTRANS) && need_trans)
goto out_fail;
/*
@ -1158,6 +1154,18 @@ out_unlock:
return error;
}
STATIC int
xfs_vm_writepages(
struct address_space *mapping,
struct writeback_control *wbc)
{
struct bhv_vnode *vp = vn_from_inode(mapping->host);
if (VN_TRUNC(vp))
VUNTRUNCATE(vp);
return generic_writepages(mapping, wbc);
}
/*
* Called to move a page into cleanable state - and from there
* to be released. Possibly the page is already clean. We always
@ -1204,7 +1212,7 @@ xfs_vm_releasepage(
/* If we are already inside a transaction or the thread cannot
* do I/O, we cannot release this page.
*/
if (PFLAGS_TEST_FSTRANS())
if (current_test_flags(PF_FSTRANS))
return 0;
/*
@ -1231,7 +1239,7 @@ __xfs_get_blocks(
int direct,
bmapi_flags_t flags)
{
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
xfs_iomap_t iomap;
xfs_off_t offset;
ssize_t size;
@ -1241,8 +1249,8 @@ __xfs_get_blocks(
offset = (xfs_off_t)iblock << inode->i_blkbits;
ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
size = bh_result->b_size;
VOP_BMAP(vp, offset, size,
create ? flags : BMAPI_READ, &iomap, &niomap, error);
error = bhv_vop_bmap(vp, offset, size,
create ? flags : BMAPI_READ, &iomap, &niomap);
if (error)
return -error;
if (niomap == 0)
@ -1370,13 +1378,13 @@ xfs_vm_direct_IO(
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
xfs_iomap_t iomap;
int maps = 1;
int error;
ssize_t ret;
VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error);
error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps);
if (error)
return -error;
@ -1409,14 +1417,12 @@ xfs_vm_bmap(
sector_t block)
{
struct inode *inode = (struct inode *)mapping->host;
vnode_t *vp = vn_from_inode(inode);
int error;
bhv_vnode_t *vp = vn_from_inode(inode);
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
VOP_RWLOCK(vp, VRWLOCK_READ);
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
VOP_RWUNLOCK(vp, VRWLOCK_READ);
bhv_vop_rwlock(vp, VRWLOCK_READ);
bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
bhv_vop_rwunlock(vp, VRWLOCK_READ);
return generic_block_bmap(mapping, block, xfs_get_blocks);
}
@ -1452,6 +1458,7 @@ struct address_space_operations xfs_address_space_operations = {
.readpage = xfs_vm_readpage,
.readpages = xfs_vm_readpages,
.writepage = xfs_vm_writepage,
.writepages = xfs_vm_writepages,
.sync_page = block_sync_page,
.releasepage = xfs_vm_releasepage,
.invalidatepage = xfs_vm_invalidatepage,

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005 Silicon Graphics, Inc.
* Copyright (c) 2005-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -30,9 +30,9 @@ typedef void (*xfs_ioend_func_t)(void *);
typedef struct xfs_ioend {
struct xfs_ioend *io_list; /* next ioend in chain */
unsigned int io_type; /* delalloc / unwritten */
unsigned int io_uptodate; /* I/O status register */
int io_error; /* I/O error code */
atomic_t io_remaining; /* hold count */
struct vnode *io_vnode; /* file being written to */
struct bhv_vnode *io_vnode; /* file being written to */
struct buffer_head *io_buffer_head;/* buffer linked list head */
struct buffer_head *io_buffer_tail;/* buffer linked list tail */
size_t io_size; /* size of the extent */
@ -43,4 +43,4 @@ typedef struct xfs_ioend {
extern struct address_space_operations xfs_address_space_operations;
extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
#endif /* __XFS_IOPS_H__ */
#endif /* __XFS_AOPS_H__ */

Просмотреть файл

@ -21,7 +21,6 @@
#include "xfs_log.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_mount.h"
#include "xfs_export.h"
@ -97,7 +96,7 @@ xfs_fs_encode_fh(
int len;
int is64 = 0;
#if XFS_BIG_INUMS
vfs_t *vfs = vfs_from_sb(inode->i_sb);
bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb);
if (!(vfs->vfs_flag & VFS_32BITINODES)) {
/* filesystem may contain 64bit inode numbers */
@ -136,13 +135,13 @@ xfs_fs_get_dentry(
struct super_block *sb,
void *data)
{
vnode_t *vp;
bhv_vnode_t *vp;
struct inode *inode;
struct dentry *result;
vfs_t *vfsp = vfs_from_sb(sb);
bhv_vfs_t *vfsp = vfs_from_sb(sb);
int error;
VFS_VGET(vfsp, &vp, (fid_t *)data, error);
error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data);
if (error || vp == NULL)
return ERR_PTR(-ESTALE) ;
@ -160,12 +159,12 @@ xfs_fs_get_parent(
struct dentry *child)
{
int error;
vnode_t *vp, *cvp;
bhv_vnode_t *vp, *cvp;
struct dentry *parent;
cvp = NULL;
vp = vn_from_inode(child->d_inode);
VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
if (unlikely(error))
return ERR_PTR(-error);

Просмотреть файл

@ -21,7 +21,6 @@
#include "xfs_inum.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_trans.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_alloc.h"
#include "xfs_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
@ -58,15 +56,12 @@ __xfs_file_read(
{
struct iovec iov = {buf, count};
struct file *file = iocb->ki_filp;
vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
ssize_t rval;
bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
return rval;
return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
}
STATIC ssize_t
@ -100,15 +95,12 @@ __xfs_file_write(
struct iovec iov = {(void __user *)buf, count};
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
vnode_t *vp = vn_from_inode(inode);
ssize_t rval;
bhv_vnode_t *vp = vn_from_inode(inode);
BUG_ON(iocb->ki_pos != pos);
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
return rval;
return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
}
STATIC ssize_t
@ -140,7 +132,7 @@ __xfs_file_readv(
loff_t *ppos)
{
struct inode *inode = file->f_mapping->host;
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
struct kiocb kiocb;
ssize_t rval;
@ -149,7 +141,8 @@ __xfs_file_readv(
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
&kiocb.ki_pos, ioflags, NULL);
*ppos = kiocb.ki_pos;
return rval;
@ -184,7 +177,7 @@ __xfs_file_writev(
loff_t *ppos)
{
struct inode *inode = file->f_mapping->host;
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
struct kiocb kiocb;
ssize_t rval;
@ -193,7 +186,8 @@ __xfs_file_writev(
if (unlikely(file->f_flags & O_DIRECT))
ioflags |= IO_ISDIRECT;
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
&kiocb.ki_pos, ioflags, NULL);
*ppos = kiocb.ki_pos;
return rval;
@ -227,11 +221,8 @@ xfs_file_sendfile(
read_actor_t actor,
void *target)
{
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
ssize_t rval;
VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
return rval;
return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
filp, pos, 0, count, actor, target, NULL);
}
STATIC ssize_t
@ -242,11 +233,8 @@ xfs_file_sendfile_invis(
read_actor_t actor,
void *target)
{
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
ssize_t rval;
VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
return rval;
return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
filp, pos, IO_INVIS, count, actor, target, NULL);
}
STATIC ssize_t
@ -257,11 +245,8 @@ xfs_file_splice_read(
size_t len,
unsigned int flags)
{
vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
ssize_t rval;
VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval);
return rval;
return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
infilp, ppos, pipe, len, flags, 0, NULL);
}
STATIC ssize_t
@ -272,11 +257,9 @@ xfs_file_splice_read_invis(
size_t len,
unsigned int flags)
{
vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
ssize_t rval;
VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval);
return rval;
return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
infilp, ppos, pipe, len, flags, IO_INVIS,
NULL);
}
STATIC ssize_t
@ -287,11 +270,8 @@ xfs_file_splice_write(
size_t len,
unsigned int flags)
{
vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
ssize_t rval;
VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval);
return rval;
return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
pipe, outfilp, ppos, len, flags, 0, NULL);
}
STATIC ssize_t
@ -302,11 +282,9 @@ xfs_file_splice_write_invis(
size_t len,
unsigned int flags)
{
vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
ssize_t rval;
VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval);
return rval;
return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
pipe, outfilp, ppos, len, flags, IO_INVIS,
NULL);
}
STATIC int
@ -314,13 +292,17 @@ xfs_file_open(
struct inode *inode,
struct file *filp)
{
vnode_t *vp = vn_from_inode(inode);
int error;
if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
return -EFBIG;
VOP_OPEN(vp, NULL, error);
return -error;
return -bhv_vop_open(vn_from_inode(inode), NULL);
}
STATIC int
xfs_file_close(
struct file *filp)
{
return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
}
STATIC int
@ -328,12 +310,11 @@ xfs_file_release(
struct inode *inode,
struct file *filp)
{
vnode_t *vp = vn_from_inode(inode);
int error = 0;
bhv_vnode_t *vp = vn_from_inode(inode);
if (vp)
VOP_RELEASE(vp, error);
return -error;
return -bhv_vop_release(vp);
return 0;
}
STATIC int
@ -342,15 +323,14 @@ xfs_file_fsync(
struct dentry *dentry,
int datasync)
{
struct inode *inode = dentry->d_inode;
vnode_t *vp = vn_from_inode(inode);
int error;
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
int flags = FSYNC_WAIT;
if (datasync)
flags |= FSYNC_DATA;
VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error);
return -error;
if (VN_TRUNC(vp))
VUNTRUNCATE(vp);
return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
}
#ifdef CONFIG_XFS_DMAPI
@ -361,16 +341,11 @@ xfs_vm_nopage(
int *type)
{
struct inode *inode = area->vm_file->f_dentry->d_inode;
vnode_t *vp = vn_from_inode(inode);
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
int error;
bhv_vnode_t *vp = vn_from_inode(inode);
ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
error = XFS_SEND_MMAP(mp, area, 0);
if (error)
if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
return NULL;
return filemap_nopage(area, address, type);
}
#endif /* CONFIG_XFS_DMAPI */
@ -382,7 +357,7 @@ xfs_file_readdir(
filldir_t filldir)
{
int error = 0;
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
bhv_vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
uio_t uio;
iovec_t iov;
int eof = 0;
@ -417,7 +392,7 @@ xfs_file_readdir(
start_offset = uio.uio_offset;
VOP_READDIR(vp, &uio, NULL, &eof, error);
error = bhv_vop_readdir(vp, &uio, NULL, &eof);
if ((uio.uio_offset == start_offset) || error) {
size = 0;
break;
@ -456,38 +431,28 @@ xfs_file_mmap(
struct file *filp,
struct vm_area_struct *vma)
{
struct inode *ip = filp->f_dentry->d_inode;
vnode_t *vp = vn_from_inode(ip);
vattr_t vattr;
int error;
vma->vm_ops = &xfs_file_vm_ops;
#ifdef CONFIG_XFS_DMAPI
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
vma->vm_ops = &xfs_dmapi_file_vm_ops;
}
#endif /* CONFIG_XFS_DMAPI */
vattr.va_mask = XFS_AT_UPDATIME;
VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
if (likely(!error))
__vn_revalidate(vp, &vattr); /* update flags */
file_accessed(filp);
return 0;
}
STATIC long
xfs_file_ioctl(
struct file *filp,
unsigned int cmd,
unsigned long arg)
unsigned long p)
{
int error;
struct inode *inode = filp->f_dentry->d_inode;
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error);
error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
VMODIFY(vp);
/* NOTE: some of the ioctl's return positive #'s as a
@ -503,13 +468,13 @@ STATIC long
xfs_file_ioctl_invis(
struct file *filp,
unsigned int cmd,
unsigned long arg)
unsigned long p)
{
struct inode *inode = filp->f_dentry->d_inode;
vnode_t *vp = vn_from_inode(inode);
int error;
struct inode *inode = filp->f_dentry->d_inode;
bhv_vnode_t *vp = vn_from_inode(inode);
VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
VMODIFY(vp);
/* NOTE: some of the ioctl's return positive #'s as a
@ -528,7 +493,7 @@ xfs_vm_mprotect(
struct vm_area_struct *vma,
unsigned int newflags)
{
vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
int error = 0;
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
@ -554,24 +519,19 @@ STATIC int
xfs_file_open_exec(
struct inode *inode)
{
vnode_t *vp = vn_from_inode(inode);
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
int error = 0;
xfs_inode_t *ip;
bhv_vnode_t *vp = vn_from_inode(inode);
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
ip = xfs_vtoi(vp);
if (!ip) {
error = -EINVAL;
goto open_exec_out;
}
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) {
error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
xfs_inode_t *ip = xfs_vtoi(vp);
if (!ip)
return -EINVAL;
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
0, 0, 0, NULL);
}
}
open_exec_out:
return error;
return 0;
}
#endif /* HAVE_FOP_OPEN_EXEC */
@ -592,6 +552,7 @@ const struct file_operations xfs_file_operations = {
#endif
.mmap = xfs_file_mmap,
.open = xfs_file_open,
.flush = xfs_file_close,
.release = xfs_file_release,
.fsync = xfs_file_fsync,
#ifdef HAVE_FOP_OPEN_EXEC
@ -616,6 +577,7 @@ const struct file_operations xfs_invis_file_operations = {
#endif
.mmap = xfs_file_mmap,
.open = xfs_file_open,
.flush = xfs_file_close,
.release = xfs_file_release,
.fsync = xfs_file_fsync,
};

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -15,40 +15,12 @@
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
/*
* Stub for no-op vnode operations that return error status.
*/
int
fs_noerr(void)
{
return 0;
}
int fs_noerr(void) { return 0; }
int fs_nosys(void) { return ENOSYS; }
void fs_noval(void) { return; }
/*
* Operation unsupported under this file system.
*/
int
fs_nosys(void)
{
return ENOSYS;
}
/*
* Stub for inactive, strategy, and read/write lock/unlock. Does nothing.
*/
/* ARGSUSED */
void
fs_noval(void)
{
}
/*
* vnode pcache layer for vnode_tosspages.
* 'last' parameter unused but left in for IRIX compatibility
*/
void
fs_tosspages(
bhv_desc_t *bdp,
@ -56,18 +28,13 @@ fs_tosspages(
xfs_off_t last,
int fiopt)
{
vnode_t *vp = BHV_TO_VNODE(bdp);
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = vn_to_inode(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,
@ -75,20 +42,17 @@ fs_flushinval_pages(
xfs_off_t last,
int fiopt)
{
vnode_t *vp = BHV_TO_VNODE(bdp);
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = vn_to_inode(vp);
if (VN_CACHED(vp)) {
if (VN_TRUNC(vp))
VUNTRUNCATE(vp);
filemap_write_and_wait(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,
@ -97,15 +61,16 @@ fs_flush_pages(
uint64_t flags,
int fiopt)
{
vnode_t *vp = BHV_TO_VNODE(bdp);
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
struct inode *ip = vn_to_inode(vp);
if (VN_CACHED(vp)) {
if (VN_DIRTY(vp)) {
if (VN_TRUNC(vp))
VUNTRUNCATE(vp);
filemap_fdatawrite(ip->i_mapping);
if (flags & XFS_B_ASYNC)
return 0;
filemap_fdatawait(ip->i_mapping);
}
return 0;
}

Просмотреть файл

@ -45,6 +45,7 @@ xfs_param_t xfs_params = {
.xfs_buf_age = { 1*100, 15*100, 7200*100},
.inherit_nosym = { 0, 0, 1 },
.rotorstep = { 1, 1, 255 },
.inherit_nodfrg = { 0, 1, 1 },
};
/*

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -31,7 +30,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
@ -78,7 +76,7 @@ xfs_find_handle(
xfs_handle_t handle;
xfs_fsop_handlereq_t hreq;
struct inode *inode;
struct vnode *vp;
bhv_vnode_t *vp;
if (copy_from_user(&hreq, arg, sizeof(hreq)))
return -XFS_ERROR(EFAULT);
@ -192,7 +190,7 @@ xfs_vget_fsop_handlereq(
xfs_mount_t *mp,
struct inode *parinode, /* parent inode pointer */
xfs_fsop_handlereq_t *hreq,
vnode_t **vp,
bhv_vnode_t **vp,
struct inode **inode)
{
void __user *hanp;
@ -202,7 +200,7 @@ xfs_vget_fsop_handlereq(
xfs_handle_t handle;
xfs_inode_t *ip;
struct inode *inodep;
vnode_t *vpp;
bhv_vnode_t *vpp;
xfs_ino_t ino;
__u32 igen;
int error;
@ -277,7 +275,7 @@ xfs_open_by_handle(
struct file *filp;
struct inode *inode;
struct dentry *dentry;
vnode_t *vp;
bhv_vnode_t *vp;
xfs_fsop_handlereq_t hreq;
if (!capable(CAP_SYS_ADMIN))
@ -362,7 +360,7 @@ xfs_readlink_by_handle(
struct uio auio;
struct inode *inode;
xfs_fsop_handlereq_t hreq;
vnode_t *vp;
bhv_vnode_t *vp;
__u32 olen;
if (!capable(CAP_SYS_ADMIN))
@ -393,9 +391,11 @@ xfs_readlink_by_handle(
auio.uio_segflg = UIO_USERSPACE;
auio.uio_resid = olen;
VOP_READLINK(vp, &auio, IO_INVIS, NULL, error);
error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
VN_RELE(vp);
if (error)
return -error;
return (olen - auio.uio_resid);
}
@ -411,7 +411,7 @@ xfs_fssetdm_by_handle(
xfs_fsop_setdm_handlereq_t dmhreq;
struct inode *inode;
bhv_desc_t *bdp;
vnode_t *vp;
bhv_vnode_t *vp;
if (!capable(CAP_MKNOD))
return -XFS_ERROR(EPERM);
@ -452,7 +452,7 @@ xfs_attrlist_by_handle(
attrlist_cursor_kern_t *cursor;
xfs_fsop_attrlist_handlereq_t al_hreq;
struct inode *inode;
vnode_t *vp;
bhv_vnode_t *vp;
char *kbuf;
if (!capable(CAP_SYS_ADMIN))
@ -472,8 +472,8 @@ xfs_attrlist_by_handle(
goto out_vn_rele;
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags,
cursor, NULL, error);
error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
cursor, NULL);
if (error)
goto out_kfree;
@ -490,7 +490,7 @@ xfs_attrlist_by_handle(
STATIC int
xfs_attrmulti_attr_get(
struct vnode *vp,
bhv_vnode_t *vp,
char *name,
char __user *ubuf,
__uint32_t *len,
@ -505,7 +505,7 @@ xfs_attrmulti_attr_get(
if (!kbuf)
return ENOMEM;
VOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error);
error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
if (error)
goto out_kfree;
@ -519,7 +519,7 @@ xfs_attrmulti_attr_get(
STATIC int
xfs_attrmulti_attr_set(
struct vnode *vp,
bhv_vnode_t *vp,
char *name,
const char __user *ubuf,
__uint32_t len,
@ -542,7 +542,7 @@ xfs_attrmulti_attr_set(
if (copy_from_user(kbuf, ubuf, len))
goto out_kfree;
VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error);
error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
out_kfree:
kfree(kbuf);
@ -551,20 +551,15 @@ xfs_attrmulti_attr_set(
STATIC int
xfs_attrmulti_attr_remove(
struct vnode *vp,
bhv_vnode_t *vp,
char *name,
__uint32_t flags)
{
int error;
if (IS_RDONLY(&vp->v_inode))
return -EROFS;
if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
return EPERM;
VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
return error;
return bhv_vop_attr_remove(vp, name, flags, NULL);
}
STATIC int
@ -578,7 +573,7 @@ xfs_attrmulti_by_handle(
xfs_attr_multiop_t *ops;
xfs_fsop_attrmulti_handlereq_t am_hreq;
struct inode *inode;
vnode_t *vp;
bhv_vnode_t *vp;
unsigned int i, size;
char *attr_name;
@ -658,7 +653,7 @@ xfs_attrmulti_by_handle(
STATIC int
xfs_ioc_space(
bhv_desc_t *bdp,
vnode_t *vp,
bhv_vnode_t *vp,
struct file *filp,
int flags,
unsigned int cmd,
@ -682,7 +677,7 @@ xfs_ioc_fsgeometry(
STATIC int
xfs_ioc_xattr(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_inode_t *ip,
struct file *filp,
unsigned int cmd,
@ -711,7 +706,7 @@ xfs_ioctl(
void __user *arg)
{
int error;
vnode_t *vp;
bhv_vnode_t *vp;
xfs_inode_t *ip;
xfs_mount_t *mp;
@ -962,7 +957,7 @@ xfs_ioctl(
STATIC int
xfs_ioc_space(
bhv_desc_t *bdp,
vnode_t *vp,
bhv_vnode_t *vp,
struct file *filp,
int ioflags,
unsigned int cmd,
@ -1153,14 +1148,14 @@ xfs_di2lxflags(
STATIC int
xfs_ioc_xattr(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_inode_t *ip,
struct file *filp,
unsigned int cmd,
void __user *arg)
{
struct fsxattr fa;
struct vattr *vattr;
struct bhv_vattr *vattr;
int error = 0;
int attr_flags;
unsigned int flags;
@ -1173,7 +1168,7 @@ xfs_ioc_xattr(
case XFS_IOC_FSGETXATTR: {
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
XFS_AT_NEXTENTS | XFS_AT_PROJID;
VOP_GETATTR(vp, vattr, 0, NULL, error);
error = bhv_vop_getattr(vp, vattr, 0, NULL);
if (unlikely(error)) {
error = -error;
break;
@ -1206,7 +1201,7 @@ xfs_ioc_xattr(
vattr->va_extsize = fa.fsx_extsize;
vattr->va_projid = fa.fsx_projid;
VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
if (likely(!error))
__vn_revalidate(vp, vattr); /* update flags */
error = -error;
@ -1216,7 +1211,7 @@ xfs_ioc_xattr(
case XFS_IOC_FSGETXATTRA: {
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
XFS_AT_ANEXTENTS | XFS_AT_PROJID;
VOP_GETATTR(vp, vattr, 0, NULL, error);
error = bhv_vop_getattr(vp, vattr, 0, NULL);
if (unlikely(error)) {
error = -error;
break;
@ -1262,7 +1257,7 @@ xfs_ioc_xattr(
vattr->va_xflags = xfs_merge_ioc_xflags(flags,
xfs_ip2xflags(ip));
VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
if (likely(!error))
__vn_revalidate(vp, vattr); /* update flags */
error = -error;

Просмотреть файл

@ -114,7 +114,7 @@ xfs_compat_ioctl(
unsigned long arg)
{
struct inode *inode = file->f_dentry->d_inode;
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
int error;
switch (cmd) {
@ -193,7 +193,7 @@ xfs_compat_ioctl(
return -ENOIOCTLCMD;
}
VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error);
error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg);
VMODIFY(vp);
return error;

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -61,7 +59,7 @@
*/
xfs_inode_t *
xfs_vtoi(
struct vnode *vp)
bhv_vnode_t *vp)
{
bhv_desc_t *bdp;
@ -80,7 +78,7 @@ void
xfs_synchronize_atime(
xfs_inode_t *ip)
{
vnode_t *vp;
bhv_vnode_t *vp;
vp = XFS_ITOV_NULL(ip);
if (vp) {
@ -200,14 +198,10 @@ xfs_ichgtime_fast(
STATIC void
xfs_validate_fields(
struct inode *ip,
struct vattr *vattr)
bhv_vattr_t *vattr)
{
vnode_t *vp = vn_from_inode(ip);
int error;
vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error);
if (likely(!error)) {
if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) {
ip->i_nlink = vattr->va_nlink;
ip->i_blocks = vattr->va_nblocks;
@ -225,7 +219,7 @@ xfs_validate_fields(
*/
STATIC int
xfs_init_security(
struct vnode *vp,
bhv_vnode_t *vp,
struct inode *dir)
{
struct inode *ip = vn_to_inode(vp);
@ -241,7 +235,7 @@ xfs_init_security(
return -error;
}
VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error);
error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL);
if (!error)
VMODIFY(vp);
@ -264,13 +258,12 @@ xfs_has_fs_struct(struct task_struct *task)
STATIC inline void
xfs_cleanup_inode(
vnode_t *dvp,
vnode_t *vp,
bhv_vnode_t *dvp,
bhv_vnode_t *vp,
struct dentry *dentry,
int mode)
{
struct dentry teardown = {};
int error;
/* Oh, the horror.
* If we can't add the ACL or we fail in
@ -281,9 +274,9 @@ xfs_cleanup_inode(
teardown.d_name = dentry->d_name;
if (S_ISDIR(mode))
VOP_RMDIR(dvp, &teardown, NULL, error);
bhv_vop_rmdir(dvp, &teardown, NULL);
else
VOP_REMOVE(dvp, &teardown, NULL, error);
bhv_vop_remove(dvp, &teardown, NULL);
VN_RELE(vp);
}
@ -295,8 +288,8 @@ xfs_vn_mknod(
dev_t rdev)
{
struct inode *ip;
vattr_t vattr = { 0 };
vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
bhv_vattr_t vattr = { 0 };
bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
xfs_acl_t *default_acl = NULL;
attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
int error;
@ -330,10 +323,10 @@ xfs_vn_mknod(
vattr.va_mask |= XFS_AT_RDEV;
/*FALLTHROUGH*/
case S_IFREG:
VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error);
error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL);
break;
case S_IFDIR:
VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error);
error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL);
break;
default:
error = EINVAL;
@ -396,14 +389,14 @@ xfs_vn_lookup(
struct dentry *dentry,
struct nameidata *nd)
{
struct vnode *vp = vn_from_inode(dir), *cvp;
bhv_vnode_t *vp = vn_from_inode(dir), *cvp;
int error;
if (dentry->d_name.len >= MAXNAMELEN)
return ERR_PTR(-ENAMETOOLONG);
VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
if (error) {
error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL);
if (unlikely(error)) {
if (unlikely(error != ENOENT))
return ERR_PTR(-error);
d_add(dentry, NULL);
@ -420,9 +413,9 @@ xfs_vn_link(
struct dentry *dentry)
{
struct inode *ip; /* inode of guy being linked to */
vnode_t *tdvp; /* target directory for new name/link */
vnode_t *vp; /* vp of name being linked */
vattr_t vattr;
bhv_vnode_t *tdvp; /* target directory for new name/link */
bhv_vnode_t *vp; /* vp of name being linked */
bhv_vattr_t vattr;
int error;
ip = old_dentry->d_inode; /* inode being linked to */
@ -432,7 +425,7 @@ xfs_vn_link(
tdvp = vn_from_inode(dir);
vp = vn_from_inode(ip);
VOP_LINK(tdvp, vp, dentry, NULL, error);
error = bhv_vop_link(tdvp, vp, dentry, NULL);
if (likely(!error)) {
VMODIFY(tdvp);
VN_HOLD(vp);
@ -448,14 +441,14 @@ xfs_vn_unlink(
struct dentry *dentry)
{
struct inode *inode;
vnode_t *dvp; /* directory containing name to remove */
vattr_t vattr;
bhv_vnode_t *dvp; /* directory containing name to remove */
bhv_vattr_t vattr;
int error;
inode = dentry->d_inode;
dvp = vn_from_inode(dir);
VOP_REMOVE(dvp, dentry, NULL, error);
error = bhv_vop_remove(dvp, dentry, NULL);
if (likely(!error)) {
xfs_validate_fields(dir, &vattr); /* size needs update */
xfs_validate_fields(inode, &vattr);
@ -470,27 +463,26 @@ xfs_vn_symlink(
const char *symname)
{
struct inode *ip;
vattr_t vattr = { 0 };
vnode_t *dvp; /* directory containing name of symlink */
vnode_t *cvp; /* used to lookup symlink to put in dentry */
bhv_vattr_t va = { 0 };
bhv_vnode_t *dvp; /* directory containing name of symlink */
bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
int error;
dvp = vn_from_inode(dir);
cvp = NULL;
vattr.va_mode = S_IFLNK |
va.va_mode = S_IFLNK |
(irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
error = 0;
VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error);
error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL);
if (likely(!error && cvp)) {
error = xfs_init_security(cvp, dir);
if (likely(!error)) {
ip = vn_to_inode(cvp);
d_instantiate(dentry, ip);
xfs_validate_fields(dir, &vattr);
xfs_validate_fields(ip, &vattr);
xfs_validate_fields(dir, &va);
xfs_validate_fields(ip, &va);
} else {
xfs_cleanup_inode(dvp, cvp, dentry, 0);
}
@ -504,11 +496,11 @@ xfs_vn_rmdir(
struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
vnode_t *dvp = vn_from_inode(dir);
vattr_t vattr;
bhv_vnode_t *dvp = vn_from_inode(dir);
bhv_vattr_t vattr;
int error;
VOP_RMDIR(dvp, dentry, NULL, error);
error = bhv_vop_rmdir(dvp, dentry, NULL);
if (likely(!error)) {
xfs_validate_fields(inode, &vattr);
xfs_validate_fields(dir, &vattr);
@ -524,15 +516,15 @@ xfs_vn_rename(
struct dentry *ndentry)
{
struct inode *new_inode = ndentry->d_inode;
vnode_t *fvp; /* from directory */
vnode_t *tvp; /* target directory */
vattr_t vattr;
bhv_vnode_t *fvp; /* from directory */
bhv_vnode_t *tvp; /* target directory */
bhv_vattr_t vattr;
int error;
fvp = vn_from_inode(odir);
tvp = vn_from_inode(ndir);
VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL);
if (likely(!error)) {
if (new_inode)
xfs_validate_fields(new_inode, &vattr);
@ -553,7 +545,7 @@ xfs_vn_follow_link(
struct dentry *dentry,
struct nameidata *nd)
{
vnode_t *vp;
bhv_vnode_t *vp;
uio_t *uio;
iovec_t iov;
int error;
@ -586,8 +578,8 @@ xfs_vn_follow_link(
uio->uio_resid = MAXPATHLEN;
uio->uio_iovcnt = 1;
VOP_READLINK(vp, uio, 0, NULL, error);
if (error) {
error = bhv_vop_readlink(vp, uio, 0, NULL);
if (unlikely(error)) {
kfree(link);
link = ERR_PTR(-error);
} else {
@ -618,12 +610,7 @@ xfs_vn_permission(
int mode,
struct nameidata *nd)
{
vnode_t *vp = vn_from_inode(inode);
int error;
mode <<= 6; /* convert from linux to vnode access bits */
VOP_ACCESS(vp, mode, NULL, error);
return -error;
return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
}
#else
#define xfs_vn_permission NULL
@ -636,14 +623,14 @@ xfs_vn_getattr(
struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
int error = 0;
if (unlikely(vp->v_flag & VMODIFIED))
error = vn_revalidate(vp);
if (!error)
generic_fillattr(inode, stat);
return 0;
return -error;
}
STATIC int
@ -653,8 +640,8 @@ xfs_vn_setattr(
{
struct inode *inode = dentry->d_inode;
unsigned int ia_valid = attr->ia_valid;
vnode_t *vp = vn_from_inode(inode);
vattr_t vattr = { 0 };
bhv_vnode_t *vp = vn_from_inode(inode);
bhv_vattr_t vattr = { 0 };
int flags = 0;
int error;
@ -697,7 +684,7 @@ xfs_vn_setattr(
flags |= ATTR_NONBLOCK;
#endif
VOP_SETATTR(vp, &vattr, flags, NULL, error);
error = bhv_vop_setattr(vp, &vattr, flags, NULL);
if (likely(!error))
__vn_revalidate(vp, &vattr);
return -error;
@ -718,7 +705,7 @@ xfs_vn_setxattr(
size_t size,
int flags)
{
vnode_t *vp = vn_from_inode(dentry->d_inode);
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
char *attr = (char *)name;
attrnames_t *namesp;
int xflags = 0;
@ -748,7 +735,7 @@ xfs_vn_getxattr(
void *data,
size_t size)
{
vnode_t *vp = vn_from_inode(dentry->d_inode);
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
char *attr = (char *)name;
attrnames_t *namesp;
int xflags = 0;
@ -777,7 +764,7 @@ xfs_vn_listxattr(
char *data,
size_t size)
{
vnode_t *vp = vn_from_inode(dentry->d_inode);
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
int error, xflags = ATTR_KERNAMELS;
ssize_t result;
@ -796,7 +783,7 @@ xfs_vn_removexattr(
struct dentry *dentry,
const char *name)
{
vnode_t *vp = vn_from_inode(dentry->d_inode);
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
char *attr = (char *)name;
attrnames_t *namesp;
int xflags = 0;

Просмотреть файл

@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten);
#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
#define xfs_rotorstep xfs_params.rotorstep.val
#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
#ifndef raw_smp_processor_id
#define raw_smp_processor_id() smp_processor_id()
#endif
#define current_cpu() raw_smp_processor_id()
#define current_cpu() (raw_smp_processor_id())
#define current_pid() (current->pid)
#define current_fsuid(cred) (current->fsuid)
#define current_fsgid(cred) (current->fsgid)
#define current_set_flags(f) (current->flags |= (f))
#define current_test_flags(f) (current->flags & (f))
#define current_clear_flags(f) (current->flags & ~(f))
#define current_set_flags_nested(sp, f) \
(*(sp) = current->flags, current->flags |= (f))
#define current_clear_flags_nested(sp, f) \
(*(sp) = current->flags, current->flags &= ~(f))
#define current_restore_flags_nested(sp, f) \
(current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
#define NBPP PAGE_SIZE
#define DPPSHFT (PAGE_SHIFT - 9)
@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten);
/* bytes to clicks */
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
#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 EWRONGFS EINVAL /* Mount with wrong filesystem type */
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
#define SYNCHRONIZE() barrier()
#define __return_address __builtin_return_address(0)

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -206,7 +204,7 @@ xfs_read(
xfs_fsize_t n;
xfs_inode_t *ip;
xfs_mount_t *mp;
vnode_t *vp;
bhv_vnode_t *vp;
unsigned long seg;
ip = XFS_BHVTOI(bdp);
@ -258,7 +256,7 @@ xfs_read(
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
!(ioflags & IO_INVIS)) {
vrwlock_t locktype = VRWLOCK_READ;
bhv_vrwlock_t locktype = VRWLOCK_READ;
int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
@ -271,7 +269,7 @@ xfs_read(
}
if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)),
bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
-1, FI_REMAPF_LOCKED);
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
@ -313,7 +311,7 @@ xfs_sendfile(
if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
(!(ioflags & IO_INVIS))) {
vrwlock_t locktype = VRWLOCK_READ;
bhv_vrwlock_t locktype = VRWLOCK_READ;
int error;
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@ -357,7 +355,7 @@ xfs_splice_read(
if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
(!(ioflags & IO_INVIS))) {
vrwlock_t locktype = VRWLOCK_READ;
bhv_vrwlock_t locktype = VRWLOCK_READ;
int error;
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@ -401,7 +399,7 @@ xfs_splice_write(
if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
(!(ioflags & IO_INVIS))) {
vrwlock_t locktype = VRWLOCK_WRITE;
bhv_vrwlock_t locktype = VRWLOCK_WRITE;
int error;
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
@ -458,7 +456,7 @@ xfs_zero_last_block(
last_fsb = XFS_B_TO_FSBT(mp, isize);
nimaps = 1;
error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
&nimaps, NULL);
&nimaps, NULL, NULL);
if (error) {
return error;
}
@ -499,7 +497,7 @@ xfs_zero_last_block(
int /* error (positive) */
xfs_zero_eof(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_iocore_t *io,
xfs_off_t offset, /* starting I/O offset */
xfs_fsize_t isize, /* current inode size */
@ -510,7 +508,6 @@ xfs_zero_eof(
xfs_fileoff_t end_zero_fsb;
xfs_fileoff_t zero_count_fsb;
xfs_fileoff_t last_fsb;
xfs_extlen_t buf_len_fsb;
xfs_mount_t *mp = io->io_mount;
int nimaps;
int error = 0;
@ -556,7 +553,7 @@ xfs_zero_eof(
nimaps = 1;
zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
0, NULL, 0, &imap, &nimaps, NULL);
0, NULL, 0, &imap, &nimaps, NULL, NULL);
if (error) {
ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@ -579,16 +576,7 @@ xfs_zero_eof(
}
/*
* There are blocks in the range requested.
* Zero them a single write at a time. We actually
* don't zero the entire range returned if it is
* too big and simply loop around to get the rest.
* That is not the most efficient thing to do, but it
* is simple and this path should not be exercised often.
*/
buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount,
mp->m_writeio_blocks << 8);
/*
* There are blocks we need to zero.
* Drop the inode lock while we're doing the I/O.
* We'll still have the iolock to protect us.
*/
@ -596,14 +584,13 @@ xfs_zero_eof(
error = xfs_iozero(ip,
XFS_FSB_TO_B(mp, start_zero_fsb),
XFS_FSB_TO_B(mp, buf_len_fsb),
XFS_FSB_TO_B(mp, imap.br_blockcount),
end_size);
if (error) {
goto out_lock;
}
start_zero_fsb = imap.br_startoff + buf_len_fsb;
start_zero_fsb = imap.br_startoff + imap.br_blockcount;
ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@ -637,11 +624,11 @@ xfs_write(
ssize_t ret = 0, error = 0;
xfs_fsize_t isize, new_size;
xfs_iocore_t *io;
vnode_t *vp;
bhv_vnode_t *vp;
unsigned long seg;
int iolock;
int eventsent = 0;
vrwlock_t locktype;
bhv_vrwlock_t locktype;
size_t ocount = 0, count;
loff_t pos;
int need_i_mutex = 1, need_flush = 0;
@ -679,11 +666,11 @@ xfs_write(
io = &xip->i_iocore;
mp = io->io_mount;
vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
if (ioflags & IO_ISDIRECT) {
xfs_buftarg_t *target =
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@ -814,7 +801,7 @@ retry:
if (need_flush) {
xfs_inval_cached_trace(io, pos, -1,
ctooff(offtoct(pos)), -1);
VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)),
bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
-1, FI_REMAPF_LOCKED);
}
@ -903,79 +890,9 @@ retry:
/* Handle various SYNC-type writes */
if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
/*
* If we're treating this as O_DSYNC and we have not updated the
* size, force the log.
*/
if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
!(xip->i_update_size)) {
xfs_inode_log_item_t *iip = xip->i_itemp;
/*
* If an allocation transaction occurred
* without extending the size, then we have to force
* the log up the proper point to ensure that the
* allocation is permanent. We can't count on
* the fact that buffered writes lock out direct I/O
* writes - the direct I/O write could have extended
* the size nontransactionally, then finished before
* we started. xfs_write_file will think that the file
* didn't grow but the update isn't safe unless the
* size change is logged.
*
* Force the log if we've committed a transaction
* against the inode or if someone else has and
* the commit record hasn't gone to disk (e.g.
* the inode is pinned). This guarantees that
* all changes affecting the inode are permanent
* when we return.
*/
if (iip && iip->ili_last_lsn) {
xfs_log_force(mp, iip->ili_last_lsn,
XFS_LOG_FORCE | XFS_LOG_SYNC);
} else if (xfs_ipincount(xip) > 0) {
xfs_log_force(mp, (xfs_lsn_t)0,
XFS_LOG_FORCE | XFS_LOG_SYNC);
}
} else {
xfs_trans_t *tp;
/*
* O_SYNC or O_DSYNC _with_ a size update are handled
* the same way.
*
* If the write was synchronous then we need to make
* sure that the inode modification time is permanent.
* We'll have updated the timestamp above, so here
* we use a synchronous transaction to log the inode.
* It's not fast, but it's necessary.
*
* If this a dsync write and the size got changed
* non-transactionally, then we need to ensure that
* the size change gets logged in a synchronous
* transaction.
*/
tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
if ((error = xfs_trans_reserve(tp, 0,
XFS_SWRITE_LOG_RES(mp),
0, 0, 0))) {
/* Transaction reserve failed */
xfs_trans_cancel(tp, 0);
} else {
/* Transaction reserve successful */
xfs_ilock(xip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, xip);
xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0, NULL);
xfs_iunlock(xip, XFS_ILOCK_EXCL);
}
if (error)
goto out_unlock_internal;
}
error = xfs_write_sync_logforce(mp, xip);
if (error)
goto out_unlock_internal;
xfs_rwunlock(bdp, locktype);
if (need_i_mutex)

Просмотреть файл

@ -18,8 +18,8 @@
#ifndef __XFS_LRW_H__
#define __XFS_LRW_H__
struct vnode;
struct bhv_desc;
struct bhv_vnode;
struct xfs_mount;
struct xfs_iocore;
struct xfs_inode;
@ -49,7 +49,7 @@ struct xfs_iomap;
#define XFS_CTRUNC4 14
#define XFS_CTRUNC5 15
#define XFS_CTRUNC6 16
#define XFS_BUNMAPI 17
#define XFS_BUNMAP 17
#define XFS_INVAL_CACHED 18
#define XFS_DIORD_ENTER 19
#define XFS_DIOWR_ENTER 20
@ -82,7 +82,7 @@ extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
extern int xfs_bdstrat_cb(struct xfs_buf *);
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t,
xfs_fsize_t, xfs_fsize_t);
extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
const struct iovec *, unsigned int,

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -151,7 +149,7 @@ xfs_set_inodeops(
STATIC __inline__ void
xfs_revalidate_inode(
xfs_mount_t *mp,
vnode_t *vp,
bhv_vnode_t *vp,
xfs_inode_t *ip)
{
struct inode *inode = vn_to_inode(vp);
@ -206,7 +204,7 @@ xfs_revalidate_inode(
void
xfs_initialize_vnode(
bhv_desc_t *bdp,
vnode_t *vp,
bhv_vnode_t *vp,
bhv_desc_t *inode_bhv,
int unlock)
{
@ -336,7 +334,7 @@ STATIC struct inode *
xfs_fs_alloc_inode(
struct super_block *sb)
{
vnode_t *vp;
bhv_vnode_t *vp;
vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
if (unlikely(!vp))
@ -359,13 +357,13 @@ xfs_fs_inode_init_once(
{
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR)
inode_init_once(vn_to_inode((vnode_t *)vnode));
inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
}
STATIC int
xfs_init_zones(void)
{
xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t",
xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
KM_ZONE_SPREAD,
xfs_fs_inode_init_once);
@ -409,22 +407,17 @@ xfs_fs_write_inode(
struct inode *inode,
int sync)
{
vnode_t *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
int error = 0, flags = FLUSH_INODE;
if (vp) {
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
if (sync)
flags |= FLUSH_SYNC;
VOP_IFLUSH(vp, flags, error);
if (error == EAGAIN) {
if (sync)
VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
else
error = 0;
}
error = bhv_vop_iflush(vp, flags);
if (error == EAGAIN)
error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
}
return -error;
}
@ -432,8 +425,7 @@ STATIC void
xfs_fs_clear_inode(
struct inode *inode)
{
vnode_t *vp = vn_from_inode(inode);
int error, cache;
bhv_vnode_t *vp = vn_from_inode(inode);
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@ -446,20 +438,18 @@ xfs_fs_clear_inode(
* This can happen because xfs_iget_core calls xfs_idestroy if we
* find an inode with di_mode == 0 but without IGET_CREATE set.
*/
if (vp->v_fbhv)
VOP_INACTIVE(vp, NULL, cache);
if (VNHEAD(vp))
bhv_vop_inactive(vp, NULL);
VN_LOCK(vp);
vp->v_flag &= ~VMODIFIED;
VN_UNLOCK(vp, 0);
if (vp->v_fbhv) {
VOP_RECLAIM(vp, error);
if (error)
panic("vn_purge: cannot reclaim");
}
if (VNHEAD(vp))
if (bhv_vop_reclaim(vp))
panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp);
ASSERT(vp->v_fbhv == NULL);
ASSERT(VNHEAD(vp) == NULL);
#ifdef XFS_VNODE_TRACE
ktrace_free(vp->v_trace);
@ -475,13 +465,13 @@ xfs_fs_clear_inode(
*/
STATIC void
xfs_syncd_queue_work(
struct vfs *vfs,
struct bhv_vfs *vfs,
void *data,
void (*syncer)(vfs_t *, void *))
void (*syncer)(bhv_vfs_t *, void *))
{
vfs_sync_work_t *work;
struct bhv_vfs_sync_work *work;
work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP);
work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP);
INIT_LIST_HEAD(&work->w_list);
work->w_syncer = syncer;
work->w_data = data;
@ -500,7 +490,7 @@ xfs_syncd_queue_work(
*/
STATIC void
xfs_flush_inode_work(
vfs_t *vfs,
bhv_vfs_t *vfs,
void *inode)
{
filemap_flush(((struct inode *)inode)->i_mapping);
@ -512,7 +502,7 @@ xfs_flush_inode(
xfs_inode_t *ip)
{
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
struct vfs *vfs = XFS_MTOVFS(ip->i_mount);
struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
igrab(inode);
xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
@ -525,7 +515,7 @@ xfs_flush_inode(
*/
STATIC void
xfs_flush_device_work(
vfs_t *vfs,
bhv_vfs_t *vfs,
void *inode)
{
sync_blockdev(vfs->vfs_super->s_bdev);
@ -537,7 +527,7 @@ xfs_flush_device(
xfs_inode_t *ip)
{
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
struct vfs *vfs = XFS_MTOVFS(ip->i_mount);
struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
igrab(inode);
xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
@ -545,16 +535,16 @@ xfs_flush_device(
xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
}
#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
STATIC void
vfs_sync_worker(
vfs_t *vfsp,
bhv_vfs_t *vfsp,
void *unused)
{
int error;
if (!(vfsp->vfs_flag & VFS_RDONLY))
VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
SYNC_ATTR | SYNC_REFCACHE, NULL);
vfsp->vfs_sync_seq++;
wmb();
wake_up(&vfsp->vfs_wait_single_sync_task);
@ -565,8 +555,8 @@ xfssyncd(
void *arg)
{
long timeleft;
vfs_t *vfsp = (vfs_t *) arg;
struct vfs_sync_work *work, *n;
bhv_vfs_t *vfsp = (bhv_vfs_t *) arg;
bhv_vfs_sync_work_t *work, *n;
LIST_HEAD (tmp);
timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
@ -600,7 +590,7 @@ xfssyncd(
list_del(&work->w_list);
if (work == &vfsp->vfs_sync_work)
continue;
kmem_free(work, sizeof(struct vfs_sync_work));
kmem_free(work, sizeof(struct bhv_vfs_sync_work));
}
}
@ -609,7 +599,7 @@ xfssyncd(
STATIC int
xfs_fs_start_syncd(
vfs_t *vfsp)
bhv_vfs_t *vfsp)
{
vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
vfsp->vfs_sync_work.w_vfs = vfsp;
@ -621,7 +611,7 @@ xfs_fs_start_syncd(
STATIC void
xfs_fs_stop_syncd(
vfs_t *vfsp)
bhv_vfs_t *vfsp)
{
kthread_stop(vfsp->vfs_sync_task);
}
@ -630,35 +620,26 @@ STATIC void
xfs_fs_put_super(
struct super_block *sb)
{
vfs_t *vfsp = vfs_from_sb(sb);
bhv_vfs_t *vfsp = vfs_from_sb(sb);
int error;
xfs_fs_stop_syncd(vfsp);
VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
if (!error)
VFS_UNMOUNT(vfsp, 0, NULL, error);
bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL);
error = bhv_vfs_unmount(vfsp, 0, NULL);
if (error) {
printk("XFS unmount got error %d\n", error);
printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp);
return;
printk("XFS: unmount got error=%d\n", error);
printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
} else {
vfs_deallocate(vfsp);
}
vfs_deallocate(vfsp);
}
STATIC void
xfs_fs_write_super(
struct super_block *sb)
{
vfs_t *vfsp = vfs_from_sb(sb);
int error;
if (sb->s_flags & MS_RDONLY) {
sb->s_dirt = 0; /* paranoia */
return;
}
/* Push the log and superblock a little */
VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
if (!(sb->s_flags & MS_RDONLY))
bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL);
sb->s_dirt = 0;
}
@ -667,16 +648,16 @@ xfs_fs_sync_super(
struct super_block *sb,
int wait)
{
vfs_t *vfsp = vfs_from_sb(sb);
int error;
int flags = SYNC_FSDATA;
bhv_vfs_t *vfsp = vfs_from_sb(sb);
int error;
int flags;
if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
flags = SYNC_QUIESCE;
else
flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
VFS_SYNC(vfsp, flags, NULL, error);
error = bhv_vfs_sync(vfsp, flags, NULL);
sb->s_dirt = 0;
if (unlikely(laptop_mode)) {
@ -706,11 +687,7 @@ xfs_fs_statfs(
struct super_block *sb,
struct kstatfs *statp)
{
vfs_t *vfsp = vfs_from_sb(sb);
int error;
VFS_STATVFS(vfsp, statp, NULL, error);
return -error;
return -bhv_vfs_statvfs(vfs_from_sb(sb), statp, NULL);
}
STATIC int
@ -719,13 +696,13 @@ xfs_fs_remount(
int *flags,
char *options)
{
vfs_t *vfsp = vfs_from_sb(sb);
bhv_vfs_t *vfsp = vfs_from_sb(sb);
struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
int error;
VFS_PARSEARGS(vfsp, options, args, 1, error);
error = bhv_vfs_parseargs(vfsp, options, args, 1);
if (!error)
VFS_MNTUPDATE(vfsp, flags, args, error);
error = bhv_vfs_mntupdate(vfsp, flags, args);
kmem_free(args, sizeof(*args));
return -error;
}
@ -734,7 +711,7 @@ STATIC void
xfs_fs_lockfs(
struct super_block *sb)
{
VFS_FREEZE(vfs_from_sb(sb));
bhv_vfs_freeze(vfs_from_sb(sb));
}
STATIC int
@ -742,11 +719,7 @@ xfs_fs_show_options(
struct seq_file *m,
struct vfsmount *mnt)
{
struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb);
int error;
VFS_SHOWARGS(vfsp, m, error);
return error;
return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m);
}
STATIC int
@ -754,11 +727,7 @@ xfs_fs_quotasync(
struct super_block *sb,
int type)
{
struct vfs *vfsp = vfs_from_sb(sb);
int error;
VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
return -error;
return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
}
STATIC int
@ -766,11 +735,7 @@ xfs_fs_getxstate(
struct super_block *sb,
struct fs_quota_stat *fqs)
{
struct vfs *vfsp = vfs_from_sb(sb);
int error;
VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
return -error;
return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
}
STATIC int
@ -779,11 +744,7 @@ xfs_fs_setxstate(
unsigned int flags,
int op)
{
struct vfs *vfsp = vfs_from_sb(sb);
int error;
VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
return -error;
return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
}
STATIC int
@ -793,13 +754,10 @@ xfs_fs_getxquota(
qid_t id,
struct fs_disk_quota *fdq)
{
struct vfs *vfsp = vfs_from_sb(sb);
int error, getmode;
getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
return -error;
return -bhv_vfs_quotactl(vfs_from_sb(sb),
(type == USRQUOTA) ? Q_XGETQUOTA :
((type == GRPQUOTA) ? Q_XGETGQUOTA :
Q_XGETPQUOTA), id, (caddr_t)fdq);
}
STATIC int
@ -809,13 +767,10 @@ xfs_fs_setxquota(
qid_t id,
struct fs_disk_quota *fdq)
{
struct vfs *vfsp = vfs_from_sb(sb);
int error, setmode;
setmode = (type == USRQUOTA) ? Q_XSETQLIM :
((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
return -error;
return -bhv_vfs_quotactl(vfs_from_sb(sb),
(type == USRQUOTA) ? Q_XSETQLIM :
((type == GRPQUOTA) ? Q_XSETGQLIM :
Q_XSETPQLIM), id, (caddr_t)fdq);
}
STATIC int
@ -824,34 +779,32 @@ xfs_fs_fill_super(
void *data,
int silent)
{
vnode_t *rootvp;
struct vfs *vfsp = vfs_allocate(sb);
struct bhv_vnode *rootvp;
struct bhv_vfs *vfsp = vfs_allocate(sb);
struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
struct kstatfs statvfs;
int error, error2;
int error;
bhv_insert_all_vfsops(vfsp);
VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0);
if (error) {
bhv_remove_all_vfsops(vfsp, 1);
goto fail_vfsop;
}
sb_min_blocksize(sb, BBSIZE);
#ifdef CONFIG_XFS_EXPORT
sb->s_export_op = &xfs_export_operations;
#endif
sb->s_qcop = &xfs_quotactl_operations;
sb->s_op = &xfs_super_operations;
VFS_MOUNT(vfsp, args, NULL, error);
error = bhv_vfs_mount(vfsp, args, NULL);
if (error) {
bhv_remove_all_vfsops(vfsp, 1);
goto fail_vfsop;
}
VFS_STATVFS(vfsp, &statvfs, NULL, error);
error = bhv_vfs_statvfs(vfsp, &statvfs, NULL);
if (error)
goto fail_unmount;
@ -863,7 +816,7 @@ xfs_fs_fill_super(
sb->s_time_gran = 1;
set_posix_acl_flag(sb);
VFS_ROOT(vfsp, &rootvp, error);
error = bhv_vfs_root(vfsp, &rootvp);
if (error)
goto fail_unmount;
@ -892,7 +845,7 @@ fail_vnrele:
}
fail_unmount:
VFS_UNMOUNT(vfsp, 0, NULL, error2);
bhv_vfs_unmount(vfsp, 0, NULL);
fail_vfsop:
vfs_deallocate(vfsp);

Просмотреть файл

@ -105,7 +105,7 @@ struct block_device;
extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int);
extern void xfs_flush_inode(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *);

Просмотреть файл

@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = {
&sysctl_intvec, NULL,
&xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
{XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
&sysctl_intvec, NULL,
&xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
/* please keep this the last entry */
#ifdef CONFIG_PROC_FS
{XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,

Просмотреть файл

@ -46,6 +46,7 @@ typedef struct xfs_param {
xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */
xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
} xfs_param_t;
/*
@ -84,6 +85,7 @@ enum {
/* XFS_IO_BYPASS = 18 */
XFS_INHERIT_NOSYM = 19,
XFS_ROTORSTEP = 20,
XFS_INHERIT_NODFRG = 21,
};
extern xfs_param_t xfs_params;

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_imap.h"
#include "xfs_alloc.h"
@ -104,7 +103,7 @@ vfs_mntupdate(
int
vfs_root(
struct bhv_desc *bdp,
struct vnode **vpp)
struct bhv_vnode **vpp)
{
struct bhv_desc *next = bdp;
@ -117,15 +116,15 @@ vfs_root(
int
vfs_statvfs(
struct bhv_desc *bdp,
xfs_statfs_t *sp,
struct vnode *vp)
bhv_statvfs_t *statp,
struct bhv_vnode *vp)
{
struct bhv_desc *next = bdp;
ASSERT(next);
while (! (bhvtovfsops(next))->vfs_statvfs)
next = BHV_NEXT(next);
return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp));
return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
}
int
@ -145,7 +144,7 @@ vfs_sync(
int
vfs_vget(
struct bhv_desc *bdp,
struct vnode **vpp,
struct bhv_vnode **vpp,
struct fid *fidp)
{
struct bhv_desc *next = bdp;
@ -187,7 +186,7 @@ vfs_quotactl(
void
vfs_init_vnode(
struct bhv_desc *bdp,
struct vnode *vp,
struct bhv_vnode *vp,
struct bhv_desc *bp,
int unlock)
{
@ -226,13 +225,13 @@ vfs_freeze(
((*bhvtovfsops(next)->vfs_freeze)(next));
}
vfs_t *
bhv_vfs_t *
vfs_allocate(
struct super_block *sb)
{
struct vfs *vfsp;
struct bhv_vfs *vfsp;
vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
INIT_LIST_HEAD(&vfsp->vfs_sync_list);
spin_lock_init(&vfsp->vfs_sync_lock);
@ -247,25 +246,25 @@ vfs_allocate(
return vfsp;
}
vfs_t *
bhv_vfs_t *
vfs_from_sb(
struct super_block *sb)
{
return (vfs_t *)sb->s_fs_info;
return (bhv_vfs_t *)sb->s_fs_info;
}
void
vfs_deallocate(
struct vfs *vfsp)
struct bhv_vfs *vfsp)
{
bhv_head_destroy(VFS_BHVHEAD(vfsp));
kmem_free(vfsp, sizeof(vfs_t));
kmem_free(vfsp, sizeof(bhv_vfs_t));
}
void
vfs_insertops(
struct vfs *vfsp,
struct bhv_vfsops *vfsops)
struct bhv_vfs *vfsp,
struct bhv_module_vfsops *vfsops)
{
struct bhv_desc *bdp;
@ -276,9 +275,9 @@ vfs_insertops(
void
vfs_insertbhv(
struct vfs *vfsp,
struct bhv_vfs *vfsp,
struct bhv_desc *bdp,
struct vfsops *vfsops,
struct bhv_vfsops *vfsops,
void *mount)
{
bhv_desc_init(bdp, mount, vfsp, vfsops);
@ -287,7 +286,7 @@ vfs_insertbhv(
void
bhv_remove_vfsops(
struct vfs *vfsp,
struct bhv_vfs *vfsp,
int pos)
{
struct bhv_desc *bhv;
@ -301,7 +300,7 @@ bhv_remove_vfsops(
void
bhv_remove_all_vfsops(
struct vfs *vfsp,
struct bhv_vfs *vfsp,
int freebase)
{
struct xfs_mount *mp;
@ -317,7 +316,7 @@ bhv_remove_all_vfsops(
void
bhv_insert_all_vfsops(
struct vfs *vfsp)
struct bhv_vfs *vfsp)
{
struct xfs_mount *mp;

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -21,42 +21,40 @@
#include <linux/vfs.h>
#include "xfs_fs.h"
struct bhv_vfs;
struct bhv_vnode;
struct fid;
struct vfs;
struct cred;
struct vnode;
struct kstatfs;
struct seq_file;
struct super_block;
struct xfs_mount_args;
typedef struct kstatfs xfs_statfs_t;
typedef struct kstatfs bhv_statvfs_t;
typedef struct vfs_sync_work {
typedef struct bhv_vfs_sync_work {
struct list_head w_list;
struct vfs *w_vfs;
struct bhv_vfs *w_vfs;
void *w_data; /* syncer routine argument */
void (*w_syncer)(struct vfs *, void *);
} vfs_sync_work_t;
void (*w_syncer)(struct bhv_vfs *, void *);
} bhv_vfs_sync_work_t;
typedef struct vfs {
typedef struct bhv_vfs {
u_int vfs_flag; /* flags */
xfs_fsid_t vfs_fsid; /* file system ID */
xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
bhv_head_t vfs_bh; /* head of vfs behavior chain */
struct super_block *vfs_super; /* generic superblock pointer */
struct task_struct *vfs_sync_task; /* generalised sync thread */
vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
bhv_vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
struct list_head vfs_sync_list; /* sync thread work item list */
spinlock_t vfs_sync_lock; /* work item list lock */
int vfs_sync_seq; /* sync thread generation no. */
int vfs_sync_seq; /* sync thread generation no. */
wait_queue_head_t vfs_wait_single_sync_task;
} vfs_t;
} bhv_vfs_t;
#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
#define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) )
#define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) )
#define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
@ -71,7 +69,7 @@ typedef enum {
VFS_BHV_QM, /* quota manager */
VFS_BHV_IO, /* IO path */
VFS_BHV_END /* housekeeping end-of-range */
} vfs_bhv_t;
} bhv_vfs_type_t;
#define VFS_POSITION_XFS (BHV_POSITION_BASE)
#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
@ -81,8 +79,9 @@ typedef enum {
#define VFS_RDONLY 0x0001 /* read-only vfs */
#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */
#define VFS_END 0x0008 /* max flag */
#define VFS_UMOUNT 0x0008 /* unmount in progress */
#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
#define VFS_END 0x0010 /* max flag */
#define SYNC_ATTR 0x0001 /* sync attributes */
#define SYNC_CLOSE 0x0002 /* close file system down */
@ -92,7 +91,14 @@ typedef enum {
#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */
#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
typedef int (*vfs_mount_t)(bhv_desc_t *,
struct xfs_mount_args *, struct cred *);
@ -102,18 +108,19 @@ typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
struct xfs_mount_args *);
typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **);
typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *);
typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
struct bhv_vnode *);
typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *);
typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
struct vnode *, bhv_desc_t *, int);
struct bhv_vnode *, bhv_desc_t *, int);
typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
typedef void (*vfs_freeze_t)(bhv_desc_t *);
typedef struct vfsops {
typedef struct bhv_vfsops {
bhv_position_t vf_position; /* behavior chain position */
vfs_mount_t vfs_mount; /* mount file system */
vfs_parseargs_t vfs_parseargs; /* parse mount options */
@ -129,82 +136,82 @@ typedef struct vfsops {
vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
} vfsops_t;
} bhv_vfsops_t;
/*
* VFS's. Operates on vfs structure pointers (starts at bhv head).
* Virtual filesystem operations, operating from head bhv.
*/
#define VHEAD(v) ((v)->vfs_fbhv)
#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr))
#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f))
#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m))
#define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr))
#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args))
#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp))
#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp))
#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr))
#define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp))
#define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p))
#define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p))
#define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) )
#define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) )
#define VFS_FREEZE(v) ( vfs_freeze(VHEAD(v)) )
#define VFSHEAD(v) ((v)->vfs_bh.bh_first)
#define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
#define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
#define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
#define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
#define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
#define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
/*
* PVFS's. Operates on behavior descriptor pointers.
* Virtual filesystem operations, operating from next bhv.
*/
#define PVFS_MOUNT(b, ma,cr, rv) ((rv) = vfs_mount(b, ma,cr))
#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f))
#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m))
#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr))
#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args))
#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp))
#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp))
#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr))
#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp))
#define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p))
#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p))
#define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) )
#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) )
#define PVFS_FREEZE(b) ( vfs_freeze(b) )
#define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
#define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
#define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
#define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
#define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
#define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
#define bhv_next_vfs_freeze(b) vfs_freeze(b)
extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
extern int vfs_root(bhv_desc_t *, struct vnode **);
extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *);
extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
extern int vfs_sync(bhv_desc_t *, int, struct cred *);
extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *);
extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int);
extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
extern void vfs_freeze(bhv_desc_t *);
typedef struct bhv_vfsops {
struct vfsops bhv_common;
#define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
#define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l))
typedef struct bhv_module_vfsops {
struct bhv_vfsops bhv_common;
void * bhv_custom;
} bhv_vfsops_t;
} bhv_module_vfsops_t;
#define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) )
#define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom )
#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o))
#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL )
#define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
#define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
#define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
#define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
extern vfs_t *vfs_allocate(struct super_block *);
extern vfs_t *vfs_from_sb(struct super_block *);
extern void vfs_deallocate(vfs_t *);
extern void vfs_insertops(vfs_t *, bhv_vfsops_t *);
extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
extern bhv_vfs_t *vfs_allocate(struct super_block *);
extern bhv_vfs_t *vfs_from_sb(struct super_block *);
extern void vfs_deallocate(bhv_vfs_t *);
extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
extern void bhv_insert_all_vfsops(struct vfs *);
extern void bhv_remove_all_vfsops(struct vfs *, int);
extern void bhv_remove_vfsops(struct vfs *, int);
extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
#define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen)
#define fs_check_frozen(vfsp, level) \
vfs_check_frozen(vfsp->vfs_super, level);
extern void bhv_insert_all_vfsops(struct bhv_vfs *);
extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
extern void bhv_remove_vfsops(struct bhv_vfs *, int);
#endif /* __XFS_VFS_H__ */

Просмотреть файл

@ -39,7 +39,7 @@ vn_init(void)
void
vn_iowait(
struct vnode *vp)
bhv_vnode_t *vp)
{
wait_queue_head_t *wq = vptosync(vp);
@ -48,17 +48,33 @@ vn_iowait(
void
vn_iowake(
struct vnode *vp)
bhv_vnode_t *vp)
{
if (atomic_dec_and_test(&vp->v_iocount))
wake_up(vptosync(vp));
}
struct vnode *
/*
* Volume managers supporting multiple paths can send back ENODEV when the
* final path disappears. In this case continuing to fill the page cache
* with dirty data which cannot be written out is evil, so prevent that.
*/
void
vn_ioerror(
bhv_vnode_t *vp,
int error,
char *f,
int l)
{
if (unlikely(error == -ENODEV))
bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
}
bhv_vnode_t *
vn_initialize(
struct inode *inode)
{
struct vnode *vp = vn_from_inode(inode);
bhv_vnode_t *vp = vn_from_inode(inode);
XFS_STATS_INC(vn_active);
XFS_STATS_INC(vn_alloc);
@ -94,8 +110,8 @@ vn_initialize(
*/
void
vn_revalidate_core(
struct vnode *vp,
vattr_t *vap)
bhv_vnode_t *vp,
bhv_vattr_t *vap)
{
struct inode *inode = vn_to_inode(vp);
@ -130,14 +146,14 @@ vn_revalidate_core(
*/
int
__vn_revalidate(
struct vnode *vp,
struct vattr *vattr)
bhv_vnode_t *vp,
bhv_vattr_t *vattr)
{
int error;
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
VOP_GETATTR(vp, vattr, 0, NULL, error);
error = bhv_vop_getattr(vp, vattr, 0, NULL);
if (likely(!error)) {
vn_revalidate_core(vp, vattr);
VUNMODIFY(vp);
@ -147,9 +163,9 @@ __vn_revalidate(
int
vn_revalidate(
struct vnode *vp)
bhv_vnode_t *vp)
{
vattr_t vattr;
bhv_vattr_t vattr;
return __vn_revalidate(vp, &vattr);
}
@ -157,9 +173,9 @@ vn_revalidate(
/*
* Add a reference to a referenced vnode.
*/
struct vnode *
bhv_vnode_t *
vn_hold(
struct vnode *vp)
bhv_vnode_t *vp)
{
struct inode *inode;
@ -192,31 +208,31 @@ vn_hold(
* Vnode tracing code.
*/
void
vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra)
vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra)
{
KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
}
void
vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra)
vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra)
{
KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
}
void
vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra)
vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
{
KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
}
void
vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra)
vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
{
KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
}
void
vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra)
vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
{
KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
}

Просмотреть файл

@ -14,57 +14,35 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Portions Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __XFS_VNODE_H__
#define __XFS_VNODE_H__
struct uio;
struct file;
struct vattr;
struct bhv_vfs;
struct bhv_vattr;
struct xfs_iomap;
struct attrlist_cursor_kern;
typedef struct dentry bhv_vname_t;
typedef __u64 bhv_vnumber_t;
typedef xfs_ino_t vnumber_t;
typedef struct dentry vname_t;
typedef bhv_head_t vn_bhv_head_t;
typedef enum bhv_vflags {
VMODIFIED = 0x08, /* XFS inode state possibly differs */
/* to the Linux inode state. */
VTRUNCATED = 0x40, /* truncated down so flush-on-close */
} bhv_vflags_t;
/*
* MP locking protocols:
* v_flag, v_vfsp VN_LOCK/VN_UNLOCK
*/
typedef struct vnode {
__u32 v_flag; /* vnode flags (see below) */
struct vfs *v_vfsp; /* ptr to containing VFS */
vnumber_t v_number; /* in-core vnode number */
vn_bhv_head_t v_bh; /* behavior head */
typedef struct bhv_vnode {
bhv_vflags_t v_flag; /* vnode flags (see above) */
bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
bhv_vnumber_t v_number; /* in-core vnode number */
bhv_head_t v_bh; /* behavior head */
spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
atomic_t v_iocount; /* outstanding I/O count */
#ifdef XFS_VNODE_TRACE
@ -72,7 +50,7 @@ typedef struct vnode {
#endif
struct inode v_inode; /* Linux inode */
/* inode MUST be last */
} vnode_t;
} bhv_vnode_t;
#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode)
@ -80,9 +58,6 @@ typedef struct vnode {
#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode)
#define v_fbhv v_bh.bh_first /* first behavior */
#define v_fops v_bh.bh_first->bd_ops /* first behavior ops */
#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
@ -104,8 +79,8 @@ typedef enum {
/*
* Macros for dealing with the behavior descriptor inside of the vnode.
*/
#define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp))
#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp))
#define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
@ -116,35 +91,29 @@ typedef enum {
/*
* Vnode to Linux inode mapping.
*/
static inline struct vnode *vn_from_inode(struct inode *inode)
static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
{
return (vnode_t *)list_entry(inode, vnode_t, v_inode);
return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode);
}
static inline struct inode *vn_to_inode(struct vnode *vnode)
static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
{
return &vnode->v_inode;
}
/*
* Vnode flags.
* Values for the vop_rwlock/rwunlock flags parameter.
*/
#define VMODIFIED 0x8 /* XFS inode state possibly differs */
/* to the Linux inode state. */
/*
* Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
*/
typedef enum vrwlock {
typedef enum bhv_vrwlock {
VRWLOCK_NONE,
VRWLOCK_READ,
VRWLOCK_WRITE,
VRWLOCK_WRITE_DIRECT,
VRWLOCK_TRY_READ,
VRWLOCK_TRY_WRITE
} vrwlock_t;
} bhv_vrwlock_t;
/*
* Return values for VOP_INACTIVE. A return value of
* Return values for bhv_vop_inactive. A return value of
* VN_INACTIVE_NOCACHE implies that the file system behavior
* has disassociated its state and bhv_desc_t from the vnode.
*/
@ -152,18 +121,20 @@ typedef enum vrwlock {
#define VN_INACTIVE_NOCACHE 1
/*
* Values for the cmd code given to VOP_VNODE_CHANGE.
* Values for the cmd code given to vop_vnode_change.
*/
typedef enum vchange {
typedef enum bhv_vchange {
VCHANGE_FLAGS_FRLOCKS = 0,
VCHANGE_FLAGS_ENF_LOCKING = 1,
VCHANGE_FLAGS_TRUNCATED = 2,
VCHANGE_FLAGS_PAGE_DIRTY = 3,
VCHANGE_FLAGS_IOEXCL_COUNT = 4
} vchange_t;
} bhv_vchange_t;
typedef enum { L_FALSE, L_TRUE } lastclose_t;
typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *);
typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
const struct iovec *, unsigned int,
loff_t *, int, struct cred *);
@ -181,27 +152,27 @@ typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
struct cred *);
typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
int, unsigned int, void __user *);
typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
struct cred *);
typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int,
typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
struct cred *);
typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *);
typedef int (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **,
int, vnode_t *, struct cred *);
typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *,
vnode_t **, struct cred *);
typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *);
typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *,
typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
int, bhv_vnode_t *, struct cred *);
typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
bhv_vnode_t **, struct cred *);
typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
struct cred *);
typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *,
struct cred *);
typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *,
vnode_t **, struct cred *);
typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *);
typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
bhv_vname_t *, struct cred *);
typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
bhv_vnode_t **, struct cred *);
typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
int *);
typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *,
char *, vnode_t **, struct cred *);
typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
char *, bhv_vnode_t **, struct cred *);
typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
struct cred *);
typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
@ -209,8 +180,8 @@ typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
typedef int (*vop_release_t)(bhv_desc_t *);
typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t);
typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t);
typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
struct xfs_iomap *, int *);
typedef int (*vop_reclaim_t)(bhv_desc_t *);
@ -222,8 +193,8 @@ typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
int, struct cred *);
typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
struct attrlist_cursor_kern *, struct cred *);
typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int);
typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t);
typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
@ -231,9 +202,10 @@ typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
typedef int (*vop_iflush_t)(bhv_desc_t *, int);
typedef struct vnodeops {
typedef struct bhv_vnodeops {
bhv_position_t vn_position; /* position within behavior chain */
vop_open_t vop_open;
vop_close_t vop_close;
vop_read_t vop_read;
vop_write_t vop_write;
vop_sendfile_t vop_sendfile;
@ -271,103 +243,80 @@ typedef struct vnodeops {
vop_pflushvp_t vop_flush_pages;
vop_release_t vop_release;
vop_iflush_t vop_iflush;
} vnodeops_t;
} bhv_vnodeops_t;
/*
* VOP's.
* Virtual node operations, operating from head bhv.
*/
#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \
rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
#define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
#define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
#define VOP_OPEN(vp, cr, rv) \
rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
#define VOP_GETATTR(vp, vap, f, cr, rv) \
rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
#define VOP_SETATTR(vp, vap, f, cr, rv) \
rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
#define VOP_ACCESS(vp, mode, cr, rv) \
rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr)
#define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \
rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
#define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \
rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
#define VOP_REMOVE(dvp,d,cr,rv) \
rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
#define VOP_LINK(tdvp,fvp,d,cr,rv) \
rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
#define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \
rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
#define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \
rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
#define VOP_RMDIR(dp,d,cr,rv) \
rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
#define VOP_READDIR(vp,uiop,cr,eofp,rv) \
rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
#define VOP_READLINK(vp,uiop,fl,cr,rv) \
rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
#define VOP_FSYNC(vp,f,cr,b,e,rv) \
rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
#define VOP_INACTIVE(vp, cr, rv) \
rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
#define VOP_RELEASE(vp, rv) \
rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
#define VOP_FID2(vp, fidp, rv) \
rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
#define VOP_RWLOCK(vp,i) \
(void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
#define VOP_RWLOCK_TRY(vp,i) \
_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
#define VOP_RWUNLOCK(vp,i) \
(void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
#define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \
rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
#define VOP_RECLAIM(vp, rv) \
rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \
rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
#define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \
rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
#define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \
rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
#define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \
rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
#define VOP_LINK_REMOVED(vp, dvp, linkzero) \
(void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
#define VOP_VNODE_CHANGE(vp, cmd, val) \
(void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
/*
* These are page cache functions that now go thru VOPs.
* 'last' parameter is unused and left in for IRIX compatibility
*/
#define VOP_TOSS_PAGES(vp, first, last, fiopt) \
_VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt)
/*
* 'last' parameter is unused and left in for IRIX compatibility
*/
#define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \
_VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt)
/*
* 'last' parameter is unused and left in for IRIX compatibility
*/
#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \
rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt)
#define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \
rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg)
#define VOP_IFLUSH(vp, flags, rv) \
rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags)
#define VNHEAD(vp) ((vp)->v_bh.bh_first)
#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
#define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
#define bhv_vop_bmap(vp,of,sz,rw,b,n) \
VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
#define bhv_vop_getattr(vp, vap,f,cr) \
VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
#define bhv_vop_setattr(vp, vap,f,cr) \
VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
#define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
#define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
#define bhv_vop_create(dvp,d,vap,vpp,cr) \
VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
#define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
#define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
#define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
#define bhv_vop_readdir(vp,uiop,cr,eofp) \
VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
#define bhv_vop_readlink(vp,uiop,fl,cr) \
VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
#define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
#define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
#define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
#define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
#define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
#define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
#define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
#define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
#define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
#define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
#define bhv_vop_attr_remove(vp, name, flags, cred) \
VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
#define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
#define bhv_vop_link_removed(vp, dvp, linkzero) \
VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
#define bhv_vop_vnode_change(vp, cmd, val) \
VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
#define bhv_vop_toss_pages(vp, first, last, fiopt) \
VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
#define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
#define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
#define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
/*
* Flags for read/write calls - same values as IRIX
@ -377,7 +326,7 @@ typedef struct vnodeops {
#define IO_INVIS 0x00020 /* don't update inode timestamps */
/*
* Flags for VOP_IFLUSH call
* Flags for vop_iflush call
*/
#define FLUSH_SYNC 1 /* wait for flush to complete */
#define FLUSH_INODE 2 /* flush the inode itself */
@ -385,8 +334,7 @@ typedef struct vnodeops {
* this inode out to disk */
/*
* Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and
* VOP_FLUSH_PAGES.
* Flush/Invalidate options for vop_toss/flush/flushinval_pages.
*/
#define FI_NONE 0 /* none */
#define FI_REMAPF 1 /* Do a remapf prior to the operation */
@ -398,7 +346,7 @@ typedef struct vnodeops {
* Vnode attributes. va_mask indicates those attributes the caller
* wants to set or extract.
*/
typedef struct vattr {
typedef struct bhv_vattr {
int va_mask; /* bit-mask of attributes present */
mode_t va_mode; /* file access mode and type */
xfs_nlink_t va_nlink; /* number of references to file */
@ -418,7 +366,7 @@ typedef struct vattr {
u_long va_nextents; /* number of extents in file */
u_long va_anextents; /* number of attr extents in file */
prid_t va_projid; /* project id */
} vattr_t;
} bhv_vattr_t;
/*
* setattr or getattr attributes
@ -492,29 +440,17 @@ typedef struct vattr {
(VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
extern void vn_init(void);
extern vnode_t *vn_initialize(struct inode *);
extern bhv_vnode_t *vn_initialize(struct inode *);
extern int vn_revalidate(struct bhv_vnode *);
extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *);
extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *);
/*
* vnode_map structures _must_ match vn_epoch and vnode structure sizes.
*/
typedef struct vnode_map {
vfs_t *v_vfsp;
vnumber_t v_number; /* in-core vnode number */
xfs_ino_t v_ino; /* inode # */
} vmap_t;
extern void vn_iowait(struct bhv_vnode *vp);
extern void vn_iowake(struct bhv_vnode *vp);
#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \
(vmap).v_number = (vp)->v_number, \
(vmap).v_ino = (vp)->v_inode.i_ino; }
extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
extern int vn_revalidate(struct vnode *);
extern int __vn_revalidate(struct vnode *, vattr_t *);
extern void vn_revalidate_core(struct vnode *, vattr_t *);
extern void vn_iowait(struct vnode *vp);
extern void vn_iowake(struct vnode *vp);
static inline int vn_count(struct vnode *vp)
static inline int vn_count(struct bhv_vnode *vp)
{
return atomic_read(&vn_to_inode(vp)->i_count);
}
@ -522,7 +458,7 @@ static inline int vn_count(struct vnode *vp)
/*
* Vnode reference counting functions (and macros for compatibility).
*/
extern vnode_t *vn_hold(struct vnode *);
extern bhv_vnode_t *vn_hold(struct bhv_vnode *);
#if defined(XFS_VNODE_TRACE)
#define VN_HOLD(vp) \
@ -536,7 +472,7 @@ extern vnode_t *vn_hold(struct vnode *);
#define VN_RELE(vp) (iput(vn_to_inode(vp)))
#endif
static inline struct vnode *vn_grab(struct vnode *vp)
static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
{
struct inode *inode = igrab(vn_to_inode(vp));
return inode ? vn_from_inode(inode) : NULL;
@ -554,32 +490,39 @@ static inline struct vnode *vn_grab(struct vnode *vp)
*/
#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s)
#define VN_FLAGSET(vp,b) vn_flagset(vp,b)
#define VN_FLAGCLR(vp,b) vn_flagclr(vp,b)
static __inline__ void vn_flagset(struct vnode *vp, uint flag)
static __inline__ void vn_flagset(struct bhv_vnode *vp, uint flag)
{
spin_lock(&vp->v_lock);
vp->v_flag |= flag;
spin_unlock(&vp->v_lock);
}
static __inline__ void vn_flagclr(struct vnode *vp, uint flag)
static __inline__ uint vn_flagclr(struct bhv_vnode *vp, uint flag)
{
uint cleared;
spin_lock(&vp->v_lock);
cleared = (vp->v_flag & flag);
vp->v_flag &= ~flag;
spin_unlock(&vp->v_lock);
return cleared;
}
#define VMODIFY(vp) vn_flagset(vp, VMODIFIED)
#define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED)
#define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED)
#define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED)
/*
* Dealing with bad inodes
*/
static inline void vn_mark_bad(struct vnode *vp)
static inline void vn_mark_bad(struct bhv_vnode *vp)
{
make_bad_inode(vn_to_inode(vp));
}
static inline int VN_BAD(struct vnode *vp)
static inline int VN_BAD(struct bhv_vnode *vp)
{
return is_bad_inode(vn_to_inode(vp));
}
@ -587,18 +530,18 @@ static inline int VN_BAD(struct vnode *vp)
/*
* Extracting atime values in various formats
*/
static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime)
static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
{
bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
}
static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts)
static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
{
*ts = vp->v_inode.i_atime;
}
static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
{
*tt = vp->v_inode.i_atime.tv_sec;
}
@ -610,11 +553,10 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
PAGECACHE_TAG_DIRTY)
#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED)
#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
#define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
/*
* Flags to VOP_SETATTR/VOP_GETATTR.
* Flags to vop_setattr/getattr.
*/
#define ATTR_UTIME 0x01 /* non-default utime(2) request */
#define ATTR_DMI 0x08 /* invocation from a DMI function */
@ -624,7 +566,7 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
/*
* Flags to VOP_FSYNC and VOP_RECLAIM.
* Flags to vop_fsync/reclaim.
*/
#define FSYNC_NOWAIT 0 /* asynchronous flush */
#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */
@ -643,11 +585,11 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
#define VNODE_KTRACE_REF 4
#define VNODE_KTRACE_RELE 5
extern void vn_trace_entry(struct vnode *, const char *, inst_t *);
extern void vn_trace_exit(struct vnode *, const char *, inst_t *);
extern void vn_trace_hold(struct vnode *, char *, int, inst_t *);
extern void vn_trace_ref(struct vnode *, char *, int, inst_t *);
extern void vn_trace_rele(struct vnode *, char *, int, inst_t *);
extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
#define VN_TRACE(vp) \
vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -444,7 +442,7 @@ xfs_qm_dqalloc(
XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
&firstblock,
XFS_QM_DQALLOC_SPACE_RES(mp),
&map, &nmaps, &flist))) {
&map, &nmaps, &flist, NULL))) {
goto error0;
}
ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@ -559,7 +557,7 @@ xfs_qm_dqtobp(
error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
XFS_DQUOT_CLUSTER_SIZE_FSB,
XFS_BMAPI_METADATA,
NULL, 0, &map, &nmaps, NULL);
NULL, 0, &map, &nmaps, NULL, NULL);
xfs_iunlock(quotip, XFS_ILOCK_SHARED);
if (error)
@ -1261,7 +1259,7 @@ xfs_qm_dqflush(
if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id),
0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
xfs_force_shutdown(dqp->q_mount, SHUTDOWN_CORRUPT_INCORE);
return XFS_ERROR(EIO);
}

Просмотреть файл

@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
*/
#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\
(dqp)->dq_flags |= XFS_DQ_FLOCKED; }
#define xfs_dqfunlock(dqp) { ASSERT(valusema(&((dqp)->q_flock)) <= 0); \
#define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \
vsema(&((dqp)->q_flock)); \
(dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); }
@ -128,7 +128,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \
&(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s)
#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (valusema(&((dqp)->q_flock)) <= 0)
#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock)))
#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -248,7 +246,7 @@ xfs_qm_dquot_logitem_pushbuf(
* inode flush completed and the inode was taken off the AIL.
* So, just get out.
*/
if ((valusema(&(dqp->q_flock)) > 0) ||
if (!issemalocked(&(dqp->q_flock)) ||
((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
qip->qli_pushbuf_flag = 0;
xfs_dqunlock(dqp);
@ -261,7 +259,7 @@ xfs_qm_dquot_logitem_pushbuf(
if (bp != NULL) {
if (XFS_BUF_ISDELAYWRITE(bp)) {
dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
(valusema(&(dqp->q_flock)) <= 0));
issemalocked(&(dqp->q_flock)));
qip->qli_pushbuf_flag = 0;
xfs_dqunlock(dqp);

Просмотреть файл

@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -33,7 +32,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -1603,7 +1601,7 @@ xfs_qm_dqiterate(
maxlblkcnt - lblkno,
XFS_BMAPI_METADATA,
NULL,
0, map, &nmaps, NULL);
0, map, &nmaps, NULL, NULL);
xfs_iunlock(qip, XFS_ILOCK_SHARED);
if (error)
break;
@ -1905,9 +1903,7 @@ xfs_qm_quotacheck(
*/
if ((error = xfs_bulkstat(mp, &lastino, &count,
xfs_qm_dqusage_adjust, NULL,
structsz, NULL,
BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
&done)))
structsz, NULL, BULKSTAT_FG_IGET, &done)))
break;
} while (! done);

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -33,7 +32,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -129,7 +127,7 @@ xfs_qm_parseargs(
return XFS_ERROR(EINVAL);
}
PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
if (!error && !referenced)
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
return error;
@ -140,9 +138,8 @@ xfs_qm_showargs(
struct bhv_desc *bhv,
struct seq_file *m)
{
struct vfs *vfsp = bhvtovfs(bhv);
struct bhv_vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
if (mp->m_qflags & XFS_UQUOTA_ACCT) {
(mp->m_qflags & XFS_UQUOTA_ENFD) ?
@ -165,8 +162,7 @@ xfs_qm_showargs(
if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
seq_puts(m, "," MNTOPT_NOQUOTA);
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
return error;
return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
}
STATIC int
@ -175,14 +171,67 @@ xfs_qm_mount(
struct xfs_mount_args *args,
struct cred *cr)
{
struct vfs *vfsp = bhvtovfs(bhv);
struct bhv_vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
xfs_qm_mount_quotainit(mp, args->flags);
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
return error;
return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
}
/*
* Directory tree accounting is implemented using project quotas, where
* the project identifier is inherited from parent directories.
* A statvfs (df, etc.) of a directory that is using project quota should
* return a statvfs of the project, not the entire filesystem.
* This makes such trees appear as if they are filesystems in themselves.
*/
STATIC int
xfs_qm_statvfs(
struct bhv_desc *bhv,
bhv_statvfs_t *statp,
struct bhv_vnode *vnode)
{
xfs_mount_t *mp;
xfs_inode_t *ip;
xfs_dquot_t *dqp;
xfs_disk_dquot_t *dp;
__uint64_t limit;
int error;
error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
if (error || !vnode)
return error;
mp = XFS_BHVTOM(bhv);
ip = xfs_vtoi(vnode);
if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
return 0;
if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
return 0;
if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
return 0;
if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
return 0;
dp = &dqp->q_core;
limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit;
if (limit && statp->f_blocks > limit) {
statp->f_blocks = limit;
statp->f_bfree = (statp->f_blocks > dp->d_bcount) ?
(statp->f_blocks - dp->d_bcount) : 0;
}
limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit;
if (limit && statp->f_files > limit) {
statp->f_files = limit;
statp->f_ffree = (statp->f_files > dp->d_icount) ?
(statp->f_ffree - dp->d_icount) : 0;
}
xfs_qm_dqput(dqp);
return 0;
}
STATIC int
@ -191,7 +240,7 @@ xfs_qm_syncall(
int flags,
cred_t *credp)
{
struct vfs *vfsp = bhvtovfs(bhv);
struct bhv_vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
@ -210,8 +259,7 @@ xfs_qm_syncall(
}
}
}
PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error);
return error;
return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
}
STATIC int
@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = {
.xfs_dqtrxops = &xfs_trans_dquot_ops,
};
struct bhv_vfsops xfs_qmops = { {
struct bhv_module_vfsops xfs_qmops = { {
BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
.vfs_parseargs = xfs_qm_parseargs,
.vfs_showargs = xfs_qm_showargs,
.vfs_mount = xfs_qm_mount,
.vfs_statvfs = xfs_qm_statvfs,
.vfs_sync = xfs_qm_syncall,
.vfs_quotactl = xfs_qm_quotactl, },
};

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"

Просмотреть файл

@ -26,7 +26,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -35,7 +34,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -91,8 +89,8 @@ xfs_qm_quotactl(
xfs_caddr_t addr)
{
xfs_mount_t *mp;
bhv_vfs_t *vfsp;
int error;
struct vfs *vfsp;
vfsp = bhvtovfs(bdp);
mp = XFS_VFSTOM(vfsp);
@ -1035,7 +1033,7 @@ xfs_qm_dqrele_all_inodes(
{
xfs_inode_t *ip, *topino;
uint ireclaims;
vnode_t *vp;
bhv_vnode_t *vp;
boolean_t vnode_refd;
ASSERT(mp->m_quotainfo);

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -33,7 +32,6 @@
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"

Просмотреть файл

@ -47,7 +47,7 @@ cmn_err(register int level, char *fmt, ...)
va_start(ap, fmt);
if (*fmt == '!') fp++;
len = vsprintf(message, fp, ap);
if (message[len-1] != '\n')
if (level != CE_DEBUG && message[len-1] != '\n')
strcat(message, "\n");
printk("%s%s", err_level[level], message);
va_end(ap);
@ -68,7 +68,7 @@ icmn_err(register int level, char *fmt, va_list ap)
level = XFS_MAX_ERR_LEVEL;
spin_lock_irqsave(&xfs_err_lock,flags);
len = vsprintf(message, fmt, ap);
if (message[len-1] != '\n')
if (level != CE_DEBUG && message[len-1] != '\n')
strcat(message, "\n");
spin_unlock_irqrestore(&xfs_err_lock,flags);
printk("%s%s", err_level[level], message);

Просмотреть файл

@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...)
__attribute__ ((format (printf, 2, 3)));
extern void assfail(char *expr, char *f, int l);
#define prdev(fmt,targ,args...) \
printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
#define ASSERT_ALWAYS(expr) \
(unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))

Просмотреть файл

@ -21,12 +21,10 @@
#include "xfs_bit.h"
#include "xfs_inum.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -39,15 +37,15 @@
#include <linux/capability.h>
#include <linux/posix_acl_xattr.h>
STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *);
STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *);
STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *);
STATIC void xfs_acl_get_endian(xfs_acl_t *);
STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
STATIC int xfs_acl_invalid(xfs_acl_t *);
STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *);
STATIC void xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *);
STATIC void xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *);
STATIC int xfs_acl_allow_set(vnode_t *, int);
STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *);
STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *);
STATIC int xfs_acl_allow_set(bhv_vnode_t *, int);
kmem_zone_t *xfs_acl_zone;
@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone;
*/
int
xfs_acl_vhasacl_access(
vnode_t *vp)
bhv_vnode_t *vp)
{
int error;
@ -70,7 +68,7 @@ xfs_acl_vhasacl_access(
*/
int
xfs_acl_vhasacl_default(
vnode_t *vp)
bhv_vnode_t *vp)
{
int error;
@ -209,7 +207,7 @@ posix_acl_xfs_to_xattr(
int
xfs_acl_vget(
vnode_t *vp,
bhv_vnode_t *vp,
void *acl,
size_t size,
int kind)
@ -241,10 +239,10 @@ xfs_acl_vget(
goto out;
}
if (kind == _ACL_TYPE_ACCESS) {
vattr_t va;
bhv_vattr_t va;
va.va_mask = XFS_AT_MODE;
VOP_GETATTR(vp, &va, 0, sys_cred, error);
error = bhv_vop_getattr(vp, &va, 0, sys_cred);
if (error)
goto out;
xfs_acl_sync_mode(va.va_mode, xfs_acl);
@ -260,7 +258,7 @@ out:
int
xfs_acl_vremove(
vnode_t *vp,
bhv_vnode_t *vp,
int kind)
{
int error;
@ -268,9 +266,9 @@ xfs_acl_vremove(
VN_HOLD(vp);
error = xfs_acl_allow_set(vp, kind);
if (!error) {
VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT?
SGI_ACL_DEFAULT: SGI_ACL_FILE,
ATTR_ROOT, sys_cred, error);
error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT?
SGI_ACL_DEFAULT: SGI_ACL_FILE,
ATTR_ROOT, sys_cred);
if (error == ENOATTR)
error = 0; /* 'scool */
}
@ -280,7 +278,7 @@ xfs_acl_vremove(
int
xfs_acl_vset(
vnode_t *vp,
bhv_vnode_t *vp,
void *acl,
size_t size,
int kind)
@ -370,10 +368,10 @@ xfs_acl_iaccess(
STATIC int
xfs_acl_allow_set(
vnode_t *vp,
bhv_vnode_t *vp,
int kind)
{
vattr_t va;
bhv_vattr_t va;
int error;
if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
@ -383,7 +381,7 @@ xfs_acl_allow_set(
if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
return EROFS;
va.va_mask = XFS_AT_UID;
VOP_GETATTR(vp, &va, 0, NULL, error);
error = bhv_vop_getattr(vp, &va, 0, NULL);
if (error)
return error;
if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
@ -606,7 +604,7 @@ xfs_acl_get_endian(
*/
STATIC void
xfs_acl_get_attr(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_acl_t *aclp,
int kind,
int flags,
@ -616,9 +614,9 @@ xfs_acl_get_attr(
ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
flags |= ATTR_ROOT;
VOP_ATTR_GET(vp,
kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT,
(char *)aclp, &len, flags, sys_cred, *error);
*error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ?
SGI_ACL_FILE : SGI_ACL_DEFAULT,
(char *)aclp, &len, flags, sys_cred);
if (*error || (flags & ATTR_KERNOVAL))
return;
xfs_acl_get_endian(aclp);
@ -629,7 +627,7 @@ xfs_acl_get_attr(
*/
STATIC void
xfs_acl_set_attr(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_acl_t *aclp,
int kind,
int *error)
@ -654,19 +652,19 @@ xfs_acl_set_attr(
INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
}
INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
VOP_ATTR_SET(vp,
kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT,
(char *)newacl, len, ATTR_ROOT, sys_cred, *error);
*error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ?
SGI_ACL_FILE: SGI_ACL_DEFAULT,
(char *)newacl, len, ATTR_ROOT, sys_cred);
_ACL_FREE(newacl);
}
int
xfs_acl_vtoacl(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_acl_t *access_acl,
xfs_acl_t *default_acl)
{
vattr_t va;
bhv_vattr_t va;
int error = 0;
if (access_acl) {
@ -678,7 +676,7 @@ xfs_acl_vtoacl(
if (!error) {
/* Got the ACL, need the mode... */
va.va_mask = XFS_AT_MODE;
VOP_GETATTR(vp, &va, 0, sys_cred, error);
error = bhv_vop_getattr(vp, &va, 0, sys_cred);
}
if (error)
@ -701,8 +699,8 @@ xfs_acl_vtoacl(
*/
int
xfs_acl_inherit(
vnode_t *vp,
vattr_t *vap,
bhv_vnode_t *vp,
bhv_vattr_t *vap,
xfs_acl_t *pdaclp)
{
xfs_acl_t *cacl;
@ -757,11 +755,11 @@ xfs_acl_inherit(
*/
STATIC int
xfs_acl_setmode(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_acl_t *acl,
int *basicperms)
{
vattr_t va;
bhv_vattr_t va;
xfs_acl_entry_t *ap;
xfs_acl_entry_t *gap = NULL;
int i, error, nomask = 1;
@ -776,7 +774,7 @@ xfs_acl_setmode(
* mode. The m:: bits take precedence over the g:: bits.
*/
va.va_mask = XFS_AT_MODE;
VOP_GETATTR(vp, &va, 0, sys_cred, error);
error = bhv_vop_getattr(vp, &va, 0, sys_cred);
if (error)
return error;
@ -810,8 +808,7 @@ xfs_acl_setmode(
if (gap && nomask)
va.va_mode |= gap->ae_perm << 3;
VOP_SETATTR(vp, &va, 0, sys_cred, error);
return error;
return bhv_vop_setattr(vp, &va, 0, sys_cred);
}
/*

Просмотреть файл

@ -50,7 +50,7 @@ typedef struct xfs_acl {
#ifdef CONFIG_XFS_POSIX_ACL
struct vattr;
struct vnode;
struct bhv_vnode;
struct xfs_inode;
extern struct kmem_zone *xfs_acl_zone;
@ -58,14 +58,14 @@ extern struct kmem_zone *xfs_acl_zone;
(zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *);
extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *);
extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *);
extern int xfs_acl_vhasacl_access(struct vnode *);
extern int xfs_acl_vhasacl_default(struct vnode *);
extern int xfs_acl_vset(struct vnode *, void *, size_t, int);
extern int xfs_acl_vget(struct vnode *, void *, size_t, int);
extern int xfs_acl_vremove(struct vnode *vp, int);
extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
extern int xfs_acl_vremove(struct bhv_vnode *, int);
#define _ACL_TYPE_ACCESS 1
#define _ACL_TYPE_DEFAULT 2

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist(
(pag->pagf_longest - delta) :
(pag->pagf_flcount > 0 || pag->pagf_longest > 0);
if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
(args->minleft &&
(!(flags & XFS_ALLOC_FLAG_FREEING) &&
(int)(pag->pagf_freeblks + pag->pagf_flcount -
need - args->total) <
(int)args->minleft)) {
@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist(
longest = (longest > delta) ? (longest - delta) :
(be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
(args->minleft &&
(!(flags & XFS_ALLOC_FLAG_FREEING) &&
(int)(be32_to_cpu(agf->agf_freeblks) +
be32_to_cpu(agf->agf_flcount) - need - args->total) <
(int)args->minleft)) {
@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist(
* the restrictions correctly. Can happen for free calls
* on a completely full ag.
*/
if (targs.agbno == NULLAGBLOCK)
if (targs.agbno == NULLAGBLOCK) {
if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
xfs_trans_brelse(tp, agflbp);
args->agbp = NULL;
return 0;
}
break;
}
/*
* Put each allocated block on the list.
*/
@ -2360,8 +2364,19 @@ xfs_alloc_vextent(
if (args->agno == sagno &&
type == XFS_ALLOCTYPE_START_BNO)
args->type = XFS_ALLOCTYPE_THIS_AG;
if (++(args->agno) == mp->m_sb.sb_agcount)
args->agno = 0;
/*
* For the first allocation, we can try any AG to get
* space. However, if we already have allocated a
* block, we don't want to try AGs whose number is below
* sagno. Otherwise, we may end up with out-of-order
* locking of AGF, which might cause deadlock.
*/
if (++(args->agno) == mp->m_sb.sb_agcount) {
if (args->firstblock != NULLFSBLOCK)
args->agno = sagno;
else
args->agno = 0;
}
/*
* Reached the starting a.g., must either be done
* or switch to non-trylock mode.
@ -2443,7 +2458,7 @@ xfs_free_extent(
args.minlen = args.minleft = args.minalignslop = 0;
down_read(&args.mp->m_peraglock);
args.pag = &args.mp->m_perag[args.agno];
if ((error = xfs_alloc_fix_freelist(&args, 0)))
if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
goto error0;
#ifdef DEBUG
ASSERT(args.agbp != NULL);

Просмотреть файл

@ -41,6 +41,7 @@ typedef enum xfs_alloctype
* Flags for xfs_alloc_fix_freelist.
*/
#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */
#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
/*
* Argument structure for xfs_alloc routines.
@ -70,6 +71,7 @@ typedef struct xfs_alloc_arg {
char wasfromfl; /* set if allocation is from freelist */
char isfl; /* set if is freelist blocks - !acctg */
char userdata; /* set if this is user data */
xfs_fsblock_t firstblock; /* io first block allocated */
} xfs_alloc_arg_t;
/*

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"

Просмотреть файл

@ -27,7 +27,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@ -35,7 +34,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -1910,7 +1908,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
args->rmtblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
NULL, 0, map, &nmap, NULL);
NULL, 0, map, &nmap, NULL, NULL);
if (error)
return(error);
ASSERT(nmap >= 1);
@ -1988,7 +1986,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
XFS_BMAPI_WRITE,
args->firstblock, args->total, &map, &nmap,
args->flist);
args->flist, NULL);
if (!error) {
error = xfs_bmap_finish(&args->trans, args->flist,
*args->firstblock, &committed);
@ -2039,7 +2037,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
args->rmtblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
args->firstblock, 0, &map, &nmap, NULL);
args->firstblock, 0, &map, &nmap,
NULL, NULL);
if (error) {
return(error);
}
@ -2104,7 +2103,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
args->rmtblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
args->firstblock, 0, &map, &nmap,
args->flist);
args->flist, NULL);
if (error) {
return(error);
}
@ -2142,7 +2141,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
XFS_BMAP_INIT(args->flist, args->firstblock);
error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
1, args->firstblock, args->flist, &done);
1, args->firstblock, args->flist,
NULL, &done);
if (!error) {
error = xfs_bmap_finish(&args->trans, args->flist,
*args->firstblock, &committed);
@ -2322,56 +2322,56 @@ xfs_attr_trace_enter(int type, char *where,
STATIC int
posix_acl_access_set(
vnode_t *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
}
STATIC int
posix_acl_access_remove(
struct vnode *vp, char *name, int xflags)
bhv_vnode_t *vp, char *name, int xflags)
{
return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
}
STATIC int
posix_acl_access_get(
vnode_t *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
}
STATIC int
posix_acl_access_exists(
vnode_t *vp)
bhv_vnode_t *vp)
{
return xfs_acl_vhasacl_access(vp);
}
STATIC int
posix_acl_default_set(
vnode_t *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
}
STATIC int
posix_acl_default_get(
vnode_t *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
}
STATIC int
posix_acl_default_remove(
struct vnode *vp, char *name, int xflags)
bhv_vnode_t *vp, char *name, int xflags)
{
return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
}
STATIC int
posix_acl_default_exists(
vnode_t *vp)
bhv_vnode_t *vp)
{
return xfs_acl_vhasacl_default(vp);
}
@ -2404,21 +2404,18 @@ STATIC struct attrnames *attr_system_names[] =
STATIC int
attr_generic_set(
struct vnode *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
int error;
VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
return -error;
return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL);
}
STATIC int
attr_generic_get(
struct vnode *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
int error, asize = size;
VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error);
error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL);
if (!error)
return asize;
return -error;
@ -2426,12 +2423,9 @@ attr_generic_get(
STATIC int
attr_generic_remove(
struct vnode *vp, char *name, int xflags)
bhv_vnode_t *vp, char *name, int xflags)
{
int error;
VOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
return -error;
return -bhv_vop_attr_remove(vp, name, xflags, NULL);
}
STATIC int
@ -2459,7 +2453,7 @@ attr_generic_listadd(
STATIC int
attr_system_list(
struct vnode *vp,
bhv_vnode_t *vp,
void *data,
size_t size,
ssize_t *result)
@ -2481,12 +2475,12 @@ attr_system_list(
int
attr_generic_list(
struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result)
bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
{
attrlist_cursor_kern_t cursor = { 0 };
int error;
VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error);
error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL);
if (error > 0)
return -error;
*result = -error;
@ -2514,7 +2508,7 @@ attr_lookup_namespace(
*/
STATIC int
attr_user_capable(
struct vnode *vp,
bhv_vnode_t *vp,
cred_t *cred)
{
struct inode *inode = vn_to_inode(vp);
@ -2532,7 +2526,7 @@ attr_user_capable(
STATIC int
attr_trusted_capable(
struct vnode *vp,
bhv_vnode_t *vp,
cred_t *cred)
{
struct inode *inode = vn_to_inode(vp);
@ -2546,7 +2540,7 @@ attr_trusted_capable(
STATIC int
attr_secure_capable(
struct vnode *vp,
bhv_vnode_t *vp,
cred_t *cred)
{
return -ENOSECURITY;
@ -2554,7 +2548,7 @@ attr_secure_capable(
STATIC int
attr_system_set(
struct vnode *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
attrnames_t *namesp;
int error;
@ -2573,7 +2567,7 @@ attr_system_set(
STATIC int
attr_system_get(
struct vnode *vp, char *name, void *data, size_t size, int xflags)
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
{
attrnames_t *namesp;
@ -2585,7 +2579,7 @@ attr_system_get(
STATIC int
attr_system_remove(
struct vnode *vp, char *name, int xflags)
bhv_vnode_t *vp, char *name, int xflags)
{
attrnames_t *namesp;

Просмотреть файл

@ -36,13 +36,13 @@
*========================================================================*/
struct cred;
struct vnode;
struct bhv_vnode;
typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int);
typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int);
typedef int (*attrremove_t)(struct vnode *, char *, int);
typedef int (*attrexists_t)(struct vnode *);
typedef int (*attrcapable_t)(struct vnode *, struct cred *);
typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
typedef int (*attrremove_t)(struct bhv_vnode *, char *, int);
typedef int (*attrexists_t)(struct bhv_vnode *);
typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *);
typedef struct attrnames {
char * attr_name;
@ -63,7 +63,7 @@ extern struct attrnames attr_trusted;
extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *);
#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */

Просмотреть файл

@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@ -34,7 +33,6 @@
#include "xfs_ialloc_btree.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -2990,7 +2988,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
nmap = 1;
error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
NULL, 0, &map, &nmap, NULL);
NULL, 0, &map, &nmap, NULL, NULL);
if (error) {
return(error);
}

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -24,13 +24,11 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -40,13 +38,15 @@
#include "xfs_mount.h"
#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
#include "xfs_inode_item.h"
#include "xfs_extfree_item.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_dir_leaf.h"
#include "xfs_attr_leaf.h"
#include "xfs_rw.h"
#include "xfs_quota.h"
@ -101,6 +101,7 @@ xfs_bmap_add_extent(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd); /* OK to allocate reserved blocks */
@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd); /* OK to allocate reserved blocks */
/*
@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp,/* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd); /* OK to allocate reserved blocks */
/*
@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork); /* data or attr fork */
/*
@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp); /* inode logging flags */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta); /* Change made to incore extents */
/*
* xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
@ -203,6 +208,7 @@ xfs_bmap_del_extent(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp,/* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd); /* OK to allocate reserved blocks */
@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local(
dargs.total = mp->m_dirblkfsbs;
dargs.whichfork = XFS_DATA_FORK;
dargs.trans = tp;
error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs);
error = xfs_dir2_sf_to_block(&dargs);
} else
error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
XFS_DATA_FORK);
@ -530,6 +536,7 @@ xfs_bmap_add_extent(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd) /* OK to use reserved data blocks */
{
@ -567,6 +574,15 @@ xfs_bmap_add_extent(
logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
} else
logflags = 0;
/* DELTA: single new extent */
if (delta) {
if (delta->xed_startoff > new->br_startoff)
delta->xed_startoff = new->br_startoff;
if (delta->xed_blockcount <
new->br_startoff + new->br_blockcount)
delta->xed_blockcount = new->br_startoff +
new->br_blockcount;
}
}
/*
* Any kind of new delayed allocation goes here.
@ -576,7 +592,7 @@ xfs_bmap_add_extent(
ASSERT((cur->bc_private.b.flags &
XFS_BTCUR_BPRV_WASDEL) == 0);
if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
&logflags, rsvd)))
&logflags, delta, rsvd)))
goto done;
}
/*
@ -587,7 +603,7 @@ xfs_bmap_add_extent(
ASSERT((cur->bc_private.b.flags &
XFS_BTCUR_BPRV_WASDEL) == 0);
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
&logflags, whichfork)))
&logflags, delta, whichfork)))
goto done;
} else {
xfs_bmbt_irec_t prev; /* old extent at offset idx */
@ -612,17 +628,17 @@ xfs_bmap_add_extent(
XFS_BTCUR_BPRV_WASDEL);
if ((error = xfs_bmap_add_extent_delay_real(ip,
idx, &cur, new, &da_new, first, flist,
&logflags, rsvd)))
&logflags, delta, rsvd)))
goto done;
} else if (new->br_state == XFS_EXT_NORM) {
ASSERT(new->br_state == XFS_EXT_NORM);
if ((error = xfs_bmap_add_extent_unwritten_real(
ip, idx, &cur, new, &logflags)))
ip, idx, &cur, new, &logflags, delta)))
goto done;
} else {
ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
if ((error = xfs_bmap_add_extent_unwritten_real(
ip, idx, &cur, new, &logflags)))
ip, idx, &cur, new, &logflags, delta)))
goto done;
}
ASSERT(*curp == cur || *curp == NULL);
@ -635,7 +651,7 @@ xfs_bmap_add_extent(
ASSERT((cur->bc_private.b.flags &
XFS_BTCUR_BPRV_WASDEL) == 0);
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
new, &logflags, whichfork)))
new, &logflags, delta, whichfork)))
goto done;
}
}
@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd) /* OK to use reserved data block allocation */
{
xfs_btree_cur_t *cur; /* btree cursor */
@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(
/* left is 0, right is 1, prev is 2 */
int rval=0; /* return value (logging flags) */
int state = 0;/* state bits, accessed thru macros */
xfs_filblks_t temp; /* value for dnew calculations */
xfs_filblks_t temp2; /* value for dnew calculations */
xfs_filblks_t temp=0; /* value for dnew calculations */
xfs_filblks_t temp2=0;/* value for dnew calculations */
int tmp_rval; /* partial logging flags */
enum { /* bit number definitions for state */
LEFT_CONTIG, RIGHT_CONTIG,
@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
goto done;
}
*dnew = 0;
/* DELTA: Three in-core extents are replaced by one. */
temp = LEFT.br_startoff;
temp2 = LEFT.br_blockcount +
PREV.br_blockcount +
RIGHT.br_blockcount;
break;
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
goto done;
}
*dnew = 0;
/* DELTA: Two in-core extents are replaced by one. */
temp = LEFT.br_startoff;
temp2 = LEFT.br_blockcount +
PREV.br_blockcount;
break;
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
goto done;
}
*dnew = 0;
/* DELTA: Two in-core extents are replaced by one. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount +
RIGHT.br_blockcount;
break;
case MASK2(LEFT_FILLING, RIGHT_FILLING):
@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
ASSERT(i == 1);
}
*dnew = 0;
/* DELTA: The in-core extent described by new changed type. */
temp = new->br_startoff;
temp2 = new->br_blockcount;
break;
case MASK2(LEFT_FILLING, LEFT_CONTIG):
@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(
xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
XFS_DATA_FORK);
*dnew = temp;
/* DELTA: The boundary between two in-core extents moved. */
temp = LEFT.br_startoff;
temp2 = LEFT.br_blockcount +
PREV.br_blockcount;
break;
case MASK(LEFT_FILLING):
@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(
xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
XFS_DATA_FORK);
*dnew = temp;
/* DELTA: One in-core extent is split in two. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount;
break;
case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(
xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
XFS_DATA_FORK);
*dnew = temp;
/* DELTA: The boundary between two in-core extents moved. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount +
RIGHT.br_blockcount;
break;
case MASK(RIGHT_FILLING):
@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
*dnew = temp;
/* DELTA: One in-core extent is split in two. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount;
break;
case 0:
@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
XFS_DATA_FORK);
*dnew = temp + temp2;
/* DELTA: One in-core extent is split in three. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount;
break;
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
ASSERT(0);
}
*curp = cur;
if (delta) {
temp2 += temp;
if (delta->xed_startoff > temp)
delta->xed_startoff = temp;
if (delta->xed_blockcount < temp2)
delta->xed_blockcount = temp2;
}
done:
*logflagsp = rval;
return error;
@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp) /* inode logging flags */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta) /* Change made to incore extents */
{
xfs_btree_cur_t *cur; /* btree cursor */
xfs_bmbt_rec_t *ep; /* extent entry for idx */
@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(
/* left is 0, right is 1, prev is 2 */
int rval=0; /* return value (logging flags) */
int state = 0;/* state bits, accessed thru macros */
xfs_filblks_t temp=0;
xfs_filblks_t temp2=0;
enum { /* bit number definitions for state */
LEFT_CONTIG, RIGHT_CONTIG,
LEFT_FILLING, RIGHT_FILLING,
@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
RIGHT.br_blockcount, LEFT.br_state)))
goto done;
}
/* DELTA: Three in-core extents are replaced by one. */
temp = LEFT.br_startoff;
temp2 = LEFT.br_blockcount +
PREV.br_blockcount +
RIGHT.br_blockcount;
break;
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
LEFT.br_state)))
goto done;
}
/* DELTA: Two in-core extents are replaced by one. */
temp = LEFT.br_startoff;
temp2 = LEFT.br_blockcount +
PREV.br_blockcount;
break;
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
newext)))
goto done;
}
/* DELTA: Two in-core extents are replaced by one. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount +
RIGHT.br_blockcount;
break;
case MASK2(LEFT_FILLING, RIGHT_FILLING):
@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
newext)))
goto done;
}
/* DELTA: The in-core extent described by new changed type. */
temp = new->br_startoff;
temp2 = new->br_blockcount;
break;
case MASK2(LEFT_FILLING, LEFT_CONTIG):
@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
LEFT.br_state))
goto done;
}
/* DELTA: The boundary between two in-core extents moved. */
temp = LEFT.br_startoff;
temp2 = LEFT.br_blockcount +
PREV.br_blockcount;
break;
case MASK(LEFT_FILLING):
@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
goto done;
ASSERT(i == 1);
}
/* DELTA: One in-core extent is split in two. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount;
break;
case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
newext)))
goto done;
}
/* DELTA: The boundary between two in-core extents moved. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount +
RIGHT.br_blockcount;
break;
case MASK(RIGHT_FILLING):
@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
goto done;
ASSERT(i == 1);
}
/* DELTA: One in-core extent is split in two. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount;
break;
case 0:
@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
goto done;
ASSERT(i == 1);
}
/* DELTA: One in-core extent is split in three. */
temp = PREV.br_startoff;
temp2 = PREV.br_blockcount;
break;
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
ASSERT(0);
}
*curp = cur;
if (delta) {
temp2 += temp;
if (delta->xed_startoff > temp)
delta->xed_startoff = temp;
if (delta->xed_blockcount < temp2)
delta->xed_blockcount = temp2;
}
done:
*logflagsp = rval;
return error;
@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd) /* OK to allocate reserved blocks */
{
xfs_bmbt_rec_t *ep; /* extent record for idx */
@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(
xfs_filblks_t oldlen=0; /* old indirect size */
xfs_bmbt_irec_t right; /* right neighbor extent entry */
int state; /* state bits, accessed thru macros */
xfs_filblks_t temp; /* temp for indirect calculations */
xfs_filblks_t temp=0; /* temp for indirect calculations */
xfs_filblks_t temp2=0;
enum { /* bit number definitions for state */
LEFT_CONTIG, RIGHT_CONTIG,
LEFT_DELAY, RIGHT_DELAY,
@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
XFS_DATA_FORK);
xfs_iext_remove(ifp, idx, 1);
ip->i_df.if_lastex = idx - 1;
/* DELTA: Two in-core extents were replaced by one. */
temp2 = temp;
temp = left.br_startoff;
break;
case MASK(LEFT_CONTIG):
@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(
xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
XFS_DATA_FORK);
ip->i_df.if_lastex = idx - 1;
/* DELTA: One in-core extent grew into a hole. */
temp2 = temp;
temp = left.br_startoff;
break;
case MASK(RIGHT_CONTIG):
@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
NULLSTARTBLOCK((int)newlen), temp, right.br_state);
xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
ip->i_df.if_lastex = idx;
/* DELTA: One in-core extent grew into a hole. */
temp2 = temp;
temp = new->br_startoff;
break;
case 0:
@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
XFS_DATA_FORK);
xfs_iext_insert(ifp, idx, 1, new);
ip->i_df.if_lastex = idx;
/* DELTA: A new in-core extent was added in a hole. */
temp2 = new->br_blockcount;
temp = new->br_startoff;
break;
}
if (oldlen != newlen) {
@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
* Nothing to do for disk quota accounting here.
*/
}
if (delta) {
temp2 += temp;
if (delta->xed_startoff > temp)
delta->xed_startoff = temp;
if (delta->xed_blockcount < temp2)
delta->xed_blockcount = temp2;
}
*logflagsp = 0;
return 0;
#undef MASK
@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork) /* data or attr fork */
{
xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(
xfs_ifork_t *ifp; /* inode fork pointer */
xfs_bmbt_irec_t left; /* left neighbor extent entry */
xfs_bmbt_irec_t right; /* right neighbor extent entry */
int rval=0; /* return value (logging flags) */
int state; /* state bits, accessed thru macros */
xfs_filblks_t temp=0;
xfs_filblks_t temp2=0;
enum { /* bit number definitions for state */
LEFT_CONTIG, RIGHT_CONTIG,
LEFT_DELAY, RIGHT_DELAY,
@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
left.br_blockcount + new->br_blockcount +
right.br_blockcount <= MAXEXTLEN));
error = 0;
/*
* Select which case we're in here, and implement it.
*/
@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(
XFS_IFORK_NEXT_SET(ip, whichfork,
XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
if (cur == NULL) {
*logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
return 0;
rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
} else {
rval = XFS_ILOG_CORE;
if ((error = xfs_bmbt_lookup_eq(cur,
right.br_startoff,
right.br_startblock,
right.br_blockcount, &i)))
goto done;
ASSERT(i == 1);
if ((error = xfs_bmbt_delete(cur, &i)))
goto done;
ASSERT(i == 1);
if ((error = xfs_bmbt_decrement(cur, 0, &i)))
goto done;
ASSERT(i == 1);
if ((error = xfs_bmbt_update(cur, left.br_startoff,
left.br_startblock,
left.br_blockcount +
new->br_blockcount +
right.br_blockcount,
left.br_state)))
goto done;
}
*logflagsp = XFS_ILOG_CORE;
if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff,
right.br_startblock, right.br_blockcount, &i)))
return error;
ASSERT(i == 1);
if ((error = xfs_bmbt_delete(cur, &i)))
return error;
ASSERT(i == 1);
if ((error = xfs_bmbt_decrement(cur, 0, &i)))
return error;
ASSERT(i == 1);
error = xfs_bmbt_update(cur, left.br_startoff,
left.br_startblock,
left.br_blockcount + new->br_blockcount +
right.br_blockcount, left.br_state);
return error;
/* DELTA: Two in-core extents were replaced by one. */
temp = left.br_startoff;
temp2 = left.br_blockcount +
new->br_blockcount +
right.br_blockcount;
break;
case MASK(LEFT_CONTIG):
/*
@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(
xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
ifp->if_lastex = idx - 1;
if (cur == NULL) {
*logflagsp = XFS_ILOG_FEXT(whichfork);
return 0;
rval = XFS_ILOG_FEXT(whichfork);
} else {
rval = 0;
if ((error = xfs_bmbt_lookup_eq(cur,
left.br_startoff,
left.br_startblock,
left.br_blockcount, &i)))
goto done;
ASSERT(i == 1);
if ((error = xfs_bmbt_update(cur, left.br_startoff,
left.br_startblock,
left.br_blockcount +
new->br_blockcount,
left.br_state)))
goto done;
}
*logflagsp = 0;
if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff,
left.br_startblock, left.br_blockcount, &i)))
return error;
ASSERT(i == 1);
error = xfs_bmbt_update(cur, left.br_startoff,
left.br_startblock,
left.br_blockcount + new->br_blockcount,
left.br_state);
return error;
/* DELTA: One in-core extent grew. */
temp = left.br_startoff;
temp2 = left.br_blockcount +
new->br_blockcount;
break;
case MASK(RIGHT_CONTIG):
/*
@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
ifp->if_lastex = idx;
if (cur == NULL) {
*logflagsp = XFS_ILOG_FEXT(whichfork);
return 0;
rval = XFS_ILOG_FEXT(whichfork);
} else {
rval = 0;
if ((error = xfs_bmbt_lookup_eq(cur,
right.br_startoff,
right.br_startblock,
right.br_blockcount, &i)))
goto done;
ASSERT(i == 1);
if ((error = xfs_bmbt_update(cur, new->br_startoff,
new->br_startblock,
new->br_blockcount +
right.br_blockcount,
right.br_state)))
goto done;
}
*logflagsp = 0;
if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff,
right.br_startblock, right.br_blockcount, &i)))
return error;
ASSERT(i == 1);
error = xfs_bmbt_update(cur, new->br_startoff,
new->br_startblock,
new->br_blockcount + right.br_blockcount,
right.br_state);
return error;
/* DELTA: One in-core extent grew. */
temp = new->br_startoff;
temp2 = new->br_blockcount +
right.br_blockcount;
break;
case 0:
/*
@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
XFS_IFORK_NEXT_SET(ip, whichfork,
XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
if (cur == NULL) {
*logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
return 0;
rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
} else {
rval = XFS_ILOG_CORE;
if ((error = xfs_bmbt_lookup_eq(cur,
new->br_startoff,
new->br_startblock,
new->br_blockcount, &i)))
goto done;
ASSERT(i == 0);
cur->bc_rec.b.br_state = new->br_state;
if ((error = xfs_bmbt_insert(cur, &i)))
goto done;
ASSERT(i == 1);
}
*logflagsp = XFS_ILOG_CORE;
if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
new->br_startblock, new->br_blockcount, &i)))
return error;
ASSERT(i == 0);
cur->bc_rec.b.br_state = new->br_state;
if ((error = xfs_bmbt_insert(cur, &i)))
return error;
ASSERT(i == 1);
return 0;
/* DELTA: A new extent was added in a hole. */
temp = new->br_startoff;
temp2 = new->br_blockcount;
break;
}
if (delta) {
temp2 += temp;
if (delta->xed_startoff > temp)
delta->xed_startoff = temp;
if (delta->xed_blockcount < temp2)
delta->xed_blockcount = temp2;
}
done:
*logflagsp = rval;
return error;
#undef MASK
#undef MASK2
#undef STATE_SET
#undef STATE_TEST
#undef STATE_SET_TEST
#undef SWITCH_STATE
/* NOTREACHED */
ASSERT(0);
return 0; /* keep gcc quite */
}
/*
@ -2598,6 +2762,7 @@ xfs_bmap_btalloc(
args.mp = mp;
args.fsbno = ap->rval;
args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
args.firstblock = ap->firstblock;
blen = 0;
if (nullfb) {
args.type = XFS_ALLOCTYPE_START_BNO;
@ -2657,7 +2822,7 @@ xfs_bmap_btalloc(
else
args.minlen = ap->alen;
} else if (ap->low) {
args.type = XFS_ALLOCTYPE_FIRST_AG;
args.type = XFS_ALLOCTYPE_START_BNO;
args.total = args.minlen = ap->minlen;
} else {
args.type = XFS_ALLOCTYPE_NEAR_BNO;
@ -2669,7 +2834,7 @@ xfs_bmap_btalloc(
args.prod = ap->ip->i_d.di_extsize;
if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
args.mod = (xfs_extlen_t)(args.prod - args.mod);
} else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {
} else if (mp->m_sb.sb_blocksize >= NBPP) {
args.prod = 1;
args.mod = 0;
} else {
@ -2885,6 +3050,7 @@ xfs_bmap_del_extent(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *del, /* data to remove from extents */
int *logflagsp, /* inode logging flags */
xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd) /* OK to allocate reserved blocks */
{
@ -3193,6 +3359,14 @@ xfs_bmap_del_extent(
if (da_old > da_new)
xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
rsvd);
if (delta) {
/* DELTA: report the original extent. */
if (delta->xed_startoff > got.br_startoff)
delta->xed_startoff = got.br_startoff;
if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
delta->xed_blockcount = got.br_startoff +
got.br_blockcount;
}
done:
*logflagsp = flags;
return error;
@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree(
XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
args.tp = tp;
args.mp = mp;
args.firstblock = *firstblock;
if (*firstblock == NULLFSBLOCK) {
args.type = XFS_ALLOCTYPE_START_BNO;
args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents(
args.tp = tp;
args.mp = ip->i_mount;
args.firstblock = *firstblock;
ASSERT((ifp->if_flags &
(XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
/*
@ -3753,7 +3929,7 @@ xfs_bunmap_trace(
if (ip->i_rwtrace == NULL)
return;
ktrace_enter(ip->i_rwtrace,
(void *)(__psint_t)XFS_BUNMAPI,
(void *)(__psint_t)XFS_BUNMAP,
(void *)ip,
(void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
(void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
@ -4087,8 +4263,8 @@ xfs_bmap_finish(
if (!XFS_FORCED_SHUTDOWN(mp))
xfs_force_shutdown(mp,
(error == EFSCORRUPTED) ?
XFS_CORRUPT_INCORE :
XFS_METADATA_IO_ERROR);
SHUTDOWN_CORRUPT_INCORE :
SHUTDOWN_META_IO_ERROR);
return error;
}
xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
@ -4538,7 +4714,8 @@ xfs_bmapi(
xfs_extlen_t total, /* total blocks needed */
xfs_bmbt_irec_t *mval, /* output: map values */
int *nmap, /* i/o: mval size/count */
xfs_bmap_free_t *flist) /* i/o: list extents to free */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
xfs_extdelta_t *delta) /* o: change made to incore extents */
{
xfs_fsblock_t abno; /* allocated block number */
xfs_extlen_t alen; /* allocated extent length */
@ -4650,6 +4827,10 @@ xfs_bmapi(
end = bno + len;
obno = bno;
bma.ip = NULL;
if (delta) {
delta->xed_startoff = NULLFILEOFF;
delta->xed_blockcount = 0;
}
while (bno < end && n < *nmap) {
/*
* Reading past eof, act as though there's a hole
@ -4886,8 +5067,8 @@ xfs_bmapi(
got.br_state = XFS_EXT_UNWRITTEN;
}
error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
firstblock, flist, &tmp_logflags, whichfork,
(flags & XFS_BMAPI_RSVBLOCKS));
firstblock, flist, &tmp_logflags, delta,
whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
logflags |= tmp_logflags;
if (error)
goto error0;
@ -4983,8 +5164,8 @@ xfs_bmapi(
}
mval->br_state = XFS_EXT_NORM;
error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
firstblock, flist, &tmp_logflags, whichfork,
(flags & XFS_BMAPI_RSVBLOCKS));
firstblock, flist, &tmp_logflags, delta,
whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
logflags |= tmp_logflags;
if (error)
goto error0;
@ -5073,7 +5254,14 @@ xfs_bmapi(
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
error = 0;
if (delta && delta->xed_startoff != NULLFILEOFF) {
/* A change was actually made.
* Note that delta->xed_blockount is an offset at this
* point and needs to be converted to a block count.
*/
ASSERT(delta->xed_blockcount > delta->xed_startoff);
delta->xed_blockcount -= delta->xed_startoff;
}
error0:
/*
* Log everything. Do this after conversion, there's no point in
@ -5185,6 +5373,8 @@ xfs_bunmapi(
xfs_fsblock_t *firstblock, /* first allocated block
controls a.g. for allocs */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
xfs_extdelta_t *delta, /* o: change made to incore
extents */
int *done) /* set if not done yet */
{
xfs_btree_cur_t *cur; /* bmap btree cursor */
@ -5242,6 +5432,10 @@ xfs_bunmapi(
bno = start + len - 1;
ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
&prev);
if (delta) {
delta->xed_startoff = NULLFILEOFF;
delta->xed_blockcount = 0;
}
/*
* Check to see if the given block number is past the end of the
* file, back up to the last block if so...
@ -5340,7 +5534,8 @@ xfs_bunmapi(
}
del.br_state = XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
firstblock, flist, &logflags, XFS_DATA_FORK, 0);
firstblock, flist, &logflags, delta,
XFS_DATA_FORK, 0);
if (error)
goto error0;
goto nodelete;
@ -5394,7 +5589,7 @@ xfs_bunmapi(
prev.br_state = XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
&prev, firstblock, flist, &logflags,
XFS_DATA_FORK, 0);
delta, XFS_DATA_FORK, 0);
if (error)
goto error0;
goto nodelete;
@ -5403,7 +5598,7 @@ xfs_bunmapi(
del.br_state = XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent(ip, lastx, &cur,
&del, firstblock, flist, &logflags,
XFS_DATA_FORK, 0);
delta, XFS_DATA_FORK, 0);
if (error)
goto error0;
goto nodelete;
@ -5456,7 +5651,7 @@ xfs_bunmapi(
goto error0;
}
error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
&tmp_logflags, whichfork, rsvd);
&tmp_logflags, delta, whichfork, rsvd);
logflags |= tmp_logflags;
if (error)
goto error0;
@ -5513,6 +5708,14 @@ nodelete:
ASSERT(ifp->if_ext_max ==
XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
error = 0;
if (delta && delta->xed_startoff != NULLFILEOFF) {
/* A change was actually made.
* Note that delta->xed_blockount is an offset at this
* point and needs to be converted to a block count.
*/
ASSERT(delta->xed_blockcount > delta->xed_startoff);
delta->xed_blockcount -= delta->xed_startoff;
}
error0:
/*
* Log everything. Do this after conversion, there's no point in
@ -5556,7 +5759,7 @@ xfs_getbmap(
__int64_t fixlen; /* length for -1 case */
int i; /* extent number */
xfs_inode_t *ip; /* xfs incore inode pointer */
vnode_t *vp; /* corresponding vnode */
bhv_vnode_t *vp; /* corresponding vnode */
int lock; /* lock state */
xfs_bmbt_irec_t *map; /* buffer for user's data */
xfs_mount_t *mp; /* file system mount point */
@ -5653,7 +5856,7 @@ xfs_getbmap(
if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
}
ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
@ -5689,7 +5892,8 @@ xfs_getbmap(
nmap = (nexleft > subnex) ? subnex : nexleft;
error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
XFS_BB_TO_FSB(mp, bmv->bmv_length),
bmapi_flags, NULL, 0, map, &nmap, NULL);
bmapi_flags, NULL, 0, map, &nmap,
NULL, NULL);
if (error)
goto unlock_and_return;
ASSERT(nmap <= subnex);

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -25,6 +25,20 @@ struct xfs_inode;
struct xfs_mount;
struct xfs_trans;
/*
* DELTA: describe a change to the in-core extent list.
*
* Internally the use of xed_blockount is somewhat funky.
* xed_blockcount contains an offset much of the time because this
* makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
* the same underlying type).
*/
typedef struct xfs_extdelta
{
xfs_fileoff_t xed_startoff; /* offset of range */
xfs_filblks_t xed_blockcount; /* blocks in range */
} xfs_extdelta_t;
/*
* List of extents to be free "later".
* The list is kept sorted on xbf_startblock.
@ -275,7 +289,9 @@ xfs_bmapi(
xfs_extlen_t total, /* total blocks needed */
struct xfs_bmbt_irec *mval, /* output: map values */
int *nmap, /* i/o: mval size/count */
xfs_bmap_free_t *flist); /* i/o: list extents to free */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
xfs_extdelta_t *delta); /* o: change made to incore
extents */
/*
* Map file blocks to filesystem blocks, simple version.
@ -309,6 +325,8 @@ xfs_bunmapi(
xfs_fsblock_t *firstblock, /* first allocated block
controls a.g. for allocs */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
xfs_extdelta_t *delta, /* o: change made to incore
extents */
int *done); /* set if not done yet */
/*

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -1569,12 +1567,11 @@ xfs_bmbt_split(
lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
left = XFS_BUF_TO_BMBT_BLOCK(lbp);
args.fsbno = cur->bc_private.b.firstblock;
args.firstblock = args.fsbno;
if (args.fsbno == NULLFSBLOCK) {
args.fsbno = lbno;
args.type = XFS_ALLOCTYPE_START_BNO;
} else if (cur->bc_private.b.flist->xbf_low)
args.type = XFS_ALLOCTYPE_FIRST_AG;
else
} else
args.type = XFS_ALLOCTYPE_NEAR_BNO;
args.mod = args.minleft = args.alignment = args.total = args.isfl =
args.userdata = args.minalignslop = 0;
@ -2356,6 +2353,7 @@ xfs_bmbt_newroot(
args.userdata = args.minalignslop = 0;
args.minlen = args.maxlen = args.prod = 1;
args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
args.firstblock = args.fsbno;
if (args.fsbno == NULLFSBLOCK) {
#ifdef DEBUG
if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
@ -2365,9 +2363,7 @@ xfs_bmbt_newroot(
#endif
args.fsbno = INT_GET(*pp, ARCH_CONVERT);
args.type = XFS_ALLOCTYPE_START_BNO;
} else if (args.wasdel)
args.type = XFS_ALLOCTYPE_FIRST_AG;
else
} else
args.type = XFS_ALLOCTYPE_NEAR_BNO;
if ((error = xfs_alloc_vextent(&args))) {
XFS_BMBT_TRACE_CURSOR(cur, ERROR);

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_buf_item.h"
@ -1030,9 +1029,9 @@ xfs_buf_iodone_callbacks(
if ((XFS_BUF_TARGET(bp) != lasttarg) ||
(time_after(jiffies, (lasttime + 5*HZ)))) {
lasttime = jiffies;
prdev("XFS write error in file system meta-data "
"block 0x%llx in %s",
XFS_BUF_TARGET(bp),
cmn_err(CE_ALERT, "Device %s, XFS metadata write error"
" block 0x%llx in %s",
XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
(__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname);
}
lasttarg = XFS_BUF_TARGET(bp);
@ -1108,7 +1107,7 @@ xfs_buf_error_relse(
XFS_BUF_ERROR(bp,0);
xfs_buftrace("BUF_ERROR_RELSE", bp);
if (! XFS_FORCED_SHUTDOWN(mp))
xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
/*
* We have to unpin the pinned buffers so do the
* callbacks.

Просмотреть файл

@ -49,12 +49,12 @@ typedef struct xfs_cap_set {
#include <linux/posix_cap_xattr.h>
struct vnode;
struct bhv_vnode;
extern int xfs_cap_vhascap(struct vnode *);
extern int xfs_cap_vset(struct vnode *, void *, size_t);
extern int xfs_cap_vget(struct vnode *, void *, size_t);
extern int xfs_cap_vremove(struct vnode *vp);
extern int xfs_cap_vhascap(struct bhv_vnode *);
extern int xfs_cap_vset(struct bhv_vnode *, void *, size_t);
extern int xfs_cap_vget(struct bhv_vnode *, void *, size_t);
extern int xfs_cap_vremove(struct bhv_vnode *);
#define _CAP_EXISTS xfs_cap_vhascap

Просмотреть файл

@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -43,7 +41,6 @@
#include "xfs_bmap.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state)
max = state->path.active - 1;
ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp));
state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
addblk = &state->path.blk[max]; /* initial dummy value */
for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state)
return(error); /* GROT: attr inconsistent */
addblk = newblk;
break;
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
error = xfs_dir_leaf_split(state, oldblk, newblk);
if ((error != 0) && (error != ENOSPC)) {
return(error); /* GROT: dir is inconsistent */
}
if (!error) {
addblk = newblk;
break;
}
/*
* Entry wouldn't fit, split the leaf again.
*/
state->extravalid = 1;
if (state->inleaf) {
state->extraafter = 0; /* before newblk */
error = xfs_dir_leaf_split(state, oldblk,
&state->extrablk);
if (error)
return(error); /* GROT: dir incon. */
addblk = newblk;
} else {
state->extraafter = 1; /* after newblk */
error = xfs_dir_leaf_split(state, newblk,
&state->extrablk);
if (error)
return(error); /* GROT: dir incon. */
addblk = newblk;
}
break;
case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
error = xfs_dir2_leafn_split(state, oldblk, newblk);
if (error)
return error;
@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
(char *)oldroot);
} else {
ASSERT(XFS_DIR_IS_V2(mp));
ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
leaf = (xfs_dir2_leaf_t *)oldroot;
size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
* Set up the new root node.
*/
error = xfs_da_node_create(args,
args->whichfork == XFS_DATA_FORK &&
XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
(args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,
be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
if (error)
return(error);
@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
/*
* With V2 the extra block is data or freespace.
* With V2 dirs the extra block is data or freespace.
*/
useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) ||
state->args->whichfork == XFS_ATTR_FORK);
useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;
newcount = 1 + useextra;
/*
* Do we have to split the node?
@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
ASSERT(newblk->blkno != 0);
if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
if (state->args->whichfork == XFS_DATA_FORK)
ASSERT(newblk->blkno >= mp->m_dirleafblk &&
newblk->blkno < mp->m_dirfreeblk);
@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state)
save_blk = &state->altpath.blk[ state->path.active-1 ];
ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp));
drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
/*
* Walk back up the tree joining/deallocating as necessary.
@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state)
return(0);
xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
break;
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
error = xfs_dir_leaf_toosmall(state, &action);
if (error)
return(error);
if (action == 0)
return(0);
xfs_dir_leaf_unbalance(state, drop_blk, save_blk);
break;
case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
error = xfs_dir2_leafn_toosmall(state, &action);
if (error)
return error;
@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
ASSERT(bp != NULL);
blkinfo = bp->data;
if (be16_to_cpu(oldroot->hdr.level) == 1) {
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC ||
be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
} else {
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
if (count == 0)
return;
break;
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
if (count == 0)
return;
break;
case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
if (count == 0)
return;
@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
* Descend thru the B-tree searching each level for the right
* node to use, until the right hashval is found.
*/
if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp))
blkno = state->mp->m_dirleafblk;
else
blkno = 0;
blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;
for (blk = &state->path.blk[0], state->path.active = 1;
state->path.active <= XFS_DA_NODE_MAXDEPTH;
blk++, state->path.active++) {
@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
}
curr = blk->bp->data;
ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
/*
@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
blk->index = probe;
blkno = be32_to_cpu(btree->before);
}
}
else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
} else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
break;
}
else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) {
blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
break;
}
else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
} else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
break;
}
@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
* next leaf and keep searching.
*/
for (;;) {
if (blk->magic == XFS_DIR_LEAF_MAGIC) {
ASSERT(XFS_DIR_IS_V1(state->mp));
retval = xfs_dir_leaf_lookup_int(blk->bp, args,
&blk->index);
} else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
ASSERT(XFS_DIR_IS_V2(state->mp));
if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
&blk->index, state);
}
@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
old_info = old_blk->bp->data;
new_info = new_blk->bp->data;
ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
old_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
old_blk->magic == XFS_ATTR_LEAF_MAGIC);
ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
ASSERT(new_blk->magic == be16_to_cpu(new_info->magic));
@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
case XFS_ATTR_LEAF_MAGIC:
before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
break;
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
break;
case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
break;
case XFS_DA_NODE_MAGIC:
@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
save_info = save_blk->bp->data;
drop_info = drop_blk->bp->data;
ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
save_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
save_blk->magic == XFS_ATTR_LEAF_MAGIC);
ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic));
@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
ASSERT(blk->bp != NULL);
info = blk->bp->data;
ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC ||
be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC ||
be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
blk->magic = be16_to_cpu(info->magic);
if (blk->magic == XFS_DA_NODE_MAGIC) {
@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
NULL);
break;
case XFS_DIR_LEAF_MAGIC:
ASSERT(XFS_DIR_IS_V1(state->mp));
blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
NULL);
break;
case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
NULL);
break;
default:
ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
blk->magic ==
XFS_DIRX_LEAF_MAGIC(state->mp));
blk->magic == XFS_DIR2_LEAFN_MAGIC);
break;
}
}
@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
xfs_bmbt_irec_t *mapp;
xfs_inode_t *dp;
int nmap, error, w, count, c, got, i, mapi;
xfs_fsize_t size;
xfs_trans_t *tp;
xfs_mount_t *mp;
@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
/*
* For new directories adjust the file offset and block count.
*/
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) {
if (w == XFS_DATA_FORK) {
bno = mp->m_dirleafblk;
count = mp->m_dirblkfsbs;
} else {
@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
/*
* Find a spot in the file space to put the new block.
*/
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) {
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w)))
return error;
}
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
if (w == XFS_DATA_FORK)
ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
/*
* Try mapping it in one filesystem block.
@ -1655,7 +1573,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
XFS_BMAPI_CONTIG,
args->firstblock, args->total, &map, &nmap,
args->flist))) {
args->flist, NULL))) {
return error;
}
ASSERT(nmap <= 1);
@ -1676,7 +1594,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
XFS_BMAPI_METADATA,
args->firstblock, args->total,
&mapp[mapi], &nmap, args->flist))) {
&mapp[mapi], &nmap, args->flist,
NULL))) {
kmem_free(mapp, sizeof(*mapp) * count);
return error;
}
@ -1705,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
if (mapp != &map)
kmem_free(mapp, sizeof(*mapp) * count);
*new_blkno = (xfs_dablk_t)bno;
/*
* For version 1 directories, adjust the file size if it changed.
*/
if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
ASSERT(mapi == 1);
if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
return error;
size = XFS_FSB_TO_B(mp, bno);
if (size != dp->i_d.di_size) {
dp->i_d.di_size = size;
xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
}
}
return 0;
}
@ -1742,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
int error, w, entno, level, dead_level;
xfs_da_blkinfo_t *dead_info, *sib_info;
xfs_da_intnode_t *par_node, *dead_node;
xfs_dir_leafblock_t *dead_leaf;
xfs_dir2_leaf_t *dead_leaf2;
xfs_dahash_t dead_hash;
@ -1753,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
w = args->whichfork;
ASSERT(w == XFS_DATA_FORK);
mp = ip->i_mount;
if (XFS_DIR_IS_V2(mp)) {
lastoff = mp->m_dirfreeblk;
error = xfs_bmap_last_before(tp, ip, &lastoff, w);
} else
error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
lastoff = mp->m_dirfreeblk;
error = xfs_bmap_last_before(tp, ip, &lastoff, w);
if (error)
return error;
if (unlikely(lastoff == 0)) {
@ -1780,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
/*
* Get values from the moved block.
*/
if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) {
ASSERT(XFS_DIR_IS_V1(mp));
dead_leaf = (xfs_dir_leafblock_t *)dead_info;
dead_level = 0;
dead_hash =
INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
} else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
ASSERT(XFS_DIR_IS_V2(mp));
if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
dead_level = 0;
dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
@ -1842,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
xfs_da_buf_done(sib_buf);
sib_buf = NULL;
}
par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk;
par_blkno = mp->m_dirleafblk;
level = -1;
/*
* Walk down the tree looking for the parent of the moved block.
@ -1941,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
{
xfs_inode_t *dp;
int done, error, w, count;
xfs_fileoff_t bno;
xfs_fsize_t size;
xfs_trans_t *tp;
xfs_mount_t *mp;
@ -1950,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
w = args->whichfork;
tp = args->trans;
mp = dp->i_mount;
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
if (w == XFS_DATA_FORK)
count = mp->m_dirblkfsbs;
else
count = 1;
@ -1961,34 +1854,17 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
*/
if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
0, args->firstblock, args->flist,
0, args->firstblock, args->flist, NULL,
&done)) == ENOSPC) {
if (w != XFS_DATA_FORK)
goto done;
break;
if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
&dead_buf)))
goto done;
} else if (error)
goto done;
else
break;
} else {
break;
}
ASSERT(done);
xfs_da_binval(tp, dead_buf);
/*
* Adjust the directory size for version 1.
*/
if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
return error;
size = XFS_FSB_TO_B(dp->i_mount, bno);
if (size != dp->i_d.di_size) {
dp->i_d.di_size = size;
xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
}
}
return 0;
done:
xfs_da_binval(tp, dead_buf);
return error;
}
@ -2049,10 +1925,7 @@ xfs_da_do_buf(
xfs_dabuf_t *rbp;
mp = dp->i_mount;
if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
nfsb = mp->m_dirblkfsbs;
else
nfsb = 1;
nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;
mappedbno = *mappedbnop;
/*
* Caller doesn't have a mapping. -2 means don't complain
@ -2086,7 +1959,7 @@ xfs_da_do_buf(
nfsb,
XFS_BMAPI_METADATA |
XFS_BMAPI_AFLAG(whichfork),
NULL, 0, mapp, &nmap, NULL)))
NULL, 0, mapp, &nmap, NULL, NULL)))
goto exit0;
}
} else {
@ -2198,7 +2071,6 @@ xfs_da_do_buf(
magic1 = be32_to_cpu(data->hdr.magic);
if (unlikely(
XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
(magic != XFS_DIR_LEAF_MAGIC) &&
(magic != XFS_ATTR_LEAF_MAGIC) &&
(magic != XFS_DIR2_LEAF1_MAGIC) &&
(magic != XFS_DIR2_LEAFN_MAGIC) &&

Просмотреть файл

@ -36,14 +36,10 @@ struct zone;
* level in the Btree, and to identify which type of block this is.
*/
#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */
#define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */
#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */
#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */
#define XFS_DIRX_LEAF_MAGIC(mp) \
(XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC)
typedef struct xfs_da_blkinfo {
__be32 forw; /* previous block in list */
__be32 back; /* following block in list */

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -54,24 +52,14 @@ xfs_swapext(
xfs_swapext_t __user *sxu)
{
xfs_swapext_t *sxp;
xfs_inode_t *ip=NULL, *tip=NULL, *ips[2];
xfs_trans_t *tp;
xfs_inode_t *ip=NULL, *tip=NULL;
xfs_mount_t *mp;
xfs_bstat_t *sbp;
struct file *fp = NULL, *tfp = NULL;
vnode_t *vp, *tvp;
static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
int ilf_fields, tilf_fields;
bhv_vnode_t *vp, *tvp;
int error = 0;
xfs_ifork_t *tempifp, *ifp, *tifp;
__uint64_t tmp;
int aforkblks = 0;
int taforkblks = 0;
char locked = 0;
sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
if (!sxp || !tempifp) {
if (!sxp) {
error = XFS_ERROR(ENOMEM);
goto error0;
}
@ -118,14 +106,56 @@ xfs_swapext(
mp = ip->i_mount;
sbp = &sxp->sx_stat;
if (XFS_FORCED_SHUTDOWN(mp)) {
error = XFS_ERROR(EIO);
goto error0;
}
locked = 1;
error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
error0:
if (fp != NULL)
fput(fp);
if (tfp != NULL)
fput(tfp);
if (sxp != NULL)
kmem_free(sxp, sizeof(xfs_swapext_t));
return error;
}
int
xfs_swap_extents(
xfs_inode_t *ip,
xfs_inode_t *tip,
xfs_swapext_t *sxp)
{
xfs_mount_t *mp;
xfs_inode_t *ips[2];
xfs_trans_t *tp;
xfs_bstat_t *sbp = &sxp->sx_stat;
bhv_vnode_t *vp, *tvp;
xfs_ifork_t *tempifp, *ifp, *tifp;
int ilf_fields, tilf_fields;
static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
int error = 0;
int aforkblks = 0;
int taforkblks = 0;
__uint64_t tmp;
char locked = 0;
mp = ip->i_mount;
tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
if (!tempifp) {
error = XFS_ERROR(ENOMEM);
goto error0;
}
sbp = &sxp->sx_stat;
vp = XFS_ITOV(ip);
tvp = XFS_ITOV(tip);
/* Lock in i_ino order */
if (ip->i_ino < tip->i_ino) {
@ -137,6 +167,7 @@ xfs_swapext(
}
xfs_lock_inodes(ips, 2, 0, lock_flags);
locked = 1;
/* Check permissions */
error = xfs_iaccess(ip, S_IWUSR, NULL);
@ -169,7 +200,7 @@ xfs_swapext(
if (VN_CACHED(tvp) != 0) {
xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED);
bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
}
/* Verify O_DIRECT for ftmp */
@ -214,7 +245,7 @@ xfs_swapext(
/* We need to fail if the file is memory mapped. Once we have tossed
* all existing pages, the page fault will have no option
* but to go to the filesystem for pages. By making the page fault call
* VOP_READ (or write in the case of autogrow) they block on the iolock
* vop_read (or write in the case of autogrow) they block on the iolock
* until we have switched the extents.
*/
if (VN_MAPPED(vp)) {
@ -233,7 +264,7 @@ xfs_swapext(
* fields change.
*/
VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF);
bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
if ((error = xfs_trans_reserve(tp, 0,
@ -360,16 +391,7 @@ xfs_swapext(
xfs_iunlock(ip, lock_flags);
xfs_iunlock(tip, lock_flags);
}
if (fp != NULL)
fput(fp);
if (tfp != NULL)
fput(tfp);
if (sxp != NULL)
kmem_free(sxp, sizeof(xfs_swapext_t));
if (tempifp != NULL)
kmem_free(tempifp, sizeof(xfs_ifork_t));
return error;
}

Просмотреть файл

@ -48,6 +48,9 @@ typedef struct xfs_swapext
*/
int xfs_swapext(struct xfs_swapext __user *sx);
int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
struct xfs_swapext *sxp);
#endif /* __KERNEL__ */
#endif /* __XFS_DFRAG_H__ */

Просмотреть файл

@ -85,7 +85,6 @@ typedef struct xfs_dinode
union {
xfs_bmdr_block_t di_bmbt; /* btree root block */
xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
xfs_dir_shortform_t di_dirsf; /* shortform directory */
xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
char di_c[1]; /* local contents */
xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
@ -257,6 +256,7 @@ typedef enum xfs_dinode_fmt
#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */
#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
#define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
@ -270,12 +270,13 @@ typedef enum xfs_dinode_fmt
#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
#define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
#define XFS_DIFLAG_ANY \
(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
XFS_DIFLAG_EXTSZINHERIT)
XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
#endif /* __XFS_DINODE_H__ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,142 +0,0 @@
/*
* Copyright (c) 2000,2005 Silicon Graphics, Inc.
* All Rights Reserved.
*
* 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.
*
* 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. 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 the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR_H__
#define __XFS_DIR_H__
/*
* Large directories are structured around Btrees where all the data
* elements are in the leaf nodes. Filenames are hashed into an int,
* then that int is used as the index into the Btree. Since the hashval
* of a filename may not be unique, we may have duplicate keys. The
* internal links in the Btree are logical block offsets into the file.
*
* Small directories use a different format and are packed as tightly
* as possible so as to fit into the literal area of the inode.
*/
/*========================================================================
* Function prototypes for the kernel.
*========================================================================*/
struct uio;
struct xfs_bmap_free;
struct xfs_da_args;
struct xfs_dinode;
struct xfs_inode;
struct xfs_mount;
struct xfs_trans;
/*
* Directory function types.
* Put in structures (xfs_dirops_t) for v1 and v2 directories.
*/
typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp);
typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp);
typedef int (*xfs_dir_init_t)(struct xfs_trans *tp,
struct xfs_inode *dp,
struct xfs_inode *pdp);
typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp,
struct xfs_inode *dp,
char *name,
int namelen,
xfs_ino_t inum,
xfs_fsblock_t *first,
struct xfs_bmap_free *flist,
xfs_extlen_t total);
typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp,
struct xfs_inode *dp,
char *name,
int namelen,
xfs_ino_t *inum);
typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp,
struct xfs_inode *dp,
char *name,
int namelen,
xfs_ino_t ino,
xfs_fsblock_t *first,
struct xfs_bmap_free *flist,
xfs_extlen_t total);
typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp,
struct xfs_inode *dp,
struct uio *uio,
int *eofp);
typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp,
struct xfs_inode *dp,
char *name,
int namelen,
xfs_ino_t inum,
xfs_fsblock_t *first,
struct xfs_bmap_free *flist,
xfs_extlen_t total);
typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp,
struct xfs_inode *dp,
char *name,
int namelen);
typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp,
struct xfs_dinode *dip);
typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args);
typedef struct xfs_dirops {
xfs_dir_mount_t xd_mount;
xfs_dir_isempty_t xd_isempty;
xfs_dir_init_t xd_init;
xfs_dir_createname_t xd_createname;
xfs_dir_lookup_t xd_lookup;
xfs_dir_removename_t xd_removename;
xfs_dir_getdents_t xd_getdents;
xfs_dir_replace_t xd_replace;
xfs_dir_canenter_t xd_canenter;
xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk;
xfs_dir_shortform_to_single_t xd_shortform_to_single;
} xfs_dirops_t;
/*
* Overall external interface routines.
*/
void xfs_dir_startup(void); /* called exactly once */
#define XFS_DIR_MOUNT(mp) \
((mp)->m_dirops.xd_mount(mp))
#define XFS_DIR_ISEMPTY(mp,dp) \
((mp)->m_dirops.xd_isempty(dp))
#define XFS_DIR_INIT(mp,tp,dp,pdp) \
((mp)->m_dirops.xd_init(tp,dp,pdp))
#define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \
((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\
total))
#define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \
((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum))
#define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \
((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total))
#define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \
((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp))
#define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \
((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total))
#define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \
((mp)->m_dirops.xd_canenter(tp,dp,name,namelen))
#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \
((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip))
#define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \
((mp)->m_dirops.xd_shortform_to_single(args))
#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1)
#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2)
extern xfs_dirops_t xfsv1_dirops;
extern xfs_dirops_t xfsv2_dirops;
#endif /* __XFS_DIR_H__ */

Просмотреть файл

@ -24,21 +24,18 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
@ -46,69 +43,14 @@
#include "xfs_dir2_trace.h"
#include "xfs_error.h"
/*
* Declarations for interface routines.
*/
static void xfs_dir2_mount(xfs_mount_t *mp);
static int xfs_dir2_isempty(xfs_inode_t *dp);
static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp,
xfs_inode_t *pdp);
static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp,
char *name, int namelen, xfs_ino_t inum,
xfs_fsblock_t *first,
xfs_bmap_free_t *flist, xfs_extlen_t total);
static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
int namelen, xfs_ino_t *inum);
static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp,
char *name, int namelen, xfs_ino_t ino,
xfs_fsblock_t *first,
xfs_bmap_free_t *flist, xfs_extlen_t total);
static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio,
int *eofp);
static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
int namelen, xfs_ino_t inum,
xfs_fsblock_t *first, xfs_bmap_free_t *flist,
xfs_extlen_t total);
static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
int namelen);
static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp,
xfs_dinode_t *dip);
/*
* Utility routine declarations.
*/
static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
/*
* Directory operations vector.
*/
xfs_dirops_t xfsv2_dirops = {
.xd_mount = xfs_dir2_mount,
.xd_isempty = xfs_dir2_isempty,
.xd_init = xfs_dir2_init,
.xd_createname = xfs_dir2_createname,
.xd_lookup = xfs_dir2_lookup,
.xd_removename = xfs_dir2_removename,
.xd_getdents = xfs_dir2_getdents,
.xd_replace = xfs_dir2_replace,
.xd_canenter = xfs_dir2_canenter,
.xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk,
.xd_shortform_to_single = xfs_dir2_sf_to_block,
};
/*
* Interface routines.
*/
/*
* Initialize directory-related fields in the mount structure.
*/
static void
xfs_dir2_mount(
xfs_mount_t *mp) /* filesystem mount point */
void
xfs_dir_mount(
xfs_mount_t *mp)
{
mp->m_dirversion = 2;
ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));
ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
XFS_MAX_BLOCKSIZE);
mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
@ -128,73 +70,99 @@ xfs_dir2_mount(
/*
* Return 1 if directory contains only "." and "..".
*/
static int /* return code */
xfs_dir2_isempty(
xfs_inode_t *dp) /* incore inode structure */
int
xfs_dir_isempty(
xfs_inode_t *dp)
{
xfs_dir2_sf_t *sfp; /* shortform directory structure */
xfs_dir2_sf_t *sfp;
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
/*
* Might happen during shutdown.
*/
if (dp->i_d.di_size == 0) {
if (dp->i_d.di_size == 0) /* might happen during shutdown. */
return 1;
}
if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
return 0;
sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
return !sfp->hdr.count;
}
/*
* Validate a given inode number.
*/
int
xfs_dir_ino_validate(
xfs_mount_t *mp,
xfs_ino_t ino)
{
xfs_agblock_t agblkno;
xfs_agino_t agino;
xfs_agnumber_t agno;
int ino_ok;
int ioff;
agno = XFS_INO_TO_AGNO(mp, ino);
agblkno = XFS_INO_TO_AGBNO(mp, ino);
ioff = XFS_INO_TO_OFFSET(mp, ino);
agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
ino_ok =
agno < mp->m_sb.sb_agcount &&
agblkno < mp->m_sb.sb_agblocks &&
agblkno != 0 &&
ioff < (1 << mp->m_sb.sb_inopblog) &&
XFS_AGINO_TO_INO(mp, agno, agino) == ino;
if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
XFS_RANDOM_DIR_INO_VALIDATE))) {
xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
(unsigned long long) ino);
XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
return 0;
}
/*
* Initialize a directory with its "." and ".." entries.
*/
static int /* error */
xfs_dir2_init(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
xfs_inode_t *pdp) /* incore parent directory inode */
int
xfs_dir_init(
xfs_trans_t *tp,
xfs_inode_t *dp,
xfs_inode_t *pdp)
{
xfs_da_args_t args; /* operation arguments */
int error; /* error return value */
xfs_da_args_t args;
int error;
memset((char *)&args, 0, sizeof(args));
args.dp = dp;
args.trans = tp;
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) {
if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))
return error;
}
return xfs_dir2_sf_create(&args, pdp->i_ino);
}
/*
Enter a name in a directory.
*/
static int /* error */
xfs_dir2_createname(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
char *name, /* new entry name */
int namelen, /* new entry name length */
int
xfs_dir_createname(
xfs_trans_t *tp,
xfs_inode_t *dp,
char *name,
int namelen,
xfs_ino_t inum, /* new entry inode number */
xfs_fsblock_t *first, /* bmap's firstblock */
xfs_bmap_free_t *flist, /* bmap's freeblock list */
xfs_extlen_t total) /* bmap's total block count */
{
xfs_da_args_t args; /* operation arguments */
int rval; /* return value */
xfs_da_args_t args;
int rval;
int v; /* type-checking value */
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
return rval;
}
XFS_STATS_INC(xs_dir_create);
/*
* Fill in the arg structure for this request.
*/
args.name = name;
args.namelen = namelen;
args.hashval = xfs_da_hashname(name, namelen);
@ -207,18 +175,16 @@ xfs_dir2_createname(
args.trans = tp;
args.justcheck = 0;
args.addname = args.oknoent = 1;
/*
* Decide on what work routines to call based on the inode size.
*/
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_addname(&args);
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_block_addname(&args);
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_leaf_addname(&args);
else
rval = xfs_dir2_node_addname(&args);
@ -228,24 +194,21 @@ xfs_dir2_createname(
/*
* Lookup a name in a directory, give back the inode number.
*/
static int /* error */
xfs_dir2_lookup(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
char *name, /* lookup name */
int namelen, /* lookup name length */
int
xfs_dir_lookup(
xfs_trans_t *tp,
xfs_inode_t *dp,
char *name,
int namelen,
xfs_ino_t *inum) /* out: inode number */
{
xfs_da_args_t args; /* operation arguments */
int rval; /* return value */
xfs_da_args_t args;
int rval;
int v; /* type-checking value */
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
XFS_STATS_INC(xs_dir_lookup);
/*
* Fill in the arg structure for this request.
*/
args.name = name;
args.namelen = namelen;
args.hashval = xfs_da_hashname(name, namelen);
@ -258,18 +221,16 @@ xfs_dir2_lookup(
args.trans = tp;
args.justcheck = args.addname = 0;
args.oknoent = 1;
/*
* Decide on what work routines to call based on the inode size.
*/
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_lookup(&args);
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_block_lookup(&args);
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_leaf_lookup(&args);
else
rval = xfs_dir2_node_lookup(&args);
@ -283,26 +244,24 @@ xfs_dir2_lookup(
/*
* Remove an entry from a directory.
*/
static int /* error */
xfs_dir2_removename(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
char *name, /* name of entry to remove */
int namelen, /* name length of entry to remove */
xfs_ino_t ino, /* inode number of entry to remove */
int
xfs_dir_removename(
xfs_trans_t *tp,
xfs_inode_t *dp,
char *name,
int namelen,
xfs_ino_t ino,
xfs_fsblock_t *first, /* bmap's firstblock */
xfs_bmap_free_t *flist, /* bmap's freeblock list */
xfs_extlen_t total) /* bmap's total block count */
{
xfs_da_args_t args; /* operation arguments */
int rval; /* return value */
xfs_da_args_t args;
int rval;
int v; /* type-checking value */
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
XFS_STATS_INC(xs_dir_remove);
/*
* Fill in the arg structure for this request.
*/
args.name = name;
args.namelen = namelen;
args.hashval = xfs_da_hashname(name, namelen);
@ -314,18 +273,16 @@ xfs_dir2_removename(
args.whichfork = XFS_DATA_FORK;
args.trans = tp;
args.justcheck = args.addname = args.oknoent = 0;
/*
* Decide on what work routines to call based on the inode size.
*/
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_removename(&args);
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_block_removename(&args);
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_leaf_removename(&args);
else
rval = xfs_dir2_node_removename(&args);
@ -335,10 +292,10 @@ xfs_dir2_removename(
/*
* Read a directory.
*/
static int /* error */
xfs_dir2_getdents(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
int
xfs_dir_getdents(
xfs_trans_t *tp,
xfs_inode_t *dp,
uio_t *uio, /* caller's buffer control */
int *eofp) /* out: eof reached */
{
@ -367,14 +324,11 @@ xfs_dir2_getdents(
}
*eofp = 0;
/*
* Decide on what work routines to call based on the inode size.
*/
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put);
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
;
} else if (v)
else if (v)
rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);
else
rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put);
@ -386,29 +340,26 @@ xfs_dir2_getdents(
/*
* Replace the inode number of a directory entry.
*/
static int /* error */
xfs_dir2_replace(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
int
xfs_dir_replace(
xfs_trans_t *tp,
xfs_inode_t *dp,
char *name, /* name of entry to replace */
int namelen, /* name length of entry to replace */
int namelen,
xfs_ino_t inum, /* new inode number */
xfs_fsblock_t *first, /* bmap's firstblock */
xfs_bmap_free_t *flist, /* bmap's freeblock list */
xfs_extlen_t total) /* bmap's total block count */
{
xfs_da_args_t args; /* operation arguments */
int rval; /* return value */
xfs_da_args_t args;
int rval;
int v; /* type-checking value */
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
return rval;
}
/*
* Fill in the arg structure for this request.
*/
args.name = name;
args.namelen = namelen;
args.hashval = xfs_da_hashname(name, namelen);
@ -420,18 +371,16 @@ xfs_dir2_replace(
args.whichfork = XFS_DATA_FORK;
args.trans = tp;
args.justcheck = args.addname = args.oknoent = 0;
/*
* Decide on what work routines to call based on the inode size.
*/
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_replace(&args);
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_block_replace(&args);
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_leaf_replace(&args);
else
rval = xfs_dir2_node_replace(&args);
@ -441,21 +390,19 @@ xfs_dir2_replace(
/*
* See if this entry can be added to the directory without allocating space.
*/
static int /* error */
xfs_dir2_canenter(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
int
xfs_dir_canenter(
xfs_trans_t *tp,
xfs_inode_t *dp,
char *name, /* name of entry to add */
int namelen) /* name length of entry to add */
int namelen)
{
xfs_da_args_t args; /* operation arguments */
int rval; /* return value */
xfs_da_args_t args;
int rval;
int v; /* type-checking value */
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
/*
* Fill in the arg structure for this request.
*/
args.name = name;
args.namelen = namelen;
args.hashval = xfs_da_hashname(name, namelen);
@ -467,37 +414,22 @@ xfs_dir2_canenter(
args.whichfork = XFS_DATA_FORK;
args.trans = tp;
args.justcheck = args.addname = args.oknoent = 1;
/*
* Decide on what work routines to call based on the inode size.
*/
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_addname(&args);
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_block_addname(&args);
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
return rval;
} else if (v)
else if (v)
rval = xfs_dir2_leaf_addname(&args);
else
rval = xfs_dir2_node_addname(&args);
return rval;
}
/*
* Dummy routine for shortform inode validation.
* Can't really do this.
*/
/* ARGSUSED */
static int /* error */
xfs_dir2_shortform_validate_ondisk(
xfs_mount_t *mp, /* filesystem mount point */
xfs_dinode_t *dip) /* ondisk inode */
{
return 0;
}
/*
* Utility routines.
*/
@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk(
* This routine is for data and free blocks, not leaf/node blocks
* which are handled by xfs_da_grow_inode.
*/
int /* error */
int
xfs_dir2_grow_inode(
xfs_da_args_t *args, /* operation arguments */
xfs_da_args_t *args,
int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
xfs_dir2_db_t *dbp) /* out: block number added */
{
xfs_fileoff_t bno; /* directory offset of new block */
int count; /* count of filesystem blocks */
xfs_inode_t *dp; /* incore directory inode */
int error; /* error return value */
int error;
int got; /* blocks actually mapped */
int i; /* temp mapping index */
int i;
xfs_bmbt_irec_t map; /* single structure for bmap */
int mapi; /* mapping index */
xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */
xfs_mount_t *mp; /* filesystem mount point */
xfs_mount_t *mp;
int nmap; /* number of bmap entries */
xfs_trans_t *tp; /* transaction pointer */
xfs_trans_t *tp;
xfs_dir2_trace_args_s("grow_inode", args, space);
dp = args->dp;
@ -538,9 +470,8 @@ xfs_dir2_grow_inode(
/*
* Find the first hole for our block.
*/
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) {
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK)))
return error;
}
nmap = 1;
ASSERT(args->firstblock != NULL);
/*
@ -549,13 +480,9 @@ xfs_dir2_grow_inode(
if ((error = xfs_bmapi(tp, dp, bno, count,
XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
args->firstblock, args->total, &map, &nmap,
args->flist))) {
args->flist, NULL)))
return error;
}
ASSERT(nmap <= 1);
/*
* Got it in 1.
*/
if (nmap == 1) {
mapp = &map;
mapi = 1;
@ -585,7 +512,8 @@ xfs_dir2_grow_inode(
if ((error = xfs_bmapi(tp, dp, b, c,
XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
args->firstblock, args->total,
&mapp[mapi], &nmap, args->flist))) {
&mapp[mapi], &nmap, args->flist,
NULL))) {
kmem_free(mapp, sizeof(*mapp) * count);
return error;
}
@ -645,20 +573,19 @@ xfs_dir2_grow_inode(
/*
* See if the directory is a single-block form directory.
*/
int /* error */
int
xfs_dir2_isblock(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
xfs_trans_t *tp,
xfs_inode_t *dp,
int *vp) /* out: 1 is block, 0 is not block */
{
xfs_fileoff_t last; /* last file offset */
xfs_mount_t *mp; /* filesystem mount point */
int rval; /* return value */
xfs_mount_t *mp;
int rval;
mp = dp->i_mount;
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) {
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
return rval;
}
rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize;
ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize);
*vp = rval;
@ -668,20 +595,19 @@ xfs_dir2_isblock(
/*
* See if the directory is a single-leaf form directory.
*/
int /* error */
int
xfs_dir2_isleaf(
xfs_trans_t *tp, /* transaction pointer */
xfs_inode_t *dp, /* incore directory inode */
xfs_trans_t *tp,
xfs_inode_t *dp,
int *vp) /* out: 1 is leaf, 0 is not leaf */
{
xfs_fileoff_t last; /* last file offset */
xfs_mount_t *mp; /* filesystem mount point */
int rval; /* return value */
xfs_mount_t *mp;
int rval;
mp = dp->i_mount;
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) {
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
return rval;
}
*vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);
return 0;
}
@ -689,9 +615,9 @@ xfs_dir2_isleaf(
/*
* Getdents put routine for 64-bit ABI, direct form.
*/
static int /* error */
static int
xfs_dir2_put_dirent64_direct(
xfs_dir2_put_args_t *pa) /* argument bundle */
xfs_dir2_put_args_t *pa)
{
xfs_dirent_t *idbp; /* dirent pointer */
iovec_t *iovp; /* io vector */
@ -726,9 +652,9 @@ xfs_dir2_put_dirent64_direct(
/*
* Getdents put routine for 64-bit ABI, uio form.
*/
static int /* error */
static int
xfs_dir2_put_dirent64_uio(
xfs_dir2_put_args_t *pa) /* argument bundle */
xfs_dir2_put_args_t *pa)
{
xfs_dirent_t *idbp; /* dirent pointer */
int namelen; /* entry name length */
@ -764,17 +690,17 @@ xfs_dir2_put_dirent64_uio(
*/
int
xfs_dir2_shrink_inode(
xfs_da_args_t *args, /* operation arguments */
xfs_dir2_db_t db, /* directory block number */
xfs_dabuf_t *bp) /* block's buffer */
xfs_da_args_t *args,
xfs_dir2_db_t db,
xfs_dabuf_t *bp)
{
xfs_fileoff_t bno; /* directory file offset */
xfs_dablk_t da; /* directory file offset */
int done; /* bunmap is finished */
xfs_inode_t *dp; /* incore directory inode */
int error; /* error return value */
xfs_mount_t *mp; /* filesystem mount point */
xfs_trans_t *tp; /* transaction pointer */
xfs_inode_t *dp;
int error;
xfs_mount_t *mp;
xfs_trans_t *tp;
xfs_dir2_trace_args_db("shrink_inode", args, db, bp);
dp = args->dp;
@ -786,7 +712,7 @@ xfs_dir2_shrink_inode(
*/
if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
&done))) {
NULL, &done))) {
/*
* ENOSPC actually can happen if we're in a removename with
* no space reservation, and the resulting block removal

Просмотреть файл

@ -22,7 +22,9 @@ struct uio;
struct xfs_dabuf;
struct xfs_da_args;
struct xfs_dir2_put_args;
struct xfs_bmap_free;
struct xfs_inode;
struct xfs_mount;
struct xfs_trans;
/*
@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args {
} xfs_dir2_put_args_t;
/*
* Other interfaces used by the rest of the dir v2 code.
* Generic directory interface routines
*/
extern void xfs_dir_startup(void);
extern void xfs_dir_mount(struct xfs_mount *mp);
extern int xfs_dir_isempty(struct xfs_inode *dp);
extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
struct xfs_inode *pdp);
extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
char *name, int namelen, xfs_ino_t inum,
xfs_fsblock_t *first,
struct xfs_bmap_free *flist, xfs_extlen_t tot);
extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
char *name, int namelen, xfs_ino_t *inum);
extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
char *name, int namelen, xfs_ino_t ino,
xfs_fsblock_t *first,
struct xfs_bmap_free *flist, xfs_extlen_t tot);
extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
uio_t *uio, int *eofp);
extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
char *name, int namelen, xfs_ino_t inum,
xfs_fsblock_t *first,
struct xfs_bmap_free *flist, xfs_extlen_t tot);
extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
char *name, int namelen);
extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
/*
* Utility routines for v2 directories.
*/
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
xfs_dir2_db_t *dbp);

Просмотреть файл

@ -22,19 +22,16 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,
int *entno);
static int xfs_dir2_block_sort(const void *a, const void *b);
static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
/*
* One-time startup routine called from xfs_init().
*/
void
xfs_dir_startup(void)
{
xfs_dir_hash_dot = xfs_da_hashname(".", 1);
xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
}
/*
* Add an entry to a block directory.
*/
@ -400,7 +409,7 @@ xfs_dir2_block_addname(
/*
* Create the new data entry.
*/
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, args->namelen);
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@ -508,7 +517,7 @@ xfs_dir2_block_getdents(
p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
ptr - (char *)block);
p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
p.ino = be64_to_cpu(dep->inumber);
#if XFS_BIG_INUMS
p.ino += mp->m_inoadd;
#endif
@ -626,7 +635,7 @@ xfs_dir2_block_lookup(
/*
* Fill in inode number, release the block.
*/
args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
args->inumber = be64_to_cpu(dep->inumber);
xfs_da_brelse(args->trans, bp);
return XFS_ERROR(EEXIST);
}
@ -844,11 +853,11 @@ xfs_dir2_block_replace(
*/
dep = (xfs_dir2_data_entry_t *)
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber);
ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
/*
* Change the inode number to the new value.
*/
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
dep->inumber = cpu_to_be64(args->inumber);
xfs_dir2_data_log_entry(args->trans, bp, dep);
xfs_dir2_data_check(dp, bp);
xfs_da_buf_done(bp);
@ -1130,7 +1139,7 @@ xfs_dir2_sf_to_block(
*/
dep = (xfs_dir2_data_entry_t *)
((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino);
dep->inumber = cpu_to_be64(dp->i_ino);
dep->namelen = 1;
dep->name[0] = '.';
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@ -1144,7 +1153,7 @@ xfs_dir2_sf_to_block(
*/
dep = (xfs_dir2_data_entry_t *)
((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
dep->namelen = 2;
dep->name[0] = dep->name[1] = '.';
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@ -1193,7 +1202,7 @@ xfs_dir2_sf_to_block(
* Copy a real entry.
*/
dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp,
dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp,
XFS_DIR2_SF_INUMBERP(sfep)));
dep->namelen = sfep->namelen;
memcpy(dep->name, sfep->name, dep->namelen);

Просмотреть файл

@ -22,18 +22,15 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
@ -133,7 +130,7 @@ xfs_dir2_data_check(
*/
dep = (xfs_dir2_data_entry_t *)p;
ASSERT(dep->namelen != 0);
ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0);
ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0);
ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) ==
(char *)dep - (char *)d);
count++;

Просмотреть файл

@ -85,11 +85,11 @@ typedef struct xfs_dir2_data_hdr {
* Tag appears as the last 2 bytes.
*/
typedef struct xfs_dir2_data_entry {
xfs_ino_t inumber; /* inode number */
__uint8_t namelen; /* name length */
__uint8_t name[1]; /* name bytes, no null */
__be64 inumber; /* inode number */
__u8 namelen; /* name length */
__u8 name[1]; /* name bytes, no null */
/* variable offset */
xfs_dir2_data_off_t tag; /* starting offset of us */
__be16 tag; /* starting offset of us */
} xfs_dir2_data_entry_t;
/*

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
@ -407,7 +405,7 @@ xfs_dir2_leaf_addname(
* Initialize our new entry (at last).
*/
dep = (xfs_dir2_data_entry_t *)dup;
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, dep->namelen);
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@ -884,7 +882,7 @@ xfs_dir2_leaf_getdents(
XFS_DIR2_BYTE_TO_DA(mp,
XFS_DIR2_LEAF_OFFSET) - map_off,
XFS_BMAPI_METADATA, NULL, 0,
&map[map_valid], &nmap, NULL);
&map[map_valid], &nmap, NULL, NULL);
/*
* Don't know if we should ignore this or
* try to return an error.
@ -1098,7 +1096,7 @@ xfs_dir2_leaf_getdents(
p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
p->ino = INT_GET(dep->inumber, ARCH_CONVERT);
p->ino = be64_to_cpu(dep->inumber);
#if XFS_BIG_INUMS
p->ino += mp->m_inoadd;
#endif
@ -1319,7 +1317,7 @@ xfs_dir2_leaf_lookup(
/*
* Return the found inode number.
*/
args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
args->inumber = be64_to_cpu(dep->inumber);
xfs_da_brelse(tp, dbp);
xfs_da_brelse(tp, lbp);
return XFS_ERROR(EEXIST);
@ -1606,11 +1604,11 @@ xfs_dir2_leaf_replace(
dep = (xfs_dir2_data_entry_t *)
((char *)dbp->data +
XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT));
ASSERT(args->inumber != be64_to_cpu(dep->inumber));
/*
* Put the new inode number in, log it.
*/
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
dep->inumber = cpu_to_be64(args->inumber);
tp = args->trans;
xfs_dir2_data_log_entry(tp, dbp, dep);
xfs_da_buf_done(dbp);

Просмотреть файл

@ -22,13 +22,11 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -505,7 +503,6 @@ xfs_dir2_leafn_lookup_int(
XFS_DATA_FORK))) {
return error;
}
curfdb = newfdb;
free = curbp->data;
ASSERT(be32_to_cpu(free->hdr.magic) ==
XFS_DIR2_FREE_MAGIC);
@ -527,8 +524,11 @@ xfs_dir2_leafn_lookup_int(
if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) {
XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
XFS_ERRLEVEL_LOW, mp);
if (curfdb != newfdb)
xfs_da_brelse(tp, curbp);
return XFS_ERROR(EFSCORRUPTED);
}
curfdb = newfdb;
if (be16_to_cpu(free->bests[fi]) >= length) {
*indexp = index;
state->extravalid = 1;
@ -580,7 +580,7 @@ xfs_dir2_leafn_lookup_int(
if (dep->namelen == args->namelen &&
dep->name[0] == args->name[0] &&
memcmp(dep->name, args->name, args->namelen) == 0) {
args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
args->inumber = be64_to_cpu(dep->inumber);
*indexp = index;
state->extravalid = 1;
state->extrablk.bp = curbp;
@ -970,7 +970,7 @@ xfs_dir2_leafn_remove(
/*
* One less used entry in the free table.
*/
free->hdr.nused = cpu_to_be32(-1);
be32_add(&free->hdr.nused, -1);
xfs_dir2_free_log_header(tp, fbp);
/*
* If this was the last entry in the table, we can
@ -1695,7 +1695,7 @@ xfs_dir2_node_addname_int(
* Fill in the new entry and log it.
*/
dep = (xfs_dir2_data_entry_t *)dup;
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen;
memcpy(dep->name, args->name, dep->namelen);
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@ -1905,11 +1905,11 @@ xfs_dir2_node_replace(
dep = (xfs_dir2_data_entry_t *)
((char *)data +
XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address)));
ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT));
ASSERT(inum != be64_to_cpu(dep->inumber));
/*
* Fill in the new inode number and log the entry.
*/
INT_SET(dep->inumber, ARCH_CONVERT, inum);
dep->inumber = cpu_to_be64(inum);
xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
rval = 0;
}

Просмотреть файл

@ -22,19 +22,16 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_dir_leaf.h"
#include "xfs_error.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
@ -117,13 +114,13 @@ xfs_dir2_block_sfsize(
dep->name[0] == '.' && dep->name[1] == '.';
#if XFS_BIG_INUMS
if (!isdot)
i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM;
i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM;
#endif
if (!isdot && !isdotdot) {
count++;
namelen += dep->namelen;
} else if (isdotdot)
parent = INT_GET(dep->inumber, ARCH_CONVERT);
parent = be64_to_cpu(dep->inumber);
/*
* Calculate the new size, see if we should give up yet.
*/
@ -229,13 +226,13 @@ xfs_dir2_block_to_sf(
* Skip .
*/
if (dep->namelen == 1 && dep->name[0] == '.')
ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino);
ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino);
/*
* Skip .., but make sure the inode number is right.
*/
else if (dep->namelen == 2 &&
dep->name[0] == '.' && dep->name[1] == '.')
ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) ==
ASSERT(be64_to_cpu(dep->inumber) ==
XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
/*
* Normal entry, copy it into shortform.
@ -246,7 +243,7 @@ xfs_dir2_block_to_sf(
(xfs_dir2_data_aoff_t)
((char *)dep - (char *)block));
memcpy(sfep->name, dep->name, dep->namelen);
temp=INT_GET(dep->inumber, ARCH_CONVERT);
temp = be64_to_cpu(dep->inumber);
XFS_DIR2_SF_PUT_INUMBER(sfp, &temp,
XFS_DIR2_SF_INUMBERP(sfep));
sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);

Просмотреть файл

@ -19,11 +19,9 @@
#include "xfs_fs.h"
#include "xfs_types.h"
#include "xfs_inum.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,231 +0,0 @@
/*
* Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
* All Rights Reserved.
*
* 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.
*
* 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. 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 the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR_LEAF_H__
#define __XFS_DIR_LEAF_H__
/*
* Directory layout, internal structure, access macros, etc.
*
* Large directories are structured around Btrees where all the data
* elements are in the leaf nodes. Filenames are hashed into an int,
* then that int is used as the index into the Btree. Since the hashval
* of a filename may not be unique, we may have duplicate keys. The
* internal links in the Btree are logical block offsets into the file.
*/
struct uio;
struct xfs_bmap_free;
struct xfs_dabuf;
struct xfs_da_args;
struct xfs_da_state;
struct xfs_da_state_blk;
struct xfs_dir_put_args;
struct xfs_inode;
struct xfs_mount;
struct xfs_trans;
/*========================================================================
* Directory Structure when equal to XFS_LBSIZE(mp) bytes.
*========================================================================*/
/*
* This is the structure of the leaf nodes in the Btree.
*
* Struct leaf_entry's are packed from the top. Names grow from the bottom
* but are not packed. The freemap contains run-length-encoded entries
* for the free bytes after the leaf_entry's, but only the N largest such,
* smaller runs are dropped. When the freemap doesn't show enough space
* for an allocation, we compact the namelist area and try again. If we
* still don't have enough space, then we have to split the block.
*
* Since we have duplicate hash keys, for each key that matches, compare
* the actual string. The root and intermediate node search always takes
* the first-in-the-block key match found, so we should only have to work
* "forw"ard. If none matches, continue with the "forw"ard leaf nodes
* until the hash key changes or the filename is found.
*
* The parent directory and the self-pointer are explicitly represented
* (ie: there are entries for "." and "..").
*
* Note that the count being a __uint16_t limits us to something like a
* blocksize of 1.3MB in the face of worst case (short) filenames.
*/
#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */
typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */
__uint16_t base; /* base of free region */
__uint16_t size; /* run length of free region */
} xfs_dir_leaf_map_t;
typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */
xfs_da_blkinfo_t info; /* block type, links, etc. */
__uint16_t count; /* count of active leaf_entry's */
__uint16_t namebytes; /* num bytes of name strings stored */
__uint16_t firstused; /* first used byte in name area */
__uint8_t holes; /* != 0 if blk needs compaction */
__uint8_t pad1;
xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];
} xfs_dir_leaf_hdr_t;
typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */
xfs_dahash_t hashval; /* hash value of name */
__uint16_t nameidx; /* index into buffer of name */
__uint8_t namelen; /* length of name string */
__uint8_t pad2;
} xfs_dir_leaf_entry_t;
typedef struct xfs_dir_leaf_name {
xfs_dir_ino_t inumber; /* inode number for this key */
__uint8_t name[1]; /* name string itself */
} xfs_dir_leaf_name_t;
typedef struct xfs_dir_leafblock {
xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */
xfs_dir_leaf_entry_t entries[1]; /* var sized array */
xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */
} xfs_dir_leafblock_t;
/*
* Length of name for which a 512-byte block filesystem
* can get a double split.
*/
#define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \
(512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \
(uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \
(uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1)
typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa);
typedef union {
xfs_off_t o; /* offset (cookie) */
/*
* Watch the order here (endian-ness dependent).
*/
struct {
#ifndef XFS_NATIVE_HOST
xfs_dahash_t h; /* hash value */
__uint32_t be; /* block and entry */
#else
__uint32_t be; /* block and entry */
xfs_dahash_t h; /* hash value */
#endif /* XFS_NATIVE_HOST */
} s;
} xfs_dircook_t;
#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \
((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))
typedef struct xfs_dir_put_args {
xfs_dircook_t cook; /* cookie of (next) entry */
xfs_intino_t ino; /* inode number */
struct xfs_dirent *dbp; /* buffer pointer */
char *name; /* directory entry name */
int namelen; /* length of name */
int done; /* output: set if value was stored */
xfs_dir_put_t put; /* put function ptr (i/o) */
struct uio *uio; /* uio control structure */
} xfs_dir_put_args_t;
#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \
xfs_dir_leaf_entsize_byname(len)
static inline int xfs_dir_leaf_entsize_byname(int len)
{
return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
}
#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \
xfs_dir_leaf_entsize_byentry(entry)
static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
{
return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen;
}
#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \
xfs_dir_leaf_namestruct(leafp,offset)
static inline xfs_dir_leaf_name_t *
xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
{
return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset];
}
/*========================================================================
* Function prototypes for the kernel.
*========================================================================*/
/*
* Internal routines when dirsize < XFS_LITINO(mp).
*/
int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent);
int xfs_dir_shortform_addname(struct xfs_da_args *args);
int xfs_dir_shortform_lookup(struct xfs_da_args *args);
int xfs_dir_shortform_to_leaf(struct xfs_da_args *args);
int xfs_dir_shortform_removename(struct xfs_da_args *args);
int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
struct xfs_dirent *dbp, xfs_dir_put_t put);
int xfs_dir_shortform_replace(struct xfs_da_args *args);
/*
* Internal routines when dirsize == XFS_LBSIZE(mp).
*/
int xfs_dir_leaf_to_node(struct xfs_da_args *args);
int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
/*
* Routines used for growing the Btree.
*/
int xfs_dir_leaf_split(struct xfs_da_state *state,
struct xfs_da_state_blk *oldblk,
struct xfs_da_state_blk *newblk);
int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer,
struct xfs_da_args *args, int insertion_index);
int xfs_dir_leaf_addname(struct xfs_da_args *args);
int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer,
struct xfs_da_args *args,
int *index_found_at);
int xfs_dir_leaf_remove(struct xfs_trans *trans,
struct xfs_dabuf *leaf_buffer,
int index_to_remove);
int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp,
xfs_dablk_t bno, struct uio *uio,
int *eobp, struct xfs_dirent *dbp,
xfs_dir_put_t put, xfs_daddr_t nextda);
/*
* Routines used for shrinking the Btree.
*/
int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval);
void xfs_dir_leaf_unbalance(struct xfs_da_state *state,
struct xfs_da_state_blk *drop_blk,
struct xfs_da_state_blk *save_blk);
/*
* Utility routines.
*/
uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count);
int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp,
struct xfs_dabuf *leaf2_bp);
int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa);
int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa);
int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
/*
* Global data.
*/
extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
#endif /* __XFS_DIR_LEAF_H__ */

Просмотреть файл

@ -1,155 +0,0 @@
/*
* Copyright (c) 2000,2005 Silicon Graphics, Inc.
* All Rights Reserved.
*
* 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.
*
* 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. 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 the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __XFS_DIR_SF_H__
#define __XFS_DIR_SF_H__
/*
* Directory layout when stored internal to an inode.
*
* Small directories are packed as tightly as possible so as to
* fit into the literal area of the inode.
*/
typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t;
/*
* The parent directory has a dedicated field, and the self-pointer must
* be calculated on the fly.
*
* Entries are packed toward the top as tight as possible. The header
* and the elements much be memcpy'd out into a work area to get correct
* alignment for the inode number fields.
*/
typedef struct xfs_dir_sf_hdr { /* constant-structure header block */
xfs_dir_ino_t parent; /* parent dir inode number */
__uint8_t count; /* count of active entries */
} xfs_dir_sf_hdr_t;
typedef struct xfs_dir_sf_entry {
xfs_dir_ino_t inumber; /* referenced inode number */
__uint8_t namelen; /* actual length of name (no NULL) */
__uint8_t name[1]; /* name */
} xfs_dir_sf_entry_t;
typedef struct xfs_dir_shortform {
xfs_dir_sf_hdr_t hdr;
xfs_dir_sf_entry_t list[1]; /* variable sized array */
} xfs_dir_shortform_t;
/*
* We generate this then sort it, so that readdirs are returned in
* hash-order. Else seekdir won't work.
*/
typedef struct xfs_dir_sf_sort {
__uint8_t entno; /* .=0, ..=1, else entry# + 2 */
__uint8_t seqno; /* sequence # with same hash value */
__uint8_t namelen; /* length of name value (no null) */
xfs_dahash_t hash; /* this entry's hash value */
xfs_intino_t ino; /* this entry's inode number */
char *name; /* name value, pointer into buffer */
} xfs_dir_sf_sort_t;
#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
{
*(to) = XFS_GET_DIR_INO8(*from);
}
#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
{
XFS_PUT_DIR_INO8(*(from), *(to));
}
#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
static inline int xfs_dir_sf_entsize_byname(int len)
{
return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len);
}
#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep)
static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
{
return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen;
}
#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep)
static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
{
return (xfs_dir_sf_entry_t *) \
((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep));
}
#define XFS_DIR_SF_ALLFIT(count,totallen) \
xfs_dir_sf_allfit(count,totallen)
static inline int xfs_dir_sf_allfit(int count, int totallen)
{
return ((uint)sizeof(xfs_dir_sf_hdr_t) + \
((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen));
}
#if defined(XFS_DIR_TRACE)
/*
* Kernel tracing support for directories.
*/
struct uio;
struct xfs_inode;
struct xfs_da_intnode;
struct xfs_dinode;
struct xfs_dir_leafblock;
struct xfs_dir_leaf_entry;
#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */
extern ktrace_t *xfs_dir_trace_buf;
/*
* Trace record types.
*/
#define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */
#define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */
#define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */
#define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */
#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */
#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */
void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio);
void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio,
xfs_dablk_t bno);
void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio,
struct xfs_da_intnode *node);
void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio,
struct xfs_dir_leafblock *leaf);
void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio,
struct xfs_dir_leaf_entry *entry);
void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio,
xfs_off_t cookie);
void xfs_dir_trace_enter(int type, char *where,
void *a0, void *a1, void *a2, void *a3,
void *a4, void *a5, void *a6, void *a7,
void *a8, void *a9, void *a10, void *a11);
#else
#define xfs_dir_trace_g_du(w,d,u)
#define xfs_dir_trace_g_dub(w,d,u,b)
#define xfs_dir_trace_g_dun(w,d,u,n)
#define xfs_dir_trace_g_dul(w,d,u,l)
#define xfs_dir_trace_g_due(w,d,u,e)
#define xfs_dir_trace_g_duc(w,d,u,c)
#endif /* DEBUG */
#endif /* __XFS_DIR_SF_H__ */

Просмотреть файл

@ -189,6 +189,6 @@ typedef enum {
#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
extern struct bhv_vfsops xfs_dmops;
extern struct bhv_module_vfsops xfs_dmops;
#endif /* __XFS_DMAPI_H__ */

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"

Просмотреть файл

@ -22,12 +22,10 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_buf_item.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
@ -293,6 +292,62 @@ xfs_efi_init(xfs_mount_t *mp,
return (efip);
}
/*
* Copy an EFI format buffer from the given buf, and into the destination
* EFI format structure.
* The given buffer can be in 32 bit or 64 bit form (which has different padding),
* one of which will be the native format for this kernel.
* It will handle the conversion of formats if necessary.
*/
int
xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
{
xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
uint i;
uint len = sizeof(xfs_efi_log_format_t) +
(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
uint len32 = sizeof(xfs_efi_log_format_32_t) +
(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);
uint len64 = sizeof(xfs_efi_log_format_64_t) +
(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);
if (buf->i_len == len) {
memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
return 0;
} else if (buf->i_len == len32) {
xfs_efi_log_format_32_t *src_efi_fmt_32 =
(xfs_efi_log_format_32_t *)buf->i_addr;
dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
dst_efi_fmt->efi_extents[i].ext_start =
src_efi_fmt_32->efi_extents[i].ext_start;
dst_efi_fmt->efi_extents[i].ext_len =
src_efi_fmt_32->efi_extents[i].ext_len;
}
return 0;
} else if (buf->i_len == len64) {
xfs_efi_log_format_64_t *src_efi_fmt_64 =
(xfs_efi_log_format_64_t *)buf->i_addr;
dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
dst_efi_fmt->efi_extents[i].ext_start =
src_efi_fmt_64->efi_extents[i].ext_start;
dst_efi_fmt->efi_extents[i].ext_len =
src_efi_fmt_64->efi_extents[i].ext_len;
}
return 0;
}
return EFSCORRUPTED;
}
/*
* This is called by the efd item code below to release references to
* the given efi item. Each efd calls this with the number of

Просмотреть файл

@ -26,6 +26,24 @@ typedef struct xfs_extent {
xfs_extlen_t ext_len;
} xfs_extent_t;
/*
* Since an xfs_extent_t has types (start:64, len: 32)
* there are different alignments on 32 bit and 64 bit kernels.
* So we provide the different variants for use by a
* conversion routine.
*/
typedef struct xfs_extent_32 {
xfs_dfsbno_t ext_start;
xfs_extlen_t ext_len;
} __attribute__((packed)) xfs_extent_32_t;
typedef struct xfs_extent_64 {
xfs_dfsbno_t ext_start;
xfs_extlen_t ext_len;
__uint32_t ext_pad;
} xfs_extent_64_t;
/*
* This is the structure used to lay out an efi log item in the
* log. The efi_extents field is a variable size array whose
@ -39,6 +57,22 @@ typedef struct xfs_efi_log_format {
xfs_extent_t efi_extents[1]; /* array of extents to free */
} xfs_efi_log_format_t;
typedef struct xfs_efi_log_format_32 {
unsigned short efi_type; /* efi log item type */
unsigned short efi_size; /* size of this item */
uint efi_nextents; /* # extents to free */
__uint64_t efi_id; /* efi identifier */
xfs_extent_32_t efi_extents[1]; /* array of extents to free */
} __attribute__((packed)) xfs_efi_log_format_32_t;
typedef struct xfs_efi_log_format_64 {
unsigned short efi_type; /* efi log item type */
unsigned short efi_size; /* size of this item */
uint efi_nextents; /* # extents to free */
__uint64_t efi_id; /* efi identifier */
xfs_extent_64_t efi_extents[1]; /* array of extents to free */
} xfs_efi_log_format_64_t;
/*
* This is the structure used to lay out an efd log item in the
* log. The efd_extents array is a variable size array whose
@ -52,6 +86,22 @@ typedef struct xfs_efd_log_format {
xfs_extent_t efd_extents[1]; /* array of extents freed */
} xfs_efd_log_format_t;
typedef struct xfs_efd_log_format_32 {
unsigned short efd_type; /* efd log item type */
unsigned short efd_size; /* size of this item */
uint efd_nextents; /* # of extents freed */
__uint64_t efd_efi_id; /* id of corresponding efi */
xfs_extent_32_t efd_extents[1]; /* array of extents freed */
} __attribute__((packed)) xfs_efd_log_format_32_t;
typedef struct xfs_efd_log_format_64 {
unsigned short efd_type; /* efd log item type */
unsigned short efd_size; /* size of this item */
uint efd_nextents; /* # of extents freed */
__uint64_t efd_efi_id; /* id of corresponding efi */
xfs_extent_64_t efd_extents[1]; /* array of extents freed */
} xfs_efd_log_format_64_t;
#ifdef __KERNEL__
@ -103,7 +153,8 @@ extern struct kmem_zone *xfs_efd_zone;
xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
uint);
int xfs_efi_copy_format(xfs_log_iovec_t *buf,
xfs_efi_log_format_t *dst_efi_fmt);
void xfs_efi_item_free(xfs_efi_log_item_t *);
#endif /* __KERNEL__ */

Просмотреть файл

@ -67,14 +67,15 @@ struct fsxattr {
#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
/*
* Structure for XFS_IOC_GETBMAP.
* On input, fill in bmv_offset and bmv_length of the first structure
* to indicate the area of interest in the file, and bmv_entry with the
* number of array elements given. The first structure is updated on
* return to give the offset and length for the next call.
* to indicate the area of interest in the file, and bmv_entries with
* the number of array elements given back. The first structure is
* updated on return to give the offset and length for the next call.
*/
#ifndef HAVE_GETBMAP
struct getbmap {

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -542,14 +540,13 @@ xfs_reserve_blocks(
}
void
xfs_fs_log_dummy(xfs_mount_t *mp)
xfs_fs_log_dummy(
xfs_mount_t *mp)
{
xfs_trans_t *tp;
xfs_inode_t *ip;
xfs_trans_t *tp;
xfs_inode_t *ip;
tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
atomic_inc(&mp->m_active_trans);
if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
xfs_trans_cancel(tp, 0);
return;
@ -574,21 +571,22 @@ xfs_fs_goingdown(
{
switch (inflags) {
case XFS_FSOP_GOING_FLAGS_DEFAULT: {
struct vfs *vfsp = XFS_MTOVFS(mp);
struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
if (sb && !IS_ERR(sb)) {
xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
thaw_bdev(sb->s_bdev, sb);
}
break;
}
case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
break;
case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR);
xfs_force_shutdown(mp,
SHUTDOWN_FORCE_UMOUNT | SHUTDOWN_LOG_IO_ERROR);
break;
default:
return XFS_ERROR(EINVAL);

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -1174,6 +1172,9 @@ xfs_dilocate(
if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
#ifdef DEBUG
/* no diagnostics for bulkstat, ino comes from userspace */
if (flags & XFS_IMAP_BULKSTAT)
return XFS_ERROR(EINVAL);
if (agno >= mp->m_sb.sb_agcount) {
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_dilocate: agno (%d) >= "

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -186,7 +184,7 @@ xfs_ihash_promote(
*/
STATIC int
xfs_iget_core(
vnode_t *vp,
bhv_vnode_t *vp,
xfs_mount_t *mp,
xfs_trans_t *tp,
xfs_ino_t ino,
@ -198,7 +196,7 @@ xfs_iget_core(
xfs_ihash_t *ih;
xfs_inode_t *ip;
xfs_inode_t *iq;
vnode_t *inode_vp;
bhv_vnode_t *inode_vp;
ulong version;
int error;
/* REFERENCED */
@ -468,7 +466,7 @@ finish_inode:
* If we have a real type for an on-disk inode, we can set ops(&unlock)
* now. If it's a new inode being created, xfs_ialloc will handle it.
*/
VFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
return 0;
}
@ -489,7 +487,7 @@ xfs_iget(
xfs_daddr_t bno)
{
struct inode *inode;
vnode_t *vp = NULL;
bhv_vnode_t *vp = NULL;
int error;
XFS_STATS_INC(xs_ig_attempts);
@ -543,7 +541,7 @@ retry:
void
xfs_inode_lock_init(
xfs_inode_t *ip,
vnode_t *vp)
bhv_vnode_t *vp)
{
mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
"xfsino", (long)vp->v_number);
@ -603,12 +601,10 @@ void
xfs_iput(xfs_inode_t *ip,
uint lock_flags)
{
vnode_t *vp = XFS_ITOV(ip);
bhv_vnode_t *vp = XFS_ITOV(ip);
vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
xfs_iunlock(ip, lock_flags);
VN_RELE(vp);
}
@ -619,7 +615,7 @@ void
xfs_iput_new(xfs_inode_t *ip,
uint lock_flags)
{
vnode_t *vp = XFS_ITOV(ip);
bhv_vnode_t *vp = XFS_ITOV(ip);
struct inode *inode = vn_to_inode(vp);
vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
@ -645,7 +641,7 @@ xfs_iput_new(xfs_inode_t *ip,
void
xfs_ireclaim(xfs_inode_t *ip)
{
vnode_t *vp;
bhv_vnode_t *vp;
/*
* Remove from old hash list and mount list.
@ -1033,6 +1029,6 @@ xfs_iflock_nowait(xfs_inode_t *ip)
void
xfs_ifunlock(xfs_inode_t *ip)
{
ASSERT(valusema(&(ip->i_flock)) <= 0);
ASSERT(issemalocked(&(ip->i_flock)));
vsema(&(ip->i_flock));
}

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -26,14 +26,12 @@
#include "xfs_trans_priv.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -256,13 +254,11 @@ xfs_itobp(
xfs_daddr_t bno,
uint imap_flags)
{
xfs_imap_t imap;
xfs_buf_t *bp;
int error;
xfs_imap_t imap;
#ifdef __KERNEL__
int i;
int ni;
#endif
if (ip->i_blkno == (xfs_daddr_t)0) {
/*
@ -319,7 +315,6 @@ xfs_itobp(
*/
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
(int)imap.im_len, XFS_BUF_LOCK, &bp);
if (error) {
#ifdef DEBUG
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
@ -330,17 +325,21 @@ xfs_itobp(
#endif /* DEBUG */
return error;
}
#ifdef __KERNEL__
/*
* Validate the magic number and version of every inode in the buffer
* (if DEBUG kernel) or the first inode in the buffer, otherwise.
* No validation is done here in userspace (xfs_repair).
*/
#ifdef DEBUG
#if !defined(__KERNEL__)
ni = 0;
#elif defined(DEBUG)
ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
(BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
#else
#else /* usual case */
ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
#endif
for (i = 0; i < ni; i++) {
int di_ok;
xfs_dinode_t *dip;
@ -352,8 +351,11 @@ xfs_itobp(
if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
#ifdef DEBUG
prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)",
mp->m_ddev_targp,
if (!(imap_flags & XFS_IMAP_BULKSTAT))
cmn_err(CE_ALERT,
"Device %s - bad inode magic/vsn "
"daddr %lld #%d (magic=%x)",
XFS_BUFTARG_NAME(mp->m_ddev_targp),
(unsigned long long)imap.im_blkno, i,
INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
#endif
@ -363,7 +365,6 @@ xfs_itobp(
return XFS_ERROR(EFSCORRUPTED);
}
}
#endif /* __KERNEL__ */
xfs_inobp_check(mp, bp);
@ -782,7 +783,6 @@ xfs_xlate_dinode_core(
STATIC uint
_xfs_dic2xflags(
xfs_dinode_core_t *dic,
__uint16_t di_flags)
{
uint flags = 0;
@ -812,6 +812,8 @@ _xfs_dic2xflags(
flags |= XFS_XFLAG_EXTSIZE;
if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
flags |= XFS_XFLAG_EXTSZINHERIT;
if (di_flags & XFS_DIFLAG_NODEFRAG)
flags |= XFS_XFLAG_NODEFRAG;
}
return flags;
@ -823,16 +825,16 @@ xfs_ip2xflags(
{
xfs_dinode_core_t *dic = &ip->i_d;
return _xfs_dic2xflags(dic, dic->di_flags) |
(XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
return _xfs_dic2xflags(dic->di_flags) |
(XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
}
uint
xfs_dic2xflags(
xfs_dinode_core_t *dic)
{
return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) |
(XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) |
(XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
}
/*
@ -1083,7 +1085,7 @@ xfs_ialloc(
{
xfs_ino_t ino;
xfs_inode_t *ip;
vnode_t *vp;
bhv_vnode_t *vp;
uint flags;
int error;
@ -1221,6 +1223,9 @@ xfs_ialloc(
di_flags |= XFS_DIFLAG_NOSYMLINKS;
if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
di_flags |= XFS_DIFLAG_PROJINHERIT;
if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
xfs_inherit_nodefrag)
di_flags |= XFS_DIFLAG_NODEFRAG;
ip->i_d.di_flags |= di_flags;
}
/* FALLTHROUGH */
@ -1244,8 +1249,8 @@ xfs_ialloc(
*/
xfs_trans_log_inode(tp, ip, flags);
/* now that we have an i_mode we can set Linux inode ops (& unlock) */
VFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
/* now that we have an i_mode we can setup inode ops and unlock */
bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
*ipp = ip;
return 0;
@ -1285,7 +1290,7 @@ xfs_isize_check(
(xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
map_first),
XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
NULL))
NULL, NULL))
return;
ASSERT(nimaps == 1);
ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
@ -1421,7 +1426,7 @@ xfs_itruncate_start(
xfs_fsize_t last_byte;
xfs_off_t toss_start;
xfs_mount_t *mp;
vnode_t *vp;
bhv_vnode_t *vp;
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
@ -1434,9 +1439,9 @@ xfs_itruncate_start(
vn_iowait(vp); /* wait for the completion of any pending DIOs */
/*
* Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers
* Call toss_pages or flushinval_pages to get rid of pages
* overlapping the region being removed. We have to use
* the less efficient VOP_FLUSHINVAL_PAGES() in the case that the
* the less efficient flushinval_pages in the case that the
* caller may not be able to finish the truncate without
* dropping the inode's I/O lock. Make sure
* to catch any pages brought in by buffers overlapping
@ -1445,10 +1450,10 @@ xfs_itruncate_start(
* so that we don't toss things on the same block as
* new_size but before it.
*
* Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to
* Before calling toss_page or flushinval_pages, make sure to
* call remapf() over the same region if the file is mapped.
* This frees up mapped file references to the pages in the
* given range and for the VOP_FLUSHINVAL_PAGES() case it ensures
* given range and for the flushinval_pages case it ensures
* that we get the latest mapped changes flushed out.
*/
toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
@ -1466,9 +1471,9 @@ xfs_itruncate_start(
last_byte);
if (last_byte > toss_start) {
if (flags & XFS_ITRUNC_DEFINITE) {
VOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
} else {
VOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
}
}
@ -1666,12 +1671,13 @@ xfs_itruncate_finish(
* runs.
*/
XFS_BMAP_INIT(&free_list, &first_block);
error = xfs_bunmapi(ntp, ip, first_unmap_block,
unmap_len,
error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
first_unmap_block, unmap_len,
XFS_BMAPI_AFLAG(fork) |
(sync ? 0 : XFS_BMAPI_ASYNC),
XFS_ITRUNC_MAX_EXTENTS,
&first_block, &free_list, &done);
&first_block, &free_list,
NULL, &done);
if (error) {
/*
* If the bunmapi call encounters an error,
@ -2745,13 +2751,14 @@ xfs_iunpin(
* the inode to become unpinned.
*/
if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
vnode_t *vp = XFS_ITOV_NULL(ip);
bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
/* make sync come back and flush this inode */
if (vp) {
struct inode *inode = vn_to_inode(vp);
if (!(inode->i_state & I_NEW))
if (!(inode->i_state &
(I_NEW|I_FREEING|I_CLEAR)))
mark_inode_dirty_sync(inode);
}
}
@ -2916,13 +2923,6 @@ xfs_iflush_fork(
ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
}
if (whichfork == XFS_DATA_FORK) {
if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
XFS_ERROR_REPORT("xfs_iflush_fork",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
}
}
break;
case XFS_DINODE_FMT_EXTENTS:
@ -3006,7 +3006,7 @@ xfs_iflush(
XFS_STATS_INC(xs_iflush_count);
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
ASSERT(valusema(&ip->i_flock) <= 0);
ASSERT(issemalocked(&(ip->i_flock)));
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
ip->i_d.di_nextents > ip->i_df.if_ext_max);
@ -3199,7 +3199,7 @@ xfs_iflush(
corrupt_out:
xfs_buf_relse(bp);
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
xfs_iflush_abort(ip);
/*
* Unlocks the flush lock
@ -3221,7 +3221,7 @@ cluster_corrupt_out:
xfs_buf_relse(bp);
}
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
if(!bufwasdelwri) {
/*
@ -3264,7 +3264,7 @@ xfs_iflush_int(
SPLDECL(s);
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
ASSERT(valusema(&ip->i_flock) <= 0);
ASSERT(issemalocked(&(ip->i_flock)));
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
ip->i_d.di_nextents > ip->i_df.if_ext_max);
@ -3504,7 +3504,7 @@ xfs_iflush_all(
xfs_mount_t *mp)
{
xfs_inode_t *ip;
vnode_t *vp;
bhv_vnode_t *vp;
again:
XFS_MOUNT_ILOCK(mp);
@ -4180,7 +4180,7 @@ xfs_iext_direct_to_inline(
*/
memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
nextents * sizeof(xfs_bmbt_rec_t));
kmem_free(ifp->if_u1.if_extents, KM_SLEEP);
kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
ifp->if_real_bytes = 0;
}

Просмотреть файл

@ -102,9 +102,9 @@ typedef struct xfs_ifork {
#ifdef __KERNEL__
struct bhv_desc;
struct bhv_vnode;
struct cred;
struct ktrace;
struct vnode;
struct xfs_buf;
struct xfs_bmap_free;
struct xfs_bmbt_irec;
@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *);
void xfs_chash_free(struct xfs_mount *);
xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
struct xfs_trans *);
void xfs_inode_lock_init(xfs_inode_t *, struct vnode *);
void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *);
int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
uint, uint, xfs_inode_t **, xfs_daddr_t);
void xfs_iput(xfs_inode_t *, uint);
@ -461,7 +461,7 @@ void xfs_ichgtime(xfs_inode_t *, int);
xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
xfs_inode_t *xfs_vtoi(struct vnode *vp);
xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp);
void xfs_synchronize_atime(xfs_inode_t *);
@ -509,7 +509,6 @@ extern struct kmem_zone *xfs_chashlist_zone;
extern struct kmem_zone *xfs_ifork_zone;
extern struct kmem_zone *xfs_inode_zone;
extern struct kmem_zone *xfs_ili_zone;
extern struct vnodeops xfs_vnodeops;
#endif /* __KERNEL__ */

Просмотреть файл

@ -25,7 +25,6 @@
#include "xfs_buf_item.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@ -33,7 +32,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -794,7 +792,7 @@ xfs_inode_item_pushbuf(
* inode flush completed and the inode was taken off the AIL.
* So, just get out.
*/
if ((valusema(&(ip->i_flock)) > 0) ||
if (!issemalocked(&(ip->i_flock)) ||
((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
iip->ili_pushbuf_flag = 0;
xfs_iunlock(ip, XFS_ILOCK_SHARED);
@ -816,7 +814,7 @@ xfs_inode_item_pushbuf(
* If not, we can flush it async.
*/
dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
(valusema(&(ip->i_flock)) <= 0));
issemalocked(&(ip->i_flock)));
iip->ili_pushbuf_flag = 0;
xfs_iunlock(ip, XFS_ILOCK_SHARED);
xfs_buftrace("INODE ITEM PUSH", bp);
@ -864,7 +862,7 @@ xfs_inode_item_push(
ip = iip->ili_inode;
ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS));
ASSERT(valusema(&(ip->i_flock)) <= 0);
ASSERT(issemalocked(&(ip->i_flock)));
/*
* Since we were able to lock the inode's flush lock and
* we found it on the AIL, the inode must be dirty. This
@ -1084,3 +1082,52 @@ xfs_istale_done(
{
xfs_iflush_abort(iip->ili_inode);
}
/*
* convert an xfs_inode_log_format struct from either 32 or 64 bit versions
* (which can have different field alignments) to the native version
*/
int
xfs_inode_item_format_convert(
xfs_log_iovec_t *buf,
xfs_inode_log_format_t *in_f)
{
if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
xfs_inode_log_format_32_t *in_f32;
in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr;
in_f->ilf_type = in_f32->ilf_type;
in_f->ilf_size = in_f32->ilf_size;
in_f->ilf_fields = in_f32->ilf_fields;
in_f->ilf_asize = in_f32->ilf_asize;
in_f->ilf_dsize = in_f32->ilf_dsize;
in_f->ilf_ino = in_f32->ilf_ino;
/* copy biggest field of ilf_u */
memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
in_f32->ilf_u.ilfu_uuid.__u_bits,
sizeof(uuid_t));
in_f->ilf_blkno = in_f32->ilf_blkno;
in_f->ilf_len = in_f32->ilf_len;
in_f->ilf_boffset = in_f32->ilf_boffset;
return 0;
} else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
xfs_inode_log_format_64_t *in_f64;
in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr;
in_f->ilf_type = in_f64->ilf_type;
in_f->ilf_size = in_f64->ilf_size;
in_f->ilf_fields = in_f64->ilf_fields;
in_f->ilf_asize = in_f64->ilf_asize;
in_f->ilf_dsize = in_f64->ilf_dsize;
in_f->ilf_ino = in_f64->ilf_ino;
/* copy biggest field of ilf_u */
memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
in_f64->ilf_u.ilfu_uuid.__u_bits,
sizeof(uuid_t));
in_f->ilf_blkno = in_f64->ilf_blkno;
in_f->ilf_len = in_f64->ilf_len;
in_f->ilf_boffset = in_f64->ilf_boffset;
return 0;
}
return EFSCORRUPTED;
}

Просмотреть файл

@ -23,25 +23,6 @@
* log. The size of the inline data/extents/b-tree root to be logged
* (if any) is indicated in the ilf_dsize field. Changes to this structure
* must be added on to the end.
*
* Convention for naming inode log item versions : The current version
* is always named XFS_LI_INODE. When an inode log item gets superseded,
* add the latest version of IRIX that will generate logs with that item
* to the version name.
*
* -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first
* union (ilf_u) field. This was released with IRIX 5.3-XFS.
* -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire
* structure. This was released with IRIX 6.0.1-XFS and IRIX 6.1.
* -Version 3 of this structure (XFS_LI_INODE) is the same as version 2
* so a new structure definition wasn't necessary. However, we had
* to add a new type because the inode cluster size changed from 4K
* to 8K and the version number had to be rev'ved to keep older kernels
* from trying to recover logs with the 8K buffers in them. The logging
* code can handle recovery on different-sized clusters now so hopefully
* this'll be the last time we need to change the inode log item just
* for a change in the inode cluster size. This new version was
* released with IRIX 6.2.
*/
typedef struct xfs_inode_log_format {
unsigned short ilf_type; /* inode log item type */
@ -59,18 +40,38 @@ typedef struct xfs_inode_log_format {
int ilf_boffset; /* off of inode in buffer */
} xfs_inode_log_format_t;
/* Initial version shipped with IRIX 5.3-XFS */
typedef struct xfs_inode_log_format_v1 {
unsigned short ilf_type; /* inode log item type */
unsigned short ilf_size; /* size of this item */
uint ilf_fields; /* flags for fields logged */
uint ilf_dsize; /* size of data/ext/root */
xfs_ino_t ilf_ino; /* inode number */
typedef struct xfs_inode_log_format_32 {
unsigned short ilf_type; /* 16: inode log item type */
unsigned short ilf_size; /* 16: size of this item */
uint ilf_fields; /* 32: flags for fields logged */
ushort ilf_asize; /* 32: size of attr d/ext/root */
ushort ilf_dsize; /* 32: size of data/ext/root */
xfs_ino_t ilf_ino; /* 64: inode number */
union {
xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/
uuid_t ilfu_uuid; /* mount point value */
xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
uuid_t ilfu_uuid; /* 128: mount point value */
} ilf_u;
} xfs_inode_log_format_t_v1;
__int64_t ilf_blkno; /* 64: blkno of inode buffer */
int ilf_len; /* 32: len of inode buffer */
int ilf_boffset; /* 32: off of inode in buffer */
} __attribute__((packed)) xfs_inode_log_format_32_t;
typedef struct xfs_inode_log_format_64 {
unsigned short ilf_type; /* 16: inode log item type */
unsigned short ilf_size; /* 16: size of this item */
uint ilf_fields; /* 32: flags for fields logged */
ushort ilf_asize; /* 32: size of attr d/ext/root */
ushort ilf_dsize; /* 32: size of data/ext/root */
__uint32_t ilf_pad; /* 32: pad for 64 bit boundary */
xfs_ino_t ilf_ino; /* 64: inode number */
union {
xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
uuid_t ilfu_uuid; /* 128: mount point value */
} ilf_u;
__int64_t ilf_blkno; /* 64: blkno of inode buffer */
int ilf_len; /* 32: len of inode buffer */
int ilf_boffset; /* 32: off of inode in buffer */
} xfs_inode_log_format_64_t;
/*
* Flags for xfs_trans_log_inode flags field.
@ -172,6 +173,8 @@ extern void xfs_inode_item_destroy(struct xfs_inode *);
extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
extern void xfs_iflush_abort(struct xfs_inode *);
extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
xfs_inode_log_format_t *);
#endif /* __KERNEL__ */

Просмотреть файл

@ -24,14 +24,13 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dfrag.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -58,7 +57,7 @@ xfs_size_fn(
STATIC int
xfs_ioinit(
struct vfs *vfsp,
struct bhv_vfs *vfsp,
struct xfs_mount_args *mntargs,
int flags)
{
@ -68,6 +67,7 @@ xfs_ioinit(
xfs_ioops_t xfs_iocore_xfs = {
.xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
.xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
.xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi,
.xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
.xfs_iomap_write_direct =
(xfs_iomap_write_direct_t) xfs_iomap_write_direct,
@ -84,6 +84,7 @@ xfs_ioops_t xfs_iocore_xfs = {
.xfs_unlock = (xfs_unlk_t) xfs_iunlock,
.xfs_size_func = (xfs_size_t) xfs_size_fn,
.xfs_iodone = (xfs_iodone_t) fs_noerr,
.xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents,
};
void

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
#include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -252,7 +250,7 @@ xfs_iomap(
error = XFS_BMAPI(mp, NULL, io, offset_fsb,
(xfs_filblks_t)(end_fsb - offset_fsb),
bmapi_flags, NULL, 0, &imap,
&nimaps, NULL);
&nimaps, NULL, NULL);
if (error)
goto out;
@ -519,8 +517,8 @@ xfs_iomap_write_direct(
*/
XFS_BMAP_INIT(&free_list, &firstfsb);
nimaps = 1;
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list);
error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
&firstfsb, 0, &imap, &nimaps, &free_list, NULL);
if (error)
goto error0;
@ -610,8 +608,8 @@ xfs_iomap_eof_want_preallocate(
while (count_fsb > 0) {
imaps = nimaps;
firstblock = NULLFSBLOCK;
error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,
0, &firstblock, 0, imap, &imaps, NULL);
error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
&firstblock, 0, imap, &imaps, NULL, NULL);
if (error)
return error;
for (n = 0; n < imaps; n++) {
@ -695,11 +693,11 @@ retry:
nimaps = XFS_WRITE_IMAPS;
firstblock = NULLFSBLOCK;
error = xfs_bmapi(NULL, ip, offset_fsb,
error = XFS_BMAPI(mp, NULL, io, offset_fsb,
(xfs_filblks_t)(last_fsb - offset_fsb),
XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
&nimaps, NULL);
&nimaps, NULL, NULL);
if (error && (error != ENOSPC))
return XFS_ERROR(error);
@ -832,9 +830,9 @@ xfs_iomap_write_allocate(
}
/* Go get the actual blocks */
error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb,
error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
XFS_BMAPI_WRITE, &first_block, 1,
imap, &nimaps, &free_list);
imap, &nimaps, &free_list, NULL);
if (error)
goto trans_cancel;
@ -955,9 +953,9 @@ xfs_iomap_write_unwritten(
*/
XFS_BMAP_INIT(&free_list, &firstfsb);
nimaps = 1;
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
1, &imap, &nimaps, &free_list);
1, &imap, &nimaps, &free_list, NULL);
if (error)
goto error_on_bmapi_transaction;

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -41,11 +39,6 @@
#include "xfs_error.h"
#include "xfs_btree.h"
#ifndef HAVE_USERACC
#define useracc(ubuffer, size, flags, foo) (0)
#define unuseracc(ubuffer, size, flags)
#endif
STATIC int
xfs_bulkstat_one_iget(
xfs_mount_t *mp, /* mount point for filesystem */
@ -56,7 +49,7 @@ xfs_bulkstat_one_iget(
{
xfs_dinode_core_t *dic; /* dinode core info pointer */
xfs_inode_t *ip; /* incore inode pointer */
vnode_t *vp;
bhv_vnode_t *vp;
int error;
error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
@ -335,15 +328,6 @@ xfs_bulkstat(
(XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
nimask = ~(nicluster - 1);
nbcluster = nicluster >> mp->m_sb.sb_inopblog;
/*
* Lock down the user's buffer. If a buffer was not sent, as in the case
* disk quota code calls here, we skip this.
*/
if (ubuffer &&
(error = useracc(ubuffer, ubcount * statstruct_size,
(B_READ|B_PHYS), NULL))) {
return error;
}
/*
* Allocate a page-sized buffer for inode btree records.
* We could try allocating something smaller, but for normal
@ -650,8 +634,6 @@ xfs_bulkstat(
* Done, we're either out of filesystem or space to put the data.
*/
kmem_free(irbuf, NBPC);
if (ubuffer)
unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
*ubcountp = ubelem;
if (agno >= mp->m_sb.sb_agcount) {
/*

Просмотреть файл

@ -45,7 +45,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
*/
#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
#define BULKSTAT_FG_VFSLOCKED 0x4 /* Already have vfs lock */
/*
* Return stat information in bulk (by-inode) for the filesystem.

Просмотреть файл

@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@ -36,7 +35,6 @@
#include "xfs_ialloc_btree.h"
#include "xfs_log_recover.h"
#include "xfs_trans_priv.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -402,7 +400,7 @@ xfs_log_release_iclog(xfs_mount_t *mp,
xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
if (xlog_state_release_iclog(log, iclog)) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
return EIO;
}
@ -498,9 +496,8 @@ xfs_log_mount(xfs_mount_t *mp,
* just worked.
*/
if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
int error;
vfs_t *vfsp = XFS_MTOVFS(mp);
int readonly = (vfsp->vfs_flag & VFS_RDONLY);
bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
if (readonly)
vfsp->vfs_flag &= ~VFS_RDONLY;
@ -726,7 +723,7 @@ xfs_log_write(xfs_mount_t * mp,
return XFS_ERROR(EIO);
if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
}
return error;
} /* xfs_log_write */
@ -816,9 +813,9 @@ xfs_log_need_covered(xfs_mount_t *mp)
SPLDECL(s);
int needed = 0, gen;
xlog_t *log = mp->m_log;
vfs_t *vfsp = XFS_MTOVFS(mp);
bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
if (fs_frozen(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
(vfsp->vfs_flag & VFS_RDONLY))
return 0;
@ -956,7 +953,7 @@ xlog_iodone(xfs_buf_t *bp)
XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
XFS_BUF_STALE(bp);
xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR);
xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR);
/*
* This flag will be propagated to the trans-committed
* callback routines to let them know that the log-commit
@ -1261,7 +1258,7 @@ xlog_commit_record(xfs_mount_t *mp,
ASSERT_ALWAYS(iclog);
if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
iclog, XLOG_COMMIT_TRANS))) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
}
return error;
} /* xlog_commit_record */
@ -1790,7 +1787,7 @@ xlog_write(xfs_mount_t * mp,
xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
"xfs_log_write: reservation ran out. Need to up reservation");
/* If we did not panic, shutdown the filesystem */
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
#endif
} else
ticket->t_curr_res -= len;

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -193,14 +191,14 @@ xlog_header_check_dump(
{
int b;
printk("%s: SB : uuid = ", __FUNCTION__);
cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__);
for (b = 0; b < 16; b++)
printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]);
printk(", fmt = %d\n", XLOG_FMT);
printk(" log : uuid = ");
cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
cmn_err(CE_DEBUG, " log : uuid = ");
for (b = 0; b < 16; b++)
printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]);
printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
}
#else
#define xlog_header_check_dump(mp, head)
@ -282,7 +280,7 @@ xlog_recover_iodone(
mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
xfs_ioerror_alert("xlog_recover_iodone",
mp, bp, XFS_BUF_ADDR(bp));
xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
}
XFS_BUF_SET_FSPRIVATE(bp, NULL);
XFS_BUF_CLR_IODONE_FUNC(bp);
@ -1889,7 +1887,7 @@ xlog_recover_do_inode_buffer(
buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
next_unlinked_offset);
INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp);
*buffer_nextp = *logged_nextp;
}
return 0;
@ -2292,12 +2290,22 @@ xlog_recover_do_inode_trans(
int attr_index;
uint fields;
xfs_dinode_core_t *dicp;
int need_free = 0;
if (pass == XLOG_RECOVER_PASS1) {
return 0;
}
in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
} else {
in_f = (xfs_inode_log_format_t *)kmem_alloc(
sizeof(xfs_inode_log_format_t), KM_SLEEP);
need_free = 1;
error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
if (error)
goto error;
}
ino = in_f->ilf_ino;
mp = log->l_mp;
if (ITEM_TYPE(item) == XFS_LI_INODE) {
@ -2323,8 +2331,10 @@ xlog_recover_do_inode_trans(
* Inode buffers can be freed, look out for it,
* and do not replay the inode.
*/
if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0))
return 0;
if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) {
error = 0;
goto error;
}
bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
XFS_BUF_LOCK);
@ -2333,7 +2343,7 @@ xlog_recover_do_inode_trans(
bp, imap.im_blkno);
error = XFS_BUF_GETERROR(bp);
xfs_buf_relse(bp);
return error;
goto error;
}
error = 0;
ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
@ -2350,7 +2360,8 @@ xlog_recover_do_inode_trans(
dip, bp, ino);
XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
error = EFSCORRUPTED;
goto error;
}
dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
@ -2360,7 +2371,8 @@ xlog_recover_do_inode_trans(
item, ino);
XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
XFS_ERRLEVEL_LOW, mp);
return XFS_ERROR(EFSCORRUPTED);
error = EFSCORRUPTED;
goto error;
}
/* Skip replay when the on disk inode is newer than the log one */
@ -2376,7 +2388,8 @@ xlog_recover_do_inode_trans(
/* do nothing */
} else {
xfs_buf_relse(bp);
return 0;
error = 0;
goto error;
}
}
/* Take the opportunity to reset the flush iteration count */
@ -2391,7 +2404,8 @@ xlog_recover_do_inode_trans(
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
item, dip, bp, ino);
return XFS_ERROR(EFSCORRUPTED);
error = EFSCORRUPTED;
goto error;
}
} else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) {
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
@ -2403,7 +2417,8 @@ xlog_recover_do_inode_trans(
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
item, dip, bp, ino);
return XFS_ERROR(EFSCORRUPTED);
error = EFSCORRUPTED;
goto error;
}
}
if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
@ -2415,7 +2430,8 @@ xlog_recover_do_inode_trans(
item, dip, bp, ino,
dicp->di_nextents + dicp->di_anextents,
dicp->di_nblocks);
return XFS_ERROR(EFSCORRUPTED);
error = EFSCORRUPTED;
goto error;
}
if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
@ -2424,7 +2440,8 @@ xlog_recover_do_inode_trans(
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
item, dip, bp, ino, dicp->di_forkoff);
return XFS_ERROR(EFSCORRUPTED);
error = EFSCORRUPTED;
goto error;
}
if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
@ -2433,7 +2450,8 @@ xlog_recover_do_inode_trans(
xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
item->ri_buf[1].i_len, item);
return XFS_ERROR(EFSCORRUPTED);
error = EFSCORRUPTED;
goto error;
}
/* The core is in in-core format */
@ -2521,7 +2539,8 @@ xlog_recover_do_inode_trans(
xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
ASSERT(0);
xfs_buf_relse(bp);
return XFS_ERROR(EIO);
error = EIO;
goto error;
}
}
@ -2537,7 +2556,10 @@ write_inode_buffer:
error = xfs_bwrite(mp, bp);
}
return (error);
error:
if (need_free)
kmem_free(in_f, sizeof(*in_f));
return XFS_ERROR(error);
}
/*
@ -2674,32 +2696,32 @@ xlog_recover_do_dquot_trans(
* structure into it, and adds the efi to the AIL with the given
* LSN.
*/
STATIC void
STATIC int
xlog_recover_do_efi_trans(
xlog_t *log,
xlog_recover_item_t *item,
xfs_lsn_t lsn,
int pass)
{
int error;
xfs_mount_t *mp;
xfs_efi_log_item_t *efip;
xfs_efi_log_format_t *efi_formatp;
SPLDECL(s);
if (pass == XLOG_RECOVER_PASS1) {
return;
return 0;
}
efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
ASSERT(item->ri_buf[0].i_len ==
(sizeof(xfs_efi_log_format_t) +
((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))));
mp = log->l_mp;
efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
memcpy((char *)&(efip->efi_format), (char *)efi_formatp,
sizeof(xfs_efi_log_format_t) +
((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t)));
if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
&(efip->efi_format)))) {
xfs_efi_item_free(efip);
return error;
}
efip->efi_next_extent = efi_formatp->efi_nextents;
efip->efi_flags |= XFS_EFI_COMMITTED;
@ -2708,6 +2730,7 @@ xlog_recover_do_efi_trans(
* xfs_trans_update_ail() drops the AIL lock.
*/
xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s);
return 0;
}
@ -2738,9 +2761,10 @@ xlog_recover_do_efd_trans(
}
efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
ASSERT(item->ri_buf[0].i_len ==
(sizeof(xfs_efd_log_format_t) +
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t))));
ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
(item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
efi_id = efd_formatp->efd_efi_id;
/*
@ -2810,15 +2834,14 @@ xlog_recover_do_trans(
if ((error = xlog_recover_do_buffer_trans(log, item,
pass)))
break;
} else if ((ITEM_TYPE(item) == XFS_LI_INODE) ||
(ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
(ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
} else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
if ((error = xlog_recover_do_inode_trans(log, item,
pass)))
break;
} else if (ITEM_TYPE(item) == XFS_LI_EFI) {
xlog_recover_do_efi_trans(log, item, trans->r_lsn,
pass);
if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
pass)))
break;
} else if (ITEM_TYPE(item) == XFS_LI_EFD) {
xlog_recover_do_efd_trans(log, item, pass);
} else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
@ -3419,13 +3442,13 @@ xlog_unpack_data_checksum(
if (rhead->h_chksum ||
((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
cmn_err(CE_DEBUG,
"XFS: LogR chksum mismatch: was (0x%x) is (0x%x)",
"XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
cmn_err(CE_DEBUG,
"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
cmn_err(CE_DEBUG,
"XFS: LogR this is a LogV2 filesystem");
"XFS: LogR this is a LogV2 filesystem\n");
}
log->l_flags |= XLOG_CHKSUM_MISMATCH;
}
@ -3798,7 +3821,7 @@ xlog_do_log_recovery(
error = xlog_do_recovery_pass(log, head_blk, tail_blk,
XLOG_RECOVER_PASS2);
#ifdef DEBUG
{
if (!error) {
int i;
for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
@ -3974,7 +3997,7 @@ xlog_recover_finish(
log->l_flags &= ~XLOG_RECOVERY_NEEDED;
} else {
cmn_err(CE_DEBUG,
"!Ending clean XFS mount for filesystem: %s",
"!Ending clean XFS mount for filesystem: %s\n",
log->l_mp->m_fsname);
}
return 0;

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -196,7 +194,7 @@ xfs_mount_free(
kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
if (remove_bhv) {
struct vfs *vfsp = XFS_MTOVFS(mp);
struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
bhv_remove_all_vfsops(vfsp, 0);
VFS_REMOVEBHV(vfsp, &mp->m_bhv);
@ -337,7 +335,7 @@ xfs_mount_validate_sb(
xfs_agnumber_t
xfs_initialize_perag(
struct vfs *vfs,
bhv_vfs_t *vfs,
xfs_mount_t *mp,
xfs_agnumber_t agcount)
{
@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
*/
int
xfs_mountfs(
vfs_t *vfsp,
bhv_vfs_t *vfsp,
xfs_mount_t *mp,
int mfsi_flags)
{
xfs_buf_t *bp;
xfs_sb_t *sbp = &(mp->m_sb);
xfs_inode_t *rip;
vnode_t *rvp = NULL;
bhv_vnode_t *rvp = NULL;
int readio_log, writeio_log;
xfs_daddr_t d;
__uint64_t ret64;
@ -934,18 +932,7 @@ xfs_mountfs(
vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
mp->m_dmevmask = 0; /* not persistent; set after each mount */
/*
* Select the right directory manager.
*/
mp->m_dirops =
XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
xfsv2_dirops :
xfsv1_dirops;
/*
* Initialize directory manager's entries.
*/
XFS_DIR_MOUNT(mp);
xfs_dir_mount(mp);
/*
* Initialize the attribute manager's entries.
@ -1006,8 +993,9 @@ xfs_mountfs(
if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
cmn_err(CE_WARN, "XFS: corrupted root inode");
prdev("Root inode %llu is not a directory",
mp->m_ddev_targp, (unsigned long long)rip->i_ino);
cmn_err(CE_WARN, "Device %s - root %llu is not a directory",
XFS_BUFTARG_NAME(mp->m_ddev_targp),
(unsigned long long)rip->i_ino);
xfs_iunlock(rip, XFS_ILOCK_EXCL);
XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
mp);
@ -1094,7 +1082,7 @@ xfs_mountfs(
int
xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
{
struct vfs *vfsp = XFS_MTOVFS(mp);
struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
int64_t fsid;
#endif
@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
xfs_trans_log_buf(tp, bp, first, last);
}
/*
* In order to avoid ENOSPC-related deadlock caused by
* out-of-order locking of AGF buffer (PV 947395), we place
* constraints on the relationship among actual allocations for
* data blocks, freelist blocks, and potential file data bmap
* btree blocks. However, these restrictions may result in no
* actual space allocated for a delayed extent, for example, a data
* block in a certain AG is allocated but there is no additional
* block for the additional bmap btree block due to a split of the
* bmap btree of the file. The result of this may lead to an
* infinite loop in xfssyncd when the file gets flushed to disk and
* all delayed extents need to be actually allocated. To get around
* this, we explicitly set aside a few blocks which will not be
* reserved in delayed allocation. Considering the minimum number of
* needed freelist blocks is 4 fsbs, a potential split of file's bmap
* btree requires 1 fsb, so we set the number of set-aside blocks to 8.
*/
#define SET_ASIDE_BLOCKS 8
/*
* xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
* a delta to a specified field in the in-core superblock. Simply
@ -1298,7 +1306,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
return 0;
case XFS_SBS_FDBLOCKS:
lcounter = (long long)mp->m_sb.sb_fdblocks;
lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS;
res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
if (delta > 0) { /* Putting blocks back */
@ -1332,7 +1340,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
}
}
mp->m_sb.sb_fdblocks = lcounter;
mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS;
return 0;
case XFS_SBS_FREXTENTS:
lcounter = (long long)mp->m_sb.sb_frextents;

Просмотреть файл

@ -53,8 +53,8 @@ typedef struct xfs_trans_reservations {
#else
struct cred;
struct log;
struct vfs;
struct vnode;
struct bhv_vfs;
struct bhv_vnode;
struct xfs_mount_args;
struct xfs_ihash;
struct xfs_chash;
@ -63,9 +63,11 @@ struct xfs_perag;
struct xfs_iocore;
struct xfs_bmbt_irec;
struct xfs_bmap_free;
struct xfs_extdelta;
struct xfs_swapext;
extern struct vfsops xfs_vfsops;
extern struct vnodeops xfs_vnodeops;
extern struct bhv_vfsops xfs_vfsops;
extern struct bhv_vnodeops xfs_vnodeops;
#define AIL_LOCK_T lock_t
#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
@ -78,15 +80,15 @@ extern struct vnodeops xfs_vnodeops;
* Prototypes and functions for the Data Migration subsystem.
*/
typedef int (*xfs_send_data_t)(int, struct vnode *,
xfs_off_t, size_t, int, vrwlock_t *);
typedef int (*xfs_send_data_t)(int, struct bhv_vnode *,
xfs_off_t, size_t, int, bhv_vrwlock_t *);
typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t);
typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *,
struct vnode *,
dm_right_t, struct vnode *, dm_right_t,
typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t);
typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *,
struct bhv_vnode *,
dm_right_t, struct bhv_vnode *, dm_right_t,
char *, char *, mode_t, int, int);
typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *,
typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *,
dm_right_t, mode_t, int, int);
typedef struct xfs_dmops {
@ -188,13 +190,18 @@ typedef struct xfs_qmops {
* Prototypes and functions for I/O core modularization.
*/
typedef int (*xfs_ioinit_t)(struct vfs *,
typedef int (*xfs_ioinit_t)(struct bhv_vfs *,
struct xfs_mount_args *, int);
typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
xfs_fileoff_t, xfs_filblks_t, int,
xfs_fsblock_t *, xfs_extlen_t,
struct xfs_bmbt_irec *, int *,
struct xfs_bmap_free *);
struct xfs_bmap_free *, struct xfs_extdelta *);
typedef int (*xfs_bunmapi_t)(struct xfs_trans *,
void *, xfs_fileoff_t,
xfs_filblks_t, int, xfs_extnum_t,
xfs_fsblock_t *, struct xfs_bmap_free *,
struct xfs_extdelta *, int *);
typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
typedef int (*xfs_iomap_write_direct_t)(
void *, xfs_off_t, size_t, int,
@ -213,11 +220,14 @@ typedef void (*xfs_lock_demote_t)(void *, uint);
typedef int (*xfs_lock_nowait_t)(void *, uint);
typedef void (*xfs_unlk_t)(void *, unsigned int);
typedef xfs_fsize_t (*xfs_size_t)(void *);
typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *);
typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *);
typedef int (*xfs_swap_extents_t)(void *, void *,
struct xfs_swapext*);
typedef struct xfs_ioops {
xfs_ioinit_t xfs_ioinit;
xfs_bmapi_t xfs_bmapi_func;
xfs_bunmapi_t xfs_bunmapi_func;
xfs_bmap_eof_t xfs_bmap_eof_func;
xfs_iomap_write_direct_t xfs_iomap_write_direct;
xfs_iomap_write_delay_t xfs_iomap_write_delay;
@ -230,13 +240,17 @@ typedef struct xfs_ioops {
xfs_unlk_t xfs_unlock;
xfs_size_t xfs_size_func;
xfs_iodone_t xfs_iodone;
xfs_swap_extents_t xfs_swap_extents_func;
} xfs_ioops_t;
#define XFS_IOINIT(vfsp, args, flags) \
(*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \
#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
(*(mp)->m_io_ops.xfs_bmapi_func) \
(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist)
(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \
(*(mp)->m_io_ops.xfs_bunmapi_func) \
(trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)
#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
(*(mp)->m_io_ops.xfs_bmap_eof_func) \
((io)->io_obj, endoff, whichfork, eof)
@ -266,6 +280,9 @@ typedef struct xfs_ioops {
(*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
#define XFS_IODONE(vfsp) \
(*(mp)->m_io_ops.xfs_iodone)(vfsp)
#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
(*(mp)->m_io_ops.xfs_swap_extents_func) \
((io)->io_obj, (tio)->io_obj, sxp)
#ifdef HAVE_PERCPU_SB
@ -386,8 +403,6 @@ typedef struct xfs_mount {
__uint8_t m_inode_quiesce;/* call quiesce on new inodes.
field governed by m_ilock */
__uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
__uint8_t m_dirversion; /* 1 or 2 */
xfs_dirops_t m_dirops; /* table of dir funcs */
int m_dirblksize; /* directory block sz--bytes */
int m_dirblkfsbs; /* directory block sz--fsbs */
xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
@ -494,16 +509,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
#define xfs_force_shutdown(m,f) \
VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
/*
* Flags sent to xfs_force_shutdown.
*/
#define XFS_METADATA_IO_ERROR 0x1
#define XFS_LOG_IO_ERROR 0x2
#define XFS_FORCE_UMOUNT 0x4
#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
/*
* Flags for xfs_mountfs
@ -521,7 +527,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
* Macros for getting from mount to vfs and back.
*/
#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp)
static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp)
{
return bhvtovfs(&mp->m_bhv);
}
@ -533,7 +539,7 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
}
#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs)
static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
{
return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
}
@ -571,7 +577,7 @@ typedef struct xfs_mod_sb {
extern xfs_mount_t *xfs_mount_init(void);
extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int);
extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
@ -589,7 +595,7 @@ extern void xfs_freesb(xfs_mount_t *);
extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *);
extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *,
extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *,
xfs_agnumber_t);
extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);

Просмотреть файл

@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"

Просмотреть файл

@ -365,7 +365,7 @@ typedef struct xfs_dqtrxops {
extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
extern struct bhv_vfsops xfs_qmops;
extern struct bhv_module_vfsops xfs_qmops;
#endif /* __KERNEL__ */

Просмотреть файл

@ -22,13 +22,11 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -40,7 +38,6 @@
#include "xfs_refcache.h"
#include "xfs_utils.h"
#include "xfs_trans_space.h"
#include "xfs_dir_leaf.h"
/*
@ -87,8 +84,8 @@ STATIC int
xfs_lock_for_rename(
xfs_inode_t *dp1, /* old (source) directory inode */
xfs_inode_t *dp2, /* new (target) directory inode */
vname_t *vname1,/* old entry name */
vname_t *vname2,/* new entry name */
bhv_vname_t *vname1,/* old entry name */
bhv_vname_t *vname2,/* new entry name */
xfs_inode_t **ipp1, /* inode of old entry */
xfs_inode_t **ipp2, /* inode of new entry, if it
already exists, NULL otherwise. */
@ -225,9 +222,9 @@ xfs_lock_for_rename(
int
xfs_rename(
bhv_desc_t *src_dir_bdp,
vname_t *src_vname,
vnode_t *target_dir_vp,
vname_t *target_vname,
bhv_vname_t *src_vname,
bhv_vnode_t *target_dir_vp,
bhv_vname_t *target_vname,
cred_t *credp)
{
xfs_trans_t *tp;
@ -242,7 +239,7 @@ xfs_rename(
int committed;
xfs_inode_t *inodes[4];
int target_ip_dropped = 0; /* dropped target_ip link? */
vnode_t *src_dir_vp;
bhv_vnode_t *src_dir_vp;
int spaceres;
int target_link_zero = 0;
int num_inodes;
@ -398,34 +395,29 @@ xfs_rename(
* fit before actually inserting it.
*/
if (spaceres == 0 &&
(error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name,
target_namelen))) {
(error = xfs_dir_canenter(tp, target_dp, target_name,
target_namelen)))
goto error_return;
}
/*
* If target does not exist and the rename crosses
* directories, adjust the target directory link count
* to account for the ".." reference from the new entry.
*/
error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name,
error = xfs_dir_createname(tp, target_dp, target_name,
target_namelen, src_ip->i_ino,
&first_block, &free_list, spaceres);
if (error == ENOSPC) {
if (error == ENOSPC)
goto error_return;
}
if (error) {
if (error)
goto abort_return;
}
xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
if (new_parent && src_is_directory) {
error = xfs_bumplink(tp, target_dp);
if (error) {
if (error)
goto abort_return;
}
}
} else { /* target_ip != NULL */
/*
* If target exists and it's a directory, check that both
* target and source are directories and that target can be
@ -435,7 +427,7 @@ xfs_rename(
/*
* Make sure target dir is empty.
*/
if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) ||
if (!(xfs_dir_isempty(target_ip)) ||
(target_ip->i_d.di_nlink > 2)) {
error = XFS_ERROR(EEXIST);
goto error_return;
@ -451,12 +443,11 @@ xfs_rename(
* In case there is already an entry with the same
* name at the destination directory, remove it first.
*/
error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name,
target_namelen, src_ip->i_ino, &first_block,
&free_list, spaceres);
if (error) {
error = xfs_dir_replace(tp, target_dp, target_name,
target_namelen, src_ip->i_ino,
&first_block, &free_list, spaceres);
if (error)
goto abort_return;
}
xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
/*
@ -464,9 +455,8 @@ xfs_rename(
* dir no longer points to it.
*/
error = xfs_droplink(tp, target_ip);
if (error) {
if (error)
goto abort_return;
}
target_ip_dropped = 1;
if (src_is_directory) {
@ -474,9 +464,8 @@ xfs_rename(
* Drop the link from the old "." entry.
*/
error = xfs_droplink(tp, target_ip);
if (error) {
if (error)
goto abort_return;
}
}
/* Do this test while we still hold the locks */
@ -488,18 +477,15 @@ xfs_rename(
* Remove the source.
*/
if (new_parent && src_is_directory) {
/*
* Rewrite the ".." entry to point to the new
* directory.
*/
error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2,
target_dp->i_ino, &first_block,
&free_list, spaceres);
error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino,
&first_block, &free_list, spaceres);
ASSERT(error != EEXIST);
if (error) {
if (error)
goto abort_return;
}
xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
} else {
@ -527,16 +513,14 @@ xfs_rename(
* entry that's moved no longer points to it.
*/
error = xfs_droplink(tp, src_dp);
if (error) {
if (error)
goto abort_return;
}
}
error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen,
error = xfs_dir_removename(tp, src_dp, src_name, src_namelen,
src_ip->i_ino, &first_block, &free_list, spaceres);
if (error) {
if (error)
goto abort_return;
}
xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
/*
@ -609,7 +593,7 @@ xfs_rename(
* Let interposed file systems know about removed links.
*/
if (target_ip_dropped) {
VOP_LINK_REMOVED(XFS_ITOV(target_ip), target_dir_vp,
bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
target_link_zero);
IRELE(target_ip);
}

Просмотреть файл

@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -141,7 +139,7 @@ xfs_growfs_rt_alloc(
cancelflags |= XFS_TRANS_ABORT;
error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
resblks, &map, &nmap, &flist);
resblks, &map, &nmap, &flist, NULL);
if (!error && nmap < 1)
error = XFS_ERROR(ENOSPC);
if (error)
@ -2404,10 +2402,10 @@ xfs_rtprint_range(
{
xfs_extlen_t i; /* block number in the extent */
printk("%Ld: ", (long long)start);
cmn_err(CE_DEBUG, "%Ld: ", (long long)start);
for (i = 0; i < len; i++)
printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
printk("\n");
cmn_err(CE_DEBUG, "%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
cmn_err(CE_DEBUG, "\n");
}
/*
@ -2431,17 +2429,17 @@ xfs_rtprint_summary(
(void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c);
if (c) {
if (!p) {
printk("%Ld-%Ld:", 1LL << l,
cmn_err(CE_DEBUG, "%Ld-%Ld:", 1LL << l,
XFS_RTMIN((1LL << l) +
((1LL << l) - 1LL),
mp->m_sb.sb_rextents));
p = 1;
}
printk(" %Ld:%d", (long long)i, c);
cmn_err(CE_DEBUG, " %Ld:%d", (long long)i, c);
}
}
if (p)
printk("\n");
cmn_err(CE_DEBUG, "\n");
}
if (sumbp)
xfs_trans_brelse(tp, sumbp);

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -24,14 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -91,6 +89,90 @@ xfs_write_clear_setuid(
return 0;
}
/*
* Handle logging requirements of various synchronous types of write.
*/
int
xfs_write_sync_logforce(
xfs_mount_t *mp,
xfs_inode_t *ip)
{
int error = 0;
/*
* If we're treating this as O_DSYNC and we have not updated the
* size, force the log.
*/
if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
!(ip->i_update_size)) {
xfs_inode_log_item_t *iip = ip->i_itemp;
/*
* If an allocation transaction occurred
* without extending the size, then we have to force
* the log up the proper point to ensure that the
* allocation is permanent. We can't count on
* the fact that buffered writes lock out direct I/O
* writes - the direct I/O write could have extended
* the size nontransactionally, then finished before
* we started. xfs_write_file will think that the file
* didn't grow but the update isn't safe unless the
* size change is logged.
*
* Force the log if we've committed a transaction
* against the inode or if someone else has and
* the commit record hasn't gone to disk (e.g.
* the inode is pinned). This guarantees that
* all changes affecting the inode are permanent
* when we return.
*/
if (iip && iip->ili_last_lsn) {
xfs_log_force(mp, iip->ili_last_lsn,
XFS_LOG_FORCE | XFS_LOG_SYNC);
} else if (xfs_ipincount(ip) > 0) {
xfs_log_force(mp, (xfs_lsn_t)0,
XFS_LOG_FORCE | XFS_LOG_SYNC);
}
} else {
xfs_trans_t *tp;
/*
* O_SYNC or O_DSYNC _with_ a size update are handled
* the same way.
*
* If the write was synchronous then we need to make
* sure that the inode modification time is permanent.
* We'll have updated the timestamp above, so here
* we use a synchronous transaction to log the inode.
* It's not fast, but it's necessary.
*
* If this a dsync write and the size got changed
* non-transactionally, then we need to ensure that
* the size change gets logged in a synchronous
* transaction.
*/
tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
if ((error = xfs_trans_reserve(tp, 0,
XFS_SWRITE_LOG_RES(mp),
0, 0, 0))) {
/* Transaction reserve failed */
xfs_trans_cancel(tp, 0);
} else {
/* Transaction reserve successful */
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_ihold(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0, NULL);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
}
return error;
}
/*
* Force a shutdown of the filesystem instantly while keeping
* the filesystem consistent. We don't do an unmount here; just shutdown
@ -109,12 +191,12 @@ xfs_do_force_shutdown(
xfs_mount_t *mp;
mp = XFS_BHVTOM(bdp);
logerror = flags & XFS_LOG_IO_ERROR;
logerror = flags & SHUTDOWN_LOG_IO_ERROR;
if (!(flags & XFS_FORCE_UMOUNT)) {
cmn_err(CE_NOTE,
"xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p",
mp->m_fsname,flags,lnnum,fname,__return_address);
if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
cmn_err(CE_NOTE, "xfs_force_shutdown(%s,0x%x) called from "
"line %d of file %s. Return address = 0x%p",
mp->m_fsname, flags, lnnum, fname, __return_address);
}
/*
* No need to duplicate efforts.
@ -125,33 +207,37 @@ xfs_do_force_shutdown(
/*
* This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
* queue up anybody new on the log reservations, and wakes up
* everybody who's sleeping on log reservations and tells
* them the bad news.
* everybody who's sleeping on log reservations to tell them
* the bad news.
*/
if (xfs_log_force_umount(mp, logerror))
return;
if (flags & XFS_CORRUPT_INCORE) {
if (flags & SHUTDOWN_CORRUPT_INCORE) {
xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
"Corruption of in-memory data detected. Shutting down filesystem: %s",
mp->m_fsname);
if (XFS_ERRLEVEL_HIGH <= xfs_error_level) {
xfs_stack_trace();
}
} else if (!(flags & XFS_FORCE_UMOUNT)) {
} else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
if (logerror) {
xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp,
"Log I/O Error Detected. Shutting down filesystem: %s",
"Log I/O Error Detected. Shutting down filesystem: %s",
mp->m_fsname);
} else if (!(flags & XFS_SHUTDOWN_REMOTE_REQ)) {
} else if (flags & SHUTDOWN_DEVICE_REQ) {
xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
"I/O Error Detected. Shutting down filesystem: %s",
"All device paths lost. Shutting down filesystem: %s",
mp->m_fsname);
} else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
"I/O Error Detected. Shutting down filesystem: %s",
mp->m_fsname);
}
}
if (!(flags & XFS_FORCE_UMOUNT)) {
cmn_err(CE_ALERT,
"Please umount the filesystem, and rectify the problem(s)");
if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
cmn_err(CE_ALERT, "Please umount the filesystem, "
"and rectify the problem(s)");
}
}
@ -335,7 +421,7 @@ xfs_bwrite(
* from bwrite and we could be tracing a buffer that has
* been reused.
*/
xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
}
return (error);
}

Просмотреть файл

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@ -75,6 +75,7 @@ xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb)
* Prototypes for functions in xfs_rw.c.
*/
extern int xfs_write_clear_setuid(struct xfs_inode *ip);
extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);
extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
extern int xfs_bioerror(struct xfs_buf *bp);
extern int xfs_bioerror_relse(struct xfs_buf *bp);
@ -87,9 +88,10 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
/*
* Prototypes for functions in xfs_vnodeops.c.
*/
extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock);
extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock);
extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp);
extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags,
cred_t *credp);
extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
xfs_off_t offset, cred_t *credp, int flags);
extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,

Просмотреть файл

@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
@ -33,7 +32,6 @@
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
@ -236,11 +234,8 @@ xfs_trans_alloc(
xfs_mount_t *mp,
uint type)
{
fs_check_frozen(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
atomic_inc(&mp->m_active_trans);
return (_xfs_trans_alloc(mp, type));
vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
return _xfs_trans_alloc(mp, type);
}
xfs_trans_t *
@ -250,12 +245,9 @@ _xfs_trans_alloc(
{
xfs_trans_t *tp;
ASSERT(xfs_trans_zone != NULL);
tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
atomic_inc(&mp->m_active_trans);
/*
* Initialize the transaction structure.
*/
tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
tp->t_magic = XFS_TRANS_MAGIC;
tp->t_type = type;
tp->t_mountp = mp;
@ -263,8 +255,7 @@ _xfs_trans_alloc(
tp->t_busy_free = XFS_LBC_NUM_SLOTS;
XFS_LIC_INIT(&(tp->t_items));
XFS_LBC_INIT(&(tp->t_busy));
return (tp);
return tp;
}
/*
@ -303,7 +294,7 @@ xfs_trans_dup(
tp->t_blk_res = tp->t_blk_res_used;
ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
tp->t_rtx_res = tp->t_rtx_res_used;
PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags);
ntp->t_pflags = tp->t_pflags;
XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
@ -335,14 +326,11 @@ xfs_trans_reserve(
uint logcount)
{
int log_flags;
int error;
int rsvd;
error = 0;
rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
int error = 0;
int rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
/* Mark this thread as being in a transaction */
PFLAGS_SET_FSTRANS(&tp->t_pflags);
current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
/*
* Attempt to reserve the needed disk blocks by decrementing
@ -353,7 +341,7 @@ xfs_trans_reserve(
error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
-blocks, rsvd);
if (error != 0) {
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
return (XFS_ERROR(ENOSPC));
}
tp->t_blk_res += blocks;
@ -426,9 +414,9 @@ undo_blocks:
tp->t_blk_res = 0;
}
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
return (error);
return error;
}
@ -819,7 +807,7 @@ shut_us_down:
if (commit_lsn == -1 && !shutdown)
shutdown = XFS_ERROR(EIO);
}
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
xfs_trans_free_busy(tp);
xfs_trans_free(tp);
@ -846,7 +834,7 @@ shut_us_down:
*/
nvec = xfs_trans_count_vecs(tp);
if (nvec == 0) {
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
goto shut_us_down;
} else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
log_vector = log_vector_fast;
@ -884,7 +872,7 @@ shut_us_down:
* had pinned, clean up, free trans structure, and return error.
*/
if (error || commit_lsn == -1) {
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
return XFS_ERROR(EIO);
}
@ -926,7 +914,7 @@ shut_us_down:
/*
* Mark this thread as no longer being in a transaction
*/
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
/*
* Once all the items of the transaction have been copied
@ -1148,7 +1136,7 @@ xfs_trans_cancel(
*/
if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {
XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
}
#ifdef DEBUG
if (!(flags & XFS_TRANS_ABORT)) {
@ -1182,7 +1170,7 @@ xfs_trans_cancel(
}
/* mark this thread as no longer being in a transaction */
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
xfs_trans_free_items(tp, flags);
xfs_trans_free_busy(tp);

Просмотреть файл

@ -805,12 +805,9 @@ typedef struct xfs_trans {
((mp)->m_sb.sb_inodesize + \
(mp)->m_sb.sb_sectsize * 2 + \
(mp)->m_dirblksize + \
(XFS_DIR_IS_V1(mp) ? 0 : \
XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \
XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
(128 * (4 + \
(XFS_DIR_IS_V1(mp) ? 0 : \
XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
(128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)

Просмотреть файл

@ -22,7 +22,6 @@
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
@ -363,9 +362,10 @@ xfs_trans_delete_ail(
AIL_UNLOCK(mp, s);
else {
xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
"xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL");
"%s: attempting to delete a log item that is not in the AIL",
__FUNCTION__);
AIL_UNLOCK(mp, s);
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше