X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmds%2Fhandler.c;h=9f3001663f698e935a0eb38c0b868fbc560608cf;hb=5ac94a75953124d934cef2788a3dddd676c49bb3;hp=00c47abae67e0eb18fcf87730db8c46a1d43acb5;hpb=52b3216f3e0c493451b72c886994bd62a8c8f1d9;p=fs%2Flustre-release.git diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 00c47ab..9f30016 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -434,24 +434,26 @@ static int mds_setup(struct obd_device *obddev, obd_count len, void *buf) { struct obd_ioctl_data* data = buf; struct mds_obd *mds = &obddev->u.mds; + struct super_operations *s_ops; + struct super_block *sb; struct vfsmount *mnt; int err; ENTRY; MOD_INC_USE_COUNT; +#ifdef CONFIG_DEV_RDONLY + dev_clear_rdonly(2); +#endif mnt = do_kern_mount(data->ioc_inlbuf2, 0, data->ioc_inlbuf1, NULL); err = PTR_ERR(mnt); if (IS_ERR(mnt)) { CERROR("do_kern_mount failed: %d\n", err); - MOD_DEC_USE_COUNT; - RETURN(err); + GOTO(err_dec, err); } - mds->mds_sb = mnt->mnt_root->d_inode->i_sb; - if (!mds->mds_sb) { - MOD_DEC_USE_COUNT; - RETURN(-ENODEV); - } + sb = mds->mds_sb = mnt->mnt_root->d_inode->i_sb; + if (!sb) + GOTO(err_put, (err = -ENODEV)); mds->mds_vfsmnt = mnt; mds->mds_fstype = strdup(data->ioc_inlbuf2); @@ -462,19 +464,9 @@ static int mds_setup(struct obd_device *obddev, obd_count len, void *buf) mds->mds_fsops = &mds_ext2_fs_ops; else { CERROR("unsupported MDS filesystem type %s\n", mds->mds_fstype); - kfree(mds->mds_fstype); - MOD_DEC_USE_COUNT; - RETURN(-EPERM); + GOTO(err_kfree, (err = -EPERM)); } - /* - * Replace the client filesystem delete_inode method with our own, - * so that we can clear the object ID before the inode is deleted. - * The fs_delete_inode method will call cl_delete_inode for us. - */ - mds->mds_fsops->cl_delete_inode = mds->mds_sb->s_op->delete_inode; - mds->mds_sb->s_op->delete_inode = mds->mds_fsops->fs_delete_inode; - mds->mds_ctxt.pwdmnt = mnt; mds->mds_ctxt.pwd = mnt->mnt_root; mds->mds_ctxt.fs = KERNEL_DS; @@ -484,19 +476,52 @@ static int mds_setup(struct obd_device *obddev, obd_count len, void *buf) "self", mds_handle); if (!mds->mds_service) { CERROR("failed to start service\n"); - RETURN(-EINVAL); + GOTO(err_kfree, (err = -EINVAL)); } err = ptlrpc_start_thread(obddev, mds->mds_service, "lustre_mds"); - if (err) + if (err) { CERROR("cannot start thread\n"); - /* FIXME: do we need to MOD_DEC_USE_COUNT here? */ + GOTO(err_svc, err); + } + + /* + * Replace the client filesystem delete_inode method with our own, + * so that we can clear the object ID before the inode is deleted. + * The fs_delete_inode method will call cl_delete_inode for us. + * + * We need to do this for the MDS superblock only, hence we install + * a modified copy of the original superblock method table. + * + * We still assume that there is only a single MDS client filesystem + * type, as we don't have access to the mds struct in * delete_inode. + */ + OBD_ALLOC(s_ops, sizeof(*s_ops)); + memcpy(s_ops, sb->s_op, sizeof(*s_ops)); + mds->mds_fsops->cl_delete_inode = s_ops->delete_inode; + s_ops->delete_inode = mds->mds_fsops->fs_delete_inode; + sb->s_op = s_ops; RETURN(0); + +err_svc: + rpc_unregister_service(mds->mds_service); + OBD_FREE(mds->mds_service, sizeof(*mds->mds_service)); +err_kfree: + kfree(mds->mds_fstype); +err_put: + unlock_kernel(); // XXX do we want/need this? + mntput(mds->mds_vfsmnt); + mds->mds_sb = 0; + lock_kernel(); // XXX do we want/need this? +err_dec: + MOD_DEC_USE_COUNT; + return err; } static int mds_cleanup(struct obd_device * obddev) { + struct super_operations *s_ops = NULL; struct super_block *sb; struct mds_obd *mds = &obddev->u.mds; @@ -509,24 +534,28 @@ static int mds_cleanup(struct obd_device * obddev) ptlrpc_stop_thread(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"); } - - rpc_unregister_service(mds->mds_service); OBD_FREE(mds->mds_service, sizeof(*mds->mds_service)); sb = mds->mds_sb; if (!mds->mds_sb) RETURN(0); + s_ops = sb->s_op; + unlock_kernel(); mntput(mds->mds_vfsmnt); mds->mds_sb = 0; kfree(mds->mds_fstype); lock_kernel(); +#ifdef CONFIG_DEV_RDONLY + dev_clear_rdonly(2); +#endif + + OBD_FREE(s_ops, sizeof(*s_ops)); MOD_DEC_USE_COUNT; RETURN(0);