diff options
author | Nathan Scott <nathans@sgi.com> | 2006-03-13 21:33:36 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-03-13 21:33:36 -0500 |
commit | 220b5284139be6ecbc39b353fd76f0923eccc3d6 (patch) | |
tree | 86ab8c671631a109690d6589a19d9774d8bed18f /fs/xfs/linux-2.6/xfs_ioctl.c | |
parent | 9b94c2eddf407ad8faa5672ffa691e2076167564 (diff) |
[XFS] Dynamically allocate vattr in places it makes sense to do so, to
reduce stack use. Also re-use vattr in some places so that multiple
copies are not held on-stack.
SGI-PV: 947312
SGI-Modid: xfs-linux-melb:xfs-kern:25369a
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 128 |
1 files changed, 76 insertions, 52 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 4db47790415c..f182721ec9a2 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -1160,105 +1160,129 @@ xfs_ioc_xattr( | |||
1160 | void __user *arg) | 1160 | void __user *arg) |
1161 | { | 1161 | { |
1162 | struct fsxattr fa; | 1162 | struct fsxattr fa; |
1163 | vattr_t va; | 1163 | struct vattr *vattr; |
1164 | int error; | 1164 | int error = 0; |
1165 | int attr_flags; | 1165 | int attr_flags; |
1166 | unsigned int flags; | 1166 | unsigned int flags; |
1167 | 1167 | ||
1168 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); | ||
1169 | if (unlikely(!vattr)) | ||
1170 | return -ENOMEM; | ||
1171 | |||
1168 | switch (cmd) { | 1172 | switch (cmd) { |
1169 | case XFS_IOC_FSGETXATTR: { | 1173 | case XFS_IOC_FSGETXATTR: { |
1170 | va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ | 1174 | vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ |
1171 | XFS_AT_NEXTENTS | XFS_AT_PROJID; | 1175 | XFS_AT_NEXTENTS | XFS_AT_PROJID; |
1172 | VOP_GETATTR(vp, &va, 0, NULL, error); | 1176 | VOP_GETATTR(vp, vattr, 0, NULL, error); |
1173 | if (error) | 1177 | if (unlikely(error)) { |
1174 | return -error; | 1178 | error = -error; |
1179 | break; | ||
1180 | } | ||
1175 | 1181 | ||
1176 | fa.fsx_xflags = va.va_xflags; | 1182 | fa.fsx_xflags = vattr->va_xflags; |
1177 | fa.fsx_extsize = va.va_extsize; | 1183 | fa.fsx_extsize = vattr->va_extsize; |
1178 | fa.fsx_nextents = va.va_nextents; | 1184 | fa.fsx_nextents = vattr->va_nextents; |
1179 | fa.fsx_projid = va.va_projid; | 1185 | fa.fsx_projid = vattr->va_projid; |
1180 | 1186 | ||
1181 | if (copy_to_user(arg, &fa, sizeof(fa))) | 1187 | if (copy_to_user(arg, &fa, sizeof(fa))) { |
1182 | return -XFS_ERROR(EFAULT); | 1188 | error = -EFAULT; |
1183 | return 0; | 1189 | break; |
1190 | } | ||
1191 | break; | ||
1184 | } | 1192 | } |
1185 | 1193 | ||
1186 | case XFS_IOC_FSSETXATTR: { | 1194 | case XFS_IOC_FSSETXATTR: { |
1187 | if (copy_from_user(&fa, arg, sizeof(fa))) | 1195 | if (copy_from_user(&fa, arg, sizeof(fa))) { |
1188 | return -XFS_ERROR(EFAULT); | 1196 | error = -EFAULT; |
1197 | break; | ||
1198 | } | ||
1189 | 1199 | ||
1190 | attr_flags = 0; | 1200 | attr_flags = 0; |
1191 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) | 1201 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
1192 | attr_flags |= ATTR_NONBLOCK; | 1202 | attr_flags |= ATTR_NONBLOCK; |
1193 | 1203 | ||
1194 | va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID; | 1204 | vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID; |
1195 | va.va_xflags = fa.fsx_xflags; | 1205 | vattr->va_xflags = fa.fsx_xflags; |
1196 | va.va_extsize = fa.fsx_extsize; | 1206 | vattr->va_extsize = fa.fsx_extsize; |
1197 | va.va_projid = fa.fsx_projid; | 1207 | vattr->va_projid = fa.fsx_projid; |
1198 | 1208 | ||
1199 | VOP_SETATTR(vp, &va, attr_flags, NULL, error); | 1209 | VOP_SETATTR(vp, vattr, attr_flags, NULL, error); |
1200 | if (!error) | 1210 | if (likely(!error)) |
1201 | vn_revalidate(vp); /* update Linux inode flags */ | 1211 | __vn_revalidate(vp, vattr); /* update flags */ |
1202 | return -error; | 1212 | error = -error; |
1213 | break; | ||
1203 | } | 1214 | } |
1204 | 1215 | ||
1205 | case XFS_IOC_FSGETXATTRA: { | 1216 | case XFS_IOC_FSGETXATTRA: { |
1206 | va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ | 1217 | vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ |
1207 | XFS_AT_ANEXTENTS | XFS_AT_PROJID; | 1218 | XFS_AT_ANEXTENTS | XFS_AT_PROJID; |
1208 | VOP_GETATTR(vp, &va, 0, NULL, error); | 1219 | VOP_GETATTR(vp, vattr, 0, NULL, error); |
1209 | if (error) | 1220 | if (unlikely(error)) { |
1210 | return -error; | 1221 | error = -error; |
1222 | break; | ||
1223 | } | ||
1211 | 1224 | ||
1212 | fa.fsx_xflags = va.va_xflags; | 1225 | fa.fsx_xflags = vattr->va_xflags; |
1213 | fa.fsx_extsize = va.va_extsize; | 1226 | fa.fsx_extsize = vattr->va_extsize; |
1214 | fa.fsx_nextents = va.va_anextents; | 1227 | fa.fsx_nextents = vattr->va_anextents; |
1215 | fa.fsx_projid = va.va_projid; | 1228 | fa.fsx_projid = vattr->va_projid; |
1216 | 1229 | ||
1217 | if (copy_to_user(arg, &fa, sizeof(fa))) | 1230 | if (copy_to_user(arg, &fa, sizeof(fa))) { |
1218 | return -XFS_ERROR(EFAULT); | 1231 | error = -EFAULT; |
1219 | return 0; | 1232 | break; |
1233 | } | ||
1234 | break; | ||
1220 | } | 1235 | } |
1221 | 1236 | ||
1222 | case XFS_IOC_GETXFLAGS: { | 1237 | case XFS_IOC_GETXFLAGS: { |
1223 | flags = xfs_di2lxflags(ip->i_d.di_flags); | 1238 | flags = xfs_di2lxflags(ip->i_d.di_flags); |
1224 | if (copy_to_user(arg, &flags, sizeof(flags))) | 1239 | if (copy_to_user(arg, &flags, sizeof(flags))) |
1225 | return -XFS_ERROR(EFAULT); | 1240 | error = -EFAULT; |
1226 | return 0; | 1241 | break; |
1227 | } | 1242 | } |
1228 | 1243 | ||
1229 | case XFS_IOC_SETXFLAGS: { | 1244 | case XFS_IOC_SETXFLAGS: { |
1230 | if (copy_from_user(&flags, arg, sizeof(flags))) | 1245 | if (copy_from_user(&flags, arg, sizeof(flags))) { |
1231 | return -XFS_ERROR(EFAULT); | 1246 | error = -EFAULT; |
1247 | break; | ||
1248 | } | ||
1232 | 1249 | ||
1233 | if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \ | 1250 | if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \ |
1234 | LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \ | 1251 | LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \ |
1235 | LINUX_XFLAG_SYNC)) | 1252 | LINUX_XFLAG_SYNC)) { |
1236 | return -XFS_ERROR(EOPNOTSUPP); | 1253 | error = -EOPNOTSUPP; |
1254 | break; | ||
1255 | } | ||
1237 | 1256 | ||
1238 | attr_flags = 0; | 1257 | attr_flags = 0; |
1239 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) | 1258 | if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) |
1240 | attr_flags |= ATTR_NONBLOCK; | 1259 | attr_flags |= ATTR_NONBLOCK; |
1241 | 1260 | ||
1242 | va.va_mask = XFS_AT_XFLAGS; | 1261 | vattr->va_mask = XFS_AT_XFLAGS; |
1243 | va.va_xflags = xfs_merge_ioc_xflags(flags, | 1262 | vattr->va_xflags = xfs_merge_ioc_xflags(flags, |
1244 | xfs_ip2xflags(ip)); | 1263 | xfs_ip2xflags(ip)); |
1245 | 1264 | ||
1246 | VOP_SETATTR(vp, &va, attr_flags, NULL, error); | 1265 | VOP_SETATTR(vp, vattr, attr_flags, NULL, error); |
1247 | if (!error) | 1266 | if (likely(!error)) |
1248 | vn_revalidate(vp); /* update Linux inode flags */ | 1267 | __vn_revalidate(vp, vattr); /* update flags */ |
1249 | return -error; | 1268 | error = -error; |
1269 | break; | ||
1250 | } | 1270 | } |
1251 | 1271 | ||
1252 | case XFS_IOC_GETVERSION: { | 1272 | case XFS_IOC_GETVERSION: { |
1253 | flags = LINVFS_GET_IP(vp)->i_generation; | 1273 | flags = LINVFS_GET_IP(vp)->i_generation; |
1254 | if (copy_to_user(arg, &flags, sizeof(flags))) | 1274 | if (copy_to_user(arg, &flags, sizeof(flags))) |
1255 | return -XFS_ERROR(EFAULT); | 1275 | error = -EFAULT; |
1256 | return 0; | 1276 | break; |
1257 | } | 1277 | } |
1258 | 1278 | ||
1259 | default: | 1279 | default: |
1260 | return -ENOTTY; | 1280 | error = -ENOTTY; |
1281 | break; | ||
1261 | } | 1282 | } |
1283 | |||
1284 | kfree(vattr); | ||
1285 | return error; | ||
1262 | } | 1286 | } |
1263 | 1287 | ||
1264 | STATIC int | 1288 | STATIC int |