⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obd_mount.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 5 页
字号:
                OBD_FREE(lsi, sizeof(*lsi));                RETURN(NULL);        }        lsi->lsi_lmd->lmd_exclude_count = 0;        s2lsi_nocast(sb) = lsi;        /* we take 1 extra ref for our setup */        atomic_set(&lsi->lsi_mounts, 1);        /* Default umount style */        lsi->lsi_flags = LSI_UMOUNT_FAILOVER;        RETURN(lsi);}static int lustre_free_lsi(struct super_block *sb){        struct lustre_sb_info *lsi = s2lsi(sb);        ENTRY;        if (!lsi)                RETURN(0);        CDEBUG(D_MOUNT, "Freeing lsi\n");        /* someone didn't call server_put_mount. */        LASSERT(atomic_read(&lsi->lsi_mounts) == 0);        if (lsi->lsi_ldd != NULL)                OBD_FREE(lsi->lsi_ldd, sizeof(*lsi->lsi_ldd));        if (lsi->lsi_lmd != NULL) {                if (lsi->lsi_lmd->lmd_dev != NULL)                        OBD_FREE(lsi->lsi_lmd->lmd_dev,                                 strlen(lsi->lsi_lmd->lmd_dev) + 1);                if (lsi->lsi_lmd->lmd_profile != NULL)                        OBD_FREE(lsi->lsi_lmd->lmd_profile,                                 strlen(lsi->lsi_lmd->lmd_profile) + 1);                if (lsi->lsi_lmd->lmd_opts != NULL)                        OBD_FREE(lsi->lsi_lmd->lmd_opts,                                 strlen(lsi->lsi_lmd->lmd_opts) + 1);                if (lsi->lsi_lmd->lmd_exclude_count)                        OBD_FREE(lsi->lsi_lmd->lmd_exclude,                                 sizeof(lsi->lsi_lmd->lmd_exclude[0]) *                                 lsi->lsi_lmd->lmd_exclude_count);                OBD_FREE(lsi->lsi_lmd, sizeof(*lsi->lsi_lmd));        }        LASSERT(lsi->lsi_llsbi == NULL);        OBD_FREE(lsi, sizeof(*lsi));        s2lsi_nocast(sb) = NULL;        RETURN(0);}/* The lsi has one reference for every server that is using the disk -   e.g. MDT, MGS, and potentially MGC */static int lustre_put_lsi(struct super_block *sb){        struct lustre_sb_info *lsi = s2lsi(sb);        ENTRY;        LASSERT(lsi);        CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts));        if (atomic_dec_and_test(&lsi->lsi_mounts)) {                lustre_free_lsi(sb);                RETURN(1);        }        RETURN(0);}/*************** server mount ******************//* Kernel mount using mount options in MOUNT_DATA_FILE */static struct vfsmount *server_kernel_mount(struct super_block *sb){        struct lvfs_run_ctxt mount_ctxt;        struct lustre_sb_info *lsi = s2lsi(sb);        struct lustre_disk_data *ldd;        struct lustre_mount_data *lmd = lsi->lsi_lmd;        struct vfsmount *mnt;        char *options = NULL;        unsigned long page, s_flags;        struct page *__page;        int rc;        ENTRY;        OBD_ALLOC(ldd, sizeof(*ldd));        if (!ldd)                RETURN(ERR_PTR(-ENOMEM));        /* In the past, we have always used flags = 0.           Note ext3/ldiskfs can't be mounted ro. */        s_flags = sb->s_flags;        /* Pre-mount ldiskfs to read the MOUNT_DATA_FILE */        CDEBUG(D_MOUNT, "Pre-mount ldiskfs %s\n", lmd->lmd_dev);        mnt = ll_kern_mount("ldiskfs", s_flags, lmd->lmd_dev, 0);        if (IS_ERR(mnt)) {                rc = PTR_ERR(mnt);#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))                /* 2.6 kernels: if ldiskfs fails, try ldiskfs2 */                mnt = ll_kern_mount("ldiskfs2", s_flags, lmd->lmd_dev, 0);                if (IS_ERR(mnt)) {                        int rc2 = PTR_ERR(mnt);                        CERROR("premount %s:%#lx ldiskfs failed: %d, ldiskfs2 "                               "failed: %d.  Is the ldiskfs module available?\n",                               lmd->lmd_dev, s_flags, rc, rc2);                        GOTO(out_free, rc);                }#else                /* 2.4 kernels: if ldiskfs fails, try ext3 */                mnt = ll_kern_mount("ext3", s_flags, lmd->lmd_dev, 0);                if (IS_ERR(mnt)) {                        rc = PTR_ERR(mnt);                        CERROR("premount ext3 failed: rc = %d\n", rc);                        GOTO(out_free, rc);                }#endif        }        OBD_SET_CTXT_MAGIC(&mount_ctxt);        mount_ctxt.pwdmnt = mnt;        mount_ctxt.pwd = mnt->mnt_root;        mount_ctxt.fs = get_ds();        rc = ldd_parse(&mount_ctxt, ldd);        unlock_mntput(mnt);        if (rc) {                CERROR("premount parse options failed: rc = %d\n", rc);                GOTO(out_free, rc);        }        /* Done with our pre-mount, now do the real mount. */        /* Glom up mount options */        OBD_PAGE_ALLOC(__page, CFS_ALLOC_STD);        if (!__page)                GOTO(out_free, rc = -ENOMEM);        page = (unsigned long)cfs_page_address(__page);        options = (char *)page;        memset(options, 0, CFS_PAGE_SIZE);        strncpy(options, ldd->ldd_mount_opts, CFS_PAGE_SIZE - 2);        /* Add in any mount-line options */        if (lmd->lmd_opts && (*(lmd->lmd_opts) != 0)) {                int len = CFS_PAGE_SIZE - strlen(options) - 2;                if (*options != 0)                        strcat(options, ",");                strncat(options, lmd->lmd_opts, len);        }        /* Special permanent mount flags */        if (IS_OST(ldd))            s_flags |= MS_NOATIME | MS_NODIRATIME;        CDEBUG(D_MOUNT, "kern_mount: %s %s %s\n",               MT_STR(ldd), lmd->lmd_dev, options);        mnt = ll_kern_mount(MT_STR(ldd), s_flags, lmd->lmd_dev,                            (void *)options);        OBD_PAGE_FREE(__page);        if (IS_ERR(mnt)) {                rc = PTR_ERR(mnt);                CERROR("ll_kern_mount failed: rc = %d\n", rc);                GOTO(out_free, rc);        }        lsi->lsi_ldd = ldd;   /* freed at lsi cleanup */        CDEBUG(D_SUPER, "%s: mnt = %p\n", lmd->lmd_dev, mnt);        RETURN(mnt);out_free:        OBD_FREE(ldd, sizeof(*ldd));        lsi->lsi_ldd = NULL;        RETURN(ERR_PTR(rc));}static void server_wait_finished(struct vfsmount *mnt){        wait_queue_head_t   waitq;        struct l_wait_info  lwi;        int                 retries = 330;        init_waitqueue_head(&waitq);        while ((atomic_read(&mnt->mnt_count) > 1) && (retries > 0)) {                LCONSOLE_WARN("Mount still busy with %d refs, waiting for "                              "%d secs...\n",                              atomic_read(&mnt->mnt_count), retries);                /* Wait for a bit */                retries -= 5;                lwi = LWI_TIMEOUT(5 * HZ, NULL, NULL);                l_wait_event(waitq, 0, &lwi);        }        if (atomic_read(&mnt->mnt_count) > 1) {                CERROR("Mount %p is still busy (%d refs), giving up.\n",                       mnt, atomic_read(&mnt->mnt_count));        }}static void server_put_super(struct super_block *sb){        struct lustre_sb_info *lsi = s2lsi(sb);        struct obd_device     *obd;        struct vfsmount       *mnt = lsi->lsi_srv_mnt;        char *tmpname, *extraname = NULL;        int tmpname_sz;        int lddflags = lsi->lsi_ldd->ldd_flags;        int lsiflags = lsi->lsi_flags;        int rc;        ENTRY;        LASSERT(lsiflags & LSI_SERVER);        tmpname_sz = strlen(lsi->lsi_ldd->ldd_svname) + 1;        OBD_ALLOC(tmpname, tmpname_sz);        memcpy(tmpname, lsi->lsi_ldd->ldd_svname, tmpname_sz);        CDEBUG(D_MOUNT, "server put_super %s\n", tmpname);        /* Stop the target */        if (IS_MDT(lsi->lsi_ldd) || IS_OST(lsi->lsi_ldd)) {                struct lustre_profile *lprof = NULL;                /* tell the mgc to drop the config log */                lustre_end_log(sb, lsi->lsi_ldd->ldd_svname, NULL);                /* COMPAT_146 - profile may get deleted in mgc_cleanup.                   If there are any setup/cleanup errors, save the lov                   name for safety cleanup later. */                lprof = class_get_profile(lsi->lsi_ldd->ldd_svname);                if (lprof && lprof->lp_osc) {                        OBD_ALLOC(extraname, strlen(lprof->lp_osc) + 1);                        strcpy(extraname, lprof->lp_osc);                }                obd = class_name2obd(lsi->lsi_ldd->ldd_svname);                if (obd) {                        CDEBUG(D_MOUNT, "stopping %s\n", obd->obd_name);                        if (lsi->lsi_flags & LSI_UMOUNT_FAILOVER)                                obd->obd_fail = 1;                        /* We can't seem to give an error return code                         * to .put_super, so we better make sure we clean up! */                        obd->obd_force = 1;                        class_manual_cleanup(obd);                } else {                        CERROR("no obd %s\n", lsi->lsi_ldd->ldd_svname);                        server_deregister_mount(lsi->lsi_ldd->ldd_svname);                }        }        /* If they wanted the mgs to stop separately from the mdt, they           should have put it on a different device. */        if (IS_MGS(lsi->lsi_ldd)) {                /* stop the mgc before the mgs so the connection gets cleaned                   up */                lustre_stop_mgc(sb);                server_stop_mgs(sb);        }        /* Clean the mgc and sb */        rc = lustre_common_put_super(sb);        /* FIXME how can I report a failure to umount? */        /* Wait for the targets to really clean up - can't exit (and let the           sb get destroyed) while the mount is still in use */        server_wait_finished(mnt);        /* drop the One True Mount */        unlock_mntput(mnt);        /* Stop the servers (MDS, OSS) if no longer needed.  We must wait           until the target is really gone so that our type refcount check           is right. */        server_stop_servers(lddflags, lsiflags);        /* In case of startup or cleanup err, stop related obds */        if (extraname) {                obd = class_name2obd(extraname);                if (obd) {                        CWARN("Cleaning orphaned obd %s\n", extraname);                        obd->obd_force = 1;                        class_manual_cleanup(obd);                }                OBD_FREE(extraname, strlen(extraname) + 1);        }        LCONSOLE_WARN("server umount %s complete\n", tmpname);        OBD_FREE(tmpname, tmpname_sz);        EXIT;}#ifdef HAVE_UMOUNTBEGIN_VFSMOUNTstatic void server_umount_begin(struct vfsmount *vfsmnt, int flags){        struct super_block *sb = vfsmnt->mnt_sb;#elsestatic void server_umount_begin(struct super_block *sb){#endif        struct lustre_sb_info *lsi = s2lsi(sb);        ENTRY;#ifdef HAVE_UMOUNTBEGIN_VFSMOUNT        if (!(flags & MNT_FORCE)) {                EXIT;                return;        }#endif        CDEBUG(D_MOUNT, "umount -f\n");        /* umount = failover           umount -f = force           no third way to do non-force, non-failover */        lsi->lsi_flags &= ~LSI_UMOUNT_FAILOVER;        lsi->lsi_flags |= LSI_UMOUNT_FORCE;        EXIT;}#ifndef HAVE_STATFS_DENTRY_PARAMstatic int server_statfs (struct super_block *sb, struct kstatfs *buf){#elsestatic int server_statfs (struct dentry *dentry, struct kstatfs *buf){        struct super_block *sb = dentry->d_sb;#endif        struct vfsmount *mnt = s2lsi(sb)->lsi_srv_mnt;        ENTRY;        if (mnt && mnt->mnt_sb && mnt->mnt_sb->s_op->statfs) {#ifdef HAVE_STATFS_DENTRY_PARAM                int rc = mnt->mnt_sb->s_op->statfs(mnt->mnt_root, buf);#else                int rc = mnt->mnt_sb->s_op->statfs(mnt->mnt_sb, buf);#endif                if (!rc) {                        buf->f_type = sb->s_magic;                        RETURN(0);                }        }        /* just return 0 */        buf->f_type = sb->s_magic;        buf->f_bsize = sb->s_blocksize;        buf->f_blocks = 1;        buf->f_bfree = 0;        buf->f_bavail = 0;        buf->f_files = 1;        buf->f_ffree = 0;        buf->f_namelen = NAME_MAX;        RETURN(0);}static int server_show_options(struct seq_file *seq, struct vfsmount *vfsmnt){        struct vfsmount *mnt = s2lsi(vfsmnt->mnt_sb)->lsi_srv_mnt;        ENTRY;        if (mnt && mnt->mnt_sb && mnt->mnt_sb->s_op->show_options) {                int rc = mnt->mnt_sb->s_op->show_options(seq, mnt);                RETURN(rc);        }        RETURN(0);}static struct super_operations server_ops ={        .put_super      = server_put_super,        .umount_begin   = server_umount_begin, /* umount -f */        .statfs         = server_statfs,        .show_options   = server_show_options,};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -