-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#define DEBUG_SUBSYSTEM S_FILTER
-#ifndef AUTOCONF_INCLUDED
-#include <linux/config.h>
-#endif
#include <linux/module.h>
#include <linux/version.h>
return 0;
}
-/* Called with res->lr_lvb_sem held */
+/* Called with res->lr_lvb_mutex held */
static int filter_lvbo_init(struct ldlm_resource *res)
{
struct ost_lvb *lvb = NULL;
ENTRY;
LASSERT(res);
- LASSERT_SEM_LOCKED(&res->lr_lvb_sem);
+ LASSERT_MUTEX_LOCKED(&res->lr_lvb_mutex);
if (res->lr_lvb_data)
RETURN(0);
LPU64")\n", obd->obd_name, res->lr_name.name[1],
res->lr_name.name[0]);
- dentry = filter_fid2dentry(obd, NULL, res->lr_name.name[1],
+ dentry = filter_fid2dentry(obd, NULL, res->lr_name.name[1],
res->lr_name.name[0]);
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
/* This will be called in two ways:
*
- * m != NULL : called by the DLM itself after a glimpse callback
- * m == NULL : called by the filter after a disk write
+ * r != NULL : called by the DLM itself after a glimpse callback
+ * r == NULL : called by the filter after a disk write
*
* If 'increase_only' is true, don't allow values to move backwards.
*/
struct ost_lvb *lvb;
struct obd_device *obd;
struct inode *inode;
+ struct inode *tmpinode = NULL;
ENTRY;
LASSERT(res);
- cfs_down(&res->lr_lvb_sem);
+ lock_res(res);
lvb = res->lr_lvb_data;
if (lvb == NULL) {
CERROR("No lvb when running lvbo_update!\n");
lvb->lvb_ctime, new->lvb_ctime);
lvb->lvb_ctime = new->lvb_ctime;
}
+ if (new->lvb_blocks > lvb->lvb_blocks || !increase_only) {
+ CDEBUG(D_DLMTRACE, "res: "LPU64" updating lvb blocks: "
+ LPU64" -> "LPU64"\n", res->lr_name.name[0],
+ lvb->lvb_blocks, new->lvb_blocks);
+ lvb->lvb_blocks = new->lvb_blocks;
+ }
}
disk_update:
LASSERT(obd);
inode = res->lr_lvb_inode;
- /* filter_fid2dentry could fail */
- if (unlikely(!inode)) {
+ /* filter_fid2dentry could fail, esp. in OBD_FAIL_OST_ENOENT test case */
+ if (unlikely(inode == NULL)) {
struct dentry *dentry;
- dentry = filter_fid2dentry(obd, NULL, res->lr_name.name[1],
+ unlock_res(res);
+
+ dentry = filter_fid2dentry(obd, NULL, res->lr_name.name[1],
res->lr_name.name[0]);
if (IS_ERR(dentry))
- GOTO(out, rc = PTR_ERR(dentry));
+ RETURN(PTR_ERR(dentry));
if (dentry->d_inode)
- inode = res->lr_lvb_inode = igrab(dentry->d_inode);
+ tmpinode = igrab(dentry->d_inode);
f_dput(dentry);
+ /* tmpinode could be NULL, but it does not matter if other
+ * have set res->lr_lvb_inode */
+ lock_res(res);
+ if (res->lr_lvb_inode == NULL) {
+ res->lr_lvb_inode = tmpinode;
+ tmpinode = NULL;
+ }
+ inode = res->lr_lvb_inode;
}
if (!inode || !inode->i_nlink)
lvb->lvb_ctime, LTIME_S(inode->i_ctime));
lvb->lvb_ctime = LTIME_S(inode->i_ctime);
}
- if (lvb->lvb_blocks != inode->i_blocks) {
+ if (inode->i_blocks > lvb->lvb_blocks || !increase_only) {
CDEBUG(D_DLMTRACE,"res: "LPU64" updating lvb blocks from disk: "
LPU64" -> %llu\n", res->lr_name.name[0],
lvb->lvb_blocks, (unsigned long long)inode->i_blocks);
}
out:
- cfs_up(&res->lr_lvb_sem);
+ unlock_res(res);
+ if (tmpinode)
+ iput(tmpinode);
return rc;
}
+static int filter_lvbo_size(struct ldlm_lock *unused)
+{
+ return sizeof(struct ost_lvb);
+}
+
+static int filter_lvbo_fill(struct ldlm_lock *lock,
+ void *buf, int buflen)
+{
+ struct ldlm_resource *res = lock->l_resource;
+
+ lock_res(res);
+ LASSERTF(buflen >= res->lr_lvb_len,
+ "actual %d, want %d\n", buflen, res->lr_lvb_len);
+ memcpy(buf, res->lr_lvb_data, res->lr_lvb_len);
+ unlock_res(res);
+
+ return res->lr_lvb_len;
+}
+
struct ldlm_valblock_ops filter_lvbo = {
lvbo_init: filter_lvbo_init,
lvbo_update: filter_lvbo_update,
- lvbo_free: filter_lvbo_free
+ lvbo_free: filter_lvbo_free,
+ lvbo_size: filter_lvbo_size,
+ lvbo_fill: filter_lvbo_fill
};