]> Pileus Git - ~andy/linux/blobdiff - fs/gfs2/inode.c
Merge remote branch 'origin/master'
[~andy/linux] / fs / gfs2 / inode.c
index 51d8061fa07ac79667148b6fec357feff8b6088f..f03afd9c44bc748b51811bff46ccdab3d66fa619 100644 (file)
@@ -169,7 +169,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
 {
        struct inode *inode;
        struct gfs2_inode *ip;
-       struct gfs2_glock *io_gl;
+       struct gfs2_glock *io_gl = NULL;
        int error;
 
        inode = gfs2_iget(sb, no_addr);
@@ -198,6 +198,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
                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;
@@ -228,7 +229,8 @@ gfs2_nfsbypass:
 fail_glock:
        gfs2_glock_dq(&ip->i_iopen_gh);
 fail_iopen:
-       gfs2_glock_put(io_gl);
+       if (io_gl)
+               gfs2_glock_put(io_gl);
 fail_put:
        if (inode->i_state & I_NEW)
                ip->i_gl->gl_object = NULL;
@@ -242,34 +244,38 @@ fail:
 }
 
 /**
- * gfs2_unlinked_inode_lookup - Lookup an unlinked inode for reclamation
+ * gfs2_process_unlinked_inode - Lookup an unlinked inode for reclamation
+ *                               and try to reclaim it by doing iput.
+ *
+ * This function assumes no rgrp locks are currently held.
+ *
  * @sb: The super block
  * no_addr: The inode number
- * @@inode: A pointer to the inode found, if any
  *
- * Returns: 0 and *inode if no errors occurred.  If an error occurs,
- *          the resulting *inode may or may not be NULL.
  */
 
-int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
-                              struct inode **inode)
+void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
 {
        struct gfs2_sbd *sdp;
        struct gfs2_inode *ip;
-       struct gfs2_glock *io_gl;
+       struct gfs2_glock *io_gl = NULL;
        int error;
        struct gfs2_holder gh;
+       struct inode *inode;
 
-       *inode = gfs2_iget_skip(sb, no_addr);
+       inode = gfs2_iget_skip(sb, no_addr);
 
-       if (!(*inode))
-               return -ENOBUFS;
+       if (!inode)
+               return;
 
-       if (!((*inode)->i_state & I_NEW))
-               return -ENOBUFS;
+       /* If it's not a new inode, someone's using it, so leave it alone. */
+       if (!(inode->i_state & I_NEW)) {
+               iput(inode);
+               return;
+       }
 
-       ip = GFS2_I(*inode);
-       sdp = GFS2_SB(*inode);
+       ip = GFS2_I(inode);
+       sdp = GFS2_SB(inode);
        ip->i_no_formal_ino = -1;
 
        error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
@@ -284,15 +290,14 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
        set_bit(GIF_INVALID, &ip->i_flags);
        error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT,
                                   &ip->i_iopen_gh);
-       if (unlikely(error)) {
-               if (error == GLR_TRYFAILED)
-                       error = 0;
+       if (unlikely(error))
                goto fail_iopen;
-       }
+
        ip->i_iopen_gh.gh_gl->gl_object = ip;
        gfs2_glock_put(io_gl);
+       io_gl = NULL;
 
-       (*inode)->i_mode = DT2IF(DT_UNKNOWN);
+       inode->i_mode = DT2IF(DT_UNKNOWN);
 
        /*
         * We must read the inode in order to work out its type in
@@ -303,25 +308,28 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr,
         */
        error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY,
                                   &gh);
-       if (unlikely(error)) {
-               if (error == GLR_TRYFAILED)
-                       error = 0;
+       if (unlikely(error))
                goto fail_glock;
-       }
+
        /* Inode is now uptodate */
        gfs2_glock_dq_uninit(&gh);
-       gfs2_set_iop(*inode);
+       gfs2_set_iop(inode);
+
+       /* The iput will cause it to be deleted. */
+       iput(inode);
+       return;
 
-       return 0;
 fail_glock:
        gfs2_glock_dq(&ip->i_iopen_gh);
 fail_iopen:
-       gfs2_glock_put(io_gl);
+       if (io_gl)
+               gfs2_glock_put(io_gl);
 fail_put:
        ip->i_gl->gl_object = NULL;
        gfs2_glock_put(ip->i_gl);
 fail:
-       return error;
+       iget_failed(inode);
+       return;
 }
 
 static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)