X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Finclude%2Flinux%2Flustre_lib.h;h=41c67fff3fb53972424a54c02a2ad9a3d82640ac;hb=040033cef24c5aca2967daf2da7a862abcd074cf;hp=e1dc9d7ba8511cfa2302f26d57b96d1500a7bb5f;hpb=dedeb3b712ee1beb911e8354851d3ecdbffbab2b;p=fs%2Flustre-release.git diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h index e1dc9d7..41c67fff 100644 --- a/lustre/include/linux/lustre_lib.h +++ b/lustre/include/linux/lustre_lib.h @@ -18,7 +18,7 @@ * along with Lustre; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Basic Lustre library routines. + * Basic Lustre library routines. * */ @@ -29,11 +29,13 @@ # include #else # include -#include /* XXX just for LASSERT! */ #endif +#include #include +#include /* XXX just for LASSERT! */ #include +#ifndef LPU64 #if BITS_PER_LONG > 32 #define LPU64 "%lu" #define LPD64 "%ld" @@ -43,26 +45,47 @@ #define LPD64 "%Ld" #define LPX64 "%#Lx" #endif +#endif -#ifdef __KERNEL__ -/* l_net.c */ +/* target.c */ struct ptlrpc_request; struct obd_device; struct recovd_data; +struct recovd_obd; +struct obd_export; +#include +#include -int target_handle_connect(struct ptlrpc_request *req); + +int target_handle_connect(struct ptlrpc_request *req, svc_handler_t handler); int target_handle_disconnect(struct ptlrpc_request *req); +int target_handle_reconnect(struct lustre_handle *conn, struct obd_export *exp, + struct obd_uuid *cluuid); +int target_revoke_connection(struct recovd_data *rd, int phase); + +#define OBD_RECOVERY_TIMEOUT (obd_timeout * 5 * HZ / 2) /* *waves hands* */ +void target_start_recovery_timer(struct obd_device *obd, svc_handler_t handler); +void target_abort_recovery(void *data); +int target_queue_recovery_request(struct ptlrpc_request *req, + struct obd_device *obd); +int target_queue_final_reply(struct ptlrpc_request *req, int rc); + +/* client.c */ int client_obd_connect(struct lustre_handle *conn, struct obd_device *obd, - obd_uuid_t cluuid); + struct obd_uuid *cluuid, struct recovd_obd *recovd, + ptlrpc_recovery_cb_t recover); int client_obd_disconnect(struct lustre_handle *conn); int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf); +int client_sanobd_setup(struct obd_device *obddev, obd_count len, void *buf); int client_obd_cleanup(struct obd_device * obddev); -struct client_obd *client_conn2cli(struct lustre_handle *conn); +struct client_obd *client_conn2cli(struct lustre_handle *conn); +struct obd_device *client_tgtuuid2obd(struct obd_uuid *tgtuuid); -int target_revoke_connection(struct recovd_data *rd, int phase); +/* statfs_pack.c */ +int obd_self_statfs(struct obd_device *dev, struct statfs *sfs); /* l_lock.c */ -struct lustre_lock { +struct lustre_lock { int l_depth; struct task_struct *l_owner; struct semaphore l_sem; @@ -72,44 +95,37 @@ struct lustre_lock { void l_lock_init(struct lustre_lock *); void l_lock(struct lustre_lock *); void l_unlock(struct lustre_lock *); +int l_has_lock(struct lustre_lock *); - -/* page.c */ #define CB_PHASE_START 12 #define CB_PHASE_FINISH 13 -/* - * io_cb_data: io callback data merged into one struct to simplify - * memory managment. This may be turn out to be too simple. - */ -struct io_cb_data; -typedef int (*brw_callback_t)(struct io_cb_data *, int err, int phase); +/* This list head doesn't need to be locked, because it's only manipulated by + * one thread at a time. */ +struct obd_brw_set { + struct list_head brw_desc_head; /* list of ptlrpc_bulk_desc */ + wait_queue_head_t brw_waitq; + atomic_t brw_refcount; + int brw_flags; -struct io_cb_data { - wait_queue_head_t waitq; - atomic_t refcount; - int complete; - int err; - struct ptlrpc_bulk_desc *desc; - brw_callback_t cb; - void *data; + int (*brw_callback)(struct obd_brw_set *, int phase); }; -int ll_sync_io_cb(struct io_cb_data *data, int err, int phase); -struct io_cb_data *ll_init_cb(void); - /* simple.c */ struct obd_run_ctxt; struct obd_ucred; -void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new, +void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx, struct obd_ucred *cred); -void pop_ctxt(struct obd_run_ctxt *saved); +void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx, + struct obd_ucred *cred); struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode); struct dentry *simple_mknod(struct dentry *dir, char *name, int mode); int lustre_fread(struct file *file, char *str, int len, loff_t *off); int lustre_fwrite(struct file *file, const char *str, int len, loff_t *off); int lustre_fsync(struct file *file); +#ifdef __KERNEL__ + static inline void l_dput(struct dentry *de) { if (!de || IS_ERR(de)) @@ -130,9 +146,9 @@ static inline void ll_sleep(int t) /* FIXME: This needs to validate pointers and cookies */ static inline void *lustre_handle2object(struct lustre_handle *handle) { - if (handle) + if (handle) return (void *)(unsigned long)(handle->addr); - return NULL; + return NULL; } static inline void ldlm_object2handle(void *object, struct lustre_handle *handle) @@ -140,23 +156,12 @@ static inline void ldlm_object2handle(void *object, struct lustre_handle *handle handle->addr = (__u64)(unsigned long)object; } -struct obd_statfs; -struct statfs; -void statfs_pack(struct obd_statfs *osfs, struct statfs *sfs); -void statfs_unpack(struct statfs *sfs, struct obd_statfs *osfs); -void obd_statfs_pack(struct obd_statfs *tgt, struct obd_statfs *src); -static inline void -obd_statfs_unpack(struct obd_statfs *tgt, struct obd_statfs *src) -{ - obd_statfs_pack(tgt, src); -} - #include /* * OBD IOCTLS */ -#define OBD_IOCTL_VERSION 0x00010001 +#define OBD_IOCTL_VERSION 0x00010002 struct obd_ioctl_data { uint32_t ioc_len; @@ -173,7 +178,10 @@ struct obd_ioctl_data { obd_size ioc_count; obd_off ioc_offset; uint32_t ioc_dev; - uint32_t ____padding; + uint32_t ioc_command; + + uint64_t ioc_nid; + uint32_t ioc_nal; /* buffers the kernel will treat as user pointers */ uint32_t ioc_plen1; @@ -268,8 +276,9 @@ static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data) printk("OBD ioctl: plen2 set but NULL pointer\n"); return 1; } - if (obd_ioctl_packlen(data) != data->ioc_len ) { - printk("OBD ioctl: packlen exceeds ioc_len\n"); + if (obd_ioctl_packlen(data) != data->ioc_len) { + printk("OBD ioctl: packlen exceeds ioc_len (%d != %d)\n", + obd_ioctl_packlen(data), data->ioc_len); return 1; } #if 0 @@ -289,7 +298,7 @@ static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data) printk("OBD ioctl: inlbuf3 not 0 terminated\n"); return 1; } -#endif +#endif return 0; } @@ -302,7 +311,7 @@ static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, data->ioc_len = obd_ioctl_packlen(data); data->ioc_version = OBD_IOCTL_VERSION; - if (*pbuf && obd_ioctl_packlen(data) > max) + if (*pbuf && data->ioc_len > max) return 1; if (*pbuf == NULL) { *pbuf = malloc(data->ioc_len); @@ -325,7 +334,34 @@ static inline int obd_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, return 0; } -#else +static inline int obd_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, + int max) +{ + char *ptr; + struct obd_ioctl_data *overlay; + + if (!pbuf) + return 1; + overlay = (struct obd_ioctl_data *)pbuf; + + /* Preserve the caller's buffer pointers */ + overlay->ioc_inlbuf1 = data->ioc_inlbuf1; + overlay->ioc_inlbuf2 = data->ioc_inlbuf2; + overlay->ioc_inlbuf3 = data->ioc_inlbuf3; + + memcpy(data, pbuf, sizeof(*data)); + + ptr = overlay->ioc_bulk; + if (data->ioc_inlbuf1) + LOGU(data->ioc_inlbuf1, data->ioc_inllen1, ptr); + if (data->ioc_inlbuf2) + LOGU(data->ioc_inlbuf2, data->ioc_inllen2, ptr); + if (data->ioc_inlbuf3) + LOGU(data->ioc_inlbuf3, data->ioc_inllen3, ptr); + + return 0; +} +#endif #include @@ -337,7 +373,6 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) int err; ENTRY; - err = copy_from_user(&hdr, (void *)arg, sizeof(hdr)); if ( err ) { EXIT; @@ -384,25 +419,26 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) } if (data->ioc_inllen2) { - data->ioc_inlbuf2 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1); + data->ioc_inlbuf2 = &data->ioc_bulk[0] + + size_round(data->ioc_inllen1); } if (data->ioc_inllen3) { - data->ioc_inlbuf3 = &data->ioc_bulk[0] + size_round(data->ioc_inllen1) + + data->ioc_inlbuf3 = &data->ioc_bulk[0] + + size_round(data->ioc_inllen1) + size_round(data->ioc_inllen2); } EXIT; return 0; } -#endif #define OBD_IOC_CREATE _IOR ('f', 101, long) #define OBD_IOC_SETUP _IOW ('f', 102, long) #define OBD_IOC_CLEANUP _IO ('f', 103 ) #define OBD_IOC_DESTROY _IOW ('f', 104, long) #define OBD_IOC_PREALLOCATE _IOWR('f', 105, long) -#define OBD_IOC_DEC_USE_COUNT _IO ('f', 106 ) + #define OBD_IOC_SETATTR _IOW ('f', 107, long) #define OBD_IOC_GETATTR _IOR ('f', 108, long) #define OBD_IOC_READ _IOWR('f', 109, long) @@ -429,22 +465,56 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) #define OBD_IOC_UUID2DEV _IOWR('f', 130, long) #define OBD_IOC_RECOVD_NEWCONN _IOWR('f', 131, long) -#define OBD_IOC_LOV_CONFIG _IOWR('f', 132, long) - -#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 133 ) +#define OBD_IOC_LOV_SET_CONFIG _IOWR('f', 132, long) +#define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 133, long) +#define OBD_IOC_LOV_CONFIG OBD_IOC_LOV_SET_CONFIG #define OBD_IOC_OPEN _IOWR('f', 134, long) #define OBD_IOC_CLOSE _IOWR('f', 135, long) #define OBD_IOC_RECOVD_FAILCONN _IOWR('f', 136, long) +#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 139 ) +#define OBD_IOC_NO_TRANSNO _IOW ('f', 140, long) +#define OBD_IOC_SET_READONLY _IOW ('f', 141, long) + +#define OBD_GET_VERSION _IOWR ('f', 144, long) + +#define OBD_IOC_ADD_UUID _IOWR ('f', 145, long) +#define OBD_IOC_DEL_UUID _IOWR ('f', 146, long) +#define OBD_IOC_CLOSE_UUID _IOWR ('f', 147, long) + +#define ECHO_IOC_GET_STRIPE _IOWR('f', 200, long) +#define ECHO_IOC_SET_STRIPE _IOWR('f', 201, long) +#define ECHO_IOC_ENQUEUE _IOWR('f', 202, long) +#define ECHO_IOC_CANCEL _IOWR('f', 203, long) + + +#define CHECKSUM_BULK 0 + +#if CHECKSUM_BULK +static inline void ost_checksum(__u64 *cksum, void *addr, int len) +{ + unsigned char *ptr = (unsigned char *)addr; + __u64 sum = 0; + + /* very stupid, but means I don't have to think about byte order */ + while (len-- > 0) + sum += *ptr++; + + *cksum = (*cksum << 2) + sum; +} +#else +#define ost_checksum(cksum, addr, len) do {} while (0) +#endif + /* * l_wait_event is a flexible sleeping function, permitting simple caller * configuration of interrupt and timeout sensitivity along with actions to * be performed in the event of either exception. * * Common usage looks like this: - * + * * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler, * intr_handler, callback_data); * rc = l_wait_event(waitq, condition, &lwi); @@ -462,8 +532,8 @@ static inline int obd_ioctl_getdata(char **buf, int *len, void *arg) * waitq or some similar mechanism, or an interrupt occurs (if the caller has * asked for interrupts to be detected). The timeout will only fire once, so * callers should take care that a timeout_handler which returns zero will take - * future steps to awaken the process. N.B. that these steps must include making - * the provided condition become true. + * future steps to awaken the process. N.B. that these steps must include + * making the provided condition become true. * * If the interrupt flag (lwi_signals) is non-zero, then the process will be * interruptible, and will be awakened by any "killable" signal (SIGTERM, @@ -482,95 +552,98 @@ struct l_wait_info { void *lwi_cb_data; }; -#define LWI_TIMEOUT(time, cb, data) \ -((struct l_wait_info) { \ - lwi_timeout: time, \ - lwi_on_timeout: cb, \ - lwi_cb_data: data \ +#define LWI_TIMEOUT(time, cb, data) \ +((struct l_wait_info) { \ + lwi_timeout: time, \ + lwi_on_timeout: cb, \ + lwi_cb_data: data \ }) -#define LWI_INTR(cb, data) \ -((struct l_wait_info) { \ - lwi_signals: 1, \ - lwi_on_signal: cb, \ - lwi_cb_data: data \ +#define LWI_INTR(cb, data) \ +((struct l_wait_info) { \ + lwi_signals: 1, \ + lwi_on_signal: cb, \ + lwi_cb_data: data \ }) -#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data) \ -((struct l_wait_info) { \ - lwi_timeout: time, \ - lwi_on_timeout: time_cb, \ - lwi_signals: 1, \ - lwi_on_signal: sig_cb, \ - lwi_cb_data: data \ +#define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data) \ +((struct l_wait_info) { \ + lwi_timeout: time, \ + lwi_on_timeout: time_cb, \ + lwi_signals: 1, \ + lwi_on_signal: sig_cb, \ + lwi_cb_data: data \ }) +#ifdef __KERNEL__ +#define l_sigismember sigismember +#else +#define l_sigismember(a,b) (*(a) & b) +#endif + /* XXX this should be one mask-check */ -#define l_killable_pending(task) \ -(sigismember(&(task->pending.signal), SIGKILL) || \ - sigismember(&(task->pending.signal), SIGINT) || \ - sigismember(&(task->pending.signal), SIGTERM)) - -#define __l_wait_event(wq, condition, info, ret) \ -do { \ - wait_queue_t __wait; \ - long __state; \ - int __timed_out = 0; \ - init_waitqueue_entry(&__wait, current); \ - \ - add_wait_queue(&wq, &__wait); \ - if (info->lwi_signals && !info->lwi_timeout) \ - __state = TASK_INTERRUPTIBLE; \ - else \ - __state = TASK_UNINTERRUPTIBLE; \ - for (;;) { \ - set_current_state(__state); \ - if (condition) \ - break; \ - if (__state == TASK_INTERRUPTIBLE && l_killable_pending(current)) { \ - CERROR("lwe: interrupt\n"); \ - if (info->lwi_on_signal) \ - info->lwi_on_signal(info->lwi_cb_data); \ - ret = -EINTR; \ - break; \ - } \ - if (info->lwi_timeout && !__timed_out) { \ - if (schedule_timeout(info->lwi_timeout) == 0) { \ - CERROR("lwe: timeout\n"); \ - __timed_out = 1; \ - if (!info->lwi_on_timeout || \ - info->lwi_on_timeout(info->lwi_cb_data)) { \ - ret = -ETIMEDOUT; \ - break; \ - } \ - /* We'll take signals after a timeout. */ \ - if (info->lwi_signals) { \ - __state = TASK_INTERRUPTIBLE; \ - /* Check for a pending interrupt. */ \ - if (info->lwi_signals && l_killable_pending(current)) { \ - CERROR("lwe: pending interrupt\n"); \ - if (info->lwi_on_signal) \ - info->lwi_on_signal(info->lwi_cb_data); \ - ret = -EINTR; \ - break; \ - } \ - } \ - } \ - } else { \ - schedule(); \ - } \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ +#define l_killable_pending(task) \ +(l_sigismember(&(task->pending.signal), SIGKILL) || \ + l_sigismember(&(task->pending.signal), SIGINT) || \ + l_sigismember(&(task->pending.signal), SIGTERM)) + +#define __l_wait_event(wq, condition, info, ret) \ +do { \ + wait_queue_t __wait; \ + long __state; \ + int __timed_out = 0; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + if (info->lwi_signals && !info->lwi_timeout) \ + __state = TASK_INTERRUPTIBLE; \ + else \ + __state = TASK_UNINTERRUPTIBLE; \ + for (;;) { \ + set_current_state(__state); \ + if (condition) \ + break; \ + if (__state == TASK_INTERRUPTIBLE && l_killable_pending(current)) {\ + if (info->lwi_on_signal) \ + info->lwi_on_signal(info->lwi_cb_data); \ + ret = -EINTR; \ + break; \ + } \ + if (info->lwi_timeout && !__timed_out) { \ + if (schedule_timeout(info->lwi_timeout) == 0) { \ + __timed_out = 1; \ + if (!info->lwi_on_timeout || \ + info->lwi_on_timeout(info->lwi_cb_data)) { \ + ret = -ETIMEDOUT; \ + break; \ + } \ + /* We'll take signals after a timeout. */ \ + if (info->lwi_signals) { \ + __state = TASK_INTERRUPTIBLE; \ + /* Check for a pending interrupt. */ \ + if (info->lwi_signals && l_killable_pending(current)) {\ + if (info->lwi_on_signal) \ + info->lwi_on_signal(info->lwi_cb_data); \ + ret = -EINTR; \ + break; \ + } \ + } \ + } \ + } else { \ + schedule(); \ + } \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ } while(0) -#define l_wait_event(wq, condition, info) \ -({ \ - int __ret = 0; \ - struct l_wait_info *__info = (info); \ - if (!(condition)) \ - __l_wait_event(wq, condition, __info, __ret); \ - __ret; \ +#define l_wait_event(wq, condition, info) \ +({ \ + int __ret = 0; \ + struct l_wait_info *__info = (info); \ + if (!(condition)) \ + __l_wait_event(wq, condition, __info, __ret); \ + __ret; \ }) #endif /* _LUSTRE_LIB_H */