aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorNathan Scott <nathans@sgi.com>2006-03-13 21:33:36 -0500
committerNathan Scott <nathans@sgi.com>2006-03-13 21:33:36 -0500
commit220b5284139be6ecbc39b353fd76f0923eccc3d6 (patch)
tree86ab8c671631a109690d6589a19d9774d8bed18f /fs/xfs/linux-2.6
parent9b94c2eddf407ad8faa5672ffa691e2076167564 (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')
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c13
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c128
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c180
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c29
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h1
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 269995ddfbd..ce8fe40e162 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 4db47790415..f182721ec9a 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
1264STATIC int 1288STATIC int
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index d7f6f2d8ac8..b1219195c6e 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 */
200STATIC void 200STATIC void
201validate_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 */
226STATIC int 226STATIC int
227linvfs_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 */
259STATIC inline int 259STATIC inline int
260has_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
265STATIC inline void 265STATIC inline void
266cleanup_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
708STATIC void 738STATIC void
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index 260dd8415dd..225e7dd8b21 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 */
131int 131int
132vn_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
148int
149vn_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 0fe2419461d..0cf92ca80ce 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
492extern int vn_revalidate(struct vnode *); 492extern int vn_revalidate(struct vnode *);
493extern int __vn_revalidate(struct vnode *, vattr_t *);
493extern void vn_revalidate_core(struct vnode *, vattr_t *); 494extern void vn_revalidate_core(struct vnode *, vattr_t *);
494 495
495extern void vn_iowait(struct vnode *vp); 496extern void vn_iowait(struct vnode *vp);