/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * Copyright (C) 2001-2003 Cluster File Systems, Inc.
- * Author: Andreas Dilger <adilger@clusterfs.com>
+ * GPL HEADER START
*
- * This file is part of the Lustre file system, http://www.lustre.org
- * Lustre is a trademark of Cluster File Systems, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * You may have signed or agreed to another license before downloading
- * this software. If so, you are bound by the terms and conditions
- * of that agreement, and the following does not apply to you. See the
- * LICENSE file included with this distribution for more information.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
*
- * If you did not agree to a different license, then this copy of Lustre
- * is open source software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
*
- * In either case, Lustre is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * license text for more details.
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
*
- * OST<->MDS recovery logging infrastructure.
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/obdclass/llog_lvfs.c
*
+ * OST<->MDS recovery logging infrastructure.
* Invariants in implementation:
* - we do not share logs among different OST<->MDS connections, so that
* if an OST or MDS fails it need only look at log(s) relevant to itself
+ *
+ * Author: Andreas Dilger <adilger@clusterfs.com>
*/
#define DEBUG_SUBSYSTEM S_LOG
file->f_pos = off;
- if (buflen == 0)
+ if (buflen == 0)
CWARN("0-length record\n");
if (!buf) {
RETURN(rc);
if (buf)
- /* write_blob adds header and tail to lrh_len. */
- reclen = sizeof(*rec) + rec->lrh_len +
+ /* write_blob adds header and tail to lrh_len. */
+ reclen = sizeof(*rec) + rec->lrh_len +
sizeof(struct llog_rec_tail);
if (idx != -1) {
if (idx && llh->llh_size && llh->llh_size != rec->lrh_len)
RETURN(-EINVAL);
- if (!ext2_test_bit(idx, llh->llh_bitmap))
+ if (!ext2_test_bit(idx, llh->llh_bitmap))
CERROR("Modify unset record %u\n", idx);
if (idx != rec->lrh_index)
CERROR("Index mismatch %d %u\n", idx, rec->lrh_index);
RETURN(-EFAULT);
}
#if 1 /* FIXME remove this safety check at some point */
- /* Verify that the record we're modifying is the
+ /* Verify that the record we're modifying is the
right one. */
rc = llog_lvfs_read_blob(obd, file, &check,
sizeof(check), saved_offset);
if (check.lrh_index != idx || check.lrh_len != reclen) {
CERROR("Bad modify idx %u/%u size %u/%u (%d)\n",
- idx, check.lrh_index, reclen,
+ idx, check.lrh_index, reclen,
check.lrh_len, rc);
RETURN(-EFAULT);
}
/* NOTE: padding is a record, but no bit is set */
if (left != 0 && left != reclen &&
left < (reclen + LLOG_MIN_REC_SIZE)) {
- loghandle->lgh_last_idx++;
- rc = llog_lvfs_pad(obd, file, left, loghandle->lgh_last_idx);
- if (rc)
- RETURN(rc);
- /* if it's the last idx in log file, then return -ENOSPC */
- if (loghandle->lgh_last_idx == LLOG_BITMAP_SIZE(llh) - 1)
- RETURN(-ENOSPC);
- }
-
+ index = loghandle->lgh_last_idx + 1;
+ rc = llog_lvfs_pad(obd, file, left, index);
+ if (rc)
+ RETURN(rc);
+ loghandle->lgh_last_idx++; /*for pad rec*/
+ }
+ /* if it's the last idx in log file, then return -ENOSPC */
+ if (loghandle->lgh_last_idx >= LLOG_BITMAP_SIZE(llh) - 1)
+ RETURN(-ENOSPC);
loghandle->lgh_last_idx++;
index = loghandle->lgh_last_idx;
LASSERT(index < LLOG_BITMAP_SIZE(llh));
lrt->lrt_len = rec->lrh_len;
lrt->lrt_index = rec->lrh_index;
}
+ /*The caller should make sure only 1 process access the lgh_last_idx,
+ *Otherwise it might hit the assert.*/
+ LASSERT(index < LLOG_BITMAP_SIZE(llh));
if (ext2_set_bit(index, llh->llh_bitmap)) {
CERROR("argh, index %u already set in log bitmap?\n", index);
LBUG(); /* should never happen */
if (rc)
RETURN(rc);
- CDEBUG(D_RPCTRACE, "added record "LPX64": idx: %u, %u bytes\n",
+ CDEBUG(D_RPCTRACE, "added record "LPX64": idx: %u, %u \n",
loghandle->lgh_id.lgl_oid, index, rec->lrh_len);
if (rc == 0 && reccookie) {
reccookie->lgc_lgl = loghandle->lgh_id;
reccookie->lgc_index = index;
- if ((rec->lrh_type == MDS_UNLINK_REC) ||
+ if ((rec->lrh_type == MDS_UNLINK_REC) ||
(rec->lrh_type == MDS_SETATTR_REC))
reccookie->lgc_subsys = LLOG_MDS_OST_ORIG_CTXT;
else if (rec->lrh_type == OST_SZ_REC)
} else if (name) {
/* COMPAT_146 */
if (strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME) == 0) {
- handle->lgh_file = llog_filp_open(MDT_LOGS_DIR, name,
+ handle->lgh_file = llog_filp_open(MDT_LOGS_DIR, name,
open_flags, 0644);
} else {
/* end COMPAT_146 */
handle->lgh_file = llog_filp_open(MOUNT_CONFIGS_DIR,
- name, open_flags,
+ name, open_flags,
0644);
}
if (IS_ERR(handle->lgh_file))
if (strcmp(fdentry->d_parent->d_name.name, dir) == 0) {
struct inode *inode = fdentry->d_parent->d_inode;
struct lvfs_run_ctxt saved;
+ struct vfsmount *mnt = mntget(handle->lgh_file->f_vfsmnt);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
dget(fdentry);
rc = llog_lvfs_close(handle);
if (rc == 0) {
- LOCK_INODE_MUTEX(inode);
- rc = vfs_unlink(inode, fdentry);
+ LOCK_INODE_MUTEX_PARENT(inode);
+ rc = ll_vfs_unlink(inode, fdentry, mnt);
UNLOCK_INODE_MUTEX(inode);
}
+ mntput(mnt);
dput(fdentry);
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
/* reads the catalog list */
int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd,
- char *name, int count, struct llog_catid *idarray)
+ char *name, int idx, int count, struct llog_catid *idarray)
{
struct lvfs_run_ctxt saved;
struct l_file *file;
- int rc;
+ int rc, rc1 = 0;
int size = sizeof(*idarray) * count;
- loff_t off = 0;
+ loff_t off = idx * sizeof(*idarray);
ENTRY;
- if (!count)
+ if (!count)
RETURN(0);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
name, rc);
GOTO(out, rc);
}
-
+
if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
CERROR("%s is not a regular file!: mode = %o\n", name,
file->f_dentry->d_inode->i_mode);
CDEBUG(D_CONFIG, "cat list: disk size=%d, read=%d\n",
(int)i_size_read(file->f_dentry->d_inode), size);
+ /* read for new ost index or for empty file */
+ memset(idarray, 0, size);
+ if (i_size_read(file->f_dentry->d_inode) < off)
+ GOTO(out, rc = 0);
+
rc = fsfilt_read_record(disk_obd, file, idarray, size, &off);
if (rc) {
CERROR("OBD filter: error reading %s: rc %d\n", name, rc);
out:
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
if (file && !IS_ERR(file))
- rc = filp_close(file, 0);
+ rc1 = filp_close(file, 0);
+ if (rc == 0)
+ rc = rc1;
return rc;
}
EXPORT_SYMBOL(llog_get_cat_list);
/* writes the cat list */
int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd,
- char *name, int count, struct llog_catid *idarray)
+ char *name, int idx, int count, struct llog_catid *idarray)
{
struct lvfs_run_ctxt saved;
struct l_file *file;
- int rc;
+ int rc, rc1 = 0;
int size = sizeof(*idarray) * count;
- loff_t off = 0;
+ loff_t off = idx * sizeof(*idarray);
- if (!count)
- return (0);
+ if (!count)
+ GOTO(out1, rc = 0);
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
file = filp_open(name, O_RDWR | O_CREAT | O_LARGEFILE, 0700);
rc = fsfilt_write_record(disk_obd, file, idarray, size, &off, 1);
if (rc) {
- CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
+ CDEBUG(D_INODE,"OBD filter: error writeing %s: rc %d\n",
name, rc);
GOTO(out, rc);
}
- out:
+out:
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
if (file && !IS_ERR(file))
- rc = filp_close(file, 0);
+ rc1 = filp_close(file, 0);
+
+ if (rc == 0)
+ rc = rc1;
+out1:
RETURN(rc);
}
+EXPORT_SYMBOL(llog_put_cat_list);
struct llog_operations llog_lvfs_ops = {
lop_write_rec: llog_lvfs_write_rec,
}
int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd,
- char *name, int count, struct llog_catid *idarray)
+ char *name, int idx, int count, struct llog_catid *idarray)
{
LBUG();
return 0;
}
int llog_put_cat_list(struct obd_device *obd, struct obd_device *disk_obd,
- char *name, int count, struct llog_catid *idarray)
+ char *name, int idx, int count, struct llog_catid *idarray)
{
LBUG();
return 0;