Commit b11f94d537e6b69f13770143fd7ded3d09fdbaab
Committed by
Tim Shimmin
1 parent
2a82b8be8a
Exists in
master
and in
4 other branches
[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 <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
Showing 2 changed files with 10 additions and 6 deletions Side-by-side Diff
fs/xfs/quota/xfs_qm.c
... | ... | @@ -65,7 +65,6 @@ |
65 | 65 | static struct shrinker *xfs_qm_shaker; |
66 | 66 | |
67 | 67 | static cred_t xfs_zerocr; |
68 | -static xfs_inode_t xfs_zeroino; | |
69 | 68 | |
70 | 69 | STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); |
71 | 70 | STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); |
... | ... | @@ -1415,7 +1414,7 @@ |
1415 | 1414 | return error; |
1416 | 1415 | } |
1417 | 1416 | |
1418 | - if ((error = xfs_dir_ialloc(&tp, &xfs_zeroino, S_IFREG, 1, 0, | |
1417 | + if ((error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, | |
1419 | 1418 | &xfs_zerocr, 0, 1, ip, &committed))) { |
1420 | 1419 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | |
1421 | 1420 | XFS_TRANS_ABORT); |
fs/xfs/xfs_inode.c
... | ... | @@ -1078,6 +1078,11 @@ |
1078 | 1078 | * also returns the [locked] bp pointing to the head of the freelist |
1079 | 1079 | * as ialloc_context. The caller should hold this buffer across |
1080 | 1080 | * the commit and pass it back into this routine on the second call. |
1081 | + * | |
1082 | + * If we are allocating quota inodes, we do not have a parent inode | |
1083 | + * to attach to or associate with (i.e. pip == NULL) because they | |
1084 | + * are not linked into the directory structure - they are attached | |
1085 | + * directly to the superblock - and so have no parent. | |
1081 | 1086 | */ |
1082 | 1087 | int |
1083 | 1088 | xfs_ialloc( |
... | ... | @@ -1103,7 +1108,7 @@ |
1103 | 1108 | * Call the space management code to pick |
1104 | 1109 | * the on-disk inode to be allocated. |
1105 | 1110 | */ |
1106 | - error = xfs_dialloc(tp, pip->i_ino, mode, okalloc, | |
1111 | + error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, | |
1107 | 1112 | ialloc_context, call_again, &ino); |
1108 | 1113 | if (error != 0) { |
1109 | 1114 | return error; |
... | ... | @@ -1157,7 +1162,7 @@ |
1157 | 1162 | if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) |
1158 | 1163 | xfs_bump_ino_vers2(tp, ip); |
1159 | 1164 | |
1160 | - if (XFS_INHERIT_GID(pip, vp->v_vfsp)) { | |
1165 | + if (pip && XFS_INHERIT_GID(pip, vp->v_vfsp)) { | |
1161 | 1166 | ip->i_d.di_gid = pip->i_d.di_gid; |
1162 | 1167 | if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { |
1163 | 1168 | ip->i_d.di_mode |= S_ISGID; |
... | ... | @@ -1199,7 +1204,7 @@ |
1199 | 1204 | flags |= XFS_ILOG_DEV; |
1200 | 1205 | break; |
1201 | 1206 | case S_IFREG: |
1202 | - if (xfs_inode_is_filestream(pip)) { | |
1207 | + if (pip && xfs_inode_is_filestream(pip)) { | |
1203 | 1208 | error = xfs_filestream_associate(pip, ip); |
1204 | 1209 | if (error < 0) |
1205 | 1210 | return -error; |
... | ... | @@ -1208,7 +1213,7 @@ |
1208 | 1213 | } |
1209 | 1214 | /* fall through */ |
1210 | 1215 | case S_IFDIR: |
1211 | - if (pip->i_d.di_flags & XFS_DIFLAG_ANY) { | |
1216 | + if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { | |
1212 | 1217 | uint di_flags = 0; |
1213 | 1218 | |
1214 | 1219 | if ((mode & S_IFMT) == S_IFDIR) { |