Commit 8651ba07 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://xfs.org:8090/xfs-linux-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents f4cc0838 20abba2c
......@@ -30,7 +30,7 @@
# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
#
EXTRA_CFLAGS += -Ifs/xfs -funsigned-char
EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux -funsigned-char
ifeq ($(CONFIG_XFS_DEBUG),y)
EXTRA_CFLAGS += -g -DSTATIC="" -DDEBUG -DXFSDEBUG
......@@ -83,6 +83,7 @@ xfs-y += xfs_alloc.o \
xfs_alloc_btree.o \
xfs_attr.o \
xfs_attr_leaf.o \
xfs_behavior.o \
xfs_bit.o \
xfs_bmap.o \
xfs_bmap_btree.o \
......@@ -106,6 +107,7 @@ xfs-y += xfs_alloc.o \
xfs_inode.o \
xfs_inode_item.o \
xfs_iocore.o \
xfs_iomap.o \
xfs_itable.o \
xfs_dfrag.o \
xfs_log.o \
......@@ -126,18 +128,15 @@ xfs-y += xfs_alloc.o \
xfs-$(CONFIG_XFS_TRACE) += xfs_dir2_trace.o
# Objects in pagebuf/
xfs-y += pagebuf/page_buf.o
# Objects in linux/
xfs-y += $(addprefix linux/, \
mrlock.o \
xfs_aops.o \
xfs_behavior.o \
xfs_buf.o \
xfs_file.o \
xfs_fs_subr.o \
xfs_globals.o \
xfs_ioctl.o \
xfs_iomap.o \
xfs_iops.o \
xfs_lrw.o \
xfs_super.o \
......@@ -148,7 +147,6 @@ xfs-y += $(addprefix linux/, \
xfs-y += $(addprefix support/, \
debug.o \
move.o \
mrlock.o \
qsort.o \
uuid.o)
......
......@@ -90,7 +90,7 @@ kmem_flags_convert(int flags)
lflags = (flags & KM_NOSLEEP) ? GFP_ATOMIC : (GFP_KERNEL|__GFP_NOFAIL);
/* avoid recusive callbacks to filesystem during transactions */
if (PFLAGS_TEST_FSTRANS())
if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
lflags &= ~__GFP_FS;
return lflags;
......
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
* Portions Copyright (c) 2002 Christoph Hellwig. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
......
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
* Portions Copyright (c) 2002 Christoph Hellwig. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
......
/*
* Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
* Portions Copyright (c) 2002 Christoph Hellwig. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
......
......@@ -45,7 +45,6 @@
*
*/
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/errno.h>
#include <linux/slab.h>
......@@ -62,9 +61,12 @@
#include <support/ktrace.h>
#include <support/debug.h>
#include <support/kmem.h>
#include "kmem.h"
#include "page_buf.h"
#include "xfs_types.h"
#include "xfs_cred.h"
#include "xfs_lrw.h"
#include "xfs_buf.h"
#define BBSHIFT 9
#define BN_ALIGN_MASK ((1 << (PAGE_CACHE_SHIFT - BBSHIFT)) - 1)
......@@ -78,7 +80,7 @@
*/
STATIC kmem_cache_t *pagebuf_cache;
STATIC void pagebuf_daemon_wakeup(int);
STATIC void pagebuf_daemon_wakeup(void);
STATIC void pagebuf_delwri_queue(page_buf_t *, int);
STATIC struct workqueue_struct *pagebuf_logio_workqueue;
STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
......@@ -164,7 +166,6 @@ pagebuf_trace(
NULL, NULL, NULL, NULL, NULL);
}
ktrace_t *pagebuf_trace_buf;
EXPORT_SYMBOL(pagebuf_trace_buf);
#define PAGEBUF_TRACE_SIZE 4096
#define PB_TRACE(pb, id, data) \
pagebuf_trace(pb, id, (void *)data, (void *)__builtin_return_address(0))
......@@ -190,10 +191,14 @@ EXPORT_SYMBOL(pagebuf_trace_buf);
(((flags) & PBF_READ_AHEAD) ? GFP_READAHEAD : \
((flags) & PBF_DONT_BLOCK) ? GFP_NOFS : GFP_KERNEL)
#define pb_to_km(flags) \
(((flags) & PBF_DONT_BLOCK) ? KM_NOFS : KM_SLEEP)
#define pagebuf_allocate(flags) \
kmem_cache_alloc(pagebuf_cache, pb_to_gfp(flags))
kmem_zone_alloc(pagebuf_cache, pb_to_km(flags))
#define pagebuf_deallocate(pb) \
kmem_cache_free(pagebuf_cache, (pb));
kmem_zone_free(pagebuf_cache, (pb));
/*
* Pagebuf hashing
......@@ -204,7 +209,6 @@ EXPORT_SYMBOL(pagebuf_trace_buf);
typedef struct {
struct list_head pb_hash;
int pb_count;
spinlock_t pb_hash_lock;
} pb_hash_t;
......@@ -375,53 +379,55 @@ _pagebuf_freepages(
}
/*
* _pagebuf_free_object
* pagebuf_free
*
* _pagebuf_free_object releases the contents specified buffer.
* The modification state of any associated pages is left unchanged.
* pagebuf_free releases the specified buffer. The modification
* state of any associated pages is left unchanged.
*/
void
_pagebuf_free_object(
pb_hash_t *hash, /* hash bucket for buffer */
page_buf_t *pb) /* buffer to deallocate */
pagebuf_free(
page_buf_t *pb)
{
page_buf_flags_t pb_flags = pb->pb_flags;
PB_TRACE(pb, "free", 0);
PB_TRACE(pb, "free_object", 0);
pb->pb_flags |= PBF_FREED;
if (pb->pb_flags & _PBF_LOCKABLE) {
pb_hash_t *hash = pb_hash(pb);
if (hash) {
if (!list_empty(&pb->pb_hash_list)) {
hash->pb_count--;
spin_lock(&hash->pb_hash_lock);
/*
* Someone grabbed a reference while we weren't looking,
* try again later.
*/
if (unlikely(atomic_read(&pb->pb_hold))) {
spin_unlock(&hash->pb_hash_lock);
return;
} else if (!list_empty(&pb->pb_hash_list))
list_del_init(&pb->pb_hash_list);
}
spin_unlock(&hash->pb_hash_lock);
}
if (!(pb_flags & PBF_FREED)) {
/* release any virtual mapping */ ;
if (pb->pb_flags & _PBF_ADDR_ALLOCATED) {
void *vaddr = pagebuf_mapout_locked(pb);
if (vaddr) {
free_address(vaddr);
}
/* release any virtual mapping */ ;
if (pb->pb_flags & _PBF_ADDR_ALLOCATED) {
void *vaddr = pagebuf_mapout_locked(pb);
if (vaddr) {
free_address(vaddr);
}
}
if (pb->pb_flags & _PBF_MEM_ALLOCATED) {
if (pb->pb_pages) {
/* release the pages in the address list */
if ((pb->pb_pages[0]) &&
(pb->pb_flags & _PBF_MEM_SLAB)) {
kfree(pb->pb_addr);
} else {
_pagebuf_freepages(pb);
}
if (pb->pb_pages != pb->pb_page_array)
kfree(pb->pb_pages);
pb->pb_pages = NULL;
if (pb->pb_flags & _PBF_MEM_ALLOCATED) {
if (pb->pb_pages) {
/* release the pages in the address list */
if ((pb->pb_pages[0]) &&
(pb->pb_flags & _PBF_MEM_SLAB)) {
kfree(pb->pb_addr);
} else {
_pagebuf_freepages(pb);
}
pb->pb_flags &= ~(_PBF_MEM_ALLOCATED|_PBF_MEM_SLAB);
if (pb->pb_pages != pb->pb_page_array)
kfree(pb->pb_pages);
pb->pb_pages = NULL;
}
pb->pb_flags &= ~(_PBF_MEM_ALLOCATED|_PBF_MEM_SLAB);
}
pagebuf_deallocate(pb);
......@@ -509,7 +515,7 @@ _pagebuf_lookup_pages(
if (!page) {
if (--retry_count > 0) {
PB_STATS_INC(pb_page_retries);
pagebuf_daemon_wakeup(1);
pagebuf_daemon_wakeup();
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(10);
goto retry;
......@@ -646,16 +652,15 @@ _pagebuf_find( /* find buffer for block */
list_for_each(p, &h->pb_hash) {
pb = list_entry(p, page_buf_t, pb_hash_list);
if ((target == pb->pb_target) &&
(pb->pb_file_offset == range_base) &&
(pb->pb_buffer_length == range_length)) {
if (pb->pb_flags & PBF_FREED)
break;
if (pb->pb_target == target &&
pb->pb_file_offset == range_base &&
pb->pb_buffer_length == range_length &&
atomic_read(&pb->pb_hold)) {
/* If we look at something bring it to the
* front of the list for next time
*/
list_del(&pb->pb_hash_list);
list_add(&pb->pb_hash_list, &h->pb_hash);
atomic_inc(&pb->pb_hold);
list_move(&pb->pb_hash_list, &h->pb_hash);
goto found;
}
}
......@@ -665,7 +670,6 @@ _pagebuf_find( /* find buffer for block */
_pagebuf_initialize(new_pb, target, range_base,
range_length, flags | _PBF_LOCKABLE);
new_pb->pb_hash_index = hval;
h->pb_count++;
list_add(&new_pb->pb_hash_list, &h->pb_hash);
} else {
PB_STATS_INC(pb_miss_locked);
......@@ -675,7 +679,6 @@ _pagebuf_find( /* find buffer for block */
return (new_pb);
found:
atomic_inc(&pb->pb_hold);
spin_unlock(&h->pb_hash_lock);
/* Attempt to get the semaphore without sleeping,
......@@ -996,26 +999,6 @@ pagebuf_hold(
PB_TRACE(pb, "hold", 0);
}
/*
* pagebuf_free
*
* pagebuf_free releases the specified buffer. The modification
* state of any associated pages is left unchanged.
*/
void
pagebuf_free(
page_buf_t *pb)
{
if (pb->pb_flags & _PBF_LOCKABLE) {
pb_hash_t *h = pb_hash(pb);
spin_lock(&h->pb_hash_lock);
_pagebuf_free_object(h, pb);
} else {
_pagebuf_free_object(NULL, pb);
}
}
/*
* pagebuf_rele
*
......@@ -1026,44 +1009,28 @@ void
pagebuf_rele(
page_buf_t *pb)
{
pb_hash_t *h;
PB_TRACE(pb, "rele", pb->pb_relse);
if (pb->pb_flags & _PBF_LOCKABLE) {
h = pb_hash(pb);
spin_lock(&h->pb_hash_lock);
} else {
h = NULL;
}
if (atomic_dec_and_test(&pb->pb_hold)) {
int do_free = 1;
if (pb->pb_relse) {
atomic_inc(&pb->pb_hold);
if (h)
spin_unlock(&h->pb_hash_lock);
(*(pb->pb_relse)) (pb);
do_free = 0;
}
if (pb->pb_flags & PBF_DELWRI) {
pb->pb_flags |= PBF_ASYNC;
atomic_inc(&pb->pb_hold);
if (h && do_free)
spin_unlock(&h->pb_hash_lock);
pagebuf_delwri_queue(pb, 0);
do_free = 0;
} else if (pb->pb_flags & PBF_FS_MANAGED) {
if (h)
spin_unlock(&h->pb_hash_lock);
do_free = 0;
}
if (do_free) {
_pagebuf_free_object(h, pb);
pagebuf_free(pb);
}
} else if (h) {
spin_unlock(&h->pb_hash_lock);
}
}
......@@ -1676,7 +1643,6 @@ pagebuf_iomove(
* Pagebuf delayed write buffer handling
*/
STATIC int pbd_active = 1;
STATIC LIST_HEAD(pbd_delwrite_queue);
STATIC spinlock_t pbd_delwrite_lock = SPIN_LOCK_UNLOCKED;
......@@ -1723,21 +1689,19 @@ pagebuf_runall_queues(
}
/* Defines for pagebuf daemon */
DECLARE_WAIT_QUEUE_HEAD(pbd_waitq);
STATIC DECLARE_COMPLETION(pagebuf_daemon_done);
STATIC struct task_struct *pagebuf_daemon_task;
STATIC int pagebuf_daemon_active;
STATIC int force_flush;
STATIC void
pagebuf_daemon_wakeup(
int flag)
pagebuf_daemon_wakeup(void)
{
force_flush = flag;
if (waitqueue_active(&pbd_waitq)) {
wake_up_interruptible(&pbd_waitq);
}
force_flush = 1;
barrier();
wake_up_process(pagebuf_daemon_task);
}
typedef void (*timeout_fn)(unsigned long);
STATIC int
pagebuf_daemon(
void *data)
......@@ -1745,29 +1709,23 @@ pagebuf_daemon(
int count;
page_buf_t *pb;
struct list_head *curr, *next, tmp;
struct timer_list pb_daemon_timer =
TIMER_INITIALIZER((timeout_fn)pagebuf_daemon_wakeup, 0, 0);
/* Set up the thread */
daemonize("pagebufd");
current->flags |= PF_MEMALLOC;
pagebuf_daemon_task = current;
pagebuf_daemon_active = 1;
barrier();
INIT_LIST_HEAD(&tmp);
do {
/* swsusp */
if (current->flags & PF_FREEZE)
refrigerator(PF_IOTHREAD);
if (pbd_active == 1) {
mod_timer(&pb_daemon_timer,
jiffies + pb_params.flush_interval.val);
interruptible_sleep_on(&pbd_waitq);
}
if (pbd_active == 0) {
del_timer_sync(&pb_daemon_timer);
}
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(pb_params.flush_interval.val);
spin_lock(&pbd_delwrite_lock);
......@@ -1811,12 +1769,9 @@ pagebuf_daemon(
blk_run_queues();
force_flush = 0;
} while (pbd_active == 1);
pbd_active = -1;
wake_up_interruptible(&pbd_waitq);
} while (pagebuf_daemon_active);
return 0;
complete_and_exit(&pagebuf_daemon_done, 0);
}
void
......@@ -1926,9 +1881,10 @@ pagebuf_daemon_start(void)
STATIC void
pagebuf_daemon_stop(void)
{
pbd_active = 0;
wake_up_interruptible(&pbd_waitq);
wait_event_interruptible(pbd_waitq, pbd_active);
pagebuf_daemon_active = 0;
barrier();
wait_for_completion(&pagebuf_daemon_done);
destroy_workqueue(pagebuf_logio_workqueue);
destroy_workqueue(pagebuf_dataio_workqueue);
}
......@@ -2088,6 +2044,10 @@ pagebuf_terminate(void)
{
pagebuf_daemon_stop();
#ifdef PAGEBUF_TRACE
ktrace_free(pagebuf_trace_buf);
#endif
kmem_cache_destroy(pagebuf_cache);
unregister_sysctl_table(pagebuf_table_header);
......@@ -2096,12 +2056,3 @@ pagebuf_terminate(void)
remove_proc_entry("fs/pagebuf", NULL);
#endif
}
/*
* Module management (for kernel debugger module)
*/
EXPORT_SYMBOL(pagebuf_offset);
#ifdef DEBUG
EXPORT_SYMBOL(pbd_delwrite_queue);
#endif
......@@ -34,8 +34,8 @@
* Written by Steve Lord, Jim Mostek, Russell Cattelan at SGI
*/
#ifndef __PAGE_BUF_H__
#define __PAGE_BUF_H__
#ifndef __XFS_BUF_H__
#define __XFS_BUF_H__
#include <linux/config.h>
#include <linux/list.h>
......@@ -76,7 +76,6 @@ typedef enum page_buf_flags_e { /* pb_flags values */
PBF_ASYNC = (1 << 4), /* initiator will not wait for completion */
PBF_NONE = (1 << 5), /* buffer not read at all */
PBF_DELWRI = (1 << 6), /* buffer has dirty pages */
PBF_FREED = (1 << 7), /* buffer has been freed and is invalid */
PBF_SYNC = (1 << 8), /* force updates to disk */
PBF_MAPPABLE = (1 << 9),/* use directly-addressable pages */
PBF_STALE = (1 << 10), /* buffer has been staled, do not find it */
......@@ -90,7 +89,6 @@ typedef enum page_buf_flags_e { /* pb_flags values */
/* flags used only internally */
_PBF_LOCKABLE = (1 << 16), /* page_buf_t may be locked */
_PBF_PRIVATE_BH = (1 << 17), /* do not use public buffer heads */
_PBF_ALL_PAGES_MAPPED = (1 << 18), /* all pages in range mapped */
_PBF_ADDR_ALLOCATED = (1 << 19), /* pb_addr space was allocated */
_PBF_MEM_ALLOCATED = (1 << 20), /* underlying pages are allocated */
......@@ -337,4 +335,282 @@ extern void pagebuf_trace(
#define pagebuf_target_name(target) \
({ char __b[BDEVNAME_SIZE]; bdevname((target)->pbr_bdev, __b); __b; })
#endif /* __PAGE_BUF_H__ */
/* These are just for xfs_syncsub... it sets an internal variable
* then passes it to VOP_FLUSH_PAGES or adds the flags to a newly gotten buf_t
*/
#define XFS_B_ASYNC PBF_ASYNC
#define XFS_B_DELWRI PBF_DELWRI
#define XFS_B_READ PBF_READ
#define XFS_B_WRITE PBF_WRITE
#define XFS_B_STALE PBF_STALE
#define XFS_BUF_TRYLOCK PBF_TRYLOCK
#define XFS_INCORE_TRYLOCK PBF_TRYLOCK
#define XFS_BUF_LOCK PBF_LOCK
#define XFS_BUF_MAPPED PBF_MAPPED
#define BUF_BUSY PBF_DONT_BLOCK
#define XFS_BUF_BFLAGS(x) ((x)->pb_flags)
#define XFS_BUF_ZEROFLAGS(x) \
((x)->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_DELWRI))
#define XFS_BUF_STALE(x) ((x)->pb_flags |= XFS_B_STALE)
#define XFS_BUF_UNSTALE(x) ((x)->pb_flags &= ~XFS_B_STALE)
#define XFS_BUF_ISSTALE(x) ((x)->pb_flags & XFS_B_STALE)
#define XFS_BUF_SUPER_STALE(x) do { \
XFS_BUF_STALE(x); \
xfs_buf_undelay(x); \
XFS_BUF_DONE(x); \
} while (0)
#define XFS_BUF_MANAGE PBF_FS_MANAGED
#define XFS_BUF_UNMANAGE(x) ((x)->pb_flags &= ~PBF_FS_MANAGED)
static inline void xfs_buf_undelay(page_buf_t *pb)
{
if (pb->pb_flags & PBF_DELWRI) {
if (pb->pb_list.next != &pb->pb_list) {
pagebuf_delwri_dequeue(pb);
pagebuf_rele(pb);
} else {
pb->pb_flags &= ~PBF_DELWRI;
}
}
}
#define XFS_BUF_DELAYWRITE(x) ((x)->pb_flags |= PBF_DELWRI)
#define XFS_BUF_UNDELAYWRITE(x) xfs_buf_undelay(x)
#define XFS_BUF_ISDELAYWRITE(x) ((x)->pb_flags & PBF_DELWRI)
#define XFS_BUF_ERROR(x,no) pagebuf_ioerror(x,no)
#define XFS_BUF_GETERROR(x) pagebuf_geterror(x)
#define XFS_BUF_ISERROR(x) (pagebuf_geterror(x)?1:0)
#define XFS_BUF_DONE(x) ((x)->pb_flags &= ~(PBF_PARTIAL|PBF_NONE))
#define XFS_BUF_UNDONE(x) ((x)->pb_flags |= PBF_PARTIAL|PBF_NONE)
#define XFS_BUF_ISDONE(x) (!(PBF_NOT_DONE(x)))
#define XFS_BUF_BUSY(x) ((x)->pb_flags |= PBF_FORCEIO)
#define XFS_BUF_UNBUSY(x) ((x)->pb_flags &= ~PBF_FORCEIO)
#define XFS_BUF_ISBUSY(x) (1)
#define XFS_BUF_ASYNC(x) ((x)->pb_flags |= PBF_ASYNC)
#define XFS_BUF_UNASYNC(x) ((x)->pb_flags &= ~PBF_ASYNC)
#define XFS_BUF_ISASYNC(x) ((x)->pb_flags & PBF_ASYNC)
#define XFS_BUF_FLUSH(x) ((x)->pb_flags |= PBF_FLUSH)
#define XFS_BUF_UNFLUSH(x) ((x)->pb_flags &= ~PBF_FLUSH)
#define XFS_BUF_ISFLUSH(x) ((x)->pb_flags & PBF_FLUSH)
#define XFS_BUF_SHUT(x) printk("XFS_BUF_SHUT not implemented yet\n")
#define XFS_BUF_UNSHUT(x) printk("XFS_BUF_UNSHUT not implemented yet\n")
#define XFS_BUF_ISSHUT(x) (0)
#define XFS_BUF_HOLD(x) pagebuf_hold(x)
#define XFS_BUF_READ(x) ((x)->pb_flags |= PBF_READ)
#define XFS_BUF_UNREAD(x) ((x)->pb_flags &= ~PBF_READ)
#define XFS_BUF_ISREAD(x) ((x)->pb_flags & PBF_READ)
#define XFS_BUF_WRITE(x) ((x)->pb_flags |= PBF_WRITE)
#define XFS_BUF_UNWRITE(x) ((x)->pb_flags &= ~PBF_WRITE)
#define XFS_BUF_ISWRITE(x) ((x)->pb_flags & PBF_WRITE)
#define XFS_BUF_ISUNINITIAL(x) (0)
#define XFS_BUF_UNUNINITIAL(x) (0)
#define XFS_BUF_BP_ISMAPPED(bp) 1
typedef struct page_buf_s xfs_buf_t;
#define xfs_buf page_buf_s
typedef struct pb_target xfs_buftarg_t;
#define xfs_buftarg pb_target
#define XFS_BUF_DATAIO(x) ((x)->pb_flags |= PBF_FS_DATAIOD)
#define XFS_BUF_UNDATAIO(x) ((x)->pb_flags &= ~PBF_FS_DATAIOD)
#define XFS_BUF_IODONE_FUNC(buf) (buf)->pb_iodone
#define XFS_BUF_SET_IODONE_FUNC(buf, func) \
(buf)->pb_iodone = (func)
#define XFS_BUF_CLR_IODONE_FUNC(buf) \
(buf)->pb_iodone = NULL
#define XFS_BUF_SET_BDSTRAT_FUNC(buf, func) \
(buf)->pb_strat = (func)
#define XFS_BUF_CLR_BDSTRAT_FUNC(buf) \
(buf)->pb_strat = NULL
#define XFS_BUF_FSPRIVATE(buf, type) \
((type)(buf)->pb_fspriv)
#define XFS_BUF_SET_FSPRIVATE(buf, value) \
(buf)->pb_fspriv = (void *)(value)
#define XFS_BUF_FSPRIVATE2(buf, type) \
((type)(buf)->pb_fspriv2)
#define XFS_BUF_SET_FSPRIVATE2(buf, value) \
(buf)->pb_fspriv2 = (void *)(value)
#define XFS_BUF_FSPRIVATE3(buf, type) \
((type)(buf)->pb_fspriv3)
#define XFS_BUF_SET_FSPRIVATE3(buf, value) \
(buf)->pb_fspriv3 = (void *)(value)
#define XFS_BUF_SET_START(buf)
#define XFS_BUF_SET_BRELSE_FUNC(buf, value) \
(buf)->pb_relse = (value)
#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->pb_addr)
extern inline xfs_caddr_t xfs_buf_offset(page_buf_t *bp, size_t offset)
{
if (bp->pb_flags & PBF_MAPPED)
return XFS_BUF_PTR(bp) + offset;
return (xfs_caddr_t) pagebuf_offset(bp, offset);
}
#define XFS_BUF_SET_PTR(bp, val, count) \
pagebuf_associate_memory(bp, val, count)
#define XFS_BUF_ADDR(bp) ((bp)->pb_bn)
#define XFS_BUF_SET_ADDR(bp, blk) \
((bp)->pb_bn = (page_buf_daddr_t)(blk))
#define XFS_BUF_OFFSET(bp) ((bp)->pb_file_offset)
#define XFS_BUF_SET_OFFSET(bp, off) \
((bp)->pb_file_offset = (off))
#define XFS_BUF_COUNT(bp) ((bp)->pb_count_desired)
#define XFS_BUF_SET_COUNT(bp, cnt) \
((bp)->pb_count_desired = (cnt))
#define XFS_BUF_SIZE(bp) ((bp)->pb_buffer_length)
#define XFS_BUF_SET_SIZE(bp, cnt) \
((bp)->pb_buffer_length = (cnt))
#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
#define XFS_BUF_SET_VTYPE(bp, type)
#define XFS_BUF_SET_REF(bp, ref)
#define XFS_BUF_ISPINNED(bp) pagebuf_ispin(bp)
#define XFS_BUF_VALUSEMA(bp) pagebuf_lock_value(bp)
#define XFS_BUF_CPSEMA(bp) (pagebuf_cond_lock(bp) == 0)
#define XFS_BUF_VSEMA(bp) pagebuf_unlock(bp)
#define XFS_BUF_PSEMA(bp,x) pagebuf_lock(bp)
#define XFS_BUF_V_IODONESEMA(bp) up(&bp->pb_iodonesema);
/* setup the buffer target from a buftarg structure */
#define XFS_BUF_SET_TARGET(bp, target) \
(bp)->pb_target = (target)
#define XFS_BUF_TARGET(bp) ((bp)->pb_target)
#define XFS_BUFTARG_NAME(target) \
pagebuf_target_name(target)
#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
#define XFS_BUF_SET_VTYPE(bp, type)
#define XFS_BUF_SET_REF(bp, ref)
#define xfs_buf_read(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_LOCK | PBF_READ | PBF_MAPPED | PBF_MAPPABLE)
#define xfs_buf_get(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_LOCK | PBF_MAPPED | PBF_MAPPABLE)
#define xfs_buf_read_flags(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_READ | PBF_MAPPABLE | flags)
#define xfs_buf_get_flags(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_MAPPABLE | flags)
static inline int xfs_bawrite(void *mp, page_buf_t *bp)
{
bp->pb_fspriv3 = mp;
bp->pb_strat = xfs_bdstrat_cb;
xfs_buf_undelay(bp);
return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | PBF_RUN_QUEUES);
}
static inline void xfs_buf_relse(page_buf_t *bp)
{
if ((bp->pb_flags & _PBF_LOCKABLE) && !bp->pb_relse)
pagebuf_unlock(bp);
pagebuf_rele(bp);
}
#define xfs_bpin(bp) pagebuf_pin(bp)
#define xfs_bunpin(bp) pagebuf_unpin(bp)
#define xfs_buftrace(id, bp) \
pagebuf_trace(bp, id, NULL, (void *)__builtin_return_address(0))
#define xfs_biodone(pb) \
pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), 0)
#define xfs_incore(buftarg,blkno,len,lockit) \
pagebuf_find(buftarg, blkno ,len, lockit)
#define xfs_biomove(pb, off, len, data, rw) \
pagebuf_iomove((pb), (off), (len), (data), \
((rw) == XFS_B_WRITE) ? PBRW_WRITE : PBRW_READ)
#define xfs_biozero(pb, off, len) \
pagebuf_iomove((pb), (off), (len), NULL, PBRW_ZERO)
static inline int XFS_bwrite(page_buf_t *pb)
{
int iowait = (pb->pb_flags & PBF_ASYNC) == 0;
int error = 0;
pb->pb_flags |= PBF_SYNC;
if (!iowait)
pb->pb_flags |= PBF_RUN_QUEUES;
xfs_buf_undelay(pb);
pagebuf_iostrategy(pb);
if (iowait) {
error = pagebuf_iowait(pb);
xfs_buf_relse(pb);
}
return error;
}
#define XFS_bdwrite(pb) \
pagebuf_iostart(pb, PBF_DELWRI | PBF_ASYNC)
static inline int xfs_bdwrite(void *mp, page_buf_t *bp)
{
bp->pb_strat = xfs_bdstrat_cb;
bp->pb_fspriv3 = mp;
return pagebuf_iostart(bp, PBF_DELWRI | PBF_ASYNC);
}
#define XFS_bdstrat(bp) pagebuf_iorequest(bp)
#define xfs_iowait(pb) pagebuf_iowait(pb)
/*
* Go through all incore buffers, and release buffers
* if they belong to the given device. This is used in
* filesystem error handling to preserve the consistency
* of its metadata.
*/
#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg)
#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg)
#define xfs_incore_relse(buftarg,delwri_only,wait) \
xfs_relse_buftarg(buftarg)
#define xfs_baread(target, rablkno, ralen) \
pagebuf_readahead((target), (rablkno), (ralen), PBF_DONT_BLOCK)
#define xfs_buf_get_empty(len, target) pagebuf_get_empty((len), (target))
#define xfs_buf_get_noaddr(len, target) pagebuf_get_no_daddr((len), (target))
#define xfs_buf_free(bp) pagebuf_free(bp)
#endif /* __XFS_BUF_H__ */
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
......@@ -36,57 +36,8 @@
*/
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_buf.h"
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_clnt.h"
#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"
#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_alloc_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_attr_sf.h"
#include "xfs_dir_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
#include "xfs_bit.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_da_btree.h"
#include "xfs_dir_leaf.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
#include "xfs_dir2_block.h"
#include "xfs_dir2_node.h"
#include "xfs_dir2_trace.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
#include "xfs_inode_item.h"
#include "xfs_buf_item.h"
#include "xfs_extfree_item.h"
#include "xfs_log_priv.h"
#include "xfs_trans_priv.h"
#include "xfs_trans_space.h"
#include "xfs_utils.h"
#include "xfs_cred.h"
#include "xfs_sysctl.h"
/*
* System memory size - used to scale certain data structures in XFS.
......@@ -117,34 +68,3 @@ xfs_param_t xfs_params = {
*/
cred_t sys_cred_val, *sys_cred = &sys_cred_val;
/*
* Export symbols used for XFS debugging
*/
EXPORT_SYMBOL(xfs_next_bit);
EXPORT_SYMBOL(xfs_contig_bits);
EXPORT_SYMBOL(xfs_bmbt_get_all);
#if ARCH_CONVERT != ARCH_NOCONVERT
EXPORT_SYMBOL(xfs_bmbt_disk_get_all);
#endif
/*
* Export symbols used for XFS tracing
*/
#ifdef XFS_ALLOC_TRACE
EXPORT_SYMBOL(xfs_alloc_trace_buf);
#endif
#ifdef XFS_BMAP_TRACE
EXPORT_SYMBOL(xfs_bmap_trace_buf);
#endif
#ifdef XFS_BMBT_TRACE
EXPORT_SYMBOL(xfs_bmbt_trace_buf);
#endif
#ifdef XFS_ATTR_TRACE
EXPORT_SYMBOL(xfs_attr_trace_buf);
#endif
#ifdef XFS_DIR2_TRACE
EXPORT_SYMBOL(xfs_dir2_trace_buf);
#endif
#ifdef XFS_DIR_TRACE
EXPORT_SYMBOL(xfs_dir_trace_buf);
#endif
......@@ -32,6 +32,44 @@
#ifndef __XFS_LINUX__
#define __XFS_LINUX__
#include <linux/types.h>
#include <linux/config.h>
/*
* Some types are conditional depending on the target system.
* XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
* XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well
* as requiring XFS_BIG_BLKNOS to be set.
*/
#if defined(CONFIG_LBD) || (BITS_PER_LONG == 64)
# define XFS_BIG_BLKNOS 1
# if BITS_PER_LONG == 64
# define XFS_BIG_INUMS 1
# else
# define XFS_BIG_INUMS 0
# endif
#else
# define XFS_BIG_BLKNOS 0
# define XFS_BIG_INUMS 0
#endif
#include <xfs_types.h>
#include <xfs_arch.h>
#include <kmem.h>
#include <mrlock.h>
#include <spin.h>
#include <sv.h>
#include <mutex.h>
#include <sema.h>
#include <time.h>
#include <support/qsort.h>
#include <support/ktrace.h>
#include <support/debug.h>
#include <support/move.h>
#include <support/uuid.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/slab.h>
......@@ -55,19 +93,18 @@
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <linux/xfs_behavior.h>
#include <linux/xfs_vfs.h>
#include <linux/xfs_cred.h>
#include <linux/xfs_vnode.h>
#include <linux/xfs_stats.h>
#include <linux/xfs_sysctl.h>
#include <linux/xfs_iops.h>
#include <linux/xfs_super.h>
#include <linux/xfs_globals.h>
#include <linux/xfs_fs_subr.h>
#include <linux/xfs_lrw.h>
#include <pagebuf/page_buf.h>
#include <xfs_behavior.h>
#include <xfs_vfs.h>
#include <xfs_cred.h>
#include <xfs_vnode.h>
#include <xfs_stats.h>
#include <xfs_sysctl.h>
#include <xfs_iops.h>
#include <xfs_super.h>
#include <xfs_globals.h>
#include <xfs_fs_subr.h>
#include <xfs_lrw.h>
#include <xfs_buf.h>
/*
* Feature macros (disable/enable)
......
......@@ -60,6 +60,14 @@
# define set_posix_acl_flag(sb) do { } while (0)
#endif
#ifdef CONFIG_XFS_SECURITY
# define XFS_SECURITY_STRING "security attrs, "
# define ENOSECURITY 0
#else
# define XFS_SECURITY_STRING
# define ENOSECURITY EOPNOTSUPP
#endif
#ifdef CONFIG_XFS_RT
# define XFS_REALTIME_STRING "realtime, "
#else
......@@ -89,6 +97,7 @@
#endif
#define XFS_BUILD_OPTIONS XFS_ACL_STRING \
XFS_SECURITY_STRING \
XFS_REALTIME_STRING \
XFS_BIGFS_STRING \
XFS_TRACE_STRING \
......
......@@ -78,7 +78,6 @@
*/
mutex_t xfs_Gqm_lock;
struct xfs_qm *xfs_Gqm;
EXPORT_SYMBOL(xfs_Gqm); /* used by xfsidbg */
kmem_zone_t *qm_dqzone;
kmem_zone_t *qm_dqtrxzone;
......
......@@ -30,13 +30,12 @@
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <xfs_types.h>
#include "kmem.h"
#include "spin.h"
#include <kmem.h>
#include <spin.h>
#include "debug.h"
#include "ktrace.h"
......@@ -273,7 +272,6 @@ ktrace_first(ktrace_t *ktp, ktrace_snap_t *ktsp)
}
return ktep;
}
EXPORT_SYMBOL(ktrace_first);
/*
* ktrace_next()
......@@ -308,7 +306,6 @@ ktrace_next(
return ktep;
}
EXPORT_SYMBOL(ktrace_next);
/*
* ktrace_skip()
......
......@@ -32,7 +32,7 @@
#ifndef __XFS_SUPPORT_KTRACE_H__
#define __XFS_SUPPORT_KTRACE_H__
#include <support/spin.h>
#include <spin.h>
/*
* Trace buffer entry structure.
......
......@@ -30,14 +30,7 @@
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#include <linux/types.h>
#include <xfs_types.h>
#include <xfs_arch.h>
#include "time.h"
#include "uuid.h"
#include "kmem.h"
#include "debug.h"
#include "mutex.h"
#include <xfs.h>
static mutex_t uuid_monitor;
static int uuid_table_size;
......
......@@ -32,28 +32,8 @@
#ifndef __XFS_H__
#define __XFS_H__
#include <linux/types.h>
#include <linux/config.h>
#include <xfs_types.h>
#include <xfs_arch.h>
#include <support/kmem.h>
#include <support/mrlock.h>
#include <support/qsort.h>
#include <support/spin.h>
#include <support/sv.h>
#include <support/ktrace.h>
#include <support/mutex.h>
#include <support/sema.h>
#include <support/debug.h>
#include <support/move.h>
#include <support/uuid.h>
#include <support/time.h>
#include <linux/xfs_linux.h>
#include <xfs_fs.h>
#include <xfs_buf.h>
#endif /* __XFS_H__ */
......@@ -106,12 +106,11 @@ STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */
#define ATTR_RMTVALUE_TRANSBLKS 8 /* max # of blks in a transaction */
#if defined(DEBUG)
#if defined(XFS_ATTR_TRACE)
ktrace_t *xfs_attr_trace_buf;
#endif
/*========================================================================
* Overall external interface routines.
*========================================================================*/
......@@ -2588,6 +2587,14 @@ attr_trusted_capable(
return 0;
}
STATIC int
attr_secure_capable(
struct vnode *vp,
cred_t *cred)
{
return -ENOSECURITY;
}
STATIC int
attr_system_set(
struct vnode *vp, char *name, void *data, size_t size, int xflags)
......@@ -2651,6 +2658,16 @@ struct attrnames attr_trusted = {
.attr_capable = attr_trusted_capable,
};
struct attrnames attr_secure = {
.attr_name = "security.",
.attr_namelen = sizeof("security.") - 1,
.attr_flag = ATTR_SECURE,
.attr_get = attr_generic_get,
.attr_set = attr_generic_set,
.attr_remove = attr_generic_remove,
.attr_capable = attr_secure_capable,
};
struct attrnames attr_user = {
.attr_name = "user.",
.attr_namelen = sizeof("user.") - 1,
......@@ -2661,4 +2678,4 @@ struct attrnames attr_user = {
};
struct attrnames *attr_namespaces[] =
{ &attr_system, &attr_trusted, &attr_user };
{ &attr_system, &attr_trusted, &attr_secure, &attr_user };
......@@ -69,8 +69,9 @@ typedef struct attrnames {
attrcapable_t attr_capable;
} attrnames_t;
#define ATTR_NAMECOUNT 3
#define ATTR_NAMECOUNT 4
extern struct attrnames attr_user;
extern struct attrnames attr_secure;
extern struct attrnames attr_system;
extern struct attrnames attr_trusted;
extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
......@@ -86,6 +87,7 @@ extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
#define ATTR_TRUST 0x0004 /* -- unused, from IRIX -- */
#define ATTR_SECURE 0x0008 /* use attrs in security namespace */
#define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */
#define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */
#define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */
......
......@@ -159,6 +159,9 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
continue;
if (((args->flags & ATTR_SECURE) != 0) !=
((sfe->flags & XFS_ATTR_SECURE) != 0))
continue;
if (((args->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0))
continue;
......@@ -173,7 +176,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args)
sfe->namelen = args->namelen;
INT_SET(sfe->valuelen, ARCH_CONVERT, args->valuelen);
sfe->flags = (args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0;
sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
memcpy(sfe->nameval, args->name, args->namelen);
memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
INT_MOD(sf->hdr.count, ARCH_CONVERT, 1);
......@@ -209,6 +213,9 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
continue;
if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
continue;
if (((args->flags & ATTR_SECURE) != 0) !=
((sfe->flags & XFS_ATTR_SECURE) != 0))
continue;
if (((args->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0))
continue;
......@@ -253,6 +260,9 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
continue;
if (((args->flags & ATTR_SECURE) != 0) !=
((sfe->flags & XFS_ATTR_SECURE) != 0))
continue;
if (((args->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0))
continue;
......@@ -281,6 +291,9 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args)
continue;
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
continue;
if (((args->flags & ATTR_SECURE) != 0) !=
((sfe->flags & XFS_ATTR_SECURE) != 0))
continue;
if (((args->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0))
continue;
......@@ -369,7 +382,8 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
nargs.valuelen = INT_GET(sfe->valuelen, ARCH_CONVERT);
nargs.hashval = xfs_da_hashname((char *)sfe->nameval,
sfe->namelen);
nargs.flags = (sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0;
nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */
ASSERT(error == ENOATTR);
error = xfs_attr_leaf_add(bp, &nargs);
......@@ -446,14 +460,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
attrnames_t *namesp;
namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user;
if (((context->flags & ATTR_ROOT) != 0) !=
((sfe->flags & XFS_ATTR_ROOT) != 0) &&
!(context->flags & ATTR_KERNFULLS)) {
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
continue;
}
namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure:
((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user);
if (context->flags & ATTR_KERNOVAL) {
ASSERT(context->flags & ATTR_KERNAMELS);
context->count += namesp->attr_namelen +
......@@ -548,8 +563,9 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
for ( ; i < nsbuf; i++, sbp++) {
attrnames_t *namesp;
namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user;
namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure :
((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user);
if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) {
cursor->hashval = INT_GET(sbp->hash, ARCH_CONVERT);
......@@ -668,7 +684,8 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args)
nargs.value = (char *)&name_loc->nameval[nargs.namelen];
nargs.valuelen = INT_GET(name_loc->valuelen, ARCH_CONVERT);
nargs.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
nargs.flags = (entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0;
nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
xfs_attr_shortform_add(&nargs);
}
error = 0;
......@@ -963,7 +980,8 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
+ INT_GET(map->size, ARCH_CONVERT));
INT_SET(entry->hashval, ARCH_CONVERT, args->hashval);
entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
entry->flags |= (args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0;
entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
if (args->rename) {
entry->flags |= XFS_ATTR_INCOMPLETE;
if ((args->blkno2 == args->blkno) &&
......@@ -1881,6 +1899,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
if (memcmp(args->name, (char *)name_loc->nameval,
args->namelen) != 0)
continue;
if (((args->flags & ATTR_SECURE) != 0) !=
((entry->flags & XFS_ATTR_SECURE) != 0))
continue;
if (((args->flags & ATTR_ROOT) != 0) !=
((entry->flags & XFS_ATTR_ROOT) != 0))
continue;
......@@ -1893,6 +1914,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
if (memcmp(args->name, (char *)name_rmt->name,
args->namelen) != 0)
continue;
if (((args->flags & ATTR_SECURE) != 0) !=
((entry->flags & XFS_ATTR_SECURE) != 0))
continue;
if (((args->flags & ATTR_ROOT) != 0) !=
((entry->flags & XFS_ATTR_ROOT) != 0))
continue;
......@@ -2290,8 +2314,9 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
!(context->flags & ATTR_KERNFULLS))
continue; /* skip non-matching entries */
namesp = (entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user;
namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
&attr_user);
if (entry->flags & XFS_ATTR_LOCAL) {
name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
......
......@@ -73,9 +73,9 @@ struct xfs_trans;
* to work "forw"ard. If none matches, continue with the "forw"ard leaf
* nodes until the hash key changes or the attribute name is found.
*
* We store the fact that an attribute is a ROOT versus USER attribute in
* We store the fact that an attribute is a ROOT/USER/SECURE attribute in
* the leaf_entry. The namespaces are independent only because we also look
* at the root/user bit when we are looking for a matching attribute name.
* at the namespace bit when we are looking for a matching attribute name.
*
* We also store a "incomplete" bit in the leaf_entry. It shows that an
* attribute is in the middle of being created and should not be shown to
......@@ -102,7 +102,7 @@ typedef struct xfs_attr_leafblock {
struct xfs_attr_leaf_entry { /* sorted on key, not name */
xfs_dahash_t hashval; /* hash value of name */
__uint16_t nameidx; /* index into buffer of name/value */
__uint8_t flags; /* LOCAL, ROOT and INCOMPLETE flags */
__uint8_t flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
__uint8_t pad2; /* unused pad byte */
} entries[1]; /* variable sized array */
struct xfs_attr_leaf_name_local {
......@@ -130,9 +130,11 @@ typedef struct xfs_attr_leaf_name_remote xfs_attr_leaf_name_remote_t;
*/
#define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */
#define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */
#define XFS_ATTR_SECURE_BIT 2 /* limit access to secure attrs */
#define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */
#define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT)
#define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT)
#define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT)
#define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT)
/*
......
......@@ -61,7 +61,7 @@
#include "xfs_error.h"
#include "xfs_quota.h"
#ifdef DEBUG
#if defined(XFS_BMBT_TRACE)
ktrace_t *xfs_bmbt_trace_buf;
#endif
......
/*
* Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
#ifndef __XFS_BUF_H__
#define __XFS_BUF_H__
/* These are just for xfs_syncsub... it sets an internal variable
* then passes it to VOP_FLUSH_PAGES or adds the flags to a newly gotten buf_t
*/
#define XFS_B_ASYNC PBF_ASYNC
#define XFS_B_DELWRI PBF_DELWRI
#define XFS_B_READ PBF_READ
#define XFS_B_WRITE PBF_WRITE
#define XFS_B_STALE PBF_STALE
#define XFS_BUF_TRYLOCK PBF_TRYLOCK
#define XFS_INCORE_TRYLOCK PBF_TRYLOCK
#define XFS_BUF_LOCK PBF_LOCK
#define XFS_BUF_MAPPED PBF_MAPPED
#define BUF_BUSY PBF_DONT_BLOCK
#define XFS_BUF_BFLAGS(x) ((x)->pb_flags)
#define XFS_BUF_ZEROFLAGS(x) \
((x)->pb_flags &= ~(PBF_READ|PBF_WRITE|PBF_ASYNC|PBF_SYNC|PBF_DELWRI))
#define XFS_BUF_STALE(x) ((x)->pb_flags |= XFS_B_STALE)
#define XFS_BUF_UNSTALE(x) ((x)->pb_flags &= ~XFS_B_STALE)
#define XFS_BUF_ISSTALE(x) ((x)->pb_flags & XFS_B_STALE)
#define XFS_BUF_SUPER_STALE(x) do { \
XFS_BUF_STALE(x); \
xfs_buf_undelay(x); \
XFS_BUF_DONE(x); \
} while (0)
#define XFS_BUF_MANAGE PBF_FS_MANAGED
#define XFS_BUF_UNMANAGE(x) ((x)->pb_flags &= ~PBF_FS_MANAGED)
static inline void xfs_buf_undelay(page_buf_t *pb)
{
if (pb->pb_flags & PBF_DELWRI) {
if (pb->pb_list.next != &pb->pb_list) {
pagebuf_delwri_dequeue(pb);
pagebuf_rele(pb);
} else {
pb->pb_flags &= ~PBF_DELWRI;
}
}
}
#define XFS_BUF_DELAYWRITE(x) ((x)->pb_flags |= PBF_DELWRI)
#define XFS_BUF_UNDELAYWRITE(x) xfs_buf_undelay(x)
#define XFS_BUF_ISDELAYWRITE(x) ((x)->pb_flags & PBF_DELWRI)
#define XFS_BUF_ERROR(x,no) pagebuf_ioerror(x,no)
#define XFS_BUF_GETERROR(x) pagebuf_geterror(x)
#define XFS_BUF_ISERROR(x) (pagebuf_geterror(x)?1:0)
#define XFS_BUF_DONE(x) ((x)->pb_flags &= ~(PBF_PARTIAL|PBF_NONE))
#define XFS_BUF_UNDONE(x) ((x)->pb_flags |= PBF_PARTIAL|PBF_NONE)
#define XFS_BUF_ISDONE(x) (!(PBF_NOT_DONE(x)))
#define XFS_BUF_BUSY(x) ((x)->pb_flags |= PBF_FORCEIO)
#define XFS_BUF_UNBUSY(x) ((x)->pb_flags &= ~PBF_FORCEIO)
#define XFS_BUF_ISBUSY(x) (1)
#define XFS_BUF_ASYNC(x) ((x)->pb_flags |= PBF_ASYNC)
#define XFS_BUF_UNASYNC(x) ((x)->pb_flags &= ~PBF_ASYNC)
#define XFS_BUF_ISASYNC(x) ((x)->pb_flags & PBF_ASYNC)
#define XFS_BUF_FLUSH(x) ((x)->pb_flags |= PBF_FLUSH)
#define XFS_BUF_UNFLUSH(x) ((x)->pb_flags &= ~PBF_FLUSH)
#define XFS_BUF_ISFLUSH(x) ((x)->pb_flags & PBF_FLUSH)
#define XFS_BUF_SHUT(x) printk("XFS_BUF_SHUT not implemented yet\n")
#define XFS_BUF_UNSHUT(x) printk("XFS_BUF_UNSHUT not implemented yet\n")
#define XFS_BUF_ISSHUT(x) (0)
#define XFS_BUF_HOLD(x) pagebuf_hold(x)
#define XFS_BUF_READ(x) ((x)->pb_flags |= PBF_READ)
#define XFS_BUF_UNREAD(x) ((x)->pb_flags &= ~PBF_READ)
#define XFS_BUF_ISREAD(x) ((x)->pb_flags & PBF_READ)
#define XFS_BUF_WRITE(x) ((x)->pb_flags |= PBF_WRITE)
#define XFS_BUF_UNWRITE(x) ((x)->pb_flags &= ~PBF_WRITE)
#define XFS_BUF_ISWRITE(x) ((x)->pb_flags & PBF_WRITE)
#define XFS_BUF_ISUNINITIAL(x) (0)
#define XFS_BUF_UNUNINITIAL(x) (0)
#define XFS_BUF_BP_ISMAPPED(bp) 1
typedef struct page_buf_s xfs_buf_t;
#define xfs_buf page_buf_s
typedef struct pb_target xfs_buftarg_t;
#define xfs_buftarg pb_target
#define XFS_BUF_DATAIO(x) ((x)->pb_flags |= PBF_FS_DATAIOD)
#define XFS_BUF_UNDATAIO(x) ((x)->pb_flags &= ~PBF_FS_DATAIOD)
#define XFS_BUF_IODONE_FUNC(buf) (buf)->pb_iodone
#define XFS_BUF_SET_IODONE_FUNC(buf, func) \
(buf)->pb_iodone = (func)
#define XFS_BUF_CLR_IODONE_FUNC(buf) \
(buf)->pb_iodone = NULL
#define XFS_BUF_SET_BDSTRAT_FUNC(buf, func) \
(buf)->pb_strat = (func)
#define XFS_BUF_CLR_BDSTRAT_FUNC(buf) \
(buf)->pb_strat = NULL
#define XFS_BUF_FSPRIVATE(buf, type) \
((type)(buf)->pb_fspriv)
#define XFS_BUF_SET_FSPRIVATE(buf, value) \
(buf)->pb_fspriv = (void *)(value)
#define XFS_BUF_FSPRIVATE2(buf, type) \
((type)(buf)->pb_fspriv2)
#define XFS_BUF_SET_FSPRIVATE2(buf, value) \
(buf)->pb_fspriv2 = (void *)(value)
#define XFS_BUF_FSPRIVATE3(buf, type) \
((type)(buf)->pb_fspriv3)
#define XFS_BUF_SET_FSPRIVATE3(buf, value) \
(buf)->pb_fspriv3 = (void *)(value)
#define XFS_BUF_SET_START(buf)
#define XFS_BUF_SET_BRELSE_FUNC(buf, value) \
(buf)->pb_relse = (value)
#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->pb_addr)
extern inline xfs_caddr_t xfs_buf_offset(page_buf_t *bp, size_t offset)
{
if (bp->pb_flags & PBF_MAPPED)
return XFS_BUF_PTR(bp) + offset;
return (xfs_caddr_t) pagebuf_offset(bp, offset);
}
#define XFS_BUF_SET_PTR(bp, val, count) \
pagebuf_associate_memory(bp, val, count)
#define XFS_BUF_ADDR(bp) ((bp)->pb_bn)
#define XFS_BUF_SET_ADDR(bp, blk) \
((bp)->pb_bn = (page_buf_daddr_t)(blk))
#define XFS_BUF_OFFSET(bp) ((bp)->pb_file_offset)
#define XFS_BUF_SET_OFFSET(bp, off) \
((bp)->pb_file_offset = (off))
#define XFS_BUF_COUNT(bp) ((bp)->pb_count_desired)
#define XFS_BUF_SET_COUNT(bp, cnt) \
((bp)->pb_count_desired = (cnt))
#define XFS_BUF_SIZE(bp) ((bp)->pb_buffer_length)
#define XFS_BUF_SET_SIZE(bp, cnt) \
((bp)->pb_buffer_length = (cnt))
#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
#define XFS_BUF_SET_VTYPE(bp, type)
#define XFS_BUF_SET_REF(bp, ref)
#define XFS_BUF_ISPINNED(bp) pagebuf_ispin(bp)
#define XFS_BUF_VALUSEMA(bp) pagebuf_lock_value(bp)
#define XFS_BUF_CPSEMA(bp) (pagebuf_cond_lock(bp) == 0)
#define XFS_BUF_VSEMA(bp) pagebuf_unlock(bp)
#define XFS_BUF_PSEMA(bp,x) pagebuf_lock(bp)
#define XFS_BUF_V_IODONESEMA(bp) up(&bp->pb_iodonesema);
/* setup the buffer target from a buftarg structure */
#define XFS_BUF_SET_TARGET(bp, target) \
(bp)->pb_target = (target)
#define XFS_BUF_TARGET(bp) ((bp)->pb_target)
#define XFS_BUFTARG_NAME(target) \
pagebuf_target_name(target)
#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
#define XFS_BUF_SET_VTYPE(bp, type)
#define XFS_BUF_SET_REF(bp, ref)
#define xfs_buf_read(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_LOCK | PBF_READ | PBF_MAPPED | PBF_MAPPABLE)
#define xfs_buf_get(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_LOCK | PBF_MAPPED | PBF_MAPPABLE)
#define xfs_buf_read_flags(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_READ | PBF_MAPPABLE | flags)
#define xfs_buf_get_flags(target, blkno, len, flags) \
pagebuf_get((target), (blkno), (len), \
PBF_MAPPABLE | flags)
static inline int xfs_bawrite(void *mp, page_buf_t *bp)
{
bp->pb_fspriv3 = mp;
bp->pb_strat = xfs_bdstrat_cb;
xfs_buf_undelay(bp);
return pagebuf_iostart(bp, PBF_WRITE | PBF_ASYNC | PBF_RUN_QUEUES);
}
static inline void xfs_buf_relse(page_buf_t *bp)
{
if ((bp->pb_flags & _PBF_LOCKABLE) && !bp->pb_relse)
pagebuf_unlock(bp);
pagebuf_rele(bp);
}
#define xfs_bpin(bp) pagebuf_pin(bp)
#define xfs_bunpin(bp) pagebuf_unpin(bp)
#define xfs_buftrace(id, bp) \
pagebuf_trace(bp, id, NULL, (void *)__builtin_return_address(0))
#define xfs_biodone(pb) \
pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), 0)
#define xfs_incore(buftarg,blkno,len,lockit) \
pagebuf_find(buftarg, blkno ,len, lockit)
#define xfs_biomove(pb, off, len, data, rw) \
pagebuf_iomove((pb), (off), (len), (data), \
((rw) == XFS_B_WRITE) ? PBRW_WRITE : PBRW_READ)
#define xfs_biozero(pb, off, len) \
pagebuf_iomove((pb), (off), (len), NULL, PBRW_ZERO)
static inline int XFS_bwrite(page_buf_t *pb)
{
int iowait = (pb->pb_flags & PBF_ASYNC) == 0;
int error = 0;
pb->pb_flags |= PBF_SYNC;
if (!iowait)
pb->pb_flags |= PBF_RUN_QUEUES;
xfs_buf_undelay(pb);
pagebuf_iostrategy(pb);
if (iowait) {
error = pagebuf_iowait(pb);
xfs_buf_relse(pb);
}
return error;
}
#define XFS_bdwrite(pb) \
pagebuf_iostart(pb, PBF_DELWRI | PBF_ASYNC)
static inline int xfs_bdwrite(void *mp, page_buf_t *bp)
{
bp->pb_strat = xfs_bdstrat_cb;
bp->pb_fspriv3 = mp;
return pagebuf_iostart(bp, PBF_DELWRI | PBF_ASYNC);
}
#define XFS_bdstrat(bp) pagebuf_iorequest(bp)
#define xfs_iowait(pb) pagebuf_iowait(pb)
/*
* Go through all incore buffers, and release buffers
* if they belong to the given device. This is used in
* filesystem error handling to preserve the consistency
* of its metadata.
*/
#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg)
#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg)
#define xfs_incore_relse(buftarg,delwri_only,wait) \
xfs_relse_buftarg(buftarg)
#define xfs_baread(target, rablkno, ralen) \
pagebuf_readahead((target), (rablkno), (ralen), PBF_DONT_BLOCK)
#define xfs_buf_get_empty(len, target) pagebuf_get_empty((len), (target))
#define xfs_buf_get_noaddr(len, target) pagebuf_get_no_daddr((len), (target))
#define xfs_buf_free(bp) pagebuf_free(bp)
#endif /* __XFS_BUF_H__ */
......@@ -162,7 +162,7 @@ STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
xfs_dir_put_t put);
STATIC int xfs_dir_node_replace(xfs_da_args_t *args);
#if defined(DEBUG)
#if defined(XFS_DIR_TRACE)
ktrace_t *xfs_dir_trace_buf;
#endif
......
......@@ -49,11 +49,9 @@
#include "xfs_da_btree.h"
#include "xfs_dir2_trace.h"
#ifdef DEBUG
#ifdef XFS_DIR2_TRACE
ktrace_t *xfs_dir2_trace_buf;
#endif /* DEBUG */
#ifdef XFS_DIR2_TRACE
/*
* Enter something in the trace buffers.
*/
......
......@@ -1531,7 +1531,7 @@ xlog_recover_reorder_trans(
xlog_recover_item_t *first_item, *itemq, *itemq_next;
xfs_buf_log_format_t *buf_f;
xfs_buf_log_format_v1_t *obuf_f;
ushort flags;
ushort flags = 0;
first_item = itemq = trans->r_itemq;
trans->r_itemq = NULL;
......
......@@ -75,24 +75,6 @@ typedef __uint64_t __psunsigned_t;
#error BITS_PER_LONG must be 32 or 64
#endif
/*
* Some types are conditional depending on the target system.
* XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
* XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well
* as requiring XFS_BIG_BLKNOS to be set.
*/
#if defined(CONFIG_LBD) || (BITS_PER_LONG == 64)
# define XFS_BIG_BLKNOS 1
# if BITS_PER_LONG == 64
# define XFS_BIG_INUMS 1
# else
# define XFS_BIG_INUMS 0
# endif
#else
# define XFS_BIG_BLKNOS 0
# define XFS_BIG_INUMS 0
#endif
#endif /* __KERNEL__ */
typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */
......
......@@ -171,6 +171,25 @@ xfs_cleanup(void)
xfs_sysctl_unregister();
xfs_refcache_destroy();
#ifdef XFS_DIR2_TRACE
ktrace_free(xfs_dir2_trace_buf);
#endif
#ifdef XFS_ATTR_TRACE
ktrace_free(xfs_attr_trace_buf);
#endif
#ifdef XFS_DIR_TRACE
ktrace_free(xfs_dir_trace_buf);
#endif
#ifdef XFS_BMBT_TRACE
ktrace_free(xfs_bmbt_trace_buf);
#endif
#ifdef XFS_BMAP_TRACE
ktrace_free(xfs_bmap_trace_buf);
#endif
#ifdef XFS_ALLOC_TRACE
ktrace_free(xfs_alloc_trace_buf);
#endif
kmem_cache_destroy(xfs_bmap_free_item_zone);
kmem_cache_destroy(xfs_btree_cur_zone);
kmem_cache_destroy(xfs_inode_zone);
......
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