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
commit 52ab3f3dc7
109 changed files with 2317 additions and 6262 deletions

View File

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

View File

@ -1,6 +1,5 @@
config XFS_FS config XFS_FS
tristate "XFS filesystem support" tristate "XFS filesystem support"
select EXPORTFS if NFSD!=n
help help
XFS is a high performance journaling filesystem which originated XFS is a high performance journaling filesystem which originated
on the SGI IRIX platform. It is completely multi-threaded, can 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 system of your root partition is compiled as a module, you'll need
to use an initial ramdisk (initrd) to boot. to use an initial ramdisk (initrd) to boot.
config XFS_EXPORT
bool
depends on XFS_FS && EXPORTFS
default y
config XFS_QUOTA config XFS_QUOTA
bool "XFS Quota support" bool "XFS Quota support"
depends on XFS_FS depends on XFS_FS
@ -65,18 +59,19 @@ config XFS_POSIX_ACL
If you don't know what Access Control Lists are, say N. If you don't know what Access Control Lists are, say N.
config XFS_RT config XFS_RT
bool "XFS Realtime support (EXPERIMENTAL)" bool "XFS Realtime subvolume support"
depends on XFS_FS && EXPERIMENTAL depends on XFS_FS
help help
If you say Y here you will be able to mount and use XFS filesystems 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 which contain a realtime subvolume. The realtime subvolume is a
separate area of disk space where only file data is stored. The separate area of disk space where only file data is stored. It was
realtime subvolume is designed to provide very deterministic originally designed to provide deterministic data rates suitable
data rates suitable for media streaming applications. 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. See the xfs man page in section 5 for additional information.
This feature is unsupported at this time, is not yet fully
functional, and may cause serious problems.
If unsure, say N. If unsure, say N.

View File

@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o
xfs-y += xfs_alloc.o \ xfs-y += xfs_alloc.o \
@ -73,14 +72,12 @@ xfs-y += xfs_alloc.o \
xfs_btree.o \ xfs_btree.o \
xfs_buf_item.o \ xfs_buf_item.o \
xfs_da_btree.o \ xfs_da_btree.o \
xfs_dir.o \
xfs_dir2.o \ xfs_dir2.o \
xfs_dir2_block.o \ xfs_dir2_block.o \
xfs_dir2_data.o \ xfs_dir2_data.o \
xfs_dir2_leaf.o \ xfs_dir2_leaf.o \
xfs_dir2_node.o \ xfs_dir2_node.o \
xfs_dir2_sf.o \ xfs_dir2_sf.o \
xfs_dir_leaf.o \
xfs_error.o \ xfs_error.o \
xfs_extfree_item.o \ xfs_extfree_item.o \
xfs_fsops.o \ xfs_fsops.o \
@ -117,6 +114,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
kmem.o \ kmem.o \
xfs_aops.o \ xfs_aops.o \
xfs_buf.o \ xfs_buf.o \
xfs_export.o \
xfs_file.o \ xfs_file.o \
xfs_fs_subr.o \ xfs_fs_subr.o \
xfs_globals.o \ xfs_globals.o \

View File

@ -22,42 +22,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.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 * General memory allocation interfaces
*/ */
@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags)
lflags = GFP_ATOMIC | __GFP_NOWARN; lflags = GFP_ATOMIC | __GFP_NOWARN;
} else { } else {
lflags = GFP_KERNEL | __GFP_NOWARN; lflags = GFP_KERNEL | __GFP_NOWARN;
if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS)) if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
lflags &= ~__GFP_FS; lflags &= ~__GFP_FS;
} }
return lflags; return lflags;

View File

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

View File

@ -34,20 +34,21 @@ typedef struct semaphore sema_t;
#define initnsema(sp, val, name) sema_init(sp, val) #define initnsema(sp, val, name) sema_init(sp, val)
#define psema(sp, b) down(sp) #define psema(sp, b) down(sp)
#define vsema(sp) up(sp) #define vsema(sp) up(sp)
#define valusema(sp) (atomic_read(&(sp)->count)) #define freesema(sema) do { } while (0)
#define freesema(sema)
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 * 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 * the return values since cpsema returns 1 (acquired) 0 (failed) and
* down_trylock returns the reverse 0 (acquired) 1 (failed). * down_trylock returns the reverse 0 (acquired) 1 (failed).
*/ */
static inline int cpsema(sema_t *sp)
#define cpsema(sp) (down_trylock(sp) ? 0 : 1) {
return 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.
*/
#endif /* __XFS_SUPPORT_SEMA_H__ */ #endif /* __XFS_SUPPORT_SEMA_H__ */

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005 Silicon Graphics, Inc. * Copyright (c) 2005-2006 Silicon Graphics, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or * 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 { typedef struct xfs_ioend {
struct xfs_ioend *io_list; /* next ioend in chain */ struct xfs_ioend *io_list; /* next ioend in chain */
unsigned int io_type; /* delalloc / unwritten */ 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 */ 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_head;/* buffer linked list head */
struct buffer_head *io_buffer_tail;/* buffer linked list tail */ struct buffer_head *io_buffer_tail;/* buffer linked list tail */
size_t io_size; /* size of the extent */ 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 struct address_space_operations xfs_address_space_operations;
extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
#endif /* __XFS_IOPS_H__ */ #endif /* __XFS_AOPS_H__ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -114,7 +114,7 @@ xfs_compat_ioctl(
unsigned long arg) unsigned long arg)
{ {
struct inode *inode = file->f_dentry->d_inode; 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; int error;
switch (cmd) { switch (cmd) {
@ -193,7 +193,7 @@ xfs_compat_ioctl(
return -ENOIOCTLCMD; 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); VMODIFY(vp);
return error; return error;

View File

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

View File

@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten);
#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val #define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
#define xfs_rotorstep xfs_params.rotorstep.val #define xfs_rotorstep xfs_params.rotorstep.val
#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
#ifndef raw_smp_processor_id #define current_cpu() (raw_smp_processor_id())
#define raw_smp_processor_id() smp_processor_id()
#endif
#define current_cpu() raw_smp_processor_id()
#define current_pid() (current->pid) #define current_pid() (current->pid)
#define current_fsuid(cred) (current->fsuid) #define current_fsuid(cred) (current->fsuid)
#define current_fsgid(cred) (current->fsgid) #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 NBPP PAGE_SIZE
#define DPPSHFT (PAGE_SHIFT - 9) #define DPPSHFT (PAGE_SHIFT - 9)
@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten);
/* bytes to clicks */ /* bytes to clicks */
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) #define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
#ifndef ENOATTR
#define ENOATTR ENODATA /* Attribute not found */ #define ENOATTR ENODATA /* Attribute not found */
#endif #define EWRONGFS EINVAL /* Mount with wrong filesystem type */
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
/* Note: EWRONGFS never visible outside the kernel */
#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
/*
* XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
* return codes out of its known range in errno.
* XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
* conflict with any code we use already or any code a driver may use)
* XXX Some options (currently we do #2):
* 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
* 2/ 990 ["Unknown error 990"]
* 3/ EUCLEAN ["Structure needs cleaning"]
* 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
*/
#define EFSCORRUPTED 990 /* Filesystem is corrupted */
#define SYNCHRONIZE() barrier() #define SYNCHRONIZE() barrier()
#define __return_address __builtin_return_address(0) #define __return_address __builtin_return_address(0)

View File

@ -23,7 +23,6 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_alloc.h" #include "xfs_alloc.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -206,7 +204,7 @@ xfs_read(
xfs_fsize_t n; xfs_fsize_t n;
xfs_inode_t *ip; xfs_inode_t *ip;
xfs_mount_t *mp; xfs_mount_t *mp;
vnode_t *vp; bhv_vnode_t *vp;
unsigned long seg; unsigned long seg;
ip = XFS_BHVTOI(bdp); ip = XFS_BHVTOI(bdp);
@ -258,7 +256,7 @@ xfs_read(
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
!(ioflags & IO_INVIS)) { !(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); int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
@ -271,7 +269,7 @@ xfs_read(
} }
if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) 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); -1, FI_REMAPF_LOCKED);
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, 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) && if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
(!(ioflags & IO_INVIS))) { (!(ioflags & IO_INVIS))) {
vrwlock_t locktype = VRWLOCK_READ; bhv_vrwlock_t locktype = VRWLOCK_READ;
int error; int error;
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 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) && if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
(!(ioflags & IO_INVIS))) { (!(ioflags & IO_INVIS))) {
vrwlock_t locktype = VRWLOCK_READ; bhv_vrwlock_t locktype = VRWLOCK_READ;
int error; int error;
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 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) && if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
(!(ioflags & IO_INVIS))) { (!(ioflags & IO_INVIS))) {
vrwlock_t locktype = VRWLOCK_WRITE; bhv_vrwlock_t locktype = VRWLOCK_WRITE;
int error; int error;
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), 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); last_fsb = XFS_B_TO_FSBT(mp, isize);
nimaps = 1; nimaps = 1;
error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
&nimaps, NULL); &nimaps, NULL, NULL);
if (error) { if (error) {
return error; return error;
} }
@ -499,7 +497,7 @@ xfs_zero_last_block(
int /* error (positive) */ int /* error (positive) */
xfs_zero_eof( xfs_zero_eof(
vnode_t *vp, bhv_vnode_t *vp,
xfs_iocore_t *io, xfs_iocore_t *io,
xfs_off_t offset, /* starting I/O offset */ xfs_off_t offset, /* starting I/O offset */
xfs_fsize_t isize, /* current inode size */ xfs_fsize_t isize, /* current inode size */
@ -510,7 +508,6 @@ xfs_zero_eof(
xfs_fileoff_t end_zero_fsb; xfs_fileoff_t end_zero_fsb;
xfs_fileoff_t zero_count_fsb; xfs_fileoff_t zero_count_fsb;
xfs_fileoff_t last_fsb; xfs_fileoff_t last_fsb;
xfs_extlen_t buf_len_fsb;
xfs_mount_t *mp = io->io_mount; xfs_mount_t *mp = io->io_mount;
int nimaps; int nimaps;
int error = 0; int error = 0;
@ -556,7 +553,7 @@ xfs_zero_eof(
nimaps = 1; nimaps = 1;
zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, 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) { if (error) {
ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@ -579,16 +576,7 @@ xfs_zero_eof(
} }
/* /*
* There are blocks in the range requested. * There are blocks we need to zero.
* 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);
/*
* Drop the inode lock while we're doing the I/O. * Drop the inode lock while we're doing the I/O.
* We'll still have the iolock to protect us. * We'll still have the iolock to protect us.
*/ */
@ -596,14 +584,13 @@ xfs_zero_eof(
error = xfs_iozero(ip, error = xfs_iozero(ip,
XFS_FSB_TO_B(mp, start_zero_fsb), 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); end_size);
if (error) { if (error) {
goto out_lock; 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)); ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@ -637,11 +624,11 @@ xfs_write(
ssize_t ret = 0, error = 0; ssize_t ret = 0, error = 0;
xfs_fsize_t isize, new_size; xfs_fsize_t isize, new_size;
xfs_iocore_t *io; xfs_iocore_t *io;
vnode_t *vp; bhv_vnode_t *vp;
unsigned long seg; unsigned long seg;
int iolock; int iolock;
int eventsent = 0; int eventsent = 0;
vrwlock_t locktype; bhv_vrwlock_t locktype;
size_t ocount = 0, count; size_t ocount = 0, count;
loff_t pos; loff_t pos;
int need_i_mutex = 1, need_flush = 0; int need_i_mutex = 1, need_flush = 0;
@ -679,11 +666,11 @@ xfs_write(
io = &xip->i_iocore; io = &xip->i_iocore;
mp = io->io_mount; mp = io->io_mount;
vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return -EIO; return -EIO;
fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
if (ioflags & IO_ISDIRECT) { if (ioflags & IO_ISDIRECT) {
xfs_buftarg_t *target = xfs_buftarg_t *target =
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@ -814,7 +801,7 @@ retry:
if (need_flush) { if (need_flush) {
xfs_inval_cached_trace(io, pos, -1, xfs_inval_cached_trace(io, pos, -1,
ctooff(offtoct(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); -1, FI_REMAPF_LOCKED);
} }
@ -903,79 +890,9 @@ retry:
/* Handle various SYNC-type writes */ /* Handle various SYNC-type writes */
if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
/* error = xfs_write_sync_logforce(mp, xip);
* If we're treating this as O_DSYNC and we have not updated the if (error)
* size, force the log. goto out_unlock_internal;
*/
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;
}
xfs_rwunlock(bdp, locktype); xfs_rwunlock(bdp, locktype);
if (need_i_mutex) if (need_i_mutex)

View File

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

View File

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

View File

@ -105,7 +105,7 @@ struct block_device;
extern __uint64_t xfs_max_file_offset(unsigned int); 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_inode(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *); extern void xfs_flush_device(struct xfs_inode *);

View File

@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = {
&sysctl_intvec, NULL, &sysctl_intvec, NULL,
&xfs_params.rotorstep.min, &xfs_params.rotorstep.max}, &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 */ /* please keep this the last entry */
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
{XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2005 Silicon Graphics, Inc. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -21,42 +21,40 @@
#include <linux/vfs.h> #include <linux/vfs.h>
#include "xfs_fs.h" #include "xfs_fs.h"
struct bhv_vfs;
struct bhv_vnode;
struct fid; struct fid;
struct vfs;
struct cred; struct cred;
struct vnode;
struct kstatfs;
struct seq_file; struct seq_file;
struct super_block; struct super_block;
struct xfs_mount_args; 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 list_head w_list;
struct vfs *w_vfs; struct bhv_vfs *w_vfs;
void *w_data; /* syncer routine argument */ void *w_data; /* syncer routine argument */
void (*w_syncer)(struct vfs *, void *); void (*w_syncer)(struct bhv_vfs *, void *);
} vfs_sync_work_t; } bhv_vfs_sync_work_t;
typedef struct vfs { typedef struct bhv_vfs {
u_int vfs_flag; /* flags */ u_int vfs_flag; /* flags */
xfs_fsid_t vfs_fsid; /* file system ID */ xfs_fsid_t vfs_fsid; /* file system ID */
xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */ xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
bhv_head_t vfs_bh; /* head of vfs behavior chain */ bhv_head_t vfs_bh; /* head of vfs behavior chain */
struct super_block *vfs_super; /* generic superblock pointer */ struct super_block *vfs_super; /* generic superblock pointer */
struct task_struct *vfs_sync_task; /* generalised sync thread */ 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 */ struct list_head vfs_sync_list; /* sync thread work item list */
spinlock_t vfs_sync_lock; /* work item list lock */ 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; 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 bhv_vfs *)BHV_VOBJ(bdp) )
#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
#define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) )
#define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) )
#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh ) #define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) ) #define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
@ -71,7 +69,7 @@ typedef enum {
VFS_BHV_QM, /* quota manager */ VFS_BHV_QM, /* quota manager */
VFS_BHV_IO, /* IO path */ VFS_BHV_IO, /* IO path */
VFS_BHV_END /* housekeeping end-of-range */ VFS_BHV_END /* housekeeping end-of-range */
} vfs_bhv_t; } bhv_vfs_type_t;
#define VFS_POSITION_XFS (BHV_POSITION_BASE) #define VFS_POSITION_XFS (BHV_POSITION_BASE)
#define VFS_POSITION_DM (VFS_POSITION_BASE+10) #define VFS_POSITION_DM (VFS_POSITION_BASE+10)
@ -81,8 +79,9 @@ typedef enum {
#define VFS_RDONLY 0x0001 /* read-only vfs */ #define VFS_RDONLY 0x0001 /* read-only vfs */
#define VFS_GRPID 0x0002 /* group-ID assigned from directory */ #define VFS_GRPID 0x0002 /* group-ID assigned from directory */
#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ #define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */ #define VFS_UMOUNT 0x0008 /* unmount in progress */
#define VFS_END 0x0008 /* max flag */ #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_ATTR 0x0001 /* sync attributes */
#define SYNC_CLOSE 0x0002 /* close file system down */ #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_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ #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 *, typedef int (*vfs_mount_t)(bhv_desc_t *,
struct xfs_mount_args *, struct cred *); 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_unmount_t)(bhv_desc_t *, int, struct cred *);
typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
struct xfs_mount_args *); struct xfs_mount_args *);
typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **); typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct 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_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_dmapiops_t)(bhv_desc_t *, caddr_t);
typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
typedef void (*vfs_init_vnode_t)(bhv_desc_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_force_shutdown_t)(bhv_desc_t *, int, char *, int);
typedef void (*vfs_freeze_t)(bhv_desc_t *); typedef void (*vfs_freeze_t)(bhv_desc_t *);
typedef struct vfsops { typedef struct bhv_vfsops {
bhv_position_t vf_position; /* behavior chain position */ bhv_position_t vf_position; /* behavior chain position */
vfs_mount_t vfs_mount; /* mount file system */ vfs_mount_t vfs_mount; /* mount file system */
vfs_parseargs_t vfs_parseargs; /* parse mount options */ 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_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */ 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 VFSHEAD(v) ((v)->vfs_bh.bh_first)
#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr)) #define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f)) #define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m)) #define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
#define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr)) #define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args)) #define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp)) #define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp)) #define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr)) #define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
#define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp)) #define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
#define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p)) #define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
#define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p)) #define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
#define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) ) #define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
#define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) ) #define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
#define VFS_FREEZE(v) ( vfs_freeze(VHEAD(v)) ) #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 bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f)) #define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m)) #define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr)) #define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args)) #define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp)) #define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp)) #define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr)) #define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp)) #define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
#define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p)) #define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p)) #define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
#define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) ) #define bhv_next_vfs_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 bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
#define PVFS_FREEZE(b) ( vfs_freeze(b) ) #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_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_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
extern int vfs_showargs(bhv_desc_t *, struct seq_file *); extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
extern int vfs_unmount(bhv_desc_t *, int, struct cred *); 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_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
extern int vfs_root(bhv_desc_t *, struct vnode **); extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct 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_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_dmapiops(bhv_desc_t *, caddr_t);
extern int vfs_quotactl(bhv_desc_t *, int, int, 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_force_shutdown(bhv_desc_t *, int, char *, int);
extern void vfs_freeze(bhv_desc_t *); extern void vfs_freeze(bhv_desc_t *);
typedef struct bhv_vfsops { #define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
struct vfsops bhv_common; #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; 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_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_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_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL ) #define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
extern vfs_t *vfs_allocate(struct super_block *); extern bhv_vfs_t *vfs_allocate(struct super_block *);
extern vfs_t *vfs_from_sb(struct super_block *); extern bhv_vfs_t *vfs_from_sb(struct super_block *);
extern void vfs_deallocate(vfs_t *); extern void vfs_deallocate(bhv_vfs_t *);
extern void vfs_insertops(vfs_t *, bhv_vfsops_t *); extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
extern void bhv_insert_all_vfsops(struct vfs *); extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
extern void bhv_remove_all_vfsops(struct vfs *, int);
extern void bhv_remove_vfsops(struct vfs *, int);
#define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen) extern void bhv_insert_all_vfsops(struct bhv_vfs *);
#define fs_check_frozen(vfsp, level) \ extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
vfs_check_frozen(vfsp->vfs_super, level); extern void bhv_remove_vfsops(struct bhv_vfs *, int);
#endif /* __XFS_VFS_H__ */ #endif /* __XFS_VFS_H__ */

View File

@ -39,7 +39,7 @@ vn_init(void)
void void
vn_iowait( vn_iowait(
struct vnode *vp) bhv_vnode_t *vp)
{ {
wait_queue_head_t *wq = vptosync(vp); wait_queue_head_t *wq = vptosync(vp);
@ -48,17 +48,33 @@ vn_iowait(
void void
vn_iowake( vn_iowake(
struct vnode *vp) bhv_vnode_t *vp)
{ {
if (atomic_dec_and_test(&vp->v_iocount)) if (atomic_dec_and_test(&vp->v_iocount))
wake_up(vptosync(vp)); 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( vn_initialize(
struct inode *inode) 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_active);
XFS_STATS_INC(vn_alloc); XFS_STATS_INC(vn_alloc);
@ -94,8 +110,8 @@ vn_initialize(
*/ */
void void
vn_revalidate_core( vn_revalidate_core(
struct vnode *vp, bhv_vnode_t *vp,
vattr_t *vap) bhv_vattr_t *vap)
{ {
struct inode *inode = vn_to_inode(vp); struct inode *inode = vn_to_inode(vp);
@ -130,14 +146,14 @@ vn_revalidate_core(
*/ */
int int
__vn_revalidate( __vn_revalidate(
struct vnode *vp, bhv_vnode_t *vp,
struct vattr *vattr) bhv_vattr_t *vattr)
{ {
int error; int error;
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; 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)) { if (likely(!error)) {
vn_revalidate_core(vp, vattr); vn_revalidate_core(vp, vattr);
VUNMODIFY(vp); VUNMODIFY(vp);
@ -147,9 +163,9 @@ __vn_revalidate(
int int
vn_revalidate( vn_revalidate(
struct vnode *vp) bhv_vnode_t *vp)
{ {
vattr_t vattr; bhv_vattr_t vattr;
return __vn_revalidate(vp, &vattr); return __vn_revalidate(vp, &vattr);
} }
@ -157,9 +173,9 @@ vn_revalidate(
/* /*
* Add a reference to a referenced vnode. * Add a reference to a referenced vnode.
*/ */
struct vnode * bhv_vnode_t *
vn_hold( vn_hold(
struct vnode *vp) bhv_vnode_t *vp)
{ {
struct inode *inode; struct inode *inode;
@ -192,31 +208,31 @@ vn_hold(
* Vnode tracing code. * Vnode tracing code.
*/ */
void 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); KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
} }
void 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); KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
} }
void 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); KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
} }
void 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); KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
} }
void 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); KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
} }

View File

@ -14,57 +14,35 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write the Free Software Foundation, * along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * 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__ #ifndef __XFS_VNODE_H__
#define __XFS_VNODE_H__ #define __XFS_VNODE_H__
struct uio; struct uio;
struct file; struct file;
struct vattr; struct bhv_vfs;
struct bhv_vattr;
struct xfs_iomap; struct xfs_iomap;
struct attrlist_cursor_kern; struct attrlist_cursor_kern;
typedef struct dentry bhv_vname_t;
typedef __u64 bhv_vnumber_t;
typedef xfs_ino_t vnumber_t; typedef enum bhv_vflags {
typedef struct dentry vname_t; VMODIFIED = 0x08, /* XFS inode state possibly differs */
typedef bhv_head_t vn_bhv_head_t; /* to the Linux inode state. */
VTRUNCATED = 0x40, /* truncated down so flush-on-close */
} bhv_vflags_t;
/* /*
* MP locking protocols: * MP locking protocols:
* v_flag, v_vfsp VN_LOCK/VN_UNLOCK * v_flag, v_vfsp VN_LOCK/VN_UNLOCK
*/ */
typedef struct vnode { typedef struct bhv_vnode {
__u32 v_flag; /* vnode flags (see below) */ bhv_vflags_t v_flag; /* vnode flags (see above) */
struct vfs *v_vfsp; /* ptr to containing VFS */ bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
vnumber_t v_number; /* in-core vnode number */ bhv_vnumber_t v_number; /* in-core vnode number */
vn_bhv_head_t v_bh; /* behavior head */ bhv_head_t v_bh; /* behavior head */
spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
atomic_t v_iocount; /* outstanding I/O count */ atomic_t v_iocount; /* outstanding I/O count */
#ifdef XFS_VNODE_TRACE #ifdef XFS_VNODE_TRACE
@ -72,7 +50,7 @@ typedef struct vnode {
#endif #endif
struct inode v_inode; /* Linux inode */ struct inode v_inode; /* Linux inode */
/* inode MUST be last */ /* inode MUST be last */
} vnode_t; } bhv_vnode_t;
#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode) #define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
#define VN_ISREG(vp) S_ISREG((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_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
#define VN_ISBLK(vp) S_ISBLK((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_BASE BHV_POSITION_BASE /* chain bottom */
#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */ #define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */ #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. * 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(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(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(vp) ((bhv_head_t *)(&((vp)->v_bh)))
#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) #define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
@ -116,35 +91,29 @@ typedef enum {
/* /*
* Vnode to Linux inode mapping. * 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; return &vnode->v_inode;
} }
/* /*
* Vnode flags. * Values for the vop_rwlock/rwunlock flags parameter.
*/ */
#define VMODIFIED 0x8 /* XFS inode state possibly differs */ typedef enum bhv_vrwlock {
/* to the Linux inode state. */
/*
* Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
*/
typedef enum vrwlock {
VRWLOCK_NONE, VRWLOCK_NONE,
VRWLOCK_READ, VRWLOCK_READ,
VRWLOCK_WRITE, VRWLOCK_WRITE,
VRWLOCK_WRITE_DIRECT, VRWLOCK_WRITE_DIRECT,
VRWLOCK_TRY_READ, VRWLOCK_TRY_READ,
VRWLOCK_TRY_WRITE 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 * VN_INACTIVE_NOCACHE implies that the file system behavior
* has disassociated its state and bhv_desc_t from the vnode. * has disassociated its state and bhv_desc_t from the vnode.
*/ */
@ -152,18 +121,20 @@ typedef enum vrwlock {
#define VN_INACTIVE_NOCACHE 1 #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_FRLOCKS = 0,
VCHANGE_FLAGS_ENF_LOCKING = 1, VCHANGE_FLAGS_ENF_LOCKING = 1,
VCHANGE_FLAGS_TRUNCATED = 2, VCHANGE_FLAGS_TRUNCATED = 2,
VCHANGE_FLAGS_PAGE_DIRTY = 3, VCHANGE_FLAGS_PAGE_DIRTY = 3,
VCHANGE_FLAGS_IOEXCL_COUNT = 4 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_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 *, typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
const struct iovec *, unsigned int, const struct iovec *, unsigned int,
loff_t *, int, struct cred *); 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 *); struct cred *);
typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
int, unsigned int, void __user *); 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 *); 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 *); struct cred *);
typedef int (*vop_access_t)(bhv_desc_t *, 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 **, typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
int, vnode_t *, struct cred *); int, bhv_vnode_t *, struct cred *);
typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *, typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
vnode_t **, struct cred *); bhv_vnode_t **, struct cred *);
typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *); typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *, typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
struct cred *); struct cred *);
typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *, typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
struct cred *); bhv_vname_t *, struct cred *);
typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *, typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
vnode_t **, struct cred *); bhv_vnode_t **, struct cred *);
typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_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 *, typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
int *); int *);
typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *, typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
char *, vnode_t **, struct cred *); char *, bhv_vnode_t **, struct cred *);
typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
struct cred *); struct cred *);
typedef int (*vop_fsync_t)(bhv_desc_t *, 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_inactive_t)(bhv_desc_t *, struct cred *);
typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
typedef int (*vop_release_t)(bhv_desc_t *); typedef int (*vop_release_t)(bhv_desc_t *);
typedef int (*vop_rwlock_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 *, 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, typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
struct xfs_iomap *, int *); struct xfs_iomap *, int *);
typedef int (*vop_reclaim_t)(bhv_desc_t *); 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 *); int, struct cred *);
typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
struct attrlist_cursor_kern *, struct cred *); struct attrlist_cursor_kern *, struct cred *);
typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int); typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t); 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_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 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, 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 int (*vop_iflush_t)(bhv_desc_t *, int);
typedef struct vnodeops { typedef struct bhv_vnodeops {
bhv_position_t vn_position; /* position within behavior chain */ bhv_position_t vn_position; /* position within behavior chain */
vop_open_t vop_open; vop_open_t vop_open;
vop_close_t vop_close;
vop_read_t vop_read; vop_read_t vop_read;
vop_write_t vop_write; vop_write_t vop_write;
vop_sendfile_t vop_sendfile; vop_sendfile_t vop_sendfile;
@ -271,103 +243,80 @@ typedef struct vnodeops {
vop_pflushvp_t vop_flush_pages; vop_pflushvp_t vop_flush_pages;
vop_release_t vop_release; vop_release_t vop_release;
vop_iflush_t vop_iflush; 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 VNHEAD(vp) ((vp)->v_bh.bh_first)
#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \ #define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) #define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \ #define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \ #define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr) VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
#define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \ #define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr) VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
#define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \ #define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr) VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ #define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n) VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
#define VOP_OPEN(vp, cr, rv) \ #define bhv_vop_bmap(vp,of,sz,rw,b,n) \
rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr) VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
#define VOP_GETATTR(vp, vap, f, cr, rv) \ #define bhv_vop_getattr(vp, vap,f,cr) \
rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr) VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
#define VOP_SETATTR(vp, vap, f, cr, rv) \ #define bhv_vop_setattr(vp, vap,f,cr) \
rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr) VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
#define VOP_ACCESS(vp, mode, cr, rv) \ #define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr) #define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
#define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \ VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr) #define bhv_vop_create(dvp,d,vap,vpp,cr) \
#define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \ VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr) #define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
#define VOP_REMOVE(dvp,d,cr,rv) \ #define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr) #define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
#define VOP_LINK(tdvp,fvp,d,cr,rv) \ VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr) #define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
#define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \ VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr) #define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
#define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \ #define bhv_vop_readdir(vp,uiop,cr,eofp) \
rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr) VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
#define VOP_RMDIR(dp,d,cr,rv) \ #define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr) VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
#define VOP_READDIR(vp,uiop,cr,eofp,rv) \ #define bhv_vop_readlink(vp,uiop,fl,cr) \
rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp) VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \ #define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr) #define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
#define VOP_READLINK(vp,uiop,fl,cr,rv) \ #define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr) #define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
#define VOP_FSYNC(vp,f,cr,b,e,rv) \ #define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e) #define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
#define VOP_INACTIVE(vp, cr, rv) \ #define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr) #define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
#define VOP_RELEASE(vp, rv) \ VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
rv = _VOP_(vop_release, vp)((vp)->v_fbhv) #define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
#define VOP_FID2(vp, fidp, rv) \ #define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp) VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
#define VOP_RWLOCK(vp,i) \ #define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
(void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i) VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
#define VOP_RWLOCK_TRY(vp,i) \ #define bhv_vop_attr_remove(vp, name, flags, cred) \
_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i) VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
#define VOP_RWUNLOCK(vp,i) \ #define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
(void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i) VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
#define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \ #define bhv_vop_link_removed(vp, dvp, linkzero) \
rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr) VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
#define VOP_RECLAIM(vp, rv) \ #define bhv_vop_vnode_change(vp, cmd, val) \
rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv) VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \ #define bhv_vop_toss_pages(vp, first, last, fiopt) \
rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred) VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
#define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \ #define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred) VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
#define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \ #define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred) VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
#define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \ #define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred) VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
#define VOP_LINK_REMOVED(vp, dvp, linkzero) \ #define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
(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)
/* /*
* Flags for read/write calls - same values as IRIX * 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 */ #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_SYNC 1 /* wait for flush to complete */
#define FLUSH_INODE 2 /* flush the inode itself */ #define FLUSH_INODE 2 /* flush the inode itself */
@ -385,8 +334,7 @@ typedef struct vnodeops {
* this inode out to disk */ * this inode out to disk */
/* /*
* Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
* VOP_FLUSH_PAGES.
*/ */
#define FI_NONE 0 /* none */ #define FI_NONE 0 /* none */
#define FI_REMAPF 1 /* Do a remapf prior to the operation */ #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 * Vnode attributes. va_mask indicates those attributes the caller
* wants to set or extract. * wants to set or extract.
*/ */
typedef struct vattr { typedef struct bhv_vattr {
int va_mask; /* bit-mask of attributes present */ int va_mask; /* bit-mask of attributes present */
mode_t va_mode; /* file access mode and type */ mode_t va_mode; /* file access mode and type */
xfs_nlink_t va_nlink; /* number of references to file */ 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_nextents; /* number of extents in file */
u_long va_anextents; /* number of attr extents in file */ u_long va_anextents; /* number of attr extents in file */
prid_t va_projid; /* project id */ prid_t va_projid; /* project id */
} vattr_t; } bhv_vattr_t;
/* /*
* setattr or getattr attributes * setattr or getattr attributes
@ -492,29 +440,17 @@ typedef struct vattr {
(VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
extern void vn_init(void); 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 *);
/* extern void vn_iowait(struct bhv_vnode *vp);
* vnode_map structures _must_ match vn_epoch and vnode structure sizes. extern void vn_iowake(struct bhv_vnode *vp);
*/
typedef struct vnode_map {
vfs_t *v_vfsp;
vnumber_t v_number; /* in-core vnode number */
xfs_ino_t v_ino; /* inode # */
} vmap_t;
#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \ extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
(vmap).v_number = (vp)->v_number, \
(vmap).v_ino = (vp)->v_inode.i_ino; }
extern int vn_revalidate(struct vnode *); static inline int vn_count(struct bhv_vnode *vp)
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)
{ {
return atomic_read(&vn_to_inode(vp)->i_count); 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). * 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) #if defined(XFS_VNODE_TRACE)
#define VN_HOLD(vp) \ #define VN_HOLD(vp) \
@ -536,7 +472,7 @@ extern vnode_t *vn_hold(struct vnode *);
#define VN_RELE(vp) (iput(vn_to_inode(vp))) #define VN_RELE(vp) (iput(vn_to_inode(vp)))
#endif #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)); struct inode *inode = igrab(vn_to_inode(vp));
return inode ? vn_from_inode(inode) : NULL; 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_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s) #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); spin_lock(&vp->v_lock);
vp->v_flag |= flag; vp->v_flag |= flag;
spin_unlock(&vp->v_lock); 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); spin_lock(&vp->v_lock);
cleared = (vp->v_flag & flag);
vp->v_flag &= ~flag; vp->v_flag &= ~flag;
spin_unlock(&vp->v_lock); 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 * 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)); 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)); 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 * 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_sec = vp->v_inode.i_atime.tv_sec;
bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec; 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; *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; *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_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ #define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
PAGECACHE_TAG_DIRTY) PAGECACHE_TAG_DIRTY)
#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED) #define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
/* /*
* Flags to VOP_SETATTR/VOP_GETATTR. * Flags to vop_setattr/getattr.
*/ */
#define ATTR_UTIME 0x01 /* non-default utime(2) request */ #define ATTR_UTIME 0x01 /* non-default utime(2) request */
#define ATTR_DMI 0x08 /* invocation from a DMI function */ #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 */ #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_NOWAIT 0 /* asynchronous flush */
#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */ #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_REF 4
#define VNODE_KTRACE_RELE 5 #define VNODE_KTRACE_RELE 5
extern void vn_trace_entry(struct vnode *, const char *, inst_t *); extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
extern void vn_trace_exit(struct vnode *, const char *, inst_t *); extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
#define VN_TRACE(vp) \ #define VN_TRACE(vp) \
vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address) vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)

View File

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

View File

@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
*/ */
#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\ #define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\
(dqp)->dq_flags |= XFS_DQ_FLOCKED; } (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)); \ vsema(&((dqp)->q_flock)); \
(dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } (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( \ #define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \
&(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s) &(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_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2005 Silicon Graphics, Inc. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -24,7 +24,6 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_alloc.h" #include "xfs_alloc.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
@ -33,7 +32,6 @@
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -129,7 +127,7 @@ xfs_qm_parseargs(
return XFS_ERROR(EINVAL); 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) if (!error && !referenced)
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
return error; return error;
@ -140,9 +138,8 @@ xfs_qm_showargs(
struct bhv_desc *bhv, struct bhv_desc *bhv,
struct seq_file *m) struct seq_file *m)
{ {
struct vfs *vfsp = bhvtovfs(bhv); struct bhv_vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp); struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
if (mp->m_qflags & XFS_UQUOTA_ACCT) { if (mp->m_qflags & XFS_UQUOTA_ACCT) {
(mp->m_qflags & XFS_UQUOTA_ENFD) ? (mp->m_qflags & XFS_UQUOTA_ENFD) ?
@ -165,8 +162,7 @@ xfs_qm_showargs(
if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
seq_puts(m, "," MNTOPT_NOQUOTA); seq_puts(m, "," MNTOPT_NOQUOTA);
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
return error;
} }
STATIC int STATIC int
@ -175,14 +171,67 @@ xfs_qm_mount(
struct xfs_mount_args *args, struct xfs_mount_args *args,
struct cred *cr) struct cred *cr)
{ {
struct vfs *vfsp = bhvtovfs(bhv); struct bhv_vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp); struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error;
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
xfs_qm_mount_quotainit(mp, args->flags); xfs_qm_mount_quotainit(mp, args->flags);
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
return error; }
/*
* 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 STATIC int
@ -191,7 +240,7 @@ xfs_qm_syncall(
int flags, int flags,
cred_t *credp) cred_t *credp)
{ {
struct vfs *vfsp = bhvtovfs(bhv); struct bhv_vfs *vfsp = bhvtovfs(bhv);
struct xfs_mount *mp = XFS_VFSTOM(vfsp); struct xfs_mount *mp = XFS_VFSTOM(vfsp);
int error; int error;
@ -210,8 +259,7 @@ xfs_qm_syncall(
} }
} }
} }
PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error); return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
return error;
} }
STATIC int STATIC int
@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = {
.xfs_dqtrxops = &xfs_trans_dquot_ops, .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), BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
.vfs_parseargs = xfs_qm_parseargs, .vfs_parseargs = xfs_qm_parseargs,
.vfs_showargs = xfs_qm_showargs, .vfs_showargs = xfs_qm_showargs,
.vfs_mount = xfs_qm_mount, .vfs_mount = xfs_qm_mount,
.vfs_statvfs = xfs_qm_statvfs,
.vfs_sync = xfs_qm_syncall, .vfs_sync = xfs_qm_syncall,
.vfs_quotactl = xfs_qm_quotactl, }, .vfs_quotactl = xfs_qm_quotactl, },
}; };

View File

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

View File

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

View File

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

View File

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

View File

@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...)
__attribute__ ((format (printf, 2, 3))); __attribute__ ((format (printf, 2, 3)));
extern void assfail(char *expr, char *f, int l); 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) \ #define ASSERT_ALWAYS(expr) \
(unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))

View File

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

View File

@ -50,7 +50,7 @@ typedef struct xfs_acl {
#ifdef CONFIG_XFS_POSIX_ACL #ifdef CONFIG_XFS_POSIX_ACL
struct vattr; struct vattr;
struct vnode; struct bhv_vnode;
struct xfs_inode; struct xfs_inode;
extern struct kmem_zone *xfs_acl_zone; 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)) (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) #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_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_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
extern int xfs_acl_vhasacl_access(struct vnode *); extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
extern int xfs_acl_vhasacl_default(struct vnode *); extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
extern int xfs_acl_vset(struct vnode *, void *, size_t, int); extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
extern int xfs_acl_vget(struct vnode *, void *, size_t, int); extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
extern int xfs_acl_vremove(struct vnode *vp, int); extern int xfs_acl_vremove(struct bhv_vnode *, int);
#define _ACL_TYPE_ACCESS 1 #define _ACL_TYPE_ACCESS 1
#define _ACL_TYPE_DEFAULT 2 #define _ACL_TYPE_DEFAULT 2

View File

@ -24,14 +24,12 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist(
(pag->pagf_longest - delta) : (pag->pagf_longest - delta) :
(pag->pagf_flcount > 0 || pag->pagf_longest > 0); (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
if (args->minlen + args->alignment + args->minalignslop - 1 > longest || if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
(args->minleft && (!(flags & XFS_ALLOC_FLAG_FREEING) &&
(int)(pag->pagf_freeblks + pag->pagf_flcount - (int)(pag->pagf_freeblks + pag->pagf_flcount -
need - args->total) < need - args->total) <
(int)args->minleft)) { (int)args->minleft)) {
@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist(
longest = (longest > delta) ? (longest - delta) : longest = (longest > delta) ? (longest - delta) :
(be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
if (args->minlen + args->alignment + args->minalignslop - 1 > longest || if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
(args->minleft && (!(flags & XFS_ALLOC_FLAG_FREEING) &&
(int)(be32_to_cpu(agf->agf_freeblks) + (int)(be32_to_cpu(agf->agf_freeblks) +
be32_to_cpu(agf->agf_flcount) - need - args->total) < be32_to_cpu(agf->agf_flcount) - need - args->total) <
(int)args->minleft)) { (int)args->minleft)) {
@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist(
* the restrictions correctly. Can happen for free calls * the restrictions correctly. Can happen for free calls
* on a completely full ag. * 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; break;
}
/* /*
* Put each allocated block on the list. * Put each allocated block on the list.
*/ */
@ -2360,8 +2364,19 @@ xfs_alloc_vextent(
if (args->agno == sagno && if (args->agno == sagno &&
type == XFS_ALLOCTYPE_START_BNO) type == XFS_ALLOCTYPE_START_BNO)
args->type = XFS_ALLOCTYPE_THIS_AG; 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 * Reached the starting a.g., must either be done
* or switch to non-trylock mode. * or switch to non-trylock mode.
@ -2443,7 +2458,7 @@ xfs_free_extent(
args.minlen = args.minleft = args.minalignslop = 0; args.minlen = args.minleft = args.minalignslop = 0;
down_read(&args.mp->m_peraglock); down_read(&args.mp->m_peraglock);
args.pag = &args.mp->m_perag[args.agno]; 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; goto error0;
#ifdef DEBUG #ifdef DEBUG
ASSERT(args.agbp != NULL); ASSERT(args.agbp != NULL);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -25,6 +25,20 @@ struct xfs_inode;
struct xfs_mount; struct xfs_mount;
struct xfs_trans; 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". * List of extents to be free "later".
* The list is kept sorted on xbf_startblock. * The list is kept sorted on xbf_startblock.
@ -275,7 +289,9 @@ xfs_bmapi(
xfs_extlen_t total, /* total blocks needed */ xfs_extlen_t total, /* total blocks needed */
struct xfs_bmbt_irec *mval, /* output: map values */ struct xfs_bmbt_irec *mval, /* output: map values */
int *nmap, /* i/o: mval size/count */ 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. * Map file blocks to filesystem blocks, simple version.
@ -309,6 +325,8 @@ xfs_bunmapi(
xfs_fsblock_t *firstblock, /* first allocated block xfs_fsblock_t *firstblock, /* first allocated block
controls a.g. for allocs */ controls a.g. for allocs */
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 */
int *done); /* set if not done yet */ int *done); /* set if not done yet */
/* /*

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,6 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
@ -32,7 +31,6 @@
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -43,7 +41,6 @@
#include "xfs_bmap.h" #include "xfs_bmap.h"
#include "xfs_attr.h" #include "xfs_attr.h"
#include "xfs_attr_leaf.h" #include "xfs_attr_leaf.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h" #include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h" #include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h" #include "xfs_dir2_block.h"
@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state)
max = state->path.active - 1; max = state->path.active - 1;
ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || 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 */ addblk = &state->path.blk[max]; /* initial dummy value */
for (i = max; (i >= 0) && addblk; state->path.active--, i--) { 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 */ return(error); /* GROT: attr inconsistent */
addblk = newblk; addblk = newblk;
break; 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: case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
error = xfs_dir2_leafn_split(state, oldblk, newblk); error = xfs_dir2_leafn_split(state, oldblk, newblk);
if (error) if (error)
return 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)] - size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
(char *)oldroot); (char *)oldroot);
} else { } else {
ASSERT(XFS_DIR_IS_V2(mp));
ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
leaf = (xfs_dir2_leaf_t *)oldroot; leaf = (xfs_dir2_leaf_t *)oldroot;
size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - 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. * Set up the new root node.
*/ */
error = xfs_da_node_create(args, error = xfs_da_node_create(args,
args->whichfork == XFS_DATA_FORK && (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,
XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
if (error) if (error)
return(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); 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) || useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;
state->args->whichfork == XFS_ATTR_FORK);
newcount = 1 + useextra; newcount = 1 + useextra;
/* /*
* Do we have to split the node? * 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(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
ASSERT(newblk->blkno != 0); 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 && ASSERT(newblk->blkno >= mp->m_dirleafblk &&
newblk->blkno < mp->m_dirfreeblk); 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 ]; save_blk = &state->altpath.blk[ state->path.active-1 ];
ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
ASSERT(drop_blk->magic == XFS_ATTR_LEAF_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. * Walk back up the tree joining/deallocating as necessary.
@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state)
return(0); return(0);
xfs_attr_leaf_unbalance(state, drop_blk, save_blk); xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
break; 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: case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
error = xfs_dir2_leafn_toosmall(state, &action); error = xfs_dir2_leafn_toosmall(state, &action);
if (error) if (error)
return 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); ASSERT(bp != NULL);
blkinfo = bp->data; blkinfo = bp->data;
if (be16_to_cpu(oldroot->hdr.level) == 1) { 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); be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
} else { } else {
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); 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) if (count == 0)
return; return;
break; 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: case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
if (count == 0) if (count == 0)
return; 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 * Descend thru the B-tree searching each level for the right
* node to use, until the right hashval is found. * node to use, until the right hashval is found.
*/ */
if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;
blkno = state->mp->m_dirleafblk;
else
blkno = 0;
for (blk = &state->path.blk[0], state->path.active = 1; for (blk = &state->path.blk[0], state->path.active = 1;
state->path.active <= XFS_DA_NODE_MAXDEPTH; state->path.active <= XFS_DA_NODE_MAXDEPTH;
blk++, state->path.active++) { blk++, state->path.active++) {
@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
} }
curr = blk->bp->data; curr = blk->bp->data;
ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || 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); 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; blk->index = probe;
blkno = be32_to_cpu(btree->before); 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); blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
break; break;
} } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
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) {
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
break; break;
} }
@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
* next leaf and keep searching. * next leaf and keep searching.
*/ */
for (;;) { for (;;) {
if (blk->magic == XFS_DIR_LEAF_MAGIC) { if (blk->magic == XFS_DIR2_LEAFN_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));
retval = xfs_dir2_leafn_lookup_int(blk->bp, args, retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
&blk->index, state); &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; old_info = old_blk->bp->data;
new_info = new_blk->bp->data; new_info = new_blk->bp->data;
ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || 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); old_blk->magic == XFS_ATTR_LEAF_MAGIC);
ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
ASSERT(new_blk->magic == be16_to_cpu(new_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: case XFS_ATTR_LEAF_MAGIC:
before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
break; 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: case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
break; break;
case XFS_DA_NODE_MAGIC: 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; save_info = save_blk->bp->data;
drop_info = drop_blk->bp->data; drop_info = drop_blk->bp->data;
ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || 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); save_blk->magic == XFS_ATTR_LEAF_MAGIC);
ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
ASSERT(drop_blk->magic == be16_to_cpu(drop_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); ASSERT(blk->bp != NULL);
info = blk->bp->data; info = blk->bp->data;
ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || 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); be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
blk->magic = be16_to_cpu(info->magic); blk->magic = be16_to_cpu(info->magic);
if (blk->magic == XFS_DA_NODE_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, blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
NULL); NULL);
break; 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: case XFS_DIR2_LEAFN_MAGIC:
ASSERT(XFS_DIR_IS_V2(state->mp));
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
NULL); NULL);
break; break;
default: default:
ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
blk->magic == blk->magic == XFS_DIR2_LEAFN_MAGIC);
XFS_DIRX_LEAF_MAGIC(state->mp));
break; 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_bmbt_irec_t *mapp;
xfs_inode_t *dp; xfs_inode_t *dp;
int nmap, error, w, count, c, got, i, mapi; int nmap, error, w, count, c, got, i, mapi;
xfs_fsize_t size;
xfs_trans_t *tp; xfs_trans_t *tp;
xfs_mount_t *mp; 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. * 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; bno = mp->m_dirleafblk;
count = mp->m_dirblkfsbs; count = mp->m_dirblkfsbs;
} else { } 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. * 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; return error;
} if (w == XFS_DATA_FORK)
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
/* /*
* Try mapping it in one filesystem block. * 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_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
XFS_BMAPI_CONTIG, XFS_BMAPI_CONTIG,
args->firstblock, args->total, &map, &nmap, args->firstblock, args->total, &map, &nmap,
args->flist))) { args->flist, NULL))) {
return error; return error;
} }
ASSERT(nmap <= 1); 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_AFLAG(w)|XFS_BMAPI_WRITE|
XFS_BMAPI_METADATA, XFS_BMAPI_METADATA,
args->firstblock, args->total, args->firstblock, args->total,
&mapp[mapi], &nmap, args->flist))) { &mapp[mapi], &nmap, args->flist,
NULL))) {
kmem_free(mapp, sizeof(*mapp) * count); kmem_free(mapp, sizeof(*mapp) * count);
return error; return error;
} }
@ -1705,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
if (mapp != &map) if (mapp != &map)
kmem_free(mapp, sizeof(*mapp) * count); kmem_free(mapp, sizeof(*mapp) * count);
*new_blkno = (xfs_dablk_t)bno; *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; 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; int error, w, entno, level, dead_level;
xfs_da_blkinfo_t *dead_info, *sib_info; xfs_da_blkinfo_t *dead_info, *sib_info;
xfs_da_intnode_t *par_node, *dead_node; xfs_da_intnode_t *par_node, *dead_node;
xfs_dir_leafblock_t *dead_leaf;
xfs_dir2_leaf_t *dead_leaf2; xfs_dir2_leaf_t *dead_leaf2;
xfs_dahash_t dead_hash; 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; w = args->whichfork;
ASSERT(w == XFS_DATA_FORK); ASSERT(w == XFS_DATA_FORK);
mp = ip->i_mount; mp = ip->i_mount;
if (XFS_DIR_IS_V2(mp)) { lastoff = mp->m_dirfreeblk;
lastoff = mp->m_dirfreeblk; error = xfs_bmap_last_before(tp, ip, &lastoff, w);
error = xfs_bmap_last_before(tp, ip, &lastoff, w);
} else
error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
if (error) if (error)
return error; return error;
if (unlikely(lastoff == 0)) { 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. * Get values from the moved block.
*/ */
if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) { if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_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));
dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
dead_level = 0; dead_level = 0;
dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); 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); xfs_da_buf_done(sib_buf);
sib_buf = NULL; sib_buf = NULL;
} }
par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; par_blkno = mp->m_dirleafblk;
level = -1; level = -1;
/* /*
* Walk down the tree looking for the parent of the moved block. * 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; xfs_inode_t *dp;
int done, error, w, count; int done, error, w, count;
xfs_fileoff_t bno;
xfs_fsize_t size;
xfs_trans_t *tp; xfs_trans_t *tp;
xfs_mount_t *mp; 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; w = args->whichfork;
tp = args->trans; tp = args->trans;
mp = dp->i_mount; mp = dp->i_mount;
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) if (w == XFS_DATA_FORK)
count = mp->m_dirblkfsbs; count = mp->m_dirblkfsbs;
else else
count = 1; 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, if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
0, args->firstblock, args->flist, 0, args->firstblock, args->flist, NULL,
&done)) == ENOSPC) { &done)) == ENOSPC) {
if (w != XFS_DATA_FORK) if (w != XFS_DATA_FORK)
goto done; break;
if ((error = xfs_da_swap_lastblock(args, &dead_blkno, if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
&dead_buf))) &dead_buf)))
goto done; break;
} else if (error) } else {
goto done;
else
break; 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); xfs_da_binval(tp, dead_buf);
return error; return error;
} }
@ -2049,10 +1925,7 @@ xfs_da_do_buf(
xfs_dabuf_t *rbp; xfs_dabuf_t *rbp;
mp = dp->i_mount; mp = dp->i_mount;
if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;
nfsb = mp->m_dirblkfsbs;
else
nfsb = 1;
mappedbno = *mappedbnop; mappedbno = *mappedbnop;
/* /*
* Caller doesn't have a mapping. -2 means don't complain * Caller doesn't have a mapping. -2 means don't complain
@ -2086,7 +1959,7 @@ xfs_da_do_buf(
nfsb, nfsb,
XFS_BMAPI_METADATA | XFS_BMAPI_METADATA |
XFS_BMAPI_AFLAG(whichfork), XFS_BMAPI_AFLAG(whichfork),
NULL, 0, mapp, &nmap, NULL))) NULL, 0, mapp, &nmap, NULL, NULL)))
goto exit0; goto exit0;
} }
} else { } else {
@ -2198,7 +2071,6 @@ xfs_da_do_buf(
magic1 = be32_to_cpu(data->hdr.magic); magic1 = be32_to_cpu(data->hdr.magic);
if (unlikely( if (unlikely(
XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
(magic != XFS_DIR_LEAF_MAGIC) &&
(magic != XFS_ATTR_LEAF_MAGIC) && (magic != XFS_ATTR_LEAF_MAGIC) &&
(magic != XFS_DIR2_LEAF1_MAGIC) && (magic != XFS_DIR2_LEAF1_MAGIC) &&
(magic != XFS_DIR2_LEAFN_MAGIC) && (magic != XFS_DIR2_LEAFN_MAGIC) &&

View File

@ -36,14 +36,10 @@ struct zone;
* level in the Btree, and to identify which type of block this is. * 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_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_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single 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_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 { typedef struct xfs_da_blkinfo {
__be32 forw; /* previous block in list */ __be32 forw; /* previous block in list */
__be32 back; /* following block in list */ __be32 back; /* following block in list */

View File

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

View File

@ -48,6 +48,9 @@ typedef struct xfs_swapext
*/ */
int xfs_swapext(struct xfs_swapext __user *sx); 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 /* __KERNEL__ */
#endif /* __XFS_DFRAG_H__ */ #endif /* __XFS_DFRAG_H__ */

View File

@ -85,7 +85,6 @@ typedef struct xfs_dinode
union { union {
xfs_bmdr_block_t di_bmbt; /* btree root block */ xfs_bmdr_block_t di_bmbt; /* btree root block */
xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ 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 */ xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
char di_c[1]; /* local contents */ char di_c[1]; /* local contents */
xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ 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_NOSYMLINKS_BIT 10 /* disallow symlink creation */
#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ #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_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_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_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
#define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
#define XFS_DIFLAG_ANY \ #define XFS_DIFLAG_ANY \
(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
XFS_DIFLAG_EXTSZINHERIT) XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
#endif /* __XFS_DINODE_H__ */ #endif /* __XFS_DINODE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

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

View File

@ -22,7 +22,9 @@ struct uio;
struct xfs_dabuf; struct xfs_dabuf;
struct xfs_da_args; struct xfs_da_args;
struct xfs_dir2_put_args; struct xfs_dir2_put_args;
struct xfs_bmap_free;
struct xfs_inode; struct xfs_inode;
struct xfs_mount;
struct xfs_trans; struct xfs_trans;
/* /*
@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args {
} xfs_dir2_put_args_t; } 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, extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
xfs_dir2_db_t *dbp); xfs_dir2_db_t *dbp);

View File

@ -22,19 +22,16 @@
#include "xfs_inum.h" #include "xfs_inum.h"
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_da_btree.h" #include "xfs_da_btree.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
#include "xfs_inode.h" #include "xfs_inode.h"
#include "xfs_inode_item.h" #include "xfs_inode_item.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h" #include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h" #include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.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); int *entno);
static int xfs_dir2_block_sort(const void *a, const void *b); 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. * Add an entry to a block directory.
*/ */
@ -400,7 +409,7 @@ xfs_dir2_block_addname(
/* /*
* Create the new data entry. * Create the new data entry.
*/ */
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); dep->inumber = cpu_to_be64(args->inumber);
dep->namelen = args->namelen; dep->namelen = args->namelen;
memcpy(dep->name, args->name, args->namelen); memcpy(dep->name, args->name, args->namelen);
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 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, p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
ptr - (char *)block); ptr - (char *)block);
p.ino = INT_GET(dep->inumber, ARCH_CONVERT); p.ino = be64_to_cpu(dep->inumber);
#if XFS_BIG_INUMS #if XFS_BIG_INUMS
p.ino += mp->m_inoadd; p.ino += mp->m_inoadd;
#endif #endif
@ -626,7 +635,7 @@ xfs_dir2_block_lookup(
/* /*
* Fill in inode number, release the block. * 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); xfs_da_brelse(args->trans, bp);
return XFS_ERROR(EEXIST); return XFS_ERROR(EEXIST);
} }
@ -844,11 +853,11 @@ xfs_dir2_block_replace(
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); ((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. * 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_log_entry(args->trans, bp, dep);
xfs_dir2_data_check(dp, bp); xfs_dir2_data_check(dp, bp);
xfs_da_buf_done(bp); xfs_da_buf_done(bp);
@ -1130,7 +1139,7 @@ xfs_dir2_sf_to_block(
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)block + XFS_DIR2_DATA_DOT_OFFSET); ((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->namelen = 1;
dep->name[0] = '.'; dep->name[0] = '.';
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@ -1144,7 +1153,7 @@ xfs_dir2_sf_to_block(
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); ((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->namelen = 2;
dep->name[0] = dep->name[1] = '.'; dep->name[0] = dep->name[1] = '.';
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@ -1193,7 +1202,7 @@ xfs_dir2_sf_to_block(
* Copy a real entry. * Copy a real entry.
*/ */
dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); 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))); XFS_DIR2_SF_INUMBERP(sfep)));
dep->namelen = sfep->namelen; dep->namelen = sfep->namelen;
memcpy(dep->name, sfep->name, dep->namelen); memcpy(dep->name, sfep->name, dep->namelen);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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__ */

View File

@ -189,6 +189,6 @@ typedef enum {
#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) #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__ */ #endif /* __XFS_DMAPI_H__ */

View File

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

View File

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

View File

@ -23,7 +23,6 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_trans_priv.h" #include "xfs_trans_priv.h"
@ -293,6 +292,62 @@ xfs_efi_init(xfs_mount_t *mp,
return (efip); 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 * 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 * the given efi item. Each efd calls this with the number of

View File

@ -26,6 +26,24 @@ typedef struct xfs_extent {
xfs_extlen_t ext_len; xfs_extlen_t ext_len;
} xfs_extent_t; } 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 * 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 * 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_extent_t efi_extents[1]; /* array of extents to free */
} xfs_efi_log_format_t; } 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 * 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 * 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_extent_t efd_extents[1]; /* array of extents freed */
} xfs_efd_log_format_t; } 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__ #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_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 *, xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
uint); 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 *); void xfs_efi_item_free(xfs_efi_log_item_t *);
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */

View File

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

View File

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

View File

@ -24,14 +24,12 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -1174,6 +1172,9 @@ xfs_dilocate(
if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
ino != XFS_AGINO_TO_INO(mp, agno, agino)) { ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
#ifdef DEBUG #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) { if (agno >= mp->m_sb.sb_agcount) {
xfs_fs_cmn_err(CE_ALERT, mp, xfs_fs_cmn_err(CE_ALERT, mp,
"xfs_dilocate: agno (%d) >= " "xfs_dilocate: agno (%d) >= "

View File

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

View File

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

View File

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

View File

@ -102,9 +102,9 @@ typedef struct xfs_ifork {
#ifdef __KERNEL__ #ifdef __KERNEL__
struct bhv_desc; struct bhv_desc;
struct bhv_vnode;
struct cred; struct cred;
struct ktrace; struct ktrace;
struct vnode;
struct xfs_buf; struct xfs_buf;
struct xfs_bmap_free; struct xfs_bmap_free;
struct xfs_bmbt_irec; struct xfs_bmbt_irec;
@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *);
void xfs_chash_free(struct xfs_mount *); void xfs_chash_free(struct xfs_mount *);
xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
struct xfs_trans *); 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, int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
uint, uint, xfs_inode_t **, xfs_daddr_t); uint, uint, xfs_inode_t **, xfs_daddr_t);
void xfs_iput(xfs_inode_t *, uint); 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 *); xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
void xfs_lock_inodes(xfs_inode_t **, int, int, uint); 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 *); 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_ifork_zone;
extern struct kmem_zone *xfs_inode_zone; extern struct kmem_zone *xfs_inode_zone;
extern struct kmem_zone *xfs_ili_zone; extern struct kmem_zone *xfs_ili_zone;
extern struct vnodeops xfs_vnodeops;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */

View File

@ -25,7 +25,6 @@
#include "xfs_buf_item.h" #include "xfs_buf_item.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
@ -33,7 +32,6 @@
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -794,7 +792,7 @@ xfs_inode_item_pushbuf(
* inode flush completed and the inode was taken off the AIL. * inode flush completed and the inode was taken off the AIL.
* So, just get out. * 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_item.li_flags & XFS_LI_IN_AIL) == 0)) {
iip->ili_pushbuf_flag = 0; iip->ili_pushbuf_flag = 0;
xfs_iunlock(ip, XFS_ILOCK_SHARED); xfs_iunlock(ip, XFS_ILOCK_SHARED);
@ -816,7 +814,7 @@ xfs_inode_item_pushbuf(
* If not, we can flush it async. * If not, we can flush it async.
*/ */
dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) && dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
(valusema(&(ip->i_flock)) <= 0)); issemalocked(&(ip->i_flock)));
iip->ili_pushbuf_flag = 0; iip->ili_pushbuf_flag = 0;
xfs_iunlock(ip, XFS_ILOCK_SHARED); xfs_iunlock(ip, XFS_ILOCK_SHARED);
xfs_buftrace("INODE ITEM PUSH", bp); xfs_buftrace("INODE ITEM PUSH", bp);
@ -864,7 +862,7 @@ xfs_inode_item_push(
ip = iip->ili_inode; ip = iip->ili_inode;
ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); 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 * Since we were able to lock the inode's flush lock and
* we found it on the AIL, the inode must be dirty. This * 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); 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;
}

View File

@ -23,25 +23,6 @@
* log. The size of the inline data/extents/b-tree root to be logged * 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 * (if any) is indicated in the ilf_dsize field. Changes to this structure
* must be added on to the end. * 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 { typedef struct xfs_inode_log_format {
unsigned short ilf_type; /* inode log item type */ 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 */ int ilf_boffset; /* off of inode in buffer */
} xfs_inode_log_format_t; } xfs_inode_log_format_t;
/* Initial version shipped with IRIX 5.3-XFS */ typedef struct xfs_inode_log_format_32 {
typedef struct xfs_inode_log_format_v1 { unsigned short ilf_type; /* 16: inode log item type */
unsigned short ilf_type; /* inode log item type */ unsigned short ilf_size; /* 16: size of this item */
unsigned short ilf_size; /* size of this item */ uint ilf_fields; /* 32: flags for fields logged */
uint ilf_fields; /* flags for fields logged */ ushort ilf_asize; /* 32: size of attr d/ext/root */
uint ilf_dsize; /* size of data/ext/root */ ushort ilf_dsize; /* 32: size of data/ext/root */
xfs_ino_t ilf_ino; /* inode number */ xfs_ino_t ilf_ino; /* 64: inode number */
union { union {
xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/ xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
uuid_t ilfu_uuid; /* mount point value */ uuid_t ilfu_uuid; /* 128: mount point value */
} ilf_u; } 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. * 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_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_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
extern void xfs_iflush_abort(struct xfs_inode *); 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__ */ #endif /* __KERNEL__ */

View File

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

View File

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

View File

@ -24,14 +24,12 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -41,11 +39,6 @@
#include "xfs_error.h" #include "xfs_error.h"
#include "xfs_btree.h" #include "xfs_btree.h"
#ifndef HAVE_USERACC
#define useracc(ubuffer, size, flags, foo) (0)
#define unuseracc(ubuffer, size, flags)
#endif
STATIC int STATIC int
xfs_bulkstat_one_iget( xfs_bulkstat_one_iget(
xfs_mount_t *mp, /* mount point for filesystem */ 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_dinode_core_t *dic; /* dinode core info pointer */
xfs_inode_t *ip; /* incore inode pointer */ xfs_inode_t *ip; /* incore inode pointer */
vnode_t *vp; bhv_vnode_t *vp;
int error; int error;
error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); 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); (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
nimask = ~(nicluster - 1); nimask = ~(nicluster - 1);
nbcluster = nicluster >> mp->m_sb.sb_inopblog; 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. * Allocate a page-sized buffer for inode btree records.
* We could try allocating something smaller, but for normal * 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. * Done, we're either out of filesystem or space to put the data.
*/ */
kmem_free(irbuf, NBPC); kmem_free(irbuf, NBPC);
if (ubuffer)
unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
*ubcountp = ubelem; *ubcountp = ubelem;
if (agno >= mp->m_sb.sb_agcount) { if (agno >= mp->m_sb.sb_agcount) {
/* /*

View File

@ -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_IGET 0x1 /* Go through the buffer cache */
#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ #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. * Return stat information in bulk (by-inode) for the filesystem.

View File

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

View File

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

View File

@ -24,14 +24,12 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -196,7 +194,7 @@ xfs_mount_free(
kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
if (remove_bhv) { if (remove_bhv) {
struct vfs *vfsp = XFS_MTOVFS(mp); struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
bhv_remove_all_vfsops(vfsp, 0); bhv_remove_all_vfsops(vfsp, 0);
VFS_REMOVEBHV(vfsp, &mp->m_bhv); VFS_REMOVEBHV(vfsp, &mp->m_bhv);
@ -337,7 +335,7 @@ xfs_mount_validate_sb(
xfs_agnumber_t xfs_agnumber_t
xfs_initialize_perag( xfs_initialize_perag(
struct vfs *vfs, bhv_vfs_t *vfs,
xfs_mount_t *mp, xfs_mount_t *mp,
xfs_agnumber_t agcount) xfs_agnumber_t agcount)
{ {
@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
*/ */
int int
xfs_mountfs( xfs_mountfs(
vfs_t *vfsp, bhv_vfs_t *vfsp,
xfs_mount_t *mp, xfs_mount_t *mp,
int mfsi_flags) int mfsi_flags)
{ {
xfs_buf_t *bp; xfs_buf_t *bp;
xfs_sb_t *sbp = &(mp->m_sb); xfs_sb_t *sbp = &(mp->m_sb);
xfs_inode_t *rip; xfs_inode_t *rip;
vnode_t *rvp = NULL; bhv_vnode_t *rvp = NULL;
int readio_log, writeio_log; int readio_log, writeio_log;
xfs_daddr_t d; xfs_daddr_t d;
__uint64_t ret64; __uint64_t ret64;
@ -934,18 +932,7 @@ xfs_mountfs(
vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
mp->m_dmevmask = 0; /* not persistent; set after each mount */ mp->m_dmevmask = 0; /* not persistent; set after each mount */
/* xfs_dir_mount(mp);
* 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);
/* /*
* Initialize the attribute manager's entries. * Initialize the attribute manager's entries.
@ -1006,8 +993,9 @@ xfs_mountfs(
if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
cmn_err(CE_WARN, "XFS: corrupted root inode"); cmn_err(CE_WARN, "XFS: corrupted root inode");
prdev("Root inode %llu is not a directory", cmn_err(CE_WARN, "Device %s - root %llu is not a directory",
mp->m_ddev_targp, (unsigned long long)rip->i_ino); XFS_BUFTARG_NAME(mp->m_ddev_targp),
(unsigned long long)rip->i_ino);
xfs_iunlock(rip, XFS_ILOCK_EXCL); xfs_iunlock(rip, XFS_ILOCK_EXCL);
XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
mp); mp);
@ -1094,7 +1082,7 @@ xfs_mountfs(
int int
xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) 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) #if defined(DEBUG) || defined(INDUCE_IO_ERROR)
int64_t fsid; int64_t fsid;
#endif #endif
@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
xfs_trans_log_buf(tp, bp, first, last); 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 * 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 * 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; return 0;
case XFS_SBS_FDBLOCKS: 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); res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
if (delta > 0) { /* Putting blocks back */ 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; return 0;
case XFS_SBS_FREXTENTS: case XFS_SBS_FREXTENTS:
lcounter = (long long)mp->m_sb.sb_frextents; lcounter = (long long)mp->m_sb.sb_frextents;

View File

@ -53,8 +53,8 @@ typedef struct xfs_trans_reservations {
#else #else
struct cred; struct cred;
struct log; struct log;
struct vfs; struct bhv_vfs;
struct vnode; struct bhv_vnode;
struct xfs_mount_args; struct xfs_mount_args;
struct xfs_ihash; struct xfs_ihash;
struct xfs_chash; struct xfs_chash;
@ -63,9 +63,11 @@ struct xfs_perag;
struct xfs_iocore; struct xfs_iocore;
struct xfs_bmbt_irec; struct xfs_bmbt_irec;
struct xfs_bmap_free; struct xfs_bmap_free;
struct xfs_extdelta;
struct xfs_swapext;
extern struct vfsops xfs_vfsops; extern struct bhv_vfsops xfs_vfsops;
extern struct vnodeops xfs_vnodeops; extern struct bhv_vnodeops xfs_vnodeops;
#define AIL_LOCK_T lock_t #define AIL_LOCK_T lock_t
#define AIL_LOCKINIT(x,y) spinlock_init(x,y) #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. * Prototypes and functions for the Data Migration subsystem.
*/ */
typedef int (*xfs_send_data_t)(int, struct vnode *, typedef int (*xfs_send_data_t)(int, struct bhv_vnode *,
xfs_off_t, size_t, int, vrwlock_t *); xfs_off_t, size_t, int, bhv_vrwlock_t *);
typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); 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_destroy_t)(struct bhv_vnode *, dm_right_t);
typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *, typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *,
struct vnode *, struct bhv_vnode *,
dm_right_t, struct vnode *, dm_right_t, dm_right_t, struct bhv_vnode *, dm_right_t,
char *, char *, mode_t, int, int); 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); dm_right_t, mode_t, int, int);
typedef struct xfs_dmops { typedef struct xfs_dmops {
@ -188,13 +190,18 @@ typedef struct xfs_qmops {
* Prototypes and functions for I/O core modularization. * 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); struct xfs_mount_args *, int);
typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
xfs_fileoff_t, xfs_filblks_t, int, xfs_fileoff_t, xfs_filblks_t, int,
xfs_fsblock_t *, xfs_extlen_t, xfs_fsblock_t *, xfs_extlen_t,
struct xfs_bmbt_irec *, int *, 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_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
typedef int (*xfs_iomap_write_direct_t)( typedef int (*xfs_iomap_write_direct_t)(
void *, xfs_off_t, size_t, int, 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 int (*xfs_lock_nowait_t)(void *, uint);
typedef void (*xfs_unlk_t)(void *, unsigned int); typedef void (*xfs_unlk_t)(void *, unsigned int);
typedef xfs_fsize_t (*xfs_size_t)(void *); 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 { typedef struct xfs_ioops {
xfs_ioinit_t xfs_ioinit; xfs_ioinit_t xfs_ioinit;
xfs_bmapi_t xfs_bmapi_func; xfs_bmapi_t xfs_bmapi_func;
xfs_bunmapi_t xfs_bunmapi_func;
xfs_bmap_eof_t xfs_bmap_eof_func; xfs_bmap_eof_t xfs_bmap_eof_func;
xfs_iomap_write_direct_t xfs_iomap_write_direct; xfs_iomap_write_direct_t xfs_iomap_write_direct;
xfs_iomap_write_delay_t xfs_iomap_write_delay; xfs_iomap_write_delay_t xfs_iomap_write_delay;
@ -230,13 +240,17 @@ typedef struct xfs_ioops {
xfs_unlk_t xfs_unlock; xfs_unlk_t xfs_unlock;
xfs_size_t xfs_size_func; xfs_size_t xfs_size_func;
xfs_iodone_t xfs_iodone; xfs_iodone_t xfs_iodone;
xfs_swap_extents_t xfs_swap_extents_func;
} xfs_ioops_t; } xfs_ioops_t;
#define XFS_IOINIT(vfsp, args, flags) \ #define XFS_IOINIT(vfsp, args, flags) \
(*(mp)->m_io_ops.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) \ (*(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) \ #define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
(*(mp)->m_io_ops.xfs_bmap_eof_func) \ (*(mp)->m_io_ops.xfs_bmap_eof_func) \
((io)->io_obj, endoff, whichfork, eof) ((io)->io_obj, endoff, whichfork, eof)
@ -266,6 +280,9 @@ typedef struct xfs_ioops {
(*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
#define XFS_IODONE(vfsp) \ #define XFS_IODONE(vfsp) \
(*(mp)->m_io_ops.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 #ifdef HAVE_PERCPU_SB
@ -386,8 +403,6 @@ typedef struct xfs_mount {
__uint8_t m_inode_quiesce;/* call quiesce on new inodes. __uint8_t m_inode_quiesce;/* call quiesce on new inodes.
field governed by m_ilock */ field governed by m_ilock */
__uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ __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_dirblksize; /* directory block sz--bytes */
int m_dirblkfsbs; /* directory block sz--fsbs */ int m_dirblkfsbs; /* directory block sz--fsbs */
xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ 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_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
#define xfs_force_shutdown(m,f) \ #define xfs_force_shutdown(m,f) \
VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__) bhv_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 */
/* /*
* Flags for xfs_mountfs * Flags for xfs_mountfs
@ -521,7 +527,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
* Macros for getting from mount to vfs and back. * Macros for getting from mount to vfs and back.
*/ */
#define XFS_MTOVFS(mp) xfs_mtovfs(mp) #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); 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) #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)); 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 xfs_mount_t *xfs_mount_init(void);
extern void xfs_mod_sb(xfs_trans_t *, __int64_t); extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); 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 void xfs_mountfs_check_barriers(xfs_mount_t *mp);
extern int xfs_unmountfs(xfs_mount_t *, struct cred *); 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 void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
extern int xfs_syncsub(xfs_mount_t *, int, int, int *); extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
extern int xfs_sync_inodes(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); xfs_agnumber_t);
extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);

View File

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

View File

@ -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_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
extern int xfs_mount_reset_sbqflags(struct xfs_mount *); extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
extern struct bhv_vfsops xfs_qmops; extern struct bhv_module_vfsops xfs_qmops;
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -24,14 +24,12 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_dir.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h" #include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h" #include "xfs_ialloc_btree.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h" #include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h" #include "xfs_attr_sf.h"
#include "xfs_dinode.h" #include "xfs_dinode.h"
@ -91,6 +89,90 @@ xfs_write_clear_setuid(
return 0; 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 * Force a shutdown of the filesystem instantly while keeping
* the filesystem consistent. We don't do an unmount here; just shutdown * the filesystem consistent. We don't do an unmount here; just shutdown
@ -109,12 +191,12 @@ xfs_do_force_shutdown(
xfs_mount_t *mp; xfs_mount_t *mp;
mp = XFS_BHVTOM(bdp); mp = XFS_BHVTOM(bdp);
logerror = flags & XFS_LOG_IO_ERROR; logerror = flags & SHUTDOWN_LOG_IO_ERROR;
if (!(flags & XFS_FORCE_UMOUNT)) { if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
cmn_err(CE_NOTE, cmn_err(CE_NOTE, "xfs_force_shutdown(%s,0x%x) called from "
"xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p", "line %d of file %s. Return address = 0x%p",
mp->m_fsname,flags,lnnum,fname,__return_address); mp->m_fsname, flags, lnnum, fname, __return_address);
} }
/* /*
* No need to duplicate efforts. * 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 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
* queue up anybody new on the log reservations, and wakes up * queue up anybody new on the log reservations, and wakes up
* everybody who's sleeping on log reservations and tells * everybody who's sleeping on log reservations to tell them
* them the bad news. * the bad news.
*/ */
if (xfs_log_force_umount(mp, logerror)) if (xfs_log_force_umount(mp, logerror))
return; return;
if (flags & XFS_CORRUPT_INCORE) { if (flags & SHUTDOWN_CORRUPT_INCORE) {
xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp, xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
"Corruption of in-memory data detected. Shutting down filesystem: %s", "Corruption of in-memory data detected. Shutting down filesystem: %s",
mp->m_fsname); mp->m_fsname);
if (XFS_ERRLEVEL_HIGH <= xfs_error_level) { if (XFS_ERRLEVEL_HIGH <= xfs_error_level) {
xfs_stack_trace(); xfs_stack_trace();
} }
} else if (!(flags & XFS_FORCE_UMOUNT)) { } else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
if (logerror) { if (logerror) {
xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp, 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); 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, 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); mp->m_fsname);
} }
} }
if (!(flags & XFS_FORCE_UMOUNT)) { if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
cmn_err(CE_ALERT, cmn_err(CE_ALERT, "Please umount the filesystem, "
"Please umount the filesystem, and rectify the problem(s)"); "and rectify the problem(s)");
} }
} }
@ -335,7 +421,7 @@ xfs_bwrite(
* from bwrite and we could be tracing a buffer that has * from bwrite and we could be tracing a buffer that has
* been reused. * been reused.
*/ */
xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
} }
return (error); return (error);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. * Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved. * All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or * 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. * Prototypes for functions in xfs_rw.c.
*/ */
extern int xfs_write_clear_setuid(struct xfs_inode *ip); 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_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
extern int xfs_bioerror(struct xfs_buf *bp); extern int xfs_bioerror(struct xfs_buf *bp);
extern int xfs_bioerror_relse(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. * Prototypes for functions in xfs_vnodeops.c.
*/ */
extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock); extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock); extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp); 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, 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); 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, extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,

View File

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

View File

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

View File

@ -22,7 +22,6 @@
#include "xfs_inum.h" #include "xfs_inum.h"
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_dir.h"
#include "xfs_dmapi.h" #include "xfs_dmapi.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_trans_priv.h" #include "xfs_trans_priv.h"
@ -363,9 +362,10 @@ xfs_trans_delete_ail(
AIL_UNLOCK(mp, s); AIL_UNLOCK(mp, s);
else { else {
xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, 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); AIL_UNLOCK(mp, s);
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More