Commit 1dd9f5ba authored by Russell King's avatar Russell King Committed by Al Viro
Browse files

fs/adfs: dir: add common directory buffer release method



With the bhs pointer in place, we have no need for separate per-format
free() methods, since a generic version will do.  Provide a generic
implementation, remove the format specific implementations and the
method function pointer.

Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 95fbadbb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,6 @@ struct adfs_dir_ops {
	int	(*create)(struct adfs_dir *dir, struct object_info *obj);
	int	(*remove)(struct adfs_dir *dir, struct object_info *obj);
	int	(*sync)(struct adfs_dir *dir);
	void	(*free)(struct adfs_dir *dir);
};

struct adfs_discmap {
@@ -167,6 +166,7 @@ extern const struct dentry_operations adfs_dentry_operations;
extern const struct adfs_dir_ops adfs_f_dir_ops;
extern const struct adfs_dir_ops adfs_fplus_dir_ops;

void adfs_dir_relse(struct adfs_dir *dir);
void adfs_object_fixup(struct adfs_dir *dir, struct object_info *obj);
extern int adfs_dir_update(struct super_block *sb, struct object_info *obj,
			   int wait);
+18 −3
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 *
 *  Common directory handling for ADFS
 */
#include <linux/slab.h>
#include "adfs.h"

/*
@@ -13,6 +14,20 @@
 */
static DEFINE_RWLOCK(adfs_dir_lock);

void adfs_dir_relse(struct adfs_dir *dir)
{
	unsigned int i;

	for (i = 0; i < dir->nr_buffers; i++)
		brelse(dir->bhs[i]);
	dir->nr_buffers = 0;

	if (dir->bhs != dir->bh)
		kfree(dir->bhs);
	dir->bhs = NULL;
	dir->sb = NULL;
}

static int adfs_dir_read(struct super_block *sb, u32 indaddr,
			 unsigned int size, struct adfs_dir *dir)
{
@@ -105,7 +120,7 @@ unlock_out:
	read_unlock(&adfs_dir_lock);

free_out:
	ops->free(&dir);
	adfs_dir_relse(&dir);
	return ret;
}

@@ -139,7 +154,7 @@ adfs_dir_update(struct super_block *sb, struct object_info *obj, int wait)
			ret = err;
	}

	ops->free(&dir);
	adfs_dir_relse(&dir);
out:
#endif
	return ret;
@@ -211,7 +226,7 @@ unlock_out:
	read_unlock(&adfs_dir_lock);

free_out:
	ops->free(&dir);
	adfs_dir_relse(&dir);
out:
	return ret;
}
+4 −24
Original line number Diff line number Diff line
@@ -9,8 +9,6 @@
#include "adfs.h"
#include "dir_f.h"

static void adfs_f_free(struct adfs_dir *dir);

/*
 * Read an (unaligned) value of length 1..4 bytes
 */
@@ -128,7 +126,7 @@ static int adfs_dir_read(struct super_block *sb, u32 indaddr,
			 unsigned int size, struct adfs_dir *dir)
{
	const unsigned int blocksize_bits = sb->s_blocksize_bits;
	int blk = 0;
	int blk;

	/*
	 * Directories which are not a multiple of 2048 bytes
@@ -152,6 +150,8 @@ static int adfs_dir_read(struct super_block *sb, u32 indaddr,
		dir->bh[blk] = sb_bread(sb, phys);
		if (!dir->bh[blk])
			goto release_buffers;

		dir->nr_buffers += 1;
	}

	memcpy(&dir->dirhead, bufoff(dir->bh, 0), sizeof(dir->dirhead));
@@ -168,17 +168,12 @@ static int adfs_dir_read(struct super_block *sb, u32 indaddr,
	if (adfs_dir_checkbyte(dir) != dir->dirtail.new.dircheckbyte)
		goto bad_dir;

	dir->nr_buffers = blk;

	return 0;

bad_dir:
	adfs_error(sb, "dir %06x is corrupted", indaddr);
release_buffers:
	for (blk -= 1; blk >= 0; blk -= 1)
		brelse(dir->bh[blk]);

	dir->sb = NULL;
	adfs_dir_relse(dir);

	return -EIO;
}
@@ -435,25 +430,10 @@ adfs_f_sync(struct adfs_dir *dir)
	return err;
}

static void
adfs_f_free(struct adfs_dir *dir)
{
	int i;

	for (i = dir->nr_buffers - 1; i >= 0; i--) {
		brelse(dir->bh[i]);
		dir->bh[i] = NULL;
	}

	dir->nr_buffers = 0;
	dir->sb = NULL;
}

const struct adfs_dir_ops adfs_f_dir_ops = {
	.read		= adfs_f_read,
	.setpos		= adfs_f_setpos,
	.getnext	= adfs_f_getnext,
	.update		= adfs_f_update,
	.sync		= adfs_f_sync,
	.free		= adfs_f_free
};
+2 −32
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ adfs_fplus_read(struct super_block *sb, unsigned int id, unsigned int sz, struct
	struct adfs_bigdirtail *t;
	unsigned long block;
	unsigned int blk, size;
	int i, ret = -EIO;
	int ret = -EIO;

	block = __adfs_block_map(sb, id, 0);
	if (!block) {
@@ -92,18 +92,8 @@ adfs_fplus_read(struct super_block *sb, unsigned int id, unsigned int sz, struct
	return 0;

out:
	if (dir->bhs) {
		for (i = 0; i < dir->nr_buffers; i++)
			brelse(dir->bhs[i]);
	adfs_dir_relse(dir);

		if (&dir->bh[0] != dir->bhs)
			kfree(dir->bhs);

		dir->bhs = NULL;
	}

	dir->nr_buffers = 0;
	dir->sb = NULL;
	return ret;
}

@@ -205,29 +195,9 @@ adfs_fplus_sync(struct adfs_dir *dir)
	return err;
}

static void
adfs_fplus_free(struct adfs_dir *dir)
{
	int i;

	if (dir->bhs) {
		for (i = 0; i < dir->nr_buffers; i++)
			brelse(dir->bhs[i]);

		if (&dir->bh[0] != dir->bhs)
			kfree(dir->bhs);

		dir->bhs = NULL;
	}

	dir->nr_buffers = 0;
	dir->sb = NULL;
}

const struct adfs_dir_ops adfs_fplus_dir_ops = {
	.read		= adfs_fplus_read,
	.setpos		= adfs_fplus_setpos,
	.getnext	= adfs_fplus_getnext,
	.sync		= adfs_fplus_sync,
	.free		= adfs_fplus_free
};