-
- out:
- gfs2_alloc_put(ip);
-
- return error;
-}
-
-/**
- * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode)
- * @sdp: the filesystem
- * @inum: the inode number to deallocate
- * @io_gh: a holder for the iopen glock for this inode
- *
- * N.B. When we enter this we already hold the iopen glock and getting
- * the glock for the inode means that we are grabbing the locks in the
- * "wrong" order so we must only so a try lock operation and fail if we
- * don't get the lock. Thats ok, since if we fail it means someone else
- * is using the inode still and thus we shouldn't be deallocating it
- * anyway.
- *
- * Returns: errno
- */
-
-static int inode_dealloc(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul,
- struct gfs2_holder *io_gh)
-{
- struct gfs2_inode *ip;
- struct gfs2_holder i_gh;
- int error;
-
- error = gfs2_glock_nq_num(sdp, ul->ul_ut.ut_inum.no_addr,
- &gfs2_inode_glops, LM_ST_EXCLUSIVE,
- LM_FLAG_TRY_1CB, &i_gh);
- switch(error) {
- case 0:
- break;
- case GLR_TRYFAILED:
- return 1; /* or back off and relock in different order? */
- default:
- return error;
- }
-
- gfs2_assert_warn(sdp, !i_gh.gh_gl->gl_object);
- error = inode_create(i_gh.gh_gl, &ul->ul_ut.ut_inum, io_gh->gh_gl,
- LM_ST_EXCLUSIVE, &ip, 0);
-
- if (error)
- goto out;
-
- error = gfs2_inode_refresh(ip);
- if (error)
- goto out_iput;
-
- if (ip->i_di.di_nlink) {
- if (gfs2_consist_inode(ip))
- gfs2_dinode_print(&ip->i_di);
- error = -EIO;
- goto out_iput;
- }
-
- if (S_ISDIR(ip->i_di.di_mode) &&
- (ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
- error = gfs2_dir_exhash_dealloc(ip);
- if (error)
- goto out_iput;
- }
-
- if (ip->i_di.di_eattr) {
- error = gfs2_ea_dealloc(ip);
- if (error)
- goto out_iput;
- }
-
- if (!gfs2_is_stuffed(ip)) {
- error = gfs2_file_dealloc(ip);
- if (error)
- goto out_iput;
- }
-
- error = dinode_dealloc(ip, ul);
- if (error)
- goto out_iput;
-
-out_iput:
- gfs2_glmutex_lock(i_gh.gh_gl);
- gfs2_inode_put(ip);
- gfs2_inode_destroy(ip, 0);
- gfs2_glmutex_unlock(i_gh.gh_gl);
-