From: adilger Date: Sun, 23 Jun 2002 02:47:20 +0000 (+0000) Subject: Move cleanup of service struct into ptlrpc_unregister_service(). X-Git-Tag: v1_7_100~5462 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=d4dc99591c3587209f93e8f58f640d2c5a8d1a26;p=fs%2Flustre-release.git Move cleanup of service struct into ptlrpc_unregister_service(). Includes MDS statfs method. Includes fixes for sgid directories on MDS. --- diff --git a/lustre/include/linux/lustre_net.h b/lustre/include/linux/lustre_net.h index 30224e2..02f5e17 100644 --- a/lustre/include/linux/lustre_net.h +++ b/lustre/include/linux/lustre_net.h @@ -305,7 +305,7 @@ ptlrpc_init_svc(__u32 bufsize, int req_portal, int rep_portal, char *uuid, void ptlrpc_stop_all_threads(struct ptlrpc_service *svc); int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc, char *name); -int rpc_unregister_service(struct ptlrpc_service *service); +int ptlrpc_unregister_service(struct ptlrpc_service *service); struct ptlrpc_svc_data { char *name; diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index d313fcc..4d60432 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -398,8 +398,7 @@ static int ldlm_setup(struct obd_device *obddev, obd_count len, void *buf) out_thread: ptlrpc_stop_all_threads(ldlm->ldlm_service); - rpc_unregister_service(ldlm->ldlm_service); - OBD_FREE(ldlm->ldlm_service, sizeof(*ldlm->ldlm_service)); + ptlrpc_unregister_service(ldlm->ldlm_service); out_dec: MOD_DEC_USE_COUNT; return rc; @@ -411,14 +410,7 @@ static int ldlm_cleanup(struct obd_device *obddev) ENTRY; ptlrpc_stop_all_threads(ldlm->ldlm_service); - rpc_unregister_service(ldlm->ldlm_service); - - if (!list_empty(&ldlm->ldlm_service->srv_reqs)) { - // XXX reply with errors and clean up - CERROR("Request list not empty!\n"); - } - - OBD_FREE(ldlm->ldlm_service, sizeof(*ldlm->ldlm_service)); + ptlrpc_unregister_service(ldlm->ldlm_service); if (mds_reint_p != NULL) inter_module_put("mds_reint"); diff --git a/lustre/mds/Makefile.am b/lustre/mds/Makefile.am index 887039c..1f66d82 100644 --- a/lustre/mds/Makefile.am +++ b/lustre/mds/Makefile.am @@ -9,7 +9,10 @@ MODULE = mds modulefs_DATA = mds.o mds_extN.o # mds_ext2.o mds_ext3.o EXTRA_PROGRAMS = mds mds_extN # mds_ext2 mds_ext3 -LINX=mds_updates.c simple.c +LINX=mds_updates.c simple.c ll_pack.c +ll_pack.c: + test -e ll_pack.c || ln -sf $(top_srcdir)/lib/ll_pack.c + mds_updates.c: test -e mds_updates.c || ln -sf $(top_srcdir)/lib/mds_updates.c diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index a28954d..abb73a3 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -27,11 +27,12 @@ extern int mds_update_last_rcvd(struct mds_obd *mds, void *handle, struct ptlrpc_request *req); static int mds_cleanup(struct obd_device * obddev); +/* Assumes caller has already pushed into the kernel filesystem context */ static int mds_sendpage(struct ptlrpc_request *req, struct file *file, __u64 offset) { int rc = 0; - mm_segment_t oldfs = get_fs(); + struct mds_obd *mds = &req->rq_obd->u.mds; struct ptlrpc_bulk_desc *desc; struct ptlrpc_bulk_page *bulk; char *buf; @@ -49,10 +50,7 @@ static int mds_sendpage(struct ptlrpc_request *req, struct file *file, if (buf == NULL) GOTO(cleanup_bulk, rc = -ENOMEM); - set_fs(KERNEL_DS); - rc = mds_fs_readpage(&req->rq_obd->u.mds, file, buf, PAGE_SIZE, - (loff_t *)&offset); - set_fs(oldfs); + rc = mds_fs_readpage(mds, file, buf, PAGE_SIZE, (loff_t *)&offset); if (rc != PAGE_SIZE) GOTO(cleanup_buf, rc = -EIO); @@ -277,6 +275,7 @@ int mds_lock_callback(struct ldlm_lock *lock, struct ldlm_lock *new, static int mds_getattr_name(int offset, struct ptlrpc_request *req) { struct mds_obd *mds = &req->rq_obd->u.mds; + struct obd_run_ctxt saved; struct mds_body *body; struct dentry *de = NULL, *dchild = NULL; struct inode *dir; @@ -302,6 +301,7 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req) if (offset) offset = 1; + push_ctxt(&saved, &mds->mds_ctxt); de = mds_fid2dentry(mds, &body->fid1, NULL); if (IS_ERR(de)) { LBUG(); @@ -370,8 +370,9 @@ out_create_dchild: ldlm_lock_decref(lock, lock_mode); out_create_de: l_dput(de); - out_pre_de: +out_pre_de: req->rq_status = rc; + pop_ctxt(&saved); return 0; } @@ -379,6 +380,7 @@ out_create_de: static int mds_getattr(int offset, struct ptlrpc_request *req) { struct mds_obd *mds = &req->rq_obd->u.mds; + struct obd_run_ctxt saved; struct dentry *de; struct inode *inode; struct mds_body *body; @@ -386,10 +388,10 @@ static int mds_getattr(int offset, struct ptlrpc_request *req) ENTRY; body = lustre_msg_buf(req->rq_reqmsg, offset); + push_ctxt(&saved, &mds->mds_ctxt); de = mds_fid2dentry(mds, &body->fid1, NULL); if (IS_ERR(de)) { - req->rq_status = -ENOENT; - RETURN(-ENOENT); + GOTO(out_pop, rc = -ENOENT); } inode = de->d_inode; @@ -405,21 +407,15 @@ static int mds_getattr(int offset, struct ptlrpc_request *req) &req->rq_repmsg); if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) { CERROR("mds: out of memory\n"); - req->rq_status = -ENOMEM; - GOTO(out, rc = -ENOMEM); + GOTO(out, rc); } if (body->valid & OBD_MD_LINKNAME) { char *tmp = lustre_msg_buf(req->rq_repmsg, 1); - mm_segment_t oldfs; - oldfs = get_fs(); - set_fs(KERNEL_DS); rc = inode->i_op->readlink(de, tmp, size[1]); - set_fs(oldfs); if (rc < 0) { - req->rq_status = rc; CERROR("readlink failed: %d\n", rc); GOTO(out, rc); } @@ -442,14 +438,49 @@ static int mds_getattr(int offset, struct ptlrpc_request *req) rc = mds_fs_get_obdo(mds, inode, lustre_msg_buf(req->rq_repmsg, 1)); if (rc < 0) { - req->rq_status = rc; CERROR("mds_fs_get_obdo failed: %d\n", rc); GOTO(out, rc); } } - out: +out: l_dput(de); - RETURN(rc); +out_pop: + pop_ctxt(&saved); + req->rq_status = rc; + RETURN(0); +} + +static int mds_statfs(struct ptlrpc_request *req) +{ + struct mds_obd *mds = &req->rq_obd->u.mds; + struct obd_statfs *osfs; + struct statfs sfs; + int rc, size = sizeof(*osfs); + ENTRY; + + rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, + &req->rq_repmsg); + if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_STATFS_PACK)) { + CERROR("mds: statfs lustre_pack_msg failed: rc = %d\n", rc); + GOTO(out, rc); + } + + rc = vfs_statfs(mds->mds_sb, &sfs); + if (rc) { + CERROR("mds: statfs failed: rc %d\n", rc); + GOTO(out, rc); + } + osfs = lustre_msg_buf(req->rq_repmsg, 0); + memset(osfs, 0, size); + /* FIXME: hack until the MDS gets the OST data, next month */ + sfs.f_blocks = -1; + sfs.f_bfree = -1; + sfs.f_bavail = -1; + obd_statfs_pack(osfs, &sfs); + +out: + req->rq_status = rc; + RETURN(0); } static int mds_open(struct ptlrpc_request *req) @@ -483,6 +514,7 @@ static int mds_open(struct ptlrpc_request *req) body = lustre_msg_buf(req->rq_reqmsg, 0); /* was this animal open already? */ + /* XXX we chould only check on re-open, or do a refcount... */ list_for_each(tmp, &mci->mci_open_head) { struct mds_file_data *fd; fd = list_entry(tmp, struct mds_file_data, mfd_list); @@ -607,31 +639,28 @@ static int mds_readpage(struct mds_obd *mds, struct ptlrpc_request *req) struct dentry *de; struct file *file; struct mds_body *body; + struct obd_run_ctxt saved; int rc, size = sizeof(*body); ENTRY; rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg); if (rc || OBD_FAIL_CHECK(OBD_FAIL_MDS_READPAGE_PACK)) { CERROR("mds: out of memory\n"); - req->rq_status = -ENOMEM; - RETURN(0); + GOTO(out, rc = -ENOMEM); } body = lustre_msg_buf(req->rq_reqmsg, 0); + push_ctxt(&saved, &mds->mds_ctxt); de = mds_fid2dentry(mds, &body->fid1, &mnt); - if (IS_ERR(de)) { - req->rq_status = PTR_ERR(de); - RETURN(0); - } + if (IS_ERR(de)) + GOTO(out_pop, rc = PTR_ERR(de)); CDEBUG(D_INODE, "ino %ld\n", de->d_inode->i_ino); file = dentry_open(de, mnt, O_RDONLY | O_LARGEFILE); /* note: in case of an error, dentry_open puts dentry */ - if (IS_ERR(file)) { - req->rq_status = PTR_ERR(file); - RETURN(0); - } + if (IS_ERR(file)) + GOTO(out_pop, rc = PTR_ERR(file)); /* to make this asynchronous make sure that the handling function doesn't send a reply when this function completes. Instead a @@ -639,6 +668,9 @@ static int mds_readpage(struct mds_obd *mds, struct ptlrpc_request *req) rc = mds_sendpage(req, file, body->size); filp_close(file, 0); +out_pop: + pop_ctxt(&saved); +out: req->rq_status = rc; RETURN(0); } @@ -715,6 +747,12 @@ int mds_handle(struct obd_device *dev, struct ptlrpc_service *svc, rc = mds_getattr(0, req); break; + case MDS_STATFS: + CDEBUG(D_INODE, "statfs\n"); + OBD_FAIL_RETURN(OBD_FAIL_MDS_STATFS_NET, 0); + rc = mds_statfs(req); + break; + case MDS_READPAGE: CDEBUG(D_INODE, "readpage\n"); OBD_FAIL_RETURN(OBD_FAIL_MDS_READPAGE_NET, 0); @@ -865,8 +903,8 @@ static int mds_setup(struct obd_device *obddev, obd_count len, void *buf) GOTO(err_put, rc); } - mds->mds_service = ptlrpc_init_svc(64 * 1024, - MDS_REQUEST_PORTAL, MDC_REPLY_PORTAL, "self", mds_handle); + mds->mds_service = ptlrpc_init_svc(64 * 1024, MDS_REQUEST_PORTAL, + MDC_REPLY_PORTAL, "self",mds_handle); if (!mds->mds_service) { CERROR("failed to start service\n"); GOTO(err_fs, rc = -EINVAL); @@ -921,8 +959,7 @@ static int mds_setup(struct obd_device *obddev, obd_count len, void *buf) err_thread: ptlrpc_stop_all_threads(mds->mds_service); err_svc: - rpc_unregister_service(mds->mds_service); - OBD_FREE(mds->mds_service, sizeof(*mds->mds_service)); + ptlrpc_unregister_service(mds->mds_service); err_fs: mds_fs_cleanup(mds); err_put: @@ -950,12 +987,7 @@ static int mds_cleanup(struct obd_device * obddev) } ptlrpc_stop_all_threads(mds->mds_service); - rpc_unregister_service(mds->mds_service); - if (!list_empty(&mds->mds_service->srv_reqs)) { - // XXX reply with errors and clean up - CERROR("Request list not empty!\n"); - } - OBD_FREE(mds->mds_service, sizeof(*mds->mds_service)); + ptlrpc_unregister_service(mds->mds_service); sb = mds->mds_sb; if (!mds->mds_sb) diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index 8efca61..b5f9d3a 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -417,6 +417,8 @@ int mds_fs_setup(struct mds_obd *mds, struct vfsmount *mnt) mds->mds_fsops = fs_ops; mds->mds_vfsmnt = mnt; + + OBD_SET_CTXT_MAGIC(&mds->mds_ctxt); mds->mds_ctxt.pwdmnt = mnt; mds->mds_ctxt.pwd = mnt->mnt_root; mds->mds_ctxt.fs = KERNEL_DS; diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 3480ffb..95655a9 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -48,11 +48,11 @@ struct mds_client_info *mds_uuid_to_mci(struct mds_obd *mds, __u8 *uuid) return NULL; } +/* Assumes caller has already pushed us into the kernel context. */ int mds_update_last_rcvd(struct mds_obd *mds, void *handle, struct ptlrpc_request *req) { /* get from req->rq_connection-> or req->rq_client */ - struct obd_run_ctxt saved; struct mds_client_info *mci; loff_t off; int rc; @@ -75,10 +75,8 @@ int mds_update_last_rcvd(struct mds_obd *mds, void *handle, mci->mci_mcd->mcd_last_xid = cpu_to_le64(req->rq_xid); mds_fs_set_last_rcvd(mds, handle); - push_ctxt(&saved, &mds->mds_ctxt); rc = lustre_fwrite(mds->mds_rcvd_filp, (char *)mci->mci_mcd, sizeof(*mci->mci_mcd), &off); - pop_ctxt(&saved); CDEBUG(D_INODE, "wrote trans #%Ld for client '%s' at #%d: rc = %d\n", mds->mds_last_rcvd, mci->mci_mcd->mcd_uuid, mci->mci_off, rc); // store new value and last committed value in req struct @@ -267,6 +265,12 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, OBD_FAIL_WRITE(OBD_FAIL_MDS_REINT_CREATE_WRITE, dir->i_sb->s_dev); + if (dir->i_mode & S_ISGID) { + rec->ur_gid = dir->i_gid; + if (S_ISDIR(rec->ur_mode)) + rec->ur_mode |= S_ISGID; + } + switch (type) { case S_IFREG: { handle = mds_fs_start(mds, dir, MDS_FSOP_CREATE); @@ -323,9 +327,11 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, struct obdo *obdo; obdo = lustre_msg_buf(req->rq_reqmsg, 2); rc = mds_fs_set_obdo(mds, inode, handle, obdo); - if (rc) - CERROR("error %d setting objid for %ld\n", + if (rc) { + CERROR("error %d setting obdo for %ld\n", rc, inode->i_ino); + GOTO(out_create_unlink, rc); + } } iattr.ia_atime = rec->ur_time; @@ -369,6 +375,25 @@ out_create_de: l_dput(de); req->rq_status = rc; return 0; + +out_create_unlink: + /* Destroy the file we just created. This should not need extra + * journal credits, as we have already modified all of the blocks + * needed in order to create the file in the first place. + */ + switch(type) { + case S_IFDIR: + err = vfs_rmdir(dir, dchild); + if (err) + CERROR("failed rmdir in error path: rc = %d\n", err); + break; + default: + err = vfs_unlink(dir, dchild); + if (err) + CERROR("failed unlink in error path: rc = %d\n", err); + } + + goto out_create_commit; } static int mds_reint_unlink(struct mds_update_record *rec, int offset, @@ -676,6 +701,9 @@ static mds_reinter reinters[REINT_MAX+1] = { int mds_reint_rec(struct mds_update_record *rec, int offset, struct ptlrpc_request *req) { + struct mds_obd *mds = &req->rq_obd->u.mds; + struct obd_run_ctxt saved; + int rc; if (rec->ur_opcode < 1 || rec->ur_opcode > REINT_MAX) { @@ -684,7 +712,9 @@ int mds_reint_rec(struct mds_update_record *rec, int offset, RETURN(rc); } + push_ctxt(&saved, &mds->mds_ctxt); rc = reinters[rec->ur_opcode](rec, offset, req); + pop_ctxt(&saved); return rc; } diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 35dd39d..7d45824 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -480,10 +480,10 @@ static int ost_brw(struct ost_obd *obddev, struct ptlrpc_request *req) { struct ost_body *body = lustre_msg_buf(req->rq_reqmsg, 0); - if (body->data == OBD_BRW_READ) - return ost_brw_read(obddev, req); - else + if (body->data & OBD_BRW_WRITE) return ost_brw_write(obddev, req); + else + return ost_brw_read(obddev, req); } static int ost_handle(struct obd_device *obddev, struct ptlrpc_service *svc, @@ -635,9 +635,8 @@ static int ost_setup(struct obd_device *obddev, obd_count len, void *buf) if (obddev->obd_namespace == NULL) LBUG(); - ost->ost_service = ptlrpc_init_svc(64 * 1024, - OST_REQUEST_PORTAL, OSC_REPLY_PORTAL, - "self", ost_handle); + ost->ost_service = ptlrpc_init_svc(64 * 1024, OST_REQUEST_PORTAL, + OSC_REPLY_PORTAL, "self",ost_handle); if (!ost->ost_service) { CERROR("failed to start service\n"); GOTO(error_disc, err = -EINVAL); @@ -684,13 +683,7 @@ static int ost_cleanup(struct obd_device * obddev) } ptlrpc_stop_all_threads(ost->ost_service); - rpc_unregister_service(ost->ost_service); - - if (!list_empty(&ost->ost_service->srv_reqs)) { - // XXX reply with errors and clean up - CERROR("Request list not empty!\n"); - } - OBD_FREE(ost->ost_service, sizeof(*ost->ost_service)); + ptlrpc_unregister_service(ost->ost_service); err = obd_disconnect(&ost->ost_conn); if (err) { diff --git a/lustre/ptlrpc/rpc.c b/lustre/ptlrpc/rpc.c index 4929ce8..7e2b630 100644 --- a/lustre/ptlrpc/rpc.c +++ b/lustre/ptlrpc/rpc.c @@ -70,7 +70,7 @@ int connmgr_setup(struct obd_device *obddev, obd_count len, void *buf) RETURN(0); err_svc: - rpc_unregister_service(recovd->recovd_service); + ptlrpc_unregister_service(recovd->recovd_service); err_recovd: recovd_cleanup(recovd); err_free: @@ -90,13 +90,7 @@ int connmgr_cleanup(struct obd_device *dev) LBUG(); ptlrpc_stop_all_threads(recovd->recovd_service); - rpc_unregister_service(recovd->recovd_service); - if (!list_empty(&recovd->recovd_service->srv_reqs)) { - // XXX reply with errors and clean up - CERROR("Request list not empty!\n"); - } - - OBD_FREE(recovd->recovd_service, sizeof(*recovd->recovd_service)); + ptlrpc_unregister_service(recovd->recovd_service); ptlrpc_cleanup_client(recovd->recovd_client); OBD_FREE(recovd->recovd_client, sizeof(*recovd->recovd_client)); MOD_DEC_USE_COUNT; @@ -200,7 +194,7 @@ EXPORT_SYMBOL(ptlrpc_check_status); EXPORT_SYMBOL(ptlrpc_init_svc); EXPORT_SYMBOL(ptlrpc_stop_all_threads); EXPORT_SYMBOL(ptlrpc_start_thread); -EXPORT_SYMBOL(rpc_unregister_service); +EXPORT_SYMBOL(ptlrpc_unregister_service); /* pack_generic.c */ EXPORT_SYMBOL(lustre_pack_msg); diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 34147d3..7363619 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -95,7 +95,8 @@ ptlrpc_init_svc(__u32 bufsize, int req_portal, int rep_portal, char *uuid, err = kportal_uuid_to_peer(uuid, &service->srv_self); if (err) { CERROR("cannot get peer for uuid '%s'", uuid); - GOTO(err_free, NULL); + OBD_FREE(service, sizeof(*service)); + RETURN(NULL); } service->srv_ring_length = RPC_RING_LENGTH; @@ -106,7 +107,8 @@ ptlrpc_init_svc(__u32 bufsize, int req_portal, int rep_portal, char *uuid, if (rc != PTL_OK) { CERROR("PtlEQAlloc failed: %d\n", rc); LBUG(); - GOTO(err_free, NULL); + OBD_FREE(service, sizeof(*service)); + RETURN(NULL); } for (i = 0; i < service->srv_ring_length; i++) { @@ -126,10 +128,7 @@ ptlrpc_init_svc(__u32 bufsize, int req_portal, int rep_portal, char *uuid, RETURN(service); err_ring: service->srv_ring_length = i; - rpc_unregister_service(service); // XXX verify this is right - PtlEQFree(service->srv_eq_h); -err_free: - OBD_FREE(service, sizeof(*service)); + ptlrpc_unregister_service(service); return NULL; } @@ -352,7 +351,7 @@ int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc, RETURN(0); } -int rpc_unregister_service(struct ptlrpc_service *service) +int ptlrpc_unregister_service(struct ptlrpc_service *service) { int rc, i; @@ -373,5 +372,11 @@ int rpc_unregister_service(struct ptlrpc_service *service) if (rc) CERROR("PtlEQFree failed: %d\n", rc); + if (!list_empty(&service->srv_reqs)) { + // XXX reply with errors and clean up + CERROR("Request list not empty!\n"); + } + + OBD_FREE(service, sizeof(*service)); return 0; }