浏览代码

ceph: define struct for dir entry in readdir reply

This avoids defining multiple arrays for entries in readdir reply

Signed-off-by: Yan, Zheng <zyan@redhat.com>
Yan, Zheng 9 年之前
父节点
当前提交
2a5beea3f1
共有 4 个文件被更改,包括 50 次插入52 次删除
  1. 12 15
      fs/ceph/dir.c
  2. 11 10
      fs/ceph/inode.c
  3. 19 23
      fs/ceph/mds_client.c
  4. 8 4
      fs/ceph/mds_client.h

+ 12 - 15
fs/ceph/dir.c

@@ -416,9 +416,9 @@ more:
 			fi->last_name = NULL;
 			fi->last_name = NULL;
 			fi->next_offset = 2;
 			fi->next_offset = 2;
 		} else {
 		} else {
-			err = note_last_dentry(fi,
-				       rinfo->dir_dname[rinfo->dir_nr-1],
-				       rinfo->dir_dname_len[rinfo->dir_nr-1],
+			struct ceph_mds_reply_dir_entry *rde =
+					rinfo->dir_entries + (rinfo->dir_nr-1);
+			err = note_last_dentry(fi, rde->name, rde->name_len,
 				       fi->next_offset + rinfo->dir_nr);
 				       fi->next_offset + rinfo->dir_nr);
 			if (err)
 			if (err)
 				return err;
 				return err;
@@ -431,24 +431,21 @@ more:
 
 
 	ctx->pos = ceph_make_fpos(frag, off);
 	ctx->pos = ceph_make_fpos(frag, off);
 	while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) {
 	while (off >= fi->offset && off - fi->offset < rinfo->dir_nr) {
-		struct ceph_mds_reply_inode *in =
-			rinfo->dir_in[off - fi->offset].in;
+		struct ceph_mds_reply_dir_entry *rde =
+			rinfo->dir_entries + (off - fi->offset);
 		struct ceph_vino vino;
 		struct ceph_vino vino;
 		ino_t ino;
 		ino_t ino;
 
 
 		dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
 		dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n",
 		     off, off - fi->offset, rinfo->dir_nr, ctx->pos,
 		     off, off - fi->offset, rinfo->dir_nr, ctx->pos,
-		     rinfo->dir_dname_len[off - fi->offset],
-		     rinfo->dir_dname[off - fi->offset], in);
-		BUG_ON(!in);
-		ftype = le32_to_cpu(in->mode) >> 12;
-		vino.ino = le64_to_cpu(in->ino);
-		vino.snap = le64_to_cpu(in->snapid);
+		     rde->name_len, rde->name, &rde->inode.in);
+		BUG_ON(!rde->inode.in);
+		ftype = le32_to_cpu(rde->inode.in->mode) >> 12;
+		vino.ino = le64_to_cpu(rde->inode.in->ino);
+		vino.snap = le64_to_cpu(rde->inode.in->snapid);
 		ino = ceph_vino_to_ino(vino);
 		ino = ceph_vino_to_ino(vino);
-		if (!dir_emit(ctx,
-			    rinfo->dir_dname[off - fi->offset],
-			    rinfo->dir_dname_len[off - fi->offset],
-			    ceph_translate_ino(inode->i_sb, ino), ftype)) {
+		if (!dir_emit(ctx, rde->name, rde->name_len,
+			      ceph_translate_ino(inode->i_sb, ino), ftype)) {
 			dout("filldir stopping us...\n");
 			dout("filldir stopping us...\n");
 			return 0;
 			return 0;
 		}
 		}

+ 11 - 10
fs/ceph/inode.c

@@ -1308,12 +1308,13 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
 	int i, err = 0;
 	int i, err = 0;
 
 
 	for (i = 0; i < rinfo->dir_nr; i++) {
 	for (i = 0; i < rinfo->dir_nr; i++) {
+		struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
 		struct ceph_vino vino;
 		struct ceph_vino vino;
 		struct inode *in;
 		struct inode *in;
 		int rc;
 		int rc;
 
 
-		vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
-		vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
+		vino.ino = le64_to_cpu(rde->inode.in->ino);
+		vino.snap = le64_to_cpu(rde->inode.in->snapid);
 
 
 		in = ceph_get_inode(req->r_dentry->d_sb, vino);
 		in = ceph_get_inode(req->r_dentry->d_sb, vino);
 		if (IS_ERR(in)) {
 		if (IS_ERR(in)) {
@@ -1321,7 +1322,7 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
 			dout("new_inode badness got %d\n", err);
 			dout("new_inode badness got %d\n", err);
 			continue;
 			continue;
 		}
 		}
-		rc = fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
+		rc = fill_inode(in, NULL, &rde->inode, NULL, session,
 				req->r_request_started, -1,
 				req->r_request_started, -1,
 				&req->r_caps_reservation);
 				&req->r_caps_reservation);
 		if (rc < 0) {
 		if (rc < 0) {
@@ -1433,14 +1434,15 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
 
 
 	/* FIXME: release caps/leases if error occurs */
 	/* FIXME: release caps/leases if error occurs */
 	for (i = 0; i < rinfo->dir_nr; i++) {
 	for (i = 0; i < rinfo->dir_nr; i++) {
+		struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
 		struct ceph_vino vino;
 		struct ceph_vino vino;
 
 
-		dname.name = rinfo->dir_dname[i];
-		dname.len = rinfo->dir_dname_len[i];
+		dname.name = rde->name;
+		dname.len = rde->name_len;
 		dname.hash = full_name_hash(dname.name, dname.len);
 		dname.hash = full_name_hash(dname.name, dname.len);
 
 
-		vino.ino = le64_to_cpu(rinfo->dir_in[i].in->ino);
-		vino.snap = le64_to_cpu(rinfo->dir_in[i].in->snapid);
+		vino.ino = le64_to_cpu(rde->inode.in->ino);
+		vino.snap = le64_to_cpu(rde->inode.in->snapid);
 
 
 retry_lookup:
 retry_lookup:
 		dn = d_lookup(parent, &dname);
 		dn = d_lookup(parent, &dname);
@@ -1486,7 +1488,7 @@ retry_lookup:
 			}
 			}
 		}
 		}
 
 
-		ret = fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
+		ret = fill_inode(in, NULL, &rde->inode, NULL, session,
 				 req->r_request_started, -1,
 				 req->r_request_started, -1,
 				 &req->r_caps_reservation);
 				 &req->r_caps_reservation);
 		if (ret < 0) {
 		if (ret < 0) {
@@ -1522,8 +1524,7 @@ retry_lookup:
 		di = dn->d_fsdata;
 		di = dn->d_fsdata;
 		di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
 		di->offset = ceph_make_fpos(frag, i + req->r_readdir_offset);
 
 
-		update_dentry_lease(dn, rinfo->dir_dlease[i],
-				    req->r_session,
+		update_dentry_lease(dn, rde->lease, req->r_session,
 				    req->r_request_started);
 				    req->r_request_started);
 
 
 		if (err == 0 && skipped == 0 && cache_ctl.index >= 0) {
 		if (err == 0 && skipped == 0 && cache_ctl.index >= 0) {

+ 19 - 23
fs/ceph/mds_client.c

@@ -186,12 +186,9 @@ static int parse_reply_info_dir(void **p, void *end,
 	if (num == 0)
 	if (num == 0)
 		goto done;
 		goto done;
 
 
-	BUG_ON(!info->dir_in);
-	info->dir_dname = (void *)(info->dir_in + num);
-	info->dir_dname_len = (void *)(info->dir_dname + num);
-	info->dir_dlease = (void *)(info->dir_dname_len + num);
-	if ((unsigned long)(info->dir_dlease + num) >
-	    (unsigned long)info->dir_in + info->dir_buf_size) {
+	BUG_ON(!info->dir_entries);
+	if ((unsigned long)(info->dir_entries + num) >
+	    (unsigned long)info->dir_entries + info->dir_buf_size) {
 		pr_err("dir contents are larger than expected\n");
 		pr_err("dir contents are larger than expected\n");
 		WARN_ON(1);
 		WARN_ON(1);
 		goto bad;
 		goto bad;
@@ -199,19 +196,19 @@ static int parse_reply_info_dir(void **p, void *end,
 
 
 	info->dir_nr = num;
 	info->dir_nr = num;
 	while (num) {
 	while (num) {
+		struct ceph_mds_reply_dir_entry *rde = info->dir_entries + i;
 		/* dentry */
 		/* dentry */
 		ceph_decode_need(p, end, sizeof(u32)*2, bad);
 		ceph_decode_need(p, end, sizeof(u32)*2, bad);
-		info->dir_dname_len[i] = ceph_decode_32(p);
-		ceph_decode_need(p, end, info->dir_dname_len[i], bad);
-		info->dir_dname[i] = *p;
-		*p += info->dir_dname_len[i];
-		dout("parsed dir dname '%.*s'\n", info->dir_dname_len[i],
-		     info->dir_dname[i]);
-		info->dir_dlease[i] = *p;
+		rde->name_len = ceph_decode_32(p);
+		ceph_decode_need(p, end, rde->name_len, bad);
+		rde->name = *p;
+		*p += rde->name_len;
+		dout("parsed dir dname '%.*s'\n", rde->name_len, rde->name);
+		rde->lease = *p;
 		*p += sizeof(struct ceph_mds_reply_lease);
 		*p += sizeof(struct ceph_mds_reply_lease);
 
 
 		/* inode */
 		/* inode */
-		err = parse_reply_info_in(p, end, &info->dir_in[i], features);
+		err = parse_reply_info_in(p, end, &rde->inode, features);
 		if (err < 0)
 		if (err < 0)
 			goto out_bad;
 			goto out_bad;
 		i++;
 		i++;
@@ -345,9 +342,9 @@ out_bad:
 
 
 static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info)
 static void destroy_reply_info(struct ceph_mds_reply_info_parsed *info)
 {
 {
-	if (!info->dir_in)
+	if (!info->dir_entries)
 		return;
 		return;
-	free_pages((unsigned long)info->dir_in, get_order(info->dir_buf_size));
+	free_pages((unsigned long)info->dir_entries, get_order(info->dir_buf_size));
 }
 }
 
 
 
 
@@ -1656,8 +1653,7 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
 	struct ceph_inode_info *ci = ceph_inode(dir);
 	struct ceph_inode_info *ci = ceph_inode(dir);
 	struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
 	struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info;
 	struct ceph_mount_options *opt = req->r_mdsc->fsc->mount_options;
 	struct ceph_mount_options *opt = req->r_mdsc->fsc->mount_options;
-	size_t size = sizeof(*rinfo->dir_in) + sizeof(*rinfo->dir_dname_len) +
-		      sizeof(*rinfo->dir_dname) + sizeof(*rinfo->dir_dlease);
+	size_t size = sizeof(struct ceph_mds_reply_dir_entry);
 	int order, num_entries;
 	int order, num_entries;
 
 
 	spin_lock(&ci->i_ceph_lock);
 	spin_lock(&ci->i_ceph_lock);
@@ -1668,14 +1664,14 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req,
 
 
 	order = get_order(size * num_entries);
 	order = get_order(size * num_entries);
 	while (order >= 0) {
 	while (order >= 0) {
-		rinfo->dir_in = (void*)__get_free_pages(GFP_KERNEL |
-							__GFP_NOWARN,
-							order);
-		if (rinfo->dir_in)
+		rinfo->dir_entries = (void*)__get_free_pages(GFP_KERNEL |
+							     __GFP_NOWARN,
+							     order);
+		if (rinfo->dir_entries)
 			break;
 			break;
 		order--;
 		order--;
 	}
 	}
-	if (!rinfo->dir_in)
+	if (!rinfo->dir_entries)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	num_entries = (PAGE_SIZE << order) / size;
 	num_entries = (PAGE_SIZE << order) / size;

+ 8 - 4
fs/ceph/mds_client.h

@@ -47,6 +47,13 @@ struct ceph_mds_reply_info_in {
 	u32 pool_ns_len;
 	u32 pool_ns_len;
 };
 };
 
 
+struct ceph_mds_reply_dir_entry {
+	char                          *name;
+	u32                           name_len;
+	struct ceph_mds_reply_lease   *lease;
+	struct ceph_mds_reply_info_in inode;
+};
+
 /*
 /*
  * parsed info about an mds reply, including information about
  * parsed info about an mds reply, including information about
  * either: 1) the target inode and/or its parent directory and dentry,
  * either: 1) the target inode and/or its parent directory and dentry,
@@ -73,11 +80,8 @@ struct ceph_mds_reply_info_parsed {
 			struct ceph_mds_reply_dirfrag *dir_dir;
 			struct ceph_mds_reply_dirfrag *dir_dir;
 			size_t			      dir_buf_size;
 			size_t			      dir_buf_size;
 			int                           dir_nr;
 			int                           dir_nr;
-			char                          **dir_dname;
-			u32                           *dir_dname_len;
-			struct ceph_mds_reply_lease   **dir_dlease;
-			struct ceph_mds_reply_info_in *dir_in;
 			u8                            dir_complete, dir_end;
 			u8                            dir_complete, dir_end;
+			struct ceph_mds_reply_dir_entry  *dir_entries;
 		};
 		};
 
 
 		/* for create results */
 		/* for create results */