-
- CDEBUG(D_INFO, "freeing client at offset %d with UUID '%s'\n",
- med->med_off, med->med_mcd->mcd_uuid);
-
- word = last_rcvd_slots + med->med_off / sizeof(unsigned long);
- bit = med->med_off % sizeof(unsigned long);
-
- if (!test_and_clear_bit(bit, word)) {
- CERROR("bit %d already clear in word %d - bad bad\n",
- bit, word - last_rcvd_slots);
- LBUG();
- }
-
- OBD_FREE(med->med_mcd, sizeof(*med->med_mcd));
-
- return 0;
-}
-
-static int mds_server_free_data(struct mds_obd *mds)
-{
- OBD_FREE(mds->mds_server_data, sizeof(*mds->mds_server_data));
- mds->mds_server_data = NULL;
-
- return 0;
-}
-
-#define LAST_RCVD "last_rcvd"
-
-static int mds_read_last_rcvd(struct obd_device *obddev, struct file *f)
-{
- struct mds_obd *mds = &obddev->u.mds;
- struct mds_server_data *msd;
- struct mds_client_data *mcd = NULL;
- loff_t fsize = f->f_dentry->d_inode->i_size;
- loff_t off = 0;
- int cl_off;
- __u64 last_rcvd = 0;
- __u64 last_mount;
- int clients = 0;
- int rc = 0;
-
- OBD_ALLOC(msd, sizeof(*msd));
- if (!msd)
- RETURN(-ENOMEM);
- rc = lustre_fread(f, (char *)msd, sizeof(*msd), &off);
-
- mds->mds_server_data = msd;
- if (rc == 0) {
- CERROR("empty MDS %s, new MDS?\n", LAST_RCVD);
- RETURN(0);
- }
-
- if (rc != sizeof(*msd)) {
- CERROR("error reading MDS %s: rc = %d\n", LAST_RCVD, rc);
- if (rc > 0) {
- rc = -EIO;
- }
- GOTO(err_msd, rc);
- }
-
- /*
- * When we do a clean MDS shutdown, we save the last_rcvd into
- * the header. If we find clients with higher last_rcvd values
- * then those clients may need recovery done.
- */
- last_rcvd = le64_to_cpu(msd->msd_last_rcvd);
- mds->mds_last_rcvd = last_rcvd;
- CDEBUG(D_INODE, "got %Lu for server last_rcvd value\n",
- (unsigned long long)last_rcvd);
-
- last_mount = le64_to_cpu(msd->msd_mount_count);
- mds->mds_mount_count = last_mount;
- CDEBUG(D_INODE, "got %Lu for server last_mount value\n",
- (unsigned long long)last_mount);
-
- for (off = MDS_LR_CLIENT, cl_off = 0, rc = sizeof(*mcd);
- off <= fsize - sizeof(*mcd) && rc == sizeof(*mcd);
- off = MDS_LR_CLIENT + ++cl_off * MDS_LR_SIZE) {
- if (!mcd) {
- OBD_ALLOC(mcd, sizeof(*mcd));
- if (!mcd)
- GOTO(err_msd, rc = -ENOMEM);
- }
-
- rc = lustre_fread(f, (char *)mcd, sizeof(*mcd), &off);
- if (rc != sizeof(*mcd)) {
- CERROR("error reading MDS %s offset %d: rc = %d\n",
- LAST_RCVD, cl_off, rc);
- if (rc > 0)
- rc = -EIO;
- break;
- }
-
- last_rcvd = le64_to_cpu(mcd->mcd_last_rcvd);
-
- /* Do client recovery here (open files, etc) */
- if (last_rcvd && (last_mount - le64_to_cpu(mcd->mcd_mount_count)
- < MDS_MOUNT_RECOV)) {
- struct obd_export *export = class_new_export(obddev);
- if (!export) {
- rc = -ENOMEM;
- break;
- }
- export->exp_mds_data.med_mcd = mcd;
- mds_client_add(&export->exp_mds_data, cl_off);
- mcd = NULL;
- clients++;
- } else {
- CDEBUG(D_INFO,
- "ignored client %d, UUID '%s', last_mount %Ld\n",
- cl_off, mcd->mcd_uuid,
- (long long)le64_to_cpu(mcd->mcd_mount_count));
- }
-
- if (last_rcvd > mds->mds_last_rcvd) {
- CDEBUG(D_OTHER,
- "client at offset %d has last_rcvd = %Lu\n",
- cl_off, (unsigned long long)last_rcvd);
- mds->mds_last_rcvd = last_rcvd;
- }
- }
- CDEBUG(D_INODE, "got %Lu for highest last_rcvd value, %d/%d clients\n",
- (unsigned long long)mds->mds_last_rcvd, clients, cl_off);
-
- if (mcd)
- OBD_FREE(mcd, sizeof(*mcd));
-
- /* After recovery, there can be no local uncommitted transactions */
- mds->mds_last_committed = mds->mds_last_rcvd;
-
- return 0;
-
-err_msd:
- mds_server_free_data(mds);
- return rc;
-}
-
-static int mds_fs_prep(struct obd_device *obddev)
-{
- struct mds_obd *mds = &obddev->u.mds;
- struct obd_run_ctxt saved;
- struct dentry *dentry;
- struct file *f;
- int rc;
-
- push_ctxt(&saved, &mds->mds_ctxt);
- dentry = simple_mkdir(current->fs->pwd, "ROOT", 0755);
- if (IS_ERR(dentry)) {
- rc = PTR_ERR(dentry);
- CERROR("cannot create ROOT directory: rc = %d\n", rc);
- GOTO(err_pop, rc);
- }
-
- mds->mds_rootfid.id = dentry->d_inode->i_ino;
- mds->mds_rootfid.generation = dentry->d_inode->i_generation;
- mds->mds_rootfid.f_type = S_IFDIR;
-
- dput(dentry);
-
- dentry = simple_mkdir(current->fs->pwd, "FH", 0700);
- if (IS_ERR(dentry)) {
- rc = PTR_ERR(dentry);
- CERROR("cannot create FH directory: rc = %d\n", rc);
- GOTO(err_pop, rc);
- }
- /* XXX probably want to hold on to this later... */
- dput(dentry);
-
- f = filp_open(LAST_RCVD, O_RDWR | O_CREAT, 0644);
- if (IS_ERR(f)) {
- rc = PTR_ERR(f);
- CERROR("cannot open/create %s file: rc = %d\n", LAST_RCVD, rc);
- GOTO(err_pop, rc = PTR_ERR(f));
- }
- if (!S_ISREG(f->f_dentry->d_inode->i_mode)) {
- CERROR("%s is not a regular file!: mode = %o\n", LAST_RCVD,
- f->f_dentry->d_inode->i_mode);
- GOTO(err_pop, rc = -ENOENT);
- }
-
- rc = mds_fs_journal_data(mds, f);
- if (rc) {
- CERROR("cannot journal data on %s: rc = %d\n", LAST_RCVD, rc);
- GOTO(err_filp, rc);