/* lustre_capa.lc_opc */
enum {
- CAPA_OPC_BODY_WRITE = 1<<0, /* write fid data */
- CAPA_OPC_BODY_READ = 1<<1, /* read fid data */
- CAPA_OPC_INDEX_LOOKUP = 1<<2, /* lookup fid */
- CAPA_OPC_INDEX_INSERT = 1<<3, /* insert fid */
- CAPA_OPC_INDEX_DELETE = 1<<4, /* delete fid */
+ CAPA_OPC_BODY_WRITE = 1<<0, /* write object data */
+ CAPA_OPC_BODY_READ = 1<<1, /* read object data */
+ CAPA_OPC_INDEX_LOOKUP = 1<<2, /* lookup object fid */
+ CAPA_OPC_INDEX_INSERT = 1<<3, /* insert object fid */
+ CAPA_OPC_INDEX_DELETE = 1<<4, /* delete object fid */
CAPA_OPC_OSS_WRITE = 1<<5, /* write oss object data */
CAPA_OPC_OSS_READ = 1<<6, /* read oss object data */
CAPA_OPC_OSS_TRUNC = 1<<7, /* truncate oss object */
- CAPA_OPC_META_WRITE = 1<<8, /* write fid meta data */
- CAPA_OPC_META_READ = 1<<9, /* read fid meta data */
+ CAPA_OPC_META_WRITE = 1<<8, /* write object meta data */
+ CAPA_OPC_META_READ = 1<<9, /* read object meta data */
};
+#define CAPA_OPC_OSS_RW (CAPA_OPC_OSS_READ | CAPA_OPC_OSS_WRITE)
#define CAPA_OPC_MDS_ONLY \
(CAPA_OPC_BODY_WRITE | CAPA_OPC_BODY_READ | CAPA_OPC_INDEX_LOOKUP | \
CAPA_OPC_INDEX_INSERT | CAPA_OPC_INDEX_DELETE)
#define CAPA_OPC_MDS_DEFAULT ~CAPA_OPC_OSS_ONLY
#define CAPA_OPC_OSS_DEFAULT ~(CAPA_OPC_MDS_ONLY | CAPA_OPC_OSS_ONLY)
+/* MDS capability covers object capability for operations of body r/w
+ * (dir readpage/sendpage), index lookup/insert/delete and meta data r/w,
+ * while OSS capability only covers object capability for operations of
+ * oss data(file content) r/w/truncate.
+ */
static inline int capa_for_mds(struct lustre_capa *c)
{
return (c->lc_opc & CAPA_OPC_INDEX_LOOKUP) != 0;
enum {
OBD_CAPA_FL_NEW = 1,
OBD_CAPA_FL_EXPIRED = 1<<1,
- OBD_CAPA_FL_ROOT = 1<<2,
};
static inline __u64 capa_opc(struct lustre_capa *capa)
oc->c_flags &= ~OBD_CAPA_FL_EXPIRED;
}
-static inline int obd_capa_is_root(struct obd_capa *oc)
-{
- return !!((oc)->c_flags & OBD_CAPA_FL_ROOT);
-}
-
-static inline void obd_capa_set_root(struct obd_capa *oc)
-{
- oc->c_flags |= OBD_CAPA_FL_ROOT;
-}
-
static inline struct obd_capa *alloc_capa(int site)
{
#ifdef __KERNEL__
if (data && lsm) {
struct obdo *oa = obdo_alloc();
- struct obd_capa *ocapa;
if (!oa)
RETURN(rc ? rc : -ENOMEM);
OBD_MD_FLMTIME | OBD_MD_FLCTIME |
OBD_MD_FLGROUP);
- ocapa = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
+ oc = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
err = obd_sync(ll_i2sbi(inode)->ll_dt_exp, oa, lsm,
- 0, OBD_OBJECT_EOF, ocapa);
- capa_put(ocapa);
+ 0, OBD_OBJECT_EOF, oc);
+ capa_put(oc);
if (!rc)
rc = err;
obdo_free(oa);
static struct list_head *ll_capa_list = &capa_list[CAPA_SITE_CLIENT];
/* llite capa renewal timer */
-cfs_timer_t ll_capa_timer;
+struct timer_list ll_capa_timer;
/* for debug: indicate whether capa on llite is enabled or not */
static atomic_t ll_capa_debug = ATOMIC_INIT(0);
static inline void update_capa_timer(struct obd_capa *ocapa, cfs_time_t expiry)
{
- if (cfs_time_before(expiry, cfs_timer_deadline(&ll_capa_timer)) ||
- !cfs_timer_is_armed(&ll_capa_timer)) {
- cfs_timer_arm(&ll_capa_timer, expiry);
+ if (time_before(expiry, ll_capa_timer.expires) ||
+ !timer_pending(&ll_capa_timer)) {
+ mod_timer(&ll_capa_timer, expiry);
DEBUG_CAPA(D_SEC, &ocapa->c_capa,
- "ll_capa_timer update: %lu/%lu by",
- expiry, jiffies);
+ "ll_capa_timer update: %lu/%lu by", expiry, jiffies);
}
}
break;
}
+ /* for MDS capability, only renew those which belong to
+ * dir, or its inode is opened, or client holds LOOKUP
+ * lock.
+ */
if (capa_for_mds(&ocapa->c_capa) &&
!S_ISDIR(ocapa->u.cli.inode->i_mode) &&
obd_capa_open_count(ocapa) == 0 &&
- !obd_capa_is_root(ocapa) &&
!ll_have_md_lock(ocapa->u.cli.inode,
MDS_INODELOCK_LOOKUP)) {
- /* MDS capa without LOOKUP lock, and the related
- * inode is not opened, it won't renew,
- * move to idle list (except root fid) */
DEBUG_CAPA(D_SEC, &ocapa->c_capa,
"skip renewal for");
list_del_init(&ocapa->c_list);
continue;
}
+ /* for OSS capability, only renew those whose inode is
+ * opened.
+ */
if (capa_for_oss(&ocapa->c_capa) &&
obd_capa_open_count(ocapa) == 0) {
/* oss capa with open count == 0 won't renew,
return NULL;
ENTRY;
- LASSERT(opc == CAPA_OPC_OSS_WRITE ||
- opc == (CAPA_OPC_OSS_WRITE | CAPA_OPC_OSS_READ) ||
+ LASSERT(opc == CAPA_OPC_OSS_WRITE || opc == CAPA_OPC_OSS_RW ||
opc == CAPA_OPC_OSS_TRUNC);
spin_lock(&capa_lock);
spin_unlock(&ocapa->c_lock);
spin_lock(&capa_lock);
- if (capa->lc_opc & (CAPA_OPC_OSS_READ | CAPA_OPC_OSS_WRITE))
+ if (capa->lc_opc & CAPA_OPC_OSS_RW)
inode_add_oss_capa(inode, ocapa);
DEBUG_CAPA(D_SEC, capa, "renew");
RETURN(rc);
}
-static int client_common_fill_super(struct super_block *sb,
- char *md, char *dt,
- int mdt_pag,
- uid_t nllu, gid_t nllg)
+static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
+ int mdt_pag, uid_t nllu, gid_t nllg)
{
struct inode *root = 0;
struct ll_sb_info *sbi = ll_s2sbi(sb);
GOTO(out_dt, err);
}
- if (lmd.mds_capa)
- obd_capa_set_root(lmd.mds_capa);
LASSERT(fid_is_sane(&sbi->ll_root_fid));
root = ll_iget(sb, ll_fid_build_ino(sbi, &sbi->ll_root_fid), &lmd);
ptlrpc_req_finished(request);
return NULL;
ll_i2gids(op_data->suppgids, i1, i2);
- op_data->fid1 = ll_i2info(i1)->lli_fid;
+ op_data->fid1 = *ll_inode2fid(i1);
op_data->mod_capa1 = ll_mdscapa_get(i1);
/* @i2 may be NULL. In this case caller itself has to initialize ->fid2
int mode)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
- struct obd_capa *ocapa = NULL;
+ struct obd_capa *oc = NULL;
struct ptlrpc_request *req = NULL;
struct inode *inode = NULL;
unsigned long valid = 0;
}
if (capa) {
- ocapa = alloc_capa(CAPA_SITE_CLIENT);
- if (!ocapa)
+ oc = alloc_capa(CAPA_SITE_CLIENT);
+ if (!oc)
return ERR_PTR(-ENOMEM);
- ocapa->c_capa = *capa;
+ oc->c_capa = *capa;
}
- rc = md_getattr(sbi->ll_md_exp, fid, (struct obd_capa *)ocapa,
- valid, eadatalen, &req);
- free_capa(ocapa);
+ rc = md_getattr(sbi->ll_md_exp, fid, oc, valid, eadatalen, &req);
+ if (oc)
+ free_capa(oc);
if (rc) {
CERROR("can't get object attrs, fid "DFID", rc %d\n",
PFID(fid), rc);
fid = (struct lu_fid *)p;
capa = (struct lustre_capa *)(p + sizeof(*fid));
- return ll_iget_for_nfs(sb, fid, (capa->lc_opc == 0) ? capa : NULL,
+ return ll_iget_for_nfs(sb, fid, (capa->lc_opc != 0) ? capa : NULL,
S_IFREG);
}
oinfo.oi_oa = oa;
oinfo.oi_md = lsm;
/* NB partial write, so we might not have CAPA_OPC_OSS_READ capa */
- opc = cmd & OBD_BRW_WRITE ? CAPA_OPC_OSS_WRITE :
- CAPA_OPC_OSS_WRITE | CAPA_OPC_OSS_READ;
+ opc = cmd & OBD_BRW_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_RW;
oinfo.oi_capa = ll_osscapa_get(inode, opc);
rc = obd_brw(cmd, ll_i2dtexp(inode), &oinfo, 1, &pg, NULL);
capa_put(oinfo.oi_capa);
static struct obd_capa *ll_ap_lookup_capa(void *data, int cmd)
{
struct ll_async_page *llap = LLAP_FROM_COOKIE(data);
- int opc = cmd & OBD_BRW_WRITE ? CAPA_OPC_OSS_WRITE :
- CAPA_OPC_OSS_WRITE | CAPA_OPC_OSS_READ;
+ int opc = cmd & OBD_BRW_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_RW;
return ll_osscapa_get(llap->llap_page->mapping->host, opc);
}
} else {
lprocfs_counter_add(ll_i2sbi(inode)->ll_stats,
LPROC_LL_DIRECT_READ, size);
- opc = CAPA_OPC_OSS_READ | CAPA_OPC_OSS_WRITE;
+ opc = CAPA_OPC_OSS_RW;
}
ocapa = ll_osscapa_get(inode, opc);
rc = obd_brw_rqset(rw == WRITE ? OBD_BRW_WRITE : OBD_BRW_READ,
int size[5] = { sizeof(struct ptlrpc_body),
sizeof(*body),
ea_size,
- acl_size };
+ acl_size,
+ sizeof(struct lustre_capa) };
int offset, rc;
ENTRY;
ea_size);
if (acl_size)
CDEBUG(D_INODE, "reserved %u bytes for ACL\n", acl_size);
- size[REPLY_REC_OFF + 2] = mdscapa ? sizeof(struct lustre_capa) : 0;
ptlrpc_req_set_repsize(req, 5, size);
#endif
if ((reqbody->valid & OBD_MD_FLMDSCAPA) &&
- info->mti_mdt->mdt_opts.mo_mds_capa) {
+ info->mti_mdt->mdt_opts.mo_mds_capa) {
struct lustre_capa *capa;
capa = req_capsule_server_get(&info->mti_pill, &RMF_CAPA1);
return rc;
if (val < 0 || val > 3) {
- CERROR("invalid capability mode, only 0/1/2/3 is accepted.\n"
+ CERROR("invalid capability mode, only 0/2/3 is accepted.\n"
" 0: disable fid capability\n"
- " 1: enable OSS fid capability\n"
" 2: enable MDS fid capability\n"
" 3: enable both MDS and OSS fid capability\n");
return -EINVAL;
/* OSS fid capability needs enable both MDS and OSS fid capability on
* MDS */
- if (val == 1)
- val = 3;
+ if (val == 1) {
+ CERROR("can't enable OSS fid capability only, you should use "
+ "'3' to enable both MDS and OSS fid capability.\n");
+ return -EINVAL;
+ }
mdt->mdt_opts.mo_oss_capa = (val & 0x1);
mdt->mdt_opts.mo_mds_capa = !!(val & 0x2);
mdt_pack_attr2body(info, repbody, &ma->ma_attr, mdt_object_fid(mo));
if (mdt->mdt_opts.mo_oss_capa &&
- S_ISREG(lu_object_attr(&mo->mot_obj.mo_lu))) {
- /* FIXME: only sent truncate capability back in size change
- * case */
+ S_ISREG(lu_object_attr(&mo->mot_obj.mo_lu)) &&
+ (ma->ma_attr.la_valid & LA_SIZE)) {
struct lustre_capa *capa;
capa = req_capsule_server_get(&info->mti_pill, &RMF_CAPA1);
capa->lc_opc = CAPA_OPC_OSS_DEFAULT | CAPA_OPC_OSS_TRUNC;
rc = mo_capa_get(info->mti_env, mdt_object_child(mo), capa, 0);
if (rc)
- RETURN(rc);
+ GOTO(out, rc);
repbody->valid |= OBD_MD_FLOSSCAPA;
}
.length = offsetof(struct lustre_capa, lc_hmac),
};
- if (capa_alg(capa) != CAPA_HMAC_ALG_SHA1)
- RETURN(-EFAULT);
+ if (capa_alg(capa) != CAPA_HMAC_ALG_SHA1) {
+ CERROR("unknown capability hmac algorithm!\n");
+ return -EFAULT;
+ }
alg = &capa_hmac_algs[capa_alg(capa)];
#warning "enable fid check in filter_verify_capa when fid ready"
if (opc == CAPA_OPC_OSS_READ) {
- if (!(capa->lc_opc & (CAPA_OPC_OSS_READ | CAPA_OPC_OSS_WRITE)))
+ if (!(capa->lc_opc & CAPA_OPC_OSS_RW))
rc = -EACCES;
} else if (!capa_opc_supported(capa, opc)) {
rc = -EACCES;