struct scan_dir_data {
int rc;
- struct lustre_id *id;
+ __u32 i_num;
+ __u8 cross_ref;
char *name;
};
LASSERT(sd != NULL);
- if (ino == id_ino(sd->id)) {
+ /* skip non-cross_ref entries if we need cross-ref */
+ if (sd->cross_ref && !(d_type & 128))
+ RETURN(0);
+
+ if (ino == sd->i_num) {
strncpy(sd->name, name, namlen);
sd->rc = 0;
RETURN(-EINTR); /* break the readdir loop */
RETURN(0);
}
-int
-scan_name_in_parent(struct lustre_id *pid, struct lustre_id *id, char *name)
+static int scan_name_in_parent(struct lustre_id *pid, struct lustre_id *id,
+ char *name, int cr)
{
struct file * file;
char *pname;
GOTO(out, rc = PTR_ERR(file));
}
- sd.id = id;
+ sd.i_num = id_ino(id);
sd.name = name;
+ sd.cross_ref = cr;
sd.rc = -ENOENT;
- vfs_readdir(file, filldir, &sd);
+ rc = vfs_readdir(file, filldir, &sd);
+ if (!rc)
+ rc = sd.rc;
filp_close(file, 0);
- rc = sd.rc;
out:
OBD_FREE(pname, len);
}
inode = dentry->d_inode;
- if (S_ISDIR(id_type(id))) {
- LASSERT(S_ISDIR(inode->i_mode));
+ if (S_ISDIR(inode->i_mode)) {
+ //LASSERT(S_ISDIR(id_type(id)));
rc = mds_md_get_attr(obd, inode, &mea, &mea_size);
if (rc)
GOTO(out, rc);
} else {
*type = PP_SPLIT_SLAVE;
*pid = mea->mea_ids[mea->mea_master];
+ LASSERT(id_fid(pid));
}
} else {
- LASSERT(!S_ISDIR(inode->i_mode));
+ //LASSERT(!S_ISDIR(id_type(id)));
*type = PP_FILE;
read_pid:
rc = mds_read_inode_pid(obd, inode, pid);
static int local_parse_id(struct obd_device *obd, struct parseid_pkg *pkg)
{
struct lvfs_run_ctxt saved;
- int rc = 0;
+ int rc = 0, cross_ref = 0;
ENTRY;
pkg->pp_rc = 0;
pkg->pp_type = 0;
memset(pkg->pp_name, 0, sizeof(pkg->pp_name));
- LASSERT(obd->u.mds.mds_num == id_group(&pkg->pp_id1));
-
/* pp_id2 is present, which indicating we want to scan parent
* dir(pp_id2) to find the cross-ref entry(pp_id1) */
if (id_fid(&pkg->pp_id2)) {
- LASSERT(S_ISDIR(id_type(&pkg->pp_id1)));
- LASSERT(S_ISDIR(id_type(&pkg->pp_id2)));
-
+ LASSERT(obd->u.mds.mds_num == id_group(&pkg->pp_id2));
pkg->pp_type = PP_DIR;
- goto scan;
+ cross_ref = 1;
+ } else {
+ LASSERT(obd->u.mds.mds_num == id_group(&pkg->pp_id1));
+ rc = id2pid(obd, &pkg->pp_id1, &pkg->pp_id2, &pkg->pp_type);
+ if (rc)
+ GOTO(out, rc);
}
- rc = id2pid(obd, &pkg->pp_id1, &pkg->pp_id2, &pkg->pp_type);
- if (rc)
- GOTO(out, rc);
-scan:
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
switch (pkg->pp_type) {
case PP_DIR:
case PP_SPLIT_MASTER:
rc = scan_name_in_parent(&pkg->pp_id2, &pkg->pp_id1,
- pkg->pp_name);
+ pkg->pp_name, cross_ref);
if (rc)
CERROR("scan "LPU64" in parent failed. rc=%d\n",
id_ino(&pkg->pp_id1), rc);
int mds_num = id_group(&pkg->pp_id1);
ENTRY;
+ //for cross-ref dir we should send request to parent's MDS
+ if (pkg->pp_type == PP_CROSS_DIR)
+ mds_num = id_group(&pkg->pp_id2);
+
LASSERT(mds_num >= 0);
if (mds_num == obd->u.mds.mds_num) {
struct lmv_obd *lmv = &obd->u.mds.mds_md_obd->u.lmv;
struct parseid_pkg *body;
int size = sizeof(*body);
- struct obd_export *exp = lmv->tgts[mds_num].ltd_exp;
+ struct obd_export *exp;
+ /* make sure connection established */
+ rc = obd_set_info(obd->u.mds.mds_md_exp, strlen("chkconnect"),
+ "chkconnect", 0, NULL);
+ if (rc)
+ RETURN(rc);
+
+ exp = lmv->tgts[mds_num].ltd_exp;
+ LASSERTF(exp, "No export for MDS #%i\n", mds_num);
+
req = ptlrpc_prep_req(class_exp2cliimp(exp),
LUSTRE_MDS_VERSION, MDS_PARSE_ID, 1,
&size, NULL);
INIT_LIST_HEAD(&item->link);
list_add(&item->link, list);
memcpy(item->name, pkg->pp_name, sizeof(item->name));
-
+
case PP_SPLIT_SLAVE:
pkg->pp_id1 = pkg->pp_id2;
memset(&pkg->pp_id2, 0, sizeof(struct lustre_id));
- break;
case PP_CROSS_DIR:
break;
default:
- LBUG();
+ CERROR("Wrong id = %i\n", pkg->pp_type);
break;
}
CERROR("log is not plain\n");
RETURN(-EINVAL);
}
- if (rec->lrh_type != SMFS_AUDIT_NAME_REC &&
- rec->lrh_type != LLOG_GEN_REC) {
+
+ if (rec->lrh_type != SMFS_AUDIT_NAME_REC)
RETURN(0);
- }
-
- ad_rec = (struct audit_record *)((char *)rec + sizeof(*rec));
-
- if (ad_rec->result ||
- ad_rec->opcode != AUDIT_UNLINK ||
- ad_rec->opcode != AUDIT_RENAME)
+
+ ad_rec = (struct audit_record *)(rec + 1);
+ if (ad_rec->result ||
+ (ad_rec->opcode != AUDIT_UNLINK &&
+ ad_rec->opcode != AUDIT_RENAME))
RETURN(0);
- cid_rec = (struct audit_id_record *)((char *)ad_rec + sizeof(*ad_rec));
+ cid_rec = (struct audit_id_record *)(ad_rec + 1);
pid_rec = cid_rec + 1;
- nm_rec = (struct audit_name_record *)
- ((char *)pid_rec + sizeof(*pid_rec));
-
+ nm_rec = (struct audit_name_record *)(pid_rec + 1);
+
if (cid_rec->au_num == id_ino(&pkg->pp_id1) &&
cid_rec->au_gen == id_gen(&pkg->pp_id1)) {
+ LASSERT(pid_rec->au_fid);
/* get parent id */
id_ino(&pkg->pp_id2) = pid_rec->au_num;
id_gen(&pkg->pp_id2) = pid_rec->au_gen;
/* get name */
memcpy(pkg->pp_name, nm_rec->name,
le32_to_cpu(nm_rec->name_len));
-
RETURN(LLOG_PROC_BREAK);
}
RETURN(0);
int rc = 0;
ENTRY;
+ pkg->pp_rc = 0;
if (ctxt)
llh = ctxt->loc_handle;
if (llh == NULL)
- RETURN(-ENOENT);
+ GOTO(out, rc = -ENOENT);
rc = llog_cat_process(llh, (llog_cb_t)&scan_audit_log_cb, (void *)pkg);
if (rc != LLOG_PROC_BREAK) {
CWARN("process catalog log failed: rc(%d)\n", rc);
- RETURN(-ENOENT);
+ rc = -ENOENT;
+ } else {
+ rc = 0;
}
- RETURN(0);
+out:
+ pkg->pp_rc = rc;
+ RETURN(rc);
}
static int
struct lmv_obd *lmv = &obd->u.mds.mds_md_obd->u.lmv;
struct parseid_pkg *body;
int size = sizeof(*body);
- struct obd_export *exp = lmv->tgts[mds_num].ltd_exp;
+ struct obd_export *exp;
+ /* make sure connection established */
+ rc = obd_set_info(obd->u.mds.mds_md_exp, strlen("chkconnect"),
+ "chkconnect", 0, NULL);
+ if (rc)
+ RETURN(rc);
+
+ exp = lmv->tgts[mds_num].ltd_exp;
+ LASSERTF(exp, "No export for MDS #%i\n", mds_num);
+
req = ptlrpc_prep_req(class_exp2cliimp(exp),
LUSTRE_MDS_VERSION, MDS_PARSE_ID, 1,
&size, NULL);
INIT_LIST_HEAD(&list);
cur_id = *id;
+ if (!id_ino(&cur_id)) {
+ CERROR("Invalid id!\n");
+ RETURN(-EINVAL);
+ }
if (id_fid(&cur_id) == ROOT_FID)
RETURN(0);
+
next:
memset(&parent_id, 0, sizeof(parent_id));
-
rc = mds_id2name(obd, &cur_id, &list, &parent_id);
if (rc == -ENOENT) {
/* can't reconstruct name from id, turn to audit log */
- LASSERT(id_fid(&parent_id));
cur_id = parent_id;
memset(&parent_id, 0, sizeof(parent_id));
item = list_entry(pos, struct name_item, link);
*namelen += strlen(item->name) + 1;
}
+
+ (*namelen)++; /* for the ending '\0' of string */
OBD_ALLOC(*name, *namelen);
if (*name == NULL)
rc = -ENOMEM;
out:
list_for_each_safe (pos, n, &list) {
item = list_entry(pos, struct name_item, link);
+
if (!rc) {
strcat(*name, "/");
strcat(*name, item->name);
}
list_del_init(&item->link);
OBD_FREE(item, sizeof(*item));
+ if (*name)
+ LASSERT(strlen(*name) < *namelen);
}
RETURN(rc);
}