Commit b11f94d5 authored by David Chinner's avatar David Chinner Committed by Tim Shimmin

[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: default avatarDavid Chinner <dgc@sgi.com>
Signed-off-by: default avatarTim Shimmin <tes@sgi.com>
parent 2a82b8be
...@@ -65,7 +65,6 @@ kmem_zone_t *qm_dqtrxzone; ...@@ -65,7 +65,6 @@ kmem_zone_t *qm_dqtrxzone;
static struct shrinker *xfs_qm_shaker; static struct shrinker *xfs_qm_shaker;
static cred_t xfs_zerocr; 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_init(xfs_dqlist_t *, char *, int);
STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); STATIC void xfs_qm_list_destroy(xfs_dqlist_t *);
...@@ -1415,7 +1414,7 @@ xfs_qm_qino_alloc( ...@@ -1415,7 +1414,7 @@ xfs_qm_qino_alloc(
return error; 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_zerocr, 0, 1, ip, &committed))) {
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
XFS_TRANS_ABORT); XFS_TRANS_ABORT);
......
...@@ -1078,6 +1078,11 @@ xfs_iread_extents( ...@@ -1078,6 +1078,11 @@ xfs_iread_extents(
* also returns the [locked] bp pointing to the head of the freelist * also returns the [locked] bp pointing to the head of the freelist
* as ialloc_context. The caller should hold this buffer across * as ialloc_context. The caller should hold this buffer across
* the commit and pass it back into this routine on the second call. * 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 int
xfs_ialloc( xfs_ialloc(
...@@ -1103,7 +1108,7 @@ xfs_ialloc( ...@@ -1103,7 +1108,7 @@ xfs_ialloc(
* Call the space management code to pick * Call the space management code to pick
* the on-disk inode to be allocated. * 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); ialloc_context, call_again, &ino);
if (error != 0) { if (error != 0) {
return error; return error;
...@@ -1157,7 +1162,7 @@ xfs_ialloc( ...@@ -1157,7 +1162,7 @@ xfs_ialloc(
if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1))
xfs_bump_ino_vers2(tp, ip); 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; ip->i_d.di_gid = pip->i_d.di_gid;
if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) {
ip->i_d.di_mode |= S_ISGID; ip->i_d.di_mode |= S_ISGID;
...@@ -1199,7 +1204,7 @@ xfs_ialloc( ...@@ -1199,7 +1204,7 @@ xfs_ialloc(
flags |= XFS_ILOG_DEV; flags |= XFS_ILOG_DEV;
break; break;
case S_IFREG: case S_IFREG:
if (xfs_inode_is_filestream(pip)) { if (pip && xfs_inode_is_filestream(pip)) {
error = xfs_filestream_associate(pip, ip); error = xfs_filestream_associate(pip, ip);
if (error < 0) if (error < 0)
return -error; return -error;
...@@ -1208,7 +1213,7 @@ xfs_ialloc( ...@@ -1208,7 +1213,7 @@ xfs_ialloc(
} }
/* fall through */ /* fall through */
case S_IFDIR: 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; uint di_flags = 0;
if ((mode & S_IFMT) == S_IFDIR) { if ((mode & S_IFMT) == S_IFDIR) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment