RETURN(rc);
}
-static int cml_open(const struct lu_context *ctx, struct md_object *mo)
+static int cml_open(const struct lu_context *ctx, struct md_object *mo,
+ int flags)
{
int rc;
ENTRY;
- rc = mo_open(ctx, md_object_next(mo));
+ rc = mo_open(ctx, md_object_next(mo), flags);
RETURN(rc);
}
RETURN(-EFAULT);
}
-static int cmr_open(const struct lu_context *ctx, struct md_object *mo)
+static int cmr_open(const struct lu_context *ctx, struct md_object *mo,
+ int flags)
{
RETURN(-EREMOTE);
}
int (*moo_ref_add)(const struct lu_context *, struct md_object *);
int (*moo_ref_del)(const struct lu_context *, struct md_object *,
struct md_attr *);
- int (*moo_open)(const struct lu_context *, struct md_object *);
+ int (*moo_open)(const struct lu_context *, struct md_object *, int flags);
int (*moo_close)(const struct lu_context *, struct md_object *,
struct md_attr *);
};
return m->mo_ops->moo_xattr_list(cx, m, buf, buf_len);
}
-static inline int mo_open(const struct lu_context *cx, struct md_object *m)
+static inline int mo_open(const struct lu_context *cx, struct md_object *m,
+ int flags)
{
LASSERT(m->mo_ops->moo_open);
- return m->mo_ops->moo_open(cx, m);
+ return m->mo_ops->moo_open(cx, m, flags);
}
static inline int mo_close(const struct lu_context *cx, struct md_object *m,
RETURN(rc);
}
-static int mdd_open(const struct lu_context *ctxt, struct md_object *obj)
+/* do NOT or the MAY_*'s, you'll get the weakest */
+static int accmode(struct mdd_object *mdd_obj, int flags)
{
- /*XXX access mod checking*/
+ int res = 0;
+
+#if 0
+ /* Sadly, NFSD reopens a file repeatedly during operation, so the
+ * "acc_mode = 0" allowance for newly-created files isn't honoured.
+ * NFSD uses the MDS_OPEN_OWNEROVERRIDE flag to say that a file
+ * owner can write to a file even if it is marked readonly to hide
+ * its brokenness. (bug 5781) */
+ if (flags & MDS_OPEN_OWNEROVERRIDE && inode->i_uid == current->fsuid)
+ return 0;
+#endif
+ if (flags & FMODE_READ)
+ res = MAY_READ;
+ if (flags & (FMODE_WRITE|MDS_OPEN_TRUNC))
+ res |= MAY_WRITE;
+ if (flags & MDS_FMODE_EXEC)
+ res = MAY_EXEC;
+ return res;
+}
+
+static int mdd_open(const struct lu_context *ctxt, struct md_object *obj,
+ int flags)
+{
+ int mode = accmode(md2mdd_obj(obj), flags);
+
+ if (mode & MAY_WRITE) {
+ if (mdd_is_immutable(md2mdd_obj(obj)))
+ RETURN(-EACCES);
+ }
+
atomic_inc(&md2mdd_obj(obj)->mod_count);
return 0;
}
CDEBUG(D_INODE, "last_transno = %llu, last_committed = %llu\n",
mdt->mdt_last_transno, exp->exp_obd->obd_last_committed);
- spin_lock(mdt->mdt_transno_lock);
+ spin_lock(&mdt->mdt_transno_lock);
req->rq_repmsg->transno = req->rq_transno = info->mti_transno;
req->rq_repmsg->last_committed = exp->exp_obd->obd_last_committed;
- spin_unlock(mdt->mdt_transno_lock);
+ spin_unlock(&mdt->mdt_transno_lock);
req->rq_repmsg->last_xid = req->rq_xid;
}
.o_init_export = mdt_init_export, /* By Huang Hua*/
.o_destroy_export = mdt_destroy_export, /* By Huang Hua*/
};
-
-static void mdt_device_fini(const struct lu_context *ctx, struct lu_device *d)
+
+static struct lu_device* mdt_device_fini(const struct lu_context *ctx, struct lu_device *d)
{
struct mdt_device *m = mdt_dev(d);
mdt_fini(ctx, m);
+ RETURN (md2lu_dev(m->mdt_child));
}
static void mdt_device_free(const struct lu_context *ctx, struct lu_device *d)
if (rc)
RETURN(rc);
+ rc = mo_open(info->mti_ctxt, mdt_object_child(o), flags);
+ if (rc)
+ RETURN(rc);
+
/* (1) client wants transno when open to keep a ref count for replay;
* see after_reply() and mdc_close_commit();
* (2) we need to record the transaction related stuff onto disk;
* and is released by mdt_mfd_close() */
mdt_object_get(info->mti_ctxt, o);
/* open hanling */
- mo_open(info->mti_ctxt, mdt_object_child(o));
mfd->mfd_mode = flags;
mfd->mfd_object = o;