Whamcloud - gitweb
Move cleanup of service struct into ptlrpc_unregister_service().
authoradilger <adilger>
Sun, 23 Jun 2002 02:47:20 +0000 (02:47 +0000)
committeradilger <adilger>
Sun, 23 Jun 2002 02:47:20 +0000 (02:47 +0000)
Includes MDS statfs method.
Includes fixes for sgid directories on MDS.

lustre/include/linux/lustre_net.h
lustre/ldlm/ldlm_lockd.c
lustre/mds/Makefile.am
lustre/mds/handler.c
lustre/mds/mds_fs.c
lustre/mds/mds_reint.c
lustre/ost/ost_handler.c
lustre/ptlrpc/rpc.c
lustre/ptlrpc/service.c

index 30224e2..02f5e17 100644 (file)
@@ -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;
index d313fcc..4d60432 100644 (file)
@@ -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");
index 887039c..1f66d82 100644 (file)
@@ -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
 
index a28954d..abb73a3 100644 (file)
@@ -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)
index 8efca61..b5f9d3a 100644 (file)
@@ -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;
index 3480ffb..95655a9 100644 (file)
@@ -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;
 }
index 35dd39d..7d45824 100644 (file)
@@ -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) {
index 4929ce8..7e2b630 100644 (file)
@@ -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);
index 34147d3..7363619 100644 (file)
@@ -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;
 }