Commit d81a8ef5 authored by Al Viro's avatar Al Viro
Browse files

[readdir] convert gfs2



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 75811d4f
Loading
Loading
Loading
Loading
+24 −32
Original line number Diff line number Diff line
@@ -1212,9 +1212,7 @@ static int compare_dents(const void *a, const void *b)
/**
 * do_filldir_main - read out directory entries
 * @dip: The GFS2 inode
 * @offset: The offset in the file to read from
 * @opaque: opaque data to pass to filldir
 * @filldir: The function to pass entries to
 * @ctx: what to feed the entries to
 * @darr: an array of struct gfs2_dirent pointers to read
 * @entries: the number of entries in darr
 * @copied: pointer to int that's non-zero if a entry has been copied out
@@ -1224,11 +1222,10 @@ static int compare_dents(const void *a, const void *b)
 * the possibility that they will fall into different readdir buffers or
 * that someone will want to seek to that location.
 *
 * Returns: errno, >0 on exception from filldir
 * Returns: errno, >0 if the actor tells you to stop
 */

static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
			   void *opaque, filldir_t filldir,
static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx,
			   const struct gfs2_dirent **darr, u32 entries,
			   int *copied)
{
@@ -1236,7 +1233,6 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
	u64 off, off_next;
	unsigned int x, y;
	int run = 0;
	int error = 0;

	sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL);

@@ -1253,9 +1249,9 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
			off_next = be32_to_cpu(dent_next->de_hash);
			off_next = gfs2_disk_hash2offset(off_next);

			if (off < *offset)
			if (off < ctx->pos)
				continue;
			*offset = off;
			ctx->pos = off;

			if (off_next == off) {
				if (*copied && !run)
@@ -1264,26 +1260,25 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
			} else
				run = 0;
		} else {
			if (off < *offset)
			if (off < ctx->pos)
				continue;
			*offset = off;
			ctx->pos = off;
		}

		error = filldir(opaque, (const char *)(dent + 1),
		if (!dir_emit(ctx, (const char *)(dent + 1),
				be16_to_cpu(dent->de_name_len),
				off, be64_to_cpu(dent->de_inum.no_addr),
				be16_to_cpu(dent->de_type));
		if (error)
				be64_to_cpu(dent->de_inum.no_addr),
				be16_to_cpu(dent->de_type)))
			return 1;

		*copied = 1;
	}

	/* Increment the *offset by one, so the next time we come into the
	/* Increment the ctx->pos by one, so the next time we come into the
	   do_filldir fxn, we get the next entry instead of the last one in the
	   current leaf */

	(*offset)++;
	ctx->pos++;

	return 0;
}
@@ -1307,8 +1302,8 @@ static void gfs2_free_sort_buffer(void *ptr)
		kfree(ptr);
}

static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
			      filldir_t filldir, int *copied, unsigned *depth,
static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx,
			      int *copied, unsigned *depth,
			      u64 leaf_no)
{
	struct gfs2_inode *ip = GFS2_I(inode);
@@ -1386,8 +1381,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
	} while(lfn);

	BUG_ON(entries2 != entries);
	error = do_filldir_main(ip, offset, opaque, filldir, darr,
				entries, copied);
	error = do_filldir_main(ip, ctx, darr, entries, copied);
out_free:
	for(i = 0; i < leaf; i++)
		brelse(larr[i]);
@@ -1446,15 +1440,13 @@ static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index,
/**
 * dir_e_read - Reads the entries from a directory into a filldir buffer
 * @dip: dinode pointer
 * @offset: the hash of the last entry read shifted to the right once
 * @opaque: buffer for the filldir function to fill
 * @filldir: points to the filldir function to use
 * @ctx: actor to feed the entries to
 *
 * Returns: errno
 */

static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
		      filldir_t filldir, struct file_ra_state *f_ra)
static int dir_e_read(struct inode *inode, struct dir_context *ctx,
		      struct file_ra_state *f_ra)
{
	struct gfs2_inode *dip = GFS2_I(inode);
	u32 hsize, len = 0;
@@ -1465,7 +1457,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
	unsigned depth = 0;

	hsize = 1 << dip->i_depth;
	hash = gfs2_dir_offset2hash(*offset);
	hash = gfs2_dir_offset2hash(ctx->pos);
	index = hash >> (32 - dip->i_depth);

	if (dip->i_hash_cache == NULL)
@@ -1477,7 +1469,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
	gfs2_dir_readahead(inode, hsize, index, f_ra);

	while (index < hsize) {
		error = gfs2_dir_read_leaf(inode, offset, opaque, filldir,
		error = gfs2_dir_read_leaf(inode, ctx,
					   &copied, &depth,
					   be64_to_cpu(lp[index]));
		if (error)
@@ -1492,8 +1484,8 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
	return error;
}

int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
		  filldir_t filldir, struct file_ra_state *f_ra)
int gfs2_dir_read(struct inode *inode, struct dir_context *ctx,
		  struct file_ra_state *f_ra)
{
	struct gfs2_inode *dip = GFS2_I(inode);
	struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -1507,7 +1499,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
		return 0;

	if (dip->i_diskflags & GFS2_DIF_EXHASH)
		return dir_e_read(inode, offset, opaque, filldir, f_ra);
		return dir_e_read(inode, ctx, f_ra);

	if (!gfs2_is_stuffed(dip)) {
		gfs2_consist_inode(dip);
@@ -1539,7 +1531,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
			error = -EIO;
			goto out;
		}
		error = do_filldir_main(dip, offset, opaque, filldir, darr,
		error = do_filldir_main(dip, ctx, darr,
					dip->i_entries, &copied);
out:
		kfree(darr);
+2 −2
Original line number Diff line number Diff line
@@ -24,8 +24,8 @@ extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
			const struct gfs2_inode *ip);
extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry);
extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
			 filldir_t filldir, struct file_ra_state *f_ra);
extern int gfs2_dir_read(struct inode *inode, struct dir_context *ctx,
			 struct file_ra_state *f_ra);
extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
			  const struct gfs2_inode *nip, unsigned int new_type);

+4 −2
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ static int gfs2_encode_fh(struct inode *inode, __u32 *p, int *len,
}

struct get_name_filldir {
	struct dir_context ctx;
	struct gfs2_inum_host inum;
	char *name;
};
@@ -90,7 +91,6 @@ static int gfs2_get_name(struct dentry *parent, char *name,
	struct gfs2_inode *dip, *ip;
	struct get_name_filldir gnfd;
	struct gfs2_holder gh;
	u64 offset = 0;
	int error;
	struct file_ra_state f_ra = { .start = 0 };

@@ -107,12 +107,14 @@ static int gfs2_get_name(struct dentry *parent, char *name,
	gnfd.inum.no_addr = ip->i_no_addr;
	gnfd.inum.no_formal_ino = ip->i_no_formal_ino;
	gnfd.name = name;
	gnfd.ctx.actor = get_name_filldir;
	gnfd.ctx.pos = 0;

	error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh);
	if (error)
		return error;

	error = gfs2_dir_read(dir, &offset, &gnfd, get_name_filldir, &f_ra);
	error = gfs2_dir_read(dir, &gnfd.ctx, &f_ra);

	gfs2_glock_dq_uninit(&gh);

+8 −15
Original line number Diff line number Diff line
@@ -82,35 +82,28 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int whence)
}

/**
 * gfs2_readdir - Read directory entries from a directory
 * gfs2_readdir - Iterator for a directory
 * @file: The directory to read from
 * @dirent: Buffer for dirents
 * @filldir: Function used to do the copying
 * @ctx: What to feed directory entries to
 *
 * Returns: errno
 */

static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir)
static int gfs2_readdir(struct file *file, struct dir_context *ctx)
{
	struct inode *dir = file->f_mapping->host;
	struct gfs2_inode *dip = GFS2_I(dir);
	struct gfs2_holder d_gh;
	u64 offset = file->f_pos;
	int error;

	gfs2_holder_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
	error = gfs2_glock_nq(&d_gh);
	if (error) {
		gfs2_holder_uninit(&d_gh);
	error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
	if (error)
		return error;
	}

	error = gfs2_dir_read(dir, &offset, dirent, filldir, &file->f_ra);
	error = gfs2_dir_read(dir, ctx, &file->f_ra);

	gfs2_glock_dq_uninit(&d_gh);

	file->f_pos = offset;

	return error;
}

@@ -1048,7 +1041,7 @@ const struct file_operations gfs2_file_fops = {
};

const struct file_operations gfs2_dir_fops = {
	.readdir	= gfs2_readdir,
	.iterate	= gfs2_readdir,
	.unlocked_ioctl	= gfs2_ioctl,
	.open		= gfs2_open,
	.release	= gfs2_release,
@@ -1078,7 +1071,7 @@ const struct file_operations gfs2_file_fops_nolock = {
};

const struct file_operations gfs2_dir_fops_nolock = {
	.readdir	= gfs2_readdir,
	.iterate	= gfs2_readdir,
	.unlocked_ioctl	= gfs2_ioctl,
	.open		= gfs2_open,
	.release	= gfs2_release,