Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes:
  GFS2: Fix error path in gfs2_lookup_by_inum()
  GFS2: remove iopen glocks from cache on failed deletes
  • Loading branch information
torvalds committed Jan 21, 2011
2 parents e589501 + 24d9765 commit b06ae1e
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 51 deletions.
72 changes: 22 additions & 50 deletions fs/gfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,14 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
}

/**
* GFS2 lookup code fills in vfs inode contents based on info obtained
* from directory entry inside gfs2_inode_lookup(). This has caused issues
* with NFS code path since its get_dentry routine doesn't have the relevant
* directory entry when gfs2_inode_lookup() is invoked. Part of the code
* segment inside gfs2_inode_lookup code needs to get moved around.
* gfs2_set_iop - Sets inode operations
* @inode: The inode with correct i_mode filled in
*
* Clears I_NEW as well.
**/
* GFS2 lookup code fills in vfs inode contents based on info obtained
* from directory entry inside gfs2_inode_lookup().
*/

void gfs2_set_iop(struct inode *inode)
static void gfs2_set_iop(struct inode *inode)
{
struct gfs2_sbd *sdp = GFS2_SB(inode);
umode_t mode = inode->i_mode;
Expand All @@ -106,8 +104,6 @@ void gfs2_set_iop(struct inode *inode)
inode->i_op = &gfs2_file_iops;
init_special_inode(inode, inode->i_mode, inode->i_rdev);
}

unlock_new_inode(inode);
}

/**
Expand All @@ -119,10 +115,8 @@ void gfs2_set_iop(struct inode *inode)
* Returns: A VFS inode, or an error
*/

struct inode *gfs2_inode_lookup(struct super_block *sb,
unsigned int type,
u64 no_addr,
u64 no_formal_ino)
struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
u64 no_addr, u64 no_formal_ino)
{
struct inode *inode;
struct gfs2_inode *ip;
Expand Down Expand Up @@ -152,51 +146,37 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
if (unlikely(error))
goto fail_iopen;
ip->i_iopen_gh.gh_gl->gl_object = ip;

ip->i_iopen_gh.gh_gl->gl_object = ip;
gfs2_glock_put(io_gl);
io_gl = NULL;

if ((type == DT_UNKNOWN) && (no_formal_ino == 0))
goto gfs2_nfsbypass;

inode->i_mode = DT2IF(type);

/*
* We must read the inode in order to work out its type in
* this case. Note that this doesn't happen often as we normally
* know the type beforehand. This code path only occurs during
* unlinked inode recovery (where it is safe to do this glock,
* which is not true in the general case).
*/
if (type == DT_UNKNOWN) {
struct gfs2_holder gh;
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
if (unlikely(error))
goto fail_glock;
/* Inode is now uptodate */
gfs2_glock_dq_uninit(&gh);
/* Inode glock must be locked already */
error = gfs2_inode_refresh(GFS2_I(inode));
if (error)
goto fail_refresh;
} else {
inode->i_mode = DT2IF(type);
}

gfs2_set_iop(inode);
unlock_new_inode(inode);
}

gfs2_nfsbypass:
return inode;
fail_glock:
gfs2_glock_dq(&ip->i_iopen_gh);

fail_refresh:
ip->i_iopen_gh.gh_gl->gl_object = NULL;
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
fail_iopen:
if (io_gl)
gfs2_glock_put(io_gl);
fail_put:
if (inode->i_state & I_NEW)
ip->i_gl->gl_object = NULL;
ip->i_gl->gl_object = NULL;
gfs2_glock_put(ip->i_gl);
fail:
if (inode->i_state & I_NEW)
iget_failed(inode);
else
iput(inode);
iget_failed(inode);
return ERR_PTR(error);
}

Expand All @@ -221,14 +201,6 @@ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
if (IS_ERR(inode))
goto fail;

error = gfs2_inode_refresh(GFS2_I(inode));
if (error)
goto fail_iput;

/* Pick up the works we bypass in gfs2_inode_lookup */
if (inode->i_state & I_NEW)
gfs2_set_iop(inode);

/* Two extra checks for NFS only */
if (no_formal_ino) {
error = -ESTALE;
Expand Down
1 change: 0 additions & 1 deletion fs/gfs2/inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ static inline int gfs2_check_internal_file_size(struct inode *inode,
return -EIO;
}

extern void gfs2_set_iop(struct inode *inode);
extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type,
u64 no_addr, u64 no_formal_ino);
extern struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
Expand Down
1 change: 1 addition & 0 deletions fs/gfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,7 @@ static void gfs2_evict_inode(struct inode *inode)
if (error)
goto out_truncate;

ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
gfs2_glock_dq_wait(&ip->i_iopen_gh);
gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
error = gfs2_glock_nq(&ip->i_iopen_gh);
Expand Down

0 comments on commit b06ae1e

Please sign in to comment.