diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 23:34:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 23:34:17 -0400 |
commit | c15a2434ed4868cad99278ac4d4ae4de9de62e02 (patch) | |
tree | 9d08692fda903f92f5bd426147a4bf00043a2ad1 | |
parent | a94a630a4c69430bb4562ab8252104449bba9a67 (diff) | |
parent | adaa693b845373296631766176ebf0f73a342e10 (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: (24 commits)
[XFS] Fix build failure after enabling CONFIG_XFS_DEBUG
[XFS] remove dmapi cruft in xfs_file.c
[XFS] remove sendfile leftovers
[XFS] allow enabling CONFIG_XFS_DEBUG
[XFS] Don't initialise new inode generation numbers to zero
[XFS] Fix check for block zero access in xfs_write_iomap_allocate()
[XFS] Don't double count reserved block changes on UP.
[XFS] remove xfs_log_ticket_zone on rmmod
[XFS] fix non-smp xfs build
[XFS] Fix broken HAVE_SPLICE removal commit.
[XFS] kill XFS_ICSB_SB_LOCKED
[XFS] split xfs_icsb_balance_counter
[XFS] Add xfs_icsb_sync_counters_locked for when m_sb_lock already held
[XFS] Cleanup xfs_attr a bit with xfs_name and remove cred
[XFS] kill usesless IHOLD calls in xfs_remove and xfs_rmdir
[XFS] kill parent == child checks in xfs_remove and xfs_rmdir
[XFS] kill usesless IHOLD calls in xfs_rename
[XFS] remove manual lookup from xfs_rename and simplify locking
[XFS] shrink mrlock_t
[XFS] simplify xfs_lookup
...
40 files changed, 396 insertions, 939 deletions
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 524021ff5436..3f53dd101f99 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig | |||
@@ -64,3 +64,16 @@ config XFS_RT | |||
64 | See the xfs man page in section 5 for additional information. | 64 | See the xfs man page in section 5 for additional information. |
65 | 65 | ||
66 | If unsure, say N. | 66 | If unsure, say N. |
67 | |||
68 | config XFS_DEBUG | ||
69 | bool "XFS Debugging support (EXPERIMENTAL)" | ||
70 | depends on XFS_FS && EXPERIMENTAL | ||
71 | help | ||
72 | Say Y here to get an XFS build with many debugging features, | ||
73 | including ASSERT checks, function wrappers around macros, | ||
74 | and extra sanity-checking functions in various code paths. | ||
75 | |||
76 | Note that the resulting code will be HUGE and SLOW, and probably | ||
77 | not useful unless you are debugging a particular problem. | ||
78 | |||
79 | Say N unless you are an XFS developer, or you play one on TV. | ||
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h index c110bb002665..ff6a19873e5c 100644 --- a/fs/xfs/linux-2.6/mrlock.h +++ b/fs/xfs/linux-2.6/mrlock.h | |||
@@ -20,29 +20,24 @@ | |||
20 | 20 | ||
21 | #include <linux/rwsem.h> | 21 | #include <linux/rwsem.h> |
22 | 22 | ||
23 | enum { MR_NONE, MR_ACCESS, MR_UPDATE }; | ||
24 | |||
25 | typedef struct { | 23 | typedef struct { |
26 | struct rw_semaphore mr_lock; | 24 | struct rw_semaphore mr_lock; |
25 | #ifdef DEBUG | ||
27 | int mr_writer; | 26 | int mr_writer; |
27 | #endif | ||
28 | } mrlock_t; | 28 | } mrlock_t; |
29 | 29 | ||
30 | #ifdef DEBUG | ||
30 | #define mrinit(mrp, name) \ | 31 | #define mrinit(mrp, name) \ |
31 | do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0) | 32 | do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0) |
33 | #else | ||
34 | #define mrinit(mrp, name) \ | ||
35 | do { init_rwsem(&(mrp)->mr_lock); } while (0) | ||
36 | #endif | ||
37 | |||
32 | #define mrlock_init(mrp, t,n,s) mrinit(mrp, n) | 38 | #define mrlock_init(mrp, t,n,s) mrinit(mrp, n) |
33 | #define mrfree(mrp) do { } while (0) | 39 | #define mrfree(mrp) do { } while (0) |
34 | 40 | ||
35 | static inline void mraccess(mrlock_t *mrp) | ||
36 | { | ||
37 | down_read(&mrp->mr_lock); | ||
38 | } | ||
39 | |||
40 | static inline void mrupdate(mrlock_t *mrp) | ||
41 | { | ||
42 | down_write(&mrp->mr_lock); | ||
43 | mrp->mr_writer = 1; | ||
44 | } | ||
45 | |||
46 | static inline void mraccess_nested(mrlock_t *mrp, int subclass) | 41 | static inline void mraccess_nested(mrlock_t *mrp, int subclass) |
47 | { | 42 | { |
48 | down_read_nested(&mrp->mr_lock, subclass); | 43 | down_read_nested(&mrp->mr_lock, subclass); |
@@ -51,10 +46,11 @@ static inline void mraccess_nested(mrlock_t *mrp, int subclass) | |||
51 | static inline void mrupdate_nested(mrlock_t *mrp, int subclass) | 46 | static inline void mrupdate_nested(mrlock_t *mrp, int subclass) |
52 | { | 47 | { |
53 | down_write_nested(&mrp->mr_lock, subclass); | 48 | down_write_nested(&mrp->mr_lock, subclass); |
49 | #ifdef DEBUG | ||
54 | mrp->mr_writer = 1; | 50 | mrp->mr_writer = 1; |
51 | #endif | ||
55 | } | 52 | } |
56 | 53 | ||
57 | |||
58 | static inline int mrtryaccess(mrlock_t *mrp) | 54 | static inline int mrtryaccess(mrlock_t *mrp) |
59 | { | 55 | { |
60 | return down_read_trylock(&mrp->mr_lock); | 56 | return down_read_trylock(&mrp->mr_lock); |
@@ -64,39 +60,31 @@ static inline int mrtryupdate(mrlock_t *mrp) | |||
64 | { | 60 | { |
65 | if (!down_write_trylock(&mrp->mr_lock)) | 61 | if (!down_write_trylock(&mrp->mr_lock)) |
66 | return 0; | 62 | return 0; |
63 | #ifdef DEBUG | ||
67 | mrp->mr_writer = 1; | 64 | mrp->mr_writer = 1; |
65 | #endif | ||
68 | return 1; | 66 | return 1; |
69 | } | 67 | } |
70 | 68 | ||
71 | static inline void mrunlock(mrlock_t *mrp) | 69 | static inline void mrunlock_excl(mrlock_t *mrp) |
72 | { | 70 | { |
73 | if (mrp->mr_writer) { | 71 | #ifdef DEBUG |
74 | mrp->mr_writer = 0; | 72 | mrp->mr_writer = 0; |
75 | up_write(&mrp->mr_lock); | 73 | #endif |
76 | } else { | 74 | up_write(&mrp->mr_lock); |
77 | up_read(&mrp->mr_lock); | ||
78 | } | ||
79 | } | 75 | } |
80 | 76 | ||
81 | static inline void mrdemote(mrlock_t *mrp) | 77 | static inline void mrunlock_shared(mrlock_t *mrp) |
82 | { | 78 | { |
83 | mrp->mr_writer = 0; | 79 | up_read(&mrp->mr_lock); |
84 | downgrade_write(&mrp->mr_lock); | ||
85 | } | 80 | } |
86 | 81 | ||
87 | #ifdef DEBUG | 82 | static inline void mrdemote(mrlock_t *mrp) |
88 | /* | ||
89 | * Debug-only routine, without some platform-specific asm code, we can | ||
90 | * now only answer requests regarding whether we hold the lock for write | ||
91 | * (reader state is outside our visibility, we only track writer state). | ||
92 | * Note: means !ismrlocked would give false positives, so don't do that. | ||
93 | */ | ||
94 | static inline int ismrlocked(mrlock_t *mrp, int type) | ||
95 | { | 83 | { |
96 | if (mrp && type == MR_UPDATE) | 84 | #ifdef DEBUG |
97 | return mrp->mr_writer; | 85 | mrp->mr_writer = 0; |
98 | return 1; | ||
99 | } | ||
100 | #endif | 86 | #endif |
87 | downgrade_write(&mrp->mr_lock); | ||
88 | } | ||
101 | 89 | ||
102 | #endif /* __XFS_SUPPORT_MRLOCK_H__ */ | 90 | #endif /* __XFS_SUPPORT_MRLOCK_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 52f6846101d5..5105015a75ad 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -886,7 +886,7 @@ int | |||
886 | xfs_buf_lock_value( | 886 | xfs_buf_lock_value( |
887 | xfs_buf_t *bp) | 887 | xfs_buf_t *bp) |
888 | { | 888 | { |
889 | return atomic_read(&bp->b_sema.count); | 889 | return bp->b_sema.count; |
890 | } | 890 | } |
891 | #endif | 891 | #endif |
892 | 892 | ||
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index 265f0168ab76..c672b3238b14 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
@@ -133,7 +133,7 @@ xfs_nfs_get_inode( | |||
133 | if (!ip) | 133 | if (!ip) |
134 | return ERR_PTR(-EIO); | 134 | return ERR_PTR(-EIO); |
135 | 135 | ||
136 | if (!ip->i_d.di_mode || ip->i_d.di_gen != generation) { | 136 | if (ip->i_d.di_gen != generation) { |
137 | xfs_iput_new(ip, XFS_ILOCK_SHARED); | 137 | xfs_iput_new(ip, XFS_ILOCK_SHARED); |
138 | return ERR_PTR(-ENOENT); | 138 | return ERR_PTR(-ENOENT); |
139 | } | 139 | } |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 05905246434d..65e78c13d4ae 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -43,9 +43,6 @@ | |||
43 | #include <linux/smp_lock.h> | 43 | #include <linux/smp_lock.h> |
44 | 44 | ||
45 | static struct vm_operations_struct xfs_file_vm_ops; | 45 | static struct vm_operations_struct xfs_file_vm_ops; |
46 | #ifdef CONFIG_XFS_DMAPI | ||
47 | static struct vm_operations_struct xfs_dmapi_file_vm_ops; | ||
48 | #endif | ||
49 | 46 | ||
50 | STATIC_INLINE ssize_t | 47 | STATIC_INLINE ssize_t |
51 | __xfs_file_read( | 48 | __xfs_file_read( |
@@ -202,22 +199,6 @@ xfs_file_fsync( | |||
202 | (xfs_off_t)0, (xfs_off_t)-1); | 199 | (xfs_off_t)0, (xfs_off_t)-1); |
203 | } | 200 | } |
204 | 201 | ||
205 | #ifdef CONFIG_XFS_DMAPI | ||
206 | STATIC int | ||
207 | xfs_vm_fault( | ||
208 | struct vm_area_struct *vma, | ||
209 | struct vm_fault *vmf) | ||
210 | { | ||
211 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | ||
212 | bhv_vnode_t *vp = vn_from_inode(inode); | ||
213 | |||
214 | ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); | ||
215 | if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), vma, 0)) | ||
216 | return VM_FAULT_SIGBUS; | ||
217 | return filemap_fault(vma, vmf); | ||
218 | } | ||
219 | #endif /* CONFIG_XFS_DMAPI */ | ||
220 | |||
221 | /* | 202 | /* |
222 | * Unfortunately we can't just use the clean and simple readdir implementation | 203 | * Unfortunately we can't just use the clean and simple readdir implementation |
223 | * below, because nfs might call back into ->lookup from the filldir callback | 204 | * below, because nfs might call back into ->lookup from the filldir callback |
@@ -386,11 +367,6 @@ xfs_file_mmap( | |||
386 | vma->vm_ops = &xfs_file_vm_ops; | 367 | vma->vm_ops = &xfs_file_vm_ops; |
387 | vma->vm_flags |= VM_CAN_NONLINEAR; | 368 | vma->vm_flags |= VM_CAN_NONLINEAR; |
388 | 369 | ||
389 | #ifdef CONFIG_XFS_DMAPI | ||
390 | if (XFS_M(filp->f_path.dentry->d_inode->i_sb)->m_flags & XFS_MOUNT_DMAPI) | ||
391 | vma->vm_ops = &xfs_dmapi_file_vm_ops; | ||
392 | #endif /* CONFIG_XFS_DMAPI */ | ||
393 | |||
394 | file_accessed(filp); | 370 | file_accessed(filp); |
395 | return 0; | 371 | return 0; |
396 | } | 372 | } |
@@ -437,47 +413,6 @@ xfs_file_ioctl_invis( | |||
437 | return error; | 413 | return error; |
438 | } | 414 | } |
439 | 415 | ||
440 | #ifdef CONFIG_XFS_DMAPI | ||
441 | #ifdef HAVE_VMOP_MPROTECT | ||
442 | STATIC int | ||
443 | xfs_vm_mprotect( | ||
444 | struct vm_area_struct *vma, | ||
445 | unsigned int newflags) | ||
446 | { | ||
447 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | ||
448 | struct xfs_mount *mp = XFS_M(inode->i_sb); | ||
449 | int error = 0; | ||
450 | |||
451 | if (mp->m_flags & XFS_MOUNT_DMAPI) { | ||
452 | if ((vma->vm_flags & VM_MAYSHARE) && | ||
453 | (newflags & VM_WRITE) && !(vma->vm_flags & VM_WRITE)) | ||
454 | error = XFS_SEND_MMAP(mp, vma, VM_WRITE); | ||
455 | } | ||
456 | return error; | ||
457 | } | ||
458 | #endif /* HAVE_VMOP_MPROTECT */ | ||
459 | #endif /* CONFIG_XFS_DMAPI */ | ||
460 | |||
461 | #ifdef HAVE_FOP_OPEN_EXEC | ||
462 | /* If the user is attempting to execute a file that is offline then | ||
463 | * we have to trigger a DMAPI READ event before the file is marked as busy | ||
464 | * otherwise the invisible I/O will not be able to write to the file to bring | ||
465 | * it back online. | ||
466 | */ | ||
467 | STATIC int | ||
468 | xfs_file_open_exec( | ||
469 | struct inode *inode) | ||
470 | { | ||
471 | struct xfs_mount *mp = XFS_M(inode->i_sb); | ||
472 | struct xfs_inode *ip = XFS_I(inode); | ||
473 | |||
474 | if (unlikely(mp->m_flags & XFS_MOUNT_DMAPI) && | ||
475 | DM_EVENT_ENABLED(ip, DM_EVENT_READ)) | ||
476 | return -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL); | ||
477 | return 0; | ||
478 | } | ||
479 | #endif /* HAVE_FOP_OPEN_EXEC */ | ||
480 | |||
481 | /* | 416 | /* |
482 | * mmap()d file has taken write protection fault and is being made | 417 | * mmap()d file has taken write protection fault and is being made |
483 | * writable. We can set the page state up correctly for a writable | 418 | * writable. We can set the page state up correctly for a writable |
@@ -546,13 +481,3 @@ static struct vm_operations_struct xfs_file_vm_ops = { | |||
546 | .fault = filemap_fault, | 481 | .fault = filemap_fault, |
547 | .page_mkwrite = xfs_vm_page_mkwrite, | 482 | .page_mkwrite = xfs_vm_page_mkwrite, |
548 | }; | 483 | }; |
549 | |||
550 | #ifdef CONFIG_XFS_DMAPI | ||
551 | static struct vm_operations_struct xfs_dmapi_file_vm_ops = { | ||
552 | .fault = xfs_vm_fault, | ||
553 | .page_mkwrite = xfs_vm_page_mkwrite, | ||
554 | #ifdef HAVE_VMOP_MPROTECT | ||
555 | .mprotect = xfs_vm_mprotect, | ||
556 | #endif | ||
557 | }; | ||
558 | #endif /* CONFIG_XFS_DMAPI */ | ||
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 4ddb86b73c6b..a42ba9d71156 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -238,7 +238,7 @@ xfs_vget_fsop_handlereq( | |||
238 | return error; | 238 | return error; |
239 | if (ip == NULL) | 239 | if (ip == NULL) |
240 | return XFS_ERROR(EIO); | 240 | return XFS_ERROR(EIO); |
241 | if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) { | 241 | if (ip->i_d.di_gen != igen) { |
242 | xfs_iput_new(ip, XFS_ILOCK_SHARED); | 242 | xfs_iput_new(ip, XFS_ILOCK_SHARED); |
243 | return XFS_ERROR(ENOENT); | 243 | return XFS_ERROR(ENOENT); |
244 | } | 244 | } |
@@ -505,14 +505,14 @@ xfs_attrmulti_attr_get( | |||
505 | { | 505 | { |
506 | char *kbuf; | 506 | char *kbuf; |
507 | int error = EFAULT; | 507 | int error = EFAULT; |
508 | 508 | ||
509 | if (*len > XATTR_SIZE_MAX) | 509 | if (*len > XATTR_SIZE_MAX) |
510 | return EINVAL; | 510 | return EINVAL; |
511 | kbuf = kmalloc(*len, GFP_KERNEL); | 511 | kbuf = kmalloc(*len, GFP_KERNEL); |
512 | if (!kbuf) | 512 | if (!kbuf) |
513 | return ENOMEM; | 513 | return ENOMEM; |
514 | 514 | ||
515 | error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags, NULL); | 515 | error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); |
516 | if (error) | 516 | if (error) |
517 | goto out_kfree; | 517 | goto out_kfree; |
518 | 518 | ||
@@ -546,7 +546,7 @@ xfs_attrmulti_attr_set( | |||
546 | 546 | ||
547 | if (copy_from_user(kbuf, ubuf, len)) | 547 | if (copy_from_user(kbuf, ubuf, len)) |
548 | goto out_kfree; | 548 | goto out_kfree; |
549 | 549 | ||
550 | error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); | 550 | error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); |
551 | 551 | ||
552 | out_kfree: | 552 | out_kfree: |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index a1237dad6430..2bf287ef5489 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -511,7 +511,8 @@ xfs_vn_rename( | |||
511 | xfs_dentry_to_name(&nname, ndentry); | 511 | xfs_dentry_to_name(&nname, ndentry); |
512 | 512 | ||
513 | error = xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode), | 513 | error = xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode), |
514 | XFS_I(ndir), &nname); | 514 | XFS_I(ndir), &nname, new_inode ? |
515 | XFS_I(new_inode) : NULL); | ||
515 | if (likely(!error)) { | 516 | if (likely(!error)) { |
516 | if (new_inode) | 517 | if (new_inode) |
517 | xfs_validate_fields(new_inode); | 518 | xfs_validate_fields(new_inode); |
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index e5143323e71f..1bc9f600365f 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -99,7 +99,6 @@ | |||
99 | /* | 99 | /* |
100 | * Feature macros (disable/enable) | 100 | * Feature macros (disable/enable) |
101 | */ | 101 | */ |
102 | #define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */ | ||
103 | #ifdef CONFIG_SMP | 102 | #ifdef CONFIG_SMP |
104 | #define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ | 103 | #define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ |
105 | #else | 104 | #else |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 1ebd8004469c..5e3b57516ec7 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -394,7 +394,7 @@ xfs_zero_last_block( | |||
394 | int error = 0; | 394 | int error = 0; |
395 | xfs_bmbt_irec_t imap; | 395 | xfs_bmbt_irec_t imap; |
396 | 396 | ||
397 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); | 397 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
398 | 398 | ||
399 | zero_offset = XFS_B_FSB_OFFSET(mp, isize); | 399 | zero_offset = XFS_B_FSB_OFFSET(mp, isize); |
400 | if (zero_offset == 0) { | 400 | if (zero_offset == 0) { |
@@ -425,14 +425,14 @@ xfs_zero_last_block( | |||
425 | * out sync. We need to drop the ilock while we do this so we | 425 | * out sync. We need to drop the ilock while we do this so we |
426 | * don't deadlock when the buffer cache calls back to us. | 426 | * don't deadlock when the buffer cache calls back to us. |
427 | */ | 427 | */ |
428 | xfs_iunlock(ip, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD); | 428 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
429 | 429 | ||
430 | zero_len = mp->m_sb.sb_blocksize - zero_offset; | 430 | zero_len = mp->m_sb.sb_blocksize - zero_offset; |
431 | if (isize + zero_len > offset) | 431 | if (isize + zero_len > offset) |
432 | zero_len = offset - isize; | 432 | zero_len = offset - isize; |
433 | error = xfs_iozero(ip, isize, zero_len); | 433 | error = xfs_iozero(ip, isize, zero_len); |
434 | 434 | ||
435 | xfs_ilock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 435 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
436 | ASSERT(error >= 0); | 436 | ASSERT(error >= 0); |
437 | return error; | 437 | return error; |
438 | } | 438 | } |
@@ -465,8 +465,7 @@ xfs_zero_eof( | |||
465 | int error = 0; | 465 | int error = 0; |
466 | xfs_bmbt_irec_t imap; | 466 | xfs_bmbt_irec_t imap; |
467 | 467 | ||
468 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 468 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
469 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); | ||
470 | ASSERT(offset > isize); | 469 | ASSERT(offset > isize); |
471 | 470 | ||
472 | /* | 471 | /* |
@@ -475,8 +474,7 @@ xfs_zero_eof( | |||
475 | */ | 474 | */ |
476 | error = xfs_zero_last_block(ip, offset, isize); | 475 | error = xfs_zero_last_block(ip, offset, isize); |
477 | if (error) { | 476 | if (error) { |
478 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 477 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
479 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); | ||
480 | return error; | 478 | return error; |
481 | } | 479 | } |
482 | 480 | ||
@@ -507,8 +505,7 @@ xfs_zero_eof( | |||
507 | error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb, | 505 | error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb, |
508 | 0, NULL, 0, &imap, &nimaps, NULL, NULL); | 506 | 0, NULL, 0, &imap, &nimaps, NULL, NULL); |
509 | if (error) { | 507 | if (error) { |
510 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 508 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
511 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); | ||
512 | return error; | 509 | return error; |
513 | } | 510 | } |
514 | ASSERT(nimaps > 0); | 511 | ASSERT(nimaps > 0); |
@@ -532,7 +529,7 @@ xfs_zero_eof( | |||
532 | * Drop the inode lock while we're doing the I/O. | 529 | * Drop the inode lock while we're doing the I/O. |
533 | * We'll still have the iolock to protect us. | 530 | * We'll still have the iolock to protect us. |
534 | */ | 531 | */ |
535 | xfs_iunlock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 532 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
536 | 533 | ||
537 | zero_off = XFS_FSB_TO_B(mp, start_zero_fsb); | 534 | zero_off = XFS_FSB_TO_B(mp, start_zero_fsb); |
538 | zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount); | 535 | zero_len = XFS_FSB_TO_B(mp, imap.br_blockcount); |
@@ -548,13 +545,13 @@ xfs_zero_eof( | |||
548 | start_zero_fsb = imap.br_startoff + imap.br_blockcount; | 545 | start_zero_fsb = imap.br_startoff + imap.br_blockcount; |
549 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); | 546 | ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); |
550 | 547 | ||
551 | xfs_ilock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 548 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
552 | } | 549 | } |
553 | 550 | ||
554 | return 0; | 551 | return 0; |
555 | 552 | ||
556 | out_lock: | 553 | out_lock: |
557 | xfs_ilock(ip, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); | 554 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
558 | ASSERT(error >= 0); | 555 | ASSERT(error >= 0); |
559 | return error; | 556 | return error; |
560 | } | 557 | } |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h index e1d498b4ba7a..e6be37dbd0e9 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.h +++ b/fs/xfs/linux-2.6/xfs_lrw.h | |||
@@ -50,7 +50,6 @@ struct xfs_iomap; | |||
50 | #define XFS_INVAL_CACHED 18 | 50 | #define XFS_INVAL_CACHED 18 |
51 | #define XFS_DIORD_ENTER 19 | 51 | #define XFS_DIORD_ENTER 19 |
52 | #define XFS_DIOWR_ENTER 20 | 52 | #define XFS_DIOWR_ENTER 20 |
53 | #define XFS_SENDFILE_ENTER 21 | ||
54 | #define XFS_WRITEPAGE_ENTER 22 | 53 | #define XFS_WRITEPAGE_ENTER 22 |
55 | #define XFS_RELEASEPAGE_ENTER 23 | 54 | #define XFS_RELEASEPAGE_ENTER 23 |
56 | #define XFS_INVALIDPAGE_ENTER 24 | 55 | #define XFS_INVALIDPAGE_ENTER 24 |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 865eb708aa95..742b2c7852c1 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1181,7 +1181,7 @@ xfs_fs_statfs( | |||
1181 | statp->f_fsid.val[0] = (u32)id; | 1181 | statp->f_fsid.val[0] = (u32)id; |
1182 | statp->f_fsid.val[1] = (u32)(id >> 32); | 1182 | statp->f_fsid.val[1] = (u32)(id >> 32); |
1183 | 1183 | ||
1184 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); | 1184 | xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); |
1185 | 1185 | ||
1186 | spin_lock(&mp->m_sb_lock); | 1186 | spin_lock(&mp->m_sb_lock); |
1187 | statp->f_bsize = sbp->sb_blocksize; | 1187 | statp->f_bsize = sbp->sb_blocksize; |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 8b4d63ce8694..9d73cb5c0fc7 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -25,12 +25,6 @@ struct attrlist_cursor_kern; | |||
25 | 25 | ||
26 | typedef struct inode bhv_vnode_t; | 26 | typedef struct inode bhv_vnode_t; |
27 | 27 | ||
28 | #define VN_ISLNK(vp) S_ISLNK((vp)->i_mode) | ||
29 | #define VN_ISREG(vp) S_ISREG((vp)->i_mode) | ||
30 | #define VN_ISDIR(vp) S_ISDIR((vp)->i_mode) | ||
31 | #define VN_ISCHR(vp) S_ISCHR((vp)->i_mode) | ||
32 | #define VN_ISBLK(vp) S_ISBLK((vp)->i_mode) | ||
33 | |||
34 | /* | 28 | /* |
35 | * Vnode to Linux inode mapping. | 29 | * Vnode to Linux inode mapping. |
36 | */ | 30 | */ |
@@ -151,24 +145,6 @@ typedef struct bhv_vattr { | |||
151 | XFS_AT_TYPE|XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|\ | 145 | XFS_AT_TYPE|XFS_AT_BLKSIZE|XFS_AT_NBLOCKS|XFS_AT_VCODE|\ |
152 | XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_GENCOUNT) | 146 | XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS|XFS_AT_GENCOUNT) |
153 | 147 | ||
154 | /* | ||
155 | * Modes. | ||
156 | */ | ||
157 | #define VSUID S_ISUID /* set user id on execution */ | ||
158 | #define VSGID S_ISGID /* set group id on execution */ | ||
159 | #define VSVTX S_ISVTX /* save swapped text even after use */ | ||
160 | #define VREAD S_IRUSR /* read, write, execute permissions */ | ||
161 | #define VWRITE S_IWUSR | ||
162 | #define VEXEC S_IXUSR | ||
163 | |||
164 | #define MODEMASK S_IALLUGO /* mode bits plus permission bits */ | ||
165 | |||
166 | /* | ||
167 | * Check whether mandatory file locking is enabled. | ||
168 | */ | ||
169 | #define MANDLOCK(vp, mode) \ | ||
170 | (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) | ||
171 | |||
172 | extern void vn_init(void); | 148 | extern void vn_init(void); |
173 | extern int vn_revalidate(bhv_vnode_t *); | 149 | extern int vn_revalidate(bhv_vnode_t *); |
174 | 150 | ||
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 631ebb31b295..85df3288efd5 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -933,7 +933,7 @@ xfs_qm_dqget( | |||
933 | type == XFS_DQ_PROJ || | 933 | type == XFS_DQ_PROJ || |
934 | type == XFS_DQ_GROUP); | 934 | type == XFS_DQ_GROUP); |
935 | if (ip) { | 935 | if (ip) { |
936 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 936 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
937 | if (type == XFS_DQ_USER) | 937 | if (type == XFS_DQ_USER) |
938 | ASSERT(ip->i_udquot == NULL); | 938 | ASSERT(ip->i_udquot == NULL); |
939 | else | 939 | else |
@@ -1088,7 +1088,7 @@ xfs_qm_dqget( | |||
1088 | xfs_qm_mplist_unlock(mp); | 1088 | xfs_qm_mplist_unlock(mp); |
1089 | XFS_DQ_HASH_UNLOCK(h); | 1089 | XFS_DQ_HASH_UNLOCK(h); |
1090 | dqret: | 1090 | dqret: |
1091 | ASSERT((ip == NULL) || XFS_ISLOCKED_INODE_EXCL(ip)); | 1091 | ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
1092 | xfs_dqtrace_entry(dqp, "DQGET DONE"); | 1092 | xfs_dqtrace_entry(dqp, "DQGET DONE"); |
1093 | *O_dqpp = dqp; | 1093 | *O_dqpp = dqp; |
1094 | return (0); | 1094 | return (0); |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 40ea56409561..d31cce1165c5 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -670,7 +670,7 @@ xfs_qm_dqattach_one( | |||
670 | xfs_dquot_t *dqp; | 670 | xfs_dquot_t *dqp; |
671 | int error; | 671 | int error; |
672 | 672 | ||
673 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 673 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
674 | error = 0; | 674 | error = 0; |
675 | /* | 675 | /* |
676 | * See if we already have it in the inode itself. IO_idqpp is | 676 | * See if we already have it in the inode itself. IO_idqpp is |
@@ -874,7 +874,7 @@ xfs_qm_dqattach( | |||
874 | return 0; | 874 | return 0; |
875 | 875 | ||
876 | ASSERT((flags & XFS_QMOPT_ILOCKED) == 0 || | 876 | ASSERT((flags & XFS_QMOPT_ILOCKED) == 0 || |
877 | XFS_ISLOCKED_INODE_EXCL(ip)); | 877 | xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
878 | 878 | ||
879 | if (! (flags & XFS_QMOPT_ILOCKED)) | 879 | if (! (flags & XFS_QMOPT_ILOCKED)) |
880 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 880 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
@@ -888,7 +888,8 @@ xfs_qm_dqattach( | |||
888 | goto done; | 888 | goto done; |
889 | nquotas++; | 889 | nquotas++; |
890 | } | 890 | } |
891 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 891 | |
892 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | ||
892 | if (XFS_IS_OQUOTA_ON(mp)) { | 893 | if (XFS_IS_OQUOTA_ON(mp)) { |
893 | error = XFS_IS_GQUOTA_ON(mp) ? | 894 | error = XFS_IS_GQUOTA_ON(mp) ? |
894 | xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, | 895 | xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, |
@@ -913,7 +914,7 @@ xfs_qm_dqattach( | |||
913 | * This WON'T, in general, result in a thrash. | 914 | * This WON'T, in general, result in a thrash. |
914 | */ | 915 | */ |
915 | if (nquotas == 2) { | 916 | if (nquotas == 2) { |
916 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 917 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
917 | ASSERT(ip->i_udquot); | 918 | ASSERT(ip->i_udquot); |
918 | ASSERT(ip->i_gdquot); | 919 | ASSERT(ip->i_gdquot); |
919 | 920 | ||
@@ -956,7 +957,7 @@ xfs_qm_dqattach( | |||
956 | 957 | ||
957 | #ifdef QUOTADEBUG | 958 | #ifdef QUOTADEBUG |
958 | else | 959 | else |
959 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 960 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
960 | #endif | 961 | #endif |
961 | return error; | 962 | return error; |
962 | } | 963 | } |
@@ -1291,7 +1292,7 @@ xfs_qm_dqget_noattach( | |||
1291 | xfs_mount_t *mp; | 1292 | xfs_mount_t *mp; |
1292 | xfs_dquot_t *udqp, *gdqp; | 1293 | xfs_dquot_t *udqp, *gdqp; |
1293 | 1294 | ||
1294 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 1295 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
1295 | mp = ip->i_mount; | 1296 | mp = ip->i_mount; |
1296 | udqp = NULL; | 1297 | udqp = NULL; |
1297 | gdqp = NULL; | 1298 | gdqp = NULL; |
@@ -1392,7 +1393,7 @@ xfs_qm_qino_alloc( | |||
1392 | * Keep an extra reference to this quota inode. This inode is | 1393 | * Keep an extra reference to this quota inode. This inode is |
1393 | * locked exclusively and joined to the transaction already. | 1394 | * locked exclusively and joined to the transaction already. |
1394 | */ | 1395 | */ |
1395 | ASSERT(XFS_ISLOCKED_INODE_EXCL(*ip)); | 1396 | ASSERT(xfs_isilocked(*ip, XFS_ILOCK_EXCL)); |
1396 | VN_HOLD(XFS_ITOV((*ip))); | 1397 | VN_HOLD(XFS_ITOV((*ip))); |
1397 | 1398 | ||
1398 | /* | 1399 | /* |
@@ -1737,12 +1738,6 @@ xfs_qm_dqusage_adjust( | |||
1737 | return error; | 1738 | return error; |
1738 | } | 1739 | } |
1739 | 1740 | ||
1740 | if (ip->i_d.di_mode == 0) { | ||
1741 | xfs_iput_new(ip, XFS_ILOCK_EXCL); | ||
1742 | *res = BULKSTAT_RV_NOTHING; | ||
1743 | return XFS_ERROR(ENOENT); | ||
1744 | } | ||
1745 | |||
1746 | /* | 1741 | /* |
1747 | * Obtain the locked dquots. In case of an error (eg. allocation | 1742 | * Obtain the locked dquots. In case of an error (eg. allocation |
1748 | * fails for ENOSPC), we return the negative of the error number | 1743 | * fails for ENOSPC), we return the negative of the error number |
@@ -2563,7 +2558,7 @@ xfs_qm_vop_chown( | |||
2563 | uint bfield = XFS_IS_REALTIME_INODE(ip) ? | 2558 | uint bfield = XFS_IS_REALTIME_INODE(ip) ? |
2564 | XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; | 2559 | XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT; |
2565 | 2560 | ||
2566 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 2561 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2567 | ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); | 2562 | ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); |
2568 | 2563 | ||
2569 | /* old dquot */ | 2564 | /* old dquot */ |
@@ -2607,7 +2602,7 @@ xfs_qm_vop_chown_reserve( | |||
2607 | uint delblks, blkflags, prjflags = 0; | 2602 | uint delblks, blkflags, prjflags = 0; |
2608 | xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; | 2603 | xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; |
2609 | 2604 | ||
2610 | ASSERT(XFS_ISLOCKED_INODE(ip)); | 2605 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
2611 | mp = ip->i_mount; | 2606 | mp = ip->i_mount; |
2612 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); | 2607 | ASSERT(XFS_IS_QUOTA_RUNNING(mp)); |
2613 | 2608 | ||
@@ -2717,7 +2712,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode( | |||
2717 | if (!XFS_IS_QUOTA_ON(tp->t_mountp)) | 2712 | if (!XFS_IS_QUOTA_ON(tp->t_mountp)) |
2718 | return; | 2713 | return; |
2719 | 2714 | ||
2720 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 2715 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2721 | ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp)); | 2716 | ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp)); |
2722 | 2717 | ||
2723 | if (udqp) { | 2718 | if (udqp) { |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 8342823dbdc3..768a3b27d2b6 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -1366,12 +1366,6 @@ xfs_qm_internalqcheck_adjust( | |||
1366 | return (error); | 1366 | return (error); |
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | if (ip->i_d.di_mode == 0) { | ||
1370 | xfs_iput_new(ip, lock_flags); | ||
1371 | *res = BULKSTAT_RV_NOTHING; | ||
1372 | return XFS_ERROR(ENOENT); | ||
1373 | } | ||
1374 | |||
1375 | /* | 1369 | /* |
1376 | * This inode can have blocks after eof which can get released | 1370 | * This inode can have blocks after eof which can get released |
1377 | * when we send it to inactive. Since we don't check the dquot | 1371 | * when we send it to inactive. Since we don't check the dquot |
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index a8b85e2be9d5..5e4a40b1c565 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h | |||
@@ -27,11 +27,6 @@ | |||
27 | /* Number of dquots that fit in to a dquot block */ | 27 | /* Number of dquots that fit in to a dquot block */ |
28 | #define XFS_QM_DQPERBLK(mp) ((mp)->m_quotainfo->qi_dqperchunk) | 28 | #define XFS_QM_DQPERBLK(mp) ((mp)->m_quotainfo->qi_dqperchunk) |
29 | 29 | ||
30 | #define XFS_ISLOCKED_INODE(ip) (ismrlocked(&(ip)->i_lock, \ | ||
31 | MR_UPDATE | MR_ACCESS) != 0) | ||
32 | #define XFS_ISLOCKED_INODE_EXCL(ip) (ismrlocked(&(ip)->i_lock, \ | ||
33 | MR_UPDATE) != 0) | ||
34 | |||
35 | #define XFS_DQ_IS_ADDEDTO_TRX(t, d) ((d)->q_transp == (t)) | 30 | #define XFS_DQ_IS_ADDEDTO_TRX(t, d) ((d)->q_transp == (t)) |
36 | 31 | ||
37 | #define XFS_QI_MPLRECLAIMS(mp) ((mp)->m_quotainfo->qi_dqreclaims) | 32 | #define XFS_QI_MPLRECLAIMS(mp) ((mp)->m_quotainfo->qi_dqreclaims) |
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index f441f836ca8b..99611381e740 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -834,7 +834,7 @@ xfs_trans_reserve_quota_nblks( | |||
834 | ASSERT(ip->i_ino != mp->m_sb.sb_uquotino); | 834 | ASSERT(ip->i_ino != mp->m_sb.sb_uquotino); |
835 | ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); | 835 | ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); |
836 | 836 | ||
837 | ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); | 837 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
838 | ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); | 838 | ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); |
839 | ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == | 839 | ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) == |
840 | XFS_TRANS_DQ_RES_RTBLKS || | 840 | XFS_TRANS_DQ_RES_RTBLKS || |
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h index 765aaf65e2d3..540e4c989825 100644 --- a/fs/xfs/xfs.h +++ b/fs/xfs/xfs.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #define STATIC | 22 | #define STATIC |
23 | #define DEBUG 1 | 23 | #define DEBUG 1 |
24 | #define XFS_BUF_LOCK_TRACKING 1 | 24 | #define XFS_BUF_LOCK_TRACKING 1 |
25 | #define QUOTADEBUG 1 | 25 | /* #define QUOTADEBUG 1 */ |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #ifdef CONFIG_XFS_TRACE | 28 | #ifdef CONFIG_XFS_TRACE |
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 8e130b9720ae..ebee3a4f703a 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -72,7 +72,7 @@ xfs_acl_vhasacl_default( | |||
72 | { | 72 | { |
73 | int error; | 73 | int error; |
74 | 74 | ||
75 | if (!VN_ISDIR(vp)) | 75 | if (!S_ISDIR(vp->i_mode)) |
76 | return 0; | 76 | return 0; |
77 | xfs_acl_get_attr(vp, NULL, _ACL_TYPE_DEFAULT, ATTR_KERNOVAL, &error); | 77 | xfs_acl_get_attr(vp, NULL, _ACL_TYPE_DEFAULT, ATTR_KERNOVAL, &error); |
78 | return (error == 0); | 78 | return (error == 0); |
@@ -238,15 +238,8 @@ xfs_acl_vget( | |||
238 | error = EINVAL; | 238 | error = EINVAL; |
239 | goto out; | 239 | goto out; |
240 | } | 240 | } |
241 | if (kind == _ACL_TYPE_ACCESS) { | 241 | if (kind == _ACL_TYPE_ACCESS) |
242 | bhv_vattr_t va; | 242 | xfs_acl_sync_mode(xfs_vtoi(vp)->i_d.di_mode, xfs_acl); |
243 | |||
244 | va.va_mask = XFS_AT_MODE; | ||
245 | error = xfs_getattr(xfs_vtoi(vp), &va, 0); | ||
246 | if (error) | ||
247 | goto out; | ||
248 | xfs_acl_sync_mode(va.va_mode, xfs_acl); | ||
249 | } | ||
250 | error = -posix_acl_xfs_to_xattr(xfs_acl, ext_acl, size); | 243 | error = -posix_acl_xfs_to_xattr(xfs_acl, ext_acl, size); |
251 | } | 244 | } |
252 | out: | 245 | out: |
@@ -341,14 +334,15 @@ xfs_acl_iaccess( | |||
341 | { | 334 | { |
342 | xfs_acl_t *acl; | 335 | xfs_acl_t *acl; |
343 | int rval; | 336 | int rval; |
337 | struct xfs_name acl_name = {SGI_ACL_FILE, SGI_ACL_FILE_SIZE}; | ||
344 | 338 | ||
345 | if (!(_ACL_ALLOC(acl))) | 339 | if (!(_ACL_ALLOC(acl))) |
346 | return -1; | 340 | return -1; |
347 | 341 | ||
348 | /* If the file has no ACL return -1. */ | 342 | /* If the file has no ACL return -1. */ |
349 | rval = sizeof(xfs_acl_t); | 343 | rval = sizeof(xfs_acl_t); |
350 | if (xfs_attr_fetch(ip, SGI_ACL_FILE, SGI_ACL_FILE_SIZE, | 344 | if (xfs_attr_fetch(ip, &acl_name, (char *)acl, &rval, |
351 | (char *)acl, &rval, ATTR_ROOT | ATTR_KERNACCESS, cr)) { | 345 | ATTR_ROOT | ATTR_KERNACCESS)) { |
352 | _ACL_FREE(acl); | 346 | _ACL_FREE(acl); |
353 | return -1; | 347 | return -1; |
354 | } | 348 | } |
@@ -373,23 +367,15 @@ xfs_acl_allow_set( | |||
373 | bhv_vnode_t *vp, | 367 | bhv_vnode_t *vp, |
374 | int kind) | 368 | int kind) |
375 | { | 369 | { |
376 | xfs_inode_t *ip = xfs_vtoi(vp); | ||
377 | bhv_vattr_t va; | ||
378 | int error; | ||
379 | |||
380 | if (vp->i_flags & (S_IMMUTABLE|S_APPEND)) | 370 | if (vp->i_flags & (S_IMMUTABLE|S_APPEND)) |
381 | return EPERM; | 371 | return EPERM; |
382 | if (kind == _ACL_TYPE_DEFAULT && !VN_ISDIR(vp)) | 372 | if (kind == _ACL_TYPE_DEFAULT && !S_ISDIR(vp->i_mode)) |
383 | return ENOTDIR; | 373 | return ENOTDIR; |
384 | if (vp->i_sb->s_flags & MS_RDONLY) | 374 | if (vp->i_sb->s_flags & MS_RDONLY) |
385 | return EROFS; | 375 | return EROFS; |
386 | va.va_mask = XFS_AT_UID; | 376 | if (xfs_vtoi(vp)->i_d.di_uid != current->fsuid && !capable(CAP_FOWNER)) |
387 | error = xfs_getattr(ip, &va, 0); | ||
388 | if (error) | ||
389 | return error; | ||
390 | if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) | ||
391 | return EPERM; | 377 | return EPERM; |
392 | return error; | 378 | return 0; |
393 | } | 379 | } |
394 | 380 | ||
395 | /* | 381 | /* |
@@ -594,7 +580,7 @@ xfs_acl_get_attr( | |||
594 | *error = xfs_attr_get(xfs_vtoi(vp), | 580 | *error = xfs_attr_get(xfs_vtoi(vp), |
595 | kind == _ACL_TYPE_ACCESS ? | 581 | kind == _ACL_TYPE_ACCESS ? |
596 | SGI_ACL_FILE : SGI_ACL_DEFAULT, | 582 | SGI_ACL_FILE : SGI_ACL_DEFAULT, |
597 | (char *)aclp, &len, flags, sys_cred); | 583 | (char *)aclp, &len, flags); |
598 | if (*error || (flags & ATTR_KERNOVAL)) | 584 | if (*error || (flags & ATTR_KERNOVAL)) |
599 | return; | 585 | return; |
600 | xfs_acl_get_endian(aclp); | 586 | xfs_acl_get_endian(aclp); |
@@ -643,7 +629,6 @@ xfs_acl_vtoacl( | |||
643 | xfs_acl_t *access_acl, | 629 | xfs_acl_t *access_acl, |
644 | xfs_acl_t *default_acl) | 630 | xfs_acl_t *default_acl) |
645 | { | 631 | { |
646 | bhv_vattr_t va; | ||
647 | int error = 0; | 632 | int error = 0; |
648 | 633 | ||
649 | if (access_acl) { | 634 | if (access_acl) { |
@@ -652,16 +637,10 @@ xfs_acl_vtoacl( | |||
652 | * be obtained for some reason, invalidate the access ACL. | 637 | * be obtained for some reason, invalidate the access ACL. |
653 | */ | 638 | */ |
654 | xfs_acl_get_attr(vp, access_acl, _ACL_TYPE_ACCESS, 0, &error); | 639 | xfs_acl_get_attr(vp, access_acl, _ACL_TYPE_ACCESS, 0, &error); |
655 | if (!error) { | ||
656 | /* Got the ACL, need the mode... */ | ||
657 | va.va_mask = XFS_AT_MODE; | ||
658 | error = xfs_getattr(xfs_vtoi(vp), &va, 0); | ||
659 | } | ||
660 | |||
661 | if (error) | 640 | if (error) |
662 | access_acl->acl_cnt = XFS_ACL_NOT_PRESENT; | 641 | access_acl->acl_cnt = XFS_ACL_NOT_PRESENT; |
663 | else /* We have a good ACL and the file mode, synchronize. */ | 642 | else /* We have a good ACL and the file mode, synchronize. */ |
664 | xfs_acl_sync_mode(va.va_mode, access_acl); | 643 | xfs_acl_sync_mode(xfs_vtoi(vp)->i_d.di_mode, access_acl); |
665 | } | 644 | } |
666 | 645 | ||
667 | if (default_acl) { | 646 | if (default_acl) { |
@@ -719,7 +698,7 @@ xfs_acl_inherit( | |||
719 | * If the new file is a directory, its default ACL is a copy of | 698 | * If the new file is a directory, its default ACL is a copy of |
720 | * the containing directory's default ACL. | 699 | * the containing directory's default ACL. |
721 | */ | 700 | */ |
722 | if (VN_ISDIR(vp)) | 701 | if (S_ISDIR(vp->i_mode)) |
723 | xfs_acl_set_attr(vp, pdaclp, _ACL_TYPE_DEFAULT, &error); | 702 | xfs_acl_set_attr(vp, pdaclp, _ACL_TYPE_DEFAULT, &error); |
724 | if (!error && !basicperms) | 703 | if (!error && !basicperms) |
725 | xfs_acl_set_attr(vp, cacl, _ACL_TYPE_ACCESS, &error); | 704 | xfs_acl_set_attr(vp, cacl, _ACL_TYPE_ACCESS, &error); |
@@ -744,7 +723,7 @@ xfs_acl_setmode( | |||
744 | bhv_vattr_t va; | 723 | bhv_vattr_t va; |
745 | xfs_acl_entry_t *ap; | 724 | xfs_acl_entry_t *ap; |
746 | xfs_acl_entry_t *gap = NULL; | 725 | xfs_acl_entry_t *gap = NULL; |
747 | int i, error, nomask = 1; | 726 | int i, nomask = 1; |
748 | 727 | ||
749 | *basicperms = 1; | 728 | *basicperms = 1; |
750 | 729 | ||
@@ -756,11 +735,7 @@ xfs_acl_setmode( | |||
756 | * mode. The m:: bits take precedence over the g:: bits. | 735 | * mode. The m:: bits take precedence over the g:: bits. |
757 | */ | 736 | */ |
758 | va.va_mask = XFS_AT_MODE; | 737 | va.va_mask = XFS_AT_MODE; |
759 | error = xfs_getattr(xfs_vtoi(vp), &va, 0); | 738 | va.va_mode = xfs_vtoi(vp)->i_d.di_mode; |
760 | if (error) | ||
761 | return error; | ||
762 | |||
763 | va.va_mask = XFS_AT_MODE; | ||
764 | va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); | 739 | va.va_mode &= ~(S_IRWXU|S_IRWXG|S_IRWXO); |
765 | ap = acl->acl_entry; | 740 | ap = acl->acl_entry; |
766 | for (i = 0; i < acl->acl_cnt; ++i) { | 741 | for (i = 0; i < acl->acl_cnt; ++i) { |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 36d781ee5fcc..df151a859186 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -101,14 +101,28 @@ STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); | |||
101 | ktrace_t *xfs_attr_trace_buf; | 101 | ktrace_t *xfs_attr_trace_buf; |
102 | #endif | 102 | #endif |
103 | 103 | ||
104 | STATIC int | ||
105 | xfs_attr_name_to_xname( | ||
106 | struct xfs_name *xname, | ||
107 | const char *aname) | ||
108 | { | ||
109 | if (!aname) | ||
110 | return EINVAL; | ||
111 | xname->name = aname; | ||
112 | xname->len = strlen(aname); | ||
113 | if (xname->len >= MAXNAMELEN) | ||
114 | return EFAULT; /* match IRIX behaviour */ | ||
115 | |||
116 | return 0; | ||
117 | } | ||
104 | 118 | ||
105 | /*======================================================================== | 119 | /*======================================================================== |
106 | * Overall external interface routines. | 120 | * Overall external interface routines. |
107 | *========================================================================*/ | 121 | *========================================================================*/ |
108 | 122 | ||
109 | int | 123 | int |
110 | xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen, | 124 | xfs_attr_fetch(xfs_inode_t *ip, struct xfs_name *name, |
111 | char *value, int *valuelenp, int flags, struct cred *cred) | 125 | char *value, int *valuelenp, int flags) |
112 | { | 126 | { |
113 | xfs_da_args_t args; | 127 | xfs_da_args_t args; |
114 | int error; | 128 | int error; |
@@ -122,8 +136,8 @@ xfs_attr_fetch(xfs_inode_t *ip, const char *name, int namelen, | |||
122 | * Fill in the arg structure for this request. | 136 | * Fill in the arg structure for this request. |
123 | */ | 137 | */ |
124 | memset((char *)&args, 0, sizeof(args)); | 138 | memset((char *)&args, 0, sizeof(args)); |
125 | args.name = name; | 139 | args.name = name->name; |
126 | args.namelen = namelen; | 140 | args.namelen = name->len; |
127 | args.value = value; | 141 | args.value = value; |
128 | args.valuelen = *valuelenp; | 142 | args.valuelen = *valuelenp; |
129 | args.flags = flags; | 143 | args.flags = flags; |
@@ -162,31 +176,29 @@ xfs_attr_get( | |||
162 | const char *name, | 176 | const char *name, |
163 | char *value, | 177 | char *value, |
164 | int *valuelenp, | 178 | int *valuelenp, |
165 | int flags, | 179 | int flags) |
166 | cred_t *cred) | ||
167 | { | 180 | { |
168 | int error, namelen; | 181 | int error; |
182 | struct xfs_name xname; | ||
169 | 183 | ||
170 | XFS_STATS_INC(xs_attr_get); | 184 | XFS_STATS_INC(xs_attr_get); |
171 | 185 | ||
172 | if (!name) | ||
173 | return(EINVAL); | ||
174 | namelen = strlen(name); | ||
175 | if (namelen >= MAXNAMELEN) | ||
176 | return(EFAULT); /* match IRIX behaviour */ | ||
177 | |||
178 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 186 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
179 | return(EIO); | 187 | return(EIO); |
180 | 188 | ||
189 | error = xfs_attr_name_to_xname(&xname, name); | ||
190 | if (error) | ||
191 | return error; | ||
192 | |||
181 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 193 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
182 | error = xfs_attr_fetch(ip, name, namelen, value, valuelenp, flags, cred); | 194 | error = xfs_attr_fetch(ip, &xname, value, valuelenp, flags); |
183 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | 195 | xfs_iunlock(ip, XFS_ILOCK_SHARED); |
184 | return(error); | 196 | return(error); |
185 | } | 197 | } |
186 | 198 | ||
187 | int | 199 | STATIC int |
188 | xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, | 200 | xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name, |
189 | char *value, int valuelen, int flags) | 201 | char *value, int valuelen, int flags) |
190 | { | 202 | { |
191 | xfs_da_args_t args; | 203 | xfs_da_args_t args; |
192 | xfs_fsblock_t firstblock; | 204 | xfs_fsblock_t firstblock; |
@@ -209,7 +221,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, | |||
209 | */ | 221 | */ |
210 | if (XFS_IFORK_Q(dp) == 0) { | 222 | if (XFS_IFORK_Q(dp) == 0) { |
211 | int sf_size = sizeof(xfs_attr_sf_hdr_t) + | 223 | int sf_size = sizeof(xfs_attr_sf_hdr_t) + |
212 | XFS_ATTR_SF_ENTSIZE_BYNAME(namelen, valuelen); | 224 | XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen); |
213 | 225 | ||
214 | if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd))) | 226 | if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd))) |
215 | return(error); | 227 | return(error); |
@@ -219,8 +231,8 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, | |||
219 | * Fill in the arg structure for this request. | 231 | * Fill in the arg structure for this request. |
220 | */ | 232 | */ |
221 | memset((char *)&args, 0, sizeof(args)); | 233 | memset((char *)&args, 0, sizeof(args)); |
222 | args.name = name; | 234 | args.name = name->name; |
223 | args.namelen = namelen; | 235 | args.namelen = name->len; |
224 | args.value = value; | 236 | args.value = value; |
225 | args.valuelen = valuelen; | 237 | args.valuelen = valuelen; |
226 | args.flags = flags; | 238 | args.flags = flags; |
@@ -236,7 +248,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, | |||
236 | * Determine space new attribute will use, and if it would be | 248 | * Determine space new attribute will use, and if it would be |
237 | * "local" or "remote" (note: local != inline). | 249 | * "local" or "remote" (note: local != inline). |
238 | */ | 250 | */ |
239 | size = xfs_attr_leaf_newentsize(namelen, valuelen, | 251 | size = xfs_attr_leaf_newentsize(name->len, valuelen, |
240 | mp->m_sb.sb_blocksize, &local); | 252 | mp->m_sb.sb_blocksize, &local); |
241 | 253 | ||
242 | nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); | 254 | nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); |
@@ -429,26 +441,27 @@ xfs_attr_set( | |||
429 | int valuelen, | 441 | int valuelen, |
430 | int flags) | 442 | int flags) |
431 | { | 443 | { |
432 | int namelen; | 444 | int error; |
433 | 445 | struct xfs_name xname; | |
434 | namelen = strlen(name); | ||
435 | if (namelen >= MAXNAMELEN) | ||
436 | return EFAULT; /* match IRIX behaviour */ | ||
437 | 446 | ||
438 | XFS_STATS_INC(xs_attr_set); | 447 | XFS_STATS_INC(xs_attr_set); |
439 | 448 | ||
440 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 449 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
441 | return (EIO); | 450 | return (EIO); |
442 | 451 | ||
443 | return xfs_attr_set_int(dp, name, namelen, value, valuelen, flags); | 452 | error = xfs_attr_name_to_xname(&xname, name); |
453 | if (error) | ||
454 | return error; | ||
455 | |||
456 | return xfs_attr_set_int(dp, &xname, value, valuelen, flags); | ||
444 | } | 457 | } |
445 | 458 | ||
446 | /* | 459 | /* |
447 | * Generic handler routine to remove a name from an attribute list. | 460 | * Generic handler routine to remove a name from an attribute list. |
448 | * Transitions attribute list from Btree to shortform as necessary. | 461 | * Transitions attribute list from Btree to shortform as necessary. |
449 | */ | 462 | */ |
450 | int | 463 | STATIC int |
451 | xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) | 464 | xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) |
452 | { | 465 | { |
453 | xfs_da_args_t args; | 466 | xfs_da_args_t args; |
454 | xfs_fsblock_t firstblock; | 467 | xfs_fsblock_t firstblock; |
@@ -460,8 +473,8 @@ xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) | |||
460 | * Fill in the arg structure for this request. | 473 | * Fill in the arg structure for this request. |
461 | */ | 474 | */ |
462 | memset((char *)&args, 0, sizeof(args)); | 475 | memset((char *)&args, 0, sizeof(args)); |
463 | args.name = name; | 476 | args.name = name->name; |
464 | args.namelen = namelen; | 477 | args.namelen = name->len; |
465 | args.flags = flags; | 478 | args.flags = flags; |
466 | args.hashval = xfs_da_hashname(args.name, args.namelen); | 479 | args.hashval = xfs_da_hashname(args.name, args.namelen); |
467 | args.dp = dp; | 480 | args.dp = dp; |
@@ -575,17 +588,18 @@ xfs_attr_remove( | |||
575 | const char *name, | 588 | const char *name, |
576 | int flags) | 589 | int flags) |
577 | { | 590 | { |
578 | int namelen; | 591 | int error; |
579 | 592 | struct xfs_name xname; | |
580 | namelen = strlen(name); | ||
581 | if (namelen >= MAXNAMELEN) | ||
582 | return EFAULT; /* match IRIX behaviour */ | ||
583 | 593 | ||
584 | XFS_STATS_INC(xs_attr_remove); | 594 | XFS_STATS_INC(xs_attr_remove); |
585 | 595 | ||
586 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 596 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
587 | return (EIO); | 597 | return (EIO); |
588 | 598 | ||
599 | error = xfs_attr_name_to_xname(&xname, name); | ||
600 | if (error) | ||
601 | return error; | ||
602 | |||
589 | xfs_ilock(dp, XFS_ILOCK_SHARED); | 603 | xfs_ilock(dp, XFS_ILOCK_SHARED); |
590 | if (XFS_IFORK_Q(dp) == 0 || | 604 | if (XFS_IFORK_Q(dp) == 0 || |
591 | (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && | 605 | (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && |
@@ -595,10 +609,10 @@ xfs_attr_remove( | |||
595 | } | 609 | } |
596 | xfs_iunlock(dp, XFS_ILOCK_SHARED); | 610 | xfs_iunlock(dp, XFS_ILOCK_SHARED); |
597 | 611 | ||
598 | return xfs_attr_remove_int(dp, name, namelen, flags); | 612 | return xfs_attr_remove_int(dp, &xname, flags); |
599 | } | 613 | } |
600 | 614 | ||
601 | int /* error */ | 615 | STATIC int |
602 | xfs_attr_list_int(xfs_attr_list_context_t *context) | 616 | xfs_attr_list_int(xfs_attr_list_context_t *context) |
603 | { | 617 | { |
604 | int error; | 618 | int error; |
@@ -2522,8 +2536,7 @@ attr_generic_get( | |||
2522 | { | 2536 | { |
2523 | int error, asize = size; | 2537 | int error, asize = size; |
2524 | 2538 | ||
2525 | error = xfs_attr_get(xfs_vtoi(vp), name, data, | 2539 | error = xfs_attr_get(xfs_vtoi(vp), name, data, &asize, xflags); |
2526 | &asize, xflags, NULL); | ||
2527 | if (!error) | 2540 | if (!error) |
2528 | return asize; | 2541 | return asize; |
2529 | return -error; | 2542 | return -error; |
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index 786eba3121c4..6cfc9384fe35 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h | |||
@@ -158,14 +158,10 @@ struct xfs_da_args; | |||
158 | /* | 158 | /* |
159 | * Overall external interface routines. | 159 | * Overall external interface routines. |
160 | */ | 160 | */ |
161 | int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int); | ||
162 | int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int); | ||
163 | int xfs_attr_list_int(struct xfs_attr_list_context *); | ||
164 | int xfs_attr_inactive(struct xfs_inode *dp); | 161 | int xfs_attr_inactive(struct xfs_inode *dp); |
165 | 162 | ||
166 | int xfs_attr_shortform_getvalue(struct xfs_da_args *); | 163 | int xfs_attr_shortform_getvalue(struct xfs_da_args *); |
167 | int xfs_attr_fetch(struct xfs_inode *, const char *, int, | 164 | int xfs_attr_fetch(struct xfs_inode *, struct xfs_name *, char *, int *, int); |
168 | char *, int *, int, struct cred *); | ||
169 | int xfs_attr_rmtval_get(struct xfs_da_args *args); | 165 | int xfs_attr_rmtval_get(struct xfs_da_args *args); |
170 | 166 | ||
171 | #endif /* __XFS_ATTR_H__ */ | 167 | #endif /* __XFS_ATTR_H__ */ |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index eb198c01c35d..53c259f5a5af 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -4074,7 +4074,6 @@ xfs_bmap_add_attrfork( | |||
4074 | error2: | 4074 | error2: |
4075 | xfs_bmap_cancel(&flist); | 4075 | xfs_bmap_cancel(&flist); |
4076 | error1: | 4076 | error1: |
4077 | ASSERT(ismrlocked(&ip->i_lock,MR_UPDATE)); | ||
4078 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 4077 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
4079 | error0: | 4078 | error0: |
4080 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); | 4079 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 3f53fad356a3..5f3647cb9885 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -162,7 +162,7 @@ xfs_swap_extents( | |||
162 | ips[1] = ip; | 162 | ips[1] = ip; |
163 | } | 163 | } |
164 | 164 | ||
165 | xfs_lock_inodes(ips, 2, 0, lock_flags); | 165 | xfs_lock_inodes(ips, 2, lock_flags); |
166 | locked = 1; | 166 | locked = 1; |
167 | 167 | ||
168 | /* Verify that both files have the same format */ | 168 | /* Verify that both files have the same format */ |
@@ -265,7 +265,7 @@ xfs_swap_extents( | |||
265 | locked = 0; | 265 | locked = 0; |
266 | goto error0; | 266 | goto error0; |
267 | } | 267 | } |
268 | xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL); | 268 | xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); |
269 | 269 | ||
270 | /* | 270 | /* |
271 | * Count the number of extended attribute blocks | 271 | * Count the number of extended attribute blocks |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index d3a0f538d6a6..381ebda4f7bc 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -462,7 +462,7 @@ xfs_fs_counts( | |||
462 | xfs_mount_t *mp, | 462 | xfs_mount_t *mp, |
463 | xfs_fsop_counts_t *cnt) | 463 | xfs_fsop_counts_t *cnt) |
464 | { | 464 | { |
465 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); | 465 | xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); |
466 | spin_lock(&mp->m_sb_lock); | 466 | spin_lock(&mp->m_sb_lock); |
467 | cnt->freedata = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); | 467 | cnt->freedata = mp->m_sb.sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp); |
468 | cnt->freertx = mp->m_sb.sb_frextents; | 468 | cnt->freertx = mp->m_sb.sb_frextents; |
@@ -524,7 +524,7 @@ xfs_reserve_blocks( | |||
524 | */ | 524 | */ |
525 | retry: | 525 | retry: |
526 | spin_lock(&mp->m_sb_lock); | 526 | spin_lock(&mp->m_sb_lock); |
527 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_SB_LOCKED); | 527 | xfs_icsb_sync_counters_locked(mp, 0); |
528 | 528 | ||
529 | /* | 529 | /* |
530 | * If our previous reservation was larger than the current value, | 530 | * If our previous reservation was larger than the current value, |
@@ -552,11 +552,8 @@ retry: | |||
552 | mp->m_resblks += free; | 552 | mp->m_resblks += free; |
553 | mp->m_resblks_avail += free; | 553 | mp->m_resblks_avail += free; |
554 | fdblks_delta = -free; | 554 | fdblks_delta = -free; |
555 | mp->m_sb.sb_fdblocks = XFS_ALLOC_SET_ASIDE(mp); | ||
556 | } else { | 555 | } else { |
557 | fdblks_delta = -delta; | 556 | fdblks_delta = -delta; |
558 | mp->m_sb.sb_fdblocks = | ||
559 | lcounter + XFS_ALLOC_SET_ASIDE(mp); | ||
560 | mp->m_resblks = request; | 557 | mp->m_resblks = request; |
561 | mp->m_resblks_avail += delta; | 558 | mp->m_resblks_avail += delta; |
562 | } | 559 | } |
@@ -587,7 +584,6 @@ out: | |||
587 | if (error == ENOSPC) | 584 | if (error == ENOSPC) |
588 | goto retry; | 585 | goto retry; |
589 | } | 586 | } |
590 | |||
591 | return 0; | 587 | return 0; |
592 | } | 588 | } |
593 | 589 | ||
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index a64dfbd565a5..aad8c5da38af 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -147,6 +147,7 @@ xfs_ialloc_ag_alloc( | |||
147 | int version; /* inode version number to use */ | 147 | int version; /* inode version number to use */ |
148 | int isaligned = 0; /* inode allocation at stripe unit */ | 148 | int isaligned = 0; /* inode allocation at stripe unit */ |
149 | /* boundary */ | 149 | /* boundary */ |
150 | unsigned int gen; | ||
150 | 151 | ||
151 | args.tp = tp; | 152 | args.tp = tp; |
152 | args.mp = tp->t_mountp; | 153 | args.mp = tp->t_mountp; |
@@ -290,6 +291,14 @@ xfs_ialloc_ag_alloc( | |||
290 | else | 291 | else |
291 | version = XFS_DINODE_VERSION_1; | 292 | version = XFS_DINODE_VERSION_1; |
292 | 293 | ||
294 | /* | ||
295 | * Seed the new inode cluster with a random generation number. This | ||
296 | * prevents short-term reuse of generation numbers if a chunk is | ||
297 | * freed and then immediately reallocated. We use random numbers | ||
298 | * rather than a linear progression to prevent the next generation | ||
299 | * number from being easily guessable. | ||
300 | */ | ||
301 | gen = random32(); | ||
293 | for (j = 0; j < nbufs; j++) { | 302 | for (j = 0; j < nbufs; j++) { |
294 | /* | 303 | /* |
295 | * Get the block. | 304 | * Get the block. |
@@ -309,6 +318,7 @@ xfs_ialloc_ag_alloc( | |||
309 | free = XFS_MAKE_IPTR(args.mp, fbuf, i); | 318 | free = XFS_MAKE_IPTR(args.mp, fbuf, i); |
310 | free->di_core.di_magic = cpu_to_be16(XFS_DINODE_MAGIC); | 319 | free->di_core.di_magic = cpu_to_be16(XFS_DINODE_MAGIC); |
311 | free->di_core.di_version = version; | 320 | free->di_core.di_version = version; |
321 | free->di_core.di_gen = cpu_to_be32(gen); | ||
312 | free->di_next_unlinked = cpu_to_be32(NULLAGINO); | 322 | free->di_next_unlinked = cpu_to_be32(NULLAGINO); |
313 | xfs_ialloc_log_di(tp, fbuf, i, | 323 | xfs_ialloc_log_di(tp, fbuf, i, |
314 | XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED); | 324 | XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED); |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e657c5128460..b07604b94d9f 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -593,8 +593,9 @@ xfs_iunlock_map_shared( | |||
593 | * XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL | 593 | * XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
594 | */ | 594 | */ |
595 | void | 595 | void |
596 | xfs_ilock(xfs_inode_t *ip, | 596 | xfs_ilock( |
597 | uint lock_flags) | 597 | xfs_inode_t *ip, |
598 | uint lock_flags) | ||
598 | { | 599 | { |
599 | /* | 600 | /* |
600 | * You can't set both SHARED and EXCL for the same lock, | 601 | * You can't set both SHARED and EXCL for the same lock, |
@@ -607,16 +608,16 @@ xfs_ilock(xfs_inode_t *ip, | |||
607 | (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); | 608 | (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); |
608 | ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0); | 609 | ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0); |
609 | 610 | ||
610 | if (lock_flags & XFS_IOLOCK_EXCL) { | 611 | if (lock_flags & XFS_IOLOCK_EXCL) |
611 | mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags)); | 612 | mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags)); |
612 | } else if (lock_flags & XFS_IOLOCK_SHARED) { | 613 | else if (lock_flags & XFS_IOLOCK_SHARED) |
613 | mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags)); | 614 | mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags)); |
614 | } | 615 | |
615 | if (lock_flags & XFS_ILOCK_EXCL) { | 616 | if (lock_flags & XFS_ILOCK_EXCL) |
616 | mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); | 617 | mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); |
617 | } else if (lock_flags & XFS_ILOCK_SHARED) { | 618 | else if (lock_flags & XFS_ILOCK_SHARED) |
618 | mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); | 619 | mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); |
619 | } | 620 | |
620 | xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address); | 621 | xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address); |
621 | } | 622 | } |
622 | 623 | ||
@@ -631,15 +632,12 @@ xfs_ilock(xfs_inode_t *ip, | |||
631 | * lock_flags -- this parameter indicates the inode's locks to be | 632 | * lock_flags -- this parameter indicates the inode's locks to be |
632 | * to be locked. See the comment for xfs_ilock() for a list | 633 | * to be locked. See the comment for xfs_ilock() for a list |
633 | * of valid values. | 634 | * of valid values. |
634 | * | ||
635 | */ | 635 | */ |
636 | int | 636 | int |
637 | xfs_ilock_nowait(xfs_inode_t *ip, | 637 | xfs_ilock_nowait( |
638 | uint lock_flags) | 638 | xfs_inode_t *ip, |
639 | uint lock_flags) | ||
639 | { | 640 | { |
640 | int iolocked; | ||
641 | int ilocked; | ||
642 | |||
643 | /* | 641 | /* |
644 | * You can't set both SHARED and EXCL for the same lock, | 642 | * You can't set both SHARED and EXCL for the same lock, |
645 | * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, | 643 | * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, |
@@ -651,37 +649,30 @@ xfs_ilock_nowait(xfs_inode_t *ip, | |||
651 | (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); | 649 | (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); |
652 | ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0); | 650 | ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0); |
653 | 651 | ||
654 | iolocked = 0; | ||
655 | if (lock_flags & XFS_IOLOCK_EXCL) { | 652 | if (lock_flags & XFS_IOLOCK_EXCL) { |
656 | iolocked = mrtryupdate(&ip->i_iolock); | 653 | if (!mrtryupdate(&ip->i_iolock)) |
657 | if (!iolocked) { | 654 | goto out; |
658 | return 0; | ||
659 | } | ||
660 | } else if (lock_flags & XFS_IOLOCK_SHARED) { | 655 | } else if (lock_flags & XFS_IOLOCK_SHARED) { |
661 | iolocked = mrtryaccess(&ip->i_iolock); | 656 | if (!mrtryaccess(&ip->i_iolock)) |
662 | if (!iolocked) { | 657 | goto out; |
663 | return 0; | ||
664 | } | ||
665 | } | 658 | } |
666 | if (lock_flags & XFS_ILOCK_EXCL) { | 659 | if (lock_flags & XFS_ILOCK_EXCL) { |
667 | ilocked = mrtryupdate(&ip->i_lock); | 660 | if (!mrtryupdate(&ip->i_lock)) |
668 | if (!ilocked) { | 661 | goto out_undo_iolock; |
669 | if (iolocked) { | ||
670 | mrunlock(&ip->i_iolock); | ||
671 | } | ||
672 | return 0; | ||
673 | } | ||
674 | } else if (lock_flags & XFS_ILOCK_SHARED) { | 662 | } else if (lock_flags & XFS_ILOCK_SHARED) { |
675 | ilocked = mrtryaccess(&ip->i_lock); | 663 | if (!mrtryaccess(&ip->i_lock)) |
676 | if (!ilocked) { | 664 | goto out_undo_iolock; |
677 | if (iolocked) { | ||
678 | mrunlock(&ip->i_iolock); | ||
679 | } | ||
680 | return 0; | ||
681 | } | ||
682 | } | 665 | } |
683 | xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address); | 666 | xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address); |
684 | return 1; | 667 | return 1; |
668 | |||
669 | out_undo_iolock: | ||
670 | if (lock_flags & XFS_IOLOCK_EXCL) | ||
671 | mrunlock_excl(&ip->i_iolock); | ||
672 | else if (lock_flags & XFS_IOLOCK_SHARED) | ||
673 | mrunlock_shared(&ip->i_iolock); | ||
674 | out: | ||
675 | return 0; | ||
685 | } | 676 | } |
686 | 677 | ||
687 | /* | 678 | /* |
@@ -697,8 +688,9 @@ xfs_ilock_nowait(xfs_inode_t *ip, | |||
697 | * | 688 | * |
698 | */ | 689 | */ |
699 | void | 690 | void |
700 | xfs_iunlock(xfs_inode_t *ip, | 691 | xfs_iunlock( |
701 | uint lock_flags) | 692 | xfs_inode_t *ip, |
693 | uint lock_flags) | ||
702 | { | 694 | { |
703 | /* | 695 | /* |
704 | * You can't set both SHARED and EXCL for the same lock, | 696 | * You can't set both SHARED and EXCL for the same lock, |
@@ -713,31 +705,25 @@ xfs_iunlock(xfs_inode_t *ip, | |||
713 | XFS_LOCK_DEP_MASK)) == 0); | 705 | XFS_LOCK_DEP_MASK)) == 0); |
714 | ASSERT(lock_flags != 0); | 706 | ASSERT(lock_flags != 0); |
715 | 707 | ||
716 | if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) { | 708 | if (lock_flags & XFS_IOLOCK_EXCL) |
717 | ASSERT(!(lock_flags & XFS_IOLOCK_SHARED) || | 709 | mrunlock_excl(&ip->i_iolock); |
718 | (ismrlocked(&ip->i_iolock, MR_ACCESS))); | 710 | else if (lock_flags & XFS_IOLOCK_SHARED) |
719 | ASSERT(!(lock_flags & XFS_IOLOCK_EXCL) || | 711 | mrunlock_shared(&ip->i_iolock); |
720 | (ismrlocked(&ip->i_iolock, MR_UPDATE))); | ||
721 | mrunlock(&ip->i_iolock); | ||
722 | } | ||
723 | 712 | ||
724 | if (lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) { | 713 | if (lock_flags & XFS_ILOCK_EXCL) |
725 | ASSERT(!(lock_flags & XFS_ILOCK_SHARED) || | 714 | mrunlock_excl(&ip->i_lock); |
726 | (ismrlocked(&ip->i_lock, MR_ACCESS))); | 715 | else if (lock_flags & XFS_ILOCK_SHARED) |
727 | ASSERT(!(lock_flags & XFS_ILOCK_EXCL) || | 716 | mrunlock_shared(&ip->i_lock); |
728 | (ismrlocked(&ip->i_lock, MR_UPDATE))); | ||
729 | mrunlock(&ip->i_lock); | ||
730 | 717 | ||
718 | if ((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) && | ||
719 | !(lock_flags & XFS_IUNLOCK_NONOTIFY) && ip->i_itemp) { | ||
731 | /* | 720 | /* |
732 | * Let the AIL know that this item has been unlocked in case | 721 | * Let the AIL know that this item has been unlocked in case |
733 | * it is in the AIL and anyone is waiting on it. Don't do | 722 | * it is in the AIL and anyone is waiting on it. Don't do |
734 | * this if the caller has asked us not to. | 723 | * this if the caller has asked us not to. |
735 | */ | 724 | */ |
736 | if (!(lock_flags & XFS_IUNLOCK_NONOTIFY) && | 725 | xfs_trans_unlocked_item(ip->i_mount, |
737 | ip->i_itemp != NULL) { | 726 | (xfs_log_item_t*)(ip->i_itemp)); |
738 | xfs_trans_unlocked_item(ip->i_mount, | ||
739 | (xfs_log_item_t*)(ip->i_itemp)); | ||
740 | } | ||
741 | } | 727 | } |
742 | xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address); | 728 | xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address); |
743 | } | 729 | } |
@@ -747,21 +733,47 @@ xfs_iunlock(xfs_inode_t *ip, | |||
747 | * if it is being demoted. | 733 | * if it is being demoted. |
748 | */ | 734 | */ |
749 | void | 735 | void |
750 | xfs_ilock_demote(xfs_inode_t *ip, | 736 | xfs_ilock_demote( |
751 | uint lock_flags) | 737 | xfs_inode_t *ip, |
738 | uint lock_flags) | ||
752 | { | 739 | { |
753 | ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)); | 740 | ASSERT(lock_flags & (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)); |
754 | ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0); | 741 | ASSERT((lock_flags & ~(XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)) == 0); |
755 | 742 | ||
756 | if (lock_flags & XFS_ILOCK_EXCL) { | 743 | if (lock_flags & XFS_ILOCK_EXCL) |
757 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | ||
758 | mrdemote(&ip->i_lock); | 744 | mrdemote(&ip->i_lock); |
759 | } | 745 | if (lock_flags & XFS_IOLOCK_EXCL) |
760 | if (lock_flags & XFS_IOLOCK_EXCL) { | ||
761 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); | ||
762 | mrdemote(&ip->i_iolock); | 746 | mrdemote(&ip->i_iolock); |
747 | } | ||
748 | |||
749 | #ifdef DEBUG | ||
750 | /* | ||
751 | * Debug-only routine, without additional rw_semaphore APIs, we can | ||
752 | * now only answer requests regarding whether we hold the lock for write | ||
753 | * (reader state is outside our visibility, we only track writer state). | ||
754 | * | ||
755 | * Note: this means !xfs_isilocked would give false positives, so don't do that. | ||
756 | */ | ||
757 | int | ||
758 | xfs_isilocked( | ||
759 | xfs_inode_t *ip, | ||
760 | uint lock_flags) | ||
761 | { | ||
762 | if ((lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) == | ||
763 | XFS_ILOCK_EXCL) { | ||
764 | if (!ip->i_lock.mr_writer) | ||
765 | return 0; | ||
763 | } | 766 | } |
767 | |||
768 | if ((lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) == | ||
769 | XFS_IOLOCK_EXCL) { | ||
770 | if (!ip->i_iolock.mr_writer) | ||
771 | return 0; | ||
772 | } | ||
773 | |||
774 | return 1; | ||
764 | } | 775 | } |
776 | #endif | ||
765 | 777 | ||
766 | /* | 778 | /* |
767 | * The following three routines simply manage the i_flock | 779 | * The following three routines simply manage the i_flock |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ca12acb90394..cf0bb9c1d621 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1291,7 +1291,7 @@ xfs_file_last_byte( | |||
1291 | xfs_fileoff_t size_last_block; | 1291 | xfs_fileoff_t size_last_block; |
1292 | int error; | 1292 | int error; |
1293 | 1293 | ||
1294 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE | MR_ACCESS)); | 1294 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)); |
1295 | 1295 | ||
1296 | mp = ip->i_mount; | 1296 | mp = ip->i_mount; |
1297 | /* | 1297 | /* |
@@ -1402,7 +1402,7 @@ xfs_itruncate_start( | |||
1402 | bhv_vnode_t *vp; | 1402 | bhv_vnode_t *vp; |
1403 | int error = 0; | 1403 | int error = 0; |
1404 | 1404 | ||
1405 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); | 1405 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
1406 | ASSERT((new_size == 0) || (new_size <= ip->i_size)); | 1406 | ASSERT((new_size == 0) || (new_size <= ip->i_size)); |
1407 | ASSERT((flags == XFS_ITRUNC_DEFINITE) || | 1407 | ASSERT((flags == XFS_ITRUNC_DEFINITE) || |
1408 | (flags == XFS_ITRUNC_MAYBE)); | 1408 | (flags == XFS_ITRUNC_MAYBE)); |
@@ -1528,8 +1528,7 @@ xfs_itruncate_finish( | |||
1528 | xfs_bmap_free_t free_list; | 1528 | xfs_bmap_free_t free_list; |
1529 | int error; | 1529 | int error; |
1530 | 1530 | ||
1531 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); | 1531 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
1532 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); | ||
1533 | ASSERT((new_size == 0) || (new_size <= ip->i_size)); | 1532 | ASSERT((new_size == 0) || (new_size <= ip->i_size)); |
1534 | ASSERT(*tp != NULL); | 1533 | ASSERT(*tp != NULL); |
1535 | ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); | 1534 | ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); |
@@ -1780,8 +1779,7 @@ xfs_igrow_start( | |||
1780 | xfs_fsize_t new_size, | 1779 | xfs_fsize_t new_size, |
1781 | cred_t *credp) | 1780 | cred_t *credp) |
1782 | { | 1781 | { |
1783 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); | 1782 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
1784 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); | ||
1785 | ASSERT(new_size > ip->i_size); | 1783 | ASSERT(new_size > ip->i_size); |
1786 | 1784 | ||
1787 | /* | 1785 | /* |
@@ -1809,8 +1807,7 @@ xfs_igrow_finish( | |||
1809 | xfs_fsize_t new_size, | 1807 | xfs_fsize_t new_size, |
1810 | int change_flag) | 1808 | int change_flag) |
1811 | { | 1809 | { |
1812 | ASSERT(ismrlocked(&(ip->i_lock), MR_UPDATE) != 0); | 1810 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); |
1813 | ASSERT(ismrlocked(&(ip->i_iolock), MR_UPDATE) != 0); | ||
1814 | ASSERT(ip->i_transp == tp); | 1811 | ASSERT(ip->i_transp == tp); |
1815 | ASSERT(new_size > ip->i_size); | 1812 | ASSERT(new_size > ip->i_size); |
1816 | 1813 | ||
@@ -2287,7 +2284,7 @@ xfs_ifree( | |||
2287 | xfs_dinode_t *dip; | 2284 | xfs_dinode_t *dip; |
2288 | xfs_buf_t *ibp; | 2285 | xfs_buf_t *ibp; |
2289 | 2286 | ||
2290 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 2287 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2291 | ASSERT(ip->i_transp == tp); | 2288 | ASSERT(ip->i_transp == tp); |
2292 | ASSERT(ip->i_d.di_nlink == 0); | 2289 | ASSERT(ip->i_d.di_nlink == 0); |
2293 | ASSERT(ip->i_d.di_nextents == 0); | 2290 | ASSERT(ip->i_d.di_nextents == 0); |
@@ -2746,7 +2743,7 @@ void | |||
2746 | xfs_ipin( | 2743 | xfs_ipin( |
2747 | xfs_inode_t *ip) | 2744 | xfs_inode_t *ip) |
2748 | { | 2745 | { |
2749 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 2746 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2750 | 2747 | ||
2751 | atomic_inc(&ip->i_pincount); | 2748 | atomic_inc(&ip->i_pincount); |
2752 | } | 2749 | } |
@@ -2779,7 +2776,7 @@ __xfs_iunpin_wait( | |||
2779 | { | 2776 | { |
2780 | xfs_inode_log_item_t *iip = ip->i_itemp; | 2777 | xfs_inode_log_item_t *iip = ip->i_itemp; |
2781 | 2778 | ||
2782 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE | MR_ACCESS)); | 2779 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
2783 | if (atomic_read(&ip->i_pincount) == 0) | 2780 | if (atomic_read(&ip->i_pincount) == 0) |
2784 | return; | 2781 | return; |
2785 | 2782 | ||
@@ -2829,7 +2826,7 @@ xfs_iextents_copy( | |||
2829 | xfs_fsblock_t start_block; | 2826 | xfs_fsblock_t start_block; |
2830 | 2827 | ||
2831 | ifp = XFS_IFORK_PTR(ip, whichfork); | 2828 | ifp = XFS_IFORK_PTR(ip, whichfork); |
2832 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); | 2829 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
2833 | ASSERT(ifp->if_bytes > 0); | 2830 | ASSERT(ifp->if_bytes > 0); |
2834 | 2831 | ||
2835 | nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 2832 | nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
@@ -3132,7 +3129,7 @@ xfs_iflush( | |||
3132 | 3129 | ||
3133 | XFS_STATS_INC(xs_iflush_count); | 3130 | XFS_STATS_INC(xs_iflush_count); |
3134 | 3131 | ||
3135 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); | 3132 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
3136 | ASSERT(issemalocked(&(ip->i_flock))); | 3133 | ASSERT(issemalocked(&(ip->i_flock))); |
3137 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 3134 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
3138 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 3135 | ip->i_d.di_nextents > ip->i_df.if_ext_max); |
@@ -3297,7 +3294,7 @@ xfs_iflush_int( | |||
3297 | int first; | 3294 | int first; |
3298 | #endif | 3295 | #endif |
3299 | 3296 | ||
3300 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); | 3297 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
3301 | ASSERT(issemalocked(&(ip->i_flock))); | 3298 | ASSERT(issemalocked(&(ip->i_flock))); |
3302 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 3299 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
3303 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 3300 | ip->i_d.di_nextents > ip->i_df.if_ext_max); |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 93c37697a72c..0a999fee4f03 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -386,20 +386,9 @@ xfs_iflags_test_and_clear(xfs_inode_t *ip, unsigned short flags) | |||
386 | #define XFS_ILOCK_EXCL (1<<2) | 386 | #define XFS_ILOCK_EXCL (1<<2) |
387 | #define XFS_ILOCK_SHARED (1<<3) | 387 | #define XFS_ILOCK_SHARED (1<<3) |
388 | #define XFS_IUNLOCK_NONOTIFY (1<<4) | 388 | #define XFS_IUNLOCK_NONOTIFY (1<<4) |
389 | /* #define XFS_IOLOCK_NESTED (1<<5) */ | ||
390 | #define XFS_EXTENT_TOKEN_RD (1<<6) | ||
391 | #define XFS_SIZE_TOKEN_RD (1<<7) | ||
392 | #define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD) | ||
393 | #define XFS_WILLLEND (1<<8) /* Always acquire tokens for lending */ | ||
394 | #define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND) | ||
395 | #define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND) | ||
396 | #define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND) | ||
397 | /* TODO:XFS_SIZE_TOKEN_WANT (1<<9) */ | ||
398 | 389 | ||
399 | #define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ | 390 | #define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \ |
400 | | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED \ | 391 | | XFS_ILOCK_EXCL | XFS_ILOCK_SHARED) |
401 | | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD \ | ||
402 | | XFS_WILLLEND) | ||
403 | 392 | ||
404 | /* | 393 | /* |
405 | * Flags for lockdep annotations. | 394 | * Flags for lockdep annotations. |
@@ -483,6 +472,7 @@ void xfs_ilock(xfs_inode_t *, uint); | |||
483 | int xfs_ilock_nowait(xfs_inode_t *, uint); | 472 | int xfs_ilock_nowait(xfs_inode_t *, uint); |
484 | void xfs_iunlock(xfs_inode_t *, uint); | 473 | void xfs_iunlock(xfs_inode_t *, uint); |
485 | void xfs_ilock_demote(xfs_inode_t *, uint); | 474 | void xfs_ilock_demote(xfs_inode_t *, uint); |
475 | int xfs_isilocked(xfs_inode_t *, uint); | ||
486 | void xfs_iflock(xfs_inode_t *); | 476 | void xfs_iflock(xfs_inode_t *); |
487 | int xfs_iflock_nowait(xfs_inode_t *); | 477 | int xfs_iflock_nowait(xfs_inode_t *); |
488 | uint xfs_ilock_map_shared(xfs_inode_t *); | 478 | uint xfs_ilock_map_shared(xfs_inode_t *); |
@@ -534,7 +524,7 @@ int xfs_iflush(xfs_inode_t *, uint); | |||
534 | void xfs_iflush_all(struct xfs_mount *); | 524 | void xfs_iflush_all(struct xfs_mount *); |
535 | void xfs_ichgtime(xfs_inode_t *, int); | 525 | void xfs_ichgtime(xfs_inode_t *, int); |
536 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); | 526 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); |
537 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); | 527 | void xfs_lock_inodes(xfs_inode_t **, int, uint); |
538 | 528 | ||
539 | void xfs_synchronize_atime(xfs_inode_t *); | 529 | void xfs_synchronize_atime(xfs_inode_t *); |
540 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); | 530 | void xfs_mark_inode_dirty_sync(xfs_inode_t *); |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 93b5db453ea2..167b33f15772 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -547,7 +547,7 @@ STATIC void | |||
547 | xfs_inode_item_pin( | 547 | xfs_inode_item_pin( |
548 | xfs_inode_log_item_t *iip) | 548 | xfs_inode_log_item_t *iip) |
549 | { | 549 | { |
550 | ASSERT(ismrlocked(&(iip->ili_inode->i_lock), MR_UPDATE)); | 550 | ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL)); |
551 | xfs_ipin(iip->ili_inode); | 551 | xfs_ipin(iip->ili_inode); |
552 | } | 552 | } |
553 | 553 | ||
@@ -664,13 +664,13 @@ xfs_inode_item_unlock( | |||
664 | 664 | ||
665 | ASSERT(iip != NULL); | 665 | ASSERT(iip != NULL); |
666 | ASSERT(iip->ili_inode->i_itemp != NULL); | 666 | ASSERT(iip->ili_inode->i_itemp != NULL); |
667 | ASSERT(ismrlocked(&(iip->ili_inode->i_lock), MR_UPDATE)); | 667 | ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL)); |
668 | ASSERT((!(iip->ili_inode->i_itemp->ili_flags & | 668 | ASSERT((!(iip->ili_inode->i_itemp->ili_flags & |
669 | XFS_ILI_IOLOCKED_EXCL)) || | 669 | XFS_ILI_IOLOCKED_EXCL)) || |
670 | ismrlocked(&(iip->ili_inode->i_iolock), MR_UPDATE)); | 670 | xfs_isilocked(iip->ili_inode, XFS_IOLOCK_EXCL)); |
671 | ASSERT((!(iip->ili_inode->i_itemp->ili_flags & | 671 | ASSERT((!(iip->ili_inode->i_itemp->ili_flags & |
672 | XFS_ILI_IOLOCKED_SHARED)) || | 672 | XFS_ILI_IOLOCKED_SHARED)) || |
673 | ismrlocked(&(iip->ili_inode->i_iolock), MR_ACCESS)); | 673 | xfs_isilocked(iip->ili_inode, XFS_IOLOCK_SHARED)); |
674 | /* | 674 | /* |
675 | * Clear the transaction pointer in the inode. | 675 | * Clear the transaction pointer in the inode. |
676 | */ | 676 | */ |
@@ -769,7 +769,7 @@ xfs_inode_item_pushbuf( | |||
769 | 769 | ||
770 | ip = iip->ili_inode; | 770 | ip = iip->ili_inode; |
771 | 771 | ||
772 | ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); | 772 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED)); |
773 | 773 | ||
774 | /* | 774 | /* |
775 | * The ili_pushbuf_flag keeps others from | 775 | * The ili_pushbuf_flag keeps others from |
@@ -857,7 +857,7 @@ xfs_inode_item_push( | |||
857 | 857 | ||
858 | ip = iip->ili_inode; | 858 | ip = iip->ili_inode; |
859 | 859 | ||
860 | ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); | 860 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED)); |
861 | ASSERT(issemalocked(&(ip->i_flock))); | 861 | ASSERT(issemalocked(&(ip->i_flock))); |
862 | /* | 862 | /* |
863 | * Since we were able to lock the inode's flush lock and | 863 | * Since we were able to lock the inode's flush lock and |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index fb3cf1191419..7edcde691d1a 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -196,14 +196,14 @@ xfs_iomap( | |||
196 | break; | 196 | break; |
197 | case BMAPI_WRITE: | 197 | case BMAPI_WRITE: |
198 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, ip, offset, count); | 198 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_ENTER, ip, offset, count); |
199 | lockmode = XFS_ILOCK_EXCL|XFS_EXTSIZE_WR; | 199 | lockmode = XFS_ILOCK_EXCL; |
200 | if (flags & BMAPI_IGNSTATE) | 200 | if (flags & BMAPI_IGNSTATE) |
201 | bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE; | 201 | bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE; |
202 | xfs_ilock(ip, lockmode); | 202 | xfs_ilock(ip, lockmode); |
203 | break; | 203 | break; |
204 | case BMAPI_ALLOCATE: | 204 | case BMAPI_ALLOCATE: |
205 | xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, ip, offset, count); | 205 | xfs_iomap_enter_trace(XFS_IOMAP_ALLOC_ENTER, ip, offset, count); |
206 | lockmode = XFS_ILOCK_SHARED|XFS_EXTSIZE_RD; | 206 | lockmode = XFS_ILOCK_SHARED; |
207 | bmapi_flags = XFS_BMAPI_ENTIRE; | 207 | bmapi_flags = XFS_BMAPI_ENTIRE; |
208 | 208 | ||
209 | /* Attempt non-blocking lock */ | 209 | /* Attempt non-blocking lock */ |
@@ -523,8 +523,7 @@ xfs_iomap_write_direct( | |||
523 | goto error_out; | 523 | goto error_out; |
524 | } | 524 | } |
525 | 525 | ||
526 | if (unlikely(!imap.br_startblock && | 526 | if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) { |
527 | !(XFS_IS_REALTIME_INODE(ip)))) { | ||
528 | error = xfs_cmn_err_fsblock_zero(ip, &imap); | 527 | error = xfs_cmn_err_fsblock_zero(ip, &imap); |
529 | goto error_out; | 528 | goto error_out; |
530 | } | 529 | } |
@@ -624,7 +623,7 @@ xfs_iomap_write_delay( | |||
624 | int prealloc, fsynced = 0; | 623 | int prealloc, fsynced = 0; |
625 | int error; | 624 | int error; |
626 | 625 | ||
627 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE) != 0); | 626 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
628 | 627 | ||
629 | /* | 628 | /* |
630 | * Make sure that the dquots are there. This doesn't hold | 629 | * Make sure that the dquots are there. This doesn't hold |
@@ -686,8 +685,7 @@ retry: | |||
686 | goto retry; | 685 | goto retry; |
687 | } | 686 | } |
688 | 687 | ||
689 | if (unlikely(!imap[0].br_startblock && | 688 | if (!(imap[0].br_startblock || XFS_IS_REALTIME_INODE(ip))) |
690 | !(XFS_IS_REALTIME_INODE(ip)))) | ||
691 | return xfs_cmn_err_fsblock_zero(ip, &imap[0]); | 689 | return xfs_cmn_err_fsblock_zero(ip, &imap[0]); |
692 | 690 | ||
693 | *ret_imap = imap[0]; | 691 | *ret_imap = imap[0]; |
@@ -838,9 +836,9 @@ xfs_iomap_write_allocate( | |||
838 | * See if we were able to allocate an extent that | 836 | * See if we were able to allocate an extent that |
839 | * covers at least part of the callers request | 837 | * covers at least part of the callers request |
840 | */ | 838 | */ |
841 | if (unlikely(!imap.br_startblock && | 839 | if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) |
842 | XFS_IS_REALTIME_INODE(ip))) | ||
843 | return xfs_cmn_err_fsblock_zero(ip, &imap); | 840 | return xfs_cmn_err_fsblock_zero(ip, &imap); |
841 | |||
844 | if ((offset_fsb >= imap.br_startoff) && | 842 | if ((offset_fsb >= imap.br_startoff) && |
845 | (offset_fsb < (imap.br_startoff + | 843 | (offset_fsb < (imap.br_startoff + |
846 | imap.br_blockcount))) { | 844 | imap.br_blockcount))) { |
@@ -934,8 +932,7 @@ xfs_iomap_write_unwritten( | |||
934 | if (error) | 932 | if (error) |
935 | return XFS_ERROR(error); | 933 | return XFS_ERROR(error); |
936 | 934 | ||
937 | if (unlikely(!imap.br_startblock && | 935 | if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) |
938 | !(XFS_IS_REALTIME_INODE(ip)))) | ||
939 | return xfs_cmn_err_fsblock_zero(ip, &imap); | 936 | return xfs_cmn_err_fsblock_zero(ip, &imap); |
940 | 937 | ||
941 | if ((numblks_fsb = imap.br_blockcount) == 0) { | 938 | if ((numblks_fsb = imap.br_blockcount) == 0) { |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index eb85bdedad0c..419de15aeb43 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -71,11 +71,6 @@ xfs_bulkstat_one_iget( | |||
71 | 71 | ||
72 | ASSERT(ip != NULL); | 72 | ASSERT(ip != NULL); |
73 | ASSERT(ip->i_blkno != (xfs_daddr_t)0); | 73 | ASSERT(ip->i_blkno != (xfs_daddr_t)0); |
74 | if (ip->i_d.di_mode == 0) { | ||
75 | *stat = BULKSTAT_RV_NOTHING; | ||
76 | error = XFS_ERROR(ENOENT); | ||
77 | goto out_iput; | ||
78 | } | ||
79 | 74 | ||
80 | vp = XFS_ITOV(ip); | 75 | vp = XFS_ITOV(ip); |
81 | dic = &ip->i_d; | 76 | dic = &ip->i_d; |
@@ -124,7 +119,6 @@ xfs_bulkstat_one_iget( | |||
124 | break; | 119 | break; |
125 | } | 120 | } |
126 | 121 | ||
127 | out_iput: | ||
128 | xfs_iput(ip, XFS_ILOCK_SHARED); | 122 | xfs_iput(ip, XFS_ILOCK_SHARED); |
129 | return error; | 123 | return error; |
130 | } | 124 | } |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 2fec452afbcc..da3988453b71 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -54,8 +54,9 @@ STATIC void xfs_unmountfs_wait(xfs_mount_t *); | |||
54 | #ifdef HAVE_PERCPU_SB | 54 | #ifdef HAVE_PERCPU_SB |
55 | STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); | 55 | STATIC void xfs_icsb_destroy_counters(xfs_mount_t *); |
56 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, | 56 | STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, |
57 | int, int); | 57 | int); |
58 | STATIC void xfs_icsb_sync_counters(xfs_mount_t *); | 58 | STATIC void xfs_icsb_balance_counter_locked(xfs_mount_t *, xfs_sb_field_t, |
59 | int); | ||
59 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, | 60 | STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t, |
60 | int64_t, int); | 61 | int64_t, int); |
61 | STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); | 62 | STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); |
@@ -63,8 +64,8 @@ STATIC void xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t); | |||
63 | #else | 64 | #else |
64 | 65 | ||
65 | #define xfs_icsb_destroy_counters(mp) do { } while (0) | 66 | #define xfs_icsb_destroy_counters(mp) do { } while (0) |
66 | #define xfs_icsb_balance_counter(mp, a, b, c) do { } while (0) | 67 | #define xfs_icsb_balance_counter(mp, a, b) do { } while (0) |
67 | #define xfs_icsb_sync_counters(mp) do { } while (0) | 68 | #define xfs_icsb_balance_counter_locked(mp, a, b) do { } while (0) |
68 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) | 69 | #define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0) |
69 | 70 | ||
70 | #endif | 71 | #endif |
@@ -1400,7 +1401,7 @@ xfs_log_sbcount( | |||
1400 | if (!xfs_fs_writable(mp)) | 1401 | if (!xfs_fs_writable(mp)) |
1401 | return 0; | 1402 | return 0; |
1402 | 1403 | ||
1403 | xfs_icsb_sync_counters(mp); | 1404 | xfs_icsb_sync_counters(mp, 0); |
1404 | 1405 | ||
1405 | /* | 1406 | /* |
1406 | * we don't need to do this if we are updating the superblock | 1407 | * we don't need to do this if we are updating the superblock |
@@ -2026,9 +2027,9 @@ xfs_icsb_cpu_notify( | |||
2026 | case CPU_ONLINE: | 2027 | case CPU_ONLINE: |
2027 | case CPU_ONLINE_FROZEN: | 2028 | case CPU_ONLINE_FROZEN: |
2028 | xfs_icsb_lock(mp); | 2029 | xfs_icsb_lock(mp); |
2029 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); | 2030 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); |
2030 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); | 2031 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); |
2031 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0, 0); | 2032 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); |
2032 | xfs_icsb_unlock(mp); | 2033 | xfs_icsb_unlock(mp); |
2033 | break; | 2034 | break; |
2034 | case CPU_DEAD: | 2035 | case CPU_DEAD: |
@@ -2048,12 +2049,9 @@ xfs_icsb_cpu_notify( | |||
2048 | 2049 | ||
2049 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); | 2050 | memset(cntp, 0, sizeof(xfs_icsb_cnts_t)); |
2050 | 2051 | ||
2051 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, | 2052 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_ICOUNT, 0); |
2052 | XFS_ICSB_SB_LOCKED, 0); | 2053 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_IFREE, 0); |
2053 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, | 2054 | xfs_icsb_balance_counter_locked(mp, XFS_SBS_FDBLOCKS, 0); |
2054 | XFS_ICSB_SB_LOCKED, 0); | ||
2055 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, | ||
2056 | XFS_ICSB_SB_LOCKED, 0); | ||
2057 | spin_unlock(&mp->m_sb_lock); | 2055 | spin_unlock(&mp->m_sb_lock); |
2058 | xfs_icsb_unlock(mp); | 2056 | xfs_icsb_unlock(mp); |
2059 | break; | 2057 | break; |
@@ -2105,9 +2103,9 @@ xfs_icsb_reinit_counters( | |||
2105 | * initial balance kicks us off correctly | 2103 | * initial balance kicks us off correctly |
2106 | */ | 2104 | */ |
2107 | mp->m_icsb_counters = -1; | 2105 | mp->m_icsb_counters = -1; |
2108 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0, 0); | 2106 | xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0); |
2109 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0, 0); | 2107 | xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0); |
2110 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0, 0); | 2108 | xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0); |
2111 | xfs_icsb_unlock(mp); | 2109 | xfs_icsb_unlock(mp); |
2112 | } | 2110 | } |
2113 | 2111 | ||
@@ -2223,7 +2221,7 @@ xfs_icsb_disable_counter( | |||
2223 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { | 2221 | if (!test_and_set_bit(field, &mp->m_icsb_counters)) { |
2224 | /* drain back to superblock */ | 2222 | /* drain back to superblock */ |
2225 | 2223 | ||
2226 | xfs_icsb_count(mp, &cnt, XFS_ICSB_SB_LOCKED|XFS_ICSB_LAZY_COUNT); | 2224 | xfs_icsb_count(mp, &cnt, XFS_ICSB_LAZY_COUNT); |
2227 | switch(field) { | 2225 | switch(field) { |
2228 | case XFS_SBS_ICOUNT: | 2226 | case XFS_SBS_ICOUNT: |
2229 | mp->m_sb.sb_icount = cnt.icsb_icount; | 2227 | mp->m_sb.sb_icount = cnt.icsb_icount; |
@@ -2278,38 +2276,33 @@ xfs_icsb_enable_counter( | |||
2278 | } | 2276 | } |
2279 | 2277 | ||
2280 | void | 2278 | void |
2281 | xfs_icsb_sync_counters_flags( | 2279 | xfs_icsb_sync_counters_locked( |
2282 | xfs_mount_t *mp, | 2280 | xfs_mount_t *mp, |
2283 | int flags) | 2281 | int flags) |
2284 | { | 2282 | { |
2285 | xfs_icsb_cnts_t cnt; | 2283 | xfs_icsb_cnts_t cnt; |
2286 | 2284 | ||
2287 | /* Pass 1: lock all counters */ | ||
2288 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) | ||
2289 | spin_lock(&mp->m_sb_lock); | ||
2290 | |||
2291 | xfs_icsb_count(mp, &cnt, flags); | 2285 | xfs_icsb_count(mp, &cnt, flags); |
2292 | 2286 | ||
2293 | /* Step 3: update mp->m_sb fields */ | ||
2294 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_ICOUNT)) | 2287 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_ICOUNT)) |
2295 | mp->m_sb.sb_icount = cnt.icsb_icount; | 2288 | mp->m_sb.sb_icount = cnt.icsb_icount; |
2296 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE)) | 2289 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE)) |
2297 | mp->m_sb.sb_ifree = cnt.icsb_ifree; | 2290 | mp->m_sb.sb_ifree = cnt.icsb_ifree; |
2298 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS)) | 2291 | if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS)) |
2299 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; | 2292 | mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks; |
2300 | |||
2301 | if ((flags & XFS_ICSB_SB_LOCKED) == 0) | ||
2302 | spin_unlock(&mp->m_sb_lock); | ||
2303 | } | 2293 | } |
2304 | 2294 | ||
2305 | /* | 2295 | /* |
2306 | * Accurate update of per-cpu counters to incore superblock | 2296 | * Accurate update of per-cpu counters to incore superblock |
2307 | */ | 2297 | */ |
2308 | STATIC void | 2298 | void |
2309 | xfs_icsb_sync_counters( | 2299 | xfs_icsb_sync_counters( |
2310 | xfs_mount_t *mp) | 2300 | xfs_mount_t *mp, |
2301 | int flags) | ||
2311 | { | 2302 | { |
2312 | xfs_icsb_sync_counters_flags(mp, 0); | 2303 | spin_lock(&mp->m_sb_lock); |
2304 | xfs_icsb_sync_counters_locked(mp, flags); | ||
2305 | spin_unlock(&mp->m_sb_lock); | ||
2313 | } | 2306 | } |
2314 | 2307 | ||
2315 | /* | 2308 | /* |
@@ -2332,19 +2325,15 @@ xfs_icsb_sync_counters( | |||
2332 | #define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \ | 2325 | #define XFS_ICSB_FDBLK_CNTR_REENABLE(mp) \ |
2333 | (uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp)) | 2326 | (uint64_t)(512 + XFS_ALLOC_SET_ASIDE(mp)) |
2334 | STATIC void | 2327 | STATIC void |
2335 | xfs_icsb_balance_counter( | 2328 | xfs_icsb_balance_counter_locked( |
2336 | xfs_mount_t *mp, | 2329 | xfs_mount_t *mp, |
2337 | xfs_sb_field_t field, | 2330 | xfs_sb_field_t field, |
2338 | int flags, | ||
2339 | int min_per_cpu) | 2331 | int min_per_cpu) |
2340 | { | 2332 | { |
2341 | uint64_t count, resid; | 2333 | uint64_t count, resid; |
2342 | int weight = num_online_cpus(); | 2334 | int weight = num_online_cpus(); |
2343 | uint64_t min = (uint64_t)min_per_cpu; | 2335 | uint64_t min = (uint64_t)min_per_cpu; |
2344 | 2336 | ||
2345 | if (!(flags & XFS_ICSB_SB_LOCKED)) | ||
2346 | spin_lock(&mp->m_sb_lock); | ||
2347 | |||
2348 | /* disable counter and sync counter */ | 2337 | /* disable counter and sync counter */ |
2349 | xfs_icsb_disable_counter(mp, field); | 2338 | xfs_icsb_disable_counter(mp, field); |
2350 | 2339 | ||
@@ -2354,19 +2343,19 @@ xfs_icsb_balance_counter( | |||
2354 | count = mp->m_sb.sb_icount; | 2343 | count = mp->m_sb.sb_icount; |
2355 | resid = do_div(count, weight); | 2344 | resid = do_div(count, weight); |
2356 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) | 2345 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) |
2357 | goto out; | 2346 | return; |
2358 | break; | 2347 | break; |
2359 | case XFS_SBS_IFREE: | 2348 | case XFS_SBS_IFREE: |
2360 | count = mp->m_sb.sb_ifree; | 2349 | count = mp->m_sb.sb_ifree; |
2361 | resid = do_div(count, weight); | 2350 | resid = do_div(count, weight); |
2362 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) | 2351 | if (count < max(min, XFS_ICSB_INO_CNTR_REENABLE)) |
2363 | goto out; | 2352 | return; |
2364 | break; | 2353 | break; |
2365 | case XFS_SBS_FDBLOCKS: | 2354 | case XFS_SBS_FDBLOCKS: |
2366 | count = mp->m_sb.sb_fdblocks; | 2355 | count = mp->m_sb.sb_fdblocks; |
2367 | resid = do_div(count, weight); | 2356 | resid = do_div(count, weight); |
2368 | if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp))) | 2357 | if (count < max(min, XFS_ICSB_FDBLK_CNTR_REENABLE(mp))) |
2369 | goto out; | 2358 | return; |
2370 | break; | 2359 | break; |
2371 | default: | 2360 | default: |
2372 | BUG(); | 2361 | BUG(); |
@@ -2375,9 +2364,17 @@ xfs_icsb_balance_counter( | |||
2375 | } | 2364 | } |
2376 | 2365 | ||
2377 | xfs_icsb_enable_counter(mp, field, count, resid); | 2366 | xfs_icsb_enable_counter(mp, field, count, resid); |
2378 | out: | 2367 | } |
2379 | if (!(flags & XFS_ICSB_SB_LOCKED)) | 2368 | |
2380 | spin_unlock(&mp->m_sb_lock); | 2369 | STATIC void |
2370 | xfs_icsb_balance_counter( | ||
2371 | xfs_mount_t *mp, | ||
2372 | xfs_sb_field_t fields, | ||
2373 | int min_per_cpu) | ||
2374 | { | ||
2375 | spin_lock(&mp->m_sb_lock); | ||
2376 | xfs_icsb_balance_counter_locked(mp, fields, min_per_cpu); | ||
2377 | spin_unlock(&mp->m_sb_lock); | ||
2381 | } | 2378 | } |
2382 | 2379 | ||
2383 | STATIC int | 2380 | STATIC int |
@@ -2484,7 +2481,7 @@ slow_path: | |||
2484 | * we are done. | 2481 | * we are done. |
2485 | */ | 2482 | */ |
2486 | if (ret != ENOSPC) | 2483 | if (ret != ENOSPC) |
2487 | xfs_icsb_balance_counter(mp, field, 0, 0); | 2484 | xfs_icsb_balance_counter(mp, field, 0); |
2488 | xfs_icsb_unlock(mp); | 2485 | xfs_icsb_unlock(mp); |
2489 | return ret; | 2486 | return ret; |
2490 | 2487 | ||
@@ -2508,7 +2505,7 @@ balance_counter: | |||
2508 | * will either succeed through the fast path or slow path without | 2505 | * will either succeed through the fast path or slow path without |
2509 | * another balance operation being required. | 2506 | * another balance operation being required. |
2510 | */ | 2507 | */ |
2511 | xfs_icsb_balance_counter(mp, field, 0, delta); | 2508 | xfs_icsb_balance_counter(mp, field, delta); |
2512 | xfs_icsb_unlock(mp); | 2509 | xfs_icsb_unlock(mp); |
2513 | goto again; | 2510 | goto again; |
2514 | } | 2511 | } |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 1ed575110ff0..63e0693a358a 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -206,17 +206,18 @@ typedef struct xfs_icsb_cnts { | |||
206 | 206 | ||
207 | #define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ | 207 | #define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */ |
208 | 208 | ||
209 | #define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */ | ||
210 | #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ | 209 | #define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */ |
211 | 210 | ||
212 | extern int xfs_icsb_init_counters(struct xfs_mount *); | 211 | extern int xfs_icsb_init_counters(struct xfs_mount *); |
213 | extern void xfs_icsb_reinit_counters(struct xfs_mount *); | 212 | extern void xfs_icsb_reinit_counters(struct xfs_mount *); |
214 | extern void xfs_icsb_sync_counters_flags(struct xfs_mount *, int); | 213 | extern void xfs_icsb_sync_counters(struct xfs_mount *, int); |
214 | extern void xfs_icsb_sync_counters_locked(struct xfs_mount *, int); | ||
215 | 215 | ||
216 | #else | 216 | #else |
217 | #define xfs_icsb_init_counters(mp) (0) | 217 | #define xfs_icsb_init_counters(mp) (0) |
218 | #define xfs_icsb_reinit_counters(mp) do { } while (0) | 218 | #define xfs_icsb_reinit_counters(mp) do { } while (0) |
219 | #define xfs_icsb_sync_counters_flags(mp, flags) do { } while (0) | 219 | #define xfs_icsb_sync_counters(mp, flags) do { } while (0) |
220 | #define xfs_icsb_sync_counters_locked(mp, flags) do { } while (0) | ||
220 | #endif | 221 | #endif |
221 | 222 | ||
222 | typedef struct xfs_ail { | 223 | typedef struct xfs_ail { |
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index ee371890d85d..d8063e1ad298 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -55,85 +55,32 @@ xfs_rename_unlock4( | |||
55 | 55 | ||
56 | xfs_iunlock(i_tab[0], lock_mode); | 56 | xfs_iunlock(i_tab[0], lock_mode); |
57 | for (i = 1; i < 4; i++) { | 57 | for (i = 1; i < 4; i++) { |
58 | if (i_tab[i] == NULL) { | 58 | if (i_tab[i] == NULL) |
59 | break; | 59 | break; |
60 | } | 60 | |
61 | /* | 61 | /* |
62 | * Watch out for duplicate entries in the table. | 62 | * Watch out for duplicate entries in the table. |
63 | */ | 63 | */ |
64 | if (i_tab[i] != i_tab[i-1]) { | 64 | if (i_tab[i] != i_tab[i-1]) |
65 | xfs_iunlock(i_tab[i], lock_mode); | 65 | xfs_iunlock(i_tab[i], lock_mode); |
66 | } | ||
67 | } | 66 | } |
68 | } | 67 | } |
69 | 68 | ||
70 | #ifdef DEBUG | ||
71 | int xfs_rename_skip, xfs_rename_nskip; | ||
72 | #endif | ||
73 | |||
74 | /* | 69 | /* |
75 | * The following routine will acquire the locks required for a rename | 70 | * Enter all inodes for a rename transaction into a sorted array. |
76 | * operation. The code understands the semantics of renames and will | ||
77 | * validate that name1 exists under dp1 & that name2 may or may not | ||
78 | * exist under dp2. | ||
79 | * | ||
80 | * We are renaming dp1/name1 to dp2/name2. | ||
81 | * | ||
82 | * Return ENOENT if dp1 does not exist, other lookup errors, or 0 for success. | ||
83 | */ | 71 | */ |
84 | STATIC int | 72 | STATIC void |
85 | xfs_lock_for_rename( | 73 | xfs_sort_for_rename( |
86 | xfs_inode_t *dp1, /* in: old (source) directory inode */ | 74 | xfs_inode_t *dp1, /* in: old (source) directory inode */ |
87 | xfs_inode_t *dp2, /* in: new (target) directory inode */ | 75 | xfs_inode_t *dp2, /* in: new (target) directory inode */ |
88 | xfs_inode_t *ip1, /* in: inode of old entry */ | 76 | xfs_inode_t *ip1, /* in: inode of old entry */ |
89 | struct xfs_name *name2, /* in: new entry name */ | 77 | xfs_inode_t *ip2, /* in: inode of new entry, if it |
90 | xfs_inode_t **ipp2, /* out: inode of new entry, if it | ||
91 | already exists, NULL otherwise. */ | 78 | already exists, NULL otherwise. */ |
92 | xfs_inode_t **i_tab,/* out: array of inode returned, sorted */ | 79 | xfs_inode_t **i_tab,/* out: array of inode returned, sorted */ |
93 | int *num_inodes) /* out: number of inodes in array */ | 80 | int *num_inodes) /* out: number of inodes in array */ |
94 | { | 81 | { |
95 | xfs_inode_t *ip2 = NULL; | ||
96 | xfs_inode_t *temp; | 82 | xfs_inode_t *temp; |
97 | xfs_ino_t inum1, inum2; | ||
98 | int error; | ||
99 | int i, j; | 83 | int i, j; |
100 | uint lock_mode; | ||
101 | int diff_dirs = (dp1 != dp2); | ||
102 | |||
103 | /* | ||
104 | * First, find out the current inums of the entries so that we | ||
105 | * can determine the initial locking order. We'll have to | ||
106 | * sanity check stuff after all the locks have been acquired | ||
107 | * to see if we still have the right inodes, directories, etc. | ||
108 | */ | ||
109 | lock_mode = xfs_ilock_map_shared(dp1); | ||
110 | IHOLD(ip1); | ||
111 | xfs_itrace_ref(ip1); | ||
112 | |||
113 | inum1 = ip1->i_ino; | ||
114 | |||
115 | /* | ||
116 | * Unlock dp1 and lock dp2 if they are different. | ||
117 | */ | ||
118 | if (diff_dirs) { | ||
119 | xfs_iunlock_map_shared(dp1, lock_mode); | ||
120 | lock_mode = xfs_ilock_map_shared(dp2); | ||
121 | } | ||
122 | |||
123 | error = xfs_dir_lookup_int(dp2, lock_mode, name2, &inum2, &ip2); | ||
124 | if (error == ENOENT) { /* target does not need to exist. */ | ||
125 | inum2 = 0; | ||
126 | } else if (error) { | ||
127 | /* | ||
128 | * If dp2 and dp1 are the same, the next line unlocks dp1. | ||
129 | * Got it? | ||
130 | */ | ||
131 | xfs_iunlock_map_shared(dp2, lock_mode); | ||
132 | IRELE (ip1); | ||
133 | return error; | ||
134 | } else { | ||
135 | xfs_itrace_ref(ip2); | ||
136 | } | ||
137 | 84 | ||
138 | /* | 85 | /* |
139 | * i_tab contains a list of pointers to inodes. We initialize | 86 | * i_tab contains a list of pointers to inodes. We initialize |
@@ -145,21 +92,20 @@ xfs_lock_for_rename( | |||
145 | i_tab[0] = dp1; | 92 | i_tab[0] = dp1; |
146 | i_tab[1] = dp2; | 93 | i_tab[1] = dp2; |
147 | i_tab[2] = ip1; | 94 | i_tab[2] = ip1; |
148 | if (inum2 == 0) { | 95 | if (ip2) { |
149 | *num_inodes = 3; | ||
150 | i_tab[3] = NULL; | ||
151 | } else { | ||
152 | *num_inodes = 4; | 96 | *num_inodes = 4; |
153 | i_tab[3] = ip2; | 97 | i_tab[3] = ip2; |
98 | } else { | ||
99 | *num_inodes = 3; | ||
100 | i_tab[3] = NULL; | ||
154 | } | 101 | } |
155 | *ipp2 = i_tab[3]; | ||
156 | 102 | ||
157 | /* | 103 | /* |
158 | * Sort the elements via bubble sort. (Remember, there are at | 104 | * Sort the elements via bubble sort. (Remember, there are at |
159 | * most 4 elements to sort, so this is adequate.) | 105 | * most 4 elements to sort, so this is adequate.) |
160 | */ | 106 | */ |
161 | for (i=0; i < *num_inodes; i++) { | 107 | for (i = 0; i < *num_inodes; i++) { |
162 | for (j=1; j < *num_inodes; j++) { | 108 | for (j = 1; j < *num_inodes; j++) { |
163 | if (i_tab[j]->i_ino < i_tab[j-1]->i_ino) { | 109 | if (i_tab[j]->i_ino < i_tab[j-1]->i_ino) { |
164 | temp = i_tab[j]; | 110 | temp = i_tab[j]; |
165 | i_tab[j] = i_tab[j-1]; | 111 | i_tab[j] = i_tab[j-1]; |
@@ -167,30 +113,6 @@ xfs_lock_for_rename( | |||
167 | } | 113 | } |
168 | } | 114 | } |
169 | } | 115 | } |
170 | |||
171 | /* | ||
172 | * We have dp2 locked. If it isn't first, unlock it. | ||
173 | * If it is first, tell xfs_lock_inodes so it can skip it | ||
174 | * when locking. if dp1 == dp2, xfs_lock_inodes will skip both | ||
175 | * since they are equal. xfs_lock_inodes needs all these inodes | ||
176 | * so that it can unlock and retry if there might be a dead-lock | ||
177 | * potential with the log. | ||
178 | */ | ||
179 | |||
180 | if (i_tab[0] == dp2 && lock_mode == XFS_ILOCK_SHARED) { | ||
181 | #ifdef DEBUG | ||
182 | xfs_rename_skip++; | ||
183 | #endif | ||
184 | xfs_lock_inodes(i_tab, *num_inodes, 1, XFS_ILOCK_SHARED); | ||
185 | } else { | ||
186 | #ifdef DEBUG | ||
187 | xfs_rename_nskip++; | ||
188 | #endif | ||
189 | xfs_iunlock_map_shared(dp2, lock_mode); | ||
190 | xfs_lock_inodes(i_tab, *num_inodes, 0, XFS_ILOCK_SHARED); | ||
191 | } | ||
192 | |||
193 | return 0; | ||
194 | } | 116 | } |
195 | 117 | ||
196 | /* | 118 | /* |
@@ -202,10 +124,10 @@ xfs_rename( | |||
202 | struct xfs_name *src_name, | 124 | struct xfs_name *src_name, |
203 | xfs_inode_t *src_ip, | 125 | xfs_inode_t *src_ip, |
204 | xfs_inode_t *target_dp, | 126 | xfs_inode_t *target_dp, |
205 | struct xfs_name *target_name) | 127 | struct xfs_name *target_name, |
128 | xfs_inode_t *target_ip) | ||
206 | { | 129 | { |
207 | xfs_trans_t *tp; | 130 | xfs_trans_t *tp = NULL; |
208 | xfs_inode_t *target_ip; | ||
209 | xfs_mount_t *mp = src_dp->i_mount; | 131 | xfs_mount_t *mp = src_dp->i_mount; |
210 | int new_parent; /* moving to a new dir */ | 132 | int new_parent; /* moving to a new dir */ |
211 | int src_is_directory; /* src_name is a directory */ | 133 | int src_is_directory; /* src_name is a directory */ |
@@ -215,9 +137,7 @@ xfs_rename( | |||
215 | int cancel_flags; | 137 | int cancel_flags; |
216 | int committed; | 138 | int committed; |
217 | xfs_inode_t *inodes[4]; | 139 | xfs_inode_t *inodes[4]; |
218 | int target_ip_dropped = 0; /* dropped target_ip link? */ | ||
219 | int spaceres; | 140 | int spaceres; |
220 | int target_link_zero = 0; | ||
221 | int num_inodes; | 141 | int num_inodes; |
222 | 142 | ||
223 | xfs_itrace_entry(src_dp); | 143 | xfs_itrace_entry(src_dp); |
@@ -230,64 +150,27 @@ xfs_rename( | |||
230 | target_dp, DM_RIGHT_NULL, | 150 | target_dp, DM_RIGHT_NULL, |
231 | src_name->name, target_name->name, | 151 | src_name->name, target_name->name, |
232 | 0, 0, 0); | 152 | 0, 0, 0); |
233 | if (error) { | 153 | if (error) |
234 | return error; | 154 | return error; |
235 | } | ||
236 | } | 155 | } |
237 | /* Return through std_return after this point. */ | 156 | /* Return through std_return after this point. */ |
238 | 157 | ||
239 | /* | 158 | new_parent = (src_dp != target_dp); |
240 | * Lock all the participating inodes. Depending upon whether | 159 | src_is_directory = ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR); |
241 | * the target_name exists in the target directory, and | ||
242 | * whether the target directory is the same as the source | ||
243 | * directory, we can lock from 2 to 4 inodes. | ||
244 | * xfs_lock_for_rename() will return ENOENT if src_name | ||
245 | * does not exist in the source directory. | ||
246 | */ | ||
247 | tp = NULL; | ||
248 | error = xfs_lock_for_rename(src_dp, target_dp, src_ip, target_name, | ||
249 | &target_ip, inodes, &num_inodes); | ||
250 | if (error) { | ||
251 | /* | ||
252 | * We have nothing locked, no inode references, and | ||
253 | * no transaction, so just get out. | ||
254 | */ | ||
255 | goto std_return; | ||
256 | } | ||
257 | |||
258 | ASSERT(src_ip != NULL); | ||
259 | 160 | ||
260 | if ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR) { | 161 | if (src_is_directory) { |
261 | /* | 162 | /* |
262 | * Check for link count overflow on target_dp | 163 | * Check for link count overflow on target_dp |
263 | */ | 164 | */ |
264 | if (target_ip == NULL && (src_dp != target_dp) && | 165 | if (target_ip == NULL && new_parent && |
265 | target_dp->i_d.di_nlink >= XFS_MAXLINK) { | 166 | target_dp->i_d.di_nlink >= XFS_MAXLINK) { |
266 | error = XFS_ERROR(EMLINK); | 167 | error = XFS_ERROR(EMLINK); |
267 | xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); | 168 | goto std_return; |
268 | goto rele_return; | ||
269 | } | 169 | } |
270 | } | 170 | } |
271 | 171 | ||
272 | /* | 172 | xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, |
273 | * If we are using project inheritance, we only allow renames | 173 | inodes, &num_inodes); |
274 | * into our tree when the project IDs are the same; else the | ||
275 | * tree quota mechanism would be circumvented. | ||
276 | */ | ||
277 | if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && | ||
278 | (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) { | ||
279 | error = XFS_ERROR(EXDEV); | ||
280 | xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); | ||
281 | goto rele_return; | ||
282 | } | ||
283 | |||
284 | new_parent = (src_dp != target_dp); | ||
285 | src_is_directory = ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
286 | |||
287 | /* | ||
288 | * Drop the locks on our inodes so that we can start the transaction. | ||
289 | */ | ||
290 | xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); | ||
291 | 174 | ||
292 | XFS_BMAP_INIT(&free_list, &first_block); | 175 | XFS_BMAP_INIT(&free_list, &first_block); |
293 | tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); | 176 | tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); |
@@ -302,7 +185,7 @@ xfs_rename( | |||
302 | } | 185 | } |
303 | if (error) { | 186 | if (error) { |
304 | xfs_trans_cancel(tp, 0); | 187 | xfs_trans_cancel(tp, 0); |
305 | goto rele_return; | 188 | goto std_return; |
306 | } | 189 | } |
307 | 190 | ||
308 | /* | 191 | /* |
@@ -310,13 +193,29 @@ xfs_rename( | |||
310 | */ | 193 | */ |
311 | if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { | 194 | if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { |
312 | xfs_trans_cancel(tp, cancel_flags); | 195 | xfs_trans_cancel(tp, cancel_flags); |
313 | goto rele_return; | 196 | goto std_return; |
314 | } | 197 | } |
315 | 198 | ||
316 | /* | 199 | /* |
317 | * Reacquire the inode locks we dropped above. | 200 | * Lock all the participating inodes. Depending upon whether |
201 | * the target_name exists in the target directory, and | ||
202 | * whether the target directory is the same as the source | ||
203 | * directory, we can lock from 2 to 4 inodes. | ||
204 | */ | ||
205 | xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL); | ||
206 | |||
207 | /* | ||
208 | * If we are using project inheritance, we only allow renames | ||
209 | * into our tree when the project IDs are the same; else the | ||
210 | * tree quota mechanism would be circumvented. | ||
318 | */ | 211 | */ |
319 | xfs_lock_inodes(inodes, num_inodes, 0, XFS_ILOCK_EXCL); | 212 | if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && |
213 | (target_dp->i_d.di_projid != src_ip->i_d.di_projid))) { | ||
214 | error = XFS_ERROR(EXDEV); | ||
215 | xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); | ||
216 | xfs_trans_cancel(tp, cancel_flags); | ||
217 | goto std_return; | ||
218 | } | ||
320 | 219 | ||
321 | /* | 220 | /* |
322 | * Join all the inodes to the transaction. From this point on, | 221 | * Join all the inodes to the transaction. From this point on, |
@@ -328,17 +227,17 @@ xfs_rename( | |||
328 | */ | 227 | */ |
329 | IHOLD(src_dp); | 228 | IHOLD(src_dp); |
330 | xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL); | 229 | xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL); |
230 | |||
331 | if (new_parent) { | 231 | if (new_parent) { |
332 | IHOLD(target_dp); | 232 | IHOLD(target_dp); |
333 | xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL); | 233 | xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL); |
334 | } | 234 | } |
335 | if ((src_ip != src_dp) && (src_ip != target_dp)) { | 235 | |
336 | xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL); | 236 | IHOLD(src_ip); |
337 | } | 237 | xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL); |
338 | if ((target_ip != NULL) && | 238 | |
339 | (target_ip != src_ip) && | 239 | if (target_ip) { |
340 | (target_ip != src_dp) && | 240 | IHOLD(target_ip); |
341 | (target_ip != target_dp)) { | ||
342 | xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL); | 241 | xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL); |
343 | } | 242 | } |
344 | 243 | ||
@@ -412,7 +311,6 @@ xfs_rename( | |||
412 | error = xfs_droplink(tp, target_ip); | 311 | error = xfs_droplink(tp, target_ip); |
413 | if (error) | 312 | if (error) |
414 | goto abort_return; | 313 | goto abort_return; |
415 | target_ip_dropped = 1; | ||
416 | 314 | ||
417 | if (src_is_directory) { | 315 | if (src_is_directory) { |
418 | /* | 316 | /* |
@@ -422,10 +320,6 @@ xfs_rename( | |||
422 | if (error) | 320 | if (error) |
423 | goto abort_return; | 321 | goto abort_return; |
424 | } | 322 | } |
425 | |||
426 | /* Do this test while we still hold the locks */ | ||
427 | target_link_zero = (target_ip)->i_d.di_nlink==0; | ||
428 | |||
429 | } /* target_ip != NULL */ | 323 | } /* target_ip != NULL */ |
430 | 324 | ||
431 | /* | 325 | /* |
@@ -492,15 +386,6 @@ xfs_rename( | |||
492 | } | 386 | } |
493 | 387 | ||
494 | /* | 388 | /* |
495 | * If there was a target inode, take an extra reference on | ||
496 | * it here so that it doesn't go to xfs_inactive() from | ||
497 | * within the commit. | ||
498 | */ | ||
499 | if (target_ip != NULL) { | ||
500 | IHOLD(target_ip); | ||
501 | } | ||
502 | |||
503 | /* | ||
504 | * If this is a synchronous mount, make sure that the | 389 | * If this is a synchronous mount, make sure that the |
505 | * rename transaction goes to disk before returning to | 390 | * rename transaction goes to disk before returning to |
506 | * the user. | 391 | * the user. |
@@ -509,30 +394,11 @@ xfs_rename( | |||
509 | xfs_trans_set_sync(tp); | 394 | xfs_trans_set_sync(tp); |
510 | } | 395 | } |
511 | 396 | ||
512 | /* | ||
513 | * Take refs. for vop_link_removed calls below. No need to worry | ||
514 | * about directory refs. because the caller holds them. | ||
515 | * | ||
516 | * Do holds before the xfs_bmap_finish since it might rele them down | ||
517 | * to zero. | ||
518 | */ | ||
519 | |||
520 | if (target_ip_dropped) | ||
521 | IHOLD(target_ip); | ||
522 | IHOLD(src_ip); | ||
523 | |||
524 | error = xfs_bmap_finish(&tp, &free_list, &committed); | 397 | error = xfs_bmap_finish(&tp, &free_list, &committed); |
525 | if (error) { | 398 | if (error) { |
526 | xfs_bmap_cancel(&free_list); | 399 | xfs_bmap_cancel(&free_list); |
527 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | | 400 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | |
528 | XFS_TRANS_ABORT)); | 401 | XFS_TRANS_ABORT)); |
529 | if (target_ip != NULL) { | ||
530 | IRELE(target_ip); | ||
531 | } | ||
532 | if (target_ip_dropped) { | ||
533 | IRELE(target_ip); | ||
534 | } | ||
535 | IRELE(src_ip); | ||
536 | goto std_return; | 402 | goto std_return; |
537 | } | 403 | } |
538 | 404 | ||
@@ -541,15 +407,6 @@ xfs_rename( | |||
541 | * the vnode references. | 407 | * the vnode references. |
542 | */ | 408 | */ |
543 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 409 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
544 | if (target_ip != NULL) | ||
545 | IRELE(target_ip); | ||
546 | /* | ||
547 | * Let interposed file systems know about removed links. | ||
548 | */ | ||
549 | if (target_ip_dropped) | ||
550 | IRELE(target_ip); | ||
551 | |||
552 | IRELE(src_ip); | ||
553 | 410 | ||
554 | /* Fall through to std_return with error = 0 or errno from | 411 | /* Fall through to std_return with error = 0 or errno from |
555 | * xfs_trans_commit */ | 412 | * xfs_trans_commit */ |
@@ -571,11 +428,4 @@ std_return: | |||
571 | xfs_bmap_cancel(&free_list); | 428 | xfs_bmap_cancel(&free_list); |
572 | xfs_trans_cancel(tp, cancel_flags); | 429 | xfs_trans_cancel(tp, cancel_flags); |
573 | goto std_return; | 430 | goto std_return; |
574 | |||
575 | rele_return: | ||
576 | IRELE(src_ip); | ||
577 | if (target_ip != NULL) { | ||
578 | IRELE(target_ip); | ||
579 | } | ||
580 | goto std_return; | ||
581 | } | 431 | } |
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index b8db1d5cde5a..4c70bf5e9985 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c | |||
@@ -111,13 +111,13 @@ xfs_trans_iget( | |||
111 | */ | 111 | */ |
112 | ASSERT(ip->i_itemp != NULL); | 112 | ASSERT(ip->i_itemp != NULL); |
113 | ASSERT(lock_flags & XFS_ILOCK_EXCL); | 113 | ASSERT(lock_flags & XFS_ILOCK_EXCL); |
114 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 114 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
115 | ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || | 115 | ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || |
116 | ismrlocked(&ip->i_iolock, MR_UPDATE)); | 116 | xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
117 | ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || | 117 | ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) || |
118 | (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL)); | 118 | (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL)); |
119 | ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || | 119 | ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || |
120 | ismrlocked(&ip->i_iolock, (MR_UPDATE | MR_ACCESS))); | 120 | xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)); |
121 | ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || | 121 | ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) || |
122 | (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY)); | 122 | (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY)); |
123 | 123 | ||
@@ -185,7 +185,7 @@ xfs_trans_ijoin( | |||
185 | xfs_inode_log_item_t *iip; | 185 | xfs_inode_log_item_t *iip; |
186 | 186 | ||
187 | ASSERT(ip->i_transp == NULL); | 187 | ASSERT(ip->i_transp == NULL); |
188 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 188 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
189 | ASSERT(lock_flags & XFS_ILOCK_EXCL); | 189 | ASSERT(lock_flags & XFS_ILOCK_EXCL); |
190 | if (ip->i_itemp == NULL) | 190 | if (ip->i_itemp == NULL) |
191 | xfs_inode_item_init(ip, ip->i_mount); | 191 | xfs_inode_item_init(ip, ip->i_mount); |
@@ -232,7 +232,7 @@ xfs_trans_ihold( | |||
232 | { | 232 | { |
233 | ASSERT(ip->i_transp == tp); | 233 | ASSERT(ip->i_transp == tp); |
234 | ASSERT(ip->i_itemp != NULL); | 234 | ASSERT(ip->i_itemp != NULL); |
235 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 235 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
236 | 236 | ||
237 | ip->i_itemp->ili_flags |= XFS_ILI_HOLD; | 237 | ip->i_itemp->ili_flags |= XFS_ILI_HOLD; |
238 | } | 238 | } |
@@ -257,7 +257,7 @@ xfs_trans_log_inode( | |||
257 | 257 | ||
258 | ASSERT(ip->i_transp == tp); | 258 | ASSERT(ip->i_transp == tp); |
259 | ASSERT(ip->i_itemp != NULL); | 259 | ASSERT(ip->i_itemp != NULL); |
260 | ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE)); | 260 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
261 | 261 | ||
262 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(ip->i_itemp)); | 262 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(ip->i_itemp)); |
263 | ASSERT(lidp != NULL); | 263 | ASSERT(lidp != NULL); |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 2b8dc7e40772..98e5f110ba5f 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -41,49 +41,6 @@ | |||
41 | #include "xfs_utils.h" | 41 | #include "xfs_utils.h" |
42 | 42 | ||
43 | 43 | ||
44 | int | ||
45 | xfs_dir_lookup_int( | ||
46 | xfs_inode_t *dp, | ||
47 | uint lock_mode, | ||
48 | struct xfs_name *name, | ||
49 | xfs_ino_t *inum, | ||
50 | xfs_inode_t **ipp) | ||
51 | { | ||
52 | int error; | ||
53 | |||
54 | xfs_itrace_entry(dp); | ||
55 | |||
56 | error = xfs_dir_lookup(NULL, dp, name, inum); | ||
57 | if (!error) { | ||
58 | /* | ||
59 | * Unlock the directory. We do this because we can't | ||
60 | * hold the directory lock while doing the vn_get() | ||
61 | * in xfs_iget(). Doing so could cause us to hold | ||
62 | * a lock while waiting for the inode to finish | ||
63 | * being inactive while it's waiting for a log | ||
64 | * reservation in the inactive routine. | ||
65 | */ | ||
66 | xfs_iunlock(dp, lock_mode); | ||
67 | error = xfs_iget(dp->i_mount, NULL, *inum, 0, 0, ipp, 0); | ||
68 | xfs_ilock(dp, lock_mode); | ||
69 | |||
70 | if (error) { | ||
71 | *ipp = NULL; | ||
72 | } else if ((*ipp)->i_d.di_mode == 0) { | ||
73 | /* | ||
74 | * The inode has been freed. Something is | ||
75 | * wrong so just get out of here. | ||
76 | */ | ||
77 | xfs_iunlock(dp, lock_mode); | ||
78 | xfs_iput_new(*ipp, 0); | ||
79 | *ipp = NULL; | ||
80 | xfs_ilock(dp, lock_mode); | ||
81 | error = XFS_ERROR(ENOENT); | ||
82 | } | ||
83 | } | ||
84 | return error; | ||
85 | } | ||
86 | |||
87 | /* | 44 | /* |
88 | * Allocates a new inode from disk and return a pointer to the | 45 | * Allocates a new inode from disk and return a pointer to the |
89 | * incore copy. This routine will internally commit the current | 46 | * incore copy. This routine will internally commit the current |
@@ -310,7 +267,7 @@ xfs_bump_ino_vers2( | |||
310 | { | 267 | { |
311 | xfs_mount_t *mp; | 268 | xfs_mount_t *mp; |
312 | 269 | ||
313 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); | 270 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
314 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1); | 271 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1); |
315 | 272 | ||
316 | ip->i_d.di_version = XFS_DINODE_VERSION_2; | 273 | ip->i_d.di_version = XFS_DINODE_VERSION_2; |
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h index 175b126d2cab..f316cb85d8e2 100644 --- a/fs/xfs/xfs_utils.h +++ b/fs/xfs/xfs_utils.h | |||
@@ -21,8 +21,6 @@ | |||
21 | #define IRELE(ip) VN_RELE(XFS_ITOV(ip)) | 21 | #define IRELE(ip) VN_RELE(XFS_ITOV(ip)) |
22 | #define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) | 22 | #define IHOLD(ip) VN_HOLD(XFS_ITOV(ip)) |
23 | 23 | ||
24 | extern int xfs_dir_lookup_int(xfs_inode_t *, uint, struct xfs_name *, | ||
25 | xfs_ino_t *, xfs_inode_t **); | ||
26 | extern int xfs_truncate_file(xfs_mount_t *, xfs_inode_t *); | 24 | extern int xfs_truncate_file(xfs_mount_t *, xfs_inode_t *); |
27 | extern int xfs_dir_ialloc(xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, | 25 | extern int xfs_dir_ialloc(xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, |
28 | xfs_dev_t, cred_t *, prid_t, int, | 26 | xfs_dev_t, cred_t *, prid_t, int, |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index fc48158fe479..30bacd8bb0e5 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -186,6 +186,7 @@ xfs_cleanup(void) | |||
186 | kmem_zone_destroy(xfs_efi_zone); | 186 | kmem_zone_destroy(xfs_efi_zone); |
187 | kmem_zone_destroy(xfs_ifork_zone); | 187 | kmem_zone_destroy(xfs_ifork_zone); |
188 | kmem_zone_destroy(xfs_ili_zone); | 188 | kmem_zone_destroy(xfs_ili_zone); |
189 | kmem_zone_destroy(xfs_log_ticket_zone); | ||
189 | } | 190 | } |
190 | 191 | ||
191 | /* | 192 | /* |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 6650601c64f7..70702a60b4bb 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -76,132 +76,6 @@ xfs_open( | |||
76 | } | 76 | } |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * xfs_getattr | ||
80 | */ | ||
81 | int | ||
82 | xfs_getattr( | ||
83 | xfs_inode_t *ip, | ||
84 | bhv_vattr_t *vap, | ||
85 | int flags) | ||
86 | { | ||
87 | bhv_vnode_t *vp = XFS_ITOV(ip); | ||
88 | xfs_mount_t *mp = ip->i_mount; | ||
89 | |||
90 | xfs_itrace_entry(ip); | ||
91 | |||
92 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
93 | return XFS_ERROR(EIO); | ||
94 | |||
95 | if (!(flags & ATTR_LAZY)) | ||
96 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
97 | |||
98 | vap->va_size = XFS_ISIZE(ip); | ||
99 | if (vap->va_mask == XFS_AT_SIZE) | ||
100 | goto all_done; | ||
101 | |||
102 | vap->va_nblocks = | ||
103 | XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); | ||
104 | vap->va_nodeid = ip->i_ino; | ||
105 | #if XFS_BIG_INUMS | ||
106 | vap->va_nodeid += mp->m_inoadd; | ||
107 | #endif | ||
108 | vap->va_nlink = ip->i_d.di_nlink; | ||
109 | |||
110 | /* | ||
111 | * Quick exit for non-stat callers | ||
112 | */ | ||
113 | if ((vap->va_mask & | ||
114 | ~(XFS_AT_SIZE|XFS_AT_FSID|XFS_AT_NODEID| | ||
115 | XFS_AT_NLINK|XFS_AT_BLKSIZE)) == 0) | ||
116 | goto all_done; | ||
117 | |||
118 | /* | ||
119 | * Copy from in-core inode. | ||
120 | */ | ||
121 | vap->va_mode = ip->i_d.di_mode; | ||
122 | vap->va_uid = ip->i_d.di_uid; | ||
123 | vap->va_gid = ip->i_d.di_gid; | ||
124 | vap->va_projid = ip->i_d.di_projid; | ||
125 | |||
126 | /* | ||
127 | * Check vnode type block/char vs. everything else. | ||
128 | */ | ||
129 | switch (ip->i_d.di_mode & S_IFMT) { | ||
130 | case S_IFBLK: | ||
131 | case S_IFCHR: | ||
132 | vap->va_rdev = ip->i_df.if_u2.if_rdev; | ||
133 | vap->va_blocksize = BLKDEV_IOSIZE; | ||
134 | break; | ||
135 | default: | ||
136 | vap->va_rdev = 0; | ||
137 | |||
138 | if (!(XFS_IS_REALTIME_INODE(ip))) { | ||
139 | vap->va_blocksize = xfs_preferred_iosize(mp); | ||
140 | } else { | ||
141 | |||
142 | /* | ||
143 | * If the file blocks are being allocated from a | ||
144 | * realtime partition, then return the inode's | ||
145 | * realtime extent size or the realtime volume's | ||
146 | * extent size. | ||
147 | */ | ||
148 | vap->va_blocksize = | ||
149 | xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; | ||
150 | } | ||
151 | break; | ||
152 | } | ||
153 | |||
154 | vn_atime_to_timespec(vp, &vap->va_atime); | ||
155 | vap->va_mtime.tv_sec = ip->i_d.di_mtime.t_sec; | ||
156 | vap->va_mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; | ||
157 | vap->va_ctime.tv_sec = ip->i_d.di_ctime.t_sec; | ||
158 | vap->va_ctime.tv_nsec = ip->i_d.di_ctime.t_nsec; | ||
159 | |||
160 | /* | ||
161 | * Exit for stat callers. See if any of the rest of the fields | ||
162 | * to be filled in are needed. | ||
163 | */ | ||
164 | if ((vap->va_mask & | ||
165 | (XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS| | ||
166 | XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0) | ||
167 | goto all_done; | ||
168 | |||
169 | /* | ||
170 | * Convert di_flags to xflags. | ||
171 | */ | ||
172 | vap->va_xflags = xfs_ip2xflags(ip); | ||
173 | |||
174 | /* | ||
175 | * Exit for inode revalidate. See if any of the rest of | ||
176 | * the fields to be filled in are needed. | ||
177 | */ | ||
178 | if ((vap->va_mask & | ||
179 | (XFS_AT_EXTSIZE|XFS_AT_NEXTENTS|XFS_AT_ANEXTENTS| | ||
180 | XFS_AT_GENCOUNT|XFS_AT_VCODE)) == 0) | ||
181 | goto all_done; | ||
182 | |||
183 | vap->va_extsize = ip->i_d.di_extsize << mp->m_sb.sb_blocklog; | ||
184 | vap->va_nextents = | ||
185 | (ip->i_df.if_flags & XFS_IFEXTENTS) ? | ||
186 | ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) : | ||
187 | ip->i_d.di_nextents; | ||
188 | if (ip->i_afp) | ||
189 | vap->va_anextents = | ||
190 | (ip->i_afp->if_flags & XFS_IFEXTENTS) ? | ||
191 | ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) : | ||
192 | ip->i_d.di_anextents; | ||
193 | else | ||
194 | vap->va_anextents = 0; | ||
195 | vap->va_gen = ip->i_d.di_gen; | ||
196 | |||
197 | all_done: | ||
198 | if (!(flags & ATTR_LAZY)) | ||
199 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | |||
204 | /* | ||
205 | * xfs_setattr | 79 | * xfs_setattr |
206 | */ | 80 | */ |
207 | int | 81 | int |
@@ -211,7 +85,6 @@ xfs_setattr( | |||
211 | int flags, | 85 | int flags, |
212 | cred_t *credp) | 86 | cred_t *credp) |
213 | { | 87 | { |
214 | bhv_vnode_t *vp = XFS_ITOV(ip); | ||
215 | xfs_mount_t *mp = ip->i_mount; | 88 | xfs_mount_t *mp = ip->i_mount; |
216 | xfs_trans_t *tp; | 89 | xfs_trans_t *tp; |
217 | int mask; | 90 | int mask; |
@@ -222,7 +95,6 @@ xfs_setattr( | |||
222 | gid_t gid=0, igid=0; | 95 | gid_t gid=0, igid=0; |
223 | int timeflags = 0; | 96 | int timeflags = 0; |
224 | xfs_prid_t projid=0, iprojid=0; | 97 | xfs_prid_t projid=0, iprojid=0; |
225 | int mandlock_before, mandlock_after; | ||
226 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; | 98 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; |
227 | int file_owner; | 99 | int file_owner; |
228 | int need_iolock = 1; | 100 | int need_iolock = 1; |
@@ -383,7 +255,7 @@ xfs_setattr( | |||
383 | m |= S_ISGID; | 255 | m |= S_ISGID; |
384 | #if 0 | 256 | #if 0 |
385 | /* Linux allows this, Irix doesn't. */ | 257 | /* Linux allows this, Irix doesn't. */ |
386 | if ((vap->va_mode & S_ISVTX) && !VN_ISDIR(vp)) | 258 | if ((vap->va_mode & S_ISVTX) && !S_ISDIR(ip->i_d.di_mode)) |
387 | m |= S_ISVTX; | 259 | m |= S_ISVTX; |
388 | #endif | 260 | #endif |
389 | if (m && !capable(CAP_FSETID)) | 261 | if (m && !capable(CAP_FSETID)) |
@@ -461,10 +333,10 @@ xfs_setattr( | |||
461 | goto error_return; | 333 | goto error_return; |
462 | } | 334 | } |
463 | 335 | ||
464 | if (VN_ISDIR(vp)) { | 336 | if (S_ISDIR(ip->i_d.di_mode)) { |
465 | code = XFS_ERROR(EISDIR); | 337 | code = XFS_ERROR(EISDIR); |
466 | goto error_return; | 338 | goto error_return; |
467 | } else if (!VN_ISREG(vp)) { | 339 | } else if (!S_ISREG(ip->i_d.di_mode)) { |
468 | code = XFS_ERROR(EINVAL); | 340 | code = XFS_ERROR(EINVAL); |
469 | goto error_return; | 341 | goto error_return; |
470 | } | 342 | } |
@@ -626,9 +498,6 @@ xfs_setattr( | |||
626 | xfs_trans_ihold(tp, ip); | 498 | xfs_trans_ihold(tp, ip); |
627 | } | 499 | } |
628 | 500 | ||
629 | /* determine whether mandatory locking mode changes */ | ||
630 | mandlock_before = MANDLOCK(vp, ip->i_d.di_mode); | ||
631 | |||
632 | /* | 501 | /* |
633 | * Truncate file. Must have write permission and not be a directory. | 502 | * Truncate file. Must have write permission and not be a directory. |
634 | */ | 503 | */ |
@@ -858,13 +727,6 @@ xfs_setattr( | |||
858 | code = xfs_trans_commit(tp, commit_flags); | 727 | code = xfs_trans_commit(tp, commit_flags); |
859 | } | 728 | } |
860 | 729 | ||
861 | /* | ||
862 | * If the (regular) file's mandatory locking mode changed, then | ||
863 | * notify the vnode. We do this under the inode lock to prevent | ||
864 | * racing calls to vop_vnode_change. | ||
865 | */ | ||
866 | mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); | ||
867 | |||
868 | xfs_iunlock(ip, lock_flags); | 730 | xfs_iunlock(ip, lock_flags); |
869 | 731 | ||
870 | /* | 732 | /* |
@@ -1443,7 +1305,7 @@ xfs_inactive_attrs( | |||
1443 | int error; | 1305 | int error; |
1444 | xfs_mount_t *mp; | 1306 | xfs_mount_t *mp; |
1445 | 1307 | ||
1446 | ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE)); | 1308 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
1447 | tp = *tpp; | 1309 | tp = *tpp; |
1448 | mp = ip->i_mount; | 1310 | mp = ip->i_mount; |
1449 | ASSERT(ip->i_d.di_forkoff != 0); | 1311 | ASSERT(ip->i_d.di_forkoff != 0); |
@@ -1491,7 +1353,7 @@ xfs_release( | |||
1491 | xfs_mount_t *mp = ip->i_mount; | 1353 | xfs_mount_t *mp = ip->i_mount; |
1492 | int error; | 1354 | int error; |
1493 | 1355 | ||
1494 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) | 1356 | if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0)) |
1495 | return 0; | 1357 | return 0; |
1496 | 1358 | ||
1497 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1359 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
@@ -1774,8 +1636,7 @@ xfs_lookup( | |||
1774 | struct xfs_name *name, | 1636 | struct xfs_name *name, |
1775 | xfs_inode_t **ipp) | 1637 | xfs_inode_t **ipp) |
1776 | { | 1638 | { |
1777 | xfs_inode_t *ip; | 1639 | xfs_ino_t inum; |
1778 | xfs_ino_t e_inum; | ||
1779 | int error; | 1640 | int error; |
1780 | uint lock_mode; | 1641 | uint lock_mode; |
1781 | 1642 | ||
@@ -1785,12 +1646,21 @@ xfs_lookup( | |||
1785 | return XFS_ERROR(EIO); | 1646 | return XFS_ERROR(EIO); |
1786 | 1647 | ||
1787 | lock_mode = xfs_ilock_map_shared(dp); | 1648 | lock_mode = xfs_ilock_map_shared(dp); |
1788 | error = xfs_dir_lookup_int(dp, lock_mode, name, &e_inum, &ip); | 1649 | error = xfs_dir_lookup(NULL, dp, name, &inum); |
1789 | if (!error) { | ||
1790 | *ipp = ip; | ||
1791 | xfs_itrace_ref(ip); | ||
1792 | } | ||
1793 | xfs_iunlock_map_shared(dp, lock_mode); | 1650 | xfs_iunlock_map_shared(dp, lock_mode); |
1651 | |||
1652 | if (error) | ||
1653 | goto out; | ||
1654 | |||
1655 | error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp, 0); | ||
1656 | if (error) | ||
1657 | goto out; | ||
1658 | |||
1659 | xfs_itrace_ref(*ipp); | ||
1660 | return 0; | ||
1661 | |||
1662 | out: | ||
1663 | *ipp = NULL; | ||
1794 | return error; | 1664 | return error; |
1795 | } | 1665 | } |
1796 | 1666 | ||
@@ -1906,7 +1776,7 @@ xfs_create( | |||
1906 | * It is locked (and joined to the transaction). | 1776 | * It is locked (and joined to the transaction). |
1907 | */ | 1777 | */ |
1908 | 1778 | ||
1909 | ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE)); | 1779 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
1910 | 1780 | ||
1911 | /* | 1781 | /* |
1912 | * Now we join the directory inode to the transaction. We do not do it | 1782 | * Now we join the directory inode to the transaction. We do not do it |
@@ -2112,7 +1982,7 @@ again: | |||
2112 | 1982 | ||
2113 | ips[0] = ip; | 1983 | ips[0] = ip; |
2114 | ips[1] = dp; | 1984 | ips[1] = dp; |
2115 | xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL); | 1985 | xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); |
2116 | } | 1986 | } |
2117 | /* else e_inum == dp->i_ino */ | 1987 | /* else e_inum == dp->i_ino */ |
2118 | /* This can happen if we're asked to lock /x/.. | 1988 | /* This can happen if we're asked to lock /x/.. |
@@ -2160,7 +2030,6 @@ void | |||
2160 | xfs_lock_inodes( | 2030 | xfs_lock_inodes( |
2161 | xfs_inode_t **ips, | 2031 | xfs_inode_t **ips, |
2162 | int inodes, | 2032 | int inodes, |
2163 | int first_locked, | ||
2164 | uint lock_mode) | 2033 | uint lock_mode) |
2165 | { | 2034 | { |
2166 | int attempts = 0, i, j, try_lock; | 2035 | int attempts = 0, i, j, try_lock; |
@@ -2168,13 +2037,8 @@ xfs_lock_inodes( | |||
2168 | 2037 | ||
2169 | ASSERT(ips && (inodes >= 2)); /* we need at least two */ | 2038 | ASSERT(ips && (inodes >= 2)); /* we need at least two */ |
2170 | 2039 | ||
2171 | if (first_locked) { | 2040 | try_lock = 0; |
2172 | try_lock = 1; | 2041 | i = 0; |
2173 | i = 1; | ||
2174 | } else { | ||
2175 | try_lock = 0; | ||
2176 | i = 0; | ||
2177 | } | ||
2178 | 2042 | ||
2179 | again: | 2043 | again: |
2180 | for (; i < inodes; i++) { | 2044 | for (; i < inodes; i++) { |
@@ -2298,29 +2162,14 @@ xfs_remove( | |||
2298 | return error; | 2162 | return error; |
2299 | } | 2163 | } |
2300 | 2164 | ||
2301 | /* | ||
2302 | * We need to get a reference to ip before we get our log | ||
2303 | * reservation. The reason for this is that we cannot call | ||
2304 | * xfs_iget for an inode for which we do not have a reference | ||
2305 | * once we've acquired a log reservation. This is because the | ||
2306 | * inode we are trying to get might be in xfs_inactive going | ||
2307 | * for a log reservation. Since we'll have to wait for the | ||
2308 | * inactive code to complete before returning from xfs_iget, | ||
2309 | * we need to make sure that we don't have log space reserved | ||
2310 | * when we call xfs_iget. Instead we get an unlocked reference | ||
2311 | * to the inode before getting our log reservation. | ||
2312 | */ | ||
2313 | IHOLD(ip); | ||
2314 | |||
2315 | xfs_itrace_entry(ip); | 2165 | xfs_itrace_entry(ip); |
2316 | xfs_itrace_ref(ip); | 2166 | xfs_itrace_ref(ip); |
2317 | 2167 | ||
2318 | error = XFS_QM_DQATTACH(mp, dp, 0); | 2168 | error = XFS_QM_DQATTACH(mp, dp, 0); |
2319 | if (!error && dp != ip) | 2169 | if (!error) |
2320 | error = XFS_QM_DQATTACH(mp, ip, 0); | 2170 | error = XFS_QM_DQATTACH(mp, ip, 0); |
2321 | if (error) { | 2171 | if (error) { |
2322 | REMOVE_DEBUG_TRACE(__LINE__); | 2172 | REMOVE_DEBUG_TRACE(__LINE__); |
2323 | IRELE(ip); | ||
2324 | goto std_return; | 2173 | goto std_return; |
2325 | } | 2174 | } |
2326 | 2175 | ||
@@ -2347,7 +2196,6 @@ xfs_remove( | |||
2347 | ASSERT(error != ENOSPC); | 2196 | ASSERT(error != ENOSPC); |
2348 | REMOVE_DEBUG_TRACE(__LINE__); | 2197 | REMOVE_DEBUG_TRACE(__LINE__); |
2349 | xfs_trans_cancel(tp, 0); | 2198 | xfs_trans_cancel(tp, 0); |
2350 | IRELE(ip); | ||
2351 | return error; | 2199 | return error; |
2352 | } | 2200 | } |
2353 | 2201 | ||
@@ -2355,7 +2203,6 @@ xfs_remove( | |||
2355 | if (error) { | 2203 | if (error) { |
2356 | REMOVE_DEBUG_TRACE(__LINE__); | 2204 | REMOVE_DEBUG_TRACE(__LINE__); |
2357 | xfs_trans_cancel(tp, cancel_flags); | 2205 | xfs_trans_cancel(tp, cancel_flags); |
2358 | IRELE(ip); | ||
2359 | goto std_return; | 2206 | goto std_return; |
2360 | } | 2207 | } |
2361 | 2208 | ||
@@ -2363,23 +2210,18 @@ xfs_remove( | |||
2363 | * At this point, we've gotten both the directory and the entry | 2210 | * At this point, we've gotten both the directory and the entry |
2364 | * inodes locked. | 2211 | * inodes locked. |
2365 | */ | 2212 | */ |
2213 | IHOLD(ip); | ||
2366 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2214 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2367 | if (dp != ip) { | 2215 | |
2368 | /* | 2216 | IHOLD(dp); |
2369 | * Increment vnode ref count only in this case since | 2217 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
2370 | * there's an extra vnode reference in the case where | ||
2371 | * dp == ip. | ||
2372 | */ | ||
2373 | IHOLD(dp); | ||
2374 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
2375 | } | ||
2376 | 2218 | ||
2377 | /* | 2219 | /* |
2378 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. | 2220 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. |
2379 | */ | 2221 | */ |
2380 | XFS_BMAP_INIT(&free_list, &first_block); | 2222 | XFS_BMAP_INIT(&free_list, &first_block); |
2381 | error = xfs_dir_removename(tp, dp, name, ip->i_ino, | 2223 | error = xfs_dir_removename(tp, dp, name, ip->i_ino, |
2382 | &first_block, &free_list, 0); | 2224 | &first_block, &free_list, resblks); |
2383 | if (error) { | 2225 | if (error) { |
2384 | ASSERT(error != ENOENT); | 2226 | ASSERT(error != ENOENT); |
2385 | REMOVE_DEBUG_TRACE(__LINE__); | 2227 | REMOVE_DEBUG_TRACE(__LINE__); |
@@ -2402,12 +2244,6 @@ xfs_remove( | |||
2402 | link_zero = (ip)->i_d.di_nlink==0; | 2244 | link_zero = (ip)->i_d.di_nlink==0; |
2403 | 2245 | ||
2404 | /* | 2246 | /* |
2405 | * Take an extra ref on the inode so that it doesn't | ||
2406 | * go to xfs_inactive() from within the commit. | ||
2407 | */ | ||
2408 | IHOLD(ip); | ||
2409 | |||
2410 | /* | ||
2411 | * If this is a synchronous mount, make sure that the | 2247 | * If this is a synchronous mount, make sure that the |
2412 | * remove transaction goes to disk before returning to | 2248 | * remove transaction goes to disk before returning to |
2413 | * the user. | 2249 | * the user. |
@@ -2423,10 +2259,8 @@ xfs_remove( | |||
2423 | } | 2259 | } |
2424 | 2260 | ||
2425 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 2261 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
2426 | if (error) { | 2262 | if (error) |
2427 | IRELE(ip); | ||
2428 | goto std_return; | 2263 | goto std_return; |
2429 | } | ||
2430 | 2264 | ||
2431 | /* | 2265 | /* |
2432 | * If we are using filestreams, kill the stream association. | 2266 | * If we are using filestreams, kill the stream association. |
@@ -2438,7 +2272,6 @@ xfs_remove( | |||
2438 | xfs_filestream_deassociate(ip); | 2272 | xfs_filestream_deassociate(ip); |
2439 | 2273 | ||
2440 | xfs_itrace_exit(ip); | 2274 | xfs_itrace_exit(ip); |
2441 | IRELE(ip); | ||
2442 | 2275 | ||
2443 | /* Fall through to std_return with error = 0 */ | 2276 | /* Fall through to std_return with error = 0 */ |
2444 | std_return: | 2277 | std_return: |
@@ -2467,8 +2300,6 @@ xfs_remove( | |||
2467 | cancel_flags |= XFS_TRANS_ABORT; | 2300 | cancel_flags |= XFS_TRANS_ABORT; |
2468 | xfs_trans_cancel(tp, cancel_flags); | 2301 | xfs_trans_cancel(tp, cancel_flags); |
2469 | 2302 | ||
2470 | IRELE(ip); | ||
2471 | |||
2472 | goto std_return; | 2303 | goto std_return; |
2473 | } | 2304 | } |
2474 | 2305 | ||
@@ -2536,7 +2367,7 @@ xfs_link( | |||
2536 | ips[1] = sip; | 2367 | ips[1] = sip; |
2537 | } | 2368 | } |
2538 | 2369 | ||
2539 | xfs_lock_inodes(ips, 2, 0, XFS_ILOCK_EXCL); | 2370 | xfs_lock_inodes(ips, 2, XFS_ILOCK_EXCL); |
2540 | 2371 | ||
2541 | /* | 2372 | /* |
2542 | * Increment vnode ref counts since xfs_trans_commit & | 2373 | * Increment vnode ref counts since xfs_trans_commit & |
@@ -2840,7 +2671,6 @@ xfs_rmdir( | |||
2840 | struct xfs_name *name, | 2671 | struct xfs_name *name, |
2841 | xfs_inode_t *cdp) | 2672 | xfs_inode_t *cdp) |
2842 | { | 2673 | { |
2843 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
2844 | xfs_mount_t *mp = dp->i_mount; | 2674 | xfs_mount_t *mp = dp->i_mount; |
2845 | xfs_trans_t *tp; | 2675 | xfs_trans_t *tp; |
2846 | int error; | 2676 | int error; |
@@ -2866,27 +2696,12 @@ xfs_rmdir( | |||
2866 | } | 2696 | } |
2867 | 2697 | ||
2868 | /* | 2698 | /* |
2869 | * We need to get a reference to cdp before we get our log | ||
2870 | * reservation. The reason for this is that we cannot call | ||
2871 | * xfs_iget for an inode for which we do not have a reference | ||
2872 | * once we've acquired a log reservation. This is because the | ||
2873 | * inode we are trying to get might be in xfs_inactive going | ||
2874 | * for a log reservation. Since we'll have to wait for the | ||
2875 | * inactive code to complete before returning from xfs_iget, | ||
2876 | * we need to make sure that we don't have log space reserved | ||
2877 | * when we call xfs_iget. Instead we get an unlocked reference | ||
2878 | * to the inode before getting our log reservation. | ||
2879 | */ | ||
2880 | IHOLD(cdp); | ||
2881 | |||
2882 | /* | ||
2883 | * Get the dquots for the inodes. | 2699 | * Get the dquots for the inodes. |
2884 | */ | 2700 | */ |
2885 | error = XFS_QM_DQATTACH(mp, dp, 0); | 2701 | error = XFS_QM_DQATTACH(mp, dp, 0); |
2886 | if (!error && dp != cdp) | 2702 | if (!error) |
2887 | error = XFS_QM_DQATTACH(mp, cdp, 0); | 2703 | error = XFS_QM_DQATTACH(mp, cdp, 0); |
2888 | if (error) { | 2704 | if (error) { |
2889 | IRELE(cdp); | ||
2890 | REMOVE_DEBUG_TRACE(__LINE__); | 2705 | REMOVE_DEBUG_TRACE(__LINE__); |
2891 | goto std_return; | 2706 | goto std_return; |
2892 | } | 2707 | } |
@@ -2913,7 +2728,6 @@ xfs_rmdir( | |||
2913 | if (error) { | 2728 | if (error) { |
2914 | ASSERT(error != ENOSPC); | 2729 | ASSERT(error != ENOSPC); |
2915 | cancel_flags = 0; | 2730 | cancel_flags = 0; |
2916 | IRELE(cdp); | ||
2917 | goto error_return; | 2731 | goto error_return; |
2918 | } | 2732 | } |
2919 | XFS_BMAP_INIT(&free_list, &first_block); | 2733 | XFS_BMAP_INIT(&free_list, &first_block); |
@@ -2927,21 +2741,13 @@ xfs_rmdir( | |||
2927 | error = xfs_lock_dir_and_entry(dp, cdp); | 2741 | error = xfs_lock_dir_and_entry(dp, cdp); |
2928 | if (error) { | 2742 | if (error) { |
2929 | xfs_trans_cancel(tp, cancel_flags); | 2743 | xfs_trans_cancel(tp, cancel_flags); |
2930 | IRELE(cdp); | ||
2931 | goto std_return; | 2744 | goto std_return; |
2932 | } | 2745 | } |
2933 | 2746 | ||
2747 | IHOLD(dp); | ||
2934 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2748 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2935 | if (dp != cdp) { | ||
2936 | /* | ||
2937 | * Only increment the parent directory vnode count if | ||
2938 | * we didn't bump it in looking up cdp. The only time | ||
2939 | * we don't bump it is when we're looking up ".". | ||
2940 | */ | ||
2941 | VN_HOLD(dir_vp); | ||
2942 | } | ||
2943 | 2749 | ||
2944 | xfs_itrace_ref(cdp); | 2750 | IHOLD(cdp); |
2945 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); | 2751 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); |
2946 | 2752 | ||
2947 | ASSERT(cdp->i_d.di_nlink >= 2); | 2753 | ASSERT(cdp->i_d.di_nlink >= 2); |
@@ -2995,12 +2801,6 @@ xfs_rmdir( | |||
2995 | last_cdp_link = (cdp)->i_d.di_nlink==0; | 2801 | last_cdp_link = (cdp)->i_d.di_nlink==0; |
2996 | 2802 | ||
2997 | /* | 2803 | /* |
2998 | * Take an extra ref on the child vnode so that it | ||
2999 | * does not go to xfs_inactive() from within the commit. | ||
3000 | */ | ||
3001 | IHOLD(cdp); | ||
3002 | |||
3003 | /* | ||
3004 | * If this is a synchronous mount, make sure that the | 2804 | * If this is a synchronous mount, make sure that the |
3005 | * rmdir transaction goes to disk before returning to | 2805 | * rmdir transaction goes to disk before returning to |
3006 | * the user. | 2806 | * the user. |
@@ -3014,19 +2814,15 @@ xfs_rmdir( | |||
3014 | xfs_bmap_cancel(&free_list); | 2814 | xfs_bmap_cancel(&free_list); |
3015 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | | 2815 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | |
3016 | XFS_TRANS_ABORT)); | 2816 | XFS_TRANS_ABORT)); |
3017 | IRELE(cdp); | ||
3018 | goto std_return; | 2817 | goto std_return; |
3019 | } | 2818 | } |
3020 | 2819 | ||
3021 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 2820 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
3022 | if (error) { | 2821 | if (error) { |
3023 | IRELE(cdp); | ||
3024 | goto std_return; | 2822 | goto std_return; |
3025 | } | 2823 | } |
3026 | 2824 | ||
3027 | 2825 | ||
3028 | IRELE(cdp); | ||
3029 | |||
3030 | /* Fall through to std_return with error = 0 or the errno | 2826 | /* Fall through to std_return with error = 0 or the errno |
3031 | * from xfs_trans_commit. */ | 2827 | * from xfs_trans_commit. */ |
3032 | std_return: | 2828 | std_return: |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index 24c53923dc2c..8abe8f186e20 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -15,7 +15,6 @@ struct xfs_iomap; | |||
15 | 15 | ||
16 | 16 | ||
17 | int xfs_open(struct xfs_inode *ip); | 17 | int xfs_open(struct xfs_inode *ip); |
18 | int xfs_getattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags); | ||
19 | int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, | 18 | int xfs_setattr(struct xfs_inode *ip, struct bhv_vattr *vap, int flags, |
20 | struct cred *credp); | 19 | struct cred *credp); |
21 | int xfs_readlink(struct xfs_inode *ip, char *link); | 20 | int xfs_readlink(struct xfs_inode *ip, char *link); |
@@ -48,9 +47,9 @@ int xfs_change_file_space(struct xfs_inode *ip, int cmd, | |||
48 | struct cred *credp, int attr_flags); | 47 | struct cred *credp, int attr_flags); |
49 | int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name, | 48 | int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name, |
50 | struct xfs_inode *src_ip, struct xfs_inode *target_dp, | 49 | struct xfs_inode *src_ip, struct xfs_inode *target_dp, |
51 | struct xfs_name *target_name); | 50 | struct xfs_name *target_name, struct xfs_inode *target_ip); |
52 | int xfs_attr_get(struct xfs_inode *ip, const char *name, char *value, | 51 | int xfs_attr_get(struct xfs_inode *ip, const char *name, char *value, |
53 | int *valuelenp, int flags, cred_t *cred); | 52 | int *valuelenp, int flags); |
54 | int xfs_attr_set(struct xfs_inode *dp, const char *name, char *value, | 53 | int xfs_attr_set(struct xfs_inode *dp, const char *name, char *value, |
55 | int valuelen, int flags); | 54 | int valuelen, int flags); |
56 | int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags); | 55 | int xfs_attr_remove(struct xfs_inode *dp, const char *name, int flags); |
@@ -61,9 +60,6 @@ int xfs_ioctl(struct xfs_inode *ip, struct file *filp, | |||
61 | ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb, | 60 | ssize_t xfs_read(struct xfs_inode *ip, struct kiocb *iocb, |
62 | const struct iovec *iovp, unsigned int segs, | 61 | const struct iovec *iovp, unsigned int segs, |
63 | loff_t *offset, int ioflags); | 62 | loff_t *offset, int ioflags); |
64 | ssize_t xfs_sendfile(struct xfs_inode *ip, struct file *filp, | ||
65 | loff_t *offset, int ioflags, size_t count, | ||
66 | read_actor_t actor, void *target); | ||
67 | ssize_t xfs_splice_read(struct xfs_inode *ip, struct file *infilp, | 63 | ssize_t xfs_splice_read(struct xfs_inode *ip, struct file *infilp, |
68 | loff_t *ppos, struct pipe_inode_info *pipe, size_t count, | 64 | loff_t *ppos, struct pipe_inode_info *pipe, size_t count, |
69 | int flags, int ioflags); | 65 | int flags, int ioflags); |