Commit dcd7b4e5 authored by Niv Sardi's avatar Niv Sardi

Merge branch 'master' of git://oss.sgi.com:8090/xfs/linux-2.6

parents 75fa6770 91b77712
......@@ -229,10 +229,6 @@ The following sysctls are available for the XFS filesystem:
ISGID bit is cleared if the irix_sgid_inherit compatibility sysctl
is set.
fs.xfs.restrict_chown (Min: 0 Default: 1 Max: 1)
Controls whether unprivileged users can use chown to "give away"
a file to another user.
fs.xfs.inherit_sync (Min: 0 Default: 1 Max: 1)
Setting this to "1" will cause the "sync" flag set
by the xfs_io(8) chattr command on a directory to be
......
......@@ -108,84 +108,100 @@ static void wake_up_inode(struct inode *inode)
wake_up_bit(&inode->i_state, __I_LOCK);
}
static struct inode *alloc_inode(struct super_block *sb)
/**
* inode_init_always - perform inode structure intialisation
* @sb - superblock inode belongs to.
* @inode - inode to initialise
*
* These are initializations that need to be done on every inode
* allocation as the fields are not initialised by slab allocation.
*/
struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
{
static const struct address_space_operations empty_aops;
static struct inode_operations empty_iops;
static const struct file_operations empty_fops;
struct inode *inode;
if (sb->s_op->alloc_inode)
inode = sb->s_op->alloc_inode(sb);
else
inode = (struct inode *) kmem_cache_alloc(inode_cachep, GFP_KERNEL);
if (inode) {
struct address_space * const mapping = &inode->i_data;
inode->i_sb = sb;
inode->i_blkbits = sb->s_blocksize_bits;
inode->i_flags = 0;
atomic_set(&inode->i_count, 1);
inode->i_op = &empty_iops;
inode->i_fop = &empty_fops;
inode->i_nlink = 1;
atomic_set(&inode->i_writecount, 0);
inode->i_size = 0;
inode->i_blocks = 0;
inode->i_bytes = 0;
inode->i_generation = 0;
struct address_space * const mapping = &inode->i_data;
inode->i_sb = sb;
inode->i_blkbits = sb->s_blocksize_bits;
inode->i_flags = 0;
atomic_set(&inode->i_count, 1);
inode->i_op = &empty_iops;
inode->i_fop = &empty_fops;
inode->i_nlink = 1;
atomic_set(&inode->i_writecount, 0);
inode->i_size = 0;
inode->i_blocks = 0;
inode->i_bytes = 0;
inode->i_generation = 0;
#ifdef CONFIG_QUOTA
memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
#endif
inode->i_pipe = NULL;
inode->i_bdev = NULL;
inode->i_cdev = NULL;
inode->i_rdev = 0;
inode->dirtied_when = 0;
if (security_inode_alloc(inode)) {
if (inode->i_sb->s_op->destroy_inode)
inode->i_sb->s_op->destroy_inode(inode);
else
kmem_cache_free(inode_cachep, (inode));
return NULL;
}
inode->i_pipe = NULL;
inode->i_bdev = NULL;
inode->i_cdev = NULL;
inode->i_rdev = 0;
inode->dirtied_when = 0;
if (security_inode_alloc(inode)) {
if (inode->i_sb->s_op->destroy_inode)
inode->i_sb->s_op->destroy_inode(inode);
else
kmem_cache_free(inode_cachep, (inode));
return NULL;
}
spin_lock_init(&inode->i_lock);
lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
spin_lock_init(&inode->i_lock);
lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
mutex_init(&inode->i_mutex);
lockdep_set_class(&inode->i_mutex, &sb->s_type->i_mutex_key);
mutex_init(&inode->i_mutex);
lockdep_set_class(&inode->i_mutex, &sb->s_type->i_mutex_key);
init_rwsem(&inode->i_alloc_sem);
lockdep_set_class(&inode->i_alloc_sem, &sb->s_type->i_alloc_sem_key);
init_rwsem(&inode->i_alloc_sem);
lockdep_set_class(&inode->i_alloc_sem, &sb->s_type->i_alloc_sem_key);
mapping->a_ops = &empty_aops;
mapping->host = inode;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE);
mapping->assoc_mapping = NULL;
mapping->backing_dev_info = &default_backing_dev_info;
mapping->writeback_index = 0;
mapping->a_ops = &empty_aops;
mapping->host = inode;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE);
mapping->assoc_mapping = NULL;
mapping->backing_dev_info = &default_backing_dev_info;
mapping->writeback_index = 0;
/*
* If the block_device provides a backing_dev_info for client
* inodes then use that. Otherwise the inode share the bdev's
* backing_dev_info.
*/
if (sb->s_bdev) {
struct backing_dev_info *bdi;
/*
* If the block_device provides a backing_dev_info for client
* inodes then use that. Otherwise the inode share the bdev's
* backing_dev_info.
*/
if (sb->s_bdev) {
struct backing_dev_info *bdi;
bdi = sb->s_bdev->bd_inode_backing_dev_info;
if (!bdi)
bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
mapping->backing_dev_info = bdi;
}
inode->i_private = NULL;
inode->i_mapping = mapping;
bdi = sb->s_bdev->bd_inode_backing_dev_info;
if (!bdi)
bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
mapping->backing_dev_info = bdi;
}
inode->i_private = NULL;
inode->i_mapping = mapping;
return inode;
}
EXPORT_SYMBOL(inode_init_always);
static struct inode *alloc_inode(struct super_block *sb)
{
struct inode *inode;
if (sb->s_op->alloc_inode)
inode = sb->s_op->alloc_inode(sb);
else
inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL);
if (inode)
return inode_init_always(sb, inode);
return NULL;
}
void destroy_inode(struct inode *inode)
{
......@@ -196,6 +212,7 @@ void destroy_inode(struct inode *inode)
else
kmem_cache_free(inode_cachep, (inode));
}
EXPORT_SYMBOL(destroy_inode);
/*
......@@ -534,6 +551,49 @@ static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head
return node ? inode : NULL;
}
static unsigned long hash(struct super_block *sb, unsigned long hashval)
{
unsigned long tmp;
tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) /
L1_CACHE_BYTES;
tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS);
return tmp & I_HASHMASK;
}
static inline void
__inode_add_to_lists(struct super_block *sb, struct hlist_head *head,
struct inode *inode)
{
inodes_stat.nr_inodes++;
list_add(&inode->i_list, &inode_in_use);
list_add(&inode->i_sb_list, &sb->s_inodes);
if (head)
hlist_add_head(&inode->i_hash, head);
}
/**
* inode_add_to_lists - add a new inode to relevant lists
* @sb - superblock inode belongs to.
* @inode - inode to mark in use
*
* When an inode is allocated it needs to be accounted for, added to the in use
* list, the owning superblock and the inode hash. This needs to be done under
* the inode_lock, so export a function to do this rather than the inode lock
* itself. We calculate the hash list to add to here so it is all internal
* which requires the caller to have already set up the inode number in the
* inode to add.
*/
void inode_add_to_lists(struct super_block *sb, struct inode *inode)
{
struct hlist_head *head = inode_hashtable + hash(sb, inode->i_ino);
spin_lock(&inode_lock);
__inode_add_to_lists(sb, head, inode);
spin_unlock(&inode_lock);
}
EXPORT_SYMBOL_GPL(inode_add_to_lists);
/**
* new_inode - obtain an inode
* @sb: superblock
......@@ -561,9 +621,7 @@ struct inode *new_inode(struct super_block *sb)
inode = alloc_inode(sb);
if (inode) {
spin_lock(&inode_lock);
inodes_stat.nr_inodes++;
list_add(&inode->i_list, &inode_in_use);
list_add(&inode->i_sb_list, &sb->s_inodes);
__inode_add_to_lists(sb, NULL, inode);
inode->i_ino = ++last_ino;
inode->i_state = 0;
spin_unlock(&inode_lock);
......@@ -622,10 +680,7 @@ static struct inode * get_new_inode(struct super_block *sb, struct hlist_head *h
if (set(inode, data))
goto set_failed;
inodes_stat.nr_inodes++;
list_add(&inode->i_list, &inode_in_use);
list_add(&inode->i_sb_list, &sb->s_inodes);
hlist_add_head(&inode->i_hash, head);
__inode_add_to_lists(sb, head, inode);
inode->i_state = I_LOCK|I_NEW;
spin_unlock(&inode_lock);
......@@ -671,10 +726,7 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_he
old = find_inode_fast(sb, head, ino);
if (!old) {
inode->i_ino = ino;
inodes_stat.nr_inodes++;
list_add(&inode->i_list, &inode_in_use);
list_add(&inode->i_sb_list, &sb->s_inodes);
hlist_add_head(&inode->i_hash, head);
__inode_add_to_lists(sb, head, inode);
inode->i_state = I_LOCK|I_NEW;
spin_unlock(&inode_lock);
......@@ -698,16 +750,6 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_he
return inode;
}
static unsigned long hash(struct super_block *sb, unsigned long hashval)
{
unsigned long tmp;
tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) /
L1_CACHE_BYTES;
tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS);
return tmp & I_HASHMASK;
}
/**
* iunique - get a unique inode number
* @sb: superblock
......
......@@ -91,7 +91,8 @@ xfs-y += xfs_alloc.o \
xfs_dmops.o \
xfs_qmops.o
xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o \
xfs_dir2_trace.o
# Objects in linux/
xfs-y += $(addprefix $(XFS_LINUX)/, \
......@@ -106,6 +107,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
xfs_iops.o \
xfs_lrw.o \
xfs_super.o \
xfs_sync.o \
xfs_vnode.o \
xfs_xattr.o)
......
......@@ -191,7 +191,7 @@ xfs_setfilesize(
ip->i_d.di_size = isize;
ip->i_update_core = 1;
ip->i_update_size = 1;
mark_inode_dirty_sync(ioend->io_inode);
xfs_mark_inode_dirty_sync(ip);
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
......
......@@ -24,15 +24,7 @@
* Credentials
*/
typedef struct cred {
/* EMPTY */
/* EMPTY */
} cred_t;
extern struct cred *sys_cred;
/* this is a hack.. (assumes sys_cred is the only cred_t in the system) */
static inline int capable_cred(cred_t *cr, int cid)
{
return (cr == sys_cred) ? 1 : capable(cid);
}
#endif /* __XFS_CRED_H__ */
......@@ -26,7 +26,6 @@
*/
xfs_param_t xfs_params = {
/* MIN DFLT MAX */
.restrict_chown = { 0, 1, 1 },
.sgid_inherit = { 0, 0, 1 },
.symlink_mode = { 0, 0, 1 },
.panic_mask = { 0, 0, 255 },
......@@ -43,10 +42,3 @@ xfs_param_t xfs_params = {
.inherit_nodfrg = { 0, 1, 1 },
.fstrm_timer = { 1, 30*100, 3600*100},
};
/*
* Global system credential structure.
*/
static cred_t sys_cred_val;
cred_t *sys_cred = &sys_cred_val;
......@@ -19,6 +19,5 @@
#define __XFS_GLOBALS_H__
extern uint64_t xfs_panic_mask; /* set to cause more panics */
extern struct cred *sys_cred;
#endif /* __XFS_GLOBALS_H__ */
......@@ -691,8 +691,7 @@ xfs_ioc_space(
if (ioflags & IO_INVIS)
attr_flags |= XFS_ATTR_DMI;
error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos,
NULL, attr_flags);
error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos, attr_flags);
return -error;
}
......@@ -1007,7 +1006,7 @@ xfs_ioctl_setattr(
* to the file owner ID, except in cases where the
* CAP_FSETID capability is applicable.
*/
if (current->fsuid != ip->i_d.di_uid && !capable(CAP_FOWNER)) {
if (current_fsuid() != ip->i_d.di_uid && !capable(CAP_FOWNER)) {
code = XFS_ERROR(EPERM);
goto error_return;
}
......@@ -1104,10 +1103,6 @@ xfs_ioctl_setattr(
/*
* Change file ownership. Must be the owner or privileged.
* If the system was configured with the "restricted_chown"
* option, the owner is not permitted to give away the file,
* and can change the group id only to a group of which he
* or she is a member.
*/
if (mask & FSX_PROJID) {
/*
......
......@@ -64,14 +64,14 @@ xfs_synchronize_atime(
{
struct inode *inode = VFS_I(ip);
if (inode) {
if (!(inode->i_state & I_CLEAR)) {
ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
}
}
/*
* If the linux inode exists, mark it dirty.
* If the linux inode is valid, mark it dirty.
* Used when commiting a dirty inode into a transaction so that
* the inode will get written back by the linux code
*/
......@@ -81,7 +81,7 @@ xfs_mark_inode_dirty_sync(
{
struct inode *inode = VFS_I(ip);
if (inode)
if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR)))
mark_inode_dirty_sync(inode);
}
......@@ -128,7 +128,7 @@ xfs_ichgtime(
if (sync_it) {
SYNCHRONIZE();
ip->i_update_core = 1;
mark_inode_dirty_sync(inode);
xfs_mark_inode_dirty_sync(ip);
}
}
......@@ -601,7 +601,7 @@ xfs_vn_setattr(
struct dentry *dentry,
struct iattr *iattr)
{
return -xfs_setattr(XFS_I(dentry->d_inode), iattr, 0, NULL);
return -xfs_setattr(XFS_I(dentry->d_inode), iattr, 0);
}
/*
......@@ -642,7 +642,7 @@ xfs_vn_fallocate(
xfs_ilock(ip, XFS_IOLOCK_EXCL);
error = xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf,
0, NULL, XFS_ATTR_NOLOCK);
0, XFS_ATTR_NOLOCK);
if (!error && !(mode & FALLOC_FL_KEEP_SIZE) &&
offset + len > i_size_read(inode))
new_size = offset + len;
......@@ -653,7 +653,7 @@ xfs_vn_fallocate(
iattr.ia_valid = ATTR_SIZE;
iattr.ia_size = new_size;
error = xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK, NULL);
error = xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK);
}
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
......@@ -766,12 +766,21 @@ xfs_diflags_to_iflags(
* When reading existing inodes from disk this is called directly
* from xfs_iget, when creating a new inode it is called from
* xfs_ialloc after setting up the inode.
*
* We are always called with an uninitialised linux inode here.
* We need to initialise the necessary fields and take a reference
* on it.
*/
void
xfs_setup_inode(
struct xfs_inode *ip)
{
struct inode *inode = ip->i_vnode;
struct inode *inode = &ip->i_vnode;
inode->i_ino = ip->i_ino;
inode->i_state = I_NEW|I_LOCK;
inode_add_to_lists(ip->i_mount->m_super, inode);
ASSERT(atomic_read(&inode->i_count) == 1);
inode->i_mode = ip->i_d.di_mode;
inode->i_nlink = ip->i_d.di_nlink;
......
......@@ -77,6 +77,7 @@
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/ctype.h>
#include <linux/writeback.h>
#include <asm/page.h>
#include <asm/div64.h>
......@@ -107,7 +108,6 @@
#undef HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
#endif
#define restricted_chown xfs_params.restrict_chown.val
#define irix_sgid_inherit xfs_params.sgid_inherit.val
#define irix_symlink_mode xfs_params.symlink_mode.val
#define xfs_panic_mask xfs_params.panic_mask.val
......
......@@ -53,6 +53,10 @@ xfs_read_xfsstats(
{ "icluster", XFSSTAT_END_INODE_CLUSTER },
{ "vnodes", XFSSTAT_END_VNODE_OPS },
{ "buf", XFSSTAT_END_BUF },
{ "abtb2", XFSSTAT_END_ABTB_V2 },
{ "abtc2", XFSSTAT_END_ABTC_V2 },
{ "bmbt2", XFSSTAT_END_BMBT_V2 },
{ "ibt2", XFSSTAT_END_IBT_V2 },
};
/* Loop over all stats groups */
......
......@@ -118,6 +118,71 @@ struct xfsstats {
__uint32_t xb_page_retries;
__uint32_t xb_page_found;
__uint32_t xb_get_read;
/* Version 2 btree counters */
#define XFSSTAT_END_ABTB_V2 (XFSSTAT_END_BUF+15)
__uint32_t xs_abtb_2_lookup;
__uint32_t xs_abtb_2_compare;
__uint32_t xs_abtb_2_insrec;
__uint32_t xs_abtb_2_delrec;
__uint32_t xs_abtb_2_newroot;
__uint32_t xs_abtb_2_killroot;
__uint32_t xs_abtb_2_increment;
__uint32_t xs_abtb_2_decrement;
__uint32_t xs_abtb_2_lshift;
__uint32_t xs_abtb_2_rshift;
__uint32_t xs_abtb_2_split;
__uint32_t xs_abtb_2_join;
__uint32_t xs_abtb_2_alloc;
__uint32_t xs_abtb_2_free;
__uint32_t xs_abtb_2_moves;
#define XFSSTAT_END_ABTC_V2 (XFSSTAT_END_ABTB_V2+15)
__uint32_t xs_abtc_2_lookup;
__uint32_t xs_abtc_2_compare;
__uint32_t xs_abtc_2_insrec;
__uint32_t xs_abtc_2_delrec;
__uint32_t xs_abtc_2_newroot;
__uint32_t xs_abtc_2_killroot;
__uint32_t xs_abtc_2_increment;
__uint32_t xs_abtc_2_decrement;
__uint32_t xs_abtc_2_lshift;
__uint32_t xs_abtc_2_rshift;
__uint32_t xs_abtc_2_split;
__uint32_t xs_abtc_2_join;
__uint32_t xs_abtc_2_alloc;
__uint32_t xs_abtc_2_free;
__uint32_t xs_abtc_2_moves;
#define XFSSTAT_END_BMBT_V2 (XFSSTAT_END_ABTC_V2+15)
__uint32_t xs_bmbt_2_lookup;
__uint32_t xs_bmbt_2_compare;
__uint32_t xs_bmbt_2_insrec;
__uint32_t xs_bmbt_2_delrec;
__uint32_t xs_bmbt_2_newroot;
__uint32_t xs_bmbt_2_killroot;
__uint32_t xs_bmbt_2_increment;
__uint32_t xs_bmbt_2_decrement;
__uint32_t xs_bmbt_2_lshift;
__uint32_t xs_bmbt_2_rshift;
__uint32_t xs_bmbt_2_split;
__uint32_t xs_bmbt_2_join;
__uint32_t xs_bmbt_2_alloc;
__uint32_t xs_bmbt_2_free;
__uint32_t xs_bmbt_2_moves;
#define XFSSTAT_END_IBT_V2 (XFSSTAT_END_BMBT_V2+15)
__uint32_t xs_ibt_2_lookup;
__uint32_t xs_ibt_2_compare;
__uint32_t xs_ibt_2_insrec;
__uint32_t xs_ibt_2_delrec;
__uint32_t xs_ibt_2_newroot;
__uint32_t xs_ibt_2_killroot;
__uint32_t xs_ibt_2_increment;
__uint32_t xs_ibt_2_decrement;
__uint32_t xs_ibt_2_lshift;
__uint32_t xs_ibt_2_rshift;
__uint32_t xs_ibt_2_split;
__uint32_t xs_ibt_2_join;
__uint32_t xs_ibt_2_alloc;
__uint32_t xs_ibt_2_free;
__uint32_t xs_ibt_2_moves;
/* Extra precision counters */
__uint64_t xs_xstrat_bytes;
__uint64_t xs_write_bytes;
......
This diff is collapsed.
......@@ -101,9 +101,6 @@ struct block_device;
extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_flush_inode(struct xfs_inode *);
extern void xfs_flush_device(struct xfs_inode *);
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
extern const struct export_operations xfs_export_operations;
......
This diff is collapsed.
/*
* Copyright (c) 2000-2006 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_SYNC_H
#define XFS_SYNC_H 1
struct xfs_mount;
typedef struct bhv_vfs_sync_work {
struct list_head w_list;
struct xfs_mount *w_mount;
void *w_data; /* syncer routine argument */
void (*w_syncer)(struct xfs_mount *, void *);
} bhv_vfs_sync_work_t;
#define SYNC_ATTR 0x0001 /* sync attributes */
#define SYNC_DELWRI 0x0002 /* look at delayed writes */
#define SYNC_WAIT 0x0004 /* wait for i/o to complete */
#define SYNC_BDFLUSH 0x0008 /* BDFLUSH is calling -- don't block */
#define SYNC_IOWAIT 0x0010 /* wait for all I/O to complete */
int xfs_syncd_init(struct xfs_mount *mp);
void xfs_syncd_stop(struct xfs_mount *mp);
int xfs_sync_inodes(struct xfs_mount *mp, int flags);
int xfs_sync_fsdata(struct xfs_mount *mp, int flags);
int xfs_quiesce_data(struct xfs_mount *mp);
void xfs_quiesce_attr(struct xfs_mount *mp);
void xfs_flush_inode(struct xfs_inode *ip);
void xfs_flush_device(struct xfs_inode *ip);
int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode);
int xfs_reclaim_inodes(struct xfs_mount *mp, int noblock, int mode);
void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip);
void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
struct xfs_inode *ip);
#endif
......@@ -55,17 +55,6 @@ xfs_stats_clear_proc_handler(
#endif /* CONFIG_PROC_FS */
static ctl_table xfs_table[] = {
{
.ctl_name = XFS_RESTRICT_CHOWN,
.procname = "restrict_chown",
.data = &xfs_params.restrict_chown.val,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &xfs_params.restrict_chown.min,
.extra2 = &xfs_params.restrict_chown.max
},
{
.ctl_name = XFS_SGID_INHERIT,
.procname = "irix_sgid_inherit",
......
......@@ -31,7 +31,6 @@ typedef struct xfs_sysctl_val {
} xfs_sysctl_val_t;
typedef struct xfs_param {
xfs_sysctl_val_t restrict_chown;/* Root/non-root can give away files.*/
xfs_sysctl_val_t sgid_inherit; /* Inherit S_ISGID if process' GID is
* not a member of parent dir GID. */
xfs_sysctl_val_t symlink_mode; /* Link creat mode affected by umask */
......@@ -68,7 +67,7 @@ typedef struct xfs_param {
enum {
/* XFS_REFCACHE_SIZE = 1 */
/* XFS_REFCACHE_PURGE = 2 */
XFS_RESTRICT_CHOWN = 3,
/* XFS_RESTRICT_CHOWN = 3 */
XFS_SGID_INHERIT = 4,
XFS_SYMLINK_MODE = 5,
XFS_PANIC_MASK = 6,
......
......@@ -33,37 +33,6 @@ struct xfs_mount_args;
typedef struct kstatfs bhv_statvfs_t;
typedef struct bhv_vfs_sync_work {
struct list_head w_list;
struct xfs_mount *w_mount;
void *w_data; /* syncer routine argument */
void (*w_syncer)(struct xfs_mount *, void *);
} bhv_vfs_sync_work_t;
#define SYNC_ATTR 0x0001 /* sync attributes */
#define SYNC_CLOSE 0x0002 /* close file system down */
#define SYNC_DELWRI 0x0004 /* look at delayed writes */
#define SYNC_WAIT 0x0008 /* wait for i/o to complete */
#define SYNC_BDFLUSH 0x0010 /* BDFLUSH is calling -- don't block */
#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_IOWAIT 0x0100 /* wait for all I/O to complete */
/*
* When remounting a filesystem read-only or freezing the filesystem,
* we have two phases to execute. This first phase is syncing the data
* before we quiesce the fielsystem, and the second is flushing all the
* inodes out after we've waited for all the transactions created by
* the first phase to complete. The second phase uses SYNC_INODE_QUIESCE
* to ensure that the inodes are written to their location on disk
* rather than just existing in transactions in the log. This means
* after a quiesce there is no log replay required to write the inodes
* to disk (this is the main difference between a sync and a quiesce).
*/
#define SYNC_DATA_QUIESCE (SYNC_DELWRI|SYNC_FSDATA|SYNC_WAIT|SYNC_IOWAIT)
#define SYNC_INODE_QUIESCE (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT)
#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 */
......
......@@ -84,25 +84,12 @@ vn_ioerror(
#ifdef XFS_INODE_TRACE
/*
* Reference count of Linux inode if present, -1 if the xfs_inode
* has no associated Linux inode.
*/
static inline int xfs_icount(struct xfs_inode *ip)
{
struct inode *vp = VFS_I(ip);
if (vp)
return vn_count(vp);
return -1;
}
#define KTRACE_ENTER(ip, vk, s, line, ra) \
ktrace_enter( (ip)->i_trace, \
/* 0 */ (void *)(__psint_t)(vk), \
/* 1 */ (void *)(s), \
/* 2 */ (void *)(__psint_t) line, \
/* 3 */ (void *)(__psint_t)xfs_icount(ip), \
/* 3 */ (void *)(__psint_t)atomic_read(&VFS_I(ip)->i_count), \
/* 4 */ (void *)(ra), \
/* 5 */ NULL, \
/* 6 */ (void *)(__psint_t)current_cpu(), \
......
......@@ -80,11 +80,6 @@ do { \
iput(VFS_I(ip)); \
} while (0)
static inline struct inode *vn_grab(struct inode *vp)
{
return igrab(vp);
}
/*
* Dealing with bad inodes
*/
......
......@@ -101,7 +101,7 @@ xfs_qm_dqinit(
if (brandnewdquot) {
dqp->dq_flnext = dqp->dq_flprev = dqp;
mutex_init(&dqp->q_qlock);
sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq");
init_waitqueue_head(&dqp->q_pinwait);
/*
* Because we want to use a counting completion, complete
......@@ -131,7 +131,7 @@ xfs_qm_dqinit(
dqp->q_res_bcount = 0;
dqp->q_res_icount = 0;
dqp->q_res_rtbcount = 0;
dqp->q_pincount = 0;
atomic_set(&dqp->q_pincount, 0);
dqp->q_hash = NULL;
ASSERT(dqp->dq_flnext == dqp->dq_flprev);
......@@ -1221,16 +1221,14 @@ xfs_qm_dqflush(
xfs_dqtrace_entry(dqp, "DQFLUSH");
/*
* If not dirty, nada.
* If not dirty, or it's pinned and we are not supposed to
* block, nada.
*/
if (!XFS_DQ_IS_DIRTY(dqp)) {
if (!XFS_DQ_IS_DIRTY(dqp) ||
(!(flags & XFS_QMOPT_SYNC) && atomic_read(&dqp->q_pincount) > 0)) {
xfs_dqfunlock(dqp);
return (0);
return 0;
}
/*
* Cant flush a pinned dquot. Wait for it.
*/
xfs_qm_dqunpin_wait(dqp);
/*
......@@ -1274,10 +1272,8 @@ xfs_qm_dqflush(
dqp->dq_flags &= ~(XFS_DQ_DIRTY);
mp = dqp->q_mount;
/* lsn is 64 bits */
spin_lock(&mp->m_ail_lock);
dqp->q_logitem.qli_flush_lsn = dqp->q_logitem.qli_item.li_lsn;
spin_unlock(&mp->m_ail_lock);
xfs_trans_ail_copy_lsn(mp->m_ail, &dqp->q_logitem.qli_flush_lsn,
&dqp->q_logitem.qli_item.li_lsn);
/*
* Attach an iodone routine so that we can remove this dquot from the
......@@ -1323,8 +1319,10 @@ xfs_qm_dqflush_done(
xfs_dq_logitem_t *qip)
{
xfs_dquot_t *dqp;
struct xfs_ail *ailp;
dqp = qip->qli_dquot;
ailp = qip->qli_item.li_ailp;
/*
* We only want to pull the item from the AIL if its
......@@ -1337,15 +1335,12 @@ xfs_qm_dqflush_done(
if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
qip->qli_item.li_lsn == qip->qli_flush_lsn) {
spin_lock(&dqp->q_mount->m_ail_lock);
/*
* xfs_trans_delete_ail() drops the AIL lock.
*/
/* xfs_trans_ail_delete() drops the AIL lock. */
spin_lock(&ailp->xa_lock);
if (qip->qli_item.li_lsn == qip->qli_flush_lsn)
xfs_trans_delete_ail(dqp->q_mount,
(xfs_log_item_t*)qip);
xfs_trans_ail_delete(ailp, (xfs_log_item_t*)qip);
else
spin_unlock(&dqp->q_mount->m_ail_lock);
spin_unlock(&ailp->xa_lock);
}
/*
......@@ -1375,7 +1370,7 @@ xfs_dqunlock(
mutex_unlock(&(dqp->q_qlock));
if (dqp->q_logitem.qli_dquot == dqp) {
/* Once was dqp->q_mount, but might just have been cleared */
xfs_trans_unlocked_item(dqp->q_logitem.qli_item.li_mountp,
xfs_trans_unlocked_item(dqp->q_logitem.qli_item.li_ailp,
(xfs_log_item_t*)&(dqp->q_logitem));
}
}
......@@ -1489,7 +1484,7 @@ xfs_qm_dqpurge(
"xfs_qm_dqpurge: dquot %p flush failed", dqp);
xfs_dqflock(dqp);
}
ASSERT(dqp->q_pincount == 0);
ASSERT(atomic_read(&dqp->q_pincount) == 0);
ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
!(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
......
......@@ -83,8 +83,8 @@ typedef struct xfs_dquot {
xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */
mutex_t q_qlock; /* quota lock */
struct completion q_flush; /* flush completion queue */
uint q_pincount; /* pin count for this dquot */
sv_t q_pinwait; /* sync var for pinning */
atomic_t q_pincount; /* dquot pin count */
wait_queue_head_t q_pinwait; /* dquot pinning wait queue */
#ifdef XFS_DQUOT_TRACE
struct ktrace *q_trace; /* trace header structure */
#endif
......
......@@ -88,25 +88,22 @@ xfs_qm_dquot_logitem_format(
/*
* Increment the pin count of the given dquot.
* This value is protected by pinlock spinlock in the xQM structure.
*/
STATIC void
xfs_qm_dquot_logitem_pin(
xfs_dq_logitem_t *logitem)
{
xfs_dquot_t *dqp;
xfs_dquot_t *dqp = logitem->qli_dquot;
dqp = logitem->qli_dquot;
ASSERT(XFS_DQ_IS_LOCKED(dqp));
spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
dqp->q_pincount++;
spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
atomic_inc(&dqp->q_pincount);
}
/*
* Decrement the pin count of the given dquot, and wake up
* anyone in xfs_dqwait_unpin() if the count goes to 0. The
* dquot must have been previously pinned with a call to xfs_dqpin().
* dquot must have been previously pinned with a call to
* xfs_qm_dquot_logitem_pin().
*/
/* ARGSUSED */
STATIC void
......@@ -114,16 +111,11 @@ xfs_qm_dquot_logitem_unpin(
xfs_dq_logitem_t *logitem,
int stale)
{
xfs_dquot_t *dqp;
xfs_dquot_t *dqp = logitem->qli_dquot;
dqp = logitem->qli_dquot;
ASSERT(dqp->q_pincount > 0);
spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
dqp->q_pincount--;
if (dqp->q_pincount == 0) {
sv_broadcast(&dqp->q_pinwait);
}
spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
ASSERT(atomic_read(&dqp->q_pincount) > 0);
if (atomic_dec_and_test(&dqp->q_pincount))
wake_up(&dqp->q_pinwait);
}
/* ARGSUSED */
......@@ -193,21 +185,14 @@ xfs_qm_dqunpin_wait(
xfs_dquot_t *dqp)
{
ASSERT(XFS_DQ_IS_LOCKED(dqp));
if (dqp->q_pincount == 0) {
if (atomic_read(&dqp->q_pincount) == 0)
return;
}
/*
* Give the log a push so we don't wait here too long.
*/
xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE);
spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
if (dqp->q_pincount == 0) {
spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
return;
}
sv_wait(&(dqp->q_pinwait), PINOD,
&(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s);
wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0));
}
/*
......@@ -310,7 +295,7 @@ xfs_qm_dquot_logitem_trylock(
uint retval;
dqp = qip->qli_dquot;
if (dqp->q_pincount > 0)
if (atomic_read(&dqp->q_pincount) > 0)
return (XFS_ITEM_PINNED);
if (! xfs_qm_dqlock_nowait(dqp))
......@@ -568,14 +553,16 @@ xfs_qm_qoffend_logitem_committed(
xfs_lsn_t lsn)
{
xfs_qoff_logitem_t *qfs;
struct xfs_ail *ailp;
qfs = qfe->qql_start_lip;
spin_lock(&qfs->qql_item.li_mountp->m_ail_lock);
ailp = qfs->qql_item.li_ailp;
spin_lock(&ailp->xa_lock);
/*
* Delete the qoff-start logitem from the AIL.
* xfs_trans_delete_ail() drops the AIL lock.
* xfs_trans_ail_delete() drops the AIL lock.
*/
xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs);
xfs_trans_ail_delete(ailp, (xfs_log_item_t *)qfs);
kmem_free(qfs);
kmem_free(qfe);
return (xfs_lsn_t)-1;
......
......@@ -20,7 +20,6 @@
#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_inum.h"
#include "xfs_clnt.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
......@@ -987,14 +986,10 @@ xfs_qm_dqdetach(
}
/*
* This is called by VFS_SYNC and flags arg determines the caller,
* and its motives, as done in xfs_sync.
*
* vfs_sync: SYNC_FSDATA|SYNC_ATTR|SYNC_BDFLUSH 0x31
* syscall sync: SYNC_FSDATA|SYNC_ATTR|SYNC_DELWRI 0x25
* umountroot : SYNC_WAIT | SYNC_CLOSE | SYNC_ATTR | SYNC_FSDATA
* This is called to sync quotas. We can be told to use non-blocking
* semantics by either the SYNC_BDFLUSH flag or the absence of the
* SYNC_WAIT flag.
*/
int
xfs_qm_sync(
xfs_mount_t *mp,
......@@ -1137,7 +1132,6 @@ xfs_qm_init_quotainfo(
return error;
}
spin_lock_init(&qinf->qi_pinlock);
xfs_qm_list_init(&qinf->qi_dqlist, "mpdqlist", 0);
qinf->qi_dqreclaims = 0;
......@@ -1234,7 +1228,6 @@ xfs_qm_destroy_quotainfo(
*/
xfs_qm_rele_quotafs_ref(mp);
spinlock_destroy(&qi->qi_pinlock);
xfs_qm_list_destroy(&qi->qi_dqlist);
if (qi->qi_uquotaip) {
......
......@@ -106,7 +106,6 @@ typedef struct xfs_qm {
typedef struct xfs_quotainfo {
xfs_inode_t *qi_uquotaip; /* user quota inode */
xfs_inode_t *qi_gquotaip; /* group quota inode */
spinlock_t qi_pinlock; /* dquot pinning lock */
xfs_dqlist_t qi_dqlist; /* all dquots in filesys */
int qi_dqreclaims; /* a change here indicates
a removal in the dqlist */
......
......@@ -20,7 +20,6 @@
#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_inum.h"
#include "xfs_clnt.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
......
......@@ -127,7 +127,7 @@ xfs_qm_quotactl(
break;
case Q_XQUOTASYNC:
return (xfs_sync_inodes(mp, SYNC_DELWRI, NULL));
return xfs_sync_inodes(mp, SYNC_DELWRI);
default:
break;
......@@ -1022,101 +1022,92 @@ xfs_qm_export_flags(
/*
* Go thru all the inodes in the file system, releasing their dquots.
* Note that the mount structure gets modified to indicate that quotas are off
* AFTER this, in the case of quotaoff. This also gets called from
* xfs_rootumount.
* Release all the dquots on the inodes in an AG.
*/
void
xfs_qm_dqrele_all_inodes(
struct xfs_mount *mp,
uint flags)
STATIC void
xfs_qm_dqrele_inodes_ag(
xfs_mount_t *mp,
int ag,
uint flags)
{
xfs_inode_t *ip, *topino;
uint ireclaims;
struct inode *vp;
boolean_t vnode_refd;
ASSERT(mp->m_quotainfo);
xfs_inode_t *ip = NULL;
xfs_perag_t *pag = &mp->m_perag[ag];
int first_index = 0;
int nr_found;
XFS_MOUNT_ILOCK(mp);
again:
ip = mp->m_inodes;
if (ip == NULL) {
XFS_MOUNT_IUNLOCK(mp);
return;
}
do {
/* Skip markers inserted by xfs_sync */
if (ip->i_mount == NULL) {
ip = ip->i_mnext;
continue;
}
/* Root inode, rbmip and rsumip have associated blocks */
if (ip == XFS_QI_UQIP(mp) || ip == XFS_QI_GQIP(mp)) {
ASSERT(ip->i_udquot == NULL);
ASSERT(ip->i_gdquot == NULL);
ip = ip->i_mnext;
continue;
boolean_t inode_refed;
struct inode *inode;
/*
* use a gang lookup to find the next inode in the tree
* as the tree is sparse and a gang lookup walks to find
* the number of objects requested.
*/
read_lock(&pag->pag_ici_lock);
nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
(void**)&ip, first_index, 1);
if (!nr_found) {
read_unlock(&pag->pag_ici_lock);
break;
}
vp = VFS_I(ip);
if (!vp) {
/* update the index for the next lookup */
first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
/* skip quota inodes and those in reclaim */
inode = VFS_I(ip);
if (!inode || ip == XFS_QI_UQIP(mp) || ip == XFS_QI_GQIP(mp)) {
ASSERT(ip->i_udquot == NULL);
ASSERT(ip->i_gdquot == NULL);
ip = ip->i_mnext;
read_unlock(&pag->pag_ici_lock);
continue;
}
vnode_refd = B_FALSE;
if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0) {
ireclaims = mp->m_ireclaims;
topino = mp->m_inodes;
vp = vn_grab(vp);
if (!vp)
goto again;
XFS_MOUNT_IUNLOCK(mp);
/* XXX restart limit ? */
inode = igrab(inode);
read_unlock(&pag->pag_ici_lock);
if (!inode)
continue;
inode_refed = B_TRUE;
xfs_ilock(ip, XFS_ILOCK_EXCL);
vnode_refd = B_TRUE;
} else {
ireclaims = mp->m_ireclaims;
topino = mp->m_inodes;
XFS_MOUNT_IUNLOCK(mp);
read_unlock(&pag->pag_ici_lock);
}
/*
* We don't keep the mountlock across the dqrele() call,
* since it can take a while..
*/
if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
xfs_qm_dqrele(ip->i_udquot);
ip->i_udquot = NULL;
}
if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) &&
ip->i_gdquot) {
xfs_qm_dqrele(ip->i_gdquot);
ip->i_gdquot = NULL;
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
/*
* Wait until we've dropped the ilock and mountlock to
* do the vn_rele. Or be condemned to an eternity in the
* inactive code in hell.
*/
if (vnode_refd)
if (inode_refed)
IRELE(ip);
XFS_MOUNT_ILOCK(mp);
/*
* If an inode was inserted or removed, we gotta
* start over again.
*/
if (topino != mp->m_inodes || mp->m_ireclaims != ireclaims) {
/* XXX use a sentinel */
goto again;
}
ip = ip->i_mnext;
} while (ip != mp->m_inodes);
} while (nr_found);
}
/*
* Go thru all the inodes in the file system, releasing their dquots.
* Note that the mount structure gets modified to indicate that quotas are off
* AFTER this, in the case of quotaoff. This also gets called from
* xfs_rootumount.
*/
void
xfs_qm_dqrele_all_inodes(
struct xfs_mount *mp,
uint flags)
{
int i;
XFS_MOUNT_IUNLOCK(mp);
ASSERT(mp->m_quotainfo);
for (i = 0; i < mp->m_sb.sb_agcount; i++) {
if (!mp->m_perag[i].pag_ici_init)
continue;
xfs_qm_dqrele_inodes_ag(mp, i, flags);
}
}
/*------------------------------------------------------------------------*/
......
......@@ -84,5 +84,5 @@ assfail(char *expr, char *file, int line)
void
xfs_hex_dump(void *p, int length)
{
print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_OFFSET, 16, 1, p, length, 1);
print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_ADDRESS, 16, 1, p, length, 1);
}
......@@ -30,7 +30,7 @@
#define XFS_ATTR_TRACE 1
#define XFS_BLI_TRACE 1
#define XFS_BMAP_TRACE 1
#define XFS_BMBT_TRACE 1
#define XFS_BTREE_TRACE 1
#define XFS_DIR2_TRACE 1
#define XFS_DQUOT_TRACE 1
#define XFS_ILOCK_TRACE 1
......
......@@ -366,7 +366,7 @@ xfs_acl_allow_set(
return ENOTDIR;
if (vp->i_sb->s_flags & MS_RDONLY)
return EROFS;
if (XFS_I(vp)->i_d.di_uid != current->fsuid && !capable(CAP_FOWNER))
if (XFS_I(vp)->i_d.di_uid != current_fsuid() && !capable(CAP_FOWNER))
return EPERM;
return 0;
}
......@@ -413,13 +413,13 @@ xfs_acl_access(
switch (fap->acl_entry[i].ae_tag) {
case ACL_USER_OBJ:
seen_userobj = 1;
if (fuid != current->fsuid)
if (fuid != current_fsuid())
continue;
matched.ae_tag = ACL_USER_OBJ;
matched.ae_perm = allows;
break;
case ACL_USER:
if (fap->acl_entry[i].ae_id != current->fsuid)
if (fap->acl_entry[i].ae_id != current_fsuid())
continue;
matched.ae_tag = ACL_USER;
matched.ae_perm = allows;
......@@ -758,7 +758,7 @@ xfs_acl_setmode(
if (gap && nomask)
iattr.ia_mode |= gap->ae_perm << 3;
return xfs_setattr(XFS_I(vp), &iattr, 0, sys_cred);
return xfs_setattr(XFS_I(vp), &iattr, 0);
}
/*
......
......@@ -192,17 +192,23 @@ typedef struct xfs_perag
xfs_agino_t pagi_freecount; /* number of free inodes */
xfs_agino_t pagi_count; /* number of allocated inodes */
int pagb_count; /* pagb slots in use */
xfs_perag_busy_t *pagb_list; /* unstable blocks */
#ifdef __KERNEL__
spinlock_t pagb_lock; /* lock for pagb_list */
#endif
xfs_perag_busy_t *pagb_list; /* unstable blocks */
atomic_t pagf_fstrms; /* # of filestreams active in this AG */
int pag_ici_init; /* incore inode cache initialised */
rwlock_t pag_ici_lock; /* incore inode lock */
struct radix_tree_root pag_ici_root; /* incore inode cache root */
#endif
} xfs_perag_t;
/*
* tags for inode radix tree
*/
#define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */
#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
#define XFS_MIN_FREELIST_RAW(bl,cl,mp) \
(MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + MIN(cl + 1, XFS_AG_MAXLEVELS(mp)))
......
This diff is collapsed.
......@@ -121,6 +121,19 @@ extern ktrace_t *xfs_alloc_trace_buf;
#define XFS_ALLOC_KTRACE_BUSYSEARCH 6
#endif
void
xfs_alloc_mark_busy(xfs_trans_t *tp,
xfs_agnumber_t agno,
xfs_agblock_t bno,
xfs_extlen_t len);
void
xfs_alloc_clear_busy(xfs_trans_t *tp,
xfs_agnumber_t ag,
int idx);
#endif /* __KERNEL__ */
/*
* Compute and fill in value of m_ag_maxlevels.
*/
......@@ -196,18 +209,4 @@ xfs_free_extent(
xfs_fsblock_t bno, /* starting block number of extent */
xfs_extlen_t len); /* length of extent */
void
xfs_alloc_mark_busy(xfs_trans_t *tp,
xfs_agnumber_t agno,
xfs_agblock_t bno,
xfs_extlen_t len);
void
xfs_alloc_clear_busy(xfs_trans_t *tp,
xfs_agnumber_t ag,
int idx);
#endif /* __KERNEL__ */
#endif /* __XFS_ALLOC_H__ */
This diff is collapsed.
......@@ -24,7 +24,6 @@
struct xfs_buf;
struct xfs_btree_cur;
struct xfs_btree_sblock;
struct xfs_mount;
/*
......@@ -50,16 +49,6 @@ typedef struct xfs_alloc_rec_incore {
/* btree pointer type */
typedef __be32 xfs_alloc_ptr_t;
/* btree block header type */
typedef struct xfs_btree_sblock xfs_alloc_block_t;
#define XFS_BUF_TO_ALLOC_BLOCK(bp) ((xfs_alloc_block_t *)XFS_BUF_PTR(bp))
/*
* Real block structures have a size equal to the disk block size.
*/
#define XFS_ALLOC_BLOCK_MAXRECS(lev,cur) ((cur)->bc_mp->m_alloc_mxr[lev != 0])
#define XFS_ALLOC_BLOCK_MINRECS(lev,cur) ((cur)->bc_mp->m_alloc_mnr[lev != 0])
/*
* Minimum and maximum blocksize and sectorsize.
......@@ -83,73 +72,39 @@ typedef struct xfs_btree_sblock xfs_alloc_block_t;
#define XFS_CNT_BLOCK(mp) ((xfs_agblock_t)(XFS_BNO_BLOCK(mp) + 1))
/*
* Record, key, and pointer address macros for btree blocks.
*/
#define XFS_ALLOC_REC_ADDR(bb,i,cur) \
XFS_BTREE_REC_ADDR(xfs_alloc, bb, i)
#define XFS_ALLOC_KEY_ADDR(bb,i,cur) \
XFS_BTREE_KEY_ADDR(xfs_alloc, bb, i)
#define XFS_ALLOC_PTR_ADDR(bb,i,cur) \
XFS_BTREE_PTR_ADDR(xfs_alloc, bb, i, XFS_ALLOC_BLOCK_MAXRECS(1, cur))
/*
* Decrement cursor by one record at the level.
* For nonzero levels the leaf-ward information is untouched.
*/
extern int xfs_alloc_decrement(struct xfs_btree_cur *cur, int level, int *stat);
/*
* Delete the record pointed to by cur.
* The cursor refers to the place where the record was (could be inserted)
* when the operation returns.
*/
extern int xfs_alloc_delete(struct xfs_btree_cur *cur, int *stat);
/*
* Get the data from the pointed-to record.
*/
extern int xfs_alloc_get_rec(struct xfs_btree_cur *cur, xfs_agblock_t *bno,
xfs_extlen_t *len, int *stat);
/*
* Increment cursor by one record at the level.
* For nonzero levels the leaf-ward information is untouched.
*/
extern int xfs_alloc_increment(struct xfs_btree_cur *cur, int level, int *stat);
/*
* Insert the current record at the point referenced by cur.
* The cursor may be inconsistent on return if splits have been done.
*/
extern int xfs_alloc_insert(struct xfs_btree_cur *cur, int *stat);
/*
* Lookup the record equal to [bno, len] in the btree given by cur.
*/
extern int xfs_alloc_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno,
xfs_extlen_t len, int *stat);
/*
* Lookup the first record greater than or equal to [bno, len]
* in the btree given by cur.
*/
extern int xfs_alloc_lookup_ge(struct xfs_btree_cur *cur, xfs_agblock_t bno,
xfs_extlen_t len, int *stat);
/*
* Lookup the first record less than or equal to [bno, len]
* in the btree given by cur.
* Btree block header size depends on a superblock flag.
*
* (not quite yet, but soon)
*/
extern int xfs_alloc_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno,
xfs_extlen_t len, int *stat);
#define XFS_ALLOC_BLOCK_LEN(mp) XFS_BTREE_SBLOCK_LEN
/*
* Update the record referred to by cur, to the value given by [bno, len].
* This either works (return 0) or gets an EFSCORRUPTED error.
*/
extern int xfs_alloc_update(struct xfs_btree_cur *cur, xfs_agblock_t bno,
xfs_extlen_t len);
* Record, key, and pointer address macros for btree blocks.
*
* (note that some of these may appear unused, but they are used in userspace)
*/
#define XFS_ALLOC_REC_ADDR(mp, block, index) \
((xfs_alloc_rec_t *) \
((char *)(block) + \
XFS_ALLOC_BLOCK_LEN(mp) + \
(((index) - 1) * sizeof(xfs_alloc_rec_t))))
#define XFS_ALLOC_KEY_ADDR(mp, block, index) \
((xfs_alloc_key_t *) \
((char *)(block) + \
XFS_ALLOC_BLOCK_LEN(mp) + \
((index) - 1) * sizeof(xfs_alloc_key_t)))
#define XFS_ALLOC_PTR_ADDR(mp, block, index, maxrecs) \
((xfs_alloc_ptr_t *) \
((char *)(block) + \
XFS_ALLOC_BLOCK_LEN(mp) + \
(maxrecs) * sizeof(xfs_alloc_key_t) + \
((index) - 1) * sizeof(xfs_alloc_ptr_t)))
extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *,
struct xfs_trans *, struct xfs_buf *,
xfs_agnumber_t, xfs_btnum_t);
extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int);
#endif /* __XFS_ALLOC_BTREE_H__ */
......@@ -41,21 +41,36 @@
#endif
#ifdef XFS_NATIVE_HOST
#define cpu_to_be16(val) ((__be16)(val))
#define cpu_to_be32(val) ((__be32)(val))
#define cpu_to_be64(val) ((__be64)(val))
#define be16_to_cpu(val) ((__uint16_t)(val))
#define be32_to_cpu(val) ((__uint32_t)(val))
#define be64_to_cpu(val) ((__uint64_t)(val))
#define cpu_to_be16(val) ((__force __be16)(__u16)(val))
#define cpu_to_be32(val) ((__force __be32)(__u32)(val))
#define cpu_to_be64(val) ((__force __be64)(__u64)(val))
#define be16_to_cpu(val) ((__force __u16)(__be16)(val))
#define be32_to_cpu(val) ((__force __u32)(__be32)(val))
#define be64_to_cpu(val) ((__force __u64)(__be64)(val))
#else
#define cpu_to_be16(val) (__swab16((__uint16_t)(val)))
#define cpu_to_be32(val) (__swab32((__uint32_t)(val)))
#define cpu_to_be64(val) (__swab64((__uint64_t)(val)))
#define be16_to_cpu(val) (__swab16((__be16)(val)))
#define be32_to_cpu(val) (__swab32((__be32)(val)))
#define be64_to_cpu(val) (__swab64((__be64)(val)))
#define cpu_to_be16(val) ((__force __be16)__swab16((__u16)(val)))
#define cpu_to_be32(val) ((__force __be32)__swab32((__u32)(val)))
#define cpu_to_be64(val) ((__force __be64)__swab64((__u64)(val)))
#define be16_to_cpu(val) (__swab16((__force __u16)(__be16)(val)))
#define be32_to_cpu(val) (__swab32((__force __u32)(__be32)(val)))
#define be64_to_cpu(val) (__swab64((__force __u64)(__be64)(val)))
#endif
static inline void be16_add_cpu(__be16 *a, __s16 b)
{
*a = cpu_to_be16(be16_to_cpu(*a) + b);
}
static inline void be32_add_cpu(__be32 *a, __s32 b)
{
*a = cpu_to_be32(be32_to_cpu(*a) + b);
}
static inline void be64_add_cpu(__be64 *a, __s64 b)
{
*a = cpu_to_be64(be64_to_cpu(*a) + b);
}
#endif /* __KERNEL__ */
/* do we need conversion? */
......
......@@ -61,8 +61,7 @@ static inline int xfs_highbit64(__uint64_t v)
/* Get low bit set out of 32-bit argument, -1 if none set */
static inline int xfs_lowbit32(__uint32_t v)
{
unsigned long t = v;
return (v) ? find_first_bit(&t, 32) : -1;
return ffs(v) - 1;
}
/* Get low bit set out of 64-bit argument, -1 if none set */
......
This diff is collapsed.
......@@ -137,9 +137,7 @@ typedef struct xfs_bmalloca {
char conv; /* overwriting unwritten extents */
} xfs_bmalloca_t;
#ifdef __KERNEL__
#if defined(XFS_BMAP_TRACE)
#if defined(__KERNEL__) && defined(XFS_BMAP_TRACE)
/*
* Trace operations for bmap extent tracing
*/
......@@ -163,9 +161,12 @@ xfs_bmap_trace_exlist(
int whichfork); /* data or attr fork */
#define XFS_BMAP_TRACE_EXLIST(ip,c,w) \
xfs_bmap_trace_exlist(__func__,ip,c,w)
#else
#else /* __KERNEL__ && XFS_BMAP_TRACE */
#define XFS_BMAP_TRACE_EXLIST(ip,c,w)
#endif
#endif /* __KERNEL__ && XFS_BMAP_TRACE */
/*
* Convert inode from non-attributed to attributed.
......@@ -205,20 +206,6 @@ xfs_bmap_compute_maxlevels(
struct xfs_mount *mp, /* file system mount structure */
int whichfork); /* data or attr fork */
/*
* Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
* caller. Frees all the extents that need freeing, which must be done
* last due to locking considerations.
*
* Return 1 if the given transaction was committed and a new one allocated,
* and 0 otherwise.
*/
int /* error */
xfs_bmap_finish(
struct xfs_trans **tp, /* transaction pointer addr */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
int *committed); /* xact committed or not */
/*
* Returns the file-relative block number of the first unused block in the file.
* This is the lowest-address hole if the file has holes, else the first block
......@@ -343,6 +330,32 @@ xfs_bunmapi(
extents */
int *done); /* set if not done yet */
/*
* Check an extent list, which has just been read, for
* any bit in the extent flag field.
*/
int
xfs_check_nostate_extents(
struct xfs_ifork *ifp,
xfs_extnum_t idx,
xfs_extnum_t num);
#ifdef __KERNEL__
/*
* Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi
* caller. Frees all the extents that need freeing, which must be done
* last due to locking considerations.
*
* Return 1 if the given transaction was committed and a new one allocated,
* and 0 otherwise.
*/
int /* error */
xfs_bmap_finish(
struct xfs_trans **tp, /* transaction pointer addr */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
int *committed); /* xact committed or not */
/*
* Fcntl interface to xfs_bmapi.
*/
......@@ -374,16 +387,6 @@ xfs_bmap_count_blocks(
int whichfork,
int *count);
/*
* Check an extent list, which has just been read, for
* any bit in the extent flag field.
*/
int
xfs_check_nostate_extents(
struct xfs_ifork *ifp,
xfs_extnum_t idx,
xfs_extnum_t num);
/*
* Search the extent records for the entry containing block bno.
* If bno lies in a hole, point to the next entry. If bno lies
......
This diff is collapsed.
......@@ -21,9 +21,10 @@
#define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */
struct xfs_btree_cur;
struct xfs_btree_lblock;
struct xfs_btree_block;
struct xfs_mount;
struct xfs_inode;
struct xfs_trans;
/*
* Bmap root header, on-disk form only.
......@@ -145,71 +146,60 @@ typedef struct xfs_bmbt_key {
/* btree pointer type */
typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
/* btree block header type */
typedef struct xfs_btree_lblock xfs_bmbt_block_t;
#define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
#define XFS_BMAP_RBLOCK_DSIZE(lev,cur) ((cur)->bc_private.b.forksize)
#define XFS_BMAP_RBLOCK_ISIZE(lev,cur) \
((int)XFS_IFORK_PTR((cur)->bc_private.b.ip, \
(cur)->bc_private.b.whichfork)->if_broot_bytes)
#define XFS_BMAP_BLOCK_DMAXRECS(lev,cur) \
(((lev) == (cur)->bc_nlevels - 1 ? \
XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur), \
xfs_bmdr, (lev) == 0) : \
((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
#define XFS_BMAP_BLOCK_IMAXRECS(lev,cur) \
(((lev) == (cur)->bc_nlevels - 1 ? \
XFS_BTREE_BLOCK_MAXRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
xfs_bmbt, (lev) == 0) : \
((cur)->bc_mp->m_bmap_dmxr[(lev) != 0])))
#define XFS_BMAP_BLOCK_DMINRECS(lev,cur) \
(((lev) == (cur)->bc_nlevels - 1 ? \
XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_DSIZE(lev,cur),\
xfs_bmdr, (lev) == 0) : \
((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
#define XFS_BMAP_BLOCK_IMINRECS(lev,cur) \
(((lev) == (cur)->bc_nlevels - 1 ? \
XFS_BTREE_BLOCK_MINRECS(XFS_BMAP_RBLOCK_ISIZE(lev,cur),\
xfs_bmbt, (lev) == 0) : \
((cur)->bc_mp->m_bmap_dmnr[(lev) != 0])))
#define XFS_BMAP_REC_DADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i))
#define XFS_BMAP_REC_IADDR(bb,i,cur) (XFS_BTREE_REC_ADDR(xfs_bmbt, bb, i))
#define XFS_BMAP_KEY_DADDR(bb,i,cur) \
(XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i))
#define XFS_BMAP_KEY_IADDR(bb,i,cur) \
(XFS_BTREE_KEY_ADDR(xfs_bmbt, bb, i))
#define XFS_BMAP_PTR_DADDR(bb,i,cur) \
(XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_DMAXRECS( \
be16_to_cpu((bb)->bb_level), cur)))
#define XFS_BMAP_PTR_IADDR(bb,i,cur) \
(XFS_BTREE_PTR_ADDR(xfs_bmbt, bb, i, XFS_BMAP_BLOCK_IMAXRECS( \
be16_to_cpu((bb)->bb_level), cur)))
/*
* Btree block header size depends on a superblock flag.
*
* (not quite yet, but soon)
*/
#define XFS_BMBT_BLOCK_LEN(mp) XFS_BTREE_LBLOCK_LEN
#define XFS_BMBT_REC_ADDR(mp, block, index) \
((xfs_bmbt_rec_t *) \
((char *)(block) + \
XFS_BMBT_BLOCK_LEN(mp) + \
((index) - 1) * sizeof(xfs_bmbt_rec_t)))
#define XFS_BMBT_KEY_ADDR(mp, block, index) \
((xfs_bmbt_key_t *) \
((char *)(block) + \
XFS_BMBT_BLOCK_LEN(mp) + \
((index) - 1) * sizeof(xfs_bmbt_key_t)))
#define XFS_BMBT_PTR_ADDR(mp, block, index, maxrecs) \
((xfs_bmbt_ptr_t *) \
((char *)(block) + \
XFS_BMBT_BLOCK_LEN(mp) + \
(maxrecs) * sizeof(xfs_bmbt_key_t) + \
((index) - 1) * sizeof(xfs_bmbt_ptr_t)))
#define XFS_BMDR_REC_ADDR(block, index) \
((xfs_bmdr_rec_t *) \
((char *)(block) + \
sizeof(struct xfs_bmdr_block) + \
((index) - 1) * sizeof(xfs_bmdr_rec_t)))
#define XFS_BMDR_KEY_ADDR(block, index) \
((xfs_bmdr_key_t *) \
((char *)(block) + \
sizeof(struct xfs_bmdr_block) + \
((index) - 1) * sizeof(xfs_bmdr_key_t)))
#define XFS_BMDR_PTR_ADDR(block, index, maxrecs) \
((xfs_bmdr_ptr_t *) \
((char *)(block) + \
sizeof(struct xfs_bmdr_block) + \
(maxrecs) * sizeof(xfs_bmdr_key_t) + \
((index) - 1) * sizeof(xfs_bmdr_ptr_t)))
/*
* These are to be used when we know the size of the block and
* we don't have a cursor.
*/
#define XFS_BMAP_BROOT_REC_ADDR(bb,i,sz) \
(XFS_BTREE_REC_ADDR(xfs_bmbt,bb,i))
#define XFS_BMAP_BROOT_KEY_ADDR(bb,i,sz) \
(XFS_BTREE_KEY_ADDR(xfs_bmbt,bb,i))
#define XFS_BMAP_BROOT_PTR_ADDR(bb,i,sz) \
(XFS_BTREE_PTR_ADDR(xfs_bmbt,bb,i,XFS_BMAP_BROOT_MAXRECS(sz)))
#define XFS_BMAP_BROOT_NUMRECS(bb) be16_to_cpu((bb)->bb_numrecs)
#define XFS_BMAP_BROOT_MAXRECS(sz) XFS_BTREE_BLOCK_MAXRECS(sz,xfs_bmbt,0)
#define XFS_BMAP_BROOT_PTR_ADDR(mp, bb, i, sz) \
XFS_BMBT_PTR_ADDR(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0))
#define XFS_BMAP_BROOT_SPACE_CALC(nrecs) \
(int)(sizeof(xfs_bmbt_block_t) + \
(int)(XFS_BTREE_LBLOCK_LEN + \
((nrecs) * (sizeof(xfs_bmbt_key_t) + sizeof(xfs_bmbt_ptr_t))))
#define XFS_BMAP_BROOT_SPACE(bb) \
......@@ -223,42 +213,12 @@ typedef struct xfs_btree_lblock xfs_bmbt_block_t;
*/
#define XFS_BM_MAXLEVELS(mp,w) ((mp)->m_bm_maxlevels[(w)])
#define XFS_BMAP_SANITY_CHECK(mp,bb,level) \
(be32_to_cpu((bb)->bb_magic) == XFS_BMAP_MAGIC && \
be16_to_cpu((bb)->bb_level) == level && \
be16_to_cpu((bb)->bb_numrecs) > 0 && \
be16_to_cpu((bb)->bb_numrecs) <= (mp)->m_bmap_dmxr[(level) != 0])
#ifdef __KERNEL__
#if defined(XFS_BMBT_TRACE)
/*
* Trace buffer entry types.
*/
#define XFS_BMBT_KTRACE_ARGBI 1
#define XFS_BMBT_KTRACE_ARGBII 2
#define XFS_BMBT_KTRACE_ARGFFFI 3
#define XFS_BMBT_KTRACE_ARGI 4
#define XFS_BMBT_KTRACE_ARGIFK 5
#define XFS_BMBT_KTRACE_ARGIFR 6
#define XFS_BMBT_KTRACE_ARGIK 7
#define XFS_BMBT_KTRACE_CUR 8
#define XFS_BMBT_TRACE_SIZE 4096 /* size of global trace buffer */
#define XFS_BMBT_KTRACE_SIZE 32 /* size of per-inode trace buffer */
extern ktrace_t *xfs_bmbt_trace_buf;
#endif
/*
* Prototypes for xfs_bmap.c to call.
*/
extern void xfs_bmdr_to_bmbt(xfs_bmdr_block_t *, int, xfs_bmbt_block_t *, int);
extern int xfs_bmbt_decrement(struct xfs_btree_cur *, int, int *);
extern int xfs_bmbt_delete(struct xfs_btree_cur *, int *);
extern void xfs_bmdr_to_bmbt(struct xfs_mount *, xfs_bmdr_block_t *, int,
struct xfs_btree_block *, int);
extern void xfs_bmbt_get_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
extern xfs_bmbt_block_t *xfs_bmbt_get_block(struct xfs_btree_cur *cur,
int, struct xfs_buf **bpp);
extern xfs_filblks_t xfs_bmbt_get_blockcount(xfs_bmbt_rec_host_t *r);
extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r);
extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r);
......@@ -268,22 +228,6 @@ extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
extern int xfs_bmbt_increment(struct xfs_btree_cur *, int, int *);
extern int xfs_bmbt_insert(struct xfs_btree_cur *, int *);
extern void xfs_bmbt_log_block(struct xfs_btree_cur *, struct xfs_buf *, int);
extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int,
int);
extern int xfs_bmbt_lookup_eq(struct xfs_btree_cur *, xfs_fileoff_t,
xfs_fsblock_t, xfs_filblks_t, int *);
extern int xfs_bmbt_lookup_ge(struct xfs_btree_cur *, xfs_fileoff_t,
xfs_fsblock_t, xfs_filblks_t, int *);
/*
* Give the bmap btree a new root block. Copy the old broot contents
* down into a real block and make the broot point to it.
*/
extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat);
extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);
extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o,
xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
......@@ -296,10 +240,15 @@ extern void xfs_bmbt_disk_set_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
extern void xfs_bmbt_disk_set_allf(xfs_bmbt_rec_t *r, xfs_fileoff_t o,
xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v);
extern void xfs_bmbt_to_bmdr(xfs_bmbt_block_t *, int, xfs_bmdr_block_t *, int);
extern int xfs_bmbt_update(struct xfs_btree_cur *, xfs_fileoff_t,
xfs_fsblock_t, xfs_filblks_t, xfs_exntst_t);
extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,
xfs_bmdr_block_t *, int);
extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);
extern int xfs_bmdr_maxrecs(struct xfs_mount *, int blocklen, int leaf);
extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf);
extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *,
struct xfs_trans *, struct xfs_inode *, int);
#endif /* __KERNEL__ */
#endif /* __XFS_BMAP_BTREE_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1566,11 +1566,14 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
int nmap, error, w, count, c, got, i, mapi;
xfs_trans_t *tp;
xfs_mount_t *mp;
xfs_drfsbno_t nblks;
dp = args->dp;
mp = dp->i_mount;
w = args->whichfork;
tp = args->trans;
nblks = dp->i_d.di_nblocks;
/*
* For new directories adjust the file offset and block count.
*/
......@@ -1647,6 +1650,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
}
if (mapp != &map)
kmem_free(mapp);
/* account for newly allocated blocks in reserved blocks total */
args->total -= dp->i_d.di_nblocks - nblks;
*new_blkno = (xfs_dablk_t)bno;
return 0;
}
......
This diff is collapsed.
......@@ -78,8 +78,7 @@ typedef struct xfs_dinode
xfs_dinode_core_t di_core;
/*
* In adding anything between the core and the union, be
* sure to update the macros like XFS_LITINO below and
* XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h.
* sure to update the macros like XFS_LITINO below.
*/
__be32 di_next_unlinked;/* agi unlinked list ptr */
union {
......@@ -166,7 +165,7 @@ typedef enum xfs_dinode_fmt
*/
#define XFS_LITINO(mp) ((mp)->m_litino)
#define XFS_BROOT_SIZE_ADJ \
(sizeof(xfs_bmbt_block_t) - sizeof(xfs_bmdr_block_t))
(XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t))
/*
* Inode data & attribute fork sizes, per inode.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -30,11 +30,9 @@ typedef struct xfs_imap {
ushort im_boffset; /* inode offset in block in bytes */
} xfs_imap_t;
#ifdef __KERNEL__
struct xfs_mount;
struct xfs_trans;
int xfs_imap(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
xfs_imap_t *, uint);
#endif
#endif /* __XFS_IMAP_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment