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 | |
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')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 13 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 128 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 180 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vnode.c | 29 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vnode.h | 1 |
5 files changed, 209 insertions, 142 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 269995ddfbdf..ce8fe40e1628 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -420,7 +420,7 @@ linvfs_file_mmap( | |||
420 | { | 420 | { |
421 | struct inode *ip = filp->f_dentry->d_inode; | 421 | struct inode *ip = filp->f_dentry->d_inode; |
422 | vnode_t *vp = LINVFS_GET_VP(ip); | 422 | vnode_t *vp = LINVFS_GET_VP(ip); |
423 | vattr_t va = { .va_mask = XFS_AT_UPDATIME }; | 423 | vattr_t *vattr; |
424 | int error; | 424 | int error; |
425 | 425 | ||
426 | vma->vm_ops = &linvfs_file_vm_ops; | 426 | vma->vm_ops = &linvfs_file_vm_ops; |
@@ -431,9 +431,14 @@ linvfs_file_mmap( | |||
431 | } | 431 | } |
432 | #endif /* CONFIG_XFS_DMAPI */ | 432 | #endif /* CONFIG_XFS_DMAPI */ |
433 | 433 | ||
434 | VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error); | 434 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); |
435 | if (!error) | 435 | if (unlikely(!vattr)) |
436 | vn_revalidate(vp); /* update Linux inode flags */ | 436 | return -ENOMEM; |
437 | vattr->va_mask = XFS_AT_UPDATIME; | ||
438 | VOP_SETATTR(vp, vattr, XFS_AT_UPDATIME, NULL, error); | ||
439 | if (likely(!error)) | ||
440 | __vn_revalidate(vp, vattr); /* update flags */ | ||
441 | kfree(vattr); | ||
437 | return 0; | 442 | return 0; |
438 | } | 443 | } |
439 | 444 | ||
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 |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index d7f6f2d8ac8e..b1219195c6e2 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -198,22 +198,22 @@ xfs_ichgtime_fast( | |||
198 | * Pull the link count and size up from the xfs inode to the linux inode | 198 | * Pull the link count and size up from the xfs inode to the linux inode |
199 | */ | 199 | */ |
200 | STATIC void | 200 | STATIC void |
201 | validate_fields( | 201 | __linvfs_validate_fields( |
202 | struct inode *ip) | 202 | struct inode *ip, |
203 | struct vattr *vattr) | ||
203 | { | 204 | { |
204 | vnode_t *vp = LINVFS_GET_VP(ip); | 205 | vnode_t *vp = LINVFS_GET_VP(ip); |
205 | vattr_t va; | ||
206 | int error; | 206 | int error; |
207 | 207 | ||
208 | va.va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; | 208 | vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; |
209 | VOP_GETATTR(vp, &va, ATTR_LAZY, NULL, error); | 209 | VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error); |
210 | if (likely(!error)) { | 210 | if (likely(!error)) { |
211 | ip->i_nlink = va.va_nlink; | 211 | ip->i_nlink = vattr->va_nlink; |
212 | ip->i_blocks = va.va_nblocks; | 212 | ip->i_blocks = vattr->va_nblocks; |
213 | 213 | ||
214 | /* we're under i_mutex so i_size can't change under us */ | 214 | /* we're under i_sem so i_size can't change under us */ |
215 | if (i_size_read(ip) != va.va_size) | 215 | if (i_size_read(ip) != vattr->va_size) |
216 | i_size_write(ip, va.va_size); | 216 | i_size_write(ip, vattr->va_size); |
217 | } | 217 | } |
218 | } | 218 | } |
219 | 219 | ||
@@ -224,7 +224,7 @@ validate_fields( | |||
224 | * inode, of course, such that log replay can't cause these to be lost). | 224 | * inode, of course, such that log replay can't cause these to be lost). |
225 | */ | 225 | */ |
226 | STATIC int | 226 | STATIC int |
227 | linvfs_init_security( | 227 | __linvfs_init_security( |
228 | struct vnode *vp, | 228 | struct vnode *vp, |
229 | struct inode *dir) | 229 | struct inode *dir) |
230 | { | 230 | { |
@@ -257,23 +257,23 @@ linvfs_init_security( | |||
257 | * XXX(hch): nfsd is broken, better fix it instead. | 257 | * XXX(hch): nfsd is broken, better fix it instead. |
258 | */ | 258 | */ |
259 | STATIC inline int | 259 | STATIC inline int |
260 | has_fs_struct(struct task_struct *task) | 260 | __linvfs_has_fs_struct(struct task_struct *task) |
261 | { | 261 | { |
262 | return (task->fs != init_task.fs); | 262 | return (task->fs != init_task.fs); |
263 | } | 263 | } |
264 | 264 | ||
265 | STATIC inline void | 265 | STATIC inline void |
266 | cleanup_inode( | 266 | __linvfs_cleanup_inode( |
267 | vnode_t *dvp, | 267 | vnode_t *dvp, |
268 | vnode_t *vp, | 268 | vnode_t *vp, |
269 | struct dentry *dentry, | 269 | struct dentry *dentry, |
270 | int mode) | 270 | int mode) |
271 | { | 271 | { |
272 | struct dentry teardown = {}; | 272 | struct dentry teardown = {}; |
273 | int err2; | 273 | int error; |
274 | 274 | ||
275 | /* Oh, the horror. | 275 | /* Oh, the horror. |
276 | * If we can't add the ACL or we fail in | 276 | * If we can't add the ACL or we fail in |
277 | * linvfs_init_security we must back out. | 277 | * linvfs_init_security we must back out. |
278 | * ENOSPC can hit here, among other things. | 278 | * ENOSPC can hit here, among other things. |
279 | */ | 279 | */ |
@@ -281,9 +281,9 @@ cleanup_inode( | |||
281 | teardown.d_name = dentry->d_name; | 281 | teardown.d_name = dentry->d_name; |
282 | 282 | ||
283 | if (S_ISDIR(mode)) | 283 | if (S_ISDIR(mode)) |
284 | VOP_RMDIR(dvp, &teardown, NULL, err2); | 284 | VOP_RMDIR(dvp, &teardown, NULL, error); |
285 | else | 285 | else |
286 | VOP_REMOVE(dvp, &teardown, NULL, err2); | 286 | VOP_REMOVE(dvp, &teardown, NULL, error); |
287 | VN_RELE(vp); | 287 | VN_RELE(vp); |
288 | } | 288 | } |
289 | 289 | ||
@@ -295,7 +295,7 @@ linvfs_mknod( | |||
295 | dev_t rdev) | 295 | dev_t rdev) |
296 | { | 296 | { |
297 | struct inode *ip; | 297 | struct inode *ip; |
298 | vattr_t va; | 298 | vattr_t *vattr; |
299 | vnode_t *vp = NULL, *dvp = LINVFS_GET_VP(dir); | 299 | vnode_t *vp = NULL, *dvp = LINVFS_GET_VP(dir); |
300 | xfs_acl_t *default_acl = NULL; | 300 | xfs_acl_t *default_acl = NULL; |
301 | attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; | 301 | attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; |
@@ -305,70 +305,76 @@ linvfs_mknod( | |||
305 | * Irix uses Missed'em'V split, but doesn't want to see | 305 | * Irix uses Missed'em'V split, but doesn't want to see |
306 | * the upper 5 bits of (14bit) major. | 306 | * the upper 5 bits of (14bit) major. |
307 | */ | 307 | */ |
308 | if (!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff) | 308 | if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)) |
309 | return -EINVAL; | 309 | return -EINVAL; |
310 | 310 | ||
311 | if (test_default_acl && test_default_acl(dvp)) { | 311 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); |
312 | if (!_ACL_ALLOC(default_acl)) | 312 | if (unlikely(!vattr)) |
313 | return -ENOMEM; | ||
314 | |||
315 | if (unlikely(test_default_acl && test_default_acl(dvp))) { | ||
316 | if (!_ACL_ALLOC(default_acl)) { | ||
317 | kfree(vattr); | ||
313 | return -ENOMEM; | 318 | return -ENOMEM; |
319 | } | ||
314 | if (!_ACL_GET_DEFAULT(dvp, default_acl)) { | 320 | if (!_ACL_GET_DEFAULT(dvp, default_acl)) { |
315 | _ACL_FREE(default_acl); | 321 | _ACL_FREE(default_acl); |
316 | default_acl = NULL; | 322 | default_acl = NULL; |
317 | } | 323 | } |
318 | } | 324 | } |
319 | 325 | ||
320 | if (IS_POSIXACL(dir) && !default_acl && has_fs_struct(current)) | 326 | if (IS_POSIXACL(dir) && !default_acl && __linvfs_has_fs_struct(current)) |
321 | mode &= ~current->fs->umask; | 327 | mode &= ~current->fs->umask; |
322 | 328 | ||
323 | memset(&va, 0, sizeof(va)); | 329 | memset(vattr, 0, sizeof(*vattr)); |
324 | va.va_mask = XFS_AT_TYPE|XFS_AT_MODE; | 330 | vattr->va_mask = XFS_AT_TYPE|XFS_AT_MODE; |
325 | va.va_mode = mode; | 331 | vattr->va_mode = mode; |
326 | 332 | ||
327 | switch (mode & S_IFMT) { | 333 | switch (mode & S_IFMT) { |
328 | case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: | 334 | case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: |
329 | va.va_rdev = sysv_encode_dev(rdev); | 335 | vattr->va_rdev = sysv_encode_dev(rdev); |
330 | va.va_mask |= XFS_AT_RDEV; | 336 | vattr->va_mask |= XFS_AT_RDEV; |
331 | /*FALLTHROUGH*/ | 337 | /*FALLTHROUGH*/ |
332 | case S_IFREG: | 338 | case S_IFREG: |
333 | VOP_CREATE(dvp, dentry, &va, &vp, NULL, error); | 339 | VOP_CREATE(dvp, dentry, vattr, &vp, NULL, error); |
334 | break; | 340 | break; |
335 | case S_IFDIR: | 341 | case S_IFDIR: |
336 | VOP_MKDIR(dvp, dentry, &va, &vp, NULL, error); | 342 | VOP_MKDIR(dvp, dentry, vattr, &vp, NULL, error); |
337 | break; | 343 | break; |
338 | default: | 344 | default: |
339 | error = EINVAL; | 345 | error = EINVAL; |
340 | break; | 346 | break; |
341 | } | 347 | } |
342 | 348 | ||
343 | if (!error) | 349 | if (unlikely(!error)) { |
344 | { | 350 | error = __linvfs_init_security(vp, dir); |
345 | error = linvfs_init_security(vp, dir); | ||
346 | if (error) | 351 | if (error) |
347 | cleanup_inode(dvp, vp, dentry, mode); | 352 | __linvfs_cleanup_inode(dvp, vp, dentry, mode); |
348 | } | 353 | } |
349 | 354 | ||
350 | if (default_acl) { | 355 | if (unlikely(default_acl)) { |
351 | if (!error) { | 356 | if (!error) { |
352 | error = _ACL_INHERIT(vp, &va, default_acl); | 357 | error = _ACL_INHERIT(vp, vattr, default_acl); |
353 | if (!error) | 358 | if (!error) |
354 | VMODIFY(vp); | 359 | VMODIFY(vp); |
355 | else | 360 | else |
356 | cleanup_inode(dvp, vp, dentry, mode); | 361 | __linvfs_cleanup_inode(dvp, vp, dentry, mode); |
357 | } | 362 | } |
358 | _ACL_FREE(default_acl); | 363 | _ACL_FREE(default_acl); |
359 | } | 364 | } |
360 | 365 | ||
361 | if (!error) { | 366 | if (likely(!error)) { |
362 | ASSERT(vp); | 367 | ASSERT(vp); |
363 | ip = LINVFS_GET_IP(vp); | 368 | ip = LINVFS_GET_IP(vp); |
364 | 369 | ||
365 | if (S_ISCHR(mode) || S_ISBLK(mode)) | 370 | if (S_ISCHR(mode) || S_ISBLK(mode)) |
366 | ip->i_rdev = rdev; | 371 | ip->i_rdev = rdev; |
367 | else if (S_ISDIR(mode)) | 372 | else if (S_ISDIR(mode)) |
368 | validate_fields(ip); | 373 | __linvfs_validate_fields(ip, vattr); |
369 | d_instantiate(dentry, ip); | 374 | d_instantiate(dentry, ip); |
370 | validate_fields(dir); | 375 | __linvfs_validate_fields(dir, vattr); |
371 | } | 376 | } |
377 | kfree(vattr); | ||
372 | return -error; | 378 | return -error; |
373 | } | 379 | } |
374 | 380 | ||
@@ -423,22 +429,28 @@ linvfs_link( | |||
423 | struct inode *ip; /* inode of guy being linked to */ | 429 | struct inode *ip; /* inode of guy being linked to */ |
424 | vnode_t *tdvp; /* target directory for new name/link */ | 430 | vnode_t *tdvp; /* target directory for new name/link */ |
425 | vnode_t *vp; /* vp of name being linked */ | 431 | vnode_t *vp; /* vp of name being linked */ |
432 | vattr_t *vattr; | ||
426 | int error; | 433 | int error; |
427 | 434 | ||
428 | ip = old_dentry->d_inode; /* inode being linked to */ | 435 | ip = old_dentry->d_inode; /* inode being linked to */ |
429 | if (S_ISDIR(ip->i_mode)) | 436 | if (S_ISDIR(ip->i_mode)) |
430 | return -EPERM; | 437 | return -EPERM; |
431 | 438 | ||
439 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); | ||
440 | if (unlikely(!vattr)) | ||
441 | return -ENOMEM; | ||
442 | |||
432 | tdvp = LINVFS_GET_VP(dir); | 443 | tdvp = LINVFS_GET_VP(dir); |
433 | vp = LINVFS_GET_VP(ip); | 444 | vp = LINVFS_GET_VP(ip); |
434 | 445 | ||
435 | VOP_LINK(tdvp, vp, dentry, NULL, error); | 446 | VOP_LINK(tdvp, vp, dentry, NULL, error); |
436 | if (!error) { | 447 | if (likely(!error)) { |
437 | VMODIFY(tdvp); | 448 | VMODIFY(tdvp); |
438 | VN_HOLD(vp); | 449 | VN_HOLD(vp); |
439 | validate_fields(ip); | 450 | __linvfs_validate_fields(ip, vattr); |
440 | d_instantiate(dentry, ip); | 451 | d_instantiate(dentry, ip); |
441 | } | 452 | } |
453 | kfree(vattr); | ||
442 | return -error; | 454 | return -error; |
443 | } | 455 | } |
444 | 456 | ||
@@ -449,17 +461,22 @@ linvfs_unlink( | |||
449 | { | 461 | { |
450 | struct inode *inode; | 462 | struct inode *inode; |
451 | vnode_t *dvp; /* directory containing name to remove */ | 463 | vnode_t *dvp; /* directory containing name to remove */ |
464 | vattr_t *vattr; | ||
452 | int error; | 465 | int error; |
453 | 466 | ||
467 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); | ||
468 | if (unlikely(!vattr)) | ||
469 | return -ENOMEM; | ||
470 | |||
454 | inode = dentry->d_inode; | 471 | inode = dentry->d_inode; |
455 | dvp = LINVFS_GET_VP(dir); | 472 | dvp = LINVFS_GET_VP(dir); |
456 | 473 | ||
457 | VOP_REMOVE(dvp, dentry, NULL, error); | 474 | VOP_REMOVE(dvp, dentry, NULL, error); |
458 | if (!error) { | 475 | if (likely(!error)) { |
459 | validate_fields(dir); /* For size only */ | 476 | __linvfs_validate_fields(dir, vattr); /* size needs update */ |
460 | validate_fields(inode); | 477 | __linvfs_validate_fields(inode, vattr); |
461 | } | 478 | } |
462 | 479 | kfree(vattr); | |
463 | return -error; | 480 | return -error; |
464 | } | 481 | } |
465 | 482 | ||
@@ -470,7 +487,7 @@ linvfs_symlink( | |||
470 | const char *symname) | 487 | const char *symname) |
471 | { | 488 | { |
472 | struct inode *ip; | 489 | struct inode *ip; |
473 | vattr_t va; | 490 | vattr_t *vattr; |
474 | vnode_t *dvp; /* directory containing name of symlink */ | 491 | vnode_t *dvp; /* directory containing name of symlink */ |
475 | vnode_t *cvp; /* used to lookup symlink to put in dentry */ | 492 | vnode_t *cvp; /* used to lookup symlink to put in dentry */ |
476 | int error; | 493 | int error; |
@@ -478,22 +495,27 @@ linvfs_symlink( | |||
478 | dvp = LINVFS_GET_VP(dir); | 495 | dvp = LINVFS_GET_VP(dir); |
479 | cvp = NULL; | 496 | cvp = NULL; |
480 | 497 | ||
481 | memset(&va, 0, sizeof(va)); | 498 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); |
482 | va.va_mode = S_IFLNK | | 499 | if (unlikely(!vattr)) |
500 | return -ENOMEM; | ||
501 | |||
502 | memset(vattr, 0, sizeof(*vattr)); | ||
503 | vattr->va_mode = S_IFLNK | | ||
483 | (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); | 504 | (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); |
484 | va.va_mask = XFS_AT_TYPE|XFS_AT_MODE; | 505 | vattr->va_mask = XFS_AT_TYPE|XFS_AT_MODE; |
485 | 506 | ||
486 | error = 0; | 507 | error = 0; |
487 | VOP_SYMLINK(dvp, dentry, &va, (char *)symname, &cvp, NULL, error); | 508 | VOP_SYMLINK(dvp, dentry, vattr, (char *)symname, &cvp, NULL, error); |
488 | if (likely(!error && cvp)) { | 509 | if (likely(!error && cvp)) { |
489 | error = linvfs_init_security(cvp, dir); | 510 | error = __linvfs_init_security(cvp, dir); |
490 | if (likely(!error)) { | 511 | if (likely(!error)) { |
491 | ip = LINVFS_GET_IP(cvp); | 512 | ip = LINVFS_GET_IP(cvp); |
492 | d_instantiate(dentry, ip); | 513 | d_instantiate(dentry, ip); |
493 | validate_fields(dir); | 514 | __linvfs_validate_fields(dir, vattr); |
494 | validate_fields(ip); | 515 | __linvfs_validate_fields(ip, vattr); |
495 | } | 516 | } |
496 | } | 517 | } |
518 | kfree(vattr); | ||
497 | return -error; | 519 | return -error; |
498 | } | 520 | } |
499 | 521 | ||
@@ -504,13 +526,19 @@ linvfs_rmdir( | |||
504 | { | 526 | { |
505 | struct inode *inode = dentry->d_inode; | 527 | struct inode *inode = dentry->d_inode; |
506 | vnode_t *dvp = LINVFS_GET_VP(dir); | 528 | vnode_t *dvp = LINVFS_GET_VP(dir); |
529 | vattr_t *vattr; | ||
507 | int error; | 530 | int error; |
508 | 531 | ||
532 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); | ||
533 | if (unlikely(!vattr)) | ||
534 | return -ENOMEM; | ||
535 | |||
509 | VOP_RMDIR(dvp, dentry, NULL, error); | 536 | VOP_RMDIR(dvp, dentry, NULL, error); |
510 | if (!error) { | 537 | if (likely(!error)) { |
511 | validate_fields(inode); | 538 | __linvfs_validate_fields(inode, vattr); |
512 | validate_fields(dir); | 539 | __linvfs_validate_fields(dir, vattr); |
513 | } | 540 | } |
541 | kfree(vattr); | ||
514 | return -error; | 542 | return -error; |
515 | } | 543 | } |
516 | 544 | ||
@@ -524,22 +552,26 @@ linvfs_rename( | |||
524 | struct inode *new_inode = ndentry->d_inode; | 552 | struct inode *new_inode = ndentry->d_inode; |
525 | vnode_t *fvp; /* from directory */ | 553 | vnode_t *fvp; /* from directory */ |
526 | vnode_t *tvp; /* target directory */ | 554 | vnode_t *tvp; /* target directory */ |
555 | vattr_t *vattr; | ||
527 | int error; | 556 | int error; |
528 | 557 | ||
558 | vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); | ||
559 | if (unlikely(!vattr)) | ||
560 | return -ENOMEM; | ||
561 | |||
529 | fvp = LINVFS_GET_VP(odir); | 562 | fvp = LINVFS_GET_VP(odir); |
530 | tvp = LINVFS_GET_VP(ndir); | 563 | tvp = LINVFS_GET_VP(ndir); |
531 | 564 | ||
532 | VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error); | 565 | VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error); |
533 | if (error) | 566 | if (likely(!error)) { |
534 | return -error; | 567 | if (new_inode) |
535 | 568 | __linvfs_validate_fields(new_inode, vattr); | |
536 | if (new_inode) | 569 | __linvfs_validate_fields(odir, vattr); |
537 | validate_fields(new_inode); | 570 | if (ndir != odir) |
538 | 571 | __linvfs_validate_fields(ndir, vattr); | |
539 | validate_fields(odir); | 572 | } |
540 | if (ndir != odir) | 573 | kfree(vattr); |
541 | validate_fields(ndir); | 574 | return -error; |
542 | return 0; | ||
543 | } | 575 | } |
544 | 576 | ||
545 | /* | 577 | /* |
@@ -653,11 +685,10 @@ linvfs_setattr( | |||
653 | struct inode *inode = dentry->d_inode; | 685 | struct inode *inode = dentry->d_inode; |
654 | unsigned int ia_valid = attr->ia_valid; | 686 | unsigned int ia_valid = attr->ia_valid; |
655 | vnode_t *vp = LINVFS_GET_VP(inode); | 687 | vnode_t *vp = LINVFS_GET_VP(inode); |
656 | vattr_t vattr; | 688 | vattr_t vattr = { 0 }; |
657 | int flags = 0; | 689 | int flags = 0; |
658 | int error; | 690 | int error; |
659 | 691 | ||
660 | memset(&vattr, 0, sizeof(vattr_t)); | ||
661 | if (ia_valid & ATTR_UID) { | 692 | if (ia_valid & ATTR_UID) { |
662 | vattr.va_mask |= XFS_AT_UID; | 693 | vattr.va_mask |= XFS_AT_UID; |
663 | vattr.va_uid = attr->ia_uid; | 694 | vattr.va_uid = attr->ia_uid; |
@@ -699,10 +730,9 @@ linvfs_setattr( | |||
699 | #endif | 730 | #endif |
700 | 731 | ||
701 | VOP_SETATTR(vp, &vattr, flags, NULL, error); | 732 | VOP_SETATTR(vp, &vattr, flags, NULL, error); |
702 | if (error) | 733 | if (likely(!error)) |
703 | return -error; | 734 | __vn_revalidate(vp, &vattr); |
704 | vn_revalidate(vp); | 735 | return -error; |
705 | return error; | ||
706 | } | 736 | } |
707 | 737 | ||
708 | STATIC void | 738 | STATIC void |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index 260dd8415dd7..225e7dd8b21d 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c | |||
@@ -83,7 +83,7 @@ vn_initialize( | |||
83 | vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); | 83 | vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); |
84 | #endif /* XFS_VNODE_TRACE */ | 84 | #endif /* XFS_VNODE_TRACE */ |
85 | 85 | ||
86 | vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address); | 86 | vn_trace_exit(vp, __FUNCTION__, (inst_t *)__return_address); |
87 | return vp; | 87 | return vp; |
88 | } | 88 | } |
89 | 89 | ||
@@ -129,24 +129,31 @@ vn_revalidate_core( | |||
129 | * Revalidate the Linux inode from the vnode. | 129 | * Revalidate the Linux inode from the vnode. |
130 | */ | 130 | */ |
131 | int | 131 | int |
132 | vn_revalidate( | 132 | __vn_revalidate( |
133 | struct vnode *vp) | 133 | struct vnode *vp, |
134 | struct vattr *vattr) | ||
134 | { | 135 | { |
135 | vattr_t va; | ||
136 | int error; | 136 | int error; |
137 | 137 | ||
138 | vn_trace_entry(vp, "vn_revalidate", (inst_t *)__return_address); | 138 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
139 | ASSERT(vp->v_fbhv != NULL); | 139 | vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; |
140 | 140 | VOP_GETATTR(vp, vattr, 0, NULL, error); | |
141 | va.va_mask = XFS_AT_STAT|XFS_AT_XFLAGS; | 141 | if (likely(!error)) { |
142 | VOP_GETATTR(vp, &va, 0, NULL, error); | 142 | vn_revalidate_core(vp, vattr); |
143 | if (!error) { | ||
144 | vn_revalidate_core(vp, &va); | ||
145 | VUNMODIFY(vp); | 143 | VUNMODIFY(vp); |
146 | } | 144 | } |
147 | return -error; | 145 | return -error; |
148 | } | 146 | } |
149 | 147 | ||
148 | int | ||
149 | vn_revalidate( | ||
150 | struct vnode *vp) | ||
151 | { | ||
152 | vattr_t vattr; | ||
153 | |||
154 | return __vn_revalidate(vp, &vattr); | ||
155 | } | ||
156 | |||
150 | /* | 157 | /* |
151 | * Add a reference to a referenced vnode. | 158 | * Add a reference to a referenced vnode. |
152 | */ | 159 | */ |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 0fe2419461d6..0cf92ca80ce7 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -490,6 +490,7 @@ typedef struct vnode_map { | |||
490 | (vmap).v_ino = (vp)->v_inode.i_ino; } | 490 | (vmap).v_ino = (vp)->v_inode.i_ino; } |
491 | 491 | ||
492 | extern int vn_revalidate(struct vnode *); | 492 | extern int vn_revalidate(struct vnode *); |
493 | extern int __vn_revalidate(struct vnode *, vattr_t *); | ||
493 | extern void vn_revalidate_core(struct vnode *, vattr_t *); | 494 | extern void vn_revalidate_core(struct vnode *, vattr_t *); |
494 | 495 | ||
495 | extern void vn_iowait(struct vnode *vp); | 496 | extern void vn_iowait(struct vnode *vp); |