#include <linux/lprocfs_status.h>
#include <linux/lustre_log.h>
#include <linux/lustre_commit_confd.h>
-#include <portals/list.h>
+#include <libcfs/list.h>
#include <linux/lustre_smfs.h>
+#include <linux/lustre_sec.h>
#include "filter_internal.h"
/* Group 0 is no longer a legal group, to catch uninitialized IDs */
LASSERT(bitmap != NULL);
/* XXX if fcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
- if (!strcmp(fed->fed_fcd->fcd_uuid, obd->obd_uuid.uuid))
+ if (!strcmp((char *)fed->fed_fcd->fcd_uuid, (char *)obd->obd_uuid.uuid))
RETURN(0);
/* the bitmap operations can handle cl_idx > sizeof(long) * 8, so
GOTO(free, 0);
/* XXX if fcd_uuid were a real obd_uuid, I could use obd_uuid_equals */
- if (strcmp(fed->fed_fcd->fcd_uuid, obd->obd_uuid.uuid ) == 0)
+ if (!strcmp((char *)fed->fed_fcd->fcd_uuid, (char *)obd->obd_uuid.uuid))
GOTO(free, 0);
LASSERT(filter->fo_last_rcvd_slots != NULL);
{
OBD_FREE(filter->fo_fsd, sizeof(*filter->fo_fsd));
filter->fo_fsd = NULL;
- OBD_FREE(filter->fo_last_rcvd_slots,
- FILTER_LR_MAX_CLIENT_WORDS * sizeof(unsigned long));
+ OBD_FREE(filter->fo_last_rcvd_slots, FILTER_LR_MAX_CLIENTS/8);
filter->fo_last_rcvd_slots = NULL;
return 0;
}
RETURN(-ENOMEM);
filter->fo_fsd = fsd;
- OBD_ALLOC(filter->fo_last_rcvd_slots,
- FILTER_LR_MAX_CLIENT_WORDS * sizeof(unsigned long));
+ OBD_ALLOC(filter->fo_last_rcvd_slots, FILTER_LR_MAX_CLIENTS/8);
if (filter->fo_last_rcvd_slots == NULL) {
OBD_FREE(fsd, sizeof(*fsd));
RETURN(-ENOMEM);
LAST_RCVD, rc);
GOTO(err_fsd, rc);
}
- if (strcmp(fsd->fsd_uuid, obd->obd_uuid.uuid) != 0) {
+ if (strcmp((char *)fsd->fsd_uuid, (char *)obd->obd_uuid.uuid)) {
CERROR("OBD UUID %s does not match last_rcvd UUID %s\n",
obd->obd_uuid.uuid, fsd->fsd_uuid);
GOTO(err_fsd, rc = -EINVAL);
spin_lock_init(&fed->fed_lock);
fcd = NULL;
- exp->exp_replay_needed = 1;
+ exp->exp_connected = 0;
+ exp->exp_req_replay_needed = 1;
+ exp->exp_lock_replay_needed = 1;
+ atomic_inc(&obd->obd_req_replay_clients);
+ atomic_inc(&obd->obd_lock_replay_clients);
obd->obd_recoverable_clients++;
obd->obd_max_recoverable_clients++;
class_export_put(exp);
extern void *lock_dir(struct inode *dir, struct qstr *name);
extern void unlock_dir(struct inode *dir, void *lock);
-static void * filter_lock_dentry(struct obd_device *obd,
- struct dentry *dparent, obd_id id)
+static void *filter_lock_dentry(struct obd_device *obd,
+ struct dentry *dparent,
+ obd_id id)
{
#ifdef S_PDIROPS
struct qstr qstr;
char name[32];
- qstr.name = name;
- qstr.len = sprintf(name, LPU64, id);
+ int len;
+
+ len = sprintf(name, LPU64, id);
+ qstr_assign(&qstr, (char *)name, len);
return lock_dir(dparent->d_inode, &qstr);
#else
down(&dparent->d_inode->i_sem);
LASSERT(dparent->d_inode);
*lock = filter_lock_dentry(obd, dparent, objid);
- if (time_after(jiffies, now + 15 * HZ))
- CERROR("slow parent lock %lus\n", (jiffies - now) / HZ);
+ fsfilt_check_slow(now, obd_timeout, "parent lock");
return dparent;
}
* dir_dentry is NULL, we do a read lock while we do the lookup to
* avoid races with create/destroy and such changing the directory
* internal to the filesystem code. */
-struct dentry *filter_fid2dentry(struct obd_device *obd,
- struct dentry *dir_dentry,
- obd_gr group, obd_id id)
+struct dentry *filter_id2dentry(struct obd_device *obd,
+ struct dentry *dir_dentry,
+ obd_gr group, obd_id id)
{
struct dentry *dparent = dir_dentry;
struct dentry *dchild;
len = sprintf(name, LPU64, id);
if (dir_dentry == NULL) {
dparent = filter_parent_lock(obd, group, id, &lock);
- if (IS_ERR(dparent))
+ if (IS_ERR(dparent)) {
+ CERROR("%s: error getting object "LPU64":"LPU64
+ " parent: rc %ld\n", obd->obd_name,
+ id, group, PTR_ERR(dparent));
RETURN(dparent);
+ }
}
- CDEBUG(D_INODE, "looking up object O/%*s/%s\n",
+ CDEBUG(D_INODE, "looking up object O/%.*s/%s\n",
dparent->d_name.len, dparent->d_name.name, name);
dchild = /*ll_*/lookup_one_len(name, dparent, len);
if (dir_dentry == NULL)
ENTRY;
if (inode->i_nlink != 1 || atomic_read(&inode->i_count) != 1) {
- CERROR("destroying objid %*s nlink = %lu, count = %d\n",
+ CERROR("destroying objid %.*s nlink = %lu, count = %d\n",
dchild->d_name.len, dchild->d_name.name,
(unsigned long)inode->i_nlink,
atomic_read(&inode->i_count));
rc = vfs_unlink(dparent->d_inode, dchild);
if (rc)
- CERROR("error unlinking objid %*s: rc %d\n",
+ CERROR("error unlinking objid %.*s: rc %d\n",
dchild->d_name.len, dchild->d_name.name, rc);
RETURN(rc);
RETURN(rc);
}
+#if 0
static int filter_group_set_fs_flags(struct obd_device *obd, int group)
{
struct filter_obd *filter = &obd->u.filter;
}
RETURN(rc);
}
+#endif
+
static int filter_post_fs_setup(struct obd_device *obd)
{
struct filter_obd *filter = &obd->u.filter;
- int rc = 0, j = 0;
- struct llog_ctxt *ctxt = NULL;
-
- rc = fsfilt_post_setup(obd, filter->fo_dentry_O);
- if (rc)
- RETURN(rc);
+ int rc = 0;
- for (j = 0; j < filter->fo_group_count; j++) {
- rc = filter_group_set_fs_flags(obd, j);
- if (rc)
- return rc;
- }
+ rc = fsfilt_post_setup(obd, filter->fo_dentry_O);
- fsfilt_get_reint_log_ctxt(obd, filter->fo_sb, &ctxt);
- if (ctxt) {
- ctxt->loc_obd = obd;
- ctxt->loc_idx = LLOG_REINT_ORIG_CTXT;
- obd->obd_llog_ctxt[LLOG_REINT_ORIG_CTXT] = ctxt;
- }
- fsfilt_set_ost_flags(obd, filter->fo_sb);
return rc;
}
int filter_common_setup(struct obd_device *obd, obd_count len, void *buf,
char *option)
{
- struct lustre_cfg* lcfg = buf;
+ struct lustre_cfg *lcfg = buf;
struct filter_obd *filter = &obd->u.filter;
+ struct lvfs_obd_ctxt *lvfs_ctxt = NULL;
struct vfsmount *mnt;
+ char *str;
char ns_name[48];
int rc = 0, i;
ENTRY;
- dev_clear_rdonly(2);
-
- if (!lcfg->lcfg_inlbuf1 || !lcfg->lcfg_inlbuf2)
+ if ((LUSTRE_CFG_BUFLEN(lcfg, 1)) < 1 ||
+ (LUSTRE_CFG_BUFLEN(lcfg, 2) < 1))
RETURN(-EINVAL);
- obd->obd_fsops = fsfilt_get_ops(lcfg->lcfg_inlbuf2);
+ obd->obd_fsops = fsfilt_get_ops(lustre_cfg_string(lcfg, 2));
if (IS_ERR(obd->obd_fsops))
RETURN(PTR_ERR(obd->obd_fsops));
- mnt = do_kern_mount(lcfg->lcfg_inlbuf2, MS_NOATIME | MS_NODIRATIME,
- lcfg->lcfg_inlbuf1, option);
- rc = PTR_ERR(mnt);
- if (IS_ERR(mnt))
+ rc = lvfs_mount_fs(lustre_cfg_string(lcfg, 1),
+ lustre_cfg_string(lcfg, 2),
+ option, MS_NOATIME | MS_NODIRATIME, &lvfs_ctxt);
+ if (rc) {
+ CERROR("lvfs_mount_fs failed: rc = %d\n", rc);
GOTO(err_ops, rc);
+ }
+ LASSERT(lvfs_ctxt);
- if (lcfg->lcfg_inllen3 > 0 && lcfg->lcfg_inlbuf3) {
- if (*lcfg->lcfg_inlbuf3 == 'f') {
+ mnt = lvfs_ctxt->loc_mnt;
+ filter->fo_lvfs_ctxt = lvfs_ctxt;
+
+ if (LUSTRE_CFG_BUFLEN(lcfg, 3) > 0 && lustre_cfg_buf(lcfg, 3)) {
+ str = lustre_cfg_string(lcfg, 3);
+ if (*str == 'f') {
obd->obd_replayable = 1;
obd_sync_filter = 1;
CWARN("%s: recovery enabled\n", obd->obd_name);
} else {
- if (*lcfg->lcfg_inlbuf3 != 'n') {
+ if (*str != 'n') {
CERROR("unrecognised flag '%c'\n",
- *lcfg->lcfg_inlbuf3);
+ *str);
}
// XXX Robert? Why do we get errors here
// GOTO(err_mntput, rc = -EINVAL);
obd->obd_lvfs_ctxt.fs = get_ds();
obd->obd_lvfs_ctxt.cb_ops = filter_lvfs_ops;
+ ll_clear_rdonly(ll_sbdev(filter->fo_sb));
+
rc = fsfilt_setup(obd, mnt->mnt_sb);
if (rc)
GOTO(err_mntput, rc);
filter_post(obd);
err_mntput:
unlock_kernel();
- mntput(mnt);
+ lvfs_umount_fs(filter->fo_lvfs_ctxt);
filter->fo_sb = 0;
lock_kernel();
err_ops:
static int filter_setup(struct obd_device *obd, obd_count len, void *buf)
{
- struct lustre_cfg* lcfg = buf;
+ struct filter_obd *filter = &obd->u.filter;
+ struct lustre_cfg *lcfg = buf;
+ unsigned long page;
int rc;
ENTRY;
+
+ spin_lock_init(&filter->fo_denylist_lock);
+ INIT_LIST_HEAD(&filter->fo_denylist);
+
+ /* 2.6.9 selinux wants a full option page for do_kern_mount (bug6471) */
+ page = get_zeroed_page(GFP_KERNEL);
+ if (!page)
+ RETURN(-ENOMEM);
+
+ memcpy((void *)page, lustre_cfg_buf(lcfg, 4),
+ LUSTRE_CFG_BUFLEN(lcfg, 4));
+
/* all mount options including errors=remount-ro and asyncdel are passed
* using 4th lcfg param. And it is good, finally we have got rid of
* hardcoded fs types in the code. */
- rc = filter_common_setup(obd, len, buf, lcfg->lcfg_inlbuf4);
+ rc = filter_common_setup(obd, len, buf, (void *)page);
+ free_page(page);
+
if (rc)
RETURN(rc);
rc = filter_post_fs_setup(obd);
static int filter_cleanup(struct obd_device *obd, int flags)
{
struct filter_obd *filter = &obd->u.filter;
+ ll_sbdev_type save_dev;
ENTRY;
if (flags & OBD_OPT_FAILOVER)
if (filter->fo_sb == NULL)
RETURN(0);
+ save_dev = ll_sbdev(filter->fo_sb);
filter_post_fs_cleanup(obd);
filter_post(obd);
shrink_dcache_parent(filter->fo_sb->s_root);
filter->fo_sb = 0;
- if (atomic_read(&filter->fo_vfsmnt->mnt_count) > 1)
- CERROR("%s: mount point %p busy, mnt_count: %d\n",
- obd->obd_name, filter->fo_vfsmnt,
- atomic_read(&filter->fo_vfsmnt->mnt_count));
+ spin_lock(&filter->fo_denylist_lock);
+ while (!list_empty(&filter->fo_denylist)) {
+ deny_sec_t *p_deny_sec = list_entry(filter->fo_denylist.next,
+ deny_sec_t, list);
+ list_del(&p_deny_sec->list);
+ OBD_FREE(p_deny_sec, sizeof(*p_deny_sec));
+ }
+ spin_unlock(&filter->fo_denylist_lock);
unlock_kernel();
- mntput(filter->fo_vfsmnt);
+ lvfs_umount_fs(filter->fo_lvfs_ctxt);
//destroy_buffers(filter->fo_sb->s_dev);
filter->fo_sb = NULL;
fsfilt_put_ops(obd->obd_fsops);
lock_kernel();
- dev_clear_rdonly(2);
+ ll_clear_rdonly(save_dev);
RETURN(0);
}
-static int filter_connect_post(struct obd_export *exp, unsigned long connect_flags)
+static int filter_process_config(struct obd_device *obd, obd_count len, void *buf)
+{
+ struct lustre_cfg *lcfg = buf;
+ struct filter_obd *filter = &obd->u.filter;
+ int rc = 0;
+ ENTRY;
+
+ switch(lcfg->lcfg_command) {
+ case LCFG_SET_SECURITY: {
+ if ((LUSTRE_CFG_BUFLEN(lcfg, 1) == 0) ||
+ (LUSTRE_CFG_BUFLEN(lcfg, 2) == 0))
+ GOTO(out, rc = -EINVAL);
+
+ if (!strcmp(lustre_cfg_string(lcfg, 1), "deny_sec")){
+ spin_lock(&filter->fo_denylist_lock);
+ rc = add_deny_security(lustre_cfg_string(lcfg, 2),
+ &filter->fo_denylist);
+ spin_unlock(&filter->fo_denylist_lock);
+ }else {
+ CERROR("Unrecognized key\n");
+ rc = -EINVAL;
+ }
+ break;
+ }
+ default: {
+ CERROR("Unknown command: %d\n", lcfg->lcfg_command);
+ GOTO(out, rc = -EINVAL);
+
+ }
+ }
+out:
+ RETURN(rc);
+}
+
+static int filter_connect_post(struct obd_export *exp, unsigned initial,
+ unsigned long connect_flags)
{
struct obd_device *obd = exp->exp_obd;
struct filter_export_data *fed;
char str[PTL_NALFMT_SIZE];
struct obd_llogs *llog;
struct llog_ctxt *ctxt;
- int rc;
+ int rc = 0;
ENTRY;
fed = &exp->exp_filter_data;
LASSERT(ctxt != NULL);
rc = llog_receptor_accept(ctxt, exp->exp_imp_reverse);
+
portals_nid2str(exp->exp_connection->c_peer.peer_ni->pni_number,
exp->exp_connection->c_peer.peer_id.nid, str);
+
CDEBUG(D_OTHER, "%s: init llog ctxt for export "LPX64"/%s, group %d\n",
obd->obd_name, exp->exp_connection->c_peer.peer_id.nid,
str, fed->fed_group);
/* nearly identical to mds_connect */
static int filter_connect(struct lustre_handle *conn, struct obd_device *obd,
- struct obd_uuid *cluuid, unsigned long connect_flags)
+ struct obd_uuid *cluuid,
+ struct obd_connect_data *data,
+ unsigned long connect_flags)
{
struct obd_export *exp;
struct filter_export_data *fed;
CERROR("can't read group %u\n", group);
GOTO(cleanup, rc);
}
+#if 0
rc = filter_group_set_fs_flags(obd, group);
- if (rc != 0) {
+ if (rc != 0) {
CERROR("can't set kml flags %u\n", group);
GOTO(cleanup, rc);
}
-
+#endif
cleanup:
if (rc) {
if (fcd)
obd_size maxsize = obd->obd_osfs.os_blocks * obd->obd_osfs.os_bsize;
obd_size tot_dirty = 0, tot_pending = 0, tot_granted = 0;
obd_size fo_tot_dirty, fo_tot_pending, fo_tot_granted;
+ int level = D_CACHE;
if (list_empty(&obd->obd_exports))
return;
spin_lock(&obd->obd_dev_lock);
list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
fed = &exp->exp_filter_data;
- LASSERTF(fed->fed_grant + fed->fed_pending <= maxsize,
- "cli %s/%p %lu+%lu > "LPU64"\n",
- exp->exp_client_uuid.uuid, exp,
- fed->fed_grant, fed->fed_pending, maxsize);
- LASSERTF(fed->fed_dirty <= maxsize, "cli %s/%p %lu > "LPU64"\n",
- exp->exp_client_uuid.uuid, exp,fed->fed_dirty,maxsize);
- CDEBUG(D_CACHE,"%s: cli %s/%p dirty %lu pend %lu grant %lu\n",
+ if (fed->fed_grant < 0 || fed->fed_pending < 0 ||
+ fed->fed_dirty < 0)
+ level = D_ERROR;
+ if (maxsize > 0) { /* we may not have done a statfs yet */
+ LASSERTF(fed->fed_grant + fed->fed_pending <= maxsize,
+ "cli %s/%p %ld+%ld > "LPU64"\n",
+ exp->exp_client_uuid.uuid, exp,
+ fed->fed_grant, fed->fed_pending, maxsize);
+ LASSERTF(fed->fed_dirty <= maxsize,
+ "cli %s/%p %ld > "LPU64"\n",
+ exp->exp_client_uuid.uuid, exp,
+ fed->fed_dirty, maxsize);
+ }
+ CDEBUG(level, "%s: cli %s/%p dirty %ld pend %ld grant %ld\n",
obd->obd_name, exp->exp_client_uuid.uuid, exp,
fed->fed_dirty, fed->fed_pending, fed->fed_grant);
tot_granted += fed->fed_grant + fed->fed_pending;
struct obd_device *obd = exp->exp_obd;
struct filter_obd *filter = &obd->u.filter;
struct filter_export_data *fed = &exp->exp_filter_data;
+ int level = D_CACHE;
spin_lock(&obd->obd_osfs_lock);
spin_lock(&exp->exp_obd->obd_dev_lock);
list_del_init(&exp->exp_obd_chain);
spin_unlock(&exp->exp_obd->obd_dev_lock);
- CDEBUG(D_CACHE, "%s: cli %s/%p dirty %lu pend %lu grant %lu\n",
+ if (fed->fed_dirty < 0 || fed->fed_grant < 0 || fed->fed_pending < 0)
+ level = D_ERROR;
+ CDEBUG(level, "%s: cli %s/%p dirty %ld pend %ld grant %ld\n",
obd->obd_name, exp->exp_client_uuid.uuid, exp,
fed->fed_dirty, fed->fed_pending, fed->fed_grant);
LASSERTF(filter->fo_tot_granted >= fed->fed_grant,
- "%s: tot_granted "LPU64" cli %s/%p fed_grant %lu\n",
+ "%s: tot_granted "LPU64" cli %s/%p fed_grant %ld\n",
obd->obd_name, filter->fo_tot_granted,
exp->exp_client_uuid.uuid, exp, fed->fed_grant);
filter->fo_tot_granted -= fed->fed_grant;
- LASSERTF(exp->exp_obd->u.filter.fo_tot_pending >= fed->fed_pending,
- "%s: tot_pending "LPU64" cli %s/%p fed_pending %lu\n",
+ LASSERTF(filter->fo_tot_pending >= fed->fed_pending,
+ "%s: tot_pending "LPU64" cli %s/%p fed_pending %ld\n",
obd->obd_name, filter->fo_tot_pending,
exp->exp_client_uuid.uuid, exp, fed->fed_pending);
LASSERTF(filter->fo_tot_dirty >= fed->fed_dirty,
- "%s: tot_dirty "LPU64" cli %s/%p fed_dirty %lu\n",
+ "%s: tot_dirty "LPU64" cli %s/%p fed_dirty %ld\n",
obd->obd_name, filter->fo_tot_dirty,
exp->exp_client_uuid.uuid, exp, fed->fed_dirty);
filter->fo_tot_dirty -= fed->fed_dirty;
}
/* also incredibly similar to mds_disconnect */
-static int filter_disconnect(struct obd_export *exp, int flags)
+static int filter_disconnect(struct obd_export *exp, unsigned long flags)
{
struct obd_device *obd = exp->exp_obd;
unsigned long irqflags;
/* flush any remaining cancel messages out to the target */
filter_sync_llogs(obd, exp);
-
class_export_put(exp);
RETURN(rc);
}
{
struct dentry *dchild = NULL;
obd_gr group = 0;
+ ENTRY;
if (oa->o_valid & OBD_MD_FLGROUP)
group = oa->o_gr;
- dchild = filter_fid2dentry(obd, NULL, group, oa->o_id);
+ dchild = filter_id2dentry(obd, NULL, group, oa->o_id);
if (IS_ERR(dchild)) {
- CERROR("%s error looking up object: "LPU64"\n", what, oa->o_id);
+ CERROR("%s error looking up object: "LPU64"\n",
+ what, oa->o_id);
RETURN(dchild);
}
if (dchild->d_inode == NULL) {
- CERROR("%s: %s on non-existent object: "LPU64"\n",
- obd->obd_name, what, oa->o_id);
+ CDEBUG(D_INFO, "%s: %s on non-existent object: "
+ LPU64"\n", obd->obd_name, what, oa->o_id);
f_dput(dchild);
RETURN(ERR_PTR(-ENOENT));
}
- return dchild;
+ RETURN(dchild);
}
static int filter_getattr(struct obd_export *exp, struct obdo *oa,
RETURN(rc);
}
-/* this is called from filter_truncate() until we have filter_punch() */
-static int filter_setattr(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md *md, struct obd_trans_info *oti)
+int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry,
+ struct obdo *oa, struct obd_trans_info *oti)
{
- struct lvfs_run_ctxt saved;
struct filter_obd *filter;
- struct dentry *dentry;
struct iattr iattr;
- struct ldlm_res_id res_id = { .name = { oa->o_id, 0, oa->o_gr, 0 } };
- struct ldlm_resource *res;
void *handle;
- int rc, rc2;
+ int rc, err;
ENTRY;
- LASSERT(oti != NULL);
-
- dentry = filter_oa2dentry(exp->exp_obd, oa);
- if (IS_ERR(dentry))
- RETURN(PTR_ERR(dentry));
-
+ LASSERT(dentry != NULL);
+ LASSERT(!IS_ERR(dentry));
+ LASSERT(dentry->d_inode != NULL);
+
filter = &exp->exp_obd->u.filter;
-
iattr_from_obdo(&iattr, oa, oa->o_valid);
- push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
- lock_kernel();
-
if (iattr.ia_valid & ATTR_SIZE)
down(&dentry->d_inode->i_sem);
- handle = fsfilt_start(exp->exp_obd, dentry->d_inode, FSFILT_OP_SETATTR,
- oti);
+ handle = fsfilt_start(exp->exp_obd, dentry->d_inode,
+ FSFILT_OP_SETATTR, oti);
if (IS_ERR(handle))
GOTO(out_unlock, rc = PTR_ERR(handle));
/* XXX this could be a rwsem instead, if filter_preprw played along */
if (iattr.ia_valid & ATTR_ATTR_FLAG)
- rc = fsfilt_iocontrol(exp->exp_obd, dentry->d_inode, NULL,
- EXT3_IOC_SETFLAGS,
+ rc = fsfilt_iocontrol(exp->exp_obd, dentry->d_inode,
+ NULL, EXT3_IOC_SETFLAGS,
(long)&iattr.ia_attr_flags);
else
- rc = fsfilt_setattr(exp->exp_obd, dentry, handle, &iattr, 1);
+ rc = fsfilt_setattr(exp->exp_obd, dentry, handle,
+ &iattr, 1);
+
rc = filter_finish_transno(exp, oti, rc);
- rc2 = fsfilt_commit(exp->exp_obd, filter->fo_sb, dentry->d_inode, handle, 0);
- if (rc2) {
- CERROR("error on commit, err = %d\n", rc2);
+
+ err = fsfilt_commit(exp->exp_obd, filter->fo_sb,
+ dentry->d_inode, handle,
+ exp->exp_sync);
+ if (err) {
+ CERROR("error on commit, err = %d\n", err);
if (!rc)
- rc = rc2;
+ rc = err;
}
+ EXIT;
+out_unlock:
+ if (iattr.ia_valid & ATTR_SIZE)
+ up(&dentry->d_inode->i_sem);
+ return rc;
+}
- if (iattr.ia_valid & ATTR_SIZE) {
- res = ldlm_resource_get(exp->exp_obd->obd_namespace, NULL,
- res_id, LDLM_EXTENT, 0);
- if (res == NULL) {
- CERROR("!!! resource_get failed for object "LPU64" -- "
- "filter_setattr with no lock?\n", oa->o_id);
- } else {
- if (res->lr_namespace->ns_lvbo &&
- res->lr_namespace->ns_lvbo->lvbo_update) {
- rc = res->lr_namespace->ns_lvbo->lvbo_update
- (res, NULL, 0, 0);
- }
- ldlm_resource_putref(res);
- }
- }
+/* this is called from filter_truncate() until we have filter_punch() */
+int filter_setattr(struct obd_export *exp, struct obdo *oa,
+ struct lov_stripe_md *md, struct obd_trans_info *oti)
+{
+ struct ldlm_res_id res_id = { .name = { oa->o_id, 0, oa->o_gr, 0 } };
+ struct ldlm_valblock_ops *ns_lvbo;
+ struct lvfs_run_ctxt saved;
+ struct filter_obd *filter;
+ struct ldlm_resource *res;
+ struct dentry *dentry;
+ int rc;
+ ENTRY;
+
+ LASSERT(oti != NULL);
+
+ filter = &exp->exp_obd->u.filter;
+ push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
+ /* make sure that object is allocated. */
+ dentry = filter_crow_object(exp->exp_obd,
+ oa->o_gr, oa->o_id);
+ if (IS_ERR(dentry))
+ GOTO(out_pop, rc = PTR_ERR(dentry));
+
+ lock_kernel();
+
+ /* setting objects attributes (including owner/group) */
+ rc = filter_setattr_internal(exp, dentry, oa, oti);
+ if (rc)
+ GOTO(out_unlock, rc);
+
+ res = ldlm_resource_get(exp->exp_obd->obd_namespace, NULL,
+ res_id, LDLM_EXTENT, 0);
+
+ if (res != NULL) {
+ ns_lvbo = res->lr_namespace->ns_lvbo;
+ if (ns_lvbo && ns_lvbo->lvbo_update)
+ rc = ns_lvbo->lvbo_update(res, NULL, 0, 0);
+ ldlm_resource_putref(res);
+ }
+
oa->o_valid = OBD_MD_FLID;
obdo_from_inode(oa, dentry->d_inode, FILTER_VALID_FLAGS);
+ EXIT;
out_unlock:
- if (iattr.ia_valid & ATTR_SIZE)
- up(&dentry->d_inode->i_sem);
unlock_kernel();
- pop_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
-
f_dput(dentry);
- RETURN(rc);
+out_pop:
+ pop_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
+ return rc;
}
/* XXX identical to osc_unpackmd */
RETURN(lsm_size);
}
-static void filter_destroy_precreated(struct obd_export *exp, struct obdo *oa,
- struct filter_obd *filter)
+static int filter_statfs(struct obd_device *obd, struct obd_statfs *osfs,
+ unsigned long max_age)
{
- struct obdo doa = { 0, }; /* XXX obdo on stack */
- __u64 last, id;
+ struct filter_obd *filter = &obd->u.filter;
+ int blockbits = filter->fo_sb->s_blocksize_bits;
+ int rc;
ENTRY;
- LASSERT(oa);
- LASSERT(oa->o_valid & OBD_MD_FLGROUP);
- LASSERT(oa->o_gr != 0);
- doa.o_mode = S_IFREG;
- doa.o_gr = oa->o_gr;
- doa.o_valid = oa->o_valid & (OBD_MD_FLGROUP | OBD_MD_FLID);
+ /* at least try to account for cached pages. its still racey and
+ * might be under-reporting if clients haven't announced their
+ * caches with brw recently */
+ spin_lock(&obd->obd_osfs_lock);
+ rc = fsfilt_statfs(obd, filter->fo_sb, max_age);
+ memcpy(osfs, &obd->obd_osfs, sizeof(*osfs));
+ spin_unlock(&obd->obd_osfs_lock);
- set_bit(doa.o_gr, &filter->fo_destroys_in_progress);
- down(&filter->fo_create_locks[doa.o_gr]);
- if (!test_bit(doa.o_gr, &filter->fo_destroys_in_progress)) {
- CERROR("%s:["LPU64"] destroy_in_progress already cleared\n",
- exp->exp_obd->obd_name, doa.o_gr);
- up(&filter->fo_create_locks[doa.o_gr]);
- EXIT;
- return;
+ CDEBUG(D_SUPER | D_CACHE, "blocks cached "LPU64" granted "LPU64
+ " pending "LPU64" free "LPU64" avail "LPU64"\n",
+ filter->fo_tot_dirty, filter->fo_tot_granted,
+ filter->fo_tot_pending,
+ osfs->os_bfree << blockbits, osfs->os_bavail << blockbits);
+
+ filter_grant_sanity_check(obd, __FUNCTION__);
+
+ osfs->os_bavail -= min(osfs->os_bavail,
+ (filter->fo_tot_dirty + filter->fo_tot_pending +
+ osfs->os_bsize -1) >> blockbits);
+
+ RETURN(rc);
+}
+
+int filter_create_object(struct obd_device *obd, struct obdo *oa,
+ obd_gr group)
+{
+ struct dentry *dparent = NULL;
+ struct dentry *dchild = NULL;
+ struct filter_obd *filter;
+ struct obd_statfs *osfs;
+ int cleanup_phase = 0;
+ int err = 0, rc = 0;
+ void *handle = NULL;
+ void *lock = NULL;
+ ENTRY;
+
+ filter = &obd->u.filter;
+
+ OBD_ALLOC(osfs, sizeof(*osfs));
+ if (osfs == NULL)
+ RETURN(-ENOMEM);
+ rc = filter_statfs(obd, osfs, jiffies - HZ);
+ if (rc == 0 && osfs->os_bavail < (osfs->os_blocks >> 10)) {
+ CDEBUG(D_HA, "OST out of space! avail "LPU64"\n",
+ osfs->os_bavail << filter->fo_sb->s_blocksize_bits);
+ rc = -ENOSPC;
}
+ OBD_FREE(osfs, sizeof(*osfs));
+ if (rc)
+ RETURN(rc);
- last = filter_last_id(filter, doa.o_gr);
- CWARN("%s:["LPU64"] deleting orphan objects from "LPU64" to "LPU64"\n",
- exp->exp_obd->obd_name, doa.o_gr, oa->o_id + 1, last);
- for (id = oa->o_id + 1; id <= last; id++) {
- doa.o_id = id;
- filter_destroy(exp, &doa, NULL, NULL);
+ down(&filter->fo_create_locks[group]);
+
+ if (test_bit(group, &filter->fo_destroys_in_progress)) {
+ CWARN("%s: precreate aborted by destroy\n",
+ obd->obd_name);
+ GOTO(out, rc = -EALREADY);
}
- CDEBUG(D_HA, "%s:["LPU64"] after destroy: set last_objids = "LPU64"\n",
- exp->exp_obd->obd_name, doa.o_gr, oa->o_id);
+ CDEBUG(D_INFO, "precreate objid "LPU64"\n", oa->o_id);
- filter_set_last_id(filter, doa.o_gr, oa->o_id);
+ dparent = filter_parent_lock(obd, group, oa->o_id, &lock);
+ if (IS_ERR(dparent))
+ GOTO(cleanup, rc = PTR_ERR(dparent));
+ cleanup_phase = 1;
- clear_bit(doa.o_gr, &filter->fo_destroys_in_progress);
- up(&filter->fo_create_locks[doa.o_gr]);
+ dchild = filter_id2dentry(obd, dparent, group, oa->o_id);
+ if (IS_ERR(dchild))
+ GOTO(cleanup, rc = PTR_ERR(dchild));
+ cleanup_phase = 2;
- EXIT;
-}
+ if (dchild->d_inode != NULL)
+ GOTO(cleanup, rc = 0);
-/* returns a negative error or a nonnegative number of files to create */
-static int filter_should_precreate(struct obd_export *exp, struct obdo *oa,
- obd_gr group)
-{
- struct obd_device *obd = exp->exp_obd;
- struct filter_obd *filter = &obd->u.filter;
- int diff, rc;
- ENTRY;
+ handle = fsfilt_start_log(obd, dparent->d_inode,
+ FSFILT_OP_CREATE, NULL, 1);
+ if (IS_ERR(handle))
+ GOTO(cleanup, rc = PTR_ERR(handle));
+ cleanup_phase = 3;
- diff = oa->o_id - filter_last_id(filter, oa->o_gr);
- CDEBUG(D_INFO, "filter_last_id() = "LPU64" -> diff = %d\n",
- filter_last_id(filter, oa->o_gr), diff);
-
- /* delete orphans request */
- if ((oa->o_valid & OBD_MD_FLFLAGS) &&
- (oa->o_flags & OBD_FL_DELORPHAN)) {
- if (diff >= 0)
- RETURN(diff);
- if (-diff > 10000) { /* XXX make this smarter */
- CERROR("ignoring bogus orphan destroy request: obdid "
- LPU64" last_id "LPU64"\n",
- oa->o_id, filter_last_id(filter, oa->o_gr));
- RETURN(-EINVAL);
- }
- filter_destroy_precreated(exp, oa, filter);
- rc = filter_update_last_objid(obd, group, 0);
- if (rc)
- CERROR("unable to write lastobjid, but orphans"
- "were deleted\n");
- RETURN(0);
- } else {
- /* only precreate if group == 0 and o_id is specfied */
- if (!(oa->o_valid & OBD_FL_DELORPHAN) &&
- (/*group != 0 ||*/ oa->o_id == 0))
- RETURN(1);
+ rc = ll_vfs_create(dparent->d_inode, dchild, S_IFREG, NULL);
+ if (rc) {
+ CERROR("create failed rc = %d\n", rc);
+ GOTO(cleanup, rc);
+ }
+
+ fsfilt_set_fs_flags(obd, dparent->d_inode, SM_DO_REC);
+
+ if (oa->o_id > filter_last_id(filter, group)) {
+ /*
+ * saving last created object id, it will be needed in recovery
+ * for deleting orphanes.
+ */
+ filter_set_last_id(filter, group, oa->o_id);
- LASSERT(diff >= 0);
- RETURN(diff);
+ rc = filter_update_last_objid(obd, group, 0);
+ if (rc) {
+ CERROR("unable to write lastobjid, but "
+ "orphans were deleted, err = %d\n",
+ rc);
+ rc = 0;
+ }
+ }
+cleanup:
+ switch(cleanup_phase) {
+ case 3:
+ err = fsfilt_commit(obd, filter->fo_sb,
+ dparent->d_inode, handle, 0);
+ if (err) {
+ CERROR("error on commit, err = %d\n", err);
+ if (!rc)
+ rc = err;
+ }
+ case 2:
+ f_dput(dchild);
+ case 1:
+ filter_parent_unlock(dparent, lock);
+ case 0:
+ break;
}
-}
-static int filter_precreate_rec(struct obd_device *obd, struct dentry *dentry,
- int *number, struct obdo *oa)
-{
- int rc;
- ENTRY;
- rc = fsfilt_precreate_rec(obd, dentry, number, oa);
+ if (rc)
+ GOTO(out, rc);
+out:
+ up(&filter->fo_create_locks[group]);
RETURN(rc);
}
-/* We rely on the fact that only one thread will be creating files in a given
- * group at a time, which is why we don't need an atomic filter_get_new_id.
- * Even if we had that atomic function, the following race would exist:
- *
- * thread 1: gets id x from filter_next_id
- * thread 2: gets id (x + 1) from filter_next_id
- * thread 2: creates object (x + 1)
- * thread 1: tries to create object x, gets -ENOSPC
- */
-static int filter_precreate(struct obd_device *obd, struct obdo *oa,
- obd_gr group, int *num)
+struct dentry *filter_crow_object(struct obd_device *obd,
+ __u64 ogr, __u64 oid)
{
- struct dentry *dchild = NULL, *dparent = NULL;
- struct filter_obd *filter;
- int err = 0, rc = 0, recreate_obj = 0, i;
- __u64 next_id;
- void *handle = NULL;
- void *lock = NULL;
+ struct dentry *dentry;
+ struct obdo *oa;
+ int rc = 0;
ENTRY;
- filter = &obd->u.filter;
+ /* check if object is already allocated */
+ dentry = filter_id2dentry(obd, NULL, ogr, oid);
+ if (IS_ERR(dentry))
+ RETURN(dentry);
- if ((oa->o_valid & OBD_MD_FLFLAGS) &&
- (oa->o_flags & OBD_FL_RECREATE_OBJS)) {
- recreate_obj = 1;
- }
+ if (dentry->d_inode)
+ RETURN(dentry);
- CDEBUG(D_HA, "%s: precreating %d objects\n", obd->obd_name, *num);
+ f_dput(dentry);
+
+ /* allocate object as it does not exist */
+ oa = obdo_alloc();
+ if (oa == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
- down(&filter->fo_create_locks[group]);
+ oa->o_id = oid;
+ oa->o_gr = ogr;
+ oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
- for (i = 0; i < *num && err == 0; i++) {
- int cleanup_phase = 0;
+ CDEBUG(D_INODE, "OSS object "LPU64"/"LPU64
+ " does not exists - allocate now\n",
+ oid, ogr);
- if (test_bit(group, &filter->fo_destroys_in_progress)) {
- CWARN("%s: precreate aborted by destroy\n",
- obd->obd_name);
- break;
- }
+ rc = filter_create_object(obd, oa, oa->o_gr);
+ if (rc) {
+ CERROR("cannot create OSS object "LPU64"/"LPU64
+ ", err = %d\n", oa->o_id, oa->o_gr, rc);
+ GOTO(out_free_oa, dentry = ERR_PTR(rc));
+ }
- if (recreate_obj) {
- __u64 last_id;
- next_id = oa->o_id;
- last_id = filter_last_id(filter, group);
- if (next_id > last_id) {
- CERROR("Error: Trying to recreate obj greater"
- "than last id "LPD64" > "LPD64"\n",
- next_id, last_id);
- GOTO(cleanup, rc = -EINVAL);
- }
- } else {
- next_id = filter_last_id(filter, group) + 1;
- }
+ /* lookup for just created object and return it to caller */
+ dentry = filter_id2dentry(obd, NULL, ogr, oid);
+ if (IS_ERR(dentry))
+ GOTO(out_free_oa, dentry);
+
+ if (dentry->d_inode == NULL) {
+ f_dput(dentry);
+ dentry = ERR_PTR(-ENOENT);
+ CERROR("cannot find just created OSS object "
+ LPU64"/"LPU64" err = %d\n", oid,
+ ogr, (int)PTR_ERR(dentry));
+ GOTO(out_free_oa, dentry);
+ }
- CDEBUG(D_INFO, "precreate objid "LPU64"\n", next_id);
-
- dparent = filter_parent_lock(obd, group, next_id, &lock);
- if (IS_ERR(dparent))
- GOTO(cleanup, rc = PTR_ERR(dparent));
- cleanup_phase = 1;
-
- /*only do precreate rec record. so clean kml flags here*/
- fsfilt_clear_fs_flags(obd, dparent->d_inode, SM_DO_REC);
-
- dchild = filter_fid2dentry(obd, dparent, group, next_id);
- if (IS_ERR(dchild))
- GOTO(cleanup, rc = PTR_ERR(dchild));
- cleanup_phase = 2;
-
- if (dchild->d_inode != NULL) {
- /* This would only happen if lastobjid was bad on disk*/
- /* Could also happen if recreating missing obj but
- * already exists
- */
- if (recreate_obj) {
- CERROR("%s: Serious error: recreating obj %*s "
- "but obj already exists \n",
- obd->obd_name, dchild->d_name.len,
- dchild->d_name.name);
- LBUG();
- } else {
- CERROR("%s: Serious error: objid %*s already "
- "exists; is this filesystem corrupt?\n",
- obd->obd_name, dchild->d_name.len,
- dchild->d_name.name);
- LBUG();
- }
- GOTO(cleanup, rc = -EEXIST);
- }
+ EXIT;
+out_free_oa:
+ obdo_free(oa);
+ return dentry;
+}
- handle = fsfilt_start_log(obd, dparent->d_inode,
- FSFILT_OP_CREATE, NULL, 1);
- if (IS_ERR(handle))
- GOTO(cleanup, rc = PTR_ERR(handle));
- cleanup_phase = 3;
+static int
+filter_clear_orphans(struct obd_export *exp, struct obdo *oa)
+{
+ struct obd_device *obd = NULL;
+ struct filter_obd *filter;
+ struct obdo *doa = NULL;
+ int rc = 0, orphans;
+ __u64 last, id;
+ ENTRY;
+
+ LASSERT(oa);
+ LASSERT(oa->o_gr != 0);
+ LASSERT(oa->o_valid & OBD_MD_FLGROUP);
- rc = ll_vfs_create(dparent->d_inode, dchild, S_IFREG, NULL);
- if (rc) {
- CERROR("create failed rc = %d\n", rc);
- GOTO(cleanup, rc);
- }
+ obd = exp->exp_obd;
+ filter = &obd->u.filter;
- if (!recreate_obj) {
- filter_set_last_id(filter, group, next_id);
- err = filter_update_last_objid(obd, group, 0);
- if (err)
- CERROR("unable to write lastobjid "
- "but file created\n");
- }
- fsfilt_set_fs_flags(obd, dparent->d_inode, SM_DO_REC);
+ last = filter_last_id(filter, oa->o_gr);
+ orphans = last - oa->o_id;
- cleanup:
- switch(cleanup_phase) {
- case 3:
- err = fsfilt_commit(obd, filter->fo_sb,
- dparent->d_inode, handle, 0);
- if (err) {
- CERROR("error on commit, err = %d\n", err);
- if (!rc)
- rc = err;
- }
- case 2:
- f_dput(dchild);
- case 1:
- filter_parent_unlock(dparent, lock);
- case 0:
- break;
- }
+ if (orphans <= 0)
+ RETURN(0);
+
+ doa = obdo_alloc();
+ if (doa == NULL)
+ RETURN(-ENOMEM);
- if (rc)
- break;
- }
+ doa->o_gr = oa->o_gr;
+ doa->o_mode = S_IFREG;
+ doa->o_valid = oa->o_valid & (OBD_MD_FLGROUP | OBD_MD_FLID);
- *num = i;
+ set_bit(doa->o_gr, &filter->fo_destroys_in_progress);
+ down(&filter->fo_create_locks[doa->o_gr]);
+ if (!test_bit(doa->o_gr, &filter->fo_destroys_in_progress)) {
+ CERROR("%s:["LPU64"] destroy_in_progress already cleared\n",
+ exp->exp_obd->obd_name, doa->o_gr);
+ up(&filter->fo_create_locks[doa->o_gr]);
+ GOTO(out_free_doa, 0);
+ }
- /* check if we have an error after ll_vfs_create(). It is possible that
- * there will be say -ENOSPC and we will leak it. */
- if (rc == 0)
- rc = filter_precreate_rec(obd, dparent, num, oa);
+ CWARN("%s:["LPU64"] deleting orphan objects from "LPU64" to "
+ LPU64"\n", exp->exp_obd->obd_name, doa->o_gr,
+ oa->o_id + 1, last);
+
+ for (id = oa->o_id + 1; id <= last; id++) {
+ doa->o_id = id;
+ filter_destroy(exp, doa, NULL, NULL);
+ }
- up(&filter->fo_create_locks[group]);
+ CDEBUG(D_HA, "%s:["LPU64"] after destroy: set last_objids = "
+ LPU64"\n", exp->exp_obd->obd_name, doa->o_gr, oa->o_id);
- CDEBUG(D_HA, "%s: server last_objid for group "LPU64": "LPU64"\n",
- obd->obd_name, group, filter->fo_last_objids[group]);
+ /* return next free id to be used as a new start of sequence -bzzz */
+ oa->o_id = last + 1;
- CDEBUG(D_HA, "%s: filter_precreate() created %d objects\n",
- obd->obd_name, i);
+ filter_set_last_id(filter, oa->o_gr, oa->o_id);
+ clear_bit(doa->o_gr, &filter->fo_destroys_in_progress);
+ up(&filter->fo_create_locks[oa->o_gr]);
- RETURN(rc);
+ EXIT;
+out_free_doa:
+ obdo_free(doa);
+ return rc;
}
-static int filter_create(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md **ea, struct obd_trans_info *oti)
+/*
+ * by now this function is only needed as entry point for deleting orphanes on
+ * OSS as objects are created on first write attempt. --umka
+ */
+static int
+filter_create(struct obd_export *exp, struct obdo *oa, void *acl,
+ int acl_size, struct lov_stripe_md **ea,
+ struct obd_trans_info *oti)
{
+ struct filter_export_data *fed;
struct obd_device *obd = NULL;
- struct filter_obd *filter;
+ int group = oa->o_gr, rc = 0;
struct lvfs_run_ctxt saved;
- struct lov_stripe_md *lsm = NULL;
- struct filter_export_data *fed;
+ struct filter_obd *filter;
char str[PTL_NALFMT_SIZE];
- int group = oa->o_gr, rc = 0, diff, recreate_objs = 0;
ENTRY;
+ LASSERT(acl == NULL && acl_size == 0);
+
if (!(oa->o_valid & OBD_MD_FLGROUP) || group == 0) {
portals_nid2str(exp->exp_connection->c_peer.peer_ni->pni_number,
exp->exp_connection->c_peer.peer_id.nid, str);
RETURN(-EINVAL);
}
- if ((oa->o_valid & OBD_MD_FLFLAGS) &&
- (oa->o_flags & OBD_FL_RECREATE_OBJS)) {
- recreate_objs = 1;
- }
-
obd = exp->exp_obd;
fed = &exp->exp_filter_data;
filter = &obd->u.filter;
- if (fed->fed_group != group && !recreate_objs &&
- !(oa->o_valid & OBD_MD_REINT)) {
+ if (fed->fed_group != group) {
portals_nid2str(exp->exp_connection->c_peer.peer_ni->pni_number,
exp->exp_connection->c_peer.peer_id.nid, str);
- CERROR("!!! This export (nid "LPX64"/%s) used object group %d "
+ CERROR("!!! this export (nid "LPX64"/%s) used object group %d "
"earlier; now it's trying to use group %d! This could "
"be a bug in the MDS. Tell CFS.\n",
exp->exp_connection->c_peer.peer_id.nid, str,
CDEBUG(D_INFO, "filter_create(od->o_gr=%d,od->o_id="LPU64")\n",
group, oa->o_id);
- if (ea != NULL) {
- lsm = *ea;
- if (lsm == NULL) {
- rc = obd_alloc_memmd(exp, &lsm);
- if (rc < 0)
- RETURN(rc);
- }
- }
obd = exp->exp_obd;
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- if (oa->o_valid & OBD_MD_REINT) {
- int num = *((int*)oa->o_inline);
- rc = filter_precreate(obd, oa, oa->o_gr, &num);
- } else if (recreate_objs) {
- if (oa->o_id > filter_last_id(&obd->u.filter, group)) {
- CERROR("recreate objid "LPU64" > last id "LPU64"\n",
- oa->o_id, filter_last_id(&obd->u.filter, group));
- rc = -EINVAL;
- } else {
- diff = 1;
- rc = filter_precreate(obd, oa, group, &diff);
- }
+ LASSERT((oa->o_valid & OBD_MD_FLFLAGS) &&
+ (oa->o_flags == OBD_FL_DELORPHAN));
+
+ rc = filter_clear_orphans(exp, oa);
+ if (rc) {
+ CERROR("cannot clear orphanes starting from "
+ LPU64", err = %d\n", oa->o_id, rc);
} else {
- diff = filter_should_precreate(exp, oa, group);
- if (diff > 0) {
- oa->o_id = filter_last_id(&obd->u.filter, group);
- rc = filter_precreate(obd, oa, group, &diff);
- oa->o_id += diff;
- oa->o_valid = OBD_MD_FLID;
+ rc = filter_update_last_objid(obd, group, 0);
+ if (rc) {
+ CERROR("unable to write lastobjid, but "
+ "orphans were deleted, err = %d\n",
+ rc);
}
}
-
pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- if (rc && ea != NULL && *ea != lsm) {
- obd_free_memmd(exp, &lsm);
- } else if (rc == 0 && ea != NULL) {
- /* XXX LOV STACKING: the lsm that is passed to us from
- * LOV does not have valid lsm_oinfo data structs, so
- * don't go touching that. This needs to be fixed in a
- * big way. */
- lsm->lsm_object_id = oa->o_id;
- lsm->lsm_object_gr = oa->o_gr;
- *ea = lsm;
- }
-
- RETURN(rc);
+
+ RETURN(0);
}
static int filter_destroy(struct obd_export *exp, struct obdo *oa,
struct lov_stripe_md *ea, struct obd_trans_info *oti)
{
- struct obd_device *obd;
- struct filter_obd *filter;
+ int rc, rc2, cleanup_phase = 0, have_prepared = 0;
struct dentry *dchild = NULL, *dparent = NULL;
+ struct llog_cookie *fcc = NULL;
struct lvfs_run_ctxt saved;
+ struct filter_obd *filter;
+ struct obd_device *obd;
void *handle = NULL;
- struct llog_cookie *fcc = NULL;
- int rc, rc2, cleanup_phase = 0, have_prepared = 0;
void *lock = NULL;
struct iattr iattr;
ENTRY;
GOTO(cleanup, rc = PTR_ERR(dparent));
cleanup_phase = 1;
- dchild = filter_fid2dentry(obd, dparent, oa->o_gr, oa->o_id);
+ dchild = filter_id2dentry(obd, dparent, oa->o_gr, oa->o_id);
if (IS_ERR(dchild))
- GOTO(cleanup, rc = -ENOENT);
+ GOTO(cleanup, rc = PTR_ERR(dchild));
cleanup_phase = 2;
if (dchild->d_inode == NULL) {
switch(cleanup_phase) {
case 3:
if (fcc != NULL) {
- if (oti != NULL)
- fsfilt_add_journal_cb(obd, filter->fo_sb, 0,
- oti->oti_handle,
- filter_cancel_cookies_cb,
- fcc);
- else
- fsfilt_add_journal_cb(obd, filter->fo_sb, 0,
- handle,
- filter_cancel_cookies_cb,
- fcc);
+ fsfilt_add_journal_cb(obd, filter->fo_sb, 0,
+ oti ? oti->oti_handle : handle,
+ filter_cancel_cookies_cb, fcc);
}
rc = filter_finish_transno(exp, oti, rc);
rc2 = fsfilt_commit(obd, filter->fo_sb, dparent->d_inode,
- handle, 0);
+ handle, exp->exp_sync);
if (rc2) {
CERROR("error on commit, err = %d\n", rc2);
if (!rc)
CERROR("PUNCH not supported, only truncate: end = "LPX64"\n",
end);
- CDEBUG(D_INODE, "calling truncate for object "LPU64", valid = %x, "
+ CDEBUG(D_INODE, "calling truncate for object "LPU64", valid = "LPU64", "
"o_size = "LPD64"\n", oa->o_id, oa->o_valid, start);
oa->o_size = start;
error = filter_setattr(exp, oa, NULL, oti);
push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
down(&dentry->d_inode->i_sem);
- rc = filemap_fdatasync(dentry->d_inode->i_mapping);
+ rc = filemap_fdatawrite(dentry->d_inode->i_mapping);
if (rc == 0) {
/* just any file to grab fsync method - "file" arg unused */
struct file *file = filter->fo_rcvd_filp;
RETURN(rc);
}
-static int filter_statfs(struct obd_device *obd, struct obd_statfs *osfs,
- unsigned long max_age)
-{
- struct filter_obd *filter = &obd->u.filter;
- int blockbits = filter->fo_sb->s_blocksize_bits;
- int rc;
- ENTRY;
-
- /* at least try to account for cached pages. its still racey and
- * might be under-reporting if clients haven't announced their
- * caches with brw recently */
- spin_lock(&obd->obd_osfs_lock);
- rc = fsfilt_statfs(obd, filter->fo_sb, max_age);
- memcpy(osfs, &obd->obd_osfs, sizeof(*osfs));
- spin_unlock(&obd->obd_osfs_lock);
-
- CDEBUG(D_SUPER | D_CACHE, "blocks cached "LPU64" granted "LPU64
- " pending "LPU64" free "LPU64" avail "LPU64"\n",
- filter->fo_tot_dirty, filter->fo_tot_granted,
- filter->fo_tot_pending,
- osfs->os_bfree << blockbits, osfs->os_bavail << blockbits);
-
- filter_grant_sanity_check(obd, __FUNCTION__);
-
- osfs->os_bavail -= min(osfs->os_bavail,
- (filter->fo_tot_dirty + filter->fo_tot_pending +
- osfs->os_bsize -1) >> blockbits);
-
- RETURN(rc);
-}
-
static int filter_get_info(struct obd_export *exp, __u32 keylen,
void *key, __u32 *vallen, void *val)
{
LASSERT(handle);
(void)fsfilt_commit(obd, sb, inode, handle, 1);
- dev_set_rdonly(ll_sbdev(obd->u.filter.fo_sb), 2);
+ ll_set_rdonly(ll_sbdev(obd->u.filter.fo_sb));
RETURN(0);
}
RETURN(rc);
}
-static struct dentry *filter_lvfs_fid2dentry(__u64 id, __u32 gen, __u64 gr,
- void *data)
+static struct dentry *filter_lvfs_id2dentry(__u64 id, __u32 gen,
+ __u64 gr, void *data)
{
- return filter_fid2dentry(data, NULL, gr, id);
+ return filter_id2dentry(data, NULL, gr, id);
}
static struct lvfs_callback_ops filter_lvfs_ops = {
- l_fid2dentry: filter_lvfs_fid2dentry,
+ l_id2dentry: filter_lvfs_id2dentry,
};
static struct obd_ops filter_obd_ops = {
.o_setup = filter_setup,
.o_precleanup = filter_precleanup,
.o_cleanup = filter_cleanup,
+ .o_process_config = filter_process_config,
.o_connect = filter_connect,
.o_connect_post = filter_connect_post,
.o_disconnect = filter_disconnect,
static int __init obdfilter_init(void)
{
struct lprocfs_static_vars lvars;
- int rc;
+ int size, rc;
printk(KERN_INFO "Lustre: Filtering OBD driver; info@clusterfs.com\n");
lprocfs_init_vars(filter, &lvars);
+ size = OBDFILTER_CREATED_SCRATCHPAD_ENTRIES *
+ sizeof(*obdfilter_created_scratchpad);
+
+ OBD_ALLOC(obdfilter_created_scratchpad, size);
+ if (obdfilter_created_scratchpad == NULL) {
+ CERROR ("Can't allocate scratchpad\n");
+ return -ENOMEM;
+ }
+
rc = class_register_type(&filter_obd_ops, NULL, lvars.module_vars,
OBD_FILTER_DEVICENAME);
- if (rc)
+ if (rc) {
+ OBD_FREE(obdfilter_created_scratchpad, size);
return rc;
+ }
rc = class_register_type(&filter_sanobd_ops, NULL, lvars.module_vars,
OBD_FILTER_SAN_DEVICENAME);
- if (rc)
+ if (rc) {
class_unregister_type(OBD_FILTER_DEVICENAME);
+ OBD_FREE(obdfilter_created_scratchpad, size);
+ }
return rc;
}
{
class_unregister_type(OBD_FILTER_SAN_DEVICENAME);
class_unregister_type(OBD_FILTER_DEVICENAME);
+ OBD_FREE(obdfilter_created_scratchpad,
+ OBDFILTER_CREATED_SCRATCHPAD_ENTRIES *
+ sizeof(*obdfilter_created_scratchpad));
}
MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");