]> git.karo-electronics.de Git - linux-beck.git/blobdiff - fs/gfs2/inode.c
Merge branch 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ickle...
[linux-beck.git] / fs / gfs2 / inode.c
index 06370f8bd8cf4aafa95fd4df64e93ec8d657328d..e1213f7f92179aa2472304ff0db4294be66040d8 100644 (file)
@@ -73,49 +73,6 @@ static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr)
        return iget5_locked(sb, hash, iget_test, iget_set, &no_addr);
 }
 
-struct gfs2_skip_data {
-       u64     no_addr;
-       int     skipped;
-};
-
-static int iget_skip_test(struct inode *inode, void *opaque)
-{
-       struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_skip_data *data = opaque;
-
-       if (ip->i_no_addr == data->no_addr) {
-               if (inode->i_state & (I_FREEING|I_WILL_FREE)){
-                       data->skipped = 1;
-                       return 0;
-               }
-               return 1;
-       }
-       return 0;
-}
-
-static int iget_skip_set(struct inode *inode, void *opaque)
-{
-       struct gfs2_inode *ip = GFS2_I(inode);
-       struct gfs2_skip_data *data = opaque;
-
-       if (data->skipped)
-               return 1;
-       inode->i_ino = (unsigned long)(data->no_addr);
-       ip->i_no_addr = data->no_addr;
-       return 0;
-}
-
-static struct inode *gfs2_iget_skip(struct super_block *sb,
-                                   u64 no_addr)
-{
-       struct gfs2_skip_data data;
-       unsigned long hash = (unsigned long)no_addr;
-
-       data.no_addr = no_addr;
-       data.skipped = 0;
-       return iget5_locked(sb, hash, iget_skip_test, iget_skip_set, &data);
-}
-
 /**
  * GFS2 lookup code fills in vfs inode contents based on info obtained
  * from directory entry inside gfs2_inode_lookup(). This has caused issues
@@ -243,93 +200,54 @@ fail:
        return ERR_PTR(error);
 }
 
-/**
- * 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
- *
- */
-
-void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
+struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr,
+                                 u64 *no_formal_ino, unsigned int blktype)
 {
-       struct gfs2_sbd *sdp;
-       struct gfs2_inode *ip;
-       struct gfs2_glock *io_gl = NULL;
-       int error;
-       struct gfs2_holder gh;
+       struct super_block *sb = sdp->sd_vfs;
+       struct gfs2_holder i_gh;
        struct inode *inode;
+       int error;
 
-       inode = gfs2_iget_skip(sb, no_addr);
-
-       if (!inode)
-               return;
-
-       /* 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->i_no_formal_ino = -1;
+       error = gfs2_glock_nq_num(sdp, no_addr, &gfs2_inode_glops,
+                                 LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
+       if (error)
+               return ERR_PTR(error);
 
-       error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
-       if (unlikely(error))
+       error = gfs2_check_blk_type(sdp, no_addr, blktype);
+       if (error)
                goto fail;
-       ip->i_gl->gl_object = ip;
 
-       error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
-       if (unlikely(error))
-               goto fail_put;
-
-       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))
-               goto fail_iopen;
+       inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0);
+       if (IS_ERR(inode))
+               goto fail;
 
-       ip->i_iopen_gh.gh_gl->gl_object = ip;
-       gfs2_glock_put(io_gl);
-       io_gl = NULL;
+       error = gfs2_inode_refresh(GFS2_I(inode));
+       if (error)
+               goto fail_iput;
 
-       inode->i_mode = DT2IF(DT_UNKNOWN);
+       /* Pick up the works we bypass in gfs2_inode_lookup */
+       if (inode->i_state & I_NEW) 
+               gfs2_set_iop(inode);
 
-       /*
-        * 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).
-        */
-       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY,
-                                  &gh);
-       if (unlikely(error))
-               goto fail_glock;
+       /* Two extra checks for NFS only */
+       if (no_formal_ino) {
+               error = -ESTALE;
+               if (GFS2_I(inode)->i_no_formal_ino != *no_formal_ino)
+                       goto fail_iput;
 
-       /* Inode is now uptodate */
-       gfs2_glock_dq_uninit(&gh);
-       gfs2_set_iop(inode);
+               error = -EIO;
+               if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM)
+                       goto fail_iput;
 
-       /* The iput will cause it to be deleted. */
-       iput(inode);
-       return;
+               error = 0;
+       }
 
-fail_glock:
-       gfs2_glock_dq(&ip->i_iopen_gh);
-fail_iopen:
-       if (io_gl)
-               gfs2_glock_put(io_gl);
-fail_put:
-       ip->i_gl->gl_object = NULL;
-       gfs2_glock_put(ip->i_gl);
 fail:
-       iget_failed(inode);
-       return;
+       gfs2_glock_dq_uninit(&i_gh);
+       return error ? ERR_PTR(error) : inode;
+fail_iput:
+       iput(inode);
+       goto fail;
 }
 
 static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)