Commit b11f94d537e6b69f13770143fd7ded3d09fdbaab

Authored by David Chinner
Committed by Tim Shimmin
1 parent 2a82b8be8a

[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);
... ... @@ -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) {