From 08e0e7c82eeadec6f4871a386b86bf0f0fbcb4eb Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 26 Apr 2007 15:55:03 -0700 Subject: [AF_RXRPC]: Make the in-kernel AFS filesystem use AF_RXRPC. Make the in-kernel AFS filesystem use AF_RXRPC instead of the old RxRPC code. Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/internal.h | 599 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 553 insertions(+), 46 deletions(-) (limited to 'fs/afs/internal.h') diff --git a/fs/afs/internal.h b/fs/afs/internal.h index b6dd20a93cce..afc6f0f30259 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1,6 +1,6 @@ /* internal AFS stuff * - * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. + * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or @@ -9,48 +9,321 @@ * 2 of the License, or (at your option) any later version. */ -#ifndef AFS_INTERNAL_H -#define AFS_INTERNAL_H - #include #include #include #include +#include +#include +#include "afs.h" +#include "afs_vl.h" + +#define AFS_CELL_MAX_ADDRS 15 + +struct afs_call; + +typedef enum { + AFS_VL_NEW, /* new, uninitialised record */ + AFS_VL_CREATING, /* creating record */ + AFS_VL_VALID, /* record is pending */ + AFS_VL_NO_VOLUME, /* no such volume available */ + AFS_VL_UPDATING, /* update in progress */ + AFS_VL_VOLUME_DELETED, /* volume was deleted */ + AFS_VL_UNCERTAIN, /* uncertain state (update failed) */ +} __attribute__((packed)) afs_vlocation_state_t; /* - * debug tracing + * definition of how to wait for the completion of an operation */ -#define kenter(FMT, a...) printk("==> %s("FMT")\n",__FUNCTION__ , ## a) -#define kleave(FMT, a...) printk("<== %s()"FMT"\n",__FUNCTION__ , ## a) -#define kdebug(FMT, a...) printk(FMT"\n" , ## a) -#define kproto(FMT, a...) printk("### "FMT"\n" , ## a) -#define knet(FMT, a...) printk(FMT"\n" , ## a) - -#ifdef __KDEBUG -#define _enter(FMT, a...) kenter(FMT , ## a) -#define _leave(FMT, a...) kleave(FMT , ## a) -#define _debug(FMT, a...) kdebug(FMT , ## a) -#define _proto(FMT, a...) kproto(FMT , ## a) -#define _net(FMT, a...) knet(FMT , ## a) -#else -#define _enter(FMT, a...) do { } while(0) -#define _leave(FMT, a...) do { } while(0) -#define _debug(FMT, a...) do { } while(0) -#define _proto(FMT, a...) do { } while(0) -#define _net(FMT, a...) do { } while(0) -#endif +struct afs_wait_mode { + /* RxRPC received message notification */ + void (*rx_wakeup)(struct afs_call *call); -static inline void afs_discard_my_signals(void) -{ - while (signal_pending(current)) { - siginfo_t sinfo; + /* synchronous call waiter and call dispatched notification */ + int (*wait)(struct afs_call *call); + + /* asynchronous call completion */ + void (*async_complete)(void *reply, int error); +}; + +extern const struct afs_wait_mode afs_sync_call; +extern const struct afs_wait_mode afs_async_call; + +/* + * a record of an in-progress RxRPC call + */ +struct afs_call { + const struct afs_call_type *type; /* type of call */ + const struct afs_wait_mode *wait_mode; /* completion wait mode */ + wait_queue_head_t waitq; /* processes awaiting completion */ + struct work_struct async_work; /* asynchronous work processor */ + struct work_struct work; /* actual work processor */ + struct sk_buff_head rx_queue; /* received packets */ + struct rxrpc_call *rxcall; /* RxRPC call handle */ + struct key *key; /* security for this call */ + struct afs_server *server; /* server affected by incoming CM call */ + void *request; /* request data (first part) */ + void *request2; /* request data (second part) */ + void *buffer; /* reply receive buffer */ + void *reply; /* reply buffer (first part) */ + void *reply2; /* reply buffer (second part) */ + void *reply3; /* reply buffer (third part) */ + enum { /* call state */ + AFS_CALL_REQUESTING, /* request is being sent for outgoing call */ + AFS_CALL_AWAIT_REPLY, /* awaiting reply to outgoing call */ + AFS_CALL_AWAIT_OP_ID, /* awaiting op ID on incoming call */ + AFS_CALL_AWAIT_REQUEST, /* awaiting request data on incoming call */ + AFS_CALL_REPLYING, /* replying to incoming call */ + AFS_CALL_AWAIT_ACK, /* awaiting final ACK of incoming call */ + AFS_CALL_COMPLETE, /* successfully completed */ + AFS_CALL_BUSY, /* server was busy */ + AFS_CALL_ABORTED, /* call was aborted */ + AFS_CALL_ERROR, /* call failed due to error */ + } state; + int error; /* error code */ + unsigned request_size; /* size of request data */ + unsigned reply_max; /* maximum size of reply */ + unsigned reply_size; /* current size of reply */ + unsigned short offset; /* offset into received data store */ + unsigned char unmarshall; /* unmarshalling phase */ + bool incoming; /* T if incoming call */ + u16 service_id; /* RxRPC service ID to call */ + __be16 port; /* target UDP port */ + __be32 operation_ID; /* operation ID for an incoming call */ + u32 count; /* count for use in unmarshalling */ + __be32 tmp; /* place to extract temporary data */ +}; + +struct afs_call_type { + /* deliver request or reply data to an call + * - returning an error will cause the call to be aborted + */ + int (*deliver)(struct afs_call *call, struct sk_buff *skb, + bool last); + + /* map an abort code to an error number */ + int (*abort_to_error)(u32 abort_code); + + /* clean up a call */ + void (*destructor)(struct afs_call *call); +}; + +/* + * AFS superblock private data + * - there's one superblock per volume + */ +struct afs_super_info { + struct afs_volume *volume; /* volume record */ + char rwparent; /* T if parent is R/W AFS volume */ +}; - spin_lock_irq(¤t->sighand->siglock); - dequeue_signal(current,¤t->blocked, &sinfo); - spin_unlock_irq(¤t->sighand->siglock); - } +static inline struct afs_super_info *AFS_FS_S(struct super_block *sb) +{ + return sb->s_fs_info; } +extern struct file_system_type afs_fs_type; + +/* + * entry in the cached cell catalogue + */ +struct afs_cache_cell { + char name[64]; /* cell name (padded with NULs) */ + struct in_addr vl_servers[15]; /* cached cell VL servers */ +}; + +/* + * AFS cell record + */ +struct afs_cell { + atomic_t usage; + struct list_head link; /* main cell list link */ + struct list_head proc_link; /* /proc cell list link */ + struct proc_dir_entry *proc_dir; /* /proc dir for this cell */ +#ifdef AFS_CACHING_SUPPORT + struct cachefs_cookie *cache; /* caching cookie */ +#endif + + /* server record management */ + rwlock_t servers_lock; /* active server list lock */ + struct list_head servers; /* active server list */ + + /* volume location record management */ + struct rw_semaphore vl_sem; /* volume management serialisation semaphore */ + struct list_head vl_list; /* cell's active VL record list */ + spinlock_t vl_lock; /* vl_list lock */ + unsigned short vl_naddrs; /* number of VL servers in addr list */ + unsigned short vl_curr_svix; /* current server index */ + struct in_addr vl_addrs[AFS_CELL_MAX_ADDRS]; /* cell VL server addresses */ + + char name[0]; /* cell name - must go last */ +}; + +/* + * entry in the cached volume location catalogue + */ +struct afs_cache_vlocation { + uint8_t name[64 + 1]; /* volume name (lowercase, padded with NULs) */ + uint8_t nservers; /* number of entries used in servers[] */ + uint8_t vidmask; /* voltype mask for vid[] */ + uint8_t srvtmask[8]; /* voltype masks for servers[] */ +#define AFS_VOL_VTM_RW 0x01 /* R/W version of the volume is available (on this server) */ +#define AFS_VOL_VTM_RO 0x02 /* R/O version of the volume is available (on this server) */ +#define AFS_VOL_VTM_BAK 0x04 /* backup version of the volume is available (on this server) */ + + afs_volid_t vid[3]; /* volume IDs for R/W, R/O and Bak volumes */ + struct in_addr servers[8]; /* fileserver addresses */ + time_t rtime; /* last retrieval time */ +}; + +/* + * volume -> vnode hash table entry + */ +struct afs_cache_vhash { + afs_voltype_t vtype; /* which volume variation */ + uint8_t hash_bucket; /* which hash bucket this represents */ +} __attribute__((packed)); + +/* + * AFS volume location record + */ +struct afs_vlocation { + atomic_t usage; + time_t time_of_death; /* time at which put reduced usage to 0 */ + struct list_head link; /* link in cell volume location list */ + struct list_head grave; /* link in master graveyard list */ + struct list_head update; /* link in master update list */ + struct afs_cell *cell; /* cell to which volume belongs */ +#ifdef AFS_CACHING_SUPPORT + struct cachefs_cookie *cache; /* caching cookie */ +#endif + struct afs_cache_vlocation vldb; /* volume information DB record */ + struct afs_volume *vols[3]; /* volume access record pointer (index by type) */ + wait_queue_head_t waitq; /* status change waitqueue */ + time_t update_at; /* time at which record should be updated */ + rwlock_t lock; /* access lock */ + afs_vlocation_state_t state; /* volume location state */ + unsigned short upd_rej_cnt; /* ENOMEDIUM count during update */ + unsigned short upd_busy_cnt; /* EBUSY count during update */ + bool valid; /* T if valid */ +}; + +/* + * AFS fileserver record + */ +struct afs_server { + atomic_t usage; + time_t time_of_death; /* time at which put reduced usage to 0 */ + struct in_addr addr; /* server address */ + struct afs_cell *cell; /* cell in which server resides */ + struct list_head link; /* link in cell's server list */ + struct list_head grave; /* link in master graveyard list */ + struct rb_node master_rb; /* link in master by-addr tree */ + struct rw_semaphore sem; /* access lock */ + + /* file service access */ + struct rb_root fs_vnodes; /* vnodes backed by this server (ordered by FID) */ + unsigned long fs_act_jif; /* time at which last activity occurred */ + unsigned long fs_dead_jif; /* time at which no longer to be considered dead */ + spinlock_t fs_lock; /* access lock */ + int fs_state; /* 0 or reason FS currently marked dead (-errno) */ + + /* callback promise management */ + struct rb_root cb_promises; /* vnode expiration list (ordered earliest first) */ + struct delayed_work cb_updater; /* callback updater */ + struct delayed_work cb_break_work; /* collected break dispatcher */ + wait_queue_head_t cb_break_waitq; /* space available in cb_break waitqueue */ + spinlock_t cb_lock; /* access lock */ + struct afs_callback cb_break[64]; /* ring of callbacks awaiting breaking */ + atomic_t cb_break_n; /* number of pending breaks */ + u8 cb_break_head; /* head of callback breaking ring */ + u8 cb_break_tail; /* tail of callback breaking ring */ +}; + +/* + * AFS volume access record + */ +struct afs_volume { + atomic_t usage; + struct afs_cell *cell; /* cell to which belongs (unrefd ptr) */ + struct afs_vlocation *vlocation; /* volume location */ +#ifdef AFS_CACHING_SUPPORT + struct cachefs_cookie *cache; /* caching cookie */ +#endif + afs_volid_t vid; /* volume ID */ + afs_voltype_t type; /* type of volume */ + char type_force; /* force volume type (suppress R/O -> R/W) */ + unsigned short nservers; /* number of server slots filled */ + unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ + struct afs_server *servers[8]; /* servers on which volume resides (ordered) */ + struct rw_semaphore server_sem; /* lock for accessing current server */ +}; + +/* + * vnode catalogue entry + */ +struct afs_cache_vnode { + afs_vnodeid_t vnode_id; /* vnode ID */ + unsigned vnode_unique; /* vnode ID uniquifier */ + afs_dataversion_t data_version; /* data version */ +}; + +/* + * AFS inode private data + */ +struct afs_vnode { + struct inode vfs_inode; /* the VFS's inode record */ + + struct afs_volume *volume; /* volume on which vnode resides */ + struct afs_server *server; /* server currently supplying this file */ + struct afs_fid fid; /* the file identifier for this inode */ + struct afs_file_status status; /* AFS status info for this file */ +#ifdef AFS_CACHING_SUPPORT + struct cachefs_cookie *cache; /* caching cookie */ +#endif + + wait_queue_head_t update_waitq; /* status fetch waitqueue */ + unsigned update_cnt; /* number of outstanding ops that will update the + * status */ + spinlock_t lock; /* waitqueue/flags lock */ + unsigned long flags; +#define AFS_VNODE_CB_BROKEN 0 /* set if vnode's callback was broken */ +#define AFS_VNODE_CHANGED 1 /* set if vnode's metadata changed */ +#define AFS_VNODE_MODIFIED 2 /* set if vnode's data modified */ +#define AFS_VNODE_ZAP_DATA 3 /* set if vnode's data should be invalidated */ +#define AFS_VNODE_DELETED 4 /* set if vnode deleted on server */ +#define AFS_VNODE_MOUNTPOINT 5 /* set if vnode is a mountpoint symlink */ +#define AFS_VNODE_DIR_CHANGED 6 /* set if vnode's parent dir metadata changed */ +#define AFS_VNODE_DIR_MODIFIED 7 /* set if vnode's parent dir data modified */ + + /* outstanding callback notification on this file */ + struct rb_node server_rb; /* link in server->fs_vnodes */ + struct rb_node cb_promise; /* link in server->cb_promises */ + struct work_struct cb_broken_work; /* work to be done on callback break */ + struct mutex cb_broken_lock; /* lock against multiple attempts to fix break */ +// struct list_head cb_hash_link; /* link in master callback hash */ + time_t cb_expires; /* time at which callback expires */ + time_t cb_expires_at; /* time used to order cb_promise */ + unsigned cb_version; /* callback version */ + unsigned cb_expiry; /* callback expiry time */ + afs_callback_type_t cb_type; /* type of callback */ + bool cb_promised; /* true if promise still holds */ +}; + +/*****************************************************************************/ +/* + * callback.c + */ +extern void afs_init_callback_state(struct afs_server *); +extern void afs_broken_callback_work(struct work_struct *); +extern void afs_break_callbacks(struct afs_server *, size_t, + struct afs_callback[]); +extern void afs_give_up_callback(struct afs_vnode *); +extern void afs_dispatch_give_up_callbacks(struct work_struct *); +extern void afs_flush_callback_breaks(struct afs_server *); +extern int __init afs_callback_update_init(void); +extern void __exit afs_callback_update_kill(void); + /* * cell.c */ @@ -60,6 +333,19 @@ extern struct list_head afs_proc_cells; extern struct cachefs_index_def afs_cache_cell_index_def; #endif +#define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0) +extern int afs_cell_init(char *); +extern struct afs_cell *afs_cell_create(const char *, char *); +extern struct afs_cell *afs_cell_lookup(const char *, unsigned); +extern struct afs_cell *afs_grab_cell(struct afs_cell *); +extern void afs_put_cell(struct afs_cell *); +extern void afs_cell_purge(void); + +/* + * cmservice.c + */ +extern bool afs_cm_incoming_call(struct afs_call *); + /* * dir.c */ @@ -76,10 +362,23 @@ extern const struct inode_operations afs_file_inode_operations; extern int afs_cache_get_page_cookie(struct page *, struct cachefs_page **); #endif +/* + * fsclient.c + */ +extern int afs_fs_fetch_file_status(struct afs_server *, + struct afs_vnode *, + struct afs_volsync *, + const struct afs_wait_mode *); +extern int afs_fs_give_up_callbacks(struct afs_server *, + const struct afs_wait_mode *); +extern int afs_fs_fetch_data(struct afs_server *, struct afs_vnode *, off_t, + size_t, struct page *, struct afs_volsync *, + const struct afs_wait_mode *); + /* * inode.c */ -extern int afs_iget(struct super_block *, struct afs_fid *, struct inode **); +extern struct inode *afs_iget(struct super_block *, struct afs_fid *); extern int afs_inode_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern void afs_clear_inode(struct inode *); @@ -91,16 +390,21 @@ extern void afs_clear_inode(struct inode *); extern struct cachefs_netfs afs_cache_netfs; #endif +/* + * misc.c + */ +extern int afs_abort_to_error(u32); + /* * mntpt.c */ extern const struct inode_operations afs_mntpt_inode_operations; extern const struct file_operations afs_mntpt_file_operations; -extern struct afs_timer afs_mntpt_expiry_timer; -extern struct afs_timer_ops afs_mntpt_expiry_timer_ops; extern unsigned long afs_mntpt_expiry_timeout; extern int afs_mntpt_check_symlink(struct afs_vnode *); +extern void afs_mntpt_kill_timer(void); +extern void afs_umount_begin(struct vfsmount *, int); /* * super.c @@ -108,16 +412,6 @@ extern int afs_mntpt_check_symlink(struct afs_vnode *); extern int afs_fs_init(void); extern void afs_fs_exit(void); -#define AFS_CB_HASH_COUNT (PAGE_SIZE / sizeof(struct list_head)) - -extern struct list_head afs_cb_hash_tbl[]; -extern spinlock_t afs_cb_hash_lock; - -#define afs_cb_hash(SRV, FID) \ - afs_cb_hash_tbl[((unsigned long)(SRV) + \ - (FID)->vid + (FID)->vnode + (FID)->unique) & \ - (AFS_CB_HASH_COUNT - 1)] - /* * proc.c */ @@ -126,4 +420,217 @@ extern void afs_proc_cleanup(void); extern int afs_proc_cell_setup(struct afs_cell *); extern void afs_proc_cell_remove(struct afs_cell *); -#endif /* AFS_INTERNAL_H */ +/* + * rxrpc.c + */ +extern int afs_open_socket(void); +extern void afs_close_socket(void); +extern int afs_make_call(struct in_addr *, struct afs_call *, gfp_t, + const struct afs_wait_mode *); +extern struct afs_call *afs_alloc_flat_call(const struct afs_call_type *, + size_t, size_t); +extern void afs_flat_call_destructor(struct afs_call *); +extern void afs_transfer_reply(struct afs_call *, struct sk_buff *); +extern void afs_send_empty_reply(struct afs_call *); +extern int afs_extract_data(struct afs_call *, struct sk_buff *, bool, void *, + size_t); + +/* + * server.c + */ +extern spinlock_t afs_server_peer_lock; + +#define afs_get_server(S) do { atomic_inc(&(S)->usage); } while(0) + +extern struct afs_server *afs_lookup_server(struct afs_cell *, + const struct in_addr *); +extern struct afs_server *afs_find_server(const struct in_addr *); +extern void afs_put_server(struct afs_server *); +extern void __exit afs_purge_servers(void); + +/* + * vlclient.c + */ +#ifdef AFS_CACHING_SUPPORT +extern struct cachefs_index_def afs_vlocation_cache_index_def; +#endif + +extern int afs_vl_get_entry_by_name(struct in_addr *, const char *, + struct afs_cache_vlocation *, + const struct afs_wait_mode *); +extern int afs_vl_get_entry_by_id(struct in_addr *, afs_volid_t, afs_voltype_t, + struct afs_cache_vlocation *, + const struct afs_wait_mode *); + +/* + * vlocation.c + */ +#define afs_get_vlocation(V) do { atomic_inc(&(V)->usage); } while(0) + +extern int __init afs_vlocation_update_init(void); +extern struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *, + const char *, size_t); +extern void afs_put_vlocation(struct afs_vlocation *); +extern void __exit afs_vlocation_purge(void); + +/* + * vnode.c + */ +#ifdef AFS_CACHING_SUPPORT +extern struct cachefs_index_def afs_vnode_cache_index_def; +#endif + +extern struct afs_timer_ops afs_vnode_cb_timed_out_ops; + +static inline struct afs_vnode *AFS_FS_I(struct inode *inode) +{ + return container_of(inode, struct afs_vnode, vfs_inode); +} + +static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode) +{ + return &vnode->vfs_inode; +} + +extern int afs_vnode_fetch_status(struct afs_vnode *); +extern int afs_vnode_fetch_data(struct afs_vnode *vnode, off_t, size_t, + struct page *); + +/* + * volume.c + */ +#ifdef AFS_CACHING_SUPPORT +extern struct cachefs_index_def afs_volume_cache_index_def; +#endif + +#define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0) + +extern void afs_put_volume(struct afs_volume *); +extern struct afs_volume *afs_volume_lookup(const char *, struct afs_cell *, + int); +extern struct afs_server *afs_volume_pick_fileserver(struct afs_vnode *); +extern int afs_volume_release_fileserver(struct afs_vnode *, + struct afs_server *, int); + +/*****************************************************************************/ +/* + * debug tracing + */ +extern unsigned afs_debug; + +#define dbgprintk(FMT,...) \ + printk("[%x%-6.6s] "FMT"\n", smp_processor_id(), current->comm ,##__VA_ARGS__) + +/* make sure we maintain the format strings, even when debugging is disabled */ +static inline __attribute__((format(printf,1,2))) +void _dbprintk(const char *fmt, ...) +{ +} + +#define kenter(FMT,...) dbgprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__) +#define kleave(FMT,...) dbgprintk("<== %s()"FMT"",__FUNCTION__ ,##__VA_ARGS__) +#define kdebug(FMT,...) dbgprintk(" "FMT ,##__VA_ARGS__) + + +#if defined(__KDEBUG) +#define _enter(FMT,...) kenter(FMT,##__VA_ARGS__) +#define _leave(FMT,...) kleave(FMT,##__VA_ARGS__) +#define _debug(FMT,...) kdebug(FMT,##__VA_ARGS__) + +#elif defined(CONFIG_AFS_DEBUG) +#define AFS_DEBUG_KENTER 0x01 +#define AFS_DEBUG_KLEAVE 0x02 +#define AFS_DEBUG_KDEBUG 0x04 + +#define _enter(FMT,...) \ +do { \ + if (unlikely(afs_debug & AFS_DEBUG_KENTER)) \ + kenter(FMT,##__VA_ARGS__); \ +} while (0) + +#define _leave(FMT,...) \ +do { \ + if (unlikely(afs_debug & AFS_DEBUG_KLEAVE)) \ + kleave(FMT,##__VA_ARGS__); \ +} while (0) + +#define _debug(FMT,...) \ +do { \ + if (unlikely(afs_debug & AFS_DEBUG_KDEBUG)) \ + kdebug(FMT,##__VA_ARGS__); \ +} while (0) + +#else +#define _enter(FMT,...) _dbprintk("==> %s("FMT")",__FUNCTION__ ,##__VA_ARGS__) +#define _leave(FMT,...) _dbprintk("<== %s()"FMT"",__FUNCTION__ ,##__VA_ARGS__) +#define _debug(FMT,...) _dbprintk(" "FMT ,##__VA_ARGS__) +#endif + +/* + * debug assertion checking + */ +#if 1 // defined(__KDEBUGALL) + +#define ASSERT(X) \ +do { \ + if (unlikely(!(X))) { \ + printk(KERN_ERR "\n"); \ + printk(KERN_ERR "AFS: Assertion failed\n"); \ + BUG(); \ + } \ +} while(0) + +#define ASSERTCMP(X, OP, Y) \ +do { \ + if (unlikely(!((X) OP (Y)))) { \ + printk(KERN_ERR "\n"); \ + printk(KERN_ERR "AFS: Assertion failed\n"); \ + printk(KERN_ERR "%lu " #OP " %lu is false\n", \ + (unsigned long)(X), (unsigned long)(Y)); \ + printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \ + (unsigned long)(X), (unsigned long)(Y)); \ + BUG(); \ + } \ +} while(0) + +#define ASSERTIF(C, X) \ +do { \ + if (unlikely((C) && !(X))) { \ + printk(KERN_ERR "\n"); \ + printk(KERN_ERR "AFS: Assertion failed\n"); \ + BUG(); \ + } \ +} while(0) + +#define ASSERTIFCMP(C, X, OP, Y) \ +do { \ + if (unlikely((C) && !((X) OP (Y)))) { \ + printk(KERN_ERR "\n"); \ + printk(KERN_ERR "AFS: Assertion failed\n"); \ + printk(KERN_ERR "%lu " #OP " %lu is false\n", \ + (unsigned long)(X), (unsigned long)(Y)); \ + printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \ + (unsigned long)(X), (unsigned long)(Y)); \ + BUG(); \ + } \ +} while(0) + +#else + +#define ASSERT(X) \ +do { \ +} while(0) + +#define ASSERTCMP(X, OP, Y) \ +do { \ +} while(0) + +#define ASSERTIF(C, X) \ +do { \ +} while(0) + +#define ASSERTIFCMP(C, X, OP, Y) \ +do { \ +} while(0) + +#endif /* __KDEBUGALL */ -- cgit v1.2.3