aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_iops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c223
1 files changed, 125 insertions, 98 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index cc4abd3daa49..0c958cf77758 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -62,12 +62,11 @@ void
62xfs_synchronize_atime( 62xfs_synchronize_atime(
63 xfs_inode_t *ip) 63 xfs_inode_t *ip)
64{ 64{
65 bhv_vnode_t *vp; 65 struct inode *inode = ip->i_vnode;
66 66
67 vp = XFS_ITOV_NULL(ip); 67 if (inode) {
68 if (vp) { 68 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
69 ip->i_d.di_atime.t_sec = (__int32_t)vp->i_atime.tv_sec; 69 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
70 ip->i_d.di_atime.t_nsec = (__int32_t)vp->i_atime.tv_nsec;
71 } 70 }
72} 71}
73 72
@@ -80,11 +79,10 @@ void
80xfs_mark_inode_dirty_sync( 79xfs_mark_inode_dirty_sync(
81 xfs_inode_t *ip) 80 xfs_inode_t *ip)
82{ 81{
83 bhv_vnode_t *vp; 82 struct inode *inode = ip->i_vnode;
84 83
85 vp = XFS_ITOV_NULL(ip); 84 if (inode)
86 if (vp) 85 mark_inode_dirty_sync(inode);
87 mark_inode_dirty_sync(vn_to_inode(vp));
88} 86}
89 87
90/* 88/*
@@ -215,66 +213,62 @@ xfs_validate_fields(
215 */ 213 */
216STATIC int 214STATIC int
217xfs_init_security( 215xfs_init_security(
218 bhv_vnode_t *vp, 216 struct inode *inode,
219 struct inode *dir) 217 struct inode *dir)
220{ 218{
221 struct inode *ip = vn_to_inode(vp); 219 struct xfs_inode *ip = XFS_I(inode);
222 size_t length; 220 size_t length;
223 void *value; 221 void *value;
224 char *name; 222 char *name;
225 int error; 223 int error;
226 224
227 error = security_inode_init_security(ip, dir, &name, &value, &length); 225 error = security_inode_init_security(inode, dir, &name,
226 &value, &length);
228 if (error) { 227 if (error) {
229 if (error == -EOPNOTSUPP) 228 if (error == -EOPNOTSUPP)
230 return 0; 229 return 0;
231 return -error; 230 return -error;
232 } 231 }
233 232
234 error = xfs_attr_set(XFS_I(ip), name, value, 233 error = xfs_attr_set(ip, name, value, length, ATTR_SECURE);
235 length, ATTR_SECURE);
236 if (!error) 234 if (!error)
237 xfs_iflags_set(XFS_I(ip), XFS_IMODIFIED); 235 xfs_iflags_set(ip, XFS_IMODIFIED);
238 236
239 kfree(name); 237 kfree(name);
240 kfree(value); 238 kfree(value);
241 return error; 239 return error;
242} 240}
243 241
244/* 242static void
245 * Determine whether a process has a valid fs_struct (kernel daemons 243xfs_dentry_to_name(
246 * like knfsd don't have an fs_struct). 244 struct xfs_name *namep,
247 * 245 struct dentry *dentry)
248 * XXX(hch): nfsd is broken, better fix it instead.
249 */
250STATIC_INLINE int
251xfs_has_fs_struct(struct task_struct *task)
252{ 246{
253 return (task->fs != init_task.fs); 247 namep->name = dentry->d_name.name;
248 namep->len = dentry->d_name.len;
254} 249}
255 250
256STATIC void 251STATIC void
257xfs_cleanup_inode( 252xfs_cleanup_inode(
258 struct inode *dir, 253 struct inode *dir,
259 bhv_vnode_t *vp, 254 struct inode *inode,
260 struct dentry *dentry, 255 struct dentry *dentry,
261 int mode) 256 int mode)
262{ 257{
263 struct dentry teardown = {}; 258 struct xfs_name teardown;
264 259
265 /* Oh, the horror. 260 /* Oh, the horror.
266 * If we can't add the ACL or we fail in 261 * If we can't add the ACL or we fail in
267 * xfs_init_security we must back out. 262 * xfs_init_security we must back out.
268 * ENOSPC can hit here, among other things. 263 * ENOSPC can hit here, among other things.
269 */ 264 */
270 teardown.d_inode = vn_to_inode(vp); 265 xfs_dentry_to_name(&teardown, dentry);
271 teardown.d_name = dentry->d_name;
272 266
273 if (S_ISDIR(mode)) 267 if (S_ISDIR(mode))
274 xfs_rmdir(XFS_I(dir), &teardown); 268 xfs_rmdir(XFS_I(dir), &teardown, XFS_I(inode));
275 else 269 else
276 xfs_remove(XFS_I(dir), &teardown); 270 xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
277 VN_RELE(vp); 271 iput(inode);
278} 272}
279 273
280STATIC int 274STATIC int
@@ -284,9 +278,10 @@ xfs_vn_mknod(
284 int mode, 278 int mode,
285 dev_t rdev) 279 dev_t rdev)
286{ 280{
287 struct inode *ip; 281 struct inode *inode;
288 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir); 282 struct xfs_inode *ip = NULL;
289 xfs_acl_t *default_acl = NULL; 283 xfs_acl_t *default_acl = NULL;
284 struct xfs_name name;
290 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; 285 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
291 int error; 286 int error;
292 287
@@ -297,59 +292,67 @@ xfs_vn_mknod(
297 if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)) 292 if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
298 return -EINVAL; 293 return -EINVAL;
299 294
300 if (unlikely(test_default_acl && test_default_acl(dvp))) { 295 if (test_default_acl && test_default_acl(dir)) {
301 if (!_ACL_ALLOC(default_acl)) { 296 if (!_ACL_ALLOC(default_acl)) {
302 return -ENOMEM; 297 return -ENOMEM;
303 } 298 }
304 if (!_ACL_GET_DEFAULT(dvp, default_acl)) { 299 if (!_ACL_GET_DEFAULT(dir, default_acl)) {
305 _ACL_FREE(default_acl); 300 _ACL_FREE(default_acl);
306 default_acl = NULL; 301 default_acl = NULL;
307 } 302 }
308 } 303 }
309 304
310 if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current)) 305 xfs_dentry_to_name(&name, dentry);
306
307 if (IS_POSIXACL(dir) && !default_acl)
311 mode &= ~current->fs->umask; 308 mode &= ~current->fs->umask;
312 309
313 switch (mode & S_IFMT) { 310 switch (mode & S_IFMT) {
314 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: 311 case S_IFCHR:
312 case S_IFBLK:
313 case S_IFIFO:
314 case S_IFSOCK:
315 rdev = sysv_encode_dev(rdev); 315 rdev = sysv_encode_dev(rdev);
316 case S_IFREG: 316 case S_IFREG:
317 error = xfs_create(XFS_I(dir), dentry, mode, rdev, &vp, NULL); 317 error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
318 break; 318 break;
319 case S_IFDIR: 319 case S_IFDIR:
320 error = xfs_mkdir(XFS_I(dir), dentry, mode, &vp, NULL); 320 error = xfs_mkdir(XFS_I(dir), &name, mode, &ip, NULL);
321 break; 321 break;
322 default: 322 default:
323 error = EINVAL; 323 error = EINVAL;
324 break; 324 break;
325 } 325 }
326 326
327 if (unlikely(!error)) { 327 if (unlikely(error))
328 error = xfs_init_security(vp, dir); 328 goto out_free_acl;
329 if (error)
330 xfs_cleanup_inode(dir, vp, dentry, mode);
331 }
332 329
333 if (unlikely(default_acl)) { 330 inode = ip->i_vnode;
334 if (!error) { 331
335 error = _ACL_INHERIT(vp, mode, default_acl); 332 error = xfs_init_security(inode, dir);
336 if (!error) 333 if (unlikely(error))
337 xfs_iflags_set(XFS_I(vp), XFS_IMODIFIED); 334 goto out_cleanup_inode;
338 else 335
339 xfs_cleanup_inode(dir, vp, dentry, mode); 336 if (default_acl) {
340 } 337 error = _ACL_INHERIT(inode, mode, default_acl);
338 if (unlikely(error))
339 goto out_cleanup_inode;
340 xfs_iflags_set(ip, XFS_IMODIFIED);
341 _ACL_FREE(default_acl); 341 _ACL_FREE(default_acl);
342 } 342 }
343 343
344 if (likely(!error)) {
345 ASSERT(vp);
346 ip = vn_to_inode(vp);
347 344
348 if (S_ISDIR(mode)) 345 if (S_ISDIR(mode))
349 xfs_validate_fields(ip); 346 xfs_validate_fields(inode);
350 d_instantiate(dentry, ip); 347 d_instantiate(dentry, inode);
351 xfs_validate_fields(dir); 348 xfs_validate_fields(dir);
352 } 349 return -error;
350
351 out_cleanup_inode:
352 xfs_cleanup_inode(dir, inode, dentry, mode);
353 out_free_acl:
354 if (default_acl)
355 _ACL_FREE(default_acl);
353 return -error; 356 return -error;
354} 357}
355 358
@@ -378,13 +381,15 @@ xfs_vn_lookup(
378 struct dentry *dentry, 381 struct dentry *dentry,
379 struct nameidata *nd) 382 struct nameidata *nd)
380{ 383{
381 bhv_vnode_t *cvp; 384 struct xfs_inode *cip;
385 struct xfs_name name;
382 int error; 386 int error;
383 387
384 if (dentry->d_name.len >= MAXNAMELEN) 388 if (dentry->d_name.len >= MAXNAMELEN)
385 return ERR_PTR(-ENAMETOOLONG); 389 return ERR_PTR(-ENAMETOOLONG);
386 390
387 error = xfs_lookup(XFS_I(dir), dentry, &cvp); 391 xfs_dentry_to_name(&name, dentry);
392 error = xfs_lookup(XFS_I(dir), &name, &cip);
388 if (unlikely(error)) { 393 if (unlikely(error)) {
389 if (unlikely(error != ENOENT)) 394 if (unlikely(error != ENOENT))
390 return ERR_PTR(-error); 395 return ERR_PTR(-error);
@@ -392,7 +397,7 @@ xfs_vn_lookup(
392 return NULL; 397 return NULL;
393 } 398 }
394 399
395 return d_splice_alias(vn_to_inode(cvp), dentry); 400 return d_splice_alias(cip->i_vnode, dentry);
396} 401}
397 402
398STATIC int 403STATIC int
@@ -401,23 +406,24 @@ xfs_vn_link(
401 struct inode *dir, 406 struct inode *dir,
402 struct dentry *dentry) 407 struct dentry *dentry)
403{ 408{
404 struct inode *ip; /* inode of guy being linked to */ 409 struct inode *inode; /* inode of guy being linked to */
405 bhv_vnode_t *vp; /* vp of name being linked */ 410 struct xfs_name name;
406 int error; 411 int error;
407 412
408 ip = old_dentry->d_inode; /* inode being linked to */ 413 inode = old_dentry->d_inode;
409 vp = vn_from_inode(ip); 414 xfs_dentry_to_name(&name, dentry);
410 415
411 VN_HOLD(vp); 416 igrab(inode);
412 error = xfs_link(XFS_I(dir), vp, dentry); 417 error = xfs_link(XFS_I(dir), XFS_I(inode), &name);
413 if (unlikely(error)) { 418 if (unlikely(error)) {
414 VN_RELE(vp); 419 iput(inode);
415 } else { 420 return -error;
416 xfs_iflags_set(XFS_I(dir), XFS_IMODIFIED);
417 xfs_validate_fields(ip);
418 d_instantiate(dentry, ip);
419 } 421 }
420 return -error; 422
423 xfs_iflags_set(XFS_I(dir), XFS_IMODIFIED);
424 xfs_validate_fields(inode);
425 d_instantiate(dentry, inode);
426 return 0;
421} 427}
422 428
423STATIC int 429STATIC int
@@ -426,11 +432,13 @@ xfs_vn_unlink(
426 struct dentry *dentry) 432 struct dentry *dentry)
427{ 433{
428 struct inode *inode; 434 struct inode *inode;
435 struct xfs_name name;
429 int error; 436 int error;
430 437
431 inode = dentry->d_inode; 438 inode = dentry->d_inode;
439 xfs_dentry_to_name(&name, dentry);
432 440
433 error = xfs_remove(XFS_I(dir), dentry); 441 error = xfs_remove(XFS_I(dir), &name, XFS_I(inode));
434 if (likely(!error)) { 442 if (likely(!error)) {
435 xfs_validate_fields(dir); /* size needs update */ 443 xfs_validate_fields(dir); /* size needs update */
436 xfs_validate_fields(inode); 444 xfs_validate_fields(inode);
@@ -444,29 +452,34 @@ xfs_vn_symlink(
444 struct dentry *dentry, 452 struct dentry *dentry,
445 const char *symname) 453 const char *symname)
446{ 454{
447 struct inode *ip; 455 struct inode *inode;
448 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */ 456 struct xfs_inode *cip = NULL;
457 struct xfs_name name;
449 int error; 458 int error;
450 mode_t mode; 459 mode_t mode;
451 460
452 cvp = NULL;
453
454 mode = S_IFLNK | 461 mode = S_IFLNK |
455 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); 462 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
463 xfs_dentry_to_name(&name, dentry);
456 464
457 error = xfs_symlink(XFS_I(dir), dentry, (char *)symname, mode, 465 error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip, NULL);
458 &cvp, NULL); 466 if (unlikely(error))
459 if (likely(!error && cvp)) { 467 goto out;
460 error = xfs_init_security(cvp, dir); 468
461 if (likely(!error)) { 469 inode = cip->i_vnode;
462 ip = vn_to_inode(cvp); 470
463 d_instantiate(dentry, ip); 471 error = xfs_init_security(inode, dir);
464 xfs_validate_fields(dir); 472 if (unlikely(error))
465 xfs_validate_fields(ip); 473 goto out_cleanup_inode;
466 } else { 474
467 xfs_cleanup_inode(dir, cvp, dentry, 0); 475 d_instantiate(dentry, inode);
468 } 476 xfs_validate_fields(dir);
469 } 477 xfs_validate_fields(inode);
478 return 0;
479
480 out_cleanup_inode:
481 xfs_cleanup_inode(dir, inode, dentry, 0);
482 out:
470 return -error; 483 return -error;
471} 484}
472 485
@@ -476,9 +489,12 @@ xfs_vn_rmdir(
476 struct dentry *dentry) 489 struct dentry *dentry)
477{ 490{
478 struct inode *inode = dentry->d_inode; 491 struct inode *inode = dentry->d_inode;
492 struct xfs_name name;
479 int error; 493 int error;
480 494
481 error = xfs_rmdir(XFS_I(dir), dentry); 495 xfs_dentry_to_name(&name, dentry);
496
497 error = xfs_rmdir(XFS_I(dir), &name, XFS_I(inode));
482 if (likely(!error)) { 498 if (likely(!error)) {
483 xfs_validate_fields(inode); 499 xfs_validate_fields(inode);
484 xfs_validate_fields(dir); 500 xfs_validate_fields(dir);
@@ -494,12 +510,15 @@ xfs_vn_rename(
494 struct dentry *ndentry) 510 struct dentry *ndentry)
495{ 511{
496 struct inode *new_inode = ndentry->d_inode; 512 struct inode *new_inode = ndentry->d_inode;
497 bhv_vnode_t *tvp; /* target directory */ 513 struct xfs_name oname;
514 struct xfs_name nname;
498 int error; 515 int error;
499 516
500 tvp = vn_from_inode(ndir); 517 xfs_dentry_to_name(&oname, odentry);
518 xfs_dentry_to_name(&nname, ndentry);
501 519
502 error = xfs_rename(XFS_I(odir), odentry, tvp, ndentry); 520 error = xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode),
521 XFS_I(ndir), &nname);
503 if (likely(!error)) { 522 if (likely(!error)) {
504 if (new_inode) 523 if (new_inode)
505 xfs_validate_fields(new_inode); 524 xfs_validate_fields(new_inode);
@@ -700,11 +719,19 @@ xfs_vn_setattr(
700 return -error; 719 return -error;
701} 720}
702 721
722/*
723 * block_truncate_page can return an error, but we can't propagate it
724 * at all here. Leave a complaint + stack trace in the syslog because
725 * this could be bad. If it is bad, we need to propagate the error further.
726 */
703STATIC void 727STATIC void
704xfs_vn_truncate( 728xfs_vn_truncate(
705 struct inode *inode) 729 struct inode *inode)
706{ 730{
707 block_truncate_page(inode->i_mapping, inode->i_size, xfs_get_blocks); 731 int error;
732 error = block_truncate_page(inode->i_mapping, inode->i_size,
733 xfs_get_blocks);
734 WARN_ON(error);
708} 735}
709 736
710STATIC int 737STATIC int