-AC_MSG_CHECKING(if you are running user mode linux for $host_alias..)
+AC_MSG_CHECKING(if you are running user mode linux for $host_cpu ...)
if test -e $LINUX/include/asm-um ; then
-if test X`ls -id $LINUX/include/asm | awk '{print $1}'` = X`ls -id $LINUX/include/asm-um | awk '{print $1}'` ; then
+if test X`ls -id $LINUX/include/asm/ | awk '{print $1}'` = X`ls -id $LINUX/include/asm-um | awk '{print $1}'` ; then
host_cpu="um";
AC_MSG_RESULT(yes)
else
- AC_MSG_RESULT(no)
+ AC_MSG_RESULT(no (asm doesn't point at asm-um))
fi
else
- AC_MSG_RESULT(no)
+ AC_MSG_RESULT(no (asm-um missing))
fi
AC_MSG_CHECKING(setting make flags system architecture: )
;;
i*86 )
AC_MSG_RESULT($host_cpu)
- KCFLAGS='-g -O2 -Wall -Wstrict-prototypes -pipe'
+ KCFLAGS='-g -Wall -Wstrict-prototypes -pipe'
KCPPFLAGS='-D__KERNEL__ -DMODULE '
MOD_LINK=elf_i386
;;
#define MDS_REQUEST_PORTAL 12
#define MDS_REPLY_PORTAL 13
#define MDS_BULK_PORTAL 14
-#define LDLM_REQUEST_PORTAL 15
-#define LDLM_REPLY_PORTAL 16
-#define LDLM_CLI_REQUEST_PORTAL 17
-#define LDLM_CLI_REPLY_PORTAL 18
+#define LDLM_CB_REQUEST_PORTAL 15
+#define LDLM_CB_REPLY_PORTAL 16
+#define LDLM_CANCEL_REQUEST_PORTAL 17
+#define LDLM_CANCEL_REPLY_PORTAL 18
+#define LDLM_CLI_REQUEST_PORTAL 19
+#define LDLM_CLI_REPLY_PORTAL 20
#define SVC_KILLED 1
#define SVC_EVENT 2
time_t ll_commitcbd_timeout;
spinlock_t ll_commitcbd_lock;
struct list_head ll_conn_chain; /* per-conn chain of SBs */
+
+ struct list_head ll_orphan_dentry_list; /*please don't ask -p*/
};
static inline struct ll_sb_info *ll_s2sbi(struct super_block *sb)
};
struct ldlm_obd {
- struct ptlrpc_service *ldlm_service;
+ struct ptlrpc_service *ldlm_cb_service;
+ struct ptlrpc_service *ldlm_cancel_service;
struct ptlrpc_client *ldlm_client;
struct ptlrpc_connection *ldlm_server_conn;
};
struct list_head obd_exports;
struct list_head obd_imports;
struct ldlm_namespace *obd_namespace;
- struct ptlrpc_client obd_ldlm_client; /* XXX OST/MDS only */
+ struct ptlrpc_client obd_ldlm_cancel_client; /* XXX OST/MDS only */
+ struct ptlrpc_client obd_ldlm_cb_client; /* XXX OST/MDS only */
/* a spinlock is OK for what we do now, may need a semaphore later */
spinlock_t obd_dev_lock;
union {
+
+
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
rc = ldlm_handle_cp_callback(req);
RETURN(rc);
+ default:
+ CERROR("invalid opcode %d\n", req->rq_reqmsg->opc);
+ RETURN(-EINVAL);
+ }
+
+ RETURN(0);
+}
+
+
+static int ldlm_cancel_handler(struct ptlrpc_request *req)
+{
+ int rc;
+ ENTRY;
+
+ rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen);
+ if (rc) {
+ CERROR("lustre_ldlm: Invalid request: %d\n", rc);
+ RETURN(rc);
+ }
+
+ if (req->rq_export == NULL) {
+ CERROR("lustre_dlm: operation %d with missing/invalid export\n",
+ req->rq_reqmsg->opc);
+ RETURN(-ENOTCONN);
+ }
+
+ switch (req->rq_reqmsg->opc) {
+
/* XXX FIXME move this back to mds/handler.c, bug 625069 */
case LDLM_CANCEL:
CDEBUG(D_INODE, "cancel\n");
return err;
}
-#define LDLM_NUM_THREADS 8
+#define LDLM_NUM_THREADS 4
static int ldlm_setup(struct obd_device *obddev, obd_count len, void *buf)
{
if (rc != 0)
GOTO(out_dec, rc);
*/
- ldlm->ldlm_service =
+ ldlm->ldlm_cb_service =
ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE,
- LDLM_MAXREQSIZE, LDLM_REQUEST_PORTAL,
- LDLM_REPLY_PORTAL, "self",
- ldlm_callback_handler, "ldlm");
- if (!ldlm->ldlm_service)
+ LDLM_MAXREQSIZE, LDLM_CB_REQUEST_PORTAL,
+ LDLM_CB_REPLY_PORTAL, "self",
+ ldlm_callback_handler, "ldlm_cbd");
+
+ if (!ldlm->ldlm_cb_service)
+ GOTO(out_dec, rc = -ENOMEM);
+
+ ldlm->ldlm_cancel_service =
+ ptlrpc_init_svc(LDLM_NEVENTS, LDLM_NBUFS, LDLM_BUFSIZE,
+ LDLM_MAXREQSIZE,
+ LDLM_CANCEL_REQUEST_PORTAL,
+ LDLM_CANCEL_REPLY_PORTAL, "self",
+ ldlm_cancel_handler, "ldlm_canceld");
+
+ if (!ldlm->ldlm_cancel_service)
GOTO(out_dec, rc = -ENOMEM);
for (i = 0; i < LDLM_NUM_THREADS; i++) {
char name[32];
sprintf(name, "lustre_dlm_%02d", i);
- rc = ptlrpc_start_thread(obddev, ldlm->ldlm_service, name);
+ rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cancel_service, name);
+ if (rc) {
+ CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc);
+ LBUG();
+ GOTO(out_thread, rc);
+ }
+ }
+
+ for (i = 0; i < LDLM_NUM_THREADS; i++) {
+ char name[32];
+ sprintf(name, "lustre_dlm_%02d", i);
+ rc = ptlrpc_start_thread(obddev, ldlm->ldlm_cb_service, name);
if (rc) {
CERROR("cannot start LDLM thread #%d: rc %d\n", i, rc);
LBUG();
RETURN(0);
out_thread:
- ptlrpc_stop_all_threads(ldlm->ldlm_service);
- ptlrpc_unregister_service(ldlm->ldlm_service);
+ ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service);
+ ptlrpc_unregister_service(ldlm->ldlm_cancel_service);
+ ptlrpc_stop_all_threads(ldlm->ldlm_cb_service);
+ ptlrpc_unregister_service(ldlm->ldlm_cb_service);
/*
out_proc:
RETURN(-EBUSY);
}
- ptlrpc_stop_all_threads(ldlm->ldlm_service);
- ptlrpc_unregister_service(ldlm->ldlm_service);
+ ptlrpc_stop_all_threads(ldlm->ldlm_cb_service);
+ ptlrpc_unregister_service(ldlm->ldlm_cb_service);
+ ptlrpc_stop_all_threads(ldlm->ldlm_cancel_service);
+ ptlrpc_unregister_service(ldlm->ldlm_cancel_service);
/* ldlm_proc_cleanup(obddev); */
ldlm_already_setup = 0;
GOTO(out, rc = -ENOMEM);
/* XXX FIXME bug 249 */
- req->rq_request_portal = LDLM_REQUEST_PORTAL;
- req->rq_reply_portal = LDLM_REPLY_PORTAL;
+ req->rq_request_portal = LDLM_CANCEL_REQUEST_PORTAL;
+ req->rq_reply_portal = LDLM_CANCEL_REPLY_PORTAL;
body = lustre_msg_buf(req->rq_reqmsg, 0);
memcpy(&body->lock_handle1, &lock->l_remote_handle,
RETURN(-ENOENT);
ptlrpc_init_client(rq_portal, rp_portal, name,
- &obddev->obd_ldlm_client);
- cli->cl_import.imp_client = &obddev->obd_ldlm_client;
+ &obddev->obd_ldlm_cb_client);
+ ptlrpc_init_client(rq_portal, rp_portal, name,
+ &obddev->obd_ldlm_cancel_client);
+ cli->cl_import.imp_client = &obddev->obd_ldlm_cb_client;
cli->cl_import.imp_obd = obddev;
cli->cl_max_mds_easize = sizeof(struct lov_mds_md);
dlmimp = &export->exp_ldlm_data.led_import;
dlmimp->imp_connection = req->rq_connection;
- dlmimp->imp_client = &export->exp_obd->obd_ldlm_client;
+ dlmimp->imp_client = &export->exp_obd->obd_ldlm_cb_client;
dlmimp->imp_handle.addr = req->rq_reqmsg->addr;
dlmimp->imp_handle.cookie = req->rq_reqmsg->cookie;
dlmimp->imp_obd = /* LDLM! */ NULL;
EXIT;
}
+extern void d_delete_aliases(struct inode *);
void ll_intent_release(struct dentry *de, struct lookup_intent *it)
{
struct lustre_handle *handle;
ENTRY;
- if (it == NULL) {
+ if (it == NULL || it->it_op == IT_RENAME2) {
EXIT;
return;
}
handle = (struct lustre_handle *)it->it_lock_handle;
if (it->it_op == IT_SETATTR) {
int rc;
+ struct inode *inode = de->d_inode;
ldlm_lock_decref(handle, it->it_lock_mode);
rc = ldlm_cli_cancel(handle);
if (rc < 0)
CERROR("ldlm_cli_cancel: %d\n", rc);
+ /* XXX should we only do this when the last lock goes? */
+ LASSERT(igrab(inode) == inode);
+ d_delete_aliases(inode);
+ iput(inode);
} else
ldlm_lock_decref(handle, it->it_lock_mode);
}
EXIT;
}
+extern struct dentry *ll_find_alias(struct inode *, struct dentry *);
+
+static int revalidate2_finish(int flag, struct ptlrpc_request *request,
+ struct dentry **de,
+ struct lookup_intent *it,
+ int offset, obd_id ino)
+{
+ ldlm_lock_set_data((struct lustre_handle *)it->it_lock_handle,
+ (*de)->d_inode, sizeof(*((*de)->d_inode)));
+ ptlrpc_req_finished(request);
+ return 0;
+}
+
int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
{
int rc;
RETURN(0);
}
- rc = ll_intent_lock(de->d_parent->d_inode, &de, it, NULL);
+ rc = ll_intent_lock(de->d_parent->d_inode, &de, it, revalidate2_finish);
if (rc < 0) {
/* Something bad happened; overwrite it_status? */
CERROR("ll_intent_lock: %d\n", rc);
}
-
- if (it != NULL && it->it_status == 0) {
+ /* unfortunately ll_intent_lock may cause a callback and revoke our
+ dentry */
+ spin_lock(&dcache_lock);
+ list_del_init(&de->d_hash);
+ spin_unlock(&dcache_lock);
+ d_rehash(de);
+
+ if (it != NULL) {
LL_SAVE_INTENT(de, it);
- } else if (it != NULL) {
+ } else {
de->d_it = NULL;
- CDEBUG(D_DENTRY,
- "D_IT dentry %p fsdata %p intent: %s status %d\n",
- de, ll_d2d(de), ldlm_it2str(it->it_op), it->it_status);
}
RETURN(1);
-#if 0
- struct ll_sb_info *sbi = ll_s2sbi(de->d_sb);
- struct lustre_handle lockh;
- __u64 res_id[RES_NAME_SIZE] = {0};
- struct obd_device *obddev;
- int rc = 0;
- ENTRY;
-
- if (it) {
- CDEBUG(D_INFO, "name: %*s, intent: %s\n", de->d_name.len,
- de->d_name.name, ldlm_it2str(it->it_op));
- if (it->it_op == IT_RENAME)
- it->it_data = de;
- }
-
- if (!de->d_inode)
- GOTO(out, rc = 0);
-
- obddev = class_conn2obd(&sbi->ll_mdc_conn);
- res_id[0] = de->d_inode->i_ino;
-
- CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id[0]);
-
- if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN, NULL, 0,
- LCK_PR, &lockh)) {
- ldlm_lock_decref(&lockh, LCK_PR);
- GOTO(out, rc = 1);
- }
-
- if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN, NULL, 0,
- LCK_PW, &lockh)) {
- ldlm_lock_decref(&lockh, LCK_PW);
- GOTO(out, rc = 1);
- }
-
- /* If the dentry is busy, we won't get called in lookup2 if we
- * return 0, so return 1.
- *
- * This is a temporary fix for bug 224, but is one of the causes of
- * 225. */
- CDEBUG(D_INFO, "d_count: %d\n", atomic_read(&de->d_count));
- if (it && atomic_read(&de->d_count) > 1) {
- CDEBUG(D_INFO, "returning 1 for %*s during %s because d_count "
- "is %d\n", de->d_name.len, de->d_name.name,
- ldlm_it2str(it->it_op), atomic_read(&de->d_count));
- GOTO(out, rc = 1);
- }
-
- out:
- if (ll_d2d(de) == NULL) {
- CERROR("allocating fsdata\n");
- ll_set_dd(de);
- }
- //down(&ll_d2d(de)->lld_it_sem);
- de->d_it = it;
-
- RETURN(rc);
-#endif
}
int ll_set_dd(struct dentry *de)
} else if (it->it_op & (IT_READDIR | IT_GETATTR | IT_OPEN | IT_UNLINK |
IT_RMDIR | IT_RENAME | IT_RENAME2 | IT_READLINK|
IT_LINK | IT_LINK2 | IT_LOOKUP | IT_SYMLINK)) {
- return LCK_PW;
+ return LCK_PR;
}
LBUG();
/* Search "inode"'s alias list for a dentry that has the same name and parent as
* de. If found, return it. If not found, return de. */
-static struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
+struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
{
struct list_head *tmp;
if (dentry == de)
continue;
+ if (!atomic_read(&dentry->d_count))
+ continue;
+
+ if (!list_empty(&dentry->d_lru))
+ continue;
+
if (dentry->d_parent != de->d_parent)
continue;
de->d_name.len) != 0)
continue;
+ list_del_init(&dentry->d_hash);
+
spin_unlock(&dcache_lock);
d_rehash(dentry);
- return dget(dentry);
+ atomic_inc(&dentry->d_count);
+ iput(inode);
+ return dentry;
}
+
spin_unlock(&dcache_lock);
+
return de;
}
if (dentry == saved)
d_add(dentry, inode);
- if (it->it_status == 0) {
+ if (it->it_status == 0 && it->it_op != IT_RENAME2) {
LL_SAVE_INTENT(dentry, it);
} else {
dentry->d_it = NULL;
struct page * old_page;
int err;
- LL_GET_INTENT(new_dentry, it);
+ LL_GET_INTENT(old_dentry, it);
if (it && it->it_disposition) {
if (tgt_inode) {
}
INIT_LIST_HEAD(&sbi->ll_conn_chain);
+ INIT_LIST_HEAD(&sbi->ll_orphan_dentry_list);
generate_random_uuid(uuid);
class_uuid_unparse(uuid, sbi->ll_sb_uuid);
GOTO(out_free, sb = NULL);
}
-#warning Peter: is this the right place to raise the connection level?
+#warning Mike: is this the right place to raise the connection level?
mdc_conn = sbi2mdc(sbi)->cl_import.imp_connection;
mdc_conn->c_level = LUSTRE_CONN_FULL;
list_add(&mdc_conn->c_sb_chain, &sbi->ll_conn_chain);
static void ll_put_super(struct super_block *sb)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct list_head *tmp, *next;
struct ll_fid rootfid;
ENTRY;
lprocfs_dereg_mnt(sbi->ll_mnt_root);
obd_disconnect(&sbi->ll_mdc_conn);
+
+ spin_lock(&dcache_lock);
+ list_for_each_safe(tmp, next, &sbi->ll_orphan_dentry_list) {
+ struct dentry *dentry = list_entry(tmp, struct dentry, d_hash);
+ shrink_dcache_parent(dentry);
+ }
+ spin_unlock(&dcache_lock);
+
OBD_FREE(sbi, sizeof(*sbi));
MOD_DEC_USE_COUNT;
+
+
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
return rc;
}
-static void d_delete_aliases(struct inode *inode)
+void d_delete_aliases(struct inode *inode)
{
struct dentry *dentry = NULL;
struct list_head *tmp;
- int dentry_count = 0;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
ENTRY;
spin_lock(&dcache_lock);
list_for_each(tmp, &inode->i_dentry) {
dentry = list_entry(tmp, struct dentry, d_alias);
- dentry_count++;
- }
- /* XXX FIXME tell phil/peter that you see this -- unless you're playing
- * with hard links, in which case, stop. */
- LASSERT(dentry_count <= 1);
+ // if (atomic_read(&dentry->d_count))
+ // continue;
+ //if (!list_empty(&dentry->d_lru))
+ // continue;
- if (dentry_count == 0) {
- spin_unlock(&dcache_lock);
- EXIT;
- return;
+ list_del_init(&dentry->d_hash);
+ list_add(&dentry->d_hash, &sbi->ll_orphan_dentry_list);
}
- CDEBUG(D_INODE, "d_deleting dentry %p\n", dentry);
- dget_locked(dentry);
spin_unlock(&dcache_lock);
- d_delete(dentry);
- dput(dentry);
EXIT;
}
if (S_ISDIR(inode->i_mode)) {
CDEBUG(D_INODE, "invalidating inode %ld\n",
inode->i_ino);
+
ll_invalidate_inode_pages(inode);
}
/* pack the intended request */
mds_getattr_pack(req, 2, dir, de->d_name.name, de->d_name.len);
- /* we need to replay opens */
- if (it->it_op == IT_OPEN)
- req->rq_flags |= PTL_RPC_FL_REPLAY;
-
/* get ready for the reply */
req->rq_replen = lustre_msg_size(3, repsize);
} else if (it->it_op == IT_READDIR) {
MODULE_DESCRIPTION("Lustre Metadata Client v1.0");
MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(d_delete_aliases);
EXPORT_SYMBOL(mdc_getstatus);
EXPORT_SYMBOL(mdc_getlovinfo);
EXPORT_SYMBOL(mdc_enqueue);
dir = de->d_inode;
CDEBUG(D_INODE, "parent ino %ld, name %*s\n", dir->i_ino,namelen,name);
- lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_CW : LCK_PW;
+ lock_mode = LCK_PR;
res_id[0] = dir->i_ino;
res_id[1] = dir->i_generation;
if (rc)
GOTO(err_fs, rc);
- ptlrpc_init_client(LDLM_REQUEST_PORTAL, LDLM_REPLY_PORTAL,
- "mds_ldlm_client", &obddev->obd_ldlm_client);
+ ptlrpc_init_client(LDLM_CANCEL_REQUEST_PORTAL,
+ LDLM_CANCEL_REPLY_PORTAL,
+ "mds_ldlm_client", &obddev->obd_ldlm_cancel_client);
+
+ ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL,
+ LDLM_CB_REPLY_PORTAL,
+ "mds_ldlm_client", &obddev->obd_ldlm_cb_client);
RETURN(0);
handle = mds_fs_start(mds, dir, MDS_FSOP_SYMLINK);
if (!handle)
GOTO(out_create_dchild, PTR_ERR(handle));
- rc = vfs_symlink(dir, dchild, rec->ur_tgt);
+ rc = vfs_symlink(dir, dchild, rec->ur_name);
EXIT;
break;
}
* and Andreas Dilger <adilger@clusterfs.com>
*/
-static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.42 2002/11/01 17:23:13 thantry Exp $";
-#define OBDECHO_VERSION "$Revision: 1.42 $"
+static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.43 2002/11/02 01:09:28 braam Exp $";
+#define OBDECHO_VERSION "$Revision: 1.43 $"
#define EXPORT_SYMTAB
if (obd->obd_namespace == NULL)
LBUG();
- ptlrpc_init_client(LDLM_REQUEST_PORTAL, LDLM_REPLY_PORTAL,
- "filter_ldlm_client", &obd->obd_ldlm_client);
+ ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
+ "filter_ldlm_cb_client", &obd->obd_ldlm_cb_client);
+ ptlrpc_init_client(LDLM_CANCEL_REQUEST_PORTAL, LDLM_CANCEL_REPLY_PORTAL,
+ "filter_ldlm_cancel_client", &obd->obd_ldlm_cancel_client);
RETURN(0);