From b11f94d537e6b69f13770143fd7ded3d09fdbaab Mon Sep 17 00:00:00 2001 From: David Chinner Date: Wed, 11 Jul 2007 11:09:33 +1000 Subject: [XFS] Quota inode has no parent. Avoid using a special "zero inode" as the parent of the quota inode as this can confuse the filestreams code into thinking the quota inode has a parent. We do not want the quota inode to follow filestreams allocation rules, so pass a NULL as the parent inode and detect this condition when doing stream associations. SGI-PV: 964469 SGI-Modid: xfs-linux-melb:xfs-kern:29098a Signed-off-by: David Chinner Signed-off-by: Tim Shimmin --- fs/xfs/quota/xfs_qm.c | 3 +-- fs/xfs/xfs_inode.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index eeb3d9cc0e8e..7def4c699343 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -65,7 +65,6 @@ kmem_zone_t *qm_dqtrxzone; static struct shrinker *xfs_qm_shaker; static cred_t xfs_zerocr; -static xfs_inode_t xfs_zeroino; STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); @@ -1415,7 +1414,7 @@ xfs_qm_qino_alloc( return error; } - if ((error = xfs_dir_ialloc(&tp, &xfs_zeroino, S_IFREG, 1, 0, + if ((error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, &xfs_zerocr, 0, 1, ip, &committed))) { xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 2ef100be6c4f..59829523ab07 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1078,6 +1078,11 @@ xfs_iread_extents( * also returns the [locked] bp pointing to the head of the freelist * as ialloc_context. The caller should hold this buffer across * the commit and pass it back into this routine on the second call. + * + * If we are allocating quota inodes, we do not have a parent inode + * to attach to or associate with (i.e. pip == NULL) because they + * are not linked into the directory structure - they are attached + * directly to the superblock - and so have no parent. */ int xfs_ialloc( @@ -1103,7 +1108,7 @@ xfs_ialloc( * Call the space management code to pick * the on-disk inode to be allocated. */ - error = xfs_dialloc(tp, pip->i_ino, mode, okalloc, + error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, ialloc_context, call_again, &ino); if (error != 0) { return error; @@ -1157,7 +1162,7 @@ xfs_ialloc( if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) xfs_bump_ino_vers2(tp, ip); - if (XFS_INHERIT_GID(pip, vp->v_vfsp)) { + if (pip && XFS_INHERIT_GID(pip, vp->v_vfsp)) { ip->i_d.di_gid = pip->i_d.di_gid; if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { ip->i_d.di_mode |= S_ISGID; @@ -1199,7 +1204,7 @@ xfs_ialloc( flags |= XFS_ILOG_DEV; break; case S_IFREG: - if (xfs_inode_is_filestream(pip)) { + if (pip && xfs_inode_is_filestream(pip)) { error = xfs_filestream_associate(pip, ip); if (error < 0) return -error; @@ -1208,7 +1213,7 @@ xfs_ialloc( } /* fall through */ case S_IFDIR: - if (pip->i_d.di_flags & XFS_DIFLAG_ANY) { + if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { uint di_flags = 0; if ((mode & S_IFMT) == S_IFDIR) { -- cgit v1.2.3