aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_iops.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 12:04:11 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 12:04:11 -0400
commit347c53dca73fca317d57781f510f5ff4f6c0d0d7 (patch)
treecdc405ac049751da4d76085ce58750b6b2a22326 /fs/xfs/linux-2.6/xfs_iops.c
parent5c8e191e8437616a498a8e1cc0af3dd0d32bbff2 (diff)
parent7f015072348a14f16d548be557ee58c5c55df0aa (diff)
Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6: (59 commits) [XFS] eagerly remove vmap mappings to avoid upsetting Xen [XFS] simplify validata_fields [XFS] no longer using io_vnode, as was remaining from 23 cherrypick [XFS] Remove STATIC which was missing from prior manual merge [XFS] Put back the QUEUE_ORDERED_NONE test in the barrier check. [XFS] Turn off XBF_ASYNC flag before re-reading superblock. [XFS] avoid race in sync_inodes() that can fail to write out all dirty data [XFS] This fix prevents bulkstat from spinning in an infinite loop. [XFS] simplify xfs_create/mknod/symlink prototype [XFS] avoid xfs_getattr in XFS_IOC_FSGETXATTR ioctl [XFS] get_bulkall() could return incorrect inode state [XFS] Kill unused IOMAP_EOF flag [XFS] fix when DMAPI mount option processing happens [XFS] ensure file size is logged on synchronous writes [XFS] growlock should be a mutex [XFS] replace some large xfs_log_priv.h macros by proper functions [XFS] kill struct bhv_vfs [XFS] move syncing related members from struct bhv_vfs to struct xfs_mount [XFS] kill the vfs_flags member in struct bhv_vfs [XFS] kill the vfs_fsid and vfs_altfsid members in struct bhv_vfs ...
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_iops.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c196
1 files changed, 68 insertions, 128 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index e0e06dd4bef2..ac50f8a37582 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -46,6 +46,7 @@
46#include "xfs_attr.h" 46#include "xfs_attr.h"
47#include "xfs_buf_item.h" 47#include "xfs_buf_item.h"
48#include "xfs_utils.h" 48#include "xfs_utils.h"
49#include "xfs_vnodeops.h"
49 50
50#include <linux/capability.h> 51#include <linux/capability.h>
51#include <linux/xattr.h> 52#include <linux/xattr.h>
@@ -53,22 +54,6 @@
53#include <linux/security.h> 54#include <linux/security.h>
54 55
55/* 56/*
56 * Get a XFS inode from a given vnode.
57 */
58xfs_inode_t *
59xfs_vtoi(
60 bhv_vnode_t *vp)
61{
62 bhv_desc_t *bdp;
63
64 bdp = bhv_lookup_range(VN_BHV_HEAD(vp),
65 VNODE_POSITION_XFS, VNODE_POSITION_XFS);
66 if (unlikely(bdp == NULL))
67 return NULL;
68 return XFS_BHVTOI(bdp);
69}
70
71/*
72 * Bring the atime in the XFS inode uptodate. 57 * Bring the atime in the XFS inode uptodate.
73 * Used before logging the inode to disk or when the Linux inode goes away. 58 * Used before logging the inode to disk or when the Linux inode goes away.
74 */ 59 */
@@ -80,9 +65,8 @@ xfs_synchronize_atime(
80 65
81 vp = XFS_ITOV_NULL(ip); 66 vp = XFS_ITOV_NULL(ip);
82 if (vp) { 67 if (vp) {
83 struct inode *inode = &vp->v_inode; 68 ip->i_d.di_atime.t_sec = (__int32_t)vp->i_atime.tv_sec;
84 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; 69 ip->i_d.di_atime.t_nsec = (__int32_t)vp->i_atime.tv_nsec;
85 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
86 } 70 }
87} 71}
88 72
@@ -195,18 +179,19 @@ xfs_ichgtime_fast(
195 */ 179 */
196STATIC void 180STATIC void
197xfs_validate_fields( 181xfs_validate_fields(
198 struct inode *ip, 182 struct inode *inode)
199 bhv_vattr_t *vattr)
200{ 183{
201 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; 184 struct xfs_inode *ip = XFS_I(inode);
202 if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) { 185 loff_t size;
203 ip->i_nlink = vattr->va_nlink; 186
204 ip->i_blocks = vattr->va_nblocks; 187 inode->i_nlink = ip->i_d.di_nlink;
205 188 inode->i_blocks =
206 /* we're under i_sem so i_size can't change under us */ 189 XFS_FSB_TO_BB(ip->i_mount, ip->i_d.di_nblocks +
207 if (i_size_read(ip) != vattr->va_size) 190 ip->i_delayed_blks);
208 i_size_write(ip, vattr->va_size); 191 /* we're under i_sem so i_size can't change under us */
209 } 192 size = XFS_ISIZE(ip);
193 if (i_size_read(inode) != size)
194 i_size_write(inode, size);
210} 195}
211 196
212/* 197/*
@@ -233,9 +218,10 @@ xfs_init_security(
233 return -error; 218 return -error;
234 } 219 }
235 220
236 error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL); 221 error = xfs_attr_set(XFS_I(ip), name, value,
222 length, ATTR_SECURE);
237 if (!error) 223 if (!error)
238 VMODIFY(vp); 224 xfs_iflags_set(XFS_I(ip), XFS_IMODIFIED);
239 225
240 kfree(name); 226 kfree(name);
241 kfree(value); 227 kfree(value);
@@ -256,7 +242,7 @@ xfs_has_fs_struct(struct task_struct *task)
256 242
257STATIC void 243STATIC void
258xfs_cleanup_inode( 244xfs_cleanup_inode(
259 bhv_vnode_t *dvp, 245 struct inode *dir,
260 bhv_vnode_t *vp, 246 bhv_vnode_t *vp,
261 struct dentry *dentry, 247 struct dentry *dentry,
262 int mode) 248 int mode)
@@ -272,9 +258,9 @@ xfs_cleanup_inode(
272 teardown.d_name = dentry->d_name; 258 teardown.d_name = dentry->d_name;
273 259
274 if (S_ISDIR(mode)) 260 if (S_ISDIR(mode))
275 bhv_vop_rmdir(dvp, &teardown, NULL); 261 xfs_rmdir(XFS_I(dir), &teardown);
276 else 262 else
277 bhv_vop_remove(dvp, &teardown, NULL); 263 xfs_remove(XFS_I(dir), &teardown);
278 VN_RELE(vp); 264 VN_RELE(vp);
279} 265}
280 266
@@ -286,7 +272,6 @@ xfs_vn_mknod(
286 dev_t rdev) 272 dev_t rdev)
287{ 273{
288 struct inode *ip; 274 struct inode *ip;
289 bhv_vattr_t vattr = { 0 };
290 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir); 275 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
291 xfs_acl_t *default_acl = NULL; 276 xfs_acl_t *default_acl = NULL;
292 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; 277 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
@@ -312,19 +297,14 @@ xfs_vn_mknod(
312 if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current)) 297 if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current))
313 mode &= ~current->fs->umask; 298 mode &= ~current->fs->umask;
314 299
315 vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
316 vattr.va_mode = mode;
317
318 switch (mode & S_IFMT) { 300 switch (mode & S_IFMT) {
319 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: 301 case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
320 vattr.va_rdev = sysv_encode_dev(rdev); 302 rdev = sysv_encode_dev(rdev);
321 vattr.va_mask |= XFS_AT_RDEV;
322 /*FALLTHROUGH*/
323 case S_IFREG: 303 case S_IFREG:
324 error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL); 304 error = xfs_create(XFS_I(dir), dentry, mode, rdev, &vp, NULL);
325 break; 305 break;
326 case S_IFDIR: 306 case S_IFDIR:
327 error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL); 307 error = xfs_mkdir(XFS_I(dir), dentry, mode, &vp, NULL);
328 break; 308 break;
329 default: 309 default:
330 error = EINVAL; 310 error = EINVAL;
@@ -334,16 +314,16 @@ xfs_vn_mknod(
334 if (unlikely(!error)) { 314 if (unlikely(!error)) {
335 error = xfs_init_security(vp, dir); 315 error = xfs_init_security(vp, dir);
336 if (error) 316 if (error)
337 xfs_cleanup_inode(dvp, vp, dentry, mode); 317 xfs_cleanup_inode(dir, vp, dentry, mode);
338 } 318 }
339 319
340 if (unlikely(default_acl)) { 320 if (unlikely(default_acl)) {
341 if (!error) { 321 if (!error) {
342 error = _ACL_INHERIT(vp, &vattr, default_acl); 322 error = _ACL_INHERIT(vp, mode, default_acl);
343 if (!error) 323 if (!error)
344 VMODIFY(vp); 324 xfs_iflags_set(XFS_I(vp), XFS_IMODIFIED);
345 else 325 else
346 xfs_cleanup_inode(dvp, vp, dentry, mode); 326 xfs_cleanup_inode(dir, vp, dentry, mode);
347 } 327 }
348 _ACL_FREE(default_acl); 328 _ACL_FREE(default_acl);
349 } 329 }
@@ -355,9 +335,9 @@ xfs_vn_mknod(
355 if (S_ISCHR(mode) || S_ISBLK(mode)) 335 if (S_ISCHR(mode) || S_ISBLK(mode))
356 ip->i_rdev = rdev; 336 ip->i_rdev = rdev;
357 else if (S_ISDIR(mode)) 337 else if (S_ISDIR(mode))
358 xfs_validate_fields(ip, &vattr); 338 xfs_validate_fields(ip);
359 d_instantiate(dentry, ip); 339 d_instantiate(dentry, ip);
360 xfs_validate_fields(dir, &vattr); 340 xfs_validate_fields(dir);
361 } 341 }
362 return -error; 342 return -error;
363} 343}
@@ -387,13 +367,13 @@ xfs_vn_lookup(
387 struct dentry *dentry, 367 struct dentry *dentry,
388 struct nameidata *nd) 368 struct nameidata *nd)
389{ 369{
390 bhv_vnode_t *vp = vn_from_inode(dir), *cvp; 370 bhv_vnode_t *cvp;
391 int error; 371 int error;
392 372
393 if (dentry->d_name.len >= MAXNAMELEN) 373 if (dentry->d_name.len >= MAXNAMELEN)
394 return ERR_PTR(-ENAMETOOLONG); 374 return ERR_PTR(-ENAMETOOLONG);
395 375
396 error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL); 376 error = xfs_lookup(XFS_I(dir), dentry, &cvp);
397 if (unlikely(error)) { 377 if (unlikely(error)) {
398 if (unlikely(error != ENOENT)) 378 if (unlikely(error != ENOENT))
399 return ERR_PTR(-error); 379 return ERR_PTR(-error);
@@ -411,22 +391,19 @@ xfs_vn_link(
411 struct dentry *dentry) 391 struct dentry *dentry)
412{ 392{
413 struct inode *ip; /* inode of guy being linked to */ 393 struct inode *ip; /* inode of guy being linked to */
414 bhv_vnode_t *tdvp; /* target directory for new name/link */
415 bhv_vnode_t *vp; /* vp of name being linked */ 394 bhv_vnode_t *vp; /* vp of name being linked */
416 bhv_vattr_t vattr;
417 int error; 395 int error;
418 396
419 ip = old_dentry->d_inode; /* inode being linked to */ 397 ip = old_dentry->d_inode; /* inode being linked to */
420 tdvp = vn_from_inode(dir);
421 vp = vn_from_inode(ip); 398 vp = vn_from_inode(ip);
422 399
423 VN_HOLD(vp); 400 VN_HOLD(vp);
424 error = bhv_vop_link(tdvp, vp, dentry, NULL); 401 error = xfs_link(XFS_I(dir), vp, dentry);
425 if (unlikely(error)) { 402 if (unlikely(error)) {
426 VN_RELE(vp); 403 VN_RELE(vp);
427 } else { 404 } else {
428 VMODIFY(tdvp); 405 xfs_iflags_set(XFS_I(dir), XFS_IMODIFIED);
429 xfs_validate_fields(ip, &vattr); 406 xfs_validate_fields(ip);
430 d_instantiate(dentry, ip); 407 d_instantiate(dentry, ip);
431 } 408 }
432 return -error; 409 return -error;
@@ -438,17 +415,14 @@ xfs_vn_unlink(
438 struct dentry *dentry) 415 struct dentry *dentry)
439{ 416{
440 struct inode *inode; 417 struct inode *inode;
441 bhv_vnode_t *dvp; /* directory containing name to remove */
442 bhv_vattr_t vattr;
443 int error; 418 int error;
444 419
445 inode = dentry->d_inode; 420 inode = dentry->d_inode;
446 dvp = vn_from_inode(dir);
447 421
448 error = bhv_vop_remove(dvp, dentry, NULL); 422 error = xfs_remove(XFS_I(dir), dentry);
449 if (likely(!error)) { 423 if (likely(!error)) {
450 xfs_validate_fields(dir, &vattr); /* size needs update */ 424 xfs_validate_fields(dir); /* size needs update */
451 xfs_validate_fields(inode, &vattr); 425 xfs_validate_fields(inode);
452 } 426 }
453 return -error; 427 return -error;
454} 428}
@@ -460,28 +434,26 @@ xfs_vn_symlink(
460 const char *symname) 434 const char *symname)
461{ 435{
462 struct inode *ip; 436 struct inode *ip;
463 bhv_vattr_t va = { 0 };
464 bhv_vnode_t *dvp; /* directory containing name of symlink */
465 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */ 437 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
466 int error; 438 int error;
439 mode_t mode;
467 440
468 dvp = vn_from_inode(dir);
469 cvp = NULL; 441 cvp = NULL;
470 442
471 va.va_mode = S_IFLNK | 443 mode = S_IFLNK |
472 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); 444 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
473 va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
474 445
475 error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL); 446 error = xfs_symlink(XFS_I(dir), dentry, (char *)symname, mode,
447 &cvp, NULL);
476 if (likely(!error && cvp)) { 448 if (likely(!error && cvp)) {
477 error = xfs_init_security(cvp, dir); 449 error = xfs_init_security(cvp, dir);
478 if (likely(!error)) { 450 if (likely(!error)) {
479 ip = vn_to_inode(cvp); 451 ip = vn_to_inode(cvp);
480 d_instantiate(dentry, ip); 452 d_instantiate(dentry, ip);
481 xfs_validate_fields(dir, &va); 453 xfs_validate_fields(dir);
482 xfs_validate_fields(ip, &va); 454 xfs_validate_fields(ip);
483 } else { 455 } else {
484 xfs_cleanup_inode(dvp, cvp, dentry, 0); 456 xfs_cleanup_inode(dir, cvp, dentry, 0);
485 } 457 }
486 } 458 }
487 return -error; 459 return -error;
@@ -493,14 +465,12 @@ xfs_vn_rmdir(
493 struct dentry *dentry) 465 struct dentry *dentry)
494{ 466{
495 struct inode *inode = dentry->d_inode; 467 struct inode *inode = dentry->d_inode;
496 bhv_vnode_t *dvp = vn_from_inode(dir);
497 bhv_vattr_t vattr;
498 int error; 468 int error;
499 469
500 error = bhv_vop_rmdir(dvp, dentry, NULL); 470 error = xfs_rmdir(XFS_I(dir), dentry);
501 if (likely(!error)) { 471 if (likely(!error)) {
502 xfs_validate_fields(inode, &vattr); 472 xfs_validate_fields(inode);
503 xfs_validate_fields(dir, &vattr); 473 xfs_validate_fields(dir);
504 } 474 }
505 return -error; 475 return -error;
506} 476}
@@ -513,21 +483,18 @@ xfs_vn_rename(
513 struct dentry *ndentry) 483 struct dentry *ndentry)
514{ 484{
515 struct inode *new_inode = ndentry->d_inode; 485 struct inode *new_inode = ndentry->d_inode;
516 bhv_vnode_t *fvp; /* from directory */
517 bhv_vnode_t *tvp; /* target directory */ 486 bhv_vnode_t *tvp; /* target directory */
518 bhv_vattr_t vattr;
519 int error; 487 int error;
520 488
521 fvp = vn_from_inode(odir);
522 tvp = vn_from_inode(ndir); 489 tvp = vn_from_inode(ndir);
523 490
524 error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL); 491 error = xfs_rename(XFS_I(odir), odentry, tvp, ndentry);
525 if (likely(!error)) { 492 if (likely(!error)) {
526 if (new_inode) 493 if (new_inode)
527 xfs_validate_fields(new_inode, &vattr); 494 xfs_validate_fields(new_inode);
528 xfs_validate_fields(odir, &vattr); 495 xfs_validate_fields(odir);
529 if (ndir != odir) 496 if (ndir != odir)
530 xfs_validate_fields(ndir, &vattr); 497 xfs_validate_fields(ndir);
531 } 498 }
532 return -error; 499 return -error;
533} 500}
@@ -542,50 +509,25 @@ xfs_vn_follow_link(
542 struct dentry *dentry, 509 struct dentry *dentry,
543 struct nameidata *nd) 510 struct nameidata *nd)
544{ 511{
545 bhv_vnode_t *vp;
546 uio_t *uio;
547 iovec_t iov;
548 int error;
549 char *link; 512 char *link;
550 513 int error = -ENOMEM;
551 ASSERT(dentry);
552 ASSERT(nd);
553 514
554 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); 515 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
555 if (!link) { 516 if (!link)
556 nd_set_link(nd, ERR_PTR(-ENOMEM)); 517 goto out_err;
557 return NULL;
558 }
559
560 uio = kmalloc(sizeof(uio_t), GFP_KERNEL);
561 if (!uio) {
562 kfree(link);
563 nd_set_link(nd, ERR_PTR(-ENOMEM));
564 return NULL;
565 }
566
567 vp = vn_from_inode(dentry->d_inode);
568
569 iov.iov_base = link;
570 iov.iov_len = MAXPATHLEN;
571 518
572 uio->uio_iov = &iov; 519 error = -xfs_readlink(XFS_I(dentry->d_inode), link);
573 uio->uio_offset = 0; 520 if (unlikely(error))
574 uio->uio_segflg = UIO_SYSSPACE; 521 goto out_kfree;
575 uio->uio_resid = MAXPATHLEN;
576 uio->uio_iovcnt = 1;
577
578 error = bhv_vop_readlink(vp, uio, 0, NULL);
579 if (unlikely(error)) {
580 kfree(link);
581 link = ERR_PTR(-error);
582 } else {
583 link[MAXPATHLEN - uio->uio_resid] = '\0';
584 }
585 kfree(uio);
586 522
587 nd_set_link(nd, link); 523 nd_set_link(nd, link);
588 return NULL; 524 return NULL;
525
526 out_kfree:
527 kfree(link);
528 out_err:
529 nd_set_link(nd, ERR_PTR(error));
530 return NULL;
589} 531}
590 532
591STATIC void 533STATIC void
@@ -607,7 +549,7 @@ xfs_vn_permission(
607 int mode, 549 int mode,
608 struct nameidata *nd) 550 struct nameidata *nd)
609{ 551{
610 return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL); 552 return -xfs_access(XFS_I(inode), mode << 6, NULL);
611} 553}
612#else 554#else
613#define xfs_vn_permission NULL 555#define xfs_vn_permission NULL
@@ -620,11 +562,10 @@ xfs_vn_getattr(
620 struct kstat *stat) 562 struct kstat *stat)
621{ 563{
622 struct inode *inode = dentry->d_inode; 564 struct inode *inode = dentry->d_inode;
623 bhv_vnode_t *vp = vn_from_inode(inode);
624 bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT }; 565 bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT };
625 int error; 566 int error;
626 567
627 error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL); 568 error = xfs_getattr(XFS_I(inode), &vattr, ATTR_LAZY);
628 if (likely(!error)) { 569 if (likely(!error)) {
629 stat->size = i_size_read(inode); 570 stat->size = i_size_read(inode);
630 stat->dev = inode->i_sb->s_dev; 571 stat->dev = inode->i_sb->s_dev;
@@ -652,7 +593,6 @@ xfs_vn_setattr(
652{ 593{
653 struct inode *inode = dentry->d_inode; 594 struct inode *inode = dentry->d_inode;
654 unsigned int ia_valid = attr->ia_valid; 595 unsigned int ia_valid = attr->ia_valid;
655 bhv_vnode_t *vp = vn_from_inode(inode);
656 bhv_vattr_t vattr = { 0 }; 596 bhv_vattr_t vattr = { 0 };
657 int flags = 0; 597 int flags = 0;
658 int error; 598 int error;
@@ -696,9 +636,9 @@ xfs_vn_setattr(
696 flags |= ATTR_NONBLOCK; 636 flags |= ATTR_NONBLOCK;
697#endif 637#endif
698 638
699 error = bhv_vop_setattr(vp, &vattr, flags, NULL); 639 error = xfs_setattr(XFS_I(inode), &vattr, flags, NULL);
700 if (likely(!error)) 640 if (likely(!error))
701 __vn_revalidate(vp, &vattr); 641 __vn_revalidate(vn_from_inode(inode), &vattr);
702 return -error; 642 return -error;
703} 643}
704 644