- struct vfsmount *mnt) = NULL;
-static void (*kill_super_cb)(struct super_block *sb) = NULL;
-
-/*********** mount lookup *********/
-
-CFS_DEFINE_MUTEX(lustre_mount_info_lock);
-static CFS_LIST_HEAD(server_mount_info_list);
-
-static struct lustre_mount_info *server_find_mount(const char *name)
-{
- cfs_list_t *tmp;
- struct lustre_mount_info *lmi;
- ENTRY;
-
- cfs_list_for_each(tmp, &server_mount_info_list) {
- lmi = cfs_list_entry(tmp, struct lustre_mount_info,
- lmi_list_chain);
- if (strcmp(name, lmi->lmi_name) == 0)
- RETURN(lmi);
- }
- RETURN(NULL);
-}
-
-/* we must register an obd for a mount before we call the setup routine.
- *_setup will call lustre_get_mount to get the mnt struct
- by obd_name, since we can't pass the pointer to setup. */
-static int server_register_mount(const char *name, struct super_block *sb,
- struct vfsmount *mnt)
-{
- struct lustre_mount_info *lmi;
- char *name_cp;
- ENTRY;
-
- LASSERT(sb);
-
- OBD_ALLOC(lmi, sizeof(*lmi));
- if (!lmi)
- RETURN(-ENOMEM);
- OBD_ALLOC(name_cp, strlen(name) + 1);
- if (!name_cp) {
- OBD_FREE(lmi, sizeof(*lmi));
- RETURN(-ENOMEM);
- }
- strcpy(name_cp, name);
-
- cfs_mutex_lock(&lustre_mount_info_lock);
-
- if (server_find_mount(name)) {
- cfs_mutex_unlock(&lustre_mount_info_lock);
- OBD_FREE(lmi, sizeof(*lmi));
- OBD_FREE(name_cp, strlen(name) + 1);
- CERROR("Already registered %s\n", name);
- RETURN(-EEXIST);
- }
- lmi->lmi_name = name_cp;
- lmi->lmi_sb = sb;
- lmi->lmi_mnt = mnt;
- cfs_list_add(&lmi->lmi_list_chain, &server_mount_info_list);
-
- cfs_mutex_unlock(&lustre_mount_info_lock);
-
- CDEBUG(D_MOUNT, "reg_mnt %p from %s, vfscount=%d\n",
- lmi->lmi_mnt, name,
- lmi->lmi_mnt ? mnt_get_count(lmi->lmi_mnt) : -1);
-
- RETURN(0);
-}
-
-/* when an obd no longer needs a mount */
-static int server_deregister_mount(const char *name)
-{
- struct lustre_mount_info *lmi;
- ENTRY;
-
- cfs_mutex_lock(&lustre_mount_info_lock);
- lmi = server_find_mount(name);
- if (!lmi) {
- cfs_mutex_unlock(&lustre_mount_info_lock);
- CERROR("%s not registered\n", name);
- RETURN(-ENOENT);
- }
-
- CDEBUG(D_MOUNT, "dereg_mnt %p from %s, vfscount=%d\n",
- lmi->lmi_mnt, name,
- lmi->lmi_mnt ? mnt_get_count(lmi->lmi_mnt) : -1);
-
- OBD_FREE(lmi->lmi_name, strlen(lmi->lmi_name) + 1);
- cfs_list_del(&lmi->lmi_list_chain);
- OBD_FREE(lmi, sizeof(*lmi));
- cfs_mutex_unlock(&lustre_mount_info_lock);
-
- RETURN(0);
-}
-
-/* obd's look up a registered mount using their obdname. This is just
- for initial obd setup to find the mount struct. It should not be
- called every time you want to mntget. */
-struct lustre_mount_info *server_get_mount(const char *name)
-{
- struct lustre_mount_info *lmi;
- struct lustre_sb_info *lsi;
- ENTRY;
-
- cfs_mutex_lock(&lustre_mount_info_lock);
- lmi = server_find_mount(name);
- cfs_mutex_unlock(&lustre_mount_info_lock);
- if (!lmi) {
- CERROR("Can't find mount for %s\n", name);
- RETURN(NULL);
- }
- lsi = s2lsi(lmi->lmi_sb);
-
- if (lmi->lmi_mnt)
- mntget(lmi->lmi_mnt);
- cfs_atomic_inc(&lsi->lsi_mounts);
-
- CDEBUG(D_MOUNT, "get_mnt %p from %s, refs=%d, vfscount=%d\n",
- lmi->lmi_mnt, name, cfs_atomic_read(&lsi->lsi_mounts),
- lmi->lmi_mnt ? mnt_get_count(lmi->lmi_mnt) - 1 : -1);
-
- RETURN(lmi);
-}
-
-/*
- * Used by mdt to get mount_info from obdname.
- * There are no blocking when using the mount_info.
- * Do not use server_get_mount for this purpose.
- */
-struct lustre_mount_info *server_get_mount_2(const char *name)
-{
- struct lustre_mount_info *lmi;
- ENTRY;
-
- cfs_mutex_lock(&lustre_mount_info_lock);
- lmi = server_find_mount(name);
- cfs_mutex_unlock(&lustre_mount_info_lock);
- if (!lmi)
- CERROR("Can't find mount for %s\n", name);
-
- RETURN(lmi);
-}
-
-static void unlock_mntput(struct vfsmount *mnt)
-{
-#ifdef HAVE_KERNEL_LOCKED
- /* for kernel < 2.6.37 */
- if (kernel_locked()) {
- unlock_kernel();
- mntput(mnt);
- lock_kernel();
- } else {
- mntput(mnt);
- }
-#else
- mntput(mnt);
-#endif
-}
-
-static int lustre_put_lsi(struct super_block *sb);
-
-/* to be called from obd_cleanup methods */
-int server_put_mount(const char *name, struct vfsmount *mnt)
-{
- struct lustre_mount_info *lmi;
- struct lustre_sb_info *lsi;
- int count = 0;
- ENTRY;
-
- /* This might be the last one, can't deref after this */
- if (mnt) {
- count = mnt_get_count(mnt) - 1;
- unlock_mntput(mnt);
- }
-
- cfs_mutex_lock(&lustre_mount_info_lock);
- lmi = server_find_mount(name);
- cfs_mutex_unlock(&lustre_mount_info_lock);
- if (!lmi) {
- CERROR("Can't find mount for %s\n", name);
- RETURN(-ENOENT);
- }
- lsi = s2lsi(lmi->lmi_sb);
- LASSERT(lmi->lmi_mnt == mnt);
-
- CDEBUG(D_MOUNT, "put_mnt %p from %s, refs=%d, vfscount=%d\n",
- lmi->lmi_mnt, name, cfs_atomic_read(&lsi->lsi_mounts), count);
-
- if (lustre_put_lsi(lmi->lmi_sb)) {
- CDEBUG(D_MOUNT, "Last put of mnt %p from %s, vfscount=%d\n",
- lmi->lmi_mnt, name, count);
- /* last mount is the One True Mount */
- if (count > 1)
- CERROR("%s: mount busy, vfscount=%d!\n", name, count);
- }
-
- /* this obd should never need the mount again */
- server_deregister_mount(name);
-
- RETURN(0);
-}
-
-/* Corresponding to server_get_mount_2 */
-int server_put_mount_2(const char *name, struct vfsmount *mnt)
-{
- ENTRY;
- RETURN(0);
-}
-
-/******* mount helper utilities *********/
-
-#if 0
-static void ldd_print(struct lustre_disk_data *ldd)
-{
- PRINT_CMD(PRINT_MASK, " disk data:\n");
- PRINT_CMD(PRINT_MASK, "server: %s\n", ldd->ldd_svname);
- PRINT_CMD(PRINT_MASK, "uuid: %s\n", (char *)ldd->ldd_uuid);
- PRINT_CMD(PRINT_MASK, "fs: %s\n", ldd->ldd_fsname);
- PRINT_CMD(PRINT_MASK, "index: %04x\n", ldd->ldd_svindex);
- PRINT_CMD(PRINT_MASK, "config: %d\n", ldd->ldd_config_ver);
- PRINT_CMD(PRINT_MASK, "flags: %#x\n", ldd->ldd_flags);
- PRINT_CMD(PRINT_MASK, "diskfs: %s\n", MT_STR(ldd));
- PRINT_CMD(PRINT_MASK, "options: %s\n", ldd->ldd_mount_opts);
- PRINT_CMD(PRINT_MASK, "params: %s\n", ldd->ldd_params);
- PRINT_CMD(PRINT_MASK, "comment: %s\n", ldd->ldd_userdata);
-}
-#endif
-
-static int ldd_parse(struct lvfs_run_ctxt *mount_ctxt,
- struct lustre_disk_data *ldd)
-{
- struct lvfs_run_ctxt saved;
- struct file *file;
- loff_t off = 0;
- unsigned long len;
- int rc;
- ENTRY;
-
- push_ctxt(&saved, mount_ctxt, NULL);
-
- file = filp_open(MOUNT_DATA_FILE, O_RDONLY, 0644);
- if (IS_ERR(file)) {
- rc = PTR_ERR(file);
- CERROR("cannot open %s: rc = %d\n", MOUNT_DATA_FILE, rc);
- GOTO(out, rc);
- }
-
- len = i_size_read(file->f_dentry->d_inode);
- CDEBUG(D_MOUNT, "Have %s, size %lu\n", MOUNT_DATA_FILE, len);
- if (len != sizeof(*ldd)) {
- CERROR("disk data size does not match: see %lu expect %u\n",
- len, (int)sizeof(*ldd));
- GOTO(out_close, rc = -EINVAL);
- }
-
- rc = lustre_fread(file, ldd, len, &off);
- if (rc != len) {
- CERROR("error reading %s: read %d of %lu\n",
- MOUNT_DATA_FILE, rc, len);
- GOTO(out_close, rc = -EINVAL);
- }
- rc = 0;
-
- if (ldd->ldd_magic != LDD_MAGIC) {
- /* FIXME add swabbing support */
- CERROR("Bad magic in %s: %x!=%x\n", MOUNT_DATA_FILE,
- ldd->ldd_magic, LDD_MAGIC);
- GOTO(out_close, rc = -EINVAL);
- }
-
- if (ldd->ldd_feature_incompat & ~LDD_INCOMPAT_SUPP) {
- CERROR("%s: unsupported incompat filesystem feature(s) %x\n",
- ldd->ldd_svname,
- ldd->ldd_feature_incompat & ~LDD_INCOMPAT_SUPP);
- GOTO(out_close, rc = -EINVAL);
- }
- if (ldd->ldd_feature_rocompat & ~LDD_ROCOMPAT_SUPP) {
- CERROR("%s: unsupported read-only filesystem feature(s) %x\n",
- ldd->ldd_svname,
- ldd->ldd_feature_rocompat & ~LDD_ROCOMPAT_SUPP);
- /* Do something like remount filesystem read-only */
- GOTO(out_close, rc = -EINVAL);
- }
-
-out_close:
- filp_close(file, 0);
-out:
- pop_ctxt(&saved, mount_ctxt, NULL);
- RETURN(rc);
-}
-
-static int ldd_write(struct lvfs_run_ctxt *mount_ctxt,
- struct lustre_disk_data *ldd)
-{
- struct lvfs_run_ctxt saved;
- struct file *file;
- loff_t off = 0;
- unsigned long len = sizeof(struct lustre_disk_data);
- int rc = 0;
- ENTRY;
-
- if (ldd->ldd_magic == 0)
- RETURN(0);
-
- LASSERT(ldd->ldd_magic == LDD_MAGIC);
-
- ldd->ldd_config_ver++;
-
- push_ctxt(&saved, mount_ctxt, NULL);
-
- file = filp_open(MOUNT_DATA_FILE, O_RDWR|O_SYNC, 0644);
- if (IS_ERR(file)) {
- rc = PTR_ERR(file);
- CERROR("cannot open %s: rc = %d\n", MOUNT_DATA_FILE, rc);
- GOTO(out, rc);
- }
-
- rc = lustre_fwrite(file, ldd, len, &off);
- if (rc != len) {
- CERROR("error writing %s: read %d of %lu\n",
- MOUNT_DATA_FILE, rc, len);
- GOTO(out_close, rc = -EINVAL);
- }
-
- rc = 0;
-
-out_close:
- filp_close(file, 0);
-out:
- pop_ctxt(&saved, mount_ctxt, NULL);
- RETURN(rc);
-}