Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
Branch HEAD
[fs/lustre-release.git]
/
lustre
/
obdclass
/
genops.c
diff --git
a/lustre/obdclass/genops.c
b/lustre/obdclass/genops.c
index
7341aaa
..
a74ee18
100644
(file)
--- a/
lustre/obdclass/genops.c
+++ b/
lustre/obdclass/genops.c
@@
-73,7
+73,7
@@
static struct obd_device *obd_device_alloc(void)
{
struct obd_device *obd;
- OBD_SLAB_ALLOC_PTR
(obd, obd_device_cachep
);
+ OBD_SLAB_ALLOC_PTR
_GFP(obd, obd_device_cachep, CFS_ALLOC_IO
);
if (obd != NULL) {
obd->obd_magic = OBD_DEVICE_MAGIC;
}
@@
-723,6
+723,7
@@
static void class_export_destroy(struct obd_export *exp)
ptlrpc_put_connection_superhack(exp->exp_connection);
LASSERT(list_empty(&exp->exp_outstanding_replies));
+ LASSERT(list_empty(&exp->exp_uncommitted_replies));
LASSERT(list_empty(&exp->exp_req_replay_queue));
LASSERT(list_empty(&exp->exp_queued_rpc));
obd_destroy_export(exp);
@@
-781,6
+782,8
@@
struct obd_export *class_new_export(struct obd_device *obd,
atomic_set(&export->exp_rpc_count, 0);
export->exp_obd = obd;
CFS_INIT_LIST_HEAD(&export->exp_outstanding_replies);
+ spin_lock_init(&export->exp_uncommitted_replies_lock);
+ CFS_INIT_LIST_HEAD(&export->exp_uncommitted_replies);
CFS_INIT_LIST_HEAD(&export->exp_req_replay_queue);
CFS_INIT_LIST_HEAD(&export->exp_handle.h_link);
CFS_INIT_LIST_HEAD(&export->exp_queued_rpc);
@@
-837,6
+840,15
@@
void class_unlink_export(struct obd_export *exp)
exp->exp_obd->obd_num_exports--;
spin_unlock(&exp->exp_obd->obd_dev_lock);
+ /* Keep these counter valid always */
+ spin_lock_bh(&exp->exp_obd->obd_processing_task_lock);
+ if (exp->exp_delayed)
+ exp->exp_obd->obd_delayed_clients--;
+ else if (exp->exp_in_recovery)
+ exp->exp_obd->obd_recoverable_clients--;
+ else if (exp->exp_obd->obd_recovering)
+ exp->exp_obd->obd_max_recoverable_clients--;
+ spin_unlock_bh(&exp->exp_obd->obd_processing_task_lock);
class_export_put(exp);
}
EXPORT_SYMBOL(class_unlink_export);
@@
-1027,10
+1039,12
@@
void class_export_recovery_cleanup(struct obd_export *exp)
spin_unlock_bh(&obd->obd_processing_task_lock);
}
-/* This function removes two references from the export: one for the
- * hash entry and one for the export pointer passed in. The export
- * pointer passed to this function is destroyed should not be used
- * again. */
+/* This function removes 1-3 references from the export:
+ * 1 - for export pointer passed
+ * and if disconnect really need
+ * 2 - removing from hash
+ * 3 - in client_unlink_export
+ * The export pointer passed to this function can destroyed */
int class_disconnect(struct obd_export *export)
{
int already_disconnected;
@@
-1045,25
+1059,27
@@
int class_disconnect(struct obd_export *export)
spin_lock(&export->exp_lock);
already_disconnected = export->exp_disconnected;
export->exp_disconnected = 1;
-
- if (!hlist_unhashed(&export->exp_nid_hash))
- lustre_hash_del(export->exp_obd->obd_nid_hash,
- &export->exp_connection->c_peer.nid,
- &export->exp_nid_hash);
-
spin_unlock(&export->exp_lock);
/* class_cleanup(), abort_recovery(), and class_fail_export()
* all end up in here, and if any of them race we shouldn't
* call extra class_export_puts(). */
- if (already_disconnected)
- RETURN(0);
+ if (already_disconnected) {
+ LASSERT(hlist_unhashed(&export->exp_nid_hash));
+ GOTO(no_disconn, already_disconnected);
+ }
CDEBUG(D_IOCTL, "disconnect: cookie "LPX64"\n",
export->exp_handle.h_cookie);
+ if (!hlist_unhashed(&export->exp_nid_hash))
+ lustre_hash_del(export->exp_obd->obd_nid_hash,
+ &export->exp_connection->c_peer.nid,
+ &export->exp_nid_hash);
+
class_export_recovery_cleanup(export);
class_unlink_export(export);
+no_disconn:
class_export_put(export);
RETURN(0);
}
@@
-1072,14
+1088,14
@@
static void class_disconnect_export_list(struct list_head *list,
enum obd_option flags)
{
int rc;
- struct lustre_handle fake_conn;
- struct obd_export *fake_exp, *exp;
+ struct obd_export *exp;
ENTRY;
/* It's possible that an export may disconnect itself, but
* nothing else will be added to this list. */
while (!list_empty(list)) {
exp = list_entry(list->next, struct obd_export, exp_obd_chain);
+ /* need for safe call CDEBUG after obd_disconnect */
class_export_get(exp);
spin_lock(&exp->exp_lock);
@@
-1098,22
+1114,16
@@
static void class_disconnect_export_list(struct list_head *list,
continue;
}
- fake_conn.cookie = exp->exp_handle.h_cookie;
- fake_exp = class_conn2export(&fake_conn);
- if (!fake_exp) {
- class_export_put(exp);
- continue;
- }
-
- spin_lock(&fake_exp->exp_lock);
- fake_exp->exp_flags = flags;
- spin_unlock(&fake_exp->exp_lock);
-
+ class_export_get(exp);
CDEBUG(D_HA, "%s: disconnecting export at %s (%p), "
"last request at "CFS_TIME_T"\n",
exp->exp_obd->obd_name, obd_export_nid2str(exp),
exp, exp->exp_last_request_time);
- rc = obd_disconnect(fake_exp);
+ /* release one export reference anyway */
+ rc = obd_disconnect(exp);
+
+ CDEBUG(D_HA, "disconnected export at %s (%p): rc %d\n",
+ obd_export_nid2str(exp), exp, rc);
class_export_put(exp);
}
EXIT;
@@
-1125,9
+1135,10
@@
void class_disconnect_exports(struct obd_device *obd)
ENTRY;
/* Move all of the exports from obd_exports to a work list, en masse. */
+ CFS_INIT_LIST_HEAD(&work_list);
spin_lock(&obd->obd_dev_lock);
- list_
add(&work_list, &obd->obd_exports
);
- list_
del_init(&obd->obd_exports
);
+ list_
splice_init(&obd->obd_exports, &work_list
);
+ list_
splice_init(&obd->obd_delayed_exports, &work_list
);
spin_unlock(&obd->obd_dev_lock);
if (!list_empty(&work_list)) {
@@
-1144,31
+1155,30
@@
EXPORT_SYMBOL(class_disconnect_exports);
/* Remove exports that have not completed recovery.
*/
-
int
class_disconnect_stale_exports(struct obd_device *obd,
- int (*test_export)(struct obd_export *),
- enum obd_option flags)
+
void
class_disconnect_stale_exports(struct obd_device *obd,
+
int (*test_export)(struct obd_export *),
+
enum obd_option flags)
{
struct list_head work_list;
struct list_head *pos, *n;
struct obd_export *exp;
- int cnt = 0;
ENTRY;
CFS_INIT_LIST_HEAD(&work_list);
spin_lock(&obd->obd_dev_lock);
+ obd->obd_stale_clients = 0;
list_for_each_safe(pos, n, &obd->obd_exports) {
exp = list_entry(pos, struct obd_export, exp_obd_chain);
if (test_export(exp))
continue;
- list_del(&exp->exp_obd_chain);
- list_add(&exp->exp_obd_chain, &work_list);
+ list_move(&exp->exp_obd_chain, &work_list);
/* don't count self-export as client */
if (obd_uuid_equals(&exp->exp_client_uuid,
&exp->exp_obd->obd_uuid))
continue;
-
cnt
++;
+
obd->obd_stale_clients
++;
CDEBUG(D_ERROR, "%s: disconnect stale client %s@%s\n",
obd->obd_name, exp->exp_client_uuid.uuid,
exp->exp_connection == NULL ? "<unknown>" :
@@
-1176,10
+1186,11
@@
int class_disconnect_stale_exports(struct obd_device *obd,
}
spin_unlock(&obd->obd_dev_lock);
- CDEBUG(D_ERROR, "%s: disconnecting %d stale clients\n",
- obd->obd_name, cnt);
+ CDEBUG(D_HA, "%s: disconnecting %d stale clients\n", obd->obd_name,
+ obd->obd_stale_clients);
+
class_disconnect_export_list(&work_list, flags);
-
RETURN(cnt)
;
+
EXIT
;
}
EXPORT_SYMBOL(class_disconnect_stale_exports);
@@
-1371,6
+1382,7
@@
static void obd_zombie_export_add(struct obd_export *exp) {
* Add import to the obd_zombe thread and notify it.
*/
static void obd_zombie_import_add(struct obd_import *imp) {
+ LASSERT(imp->imp_sec == NULL);
spin_lock(&obd_zombie_impexp_lock);
LASSERT(list_empty(&imp->imp_zombie_chain));
list_add(&imp->imp_zombie_chain, &obd_zombie_imports);