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:
commit
52ab3f3dc7
|
@ -3191,7 +3191,7 @@ XFS FILESYSTEM
|
|||
P: Silicon Graphics Inc
|
||||
M: xfs-masters@oss.sgi.com
|
||||
M: nathans@sgi.com
|
||||
L: linux-xfs@oss.sgi.com
|
||||
L: xfs@oss.sgi.com
|
||||
W: http://oss.sgi.com/projects/xfs
|
||||
S: Supported
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
config XFS_FS
|
||||
tristate "XFS filesystem support"
|
||||
select EXPORTFS if NFSD!=n
|
||||
help
|
||||
XFS is a high performance journaling filesystem which originated
|
||||
on the SGI IRIX platform. It is completely multi-threaded, can
|
||||
|
@ -18,11 +17,6 @@ config XFS_FS
|
|||
system of your root partition is compiled as a module, you'll need
|
||||
to use an initial ramdisk (initrd) to boot.
|
||||
|
||||
config XFS_EXPORT
|
||||
bool
|
||||
depends on XFS_FS && EXPORTFS
|
||||
default y
|
||||
|
||||
config XFS_QUOTA
|
||||
bool "XFS Quota support"
|
||||
depends on XFS_FS
|
||||
|
@ -65,18 +59,19 @@ config XFS_POSIX_ACL
|
|||
If you don't know what Access Control Lists are, say N.
|
||||
|
||||
config XFS_RT
|
||||
bool "XFS Realtime support (EXPERIMENTAL)"
|
||||
depends on XFS_FS && EXPERIMENTAL
|
||||
bool "XFS Realtime subvolume support"
|
||||
depends on XFS_FS
|
||||
help
|
||||
If you say Y here you will be able to mount and use XFS filesystems
|
||||
which contain a realtime subvolume. The realtime subvolume is a
|
||||
separate area of disk space where only file data is stored. The
|
||||
realtime subvolume is designed to provide very deterministic
|
||||
data rates suitable for media streaming applications.
|
||||
separate area of disk space where only file data is stored. It was
|
||||
originally designed to provide deterministic data rates suitable
|
||||
for media streaming applications, but is also useful as a generic
|
||||
mechanism for ensuring data and metadata/log I/Os are completely
|
||||
separated. Regular file I/Os are isolated to a separate device
|
||||
from all other requests, and this can be done quite transparently
|
||||
to applications via the inherit-realtime directory inode flag.
|
||||
|
||||
See the xfs man page in section 5 for a bit more information.
|
||||
|
||||
This feature is unsupported at this time, is not yet fully
|
||||
functional, and may cause serious problems.
|
||||
See the xfs man page in section 5 for additional information.
|
||||
|
||||
If unsure, say N.
|
||||
|
|
|
@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
|
|||
xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
|
||||
xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
|
||||
xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
|
||||
xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o
|
||||
|
||||
|
||||
xfs-y += xfs_alloc.o \
|
||||
|
@ -73,14 +72,12 @@ xfs-y += xfs_alloc.o \
|
|||
xfs_btree.o \
|
||||
xfs_buf_item.o \
|
||||
xfs_da_btree.o \
|
||||
xfs_dir.o \
|
||||
xfs_dir2.o \
|
||||
xfs_dir2_block.o \
|
||||
xfs_dir2_data.o \
|
||||
xfs_dir2_leaf.o \
|
||||
xfs_dir2_node.o \
|
||||
xfs_dir2_sf.o \
|
||||
xfs_dir_leaf.o \
|
||||
xfs_error.o \
|
||||
xfs_extfree_item.o \
|
||||
xfs_fsops.o \
|
||||
|
@ -117,6 +114,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
|
|||
kmem.o \
|
||||
xfs_aops.o \
|
||||
xfs_buf.o \
|
||||
xfs_export.o \
|
||||
xfs_file.o \
|
||||
xfs_fs_subr.o \
|
||||
xfs_globals.o \
|
||||
|
|
|
@ -22,42 +22,6 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
* Process flags handling
|
||||
*/
|
||||
|
||||
#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO)
|
||||
#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
|
||||
|
||||
#define PFLAGS_SET_NOIO() do { \
|
||||
current->flags |= PF_NOIO; \
|
||||
} while (0)
|
||||
|
||||
#define PFLAGS_CLEAR_NOIO() do { \
|
||||
current->flags &= ~PF_NOIO; \
|
||||
} while (0)
|
||||
|
||||
/* these could be nested, so we save state */
|
||||
#define PFLAGS_SET_FSTRANS(STATEP) do { \
|
||||
*(STATEP) = current->flags; \
|
||||
current->flags |= PF_FSTRANS; \
|
||||
} while (0)
|
||||
|
||||
#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
|
||||
*(STATEP) = current->flags; \
|
||||
current->flags &= ~PF_FSTRANS; \
|
||||
} while (0)
|
||||
|
||||
/* Restore the PF_FSTRANS state to what was saved in STATEP */
|
||||
#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
|
||||
current->flags = ((current->flags & ~PF_FSTRANS) | \
|
||||
(*(STATEP) & PF_FSTRANS)); \
|
||||
} while (0)
|
||||
|
||||
#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
|
||||
*(NSTATEP) = *(OSTATEP); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* General memory allocation interfaces
|
||||
*/
|
||||
|
@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags)
|
|||
lflags = GFP_ATOMIC | __GFP_NOWARN;
|
||||
} else {
|
||||
lflags = GFP_KERNEL | __GFP_NOWARN;
|
||||
if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
|
||||
if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
|
||||
lflags &= ~__GFP_FS;
|
||||
}
|
||||
return lflags;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -28,7 +28,7 @@ typedef struct {
|
|||
} mrlock_t;
|
||||
|
||||
#define mrinit(mrp, name) \
|
||||
( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) )
|
||||
do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
|
||||
#define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
|
||||
#define mrfree(mrp) do { } while (0)
|
||||
#define mraccess(mrp) mraccessf(mrp, 0)
|
||||
|
|
|
@ -34,20 +34,21 @@ typedef struct semaphore sema_t;
|
|||
#define initnsema(sp, val, name) sema_init(sp, val)
|
||||
#define psema(sp, b) down(sp)
|
||||
#define vsema(sp) up(sp)
|
||||
#define valusema(sp) (atomic_read(&(sp)->count))
|
||||
#define freesema(sema)
|
||||
#define freesema(sema) do { } while (0)
|
||||
|
||||
static inline int issemalocked(sema_t *sp)
|
||||
{
|
||||
return down_trylock(sp) || (up(sp), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map cpsema (try to get the sema) to down_trylock. We need to switch
|
||||
* the return values since cpsema returns 1 (acquired) 0 (failed) and
|
||||
* down_trylock returns the reverse 0 (acquired) 1 (failed).
|
||||
*/
|
||||
|
||||
#define cpsema(sp) (down_trylock(sp) ? 0 : 1)
|
||||
|
||||
/*
|
||||
* Didn't do cvsema(sp). Not sure how to map this to up/down/...
|
||||
* It does a vsema if the values is < 0 other wise nothing.
|
||||
*/
|
||||
static inline int cpsema(sema_t *sp)
|
||||
{
|
||||
return down_trylock(sp) ? 0 : 1;
|
||||
}
|
||||
|
||||
#endif /* __XFS_SUPPORT_SEMA_H__ */
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -29,7 +28,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -76,7 +74,7 @@ xfs_page_trace(
|
|||
int mask)
|
||||
{
|
||||
xfs_inode_t *ip;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
loff_t isize = i_size_read(inode);
|
||||
loff_t offset = page_offset(page);
|
||||
int delalloc = -1, unmapped = -1, unwritten = -1;
|
||||
|
@ -136,9 +134,10 @@ xfs_destroy_ioend(
|
|||
|
||||
for (bh = ioend->io_buffer_head; bh; bh = next) {
|
||||
next = bh->b_private;
|
||||
bh->b_end_io(bh, ioend->io_uptodate);
|
||||
bh->b_end_io(bh, !ioend->io_error);
|
||||
}
|
||||
|
||||
if (unlikely(ioend->io_error))
|
||||
vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
|
||||
vn_iowake(ioend->io_vnode);
|
||||
mempool_free(ioend, xfs_ioend_pool);
|
||||
}
|
||||
|
@ -180,13 +179,12 @@ xfs_end_bio_unwritten(
|
|||
void *data)
|
||||
{
|
||||
xfs_ioend_t *ioend = data;
|
||||
vnode_t *vp = ioend->io_vnode;
|
||||
bhv_vnode_t *vp = ioend->io_vnode;
|
||||
xfs_off_t offset = ioend->io_offset;
|
||||
size_t size = ioend->io_size;
|
||||
int error;
|
||||
|
||||
if (ioend->io_uptodate)
|
||||
VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error);
|
||||
if (likely(!ioend->io_error))
|
||||
bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
|
@ -211,7 +209,7 @@ xfs_alloc_ioend(
|
|||
* all the I/O from calling the completion routine too early.
|
||||
*/
|
||||
atomic_set(&ioend->io_remaining, 1);
|
||||
ioend->io_uptodate = 1; /* cleared if any I/O fails */
|
||||
ioend->io_error = 0;
|
||||
ioend->io_list = NULL;
|
||||
ioend->io_type = type;
|
||||
ioend->io_vnode = vn_from_inode(inode);
|
||||
|
@ -239,10 +237,10 @@ xfs_map_blocks(
|
|||
xfs_iomap_t *mapp,
|
||||
int flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
int error, nmaps = 1;
|
||||
|
||||
VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error);
|
||||
error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps);
|
||||
if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
|
||||
VMODIFY(vp);
|
||||
return -error;
|
||||
|
@ -271,16 +269,14 @@ xfs_end_bio(
|
|||
if (bio->bi_size)
|
||||
return 1;
|
||||
|
||||
ASSERT(ioend);
|
||||
ASSERT(atomic_read(&bio->bi_cnt) >= 1);
|
||||
ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
|
||||
|
||||
/* Toss bio and pass work off to an xfsdatad thread */
|
||||
if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
|
||||
ioend->io_uptodate = 0;
|
||||
bio->bi_private = NULL;
|
||||
bio->bi_end_io = NULL;
|
||||
|
||||
bio_put(bio);
|
||||
|
||||
xfs_finish_ioend(ioend);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1127,7 +1123,7 @@ xfs_vm_writepage(
|
|||
* then mark the page dirty again and leave the page
|
||||
* as is.
|
||||
*/
|
||||
if (PFLAGS_TEST_FSTRANS() && need_trans)
|
||||
if (current_test_flags(PF_FSTRANS) && need_trans)
|
||||
goto out_fail;
|
||||
|
||||
/*
|
||||
|
@ -1158,6 +1154,18 @@ out_unlock:
|
|||
return error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_vm_writepages(
|
||||
struct address_space *mapping,
|
||||
struct writeback_control *wbc)
|
||||
{
|
||||
struct bhv_vnode *vp = vn_from_inode(mapping->host);
|
||||
|
||||
if (VN_TRUNC(vp))
|
||||
VUNTRUNCATE(vp);
|
||||
return generic_writepages(mapping, wbc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to move a page into cleanable state - and from there
|
||||
* to be released. Possibly the page is already clean. We always
|
||||
|
@ -1204,7 +1212,7 @@ xfs_vm_releasepage(
|
|||
/* If we are already inside a transaction or the thread cannot
|
||||
* do I/O, we cannot release this page.
|
||||
*/
|
||||
if (PFLAGS_TEST_FSTRANS())
|
||||
if (current_test_flags(PF_FSTRANS))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
@ -1231,7 +1239,7 @@ __xfs_get_blocks(
|
|||
int direct,
|
||||
bmapi_flags_t flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_iomap_t iomap;
|
||||
xfs_off_t offset;
|
||||
ssize_t size;
|
||||
|
@ -1241,8 +1249,8 @@ __xfs_get_blocks(
|
|||
offset = (xfs_off_t)iblock << inode->i_blkbits;
|
||||
ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
|
||||
size = bh_result->b_size;
|
||||
VOP_BMAP(vp, offset, size,
|
||||
create ? flags : BMAPI_READ, &iomap, &niomap, error);
|
||||
error = bhv_vop_bmap(vp, offset, size,
|
||||
create ? flags : BMAPI_READ, &iomap, &niomap);
|
||||
if (error)
|
||||
return -error;
|
||||
if (niomap == 0)
|
||||
|
@ -1370,13 +1378,13 @@ xfs_vm_direct_IO(
|
|||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_iomap_t iomap;
|
||||
int maps = 1;
|
||||
int error;
|
||||
ssize_t ret;
|
||||
|
||||
VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error);
|
||||
error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps);
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
|
@ -1409,14 +1417,12 @@ xfs_vm_bmap(
|
|||
sector_t block)
|
||||
{
|
||||
struct inode *inode = (struct inode *)mapping->host;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
|
||||
VOP_RWLOCK(vp, VRWLOCK_READ);
|
||||
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
|
||||
VOP_RWUNLOCK(vp, VRWLOCK_READ);
|
||||
bhv_vop_rwlock(vp, VRWLOCK_READ);
|
||||
bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
|
||||
bhv_vop_rwunlock(vp, VRWLOCK_READ);
|
||||
return generic_block_bmap(mapping, block, xfs_get_blocks);
|
||||
}
|
||||
|
||||
|
@ -1452,6 +1458,7 @@ struct address_space_operations xfs_address_space_operations = {
|
|||
.readpage = xfs_vm_readpage,
|
||||
.readpages = xfs_vm_readpages,
|
||||
.writepage = xfs_vm_writepage,
|
||||
.writepages = xfs_vm_writepages,
|
||||
.sync_page = block_sync_page,
|
||||
.releasepage = xfs_vm_releasepage,
|
||||
.invalidatepage = xfs_vm_invalidatepage,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2005-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -30,9 +30,9 @@ typedef void (*xfs_ioend_func_t)(void *);
|
|||
typedef struct xfs_ioend {
|
||||
struct xfs_ioend *io_list; /* next ioend in chain */
|
||||
unsigned int io_type; /* delalloc / unwritten */
|
||||
unsigned int io_uptodate; /* I/O status register */
|
||||
int io_error; /* I/O error code */
|
||||
atomic_t io_remaining; /* hold count */
|
||||
struct vnode *io_vnode; /* file being written to */
|
||||
struct bhv_vnode *io_vnode; /* file being written to */
|
||||
struct buffer_head *io_buffer_head;/* buffer linked list head */
|
||||
struct buffer_head *io_buffer_tail;/* buffer linked list tail */
|
||||
size_t io_size; /* size of the extent */
|
||||
|
@ -43,4 +43,4 @@ typedef struct xfs_ioend {
|
|||
extern struct address_space_operations xfs_address_space_operations;
|
||||
extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
|
||||
|
||||
#endif /* __XFS_IOPS_H__ */
|
||||
#endif /* __XFS_AOPS_H__ */
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "xfs_log.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_export.h"
|
||||
|
||||
|
@ -97,7 +96,7 @@ xfs_fs_encode_fh(
|
|||
int len;
|
||||
int is64 = 0;
|
||||
#if XFS_BIG_INUMS
|
||||
vfs_t *vfs = vfs_from_sb(inode->i_sb);
|
||||
bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb);
|
||||
|
||||
if (!(vfs->vfs_flag & VFS_32BITINODES)) {
|
||||
/* filesystem may contain 64bit inode numbers */
|
||||
|
@ -136,13 +135,13 @@ xfs_fs_get_dentry(
|
|||
struct super_block *sb,
|
||||
void *data)
|
||||
{
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
struct inode *inode;
|
||||
struct dentry *result;
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
bhv_vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_VGET(vfsp, &vp, (fid_t *)data, error);
|
||||
error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data);
|
||||
if (error || vp == NULL)
|
||||
return ERR_PTR(-ESTALE) ;
|
||||
|
||||
|
@ -160,12 +159,12 @@ xfs_fs_get_parent(
|
|||
struct dentry *child)
|
||||
{
|
||||
int error;
|
||||
vnode_t *vp, *cvp;
|
||||
bhv_vnode_t *vp, *cvp;
|
||||
struct dentry *parent;
|
||||
|
||||
cvp = NULL;
|
||||
vp = vn_from_inode(child->d_inode);
|
||||
VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
|
||||
error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
|
||||
if (unlikely(error))
|
||||
return ERR_PTR(-error);
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_alloc.h"
|
||||
#include "xfs_btree.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_inode.h"
|
||||
|
@ -58,15 +56,12 @@ __xfs_file_read(
|
|||
{
|
||||
struct iovec iov = {buf, count};
|
||||
struct file *file = iocb->ki_filp;
|
||||
vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
|
||||
|
||||
BUG_ON(iocb->ki_pos != pos);
|
||||
|
||||
if (unlikely(file->f_flags & O_DIRECT))
|
||||
ioflags |= IO_ISDIRECT;
|
||||
VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
|
@ -100,15 +95,12 @@ __xfs_file_write(
|
|||
struct iovec iov = {(void __user *)buf, count};
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
ssize_t rval;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
BUG_ON(iocb->ki_pos != pos);
|
||||
if (unlikely(file->f_flags & O_DIRECT))
|
||||
ioflags |= IO_ISDIRECT;
|
||||
|
||||
VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
|
@ -140,7 +132,7 @@ __xfs_file_readv(
|
|||
loff_t *ppos)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
struct kiocb kiocb;
|
||||
ssize_t rval;
|
||||
|
||||
|
@ -149,7 +141,8 @@ __xfs_file_readv(
|
|||
|
||||
if (unlikely(file->f_flags & O_DIRECT))
|
||||
ioflags |= IO_ISDIRECT;
|
||||
VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
|
||||
rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
|
||||
&kiocb.ki_pos, ioflags, NULL);
|
||||
|
||||
*ppos = kiocb.ki_pos;
|
||||
return rval;
|
||||
|
@ -184,7 +177,7 @@ __xfs_file_writev(
|
|||
loff_t *ppos)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
struct kiocb kiocb;
|
||||
ssize_t rval;
|
||||
|
||||
|
@ -193,7 +186,8 @@ __xfs_file_writev(
|
|||
if (unlikely(file->f_flags & O_DIRECT))
|
||||
ioflags |= IO_ISDIRECT;
|
||||
|
||||
VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
|
||||
rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
|
||||
&kiocb.ki_pos, ioflags, NULL);
|
||||
|
||||
*ppos = kiocb.ki_pos;
|
||||
return rval;
|
||||
|
@ -227,11 +221,8 @@ xfs_file_sendfile(
|
|||
read_actor_t actor,
|
||||
void *target)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
|
||||
filp, pos, 0, count, actor, target, NULL);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
|
@ -242,11 +233,8 @@ xfs_file_sendfile_invis(
|
|||
read_actor_t actor,
|
||||
void *target)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
|
||||
filp, pos, IO_INVIS, count, actor, target, NULL);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
|
@ -257,11 +245,8 @@ xfs_file_splice_read(
|
|||
size_t len,
|
||||
unsigned int flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
|
||||
infilp, ppos, pipe, len, flags, 0, NULL);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
|
@ -272,11 +257,9 @@ xfs_file_splice_read_invis(
|
|||
size_t len,
|
||||
unsigned int flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
|
||||
infilp, ppos, pipe, len, flags, IO_INVIS,
|
||||
NULL);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
|
@ -287,11 +270,8 @@ xfs_file_splice_write(
|
|||
size_t len,
|
||||
unsigned int flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
|
||||
pipe, outfilp, ppos, len, flags, 0, NULL);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
|
@ -302,11 +282,9 @@ xfs_file_splice_write_invis(
|
|||
size_t len,
|
||||
unsigned int flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval);
|
||||
return rval;
|
||||
return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
|
||||
pipe, outfilp, ppos, len, flags, IO_INVIS,
|
||||
NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -314,13 +292,17 @@ xfs_file_open(
|
|||
struct inode *inode,
|
||||
struct file *filp)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
|
||||
if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
|
||||
return -EFBIG;
|
||||
VOP_OPEN(vp, NULL, error);
|
||||
return -error;
|
||||
return -bhv_vop_open(vn_from_inode(inode), NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_file_close(
|
||||
struct file *filp)
|
||||
{
|
||||
return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
|
||||
file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -328,12 +310,11 @@ xfs_file_release(
|
|||
struct inode *inode,
|
||||
struct file *filp)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error = 0;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
if (vp)
|
||||
VOP_RELEASE(vp, error);
|
||||
return -error;
|
||||
return -bhv_vop_release(vp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -342,15 +323,14 @@ xfs_file_fsync(
|
|||
struct dentry *dentry,
|
||||
int datasync)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
int flags = FSYNC_WAIT;
|
||||
|
||||
if (datasync)
|
||||
flags |= FSYNC_DATA;
|
||||
VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error);
|
||||
return -error;
|
||||
if (VN_TRUNC(vp))
|
||||
VUNTRUNCATE(vp);
|
||||
return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
|
@ -361,16 +341,11 @@ xfs_vm_nopage(
|
|||
int *type)
|
||||
{
|
||||
struct inode *inode = area->vm_file->f_dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
|
||||
int error;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
|
||||
|
||||
error = XFS_SEND_MMAP(mp, area, 0);
|
||||
if (error)
|
||||
if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
|
||||
return NULL;
|
||||
|
||||
return filemap_nopage(area, address, type);
|
||||
}
|
||||
#endif /* CONFIG_XFS_DMAPI */
|
||||
|
@ -382,7 +357,7 @@ xfs_file_readdir(
|
|||
filldir_t filldir)
|
||||
{
|
||||
int error = 0;
|
||||
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
|
||||
uio_t uio;
|
||||
iovec_t iov;
|
||||
int eof = 0;
|
||||
|
@ -417,7 +392,7 @@ xfs_file_readdir(
|
|||
|
||||
start_offset = uio.uio_offset;
|
||||
|
||||
VOP_READDIR(vp, &uio, NULL, &eof, error);
|
||||
error = bhv_vop_readdir(vp, &uio, NULL, &eof);
|
||||
if ((uio.uio_offset == start_offset) || error) {
|
||||
size = 0;
|
||||
break;
|
||||
|
@ -456,38 +431,28 @@ xfs_file_mmap(
|
|||
struct file *filp,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct inode *ip = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(ip);
|
||||
vattr_t vattr;
|
||||
int error;
|
||||
|
||||
vma->vm_ops = &xfs_file_vm_ops;
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
|
||||
if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
|
||||
vma->vm_ops = &xfs_dmapi_file_vm_ops;
|
||||
}
|
||||
#endif /* CONFIG_XFS_DMAPI */
|
||||
|
||||
vattr.va_mask = XFS_AT_UPDATIME;
|
||||
VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, &vattr); /* update flags */
|
||||
file_accessed(filp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC long
|
||||
xfs_file_ioctl(
|
||||
struct file *filp,
|
||||
unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long p)
|
||||
{
|
||||
int error;
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error);
|
||||
error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
|
||||
VMODIFY(vp);
|
||||
|
||||
/* NOTE: some of the ioctl's return positive #'s as a
|
||||
|
@ -503,13 +468,13 @@ STATIC long
|
|||
xfs_file_ioctl_invis(
|
||||
struct file *filp,
|
||||
unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long p)
|
||||
{
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
|
||||
error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
|
||||
VMODIFY(vp);
|
||||
|
||||
/* NOTE: some of the ioctl's return positive #'s as a
|
||||
|
@ -528,7 +493,7 @@ xfs_vm_mprotect(
|
|||
struct vm_area_struct *vma,
|
||||
unsigned int newflags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
|
||||
int error = 0;
|
||||
|
||||
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
|
||||
|
@ -554,24 +519,19 @@ STATIC int
|
|||
xfs_file_open_exec(
|
||||
struct inode *inode)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
|
||||
int error = 0;
|
||||
xfs_inode_t *ip;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
|
||||
ip = xfs_vtoi(vp);
|
||||
if (!ip) {
|
||||
error = -EINVAL;
|
||||
goto open_exec_out;
|
||||
}
|
||||
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) {
|
||||
error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
|
||||
if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
|
||||
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
|
||||
xfs_inode_t *ip = xfs_vtoi(vp);
|
||||
|
||||
if (!ip)
|
||||
return -EINVAL;
|
||||
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
|
||||
return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
|
||||
0, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
open_exec_out:
|
||||
return error;
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_FOP_OPEN_EXEC */
|
||||
|
||||
|
@ -592,6 +552,7 @@ const struct file_operations xfs_file_operations = {
|
|||
#endif
|
||||
.mmap = xfs_file_mmap,
|
||||
.open = xfs_file_open,
|
||||
.flush = xfs_file_close,
|
||||
.release = xfs_file_release,
|
||||
.fsync = xfs_file_fsync,
|
||||
#ifdef HAVE_FOP_OPEN_EXEC
|
||||
|
@ -616,6 +577,7 @@ const struct file_operations xfs_invis_file_operations = {
|
|||
#endif
|
||||
.mmap = xfs_file_mmap,
|
||||
.open = xfs_file_open,
|
||||
.flush = xfs_file_close,
|
||||
.release = xfs_file_release,
|
||||
.fsync = xfs_file_fsync,
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -15,40 +15,12 @@
|
|||
* along with this program; if not, write the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "xfs.h"
|
||||
|
||||
/*
|
||||
* Stub for no-op vnode operations that return error status.
|
||||
*/
|
||||
int
|
||||
fs_noerr(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int fs_noerr(void) { return 0; }
|
||||
int fs_nosys(void) { return ENOSYS; }
|
||||
void fs_noval(void) { return; }
|
||||
|
||||
/*
|
||||
* Operation unsupported under this file system.
|
||||
*/
|
||||
int
|
||||
fs_nosys(void)
|
||||
{
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stub for inactive, strategy, and read/write lock/unlock. Does nothing.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
void
|
||||
fs_noval(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* vnode pcache layer for vnode_tosspages.
|
||||
* 'last' parameter unused but left in for IRIX compatibility
|
||||
*/
|
||||
void
|
||||
fs_tosspages(
|
||||
bhv_desc_t *bdp,
|
||||
|
@ -56,18 +28,13 @@ fs_tosspages(
|
|||
xfs_off_t last,
|
||||
int fiopt)
|
||||
{
|
||||
vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
|
||||
if (VN_CACHED(vp))
|
||||
truncate_inode_pages(ip->i_mapping, first);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* vnode pcache layer for vnode_flushinval_pages.
|
||||
* 'last' parameter unused but left in for IRIX compatibility
|
||||
*/
|
||||
void
|
||||
fs_flushinval_pages(
|
||||
bhv_desc_t *bdp,
|
||||
|
@ -75,20 +42,17 @@ fs_flushinval_pages(
|
|||
xfs_off_t last,
|
||||
int fiopt)
|
||||
{
|
||||
vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
|
||||
if (VN_CACHED(vp)) {
|
||||
if (VN_TRUNC(vp))
|
||||
VUNTRUNCATE(vp);
|
||||
filemap_write_and_wait(ip->i_mapping);
|
||||
|
||||
truncate_inode_pages(ip->i_mapping, first);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* vnode pcache layer for vnode_flush_pages.
|
||||
* 'last' parameter unused but left in for IRIX compatibility
|
||||
*/
|
||||
int
|
||||
fs_flush_pages(
|
||||
bhv_desc_t *bdp,
|
||||
|
@ -97,15 +61,16 @@ fs_flush_pages(
|
|||
uint64_t flags,
|
||||
int fiopt)
|
||||
{
|
||||
vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
|
||||
if (VN_CACHED(vp)) {
|
||||
if (VN_DIRTY(vp)) {
|
||||
if (VN_TRUNC(vp))
|
||||
VUNTRUNCATE(vp);
|
||||
filemap_fdatawrite(ip->i_mapping);
|
||||
if (flags & XFS_B_ASYNC)
|
||||
return 0;
|
||||
filemap_fdatawait(ip->i_mapping);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ xfs_param_t xfs_params = {
|
|||
.xfs_buf_age = { 1*100, 15*100, 7200*100},
|
||||
.inherit_nosym = { 0, 0, 1 },
|
||||
.rotorstep = { 1, 1, 255 },
|
||||
.inherit_nodfrg = { 0, 1, 1 },
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -31,7 +30,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -78,7 +76,7 @@ xfs_find_handle(
|
|||
xfs_handle_t handle;
|
||||
xfs_fsop_handlereq_t hreq;
|
||||
struct inode *inode;
|
||||
struct vnode *vp;
|
||||
bhv_vnode_t *vp;
|
||||
|
||||
if (copy_from_user(&hreq, arg, sizeof(hreq)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
|
@ -192,7 +190,7 @@ xfs_vget_fsop_handlereq(
|
|||
xfs_mount_t *mp,
|
||||
struct inode *parinode, /* parent inode pointer */
|
||||
xfs_fsop_handlereq_t *hreq,
|
||||
vnode_t **vp,
|
||||
bhv_vnode_t **vp,
|
||||
struct inode **inode)
|
||||
{
|
||||
void __user *hanp;
|
||||
|
@ -202,7 +200,7 @@ xfs_vget_fsop_handlereq(
|
|||
xfs_handle_t handle;
|
||||
xfs_inode_t *ip;
|
||||
struct inode *inodep;
|
||||
vnode_t *vpp;
|
||||
bhv_vnode_t *vpp;
|
||||
xfs_ino_t ino;
|
||||
__u32 igen;
|
||||
int error;
|
||||
|
@ -277,7 +275,7 @@ xfs_open_by_handle(
|
|||
struct file *filp;
|
||||
struct inode *inode;
|
||||
struct dentry *dentry;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
xfs_fsop_handlereq_t hreq;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
|
@ -362,7 +360,7 @@ xfs_readlink_by_handle(
|
|||
struct uio auio;
|
||||
struct inode *inode;
|
||||
xfs_fsop_handlereq_t hreq;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
__u32 olen;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
|
@ -393,9 +391,11 @@ xfs_readlink_by_handle(
|
|||
auio.uio_segflg = UIO_USERSPACE;
|
||||
auio.uio_resid = olen;
|
||||
|
||||
VOP_READLINK(vp, &auio, IO_INVIS, NULL, error);
|
||||
|
||||
error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
|
||||
VN_RELE(vp);
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
return (olen - auio.uio_resid);
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ xfs_fssetdm_by_handle(
|
|||
xfs_fsop_setdm_handlereq_t dmhreq;
|
||||
struct inode *inode;
|
||||
bhv_desc_t *bdp;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
|
||||
if (!capable(CAP_MKNOD))
|
||||
return -XFS_ERROR(EPERM);
|
||||
|
@ -452,7 +452,7 @@ xfs_attrlist_by_handle(
|
|||
attrlist_cursor_kern_t *cursor;
|
||||
xfs_fsop_attrlist_handlereq_t al_hreq;
|
||||
struct inode *inode;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
char *kbuf;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
|
@ -472,8 +472,8 @@ xfs_attrlist_by_handle(
|
|||
goto out_vn_rele;
|
||||
|
||||
cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
|
||||
VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags,
|
||||
cursor, NULL, error);
|
||||
error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
|
||||
cursor, NULL);
|
||||
if (error)
|
||||
goto out_kfree;
|
||||
|
||||
|
@ -490,7 +490,7 @@ xfs_attrlist_by_handle(
|
|||
|
||||
STATIC int
|
||||
xfs_attrmulti_attr_get(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
char *name,
|
||||
char __user *ubuf,
|
||||
__uint32_t *len,
|
||||
|
@ -505,7 +505,7 @@ xfs_attrmulti_attr_get(
|
|||
if (!kbuf)
|
||||
return ENOMEM;
|
||||
|
||||
VOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error);
|
||||
error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
|
||||
if (error)
|
||||
goto out_kfree;
|
||||
|
||||
|
@ -519,7 +519,7 @@ xfs_attrmulti_attr_get(
|
|||
|
||||
STATIC int
|
||||
xfs_attrmulti_attr_set(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
char *name,
|
||||
const char __user *ubuf,
|
||||
__uint32_t len,
|
||||
|
@ -542,7 +542,7 @@ xfs_attrmulti_attr_set(
|
|||
if (copy_from_user(kbuf, ubuf, len))
|
||||
goto out_kfree;
|
||||
|
||||
VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error);
|
||||
error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
|
||||
|
||||
out_kfree:
|
||||
kfree(kbuf);
|
||||
|
@ -551,20 +551,15 @@ xfs_attrmulti_attr_set(
|
|||
|
||||
STATIC int
|
||||
xfs_attrmulti_attr_remove(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
char *name,
|
||||
__uint32_t flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
||||
if (IS_RDONLY(&vp->v_inode))
|
||||
return -EROFS;
|
||||
if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
|
||||
return EPERM;
|
||||
|
||||
VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
|
||||
return error;
|
||||
return bhv_vop_attr_remove(vp, name, flags, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -578,7 +573,7 @@ xfs_attrmulti_by_handle(
|
|||
xfs_attr_multiop_t *ops;
|
||||
xfs_fsop_attrmulti_handlereq_t am_hreq;
|
||||
struct inode *inode;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
unsigned int i, size;
|
||||
char *attr_name;
|
||||
|
||||
|
@ -658,7 +653,7 @@ xfs_attrmulti_by_handle(
|
|||
STATIC int
|
||||
xfs_ioc_space(
|
||||
bhv_desc_t *bdp,
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
struct file *filp,
|
||||
int flags,
|
||||
unsigned int cmd,
|
||||
|
@ -682,7 +677,7 @@ xfs_ioc_fsgeometry(
|
|||
|
||||
STATIC int
|
||||
xfs_ioc_xattr(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_inode_t *ip,
|
||||
struct file *filp,
|
||||
unsigned int cmd,
|
||||
|
@ -711,7 +706,7 @@ xfs_ioctl(
|
|||
void __user *arg)
|
||||
{
|
||||
int error;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
xfs_inode_t *ip;
|
||||
xfs_mount_t *mp;
|
||||
|
||||
|
@ -962,7 +957,7 @@ xfs_ioctl(
|
|||
STATIC int
|
||||
xfs_ioc_space(
|
||||
bhv_desc_t *bdp,
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
struct file *filp,
|
||||
int ioflags,
|
||||
unsigned int cmd,
|
||||
|
@ -1153,14 +1148,14 @@ xfs_di2lxflags(
|
|||
|
||||
STATIC int
|
||||
xfs_ioc_xattr(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_inode_t *ip,
|
||||
struct file *filp,
|
||||
unsigned int cmd,
|
||||
void __user *arg)
|
||||
{
|
||||
struct fsxattr fa;
|
||||
struct vattr *vattr;
|
||||
struct bhv_vattr *vattr;
|
||||
int error = 0;
|
||||
int attr_flags;
|
||||
unsigned int flags;
|
||||
|
@ -1173,7 +1168,7 @@ xfs_ioc_xattr(
|
|||
case XFS_IOC_FSGETXATTR: {
|
||||
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_NEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, vattr, 0, NULL, error);
|
||||
error = bhv_vop_getattr(vp, vattr, 0, NULL);
|
||||
if (unlikely(error)) {
|
||||
error = -error;
|
||||
break;
|
||||
|
@ -1206,7 +1201,7 @@ xfs_ioc_xattr(
|
|||
vattr->va_extsize = fa.fsx_extsize;
|
||||
vattr->va_projid = fa.fsx_projid;
|
||||
|
||||
VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
|
||||
error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, vattr); /* update flags */
|
||||
error = -error;
|
||||
|
@ -1216,7 +1211,7 @@ xfs_ioc_xattr(
|
|||
case XFS_IOC_FSGETXATTRA: {
|
||||
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_ANEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, vattr, 0, NULL, error);
|
||||
error = bhv_vop_getattr(vp, vattr, 0, NULL);
|
||||
if (unlikely(error)) {
|
||||
error = -error;
|
||||
break;
|
||||
|
@ -1262,7 +1257,7 @@ xfs_ioc_xattr(
|
|||
vattr->va_xflags = xfs_merge_ioc_xflags(flags,
|
||||
xfs_ip2xflags(ip));
|
||||
|
||||
VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
|
||||
error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, vattr); /* update flags */
|
||||
error = -error;
|
||||
|
|
|
@ -114,7 +114,7 @@ xfs_compat_ioctl(
|
|||
unsigned long arg)
|
||||
{
|
||||
struct inode *inode = file->f_dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -193,7 +193,7 @@ xfs_compat_ioctl(
|
|||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error);
|
||||
error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg);
|
||||
VMODIFY(vp);
|
||||
|
||||
return error;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -61,7 +59,7 @@
|
|||
*/
|
||||
xfs_inode_t *
|
||||
xfs_vtoi(
|
||||
struct vnode *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
bhv_desc_t *bdp;
|
||||
|
||||
|
@ -80,7 +78,7 @@ void
|
|||
xfs_synchronize_atime(
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
|
||||
vp = XFS_ITOV_NULL(ip);
|
||||
if (vp) {
|
||||
|
@ -200,14 +198,10 @@ xfs_ichgtime_fast(
|
|||
STATIC void
|
||||
xfs_validate_fields(
|
||||
struct inode *ip,
|
||||
struct vattr *vattr)
|
||||
bhv_vattr_t *vattr)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(ip);
|
||||
int error;
|
||||
|
||||
vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
|
||||
VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error);
|
||||
if (likely(!error)) {
|
||||
if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) {
|
||||
ip->i_nlink = vattr->va_nlink;
|
||||
ip->i_blocks = vattr->va_nblocks;
|
||||
|
||||
|
@ -225,7 +219,7 @@ xfs_validate_fields(
|
|||
*/
|
||||
STATIC int
|
||||
xfs_init_security(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
struct inode *dir)
|
||||
{
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
|
@ -241,7 +235,7 @@ xfs_init_security(
|
|||
return -error;
|
||||
}
|
||||
|
||||
VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error);
|
||||
error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL);
|
||||
if (!error)
|
||||
VMODIFY(vp);
|
||||
|
||||
|
@ -264,13 +258,12 @@ xfs_has_fs_struct(struct task_struct *task)
|
|||
|
||||
STATIC inline void
|
||||
xfs_cleanup_inode(
|
||||
vnode_t *dvp,
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *dvp,
|
||||
bhv_vnode_t *vp,
|
||||
struct dentry *dentry,
|
||||
int mode)
|
||||
{
|
||||
struct dentry teardown = {};
|
||||
int error;
|
||||
|
||||
/* Oh, the horror.
|
||||
* If we can't add the ACL or we fail in
|
||||
|
@ -281,9 +274,9 @@ xfs_cleanup_inode(
|
|||
teardown.d_name = dentry->d_name;
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
VOP_RMDIR(dvp, &teardown, NULL, error);
|
||||
bhv_vop_rmdir(dvp, &teardown, NULL);
|
||||
else
|
||||
VOP_REMOVE(dvp, &teardown, NULL, error);
|
||||
bhv_vop_remove(dvp, &teardown, NULL);
|
||||
VN_RELE(vp);
|
||||
}
|
||||
|
||||
|
@ -295,8 +288,8 @@ xfs_vn_mknod(
|
|||
dev_t rdev)
|
||||
{
|
||||
struct inode *ip;
|
||||
vattr_t vattr = { 0 };
|
||||
vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
|
||||
bhv_vattr_t vattr = { 0 };
|
||||
bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
|
||||
xfs_acl_t *default_acl = NULL;
|
||||
attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
|
||||
int error;
|
||||
|
@ -330,10 +323,10 @@ xfs_vn_mknod(
|
|||
vattr.va_mask |= XFS_AT_RDEV;
|
||||
/*FALLTHROUGH*/
|
||||
case S_IFREG:
|
||||
VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error);
|
||||
error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL);
|
||||
break;
|
||||
case S_IFDIR:
|
||||
VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error);
|
||||
error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
|
@ -396,14 +389,14 @@ xfs_vn_lookup(
|
|||
struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
{
|
||||
struct vnode *vp = vn_from_inode(dir), *cvp;
|
||||
bhv_vnode_t *vp = vn_from_inode(dir), *cvp;
|
||||
int error;
|
||||
|
||||
if (dentry->d_name.len >= MAXNAMELEN)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
|
||||
if (error) {
|
||||
error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL);
|
||||
if (unlikely(error)) {
|
||||
if (unlikely(error != ENOENT))
|
||||
return ERR_PTR(-error);
|
||||
d_add(dentry, NULL);
|
||||
|
@ -420,9 +413,9 @@ xfs_vn_link(
|
|||
struct dentry *dentry)
|
||||
{
|
||||
struct inode *ip; /* inode of guy being linked to */
|
||||
vnode_t *tdvp; /* target directory for new name/link */
|
||||
vnode_t *vp; /* vp of name being linked */
|
||||
vattr_t vattr;
|
||||
bhv_vnode_t *tdvp; /* target directory for new name/link */
|
||||
bhv_vnode_t *vp; /* vp of name being linked */
|
||||
bhv_vattr_t vattr;
|
||||
int error;
|
||||
|
||||
ip = old_dentry->d_inode; /* inode being linked to */
|
||||
|
@ -432,7 +425,7 @@ xfs_vn_link(
|
|||
tdvp = vn_from_inode(dir);
|
||||
vp = vn_from_inode(ip);
|
||||
|
||||
VOP_LINK(tdvp, vp, dentry, NULL, error);
|
||||
error = bhv_vop_link(tdvp, vp, dentry, NULL);
|
||||
if (likely(!error)) {
|
||||
VMODIFY(tdvp);
|
||||
VN_HOLD(vp);
|
||||
|
@ -448,14 +441,14 @@ xfs_vn_unlink(
|
|||
struct dentry *dentry)
|
||||
{
|
||||
struct inode *inode;
|
||||
vnode_t *dvp; /* directory containing name to remove */
|
||||
vattr_t vattr;
|
||||
bhv_vnode_t *dvp; /* directory containing name to remove */
|
||||
bhv_vattr_t vattr;
|
||||
int error;
|
||||
|
||||
inode = dentry->d_inode;
|
||||
dvp = vn_from_inode(dir);
|
||||
|
||||
VOP_REMOVE(dvp, dentry, NULL, error);
|
||||
error = bhv_vop_remove(dvp, dentry, NULL);
|
||||
if (likely(!error)) {
|
||||
xfs_validate_fields(dir, &vattr); /* size needs update */
|
||||
xfs_validate_fields(inode, &vattr);
|
||||
|
@ -470,27 +463,26 @@ xfs_vn_symlink(
|
|||
const char *symname)
|
||||
{
|
||||
struct inode *ip;
|
||||
vattr_t vattr = { 0 };
|
||||
vnode_t *dvp; /* directory containing name of symlink */
|
||||
vnode_t *cvp; /* used to lookup symlink to put in dentry */
|
||||
bhv_vattr_t va = { 0 };
|
||||
bhv_vnode_t *dvp; /* directory containing name of symlink */
|
||||
bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
|
||||
int error;
|
||||
|
||||
dvp = vn_from_inode(dir);
|
||||
cvp = NULL;
|
||||
|
||||
vattr.va_mode = S_IFLNK |
|
||||
va.va_mode = S_IFLNK |
|
||||
(irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
|
||||
vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
|
||||
va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
|
||||
|
||||
error = 0;
|
||||
VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error);
|
||||
error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL);
|
||||
if (likely(!error && cvp)) {
|
||||
error = xfs_init_security(cvp, dir);
|
||||
if (likely(!error)) {
|
||||
ip = vn_to_inode(cvp);
|
||||
d_instantiate(dentry, ip);
|
||||
xfs_validate_fields(dir, &vattr);
|
||||
xfs_validate_fields(ip, &vattr);
|
||||
xfs_validate_fields(dir, &va);
|
||||
xfs_validate_fields(ip, &va);
|
||||
} else {
|
||||
xfs_cleanup_inode(dvp, cvp, dentry, 0);
|
||||
}
|
||||
|
@ -504,11 +496,11 @@ xfs_vn_rmdir(
|
|||
struct dentry *dentry)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
vnode_t *dvp = vn_from_inode(dir);
|
||||
vattr_t vattr;
|
||||
bhv_vnode_t *dvp = vn_from_inode(dir);
|
||||
bhv_vattr_t vattr;
|
||||
int error;
|
||||
|
||||
VOP_RMDIR(dvp, dentry, NULL, error);
|
||||
error = bhv_vop_rmdir(dvp, dentry, NULL);
|
||||
if (likely(!error)) {
|
||||
xfs_validate_fields(inode, &vattr);
|
||||
xfs_validate_fields(dir, &vattr);
|
||||
|
@ -524,15 +516,15 @@ xfs_vn_rename(
|
|||
struct dentry *ndentry)
|
||||
{
|
||||
struct inode *new_inode = ndentry->d_inode;
|
||||
vnode_t *fvp; /* from directory */
|
||||
vnode_t *tvp; /* target directory */
|
||||
vattr_t vattr;
|
||||
bhv_vnode_t *fvp; /* from directory */
|
||||
bhv_vnode_t *tvp; /* target directory */
|
||||
bhv_vattr_t vattr;
|
||||
int error;
|
||||
|
||||
fvp = vn_from_inode(odir);
|
||||
tvp = vn_from_inode(ndir);
|
||||
|
||||
VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
|
||||
error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL);
|
||||
if (likely(!error)) {
|
||||
if (new_inode)
|
||||
xfs_validate_fields(new_inode, &vattr);
|
||||
|
@ -553,7 +545,7 @@ xfs_vn_follow_link(
|
|||
struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
{
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
uio_t *uio;
|
||||
iovec_t iov;
|
||||
int error;
|
||||
|
@ -586,8 +578,8 @@ xfs_vn_follow_link(
|
|||
uio->uio_resid = MAXPATHLEN;
|
||||
uio->uio_iovcnt = 1;
|
||||
|
||||
VOP_READLINK(vp, uio, 0, NULL, error);
|
||||
if (error) {
|
||||
error = bhv_vop_readlink(vp, uio, 0, NULL);
|
||||
if (unlikely(error)) {
|
||||
kfree(link);
|
||||
link = ERR_PTR(-error);
|
||||
} else {
|
||||
|
@ -618,12 +610,7 @@ xfs_vn_permission(
|
|||
int mode,
|
||||
struct nameidata *nd)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
|
||||
mode <<= 6; /* convert from linux to vnode access bits */
|
||||
VOP_ACCESS(vp, mode, NULL, error);
|
||||
return -error;
|
||||
return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
|
||||
}
|
||||
#else
|
||||
#define xfs_vn_permission NULL
|
||||
|
@ -636,14 +623,14 @@ xfs_vn_getattr(
|
|||
struct kstat *stat)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
int error = 0;
|
||||
|
||||
if (unlikely(vp->v_flag & VMODIFIED))
|
||||
error = vn_revalidate(vp);
|
||||
if (!error)
|
||||
generic_fillattr(inode, stat);
|
||||
return 0;
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -653,8 +640,8 @@ xfs_vn_setattr(
|
|||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
unsigned int ia_valid = attr->ia_valid;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
vattr_t vattr = { 0 };
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vattr_t vattr = { 0 };
|
||||
int flags = 0;
|
||||
int error;
|
||||
|
||||
|
@ -697,7 +684,7 @@ xfs_vn_setattr(
|
|||
flags |= ATTR_NONBLOCK;
|
||||
#endif
|
||||
|
||||
VOP_SETATTR(vp, &vattr, flags, NULL, error);
|
||||
error = bhv_vop_setattr(vp, &vattr, flags, NULL);
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, &vattr);
|
||||
return -error;
|
||||
|
@ -718,7 +705,7 @@ xfs_vn_setxattr(
|
|||
size_t size,
|
||||
int flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
char *attr = (char *)name;
|
||||
attrnames_t *namesp;
|
||||
int xflags = 0;
|
||||
|
@ -748,7 +735,7 @@ xfs_vn_getxattr(
|
|||
void *data,
|
||||
size_t size)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
char *attr = (char *)name;
|
||||
attrnames_t *namesp;
|
||||
int xflags = 0;
|
||||
|
@ -777,7 +764,7 @@ xfs_vn_listxattr(
|
|||
char *data,
|
||||
size_t size)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
int error, xflags = ATTR_KERNAMELS;
|
||||
ssize_t result;
|
||||
|
||||
|
@ -796,7 +783,7 @@ xfs_vn_removexattr(
|
|||
struct dentry *dentry,
|
||||
const char *name)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
char *attr = (char *)name;
|
||||
attrnames_t *namesp;
|
||||
int xflags = 0;
|
||||
|
|
|
@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten);
|
|||
#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
|
||||
#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
|
||||
#define xfs_rotorstep xfs_params.rotorstep.val
|
||||
#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
|
||||
|
||||
#ifndef raw_smp_processor_id
|
||||
#define raw_smp_processor_id() smp_processor_id()
|
||||
#endif
|
||||
#define current_cpu() raw_smp_processor_id()
|
||||
#define current_cpu() (raw_smp_processor_id())
|
||||
#define current_pid() (current->pid)
|
||||
#define current_fsuid(cred) (current->fsuid)
|
||||
#define current_fsgid(cred) (current->fsgid)
|
||||
#define current_set_flags(f) (current->flags |= (f))
|
||||
#define current_test_flags(f) (current->flags & (f))
|
||||
#define current_clear_flags(f) (current->flags & ~(f))
|
||||
#define current_set_flags_nested(sp, f) \
|
||||
(*(sp) = current->flags, current->flags |= (f))
|
||||
#define current_clear_flags_nested(sp, f) \
|
||||
(*(sp) = current->flags, current->flags &= ~(f))
|
||||
#define current_restore_flags_nested(sp, f) \
|
||||
(current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
|
||||
|
||||
#define NBPP PAGE_SIZE
|
||||
#define DPPSHFT (PAGE_SHIFT - 9)
|
||||
|
@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten);
|
|||
/* bytes to clicks */
|
||||
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
|
||||
|
||||
#ifndef ENOATTR
|
||||
#define ENOATTR ENODATA /* Attribute not found */
|
||||
#endif
|
||||
|
||||
/* Note: EWRONGFS never visible outside the kernel */
|
||||
#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
|
||||
|
||||
/*
|
||||
* XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
|
||||
* return codes out of its known range in errno.
|
||||
* XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
|
||||
* conflict with any code we use already or any code a driver may use)
|
||||
* XXX Some options (currently we do #2):
|
||||
* 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
|
||||
* 2/ 990 ["Unknown error 990"]
|
||||
* 3/ EUCLEAN ["Structure needs cleaning"]
|
||||
* 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
|
||||
*/
|
||||
#define EFSCORRUPTED 990 /* Filesystem is corrupted */
|
||||
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
|
||||
|
||||
#define SYNCHRONIZE() barrier()
|
||||
#define __return_address __builtin_return_address(0)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -206,7 +204,7 @@ xfs_read(
|
|||
xfs_fsize_t n;
|
||||
xfs_inode_t *ip;
|
||||
xfs_mount_t *mp;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
unsigned long seg;
|
||||
|
||||
ip = XFS_BHVTOI(bdp);
|
||||
|
@ -258,7 +256,7 @@ xfs_read(
|
|||
|
||||
if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
|
||||
!(ioflags & IO_INVIS)) {
|
||||
vrwlock_t locktype = VRWLOCK_READ;
|
||||
bhv_vrwlock_t locktype = VRWLOCK_READ;
|
||||
int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
|
||||
|
||||
ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
|
||||
|
@ -271,7 +269,7 @@ xfs_read(
|
|||
}
|
||||
|
||||
if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
|
||||
VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)),
|
||||
bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
|
||||
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
|
||||
|
@ -313,7 +311,7 @@ xfs_sendfile(
|
|||
|
||||
if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
|
||||
(!(ioflags & IO_INVIS))) {
|
||||
vrwlock_t locktype = VRWLOCK_READ;
|
||||
bhv_vrwlock_t locktype = VRWLOCK_READ;
|
||||
int error;
|
||||
|
||||
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
|
||||
|
@ -357,7 +355,7 @@ xfs_splice_read(
|
|||
|
||||
if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
|
||||
(!(ioflags & IO_INVIS))) {
|
||||
vrwlock_t locktype = VRWLOCK_READ;
|
||||
bhv_vrwlock_t locktype = VRWLOCK_READ;
|
||||
int error;
|
||||
|
||||
error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
|
||||
|
@ -401,7 +399,7 @@ xfs_splice_write(
|
|||
|
||||
if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
|
||||
(!(ioflags & IO_INVIS))) {
|
||||
vrwlock_t locktype = VRWLOCK_WRITE;
|
||||
bhv_vrwlock_t locktype = VRWLOCK_WRITE;
|
||||
int error;
|
||||
|
||||
error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
|
||||
|
@ -458,7 +456,7 @@ xfs_zero_last_block(
|
|||
last_fsb = XFS_B_TO_FSBT(mp, isize);
|
||||
nimaps = 1;
|
||||
error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
|
||||
&nimaps, NULL);
|
||||
&nimaps, NULL, NULL);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
@ -499,7 +497,7 @@ xfs_zero_last_block(
|
|||
|
||||
int /* error (positive) */
|
||||
xfs_zero_eof(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_iocore_t *io,
|
||||
xfs_off_t offset, /* starting I/O offset */
|
||||
xfs_fsize_t isize, /* current inode size */
|
||||
|
@ -510,7 +508,6 @@ xfs_zero_eof(
|
|||
xfs_fileoff_t end_zero_fsb;
|
||||
xfs_fileoff_t zero_count_fsb;
|
||||
xfs_fileoff_t last_fsb;
|
||||
xfs_extlen_t buf_len_fsb;
|
||||
xfs_mount_t *mp = io->io_mount;
|
||||
int nimaps;
|
||||
int error = 0;
|
||||
|
@ -556,7 +553,7 @@ xfs_zero_eof(
|
|||
nimaps = 1;
|
||||
zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
|
||||
error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
|
||||
0, NULL, 0, &imap, &nimaps, NULL);
|
||||
0, NULL, 0, &imap, &nimaps, NULL, NULL);
|
||||
if (error) {
|
||||
ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
|
||||
ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
|
||||
|
@ -579,16 +576,7 @@ xfs_zero_eof(
|
|||
}
|
||||
|
||||
/*
|
||||
* There are blocks in the range requested.
|
||||
* Zero them a single write at a time. We actually
|
||||
* don't zero the entire range returned if it is
|
||||
* too big and simply loop around to get the rest.
|
||||
* That is not the most efficient thing to do, but it
|
||||
* is simple and this path should not be exercised often.
|
||||
*/
|
||||
buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount,
|
||||
mp->m_writeio_blocks << 8);
|
||||
/*
|
||||
* There are blocks we need to zero.
|
||||
* Drop the inode lock while we're doing the I/O.
|
||||
* We'll still have the iolock to protect us.
|
||||
*/
|
||||
|
@ -596,14 +584,13 @@ xfs_zero_eof(
|
|||
|
||||
error = xfs_iozero(ip,
|
||||
XFS_FSB_TO_B(mp, start_zero_fsb),
|
||||
XFS_FSB_TO_B(mp, buf_len_fsb),
|
||||
XFS_FSB_TO_B(mp, imap.br_blockcount),
|
||||
end_size);
|
||||
|
||||
if (error) {
|
||||
goto out_lock;
|
||||
}
|
||||
|
||||
start_zero_fsb = imap.br_startoff + buf_len_fsb;
|
||||
start_zero_fsb = imap.br_startoff + imap.br_blockcount;
|
||||
ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
|
||||
|
||||
XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
|
||||
|
@ -637,11 +624,11 @@ xfs_write(
|
|||
ssize_t ret = 0, error = 0;
|
||||
xfs_fsize_t isize, new_size;
|
||||
xfs_iocore_t *io;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
unsigned long seg;
|
||||
int iolock;
|
||||
int eventsent = 0;
|
||||
vrwlock_t locktype;
|
||||
bhv_vrwlock_t locktype;
|
||||
size_t ocount = 0, count;
|
||||
loff_t pos;
|
||||
int need_i_mutex = 1, need_flush = 0;
|
||||
|
@ -679,11 +666,11 @@ xfs_write(
|
|||
io = &xip->i_iocore;
|
||||
mp = io->io_mount;
|
||||
|
||||
vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return -EIO;
|
||||
|
||||
fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
|
||||
|
||||
if (ioflags & IO_ISDIRECT) {
|
||||
xfs_buftarg_t *target =
|
||||
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
|
||||
|
@ -814,7 +801,7 @@ retry:
|
|||
if (need_flush) {
|
||||
xfs_inval_cached_trace(io, pos, -1,
|
||||
ctooff(offtoct(pos)), -1);
|
||||
VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)),
|
||||
bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
}
|
||||
|
||||
|
@ -903,79 +890,9 @@ retry:
|
|||
|
||||
/* Handle various SYNC-type writes */
|
||||
if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
|
||||
/*
|
||||
* If we're treating this as O_DSYNC and we have not updated the
|
||||
* size, force the log.
|
||||
*/
|
||||
if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
|
||||
!(xip->i_update_size)) {
|
||||
xfs_inode_log_item_t *iip = xip->i_itemp;
|
||||
|
||||
/*
|
||||
* If an allocation transaction occurred
|
||||
* without extending the size, then we have to force
|
||||
* the log up the proper point to ensure that the
|
||||
* allocation is permanent. We can't count on
|
||||
* the fact that buffered writes lock out direct I/O
|
||||
* writes - the direct I/O write could have extended
|
||||
* the size nontransactionally, then finished before
|
||||
* we started. xfs_write_file will think that the file
|
||||
* didn't grow but the update isn't safe unless the
|
||||
* size change is logged.
|
||||
*
|
||||
* Force the log if we've committed a transaction
|
||||
* against the inode or if someone else has and
|
||||
* the commit record hasn't gone to disk (e.g.
|
||||
* the inode is pinned). This guarantees that
|
||||
* all changes affecting the inode are permanent
|
||||
* when we return.
|
||||
*/
|
||||
if (iip && iip->ili_last_lsn) {
|
||||
xfs_log_force(mp, iip->ili_last_lsn,
|
||||
XFS_LOG_FORCE | XFS_LOG_SYNC);
|
||||
} else if (xfs_ipincount(xip) > 0) {
|
||||
xfs_log_force(mp, (xfs_lsn_t)0,
|
||||
XFS_LOG_FORCE | XFS_LOG_SYNC);
|
||||
}
|
||||
|
||||
} else {
|
||||
xfs_trans_t *tp;
|
||||
|
||||
/*
|
||||
* O_SYNC or O_DSYNC _with_ a size update are handled
|
||||
* the same way.
|
||||
*
|
||||
* If the write was synchronous then we need to make
|
||||
* sure that the inode modification time is permanent.
|
||||
* We'll have updated the timestamp above, so here
|
||||
* we use a synchronous transaction to log the inode.
|
||||
* It's not fast, but it's necessary.
|
||||
*
|
||||
* If this a dsync write and the size got changed
|
||||
* non-transactionally, then we need to ensure that
|
||||
* the size change gets logged in a synchronous
|
||||
* transaction.
|
||||
*/
|
||||
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
|
||||
if ((error = xfs_trans_reserve(tp, 0,
|
||||
XFS_SWRITE_LOG_RES(mp),
|
||||
0, 0, 0))) {
|
||||
/* Transaction reserve failed */
|
||||
xfs_trans_cancel(tp, 0);
|
||||
} else {
|
||||
/* Transaction reserve successful */
|
||||
xfs_ilock(xip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ihold(tp, xip);
|
||||
xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
|
||||
xfs_trans_set_sync(tp);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
error = xfs_write_sync_logforce(mp, xip);
|
||||
if (error)
|
||||
goto out_unlock_internal;
|
||||
}
|
||||
|
||||
xfs_rwunlock(bdp, locktype);
|
||||
if (need_i_mutex)
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#ifndef __XFS_LRW_H__
|
||||
#define __XFS_LRW_H__
|
||||
|
||||
struct vnode;
|
||||
struct bhv_desc;
|
||||
struct bhv_vnode;
|
||||
struct xfs_mount;
|
||||
struct xfs_iocore;
|
||||
struct xfs_inode;
|
||||
|
@ -49,7 +49,7 @@ struct xfs_iomap;
|
|||
#define XFS_CTRUNC4 14
|
||||
#define XFS_CTRUNC5 15
|
||||
#define XFS_CTRUNC6 16
|
||||
#define XFS_BUNMAPI 17
|
||||
#define XFS_BUNMAP 17
|
||||
#define XFS_INVAL_CACHED 18
|
||||
#define XFS_DIORD_ENTER 19
|
||||
#define XFS_DIOWR_ENTER 20
|
||||
|
@ -82,7 +82,7 @@ extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
|
|||
extern int xfs_bdstrat_cb(struct xfs_buf *);
|
||||
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
|
||||
|
||||
extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
|
||||
extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t,
|
||||
xfs_fsize_t, xfs_fsize_t);
|
||||
extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
|
||||
const struct iovec *, unsigned int,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -151,7 +149,7 @@ xfs_set_inodeops(
|
|||
STATIC __inline__ void
|
||||
xfs_revalidate_inode(
|
||||
xfs_mount_t *mp,
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
@ -206,7 +204,7 @@ xfs_revalidate_inode(
|
|||
void
|
||||
xfs_initialize_vnode(
|
||||
bhv_desc_t *bdp,
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
bhv_desc_t *inode_bhv,
|
||||
int unlock)
|
||||
{
|
||||
|
@ -336,7 +334,7 @@ STATIC struct inode *
|
|||
xfs_fs_alloc_inode(
|
||||
struct super_block *sb)
|
||||
{
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
|
||||
vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
|
||||
if (unlikely(!vp))
|
||||
|
@ -359,13 +357,13 @@ xfs_fs_inode_init_once(
|
|||
{
|
||||
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
|
||||
SLAB_CTOR_CONSTRUCTOR)
|
||||
inode_init_once(vn_to_inode((vnode_t *)vnode));
|
||||
inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_init_zones(void)
|
||||
{
|
||||
xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t",
|
||||
xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
|
||||
KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
|
||||
KM_ZONE_SPREAD,
|
||||
xfs_fs_inode_init_once);
|
||||
|
@ -409,22 +407,17 @@ xfs_fs_write_inode(
|
|||
struct inode *inode,
|
||||
int sync)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
int error = 0, flags = FLUSH_INODE;
|
||||
|
||||
if (vp) {
|
||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
if (sync)
|
||||
flags |= FLUSH_SYNC;
|
||||
VOP_IFLUSH(vp, flags, error);
|
||||
if (error == EAGAIN) {
|
||||
if (sync)
|
||||
VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
|
||||
else
|
||||
error = 0;
|
||||
error = bhv_vop_iflush(vp, flags);
|
||||
if (error == EAGAIN)
|
||||
error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
|
@ -432,8 +425,7 @@ STATIC void
|
|||
xfs_fs_clear_inode(
|
||||
struct inode *inode)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error, cache;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
|
||||
|
@ -446,20 +438,18 @@ xfs_fs_clear_inode(
|
|||
* This can happen because xfs_iget_core calls xfs_idestroy if we
|
||||
* find an inode with di_mode == 0 but without IGET_CREATE set.
|
||||
*/
|
||||
if (vp->v_fbhv)
|
||||
VOP_INACTIVE(vp, NULL, cache);
|
||||
if (VNHEAD(vp))
|
||||
bhv_vop_inactive(vp, NULL);
|
||||
|
||||
VN_LOCK(vp);
|
||||
vp->v_flag &= ~VMODIFIED;
|
||||
VN_UNLOCK(vp, 0);
|
||||
|
||||
if (vp->v_fbhv) {
|
||||
VOP_RECLAIM(vp, error);
|
||||
if (error)
|
||||
panic("vn_purge: cannot reclaim");
|
||||
}
|
||||
if (VNHEAD(vp))
|
||||
if (bhv_vop_reclaim(vp))
|
||||
panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp);
|
||||
|
||||
ASSERT(vp->v_fbhv == NULL);
|
||||
ASSERT(VNHEAD(vp) == NULL);
|
||||
|
||||
#ifdef XFS_VNODE_TRACE
|
||||
ktrace_free(vp->v_trace);
|
||||
|
@ -475,13 +465,13 @@ xfs_fs_clear_inode(
|
|||
*/
|
||||
STATIC void
|
||||
xfs_syncd_queue_work(
|
||||
struct vfs *vfs,
|
||||
struct bhv_vfs *vfs,
|
||||
void *data,
|
||||
void (*syncer)(vfs_t *, void *))
|
||||
void (*syncer)(bhv_vfs_t *, void *))
|
||||
{
|
||||
vfs_sync_work_t *work;
|
||||
struct bhv_vfs_sync_work *work;
|
||||
|
||||
work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP);
|
||||
work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP);
|
||||
INIT_LIST_HEAD(&work->w_list);
|
||||
work->w_syncer = syncer;
|
||||
work->w_data = data;
|
||||
|
@ -500,7 +490,7 @@ xfs_syncd_queue_work(
|
|||
*/
|
||||
STATIC void
|
||||
xfs_flush_inode_work(
|
||||
vfs_t *vfs,
|
||||
bhv_vfs_t *vfs,
|
||||
void *inode)
|
||||
{
|
||||
filemap_flush(((struct inode *)inode)->i_mapping);
|
||||
|
@ -512,7 +502,7 @@ xfs_flush_inode(
|
|||
xfs_inode_t *ip)
|
||||
{
|
||||
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
|
||||
struct vfs *vfs = XFS_MTOVFS(ip->i_mount);
|
||||
struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
|
||||
|
||||
igrab(inode);
|
||||
xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
|
||||
|
@ -525,7 +515,7 @@ xfs_flush_inode(
|
|||
*/
|
||||
STATIC void
|
||||
xfs_flush_device_work(
|
||||
vfs_t *vfs,
|
||||
bhv_vfs_t *vfs,
|
||||
void *inode)
|
||||
{
|
||||
sync_blockdev(vfs->vfs_super->s_bdev);
|
||||
|
@ -537,7 +527,7 @@ xfs_flush_device(
|
|||
xfs_inode_t *ip)
|
||||
{
|
||||
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
|
||||
struct vfs *vfs = XFS_MTOVFS(ip->i_mount);
|
||||
struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
|
||||
|
||||
igrab(inode);
|
||||
xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
|
||||
|
@ -545,16 +535,16 @@ xfs_flush_device(
|
|||
xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
|
||||
}
|
||||
|
||||
#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
|
||||
STATIC void
|
||||
vfs_sync_worker(
|
||||
vfs_t *vfsp,
|
||||
bhv_vfs_t *vfsp,
|
||||
void *unused)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!(vfsp->vfs_flag & VFS_RDONLY))
|
||||
VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
|
||||
error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
|
||||
SYNC_ATTR | SYNC_REFCACHE, NULL);
|
||||
vfsp->vfs_sync_seq++;
|
||||
wmb();
|
||||
wake_up(&vfsp->vfs_wait_single_sync_task);
|
||||
|
@ -565,8 +555,8 @@ xfssyncd(
|
|||
void *arg)
|
||||
{
|
||||
long timeleft;
|
||||
vfs_t *vfsp = (vfs_t *) arg;
|
||||
struct vfs_sync_work *work, *n;
|
||||
bhv_vfs_t *vfsp = (bhv_vfs_t *) arg;
|
||||
bhv_vfs_sync_work_t *work, *n;
|
||||
LIST_HEAD (tmp);
|
||||
|
||||
timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
|
||||
|
@ -600,7 +590,7 @@ xfssyncd(
|
|||
list_del(&work->w_list);
|
||||
if (work == &vfsp->vfs_sync_work)
|
||||
continue;
|
||||
kmem_free(work, sizeof(struct vfs_sync_work));
|
||||
kmem_free(work, sizeof(struct bhv_vfs_sync_work));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -609,7 +599,7 @@ xfssyncd(
|
|||
|
||||
STATIC int
|
||||
xfs_fs_start_syncd(
|
||||
vfs_t *vfsp)
|
||||
bhv_vfs_t *vfsp)
|
||||
{
|
||||
vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
|
||||
vfsp->vfs_sync_work.w_vfs = vfsp;
|
||||
|
@ -621,7 +611,7 @@ xfs_fs_start_syncd(
|
|||
|
||||
STATIC void
|
||||
xfs_fs_stop_syncd(
|
||||
vfs_t *vfsp)
|
||||
bhv_vfs_t *vfsp)
|
||||
{
|
||||
kthread_stop(vfsp->vfs_sync_task);
|
||||
}
|
||||
|
@ -630,35 +620,26 @@ STATIC void
|
|||
xfs_fs_put_super(
|
||||
struct super_block *sb)
|
||||
{
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
bhv_vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
xfs_fs_stop_syncd(vfsp);
|
||||
VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
|
||||
if (!error)
|
||||
VFS_UNMOUNT(vfsp, 0, NULL, error);
|
||||
bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL);
|
||||
error = bhv_vfs_unmount(vfsp, 0, NULL);
|
||||
if (error) {
|
||||
printk("XFS unmount got error %d\n", error);
|
||||
printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("XFS: unmount got error=%d\n", error);
|
||||
printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
|
||||
} else {
|
||||
vfs_deallocate(vfsp);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_fs_write_super(
|
||||
struct super_block *sb)
|
||||
{
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
if (sb->s_flags & MS_RDONLY) {
|
||||
sb->s_dirt = 0; /* paranoia */
|
||||
return;
|
||||
}
|
||||
/* Push the log and superblock a little */
|
||||
VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
|
||||
if (!(sb->s_flags & MS_RDONLY))
|
||||
bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL);
|
||||
sb->s_dirt = 0;
|
||||
}
|
||||
|
||||
|
@ -667,16 +648,16 @@ xfs_fs_sync_super(
|
|||
struct super_block *sb,
|
||||
int wait)
|
||||
{
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
bhv_vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
int flags = SYNC_FSDATA;
|
||||
int flags;
|
||||
|
||||
if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
|
||||
flags = SYNC_QUIESCE;
|
||||
else
|
||||
flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
|
||||
|
||||
VFS_SYNC(vfsp, flags, NULL, error);
|
||||
error = bhv_vfs_sync(vfsp, flags, NULL);
|
||||
sb->s_dirt = 0;
|
||||
|
||||
if (unlikely(laptop_mode)) {
|
||||
|
@ -706,11 +687,7 @@ xfs_fs_statfs(
|
|||
struct super_block *sb,
|
||||
struct kstatfs *statp)
|
||||
{
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_STATVFS(vfsp, statp, NULL, error);
|
||||
return -error;
|
||||
return -bhv_vfs_statvfs(vfs_from_sb(sb), statp, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -719,13 +696,13 @@ xfs_fs_remount(
|
|||
int *flags,
|
||||
char *options)
|
||||
{
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
bhv_vfs_t *vfsp = vfs_from_sb(sb);
|
||||
struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
|
||||
int error;
|
||||
|
||||
VFS_PARSEARGS(vfsp, options, args, 1, error);
|
||||
error = bhv_vfs_parseargs(vfsp, options, args, 1);
|
||||
if (!error)
|
||||
VFS_MNTUPDATE(vfsp, flags, args, error);
|
||||
error = bhv_vfs_mntupdate(vfsp, flags, args);
|
||||
kmem_free(args, sizeof(*args));
|
||||
return -error;
|
||||
}
|
||||
|
@ -734,7 +711,7 @@ STATIC void
|
|||
xfs_fs_lockfs(
|
||||
struct super_block *sb)
|
||||
{
|
||||
VFS_FREEZE(vfs_from_sb(sb));
|
||||
bhv_vfs_freeze(vfs_from_sb(sb));
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -742,11 +719,7 @@ xfs_fs_show_options(
|
|||
struct seq_file *m,
|
||||
struct vfsmount *mnt)
|
||||
{
|
||||
struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb);
|
||||
int error;
|
||||
|
||||
VFS_SHOWARGS(vfsp, m, error);
|
||||
return error;
|
||||
return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -754,11 +727,7 @@ xfs_fs_quotasync(
|
|||
struct super_block *sb,
|
||||
int type)
|
||||
{
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
|
||||
return -error;
|
||||
return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -766,11 +735,7 @@ xfs_fs_getxstate(
|
|||
struct super_block *sb,
|
||||
struct fs_quota_stat *fqs)
|
||||
{
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
|
||||
return -error;
|
||||
return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -779,11 +744,7 @@ xfs_fs_setxstate(
|
|||
unsigned int flags,
|
||||
int op)
|
||||
{
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
|
||||
return -error;
|
||||
return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -793,13 +754,10 @@ xfs_fs_getxquota(
|
|||
qid_t id,
|
||||
struct fs_disk_quota *fdq)
|
||||
{
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error, getmode;
|
||||
|
||||
getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
|
||||
((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
|
||||
VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
|
||||
return -error;
|
||||
return -bhv_vfs_quotactl(vfs_from_sb(sb),
|
||||
(type == USRQUOTA) ? Q_XGETQUOTA :
|
||||
((type == GRPQUOTA) ? Q_XGETGQUOTA :
|
||||
Q_XGETPQUOTA), id, (caddr_t)fdq);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -809,13 +767,10 @@ xfs_fs_setxquota(
|
|||
qid_t id,
|
||||
struct fs_disk_quota *fdq)
|
||||
{
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error, setmode;
|
||||
|
||||
setmode = (type == USRQUOTA) ? Q_XSETQLIM :
|
||||
((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
|
||||
VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
|
||||
return -error;
|
||||
return -bhv_vfs_quotactl(vfs_from_sb(sb),
|
||||
(type == USRQUOTA) ? Q_XSETQLIM :
|
||||
((type == GRPQUOTA) ? Q_XSETGQLIM :
|
||||
Q_XSETPQLIM), id, (caddr_t)fdq);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -824,34 +779,32 @@ xfs_fs_fill_super(
|
|||
void *data,
|
||||
int silent)
|
||||
{
|
||||
vnode_t *rootvp;
|
||||
struct vfs *vfsp = vfs_allocate(sb);
|
||||
struct bhv_vnode *rootvp;
|
||||
struct bhv_vfs *vfsp = vfs_allocate(sb);
|
||||
struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
|
||||
struct kstatfs statvfs;
|
||||
int error, error2;
|
||||
int error;
|
||||
|
||||
bhv_insert_all_vfsops(vfsp);
|
||||
|
||||
VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
|
||||
error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0);
|
||||
if (error) {
|
||||
bhv_remove_all_vfsops(vfsp, 1);
|
||||
goto fail_vfsop;
|
||||
}
|
||||
|
||||
sb_min_blocksize(sb, BBSIZE);
|
||||
#ifdef CONFIG_XFS_EXPORT
|
||||
sb->s_export_op = &xfs_export_operations;
|
||||
#endif
|
||||
sb->s_qcop = &xfs_quotactl_operations;
|
||||
sb->s_op = &xfs_super_operations;
|
||||
|
||||
VFS_MOUNT(vfsp, args, NULL, error);
|
||||
error = bhv_vfs_mount(vfsp, args, NULL);
|
||||
if (error) {
|
||||
bhv_remove_all_vfsops(vfsp, 1);
|
||||
goto fail_vfsop;
|
||||
}
|
||||
|
||||
VFS_STATVFS(vfsp, &statvfs, NULL, error);
|
||||
error = bhv_vfs_statvfs(vfsp, &statvfs, NULL);
|
||||
if (error)
|
||||
goto fail_unmount;
|
||||
|
||||
|
@ -863,7 +816,7 @@ xfs_fs_fill_super(
|
|||
sb->s_time_gran = 1;
|
||||
set_posix_acl_flag(sb);
|
||||
|
||||
VFS_ROOT(vfsp, &rootvp, error);
|
||||
error = bhv_vfs_root(vfsp, &rootvp);
|
||||
if (error)
|
||||
goto fail_unmount;
|
||||
|
||||
|
@ -892,7 +845,7 @@ fail_vnrele:
|
|||
}
|
||||
|
||||
fail_unmount:
|
||||
VFS_UNMOUNT(vfsp, 0, NULL, error2);
|
||||
bhv_vfs_unmount(vfsp, 0, NULL);
|
||||
|
||||
fail_vfsop:
|
||||
vfs_deallocate(vfsp);
|
||||
|
|
|
@ -105,7 +105,7 @@ struct block_device;
|
|||
|
||||
extern __uint64_t xfs_max_file_offset(unsigned int);
|
||||
|
||||
extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
|
||||
extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int);
|
||||
|
||||
extern void xfs_flush_inode(struct xfs_inode *);
|
||||
extern void xfs_flush_device(struct xfs_inode *);
|
||||
|
|
|
@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = {
|
|||
&sysctl_intvec, NULL,
|
||||
&xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
|
||||
|
||||
{XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
|
||||
sizeof(int), 0644, NULL, &proc_dointvec_minmax,
|
||||
&sysctl_intvec, NULL,
|
||||
&xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
|
||||
|
||||
/* please keep this the last entry */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
{XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct xfs_param {
|
|||
xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */
|
||||
xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
|
||||
xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
|
||||
xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
|
||||
} xfs_param_t;
|
||||
|
||||
/*
|
||||
|
@ -84,6 +85,7 @@ enum {
|
|||
/* XFS_IO_BYPASS = 18 */
|
||||
XFS_INHERIT_NOSYM = 19,
|
||||
XFS_ROTORSTEP = 20,
|
||||
XFS_INHERIT_NODFRG = 21,
|
||||
};
|
||||
|
||||
extern xfs_param_t xfs_params;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_imap.h"
|
||||
#include "xfs_alloc.h"
|
||||
|
@ -104,7 +103,7 @@ vfs_mntupdate(
|
|||
int
|
||||
vfs_root(
|
||||
struct bhv_desc *bdp,
|
||||
struct vnode **vpp)
|
||||
struct bhv_vnode **vpp)
|
||||
{
|
||||
struct bhv_desc *next = bdp;
|
||||
|
||||
|
@ -117,15 +116,15 @@ vfs_root(
|
|||
int
|
||||
vfs_statvfs(
|
||||
struct bhv_desc *bdp,
|
||||
xfs_statfs_t *sp,
|
||||
struct vnode *vp)
|
||||
bhv_statvfs_t *statp,
|
||||
struct bhv_vnode *vp)
|
||||
{
|
||||
struct bhv_desc *next = bdp;
|
||||
|
||||
ASSERT(next);
|
||||
while (! (bhvtovfsops(next))->vfs_statvfs)
|
||||
next = BHV_NEXT(next);
|
||||
return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp));
|
||||
return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -145,7 +144,7 @@ vfs_sync(
|
|||
int
|
||||
vfs_vget(
|
||||
struct bhv_desc *bdp,
|
||||
struct vnode **vpp,
|
||||
struct bhv_vnode **vpp,
|
||||
struct fid *fidp)
|
||||
{
|
||||
struct bhv_desc *next = bdp;
|
||||
|
@ -187,7 +186,7 @@ vfs_quotactl(
|
|||
void
|
||||
vfs_init_vnode(
|
||||
struct bhv_desc *bdp,
|
||||
struct vnode *vp,
|
||||
struct bhv_vnode *vp,
|
||||
struct bhv_desc *bp,
|
||||
int unlock)
|
||||
{
|
||||
|
@ -226,13 +225,13 @@ vfs_freeze(
|
|||
((*bhvtovfsops(next)->vfs_freeze)(next));
|
||||
}
|
||||
|
||||
vfs_t *
|
||||
bhv_vfs_t *
|
||||
vfs_allocate(
|
||||
struct super_block *sb)
|
||||
{
|
||||
struct vfs *vfsp;
|
||||
struct bhv_vfs *vfsp;
|
||||
|
||||
vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
|
||||
vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
|
||||
bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
|
||||
INIT_LIST_HEAD(&vfsp->vfs_sync_list);
|
||||
spin_lock_init(&vfsp->vfs_sync_lock);
|
||||
|
@ -247,25 +246,25 @@ vfs_allocate(
|
|||
return vfsp;
|
||||
}
|
||||
|
||||
vfs_t *
|
||||
bhv_vfs_t *
|
||||
vfs_from_sb(
|
||||
struct super_block *sb)
|
||||
{
|
||||
return (vfs_t *)sb->s_fs_info;
|
||||
return (bhv_vfs_t *)sb->s_fs_info;
|
||||
}
|
||||
|
||||
void
|
||||
vfs_deallocate(
|
||||
struct vfs *vfsp)
|
||||
struct bhv_vfs *vfsp)
|
||||
{
|
||||
bhv_head_destroy(VFS_BHVHEAD(vfsp));
|
||||
kmem_free(vfsp, sizeof(vfs_t));
|
||||
kmem_free(vfsp, sizeof(bhv_vfs_t));
|
||||
}
|
||||
|
||||
void
|
||||
vfs_insertops(
|
||||
struct vfs *vfsp,
|
||||
struct bhv_vfsops *vfsops)
|
||||
struct bhv_vfs *vfsp,
|
||||
struct bhv_module_vfsops *vfsops)
|
||||
{
|
||||
struct bhv_desc *bdp;
|
||||
|
||||
|
@ -276,9 +275,9 @@ vfs_insertops(
|
|||
|
||||
void
|
||||
vfs_insertbhv(
|
||||
struct vfs *vfsp,
|
||||
struct bhv_vfs *vfsp,
|
||||
struct bhv_desc *bdp,
|
||||
struct vfsops *vfsops,
|
||||
struct bhv_vfsops *vfsops,
|
||||
void *mount)
|
||||
{
|
||||
bhv_desc_init(bdp, mount, vfsp, vfsops);
|
||||
|
@ -287,7 +286,7 @@ vfs_insertbhv(
|
|||
|
||||
void
|
||||
bhv_remove_vfsops(
|
||||
struct vfs *vfsp,
|
||||
struct bhv_vfs *vfsp,
|
||||
int pos)
|
||||
{
|
||||
struct bhv_desc *bhv;
|
||||
|
@ -301,7 +300,7 @@ bhv_remove_vfsops(
|
|||
|
||||
void
|
||||
bhv_remove_all_vfsops(
|
||||
struct vfs *vfsp,
|
||||
struct bhv_vfs *vfsp,
|
||||
int freebase)
|
||||
{
|
||||
struct xfs_mount *mp;
|
||||
|
@ -317,7 +316,7 @@ bhv_remove_all_vfsops(
|
|||
|
||||
void
|
||||
bhv_insert_all_vfsops(
|
||||
struct vfs *vfsp)
|
||||
struct bhv_vfs *vfsp)
|
||||
{
|
||||
struct xfs_mount *mp;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -21,42 +21,40 @@
|
|||
#include <linux/vfs.h>
|
||||
#include "xfs_fs.h"
|
||||
|
||||
struct bhv_vfs;
|
||||
struct bhv_vnode;
|
||||
|
||||
struct fid;
|
||||
struct vfs;
|
||||
struct cred;
|
||||
struct vnode;
|
||||
struct kstatfs;
|
||||
struct seq_file;
|
||||
struct super_block;
|
||||
struct xfs_mount_args;
|
||||
|
||||
typedef struct kstatfs xfs_statfs_t;
|
||||
typedef struct kstatfs bhv_statvfs_t;
|
||||
|
||||
typedef struct vfs_sync_work {
|
||||
typedef struct bhv_vfs_sync_work {
|
||||
struct list_head w_list;
|
||||
struct vfs *w_vfs;
|
||||
struct bhv_vfs *w_vfs;
|
||||
void *w_data; /* syncer routine argument */
|
||||
void (*w_syncer)(struct vfs *, void *);
|
||||
} vfs_sync_work_t;
|
||||
void (*w_syncer)(struct bhv_vfs *, void *);
|
||||
} bhv_vfs_sync_work_t;
|
||||
|
||||
typedef struct vfs {
|
||||
typedef struct bhv_vfs {
|
||||
u_int vfs_flag; /* flags */
|
||||
xfs_fsid_t vfs_fsid; /* file system ID */
|
||||
xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
|
||||
bhv_head_t vfs_bh; /* head of vfs behavior chain */
|
||||
struct super_block *vfs_super; /* generic superblock pointer */
|
||||
struct task_struct *vfs_sync_task; /* generalised sync thread */
|
||||
vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
|
||||
bhv_vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
|
||||
struct list_head vfs_sync_list; /* sync thread work item list */
|
||||
spinlock_t vfs_sync_lock; /* work item list lock */
|
||||
int vfs_sync_seq; /* sync thread generation no. */
|
||||
wait_queue_head_t vfs_wait_single_sync_task;
|
||||
} vfs_t;
|
||||
} bhv_vfs_t;
|
||||
|
||||
#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
|
||||
|
||||
#define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) )
|
||||
#define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) )
|
||||
#define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
|
||||
#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
|
||||
#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
|
||||
#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
|
||||
|
||||
|
@ -71,7 +69,7 @@ typedef enum {
|
|||
VFS_BHV_QM, /* quota manager */
|
||||
VFS_BHV_IO, /* IO path */
|
||||
VFS_BHV_END /* housekeeping end-of-range */
|
||||
} vfs_bhv_t;
|
||||
} bhv_vfs_type_t;
|
||||
|
||||
#define VFS_POSITION_XFS (BHV_POSITION_BASE)
|
||||
#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
|
||||
|
@ -81,8 +79,9 @@ typedef enum {
|
|||
#define VFS_RDONLY 0x0001 /* read-only vfs */
|
||||
#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
|
||||
#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
|
||||
#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */
|
||||
#define VFS_END 0x0008 /* max flag */
|
||||
#define VFS_UMOUNT 0x0008 /* unmount in progress */
|
||||
#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
|
||||
#define VFS_END 0x0010 /* max flag */
|
||||
|
||||
#define SYNC_ATTR 0x0001 /* sync attributes */
|
||||
#define SYNC_CLOSE 0x0002 /* close file system down */
|
||||
|
@ -92,7 +91,14 @@ typedef enum {
|
|||
#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
|
||||
#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
|
||||
#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
|
||||
#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */
|
||||
#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
|
||||
|
||||
#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
|
||||
#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
|
||||
#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
|
||||
#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
|
||||
#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
|
||||
#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
|
||||
|
||||
typedef int (*vfs_mount_t)(bhv_desc_t *,
|
||||
struct xfs_mount_args *, struct cred *);
|
||||
|
@ -102,18 +108,19 @@ typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
|
|||
typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
|
||||
typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
|
||||
struct xfs_mount_args *);
|
||||
typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **);
|
||||
typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *);
|
||||
typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
|
||||
typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
|
||||
struct bhv_vnode *);
|
||||
typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
|
||||
typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *);
|
||||
typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
|
||||
typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
|
||||
typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
|
||||
typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
|
||||
struct vnode *, bhv_desc_t *, int);
|
||||
struct bhv_vnode *, bhv_desc_t *, int);
|
||||
typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
|
||||
typedef void (*vfs_freeze_t)(bhv_desc_t *);
|
||||
|
||||
typedef struct vfsops {
|
||||
typedef struct bhv_vfsops {
|
||||
bhv_position_t vf_position; /* behavior chain position */
|
||||
vfs_mount_t vfs_mount; /* mount file system */
|
||||
vfs_parseargs_t vfs_parseargs; /* parse mount options */
|
||||
|
@ -129,82 +136,82 @@ typedef struct vfsops {
|
|||
vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
|
||||
vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
|
||||
vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
|
||||
} vfsops_t;
|
||||
} bhv_vfsops_t;
|
||||
|
||||
/*
|
||||
* VFS's. Operates on vfs structure pointers (starts at bhv head).
|
||||
* Virtual filesystem operations, operating from head bhv.
|
||||
*/
|
||||
#define VHEAD(v) ((v)->vfs_fbhv)
|
||||
#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr))
|
||||
#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f))
|
||||
#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m))
|
||||
#define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr))
|
||||
#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args))
|
||||
#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp))
|
||||
#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp))
|
||||
#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr))
|
||||
#define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp))
|
||||
#define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p))
|
||||
#define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p))
|
||||
#define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) )
|
||||
#define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) )
|
||||
#define VFS_FREEZE(v) ( vfs_freeze(VHEAD(v)) )
|
||||
#define VFSHEAD(v) ((v)->vfs_bh.bh_first)
|
||||
#define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
|
||||
#define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
|
||||
#define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
|
||||
#define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
|
||||
#define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
|
||||
#define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
|
||||
#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
|
||||
#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
|
||||
#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
|
||||
#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
|
||||
#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
|
||||
#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
|
||||
#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
|
||||
#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
|
||||
|
||||
/*
|
||||
* PVFS's. Operates on behavior descriptor pointers.
|
||||
* Virtual filesystem operations, operating from next bhv.
|
||||
*/
|
||||
#define PVFS_MOUNT(b, ma,cr, rv) ((rv) = vfs_mount(b, ma,cr))
|
||||
#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f))
|
||||
#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m))
|
||||
#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr))
|
||||
#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args))
|
||||
#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp))
|
||||
#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp))
|
||||
#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr))
|
||||
#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp))
|
||||
#define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p))
|
||||
#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p))
|
||||
#define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) )
|
||||
#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) )
|
||||
#define PVFS_FREEZE(b) ( vfs_freeze(b) )
|
||||
#define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
|
||||
#define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
|
||||
#define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
|
||||
#define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
|
||||
#define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
|
||||
#define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
|
||||
#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
|
||||
#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
|
||||
#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
|
||||
#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
|
||||
#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
|
||||
#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
|
||||
#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
|
||||
#define bhv_next_vfs_freeze(b) vfs_freeze(b)
|
||||
|
||||
extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
|
||||
extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
|
||||
extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
|
||||
extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
|
||||
extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
|
||||
extern int vfs_root(bhv_desc_t *, struct vnode **);
|
||||
extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *);
|
||||
extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
|
||||
extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
|
||||
extern int vfs_sync(bhv_desc_t *, int, struct cred *);
|
||||
extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *);
|
||||
extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
|
||||
extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
|
||||
extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
|
||||
extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int);
|
||||
extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
|
||||
extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
|
||||
extern void vfs_freeze(bhv_desc_t *);
|
||||
|
||||
typedef struct bhv_vfsops {
|
||||
struct vfsops bhv_common;
|
||||
#define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
|
||||
#define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l))
|
||||
|
||||
typedef struct bhv_module_vfsops {
|
||||
struct bhv_vfsops bhv_common;
|
||||
void * bhv_custom;
|
||||
} bhv_vfsops_t;
|
||||
} bhv_module_vfsops_t;
|
||||
|
||||
#define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) )
|
||||
#define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom )
|
||||
#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o))
|
||||
#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL )
|
||||
#define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
|
||||
#define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
|
||||
#define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
|
||||
#define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
|
||||
|
||||
extern vfs_t *vfs_allocate(struct super_block *);
|
||||
extern vfs_t *vfs_from_sb(struct super_block *);
|
||||
extern void vfs_deallocate(vfs_t *);
|
||||
extern void vfs_insertops(vfs_t *, bhv_vfsops_t *);
|
||||
extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
|
||||
extern bhv_vfs_t *vfs_allocate(struct super_block *);
|
||||
extern bhv_vfs_t *vfs_from_sb(struct super_block *);
|
||||
extern void vfs_deallocate(bhv_vfs_t *);
|
||||
extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
|
||||
|
||||
extern void bhv_insert_all_vfsops(struct vfs *);
|
||||
extern void bhv_remove_all_vfsops(struct vfs *, int);
|
||||
extern void bhv_remove_vfsops(struct vfs *, int);
|
||||
extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
|
||||
|
||||
#define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen)
|
||||
#define fs_check_frozen(vfsp, level) \
|
||||
vfs_check_frozen(vfsp->vfs_super, level);
|
||||
extern void bhv_insert_all_vfsops(struct bhv_vfs *);
|
||||
extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
|
||||
extern void bhv_remove_vfsops(struct bhv_vfs *, int);
|
||||
|
||||
#endif /* __XFS_VFS_H__ */
|
||||
|
|
|
@ -39,7 +39,7 @@ vn_init(void)
|
|||
|
||||
void
|
||||
vn_iowait(
|
||||
struct vnode *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
wait_queue_head_t *wq = vptosync(vp);
|
||||
|
||||
|
@ -48,17 +48,33 @@ vn_iowait(
|
|||
|
||||
void
|
||||
vn_iowake(
|
||||
struct vnode *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
if (atomic_dec_and_test(&vp->v_iocount))
|
||||
wake_up(vptosync(vp));
|
||||
}
|
||||
|
||||
struct vnode *
|
||||
/*
|
||||
* Volume managers supporting multiple paths can send back ENODEV when the
|
||||
* final path disappears. In this case continuing to fill the page cache
|
||||
* with dirty data which cannot be written out is evil, so prevent that.
|
||||
*/
|
||||
void
|
||||
vn_ioerror(
|
||||
bhv_vnode_t *vp,
|
||||
int error,
|
||||
char *f,
|
||||
int l)
|
||||
{
|
||||
if (unlikely(error == -ENODEV))
|
||||
bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
|
||||
}
|
||||
|
||||
bhv_vnode_t *
|
||||
vn_initialize(
|
||||
struct inode *inode)
|
||||
{
|
||||
struct vnode *vp = vn_from_inode(inode);
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
XFS_STATS_INC(vn_active);
|
||||
XFS_STATS_INC(vn_alloc);
|
||||
|
@ -94,8 +110,8 @@ vn_initialize(
|
|||
*/
|
||||
void
|
||||
vn_revalidate_core(
|
||||
struct vnode *vp,
|
||||
vattr_t *vap)
|
||||
bhv_vnode_t *vp,
|
||||
bhv_vattr_t *vap)
|
||||
{
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
|
@ -130,14 +146,14 @@ vn_revalidate_core(
|
|||
*/
|
||||
int
|
||||
__vn_revalidate(
|
||||
struct vnode *vp,
|
||||
struct vattr *vattr)
|
||||
bhv_vnode_t *vp,
|
||||
bhv_vattr_t *vattr)
|
||||
{
|
||||
int error;
|
||||
|
||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
|
||||
VOP_GETATTR(vp, vattr, 0, NULL, error);
|
||||
error = bhv_vop_getattr(vp, vattr, 0, NULL);
|
||||
if (likely(!error)) {
|
||||
vn_revalidate_core(vp, vattr);
|
||||
VUNMODIFY(vp);
|
||||
|
@ -147,9 +163,9 @@ __vn_revalidate(
|
|||
|
||||
int
|
||||
vn_revalidate(
|
||||
struct vnode *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
vattr_t vattr;
|
||||
bhv_vattr_t vattr;
|
||||
|
||||
return __vn_revalidate(vp, &vattr);
|
||||
}
|
||||
|
@ -157,9 +173,9 @@ vn_revalidate(
|
|||
/*
|
||||
* Add a reference to a referenced vnode.
|
||||
*/
|
||||
struct vnode *
|
||||
bhv_vnode_t *
|
||||
vn_hold(
|
||||
struct vnode *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
||||
|
@ -192,31 +208,31 @@ vn_hold(
|
|||
* Vnode tracing code.
|
||||
*/
|
||||
void
|
||||
vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra)
|
||||
vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra)
|
||||
{
|
||||
KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
|
||||
}
|
||||
|
||||
void
|
||||
vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra)
|
||||
vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra)
|
||||
{
|
||||
KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
|
||||
}
|
||||
|
||||
void
|
||||
vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra)
|
||||
vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
|
||||
{
|
||||
KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
|
||||
}
|
||||
|
||||
void
|
||||
vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra)
|
||||
vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
|
||||
{
|
||||
KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
|
||||
}
|
||||
|
||||
void
|
||||
vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra)
|
||||
vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
|
||||
{
|
||||
KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
|
||||
}
|
||||
|
|
|
@ -14,57 +14,35 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Portions Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __XFS_VNODE_H__
|
||||
#define __XFS_VNODE_H__
|
||||
|
||||
struct uio;
|
||||
struct file;
|
||||
struct vattr;
|
||||
struct bhv_vfs;
|
||||
struct bhv_vattr;
|
||||
struct xfs_iomap;
|
||||
struct attrlist_cursor_kern;
|
||||
|
||||
typedef struct dentry bhv_vname_t;
|
||||
typedef __u64 bhv_vnumber_t;
|
||||
|
||||
typedef xfs_ino_t vnumber_t;
|
||||
typedef struct dentry vname_t;
|
||||
typedef bhv_head_t vn_bhv_head_t;
|
||||
typedef enum bhv_vflags {
|
||||
VMODIFIED = 0x08, /* XFS inode state possibly differs */
|
||||
/* to the Linux inode state. */
|
||||
VTRUNCATED = 0x40, /* truncated down so flush-on-close */
|
||||
} bhv_vflags_t;
|
||||
|
||||
/*
|
||||
* MP locking protocols:
|
||||
* v_flag, v_vfsp VN_LOCK/VN_UNLOCK
|
||||
*/
|
||||
typedef struct vnode {
|
||||
__u32 v_flag; /* vnode flags (see below) */
|
||||
struct vfs *v_vfsp; /* ptr to containing VFS */
|
||||
vnumber_t v_number; /* in-core vnode number */
|
||||
vn_bhv_head_t v_bh; /* behavior head */
|
||||
typedef struct bhv_vnode {
|
||||
bhv_vflags_t v_flag; /* vnode flags (see above) */
|
||||
bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
|
||||
bhv_vnumber_t v_number; /* in-core vnode number */
|
||||
bhv_head_t v_bh; /* behavior head */
|
||||
spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
|
||||
atomic_t v_iocount; /* outstanding I/O count */
|
||||
#ifdef XFS_VNODE_TRACE
|
||||
|
@ -72,7 +50,7 @@ typedef struct vnode {
|
|||
#endif
|
||||
struct inode v_inode; /* Linux inode */
|
||||
/* inode MUST be last */
|
||||
} vnode_t;
|
||||
} bhv_vnode_t;
|
||||
|
||||
#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
|
||||
#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode)
|
||||
|
@ -80,9 +58,6 @@ typedef struct vnode {
|
|||
#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
|
||||
#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode)
|
||||
|
||||
#define v_fbhv v_bh.bh_first /* first behavior */
|
||||
#define v_fops v_bh.bh_first->bd_ops /* first behavior ops */
|
||||
|
||||
#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
|
||||
#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
|
||||
#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
|
||||
|
@ -104,8 +79,8 @@ typedef enum {
|
|||
/*
|
||||
* Macros for dealing with the behavior descriptor inside of the vnode.
|
||||
*/
|
||||
#define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp))
|
||||
#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp))
|
||||
#define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
|
||||
#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
|
||||
|
||||
#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
|
||||
#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
|
||||
|
@ -116,35 +91,29 @@ typedef enum {
|
|||
/*
|
||||
* Vnode to Linux inode mapping.
|
||||
*/
|
||||
static inline struct vnode *vn_from_inode(struct inode *inode)
|
||||
static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
|
||||
{
|
||||
return (vnode_t *)list_entry(inode, vnode_t, v_inode);
|
||||
return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode);
|
||||
}
|
||||
static inline struct inode *vn_to_inode(struct vnode *vnode)
|
||||
static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
|
||||
{
|
||||
return &vnode->v_inode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode flags.
|
||||
* Values for the vop_rwlock/rwunlock flags parameter.
|
||||
*/
|
||||
#define VMODIFIED 0x8 /* XFS inode state possibly differs */
|
||||
/* to the Linux inode state. */
|
||||
|
||||
/*
|
||||
* Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
|
||||
*/
|
||||
typedef enum vrwlock {
|
||||
typedef enum bhv_vrwlock {
|
||||
VRWLOCK_NONE,
|
||||
VRWLOCK_READ,
|
||||
VRWLOCK_WRITE,
|
||||
VRWLOCK_WRITE_DIRECT,
|
||||
VRWLOCK_TRY_READ,
|
||||
VRWLOCK_TRY_WRITE
|
||||
} vrwlock_t;
|
||||
} bhv_vrwlock_t;
|
||||
|
||||
/*
|
||||
* Return values for VOP_INACTIVE. A return value of
|
||||
* Return values for bhv_vop_inactive. A return value of
|
||||
* VN_INACTIVE_NOCACHE implies that the file system behavior
|
||||
* has disassociated its state and bhv_desc_t from the vnode.
|
||||
*/
|
||||
|
@ -152,18 +121,20 @@ typedef enum vrwlock {
|
|||
#define VN_INACTIVE_NOCACHE 1
|
||||
|
||||
/*
|
||||
* Values for the cmd code given to VOP_VNODE_CHANGE.
|
||||
* Values for the cmd code given to vop_vnode_change.
|
||||
*/
|
||||
typedef enum vchange {
|
||||
typedef enum bhv_vchange {
|
||||
VCHANGE_FLAGS_FRLOCKS = 0,
|
||||
VCHANGE_FLAGS_ENF_LOCKING = 1,
|
||||
VCHANGE_FLAGS_TRUNCATED = 2,
|
||||
VCHANGE_FLAGS_PAGE_DIRTY = 3,
|
||||
VCHANGE_FLAGS_IOEXCL_COUNT = 4
|
||||
} vchange_t;
|
||||
} bhv_vchange_t;
|
||||
|
||||
typedef enum { L_FALSE, L_TRUE } lastclose_t;
|
||||
|
||||
typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
|
||||
typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *);
|
||||
typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
|
||||
const struct iovec *, unsigned int,
|
||||
loff_t *, int, struct cred *);
|
||||
|
@ -181,27 +152,27 @@ typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
|
|||
struct cred *);
|
||||
typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
|
||||
int, unsigned int, void __user *);
|
||||
typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
|
||||
typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
|
||||
struct cred *);
|
||||
typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int,
|
||||
typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
|
||||
struct cred *);
|
||||
typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *);
|
||||
typedef int (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **,
|
||||
int, vnode_t *, struct cred *);
|
||||
typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *,
|
||||
vnode_t **, struct cred *);
|
||||
typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *);
|
||||
typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *,
|
||||
typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
|
||||
int, bhv_vnode_t *, struct cred *);
|
||||
typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
|
||||
bhv_vnode_t **, struct cred *);
|
||||
typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
|
||||
typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
|
||||
struct cred *);
|
||||
typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *,
|
||||
struct cred *);
|
||||
typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *,
|
||||
vnode_t **, struct cred *);
|
||||
typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *);
|
||||
typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
|
||||
bhv_vname_t *, struct cred *);
|
||||
typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
|
||||
bhv_vnode_t **, struct cred *);
|
||||
typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
|
||||
typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
|
||||
int *);
|
||||
typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *,
|
||||
char *, vnode_t **, struct cred *);
|
||||
typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
|
||||
char *, bhv_vnode_t **, struct cred *);
|
||||
typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
|
||||
struct cred *);
|
||||
typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
|
||||
|
@ -209,8 +180,8 @@ typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
|
|||
typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
|
||||
typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
|
||||
typedef int (*vop_release_t)(bhv_desc_t *);
|
||||
typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t);
|
||||
typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t);
|
||||
typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
|
||||
typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
|
||||
typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
|
||||
struct xfs_iomap *, int *);
|
||||
typedef int (*vop_reclaim_t)(bhv_desc_t *);
|
||||
|
@ -222,8 +193,8 @@ typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
|
|||
int, struct cred *);
|
||||
typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
|
||||
struct attrlist_cursor_kern *, struct cred *);
|
||||
typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int);
|
||||
typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t);
|
||||
typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
|
||||
typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
|
||||
typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
|
||||
typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
|
||||
|
@ -231,9 +202,10 @@ typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
|
|||
typedef int (*vop_iflush_t)(bhv_desc_t *, int);
|
||||
|
||||
|
||||
typedef struct vnodeops {
|
||||
typedef struct bhv_vnodeops {
|
||||
bhv_position_t vn_position; /* position within behavior chain */
|
||||
vop_open_t vop_open;
|
||||
vop_close_t vop_close;
|
||||
vop_read_t vop_read;
|
||||
vop_write_t vop_write;
|
||||
vop_sendfile_t vop_sendfile;
|
||||
|
@ -271,103 +243,80 @@ typedef struct vnodeops {
|
|||
vop_pflushvp_t vop_flush_pages;
|
||||
vop_release_t vop_release;
|
||||
vop_iflush_t vop_iflush;
|
||||
} vnodeops_t;
|
||||
} bhv_vnodeops_t;
|
||||
|
||||
/*
|
||||
* VOP's.
|
||||
* Virtual node operations, operating from head bhv.
|
||||
*/
|
||||
#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
|
||||
|
||||
#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \
|
||||
rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
|
||||
#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \
|
||||
rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
|
||||
#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
|
||||
rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
|
||||
#define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
|
||||
rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
|
||||
#define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
|
||||
rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
|
||||
#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
|
||||
rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
|
||||
#define VOP_OPEN(vp, cr, rv) \
|
||||
rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
|
||||
#define VOP_GETATTR(vp, vap, f, cr, rv) \
|
||||
rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
|
||||
#define VOP_SETATTR(vp, vap, f, cr, rv) \
|
||||
rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
|
||||
#define VOP_ACCESS(vp, mode, cr, rv) \
|
||||
rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr)
|
||||
#define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \
|
||||
rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
|
||||
#define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \
|
||||
rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
|
||||
#define VOP_REMOVE(dvp,d,cr,rv) \
|
||||
rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
|
||||
#define VOP_LINK(tdvp,fvp,d,cr,rv) \
|
||||
rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
|
||||
#define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \
|
||||
rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
|
||||
#define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \
|
||||
rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
|
||||
#define VOP_RMDIR(dp,d,cr,rv) \
|
||||
rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
|
||||
#define VOP_READDIR(vp,uiop,cr,eofp,rv) \
|
||||
rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
|
||||
#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
|
||||
rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
|
||||
#define VOP_READLINK(vp,uiop,fl,cr,rv) \
|
||||
rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
|
||||
#define VOP_FSYNC(vp,f,cr,b,e,rv) \
|
||||
rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
|
||||
#define VOP_INACTIVE(vp, cr, rv) \
|
||||
rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
|
||||
#define VOP_RELEASE(vp, rv) \
|
||||
rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
|
||||
#define VOP_FID2(vp, fidp, rv) \
|
||||
rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
|
||||
#define VOP_RWLOCK(vp,i) \
|
||||
(void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
|
||||
#define VOP_RWLOCK_TRY(vp,i) \
|
||||
_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
|
||||
#define VOP_RWUNLOCK(vp,i) \
|
||||
(void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
|
||||
#define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \
|
||||
rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
|
||||
#define VOP_RECLAIM(vp, rv) \
|
||||
rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
|
||||
#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \
|
||||
rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
|
||||
#define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \
|
||||
rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
|
||||
#define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \
|
||||
rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
|
||||
#define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \
|
||||
rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
|
||||
#define VOP_LINK_REMOVED(vp, dvp, linkzero) \
|
||||
(void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
|
||||
#define VOP_VNODE_CHANGE(vp, cmd, val) \
|
||||
(void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
|
||||
/*
|
||||
* These are page cache functions that now go thru VOPs.
|
||||
* 'last' parameter is unused and left in for IRIX compatibility
|
||||
*/
|
||||
#define VOP_TOSS_PAGES(vp, first, last, fiopt) \
|
||||
_VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt)
|
||||
/*
|
||||
* 'last' parameter is unused and left in for IRIX compatibility
|
||||
*/
|
||||
#define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \
|
||||
_VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt)
|
||||
/*
|
||||
* 'last' parameter is unused and left in for IRIX compatibility
|
||||
*/
|
||||
#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \
|
||||
rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt)
|
||||
#define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \
|
||||
rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg)
|
||||
#define VOP_IFLUSH(vp, flags, rv) \
|
||||
rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags)
|
||||
#define VNHEAD(vp) ((vp)->v_bh.bh_first)
|
||||
#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
|
||||
#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
|
||||
#define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
|
||||
#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
|
||||
VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
|
||||
#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
|
||||
VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
|
||||
#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
|
||||
VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
|
||||
#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
|
||||
VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
|
||||
#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
|
||||
VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
|
||||
#define bhv_vop_bmap(vp,of,sz,rw,b,n) \
|
||||
VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
|
||||
#define bhv_vop_getattr(vp, vap,f,cr) \
|
||||
VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
|
||||
#define bhv_vop_setattr(vp, vap,f,cr) \
|
||||
VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
|
||||
#define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
|
||||
#define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
|
||||
VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
|
||||
#define bhv_vop_create(dvp,d,vap,vpp,cr) \
|
||||
VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
|
||||
#define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
|
||||
#define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
|
||||
#define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
|
||||
VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
|
||||
#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
|
||||
VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
|
||||
#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
|
||||
#define bhv_vop_readdir(vp,uiop,cr,eofp) \
|
||||
VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
|
||||
#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
|
||||
VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
|
||||
#define bhv_vop_readlink(vp,uiop,fl,cr) \
|
||||
VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
|
||||
#define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
|
||||
#define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
|
||||
#define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
|
||||
#define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
|
||||
#define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
|
||||
#define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
|
||||
#define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
|
||||
#define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
|
||||
VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
|
||||
#define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
|
||||
#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
|
||||
VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
|
||||
#define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
|
||||
VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
|
||||
#define bhv_vop_attr_remove(vp, name, flags, cred) \
|
||||
VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
|
||||
#define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
|
||||
VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
|
||||
#define bhv_vop_link_removed(vp, dvp, linkzero) \
|
||||
VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
|
||||
#define bhv_vop_vnode_change(vp, cmd, val) \
|
||||
VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
|
||||
#define bhv_vop_toss_pages(vp, first, last, fiopt) \
|
||||
VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
|
||||
#define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
|
||||
VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
|
||||
#define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
|
||||
VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
|
||||
#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
|
||||
VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
|
||||
#define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
|
||||
|
||||
/*
|
||||
* Flags for read/write calls - same values as IRIX
|
||||
|
@ -377,7 +326,7 @@ typedef struct vnodeops {
|
|||
#define IO_INVIS 0x00020 /* don't update inode timestamps */
|
||||
|
||||
/*
|
||||
* Flags for VOP_IFLUSH call
|
||||
* Flags for vop_iflush call
|
||||
*/
|
||||
#define FLUSH_SYNC 1 /* wait for flush to complete */
|
||||
#define FLUSH_INODE 2 /* flush the inode itself */
|
||||
|
@ -385,8 +334,7 @@ typedef struct vnodeops {
|
|||
* this inode out to disk */
|
||||
|
||||
/*
|
||||
* Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and
|
||||
* VOP_FLUSH_PAGES.
|
||||
* Flush/Invalidate options for vop_toss/flush/flushinval_pages.
|
||||
*/
|
||||
#define FI_NONE 0 /* none */
|
||||
#define FI_REMAPF 1 /* Do a remapf prior to the operation */
|
||||
|
@ -398,7 +346,7 @@ typedef struct vnodeops {
|
|||
* Vnode attributes. va_mask indicates those attributes the caller
|
||||
* wants to set or extract.
|
||||
*/
|
||||
typedef struct vattr {
|
||||
typedef struct bhv_vattr {
|
||||
int va_mask; /* bit-mask of attributes present */
|
||||
mode_t va_mode; /* file access mode and type */
|
||||
xfs_nlink_t va_nlink; /* number of references to file */
|
||||
|
@ -418,7 +366,7 @@ typedef struct vattr {
|
|||
u_long va_nextents; /* number of extents in file */
|
||||
u_long va_anextents; /* number of attr extents in file */
|
||||
prid_t va_projid; /* project id */
|
||||
} vattr_t;
|
||||
} bhv_vattr_t;
|
||||
|
||||
/*
|
||||
* setattr or getattr attributes
|
||||
|
@ -492,29 +440,17 @@ typedef struct vattr {
|
|||
(VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
|
||||
|
||||
extern void vn_init(void);
|
||||
extern vnode_t *vn_initialize(struct inode *);
|
||||
extern bhv_vnode_t *vn_initialize(struct inode *);
|
||||
extern int vn_revalidate(struct bhv_vnode *);
|
||||
extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *);
|
||||
extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *);
|
||||
|
||||
/*
|
||||
* vnode_map structures _must_ match vn_epoch and vnode structure sizes.
|
||||
*/
|
||||
typedef struct vnode_map {
|
||||
vfs_t *v_vfsp;
|
||||
vnumber_t v_number; /* in-core vnode number */
|
||||
xfs_ino_t v_ino; /* inode # */
|
||||
} vmap_t;
|
||||
extern void vn_iowait(struct bhv_vnode *vp);
|
||||
extern void vn_iowake(struct bhv_vnode *vp);
|
||||
|
||||
#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \
|
||||
(vmap).v_number = (vp)->v_number, \
|
||||
(vmap).v_ino = (vp)->v_inode.i_ino; }
|
||||
extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
|
||||
|
||||
extern int vn_revalidate(struct vnode *);
|
||||
extern int __vn_revalidate(struct vnode *, vattr_t *);
|
||||
extern void vn_revalidate_core(struct vnode *, vattr_t *);
|
||||
|
||||
extern void vn_iowait(struct vnode *vp);
|
||||
extern void vn_iowake(struct vnode *vp);
|
||||
|
||||
static inline int vn_count(struct vnode *vp)
|
||||
static inline int vn_count(struct bhv_vnode *vp)
|
||||
{
|
||||
return atomic_read(&vn_to_inode(vp)->i_count);
|
||||
}
|
||||
|
@ -522,7 +458,7 @@ static inline int vn_count(struct vnode *vp)
|
|||
/*
|
||||
* Vnode reference counting functions (and macros for compatibility).
|
||||
*/
|
||||
extern vnode_t *vn_hold(struct vnode *);
|
||||
extern bhv_vnode_t *vn_hold(struct bhv_vnode *);
|
||||
|
||||
#if defined(XFS_VNODE_TRACE)
|
||||
#define VN_HOLD(vp) \
|
||||
|
@ -536,7 +472,7 @@ extern vnode_t *vn_hold(struct vnode *);
|
|||
#define VN_RELE(vp) (iput(vn_to_inode(vp)))
|
||||
#endif
|
||||
|
||||
static inline struct vnode *vn_grab(struct vnode *vp)
|
||||
static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
|
||||
{
|
||||
struct inode *inode = igrab(vn_to_inode(vp));
|
||||
return inode ? vn_from_inode(inode) : NULL;
|
||||
|
@ -554,32 +490,39 @@ static inline struct vnode *vn_grab(struct vnode *vp)
|
|||
*/
|
||||
#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
|
||||
#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s)
|
||||
#define VN_FLAGSET(vp,b) vn_flagset(vp,b)
|
||||
#define VN_FLAGCLR(vp,b) vn_flagclr(vp,b)
|
||||
|
||||
static __inline__ void vn_flagset(struct vnode *vp, uint flag)
|
||||
static __inline__ void vn_flagset(struct bhv_vnode *vp, uint flag)
|
||||
{
|
||||
spin_lock(&vp->v_lock);
|
||||
vp->v_flag |= flag;
|
||||
spin_unlock(&vp->v_lock);
|
||||
}
|
||||
|
||||
static __inline__ void vn_flagclr(struct vnode *vp, uint flag)
|
||||
static __inline__ uint vn_flagclr(struct bhv_vnode *vp, uint flag)
|
||||
{
|
||||
uint cleared;
|
||||
|
||||
spin_lock(&vp->v_lock);
|
||||
cleared = (vp->v_flag & flag);
|
||||
vp->v_flag &= ~flag;
|
||||
spin_unlock(&vp->v_lock);
|
||||
return cleared;
|
||||
}
|
||||
|
||||
#define VMODIFY(vp) vn_flagset(vp, VMODIFIED)
|
||||
#define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED)
|
||||
#define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED)
|
||||
#define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED)
|
||||
|
||||
/*
|
||||
* Dealing with bad inodes
|
||||
*/
|
||||
static inline void vn_mark_bad(struct vnode *vp)
|
||||
static inline void vn_mark_bad(struct bhv_vnode *vp)
|
||||
{
|
||||
make_bad_inode(vn_to_inode(vp));
|
||||
}
|
||||
|
||||
static inline int VN_BAD(struct vnode *vp)
|
||||
static inline int VN_BAD(struct bhv_vnode *vp)
|
||||
{
|
||||
return is_bad_inode(vn_to_inode(vp));
|
||||
}
|
||||
|
@ -587,18 +530,18 @@ static inline int VN_BAD(struct vnode *vp)
|
|||
/*
|
||||
* Extracting atime values in various formats
|
||||
*/
|
||||
static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime)
|
||||
static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
|
||||
{
|
||||
bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
|
||||
bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
|
||||
}
|
||||
|
||||
static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts)
|
||||
static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
|
||||
{
|
||||
*ts = vp->v_inode.i_atime;
|
||||
}
|
||||
|
||||
static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
|
||||
static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
|
||||
{
|
||||
*tt = vp->v_inode.i_atime.tv_sec;
|
||||
}
|
||||
|
@ -610,11 +553,10 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
|
|||
#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
|
||||
#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
|
||||
PAGECACHE_TAG_DIRTY)
|
||||
#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED)
|
||||
#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
|
||||
#define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
|
||||
|
||||
/*
|
||||
* Flags to VOP_SETATTR/VOP_GETATTR.
|
||||
* Flags to vop_setattr/getattr.
|
||||
*/
|
||||
#define ATTR_UTIME 0x01 /* non-default utime(2) request */
|
||||
#define ATTR_DMI 0x08 /* invocation from a DMI function */
|
||||
|
@ -624,7 +566,7 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
|
|||
#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
|
||||
|
||||
/*
|
||||
* Flags to VOP_FSYNC and VOP_RECLAIM.
|
||||
* Flags to vop_fsync/reclaim.
|
||||
*/
|
||||
#define FSYNC_NOWAIT 0 /* asynchronous flush */
|
||||
#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */
|
||||
|
@ -643,11 +585,11 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
|
|||
#define VNODE_KTRACE_REF 4
|
||||
#define VNODE_KTRACE_RELE 5
|
||||
|
||||
extern void vn_trace_entry(struct vnode *, const char *, inst_t *);
|
||||
extern void vn_trace_exit(struct vnode *, const char *, inst_t *);
|
||||
extern void vn_trace_hold(struct vnode *, char *, int, inst_t *);
|
||||
extern void vn_trace_ref(struct vnode *, char *, int, inst_t *);
|
||||
extern void vn_trace_rele(struct vnode *, char *, int, inst_t *);
|
||||
extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
|
||||
extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
|
||||
extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
|
||||
extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
|
||||
extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
|
||||
|
||||
#define VN_TRACE(vp) \
|
||||
vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -444,7 +442,7 @@ xfs_qm_dqalloc(
|
|||
XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
|
||||
&firstblock,
|
||||
XFS_QM_DQALLOC_SPACE_RES(mp),
|
||||
&map, &nmaps, &flist))) {
|
||||
&map, &nmaps, &flist, NULL))) {
|
||||
goto error0;
|
||||
}
|
||||
ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
|
||||
|
@ -559,7 +557,7 @@ xfs_qm_dqtobp(
|
|||
error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
|
||||
XFS_DQUOT_CLUSTER_SIZE_FSB,
|
||||
XFS_BMAPI_METADATA,
|
||||
NULL, 0, &map, &nmaps, NULL);
|
||||
NULL, 0, &map, &nmaps, NULL, NULL);
|
||||
|
||||
xfs_iunlock(quotip, XFS_ILOCK_SHARED);
|
||||
if (error)
|
||||
|
@ -1261,7 +1259,7 @@ xfs_qm_dqflush(
|
|||
|
||||
if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id),
|
||||
0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
|
||||
xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
|
||||
xfs_force_shutdown(dqp->q_mount, SHUTDOWN_CORRUPT_INCORE);
|
||||
return XFS_ERROR(EIO);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
|
|||
*/
|
||||
#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\
|
||||
(dqp)->dq_flags |= XFS_DQ_FLOCKED; }
|
||||
#define xfs_dqfunlock(dqp) { ASSERT(valusema(&((dqp)->q_flock)) <= 0); \
|
||||
#define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \
|
||||
vsema(&((dqp)->q_flock)); \
|
||||
(dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); }
|
||||
|
||||
|
@ -128,7 +128,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
|
|||
#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \
|
||||
&(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s)
|
||||
|
||||
#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (valusema(&((dqp)->q_flock)) <= 0)
|
||||
#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock)))
|
||||
#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
|
||||
#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
|
||||
#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -248,7 +246,7 @@ xfs_qm_dquot_logitem_pushbuf(
|
|||
* inode flush completed and the inode was taken off the AIL.
|
||||
* So, just get out.
|
||||
*/
|
||||
if ((valusema(&(dqp->q_flock)) > 0) ||
|
||||
if (!issemalocked(&(dqp->q_flock)) ||
|
||||
((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
|
||||
qip->qli_pushbuf_flag = 0;
|
||||
xfs_dqunlock(dqp);
|
||||
|
@ -261,7 +259,7 @@ xfs_qm_dquot_logitem_pushbuf(
|
|||
if (bp != NULL) {
|
||||
if (XFS_BUF_ISDELAYWRITE(bp)) {
|
||||
dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
|
||||
(valusema(&(dqp->q_flock)) <= 0));
|
||||
issemalocked(&(dqp->q_flock)));
|
||||
qip->qli_pushbuf_flag = 0;
|
||||
xfs_dqunlock(dqp);
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -33,7 +32,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -1603,7 +1601,7 @@ xfs_qm_dqiterate(
|
|||
maxlblkcnt - lblkno,
|
||||
XFS_BMAPI_METADATA,
|
||||
NULL,
|
||||
0, map, &nmaps, NULL);
|
||||
0, map, &nmaps, NULL, NULL);
|
||||
xfs_iunlock(qip, XFS_ILOCK_SHARED);
|
||||
if (error)
|
||||
break;
|
||||
|
@ -1905,9 +1903,7 @@ xfs_qm_quotacheck(
|
|||
*/
|
||||
if ((error = xfs_bulkstat(mp, &lastino, &count,
|
||||
xfs_qm_dqusage_adjust, NULL,
|
||||
structsz, NULL,
|
||||
BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
|
||||
&done)))
|
||||
structsz, NULL, BULKSTAT_FG_IGET, &done)))
|
||||
break;
|
||||
|
||||
} while (! done);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -24,7 +24,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -33,7 +32,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -129,7 +127,7 @@ xfs_qm_parseargs(
|
|||
return XFS_ERROR(EINVAL);
|
||||
}
|
||||
|
||||
PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
|
||||
error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
|
||||
if (!error && !referenced)
|
||||
bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
|
||||
return error;
|
||||
|
@ -140,9 +138,8 @@ xfs_qm_showargs(
|
|||
struct bhv_desc *bhv,
|
||||
struct seq_file *m)
|
||||
{
|
||||
struct vfs *vfsp = bhvtovfs(bhv);
|
||||
struct bhv_vfs *vfsp = bhvtovfs(bhv);
|
||||
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
|
||||
int error;
|
||||
|
||||
if (mp->m_qflags & XFS_UQUOTA_ACCT) {
|
||||
(mp->m_qflags & XFS_UQUOTA_ENFD) ?
|
||||
|
@ -165,8 +162,7 @@ xfs_qm_showargs(
|
|||
if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
|
||||
seq_puts(m, "," MNTOPT_NOQUOTA);
|
||||
|
||||
PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
|
||||
return error;
|
||||
return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -175,14 +171,67 @@ xfs_qm_mount(
|
|||
struct xfs_mount_args *args,
|
||||
struct cred *cr)
|
||||
{
|
||||
struct vfs *vfsp = bhvtovfs(bhv);
|
||||
struct bhv_vfs *vfsp = bhvtovfs(bhv);
|
||||
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
|
||||
int error;
|
||||
|
||||
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
|
||||
xfs_qm_mount_quotainit(mp, args->flags);
|
||||
PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
|
||||
return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory tree accounting is implemented using project quotas, where
|
||||
* the project identifier is inherited from parent directories.
|
||||
* A statvfs (df, etc.) of a directory that is using project quota should
|
||||
* return a statvfs of the project, not the entire filesystem.
|
||||
* This makes such trees appear as if they are filesystems in themselves.
|
||||
*/
|
||||
STATIC int
|
||||
xfs_qm_statvfs(
|
||||
struct bhv_desc *bhv,
|
||||
bhv_statvfs_t *statp,
|
||||
struct bhv_vnode *vnode)
|
||||
{
|
||||
xfs_mount_t *mp;
|
||||
xfs_inode_t *ip;
|
||||
xfs_dquot_t *dqp;
|
||||
xfs_disk_dquot_t *dp;
|
||||
__uint64_t limit;
|
||||
int error;
|
||||
|
||||
error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
|
||||
if (error || !vnode)
|
||||
return error;
|
||||
|
||||
mp = XFS_BHVTOM(bhv);
|
||||
ip = xfs_vtoi(vnode);
|
||||
|
||||
if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
|
||||
return 0;
|
||||
if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
|
||||
return 0;
|
||||
if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
|
||||
return 0;
|
||||
|
||||
if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
|
||||
return 0;
|
||||
dp = &dqp->q_core;
|
||||
|
||||
limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit;
|
||||
if (limit && statp->f_blocks > limit) {
|
||||
statp->f_blocks = limit;
|
||||
statp->f_bfree = (statp->f_blocks > dp->d_bcount) ?
|
||||
(statp->f_blocks - dp->d_bcount) : 0;
|
||||
}
|
||||
limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit;
|
||||
if (limit && statp->f_files > limit) {
|
||||
statp->f_files = limit;
|
||||
statp->f_ffree = (statp->f_files > dp->d_icount) ?
|
||||
(statp->f_ffree - dp->d_icount) : 0;
|
||||
}
|
||||
|
||||
xfs_qm_dqput(dqp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -191,7 +240,7 @@ xfs_qm_syncall(
|
|||
int flags,
|
||||
cred_t *credp)
|
||||
{
|
||||
struct vfs *vfsp = bhvtovfs(bhv);
|
||||
struct bhv_vfs *vfsp = bhvtovfs(bhv);
|
||||
struct xfs_mount *mp = XFS_VFSTOM(vfsp);
|
||||
int error;
|
||||
|
||||
|
@ -210,8 +259,7 @@ xfs_qm_syncall(
|
|||
}
|
||||
}
|
||||
}
|
||||
PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error);
|
||||
return error;
|
||||
return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = {
|
|||
.xfs_dqtrxops = &xfs_trans_dquot_ops,
|
||||
};
|
||||
|
||||
struct bhv_vfsops xfs_qmops = { {
|
||||
struct bhv_module_vfsops xfs_qmops = { {
|
||||
BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
|
||||
.vfs_parseargs = xfs_qm_parseargs,
|
||||
.vfs_showargs = xfs_qm_showargs,
|
||||
.vfs_mount = xfs_qm_mount,
|
||||
.vfs_statvfs = xfs_qm_statvfs,
|
||||
.vfs_sync = xfs_qm_syncall,
|
||||
.vfs_quotactl = xfs_qm_quotactl, },
|
||||
};
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -35,7 +34,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -91,8 +89,8 @@ xfs_qm_quotactl(
|
|||
xfs_caddr_t addr)
|
||||
{
|
||||
xfs_mount_t *mp;
|
||||
bhv_vfs_t *vfsp;
|
||||
int error;
|
||||
struct vfs *vfsp;
|
||||
|
||||
vfsp = bhvtovfs(bdp);
|
||||
mp = XFS_VFSTOM(vfsp);
|
||||
|
@ -1035,7 +1033,7 @@ xfs_qm_dqrele_all_inodes(
|
|||
{
|
||||
xfs_inode_t *ip, *topino;
|
||||
uint ireclaims;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
boolean_t vnode_refd;
|
||||
|
||||
ASSERT(mp->m_quotainfo);
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -33,7 +32,6 @@
|
|||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_inode.h"
|
||||
|
|
|
@ -47,7 +47,7 @@ cmn_err(register int level, char *fmt, ...)
|
|||
va_start(ap, fmt);
|
||||
if (*fmt == '!') fp++;
|
||||
len = vsprintf(message, fp, ap);
|
||||
if (message[len-1] != '\n')
|
||||
if (level != CE_DEBUG && message[len-1] != '\n')
|
||||
strcat(message, "\n");
|
||||
printk("%s%s", err_level[level], message);
|
||||
va_end(ap);
|
||||
|
@ -68,7 +68,7 @@ icmn_err(register int level, char *fmt, va_list ap)
|
|||
level = XFS_MAX_ERR_LEVEL;
|
||||
spin_lock_irqsave(&xfs_err_lock,flags);
|
||||
len = vsprintf(message, fmt, ap);
|
||||
if (message[len-1] != '\n')
|
||||
if (level != CE_DEBUG && message[len-1] != '\n')
|
||||
strcat(message, "\n");
|
||||
spin_unlock_irqrestore(&xfs_err_lock,flags);
|
||||
printk("%s%s", err_level[level], message);
|
||||
|
|
|
@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...)
|
|||
__attribute__ ((format (printf, 2, 3)));
|
||||
extern void assfail(char *expr, char *f, int l);
|
||||
|
||||
#define prdev(fmt,targ,args...) \
|
||||
printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
|
||||
|
||||
#define ASSERT_ALWAYS(expr) \
|
||||
(unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
|
||||
|
||||
|
|
|
@ -21,12 +21,10 @@
|
|||
#include "xfs_bit.h"
|
||||
#include "xfs_inum.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -39,15 +37,15 @@
|
|||
#include <linux/capability.h>
|
||||
#include <linux/posix_acl_xattr.h>
|
||||
|
||||
STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *);
|
||||
STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *);
|
||||
STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *);
|
||||
STATIC void xfs_acl_get_endian(xfs_acl_t *);
|
||||
STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
|
||||
STATIC int xfs_acl_invalid(xfs_acl_t *);
|
||||
STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *);
|
||||
STATIC void xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *);
|
||||
STATIC void xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *);
|
||||
STATIC int xfs_acl_allow_set(vnode_t *, int);
|
||||
STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *);
|
||||
STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *);
|
||||
STATIC int xfs_acl_allow_set(bhv_vnode_t *, int);
|
||||
|
||||
kmem_zone_t *xfs_acl_zone;
|
||||
|
||||
|
@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone;
|
|||
*/
|
||||
int
|
||||
xfs_acl_vhasacl_access(
|
||||
vnode_t *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
@ -70,7 +68,7 @@ xfs_acl_vhasacl_access(
|
|||
*/
|
||||
int
|
||||
xfs_acl_vhasacl_default(
|
||||
vnode_t *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
@ -209,7 +207,7 @@ posix_acl_xfs_to_xattr(
|
|||
|
||||
int
|
||||
xfs_acl_vget(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
void *acl,
|
||||
size_t size,
|
||||
int kind)
|
||||
|
@ -241,10 +239,10 @@ xfs_acl_vget(
|
|||
goto out;
|
||||
}
|
||||
if (kind == _ACL_TYPE_ACCESS) {
|
||||
vattr_t va;
|
||||
bhv_vattr_t va;
|
||||
|
||||
va.va_mask = XFS_AT_MODE;
|
||||
VOP_GETATTR(vp, &va, 0, sys_cred, error);
|
||||
error = bhv_vop_getattr(vp, &va, 0, sys_cred);
|
||||
if (error)
|
||||
goto out;
|
||||
xfs_acl_sync_mode(va.va_mode, xfs_acl);
|
||||
|
@ -260,7 +258,7 @@ out:
|
|||
|
||||
int
|
||||
xfs_acl_vremove(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
int kind)
|
||||
{
|
||||
int error;
|
||||
|
@ -268,9 +266,9 @@ xfs_acl_vremove(
|
|||
VN_HOLD(vp);
|
||||
error = xfs_acl_allow_set(vp, kind);
|
||||
if (!error) {
|
||||
VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT?
|
||||
error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT?
|
||||
SGI_ACL_DEFAULT: SGI_ACL_FILE,
|
||||
ATTR_ROOT, sys_cred, error);
|
||||
ATTR_ROOT, sys_cred);
|
||||
if (error == ENOATTR)
|
||||
error = 0; /* 'scool */
|
||||
}
|
||||
|
@ -280,7 +278,7 @@ xfs_acl_vremove(
|
|||
|
||||
int
|
||||
xfs_acl_vset(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
void *acl,
|
||||
size_t size,
|
||||
int kind)
|
||||
|
@ -370,10 +368,10 @@ xfs_acl_iaccess(
|
|||
|
||||
STATIC int
|
||||
xfs_acl_allow_set(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
int kind)
|
||||
{
|
||||
vattr_t va;
|
||||
bhv_vattr_t va;
|
||||
int error;
|
||||
|
||||
if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
|
||||
|
@ -383,7 +381,7 @@ xfs_acl_allow_set(
|
|||
if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
|
||||
return EROFS;
|
||||
va.va_mask = XFS_AT_UID;
|
||||
VOP_GETATTR(vp, &va, 0, NULL, error);
|
||||
error = bhv_vop_getattr(vp, &va, 0, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
|
||||
|
@ -606,7 +604,7 @@ xfs_acl_get_endian(
|
|||
*/
|
||||
STATIC void
|
||||
xfs_acl_get_attr(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_acl_t *aclp,
|
||||
int kind,
|
||||
int flags,
|
||||
|
@ -616,9 +614,9 @@ xfs_acl_get_attr(
|
|||
|
||||
ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
|
||||
flags |= ATTR_ROOT;
|
||||
VOP_ATTR_GET(vp,
|
||||
kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT,
|
||||
(char *)aclp, &len, flags, sys_cred, *error);
|
||||
*error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ?
|
||||
SGI_ACL_FILE : SGI_ACL_DEFAULT,
|
||||
(char *)aclp, &len, flags, sys_cred);
|
||||
if (*error || (flags & ATTR_KERNOVAL))
|
||||
return;
|
||||
xfs_acl_get_endian(aclp);
|
||||
|
@ -629,7 +627,7 @@ xfs_acl_get_attr(
|
|||
*/
|
||||
STATIC void
|
||||
xfs_acl_set_attr(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_acl_t *aclp,
|
||||
int kind,
|
||||
int *error)
|
||||
|
@ -654,19 +652,19 @@ xfs_acl_set_attr(
|
|||
INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
|
||||
}
|
||||
INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
|
||||
VOP_ATTR_SET(vp,
|
||||
kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT,
|
||||
(char *)newacl, len, ATTR_ROOT, sys_cred, *error);
|
||||
*error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ?
|
||||
SGI_ACL_FILE: SGI_ACL_DEFAULT,
|
||||
(char *)newacl, len, ATTR_ROOT, sys_cred);
|
||||
_ACL_FREE(newacl);
|
||||
}
|
||||
|
||||
int
|
||||
xfs_acl_vtoacl(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_acl_t *access_acl,
|
||||
xfs_acl_t *default_acl)
|
||||
{
|
||||
vattr_t va;
|
||||
bhv_vattr_t va;
|
||||
int error = 0;
|
||||
|
||||
if (access_acl) {
|
||||
|
@ -678,7 +676,7 @@ xfs_acl_vtoacl(
|
|||
if (!error) {
|
||||
/* Got the ACL, need the mode... */
|
||||
va.va_mask = XFS_AT_MODE;
|
||||
VOP_GETATTR(vp, &va, 0, sys_cred, error);
|
||||
error = bhv_vop_getattr(vp, &va, 0, sys_cred);
|
||||
}
|
||||
|
||||
if (error)
|
||||
|
@ -701,8 +699,8 @@ xfs_acl_vtoacl(
|
|||
*/
|
||||
int
|
||||
xfs_acl_inherit(
|
||||
vnode_t *vp,
|
||||
vattr_t *vap,
|
||||
bhv_vnode_t *vp,
|
||||
bhv_vattr_t *vap,
|
||||
xfs_acl_t *pdaclp)
|
||||
{
|
||||
xfs_acl_t *cacl;
|
||||
|
@ -757,11 +755,11 @@ xfs_acl_inherit(
|
|||
*/
|
||||
STATIC int
|
||||
xfs_acl_setmode(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_acl_t *acl,
|
||||
int *basicperms)
|
||||
{
|
||||
vattr_t va;
|
||||
bhv_vattr_t va;
|
||||
xfs_acl_entry_t *ap;
|
||||
xfs_acl_entry_t *gap = NULL;
|
||||
int i, error, nomask = 1;
|
||||
|
@ -776,7 +774,7 @@ xfs_acl_setmode(
|
|||
* mode. The m:: bits take precedence over the g:: bits.
|
||||
*/
|
||||
va.va_mask = XFS_AT_MODE;
|
||||
VOP_GETATTR(vp, &va, 0, sys_cred, error);
|
||||
error = bhv_vop_getattr(vp, &va, 0, sys_cred);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -810,8 +808,7 @@ xfs_acl_setmode(
|
|||
if (gap && nomask)
|
||||
va.va_mode |= gap->ae_perm << 3;
|
||||
|
||||
VOP_SETATTR(vp, &va, 0, sys_cred, error);
|
||||
return error;
|
||||
return bhv_vop_setattr(vp, &va, 0, sys_cred);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef struct xfs_acl {
|
|||
#ifdef CONFIG_XFS_POSIX_ACL
|
||||
|
||||
struct vattr;
|
||||
struct vnode;
|
||||
struct bhv_vnode;
|
||||
struct xfs_inode;
|
||||
|
||||
extern struct kmem_zone *xfs_acl_zone;
|
||||
|
@ -58,14 +58,14 @@ extern struct kmem_zone *xfs_acl_zone;
|
|||
(zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
|
||||
#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
|
||||
|
||||
extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *);
|
||||
extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *);
|
||||
extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
|
||||
extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *);
|
||||
extern int xfs_acl_vhasacl_access(struct vnode *);
|
||||
extern int xfs_acl_vhasacl_default(struct vnode *);
|
||||
extern int xfs_acl_vset(struct vnode *, void *, size_t, int);
|
||||
extern int xfs_acl_vget(struct vnode *, void *, size_t, int);
|
||||
extern int xfs_acl_vremove(struct vnode *vp, int);
|
||||
extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
|
||||
extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
|
||||
extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
|
||||
extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
|
||||
extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
|
||||
extern int xfs_acl_vremove(struct bhv_vnode *, int);
|
||||
|
||||
#define _ACL_TYPE_ACCESS 1
|
||||
#define _ACL_TYPE_DEFAULT 2
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist(
|
|||
(pag->pagf_longest - delta) :
|
||||
(pag->pagf_flcount > 0 || pag->pagf_longest > 0);
|
||||
if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
|
||||
(args->minleft &&
|
||||
(!(flags & XFS_ALLOC_FLAG_FREEING) &&
|
||||
(int)(pag->pagf_freeblks + pag->pagf_flcount -
|
||||
need - args->total) <
|
||||
(int)args->minleft)) {
|
||||
|
@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist(
|
|||
longest = (longest > delta) ? (longest - delta) :
|
||||
(be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
|
||||
if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
|
||||
(args->minleft &&
|
||||
(!(flags & XFS_ALLOC_FLAG_FREEING) &&
|
||||
(int)(be32_to_cpu(agf->agf_freeblks) +
|
||||
be32_to_cpu(agf->agf_flcount) - need - args->total) <
|
||||
(int)args->minleft)) {
|
||||
|
@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist(
|
|||
* the restrictions correctly. Can happen for free calls
|
||||
* on a completely full ag.
|
||||
*/
|
||||
if (targs.agbno == NULLAGBLOCK)
|
||||
if (targs.agbno == NULLAGBLOCK) {
|
||||
if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
|
||||
xfs_trans_brelse(tp, agflbp);
|
||||
args->agbp = NULL;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Put each allocated block on the list.
|
||||
*/
|
||||
|
@ -2360,8 +2364,19 @@ xfs_alloc_vextent(
|
|||
if (args->agno == sagno &&
|
||||
type == XFS_ALLOCTYPE_START_BNO)
|
||||
args->type = XFS_ALLOCTYPE_THIS_AG;
|
||||
if (++(args->agno) == mp->m_sb.sb_agcount)
|
||||
/*
|
||||
* For the first allocation, we can try any AG to get
|
||||
* space. However, if we already have allocated a
|
||||
* block, we don't want to try AGs whose number is below
|
||||
* sagno. Otherwise, we may end up with out-of-order
|
||||
* locking of AGF, which might cause deadlock.
|
||||
*/
|
||||
if (++(args->agno) == mp->m_sb.sb_agcount) {
|
||||
if (args->firstblock != NULLFSBLOCK)
|
||||
args->agno = sagno;
|
||||
else
|
||||
args->agno = 0;
|
||||
}
|
||||
/*
|
||||
* Reached the starting a.g., must either be done
|
||||
* or switch to non-trylock mode.
|
||||
|
@ -2443,7 +2458,7 @@ xfs_free_extent(
|
|||
args.minlen = args.minleft = args.minalignslop = 0;
|
||||
down_read(&args.mp->m_peraglock);
|
||||
args.pag = &args.mp->m_perag[args.agno];
|
||||
if ((error = xfs_alloc_fix_freelist(&args, 0)))
|
||||
if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
|
||||
goto error0;
|
||||
#ifdef DEBUG
|
||||
ASSERT(args.agbp != NULL);
|
||||
|
|
|
@ -41,6 +41,7 @@ typedef enum xfs_alloctype
|
|||
* Flags for xfs_alloc_fix_freelist.
|
||||
*/
|
||||
#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */
|
||||
#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
|
||||
|
||||
/*
|
||||
* Argument structure for xfs_alloc routines.
|
||||
|
@ -70,6 +71,7 @@ typedef struct xfs_alloc_arg {
|
|||
char wasfromfl; /* set if allocation is from freelist */
|
||||
char isfl; /* set if is freelist blocks - !acctg */
|
||||
char userdata; /* set if this is user data */
|
||||
xfs_fsblock_t firstblock; /* io first block allocated */
|
||||
} xfs_alloc_arg_t;
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
@ -35,7 +34,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -1910,7 +1908,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
|
|||
error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
|
||||
args->rmtblkcnt,
|
||||
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
|
||||
NULL, 0, map, &nmap, NULL);
|
||||
NULL, 0, map, &nmap, NULL, NULL);
|
||||
if (error)
|
||||
return(error);
|
||||
ASSERT(nmap >= 1);
|
||||
|
@ -1988,7 +1986,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
|
|||
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
|
||||
XFS_BMAPI_WRITE,
|
||||
args->firstblock, args->total, &map, &nmap,
|
||||
args->flist);
|
||||
args->flist, NULL);
|
||||
if (!error) {
|
||||
error = xfs_bmap_finish(&args->trans, args->flist,
|
||||
*args->firstblock, &committed);
|
||||
|
@ -2039,7 +2037,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
|
|||
error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
|
||||
args->rmtblkcnt,
|
||||
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
|
||||
args->firstblock, 0, &map, &nmap, NULL);
|
||||
args->firstblock, 0, &map, &nmap,
|
||||
NULL, NULL);
|
||||
if (error) {
|
||||
return(error);
|
||||
}
|
||||
|
@ -2104,7 +2103,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
|
|||
args->rmtblkcnt,
|
||||
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
|
||||
args->firstblock, 0, &map, &nmap,
|
||||
args->flist);
|
||||
args->flist, NULL);
|
||||
if (error) {
|
||||
return(error);
|
||||
}
|
||||
|
@ -2142,7 +2141,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
|
|||
XFS_BMAP_INIT(args->flist, args->firstblock);
|
||||
error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
|
||||
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
|
||||
1, args->firstblock, args->flist, &done);
|
||||
1, args->firstblock, args->flist,
|
||||
NULL, &done);
|
||||
if (!error) {
|
||||
error = xfs_bmap_finish(&args->trans, args->flist,
|
||||
*args->firstblock, &committed);
|
||||
|
@ -2322,56 +2322,56 @@ xfs_attr_trace_enter(int type, char *where,
|
|||
|
||||
STATIC int
|
||||
posix_acl_access_set(
|
||||
vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_access_remove(
|
||||
struct vnode *vp, char *name, int xflags)
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_access_get(
|
||||
vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_access_exists(
|
||||
vnode_t *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
return xfs_acl_vhasacl_access(vp);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_set(
|
||||
vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_get(
|
||||
vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_remove(
|
||||
struct vnode *vp, char *name, int xflags)
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
posix_acl_default_exists(
|
||||
vnode_t *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
return xfs_acl_vhasacl_default(vp);
|
||||
}
|
||||
|
@ -2404,21 +2404,18 @@ STATIC struct attrnames *attr_system_names[] =
|
|||
|
||||
STATIC int
|
||||
attr_generic_set(
|
||||
struct vnode *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
int error;
|
||||
|
||||
VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
|
||||
return -error;
|
||||
return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
attr_generic_get(
|
||||
struct vnode *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
int error, asize = size;
|
||||
|
||||
VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error);
|
||||
error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL);
|
||||
if (!error)
|
||||
return asize;
|
||||
return -error;
|
||||
|
@ -2426,12 +2423,9 @@ attr_generic_get(
|
|||
|
||||
STATIC int
|
||||
attr_generic_remove(
|
||||
struct vnode *vp, char *name, int xflags)
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
int error;
|
||||
|
||||
VOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
|
||||
return -error;
|
||||
return -bhv_vop_attr_remove(vp, name, xflags, NULL);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -2459,7 +2453,7 @@ attr_generic_listadd(
|
|||
|
||||
STATIC int
|
||||
attr_system_list(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
void *data,
|
||||
size_t size,
|
||||
ssize_t *result)
|
||||
|
@ -2481,12 +2475,12 @@ attr_system_list(
|
|||
|
||||
int
|
||||
attr_generic_list(
|
||||
struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result)
|
||||
bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
|
||||
{
|
||||
attrlist_cursor_kern_t cursor = { 0 };
|
||||
int error;
|
||||
|
||||
VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error);
|
||||
error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL);
|
||||
if (error > 0)
|
||||
return -error;
|
||||
*result = -error;
|
||||
|
@ -2514,7 +2508,7 @@ attr_lookup_namespace(
|
|||
*/
|
||||
STATIC int
|
||||
attr_user_capable(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
cred_t *cred)
|
||||
{
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
@ -2532,7 +2526,7 @@ attr_user_capable(
|
|||
|
||||
STATIC int
|
||||
attr_trusted_capable(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
cred_t *cred)
|
||||
{
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
@ -2546,7 +2540,7 @@ attr_trusted_capable(
|
|||
|
||||
STATIC int
|
||||
attr_secure_capable(
|
||||
struct vnode *vp,
|
||||
bhv_vnode_t *vp,
|
||||
cred_t *cred)
|
||||
{
|
||||
return -ENOSECURITY;
|
||||
|
@ -2554,7 +2548,7 @@ attr_secure_capable(
|
|||
|
||||
STATIC int
|
||||
attr_system_set(
|
||||
struct vnode *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
attrnames_t *namesp;
|
||||
int error;
|
||||
|
@ -2573,7 +2567,7 @@ attr_system_set(
|
|||
|
||||
STATIC int
|
||||
attr_system_get(
|
||||
struct vnode *vp, char *name, void *data, size_t size, int xflags)
|
||||
bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
|
||||
{
|
||||
attrnames_t *namesp;
|
||||
|
||||
|
@ -2585,7 +2579,7 @@ attr_system_get(
|
|||
|
||||
STATIC int
|
||||
attr_system_remove(
|
||||
struct vnode *vp, char *name, int xflags)
|
||||
bhv_vnode_t *vp, char *name, int xflags)
|
||||
{
|
||||
attrnames_t *namesp;
|
||||
|
||||
|
|
|
@ -36,13 +36,13 @@
|
|||
*========================================================================*/
|
||||
|
||||
struct cred;
|
||||
struct vnode;
|
||||
struct bhv_vnode;
|
||||
|
||||
typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int);
|
||||
typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int);
|
||||
typedef int (*attrremove_t)(struct vnode *, char *, int);
|
||||
typedef int (*attrexists_t)(struct vnode *);
|
||||
typedef int (*attrcapable_t)(struct vnode *, struct cred *);
|
||||
typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
|
||||
typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
|
||||
typedef int (*attrremove_t)(struct bhv_vnode *, char *, int);
|
||||
typedef int (*attrexists_t)(struct bhv_vnode *);
|
||||
typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *);
|
||||
|
||||
typedef struct attrnames {
|
||||
char * attr_name;
|
||||
|
@ -63,7 +63,7 @@ extern struct attrnames attr_trusted;
|
|||
extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
|
||||
|
||||
extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
|
||||
extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
|
||||
extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *);
|
||||
|
||||
#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
|
||||
#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
@ -34,7 +33,6 @@
|
|||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -2990,7 +2988,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
|
|||
nmap = 1;
|
||||
error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
|
||||
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
|
||||
NULL, 0, &map, &nmap, NULL);
|
||||
NULL, 0, &map, &nmap, NULL, NULL);
|
||||
if (error) {
|
||||
return(error);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -24,13 +24,11 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -40,13 +38,15 @@
|
|||
#include "xfs_mount.h"
|
||||
#include "xfs_ialloc.h"
|
||||
#include "xfs_itable.h"
|
||||
#include "xfs_dir2_data.h"
|
||||
#include "xfs_dir2_leaf.h"
|
||||
#include "xfs_dir2_block.h"
|
||||
#include "xfs_inode_item.h"
|
||||
#include "xfs_extfree_item.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_bmap.h"
|
||||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_dir_leaf.h"
|
||||
#include "xfs_attr_leaf.h"
|
||||
#include "xfs_rw.h"
|
||||
#include "xfs_quota.h"
|
||||
|
@ -101,6 +101,7 @@ xfs_bmap_add_extent(
|
|||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int whichfork, /* data or attr fork */
|
||||
int rsvd); /* OK to allocate reserved blocks */
|
||||
|
||||
|
@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int rsvd); /* OK to allocate reserved blocks */
|
||||
|
||||
/*
|
||||
|
@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(
|
|||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp,/* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int rsvd); /* OK to allocate reserved blocks */
|
||||
|
||||
/*
|
||||
|
@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(
|
|||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int whichfork); /* data or attr fork */
|
||||
|
||||
/*
|
||||
|
@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
xfs_extnum_t idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp); /* inode logging flags */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta); /* Change made to incore extents */
|
||||
|
||||
/*
|
||||
* xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
|
||||
|
@ -203,6 +208,7 @@ xfs_bmap_del_extent(
|
|||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp,/* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int whichfork, /* data or attr fork */
|
||||
int rsvd); /* OK to allocate reserved blocks */
|
||||
|
||||
|
@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local(
|
|||
dargs.total = mp->m_dirblkfsbs;
|
||||
dargs.whichfork = XFS_DATA_FORK;
|
||||
dargs.trans = tp;
|
||||
error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs);
|
||||
error = xfs_dir2_sf_to_block(&dargs);
|
||||
} else
|
||||
error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
|
||||
XFS_DATA_FORK);
|
||||
|
@ -530,6 +536,7 @@ xfs_bmap_add_extent(
|
|||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int whichfork, /* data or attr fork */
|
||||
int rsvd) /* OK to use reserved data blocks */
|
||||
{
|
||||
|
@ -567,6 +574,15 @@ xfs_bmap_add_extent(
|
|||
logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
|
||||
} else
|
||||
logflags = 0;
|
||||
/* DELTA: single new extent */
|
||||
if (delta) {
|
||||
if (delta->xed_startoff > new->br_startoff)
|
||||
delta->xed_startoff = new->br_startoff;
|
||||
if (delta->xed_blockcount <
|
||||
new->br_startoff + new->br_blockcount)
|
||||
delta->xed_blockcount = new->br_startoff +
|
||||
new->br_blockcount;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Any kind of new delayed allocation goes here.
|
||||
|
@ -576,7 +592,7 @@ xfs_bmap_add_extent(
|
|||
ASSERT((cur->bc_private.b.flags &
|
||||
XFS_BTCUR_BPRV_WASDEL) == 0);
|
||||
if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
|
||||
&logflags, rsvd)))
|
||||
&logflags, delta, rsvd)))
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
|
@ -587,7 +603,7 @@ xfs_bmap_add_extent(
|
|||
ASSERT((cur->bc_private.b.flags &
|
||||
XFS_BTCUR_BPRV_WASDEL) == 0);
|
||||
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
|
||||
&logflags, whichfork)))
|
||||
&logflags, delta, whichfork)))
|
||||
goto done;
|
||||
} else {
|
||||
xfs_bmbt_irec_t prev; /* old extent at offset idx */
|
||||
|
@ -612,17 +628,17 @@ xfs_bmap_add_extent(
|
|||
XFS_BTCUR_BPRV_WASDEL);
|
||||
if ((error = xfs_bmap_add_extent_delay_real(ip,
|
||||
idx, &cur, new, &da_new, first, flist,
|
||||
&logflags, rsvd)))
|
||||
&logflags, delta, rsvd)))
|
||||
goto done;
|
||||
} else if (new->br_state == XFS_EXT_NORM) {
|
||||
ASSERT(new->br_state == XFS_EXT_NORM);
|
||||
if ((error = xfs_bmap_add_extent_unwritten_real(
|
||||
ip, idx, &cur, new, &logflags)))
|
||||
ip, idx, &cur, new, &logflags, delta)))
|
||||
goto done;
|
||||
} else {
|
||||
ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
|
||||
if ((error = xfs_bmap_add_extent_unwritten_real(
|
||||
ip, idx, &cur, new, &logflags)))
|
||||
ip, idx, &cur, new, &logflags, delta)))
|
||||
goto done;
|
||||
}
|
||||
ASSERT(*curp == cur || *curp == NULL);
|
||||
|
@ -635,7 +651,7 @@ xfs_bmap_add_extent(
|
|||
ASSERT((cur->bc_private.b.flags &
|
||||
XFS_BTCUR_BPRV_WASDEL) == 0);
|
||||
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
|
||||
new, &logflags, whichfork)))
|
||||
new, &logflags, delta, whichfork)))
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int rsvd) /* OK to use reserved data block allocation */
|
||||
{
|
||||
xfs_btree_cur_t *cur; /* btree cursor */
|
||||
|
@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(
|
|||
/* left is 0, right is 1, prev is 2 */
|
||||
int rval=0; /* return value (logging flags) */
|
||||
int state = 0;/* state bits, accessed thru macros */
|
||||
xfs_filblks_t temp; /* value for dnew calculations */
|
||||
xfs_filblks_t temp2; /* value for dnew calculations */
|
||||
xfs_filblks_t temp=0; /* value for dnew calculations */
|
||||
xfs_filblks_t temp2=0;/* value for dnew calculations */
|
||||
int tmp_rval; /* partial logging flags */
|
||||
enum { /* bit number definitions for state */
|
||||
LEFT_CONTIG, RIGHT_CONTIG,
|
||||
|
@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
|
|||
goto done;
|
||||
}
|
||||
*dnew = 0;
|
||||
/* DELTA: Three in-core extents are replaced by one. */
|
||||
temp = LEFT.br_startoff;
|
||||
temp2 = LEFT.br_blockcount +
|
||||
PREV.br_blockcount +
|
||||
RIGHT.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
|
||||
|
@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
|
|||
goto done;
|
||||
}
|
||||
*dnew = 0;
|
||||
/* DELTA: Two in-core extents are replaced by one. */
|
||||
temp = LEFT.br_startoff;
|
||||
temp2 = LEFT.br_blockcount +
|
||||
PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
|
||||
|
@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
|
|||
goto done;
|
||||
}
|
||||
*dnew = 0;
|
||||
/* DELTA: Two in-core extents are replaced by one. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount +
|
||||
RIGHT.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK2(LEFT_FILLING, RIGHT_FILLING):
|
||||
|
@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
|
|||
ASSERT(i == 1);
|
||||
}
|
||||
*dnew = 0;
|
||||
/* DELTA: The in-core extent described by new changed type. */
|
||||
temp = new->br_startoff;
|
||||
temp2 = new->br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK2(LEFT_FILLING, LEFT_CONTIG):
|
||||
|
@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
|
||||
XFS_DATA_FORK);
|
||||
*dnew = temp;
|
||||
/* DELTA: The boundary between two in-core extents moved. */
|
||||
temp = LEFT.br_startoff;
|
||||
temp2 = LEFT.br_blockcount +
|
||||
PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK(LEFT_FILLING):
|
||||
|
@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
|
||||
XFS_DATA_FORK);
|
||||
*dnew = temp;
|
||||
/* DELTA: One in-core extent is split in two. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
|
||||
|
@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
|
||||
XFS_DATA_FORK);
|
||||
*dnew = temp;
|
||||
/* DELTA: The boundary between two in-core extents moved. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount +
|
||||
RIGHT.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK(RIGHT_FILLING):
|
||||
|
@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
|
||||
xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
|
||||
*dnew = temp;
|
||||
/* DELTA: One in-core extent is split in two. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
|
@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
|
||||
XFS_DATA_FORK);
|
||||
*dnew = temp + temp2;
|
||||
/* DELTA: One in-core extent is split in three. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
|
||||
|
@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
|
|||
ASSERT(0);
|
||||
}
|
||||
*curp = cur;
|
||||
if (delta) {
|
||||
temp2 += temp;
|
||||
if (delta->xed_startoff > temp)
|
||||
delta->xed_startoff = temp;
|
||||
if (delta->xed_blockcount < temp2)
|
||||
delta->xed_blockcount = temp2;
|
||||
}
|
||||
done:
|
||||
*logflagsp = rval;
|
||||
return error;
|
||||
|
@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
xfs_extnum_t idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp) /* inode logging flags */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta) /* Change made to incore extents */
|
||||
{
|
||||
xfs_btree_cur_t *cur; /* btree cursor */
|
||||
xfs_bmbt_rec_t *ep; /* extent entry for idx */
|
||||
|
@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
/* left is 0, right is 1, prev is 2 */
|
||||
int rval=0; /* return value (logging flags) */
|
||||
int state = 0;/* state bits, accessed thru macros */
|
||||
xfs_filblks_t temp=0;
|
||||
xfs_filblks_t temp2=0;
|
||||
enum { /* bit number definitions for state */
|
||||
LEFT_CONTIG, RIGHT_CONTIG,
|
||||
LEFT_FILLING, RIGHT_FILLING,
|
||||
|
@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
RIGHT.br_blockcount, LEFT.br_state)))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: Three in-core extents are replaced by one. */
|
||||
temp = LEFT.br_startoff;
|
||||
temp2 = LEFT.br_blockcount +
|
||||
PREV.br_blockcount +
|
||||
RIGHT.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
|
||||
|
@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
LEFT.br_state)))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: Two in-core extents are replaced by one. */
|
||||
temp = LEFT.br_startoff;
|
||||
temp2 = LEFT.br_blockcount +
|
||||
PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
|
||||
|
@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
newext)))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: Two in-core extents are replaced by one. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount +
|
||||
RIGHT.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK2(LEFT_FILLING, RIGHT_FILLING):
|
||||
|
@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
newext)))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: The in-core extent described by new changed type. */
|
||||
temp = new->br_startoff;
|
||||
temp2 = new->br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK2(LEFT_FILLING, LEFT_CONTIG):
|
||||
|
@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
LEFT.br_state))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: The boundary between two in-core extents moved. */
|
||||
temp = LEFT.br_startoff;
|
||||
temp2 = LEFT.br_blockcount +
|
||||
PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK(LEFT_FILLING):
|
||||
|
@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
goto done;
|
||||
ASSERT(i == 1);
|
||||
}
|
||||
/* DELTA: One in-core extent is split in two. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
|
||||
|
@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
newext)))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: The boundary between two in-core extents moved. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount +
|
||||
RIGHT.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK(RIGHT_FILLING):
|
||||
|
@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
goto done;
|
||||
ASSERT(i == 1);
|
||||
}
|
||||
/* DELTA: One in-core extent is split in two. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
|
@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
goto done;
|
||||
ASSERT(i == 1);
|
||||
}
|
||||
/* DELTA: One in-core extent is split in three. */
|
||||
temp = PREV.br_startoff;
|
||||
temp2 = PREV.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
|
||||
|
@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
ASSERT(0);
|
||||
}
|
||||
*curp = cur;
|
||||
if (delta) {
|
||||
temp2 += temp;
|
||||
if (delta->xed_startoff > temp)
|
||||
delta->xed_startoff = temp;
|
||||
if (delta->xed_blockcount < temp2)
|
||||
delta->xed_blockcount = temp2;
|
||||
}
|
||||
done:
|
||||
*logflagsp = rval;
|
||||
return error;
|
||||
|
@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
|
|||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int rsvd) /* OK to allocate reserved blocks */
|
||||
{
|
||||
xfs_bmbt_rec_t *ep; /* extent record for idx */
|
||||
|
@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(
|
|||
xfs_filblks_t oldlen=0; /* old indirect size */
|
||||
xfs_bmbt_irec_t right; /* right neighbor extent entry */
|
||||
int state; /* state bits, accessed thru macros */
|
||||
xfs_filblks_t temp; /* temp for indirect calculations */
|
||||
xfs_filblks_t temp=0; /* temp for indirect calculations */
|
||||
xfs_filblks_t temp2=0;
|
||||
enum { /* bit number definitions for state */
|
||||
LEFT_CONTIG, RIGHT_CONTIG,
|
||||
LEFT_DELAY, RIGHT_DELAY,
|
||||
|
@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
|
|||
XFS_DATA_FORK);
|
||||
xfs_iext_remove(ifp, idx, 1);
|
||||
ip->i_df.if_lastex = idx - 1;
|
||||
/* DELTA: Two in-core extents were replaced by one. */
|
||||
temp2 = temp;
|
||||
temp = left.br_startoff;
|
||||
break;
|
||||
|
||||
case MASK(LEFT_CONTIG):
|
||||
|
@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(
|
|||
xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
|
||||
XFS_DATA_FORK);
|
||||
ip->i_df.if_lastex = idx - 1;
|
||||
/* DELTA: One in-core extent grew into a hole. */
|
||||
temp2 = temp;
|
||||
temp = left.br_startoff;
|
||||
break;
|
||||
|
||||
case MASK(RIGHT_CONTIG):
|
||||
|
@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
|
|||
NULLSTARTBLOCK((int)newlen), temp, right.br_state);
|
||||
xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
|
||||
ip->i_df.if_lastex = idx;
|
||||
/* DELTA: One in-core extent grew into a hole. */
|
||||
temp2 = temp;
|
||||
temp = new->br_startoff;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
|
@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
|
|||
XFS_DATA_FORK);
|
||||
xfs_iext_insert(ifp, idx, 1, new);
|
||||
ip->i_df.if_lastex = idx;
|
||||
/* DELTA: A new in-core extent was added in a hole. */
|
||||
temp2 = new->br_blockcount;
|
||||
temp = new->br_startoff;
|
||||
break;
|
||||
}
|
||||
if (oldlen != newlen) {
|
||||
|
@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
|
|||
* Nothing to do for disk quota accounting here.
|
||||
*/
|
||||
}
|
||||
if (delta) {
|
||||
temp2 += temp;
|
||||
if (delta->xed_startoff > temp)
|
||||
delta->xed_startoff = temp;
|
||||
if (delta->xed_blockcount < temp2)
|
||||
delta->xed_blockcount = temp2;
|
||||
}
|
||||
*logflagsp = 0;
|
||||
return 0;
|
||||
#undef MASK
|
||||
|
@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
|
|||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int whichfork) /* data or attr fork */
|
||||
{
|
||||
xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
|
||||
|
@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(
|
|||
xfs_ifork_t *ifp; /* inode fork pointer */
|
||||
xfs_bmbt_irec_t left; /* left neighbor extent entry */
|
||||
xfs_bmbt_irec_t right; /* right neighbor extent entry */
|
||||
int rval=0; /* return value (logging flags) */
|
||||
int state; /* state bits, accessed thru macros */
|
||||
xfs_filblks_t temp=0;
|
||||
xfs_filblks_t temp2=0;
|
||||
enum { /* bit number definitions for state */
|
||||
LEFT_CONTIG, RIGHT_CONTIG,
|
||||
LEFT_DELAY, RIGHT_DELAY,
|
||||
|
@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
|
|||
left.br_blockcount + new->br_blockcount +
|
||||
right.br_blockcount <= MAXEXTLEN));
|
||||
|
||||
error = 0;
|
||||
/*
|
||||
* Select which case we're in here, and implement it.
|
||||
*/
|
||||
|
@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(
|
|||
XFS_IFORK_NEXT_SET(ip, whichfork,
|
||||
XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
|
||||
if (cur == NULL) {
|
||||
*logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
|
||||
return 0;
|
||||
}
|
||||
*logflagsp = XFS_ILOG_CORE;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff,
|
||||
right.br_startblock, right.br_blockcount, &i)))
|
||||
return error;
|
||||
rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
|
||||
} else {
|
||||
rval = XFS_ILOG_CORE;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur,
|
||||
right.br_startoff,
|
||||
right.br_startblock,
|
||||
right.br_blockcount, &i)))
|
||||
goto done;
|
||||
ASSERT(i == 1);
|
||||
if ((error = xfs_bmbt_delete(cur, &i)))
|
||||
return error;
|
||||
goto done;
|
||||
ASSERT(i == 1);
|
||||
if ((error = xfs_bmbt_decrement(cur, 0, &i)))
|
||||
return error;
|
||||
goto done;
|
||||
ASSERT(i == 1);
|
||||
error = xfs_bmbt_update(cur, left.br_startoff,
|
||||
if ((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;
|
||||
left.br_blockcount +
|
||||
new->br_blockcount +
|
||||
right.br_blockcount,
|
||||
left.br_state)))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: Two in-core extents were replaced by one. */
|
||||
temp = left.br_startoff;
|
||||
temp2 = left.br_blockcount +
|
||||
new->br_blockcount +
|
||||
right.br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK(LEFT_CONTIG):
|
||||
/*
|
||||
|
@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(
|
|||
xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
|
||||
ifp->if_lastex = idx - 1;
|
||||
if (cur == NULL) {
|
||||
*logflagsp = XFS_ILOG_FEXT(whichfork);
|
||||
return 0;
|
||||
}
|
||||
*logflagsp = 0;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff,
|
||||
left.br_startblock, left.br_blockcount, &i)))
|
||||
return error;
|
||||
ASSERT(i == 1);
|
||||
error = xfs_bmbt_update(cur, left.br_startoff,
|
||||
rval = XFS_ILOG_FEXT(whichfork);
|
||||
} else {
|
||||
rval = 0;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur,
|
||||
left.br_startoff,
|
||||
left.br_startblock,
|
||||
left.br_blockcount + new->br_blockcount,
|
||||
left.br_state);
|
||||
return error;
|
||||
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;
|
||||
}
|
||||
/* DELTA: One in-core extent grew. */
|
||||
temp = left.br_startoff;
|
||||
temp2 = left.br_blockcount +
|
||||
new->br_blockcount;
|
||||
break;
|
||||
|
||||
case MASK(RIGHT_CONTIG):
|
||||
/*
|
||||
|
@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
|
|||
xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
|
||||
ifp->if_lastex = idx;
|
||||
if (cur == NULL) {
|
||||
*logflagsp = XFS_ILOG_FEXT(whichfork);
|
||||
return 0;
|
||||
}
|
||||
*logflagsp = 0;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff,
|
||||
right.br_startblock, right.br_blockcount, &i)))
|
||||
return error;
|
||||
rval = XFS_ILOG_FEXT(whichfork);
|
||||
} else {
|
||||
rval = 0;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur,
|
||||
right.br_startoff,
|
||||
right.br_startblock,
|
||||
right.br_blockcount, &i)))
|
||||
goto done;
|
||||
ASSERT(i == 1);
|
||||
error = xfs_bmbt_update(cur, new->br_startoff,
|
||||
if ((error = xfs_bmbt_update(cur, new->br_startoff,
|
||||
new->br_startblock,
|
||||
new->br_blockcount + right.br_blockcount,
|
||||
right.br_state);
|
||||
return error;
|
||||
new->br_blockcount +
|
||||
right.br_blockcount,
|
||||
right.br_state)))
|
||||
goto done;
|
||||
}
|
||||
/* DELTA: One in-core extent grew. */
|
||||
temp = new->br_startoff;
|
||||
temp2 = new->br_blockcount +
|
||||
right.br_blockcount;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
/*
|
||||
|
@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
|
|||
XFS_IFORK_NEXT_SET(ip, whichfork,
|
||||
XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
|
||||
if (cur == NULL) {
|
||||
*logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
|
||||
return 0;
|
||||
}
|
||||
*logflagsp = XFS_ILOG_CORE;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
|
||||
new->br_startblock, new->br_blockcount, &i)))
|
||||
return error;
|
||||
rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
|
||||
} else {
|
||||
rval = XFS_ILOG_CORE;
|
||||
if ((error = xfs_bmbt_lookup_eq(cur,
|
||||
new->br_startoff,
|
||||
new->br_startblock,
|
||||
new->br_blockcount, &i)))
|
||||
goto done;
|
||||
ASSERT(i == 0);
|
||||
cur->bc_rec.b.br_state = new->br_state;
|
||||
if ((error = xfs_bmbt_insert(cur, &i)))
|
||||
return error;
|
||||
goto done;
|
||||
ASSERT(i == 1);
|
||||
return 0;
|
||||
}
|
||||
/* DELTA: A new extent was added in a hole. */
|
||||
temp = new->br_startoff;
|
||||
temp2 = new->br_blockcount;
|
||||
break;
|
||||
}
|
||||
if (delta) {
|
||||
temp2 += temp;
|
||||
if (delta->xed_startoff > temp)
|
||||
delta->xed_startoff = temp;
|
||||
if (delta->xed_blockcount < temp2)
|
||||
delta->xed_blockcount = temp2;
|
||||
}
|
||||
done:
|
||||
*logflagsp = rval;
|
||||
return error;
|
||||
#undef MASK
|
||||
#undef MASK2
|
||||
#undef STATE_SET
|
||||
#undef STATE_TEST
|
||||
#undef STATE_SET_TEST
|
||||
#undef SWITCH_STATE
|
||||
/* NOTREACHED */
|
||||
ASSERT(0);
|
||||
return 0; /* keep gcc quite */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2598,6 +2762,7 @@ xfs_bmap_btalloc(
|
|||
args.mp = mp;
|
||||
args.fsbno = ap->rval;
|
||||
args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
|
||||
args.firstblock = ap->firstblock;
|
||||
blen = 0;
|
||||
if (nullfb) {
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
|
@ -2657,7 +2822,7 @@ xfs_bmap_btalloc(
|
|||
else
|
||||
args.minlen = ap->alen;
|
||||
} else if (ap->low) {
|
||||
args.type = XFS_ALLOCTYPE_FIRST_AG;
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
args.total = args.minlen = ap->minlen;
|
||||
} else {
|
||||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
|
@ -2669,7 +2834,7 @@ xfs_bmap_btalloc(
|
|||
args.prod = ap->ip->i_d.di_extsize;
|
||||
if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
|
||||
args.mod = (xfs_extlen_t)(args.prod - args.mod);
|
||||
} else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {
|
||||
} else if (mp->m_sb.sb_blocksize >= NBPP) {
|
||||
args.prod = 1;
|
||||
args.mod = 0;
|
||||
} else {
|
||||
|
@ -2885,6 +3050,7 @@ xfs_bmap_del_extent(
|
|||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *del, /* data to remove from extents */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
xfs_extdelta_t *delta, /* Change made to incore extents */
|
||||
int whichfork, /* data or attr fork */
|
||||
int rsvd) /* OK to allocate reserved blocks */
|
||||
{
|
||||
|
@ -3193,6 +3359,14 @@ xfs_bmap_del_extent(
|
|||
if (da_old > da_new)
|
||||
xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
|
||||
rsvd);
|
||||
if (delta) {
|
||||
/* DELTA: report the original extent. */
|
||||
if (delta->xed_startoff > got.br_startoff)
|
||||
delta->xed_startoff = got.br_startoff;
|
||||
if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
|
||||
delta->xed_blockcount = got.br_startoff +
|
||||
got.br_blockcount;
|
||||
}
|
||||
done:
|
||||
*logflagsp = flags;
|
||||
return error;
|
||||
|
@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree(
|
|||
XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
|
||||
args.tp = tp;
|
||||
args.mp = mp;
|
||||
args.firstblock = *firstblock;
|
||||
if (*firstblock == NULLFSBLOCK) {
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
|
||||
|
@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents(
|
|||
|
||||
args.tp = tp;
|
||||
args.mp = ip->i_mount;
|
||||
args.firstblock = *firstblock;
|
||||
ASSERT((ifp->if_flags &
|
||||
(XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
|
||||
/*
|
||||
|
@ -3753,7 +3929,7 @@ xfs_bunmap_trace(
|
|||
if (ip->i_rwtrace == NULL)
|
||||
return;
|
||||
ktrace_enter(ip->i_rwtrace,
|
||||
(void *)(__psint_t)XFS_BUNMAPI,
|
||||
(void *)(__psint_t)XFS_BUNMAP,
|
||||
(void *)ip,
|
||||
(void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
|
||||
(void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
|
||||
|
@ -4087,8 +4263,8 @@ xfs_bmap_finish(
|
|||
if (!XFS_FORCED_SHUTDOWN(mp))
|
||||
xfs_force_shutdown(mp,
|
||||
(error == EFSCORRUPTED) ?
|
||||
XFS_CORRUPT_INCORE :
|
||||
XFS_METADATA_IO_ERROR);
|
||||
SHUTDOWN_CORRUPT_INCORE :
|
||||
SHUTDOWN_META_IO_ERROR);
|
||||
return error;
|
||||
}
|
||||
xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
|
||||
|
@ -4538,7 +4714,8 @@ xfs_bmapi(
|
|||
xfs_extlen_t total, /* total blocks needed */
|
||||
xfs_bmbt_irec_t *mval, /* output: map values */
|
||||
int *nmap, /* i/o: mval size/count */
|
||||
xfs_bmap_free_t *flist) /* i/o: list extents to free */
|
||||
xfs_bmap_free_t *flist, /* i/o: list extents to free */
|
||||
xfs_extdelta_t *delta) /* o: change made to incore extents */
|
||||
{
|
||||
xfs_fsblock_t abno; /* allocated block number */
|
||||
xfs_extlen_t alen; /* allocated extent length */
|
||||
|
@ -4650,6 +4827,10 @@ xfs_bmapi(
|
|||
end = bno + len;
|
||||
obno = bno;
|
||||
bma.ip = NULL;
|
||||
if (delta) {
|
||||
delta->xed_startoff = NULLFILEOFF;
|
||||
delta->xed_blockcount = 0;
|
||||
}
|
||||
while (bno < end && n < *nmap) {
|
||||
/*
|
||||
* Reading past eof, act as though there's a hole
|
||||
|
@ -4886,8 +5067,8 @@ xfs_bmapi(
|
|||
got.br_state = XFS_EXT_UNWRITTEN;
|
||||
}
|
||||
error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
|
||||
firstblock, flist, &tmp_logflags, whichfork,
|
||||
(flags & XFS_BMAPI_RSVBLOCKS));
|
||||
firstblock, flist, &tmp_logflags, delta,
|
||||
whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
|
||||
logflags |= tmp_logflags;
|
||||
if (error)
|
||||
goto error0;
|
||||
|
@ -4983,8 +5164,8 @@ xfs_bmapi(
|
|||
}
|
||||
mval->br_state = XFS_EXT_NORM;
|
||||
error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
|
||||
firstblock, flist, &tmp_logflags, whichfork,
|
||||
(flags & XFS_BMAPI_RSVBLOCKS));
|
||||
firstblock, flist, &tmp_logflags, delta,
|
||||
whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
|
||||
logflags |= tmp_logflags;
|
||||
if (error)
|
||||
goto error0;
|
||||
|
@ -5073,7 +5254,14 @@ xfs_bmapi(
|
|||
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
|
||||
XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
|
||||
error = 0;
|
||||
|
||||
if (delta && delta->xed_startoff != NULLFILEOFF) {
|
||||
/* A change was actually made.
|
||||
* Note that delta->xed_blockount is an offset at this
|
||||
* point and needs to be converted to a block count.
|
||||
*/
|
||||
ASSERT(delta->xed_blockcount > delta->xed_startoff);
|
||||
delta->xed_blockcount -= delta->xed_startoff;
|
||||
}
|
||||
error0:
|
||||
/*
|
||||
* Log everything. Do this after conversion, there's no point in
|
||||
|
@ -5185,6 +5373,8 @@ xfs_bunmapi(
|
|||
xfs_fsblock_t *firstblock, /* first allocated block
|
||||
controls a.g. for allocs */
|
||||
xfs_bmap_free_t *flist, /* i/o: list extents to free */
|
||||
xfs_extdelta_t *delta, /* o: change made to incore
|
||||
extents */
|
||||
int *done) /* set if not done yet */
|
||||
{
|
||||
xfs_btree_cur_t *cur; /* bmap btree cursor */
|
||||
|
@ -5242,6 +5432,10 @@ xfs_bunmapi(
|
|||
bno = start + len - 1;
|
||||
ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
|
||||
&prev);
|
||||
if (delta) {
|
||||
delta->xed_startoff = NULLFILEOFF;
|
||||
delta->xed_blockcount = 0;
|
||||
}
|
||||
/*
|
||||
* Check to see if the given block number is past the end of the
|
||||
* file, back up to the last block if so...
|
||||
|
@ -5340,7 +5534,8 @@ xfs_bunmapi(
|
|||
}
|
||||
del.br_state = XFS_EXT_UNWRITTEN;
|
||||
error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
|
||||
firstblock, flist, &logflags, XFS_DATA_FORK, 0);
|
||||
firstblock, flist, &logflags, delta,
|
||||
XFS_DATA_FORK, 0);
|
||||
if (error)
|
||||
goto error0;
|
||||
goto nodelete;
|
||||
|
@ -5394,7 +5589,7 @@ xfs_bunmapi(
|
|||
prev.br_state = XFS_EXT_UNWRITTEN;
|
||||
error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
|
||||
&prev, firstblock, flist, &logflags,
|
||||
XFS_DATA_FORK, 0);
|
||||
delta, XFS_DATA_FORK, 0);
|
||||
if (error)
|
||||
goto error0;
|
||||
goto nodelete;
|
||||
|
@ -5403,7 +5598,7 @@ xfs_bunmapi(
|
|||
del.br_state = XFS_EXT_UNWRITTEN;
|
||||
error = xfs_bmap_add_extent(ip, lastx, &cur,
|
||||
&del, firstblock, flist, &logflags,
|
||||
XFS_DATA_FORK, 0);
|
||||
delta, XFS_DATA_FORK, 0);
|
||||
if (error)
|
||||
goto error0;
|
||||
goto nodelete;
|
||||
|
@ -5456,7 +5651,7 @@ xfs_bunmapi(
|
|||
goto error0;
|
||||
}
|
||||
error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
|
||||
&tmp_logflags, whichfork, rsvd);
|
||||
&tmp_logflags, delta, whichfork, rsvd);
|
||||
logflags |= tmp_logflags;
|
||||
if (error)
|
||||
goto error0;
|
||||
|
@ -5513,6 +5708,14 @@ nodelete:
|
|||
ASSERT(ifp->if_ext_max ==
|
||||
XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
||||
error = 0;
|
||||
if (delta && delta->xed_startoff != NULLFILEOFF) {
|
||||
/* A change was actually made.
|
||||
* Note that delta->xed_blockount is an offset at this
|
||||
* point and needs to be converted to a block count.
|
||||
*/
|
||||
ASSERT(delta->xed_blockcount > delta->xed_startoff);
|
||||
delta->xed_blockcount -= delta->xed_startoff;
|
||||
}
|
||||
error0:
|
||||
/*
|
||||
* Log everything. Do this after conversion, there's no point in
|
||||
|
@ -5556,7 +5759,7 @@ xfs_getbmap(
|
|||
__int64_t fixlen; /* length for -1 case */
|
||||
int i; /* extent number */
|
||||
xfs_inode_t *ip; /* xfs incore inode pointer */
|
||||
vnode_t *vp; /* corresponding vnode */
|
||||
bhv_vnode_t *vp; /* corresponding vnode */
|
||||
int lock; /* lock state */
|
||||
xfs_bmbt_irec_t *map; /* buffer for user's data */
|
||||
xfs_mount_t *mp; /* file system mount point */
|
||||
|
@ -5653,7 +5856,7 @@ xfs_getbmap(
|
|||
|
||||
if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
|
||||
/* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
|
||||
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
|
||||
error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
|
||||
}
|
||||
|
||||
ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
|
||||
|
@ -5689,7 +5892,8 @@ xfs_getbmap(
|
|||
nmap = (nexleft > subnex) ? subnex : nexleft;
|
||||
error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
|
||||
XFS_BB_TO_FSB(mp, bmv->bmv_length),
|
||||
bmapi_flags, NULL, 0, map, &nmap, NULL);
|
||||
bmapi_flags, NULL, 0, map, &nmap,
|
||||
NULL, NULL);
|
||||
if (error)
|
||||
goto unlock_and_return;
|
||||
ASSERT(nmap <= subnex);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -25,6 +25,20 @@ struct xfs_inode;
|
|||
struct xfs_mount;
|
||||
struct xfs_trans;
|
||||
|
||||
/*
|
||||
* DELTA: describe a change to the in-core extent list.
|
||||
*
|
||||
* Internally the use of xed_blockount is somewhat funky.
|
||||
* xed_blockcount contains an offset much of the time because this
|
||||
* makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
|
||||
* the same underlying type).
|
||||
*/
|
||||
typedef struct xfs_extdelta
|
||||
{
|
||||
xfs_fileoff_t xed_startoff; /* offset of range */
|
||||
xfs_filblks_t xed_blockcount; /* blocks in range */
|
||||
} xfs_extdelta_t;
|
||||
|
||||
/*
|
||||
* List of extents to be free "later".
|
||||
* The list is kept sorted on xbf_startblock.
|
||||
|
@ -275,7 +289,9 @@ xfs_bmapi(
|
|||
xfs_extlen_t total, /* total blocks needed */
|
||||
struct xfs_bmbt_irec *mval, /* output: map values */
|
||||
int *nmap, /* i/o: mval size/count */
|
||||
xfs_bmap_free_t *flist); /* i/o: list extents to free */
|
||||
xfs_bmap_free_t *flist, /* i/o: list extents to free */
|
||||
xfs_extdelta_t *delta); /* o: change made to incore
|
||||
extents */
|
||||
|
||||
/*
|
||||
* Map file blocks to filesystem blocks, simple version.
|
||||
|
@ -309,6 +325,8 @@ xfs_bunmapi(
|
|||
xfs_fsblock_t *firstblock, /* first allocated block
|
||||
controls a.g. for allocs */
|
||||
xfs_bmap_free_t *flist, /* i/o: list extents to free */
|
||||
xfs_extdelta_t *delta, /* o: change made to incore
|
||||
extents */
|
||||
int *done); /* set if not done yet */
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -1569,12 +1567,11 @@ xfs_bmbt_split(
|
|||
lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
|
||||
left = XFS_BUF_TO_BMBT_BLOCK(lbp);
|
||||
args.fsbno = cur->bc_private.b.firstblock;
|
||||
args.firstblock = args.fsbno;
|
||||
if (args.fsbno == NULLFSBLOCK) {
|
||||
args.fsbno = lbno;
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
} else if (cur->bc_private.b.flist->xbf_low)
|
||||
args.type = XFS_ALLOCTYPE_FIRST_AG;
|
||||
else
|
||||
} else
|
||||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
args.mod = args.minleft = args.alignment = args.total = args.isfl =
|
||||
args.userdata = args.minalignslop = 0;
|
||||
|
@ -2356,6 +2353,7 @@ xfs_bmbt_newroot(
|
|||
args.userdata = args.minalignslop = 0;
|
||||
args.minlen = args.maxlen = args.prod = 1;
|
||||
args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
|
||||
args.firstblock = args.fsbno;
|
||||
if (args.fsbno == NULLFSBLOCK) {
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
|
||||
|
@ -2365,9 +2363,7 @@ xfs_bmbt_newroot(
|
|||
#endif
|
||||
args.fsbno = INT_GET(*pp, ARCH_CONVERT);
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
} else if (args.wasdel)
|
||||
args.type = XFS_ALLOCTYPE_FIRST_AG;
|
||||
else
|
||||
} else
|
||||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
if ((error = xfs_alloc_vextent(&args))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_buf_item.h"
|
||||
|
@ -1030,9 +1029,9 @@ xfs_buf_iodone_callbacks(
|
|||
if ((XFS_BUF_TARGET(bp) != lasttarg) ||
|
||||
(time_after(jiffies, (lasttime + 5*HZ)))) {
|
||||
lasttime = jiffies;
|
||||
prdev("XFS write error in file system meta-data "
|
||||
"block 0x%llx in %s",
|
||||
XFS_BUF_TARGET(bp),
|
||||
cmn_err(CE_ALERT, "Device %s, XFS metadata write error"
|
||||
" block 0x%llx in %s",
|
||||
XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
|
||||
(__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname);
|
||||
}
|
||||
lasttarg = XFS_BUF_TARGET(bp);
|
||||
|
@ -1108,7 +1107,7 @@ xfs_buf_error_relse(
|
|||
XFS_BUF_ERROR(bp,0);
|
||||
xfs_buftrace("BUF_ERROR_RELSE", bp);
|
||||
if (! XFS_FORCED_SHUTDOWN(mp))
|
||||
xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
|
||||
/*
|
||||
* We have to unpin the pinned buffers so do the
|
||||
* callbacks.
|
||||
|
|
|
@ -49,12 +49,12 @@ typedef struct xfs_cap_set {
|
|||
|
||||
#include <linux/posix_cap_xattr.h>
|
||||
|
||||
struct vnode;
|
||||
struct bhv_vnode;
|
||||
|
||||
extern int xfs_cap_vhascap(struct vnode *);
|
||||
extern int xfs_cap_vset(struct vnode *, void *, size_t);
|
||||
extern int xfs_cap_vget(struct vnode *, void *, size_t);
|
||||
extern int xfs_cap_vremove(struct vnode *vp);
|
||||
extern int xfs_cap_vhascap(struct bhv_vnode *);
|
||||
extern int xfs_cap_vset(struct bhv_vnode *, void *, size_t);
|
||||
extern int xfs_cap_vget(struct bhv_vnode *, void *, size_t);
|
||||
extern int xfs_cap_vremove(struct bhv_vnode *);
|
||||
|
||||
#define _CAP_EXISTS xfs_cap_vhascap
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -43,7 +41,6 @@
|
|||
#include "xfs_bmap.h"
|
||||
#include "xfs_attr.h"
|
||||
#include "xfs_attr_leaf.h"
|
||||
#include "xfs_dir_leaf.h"
|
||||
#include "xfs_dir2_data.h"
|
||||
#include "xfs_dir2_leaf.h"
|
||||
#include "xfs_dir2_block.h"
|
||||
|
@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state)
|
|||
max = state->path.active - 1;
|
||||
ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
|
||||
ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
|
||||
state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp));
|
||||
state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
|
||||
|
||||
addblk = &state->path.blk[max]; /* initial dummy value */
|
||||
for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
|
||||
|
@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state)
|
|||
return(error); /* GROT: attr inconsistent */
|
||||
addblk = newblk;
|
||||
break;
|
||||
case XFS_DIR_LEAF_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V1(state->mp));
|
||||
error = xfs_dir_leaf_split(state, oldblk, newblk);
|
||||
if ((error != 0) && (error != ENOSPC)) {
|
||||
return(error); /* GROT: dir is inconsistent */
|
||||
}
|
||||
if (!error) {
|
||||
addblk = newblk;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Entry wouldn't fit, split the leaf again.
|
||||
*/
|
||||
state->extravalid = 1;
|
||||
if (state->inleaf) {
|
||||
state->extraafter = 0; /* before newblk */
|
||||
error = xfs_dir_leaf_split(state, oldblk,
|
||||
&state->extrablk);
|
||||
if (error)
|
||||
return(error); /* GROT: dir incon. */
|
||||
addblk = newblk;
|
||||
} else {
|
||||
state->extraafter = 1; /* after newblk */
|
||||
error = xfs_dir_leaf_split(state, newblk,
|
||||
&state->extrablk);
|
||||
if (error)
|
||||
return(error); /* GROT: dir incon. */
|
||||
addblk = newblk;
|
||||
}
|
||||
break;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V2(state->mp));
|
||||
error = xfs_dir2_leafn_split(state, oldblk, newblk);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
|||
size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
|
||||
(char *)oldroot);
|
||||
} else {
|
||||
ASSERT(XFS_DIR_IS_V2(mp));
|
||||
ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
leaf = (xfs_dir2_leaf_t *)oldroot;
|
||||
size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
|
||||
|
@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
|||
* Set up the new root node.
|
||||
*/
|
||||
error = xfs_da_node_create(args,
|
||||
args->whichfork == XFS_DATA_FORK &&
|
||||
XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
|
||||
(args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,
|
||||
be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return(error);
|
||||
|
@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
|
|||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
|
||||
/*
|
||||
* With V2 the extra block is data or freespace.
|
||||
* With V2 dirs the extra block is data or freespace.
|
||||
*/
|
||||
useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) ||
|
||||
state->args->whichfork == XFS_ATTR_FORK);
|
||||
useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;
|
||||
newcount = 1 + useextra;
|
||||
/*
|
||||
* Do we have to split the node?
|
||||
|
@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
|
|||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
|
||||
ASSERT(newblk->blkno != 0);
|
||||
if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
|
||||
if (state->args->whichfork == XFS_DATA_FORK)
|
||||
ASSERT(newblk->blkno >= mp->m_dirleafblk &&
|
||||
newblk->blkno < mp->m_dirfreeblk);
|
||||
|
||||
|
@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state)
|
|||
save_blk = &state->altpath.blk[ state->path.active-1 ];
|
||||
ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
|
||||
drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp));
|
||||
drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
|
||||
|
||||
/*
|
||||
* Walk back up the tree joining/deallocating as necessary.
|
||||
|
@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state)
|
|||
return(0);
|
||||
xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
|
||||
break;
|
||||
case XFS_DIR_LEAF_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V1(state->mp));
|
||||
error = xfs_dir_leaf_toosmall(state, &action);
|
||||
if (error)
|
||||
return(error);
|
||||
if (action == 0)
|
||||
return(0);
|
||||
xfs_dir_leaf_unbalance(state, drop_blk, save_blk);
|
||||
break;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V2(state->mp));
|
||||
error = xfs_dir2_leafn_toosmall(state, &action);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
|
|||
ASSERT(bp != NULL);
|
||||
blkinfo = bp->data;
|
||||
if (be16_to_cpu(oldroot->hdr.level) == 1) {
|
||||
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC ||
|
||||
be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
|
||||
} else {
|
||||
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
|
||||
|
@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
|
|||
if (count == 0)
|
||||
return;
|
||||
break;
|
||||
case XFS_DIR_LEAF_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V1(state->mp));
|
||||
lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
|
||||
if (count == 0)
|
||||
return;
|
||||
break;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V2(state->mp));
|
||||
lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
|||
* Descend thru the B-tree searching each level for the right
|
||||
* node to use, until the right hashval is found.
|
||||
*/
|
||||
if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp))
|
||||
blkno = state->mp->m_dirleafblk;
|
||||
else
|
||||
blkno = 0;
|
||||
blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;
|
||||
for (blk = &state->path.blk[0], state->path.active = 1;
|
||||
state->path.active <= XFS_DA_NODE_MAXDEPTH;
|
||||
blk++, state->path.active++) {
|
||||
|
@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
|||
}
|
||||
curr = blk->bp->data;
|
||||
ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
|
||||
be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
|
||||
be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
|
||||
|
||||
/*
|
||||
|
@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
|||
blk->index = probe;
|
||||
blkno = be32_to_cpu(btree->before);
|
||||
}
|
||||
}
|
||||
else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
|
||||
} else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
|
||||
blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) {
|
||||
blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
} else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
|
@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
|||
* next leaf and keep searching.
|
||||
*/
|
||||
for (;;) {
|
||||
if (blk->magic == XFS_DIR_LEAF_MAGIC) {
|
||||
ASSERT(XFS_DIR_IS_V1(state->mp));
|
||||
retval = xfs_dir_leaf_lookup_int(blk->bp, args,
|
||||
&blk->index);
|
||||
} else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
|
||||
ASSERT(XFS_DIR_IS_V2(state->mp));
|
||||
if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
|
||||
retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
|
||||
&blk->index, state);
|
||||
}
|
||||
|
@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
|
|||
old_info = old_blk->bp->data;
|
||||
new_info = new_blk->bp->data;
|
||||
ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
|
||||
old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
old_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
|
||||
old_blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
|
||||
ASSERT(new_blk->magic == be16_to_cpu(new_info->magic));
|
||||
|
@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
|
|||
case XFS_ATTR_LEAF_MAGIC:
|
||||
before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
|
||||
break;
|
||||
case XFS_DIR_LEAF_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V1(state->mp));
|
||||
before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
|
||||
break;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V2(state->mp));
|
||||
before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
|
||||
break;
|
||||
case XFS_DA_NODE_MAGIC:
|
||||
|
@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
|
|||
save_info = save_blk->bp->data;
|
||||
drop_info = drop_blk->bp->data;
|
||||
ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
|
||||
save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
save_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
|
||||
save_blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
|
||||
ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic));
|
||||
|
@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
|
|||
ASSERT(blk->bp != NULL);
|
||||
info = blk->bp->data;
|
||||
ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC ||
|
||||
be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC ||
|
||||
be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
|
||||
blk->magic = be16_to_cpu(info->magic);
|
||||
if (blk->magic == XFS_DA_NODE_MAGIC) {
|
||||
|
@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
|
|||
blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
|
||||
NULL);
|
||||
break;
|
||||
case XFS_DIR_LEAF_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V1(state->mp));
|
||||
blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
|
||||
NULL);
|
||||
break;
|
||||
case XFS_DIR2_LEAFN_MAGIC:
|
||||
ASSERT(XFS_DIR_IS_V2(state->mp));
|
||||
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
|
||||
blk->magic ==
|
||||
XFS_DIRX_LEAF_MAGIC(state->mp));
|
||||
blk->magic == XFS_DIR2_LEAFN_MAGIC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
|
|||
xfs_bmbt_irec_t *mapp;
|
||||
xfs_inode_t *dp;
|
||||
int nmap, error, w, count, c, got, i, mapi;
|
||||
xfs_fsize_t size;
|
||||
xfs_trans_t *tp;
|
||||
xfs_mount_t *mp;
|
||||
|
||||
|
@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
|
|||
/*
|
||||
* For new directories adjust the file offset and block count.
|
||||
*/
|
||||
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) {
|
||||
if (w == XFS_DATA_FORK) {
|
||||
bno = mp->m_dirleafblk;
|
||||
count = mp->m_dirblkfsbs;
|
||||
} else {
|
||||
|
@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
|
|||
/*
|
||||
* Find a spot in the file space to put the new block.
|
||||
*/
|
||||
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) {
|
||||
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w)))
|
||||
return error;
|
||||
}
|
||||
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
|
||||
if (w == XFS_DATA_FORK)
|
||||
ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
|
||||
/*
|
||||
* Try mapping it in one filesystem block.
|
||||
|
@ -1655,7 +1573,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
|
|||
XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
|
||||
XFS_BMAPI_CONTIG,
|
||||
args->firstblock, args->total, &map, &nmap,
|
||||
args->flist))) {
|
||||
args->flist, NULL))) {
|
||||
return error;
|
||||
}
|
||||
ASSERT(nmap <= 1);
|
||||
|
@ -1676,7 +1594,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
|
|||
XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
|
||||
XFS_BMAPI_METADATA,
|
||||
args->firstblock, args->total,
|
||||
&mapp[mapi], &nmap, args->flist))) {
|
||||
&mapp[mapi], &nmap, args->flist,
|
||||
NULL))) {
|
||||
kmem_free(mapp, sizeof(*mapp) * count);
|
||||
return error;
|
||||
}
|
||||
|
@ -1705,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
|
|||
if (mapp != &map)
|
||||
kmem_free(mapp, sizeof(*mapp) * count);
|
||||
*new_blkno = (xfs_dablk_t)bno;
|
||||
/*
|
||||
* For version 1 directories, adjust the file size if it changed.
|
||||
*/
|
||||
if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
|
||||
ASSERT(mapi == 1);
|
||||
if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
|
||||
return error;
|
||||
size = XFS_FSB_TO_B(mp, bno);
|
||||
if (size != dp->i_d.di_size) {
|
||||
dp->i_d.di_size = size;
|
||||
xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1742,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
|||
int error, w, entno, level, dead_level;
|
||||
xfs_da_blkinfo_t *dead_info, *sib_info;
|
||||
xfs_da_intnode_t *par_node, *dead_node;
|
||||
xfs_dir_leafblock_t *dead_leaf;
|
||||
xfs_dir2_leaf_t *dead_leaf2;
|
||||
xfs_dahash_t dead_hash;
|
||||
|
||||
|
@ -1753,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
|||
w = args->whichfork;
|
||||
ASSERT(w == XFS_DATA_FORK);
|
||||
mp = ip->i_mount;
|
||||
if (XFS_DIR_IS_V2(mp)) {
|
||||
lastoff = mp->m_dirfreeblk;
|
||||
error = xfs_bmap_last_before(tp, ip, &lastoff, w);
|
||||
} else
|
||||
error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
|
||||
if (error)
|
||||
return error;
|
||||
if (unlikely(lastoff == 0)) {
|
||||
|
@ -1780,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
|||
/*
|
||||
* Get values from the moved block.
|
||||
*/
|
||||
if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) {
|
||||
ASSERT(XFS_DIR_IS_V1(mp));
|
||||
dead_leaf = (xfs_dir_leafblock_t *)dead_info;
|
||||
dead_level = 0;
|
||||
dead_hash =
|
||||
INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
|
||||
} else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
ASSERT(XFS_DIR_IS_V2(mp));
|
||||
if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
|
||||
dead_level = 0;
|
||||
dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
|
||||
|
@ -1842,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
|||
xfs_da_buf_done(sib_buf);
|
||||
sib_buf = NULL;
|
||||
}
|
||||
par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk;
|
||||
par_blkno = mp->m_dirleafblk;
|
||||
level = -1;
|
||||
/*
|
||||
* Walk down the tree looking for the parent of the moved block.
|
||||
|
@ -1941,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
|
|||
{
|
||||
xfs_inode_t *dp;
|
||||
int done, error, w, count;
|
||||
xfs_fileoff_t bno;
|
||||
xfs_fsize_t size;
|
||||
xfs_trans_t *tp;
|
||||
xfs_mount_t *mp;
|
||||
|
||||
|
@ -1950,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
|
|||
w = args->whichfork;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
|
||||
if (w == XFS_DATA_FORK)
|
||||
count = mp->m_dirblkfsbs;
|
||||
else
|
||||
count = 1;
|
||||
|
@ -1961,34 +1854,17 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
|
|||
*/
|
||||
if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
|
||||
XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
|
||||
0, args->firstblock, args->flist,
|
||||
0, args->firstblock, args->flist, NULL,
|
||||
&done)) == ENOSPC) {
|
||||
if (w != XFS_DATA_FORK)
|
||||
goto done;
|
||||
break;
|
||||
if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
|
||||
&dead_buf)))
|
||||
goto done;
|
||||
} else if (error)
|
||||
goto done;
|
||||
else
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
ASSERT(done);
|
||||
xfs_da_binval(tp, dead_buf);
|
||||
/*
|
||||
* Adjust the directory size for version 1.
|
||||
*/
|
||||
if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
|
||||
if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
|
||||
return error;
|
||||
size = XFS_FSB_TO_B(dp->i_mount, bno);
|
||||
if (size != dp->i_d.di_size) {
|
||||
dp->i_d.di_size = size;
|
||||
xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
done:
|
||||
xfs_da_binval(tp, dead_buf);
|
||||
return error;
|
||||
}
|
||||
|
@ -2049,10 +1925,7 @@ xfs_da_do_buf(
|
|||
xfs_dabuf_t *rbp;
|
||||
|
||||
mp = dp->i_mount;
|
||||
if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
|
||||
nfsb = mp->m_dirblkfsbs;
|
||||
else
|
||||
nfsb = 1;
|
||||
nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;
|
||||
mappedbno = *mappedbnop;
|
||||
/*
|
||||
* Caller doesn't have a mapping. -2 means don't complain
|
||||
|
@ -2086,7 +1959,7 @@ xfs_da_do_buf(
|
|||
nfsb,
|
||||
XFS_BMAPI_METADATA |
|
||||
XFS_BMAPI_AFLAG(whichfork),
|
||||
NULL, 0, mapp, &nmap, NULL)))
|
||||
NULL, 0, mapp, &nmap, NULL, NULL)))
|
||||
goto exit0;
|
||||
}
|
||||
} else {
|
||||
|
@ -2198,7 +2071,6 @@ xfs_da_do_buf(
|
|||
magic1 = be32_to_cpu(data->hdr.magic);
|
||||
if (unlikely(
|
||||
XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
|
||||
(magic != XFS_DIR_LEAF_MAGIC) &&
|
||||
(magic != XFS_ATTR_LEAF_MAGIC) &&
|
||||
(magic != XFS_DIR2_LEAF1_MAGIC) &&
|
||||
(magic != XFS_DIR2_LEAFN_MAGIC) &&
|
||||
|
|
|
@ -36,14 +36,10 @@ struct zone;
|
|||
* level in the Btree, and to identify which type of block this is.
|
||||
*/
|
||||
#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */
|
||||
#define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */
|
||||
#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
|
||||
#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */
|
||||
#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */
|
||||
|
||||
#define XFS_DIRX_LEAF_MAGIC(mp) \
|
||||
(XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC)
|
||||
|
||||
typedef struct xfs_da_blkinfo {
|
||||
__be32 forw; /* previous block in list */
|
||||
__be32 back; /* following block in list */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -54,24 +52,14 @@ xfs_swapext(
|
|||
xfs_swapext_t __user *sxu)
|
||||
{
|
||||
xfs_swapext_t *sxp;
|
||||
xfs_inode_t *ip=NULL, *tip=NULL, *ips[2];
|
||||
xfs_trans_t *tp;
|
||||
xfs_inode_t *ip=NULL, *tip=NULL;
|
||||
xfs_mount_t *mp;
|
||||
xfs_bstat_t *sbp;
|
||||
struct file *fp = NULL, *tfp = NULL;
|
||||
vnode_t *vp, *tvp;
|
||||
static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
|
||||
int ilf_fields, tilf_fields;
|
||||
bhv_vnode_t *vp, *tvp;
|
||||
int error = 0;
|
||||
xfs_ifork_t *tempifp, *ifp, *tifp;
|
||||
__uint64_t tmp;
|
||||
int aforkblks = 0;
|
||||
int taforkblks = 0;
|
||||
char locked = 0;
|
||||
|
||||
sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
|
||||
tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
|
||||
if (!sxp || !tempifp) {
|
||||
if (!sxp) {
|
||||
error = XFS_ERROR(ENOMEM);
|
||||
goto error0;
|
||||
}
|
||||
|
@ -118,14 +106,56 @@ xfs_swapext(
|
|||
|
||||
mp = ip->i_mount;
|
||||
|
||||
sbp = &sxp->sx_stat;
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||
error = XFS_ERROR(EIO);
|
||||
goto error0;
|
||||
}
|
||||
|
||||
locked = 1;
|
||||
error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
|
||||
|
||||
error0:
|
||||
if (fp != NULL)
|
||||
fput(fp);
|
||||
if (tfp != NULL)
|
||||
fput(tfp);
|
||||
|
||||
if (sxp != NULL)
|
||||
kmem_free(sxp, sizeof(xfs_swapext_t));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_swap_extents(
|
||||
xfs_inode_t *ip,
|
||||
xfs_inode_t *tip,
|
||||
xfs_swapext_t *sxp)
|
||||
{
|
||||
xfs_mount_t *mp;
|
||||
xfs_inode_t *ips[2];
|
||||
xfs_trans_t *tp;
|
||||
xfs_bstat_t *sbp = &sxp->sx_stat;
|
||||
bhv_vnode_t *vp, *tvp;
|
||||
xfs_ifork_t *tempifp, *ifp, *tifp;
|
||||
int ilf_fields, tilf_fields;
|
||||
static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
|
||||
int error = 0;
|
||||
int aforkblks = 0;
|
||||
int taforkblks = 0;
|
||||
__uint64_t tmp;
|
||||
char locked = 0;
|
||||
|
||||
mp = ip->i_mount;
|
||||
|
||||
tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
|
||||
if (!tempifp) {
|
||||
error = XFS_ERROR(ENOMEM);
|
||||
goto error0;
|
||||
}
|
||||
|
||||
sbp = &sxp->sx_stat;
|
||||
vp = XFS_ITOV(ip);
|
||||
tvp = XFS_ITOV(tip);
|
||||
|
||||
/* Lock in i_ino order */
|
||||
if (ip->i_ino < tip->i_ino) {
|
||||
|
@ -137,6 +167,7 @@ xfs_swapext(
|
|||
}
|
||||
|
||||
xfs_lock_inodes(ips, 2, 0, lock_flags);
|
||||
locked = 1;
|
||||
|
||||
/* Check permissions */
|
||||
error = xfs_iaccess(ip, S_IWUSR, NULL);
|
||||
|
@ -169,7 +200,7 @@ xfs_swapext(
|
|||
|
||||
if (VN_CACHED(tvp) != 0) {
|
||||
xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
|
||||
VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED);
|
||||
bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
|
||||
}
|
||||
|
||||
/* Verify O_DIRECT for ftmp */
|
||||
|
@ -214,7 +245,7 @@ xfs_swapext(
|
|||
/* We need to fail if the file is memory mapped. Once we have tossed
|
||||
* all existing pages, the page fault will have no option
|
||||
* but to go to the filesystem for pages. By making the page fault call
|
||||
* VOP_READ (or write in the case of autogrow) they block on the iolock
|
||||
* vop_read (or write in the case of autogrow) they block on the iolock
|
||||
* until we have switched the extents.
|
||||
*/
|
||||
if (VN_MAPPED(vp)) {
|
||||
|
@ -233,7 +264,7 @@ xfs_swapext(
|
|||
* fields change.
|
||||
*/
|
||||
|
||||
VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF);
|
||||
bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
|
||||
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
|
||||
if ((error = xfs_trans_reserve(tp, 0,
|
||||
|
@ -360,16 +391,7 @@ xfs_swapext(
|
|||
xfs_iunlock(ip, lock_flags);
|
||||
xfs_iunlock(tip, lock_flags);
|
||||
}
|
||||
|
||||
if (fp != NULL)
|
||||
fput(fp);
|
||||
if (tfp != NULL)
|
||||
fput(tfp);
|
||||
|
||||
if (sxp != NULL)
|
||||
kmem_free(sxp, sizeof(xfs_swapext_t));
|
||||
if (tempifp != NULL)
|
||||
kmem_free(tempifp, sizeof(xfs_ifork_t));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ typedef struct xfs_swapext
|
|||
*/
|
||||
int xfs_swapext(struct xfs_swapext __user *sx);
|
||||
|
||||
int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
|
||||
struct xfs_swapext *sxp);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __XFS_DFRAG_H__ */
|
||||
|
|
|
@ -85,7 +85,6 @@ typedef struct xfs_dinode
|
|||
union {
|
||||
xfs_bmdr_block_t di_bmbt; /* btree root block */
|
||||
xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
|
||||
xfs_dir_shortform_t di_dirsf; /* shortform directory */
|
||||
xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
|
||||
char di_c[1]; /* local contents */
|
||||
xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
|
||||
|
@ -257,6 +256,7 @@ typedef enum xfs_dinode_fmt
|
|||
#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */
|
||||
#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
|
||||
#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
|
||||
#define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
|
||||
#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
|
||||
#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
|
||||
#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
|
||||
|
@ -270,12 +270,13 @@ typedef enum xfs_dinode_fmt
|
|||
#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
|
||||
#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
|
||||
#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
|
||||
#define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
|
||||
|
||||
#define XFS_DIFLAG_ANY \
|
||||
(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
|
||||
XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
|
||||
XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
|
||||
XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
|
||||
XFS_DIFLAG_EXTSZINHERIT)
|
||||
XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
|
||||
|
||||
#endif /* __XFS_DINODE_H__ */
|
||||
|
|
1217
fs/xfs/xfs_dir.c
1217
fs/xfs/xfs_dir.c
File diff suppressed because it is too large
Load Diff
142
fs/xfs/xfs_dir.h
142
fs/xfs/xfs_dir.h
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000,2005 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __XFS_DIR_H__
|
||||
#define __XFS_DIR_H__
|
||||
|
||||
/*
|
||||
* Large directories are structured around Btrees where all the data
|
||||
* elements are in the leaf nodes. Filenames are hashed into an int,
|
||||
* then that int is used as the index into the Btree. Since the hashval
|
||||
* of a filename may not be unique, we may have duplicate keys. The
|
||||
* internal links in the Btree are logical block offsets into the file.
|
||||
*
|
||||
* Small directories use a different format and are packed as tightly
|
||||
* as possible so as to fit into the literal area of the inode.
|
||||
*/
|
||||
|
||||
/*========================================================================
|
||||
* Function prototypes for the kernel.
|
||||
*========================================================================*/
|
||||
|
||||
struct uio;
|
||||
struct xfs_bmap_free;
|
||||
struct xfs_da_args;
|
||||
struct xfs_dinode;
|
||||
struct xfs_inode;
|
||||
struct xfs_mount;
|
||||
struct xfs_trans;
|
||||
|
||||
/*
|
||||
* Directory function types.
|
||||
* Put in structures (xfs_dirops_t) for v1 and v2 directories.
|
||||
*/
|
||||
typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp);
|
||||
typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp);
|
||||
typedef int (*xfs_dir_init_t)(struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct xfs_inode *pdp);
|
||||
typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
char *name,
|
||||
int namelen,
|
||||
xfs_ino_t inum,
|
||||
xfs_fsblock_t *first,
|
||||
struct xfs_bmap_free *flist,
|
||||
xfs_extlen_t total);
|
||||
typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
char *name,
|
||||
int namelen,
|
||||
xfs_ino_t *inum);
|
||||
typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
char *name,
|
||||
int namelen,
|
||||
xfs_ino_t ino,
|
||||
xfs_fsblock_t *first,
|
||||
struct xfs_bmap_free *flist,
|
||||
xfs_extlen_t total);
|
||||
typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
struct uio *uio,
|
||||
int *eofp);
|
||||
typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
char *name,
|
||||
int namelen,
|
||||
xfs_ino_t inum,
|
||||
xfs_fsblock_t *first,
|
||||
struct xfs_bmap_free *flist,
|
||||
xfs_extlen_t total);
|
||||
typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
char *name,
|
||||
int namelen);
|
||||
typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp,
|
||||
struct xfs_dinode *dip);
|
||||
typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args);
|
||||
|
||||
typedef struct xfs_dirops {
|
||||
xfs_dir_mount_t xd_mount;
|
||||
xfs_dir_isempty_t xd_isempty;
|
||||
xfs_dir_init_t xd_init;
|
||||
xfs_dir_createname_t xd_createname;
|
||||
xfs_dir_lookup_t xd_lookup;
|
||||
xfs_dir_removename_t xd_removename;
|
||||
xfs_dir_getdents_t xd_getdents;
|
||||
xfs_dir_replace_t xd_replace;
|
||||
xfs_dir_canenter_t xd_canenter;
|
||||
xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk;
|
||||
xfs_dir_shortform_to_single_t xd_shortform_to_single;
|
||||
} xfs_dirops_t;
|
||||
|
||||
/*
|
||||
* Overall external interface routines.
|
||||
*/
|
||||
void xfs_dir_startup(void); /* called exactly once */
|
||||
|
||||
#define XFS_DIR_MOUNT(mp) \
|
||||
((mp)->m_dirops.xd_mount(mp))
|
||||
#define XFS_DIR_ISEMPTY(mp,dp) \
|
||||
((mp)->m_dirops.xd_isempty(dp))
|
||||
#define XFS_DIR_INIT(mp,tp,dp,pdp) \
|
||||
((mp)->m_dirops.xd_init(tp,dp,pdp))
|
||||
#define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \
|
||||
((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\
|
||||
total))
|
||||
#define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \
|
||||
((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum))
|
||||
#define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \
|
||||
((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total))
|
||||
#define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \
|
||||
((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp))
|
||||
#define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \
|
||||
((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total))
|
||||
#define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \
|
||||
((mp)->m_dirops.xd_canenter(tp,dp,name,namelen))
|
||||
#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \
|
||||
((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip))
|
||||
#define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \
|
||||
((mp)->m_dirops.xd_shortform_to_single(args))
|
||||
|
||||
#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1)
|
||||
#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2)
|
||||
extern xfs_dirops_t xfsv1_dirops;
|
||||
extern xfs_dirops_t xfsv2_dirops;
|
||||
|
||||
#endif /* __XFS_DIR_H__ */
|
|
@ -24,21 +24,18 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_inode_item.h"
|
||||
#include "xfs_bmap.h"
|
||||
#include "xfs_dir_leaf.h"
|
||||
#include "xfs_dir2_data.h"
|
||||
#include "xfs_dir2_leaf.h"
|
||||
#include "xfs_dir2_block.h"
|
||||
|
@ -46,69 +43,14 @@
|
|||
#include "xfs_dir2_trace.h"
|
||||
#include "xfs_error.h"
|
||||
|
||||
/*
|
||||
* Declarations for interface routines.
|
||||
*/
|
||||
static void xfs_dir2_mount(xfs_mount_t *mp);
|
||||
static int xfs_dir2_isempty(xfs_inode_t *dp);
|
||||
static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp,
|
||||
xfs_inode_t *pdp);
|
||||
static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp,
|
||||
char *name, int namelen, xfs_ino_t inum,
|
||||
xfs_fsblock_t *first,
|
||||
xfs_bmap_free_t *flist, xfs_extlen_t total);
|
||||
static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
|
||||
int namelen, xfs_ino_t *inum);
|
||||
static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp,
|
||||
char *name, int namelen, xfs_ino_t ino,
|
||||
xfs_fsblock_t *first,
|
||||
xfs_bmap_free_t *flist, xfs_extlen_t total);
|
||||
static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio,
|
||||
int *eofp);
|
||||
static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
|
||||
int namelen, xfs_ino_t inum,
|
||||
xfs_fsblock_t *first, xfs_bmap_free_t *flist,
|
||||
xfs_extlen_t total);
|
||||
static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
|
||||
int namelen);
|
||||
static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp,
|
||||
xfs_dinode_t *dip);
|
||||
|
||||
/*
|
||||
* Utility routine declarations.
|
||||
*/
|
||||
static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
|
||||
static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
|
||||
|
||||
/*
|
||||
* Directory operations vector.
|
||||
*/
|
||||
xfs_dirops_t xfsv2_dirops = {
|
||||
.xd_mount = xfs_dir2_mount,
|
||||
.xd_isempty = xfs_dir2_isempty,
|
||||
.xd_init = xfs_dir2_init,
|
||||
.xd_createname = xfs_dir2_createname,
|
||||
.xd_lookup = xfs_dir2_lookup,
|
||||
.xd_removename = xfs_dir2_removename,
|
||||
.xd_getdents = xfs_dir2_getdents,
|
||||
.xd_replace = xfs_dir2_replace,
|
||||
.xd_canenter = xfs_dir2_canenter,
|
||||
.xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk,
|
||||
.xd_shortform_to_single = xfs_dir2_sf_to_block,
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize directory-related fields in the mount structure.
|
||||
*/
|
||||
static void
|
||||
xfs_dir2_mount(
|
||||
xfs_mount_t *mp) /* filesystem mount point */
|
||||
void
|
||||
xfs_dir_mount(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
mp->m_dirversion = 2;
|
||||
ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));
|
||||
ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
|
||||
XFS_MAX_BLOCKSIZE);
|
||||
mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
|
||||
|
@ -128,73 +70,99 @@ xfs_dir2_mount(
|
|||
/*
|
||||
* Return 1 if directory contains only "." and "..".
|
||||
*/
|
||||
static int /* return code */
|
||||
xfs_dir2_isempty(
|
||||
xfs_inode_t *dp) /* incore inode structure */
|
||||
int
|
||||
xfs_dir_isempty(
|
||||
xfs_inode_t *dp)
|
||||
{
|
||||
xfs_dir2_sf_t *sfp; /* shortform directory structure */
|
||||
xfs_dir2_sf_t *sfp;
|
||||
|
||||
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
|
||||
/*
|
||||
* Might happen during shutdown.
|
||||
*/
|
||||
if (dp->i_d.di_size == 0) {
|
||||
if (dp->i_d.di_size == 0) /* might happen during shutdown. */
|
||||
return 1;
|
||||
}
|
||||
if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
|
||||
return 0;
|
||||
sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
|
||||
return !sfp->hdr.count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate a given inode number.
|
||||
*/
|
||||
int
|
||||
xfs_dir_ino_validate(
|
||||
xfs_mount_t *mp,
|
||||
xfs_ino_t ino)
|
||||
{
|
||||
xfs_agblock_t agblkno;
|
||||
xfs_agino_t agino;
|
||||
xfs_agnumber_t agno;
|
||||
int ino_ok;
|
||||
int ioff;
|
||||
|
||||
agno = XFS_INO_TO_AGNO(mp, ino);
|
||||
agblkno = XFS_INO_TO_AGBNO(mp, ino);
|
||||
ioff = XFS_INO_TO_OFFSET(mp, ino);
|
||||
agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
|
||||
ino_ok =
|
||||
agno < mp->m_sb.sb_agcount &&
|
||||
agblkno < mp->m_sb.sb_agblocks &&
|
||||
agblkno != 0 &&
|
||||
ioff < (1 << mp->m_sb.sb_inopblog) &&
|
||||
XFS_AGINO_TO_INO(mp, agno, agino) == ino;
|
||||
if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
|
||||
XFS_RANDOM_DIR_INO_VALIDATE))) {
|
||||
xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
|
||||
(unsigned long long) ino);
|
||||
XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize a directory with its "." and ".." entries.
|
||||
*/
|
||||
static int /* error */
|
||||
xfs_dir2_init(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
xfs_inode_t *pdp) /* incore parent directory inode */
|
||||
int
|
||||
xfs_dir_init(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
xfs_inode_t *pdp)
|
||||
{
|
||||
xfs_da_args_t args; /* operation arguments */
|
||||
int error; /* error return value */
|
||||
xfs_da_args_t args;
|
||||
int error;
|
||||
|
||||
memset((char *)&args, 0, sizeof(args));
|
||||
args.dp = dp;
|
||||
args.trans = tp;
|
||||
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
|
||||
if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) {
|
||||
if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))
|
||||
return error;
|
||||
}
|
||||
return xfs_dir2_sf_create(&args, pdp->i_ino);
|
||||
}
|
||||
|
||||
/*
|
||||
Enter a name in a directory.
|
||||
*/
|
||||
static int /* error */
|
||||
xfs_dir2_createname(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
char *name, /* new entry name */
|
||||
int namelen, /* new entry name length */
|
||||
int
|
||||
xfs_dir_createname(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
char *name,
|
||||
int namelen,
|
||||
xfs_ino_t inum, /* new entry inode number */
|
||||
xfs_fsblock_t *first, /* bmap's firstblock */
|
||||
xfs_bmap_free_t *flist, /* bmap's freeblock list */
|
||||
xfs_extlen_t total) /* bmap's total block count */
|
||||
{
|
||||
xfs_da_args_t args; /* operation arguments */
|
||||
int rval; /* return value */
|
||||
xfs_da_args_t args;
|
||||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
|
||||
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
|
||||
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
|
||||
return rval;
|
||||
}
|
||||
XFS_STATS_INC(xs_dir_create);
|
||||
/*
|
||||
* Fill in the arg structure for this request.
|
||||
*/
|
||||
|
||||
args.name = name;
|
||||
args.namelen = namelen;
|
||||
args.hashval = xfs_da_hashname(name, namelen);
|
||||
|
@ -207,18 +175,16 @@ xfs_dir2_createname(
|
|||
args.trans = tp;
|
||||
args.justcheck = 0;
|
||||
args.addname = args.oknoent = 1;
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
|
||||
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
|
||||
rval = xfs_dir2_sf_addname(&args);
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_block_addname(&args);
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_leaf_addname(&args);
|
||||
else
|
||||
rval = xfs_dir2_node_addname(&args);
|
||||
|
@ -228,24 +194,21 @@ xfs_dir2_createname(
|
|||
/*
|
||||
* Lookup a name in a directory, give back the inode number.
|
||||
*/
|
||||
static int /* error */
|
||||
xfs_dir2_lookup(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
char *name, /* lookup name */
|
||||
int namelen, /* lookup name length */
|
||||
int
|
||||
xfs_dir_lookup(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
char *name,
|
||||
int namelen,
|
||||
xfs_ino_t *inum) /* out: inode number */
|
||||
{
|
||||
xfs_da_args_t args; /* operation arguments */
|
||||
int rval; /* return value */
|
||||
xfs_da_args_t args;
|
||||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
|
||||
XFS_STATS_INC(xs_dir_lookup);
|
||||
|
||||
/*
|
||||
* Fill in the arg structure for this request.
|
||||
*/
|
||||
args.name = name;
|
||||
args.namelen = namelen;
|
||||
args.hashval = xfs_da_hashname(name, namelen);
|
||||
|
@ -258,18 +221,16 @@ xfs_dir2_lookup(
|
|||
args.trans = tp;
|
||||
args.justcheck = args.addname = 0;
|
||||
args.oknoent = 1;
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
|
||||
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
|
||||
rval = xfs_dir2_sf_lookup(&args);
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_block_lookup(&args);
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_leaf_lookup(&args);
|
||||
else
|
||||
rval = xfs_dir2_node_lookup(&args);
|
||||
|
@ -283,26 +244,24 @@ xfs_dir2_lookup(
|
|||
/*
|
||||
* Remove an entry from a directory.
|
||||
*/
|
||||
static int /* error */
|
||||
xfs_dir2_removename(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
char *name, /* name of entry to remove */
|
||||
int namelen, /* name length of entry to remove */
|
||||
xfs_ino_t ino, /* inode number of entry to remove */
|
||||
int
|
||||
xfs_dir_removename(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
char *name,
|
||||
int namelen,
|
||||
xfs_ino_t ino,
|
||||
xfs_fsblock_t *first, /* bmap's firstblock */
|
||||
xfs_bmap_free_t *flist, /* bmap's freeblock list */
|
||||
xfs_extlen_t total) /* bmap's total block count */
|
||||
{
|
||||
xfs_da_args_t args; /* operation arguments */
|
||||
int rval; /* return value */
|
||||
xfs_da_args_t args;
|
||||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
|
||||
XFS_STATS_INC(xs_dir_remove);
|
||||
/*
|
||||
* Fill in the arg structure for this request.
|
||||
*/
|
||||
|
||||
args.name = name;
|
||||
args.namelen = namelen;
|
||||
args.hashval = xfs_da_hashname(name, namelen);
|
||||
|
@ -314,18 +273,16 @@ xfs_dir2_removename(
|
|||
args.whichfork = XFS_DATA_FORK;
|
||||
args.trans = tp;
|
||||
args.justcheck = args.addname = args.oknoent = 0;
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
|
||||
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
|
||||
rval = xfs_dir2_sf_removename(&args);
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_block_removename(&args);
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_leaf_removename(&args);
|
||||
else
|
||||
rval = xfs_dir2_node_removename(&args);
|
||||
|
@ -335,10 +292,10 @@ xfs_dir2_removename(
|
|||
/*
|
||||
* Read a directory.
|
||||
*/
|
||||
static int /* error */
|
||||
xfs_dir2_getdents(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
int
|
||||
xfs_dir_getdents(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
uio_t *uio, /* caller's buffer control */
|
||||
int *eofp) /* out: eof reached */
|
||||
{
|
||||
|
@ -367,14 +324,11 @@ xfs_dir2_getdents(
|
|||
}
|
||||
|
||||
*eofp = 0;
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
|
||||
rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put);
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
|
||||
;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);
|
||||
else
|
||||
rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put);
|
||||
|
@ -386,29 +340,26 @@ xfs_dir2_getdents(
|
|||
/*
|
||||
* Replace the inode number of a directory entry.
|
||||
*/
|
||||
static int /* error */
|
||||
xfs_dir2_replace(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
int
|
||||
xfs_dir_replace(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
char *name, /* name of entry to replace */
|
||||
int namelen, /* name length of entry to replace */
|
||||
int namelen,
|
||||
xfs_ino_t inum, /* new inode number */
|
||||
xfs_fsblock_t *first, /* bmap's firstblock */
|
||||
xfs_bmap_free_t *flist, /* bmap's freeblock list */
|
||||
xfs_extlen_t total) /* bmap's total block count */
|
||||
{
|
||||
xfs_da_args_t args; /* operation arguments */
|
||||
int rval; /* return value */
|
||||
xfs_da_args_t args;
|
||||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
|
||||
|
||||
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
|
||||
if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
|
||||
return rval;
|
||||
}
|
||||
/*
|
||||
* Fill in the arg structure for this request.
|
||||
*/
|
||||
|
||||
args.name = name;
|
||||
args.namelen = namelen;
|
||||
args.hashval = xfs_da_hashname(name, namelen);
|
||||
|
@ -420,18 +371,16 @@ xfs_dir2_replace(
|
|||
args.whichfork = XFS_DATA_FORK;
|
||||
args.trans = tp;
|
||||
args.justcheck = args.addname = args.oknoent = 0;
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
|
||||
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
|
||||
rval = xfs_dir2_sf_replace(&args);
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_block_replace(&args);
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_leaf_replace(&args);
|
||||
else
|
||||
rval = xfs_dir2_node_replace(&args);
|
||||
|
@ -441,21 +390,19 @@ xfs_dir2_replace(
|
|||
/*
|
||||
* See if this entry can be added to the directory without allocating space.
|
||||
*/
|
||||
static int /* error */
|
||||
xfs_dir2_canenter(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
int
|
||||
xfs_dir_canenter(
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
char *name, /* name of entry to add */
|
||||
int namelen) /* name length of entry to add */
|
||||
int namelen)
|
||||
{
|
||||
xfs_da_args_t args; /* operation arguments */
|
||||
int rval; /* return value */
|
||||
xfs_da_args_t args;
|
||||
int rval;
|
||||
int v; /* type-checking value */
|
||||
|
||||
ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
|
||||
/*
|
||||
* Fill in the arg structure for this request.
|
||||
*/
|
||||
|
||||
args.name = name;
|
||||
args.namelen = namelen;
|
||||
args.hashval = xfs_da_hashname(name, namelen);
|
||||
|
@ -467,37 +414,22 @@ xfs_dir2_canenter(
|
|||
args.whichfork = XFS_DATA_FORK;
|
||||
args.trans = tp;
|
||||
args.justcheck = args.addname = args.oknoent = 1;
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
|
||||
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
|
||||
rval = xfs_dir2_sf_addname(&args);
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_block_addname(&args);
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) {
|
||||
else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
|
||||
return rval;
|
||||
} else if (v)
|
||||
else if (v)
|
||||
rval = xfs_dir2_leaf_addname(&args);
|
||||
else
|
||||
rval = xfs_dir2_node_addname(&args);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy routine for shortform inode validation.
|
||||
* Can't really do this.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int /* error */
|
||||
xfs_dir2_shortform_validate_ondisk(
|
||||
xfs_mount_t *mp, /* filesystem mount point */
|
||||
xfs_dinode_t *dip) /* ondisk inode */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility routines.
|
||||
*/
|
||||
|
@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk(
|
|||
* This routine is for data and free blocks, not leaf/node blocks
|
||||
* which are handled by xfs_da_grow_inode.
|
||||
*/
|
||||
int /* error */
|
||||
int
|
||||
xfs_dir2_grow_inode(
|
||||
xfs_da_args_t *args, /* operation arguments */
|
||||
xfs_da_args_t *args,
|
||||
int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
|
||||
xfs_dir2_db_t *dbp) /* out: block number added */
|
||||
{
|
||||
xfs_fileoff_t bno; /* directory offset of new block */
|
||||
int count; /* count of filesystem blocks */
|
||||
xfs_inode_t *dp; /* incore directory inode */
|
||||
int error; /* error return value */
|
||||
int error;
|
||||
int got; /* blocks actually mapped */
|
||||
int i; /* temp mapping index */
|
||||
int i;
|
||||
xfs_bmbt_irec_t map; /* single structure for bmap */
|
||||
int mapi; /* mapping index */
|
||||
xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
xfs_mount_t *mp;
|
||||
int nmap; /* number of bmap entries */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
xfs_trans_t *tp;
|
||||
|
||||
xfs_dir2_trace_args_s("grow_inode", args, space);
|
||||
dp = args->dp;
|
||||
|
@ -538,9 +470,8 @@ xfs_dir2_grow_inode(
|
|||
/*
|
||||
* Find the first hole for our block.
|
||||
*/
|
||||
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) {
|
||||
if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK)))
|
||||
return error;
|
||||
}
|
||||
nmap = 1;
|
||||
ASSERT(args->firstblock != NULL);
|
||||
/*
|
||||
|
@ -549,13 +480,9 @@ xfs_dir2_grow_inode(
|
|||
if ((error = xfs_bmapi(tp, dp, bno, count,
|
||||
XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
|
||||
args->firstblock, args->total, &map, &nmap,
|
||||
args->flist))) {
|
||||
args->flist, NULL)))
|
||||
return error;
|
||||
}
|
||||
ASSERT(nmap <= 1);
|
||||
/*
|
||||
* Got it in 1.
|
||||
*/
|
||||
if (nmap == 1) {
|
||||
mapp = ↦
|
||||
mapi = 1;
|
||||
|
@ -585,7 +512,8 @@ xfs_dir2_grow_inode(
|
|||
if ((error = xfs_bmapi(tp, dp, b, c,
|
||||
XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
|
||||
args->firstblock, args->total,
|
||||
&mapp[mapi], &nmap, args->flist))) {
|
||||
&mapp[mapi], &nmap, args->flist,
|
||||
NULL))) {
|
||||
kmem_free(mapp, sizeof(*mapp) * count);
|
||||
return error;
|
||||
}
|
||||
|
@ -645,20 +573,19 @@ xfs_dir2_grow_inode(
|
|||
/*
|
||||
* See if the directory is a single-block form directory.
|
||||
*/
|
||||
int /* error */
|
||||
int
|
||||
xfs_dir2_isblock(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
int *vp) /* out: 1 is block, 0 is not block */
|
||||
{
|
||||
xfs_fileoff_t last; /* last file offset */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int rval; /* return value */
|
||||
xfs_mount_t *mp;
|
||||
int rval;
|
||||
|
||||
mp = dp->i_mount;
|
||||
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) {
|
||||
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
|
||||
return rval;
|
||||
}
|
||||
rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize;
|
||||
ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize);
|
||||
*vp = rval;
|
||||
|
@ -668,20 +595,19 @@ xfs_dir2_isblock(
|
|||
/*
|
||||
* See if the directory is a single-leaf form directory.
|
||||
*/
|
||||
int /* error */
|
||||
int
|
||||
xfs_dir2_isleaf(
|
||||
xfs_trans_t *tp, /* transaction pointer */
|
||||
xfs_inode_t *dp, /* incore directory inode */
|
||||
xfs_trans_t *tp,
|
||||
xfs_inode_t *dp,
|
||||
int *vp) /* out: 1 is leaf, 0 is not leaf */
|
||||
{
|
||||
xfs_fileoff_t last; /* last file offset */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int rval; /* return value */
|
||||
xfs_mount_t *mp;
|
||||
int rval;
|
||||
|
||||
mp = dp->i_mount;
|
||||
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) {
|
||||
if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
|
||||
return rval;
|
||||
}
|
||||
*vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);
|
||||
return 0;
|
||||
}
|
||||
|
@ -689,9 +615,9 @@ xfs_dir2_isleaf(
|
|||
/*
|
||||
* Getdents put routine for 64-bit ABI, direct form.
|
||||
*/
|
||||
static int /* error */
|
||||
static int
|
||||
xfs_dir2_put_dirent64_direct(
|
||||
xfs_dir2_put_args_t *pa) /* argument bundle */
|
||||
xfs_dir2_put_args_t *pa)
|
||||
{
|
||||
xfs_dirent_t *idbp; /* dirent pointer */
|
||||
iovec_t *iovp; /* io vector */
|
||||
|
@ -726,9 +652,9 @@ xfs_dir2_put_dirent64_direct(
|
|||
/*
|
||||
* Getdents put routine for 64-bit ABI, uio form.
|
||||
*/
|
||||
static int /* error */
|
||||
static int
|
||||
xfs_dir2_put_dirent64_uio(
|
||||
xfs_dir2_put_args_t *pa) /* argument bundle */
|
||||
xfs_dir2_put_args_t *pa)
|
||||
{
|
||||
xfs_dirent_t *idbp; /* dirent pointer */
|
||||
int namelen; /* entry name length */
|
||||
|
@ -764,17 +690,17 @@ xfs_dir2_put_dirent64_uio(
|
|||
*/
|
||||
int
|
||||
xfs_dir2_shrink_inode(
|
||||
xfs_da_args_t *args, /* operation arguments */
|
||||
xfs_dir2_db_t db, /* directory block number */
|
||||
xfs_dabuf_t *bp) /* block's buffer */
|
||||
xfs_da_args_t *args,
|
||||
xfs_dir2_db_t db,
|
||||
xfs_dabuf_t *bp)
|
||||
{
|
||||
xfs_fileoff_t bno; /* directory file offset */
|
||||
xfs_dablk_t da; /* directory file offset */
|
||||
int done; /* bunmap is finished */
|
||||
xfs_inode_t *dp; /* incore directory inode */
|
||||
int error; /* error return value */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
xfs_inode_t *dp;
|
||||
int error;
|
||||
xfs_mount_t *mp;
|
||||
xfs_trans_t *tp;
|
||||
|
||||
xfs_dir2_trace_args_db("shrink_inode", args, db, bp);
|
||||
dp = args->dp;
|
||||
|
@ -786,7 +712,7 @@ xfs_dir2_shrink_inode(
|
|||
*/
|
||||
if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
|
||||
XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
|
||||
&done))) {
|
||||
NULL, &done))) {
|
||||
/*
|
||||
* ENOSPC actually can happen if we're in a removename with
|
||||
* no space reservation, and the resulting block removal
|
||||
|
|
|
@ -22,7 +22,9 @@ struct uio;
|
|||
struct xfs_dabuf;
|
||||
struct xfs_da_args;
|
||||
struct xfs_dir2_put_args;
|
||||
struct xfs_bmap_free;
|
||||
struct xfs_inode;
|
||||
struct xfs_mount;
|
||||
struct xfs_trans;
|
||||
|
||||
/*
|
||||
|
@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args {
|
|||
} xfs_dir2_put_args_t;
|
||||
|
||||
/*
|
||||
* Other interfaces used by the rest of the dir v2 code.
|
||||
* Generic directory interface routines
|
||||
*/
|
||||
extern void xfs_dir_startup(void);
|
||||
extern void xfs_dir_mount(struct xfs_mount *mp);
|
||||
extern int xfs_dir_isempty(struct xfs_inode *dp);
|
||||
extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
struct xfs_inode *pdp);
|
||||
extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
char *name, int namelen, xfs_ino_t inum,
|
||||
xfs_fsblock_t *first,
|
||||
struct xfs_bmap_free *flist, xfs_extlen_t tot);
|
||||
extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
char *name, int namelen, xfs_ino_t *inum);
|
||||
extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
char *name, int namelen, xfs_ino_t ino,
|
||||
xfs_fsblock_t *first,
|
||||
struct xfs_bmap_free *flist, xfs_extlen_t tot);
|
||||
extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
uio_t *uio, int *eofp);
|
||||
extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
char *name, int namelen, xfs_ino_t inum,
|
||||
xfs_fsblock_t *first,
|
||||
struct xfs_bmap_free *flist, xfs_extlen_t tot);
|
||||
extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
char *name, int namelen);
|
||||
extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
|
||||
|
||||
/*
|
||||
* Utility routines for v2 directories.
|
||||
*/
|
||||
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
|
||||
xfs_dir2_db_t *dbp);
|
||||
|
|
|
@ -22,19 +22,16 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_inode_item.h"
|
||||
#include "xfs_dir_leaf.h"
|
||||
#include "xfs_dir2_data.h"
|
||||
#include "xfs_dir2_leaf.h"
|
||||
#include "xfs_dir2_block.h"
|
||||
|
@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,
|
|||
int *entno);
|
||||
static int xfs_dir2_block_sort(const void *a, const void *b);
|
||||
|
||||
static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
|
||||
|
||||
/*
|
||||
* One-time startup routine called from xfs_init().
|
||||
*/
|
||||
void
|
||||
xfs_dir_startup(void)
|
||||
{
|
||||
xfs_dir_hash_dot = xfs_da_hashname(".", 1);
|
||||
xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an entry to a block directory.
|
||||
*/
|
||||
|
@ -400,7 +409,7 @@ xfs_dir2_block_addname(
|
|||
/*
|
||||
* Create the new data entry.
|
||||
*/
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
|
||||
dep->inumber = cpu_to_be64(args->inumber);
|
||||
dep->namelen = args->namelen;
|
||||
memcpy(dep->name, args->name, args->namelen);
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
|
@ -508,7 +517,7 @@ xfs_dir2_block_getdents(
|
|||
|
||||
p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
|
||||
ptr - (char *)block);
|
||||
p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
p.ino = be64_to_cpu(dep->inumber);
|
||||
#if XFS_BIG_INUMS
|
||||
p.ino += mp->m_inoadd;
|
||||
#endif
|
||||
|
@ -626,7 +635,7 @@ xfs_dir2_block_lookup(
|
|||
/*
|
||||
* Fill in inode number, release the block.
|
||||
*/
|
||||
args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
args->inumber = be64_to_cpu(dep->inumber);
|
||||
xfs_da_brelse(args->trans, bp);
|
||||
return XFS_ERROR(EEXIST);
|
||||
}
|
||||
|
@ -844,11 +853,11 @@ xfs_dir2_block_replace(
|
|||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
|
||||
ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber);
|
||||
ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
|
||||
/*
|
||||
* Change the inode number to the new value.
|
||||
*/
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
|
||||
dep->inumber = cpu_to_be64(args->inumber);
|
||||
xfs_dir2_data_log_entry(args->trans, bp, dep);
|
||||
xfs_dir2_data_check(dp, bp);
|
||||
xfs_da_buf_done(bp);
|
||||
|
@ -1130,7 +1139,7 @@ xfs_dir2_sf_to_block(
|
|||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino);
|
||||
dep->inumber = cpu_to_be64(dp->i_ino);
|
||||
dep->namelen = 1;
|
||||
dep->name[0] = '.';
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
|
@ -1144,7 +1153,7 @@ xfs_dir2_sf_to_block(
|
|||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
|
||||
dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
|
||||
dep->namelen = 2;
|
||||
dep->name[0] = dep->name[1] = '.';
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
|
@ -1193,7 +1202,7 @@ xfs_dir2_sf_to_block(
|
|||
* Copy a real entry.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp,
|
||||
dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp,
|
||||
XFS_DIR2_SF_INUMBERP(sfep)));
|
||||
dep->namelen = sfep->namelen;
|
||||
memcpy(dep->name, sfep->name, dep->namelen);
|
||||
|
|
|
@ -22,18 +22,15 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_dir_leaf.h"
|
||||
#include "xfs_dir2_data.h"
|
||||
#include "xfs_dir2_leaf.h"
|
||||
#include "xfs_dir2_block.h"
|
||||
|
@ -133,7 +130,7 @@ xfs_dir2_data_check(
|
|||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)p;
|
||||
ASSERT(dep->namelen != 0);
|
||||
ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0);
|
||||
ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0);
|
||||
ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) ==
|
||||
(char *)dep - (char *)d);
|
||||
count++;
|
||||
|
|
|
@ -85,11 +85,11 @@ typedef struct xfs_dir2_data_hdr {
|
|||
* Tag appears as the last 2 bytes.
|
||||
*/
|
||||
typedef struct xfs_dir2_data_entry {
|
||||
xfs_ino_t inumber; /* inode number */
|
||||
__uint8_t namelen; /* name length */
|
||||
__uint8_t name[1]; /* name bytes, no null */
|
||||
__be64 inumber; /* inode number */
|
||||
__u8 namelen; /* name length */
|
||||
__u8 name[1]; /* name bytes, no null */
|
||||
/* variable offset */
|
||||
xfs_dir2_data_off_t tag; /* starting offset of us */
|
||||
__be16 tag; /* starting offset of us */
|
||||
} xfs_dir2_data_entry_t;
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_inode.h"
|
||||
|
@ -407,7 +405,7 @@ xfs_dir2_leaf_addname(
|
|||
* Initialize our new entry (at last).
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)dup;
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
|
||||
dep->inumber = cpu_to_be64(args->inumber);
|
||||
dep->namelen = args->namelen;
|
||||
memcpy(dep->name, args->name, dep->namelen);
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
|
@ -884,7 +882,7 @@ xfs_dir2_leaf_getdents(
|
|||
XFS_DIR2_BYTE_TO_DA(mp,
|
||||
XFS_DIR2_LEAF_OFFSET) - map_off,
|
||||
XFS_BMAPI_METADATA, NULL, 0,
|
||||
&map[map_valid], &nmap, NULL);
|
||||
&map[map_valid], &nmap, NULL, NULL);
|
||||
/*
|
||||
* Don't know if we should ignore this or
|
||||
* try to return an error.
|
||||
|
@ -1098,7 +1096,7 @@ xfs_dir2_leaf_getdents(
|
|||
|
||||
p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
|
||||
|
||||
p->ino = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
p->ino = be64_to_cpu(dep->inumber);
|
||||
#if XFS_BIG_INUMS
|
||||
p->ino += mp->m_inoadd;
|
||||
#endif
|
||||
|
@ -1319,7 +1317,7 @@ xfs_dir2_leaf_lookup(
|
|||
/*
|
||||
* Return the found inode number.
|
||||
*/
|
||||
args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
args->inumber = be64_to_cpu(dep->inumber);
|
||||
xfs_da_brelse(tp, dbp);
|
||||
xfs_da_brelse(tp, lbp);
|
||||
return XFS_ERROR(EEXIST);
|
||||
|
@ -1606,11 +1604,11 @@ xfs_dir2_leaf_replace(
|
|||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)dbp->data +
|
||||
XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
|
||||
ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT));
|
||||
ASSERT(args->inumber != be64_to_cpu(dep->inumber));
|
||||
/*
|
||||
* Put the new inode number in, log it.
|
||||
*/
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
|
||||
dep->inumber = cpu_to_be64(args->inumber);
|
||||
tp = args->trans;
|
||||
xfs_dir2_data_log_entry(tp, dbp, dep);
|
||||
xfs_da_buf_done(dbp);
|
||||
|
|
|
@ -22,13 +22,11 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -505,7 +503,6 @@ xfs_dir2_leafn_lookup_int(
|
|||
XFS_DATA_FORK))) {
|
||||
return error;
|
||||
}
|
||||
curfdb = newfdb;
|
||||
free = curbp->data;
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) ==
|
||||
XFS_DIR2_FREE_MAGIC);
|
||||
|
@ -527,8 +524,11 @@ xfs_dir2_leafn_lookup_int(
|
|||
if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) {
|
||||
XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
if (curfdb != newfdb)
|
||||
xfs_da_brelse(tp, curbp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
curfdb = newfdb;
|
||||
if (be16_to_cpu(free->bests[fi]) >= length) {
|
||||
*indexp = index;
|
||||
state->extravalid = 1;
|
||||
|
@ -580,7 +580,7 @@ xfs_dir2_leafn_lookup_int(
|
|||
if (dep->namelen == args->namelen &&
|
||||
dep->name[0] == args->name[0] &&
|
||||
memcmp(dep->name, args->name, args->namelen) == 0) {
|
||||
args->inumber = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
args->inumber = be64_to_cpu(dep->inumber);
|
||||
*indexp = index;
|
||||
state->extravalid = 1;
|
||||
state->extrablk.bp = curbp;
|
||||
|
@ -970,7 +970,7 @@ xfs_dir2_leafn_remove(
|
|||
/*
|
||||
* One less used entry in the free table.
|
||||
*/
|
||||
free->hdr.nused = cpu_to_be32(-1);
|
||||
be32_add(&free->hdr.nused, -1);
|
||||
xfs_dir2_free_log_header(tp, fbp);
|
||||
/*
|
||||
* If this was the last entry in the table, we can
|
||||
|
@ -1695,7 +1695,7 @@ xfs_dir2_node_addname_int(
|
|||
* Fill in the new entry and log it.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)dup;
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, args->inumber);
|
||||
dep->inumber = cpu_to_be64(args->inumber);
|
||||
dep->namelen = args->namelen;
|
||||
memcpy(dep->name, args->name, dep->namelen);
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
|
@ -1905,11 +1905,11 @@ xfs_dir2_node_replace(
|
|||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)data +
|
||||
XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address)));
|
||||
ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT));
|
||||
ASSERT(inum != be64_to_cpu(dep->inumber));
|
||||
/*
|
||||
* Fill in the new inode number and log the entry.
|
||||
*/
|
||||
INT_SET(dep->inumber, ARCH_CONVERT, inum);
|
||||
dep->inumber = cpu_to_be64(inum);
|
||||
xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
|
||||
rval = 0;
|
||||
}
|
||||
|
|
|
@ -22,19 +22,16 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_inode_item.h"
|
||||
#include "xfs_dir_leaf.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_dir2_data.h"
|
||||
#include "xfs_dir2_leaf.h"
|
||||
|
@ -117,13 +114,13 @@ xfs_dir2_block_sfsize(
|
|||
dep->name[0] == '.' && dep->name[1] == '.';
|
||||
#if XFS_BIG_INUMS
|
||||
if (!isdot)
|
||||
i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM;
|
||||
i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM;
|
||||
#endif
|
||||
if (!isdot && !isdotdot) {
|
||||
count++;
|
||||
namelen += dep->namelen;
|
||||
} else if (isdotdot)
|
||||
parent = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
parent = be64_to_cpu(dep->inumber);
|
||||
/*
|
||||
* Calculate the new size, see if we should give up yet.
|
||||
*/
|
||||
|
@ -229,13 +226,13 @@ xfs_dir2_block_to_sf(
|
|||
* Skip .
|
||||
*/
|
||||
if (dep->namelen == 1 && dep->name[0] == '.')
|
||||
ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino);
|
||||
ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino);
|
||||
/*
|
||||
* Skip .., but make sure the inode number is right.
|
||||
*/
|
||||
else if (dep->namelen == 2 &&
|
||||
dep->name[0] == '.' && dep->name[1] == '.')
|
||||
ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) ==
|
||||
ASSERT(be64_to_cpu(dep->inumber) ==
|
||||
XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
|
||||
/*
|
||||
* Normal entry, copy it into shortform.
|
||||
|
@ -246,7 +243,7 @@ xfs_dir2_block_to_sf(
|
|||
(xfs_dir2_data_aoff_t)
|
||||
((char *)dep - (char *)block));
|
||||
memcpy(sfep->name, dep->name, dep->namelen);
|
||||
temp=INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
temp = be64_to_cpu(dep->inumber);
|
||||
XFS_DIR2_SF_PUT_INUMBER(sfp, &temp,
|
||||
XFS_DIR2_SF_INUMBERP(sfep));
|
||||
sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
|
||||
|
|
|
@ -19,11 +19,9 @@
|
|||
#include "xfs_fs.h"
|
||||
#include "xfs_types.h"
|
||||
#include "xfs_inum.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __XFS_DIR_LEAF_H__
|
||||
#define __XFS_DIR_LEAF_H__
|
||||
|
||||
/*
|
||||
* Directory layout, internal structure, access macros, etc.
|
||||
*
|
||||
* Large directories are structured around Btrees where all the data
|
||||
* elements are in the leaf nodes. Filenames are hashed into an int,
|
||||
* then that int is used as the index into the Btree. Since the hashval
|
||||
* of a filename may not be unique, we may have duplicate keys. The
|
||||
* internal links in the Btree are logical block offsets into the file.
|
||||
*/
|
||||
|
||||
struct uio;
|
||||
struct xfs_bmap_free;
|
||||
struct xfs_dabuf;
|
||||
struct xfs_da_args;
|
||||
struct xfs_da_state;
|
||||
struct xfs_da_state_blk;
|
||||
struct xfs_dir_put_args;
|
||||
struct xfs_inode;
|
||||
struct xfs_mount;
|
||||
struct xfs_trans;
|
||||
|
||||
/*========================================================================
|
||||
* Directory Structure when equal to XFS_LBSIZE(mp) bytes.
|
||||
*========================================================================*/
|
||||
|
||||
/*
|
||||
* This is the structure of the leaf nodes in the Btree.
|
||||
*
|
||||
* Struct leaf_entry's are packed from the top. Names grow from the bottom
|
||||
* but are not packed. The freemap contains run-length-encoded entries
|
||||
* for the free bytes after the leaf_entry's, but only the N largest such,
|
||||
* smaller runs are dropped. When the freemap doesn't show enough space
|
||||
* for an allocation, we compact the namelist area and try again. If we
|
||||
* still don't have enough space, then we have to split the block.
|
||||
*
|
||||
* Since we have duplicate hash keys, for each key that matches, compare
|
||||
* the actual string. The root and intermediate node search always takes
|
||||
* the first-in-the-block key match found, so we should only have to work
|
||||
* "forw"ard. If none matches, continue with the "forw"ard leaf nodes
|
||||
* until the hash key changes or the filename is found.
|
||||
*
|
||||
* The parent directory and the self-pointer are explicitly represented
|
||||
* (ie: there are entries for "." and "..").
|
||||
*
|
||||
* Note that the count being a __uint16_t limits us to something like a
|
||||
* blocksize of 1.3MB in the face of worst case (short) filenames.
|
||||
*/
|
||||
#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */
|
||||
|
||||
typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */
|
||||
__uint16_t base; /* base of free region */
|
||||
__uint16_t size; /* run length of free region */
|
||||
} xfs_dir_leaf_map_t;
|
||||
|
||||
typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */
|
||||
xfs_da_blkinfo_t info; /* block type, links, etc. */
|
||||
__uint16_t count; /* count of active leaf_entry's */
|
||||
__uint16_t namebytes; /* num bytes of name strings stored */
|
||||
__uint16_t firstused; /* first used byte in name area */
|
||||
__uint8_t holes; /* != 0 if blk needs compaction */
|
||||
__uint8_t pad1;
|
||||
xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];
|
||||
} xfs_dir_leaf_hdr_t;
|
||||
|
||||
typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */
|
||||
xfs_dahash_t hashval; /* hash value of name */
|
||||
__uint16_t nameidx; /* index into buffer of name */
|
||||
__uint8_t namelen; /* length of name string */
|
||||
__uint8_t pad2;
|
||||
} xfs_dir_leaf_entry_t;
|
||||
|
||||
typedef struct xfs_dir_leaf_name {
|
||||
xfs_dir_ino_t inumber; /* inode number for this key */
|
||||
__uint8_t name[1]; /* name string itself */
|
||||
} xfs_dir_leaf_name_t;
|
||||
|
||||
typedef struct xfs_dir_leafblock {
|
||||
xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */
|
||||
xfs_dir_leaf_entry_t entries[1]; /* var sized array */
|
||||
xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */
|
||||
} xfs_dir_leafblock_t;
|
||||
|
||||
/*
|
||||
* Length of name for which a 512-byte block filesystem
|
||||
* can get a double split.
|
||||
*/
|
||||
#define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \
|
||||
(512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \
|
||||
(uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \
|
||||
(uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1)
|
||||
|
||||
typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa);
|
||||
|
||||
typedef union {
|
||||
xfs_off_t o; /* offset (cookie) */
|
||||
/*
|
||||
* Watch the order here (endian-ness dependent).
|
||||
*/
|
||||
struct {
|
||||
#ifndef XFS_NATIVE_HOST
|
||||
xfs_dahash_t h; /* hash value */
|
||||
__uint32_t be; /* block and entry */
|
||||
#else
|
||||
__uint32_t be; /* block and entry */
|
||||
xfs_dahash_t h; /* hash value */
|
||||
#endif /* XFS_NATIVE_HOST */
|
||||
} s;
|
||||
} xfs_dircook_t;
|
||||
|
||||
#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \
|
||||
((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))
|
||||
|
||||
typedef struct xfs_dir_put_args {
|
||||
xfs_dircook_t cook; /* cookie of (next) entry */
|
||||
xfs_intino_t ino; /* inode number */
|
||||
struct xfs_dirent *dbp; /* buffer pointer */
|
||||
char *name; /* directory entry name */
|
||||
int namelen; /* length of name */
|
||||
int done; /* output: set if value was stored */
|
||||
xfs_dir_put_t put; /* put function ptr (i/o) */
|
||||
struct uio *uio; /* uio control structure */
|
||||
} xfs_dir_put_args_t;
|
||||
|
||||
#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \
|
||||
xfs_dir_leaf_entsize_byname(len)
|
||||
static inline int xfs_dir_leaf_entsize_byname(int len)
|
||||
{
|
||||
return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
|
||||
}
|
||||
|
||||
#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \
|
||||
xfs_dir_leaf_entsize_byentry(entry)
|
||||
static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
|
||||
{
|
||||
return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen;
|
||||
}
|
||||
|
||||
#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \
|
||||
xfs_dir_leaf_namestruct(leafp,offset)
|
||||
static inline xfs_dir_leaf_name_t *
|
||||
xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
|
||||
{
|
||||
return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset];
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
* Function prototypes for the kernel.
|
||||
*========================================================================*/
|
||||
|
||||
/*
|
||||
* Internal routines when dirsize < XFS_LITINO(mp).
|
||||
*/
|
||||
int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent);
|
||||
int xfs_dir_shortform_addname(struct xfs_da_args *args);
|
||||
int xfs_dir_shortform_lookup(struct xfs_da_args *args);
|
||||
int xfs_dir_shortform_to_leaf(struct xfs_da_args *args);
|
||||
int xfs_dir_shortform_removename(struct xfs_da_args *args);
|
||||
int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
|
||||
struct xfs_dirent *dbp, xfs_dir_put_t put);
|
||||
int xfs_dir_shortform_replace(struct xfs_da_args *args);
|
||||
|
||||
/*
|
||||
* Internal routines when dirsize == XFS_LBSIZE(mp).
|
||||
*/
|
||||
int xfs_dir_leaf_to_node(struct xfs_da_args *args);
|
||||
int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
|
||||
|
||||
/*
|
||||
* Routines used for growing the Btree.
|
||||
*/
|
||||
int xfs_dir_leaf_split(struct xfs_da_state *state,
|
||||
struct xfs_da_state_blk *oldblk,
|
||||
struct xfs_da_state_blk *newblk);
|
||||
int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer,
|
||||
struct xfs_da_args *args, int insertion_index);
|
||||
int xfs_dir_leaf_addname(struct xfs_da_args *args);
|
||||
int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer,
|
||||
struct xfs_da_args *args,
|
||||
int *index_found_at);
|
||||
int xfs_dir_leaf_remove(struct xfs_trans *trans,
|
||||
struct xfs_dabuf *leaf_buffer,
|
||||
int index_to_remove);
|
||||
int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp,
|
||||
xfs_dablk_t bno, struct uio *uio,
|
||||
int *eobp, struct xfs_dirent *dbp,
|
||||
xfs_dir_put_t put, xfs_daddr_t nextda);
|
||||
|
||||
/*
|
||||
* Routines used for shrinking the Btree.
|
||||
*/
|
||||
int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval);
|
||||
void xfs_dir_leaf_unbalance(struct xfs_da_state *state,
|
||||
struct xfs_da_state_blk *drop_blk,
|
||||
struct xfs_da_state_blk *save_blk);
|
||||
|
||||
/*
|
||||
* Utility routines.
|
||||
*/
|
||||
uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count);
|
||||
int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp,
|
||||
struct xfs_dabuf *leaf2_bp);
|
||||
int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa);
|
||||
int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa);
|
||||
int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
|
||||
|
||||
/*
|
||||
* Global data.
|
||||
*/
|
||||
extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
|
||||
|
||||
#endif /* __XFS_DIR_LEAF_H__ */
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2000,2005 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __XFS_DIR_SF_H__
|
||||
#define __XFS_DIR_SF_H__
|
||||
|
||||
/*
|
||||
* Directory layout when stored internal to an inode.
|
||||
*
|
||||
* Small directories are packed as tightly as possible so as to
|
||||
* fit into the literal area of the inode.
|
||||
*/
|
||||
|
||||
typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t;
|
||||
|
||||
/*
|
||||
* The parent directory has a dedicated field, and the self-pointer must
|
||||
* be calculated on the fly.
|
||||
*
|
||||
* Entries are packed toward the top as tight as possible. The header
|
||||
* and the elements much be memcpy'd out into a work area to get correct
|
||||
* alignment for the inode number fields.
|
||||
*/
|
||||
typedef struct xfs_dir_sf_hdr { /* constant-structure header block */
|
||||
xfs_dir_ino_t parent; /* parent dir inode number */
|
||||
__uint8_t count; /* count of active entries */
|
||||
} xfs_dir_sf_hdr_t;
|
||||
|
||||
typedef struct xfs_dir_sf_entry {
|
||||
xfs_dir_ino_t inumber; /* referenced inode number */
|
||||
__uint8_t namelen; /* actual length of name (no NULL) */
|
||||
__uint8_t name[1]; /* name */
|
||||
} xfs_dir_sf_entry_t;
|
||||
|
||||
typedef struct xfs_dir_shortform {
|
||||
xfs_dir_sf_hdr_t hdr;
|
||||
xfs_dir_sf_entry_t list[1]; /* variable sized array */
|
||||
} xfs_dir_shortform_t;
|
||||
|
||||
/*
|
||||
* We generate this then sort it, so that readdirs are returned in
|
||||
* hash-order. Else seekdir won't work.
|
||||
*/
|
||||
typedef struct xfs_dir_sf_sort {
|
||||
__uint8_t entno; /* .=0, ..=1, else entry# + 2 */
|
||||
__uint8_t seqno; /* sequence # with same hash value */
|
||||
__uint8_t namelen; /* length of name value (no null) */
|
||||
xfs_dahash_t hash; /* this entry's hash value */
|
||||
xfs_intino_t ino; /* this entry's inode number */
|
||||
char *name; /* name value, pointer into buffer */
|
||||
} xfs_dir_sf_sort_t;
|
||||
|
||||
#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
|
||||
static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
|
||||
{
|
||||
*(to) = XFS_GET_DIR_INO8(*from);
|
||||
}
|
||||
|
||||
#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
|
||||
static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
|
||||
{
|
||||
XFS_PUT_DIR_INO8(*(from), *(to));
|
||||
}
|
||||
|
||||
#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
|
||||
static inline int xfs_dir_sf_entsize_byname(int len)
|
||||
{
|
||||
return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len);
|
||||
}
|
||||
|
||||
#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep)
|
||||
static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
|
||||
{
|
||||
return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen;
|
||||
}
|
||||
|
||||
#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep)
|
||||
static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
|
||||
{
|
||||
return (xfs_dir_sf_entry_t *) \
|
||||
((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep));
|
||||
}
|
||||
|
||||
#define XFS_DIR_SF_ALLFIT(count,totallen) \
|
||||
xfs_dir_sf_allfit(count,totallen)
|
||||
static inline int xfs_dir_sf_allfit(int count, int totallen)
|
||||
{
|
||||
return ((uint)sizeof(xfs_dir_sf_hdr_t) + \
|
||||
((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen));
|
||||
}
|
||||
|
||||
#if defined(XFS_DIR_TRACE)
|
||||
|
||||
/*
|
||||
* Kernel tracing support for directories.
|
||||
*/
|
||||
struct uio;
|
||||
struct xfs_inode;
|
||||
struct xfs_da_intnode;
|
||||
struct xfs_dinode;
|
||||
struct xfs_dir_leafblock;
|
||||
struct xfs_dir_leaf_entry;
|
||||
|
||||
#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */
|
||||
extern ktrace_t *xfs_dir_trace_buf;
|
||||
|
||||
/*
|
||||
* Trace record types.
|
||||
*/
|
||||
#define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */
|
||||
#define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */
|
||||
#define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */
|
||||
#define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */
|
||||
#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */
|
||||
#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */
|
||||
|
||||
void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio);
|
||||
void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio,
|
||||
xfs_dablk_t bno);
|
||||
void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio,
|
||||
struct xfs_da_intnode *node);
|
||||
void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio,
|
||||
struct xfs_dir_leafblock *leaf);
|
||||
void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio,
|
||||
struct xfs_dir_leaf_entry *entry);
|
||||
void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio,
|
||||
xfs_off_t cookie);
|
||||
void xfs_dir_trace_enter(int type, char *where,
|
||||
void *a0, void *a1, void *a2, void *a3,
|
||||
void *a4, void *a5, void *a6, void *a7,
|
||||
void *a8, void *a9, void *a10, void *a11);
|
||||
#else
|
||||
#define xfs_dir_trace_g_du(w,d,u)
|
||||
#define xfs_dir_trace_g_dub(w,d,u,b)
|
||||
#define xfs_dir_trace_g_dun(w,d,u,n)
|
||||
#define xfs_dir_trace_g_dul(w,d,u,l)
|
||||
#define xfs_dir_trace_g_due(w,d,u,e)
|
||||
#define xfs_dir_trace_g_duc(w,d,u,c)
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* __XFS_DIR_SF_H__ */
|
|
@ -189,6 +189,6 @@ typedef enum {
|
|||
#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
|
||||
|
||||
|
||||
extern struct bhv_vfsops xfs_dmops;
|
||||
extern struct bhv_module_vfsops xfs_dmops;
|
||||
|
||||
#endif /* __XFS_DMAPI_H__ */
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
|
|
@ -22,12 +22,10 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_trans_priv.h"
|
||||
|
@ -293,6 +292,62 @@ xfs_efi_init(xfs_mount_t *mp,
|
|||
return (efip);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy an EFI format buffer from the given buf, and into the destination
|
||||
* EFI format structure.
|
||||
* The given buffer can be in 32 bit or 64 bit form (which has different padding),
|
||||
* one of which will be the native format for this kernel.
|
||||
* It will handle the conversion of formats if necessary.
|
||||
*/
|
||||
int
|
||||
xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
|
||||
{
|
||||
xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
|
||||
uint i;
|
||||
uint len = sizeof(xfs_efi_log_format_t) +
|
||||
(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
|
||||
uint len32 = sizeof(xfs_efi_log_format_32_t) +
|
||||
(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);
|
||||
uint len64 = sizeof(xfs_efi_log_format_64_t) +
|
||||
(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);
|
||||
|
||||
if (buf->i_len == len) {
|
||||
memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
|
||||
return 0;
|
||||
} else if (buf->i_len == len32) {
|
||||
xfs_efi_log_format_32_t *src_efi_fmt_32 =
|
||||
(xfs_efi_log_format_32_t *)buf->i_addr;
|
||||
|
||||
dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
|
||||
dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
|
||||
dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
|
||||
dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
|
||||
for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
|
||||
dst_efi_fmt->efi_extents[i].ext_start =
|
||||
src_efi_fmt_32->efi_extents[i].ext_start;
|
||||
dst_efi_fmt->efi_extents[i].ext_len =
|
||||
src_efi_fmt_32->efi_extents[i].ext_len;
|
||||
}
|
||||
return 0;
|
||||
} else if (buf->i_len == len64) {
|
||||
xfs_efi_log_format_64_t *src_efi_fmt_64 =
|
||||
(xfs_efi_log_format_64_t *)buf->i_addr;
|
||||
|
||||
dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
|
||||
dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
|
||||
dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
|
||||
dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
|
||||
for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
|
||||
dst_efi_fmt->efi_extents[i].ext_start =
|
||||
src_efi_fmt_64->efi_extents[i].ext_start;
|
||||
dst_efi_fmt->efi_extents[i].ext_len =
|
||||
src_efi_fmt_64->efi_extents[i].ext_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return EFSCORRUPTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called by the efd item code below to release references to
|
||||
* the given efi item. Each efd calls this with the number of
|
||||
|
|
|
@ -26,6 +26,24 @@ typedef struct xfs_extent {
|
|||
xfs_extlen_t ext_len;
|
||||
} xfs_extent_t;
|
||||
|
||||
/*
|
||||
* Since an xfs_extent_t has types (start:64, len: 32)
|
||||
* there are different alignments on 32 bit and 64 bit kernels.
|
||||
* So we provide the different variants for use by a
|
||||
* conversion routine.
|
||||
*/
|
||||
|
||||
typedef struct xfs_extent_32 {
|
||||
xfs_dfsbno_t ext_start;
|
||||
xfs_extlen_t ext_len;
|
||||
} __attribute__((packed)) xfs_extent_32_t;
|
||||
|
||||
typedef struct xfs_extent_64 {
|
||||
xfs_dfsbno_t ext_start;
|
||||
xfs_extlen_t ext_len;
|
||||
__uint32_t ext_pad;
|
||||
} xfs_extent_64_t;
|
||||
|
||||
/*
|
||||
* This is the structure used to lay out an efi log item in the
|
||||
* log. The efi_extents field is a variable size array whose
|
||||
|
@ -39,6 +57,22 @@ typedef struct xfs_efi_log_format {
|
|||
xfs_extent_t efi_extents[1]; /* array of extents to free */
|
||||
} xfs_efi_log_format_t;
|
||||
|
||||
typedef struct xfs_efi_log_format_32 {
|
||||
unsigned short efi_type; /* efi log item type */
|
||||
unsigned short efi_size; /* size of this item */
|
||||
uint efi_nextents; /* # extents to free */
|
||||
__uint64_t efi_id; /* efi identifier */
|
||||
xfs_extent_32_t efi_extents[1]; /* array of extents to free */
|
||||
} __attribute__((packed)) xfs_efi_log_format_32_t;
|
||||
|
||||
typedef struct xfs_efi_log_format_64 {
|
||||
unsigned short efi_type; /* efi log item type */
|
||||
unsigned short efi_size; /* size of this item */
|
||||
uint efi_nextents; /* # extents to free */
|
||||
__uint64_t efi_id; /* efi identifier */
|
||||
xfs_extent_64_t efi_extents[1]; /* array of extents to free */
|
||||
} xfs_efi_log_format_64_t;
|
||||
|
||||
/*
|
||||
* This is the structure used to lay out an efd log item in the
|
||||
* log. The efd_extents array is a variable size array whose
|
||||
|
@ -52,6 +86,22 @@ typedef struct xfs_efd_log_format {
|
|||
xfs_extent_t efd_extents[1]; /* array of extents freed */
|
||||
} xfs_efd_log_format_t;
|
||||
|
||||
typedef struct xfs_efd_log_format_32 {
|
||||
unsigned short efd_type; /* efd log item type */
|
||||
unsigned short efd_size; /* size of this item */
|
||||
uint efd_nextents; /* # of extents freed */
|
||||
__uint64_t efd_efi_id; /* id of corresponding efi */
|
||||
xfs_extent_32_t efd_extents[1]; /* array of extents freed */
|
||||
} __attribute__((packed)) xfs_efd_log_format_32_t;
|
||||
|
||||
typedef struct xfs_efd_log_format_64 {
|
||||
unsigned short efd_type; /* efd log item type */
|
||||
unsigned short efd_size; /* size of this item */
|
||||
uint efd_nextents; /* # of extents freed */
|
||||
__uint64_t efd_efi_id; /* id of corresponding efi */
|
||||
xfs_extent_64_t efd_extents[1]; /* array of extents freed */
|
||||
} xfs_efd_log_format_64_t;
|
||||
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
|
@ -103,7 +153,8 @@ extern struct kmem_zone *xfs_efd_zone;
|
|||
xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
|
||||
xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
|
||||
uint);
|
||||
|
||||
int xfs_efi_copy_format(xfs_log_iovec_t *buf,
|
||||
xfs_efi_log_format_t *dst_efi_fmt);
|
||||
void xfs_efi_item_free(xfs_efi_log_item_t *);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
@ -67,14 +67,15 @@ struct fsxattr {
|
|||
#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
|
||||
#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
|
||||
#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
|
||||
#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
|
||||
#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
|
||||
|
||||
/*
|
||||
* Structure for XFS_IOC_GETBMAP.
|
||||
* On input, fill in bmv_offset and bmv_length of the first structure
|
||||
* to indicate the area of interest in the file, and bmv_entry with the
|
||||
* number of array elements given. The first structure is updated on
|
||||
* return to give the offset and length for the next call.
|
||||
* to indicate the area of interest in the file, and bmv_entries with
|
||||
* the number of array elements given back. The first structure is
|
||||
* updated on return to give the offset and length for the next call.
|
||||
*/
|
||||
#ifndef HAVE_GETBMAP
|
||||
struct getbmap {
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -542,14 +540,13 @@ xfs_reserve_blocks(
|
|||
}
|
||||
|
||||
void
|
||||
xfs_fs_log_dummy(xfs_mount_t *mp)
|
||||
xfs_fs_log_dummy(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
xfs_trans_t *tp;
|
||||
xfs_inode_t *ip;
|
||||
|
||||
|
||||
tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
|
||||
atomic_inc(&mp->m_active_trans);
|
||||
if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
|
||||
xfs_trans_cancel(tp, 0);
|
||||
return;
|
||||
|
@ -574,21 +571,22 @@ xfs_fs_goingdown(
|
|||
{
|
||||
switch (inflags) {
|
||||
case XFS_FSOP_GOING_FLAGS_DEFAULT: {
|
||||
struct vfs *vfsp = XFS_MTOVFS(mp);
|
||||
struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
|
||||
struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
|
||||
|
||||
if (sb && !IS_ERR(sb)) {
|
||||
xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
|
||||
thaw_bdev(sb->s_bdev, sb);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
|
||||
xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
|
||||
break;
|
||||
case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
|
||||
xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR);
|
||||
xfs_force_shutdown(mp,
|
||||
SHUTDOWN_FORCE_UMOUNT | SHUTDOWN_LOG_IO_ERROR);
|
||||
break;
|
||||
default:
|
||||
return XFS_ERROR(EINVAL);
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -1174,6 +1172,9 @@ xfs_dilocate(
|
|||
if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
|
||||
ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
|
||||
#ifdef DEBUG
|
||||
/* no diagnostics for bulkstat, ino comes from userspace */
|
||||
if (flags & XFS_IMAP_BULKSTAT)
|
||||
return XFS_ERROR(EINVAL);
|
||||
if (agno >= mp->m_sb.sb_agcount) {
|
||||
xfs_fs_cmn_err(CE_ALERT, mp,
|
||||
"xfs_dilocate: agno (%d) >= "
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -186,7 +184,7 @@ xfs_ihash_promote(
|
|||
*/
|
||||
STATIC int
|
||||
xfs_iget_core(
|
||||
vnode_t *vp,
|
||||
bhv_vnode_t *vp,
|
||||
xfs_mount_t *mp,
|
||||
xfs_trans_t *tp,
|
||||
xfs_ino_t ino,
|
||||
|
@ -198,7 +196,7 @@ xfs_iget_core(
|
|||
xfs_ihash_t *ih;
|
||||
xfs_inode_t *ip;
|
||||
xfs_inode_t *iq;
|
||||
vnode_t *inode_vp;
|
||||
bhv_vnode_t *inode_vp;
|
||||
ulong version;
|
||||
int error;
|
||||
/* REFERENCED */
|
||||
|
@ -468,7 +466,7 @@ finish_inode:
|
|||
* If we have a real type for an on-disk inode, we can set ops(&unlock)
|
||||
* now. If it's a new inode being created, xfs_ialloc will handle it.
|
||||
*/
|
||||
VFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
|
||||
bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -489,7 +487,7 @@ xfs_iget(
|
|||
xfs_daddr_t bno)
|
||||
{
|
||||
struct inode *inode;
|
||||
vnode_t *vp = NULL;
|
||||
bhv_vnode_t *vp = NULL;
|
||||
int error;
|
||||
|
||||
XFS_STATS_INC(xs_ig_attempts);
|
||||
|
@ -543,7 +541,7 @@ retry:
|
|||
void
|
||||
xfs_inode_lock_init(
|
||||
xfs_inode_t *ip,
|
||||
vnode_t *vp)
|
||||
bhv_vnode_t *vp)
|
||||
{
|
||||
mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
|
||||
"xfsino", (long)vp->v_number);
|
||||
|
@ -603,12 +601,10 @@ void
|
|||
xfs_iput(xfs_inode_t *ip,
|
||||
uint lock_flags)
|
||||
{
|
||||
vnode_t *vp = XFS_ITOV(ip);
|
||||
bhv_vnode_t *vp = XFS_ITOV(ip);
|
||||
|
||||
vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
|
||||
|
||||
xfs_iunlock(ip, lock_flags);
|
||||
|
||||
VN_RELE(vp);
|
||||
}
|
||||
|
||||
|
@ -619,7 +615,7 @@ void
|
|||
xfs_iput_new(xfs_inode_t *ip,
|
||||
uint lock_flags)
|
||||
{
|
||||
vnode_t *vp = XFS_ITOV(ip);
|
||||
bhv_vnode_t *vp = XFS_ITOV(ip);
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
|
||||
|
@ -645,7 +641,7 @@ xfs_iput_new(xfs_inode_t *ip,
|
|||
void
|
||||
xfs_ireclaim(xfs_inode_t *ip)
|
||||
{
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
|
||||
/*
|
||||
* Remove from old hash list and mount list.
|
||||
|
@ -1033,6 +1029,6 @@ xfs_iflock_nowait(xfs_inode_t *ip)
|
|||
void
|
||||
xfs_ifunlock(xfs_inode_t *ip)
|
||||
{
|
||||
ASSERT(valusema(&(ip->i_flock)) <= 0);
|
||||
ASSERT(issemalocked(&(ip->i_flock)));
|
||||
vsema(&(ip->i_flock));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -26,14 +26,12 @@
|
|||
#include "xfs_trans_priv.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -256,13 +254,11 @@ xfs_itobp(
|
|||
xfs_daddr_t bno,
|
||||
uint imap_flags)
|
||||
{
|
||||
xfs_imap_t imap;
|
||||
xfs_buf_t *bp;
|
||||
int error;
|
||||
xfs_imap_t imap;
|
||||
#ifdef __KERNEL__
|
||||
int i;
|
||||
int ni;
|
||||
#endif
|
||||
|
||||
if (ip->i_blkno == (xfs_daddr_t)0) {
|
||||
/*
|
||||
|
@ -319,7 +315,6 @@ xfs_itobp(
|
|||
*/
|
||||
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
|
||||
(int)imap.im_len, XFS_BUF_LOCK, &bp);
|
||||
|
||||
if (error) {
|
||||
#ifdef DEBUG
|
||||
xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
|
||||
|
@ -330,17 +325,21 @@ xfs_itobp(
|
|||
#endif /* DEBUG */
|
||||
return error;
|
||||
}
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* Validate the magic number and version of every inode in the buffer
|
||||
* (if DEBUG kernel) or the first inode in the buffer, otherwise.
|
||||
* No validation is done here in userspace (xfs_repair).
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#if !defined(__KERNEL__)
|
||||
ni = 0;
|
||||
#elif defined(DEBUG)
|
||||
ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
|
||||
(BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
|
||||
#else
|
||||
#else /* usual case */
|
||||
ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ni; i++) {
|
||||
int di_ok;
|
||||
xfs_dinode_t *dip;
|
||||
|
@ -352,8 +351,11 @@ xfs_itobp(
|
|||
if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
|
||||
XFS_RANDOM_ITOBP_INOTOBP))) {
|
||||
#ifdef DEBUG
|
||||
prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)",
|
||||
mp->m_ddev_targp,
|
||||
if (!(imap_flags & XFS_IMAP_BULKSTAT))
|
||||
cmn_err(CE_ALERT,
|
||||
"Device %s - bad inode magic/vsn "
|
||||
"daddr %lld #%d (magic=%x)",
|
||||
XFS_BUFTARG_NAME(mp->m_ddev_targp),
|
||||
(unsigned long long)imap.im_blkno, i,
|
||||
INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
|
||||
#endif
|
||||
|
@ -363,7 +365,6 @@ xfs_itobp(
|
|||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
}
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
xfs_inobp_check(mp, bp);
|
||||
|
||||
|
@ -782,7 +783,6 @@ xfs_xlate_dinode_core(
|
|||
|
||||
STATIC uint
|
||||
_xfs_dic2xflags(
|
||||
xfs_dinode_core_t *dic,
|
||||
__uint16_t di_flags)
|
||||
{
|
||||
uint flags = 0;
|
||||
|
@ -812,6 +812,8 @@ _xfs_dic2xflags(
|
|||
flags |= XFS_XFLAG_EXTSIZE;
|
||||
if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
|
||||
flags |= XFS_XFLAG_EXTSZINHERIT;
|
||||
if (di_flags & XFS_DIFLAG_NODEFRAG)
|
||||
flags |= XFS_XFLAG_NODEFRAG;
|
||||
}
|
||||
|
||||
return flags;
|
||||
|
@ -823,7 +825,7 @@ xfs_ip2xflags(
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -831,7 +833,7 @@ uint
|
|||
xfs_dic2xflags(
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1083,7 +1085,7 @@ xfs_ialloc(
|
|||
{
|
||||
xfs_ino_t ino;
|
||||
xfs_inode_t *ip;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
uint flags;
|
||||
int error;
|
||||
|
||||
|
@ -1221,6 +1223,9 @@ xfs_ialloc(
|
|||
di_flags |= XFS_DIFLAG_NOSYMLINKS;
|
||||
if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
|
||||
di_flags |= XFS_DIFLAG_PROJINHERIT;
|
||||
if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
|
||||
xfs_inherit_nodefrag)
|
||||
di_flags |= XFS_DIFLAG_NODEFRAG;
|
||||
ip->i_d.di_flags |= di_flags;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
@ -1244,8 +1249,8 @@ xfs_ialloc(
|
|||
*/
|
||||
xfs_trans_log_inode(tp, ip, flags);
|
||||
|
||||
/* now that we have an i_mode we can set Linux inode ops (& unlock) */
|
||||
VFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
|
||||
/* now that we have an i_mode we can setup inode ops and unlock */
|
||||
bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
|
||||
|
||||
*ipp = ip;
|
||||
return 0;
|
||||
|
@ -1285,7 +1290,7 @@ xfs_isize_check(
|
|||
(xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
|
||||
map_first),
|
||||
XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
|
||||
NULL))
|
||||
NULL, NULL))
|
||||
return;
|
||||
ASSERT(nimaps == 1);
|
||||
ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
|
||||
|
@ -1421,7 +1426,7 @@ xfs_itruncate_start(
|
|||
xfs_fsize_t last_byte;
|
||||
xfs_off_t toss_start;
|
||||
xfs_mount_t *mp;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
|
||||
ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
|
||||
ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
|
||||
|
@ -1434,9 +1439,9 @@ xfs_itruncate_start(
|
|||
vn_iowait(vp); /* wait for the completion of any pending DIOs */
|
||||
|
||||
/*
|
||||
* Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers
|
||||
* Call toss_pages or flushinval_pages to get rid of pages
|
||||
* overlapping the region being removed. We have to use
|
||||
* the less efficient VOP_FLUSHINVAL_PAGES() in the case that the
|
||||
* the less efficient flushinval_pages in the case that the
|
||||
* caller may not be able to finish the truncate without
|
||||
* dropping the inode's I/O lock. Make sure
|
||||
* to catch any pages brought in by buffers overlapping
|
||||
|
@ -1445,10 +1450,10 @@ xfs_itruncate_start(
|
|||
* so that we don't toss things on the same block as
|
||||
* new_size but before it.
|
||||
*
|
||||
* Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to
|
||||
* Before calling toss_page or flushinval_pages, make sure to
|
||||
* call remapf() over the same region if the file is mapped.
|
||||
* This frees up mapped file references to the pages in the
|
||||
* given range and for the VOP_FLUSHINVAL_PAGES() case it ensures
|
||||
* given range and for the flushinval_pages case it ensures
|
||||
* that we get the latest mapped changes flushed out.
|
||||
*/
|
||||
toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
|
||||
|
@ -1466,9 +1471,9 @@ xfs_itruncate_start(
|
|||
last_byte);
|
||||
if (last_byte > toss_start) {
|
||||
if (flags & XFS_ITRUNC_DEFINITE) {
|
||||
VOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
|
||||
bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
|
||||
} else {
|
||||
VOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED);
|
||||
bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1666,12 +1671,13 @@ xfs_itruncate_finish(
|
|||
* runs.
|
||||
*/
|
||||
XFS_BMAP_INIT(&free_list, &first_block);
|
||||
error = xfs_bunmapi(ntp, ip, first_unmap_block,
|
||||
unmap_len,
|
||||
error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
|
||||
first_unmap_block, unmap_len,
|
||||
XFS_BMAPI_AFLAG(fork) |
|
||||
(sync ? 0 : XFS_BMAPI_ASYNC),
|
||||
XFS_ITRUNC_MAX_EXTENTS,
|
||||
&first_block, &free_list, &done);
|
||||
&first_block, &free_list,
|
||||
NULL, &done);
|
||||
if (error) {
|
||||
/*
|
||||
* If the bunmapi call encounters an error,
|
||||
|
@ -2745,13 +2751,14 @@ xfs_iunpin(
|
|||
* the inode to become unpinned.
|
||||
*/
|
||||
if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
|
||||
vnode_t *vp = XFS_ITOV_NULL(ip);
|
||||
bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
|
||||
|
||||
/* make sync come back and flush this inode */
|
||||
if (vp) {
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
if (!(inode->i_state & I_NEW))
|
||||
if (!(inode->i_state &
|
||||
(I_NEW|I_FREEING|I_CLEAR)))
|
||||
mark_inode_dirty_sync(inode);
|
||||
}
|
||||
}
|
||||
|
@ -2916,13 +2923,6 @@ xfs_iflush_fork(
|
|||
ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
|
||||
memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
|
||||
}
|
||||
if (whichfork == XFS_DATA_FORK) {
|
||||
if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
|
||||
XFS_ERROR_REPORT("xfs_iflush_fork",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XFS_DINODE_FMT_EXTENTS:
|
||||
|
@ -3006,7 +3006,7 @@ xfs_iflush(
|
|||
XFS_STATS_INC(xs_iflush_count);
|
||||
|
||||
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
|
||||
ASSERT(valusema(&ip->i_flock) <= 0);
|
||||
ASSERT(issemalocked(&(ip->i_flock)));
|
||||
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
|
||||
ip->i_d.di_nextents > ip->i_df.if_ext_max);
|
||||
|
||||
|
@ -3199,7 +3199,7 @@ xfs_iflush(
|
|||
|
||||
corrupt_out:
|
||||
xfs_buf_relse(bp);
|
||||
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
|
||||
xfs_iflush_abort(ip);
|
||||
/*
|
||||
* Unlocks the flush lock
|
||||
|
@ -3221,7 +3221,7 @@ cluster_corrupt_out:
|
|||
xfs_buf_relse(bp);
|
||||
}
|
||||
|
||||
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
|
||||
|
||||
if(!bufwasdelwri) {
|
||||
/*
|
||||
|
@ -3264,7 +3264,7 @@ xfs_iflush_int(
|
|||
SPLDECL(s);
|
||||
|
||||
ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
|
||||
ASSERT(valusema(&ip->i_flock) <= 0);
|
||||
ASSERT(issemalocked(&(ip->i_flock)));
|
||||
ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
|
||||
ip->i_d.di_nextents > ip->i_df.if_ext_max);
|
||||
|
||||
|
@ -3504,7 +3504,7 @@ xfs_iflush_all(
|
|||
xfs_mount_t *mp)
|
||||
{
|
||||
xfs_inode_t *ip;
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
|
||||
again:
|
||||
XFS_MOUNT_ILOCK(mp);
|
||||
|
@ -4180,7 +4180,7 @@ xfs_iext_direct_to_inline(
|
|||
*/
|
||||
memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
|
||||
nextents * sizeof(xfs_bmbt_rec_t));
|
||||
kmem_free(ifp->if_u1.if_extents, KM_SLEEP);
|
||||
kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
|
||||
ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
|
||||
ifp->if_real_bytes = 0;
|
||||
}
|
||||
|
|
|
@ -102,9 +102,9 @@ typedef struct xfs_ifork {
|
|||
|
||||
#ifdef __KERNEL__
|
||||
struct bhv_desc;
|
||||
struct bhv_vnode;
|
||||
struct cred;
|
||||
struct ktrace;
|
||||
struct vnode;
|
||||
struct xfs_buf;
|
||||
struct xfs_bmap_free;
|
||||
struct xfs_bmbt_irec;
|
||||
|
@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *);
|
|||
void xfs_chash_free(struct xfs_mount *);
|
||||
xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
|
||||
struct xfs_trans *);
|
||||
void xfs_inode_lock_init(xfs_inode_t *, struct vnode *);
|
||||
void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *);
|
||||
int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
|
||||
uint, uint, xfs_inode_t **, xfs_daddr_t);
|
||||
void xfs_iput(xfs_inode_t *, uint);
|
||||
|
@ -461,7 +461,7 @@ void xfs_ichgtime(xfs_inode_t *, int);
|
|||
xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
|
||||
void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
|
||||
|
||||
xfs_inode_t *xfs_vtoi(struct vnode *vp);
|
||||
xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp);
|
||||
|
||||
void xfs_synchronize_atime(xfs_inode_t *);
|
||||
|
||||
|
@ -509,7 +509,6 @@ extern struct kmem_zone *xfs_chashlist_zone;
|
|||
extern struct kmem_zone *xfs_ifork_zone;
|
||||
extern struct kmem_zone *xfs_inode_zone;
|
||||
extern struct kmem_zone *xfs_ili_zone;
|
||||
extern struct vnodeops xfs_vnodeops;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "xfs_buf_item.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
@ -33,7 +32,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -794,7 +792,7 @@ xfs_inode_item_pushbuf(
|
|||
* inode flush completed and the inode was taken off the AIL.
|
||||
* So, just get out.
|
||||
*/
|
||||
if ((valusema(&(ip->i_flock)) > 0) ||
|
||||
if (!issemalocked(&(ip->i_flock)) ||
|
||||
((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
|
||||
iip->ili_pushbuf_flag = 0;
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
|
@ -816,7 +814,7 @@ xfs_inode_item_pushbuf(
|
|||
* If not, we can flush it async.
|
||||
*/
|
||||
dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
|
||||
(valusema(&(ip->i_flock)) <= 0));
|
||||
issemalocked(&(ip->i_flock)));
|
||||
iip->ili_pushbuf_flag = 0;
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
xfs_buftrace("INODE ITEM PUSH", bp);
|
||||
|
@ -864,7 +862,7 @@ xfs_inode_item_push(
|
|||
ip = iip->ili_inode;
|
||||
|
||||
ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS));
|
||||
ASSERT(valusema(&(ip->i_flock)) <= 0);
|
||||
ASSERT(issemalocked(&(ip->i_flock)));
|
||||
/*
|
||||
* Since we were able to lock the inode's flush lock and
|
||||
* we found it on the AIL, the inode must be dirty. This
|
||||
|
@ -1084,3 +1082,52 @@ xfs_istale_done(
|
|||
{
|
||||
xfs_iflush_abort(iip->ili_inode);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert an xfs_inode_log_format struct from either 32 or 64 bit versions
|
||||
* (which can have different field alignments) to the native version
|
||||
*/
|
||||
int
|
||||
xfs_inode_item_format_convert(
|
||||
xfs_log_iovec_t *buf,
|
||||
xfs_inode_log_format_t *in_f)
|
||||
{
|
||||
if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
|
||||
xfs_inode_log_format_32_t *in_f32;
|
||||
|
||||
in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr;
|
||||
in_f->ilf_type = in_f32->ilf_type;
|
||||
in_f->ilf_size = in_f32->ilf_size;
|
||||
in_f->ilf_fields = in_f32->ilf_fields;
|
||||
in_f->ilf_asize = in_f32->ilf_asize;
|
||||
in_f->ilf_dsize = in_f32->ilf_dsize;
|
||||
in_f->ilf_ino = in_f32->ilf_ino;
|
||||
/* copy biggest field of ilf_u */
|
||||
memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
|
||||
in_f32->ilf_u.ilfu_uuid.__u_bits,
|
||||
sizeof(uuid_t));
|
||||
in_f->ilf_blkno = in_f32->ilf_blkno;
|
||||
in_f->ilf_len = in_f32->ilf_len;
|
||||
in_f->ilf_boffset = in_f32->ilf_boffset;
|
||||
return 0;
|
||||
} else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
|
||||
xfs_inode_log_format_64_t *in_f64;
|
||||
|
||||
in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr;
|
||||
in_f->ilf_type = in_f64->ilf_type;
|
||||
in_f->ilf_size = in_f64->ilf_size;
|
||||
in_f->ilf_fields = in_f64->ilf_fields;
|
||||
in_f->ilf_asize = in_f64->ilf_asize;
|
||||
in_f->ilf_dsize = in_f64->ilf_dsize;
|
||||
in_f->ilf_ino = in_f64->ilf_ino;
|
||||
/* copy biggest field of ilf_u */
|
||||
memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
|
||||
in_f64->ilf_u.ilfu_uuid.__u_bits,
|
||||
sizeof(uuid_t));
|
||||
in_f->ilf_blkno = in_f64->ilf_blkno;
|
||||
in_f->ilf_len = in_f64->ilf_len;
|
||||
in_f->ilf_boffset = in_f64->ilf_boffset;
|
||||
return 0;
|
||||
}
|
||||
return EFSCORRUPTED;
|
||||
}
|
||||
|
|
|
@ -23,25 +23,6 @@
|
|||
* log. The size of the inline data/extents/b-tree root to be logged
|
||||
* (if any) is indicated in the ilf_dsize field. Changes to this structure
|
||||
* must be added on to the end.
|
||||
*
|
||||
* Convention for naming inode log item versions : The current version
|
||||
* is always named XFS_LI_INODE. When an inode log item gets superseded,
|
||||
* add the latest version of IRIX that will generate logs with that item
|
||||
* to the version name.
|
||||
*
|
||||
* -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first
|
||||
* union (ilf_u) field. This was released with IRIX 5.3-XFS.
|
||||
* -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire
|
||||
* structure. This was released with IRIX 6.0.1-XFS and IRIX 6.1.
|
||||
* -Version 3 of this structure (XFS_LI_INODE) is the same as version 2
|
||||
* so a new structure definition wasn't necessary. However, we had
|
||||
* to add a new type because the inode cluster size changed from 4K
|
||||
* to 8K and the version number had to be rev'ved to keep older kernels
|
||||
* from trying to recover logs with the 8K buffers in them. The logging
|
||||
* code can handle recovery on different-sized clusters now so hopefully
|
||||
* this'll be the last time we need to change the inode log item just
|
||||
* for a change in the inode cluster size. This new version was
|
||||
* released with IRIX 6.2.
|
||||
*/
|
||||
typedef struct xfs_inode_log_format {
|
||||
unsigned short ilf_type; /* inode log item type */
|
||||
|
@ -59,18 +40,38 @@ typedef struct xfs_inode_log_format {
|
|||
int ilf_boffset; /* off of inode in buffer */
|
||||
} xfs_inode_log_format_t;
|
||||
|
||||
/* Initial version shipped with IRIX 5.3-XFS */
|
||||
typedef struct xfs_inode_log_format_v1 {
|
||||
unsigned short ilf_type; /* inode log item type */
|
||||
unsigned short ilf_size; /* size of this item */
|
||||
uint ilf_fields; /* flags for fields logged */
|
||||
uint ilf_dsize; /* size of data/ext/root */
|
||||
xfs_ino_t ilf_ino; /* inode number */
|
||||
typedef struct xfs_inode_log_format_32 {
|
||||
unsigned short ilf_type; /* 16: inode log item type */
|
||||
unsigned short ilf_size; /* 16: size of this item */
|
||||
uint ilf_fields; /* 32: flags for fields logged */
|
||||
ushort ilf_asize; /* 32: size of attr d/ext/root */
|
||||
ushort ilf_dsize; /* 32: size of data/ext/root */
|
||||
xfs_ino_t ilf_ino; /* 64: inode number */
|
||||
union {
|
||||
xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* mount point value */
|
||||
xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* 128: mount point value */
|
||||
} ilf_u;
|
||||
} xfs_inode_log_format_t_v1;
|
||||
__int64_t ilf_blkno; /* 64: blkno of inode buffer */
|
||||
int ilf_len; /* 32: len of inode buffer */
|
||||
int ilf_boffset; /* 32: off of inode in buffer */
|
||||
} __attribute__((packed)) xfs_inode_log_format_32_t;
|
||||
|
||||
typedef struct xfs_inode_log_format_64 {
|
||||
unsigned short ilf_type; /* 16: inode log item type */
|
||||
unsigned short ilf_size; /* 16: size of this item */
|
||||
uint ilf_fields; /* 32: flags for fields logged */
|
||||
ushort ilf_asize; /* 32: size of attr d/ext/root */
|
||||
ushort ilf_dsize; /* 32: size of data/ext/root */
|
||||
__uint32_t ilf_pad; /* 32: pad for 64 bit boundary */
|
||||
xfs_ino_t ilf_ino; /* 64: inode number */
|
||||
union {
|
||||
xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* 128: mount point value */
|
||||
} ilf_u;
|
||||
__int64_t ilf_blkno; /* 64: blkno of inode buffer */
|
||||
int ilf_len; /* 32: len of inode buffer */
|
||||
int ilf_boffset; /* 32: off of inode in buffer */
|
||||
} xfs_inode_log_format_64_t;
|
||||
|
||||
/*
|
||||
* Flags for xfs_trans_log_inode flags field.
|
||||
|
@ -172,6 +173,8 @@ extern void xfs_inode_item_destroy(struct xfs_inode *);
|
|||
extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
|
||||
extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
|
||||
extern void xfs_iflush_abort(struct xfs_inode *);
|
||||
extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
|
||||
xfs_inode_log_format_t *);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -24,14 +24,13 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dfrag.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -58,7 +57,7 @@ xfs_size_fn(
|
|||
|
||||
STATIC int
|
||||
xfs_ioinit(
|
||||
struct vfs *vfsp,
|
||||
struct bhv_vfs *vfsp,
|
||||
struct xfs_mount_args *mntargs,
|
||||
int flags)
|
||||
{
|
||||
|
@ -68,6 +67,7 @@ xfs_ioinit(
|
|||
xfs_ioops_t xfs_iocore_xfs = {
|
||||
.xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
|
||||
.xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
|
||||
.xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi,
|
||||
.xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
|
||||
.xfs_iomap_write_direct =
|
||||
(xfs_iomap_write_direct_t) xfs_iomap_write_direct,
|
||||
|
@ -84,6 +84,7 @@ xfs_ioops_t xfs_iocore_xfs = {
|
|||
.xfs_unlock = (xfs_unlk_t) xfs_iunlock,
|
||||
.xfs_size_func = (xfs_size_t) xfs_size_fn,
|
||||
.xfs_iodone = (xfs_iodone_t) fs_noerr,
|
||||
.xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents,
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_alloc.h"
|
||||
#include "xfs_dmapi.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -252,7 +250,7 @@ xfs_iomap(
|
|||
error = XFS_BMAPI(mp, NULL, io, offset_fsb,
|
||||
(xfs_filblks_t)(end_fsb - offset_fsb),
|
||||
bmapi_flags, NULL, 0, &imap,
|
||||
&nimaps, NULL);
|
||||
&nimaps, NULL, NULL);
|
||||
|
||||
if (error)
|
||||
goto out;
|
||||
|
@ -519,8 +517,8 @@ xfs_iomap_write_direct(
|
|||
*/
|
||||
XFS_BMAP_INIT(&free_list, &firstfsb);
|
||||
nimaps = 1;
|
||||
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
|
||||
bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list);
|
||||
error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
|
||||
&firstfsb, 0, &imap, &nimaps, &free_list, NULL);
|
||||
if (error)
|
||||
goto error0;
|
||||
|
||||
|
@ -610,8 +608,8 @@ xfs_iomap_eof_want_preallocate(
|
|||
while (count_fsb > 0) {
|
||||
imaps = nimaps;
|
||||
firstblock = NULLFSBLOCK;
|
||||
error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb,
|
||||
0, &firstblock, 0, imap, &imaps, NULL);
|
||||
error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
|
||||
&firstblock, 0, imap, &imaps, NULL, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
for (n = 0; n < imaps; n++) {
|
||||
|
@ -695,11 +693,11 @@ retry:
|
|||
|
||||
nimaps = XFS_WRITE_IMAPS;
|
||||
firstblock = NULLFSBLOCK;
|
||||
error = xfs_bmapi(NULL, ip, offset_fsb,
|
||||
error = XFS_BMAPI(mp, NULL, io, offset_fsb,
|
||||
(xfs_filblks_t)(last_fsb - offset_fsb),
|
||||
XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
|
||||
XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
|
||||
&nimaps, NULL);
|
||||
&nimaps, NULL, NULL);
|
||||
if (error && (error != ENOSPC))
|
||||
return XFS_ERROR(error);
|
||||
|
||||
|
@ -832,9 +830,9 @@ xfs_iomap_write_allocate(
|
|||
}
|
||||
|
||||
/* Go get the actual blocks */
|
||||
error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb,
|
||||
error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
|
||||
XFS_BMAPI_WRITE, &first_block, 1,
|
||||
imap, &nimaps, &free_list);
|
||||
imap, &nimaps, &free_list, NULL);
|
||||
if (error)
|
||||
goto trans_cancel;
|
||||
|
||||
|
@ -955,9 +953,9 @@ xfs_iomap_write_unwritten(
|
|||
*/
|
||||
XFS_BMAP_INIT(&free_list, &firstfsb);
|
||||
nimaps = 1;
|
||||
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
|
||||
error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
|
||||
XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
|
||||
1, &imap, &nimaps, &free_list);
|
||||
1, &imap, &nimaps, &free_list, NULL);
|
||||
if (error)
|
||||
goto error_on_bmapi_transaction;
|
||||
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -41,11 +39,6 @@
|
|||
#include "xfs_error.h"
|
||||
#include "xfs_btree.h"
|
||||
|
||||
#ifndef HAVE_USERACC
|
||||
#define useracc(ubuffer, size, flags, foo) (0)
|
||||
#define unuseracc(ubuffer, size, flags)
|
||||
#endif
|
||||
|
||||
STATIC int
|
||||
xfs_bulkstat_one_iget(
|
||||
xfs_mount_t *mp, /* mount point for filesystem */
|
||||
|
@ -56,7 +49,7 @@ xfs_bulkstat_one_iget(
|
|||
{
|
||||
xfs_dinode_core_t *dic; /* dinode core info pointer */
|
||||
xfs_inode_t *ip; /* incore inode pointer */
|
||||
vnode_t *vp;
|
||||
bhv_vnode_t *vp;
|
||||
int error;
|
||||
|
||||
error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
|
||||
|
@ -335,15 +328,6 @@ xfs_bulkstat(
|
|||
(XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
|
||||
nimask = ~(nicluster - 1);
|
||||
nbcluster = nicluster >> mp->m_sb.sb_inopblog;
|
||||
/*
|
||||
* Lock down the user's buffer. If a buffer was not sent, as in the case
|
||||
* disk quota code calls here, we skip this.
|
||||
*/
|
||||
if (ubuffer &&
|
||||
(error = useracc(ubuffer, ubcount * statstruct_size,
|
||||
(B_READ|B_PHYS), NULL))) {
|
||||
return error;
|
||||
}
|
||||
/*
|
||||
* Allocate a page-sized buffer for inode btree records.
|
||||
* We could try allocating something smaller, but for normal
|
||||
|
@ -650,8 +634,6 @@ xfs_bulkstat(
|
|||
* Done, we're either out of filesystem or space to put the data.
|
||||
*/
|
||||
kmem_free(irbuf, NBPC);
|
||||
if (ubuffer)
|
||||
unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
|
||||
*ubcountp = ubelem;
|
||||
if (agno >= mp->m_sb.sb_agcount) {
|
||||
/*
|
||||
|
|
|
@ -45,7 +45,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
|
|||
*/
|
||||
#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
|
||||
#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
|
||||
#define BULKSTAT_FG_VFSLOCKED 0x4 /* Already have vfs lock */
|
||||
|
||||
/*
|
||||
* Return stat information in bulk (by-inode) for the filesystem.
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
@ -36,7 +35,6 @@
|
|||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_log_recover.h"
|
||||
#include "xfs_trans_priv.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -402,7 +400,7 @@ xfs_log_release_iclog(xfs_mount_t *mp,
|
|||
xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
|
||||
|
||||
if (xlog_state_release_iclog(log, iclog)) {
|
||||
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
|
@ -498,9 +496,8 @@ xfs_log_mount(xfs_mount_t *mp,
|
|||
* just worked.
|
||||
*/
|
||||
if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
|
||||
int error;
|
||||
vfs_t *vfsp = XFS_MTOVFS(mp);
|
||||
int readonly = (vfsp->vfs_flag & VFS_RDONLY);
|
||||
bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
|
||||
int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
|
||||
|
||||
if (readonly)
|
||||
vfsp->vfs_flag &= ~VFS_RDONLY;
|
||||
|
@ -726,7 +723,7 @@ xfs_log_write(xfs_mount_t * mp,
|
|||
return XFS_ERROR(EIO);
|
||||
|
||||
if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
|
||||
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
|
||||
}
|
||||
return error;
|
||||
} /* xfs_log_write */
|
||||
|
@ -816,9 +813,9 @@ xfs_log_need_covered(xfs_mount_t *mp)
|
|||
SPLDECL(s);
|
||||
int needed = 0, gen;
|
||||
xlog_t *log = mp->m_log;
|
||||
vfs_t *vfsp = XFS_MTOVFS(mp);
|
||||
bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
|
||||
|
||||
if (fs_frozen(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
|
||||
if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
|
||||
(vfsp->vfs_flag & VFS_RDONLY))
|
||||
return 0;
|
||||
|
||||
|
@ -956,7 +953,7 @@ xlog_iodone(xfs_buf_t *bp)
|
|||
XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
|
||||
xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
|
||||
XFS_BUF_STALE(bp);
|
||||
xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR);
|
||||
xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR);
|
||||
/*
|
||||
* This flag will be propagated to the trans-committed
|
||||
* callback routines to let them know that the log-commit
|
||||
|
@ -1261,7 +1258,7 @@ xlog_commit_record(xfs_mount_t *mp,
|
|||
ASSERT_ALWAYS(iclog);
|
||||
if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
|
||||
iclog, XLOG_COMMIT_TRANS))) {
|
||||
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
|
||||
}
|
||||
return error;
|
||||
} /* xlog_commit_record */
|
||||
|
@ -1790,7 +1787,7 @@ xlog_write(xfs_mount_t * mp,
|
|||
xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
|
||||
"xfs_log_write: reservation ran out. Need to up reservation");
|
||||
/* If we did not panic, shutdown the filesystem */
|
||||
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
|
||||
#endif
|
||||
} else
|
||||
ticket->t_curr_res -= len;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -24,7 +24,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
@ -32,7 +31,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -193,14 +191,14 @@ xlog_header_check_dump(
|
|||
{
|
||||
int b;
|
||||
|
||||
printk("%s: SB : uuid = ", __FUNCTION__);
|
||||
cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__);
|
||||
for (b = 0; b < 16; b++)
|
||||
printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]);
|
||||
printk(", fmt = %d\n", XLOG_FMT);
|
||||
printk(" log : uuid = ");
|
||||
cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
|
||||
cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
|
||||
cmn_err(CE_DEBUG, " log : uuid = ");
|
||||
for (b = 0; b < 16; b++)
|
||||
printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]);
|
||||
printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
|
||||
cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
|
||||
cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
|
||||
}
|
||||
#else
|
||||
#define xlog_header_check_dump(mp, head)
|
||||
|
@ -282,7 +280,7 @@ xlog_recover_iodone(
|
|||
mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
|
||||
xfs_ioerror_alert("xlog_recover_iodone",
|
||||
mp, bp, XFS_BUF_ADDR(bp));
|
||||
xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
|
||||
}
|
||||
XFS_BUF_SET_FSPRIVATE(bp, NULL);
|
||||
XFS_BUF_CLR_IODONE_FUNC(bp);
|
||||
|
@ -1889,7 +1887,7 @@ xlog_recover_do_inode_buffer(
|
|||
|
||||
buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
|
||||
next_unlinked_offset);
|
||||
INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp);
|
||||
*buffer_nextp = *logged_nextp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2292,12 +2290,22 @@ xlog_recover_do_inode_trans(
|
|||
int attr_index;
|
||||
uint fields;
|
||||
xfs_dinode_core_t *dicp;
|
||||
int need_free = 0;
|
||||
|
||||
if (pass == XLOG_RECOVER_PASS1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
|
||||
in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
|
||||
} else {
|
||||
in_f = (xfs_inode_log_format_t *)kmem_alloc(
|
||||
sizeof(xfs_inode_log_format_t), KM_SLEEP);
|
||||
need_free = 1;
|
||||
error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
|
||||
if (error)
|
||||
goto error;
|
||||
}
|
||||
ino = in_f->ilf_ino;
|
||||
mp = log->l_mp;
|
||||
if (ITEM_TYPE(item) == XFS_LI_INODE) {
|
||||
|
@ -2323,8 +2331,10 @@ xlog_recover_do_inode_trans(
|
|||
* Inode buffers can be freed, look out for it,
|
||||
* and do not replay the inode.
|
||||
*/
|
||||
if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0))
|
||||
return 0;
|
||||
if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) {
|
||||
error = 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
|
||||
XFS_BUF_LOCK);
|
||||
|
@ -2333,7 +2343,7 @@ xlog_recover_do_inode_trans(
|
|||
bp, imap.im_blkno);
|
||||
error = XFS_BUF_GETERROR(bp);
|
||||
xfs_buf_relse(bp);
|
||||
return error;
|
||||
goto error;
|
||||
}
|
||||
error = 0;
|
||||
ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
|
||||
|
@ -2350,7 +2360,8 @@ xlog_recover_do_inode_trans(
|
|||
dip, bp, ino);
|
||||
XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
error = EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
|
||||
if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
|
||||
|
@ -2360,7 +2371,8 @@ xlog_recover_do_inode_trans(
|
|||
item, ino);
|
||||
XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
error = EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Skip replay when the on disk inode is newer than the log one */
|
||||
|
@ -2376,7 +2388,8 @@ xlog_recover_do_inode_trans(
|
|||
/* do nothing */
|
||||
} else {
|
||||
xfs_buf_relse(bp);
|
||||
return 0;
|
||||
error = 0;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* Take the opportunity to reset the flush iteration count */
|
||||
|
@ -2391,7 +2404,8 @@ xlog_recover_do_inode_trans(
|
|||
xfs_fs_cmn_err(CE_ALERT, mp,
|
||||
"xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
|
||||
item, dip, bp, ino);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
error = EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
} else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) {
|
||||
if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
|
||||
|
@ -2403,7 +2417,8 @@ xlog_recover_do_inode_trans(
|
|||
xfs_fs_cmn_err(CE_ALERT, mp,
|
||||
"xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
|
||||
item, dip, bp, ino);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
error = EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
|
||||
|
@ -2415,7 +2430,8 @@ xlog_recover_do_inode_trans(
|
|||
item, dip, bp, ino,
|
||||
dicp->di_nextents + dicp->di_anextents,
|
||||
dicp->di_nblocks);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
error = EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
|
||||
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
|
||||
|
@ -2424,7 +2440,8 @@ xlog_recover_do_inode_trans(
|
|||
xfs_fs_cmn_err(CE_ALERT, mp,
|
||||
"xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
|
||||
item, dip, bp, ino, dicp->di_forkoff);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
error = EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
|
||||
XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
|
||||
|
@ -2433,7 +2450,8 @@ xlog_recover_do_inode_trans(
|
|||
xfs_fs_cmn_err(CE_ALERT, mp,
|
||||
"xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
|
||||
item->ri_buf[1].i_len, item);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
error = EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* The core is in in-core format */
|
||||
|
@ -2521,7 +2539,8 @@ xlog_recover_do_inode_trans(
|
|||
xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
|
||||
ASSERT(0);
|
||||
xfs_buf_relse(bp);
|
||||
return XFS_ERROR(EIO);
|
||||
error = EIO;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2537,7 +2556,10 @@ write_inode_buffer:
|
|||
error = xfs_bwrite(mp, bp);
|
||||
}
|
||||
|
||||
return (error);
|
||||
error:
|
||||
if (need_free)
|
||||
kmem_free(in_f, sizeof(*in_f));
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2674,32 +2696,32 @@ xlog_recover_do_dquot_trans(
|
|||
* structure into it, and adds the efi to the AIL with the given
|
||||
* LSN.
|
||||
*/
|
||||
STATIC void
|
||||
STATIC int
|
||||
xlog_recover_do_efi_trans(
|
||||
xlog_t *log,
|
||||
xlog_recover_item_t *item,
|
||||
xfs_lsn_t lsn,
|
||||
int pass)
|
||||
{
|
||||
int error;
|
||||
xfs_mount_t *mp;
|
||||
xfs_efi_log_item_t *efip;
|
||||
xfs_efi_log_format_t *efi_formatp;
|
||||
SPLDECL(s);
|
||||
|
||||
if (pass == XLOG_RECOVER_PASS1) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
|
||||
ASSERT(item->ri_buf[0].i_len ==
|
||||
(sizeof(xfs_efi_log_format_t) +
|
||||
((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))));
|
||||
|
||||
mp = log->l_mp;
|
||||
efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
|
||||
memcpy((char *)&(efip->efi_format), (char *)efi_formatp,
|
||||
sizeof(xfs_efi_log_format_t) +
|
||||
((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t)));
|
||||
if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
|
||||
&(efip->efi_format)))) {
|
||||
xfs_efi_item_free(efip);
|
||||
return error;
|
||||
}
|
||||
efip->efi_next_extent = efi_formatp->efi_nextents;
|
||||
efip->efi_flags |= XFS_EFI_COMMITTED;
|
||||
|
||||
|
@ -2708,6 +2730,7 @@ xlog_recover_do_efi_trans(
|
|||
* xfs_trans_update_ail() drops the AIL lock.
|
||||
*/
|
||||
xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2738,9 +2761,10 @@ xlog_recover_do_efd_trans(
|
|||
}
|
||||
|
||||
efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
|
||||
ASSERT(item->ri_buf[0].i_len ==
|
||||
(sizeof(xfs_efd_log_format_t) +
|
||||
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t))));
|
||||
ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
|
||||
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
|
||||
(item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
|
||||
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
|
||||
efi_id = efd_formatp->efd_efi_id;
|
||||
|
||||
/*
|
||||
|
@ -2810,15 +2834,14 @@ xlog_recover_do_trans(
|
|||
if ((error = xlog_recover_do_buffer_trans(log, item,
|
||||
pass)))
|
||||
break;
|
||||
} else if ((ITEM_TYPE(item) == XFS_LI_INODE) ||
|
||||
(ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
|
||||
(ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
|
||||
} else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
|
||||
if ((error = xlog_recover_do_inode_trans(log, item,
|
||||
pass)))
|
||||
break;
|
||||
} else if (ITEM_TYPE(item) == XFS_LI_EFI) {
|
||||
xlog_recover_do_efi_trans(log, item, trans->r_lsn,
|
||||
pass);
|
||||
if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
|
||||
pass)))
|
||||
break;
|
||||
} else if (ITEM_TYPE(item) == XFS_LI_EFD) {
|
||||
xlog_recover_do_efd_trans(log, item, pass);
|
||||
} else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
|
||||
|
@ -3419,13 +3442,13 @@ xlog_unpack_data_checksum(
|
|||
if (rhead->h_chksum ||
|
||||
((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
|
||||
cmn_err(CE_DEBUG,
|
||||
"XFS: LogR chksum mismatch: was (0x%x) is (0x%x)",
|
||||
"XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
|
||||
INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
|
||||
cmn_err(CE_DEBUG,
|
||||
"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
|
||||
if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
|
||||
cmn_err(CE_DEBUG,
|
||||
"XFS: LogR this is a LogV2 filesystem");
|
||||
"XFS: LogR this is a LogV2 filesystem\n");
|
||||
}
|
||||
log->l_flags |= XLOG_CHKSUM_MISMATCH;
|
||||
}
|
||||
|
@ -3798,7 +3821,7 @@ xlog_do_log_recovery(
|
|||
error = xlog_do_recovery_pass(log, head_blk, tail_blk,
|
||||
XLOG_RECOVER_PASS2);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
if (!error) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
|
||||
|
@ -3974,7 +3997,7 @@ xlog_recover_finish(
|
|||
log->l_flags &= ~XLOG_RECOVERY_NEEDED;
|
||||
} else {
|
||||
cmn_err(CE_DEBUG,
|
||||
"!Ending clean XFS mount for filesystem: %s",
|
||||
"!Ending clean XFS mount for filesystem: %s\n",
|
||||
log->l_mp->m_fsname);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -196,7 +194,7 @@ xfs_mount_free(
|
|||
kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
|
||||
|
||||
if (remove_bhv) {
|
||||
struct vfs *vfsp = XFS_MTOVFS(mp);
|
||||
struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
|
||||
|
||||
bhv_remove_all_vfsops(vfsp, 0);
|
||||
VFS_REMOVEBHV(vfsp, &mp->m_bhv);
|
||||
|
@ -337,7 +335,7 @@ xfs_mount_validate_sb(
|
|||
|
||||
xfs_agnumber_t
|
||||
xfs_initialize_perag(
|
||||
struct vfs *vfs,
|
||||
bhv_vfs_t *vfs,
|
||||
xfs_mount_t *mp,
|
||||
xfs_agnumber_t agcount)
|
||||
{
|
||||
|
@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
|
|||
*/
|
||||
int
|
||||
xfs_mountfs(
|
||||
vfs_t *vfsp,
|
||||
bhv_vfs_t *vfsp,
|
||||
xfs_mount_t *mp,
|
||||
int mfsi_flags)
|
||||
{
|
||||
xfs_buf_t *bp;
|
||||
xfs_sb_t *sbp = &(mp->m_sb);
|
||||
xfs_inode_t *rip;
|
||||
vnode_t *rvp = NULL;
|
||||
bhv_vnode_t *rvp = NULL;
|
||||
int readio_log, writeio_log;
|
||||
xfs_daddr_t d;
|
||||
__uint64_t ret64;
|
||||
|
@ -934,18 +932,7 @@ xfs_mountfs(
|
|||
vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
|
||||
mp->m_dmevmask = 0; /* not persistent; set after each mount */
|
||||
|
||||
/*
|
||||
* Select the right directory manager.
|
||||
*/
|
||||
mp->m_dirops =
|
||||
XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
|
||||
xfsv2_dirops :
|
||||
xfsv1_dirops;
|
||||
|
||||
/*
|
||||
* Initialize directory manager's entries.
|
||||
*/
|
||||
XFS_DIR_MOUNT(mp);
|
||||
xfs_dir_mount(mp);
|
||||
|
||||
/*
|
||||
* Initialize the attribute manager's entries.
|
||||
|
@ -1006,8 +993,9 @@ xfs_mountfs(
|
|||
|
||||
if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
|
||||
cmn_err(CE_WARN, "XFS: corrupted root inode");
|
||||
prdev("Root inode %llu is not a directory",
|
||||
mp->m_ddev_targp, (unsigned long long)rip->i_ino);
|
||||
cmn_err(CE_WARN, "Device %s - root %llu is not a directory",
|
||||
XFS_BUFTARG_NAME(mp->m_ddev_targp),
|
||||
(unsigned long long)rip->i_ino);
|
||||
xfs_iunlock(rip, XFS_ILOCK_EXCL);
|
||||
XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
|
||||
mp);
|
||||
|
@ -1094,7 +1082,7 @@ xfs_mountfs(
|
|||
int
|
||||
xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
|
||||
{
|
||||
struct vfs *vfsp = XFS_MTOVFS(mp);
|
||||
struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
|
||||
#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
|
||||
int64_t fsid;
|
||||
#endif
|
||||
|
@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
|
|||
|
||||
xfs_trans_log_buf(tp, bp, first, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* In order to avoid ENOSPC-related deadlock caused by
|
||||
* out-of-order locking of AGF buffer (PV 947395), we place
|
||||
* constraints on the relationship among actual allocations for
|
||||
* data blocks, freelist blocks, and potential file data bmap
|
||||
* btree blocks. However, these restrictions may result in no
|
||||
* actual space allocated for a delayed extent, for example, a data
|
||||
* block in a certain AG is allocated but there is no additional
|
||||
* block for the additional bmap btree block due to a split of the
|
||||
* bmap btree of the file. The result of this may lead to an
|
||||
* infinite loop in xfssyncd when the file gets flushed to disk and
|
||||
* all delayed extents need to be actually allocated. To get around
|
||||
* this, we explicitly set aside a few blocks which will not be
|
||||
* reserved in delayed allocation. Considering the minimum number of
|
||||
* needed freelist blocks is 4 fsbs, a potential split of file's bmap
|
||||
* btree requires 1 fsb, so we set the number of set-aside blocks to 8.
|
||||
*/
|
||||
#define SET_ASIDE_BLOCKS 8
|
||||
|
||||
/*
|
||||
* xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
|
||||
* a delta to a specified field in the in-core superblock. Simply
|
||||
|
@ -1298,7 +1306,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
|
|||
return 0;
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
|
||||
lcounter = (long long)mp->m_sb.sb_fdblocks;
|
||||
lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS;
|
||||
res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
|
||||
|
||||
if (delta > 0) { /* Putting blocks back */
|
||||
|
@ -1332,7 +1340,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
|
|||
}
|
||||
}
|
||||
|
||||
mp->m_sb.sb_fdblocks = lcounter;
|
||||
mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS;
|
||||
return 0;
|
||||
case XFS_SBS_FREXTENTS:
|
||||
lcounter = (long long)mp->m_sb.sb_frextents;
|
||||
|
|
|
@ -53,8 +53,8 @@ typedef struct xfs_trans_reservations {
|
|||
#else
|
||||
struct cred;
|
||||
struct log;
|
||||
struct vfs;
|
||||
struct vnode;
|
||||
struct bhv_vfs;
|
||||
struct bhv_vnode;
|
||||
struct xfs_mount_args;
|
||||
struct xfs_ihash;
|
||||
struct xfs_chash;
|
||||
|
@ -63,9 +63,11 @@ struct xfs_perag;
|
|||
struct xfs_iocore;
|
||||
struct xfs_bmbt_irec;
|
||||
struct xfs_bmap_free;
|
||||
struct xfs_extdelta;
|
||||
struct xfs_swapext;
|
||||
|
||||
extern struct vfsops xfs_vfsops;
|
||||
extern struct vnodeops xfs_vnodeops;
|
||||
extern struct bhv_vfsops xfs_vfsops;
|
||||
extern struct bhv_vnodeops xfs_vnodeops;
|
||||
|
||||
#define AIL_LOCK_T lock_t
|
||||
#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
|
||||
|
@ -78,15 +80,15 @@ extern struct vnodeops xfs_vnodeops;
|
|||
* Prototypes and functions for the Data Migration subsystem.
|
||||
*/
|
||||
|
||||
typedef int (*xfs_send_data_t)(int, struct vnode *,
|
||||
xfs_off_t, size_t, int, vrwlock_t *);
|
||||
typedef int (*xfs_send_data_t)(int, struct bhv_vnode *,
|
||||
xfs_off_t, size_t, int, bhv_vrwlock_t *);
|
||||
typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
|
||||
typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t);
|
||||
typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *,
|
||||
struct vnode *,
|
||||
dm_right_t, struct vnode *, dm_right_t,
|
||||
typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t);
|
||||
typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *,
|
||||
struct bhv_vnode *,
|
||||
dm_right_t, struct bhv_vnode *, dm_right_t,
|
||||
char *, char *, mode_t, int, int);
|
||||
typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *,
|
||||
typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *,
|
||||
dm_right_t, mode_t, int, int);
|
||||
|
||||
typedef struct xfs_dmops {
|
||||
|
@ -188,13 +190,18 @@ typedef struct xfs_qmops {
|
|||
* Prototypes and functions for I/O core modularization.
|
||||
*/
|
||||
|
||||
typedef int (*xfs_ioinit_t)(struct vfs *,
|
||||
typedef int (*xfs_ioinit_t)(struct bhv_vfs *,
|
||||
struct xfs_mount_args *, int);
|
||||
typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
|
||||
xfs_fileoff_t, xfs_filblks_t, int,
|
||||
xfs_fsblock_t *, xfs_extlen_t,
|
||||
struct xfs_bmbt_irec *, int *,
|
||||
struct xfs_bmap_free *);
|
||||
struct xfs_bmap_free *, struct xfs_extdelta *);
|
||||
typedef int (*xfs_bunmapi_t)(struct xfs_trans *,
|
||||
void *, xfs_fileoff_t,
|
||||
xfs_filblks_t, int, xfs_extnum_t,
|
||||
xfs_fsblock_t *, struct xfs_bmap_free *,
|
||||
struct xfs_extdelta *, int *);
|
||||
typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
|
||||
typedef int (*xfs_iomap_write_direct_t)(
|
||||
void *, xfs_off_t, size_t, int,
|
||||
|
@ -213,11 +220,14 @@ typedef void (*xfs_lock_demote_t)(void *, uint);
|
|||
typedef int (*xfs_lock_nowait_t)(void *, uint);
|
||||
typedef void (*xfs_unlk_t)(void *, unsigned int);
|
||||
typedef xfs_fsize_t (*xfs_size_t)(void *);
|
||||
typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *);
|
||||
typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *);
|
||||
typedef int (*xfs_swap_extents_t)(void *, void *,
|
||||
struct xfs_swapext*);
|
||||
|
||||
typedef struct xfs_ioops {
|
||||
xfs_ioinit_t xfs_ioinit;
|
||||
xfs_bmapi_t xfs_bmapi_func;
|
||||
xfs_bunmapi_t xfs_bunmapi_func;
|
||||
xfs_bmap_eof_t xfs_bmap_eof_func;
|
||||
xfs_iomap_write_direct_t xfs_iomap_write_direct;
|
||||
xfs_iomap_write_delay_t xfs_iomap_write_delay;
|
||||
|
@ -230,13 +240,17 @@ typedef struct xfs_ioops {
|
|||
xfs_unlk_t xfs_unlock;
|
||||
xfs_size_t xfs_size_func;
|
||||
xfs_iodone_t xfs_iodone;
|
||||
xfs_swap_extents_t xfs_swap_extents_func;
|
||||
} xfs_ioops_t;
|
||||
|
||||
#define XFS_IOINIT(vfsp, args, flags) \
|
||||
(*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
|
||||
#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \
|
||||
#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
|
||||
(*(mp)->m_io_ops.xfs_bmapi_func) \
|
||||
(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist)
|
||||
(trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
|
||||
#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \
|
||||
(*(mp)->m_io_ops.xfs_bunmapi_func) \
|
||||
(trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)
|
||||
#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
|
||||
(*(mp)->m_io_ops.xfs_bmap_eof_func) \
|
||||
((io)->io_obj, endoff, whichfork, eof)
|
||||
|
@ -266,6 +280,9 @@ typedef struct xfs_ioops {
|
|||
(*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
|
||||
#define XFS_IODONE(vfsp) \
|
||||
(*(mp)->m_io_ops.xfs_iodone)(vfsp)
|
||||
#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
|
||||
(*(mp)->m_io_ops.xfs_swap_extents_func) \
|
||||
((io)->io_obj, (tio)->io_obj, sxp)
|
||||
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
|
||||
|
@ -386,8 +403,6 @@ typedef struct xfs_mount {
|
|||
__uint8_t m_inode_quiesce;/* call quiesce on new inodes.
|
||||
field governed by m_ilock */
|
||||
__uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
|
||||
__uint8_t m_dirversion; /* 1 or 2 */
|
||||
xfs_dirops_t m_dirops; /* table of dir funcs */
|
||||
int m_dirblksize; /* directory block sz--bytes */
|
||||
int m_dirblkfsbs; /* directory block sz--fsbs */
|
||||
xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
|
||||
|
@ -494,16 +509,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
|
|||
|
||||
#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
|
||||
#define xfs_force_shutdown(m,f) \
|
||||
VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
|
||||
|
||||
/*
|
||||
* Flags sent to xfs_force_shutdown.
|
||||
*/
|
||||
#define XFS_METADATA_IO_ERROR 0x1
|
||||
#define XFS_LOG_IO_ERROR 0x2
|
||||
#define XFS_FORCE_UMOUNT 0x4
|
||||
#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
|
||||
#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
|
||||
bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
|
||||
|
||||
/*
|
||||
* Flags for xfs_mountfs
|
||||
|
@ -521,7 +527,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
|
|||
* Macros for getting from mount to vfs and back.
|
||||
*/
|
||||
#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
|
||||
static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp)
|
||||
static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp)
|
||||
{
|
||||
return bhvtovfs(&mp->m_bhv);
|
||||
}
|
||||
|
@ -533,7 +539,7 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
|
|||
}
|
||||
|
||||
#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
|
||||
static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs)
|
||||
static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
|
||||
{
|
||||
return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
|
||||
}
|
||||
|
@ -571,7 +577,7 @@ typedef struct xfs_mod_sb {
|
|||
extern xfs_mount_t *xfs_mount_init(void);
|
||||
extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
|
||||
extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
|
||||
extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
|
||||
extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int);
|
||||
extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
|
||||
|
||||
extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
|
||||
|
@ -589,7 +595,7 @@ extern void xfs_freesb(xfs_mount_t *);
|
|||
extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
|
||||
extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
|
||||
extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *);
|
||||
extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *,
|
||||
extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *,
|
||||
xfs_agnumber_t);
|
||||
extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
|
|
@ -365,7 +365,7 @@ typedef struct xfs_dqtrxops {
|
|||
extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
|
||||
extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
|
||||
|
||||
extern struct bhv_vfsops xfs_qmops;
|
||||
extern struct bhv_module_vfsops xfs_qmops;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -22,13 +22,11 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -40,7 +38,6 @@
|
|||
#include "xfs_refcache.h"
|
||||
#include "xfs_utils.h"
|
||||
#include "xfs_trans_space.h"
|
||||
#include "xfs_dir_leaf.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -87,8 +84,8 @@ STATIC int
|
|||
xfs_lock_for_rename(
|
||||
xfs_inode_t *dp1, /* old (source) directory inode */
|
||||
xfs_inode_t *dp2, /* new (target) directory inode */
|
||||
vname_t *vname1,/* old entry name */
|
||||
vname_t *vname2,/* new entry name */
|
||||
bhv_vname_t *vname1,/* old entry name */
|
||||
bhv_vname_t *vname2,/* new entry name */
|
||||
xfs_inode_t **ipp1, /* inode of old entry */
|
||||
xfs_inode_t **ipp2, /* inode of new entry, if it
|
||||
already exists, NULL otherwise. */
|
||||
|
@ -225,9 +222,9 @@ xfs_lock_for_rename(
|
|||
int
|
||||
xfs_rename(
|
||||
bhv_desc_t *src_dir_bdp,
|
||||
vname_t *src_vname,
|
||||
vnode_t *target_dir_vp,
|
||||
vname_t *target_vname,
|
||||
bhv_vname_t *src_vname,
|
||||
bhv_vnode_t *target_dir_vp,
|
||||
bhv_vname_t *target_vname,
|
||||
cred_t *credp)
|
||||
{
|
||||
xfs_trans_t *tp;
|
||||
|
@ -242,7 +239,7 @@ xfs_rename(
|
|||
int committed;
|
||||
xfs_inode_t *inodes[4];
|
||||
int target_ip_dropped = 0; /* dropped target_ip link? */
|
||||
vnode_t *src_dir_vp;
|
||||
bhv_vnode_t *src_dir_vp;
|
||||
int spaceres;
|
||||
int target_link_zero = 0;
|
||||
int num_inodes;
|
||||
|
@ -398,34 +395,29 @@ xfs_rename(
|
|||
* fit before actually inserting it.
|
||||
*/
|
||||
if (spaceres == 0 &&
|
||||
(error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name,
|
||||
target_namelen))) {
|
||||
(error = xfs_dir_canenter(tp, target_dp, target_name,
|
||||
target_namelen)))
|
||||
goto error_return;
|
||||
}
|
||||
/*
|
||||
* If target does not exist and the rename crosses
|
||||
* directories, adjust the target directory link count
|
||||
* to account for the ".." reference from the new entry.
|
||||
*/
|
||||
error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name,
|
||||
error = xfs_dir_createname(tp, target_dp, target_name,
|
||||
target_namelen, src_ip->i_ino,
|
||||
&first_block, &free_list, spaceres);
|
||||
if (error == ENOSPC) {
|
||||
if (error == ENOSPC)
|
||||
goto error_return;
|
||||
}
|
||||
if (error) {
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
|
||||
|
||||
if (new_parent && src_is_directory) {
|
||||
error = xfs_bumplink(tp, target_dp);
|
||||
if (error) {
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
}
|
||||
} else { /* target_ip != NULL */
|
||||
|
||||
/*
|
||||
* If target exists and it's a directory, check that both
|
||||
* target and source are directories and that target can be
|
||||
|
@ -435,7 +427,7 @@ xfs_rename(
|
|||
/*
|
||||
* Make sure target dir is empty.
|
||||
*/
|
||||
if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) ||
|
||||
if (!(xfs_dir_isempty(target_ip)) ||
|
||||
(target_ip->i_d.di_nlink > 2)) {
|
||||
error = XFS_ERROR(EEXIST);
|
||||
goto error_return;
|
||||
|
@ -451,12 +443,11 @@ xfs_rename(
|
|||
* In case there is already an entry with the same
|
||||
* name at the destination directory, remove it first.
|
||||
*/
|
||||
error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name,
|
||||
target_namelen, src_ip->i_ino, &first_block,
|
||||
&free_list, spaceres);
|
||||
if (error) {
|
||||
error = xfs_dir_replace(tp, target_dp, target_name,
|
||||
target_namelen, src_ip->i_ino,
|
||||
&first_block, &free_list, spaceres);
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
|
||||
|
||||
/*
|
||||
|
@ -464,9 +455,8 @@ xfs_rename(
|
|||
* dir no longer points to it.
|
||||
*/
|
||||
error = xfs_droplink(tp, target_ip);
|
||||
if (error) {
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
target_ip_dropped = 1;
|
||||
|
||||
if (src_is_directory) {
|
||||
|
@ -474,10 +464,9 @@ xfs_rename(
|
|||
* Drop the link from the old "." entry.
|
||||
*/
|
||||
error = xfs_droplink(tp, target_ip);
|
||||
if (error) {
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do this test while we still hold the locks */
|
||||
target_link_zero = (target_ip)->i_d.di_nlink==0;
|
||||
|
@ -488,18 +477,15 @@ xfs_rename(
|
|||
* Remove the source.
|
||||
*/
|
||||
if (new_parent && src_is_directory) {
|
||||
|
||||
/*
|
||||
* Rewrite the ".." entry to point to the new
|
||||
* directory.
|
||||
*/
|
||||
error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2,
|
||||
target_dp->i_ino, &first_block,
|
||||
&free_list, spaceres);
|
||||
error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino,
|
||||
&first_block, &free_list, spaceres);
|
||||
ASSERT(error != EEXIST);
|
||||
if (error) {
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
|
||||
|
||||
} else {
|
||||
|
@ -527,16 +513,14 @@ xfs_rename(
|
|||
* entry that's moved no longer points to it.
|
||||
*/
|
||||
error = xfs_droplink(tp, src_dp);
|
||||
if (error) {
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
}
|
||||
|
||||
error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen,
|
||||
error = xfs_dir_removename(tp, src_dp, src_name, src_namelen,
|
||||
src_ip->i_ino, &first_block, &free_list, spaceres);
|
||||
if (error) {
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
|
||||
|
||||
/*
|
||||
|
@ -609,7 +593,7 @@ xfs_rename(
|
|||
* Let interposed file systems know about removed links.
|
||||
*/
|
||||
if (target_ip_dropped) {
|
||||
VOP_LINK_REMOVED(XFS_ITOV(target_ip), target_dir_vp,
|
||||
bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
|
||||
target_link_zero);
|
||||
IRELE(target_ip);
|
||||
}
|
||||
|
|
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -141,7 +139,7 @@ xfs_growfs_rt_alloc(
|
|||
cancelflags |= XFS_TRANS_ABORT;
|
||||
error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
|
||||
XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
|
||||
resblks, &map, &nmap, &flist);
|
||||
resblks, &map, &nmap, &flist, NULL);
|
||||
if (!error && nmap < 1)
|
||||
error = XFS_ERROR(ENOSPC);
|
||||
if (error)
|
||||
|
@ -2404,10 +2402,10 @@ xfs_rtprint_range(
|
|||
{
|
||||
xfs_extlen_t i; /* block number in the extent */
|
||||
|
||||
printk("%Ld: ", (long long)start);
|
||||
cmn_err(CE_DEBUG, "%Ld: ", (long long)start);
|
||||
for (i = 0; i < len; i++)
|
||||
printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
|
||||
printk("\n");
|
||||
cmn_err(CE_DEBUG, "%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
|
||||
cmn_err(CE_DEBUG, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2431,17 +2429,17 @@ xfs_rtprint_summary(
|
|||
(void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c);
|
||||
if (c) {
|
||||
if (!p) {
|
||||
printk("%Ld-%Ld:", 1LL << l,
|
||||
cmn_err(CE_DEBUG, "%Ld-%Ld:", 1LL << l,
|
||||
XFS_RTMIN((1LL << l) +
|
||||
((1LL << l) - 1LL),
|
||||
mp->m_sb.sb_rextents));
|
||||
p = 1;
|
||||
}
|
||||
printk(" %Ld:%d", (long long)i, c);
|
||||
cmn_err(CE_DEBUG, " %Ld:%d", (long long)i, c);
|
||||
}
|
||||
}
|
||||
if (p)
|
||||
printk("\n");
|
||||
cmn_err(CE_DEBUG, "\n");
|
||||
}
|
||||
if (sumbp)
|
||||
xfs_trans_brelse(tp, sumbp);
|
||||
|
|
120
fs/xfs/xfs_rw.c
120
fs/xfs/xfs_rw.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -24,14 +24,12 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -91,6 +89,90 @@ xfs_write_clear_setuid(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle logging requirements of various synchronous types of write.
|
||||
*/
|
||||
int
|
||||
xfs_write_sync_logforce(
|
||||
xfs_mount_t *mp,
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* If we're treating this as O_DSYNC and we have not updated the
|
||||
* size, force the log.
|
||||
*/
|
||||
if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
|
||||
!(ip->i_update_size)) {
|
||||
xfs_inode_log_item_t *iip = ip->i_itemp;
|
||||
|
||||
/*
|
||||
* If an allocation transaction occurred
|
||||
* without extending the size, then we have to force
|
||||
* the log up the proper point to ensure that the
|
||||
* allocation is permanent. We can't count on
|
||||
* the fact that buffered writes lock out direct I/O
|
||||
* writes - the direct I/O write could have extended
|
||||
* the size nontransactionally, then finished before
|
||||
* we started. xfs_write_file will think that the file
|
||||
* didn't grow but the update isn't safe unless the
|
||||
* size change is logged.
|
||||
*
|
||||
* Force the log if we've committed a transaction
|
||||
* against the inode or if someone else has and
|
||||
* the commit record hasn't gone to disk (e.g.
|
||||
* the inode is pinned). This guarantees that
|
||||
* all changes affecting the inode are permanent
|
||||
* when we return.
|
||||
*/
|
||||
if (iip && iip->ili_last_lsn) {
|
||||
xfs_log_force(mp, iip->ili_last_lsn,
|
||||
XFS_LOG_FORCE | XFS_LOG_SYNC);
|
||||
} else if (xfs_ipincount(ip) > 0) {
|
||||
xfs_log_force(mp, (xfs_lsn_t)0,
|
||||
XFS_LOG_FORCE | XFS_LOG_SYNC);
|
||||
}
|
||||
|
||||
} else {
|
||||
xfs_trans_t *tp;
|
||||
|
||||
/*
|
||||
* O_SYNC or O_DSYNC _with_ a size update are handled
|
||||
* the same way.
|
||||
*
|
||||
* If the write was synchronous then we need to make
|
||||
* sure that the inode modification time is permanent.
|
||||
* We'll have updated the timestamp above, so here
|
||||
* we use a synchronous transaction to log the inode.
|
||||
* It's not fast, but it's necessary.
|
||||
*
|
||||
* If this a dsync write and the size got changed
|
||||
* non-transactionally, then we need to ensure that
|
||||
* the size change gets logged in a synchronous
|
||||
* transaction.
|
||||
*/
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
|
||||
if ((error = xfs_trans_reserve(tp, 0,
|
||||
XFS_SWRITE_LOG_RES(mp),
|
||||
0, 0, 0))) {
|
||||
/* Transaction reserve failed */
|
||||
xfs_trans_cancel(tp, 0);
|
||||
} else {
|
||||
/* Transaction reserve successful */
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ihold(tp, ip);
|
||||
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
|
||||
xfs_trans_set_sync(tp);
|
||||
error = xfs_trans_commit(tp, 0, NULL);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force a shutdown of the filesystem instantly while keeping
|
||||
* the filesystem consistent. We don't do an unmount here; just shutdown
|
||||
|
@ -109,12 +191,12 @@ xfs_do_force_shutdown(
|
|||
xfs_mount_t *mp;
|
||||
|
||||
mp = XFS_BHVTOM(bdp);
|
||||
logerror = flags & XFS_LOG_IO_ERROR;
|
||||
logerror = flags & SHUTDOWN_LOG_IO_ERROR;
|
||||
|
||||
if (!(flags & XFS_FORCE_UMOUNT)) {
|
||||
cmn_err(CE_NOTE,
|
||||
"xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p",
|
||||
mp->m_fsname,flags,lnnum,fname,__return_address);
|
||||
if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
|
||||
cmn_err(CE_NOTE, "xfs_force_shutdown(%s,0x%x) called from "
|
||||
"line %d of file %s. Return address = 0x%p",
|
||||
mp->m_fsname, flags, lnnum, fname, __return_address);
|
||||
}
|
||||
/*
|
||||
* No need to duplicate efforts.
|
||||
|
@ -125,33 +207,37 @@ xfs_do_force_shutdown(
|
|||
/*
|
||||
* This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
|
||||
* queue up anybody new on the log reservations, and wakes up
|
||||
* everybody who's sleeping on log reservations and tells
|
||||
* them the bad news.
|
||||
* everybody who's sleeping on log reservations to tell them
|
||||
* the bad news.
|
||||
*/
|
||||
if (xfs_log_force_umount(mp, logerror))
|
||||
return;
|
||||
|
||||
if (flags & XFS_CORRUPT_INCORE) {
|
||||
if (flags & SHUTDOWN_CORRUPT_INCORE) {
|
||||
xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
|
||||
"Corruption of in-memory data detected. Shutting down filesystem: %s",
|
||||
mp->m_fsname);
|
||||
if (XFS_ERRLEVEL_HIGH <= xfs_error_level) {
|
||||
xfs_stack_trace();
|
||||
}
|
||||
} else if (!(flags & XFS_FORCE_UMOUNT)) {
|
||||
} else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
|
||||
if (logerror) {
|
||||
xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp,
|
||||
"Log I/O Error Detected. Shutting down filesystem: %s",
|
||||
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,
|
||||
"All device paths lost. Shutting down filesystem: %s",
|
||||
mp->m_fsname);
|
||||
} else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
|
||||
xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
|
||||
"I/O Error Detected. Shutting down filesystem: %s",
|
||||
mp->m_fsname);
|
||||
}
|
||||
}
|
||||
if (!(flags & XFS_FORCE_UMOUNT)) {
|
||||
cmn_err(CE_ALERT,
|
||||
"Please umount the filesystem, and rectify the problem(s)");
|
||||
if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
|
||||
cmn_err(CE_ALERT, "Please umount the filesystem, "
|
||||
"and rectify the problem(s)");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,7 +421,7 @@ xfs_bwrite(
|
|||
* from bwrite and we could be tracing a buffer that has
|
||||
* been reused.
|
||||
*/
|
||||
xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -75,6 +75,7 @@ xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb)
|
|||
* Prototypes for functions in xfs_rw.c.
|
||||
*/
|
||||
extern int xfs_write_clear_setuid(struct xfs_inode *ip);
|
||||
extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);
|
||||
extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
|
||||
extern int xfs_bioerror(struct xfs_buf *bp);
|
||||
extern int xfs_bioerror_relse(struct xfs_buf *bp);
|
||||
|
@ -87,9 +88,10 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
|
|||
/*
|
||||
* Prototypes for functions in xfs_vnodeops.c.
|
||||
*/
|
||||
extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock);
|
||||
extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock);
|
||||
extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp);
|
||||
extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
|
||||
extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
|
||||
extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags,
|
||||
cred_t *credp);
|
||||
extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
|
||||
xfs_off_t offset, cred_t *credp, int flags);
|
||||
extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
|
@ -33,7 +32,6 @@
|
|||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_alloc_btree.h"
|
||||
#include "xfs_ialloc_btree.h"
|
||||
#include "xfs_dir_sf.h"
|
||||
#include "xfs_dir2_sf.h"
|
||||
#include "xfs_attr_sf.h"
|
||||
#include "xfs_dinode.h"
|
||||
|
@ -236,11 +234,8 @@ xfs_trans_alloc(
|
|||
xfs_mount_t *mp,
|
||||
uint type)
|
||||
{
|
||||
fs_check_frozen(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
|
||||
atomic_inc(&mp->m_active_trans);
|
||||
|
||||
return (_xfs_trans_alloc(mp, type));
|
||||
|
||||
vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
|
||||
return _xfs_trans_alloc(mp, type);
|
||||
}
|
||||
|
||||
xfs_trans_t *
|
||||
|
@ -250,12 +245,9 @@ _xfs_trans_alloc(
|
|||
{
|
||||
xfs_trans_t *tp;
|
||||
|
||||
ASSERT(xfs_trans_zone != NULL);
|
||||
tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
|
||||
atomic_inc(&mp->m_active_trans);
|
||||
|
||||
/*
|
||||
* Initialize the transaction structure.
|
||||
*/
|
||||
tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
|
||||
tp->t_magic = XFS_TRANS_MAGIC;
|
||||
tp->t_type = type;
|
||||
tp->t_mountp = mp;
|
||||
|
@ -263,8 +255,7 @@ _xfs_trans_alloc(
|
|||
tp->t_busy_free = XFS_LBC_NUM_SLOTS;
|
||||
XFS_LIC_INIT(&(tp->t_items));
|
||||
XFS_LBC_INIT(&(tp->t_busy));
|
||||
|
||||
return (tp);
|
||||
return tp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -303,7 +294,7 @@ xfs_trans_dup(
|
|||
tp->t_blk_res = tp->t_blk_res_used;
|
||||
ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
|
||||
tp->t_rtx_res = tp->t_rtx_res_used;
|
||||
PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags);
|
||||
ntp->t_pflags = tp->t_pflags;
|
||||
|
||||
XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
|
||||
|
||||
|
@ -335,14 +326,11 @@ xfs_trans_reserve(
|
|||
uint logcount)
|
||||
{
|
||||
int log_flags;
|
||||
int error;
|
||||
int rsvd;
|
||||
|
||||
error = 0;
|
||||
rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
|
||||
int error = 0;
|
||||
int rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
|
||||
|
||||
/* Mark this thread as being in a transaction */
|
||||
PFLAGS_SET_FSTRANS(&tp->t_pflags);
|
||||
current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
||||
|
||||
/*
|
||||
* Attempt to reserve the needed disk blocks by decrementing
|
||||
|
@ -353,7 +341,7 @@ xfs_trans_reserve(
|
|||
error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
|
||||
-blocks, rsvd);
|
||||
if (error != 0) {
|
||||
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
|
||||
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
||||
return (XFS_ERROR(ENOSPC));
|
||||
}
|
||||
tp->t_blk_res += blocks;
|
||||
|
@ -426,9 +414,9 @@ undo_blocks:
|
|||
tp->t_blk_res = 0;
|
||||
}
|
||||
|
||||
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
|
||||
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
||||
|
||||
return (error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
@ -819,7 +807,7 @@ shut_us_down:
|
|||
if (commit_lsn == -1 && !shutdown)
|
||||
shutdown = XFS_ERROR(EIO);
|
||||
}
|
||||
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
|
||||
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
||||
xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
|
||||
xfs_trans_free_busy(tp);
|
||||
xfs_trans_free(tp);
|
||||
|
@ -846,7 +834,7 @@ shut_us_down:
|
|||
*/
|
||||
nvec = xfs_trans_count_vecs(tp);
|
||||
if (nvec == 0) {
|
||||
xfs_force_shutdown(mp, XFS_LOG_IO_ERROR);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
|
||||
goto shut_us_down;
|
||||
} else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
|
||||
log_vector = log_vector_fast;
|
||||
|
@ -884,7 +872,7 @@ shut_us_down:
|
|||
* had pinned, clean up, free trans structure, and return error.
|
||||
*/
|
||||
if (error || commit_lsn == -1) {
|
||||
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
|
||||
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
||||
xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
|
||||
return XFS_ERROR(EIO);
|
||||
}
|
||||
|
@ -926,7 +914,7 @@ shut_us_down:
|
|||
/*
|
||||
* Mark this thread as no longer being in a transaction
|
||||
*/
|
||||
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
|
||||
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
||||
|
||||
/*
|
||||
* Once all the items of the transaction have been copied
|
||||
|
@ -1148,7 +1136,7 @@ xfs_trans_cancel(
|
|||
*/
|
||||
if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {
|
||||
XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
|
||||
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (!(flags & XFS_TRANS_ABORT)) {
|
||||
|
@ -1182,7 +1170,7 @@ xfs_trans_cancel(
|
|||
}
|
||||
|
||||
/* mark this thread as no longer being in a transaction */
|
||||
PFLAGS_RESTORE_FSTRANS(&tp->t_pflags);
|
||||
current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
|
||||
|
||||
xfs_trans_free_items(tp, flags);
|
||||
xfs_trans_free_busy(tp);
|
||||
|
|
|
@ -805,12 +805,9 @@ typedef struct xfs_trans {
|
|||
((mp)->m_sb.sb_inodesize + \
|
||||
(mp)->m_sb.sb_sectsize * 2 + \
|
||||
(mp)->m_dirblksize + \
|
||||
(XFS_DIR_IS_V1(mp) ? 0 : \
|
||||
XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \
|
||||
XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \
|
||||
XFS_ALLOCFREE_LOG_RES(mp, 1) + \
|
||||
(128 * (4 + \
|
||||
(XFS_DIR_IS_V1(mp) ? 0 : \
|
||||
XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
|
||||
(128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
|
||||
XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
|
||||
|
||||
#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "xfs_inum.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_dir.h"
|
||||
#include "xfs_dmapi.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_trans_priv.h"
|
||||
|
@ -363,9 +362,10 @@ xfs_trans_delete_ail(
|
|||
AIL_UNLOCK(mp, s);
|
||||
else {
|
||||
xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
|
||||
"xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL");
|
||||
"%s: attempting to delete a log item that is not in the AIL",
|
||||
__FUNCTION__);
|
||||
AIL_UNLOCK(mp, s);
|
||||
xfs_force_shutdown(mp, XFS_CORRUPT_INCORE);
|
||||
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue