extern unsigned int portal_printk;
extern unsigned int portal_cerror;
/* Debugging subsystems (32 bits, non-overlapping) */
-#define S_UNDEFINED (1 << 0)
-#define S_MDC (1 << 1)
-#define S_MDS (1 << 2)
-#define S_OSC (1 << 3)
-#define S_OST (1 << 4)
-#define S_CLASS (1 << 5)
-#define S_LOG (1 << 6)
-#define S_LLITE (1 << 7)
-#define S_RPC (1 << 8)
-#define S_MGMT (1 << 9)
-#define S_PORTALS (1 << 10)
-#define S_SOCKNAL (1 << 11)
-#define S_QSWNAL (1 << 12)
-#define S_PINGER (1 << 13)
-#define S_FILTER (1 << 14)
-#define S_PTLBD (1 << 15)
-#define S_ECHO (1 << 16)
-#define S_LDLM (1 << 17)
-#define S_LOV (1 << 18)
-#define S_GMNAL (1 << 19)
-#define S_PTLROUTER (1 << 20)
-#define S_COBD (1 << 21)
-#define S_IBNAL (1 << 22)
+#define S_UNDEFINED 0x00000001
+#define S_MDC 0x00000002
+#define S_MDS 0x00000004
+#define S_OSC 0x00000008
+#define S_OST 0x00000010
+#define S_CLASS 0x00000020
+#define S_LOG 0x00000040
+#define S_LLITE 0x00000080
+#define S_RPC 0x00000100
+#define S_MGMT 0x00000200
+#define S_PORTALS 0x00000400
+#define S_SOCKNAL 0x00000800
+#define S_QSWNAL 0x00001000
+#define S_PINGER 0x00002000
+#define S_FILTER 0x00004000
+#define S_PTLBD 0x00008000
+#define S_ECHO 0x00010000
+#define S_LDLM 0x00020000
+#define S_LOV 0x00040000
+#define S_GMNAL 0x00080000
+#define S_PTLROUTER 0x00100000
+#define S_COBD 0x00200000
+#define S_IBNAL 0x00400000
/* If you change these values, please keep portals/utils/debug.c
* up to date! */
/* Debugging masks (32 bits, non-overlapping) */
-#define D_TRACE (1 << 0) /* ENTRY/EXIT markers */
-#define D_INODE (1 << 1)
-#define D_SUPER (1 << 2)
-#define D_EXT2 (1 << 3) /* anything from ext2_debug */
-#define D_MALLOC (1 << 4) /* print malloc, free information */
-#define D_CACHE (1 << 5) /* cache-related items */
-#define D_INFO (1 << 6) /* general information */
-#define D_IOCTL (1 << 7) /* ioctl related information */
-#define D_BLOCKS (1 << 8) /* ext2 block allocation */
-#define D_NET (1 << 9) /* network communications */
-#define D_WARNING (1 << 10) /* CWARN(...) == CDEBUG (D_WARNING, ...) */
-#define D_BUFFS (1 << 11)
-#define D_OTHER (1 << 12)
-#define D_DENTRY (1 << 13)
-#define D_PORTALS (1 << 14) /* ENTRY/EXIT markers */
-#define D_PAGE (1 << 15) /* bulk page handling */
-#define D_DLMTRACE (1 << 16)
-#define D_ERROR (1 << 17) /* CERROR(...) == CDEBUG (D_ERROR, ...) */
-#define D_EMERG (1 << 18) /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
-#define D_HA (1 << 19) /* recovery and failover */
-#define D_RPCTRACE (1 << 20) /* for distributed debugging */
-#define D_VFSTRACE (1 << 21)
-#define D_READA (1 << 22) /* read-ahead */
+#define D_TRACE 0x00000001 /* ENTRY/EXIT markers */
+#define D_INODE 0x00000002
+#define D_SUPER 0x00000004
+#define D_EXT2 0x00000008 /* anything from ext2_debug */
+#define D_MALLOC 0x00000010 /* print malloc, free information */
+#define D_CACHE 0x00000020 /* cache-related items */
+#define D_INFO 0x00000040 /* general information */
+#define D_IOCTL 0x00000080 /* ioctl related information */
+#define D_BLOCKS 0x00000100 /* ext2 block allocation */
+#define D_NET 0x00000200 /* network communications */
+#define D_WARNING 0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */
+#define D_BUFFS 0x00000800
+#define D_OTHER 0x00001000
+#define D_DENTRY 0x00002000
+#define D_PORTALS 0x00004000 /* ENTRY/EXIT markers */
+#define D_PAGE 0x00008000 /* bulk page handling */
+#define D_DLMTRACE 0x00010000
+#define D_ERROR 0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */
+#define D_EMERG 0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
+#define D_HA 0x00080000 /* recovery and failover */
+#define D_RPCTRACE 0x00100000 /* for distributed debugging */
+#define D_VFSTRACE 0x00200000
+#define D_READA 0x00400000 /* read-ahead */
#ifdef __KERNEL__
# include <linux/sched.h> /* THREAD_SIZE */
}
ksock_conn_t *
-ksocknal_find_conn_locked (ksock_tx_t *tx, ksock_peer_t *peer)
+ksocknal_find_conn_locked (ksock_tx_t *tx, ksock_peer_t *peer)
{
struct list_head *tmp;
ksock_conn_t *typed = NULL;
int tnob = 0;
ksock_conn_t *fallback = NULL;
int fnob = 0;
-
+
/* Find the conn with the shortest tx queue */
list_for_each (tmp, &peer->ksnp_conns) {
ksock_conn_t *c = list_entry(tmp, ksock_conn_t, ksnc_list);
- int nob = atomic_read(&c->ksnc_tx_nob);
+ int nob = atomic_read(&c->ksnc_tx_nob) +
+ c->ksnc_sock->sk->sk_wmem_queued;
LASSERT (!c->ksnc_closing);
- don't call usermode_helper from ptlrpcd, DEFAULT upcall (2773)
- put magic in mount.lustre data, check for bad/NULL mount data (2529)
- MDS recovery shouldn't delete objects that it has given out (2730)
+ - if enqueue arrives after completion, don't clobber LVB (2819)
+ - don't unlock pages twice when trigger_group_io returns error (2814)
+ - don't deref NULL rq_repmsg if ldlm_handle_enqueue failed (2822)
+ - don't write pages to disk if there was an error (1450)
+ - don't ping imports that have recovery disabled (2676)
+ - take buffered bytes into account when balancing socknal conn (2817)
* miscellania
- return LL_SUPER_MAGIC from statfs for the filesystem type (1972)
static int cobd_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
int objcount, struct obd_ioobj *obj,
int niocount, struct niobuf_local *local,
- struct obd_trans_info *oti)
+ struct obd_trans_info *oti, int rc)
{
struct obd_export *cobd_exp;
- int rc;
if (exp->exp_obd == NULL)
return -EINVAL;
return -EOPNOTSUPP;
cobd_exp = exp->exp_obd->u.cobd.cobd_target_exp;
- rc = obd_commitrw(cmd, cobd_exp, oa, objcount, obj,niocount,local,oti);
+ rc = obd_commitrw(cmd, cobd_exp, oa, objcount, obj, niocount, local,
+ oti, rc);
return rc;
}
struct cache_obd *cobd;
if (obd == NULL) {
- CERROR("invalid client cookie "LPX64"\n",
+ CERROR("invalid client cookie "LPX64"\n",
exp->exp_handle.h_cookie);
return -EINVAL;
}
#ifdef __KERNEL__
-struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode);
-struct dentry *simple_mknod(struct dentry *dir, char *name, int mode);
+struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode, int fix);
+struct dentry *simple_mknod(struct dentry *dir, char *name, int mode, int fix);
int lustre_fread(struct file *file, void *buf, int len, loff_t *off);
int lustre_fwrite(struct file *file, const void *buf, int len, loff_t *off);
int lustre_fsync(struct file *file);
int (*o_commitrw)(int cmd, struct obd_export *exp, struct obdo *oa,
int objcount, struct obd_ioobj *obj,
int niocount, struct niobuf_local *local,
- struct obd_trans_info *oti);
+ struct obd_trans_info *oti, int rc);
int (*o_enqueue)(struct obd_export *, struct lov_stripe_md *,
__u32 type, ldlm_policy_data_t *, __u32 mode,
int *flags, void *bl_cb, void *cp_cb, void *gl_cb,
static inline int obd_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
int objcount, struct obd_ioobj *obj,
int niocount, struct niobuf_local *local,
- struct obd_trans_info *oti)
+ struct obd_trans_info *oti, int rc)
{
- int rc;
ENTRY;
OBD_CHECK_OP(exp->exp_obd, commitrw, -EOPNOTSUPP);
OBD_COUNTER_INCREMENT(exp->exp_obd, commitrw);
rc = OBP(exp->exp_obd, commitrw)(cmd, exp, oa, objcount, obj, niocount,
- local, oti);
+ local, oti, rc);
RETURN(rc);
}
if (rc == -ETIMEDOUT || rc == -EINTR || rc == -ENOTCONN) {
ldlm_del_waiting_lock(lock);
ldlm_failed_ast(lock, rc, "completion");
+ } else if (rc == -EINVAL) {
+ LDLM_DEBUG(lock, "lost the race -- client no longer has this "
+ "lock");
} else if (rc) {
LDLM_ERROR(lock, "client sent rc %d rq_status %d from "
- "completion AST\n", rc, req->rq_status);
+ "completion AST", rc, req->rq_status);
ldlm_lock_cancel(lock);
/* Server-side AST functions are called from ldlm_reprocess_all,
* which needs to be told to please restart its reprocessing. */
if (rc == -ETIMEDOUT || rc == -EINTR || rc == -ENOTCONN) {
ldlm_del_waiting_lock(lock);
ldlm_failed_ast(lock, rc, "glimpse");
+ } else if (rc == -EINVAL) {
+ LDLM_DEBUG(lock, "lost the race -- client no longer has this "
+ "lock");
} else if (rc) {
LDLM_ERROR(lock, "client sent rc %d rq_status %d from "
- "completion AST\n", rc, req->rq_status);
- ldlm_lock_cancel(lock);
+ "glimpse AST", rc, req->rq_status);
} else {
rc = res->lr_namespace->ns_lvbo->lvbo_update(res,
req->rq_repmsg, 0);
struct obd_device *obddev = req->rq_export->exp_obd;
struct ldlm_reply *dlm_rep;
struct ldlm_request *dlm_req;
- int rc, size[2] = {sizeof(*dlm_rep)};
+ int rc = 0, size[2] = {sizeof(*dlm_rep)};
__u32 flags;
- ldlm_error_t err;
+ ldlm_error_t err = ELDLM_OK;
struct ldlm_lock *lock = NULL;
void *cookie = NULL;
ENTRY;
lustre_swab_ldlm_request);
if (dlm_req == NULL) {
CERROR ("Can't unpack dlm_req\n");
- RETURN (-EFAULT);
+ GOTO(out, rc = -EFAULT);
}
flags = dlm_req->lock_flags;
blocking_callback, completion_callback,
glimpse_callback, NULL, 0);
if (!lock)
- GOTO(out, err = -ENOMEM);
+ GOTO(out, rc = -ENOMEM);
do_gettimeofday(&lock->l_enqueued_time);
memcpy(&lock->l_remote_handle, &dlm_req->lock_handle1,
rc = lustre_pack_reply(req, buffers, size, NULL);
if (rc)
- RETURN(rc);
+ GOTO(out, rc);
}
if (dlm_req->lock_desc.l_resource.lr_type != LDLM_PLAIN)
EXIT;
out:
req->rq_status = err;
+ if (req->rq_reply_state == NULL) {
+ err = lustre_pack_reply(req, 0, NULL, NULL);
+ if (rc == 0)
+ rc = err;
+ }
/* The LOCK_CHANGED code in ldlm_lock_enqueue depends on this
* ldlm_reprocess_all. If this moves, revisit that code. -phil */
if (lock) {
LDLM_DEBUG(lock, "server-side enqueue handler, sending reply"
- "(err=%d)", err);
+ "(err=%d, rc=%d)", err, rc);
if (lock->l_resource->lr_lvb_len > 0) {
void *lvb = lustre_msg_buf(req->rq_repmsg, 1,
ldlm_reprocess_all(lock->l_resource);
LDLM_LOCK_PUT(lock);
}
- LDLM_DEBUG_NOLOCK("server-side enqueue handler END (lock %p)", lock);
+ LDLM_DEBUG_NOLOCK("server-side enqueue handler END (lock %p, rc %d)",
+ lock, rc);
- return 0;
+ return rc;
}
int ldlm_handle_convert(struct ptlrpc_request *req)
LDLM_DEBUG(lock, "enqueue reply includes blocking AST");
}
- if (lvb_len) {
+ /* If the lock has already been granted by a completion AST, don't
+ * clobber the LVB with an older one. */
+ if (lvb_len && (lock->l_req_mode != lock->l_granted_mode)) {
void *tmplvb;
tmplvb = lustre_swab_repbuf(req, 1, lvb_len, lvb_swabber);
if (tmplvb == NULL)
{
struct list_head *bucket, *tmp;
struct ldlm_resource *res = NULL;
- int rc;
ENTRY;
LASSERT(ns != NULL);
l_unlock(&ns->ns_lock);
if (create && ns->ns_lvbo && ns->ns_lvbo->lvbo_init) {
- rc = ns->ns_lvbo->lvbo_init(res);
- if (rc) {
- CERROR("lvbo_init failure %d\n", rc);
- LASSERT(ldlm_resource_putref(res) == 1);
- res = NULL;
- }
+ int rc = ns->ns_lvbo->lvbo_init(res);
+ if (rc)
+ CERROR("lvbo_init failed for resource "LPU64": rc %d\n",
+ name.name[0], rc);
}
RETURN(res);
EXPORT_SYMBOL(pop_ctxt);
/* utility to make a file */
-struct dentry *simple_mknod(struct dentry *dir, char *name, int mode)
+struct dentry *simple_mknod(struct dentry *dir, char *name, int mode, int fix)
{
struct dentry *dchild;
int err = 0;
GOTO(out_err, err = -EEXIST);
/* Fixup file permissions if necessary */
- if ((old_mode & S_IALLUGO) != (mode & S_IALLUGO)) {
+ if (fix && (old_mode & S_IALLUGO) != (mode & S_IALLUGO)) {
CWARN("fixing permissions on %s from %o to %o\n",
name, old_mode, mode);
dchild->d_inode->i_mode = (mode & S_IALLUGO) |
EXPORT_SYMBOL(simple_mknod);
/* utility to make a directory */
-struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode)
+struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode, int fix)
{
struct dentry *dchild;
int err = 0;
GOTO(out_err, err = -ENOTDIR);
/* Fixup directory permissions if necessary */
- if ((old_mode & S_IALLUGO) != (mode & S_IALLUGO)) {
+ if (fix && (old_mode & S_IALLUGO) != (mode & S_IALLUGO)) {
CWARN("fixing permissions on %s from %o to %o\n",
name, old_mode, mode);
dchild->d_inode->i_mode = (mode & S_IALLUGO) |
/* setup the directory tree */
push_ctxt(&saved, &obd->obd_ctxt, NULL);
- dentry = simple_mkdir(current->fs->pwd, "ROOT", 0755);
+ dentry = simple_mkdir(current->fs->pwd, "ROOT", 0755, 0);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
CERROR("cannot create ROOT directory: rc = %d\n", rc);
}
mds->mds_fid_de = dentry;
- dentry = simple_mkdir(current->fs->pwd, "PENDING", 0777);
+ dentry = simple_mkdir(current->fs->pwd, "PENDING", 0777, 1);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
CERROR("cannot create PENDING directory: rc = %d\n", rc);
}
mds->mds_pending_dir = dentry;
- dentry = simple_mkdir(current->fs->pwd, "LOGS", 0777);
+ dentry = simple_mkdir(current->fs->pwd, "LOGS", 0777, 1);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
CERROR("cannot create LOGS directory: rc = %d\n", rc);
}
mds->mds_logs_dir = dentry;
- dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777);
+ dentry = simple_mkdir(current->fs->pwd, "OBJECTS", 0777, 1);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
CERROR("cannot create OBJECTS directory: rc = %d\n", rc);
int echo_commitrw(int cmd, struct obd_export *export, struct obdo *oa,
int objcount, struct obd_ioobj *obj, int niocount,
- struct niobuf_local *res, struct obd_trans_info *oti)
+ struct niobuf_local *res, struct obd_trans_info *oti, int rc)
{
struct obd_device *obd;
struct niobuf_local *r = res;
- int i, vrc = 0, rc = 0;
+ int i, vrc = 0;
ENTRY;
obd = export->exp_obd;
if (obd == NULL)
RETURN(-EINVAL);
+ if (rc)
+ GOTO(commitrw_cleanup, rc);
+
if ((cmd & OBD_BRW_RWMASK) == OBD_BRW_READ) {
CDEBUG(D_PAGE, "reading %d obdos with %d IOs\n",
objcount, niocount);
struct niobuf_remote *rnb;
obd_off off;
obd_size npages, tot_pages;
- int i, ret = 0, err = 0;
+ int i, ret = 0;
ENTRY;
if (count <= 0 || (count & (PAGE_SIZE - 1)) != 0 ||
struct page *page = lnb[i].page;
/* read past eof? */
- if (page == NULL && lnb[i].rc == 0)
+ if (page == NULL && lnb[i].rc == 0)
continue;
- if (rw == OBD_BRW_WRITE)
- echo_page_debug_setup(lsm, page, rw, oa->o_id,
- rnb[i].offset,
+ if (rw == OBD_BRW_WRITE)
+ echo_page_debug_setup(lsm, page, rw, oa->o_id,
+ rnb[i].offset,
rnb[i].len);
else
- echo_page_debug_check(lsm, page, oa->o_id,
- rnb[i].offset,
+ echo_page_debug_check(lsm, page, oa->o_id,
+ rnb[i].offset,
rnb[i].len);
}
- ret = obd_commitrw(rw, exp, oa, 1, &ioo, npages, lnb, oti);
+ ret = obd_commitrw(rw, exp, oa, 1, &ioo, npages, lnb, oti, ret);
if (ret != 0)
GOTO(out, ret);
- if (err)
- GOTO(out, ret = err);
}
out:
RETURN(ret);
}
-int echo_client_brw_ioctl(int rw, struct obd_export *exp,
+int echo_client_brw_ioctl(int rw, struct obd_export *exp,
struct obd_ioctl_data *data)
{
struct obd_device *obd = class_exp2obd(exp);
int i, rc = 0, cleanup_phase = 0;
ENTRY;
- O_dentry = simple_mkdir(current->fs->pwd, "O", 0700);
+ O_dentry = simple_mkdir(current->fs->pwd, "O", 0700, 1);
CDEBUG(D_INODE, "got/created O: %p\n", O_dentry);
if (IS_ERR(O_dentry)) {
rc = PTR_ERR(O_dentry);
loff_t off = 0;
sprintf(name, "%d", i);
- dentry = simple_mkdir(O_dentry, name, 0700);
+ dentry = simple_mkdir(O_dentry, name, 0700, 1);
CDEBUG(D_INODE, "got/created O/%s: %p\n", name, dentry);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
char dir[20];
snprintf(dir, sizeof(dir), "d%u", i);
- dentry = simple_mkdir(O_dentry, dir, 0700);
+ dentry = simple_mkdir(O_dentry, dir, 0700, 1);
CDEBUG(D_INODE, "got/created O/0/%s: %p\n", dir,dentry);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
obd_size tot_dirty = 0, tot_pending = 0, tot_granted = 0;
obd_size fo_tot_dirty, fo_tot_pending, fo_tot_granted;
+ if (list_empty(&obd->obd_exports))
+ return;
+
spin_lock(&obd->obd_osfs_lock);
spin_lock(&obd->obd_dev_lock);
list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
struct filter_obd *filter = &obd->u.filter;
struct filter_export_data *fed = &exp->exp_filter_data;
- filter_grant_sanity_check(obd, __FUNCTION__);
-
spin_lock(&obd->obd_osfs_lock);
CDEBUG(D_CACHE, "%s: cli %s/%p dirty %lu pend %lu grant %lu\n",
obd->obd_name, exp->exp_client_uuid.uuid, exp,
exp->exp_flags = flags;
spin_unlock_irqrestore(&exp->exp_lock, irqflags);
+ if (!(flags & OBD_OPT_FORCE))
+ filter_grant_sanity_check(obd, __FUNCTION__);
filter_grant_discard(exp);
/* Disconnect early so that clients can't keep using export */
/* Do this twice in case a BRW arrived between the first call and
* the class_export_unlink() call (bug 2663) */
+ if (!(flags & OBD_OPT_FORCE))
+ filter_grant_sanity_check(obd, __FUNCTION__);
filter_grant_discard(exp);
ldlm_cancel_locks_for_export(exp);
struct niobuf_local *, struct obd_trans_info *);
int filter_commitrw(int cmd, struct obd_export *, struct obdo *, int objcount,
struct obd_ioobj *, int niocount, struct niobuf_local *,
- struct obd_trans_info *);
+ struct obd_trans_info *, int rc);
int filter_brw(int cmd, struct obd_export *, struct obdo *,
struct lov_stripe_md *, obd_count oa_bufs, struct brw_page *,
struct obd_trans_info *);
/* filter_io_*.c */
int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
struct obd_ioobj *obj, int niocount,
- struct niobuf_local *res, struct obd_trans_info *oti);
+ struct niobuf_local *res, struct obd_trans_info *oti,
+ int rc);
obd_size filter_grant_space_left(struct obd_export *exp);
long filter_grant(struct obd_export *exp, obd_size current_grant,
obd_size want, obd_size fs_space_left);
static int filter_commitrw_read(struct obd_export *exp, struct obdo *oa,
int objcount, struct obd_ioobj *obj,
int niocount, struct niobuf_local *res,
- struct obd_trans_info *oti)
+ struct obd_trans_info *oti, int rc)
{
struct obd_ioobj *o;
struct niobuf_local *lnb;
page_cache_release(lnb->page);
}
}
+
if (res->dentry != NULL)
f_dput(res->dentry);
- RETURN(0);
+ RETURN(rc);
}
void flip_into_page_cache(struct inode *inode, struct page *new_page)
int filter_commitrw(int cmd, struct obd_export *exp, struct obdo *oa,
int objcount, struct obd_ioobj *obj, int niocount,
- struct niobuf_local *res, struct obd_trans_info *oti)
+ struct niobuf_local *res, struct obd_trans_info *oti,int rc)
{
if (cmd == OBD_BRW_WRITE)
return filter_commitrw_write(exp, oa, objcount, obj, niocount,
- res, oti);
+ res, oti, rc);
if (cmd == OBD_BRW_READ)
return filter_commitrw_read(exp, oa, objcount, obj, niocount,
- res, oti);
+ res, oti, rc);
LBUG();
return -EPROTO;
}
kunmap(pga[i].pg);
}
- ret = filter_commitrw(cmd, exp, oa, 1, &ioo, oa_bufs, lnb, oti);
+ ret = filter_commitrw(cmd, exp, oa, 1, &ioo, oa_bufs, lnb, oti, ret);
out:
if (lnb)
int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, int objcount,
struct obd_ioobj *obj, int niocount,
- struct niobuf_local *res, struct obd_trans_info *oti)
+ struct niobuf_local *res, struct obd_trans_info *oti,
+ int rc)
{
struct obd_device *obd = exp->exp_obd;
struct obd_run_ctxt saved;
struct iattr iattr = { 0 };
struct kiobuf *iobuf;
struct inode *inode = NULL;
- int rc = 0, i, n, cleanup_phase = 0, err;
+ int i, n, cleanup_phase = 0, err;
unsigned long now = jiffies; /* DEBUGGING OST TIMEOUTS */
void *wait_handle;
ENTRY;
LASSERT(objcount == 1);
LASSERT(current->journal_info == NULL);
+ if (rc != 0)
+ GOTO(cleanup, rc);
+
rc = alloc_kiovec(1, &iobuf);
if (rc)
GOTO(cleanup, rc);
lvb->lvb_size = dentry->d_inode->i_size;
lvb->lvb_time = LTIME_S(dentry->d_inode->i_mtime);
+ CDEBUG(D_DLMTRACE, "res: "LPU64" initial lvb size: "LPU64", time: "
+ LPU64"\n", res->lr_name.name[0], lvb->lvb_size, lvb->lvb_time);
out:
if (oa)
lvb->lvb_size = dentry->d_inode->i_size;
lvb->lvb_time = LTIME_S(dentry->d_inode->i_mtime);
- CDEBUG(D_DLMTRACE, "res: "LPU64" initial lvb size: "LPU64", time: "
+ CDEBUG(D_DLMTRACE, "res: "LPU64" disk lvb size: "LPU64", time: "
LPU64"\n", res->lr_name.name[0], lvb->lvb_size, lvb->lvb_time);
f_dput(dentry);
struct client_obd *cli = &exp->exp_obd->u.cli;
ENTRY;
- if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
- RETURN(-EIO);
-
if (loi == NULL)
loi = &lsm->lsm_oinfo[0];
policy, mode, flags, bl_cb, cp_cb, gl_cb, data,
&lvb, sizeof(lvb), lustre_swab_ost_lvb, lockh);
- if ((*flags & LDLM_FL_HAS_INTENT && rc == ELDLM_LOCK_ABORTED) || !rc)
+ if ((*flags & LDLM_FL_HAS_INTENT && rc == ELDLM_LOCK_ABORTED) || !rc) {
+ CDEBUG(D_INODE, "received kms == "LPU64"\n", lvb.lvb_size);
lsm->lsm_oinfo->loi_rss = lvb.lvb_size;
+ }
RETURN(rc);
}
if (page_rc != 0) { /* some data! */
LASSERT (local_nb[i].page != NULL);
ptlrpc_prep_bulk_page(desc, local_nb[i].page,
- pp_rnb[i].offset & (PAGE_SIZE - 1),
+ pp_rnb[i].offset & (PAGE_SIZE-1),
page_rc);
}
} else if (!desc->bd_success ||
desc->bd_nob_transferred != desc->bd_nob) {
DEBUG_REQ(D_ERROR, req, "%s bulk PUT %d(%d)",
- desc->bd_success ?
+ desc->bd_success ?
"truncated" : "network error on",
- desc->bd_nob_transferred,
+ desc->bd_nob_transferred,
desc->bd_nob);
/* XXX should this be a different errno? */
rc = -ETIMEDOUT;
/* Must commit after prep above in all cases */
rc = obd_commitrw(OBD_BRW_READ, req->rq_export, &body->oa, 1,
- ioo, npages, local_nb, &oti);
+ ioo, npages, local_nb, &oti, rc);
if (rc == 0) {
repbody = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*repbody));
int size[2] = { sizeof(*body) };
int objcount, niocount, npages;
int comms_error = 0;
- int rc, rc2, swab, i, j;
+ int rc, swab, i, j;
char str[PTL_NALFMT_SIZE];
ENTRY;
}
#endif
/* Must commit after prep above in all cases */
- rc2 = obd_commitrw(OBD_BRW_WRITE, req->rq_export, &repbody->oa,
- objcount, ioo, npages, local_nb, oti);
+ rc = obd_commitrw(OBD_BRW_WRITE, req->rq_export, &repbody->oa,
+ objcount, ioo, npages, local_nb, oti, rc);
if (rc == 0) {
/* set per-requested niobuf return codes */
}
LASSERT(j == npages);
}
- if (rc == 0)
- rc = rc2;
out_bulk:
ptlrpc_free_bulk(desc);
extern unsigned int portal_printk;
extern unsigned int portal_cerror;
/* Debugging subsystems (32 bits, non-overlapping) */
-#define S_UNDEFINED (1 << 0)
-#define S_MDC (1 << 1)
-#define S_MDS (1 << 2)
-#define S_OSC (1 << 3)
-#define S_OST (1 << 4)
-#define S_CLASS (1 << 5)
-#define S_LOG (1 << 6)
-#define S_LLITE (1 << 7)
-#define S_RPC (1 << 8)
-#define S_MGMT (1 << 9)
-#define S_PORTALS (1 << 10)
-#define S_SOCKNAL (1 << 11)
-#define S_QSWNAL (1 << 12)
-#define S_PINGER (1 << 13)
-#define S_FILTER (1 << 14)
-#define S_PTLBD (1 << 15)
-#define S_ECHO (1 << 16)
-#define S_LDLM (1 << 17)
-#define S_LOV (1 << 18)
-#define S_GMNAL (1 << 19)
-#define S_PTLROUTER (1 << 20)
-#define S_COBD (1 << 21)
-#define S_IBNAL (1 << 22)
+#define S_UNDEFINED 0x00000001
+#define S_MDC 0x00000002
+#define S_MDS 0x00000004
+#define S_OSC 0x00000008
+#define S_OST 0x00000010
+#define S_CLASS 0x00000020
+#define S_LOG 0x00000040
+#define S_LLITE 0x00000080
+#define S_RPC 0x00000100
+#define S_MGMT 0x00000200
+#define S_PORTALS 0x00000400
+#define S_SOCKNAL 0x00000800
+#define S_QSWNAL 0x00001000
+#define S_PINGER 0x00002000
+#define S_FILTER 0x00004000
+#define S_PTLBD 0x00008000
+#define S_ECHO 0x00010000
+#define S_LDLM 0x00020000
+#define S_LOV 0x00040000
+#define S_GMNAL 0x00080000
+#define S_PTLROUTER 0x00100000
+#define S_COBD 0x00200000
+#define S_IBNAL 0x00400000
/* If you change these values, please keep portals/utils/debug.c
* up to date! */
/* Debugging masks (32 bits, non-overlapping) */
-#define D_TRACE (1 << 0) /* ENTRY/EXIT markers */
-#define D_INODE (1 << 1)
-#define D_SUPER (1 << 2)
-#define D_EXT2 (1 << 3) /* anything from ext2_debug */
-#define D_MALLOC (1 << 4) /* print malloc, free information */
-#define D_CACHE (1 << 5) /* cache-related items */
-#define D_INFO (1 << 6) /* general information */
-#define D_IOCTL (1 << 7) /* ioctl related information */
-#define D_BLOCKS (1 << 8) /* ext2 block allocation */
-#define D_NET (1 << 9) /* network communications */
-#define D_WARNING (1 << 10) /* CWARN(...) == CDEBUG (D_WARNING, ...) */
-#define D_BUFFS (1 << 11)
-#define D_OTHER (1 << 12)
-#define D_DENTRY (1 << 13)
-#define D_PORTALS (1 << 14) /* ENTRY/EXIT markers */
-#define D_PAGE (1 << 15) /* bulk page handling */
-#define D_DLMTRACE (1 << 16)
-#define D_ERROR (1 << 17) /* CERROR(...) == CDEBUG (D_ERROR, ...) */
-#define D_EMERG (1 << 18) /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
-#define D_HA (1 << 19) /* recovery and failover */
-#define D_RPCTRACE (1 << 20) /* for distributed debugging */
-#define D_VFSTRACE (1 << 21)
-#define D_READA (1 << 22) /* read-ahead */
+#define D_TRACE 0x00000001 /* ENTRY/EXIT markers */
+#define D_INODE 0x00000002
+#define D_SUPER 0x00000004
+#define D_EXT2 0x00000008 /* anything from ext2_debug */
+#define D_MALLOC 0x00000010 /* print malloc, free information */
+#define D_CACHE 0x00000020 /* cache-related items */
+#define D_INFO 0x00000040 /* general information */
+#define D_IOCTL 0x00000080 /* ioctl related information */
+#define D_BLOCKS 0x00000100 /* ext2 block allocation */
+#define D_NET 0x00000200 /* network communications */
+#define D_WARNING 0x00000400 /* CWARN(...) == CDEBUG (D_WARNING, ...) */
+#define D_BUFFS 0x00000800
+#define D_OTHER 0x00001000
+#define D_DENTRY 0x00002000
+#define D_PORTALS 0x00004000 /* ENTRY/EXIT markers */
+#define D_PAGE 0x00008000 /* bulk page handling */
+#define D_DLMTRACE 0x00010000
+#define D_ERROR 0x00020000 /* CERROR(...) == CDEBUG (D_ERROR, ...) */
+#define D_EMERG 0x00040000 /* CEMERG(...) == CDEBUG (D_EMERG, ...) */
+#define D_HA 0x00080000 /* recovery and failover */
+#define D_RPCTRACE 0x00100000 /* for distributed debugging */
+#define D_VFSTRACE 0x00200000
+#define D_READA 0x00400000 /* read-ahead */
#ifdef __KERNEL__
# include <linux/sched.h> /* THREAD_SIZE */
}
ksock_conn_t *
-ksocknal_find_conn_locked (ksock_tx_t *tx, ksock_peer_t *peer)
+ksocknal_find_conn_locked (ksock_tx_t *tx, ksock_peer_t *peer)
{
struct list_head *tmp;
ksock_conn_t *typed = NULL;
int tnob = 0;
ksock_conn_t *fallback = NULL;
int fnob = 0;
-
+
/* Find the conn with the shortest tx queue */
list_for_each (tmp, &peer->ksnp_conns) {
ksock_conn_t *c = list_entry(tmp, ksock_conn_t, ksnc_list);
- int nob = atomic_read(&c->ksnc_tx_nob);
+ int nob = atomic_read(&c->ksnc_tx_nob) +
+ c->ksnc_sock->sk->sk_wmem_queued;
LASSERT (!c->ksnc_closing);
(obd_timeout * HZ);
ptlrpc_initiate_recovery(imp);
}
- else if (level != LUSTRE_IMP_FULL) {
+ else if (level != LUSTRE_IMP_FULL ||
+ imp->imp_obd->obd_no_recov) {
CDEBUG(D_HA,
- "not pinging %s "
- "(in recovery: %s)\n",
+ "not pinging %s (in recovery "
+ " or recovery disabled: %s)\n",
imp->imp_target_uuid.uuid,
ptlrpc_import_state_name(level));
}
--- /dev/null
+#!/bin/sh -e
+CVS=${CVS:-cvs}
+
+if [ $# != 2 ]; then
+ echo "This creates a new branch in CVS. Usage: $0 parent child"
+ exit
+fi
+
+parent=$1
+child=$2
+CHILD=`echo $child | sed -e "s/^b_//" | tr "[a-z]" "[A-Z]"`
+module=lustre
+
+case $parent in
+ HEAD) : ;;
+ b_*|b1*) : ;;
+ *) parent="b_$parent" ;;
+esac
+case $child in
+ HEAD) : ;;
+ b_*|b1*) : ;;
+ *) child="b_$child"
+esac
+
+if [ "$parent" != "HEAD" -a "`cat CVS/Tag`" != "T$parent" ]; then
+ echo "This script must be run within the $parent branch"
+ exit 1
+fi
+
+echo parent: $parent CHILD: $CHILD child: $child date: $date
+
+echo -n "tagging $parent as '${CHILD}_BASE' ...."
+$CVS rtag -r $parent ${CHILD}_BASE $module
+echo "done"
+echo -n "branching $child at ${CHILD}_BASE' ...."
+$CVS rtag -b -r ${CHILD}_BASE $child $module
+echo -n "updating to $child ...."
+$CVS update -r $child
+echo "done"
# lustre.spec
-%define version 4pre1.2.0
+%define version v1_2_0pre5
%define kversion @LINUXRELEASE@
%define linuxdir @LINUX@
%define enable_doc @ENABLE_DOC@
if [ "$CONF_SANITY" != "no" ]; then
sh conf-sanity.sh
fi
+
+if [ "$REPLAY_OST_SINGLE" != "no" ]; then
+ sh replay-ost-single.sh
+fi
+
+if [ "$RECOVERY_SMALL" != "no" ]; then
+ sh recovery-small.sh
+fi
}
stop_mds() {
echo "stop mds service on `facet_active_host mds`"
- stop mds $@ || return 97
+ stop mds $@ || return 97
}
start_ost() {
stop_ost() {
echo "stop ost service on `facet_active_host ost`"
- stop ost $@ || return 98
+ stop ost $@ || return 98
}
mount_client() {
setup() {
start_ost
start_mds
- mount_client $MOUNT
+ mount_client $MOUNT
}
cleanup() {
stop_mds || return 201
stop_ost || return 202
# catch case where these return just fine, but modules are still not unloaded
- /sbin/lsmod | grep -q portals
+ /sbin/lsmod | grep -q portals
if [ 1 -ne $? ]; then
echo "modules still loaded..."
return 203
test_0() {
start_ost
start_mds
- mount_client $MOUNT
+ mount_client $MOUNT
check_mount || return 41
cleanup || return $?
}
test_1() {
start_ost
echo "start ost second time..."
- start ost --reformat $OSTLCONFARGS
+ start ost --reformat $OSTLCONFARGS
start_mds
mount_client $MOUNT
check_mount || return 42
start_ost
start_mds
echo "start mds second time.."
- start mds --reformat $MDSLCONFARGS
+ start mds --reformat $MDSLCONFARGS
- mount_client $MOUNT
+ mount_client $MOUNT
check_mount || return 43
cleanup || return $?
}
run_test 2 "start up mds twice"
test_3() {
- setup
+ setup
mount_client $MOUNT
check_mount || return 44
setup
touch $DIR/$tfile || return 85
stop_ost --force
- cleanup
+ cleanup
eno=$?
# ok for ost to fail shutdown
if [ 202 -ne $eno ]; then
touch $DIR/$tfile || return 1
stop_mds --force || return 2
- # cleanup may return an error from the failed
- # disconnects; for now I'll consider this successful
+ # cleanup may return an error from the failed
+ # disconnects; for now I'll consider this successful
# if all the modules have unloaded.
umount $MOUNT &
UMOUNT_PID=$!
echo "killing umount"
kill -TERM $UMOUNT_PID
echo "waiting for umount to finish"
- wait $UMOUNT_PID
+ wait $UMOUNT_PID
# cleanup client modules
- $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null
+ $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null
# stop_mds is a no-op here, and should not fail
stop_mds || return 4
stop_mds
[ -d $MOUNT ] || mkdir -p $MOUNT
- $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null
+ $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null
llmount $mds_HOST://mds_svc/client_facet $MOUNT && exit 1
# cleanup client modules
- $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null
+ $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null
# stop_mds is a no-op here, and should not fail
stop_mds || return 2
start_mds
[ -d $MOUNT ] || mkdir -p $MOUNT
- $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null
+ $LCONF --nosetup --node client_facet $XMLCONFIG > /dev/null
llmount $mds_HOST://wrong_mds_svc/client_facet $MOUNT && exit 1
# cleanup client modules
- $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null
+ $LCONF --cleanup --nosetup --node client_facet $XMLCONFIG > /dev/null
stop_mds || return 2
stop_ost || return 3
start_ost
start_mds
- mount_client $MOUNT
- mount_client $MOUNT2
+ mount_client $MOUNT
+ mount_client $MOUNT2
check_mount2 || return 45
umount $MOUNT
- umount_client $MOUNT2
+ umount_client $MOUNT2
stop_mds
stop_ost
# backup the old values of PTLDEBUG and SUBSYSTEM
OLDPTLDEBUG=$PTLDEBUG
OLDSUBSYSTEM=$SUBSYSTEM
-
+
# generate new configuration file with lmc --ptldebug and --subsystem
PTLDEBUG="trace"
SUBSYSTEM="mdc"
add_ost ost --dev $OSTDEV --size $OSTSIZE
add_client client mds --path $MOUNT --ost ost_svc || return $?
echo "Default lov config success!"
-
+
[ -f "$XMLCONFIG" ] && rm -f $XMLCONFIG
add_mds mds --dev $MDSDEV --size $MDSSIZE
add_ost ost --dev $OSTDEV --size $OSTSIZE
else
echo "matched double quote fail"
return 1
- fi
+ fi
rm -f $XMLCONFIG
rm -f $BATCHFILE
echo "--add net --node localhost --nid localhost.localdomain --nettype tcp" > $BATCHFILE
add_lov lov1 mds --stripe_sz $STRIPE_BYTES\
--stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
add_ost ost --lov lov1 --dev $OSTDEV --size $OSTSIZE \
- --mkfsoptions "-Llabel_conf_15"
+ --mkfsoptions "-Llabel_conf_14"
add_client client mds --lov lov1 --path $MOUNT
FOUNDSTRING=`awk -F"<" '/<mkfsoptions>/{print $2}' $XMLCONFIG`
- EXPECTEDSTRING="mkfsoptions>-Llabel_conf_15"
+ EXPECTEDSTRING="mkfsoptions>-Llabel_conf_14"
if [ $EXPECTEDSTRING != $FOUNDSTRING ]; then
echo "Error: expected: $EXPECTEDSTRING; found: $FOUNDSTRING"
return 1
start_ost
start_mds
mount_client $MOUNT || return $?
- if [ -z "`dumpe2fs -h $OSTDEV | grep label_conf_15`" ]; then
+ if [ -z "`dumpe2fs -h $OSTDEV | grep label_conf_14`" ]; then
echo "Error: the mkoptions not applied to mke2fs of ost."
return 1
fi
}
run_test 14 "test mkfsoptions of ost for lmc and lconf"
-test_15() {
- start_ost
- start_mds
- echo "mount lustre on ${MOUNT} with $MOUNTLUSTRE....."
- [ -f "$MOUNTLUSTRE" ] && rm -f $MOUNTLUSTRE
- [ ! `cp $LUSTRE/utils/llmount $MOUNTLUSTRE` ] || return $?
- do_node `hostname` mkdir $MOUNT 2> /dev/null || :
- do_node `hostname` mount -t lustre -o nettype=$NETTYPE `facet_active_host mds`:/mds_svc/client_facet $MOUNT || return $?
- echo "mount lustre on ${MOUNT} with $MOUNTLUSTRE: success"
- [ -d /r ] && $LCTL modules > /r/tmp/ogdb-`hostname`
- check_mount || return 41
- cleanup || return $?
+cleanup_15() {
+ trap 0
+ [ -f $MOUNTLUSTRE ] && echo "remove $MOUNTLUSTRE" && rm -f $MOUNTLUSTRE
+ if [ -f $MOUNTLUSTRE.sav ]; then
+ echo "return original $MOUNTLUSTRE.sav to $MOUNTLUSTRE"
+ mv $MOUNTLUSTRE.sav $MOUNTLUSTRE
+ fi
+}
- start_ost
- start_mds
- [ -f "$MOUNTLUSTRE" ] && rm -f $MOUNTLUSTRE
- echo "mount lustre on ${MOUNT} without $MOUNTLUSTRE....."
- do_node `hostname` mkdir $MOUNT 2> /dev/null || :
- do_node `hostname` mount -t lustre -o nettype=$NETTYPE `facet_active_host mds`:/mds_svc/client_facet $MOUNT && return $?
- echo "mount lustre on ${MOUNT} without $MOUNTLUSTRE should return error: success"
- [ -d /r ] && $LCTL modules > /r/tmp/ogdb-`hostname`
- check_mount || return 41
- cleanup || return $?
+test_15() {
+ start_ost
+ start_mds
+ echo "mount lustre on ${MOUNT} with $MOUNTLUSTRE....."
+ if [ -f "$MOUNTLUSTRE" ]; then
+ echo "save $MOUNTLUSTRE to $MOUNTLUSTRE.sav"
+ mv $MOUNTLUSTRE $MOUNTLUSTRE.sav
+ fi
+ [ -f "$MOUNTLUSTRE" ] && echo "can't move $MOUNTLUSTRE" && return 40
+ trap cleanup_15 EXIT INT
+ [ ! `cp $LUSTRE/utils/llmount $MOUNTLUSTRE` ] || return $?
+ do_node `hostname` mkdir -p $MOUNT 2> /dev/null
+ # load llite module on the client if it isn't in /lib/modules
+ do_node `hostname` lconf --nosetup --node client_facet $XMLCONFIG
+ do_node `hostname` mount -t lustre -o nettype=$NETTYPE \
+ `facet_active_host mds`:/mds_svc/client_facet $MOUNT ||return $?
+ echo "mount lustre on $MOUNT with $MOUNTLUSTRE: success"
+ [ -d /r ] && $LCTL modules > /r/tmp/ogdb-`hostname`
+ check_mount || return 41
+ do_node `hostname` umount $MOUNT
+ [ -f "$MOUNTLUSTRE" ] && rm -f $MOUNTLUSTRE
+ echo "mount lustre on ${MOUNT} without $MOUNTLUSTRE....."
+ do_node `hostname` mount -t lustre -o nettype=$NETTYPE \
+ `facet_active_host mds`:/mds_svc/client_facet $MOUNT &&return $?
+ echo "mount lustre on $MOUNT without $MOUNTLUSTRE failed as expected"
+ cleanup || return $?
+ cleanup_15
}
-run_test 15 "zconf-mount without /sbin/mount.lustre, should return error"
+run_test 15 "zconf-mount without /sbin/mount.lustre (should return error)"
equals_msg "Done"
}
run_test 40 "cause recovery in ptlrpc, ensure IO continues"
+#b=2814
+# make sure that a read to one osc doesn't try to double-unlock its page just
+# because another osc is invalid. trigger_group_io used to mistakenly return
+# an error if any oscs were invalid even after having successfully put rpcs
+# on valid oscs. This was fatal if the caller was ll_readpage who unlocked
+# the page, guarnateeing that the unlock from the RPC completion would
+# assert on trying to unlock the unlocked page.
+test_41(){
+ local f=$MOUNT/t42
+ # make sure the start of the file is ost1
+ lfs setstripe $f $((128 * 1024)) 0 0
+ do_facet client dd if=/dev/zero of=$f bs=4k count=1 || return 3
+ cancel_lru_locks OSC
+ # fail ost2 and read from ost1
+ local osc2_dev=`../utils/lctl device_list | \
+ awk '(/ost2.*client_facet/){print $4}' `
+ lctl --device "\$"$osc2_dev deactivate
+ do_facet client dd if=$f of=/dev/null bs=4k count=1 || return 3
+ lctl --device "\$"$osc2_dev activate
+ return 0
+}
+run_test 41 "read from a valid osc while other oscs are invalid"
+
equals_msg test complete, cleaning up
$CLEANUP