aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pretzel.yyz.us>2005-06-22 13:10:49 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-06-22 13:10:49 -0400
commit80bd6d7f5e0d872a0f5a151473d2a39d95d210a8 (patch)
treeb3a36048d6b7de88f7e906624ecb4b98816bb736 /fs
parent949d33e70f2c3e93bfe5265a50e40175b1ab1ec1 (diff)
parent2a5a68b840cbab31baab2d9b2e1e6de3b289ae1e (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig50
-rw-r--r--fs/autofs4/autofs_i.h13
-rw-r--r--fs/autofs4/expire.c5
-rw-r--r--fs/autofs4/root.c15
-rw-r--r--fs/autofs4/waitq.c7
-rw-r--r--fs/binfmt_aout.c1
-rw-r--r--fs/binfmt_elf.c3
-rw-r--r--fs/binfmt_flat.c6
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/cifs/CHANGES3
-rw-r--r--fs/cifs/README4
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c56
-rw-r--r--fs/cifs/dir.c3
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/cifs/inode.c48
-rw-r--r--fs/cifs/misc.c1
-rw-r--r--fs/coda/psdev.c18
-rw-r--r--fs/debugfs/file.c67
-rw-r--r--fs/exec.c16
-rw-r--r--fs/hostfs/hostfs_kern.c1
-rw-r--r--fs/hugetlbfs/inode.c3
-rw-r--r--fs/isofs/dir.c17
-rw-r--r--fs/isofs/inode.c128
-rw-r--r--fs/isofs/isofs.h2
-rw-r--r--fs/isofs/namei.c16
-rw-r--r--fs/isofs/rock.c962
-rw-r--r--fs/isofs/rock.h183
-rw-r--r--fs/jbd/checkpoint.c5
-rw-r--r--fs/jfs/acl.c6
-rw-r--r--fs/jfs/file.c9
-rw-r--r--fs/jfs/inode.c11
-rw-r--r--fs/jfs/jfs_debug.c10
-rw-r--r--fs/jfs/jfs_debug.h15
-rw-r--r--fs/jfs/jfs_dmap.c9
-rw-r--r--fs/jfs/jfs_dtree.c3
-rw-r--r--fs/jfs/jfs_extent.c7
-rw-r--r--fs/jfs/jfs_imap.c6
-rw-r--r--fs/jfs/jfs_inode.c1
-rw-r--r--fs/jfs/jfs_inode.h19
-rw-r--r--fs/jfs/jfs_logmgr.c14
-rw-r--r--fs/jfs/jfs_logmgr.h2
-rw-r--r--fs/jfs/jfs_metapage.c6
-rw-r--r--fs/jfs/jfs_metapage.h6
-rw-r--r--fs/jfs/jfs_superblock.h11
-rw-r--r--fs/jfs/jfs_txnmgr.c40
-rw-r--r--fs/jfs/jfs_txnmgr.h52
-rw-r--r--fs/jfs/namei.c28
-rw-r--r--fs/jfs/super.c37
-rw-r--r--fs/jfs/symlink.c3
-rw-r--r--fs/jfs/xattr.c6
-rw-r--r--fs/libfs.c100
-rw-r--r--fs/mpage.c5
-rw-r--r--fs/namei.c153
-rw-r--r--fs/nfs/dir.c49
-rw-r--r--fs/nfs/file.c42
-rw-r--r--fs/proc/proc_devtree.c105
-rw-r--r--fs/proc/proc_misc.c14
-rw-r--r--fs/super.c1
-rw-r--r--fs/sysfs/bin.c4
-rw-r--r--fs/sysfs/dir.c26
-rw-r--r--fs/sysfs/file.c6
-rw-r--r--fs/sysfs/inode.c102
-rw-r--r--fs/sysfs/mount.c4
-rw-r--r--fs/sysfs/symlink.c8
-rw-r--r--fs/sysfs/sysfs.h4
-rw-r--r--fs/udf/udftime.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c153
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c34
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c29
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.h6
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h12
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c34
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c15
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h2
-rw-r--r--fs/xfs/quota/xfs_dquot.c105
-rw-r--r--fs/xfs/quota/xfs_dquot.h30
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c6
-rw-r--r--fs/xfs/quota/xfs_qm.c202
-rw-r--r--fs/xfs/quota/xfs_qm.h16
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c43
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c175
-rw-r--r--fs/xfs/quota/xfs_quota_priv.h15
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c60
-rw-r--r--fs/xfs/support/debug.c1
-rw-r--r--fs/xfs/support/debug.h7
-rw-r--r--fs/xfs/xfs_alloc.c4
-rw-r--r--fs/xfs/xfs_attr.c17
-rw-r--r--fs/xfs/xfs_attr.h7
-rw-r--r--fs/xfs/xfs_attr_leaf.c28
-rw-r--r--fs/xfs/xfs_attr_leaf.h12
-rw-r--r--fs/xfs/xfs_bit.c2
-rw-r--r--fs/xfs/xfs_bmap.c127
-rw-r--r--fs/xfs/xfs_bmap.h13
-rw-r--r--fs/xfs/xfs_bmap_btree.c14
-rw-r--r--fs/xfs/xfs_bmap_btree.h8
-rw-r--r--fs/xfs/xfs_btree.c12
-rw-r--r--fs/xfs/xfs_btree.h10
-rw-r--r--fs/xfs/xfs_buf_item.c24
-rw-r--r--fs/xfs/xfs_buf_item.h2
-rw-r--r--fs/xfs/xfs_da_btree.c9
-rw-r--r--fs/xfs/xfs_da_btree.h3
-rw-r--r--fs/xfs/xfs_dfrag.c7
-rw-r--r--fs/xfs/xfs_dir2_data.c2
-rw-r--r--fs/xfs/xfs_dir2_data.h4
-rw-r--r--fs/xfs/xfs_dir2_leaf.c8
-rw-r--r--fs/xfs/xfs_dir2_leaf.h7
-rw-r--r--fs/xfs/xfs_dir_leaf.c6
-rw-r--r--fs/xfs/xfs_dir_leaf.h2
-rw-r--r--fs/xfs/xfs_dmapi.h19
-rw-r--r--fs/xfs/xfs_error.c2
-rw-r--r--fs/xfs/xfs_error.h3
-rw-r--r--fs/xfs/xfs_extfree_item.c126
-rw-r--r--fs/xfs/xfs_extfree_item.h2
-rw-r--r--fs/xfs/xfs_fs.h3
-rw-r--r--fs/xfs/xfs_fsops.c26
-rw-r--r--fs/xfs/xfs_ialloc_btree.h8
-rw-r--r--fs/xfs/xfs_inode.c185
-rw-r--r--fs/xfs/xfs_inode.h9
-rw-r--r--fs/xfs/xfs_inode_item.c2
-rw-r--r--fs/xfs/xfs_iomap.c69
-rw-r--r--fs/xfs/xfs_log.c6
-rw-r--r--fs/xfs/xfs_log_priv.h2
-rw-r--r--fs/xfs/xfs_log_recover.c31
-rw-r--r--fs/xfs/xfs_macros.c5
-rw-r--r--fs/xfs/xfs_mount.c16
-rw-r--r--fs/xfs/xfs_mount.h7
-rw-r--r--fs/xfs/xfs_quota.h72
-rw-r--r--fs/xfs/xfs_rename.c18
-rw-r--r--fs/xfs/xfs_trans.c21
-rw-r--r--fs/xfs/xfs_trans.h3
-rw-r--r--fs/xfs/xfs_trans_buf.c1
-rw-r--r--fs/xfs/xfs_trans_inode.c18
-rw-r--r--fs/xfs/xfs_types.h2
-rw-r--r--fs/xfs/xfs_utils.c2
-rw-r--r--fs/xfs/xfs_vfsops.c74
-rw-r--r--fs/xfs/xfs_vnodeops.c95
144 files changed, 2437 insertions, 2250 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 6a4ad4bb7a54..178e27494b74 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -741,56 +741,6 @@ config SYSFS
741 741
742 Designers of embedded systems may wish to say N here to conserve space. 742 Designers of embedded systems may wish to say N here to conserve space.
743 743
744config DEVFS_FS
745 bool "/dev file system support (OBSOLETE)"
746 depends on EXPERIMENTAL
747 help
748 This is support for devfs, a virtual file system (like /proc) which
749 provides the file system interface to device drivers, normally found
750 in /dev. Devfs does not depend on major and minor number
751 allocations. Device drivers register entries in /dev which then
752 appear automatically, which means that the system administrator does
753 not have to create character and block special device files in the
754 /dev directory using the mknod command (or MAKEDEV script) anymore.
755
756 This is work in progress. If you want to use this, you *must* read
757 the material in <file:Documentation/filesystems/devfs/>, especially
758 the file README there.
759
760 Note that devfs no longer manages /dev/pts! If you are using UNIX98
761 ptys, you will also need to mount the /dev/pts filesystem (devpts).
762
763 Note that devfs has been obsoleted by udev,
764 <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>.
765 It has been stripped down to a bare minimum and is only provided for
766 legacy installations that use its naming scheme which is
767 unfortunately different from the names normal Linux installations
768 use.
769
770 If unsure, say N.
771
772config DEVFS_MOUNT
773 bool "Automatically mount at boot"
774 depends on DEVFS_FS
775 help
776 This option appears if you have CONFIG_DEVFS_FS enabled. Setting
777 this to 'Y' will make the kernel automatically mount devfs onto /dev
778 when the system is booted, before the init thread is started.
779 You can override this with the "devfs=nomount" boot option.
780
781 If unsure, say N.
782
783config DEVFS_DEBUG
784 bool "Debug devfs"
785 depends on DEVFS_FS
786 help
787 If you say Y here, then the /dev file system code will generate
788 debugging messages. See the file
789 <file:Documentation/filesystems/devfs/boot-options> for more
790 details.
791
792 If unsure, say N.
793
794config DEVPTS_FS_XATTR 744config DEVPTS_FS_XATTR
795 bool "/dev/pts Extended Attributes" 745 bool "/dev/pts Extended Attributes"
796 depends on UNIX98_PTYS 746 depends on UNIX98_PTYS
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index c7b2b8890188..9c09641ce907 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -185,6 +185,19 @@ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify);
185int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int); 185int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
186void autofs4_catatonic_mode(struct autofs_sb_info *); 186void autofs4_catatonic_mode(struct autofs_sb_info *);
187 187
188static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry)
189{
190 int res = 0;
191
192 while (d_mountpoint(*dentry)) {
193 int followed = follow_down(mnt, dentry);
194 if (!followed)
195 break;
196 res = 1;
197 }
198 return res;
199}
200
188static inline int simple_positive(struct dentry *dentry) 201static inline int simple_positive(struct dentry *dentry)
189{ 202{
190 return dentry->d_inode && !d_unhashed(dentry); 203 return dentry->d_inode && !d_unhashed(dentry);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 500425e24fba..feb6ac427d05 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -56,12 +56,9 @@ static int autofs4_check_mount(struct vfsmount *mnt, struct dentry *dentry)
56 mntget(mnt); 56 mntget(mnt);
57 dget(dentry); 57 dget(dentry);
58 58
59 if (!follow_down(&mnt, &dentry)) 59 if (!autofs4_follow_mount(&mnt, &dentry))
60 goto done; 60 goto done;
61 61
62 while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
63 ;
64
65 /* This is an autofs submount, we can't expire it */ 62 /* This is an autofs submount, we can't expire it */
66 if (is_autofs4_dentry(dentry)) 63 if (is_autofs4_dentry(dentry))
67 goto done; 64 goto done;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 3765c047f157..2a771ec66956 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -205,7 +205,11 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
205 struct vfsmount *fp_mnt = mntget(mnt); 205 struct vfsmount *fp_mnt = mntget(mnt);
206 struct dentry *fp_dentry = dget(dentry); 206 struct dentry *fp_dentry = dget(dentry);
207 207
208 while (follow_down(&fp_mnt, &fp_dentry) && d_mountpoint(fp_dentry)); 208 if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) {
209 dput(fp_dentry);
210 mntput(fp_mnt);
211 return -ENOENT;
212 }
209 213
210 fp = dentry_open(fp_dentry, fp_mnt, file->f_flags); 214 fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
211 status = PTR_ERR(fp); 215 status = PTR_ERR(fp);
@@ -302,7 +306,14 @@ static int try_to_fill_dentry(struct dentry *dentry,
302 306
303 DPRINTK("expire done status=%d", status); 307 DPRINTK("expire done status=%d", status);
304 308
305 return 0; 309 /*
310 * If the directory still exists the mount request must
311 * continue otherwise it can't be followed at the right
312 * time during the walk.
313 */
314 status = d_invalidate(dentry);
315 if (status != -EBUSY)
316 return 0;
306 } 317 }
307 318
308 DPRINTK("dentry=%p %.*s ino=%p", 319 DPRINTK("dentry=%p %.*s ino=%p",
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 5a40d36e5a51..fa2348dcd671 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -191,6 +191,13 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
191 } 191 }
192 192
193 if ( !wq ) { 193 if ( !wq ) {
194 /* Can't wait for an expire if there's no mount */
195 if (notify == NFY_NONE && !d_mountpoint(dentry)) {
196 kfree(name);
197 up(&sbi->wq_sem);
198 return -ENOENT;
199 }
200
194 /* Create a new wait queue */ 201 /* Create a new wait queue */
195 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL); 202 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
196 if ( !wq ) { 203 if ( !wq ) {
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 009b8920c1ff..dd9baabaf016 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -316,6 +316,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
316 current->mm->brk = ex.a_bss + 316 current->mm->brk = ex.a_bss +
317 (current->mm->start_brk = N_BSSADDR(ex)); 317 (current->mm->start_brk = N_BSSADDR(ex));
318 current->mm->free_area_cache = current->mm->mmap_base; 318 current->mm->free_area_cache = current->mm->mmap_base;
319 current->mm->cached_hole_size = 0;
319 320
320 set_mm_counter(current->mm, rss, 0); 321 set_mm_counter(current->mm, rss, 0);
321 current->mm->mmap = NULL; 322 current->mm->mmap = NULL;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index c374be51b041..7976a238f0a3 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -775,6 +775,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
775 change some of these later */ 775 change some of these later */
776 set_mm_counter(current->mm, rss, 0); 776 set_mm_counter(current->mm, rss, 0);
777 current->mm->free_area_cache = current->mm->mmap_base; 777 current->mm->free_area_cache = current->mm->mmap_base;
778 current->mm->cached_hole_size = 0;
778 retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP), 779 retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
779 executable_stack); 780 executable_stack);
780 if (retval < 0) { 781 if (retval < 0) {
@@ -1125,7 +1126,7 @@ static int dump_write(struct file *file, const void *addr, int nr)
1125 return file->f_op->write(file, addr, nr, &file->f_pos) == nr; 1126 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1126} 1127}
1127 1128
1128static int dump_seek(struct file *file, off_t off) 1129static int dump_seek(struct file *file, loff_t off)
1129{ 1130{
1130 if (file->f_op->llseek) { 1131 if (file->f_op->llseek) {
1131 if (file->f_op->llseek(file, off, 0) != off) 1132 if (file->f_op->llseek(file, off, 0) != off)
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index f0cd67d9d31b..c8998dc66882 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -520,7 +520,7 @@ static int load_flat_file(struct linux_binprm * bprm,
520 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); 520 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
521 521
522 down_write(&current->mm->mmap_sem); 522 down_write(&current->mm->mmap_sem);
523 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0); 523 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0);
524 up_write(&current->mm->mmap_sem); 524 up_write(&current->mm->mmap_sem);
525 if (!textpos || textpos >= (unsigned long) -4096) { 525 if (!textpos || textpos >= (unsigned long) -4096) {
526 if (!textpos) 526 if (!textpos)
@@ -532,7 +532,7 @@ static int load_flat_file(struct linux_binprm * bprm,
532 down_write(&current->mm->mmap_sem); 532 down_write(&current->mm->mmap_sem);
533 realdatastart = do_mmap(0, 0, data_len + extra + 533 realdatastart = do_mmap(0, 0, data_len + extra +
534 MAX_SHARED_LIBS * sizeof(unsigned long), 534 MAX_SHARED_LIBS * sizeof(unsigned long),
535 PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0); 535 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
536 up_write(&current->mm->mmap_sem); 536 up_write(&current->mm->mmap_sem);
537 537
538 if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { 538 if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm * bprm,
574 down_write(&current->mm->mmap_sem); 574 down_write(&current->mm->mmap_sem);
575 textpos = do_mmap(0, 0, text_len + data_len + extra + 575 textpos = do_mmap(0, 0, text_len + data_len + extra +
576 MAX_SHARED_LIBS * sizeof(unsigned long), 576 MAX_SHARED_LIBS * sizeof(unsigned long),
577 PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0); 577 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
578 up_write(&current->mm->mmap_sem); 578 up_write(&current->mm->mmap_sem);
579 if (!textpos || textpos >= (unsigned long) -4096) { 579 if (!textpos || textpos >= (unsigned long) -4096) {
580 if (!textpos) 580 if (!textpos)
diff --git a/fs/buffer.c b/fs/buffer.c
index 7e9e409feaa7..0befa724ab98 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -528,7 +528,7 @@ static void free_more_memory(void)
528 for_each_pgdat(pgdat) { 528 for_each_pgdat(pgdat) {
529 zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones; 529 zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones;
530 if (*zones) 530 if (*zones)
531 try_to_free_pages(zones, GFP_NOFS, 0); 531 try_to_free_pages(zones, GFP_NOFS);
532 } 532 }
533} 533}
534 534
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 95483baab706..dab4774ee7bb 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -6,7 +6,8 @@ kills the cifsd thread (NB: killing the cifs kernel threads is not
6recommended, unmount and rmmod cifs will kill them when they are 6recommended, unmount and rmmod cifs will kill them when they are
7no longer needed). Fix readdir to ASCII servers (ie older servers 7no longer needed). Fix readdir to ASCII servers (ie older servers
8which do not support Unicode) and also require asterik. 8which do not support Unicode) and also require asterik.
9 9Fix out of memory case in which data could be written one page
10off in the page cache.
10 11
11Version 1.33 12Version 1.33
12------------ 13------------
diff --git a/fs/cifs/README b/fs/cifs/README
index e74df0c73256..34b0cf7111f3 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -371,7 +371,7 @@ A partial list of the supported mount options follows:
371 on newly created files, directories, and devices (create, 371 on newly created files, directories, and devices (create,
372 mkdir, mknod) which will result in the server setting the 372 mkdir, mknod) which will result in the server setting the
373 uid and gid to the default (usually the server uid of the 373 uid and gid to the default (usually the server uid of the
374 usern who mounted the share). Letting the server (rather than 374 user who mounted the share). Letting the server (rather than
375 the client) set the uid and gid is the default. This 375 the client) set the uid and gid is the default. This
376 parameter has no effect if the CIFS Unix Extensions are not 376 parameter has no effect if the CIFS Unix Extensions are not
377 negotiated. 377 negotiated.
@@ -384,7 +384,7 @@ A partial list of the supported mount options follows:
384 client (e.g. when the application is doing large sequential 384 client (e.g. when the application is doing large sequential
385 reads bigger than page size without rereading the same data) 385 reads bigger than page size without rereading the same data)
386 this can provide better performance than the default 386 this can provide better performance than the default
387 behavior which caches reads (reaadahead) and writes 387 behavior which caches reads (readahead) and writes
388 (writebehind) through the local Linux client pagecache 388 (writebehind) through the local Linux client pagecache
389 if oplock (caching token) is granted and held. Note that 389 if oplock (caching token) is granted and held. Note that
390 direct allows write operations larger than page size 390 direct allows write operations larger than page size
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index d00b3bfe1a52..78af5850c558 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -96,5 +96,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
96extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 96extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
97extern int cifs_ioctl (struct inode * inode, struct file * filep, 97extern int cifs_ioctl (struct inode * inode, struct file * filep,
98 unsigned int command, unsigned long arg); 98 unsigned int command, unsigned long arg);
99#define CIFS_VERSION "1.34" 99#define CIFS_VERSION "1.35"
100#endif /* _CIFSFS_H */ 100#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 0010511083fc..ea239dea571e 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -228,7 +228,7 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
228 const struct nls_table *nls_codepage, 228 const struct nls_table *nls_codepage,
229 int remap_special_chars); 229 int remap_special_chars);
230#endif /* CONFIG_CIFS_EXPERIMENTAL */ 230#endif /* CONFIG_CIFS_EXPERIMENTAL */
231extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen, 231extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen,
232 const struct nls_table * codepage); 232 const struct nls_table * codepage);
233extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, 233extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
234 const struct nls_table * cp, int mapChars); 234 const struct nls_table * cp, int mapChars);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 741ff0c69f37..3c628bf667a5 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -567,7 +567,7 @@ DelFileRetry:
567 567
568 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 568 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
569 name_len = 569 name_len =
570 cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, 570 cifsConvertToUCS((__le16 *) pSMB->fileName, fileName,
571 PATH_MAX, nls_codepage, remap); 571 PATH_MAX, nls_codepage, remap);
572 name_len++; /* trailing null */ 572 name_len++; /* trailing null */
573 name_len *= 2; 573 name_len *= 2;
@@ -665,7 +665,7 @@ MkDirRetry:
665 return rc; 665 return rc;
666 666
667 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 667 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
668 name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, 668 name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name,
669 PATH_MAX, nls_codepage, remap); 669 PATH_MAX, nls_codepage, remap);
670 name_len++; /* trailing null */ 670 name_len++; /* trailing null */
671 name_len *= 2; 671 name_len *= 2;
@@ -719,7 +719,7 @@ openRetry:
719 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 719 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
720 count = 1; /* account for one byte pad to word boundary */ 720 count = 1; /* account for one byte pad to word boundary */
721 name_len = 721 name_len =
722 cifsConvertToUCS((__u16 *) (pSMB->fileName + 1), 722 cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
723 fileName, PATH_MAX, nls_codepage, remap); 723 fileName, PATH_MAX, nls_codepage, remap);
724 name_len++; /* trailing null */ 724 name_len++; /* trailing null */
725 name_len *= 2; 725 name_len *= 2;
@@ -1141,7 +1141,7 @@ renameRetry:
1141 1141
1142 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1142 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1143 name_len = 1143 name_len =
1144 cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, 1144 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
1145 PATH_MAX, nls_codepage, remap); 1145 PATH_MAX, nls_codepage, remap);
1146 name_len++; /* trailing null */ 1146 name_len++; /* trailing null */
1147 name_len *= 2; 1147 name_len *= 2;
@@ -1149,7 +1149,7 @@ renameRetry:
1149 /* protocol requires ASCII signature byte on Unicode string */ 1149 /* protocol requires ASCII signature byte on Unicode string */
1150 pSMB->OldFileName[name_len + 1] = 0x00; 1150 pSMB->OldFileName[name_len + 1] = 0x00;
1151 name_len2 = 1151 name_len2 =
1152 cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2], 1152 cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2],
1153 toName, PATH_MAX, nls_codepage, remap); 1153 toName, PATH_MAX, nls_codepage, remap);
1154 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 1154 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1155 name_len2 *= 2; /* convert to bytes */ 1155 name_len2 *= 2; /* convert to bytes */
@@ -1236,10 +1236,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1236 /* unicode only call */ 1236 /* unicode only call */
1237 if(target_name == NULL) { 1237 if(target_name == NULL) {
1238 sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); 1238 sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
1239 len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, 1239 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
1240 dummy_string, 24, nls_codepage, remap); 1240 dummy_string, 24, nls_codepage, remap);
1241 } else { 1241 } else {
1242 len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, 1242 len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name,
1243 target_name, PATH_MAX, nls_codepage, remap); 1243 target_name, PATH_MAX, nls_codepage, remap);
1244 } 1244 }
1245 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 1245 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
@@ -1296,7 +1296,7 @@ copyRetry:
1296 pSMB->Flags = cpu_to_le16(flags & COPY_TREE); 1296 pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
1297 1297
1298 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1298 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1299 name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, 1299 name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName,
1300 fromName, PATH_MAX, nls_codepage, 1300 fromName, PATH_MAX, nls_codepage,
1301 remap); 1301 remap);
1302 name_len++; /* trailing null */ 1302 name_len++; /* trailing null */
@@ -1304,7 +1304,7 @@ copyRetry:
1304 pSMB->OldFileName[name_len] = 0x04; /* pad */ 1304 pSMB->OldFileName[name_len] = 0x04; /* pad */
1305 /* protocol requires ASCII signature byte on Unicode string */ 1305 /* protocol requires ASCII signature byte on Unicode string */
1306 pSMB->OldFileName[name_len + 1] = 0x00; 1306 pSMB->OldFileName[name_len + 1] = 0x00;
1307 name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 1307 name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
1308 toName, PATH_MAX, nls_codepage, remap); 1308 toName, PATH_MAX, nls_codepage, remap);
1309 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 1309 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1310 name_len2 *= 2; /* convert to bytes */ 1310 name_len2 *= 2; /* convert to bytes */
@@ -1453,7 +1453,7 @@ createHardLinkRetry:
1453 return rc; 1453 return rc;
1454 1454
1455 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1455 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1456 name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName, 1456 name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName,
1457 PATH_MAX, nls_codepage, remap); 1457 PATH_MAX, nls_codepage, remap);
1458 name_len++; /* trailing null */ 1458 name_len++; /* trailing null */
1459 name_len *= 2; 1459 name_len *= 2;
@@ -1476,7 +1476,7 @@ createHardLinkRetry:
1476 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 1476 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
1477 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1477 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1478 name_len_target = 1478 name_len_target =
1479 cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX, 1479 cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX,
1480 nls_codepage, remap); 1480 nls_codepage, remap);
1481 name_len_target++; /* trailing null */ 1481 name_len_target++; /* trailing null */
1482 name_len_target *= 2; 1482 name_len_target *= 2;
@@ -1546,14 +1546,14 @@ winCreateHardLinkRetry:
1546 1546
1547 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1547 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1548 name_len = 1548 name_len =
1549 cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, 1549 cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName,
1550 PATH_MAX, nls_codepage, remap); 1550 PATH_MAX, nls_codepage, remap);
1551 name_len++; /* trailing null */ 1551 name_len++; /* trailing null */
1552 name_len *= 2; 1552 name_len *= 2;
1553 pSMB->OldFileName[name_len] = 0; /* pad */ 1553 pSMB->OldFileName[name_len] = 0; /* pad */
1554 pSMB->OldFileName[name_len + 1] = 0x04; 1554 pSMB->OldFileName[name_len + 1] = 0x04;
1555 name_len2 = 1555 name_len2 =
1556 cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], 1556 cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2],
1557 toName, PATH_MAX, nls_codepage, remap); 1557 toName, PATH_MAX, nls_codepage, remap);
1558 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 1558 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1559 name_len2 *= 2; /* convert to bytes */ 1559 name_len2 *= 2; /* convert to bytes */
@@ -1939,7 +1939,7 @@ queryAclRetry:
1939 1939
1940 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1940 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1941 name_len = 1941 name_len =
1942 cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 1942 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
1943 PATH_MAX, nls_codepage, remap); 1943 PATH_MAX, nls_codepage, remap);
1944 name_len++; /* trailing null */ 1944 name_len++; /* trailing null */
1945 name_len *= 2; 1945 name_len *= 2;
@@ -2024,7 +2024,7 @@ setAclRetry:
2024 return rc; 2024 return rc;
2025 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2025 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2026 name_len = 2026 name_len =
2027 cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 2027 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
2028 PATH_MAX, nls_codepage, remap); 2028 PATH_MAX, nls_codepage, remap);
2029 name_len++; /* trailing null */ 2029 name_len++; /* trailing null */
2030 name_len *= 2; 2030 name_len *= 2;
@@ -2188,7 +2188,7 @@ QPathInfoRetry:
2188 2188
2189 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2189 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2190 name_len = 2190 name_len =
2191 cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 2191 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2192 PATH_MAX, nls_codepage, remap); 2192 PATH_MAX, nls_codepage, remap);
2193 name_len++; /* trailing null */ 2193 name_len++; /* trailing null */
2194 name_len *= 2; 2194 name_len *= 2;
@@ -2269,7 +2269,7 @@ UnixQPathInfoRetry:
2269 2269
2270 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2270 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2271 name_len = 2271 name_len =
2272 cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 2272 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2273 PATH_MAX, nls_codepage, remap); 2273 PATH_MAX, nls_codepage, remap);
2274 name_len++; /* trailing null */ 2274 name_len++; /* trailing null */
2275 name_len *= 2; 2275 name_len *= 2;
@@ -2350,7 +2350,7 @@ findUniqueRetry:
2350 2350
2351 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2351 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2352 name_len = 2352 name_len =
2353 cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX 2353 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
2354 /* find define for this maxpathcomponent */ 2354 /* find define for this maxpathcomponent */
2355 , nls_codepage); 2355 , nls_codepage);
2356 name_len++; /* trailing null */ 2356 name_len++; /* trailing null */
@@ -2435,7 +2435,7 @@ findFirstRetry:
2435 2435
2436 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2436 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2437 name_len = 2437 name_len =
2438 cifsConvertToUCS((__u16 *) pSMB->FileName,searchName, 2438 cifsConvertToUCS((__le16 *) pSMB->FileName,searchName,
2439 PATH_MAX, nls_codepage, remap); 2439 PATH_MAX, nls_codepage, remap);
2440 /* We can not add the asterik earlier in case 2440 /* We can not add the asterik earlier in case
2441 it got remapped to 0xF03A as if it were part of the 2441 it got remapped to 0xF03A as if it were part of the
@@ -2726,7 +2726,7 @@ GetInodeNumberRetry:
2726 2726
2727 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2727 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2728 name_len = 2728 name_len =
2729 cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 2729 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2730 PATH_MAX,nls_codepage, remap); 2730 PATH_MAX,nls_codepage, remap);
2731 name_len++; /* trailing null */ 2731 name_len++; /* trailing null */
2732 name_len *= 2; 2732 name_len *= 2;
@@ -2837,7 +2837,7 @@ getDFSRetry:
2837 if (ses->capabilities & CAP_UNICODE) { 2837 if (ses->capabilities & CAP_UNICODE) {
2838 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 2838 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
2839 name_len = 2839 name_len =
2840 cifsConvertToUCS((__u16 *) pSMB->RequestFileName, 2840 cifsConvertToUCS((__le16 *) pSMB->RequestFileName,
2841 searchName, PATH_MAX, nls_codepage, remap); 2841 searchName, PATH_MAX, nls_codepage, remap);
2842 name_len++; /* trailing null */ 2842 name_len++; /* trailing null */
2843 name_len *= 2; 2843 name_len *= 2;
@@ -3369,7 +3369,7 @@ SetEOFRetry:
3369 3369
3370 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3370 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3371 name_len = 3371 name_len =
3372 cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 3372 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
3373 PATH_MAX, nls_codepage, remap); 3373 PATH_MAX, nls_codepage, remap);
3374 name_len++; /* trailing null */ 3374 name_len++; /* trailing null */
3375 name_len *= 2; 3375 name_len *= 2;
@@ -3627,7 +3627,7 @@ SetTimesRetry:
3627 3627
3628 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3628 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3629 name_len = 3629 name_len =
3630 cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 3630 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
3631 PATH_MAX, nls_codepage, remap); 3631 PATH_MAX, nls_codepage, remap);
3632 name_len++; /* trailing null */ 3632 name_len++; /* trailing null */
3633 name_len *= 2; 3633 name_len *= 2;
@@ -3708,7 +3708,7 @@ SetAttrLgcyRetry:
3708 3708
3709 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3709 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3710 name_len = 3710 name_len =
3711 ConvertToUCS((wchar_t *) pSMB->fileName, fileName, 3711 ConvertToUCS((__le16 *) pSMB->fileName, fileName,
3712 PATH_MAX, nls_codepage); 3712 PATH_MAX, nls_codepage);
3713 name_len++; /* trailing null */ 3713 name_len++; /* trailing null */
3714 name_len *= 2; 3714 name_len *= 2;
@@ -3759,7 +3759,7 @@ setPermsRetry:
3759 3759
3760 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3760 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3761 name_len = 3761 name_len =
3762 cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 3762 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
3763 PATH_MAX, nls_codepage, remap); 3763 PATH_MAX, nls_codepage, remap);
3764 name_len++; /* trailing null */ 3764 name_len++; /* trailing null */
3765 name_len *= 2; 3765 name_len *= 2;
@@ -3904,7 +3904,7 @@ QAllEAsRetry:
3904 3904
3905 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3905 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
3906 name_len = 3906 name_len =
3907 cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, 3907 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
3908 PATH_MAX, nls_codepage, remap); 3908 PATH_MAX, nls_codepage, remap);
3909 name_len++; /* trailing null */ 3909 name_len++; /* trailing null */
3910 name_len *= 2; 3910 name_len *= 2;
@@ -4047,7 +4047,7 @@ QEARetry:
4047 4047
4048 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4048 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4049 name_len = 4049 name_len =
4050 cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, 4050 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
4051 PATH_MAX, nls_codepage, remap); 4051 PATH_MAX, nls_codepage, remap);
4052 name_len++; /* trailing null */ 4052 name_len++; /* trailing null */
4053 name_len *= 2; 4053 name_len *= 2;
@@ -4194,7 +4194,7 @@ SetEARetry:
4194 4194
4195 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4195 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4196 name_len = 4196 name_len =
4197 cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, 4197 cifsConvertToUCS((__le16 *) pSMB->FileName, fileName,
4198 PATH_MAX, nls_codepage, remap); 4198 PATH_MAX, nls_codepage, remap);
4199 name_len++; /* trailing null */ 4199 name_len++; /* trailing null */
4200 name_len *= 2; 4200 name_len *= 2;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index e3137aa48cdd..3f3538d4a1fa 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -392,7 +392,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
392 rc = 0; 392 rc = 0;
393 d_add(direntry, NULL); 393 d_add(direntry, NULL);
394 } else { 394 } else {
395 cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc)); 395 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
396 rc,full_path));
396 /* BB special case check for Access Denied - watch security 397 /* BB special case check for Access Denied - watch security
397 exposure of returning dir info implicitly via different rc 398 exposure of returning dir info implicitly via different rc
398 if file exists or not but no access BB */ 399 if file exists or not but no access BB */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index dde2d251fc3d..30ab70ce5547 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1352,6 +1352,8 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
1352 GFP_KERNEL)) { 1352 GFP_KERNEL)) {
1353 page_cache_release(page); 1353 page_cache_release(page);
1354 cFYI(1, ("Add page cache failed")); 1354 cFYI(1, ("Add page cache failed"));
1355 data += PAGE_CACHE_SIZE;
1356 bytes_read -= PAGE_CACHE_SIZE;
1355 continue; 1357 continue;
1356 } 1358 }
1357 1359
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 670947288262..8d336a900255 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -82,12 +82,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,
82 /* get new inode */ 82 /* get new inode */
83 if (*pinode == NULL) { 83 if (*pinode == NULL) {
84 *pinode = new_inode(sb); 84 *pinode = new_inode(sb);
85 if(*pinode == NULL) 85 if (*pinode == NULL)
86 return -ENOMEM; 86 return -ENOMEM;
87 /* Is an i_ino of zero legal? */ 87 /* Is an i_ino of zero legal? */
88 /* Are there sanity checks we can use to ensure that 88 /* Are there sanity checks we can use to ensure that
89 the server is really filling in that field? */ 89 the server is really filling in that field? */
90 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 90 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
91 (*pinode)->i_ino = 91 (*pinode)->i_ino =
92 (unsigned long)findData.UniqueId; 92 (unsigned long)findData.UniqueId;
93 } /* note ino incremented to unique num in new_inode */ 93 } /* note ino incremented to unique num in new_inode */
@@ -134,7 +134,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
134 inode->i_gid = le64_to_cpu(findData.Gid); 134 inode->i_gid = le64_to_cpu(findData.Gid);
135 inode->i_nlink = le64_to_cpu(findData.Nlinks); 135 inode->i_nlink = le64_to_cpu(findData.Nlinks);
136 136
137 if(is_size_safe_to_change(cifsInfo)) { 137 if (is_size_safe_to_change(cifsInfo)) {
138 /* can not safely change the file size here if the 138 /* can not safely change the file size here if the
139 client is writing to it due to potential races */ 139 client is writing to it due to potential races */
140 140
@@ -162,7 +162,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
162 if (S_ISREG(inode->i_mode)) { 162 if (S_ISREG(inode->i_mode)) {
163 cFYI(1, (" File inode ")); 163 cFYI(1, (" File inode "));
164 inode->i_op = &cifs_file_inode_ops; 164 inode->i_op = &cifs_file_inode_ops;
165 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 165 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
166 inode->i_fop = &cifs_file_direct_ops; 166 inode->i_fop = &cifs_file_direct_ops;
167 else 167 else
168 inode->i_fop = &cifs_file_ops; 168 inode->i_fop = &cifs_file_ops;
@@ -198,17 +198,17 @@ int cifs_get_inode_info(struct inode **pinode,
198 pTcon = cifs_sb->tcon; 198 pTcon = cifs_sb->tcon;
199 cFYI(1,("Getting info on %s ", search_path)); 199 cFYI(1,("Getting info on %s ", search_path));
200 200
201 if((pfindData == NULL) && (*pinode != NULL)) { 201 if ((pfindData == NULL) && (*pinode != NULL)) {
202 if(CIFS_I(*pinode)->clientCanCacheRead) { 202 if (CIFS_I(*pinode)->clientCanCacheRead) {
203 cFYI(1,("No need to revalidate cached inode sizes")); 203 cFYI(1,("No need to revalidate cached inode sizes"));
204 return rc; 204 return rc;
205 } 205 }
206 } 206 }
207 207
208 /* if file info not passed in then get it from server */ 208 /* if file info not passed in then get it from server */
209 if(pfindData == NULL) { 209 if (pfindData == NULL) {
210 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 210 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
211 if(buf == NULL) 211 if (buf == NULL)
212 return -ENOMEM; 212 return -ENOMEM;
213 pfindData = (FILE_ALL_INFO *)buf; 213 pfindData = (FILE_ALL_INFO *)buf;
214 /* could do find first instead but this returns more info */ 214 /* could do find first instead but this returns more info */
@@ -268,7 +268,7 @@ int cifs_get_inode_info(struct inode **pinode,
268 IndexNumber field is not guaranteed unique? */ 268 IndexNumber field is not guaranteed unique? */
269 269
270#ifdef CONFIG_CIFS_EXPERIMENTAL 270#ifdef CONFIG_CIFS_EXPERIMENTAL
271 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ 271 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
272 int rc1 = 0; 272 int rc1 = 0;
273 __u64 inode_num; 273 __u64 inode_num;
274 274
@@ -277,7 +277,7 @@ int cifs_get_inode_info(struct inode **pinode,
277 cifs_sb->local_nls, 277 cifs_sb->local_nls,
278 cifs_sb->mnt_cifs_flags & 278 cifs_sb->mnt_cifs_flags &
279 CIFS_MOUNT_MAP_SPECIAL_CHR); 279 CIFS_MOUNT_MAP_SPECIAL_CHR);
280 if(rc1) { 280 if (rc1) {
281 cFYI(1,("GetSrvInodeNum rc %d", rc1)); 281 cFYI(1,("GetSrvInodeNum rc %d", rc1));
282 /* BB EOPNOSUPP disable SERVER_INUM? */ 282 /* BB EOPNOSUPP disable SERVER_INUM? */
283 } else /* do we need cast or hash to ino? */ 283 } else /* do we need cast or hash to ino? */
@@ -355,7 +355,7 @@ int cifs_get_inode_info(struct inode **pinode,
355 if (S_ISREG(inode->i_mode)) { 355 if (S_ISREG(inode->i_mode)) {
356 cFYI(1, (" File inode ")); 356 cFYI(1, (" File inode "));
357 inode->i_op = &cifs_file_inode_ops; 357 inode->i_op = &cifs_file_inode_ops;
358 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 358 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
359 inode->i_fop = &cifs_file_direct_ops; 359 inode->i_fop = &cifs_file_direct_ops;
360 else 360 else
361 inode->i_fop = &cifs_file_ops; 361 inode->i_fop = &cifs_file_ops;
@@ -422,7 +422,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
422 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 422 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
423 423
424 if (!rc) { 424 if (!rc) {
425 direntry->d_inode->i_nlink--; 425 if (direntry->d_inode)
426 direntry->d_inode->i_nlink--;
426 } else if (rc == -ENOENT) { 427 } else if (rc == -ENOENT) {
427 d_drop(direntry); 428 d_drop(direntry);
428 } else if (rc == -ETXTBSY) { 429 } else if (rc == -ETXTBSY) {
@@ -440,7 +441,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
440 cifs_sb->mnt_cifs_flags & 441 cifs_sb->mnt_cifs_flags &
441 CIFS_MOUNT_MAP_SPECIAL_CHR); 442 CIFS_MOUNT_MAP_SPECIAL_CHR);
442 CIFSSMBClose(xid, pTcon, netfid); 443 CIFSSMBClose(xid, pTcon, netfid);
443 direntry->d_inode->i_nlink--; 444 if (direntry->d_inode)
445 direntry->d_inode->i_nlink--;
444 } 446 }
445 } else if (rc == -EACCES) { 447 } else if (rc == -EACCES) {
446 /* try only if r/o attribute set in local lookup data? */ 448 /* try only if r/o attribute set in local lookup data? */
@@ -494,7 +496,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
494 cifs_sb->mnt_cifs_flags & 496 cifs_sb->mnt_cifs_flags &
495 CIFS_MOUNT_MAP_SPECIAL_CHR); 497 CIFS_MOUNT_MAP_SPECIAL_CHR);
496 if (!rc) { 498 if (!rc) {
497 direntry->d_inode->i_nlink--; 499 if (direntry->d_inode)
500 direntry->d_inode->i_nlink--;
498 } else if (rc == -ETXTBSY) { 501 } else if (rc == -ETXTBSY) {
499 int oplock = FALSE; 502 int oplock = FALSE;
500 __u16 netfid; 503 __u16 netfid;
@@ -514,17 +517,20 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
514 cifs_sb->mnt_cifs_flags & 517 cifs_sb->mnt_cifs_flags &
515 CIFS_MOUNT_MAP_SPECIAL_CHR); 518 CIFS_MOUNT_MAP_SPECIAL_CHR);
516 CIFSSMBClose(xid, pTcon, netfid); 519 CIFSSMBClose(xid, pTcon, netfid);
517 direntry->d_inode->i_nlink--; 520 if (direntry->d_inode)
521 direntry->d_inode->i_nlink--;
518 } 522 }
519 /* BB if rc = -ETXTBUSY goto the rename logic BB */ 523 /* BB if rc = -ETXTBUSY goto the rename logic BB */
520 } 524 }
521 } 525 }
522 } 526 }
523 cifsInode = CIFS_I(direntry->d_inode); 527 if (direntry->d_inode) {
524 cifsInode->time = 0; /* will force revalidate to get info when 528 cifsInode = CIFS_I(direntry->d_inode);
525 needed */ 529 cifsInode->time = 0; /* will force revalidate to get info
526 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = 530 when needed */
527 current_fs_time(inode->i_sb); 531 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
532 }
533 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
528 cifsInode = CIFS_I(inode); 534 cifsInode = CIFS_I(inode);
529 cifsInode->time = 0; /* force revalidate of dir as well */ 535 cifsInode->time = 0; /* force revalidate of dir as well */
530 536
@@ -576,7 +582,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
576 if (direntry->d_inode) 582 if (direntry->d_inode)
577 direntry->d_inode->i_nlink = 2; 583 direntry->d_inode->i_nlink = 2;
578 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 584 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
579 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 585 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
580 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 586 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
581 mode, 587 mode,
582 (__u64)current->euid, 588 (__u64)current->euid,
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index db14b503d89e..072b4ee8c53e 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -571,6 +571,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen,
571 break; 571 break;
572 case UNI_LESSTHAN: 572 case UNI_LESSTHAN:
573 target[j] = '<'; 573 target[j] = '<';
574 break;
574 default: 575 default:
575 len = cp->uni2char(src_char, &target[j], 576 len = cp->uni2char(src_char, &target[j],
576 NLS_MAX_CHARSET_SIZE); 577 NLS_MAX_CHARSET_SIZE);
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index ef001a9313e6..3d1cce3653b8 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -61,7 +61,7 @@ unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */
61 61
62 62
63struct venus_comm coda_comms[MAX_CODADEVS]; 63struct venus_comm coda_comms[MAX_CODADEVS];
64static struct class_simple *coda_psdev_class; 64static struct class *coda_psdev_class;
65 65
66/* 66/*
67 * Device operations 67 * Device operations
@@ -363,14 +363,14 @@ static int init_coda_psdev(void)
363 CODA_PSDEV_MAJOR); 363 CODA_PSDEV_MAJOR);
364 return -EIO; 364 return -EIO;
365 } 365 }
366 coda_psdev_class = class_simple_create(THIS_MODULE, "coda"); 366 coda_psdev_class = class_create(THIS_MODULE, "coda");
367 if (IS_ERR(coda_psdev_class)) { 367 if (IS_ERR(coda_psdev_class)) {
368 err = PTR_ERR(coda_psdev_class); 368 err = PTR_ERR(coda_psdev_class);
369 goto out_chrdev; 369 goto out_chrdev;
370 } 370 }
371 devfs_mk_dir ("coda"); 371 devfs_mk_dir ("coda");
372 for (i = 0; i < MAX_CODADEVS; i++) { 372 for (i = 0; i < MAX_CODADEVS; i++) {
373 class_simple_device_add(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i), 373 class_device_create(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i),
374 NULL, "cfs%d", i); 374 NULL, "cfs%d", i);
375 err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i), 375 err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
376 S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i); 376 S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
@@ -382,8 +382,8 @@ static int init_coda_psdev(void)
382 382
383out_class: 383out_class:
384 for (i = 0; i < MAX_CODADEVS; i++) 384 for (i = 0; i < MAX_CODADEVS; i++)
385 class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i)); 385 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
386 class_simple_destroy(coda_psdev_class); 386 class_destroy(coda_psdev_class);
387out_chrdev: 387out_chrdev:
388 unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); 388 unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
389out: 389out:
@@ -425,10 +425,10 @@ static int __init init_coda(void)
425 return 0; 425 return 0;
426out: 426out:
427 for (i = 0; i < MAX_CODADEVS; i++) { 427 for (i = 0; i < MAX_CODADEVS; i++) {
428 class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i)); 428 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
429 devfs_remove("coda/%d", i); 429 devfs_remove("coda/%d", i);
430 } 430 }
431 class_simple_destroy(coda_psdev_class); 431 class_destroy(coda_psdev_class);
432 devfs_remove("coda"); 432 devfs_remove("coda");
433 unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); 433 unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
434 coda_sysctl_clean(); 434 coda_sysctl_clean();
@@ -447,10 +447,10 @@ static void __exit exit_coda(void)
447 printk("coda: failed to unregister filesystem\n"); 447 printk("coda: failed to unregister filesystem\n");
448 } 448 }
449 for (i = 0; i < MAX_CODADEVS; i++) { 449 for (i = 0; i < MAX_CODADEVS; i++) {
450 class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i)); 450 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
451 devfs_remove("coda/%d", i); 451 devfs_remove("coda/%d", i);
452 } 452 }
453 class_simple_destroy(coda_psdev_class); 453 class_destroy(coda_psdev_class);
454 devfs_remove("coda"); 454 devfs_remove("coda");
455 unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); 455 unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
456 coda_sysctl_clean(); 456 coda_sysctl_clean();
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 548556ff2506..efc97d9b7860 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -45,44 +45,15 @@ struct file_operations debugfs_file_operations = {
45 .open = default_open, 45 .open = default_open,
46}; 46};
47 47
48#define simple_type(type, format, temptype, strtolfn) \ 48static void debugfs_u8_set(void *data, u64 val)
49static ssize_t read_file_##type(struct file *file, char __user *user_buf, \ 49{
50 size_t count, loff_t *ppos) \ 50 *(u8 *)data = val;
51{ \ 51}
52 char buf[32]; \ 52static u64 debugfs_u8_get(void *data)
53 type *val = file->private_data; \ 53{
54 \ 54 return *(u8 *)data;
55 snprintf(buf, sizeof(buf), format "\n", *val); \ 55}
56 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));\ 56DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
57} \
58static ssize_t write_file_##type(struct file *file, const char __user *user_buf,\
59 size_t count, loff_t *ppos) \
60{ \
61 char *endp; \
62 char buf[32]; \
63 int buf_size; \
64 type *val = file->private_data; \
65 temptype tmp; \
66 \
67 memset(buf, 0x00, sizeof(buf)); \
68 buf_size = min(count, (sizeof(buf)-1)); \
69 if (copy_from_user(buf, user_buf, buf_size)) \
70 return -EFAULT; \
71 \
72 tmp = strtolfn(buf, &endp, 0); \
73 if ((endp == buf) || ((type)tmp != tmp)) \
74 return -EINVAL; \
75 *val = tmp; \
76 return count; \
77} \
78static struct file_operations fops_##type = { \
79 .read = read_file_##type, \
80 .write = write_file_##type, \
81 .open = default_open, \
82};
83simple_type(u8, "%c", unsigned long, simple_strtoul);
84simple_type(u16, "%hi", unsigned long, simple_strtoul);
85simple_type(u32, "%i", unsigned long, simple_strtoul);
86 57
87/** 58/**
88 * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. 59 * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
@@ -116,6 +87,16 @@ struct dentry *debugfs_create_u8(const char *name, mode_t mode,
116} 87}
117EXPORT_SYMBOL_GPL(debugfs_create_u8); 88EXPORT_SYMBOL_GPL(debugfs_create_u8);
118 89
90static void debugfs_u16_set(void *data, u64 val)
91{
92 *(u16 *)data = val;
93}
94static u64 debugfs_u16_get(void *data)
95{
96 return *(u16 *)data;
97}
98DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
99
119/** 100/**
120 * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. 101 * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
121 * 102 *
@@ -148,6 +129,16 @@ struct dentry *debugfs_create_u16(const char *name, mode_t mode,
148} 129}
149EXPORT_SYMBOL_GPL(debugfs_create_u16); 130EXPORT_SYMBOL_GPL(debugfs_create_u16);
150 131
132static void debugfs_u32_set(void *data, u64 val)
133{
134 *(u32 *)data = val;
135}
136static u64 debugfs_u32_get(void *data)
137{
138 return *(u32 *)data;
139}
140DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
141
151/** 142/**
152 * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. 143 * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
153 * 144 *
diff --git a/fs/exec.c b/fs/exec.c
index e56ee2437025..3a4b35a14c0d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -649,6 +649,7 @@ static inline int de_thread(struct task_struct *tsk)
649 } 649 }
650 sig->group_exit_task = NULL; 650 sig->group_exit_task = NULL;
651 sig->notify_count = 0; 651 sig->notify_count = 0;
652 sig->real_timer.data = (unsigned long)current;
652 spin_unlock_irq(lock); 653 spin_unlock_irq(lock);
653 654
654 /* 655 /*
@@ -675,10 +676,8 @@ static inline int de_thread(struct task_struct *tsk)
675 proc_dentry2 = proc_pid_unhash(leader); 676 proc_dentry2 = proc_pid_unhash(leader);
676 write_lock_irq(&tasklist_lock); 677 write_lock_irq(&tasklist_lock);
677 678
678 if (leader->tgid != current->tgid) 679 BUG_ON(leader->tgid != current->tgid);
679 BUG(); 680 BUG_ON(current->pid == current->tgid);
680 if (current->pid == current->tgid)
681 BUG();
682 /* 681 /*
683 * An exec() starts a new thread group with the 682 * An exec() starts a new thread group with the
684 * TGID of the previous thread group. Rehash the 683 * TGID of the previous thread group. Rehash the
@@ -726,8 +725,7 @@ static inline int de_thread(struct task_struct *tsk)
726 proc_pid_flush(proc_dentry1); 725 proc_pid_flush(proc_dentry1);
727 proc_pid_flush(proc_dentry2); 726 proc_pid_flush(proc_dentry2);
728 727
729 if (exit_state != EXIT_ZOMBIE) 728 BUG_ON(exit_state != EXIT_ZOMBIE);
730 BUG();
731 release_task(leader); 729 release_task(leader);
732 } 730 }
733 731
@@ -772,10 +770,8 @@ no_thread_group:
772 kmem_cache_free(sighand_cachep, oldsighand); 770 kmem_cache_free(sighand_cachep, oldsighand);
773 } 771 }
774 772
775 if (!thread_group_empty(current)) 773 BUG_ON(!thread_group_empty(current));
776 BUG(); 774 BUG_ON(!thread_group_leader(current));
777 if (!thread_group_leader(current))
778 BUG();
779 return 0; 775 return 0;
780} 776}
781 777
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 14a0d339d036..4bf43ea87c46 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -23,7 +23,6 @@
23#include "kern_util.h" 23#include "kern_util.h"
24#include "kern.h" 24#include "kern.h"
25#include "user_util.h" 25#include "user_util.h"
26#include "2_5compat.h"
27#include "init.h" 26#include "init.h"
28 27
29struct hostfs_inode_info { 28struct hostfs_inode_info {
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 2af3338f891b..3a9b6d179cbd 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -122,6 +122,9 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
122 122
123 start_addr = mm->free_area_cache; 123 start_addr = mm->free_area_cache;
124 124
125 if (len <= mm->cached_hole_size)
126 start_addr = TASK_UNMAPPED_BASE;
127
125full_search: 128full_search:
126 addr = ALIGN(start_addr, HPAGE_SIZE); 129 addr = ALIGN(start_addr, HPAGE_SIZE);
127 130
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index 6030956b894b..7901ac9f97ab 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -193,12 +193,17 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
193 193
194 /* Handle everything else. Do name translation if there 194 /* Handle everything else. Do name translation if there
195 is no Rock Ridge NM field. */ 195 is no Rock Ridge NM field. */
196 if (sbi->s_unhide == 'n') { 196
197 /* Do not report hidden or associated files */ 197 /*
198 if (de->flags[-sbi->s_high_sierra] & 5) { 198 * Do not report hidden files if so instructed, or associated
199 filp->f_pos += de_len; 199 * files unless instructed to do so
200 continue; 200 */
201 } 201 if ((sbi->s_hide == 'y' &&
202 (de->flags[-sbi->s_high_sierra] & 1)) ||
203 (sbi->s_showassoc =='n' &&
204 (de->flags[-sbi->s_high_sierra] & 4))) {
205 filp->f_pos += de_len;
206 continue;
202 } 207 }
203 208
204 map = 1; 209 map = 1;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index abd7b12eeca7..1652de1b6cb9 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -28,11 +28,6 @@
28 28
29#define BEQUIET 29#define BEQUIET
30 30
31#ifdef LEAK_CHECK
32static int check_malloc;
33static int check_bread;
34#endif
35
36static int isofs_hashi(struct dentry *parent, struct qstr *qstr); 31static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
37static int isofs_hash(struct dentry *parent, struct qstr *qstr); 32static int isofs_hash(struct dentry *parent, struct qstr *qstr);
38static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); 33static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
@@ -55,11 +50,6 @@ static void isofs_put_super(struct super_block *sb)
55 } 50 }
56#endif 51#endif
57 52
58#ifdef LEAK_CHECK
59 printk("Outstanding mallocs:%d, outstanding buffers: %d\n",
60 check_malloc, check_bread);
61#endif
62
63 kfree(sbi); 53 kfree(sbi);
64 sb->s_fs_info = NULL; 54 sb->s_fs_info = NULL;
65 return; 55 return;
@@ -73,7 +63,7 @@ static kmem_cache_t *isofs_inode_cachep;
73static struct inode *isofs_alloc_inode(struct super_block *sb) 63static struct inode *isofs_alloc_inode(struct super_block *sb)
74{ 64{
75 struct iso_inode_info *ei; 65 struct iso_inode_info *ei;
76 ei = (struct iso_inode_info *)kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL); 66 ei = kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL);
77 if (!ei) 67 if (!ei)
78 return NULL; 68 return NULL;
79 return &ei->vfs_inode; 69 return &ei->vfs_inode;
@@ -84,9 +74,9 @@ static void isofs_destroy_inode(struct inode *inode)
84 kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); 74 kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
85} 75}
86 76
87static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) 77static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
88{ 78{
89 struct iso_inode_info *ei = (struct iso_inode_info *) foo; 79 struct iso_inode_info *ei = foo;
90 80
91 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == 81 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
92 SLAB_CTOR_CONSTRUCTOR) 82 SLAB_CTOR_CONSTRUCTOR)
@@ -107,7 +97,8 @@ static int init_inodecache(void)
107static void destroy_inodecache(void) 97static void destroy_inodecache(void)
108{ 98{
109 if (kmem_cache_destroy(isofs_inode_cachep)) 99 if (kmem_cache_destroy(isofs_inode_cachep))
110 printk(KERN_INFO "iso_inode_cache: not all structures were freed\n"); 100 printk(KERN_INFO "iso_inode_cache: not all structures were "
101 "freed\n");
111} 102}
112 103
113static int isofs_remount(struct super_block *sb, int *flags, char *data) 104static int isofs_remount(struct super_block *sb, int *flags, char *data)
@@ -144,7 +135,7 @@ static struct dentry_operations isofs_dentry_ops[] = {
144 { 135 {
145 .d_hash = isofs_hashi_ms, 136 .d_hash = isofs_hashi_ms,
146 .d_compare = isofs_dentry_cmpi_ms, 137 .d_compare = isofs_dentry_cmpi_ms,
147 } 138 },
148#endif 139#endif
149}; 140};
150 141
@@ -153,7 +144,8 @@ struct iso9660_options{
153 char rock; 144 char rock;
154 char joliet; 145 char joliet;
155 char cruft; 146 char cruft;
156 char unhide; 147 char hide;
148 char showassoc;
157 char nocompress; 149 char nocompress;
158 unsigned char check; 150 unsigned char check;
159 unsigned int blocksize; 151 unsigned int blocksize;
@@ -219,8 +211,8 @@ isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
219/* 211/*
220 * Case insensitive compare of two isofs names. 212 * Case insensitive compare of two isofs names.
221 */ 213 */
222static int 214static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a,
223isofs_dentry_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms) 215 struct qstr *b, int ms)
224{ 216{
225 int alen, blen; 217 int alen, blen;
226 218
@@ -243,8 +235,8 @@ isofs_dentry_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int
243/* 235/*
244 * Case sensitive compare of two isofs names. 236 * Case sensitive compare of two isofs names.
245 */ 237 */
246static int 238static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a,
247isofs_dentry_cmp_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms) 239 struct qstr *b, int ms)
248{ 240{
249 int alen, blen; 241 int alen, blen;
250 242
@@ -318,13 +310,15 @@ enum {
318 Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore, 310 Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
319 Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet, 311 Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
320 Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err, 312 Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
321 Opt_nocompress, 313 Opt_nocompress, Opt_hide, Opt_showassoc,
322}; 314};
323 315
324static match_table_t tokens = { 316static match_table_t tokens = {
325 {Opt_norock, "norock"}, 317 {Opt_norock, "norock"},
326 {Opt_nojoliet, "nojoliet"}, 318 {Opt_nojoliet, "nojoliet"},
327 {Opt_unhide, "unhide"}, 319 {Opt_unhide, "unhide"},
320 {Opt_hide, "hide"},
321 {Opt_showassoc, "showassoc"},
328 {Opt_cruft, "cruft"}, 322 {Opt_cruft, "cruft"},
329 {Opt_utf8, "utf8"}, 323 {Opt_utf8, "utf8"},
330 {Opt_iocharset, "iocharset=%s"}, 324 {Opt_iocharset, "iocharset=%s"},
@@ -356,7 +350,7 @@ static match_table_t tokens = {
356 {Opt_err, NULL} 350 {Opt_err, NULL}
357}; 351};
358 352
359static int parse_options(char *options, struct iso9660_options * popt) 353static int parse_options(char *options, struct iso9660_options *popt)
360{ 354{
361 char *p; 355 char *p;
362 int option; 356 int option;
@@ -365,7 +359,8 @@ static int parse_options(char *options, struct iso9660_options * popt)
365 popt->rock = 'y'; 359 popt->rock = 'y';
366 popt->joliet = 'y'; 360 popt->joliet = 'y';
367 popt->cruft = 'n'; 361 popt->cruft = 'n';
368 popt->unhide = 'n'; 362 popt->hide = 'n';
363 popt->showassoc = 'n';
369 popt->check = 'u'; /* unset */ 364 popt->check = 'u'; /* unset */
370 popt->nocompress = 0; 365 popt->nocompress = 0;
371 popt->blocksize = 1024; 366 popt->blocksize = 1024;
@@ -398,8 +393,12 @@ static int parse_options(char *options, struct iso9660_options * popt)
398 case Opt_nojoliet: 393 case Opt_nojoliet:
399 popt->joliet = 'n'; 394 popt->joliet = 'n';
400 break; 395 break;
396 case Opt_hide:
397 popt->hide = 'y';
398 break;
401 case Opt_unhide: 399 case Opt_unhide:
402 popt->unhide = 'y'; 400 case Opt_showassoc:
401 popt->showassoc = 'y';
403 break; 402 break;
404 case Opt_cruft: 403 case Opt_cruft:
405 popt->cruft = 'y'; 404 popt->cruft = 'y';
@@ -493,7 +492,7 @@ static int parse_options(char *options, struct iso9660_options * popt)
493 */ 492 */
494#define WE_OBEY_THE_WRITTEN_STANDARDS 1 493#define WE_OBEY_THE_WRITTEN_STANDARDS 1
495 494
496static unsigned int isofs_get_last_session(struct super_block *sb,s32 session ) 495static unsigned int isofs_get_last_session(struct super_block *sb, s32 session)
497{ 496{
498 struct cdrom_multisession ms_info; 497 struct cdrom_multisession ms_info;
499 unsigned int vol_desc_start; 498 unsigned int vol_desc_start;
@@ -518,7 +517,8 @@ static unsigned int isofs_get_last_session(struct super_block *sb,s32 session )
518 printk(KERN_ERR "Invalid session number or type of track\n"); 517 printk(KERN_ERR "Invalid session number or type of track\n");
519 } 518 }
520 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info); 519 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
521 if(session > 0) printk(KERN_ERR "Invalid session number\n"); 520 if (session > 0)
521 printk(KERN_ERR "Invalid session number\n");
522#if 0 522#if 0
523 printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i); 523 printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
524 if (i==0) { 524 if (i==0) {
@@ -557,13 +557,13 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
557 struct iso9660_options opt; 557 struct iso9660_options opt;
558 struct isofs_sb_info * sbi; 558 struct isofs_sb_info * sbi;
559 559
560 sbi = kmalloc(sizeof(struct isofs_sb_info), GFP_KERNEL); 560 sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
561 if (!sbi) 561 if (!sbi)
562 return -ENOMEM; 562 return -ENOMEM;
563 s->s_fs_info = sbi; 563 s->s_fs_info = sbi;
564 memset(sbi, 0, sizeof(struct isofs_sb_info)); 564 memset(sbi, 0, sizeof(*sbi));
565 565
566 if (!parse_options((char *) data, &opt)) 566 if (!parse_options((char *)data, &opt))
567 goto out_freesbi; 567 goto out_freesbi;
568 568
569 /* 569 /*
@@ -792,7 +792,8 @@ root_found:
792 sbi->s_rock = (opt.rock == 'y' ? 2 : 0); 792 sbi->s_rock = (opt.rock == 'y' ? 2 : 0);
793 sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/ 793 sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/
794 sbi->s_cruft = opt.cruft; 794 sbi->s_cruft = opt.cruft;
795 sbi->s_unhide = opt.unhide; 795 sbi->s_hide = opt.hide;
796 sbi->s_showassoc = opt.showassoc;
796 sbi->s_uid = opt.uid; 797 sbi->s_uid = opt.uid;
797 sbi->s_gid = opt.gid; 798 sbi->s_gid = opt.gid;
798 sbi->s_utf8 = opt.utf8; 799 sbi->s_utf8 = opt.utf8;
@@ -1002,7 +1003,6 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
1002 rv++; 1003 rv++;
1003 } 1004 }
1004 1005
1005
1006abort: 1006abort:
1007 unlock_kernel(); 1007 unlock_kernel();
1008 return rv; 1008 return rv;
@@ -1014,7 +1014,7 @@ abort:
1014static int isofs_get_block(struct inode *inode, sector_t iblock, 1014static int isofs_get_block(struct inode *inode, sector_t iblock,
1015 struct buffer_head *bh_result, int create) 1015 struct buffer_head *bh_result, int create)
1016{ 1016{
1017 if ( create ) { 1017 if (create) {
1018 printk("isofs_get_block: Kernel tries to allocate a block\n"); 1018 printk("isofs_get_block: Kernel tries to allocate a block\n");
1019 return -EROFS; 1019 return -EROFS;
1020 } 1020 }
@@ -1061,19 +1061,17 @@ static struct address_space_operations isofs_aops = {
1061 1061
1062static inline void test_and_set_uid(uid_t *p, uid_t value) 1062static inline void test_and_set_uid(uid_t *p, uid_t value)
1063{ 1063{
1064 if(value) { 1064 if (value)
1065 *p = value; 1065 *p = value;
1066 }
1067} 1066}
1068 1067
1069static inline void test_and_set_gid(gid_t *p, gid_t value) 1068static inline void test_and_set_gid(gid_t *p, gid_t value)
1070{ 1069{
1071 if(value) { 1070 if (value)
1072 *p = value; 1071 *p = value;
1073 }
1074} 1072}
1075 1073
1076static int isofs_read_level3_size(struct inode * inode) 1074static int isofs_read_level3_size(struct inode *inode)
1077{ 1075{
1078 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); 1076 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
1079 int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra; 1077 int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra;
@@ -1136,7 +1134,7 @@ static int isofs_read_level3_size(struct inode * inode)
1136 bh = sb_bread(inode->i_sb, block); 1134 bh = sb_bread(inode->i_sb, block);
1137 if (!bh) 1135 if (!bh)
1138 goto out_noread; 1136 goto out_noread;
1139 memcpy((void *) tmpde + slop, bh->b_data, offset); 1137 memcpy((void *)tmpde+slop, bh->b_data, offset);
1140 } 1138 }
1141 de = tmpde; 1139 de = tmpde;
1142 } 1140 }
@@ -1150,12 +1148,11 @@ static int isofs_read_level3_size(struct inode * inode)
1150 more_entries = de->flags[-high_sierra] & 0x80; 1148 more_entries = de->flags[-high_sierra] & 0x80;
1151 1149
1152 i++; 1150 i++;
1153 if(i > 100) 1151 if (i > 100)
1154 goto out_toomany; 1152 goto out_toomany;
1155 } while(more_entries); 1153 } while (more_entries);
1156out: 1154out:
1157 if (tmpde) 1155 kfree(tmpde);
1158 kfree(tmpde);
1159 if (bh) 1156 if (bh)
1160 brelse(bh); 1157 brelse(bh);
1161 return 0; 1158 return 0;
@@ -1179,7 +1176,7 @@ out_toomany:
1179 goto out; 1176 goto out;
1180} 1177}
1181 1178
1182static void isofs_read_inode(struct inode * inode) 1179static void isofs_read_inode(struct inode *inode)
1183{ 1180{
1184 struct super_block *sb = inode->i_sb; 1181 struct super_block *sb = inode->i_sb;
1185 struct isofs_sb_info *sbi = ISOFS_SB(sb); 1182 struct isofs_sb_info *sbi = ISOFS_SB(sb);
@@ -1249,7 +1246,7 @@ static void isofs_read_inode(struct inode * inode)
1249 ei->i_format_parm[2] = 0; 1246 ei->i_format_parm[2] = 0;
1250 1247
1251 ei->i_section_size = isonum_733 (de->size); 1248 ei->i_section_size = isonum_733 (de->size);
1252 if(de->flags[-high_sierra] & 0x80) { 1249 if (de->flags[-high_sierra] & 0x80) {
1253 if(isofs_read_level3_size(inode)) goto fail; 1250 if(isofs_read_level3_size(inode)) goto fail;
1254 } else { 1251 } else {
1255 ei->i_next_section_block = 0; 1252 ei->i_next_section_block = 0;
@@ -1336,16 +1333,16 @@ static void isofs_read_inode(struct inode * inode)
1336 /* XXX - parse_rock_ridge_inode() had already set i_rdev. */ 1333 /* XXX - parse_rock_ridge_inode() had already set i_rdev. */
1337 init_special_inode(inode, inode->i_mode, inode->i_rdev); 1334 init_special_inode(inode, inode->i_mode, inode->i_rdev);
1338 1335
1339 out: 1336out:
1340 if (tmpde) 1337 if (tmpde)
1341 kfree(tmpde); 1338 kfree(tmpde);
1342 if (bh) 1339 if (bh)
1343 brelse(bh); 1340 brelse(bh);
1344 return; 1341 return;
1345 1342
1346 out_badread: 1343out_badread:
1347 printk(KERN_WARNING "ISOFS: unable to read i-node block\n"); 1344 printk(KERN_WARNING "ISOFS: unable to read i-node block\n");
1348 fail: 1345fail:
1349 make_bad_inode(inode); 1346 make_bad_inode(inode);
1350 goto out; 1347 goto out;
1351} 1348}
@@ -1394,11 +1391,8 @@ struct inode *isofs_iget(struct super_block *sb,
1394 1391
1395 hashval = (block << sb->s_blocksize_bits) | offset; 1392 hashval = (block << sb->s_blocksize_bits) | offset;
1396 1393
1397 inode = iget5_locked(sb, 1394 inode = iget5_locked(sb, hashval, &isofs_iget5_test,
1398 hashval, 1395 &isofs_iget5_set, &data);
1399 &isofs_iget5_test,
1400 &isofs_iget5_set,
1401 &data);
1402 1396
1403 if (inode && (inode->i_state & I_NEW)) { 1397 if (inode && (inode->i_state & I_NEW)) {
1404 sb->s_op->read_inode(inode); 1398 sb->s_op->read_inode(inode);
@@ -1408,36 +1402,6 @@ struct inode *isofs_iget(struct super_block *sb,
1408 return inode; 1402 return inode;
1409} 1403}
1410 1404
1411#ifdef LEAK_CHECK
1412#undef malloc
1413#undef free_s
1414#undef sb_bread
1415#undef brelse
1416
1417void * leak_check_malloc(unsigned int size){
1418 void * tmp;
1419 check_malloc++;
1420 tmp = kmalloc(size, GFP_KERNEL);
1421 return tmp;
1422}
1423
1424void leak_check_free_s(void * obj, int size){
1425 check_malloc--;
1426 return kfree(obj);
1427}
1428
1429struct buffer_head * leak_check_bread(struct super_block *sb, int block){
1430 check_bread++;
1431 return sb_bread(sb, block);
1432}
1433
1434void leak_check_brelse(struct buffer_head * bh){
1435 check_bread--;
1436 return brelse(bh);
1437}
1438
1439#endif
1440
1441static struct super_block *isofs_get_sb(struct file_system_type *fs_type, 1405static struct super_block *isofs_get_sb(struct file_system_type *fs_type,
1442 int flags, const char *dev_name, void *data) 1406 int flags, const char *dev_name, void *data)
1443{ 1407{
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
index 9ce7b51fb614..38c75151fc66 100644
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -47,6 +47,8 @@ struct isofs_sb_info {
47 unsigned char s_nosuid; 47 unsigned char s_nosuid;
48 unsigned char s_nodev; 48 unsigned char s_nodev;
49 unsigned char s_nocompress; 49 unsigned char s_nocompress;
50 unsigned char s_hide;
51 unsigned char s_showassoc;
50 52
51 mode_t s_mode; 53 mode_t s_mode;
52 gid_t s_gid; 54 gid_t s_gid;
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index 690edf37173c..e37e82b7cbf0 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -131,14 +131,16 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
131 } 131 }
132 132
133 /* 133 /*
134 * Skip hidden or associated files unless unhide is set 134 * Skip hidden or associated files unless hide or showassoc,
135 * respectively, is set
135 */ 136 */
136 match = 0; 137 match = 0;
137 if (dlen > 0 && 138 if (dlen > 0 &&
138 (!(de->flags[-sbi->s_high_sierra] & 5) 139 (sbi->s_hide =='n' ||
139 || sbi->s_unhide == 'y')) 140 (!(de->flags[-sbi->s_high_sierra] & 1))) &&
140 { 141 (sbi->s_showassoc =='y' ||
141 match = (isofs_cmp(dentry,dpnt,dlen) == 0); 142 (!(de->flags[-sbi->s_high_sierra] & 4)))) {
143 match = (isofs_cmp(dentry, dpnt, dlen) == 0);
142 } 144 }
143 if (match) { 145 if (match) {
144 isofs_normalize_block_and_offset(de, 146 isofs_normalize_block_and_offset(de,
@@ -146,11 +148,11 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry,
146 &offset_saved); 148 &offset_saved);
147 *block_rv = block_saved; 149 *block_rv = block_saved;
148 *offset_rv = offset_saved; 150 *offset_rv = offset_saved;
149 if (bh) brelse(bh); 151 brelse(bh);
150 return 1; 152 return 1;
151 } 153 }
152 } 154 }
153 if (bh) brelse(bh); 155 brelse(bh);
154 return 0; 156 return 0;
155} 157}
156 158
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index 089e79c65585..4326cb47f8fa 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -13,352 +13,542 @@
13#include "isofs.h" 13#include "isofs.h"
14#include "rock.h" 14#include "rock.h"
15 15
16/* These functions are designed to read the system areas of a directory record 16/*
17 * These functions are designed to read the system areas of a directory record
17 * and extract relevant information. There are different functions provided 18 * and extract relevant information. There are different functions provided
18 * depending upon what information we need at the time. One function fills 19 * depending upon what information we need at the time. One function fills
19 * out an inode structure, a second one extracts a filename, a third one 20 * out an inode structure, a second one extracts a filename, a third one
20 * returns a symbolic link name, and a fourth one returns the extent number 21 * returns a symbolic link name, and a fourth one returns the extent number
21 * for the file. */ 22 * for the file.
22 23 */
23#define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */ 24
24 25#define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */
25 26
26/* This is a way of ensuring that we have something in the system 27struct rock_state {
27 use fields that is compatible with Rock Ridge */ 28 void *buffer;
28#define CHECK_SP(FAIL) \ 29 unsigned char *chr;
29 if(rr->u.SP.magic[0] != 0xbe) FAIL; \ 30 int len;
30 if(rr->u.SP.magic[1] != 0xef) FAIL; \ 31 int cont_size;
31 ISOFS_SB(inode->i_sb)->s_rock_offset=rr->u.SP.skip; 32 int cont_extent;
32/* We define a series of macros because each function must do exactly the 33 int cont_offset;
33 same thing in certain places. We use the macros to ensure that everything 34 struct inode *inode;
34 is done correctly */ 35};
35 36
36#define CONTINUE_DECLS \ 37/*
37 int cont_extent = 0, cont_offset = 0, cont_size = 0; \ 38 * This is a way of ensuring that we have something in the system
38 void *buffer = NULL 39 * use fields that is compatible with Rock Ridge. Return zero on success.
39 40 */
40#define CHECK_CE \ 41
41 {cont_extent = isonum_733(rr->u.CE.extent); \ 42static int check_sp(struct rock_ridge *rr, struct inode *inode)
42 cont_offset = isonum_733(rr->u.CE.offset); \
43 cont_size = isonum_733(rr->u.CE.size);}
44
45#define SETUP_ROCK_RIDGE(DE,CHR,LEN) \
46 {LEN= sizeof(struct iso_directory_record) + DE->name_len[0]; \
47 if(LEN & 1) LEN++; \
48 CHR = ((unsigned char *) DE) + LEN; \
49 LEN = *((unsigned char *) DE) - LEN; \
50 if (LEN<0) LEN=0; \
51 if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1) \
52 { \
53 LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset; \
54 CHR+=ISOFS_SB(inode->i_sb)->s_rock_offset; \
55 if (LEN<0) LEN=0; \
56 } \
57}
58
59#define MAYBE_CONTINUE(LABEL,DEV) \
60 {if (buffer) { kfree(buffer); buffer = NULL; } \
61 if (cont_extent){ \
62 int block, offset, offset1; \
63 struct buffer_head * pbh; \
64 buffer = kmalloc(cont_size,GFP_KERNEL); \
65 if (!buffer) goto out; \
66 block = cont_extent; \
67 offset = cont_offset; \
68 offset1 = 0; \
69 pbh = sb_bread(DEV->i_sb, block); \
70 if(pbh){ \
71 if (offset > pbh->b_size || offset + cont_size > pbh->b_size){ \
72 brelse(pbh); \
73 goto out; \
74 } \
75 memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \
76 brelse(pbh); \
77 chr = (unsigned char *) buffer; \
78 len = cont_size; \
79 cont_extent = 0; \
80 cont_size = 0; \
81 cont_offset = 0; \
82 goto LABEL; \
83 } \
84 printk("Unable to read rock-ridge attributes\n"); \
85 }}
86
87/* return length of name field; 0: not found, -1: to be ignored */
88int get_rock_ridge_filename(struct iso_directory_record * de,
89 char * retname, struct inode * inode)
90{ 43{
91 int len; 44 if (rr->u.SP.magic[0] != 0xbe)
92 unsigned char * chr; 45 return -1;
93 CONTINUE_DECLS; 46 if (rr->u.SP.magic[1] != 0xef)
94 int retnamlen = 0, truncate=0; 47 return -1;
95 48 ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip;
96 if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; 49 return 0;
97 *retname = 0; 50}
98 51
99 SETUP_ROCK_RIDGE(de, chr, len); 52static void setup_rock_ridge(struct iso_directory_record *de,
100 repeat: 53 struct inode *inode, struct rock_state *rs)
101 { 54{
102 struct rock_ridge * rr; 55 rs->len = sizeof(struct iso_directory_record) + de->name_len[0];
103 int sig; 56 if (rs->len & 1)
104 57 (rs->len)++;
105 while (len > 2){ /* There may be one byte for padding somewhere */ 58 rs->chr = (unsigned char *)de + rs->len;
106 rr = (struct rock_ridge *) chr; 59 rs->len = *((unsigned char *)de) - rs->len;
107 if (rr->len < 3) goto out; /* Something got screwed up here */ 60 if (rs->len < 0)
108 sig = isonum_721(chr); 61 rs->len = 0;
109 chr += rr->len; 62
110 len -= rr->len; 63 if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) {
111 if (len < 0) goto out; /* corrupted isofs */ 64 rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset;
112 65 rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset;
113 switch(sig){ 66 if (rs->len < 0)
114 case SIG('R','R'): 67 rs->len = 0;
115 if((rr->u.RR.flags[0] & RR_NM) == 0) goto out; 68 }
116 break; 69}
117 case SIG('S','P'): 70
118 CHECK_SP(goto out); 71static void init_rock_state(struct rock_state *rs, struct inode *inode)
119 break; 72{
120 case SIG('C','E'): 73 memset(rs, 0, sizeof(*rs));
121 CHECK_CE; 74 rs->inode = inode;
122 break; 75}
123 case SIG('N','M'): 76
124 if (truncate) break; 77/*
125 if (rr->len < 5) break; 78 * Returns 0 if the caller should continue scanning, 1 if the scan must end
126 /* 79 * and -ve on error.
127 * If the flags are 2 or 4, this indicates '.' or '..'. 80 */
128 * We don't want to do anything with this, because it 81static int rock_continue(struct rock_state *rs)
129 * screws up the code that calls us. We don't really 82{
130 * care anyways, since we can just use the non-RR 83 int ret = 1;
131 * name. 84 int blocksize = 1 << rs->inode->i_blkbits;
132 */ 85 const int min_de_size = offsetof(struct rock_ridge, u);
133 if (rr->u.NM.flags & 6) { 86
134 break; 87 kfree(rs->buffer);
88 rs->buffer = NULL;
89
90 if ((unsigned)rs->cont_offset > blocksize - min_de_size ||
91 (unsigned)rs->cont_size > blocksize ||
92 (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) {
93 printk(KERN_NOTICE "rock: corrupted directory entry. "
94 "extent=%d, offset=%d, size=%d\n",
95 rs->cont_extent, rs->cont_offset, rs->cont_size);
96 ret = -EIO;
97 goto out;
135 } 98 }
136 99
137 if (rr->u.NM.flags & ~1) { 100 if (rs->cont_extent) {
138 printk("Unsupported NM flag settings (%d)\n",rr->u.NM.flags); 101 struct buffer_head *bh;
139 break; 102
103 rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL);
104 if (!rs->buffer) {
105 ret = -ENOMEM;
106 goto out;
107 }
108 ret = -EIO;
109 bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
110 if (bh) {
111 memcpy(rs->buffer, bh->b_data + rs->cont_offset,
112 rs->cont_size);
113 put_bh(bh);
114 rs->chr = rs->buffer;
115 rs->len = rs->cont_size;
116 rs->cont_extent = 0;
117 rs->cont_size = 0;
118 rs->cont_offset = 0;
119 return 0;
120 }
121 printk("Unable to read rock-ridge attributes\n");
122 }
123out:
124 kfree(rs->buffer);
125 rs->buffer = NULL;
126 return ret;
127}
128
129/*
130 * We think there's a record of type `sig' at rs->chr. Parse the signature
131 * and make sure that there's really room for a record of that type.
132 */
133static int rock_check_overflow(struct rock_state *rs, int sig)
134{
135 int len;
136
137 switch (sig) {
138 case SIG('S', 'P'):
139 len = sizeof(struct SU_SP_s);
140 break;
141 case SIG('C', 'E'):
142 len = sizeof(struct SU_CE_s);
143 break;
144 case SIG('E', 'R'):
145 len = sizeof(struct SU_ER_s);
146 break;
147 case SIG('R', 'R'):
148 len = sizeof(struct RR_RR_s);
149 break;
150 case SIG('P', 'X'):
151 len = sizeof(struct RR_PX_s);
152 break;
153 case SIG('P', 'N'):
154 len = sizeof(struct RR_PN_s);
155 break;
156 case SIG('S', 'L'):
157 len = sizeof(struct RR_SL_s);
158 break;
159 case SIG('N', 'M'):
160 len = sizeof(struct RR_NM_s);
161 break;
162 case SIG('C', 'L'):
163 len = sizeof(struct RR_CL_s);
164 break;
165 case SIG('P', 'L'):
166 len = sizeof(struct RR_PL_s);
167 break;
168 case SIG('T', 'F'):
169 len = sizeof(struct RR_TF_s);
170 break;
171 case SIG('Z', 'F'):
172 len = sizeof(struct RR_ZF_s);
173 break;
174 default:
175 len = 0;
176 break;
140 } 177 }
141 if((strlen(retname) + rr->len - 5) >= 254) { 178 len += offsetof(struct rock_ridge, u);
142 truncate = 1; 179 if (len > rs->len) {
143 break; 180 printk(KERN_NOTICE "rock: directory entry would overflow "
181 "storage\n");
182 printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n",
183 sig, len, rs->len);
184 return -EIO;
185 }
186 return 0;
187}
188
189/*
190 * return length of name field; 0: not found, -1: to be ignored
191 */
192int get_rock_ridge_filename(struct iso_directory_record *de,
193 char *retname, struct inode *inode)
194{
195 struct rock_state rs;
196 struct rock_ridge *rr;
197 int sig;
198 int retnamlen = 0;
199 int truncate = 0;
200 int ret = 0;
201
202 if (!ISOFS_SB(inode->i_sb)->s_rock)
203 return 0;
204 *retname = 0;
205
206 init_rock_state(&rs, inode);
207 setup_rock_ridge(de, inode, &rs);
208repeat:
209
210 while (rs.len > 2) { /* There may be one byte for padding somewhere */
211 rr = (struct rock_ridge *)rs.chr;
212 if (rr->len < 3)
213 goto out; /* Something got screwed up here */
214 sig = isonum_721(rs.chr);
215 if (rock_check_overflow(&rs, sig))
216 goto eio;
217 rs.chr += rr->len;
218 rs.len -= rr->len;
219 if (rs.len < 0)
220 goto eio; /* corrupted isofs */
221
222 switch (sig) {
223 case SIG('R', 'R'):
224 if ((rr->u.RR.flags[0] & RR_NM) == 0)
225 goto out;
226 break;
227 case SIG('S', 'P'):
228 if (check_sp(rr, inode))
229 goto out;
230 break;
231 case SIG('C', 'E'):
232 rs.cont_extent = isonum_733(rr->u.CE.extent);
233 rs.cont_offset = isonum_733(rr->u.CE.offset);
234 rs.cont_size = isonum_733(rr->u.CE.size);
235 break;
236 case SIG('N', 'M'):
237 if (truncate)
238 break;
239 if (rr->len < 5)
240 break;
241 /*
242 * If the flags are 2 or 4, this indicates '.' or '..'.
243 * We don't want to do anything with this, because it
244 * screws up the code that calls us. We don't really
245 * care anyways, since we can just use the non-RR
246 * name.
247 */
248 if (rr->u.NM.flags & 6)
249 break;
250
251 if (rr->u.NM.flags & ~1) {
252 printk("Unsupported NM flag settings (%d)\n",
253 rr->u.NM.flags);
254 break;
255 }
256 if ((strlen(retname) + rr->len - 5) >= 254) {
257 truncate = 1;
258 break;
259 }
260 strncat(retname, rr->u.NM.name, rr->len - 5);
261 retnamlen += rr->len - 5;
262 break;
263 case SIG('R', 'E'):
264 kfree(rs.buffer);
265 return -1;
266 default:
267 break;
268 }
144 } 269 }
145 strncat(retname, rr->u.NM.name, rr->len - 5); 270 ret = rock_continue(&rs);
146 retnamlen += rr->len - 5; 271 if (ret == 0)
147 break; 272 goto repeat;
148 case SIG('R','E'): 273 if (ret == 1)
149 if (buffer) kfree(buffer); 274 return retnamlen; /* If 0, this file did not have a NM field */
150 return -1; 275out:
151 default: 276 kfree(rs.buffer);
152 break; 277 return ret;
153 } 278eio:
154 } 279 ret = -EIO;
155 } 280 goto out;
156 MAYBE_CONTINUE(repeat,inode);
157 if (buffer) kfree(buffer);
158 return retnamlen; /* If 0, this file did not have a NM field */
159 out:
160 if(buffer) kfree(buffer);
161 return 0;
162} 281}
163 282
164static int 283static int
165parse_rock_ridge_inode_internal(struct iso_directory_record *de, 284parse_rock_ridge_inode_internal(struct iso_directory_record *de,
166 struct inode *inode, int regard_xa) 285 struct inode *inode, int regard_xa)
167{ 286{
168 int len; 287 int symlink_len = 0;
169 unsigned char * chr; 288 int cnt, sig;
170 int symlink_len = 0; 289 struct inode *reloc;
171 CONTINUE_DECLS; 290 struct rock_ridge *rr;
172 291 int rootflag;
173 if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; 292 struct rock_state rs;
174 293 int ret = 0;
175 SETUP_ROCK_RIDGE(de, chr, len); 294
176 if (regard_xa) 295 if (!ISOFS_SB(inode->i_sb)->s_rock)
177 { 296 return 0;
178 chr+=14; 297
179 len-=14; 298 init_rock_state(&rs, inode);
180 if (len<0) len=0; 299 setup_rock_ridge(de, inode, &rs);
181 } 300 if (regard_xa) {
182 301 rs.chr += 14;
183 repeat: 302 rs.len -= 14;
184 { 303 if (rs.len < 0)
185 int cnt, sig; 304 rs.len = 0;
186 struct inode * reloc; 305 }
187 struct rock_ridge * rr; 306
188 int rootflag; 307repeat:
189 308 while (rs.len > 2) { /* There may be one byte for padding somewhere */
190 while (len > 2){ /* There may be one byte for padding somewhere */ 309 rr = (struct rock_ridge *)rs.chr;
191 rr = (struct rock_ridge *) chr; 310 if (rr->len < 3)
192 if (rr->len < 3) goto out; /* Something got screwed up here */ 311 goto out; /* Something got screwed up here */
193 sig = isonum_721(chr); 312 sig = isonum_721(rs.chr);
194 chr += rr->len; 313 if (rock_check_overflow(&rs, sig))
195 len -= rr->len; 314 goto eio;
196 if (len < 0) goto out; /* corrupted isofs */ 315 rs.chr += rr->len;
197 316 rs.len -= rr->len;
198 switch(sig){ 317 if (rs.len < 0)
318 goto eio; /* corrupted isofs */
319
320 switch (sig) {
199#ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ 321#ifndef CONFIG_ZISOFS /* No flag for SF or ZF */
200 case SIG('R','R'): 322 case SIG('R', 'R'):
201 if((rr->u.RR.flags[0] & 323 if ((rr->u.RR.flags[0] &
202 (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) goto out; 324 (RR_PX | RR_TF | RR_SL | RR_CL)) == 0)
203 break; 325 goto out;
326 break;
204#endif 327#endif
205 case SIG('S','P'): 328 case SIG('S', 'P'):
206 CHECK_SP(goto out); 329 if (check_sp(rr, inode))
207 break; 330 goto out;
208 case SIG('C','E'): 331 break;
209 CHECK_CE; 332 case SIG('C', 'E'):
210 break; 333 rs.cont_extent = isonum_733(rr->u.CE.extent);
211 case SIG('E','R'): 334 rs.cont_offset = isonum_733(rr->u.CE.offset);
212 ISOFS_SB(inode->i_sb)->s_rock = 1; 335 rs.cont_size = isonum_733(rr->u.CE.size);
213 printk(KERN_DEBUG "ISO 9660 Extensions: "); 336 break;
214 { int p; 337 case SIG('E', 'R'):
215 for(p=0;p<rr->u.ER.len_id;p++) printk("%c",rr->u.ER.data[p]); 338 ISOFS_SB(inode->i_sb)->s_rock = 1;
216 } 339 printk(KERN_DEBUG "ISO 9660 Extensions: ");
217 printk("\n"); 340 {
218 break; 341 int p;
219 case SIG('P','X'): 342 for (p = 0; p < rr->u.ER.len_id; p++)
220 inode->i_mode = isonum_733(rr->u.PX.mode); 343 printk("%c", rr->u.ER.data[p]);
221 inode->i_nlink = isonum_733(rr->u.PX.n_links); 344 }
222 inode->i_uid = isonum_733(rr->u.PX.uid); 345 printk("\n");
223 inode->i_gid = isonum_733(rr->u.PX.gid); 346 break;
224 break; 347 case SIG('P', 'X'):
225 case SIG('P','N'): 348 inode->i_mode = isonum_733(rr->u.PX.mode);
226 { int high, low; 349 inode->i_nlink = isonum_733(rr->u.PX.n_links);
227 high = isonum_733(rr->u.PN.dev_high); 350 inode->i_uid = isonum_733(rr->u.PX.uid);
228 low = isonum_733(rr->u.PN.dev_low); 351 inode->i_gid = isonum_733(rr->u.PX.gid);
229 /* 352 break;
230 * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, 353 case SIG('P', 'N'):
231 * then the high field is unused, and the device number is completely 354 {
232 * stored in the low field. Some writers may ignore this subtlety, 355 int high, low;
233 * and as a result we test to see if the entire device number is 356 high = isonum_733(rr->u.PN.dev_high);
234 * stored in the low field, and use that. 357 low = isonum_733(rr->u.PN.dev_low);
235 */ 358 /*
236 if((low & ~0xff) && high == 0) { 359 * The Rock Ridge standard specifies that if
237 inode->i_rdev = MKDEV(low >> 8, low & 0xff); 360 * sizeof(dev_t) <= 4, then the high field is
238 } else { 361 * unused, and the device number is completely
239 inode->i_rdev = MKDEV(high, low); 362 * stored in the low field. Some writers may
240 } 363 * ignore this subtlety,
241 } 364 * and as a result we test to see if the entire
242 break; 365 * device number is
243 case SIG('T','F'): 366 * stored in the low field, and use that.
244 /* Some RRIP writers incorrectly place ctime in the TF_CREATE field. 367 */
245 Try to handle this correctly for either case. */ 368 if ((low & ~0xff) && high == 0) {
246 cnt = 0; /* Rock ridge never appears on a High Sierra disk */ 369 inode->i_rdev =
247 if(rr->u.TF.flags & TF_CREATE) { 370 MKDEV(low >> 8, low & 0xff);
248 inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 371 } else {
249 inode->i_ctime.tv_nsec = 0; 372 inode->i_rdev =
250 } 373 MKDEV(high, low);
251 if(rr->u.TF.flags & TF_MODIFY) { 374 }
252 inode->i_mtime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 375 }
253 inode->i_mtime.tv_nsec = 0; 376 break;
254 } 377 case SIG('T', 'F'):
255 if(rr->u.TF.flags & TF_ACCESS) { 378 /*
256 inode->i_atime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 379 * Some RRIP writers incorrectly place ctime in the
257 inode->i_atime.tv_nsec = 0; 380 * TF_CREATE field. Try to handle this correctly for
258 } 381 * either case.
259 if(rr->u.TF.flags & TF_ATTRIBUTES) { 382 */
260 inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); 383 /* Rock ridge never appears on a High Sierra disk */
261 inode->i_ctime.tv_nsec = 0; 384 cnt = 0;
262 } 385 if (rr->u.TF.flags & TF_CREATE) {
263 break; 386 inode->i_ctime.tv_sec =
264 case SIG('S','L'): 387 iso_date(rr->u.TF.times[cnt++].time,
265 {int slen; 388 0);
266 struct SL_component * slp; 389 inode->i_ctime.tv_nsec = 0;
267 struct SL_component * oldslp; 390 }
268 slen = rr->len - 5; 391 if (rr->u.TF.flags & TF_MODIFY) {
269 slp = &rr->u.SL.link; 392 inode->i_mtime.tv_sec =
270 inode->i_size = symlink_len; 393 iso_date(rr->u.TF.times[cnt++].time,
271 while (slen > 1){ 394 0);
272 rootflag = 0; 395 inode->i_mtime.tv_nsec = 0;
273 switch(slp->flags &~1){ 396 }
274 case 0: 397 if (rr->u.TF.flags & TF_ACCESS) {
275 inode->i_size += slp->len; 398 inode->i_atime.tv_sec =
276 break; 399 iso_date(rr->u.TF.times[cnt++].time,
277 case 2: 400 0);
278 inode->i_size += 1; 401 inode->i_atime.tv_nsec = 0;
279 break; 402 }
280 case 4: 403 if (rr->u.TF.flags & TF_ATTRIBUTES) {
281 inode->i_size += 2; 404 inode->i_ctime.tv_sec =
282 break; 405 iso_date(rr->u.TF.times[cnt++].time,
283 case 8: 406 0);
284 rootflag = 1; 407 inode->i_ctime.tv_nsec = 0;
285 inode->i_size += 1; 408 }
286 break; 409 break;
287 default: 410 case SIG('S', 'L'):
288 printk("Symlink component flag not implemented\n"); 411 {
289 } 412 int slen;
290 slen -= slp->len + 2; 413 struct SL_component *slp;
291 oldslp = slp; 414 struct SL_component *oldslp;
292 slp = (struct SL_component *) (((char *) slp) + slp->len + 2); 415 slen = rr->len - 5;
293 416 slp = &rr->u.SL.link;
294 if(slen < 2) { 417 inode->i_size = symlink_len;
295 if( ((rr->u.SL.flags & 1) != 0) 418 while (slen > 1) {
296 && ((oldslp->flags & 1) == 0) ) inode->i_size += 1; 419 rootflag = 0;
297 break; 420 switch (slp->flags & ~1) {
298 } 421 case 0:
299 422 inode->i_size +=
300 /* 423 slp->len;
301 * If this component record isn't continued, then append a '/'. 424 break;
302 */ 425 case 2:
303 if (!rootflag && (oldslp->flags & 1) == 0) 426 inode->i_size += 1;
304 inode->i_size += 1; 427 break;
305 } 428 case 4:
306 } 429 inode->i_size += 2;
307 symlink_len = inode->i_size; 430 break;
308 break; 431 case 8:
309 case SIG('R','E'): 432 rootflag = 1;
310 printk(KERN_WARNING "Attempt to read inode for relocated directory\n"); 433 inode->i_size += 1;
311 goto out; 434 break;
312 case SIG('C','L'): 435 default:
313 ISOFS_I(inode)->i_first_extent = isonum_733(rr->u.CL.location); 436 printk("Symlink component flag "
314 reloc = isofs_iget(inode->i_sb, ISOFS_I(inode)->i_first_extent, 0); 437 "not implemented\n");
315 if (!reloc) 438 }
316 goto out; 439 slen -= slp->len + 2;
317 inode->i_mode = reloc->i_mode; 440 oldslp = slp;
318 inode->i_nlink = reloc->i_nlink; 441 slp = (struct SL_component *)
319 inode->i_uid = reloc->i_uid; 442 (((char *)slp) + slp->len + 2);
320 inode->i_gid = reloc->i_gid; 443
321 inode->i_rdev = reloc->i_rdev; 444 if (slen < 2) {
322 inode->i_size = reloc->i_size; 445 if (((rr->u.SL.
323 inode->i_blocks = reloc->i_blocks; 446 flags & 1) != 0)
324 inode->i_atime = reloc->i_atime; 447 &&
325 inode->i_ctime = reloc->i_ctime; 448 ((oldslp->
326 inode->i_mtime = reloc->i_mtime; 449 flags & 1) == 0))
327 iput(reloc); 450 inode->i_size +=
328 break; 451 1;
452 break;
453 }
454
455 /*
456 * If this component record isn't
457 * continued, then append a '/'.
458 */
459 if (!rootflag
460 && (oldslp->flags & 1) == 0)
461 inode->i_size += 1;
462 }
463 }
464 symlink_len = inode->i_size;
465 break;
466 case SIG('R', 'E'):
467 printk(KERN_WARNING "Attempt to read inode for "
468 "relocated directory\n");
469 goto out;
470 case SIG('C', 'L'):
471 ISOFS_I(inode)->i_first_extent =
472 isonum_733(rr->u.CL.location);
473 reloc =
474 isofs_iget(inode->i_sb,
475 ISOFS_I(inode)->i_first_extent,
476 0);
477 if (!reloc)
478 goto out;
479 inode->i_mode = reloc->i_mode;
480 inode->i_nlink = reloc->i_nlink;
481 inode->i_uid = reloc->i_uid;
482 inode->i_gid = reloc->i_gid;
483 inode->i_rdev = reloc->i_rdev;
484 inode->i_size = reloc->i_size;
485 inode->i_blocks = reloc->i_blocks;
486 inode->i_atime = reloc->i_atime;
487 inode->i_ctime = reloc->i_ctime;
488 inode->i_mtime = reloc->i_mtime;
489 iput(reloc);
490 break;
329#ifdef CONFIG_ZISOFS 491#ifdef CONFIG_ZISOFS
330 case SIG('Z','F'): 492 case SIG('Z', 'F'): {
331 if ( !ISOFS_SB(inode->i_sb)->s_nocompress ) { 493 int algo;
332 int algo; 494
333 algo = isonum_721(rr->u.ZF.algorithm); 495 if (ISOFS_SB(inode->i_sb)->s_nocompress)
334 if ( algo == SIG('p','z') ) { 496 break;
335 int block_shift = isonum_711(&rr->u.ZF.parms[1]); 497 algo = isonum_721(rr->u.ZF.algorithm);
336 if ( block_shift < PAGE_CACHE_SHIFT || block_shift > 17 ) { 498 if (algo == SIG('p', 'z')) {
337 printk(KERN_WARNING "isofs: Can't handle ZF block size of 2^%d\n", block_shift); 499 int block_shift =
338 } else { 500 isonum_711(&rr->u.ZF.parms[1]);
339 /* Note: we don't change i_blocks here */ 501 if (block_shift < PAGE_CACHE_SHIFT
340 ISOFS_I(inode)->i_file_format = isofs_file_compressed; 502 || block_shift > 17) {
341 /* Parameters to compression algorithm (header size, block size) */ 503 printk(KERN_WARNING "isofs: "
342 ISOFS_I(inode)->i_format_parm[0] = isonum_711(&rr->u.ZF.parms[0]); 504 "Can't handle ZF block "
343 ISOFS_I(inode)->i_format_parm[1] = isonum_711(&rr->u.ZF.parms[1]); 505 "size of 2^%d\n",
344 inode->i_size = isonum_733(rr->u.ZF.real_size); 506 block_shift);
345 } 507 } else {
346 } else { 508 /*
347 printk(KERN_WARNING "isofs: Unknown ZF compression algorithm: %c%c\n", 509 * Note: we don't change
348 rr->u.ZF.algorithm[0], rr->u.ZF.algorithm[1]); 510 * i_blocks here
349 } 511 */
350 } 512 ISOFS_I(inode)->i_file_format =
351 break; 513 isofs_file_compressed;
514 /*
515 * Parameters to compression
516 * algorithm (header size,
517 * block size)
518 */
519 ISOFS_I(inode)->i_format_parm[0] =
520 isonum_711(&rr->u.ZF.parms[0]);
521 ISOFS_I(inode)->i_format_parm[1] =
522 isonum_711(&rr->u.ZF.parms[1]);
523 inode->i_size =
524 isonum_733(rr->u.ZF.
525 real_size);
526 }
527 } else {
528 printk(KERN_WARNING
529 "isofs: Unknown ZF compression "
530 "algorithm: %c%c\n",
531 rr->u.ZF.algorithm[0],
532 rr->u.ZF.algorithm[1]);
533 }
534 break;
535 }
352#endif 536#endif
353 default: 537 default:
354 break; 538 break;
355 } 539 }
356 } 540 }
357 } 541 ret = rock_continue(&rs);
358 MAYBE_CONTINUE(repeat,inode); 542 if (ret == 0)
359 out: 543 goto repeat;
360 if(buffer) kfree(buffer); 544 if (ret == 1)
361 return 0; 545 ret = 0;
546out:
547 kfree(rs.buffer);
548 return ret;
549eio:
550 ret = -EIO;
551 goto out;
362} 552}
363 553
364static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit) 554static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
@@ -376,32 +566,32 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
376 if (slp->len > plimit - rpnt) 566 if (slp->len > plimit - rpnt)
377 return NULL; 567 return NULL;
378 memcpy(rpnt, slp->text, slp->len); 568 memcpy(rpnt, slp->text, slp->len);
379 rpnt+=slp->len; 569 rpnt += slp->len;
380 break; 570 break;
381 case 2: 571 case 2:
382 if (rpnt >= plimit) 572 if (rpnt >= plimit)
383 return NULL; 573 return NULL;
384 *rpnt++='.'; 574 *rpnt++ = '.';
385 break; 575 break;
386 case 4: 576 case 4:
387 if (2 > plimit - rpnt) 577 if (2 > plimit - rpnt)
388 return NULL; 578 return NULL;
389 *rpnt++='.'; 579 *rpnt++ = '.';
390 *rpnt++='.'; 580 *rpnt++ = '.';
391 break; 581 break;
392 case 8: 582 case 8:
393 if (rpnt >= plimit) 583 if (rpnt >= plimit)
394 return NULL; 584 return NULL;
395 rootflag = 1; 585 rootflag = 1;
396 *rpnt++='/'; 586 *rpnt++ = '/';
397 break; 587 break;
398 default: 588 default:
399 printk("Symlink component flag not implemented (%d)\n", 589 printk("Symlink component flag not implemented (%d)\n",
400 slp->flags); 590 slp->flags);
401 } 591 }
402 slen -= slp->len + 2; 592 slen -= slp->len + 2;
403 oldslp = slp; 593 oldslp = slp;
404 slp = (struct SL_component *) ((char *) slp + slp->len + 2); 594 slp = (struct SL_component *)((char *)slp + slp->len + 2);
405 595
406 if (slen < 2) { 596 if (slen < 2) {
407 /* 597 /*
@@ -412,7 +602,7 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
412 !(oldslp->flags & 1)) { 602 !(oldslp->flags & 1)) {
413 if (rpnt >= plimit) 603 if (rpnt >= plimit)
414 return NULL; 604 return NULL;
415 *rpnt++='/'; 605 *rpnt++ = '/';
416 } 606 }
417 break; 607 break;
418 } 608 }
@@ -423,59 +613,61 @@ static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
423 if (!rootflag && !(oldslp->flags & 1)) { 613 if (!rootflag && !(oldslp->flags & 1)) {
424 if (rpnt >= plimit) 614 if (rpnt >= plimit)
425 return NULL; 615 return NULL;
426 *rpnt++='/'; 616 *rpnt++ = '/';
427 } 617 }
428 } 618 }
429 return rpnt; 619 return rpnt;
430} 620}
431 621
432int parse_rock_ridge_inode(struct iso_directory_record * de, 622int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
433 struct inode * inode)
434{ 623{
435 int result=parse_rock_ridge_inode_internal(de,inode,0); 624 int result = parse_rock_ridge_inode_internal(de, inode, 0);
436 /* if rockridge flag was reset and we didn't look for attributes
437 * behind eventual XA attributes, have a look there */
438 if ((ISOFS_SB(inode->i_sb)->s_rock_offset==-1)
439 &&(ISOFS_SB(inode->i_sb)->s_rock==2))
440 {
441 result=parse_rock_ridge_inode_internal(de,inode,14);
442 }
443 return result;
444}
445 625
446/* readpage() for symlinks: reads symlink contents into the page and either 626 /*
447 makes it uptodate and returns 0 or returns error (-EIO) */ 627 * if rockridge flag was reset and we didn't look for attributes
628 * behind eventual XA attributes, have a look there
629 */
630 if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
631 && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
632 result = parse_rock_ridge_inode_internal(de, inode, 14);
633 }
634 return result;
635}
448 636
637/*
638 * readpage() for symlinks: reads symlink contents into the page and either
639 * makes it uptodate and returns 0 or returns error (-EIO)
640 */
449static int rock_ridge_symlink_readpage(struct file *file, struct page *page) 641static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
450{ 642{
451 struct inode *inode = page->mapping->host; 643 struct inode *inode = page->mapping->host;
452 struct iso_inode_info *ei = ISOFS_I(inode); 644 struct iso_inode_info *ei = ISOFS_I(inode);
453 char *link = kmap(page); 645 char *link = kmap(page);
454 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); 646 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
455 struct buffer_head *bh; 647 struct buffer_head *bh;
456 char *rpnt = link; 648 char *rpnt = link;
457 unsigned char *pnt; 649 unsigned char *pnt;
458 struct iso_directory_record *raw_inode; 650 struct iso_directory_record *raw_de;
459 CONTINUE_DECLS;
460 unsigned long block, offset; 651 unsigned long block, offset;
461 int sig; 652 int sig;
462 int len;
463 unsigned char *chr;
464 struct rock_ridge *rr; 653 struct rock_ridge *rr;
654 struct rock_state rs;
655 int ret;
465 656
466 if (!ISOFS_SB(inode->i_sb)->s_rock) 657 if (!ISOFS_SB(inode->i_sb)->s_rock)
467 goto error; 658 goto error;
468 659
660 init_rock_state(&rs, inode);
469 block = ei->i_iget5_block; 661 block = ei->i_iget5_block;
470 lock_kernel(); 662 lock_kernel();
471 bh = sb_bread(inode->i_sb, block); 663 bh = sb_bread(inode->i_sb, block);
472 if (!bh) 664 if (!bh)
473 goto out_noread; 665 goto out_noread;
474 666
475 offset = ei->i_iget5_offset; 667 offset = ei->i_iget5_offset;
476 pnt = (unsigned char *) bh->b_data + offset; 668 pnt = (unsigned char *)bh->b_data + offset;
477 669
478 raw_inode = (struct iso_directory_record *) pnt; 670 raw_de = (struct iso_directory_record *)pnt;
479 671
480 /* 672 /*
481 * If we go past the end of the buffer, there is some sort of error. 673 * If we go past the end of the buffer, there is some sort of error.
@@ -483,20 +675,24 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
483 if (offset + *pnt > bufsize) 675 if (offset + *pnt > bufsize)
484 goto out_bad_span; 676 goto out_bad_span;
485 677
486 /* Now test for possible Rock Ridge extensions which will override 678 /*
487 some of these numbers in the inode structure. */ 679 * Now test for possible Rock Ridge extensions which will override
680 * some of these numbers in the inode structure.
681 */
488 682
489 SETUP_ROCK_RIDGE(raw_inode, chr, len); 683 setup_rock_ridge(raw_de, inode, &rs);
490 684
491 repeat: 685repeat:
492 while (len > 2) { /* There may be one byte for padding somewhere */ 686 while (rs.len > 2) { /* There may be one byte for padding somewhere */
493 rr = (struct rock_ridge *) chr; 687 rr = (struct rock_ridge *)rs.chr;
494 if (rr->len < 3) 688 if (rr->len < 3)
495 goto out; /* Something got screwed up here */ 689 goto out; /* Something got screwed up here */
496 sig = isonum_721(chr); 690 sig = isonum_721(rs.chr);
497 chr += rr->len; 691 if (rock_check_overflow(&rs, sig))
498 len -= rr->len; 692 goto out;
499 if (len < 0) 693 rs.chr += rr->len;
694 rs.len -= rr->len;
695 if (rs.len < 0)
500 goto out; /* corrupted isofs */ 696 goto out; /* corrupted isofs */
501 697
502 switch (sig) { 698 switch (sig) {
@@ -505,7 +701,8 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
505 goto out; 701 goto out;
506 break; 702 break;
507 case SIG('S', 'P'): 703 case SIG('S', 'P'):
508 CHECK_SP(goto out); 704 if (check_sp(rr, inode))
705 goto out;
509 break; 706 break;
510 case SIG('S', 'L'): 707 case SIG('S', 'L'):
511 rpnt = get_symlink_chunk(rpnt, rr, 708 rpnt = get_symlink_chunk(rpnt, rr,
@@ -515,14 +712,18 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
515 break; 712 break;
516 case SIG('C', 'E'): 713 case SIG('C', 'E'):
517 /* This tells is if there is a continuation record */ 714 /* This tells is if there is a continuation record */
518 CHECK_CE; 715 rs.cont_extent = isonum_733(rr->u.CE.extent);
716 rs.cont_offset = isonum_733(rr->u.CE.offset);
717 rs.cont_size = isonum_733(rr->u.CE.size);
519 default: 718 default:
520 break; 719 break;
521 } 720 }
522 } 721 }
523 MAYBE_CONTINUE(repeat, inode); 722 ret = rock_continue(&rs);
524 if (buffer) 723 if (ret == 0)
525 kfree(buffer); 724 goto repeat;
725 if (ret < 0)
726 goto fail;
526 727
527 if (rpnt == link) 728 if (rpnt == link)
528 goto fail; 729 goto fail;
@@ -535,19 +736,18 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
535 return 0; 736 return 0;
536 737
537 /* error exit from macro */ 738 /* error exit from macro */
538 out: 739out:
539 if (buffer) 740 kfree(rs.buffer);
540 kfree(buffer);
541 goto fail; 741 goto fail;
542 out_noread: 742out_noread:
543 printk("unable to read i-node block"); 743 printk("unable to read i-node block");
544 goto fail; 744 goto fail;
545 out_bad_span: 745out_bad_span:
546 printk("symlink spans iso9660 blocks\n"); 746 printk("symlink spans iso9660 blocks\n");
547 fail: 747fail:
548 brelse(bh); 748 brelse(bh);
549 unlock_kernel(); 749 unlock_kernel();
550 error: 750error:
551 SetPageError(page); 751 SetPageError(page);
552 kunmap(page); 752 kunmap(page);
553 unlock_page(page); 753 unlock_page(page);
@@ -555,5 +755,5 @@ static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
555} 755}
556 756
557struct address_space_operations isofs_symlink_aops = { 757struct address_space_operations isofs_symlink_aops = {
558 .readpage = rock_ridge_symlink_readpage 758 .readpage = rock_ridge_symlink_readpage
559}; 759};
diff --git a/fs/isofs/rock.h b/fs/isofs/rock.h
index deaf5c8e8b4a..ed09e2b08637 100644
--- a/fs/isofs/rock.h
+++ b/fs/isofs/rock.h
@@ -1,85 +1,88 @@
1/* These structs are used by the system-use-sharing protocol, in which the 1/*
2 Rock Ridge extensions are embedded. It is quite possible that other 2 * These structs are used by the system-use-sharing protocol, in which the
3 extensions are present on the disk, and this is fine as long as they 3 * Rock Ridge extensions are embedded. It is quite possible that other
4 all use SUSP */ 4 * extensions are present on the disk, and this is fine as long as they
5 5 * all use SUSP
6struct SU_SP{ 6 */
7 unsigned char magic[2]; 7
8 unsigned char skip; 8struct SU_SP_s {
9} __attribute__((packed)); 9 unsigned char magic[2];
10 10 unsigned char skip;
11struct SU_CE{ 11} __attribute__ ((packed));
12 char extent[8]; 12
13 char offset[8]; 13struct SU_CE_s {
14 char size[8]; 14 char extent[8];
15 char offset[8];
16 char size[8];
15}; 17};
16 18
17struct SU_ER{ 19struct SU_ER_s {
18 unsigned char len_id; 20 unsigned char len_id;
19 unsigned char len_des; 21 unsigned char len_des;
20 unsigned char len_src; 22 unsigned char len_src;
21 unsigned char ext_ver; 23 unsigned char ext_ver;
22 char data[0]; 24 char data[0];
23} __attribute__((packed)); 25} __attribute__ ((packed));
24 26
25struct RR_RR{ 27struct RR_RR_s {
26 char flags[1]; 28 char flags[1];
27} __attribute__((packed)); 29} __attribute__ ((packed));
28 30
29struct RR_PX{ 31struct RR_PX_s {
30 char mode[8]; 32 char mode[8];
31 char n_links[8]; 33 char n_links[8];
32 char uid[8]; 34 char uid[8];
33 char gid[8]; 35 char gid[8];
34}; 36};
35 37
36struct RR_PN{ 38struct RR_PN_s {
37 char dev_high[8]; 39 char dev_high[8];
38 char dev_low[8]; 40 char dev_low[8];
39}; 41};
40 42
43struct SL_component {
44 unsigned char flags;
45 unsigned char len;
46 char text[0];
47} __attribute__ ((packed));
41 48
42struct SL_component{ 49struct RR_SL_s {
43 unsigned char flags; 50 unsigned char flags;
44 unsigned char len; 51 struct SL_component link;
45 char text[0]; 52} __attribute__ ((packed));
46} __attribute__((packed));
47 53
48struct RR_SL{ 54struct RR_NM_s {
49 unsigned char flags; 55 unsigned char flags;
50 struct SL_component link; 56 char name[0];
51} __attribute__((packed)); 57} __attribute__ ((packed));
52 58
53struct RR_NM{ 59struct RR_CL_s {
54 unsigned char flags; 60 char location[8];
55 char name[0];
56} __attribute__((packed));
57
58struct RR_CL{
59 char location[8];
60}; 61};
61 62
62struct RR_PL{ 63struct RR_PL_s {
63 char location[8]; 64 char location[8];
64}; 65};
65 66
66struct stamp{ 67struct stamp {
67 char time[7]; 68 char time[7];
68} __attribute__((packed)); 69} __attribute__ ((packed));
69 70
70struct RR_TF{ 71struct RR_TF_s {
71 char flags; 72 char flags;
72 struct stamp times[0]; /* Variable number of these beasts */ 73 struct stamp times[0]; /* Variable number of these beasts */
73} __attribute__((packed)); 74} __attribute__ ((packed));
74 75
75/* Linux-specific extension for transparent decompression */ 76/* Linux-specific extension for transparent decompression */
76struct RR_ZF{ 77struct RR_ZF_s {
77 char algorithm[2]; 78 char algorithm[2];
78 char parms[2]; 79 char parms[2];
79 char real_size[8]; 80 char real_size[8];
80}; 81};
81 82
82/* These are the bits and their meanings for flags in the TF structure. */ 83/*
84 * These are the bits and their meanings for flags in the TF structure.
85 */
83#define TF_CREATE 1 86#define TF_CREATE 1
84#define TF_MODIFY 2 87#define TF_MODIFY 2
85#define TF_ACCESS 4 88#define TF_ACCESS 4
@@ -89,31 +92,31 @@ struct RR_ZF{
89#define TF_EFFECTIVE 64 92#define TF_EFFECTIVE 64
90#define TF_LONG_FORM 128 93#define TF_LONG_FORM 128
91 94
92struct rock_ridge{ 95struct rock_ridge {
93 char signature[2]; 96 char signature[2];
94 unsigned char len; 97 unsigned char len;
95 unsigned char version; 98 unsigned char version;
96 union{ 99 union {
97 struct SU_SP SP; 100 struct SU_SP_s SP;
98 struct SU_CE CE; 101 struct SU_CE_s CE;
99 struct SU_ER ER; 102 struct SU_ER_s ER;
100 struct RR_RR RR; 103 struct RR_RR_s RR;
101 struct RR_PX PX; 104 struct RR_PX_s PX;
102 struct RR_PN PN; 105 struct RR_PN_s PN;
103 struct RR_SL SL; 106 struct RR_SL_s SL;
104 struct RR_NM NM; 107 struct RR_NM_s NM;
105 struct RR_CL CL; 108 struct RR_CL_s CL;
106 struct RR_PL PL; 109 struct RR_PL_s PL;
107 struct RR_TF TF; 110 struct RR_TF_s TF;
108 struct RR_ZF ZF; 111 struct RR_ZF_s ZF;
109 } u; 112 } u;
110}; 113};
111 114
112#define RR_PX 1 /* POSIX attributes */ 115#define RR_PX 1 /* POSIX attributes */
113#define RR_PN 2 /* POSIX devices */ 116#define RR_PN 2 /* POSIX devices */
114#define RR_SL 4 /* Symbolic link */ 117#define RR_SL 4 /* Symbolic link */
115#define RR_NM 8 /* Alternate Name */ 118#define RR_NM 8 /* Alternate Name */
116#define RR_CL 16 /* Child link */ 119#define RR_CL 16 /* Child link */
117#define RR_PL 32 /* Parent link */ 120#define RR_PL 32 /* Parent link */
118#define RR_RE 64 /* Relocation directory */ 121#define RR_RE 64 /* Relocation directory */
119#define RR_TF 128 /* Timestamps */ 122#define RR_TF 128 /* Timestamps */
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 98d830401c56..5a97e346bd95 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction)
188 } else { 188 } else {
189 jbd_unlock_bh_state(bh); 189 jbd_unlock_bh_state(bh);
190 } 190 }
191 jh = next_jh;
192 } while (jh != last_jh); 191 } while (jh != last_jh);
193 192
194 return ret; 193 return ret;
@@ -339,8 +338,10 @@ int log_do_checkpoint(journal_t *journal)
339 } 338 }
340 } while (jh != last_jh && !retry); 339 } while (jh != last_jh && !retry);
341 340
342 if (batch_count) 341 if (batch_count) {
343 __flush_batch(journal, bhs, &batch_count); 342 __flush_batch(journal, bhs, &batch_count);
343 retry = 1;
344 }
344 345
345 /* 346 /*
346 * If someone cleaned up this transaction while we slept, we're 347 * If someone cleaned up this transaction while we slept, we're
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 8d2a9ab981d4..30a2bf9eeda5 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -70,8 +70,7 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
70 if (!IS_ERR(acl)) 70 if (!IS_ERR(acl))
71 *p_acl = posix_acl_dup(acl); 71 *p_acl = posix_acl_dup(acl);
72 } 72 }
73 if (value) 73 kfree(value);
74 kfree(value);
75 return acl; 74 return acl;
76} 75}
77 76
@@ -112,8 +111,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
112 } 111 }
113 rc = __jfs_setxattr(inode, ea_name, value, size, 0); 112 rc = __jfs_setxattr(inode, ea_name, value, size, 0);
114out: 113out:
115 if (value) 114 kfree(value);
116 kfree(value);
117 115
118 if (!rc) { 116 if (!rc) {
119 if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED)) 117 if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED))
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index a87b06fa8ff8..c2c19c9ed9a4 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) International Business Machines Corp., 2000-2002 2 * Copyright (C) International Business Machines Corp., 2000-2002
3 * Portions Copyright (c) Christoph Hellwig, 2001-2002 3 * Portions Copyright (C) Christoph Hellwig, 2001-2002
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -19,16 +19,13 @@
19 19
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include "jfs_incore.h" 21#include "jfs_incore.h"
22#include "jfs_inode.h"
22#include "jfs_dmap.h" 23#include "jfs_dmap.h"
23#include "jfs_txnmgr.h" 24#include "jfs_txnmgr.h"
24#include "jfs_xattr.h" 25#include "jfs_xattr.h"
25#include "jfs_acl.h" 26#include "jfs_acl.h"
26#include "jfs_debug.h" 27#include "jfs_debug.h"
27 28
28
29extern int jfs_commit_inode(struct inode *, int);
30extern void jfs_truncate(struct inode *);
31
32int jfs_fsync(struct file *file, struct dentry *dentry, int datasync) 29int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
33{ 30{
34 struct inode *inode = dentry->d_inode; 31 struct inode *inode = dentry->d_inode;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 24a689179af2..2137138c59b0 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -23,6 +23,7 @@
23#include <linux/pagemap.h> 23#include <linux/pagemap.h>
24#include <linux/quotaops.h> 24#include <linux/quotaops.h>
25#include "jfs_incore.h" 25#include "jfs_incore.h"
26#include "jfs_inode.h"
26#include "jfs_filsys.h" 27#include "jfs_filsys.h"
27#include "jfs_imap.h" 28#include "jfs_imap.h"
28#include "jfs_extent.h" 29#include "jfs_extent.h"
@@ -30,14 +31,6 @@
30#include "jfs_debug.h" 31#include "jfs_debug.h"
31 32
32 33
33extern struct inode_operations jfs_dir_inode_operations;
34extern struct inode_operations jfs_file_inode_operations;
35extern struct inode_operations jfs_symlink_inode_operations;
36extern struct file_operations jfs_dir_operations;
37extern struct file_operations jfs_file_operations;
38struct address_space_operations jfs_aops;
39extern int freeZeroLink(struct inode *);
40
41void jfs_read_inode(struct inode *inode) 34void jfs_read_inode(struct inode *inode)
42{ 35{
43 if (diRead(inode)) { 36 if (diRead(inode)) {
@@ -136,7 +129,7 @@ void jfs_delete_inode(struct inode *inode)
136 jfs_info("In jfs_delete_inode, inode = 0x%p", inode); 129 jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
137 130
138 if (test_cflag(COMMIT_Freewmap, inode)) 131 if (test_cflag(COMMIT_Freewmap, inode))
139 freeZeroLink(inode); 132 jfs_free_zero_link(inode);
140 133
141 diFree(inode); 134 diFree(inode);
142 135
diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
index 91a0a889ebc5..4caea6b43b92 100644
--- a/fs/jfs/jfs_debug.c
+++ b/fs/jfs/jfs_debug.c
@@ -58,8 +58,6 @@ void dump_mem(char *label, void *data, int length)
58 58
59static struct proc_dir_entry *base; 59static struct proc_dir_entry *base;
60#ifdef CONFIG_JFS_DEBUG 60#ifdef CONFIG_JFS_DEBUG
61extern read_proc_t jfs_txanchor_read;
62
63static int loglevel_read(char *page, char **start, off_t off, 61static int loglevel_read(char *page, char **start, off_t off,
64 int count, int *eof, void *data) 62 int count, int *eof, void *data)
65{ 63{
@@ -97,14 +95,6 @@ static int loglevel_write(struct file *file, const char __user *buffer,
97} 95}
98#endif 96#endif
99 97
100
101#ifdef CONFIG_JFS_STATISTICS
102extern read_proc_t jfs_lmstats_read;
103extern read_proc_t jfs_txstats_read;
104extern read_proc_t jfs_xtstat_read;
105extern read_proc_t jfs_mpstat_read;
106#endif
107
108static struct { 98static struct {
109 const char *name; 99 const char *name;
110 read_proc_t *read_fn; 100 read_proc_t *read_fn;
diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h
index a38079ae1e00..ddffbbd4d955 100644
--- a/fs/jfs/jfs_debug.h
+++ b/fs/jfs/jfs_debug.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) International Business Machines Corp., 2000-2002 2 * Copyright (C) International Business Machines Corp., 2000-2002
3 * Portions Copyright (c) Christoph Hellwig, 2001-2002 3 * Portions Copyright (C) Christoph Hellwig, 2001-2002
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,9 @@
31 * CONFIG_JFS_DEBUG or CONFIG_JFS_STATISTICS is defined 31 * CONFIG_JFS_DEBUG or CONFIG_JFS_STATISTICS is defined
32 */ 32 */
33#if defined(CONFIG_PROC_FS) && (defined(CONFIG_JFS_DEBUG) || defined(CONFIG_JFS_STATISTICS)) 33#if defined(CONFIG_PROC_FS) && (defined(CONFIG_JFS_DEBUG) || defined(CONFIG_JFS_STATISTICS))
34 #define PROC_FS_JFS 34#define PROC_FS_JFS
35extern void jfs_proc_init(void);
36extern void jfs_proc_clean(void);
35#endif 37#endif
36 38
37/* 39/*
@@ -65,8 +67,8 @@
65 67
66extern int jfsloglevel; 68extern int jfsloglevel;
67 69
68/* dump memory contents */
69extern void dump_mem(char *label, void *data, int length); 70extern void dump_mem(char *label, void *data, int length);
71extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *);
70 72
71/* information message: e.g., configuration, major event */ 73/* information message: e.g., configuration, major event */
72#define jfs_info(fmt, arg...) do { \ 74#define jfs_info(fmt, arg...) do { \
@@ -110,6 +112,11 @@ extern void dump_mem(char *label, void *data, int length);
110 * ---------- 112 * ----------
111 */ 113 */
112#ifdef CONFIG_JFS_STATISTICS 114#ifdef CONFIG_JFS_STATISTICS
115extern int jfs_lmstats_read(char *, char **, off_t, int, int *, void *);
116extern int jfs_txstats_read(char *, char **, off_t, int, int *, void *);
117extern int jfs_mpstat_read(char *, char **, off_t, int, int *, void *);
118extern int jfs_xtstat_read(char *, char **, off_t, int, int *, void *);
119
113#define INCREMENT(x) ((x)++) 120#define INCREMENT(x) ((x)++)
114#define DECREMENT(x) ((x)--) 121#define DECREMENT(x) ((x)--)
115#define HIGHWATERMARK(x,y) ((x) = max((x), (y))) 122#define HIGHWATERMARK(x,y) ((x) = max((x), (y)))
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 69007fd546ef..cced2fed9d0f 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -272,7 +272,6 @@ int dbMount(struct inode *ipbmap)
272int dbUnmount(struct inode *ipbmap, int mounterror) 272int dbUnmount(struct inode *ipbmap, int mounterror)
273{ 273{
274 struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap; 274 struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
275 int i;
276 275
277 if (!(mounterror || isReadOnly(ipbmap))) 276 if (!(mounterror || isReadOnly(ipbmap)))
278 dbSync(ipbmap); 277 dbSync(ipbmap);
@@ -282,14 +281,6 @@ int dbUnmount(struct inode *ipbmap, int mounterror)
282 */ 281 */
283 truncate_inode_pages(ipbmap->i_mapping, 0); 282 truncate_inode_pages(ipbmap->i_mapping, 0);
284 283
285 /*
286 * Sanity Check
287 */
288 for (i = 0; i < bmp->db_numag; i++)
289 if (atomic_read(&bmp->db_active[i]))
290 printk(KERN_ERR "dbUnmount: db_active[%d] = %d\n",
291 i, atomic_read(&bmp->db_active[i]));
292
293 /* free the memory for the in-memory bmap. */ 284 /* free the memory for the in-memory bmap. */
294 kfree(bmp); 285 kfree(bmp);
295 286
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index ac41f72d6d50..8676aee3ae48 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -2931,6 +2931,9 @@ static void add_missing_indices(struct inode *inode, s64 bn)
2931 ASSERT(p->header.flag & BT_LEAF); 2931 ASSERT(p->header.flag & BT_LEAF);
2932 2932
2933 tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY); 2933 tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY);
2934 if (BT_IS_ROOT(mp))
2935 tlck->type |= tlckBTROOT;
2936
2934 dtlck = (struct dt_lock *) &tlck->lock; 2937 dtlck = (struct dt_lock *) &tlck->lock;
2935 2938
2936 stbl = DT_GETSTBL(p); 2939 stbl = DT_GETSTBL(p);
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index 1953acb79266..4879603daa1c 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -19,6 +19,7 @@
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/quotaops.h> 20#include <linux/quotaops.h>
21#include "jfs_incore.h" 21#include "jfs_incore.h"
22#include "jfs_inode.h"
22#include "jfs_superblock.h" 23#include "jfs_superblock.h"
23#include "jfs_dmap.h" 24#include "jfs_dmap.h"
24#include "jfs_extent.h" 25#include "jfs_extent.h"
@@ -33,12 +34,6 @@ static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
33#endif 34#endif
34static s64 extRoundDown(s64 nb); 35static s64 extRoundDown(s64 nb);
35 36
36/*
37 * external references
38 */
39extern int jfs_commit_inode(struct inode *, int);
40
41
42#define DPD(a) (printk("(a): %d\n",(a))) 37#define DPD(a) (printk("(a): %d\n",(a)))
43#define DPC(a) (printk("(a): %c\n",(a))) 38#define DPC(a) (printk("(a): %c\n",(a)))
44#define DPL1(a) \ 39#define DPL1(a) \
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 7acff2ce3c80..971af2977eff 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -47,6 +47,7 @@
47#include <linux/quotaops.h> 47#include <linux/quotaops.h>
48 48
49#include "jfs_incore.h" 49#include "jfs_incore.h"
50#include "jfs_inode.h"
50#include "jfs_filsys.h" 51#include "jfs_filsys.h"
51#include "jfs_dinode.h" 52#include "jfs_dinode.h"
52#include "jfs_dmap.h" 53#include "jfs_dmap.h"
@@ -69,11 +70,6 @@
69#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno]) 70#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno])
70 71
71/* 72/*
72 * external references
73 */
74extern struct address_space_operations jfs_aops;
75
76/*
77 * forward references 73 * forward references
78 */ 74 */
79static int diAllocAG(struct inomap *, int, boolean_t, struct inode *); 75static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index 84f2459b2191..2af5efbfd06f 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -19,6 +19,7 @@
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/quotaops.h> 20#include <linux/quotaops.h>
21#include "jfs_incore.h" 21#include "jfs_incore.h"
22#include "jfs_inode.h"
22#include "jfs_filsys.h" 23#include "jfs_filsys.h"
23#include "jfs_imap.h" 24#include "jfs_imap.h"
24#include "jfs_dinode.h" 25#include "jfs_dinode.h"
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 3df91fbfe781..b54bac576cb3 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) International Business Machines Corp., 2000-2001 2 * Copyright (C) International Business Machines Corp., 2000-2001
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -19,5 +19,22 @@
19#define _H_JFS_INODE 19#define _H_JFS_INODE
20 20
21extern struct inode *ialloc(struct inode *, umode_t); 21extern struct inode *ialloc(struct inode *, umode_t);
22extern int jfs_fsync(struct file *, struct dentry *, int);
23extern void jfs_read_inode(struct inode *);
24extern int jfs_commit_inode(struct inode *, int);
25extern int jfs_write_inode(struct inode*, int);
26extern void jfs_delete_inode(struct inode *);
27extern void jfs_dirty_inode(struct inode *);
28extern void jfs_truncate(struct inode *);
29extern void jfs_truncate_nolock(struct inode *, loff_t);
30extern void jfs_free_zero_link(struct inode *);
31extern struct dentry *jfs_get_parent(struct dentry *dentry);
22 32
33extern struct address_space_operations jfs_aops;
34extern struct inode_operations jfs_dir_inode_operations;
35extern struct file_operations jfs_dir_operations;
36extern struct inode_operations jfs_file_inode_operations;
37extern struct file_operations jfs_file_operations;
38extern struct inode_operations jfs_symlink_inode_operations;
39extern struct dentry_operations jfs_ci_dentry_operations;
23#endif /* _H_JFS_INODE */ 40#endif /* _H_JFS_INODE */
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index dfa1200daa61..7c8387ed4192 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -71,6 +71,7 @@
71#include "jfs_incore.h" 71#include "jfs_incore.h"
72#include "jfs_filsys.h" 72#include "jfs_filsys.h"
73#include "jfs_metapage.h" 73#include "jfs_metapage.h"
74#include "jfs_superblock.h"
74#include "jfs_txnmgr.h" 75#include "jfs_txnmgr.h"
75#include "jfs_debug.h" 76#include "jfs_debug.h"
76 77
@@ -167,14 +168,6 @@ static struct jfs_log *dummy_log = NULL;
167static DECLARE_MUTEX(jfs_log_sem); 168static DECLARE_MUTEX(jfs_log_sem);
168 169
169/* 170/*
170 * external references
171 */
172extern void txLazyUnlock(struct tblock * tblk);
173extern int jfs_stop_threads;
174extern struct completion jfsIOwait;
175extern int jfs_tlocks_low;
176
177/*
178 * forward references 171 * forward references
179 */ 172 */
180static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk, 173static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk,
@@ -1624,6 +1617,8 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
1624 } 1617 }
1625 } 1618 }
1626 assert(list_empty(&log->cqueue)); 1619 assert(list_empty(&log->cqueue));
1620
1621#ifdef CONFIG_JFS_DEBUG
1627 if (!list_empty(&log->synclist)) { 1622 if (!list_empty(&log->synclist)) {
1628 struct logsyncblk *lp; 1623 struct logsyncblk *lp;
1629 1624
@@ -1638,9 +1633,8 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
1638 dump_mem("orphan tblock", lp, 1633 dump_mem("orphan tblock", lp,
1639 sizeof(struct tblock)); 1634 sizeof(struct tblock));
1640 } 1635 }
1641// current->state = TASK_INTERRUPTIBLE;
1642// schedule();
1643 } 1636 }
1637#endif
1644 //assert(list_empty(&log->synclist)); 1638 //assert(list_empty(&log->synclist));
1645 clear_bit(log_FLUSH, &log->flag); 1639 clear_bit(log_FLUSH, &log->flag);
1646} 1640}
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index 51291fbc420c..747114cd38b8 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -507,6 +507,8 @@ extern int lmLogClose(struct super_block *sb);
507extern int lmLogShutdown(struct jfs_log * log); 507extern int lmLogShutdown(struct jfs_log * log);
508extern int lmLogInit(struct jfs_log * log); 508extern int lmLogInit(struct jfs_log * log);
509extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize); 509extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize);
510extern int lmGroupCommit(struct jfs_log *, struct tblock *);
511extern int jfsIOWait(void *);
510extern void jfs_flush_journal(struct jfs_log * log, int wait); 512extern void jfs_flush_journal(struct jfs_log * log, int wait);
511extern void jfs_syncpt(struct jfs_log *log); 513extern void jfs_syncpt(struct jfs_log *log);
512 514
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 41bf078dce05..6c5485d16c39 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -198,7 +198,7 @@ static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
198 } 198 }
199} 199}
200 200
201static inline struct metapage *alloc_metapage(int gfp_mask) 201static inline struct metapage *alloc_metapage(unsigned int gfp_mask)
202{ 202{
203 return mempool_alloc(metapage_mempool, gfp_mask); 203 return mempool_alloc(metapage_mempool, gfp_mask);
204} 204}
@@ -726,12 +726,12 @@ void force_metapage(struct metapage *mp)
726 page_cache_release(page); 726 page_cache_release(page);
727} 727}
728 728
729extern void hold_metapage(struct metapage *mp) 729void hold_metapage(struct metapage *mp)
730{ 730{
731 lock_page(mp->page); 731 lock_page(mp->page);
732} 732}
733 733
734extern void put_metapage(struct metapage *mp) 734void put_metapage(struct metapage *mp)
735{ 735{
736 if (mp->count || mp->nohomeok) { 736 if (mp->count || mp->nohomeok) {
737 /* Someone else will release this */ 737 /* Someone else will release this */
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
index 991e9fb84c75..f0b7d3282b07 100644
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) International Business Machines Corp., 2000-2002 2 * Copyright (C) International Business Machines Corp., 2000-2002
3 * Portions Copyright (c) Christoph Hellwig, 2001-2002 3 * Portions Copyright (C) Christoph Hellwig, 2001-2002
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -58,6 +58,8 @@ struct metapage {
58#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag) 58#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
59 59
60/* function prototypes */ 60/* function prototypes */
61extern int metapage_init(void);
62extern void metapage_exit(void);
61extern struct metapage *__get_metapage(struct inode *inode, 63extern struct metapage *__get_metapage(struct inode *inode,
62 unsigned long lblock, unsigned int size, 64 unsigned long lblock, unsigned int size,
63 int absolute, unsigned long new); 65 int absolute, unsigned long new);
diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h
index ab0566f70cfa..fcf781bf31cb 100644
--- a/fs/jfs/jfs_superblock.h
+++ b/fs/jfs/jfs_superblock.h
@@ -109,5 +109,16 @@ struct jfs_superblock {
109extern int readSuper(struct super_block *, struct buffer_head **); 109extern int readSuper(struct super_block *, struct buffer_head **);
110extern int updateSuper(struct super_block *, uint); 110extern int updateSuper(struct super_block *, uint);
111extern void jfs_error(struct super_block *, const char *, ...); 111extern void jfs_error(struct super_block *, const char *, ...);
112extern int jfs_mount(struct super_block *);
113extern int jfs_mount_rw(struct super_block *, int);
114extern int jfs_umount(struct super_block *);
115extern int jfs_umount_rw(struct super_block *);
116
117extern int jfs_stop_threads;
118extern struct completion jfsIOwait;
119extern wait_queue_head_t jfs_IO_thread_wait;
120extern wait_queue_head_t jfs_commit_thread_wait;
121extern wait_queue_head_t jfs_sync_thread_wait;
122extern int jfs_extendfs(struct super_block *, s64, int);
112 123
113#endif /*_H_JFS_SUPERBLOCK */ 124#endif /*_H_JFS_SUPERBLOCK */
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index e93d01aa12c4..8cbaaff1d5fa 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -42,7 +42,6 @@
42 * hold on to mp+lock thru update of maps 42 * hold on to mp+lock thru update of maps
43 */ 43 */
44 44
45
46#include <linux/fs.h> 45#include <linux/fs.h>
47#include <linux/vmalloc.h> 46#include <linux/vmalloc.h>
48#include <linux/smp_lock.h> 47#include <linux/smp_lock.h>
@@ -51,6 +50,7 @@
51#include <linux/module.h> 50#include <linux/module.h>
52#include <linux/moduleparam.h> 51#include <linux/moduleparam.h>
53#include "jfs_incore.h" 52#include "jfs_incore.h"
53#include "jfs_inode.h"
54#include "jfs_filsys.h" 54#include "jfs_filsys.h"
55#include "jfs_metapage.h" 55#include "jfs_metapage.h"
56#include "jfs_dinode.h" 56#include "jfs_dinode.h"
@@ -109,7 +109,6 @@ static int TxLockHWM; /* High water mark for number of txLocks used */
109static int TxLockVHWM; /* Very High water mark */ 109static int TxLockVHWM; /* Very High water mark */
110struct tlock *TxLock; /* transaction lock table */ 110struct tlock *TxLock; /* transaction lock table */
111 111
112
113/* 112/*
114 * transaction management lock 113 * transaction management lock
115 */ 114 */
@@ -149,7 +148,6 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
149 148
150#define TXN_WAKEUP(event) wake_up_all(event) 149#define TXN_WAKEUP(event) wake_up_all(event)
151 150
152
153/* 151/*
154 * statistics 152 * statistics
155 */ 153 */
@@ -161,16 +159,6 @@ static struct {
161 int waitlock; /* 4: # of tlock wait */ 159 int waitlock; /* 4: # of tlock wait */
162} stattx; 160} stattx;
163 161
164
165/*
166 * external references
167 */
168extern int lmGroupCommit(struct jfs_log *, struct tblock *);
169extern int jfs_commit_inode(struct inode *, int);
170extern int jfs_stop_threads;
171
172extern struct completion jfsIOwait;
173
174/* 162/*
175 * forward references 163 * forward references
176 */ 164 */
@@ -358,7 +346,6 @@ void txExit(void)
358 TxBlock = NULL; 346 TxBlock = NULL;
359} 347}
360 348
361
362/* 349/*
363 * NAME: txBegin() 350 * NAME: txBegin()
364 * 351 *
@@ -460,7 +447,6 @@ tid_t txBegin(struct super_block *sb, int flag)
460 return t; 447 return t;
461} 448}
462 449
463
464/* 450/*
465 * NAME: txBeginAnon() 451 * NAME: txBeginAnon()
466 * 452 *
@@ -503,7 +489,6 @@ void txBeginAnon(struct super_block *sb)
503 TXN_UNLOCK(); 489 TXN_UNLOCK();
504} 490}
505 491
506
507/* 492/*
508 * txEnd() 493 * txEnd()
509 * 494 *
@@ -592,7 +577,6 @@ wakeup:
592 TXN_WAKEUP(&TxAnchor.freewait); 577 TXN_WAKEUP(&TxAnchor.freewait);
593} 578}
594 579
595
596/* 580/*
597 * txLock() 581 * txLock()
598 * 582 *
@@ -868,7 +852,6 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
868 return NULL; 852 return NULL;
869} 853}
870 854
871
872/* 855/*
873 * NAME: txRelease() 856 * NAME: txRelease()
874 * 857 *
@@ -908,7 +891,6 @@ static void txRelease(struct tblock * tblk)
908 TXN_UNLOCK(); 891 TXN_UNLOCK();
909} 892}
910 893
911
912/* 894/*
913 * NAME: txUnlock() 895 * NAME: txUnlock()
914 * 896 *
@@ -996,7 +978,6 @@ static void txUnlock(struct tblock * tblk)
996 } 978 }
997} 979}
998 980
999
1000/* 981/*
1001 * txMaplock() 982 * txMaplock()
1002 * 983 *
@@ -1069,7 +1050,6 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
1069 return tlck; 1050 return tlck;
1070} 1051}
1071 1052
1072
1073/* 1053/*
1074 * txLinelock() 1054 * txLinelock()
1075 * 1055 *
@@ -1103,8 +1083,6 @@ struct linelock *txLinelock(struct linelock * tlock)
1103 return linelock; 1083 return linelock;
1104} 1084}
1105 1085
1106
1107
1108/* 1086/*
1109 * transaction commit management 1087 * transaction commit management
1110 * ----------------------------- 1088 * -----------------------------
@@ -1373,7 +1351,6 @@ int txCommit(tid_t tid, /* transaction identifier */
1373 return rc; 1351 return rc;
1374} 1352}
1375 1353
1376
1377/* 1354/*
1378 * NAME: txLog() 1355 * NAME: txLog()
1379 * 1356 *
@@ -1437,7 +1414,6 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
1437 return rc; 1414 return rc;
1438} 1415}
1439 1416
1440
1441/* 1417/*
1442 * diLog() 1418 * diLog()
1443 * 1419 *
@@ -1465,7 +1441,6 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1465 if (tlck->type & tlckENTRY) { 1441 if (tlck->type & tlckENTRY) {
1466 /* log after-image for logredo(): */ 1442 /* log after-image for logredo(): */
1467 lrd->type = cpu_to_le16(LOG_REDOPAGE); 1443 lrd->type = cpu_to_le16(LOG_REDOPAGE);
1468// *pxd = mp->cm_pxd;
1469 PXDaddress(pxd, mp->index); 1444 PXDaddress(pxd, mp->index);
1470 PXDlength(pxd, 1445 PXDlength(pxd,
1471 mp->logical_size >> tblk->sb->s_blocksize_bits); 1446 mp->logical_size >> tblk->sb->s_blocksize_bits);
@@ -1552,7 +1527,6 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1552 return rc; 1527 return rc;
1553} 1528}
1554 1529
1555
1556/* 1530/*
1557 * dataLog() 1531 * dataLog()
1558 * 1532 *
@@ -1599,7 +1573,6 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1599 return 0; 1573 return 0;
1600} 1574}
1601 1575
1602
1603/* 1576/*
1604 * dtLog() 1577 * dtLog()
1605 * 1578 *
@@ -1639,7 +1612,6 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1639 lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND); 1612 lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND);
1640 else 1613 else
1641 lrd->log.redopage.type |= cpu_to_le16(LOG_NEW); 1614 lrd->log.redopage.type |= cpu_to_le16(LOG_NEW);
1642// *pxd = mp->cm_pxd;
1643 PXDaddress(pxd, mp->index); 1615 PXDaddress(pxd, mp->index);
1644 PXDlength(pxd, 1616 PXDlength(pxd,
1645 mp->logical_size >> tblk->sb->s_blocksize_bits); 1617 mp->logical_size >> tblk->sb->s_blocksize_bits);
@@ -1704,7 +1676,6 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1704 return; 1676 return;
1705} 1677}
1706 1678
1707
1708/* 1679/*
1709 * xtLog() 1680 * xtLog()
1710 * 1681 *
@@ -1760,7 +1731,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1760 * applying the after-image to the meta-data page. 1731 * applying the after-image to the meta-data page.
1761 */ 1732 */
1762 lrd->type = cpu_to_le16(LOG_REDOPAGE); 1733 lrd->type = cpu_to_le16(LOG_REDOPAGE);
1763// *page_pxd = mp->cm_pxd;
1764 PXDaddress(page_pxd, mp->index); 1734 PXDaddress(page_pxd, mp->index);
1765 PXDlength(page_pxd, 1735 PXDlength(page_pxd,
1766 mp->logical_size >> tblk->sb->s_blocksize_bits); 1736 mp->logical_size >> tblk->sb->s_blocksize_bits);
@@ -2093,7 +2063,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
2093 return; 2063 return;
2094} 2064}
2095 2065
2096
2097/* 2066/*
2098 * mapLog() 2067 * mapLog()
2099 * 2068 *
@@ -2180,7 +2149,6 @@ void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
2180 } 2149 }
2181} 2150}
2182 2151
2183
2184/* 2152/*
2185 * txEA() 2153 * txEA()
2186 * 2154 *
@@ -2233,7 +2201,6 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
2233 } 2201 }
2234} 2202}
2235 2203
2236
2237/* 2204/*
2238 * txForce() 2205 * txForce()
2239 * 2206 *
@@ -2300,7 +2267,6 @@ void txForce(struct tblock * tblk)
2300 } 2267 }
2301} 2268}
2302 2269
2303
2304/* 2270/*
2305 * txUpdateMap() 2271 * txUpdateMap()
2306 * 2272 *
@@ -2437,7 +2403,6 @@ static void txUpdateMap(struct tblock * tblk)
2437 } 2403 }
2438} 2404}
2439 2405
2440
2441/* 2406/*
2442 * txAllocPMap() 2407 * txAllocPMap()
2443 * 2408 *
@@ -2509,7 +2474,6 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
2509 } 2474 }
2510} 2475}
2511 2476
2512
2513/* 2477/*
2514 * txFreeMap() 2478 * txFreeMap()
2515 * 2479 *
@@ -2611,7 +2575,6 @@ void txFreeMap(struct inode *ip,
2611 } 2575 }
2612} 2576}
2613 2577
2614
2615/* 2578/*
2616 * txFreelock() 2579 * txFreelock()
2617 * 2580 *
@@ -2652,7 +2615,6 @@ void txFreelock(struct inode *ip)
2652 TXN_UNLOCK(); 2615 TXN_UNLOCK();
2653} 2616}
2654 2617
2655
2656/* 2618/*
2657 * txAbort() 2619 * txAbort()
2658 * 2620 *
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
index b71b82c2df04..59ad0f6b7231 100644
--- a/fs/jfs/jfs_txnmgr.h
+++ b/fs/jfs/jfs_txnmgr.h
@@ -285,34 +285,26 @@ struct commit {
285/* 285/*
286 * external declarations 286 * external declarations
287 */ 287 */
288extern struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage *mp, 288extern int jfs_tlocks_low;
289 int flag); 289
290 290extern int txInit(void);
291extern struct tlock *txMaplock(tid_t tid, struct inode *ip, int flag); 291extern void txExit(void);
292 292extern struct tlock *txLock(tid_t, struct inode *, struct metapage *, int);
293extern int txCommit(tid_t tid, int nip, struct inode **iplist, int flag); 293extern struct tlock *txMaplock(tid_t, struct inode *, int);
294 294extern int txCommit(tid_t, int, struct inode **, int);
295extern tid_t txBegin(struct super_block *sb, int flag); 295extern tid_t txBegin(struct super_block *, int);
296 296extern void txBeginAnon(struct super_block *);
297extern void txBeginAnon(struct super_block *sb); 297extern void txEnd(tid_t);
298 298extern void txAbort(tid_t, int);
299extern void txEnd(tid_t tid); 299extern struct linelock *txLinelock(struct linelock *);
300 300extern void txFreeMap(struct inode *, struct maplock *, struct tblock *, int);
301extern void txAbort(tid_t tid, int dirty); 301extern void txEA(tid_t, struct inode *, dxd_t *, dxd_t *);
302 302extern void txFreelock(struct inode *);
303extern struct linelock *txLinelock(struct linelock * tlock); 303extern int lmLog(struct jfs_log *, struct tblock *, struct lrd *,
304 304 struct tlock *);
305extern void txFreeMap(struct inode *ip, struct maplock * maplock, 305extern void txQuiesce(struct super_block *);
306 struct tblock * tblk, int maptype); 306extern void txResume(struct super_block *);
307 307extern void txLazyUnlock(struct tblock *);
308extern void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea); 308extern int jfs_lazycommit(void *);
309 309extern int jfs_sync(void *);
310extern void txFreelock(struct inode *ip);
311
312extern int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
313 struct tlock * tlck);
314
315extern void txQuiesce(struct super_block *sb);
316
317extern void txResume(struct super_block *sb);
318#endif /* _H_JFS_TXNMGR */ 310#endif /* _H_JFS_TXNMGR */
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 8413a368f449..1cae14e741eb 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -31,20 +31,9 @@
31#include "jfs_acl.h" 31#include "jfs_acl.h"
32#include "jfs_debug.h" 32#include "jfs_debug.h"
33 33
34extern struct inode_operations jfs_file_inode_operations;
35extern struct inode_operations jfs_symlink_inode_operations;
36extern struct file_operations jfs_file_operations;
37extern struct address_space_operations jfs_aops;
38
39extern int jfs_fsync(struct file *, struct dentry *, int);
40extern void jfs_truncate_nolock(struct inode *, loff_t);
41extern int jfs_init_acl(struct inode *, struct inode *);
42
43/* 34/*
44 * forward references 35 * forward references
45 */ 36 */
46struct inode_operations jfs_dir_inode_operations;
47struct file_operations jfs_dir_operations;
48struct dentry_operations jfs_ci_dentry_operations; 37struct dentry_operations jfs_ci_dentry_operations;
49 38
50static s64 commitZeroLink(tid_t, struct inode *); 39static s64 commitZeroLink(tid_t, struct inode *);
@@ -655,7 +644,7 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
655 644
656 645
657/* 646/*
658 * NAME: freeZeroLink() 647 * NAME: jfs_free_zero_link()
659 * 648 *
660 * FUNCTION: for non-directory, called by iClose(), 649 * FUNCTION: for non-directory, called by iClose(),
661 * free resources of a file from cache and WORKING map 650 * free resources of a file from cache and WORKING map
@@ -663,15 +652,12 @@ static s64 commitZeroLink(tid_t tid, struct inode *ip)
663 * while associated with a pager object, 652 * while associated with a pager object,
664 * 653 *
665 * PARAMETER: ip - pointer to inode of file. 654 * PARAMETER: ip - pointer to inode of file.
666 *
667 * RETURN: 0 -ok
668 */ 655 */
669int freeZeroLink(struct inode *ip) 656void jfs_free_zero_link(struct inode *ip)
670{ 657{
671 int rc = 0;
672 int type; 658 int type;
673 659
674 jfs_info("freeZeroLink: ip = 0x%p", ip); 660 jfs_info("jfs_free_zero_link: ip = 0x%p", ip);
675 661
676 /* return if not reg or symbolic link or if size is 662 /* return if not reg or symbolic link or if size is
677 * already ok. 663 * already ok.
@@ -684,10 +670,10 @@ int freeZeroLink(struct inode *ip)
684 case S_IFLNK: 670 case S_IFLNK:
685 /* if its contained in inode nothing to do */ 671 /* if its contained in inode nothing to do */
686 if (ip->i_size < IDATASIZE) 672 if (ip->i_size < IDATASIZE)
687 return 0; 673 return;
688 break; 674 break;
689 default: 675 default:
690 return 0; 676 return;
691 } 677 }
692 678
693 /* 679 /*
@@ -737,9 +723,7 @@ int freeZeroLink(struct inode *ip)
737 * free xtree/data blocks from working block map; 723 * free xtree/data blocks from working block map;
738 */ 724 */
739 if (ip->i_size) 725 if (ip->i_size)
740 rc = xtTruncate(0, ip, 0, COMMIT_WMAP); 726 xtTruncate(0, ip, 0, COMMIT_WMAP);
741
742 return rc;
743} 727}
744 728
745/* 729/*
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 5e774ed7fb64..810a3653d8b3 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -28,6 +28,7 @@
28 28
29#include "jfs_incore.h" 29#include "jfs_incore.h"
30#include "jfs_filsys.h" 30#include "jfs_filsys.h"
31#include "jfs_inode.h"
31#include "jfs_metapage.h" 32#include "jfs_metapage.h"
32#include "jfs_superblock.h" 33#include "jfs_superblock.h"
33#include "jfs_dmap.h" 34#include "jfs_dmap.h"
@@ -62,37 +63,6 @@ module_param(jfsloglevel, int, 0644);
62MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)"); 63MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)");
63#endif 64#endif
64 65
65/*
66 * External declarations
67 */
68extern int jfs_mount(struct super_block *);
69extern int jfs_mount_rw(struct super_block *, int);
70extern int jfs_umount(struct super_block *);
71extern int jfs_umount_rw(struct super_block *);
72
73extern int jfsIOWait(void *);
74extern int jfs_lazycommit(void *);
75extern int jfs_sync(void *);
76
77extern void jfs_read_inode(struct inode *inode);
78extern void jfs_dirty_inode(struct inode *inode);
79extern void jfs_delete_inode(struct inode *inode);
80extern int jfs_write_inode(struct inode *inode, int wait);
81
82extern struct dentry *jfs_get_parent(struct dentry *dentry);
83extern int jfs_extendfs(struct super_block *, s64, int);
84
85extern struct dentry_operations jfs_ci_dentry_operations;
86
87#ifdef PROC_FS_JFS /* see jfs_debug.h */
88extern void jfs_proc_init(void);
89extern void jfs_proc_clean(void);
90#endif
91
92extern wait_queue_head_t jfs_IO_thread_wait;
93extern wait_queue_head_t jfs_commit_thread_wait;
94extern wait_queue_head_t jfs_sync_thread_wait;
95
96static void jfs_handle_error(struct super_block *sb) 66static void jfs_handle_error(struct super_block *sb)
97{ 67{
98 struct jfs_sb_info *sbi = JFS_SBI(sb); 68 struct jfs_sb_info *sbi = JFS_SBI(sb);
@@ -593,11 +563,6 @@ static struct file_system_type jfs_fs_type = {
593 .fs_flags = FS_REQUIRES_DEV, 563 .fs_flags = FS_REQUIRES_DEV,
594}; 564};
595 565
596extern int metapage_init(void);
597extern int txInit(void);
598extern void txExit(void);
599extern void metapage_exit(void);
600
601static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) 566static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
602{ 567{
603 struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; 568 struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index ef4c07ee92b2..287d8d6c3cfd 100644
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) Christoph Hellwig, 2001-2002 2 * Copyright (C) Christoph Hellwig, 2001-2002
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/namei.h> 20#include <linux/namei.h>
21#include "jfs_incore.h" 21#include "jfs_incore.h"
22#include "jfs_inode.h"
22#include "jfs_xattr.h" 23#include "jfs_xattr.h"
23 24
24static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd) 25static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 7a9ffd5d03dc..6016373701a3 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -946,8 +946,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
946 out: 946 out:
947 up_write(&JFS_IP(inode)->xattr_sem); 947 up_write(&JFS_IP(inode)->xattr_sem);
948 948
949 if (os2name) 949 kfree(os2name);
950 kfree(os2name);
951 950
952 return rc; 951 return rc;
953} 952}
@@ -1042,8 +1041,7 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
1042 out: 1041 out:
1043 up_read(&JFS_IP(inode)->xattr_sem); 1042 up_read(&JFS_IP(inode)->xattr_sem);
1044 1043
1045 if (os2name) 1044 kfree(os2name);
1046 kfree(os2name);
1047 1045
1048 return size; 1046 return size;
1049} 1047}
diff --git a/fs/libfs.c b/fs/libfs.c
index f90b29595927..5025563e7379 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -519,6 +519,102 @@ int simple_transaction_release(struct inode *inode, struct file *file)
519 return 0; 519 return 0;
520} 520}
521 521
522/* Simple attribute files */
523
524struct simple_attr {
525 u64 (*get)(void *);
526 void (*set)(void *, u64);
527 char get_buf[24]; /* enough to store a u64 and "\n\0" */
528 char set_buf[24];
529 void *data;
530 const char *fmt; /* format for read operation */
531 struct semaphore sem; /* protects access to these buffers */
532};
533
534/* simple_attr_open is called by an actual attribute open file operation
535 * to set the attribute specific access operations. */
536int simple_attr_open(struct inode *inode, struct file *file,
537 u64 (*get)(void *), void (*set)(void *, u64),
538 const char *fmt)
539{
540 struct simple_attr *attr;
541
542 attr = kmalloc(sizeof(*attr), GFP_KERNEL);
543 if (!attr)
544 return -ENOMEM;
545
546 attr->get = get;
547 attr->set = set;
548 attr->data = inode->u.generic_ip;
549 attr->fmt = fmt;
550 init_MUTEX(&attr->sem);
551
552 file->private_data = attr;
553
554 return nonseekable_open(inode, file);
555}
556
557int simple_attr_close(struct inode *inode, struct file *file)
558{
559 kfree(file->private_data);
560 return 0;
561}
562
563/* read from the buffer that is filled with the get function */
564ssize_t simple_attr_read(struct file *file, char __user *buf,
565 size_t len, loff_t *ppos)
566{
567 struct simple_attr *attr;
568 size_t size;
569 ssize_t ret;
570
571 attr = file->private_data;
572
573 if (!attr->get)
574 return -EACCES;
575
576 down(&attr->sem);
577 if (*ppos) /* continued read */
578 size = strlen(attr->get_buf);
579 else /* first read */
580 size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
581 attr->fmt,
582 (unsigned long long)attr->get(attr->data));
583
584 ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
585 up(&attr->sem);
586 return ret;
587}
588
589/* interpret the buffer as a number to call the set function with */
590ssize_t simple_attr_write(struct file *file, const char __user *buf,
591 size_t len, loff_t *ppos)
592{
593 struct simple_attr *attr;
594 u64 val;
595 size_t size;
596 ssize_t ret;
597
598 attr = file->private_data;
599
600 if (!attr->set)
601 return -EACCES;
602
603 down(&attr->sem);
604 ret = -EFAULT;
605 size = min(sizeof(attr->set_buf) - 1, len);
606 if (copy_from_user(attr->set_buf, buf, size))
607 goto out;
608
609 ret = len; /* claim we got the whole input */
610 attr->set_buf[size] = '\0';
611 val = simple_strtol(attr->set_buf, NULL, 0);
612 attr->set(attr->data, val);
613out:
614 up(&attr->sem);
615 return ret;
616}
617
522EXPORT_SYMBOL(dcache_dir_close); 618EXPORT_SYMBOL(dcache_dir_close);
523EXPORT_SYMBOL(dcache_dir_lseek); 619EXPORT_SYMBOL(dcache_dir_lseek);
524EXPORT_SYMBOL(dcache_dir_open); 620EXPORT_SYMBOL(dcache_dir_open);
@@ -547,3 +643,7 @@ EXPORT_SYMBOL(simple_read_from_buffer);
547EXPORT_SYMBOL(simple_transaction_get); 643EXPORT_SYMBOL(simple_transaction_get);
548EXPORT_SYMBOL(simple_transaction_read); 644EXPORT_SYMBOL(simple_transaction_read);
549EXPORT_SYMBOL(simple_transaction_release); 645EXPORT_SYMBOL(simple_transaction_release);
646EXPORT_SYMBOL_GPL(simple_attr_open);
647EXPORT_SYMBOL_GPL(simple_attr_close);
648EXPORT_SYMBOL_GPL(simple_attr_read);
649EXPORT_SYMBOL_GPL(simple_attr_write);
diff --git a/fs/mpage.c b/fs/mpage.c
index b92c0e64aefa..bb9aebe93862 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -79,8 +79,11 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
79 if (--bvec >= bio->bi_io_vec) 79 if (--bvec >= bio->bi_io_vec)
80 prefetchw(&bvec->bv_page->flags); 80 prefetchw(&bvec->bv_page->flags);
81 81
82 if (!uptodate) 82 if (!uptodate){
83 SetPageError(page); 83 SetPageError(page);
84 if (page->mapping)
85 set_bit(AS_EIO, &page->mapping->flags);
86 }
84 end_page_writeback(page); 87 end_page_writeback(page);
85 } while (bvec >= bio->bi_io_vec); 88 } while (bvec >= bio->bi_io_vec);
86 bio_put(bio); 89 bio_put(bio);
diff --git a/fs/namei.c b/fs/namei.c
index dd78f01b6de8..a7f7f44119b3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -493,12 +493,21 @@ fail:
493 return PTR_ERR(link); 493 return PTR_ERR(link);
494} 494}
495 495
496static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) 496struct path {
497 struct vfsmount *mnt;
498 struct dentry *dentry;
499};
500
501static inline int __do_follow_link(struct path *path, struct nameidata *nd)
497{ 502{
498 int error; 503 int error;
504 struct dentry *dentry = path->dentry;
499 505
500 touch_atime(nd->mnt, dentry); 506 touch_atime(path->mnt, dentry);
501 nd_set_link(nd, NULL); 507 nd_set_link(nd, NULL);
508
509 if (path->mnt == nd->mnt)
510 mntget(path->mnt);
502 error = dentry->d_inode->i_op->follow_link(dentry, nd); 511 error = dentry->d_inode->i_op->follow_link(dentry, nd);
503 if (!error) { 512 if (!error) {
504 char *s = nd_get_link(nd); 513 char *s = nd_get_link(nd);
@@ -507,6 +516,8 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
507 if (dentry->d_inode->i_op->put_link) 516 if (dentry->d_inode->i_op->put_link)
508 dentry->d_inode->i_op->put_link(dentry, nd); 517 dentry->d_inode->i_op->put_link(dentry, nd);
509 } 518 }
519 dput(dentry);
520 mntput(path->mnt);
510 521
511 return error; 522 return error;
512} 523}
@@ -518,7 +529,7 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
518 * Without that kind of total limit, nasty chains of consecutive 529 * Without that kind of total limit, nasty chains of consecutive
519 * symlinks can cause almost arbitrarily long lookups. 530 * symlinks can cause almost arbitrarily long lookups.
520 */ 531 */
521static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) 532static inline int do_follow_link(struct path *path, struct nameidata *nd)
522{ 533{
523 int err = -ELOOP; 534 int err = -ELOOP;
524 if (current->link_count >= MAX_NESTED_LINKS) 535 if (current->link_count >= MAX_NESTED_LINKS)
@@ -527,17 +538,20 @@ static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
527 goto loop; 538 goto loop;
528 BUG_ON(nd->depth >= MAX_NESTED_LINKS); 539 BUG_ON(nd->depth >= MAX_NESTED_LINKS);
529 cond_resched(); 540 cond_resched();
530 err = security_inode_follow_link(dentry, nd); 541 err = security_inode_follow_link(path->dentry, nd);
531 if (err) 542 if (err)
532 goto loop; 543 goto loop;
533 current->link_count++; 544 current->link_count++;
534 current->total_link_count++; 545 current->total_link_count++;
535 nd->depth++; 546 nd->depth++;
536 err = __do_follow_link(dentry, nd); 547 err = __do_follow_link(path, nd);
537 current->link_count--; 548 current->link_count--;
538 nd->depth--; 549 nd->depth--;
539 return err; 550 return err;
540loop: 551loop:
552 dput(path->dentry);
553 if (path->mnt != nd->mnt)
554 mntput(path->mnt);
541 path_release(nd); 555 path_release(nd);
542 return err; 556 return err;
543} 557}
@@ -565,87 +579,91 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry)
565/* no need for dcache_lock, as serialization is taken care in 579/* no need for dcache_lock, as serialization is taken care in
566 * namespace.c 580 * namespace.c
567 */ 581 */
568static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) 582static int __follow_mount(struct path *path)
569{ 583{
570 int res = 0; 584 int res = 0;
585 while (d_mountpoint(path->dentry)) {
586 struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
587 if (!mounted)
588 break;
589 dput(path->dentry);
590 if (res)
591 mntput(path->mnt);
592 path->mnt = mounted;
593 path->dentry = dget(mounted->mnt_root);
594 res = 1;
595 }
596 return res;
597}
598
599static void follow_mount(struct vfsmount **mnt, struct dentry **dentry)
600{
571 while (d_mountpoint(*dentry)) { 601 while (d_mountpoint(*dentry)) {
572 struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); 602 struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
573 if (!mounted) 603 if (!mounted)
574 break; 604 break;
605 dput(*dentry);
575 mntput(*mnt); 606 mntput(*mnt);
576 *mnt = mounted; 607 *mnt = mounted;
577 dput(*dentry);
578 *dentry = dget(mounted->mnt_root); 608 *dentry = dget(mounted->mnt_root);
579 res = 1;
580 } 609 }
581 return res;
582} 610}
583 611
584/* no need for dcache_lock, as serialization is taken care in 612/* no need for dcache_lock, as serialization is taken care in
585 * namespace.c 613 * namespace.c
586 */ 614 */
587static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) 615int follow_down(struct vfsmount **mnt, struct dentry **dentry)
588{ 616{
589 struct vfsmount *mounted; 617 struct vfsmount *mounted;
590 618
591 mounted = lookup_mnt(*mnt, *dentry); 619 mounted = lookup_mnt(*mnt, *dentry);
592 if (mounted) { 620 if (mounted) {
621 dput(*dentry);
593 mntput(*mnt); 622 mntput(*mnt);
594 *mnt = mounted; 623 *mnt = mounted;
595 dput(*dentry);
596 *dentry = dget(mounted->mnt_root); 624 *dentry = dget(mounted->mnt_root);
597 return 1; 625 return 1;
598 } 626 }
599 return 0; 627 return 0;
600} 628}
601 629
602int follow_down(struct vfsmount **mnt, struct dentry **dentry) 630static inline void follow_dotdot(struct nameidata *nd)
603{
604 return __follow_down(mnt,dentry);
605}
606
607static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
608{ 631{
609 while(1) { 632 while(1) {
610 struct vfsmount *parent; 633 struct vfsmount *parent;
611 struct dentry *old = *dentry; 634 struct dentry *old = nd->dentry;
612 635
613 read_lock(&current->fs->lock); 636 read_lock(&current->fs->lock);
614 if (*dentry == current->fs->root && 637 if (nd->dentry == current->fs->root &&
615 *mnt == current->fs->rootmnt) { 638 nd->mnt == current->fs->rootmnt) {
616 read_unlock(&current->fs->lock); 639 read_unlock(&current->fs->lock);
617 break; 640 break;
618 } 641 }
619 read_unlock(&current->fs->lock); 642 read_unlock(&current->fs->lock);
620 spin_lock(&dcache_lock); 643 spin_lock(&dcache_lock);
621 if (*dentry != (*mnt)->mnt_root) { 644 if (nd->dentry != nd->mnt->mnt_root) {
622 *dentry = dget((*dentry)->d_parent); 645 nd->dentry = dget(nd->dentry->d_parent);
623 spin_unlock(&dcache_lock); 646 spin_unlock(&dcache_lock);
624 dput(old); 647 dput(old);
625 break; 648 break;
626 } 649 }
627 spin_unlock(&dcache_lock); 650 spin_unlock(&dcache_lock);
628 spin_lock(&vfsmount_lock); 651 spin_lock(&vfsmount_lock);
629 parent = (*mnt)->mnt_parent; 652 parent = nd->mnt->mnt_parent;
630 if (parent == *mnt) { 653 if (parent == nd->mnt) {
631 spin_unlock(&vfsmount_lock); 654 spin_unlock(&vfsmount_lock);
632 break; 655 break;
633 } 656 }
634 mntget(parent); 657 mntget(parent);
635 *dentry = dget((*mnt)->mnt_mountpoint); 658 nd->dentry = dget(nd->mnt->mnt_mountpoint);
636 spin_unlock(&vfsmount_lock); 659 spin_unlock(&vfsmount_lock);
637 dput(old); 660 dput(old);
638 mntput(*mnt); 661 mntput(nd->mnt);
639 *mnt = parent; 662 nd->mnt = parent;
640 } 663 }
641 follow_mount(mnt, dentry); 664 follow_mount(&nd->mnt, &nd->dentry);
642} 665}
643 666
644struct path {
645 struct vfsmount *mnt;
646 struct dentry *dentry;
647};
648
649/* 667/*
650 * It's more convoluted than I'd like it to be, but... it's still fairly 668 * It's more convoluted than I'd like it to be, but... it's still fairly
651 * small and for now I'd prefer to have fast path as straight as possible. 669 * small and for now I'd prefer to have fast path as straight as possible.
@@ -664,6 +682,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
664done: 682done:
665 path->mnt = mnt; 683 path->mnt = mnt;
666 path->dentry = dentry; 684 path->dentry = dentry;
685 __follow_mount(path);
667 return 0; 686 return 0;
668 687
669need_lookup: 688need_lookup:
@@ -751,7 +770,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
751 case 2: 770 case 2:
752 if (this.name[1] != '.') 771 if (this.name[1] != '.')
753 break; 772 break;
754 follow_dotdot(&nd->mnt, &nd->dentry); 773 follow_dotdot(nd);
755 inode = nd->dentry->d_inode; 774 inode = nd->dentry->d_inode;
756 /* fallthrough */ 775 /* fallthrough */
757 case 1: 776 case 1:
@@ -771,8 +790,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
771 err = do_lookup(nd, &this, &next); 790 err = do_lookup(nd, &this, &next);
772 if (err) 791 if (err)
773 break; 792 break;
774 /* Check mountpoints.. */
775 follow_mount(&next.mnt, &next.dentry);
776 793
777 err = -ENOENT; 794 err = -ENOENT;
778 inode = next.dentry->d_inode; 795 inode = next.dentry->d_inode;
@@ -783,10 +800,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
783 goto out_dput; 800 goto out_dput;
784 801
785 if (inode->i_op->follow_link) { 802 if (inode->i_op->follow_link) {
786 mntget(next.mnt); 803 err = do_follow_link(&next, nd);
787 err = do_follow_link(next.dentry, nd);
788 dput(next.dentry);
789 mntput(next.mnt);
790 if (err) 804 if (err)
791 goto return_err; 805 goto return_err;
792 err = -ENOENT; 806 err = -ENOENT;
@@ -798,6 +812,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
798 break; 812 break;
799 } else { 813 } else {
800 dput(nd->dentry); 814 dput(nd->dentry);
815 if (nd->mnt != next.mnt)
816 mntput(nd->mnt);
801 nd->mnt = next.mnt; 817 nd->mnt = next.mnt;
802 nd->dentry = next.dentry; 818 nd->dentry = next.dentry;
803 } 819 }
@@ -819,7 +835,7 @@ last_component:
819 case 2: 835 case 2:
820 if (this.name[1] != '.') 836 if (this.name[1] != '.')
821 break; 837 break;
822 follow_dotdot(&nd->mnt, &nd->dentry); 838 follow_dotdot(nd);
823 inode = nd->dentry->d_inode; 839 inode = nd->dentry->d_inode;
824 /* fallthrough */ 840 /* fallthrough */
825 case 1: 841 case 1:
@@ -833,19 +849,17 @@ last_component:
833 err = do_lookup(nd, &this, &next); 849 err = do_lookup(nd, &this, &next);
834 if (err) 850 if (err)
835 break; 851 break;
836 follow_mount(&next.mnt, &next.dentry);
837 inode = next.dentry->d_inode; 852 inode = next.dentry->d_inode;
838 if ((lookup_flags & LOOKUP_FOLLOW) 853 if ((lookup_flags & LOOKUP_FOLLOW)
839 && inode && inode->i_op && inode->i_op->follow_link) { 854 && inode && inode->i_op && inode->i_op->follow_link) {
840 mntget(next.mnt); 855 err = do_follow_link(&next, nd);
841 err = do_follow_link(next.dentry, nd);
842 dput(next.dentry);
843 mntput(next.mnt);
844 if (err) 856 if (err)
845 goto return_err; 857 goto return_err;
846 inode = nd->dentry->d_inode; 858 inode = nd->dentry->d_inode;
847 } else { 859 } else {
848 dput(nd->dentry); 860 dput(nd->dentry);
861 if (nd->mnt != next.mnt)
862 mntput(nd->mnt);
849 nd->mnt = next.mnt; 863 nd->mnt = next.mnt;
850 nd->dentry = next.dentry; 864 nd->dentry = next.dentry;
851 } 865 }
@@ -885,6 +899,8 @@ return_base:
885 return 0; 899 return 0;
886out_dput: 900out_dput:
887 dput(next.dentry); 901 dput(next.dentry);
902 if (nd->mnt != next.mnt)
903 mntput(next.mnt);
888 break; 904 break;
889 } 905 }
890 path_release(nd); 906 path_release(nd);
@@ -1398,7 +1414,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1398int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) 1414int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1399{ 1415{
1400 int acc_mode, error = 0; 1416 int acc_mode, error = 0;
1401 struct dentry *dentry; 1417 struct path path;
1402 struct dentry *dir; 1418 struct dentry *dir;
1403 int count = 0; 1419 int count = 0;
1404 1420
@@ -1442,23 +1458,24 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1442 dir = nd->dentry; 1458 dir = nd->dentry;
1443 nd->flags &= ~LOOKUP_PARENT; 1459 nd->flags &= ~LOOKUP_PARENT;
1444 down(&dir->d_inode->i_sem); 1460 down(&dir->d_inode->i_sem);
1445 dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1461 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
1462 path.mnt = nd->mnt;
1446 1463
1447do_last: 1464do_last:
1448 error = PTR_ERR(dentry); 1465 error = PTR_ERR(path.dentry);
1449 if (IS_ERR(dentry)) { 1466 if (IS_ERR(path.dentry)) {
1450 up(&dir->d_inode->i_sem); 1467 up(&dir->d_inode->i_sem);
1451 goto exit; 1468 goto exit;
1452 } 1469 }
1453 1470
1454 /* Negative dentry, just create the file */ 1471 /* Negative dentry, just create the file */
1455 if (!dentry->d_inode) { 1472 if (!path.dentry->d_inode) {
1456 if (!IS_POSIXACL(dir->d_inode)) 1473 if (!IS_POSIXACL(dir->d_inode))
1457 mode &= ~current->fs->umask; 1474 mode &= ~current->fs->umask;
1458 error = vfs_create(dir->d_inode, dentry, mode, nd); 1475 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
1459 up(&dir->d_inode->i_sem); 1476 up(&dir->d_inode->i_sem);
1460 dput(nd->dentry); 1477 dput(nd->dentry);
1461 nd->dentry = dentry; 1478 nd->dentry = path.dentry;
1462 if (error) 1479 if (error)
1463 goto exit; 1480 goto exit;
1464 /* Don't check for write permission, don't truncate */ 1481 /* Don't check for write permission, don't truncate */
@@ -1476,22 +1493,24 @@ do_last:
1476 if (flag & O_EXCL) 1493 if (flag & O_EXCL)
1477 goto exit_dput; 1494 goto exit_dput;
1478 1495
1479 if (d_mountpoint(dentry)) { 1496 if (__follow_mount(&path)) {
1480 error = -ELOOP; 1497 error = -ELOOP;
1481 if (flag & O_NOFOLLOW) 1498 if (flag & O_NOFOLLOW)
1482 goto exit_dput; 1499 goto exit_dput;
1483 while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
1484 } 1500 }
1485 error = -ENOENT; 1501 error = -ENOENT;
1486 if (!dentry->d_inode) 1502 if (!path.dentry->d_inode)
1487 goto exit_dput; 1503 goto exit_dput;
1488 if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) 1504 if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
1489 goto do_link; 1505 goto do_link;
1490 1506
1491 dput(nd->dentry); 1507 dput(nd->dentry);
1492 nd->dentry = dentry; 1508 nd->dentry = path.dentry;
1509 if (nd->mnt != path.mnt)
1510 mntput(nd->mnt);
1511 nd->mnt = path.mnt;
1493 error = -EISDIR; 1512 error = -EISDIR;
1494 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) 1513 if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
1495 goto exit; 1514 goto exit;
1496ok: 1515ok:
1497 error = may_open(nd, acc_mode, flag); 1516 error = may_open(nd, acc_mode, flag);
@@ -1500,7 +1519,9 @@ ok:
1500 return 0; 1519 return 0;
1501 1520
1502exit_dput: 1521exit_dput:
1503 dput(dentry); 1522 dput(path.dentry);
1523 if (nd->mnt != path.mnt)
1524 mntput(path.mnt);
1504exit: 1525exit:
1505 path_release(nd); 1526 path_release(nd);
1506 return error; 1527 return error;
@@ -1520,18 +1541,15 @@ do_link:
1520 * are done. Procfs-like symlinks just set LAST_BIND. 1541 * are done. Procfs-like symlinks just set LAST_BIND.
1521 */ 1542 */
1522 nd->flags |= LOOKUP_PARENT; 1543 nd->flags |= LOOKUP_PARENT;
1523 error = security_inode_follow_link(dentry, nd); 1544 error = security_inode_follow_link(path.dentry, nd);
1524 if (error) 1545 if (error)
1525 goto exit_dput; 1546 goto exit_dput;
1526 error = __do_follow_link(dentry, nd); 1547 error = __do_follow_link(&path, nd);
1527 dput(dentry);
1528 if (error) 1548 if (error)
1529 return error; 1549 return error;
1530 nd->flags &= ~LOOKUP_PARENT; 1550 nd->flags &= ~LOOKUP_PARENT;
1531 if (nd->last_type == LAST_BIND) { 1551 if (nd->last_type == LAST_BIND)
1532 dentry = nd->dentry;
1533 goto ok; 1552 goto ok;
1534 }
1535 error = -EISDIR; 1553 error = -EISDIR;
1536 if (nd->last_type != LAST_NORM) 1554 if (nd->last_type != LAST_NORM)
1537 goto exit; 1555 goto exit;
@@ -1546,7 +1564,8 @@ do_link:
1546 } 1564 }
1547 dir = nd->dentry; 1565 dir = nd->dentry;
1548 down(&dir->d_inode->i_sem); 1566 down(&dir->d_inode->i_sem);
1549 dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1567 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
1568 path.mnt = nd->mnt;
1550 putname(nd->last.name); 1569 putname(nd->last.name);
1551 goto do_last; 1570 goto do_last;
1552} 1571}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 73f96acd5d37..ff6155f5e8d9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -528,19 +528,39 @@ static inline void nfs_renew_times(struct dentry * dentry)
528 dentry->d_time = jiffies; 528 dentry->d_time = jiffies;
529} 529}
530 530
531/*
532 * Return the intent data that applies to this particular path component
533 *
534 * Note that the current set of intents only apply to the very last
535 * component of the path.
536 * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT.
537 */
538static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask)
539{
540 if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
541 return 0;
542 return nd->flags & mask;
543}
544
545/*
546 * Inode and filehandle revalidation for lookups.
547 *
548 * We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
549 * or if the intent information indicates that we're about to open this
550 * particular file and the "nocto" mount flag is not set.
551 *
552 */
531static inline 553static inline
532int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) 554int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
533{ 555{
534 struct nfs_server *server = NFS_SERVER(inode); 556 struct nfs_server *server = NFS_SERVER(inode);
535 557
536 if (nd != NULL) { 558 if (nd != NULL) {
537 int ndflags = nd->flags;
538 /* VFS wants an on-the-wire revalidation */ 559 /* VFS wants an on-the-wire revalidation */
539 if (ndflags & LOOKUP_REVAL) 560 if (nd->flags & LOOKUP_REVAL)
540 goto out_force; 561 goto out_force;
541 /* This is an open(2) */ 562 /* This is an open(2) */
542 if ((ndflags & LOOKUP_OPEN) && 563 if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
543 !(ndflags & LOOKUP_CONTINUE) &&
544 !(server->flags & NFS_MOUNT_NOCTO)) 564 !(server->flags & NFS_MOUNT_NOCTO))
545 goto out_force; 565 goto out_force;
546 } 566 }
@@ -560,12 +580,8 @@ static inline
560int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, 580int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
561 struct nameidata *nd) 581 struct nameidata *nd)
562{ 582{
563 int ndflags = 0;
564
565 if (nd)
566 ndflags = nd->flags;
567 /* Don't revalidate a negative dentry if we're creating a new file */ 583 /* Don't revalidate a negative dentry if we're creating a new file */
568 if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE)) 584 if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
569 return 0; 585 return 0;
570 return !nfs_check_verifier(dir, dentry); 586 return !nfs_check_verifier(dir, dentry);
571} 587}
@@ -700,12 +716,16 @@ struct dentry_operations nfs_dentry_operations = {
700 .d_iput = nfs_dentry_iput, 716 .d_iput = nfs_dentry_iput,
701}; 717};
702 718
719/*
720 * Use intent information to check whether or not we're going to do
721 * an O_EXCL create using this path component.
722 */
703static inline 723static inline
704int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) 724int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
705{ 725{
706 if (NFS_PROTO(dir)->version == 2) 726 if (NFS_PROTO(dir)->version == 2)
707 return 0; 727 return 0;
708 if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE)) 728 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
709 return 0; 729 return 0;
710 return (nd->intent.open.flags & O_EXCL) != 0; 730 return (nd->intent.open.flags & O_EXCL) != 0;
711} 731}
@@ -772,12 +792,13 @@ struct dentry_operations nfs4_dentry_operations = {
772 .d_iput = nfs_dentry_iput, 792 .d_iput = nfs_dentry_iput,
773}; 793};
774 794
795/*
796 * Use intent information to determine whether we need to substitute
797 * the NFSv4-style stateful OPEN for the LOOKUP call
798 */
775static int is_atomic_open(struct inode *dir, struct nameidata *nd) 799static int is_atomic_open(struct inode *dir, struct nameidata *nd)
776{ 800{
777 if (!nd) 801 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
778 return 0;
779 /* Check that we are indeed trying to open this file */
780 if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN))
781 return 0; 802 return 0;
782 /* NFS does not (yet) have a stateful open for directories */ 803 /* NFS does not (yet) have a stateful open for directories */
783 if (nd->flags & LOOKUP_DIRECTORY) 804 if (nd->flags & LOOKUP_DIRECTORY)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f06eee6dcff5..55c907592490 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -37,6 +37,7 @@
37 37
38static int nfs_file_open(struct inode *, struct file *); 38static int nfs_file_open(struct inode *, struct file *);
39static int nfs_file_release(struct inode *, struct file *); 39static int nfs_file_release(struct inode *, struct file *);
40static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
40static int nfs_file_mmap(struct file *, struct vm_area_struct *); 41static int nfs_file_mmap(struct file *, struct vm_area_struct *);
41static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); 42static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
42static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); 43static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
@@ -48,7 +49,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
48static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 49static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
49 50
50struct file_operations nfs_file_operations = { 51struct file_operations nfs_file_operations = {
51 .llseek = remote_llseek, 52 .llseek = nfs_file_llseek,
52 .read = do_sync_read, 53 .read = do_sync_read,
53 .write = do_sync_write, 54 .write = do_sync_write,
54 .aio_read = nfs_file_read, 55 .aio_read = nfs_file_read,
@@ -114,6 +115,45 @@ nfs_file_release(struct inode *inode, struct file *filp)
114 return NFS_PROTO(inode)->file_release(inode, filp); 115 return NFS_PROTO(inode)->file_release(inode, filp);
115} 116}
116 117
118/**
119 * nfs_revalidate_size - Revalidate the file size
120 * @inode - pointer to inode struct
121 * @file - pointer to struct file
122 *
123 * Revalidates the file length. This is basically a wrapper around
124 * nfs_revalidate_inode() that takes into account the fact that we may
125 * have cached writes (in which case we don't care about the server's
126 * idea of what the file length is), or O_DIRECT (in which case we
127 * shouldn't trust the cache).
128 */
129static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
130{
131 struct nfs_server *server = NFS_SERVER(inode);
132 struct nfs_inode *nfsi = NFS_I(inode);
133
134 if (server->flags & NFS_MOUNT_NOAC)
135 goto force_reval;
136 if (filp->f_flags & O_DIRECT)
137 goto force_reval;
138 if (nfsi->npages != 0)
139 return 0;
140 return nfs_revalidate_inode(server, inode);
141force_reval:
142 return __nfs_revalidate_inode(server, inode);
143}
144
145static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
146{
147 /* origin == SEEK_END => we must revalidate the cached file length */
148 if (origin == 2) {
149 struct inode *inode = filp->f_mapping->host;
150 int retval = nfs_revalidate_file_size(inode, filp);
151 if (retval < 0)
152 return (loff_t)retval;
153 }
154 return remote_llseek(filp, offset, origin);
155}
156
117/* 157/*
118 * Flush all dirty pages, and check for write errors. 158 * Flush all dirty pages, and check for write errors.
119 * 159 *
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 67423c696c0a..6fd57f154197 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -12,15 +12,8 @@
12#include <asm/uaccess.h> 12#include <asm/uaccess.h>
13 13
14#ifndef HAVE_ARCH_DEVTREE_FIXUPS 14#ifndef HAVE_ARCH_DEVTREE_FIXUPS
15static inline void set_node_proc_entry(struct device_node *np, struct proc_dir_entry *de) 15static inline void set_node_proc_entry(struct device_node *np,
16{ 16 struct proc_dir_entry *de)
17}
18
19static void inline set_node_name_link(struct device_node *np, struct proc_dir_entry *de)
20{
21}
22
23static void inline set_node_addr_link(struct device_node *np, struct proc_dir_entry *de)
24{ 17{
25} 18}
26#endif 19#endif
@@ -58,89 +51,67 @@ static int property_read_proc(char *page, char **start, off_t off,
58/* 51/*
59 * Process a node, adding entries for its children and its properties. 52 * Process a node, adding entries for its children and its properties.
60 */ 53 */
61void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *de) 54void proc_device_tree_add_node(struct device_node *np,
55 struct proc_dir_entry *de)
62{ 56{
63 struct property *pp; 57 struct property *pp;
64 struct proc_dir_entry *ent; 58 struct proc_dir_entry *ent;
65 struct device_node *child, *sib; 59 struct device_node *child;
66 const char *p, *at; 60 struct proc_dir_entry *list = NULL, **lastp;
67 int l; 61 const char *p;
68 struct proc_dir_entry *list, **lastp, *al;
69 62
70 set_node_proc_entry(np, de); 63 set_node_proc_entry(np, de);
71 lastp = &list; 64 lastp = &list;
72 for (pp = np->properties; pp != 0; pp = pp->next) { 65 for (child = NULL; (child = of_get_next_child(np, child));) {
73 /*
74 * Unfortunately proc_register puts each new entry
75 * at the beginning of the list. So we rearrange them.
76 */
77 ent = create_proc_read_entry(pp->name, strncmp(pp->name, "security-", 9) ?
78 S_IRUGO : S_IRUSR, de, property_read_proc, pp);
79 if (ent == 0)
80 break;
81 if (!strncmp(pp->name, "security-", 9))
82 ent->size = 0; /* don't leak number of password chars */
83 else
84 ent->size = pp->length;
85 *lastp = ent;
86 lastp = &ent->next;
87 }
88 child = NULL;
89 while ((child = of_get_next_child(np, child))) {
90 p = strrchr(child->full_name, '/'); 66 p = strrchr(child->full_name, '/');
91 if (!p) 67 if (!p)
92 p = child->full_name; 68 p = child->full_name;
93 else 69 else
94 ++p; 70 ++p;
95 /* chop off '@0' if the name ends with that */
96 l = strlen(p);
97 if (l > 2 && p[l-2] == '@' && p[l-1] == '0')
98 l -= 2;
99 ent = proc_mkdir(p, de); 71 ent = proc_mkdir(p, de);
100 if (ent == 0) 72 if (ent == 0)
101 break; 73 break;
102 *lastp = ent; 74 *lastp = ent;
75 ent->next = NULL;
103 lastp = &ent->next; 76 lastp = &ent->next;
104 proc_device_tree_add_node(child, ent); 77 proc_device_tree_add_node(child, ent);
105 78 }
106 /* 79 of_node_put(child);
107 * If we left the address part on the name, consider 80 for (pp = np->properties; pp != 0; pp = pp->next) {
108 * adding symlinks from the name and address parts.
109 */
110 if (p[l] != 0 || (at = strchr(p, '@')) == 0)
111 continue;
112
113 /* 81 /*
114 * If this is the first node with a given name property, 82 * Yet another Apple device-tree bogosity: on some machines,
115 * add a symlink with the name property as its name. 83 * they have properties & nodes with the same name. Those
84 * properties are quite unimportant for us though, thus we
85 * simply "skip" them here, but we do have to check.
116 */ 86 */
117 sib = NULL; 87 for (ent = list; ent != NULL; ent = ent->next)
118 while ((sib = of_get_next_child(np, sib)) && sib != child) 88 if (!strcmp(ent->name, pp->name))
119 if (sib->name && strcmp(sib->name, child->name) == 0)
120 break;
121 if (sib == child && strncmp(p, child->name, l) != 0) {
122 al = proc_symlink(child->name, de, ent->name);
123 if (al == 0) {
124 of_node_put(sib);
125 break; 89 break;
126 } 90 if (ent != NULL) {
127 set_node_name_link(child, al); 91 printk(KERN_WARNING "device-tree: property \"%s\" name"
128 *lastp = al; 92 " conflicts with node in %s\n", pp->name,
129 lastp = &al->next; 93 np->full_name);
94 continue;
130 } 95 }
131 of_node_put(sib); 96
132 /* 97 /*
133 * Add another directory with the @address part as its name. 98 * Unfortunately proc_register puts each new entry
99 * at the beginning of the list. So we rearrange them.
134 */ 100 */
135 al = proc_symlink(at, de, ent->name); 101 ent = create_proc_read_entry(pp->name,
136 if (al == 0) 102 strncmp(pp->name, "security-", 9)
103 ? S_IRUGO : S_IRUSR, de,
104 property_read_proc, pp);
105 if (ent == 0)
137 break; 106 break;
138 set_node_addr_link(child, al); 107 if (!strncmp(pp->name, "security-", 9))
139 *lastp = al; 108 ent->size = 0; /* don't leak number of password chars */
140 lastp = &al->next; 109 else
110 ent->size = pp->length;
111 ent->next = NULL;
112 *lastp = ent;
113 lastp = &ent->next;
141 } 114 }
142 of_node_put(child);
143 *lastp = NULL;
144 de->subdir = list; 115 de->subdir = list;
145} 116}
146 117
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index a60a3b3d8a7b..63a9fbf1ac51 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -219,6 +219,19 @@ static struct file_operations fragmentation_file_operations = {
219 .release = seq_release, 219 .release = seq_release,
220}; 220};
221 221
222extern struct seq_operations zoneinfo_op;
223static int zoneinfo_open(struct inode *inode, struct file *file)
224{
225 return seq_open(file, &zoneinfo_op);
226}
227
228static struct file_operations proc_zoneinfo_file_operations = {
229 .open = zoneinfo_open,
230 .read = seq_read,
231 .llseek = seq_lseek,
232 .release = seq_release,
233};
234
222static int version_read_proc(char *page, char **start, off_t off, 235static int version_read_proc(char *page, char **start, off_t off,
223 int count, int *eof, void *data) 236 int count, int *eof, void *data)
224{ 237{
@@ -589,6 +602,7 @@ void __init proc_misc_init(void)
589 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); 602 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
590 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); 603 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
591 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); 604 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
605 create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
592 create_seq_entry("diskstats", 0, &proc_diskstats_operations); 606 create_seq_entry("diskstats", 0, &proc_diskstats_operations);
593#ifdef CONFIG_MODULES 607#ifdef CONFIG_MODULES
594 create_seq_entry("modules", 0, &proc_modules_operations); 608 create_seq_entry("modules", 0, &proc_modules_operations);
diff --git a/fs/super.c b/fs/super.c
index 3a1b8ca04ba6..573bcc81bb82 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -835,6 +835,7 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
835 mnt->mnt_parent = mnt; 835 mnt->mnt_parent = mnt;
836 mnt->mnt_namespace = current->namespace; 836 mnt->mnt_namespace = current->namespace;
837 up_write(&sb->s_umount); 837 up_write(&sb->s_umount);
838 free_secdata(secdata);
838 put_filesystem(type); 839 put_filesystem(type);
839 return mnt; 840 return mnt;
840out_sb: 841out_sb:
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index d4aaa88d0214..78899eeab974 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -25,7 +25,7 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
25 struct kobject * kobj = to_kobj(dentry->d_parent); 25 struct kobject * kobj = to_kobj(dentry->d_parent);
26 26
27 if (!attr->read) 27 if (!attr->read)
28 return -EINVAL; 28 return -EIO;
29 29
30 return attr->read(kobj, buffer, off, count); 30 return attr->read(kobj, buffer, off, count);
31} 31}
@@ -71,7 +71,7 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
71 struct kobject *kobj = to_kobj(dentry->d_parent); 71 struct kobject *kobj = to_kobj(dentry->d_parent);
72 72
73 if (!attr->write) 73 if (!attr->write)
74 return -EINVAL; 74 return -EIO;
75 75
76 return attr->write(kobj, buffer, offset, count); 76 return attr->write(kobj, buffer, offset, count);
77} 77}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index fe198210bc2d..37d7a6875d86 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -101,18 +101,19 @@ static int create_dir(struct kobject * k, struct dentry * p,
101 down(&p->d_inode->i_sem); 101 down(&p->d_inode->i_sem);
102 *d = sysfs_get_dentry(p,n); 102 *d = sysfs_get_dentry(p,n);
103 if (!IS_ERR(*d)) { 103 if (!IS_ERR(*d)) {
104 error = sysfs_create(*d, mode, init_dir); 104 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
105 if (!error) { 105 if (!error) {
106 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, 106 error = sysfs_create(*d, mode, init_dir);
107 SYSFS_DIR);
108 if (!error) { 107 if (!error) {
109 p->d_inode->i_nlink++; 108 p->d_inode->i_nlink++;
110 (*d)->d_op = &sysfs_dentry_ops; 109 (*d)->d_op = &sysfs_dentry_ops;
111 d_rehash(*d); 110 d_rehash(*d);
112 } 111 }
113 } 112 }
114 if (error && (error != -EEXIST)) 113 if (error && (error != -EEXIST)) {
114 sysfs_put((*d)->d_fsdata);
115 d_drop(*d); 115 d_drop(*d);
116 }
116 dput(*d); 117 dput(*d);
117 } else 118 } else
118 error = PTR_ERR(*d); 119 error = PTR_ERR(*d);
@@ -171,17 +172,19 @@ static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
171 init = init_file; 172 init = init_file;
172 } 173 }
173 174
175 dentry->d_fsdata = sysfs_get(sd);
176 sd->s_dentry = dentry;
174 error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); 177 error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
175 if (error) 178 if (error) {
179 sysfs_put(sd);
176 return error; 180 return error;
181 }
177 182
178 if (bin_attr) { 183 if (bin_attr) {
179 dentry->d_inode->i_size = bin_attr->size; 184 dentry->d_inode->i_size = bin_attr->size;
180 dentry->d_inode->i_fop = &bin_fops; 185 dentry->d_inode->i_fop = &bin_fops;
181 } 186 }
182 dentry->d_op = &sysfs_dentry_ops; 187 dentry->d_op = &sysfs_dentry_ops;
183 dentry->d_fsdata = sysfs_get(sd);
184 sd->s_dentry = dentry;
185 d_rehash(dentry); 188 d_rehash(dentry);
186 189
187 return 0; 190 return 0;
@@ -191,13 +194,15 @@ static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
191{ 194{
192 int err = 0; 195 int err = 0;
193 196
197 dentry->d_fsdata = sysfs_get(sd);
198 sd->s_dentry = dentry;
194 err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); 199 err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
195 if (!err) { 200 if (!err) {
196 dentry->d_op = &sysfs_dentry_ops; 201 dentry->d_op = &sysfs_dentry_ops;
197 dentry->d_fsdata = sysfs_get(sd);
198 sd->s_dentry = dentry;
199 d_rehash(dentry); 202 d_rehash(dentry);
200 } 203 } else
204 sysfs_put(sd);
205
201 return err; 206 return err;
202} 207}
203 208
@@ -228,6 +233,7 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
228 233
229struct inode_operations sysfs_dir_inode_operations = { 234struct inode_operations sysfs_dir_inode_operations = {
230 .lookup = sysfs_lookup, 235 .lookup = sysfs_lookup,
236 .setattr = sysfs_setattr,
231}; 237};
232 238
233static void remove_dir(struct dentry * d) 239static void remove_dir(struct dentry * d)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 364208071e17..849aac115460 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -23,7 +23,7 @@ subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
23{ 23{
24 struct subsystem * s = to_subsys(kobj); 24 struct subsystem * s = to_subsys(kobj);
25 struct subsys_attribute * sattr = to_sattr(attr); 25 struct subsys_attribute * sattr = to_sattr(attr);
26 ssize_t ret = 0; 26 ssize_t ret = -EIO;
27 27
28 if (sattr->show) 28 if (sattr->show)
29 ret = sattr->show(s,page); 29 ret = sattr->show(s,page);
@@ -36,7 +36,7 @@ subsys_attr_store(struct kobject * kobj, struct attribute * attr,
36{ 36{
37 struct subsystem * s = to_subsys(kobj); 37 struct subsystem * s = to_subsys(kobj);
38 struct subsys_attribute * sattr = to_sattr(attr); 38 struct subsys_attribute * sattr = to_sattr(attr);
39 ssize_t ret = 0; 39 ssize_t ret = -EIO;
40 40
41 if (sattr->store) 41 if (sattr->store)
42 ret = sattr->store(s,page,count); 42 ret = sattr->store(s,page,count);
@@ -182,7 +182,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
182 return -ENOMEM; 182 return -ENOMEM;
183 183
184 if (count >= PAGE_SIZE) 184 if (count >= PAGE_SIZE)
185 count = PAGE_SIZE - 1; 185 count = PAGE_SIZE;
186 error = copy_from_user(buffer->page,buf,count); 186 error = copy_from_user(buffer->page,buf,count);
187 buffer->needs_read_fill = 1; 187 buffer->needs_read_fill = 1;
188 return error ? -EFAULT : count; 188 return error ? -EFAULT : count;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index aff7b2dfa8ee..565cac1d4200 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -26,18 +26,107 @@ static struct backing_dev_info sysfs_backing_dev_info = {
26 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, 26 .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
27}; 27};
28 28
29struct inode * sysfs_new_inode(mode_t mode) 29static struct inode_operations sysfs_inode_operations ={
30 .setattr = sysfs_setattr,
31};
32
33int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
34{
35 struct inode * inode = dentry->d_inode;
36 struct sysfs_dirent * sd = dentry->d_fsdata;
37 struct iattr * sd_iattr;
38 unsigned int ia_valid = iattr->ia_valid;
39 int error;
40
41 if (!sd)
42 return -EINVAL;
43
44 sd_iattr = sd->s_iattr;
45
46 error = inode_change_ok(inode, iattr);
47 if (error)
48 return error;
49
50 error = inode_setattr(inode, iattr);
51 if (error)
52 return error;
53
54 if (!sd_iattr) {
55 /* setting attributes for the first time, allocate now */
56 sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL);
57 if (!sd_iattr)
58 return -ENOMEM;
59 /* assign default attributes */
60 memset(sd_iattr, 0, sizeof(struct iattr));
61 sd_iattr->ia_mode = sd->s_mode;
62 sd_iattr->ia_uid = 0;
63 sd_iattr->ia_gid = 0;
64 sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
65 sd->s_iattr = sd_iattr;
66 }
67
68 /* attributes were changed atleast once in past */
69
70 if (ia_valid & ATTR_UID)
71 sd_iattr->ia_uid = iattr->ia_uid;
72 if (ia_valid & ATTR_GID)
73 sd_iattr->ia_gid = iattr->ia_gid;
74 if (ia_valid & ATTR_ATIME)
75 sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime,
76 inode->i_sb->s_time_gran);
77 if (ia_valid & ATTR_MTIME)
78 sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime,
79 inode->i_sb->s_time_gran);
80 if (ia_valid & ATTR_CTIME)
81 sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime,
82 inode->i_sb->s_time_gran);
83 if (ia_valid & ATTR_MODE) {
84 umode_t mode = iattr->ia_mode;
85
86 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
87 mode &= ~S_ISGID;
88 sd_iattr->ia_mode = mode;
89 }
90
91 return error;
92}
93
94static inline void set_default_inode_attr(struct inode * inode, mode_t mode)
95{
96 inode->i_mode = mode;
97 inode->i_uid = 0;
98 inode->i_gid = 0;
99 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
100}
101
102static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
103{
104 inode->i_mode = iattr->ia_mode;
105 inode->i_uid = iattr->ia_uid;
106 inode->i_gid = iattr->ia_gid;
107 inode->i_atime = iattr->ia_atime;
108 inode->i_mtime = iattr->ia_mtime;
109 inode->i_ctime = iattr->ia_ctime;
110}
111
112struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
30{ 113{
31 struct inode * inode = new_inode(sysfs_sb); 114 struct inode * inode = new_inode(sysfs_sb);
32 if (inode) { 115 if (inode) {
33 inode->i_mode = mode;
34 inode->i_uid = 0;
35 inode->i_gid = 0;
36 inode->i_blksize = PAGE_CACHE_SIZE; 116 inode->i_blksize = PAGE_CACHE_SIZE;
37 inode->i_blocks = 0; 117 inode->i_blocks = 0;
38 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
39 inode->i_mapping->a_ops = &sysfs_aops; 118 inode->i_mapping->a_ops = &sysfs_aops;
40 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; 119 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
120 inode->i_op = &sysfs_inode_operations;
121
122 if (sd->s_iattr) {
123 /* sysfs_dirent has non-default attributes
124 * get them for the new inode from persistent copy
125 * in sysfs_dirent
126 */
127 set_inode_attr(inode, sd->s_iattr);
128 } else
129 set_default_inode_attr(inode, mode);
41 } 130 }
42 return inode; 131 return inode;
43} 132}
@@ -48,7 +137,8 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
48 struct inode * inode = NULL; 137 struct inode * inode = NULL;
49 if (dentry) { 138 if (dentry) {
50 if (!dentry->d_inode) { 139 if (!dentry->d_inode) {
51 if ((inode = sysfs_new_inode(mode))) { 140 struct sysfs_dirent * sd = dentry->d_fsdata;
141 if ((inode = sysfs_new_inode(mode, sd))) {
52 if (dentry->d_parent && dentry->d_parent->d_inode) { 142 if (dentry->d_parent && dentry->d_parent->d_inode) {
53 struct inode *p_inode = dentry->d_parent->d_inode; 143 struct inode *p_inode = dentry->d_parent->d_inode;
54 p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; 144 p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 5c805bb1a4b7..f1117e885bd6 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -28,6 +28,7 @@ static struct sysfs_dirent sysfs_root = {
28 .s_children = LIST_HEAD_INIT(sysfs_root.s_children), 28 .s_children = LIST_HEAD_INIT(sysfs_root.s_children),
29 .s_element = NULL, 29 .s_element = NULL,
30 .s_type = SYSFS_ROOT, 30 .s_type = SYSFS_ROOT,
31 .s_iattr = NULL,
31}; 32};
32 33
33static int sysfs_fill_super(struct super_block *sb, void *data, int silent) 34static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -42,7 +43,8 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
42 sb->s_time_gran = 1; 43 sb->s_time_gran = 1;
43 sysfs_sb = sb; 44 sysfs_sb = sb;
44 45
45 inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO); 46 inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
47 &sysfs_root);
46 if (inode) { 48 if (inode) {
47 inode->i_op = &sysfs_dir_inode_operations; 49 inode->i_op = &sysfs_dir_inode_operations;
48 inode->i_fop = &sysfs_dir_operations; 50 inode->i_fop = &sysfs_dir_operations;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index dfdf70174354..fae57c83a722 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -43,7 +43,7 @@ static void fill_object_path(struct kobject * kobj, char * buffer, int length)
43 } 43 }
44} 44}
45 45
46static int sysfs_add_link(struct dentry * parent, char * name, struct kobject * target) 46static int sysfs_add_link(struct dentry * parent, const char * name, struct kobject * target)
47{ 47{
48 struct sysfs_dirent * parent_sd = parent->d_fsdata; 48 struct sysfs_dirent * parent_sd = parent->d_fsdata;
49 struct sysfs_symlink * sl; 49 struct sysfs_symlink * sl;
@@ -79,7 +79,7 @@ exit1:
79 * @target: object we're pointing to. 79 * @target: object we're pointing to.
80 * @name: name of the symlink. 80 * @name: name of the symlink.
81 */ 81 */
82int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name) 82int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
83{ 83{
84 struct dentry * dentry = kobj->dentry; 84 struct dentry * dentry = kobj->dentry;
85 int error = 0; 85 int error = 0;
@@ -99,13 +99,13 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * nam
99 * @name: name of the symlink to remove. 99 * @name: name of the symlink to remove.
100 */ 100 */
101 101
102void sysfs_remove_link(struct kobject * kobj, char * name) 102void sysfs_remove_link(struct kobject * kobj, const char * name)
103{ 103{
104 sysfs_hash_and_remove(kobj->dentry,name); 104 sysfs_hash_and_remove(kobj->dentry,name);
105} 105}
106 106
107static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target, 107static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
108 char *path) 108 char *path)
109{ 109{
110 char * s; 110 char * s;
111 int depth, size; 111 int depth, size;
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index a8a24a0c0b3b..29da6f5f07c8 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -2,7 +2,7 @@
2extern struct vfsmount * sysfs_mount; 2extern struct vfsmount * sysfs_mount;
3extern kmem_cache_t *sysfs_dir_cachep; 3extern kmem_cache_t *sysfs_dir_cachep;
4 4
5extern struct inode * sysfs_new_inode(mode_t mode); 5extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); 6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
7 7
8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, 8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
@@ -17,6 +17,7 @@ extern void sysfs_remove_subdir(struct dentry *);
17 17
18extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd); 18extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd);
19extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent); 19extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent);
20extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
20 21
21extern struct rw_semaphore sysfs_rename_sem; 22extern struct rw_semaphore sysfs_rename_sem;
22extern struct super_block * sysfs_sb; 23extern struct super_block * sysfs_sb;
@@ -75,6 +76,7 @@ static inline void release_sysfs_dirent(struct sysfs_dirent * sd)
75 kobject_put(sl->target_kobj); 76 kobject_put(sl->target_kobj);
76 kfree(sl); 77 kfree(sl);
77 } 78 }
79 kfree(sd->s_iattr);
78 kmem_cache_free(sysfs_dir_cachep, sd); 80 kmem_cache_free(sysfs_dir_cachep, sd);
79} 81}
80 82
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 457a8fe28575..85d8dbe843f1 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -46,7 +46,7 @@
46#endif 46#endif
47 47
48/* How many days come before each month (0-12). */ 48/* How many days come before each month (0-12). */
49const unsigned short int __mon_yday[2][13] = 49static const unsigned short int __mon_yday[2][13] =
50{ 50{
51 /* Normal years. */ 51 /* Normal years. */
52 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 52 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 9278e9aba9ba..93ce257cd149 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -886,7 +886,6 @@ xfs_page_state_convert(
886 SetPageUptodate(page); 886 SetPageUptodate(page);
887 887
888 if (startio) { 888 if (startio) {
889 WARN_ON(page_dirty);
890 xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty); 889 xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty);
891 } 890 }
892 891
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 997963e53622..c60e69431e11 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -61,12 +61,13 @@
61 * File wide globals 61 * File wide globals
62 */ 62 */
63 63
64STATIC kmem_cache_t *pagebuf_cache; 64STATIC kmem_cache_t *pagebuf_zone;
65STATIC kmem_shaker_t pagebuf_shake; 65STATIC kmem_shaker_t pagebuf_shake;
66STATIC int pagebuf_daemon_wakeup(int, unsigned int); 66STATIC int xfsbufd_wakeup(int, unsigned int);
67STATIC void pagebuf_delwri_queue(xfs_buf_t *, int); 67STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
68STATIC struct workqueue_struct *pagebuf_logio_workqueue; 68
69STATIC struct workqueue_struct *pagebuf_dataio_workqueue; 69STATIC struct workqueue_struct *xfslogd_workqueue;
70STATIC struct workqueue_struct *xfsdatad_workqueue;
70 71
71/* 72/*
72 * Pagebuf debugging 73 * Pagebuf debugging
@@ -123,9 +124,9 @@ ktrace_t *pagebuf_trace_buf;
123 124
124 125
125#define pagebuf_allocate(flags) \ 126#define pagebuf_allocate(flags) \
126 kmem_zone_alloc(pagebuf_cache, pb_to_km(flags)) 127 kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))
127#define pagebuf_deallocate(pb) \ 128#define pagebuf_deallocate(pb) \
128 kmem_zone_free(pagebuf_cache, (pb)); 129 kmem_zone_free(pagebuf_zone, (pb));
129 130
130/* 131/*
131 * Page Region interfaces. 132 * Page Region interfaces.
@@ -425,7 +426,7 @@ _pagebuf_lookup_pages(
425 __FUNCTION__, gfp_mask); 426 __FUNCTION__, gfp_mask);
426 427
427 XFS_STATS_INC(pb_page_retries); 428 XFS_STATS_INC(pb_page_retries);
428 pagebuf_daemon_wakeup(0, gfp_mask); 429 xfsbufd_wakeup(0, gfp_mask);
429 blk_congestion_wait(WRITE, HZ/50); 430 blk_congestion_wait(WRITE, HZ/50);
430 goto retry; 431 goto retry;
431 } 432 }
@@ -1136,8 +1137,8 @@ pagebuf_iodone(
1136 if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) { 1137 if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
1137 if (schedule) { 1138 if (schedule) {
1138 INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb); 1139 INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
1139 queue_work(dataio ? pagebuf_dataio_workqueue : 1140 queue_work(dataio ? xfsdatad_workqueue :
1140 pagebuf_logio_workqueue, &pb->pb_iodone_work); 1141 xfslogd_workqueue, &pb->pb_iodone_work);
1141 } else { 1142 } else {
1142 pagebuf_iodone_work(pb); 1143 pagebuf_iodone_work(pb);
1143 } 1144 }
@@ -1562,16 +1563,6 @@ xfs_free_buftarg(
1562 kmem_free(btp, sizeof(*btp)); 1563 kmem_free(btp, sizeof(*btp));
1563} 1564}
1564 1565
1565void
1566xfs_incore_relse(
1567 xfs_buftarg_t *btp,
1568 int delwri_only,
1569 int wait)
1570{
1571 invalidate_bdev(btp->pbr_bdev, 1);
1572 truncate_inode_pages(btp->pbr_mapping, 0LL);
1573}
1574
1575STATIC int 1566STATIC int
1576xfs_setsize_buftarg_flags( 1567xfs_setsize_buftarg_flags(
1577 xfs_buftarg_t *btp, 1568 xfs_buftarg_t *btp,
@@ -1742,27 +1733,27 @@ pagebuf_runall_queues(
1742} 1733}
1743 1734
1744/* Defines for pagebuf daemon */ 1735/* Defines for pagebuf daemon */
1745STATIC DECLARE_COMPLETION(pagebuf_daemon_done); 1736STATIC DECLARE_COMPLETION(xfsbufd_done);
1746STATIC struct task_struct *pagebuf_daemon_task; 1737STATIC struct task_struct *xfsbufd_task;
1747STATIC int pagebuf_daemon_active; 1738STATIC int xfsbufd_active;
1748STATIC int force_flush; 1739STATIC int xfsbufd_force_flush;
1749STATIC int force_sleep; 1740STATIC int xfsbufd_force_sleep;
1750 1741
1751STATIC int 1742STATIC int
1752pagebuf_daemon_wakeup( 1743xfsbufd_wakeup(
1753 int priority, 1744 int priority,
1754 unsigned int mask) 1745 unsigned int mask)
1755{ 1746{
1756 if (force_sleep) 1747 if (xfsbufd_force_sleep)
1757 return 0; 1748 return 0;
1758 force_flush = 1; 1749 xfsbufd_force_flush = 1;
1759 barrier(); 1750 barrier();
1760 wake_up_process(pagebuf_daemon_task); 1751 wake_up_process(xfsbufd_task);
1761 return 0; 1752 return 0;
1762} 1753}
1763 1754
1764STATIC int 1755STATIC int
1765pagebuf_daemon( 1756xfsbufd(
1766 void *data) 1757 void *data)
1767{ 1758{
1768 struct list_head tmp; 1759 struct list_head tmp;
@@ -1774,17 +1765,17 @@ pagebuf_daemon(
1774 daemonize("xfsbufd"); 1765 daemonize("xfsbufd");
1775 current->flags |= PF_MEMALLOC; 1766 current->flags |= PF_MEMALLOC;
1776 1767
1777 pagebuf_daemon_task = current; 1768 xfsbufd_task = current;
1778 pagebuf_daemon_active = 1; 1769 xfsbufd_active = 1;
1779 barrier(); 1770 barrier();
1780 1771
1781 INIT_LIST_HEAD(&tmp); 1772 INIT_LIST_HEAD(&tmp);
1782 do { 1773 do {
1783 if (unlikely(current->flags & PF_FREEZE)) { 1774 if (unlikely(current->flags & PF_FREEZE)) {
1784 force_sleep = 1; 1775 xfsbufd_force_sleep = 1;
1785 refrigerator(PF_FREEZE); 1776 refrigerator(PF_FREEZE);
1786 } else { 1777 } else {
1787 force_sleep = 0; 1778 xfsbufd_force_sleep = 0;
1788 } 1779 }
1789 1780
1790 set_current_state(TASK_INTERRUPTIBLE); 1781 set_current_state(TASK_INTERRUPTIBLE);
@@ -1797,7 +1788,7 @@ pagebuf_daemon(
1797 ASSERT(pb->pb_flags & PBF_DELWRI); 1788 ASSERT(pb->pb_flags & PBF_DELWRI);
1798 1789
1799 if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) { 1790 if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) {
1800 if (!force_flush && 1791 if (!xfsbufd_force_flush &&
1801 time_before(jiffies, 1792 time_before(jiffies,
1802 pb->pb_queuetime + age)) { 1793 pb->pb_queuetime + age)) {
1803 pagebuf_unlock(pb); 1794 pagebuf_unlock(pb);
@@ -1824,10 +1815,10 @@ pagebuf_daemon(
1824 if (as_list_len > 0) 1815 if (as_list_len > 0)
1825 purge_addresses(); 1816 purge_addresses();
1826 1817
1827 force_flush = 0; 1818 xfsbufd_force_flush = 0;
1828 } while (pagebuf_daemon_active); 1819 } while (xfsbufd_active);
1829 1820
1830 complete_and_exit(&pagebuf_daemon_done, 0); 1821 complete_and_exit(&xfsbufd_done, 0);
1831} 1822}
1832 1823
1833/* 1824/*
@@ -1844,8 +1835,8 @@ xfs_flush_buftarg(
1844 xfs_buf_t *pb, *n; 1835 xfs_buf_t *pb, *n;
1845 int pincount = 0; 1836 int pincount = 0;
1846 1837
1847 pagebuf_runall_queues(pagebuf_dataio_workqueue); 1838 pagebuf_runall_queues(xfsdatad_workqueue);
1848 pagebuf_runall_queues(pagebuf_logio_workqueue); 1839 pagebuf_runall_queues(xfslogd_workqueue);
1849 1840
1850 INIT_LIST_HEAD(&tmp); 1841 INIT_LIST_HEAD(&tmp);
1851 spin_lock(&pbd_delwrite_lock); 1842 spin_lock(&pbd_delwrite_lock);
@@ -1898,43 +1889,43 @@ xfs_flush_buftarg(
1898} 1889}
1899 1890
1900STATIC int 1891STATIC int
1901pagebuf_daemon_start(void) 1892xfs_buf_daemons_start(void)
1902{ 1893{
1903 int rval; 1894 int error = -ENOMEM;
1904 1895
1905 pagebuf_logio_workqueue = create_workqueue("xfslogd"); 1896 xfslogd_workqueue = create_workqueue("xfslogd");
1906 if (!pagebuf_logio_workqueue) 1897 if (!xfslogd_workqueue)
1907 return -ENOMEM; 1898 goto out;
1908 1899
1909 pagebuf_dataio_workqueue = create_workqueue("xfsdatad"); 1900 xfsdatad_workqueue = create_workqueue("xfsdatad");
1910 if (!pagebuf_dataio_workqueue) { 1901 if (!xfsdatad_workqueue)
1911 destroy_workqueue(pagebuf_logio_workqueue); 1902 goto out_destroy_xfslogd_workqueue;
1912 return -ENOMEM;
1913 }
1914 1903
1915 rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES); 1904 error = kernel_thread(xfsbufd, NULL, CLONE_FS|CLONE_FILES);
1916 if (rval < 0) { 1905 if (error < 0)
1917 destroy_workqueue(pagebuf_logio_workqueue); 1906 goto out_destroy_xfsdatad_workqueue;
1918 destroy_workqueue(pagebuf_dataio_workqueue); 1907 return 0;
1919 }
1920 1908
1921 return rval; 1909 out_destroy_xfsdatad_workqueue:
1910 destroy_workqueue(xfsdatad_workqueue);
1911 out_destroy_xfslogd_workqueue:
1912 destroy_workqueue(xfslogd_workqueue);
1913 out:
1914 return error;
1922} 1915}
1923 1916
1924/* 1917/*
1925 * pagebuf_daemon_stop
1926 *
1927 * Note: do not mark as __exit, it is called from pagebuf_terminate. 1918 * Note: do not mark as __exit, it is called from pagebuf_terminate.
1928 */ 1919 */
1929STATIC void 1920STATIC void
1930pagebuf_daemon_stop(void) 1921xfs_buf_daemons_stop(void)
1931{ 1922{
1932 pagebuf_daemon_active = 0; 1923 xfsbufd_active = 0;
1933 barrier(); 1924 barrier();
1934 wait_for_completion(&pagebuf_daemon_done); 1925 wait_for_completion(&xfsbufd_done);
1935 1926
1936 destroy_workqueue(pagebuf_logio_workqueue); 1927 destroy_workqueue(xfslogd_workqueue);
1937 destroy_workqueue(pagebuf_dataio_workqueue); 1928 destroy_workqueue(xfsdatad_workqueue);
1938} 1929}
1939 1930
1940/* 1931/*
@@ -1944,27 +1935,37 @@ pagebuf_daemon_stop(void)
1944int __init 1935int __init
1945pagebuf_init(void) 1936pagebuf_init(void)
1946{ 1937{
1947 pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0, 1938 int error = -ENOMEM;
1948 SLAB_HWCACHE_ALIGN, NULL, NULL); 1939
1949 if (pagebuf_cache == NULL) { 1940 pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
1950 printk("XFS: couldn't init xfs_buf_t cache\n"); 1941 if (!pagebuf_zone)
1951 pagebuf_terminate(); 1942 goto out;
1952 return -ENOMEM;
1953 }
1954 1943
1955#ifdef PAGEBUF_TRACE 1944#ifdef PAGEBUF_TRACE
1956 pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP); 1945 pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
1957#endif 1946#endif
1958 1947
1959 pagebuf_daemon_start(); 1948 error = xfs_buf_daemons_start();
1949 if (error)
1950 goto out_free_buf_zone;
1960 1951
1961 pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup); 1952 pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
1962 if (pagebuf_shake == NULL) { 1953 if (!pagebuf_shake) {
1963 pagebuf_terminate(); 1954 error = -ENOMEM;
1964 return -ENOMEM; 1955 goto out_stop_daemons;
1965 } 1956 }
1966 1957
1967 return 0; 1958 return 0;
1959
1960 out_stop_daemons:
1961 xfs_buf_daemons_stop();
1962 out_free_buf_zone:
1963#ifdef PAGEBUF_TRACE
1964 ktrace_free(pagebuf_trace_buf);
1965#endif
1966 kmem_zone_destroy(pagebuf_zone);
1967 out:
1968 return error;
1968} 1969}
1969 1970
1970 1971
@@ -1976,12 +1977,12 @@ pagebuf_init(void)
1976void 1977void
1977pagebuf_terminate(void) 1978pagebuf_terminate(void)
1978{ 1979{
1979 pagebuf_daemon_stop(); 1980 xfs_buf_daemons_stop();
1980 1981
1981#ifdef PAGEBUF_TRACE 1982#ifdef PAGEBUF_TRACE
1982 ktrace_free(pagebuf_trace_buf); 1983 ktrace_free(pagebuf_trace_buf);
1983#endif 1984#endif
1984 1985
1985 kmem_zone_destroy(pagebuf_cache); 1986 kmem_zone_destroy(pagebuf_zone);
1986 kmem_shake_deregister(pagebuf_shake); 1987 kmem_shake_deregister(pagebuf_shake);
1987} 1988}
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 74deed8e6d90..3f8f69a66aea 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -576,7 +576,6 @@ extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int);
576extern void xfs_free_buftarg(xfs_buftarg_t *, int); 576extern void xfs_free_buftarg(xfs_buftarg_t *, int);
577extern void xfs_wait_buftarg(xfs_buftarg_t *); 577extern void xfs_wait_buftarg(xfs_buftarg_t *);
578extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); 578extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
579extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
580extern int xfs_flush_buftarg(xfs_buftarg_t *, int); 579extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
581 580
582#define xfs_getsize_buftarg(buftarg) \ 581#define xfs_getsize_buftarg(buftarg) \
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index d0d412afd261..f1ce4323f56e 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -57,7 +57,9 @@
57#include <linux/smp_lock.h> 57#include <linux/smp_lock.h>
58 58
59static struct vm_operations_struct linvfs_file_vm_ops; 59static struct vm_operations_struct linvfs_file_vm_ops;
60 60#ifdef CONFIG_XFS_DMAPI
61static struct vm_operations_struct linvfs_dmapi_file_vm_ops;
62#endif
61 63
62STATIC inline ssize_t 64STATIC inline ssize_t
63__linvfs_read( 65__linvfs_read(
@@ -388,6 +390,14 @@ done:
388 return -error; 390 return -error;
389} 391}
390 392
393#ifdef CONFIG_XFS_DMAPI
394STATIC void
395linvfs_mmap_close(
396 struct vm_area_struct *vma)
397{
398 xfs_dm_mm_put(vma);
399}
400#endif /* CONFIG_XFS_DMAPI */
391 401
392STATIC int 402STATIC int
393linvfs_file_mmap( 403linvfs_file_mmap(
@@ -399,16 +409,19 @@ linvfs_file_mmap(
399 vattr_t va = { .va_mask = XFS_AT_UPDATIME }; 409 vattr_t va = { .va_mask = XFS_AT_UPDATIME };
400 int error; 410 int error;
401 411
412 vma->vm_ops = &linvfs_file_vm_ops;
413
402 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 414 if (vp->v_vfsp->vfs_flag & VFS_DMI) {
403 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp); 415 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
404 416
405 error = -XFS_SEND_MMAP(mp, vma, 0); 417 error = -XFS_SEND_MMAP(mp, vma, 0);
406 if (error) 418 if (error)
407 return error; 419 return error;
420#ifdef CONFIG_XFS_DMAPI
421 vma->vm_ops = &linvfs_dmapi_file_vm_ops;
422#endif
408 } 423 }
409 424
410 vma->vm_ops = &linvfs_file_vm_ops;
411
412 VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error); 425 VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
413 if (!error) 426 if (!error)
414 vn_revalidate(vp); /* update Linux inode flags */ 427 vn_revalidate(vp); /* update Linux inode flags */
@@ -565,7 +578,7 @@ struct file_operations linvfs_file_operations = {
565 .sendfile = linvfs_sendfile, 578 .sendfile = linvfs_sendfile,
566 .unlocked_ioctl = linvfs_ioctl, 579 .unlocked_ioctl = linvfs_ioctl,
567#ifdef CONFIG_COMPAT 580#ifdef CONFIG_COMPAT
568 .compat_ioctl = xfs_compat_ioctl, 581 .compat_ioctl = linvfs_compat_ioctl,
569#endif 582#endif
570 .mmap = linvfs_file_mmap, 583 .mmap = linvfs_file_mmap,
571 .open = linvfs_open, 584 .open = linvfs_open,
@@ -587,7 +600,7 @@ struct file_operations linvfs_invis_file_operations = {
587 .sendfile = linvfs_sendfile, 600 .sendfile = linvfs_sendfile,
588 .unlocked_ioctl = linvfs_ioctl_invis, 601 .unlocked_ioctl = linvfs_ioctl_invis,
589#ifdef CONFIG_COMPAT 602#ifdef CONFIG_COMPAT
590 .compat_ioctl = xfs_compat_invis_ioctl, 603 .compat_ioctl = linvfs_compat_invis_ioctl,
591#endif 604#endif
592 .mmap = linvfs_file_mmap, 605 .mmap = linvfs_file_mmap,
593 .open = linvfs_open, 606 .open = linvfs_open,
@@ -600,13 +613,24 @@ struct file_operations linvfs_dir_operations = {
600 .read = generic_read_dir, 613 .read = generic_read_dir,
601 .readdir = linvfs_readdir, 614 .readdir = linvfs_readdir,
602 .unlocked_ioctl = linvfs_ioctl, 615 .unlocked_ioctl = linvfs_ioctl,
616#ifdef CONFIG_COMPAT
617 .compat_ioctl = linvfs_compat_ioctl,
618#endif
603 .fsync = linvfs_fsync, 619 .fsync = linvfs_fsync,
604}; 620};
605 621
606static struct vm_operations_struct linvfs_file_vm_ops = { 622static struct vm_operations_struct linvfs_file_vm_ops = {
607 .nopage = filemap_nopage, 623 .nopage = filemap_nopage,
608 .populate = filemap_populate, 624 .populate = filemap_populate,
625};
626
627#ifdef CONFIG_XFS_DMAPI
628static struct vm_operations_struct linvfs_dmapi_file_vm_ops = {
629 .close = linvfs_mmap_close,
630 .nopage = filemap_nopage,
631 .populate = filemap_populate,
609#ifdef HAVE_VMOP_MPROTECT 632#ifdef HAVE_VMOP_MPROTECT
610 .mprotect = linvfs_mprotect, 633 .mprotect = linvfs_mprotect,
611#endif 634#endif
612}; 635};
636#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 69809eef8a54..05a447e51cc0 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -1174,7 +1174,8 @@ xfs_ioc_xattr(
1174 1174
1175 switch (cmd) { 1175 switch (cmd) {
1176 case XFS_IOC_FSGETXATTR: { 1176 case XFS_IOC_FSGETXATTR: {
1177 va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS; 1177 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1178 XFS_AT_NEXTENTS | XFS_AT_PROJID;
1178 VOP_GETATTR(vp, &va, 0, NULL, error); 1179 VOP_GETATTR(vp, &va, 0, NULL, error);
1179 if (error) 1180 if (error)
1180 return -error; 1181 return -error;
@@ -1182,6 +1183,7 @@ xfs_ioc_xattr(
1182 fa.fsx_xflags = va.va_xflags; 1183 fa.fsx_xflags = va.va_xflags;
1183 fa.fsx_extsize = va.va_extsize; 1184 fa.fsx_extsize = va.va_extsize;
1184 fa.fsx_nextents = va.va_nextents; 1185 fa.fsx_nextents = va.va_nextents;
1186 fa.fsx_projid = va.va_projid;
1185 1187
1186 if (copy_to_user(arg, &fa, sizeof(fa))) 1188 if (copy_to_user(arg, &fa, sizeof(fa)))
1187 return -XFS_ERROR(EFAULT); 1189 return -XFS_ERROR(EFAULT);
@@ -1196,9 +1198,10 @@ xfs_ioc_xattr(
1196 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 1198 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1197 attr_flags |= ATTR_NONBLOCK; 1199 attr_flags |= ATTR_NONBLOCK;
1198 1200
1199 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE; 1201 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
1200 va.va_xflags = fa.fsx_xflags; 1202 va.va_xflags = fa.fsx_xflags;
1201 va.va_extsize = fa.fsx_extsize; 1203 va.va_extsize = fa.fsx_extsize;
1204 va.va_projid = fa.fsx_projid;
1202 1205
1203 VOP_SETATTR(vp, &va, attr_flags, NULL, error); 1206 VOP_SETATTR(vp, &va, attr_flags, NULL, error);
1204 if (!error) 1207 if (!error)
@@ -1207,7 +1210,8 @@ xfs_ioc_xattr(
1207 } 1210 }
1208 1211
1209 case XFS_IOC_FSGETXATTRA: { 1212 case XFS_IOC_FSGETXATTRA: {
1210 va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS; 1213 va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1214 XFS_AT_ANEXTENTS | XFS_AT_PROJID;
1211 VOP_GETATTR(vp, &va, 0, NULL, error); 1215 VOP_GETATTR(vp, &va, 0, NULL, error);
1212 if (error) 1216 if (error)
1213 return -error; 1217 return -error;
@@ -1215,6 +1219,7 @@ xfs_ioc_xattr(
1215 fa.fsx_xflags = va.va_xflags; 1219 fa.fsx_xflags = va.va_xflags;
1216 fa.fsx_extsize = va.va_extsize; 1220 fa.fsx_extsize = va.va_extsize;
1217 fa.fsx_nextents = va.va_anextents; 1221 fa.fsx_nextents = va.va_anextents;
1222 fa.fsx_projid = va.va_projid;
1218 1223
1219 if (copy_to_user(arg, &fa, sizeof(fa))) 1224 if (copy_to_user(arg, &fa, sizeof(fa)))
1220 return -XFS_ERROR(EFAULT); 1225 return -XFS_ERROR(EFAULT);
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 7a12c83184f5..0f8f1384eb36 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -58,8 +58,9 @@ typedef struct xfs_fsop_bulkreq32 {
58 __s32 ocount; /* output count pointer */ 58 __s32 ocount; /* output count pointer */
59} xfs_fsop_bulkreq32_t; 59} xfs_fsop_bulkreq32_t;
60 60
61static unsigned long 61STATIC unsigned long
62xfs_ioctl32_bulkstat(unsigned long arg) 62xfs_ioctl32_bulkstat(
63 unsigned long arg)
63{ 64{
64 xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg; 65 xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg;
65 xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p)); 66 xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p));
@@ -78,11 +79,11 @@ xfs_ioctl32_bulkstat(unsigned long arg)
78} 79}
79#endif 80#endif
80 81
81static long 82STATIC long
82__xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) 83__linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
83{ 84{
84 int error; 85 int error;
85 struct inode *inode = f->f_dentry->d_inode; 86 struct inode *inode = f->f_dentry->d_inode;
86 vnode_t *vp = LINVFS_GET_VP(inode); 87 vnode_t *vp = LINVFS_GET_VP(inode);
87 88
88 switch (cmd) { 89 switch (cmd) {
@@ -152,12 +153,20 @@ __xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
152 return error; 153 return error;
153} 154}
154 155
155long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg) 156long
157linvfs_compat_ioctl(
158 struct file *f,
159 unsigned cmd,
160 unsigned long arg)
156{ 161{
157 return __xfs_compat_ioctl(0, f, cmd, arg); 162 return __linvfs_compat_ioctl(0, f, cmd, arg);
158} 163}
159 164
160long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg) 165long
166linvfs_compat_invis_ioctl(
167 struct file *f,
168 unsigned cmd,
169 unsigned long arg)
161{ 170{
162 return __xfs_compat_ioctl(IO_INVIS, f, cmd, arg); 171 return __linvfs_compat_ioctl(IO_INVIS, f, cmd, arg);
163} 172}
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.h b/fs/xfs/linux-2.6/xfs_ioctl32.h
index 779f69a48116..c874793a1dc9 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.h
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2004-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -30,5 +30,5 @@
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ 30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */ 31 */
32 32
33long xfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); 33long linvfs_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg);
34long xfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg); 34long linvfs_compat_invis_ioctl(struct file *f, unsigned cmd, unsigned long arg);
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 71bb41019a12..42dc5e4662ed 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -145,10 +145,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
145#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val 145#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
146#define xfs_rotorstep xfs_params.rotorstep.val 146#define xfs_rotorstep xfs_params.rotorstep.val
147 147
148#ifndef __smp_processor_id 148#ifndef raw_smp_processor_id
149#define __smp_processor_id() smp_processor_id() 149#define raw_smp_processor_id() smp_processor_id()
150#endif 150#endif
151#define current_cpu() __smp_processor_id() 151#define current_cpu() raw_smp_processor_id()
152#define current_pid() (current->pid) 152#define current_pid() (current->pid)
153#define current_fsuid(cred) (current->fsuid) 153#define current_fsuid(cred) (current->fsuid)
154#define current_fsgid(cred) (current->fsgid) 154#define current_fsgid(cred) (current->fsgid)
@@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
230 * field (see the QCMD macro in quota.h). These macros help keep the 230 * field (see the QCMD macro in quota.h). These macros help keep the
231 * code portable - they are not visible from the syscall interface. 231 * code portable - they are not visible from the syscall interface.
232 */ 232 */
233#define Q_XSETGQLIM XQM_CMD(0x8) /* set groups disk limits */ 233#define Q_XSETGQLIM XQM_CMD(8) /* set groups disk limits */
234#define Q_XGETGQUOTA XQM_CMD(0x9) /* get groups disk limits */ 234#define Q_XGETGQUOTA XQM_CMD(9) /* get groups disk limits */
235#define Q_XSETPQLIM XQM_CMD(10) /* set projects disk limits */
236#define Q_XGETPQUOTA XQM_CMD(11) /* get projects disk limits */
235 237
236/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */ 238/* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
237/* we may well need to fine-tune this if it ever becomes an issue. */ 239/* we may well need to fine-tune this if it ever becomes an issue. */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index aa9daaea6c34..acab58c48043 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -209,30 +209,6 @@ unlock:
209 return (-status); 209 return (-status);
210} 210}
211 211
212/*
213 * xfs_inval_cached_pages
214 *
215 * This routine is responsible for keeping direct I/O and buffered I/O
216 * somewhat coherent. From here we make sure that we're at least
217 * temporarily holding the inode I/O lock exclusively and then call
218 * the page cache to flush and invalidate any cached pages. If there
219 * are no cached pages this routine will be very quick.
220 */
221void
222xfs_inval_cached_pages(
223 vnode_t *vp,
224 xfs_iocore_t *io,
225 xfs_off_t offset,
226 int write,
227 int relock)
228{
229 if (VN_CACHED(vp)) {
230 xfs_inval_cached_trace(io, offset, -1, ctooff(offtoct(offset)), -1);
231 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(offset)), -1, FI_REMAPF_LOCKED);
232 }
233
234}
235
236ssize_t /* bytes read, or (-) error */ 212ssize_t /* bytes read, or (-) error */
237xfs_read( 213xfs_read(
238 bhv_desc_t *bdp, 214 bhv_desc_t *bdp,
@@ -304,10 +280,11 @@ xfs_read(
304 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 280 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
305 !(ioflags & IO_INVIS)) { 281 !(ioflags & IO_INVIS)) {
306 vrwlock_t locktype = VRWLOCK_READ; 282 vrwlock_t locktype = VRWLOCK_READ;
283 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
307 284
308 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, 285 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
309 BHV_TO_VNODE(bdp), *offset, size, 286 BHV_TO_VNODE(bdp), *offset, size,
310 FILP_DELAY_FLAG(file), &locktype); 287 dmflags, &locktype);
311 if (ret) { 288 if (ret) {
312 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 289 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
313 goto unlock_isem; 290 goto unlock_isem;
@@ -867,11 +844,15 @@ retry:
867 !(ioflags & IO_INVIS)) { 844 !(ioflags & IO_INVIS)) {
868 845
869 xfs_rwunlock(bdp, locktype); 846 xfs_rwunlock(bdp, locktype);
847 if (need_isem)
848 up(&inode->i_sem);
870 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, 849 error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
871 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, 850 DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
872 0, 0, 0); /* Delay flag intentionally unused */ 851 0, 0, 0); /* Delay flag intentionally unused */
873 if (error) 852 if (error)
874 goto out_unlock_isem; 853 goto out_nounlocks;
854 if (need_isem)
855 down(&inode->i_sem);
875 xfs_rwlock(bdp, locktype); 856 xfs_rwlock(bdp, locktype);
876 pos = xip->i_d.di_size; 857 pos = xip->i_d.di_size;
877 ret = 0; 858 ret = 0;
@@ -986,6 +967,7 @@ retry:
986 out_unlock_isem: 967 out_unlock_isem:
987 if (need_isem) 968 if (need_isem)
988 up(&inode->i_sem); 969 up(&inode->i_sem);
970 out_nounlocks:
989 return -error; 971 return -error;
990} 972}
991 973
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index d723e35254a0..f197a720e394 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -94,8 +94,6 @@ extern int xfs_bdstrat_cb(struct xfs_buf *);
94 94
95extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, 95extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
96 xfs_fsize_t, xfs_fsize_t); 96 xfs_fsize_t, xfs_fsize_t);
97extern void xfs_inval_cached_pages(struct vnode *, struct xfs_iocore *,
98 xfs_off_t, int, int);
99extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, 97extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
100 const struct iovec *, unsigned int, 98 const struct iovec *, unsigned int,
101 loff_t *, int, struct cred *); 99 loff_t *, int, struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 53dc658cafa6..5fe9af38aa20 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -66,7 +66,6 @@
66#include "xfs_buf_item.h" 66#include "xfs_buf_item.h"
67#include "xfs_utils.h" 67#include "xfs_utils.h"
68#include "xfs_version.h" 68#include "xfs_version.h"
69#include "xfs_ioctl32.h"
70 69
71#include <linux/namei.h> 70#include <linux/namei.h>
72#include <linux/init.h> 71#include <linux/init.h>
@@ -591,8 +590,10 @@ linvfs_sync_super(
591 int error; 590 int error;
592 int flags = SYNC_FSDATA; 591 int flags = SYNC_FSDATA;
593 592
594 if (wait) 593 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
595 flags |= SYNC_WAIT; 594 flags = SYNC_QUIESCE;
595 else
596 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
596 597
597 VFS_SYNC(vfsp, flags, NULL, error); 598 VFS_SYNC(vfsp, flags, NULL, error);
598 sb->s_dirt = 0; 599 sb->s_dirt = 0;
@@ -702,7 +703,8 @@ linvfs_getxquota(
702 struct vfs *vfsp = LINVFS_GET_VFS(sb); 703 struct vfs *vfsp = LINVFS_GET_VFS(sb);
703 int error, getmode; 704 int error, getmode;
704 705
705 getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA; 706 getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
707 ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
706 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error); 708 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
707 return -error; 709 return -error;
708} 710}
@@ -717,7 +719,8 @@ linvfs_setxquota(
717 struct vfs *vfsp = LINVFS_GET_VFS(sb); 719 struct vfs *vfsp = LINVFS_GET_VFS(sb);
718 int error, setmode; 720 int error, setmode;
719 721
720 setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM; 722 setmode = (type == USRQUOTA) ? Q_XSETQLIM :
723 ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
721 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error); 724 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
722 return -error; 725 return -error;
723} 726}
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 76493991578f..7ee1f714e9ba 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -107,6 +107,7 @@ typedef enum {
107#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ 107#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
108#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ 108#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
109#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ 109#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
110#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
110 111
111typedef int (*vfs_mount_t)(bhv_desc_t *, 112typedef int (*vfs_mount_t)(bhv_desc_t *,
112 struct xfs_mount_args *, struct cred *); 113 struct xfs_mount_args *, struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index a832d165f24f..250cad54e892 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -411,13 +411,13 @@ vn_remove(
411/* 0 */ (void *)(__psint_t)(vk), \ 411/* 0 */ (void *)(__psint_t)(vk), \
412/* 1 */ (void *)(s), \ 412/* 1 */ (void *)(s), \
413/* 2 */ (void *)(__psint_t) line, \ 413/* 2 */ (void *)(__psint_t) line, \
414/* 3 */ (void *)(vn_count(vp)), \ 414/* 3 */ (void *)(__psint_t)(vn_count(vp)), \
415/* 4 */ (void *)(ra), \ 415/* 4 */ (void *)(ra), \
416/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \ 416/* 5 */ (void *)(__psunsigned_t)(vp)->v_flag, \
417/* 6 */ (void *)(__psint_t)current_cpu(), \ 417/* 6 */ (void *)(__psint_t)current_cpu(), \
418/* 7 */ (void *)(__psint_t)current_pid(), \ 418/* 7 */ (void *)(__psint_t)current_pid(), \
419/* 8 */ (void *)__return_address, \ 419/* 8 */ (void *)__return_address, \
420/* 9 */ 0, 0, 0, 0, 0, 0, 0) 420/* 9 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL)
421 421
422/* 422/*
423 * Vnode tracing code. 423 * Vnode tracing code.
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 00466c3194ac..a6e57c647be4 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -426,7 +426,7 @@ typedef struct vattr {
426 u_long va_extsize; /* file extent size */ 426 u_long va_extsize; /* file extent size */
427 u_long va_nextents; /* number of extents in file */ 427 u_long va_nextents; /* number of extents in file */
428 u_long va_anextents; /* number of attr extents in file */ 428 u_long va_anextents; /* number of attr extents in file */
429 int va_projid; /* project id */ 429 prid_t va_projid; /* project id */
430} vattr_t; 430} vattr_t;
431 431
432/* 432/*
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 740d20d33187..46ce1e3ce1d6 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -101,7 +101,7 @@ int xfs_dqerror_mod = 33;
101 * is the d_id field. The idea is to fill in the entire q_core 101 * is the d_id field. The idea is to fill in the entire q_core
102 * when we read in the on disk dquot. 102 * when we read in the on disk dquot.
103 */ 103 */
104xfs_dquot_t * 104STATIC xfs_dquot_t *
105xfs_qm_dqinit( 105xfs_qm_dqinit(
106 xfs_mount_t *mp, 106 xfs_mount_t *mp,
107 xfs_dqid_t id, 107 xfs_dqid_t id,
@@ -286,7 +286,9 @@ xfs_qm_adjust_dqlimits(
286 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when 286 * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
287 * enforcement's off. 287 * enforcement's off.
288 * In contrast, warnings are a little different in that they don't 288 * In contrast, warnings are a little different in that they don't
289 * 'automatically' get started when limits get exceeded. 289 * 'automatically' get started when limits get exceeded. They do
290 * get reset to zero, however, when we find the count to be under
291 * the soft limit (they are only ever set non-zero via userspace).
290 */ 292 */
291void 293void
292xfs_qm_adjust_dqtimers( 294xfs_qm_adjust_dqtimers(
@@ -315,6 +317,8 @@ xfs_qm_adjust_dqtimers(
315 INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) { 317 INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
316 INT_SET(d->d_btimer, ARCH_CONVERT, 318 INT_SET(d->d_btimer, ARCH_CONVERT,
317 get_seconds() + XFS_QI_BTIMELIMIT(mp)); 319 get_seconds() + XFS_QI_BTIMELIMIT(mp));
320 } else {
321 d->d_bwarns = 0;
318 } 322 }
319 } else { 323 } else {
320 if ((!d->d_blk_softlimit || 324 if ((!d->d_blk_softlimit ||
@@ -336,6 +340,8 @@ xfs_qm_adjust_dqtimers(
336 INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) { 340 INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
337 INT_SET(d->d_itimer, ARCH_CONVERT, 341 INT_SET(d->d_itimer, ARCH_CONVERT,
338 get_seconds() + XFS_QI_ITIMELIMIT(mp)); 342 get_seconds() + XFS_QI_ITIMELIMIT(mp));
343 } else {
344 d->d_iwarns = 0;
339 } 345 }
340 } else { 346 } else {
341 if ((!d->d_ino_softlimit || 347 if ((!d->d_ino_softlimit ||
@@ -357,6 +363,8 @@ xfs_qm_adjust_dqtimers(
357 INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) { 363 INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
358 INT_SET(d->d_rtbtimer, ARCH_CONVERT, 364 INT_SET(d->d_rtbtimer, ARCH_CONVERT,
359 get_seconds() + XFS_QI_RTBTIMELIMIT(mp)); 365 get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
366 } else {
367 d->d_rtbwarns = 0;
360 } 368 }
361 } else { 369 } else {
362 if ((!d->d_rtb_softlimit || 370 if ((!d->d_rtb_softlimit ||
@@ -371,68 +379,6 @@ xfs_qm_adjust_dqtimers(
371} 379}
372 380
373/* 381/*
374 * Increment or reset warnings of a given dquot.
375 */
376int
377xfs_qm_dqwarn(
378 xfs_disk_dquot_t *d,
379 uint flags)
380{
381 int warned;
382
383 /*
384 * root's limits are not real limits.
385 */
386 if (!d->d_id)
387 return (0);
388
389 warned = 0;
390 if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
391 (INT_GET(d->d_bcount, ARCH_CONVERT) >=
392 INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
393 if (flags & XFS_QMOPT_DOWARN) {
394 INT_MOD(d->d_bwarns, ARCH_CONVERT, +1);
395 warned++;
396 }
397 } else {
398 if (!d->d_blk_softlimit ||
399 (INT_GET(d->d_bcount, ARCH_CONVERT) <
400 INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
401 d->d_bwarns = 0;
402 }
403 }
404
405 if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 &&
406 (INT_GET(d->d_icount, ARCH_CONVERT) >=
407 INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
408 if (flags & XFS_QMOPT_DOWARN) {
409 INT_MOD(d->d_iwarns, ARCH_CONVERT, +1);
410 warned++;
411 }
412 } else {
413 if (!d->d_ino_softlimit ||
414 (INT_GET(d->d_icount, ARCH_CONVERT) <
415 INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
416 d->d_iwarns = 0;
417 }
418 }
419#ifdef QUOTADEBUG
420 if (INT_GET(d->d_iwarns, ARCH_CONVERT))
421 cmn_err(CE_DEBUG,
422 "--------@@Inode warnings running : %Lu >= %Lu",
423 INT_GET(d->d_icount, ARCH_CONVERT),
424 INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
425 if (INT_GET(d->d_bwarns, ARCH_CONVERT))
426 cmn_err(CE_DEBUG,
427 "--------@@Blks warnings running : %Lu >= %Lu",
428 INT_GET(d->d_bcount, ARCH_CONVERT),
429 INT_GET(d->d_blk_softlimit, ARCH_CONVERT));
430#endif
431 return (warned);
432}
433
434
435/*
436 * initialize a buffer full of dquots and log the whole thing 382 * initialize a buffer full of dquots and log the whole thing
437 */ 383 */
438STATIC void 384STATIC void
@@ -461,9 +407,9 @@ xfs_qm_init_dquot_blk(
461 for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++) 407 for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++)
462 xfs_qm_dqinit_core(curid, type, d); 408 xfs_qm_dqinit_core(curid, type, d);
463 xfs_trans_dquot_buf(tp, bp, 409 xfs_trans_dquot_buf(tp, bp,
464 type & XFS_DQ_USER ? 410 (type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF :
465 XFS_BLI_UDQUOT_BUF : 411 ((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF :
466 XFS_BLI_GDQUOT_BUF); 412 XFS_BLI_GDQUOT_BUF)));
467 xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1); 413 xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1);
468} 414}
469 415
@@ -544,8 +490,7 @@ xfs_qm_dqalloc(
544 * the entire thing. 490 * the entire thing.
545 */ 491 */
546 xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT), 492 xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
547 dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP), 493 dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
548 bp);
549 494
550 if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) { 495 if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) {
551 goto error1; 496 goto error1;
@@ -675,8 +620,7 @@ xfs_qm_dqtobp(
675 /* 620 /*
676 * A simple sanity check in case we got a corrupted dquot... 621 * A simple sanity check in case we got a corrupted dquot...
677 */ 622 */
678 if (xfs_qm_dqcheck(ddq, id, 623 if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES,
679 dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
680 flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN), 624 flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN),
681 "dqtobp")) { 625 "dqtobp")) {
682 if (!(flags & XFS_QMOPT_DQREPAIR)) { 626 if (!(flags & XFS_QMOPT_DQREPAIR)) {
@@ -953,8 +897,8 @@ int
953xfs_qm_dqget( 897xfs_qm_dqget(
954 xfs_mount_t *mp, 898 xfs_mount_t *mp,
955 xfs_inode_t *ip, /* locked inode (optional) */ 899 xfs_inode_t *ip, /* locked inode (optional) */
956 xfs_dqid_t id, /* gid or uid, depending on type */ 900 xfs_dqid_t id, /* uid/projid/gid depending on type */
957 uint type, /* UDQUOT or GDQUOT */ 901 uint type, /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
958 uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */ 902 uint flags, /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
959 xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */ 903 xfs_dquot_t **O_dqpp) /* OUT : locked incore dquot */
960{ 904{
@@ -965,6 +909,7 @@ xfs_qm_dqget(
965 909
966 ASSERT(XFS_IS_QUOTA_RUNNING(mp)); 910 ASSERT(XFS_IS_QUOTA_RUNNING(mp));
967 if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) || 911 if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) ||
912 (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) ||
968 (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) { 913 (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
969 return (ESRCH); 914 return (ESRCH);
970 } 915 }
@@ -983,7 +928,9 @@ xfs_qm_dqget(
983 again: 928 again:
984 929
985#ifdef DEBUG 930#ifdef DEBUG
986 ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP); 931 ASSERT(type == XFS_DQ_USER ||
932 type == XFS_DQ_PROJ ||
933 type == XFS_DQ_GROUP);
987 if (ip) { 934 if (ip) {
988 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 935 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
989 if (type == XFS_DQ_USER) 936 if (type == XFS_DQ_USER)
@@ -1306,8 +1253,8 @@ xfs_qm_dqflush(
1306 return (error); 1253 return (error);
1307 } 1254 }
1308 1255
1309 if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN, 1256 if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT),
1310 "dqflush (incore copy)")) { 1257 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
1311 xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); 1258 xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
1312 return XFS_ERROR(EIO); 1259 return XFS_ERROR(EIO);
1313 } 1260 }
@@ -1459,7 +1406,8 @@ xfs_dqlock2(
1459{ 1406{
1460 if (d1 && d2) { 1407 if (d1 && d2) {
1461 ASSERT(d1 != d2); 1408 ASSERT(d1 != d2);
1462 if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) { 1409 if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) >
1410 INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
1463 xfs_dqlock(d2); 1411 xfs_dqlock(d2);
1464 xfs_dqlock(d1); 1412 xfs_dqlock(d1);
1465 } else { 1413 } else {
@@ -1582,8 +1530,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp)
1582 cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------"); 1530 cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
1583 cmn_err(CE_DEBUG, "---- dquotID = %d", 1531 cmn_err(CE_DEBUG, "---- dquotID = %d",
1584 (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT)); 1532 (int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
1585 cmn_err(CE_DEBUG, "---- type = %s", 1533 cmn_err(CE_DEBUG, "---- type = %s", DQFLAGTO_TYPESTR(dqp));
1586 XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
1587 cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount); 1534 cmn_err(CE_DEBUG, "---- fs = 0x%p", dqp->q_mount);
1588 cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno); 1535 cmn_err(CE_DEBUG, "---- blkno = 0x%x", (int) dqp->q_blkno);
1589 cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset); 1536 cmn_err(CE_DEBUG, "---- boffset = 0x%x", (int) dqp->q_bufoffset);
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index 0c3fe3175baa..39175103c8e0 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -114,25 +114,18 @@ typedef struct xfs_dquot {
114#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) 114#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++)
115 115
116/* 116/*
117 * Quota Accounting flags 117 * Quota Accounting/Enforcement flags
118 */ 118 */
119#define XFS_ALL_QUOTA_ACCT (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT) 119#define XFS_ALL_QUOTA_ACCT \
120#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD) 120 (XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
121#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD) 121#define XFS_ALL_QUOTA_ENFD (XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
122#define XFS_ALL_QUOTA_ACTV (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE) 122#define XFS_ALL_QUOTA_CHKD (XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
123#define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
124 XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD)
125 123
126#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) 124#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
127#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
128#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
129
130/*
131 * Quota Limit Enforcement flags
132 */
133#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD) 125#define XFS_IS_QUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
134#define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) 126#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
135#define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) 127#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT)
128#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
136 129
137#ifdef DEBUG 130#ifdef DEBUG
138static inline int 131static inline int
@@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
167#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) 160#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
168#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) 161#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
169#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) 162#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
163#define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ)
164#define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP)
170#define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo) 165#define XFS_DQ_TO_QINF(dqp) ((dqp)->q_mount->m_quotainfo)
171#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \ 166#define XFS_DQ_TO_QIP(dqp) (XFS_QM_ISUDQ(dqp) ? \
172 XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \ 167 XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
174 169
175#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \ 170#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \
176 (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ 171 (XFS_IS_UQUOTA_ON((d)->q_mount)) : \
177 (XFS_IS_GQUOTA_ON((d)->q_mount)))) 172 (XFS_IS_OQUOTA_ON((d)->q_mount))))
178 173
179#ifdef XFS_DQUOT_TRACE 174#ifdef XFS_DQUOT_TRACE
180/* 175/*
@@ -211,7 +206,6 @@ extern void xfs_qm_adjust_dqtimers(xfs_mount_t *,
211 xfs_disk_dquot_t *); 206 xfs_disk_dquot_t *);
212extern void xfs_qm_adjust_dqlimits(xfs_mount_t *, 207extern void xfs_qm_adjust_dqlimits(xfs_mount_t *,
213 xfs_disk_dquot_t *); 208 xfs_disk_dquot_t *);
214extern int xfs_qm_dqwarn(xfs_disk_dquot_t *, uint);
215extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *, 209extern int xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
216 xfs_dqid_t, uint, uint, xfs_dquot_t **); 210 xfs_dqid_t, uint, uint, xfs_dquot_t **);
217extern void xfs_qm_dqput(xfs_dquot_t *); 211extern void xfs_qm_dqput(xfs_dquot_t *);
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index a5425ee6e7bd..f5271b7b1e84 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -428,7 +428,7 @@ xfs_qm_dquot_logitem_committing(
428/* 428/*
429 * This is the ops vector for dquots 429 * This is the ops vector for dquots
430 */ 430 */
431struct xfs_item_ops xfs_dquot_item_ops = { 431STATIC struct xfs_item_ops xfs_dquot_item_ops = {
432 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size, 432 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
433 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 433 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
434 xfs_qm_dquot_logitem_format, 434 xfs_qm_dquot_logitem_format,
@@ -646,7 +646,7 @@ xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
646 return; 646 return;
647} 647}
648 648
649struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { 649STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
650 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, 650 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
651 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 651 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
652 xfs_qm_qoff_logitem_format, 652 xfs_qm_qoff_logitem_format,
@@ -669,7 +669,7 @@ struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
669/* 669/*
670 * This is the ops vector shared by all quotaoff-start log items. 670 * This is the ops vector shared by all quotaoff-start log items.
671 */ 671 */
672struct xfs_item_ops xfs_qm_qoff_logitem_ops = { 672STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
673 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size, 673 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
674 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 674 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
675 xfs_qm_qoff_logitem_format, 675 xfs_qm_qoff_logitem_format,
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 89f2cd656ebf..f665ca8f9e96 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -81,12 +81,18 @@ struct xfs_qm *xfs_Gqm;
81 81
82kmem_zone_t *qm_dqzone; 82kmem_zone_t *qm_dqzone;
83kmem_zone_t *qm_dqtrxzone; 83kmem_zone_t *qm_dqtrxzone;
84kmem_shaker_t xfs_qm_shaker; 84STATIC kmem_shaker_t xfs_qm_shaker;
85 85
86STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); 86STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int);
87STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); 87STATIC void xfs_qm_list_destroy(xfs_dqlist_t *);
88 88
89STATIC void xfs_qm_freelist_init(xfs_frlist_t *);
90STATIC void xfs_qm_freelist_destroy(xfs_frlist_t *);
91STATIC int xfs_qm_mplist_nowait(xfs_mount_t *);
92STATIC int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
93
89STATIC int xfs_qm_init_quotainos(xfs_mount_t *); 94STATIC int xfs_qm_init_quotainos(xfs_mount_t *);
95STATIC int xfs_qm_init_quotainfo(xfs_mount_t *);
90STATIC int xfs_qm_shake(int, unsigned int); 96STATIC int xfs_qm_shake(int, unsigned int);
91 97
92#ifdef DEBUG 98#ifdef DEBUG
@@ -184,7 +190,7 @@ xfs_Gqm_init(void)
184/* 190/*
185 * Destroy the global quota manager when its reference count goes to zero. 191 * Destroy the global quota manager when its reference count goes to zero.
186 */ 192 */
187void 193STATIC void
188xfs_qm_destroy( 194xfs_qm_destroy(
189 struct xfs_qm *xqm) 195 struct xfs_qm *xqm)
190{ 196{
@@ -304,9 +310,9 @@ xfs_qm_mount_quotainit(
304 uint flags) 310 uint flags)
305{ 311{
306 /* 312 /*
307 * User or group quotas has to be on. 313 * User, projects or group quotas has to be on.
308 */ 314 */
309 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)); 315 ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
310 316
311 /* 317 /*
312 * Initialize the flags in the mount structure. From this point 318 * Initialize the flags in the mount structure. From this point
@@ -324,7 +330,11 @@ xfs_qm_mount_quotainit(
324 if (flags & XFSMNT_GQUOTA) { 330 if (flags & XFSMNT_GQUOTA) {
325 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); 331 mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
326 if (flags & XFSMNT_GQUOTAENF) 332 if (flags & XFSMNT_GQUOTAENF)
327 mp->m_qflags |= XFS_GQUOTA_ENFD; 333 mp->m_qflags |= XFS_OQUOTA_ENFD;
334 } else if (flags & XFSMNT_PQUOTA) {
335 mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
336 if (flags & XFSMNT_PQUOTAENF)
337 mp->m_qflags |= XFS_OQUOTA_ENFD;
328 } 338 }
329} 339}
330 340
@@ -357,11 +367,11 @@ xfs_qm_mount_quotas(
357 367
358 /* 368 /*
359 * If a file system had quotas running earlier, but decided to 369 * If a file system had quotas running earlier, but decided to
360 * mount without -o quota/uquota/gquota options, revoke the 370 * mount without -o uquota/pquota/gquota options, revoke the
361 * quotachecked license, and bail out. 371 * quotachecked license, and bail out.
362 */ 372 */
363 if (! XFS_IS_QUOTA_ON(mp) && 373 if (! XFS_IS_QUOTA_ON(mp) &&
364 (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) { 374 (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) {
365 mp->m_qflags = 0; 375 mp->m_qflags = 0;
366 goto write_changes; 376 goto write_changes;
367 } 377 }
@@ -509,7 +519,7 @@ out:
509 * Flush all dquots of the given file system to disk. The dquots are 519 * Flush all dquots of the given file system to disk. The dquots are
510 * _not_ purged from memory here, just their data written to disk. 520 * _not_ purged from memory here, just their data written to disk.
511 */ 521 */
512int 522STATIC int
513xfs_qm_dqflush_all( 523xfs_qm_dqflush_all(
514 xfs_mount_t *mp, 524 xfs_mount_t *mp,
515 int flags) 525 int flags)
@@ -613,7 +623,7 @@ xfs_qm_detach_gdquots(
613STATIC int 623STATIC int
614xfs_qm_dqpurge_int( 624xfs_qm_dqpurge_int(
615 xfs_mount_t *mp, 625 xfs_mount_t *mp,
616 uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */ 626 uint flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */
617{ 627{
618 xfs_dquot_t *dqp; 628 xfs_dquot_t *dqp;
619 uint dqtype; 629 uint dqtype;
@@ -625,6 +635,7 @@ xfs_qm_dqpurge_int(
625 return (0); 635 return (0);
626 636
627 dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0; 637 dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0;
638 dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0;
628 dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0; 639 dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0;
629 640
630 xfs_qm_mplist_lock(mp); 641 xfs_qm_mplist_lock(mp);
@@ -734,11 +745,11 @@ xfs_qm_dqattach_one(
734 745
735 /* 746 /*
736 * udqhint is the i_udquot field in inode, and is non-NULL only 747 * udqhint is the i_udquot field in inode, and is non-NULL only
737 * when the type arg is XFS_DQ_GROUP. Its purpose is to save a 748 * when the type arg is group/project. Its purpose is to save a
738 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside 749 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
739 * the user dquot. 750 * the user dquot.
740 */ 751 */
741 ASSERT(!udqhint || type == XFS_DQ_GROUP); 752 ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
742 if (udqhint && !dolock) 753 if (udqhint && !dolock)
743 xfs_dqlock(udqhint); 754 xfs_dqlock(udqhint);
744 755
@@ -897,8 +908,8 @@ xfs_qm_dqattach_grouphint(
897 908
898 909
899/* 910/*
900 * Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON 911 * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
901 * in to account. 912 * into account.
902 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed. 913 * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
903 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty 914 * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
904 * much made this code a complete mess, but it has been pretty useful. 915 * much made this code a complete mess, but it has been pretty useful.
@@ -937,8 +948,13 @@ xfs_qm_dqattach(
937 nquotas++; 948 nquotas++;
938 } 949 }
939 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 950 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
940 if (XFS_IS_GQUOTA_ON(mp)) { 951 if (XFS_IS_OQUOTA_ON(mp)) {
941 error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP, 952 error = XFS_IS_GQUOTA_ON(mp) ?
953 xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
954 flags & XFS_QMOPT_DQALLOC,
955 flags & XFS_QMOPT_DQLOCK,
956 ip->i_udquot, &ip->i_gdquot) :
957 xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
942 flags & XFS_QMOPT_DQALLOC, 958 flags & XFS_QMOPT_DQALLOC,
943 flags & XFS_QMOPT_DQLOCK, 959 flags & XFS_QMOPT_DQLOCK,
944 ip->i_udquot, &ip->i_gdquot); 960 ip->i_udquot, &ip->i_gdquot);
@@ -989,7 +1005,7 @@ xfs_qm_dqattach(
989 } 1005 }
990 if (XFS_IS_UQUOTA_ON(mp)) 1006 if (XFS_IS_UQUOTA_ON(mp))
991 ASSERT(ip->i_udquot); 1007 ASSERT(ip->i_udquot);
992 if (XFS_IS_GQUOTA_ON(mp)) 1008 if (XFS_IS_OQUOTA_ON(mp))
993 ASSERT(ip->i_gdquot); 1009 ASSERT(ip->i_gdquot);
994 } 1010 }
995#endif 1011#endif
@@ -1018,13 +1034,13 @@ xfs_qm_dqdetach(
1018 1034
1019 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); 1035 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
1020 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); 1036 ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
1021 if (ip->i_udquot)
1022 xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
1023 if (ip->i_udquot) { 1037 if (ip->i_udquot) {
1038 xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
1024 xfs_qm_dqrele(ip->i_udquot); 1039 xfs_qm_dqrele(ip->i_udquot);
1025 ip->i_udquot = NULL; 1040 ip->i_udquot = NULL;
1026 } 1041 }
1027 if (ip->i_gdquot) { 1042 if (ip->i_gdquot) {
1043 xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip);
1028 xfs_qm_dqrele(ip->i_gdquot); 1044 xfs_qm_dqrele(ip->i_gdquot);
1029 ip->i_gdquot = NULL; 1045 ip->i_gdquot = NULL;
1030 } 1046 }
@@ -1149,7 +1165,7 @@ xfs_qm_sync(
1149 * This initializes all the quota information that's kept in the 1165 * This initializes all the quota information that's kept in the
1150 * mount structure 1166 * mount structure
1151 */ 1167 */
1152int 1168STATIC int
1153xfs_qm_init_quotainfo( 1169xfs_qm_init_quotainfo(
1154 xfs_mount_t *mp) 1170 xfs_mount_t *mp)
1155{ 1171{
@@ -1202,8 +1218,9 @@ xfs_qm_init_quotainfo(
1202 * and group quotas, at least not at this point. 1218 * and group quotas, at least not at this point.
1203 */ 1219 */
1204 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0, 1220 error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0,
1205 (XFS_IS_UQUOTA_RUNNING(mp)) ? 1221 XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER :
1206 XFS_DQ_USER : XFS_DQ_GROUP, 1222 (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP :
1223 XFS_DQ_PROJ),
1207 XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN, 1224 XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
1208 &dqp); 1225 &dqp);
1209 if (! error) { 1226 if (! error) {
@@ -1234,6 +1251,10 @@ xfs_qm_init_quotainfo(
1234 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ? 1251 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
1235 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) : 1252 INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
1236 XFS_QM_IWARNLIMIT; 1253 XFS_QM_IWARNLIMIT;
1254 qinf->qi_rtbwarnlimit =
1255 INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ?
1256 INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) :
1257 XFS_QM_RTBWARNLIMIT;
1237 qinf->qi_bhardlimit = 1258 qinf->qi_bhardlimit =
1238 INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT); 1259 INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
1239 qinf->qi_bsoftlimit = 1260 qinf->qi_bsoftlimit =
@@ -1259,6 +1280,7 @@ xfs_qm_init_quotainfo(
1259 qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT; 1280 qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT;
1260 qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT; 1281 qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT;
1261 qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT; 1282 qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT;
1283 qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
1262 } 1284 }
1263 1285
1264 return (0); 1286 return (0);
@@ -1366,13 +1388,20 @@ xfs_qm_dqget_noattach(
1366 ASSERT(udqp); 1388 ASSERT(udqp);
1367 } 1389 }
1368 1390
1369 if (XFS_IS_GQUOTA_ON(mp)) { 1391 if (XFS_IS_OQUOTA_ON(mp)) {
1370 ASSERT(ip->i_gdquot == NULL); 1392 ASSERT(ip->i_gdquot == NULL);
1371 if (udqp) 1393 if (udqp)
1372 xfs_dqunlock(udqp); 1394 xfs_dqunlock(udqp);
1373 if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP, 1395 error = XFS_IS_GQUOTA_ON(mp) ?
1374 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN, 1396 xfs_qm_dqget(mp, ip,
1375 &gdqp))) { 1397 ip->i_d.di_gid, XFS_DQ_GROUP,
1398 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
1399 &gdqp) :
1400 xfs_qm_dqget(mp, ip,
1401 ip->i_d.di_projid, XFS_DQ_PROJ,
1402 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
1403 &gdqp);
1404 if (error) {
1376 if (udqp) 1405 if (udqp)
1377 xfs_qm_dqrele(udqp); 1406 xfs_qm_dqrele(udqp);
1378 ASSERT(error != ESRCH); 1407 ASSERT(error != ESRCH);
@@ -1521,8 +1550,10 @@ xfs_qm_reset_dqcounts(
1521 INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL); 1550 INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL);
1522 INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0); 1551 INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0);
1523 INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0); 1552 INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0);
1553 INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, (time_t)0);
1524 INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL); 1554 INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL);
1525 INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL); 1555 INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL);
1556 INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, 0UL);
1526 ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1); 1557 ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
1527 } 1558 }
1528 1559
@@ -1541,11 +1572,14 @@ xfs_qm_dqiter_bufs(
1541 int error; 1572 int error;
1542 int notcommitted; 1573 int notcommitted;
1543 int incr; 1574 int incr;
1575 int type;
1544 1576
1545 ASSERT(blkcnt > 0); 1577 ASSERT(blkcnt > 0);
1546 notcommitted = 0; 1578 notcommitted = 0;
1547 incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ? 1579 incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ?
1548 XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt; 1580 XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt;
1581 type = flags & XFS_QMOPT_UQUOTA ? XFS_DQ_USER :
1582 (flags & XFS_QMOPT_PQUOTA ? XFS_DQ_PROJ : XFS_DQ_GROUP);
1549 error = 0; 1583 error = 0;
1550 1584
1551 /* 1585 /*
@@ -1564,9 +1598,7 @@ xfs_qm_dqiter_bufs(
1564 if (error) 1598 if (error)
1565 break; 1599 break;
1566 1600
1567 (void) xfs_qm_reset_dqcounts(mp, bp, firstid, 1601 (void) xfs_qm_reset_dqcounts(mp, bp, firstid, type);
1568 flags & XFS_QMOPT_UQUOTA ?
1569 XFS_DQ_USER : XFS_DQ_GROUP);
1570 xfs_bdwrite(mp, bp); 1602 xfs_bdwrite(mp, bp);
1571 /* 1603 /*
1572 * goto the next block. 1604 * goto the next block.
@@ -1578,7 +1610,7 @@ xfs_qm_dqiter_bufs(
1578} 1610}
1579 1611
1580/* 1612/*
1581 * Iterate over all allocated USR/GRP dquots in the system, calling a 1613 * Iterate over all allocated USR/GRP/PRJ dquots in the system, calling a
1582 * caller supplied function for every chunk of dquots that we find. 1614 * caller supplied function for every chunk of dquots that we find.
1583 */ 1615 */
1584STATIC int 1616STATIC int
@@ -1849,7 +1881,7 @@ xfs_qm_dqusage_adjust(
1849 xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks); 1881 xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks);
1850 xfs_qm_dqput(udqp); 1882 xfs_qm_dqput(udqp);
1851 } 1883 }
1852 if (XFS_IS_GQUOTA_ON(mp)) { 1884 if (XFS_IS_OQUOTA_ON(mp)) {
1853 ASSERT(gdqp); 1885 ASSERT(gdqp);
1854 xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks); 1886 xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks);
1855 xfs_qm_dqput(gdqp); 1887 xfs_qm_dqput(gdqp);
@@ -1898,7 +1930,7 @@ xfs_qm_quotacheck(
1898 cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname); 1930 cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname);
1899 1931
1900 /* 1932 /*
1901 * First we go thru all the dquots on disk, USR and GRP, and reset 1933 * First we go thru all the dquots on disk, USR and GRP/PRJ, and reset
1902 * their counters to zero. We need a clean slate. 1934 * their counters to zero. We need a clean slate.
1903 * We don't log our changes till later. 1935 * We don't log our changes till later.
1904 */ 1936 */
@@ -1909,9 +1941,10 @@ xfs_qm_quotacheck(
1909 } 1941 }
1910 1942
1911 if ((gip = XFS_QI_GQIP(mp))) { 1943 if ((gip = XFS_QI_GQIP(mp))) {
1912 if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA))) 1944 if ((error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
1945 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA)))
1913 goto error_return; 1946 goto error_return;
1914 flags |= XFS_GQUOTA_CHKD; 1947 flags |= XFS_OQUOTA_CHKD;
1915 } 1948 }
1916 1949
1917 do { 1950 do {
@@ -1938,7 +1971,7 @@ xfs_qm_quotacheck(
1938 if (error) { 1971 if (error) {
1939 xfs_qm_dqpurge_all(mp, 1972 xfs_qm_dqpurge_all(mp,
1940 XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA| 1973 XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA|
1941 XFS_QMOPT_QUOTAOFF); 1974 XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF);
1942 goto error_return; 1975 goto error_return;
1943 } 1976 }
1944 /* 1977 /*
@@ -1961,7 +1994,7 @@ xfs_qm_quotacheck(
1961 * quotachecked status, since we won't be doing accounting for 1994 * quotachecked status, since we won't be doing accounting for
1962 * that type anymore. 1995 * that type anymore.
1963 */ 1996 */
1964 mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD); 1997 mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD);
1965 mp->m_qflags |= flags; 1998 mp->m_qflags |= flags;
1966 1999
1967 XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++"); 2000 XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
@@ -2013,7 +2046,7 @@ xfs_qm_init_quotainos(
2013 0, 0, &uip, 0))) 2046 0, 0, &uip, 0)))
2014 return XFS_ERROR(error); 2047 return XFS_ERROR(error);
2015 } 2048 }
2016 if (XFS_IS_GQUOTA_ON(mp) && 2049 if (XFS_IS_OQUOTA_ON(mp) &&
2017 mp->m_sb.sb_gquotino != NULLFSINO) { 2050 mp->m_sb.sb_gquotino != NULLFSINO) {
2018 ASSERT(mp->m_sb.sb_gquotino > 0); 2051 ASSERT(mp->m_sb.sb_gquotino > 0);
2019 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 2052 if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
@@ -2043,10 +2076,12 @@ xfs_qm_init_quotainos(
2043 2076
2044 flags &= ~XFS_QMOPT_SBVERSION; 2077 flags &= ~XFS_QMOPT_SBVERSION;
2045 } 2078 }
2046 if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { 2079 if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) {
2047 if ((error = xfs_qm_qino_alloc(mp, &gip, 2080 flags |= (XFS_IS_GQUOTA_ON(mp) ?
2048 sbflags | XFS_SB_GQUOTINO, 2081 XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
2049 flags | XFS_QMOPT_GQUOTA))) { 2082 error = xfs_qm_qino_alloc(mp, &gip,
2083 sbflags | XFS_SB_GQUOTINO, flags);
2084 if (error) {
2050 if (uip) 2085 if (uip)
2051 VN_RELE(XFS_ITOV(uip)); 2086 VN_RELE(XFS_ITOV(uip));
2052 2087
@@ -2452,6 +2487,7 @@ xfs_qm_vop_dqalloc(
2452 xfs_inode_t *ip, 2487 xfs_inode_t *ip,
2453 uid_t uid, 2488 uid_t uid,
2454 gid_t gid, 2489 gid_t gid,
2490 prid_t prid,
2455 uint flags, 2491 uint flags,
2456 xfs_dquot_t **O_udqpp, 2492 xfs_dquot_t **O_udqpp,
2457 xfs_dquot_t **O_gdqpp) 2493 xfs_dquot_t **O_gdqpp)
@@ -2483,8 +2519,7 @@ xfs_qm_vop_dqalloc(
2483 } 2519 }
2484 2520
2485 uq = gq = NULL; 2521 uq = gq = NULL;
2486 if ((flags & XFS_QMOPT_UQUOTA) && 2522 if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
2487 XFS_IS_UQUOTA_ON(mp)) {
2488 if (ip->i_d.di_uid != uid) { 2523 if (ip->i_d.di_uid != uid) {
2489 /* 2524 /*
2490 * What we need is the dquot that has this uid, and 2525 * What we need is the dquot that has this uid, and
@@ -2522,8 +2557,7 @@ xfs_qm_vop_dqalloc(
2522 xfs_dqunlock(uq); 2557 xfs_dqunlock(uq);
2523 } 2558 }
2524 } 2559 }
2525 if ((flags & XFS_QMOPT_GQUOTA) && 2560 if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
2526 XFS_IS_GQUOTA_ON(mp)) {
2527 if (ip->i_d.di_gid != gid) { 2561 if (ip->i_d.di_gid != gid) {
2528 xfs_iunlock(ip, lockflags); 2562 xfs_iunlock(ip, lockflags);
2529 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, 2563 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
@@ -2546,6 +2580,29 @@ xfs_qm_vop_dqalloc(
2546 XFS_DQHOLD(gq); 2580 XFS_DQHOLD(gq);
2547 xfs_dqunlock(gq); 2581 xfs_dqunlock(gq);
2548 } 2582 }
2583 } else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
2584 if (ip->i_d.di_projid != prid) {
2585 xfs_iunlock(ip, lockflags);
2586 if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
2587 XFS_DQ_PROJ,
2588 XFS_QMOPT_DQALLOC |
2589 XFS_QMOPT_DOWARN,
2590 &gq))) {
2591 if (uq)
2592 xfs_qm_dqrele(uq);
2593 ASSERT(error != ENOENT);
2594 return (error);
2595 }
2596 xfs_dqunlock(gq);
2597 lockflags = XFS_ILOCK_SHARED;
2598 xfs_ilock(ip, lockflags);
2599 } else {
2600 ASSERT(ip->i_gdquot);
2601 gq = ip->i_gdquot;
2602 xfs_dqlock(gq);
2603 XFS_DQHOLD(gq);
2604 xfs_dqunlock(gq);
2605 }
2549 } 2606 }
2550 if (uq) 2607 if (uq)
2551 xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); 2608 xfs_dqtrace_entry_ino(uq, "DQALLOC", ip);
@@ -2574,6 +2631,9 @@ xfs_qm_vop_chown(
2574 xfs_dquot_t *newdq) 2631 xfs_dquot_t *newdq)
2575{ 2632{
2576 xfs_dquot_t *prevdq; 2633 xfs_dquot_t *prevdq;
2634 uint bfield = XFS_IS_REALTIME_INODE(ip) ?
2635 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;
2636
2577 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 2637 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
2578 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); 2638 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
2579 2639
@@ -2582,20 +2642,12 @@ xfs_qm_vop_chown(
2582 ASSERT(prevdq); 2642 ASSERT(prevdq);
2583 ASSERT(prevdq != newdq); 2643 ASSERT(prevdq != newdq);
2584 2644
2585 xfs_trans_mod_dquot(tp, prevdq, 2645 xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks));
2586 XFS_TRANS_DQ_BCOUNT, 2646 xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1);
2587 -(ip->i_d.di_nblocks));
2588 xfs_trans_mod_dquot(tp, prevdq,
2589 XFS_TRANS_DQ_ICOUNT,
2590 -1);
2591 2647
2592 /* the sparkling new dquot */ 2648 /* the sparkling new dquot */
2593 xfs_trans_mod_dquot(tp, newdq, 2649 xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks);
2594 XFS_TRANS_DQ_BCOUNT, 2650 xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1);
2595 ip->i_d.di_nblocks);
2596 xfs_trans_mod_dquot(tp, newdq,
2597 XFS_TRANS_DQ_ICOUNT,
2598 1);
2599 2651
2600 /* 2652 /*
2601 * Take an extra reference, because the inode 2653 * Take an extra reference, because the inode
@@ -2611,7 +2663,7 @@ xfs_qm_vop_chown(
2611} 2663}
2612 2664
2613/* 2665/*
2614 * Quota reservations for setattr(AT_UID|AT_GID). 2666 * Quota reservations for setattr(AT_UID|AT_GID|AT_PROJID).
2615 */ 2667 */
2616int 2668int
2617xfs_qm_vop_chown_reserve( 2669xfs_qm_vop_chown_reserve(
@@ -2623,7 +2675,7 @@ xfs_qm_vop_chown_reserve(
2623{ 2675{
2624 int error; 2676 int error;
2625 xfs_mount_t *mp; 2677 xfs_mount_t *mp;
2626 uint delblks; 2678 uint delblks, blkflags;
2627 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; 2679 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
2628 2680
2629 ASSERT(XFS_ISLOCKED_INODE(ip)); 2681 ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2632,6 +2684,8 @@ xfs_qm_vop_chown_reserve(
2632 2684
2633 delblks = ip->i_delayed_blks; 2685 delblks = ip->i_delayed_blks;
2634 delblksudq = delblksgdq = unresudq = unresgdq = NULL; 2686 delblksudq = delblksgdq = unresudq = unresgdq = NULL;
2687 blkflags = XFS_IS_REALTIME_INODE(ip) ?
2688 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
2635 2689
2636 if (XFS_IS_UQUOTA_ON(mp) && udqp && 2690 if (XFS_IS_UQUOTA_ON(mp) && udqp &&
2637 ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) { 2691 ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) {
@@ -2646,18 +2700,22 @@ xfs_qm_vop_chown_reserve(
2646 unresudq = ip->i_udquot; 2700 unresudq = ip->i_udquot;
2647 } 2701 }
2648 } 2702 }
2649 if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp && 2703 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
2650 ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) { 2704 if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid !=
2651 delblksgdq = gdqp; 2705 INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) ||
2652 if (delblks) { 2706 (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid !=
2653 ASSERT(ip->i_gdquot); 2707 INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) {
2654 unresgdq = ip->i_gdquot; 2708 delblksgdq = gdqp;
2709 if (delblks) {
2710 ASSERT(ip->i_gdquot);
2711 unresgdq = ip->i_gdquot;
2712 }
2655 } 2713 }
2656 } 2714 }
2657 2715
2658 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, 2716 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
2659 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, 2717 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
2660 flags | XFS_QMOPT_RES_REGBLKS))) 2718 flags | blkflags)))
2661 return (error); 2719 return (error);
2662 2720
2663 /* 2721 /*
@@ -2674,11 +2732,11 @@ xfs_qm_vop_chown_reserve(
2674 ASSERT(unresudq || unresgdq); 2732 ASSERT(unresudq || unresgdq);
2675 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2733 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2676 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, 2734 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
2677 flags | XFS_QMOPT_RES_REGBLKS))) 2735 flags | blkflags)))
2678 return (error); 2736 return (error);
2679 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2737 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2680 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, 2738 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
2681 XFS_QMOPT_RES_REGBLKS); 2739 blkflags);
2682 } 2740 }
2683 2741
2684 return (0); 2742 return (0);
@@ -2751,7 +2809,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
2751} 2809}
2752 2810
2753/* ------------- list stuff -----------------*/ 2811/* ------------- list stuff -----------------*/
2754void 2812STATIC void
2755xfs_qm_freelist_init(xfs_frlist_t *ql) 2813xfs_qm_freelist_init(xfs_frlist_t *ql)
2756{ 2814{
2757 ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql; 2815 ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql;
@@ -2760,7 +2818,7 @@ xfs_qm_freelist_init(xfs_frlist_t *ql)
2760 ql->qh_nelems = 0; 2818 ql->qh_nelems = 0;
2761} 2819}
2762 2820
2763void 2821STATIC void
2764xfs_qm_freelist_destroy(xfs_frlist_t *ql) 2822xfs_qm_freelist_destroy(xfs_frlist_t *ql)
2765{ 2823{
2766 xfs_dquot_t *dqp, *nextdqp; 2824 xfs_dquot_t *dqp, *nextdqp;
@@ -2786,7 +2844,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql)
2786 ASSERT(ql->qh_nelems == 0); 2844 ASSERT(ql->qh_nelems == 0);
2787} 2845}
2788 2846
2789void 2847STATIC void
2790xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq) 2848xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq)
2791{ 2849{
2792 dq->dq_flnext = ql->qh_next; 2850 dq->dq_flnext = ql->qh_next;
@@ -2816,7 +2874,7 @@ xfs_qm_freelist_append(xfs_frlist_t *ql, xfs_dquot_t *dq)
2816 xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq); 2874 xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
2817} 2875}
2818 2876
2819int 2877STATIC int
2820xfs_qm_dqhashlock_nowait( 2878xfs_qm_dqhashlock_nowait(
2821 xfs_dquot_t *dqp) 2879 xfs_dquot_t *dqp)
2822{ 2880{
@@ -2836,7 +2894,7 @@ xfs_qm_freelist_lock_nowait(
2836 return (locked); 2894 return (locked);
2837} 2895}
2838 2896
2839int 2897STATIC int
2840xfs_qm_mplist_nowait( 2898xfs_qm_mplist_nowait(
2841 xfs_mount_t *mp) 2899 xfs_mount_t *mp)
2842{ 2900{
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index dcf1a7a831d8..b03eecf3b6cb 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -133,8 +133,9 @@ typedef struct xfs_quotainfo {
133 time_t qi_btimelimit; /* limit for blks timer */ 133 time_t qi_btimelimit; /* limit for blks timer */
134 time_t qi_itimelimit; /* limit for inodes timer */ 134 time_t qi_itimelimit; /* limit for inodes timer */
135 time_t qi_rtbtimelimit;/* limit for rt blks timer */ 135 time_t qi_rtbtimelimit;/* limit for rt blks timer */
136 xfs_qwarncnt_t qi_bwarnlimit; /* limit for num warnings */ 136 xfs_qwarncnt_t qi_bwarnlimit; /* limit for blks warnings */
137 xfs_qwarncnt_t qi_iwarnlimit; /* limit for num warnings */ 137 xfs_qwarncnt_t qi_iwarnlimit; /* limit for inodes warnings */
138 xfs_qwarncnt_t qi_rtbwarnlimit;/* limit for rt blks warnings */
138 mutex_t qi_quotaofflock;/* to serialize quotaoff */ 139 mutex_t qi_quotaofflock;/* to serialize quotaoff */
139 xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ 140 xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */
140 uint qi_dqperchunk; /* # ondisk dqs in above chunk */ 141 uint qi_dqperchunk; /* # ondisk dqs in above chunk */
@@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct {
176 177
177#define XFS_QM_BWARNLIMIT 5 178#define XFS_QM_BWARNLIMIT 5
178#define XFS_QM_IWARNLIMIT 5 179#define XFS_QM_IWARNLIMIT 5
180#define XFS_QM_RTBWARNLIMIT 5
179 181
180#define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD)) 182#define XFS_QM_LOCK(xqm) (mutex_lock(&xqm##_lock, PINOD))
181#define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock)) 183#define XFS_QM_UNLOCK(xqm) (mutex_unlock(&xqm##_lock))
@@ -184,7 +186,6 @@ typedef struct xfs_dquot_acct {
184 186
185extern void xfs_mount_reset_sbqflags(xfs_mount_t *); 187extern void xfs_mount_reset_sbqflags(xfs_mount_t *);
186 188
187extern int xfs_qm_init_quotainfo(xfs_mount_t *);
188extern void xfs_qm_destroy_quotainfo(xfs_mount_t *); 189extern void xfs_qm_destroy_quotainfo(xfs_mount_t *);
189extern int xfs_qm_mount_quotas(xfs_mount_t *, int); 190extern int xfs_qm_mount_quotas(xfs_mount_t *, int);
190extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint); 191extern void xfs_qm_mount_quotainit(xfs_mount_t *, uint);
@@ -203,7 +204,7 @@ extern void xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
203 204
204/* vop stuff */ 205/* vop stuff */
205extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *, 206extern int xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
206 uid_t, gid_t, uint, 207 uid_t, gid_t, prid_t, uint,
207 xfs_dquot_t **, xfs_dquot_t **); 208 xfs_dquot_t **, xfs_dquot_t **);
208extern void xfs_qm_vop_dqattach_and_dqmod_newinode( 209extern void xfs_qm_vop_dqattach_and_dqmod_newinode(
209 xfs_trans_t *, xfs_inode_t *, 210 xfs_trans_t *, xfs_inode_t *,
@@ -215,14 +216,9 @@ extern int xfs_qm_vop_chown_reserve(xfs_trans_t *, xfs_inode_t *,
215 xfs_dquot_t *, xfs_dquot_t *, uint); 216 xfs_dquot_t *, xfs_dquot_t *, uint);
216 217
217/* list stuff */ 218/* list stuff */
218extern void xfs_qm_freelist_init(xfs_frlist_t *);
219extern void xfs_qm_freelist_destroy(xfs_frlist_t *);
220extern void xfs_qm_freelist_insert(xfs_frlist_t *, xfs_dquot_t *);
221extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *); 219extern void xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
222extern void xfs_qm_freelist_unlink(xfs_dquot_t *); 220extern void xfs_qm_freelist_unlink(xfs_dquot_t *);
223extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *); 221extern int xfs_qm_freelist_lock_nowait(xfs_qm_t *);
224extern int xfs_qm_mplist_nowait(xfs_mount_t *);
225extern int xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
226 222
227/* system call interface */ 223/* system call interface */
228extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t); 224extern int xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index be67d9c265f8..dc3c37a1e158 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -71,10 +71,13 @@
71#define MNTOPT_NOQUOTA "noquota" /* no quotas */ 71#define MNTOPT_NOQUOTA "noquota" /* no quotas */
72#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */ 72#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
73#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */ 73#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
74#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
74#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */ 75#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
75#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */ 76#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
77#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
76#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */ 78#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
77#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */ 79#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
80#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
78#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */ 81#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
79 82
80STATIC int 83STATIC int
@@ -109,6 +112,14 @@ xfs_qm_parseargs(
109 args->flags |= XFSMNT_UQUOTA; 112 args->flags |= XFSMNT_UQUOTA;
110 args->flags &= ~XFSMNT_UQUOTAENF; 113 args->flags &= ~XFSMNT_UQUOTAENF;
111 referenced = 1; 114 referenced = 1;
115 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
116 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
117 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
118 referenced = 1;
119 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
120 args->flags |= XFSMNT_PQUOTA;
121 args->flags &= ~XFSMNT_PQUOTAENF;
122 referenced = 1;
112 } else if (!strcmp(this_char, MNTOPT_GQUOTA) || 123 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
113 !strcmp(this_char, MNTOPT_GRPQUOTA)) { 124 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
114 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF; 125 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
@@ -127,6 +138,12 @@ xfs_qm_parseargs(
127 *this_char++ = ','; 138 *this_char++ = ',';
128 } 139 }
129 140
141 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
142 cmn_err(CE_WARN,
143 "XFS: cannot mount with both project and group quota");
144 return XFS_ERROR(EINVAL);
145 }
146
130 PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); 147 PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
131 if (!error && !referenced) 148 if (!error && !referenced)
132 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); 149 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
@@ -148,13 +165,19 @@ xfs_qm_showargs(
148 seq_puts(m, "," MNTOPT_UQUOTANOENF); 165 seq_puts(m, "," MNTOPT_UQUOTANOENF);
149 } 166 }
150 167
168 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
169 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
170 seq_puts(m, "," MNTOPT_PRJQUOTA) :
171 seq_puts(m, "," MNTOPT_PQUOTANOENF);
172 }
173
151 if (mp->m_qflags & XFS_GQUOTA_ACCT) { 174 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
152 (mp->m_qflags & XFS_GQUOTA_ENFD) ? 175 (mp->m_qflags & XFS_OQUOTA_ENFD) ?
153 seq_puts(m, "," MNTOPT_GRPQUOTA) : 176 seq_puts(m, "," MNTOPT_GRPQUOTA) :
154 seq_puts(m, "," MNTOPT_GQUOTANOENF); 177 seq_puts(m, "," MNTOPT_GQUOTANOENF);
155 } 178 }
156 179
157 if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) 180 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
158 seq_puts(m, "," MNTOPT_NOQUOTA); 181 seq_puts(m, "," MNTOPT_NOQUOTA);
159 182
160 PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); 183 PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
@@ -171,7 +194,7 @@ xfs_qm_mount(
171 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 194 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
172 int error; 195 int error;
173 196
174 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA)) 197 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
175 xfs_qm_mount_quotainit(mp, args->flags); 198 xfs_qm_mount_quotainit(mp, args->flags);
176 PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); 199 PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
177 return error; 200 return error;
@@ -255,16 +278,17 @@ xfs_qm_newmount(
255 uint *quotaflags) 278 uint *quotaflags)
256{ 279{
257 uint quotaondisk; 280 uint quotaondisk;
258 uint uquotaondisk = 0, gquotaondisk = 0; 281 uint uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
259 282
260 *quotaflags = 0; 283 *quotaflags = 0;
261 *needquotamount = B_FALSE; 284 *needquotamount = B_FALSE;
262 285
263 quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && 286 quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
264 mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT); 287 (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
265 288
266 if (quotaondisk) { 289 if (quotaondisk) {
267 uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT; 290 uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
291 pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
268 gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT; 292 gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
269 } 293 }
270 294
@@ -277,13 +301,16 @@ xfs_qm_newmount(
277 301
278 if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || 302 if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
279 (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || 303 (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) ||
304 (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
305 (!pquotaondisk && XFS_IS_PQUOTA_ON(mp)) ||
280 (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || 306 (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
281 (!gquotaondisk && XFS_IS_GQUOTA_ON(mp))) && 307 (!gquotaondisk && XFS_IS_OQUOTA_ON(mp))) &&
282 xfs_dev_is_read_only(mp, "changing quota state")) { 308 xfs_dev_is_read_only(mp, "changing quota state")) {
283 cmn_err(CE_WARN, 309 cmn_err(CE_WARN,
284 "XFS: please mount with%s%s%s.", 310 "XFS: please mount with%s%s%s%s.",
285 (!quotaondisk ? "out quota" : ""), 311 (!quotaondisk ? "out quota" : ""),
286 (uquotaondisk ? " usrquota" : ""), 312 (uquotaondisk ? " usrquota" : ""),
313 (pquotaondisk ? " prjquota" : ""),
287 (gquotaondisk ? " grpquota" : "")); 314 (gquotaondisk ? " grpquota" : ""));
288 return XFS_ERROR(EPERM); 315 return XFS_ERROR(EPERM);
289 } 316 }
@@ -359,7 +386,7 @@ xfs_qm_dqrele_null(
359} 386}
360 387
361 388
362struct xfs_qmops xfs_qmcore_xfs = { 389STATIC struct xfs_qmops xfs_qmcore_xfs = {
363 .xfs_qminit = xfs_qm_newmount, 390 .xfs_qminit = xfs_qm_newmount,
364 .xfs_qmdone = xfs_qm_unmount_quotadestroy, 391 .xfs_qmdone = xfs_qm_unmount_quotadestroy,
365 .xfs_qmmount = xfs_qm_endmount, 392 .xfs_qmmount = xfs_qm_endmount,
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 229f5b5a2d25..68e98962dbef 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -118,40 +118,41 @@ xfs_qm_quotactl(
118 * The following commands are valid even when quotaoff. 118 * The following commands are valid even when quotaoff.
119 */ 119 */
120 switch (cmd) { 120 switch (cmd) {
121 case Q_XQUOTARM:
121 /* 122 /*
122 * truncate quota files. quota must be off. 123 * Truncate quota files. quota must be off.
123 */ 124 */
124 case Q_XQUOTARM:
125 if (XFS_IS_QUOTA_ON(mp) || addr == NULL) 125 if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
126 return XFS_ERROR(EINVAL); 126 return XFS_ERROR(EINVAL);
127 if (vfsp->vfs_flag & VFS_RDONLY) 127 if (vfsp->vfs_flag & VFS_RDONLY)
128 return XFS_ERROR(EROFS); 128 return XFS_ERROR(EROFS);
129 return (xfs_qm_scall_trunc_qfiles(mp, 129 return (xfs_qm_scall_trunc_qfiles(mp,
130 xfs_qm_import_qtype_flags(*(uint *)addr))); 130 xfs_qm_import_qtype_flags(*(uint *)addr)));
131
132 case Q_XGETQSTAT:
131 /* 133 /*
132 * Get quota status information. 134 * Get quota status information.
133 */ 135 */
134 case Q_XGETQSTAT:
135 return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr)); 136 return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
136 137
138 case Q_XQUOTAON:
137 /* 139 /*
138 * QUOTAON for root f/s and quota enforcement on others.. 140 * QUOTAON - enabling quota enforcement.
139 * Quota accounting for non-root f/s's must be turned on 141 * Quota accounting must be turned on at mount time.
140 * at mount time.
141 */ 142 */
142 case Q_XQUOTAON:
143 if (addr == NULL) 143 if (addr == NULL)
144 return XFS_ERROR(EINVAL); 144 return XFS_ERROR(EINVAL);
145 if (vfsp->vfs_flag & VFS_RDONLY) 145 if (vfsp->vfs_flag & VFS_RDONLY)
146 return XFS_ERROR(EROFS); 146 return XFS_ERROR(EROFS);
147 return (xfs_qm_scall_quotaon(mp, 147 return (xfs_qm_scall_quotaon(mp,
148 xfs_qm_import_flags(*(uint *)addr))); 148 xfs_qm_import_flags(*(uint *)addr)));
149 case Q_XQUOTAOFF: 149
150 case Q_XQUOTAOFF:
150 if (vfsp->vfs_flag & VFS_RDONLY) 151 if (vfsp->vfs_flag & VFS_RDONLY)
151 return XFS_ERROR(EROFS); 152 return XFS_ERROR(EROFS);
152 break; 153 break;
153 154
154 default: 155 default:
155 break; 156 break;
156 } 157 }
157 158
@@ -159,7 +160,7 @@ xfs_qm_quotactl(
159 return XFS_ERROR(ESRCH); 160 return XFS_ERROR(ESRCH);
160 161
161 switch (cmd) { 162 switch (cmd) {
162 case Q_XQUOTAOFF: 163 case Q_XQUOTAOFF:
163 if (vfsp->vfs_flag & VFS_RDONLY) 164 if (vfsp->vfs_flag & VFS_RDONLY)
164 return XFS_ERROR(EROFS); 165 return XFS_ERROR(EROFS);
165 error = xfs_qm_scall_quotaoff(mp, 166 error = xfs_qm_scall_quotaoff(mp,
@@ -167,42 +168,39 @@ xfs_qm_quotactl(
167 B_FALSE); 168 B_FALSE);
168 break; 169 break;
169 170
170 /* 171 case Q_XGETQUOTA:
171 * Defaults to XFS_GETUQUOTA.
172 */
173 case Q_XGETQUOTA:
174 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER, 172 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
175 (fs_disk_quota_t *)addr); 173 (fs_disk_quota_t *)addr);
176 break; 174 break;
177 /* 175 case Q_XGETGQUOTA:
178 * Set limits, both hard and soft. Defaults to Q_SETUQLIM. 176 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
179 */ 177 (fs_disk_quota_t *)addr);
180 case Q_XSETQLIM: 178 break;
179 case Q_XGETPQUOTA:
180 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
181 (fs_disk_quota_t *)addr);
182 break;
183
184 case Q_XSETQLIM:
181 if (vfsp->vfs_flag & VFS_RDONLY) 185 if (vfsp->vfs_flag & VFS_RDONLY)
182 return XFS_ERROR(EROFS); 186 return XFS_ERROR(EROFS);
183 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER, 187 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
184 (fs_disk_quota_t *)addr); 188 (fs_disk_quota_t *)addr);
185 break; 189 break;
186 190 case Q_XSETGQLIM:
187 case Q_XSETGQLIM:
188 if (vfsp->vfs_flag & VFS_RDONLY) 191 if (vfsp->vfs_flag & VFS_RDONLY)
189 return XFS_ERROR(EROFS); 192 return XFS_ERROR(EROFS);
190 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, 193 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
191 (fs_disk_quota_t *)addr); 194 (fs_disk_quota_t *)addr);
192 break; 195 break;
193 196 case Q_XSETPQLIM:
194 197 if (vfsp->vfs_flag & VFS_RDONLY)
195 case Q_XGETGQUOTA: 198 return XFS_ERROR(EROFS);
196 error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP, 199 error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
197 (fs_disk_quota_t *)addr); 200 (fs_disk_quota_t *)addr);
198 break; 201 break;
199 202
200 /* 203 default:
201 * Quotas are entirely undefined after quotaoff in XFS quotas.
202 * For instance, there's no way to set limits when quotaoff.
203 */
204
205 default:
206 error = XFS_ERROR(EINVAL); 204 error = XFS_ERROR(EINVAL);
207 break; 205 break;
208 } 206 }
@@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff(
286 } 284 }
287 if (flags & XFS_GQUOTA_ACCT) { 285 if (flags & XFS_GQUOTA_ACCT) {
288 dqtype |= XFS_QMOPT_GQUOTA; 286 dqtype |= XFS_QMOPT_GQUOTA;
289 flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD); 287 flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
290 inactivate_flags |= XFS_GQUOTA_ACTIVE; 288 inactivate_flags |= XFS_GQUOTA_ACTIVE;
289 } else if (flags & XFS_PQUOTA_ACCT) {
290 dqtype |= XFS_QMOPT_PQUOTA;
291 flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
292 inactivate_flags |= XFS_PQUOTA_ACTIVE;
291 } 293 }
292 294
293 /* 295 /*
@@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff(
364 /* 366 /*
365 * If quotas is completely disabled, close shop. 367 * If quotas is completely disabled, close shop.
366 */ 368 */
367 if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) { 369 if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) ||
370 ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) {
368 mutex_unlock(&(XFS_QI_QOFFLOCK(mp))); 371 mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
369 xfs_qm_destroy_quotainfo(mp); 372 xfs_qm_destroy_quotainfo(mp);
370 return (0); 373 return (0);
@@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff(
378 XFS_PURGE_INODE(XFS_QI_UQIP(mp)); 381 XFS_PURGE_INODE(XFS_QI_UQIP(mp));
379 XFS_QI_UQIP(mp) = NULL; 382 XFS_QI_UQIP(mp) = NULL;
380 } 383 }
381 if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) { 384 if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) {
382 XFS_PURGE_INODE(XFS_QI_GQIP(mp)); 385 XFS_PURGE_INODE(XFS_QI_GQIP(mp));
383 XFS_QI_GQIP(mp) = NULL; 386 XFS_QI_GQIP(mp) = NULL;
384 } 387 }
@@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles(
411 } 414 }
412 } 415 }
413 416
414 if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) { 417 if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) &&
418 mp->m_sb.sb_gquotino != NULLFSINO) {
415 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0); 419 error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0);
416 if (! error) { 420 if (! error) {
417 (void) xfs_truncate_file(mp, qip); 421 (void) xfs_truncate_file(mp, qip);
@@ -434,7 +438,7 @@ xfs_qm_scall_quotaon(
434 uint flags) 438 uint flags)
435{ 439{
436 int error; 440 int error;
437 unsigned long s; 441 unsigned long s;
438 uint qf; 442 uint qf;
439 uint accflags; 443 uint accflags;
440 __int64_t sbflags; 444 __int64_t sbflags;
@@ -468,9 +472,13 @@ xfs_qm_scall_quotaon(
468 (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && 472 (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
469 (flags & XFS_UQUOTA_ENFD)) 473 (flags & XFS_UQUOTA_ENFD))
470 || 474 ||
475 ((flags & XFS_PQUOTA_ACCT) == 0 &&
476 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
477 (flags & XFS_OQUOTA_ENFD))
478 ||
471 ((flags & XFS_GQUOTA_ACCT) == 0 && 479 ((flags & XFS_GQUOTA_ACCT) == 0 &&
472 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && 480 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
473 (flags & XFS_GQUOTA_ENFD))) { 481 (flags & XFS_OQUOTA_ENFD))) {
474 qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n", 482 qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
475 flags, mp->m_sb.sb_qflags); 483 flags, mp->m_sb.sb_qflags);
476 return XFS_ERROR(EINVAL); 484 return XFS_ERROR(EINVAL);
@@ -504,6 +512,10 @@ xfs_qm_scall_quotaon(
504 */ 512 */
505 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != 513 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
506 (mp->m_qflags & XFS_UQUOTA_ACCT)) || 514 (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
515 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
516 (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
517 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
518 (mp->m_qflags & XFS_GQUOTA_ACCT)) ||
507 (flags & XFS_ALL_QUOTA_ENFD) == 0) 519 (flags & XFS_ALL_QUOTA_ENFD) == 0)
508 return (0); 520 return (0);
509 521
@@ -521,7 +533,6 @@ xfs_qm_scall_quotaon(
521} 533}
522 534
523 535
524
525/* 536/*
526 * Return quota status information, such as uquota-off, enforcements, etc. 537 * Return quota status information, such as uquota-off, enforcements, etc.
527 */ 538 */
@@ -606,7 +617,8 @@ xfs_qm_scall_setqlim(
606 if (!capable(CAP_SYS_ADMIN)) 617 if (!capable(CAP_SYS_ADMIN))
607 return XFS_ERROR(EPERM); 618 return XFS_ERROR(EPERM);
608 619
609 if ((newlim->d_fieldmask & (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK)) == 0) 620 if ((newlim->d_fieldmask &
621 (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
610 return (0); 622 return (0);
611 623
612 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM); 624 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
@@ -691,12 +703,23 @@ xfs_qm_scall_setqlim(
691 qdprintk("ihard %Ld < isoft %Ld\n", hard, soft); 703 qdprintk("ihard %Ld < isoft %Ld\n", hard, soft);
692 } 704 }
693 705
706 /*
707 * Update warnings counter(s) if requested
708 */
709 if (newlim->d_fieldmask & FS_DQ_BWARNS)
710 INT_SET(ddq->d_bwarns, ARCH_CONVERT, newlim->d_bwarns);
711 if (newlim->d_fieldmask & FS_DQ_IWARNS)
712 INT_SET(ddq->d_iwarns, ARCH_CONVERT, newlim->d_iwarns);
713 if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
714 INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, newlim->d_rtbwarns);
715
694 if (id == 0) { 716 if (id == 0) {
695 /* 717 /*
696 * Timelimits for the super user set the relative time 718 * Timelimits for the super user set the relative time
697 * the other users can be over quota for this file system. 719 * the other users can be over quota for this file system.
698 * If it is zero a default is used. Ditto for the default 720 * If it is zero a default is used. Ditto for the default
699 * soft and hard limit values (already done, above). 721 * soft and hard limit values (already done, above), and
722 * for warnings.
700 */ 723 */
701 if (newlim->d_fieldmask & FS_DQ_BTIMER) { 724 if (newlim->d_fieldmask & FS_DQ_BTIMER) {
702 mp->m_quotainfo->qi_btimelimit = newlim->d_btimer; 725 mp->m_quotainfo->qi_btimelimit = newlim->d_btimer;
@@ -710,7 +733,13 @@ xfs_qm_scall_setqlim(
710 mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer; 733 mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer;
711 INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer); 734 INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer);
712 } 735 }
713 } else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ { 736 if (newlim->d_fieldmask & FS_DQ_BWARNS)
737 mp->m_quotainfo->qi_bwarnlimit = newlim->d_bwarns;
738 if (newlim->d_fieldmask & FS_DQ_IWARNS)
739 mp->m_quotainfo->qi_iwarnlimit = newlim->d_iwarns;
740 if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
741 mp->m_quotainfo->qi_rtbwarnlimit = newlim->d_rtbwarns;
742 } else {
714 /* 743 /*
715 * If the user is now over quota, start the timelimit. 744 * If the user is now over quota, start the timelimit.
716 * The user will not be 'warned'. 745 * The user will not be 'warned'.
@@ -776,9 +805,9 @@ xfs_qm_log_quotaoff_end(
776 xfs_qoff_logitem_t *startqoff, 805 xfs_qoff_logitem_t *startqoff,
777 uint flags) 806 uint flags)
778{ 807{
779 xfs_trans_t *tp; 808 xfs_trans_t *tp;
780 int error; 809 int error;
781 xfs_qoff_logitem_t *qoffi; 810 xfs_qoff_logitem_t *qoffi;
782 811
783 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END); 812 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
784 813
@@ -928,18 +957,26 @@ xfs_qm_export_dquot(
928 957
929STATIC uint 958STATIC uint
930xfs_qm_import_qtype_flags( 959xfs_qm_import_qtype_flags(
931 uint uflags) 960 uint uflags)
932{ 961{
962 uint oflags = 0;
963
933 /* 964 /*
934 * Can't be both at the same time. 965 * Can't be more than one, or none.
935 */ 966 */
936 if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 967 if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
937 (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) || 968 (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
938 ((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0)) 969 ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
970 (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
971 ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
972 (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
973 ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
939 return (0); 974 return (0);
940 975
941 return (uflags & XFS_USER_QUOTA) ? 976 oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
942 XFS_DQ_USER : XFS_DQ_GROUP; 977 oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
978 oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
979 return oflags;
943} 980}
944 981
945STATIC uint 982STATIC uint
@@ -947,14 +984,19 @@ xfs_qm_export_qtype_flags(
947 uint flags) 984 uint flags)
948{ 985{
949 /* 986 /*
950 * Can't be both at the same time. 987 * Can't be more than one, or none.
951 */ 988 */
952 ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 989 ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) !=
953 (XFS_GROUP_QUOTA | XFS_USER_QUOTA)); 990 (XFS_PROJ_QUOTA | XFS_USER_QUOTA));
954 ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0); 991 ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) !=
992 (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA));
993 ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) !=
994 (XFS_USER_QUOTA | XFS_GROUP_QUOTA));
995 ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0);
955 996
956 return (flags & XFS_DQ_USER) ? 997 return (flags & XFS_DQ_USER) ?
957 XFS_USER_QUOTA : XFS_GROUP_QUOTA; 998 XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
999 XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
958} 1000}
959 1001
960STATIC uint 1002STATIC uint
@@ -965,12 +1007,14 @@ xfs_qm_import_flags(
965 1007
966 if (uflags & XFS_QUOTA_UDQ_ACCT) 1008 if (uflags & XFS_QUOTA_UDQ_ACCT)
967 flags |= XFS_UQUOTA_ACCT; 1009 flags |= XFS_UQUOTA_ACCT;
1010 if (uflags & XFS_QUOTA_PDQ_ACCT)
1011 flags |= XFS_PQUOTA_ACCT;
968 if (uflags & XFS_QUOTA_GDQ_ACCT) 1012 if (uflags & XFS_QUOTA_GDQ_ACCT)
969 flags |= XFS_GQUOTA_ACCT; 1013 flags |= XFS_GQUOTA_ACCT;
970 if (uflags & XFS_QUOTA_UDQ_ENFD) 1014 if (uflags & XFS_QUOTA_UDQ_ENFD)
971 flags |= XFS_UQUOTA_ENFD; 1015 flags |= XFS_UQUOTA_ENFD;
972 if (uflags & XFS_QUOTA_GDQ_ENFD) 1016 if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
973 flags |= XFS_GQUOTA_ENFD; 1017 flags |= XFS_OQUOTA_ENFD;
974 return (flags); 1018 return (flags);
975} 1019}
976 1020
@@ -984,12 +1028,16 @@ xfs_qm_export_flags(
984 uflags = 0; 1028 uflags = 0;
985 if (flags & XFS_UQUOTA_ACCT) 1029 if (flags & XFS_UQUOTA_ACCT)
986 uflags |= XFS_QUOTA_UDQ_ACCT; 1030 uflags |= XFS_QUOTA_UDQ_ACCT;
1031 if (flags & XFS_PQUOTA_ACCT)
1032 uflags |= XFS_QUOTA_PDQ_ACCT;
987 if (flags & XFS_GQUOTA_ACCT) 1033 if (flags & XFS_GQUOTA_ACCT)
988 uflags |= XFS_QUOTA_GDQ_ACCT; 1034 uflags |= XFS_QUOTA_GDQ_ACCT;
989 if (flags & XFS_UQUOTA_ENFD) 1035 if (flags & XFS_UQUOTA_ENFD)
990 uflags |= XFS_QUOTA_UDQ_ENFD; 1036 uflags |= XFS_QUOTA_UDQ_ENFD;
991 if (flags & XFS_GQUOTA_ENFD) 1037 if (flags & (XFS_OQUOTA_ENFD)) {
992 uflags |= XFS_QUOTA_GDQ_ENFD; 1038 uflags |= (flags & XFS_GQUOTA_ACCT) ?
1039 XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD;
1040 }
993 return (uflags); 1041 return (uflags);
994} 1042}
995 1043
@@ -1070,7 +1118,7 @@ again:
1070 xfs_qm_dqrele(ip->i_udquot); 1118 xfs_qm_dqrele(ip->i_udquot);
1071 ip->i_udquot = NULL; 1119 ip->i_udquot = NULL;
1072 } 1120 }
1073 if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { 1121 if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
1074 xfs_qm_dqrele(ip->i_gdquot); 1122 xfs_qm_dqrele(ip->i_gdquot);
1075 ip->i_gdquot = NULL; 1123 ip->i_gdquot = NULL;
1076 } 1124 }
@@ -1160,7 +1208,6 @@ xfs_qm_dqtest_print(
1160{ 1208{
1161 cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------"); 1209 cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------");
1162 cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id); 1210 cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id);
1163 cmn_err(CE_DEBUG, "---- type = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP");
1164 cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount); 1211 cmn_err(CE_DEBUG, "---- fs = 0x%p", d->q_mount);
1165 cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)", 1212 cmn_err(CE_DEBUG, "---- bcount = %Lu (0x%x)",
1166 d->d_bcount, (int)d->d_bcount); 1213 d->d_bcount, (int)d->d_bcount);
@@ -1231,7 +1278,7 @@ xfs_dqtest_cmp2(
1231#ifdef QUOTADEBUG 1278#ifdef QUOTADEBUG
1232 if (!err) { 1279 if (!err) {
1233 cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked", 1280 cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked",
1234 d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount); 1281 d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
1235 } 1282 }
1236#endif 1283#endif
1237 return (err); 1284 return (err);
@@ -1287,6 +1334,7 @@ STATIC void
1287xfs_qm_internalqcheck_get_dquots( 1334xfs_qm_internalqcheck_get_dquots(
1288 xfs_mount_t *mp, 1335 xfs_mount_t *mp,
1289 xfs_dqid_t uid, 1336 xfs_dqid_t uid,
1337 xfs_dqid_t projid,
1290 xfs_dqid_t gid, 1338 xfs_dqid_t gid,
1291 xfs_dqtest_t **ud, 1339 xfs_dqtest_t **ud,
1292 xfs_dqtest_t **gd) 1340 xfs_dqtest_t **gd)
@@ -1295,6 +1343,8 @@ xfs_qm_internalqcheck_get_dquots(
1295 xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud); 1343 xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud);
1296 if (XFS_IS_GQUOTA_ON(mp)) 1344 if (XFS_IS_GQUOTA_ON(mp))
1297 xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd); 1345 xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd);
1346 else if (XFS_IS_PQUOTA_ON(mp))
1347 xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd);
1298} 1348}
1299 1349
1300 1350
@@ -1362,13 +1412,14 @@ xfs_qm_internalqcheck_adjust(
1362 } 1412 }
1363 xfs_qm_internalqcheck_get_dquots(mp, 1413 xfs_qm_internalqcheck_get_dquots(mp,
1364 (xfs_dqid_t) ip->i_d.di_uid, 1414 (xfs_dqid_t) ip->i_d.di_uid,
1415 (xfs_dqid_t) ip->i_d.di_projid,
1365 (xfs_dqid_t) ip->i_d.di_gid, 1416 (xfs_dqid_t) ip->i_d.di_gid,
1366 &ud, &gd); 1417 &ud, &gd);
1367 if (XFS_IS_UQUOTA_ON(mp)) { 1418 if (XFS_IS_UQUOTA_ON(mp)) {
1368 ASSERT(ud); 1419 ASSERT(ud);
1369 xfs_qm_internalqcheck_dqadjust(ip, ud); 1420 xfs_qm_internalqcheck_dqadjust(ip, ud);
1370 } 1421 }
1371 if (XFS_IS_GQUOTA_ON(mp)) { 1422 if (XFS_IS_OQUOTA_ON(mp)) {
1372 ASSERT(gd); 1423 ASSERT(gd);
1373 xfs_qm_internalqcheck_dqadjust(ip, gd); 1424 xfs_qm_internalqcheck_dqadjust(ip, gd);
1374 } 1425 }
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index 414b6004af21..bf413e70ec07 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -56,6 +56,7 @@
56#define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit) 56#define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit)
57#define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit) 57#define XFS_QI_ITIMELIMIT(mp) ((mp)->m_quotainfo->qi_itimelimit)
58#define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit) 58#define XFS_QI_BWARNLIMIT(mp) ((mp)->m_quotainfo->qi_bwarnlimit)
59#define XFS_QI_RTBWARNLIMIT(mp) ((mp)->m_quotainfo->qi_rtbwarnlimit)
59#define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit) 60#define XFS_QI_IWARNLIMIT(mp) ((mp)->m_quotainfo->qi_iwarnlimit)
60#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock) 61#define XFS_QI_QOFFLOCK(mp) ((mp)->m_quotainfo->qi_quotaofflock)
61 62
@@ -102,7 +103,8 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
102 (xfs_Gqm->qm_grp_dqhtable + \ 103 (xfs_Gqm->qm_grp_dqhtable + \
103 XFS_DQ_HASHVAL(mp, id))) 104 XFS_DQ_HASHVAL(mp, id)))
104#define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \ 105#define XFS_IS_DQTYPE_ON(mp, type) (type == XFS_DQ_USER ? \
105 XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp)) 106 XFS_IS_UQUOTA_ON(mp) : \
107 XFS_IS_OQUOTA_ON(mp))
106#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ 108#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
107 !dqp->q_core.d_blk_hardlimit && \ 109 !dqp->q_core.d_blk_hardlimit && \
108 !dqp->q_core.d_blk_softlimit && \ 110 !dqp->q_core.d_blk_softlimit && \
@@ -177,16 +179,11 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
177 (!((dqp)->q_core.d_id)) 179 (!((dqp)->q_core.d_id))
178 180
179#define XFS_PURGE_INODE(ip) \ 181#define XFS_PURGE_INODE(ip) \
180 { \ 182 IRELE(ip);
181 vmap_t dqvmap; \
182 vnode_t *dqvp; \
183 dqvp = XFS_ITOV(ip); \
184 VMAP(dqvp, dqvmap); \
185 VN_RELE(dqvp); \
186 }
187 183
188#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ 184#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
189 (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???")) 185 (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
186 (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
190#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") 187#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
191 188
192#endif /* __XFS_QUOTA_PRIV_H__ */ 189#endif /* __XFS_QUOTA_PRIV_H__ */
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 149b2a1fd949..3b99daf8a640 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -187,7 +187,7 @@ xfs_trans_dup_dqinfo(
187/* 187/*
188 * Wrap around mod_dquot to account for both user and group quotas. 188 * Wrap around mod_dquot to account for both user and group quotas.
189 */ 189 */
190void 190STATIC void
191xfs_trans_mod_dquot_byino( 191xfs_trans_mod_dquot_byino(
192 xfs_trans_t *tp, 192 xfs_trans_t *tp,
193 xfs_inode_t *ip, 193 xfs_inode_t *ip,
@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino(
207 if (tp->t_dqinfo == NULL) 207 if (tp->t_dqinfo == NULL)
208 xfs_trans_alloc_dqinfo(tp); 208 xfs_trans_alloc_dqinfo(tp);
209 209
210 if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) { 210 if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
211 (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta); 211 (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
212 } 212 if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
213 if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
214 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta); 213 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
215 }
216} 214}
217 215
218STATIC xfs_dqtrx_t * 216STATIC xfs_dqtrx_t *
@@ -368,7 +366,7 @@ xfs_trans_dqlockedjoin(
368 * Unreserve just the reservations done by this transaction. 366 * Unreserve just the reservations done by this transaction.
369 * dquot is still left locked at exit. 367 * dquot is still left locked at exit.
370 */ 368 */
371void 369STATIC void
372xfs_trans_apply_dquot_deltas( 370xfs_trans_apply_dquot_deltas(
373 xfs_trans_t *tp) 371 xfs_trans_t *tp)
374{ 372{
@@ -499,7 +497,7 @@ xfs_trans_apply_dquot_deltas(
499 * Adjust the RT reservation. 497 * Adjust the RT reservation.
500 */ 498 */
501 if (qtrx->qt_rtblk_res != 0) { 499 if (qtrx->qt_rtblk_res != 0) {
502 if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) { 500 if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
503 if (qtrx->qt_rtblk_res > 501 if (qtrx->qt_rtblk_res >
504 qtrx->qt_rtblk_res_used) 502 qtrx->qt_rtblk_res_used)
505 dqp->q_res_rtbcount -= (xfs_qcnt_t) 503 dqp->q_res_rtbcount -= (xfs_qcnt_t)
@@ -532,12 +530,6 @@ xfs_trans_apply_dquot_deltas(
532 (xfs_qcnt_t)qtrx->qt_icount_delta; 530 (xfs_qcnt_t)qtrx->qt_icount_delta;
533 } 531 }
534 532
535
536#ifdef QUOTADEBUG
537 if (qtrx->qt_rtblk_res != 0)
538 cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
539 (int) qtrx->qt_rtblk_res, dqp);
540#endif
541 ASSERT(dqp->q_res_bcount >= 533 ASSERT(dqp->q_res_bcount >=
542 INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT)); 534 INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
543 ASSERT(dqp->q_res_icount >= 535 ASSERT(dqp->q_res_icount >=
@@ -638,7 +630,10 @@ xfs_trans_dqresv(
638 int error; 630 int error;
639 xfs_qcnt_t hardlimit; 631 xfs_qcnt_t hardlimit;
640 xfs_qcnt_t softlimit; 632 xfs_qcnt_t softlimit;
641 time_t btimer; 633 time_t timer;
634 xfs_qwarncnt_t warns;
635 xfs_qwarncnt_t warnlimit;
636 xfs_qcnt_t count;
642 xfs_qcnt_t *resbcountp; 637 xfs_qcnt_t *resbcountp;
643 xfs_quotainfo_t *q = mp->m_quotainfo; 638 xfs_quotainfo_t *q = mp->m_quotainfo;
644 639
@@ -653,7 +648,9 @@ xfs_trans_dqresv(
653 softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT); 648 softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
654 if (!softlimit) 649 if (!softlimit)
655 softlimit = q->qi_bsoftlimit; 650 softlimit = q->qi_bsoftlimit;
656 btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT); 651 timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
652 warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT);
653 warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount);
657 resbcountp = &dqp->q_res_bcount; 654 resbcountp = &dqp->q_res_bcount;
658 } else { 655 } else {
659 ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS); 656 ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
@@ -663,7 +660,9 @@ xfs_trans_dqresv(
663 softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT); 660 softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
664 if (!softlimit) 661 if (!softlimit)
665 softlimit = q->qi_rtbsoftlimit; 662 softlimit = q->qi_rtbsoftlimit;
666 btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT); 663 timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
664 warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT);
665 warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount);
667 resbcountp = &dqp->q_res_rtbcount; 666 resbcountp = &dqp->q_res_rtbcount;
668 } 667 }
669 error = 0; 668 error = 0;
@@ -693,37 +692,36 @@ xfs_trans_dqresv(
693 * If timer or warnings has expired, 692 * If timer or warnings has expired,
694 * return EDQUOT 693 * return EDQUOT
695 */ 694 */
696 if ((btimer != 0 && get_seconds() > btimer) || 695 if ((timer != 0 && get_seconds() > timer) ||
697 (dqp->q_core.d_bwarns && 696 (warns != 0 && warns >= warnlimit)) {
698 INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
699 XFS_QI_BWARNLIMIT(dqp->q_mount))) {
700 error = EDQUOT; 697 error = EDQUOT;
701 goto error_return; 698 goto error_return;
702 } 699 }
703 } 700 }
704 } 701 }
705 if (ninos > 0) { 702 if (ninos > 0) {
706 hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT); 703 count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT);
704 timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT);
705 warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT);
706 warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount);
707 hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit,
708 ARCH_CONVERT);
707 if (!hardlimit) 709 if (!hardlimit)
708 hardlimit = q->qi_ihardlimit; 710 hardlimit = q->qi_ihardlimit;
709 softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT); 711 softlimit = INT_GET(dqp->q_core.d_ino_softlimit,
712 ARCH_CONVERT);
710 if (!softlimit) 713 if (!softlimit)
711 softlimit = q->qi_isoftlimit; 714 softlimit = q->qi_isoftlimit;
712 if (hardlimit > 0ULL && 715 if (hardlimit > 0ULL && count >= hardlimit) {
713 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
714 error = EDQUOT; 716 error = EDQUOT;
715 goto error_return; 717 goto error_return;
716 } else if (softlimit > 0ULL && 718 } else if (softlimit > 0ULL && count >= softlimit) {
717 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
718 /* 719 /*
719 * If timer or warnings has expired, 720 * If timer or warnings has expired,
720 * return EDQUOT 721 * return EDQUOT
721 */ 722 */
722 if ((dqp->q_core.d_itimer && 723 if ((timer != 0 && get_seconds() > timer) ||
723 get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) || 724 (warns != 0 && warns >= warnlimit)) {
724 (dqp->q_core.d_iwarns &&
725 INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
726 XFS_QI_IWARNLIMIT(dqp->q_mount))) {
727 error = EDQUOT; 725 error = EDQUOT;
728 goto error_return; 726 goto error_return;
729 } 727 }
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 7d6e1f37df10..4ed7b6928cd7 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -36,7 +36,6 @@
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38 38
39int doass = 1;
40static char message[256]; /* keep it off the stack */ 39static char message[256]; /* keep it off the stack */
41static DEFINE_SPINLOCK(xfs_err_lock); 40static DEFINE_SPINLOCK(xfs_err_lock);
42 41
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index 40b0f4c54d9e..c5b9365a7e2a 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -50,16 +50,11 @@ extern void cmn_err(int, char *, ...);
50#endif 50#endif
51 51
52#ifdef DEBUG 52#ifdef DEBUG
53# ifdef lint 53# define ASSERT(EX) ((EX) ? ((void)0) : assfail(#EX, __FILE__, __LINE__))
54# define ASSERT(EX) ((void)0) /* avoid "constant in conditional" babble */
55# else
56# define ASSERT(EX) ((!doass||(EX))?((void)0):assfail(#EX, __FILE__, __LINE__))
57# endif /* lint */
58#else 54#else
59# define ASSERT(x) ((void)0) 55# define ASSERT(x) ((void)0)
60#endif 56#endif
61 57
62extern int doass; /* dynamically turn off asserts */
63extern void assfail(char *, char *, int); 58extern void assfail(char *, char *, int);
64#ifdef DEBUG 59#ifdef DEBUG
65extern unsigned long random(void); 60extern unsigned long random(void);
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 36603db10fe9..dcfe19703620 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -59,7 +59,7 @@
59#define XFSA_FIXUP_BNO_OK 1 59#define XFSA_FIXUP_BNO_OK 1
60#define XFSA_FIXUP_CNT_OK 2 60#define XFSA_FIXUP_CNT_OK 2
61 61
62int 62STATIC int
63xfs_alloc_search_busy(xfs_trans_t *tp, 63xfs_alloc_search_busy(xfs_trans_t *tp,
64 xfs_agnumber_t agno, 64 xfs_agnumber_t agno,
65 xfs_agblock_t bno, 65 xfs_agblock_t bno,
@@ -2562,7 +2562,7 @@ xfs_alloc_clear_busy(xfs_trans_t *tp,
2562/* 2562/*
2563 * returns non-zero if any of (agno,bno):len is in a busy list 2563 * returns non-zero if any of (agno,bno):len is in a busy list
2564 */ 2564 */
2565int 2565STATIC int
2566xfs_alloc_search_busy(xfs_trans_t *tp, 2566xfs_alloc_search_busy(xfs_trans_t *tp,
2567 xfs_agnumber_t agno, 2567 xfs_agnumber_t agno,
2568 xfs_agblock_t bno, 2568 xfs_agblock_t bno,
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index ee8b5904ec7c..a41ad3a5e554 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -71,6 +71,11 @@
71 * Provide the external interfaces to manage attribute lists. 71 * Provide the external interfaces to manage attribute lists.
72 */ 72 */
73 73
74#define ATTR_SYSCOUNT 2
75STATIC struct attrnames posix_acl_access;
76STATIC struct attrnames posix_acl_default;
77STATIC struct attrnames *attr_system_names[ATTR_SYSCOUNT];
78
74/*======================================================================== 79/*========================================================================
75 * Function prototypes for the kernel. 80 * Function prototypes for the kernel.
76 *========================================================================*/ 81 *========================================================================*/
@@ -83,6 +88,7 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
83/* 88/*
84 * Internal routines when attribute list is one block. 89 * Internal routines when attribute list is one block.
85 */ 90 */
91STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
86STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); 92STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
87STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); 93STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
88STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context); 94STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
@@ -90,6 +96,7 @@ STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
90/* 96/*
91 * Internal routines when attribute list is more than one block. 97 * Internal routines when attribute list is more than one block.
92 */ 98 */
99STATIC int xfs_attr_node_get(xfs_da_args_t *args);
93STATIC int xfs_attr_node_addname(xfs_da_args_t *args); 100STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
94STATIC int xfs_attr_node_removename(xfs_da_args_t *args); 101STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
95STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context); 102STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context);
@@ -1102,7 +1109,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
1102 * This leaf block cannot have a "remote" value, we only call this routine 1109 * This leaf block cannot have a "remote" value, we only call this routine
1103 * if bmap_one_block() says there is only one block (ie: no remote blks). 1110 * if bmap_one_block() says there is only one block (ie: no remote blks).
1104 */ 1111 */
1105int 1112STATIC int
1106xfs_attr_leaf_get(xfs_da_args_t *args) 1113xfs_attr_leaf_get(xfs_da_args_t *args)
1107{ 1114{
1108 xfs_dabuf_t *bp; 1115 xfs_dabuf_t *bp;
@@ -1707,7 +1714,7 @@ xfs_attr_refillstate(xfs_da_state_t *state)
1707 * block, ie: both true Btree attr lists and for single-leaf-blocks with 1714 * block, ie: both true Btree attr lists and for single-leaf-blocks with
1708 * "remote" values taking up more blocks. 1715 * "remote" values taking up more blocks.
1709 */ 1716 */
1710int 1717STATIC int
1711xfs_attr_node_get(xfs_da_args_t *args) 1718xfs_attr_node_get(xfs_da_args_t *args)
1712{ 1719{
1713 xfs_da_state_t *state; 1720 xfs_da_state_t *state;
@@ -2398,7 +2405,7 @@ posix_acl_default_exists(
2398 return xfs_acl_vhasacl_default(vp); 2405 return xfs_acl_vhasacl_default(vp);
2399} 2406}
2400 2407
2401struct attrnames posix_acl_access = { 2408STATIC struct attrnames posix_acl_access = {
2402 .attr_name = "posix_acl_access", 2409 .attr_name = "posix_acl_access",
2403 .attr_namelen = sizeof("posix_acl_access") - 1, 2410 .attr_namelen = sizeof("posix_acl_access") - 1,
2404 .attr_get = posix_acl_access_get, 2411 .attr_get = posix_acl_access_get,
@@ -2407,7 +2414,7 @@ struct attrnames posix_acl_access = {
2407 .attr_exists = posix_acl_access_exists, 2414 .attr_exists = posix_acl_access_exists,
2408}; 2415};
2409 2416
2410struct attrnames posix_acl_default = { 2417STATIC struct attrnames posix_acl_default = {
2411 .attr_name = "posix_acl_default", 2418 .attr_name = "posix_acl_default",
2412 .attr_namelen = sizeof("posix_acl_default") - 1, 2419 .attr_namelen = sizeof("posix_acl_default") - 1,
2413 .attr_get = posix_acl_default_get, 2420 .attr_get = posix_acl_default_get,
@@ -2416,7 +2423,7 @@ struct attrnames posix_acl_default = {
2416 .attr_exists = posix_acl_default_exists, 2423 .attr_exists = posix_acl_default_exists,
2417}; 2424};
2418 2425
2419struct attrnames *attr_system_names[] = 2426STATIC struct attrnames *attr_system_names[] =
2420 { &posix_acl_access, &posix_acl_default }; 2427 { &posix_acl_access, &posix_acl_default };
2421 2428
2422 2429
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index 67cd0f5ac1a7..45ab1c542baf 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -76,11 +76,6 @@ extern struct attrnames attr_system;
76extern struct attrnames attr_trusted; 76extern struct attrnames attr_trusted;
77extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; 77extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
78 78
79#define ATTR_SYSCOUNT 2
80extern struct attrnames posix_acl_access;
81extern struct attrnames posix_acl_default;
82extern struct attrnames *attr_system_names[ATTR_SYSCOUNT];
83
84extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); 79extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
85extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); 80extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
86 81
@@ -184,8 +179,6 @@ int xfs_attr_list(bhv_desc_t *, char *, int, int,
184 struct attrlist_cursor_kern *, struct cred *); 179 struct attrlist_cursor_kern *, struct cred *);
185int xfs_attr_inactive(struct xfs_inode *dp); 180int xfs_attr_inactive(struct xfs_inode *dp);
186 181
187int xfs_attr_node_get(struct xfs_da_args *);
188int xfs_attr_leaf_get(struct xfs_da_args *);
189int xfs_attr_shortform_getvalue(struct xfs_da_args *); 182int xfs_attr_shortform_getvalue(struct xfs_da_args *);
190int xfs_attr_fetch(struct xfs_inode *, char *, int, 183int xfs_attr_fetch(struct xfs_inode *, char *, int,
191 char *, int *, int, struct cred *); 184 char *, int *, int, struct cred *);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index b11256e58bf4..1cdd574c63a9 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -79,6 +79,8 @@
79/* 79/*
80 * Routines used for growing the Btree. 80 * Routines used for growing the Btree.
81 */ 81 */
82STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block,
83 xfs_dabuf_t **bpp);
82STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, 84STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
83 int freemap_index); 85 int freemap_index);
84STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer); 86STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer);
@@ -92,6 +94,16 @@ STATIC int xfs_attr_leaf_figure_balance(xfs_da_state_t *state,
92 int *number_usedbytes_in_blk1); 94 int *number_usedbytes_in_blk1);
93 95
94/* 96/*
97 * Routines used for shrinking the Btree.
98 */
99STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
100 xfs_dabuf_t *bp, int level);
101STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
102 xfs_dabuf_t *bp);
103STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
104 xfs_dablk_t blkno, int blkcnt);
105
106/*
95 * Utility routines. 107 * Utility routines.
96 */ 108 */
97STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, 109STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
@@ -99,6 +111,10 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
99 xfs_attr_leafblock_t *dst_leaf, 111 xfs_attr_leafblock_t *dst_leaf,
100 int dst_start, int move_count, 112 int dst_start, int move_count,
101 xfs_mount_t *mp); 113 xfs_mount_t *mp);
114STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
115STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
116 attrnames_t *, char *name, int namelen,
117 int valuelen);
102 118
103 119
104/*======================================================================== 120/*========================================================================
@@ -774,7 +790,7 @@ out:
774 * Create the initial contents of a leaf attribute list 790 * Create the initial contents of a leaf attribute list
775 * or a leaf in a node attribute list. 791 * or a leaf in a node attribute list.
776 */ 792 */
777int 793STATIC int
778xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) 794xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
779{ 795{
780 xfs_attr_leafblock_t *leaf; 796 xfs_attr_leafblock_t *leaf;
@@ -2209,7 +2225,7 @@ xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, int *count)
2209 * Calculate the number of bytes used to store the indicated attribute 2225 * Calculate the number of bytes used to store the indicated attribute
2210 * (whether local or remote only calculate bytes in this block). 2226 * (whether local or remote only calculate bytes in this block).
2211 */ 2227 */
2212int 2228STATIC int
2213xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index) 2229xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
2214{ 2230{
2215 xfs_attr_leaf_name_local_t *name_loc; 2231 xfs_attr_leaf_name_local_t *name_loc;
@@ -2380,7 +2396,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
2380 * we may be reading them directly out of a user buffer. 2396 * we may be reading them directly out of a user buffer.
2381 */ 2397 */
2382/*ARGSUSED*/ 2398/*ARGSUSED*/
2383int 2399STATIC int
2384xfs_attr_put_listent(xfs_attr_list_context_t *context, 2400xfs_attr_put_listent(xfs_attr_list_context_t *context,
2385 attrnames_t *namesp, char *name, int namelen, int valuelen) 2401 attrnames_t *namesp, char *name, int namelen, int valuelen)
2386{ 2402{
@@ -2740,7 +2756,7 @@ xfs_attr_root_inactive(xfs_trans_t **trans, xfs_inode_t *dp)
2740 * Recurse (gasp!) through the attribute nodes until we find leaves. 2756 * Recurse (gasp!) through the attribute nodes until we find leaves.
2741 * We're doing a depth-first traversal in order to invalidate everything. 2757 * We're doing a depth-first traversal in order to invalidate everything.
2742 */ 2758 */
2743int 2759STATIC int
2744xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp, 2760xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
2745 int level) 2761 int level)
2746{ 2762{
@@ -2849,7 +2865,7 @@ xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
2849 * Note that we must release the lock on the buffer so that we are not 2865 * Note that we must release the lock on the buffer so that we are not
2850 * caught holding something that the logging code wants to flush to disk. 2866 * caught holding something that the logging code wants to flush to disk.
2851 */ 2867 */
2852int 2868STATIC int
2853xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp) 2869xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
2854{ 2870{
2855 xfs_attr_leafblock_t *leaf; 2871 xfs_attr_leafblock_t *leaf;
@@ -2934,7 +2950,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
2934 * Look at all the extents for this logical region, 2950 * Look at all the extents for this logical region,
2935 * invalidate any buffers that are incore/in transactions. 2951 * invalidate any buffers that are incore/in transactions.
2936 */ 2952 */
2937int 2953STATIC int
2938xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp, 2954xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2939 xfs_dablk_t blkno, int blkcnt) 2955 xfs_dablk_t blkno, int blkcnt)
2940{ 2956{
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index b1480e0b3349..0a4cfad6df91 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -261,8 +261,6 @@ int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
261/* 261/*
262 * Routines used for growing the Btree. 262 * Routines used for growing the Btree.
263 */ 263 */
264int xfs_attr_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block,
265 struct xfs_dabuf **bpp);
266int xfs_attr_leaf_split(struct xfs_da_state *state, 264int xfs_attr_leaf_split(struct xfs_da_state *state,
267 struct xfs_da_state_blk *oldblk, 265 struct xfs_da_state_blk *oldblk,
268 struct xfs_da_state_blk *newblk); 266 struct xfs_da_state_blk *newblk);
@@ -284,12 +282,6 @@ void xfs_attr_leaf_unbalance(struct xfs_da_state *state,
284 struct xfs_da_state_blk *drop_blk, 282 struct xfs_da_state_blk *drop_blk,
285 struct xfs_da_state_blk *save_blk); 283 struct xfs_da_state_blk *save_blk);
286int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); 284int xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
287int xfs_attr_node_inactive(struct xfs_trans **trans, struct xfs_inode *dp,
288 struct xfs_dabuf *bp, int level);
289int xfs_attr_leaf_inactive(struct xfs_trans **trans, struct xfs_inode *dp,
290 struct xfs_dabuf *bp);
291int xfs_attr_leaf_freextent(struct xfs_trans **trans, struct xfs_inode *dp,
292 xfs_dablk_t blkno, int blkcnt);
293 285
294/* 286/*
295 * Utility routines. 287 * Utility routines.
@@ -299,10 +291,6 @@ int xfs_attr_leaf_order(struct xfs_dabuf *leaf1_bp,
299 struct xfs_dabuf *leaf2_bp); 291 struct xfs_dabuf *leaf2_bp);
300int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize, 292int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize,
301 int *local); 293 int *local);
302int xfs_attr_leaf_entsize(struct xfs_attr_leafblock *leaf, int index);
303int xfs_attr_put_listent(struct xfs_attr_list_context *context,
304 struct attrnames *, char *name, int namelen,
305 int valuelen);
306int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp); 294int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
307 295
308#endif /* __XFS_ATTR_LEAF_H__ */ 296#endif /* __XFS_ATTR_LEAF_H__ */
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c
index a20a6c3dc13e..76c9ad3875ef 100644
--- a/fs/xfs/xfs_bit.c
+++ b/fs/xfs/xfs_bit.c
@@ -45,7 +45,7 @@
45/* 45/*
46 * Index of high bit number in byte, -1 for none set, 0..7 otherwise. 46 * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
47 */ 47 */
48const char xfs_highbit[256] = { 48STATIC const char xfs_highbit[256] = {
49 -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ 49 -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */
50 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ 50 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */
51 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ 51 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index de3162418663..6f5d283888aa 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -301,6 +301,19 @@ xfs_bmap_search_extents(
301 xfs_bmbt_irec_t *gotp, /* out: extent entry found */ 301 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
302 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */ 302 xfs_bmbt_irec_t *prevp); /* out: previous extent entry found */
303 303
304/*
305 * Check the last inode extent to determine whether this allocation will result
306 * in blocks being allocated at the end of the file. When we allocate new data
307 * blocks at the end of the file which do not start at the previous data block,
308 * we will try to align the new blocks at stripe unit boundaries.
309 */
310STATIC int /* error */
311xfs_bmap_isaeof(
312 xfs_inode_t *ip, /* incore inode pointer */
313 xfs_fileoff_t off, /* file offset in fsblocks */
314 int whichfork, /* data or attribute fork */
315 char *aeof); /* return value */
316
304#ifdef XFS_BMAP_TRACE 317#ifdef XFS_BMAP_TRACE
305/* 318/*
306 * Add a bmap trace buffer entry. Base routine for the others. 319 * Add a bmap trace buffer entry. Base routine for the others.
@@ -4532,18 +4545,17 @@ xfs_bmapi(
4532 xfs_extlen_t alen; /* allocated extent length */ 4545 xfs_extlen_t alen; /* allocated extent length */
4533 xfs_fileoff_t aoff; /* allocated file offset */ 4546 xfs_fileoff_t aoff; /* allocated file offset */
4534 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ 4547 xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */
4535 char contig; /* allocation must be one extent */
4536 xfs_btree_cur_t *cur; /* bmap btree cursor */ 4548 xfs_btree_cur_t *cur; /* bmap btree cursor */
4537 char delay; /* this request is for delayed alloc */
4538 xfs_fileoff_t end; /* end of mapped file region */ 4549 xfs_fileoff_t end; /* end of mapped file region */
4539 int eof; /* we've hit the end of extent list */ 4550 int eof; /* we've hit the end of extent list */
4551 char contig; /* allocation must be one extent */
4552 char delay; /* this request is for delayed alloc */
4553 char exact; /* don't do all of wasdelayed extent */
4540 xfs_bmbt_rec_t *ep; /* extent list entry pointer */ 4554 xfs_bmbt_rec_t *ep; /* extent list entry pointer */
4541 int error; /* error return */ 4555 int error; /* error return */
4542 char exact; /* don't do all of wasdelayed extent */
4543 xfs_bmbt_irec_t got; /* current extent list record */ 4556 xfs_bmbt_irec_t got; /* current extent list record */
4544 xfs_ifork_t *ifp; /* inode fork pointer */ 4557 xfs_ifork_t *ifp; /* inode fork pointer */
4545 xfs_extlen_t indlen; /* indirect blocks length */ 4558 xfs_extlen_t indlen; /* indirect blocks length */
4546 char inhole; /* current location is hole in file */
4547 xfs_extnum_t lastx; /* last useful extent number */ 4559 xfs_extnum_t lastx; /* last useful extent number */
4548 int logflags; /* flags for transaction logging */ 4560 int logflags; /* flags for transaction logging */
4549 xfs_extlen_t minleft; /* min blocks left after allocation */ 4561 xfs_extlen_t minleft; /* min blocks left after allocation */
@@ -4554,13 +4566,15 @@ xfs_bmapi(
4554 xfs_extnum_t nextents; /* number of extents in file */ 4566 xfs_extnum_t nextents; /* number of extents in file */
4555 xfs_fileoff_t obno; /* old block number (offset) */ 4567 xfs_fileoff_t obno; /* old block number (offset) */
4556 xfs_bmbt_irec_t prev; /* previous extent list record */ 4568 xfs_bmbt_irec_t prev; /* previous extent list record */
4557 char stateless; /* ignore state flag set */
4558 int tmp_logflags; /* temp flags holder */ 4569 int tmp_logflags; /* temp flags holder */
4570 int whichfork; /* data or attr fork */
4571 char inhole; /* current location is hole in file */
4572 char stateless; /* ignore state flag set */
4559 char trim; /* output trimmed to match range */ 4573 char trim; /* output trimmed to match range */
4560 char userdata; /* allocating non-metadata */ 4574 char userdata; /* allocating non-metadata */
4561 char wasdelay; /* old extent was delayed */ 4575 char wasdelay; /* old extent was delayed */
4562 int whichfork; /* data or attr fork */
4563 char wr; /* this is a write request */ 4576 char wr; /* this is a write request */
4577 char rt; /* this is a realtime file */
4564 char rsvd; /* OK to allocate reserved blocks */ 4578 char rsvd; /* OK to allocate reserved blocks */
4565#ifdef DEBUG 4579#ifdef DEBUG
4566 xfs_fileoff_t orig_bno; /* original block number value */ 4580 xfs_fileoff_t orig_bno; /* original block number value */
@@ -4590,6 +4604,7 @@ xfs_bmapi(
4590 } 4604 }
4591 if (XFS_FORCED_SHUTDOWN(mp)) 4605 if (XFS_FORCED_SHUTDOWN(mp))
4592 return XFS_ERROR(EIO); 4606 return XFS_ERROR(EIO);
4607 rt = XFS_IS_REALTIME_INODE(ip);
4593 ifp = XFS_IFORK_PTR(ip, whichfork); 4608 ifp = XFS_IFORK_PTR(ip, whichfork);
4594 ASSERT(ifp->if_ext_max == 4609 ASSERT(ifp->if_ext_max ==
4595 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 4610 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
@@ -4694,9 +4709,16 @@ xfs_bmapi(
4694 } 4709 }
4695 minlen = contig ? alen : 1; 4710 minlen = contig ? alen : 1;
4696 if (delay) { 4711 if (delay) {
4697 indlen = (xfs_extlen_t) 4712 xfs_extlen_t extsz = 0;
4698 xfs_bmap_worst_indlen(ip, alen); 4713
4699 ASSERT(indlen > 0); 4714 /* Figure out the extent size, adjust alen */
4715 if (rt) {
4716 if (!(extsz = ip->i_d.di_extsize))
4717 extsz = mp->m_sb.sb_rextsize;
4718 alen = roundup(alen, extsz);
4719 extsz = alen / mp->m_sb.sb_rextsize;
4720 }
4721
4700 /* 4722 /*
4701 * Make a transaction-less quota reservation for 4723 * Make a transaction-less quota reservation for
4702 * delayed allocation blocks. This number gets 4724 * delayed allocation blocks. This number gets
@@ -4704,8 +4726,10 @@ xfs_bmapi(
4704 * We return EDQUOT if we haven't allocated 4726 * We return EDQUOT if we haven't allocated
4705 * blks already inside this loop; 4727 * blks already inside this loop;
4706 */ 4728 */
4707 if (XFS_TRANS_RESERVE_BLKQUOTA( 4729 if (XFS_TRANS_RESERVE_QUOTA_NBLKS(
4708 mp, NULL, ip, (long)alen)) { 4730 mp, NULL, ip, (long)alen, 0,
4731 rt ? XFS_QMOPT_RES_RTBLKS :
4732 XFS_QMOPT_RES_REGBLKS)) {
4709 if (n == 0) { 4733 if (n == 0) {
4710 *nmap = 0; 4734 *nmap = 0;
4711 ASSERT(cur == NULL); 4735 ASSERT(cur == NULL);
@@ -4718,40 +4742,34 @@ xfs_bmapi(
4718 * Split changing sb for alen and indlen since 4742 * Split changing sb for alen and indlen since
4719 * they could be coming from different places. 4743 * they could be coming from different places.
4720 */ 4744 */
4721 if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { 4745 indlen = (xfs_extlen_t)
4722 xfs_extlen_t extsz; 4746 xfs_bmap_worst_indlen(ip, alen);
4723 xfs_extlen_t ralen; 4747 ASSERT(indlen > 0);
4724 if (!(extsz = ip->i_d.di_extsize))
4725 extsz = mp->m_sb.sb_rextsize;
4726 ralen = roundup(alen, extsz);
4727 ralen = ralen / mp->m_sb.sb_rextsize;
4728 if (xfs_mod_incore_sb(mp,
4729 XFS_SBS_FREXTENTS,
4730 -(ralen), rsvd)) {
4731 if (XFS_IS_QUOTA_ON(ip->i_mount))
4732 XFS_TRANS_UNRESERVE_BLKQUOTA(
4733 mp, NULL, ip,
4734 (long)alen);
4735 break;
4736 }
4737 } else {
4738 if (xfs_mod_incore_sb(mp,
4739 XFS_SBS_FDBLOCKS,
4740 -(alen), rsvd)) {
4741 if (XFS_IS_QUOTA_ON(ip->i_mount))
4742 XFS_TRANS_UNRESERVE_BLKQUOTA(
4743 mp, NULL, ip,
4744 (long)alen);
4745 break;
4746 }
4747 }
4748 4748
4749 if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, 4749 if (rt)
4750 -(indlen), rsvd)) { 4750 error = xfs_mod_incore_sb(mp,
4751 XFS_TRANS_UNRESERVE_BLKQUOTA( 4751 XFS_SBS_FREXTENTS,
4752 mp, NULL, ip, (long)alen); 4752 -(extsz), rsvd);
4753 else
4754 error = xfs_mod_incore_sb(mp,
4755 XFS_SBS_FDBLOCKS,
4756 -(alen), rsvd);
4757 if (!error)
4758 error = xfs_mod_incore_sb(mp,
4759 XFS_SBS_FDBLOCKS,
4760 -(indlen), rsvd);
4761
4762 if (error) {
4763 if (XFS_IS_QUOTA_ON(ip->i_mount))
4764 /* unreserve the blocks now */
4765 XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
4766 mp, NULL, ip,
4767 (long)alen, 0, rt ?
4768 XFS_QMOPT_RES_RTBLKS :
4769 XFS_QMOPT_RES_REGBLKS);
4753 break; 4770 break;
4754 } 4771 }
4772
4755 ip->i_delayed_blks += alen; 4773 ip->i_delayed_blks += alen;
4756 abno = NULLSTARTBLOCK(indlen); 4774 abno = NULLSTARTBLOCK(indlen);
4757 } else { 4775 } else {
@@ -5376,13 +5394,24 @@ xfs_bunmapi(
5376 } 5394 }
5377 if (wasdel) { 5395 if (wasdel) {
5378 ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); 5396 ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
5379 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, 5397 /* Update realtim/data freespace, unreserve quota */
5380 (int)del.br_blockcount, rsvd); 5398 if (isrt) {
5381 /* Unreserve our quota space */ 5399 xfs_filblks_t rtexts;
5382 XFS_TRANS_RESERVE_QUOTA_NBLKS( 5400
5383 mp, NULL, ip, -((long)del.br_blockcount), 0, 5401 rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
5384 isrt ? XFS_QMOPT_RES_RTBLKS : 5402 do_div(rtexts, mp->m_sb.sb_rextsize);
5403 xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
5404 (int)rtexts, rsvd);
5405 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
5406 -((long)del.br_blockcount), 0,
5407 XFS_QMOPT_RES_RTBLKS);
5408 } else {
5409 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
5410 (int)del.br_blockcount, rsvd);
5411 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
5412 -((long)del.br_blockcount), 0,
5385 XFS_QMOPT_RES_REGBLKS); 5413 XFS_QMOPT_RES_REGBLKS);
5414 }
5386 ip->i_delayed_blks -= del.br_blockcount; 5415 ip->i_delayed_blks -= del.br_blockcount;
5387 if (cur) 5416 if (cur)
5388 cur->bc_private.b.flags |= 5417 cur->bc_private.b.flags |=
@@ -5714,7 +5743,7 @@ unlock_and_return:
5714 * blocks at the end of the file which do not start at the previous data block, 5743 * blocks at the end of the file which do not start at the previous data block,
5715 * we will try to align the new blocks at stripe unit boundaries. 5744 * we will try to align the new blocks at stripe unit boundaries.
5716 */ 5745 */
5717int /* error */ 5746STATIC int /* error */
5718xfs_bmap_isaeof( 5747xfs_bmap_isaeof(
5719 xfs_inode_t *ip, /* incore inode pointer */ 5748 xfs_inode_t *ip, /* incore inode pointer */
5720 xfs_fileoff_t off, /* file offset in fsblocks */ 5749 xfs_fileoff_t off, /* file offset in fsblocks */
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index f1bc22fb26ae..e6d22ec9b2e4 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -332,19 +332,6 @@ xfs_getbmap(
332 int iflags); /* interface flags */ 332 int iflags); /* interface flags */
333 333
334/* 334/*
335 * Check the last inode extent to determine whether this allocation will result
336 * in blocks being allocated at the end of the file. When we allocate new data
337 * blocks at the end of the file which do not start at the previous data block,
338 * we will try to align the new blocks at stripe unit boundaries.
339 */
340int
341xfs_bmap_isaeof(
342 struct xfs_inode *ip,
343 xfs_fileoff_t off,
344 int whichfork,
345 char *aeof);
346
347/*
348 * Check if the endoff is outside the last extent. If so the caller will grow 335 * Check if the endoff is outside the last extent. If so the caller will grow
349 * the allocation to a stripe unit boundary 336 * the allocation to a stripe unit boundary
350 */ 337 */
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 163305a79fcc..09c413576ba8 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -2331,20 +2331,6 @@ xfs_bmbt_lookup_ge(
2331 return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat); 2331 return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat);
2332} 2332}
2333 2333
2334int /* error */
2335xfs_bmbt_lookup_le(
2336 xfs_btree_cur_t *cur,
2337 xfs_fileoff_t off,
2338 xfs_fsblock_t bno,
2339 xfs_filblks_t len,
2340 int *stat) /* success/failure */
2341{
2342 cur->bc_rec.b.br_startoff = off;
2343 cur->bc_rec.b.br_startblock = bno;
2344 cur->bc_rec.b.br_blockcount = len;
2345 return xfs_bmbt_lookup(cur, XFS_LOOKUP_LE, stat);
2346}
2347
2348/* 2334/*
2349 * Give the bmap btree a new root block. Copy the old broot contents 2335 * Give the bmap btree a new root block. Copy the old broot contents
2350 * down into a real block and make the broot point to it. 2336 * down into a real block and make the broot point to it.
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 843ff12b4bf2..0a40cf126c28 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -580,14 +580,6 @@ xfs_bmbt_lookup_ge(
580 xfs_filblks_t, 580 xfs_filblks_t,
581 int *); 581 int *);
582 582
583int
584xfs_bmbt_lookup_le(
585 struct xfs_btree_cur *,
586 xfs_fileoff_t,
587 xfs_fsblock_t,
588 xfs_filblks_t,
589 int *);
590
591/* 583/*
592 * Give the bmap btree a new root block. Copy the old broot contents 584 * Give the bmap btree a new root block. Copy the old broot contents
593 * down into a real block and make the broot point to it. 585 * down into a real block and make the broot point to it.
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 9dd22dd95487..0cc63d657a14 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -90,6 +90,16 @@ xfs_btree_maxrecs(
90 */ 90 */
91 91
92/* 92/*
93 * Retrieve the block pointer from the cursor at the given level.
94 * This may be a bmap btree root or from a buffer.
95 */
96STATIC xfs_btree_block_t * /* generic btree block pointer */
97xfs_btree_get_block(
98 xfs_btree_cur_t *cur, /* btree cursor */
99 int level, /* level in btree */
100 struct xfs_buf **bpp); /* buffer containing the block */
101
102/*
93 * Checking routine: return maxrecs for the block. 103 * Checking routine: return maxrecs for the block.
94 */ 104 */
95STATIC int /* number of records fitting in block */ 105STATIC int /* number of records fitting in block */
@@ -497,7 +507,7 @@ xfs_btree_firstrec(
497 * Retrieve the block pointer from the cursor at the given level. 507 * Retrieve the block pointer from the cursor at the given level.
498 * This may be a bmap btree root or from a buffer. 508 * This may be a bmap btree root or from a buffer.
499 */ 509 */
500xfs_btree_block_t * /* generic btree block pointer */ 510STATIC xfs_btree_block_t * /* generic btree block pointer */
501xfs_btree_get_block( 511xfs_btree_get_block(
502 xfs_btree_cur_t *cur, /* btree cursor */ 512 xfs_btree_cur_t *cur, /* btree cursor */
503 int level, /* level in btree */ 513 int level, /* level in btree */
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 93872bba41f5..09b4e1532a35 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -325,16 +325,6 @@ xfs_btree_firstrec(
325 int level); /* level to change */ 325 int level); /* level to change */
326 326
327/* 327/*
328 * Retrieve the block pointer from the cursor at the given level.
329 * This may be a bmap btree root or from a buffer.
330 */
331xfs_btree_block_t * /* generic btree block pointer */
332xfs_btree_get_block(
333 xfs_btree_cur_t *cur, /* btree cursor */
334 int level, /* level in btree */
335 struct xfs_buf **bpp); /* buffer containing the block */
336
337/*
338 * Get a buffer for the block, return it with no data read. 328 * Get a buffer for the block, return it with no data read.
339 * Long-form addressing. 329 * Long-form addressing.
340 */ 330 */
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 9ab0039f07df..30b8285ad476 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -172,7 +172,7 @@ STATIC void xfs_buf_do_callbacks(xfs_buf_t *bp, xfs_log_item_t *lip);
172 * 172 *
173 * If the XFS_BLI_STALE flag has been set, then log nothing. 173 * If the XFS_BLI_STALE flag has been set, then log nothing.
174 */ 174 */
175uint 175STATIC uint
176xfs_buf_item_size( 176xfs_buf_item_size(
177 xfs_buf_log_item_t *bip) 177 xfs_buf_log_item_t *bip)
178{ 178{
@@ -240,7 +240,7 @@ xfs_buf_item_size(
240 * format structure, and the rest point to contiguous chunks 240 * format structure, and the rest point to contiguous chunks
241 * within the buffer. 241 * within the buffer.
242 */ 242 */
243void 243STATIC void
244xfs_buf_item_format( 244xfs_buf_item_format(
245 xfs_buf_log_item_t *bip, 245 xfs_buf_log_item_t *bip,
246 xfs_log_iovec_t *log_vector) 246 xfs_log_iovec_t *log_vector)
@@ -365,7 +365,7 @@ xfs_buf_item_format(
365 * item in memory so it cannot be written out. Simply call bpin() 365 * item in memory so it cannot be written out. Simply call bpin()
366 * on the buffer to do this. 366 * on the buffer to do this.
367 */ 367 */
368void 368STATIC void
369xfs_buf_item_pin( 369xfs_buf_item_pin(
370 xfs_buf_log_item_t *bip) 370 xfs_buf_log_item_t *bip)
371{ 371{
@@ -391,7 +391,7 @@ xfs_buf_item_pin(
391 * If the XFS_BLI_STALE flag is set and we are the last reference, 391 * If the XFS_BLI_STALE flag is set and we are the last reference,
392 * then free up the buf log item and unlock the buffer. 392 * then free up the buf log item and unlock the buffer.
393 */ 393 */
394void 394STATIC void
395xfs_buf_item_unpin( 395xfs_buf_item_unpin(
396 xfs_buf_log_item_t *bip, 396 xfs_buf_log_item_t *bip,
397 int stale) 397 int stale)
@@ -446,7 +446,7 @@ xfs_buf_item_unpin(
446 * so we need to free the item's descriptor (that points to the item) 446 * so we need to free the item's descriptor (that points to the item)
447 * in the transaction. 447 * in the transaction.
448 */ 448 */
449void 449STATIC void
450xfs_buf_item_unpin_remove( 450xfs_buf_item_unpin_remove(
451 xfs_buf_log_item_t *bip, 451 xfs_buf_log_item_t *bip,
452 xfs_trans_t *tp) 452 xfs_trans_t *tp)
@@ -493,7 +493,7 @@ xfs_buf_item_unpin_remove(
493 * the lock right away, return 0. If we can get the lock, pull the 493 * the lock right away, return 0. If we can get the lock, pull the
494 * buffer from the free list, mark it busy, and return 1. 494 * buffer from the free list, mark it busy, and return 1.
495 */ 495 */
496uint 496STATIC uint
497xfs_buf_item_trylock( 497xfs_buf_item_trylock(
498 xfs_buf_log_item_t *bip) 498 xfs_buf_log_item_t *bip)
499{ 499{
@@ -537,7 +537,7 @@ xfs_buf_item_trylock(
537 * This is for support of xfs_trans_bhold(). Make sure the 537 * This is for support of xfs_trans_bhold(). Make sure the
538 * XFS_BLI_HOLD field is cleared if we don't free the item. 538 * XFS_BLI_HOLD field is cleared if we don't free the item.
539 */ 539 */
540void 540STATIC void
541xfs_buf_item_unlock( 541xfs_buf_item_unlock(
542 xfs_buf_log_item_t *bip) 542 xfs_buf_log_item_t *bip)
543{ 543{
@@ -635,7 +635,7 @@ xfs_buf_item_unlock(
635 * by returning the original lsn of that transaction here rather than 635 * by returning the original lsn of that transaction here rather than
636 * the current one. 636 * the current one.
637 */ 637 */
638xfs_lsn_t 638STATIC xfs_lsn_t
639xfs_buf_item_committed( 639xfs_buf_item_committed(
640 xfs_buf_log_item_t *bip, 640 xfs_buf_log_item_t *bip,
641 xfs_lsn_t lsn) 641 xfs_lsn_t lsn)
@@ -654,7 +654,7 @@ xfs_buf_item_committed(
654 * and have aborted this transaction, we'll trap this buffer when it tries to 654 * and have aborted this transaction, we'll trap this buffer when it tries to
655 * get written out. 655 * get written out.
656 */ 656 */
657void 657STATIC void
658xfs_buf_item_abort( 658xfs_buf_item_abort(
659 xfs_buf_log_item_t *bip) 659 xfs_buf_log_item_t *bip)
660{ 660{
@@ -674,7 +674,7 @@ xfs_buf_item_abort(
674 * B_DELWRI set, then get it going out to disk with a call to bawrite(). 674 * B_DELWRI set, then get it going out to disk with a call to bawrite().
675 * If not, then just release the buffer. 675 * If not, then just release the buffer.
676 */ 676 */
677void 677STATIC void
678xfs_buf_item_push( 678xfs_buf_item_push(
679 xfs_buf_log_item_t *bip) 679 xfs_buf_log_item_t *bip)
680{ 680{
@@ -693,7 +693,7 @@ xfs_buf_item_push(
693} 693}
694 694
695/* ARGSUSED */ 695/* ARGSUSED */
696void 696STATIC void
697xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn) 697xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
698{ 698{
699} 699}
@@ -701,7 +701,7 @@ xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
701/* 701/*
702 * This is the ops vector shared by all buf log items. 702 * This is the ops vector shared by all buf log items.
703 */ 703 */
704struct xfs_item_ops xfs_buf_item_ops = { 704STATIC struct xfs_item_ops xfs_buf_item_ops = {
705 .iop_size = (uint(*)(xfs_log_item_t*))xfs_buf_item_size, 705 .iop_size = (uint(*)(xfs_log_item_t*))xfs_buf_item_size,
706 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 706 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
707 xfs_buf_item_format, 707 xfs_buf_item_format,
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index 5f1b0c9308f6..01aed5f2d579 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t {
80 * user or group dquots and may require special recovery handling. 80 * user or group dquots and may require special recovery handling.
81 */ 81 */
82#define XFS_BLI_UDQUOT_BUF 0x4 82#define XFS_BLI_UDQUOT_BUF 0x4
83/* #define XFS_BLI_PDQUOT_BUF 0x8 */ 83#define XFS_BLI_PDQUOT_BUF 0x8
84#define XFS_BLI_GDQUOT_BUF 0x10 84#define XFS_BLI_GDQUOT_BUF 0x10
85 85
86#define XFS_BLI_CHUNK 128 86#define XFS_BLI_CHUNK 128
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index d7fe28866764..8b792ddf2164 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -113,7 +113,10 @@ STATIC void xfs_da_node_unbalance(xfs_da_state_t *state,
113STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count); 113STATIC uint xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count);
114STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp); 114STATIC int xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp);
115STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra); 115STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra);
116 116STATIC int xfs_da_blk_unlink(xfs_da_state_t *state,
117 xfs_da_state_blk_t *drop_blk,
118 xfs_da_state_blk_t *save_blk);
119STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);
117 120
118/*======================================================================== 121/*========================================================================
119 * Routines used for growing the Btree. 122 * Routines used for growing the Btree.
@@ -1424,7 +1427,7 @@ xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count)
1424/* 1427/*
1425 * Unlink a block from a doubly linked list of blocks. 1428 * Unlink a block from a doubly linked list of blocks.
1426 */ 1429 */
1427int /* error */ 1430STATIC int /* error */
1428xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, 1431xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1429 xfs_da_state_blk_t *save_blk) 1432 xfs_da_state_blk_t *save_blk)
1430{ 1433{
@@ -2381,7 +2384,7 @@ xfs_da_state_alloc(void)
2381/* 2384/*
2382 * Kill the altpath contents of a da-state structure. 2385 * Kill the altpath contents of a da-state structure.
2383 */ 2386 */
2384void 2387STATIC void
2385xfs_da_state_kill_altpath(xfs_da_state_t *state) 2388xfs_da_state_kill_altpath(xfs_da_state_t *state)
2386{ 2389{
2387 int i; 2390 int i;
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 9fc699d96995..3a9b9e809c60 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -296,8 +296,6 @@ int xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
296/* 296/*
297 * Utility routines. 297 * Utility routines.
298 */ 298 */
299int xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
300 xfs_da_state_blk_t *save_blk);
301int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, 299int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
302 xfs_da_state_blk_t *new_blk); 300 xfs_da_state_blk_t *new_blk);
303 301
@@ -320,7 +318,6 @@ uint xfs_da_hashname(uchar_t *name_string, int name_length);
320uint xfs_da_log2_roundup(uint i); 318uint xfs_da_log2_roundup(uint i);
321xfs_da_state_t *xfs_da_state_alloc(void); 319xfs_da_state_t *xfs_da_state_alloc(void);
322void xfs_da_state_free(xfs_da_state_t *state); 320void xfs_da_state_free(xfs_da_state_t *state);
323void xfs_da_state_kill_altpath(xfs_da_state_t *state);
324 321
325void xfs_da_buf_done(xfs_dabuf_t *dabuf); 322void xfs_da_buf_done(xfs_dabuf_t *dabuf);
326void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first, 323void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first,
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 63abdc2ac7f4..681be5c93af5 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -180,9 +180,10 @@ xfs_swapext(
180 goto error0; 180 goto error0;
181 } 181 }
182 182
183 if (VN_CACHED(tvp) != 0) 183 if (VN_CACHED(tvp) != 0) {
184 xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), 184 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
185 (xfs_off_t)0, 0, 0); 185 VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED);
186 }
186 187
187 /* Verify O_DIRECT for ftmp */ 188 /* Verify O_DIRECT for ftmp */
188 if (VN_CACHED(tvp) != 0) { 189 if (VN_CACHED(tvp) != 0) {
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index db9887a107de..a0aa0e44ff9d 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -304,7 +304,7 @@ xfs_dir2_data_freeinsert(
304/* 304/*
305 * Remove a bestfree entry from the table. 305 * Remove a bestfree entry from the table.
306 */ 306 */
307void 307STATIC void
308xfs_dir2_data_freeremove( 308xfs_dir2_data_freeremove(
309 xfs_dir2_data_t *d, /* data block pointer */ 309 xfs_dir2_data_t *d, /* data block pointer */
310 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ 310 xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index 3f02294ccff0..476cac920bf5 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -193,10 +193,6 @@ extern xfs_dir2_data_free_t *
193 xfs_dir2_data_unused_t *dup, int *loghead); 193 xfs_dir2_data_unused_t *dup, int *loghead);
194 194
195extern void 195extern void
196 xfs_dir2_data_freeremove(xfs_dir2_data_t *d,
197 xfs_dir2_data_free_t *dfp, int *loghead);
198
199extern void
200 xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, 196 xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
201 int *loghead, char *aendp); 197 int *loghead, char *aendp);
202 198
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 262d1e86df30..056f5283904b 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -77,6 +77,10 @@ static void xfs_dir2_leaf_check(xfs_inode_t *dp, xfs_dabuf_t *bp);
77#endif 77#endif
78static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp, 78static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp,
79 int *indexp, xfs_dabuf_t **dbpp); 79 int *indexp, xfs_dabuf_t **dbpp);
80static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
81 int first, int last);
82static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
83
80 84
81/* 85/*
82 * Convert a block form directory to a leaf form directory. 86 * Convert a block form directory to a leaf form directory.
@@ -1214,7 +1218,7 @@ xfs_dir2_leaf_init(
1214/* 1218/*
1215 * Log the bests entries indicated from a leaf1 block. 1219 * Log the bests entries indicated from a leaf1 block.
1216 */ 1220 */
1217void 1221static void
1218xfs_dir2_leaf_log_bests( 1222xfs_dir2_leaf_log_bests(
1219 xfs_trans_t *tp, /* transaction pointer */ 1223 xfs_trans_t *tp, /* transaction pointer */
1220 xfs_dabuf_t *bp, /* leaf buffer */ 1224 xfs_dabuf_t *bp, /* leaf buffer */
@@ -1278,7 +1282,7 @@ xfs_dir2_leaf_log_header(
1278/* 1282/*
1279 * Log the tail of the leaf1 block. 1283 * Log the tail of the leaf1 block.
1280 */ 1284 */
1281void 1285STATIC void
1282xfs_dir2_leaf_log_tail( 1286xfs_dir2_leaf_log_tail(
1283 xfs_trans_t *tp, /* transaction pointer */ 1287 xfs_trans_t *tp, /* transaction pointer */
1284 xfs_dabuf_t *bp) /* leaf buffer */ 1288 xfs_dabuf_t *bp) /* leaf buffer */
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
index 7f20eee56a52..3303cd6f4c00 100644
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -330,15 +330,8 @@ extern void
330 int first, int last); 330 int first, int last);
331 331
332extern void 332extern void
333 xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
334 int first, int last);
335
336extern void
337 xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp); 333 xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp);
338 334
339extern void
340 xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
341
342extern int 335extern int
343 xfs_dir2_leaf_lookup(struct xfs_da_args *args); 336 xfs_dir2_leaf_lookup(struct xfs_da_args *args);
344 337
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
index 617018d6bbdc..c2ea6171fb0e 100644
--- a/fs/xfs/xfs_dir_leaf.c
+++ b/fs/xfs/xfs_dir_leaf.c
@@ -91,6 +91,10 @@ STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
91 int *number_entries_in_blk1, 91 int *number_entries_in_blk1,
92 int *number_namebytes_in_blk1); 92 int *number_namebytes_in_blk1);
93 93
94STATIC int xfs_dir_leaf_create(struct xfs_da_args *args,
95 xfs_dablk_t which_block,
96 struct xfs_dabuf **bpp);
97
94/* 98/*
95 * Utility routines. 99 * Utility routines.
96 */ 100 */
@@ -781,7 +785,7 @@ xfs_dir_leaf_to_node(xfs_da_args_t *args)
781 * Create the initial contents of a leaf directory 785 * Create the initial contents of a leaf directory
782 * or a leaf in a node directory. 786 * or a leaf in a node directory.
783 */ 787 */
784int 788STATIC int
785xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) 789xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
786{ 790{
787 xfs_dir_leafblock_t *leaf; 791 xfs_dir_leafblock_t *leaf;
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
index 00d68d33cc7a..dd423ce1bc8d 100644
--- a/fs/xfs/xfs_dir_leaf.h
+++ b/fs/xfs/xfs_dir_leaf.h
@@ -202,8 +202,6 @@ int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
202/* 202/*
203 * Routines used for growing the Btree. 203 * Routines used for growing the Btree.
204 */ 204 */
205int xfs_dir_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block,
206 struct xfs_dabuf **bpp);
207int xfs_dir_leaf_split(struct xfs_da_state *state, 205int xfs_dir_leaf_split(struct xfs_da_state *state,
208 struct xfs_da_state_blk *oldblk, 206 struct xfs_da_state_blk *oldblk,
209 struct xfs_da_state_blk *newblk); 207 struct xfs_da_state_blk *newblk);
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 55ae3e67d245..55c17adaaa37 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -166,27 +166,32 @@ typedef enum {
166#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */ 166#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */
167#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */ 167#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */
168#define DM_FLAGS_ISEM 0x004 /* thread holds i_sem */ 168#define DM_FLAGS_ISEM 0x004 /* thread holds i_sem */
169#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
170#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)
171/* i_alloc_sem was added in 2.4.22-pre1 */
172#define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */ 169#define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */
173#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ 170#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */
174#endif
175#endif
176 171
177/* 172/*
178 * Based on IO_ISDIRECT, decide which i_ flag is set. 173 * Based on IO_ISDIRECT, decide which i_ flag is set.
179 */ 174 */
180#ifdef DM_FLAGS_IALLOCSEM_RD 175#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
176#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
177 DM_FLAGS_ISEM : 0)
178#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
179#endif
180
181#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
182 (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
181#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ 183#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
182 DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM) 184 DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM)
183#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM) 185#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
184#else 186#endif
187
188#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
185#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ 189#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
186 0 : DM_FLAGS_ISEM) 190 0 : DM_FLAGS_ISEM)
187#define DM_SEM_FLAG_WR (DM_FLAGS_ISEM) 191#define DM_SEM_FLAG_WR (DM_FLAGS_ISEM)
188#endif 192#endif
189 193
194
190/* 195/*
191 * Macros to turn caller specified delay/block flags into 196 * Macros to turn caller specified delay/block flags into
192 * dm_send_xxxx_event flag DM_FLAGS_NDELAY. 197 * dm_send_xxxx_event flag DM_FLAGS_NDELAY.
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index bbe1dea11c08..dcd3fdd5c1f7 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -280,7 +280,7 @@ xfs_error_report(
280 } 280 }
281} 281}
282 282
283void 283STATIC void
284xfs_hex_dump(void *p, int length) 284xfs_hex_dump(void *p, int length)
285{ 285{
286 __uint8_t *uip = (__uint8_t*)p; 286 __uint8_t *uip = (__uint8_t*)p;
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 6bc0535c0a65..52ee2b90b5ed 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -73,9 +73,6 @@ xfs_corruption_error(
73 int linenum, 73 int linenum,
74 inst_t *ra); 74 inst_t *ra);
75 75
76extern void
77xfs_hex_dump(void *p, int length);
78
79#define XFS_ERROR_REPORT(e, lvl, mp) \ 76#define XFS_ERROR_REPORT(e, lvl, mp) \
80 xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address) 77 xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
81#define XFS_CORRUPTION_ERROR(e, lvl, mp, mem) \ 78#define XFS_CORRUPTION_ERROR(e, lvl, mp, mem) \
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 5eafd5b63211..db7cbd1bc857 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -59,6 +59,18 @@ STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *);
59STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *); 59STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *);
60 60
61 61
62void
63xfs_efi_item_free(xfs_efi_log_item_t *efip)
64{
65 int nexts = efip->efi_format.efi_nextents;
66
67 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
68 kmem_free(efip, sizeof(xfs_efi_log_item_t) +
69 (nexts - 1) * sizeof(xfs_extent_t));
70 } else {
71 kmem_zone_free(xfs_efi_zone, efip);
72 }
73}
62 74
63/* 75/*
64 * This returns the number of iovecs needed to log the given efi item. 76 * This returns the number of iovecs needed to log the given efi item.
@@ -120,8 +132,6 @@ xfs_efi_item_pin(xfs_efi_log_item_t *efip)
120STATIC void 132STATIC void
121xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale) 133xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
122{ 134{
123 int nexts;
124 int size;
125 xfs_mount_t *mp; 135 xfs_mount_t *mp;
126 SPLDECL(s); 136 SPLDECL(s);
127 137
@@ -132,21 +142,11 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
132 * xfs_trans_delete_ail() drops the AIL lock. 142 * xfs_trans_delete_ail() drops the AIL lock.
133 */ 143 */
134 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 144 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
135 145 xfs_efi_item_free(efip);
136 nexts = efip->efi_format.efi_nextents;
137 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
138 size = sizeof(xfs_efi_log_item_t);
139 size += (nexts - 1) * sizeof(xfs_extent_t);
140 kmem_free(efip, size);
141 } else {
142 kmem_zone_free(xfs_efi_zone, efip);
143 }
144 } else { 146 } else {
145 efip->efi_flags |= XFS_EFI_COMMITTED; 147 efip->efi_flags |= XFS_EFI_COMMITTED;
146 AIL_UNLOCK(mp, s); 148 AIL_UNLOCK(mp, s);
147 } 149 }
148
149 return;
150} 150}
151 151
152/* 152/*
@@ -159,8 +159,6 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
159STATIC void 159STATIC void
160xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) 160xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
161{ 161{
162 int nexts;
163 int size;
164 xfs_mount_t *mp; 162 xfs_mount_t *mp;
165 xfs_log_item_desc_t *lidp; 163 xfs_log_item_desc_t *lidp;
166 SPLDECL(s); 164 SPLDECL(s);
@@ -178,23 +176,11 @@ xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
178 * xfs_trans_delete_ail() drops the AIL lock. 176 * xfs_trans_delete_ail() drops the AIL lock.
179 */ 177 */
180 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 178 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
181 /* 179 xfs_efi_item_free(efip);
182 * now free the item itself
183 */
184 nexts = efip->efi_format.efi_nextents;
185 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
186 size = sizeof(xfs_efi_log_item_t);
187 size += (nexts - 1) * sizeof(xfs_extent_t);
188 kmem_free(efip, size);
189 } else {
190 kmem_zone_free(xfs_efi_zone, efip);
191 }
192 } else { 180 } else {
193 efip->efi_flags |= XFS_EFI_COMMITTED; 181 efip->efi_flags |= XFS_EFI_COMMITTED;
194 AIL_UNLOCK(mp, s); 182 AIL_UNLOCK(mp, s);
195 } 183 }
196
197 return;
198} 184}
199 185
200/* 186/*
@@ -245,18 +231,7 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
245STATIC void 231STATIC void
246xfs_efi_item_abort(xfs_efi_log_item_t *efip) 232xfs_efi_item_abort(xfs_efi_log_item_t *efip)
247{ 233{
248 int nexts; 234 xfs_efi_item_free(efip);
249 int size;
250
251 nexts = efip->efi_format.efi_nextents;
252 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
253 size = sizeof(xfs_efi_log_item_t);
254 size += (nexts - 1) * sizeof(xfs_extent_t);
255 kmem_free(efip, size);
256 } else {
257 kmem_zone_free(xfs_efi_zone, efip);
258 }
259 return;
260} 235}
261 236
262/* 237/*
@@ -288,7 +263,7 @@ xfs_efi_item_committing(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
288/* 263/*
289 * This is the ops vector shared by all efi log items. 264 * This is the ops vector shared by all efi log items.
290 */ 265 */
291struct xfs_item_ops xfs_efi_item_ops = { 266STATIC struct xfs_item_ops xfs_efi_item_ops = {
292 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efi_item_size, 267 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efi_item_size,
293 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 268 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
294 xfs_efi_item_format, 269 xfs_efi_item_format,
@@ -355,8 +330,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
355{ 330{
356 xfs_mount_t *mp; 331 xfs_mount_t *mp;
357 int extents_left; 332 int extents_left;
358 uint size;
359 int nexts;
360 SPLDECL(s); 333 SPLDECL(s);
361 334
362 mp = efip->efi_item.li_mountp; 335 mp = efip->efi_item.li_mountp;
@@ -372,20 +345,10 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
372 * xfs_trans_delete_ail() drops the AIL lock. 345 * xfs_trans_delete_ail() drops the AIL lock.
373 */ 346 */
374 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 347 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
348 xfs_efi_item_free(efip);
375 } else { 349 } else {
376 AIL_UNLOCK(mp, s); 350 AIL_UNLOCK(mp, s);
377 } 351 }
378
379 if (extents_left == 0) {
380 nexts = efip->efi_format.efi_nextents;
381 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
382 size = sizeof(xfs_efi_log_item_t);
383 size += (nexts - 1) * sizeof(xfs_extent_t);
384 kmem_free(efip, size);
385 } else {
386 kmem_zone_free(xfs_efi_zone, efip);
387 }
388 }
389} 352}
390 353
391/* 354/*
@@ -398,8 +361,6 @@ STATIC void
398xfs_efi_cancel( 361xfs_efi_cancel(
399 xfs_efi_log_item_t *efip) 362 xfs_efi_log_item_t *efip)
400{ 363{
401 int nexts;
402 int size;
403 xfs_mount_t *mp; 364 xfs_mount_t *mp;
404 SPLDECL(s); 365 SPLDECL(s);
405 366
@@ -410,26 +371,25 @@ xfs_efi_cancel(
410 * xfs_trans_delete_ail() drops the AIL lock. 371 * xfs_trans_delete_ail() drops the AIL lock.
411 */ 372 */
412 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); 373 xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
413 374 xfs_efi_item_free(efip);
414 nexts = efip->efi_format.efi_nextents;
415 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
416 size = sizeof(xfs_efi_log_item_t);
417 size += (nexts - 1) * sizeof(xfs_extent_t);
418 kmem_free(efip, size);
419 } else {
420 kmem_zone_free(xfs_efi_zone, efip);
421 }
422 } else { 375 } else {
423 efip->efi_flags |= XFS_EFI_CANCELED; 376 efip->efi_flags |= XFS_EFI_CANCELED;
424 AIL_UNLOCK(mp, s); 377 AIL_UNLOCK(mp, s);
425 } 378 }
426
427 return;
428} 379}
429 380
381STATIC void
382xfs_efd_item_free(xfs_efd_log_item_t *efdp)
383{
384 int nexts = efdp->efd_format.efd_nextents;
430 385
431 386 if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
432 387 kmem_free(efdp, sizeof(xfs_efd_log_item_t) +
388 (nexts - 1) * sizeof(xfs_extent_t));
389 } else {
390 kmem_zone_free(xfs_efd_zone, efdp);
391 }
392}
433 393
434/* 394/*
435 * This returns the number of iovecs needed to log the given efd item. 395 * This returns the number of iovecs needed to log the given efd item.
@@ -533,9 +493,6 @@ xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
533STATIC xfs_lsn_t 493STATIC xfs_lsn_t
534xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn) 494xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
535{ 495{
536 uint size;
537 int nexts;
538
539 /* 496 /*
540 * If we got a log I/O error, it's always the case that the LR with the 497 * If we got a log I/O error, it's always the case that the LR with the
541 * EFI got unpinned and freed before the EFD got aborted. 498 * EFI got unpinned and freed before the EFD got aborted.
@@ -543,15 +500,7 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
543 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) 500 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
544 xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents); 501 xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents);
545 502
546 nexts = efdp->efd_format.efd_nextents; 503 xfs_efd_item_free(efdp);
547 if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
548 size = sizeof(xfs_efd_log_item_t);
549 size += (nexts - 1) * sizeof(xfs_extent_t);
550 kmem_free(efdp, size);
551 } else {
552 kmem_zone_free(xfs_efd_zone, efdp);
553 }
554
555 return (xfs_lsn_t)-1; 504 return (xfs_lsn_t)-1;
556} 505}
557 506
@@ -565,9 +514,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
565STATIC void 514STATIC void
566xfs_efd_item_abort(xfs_efd_log_item_t *efdp) 515xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
567{ 516{
568 int nexts;
569 int size;
570
571 /* 517 /*
572 * If we got a log I/O error, it's always the case that the LR with the 518 * If we got a log I/O error, it's always the case that the LR with the
573 * EFI got unpinned and freed before the EFD got aborted. So don't 519 * EFI got unpinned and freed before the EFD got aborted. So don't
@@ -576,15 +522,7 @@ xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
576 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) 522 if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
577 xfs_efi_cancel(efdp->efd_efip); 523 xfs_efi_cancel(efdp->efd_efip);
578 524
579 nexts = efdp->efd_format.efd_nextents; 525 xfs_efd_item_free(efdp);
580 if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
581 size = sizeof(xfs_efd_log_item_t);
582 size += (nexts - 1) * sizeof(xfs_extent_t);
583 kmem_free(efdp, size);
584 } else {
585 kmem_zone_free(xfs_efd_zone, efdp);
586 }
587 return;
588} 526}
589 527
590/* 528/*
@@ -615,7 +553,7 @@ xfs_efd_item_committing(xfs_efd_log_item_t *efip, xfs_lsn_t lsn)
615/* 553/*
616 * This is the ops vector shared by all efd log items. 554 * This is the ops vector shared by all efd log items.
617 */ 555 */
618struct xfs_item_ops xfs_efd_item_ops = { 556STATIC struct xfs_item_ops xfs_efd_item_ops = {
619 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efd_item_size, 557 .iop_size = (uint(*)(xfs_log_item_t*))xfs_efd_item_size,
620 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 558 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
621 xfs_efd_item_format, 559 xfs_efd_item_format,
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 7122d6101d15..d433bac9f59d 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -118,6 +118,8 @@ xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
118xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, 118xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
119 uint); 119 uint);
120 120
121void xfs_efi_item_free(xfs_efi_log_item_t *);
122
121#endif /* __KERNEL__ */ 123#endif /* __KERNEL__ */
122 124
123#endif /* __XFS_EXTFREE_ITEM_H__ */ 125#endif /* __XFS_EXTFREE_ITEM_H__ */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 6ee8443bf9d3..095af0a5cff3 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -60,7 +60,8 @@ struct fsxattr {
60 __u32 fsx_xflags; /* xflags field value (get/set) */ 60 __u32 fsx_xflags; /* xflags field value (get/set) */
61 __u32 fsx_extsize; /* extsize field value (get/set)*/ 61 __u32 fsx_extsize; /* extsize field value (get/set)*/
62 __u32 fsx_nextents; /* nextents field value (get) */ 62 __u32 fsx_nextents; /* nextents field value (get) */
63 unsigned char fsx_pad[16]; 63 __u32 fsx_projid; /* project identifier (get/set) */
64 unsigned char fsx_pad[12];
64}; 65};
65#endif 66#endif
66 67
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 21213057c27f..ca535d613190 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -559,32 +559,6 @@ xfs_reserve_blocks(
559 return(0); 559 return(0);
560} 560}
561 561
562void
563xfs_fs_log_dummy(xfs_mount_t *mp)
564{
565 xfs_trans_t *tp;
566 xfs_inode_t *ip;
567
568
569 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
570 atomic_inc(&mp->m_active_trans);
571 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
572 xfs_trans_cancel(tp, 0);
573 return;
574 }
575
576 ip = mp->m_rootip;
577 xfs_ilock(ip, XFS_ILOCK_EXCL);
578
579 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
580 xfs_trans_ihold(tp, ip);
581 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
582 xfs_trans_set_sync(tp);
583 xfs_trans_commit(tp, 0, NULL);
584
585 xfs_iunlock(ip, XFS_ILOCK_EXCL);
586}
587
588int 562int
589xfs_fs_goingdown( 563xfs_fs_goingdown(
590 xfs_mount_t *mp, 564 xfs_mount_t *mp,
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index 803c4d17a057..44be188674a6 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -100,9 +100,13 @@ xfs_inofree_t xfs_inobt_mask(int i);
100#endif 100#endif
101#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE) 101#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE)
102int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i); 102int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i);
103#define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i) 103#define XFS_INOBT_IS_FREE(rp,i) xfs_inobt_is_free(rp,i)
104#define XFS_INOBT_IS_FREE_DISK(rp,i) xfs_inobt_is_free_disk(rp,i)
104#else 105#else
105#define XFS_INOBT_IS_FREE(rp,i) (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) 106#define XFS_INOBT_IS_FREE(rp,i) \
107 (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
108#define XFS_INOBT_IS_FREE_DISK(rp,i) \
109 ((INT_GET((rp)->ir_free, ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
106#endif 110#endif
107#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE) 111#if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE)
108void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i); 112void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index bc8c8c7f9039..34bdf5909687 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -146,51 +146,6 @@ xfs_inobp_check(
146#endif 146#endif
147 147
148/* 148/*
149 * called from bwrite on xfs inode buffers
150 */
151void
152xfs_inobp_bwcheck(xfs_buf_t *bp)
153{
154 xfs_mount_t *mp;
155 int i;
156 int j;
157 xfs_dinode_t *dip;
158
159 ASSERT(XFS_BUF_FSPRIVATE3(bp, void *) != NULL);
160
161 mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *);
162
163
164 j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
165
166 for (i = 0; i < j; i++) {
167 dip = (xfs_dinode_t *) xfs_buf_offset(bp,
168 i * mp->m_sb.sb_inodesize);
169 if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) {
170 cmn_err(CE_WARN,
171"Bad magic # 0x%x in XFS inode buffer 0x%Lx, starting blockno %Ld, offset 0x%x",
172 INT_GET(dip->di_core.di_magic, ARCH_CONVERT),
173 (__uint64_t)(__psunsigned_t) bp,
174 (__int64_t) XFS_BUF_ADDR(bp),
175 xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
176 xfs_fs_cmn_err(CE_WARN, mp,
177 "corrupt, unmount and run xfs_repair");
178 }
179 if (!dip->di_next_unlinked) {
180 cmn_err(CE_WARN,
181"Bad next_unlinked field (0) in XFS inode buffer 0x%p, starting blockno %Ld, offset 0x%x",
182 (__uint64_t)(__psunsigned_t) bp,
183 (__int64_t) XFS_BUF_ADDR(bp),
184 xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
185 xfs_fs_cmn_err(CE_WARN, mp,
186 "corrupt, unmount and run xfs_repair");
187 }
188 }
189
190 return;
191}
192
193/*
194 * This routine is called to map an inode number within a file 149 * This routine is called to map an inode number within a file
195 * system to the buffer containing the on-disk version of the 150 * system to the buffer containing the on-disk version of the
196 * inode. It returns a pointer to the buffer containing the 151 * inode. It returns a pointer to the buffer containing the
@@ -203,7 +158,7 @@ xfs_inobp_bwcheck(xfs_buf_t *bp)
203 * Use xfs_imap() to determine the size and location of the 158 * Use xfs_imap() to determine the size and location of the
204 * buffer to read from disk. 159 * buffer to read from disk.
205 */ 160 */
206int 161STATIC int
207xfs_inotobp( 162xfs_inotobp(
208 xfs_mount_t *mp, 163 xfs_mount_t *mp,
209 xfs_trans_t *tp, 164 xfs_trans_t *tp,
@@ -1247,26 +1202,32 @@ xfs_ialloc(
1247 case S_IFREG: 1202 case S_IFREG:
1248 case S_IFDIR: 1203 case S_IFDIR:
1249 if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { 1204 if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
1250 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) { 1205 uint di_flags = 0;
1251 if ((mode & S_IFMT) == S_IFDIR) { 1206
1252 ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT; 1207 if ((mode & S_IFMT) == S_IFDIR) {
1253 } else { 1208 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
1254 ip->i_d.di_flags |= XFS_DIFLAG_REALTIME; 1209 di_flags |= XFS_DIFLAG_RTINHERIT;
1210 } else {
1211 if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
1212 di_flags |= XFS_DIFLAG_REALTIME;
1255 ip->i_iocore.io_flags |= XFS_IOCORE_RT; 1213 ip->i_iocore.io_flags |= XFS_IOCORE_RT;
1256 } 1214 }
1257 } 1215 }
1258 if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) && 1216 if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
1259 xfs_inherit_noatime) 1217 xfs_inherit_noatime)
1260 ip->i_d.di_flags |= XFS_DIFLAG_NOATIME; 1218 di_flags |= XFS_DIFLAG_NOATIME;
1261 if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) && 1219 if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
1262 xfs_inherit_nodump) 1220 xfs_inherit_nodump)
1263 ip->i_d.di_flags |= XFS_DIFLAG_NODUMP; 1221 di_flags |= XFS_DIFLAG_NODUMP;
1264 if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) && 1222 if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
1265 xfs_inherit_sync) 1223 xfs_inherit_sync)
1266 ip->i_d.di_flags |= XFS_DIFLAG_SYNC; 1224 di_flags |= XFS_DIFLAG_SYNC;
1267 if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && 1225 if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
1268 xfs_inherit_nosymlinks) 1226 xfs_inherit_nosymlinks)
1269 ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS; 1227 di_flags |= XFS_DIFLAG_NOSYMLINKS;
1228 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1229 di_flags |= XFS_DIFLAG_PROJINHERIT;
1230 ip->i_d.di_flags |= di_flags;
1270 } 1231 }
1271 /* FALLTHROUGH */ 1232 /* FALLTHROUGH */
1272 case S_IFLNK: 1233 case S_IFLNK:
@@ -2156,7 +2117,7 @@ static __inline__ int xfs_inode_clean(xfs_inode_t *ip)
2156 (ip->i_update_core == 0)); 2117 (ip->i_update_core == 0));
2157} 2118}
2158 2119
2159void 2120STATIC void
2160xfs_ifree_cluster( 2121xfs_ifree_cluster(
2161 xfs_inode_t *free_ip, 2122 xfs_inode_t *free_ip,
2162 xfs_trans_t *tp, 2123 xfs_trans_t *tp,
@@ -2875,7 +2836,7 @@ xfs_iunpin(
2875 * be subsequently pinned once someone is waiting for it to be 2836 * be subsequently pinned once someone is waiting for it to be
2876 * unpinned. 2837 * unpinned.
2877 */ 2838 */
2878void 2839STATIC void
2879xfs_iunpin_wait( 2840xfs_iunpin_wait(
2880 xfs_inode_t *ip) 2841 xfs_inode_t *ip)
2881{ 2842{
@@ -3601,107 +3562,43 @@ corrupt_out:
3601 3562
3602 3563
3603/* 3564/*
3604 * Flush all inactive inodes in mp. Return true if no user references 3565 * Flush all inactive inodes in mp.
3605 * were found, false otherwise.
3606 */ 3566 */
3607int 3567void
3608xfs_iflush_all( 3568xfs_iflush_all(
3609 xfs_mount_t *mp, 3569 xfs_mount_t *mp)
3610 int flag)
3611{ 3570{
3612 int busy;
3613 int done;
3614 int purged;
3615 xfs_inode_t *ip; 3571 xfs_inode_t *ip;
3616 vmap_t vmap;
3617 vnode_t *vp; 3572 vnode_t *vp;
3618 3573
3619 busy = done = 0; 3574 again:
3620 while (!done) { 3575 XFS_MOUNT_ILOCK(mp);
3621 purged = 0; 3576 ip = mp->m_inodes;
3622 XFS_MOUNT_ILOCK(mp); 3577 if (ip == NULL)
3623 ip = mp->m_inodes; 3578 goto out;
3624 if (ip == NULL) {
3625 break;
3626 }
3627 do {
3628 /* Make sure we skip markers inserted by sync */
3629 if (ip->i_mount == NULL) {
3630 ip = ip->i_mnext;
3631 continue;
3632 }
3633
3634 /*
3635 * It's up to our caller to purge the root
3636 * and quota vnodes later.
3637 */
3638 vp = XFS_ITOV_NULL(ip);
3639
3640 if (!vp) {
3641 XFS_MOUNT_IUNLOCK(mp);
3642 xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
3643 purged = 1;
3644 break;
3645 }
3646 3579
3647 if (vn_count(vp) != 0) { 3580 do {
3648 if (vn_count(vp) == 1 && 3581 /* Make sure we skip markers inserted by sync */
3649 (ip == mp->m_rootip || 3582 if (ip->i_mount == NULL) {
3650 (mp->m_quotainfo && 3583 ip = ip->i_mnext;
3651 (ip->i_ino == mp->m_sb.sb_uquotino || 3584 continue;
3652 ip->i_ino == mp->m_sb.sb_gquotino)))) { 3585 }
3653 3586
3654 ip = ip->i_mnext; 3587 vp = XFS_ITOV_NULL(ip);
3655 continue; 3588 if (!vp) {
3656 }
3657 if (!(flag & XFS_FLUSH_ALL)) {
3658 busy = 1;
3659 done = 1;
3660 break;
3661 }
3662 /*
3663 * Ignore busy inodes but continue flushing
3664 * others.
3665 */
3666 ip = ip->i_mnext;
3667 continue;
3668 }
3669 /*
3670 * Sample vp mapping while holding mp locked on MP
3671 * systems, so we don't purge a reclaimed or
3672 * nonexistent vnode. We break from the loop
3673 * since we know that we modify
3674 * it by pulling ourselves from it in xfs_reclaim()
3675 * called via vn_purge() below. Set ip to the next
3676 * entry in the list anyway so we'll know below
3677 * whether we reached the end or not.
3678 */
3679 VMAP(vp, vmap);
3680 XFS_MOUNT_IUNLOCK(mp); 3589 XFS_MOUNT_IUNLOCK(mp);
3590 xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
3591 goto again;
3592 }
3681 3593
3682 vn_purge(vp, &vmap); 3594 ASSERT(vn_count(vp) == 0);
3683 3595
3684 purged = 1; 3596 ip = ip->i_mnext;
3685 break; 3597 } while (ip != mp->m_inodes);
3686 } while (ip != mp->m_inodes); 3598 out:
3687 /*
3688 * We need to distinguish between when we exit the loop
3689 * after a purge and when we simply hit the end of the
3690 * list. We can't use the (ip == mp->m_inodes) test,
3691 * because when we purge an inode at the start of the list
3692 * the next inode on the list becomes mp->m_inodes. That
3693 * would cause such a test to bail out early. The purged
3694 * variable tells us how we got out of the loop.
3695 */
3696 if (!purged) {
3697 done = 1;
3698 }
3699 }
3700 XFS_MOUNT_IUNLOCK(mp); 3599 XFS_MOUNT_IUNLOCK(mp);
3701 return !busy;
3702} 3600}
3703 3601
3704
3705/* 3602/*
3706 * xfs_iaccess: check accessibility of inode for mode. 3603 * xfs_iaccess: check accessibility of inode for mode.
3707 */ 3604 */
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 37e1c316f3b6..54d9e54c7c95 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -412,11 +412,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip, int w, int n);
412#define XFS_IFLUSH_DELWRI 5 412#define XFS_IFLUSH_DELWRI 5
413 413
414/* 414/*
415 * Flags for xfs_iflush_all.
416 */
417#define XFS_FLUSH_ALL 0x1
418
419/*
420 * Flags for xfs_itruncate_start(). 415 * Flags for xfs_itruncate_start().
421 */ 416 */
422#define XFS_ITRUNC_DEFINITE 0x1 417#define XFS_ITRUNC_DEFINITE 0x1
@@ -487,8 +482,6 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int);
487/* 482/*
488 * xfs_inode.c prototypes. 483 * xfs_inode.c prototypes.
489 */ 484 */
490int xfs_inotobp(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
491 xfs_dinode_t **, struct xfs_buf **, int *);
492int xfs_itobp(struct xfs_mount *, struct xfs_trans *, 485int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
493 xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, 486 xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
494 xfs_daddr_t); 487 xfs_daddr_t);
@@ -522,7 +515,7 @@ void xfs_ipin(xfs_inode_t *);
522void xfs_iunpin(xfs_inode_t *); 515void xfs_iunpin(xfs_inode_t *);
523int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int); 516int xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
524int xfs_iflush(xfs_inode_t *, uint); 517int xfs_iflush(xfs_inode_t *, uint);
525int xfs_iflush_all(struct xfs_mount *, int); 518void xfs_iflush_all(struct xfs_mount *);
526int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *); 519int xfs_iaccess(xfs_inode_t *, mode_t, cred_t *);
527uint xfs_iroundup(uint); 520uint xfs_iroundup(uint);
528void xfs_ichgtime(xfs_inode_t *, int); 521void xfs_ichgtime(xfs_inode_t *, int);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 768cb1816b8e..0eed30f5cb19 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -910,7 +910,7 @@ xfs_inode_item_committing(
910/* 910/*
911 * This is the ops vector shared by all buf log items. 911 * This is the ops vector shared by all buf log items.
912 */ 912 */
913struct xfs_item_ops xfs_inode_item_ops = { 913STATIC struct xfs_item_ops xfs_inode_item_ops = {
914 .iop_size = (uint(*)(xfs_log_item_t*))xfs_inode_item_size, 914 .iop_size = (uint(*)(xfs_log_item_t*))xfs_inode_item_size,
915 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*)) 915 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
916 xfs_inode_item_format, 916 xfs_inode_item_format,
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 991f8a61f7c4..2edd6769e5d3 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -278,7 +278,9 @@ phase2:
278 switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) { 278 switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE|BMAPI_UNWRITTEN)) {
279 case BMAPI_WRITE: 279 case BMAPI_WRITE:
280 /* If we found an extent, return it */ 280 /* If we found an extent, return it */
281 if (nimaps && (imap.br_startblock != HOLESTARTBLOCK)) { 281 if (nimaps &&
282 (imap.br_startblock != HOLESTARTBLOCK) &&
283 (imap.br_startblock != DELAYSTARTBLOCK)) {
282 xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io, 284 xfs_iomap_map_trace(XFS_IOMAP_WRITE_MAP, io,
283 offset, count, iomapp, &imap, flags); 285 offset, count, iomapp, &imap, flags);
284 break; 286 break;
@@ -383,15 +385,15 @@ xfs_iomap_write_direct(
383 int nimaps, maps; 385 int nimaps, maps;
384 int error; 386 int error;
385 int bmapi_flag; 387 int bmapi_flag;
388 int quota_flag;
386 int rt; 389 int rt;
387 xfs_trans_t *tp; 390 xfs_trans_t *tp;
388 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; 391 xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp;
389 xfs_bmap_free_t free_list; 392 xfs_bmap_free_t free_list;
390 int aeof; 393 int aeof;
391 xfs_filblks_t datablocks; 394 xfs_filblks_t datablocks, qblocks, resblks;
392 int committed; 395 int committed;
393 int numrtextents; 396 int numrtextents;
394 uint resblks;
395 397
396 /* 398 /*
397 * Make sure that the dquots are there. This doesn't hold 399 * Make sure that the dquots are there. This doesn't hold
@@ -417,7 +419,6 @@ xfs_iomap_write_direct(
417 xfs_fileoff_t map_last_fsb; 419 xfs_fileoff_t map_last_fsb;
418 420
419 map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; 421 map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;
420
421 if (map_last_fsb < last_fsb) { 422 if (map_last_fsb < last_fsb) {
422 last_fsb = map_last_fsb; 423 last_fsb = map_last_fsb;
423 count_fsb = last_fsb - offset_fsb; 424 count_fsb = last_fsb - offset_fsb;
@@ -426,56 +427,47 @@ xfs_iomap_write_direct(
426 } 427 }
427 428
428 /* 429 /*
429 * determine if reserving space on 430 * Determine if reserving space on the data or realtime partition.
430 * the data or realtime partition.
431 */ 431 */
432 if ((rt = XFS_IS_REALTIME_INODE(ip))) { 432 if ((rt = XFS_IS_REALTIME_INODE(ip))) {
433 int sbrtextsize, iprtextsize; 433 xfs_extlen_t extsz;
434 434
435 sbrtextsize = mp->m_sb.sb_rextsize; 435 if (!(extsz = ip->i_d.di_extsize))
436 iprtextsize = 436 extsz = mp->m_sb.sb_rextsize;
437 ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize; 437 numrtextents = qblocks = (count_fsb + extsz - 1);
438 numrtextents = (count_fsb + iprtextsize - 1); 438 do_div(numrtextents, mp->m_sb.sb_rextsize);
439 do_div(numrtextents, sbrtextsize); 439 quota_flag = XFS_QMOPT_RES_RTBLKS;
440 datablocks = 0; 440 datablocks = 0;
441 } else { 441 } else {
442 datablocks = count_fsb; 442 datablocks = qblocks = count_fsb;
443 quota_flag = XFS_QMOPT_RES_REGBLKS;
443 numrtextents = 0; 444 numrtextents = 0;
444 } 445 }
445 446
446 /* 447 /*
447 * allocate and setup the transaction 448 * Allocate and setup the transaction
448 */ 449 */
449 xfs_iunlock(ip, XFS_ILOCK_EXCL); 450 xfs_iunlock(ip, XFS_ILOCK_EXCL);
450 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); 451 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
451
452 resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); 452 resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
453
454 error = xfs_trans_reserve(tp, resblks, 453 error = xfs_trans_reserve(tp, resblks,
455 XFS_WRITE_LOG_RES(mp), numrtextents, 454 XFS_WRITE_LOG_RES(mp), numrtextents,
456 XFS_TRANS_PERM_LOG_RES, 455 XFS_TRANS_PERM_LOG_RES,
457 XFS_WRITE_LOG_COUNT); 456 XFS_WRITE_LOG_COUNT);
458 457
459 /* 458 /*
460 * check for running out of space 459 * Check for running out of space, note: need lock to return
461 */ 460 */
462 if (error) 461 if (error)
463 /*
464 * Free the transaction structure.
465 */
466 xfs_trans_cancel(tp, 0); 462 xfs_trans_cancel(tp, 0);
467
468 xfs_ilock(ip, XFS_ILOCK_EXCL); 463 xfs_ilock(ip, XFS_ILOCK_EXCL);
469
470 if (error) 464 if (error)
471 goto error_out; /* Don't return in above if .. trans .., 465 goto error_out;
472 need lock to return */
473 466
474 if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) { 467 if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {
475 error = (EDQUOT); 468 error = (EDQUOT);
476 goto error1; 469 goto error1;
477 } 470 }
478 nimaps = 1;
479 471
480 bmapi_flag = XFS_BMAPI_WRITE; 472 bmapi_flag = XFS_BMAPI_WRITE;
481 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 473 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
@@ -485,31 +477,29 @@ xfs_iomap_write_direct(
485 bmapi_flag |= XFS_BMAPI_PREALLOC; 477 bmapi_flag |= XFS_BMAPI_PREALLOC;
486 478
487 /* 479 /*
488 * issue the bmapi() call to allocate the blocks 480 * Issue the bmapi() call to allocate the blocks
489 */ 481 */
490 XFS_BMAP_INIT(&free_list, &firstfsb); 482 XFS_BMAP_INIT(&free_list, &firstfsb);
483 nimaps = 1;
491 imapp = &imap[0]; 484 imapp = &imap[0];
492 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 485 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
493 bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); 486 bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list);
494 if (error) { 487 if (error)
495 goto error0; 488 goto error0;
496 }
497 489
498 /* 490 /*
499 * complete the transaction 491 * Complete the transaction
500 */ 492 */
501
502 error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); 493 error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
503 if (error) { 494 if (error)
504 goto error0; 495 goto error0;
505 }
506
507 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 496 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
508 if (error) { 497 if (error)
509 goto error_out; 498 goto error_out;
510 }
511 499
512 /* copy any maps to caller's array and return any error. */ 500 /*
501 * Copy any maps to caller's array and return any error.
502 */
513 if (nimaps == 0) { 503 if (nimaps == 0) {
514 error = (ENOSPC); 504 error = (ENOSPC);
515 goto error_out; 505 goto error_out;
@@ -528,10 +518,11 @@ xfs_iomap_write_direct(
528 } 518 }
529 return 0; 519 return 0;
530 520
531 error0: /* Cancel bmap, unlock inode, and cancel trans */ 521error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
532 xfs_bmap_cancel(&free_list); 522 xfs_bmap_cancel(&free_list);
523 XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
533 524
534 error1: /* Just cancel transaction */ 525error1: /* Just cancel transaction */
535 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); 526 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
536 *nmaps = 0; /* nothing set-up here */ 527 *nmaps = 0; /* nothing set-up here */
537 528
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 092d5fb096b1..1cd2ac163877 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -134,7 +134,7 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
134#define xlog_verify_tail_lsn(a,b,c) 134#define xlog_verify_tail_lsn(a,b,c)
135#endif 135#endif
136 136
137int xlog_iclogs_empty(xlog_t *log); 137STATIC int xlog_iclogs_empty(xlog_t *log);
138 138
139#ifdef DEBUG 139#ifdef DEBUG
140int xlog_do_error = 0; 140int xlog_do_error = 0;
@@ -1857,7 +1857,7 @@ xlog_write(xfs_mount_t * mp,
1857 * 1857 *
1858 * State Change: DIRTY -> ACTIVE 1858 * State Change: DIRTY -> ACTIVE
1859 */ 1859 */
1860void 1860STATIC void
1861xlog_state_clean_log(xlog_t *log) 1861xlog_state_clean_log(xlog_t *log)
1862{ 1862{
1863 xlog_in_core_t *iclog; 1863 xlog_in_core_t *iclog;
@@ -3542,7 +3542,7 @@ xfs_log_force_umount(
3542 return (retval); 3542 return (retval);
3543} 3543}
3544 3544
3545int 3545STATIC int
3546xlog_iclogs_empty(xlog_t *log) 3546xlog_iclogs_empty(xlog_t *log)
3547{ 3547{
3548 xlog_in_core_t *iclog; 3548 xlog_in_core_t *iclog;
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index c31e3ce3be66..1a1d452f15f9 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -535,7 +535,6 @@ typedef struct log {
535 535
536/* common routines */ 536/* common routines */
537extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); 537extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
538extern int xlog_find_head(xlog_t *log, xfs_daddr_t *head_blk);
539extern int xlog_find_tail(xlog_t *log, 538extern int xlog_find_tail(xlog_t *log,
540 xfs_daddr_t *head_blk, 539 xfs_daddr_t *head_blk,
541 xfs_daddr_t *tail_blk, 540 xfs_daddr_t *tail_blk,
@@ -548,7 +547,6 @@ extern void xlog_recover_process_iunlinks(xlog_t *log);
548extern struct xfs_buf *xlog_get_bp(xlog_t *, int); 547extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
549extern void xlog_put_bp(struct xfs_buf *); 548extern void xlog_put_bp(struct xfs_buf *);
550extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); 549extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
551extern xfs_caddr_t xlog_align(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
552 550
553/* iclog tracing */ 551/* iclog tracing */
554#define XLOG_TRACE_GRAB_FLUSH 1 552#define XLOG_TRACE_GRAB_FLUSH 1
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 9824b5bf0ec0..0aac28ddb81c 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -148,7 +148,7 @@ xlog_bread(
148 * The buffer is kept locked across the write and is returned locked. 148 * The buffer is kept locked across the write and is returned locked.
149 * This can only be used for synchronous log writes. 149 * This can only be used for synchronous log writes.
150 */ 150 */
151int 151STATIC int
152xlog_bwrite( 152xlog_bwrite(
153 xlog_t *log, 153 xlog_t *log,
154 xfs_daddr_t blk_no, 154 xfs_daddr_t blk_no,
@@ -179,7 +179,7 @@ xlog_bwrite(
179 return error; 179 return error;
180} 180}
181 181
182xfs_caddr_t 182STATIC xfs_caddr_t
183xlog_align( 183xlog_align(
184 xlog_t *log, 184 xlog_t *log,
185 xfs_daddr_t blk_no, 185 xfs_daddr_t blk_no,
@@ -528,7 +528,7 @@ out:
528 * 528 *
529 * Return: zero if normal, non-zero if error. 529 * Return: zero if normal, non-zero if error.
530 */ 530 */
531int 531STATIC int
532xlog_find_head( 532xlog_find_head(
533 xlog_t *log, 533 xlog_t *log,
534 xfs_daddr_t *return_head_blk) 534 xfs_daddr_t *return_head_blk)
@@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer(
1964 * probably a good thing to do for other buf types also. 1964 * probably a good thing to do for other buf types also.
1965 */ 1965 */
1966 error = 0; 1966 error = 0;
1967 if (buf_f->blf_flags & (XFS_BLI_UDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) { 1967 if (buf_f->blf_flags &
1968 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
1968 error = xfs_qm_dqcheck((xfs_disk_dquot_t *) 1969 error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
1969 item->ri_buf[i].i_addr, 1970 item->ri_buf[i].i_addr,
1970 -1, 0, XFS_QMOPT_DOWARN, 1971 -1, 0, XFS_QMOPT_DOWARN,
@@ -2030,6 +2031,7 @@ xfs_qm_dqcheck(
2030 } 2031 }
2031 2032
2032 if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER && 2033 if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER &&
2034 INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ &&
2033 INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) { 2035 INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
2034 if (flags & XFS_QMOPT_DOWARN) 2036 if (flags & XFS_QMOPT_DOWARN)
2035 cmn_err(CE_ALERT, 2037 cmn_err(CE_ALERT,
@@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer(
2135 type = 0; 2137 type = 0;
2136 if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF) 2138 if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF)
2137 type |= XFS_DQ_USER; 2139 type |= XFS_DQ_USER;
2140 if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF)
2141 type |= XFS_DQ_PROJ;
2138 if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF) 2142 if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF)
2139 type |= XFS_DQ_GROUP; 2143 type |= XFS_DQ_GROUP;
2140 /* 2144 /*
@@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans(
2247 error = 0; 2251 error = 0;
2248 if (flags & XFS_BLI_INODE_BUF) { 2252 if (flags & XFS_BLI_INODE_BUF) {
2249 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); 2253 error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
2250 } else if (flags & (XFS_BLI_UDQUOT_BUF | XFS_BLI_GDQUOT_BUF)) { 2254 } else if (flags &
2255 (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
2251 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); 2256 xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
2252 } else { 2257 } else {
2253 xlog_recover_do_reg_buffer(mp, item, bp, buf_f); 2258 xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
@@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans(
2619 * This type of quotas was turned off, so ignore this record. 2624 * This type of quotas was turned off, so ignore this record.
2620 */ 2625 */
2621 type = INT_GET(recddq->d_flags, ARCH_CONVERT) & 2626 type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
2622 (XFS_DQ_USER | XFS_DQ_GROUP); 2627 (XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
2623 ASSERT(type); 2628 ASSERT(type);
2624 if (log->l_quotaoffs_flag & type) 2629 if (log->l_quotaoffs_flag & type)
2625 return (0); 2630 return (0);
@@ -2742,7 +2747,6 @@ xlog_recover_do_efd_trans(
2742 xfs_efi_log_item_t *efip = NULL; 2747 xfs_efi_log_item_t *efip = NULL;
2743 xfs_log_item_t *lip; 2748 xfs_log_item_t *lip;
2744 int gen; 2749 int gen;
2745 int nexts;
2746 __uint64_t efi_id; 2750 __uint64_t efi_id;
2747 SPLDECL(s); 2751 SPLDECL(s);
2748 2752
@@ -2777,22 +2781,15 @@ xlog_recover_do_efd_trans(
2777 } 2781 }
2778 lip = xfs_trans_next_ail(mp, lip, &gen, NULL); 2782 lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
2779 } 2783 }
2780 if (lip == NULL) {
2781 AIL_UNLOCK(mp, s);
2782 }
2783 2784
2784 /* 2785 /*
2785 * If we found it, then free it up. If it wasn't there, it 2786 * If we found it, then free it up. If it wasn't there, it
2786 * must have been overwritten in the log. Oh well. 2787 * must have been overwritten in the log. Oh well.
2787 */ 2788 */
2788 if (lip != NULL) { 2789 if (lip != NULL) {
2789 nexts = efip->efi_format.efi_nextents; 2790 xfs_efi_item_free(efip);
2790 if (nexts > XFS_EFI_MAX_FAST_EXTENTS) { 2791 } else {
2791 kmem_free(lip, sizeof(xfs_efi_log_item_t) + 2792 AIL_UNLOCK(mp, s);
2792 ((nexts - 1) * sizeof(xfs_extent_t)));
2793 } else {
2794 kmem_zone_free(xfs_efi_zone, efip);
2795 }
2796 } 2793 }
2797} 2794}
2798 2795
diff --git a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c
index ce4f46c6b3ab..698c2cd62858 100644
--- a/fs/xfs/xfs_macros.c
+++ b/fs/xfs/xfs_macros.c
@@ -1658,6 +1658,11 @@ xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i)
1658{ 1658{
1659 return XFS_INOBT_IS_FREE(rp, i); 1659 return XFS_INOBT_IS_FREE(rp, i);
1660} 1660}
1661int
1662xfs_inobt_is_free_disk(xfs_inobt_rec_t *rp, int i)
1663{
1664 return XFS_INOBT_IS_FREE_DISK(rp, i);
1665}
1661#endif 1666#endif
1662 1667
1663#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_LAST_REC) 1668#if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_LAST_REC)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 2ec967d93e5a..82e1646e6243 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -64,6 +64,7 @@
64STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); 64STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
65STATIC int xfs_uuid_mount(xfs_mount_t *); 65STATIC int xfs_uuid_mount(xfs_mount_t *);
66STATIC void xfs_uuid_unmount(xfs_mount_t *mp); 66STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
67STATIC void xfs_unmountfs_wait(xfs_mount_t *);
67 68
68static struct { 69static struct {
69 short offset; 70 short offset;
@@ -555,7 +556,7 @@ xfs_readsb(xfs_mount_t *mp)
555 * fields from the superblock associated with the given 556 * fields from the superblock associated with the given
556 * mount structure 557 * mount structure
557 */ 558 */
558void 559STATIC void
559xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) 560xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
560{ 561{
561 int i; 562 int i;
@@ -1081,7 +1082,7 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1081 int64_t fsid; 1082 int64_t fsid;
1082#endif 1083#endif
1083 1084
1084 xfs_iflush_all(mp, XFS_FLUSH_ALL); 1085 xfs_iflush_all(mp);
1085 1086
1086 XFS_QM_DQPURGEALL(mp, 1087 XFS_QM_DQPURGEALL(mp,
1087 XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING); 1088 XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING);
@@ -1111,15 +1112,6 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1111 */ 1112 */
1112 ASSERT(mp->m_inodes == NULL); 1113 ASSERT(mp->m_inodes == NULL);
1113 1114
1114 /*
1115 * We may have bufs that are in the process of getting written still.
1116 * We must wait for the I/O completion of those. The sync flag here
1117 * does a two pass iteration thru the bufcache.
1118 */
1119 if (XFS_FORCED_SHUTDOWN(mp)) {
1120 xfs_incore_relse(mp->m_ddev_targp, 0, 1); /* synchronous */
1121 }
1122
1123 xfs_unmountfs_close(mp, cr); 1115 xfs_unmountfs_close(mp, cr);
1124 if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) 1116 if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
1125 xfs_uuid_unmount(mp); 1117 xfs_uuid_unmount(mp);
@@ -1146,7 +1138,7 @@ xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
1146 xfs_free_buftarg(mp->m_ddev_targp, 0); 1138 xfs_free_buftarg(mp->m_ddev_targp, 0);
1147} 1139}
1148 1140
1149void 1141STATIC void
1150xfs_unmountfs_wait(xfs_mount_t *mp) 1142xfs_unmountfs_wait(xfs_mount_t *mp)
1151{ 1143{
1152 if (mp->m_logdev_targp != mp->m_ddev_targp) 1144 if (mp->m_logdev_targp != mp->m_ddev_targp)
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 30dd08fb9f57..5affba38a577 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -141,7 +141,7 @@ typedef int (*xfs_dqattach_t)(struct xfs_inode *, uint);
141typedef void (*xfs_dqdetach_t)(struct xfs_inode *); 141typedef void (*xfs_dqdetach_t)(struct xfs_inode *);
142typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint); 142typedef int (*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
143typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *, 143typedef int (*xfs_dqvopalloc_t)(struct xfs_mount *,
144 struct xfs_inode *, uid_t, gid_t, uint, 144 struct xfs_inode *, uid_t, gid_t, prid_t, uint,
145 struct xfs_dquot **, struct xfs_dquot **); 145 struct xfs_dquot **, struct xfs_dquot **);
146typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *, 146typedef void (*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
147 struct xfs_dquot *, struct xfs_dquot *); 147 struct xfs_dquot *, struct xfs_dquot *);
@@ -185,8 +185,8 @@ typedef struct xfs_qmops {
185 (*(mp)->m_qm_ops.xfs_dqdetach)(ip) 185 (*(mp)->m_qm_ops.xfs_dqdetach)(ip)
186#define XFS_QM_DQPURGEALL(mp, fl) \ 186#define XFS_QM_DQPURGEALL(mp, fl) \
187 (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl) 187 (*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
188#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, fl, dq1, dq2) \ 188#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
189 (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, fl, dq1, dq2) 189 (*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
190#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \ 190#define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
191 (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2) 191 (*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
192#define XFS_QM_DQVOPRENAME(mp, ip) \ 192#define XFS_QM_DQVOPRENAME(mp, ip) \
@@ -544,7 +544,6 @@ extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
544extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); 544extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
545 545
546extern int xfs_unmountfs(xfs_mount_t *, struct cred *); 546extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
547extern void xfs_unmountfs_wait(xfs_mount_t *);
548extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *); 547extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
549extern int xfs_unmountfs_writesb(xfs_mount_t *); 548extern int xfs_unmountfs_writesb(xfs_mount_t *);
550extern int xfs_unmount_flush(xfs_mount_t *, int); 549extern int xfs_unmount_flush(xfs_mount_t *, int);
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 703ec4efcb41..7134576ae7fa 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -96,7 +96,7 @@ typedef struct xfs_dqblk {
96 * flags for q_flags field in the dquot. 96 * flags for q_flags field in the dquot.
97 */ 97 */
98#define XFS_DQ_USER 0x0001 /* a user quota */ 98#define XFS_DQ_USER 0x0001 /* a user quota */
99/* #define XFS_DQ_PROJ 0x0002 -- project quota (IRIX) */ 99#define XFS_DQ_PROJ 0x0002 /* project quota */
100#define XFS_DQ_GROUP 0x0004 /* a group quota */ 100#define XFS_DQ_GROUP 0x0004 /* a group quota */
101#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */ 101#define XFS_DQ_FLOCKED 0x0008 /* flush lock taken */
102#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */ 102#define XFS_DQ_DIRTY 0x0010 /* dquot is dirty */
@@ -104,6 +104,8 @@ typedef struct xfs_dqblk {
104#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */ 104#define XFS_DQ_INACTIVE 0x0040 /* dq off mplist & hashlist */
105#define XFS_DQ_MARKER 0x0080 /* sentinel */ 105#define XFS_DQ_MARKER 0x0080 /* sentinel */
106 106
107#define XFS_DQ_ALLTYPES (XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
108
107/* 109/*
108 * In the worst case, when both user and group quotas are on, 110 * In the worst case, when both user and group quotas are on,
109 * we can have a max of three dquots changing in a single transaction. 111 * we can have a max of three dquots changing in a single transaction.
@@ -124,7 +126,7 @@ typedef struct xfs_dqblk {
124typedef struct xfs_dq_logformat { 126typedef struct xfs_dq_logformat {
125 __uint16_t qlf_type; /* dquot log item type */ 127 __uint16_t qlf_type; /* dquot log item type */
126 __uint16_t qlf_size; /* size of this item */ 128 __uint16_t qlf_size; /* size of this item */
127 xfs_dqid_t qlf_id; /* usr/grp id number : 32 bits */ 129 xfs_dqid_t qlf_id; /* usr/grp/proj id : 32 bits */
128 __int64_t qlf_blkno; /* blkno of dquot buffer */ 130 __int64_t qlf_blkno; /* blkno of dquot buffer */
129 __int32_t qlf_len; /* len of dquot buffer */ 131 __int32_t qlf_len; /* len of dquot buffer */
130 __uint32_t qlf_boffset; /* off of dquot in buffer */ 132 __uint32_t qlf_boffset; /* off of dquot in buffer */
@@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat {
152#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */ 154#define XFS_UQUOTA_ACCT 0x0001 /* user quota accounting ON */
153#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */ 155#define XFS_UQUOTA_ENFD 0x0002 /* user quota limits enforced */
154#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */ 156#define XFS_UQUOTA_CHKD 0x0004 /* quotacheck run on usr quotas */
155#define XFS_PQUOTA_ACCT 0x0008 /* (IRIX) project quota accounting ON */ 157#define XFS_PQUOTA_ACCT 0x0008 /* project quota accounting ON */
156#define XFS_GQUOTA_ENFD 0x0010 /* group quota limits enforced */ 158#define XFS_OQUOTA_ENFD 0x0010 /* other (grp/prj) quota limits enforced */
157#define XFS_GQUOTA_CHKD 0x0020 /* quotacheck run on grp quotas */ 159#define XFS_OQUOTA_CHKD 0x0020 /* quotacheck run on other (grp/prj) quotas */
158#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */ 160#define XFS_GQUOTA_ACCT 0x0040 /* group quota accounting ON */
159 161
160/* 162/*
@@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat {
162 * are in the process of getting turned off. These flags are in m_qflags but 164 * are in the process of getting turned off. These flags are in m_qflags but
163 * never in sb_qflags. 165 * never in sb_qflags.
164 */ 166 */
165#define XFS_UQUOTA_ACTIVE 0x0080 /* uquotas are being turned off */ 167#define XFS_UQUOTA_ACTIVE 0x0100 /* uquotas are being turned off */
166#define XFS_GQUOTA_ACTIVE 0x0100 /* gquotas are being turned off */ 168#define XFS_PQUOTA_ACTIVE 0x0200 /* pquotas are being turned off */
169#define XFS_GQUOTA_ACTIVE 0x0400 /* gquotas are being turned off */
167 170
168/* 171/*
169 * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees 172 * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
170 * quota will be not be switched off as long as that inode lock is held. 173 * quota will be not be switched off as long as that inode lock is held.
171 */ 174 */
172#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ 175#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \
173 XFS_GQUOTA_ACTIVE)) 176 XFS_GQUOTA_ACTIVE | \
177 XFS_PQUOTA_ACTIVE))
178#define XFS_IS_OQUOTA_ON(mp) ((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \
179 XFS_PQUOTA_ACTIVE))
174#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) 180#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
175#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) 181#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE)
182#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE)
176 183
177/* 184/*
178 * Flags to tell various functions what to do. Not all of these are meaningful 185 * Flags to tell various functions what to do. Not all of these are meaningful
@@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat {
182#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */ 189#define XFS_QMOPT_DQLOCK 0x0000001 /* dqlock */
183#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */ 190#define XFS_QMOPT_DQALLOC 0x0000002 /* alloc dquot ondisk if needed */
184#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */ 191#define XFS_QMOPT_UQUOTA 0x0000004 /* user dquot requested */
185#define XFS_QMOPT_GQUOTA 0x0000008 /* group dquot requested */ 192#define XFS_QMOPT_PQUOTA 0x0000008 /* project dquot requested */
186#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */ 193#define XFS_QMOPT_FORCE_RES 0x0000010 /* ignore quota limits */
187#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */ 194#define XFS_QMOPT_DQSUSER 0x0000020 /* don't cache super users dquot */
188#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */ 195#define XFS_QMOPT_SBVERSION 0x0000040 /* change superblock version num */
@@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat {
192#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ 199#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */
193#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ 200#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
194#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ 201#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */
202#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
195 203
196/* 204/*
197 * flags to xfs_trans_mod_dquot to indicate which field needs to be 205 * flags to xfs_trans_mod_dquot to indicate which field needs to be
@@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat {
231#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT 239#define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT
232 240
233 241
234#define XFS_QMOPT_QUOTALL (XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA) 242#define XFS_QMOPT_QUOTALL \
243 (XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
235#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS) 244#define XFS_QMOPT_RESBLK_MASK (XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
236 245
237#ifdef __KERNEL__ 246#ifdef __KERNEL__
@@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat {
246 */ 255 */
247#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\ 256#define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
248 (ip)->i_udquot == NULL) || \ 257 (ip)->i_udquot == NULL) || \
249 (XFS_IS_GQUOTA_ON(mp) && \ 258 (XFS_IS_OQUOTA_ON(mp) && \
250 (ip)->i_gdquot == NULL)) 259 (ip)->i_gdquot == NULL))
251 260
252#define XFS_QM_NEED_QUOTACHECK(mp) ((XFS_IS_UQUOTA_ON(mp) && \ 261#define XFS_QM_NEED_QUOTACHECK(mp) \
253 (mp->m_sb.sb_qflags & \ 262 ((XFS_IS_UQUOTA_ON(mp) && \
254 XFS_UQUOTA_CHKD) == 0) || \ 263 (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
255 (XFS_IS_GQUOTA_ON(mp) && \ 264 (XFS_IS_GQUOTA_ON(mp) && \
256 (mp->m_sb.sb_qflags & \ 265 ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
257 XFS_GQUOTA_CHKD) == 0)) 266 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
267 (XFS_IS_PQUOTA_ON(mp) && \
268 ((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
269 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
270
271#define XFS_MOUNT_QUOTA_SET1 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
272 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
273 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
274
275#define XFS_MOUNT_QUOTA_SET2 (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
276 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
277 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
258 278
259#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\ 279#define XFS_MOUNT_QUOTA_ALL (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
260 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\ 280 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
261 XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD) 281 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
282 XFS_GQUOTA_ACCT)
262#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ 283#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
263 XFS_GQUOTA_ACTIVE) 284 XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
264 285
265 286
266/* 287/*
@@ -331,15 +352,8 @@ typedef struct xfs_dqtrxops {
331#define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \ 352#define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \
332 XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots) 353 XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots)
333 354
334#define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \ 355#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \
335 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \ 356 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags)
336 XFS_QMOPT_RES_REGBLKS)
337#define XFS_TRANS_RESERVE_BLKQUOTA_FORCE(mp, tp, ip, nblks) \
338 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
339 XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES)
340#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp, tp, ip, nblks) \
341 XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), 0, \
342 XFS_QMOPT_RES_REGBLKS)
343#define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \ 357#define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
344 XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \ 358 XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \
345 f | XFS_QMOPT_RES_REGBLKS) 359 f | XFS_QMOPT_RES_REGBLKS)
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index cb13f9a1d45b..23b48ac1cb7e 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -234,9 +234,6 @@ xfs_lock_for_rename(
234 return 0; 234 return 0;
235} 235}
236 236
237
238int rename_which_error_return = 0;
239
240/* 237/*
241 * xfs_rename 238 * xfs_rename
242 */ 239 */
@@ -316,7 +313,6 @@ xfs_rename(
316 &num_inodes); 313 &num_inodes);
317 314
318 if (error) { 315 if (error) {
319 rename_which_error_return = __LINE__;
320 /* 316 /*
321 * We have nothing locked, no inode references, and 317 * We have nothing locked, no inode references, and
322 * no transaction, so just get out. 318 * no transaction, so just get out.
@@ -332,7 +328,6 @@ xfs_rename(
332 */ 328 */
333 if (target_ip == NULL && (src_dp != target_dp) && 329 if (target_ip == NULL && (src_dp != target_dp) &&
334 target_dp->i_d.di_nlink >= XFS_MAXLINK) { 330 target_dp->i_d.di_nlink >= XFS_MAXLINK) {
335 rename_which_error_return = __LINE__;
336 error = XFS_ERROR(EMLINK); 331 error = XFS_ERROR(EMLINK);
337 xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); 332 xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
338 goto rele_return; 333 goto rele_return;
@@ -359,7 +354,6 @@ xfs_rename(
359 XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT); 354 XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT);
360 } 355 }
361 if (error) { 356 if (error) {
362 rename_which_error_return = __LINE__;
363 xfs_trans_cancel(tp, 0); 357 xfs_trans_cancel(tp, 0);
364 goto rele_return; 358 goto rele_return;
365 } 359 }
@@ -369,7 +363,6 @@ xfs_rename(
369 */ 363 */
370 if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { 364 if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) {
371 xfs_trans_cancel(tp, cancel_flags); 365 xfs_trans_cancel(tp, cancel_flags);
372 rename_which_error_return = __LINE__;
373 goto rele_return; 366 goto rele_return;
374 } 367 }
375 368
@@ -413,7 +406,6 @@ xfs_rename(
413 if (spaceres == 0 && 406 if (spaceres == 0 &&
414 (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, 407 (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name,
415 target_namelen))) { 408 target_namelen))) {
416 rename_which_error_return = __LINE__;
417 goto error_return; 409 goto error_return;
418 } 410 }
419 /* 411 /*
@@ -425,11 +417,9 @@ xfs_rename(
425 target_namelen, src_ip->i_ino, 417 target_namelen, src_ip->i_ino,
426 &first_block, &free_list, spaceres); 418 &first_block, &free_list, spaceres);
427 if (error == ENOSPC) { 419 if (error == ENOSPC) {
428 rename_which_error_return = __LINE__;
429 goto error_return; 420 goto error_return;
430 } 421 }
431 if (error) { 422 if (error) {
432 rename_which_error_return = __LINE__;
433 goto abort_return; 423 goto abort_return;
434 } 424 }
435 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 425 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -437,7 +427,6 @@ xfs_rename(
437 if (new_parent && src_is_directory) { 427 if (new_parent && src_is_directory) {
438 error = xfs_bumplink(tp, target_dp); 428 error = xfs_bumplink(tp, target_dp);
439 if (error) { 429 if (error) {
440 rename_which_error_return = __LINE__;
441 goto abort_return; 430 goto abort_return;
442 } 431 }
443 } 432 }
@@ -455,7 +444,6 @@ xfs_rename(
455 if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || 444 if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) ||
456 (target_ip->i_d.di_nlink > 2)) { 445 (target_ip->i_d.di_nlink > 2)) {
457 error = XFS_ERROR(EEXIST); 446 error = XFS_ERROR(EEXIST);
458 rename_which_error_return = __LINE__;
459 goto error_return; 447 goto error_return;
460 } 448 }
461 } 449 }
@@ -473,7 +461,6 @@ xfs_rename(
473 target_namelen, src_ip->i_ino, &first_block, 461 target_namelen, src_ip->i_ino, &first_block,
474 &free_list, spaceres); 462 &free_list, spaceres);
475 if (error) { 463 if (error) {
476 rename_which_error_return = __LINE__;
477 goto abort_return; 464 goto abort_return;
478 } 465 }
479 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 466 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -484,7 +471,6 @@ xfs_rename(
484 */ 471 */
485 error = xfs_droplink(tp, target_ip); 472 error = xfs_droplink(tp, target_ip);
486 if (error) { 473 if (error) {
487 rename_which_error_return = __LINE__;
488 goto abort_return; 474 goto abort_return;
489 } 475 }
490 target_ip_dropped = 1; 476 target_ip_dropped = 1;
@@ -495,7 +481,6 @@ xfs_rename(
495 */ 481 */
496 error = xfs_droplink(tp, target_ip); 482 error = xfs_droplink(tp, target_ip);
497 if (error) { 483 if (error) {
498 rename_which_error_return = __LINE__;
499 goto abort_return; 484 goto abort_return;
500 } 485 }
501 } 486 }
@@ -519,7 +504,6 @@ xfs_rename(
519 &free_list, spaceres); 504 &free_list, spaceres);
520 ASSERT(error != EEXIST); 505 ASSERT(error != EEXIST);
521 if (error) { 506 if (error) {
522 rename_which_error_return = __LINE__;
523 goto abort_return; 507 goto abort_return;
524 } 508 }
525 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 509 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -550,7 +534,6 @@ xfs_rename(
550 */ 534 */
551 error = xfs_droplink(tp, src_dp); 535 error = xfs_droplink(tp, src_dp);
552 if (error) { 536 if (error) {
553 rename_which_error_return = __LINE__;
554 goto abort_return; 537 goto abort_return;
555 } 538 }
556 } 539 }
@@ -558,7 +541,6 @@ xfs_rename(
558 error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, 541 error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen,
559 src_ip->i_ino, &first_block, &free_list, spaceres); 542 src_ip->i_ino, &first_block, &free_list, spaceres);
560 if (error) { 543 if (error) {
561 rename_which_error_return = __LINE__;
562 goto abort_return; 544 goto abort_return;
563 } 545 }
564 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 546 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 3db0e2200775..06dfca531f79 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -332,25 +332,6 @@ undo_blocks:
332 332
333 333
334/* 334/*
335 * This is called to set the a callback to be called when the given
336 * transaction is committed to disk. The transaction pointer and the
337 * argument pointer will be passed to the callback routine.
338 *
339 * Only one callback can be associated with any single transaction.
340 */
341void
342xfs_trans_callback(
343 xfs_trans_t *tp,
344 xfs_trans_callback_t callback,
345 void *arg)
346{
347 ASSERT(tp->t_callback == NULL);
348 tp->t_callback = callback;
349 tp->t_callarg = arg;
350}
351
352
353/*
354 * Record the indicated change to the given field for application 335 * Record the indicated change to the given field for application
355 * to the file system's superblock when the transaction commits. 336 * to the file system's superblock when the transaction commits.
356 * For now, just store the change in the transaction structure. 337 * For now, just store the change in the transaction structure.
@@ -551,7 +532,7 @@ xfs_trans_apply_sb_deltas(
551 * 532 *
552 * This is done efficiently with a single call to xfs_mod_incore_sb_batch(). 533 * This is done efficiently with a single call to xfs_mod_incore_sb_batch().
553 */ 534 */
554void 535STATIC void
555xfs_trans_unreserve_and_mod_sb( 536xfs_trans_unreserve_and_mod_sb(
556 xfs_trans_t *tp) 537 xfs_trans_t *tp)
557{ 538{
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index bd37ccb85e76..ec541d66fa2a 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -987,8 +987,6 @@ xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint);
987xfs_trans_t *xfs_trans_dup(xfs_trans_t *); 987xfs_trans_t *xfs_trans_dup(xfs_trans_t *);
988int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, 988int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint,
989 uint, uint); 989 uint, uint);
990void xfs_trans_callback(xfs_trans_t *,
991 void (*)(xfs_trans_t *, void *), void *);
992void xfs_trans_mod_sb(xfs_trans_t *, uint, long); 990void xfs_trans_mod_sb(xfs_trans_t *, uint, long);
993struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t, 991struct xfs_buf *xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t,
994 int, uint); 992 int, uint);
@@ -1010,7 +1008,6 @@ int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
1010 xfs_ino_t , uint, uint, struct xfs_inode **); 1008 xfs_ino_t , uint, uint, struct xfs_inode **);
1011void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint); 1009void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
1012void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *); 1010void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
1013void xfs_trans_ihold_release(xfs_trans_t *, struct xfs_inode *);
1014void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); 1011void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
1015void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); 1012void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
1016struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); 1013struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index a9682b9510c1..144da7a85466 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -976,6 +976,7 @@ xfs_trans_dquot_buf(
976 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); 976 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
977 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); 977 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
978 ASSERT(type == XFS_BLI_UDQUOT_BUF || 978 ASSERT(type == XFS_BLI_UDQUOT_BUF ||
979 type == XFS_BLI_PDQUOT_BUF ||
979 type == XFS_BLI_GDQUOT_BUF); 980 type == XFS_BLI_GDQUOT_BUF);
980 981
981 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); 982 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index e2c3706f453d..7e7631ca4979 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -253,24 +253,6 @@ xfs_trans_ihold(
253 ip->i_itemp->ili_flags |= XFS_ILI_HOLD; 253 ip->i_itemp->ili_flags |= XFS_ILI_HOLD;
254} 254}
255 255
256/*
257 * Cancel the previous inode hold request made on this inode
258 * for this transaction.
259 */
260/*ARGSUSED*/
261void
262xfs_trans_ihold_release(
263 xfs_trans_t *tp,
264 xfs_inode_t *ip)
265{
266 ASSERT(ip->i_transp == tp);
267 ASSERT(ip->i_itemp != NULL);
268 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
269 ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD);
270
271 ip->i_itemp->ili_flags &= ~XFS_ILI_HOLD;
272}
273
274 256
275/* 257/*
276 * This is called to mark the fields indicated in fieldmask as needing 258 * This is called to mark the fields indicated in fieldmask as needing
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index e4bf711e48ff..16f5371ce102 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -55,7 +55,7 @@ typedef signed long long int __int64_t;
55typedef unsigned long long int __uint64_t; 55typedef unsigned long long int __uint64_t;
56 56
57typedef enum { B_FALSE,B_TRUE } boolean_t; 57typedef enum { B_FALSE,B_TRUE } boolean_t;
58typedef __int64_t prid_t; /* project ID */ 58typedef __uint32_t prid_t; /* project ID */
59typedef __uint32_t inst_t; /* an instruction */ 59typedef __uint32_t inst_t; /* an instruction */
60 60
61typedef __s64 xfs_off_t; /* <file offset> type */ 61typedef __s64 xfs_off_t; /* <file offset> type */
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index d1f8146a06ea..11351f08d438 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -428,7 +428,7 @@ xfs_truncate_file(
428 if (ip->i_ino != mp->m_sb.sb_uquotino) 428 if (ip->i_ino != mp->m_sb.sb_uquotino)
429 ASSERT(ip->i_udquot); 429 ASSERT(ip->i_udquot);
430 } 430 }
431 if (XFS_IS_GQUOTA_ON(mp)) { 431 if (XFS_IS_OQUOTA_ON(mp)) {
432 if (ip->i_ino != mp->m_sb.sb_gquotino) 432 if (ip->i_ino != mp->m_sb.sb_gquotino)
433 ASSERT(ip->i_gdquot); 433 ASSERT(ip->i_gdquot);
434 } 434 }
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index b53736650100..42bcc0215203 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -368,16 +368,6 @@ xfs_finish_flags(
368 } 368 }
369 369
370 /* 370 /*
371 * disallow mount attempts with (IRIX) project quota enabled
372 */
373 if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
374 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) {
375 cmn_err(CE_WARN,
376 "XFS: cannot mount a filesystem with IRIX project quota enabled");
377 return XFS_ERROR(ENOSYS);
378 }
379
380 /*
381 * check for shared mount. 371 * check for shared mount.
382 */ 372 */
383 if (ap->flags & XFSMNT_SHARED) { 373 if (ap->flags & XFSMNT_SHARED) {
@@ -622,7 +612,34 @@ out:
622 return XFS_ERROR(error); 612 return XFS_ERROR(error);
623} 613}
624 614
625#define REMOUNT_READONLY_FLAGS (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT) 615STATIC int
616xfs_quiesce_fs(
617 xfs_mount_t *mp)
618{
619 int count = 0, pincount;
620
621 xfs_refcache_purge_mp(mp);
622 xfs_flush_buftarg(mp->m_ddev_targp, 0);
623 xfs_finish_reclaim_all(mp, 0);
624
625 /* This loop must run at least twice.
626 * The first instance of the loop will flush
627 * most meta data but that will generate more
628 * meta data (typically directory updates).
629 * Which then must be flushed and logged before
630 * we can write the unmount record.
631 */
632 do {
633 xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL);
634 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
635 if (!pincount) {
636 delay(50);
637 count++;
638 }
639 } while (count < 2);
640
641 return 0;
642}
626 643
627STATIC int 644STATIC int
628xfs_mntupdate( 645xfs_mntupdate(
@@ -632,8 +649,7 @@ xfs_mntupdate(
632{ 649{
633 struct vfs *vfsp = bhvtovfs(bdp); 650 struct vfs *vfsp = bhvtovfs(bdp);
634 xfs_mount_t *mp = XFS_BHVTOM(bdp); 651 xfs_mount_t *mp = XFS_BHVTOM(bdp);
635 int pincount, error; 652 int error;
636 int count = 0;
637 653
638 if (args->flags & XFSMNT_NOATIME) 654 if (args->flags & XFSMNT_NOATIME)
639 mp->m_flags |= XFS_MOUNT_NOATIME; 655 mp->m_flags |= XFS_MOUNT_NOATIME;
@@ -645,25 +661,7 @@ xfs_mntupdate(
645 } 661 }
646 662
647 if (*flags & MS_RDONLY) { 663 if (*flags & MS_RDONLY) {
648 xfs_refcache_purge_mp(mp); 664 xfs_quiesce_fs(mp);
649 xfs_flush_buftarg(mp->m_ddev_targp, 0);
650 xfs_finish_reclaim_all(mp, 0);
651
652 /* This loop must run at least twice.
653 * The first instance of the loop will flush
654 * most meta data but that will generate more
655 * meta data (typically directory updates).
656 * Which then must be flushed and logged before
657 * we can write the unmount record.
658 */
659 do {
660 VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error);
661 pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
662 if (!pincount) {
663 delay(50);
664 count++;
665 }
666 } while (count < 2);
667 665
668 /* Ok now write out an unmount record */ 666 /* Ok now write out an unmount record */
669 xfs_log_unmount_write(mp); 667 xfs_log_unmount_write(mp);
@@ -879,10 +877,12 @@ xfs_sync(
879 int flags, 877 int flags,
880 cred_t *credp) 878 cred_t *credp)
881{ 879{
882 xfs_mount_t *mp; 880 xfs_mount_t *mp = XFS_BHVTOM(bdp);
883 881
884 mp = XFS_BHVTOM(bdp); 882 if (unlikely(flags == SYNC_QUIESCE))
885 return (xfs_syncsub(mp, flags, 0, NULL)); 883 return xfs_quiesce_fs(mp);
884 else
885 return xfs_syncsub(mp, flags, 0, NULL);
886} 886}
887 887
888/* 888/*
@@ -1681,7 +1681,7 @@ suffix_strtoul(const char *cp, char **endp, unsigned int base)
1681 return simple_strtoul(cp, endp, base) << shift_left_factor; 1681 return simple_strtoul(cp, endp, base) << shift_left_factor;
1682} 1682}
1683 1683
1684int 1684STATIC int
1685xfs_parseargs( 1685xfs_parseargs(
1686 struct bhv_desc *bhv, 1686 struct bhv_desc *bhv,
1687 char *options, 1687 char *options,
@@ -1867,7 +1867,7 @@ printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n");
1867 return 0; 1867 return 0;
1868} 1868}
1869 1869
1870int 1870STATIC int
1871xfs_showargs( 1871xfs_showargs(
1872 struct bhv_desc *bhv, 1872 struct bhv_desc *bhv,
1873 struct seq_file *m) 1873 struct seq_file *m)
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 25a526629b12..1377c868f3f4 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as 5 * under the terms of version 2 of the GNU General Public License as
@@ -351,21 +351,28 @@ xfs_setattr(
351 * If the IDs do change before we take the ilock, we're covered 351 * If the IDs do change before we take the ilock, we're covered
352 * because the i_*dquot fields will get updated anyway. 352 * because the i_*dquot fields will get updated anyway.
353 */ 353 */
354 if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) { 354 if (XFS_IS_QUOTA_ON(mp) &&
355 (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
355 uint qflags = 0; 356 uint qflags = 0;
356 357
357 if (mask & XFS_AT_UID) { 358 if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
358 uid = vap->va_uid; 359 uid = vap->va_uid;
359 qflags |= XFS_QMOPT_UQUOTA; 360 qflags |= XFS_QMOPT_UQUOTA;
360 } else { 361 } else {
361 uid = ip->i_d.di_uid; 362 uid = ip->i_d.di_uid;
362 } 363 }
363 if (mask & XFS_AT_GID) { 364 if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) {
364 gid = vap->va_gid; 365 gid = vap->va_gid;
365 qflags |= XFS_QMOPT_GQUOTA; 366 qflags |= XFS_QMOPT_GQUOTA;
366 } else { 367 } else {
367 gid = ip->i_d.di_gid; 368 gid = ip->i_d.di_gid;
368 } 369 }
370 if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) {
371 projid = vap->va_projid;
372 qflags |= XFS_QMOPT_PQUOTA;
373 } else {
374 projid = ip->i_d.di_projid;
375 }
369 /* 376 /*
370 * We take a reference when we initialize udqp and gdqp, 377 * We take a reference when we initialize udqp and gdqp,
371 * so it is important that we never blindly double trip on 378 * so it is important that we never blindly double trip on
@@ -373,7 +380,8 @@ xfs_setattr(
373 */ 380 */
374 ASSERT(udqp == NULL); 381 ASSERT(udqp == NULL);
375 ASSERT(gdqp == NULL); 382 ASSERT(gdqp == NULL);
376 code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp); 383 code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags,
384 &udqp, &gdqp);
377 if (code) 385 if (code)
378 return (code); 386 return (code);
379 } 387 }
@@ -499,8 +507,6 @@ xfs_setattr(
499 * that the group ID supplied to the chown() function 507 * that the group ID supplied to the chown() function
500 * shall be equal to either the group ID or one of the 508 * shall be equal to either the group ID or one of the
501 * supplementary group IDs of the calling process. 509 * supplementary group IDs of the calling process.
502 *
503 * XXX: How does restricted_chown affect projid?
504 */ 510 */
505 if (restricted_chown && 511 if (restricted_chown &&
506 (iuid != uid || (igid != gid && 512 (iuid != uid || (igid != gid &&
@@ -510,10 +516,11 @@ xfs_setattr(
510 goto error_return; 516 goto error_return;
511 } 517 }
512 /* 518 /*
513 * Do a quota reservation only if uid or gid is actually 519 * Do a quota reservation only if uid/projid/gid is actually
514 * going to change. 520 * going to change.
515 */ 521 */
516 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || 522 if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
523 (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
517 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) { 524 (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
518 ASSERT(tp); 525 ASSERT(tp);
519 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp, 526 code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
@@ -774,6 +781,7 @@ xfs_setattr(
774 } 781 }
775 if (igid != gid) { 782 if (igid != gid) {
776 if (XFS_IS_GQUOTA_ON(mp)) { 783 if (XFS_IS_GQUOTA_ON(mp)) {
784 ASSERT(!XFS_IS_PQUOTA_ON(mp));
777 ASSERT(mask & XFS_AT_GID); 785 ASSERT(mask & XFS_AT_GID);
778 ASSERT(gdqp); 786 ASSERT(gdqp);
779 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip, 787 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
@@ -782,6 +790,13 @@ xfs_setattr(
782 ip->i_d.di_gid = gid; 790 ip->i_d.di_gid = gid;
783 } 791 }
784 if (iprojid != projid) { 792 if (iprojid != projid) {
793 if (XFS_IS_PQUOTA_ON(mp)) {
794 ASSERT(!XFS_IS_GQUOTA_ON(mp));
795 ASSERT(mask & XFS_AT_PROJID);
796 ASSERT(gdqp);
797 olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
798 &ip->i_gdquot, gdqp);
799 }
785 ip->i_d.di_projid = projid; 800 ip->i_d.di_projid = projid;
786 /* 801 /*
787 * We may have to rev the inode as well as 802 * We may have to rev the inode as well as
@@ -843,6 +858,8 @@ xfs_setattr(
843 di_flags |= XFS_DIFLAG_NOATIME; 858 di_flags |= XFS_DIFLAG_NOATIME;
844 if (vap->va_xflags & XFS_XFLAG_NODUMP) 859 if (vap->va_xflags & XFS_XFLAG_NODUMP)
845 di_flags |= XFS_DIFLAG_NODUMP; 860 di_flags |= XFS_DIFLAG_NODUMP;
861 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
862 di_flags |= XFS_DIFLAG_PROJINHERIT;
846 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 863 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
847 if (vap->va_xflags & XFS_XFLAG_RTINHERIT) 864 if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
848 di_flags |= XFS_DIFLAG_RTINHERIT; 865 di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -1898,7 +1915,9 @@ xfs_create(
1898 /* Return through std_return after this point. */ 1915 /* Return through std_return after this point. */
1899 1916
1900 udqp = gdqp = NULL; 1917 udqp = gdqp = NULL;
1901 if (vap->va_mask & XFS_AT_PROJID) 1918 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1919 prid = dp->i_d.di_projid;
1920 else if (vap->va_mask & XFS_AT_PROJID)
1902 prid = (xfs_prid_t)vap->va_projid; 1921 prid = (xfs_prid_t)vap->va_projid;
1903 else 1922 else
1904 prid = (xfs_prid_t)dfltprid; 1923 prid = (xfs_prid_t)dfltprid;
@@ -1907,7 +1926,7 @@ xfs_create(
1907 * Make sure that we have allocated dquot(s) on disk. 1926 * Make sure that we have allocated dquot(s) on disk.
1908 */ 1927 */
1909 error = XFS_QM_DQVOPALLOC(mp, dp, 1928 error = XFS_QM_DQVOPALLOC(mp, dp,
1910 current_fsuid(credp), current_fsgid(credp), 1929 current_fsuid(credp), current_fsgid(credp), prid,
1911 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp); 1930 XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
1912 if (error) 1931 if (error)
1913 goto std_return; 1932 goto std_return;
@@ -2604,17 +2623,7 @@ xfs_link(
2604 if (src_vp->v_type == VDIR) 2623 if (src_vp->v_type == VDIR)
2605 return XFS_ERROR(EPERM); 2624 return XFS_ERROR(EPERM);
2606 2625
2607 /*
2608 * For now, manually find the XFS behavior descriptor for
2609 * the source vnode. If it doesn't exist then something
2610 * is wrong and we should just return an error.
2611 * Eventually we need to figure out how link is going to
2612 * work in the face of stacked vnodes.
2613 */
2614 src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); 2626 src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops);
2615 if (src_bdp == NULL) {
2616 return XFS_ERROR(EXDEV);
2617 }
2618 sip = XFS_BHVTOI(src_bdp); 2627 sip = XFS_BHVTOI(src_bdp);
2619 tdp = XFS_BHVTOI(target_dir_bdp); 2628 tdp = XFS_BHVTOI(target_dir_bdp);
2620 mp = tdp->i_mount; 2629 mp = tdp->i_mount;
@@ -2681,6 +2690,17 @@ xfs_link(
2681 goto error_return; 2690 goto error_return;
2682 } 2691 }
2683 2692
2693 /*
2694 * If we are using project inheritance, we only allow hard link
2695 * creation in our tree when the project IDs are the same; else
2696 * the tree quota mechanism could be circumvented.
2697 */
2698 if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
2699 (tdp->i_d.di_projid != sip->i_d.di_projid))) {
2700 error = XFS_ERROR(EPERM);
2701 goto error_return;
2702 }
2703
2684 if (resblks == 0 && 2704 if (resblks == 0 &&
2685 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, 2705 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name,
2686 target_namelen))) 2706 target_namelen)))
@@ -2803,7 +2823,9 @@ xfs_mkdir(
2803 2823
2804 mp = dp->i_mount; 2824 mp = dp->i_mount;
2805 udqp = gdqp = NULL; 2825 udqp = gdqp = NULL;
2806 if (vap->va_mask & XFS_AT_PROJID) 2826 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
2827 prid = dp->i_d.di_projid;
2828 else if (vap->va_mask & XFS_AT_PROJID)
2807 prid = (xfs_prid_t)vap->va_projid; 2829 prid = (xfs_prid_t)vap->va_projid;
2808 else 2830 else
2809 prid = (xfs_prid_t)dfltprid; 2831 prid = (xfs_prid_t)dfltprid;
@@ -2812,7 +2834,7 @@ xfs_mkdir(
2812 * Make sure that we have allocated dquot(s) on disk. 2834 * Make sure that we have allocated dquot(s) on disk.
2813 */ 2835 */
2814 error = XFS_QM_DQVOPALLOC(mp, dp, 2836 error = XFS_QM_DQVOPALLOC(mp, dp,
2815 current_fsuid(credp), current_fsgid(credp), 2837 current_fsuid(credp), current_fsgid(credp), prid,
2816 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 2838 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
2817 if (error) 2839 if (error)
2818 goto std_return; 2840 goto std_return;
@@ -3357,7 +3379,9 @@ xfs_symlink(
3357 /* Return through std_return after this point. */ 3379 /* Return through std_return after this point. */
3358 3380
3359 udqp = gdqp = NULL; 3381 udqp = gdqp = NULL;
3360 if (vap->va_mask & XFS_AT_PROJID) 3382 if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
3383 prid = dp->i_d.di_projid;
3384 else if (vap->va_mask & XFS_AT_PROJID)
3361 prid = (xfs_prid_t)vap->va_projid; 3385 prid = (xfs_prid_t)vap->va_projid;
3362 else 3386 else
3363 prid = (xfs_prid_t)dfltprid; 3387 prid = (xfs_prid_t)dfltprid;
@@ -3366,7 +3390,7 @@ xfs_symlink(
3366 * Make sure that we have allocated dquot(s) on disk. 3390 * Make sure that we have allocated dquot(s) on disk.
3367 */ 3391 */
3368 error = XFS_QM_DQVOPALLOC(mp, dp, 3392 error = XFS_QM_DQVOPALLOC(mp, dp,
3369 current_fsuid(credp), current_fsgid(credp), 3393 current_fsuid(credp), current_fsgid(credp), prid,
3370 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 3394 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
3371 if (error) 3395 if (error)
3372 goto std_return; 3396 goto std_return;
@@ -4028,7 +4052,7 @@ xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
4028 * errno on error 4052 * errno on error
4029 * 4053 *
4030 */ 4054 */
4031int 4055STATIC int
4032xfs_alloc_file_space( 4056xfs_alloc_file_space(
4033 xfs_inode_t *ip, 4057 xfs_inode_t *ip,
4034 xfs_off_t offset, 4058 xfs_off_t offset,
@@ -4151,9 +4175,8 @@ retry:
4151 break; 4175 break;
4152 } 4176 }
4153 xfs_ilock(ip, XFS_ILOCK_EXCL); 4177 xfs_ilock(ip, XFS_ILOCK_EXCL);
4154 error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, 4178 error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
4155 ip->i_udquot, ip->i_gdquot, resblks, 0, rt ? 4179 ip->i_udquot, ip->i_gdquot, resblks, 0, 0);
4156 XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
4157 if (error) 4180 if (error)
4158 goto error1; 4181 goto error1;
4159 4182
@@ -4305,6 +4328,7 @@ xfs_free_file_space(
4305 xfs_off_t len, 4328 xfs_off_t len,
4306 int attr_flags) 4329 int attr_flags)
4307{ 4330{
4331 vnode_t *vp;
4308 int committed; 4332 int committed;
4309 int done; 4333 int done;
4310 xfs_off_t end_dmi_offset; 4334 xfs_off_t end_dmi_offset;
@@ -4325,9 +4349,11 @@ xfs_free_file_space(
4325 xfs_trans_t *tp; 4349 xfs_trans_t *tp;
4326 int need_iolock = 1; 4350 int need_iolock = 1;
4327 4351
4328 vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); 4352 vp = XFS_ITOV(ip);
4329 mp = ip->i_mount; 4353 mp = ip->i_mount;
4330 4354
4355 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
4356
4331 if ((error = XFS_QM_DQATTACH(mp, ip, 0))) 4357 if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
4332 return error; 4358 return error;
4333 4359
@@ -4344,7 +4370,7 @@ xfs_free_file_space(
4344 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) { 4370 DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
4345 if (end_dmi_offset > ip->i_d.di_size) 4371 if (end_dmi_offset > ip->i_d.di_size)
4346 end_dmi_offset = ip->i_d.di_size; 4372 end_dmi_offset = ip->i_d.di_size;
4347 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip), 4373 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
4348 offset, end_dmi_offset - offset, 4374 offset, end_dmi_offset - offset,
4349 AT_DELAY_FLAG(attr_flags), NULL); 4375 AT_DELAY_FLAG(attr_flags), NULL);
4350 if (error) 4376 if (error)
@@ -4363,7 +4389,14 @@ xfs_free_file_space(
4363 ioffset = offset & ~(rounding - 1); 4389 ioffset = offset & ~(rounding - 1);
4364 if (ilen & (rounding - 1)) 4390 if (ilen & (rounding - 1))
4365 ilen = (ilen + rounding) & ~(rounding - 1); 4391 ilen = (ilen + rounding) & ~(rounding - 1);
4366 xfs_inval_cached_pages(XFS_ITOV(ip), &(ip->i_iocore), ioffset, 0, 0); 4392
4393 if (VN_CACHED(vp) != 0) {
4394 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4395 ctooff(offtoct(ioffset)), -1);
4396 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)),
4397 -1, FI_REMAPF_LOCKED);
4398 }
4399
4367 /* 4400 /*
4368 * Need to zero the stuff we're not freeing, on disk. 4401 * Need to zero the stuff we're not freeing, on disk.
4369 * If its a realtime file & can't use unwritten extents then we 4402 * If its a realtime file & can't use unwritten extents then we