X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmds%2Fhandler.c;h=6bd5e0c6981853169b337489ef44e0c0079d245a;hp=5096bd195eb7f7ff7a5ab716c7ec66ee9f1a2250;hb=400b0681017091fab9cef9bd00e0f536e1793dcc;hpb=f26c03bf3aefccbd909e0acb9c9684007d5edc3a diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 5096bd1..6bd5e0c 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -34,9 +34,11 @@ #include #include #include +#include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) #include #endif +#include static kmem_cache_t *mds_file_cache; @@ -47,6 +49,9 @@ extern int mds_update_last_rcvd(struct mds_obd *mds, void *handle, struct ptlrpc_request *req); static int mds_cleanup(struct obd_device * obddev); +extern lprocfs_vars_t status_var_nm_1[]; +extern lprocfs_vars_t status_class_var[]; + inline struct mds_obd *mds_req2mds(struct ptlrpc_request *req) { return &req->rq_export->exp_obd->u.mds; @@ -160,6 +165,7 @@ struct dentry *mds_name2locked_dentry(struct obd_device *obd, RETURN(dchild); res_id[0] = dchild->d_inode->i_ino; + res_id[1] = dchild->d_inode->i_generation; rc = ldlm_match_or_enqueue(NULL, NULL, obd->obd_namespace, NULL, res_id, LDLM_PLAIN, NULL, 0, lock_mode, &flags, ldlm_completion_ast, @@ -187,6 +193,7 @@ struct dentry *mds_fid2locked_dentry(struct obd_device *obd, struct ll_fid *fid, RETURN(de); res_id[0] = de->d_inode->i_ino; + res_id[1] = de->d_inode->i_generation; rc = ldlm_match_or_enqueue(NULL, NULL, obd->obd_namespace, NULL, res_id, LDLM_PLAIN, NULL, 0, lock_mode, &flags, ldlm_completion_ast, @@ -385,7 +392,7 @@ static int mds_disconnect(struct lustre_handle *conn) } } spin_unlock(&med->med_open_lock); - + ldlm_cancel_locks_for_export(export); mds_client_free(export); @@ -396,6 +403,23 @@ static int mds_disconnect(struct lustre_handle *conn) RETURN(rc); } +/* + * XXX This is NOT guaranteed to flush all transactions to disk (even though + * it is equivalent to calling sync()) because it only _starts_ the flush + * and does not wait for completion. It's better than nothing though. + * What we really want is a mild form of fsync_dev_lockfs(), but it is + * non-standard, or enabling do_sync_supers in ext3, just for this call. + */ +static void mds_fsync_super(struct super_block *sb) +{ + lock_kernel(); + lock_super(sb); + if (sb->s_dirt && sb->s_op && sb->s_op->write_super) + sb->s_op->write_super(sb); + unlock_super(sb); + unlock_kernel(); +} + static int mds_getstatus(struct ptlrpc_request *req) { struct mds_obd *mds = mds_req2mds(req); @@ -410,7 +434,13 @@ static int mds_getstatus(struct ptlrpc_request *req) RETURN(0); } - /* Anything we need to do here with the client's trans no or so? */ + /* Flush any outstanding transactions to disk so the client will + * get the latest last_committed value and can drop their local + * requests if they have any. This would be fsync_super() if it + * was exported. + */ + mds_fsync_super(mds->mds_sb); + body = lustre_msg_buf(req->rq_repmsg, 0); memcpy(&body->fid1, &mds->mds_rootfid, sizeof(body->fid1)); @@ -590,6 +620,7 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req) lock_mode = (req->rq_reqmsg->opc == MDS_REINT) ? LCK_CW : LCK_PW; res_id[0] = dir->i_ino; + res_id[1] = dir->i_generation; rc = ldlm_lock_match(obd->obd_namespace, res_id, LDLM_PLAIN, NULL, 0, lock_mode, &lockh); @@ -1421,6 +1452,21 @@ static int ldlm_intent_policy(struct ldlm_lock *lock, void *req_cookie, RETURN(rc); } +int mds_attach(struct obd_device *dev, + obd_count len, void *data) +{ + int rc; + rc = lprocfs_reg_obd(dev, (lprocfs_vars_t*)status_var_nm_1, (void*)dev); + return rc; +} + +int mds_detach(struct obd_device *dev) +{ + int rc; + rc = lprocfs_dereg_obd(dev); + return rc; + +} #define MDT_NUM_THREADS 8 static int mdt_setup(struct obd_device *obddev, obd_count len, void *buf) @@ -1480,6 +1526,8 @@ extern int mds_iocontrol(long cmd, struct lustre_handle *conn, /* use obd ops to offer management infrastructure */ static struct obd_ops mds_obd_ops = { + o_attach: mds_attach, + o_detach: mds_detach, o_connect: mds_connect, o_disconnect: mds_disconnect, o_setup: mds_setup, @@ -1495,25 +1543,33 @@ static struct obd_ops mdt_obd_ops = { static int __init mds_init(void) { + mds_file_cache = kmem_cache_create("ll_mds_file_data", sizeof(struct mds_file_data), 0, 0, NULL, NULL); if (mds_file_cache == NULL) return -ENOMEM; - class_register_type(&mds_obd_ops, LUSTRE_MDS_NAME); - class_register_type(&mdt_obd_ops, LUSTRE_MDT_NAME); + class_register_type(&mds_obd_ops, (lprocfs_vars_t*)status_class_var, + LUSTRE_MDS_NAME); + class_register_type(&mdt_obd_ops, 0, LUSTRE_MDT_NAME); + ldlm_register_intent(ldlm_intent_policy); + return 0; + } static void __exit mds_exit(void) { + + ldlm_unregister_intent(); class_unregister_type(LUSTRE_MDS_NAME); class_unregister_type(LUSTRE_MDT_NAME); if (kmem_cache_destroy(mds_file_cache)) CERROR("couldn't free MDS file cache\n"); + } MODULE_AUTHOR("Cluster File Systems ");