Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbb7cae2 authored by Steven Whitehouse's avatar Steven Whitehouse
Browse files

[GFS2] Clean up inode number handling



This patch cleans up the inode number handling code. The main difference
is that instead of looking up the inodes using a struct gfs2_inum_host
we now use just the no_addr member of this structure. The tests relating
to no_formal_ino can then be done by the calling code. This has
advantages in that we want to do different things in different code
paths if the no_formal_ino doesn't match. In the NFS patch we want to
return -ESTALE, but in the ->lookup() path, its a bug in the fs if the
no_formal_ino doesn't match and thus we can withdraw in this case.

In order to later fix bz #201012, we need to be able to look up an inode
without knowing no_formal_ino, as the only information that is known to
us is the on-disk location of the inode in question.

This patch will also help us to fix bz #236099 at a later date by
cleaning up a lot of the code in that area.

There are no user visible changes as a result of this patch and there
are no changes to the on-disk format either.

Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 41d7db0a
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -1040,7 +1040,7 @@ static int trunc_end(struct gfs2_inode *ip)
		ip->i_di.di_height = 0;
		ip->i_di.di_height = 0;
		ip->i_di.di_goal_meta =
		ip->i_di.di_goal_meta =
			ip->i_di.di_goal_data =
			ip->i_di.di_goal_data =
			ip->i_num.no_addr;
			ip->i_no_addr;
		gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
		gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
	}
	}
	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
+43 −13
Original line number Original line Diff line number Diff line
@@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
		if (dip->i_di.di_entries != g.offset) {
		if (dip->i_di.di_entries != g.offset) {
			fs_warn(sdp, "Number of entries corrupt in dir %llu, "
			fs_warn(sdp, "Number of entries corrupt in dir %llu, "
				"ip->i_di.di_entries (%u) != g.offset (%u)\n",
				"ip->i_di.di_entries (%u) != g.offset (%u)\n",
				(unsigned long long)dip->i_num.no_addr,
				(unsigned long long)dip->i_no_addr,
				dip->i_di.di_entries,
				dip->i_di.di_entries,
				g.offset);
				g.offset);
			error = -EIO;
			error = -EIO;
@@ -1488,24 +1488,54 @@ out:
 * Returns: errno
 * Returns: errno
 */
 */


int gfs2_dir_search(struct inode *dir, const struct qstr *name,
struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
		    struct gfs2_inum_host *inum, unsigned int *type)
{
{
	struct buffer_head *bh;
	struct buffer_head *bh;
	struct gfs2_dirent *dent;
	struct gfs2_dirent *dent;
	struct inode *inode;

	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
	if (dent) {
		if (IS_ERR(dent))
			return ERR_PTR(PTR_ERR(dent));
		inode = gfs2_inode_lookup(dir->i_sb,
					  be64_to_cpu(dent->de_inum.no_addr),
					  be16_to_cpu(dent->de_type));
		brelse(bh);
		return inode;
	}
	return ERR_PTR(-ENOENT);
}

int gfs2_dir_check(struct inode *dir, const struct qstr *name,
		   const struct gfs2_inode *ip)
{
	struct buffer_head *bh;
	struct gfs2_dirent *dent;
	int ret = -ENOENT;


	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
	if (dent) {
	if (dent) {
		if (IS_ERR(dent))
		if (IS_ERR(dent))
			return PTR_ERR(dent);
			return PTR_ERR(dent);
		if (inum)
		if (ip) {
			gfs2_inum_in(inum, (char *)&dent->de_inum);
			if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
		if (type)
				goto out;
			*type = be16_to_cpu(dent->de_type);
			if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
			    ip->i_no_formal_ino)
				goto out;
			if (unlikely(IF2DT(ip->i_inode.i_mode) !=
			    be16_to_cpu(dent->de_type))) {
				gfs2_consist_inode(GFS2_I(dir));
				ret = -EIO;
				goto out;
			}
		}
		ret = 0;
out:
		brelse(bh);
		brelse(bh);
		return 0;
	}
	}
	return -ENOENT;
	return ret;
}
}


static int dir_new_leaf(struct inode *inode, const struct qstr *name)
static int dir_new_leaf(struct inode *inode, const struct qstr *name)
@@ -1565,7 +1595,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
 */
 */


int gfs2_dir_add(struct inode *inode, const struct qstr *name,
int gfs2_dir_add(struct inode *inode, const struct qstr *name,
		 const struct gfs2_inum_host *inum, unsigned type)
		 const struct gfs2_inode *nip, unsigned type)
{
{
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_inode *ip = GFS2_I(inode);
	struct buffer_head *bh;
	struct buffer_head *bh;
@@ -1580,7 +1610,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
			if (IS_ERR(dent))
			if (IS_ERR(dent))
				return PTR_ERR(dent);
				return PTR_ERR(dent);
			dent = gfs2_init_dirent(inode, dent, name, bh);
			dent = gfs2_init_dirent(inode, dent, name, bh);
			gfs2_inum_out(inum, (char *)&dent->de_inum);
			gfs2_inum_out(nip, dent);
			dent->de_type = cpu_to_be16(type);
			dent->de_type = cpu_to_be16(type);
			if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
			if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
				leaf = (struct gfs2_leaf *)bh->b_data;
				leaf = (struct gfs2_leaf *)bh->b_data;
@@ -1700,7 +1730,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
 */
 */


int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
		   struct gfs2_inum_host *inum, unsigned int new_type)
		   const struct gfs2_inode *nip, unsigned int new_type)
{
{
	struct buffer_head *bh;
	struct buffer_head *bh;
	struct gfs2_dirent *dent;
	struct gfs2_dirent *dent;
@@ -1715,7 +1745,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
		return PTR_ERR(dent);
		return PTR_ERR(dent);


	gfs2_trans_add_bh(dip->i_gl, bh, 1);
	gfs2_trans_add_bh(dip->i_gl, bh, 1);
	gfs2_inum_out(inum, (char *)&dent->de_inum);
	gfs2_inum_out(nip, dent);
	dent->de_type = cpu_to_be16(new_type);
	dent->de_type = cpu_to_be16(new_type);


	if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
	if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
+5 −4
Original line number Original line Diff line number Diff line
@@ -16,15 +16,16 @@ struct inode;
struct gfs2_inode;
struct gfs2_inode;
struct gfs2_inum;
struct gfs2_inum;


int gfs2_dir_search(struct inode *dir, const struct qstr *filename,
struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *filename);
		    struct gfs2_inum_host *inum, unsigned int *type);
int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
		   const struct gfs2_inode *ip);
int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
		 const struct gfs2_inum_host *inum, unsigned int type);
		 const struct gfs2_inode *ip, unsigned int type);
int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename);
int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename);
int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
		  filldir_t filldir);
		  filldir_t filldir);
int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
		   struct gfs2_inum_host *new_inum, unsigned int new_type);
		   const struct gfs2_inode *nip, unsigned int new_type);


int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);


+2 −2
Original line number Original line Diff line number Diff line
@@ -1823,8 +1823,8 @@ static int dump_inode(struct glock_iter *gi, struct gfs2_inode *ip)


	print_dbg(gi, "  Inode:\n");
	print_dbg(gi, "  Inode:\n");
	print_dbg(gi, "    num = %llu/%llu\n",
	print_dbg(gi, "    num = %llu/%llu\n",
		  (unsigned long long)ip->i_num.no_formal_ino,
		  (unsigned long long)ip->i_no_formal_ino,
		  (unsigned long long)ip->i_num.no_addr);
		  (unsigned long long)ip->i_no_addr);
	print_dbg(gi, "    type = %u\n", IF2DT(ip->i_inode.i_mode));
	print_dbg(gi, "    type = %u\n", IF2DT(ip->i_inode.i_mode));
	print_dbg(gi, "    i_flags =");
	print_dbg(gi, "    i_flags =");
	for (x = 0; x < 32; x++)
	for (x = 0; x < 32; x++)
+2 −2
Original line number Original line Diff line number Diff line
@@ -213,8 +213,8 @@ enum {


struct gfs2_inode {
struct gfs2_inode {
	struct inode i_inode;
	struct inode i_inode;
	struct gfs2_inum_host i_num;
	u64 i_no_addr;

	u64 i_no_formal_ino;
	unsigned long i_flags;		/* GIF_... */
	unsigned long i_flags;		/* GIF_... */


	struct gfs2_dinode_host i_di; /* To be replaced by ref to block */
	struct gfs2_dinode_host i_di; /* To be replaced by ref to block */
Loading