aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_super.c21
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/adfs/super.c15
-rw-r--r--fs/affs/super.c12
-rw-r--r--fs/afs/dir.c4
-rw-r--r--fs/afs/mntpt.c11
-rw-r--r--fs/afs/super.c24
-rw-r--r--fs/aio.c4
-rw-r--r--fs/autofs/init.c6
-rw-r--r--fs/autofs4/init.c6
-rw-r--r--fs/befs/linuxvfs.c12
-rw-r--r--fs/bfs/inode.c9
-rw-r--r--fs/binfmt_elf.c348
-rw-r--r--fs/binfmt_elf_fdpic.c26
-rw-r--r--fs/binfmt_misc.c7
-rw-r--r--fs/block_dev.c38
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/cifs/cifsfs.c13
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/file.c26
-rw-r--r--fs/coda/file.c2
-rw-r--r--fs/coda/inode.c12
-rw-r--r--fs/coda/upcall.c4
-rw-r--r--fs/compat.c8
-rw-r--r--fs/configfs/mount.c6
-rw-r--r--fs/cramfs/inode.c15
-rw-r--r--fs/dcache.c109
-rw-r--r--fs/debugfs/inode.c8
-rw-r--r--fs/devfs/base.c8
-rw-r--r--fs/devpts/inode.c6
-rw-r--r--fs/direct-io.c18
-rw-r--r--fs/efs/super.c12
-rw-r--r--fs/eventpoll.c13
-rw-r--r--fs/exec.c1
-rw-r--r--fs/ext2/dir.c3
-rw-r--r--fs/ext2/super.c36
-rw-r--r--fs/ext3/super.c70
-rw-r--r--fs/fat/inode.c8
-rw-r--r--fs/fat/misc.c1
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/freevxfs/vxfs_subr.c3
-rw-r--r--fs/freevxfs/vxfs_super.c20
-rw-r--r--fs/fs-writeback.c6
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/fuse/inode.c11
-rw-r--r--fs/hfs/bnode.c2
-rw-r--r--fs/hfs/btree.c2
-rw-r--r--fs/hfs/super.c11
-rw-r--r--fs/hfsplus/bitmap.c15
-rw-r--r--fs/hfsplus/bnode.c2
-rw-r--r--fs/hfsplus/btree.c2
-rw-r--r--fs/hfsplus/super.c12
-rw-r--r--fs/hostfs/hostfs_kern.c12
-rw-r--r--fs/hpfs/super.c10
-rw-r--r--fs/hppfs/hppfs_kern.c10
-rw-r--r--fs/hugetlbfs/inode.c31
-rw-r--r--fs/inotify_user.c6
-rw-r--r--fs/ioprio.c6
-rw-r--r--fs/isofs/inode.c13
-rw-r--r--fs/jbd/checkpoint.c419
-rw-r--r--fs/jbd/commit.c21
-rw-r--r--fs/jbd/transaction.c12
-rw-r--r--fs/jffs/inode-v23.c11
-rw-r--r--fs/jffs2/fs.c4
-rw-r--r--fs/jffs2/os-linux.h2
-rw-r--r--fs/jffs2/super.c49
-rw-r--r--fs/jfs/jfs_metapage.c5
-rw-r--r--fs/jfs/super.c11
-rw-r--r--fs/libfs.c16
-rw-r--r--fs/locks.c123
-rw-r--r--fs/minix/dir.c3
-rw-r--r--fs/minix/inode.c17
-rw-r--r--fs/mpage.c22
-rw-r--r--fs/msdos/namei.c9
-rw-r--r--fs/namei.c3
-rw-r--r--fs/namespace.c9
-rw-r--r--fs/ncpfs/inode.c11
-rw-r--r--fs/nfs/file.c4
-rw-r--r--fs/nfs/nfs2xdr.c1
-rw-r--r--fs/nfs/super.c168
-rw-r--r--fs/nfsd/nfs4xdr.c2
-rw-r--r--fs/nfsd/nfsctl.c6
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/ntfs/aops.h3
-rw-r--r--fs/ntfs/attrib.c6
-rw-r--r--fs/ntfs/file.c16
-rw-r--r--fs/ntfs/super.c14
-rw-r--r--fs/ocfs2/dlm/dlmfs.c6
-rw-r--r--fs/ocfs2/super.c22
-rw-r--r--fs/ocfs2/symlink.c3
-rw-r--r--fs/open.c28
-rw-r--r--fs/openpromfs/inode.c6
-rw-r--r--fs/partitions/check.c12
-rw-r--r--fs/pipe.c9
-rw-r--r--fs/proc/root.c6
-rw-r--r--fs/qnx4/inode.c13
-rw-r--r--fs/ramfs/inode.c13
-rw-r--r--fs/reiserfs/super.c17
-rw-r--r--fs/reiserfs/xattr.c3
-rw-r--r--fs/romfs/inode.c11
-rw-r--r--fs/select.c83
-rw-r--r--fs/smbfs/inode.c12
-rw-r--r--fs/smbfs/proc.c4
-rw-r--r--fs/smbfs/proto.h2
-rw-r--r--fs/splice.c46
-rw-r--r--fs/super.c95
-rw-r--r--fs/sync.c2
-rw-r--r--fs/sysfs/mount.c6
-rw-r--r--fs/sysv/dir.c3
-rw-r--r--fs/sysv/inode.c3
-rw-r--r--fs/sysv/super.c13
-rw-r--r--fs/udf/super.c12
-rw-r--r--fs/ufs/super.c9
-rw-r--r--fs/vfat/namei.c9
-rw-r--r--fs/xfs/Kconfig27
-rw-r--r--fs/xfs/Makefile-linux-2.64
-rw-r--r--fs/xfs/linux-2.6/kmem.h38
-rw-r--r--fs/xfs/linux-2.6/mrlock.h4
-rw-r--r--fs/xfs/linux-2.6/sema.h19
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c65
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c13
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c170
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c59
-rw-r--r--fs/xfs/linux-2.6/xfs_globals.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c65
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c117
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h35
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c123
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h6
-rw-r--r--fs/xfs/linux-2.6/xfs_stats.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c200
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.c7
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.c41
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h167
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c52
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h376
-rw-r--r--fs/xfs/quota/xfs_dquot.c8
-rw-r--r--fs/xfs/quota/xfs_dquot.h4
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c6
-rw-r--r--fs/xfs/quota/xfs_qm.c8
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c81
-rw-r--r--fs/xfs/quota/xfs_qm_stats.c2
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c6
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c2
-rw-r--r--fs/xfs/support/debug.c4
-rw-r--r--fs/xfs/support/debug.h3
-rw-r--r--fs/xfs/xfs_acl.c71
-rw-r--r--fs/xfs/xfs_acl.h16
-rw-r--r--fs/xfs/xfs_alloc.c31
-rw-r--r--fs/xfs/xfs_alloc.h2
-rw-r--r--fs/xfs/xfs_alloc_btree.c2
-rw-r--r--fs/xfs/xfs_attr.c66
-rw-r--r--fs/xfs/xfs_attr.h14
-rw-r--r--fs/xfs/xfs_attr_leaf.c4
-rw-r--r--fs/xfs/xfs_bmap.c386
-rw-r--r--fs/xfs/xfs_bmap.h22
-rw-r--r--fs/xfs/xfs_bmap_btree.c12
-rw-r--r--fs/xfs/xfs_btree.c2
-rw-r--r--fs/xfs/xfs_buf_item.c9
-rw-r--r--fs/xfs/xfs_cap.h10
-rw-r--r--fs/xfs/xfs_da_btree.c194
-rw-r--r--fs/xfs/xfs_da_btree.h4
-rw-r--r--fs/xfs/xfs_dfrag.c84
-rw-r--r--fs/xfs/xfs_dfrag.h3
-rw-r--r--fs/xfs/xfs_dinode.h5
-rw-r--r--fs/xfs/xfs_dir.c1217
-rw-r--r--fs/xfs/xfs_dir.h142
-rw-r--r--fs/xfs/xfs_dir2.c396
-rw-r--r--fs/xfs/xfs_dir2.h32
-rw-r--r--fs/xfs/xfs_dir2_block.c31
-rw-r--r--fs/xfs/xfs_dir2_data.c5
-rw-r--r--fs/xfs/xfs_dir2_data.h8
-rw-r--r--fs/xfs/xfs_dir2_leaf.c14
-rw-r--r--fs/xfs/xfs_dir2_node.c16
-rw-r--r--fs/xfs/xfs_dir2_sf.c13
-rw-r--r--fs/xfs/xfs_dir2_trace.c2
-rw-r--r--fs/xfs/xfs_dir_leaf.c2213
-rw-r--r--fs/xfs/xfs_dir_leaf.h231
-rw-r--r--fs/xfs/xfs_dir_sf.h155
-rw-r--r--fs/xfs/xfs_dmapi.h2
-rw-r--r--fs/xfs/xfs_dmops.c1
-rw-r--r--fs/xfs/xfs_error.c2
-rw-r--r--fs/xfs/xfs_extfree_item.c57
-rw-r--r--fs/xfs/xfs_extfree_item.h53
-rw-r--r--fs/xfs/xfs_fs.h7
-rw-r--r--fs/xfs/xfs_fsops.c20
-rw-r--r--fs/xfs/xfs_ialloc.c5
-rw-r--r--fs/xfs/xfs_ialloc_btree.c2
-rw-r--r--fs/xfs/xfs_iget.c22
-rw-r--r--fs/xfs/xfs_inode.c94
-rw-r--r--fs/xfs/xfs_inode.h7
-rw-r--r--fs/xfs/xfs_inode_item.c57
-rw-r--r--fs/xfs/xfs_inode_item.h61
-rw-r--r--fs/xfs/xfs_iocore.c7
-rw-r--r--fs/xfs/xfs_iomap.c26
-rw-r--r--fs/xfs/xfs_itable.c20
-rw-r--r--fs/xfs/xfs_itable.h1
-rw-r--r--fs/xfs/xfs_log.c21
-rw-r--r--fs/xfs/xfs_log_recover.c113
-rw-r--r--fs/xfs/xfs_mount.c54
-rw-r--r--fs/xfs/xfs_mount.h70
-rw-r--r--fs/xfs/xfs_qmops.c1
-rw-r--r--fs/xfs/xfs_quota.h2
-rw-r--r--fs/xfs/xfs_rename.c68
-rw-r--r--fs/xfs/xfs_rtalloc.c16
-rw-r--r--fs/xfs/xfs_rw.c124
-rw-r--r--fs/xfs/xfs_rw.h10
-rw-r--r--fs/xfs/xfs_trans.c48
-rw-r--r--fs/xfs/xfs_trans.h7
-rw-r--r--fs/xfs/xfs_trans_ail.c6
-rw-r--r--fs/xfs/xfs_trans_buf.c12
-rw-r--r--fs/xfs/xfs_trans_extfree.c1
-rw-r--r--fs/xfs/xfs_trans_inode.c2
-rw-r--r--fs/xfs/xfs_trans_item.c2
-rw-r--r--fs/xfs/xfs_trans_space.h11
-rw-r--r--fs/xfs/xfs_utils.c13
-rw-r--r--fs/xfs/xfs_utils.h7
-rw-r--r--fs/xfs/xfs_vfsops.c122
-rw-r--r--fs/xfs/xfs_vnodeops.c295
223 files changed, 3685 insertions, 7432 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 00c1f6baf870..8b15bb22caca 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -99,12 +99,13 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
99 * @flags: mount flags 99 * @flags: mount flags
100 * @dev_name: device name that was mounted 100 * @dev_name: device name that was mounted
101 * @data: mount options 101 * @data: mount options
102 * @mnt: mountpoint record to be instantiated
102 * 103 *
103 */ 104 */
104 105
105static struct super_block *v9fs_get_sb(struct file_system_type 106static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
106 *fs_type, int flags, 107 const char *dev_name, void *data,
107 const char *dev_name, void *data) 108 struct vfsmount *mnt)
108{ 109{
109 struct super_block *sb = NULL; 110 struct super_block *sb = NULL;
110 struct v9fs_fcall *fcall = NULL; 111 struct v9fs_fcall *fcall = NULL;
@@ -123,17 +124,19 @@ static struct super_block *v9fs_get_sb(struct file_system_type
123 124
124 v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); 125 v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
125 if (!v9ses) 126 if (!v9ses)
126 return ERR_PTR(-ENOMEM); 127 return -ENOMEM;
127 128
128 if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { 129 if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
129 dprintk(DEBUG_ERROR, "problem initiating session\n"); 130 dprintk(DEBUG_ERROR, "problem initiating session\n");
130 sb = ERR_PTR(newfid); 131 retval = newfid;
131 goto out_free_session; 132 goto out_free_session;
132 } 133 }
133 134
134 sb = sget(fs_type, NULL, v9fs_set_super, v9ses); 135 sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
135 if (IS_ERR(sb)) 136 if (IS_ERR(sb)) {
137 retval = PTR_ERR(sb);
136 goto out_close_session; 138 goto out_close_session;
139 }
137 v9fs_fill_super(sb, v9ses, flags); 140 v9fs_fill_super(sb, v9ses, flags);
138 141
139 inode = v9fs_get_inode(sb, S_IFDIR | mode); 142 inode = v9fs_get_inode(sb, S_IFDIR | mode);
@@ -184,19 +187,19 @@ static struct super_block *v9fs_get_sb(struct file_system_type
184 goto put_back_sb; 187 goto put_back_sb;
185 } 188 }
186 189
187 return sb; 190 return simple_set_mnt(mnt, sb);
188 191
189out_close_session: 192out_close_session:
190 v9fs_session_close(v9ses); 193 v9fs_session_close(v9ses);
191out_free_session: 194out_free_session:
192 kfree(v9ses); 195 kfree(v9ses);
193 return sb; 196 return retval;
194 197
195put_back_sb: 198put_back_sb:
196 /* deactivate_super calls v9fs_kill_super which will frees the rest */ 199 /* deactivate_super calls v9fs_kill_super which will frees the rest */
197 up_write(&sb->s_umount); 200 up_write(&sb->s_umount);
198 deactivate_super(sb); 201 deactivate_super(sb);
199 return ERR_PTR(retval); 202 return retval;
200} 203}
201 204
202/** 205/**
diff --git a/fs/Kconfig b/fs/Kconfig
index 20f9b557732d..2aa4624cc018 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -53,7 +53,7 @@ config EXT2_FS_SECURITY
53 53
54config EXT2_FS_XIP 54config EXT2_FS_XIP
55 bool "Ext2 execute in place support" 55 bool "Ext2 execute in place support"
56 depends on EXT2_FS 56 depends on EXT2_FS && MMU
57 help 57 help
58 Execute in place can be used on memory-backed block devices. If you 58 Execute in place can be used on memory-backed block devices. If you
59 enable this option, you can select to mount block devices which are 59 enable this option, you can select to mount block devices which are
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 252abda0d200..ba1c88af49fe 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -196,17 +196,17 @@ static int adfs_remount(struct super_block *sb, int *flags, char *data)
196 return parse_options(sb, data); 196 return parse_options(sb, data);
197} 197}
198 198
199static int adfs_statfs(struct super_block *sb, struct kstatfs *buf) 199static int adfs_statfs(struct dentry *dentry, struct kstatfs *buf)
200{ 200{
201 struct adfs_sb_info *asb = ADFS_SB(sb); 201 struct adfs_sb_info *asb = ADFS_SB(dentry->d_sb);
202 202
203 buf->f_type = ADFS_SUPER_MAGIC; 203 buf->f_type = ADFS_SUPER_MAGIC;
204 buf->f_namelen = asb->s_namelen; 204 buf->f_namelen = asb->s_namelen;
205 buf->f_bsize = sb->s_blocksize; 205 buf->f_bsize = dentry->d_sb->s_blocksize;
206 buf->f_blocks = asb->s_size; 206 buf->f_blocks = asb->s_size;
207 buf->f_files = asb->s_ids_per_zone * asb->s_map_size; 207 buf->f_files = asb->s_ids_per_zone * asb->s_map_size;
208 buf->f_bavail = 208 buf->f_bavail =
209 buf->f_bfree = adfs_map_free(sb); 209 buf->f_bfree = adfs_map_free(dentry->d_sb);
210 buf->f_ffree = (long)(buf->f_bfree * buf->f_files) / (long)buf->f_blocks; 210 buf->f_ffree = (long)(buf->f_bfree * buf->f_files) / (long)buf->f_blocks;
211 211
212 return 0; 212 return 0;
@@ -470,10 +470,11 @@ error:
470 return -EINVAL; 470 return -EINVAL;
471} 471}
472 472
473static struct super_block *adfs_get_sb(struct file_system_type *fs_type, 473static int adfs_get_sb(struct file_system_type *fs_type,
474 int flags, const char *dev_name, void *data) 474 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
475{ 475{
476 return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super); 476 return get_sb_bdev(fs_type, flags, dev_name, data, adfs_fill_super,
477 mnt);
477} 478}
478 479
479static struct file_system_type adfs_fs_type = { 480static struct file_system_type adfs_fs_type = {
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 4d7e5b19e5cd..8765cba35bb9 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -18,7 +18,7 @@
18 18
19extern struct timezone sys_tz; 19extern struct timezone sys_tz;
20 20
21static int affs_statfs(struct super_block *sb, struct kstatfs *buf); 21static int affs_statfs(struct dentry *dentry, struct kstatfs *buf);
22static int affs_remount (struct super_block *sb, int *flags, char *data); 22static int affs_remount (struct super_block *sb, int *flags, char *data);
23 23
24static void 24static void
@@ -508,8 +508,9 @@ affs_remount(struct super_block *sb, int *flags, char *data)
508} 508}
509 509
510static int 510static int
511affs_statfs(struct super_block *sb, struct kstatfs *buf) 511affs_statfs(struct dentry *dentry, struct kstatfs *buf)
512{ 512{
513 struct super_block *sb = dentry->d_sb;
513 int free; 514 int free;
514 515
515 pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",AFFS_SB(sb)->s_partition_size, 516 pr_debug("AFFS: statfs() partsize=%d, reserved=%d\n",AFFS_SB(sb)->s_partition_size,
@@ -524,10 +525,11 @@ affs_statfs(struct super_block *sb, struct kstatfs *buf)
524 return 0; 525 return 0;
525} 526}
526 527
527static struct super_block *affs_get_sb(struct file_system_type *fs_type, 528static int affs_get_sb(struct file_system_type *fs_type,
528 int flags, const char *dev_name, void *data) 529 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
529{ 530{
530 return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super); 531 return get_sb_bdev(fs_type, flags, dev_name, data, affs_fill_super,
532 mnt);
531} 533}
532 534
533static struct file_system_type affs_fs_type = { 535static struct file_system_type affs_fs_type = {
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index a6dff6a4f204..2fc99877cb0d 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -185,9 +185,7 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index)
185 185
186 _enter("{%lu},%lu", dir->i_ino, index); 186 _enter("{%lu},%lu", dir->i_ino, index);
187 187
188 page = read_cache_page(dir->i_mapping,index, 188 page = read_mapping_page(dir->i_mapping, index, NULL);
189 (filler_t *) dir->i_mapping->a_ops->readpage,
190 NULL);
191 if (!IS_ERR(page)) { 189 if (!IS_ERR(page)) {
192 wait_on_page_locked(page); 190 wait_on_page_locked(page);
193 kmap(page); 191 kmap(page);
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 7b6dc03caf44..99785a79d043 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -63,7 +63,6 @@ unsigned long afs_mntpt_expiry_timeout = 20;
63int afs_mntpt_check_symlink(struct afs_vnode *vnode) 63int afs_mntpt_check_symlink(struct afs_vnode *vnode)
64{ 64{
65 struct page *page; 65 struct page *page;
66 filler_t *filler;
67 size_t size; 66 size_t size;
68 char *buf; 67 char *buf;
69 int ret; 68 int ret;
@@ -71,10 +70,7 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode)
71 _enter("{%u,%u}", vnode->fid.vnode, vnode->fid.unique); 70 _enter("{%u,%u}", vnode->fid.vnode, vnode->fid.unique);
72 71
73 /* read the contents of the symlink into the pagecache */ 72 /* read the contents of the symlink into the pagecache */
74 filler = (filler_t *) AFS_VNODE_TO_I(vnode)->i_mapping->a_ops->readpage; 73 page = read_mapping_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0, NULL);
75
76 page = read_cache_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0,
77 filler, NULL);
78 if (IS_ERR(page)) { 74 if (IS_ERR(page)) {
79 ret = PTR_ERR(page); 75 ret = PTR_ERR(page);
80 goto out; 76 goto out;
@@ -160,7 +156,6 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
160 struct page *page = NULL; 156 struct page *page = NULL;
161 size_t size; 157 size_t size;
162 char *buf, *devname = NULL, *options = NULL; 158 char *buf, *devname = NULL, *options = NULL;
163 filler_t *filler;
164 int ret; 159 int ret;
165 160
166 kenter("{%s}", mntpt->d_name.name); 161 kenter("{%s}", mntpt->d_name.name);
@@ -182,9 +177,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
182 goto error; 177 goto error;
183 178
184 /* read the contents of the AFS special symlink */ 179 /* read the contents of the AFS special symlink */
185 filler = (filler_t *)mntpt->d_inode->i_mapping->a_ops->readpage; 180 page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL);
186
187 page = read_cache_page(mntpt->d_inode->i_mapping, 0, filler, NULL);
188 if (IS_ERR(page)) { 181 if (IS_ERR(page)) {
189 ret = PTR_ERR(page); 182 ret = PTR_ERR(page);
190 goto error; 183 goto error;
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 93a7821db0d7..67d1f5c819ec 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -38,9 +38,9 @@ struct afs_mount_params {
38static void afs_i_init_once(void *foo, kmem_cache_t *cachep, 38static void afs_i_init_once(void *foo, kmem_cache_t *cachep,
39 unsigned long flags); 39 unsigned long flags);
40 40
41static struct super_block *afs_get_sb(struct file_system_type *fs_type, 41static int afs_get_sb(struct file_system_type *fs_type,
42 int flags, const char *dev_name, 42 int flags, const char *dev_name,
43 void *data); 43 void *data, struct vfsmount *mnt);
44 44
45static struct inode *afs_alloc_inode(struct super_block *sb); 45static struct inode *afs_alloc_inode(struct super_block *sb);
46 46
@@ -294,10 +294,11 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent)
294 * get an AFS superblock 294 * get an AFS superblock
295 * - TODO: don't use get_sb_nodev(), but rather call sget() directly 295 * - TODO: don't use get_sb_nodev(), but rather call sget() directly
296 */ 296 */
297static struct super_block *afs_get_sb(struct file_system_type *fs_type, 297static int afs_get_sb(struct file_system_type *fs_type,
298 int flags, 298 int flags,
299 const char *dev_name, 299 const char *dev_name,
300 void *options) 300 void *options,
301 struct vfsmount *mnt)
301{ 302{
302 struct afs_mount_params params; 303 struct afs_mount_params params;
303 struct super_block *sb; 304 struct super_block *sb;
@@ -311,7 +312,7 @@ static struct super_block *afs_get_sb(struct file_system_type *fs_type,
311 ret = afscm_start(); 312 ret = afscm_start();
312 if (ret < 0) { 313 if (ret < 0) {
313 _leave(" = %d", ret); 314 _leave(" = %d", ret);
314 return ERR_PTR(ret); 315 return ret;
315 } 316 }
316 317
317 /* parse the options */ 318 /* parse the options */
@@ -348,18 +349,19 @@ static struct super_block *afs_get_sb(struct file_system_type *fs_type,
348 goto error; 349 goto error;
349 } 350 }
350 sb->s_flags |= MS_ACTIVE; 351 sb->s_flags |= MS_ACTIVE;
352 simple_set_mnt(mnt, sb);
351 353
352 afs_put_volume(params.volume); 354 afs_put_volume(params.volume);
353 afs_put_cell(params.default_cell); 355 afs_put_cell(params.default_cell);
354 _leave(" = %p", sb); 356 _leave(" = 0 [%p]", 0, sb);
355 return sb; 357 return 0;
356 358
357 error: 359 error:
358 afs_put_volume(params.volume); 360 afs_put_volume(params.volume);
359 afs_put_cell(params.default_cell); 361 afs_put_cell(params.default_cell);
360 afscm_stop(); 362 afscm_stop();
361 _leave(" = %d", ret); 363 _leave(" = %d", ret);
362 return ERR_PTR(ret); 364 return ret;
363} /* end afs_get_sb() */ 365} /* end afs_get_sb() */
364 366
365/*****************************************************************************/ 367/*****************************************************************************/
diff --git a/fs/aio.c b/fs/aio.c
index e41e932ba489..8c34a62df7d7 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -777,11 +777,11 @@ out:
777static int __aio_run_iocbs(struct kioctx *ctx) 777static int __aio_run_iocbs(struct kioctx *ctx)
778{ 778{
779 struct kiocb *iocb; 779 struct kiocb *iocb;
780 LIST_HEAD(run_list); 780 struct list_head run_list;
781 781
782 assert_spin_locked(&ctx->ctx_lock); 782 assert_spin_locked(&ctx->ctx_lock);
783 783
784 list_splice_init(&ctx->run_list, &run_list); 784 list_replace_init(&ctx->run_list, &run_list);
785 while (!list_empty(&run_list)) { 785 while (!list_empty(&run_list)) {
786 iocb = list_entry(run_list.next, struct kiocb, 786 iocb = list_entry(run_list.next, struct kiocb,
787 ki_run_list); 787 ki_run_list);
diff --git a/fs/autofs/init.c b/fs/autofs/init.c
index b977ece69f0c..aca123752406 100644
--- a/fs/autofs/init.c
+++ b/fs/autofs/init.c
@@ -14,10 +14,10 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include "autofs_i.h" 15#include "autofs_i.h"
16 16
17static struct super_block *autofs_get_sb(struct file_system_type *fs_type, 17static int autofs_get_sb(struct file_system_type *fs_type,
18 int flags, const char *dev_name, void *data) 18 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
19{ 19{
20 return get_sb_nodev(fs_type, flags, data, autofs_fill_super); 20 return get_sb_nodev(fs_type, flags, data, autofs_fill_super, mnt);
21} 21}
22 22
23static struct file_system_type autofs_fs_type = { 23static struct file_system_type autofs_fs_type = {
diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c
index acecec8578ce..5d9193332bef 100644
--- a/fs/autofs4/init.c
+++ b/fs/autofs4/init.c
@@ -14,10 +14,10 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include "autofs_i.h" 15#include "autofs_i.h"
16 16
17static struct super_block *autofs_get_sb(struct file_system_type *fs_type, 17static int autofs_get_sb(struct file_system_type *fs_type,
18 int flags, const char *dev_name, void *data) 18 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
19{ 19{
20 return get_sb_nodev(fs_type, flags, data, autofs4_fill_super); 20 return get_sb_nodev(fs_type, flags, data, autofs4_fill_super, mnt);
21} 21}
22 22
23static struct file_system_type autofs_fs_type = { 23static struct file_system_type autofs_fs_type = {
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 68ebd10f345d..08201fab26cd 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -49,7 +49,7 @@ static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
49 char **out, int *out_len); 49 char **out, int *out_len);
50static void befs_put_super(struct super_block *); 50static void befs_put_super(struct super_block *);
51static int befs_remount(struct super_block *, int *, char *); 51static int befs_remount(struct super_block *, int *, char *);
52static int befs_statfs(struct super_block *, struct kstatfs *); 52static int befs_statfs(struct dentry *, struct kstatfs *);
53static int parse_options(char *, befs_mount_options *); 53static int parse_options(char *, befs_mount_options *);
54 54
55static const struct super_operations befs_sops = { 55static const struct super_operations befs_sops = {
@@ -880,8 +880,9 @@ befs_remount(struct super_block *sb, int *flags, char *data)
880} 880}
881 881
882static int 882static int
883befs_statfs(struct super_block *sb, struct kstatfs *buf) 883befs_statfs(struct dentry *dentry, struct kstatfs *buf)
884{ 884{
885 struct super_block *sb = dentry->d_sb;
885 886
886 befs_debug(sb, "---> befs_statfs()"); 887 befs_debug(sb, "---> befs_statfs()");
887 888
@@ -899,11 +900,12 @@ befs_statfs(struct super_block *sb, struct kstatfs *buf)
899 return 0; 900 return 0;
900} 901}
901 902
902static struct super_block * 903static int
903befs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, 904befs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name,
904 void *data) 905 void *data, struct vfsmount *mnt)
905{ 906{
906 return get_sb_bdev(fs_type, flags, dev_name, data, befs_fill_super); 907 return get_sb_bdev(fs_type, flags, dev_name, data, befs_fill_super,
908 mnt);
907} 909}
908 910
909static struct file_system_type befs_fs_type = { 911static struct file_system_type befs_fs_type = {
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 55a7a78332f8..cf74f3d4d966 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -203,8 +203,9 @@ static void bfs_put_super(struct super_block *s)
203 s->s_fs_info = NULL; 203 s->s_fs_info = NULL;
204} 204}
205 205
206static int bfs_statfs(struct super_block *s, struct kstatfs *buf) 206static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
207{ 207{
208 struct super_block *s = dentry->d_sb;
208 struct bfs_sb_info *info = BFS_SB(s); 209 struct bfs_sb_info *info = BFS_SB(s);
209 u64 id = huge_encode_dev(s->s_bdev->bd_dev); 210 u64 id = huge_encode_dev(s->s_bdev->bd_dev);
210 buf->f_type = BFS_MAGIC; 211 buf->f_type = BFS_MAGIC;
@@ -410,10 +411,10 @@ out:
410 return -EINVAL; 411 return -EINVAL;
411} 412}
412 413
413static struct super_block *bfs_get_sb(struct file_system_type *fs_type, 414static int bfs_get_sb(struct file_system_type *fs_type,
414 int flags, const char *dev_name, void *data) 415 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
415{ 416{
416 return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super); 417 return get_sb_bdev(fs_type, flags, dev_name, data, bfs_fill_super, mnt);
417} 418}
418 419
419static struct file_system_type bfs_fs_type = { 420static struct file_system_type bfs_fs_type = {
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 537893a16014..d0434406eaeb 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -38,15 +38,13 @@
38#include <linux/security.h> 38#include <linux/security.h>
39#include <linux/syscalls.h> 39#include <linux/syscalls.h>
40#include <linux/random.h> 40#include <linux/random.h>
41 41#include <linux/elf.h>
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43#include <asm/param.h> 43#include <asm/param.h>
44#include <asm/page.h> 44#include <asm/page.h>
45 45
46#include <linux/elf.h> 46static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
47 47static int load_elf_library(struct file *);
48static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
49static int load_elf_library(struct file*);
50static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); 48static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
51extern int dump_fpu (struct pt_regs *, elf_fpregset_t *); 49extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
52 50
@@ -59,15 +57,15 @@ extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
59 * don't even try. 57 * don't even try.
60 */ 58 */
61#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 59#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
62static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file); 60static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file);
63#else 61#else
64#define elf_core_dump NULL 62#define elf_core_dump NULL
65#endif 63#endif
66 64
67#if ELF_EXEC_PAGESIZE > PAGE_SIZE 65#if ELF_EXEC_PAGESIZE > PAGE_SIZE
68# define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE 66#define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
69#else 67#else
70# define ELF_MIN_ALIGN PAGE_SIZE 68#define ELF_MIN_ALIGN PAGE_SIZE
71#endif 69#endif
72 70
73#ifndef ELF_CORE_EFLAGS 71#ifndef ELF_CORE_EFLAGS
@@ -86,7 +84,7 @@ static struct linux_binfmt elf_format = {
86 .min_coredump = ELF_EXEC_PAGESIZE 84 .min_coredump = ELF_EXEC_PAGESIZE
87}; 85};
88 86
89#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) 87#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE)
90 88
91static int set_brk(unsigned long start, unsigned long end) 89static int set_brk(unsigned long start, unsigned long end)
92{ 90{
@@ -104,13 +102,11 @@ static int set_brk(unsigned long start, unsigned long end)
104 return 0; 102 return 0;
105} 103}
106 104
107
108/* We need to explicitly zero any fractional pages 105/* We need to explicitly zero any fractional pages
109 after the data section (i.e. bss). This would 106 after the data section (i.e. bss). This would
110 contain the junk from the file that should not 107 contain the junk from the file that should not
111 be in memory */ 108 be in memory
112 109 */
113
114static int padzero(unsigned long elf_bss) 110static int padzero(unsigned long elf_bss)
115{ 111{
116 unsigned long nbyte; 112 unsigned long nbyte;
@@ -129,7 +125,9 @@ static int padzero(unsigned long elf_bss)
129#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) + (items)) 125#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) + (items))
130#define STACK_ROUND(sp, items) \ 126#define STACK_ROUND(sp, items) \
131 ((15 + (unsigned long) ((sp) + (items))) &~ 15UL) 127 ((15 + (unsigned long) ((sp) + (items))) &~ 15UL)
132#define STACK_ALLOC(sp, len) ({ elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; old_sp; }) 128#define STACK_ALLOC(sp, len) ({ \
129 elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; \
130 old_sp; })
133#else 131#else
134#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items)) 132#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items))
135#define STACK_ROUND(sp, items) \ 133#define STACK_ROUND(sp, items) \
@@ -138,7 +136,7 @@ static int padzero(unsigned long elf_bss)
138#endif 136#endif
139 137
140static int 138static int
141create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, 139create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
142 int interp_aout, unsigned long load_addr, 140 int interp_aout, unsigned long load_addr,
143 unsigned long interp_load_addr) 141 unsigned long interp_load_addr)
144{ 142{
@@ -161,7 +159,6 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
161 * for userspace to get any other way, in others (i386) it is 159 * for userspace to get any other way, in others (i386) it is
162 * merely difficult. 160 * merely difficult.
163 */ 161 */
164
165 u_platform = NULL; 162 u_platform = NULL;
166 if (k_platform) { 163 if (k_platform) {
167 size_t len = strlen(k_platform) + 1; 164 size_t len = strlen(k_platform) + 1;
@@ -171,7 +168,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
171 * evictions by the processes running on the same package. One 168 * evictions by the processes running on the same package. One
172 * thing we can do is to shuffle the initial stack for them. 169 * thing we can do is to shuffle the initial stack for them.
173 */ 170 */
174 171
175 p = arch_align_stack(p); 172 p = arch_align_stack(p);
176 173
177 u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); 174 u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len);
@@ -180,9 +177,12 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
180 } 177 }
181 178
182 /* Create the ELF interpreter info */ 179 /* Create the ELF interpreter info */
183 elf_info = (elf_addr_t *) current->mm->saved_auxv; 180 elf_info = (elf_addr_t *)current->mm->saved_auxv;
184#define NEW_AUX_ENT(id, val) \ 181#define NEW_AUX_ENT(id, val) \
185 do { elf_info[ei_index++] = id; elf_info[ei_index++] = val; } while (0) 182 do { \
183 elf_info[ei_index++] = id; \
184 elf_info[ei_index++] = val; \
185 } while (0)
186 186
187#ifdef ARCH_DLINFO 187#ifdef ARCH_DLINFO
188 /* 188 /*
@@ -195,21 +195,22 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
195 NEW_AUX_ENT(AT_PAGESZ, ELF_EXEC_PAGESIZE); 195 NEW_AUX_ENT(AT_PAGESZ, ELF_EXEC_PAGESIZE);
196 NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC); 196 NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC);
197 NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff); 197 NEW_AUX_ENT(AT_PHDR, load_addr + exec->e_phoff);
198 NEW_AUX_ENT(AT_PHENT, sizeof (struct elf_phdr)); 198 NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
199 NEW_AUX_ENT(AT_PHNUM, exec->e_phnum); 199 NEW_AUX_ENT(AT_PHNUM, exec->e_phnum);
200 NEW_AUX_ENT(AT_BASE, interp_load_addr); 200 NEW_AUX_ENT(AT_BASE, interp_load_addr);
201 NEW_AUX_ENT(AT_FLAGS, 0); 201 NEW_AUX_ENT(AT_FLAGS, 0);
202 NEW_AUX_ENT(AT_ENTRY, exec->e_entry); 202 NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
203 NEW_AUX_ENT(AT_UID, (elf_addr_t) tsk->uid); 203 NEW_AUX_ENT(AT_UID, tsk->uid);
204 NEW_AUX_ENT(AT_EUID, (elf_addr_t) tsk->euid); 204 NEW_AUX_ENT(AT_EUID, tsk->euid);
205 NEW_AUX_ENT(AT_GID, (elf_addr_t) tsk->gid); 205 NEW_AUX_ENT(AT_GID, tsk->gid);
206 NEW_AUX_ENT(AT_EGID, (elf_addr_t) tsk->egid); 206 NEW_AUX_ENT(AT_EGID, tsk->egid);
207 NEW_AUX_ENT(AT_SECURE, (elf_addr_t) security_bprm_secureexec(bprm)); 207 NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
208 if (k_platform) { 208 if (k_platform) {
209 NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(unsigned long)u_platform); 209 NEW_AUX_ENT(AT_PLATFORM,
210 (elf_addr_t)(unsigned long)u_platform);
210 } 211 }
211 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) { 212 if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
212 NEW_AUX_ENT(AT_EXECFD, (elf_addr_t) bprm->interp_data); 213 NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
213 } 214 }
214#undef NEW_AUX_ENT 215#undef NEW_AUX_ENT
215 /* AT_NULL is zero; clear the rest too */ 216 /* AT_NULL is zero; clear the rest too */
@@ -232,7 +233,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
232 /* Point sp at the lowest address on the stack */ 233 /* Point sp at the lowest address on the stack */
233#ifdef CONFIG_STACK_GROWSUP 234#ifdef CONFIG_STACK_GROWSUP
234 sp = (elf_addr_t __user *)bprm->p - items - ei_index; 235 sp = (elf_addr_t __user *)bprm->p - items - ei_index;
235 bprm->exec = (unsigned long) sp; /* XXX: PARISC HACK */ 236 bprm->exec = (unsigned long)sp; /* XXX: PARISC HACK */
236#else 237#else
237 sp = (elf_addr_t __user *)bprm->p; 238 sp = (elf_addr_t __user *)bprm->p;
238#endif 239#endif
@@ -285,7 +286,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec,
285#ifndef elf_map 286#ifndef elf_map
286 287
287static unsigned long elf_map(struct file *filep, unsigned long addr, 288static unsigned long elf_map(struct file *filep, unsigned long addr,
288 struct elf_phdr *eppnt, int prot, int type) 289 struct elf_phdr *eppnt, int prot, int type)
289{ 290{
290 unsigned long map_addr; 291 unsigned long map_addr;
291 unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr); 292 unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr);
@@ -310,9 +311,8 @@ static unsigned long elf_map(struct file *filep, unsigned long addr,
310 is only provided so that we can read a.out libraries that have 311 is only provided so that we can read a.out libraries that have
311 an ELF header */ 312 an ELF header */
312 313
313static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, 314static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
314 struct file * interpreter, 315 struct file *interpreter, unsigned long *interp_load_addr)
315 unsigned long *interp_load_addr)
316{ 316{
317 struct elf_phdr *elf_phdata; 317 struct elf_phdr *elf_phdata;
318 struct elf_phdr *eppnt; 318 struct elf_phdr *eppnt;
@@ -342,15 +342,15 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
342 goto out; 342 goto out;
343 343
344 /* Now read in all of the header information */ 344 /* Now read in all of the header information */
345
346 size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum; 345 size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum;
347 if (size > ELF_MIN_ALIGN) 346 if (size > ELF_MIN_ALIGN)
348 goto out; 347 goto out;
349 elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL); 348 elf_phdata = kmalloc(size, GFP_KERNEL);
350 if (!elf_phdata) 349 if (!elf_phdata)
351 goto out; 350 goto out;
352 351
353 retval = kernel_read(interpreter,interp_elf_ex->e_phoff,(char *)elf_phdata,size); 352 retval = kernel_read(interpreter, interp_elf_ex->e_phoff,
353 (char *)elf_phdata,size);
354 error = -EIO; 354 error = -EIO;
355 if (retval != size) { 355 if (retval != size) {
356 if (retval < 0) 356 if (retval < 0)
@@ -359,58 +359,65 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
359 } 359 }
360 360
361 eppnt = elf_phdata; 361 eppnt = elf_phdata;
362 for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) { 362 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
363 if (eppnt->p_type == PT_LOAD) { 363 if (eppnt->p_type == PT_LOAD) {
364 int elf_type = MAP_PRIVATE | MAP_DENYWRITE; 364 int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
365 int elf_prot = 0; 365 int elf_prot = 0;
366 unsigned long vaddr = 0; 366 unsigned long vaddr = 0;
367 unsigned long k, map_addr; 367 unsigned long k, map_addr;
368 368
369 if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; 369 if (eppnt->p_flags & PF_R)
370 if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; 370 elf_prot = PROT_READ;
371 if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; 371 if (eppnt->p_flags & PF_W)
372 vaddr = eppnt->p_vaddr; 372 elf_prot |= PROT_WRITE;
373 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) 373 if (eppnt->p_flags & PF_X)
374 elf_type |= MAP_FIXED; 374 elf_prot |= PROT_EXEC;
375 375 vaddr = eppnt->p_vaddr;
376 map_addr = elf_map(interpreter, load_addr + vaddr, eppnt, elf_prot, elf_type); 376 if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
377 error = map_addr; 377 elf_type |= MAP_FIXED;
378 if (BAD_ADDR(map_addr)) 378
379 goto out_close; 379 map_addr = elf_map(interpreter, load_addr + vaddr,
380 380 eppnt, elf_prot, elf_type);
381 if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { 381 error = map_addr;
382 load_addr = map_addr - ELF_PAGESTART(vaddr); 382 if (BAD_ADDR(map_addr))
383 load_addr_set = 1; 383 goto out_close;
384 } 384
385 385 if (!load_addr_set &&
386 /* 386 interp_elf_ex->e_type == ET_DYN) {
387 * Check to see if the section's size will overflow the 387 load_addr = map_addr - ELF_PAGESTART(vaddr);
388 * allowed task size. Note that p_filesz must always be 388 load_addr_set = 1;
389 * <= p_memsize so it is only necessary to check p_memsz. 389 }
390 */ 390
391 k = load_addr + eppnt->p_vaddr; 391 /*
392 if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz || 392 * Check to see if the section's size will overflow the
393 eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) { 393 * allowed task size. Note that p_filesz must always be
394 error = -ENOMEM; 394 * <= p_memsize so it's only necessary to check p_memsz.
395 goto out_close; 395 */
396 } 396 k = load_addr + eppnt->p_vaddr;
397 397 if (k > TASK_SIZE ||
398 /* 398 eppnt->p_filesz > eppnt->p_memsz ||
399 * Find the end of the file mapping for this phdr, and keep 399 eppnt->p_memsz > TASK_SIZE ||
400 * track of the largest address we see for this. 400 TASK_SIZE - eppnt->p_memsz < k) {
401 */ 401 error = -ENOMEM;
402 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; 402 goto out_close;
403 if (k > elf_bss) 403 }
404 elf_bss = k; 404
405 405 /*
406 /* 406 * Find the end of the file mapping for this phdr, and
407 * Do the same thing for the memory mapping - between 407 * keep track of the largest address we see for this.
408 * elf_bss and last_bss is the bss section. 408 */
409 */ 409 k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
410 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; 410 if (k > elf_bss)
411 if (k > last_bss) 411 elf_bss = k;
412 last_bss = k; 412
413 } 413 /*
414 * Do the same thing for the memory mapping - between
415 * elf_bss and last_bss is the bss section.
416 */
417 k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
418 if (k > last_bss)
419 last_bss = k;
420 }
414 } 421 }
415 422
416 /* 423 /*
@@ -424,7 +431,8 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
424 goto out_close; 431 goto out_close;
425 } 432 }
426 433
427 elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* What we have mapped so far */ 434 /* What we have mapped so far */
435 elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);
428 436
429 /* Map the last of the bss segment */ 437 /* Map the last of the bss segment */
430 if (last_bss > elf_bss) { 438 if (last_bss > elf_bss) {
@@ -436,7 +444,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
436 } 444 }
437 445
438 *interp_load_addr = load_addr; 446 *interp_load_addr = load_addr;
439 error = ((unsigned long) interp_elf_ex->e_entry) + load_addr; 447 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
440 448
441out_close: 449out_close:
442 kfree(elf_phdata); 450 kfree(elf_phdata);
@@ -444,8 +452,8 @@ out:
444 return error; 452 return error;
445} 453}
446 454
447static unsigned long load_aout_interp(struct exec * interp_ex, 455static unsigned long load_aout_interp(struct exec *interp_ex,
448 struct file * interpreter) 456 struct file *interpreter)
449{ 457{
450 unsigned long text_data, elf_entry = ~0UL; 458 unsigned long text_data, elf_entry = ~0UL;
451 char __user * addr; 459 char __user * addr;
@@ -464,7 +472,7 @@ static unsigned long load_aout_interp(struct exec * interp_ex,
464 case ZMAGIC: 472 case ZMAGIC:
465 case QMAGIC: 473 case QMAGIC:
466 offset = N_TXTOFF(*interp_ex); 474 offset = N_TXTOFF(*interp_ex);
467 addr = (char __user *) N_TXTADDR(*interp_ex); 475 addr = (char __user *)N_TXTADDR(*interp_ex);
468 break; 476 break;
469 default: 477 default:
470 goto out; 478 goto out;
@@ -480,7 +488,6 @@ static unsigned long load_aout_interp(struct exec * interp_ex,
480 flush_icache_range((unsigned long)addr, 488 flush_icache_range((unsigned long)addr,
481 (unsigned long)addr + text_data); 489 (unsigned long)addr + text_data);
482 490
483
484 down_write(&current->mm->mmap_sem); 491 down_write(&current->mm->mmap_sem);
485 do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), 492 do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
486 interp_ex->a_bss); 493 interp_ex->a_bss);
@@ -519,7 +526,7 @@ static unsigned long randomize_stack_top(unsigned long stack_top)
519#endif 526#endif
520} 527}
521 528
522static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) 529static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
523{ 530{
524 struct file *interpreter = NULL; /* to shut gcc up */ 531 struct file *interpreter = NULL; /* to shut gcc up */
525 unsigned long load_addr = 0, load_bias = 0; 532 unsigned long load_addr = 0, load_bias = 0;
@@ -528,7 +535,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
528 unsigned int interpreter_type = INTERPRETER_NONE; 535 unsigned int interpreter_type = INTERPRETER_NONE;
529 unsigned char ibcs2_interpreter = 0; 536 unsigned char ibcs2_interpreter = 0;
530 unsigned long error; 537 unsigned long error;
531 struct elf_phdr * elf_ppnt, *elf_phdata; 538 struct elf_phdr *elf_ppnt, *elf_phdata;
532 unsigned long elf_bss, elf_brk; 539 unsigned long elf_bss, elf_brk;
533 int elf_exec_fileno; 540 int elf_exec_fileno;
534 int retval, i; 541 int retval, i;
@@ -553,7 +560,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
553 } 560 }
554 561
555 /* Get the exec-header */ 562 /* Get the exec-header */
556 loc->elf_ex = *((struct elfhdr *) bprm->buf); 563 loc->elf_ex = *((struct elfhdr *)bprm->buf);
557 564
558 retval = -ENOEXEC; 565 retval = -ENOEXEC;
559 /* First of all, some simple consistency checks */ 566 /* First of all, some simple consistency checks */
@@ -568,7 +575,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
568 goto out; 575 goto out;
569 576
570 /* Now read in all of the header information */ 577 /* Now read in all of the header information */
571
572 if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr)) 578 if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr))
573 goto out; 579 goto out;
574 if (loc->elf_ex.e_phnum < 1 || 580 if (loc->elf_ex.e_phnum < 1 ||
@@ -576,18 +582,19 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
576 goto out; 582 goto out;
577 size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr); 583 size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr);
578 retval = -ENOMEM; 584 retval = -ENOMEM;
579 elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL); 585 elf_phdata = kmalloc(size, GFP_KERNEL);
580 if (!elf_phdata) 586 if (!elf_phdata)
581 goto out; 587 goto out;
582 588
583 retval = kernel_read(bprm->file, loc->elf_ex.e_phoff, (char *) elf_phdata, size); 589 retval = kernel_read(bprm->file, loc->elf_ex.e_phoff,
590 (char *)elf_phdata, size);
584 if (retval != size) { 591 if (retval != size) {
585 if (retval >= 0) 592 if (retval >= 0)
586 retval = -EIO; 593 retval = -EIO;
587 goto out_free_ph; 594 goto out_free_ph;
588 } 595 }
589 596
590 files = current->files; /* Refcounted so ok */ 597 files = current->files; /* Refcounted so ok */
591 retval = unshare_files(); 598 retval = unshare_files();
592 if (retval < 0) 599 if (retval < 0)
593 goto out_free_ph; 600 goto out_free_ph;
@@ -598,7 +605,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
598 605
599 /* exec will make our files private anyway, but for the a.out 606 /* exec will make our files private anyway, but for the a.out
600 loader stuff we need to do it earlier */ 607 loader stuff we need to do it earlier */
601
602 retval = get_unused_fd(); 608 retval = get_unused_fd();
603 if (retval < 0) 609 if (retval < 0)
604 goto out_free_fh; 610 goto out_free_fh;
@@ -620,7 +626,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
620 * shared libraries - for now assume that this 626 * shared libraries - for now assume that this
621 * is an a.out format binary 627 * is an a.out format binary
622 */ 628 */
623
624 retval = -ENOEXEC; 629 retval = -ENOEXEC;
625 if (elf_ppnt->p_filesz > PATH_MAX || 630 if (elf_ppnt->p_filesz > PATH_MAX ||
626 elf_ppnt->p_filesz < 2) 631 elf_ppnt->p_filesz < 2)
@@ -628,13 +633,13 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
628 633
629 retval = -ENOMEM; 634 retval = -ENOMEM;
630 elf_interpreter = kmalloc(elf_ppnt->p_filesz, 635 elf_interpreter = kmalloc(elf_ppnt->p_filesz,
631 GFP_KERNEL); 636 GFP_KERNEL);
632 if (!elf_interpreter) 637 if (!elf_interpreter)
633 goto out_free_file; 638 goto out_free_file;
634 639
635 retval = kernel_read(bprm->file, elf_ppnt->p_offset, 640 retval = kernel_read(bprm->file, elf_ppnt->p_offset,
636 elf_interpreter, 641 elf_interpreter,
637 elf_ppnt->p_filesz); 642 elf_ppnt->p_filesz);
638 if (retval != elf_ppnt->p_filesz) { 643 if (retval != elf_ppnt->p_filesz) {
639 if (retval >= 0) 644 if (retval >= 0)
640 retval = -EIO; 645 retval = -EIO;
@@ -678,7 +683,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
678 retval = PTR_ERR(interpreter); 683 retval = PTR_ERR(interpreter);
679 if (IS_ERR(interpreter)) 684 if (IS_ERR(interpreter))
680 goto out_free_interp; 685 goto out_free_interp;
681 retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); 686 retval = kernel_read(interpreter, 0, bprm->buf,
687 BINPRM_BUF_SIZE);
682 if (retval != BINPRM_BUF_SIZE) { 688 if (retval != BINPRM_BUF_SIZE) {
683 if (retval >= 0) 689 if (retval >= 0)
684 retval = -EIO; 690 retval = -EIO;
@@ -686,8 +692,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
686 } 692 }
687 693
688 /* Get the exec headers */ 694 /* Get the exec headers */
689 loc->interp_ex = *((struct exec *) bprm->buf); 695 loc->interp_ex = *((struct exec *)bprm->buf);
690 loc->interp_elf_ex = *((struct elfhdr *) bprm->buf); 696 loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
691 break; 697 break;
692 } 698 }
693 elf_ppnt++; 699 elf_ppnt++;
@@ -739,7 +745,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
739 745
740 /* OK, we are done with that, now set up the arg stuff, 746 /* OK, we are done with that, now set up the arg stuff,
741 and then start this sucker up */ 747 and then start this sucker up */
742
743 if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) { 748 if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) {
744 char *passed_p = passed_fileno; 749 char *passed_p = passed_fileno;
745 sprintf(passed_fileno, "%d", elf_exec_fileno); 750 sprintf(passed_fileno, "%d", elf_exec_fileno);
@@ -759,7 +764,6 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
759 764
760 /* Discard our unneeded old files struct */ 765 /* Discard our unneeded old files struct */
761 if (files) { 766 if (files) {
762 steal_locks(files);
763 put_files_struct(files); 767 put_files_struct(files);
764 files = NULL; 768 files = NULL;
765 } 769 }
@@ -778,7 +782,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
778 if (elf_read_implies_exec(loc->elf_ex, executable_stack)) 782 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
779 current->personality |= READ_IMPLIES_EXEC; 783 current->personality |= READ_IMPLIES_EXEC;
780 784
781 if ( !(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 785 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
782 current->flags |= PF_RANDOMIZE; 786 current->flags |= PF_RANDOMIZE;
783 arch_pick_mmap_layout(current->mm); 787 arch_pick_mmap_layout(current->mm);
784 788
@@ -799,8 +803,8 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
799 the correct location in memory. At this point, we assume that 803 the correct location in memory. At this point, we assume that
800 the image should be loaded at fixed address, not at a variable 804 the image should be loaded at fixed address, not at a variable
801 address. */ 805 address. */
802 806 for(i = 0, elf_ppnt = elf_phdata;
803 for(i = 0, elf_ppnt = elf_phdata; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { 807 i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
804 int elf_prot = 0, elf_flags; 808 int elf_prot = 0, elf_flags;
805 unsigned long k, vaddr; 809 unsigned long k, vaddr;
806 810
@@ -828,30 +832,35 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
828 load_bias, nbyte)) { 832 load_bias, nbyte)) {
829 /* 833 /*
830 * This bss-zeroing can fail if the ELF 834 * This bss-zeroing can fail if the ELF
831 * file specifies odd protections. So 835 * file specifies odd protections. So
832 * we don't check the return value 836 * we don't check the return value
833 */ 837 */
834 } 838 }
835 } 839 }
836 } 840 }
837 841
838 if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ; 842 if (elf_ppnt->p_flags & PF_R)
839 if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; 843 elf_prot |= PROT_READ;
840 if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; 844 if (elf_ppnt->p_flags & PF_W)
845 elf_prot |= PROT_WRITE;
846 if (elf_ppnt->p_flags & PF_X)
847 elf_prot |= PROT_EXEC;
841 848
842 elf_flags = MAP_PRIVATE|MAP_DENYWRITE|MAP_EXECUTABLE; 849 elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE;
843 850
844 vaddr = elf_ppnt->p_vaddr; 851 vaddr = elf_ppnt->p_vaddr;
845 if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) { 852 if (loc->elf_ex.e_type == ET_EXEC || load_addr_set) {
846 elf_flags |= MAP_FIXED; 853 elf_flags |= MAP_FIXED;
847 } else if (loc->elf_ex.e_type == ET_DYN) { 854 } else if (loc->elf_ex.e_type == ET_DYN) {
848 /* Try and get dynamic programs out of the way of the default mmap 855 /* Try and get dynamic programs out of the way of the
849 base, as well as whatever program they might try to exec. This 856 * default mmap base, as well as whatever program they
850 is because the brk will follow the loader, and is not movable. */ 857 * might try to exec. This is because the brk will
858 * follow the loader, and is not movable. */
851 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); 859 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
852 } 860 }
853 861
854 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); 862 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
863 elf_prot, elf_flags);
855 if (BAD_ADDR(error)) { 864 if (BAD_ADDR(error)) {
856 send_sig(SIGKILL, current, 0); 865 send_sig(SIGKILL, current, 0);
857 goto out_free_dentry; 866 goto out_free_dentry;
@@ -868,8 +877,10 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
868 } 877 }
869 } 878 }
870 k = elf_ppnt->p_vaddr; 879 k = elf_ppnt->p_vaddr;
871 if (k < start_code) start_code = k; 880 if (k < start_code)
872 if (start_data < k) start_data = k; 881 start_code = k;
882 if (start_data < k)
883 start_data = k;
873 884
874 /* 885 /*
875 * Check to see if the section's size will overflow the 886 * Check to see if the section's size will overflow the
@@ -879,7 +890,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
879 if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || 890 if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
880 elf_ppnt->p_memsz > TASK_SIZE || 891 elf_ppnt->p_memsz > TASK_SIZE ||
881 TASK_SIZE - elf_ppnt->p_memsz < k) { 892 TASK_SIZE - elf_ppnt->p_memsz < k) {
882 /* set_brk can never work. Avoid overflows. */ 893 /* set_brk can never work. Avoid overflows. */
883 send_sig(SIGKILL, current, 0); 894 send_sig(SIGKILL, current, 0);
884 goto out_free_dentry; 895 goto out_free_dentry;
885 } 896 }
@@ -967,8 +978,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
967 978
968 compute_creds(bprm); 979 compute_creds(bprm);
969 current->flags &= ~PF_FORKNOEXEC; 980 current->flags &= ~PF_FORKNOEXEC;
970 create_elf_tables(bprm, &loc->elf_ex, (interpreter_type == INTERPRETER_AOUT), 981 create_elf_tables(bprm, &loc->elf_ex,
971 load_addr, interp_load_addr); 982 (interpreter_type == INTERPRETER_AOUT),
983 load_addr, interp_load_addr);
972 /* N.B. passed_fileno might not be initialized? */ 984 /* N.B. passed_fileno might not be initialized? */
973 if (interpreter_type == INTERPRETER_AOUT) 985 if (interpreter_type == INTERPRETER_AOUT)
974 current->mm->arg_start += strlen(passed_fileno) + 1; 986 current->mm->arg_start += strlen(passed_fileno) + 1;
@@ -982,7 +994,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
982 /* Why this, you ask??? Well SVr4 maps page 0 as read-only, 994 /* Why this, you ask??? Well SVr4 maps page 0 as read-only,
983 and some applications "depend" upon this behavior. 995 and some applications "depend" upon this behavior.
984 Since we do not have the power to recompile these, we 996 Since we do not have the power to recompile these, we
985 emulate the SVr4 behavior. Sigh. */ 997 emulate the SVr4 behavior. Sigh. */
986 down_write(&current->mm->mmap_sem); 998 down_write(&current->mm->mmap_sem);
987 error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, 999 error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC,
988 MAP_FIXED | MAP_PRIVATE, 0); 1000 MAP_FIXED | MAP_PRIVATE, 0);
@@ -1037,7 +1049,6 @@ out_free_ph:
1037 1049
1038/* This is really simpleminded and specialized - we are loading an 1050/* This is really simpleminded and specialized - we are loading an
1039 a.out library that is given an ELF header. */ 1051 a.out library that is given an ELF header. */
1040
1041static int load_elf_library(struct file *file) 1052static int load_elf_library(struct file *file)
1042{ 1053{
1043 struct elf_phdr *elf_phdata; 1054 struct elf_phdr *elf_phdata;
@@ -1047,7 +1058,7 @@ static int load_elf_library(struct file *file)
1047 struct elfhdr elf_ex; 1058 struct elfhdr elf_ex;
1048 1059
1049 error = -ENOEXEC; 1060 error = -ENOEXEC;
1050 retval = kernel_read(file, 0, (char *) &elf_ex, sizeof(elf_ex)); 1061 retval = kernel_read(file, 0, (char *)&elf_ex, sizeof(elf_ex));
1051 if (retval != sizeof(elf_ex)) 1062 if (retval != sizeof(elf_ex))
1052 goto out; 1063 goto out;
1053 1064
@@ -1056,7 +1067,7 @@ static int load_elf_library(struct file *file)
1056 1067
1057 /* First of all, some simple consistency checks */ 1068 /* First of all, some simple consistency checks */
1058 if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || 1069 if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
1059 !elf_check_arch(&elf_ex) || !file->f_op || !file->f_op->mmap) 1070 !elf_check_arch(&elf_ex) || !file->f_op || !file->f_op->mmap)
1060 goto out; 1071 goto out;
1061 1072
1062 /* Now read in all of the header information */ 1073 /* Now read in all of the header information */
@@ -1104,7 +1115,8 @@ static int load_elf_library(struct file *file)
1104 goto out_free_ph; 1115 goto out_free_ph;
1105 } 1116 }
1106 1117
1107 len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); 1118 len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
1119 ELF_MIN_ALIGN - 1);
1108 bss = eppnt->p_memsz + eppnt->p_vaddr; 1120 bss = eppnt->p_memsz + eppnt->p_vaddr;
1109 if (bss > len) { 1121 if (bss > len) {
1110 down_write(&current->mm->mmap_sem); 1122 down_write(&current->mm->mmap_sem);
@@ -1163,7 +1175,7 @@ static int maydump(struct vm_area_struct *vma)
1163 if (vma->vm_flags & (VM_IO | VM_RESERVED)) 1175 if (vma->vm_flags & (VM_IO | VM_RESERVED))
1164 return 0; 1176 return 0;
1165 1177
1166 /* Dump shared memory only if mapped from an anonymous file. */ 1178 /* Dump shared memory only if mapped from an anonymous file. */
1167 if (vma->vm_flags & VM_SHARED) 1179 if (vma->vm_flags & VM_SHARED)
1168 return vma->vm_file->f_dentry->d_inode->i_nlink == 0; 1180 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
1169 1181
@@ -1174,7 +1186,7 @@ static int maydump(struct vm_area_struct *vma)
1174 return 1; 1186 return 1;
1175} 1187}
1176 1188
1177#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 1189#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
1178 1190
1179/* An ELF note in memory */ 1191/* An ELF note in memory */
1180struct memelfnote 1192struct memelfnote
@@ -1277,11 +1289,11 @@ static void fill_note(struct memelfnote *note, const char *name, int type,
1277} 1289}
1278 1290
1279/* 1291/*
1280 * fill up all the fields in prstatus from the given task struct, except registers 1292 * fill up all the fields in prstatus from the given task struct, except
1281 * which need to be filled up separately. 1293 * registers which need to be filled up separately.
1282 */ 1294 */
1283static void fill_prstatus(struct elf_prstatus *prstatus, 1295static void fill_prstatus(struct elf_prstatus *prstatus,
1284 struct task_struct *p, long signr) 1296 struct task_struct *p, long signr)
1285{ 1297{
1286 prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; 1298 prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
1287 prstatus->pr_sigpend = p->pending.signal.sig[0]; 1299 prstatus->pr_sigpend = p->pending.signal.sig[0];
@@ -1366,8 +1378,8 @@ struct elf_thread_status
1366 1378
1367/* 1379/*
1368 * In order to add the specific thread information for the elf file format, 1380 * In order to add the specific thread information for the elf file format,
1369 * we need to keep a linked list of every threads pr_status and then 1381 * we need to keep a linked list of every threads pr_status and then create
1370 * create a single section for them in the final core file. 1382 * a single section for them in the final core file.
1371 */ 1383 */
1372static int elf_dump_thread_status(long signr, struct elf_thread_status *t) 1384static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1373{ 1385{
@@ -1378,19 +1390,23 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1378 fill_prstatus(&t->prstatus, p, signr); 1390 fill_prstatus(&t->prstatus, p, signr);
1379 elf_core_copy_task_regs(p, &t->prstatus.pr_reg); 1391 elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
1380 1392
1381 fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus), &(t->prstatus)); 1393 fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
1394 &(t->prstatus));
1382 t->num_notes++; 1395 t->num_notes++;
1383 sz += notesize(&t->notes[0]); 1396 sz += notesize(&t->notes[0]);
1384 1397
1385 if ((t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL, &t->fpu))) { 1398 if ((t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL,
1386 fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu), &(t->fpu)); 1399 &t->fpu))) {
1400 fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu),
1401 &(t->fpu));
1387 t->num_notes++; 1402 t->num_notes++;
1388 sz += notesize(&t->notes[1]); 1403 sz += notesize(&t->notes[1]);
1389 } 1404 }
1390 1405
1391#ifdef ELF_CORE_COPY_XFPREGS 1406#ifdef ELF_CORE_COPY_XFPREGS
1392 if (elf_core_copy_task_xfpregs(p, &t->xfpu)) { 1407 if (elf_core_copy_task_xfpregs(p, &t->xfpu)) {
1393 fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu), &t->xfpu); 1408 fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu),
1409 &t->xfpu);
1394 t->num_notes++; 1410 t->num_notes++;
1395 sz += notesize(&t->notes[2]); 1411 sz += notesize(&t->notes[2]);
1396 } 1412 }
@@ -1405,7 +1421,7 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1405 * and then they are actually written out. If we run out of core limit 1421 * and then they are actually written out. If we run out of core limit
1406 * we just truncate. 1422 * we just truncate.
1407 */ 1423 */
1408static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) 1424static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1409{ 1425{
1410#define NUM_NOTES 6 1426#define NUM_NOTES 6
1411 int has_dumped = 0; 1427 int has_dumped = 0;
@@ -1434,12 +1450,12 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1434 /* 1450 /*
1435 * We no longer stop all VM operations. 1451 * We no longer stop all VM operations.
1436 * 1452 *
1437 * This is because those proceses that could possibly change map_count or 1453 * This is because those proceses that could possibly change map_count
1438 * the mmap / vma pages are now blocked in do_exit on current finishing 1454 * or the mmap / vma pages are now blocked in do_exit on current
1439 * this core dump. 1455 * finishing this core dump.
1440 * 1456 *
1441 * Only ptrace can touch these memory addresses, but it doesn't change 1457 * Only ptrace can touch these memory addresses, but it doesn't change
1442 * the map_count or the pages allocated. So no possibility of crashing 1458 * the map_count or the pages allocated. So no possibility of crashing
1443 * exists while dumping the mm->vm_next areas to the core file. 1459 * exists while dumping the mm->vm_next areas to the core file.
1444 */ 1460 */
1445 1461
@@ -1501,7 +1517,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1501#endif 1517#endif
1502 1518
1503 /* Set up header */ 1519 /* Set up header */
1504 fill_elf_header(elf, segs+1); /* including notes section */ 1520 fill_elf_header(elf, segs + 1); /* including notes section */
1505 1521
1506 has_dumped = 1; 1522 has_dumped = 1;
1507 current->flags |= PF_DUMPCORE; 1523 current->flags |= PF_DUMPCORE;
@@ -1511,24 +1527,24 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1511 * with info from their /proc. 1527 * with info from their /proc.
1512 */ 1528 */
1513 1529
1514 fill_note(notes +0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus); 1530 fill_note(notes + 0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus);
1515
1516 fill_psinfo(psinfo, current->group_leader, current->mm); 1531 fill_psinfo(psinfo, current->group_leader, current->mm);
1517 fill_note(notes +1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo); 1532 fill_note(notes + 1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
1518 1533
1519 numnote = 2; 1534 numnote = 2;
1520 1535
1521 auxv = (elf_addr_t *) current->mm->saved_auxv; 1536 auxv = (elf_addr_t *)current->mm->saved_auxv;
1522 1537
1523 i = 0; 1538 i = 0;
1524 do 1539 do
1525 i += 2; 1540 i += 2;
1526 while (auxv[i - 2] != AT_NULL); 1541 while (auxv[i - 2] != AT_NULL);
1527 fill_note(&notes[numnote++], "CORE", NT_AUXV, 1542 fill_note(&notes[numnote++], "CORE", NT_AUXV,
1528 i * sizeof (elf_addr_t), auxv); 1543 i * sizeof(elf_addr_t), auxv);
1529 1544
1530 /* Try to dump the FPU. */ 1545 /* Try to dump the FPU. */
1531 if ((prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs, fpu))) 1546 if ((prstatus->pr_fpvalid =
1547 elf_core_copy_task_fpregs(current, regs, fpu)))
1532 fill_note(notes + numnote++, 1548 fill_note(notes + numnote++,
1533 "CORE", NT_PRFPREG, sizeof(*fpu), fpu); 1549 "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
1534#ifdef ELF_CORE_COPY_XFPREGS 1550#ifdef ELF_CORE_COPY_XFPREGS
@@ -1577,8 +1593,10 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1577 phdr.p_memsz = sz; 1593 phdr.p_memsz = sz;
1578 offset += phdr.p_filesz; 1594 offset += phdr.p_filesz;
1579 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1595 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1580 if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W; 1596 if (vma->vm_flags & VM_WRITE)
1581 if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X; 1597 phdr.p_flags |= PF_W;
1598 if (vma->vm_flags & VM_EXEC)
1599 phdr.p_flags |= PF_X;
1582 phdr.p_align = ELF_EXEC_PAGESIZE; 1600 phdr.p_align = ELF_EXEC_PAGESIZE;
1583 1601
1584 DUMP_WRITE(&phdr, sizeof(phdr)); 1602 DUMP_WRITE(&phdr, sizeof(phdr));
@@ -1595,7 +1613,9 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1595 1613
1596 /* write out the thread status notes section */ 1614 /* write out the thread status notes section */
1597 list_for_each(t, &thread_list) { 1615 list_for_each(t, &thread_list) {
1598 struct elf_thread_status *tmp = list_entry(t, struct elf_thread_status, list); 1616 struct elf_thread_status *tmp =
1617 list_entry(t, struct elf_thread_status, list);
1618
1599 for (i = 0; i < tmp->num_notes; i++) 1619 for (i = 0; i < tmp->num_notes; i++)
1600 if (!writenote(&tmp->notes[i], file)) 1620 if (!writenote(&tmp->notes[i], file))
1601 goto end_coredump; 1621 goto end_coredump;
@@ -1612,18 +1632,19 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1612 for (addr = vma->vm_start; 1632 for (addr = vma->vm_start;
1613 addr < vma->vm_end; 1633 addr < vma->vm_end;
1614 addr += PAGE_SIZE) { 1634 addr += PAGE_SIZE) {
1615 struct page* page; 1635 struct page *page;
1616 struct vm_area_struct *vma; 1636 struct vm_area_struct *vma;
1617 1637
1618 if (get_user_pages(current, current->mm, addr, 1, 0, 1, 1638 if (get_user_pages(current, current->mm, addr, 1, 0, 1,
1619 &page, &vma) <= 0) { 1639 &page, &vma) <= 0) {
1620 DUMP_SEEK (file->f_pos + PAGE_SIZE); 1640 DUMP_SEEK(file->f_pos + PAGE_SIZE);
1621 } else { 1641 } else {
1622 if (page == ZERO_PAGE(addr)) { 1642 if (page == ZERO_PAGE(addr)) {
1623 DUMP_SEEK (file->f_pos + PAGE_SIZE); 1643 DUMP_SEEK(file->f_pos + PAGE_SIZE);
1624 } else { 1644 } else {
1625 void *kaddr; 1645 void *kaddr;
1626 flush_cache_page(vma, addr, page_to_pfn(page)); 1646 flush_cache_page(vma, addr,
1647 page_to_pfn(page));
1627 kaddr = kmap(page); 1648 kaddr = kmap(page);
1628 if ((size += PAGE_SIZE) > limit || 1649 if ((size += PAGE_SIZE) > limit ||
1629 !dump_write(file, kaddr, 1650 !dump_write(file, kaddr,
@@ -1645,7 +1666,8 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1645 1666
1646 if ((off_t)file->f_pos != offset) { 1667 if ((off_t)file->f_pos != offset) {
1647 /* Sanity check */ 1668 /* Sanity check */
1648 printk(KERN_WARNING "elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", 1669 printk(KERN_WARNING
1670 "elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
1649 (off_t)file->f_pos, offset); 1671 (off_t)file->f_pos, offset);
1650 } 1672 }
1651 1673
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index a2e48c999c24..eba4e23b9ca0 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -435,9 +435,10 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
435 struct elf_fdpic_params *interp_params) 435 struct elf_fdpic_params *interp_params)
436{ 436{
437 unsigned long sp, csp, nitems; 437 unsigned long sp, csp, nitems;
438 elf_caddr_t *argv, *envp; 438 elf_caddr_t __user *argv, *envp;
439 size_t platform_len = 0, len; 439 size_t platform_len = 0, len;
440 char *k_platform, *u_platform, *p; 440 char *k_platform;
441 char __user *u_platform, *p;
441 long hwcap; 442 long hwcap;
442 int loop; 443 int loop;
443 444
@@ -462,12 +463,11 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
462 if (k_platform) { 463 if (k_platform) {
463 platform_len = strlen(k_platform) + 1; 464 platform_len = strlen(k_platform) + 1;
464 sp -= platform_len; 465 sp -= platform_len;
466 u_platform = (char __user *) sp;
465 if (__copy_to_user(u_platform, k_platform, platform_len) != 0) 467 if (__copy_to_user(u_platform, k_platform, platform_len) != 0)
466 return -EFAULT; 468 return -EFAULT;
467 } 469 }
468 470
469 u_platform = (char *) sp;
470
471#if defined(__i386__) && defined(CONFIG_SMP) 471#if defined(__i386__) && defined(CONFIG_SMP)
472 /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions 472 /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
473 * by the processes running on the same package. One thing we can do 473 * by the processes running on the same package. One thing we can do
@@ -490,7 +490,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
490 sp = (sp - len) & ~7UL; 490 sp = (sp - len) & ~7UL;
491 exec_params->map_addr = sp; 491 exec_params->map_addr = sp;
492 492
493 if (copy_to_user((void *) sp, exec_params->loadmap, len) != 0) 493 if (copy_to_user((void __user *) sp, exec_params->loadmap, len) != 0)
494 return -EFAULT; 494 return -EFAULT;
495 495
496 current->mm->context.exec_fdpic_loadmap = (unsigned long) sp; 496 current->mm->context.exec_fdpic_loadmap = (unsigned long) sp;
@@ -501,7 +501,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
501 sp = (sp - len) & ~7UL; 501 sp = (sp - len) & ~7UL;
502 interp_params->map_addr = sp; 502 interp_params->map_addr = sp;
503 503
504 if (copy_to_user((void *) sp, interp_params->loadmap, len) != 0) 504 if (copy_to_user((void __user *) sp, interp_params->loadmap, len) != 0)
505 return -EFAULT; 505 return -EFAULT;
506 506
507 current->mm->context.interp_fdpic_loadmap = (unsigned long) sp; 507 current->mm->context.interp_fdpic_loadmap = (unsigned long) sp;
@@ -527,7 +527,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
527 /* put the ELF interpreter info on the stack */ 527 /* put the ELF interpreter info on the stack */
528#define NEW_AUX_ENT(nr, id, val) \ 528#define NEW_AUX_ENT(nr, id, val) \
529 do { \ 529 do { \
530 struct { unsigned long _id, _val; } *ent = (void *) csp; \ 530 struct { unsigned long _id, _val; } __user *ent = (void __user *) csp; \
531 __put_user((id), &ent[nr]._id); \ 531 __put_user((id), &ent[nr]._id); \
532 __put_user((val), &ent[nr]._val); \ 532 __put_user((val), &ent[nr]._val); \
533 } while (0) 533 } while (0)
@@ -564,13 +564,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
564 564
565 /* allocate room for argv[] and envv[] */ 565 /* allocate room for argv[] and envv[] */
566 csp -= (bprm->envc + 1) * sizeof(elf_caddr_t); 566 csp -= (bprm->envc + 1) * sizeof(elf_caddr_t);
567 envp = (elf_caddr_t *) csp; 567 envp = (elf_caddr_t __user *) csp;
568 csp -= (bprm->argc + 1) * sizeof(elf_caddr_t); 568 csp -= (bprm->argc + 1) * sizeof(elf_caddr_t);
569 argv = (elf_caddr_t *) csp; 569 argv = (elf_caddr_t __user *) csp;
570 570
571 /* stack argc */ 571 /* stack argc */
572 csp -= sizeof(unsigned long); 572 csp -= sizeof(unsigned long);
573 __put_user(bprm->argc, (unsigned long *) csp); 573 __put_user(bprm->argc, (unsigned long __user *) csp);
574 574
575 BUG_ON(csp != sp); 575 BUG_ON(csp != sp);
576 576
@@ -581,7 +581,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
581 current->mm->arg_start = current->mm->start_stack - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p); 581 current->mm->arg_start = current->mm->start_stack - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
582#endif 582#endif
583 583
584 p = (char *) current->mm->arg_start; 584 p = (char __user *) current->mm->arg_start;
585 for (loop = bprm->argc; loop > 0; loop--) { 585 for (loop = bprm->argc; loop > 0; loop--) {
586 __put_user((elf_caddr_t) p, argv++); 586 __put_user((elf_caddr_t) p, argv++);
587 len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES); 587 len = strnlen_user(p, PAGE_SIZE * MAX_ARG_PAGES);
@@ -1025,7 +1025,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1025 /* clear the bit between beginning of mapping and beginning of PT_LOAD */ 1025 /* clear the bit between beginning of mapping and beginning of PT_LOAD */
1026 if (prot & PROT_WRITE && disp > 0) { 1026 if (prot & PROT_WRITE && disp > 0) {
1027 kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); 1027 kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
1028 clear_user((void *) maddr, disp); 1028 clear_user((void __user *) maddr, disp);
1029 maddr += disp; 1029 maddr += disp;
1030 } 1030 }
1031 1031
@@ -1059,7 +1059,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1059 if (prot & PROT_WRITE && excess1 > 0) { 1059 if (prot & PROT_WRITE && excess1 > 0) {
1060 kdebug("clear[%d] ad=%lx sz=%lx", 1060 kdebug("clear[%d] ad=%lx sz=%lx",
1061 loop, maddr + phdr->p_filesz, excess1); 1061 loop, maddr + phdr->p_filesz, excess1);
1062 clear_user((void *) maddr + phdr->p_filesz, excess1); 1062 clear_user((void __user *) maddr + phdr->p_filesz, excess1);
1063 } 1063 }
1064 1064
1065#else 1065#else
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index c0a909e1d290..34ebbc191e46 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -204,7 +204,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
204 goto _error; 204 goto _error;
205 205
206 if (files) { 206 if (files) {
207 steal_locks(files);
208 put_files_struct(files); 207 put_files_struct(files);
209 files = NULL; 208 files = NULL;
210 } 209 }
@@ -741,10 +740,10 @@ static int bm_fill_super(struct super_block * sb, void * data, int silent)
741 return err; 740 return err;
742} 741}
743 742
744static struct super_block *bm_get_sb(struct file_system_type *fs_type, 743static int bm_get_sb(struct file_system_type *fs_type,
745 int flags, const char *dev_name, void *data) 744 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
746{ 745{
747 return get_sb_single(fs_type, flags, data, bm_fill_super); 746 return get_sb_single(fs_type, flags, data, bm_fill_super, mnt);
748} 747}
749 748
750static struct linux_binfmt misc_format = { 749static struct linux_binfmt misc_format = {
diff --git a/fs/block_dev.c b/fs/block_dev.c
index f5958f413bd1..028d9fb9c2d5 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -300,10 +300,10 @@ static struct super_operations bdev_sops = {
300 .clear_inode = bdev_clear_inode, 300 .clear_inode = bdev_clear_inode,
301}; 301};
302 302
303static struct super_block *bd_get_sb(struct file_system_type *fs_type, 303static int bd_get_sb(struct file_system_type *fs_type,
304 int flags, const char *dev_name, void *data) 304 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
305{ 305{
306 return get_sb_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576); 306 return get_sb_pseudo(fs_type, "bdev:", &bdev_sops, 0x62646576, mnt);
307} 307}
308 308
309static struct file_system_type bd_type = { 309static struct file_system_type bd_type = {
@@ -414,21 +414,31 @@ EXPORT_SYMBOL(bdput);
414static struct block_device *bd_acquire(struct inode *inode) 414static struct block_device *bd_acquire(struct inode *inode)
415{ 415{
416 struct block_device *bdev; 416 struct block_device *bdev;
417
417 spin_lock(&bdev_lock); 418 spin_lock(&bdev_lock);
418 bdev = inode->i_bdev; 419 bdev = inode->i_bdev;
419 if (bdev && igrab(bdev->bd_inode)) { 420 if (bdev) {
421 atomic_inc(&bdev->bd_inode->i_count);
420 spin_unlock(&bdev_lock); 422 spin_unlock(&bdev_lock);
421 return bdev; 423 return bdev;
422 } 424 }
423 spin_unlock(&bdev_lock); 425 spin_unlock(&bdev_lock);
426
424 bdev = bdget(inode->i_rdev); 427 bdev = bdget(inode->i_rdev);
425 if (bdev) { 428 if (bdev) {
426 spin_lock(&bdev_lock); 429 spin_lock(&bdev_lock);
427 if (inode->i_bdev) 430 if (!inode->i_bdev) {
428 __bd_forget(inode); 431 /*
429 inode->i_bdev = bdev; 432 * We take an additional bd_inode->i_count for inode,
430 inode->i_mapping = bdev->bd_inode->i_mapping; 433 * and it's released in clear_inode() of inode.
431 list_add(&inode->i_devices, &bdev->bd_inodes); 434 * So, we can access it via ->i_mapping always
435 * without igrab().
436 */
437 atomic_inc(&bdev->bd_inode->i_count);
438 inode->i_bdev = bdev;
439 inode->i_mapping = bdev->bd_inode->i_mapping;
440 list_add(&inode->i_devices, &bdev->bd_inodes);
441 }
432 spin_unlock(&bdev_lock); 442 spin_unlock(&bdev_lock);
433 } 443 }
434 return bdev; 444 return bdev;
@@ -438,10 +448,18 @@ static struct block_device *bd_acquire(struct inode *inode)
438 448
439void bd_forget(struct inode *inode) 449void bd_forget(struct inode *inode)
440{ 450{
451 struct block_device *bdev = NULL;
452
441 spin_lock(&bdev_lock); 453 spin_lock(&bdev_lock);
442 if (inode->i_bdev) 454 if (inode->i_bdev) {
455 if (inode->i_sb != blockdev_superblock)
456 bdev = inode->i_bdev;
443 __bd_forget(inode); 457 __bd_forget(inode);
458 }
444 spin_unlock(&bdev_lock); 459 spin_unlock(&bdev_lock);
460
461 if (bdev)
462 iput(bdev->bd_inode);
445} 463}
446 464
447int bd_claim(struct block_device *bdev, void *holder) 465int bd_claim(struct block_device *bdev, void *holder)
diff --git a/fs/buffer.c b/fs/buffer.c
index 23f1f3a68077..373bb6292bdc 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -331,7 +331,6 @@ long do_fsync(struct file *file, int datasync)
331 goto out; 331 goto out;
332 } 332 }
333 333
334 current->flags |= PF_SYNCWRITE;
335 ret = filemap_fdatawrite(mapping); 334 ret = filemap_fdatawrite(mapping);
336 335
337 /* 336 /*
@@ -346,7 +345,6 @@ long do_fsync(struct file *file, int datasync)
346 err = filemap_fdatawait(mapping); 345 err = filemap_fdatawait(mapping);
347 if (!ret) 346 if (!ret)
348 ret = err; 347 ret = err;
349 current->flags &= ~PF_SYNCWRITE;
350out: 348out:
351 return ret; 349 return ret;
352} 350}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 3fdc2258f447..8b4de6eaabd0 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -166,8 +166,9 @@ cifs_put_super(struct super_block *sb)
166} 166}
167 167
168static int 168static int
169cifs_statfs(struct super_block *sb, struct kstatfs *buf) 169cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
170{ 170{
171 struct super_block *sb = dentry->d_sb;
171 int xid; 172 int xid;
172 int rc = -EOPNOTSUPP; 173 int rc = -EOPNOTSUPP;
173 struct cifs_sb_info *cifs_sb; 174 struct cifs_sb_info *cifs_sb;
@@ -462,9 +463,9 @@ struct super_operations cifs_super_ops = {
462 .remount_fs = cifs_remount, 463 .remount_fs = cifs_remount,
463}; 464};
464 465
465static struct super_block * 466static int
466cifs_get_sb(struct file_system_type *fs_type, 467cifs_get_sb(struct file_system_type *fs_type,
467 int flags, const char *dev_name, void *data) 468 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
468{ 469{
469 int rc; 470 int rc;
470 struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL); 471 struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
@@ -472,7 +473,7 @@ cifs_get_sb(struct file_system_type *fs_type,
472 cFYI(1, ("Devname: %s flags: %d ", dev_name, flags)); 473 cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
473 474
474 if (IS_ERR(sb)) 475 if (IS_ERR(sb))
475 return sb; 476 return PTR_ERR(sb);
476 477
477 sb->s_flags = flags; 478 sb->s_flags = flags;
478 479
@@ -480,10 +481,10 @@ cifs_get_sb(struct file_system_type *fs_type,
480 if (rc) { 481 if (rc) {
481 up_write(&sb->s_umount); 482 up_write(&sb->s_umount);
482 deactivate_super(sb); 483 deactivate_super(sb);
483 return ERR_PTR(rc); 484 return rc;
484 } 485 }
485 sb->s_flags |= MS_ACTIVE; 486 sb->s_flags |= MS_ACTIVE;
486 return sb; 487 return simple_set_mnt(mnt, sb);
487} 488}
488 489
489static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, 490static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index c98755dca868..d56c0577c710 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -74,7 +74,7 @@ extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
74 size_t write_size, loff_t * poffset); 74 size_t write_size, loff_t * poffset);
75extern int cifs_lock(struct file *, int, struct file_lock *); 75extern int cifs_lock(struct file *, int, struct file_lock *);
76extern int cifs_fsync(struct file *, struct dentry *, int); 76extern int cifs_fsync(struct file *, struct dentry *, int);
77extern int cifs_flush(struct file *); 77extern int cifs_flush(struct file *, fl_owner_t id);
78extern int cifs_file_mmap(struct file * , struct vm_area_struct *); 78extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
79extern const struct file_operations cifs_dir_ops; 79extern const struct file_operations cifs_dir_ops;
80extern int cifs_dir_open(struct inode *inode, struct file *file); 80extern int cifs_dir_open(struct inode *inode, struct file *file);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e2b4ce1dad66..b4a18c1cab0a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1079,9 +1079,9 @@ static int cifs_writepages(struct address_space *mapping,
1079 unsigned int bytes_written; 1079 unsigned int bytes_written;
1080 struct cifs_sb_info *cifs_sb; 1080 struct cifs_sb_info *cifs_sb;
1081 int done = 0; 1081 int done = 0;
1082 pgoff_t end = -1; 1082 pgoff_t end;
1083 pgoff_t index; 1083 pgoff_t index;
1084 int is_range = 0; 1084 int range_whole = 0;
1085 struct kvec iov[32]; 1085 struct kvec iov[32];
1086 int len; 1086 int len;
1087 int n_iov = 0; 1087 int n_iov = 0;
@@ -1122,16 +1122,14 @@ static int cifs_writepages(struct address_space *mapping,
1122 xid = GetXid(); 1122 xid = GetXid();
1123 1123
1124 pagevec_init(&pvec, 0); 1124 pagevec_init(&pvec, 0);
1125 if (wbc->sync_mode == WB_SYNC_NONE) 1125 if (wbc->range_cyclic) {
1126 index = mapping->writeback_index; /* Start from prev offset */ 1126 index = mapping->writeback_index; /* Start from prev offset */
1127 else { 1127 end = -1;
1128 index = 0; 1128 } else {
1129 scanned = 1; 1129 index = wbc->range_start >> PAGE_CACHE_SHIFT;
1130 } 1130 end = wbc->range_end >> PAGE_CACHE_SHIFT;
1131 if (wbc->start || wbc->end) { 1131 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
1132 index = wbc->start >> PAGE_CACHE_SHIFT; 1132 range_whole = 1;
1133 end = wbc->end >> PAGE_CACHE_SHIFT;
1134 is_range = 1;
1135 scanned = 1; 1133 scanned = 1;
1136 } 1134 }
1137retry: 1135retry:
@@ -1167,7 +1165,7 @@ retry:
1167 break; 1165 break;
1168 } 1166 }
1169 1167
1170 if (unlikely(is_range) && (page->index > end)) { 1168 if (!wbc->range_cyclic && page->index > end) {
1171 done = 1; 1169 done = 1;
1172 unlock_page(page); 1170 unlock_page(page);
1173 break; 1171 break;
@@ -1271,7 +1269,7 @@ retry:
1271 index = 0; 1269 index = 0;
1272 goto retry; 1270 goto retry;
1273 } 1271 }
1274 if (!is_range) 1272 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
1275 mapping->writeback_index = index; 1273 mapping->writeback_index = index;
1276 1274
1277 FreeXid(xid); 1275 FreeXid(xid);
@@ -1419,7 +1417,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1419 * As file closes, flush all cached write data for this inode checking 1417 * As file closes, flush all cached write data for this inode checking
1420 * for write behind errors. 1418 * for write behind errors.
1421 */ 1419 */
1422int cifs_flush(struct file *file) 1420int cifs_flush(struct file *file, fl_owner_t id)
1423{ 1421{
1424 struct inode * inode = file->f_dentry->d_inode; 1422 struct inode * inode = file->f_dentry->d_inode;
1425 int rc = 0; 1423 int rc = 0;
diff --git a/fs/coda/file.c b/fs/coda/file.c
index 7c2642431fa5..cc66c681bd11 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -164,7 +164,7 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
164 return 0; 164 return 0;
165} 165}
166 166
167int coda_flush(struct file *coda_file) 167int coda_flush(struct file *coda_file, fl_owner_t id)
168{ 168{
169 unsigned short flags = coda_file->f_flags & ~O_EXCL; 169 unsigned short flags = coda_file->f_flags & ~O_EXCL;
170 unsigned short coda_flags = coda_flags_to_cflags(flags); 170 unsigned short coda_flags = coda_flags_to_cflags(flags);
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index ada1a81df6bd..87f1dc8aa24b 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -36,7 +36,7 @@
36/* VFS super_block ops */ 36/* VFS super_block ops */
37static void coda_clear_inode(struct inode *); 37static void coda_clear_inode(struct inode *);
38static void coda_put_super(struct super_block *); 38static void coda_put_super(struct super_block *);
39static int coda_statfs(struct super_block *sb, struct kstatfs *buf); 39static int coda_statfs(struct dentry *dentry, struct kstatfs *buf);
40 40
41static kmem_cache_t * coda_inode_cachep; 41static kmem_cache_t * coda_inode_cachep;
42 42
@@ -278,13 +278,13 @@ struct inode_operations coda_file_inode_operations = {
278 .setattr = coda_setattr, 278 .setattr = coda_setattr,
279}; 279};
280 280
281static int coda_statfs(struct super_block *sb, struct kstatfs *buf) 281static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
282{ 282{
283 int error; 283 int error;
284 284
285 lock_kernel(); 285 lock_kernel();
286 286
287 error = venus_statfs(sb, buf); 287 error = venus_statfs(dentry, buf);
288 288
289 unlock_kernel(); 289 unlock_kernel();
290 290
@@ -307,10 +307,10 @@ static int coda_statfs(struct super_block *sb, struct kstatfs *buf)
307 307
308/* init_coda: used by filesystems.c to register coda */ 308/* init_coda: used by filesystems.c to register coda */
309 309
310static struct super_block *coda_get_sb(struct file_system_type *fs_type, 310static int coda_get_sb(struct file_system_type *fs_type,
311 int flags, const char *dev_name, void *data) 311 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
312{ 312{
313 return get_sb_nodev(fs_type, flags, data, coda_fill_super); 313 return get_sb_nodev(fs_type, flags, data, coda_fill_super, mnt);
314} 314}
315 315
316struct file_system_type coda_fs_type = { 316struct file_system_type coda_fs_type = {
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 1bae99650a91..b040eba13a7d 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -611,7 +611,7 @@ int venus_pioctl(struct super_block *sb, struct CodaFid *fid,
611 return error; 611 return error;
612} 612}
613 613
614int venus_statfs(struct super_block *sb, struct kstatfs *sfs) 614int venus_statfs(struct dentry *dentry, struct kstatfs *sfs)
615{ 615{
616 union inputArgs *inp; 616 union inputArgs *inp;
617 union outputArgs *outp; 617 union outputArgs *outp;
@@ -620,7 +620,7 @@ int venus_statfs(struct super_block *sb, struct kstatfs *sfs)
620 insize = max_t(unsigned int, INSIZE(statfs), OUTSIZE(statfs)); 620 insize = max_t(unsigned int, INSIZE(statfs), OUTSIZE(statfs));
621 UPARG(CODA_STATFS); 621 UPARG(CODA_STATFS);
622 622
623 error = coda_upcall(coda_sbp(sb), insize, &outsize, inp); 623 error = coda_upcall(coda_sbp(dentry->d_sb), insize, &outsize, inp);
624 624
625 if (!error) { 625 if (!error) {
626 sfs->f_blocks = outp->coda_statfs.stat.f_blocks; 626 sfs->f_blocks = outp->coda_statfs.stat.f_blocks;
diff --git a/fs/compat.c b/fs/compat.c
index b1f64786a613..7e7e5bc4f3cf 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -197,7 +197,7 @@ asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs
197 error = user_path_walk(path, &nd); 197 error = user_path_walk(path, &nd);
198 if (!error) { 198 if (!error) {
199 struct kstatfs tmp; 199 struct kstatfs tmp;
200 error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); 200 error = vfs_statfs(nd.dentry, &tmp);
201 if (!error) 201 if (!error)
202 error = put_compat_statfs(buf, &tmp); 202 error = put_compat_statfs(buf, &tmp);
203 path_release(&nd); 203 path_release(&nd);
@@ -215,7 +215,7 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user
215 file = fget(fd); 215 file = fget(fd);
216 if (!file) 216 if (!file)
217 goto out; 217 goto out;
218 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); 218 error = vfs_statfs(file->f_dentry, &tmp);
219 if (!error) 219 if (!error)
220 error = put_compat_statfs(buf, &tmp); 220 error = put_compat_statfs(buf, &tmp);
221 fput(file); 221 fput(file);
@@ -265,7 +265,7 @@ asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, s
265 error = user_path_walk(path, &nd); 265 error = user_path_walk(path, &nd);
266 if (!error) { 266 if (!error) {
267 struct kstatfs tmp; 267 struct kstatfs tmp;
268 error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); 268 error = vfs_statfs(nd.dentry, &tmp);
269 if (!error) 269 if (!error)
270 error = put_compat_statfs64(buf, &tmp); 270 error = put_compat_statfs64(buf, &tmp);
271 path_release(&nd); 271 path_release(&nd);
@@ -286,7 +286,7 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c
286 file = fget(fd); 286 file = fget(fd);
287 if (!file) 287 if (!file)
288 goto out; 288 goto out;
289 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); 289 error = vfs_statfs(file->f_dentry, &tmp);
290 if (!error) 290 if (!error)
291 error = put_compat_statfs64(buf, &tmp); 291 error = put_compat_statfs64(buf, &tmp);
292 fput(file); 292 fput(file);
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index be5d86ae56f0..3e5fe843e1df 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -103,10 +103,10 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent)
103 return 0; 103 return 0;
104} 104}
105 105
106static struct super_block *configfs_get_sb(struct file_system_type *fs_type, 106static int configfs_get_sb(struct file_system_type *fs_type,
107 int flags, const char *dev_name, void *data) 107 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
108{ 108{
109 return get_sb_single(fs_type, flags, data, configfs_fill_super); 109 return get_sb_single(fs_type, flags, data, configfs_fill_super, mnt);
110} 110}
111 111
112static struct file_system_type configfs_fs_type = { 112static struct file_system_type configfs_fs_type = {
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 9efcc3a164e8..c45d73860803 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -181,9 +181,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
181 struct page *page = NULL; 181 struct page *page = NULL;
182 182
183 if (blocknr + i < devsize) { 183 if (blocknr + i < devsize) {
184 page = read_cache_page(mapping, blocknr + i, 184 page = read_mapping_page(mapping, blocknr + i, NULL);
185 (filler_t *)mapping->a_ops->readpage,
186 NULL);
187 /* synchronous error? */ 185 /* synchronous error? */
188 if (IS_ERR(page)) 186 if (IS_ERR(page))
189 page = NULL; 187 page = NULL;
@@ -322,8 +320,10 @@ out:
322 return -EINVAL; 320 return -EINVAL;
323} 321}
324 322
325static int cramfs_statfs(struct super_block *sb, struct kstatfs *buf) 323static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf)
326{ 324{
325 struct super_block *sb = dentry->d_sb;
326
327 buf->f_type = CRAMFS_MAGIC; 327 buf->f_type = CRAMFS_MAGIC;
328 buf->f_bsize = PAGE_CACHE_SIZE; 328 buf->f_bsize = PAGE_CACHE_SIZE;
329 buf->f_blocks = CRAMFS_SB(sb)->blocks; 329 buf->f_blocks = CRAMFS_SB(sb)->blocks;
@@ -528,10 +528,11 @@ static struct super_operations cramfs_ops = {
528 .statfs = cramfs_statfs, 528 .statfs = cramfs_statfs,
529}; 529};
530 530
531static struct super_block *cramfs_get_sb(struct file_system_type *fs_type, 531static int cramfs_get_sb(struct file_system_type *fs_type,
532 int flags, const char *dev_name, void *data) 532 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
533{ 533{
534 return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super); 534 return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super,
535 mnt);
535} 536}
536 537
537static struct file_system_type cramfs_fs_type = { 538static struct file_system_type cramfs_fs_type = {
diff --git a/fs/dcache.c b/fs/dcache.c
index 940d188e5d14..313b54b2b8f2 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -359,12 +359,13 @@ restart:
359} 359}
360 360
361/* 361/*
362 * Throw away a dentry - free the inode, dput the parent. 362 * Throw away a dentry - free the inode, dput the parent. This requires that
363 * This requires that the LRU list has already been 363 * the LRU list has already been removed.
364 * removed. 364 *
365 * Called with dcache_lock, drops it and then regains. 365 * Called with dcache_lock, drops it and then regains.
366 * Called with dentry->d_lock held, drops it.
366 */ 367 */
367static inline void prune_one_dentry(struct dentry * dentry) 368static void prune_one_dentry(struct dentry * dentry)
368{ 369{
369 struct dentry * parent; 370 struct dentry * parent;
370 371
@@ -382,6 +383,8 @@ static inline void prune_one_dentry(struct dentry * dentry)
382/** 383/**
383 * prune_dcache - shrink the dcache 384 * prune_dcache - shrink the dcache
384 * @count: number of entries to try and free 385 * @count: number of entries to try and free
386 * @sb: if given, ignore dentries for other superblocks
387 * which are being unmounted.
385 * 388 *
386 * Shrink the dcache. This is done when we need 389 * Shrink the dcache. This is done when we need
387 * more memory, or simply when we need to unmount 390 * more memory, or simply when we need to unmount
@@ -392,16 +395,29 @@ static inline void prune_one_dentry(struct dentry * dentry)
392 * all the dentries are in use. 395 * all the dentries are in use.
393 */ 396 */
394 397
395static void prune_dcache(int count) 398static void prune_dcache(int count, struct super_block *sb)
396{ 399{
397 spin_lock(&dcache_lock); 400 spin_lock(&dcache_lock);
398 for (; count ; count--) { 401 for (; count ; count--) {
399 struct dentry *dentry; 402 struct dentry *dentry;
400 struct list_head *tmp; 403 struct list_head *tmp;
404 struct rw_semaphore *s_umount;
401 405
402 cond_resched_lock(&dcache_lock); 406 cond_resched_lock(&dcache_lock);
403 407
404 tmp = dentry_unused.prev; 408 tmp = dentry_unused.prev;
409 if (unlikely(sb)) {
410 /* Try to find a dentry for this sb, but don't try
411 * too hard, if they aren't near the tail they will
412 * be moved down again soon
413 */
414 int skip = count;
415 while (skip && tmp != &dentry_unused &&
416 list_entry(tmp, struct dentry, d_lru)->d_sb != sb) {
417 skip--;
418 tmp = tmp->prev;
419 }
420 }
405 if (tmp == &dentry_unused) 421 if (tmp == &dentry_unused)
406 break; 422 break;
407 list_del_init(tmp); 423 list_del_init(tmp);
@@ -427,7 +443,45 @@ static void prune_dcache(int count)
427 spin_unlock(&dentry->d_lock); 443 spin_unlock(&dentry->d_lock);
428 continue; 444 continue;
429 } 445 }
430 prune_one_dentry(dentry); 446 /*
447 * If the dentry is not DCACHED_REFERENCED, it is time
448 * to remove it from the dcache, provided the super block is
449 * NULL (which means we are trying to reclaim memory)
450 * or this dentry belongs to the same super block that
451 * we want to shrink.
452 */
453 /*
454 * If this dentry is for "my" filesystem, then I can prune it
455 * without taking the s_umount lock (I already hold it).
456 */
457 if (sb && dentry->d_sb == sb) {
458 prune_one_dentry(dentry);
459 continue;
460 }
461 /*
462 * ...otherwise we need to be sure this filesystem isn't being
463 * unmounted, otherwise we could race with
464 * generic_shutdown_super(), and end up holding a reference to
465 * an inode while the filesystem is unmounted.
466 * So we try to get s_umount, and make sure s_root isn't NULL.
467 * (Take a local copy of s_umount to avoid a use-after-free of
468 * `dentry').
469 */
470 s_umount = &dentry->d_sb->s_umount;
471 if (down_read_trylock(s_umount)) {
472 if (dentry->d_sb->s_root != NULL) {
473 prune_one_dentry(dentry);
474 up_read(s_umount);
475 continue;
476 }
477 up_read(s_umount);
478 }
479 spin_unlock(&dentry->d_lock);
480 /* Cannot remove the first dentry, and it isn't appropriate
481 * to move it to the head of the list, so give up, and try
482 * later
483 */
484 break;
431 } 485 }
432 spin_unlock(&dcache_lock); 486 spin_unlock(&dcache_lock);
433} 487}
@@ -630,46 +684,7 @@ void shrink_dcache_parent(struct dentry * parent)
630 int found; 684 int found;
631 685
632 while ((found = select_parent(parent)) != 0) 686 while ((found = select_parent(parent)) != 0)
633 prune_dcache(found); 687 prune_dcache(found, parent->d_sb);
634}
635
636/**
637 * shrink_dcache_anon - further prune the cache
638 * @head: head of d_hash list of dentries to prune
639 *
640 * Prune the dentries that are anonymous
641 *
642 * parsing d_hash list does not hlist_for_each_entry_rcu() as it
643 * done under dcache_lock.
644 *
645 */
646void shrink_dcache_anon(struct hlist_head *head)
647{
648 struct hlist_node *lp;
649 int found;
650 do {
651 found = 0;
652 spin_lock(&dcache_lock);
653 hlist_for_each(lp, head) {
654 struct dentry *this = hlist_entry(lp, struct dentry, d_hash);
655 if (!list_empty(&this->d_lru)) {
656 dentry_stat.nr_unused--;
657 list_del_init(&this->d_lru);
658 }
659
660 /*
661 * move only zero ref count dentries to the end
662 * of the unused list for prune_dcache
663 */
664 if (!atomic_read(&this->d_count)) {
665 list_add_tail(&this->d_lru, &dentry_unused);
666 dentry_stat.nr_unused++;
667 found++;
668 }
669 }
670 spin_unlock(&dcache_lock);
671 prune_dcache(found);
672 } while(found);
673} 688}
674 689
675/* 690/*
@@ -689,7 +704,7 @@ static int shrink_dcache_memory(int nr, gfp_t gfp_mask)
689 if (nr) { 704 if (nr) {
690 if (!(gfp_mask & __GFP_FS)) 705 if (!(gfp_mask & __GFP_FS))
691 return -1; 706 return -1;
692 prune_dcache(nr); 707 prune_dcache(nr, NULL);
693 } 708 }
694 return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure; 709 return (dentry_stat.nr_unused / 100) * sysctl_vfs_cache_pressure;
695} 710}
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 90f9417181fd..6fa1e04f8415 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -111,11 +111,11 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
111 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); 111 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
112} 112}
113 113
114static struct super_block *debug_get_sb(struct file_system_type *fs_type, 114static int debug_get_sb(struct file_system_type *fs_type,
115 int flags, const char *dev_name, 115 int flags, const char *dev_name,
116 void *data) 116 void *data, struct vfsmount *mnt)
117{ 117{
118 return get_sb_single(fs_type, flags, data, debug_fill_super); 118 return get_sb_single(fs_type, flags, data, debug_fill_super, mnt);
119} 119}
120 120
121static struct file_system_type debug_fs_type = { 121static struct file_system_type debug_fs_type = {
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 52f5059c4f31..51a97f132745 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2549,11 +2549,11 @@ static int devfs_fill_super(struct super_block *sb, void *data, int silent)
2549 return -EINVAL; 2549 return -EINVAL;
2550} /* End Function devfs_fill_super */ 2550} /* End Function devfs_fill_super */
2551 2551
2552static struct super_block *devfs_get_sb(struct file_system_type *fs_type, 2552static int devfs_get_sb(struct file_system_type *fs_type,
2553 int flags, const char *dev_name, 2553 int flags, const char *dev_name,
2554 void *data) 2554 void *data, struct vfsmount *mnt)
2555{ 2555{
2556 return get_sb_single(fs_type, flags, data, devfs_fill_super); 2556 return get_sb_single(fs_type, flags, data, devfs_fill_super, mnt);
2557} 2557}
2558 2558
2559static struct file_system_type devfs_fs_type = { 2559static struct file_system_type devfs_fs_type = {
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 14c5620b5cab..f7aef5bb584a 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -130,10 +130,10 @@ fail:
130 return -ENOMEM; 130 return -ENOMEM;
131} 131}
132 132
133static struct super_block *devpts_get_sb(struct file_system_type *fs_type, 133static int devpts_get_sb(struct file_system_type *fs_type,
134 int flags, const char *dev_name, void *data) 134 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
135{ 135{
136 return get_sb_single(fs_type, flags, data, devpts_fill_super); 136 return get_sb_single(fs_type, flags, data, devpts_fill_super, mnt);
137} 137}
138 138
139static struct file_system_type devpts_fs_type = { 139static struct file_system_type devpts_fs_type = {
diff --git a/fs/direct-io.c b/fs/direct-io.c
index b05d1b218776..538fb0418fba 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -162,7 +162,7 @@ static int dio_refill_pages(struct dio *dio)
162 NULL); /* vmas */ 162 NULL); /* vmas */
163 up_read(&current->mm->mmap_sem); 163 up_read(&current->mm->mmap_sem);
164 164
165 if (ret < 0 && dio->blocks_available && (dio->rw == WRITE)) { 165 if (ret < 0 && dio->blocks_available && (dio->rw & WRITE)) {
166 struct page *page = ZERO_PAGE(dio->curr_user_address); 166 struct page *page = ZERO_PAGE(dio->curr_user_address);
167 /* 167 /*
168 * A memory fault, but the filesystem has some outstanding 168 * A memory fault, but the filesystem has some outstanding
@@ -535,7 +535,7 @@ static int get_more_blocks(struct dio *dio)
535 map_bh->b_state = 0; 535 map_bh->b_state = 0;
536 map_bh->b_size = fs_count << dio->inode->i_blkbits; 536 map_bh->b_size = fs_count << dio->inode->i_blkbits;
537 537
538 create = dio->rw == WRITE; 538 create = dio->rw & WRITE;
539 if (dio->lock_type == DIO_LOCKING) { 539 if (dio->lock_type == DIO_LOCKING) {
540 if (dio->block_in_file < (i_size_read(dio->inode) >> 540 if (dio->block_in_file < (i_size_read(dio->inode) >>
541 dio->blkbits)) 541 dio->blkbits))
@@ -867,7 +867,7 @@ do_holes:
867 loff_t i_size_aligned; 867 loff_t i_size_aligned;
868 868
869 /* AKPM: eargh, -ENOTBLK is a hack */ 869 /* AKPM: eargh, -ENOTBLK is a hack */
870 if (dio->rw == WRITE) { 870 if (dio->rw & WRITE) {
871 page_cache_release(page); 871 page_cache_release(page);
872 return -ENOTBLK; 872 return -ENOTBLK;
873 } 873 }
@@ -1045,7 +1045,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
1045 } 1045 }
1046 } /* end iovec loop */ 1046 } /* end iovec loop */
1047 1047
1048 if (ret == -ENOTBLK && rw == WRITE) { 1048 if (ret == -ENOTBLK && (rw & WRITE)) {
1049 /* 1049 /*
1050 * The remaining part of the request will be 1050 * The remaining part of the request will be
1051 * be handled by buffered I/O when we return 1051 * be handled by buffered I/O when we return
@@ -1089,7 +1089,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
1089 if (dio->is_async) { 1089 if (dio->is_async) {
1090 int should_wait = 0; 1090 int should_wait = 0;
1091 1091
1092 if (dio->result < dio->size && rw == WRITE) { 1092 if (dio->result < dio->size && (rw & WRITE)) {
1093 dio->waiter = current; 1093 dio->waiter = current;
1094 should_wait = 1; 1094 should_wait = 1;
1095 } 1095 }
@@ -1142,7 +1142,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
1142 ret = transferred; 1142 ret = transferred;
1143 1143
1144 /* We could have also come here on an AIO file extend */ 1144 /* We could have also come here on an AIO file extend */
1145 if (!is_sync_kiocb(iocb) && rw == WRITE && 1145 if (!is_sync_kiocb(iocb) && (rw & WRITE) &&
1146 ret >= 0 && dio->result == dio->size) 1146 ret >= 0 && dio->result == dio->size)
1147 /* 1147 /*
1148 * For AIO writes where we have completed the 1148 * For AIO writes where we have completed the
@@ -1194,7 +1194,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1194 int acquire_i_mutex = 0; 1194 int acquire_i_mutex = 0;
1195 1195
1196 if (rw & WRITE) 1196 if (rw & WRITE)
1197 current->flags |= PF_SYNCWRITE; 1197 rw = WRITE_SYNC;
1198 1198
1199 if (bdev) 1199 if (bdev)
1200 bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev)); 1200 bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
@@ -1270,7 +1270,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1270 * even for AIO, we need to wait for i/o to complete before 1270 * even for AIO, we need to wait for i/o to complete before
1271 * returning in this case. 1271 * returning in this case.
1272 */ 1272 */
1273 dio->is_async = !is_sync_kiocb(iocb) && !((rw == WRITE) && 1273 dio->is_async = !is_sync_kiocb(iocb) && !((rw & WRITE) &&
1274 (end > i_size_read(inode))); 1274 (end > i_size_read(inode)));
1275 1275
1276 retval = direct_io_worker(rw, iocb, inode, iov, offset, 1276 retval = direct_io_worker(rw, iocb, inode, iov, offset,
@@ -1284,8 +1284,6 @@ out:
1284 mutex_unlock(&inode->i_mutex); 1284 mutex_unlock(&inode->i_mutex);
1285 else if (acquire_i_mutex) 1285 else if (acquire_i_mutex)
1286 mutex_lock(&inode->i_mutex); 1286 mutex_lock(&inode->i_mutex);
1287 if (rw & WRITE)
1288 current->flags &= ~PF_SYNCWRITE;
1289 return retval; 1287 return retval;
1290} 1288}
1291EXPORT_SYMBOL(__blockdev_direct_IO); 1289EXPORT_SYMBOL(__blockdev_direct_IO);
diff --git a/fs/efs/super.c b/fs/efs/super.c
index dff623e3ddbf..8ac2462ae5dd 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -15,13 +15,13 @@
15#include <linux/buffer_head.h> 15#include <linux/buffer_head.h>
16#include <linux/vfs.h> 16#include <linux/vfs.h>
17 17
18static int efs_statfs(struct super_block *s, struct kstatfs *buf); 18static int efs_statfs(struct dentry *dentry, struct kstatfs *buf);
19static int efs_fill_super(struct super_block *s, void *d, int silent); 19static int efs_fill_super(struct super_block *s, void *d, int silent);
20 20
21static struct super_block *efs_get_sb(struct file_system_type *fs_type, 21static int efs_get_sb(struct file_system_type *fs_type,
22 int flags, const char *dev_name, void *data) 22 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
23{ 23{
24 return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super); 24 return get_sb_bdev(fs_type, flags, dev_name, data, efs_fill_super, mnt);
25} 25}
26 26
27static struct file_system_type efs_fs_type = { 27static struct file_system_type efs_fs_type = {
@@ -322,8 +322,8 @@ out_no_fs:
322 return -EINVAL; 322 return -EINVAL;
323} 323}
324 324
325static int efs_statfs(struct super_block *s, struct kstatfs *buf) { 325static int efs_statfs(struct dentry *dentry, struct kstatfs *buf) {
326 struct efs_sb_info *sb = SUPER_INFO(s); 326 struct efs_sb_info *sb = SUPER_INFO(dentry->d_sb);
327 327
328 buf->f_type = EFS_SUPER_MAGIC; /* efs magic number */ 328 buf->f_type = EFS_SUPER_MAGIC; /* efs magic number */
329 buf->f_bsize = EFS_BLOCKSIZE; /* blocksize */ 329 buf->f_bsize = EFS_BLOCKSIZE; /* blocksize */
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 2695337d4d64..08e7e6a555ca 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -268,9 +268,9 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
268 int maxevents, long timeout); 268 int maxevents, long timeout);
269static int eventpollfs_delete_dentry(struct dentry *dentry); 269static int eventpollfs_delete_dentry(struct dentry *dentry);
270static struct inode *ep_eventpoll_inode(void); 270static struct inode *ep_eventpoll_inode(void);
271static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type, 271static int eventpollfs_get_sb(struct file_system_type *fs_type,
272 int flags, const char *dev_name, 272 int flags, const char *dev_name,
273 void *data); 273 void *data, struct vfsmount *mnt);
274 274
275/* 275/*
276 * This semaphore is used to serialize ep_free() and eventpoll_release_file(). 276 * This semaphore is used to serialize ep_free() and eventpoll_release_file().
@@ -1595,11 +1595,12 @@ eexit_1:
1595} 1595}
1596 1596
1597 1597
1598static struct super_block * 1598static int
1599eventpollfs_get_sb(struct file_system_type *fs_type, int flags, 1599eventpollfs_get_sb(struct file_system_type *fs_type, int flags,
1600 const char *dev_name, void *data) 1600 const char *dev_name, void *data, struct vfsmount *mnt)
1601{ 1601{
1602 return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC); 1602 return get_sb_pseudo(fs_type, "eventpoll:", NULL, EVENTPOLLFS_MAGIC,
1603 mnt);
1603} 1604}
1604 1605
1605 1606
diff --git a/fs/exec.c b/fs/exec.c
index d07858c0b7c4..0b88bf646143 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -866,7 +866,6 @@ int flush_old_exec(struct linux_binprm * bprm)
866 bprm->mm = NULL; /* We're using it now */ 866 bprm->mm = NULL; /* We're using it now */
867 867
868 /* This is the point of no return */ 868 /* This is the point of no return */
869 steal_locks(files);
870 put_files_struct(files); 869 put_files_struct(files);
871 870
872 current->sas_ss_sp = current->sas_ss_size = 0; 871 current->sas_ss_sp = current->sas_ss_size = 0;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index d672aa9f4061..3c1c9aaaca6b 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -159,8 +159,7 @@ fail:
159static struct page * ext2_get_page(struct inode *dir, unsigned long n) 159static struct page * ext2_get_page(struct inode *dir, unsigned long n)
160{ 160{
161 struct address_space *mapping = dir->i_mapping; 161 struct address_space *mapping = dir->i_mapping;
162 struct page *page = read_cache_page(mapping, n, 162 struct page *page = read_mapping_page(mapping, n, NULL);
163 (filler_t*)mapping->a_ops->readpage, NULL);
164 if (!IS_ERR(page)) { 163 if (!IS_ERR(page)) {
165 wait_on_page_locked(page); 164 wait_on_page_locked(page);
166 kmap(page); 165 kmap(page);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 7e30bae174ed..ee4ba759581e 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -39,7 +39,7 @@
39static void ext2_sync_super(struct super_block *sb, 39static void ext2_sync_super(struct super_block *sb,
40 struct ext2_super_block *es); 40 struct ext2_super_block *es);
41static int ext2_remount (struct super_block * sb, int * flags, char * data); 41static int ext2_remount (struct super_block * sb, int * flags, char * data);
42static int ext2_statfs (struct super_block * sb, struct kstatfs * buf); 42static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf);
43 43
44void ext2_error (struct super_block * sb, const char * function, 44void ext2_error (struct super_block * sb, const char * function,
45 const char * fmt, ...) 45 const char * fmt, ...)
@@ -834,9 +834,6 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
834 printk ("EXT2-fs: not enough memory\n"); 834 printk ("EXT2-fs: not enough memory\n");
835 goto failed_mount; 835 goto failed_mount;
836 } 836 }
837 percpu_counter_init(&sbi->s_freeblocks_counter);
838 percpu_counter_init(&sbi->s_freeinodes_counter);
839 percpu_counter_init(&sbi->s_dirs_counter);
840 bgl_lock_init(&sbi->s_blockgroup_lock); 837 bgl_lock_init(&sbi->s_blockgroup_lock);
841 sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts), 838 sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts),
842 GFP_KERNEL); 839 GFP_KERNEL);
@@ -863,6 +860,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
863 sbi->s_gdb_count = db_count; 860 sbi->s_gdb_count = db_count;
864 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 861 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
865 spin_lock_init(&sbi->s_next_gen_lock); 862 spin_lock_init(&sbi->s_next_gen_lock);
863
864 percpu_counter_init(&sbi->s_freeblocks_counter,
865 ext2_count_free_blocks(sb));
866 percpu_counter_init(&sbi->s_freeinodes_counter,
867 ext2_count_free_inodes(sb));
868 percpu_counter_init(&sbi->s_dirs_counter,
869 ext2_count_dirs(sb));
866 /* 870 /*
867 * set up enough so that it can read an inode 871 * set up enough so that it can read an inode
868 */ 872 */
@@ -874,24 +878,18 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
874 if (!sb->s_root) { 878 if (!sb->s_root) {
875 iput(root); 879 iput(root);
876 printk(KERN_ERR "EXT2-fs: get root inode failed\n"); 880 printk(KERN_ERR "EXT2-fs: get root inode failed\n");
877 goto failed_mount2; 881 goto failed_mount3;
878 } 882 }
879 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { 883 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
880 dput(sb->s_root); 884 dput(sb->s_root);
881 sb->s_root = NULL; 885 sb->s_root = NULL;
882 printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); 886 printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n");
883 goto failed_mount2; 887 goto failed_mount3;
884 } 888 }
885 if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) 889 if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
886 ext2_warning(sb, __FUNCTION__, 890 ext2_warning(sb, __FUNCTION__,
887 "mounting ext3 filesystem as ext2"); 891 "mounting ext3 filesystem as ext2");
888 ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); 892 ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
889 percpu_counter_mod(&sbi->s_freeblocks_counter,
890 ext2_count_free_blocks(sb));
891 percpu_counter_mod(&sbi->s_freeinodes_counter,
892 ext2_count_free_inodes(sb));
893 percpu_counter_mod(&sbi->s_dirs_counter,
894 ext2_count_dirs(sb));
895 return 0; 893 return 0;
896 894
897cantfind_ext2: 895cantfind_ext2:
@@ -899,7 +897,10 @@ cantfind_ext2:
899 printk("VFS: Can't find an ext2 filesystem on dev %s.\n", 897 printk("VFS: Can't find an ext2 filesystem on dev %s.\n",
900 sb->s_id); 898 sb->s_id);
901 goto failed_mount; 899 goto failed_mount;
902 900failed_mount3:
901 percpu_counter_destroy(&sbi->s_freeblocks_counter);
902 percpu_counter_destroy(&sbi->s_freeinodes_counter);
903 percpu_counter_destroy(&sbi->s_dirs_counter);
903failed_mount2: 904failed_mount2:
904 for (i = 0; i < db_count; i++) 905 for (i = 0; i < db_count; i++)
905 brelse(sbi->s_group_desc[i]); 906 brelse(sbi->s_group_desc[i]);
@@ -1038,8 +1039,9 @@ restore_opts:
1038 return err; 1039 return err;
1039} 1040}
1040 1041
1041static int ext2_statfs (struct super_block * sb, struct kstatfs * buf) 1042static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)
1042{ 1043{
1044 struct super_block *sb = dentry->d_sb;
1043 struct ext2_sb_info *sbi = EXT2_SB(sb); 1045 struct ext2_sb_info *sbi = EXT2_SB(sb);
1044 unsigned long overhead; 1046 unsigned long overhead;
1045 int i; 1047 int i;
@@ -1087,10 +1089,10 @@ static int ext2_statfs (struct super_block * sb, struct kstatfs * buf)
1087 return 0; 1089 return 0;
1088} 1090}
1089 1091
1090static struct super_block *ext2_get_sb(struct file_system_type *fs_type, 1092static int ext2_get_sb(struct file_system_type *fs_type,
1091 int flags, const char *dev_name, void *data) 1093 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1092{ 1094{
1093 return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super); 1095 return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super, mnt);
1094} 1096}
1095 1097
1096#ifdef CONFIG_QUOTA 1098#ifdef CONFIG_QUOTA
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index f8a5266ea1ff..a60cc6ec130f 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -58,7 +58,7 @@ static int ext3_sync_fs(struct super_block *sb, int wait);
58static const char *ext3_decode_error(struct super_block * sb, int errno, 58static const char *ext3_decode_error(struct super_block * sb, int errno,
59 char nbuf[16]); 59 char nbuf[16]);
60static int ext3_remount (struct super_block * sb, int * flags, char * data); 60static int ext3_remount (struct super_block * sb, int * flags, char * data);
61static int ext3_statfs (struct super_block * sb, struct kstatfs * buf); 61static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf);
62static void ext3_unlockfs(struct super_block *sb); 62static void ext3_unlockfs(struct super_block *sb);
63static void ext3_write_super (struct super_block * sb); 63static void ext3_write_super (struct super_block * sb);
64static void ext3_write_super_lockfs(struct super_block *sb); 64static void ext3_write_super_lockfs(struct super_block *sb);
@@ -499,20 +499,21 @@ static void ext3_clear_inode(struct inode *inode)
499{ 499{
500 struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; 500 struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info;
501#ifdef CONFIG_EXT3_FS_POSIX_ACL 501#ifdef CONFIG_EXT3_FS_POSIX_ACL
502 if (EXT3_I(inode)->i_acl && 502 if (EXT3_I(inode)->i_acl &&
503 EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) { 503 EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) {
504 posix_acl_release(EXT3_I(inode)->i_acl); 504 posix_acl_release(EXT3_I(inode)->i_acl);
505 EXT3_I(inode)->i_acl = EXT3_ACL_NOT_CACHED; 505 EXT3_I(inode)->i_acl = EXT3_ACL_NOT_CACHED;
506 } 506 }
507 if (EXT3_I(inode)->i_default_acl && 507 if (EXT3_I(inode)->i_default_acl &&
508 EXT3_I(inode)->i_default_acl != EXT3_ACL_NOT_CACHED) { 508 EXT3_I(inode)->i_default_acl != EXT3_ACL_NOT_CACHED) {
509 posix_acl_release(EXT3_I(inode)->i_default_acl); 509 posix_acl_release(EXT3_I(inode)->i_default_acl);
510 EXT3_I(inode)->i_default_acl = EXT3_ACL_NOT_CACHED; 510 EXT3_I(inode)->i_default_acl = EXT3_ACL_NOT_CACHED;
511 } 511 }
512#endif 512#endif
513 ext3_discard_reservation(inode); 513 ext3_discard_reservation(inode);
514 EXT3_I(inode)->i_block_alloc_info = NULL; 514 EXT3_I(inode)->i_block_alloc_info = NULL;
515 kfree(rsv); 515 if (unlikely(rsv))
516 kfree(rsv);
516} 517}
517 518
518static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb) 519static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb)
@@ -1579,9 +1580,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1579 goto failed_mount; 1580 goto failed_mount;
1580 } 1581 }
1581 1582
1582 percpu_counter_init(&sbi->s_freeblocks_counter);
1583 percpu_counter_init(&sbi->s_freeinodes_counter);
1584 percpu_counter_init(&sbi->s_dirs_counter);
1585 bgl_lock_init(&sbi->s_blockgroup_lock); 1583 bgl_lock_init(&sbi->s_blockgroup_lock);
1586 1584
1587 for (i = 0; i < db_count; i++) { 1585 for (i = 0; i < db_count; i++) {
@@ -1601,6 +1599,14 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1601 sbi->s_gdb_count = db_count; 1599 sbi->s_gdb_count = db_count;
1602 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 1600 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
1603 spin_lock_init(&sbi->s_next_gen_lock); 1601 spin_lock_init(&sbi->s_next_gen_lock);
1602
1603 percpu_counter_init(&sbi->s_freeblocks_counter,
1604 ext3_count_free_blocks(sb));
1605 percpu_counter_init(&sbi->s_freeinodes_counter,
1606 ext3_count_free_inodes(sb));
1607 percpu_counter_init(&sbi->s_dirs_counter,
1608 ext3_count_dirs(sb));
1609
1604 /* per fileystem reservation list head & lock */ 1610 /* per fileystem reservation list head & lock */
1605 spin_lock_init(&sbi->s_rsv_window_lock); 1611 spin_lock_init(&sbi->s_rsv_window_lock);
1606 sbi->s_rsv_window_root = RB_ROOT; 1612 sbi->s_rsv_window_root = RB_ROOT;
@@ -1639,16 +1645,16 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1639 if (!test_opt(sb, NOLOAD) && 1645 if (!test_opt(sb, NOLOAD) &&
1640 EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { 1646 EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
1641 if (ext3_load_journal(sb, es, journal_devnum)) 1647 if (ext3_load_journal(sb, es, journal_devnum))
1642 goto failed_mount2; 1648 goto failed_mount3;
1643 } else if (journal_inum) { 1649 } else if (journal_inum) {
1644 if (ext3_create_journal(sb, es, journal_inum)) 1650 if (ext3_create_journal(sb, es, journal_inum))
1645 goto failed_mount2; 1651 goto failed_mount3;
1646 } else { 1652 } else {
1647 if (!silent) 1653 if (!silent)
1648 printk (KERN_ERR 1654 printk (KERN_ERR
1649 "ext3: No journal on filesystem on %s\n", 1655 "ext3: No journal on filesystem on %s\n",
1650 sb->s_id); 1656 sb->s_id);
1651 goto failed_mount2; 1657 goto failed_mount3;
1652 } 1658 }
1653 1659
1654 /* We have now updated the journal if required, so we can 1660 /* We have now updated the journal if required, so we can
@@ -1671,7 +1677,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1671 (sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)) { 1677 (sbi->s_journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)) {
1672 printk(KERN_ERR "EXT3-fs: Journal does not support " 1678 printk(KERN_ERR "EXT3-fs: Journal does not support "
1673 "requested data journaling mode\n"); 1679 "requested data journaling mode\n");
1674 goto failed_mount3; 1680 goto failed_mount4;
1675 } 1681 }
1676 default: 1682 default:
1677 break; 1683 break;
@@ -1694,13 +1700,13 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1694 if (!sb->s_root) { 1700 if (!sb->s_root) {
1695 printk(KERN_ERR "EXT3-fs: get root inode failed\n"); 1701 printk(KERN_ERR "EXT3-fs: get root inode failed\n");
1696 iput(root); 1702 iput(root);
1697 goto failed_mount3; 1703 goto failed_mount4;
1698 } 1704 }
1699 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { 1705 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
1700 dput(sb->s_root); 1706 dput(sb->s_root);
1701 sb->s_root = NULL; 1707 sb->s_root = NULL;
1702 printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n"); 1708 printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n");
1703 goto failed_mount3; 1709 goto failed_mount4;
1704 } 1710 }
1705 1711
1706 ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); 1712 ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
@@ -1723,13 +1729,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1723 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": 1729 test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
1724 "writeback"); 1730 "writeback");
1725 1731
1726 percpu_counter_mod(&sbi->s_freeblocks_counter,
1727 ext3_count_free_blocks(sb));
1728 percpu_counter_mod(&sbi->s_freeinodes_counter,
1729 ext3_count_free_inodes(sb));
1730 percpu_counter_mod(&sbi->s_dirs_counter,
1731 ext3_count_dirs(sb));
1732
1733 lock_kernel(); 1732 lock_kernel();
1734 return 0; 1733 return 0;
1735 1734
@@ -1739,8 +1738,12 @@ cantfind_ext3:
1739 sb->s_id); 1738 sb->s_id);
1740 goto failed_mount; 1739 goto failed_mount;
1741 1740
1742failed_mount3: 1741failed_mount4:
1743 journal_destroy(sbi->s_journal); 1742 journal_destroy(sbi->s_journal);
1743failed_mount3:
1744 percpu_counter_destroy(&sbi->s_freeblocks_counter);
1745 percpu_counter_destroy(&sbi->s_freeinodes_counter);
1746 percpu_counter_destroy(&sbi->s_dirs_counter);
1744failed_mount2: 1747failed_mount2:
1745 for (i = 0; i < db_count; i++) 1748 for (i = 0; i < db_count; i++)
1746 brelse(sbi->s_group_desc[i]); 1749 brelse(sbi->s_group_desc[i]);
@@ -2318,8 +2321,9 @@ restore_opts:
2318 return err; 2321 return err;
2319} 2322}
2320 2323
2321static int ext3_statfs (struct super_block * sb, struct kstatfs * buf) 2324static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
2322{ 2325{
2326 struct super_block *sb = dentry->d_sb;
2323 struct ext3_sb_info *sbi = EXT3_SB(sb); 2327 struct ext3_sb_info *sbi = EXT3_SB(sb);
2324 struct ext3_super_block *es = sbi->s_es; 2328 struct ext3_super_block *es = sbi->s_es;
2325 unsigned long overhead; 2329 unsigned long overhead;
@@ -2646,10 +2650,10 @@ out:
2646 2650
2647#endif 2651#endif
2648 2652
2649static struct super_block *ext3_get_sb(struct file_system_type *fs_type, 2653static int ext3_get_sb(struct file_system_type *fs_type,
2650 int flags, const char *dev_name, void *data) 2654 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
2651{ 2655{
2652 return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super); 2656 return get_sb_bdev(fs_type, flags, dev_name, data, ext3_fill_super, mnt);
2653} 2657}
2654 2658
2655static struct file_system_type ext3_fs_type = { 2659static struct file_system_type ext3_fs_type = {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index c1ce284f8a94..7c35d582ec10 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -539,18 +539,18 @@ static int fat_remount(struct super_block *sb, int *flags, char *data)
539 return 0; 539 return 0;
540} 540}
541 541
542static int fat_statfs(struct super_block *sb, struct kstatfs *buf) 542static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
543{ 543{
544 struct msdos_sb_info *sbi = MSDOS_SB(sb); 544 struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
545 545
546 /* If the count of free cluster is still unknown, counts it here. */ 546 /* If the count of free cluster is still unknown, counts it here. */
547 if (sbi->free_clusters == -1) { 547 if (sbi->free_clusters == -1) {
548 int err = fat_count_free_clusters(sb); 548 int err = fat_count_free_clusters(dentry->d_sb);
549 if (err) 549 if (err)
550 return err; 550 return err;
551 } 551 }
552 552
553 buf->f_type = sb->s_magic; 553 buf->f_type = dentry->d_sb->s_magic;
554 buf->f_bsize = sbi->cluster_size; 554 buf->f_bsize = sbi->cluster_size;
555 buf->f_blocks = sbi->max_cluster - FAT_START_ENT; 555 buf->f_blocks = sbi->max_cluster - FAT_START_ENT;
556 buf->f_bfree = sbi->free_clusters; 556 buf->f_bfree = sbi->free_clusters;
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 944652e9dde1..308f2b6b5026 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -210,4 +210,3 @@ int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
210 return err; 210 return err;
211} 211}
212 212
213EXPORT_SYMBOL_GPL(fat_sync_bhs);
diff --git a/fs/file_table.c b/fs/file_table.c
index bcea1998b4de..506d5307108d 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -300,5 +300,5 @@ void __init files_init(unsigned long mempages)
300 if (files_stat.max_files < NR_FILE) 300 if (files_stat.max_files < NR_FILE)
301 files_stat.max_files = NR_FILE; 301 files_stat.max_files = NR_FILE;
302 files_defer_init(); 302 files_defer_init();
303 percpu_counter_init(&nr_files); 303 percpu_counter_init(&nr_files, 0);
304} 304}
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
index 50aae77651b2..c1be118fc067 100644
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -71,8 +71,7 @@ vxfs_get_page(struct address_space *mapping, u_long n)
71{ 71{
72 struct page * pp; 72 struct page * pp;
73 73
74 pp = read_cache_page(mapping, n, 74 pp = read_mapping_page(mapping, n, NULL);
75 (filler_t*)mapping->a_ops->readpage, NULL);
76 75
77 if (!IS_ERR(pp)) { 76 if (!IS_ERR(pp)) {
78 wait_on_page_locked(pp); 77 wait_on_page_locked(pp);
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index b44c916d24a1..b74b791fc23b 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -40,6 +40,7 @@
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/stat.h> 41#include <linux/stat.h>
42#include <linux/vfs.h> 42#include <linux/vfs.h>
43#include <linux/mount.h>
43 44
44#include "vxfs.h" 45#include "vxfs.h"
45#include "vxfs_extern.h" 46#include "vxfs_extern.h"
@@ -55,7 +56,7 @@ MODULE_ALIAS("vxfs"); /* makes mount -t vxfs autoload the module */
55 56
56 57
57static void vxfs_put_super(struct super_block *); 58static void vxfs_put_super(struct super_block *);
58static int vxfs_statfs(struct super_block *, struct kstatfs *); 59static int vxfs_statfs(struct dentry *, struct kstatfs *);
59static int vxfs_remount(struct super_block *, int *, char *); 60static int vxfs_remount(struct super_block *, int *, char *);
60 61
61static struct super_operations vxfs_super_ops = { 62static struct super_operations vxfs_super_ops = {
@@ -90,12 +91,12 @@ vxfs_put_super(struct super_block *sbp)
90 91
91/** 92/**
92 * vxfs_statfs - get filesystem information 93 * vxfs_statfs - get filesystem information
93 * @sbp: VFS superblock 94 * @dentry: VFS dentry to locate superblock
94 * @bufp: output buffer 95 * @bufp: output buffer
95 * 96 *
96 * Description: 97 * Description:
97 * vxfs_statfs fills the statfs buffer @bufp with information 98 * vxfs_statfs fills the statfs buffer @bufp with information
98 * about the filesystem described by @sbp. 99 * about the filesystem described by @dentry.
99 * 100 *
100 * Returns: 101 * Returns:
101 * Zero. 102 * Zero.
@@ -107,12 +108,12 @@ vxfs_put_super(struct super_block *sbp)
107 * This is everything but complete... 108 * This is everything but complete...
108 */ 109 */
109static int 110static int
110vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp) 111vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
111{ 112{
112 struct vxfs_sb_info *infp = VXFS_SBI(sbp); 113 struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb);
113 114
114 bufp->f_type = VXFS_SUPER_MAGIC; 115 bufp->f_type = VXFS_SUPER_MAGIC;
115 bufp->f_bsize = sbp->s_blocksize; 116 bufp->f_bsize = dentry->d_sb->s_blocksize;
116 bufp->f_blocks = infp->vsi_raw->vs_dsize; 117 bufp->f_blocks = infp->vsi_raw->vs_dsize;
117 bufp->f_bfree = infp->vsi_raw->vs_free; 118 bufp->f_bfree = infp->vsi_raw->vs_free;
118 bufp->f_bavail = 0; 119 bufp->f_bavail = 0;
@@ -241,10 +242,11 @@ out:
241/* 242/*
242 * The usual module blurb. 243 * The usual module blurb.
243 */ 244 */
244static struct super_block *vxfs_get_sb(struct file_system_type *fs_type, 245static int vxfs_get_sb(struct file_system_type *fs_type,
245 int flags, const char *dev_name, void *data) 246 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
246{ 247{
247 return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super); 248 return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super,
249 mnt);
248} 250}
249 251
250static struct file_system_type vxfs_fs_type = { 252static struct file_system_type vxfs_fs_type = {
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index f3fbe2d030f4..031b27a4bc9a 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -461,6 +461,8 @@ void sync_inodes_sb(struct super_block *sb, int wait)
461{ 461{
462 struct writeback_control wbc = { 462 struct writeback_control wbc = {
463 .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD, 463 .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD,
464 .range_start = 0,
465 .range_end = LLONG_MAX,
464 }; 466 };
465 unsigned long nr_dirty = read_page_state(nr_dirty); 467 unsigned long nr_dirty = read_page_state(nr_dirty);
466 unsigned long nr_unstable = read_page_state(nr_unstable); 468 unsigned long nr_unstable = read_page_state(nr_unstable);
@@ -559,6 +561,8 @@ int write_inode_now(struct inode *inode, int sync)
559 struct writeback_control wbc = { 561 struct writeback_control wbc = {
560 .nr_to_write = LONG_MAX, 562 .nr_to_write = LONG_MAX,
561 .sync_mode = WB_SYNC_ALL, 563 .sync_mode = WB_SYNC_ALL,
564 .range_start = 0,
565 .range_end = LLONG_MAX,
562 }; 566 };
563 567
564 if (!mapping_cap_writeback_dirty(inode->i_mapping)) 568 if (!mapping_cap_writeback_dirty(inode->i_mapping))
@@ -619,7 +623,6 @@ int generic_osync_inode(struct inode *inode, struct address_space *mapping, int
619 int need_write_inode_now = 0; 623 int need_write_inode_now = 0;
620 int err2; 624 int err2;
621 625
622 current->flags |= PF_SYNCWRITE;
623 if (what & OSYNC_DATA) 626 if (what & OSYNC_DATA)
624 err = filemap_fdatawrite(mapping); 627 err = filemap_fdatawrite(mapping);
625 if (what & (OSYNC_METADATA|OSYNC_DATA)) { 628 if (what & (OSYNC_METADATA|OSYNC_DATA)) {
@@ -632,7 +635,6 @@ int generic_osync_inode(struct inode *inode, struct address_space *mapping, int
632 if (!err) 635 if (!err)
633 err = err2; 636 err = err2;
634 } 637 }
635 current->flags &= ~PF_SYNCWRITE;
636 638
637 spin_lock(&inode_lock); 639 spin_lock(&inode_lock);
638 if ((inode->i_state & I_DIRTY) && 640 if ((inode->i_state & I_DIRTY) &&
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index fc342cf7c2cc..087f3b734f40 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -169,7 +169,7 @@ static int fuse_release(struct inode *inode, struct file *file)
169 return fuse_release_common(inode, file, 0); 169 return fuse_release_common(inode, file, 0);
170} 170}
171 171
172static int fuse_flush(struct file *file) 172static int fuse_flush(struct file *file, fl_owner_t id)
173{ 173{
174 struct inode *inode = file->f_dentry->d_inode; 174 struct inode *inode = file->f_dentry->d_inode;
175 struct fuse_conn *fc = get_fuse_conn(inode); 175 struct fuse_conn *fc = get_fuse_conn(inode);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 13ebe5780c93..815c824f4fc8 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -237,8 +237,9 @@ static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr
237 /* fsid is left zero */ 237 /* fsid is left zero */
238} 238}
239 239
240static int fuse_statfs(struct super_block *sb, struct kstatfs *buf) 240static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
241{ 241{
242 struct super_block *sb = dentry->d_sb;
242 struct fuse_conn *fc = get_fuse_conn_super(sb); 243 struct fuse_conn *fc = get_fuse_conn_super(sb);
243 struct fuse_req *req; 244 struct fuse_req *req;
244 struct fuse_statfs_out outarg; 245 struct fuse_statfs_out outarg;
@@ -570,11 +571,11 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
570 return err; 571 return err;
571} 572}
572 573
573static struct super_block *fuse_get_sb(struct file_system_type *fs_type, 574static int fuse_get_sb(struct file_system_type *fs_type,
574 int flags, const char *dev_name, 575 int flags, const char *dev_name,
575 void *raw_data) 576 void *raw_data, struct vfsmount *mnt)
576{ 577{
577 return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super); 578 return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super, mnt);
578} 579}
579 580
580static struct file_system_type fuse_fs_type = { 581static struct file_system_type fuse_fs_type = {
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
index 1e44dcfe49c4..13231dd5ce66 100644
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -280,7 +280,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
280 block = off >> PAGE_CACHE_SHIFT; 280 block = off >> PAGE_CACHE_SHIFT;
281 node->page_offset = off & ~PAGE_CACHE_MASK; 281 node->page_offset = off & ~PAGE_CACHE_MASK;
282 for (i = 0; i < tree->pages_per_bnode; i++) { 282 for (i = 0; i < tree->pages_per_bnode; i++) {
283 page = read_cache_page(mapping, block++, (filler_t *)mapping->a_ops->readpage, NULL); 283 page = read_mapping_page(mapping, block++, NULL);
284 if (IS_ERR(page)) 284 if (IS_ERR(page))
285 goto fail; 285 goto fail;
286 if (PageError(page)) { 286 if (PageError(page)) {
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index d20131ce4b95..400357994319 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -59,7 +59,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
59 unlock_new_inode(tree->inode); 59 unlock_new_inode(tree->inode);
60 60
61 mapping = tree->inode->i_mapping; 61 mapping = tree->inode->i_mapping;
62 page = read_cache_page(mapping, 0, (filler_t *)mapping->a_ops->readpage, NULL); 62 page = read_mapping_page(mapping, 0, NULL);
63 if (IS_ERR(page)) 63 if (IS_ERR(page))
64 goto free_tree; 64 goto free_tree;
65 65
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 1181d116117d..d9227bf14e86 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -80,8 +80,10 @@ static void hfs_put_super(struct super_block *sb)
80 * 80 *
81 * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks. 81 * changed f_files/f_ffree to reflect the fs_ablock/free_ablocks.
82 */ 82 */
83static int hfs_statfs(struct super_block *sb, struct kstatfs *buf) 83static int hfs_statfs(struct dentry *dentry, struct kstatfs *buf)
84{ 84{
85 struct super_block *sb = dentry->d_sb;
86
85 buf->f_type = HFS_SUPER_MAGIC; 87 buf->f_type = HFS_SUPER_MAGIC;
86 buf->f_bsize = sb->s_blocksize; 88 buf->f_bsize = sb->s_blocksize;
87 buf->f_blocks = (u32)HFS_SB(sb)->fs_ablocks * HFS_SB(sb)->fs_div; 89 buf->f_blocks = (u32)HFS_SB(sb)->fs_ablocks * HFS_SB(sb)->fs_div;
@@ -413,10 +415,11 @@ bail:
413 return res; 415 return res;
414} 416}
415 417
416static struct super_block *hfs_get_sb(struct file_system_type *fs_type, 418static int hfs_get_sb(struct file_system_type *fs_type,
417 int flags, const char *dev_name, void *data) 419 int flags, const char *dev_name, void *data,
420 struct vfsmount *mnt)
418{ 421{
419 return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super); 422 return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super, mnt);
420} 423}
421 424
422static struct file_system_type hfs_fs_type = { 425static struct file_system_type hfs_fs_type = {
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
index 9fb51632303c..d128a25b74d2 100644
--- a/fs/hfsplus/bitmap.c
+++ b/fs/hfsplus/bitmap.c
@@ -31,8 +31,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
31 dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); 31 dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len);
32 mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex); 32 mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
33 mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; 33 mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
34 page = read_cache_page(mapping, offset / PAGE_CACHE_BITS, 34 page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
35 (filler_t *)mapping->a_ops->readpage, NULL);
36 pptr = kmap(page); 35 pptr = kmap(page);
37 curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; 36 curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
38 i = offset % 32; 37 i = offset % 32;
@@ -72,8 +71,8 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
72 offset += PAGE_CACHE_BITS; 71 offset += PAGE_CACHE_BITS;
73 if (offset >= size) 72 if (offset >= size)
74 break; 73 break;
75 page = read_cache_page(mapping, offset / PAGE_CACHE_BITS, 74 page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
76 (filler_t *)mapping->a_ops->readpage, NULL); 75 NULL);
77 curr = pptr = kmap(page); 76 curr = pptr = kmap(page);
78 if ((size ^ offset) / PAGE_CACHE_BITS) 77 if ((size ^ offset) / PAGE_CACHE_BITS)
79 end = pptr + PAGE_CACHE_BITS / 32; 78 end = pptr + PAGE_CACHE_BITS / 32;
@@ -119,8 +118,8 @@ found:
119 set_page_dirty(page); 118 set_page_dirty(page);
120 kunmap(page); 119 kunmap(page);
121 offset += PAGE_CACHE_BITS; 120 offset += PAGE_CACHE_BITS;
122 page = read_cache_page(mapping, offset / PAGE_CACHE_BITS, 121 page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
123 (filler_t *)mapping->a_ops->readpage, NULL); 122 NULL);
124 pptr = kmap(page); 123 pptr = kmap(page);
125 curr = pptr; 124 curr = pptr;
126 end = pptr + PAGE_CACHE_BITS / 32; 125 end = pptr + PAGE_CACHE_BITS / 32;
@@ -167,7 +166,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
167 mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex); 166 mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
168 mapping = HFSPLUS_SB(sb).alloc_file->i_mapping; 167 mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
169 pnr = offset / PAGE_CACHE_BITS; 168 pnr = offset / PAGE_CACHE_BITS;
170 page = read_cache_page(mapping, pnr, (filler_t *)mapping->a_ops->readpage, NULL); 169 page = read_mapping_page(mapping, pnr, NULL);
171 pptr = kmap(page); 170 pptr = kmap(page);
172 curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; 171 curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
173 end = pptr + PAGE_CACHE_BITS / 32; 172 end = pptr + PAGE_CACHE_BITS / 32;
@@ -199,7 +198,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
199 break; 198 break;
200 set_page_dirty(page); 199 set_page_dirty(page);
201 kunmap(page); 200 kunmap(page);
202 page = read_cache_page(mapping, ++pnr, (filler_t *)mapping->a_ops->readpage, NULL); 201 page = read_mapping_page(mapping, ++pnr, NULL);
203 pptr = kmap(page); 202 pptr = kmap(page);
204 curr = pptr; 203 curr = pptr;
205 end = pptr + PAGE_CACHE_BITS / 32; 204 end = pptr + PAGE_CACHE_BITS / 32;
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index 746abc9ecf70..77bf434da679 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -440,7 +440,7 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid)
440 block = off >> PAGE_CACHE_SHIFT; 440 block = off >> PAGE_CACHE_SHIFT;
441 node->page_offset = off & ~PAGE_CACHE_MASK; 441 node->page_offset = off & ~PAGE_CACHE_MASK;
442 for (i = 0; i < tree->pages_per_bnode; block++, i++) { 442 for (i = 0; i < tree->pages_per_bnode; block++, i++) {
443 page = read_cache_page(mapping, block, (filler_t *)mapping->a_ops->readpage, NULL); 443 page = read_mapping_page(mapping, block, NULL);
444 if (IS_ERR(page)) 444 if (IS_ERR(page))
445 goto fail; 445 goto fail;
446 if (PageError(page)) { 446 if (PageError(page)) {
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index effa8991999c..cfc852fdd1b5 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -38,7 +38,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
38 goto free_tree; 38 goto free_tree;
39 39
40 mapping = tree->inode->i_mapping; 40 mapping = tree->inode->i_mapping;
41 page = read_cache_page(mapping, 0, (filler_t *)mapping->a_ops->readpage, NULL); 41 page = read_mapping_page(mapping, 0, NULL);
42 if (IS_ERR(page)) 42 if (IS_ERR(page))
43 goto free_tree; 43 goto free_tree;
44 44
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 7843f792a4b7..0a92fa2336a2 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -212,8 +212,10 @@ static void hfsplus_put_super(struct super_block *sb)
212 sb->s_fs_info = NULL; 212 sb->s_fs_info = NULL;
213} 213}
214 214
215static int hfsplus_statfs(struct super_block *sb, struct kstatfs *buf) 215static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf)
216{ 216{
217 struct super_block *sb = dentry->d_sb;
218
217 buf->f_type = HFSPLUS_SUPER_MAGIC; 219 buf->f_type = HFSPLUS_SUPER_MAGIC;
218 buf->f_bsize = sb->s_blocksize; 220 buf->f_bsize = sb->s_blocksize;
219 buf->f_blocks = HFSPLUS_SB(sb).total_blocks << HFSPLUS_SB(sb).fs_shift; 221 buf->f_blocks = HFSPLUS_SB(sb).total_blocks << HFSPLUS_SB(sb).fs_shift;
@@ -450,10 +452,12 @@ static void hfsplus_destroy_inode(struct inode *inode)
450 452
451#define HFSPLUS_INODE_SIZE sizeof(struct hfsplus_inode_info) 453#define HFSPLUS_INODE_SIZE sizeof(struct hfsplus_inode_info)
452 454
453static struct super_block *hfsplus_get_sb(struct file_system_type *fs_type, 455static int hfsplus_get_sb(struct file_system_type *fs_type,
454 int flags, const char *dev_name, void *data) 456 int flags, const char *dev_name, void *data,
457 struct vfsmount *mnt)
455{ 458{
456 return get_sb_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super); 459 return get_sb_bdev(fs_type, flags, dev_name, data, hfsplus_fill_super,
460 mnt);
457} 461}
458 462
459static struct file_system_type hfsplus_fs_type = { 463static struct file_system_type hfsplus_fs_type = {
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index bf0f8e16e433..8e0d37743e7c 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -239,7 +239,7 @@ static int read_inode(struct inode *ino)
239 return(err); 239 return(err);
240} 240}
241 241
242int hostfs_statfs(struct super_block *sb, struct kstatfs *sf) 242int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
243{ 243{
244 /* do_statfs uses struct statfs64 internally, but the linux kernel 244 /* do_statfs uses struct statfs64 internally, but the linux kernel
245 * struct statfs still has 32-bit versions for most of these fields, 245 * struct statfs still has 32-bit versions for most of these fields,
@@ -252,7 +252,7 @@ int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
252 long long f_files; 252 long long f_files;
253 long long f_ffree; 253 long long f_ffree;
254 254
255 err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename, 255 err = do_statfs(HOSTFS_I(dentry->d_sb->s_root->d_inode)->host_filename,
256 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, 256 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
257 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 257 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
258 &sf->f_namelen, sf->f_spare); 258 &sf->f_namelen, sf->f_spare);
@@ -993,11 +993,11 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
993 return(err); 993 return(err);
994} 994}
995 995
996static struct super_block *hostfs_read_sb(struct file_system_type *type, 996static int hostfs_read_sb(struct file_system_type *type,
997 int flags, const char *dev_name, 997 int flags, const char *dev_name,
998 void *data) 998 void *data, struct vfsmount *mnt)
999{ 999{
1000 return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common)); 1000 return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt);
1001} 1001}
1002 1002
1003static struct file_system_type hostfs_type = { 1003static struct file_system_type hostfs_type = {
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index d72d8c87c996..f798480a363f 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -135,8 +135,9 @@ static unsigned count_bitmaps(struct super_block *s)
135 return count; 135 return count;
136} 136}
137 137
138static int hpfs_statfs(struct super_block *s, struct kstatfs *buf) 138static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf)
139{ 139{
140 struct super_block *s = dentry->d_sb;
140 struct hpfs_sb_info *sbi = hpfs_sb(s); 141 struct hpfs_sb_info *sbi = hpfs_sb(s);
141 lock_kernel(); 142 lock_kernel();
142 143
@@ -662,10 +663,11 @@ bail0:
662 return -EINVAL; 663 return -EINVAL;
663} 664}
664 665
665static struct super_block *hpfs_get_sb(struct file_system_type *fs_type, 666static int hpfs_get_sb(struct file_system_type *fs_type,
666 int flags, const char *dev_name, void *data) 667 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
667{ 668{
668 return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super); 669 return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super,
670 mnt);
669} 671}
670 672
671static struct file_system_type hpfs_fs_type = { 673static struct file_system_type hpfs_fs_type = {
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index 5e6363be246f..3a9bdf58166f 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -616,7 +616,7 @@ static const struct file_operations hppfs_dir_fops = {
616 .fsync = hppfs_fsync, 616 .fsync = hppfs_fsync,
617}; 617};
618 618
619static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf) 619static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
620{ 620{
621 sf->f_blocks = 0; 621 sf->f_blocks = 0;
622 sf->f_bfree = 0; 622 sf->f_bfree = 0;
@@ -769,11 +769,11 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
769 return(err); 769 return(err);
770} 770}
771 771
772static struct super_block *hppfs_read_super(struct file_system_type *type, 772static int hppfs_read_super(struct file_system_type *type,
773 int flags, const char *dev_name, 773 int flags, const char *dev_name,
774 void *data) 774 void *data, struct vfsmount *mnt)
775{ 775{
776 return(get_sb_nodev(type, flags, data, hppfs_fill_super)); 776 return get_sb_nodev(type, flags, data, hppfs_fill_super, mnt);
777} 777}
778 778
779static struct file_system_type hppfs_type = { 779static struct file_system_type hppfs_type = {
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 3a5b4e923455..e6410d8edd0e 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -59,7 +59,6 @@ static void huge_pagevec_release(struct pagevec *pvec)
59static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) 59static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
60{ 60{
61 struct inode *inode = file->f_dentry->d_inode; 61 struct inode *inode = file->f_dentry->d_inode;
62 struct hugetlbfs_inode_info *info = HUGETLBFS_I(inode);
63 loff_t len, vma_len; 62 loff_t len, vma_len;
64 int ret; 63 int ret;
65 64
@@ -87,9 +86,10 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
87 if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size) 86 if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size)
88 goto out; 87 goto out;
89 88
90 if (vma->vm_flags & VM_MAYSHARE) 89 if (vma->vm_flags & VM_MAYSHARE &&
91 if (hugetlb_extend_reservation(info, len >> HPAGE_SHIFT) != 0) 90 hugetlb_reserve_pages(inode, vma->vm_pgoff >> (HPAGE_SHIFT-PAGE_SHIFT),
92 goto out; 91 len >> HPAGE_SHIFT))
92 goto out;
93 93
94 ret = 0; 94 ret = 0;
95 hugetlb_prefault_arch_hook(vma->vm_mm); 95 hugetlb_prefault_arch_hook(vma->vm_mm);
@@ -195,12 +195,8 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart)
195 const pgoff_t start = lstart >> HPAGE_SHIFT; 195 const pgoff_t start = lstart >> HPAGE_SHIFT;
196 struct pagevec pvec; 196 struct pagevec pvec;
197 pgoff_t next; 197 pgoff_t next;
198 int i; 198 int i, freed = 0;
199 199
200 hugetlb_truncate_reservation(HUGETLBFS_I(inode),
201 lstart >> HPAGE_SHIFT);
202 if (!mapping->nrpages)
203 return;
204 pagevec_init(&pvec, 0); 200 pagevec_init(&pvec, 0);
205 next = start; 201 next = start;
206 while (1) { 202 while (1) {
@@ -221,10 +217,12 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart)
221 truncate_huge_page(page); 217 truncate_huge_page(page);
222 unlock_page(page); 218 unlock_page(page);
223 hugetlb_put_quota(mapping); 219 hugetlb_put_quota(mapping);
220 freed++;
224 } 221 }
225 huge_pagevec_release(&pvec); 222 huge_pagevec_release(&pvec);
226 } 223 }
227 BUG_ON(!lstart && mapping->nrpages); 224 BUG_ON(!lstart && mapping->nrpages);
225 hugetlb_unreserve_pages(inode, start, freed);
228} 226}
229 227
230static void hugetlbfs_delete_inode(struct inode *inode) 228static void hugetlbfs_delete_inode(struct inode *inode)
@@ -366,6 +364,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
366 inode->i_mapping->a_ops = &hugetlbfs_aops; 364 inode->i_mapping->a_ops = &hugetlbfs_aops;
367 inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info; 365 inode->i_mapping->backing_dev_info =&hugetlbfs_backing_dev_info;
368 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 366 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
367 INIT_LIST_HEAD(&inode->i_mapping->private_list);
369 info = HUGETLBFS_I(inode); 368 info = HUGETLBFS_I(inode);
370 mpol_shared_policy_init(&info->policy, MPOL_DEFAULT, NULL); 369 mpol_shared_policy_init(&info->policy, MPOL_DEFAULT, NULL);
371 switch (mode & S_IFMT) { 370 switch (mode & S_IFMT) {
@@ -467,9 +466,9 @@ static int hugetlbfs_set_page_dirty(struct page *page)
467 return 0; 466 return 0;
468} 467}
469 468
470static int hugetlbfs_statfs(struct super_block *sb, struct kstatfs *buf) 469static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf)
471{ 470{
472 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb); 471 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(dentry->d_sb);
473 472
474 buf->f_type = HUGETLBFS_MAGIC; 473 buf->f_type = HUGETLBFS_MAGIC;
475 buf->f_bsize = HPAGE_SIZE; 474 buf->f_bsize = HPAGE_SIZE;
@@ -538,7 +537,6 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
538 hugetlbfs_inc_free_inodes(sbinfo); 537 hugetlbfs_inc_free_inodes(sbinfo);
539 return NULL; 538 return NULL;
540 } 539 }
541 p->prereserved_hpages = 0;
542 return &p->vfs_inode; 540 return &p->vfs_inode;
543} 541}
544 542
@@ -723,10 +721,10 @@ void hugetlb_put_quota(struct address_space *mapping)
723 } 721 }
724} 722}
725 723
726static struct super_block *hugetlbfs_get_sb(struct file_system_type *fs_type, 724static int hugetlbfs_get_sb(struct file_system_type *fs_type,
727 int flags, const char *dev_name, void *data) 725 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
728{ 726{
729 return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super); 727 return get_sb_nodev(fs_type, flags, data, hugetlbfs_fill_super, mnt);
730} 728}
731 729
732static struct file_system_type hugetlbfs_fs_type = { 730static struct file_system_type hugetlbfs_fs_type = {
@@ -781,8 +779,7 @@ struct file *hugetlb_zero_setup(size_t size)
781 goto out_file; 779 goto out_file;
782 780
783 error = -ENOMEM; 781 error = -ENOMEM;
784 if (hugetlb_extend_reservation(HUGETLBFS_I(inode), 782 if (hugetlb_reserve_pages(inode, 0, size >> HPAGE_SHIFT))
785 size >> HPAGE_SHIFT) != 0)
786 goto out_inode; 783 goto out_inode;
787 784
788 d_instantiate(dentry, inode); 785 d_instantiate(dentry, inode);
diff --git a/fs/inotify_user.c b/fs/inotify_user.c
index 9e9931e2badd..f2386442adee 100644
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -672,11 +672,11 @@ out:
672 return ret; 672 return ret;
673} 673}
674 674
675static struct super_block * 675static int
676inotify_get_sb(struct file_system_type *fs_type, int flags, 676inotify_get_sb(struct file_system_type *fs_type, int flags,
677 const char *dev_name, void *data) 677 const char *dev_name, void *data, struct vfsmount *mnt)
678{ 678{
679 return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA); 679 return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA, mnt);
680} 680}
681 681
682static struct file_system_type inotify_fs_type = { 682static struct file_system_type inotify_fs_type = {
diff --git a/fs/ioprio.c b/fs/ioprio.c
index ca77008146c0..7fa76ed53c10 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -24,15 +24,21 @@
24#include <linux/blkdev.h> 24#include <linux/blkdev.h>
25#include <linux/capability.h> 25#include <linux/capability.h>
26#include <linux/syscalls.h> 26#include <linux/syscalls.h>
27#include <linux/security.h>
27 28
28static int set_task_ioprio(struct task_struct *task, int ioprio) 29static int set_task_ioprio(struct task_struct *task, int ioprio)
29{ 30{
31 int err;
30 struct io_context *ioc; 32 struct io_context *ioc;
31 33
32 if (task->uid != current->euid && 34 if (task->uid != current->euid &&
33 task->uid != current->uid && !capable(CAP_SYS_NICE)) 35 task->uid != current->uid && !capable(CAP_SYS_NICE))
34 return -EPERM; 36 return -EPERM;
35 37
38 err = security_task_setioprio(task, ioprio);
39 if (err)
40 return err;
41
36 task_lock(task); 42 task_lock(task);
37 43
38 task->ioprio = ioprio; 44 task->ioprio = ioprio;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 70adbb98bad1..3f9c8ba1fa1f 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -56,7 +56,7 @@ static void isofs_put_super(struct super_block *sb)
56} 56}
57 57
58static void isofs_read_inode(struct inode *); 58static void isofs_read_inode(struct inode *);
59static int isofs_statfs (struct super_block *, struct kstatfs *); 59static int isofs_statfs (struct dentry *, struct kstatfs *);
60 60
61static kmem_cache_t *isofs_inode_cachep; 61static kmem_cache_t *isofs_inode_cachep;
62 62
@@ -901,8 +901,10 @@ out_freesbi:
901 return -EINVAL; 901 return -EINVAL;
902} 902}
903 903
904static int isofs_statfs (struct super_block *sb, struct kstatfs *buf) 904static int isofs_statfs (struct dentry *dentry, struct kstatfs *buf)
905{ 905{
906 struct super_block *sb = dentry->d_sb;
907
906 buf->f_type = ISOFS_SUPER_MAGIC; 908 buf->f_type = ISOFS_SUPER_MAGIC;
907 buf->f_bsize = sb->s_blocksize; 909 buf->f_bsize = sb->s_blocksize;
908 buf->f_blocks = (ISOFS_SB(sb)->s_nzones 910 buf->f_blocks = (ISOFS_SB(sb)->s_nzones
@@ -1399,10 +1401,11 @@ struct inode *isofs_iget(struct super_block *sb,
1399 return inode; 1401 return inode;
1400} 1402}
1401 1403
1402static struct super_block *isofs_get_sb(struct file_system_type *fs_type, 1404static int isofs_get_sb(struct file_system_type *fs_type,
1403 int flags, const char *dev_name, void *data) 1405 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1404{ 1406{
1405 return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super); 1407 return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super,
1408 mnt);
1406} 1409}
1407 1410
1408static struct file_system_type iso9660_fs_type = { 1411static struct file_system_type iso9660_fs_type = {
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 3f5102b069db..47678a26c13b 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -24,29 +24,67 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25 25
26/* 26/*
27 * Unlink a buffer from a transaction. 27 * Unlink a buffer from a transaction checkpoint list.
28 * 28 *
29 * Called with j_list_lock held. 29 * Called with j_list_lock held.
30 */ 30 */
31 31static inline void __buffer_unlink_first(struct journal_head *jh)
32static inline void __buffer_unlink(struct journal_head *jh)
33{ 32{
34 transaction_t *transaction; 33 transaction_t *transaction = jh->b_cp_transaction;
35
36 transaction = jh->b_cp_transaction;
37 jh->b_cp_transaction = NULL;
38 34
39 jh->b_cpnext->b_cpprev = jh->b_cpprev; 35 jh->b_cpnext->b_cpprev = jh->b_cpprev;
40 jh->b_cpprev->b_cpnext = jh->b_cpnext; 36 jh->b_cpprev->b_cpnext = jh->b_cpnext;
41 if (transaction->t_checkpoint_list == jh) 37 if (transaction->t_checkpoint_list == jh) {
42 transaction->t_checkpoint_list = jh->b_cpnext; 38 transaction->t_checkpoint_list = jh->b_cpnext;
43 if (transaction->t_checkpoint_list == jh) 39 if (transaction->t_checkpoint_list == jh)
44 transaction->t_checkpoint_list = NULL; 40 transaction->t_checkpoint_list = NULL;
41 }
42}
43
44/*
45 * Unlink a buffer from a transaction checkpoint(io) list.
46 *
47 * Called with j_list_lock held.
48 */
49static inline void __buffer_unlink(struct journal_head *jh)
50{
51 transaction_t *transaction = jh->b_cp_transaction;
52
53 __buffer_unlink_first(jh);
54 if (transaction->t_checkpoint_io_list == jh) {
55 transaction->t_checkpoint_io_list = jh->b_cpnext;
56 if (transaction->t_checkpoint_io_list == jh)
57 transaction->t_checkpoint_io_list = NULL;
58 }
59}
60
61/*
62 * Move a buffer from the checkpoint list to the checkpoint io list
63 *
64 * Called with j_list_lock held
65 */
66static inline void __buffer_relink_io(struct journal_head *jh)
67{
68 transaction_t *transaction = jh->b_cp_transaction;
69
70 __buffer_unlink_first(jh);
71
72 if (!transaction->t_checkpoint_io_list) {
73 jh->b_cpnext = jh->b_cpprev = jh;
74 } else {
75 jh->b_cpnext = transaction->t_checkpoint_io_list;
76 jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
77 jh->b_cpprev->b_cpnext = jh;
78 jh->b_cpnext->b_cpprev = jh;
79 }
80 transaction->t_checkpoint_io_list = jh;
45} 81}
46 82
47/* 83/*
48 * Try to release a checkpointed buffer from its transaction. 84 * Try to release a checkpointed buffer from its transaction.
49 * Returns 1 if we released it. 85 * Returns 1 if we released it and 2 if we also released the
86 * whole transaction.
87 *
50 * Requires j_list_lock 88 * Requires j_list_lock
51 * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it 89 * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
52 */ 90 */
@@ -57,12 +95,11 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
57 95
58 if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) { 96 if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) {
59 JBUFFER_TRACE(jh, "remove from checkpoint list"); 97 JBUFFER_TRACE(jh, "remove from checkpoint list");
60 __journal_remove_checkpoint(jh); 98 ret = __journal_remove_checkpoint(jh) + 1;
61 jbd_unlock_bh_state(bh); 99 jbd_unlock_bh_state(bh);
62 journal_remove_journal_head(bh); 100 journal_remove_journal_head(bh);
63 BUFFER_TRACE(bh, "release"); 101 BUFFER_TRACE(bh, "release");
64 __brelse(bh); 102 __brelse(bh);
65 ret = 1;
66 } else { 103 } else {
67 jbd_unlock_bh_state(bh); 104 jbd_unlock_bh_state(bh);
68 } 105 }
@@ -117,83 +154,54 @@ static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh)
117} 154}
118 155
119/* 156/*
120 * Clean up a transaction's checkpoint list. 157 * Clean up transaction's list of buffers submitted for io.
121 * 158 * We wait for any pending IO to complete and remove any clean
122 * We wait for any pending IO to complete and make sure any clean 159 * buffers. Note that we take the buffers in the opposite ordering
123 * buffers are removed from the transaction. 160 * from the one in which they were submitted for IO.
124 *
125 * Return 1 if we performed any actions which might have destroyed the
126 * checkpoint. (journal_remove_checkpoint() deletes the transaction when
127 * the last checkpoint buffer is cleansed)
128 * 161 *
129 * Called with j_list_lock held. 162 * Called with j_list_lock held.
130 */ 163 */
131static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) 164static void __wait_cp_io(journal_t *journal, transaction_t *transaction)
132{ 165{
133 struct journal_head *jh, *next_jh, *last_jh; 166 struct journal_head *jh;
134 struct buffer_head *bh; 167 struct buffer_head *bh;
135 int ret = 0; 168 tid_t this_tid;
136 169 int released = 0;
137 assert_spin_locked(&journal->j_list_lock); 170
138 jh = transaction->t_checkpoint_list; 171 this_tid = transaction->t_tid;
139 if (!jh) 172restart:
140 return 0; 173 /* Did somebody clean up the transaction in the meanwhile? */
141 174 if (journal->j_checkpoint_transactions != transaction ||
142 last_jh = jh->b_cpprev; 175 transaction->t_tid != this_tid)
143 next_jh = jh; 176 return;
144 do { 177 while (!released && transaction->t_checkpoint_io_list) {
145 jh = next_jh; 178 jh = transaction->t_checkpoint_io_list;
146 bh = jh2bh(jh); 179 bh = jh2bh(jh);
180 if (!jbd_trylock_bh_state(bh)) {
181 jbd_sync_bh(journal, bh);
182 spin_lock(&journal->j_list_lock);
183 goto restart;
184 }
147 if (buffer_locked(bh)) { 185 if (buffer_locked(bh)) {
148 atomic_inc(&bh->b_count); 186 atomic_inc(&bh->b_count);
149 spin_unlock(&journal->j_list_lock); 187 spin_unlock(&journal->j_list_lock);
188 jbd_unlock_bh_state(bh);
150 wait_on_buffer(bh); 189 wait_on_buffer(bh);
151 /* the journal_head may have gone by now */ 190 /* the journal_head may have gone by now */
152 BUFFER_TRACE(bh, "brelse"); 191 BUFFER_TRACE(bh, "brelse");
153 __brelse(bh); 192 __brelse(bh);
154 goto out_return_1; 193 spin_lock(&journal->j_list_lock);
194 goto restart;
155 } 195 }
156
157 /* 196 /*
158 * This is foul 197 * Now in whatever state the buffer currently is, we know that
198 * it has been written out and so we can drop it from the list
159 */ 199 */
160 if (!jbd_trylock_bh_state(bh)) { 200 released = __journal_remove_checkpoint(jh);
161 jbd_sync_bh(journal, bh); 201 jbd_unlock_bh_state(bh);
162 goto out_return_1; 202 journal_remove_journal_head(bh);
163 } 203 __brelse(bh);
164 204 }
165 if (jh->b_transaction != NULL) {
166 transaction_t *t = jh->b_transaction;
167 tid_t tid = t->t_tid;
168
169 spin_unlock(&journal->j_list_lock);
170 jbd_unlock_bh_state(bh);
171 log_start_commit(journal, tid);
172 log_wait_commit(journal, tid);
173 goto out_return_1;
174 }
175
176 /*
177 * AKPM: I think the buffer_jbddirty test is redundant - it
178 * shouldn't have NULL b_transaction?
179 */
180 next_jh = jh->b_cpnext;
181 if (!buffer_dirty(bh) && !buffer_jbddirty(bh)) {
182 BUFFER_TRACE(bh, "remove from checkpoint");
183 __journal_remove_checkpoint(jh);
184 jbd_unlock_bh_state(bh);
185 journal_remove_journal_head(bh);
186 __brelse(bh);
187 ret = 1;
188 } else {
189 jbd_unlock_bh_state(bh);
190 }
191 } while (jh != last_jh);
192
193 return ret;
194out_return_1:
195 spin_lock(&journal->j_list_lock);
196 return 1;
197} 205}
198 206
199#define NR_BATCH 64 207#define NR_BATCH 64
@@ -203,9 +211,7 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
203{ 211{
204 int i; 212 int i;
205 213
206 spin_unlock(&journal->j_list_lock);
207 ll_rw_block(SWRITE, *batch_count, bhs); 214 ll_rw_block(SWRITE, *batch_count, bhs);
208 spin_lock(&journal->j_list_lock);
209 for (i = 0; i < *batch_count; i++) { 215 for (i = 0; i < *batch_count; i++) {
210 struct buffer_head *bh = bhs[i]; 216 struct buffer_head *bh = bhs[i];
211 clear_buffer_jwrite(bh); 217 clear_buffer_jwrite(bh);
@@ -221,19 +227,43 @@ __flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
221 * Return 1 if something happened which requires us to abort the current 227 * Return 1 if something happened which requires us to abort the current
222 * scan of the checkpoint list. 228 * scan of the checkpoint list.
223 * 229 *
224 * Called with j_list_lock held. 230 * Called with j_list_lock held and drops it if 1 is returned
225 * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it 231 * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
226 */ 232 */
227static int __flush_buffer(journal_t *journal, struct journal_head *jh, 233static int __process_buffer(journal_t *journal, struct journal_head *jh,
228 struct buffer_head **bhs, int *batch_count, 234 struct buffer_head **bhs, int *batch_count)
229 int *drop_count)
230{ 235{
231 struct buffer_head *bh = jh2bh(jh); 236 struct buffer_head *bh = jh2bh(jh);
232 int ret = 0; 237 int ret = 0;
233 238
234 if (buffer_dirty(bh) && !buffer_locked(bh) && jh->b_jlist == BJ_None) { 239 if (buffer_locked(bh)) {
235 J_ASSERT_JH(jh, jh->b_transaction == NULL); 240 atomic_inc(&bh->b_count);
241 spin_unlock(&journal->j_list_lock);
242 jbd_unlock_bh_state(bh);
243 wait_on_buffer(bh);
244 /* the journal_head may have gone by now */
245 BUFFER_TRACE(bh, "brelse");
246 __brelse(bh);
247 ret = 1;
248 } else if (jh->b_transaction != NULL) {
249 transaction_t *t = jh->b_transaction;
250 tid_t tid = t->t_tid;
236 251
252 spin_unlock(&journal->j_list_lock);
253 jbd_unlock_bh_state(bh);
254 log_start_commit(journal, tid);
255 log_wait_commit(journal, tid);
256 ret = 1;
257 } else if (!buffer_dirty(bh)) {
258 J_ASSERT_JH(jh, !buffer_jbddirty(bh));
259 BUFFER_TRACE(bh, "remove from checkpoint");
260 __journal_remove_checkpoint(jh);
261 spin_unlock(&journal->j_list_lock);
262 jbd_unlock_bh_state(bh);
263 journal_remove_journal_head(bh);
264 __brelse(bh);
265 ret = 1;
266 } else {
237 /* 267 /*
238 * Important: we are about to write the buffer, and 268 * Important: we are about to write the buffer, and
239 * possibly block, while still holding the journal lock. 269 * possibly block, while still holding the journal lock.
@@ -246,45 +276,30 @@ static int __flush_buffer(journal_t *journal, struct journal_head *jh,
246 J_ASSERT_BH(bh, !buffer_jwrite(bh)); 276 J_ASSERT_BH(bh, !buffer_jwrite(bh));
247 set_buffer_jwrite(bh); 277 set_buffer_jwrite(bh);
248 bhs[*batch_count] = bh; 278 bhs[*batch_count] = bh;
279 __buffer_relink_io(jh);
249 jbd_unlock_bh_state(bh); 280 jbd_unlock_bh_state(bh);
250 (*batch_count)++; 281 (*batch_count)++;
251 if (*batch_count == NR_BATCH) { 282 if (*batch_count == NR_BATCH) {
283 spin_unlock(&journal->j_list_lock);
252 __flush_batch(journal, bhs, batch_count); 284 __flush_batch(journal, bhs, batch_count);
253 ret = 1; 285 ret = 1;
254 } 286 }
255 } else {
256 int last_buffer = 0;
257 if (jh->b_cpnext == jh) {
258 /* We may be about to drop the transaction. Tell the
259 * caller that the lists have changed.
260 */
261 last_buffer = 1;
262 }
263 if (__try_to_free_cp_buf(jh)) {
264 (*drop_count)++;
265 ret = last_buffer;
266 }
267 } 287 }
268 return ret; 288 return ret;
269} 289}
270 290
271/* 291/*
272 * Perform an actual checkpoint. We don't write out only enough to 292 * Perform an actual checkpoint. We take the first transaction on the
273 * satisfy the current blocked requests: rather we submit a reasonably 293 * list of transactions to be checkpointed and send all its buffers
274 * sized chunk of the outstanding data to disk at once for 294 * to disk. We submit larger chunks of data at once.
275 * efficiency. __log_wait_for_space() will retry if we didn't free enough.
276 * 295 *
277 * However, we _do_ take into account the amount requested so that once
278 * the IO has been queued, we can return as soon as enough of it has
279 * completed to disk.
280 *
281 * The journal should be locked before calling this function. 296 * The journal should be locked before calling this function.
282 */ 297 */
283int log_do_checkpoint(journal_t *journal) 298int log_do_checkpoint(journal_t *journal)
284{ 299{
300 transaction_t *transaction;
301 tid_t this_tid;
285 int result; 302 int result;
286 int batch_count = 0;
287 struct buffer_head *bhs[NR_BATCH];
288 303
289 jbd_debug(1, "Start checkpoint\n"); 304 jbd_debug(1, "Start checkpoint\n");
290 305
@@ -299,79 +314,68 @@ int log_do_checkpoint(journal_t *journal)
299 return result; 314 return result;
300 315
301 /* 316 /*
302 * OK, we need to start writing disk blocks. Try to free up a 317 * OK, we need to start writing disk blocks. Take one transaction
303 * quarter of the log in a single checkpoint if we can. 318 * and write it.
304 */ 319 */
320 spin_lock(&journal->j_list_lock);
321 if (!journal->j_checkpoint_transactions)
322 goto out;
323 transaction = journal->j_checkpoint_transactions;
324 this_tid = transaction->t_tid;
325restart:
305 /* 326 /*
306 * AKPM: check this code. I had a feeling a while back that it 327 * If someone cleaned up this transaction while we slept, we're
307 * degenerates into a busy loop at unmount time. 328 * done (maybe it's a new transaction, but it fell at the same
329 * address).
308 */ 330 */
309 spin_lock(&journal->j_list_lock); 331 if (journal->j_checkpoint_transactions == transaction &&
310 while (journal->j_checkpoint_transactions) { 332 transaction->t_tid == this_tid) {
311 transaction_t *transaction; 333 int batch_count = 0;
312 struct journal_head *jh, *last_jh, *next_jh; 334 struct buffer_head *bhs[NR_BATCH];
313 int drop_count = 0; 335 struct journal_head *jh;
314 int cleanup_ret, retry = 0; 336 int retry = 0;
315 tid_t this_tid; 337
316 338 while (!retry && transaction->t_checkpoint_list) {
317 transaction = journal->j_checkpoint_transactions;
318 this_tid = transaction->t_tid;
319 jh = transaction->t_checkpoint_list;
320 last_jh = jh->b_cpprev;
321 next_jh = jh;
322 do {
323 struct buffer_head *bh; 339 struct buffer_head *bh;
324 340
325 jh = next_jh; 341 jh = transaction->t_checkpoint_list;
326 next_jh = jh->b_cpnext;
327 bh = jh2bh(jh); 342 bh = jh2bh(jh);
328 if (!jbd_trylock_bh_state(bh)) { 343 if (!jbd_trylock_bh_state(bh)) {
329 jbd_sync_bh(journal, bh); 344 jbd_sync_bh(journal, bh);
330 spin_lock(&journal->j_list_lock);
331 retry = 1; 345 retry = 1;
332 break; 346 break;
333 } 347 }
334 retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count); 348 retry = __process_buffer(journal, jh, bhs,&batch_count);
335 if (cond_resched_lock(&journal->j_list_lock)) { 349 if (!retry && lock_need_resched(&journal->j_list_lock)){
350 spin_unlock(&journal->j_list_lock);
336 retry = 1; 351 retry = 1;
337 break; 352 break;
338 } 353 }
339 } while (jh != last_jh && !retry); 354 }
340 355
341 if (batch_count) { 356 if (batch_count) {
357 if (!retry) {
358 spin_unlock(&journal->j_list_lock);
359 retry = 1;
360 }
342 __flush_batch(journal, bhs, &batch_count); 361 __flush_batch(journal, bhs, &batch_count);
343 retry = 1;
344 } 362 }
345 363
364 if (retry) {
365 spin_lock(&journal->j_list_lock);
366 goto restart;
367 }
346 /* 368 /*
347 * If someone cleaned up this transaction while we slept, we're 369 * Now we have cleaned up the first transaction's checkpoint
348 * done 370 * list. Let's clean up the second one
349 */
350 if (journal->j_checkpoint_transactions != transaction)
351 break;
352 if (retry)
353 continue;
354 /*
355 * Maybe it's a new transaction, but it fell at the same
356 * address
357 */
358 if (transaction->t_tid != this_tid)
359 continue;
360 /*
361 * We have walked the whole transaction list without
362 * finding anything to write to disk. We had better be
363 * able to make some progress or we are in trouble.
364 */ 371 */
365 cleanup_ret = __cleanup_transaction(journal, transaction); 372 __wait_cp_io(journal, transaction);
366 J_ASSERT(drop_count != 0 || cleanup_ret != 0);
367 if (journal->j_checkpoint_transactions != transaction)
368 break;
369 } 373 }
374out:
370 spin_unlock(&journal->j_list_lock); 375 spin_unlock(&journal->j_list_lock);
371 result = cleanup_journal_tail(journal); 376 result = cleanup_journal_tail(journal);
372 if (result < 0) 377 if (result < 0)
373 return result; 378 return result;
374
375 return 0; 379 return 0;
376} 380}
377 381
@@ -456,52 +460,98 @@ int cleanup_journal_tail(journal_t *journal)
456/* Checkpoint list management */ 460/* Checkpoint list management */
457 461
458/* 462/*
463 * journal_clean_one_cp_list
464 *
465 * Find all the written-back checkpoint buffers in the given list and release them.
466 *
467 * Called with the journal locked.
468 * Called with j_list_lock held.
469 * Returns number of bufers reaped (for debug)
470 */
471
472static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
473{
474 struct journal_head *last_jh;
475 struct journal_head *next_jh = jh;
476 int ret, freed = 0;
477
478 *released = 0;
479 if (!jh)
480 return 0;
481
482 last_jh = jh->b_cpprev;
483 do {
484 jh = next_jh;
485 next_jh = jh->b_cpnext;
486 /* Use trylock because of the ranking */
487 if (jbd_trylock_bh_state(jh2bh(jh))) {
488 ret = __try_to_free_cp_buf(jh);
489 if (ret) {
490 freed++;
491 if (ret == 2) {
492 *released = 1;
493 return freed;
494 }
495 }
496 }
497 /*
498 * This function only frees up some memory
499 * if possible so we dont have an obligation
500 * to finish processing. Bail out if preemption
501 * requested:
502 */
503 if (need_resched())
504 return freed;
505 } while (jh != last_jh);
506
507 return freed;
508}
509
510/*
459 * journal_clean_checkpoint_list 511 * journal_clean_checkpoint_list
460 * 512 *
461 * Find all the written-back checkpoint buffers in the journal and release them. 513 * Find all the written-back checkpoint buffers in the journal and release them.
462 * 514 *
463 * Called with the journal locked. 515 * Called with the journal locked.
464 * Called with j_list_lock held. 516 * Called with j_list_lock held.
465 * Returns number of bufers reaped (for debug) 517 * Returns number of buffers reaped (for debug)
466 */ 518 */
467 519
468int __journal_clean_checkpoint_list(journal_t *journal) 520int __journal_clean_checkpoint_list(journal_t *journal)
469{ 521{
470 transaction_t *transaction, *last_transaction, *next_transaction; 522 transaction_t *transaction, *last_transaction, *next_transaction;
471 int ret = 0; 523 int ret = 0;
524 int released;
472 525
473 transaction = journal->j_checkpoint_transactions; 526 transaction = journal->j_checkpoint_transactions;
474 if (transaction == 0) 527 if (!transaction)
475 goto out; 528 goto out;
476 529
477 last_transaction = transaction->t_cpprev; 530 last_transaction = transaction->t_cpprev;
478 next_transaction = transaction; 531 next_transaction = transaction;
479 do { 532 do {
480 struct journal_head *jh;
481
482 transaction = next_transaction; 533 transaction = next_transaction;
483 next_transaction = transaction->t_cpnext; 534 next_transaction = transaction->t_cpnext;
484 jh = transaction->t_checkpoint_list; 535 ret += journal_clean_one_cp_list(transaction->
485 if (jh) { 536 t_checkpoint_list, &released);
486 struct journal_head *last_jh = jh->b_cpprev; 537 /*
487 struct journal_head *next_jh = jh; 538 * This function only frees up some memory if possible so we
488 539 * dont have an obligation to finish processing. Bail out if
489 do { 540 * preemption requested:
490 jh = next_jh; 541 */
491 next_jh = jh->b_cpnext; 542 if (need_resched())
492 /* Use trylock because of the ranknig */ 543 goto out;
493 if (jbd_trylock_bh_state(jh2bh(jh))) 544 if (released)
494 ret += __try_to_free_cp_buf(jh); 545 continue;
495 /* 546 /*
496 * This function only frees up some memory 547 * It is essential that we are as careful as in the case of
497 * if possible so we dont have an obligation 548 * t_checkpoint_list with removing the buffer from the list as
498 * to finish processing. Bail out if preemption 549 * we can possibly see not yet submitted buffers on io_list
499 * requested: 550 */
500 */ 551 ret += journal_clean_one_cp_list(transaction->
501 if (need_resched()) 552 t_checkpoint_io_list, &released);
502 goto out; 553 if (need_resched())
503 } while (jh != last_jh); 554 goto out;
504 }
505 } while (transaction != last_transaction); 555 } while (transaction != last_transaction);
506out: 556out:
507 return ret; 557 return ret;
@@ -516,18 +566,22 @@ out:
516 * buffer updates committed in that transaction have safely been stored 566 * buffer updates committed in that transaction have safely been stored
517 * elsewhere on disk. To achieve this, all of the buffers in a 567 * elsewhere on disk. To achieve this, all of the buffers in a
518 * transaction need to be maintained on the transaction's checkpoint 568 * transaction need to be maintained on the transaction's checkpoint
519 * list until they have been rewritten, at which point this function is 569 * lists until they have been rewritten, at which point this function is
520 * called to remove the buffer from the existing transaction's 570 * called to remove the buffer from the existing transaction's
521 * checkpoint list. 571 * checkpoint lists.
572 *
573 * The function returns 1 if it frees the transaction, 0 otherwise.
522 * 574 *
523 * This function is called with the journal locked. 575 * This function is called with the journal locked.
524 * This function is called with j_list_lock held. 576 * This function is called with j_list_lock held.
577 * This function is called with jbd_lock_bh_state(jh2bh(jh))
525 */ 578 */
526 579
527void __journal_remove_checkpoint(struct journal_head *jh) 580int __journal_remove_checkpoint(struct journal_head *jh)
528{ 581{
529 transaction_t *transaction; 582 transaction_t *transaction;
530 journal_t *journal; 583 journal_t *journal;
584 int ret = 0;
531 585
532 JBUFFER_TRACE(jh, "entry"); 586 JBUFFER_TRACE(jh, "entry");
533 587
@@ -538,8 +592,10 @@ void __journal_remove_checkpoint(struct journal_head *jh)
538 journal = transaction->t_journal; 592 journal = transaction->t_journal;
539 593
540 __buffer_unlink(jh); 594 __buffer_unlink(jh);
595 jh->b_cp_transaction = NULL;
541 596
542 if (transaction->t_checkpoint_list != NULL) 597 if (transaction->t_checkpoint_list != NULL ||
598 transaction->t_checkpoint_io_list != NULL)
543 goto out; 599 goto out;
544 JBUFFER_TRACE(jh, "transaction has no more buffers"); 600 JBUFFER_TRACE(jh, "transaction has no more buffers");
545 601
@@ -565,8 +621,10 @@ void __journal_remove_checkpoint(struct journal_head *jh)
565 /* Just in case anybody was waiting for more transactions to be 621 /* Just in case anybody was waiting for more transactions to be
566 checkpointed... */ 622 checkpointed... */
567 wake_up(&journal->j_wait_logspace); 623 wake_up(&journal->j_wait_logspace);
624 ret = 1;
568out: 625out:
569 JBUFFER_TRACE(jh, "exit"); 626 JBUFFER_TRACE(jh, "exit");
627 return ret;
570} 628}
571 629
572/* 630/*
@@ -628,6 +686,7 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
628 J_ASSERT(transaction->t_shadow_list == NULL); 686 J_ASSERT(transaction->t_shadow_list == NULL);
629 J_ASSERT(transaction->t_log_list == NULL); 687 J_ASSERT(transaction->t_log_list == NULL);
630 J_ASSERT(transaction->t_checkpoint_list == NULL); 688 J_ASSERT(transaction->t_checkpoint_list == NULL);
689 J_ASSERT(transaction->t_checkpoint_io_list == NULL);
631 J_ASSERT(transaction->t_updates == 0); 690 J_ASSERT(transaction->t_updates == 0);
632 J_ASSERT(journal->j_committing_transaction != transaction); 691 J_ASSERT(journal->j_committing_transaction != transaction);
633 J_ASSERT(journal->j_running_transaction != transaction); 692 J_ASSERT(journal->j_running_transaction != transaction);
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 002ad2bbc769..0971814c38b8 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -790,11 +790,22 @@ restart_loop:
790 jbd_unlock_bh_state(bh); 790 jbd_unlock_bh_state(bh);
791 } else { 791 } else {
792 J_ASSERT_BH(bh, !buffer_dirty(bh)); 792 J_ASSERT_BH(bh, !buffer_dirty(bh));
793 J_ASSERT_JH(jh, jh->b_next_transaction == NULL); 793 /* The buffer on BJ_Forget list and not jbddirty means
794 __journal_unfile_buffer(jh); 794 * it has been freed by this transaction and hence it
795 jbd_unlock_bh_state(bh); 795 * could not have been reallocated until this
796 journal_remove_journal_head(bh); /* needs a brelse */ 796 * transaction has committed. *BUT* it could be
797 release_buffer_page(bh); 797 * reallocated once we have written all the data to
798 * disk and before we process the buffer on BJ_Forget
799 * list. */
800 JBUFFER_TRACE(jh, "refile or unfile freed buffer");
801 __journal_refile_buffer(jh);
802 if (!jh->b_transaction) {
803 jbd_unlock_bh_state(bh);
804 /* needs a brelse */
805 journal_remove_journal_head(bh);
806 release_buffer_page(bh);
807 } else
808 jbd_unlock_bh_state(bh);
798 } 809 }
799 cond_resched_lock(&journal->j_list_lock); 810 cond_resched_lock(&journal->j_list_lock);
800 } 811 }
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index c609f5034fcd..508b2ea91f43 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -227,7 +227,8 @@ repeat_locked:
227 spin_unlock(&transaction->t_handle_lock); 227 spin_unlock(&transaction->t_handle_lock);
228 spin_unlock(&journal->j_state_lock); 228 spin_unlock(&journal->j_state_lock);
229out: 229out:
230 kfree(new_transaction); 230 if (unlikely(new_transaction)) /* It's usually NULL */
231 kfree(new_transaction);
231 return ret; 232 return ret;
232} 233}
233 234
@@ -724,7 +725,8 @@ done:
724 journal_cancel_revoke(handle, jh); 725 journal_cancel_revoke(handle, jh);
725 726
726out: 727out:
727 kfree(frozen_buffer); 728 if (unlikely(frozen_buffer)) /* It's usually NULL */
729 kfree(frozen_buffer);
728 730
729 JBUFFER_TRACE(jh, "exit"); 731 JBUFFER_TRACE(jh, "exit");
730 return error; 732 return error;
@@ -903,7 +905,8 @@ repeat:
903 jbd_unlock_bh_state(bh); 905 jbd_unlock_bh_state(bh);
904out: 906out:
905 journal_put_journal_head(jh); 907 journal_put_journal_head(jh);
906 kfree(committed_data); 908 if (unlikely(committed_data))
909 kfree(committed_data);
907 return err; 910 return err;
908} 911}
909 912
@@ -2038,7 +2041,8 @@ void __journal_refile_buffer(struct journal_head *jh)
2038 __journal_temp_unlink_buffer(jh); 2041 __journal_temp_unlink_buffer(jh);
2039 jh->b_transaction = jh->b_next_transaction; 2042 jh->b_transaction = jh->b_next_transaction;
2040 jh->b_next_transaction = NULL; 2043 jh->b_next_transaction = NULL;
2041 __journal_file_buffer(jh, jh->b_transaction, BJ_Metadata); 2044 __journal_file_buffer(jh, jh->b_transaction,
2045 was_dirty ? BJ_Metadata : BJ_Reserved);
2042 J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING); 2046 J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING);
2043 2047
2044 if (was_dirty) 2048 if (was_dirty)
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 020cc097c539..9e46ea6da752 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -377,9 +377,9 @@ jffs_new_inode(const struct inode * dir, struct jffs_raw_inode *raw_inode,
377 377
378/* Get statistics of the file system. */ 378/* Get statistics of the file system. */
379static int 379static int
380jffs_statfs(struct super_block *sb, struct kstatfs *buf) 380jffs_statfs(struct dentry *dentry, struct kstatfs *buf)
381{ 381{
382 struct jffs_control *c = (struct jffs_control *) sb->s_fs_info; 382 struct jffs_control *c = (struct jffs_control *) dentry->d_sb->s_fs_info;
383 struct jffs_fmcontrol *fmc; 383 struct jffs_fmcontrol *fmc;
384 384
385 lock_kernel(); 385 lock_kernel();
@@ -1785,10 +1785,11 @@ static struct super_operations jffs_ops =
1785 .remount_fs = jffs_remount, 1785 .remount_fs = jffs_remount,
1786}; 1786};
1787 1787
1788static struct super_block *jffs_get_sb(struct file_system_type *fs_type, 1788static int jffs_get_sb(struct file_system_type *fs_type,
1789 int flags, const char *dev_name, void *data) 1789 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1790{ 1790{
1791 return get_sb_bdev(fs_type, flags, dev_name, data, jffs_fill_super); 1791 return get_sb_bdev(fs_type, flags, dev_name, data, jffs_fill_super,
1792 mnt);
1792} 1793}
1793 1794
1794static struct file_system_type jffs_fs_type = { 1795static struct file_system_type jffs_fs_type = {
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 7b6c24b14f85..2900ec3ec3af 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -192,9 +192,9 @@ int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
192 return rc; 192 return rc;
193} 193}
194 194
195int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) 195int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf)
196{ 196{
197 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 197 struct jffs2_sb_info *c = JFFS2_SB_INFO(dentry->d_sb);
198 unsigned long avail; 198 unsigned long avail;
199 199
200 buf->f_type = JFFS2_SUPER_MAGIC; 200 buf->f_type = JFFS2_SUPER_MAGIC;
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index cd4021bcb944..6b5223565405 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -175,7 +175,7 @@ void jffs2_clear_inode (struct inode *);
175void jffs2_dirty_inode(struct inode *inode); 175void jffs2_dirty_inode(struct inode *inode);
176struct inode *jffs2_new_inode (struct inode *dir_i, int mode, 176struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
177 struct jffs2_raw_inode *ri); 177 struct jffs2_raw_inode *ri);
178int jffs2_statfs (struct super_block *, struct kstatfs *); 178int jffs2_statfs (struct dentry *, struct kstatfs *);
179void jffs2_write_super (struct super_block *); 179void jffs2_write_super (struct super_block *);
180int jffs2_remount_fs (struct super_block *, int *, char *); 180int jffs2_remount_fs (struct super_block *, int *, char *);
181int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); 181int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 9d0521451f59..2378a662c256 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -111,9 +111,10 @@ static int jffs2_sb_set(struct super_block *sb, void *data)
111 return 0; 111 return 0;
112} 112}
113 113
114static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, 114static int jffs2_get_sb_mtd(struct file_system_type *fs_type,
115 int flags, const char *dev_name, 115 int flags, const char *dev_name,
116 void *data, struct mtd_info *mtd) 116 void *data, struct mtd_info *mtd,
117 struct vfsmount *mnt)
117{ 118{
118 struct super_block *sb; 119 struct super_block *sb;
119 struct jffs2_sb_info *c; 120 struct jffs2_sb_info *c;
@@ -121,19 +122,20 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
121 122
122 c = kmalloc(sizeof(*c), GFP_KERNEL); 123 c = kmalloc(sizeof(*c), GFP_KERNEL);
123 if (!c) 124 if (!c)
124 return ERR_PTR(-ENOMEM); 125 return -ENOMEM;
125 memset(c, 0, sizeof(*c)); 126 memset(c, 0, sizeof(*c));
126 c->mtd = mtd; 127 c->mtd = mtd;
127 128
128 sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c); 129 sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c);
129 130
130 if (IS_ERR(sb)) 131 if (IS_ERR(sb))
131 goto out_put; 132 goto out_error;
132 133
133 if (sb->s_root) { 134 if (sb->s_root) {
134 /* New mountpoint for JFFS2 which is already mounted */ 135 /* New mountpoint for JFFS2 which is already mounted */
135 D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n", 136 D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n",
136 mtd->index, mtd->name)); 137 mtd->index, mtd->name));
138 ret = simple_set_mnt(mnt, sb);
137 goto out_put; 139 goto out_put;
138 } 140 }
139 141
@@ -161,44 +163,47 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
161 /* Failure case... */ 163 /* Failure case... */
162 up_write(&sb->s_umount); 164 up_write(&sb->s_umount);
163 deactivate_super(sb); 165 deactivate_super(sb);
164 return ERR_PTR(ret); 166 return ret;
165 } 167 }
166 168
167 sb->s_flags |= MS_ACTIVE; 169 sb->s_flags |= MS_ACTIVE;
168 return sb; 170 return simple_set_mnt(mnt, sb);
169 171
172out_error:
173 ret = PTR_ERR(sb);
170 out_put: 174 out_put:
171 kfree(c); 175 kfree(c);
172 put_mtd_device(mtd); 176 put_mtd_device(mtd);
173 177
174 return sb; 178 return ret;
175} 179}
176 180
177static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type, 181static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
178 int flags, const char *dev_name, 182 int flags, const char *dev_name,
179 void *data, int mtdnr) 183 void *data, int mtdnr,
184 struct vfsmount *mnt)
180{ 185{
181 struct mtd_info *mtd; 186 struct mtd_info *mtd;
182 187
183 mtd = get_mtd_device(NULL, mtdnr); 188 mtd = get_mtd_device(NULL, mtdnr);
184 if (!mtd) { 189 if (!mtd) {
185 D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr)); 190 D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
186 return ERR_PTR(-EINVAL); 191 return -EINVAL;
187 } 192 }
188 193
189 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd); 194 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
190} 195}
191 196
192static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, 197static int jffs2_get_sb(struct file_system_type *fs_type,
193 int flags, const char *dev_name, 198 int flags, const char *dev_name,
194 void *data) 199 void *data, struct vfsmount *mnt)
195{ 200{
196 int err; 201 int err;
197 struct nameidata nd; 202 struct nameidata nd;
198 int mtdnr; 203 int mtdnr;
199 204
200 if (!dev_name) 205 if (!dev_name)
201 return ERR_PTR(-EINVAL); 206 return -EINVAL;
202 207
203 D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name)); 208 D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name));
204 209
@@ -220,7 +225,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
220 mtd = get_mtd_device(NULL, mtdnr); 225 mtd = get_mtd_device(NULL, mtdnr);
221 if (mtd) { 226 if (mtd) {
222 if (!strcmp(mtd->name, dev_name+4)) 227 if (!strcmp(mtd->name, dev_name+4))
223 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd); 228 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
224 put_mtd_device(mtd); 229 put_mtd_device(mtd);
225 } 230 }
226 } 231 }
@@ -233,7 +238,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
233 if (!*endptr) { 238 if (!*endptr) {
234 /* It was a valid number */ 239 /* It was a valid number */
235 D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr)); 240 D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr));
236 return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr); 241 return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
237 } 242 }
238 } 243 }
239 } 244 }
@@ -247,7 +252,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
247 err, nd.dentry->d_inode)); 252 err, nd.dentry->d_inode));
248 253
249 if (err) 254 if (err)
250 return ERR_PTR(err); 255 return err;
251 256
252 err = -EINVAL; 257 err = -EINVAL;
253 258
@@ -269,11 +274,11 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
269 mtdnr = iminor(nd.dentry->d_inode); 274 mtdnr = iminor(nd.dentry->d_inode);
270 path_release(&nd); 275 path_release(&nd);
271 276
272 return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr); 277 return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr, mnt);
273 278
274out: 279out:
275 path_release(&nd); 280 path_release(&nd);
276 return ERR_PTR(err); 281 return err;
277} 282}
278 283
279static void jffs2_put_super (struct super_block *sb) 284static void jffs2_put_super (struct super_block *sb)
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 2b220dd6b4e7..7f6e88039700 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -632,10 +632,9 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
632 } 632 }
633 SetPageUptodate(page); 633 SetPageUptodate(page);
634 } else { 634 } else {
635 page = read_cache_page(mapping, page_index, 635 page = read_mapping_page(mapping, page_index, NULL);
636 (filler_t *)mapping->a_ops->readpage, NULL);
637 if (IS_ERR(page) || !PageUptodate(page)) { 636 if (IS_ERR(page) || !PageUptodate(page)) {
638 jfs_err("read_cache_page failed!"); 637 jfs_err("read_mapping_page failed!");
639 return NULL; 638 return NULL;
640 } 639 }
641 lock_page(page); 640 lock_page(page);
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index db6f41d6dd60..73d2aba084c6 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -139,9 +139,9 @@ static void jfs_destroy_inode(struct inode *inode)
139 kmem_cache_free(jfs_inode_cachep, ji); 139 kmem_cache_free(jfs_inode_cachep, ji);
140} 140}
141 141
142static int jfs_statfs(struct super_block *sb, struct kstatfs *buf) 142static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf)
143{ 143{
144 struct jfs_sb_info *sbi = JFS_SBI(sb); 144 struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb);
145 s64 maxinodes; 145 s64 maxinodes;
146 struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap; 146 struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap;
147 147
@@ -565,10 +565,11 @@ static void jfs_unlockfs(struct super_block *sb)
565 } 565 }
566} 566}
567 567
568static struct super_block *jfs_get_sb(struct file_system_type *fs_type, 568static int jfs_get_sb(struct file_system_type *fs_type,
569 int flags, const char *dev_name, void *data) 569 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
570{ 570{
571 return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super); 571 return get_sb_bdev(fs_type, flags, dev_name, data, jfs_fill_super,
572 mnt);
572} 573}
573 574
574static int jfs_sync_fs(struct super_block *sb, int wait) 575static int jfs_sync_fs(struct super_block *sb, int wait)
diff --git a/fs/libfs.c b/fs/libfs.c
index 4a3ec9ad8bed..fc785d8befb9 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -20,9 +20,9 @@ int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
20 return 0; 20 return 0;
21} 21}
22 22
23int simple_statfs(struct super_block *sb, struct kstatfs *buf) 23int simple_statfs(struct dentry *dentry, struct kstatfs *buf)
24{ 24{
25 buf->f_type = sb->s_magic; 25 buf->f_type = dentry->d_sb->s_magic;
26 buf->f_bsize = PAGE_CACHE_SIZE; 26 buf->f_bsize = PAGE_CACHE_SIZE;
27 buf->f_namelen = NAME_MAX; 27 buf->f_namelen = NAME_MAX;
28 return 0; 28 return 0;
@@ -196,9 +196,9 @@ struct inode_operations simple_dir_inode_operations = {
196 * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that 196 * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that
197 * will never be mountable) 197 * will never be mountable)
198 */ 198 */
199struct super_block * 199int get_sb_pseudo(struct file_system_type *fs_type, char *name,
200get_sb_pseudo(struct file_system_type *fs_type, char *name, 200 struct super_operations *ops, unsigned long magic,
201 struct super_operations *ops, unsigned long magic) 201 struct vfsmount *mnt)
202{ 202{
203 struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); 203 struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
204 static struct super_operations default_ops = {.statfs = simple_statfs}; 204 static struct super_operations default_ops = {.statfs = simple_statfs};
@@ -207,7 +207,7 @@ get_sb_pseudo(struct file_system_type *fs_type, char *name,
207 struct qstr d_name = {.name = name, .len = strlen(name)}; 207 struct qstr d_name = {.name = name, .len = strlen(name)};
208 208
209 if (IS_ERR(s)) 209 if (IS_ERR(s))
210 return s; 210 return PTR_ERR(s);
211 211
212 s->s_flags = MS_NOUSER; 212 s->s_flags = MS_NOUSER;
213 s->s_maxbytes = ~0ULL; 213 s->s_maxbytes = ~0ULL;
@@ -232,12 +232,12 @@ get_sb_pseudo(struct file_system_type *fs_type, char *name,
232 d_instantiate(dentry, root); 232 d_instantiate(dentry, root);
233 s->s_root = dentry; 233 s->s_root = dentry;
234 s->s_flags |= MS_ACTIVE; 234 s->s_flags |= MS_ACTIVE;
235 return s; 235 return simple_set_mnt(mnt, s);
236 236
237Enomem: 237Enomem:
238 up_write(&s->s_umount); 238 up_write(&s->s_umount);
239 deactivate_super(s); 239 deactivate_super(s);
240 return ERR_PTR(-ENOMEM); 240 return -ENOMEM;
241} 241}
242 242
243int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) 243int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
diff --git a/fs/locks.c b/fs/locks.c
index ab61a8b54829..1ad29c9b6252 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -703,7 +703,7 @@ EXPORT_SYMBOL(posix_test_lock);
703 * from a broken NFS client. But broken NFS clients have a lot more to 703 * from a broken NFS client. But broken NFS clients have a lot more to
704 * worry about than proper deadlock detection anyway... --okir 704 * worry about than proper deadlock detection anyway... --okir
705 */ 705 */
706int posix_locks_deadlock(struct file_lock *caller_fl, 706static int posix_locks_deadlock(struct file_lock *caller_fl,
707 struct file_lock *block_fl) 707 struct file_lock *block_fl)
708{ 708{
709 struct list_head *tmp; 709 struct list_head *tmp;
@@ -722,8 +722,6 @@ next_task:
722 return 0; 722 return 0;
723} 723}
724 724
725EXPORT_SYMBOL(posix_locks_deadlock);
726
727/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 725/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
728 * at the head of the list, but that's secret knowledge known only to 726 * at the head of the list, but that's secret knowledge known only to
729 * flock_lock_file and posix_lock_file. 727 * flock_lock_file and posix_lock_file.
@@ -794,7 +792,8 @@ out:
794static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock) 792static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock)
795{ 793{
796 struct file_lock *fl; 794 struct file_lock *fl;
797 struct file_lock *new_fl, *new_fl2; 795 struct file_lock *new_fl = NULL;
796 struct file_lock *new_fl2 = NULL;
798 struct file_lock *left = NULL; 797 struct file_lock *left = NULL;
799 struct file_lock *right = NULL; 798 struct file_lock *right = NULL;
800 struct file_lock **before; 799 struct file_lock **before;
@@ -803,9 +802,15 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
803 /* 802 /*
804 * We may need two file_lock structures for this operation, 803 * We may need two file_lock structures for this operation,
805 * so we get them in advance to avoid races. 804 * so we get them in advance to avoid races.
805 *
806 * In some cases we can be sure, that no new locks will be needed
806 */ 807 */
807 new_fl = locks_alloc_lock(); 808 if (!(request->fl_flags & FL_ACCESS) &&
808 new_fl2 = locks_alloc_lock(); 809 (request->fl_type != F_UNLCK ||
810 request->fl_start != 0 || request->fl_end != OFFSET_MAX)) {
811 new_fl = locks_alloc_lock();
812 new_fl2 = locks_alloc_lock();
813 }
809 814
810 lock_kernel(); 815 lock_kernel();
811 if (request->fl_type != F_UNLCK) { 816 if (request->fl_type != F_UNLCK) {
@@ -834,14 +839,7 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
834 if (request->fl_flags & FL_ACCESS) 839 if (request->fl_flags & FL_ACCESS)
835 goto out; 840 goto out;
836 841
837 error = -ENOLCK; /* "no luck" */
838 if (!(new_fl && new_fl2))
839 goto out;
840
841 /* 842 /*
842 * We've allocated the new locks in advance, so there are no
843 * errors possible (and no blocking operations) from here on.
844 *
845 * Find the first old lock with the same owner as the new lock. 843 * Find the first old lock with the same owner as the new lock.
846 */ 844 */
847 845
@@ -938,10 +936,25 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
938 before = &fl->fl_next; 936 before = &fl->fl_next;
939 } 937 }
940 938
939 /*
940 * The above code only modifies existing locks in case of
941 * merging or replacing. If new lock(s) need to be inserted
942 * all modifications are done bellow this, so it's safe yet to
943 * bail out.
944 */
945 error = -ENOLCK; /* "no luck" */
946 if (right && left == right && !new_fl2)
947 goto out;
948
941 error = 0; 949 error = 0;
942 if (!added) { 950 if (!added) {
943 if (request->fl_type == F_UNLCK) 951 if (request->fl_type == F_UNLCK)
944 goto out; 952 goto out;
953
954 if (!new_fl) {
955 error = -ENOLCK;
956 goto out;
957 }
945 locks_copy_lock(new_fl, request); 958 locks_copy_lock(new_fl, request);
946 locks_insert_lock(before, new_fl); 959 locks_insert_lock(before, new_fl);
947 new_fl = NULL; 960 new_fl = NULL;
@@ -1881,19 +1894,18 @@ out:
1881 */ 1894 */
1882void locks_remove_posix(struct file *filp, fl_owner_t owner) 1895void locks_remove_posix(struct file *filp, fl_owner_t owner)
1883{ 1896{
1884 struct file_lock lock, **before; 1897 struct file_lock lock;
1885 1898
1886 /* 1899 /*
1887 * If there are no locks held on this file, we don't need to call 1900 * If there are no locks held on this file, we don't need to call
1888 * posix_lock_file(). Another process could be setting a lock on this 1901 * posix_lock_file(). Another process could be setting a lock on this
1889 * file at the same time, but we wouldn't remove that lock anyway. 1902 * file at the same time, but we wouldn't remove that lock anyway.
1890 */ 1903 */
1891 before = &filp->f_dentry->d_inode->i_flock; 1904 if (!filp->f_dentry->d_inode->i_flock)
1892 if (*before == NULL)
1893 return; 1905 return;
1894 1906
1895 lock.fl_type = F_UNLCK; 1907 lock.fl_type = F_UNLCK;
1896 lock.fl_flags = FL_POSIX; 1908 lock.fl_flags = FL_POSIX | FL_CLOSE;
1897 lock.fl_start = 0; 1909 lock.fl_start = 0;
1898 lock.fl_end = OFFSET_MAX; 1910 lock.fl_end = OFFSET_MAX;
1899 lock.fl_owner = owner; 1911 lock.fl_owner = owner;
@@ -1902,25 +1914,11 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
1902 lock.fl_ops = NULL; 1914 lock.fl_ops = NULL;
1903 lock.fl_lmops = NULL; 1915 lock.fl_lmops = NULL;
1904 1916
1905 if (filp->f_op && filp->f_op->lock != NULL) { 1917 if (filp->f_op && filp->f_op->lock != NULL)
1906 filp->f_op->lock(filp, F_SETLK, &lock); 1918 filp->f_op->lock(filp, F_SETLK, &lock);
1907 goto out; 1919 else
1908 } 1920 posix_lock_file(filp, &lock);
1909 1921
1910 /* Can't use posix_lock_file here; we need to remove it no matter
1911 * which pid we have.
1912 */
1913 lock_kernel();
1914 while (*before != NULL) {
1915 struct file_lock *fl = *before;
1916 if (IS_POSIX(fl) && posix_same_owner(fl, &lock)) {
1917 locks_delete_lock(before);
1918 continue;
1919 }
1920 before = &fl->fl_next;
1921 }
1922 unlock_kernel();
1923out:
1924 if (lock.fl_ops && lock.fl_ops->fl_release_private) 1922 if (lock.fl_ops && lock.fl_ops->fl_release_private)
1925 lock.fl_ops->fl_release_private(&lock); 1923 lock.fl_ops->fl_release_private(&lock);
1926} 1924}
@@ -2206,63 +2204,6 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
2206 2204
2207EXPORT_SYMBOL(lock_may_write); 2205EXPORT_SYMBOL(lock_may_write);
2208 2206
2209static inline void __steal_locks(struct file *file, fl_owner_t from)
2210{
2211 struct inode *inode = file->f_dentry->d_inode;
2212 struct file_lock *fl = inode->i_flock;
2213
2214 while (fl) {
2215 if (fl->fl_file == file && fl->fl_owner == from)
2216 fl->fl_owner = current->files;
2217 fl = fl->fl_next;
2218 }
2219}
2220
2221/* When getting ready for executing a binary, we make sure that current
2222 * has a files_struct on its own. Before dropping the old files_struct,
2223 * we take over ownership of all locks for all file descriptors we own.
2224 * Note that we may accidentally steal a lock for a file that a sibling
2225 * has created since the unshare_files() call.
2226 */
2227void steal_locks(fl_owner_t from)
2228{
2229 struct files_struct *files = current->files;
2230 int i, j;
2231 struct fdtable *fdt;
2232
2233 if (from == files)
2234 return;
2235
2236 lock_kernel();
2237 j = 0;
2238
2239 /*
2240 * We are not taking a ref to the file structures, so
2241 * we need to acquire ->file_lock.
2242 */
2243 spin_lock(&files->file_lock);
2244 fdt = files_fdtable(files);
2245 for (;;) {
2246 unsigned long set;
2247 i = j * __NFDBITS;
2248 if (i >= fdt->max_fdset || i >= fdt->max_fds)
2249 break;
2250 set = fdt->open_fds->fds_bits[j++];
2251 while (set) {
2252 if (set & 1) {
2253 struct file *file = fdt->fd[i];
2254 if (file)
2255 __steal_locks(file, from);
2256 }
2257 i++;
2258 set >>= 1;
2259 }
2260 }
2261 spin_unlock(&files->file_lock);
2262 unlock_kernel();
2263}
2264EXPORT_SYMBOL(steal_locks);
2265
2266static int __init filelock_init(void) 2207static int __init filelock_init(void)
2267{ 2208{
2268 filelock_cache = kmem_cache_create("file_lock_cache", 2209 filelock_cache = kmem_cache_create("file_lock_cache",
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 69224d1fe043..2b0a389d1987 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -60,8 +60,7 @@ static int dir_commit_chunk(struct page *page, unsigned from, unsigned to)
60static struct page * dir_get_page(struct inode *dir, unsigned long n) 60static struct page * dir_get_page(struct inode *dir, unsigned long n)
61{ 61{
62 struct address_space *mapping = dir->i_mapping; 62 struct address_space *mapping = dir->i_mapping;
63 struct page *page = read_cache_page(mapping, n, 63 struct page *page = read_mapping_page(mapping, n, NULL);
64 (filler_t*)mapping->a_ops->readpage, NULL);
65 if (!IS_ERR(page)) { 64 if (!IS_ERR(page)) {
66 wait_on_page_locked(page); 65 wait_on_page_locked(page);
67 kmap(page); 66 kmap(page);
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 2dcccf1d1b7f..a6fb509b7341 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -19,7 +19,7 @@
19 19
20static void minix_read_inode(struct inode * inode); 20static void minix_read_inode(struct inode * inode);
21static int minix_write_inode(struct inode * inode, int wait); 21static int minix_write_inode(struct inode * inode, int wait);
22static int minix_statfs(struct super_block *sb, struct kstatfs *buf); 22static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
23static int minix_remount (struct super_block * sb, int * flags, char * data); 23static int minix_remount (struct super_block * sb, int * flags, char * data);
24 24
25static void minix_delete_inode(struct inode *inode) 25static void minix_delete_inode(struct inode *inode)
@@ -296,11 +296,11 @@ out_bad_sb:
296 return -EINVAL; 296 return -EINVAL;
297} 297}
298 298
299static int minix_statfs(struct super_block *sb, struct kstatfs *buf) 299static int minix_statfs(struct dentry *dentry, struct kstatfs *buf)
300{ 300{
301 struct minix_sb_info *sbi = minix_sb(sb); 301 struct minix_sb_info *sbi = minix_sb(dentry->d_sb);
302 buf->f_type = sb->s_magic; 302 buf->f_type = dentry->d_sb->s_magic;
303 buf->f_bsize = sb->s_blocksize; 303 buf->f_bsize = dentry->d_sb->s_blocksize;
304 buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size; 304 buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size;
305 buf->f_bfree = minix_count_free_blocks(sbi); 305 buf->f_bfree = minix_count_free_blocks(sbi);
306 buf->f_bavail = buf->f_bfree; 306 buf->f_bavail = buf->f_bfree;
@@ -559,10 +559,11 @@ void minix_truncate(struct inode * inode)
559 V2_minix_truncate(inode); 559 V2_minix_truncate(inode);
560} 560}
561 561
562static struct super_block *minix_get_sb(struct file_system_type *fs_type, 562static int minix_get_sb(struct file_system_type *fs_type,
563 int flags, const char *dev_name, void *data) 563 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
564{ 564{
565 return get_sb_bdev(fs_type, flags, dev_name, data, minix_fill_super); 565 return get_sb_bdev(fs_type, flags, dev_name, data, minix_fill_super,
566 mnt);
566} 567}
567 568
568static struct file_system_type minix_fs_type = { 569static struct file_system_type minix_fs_type = {
diff --git a/fs/mpage.c b/fs/mpage.c
index 9bf2eb30e6f4..1e4598247d0b 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -707,9 +707,9 @@ mpage_writepages(struct address_space *mapping,
707 struct pagevec pvec; 707 struct pagevec pvec;
708 int nr_pages; 708 int nr_pages;
709 pgoff_t index; 709 pgoff_t index;
710 pgoff_t end = -1; /* Inclusive */ 710 pgoff_t end; /* Inclusive */
711 int scanned = 0; 711 int scanned = 0;
712 int is_range = 0; 712 int range_whole = 0;
713 713
714 if (wbc->nonblocking && bdi_write_congested(bdi)) { 714 if (wbc->nonblocking && bdi_write_congested(bdi)) {
715 wbc->encountered_congestion = 1; 715 wbc->encountered_congestion = 1;
@@ -721,16 +721,14 @@ mpage_writepages(struct address_space *mapping,
721 writepage = mapping->a_ops->writepage; 721 writepage = mapping->a_ops->writepage;
722 722
723 pagevec_init(&pvec, 0); 723 pagevec_init(&pvec, 0);
724 if (wbc->sync_mode == WB_SYNC_NONE) { 724 if (wbc->range_cyclic) {
725 index = mapping->writeback_index; /* Start from prev offset */ 725 index = mapping->writeback_index; /* Start from prev offset */
726 end = -1;
726 } else { 727 } else {
727 index = 0; /* whole-file sweep */ 728 index = wbc->range_start >> PAGE_CACHE_SHIFT;
728 scanned = 1; 729 end = wbc->range_end >> PAGE_CACHE_SHIFT;
729 } 730 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
730 if (wbc->start || wbc->end) { 731 range_whole = 1;
731 index = wbc->start >> PAGE_CACHE_SHIFT;
732 end = wbc->end >> PAGE_CACHE_SHIFT;
733 is_range = 1;
734 scanned = 1; 732 scanned = 1;
735 } 733 }
736retry: 734retry:
@@ -759,7 +757,7 @@ retry:
759 continue; 757 continue;
760 } 758 }
761 759
762 if (unlikely(is_range) && page->index > end) { 760 if (!wbc->range_cyclic && page->index > end) {
763 done = 1; 761 done = 1;
764 unlock_page(page); 762 unlock_page(page);
765 continue; 763 continue;
@@ -810,7 +808,7 @@ retry:
810 index = 0; 808 index = 0;
811 goto retry; 809 goto retry;
812 } 810 }
813 if (!is_range) 811 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
814 mapping->writeback_index = index; 812 mapping->writeback_index = index;
815 if (bio) 813 if (bio)
816 mpage_bio_submit(WRITE, bio); 814 mpage_bio_submit(WRITE, bio);
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 5b76ccd19e3f..9e44158a7540 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -661,11 +661,12 @@ static int msdos_fill_super(struct super_block *sb, void *data, int silent)
661 return 0; 661 return 0;
662} 662}
663 663
664static struct super_block *msdos_get_sb(struct file_system_type *fs_type, 664static int msdos_get_sb(struct file_system_type *fs_type,
665 int flags, const char *dev_name, 665 int flags, const char *dev_name,
666 void *data) 666 void *data, struct vfsmount *mnt)
667{ 667{
668 return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super); 668 return get_sb_bdev(fs_type, flags, dev_name, data, msdos_fill_super,
669 mnt);
669} 670}
670 671
671static struct file_system_type msdos_fs_type = { 672static struct file_system_type msdos_fs_type = {
diff --git a/fs/namei.c b/fs/namei.c
index 184fe4acf824..bb4a3e40e432 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2577,8 +2577,7 @@ static char *page_getlink(struct dentry * dentry, struct page **ppage)
2577{ 2577{
2578 struct page * page; 2578 struct page * page;
2579 struct address_space *mapping = dentry->d_inode->i_mapping; 2579 struct address_space *mapping = dentry->d_inode->i_mapping;
2580 page = read_cache_page(mapping, 0, (filler_t *)mapping->a_ops->readpage, 2580 page = read_mapping_page(mapping, 0, NULL);
2581 NULL);
2582 if (IS_ERR(page)) 2581 if (IS_ERR(page))
2583 goto sync_fail; 2582 goto sync_fail;
2584 wait_on_page_locked(page); 2583 wait_on_page_locked(page);
diff --git a/fs/namespace.c b/fs/namespace.c
index 6bb0b85293e7..866430bb024d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -86,6 +86,15 @@ struct vfsmount *alloc_vfsmnt(const char *name)
86 return mnt; 86 return mnt;
87} 87}
88 88
89int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb)
90{
91 mnt->mnt_sb = sb;
92 mnt->mnt_root = dget(sb->s_root);
93 return 0;
94}
95
96EXPORT_SYMBOL(simple_set_mnt);
97
89void free_vfsmnt(struct vfsmount *mnt) 98void free_vfsmnt(struct vfsmount *mnt)
90{ 99{
91 kfree(mnt->mnt_devname); 100 kfree(mnt->mnt_devname);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index a1f3e972c6ef..90d2ea28f333 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -39,7 +39,7 @@
39 39
40static void ncp_delete_inode(struct inode *); 40static void ncp_delete_inode(struct inode *);
41static void ncp_put_super(struct super_block *); 41static void ncp_put_super(struct super_block *);
42static int ncp_statfs(struct super_block *, struct kstatfs *); 42static int ncp_statfs(struct dentry *, struct kstatfs *);
43 43
44static kmem_cache_t * ncp_inode_cachep; 44static kmem_cache_t * ncp_inode_cachep;
45 45
@@ -724,13 +724,14 @@ static void ncp_put_super(struct super_block *sb)
724 kfree(server); 724 kfree(server);
725} 725}
726 726
727static int ncp_statfs(struct super_block *sb, struct kstatfs *buf) 727static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
728{ 728{
729 struct dentry* d; 729 struct dentry* d;
730 struct inode* i; 730 struct inode* i;
731 struct ncp_inode_info* ni; 731 struct ncp_inode_info* ni;
732 struct ncp_server* s; 732 struct ncp_server* s;
733 struct ncp_volume_info vi; 733 struct ncp_volume_info vi;
734 struct super_block *sb = dentry->d_sb;
734 int err; 735 int err;
735 __u8 dh; 736 __u8 dh;
736 737
@@ -957,10 +958,10 @@ out:
957 return result; 958 return result;
958} 959}
959 960
960static struct super_block *ncp_get_sb(struct file_system_type *fs_type, 961static int ncp_get_sb(struct file_system_type *fs_type,
961 int flags, const char *dev_name, void *data) 962 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
962{ 963{
963 return get_sb_nodev(fs_type, flags, data, ncp_fill_super); 964 return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt);
964} 965}
965 966
966static struct file_system_type ncp_fs_type = { 967static struct file_system_type ncp_fs_type = {
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 106ef0dec04d..add289138836 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -43,7 +43,7 @@ static int nfs_file_mmap(struct file *, struct vm_area_struct *);
43static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); 43static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
44static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); 44static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
45static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); 45static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t);
46static int nfs_file_flush(struct file *); 46static int nfs_file_flush(struct file *, fl_owner_t id);
47static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); 47static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
48static int nfs_check_flags(int flags); 48static int nfs_check_flags(int flags);
49static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); 49static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
@@ -171,7 +171,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
171 * 171 *
172 */ 172 */
173static int 173static int
174nfs_file_flush(struct file *file) 174nfs_file_flush(struct file *file, fl_owner_t id)
175{ 175{
176 struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; 176 struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
177 struct inode *inode = file->f_dentry->d_inode; 177 struct inode *inode = file->f_dentry->d_inode;
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 4a006f81666b..67391eef6b93 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -23,6 +23,7 @@
23#include <linux/nfs.h> 23#include <linux/nfs.h>
24#include <linux/nfs2.h> 24#include <linux/nfs2.h>
25#include <linux/nfs_fs.h> 25#include <linux/nfs_fs.h>
26#include "internal.h"
26 27
27#define NFSDBG_FACILITY NFSDBG_XDR 28#define NFSDBG_FACILITY NFSDBG_XDR
28/* #define NFS_PARANOIA 1 */ 29/* #define NFS_PARANOIA 1 */
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 30f939bcb724..b977748553d3 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -107,12 +107,12 @@ struct rpc_program nfsacl_program = {
107#endif /* CONFIG_NFS_V3_ACL */ 107#endif /* CONFIG_NFS_V3_ACL */
108 108
109static void nfs_umount_begin(struct vfsmount *, int); 109static void nfs_umount_begin(struct vfsmount *, int);
110static int nfs_statfs(struct super_block *, struct kstatfs *); 110static int nfs_statfs(struct dentry *, struct kstatfs *);
111static int nfs_show_options(struct seq_file *, struct vfsmount *); 111static int nfs_show_options(struct seq_file *, struct vfsmount *);
112static int nfs_show_stats(struct seq_file *, struct vfsmount *); 112static int nfs_show_stats(struct seq_file *, struct vfsmount *);
113static struct super_block *nfs_get_sb(struct file_system_type *, int, const char *, void *); 113static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
114static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type, 114static int nfs_clone_nfs_sb(struct file_system_type *fs_type,
115 int flags, const char *dev_name, void *raw_data); 115 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
116static void nfs_kill_super(struct super_block *); 116static void nfs_kill_super(struct super_block *);
117 117
118static struct file_system_type nfs_fs_type = { 118static struct file_system_type nfs_fs_type = {
@@ -143,12 +143,12 @@ static struct super_operations nfs_sops = {
143}; 143};
144 144
145#ifdef CONFIG_NFS_V4 145#ifdef CONFIG_NFS_V4
146static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, 146static int nfs4_get_sb(struct file_system_type *fs_type,
147 int flags, const char *dev_name, void *raw_data); 147 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
148static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type, 148static int nfs_clone_nfs4_sb(struct file_system_type *fs_type,
149 int flags, const char *dev_name, void *raw_data); 149 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
150static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type, 150static int nfs_referral_nfs4_sb(struct file_system_type *fs_type,
151 int flags, const char *dev_name, void *raw_data); 151 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
152static void nfs4_kill_super(struct super_block *sb); 152static void nfs4_kill_super(struct super_block *sb);
153 153
154static struct file_system_type nfs4_fs_type = { 154static struct file_system_type nfs4_fs_type = {
@@ -263,8 +263,9 @@ void __exit unregister_nfs_fs(void)
263/* 263/*
264 * Deliver file system statistics to userspace 264 * Deliver file system statistics to userspace
265 */ 265 */
266static int nfs_statfs(struct super_block *sb, struct kstatfs *buf) 266static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
267{ 267{
268 struct super_block *sb = dentry->d_sb;
268 struct nfs_server *server = NFS_SB(sb); 269 struct nfs_server *server = NFS_SB(sb);
269 unsigned char blockbits; 270 unsigned char blockbits;
270 unsigned long blockres; 271 unsigned long blockres;
@@ -770,15 +771,16 @@ out:
770/* 771/*
771 * Copy an existing superblock and attach revised data 772 * Copy an existing superblock and attach revised data
772 */ 773 */
773static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data, 774static int nfs_clone_generic_sb(struct nfs_clone_mount *data,
774 struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *), 775 struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *),
775 struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *)) 776 struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *),
777 struct vfsmount *mnt)
776{ 778{
777 struct nfs_server *server; 779 struct nfs_server *server;
778 struct nfs_server *parent = NFS_SB(data->sb); 780 struct nfs_server *parent = NFS_SB(data->sb);
779 struct super_block *sb = ERR_PTR(-EINVAL); 781 struct super_block *sb = ERR_PTR(-EINVAL);
780 void *err = ERR_PTR(-ENOMEM);
781 char *hostname; 782 char *hostname;
783 int error = -ENOMEM;
782 int len; 784 int len;
783 785
784 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL); 786 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
@@ -791,21 +793,34 @@ static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data,
791 if (server->hostname == NULL) 793 if (server->hostname == NULL)
792 goto free_server; 794 goto free_server;
793 memcpy(server->hostname, hostname, len); 795 memcpy(server->hostname, hostname, len);
794 if (rpciod_up() != 0) 796 error = rpciod_up();
797 if (error != 0)
795 goto free_hostname; 798 goto free_hostname;
796 799
797 sb = fill_sb(server, data); 800 sb = fill_sb(server, data);
798 if (IS_ERR((err = sb)) || sb->s_root) 801 if (IS_ERR(sb)) {
802 error = PTR_ERR(sb);
799 goto kill_rpciod; 803 goto kill_rpciod;
804 }
805
806 if (sb->s_root)
807 goto out_rpciod_down;
800 808
801 server = fill_server(sb, data); 809 server = fill_server(sb, data);
802 if (IS_ERR((err = server))) 810 if (IS_ERR(server)) {
811 error = PTR_ERR(server);
803 goto out_deactivate; 812 goto out_deactivate;
804 return sb; 813 }
814 return simple_set_mnt(mnt, sb);
805out_deactivate: 815out_deactivate:
806 up_write(&sb->s_umount); 816 up_write(&sb->s_umount);
807 deactivate_super(sb); 817 deactivate_super(sb);
808 return (struct super_block *)err; 818 return error;
819out_rpciod_down:
820 rpciod_down();
821 kfree(server->hostname);
822 kfree(server);
823 return simple_set_mnt(mnt, sb);
809kill_rpciod: 824kill_rpciod:
810 rpciod_down(); 825 rpciod_down();
811free_hostname: 826free_hostname:
@@ -813,7 +828,7 @@ free_hostname:
813free_server: 828free_server:
814 kfree(server); 829 kfree(server);
815out_err: 830out_err:
816 return (struct super_block *)err; 831 return error;
817} 832}
818 833
819/* 834/*
@@ -939,8 +954,8 @@ static int nfs_compare_super(struct super_block *sb, void *data)
939 return !nfs_compare_fh(&old->fh, &server->fh); 954 return !nfs_compare_fh(&old->fh, &server->fh);
940} 955}
941 956
942static struct super_block *nfs_get_sb(struct file_system_type *fs_type, 957static int nfs_get_sb(struct file_system_type *fs_type,
943 int flags, const char *dev_name, void *raw_data) 958 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
944{ 959{
945 int error; 960 int error;
946 struct nfs_server *server = NULL; 961 struct nfs_server *server = NULL;
@@ -948,14 +963,14 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
948 struct nfs_fh *root; 963 struct nfs_fh *root;
949 struct nfs_mount_data *data = raw_data; 964 struct nfs_mount_data *data = raw_data;
950 965
951 s = ERR_PTR(-EINVAL); 966 error = -EINVAL;
952 if (data == NULL) { 967 if (data == NULL) {
953 dprintk("%s: missing data argument\n", __FUNCTION__); 968 dprintk("%s: missing data argument\n", __FUNCTION__);
954 goto out_err; 969 goto out_err_noserver;
955 } 970 }
956 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) { 971 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
957 dprintk("%s: bad mount version\n", __FUNCTION__); 972 dprintk("%s: bad mount version\n", __FUNCTION__);
958 goto out_err; 973 goto out_err_noserver;
959 } 974 }
960 switch (data->version) { 975 switch (data->version) {
961 case 1: 976 case 1:
@@ -967,7 +982,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
967 dprintk("%s: mount structure version %d does not support NFSv3\n", 982 dprintk("%s: mount structure version %d does not support NFSv3\n",
968 __FUNCTION__, 983 __FUNCTION__,
969 data->version); 984 data->version);
970 goto out_err; 985 goto out_err_noserver;
971 } 986 }
972 data->root.size = NFS2_FHSIZE; 987 data->root.size = NFS2_FHSIZE;
973 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); 988 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
@@ -976,24 +991,24 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
976 dprintk("%s: mount structure version %d does not support strong security\n", 991 dprintk("%s: mount structure version %d does not support strong security\n",
977 __FUNCTION__, 992 __FUNCTION__,
978 data->version); 993 data->version);
979 goto out_err; 994 goto out_err_noserver;
980 } 995 }
981 case 5: 996 case 5:
982 memset(data->context, 0, sizeof(data->context)); 997 memset(data->context, 0, sizeof(data->context));
983 } 998 }
984#ifndef CONFIG_NFS_V3 999#ifndef CONFIG_NFS_V3
985 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */ 1000 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
986 s = ERR_PTR(-EPROTONOSUPPORT); 1001 error = -EPROTONOSUPPORT;
987 if (data->flags & NFS_MOUNT_VER3) { 1002 if (data->flags & NFS_MOUNT_VER3) {
988 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__); 1003 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
989 goto out_err; 1004 goto out_err_noserver;
990 } 1005 }
991#endif /* CONFIG_NFS_V3 */ 1006#endif /* CONFIG_NFS_V3 */
992 1007
993 s = ERR_PTR(-ENOMEM); 1008 error = -ENOMEM;
994 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); 1009 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
995 if (!server) 1010 if (!server)
996 goto out_err; 1011 goto out_err_noserver;
997 /* Zero out the NFS state stuff */ 1012 /* Zero out the NFS state stuff */
998 init_nfsv4_state(server); 1013 init_nfsv4_state(server);
999 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 1014 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -1003,7 +1018,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1003 root->size = data->root.size; 1018 root->size = data->root.size;
1004 else 1019 else
1005 root->size = NFS2_FHSIZE; 1020 root->size = NFS2_FHSIZE;
1006 s = ERR_PTR(-EINVAL); 1021 error = -EINVAL;
1007 if (root->size > sizeof(root->data)) { 1022 if (root->size > sizeof(root->data)) {
1008 dprintk("%s: invalid root filehandle\n", __FUNCTION__); 1023 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
1009 goto out_err; 1024 goto out_err;
@@ -1019,15 +1034,20 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1019 } 1034 }
1020 1035
1021 /* Fire up rpciod if not yet running */ 1036 /* Fire up rpciod if not yet running */
1022 s = ERR_PTR(rpciod_up()); 1037 error = rpciod_up();
1023 if (IS_ERR(s)) { 1038 if (error < 0) {
1024 dprintk("%s: couldn't start rpciod! Error = %ld\n", 1039 dprintk("%s: couldn't start rpciod! Error = %d\n",
1025 __FUNCTION__, PTR_ERR(s)); 1040 __FUNCTION__, error);
1026 goto out_err; 1041 goto out_err;
1027 } 1042 }
1028 1043
1029 s = sget(fs_type, nfs_compare_super, nfs_set_super, server); 1044 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1030 if (IS_ERR(s) || s->s_root) 1045 if (IS_ERR(s)) {
1046 error = PTR_ERR(s);
1047 goto out_err_rpciod;
1048 }
1049
1050 if (s->s_root)
1031 goto out_rpciod_down; 1051 goto out_rpciod_down;
1032 1052
1033 s->s_flags = flags; 1053 s->s_flags = flags;
@@ -1036,15 +1056,22 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1036 if (error) { 1056 if (error) {
1037 up_write(&s->s_umount); 1057 up_write(&s->s_umount);
1038 deactivate_super(s); 1058 deactivate_super(s);
1039 return ERR_PTR(error); 1059 return error;
1040 } 1060 }
1041 s->s_flags |= MS_ACTIVE; 1061 s->s_flags |= MS_ACTIVE;
1042 return s; 1062 return simple_set_mnt(mnt, s);
1063
1043out_rpciod_down: 1064out_rpciod_down:
1044 rpciod_down(); 1065 rpciod_down();
1066 kfree(server);
1067 return simple_set_mnt(mnt, s);
1068
1069out_err_rpciod:
1070 rpciod_down();
1045out_err: 1071out_err:
1046 kfree(server); 1072 kfree(server);
1047 return s; 1073out_err_noserver:
1074 return error;
1048} 1075}
1049 1076
1050static void nfs_kill_super(struct super_block *s) 1077static void nfs_kill_super(struct super_block *s)
@@ -1083,11 +1110,11 @@ static struct super_block *nfs_clone_sb(struct nfs_server *server, struct nfs_cl
1083 return sb; 1110 return sb;
1084} 1111}
1085 1112
1086static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type, 1113static int nfs_clone_nfs_sb(struct file_system_type *fs_type,
1087 int flags, const char *dev_name, void *raw_data) 1114 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1088{ 1115{
1089 struct nfs_clone_mount *data = raw_data; 1116 struct nfs_clone_mount *data = raw_data;
1090 return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server); 1117 return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server, mnt);
1091} 1118}
1092 1119
1093#ifdef CONFIG_NFS_V4 1120#ifdef CONFIG_NFS_V4
@@ -1266,8 +1293,8 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
1266 return dst; 1293 return dst;
1267} 1294}
1268 1295
1269static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, 1296static int nfs4_get_sb(struct file_system_type *fs_type,
1270 int flags, const char *dev_name, void *raw_data) 1297 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1271{ 1298{
1272 int error; 1299 int error;
1273 struct nfs_server *server; 1300 struct nfs_server *server;
@@ -1277,16 +1304,16 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1277 1304
1278 if (data == NULL) { 1305 if (data == NULL) {
1279 dprintk("%s: missing data argument\n", __FUNCTION__); 1306 dprintk("%s: missing data argument\n", __FUNCTION__);
1280 return ERR_PTR(-EINVAL); 1307 return -EINVAL;
1281 } 1308 }
1282 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) { 1309 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
1283 dprintk("%s: bad mount version\n", __FUNCTION__); 1310 dprintk("%s: bad mount version\n", __FUNCTION__);
1284 return ERR_PTR(-EINVAL); 1311 return -EINVAL;
1285 } 1312 }
1286 1313
1287 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); 1314 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
1288 if (!server) 1315 if (!server)
1289 return ERR_PTR(-ENOMEM); 1316 return -ENOMEM;
1290 /* Zero out the NFS state stuff */ 1317 /* Zero out the NFS state stuff */
1291 init_nfsv4_state(server); 1318 init_nfsv4_state(server);
1292 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 1319 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
@@ -1308,33 +1335,42 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1308 1335
1309 /* We now require that the mount process passes the remote address */ 1336 /* We now require that the mount process passes the remote address */
1310 if (data->host_addrlen != sizeof(server->addr)) { 1337 if (data->host_addrlen != sizeof(server->addr)) {
1311 s = ERR_PTR(-EINVAL); 1338 error = -EINVAL;
1312 goto out_free; 1339 goto out_free;
1313 } 1340 }
1314 if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) { 1341 if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) {
1315 s = ERR_PTR(-EFAULT); 1342 error = -EFAULT;
1316 goto out_free; 1343 goto out_free;
1317 } 1344 }
1318 if (server->addr.sin_family != AF_INET || 1345 if (server->addr.sin_family != AF_INET ||
1319 server->addr.sin_addr.s_addr == INADDR_ANY) { 1346 server->addr.sin_addr.s_addr == INADDR_ANY) {
1320 dprintk("%s: mount program didn't pass remote IP address!\n", 1347 dprintk("%s: mount program didn't pass remote IP address!\n",
1321 __FUNCTION__); 1348 __FUNCTION__);
1322 s = ERR_PTR(-EINVAL); 1349 error = -EINVAL;
1323 goto out_free; 1350 goto out_free;
1324 } 1351 }
1325 1352
1326 /* Fire up rpciod if not yet running */ 1353 /* Fire up rpciod if not yet running */
1327 s = ERR_PTR(rpciod_up()); 1354 error = rpciod_up();
1328 if (IS_ERR(s)) { 1355 if (error < 0) {
1329 dprintk("%s: couldn't start rpciod! Error = %ld\n", 1356 dprintk("%s: couldn't start rpciod! Error = %d\n",
1330 __FUNCTION__, PTR_ERR(s)); 1357 __FUNCTION__, error);
1331 goto out_free; 1358 goto out_free;
1332 } 1359 }
1333 1360
1334 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server); 1361 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
1335 1362
1336 if (IS_ERR(s) || s->s_root) 1363 if (IS_ERR(s)) {
1364 error = PTR_ERR(s);
1337 goto out_free; 1365 goto out_free;
1366 }
1367
1368 if (s->s_root) {
1369 kfree(server->mnt_path);
1370 kfree(server->hostname);
1371 kfree(server);
1372 return simple_set_mnt(mnt, s);
1373 }
1338 1374
1339 s->s_flags = flags; 1375 s->s_flags = flags;
1340 1376
@@ -1342,17 +1378,17 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1342 if (error) { 1378 if (error) {
1343 up_write(&s->s_umount); 1379 up_write(&s->s_umount);
1344 deactivate_super(s); 1380 deactivate_super(s);
1345 return ERR_PTR(error); 1381 return error;
1346 } 1382 }
1347 s->s_flags |= MS_ACTIVE; 1383 s->s_flags |= MS_ACTIVE;
1348 return s; 1384 return simple_set_mnt(mnt, s);
1349out_err: 1385out_err:
1350 s = (struct super_block *)p; 1386 error = PTR_ERR(p);
1351out_free: 1387out_free:
1352 kfree(server->mnt_path); 1388 kfree(server->mnt_path);
1353 kfree(server->hostname); 1389 kfree(server->hostname);
1354 kfree(server); 1390 kfree(server);
1355 return s; 1391 return error;
1356} 1392}
1357 1393
1358static void nfs4_kill_super(struct super_block *sb) 1394static void nfs4_kill_super(struct super_block *sb)
@@ -1430,11 +1466,11 @@ err:
1430 return sb; 1466 return sb;
1431} 1467}
1432 1468
1433static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type, 1469static int nfs_clone_nfs4_sb(struct file_system_type *fs_type,
1434 int flags, const char *dev_name, void *raw_data) 1470 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1435{ 1471{
1436 struct nfs_clone_mount *data = raw_data; 1472 struct nfs_clone_mount *data = raw_data;
1437 return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server); 1473 return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server, mnt);
1438} 1474}
1439 1475
1440static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data) 1476static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data)
@@ -1487,11 +1523,11 @@ out_err:
1487 return (struct nfs_server *)err; 1523 return (struct nfs_server *)err;
1488} 1524}
1489 1525
1490static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type, 1526static int nfs_referral_nfs4_sb(struct file_system_type *fs_type,
1491 int flags, const char *dev_name, void *raw_data) 1527 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1492{ 1528{
1493 struct nfs_clone_mount *data = raw_data; 1529 struct nfs_clone_mount *data = raw_data;
1494 return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server); 1530 return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server, mnt);
1495} 1531}
1496 1532
1497#endif 1533#endif
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index de3998f15f10..5446a0861d1d 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1310,7 +1310,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1310 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) || 1310 if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL)) ||
1311 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | 1311 (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
1312 FATTR4_WORD1_SPACE_TOTAL))) { 1312 FATTR4_WORD1_SPACE_TOTAL))) {
1313 status = vfs_statfs(dentry->d_inode->i_sb, &statfs); 1313 status = vfs_statfs(dentry, &statfs);
1314 if (status) 1314 if (status)
1315 goto out_nfserr; 1315 goto out_nfserr;
1316 } 1316 }
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 3ef017b3b5bd..a1810e6a93e5 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -494,10 +494,10 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
494 return simple_fill_super(sb, 0x6e667364, nfsd_files); 494 return simple_fill_super(sb, 0x6e667364, nfsd_files);
495} 495}
496 496
497static struct super_block *nfsd_get_sb(struct file_system_type *fs_type, 497static int nfsd_get_sb(struct file_system_type *fs_type,
498 int flags, const char *dev_name, void *data) 498 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
499{ 499{
500 return get_sb_single(fs_type, flags, data, nfsd_fill_super); 500 return get_sb_single(fs_type, flags, data, nfsd_fill_super, mnt);
501} 501}
502 502
503static struct file_system_type nfsd_fs_type = { 503static struct file_system_type nfsd_fs_type = {
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 1d65f13f458c..245eaa1fb59b 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1737,7 +1737,7 @@ int
1737nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) 1737nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
1738{ 1738{
1739 int err = fh_verify(rqstp, fhp, 0, MAY_NOP); 1739 int err = fh_verify(rqstp, fhp, 0, MAY_NOP);
1740 if (!err && vfs_statfs(fhp->fh_dentry->d_inode->i_sb,stat)) 1740 if (!err && vfs_statfs(fhp->fh_dentry,stat))
1741 err = nfserr_io; 1741 err = nfserr_io;
1742 return err; 1742 return err;
1743} 1743}
diff --git a/fs/ntfs/aops.h b/fs/ntfs/aops.h
index 3b74e66ca2ff..325ce261a107 100644
--- a/fs/ntfs/aops.h
+++ b/fs/ntfs/aops.h
@@ -86,8 +86,7 @@ static inline void ntfs_unmap_page(struct page *page)
86static inline struct page *ntfs_map_page(struct address_space *mapping, 86static inline struct page *ntfs_map_page(struct address_space *mapping,
87 unsigned long index) 87 unsigned long index)
88{ 88{
89 struct page *page = read_cache_page(mapping, index, 89 struct page *page = read_mapping_page(mapping, index, NULL);
90 (filler_t*)mapping->a_ops->readpage, NULL);
91 90
92 if (!IS_ERR(page)) { 91 if (!IS_ERR(page)) {
93 wait_on_page_locked(page); 92 wait_on_page_locked(page);
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 1663f5c3c6aa..6708e1d68a9e 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -2529,8 +2529,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
2529 end >>= PAGE_CACHE_SHIFT; 2529 end >>= PAGE_CACHE_SHIFT;
2530 /* If there is a first partial page, need to do it the slow way. */ 2530 /* If there is a first partial page, need to do it the slow way. */
2531 if (start_ofs) { 2531 if (start_ofs) {
2532 page = read_cache_page(mapping, idx, 2532 page = read_mapping_page(mapping, idx, NULL);
2533 (filler_t*)mapping->a_ops->readpage, NULL);
2534 if (IS_ERR(page)) { 2533 if (IS_ERR(page)) {
2535 ntfs_error(vol->sb, "Failed to read first partial " 2534 ntfs_error(vol->sb, "Failed to read first partial "
2536 "page (sync error, index 0x%lx).", idx); 2535 "page (sync error, index 0x%lx).", idx);
@@ -2600,8 +2599,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
2600 } 2599 }
2601 /* If there is a last partial page, need to do it the slow way. */ 2600 /* If there is a last partial page, need to do it the slow way. */
2602 if (end_ofs) { 2601 if (end_ofs) {
2603 page = read_cache_page(mapping, idx, 2602 page = read_mapping_page(mapping, idx, NULL);
2604 (filler_t*)mapping->a_ops->readpage, NULL);
2605 if (IS_ERR(page)) { 2603 if (IS_ERR(page)) {
2606 ntfs_error(vol->sb, "Failed to read last partial page " 2604 ntfs_error(vol->sb, "Failed to read last partial page "
2607 "(sync error, index 0x%lx).", idx); 2605 "(sync error, index 0x%lx).", idx);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index c63a83e8da98..88292f9e4b9b 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -231,8 +231,7 @@ do_non_resident_extend:
231 * Read the page. If the page is not present, this will zero 231 * Read the page. If the page is not present, this will zero
232 * the uninitialized regions for us. 232 * the uninitialized regions for us.
233 */ 233 */
234 page = read_cache_page(mapping, index, 234 page = read_mapping_page(mapping, index, NULL);
235 (filler_t*)mapping->a_ops->readpage, NULL);
236 if (IS_ERR(page)) { 235 if (IS_ERR(page)) {
237 err = PTR_ERR(page); 236 err = PTR_ERR(page);
238 goto init_err_out; 237 goto init_err_out;
@@ -1484,14 +1483,15 @@ static inline void ntfs_flush_dcache_pages(struct page **pages,
1484 unsigned nr_pages) 1483 unsigned nr_pages)
1485{ 1484{
1486 BUG_ON(!nr_pages); 1485 BUG_ON(!nr_pages);
1486 /*
1487 * Warning: Do not do the decrement at the same time as the call to
1488 * flush_dcache_page() because it is a NULL macro on i386 and hence the
1489 * decrement never happens so the loop never terminates.
1490 */
1487 do { 1491 do {
1488 /* 1492 --nr_pages;
1489 * Warning: Do not do the decrement at the same time as the
1490 * call because flush_dcache_page() is a NULL macro on i386
1491 * and hence the decrement never happens.
1492 */
1493 flush_dcache_page(pages[nr_pages]); 1493 flush_dcache_page(pages[nr_pages]);
1494 } while (--nr_pages > 0); 1494 } while (nr_pages > 0);
1495} 1495}
1496 1496
1497/** 1497/**
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 27833f6df49f..0e14acea3f8b 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2601,10 +2601,10 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
2601 2601
2602/** 2602/**
2603 * ntfs_statfs - return information about mounted NTFS volume 2603 * ntfs_statfs - return information about mounted NTFS volume
2604 * @sb: super block of mounted volume 2604 * @dentry: dentry from mounted volume
2605 * @sfs: statfs structure in which to return the information 2605 * @sfs: statfs structure in which to return the information
2606 * 2606 *
2607 * Return information about the mounted NTFS volume @sb in the statfs structure 2607 * Return information about the mounted NTFS volume @dentry in the statfs structure
2608 * pointed to by @sfs (this is initialized with zeros before ntfs_statfs is 2608 * pointed to by @sfs (this is initialized with zeros before ntfs_statfs is
2609 * called). We interpret the values to be correct of the moment in time at 2609 * called). We interpret the values to be correct of the moment in time at
2610 * which we are called. Most values are variable otherwise and this isn't just 2610 * which we are called. Most values are variable otherwise and this isn't just
@@ -2617,8 +2617,9 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
2617 * 2617 *
2618 * Return 0 on success or -errno on error. 2618 * Return 0 on success or -errno on error.
2619 */ 2619 */
2620static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs) 2620static int ntfs_statfs(struct dentry *dentry, struct kstatfs *sfs)
2621{ 2621{
2622 struct super_block *sb = dentry->d_sb;
2622 s64 size; 2623 s64 size;
2623 ntfs_volume *vol = NTFS_SB(sb); 2624 ntfs_volume *vol = NTFS_SB(sb);
2624 ntfs_inode *mft_ni = NTFS_I(vol->mft_ino); 2625 ntfs_inode *mft_ni = NTFS_I(vol->mft_ino);
@@ -3093,10 +3094,11 @@ struct kmem_cache *ntfs_index_ctx_cache;
3093/* Driver wide mutex. */ 3094/* Driver wide mutex. */
3094DEFINE_MUTEX(ntfs_lock); 3095DEFINE_MUTEX(ntfs_lock);
3095 3096
3096static struct super_block *ntfs_get_sb(struct file_system_type *fs_type, 3097static int ntfs_get_sb(struct file_system_type *fs_type,
3097 int flags, const char *dev_name, void *data) 3098 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
3098{ 3099{
3099 return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super); 3100 return get_sb_bdev(fs_type, flags, dev_name, data, ntfs_fill_super,
3101 mnt);
3100} 3102}
3101 3103
3102static struct file_system_type ntfs_fs_type = { 3104static struct file_system_type ntfs_fs_type = {
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
index 7e88e24b3471..7273d9fa6bab 100644
--- a/fs/ocfs2/dlm/dlmfs.c
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -574,10 +574,10 @@ static struct inode_operations dlmfs_file_inode_operations = {
574 .getattr = simple_getattr, 574 .getattr = simple_getattr,
575}; 575};
576 576
577static struct super_block *dlmfs_get_sb(struct file_system_type *fs_type, 577static int dlmfs_get_sb(struct file_system_type *fs_type,
578 int flags, const char *dev_name, void *data) 578 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
579{ 579{
580 return get_sb_nodev(fs_type, flags, data, dlmfs_fill_super); 580 return get_sb_nodev(fs_type, flags, data, dlmfs_fill_super, mnt);
581} 581}
582 582
583static struct file_system_type dlmfs_fs_type = { 583static struct file_system_type dlmfs_fs_type = {
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 949b3dac30f1..cdf73393f094 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -100,7 +100,7 @@ static int ocfs2_initialize_mem_caches(void);
100static void ocfs2_free_mem_caches(void); 100static void ocfs2_free_mem_caches(void);
101static void ocfs2_delete_osb(struct ocfs2_super *osb); 101static void ocfs2_delete_osb(struct ocfs2_super *osb);
102 102
103static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf); 103static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf);
104 104
105static int ocfs2_sync_fs(struct super_block *sb, int wait); 105static int ocfs2_sync_fs(struct super_block *sb, int wait);
106 106
@@ -672,12 +672,14 @@ read_super_error:
672 return status; 672 return status;
673} 673}
674 674
675static struct super_block *ocfs2_get_sb(struct file_system_type *fs_type, 675static int ocfs2_get_sb(struct file_system_type *fs_type,
676 int flags, 676 int flags,
677 const char *dev_name, 677 const char *dev_name,
678 void *data) 678 void *data,
679 struct vfsmount *mnt)
679{ 680{
680 return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super); 681 return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super,
682 mnt);
681} 683}
682 684
683static struct file_system_type ocfs2_fs_type = { 685static struct file_system_type ocfs2_fs_type = {
@@ -855,7 +857,7 @@ static void ocfs2_put_super(struct super_block *sb)
855 mlog_exit_void(); 857 mlog_exit_void();
856} 858}
857 859
858static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf) 860static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
859{ 861{
860 struct ocfs2_super *osb; 862 struct ocfs2_super *osb;
861 u32 numbits, freebits; 863 u32 numbits, freebits;
@@ -864,9 +866,9 @@ static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf)
864 struct buffer_head *bh = NULL; 866 struct buffer_head *bh = NULL;
865 struct inode *inode = NULL; 867 struct inode *inode = NULL;
866 868
867 mlog_entry("(%p, %p)\n", sb, buf); 869 mlog_entry("(%p, %p)\n", dentry->d_sb, buf);
868 870
869 osb = OCFS2_SB(sb); 871 osb = OCFS2_SB(dentry->d_sb);
870 872
871 inode = ocfs2_get_system_file_inode(osb, 873 inode = ocfs2_get_system_file_inode(osb,
872 GLOBAL_BITMAP_SYSTEM_INODE, 874 GLOBAL_BITMAP_SYSTEM_INODE,
@@ -889,7 +891,7 @@ static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf)
889 freebits = numbits - le32_to_cpu(bm_lock->id1.bitmap1.i_used); 891 freebits = numbits - le32_to_cpu(bm_lock->id1.bitmap1.i_used);
890 892
891 buf->f_type = OCFS2_SUPER_MAGIC; 893 buf->f_type = OCFS2_SUPER_MAGIC;
892 buf->f_bsize = sb->s_blocksize; 894 buf->f_bsize = dentry->d_sb->s_blocksize;
893 buf->f_namelen = OCFS2_MAX_FILENAME_LEN; 895 buf->f_namelen = OCFS2_MAX_FILENAME_LEN;
894 buf->f_blocks = ((sector_t) numbits) * 896 buf->f_blocks = ((sector_t) numbits) *
895 (osb->s_clustersize >> osb->sb->s_blocksize_bits); 897 (osb->s_clustersize >> osb->sb->s_blocksize_bits);
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index f6986bd79e75..0c8a1294ec96 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -64,8 +64,7 @@ static char *ocfs2_page_getlink(struct dentry * dentry,
64{ 64{
65 struct page * page; 65 struct page * page;
66 struct address_space *mapping = dentry->d_inode->i_mapping; 66 struct address_space *mapping = dentry->d_inode->i_mapping;
67 page = read_cache_page(mapping, 0, 67 page = read_mapping_page(mapping, 0, NULL);
68 (filler_t *)mapping->a_ops->readpage, NULL);
69 if (IS_ERR(page)) 68 if (IS_ERR(page))
70 goto sync_fail; 69 goto sync_fail;
71 wait_on_page_locked(page); 70 wait_on_page_locked(page);
diff --git a/fs/open.c b/fs/open.c
index 4f178acd4c09..5fb16e5267dc 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -31,18 +31,18 @@
31 31
32#include <asm/unistd.h> 32#include <asm/unistd.h>
33 33
34int vfs_statfs(struct super_block *sb, struct kstatfs *buf) 34int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
35{ 35{
36 int retval = -ENODEV; 36 int retval = -ENODEV;
37 37
38 if (sb) { 38 if (dentry) {
39 retval = -ENOSYS; 39 retval = -ENOSYS;
40 if (sb->s_op->statfs) { 40 if (dentry->d_sb->s_op->statfs) {
41 memset(buf, 0, sizeof(*buf)); 41 memset(buf, 0, sizeof(*buf));
42 retval = security_sb_statfs(sb); 42 retval = security_sb_statfs(dentry);
43 if (retval) 43 if (retval)
44 return retval; 44 return retval;
45 retval = sb->s_op->statfs(sb, buf); 45 retval = dentry->d_sb->s_op->statfs(dentry, buf);
46 if (retval == 0 && buf->f_frsize == 0) 46 if (retval == 0 && buf->f_frsize == 0)
47 buf->f_frsize = buf->f_bsize; 47 buf->f_frsize = buf->f_bsize;
48 } 48 }
@@ -52,12 +52,12 @@ int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
52 52
53EXPORT_SYMBOL(vfs_statfs); 53EXPORT_SYMBOL(vfs_statfs);
54 54
55static int vfs_statfs_native(struct super_block *sb, struct statfs *buf) 55static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf)
56{ 56{
57 struct kstatfs st; 57 struct kstatfs st;
58 int retval; 58 int retval;
59 59
60 retval = vfs_statfs(sb, &st); 60 retval = vfs_statfs(dentry, &st);
61 if (retval) 61 if (retval)
62 return retval; 62 return retval;
63 63
@@ -95,12 +95,12 @@ static int vfs_statfs_native(struct super_block *sb, struct statfs *buf)
95 return 0; 95 return 0;
96} 96}
97 97
98static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf) 98static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf)
99{ 99{
100 struct kstatfs st; 100 struct kstatfs st;
101 int retval; 101 int retval;
102 102
103 retval = vfs_statfs(sb, &st); 103 retval = vfs_statfs(dentry, &st);
104 if (retval) 104 if (retval)
105 return retval; 105 return retval;
106 106
@@ -130,7 +130,7 @@ asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf)
130 error = user_path_walk(path, &nd); 130 error = user_path_walk(path, &nd);
131 if (!error) { 131 if (!error) {
132 struct statfs tmp; 132 struct statfs tmp;
133 error = vfs_statfs_native(nd.dentry->d_inode->i_sb, &tmp); 133 error = vfs_statfs_native(nd.dentry, &tmp);
134 if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 134 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
135 error = -EFAULT; 135 error = -EFAULT;
136 path_release(&nd); 136 path_release(&nd);
@@ -149,7 +149,7 @@ asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64
149 error = user_path_walk(path, &nd); 149 error = user_path_walk(path, &nd);
150 if (!error) { 150 if (!error) {
151 struct statfs64 tmp; 151 struct statfs64 tmp;
152 error = vfs_statfs64(nd.dentry->d_inode->i_sb, &tmp); 152 error = vfs_statfs64(nd.dentry, &tmp);
153 if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 153 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
154 error = -EFAULT; 154 error = -EFAULT;
155 path_release(&nd); 155 path_release(&nd);
@@ -168,7 +168,7 @@ asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf)
168 file = fget(fd); 168 file = fget(fd);
169 if (!file) 169 if (!file)
170 goto out; 170 goto out;
171 error = vfs_statfs_native(file->f_dentry->d_inode->i_sb, &tmp); 171 error = vfs_statfs_native(file->f_dentry, &tmp);
172 if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 172 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
173 error = -EFAULT; 173 error = -EFAULT;
174 fput(file); 174 fput(file);
@@ -189,7 +189,7 @@ asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user
189 file = fget(fd); 189 file = fget(fd);
190 if (!file) 190 if (!file)
191 goto out; 191 goto out;
192 error = vfs_statfs64(file->f_dentry->d_inode->i_sb, &tmp); 192 error = vfs_statfs64(file->f_dentry, &tmp);
193 if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 193 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
194 error = -EFAULT; 194 error = -EFAULT;
195 fput(file); 195 fput(file);
@@ -1152,7 +1152,7 @@ int filp_close(struct file *filp, fl_owner_t id)
1152 } 1152 }
1153 1153
1154 if (filp->f_op && filp->f_op->flush) 1154 if (filp->f_op && filp->f_op->flush)
1155 retval = filp->f_op->flush(filp); 1155 retval = filp->f_op->flush(filp, id);
1156 1156
1157 dnotify_flush(filp, id); 1157 dnotify_flush(filp, id);
1158 locks_remove_posix(filp, id); 1158 locks_remove_posix(filp, id);
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 0f14276a2e51..464e2bce0203 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -1054,10 +1054,10 @@ out_no_root:
1054 return -ENOMEM; 1054 return -ENOMEM;
1055} 1055}
1056 1056
1057static struct super_block *openprom_get_sb(struct file_system_type *fs_type, 1057static int openprom_get_sb(struct file_system_type *fs_type,
1058 int flags, const char *dev_name, void *data) 1058 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1059{ 1059{
1060 return get_sb_single(fs_type, flags, data, openprom_fill_super); 1060 return get_sb_single(fs_type, flags, data, openprom_fill_super, mnt);
1061} 1061}
1062 1062
1063static struct file_system_type openprom_fs_type = { 1063static struct file_system_type openprom_fs_type = {
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 7ef1f094de91..2ef313a96b66 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -329,6 +329,7 @@ void delete_partition(struct gendisk *disk, int part)
329 p->ios[0] = p->ios[1] = 0; 329 p->ios[0] = p->ios[1] = 0;
330 p->sectors[0] = p->sectors[1] = 0; 330 p->sectors[0] = p->sectors[1] = 0;
331 devfs_remove("%s/part%d", disk->devfs_name, part); 331 devfs_remove("%s/part%d", disk->devfs_name, part);
332 sysfs_remove_link(&p->kobj, "subsystem");
332 if (p->holder_dir) 333 if (p->holder_dir)
333 kobject_unregister(p->holder_dir); 334 kobject_unregister(p->holder_dir);
334 kobject_uevent(&p->kobj, KOBJ_REMOVE); 335 kobject_uevent(&p->kobj, KOBJ_REMOVE);
@@ -363,6 +364,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
363 kobject_add(&p->kobj); 364 kobject_add(&p->kobj);
364 if (!disk->part_uevent_suppress) 365 if (!disk->part_uevent_suppress)
365 kobject_uevent(&p->kobj, KOBJ_ADD); 366 kobject_uevent(&p->kobj, KOBJ_ADD);
367 sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem");
366 partition_sysfs_add_subdir(p); 368 partition_sysfs_add_subdir(p);
367 disk->part[part-1] = p; 369 disk->part[part-1] = p;
368} 370}
@@ -398,6 +400,7 @@ static void disk_sysfs_symlinks(struct gendisk *disk)
398 kfree(disk_name); 400 kfree(disk_name);
399 } 401 }
400 } 402 }
403 sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, "subsystem");
401} 404}
402 405
403/* Not exported, helper to add_disk(). */ 406/* Not exported, helper to add_disk(). */
@@ -481,6 +484,10 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
481 sector_t from = state->parts[p].from; 484 sector_t from = state->parts[p].from;
482 if (!size) 485 if (!size)
483 continue; 486 continue;
487 if (from + size > get_capacity(disk)) {
488 printk(" %s: p%d exceeds device capacity\n",
489 disk->disk_name, p);
490 }
484 add_partition(disk, p, from, size); 491 add_partition(disk, p, from, size);
485#ifdef CONFIG_BLK_DEV_MD 492#ifdef CONFIG_BLK_DEV_MD
486 if (state->parts[p].flags) 493 if (state->parts[p].flags)
@@ -496,8 +503,8 @@ unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
496 struct address_space *mapping = bdev->bd_inode->i_mapping; 503 struct address_space *mapping = bdev->bd_inode->i_mapping;
497 struct page *page; 504 struct page *page;
498 505
499 page = read_cache_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), 506 page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)),
500 (filler_t *)mapping->a_ops->readpage, NULL); 507 NULL);
501 if (!IS_ERR(page)) { 508 if (!IS_ERR(page)) {
502 wait_on_page_locked(page); 509 wait_on_page_locked(page);
503 if (!PageUptodate(page)) 510 if (!PageUptodate(page))
@@ -548,5 +555,6 @@ void del_gendisk(struct gendisk *disk)
548 put_device(disk->driverfs_dev); 555 put_device(disk->driverfs_dev);
549 disk->driverfs_dev = NULL; 556 disk->driverfs_dev = NULL;
550 } 557 }
558 sysfs_remove_link(&disk->kobj, "subsystem");
551 kobject_del(&disk->kobj); 559 kobject_del(&disk->kobj);
552} 560}
diff --git a/fs/pipe.c b/fs/pipe.c
index 5acd8954aaa0..20352573e025 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -979,12 +979,11 @@ no_files:
979 * any operations on the root directory. However, we need a non-trivial 979 * any operations on the root directory. However, we need a non-trivial
980 * d_name - pipe: will go nicely and kill the special-casing in procfs. 980 * d_name - pipe: will go nicely and kill the special-casing in procfs.
981 */ 981 */
982 982static int pipefs_get_sb(struct file_system_type *fs_type,
983static struct super_block * 983 int flags, const char *dev_name, void *data,
984pipefs_get_sb(struct file_system_type *fs_type, int flags, 984 struct vfsmount *mnt)
985 const char *dev_name, void *data)
986{ 985{
987 return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC); 986 return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC, mnt);
988} 987}
989 988
990static struct file_system_type pipe_fs_type = { 989static struct file_system_type pipe_fs_type = {
diff --git a/fs/proc/root.c b/fs/proc/root.c
index c3fd3611112f..9995356ce73e 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -26,10 +26,10 @@ struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc
26struct proc_dir_entry *proc_sys_root; 26struct proc_dir_entry *proc_sys_root;
27#endif 27#endif
28 28
29static struct super_block *proc_get_sb(struct file_system_type *fs_type, 29static int proc_get_sb(struct file_system_type *fs_type,
30 int flags, const char *dev_name, void *data) 30 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
31{ 31{
32 return get_sb_single(fs_type, flags, data, proc_fill_super); 32 return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
33} 33}
34 34
35static struct file_system_type proc_fs_type = { 35static struct file_system_type proc_fs_type = {
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 2ecd46f85e9f..2f24c46f72a1 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -128,7 +128,7 @@ static struct inode *qnx4_alloc_inode(struct super_block *sb);
128static void qnx4_destroy_inode(struct inode *inode); 128static void qnx4_destroy_inode(struct inode *inode);
129static void qnx4_read_inode(struct inode *); 129static void qnx4_read_inode(struct inode *);
130static int qnx4_remount(struct super_block *sb, int *flags, char *data); 130static int qnx4_remount(struct super_block *sb, int *flags, char *data);
131static int qnx4_statfs(struct super_block *, struct kstatfs *); 131static int qnx4_statfs(struct dentry *, struct kstatfs *);
132 132
133static struct super_operations qnx4_sops = 133static struct super_operations qnx4_sops =
134{ 134{
@@ -282,8 +282,10 @@ unsigned long qnx4_block_map( struct inode *inode, long iblock )
282 return block; 282 return block;
283} 283}
284 284
285static int qnx4_statfs(struct super_block *sb, struct kstatfs *buf) 285static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
286{ 286{
287 struct super_block *sb = dentry->d_sb;
288
287 lock_kernel(); 289 lock_kernel();
288 290
289 buf->f_type = sb->s_magic; 291 buf->f_type = sb->s_magic;
@@ -561,10 +563,11 @@ static void destroy_inodecache(void)
561 "qnx4_inode_cache: not all structures were freed\n"); 563 "qnx4_inode_cache: not all structures were freed\n");
562} 564}
563 565
564static struct super_block *qnx4_get_sb(struct file_system_type *fs_type, 566static int qnx4_get_sb(struct file_system_type *fs_type,
565 int flags, const char *dev_name, void *data) 567 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
566{ 568{
567 return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super); 569 return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super,
570 mnt);
568} 571}
569 572
570static struct file_system_type qnx4_fs_type = { 573static struct file_system_type qnx4_fs_type = {
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index 14bd2246fb6d..b9677335cc8d 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -185,16 +185,17 @@ static int ramfs_fill_super(struct super_block * sb, void * data, int silent)
185 return 0; 185 return 0;
186} 186}
187 187
188struct super_block *ramfs_get_sb(struct file_system_type *fs_type, 188int ramfs_get_sb(struct file_system_type *fs_type,
189 int flags, const char *dev_name, void *data) 189 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
190{ 190{
191 return get_sb_nodev(fs_type, flags, data, ramfs_fill_super); 191 return get_sb_nodev(fs_type, flags, data, ramfs_fill_super, mnt);
192} 192}
193 193
194static struct super_block *rootfs_get_sb(struct file_system_type *fs_type, 194static int rootfs_get_sb(struct file_system_type *fs_type,
195 int flags, const char *dev_name, void *data) 195 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
196{ 196{
197 return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super); 197 return get_sb_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super,
198 mnt);
198} 199}
199 200
200static struct file_system_type ramfs_fs_type = { 201static struct file_system_type ramfs_fs_type = {
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index cae2abbc0c71..00f1321e9209 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -60,7 +60,7 @@ static int is_any_reiserfs_magic_string(struct reiserfs_super_block *rs)
60} 60}
61 61
62static int reiserfs_remount(struct super_block *s, int *flags, char *data); 62static int reiserfs_remount(struct super_block *s, int *flags, char *data);
63static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf); 63static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf);
64 64
65static int reiserfs_sync_fs(struct super_block *s, int wait) 65static int reiserfs_sync_fs(struct super_block *s, int wait)
66{ 66{
@@ -1938,15 +1938,15 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1938 return errval; 1938 return errval;
1939} 1939}
1940 1940
1941static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf) 1941static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf)
1942{ 1942{
1943 struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s); 1943 struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(dentry->d_sb);
1944 1944
1945 buf->f_namelen = (REISERFS_MAX_NAME(s->s_blocksize)); 1945 buf->f_namelen = (REISERFS_MAX_NAME(s->s_blocksize));
1946 buf->f_bfree = sb_free_blocks(rs); 1946 buf->f_bfree = sb_free_blocks(rs);
1947 buf->f_bavail = buf->f_bfree; 1947 buf->f_bavail = buf->f_bfree;
1948 buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1; 1948 buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
1949 buf->f_bsize = s->s_blocksize; 1949 buf->f_bsize = dentry->d_sb->s_blocksize;
1950 /* changed to accommodate gcc folks. */ 1950 /* changed to accommodate gcc folks. */
1951 buf->f_type = REISERFS_SUPER_MAGIC; 1951 buf->f_type = REISERFS_SUPER_MAGIC;
1952 return 0; 1952 return 0;
@@ -2249,11 +2249,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
2249 2249
2250#endif 2250#endif
2251 2251
2252static struct super_block *get_super_block(struct file_system_type *fs_type, 2252static int get_super_block(struct file_system_type *fs_type,
2253 int flags, const char *dev_name, 2253 int flags, const char *dev_name,
2254 void *data) 2254 void *data, struct vfsmount *mnt)
2255{ 2255{
2256 return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super); 2256 return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super,
2257 mnt);
2257} 2258}
2258 2259
2259static int __init init_reiserfs_fs(void) 2260static int __init init_reiserfs_fs(void)
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index ffb79c48c5bf..39fedaa88a0c 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -452,8 +452,7 @@ static struct page *reiserfs_get_page(struct inode *dir, unsigned long n)
452 /* We can deadlock if we try to free dentries, 452 /* We can deadlock if we try to free dentries,
453 and an unlink/rmdir has just occured - GFP_NOFS avoids this */ 453 and an unlink/rmdir has just occured - GFP_NOFS avoids this */
454 mapping_set_gfp_mask(mapping, GFP_NOFS); 454 mapping_set_gfp_mask(mapping, GFP_NOFS);
455 page = read_cache_page(mapping, n, 455 page = read_mapping_page(mapping, n, NULL);
456 (filler_t *) mapping->a_ops->readpage, NULL);
457 if (!IS_ERR(page)) { 456 if (!IS_ERR(page)) {
458 wait_on_page_locked(page); 457 wait_on_page_locked(page);
459 kmap(page); 458 kmap(page);
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 9b9eda7b335c..283fbc6b8eea 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -179,12 +179,12 @@ outnobh:
179/* That's simple too. */ 179/* That's simple too. */
180 180
181static int 181static int
182romfs_statfs(struct super_block *sb, struct kstatfs *buf) 182romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
183{ 183{
184 buf->f_type = ROMFS_MAGIC; 184 buf->f_type = ROMFS_MAGIC;
185 buf->f_bsize = ROMBSIZE; 185 buf->f_bsize = ROMBSIZE;
186 buf->f_bfree = buf->f_bavail = buf->f_ffree; 186 buf->f_bfree = buf->f_bavail = buf->f_ffree;
187 buf->f_blocks = (romfs_maxsize(sb)+ROMBSIZE-1)>>ROMBSBITS; 187 buf->f_blocks = (romfs_maxsize(dentry->d_sb)+ROMBSIZE-1)>>ROMBSBITS;
188 buf->f_namelen = ROMFS_MAXFN; 188 buf->f_namelen = ROMFS_MAXFN;
189 return 0; 189 return 0;
190} 190}
@@ -607,10 +607,11 @@ static struct super_operations romfs_ops = {
607 .remount_fs = romfs_remount, 607 .remount_fs = romfs_remount,
608}; 608};
609 609
610static struct super_block *romfs_get_sb(struct file_system_type *fs_type, 610static int romfs_get_sb(struct file_system_type *fs_type,
611 int flags, const char *dev_name, void *data) 611 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
612{ 612{
613 return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super); 613 return get_sb_bdev(fs_type, flags, dev_name, data, romfs_fill_super,
614 mnt);
614} 615}
615 616
616static struct file_system_type romfs_fs_type = { 617static struct file_system_type romfs_fs_type = {
diff --git a/fs/select.c b/fs/select.c
index a8109baa5e46..9c4f0f2604f1 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -546,37 +546,38 @@ struct poll_list {
546 546
547#define POLLFD_PER_PAGE ((PAGE_SIZE-sizeof(struct poll_list)) / sizeof(struct pollfd)) 547#define POLLFD_PER_PAGE ((PAGE_SIZE-sizeof(struct poll_list)) / sizeof(struct pollfd))
548 548
549static void do_pollfd(unsigned int num, struct pollfd * fdpage, 549/*
550 poll_table ** pwait, int *count) 550 * Fish for pollable events on the pollfd->fd file descriptor. We're only
551 * interested in events matching the pollfd->events mask, and the result
552 * matching that mask is both recorded in pollfd->revents and returned. The
553 * pwait poll_table will be used by the fd-provided poll handler for waiting,
554 * if non-NULL.
555 */
556static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait)
551{ 557{
552 int i; 558 unsigned int mask;
553 559 int fd;
554 for (i = 0; i < num; i++) { 560
555 int fd; 561 mask = 0;
556 unsigned int mask; 562 fd = pollfd->fd;
557 struct pollfd *fdp; 563 if (fd >= 0) {
558 564 int fput_needed;
559 mask = 0; 565 struct file * file;
560 fdp = fdpage+i; 566
561 fd = fdp->fd; 567 file = fget_light(fd, &fput_needed);
562 if (fd >= 0) { 568 mask = POLLNVAL;
563 int fput_needed; 569 if (file != NULL) {
564 struct file * file = fget_light(fd, &fput_needed); 570 mask = DEFAULT_POLLMASK;
565 mask = POLLNVAL; 571 if (file->f_op && file->f_op->poll)
566 if (file != NULL) { 572 mask = file->f_op->poll(file, pwait);
567 mask = DEFAULT_POLLMASK; 573 /* Mask out unneeded events. */
568 if (file->f_op && file->f_op->poll) 574 mask &= pollfd->events | POLLERR | POLLHUP;
569 mask = file->f_op->poll(file, *pwait); 575 fput_light(file, fput_needed);
570 mask &= fdp->events | POLLERR | POLLHUP;
571 fput_light(file, fput_needed);
572 }
573 if (mask) {
574 *pwait = NULL;
575 (*count)++;
576 }
577 } 576 }
578 fdp->revents = mask;
579 } 577 }
578 pollfd->revents = mask;
579
580 return mask;
580} 581}
581 582
582static int do_poll(unsigned int nfds, struct poll_list *list, 583static int do_poll(unsigned int nfds, struct poll_list *list,
@@ -594,11 +595,29 @@ static int do_poll(unsigned int nfds, struct poll_list *list,
594 long __timeout; 595 long __timeout;
595 596
596 set_current_state(TASK_INTERRUPTIBLE); 597 set_current_state(TASK_INTERRUPTIBLE);
597 walk = list; 598 for (walk = list; walk != NULL; walk = walk->next) {
598 while(walk != NULL) { 599 struct pollfd * pfd, * pfd_end;
599 do_pollfd( walk->len, walk->entries, &pt, &count); 600
600 walk = walk->next; 601 pfd = walk->entries;
602 pfd_end = pfd + walk->len;
603 for (; pfd != pfd_end; pfd++) {
604 /*
605 * Fish for events. If we found one, record it
606 * and kill the poll_table, so we don't
607 * needlessly register any other waiters after
608 * this. They'll get immediately deregistered
609 * when we break out and return.
610 */
611 if (do_pollfd(pfd, pt)) {
612 count++;
613 pt = NULL;
614 }
615 }
601 } 616 }
617 /*
618 * All waiters have already been registered, so don't provide
619 * a poll_table to them on the next loop iteration.
620 */
602 pt = NULL; 621 pt = NULL;
603 if (count || !*timeout || signal_pending(current)) 622 if (count || !*timeout || signal_pending(current))
604 break; 623 break;
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index fdeabc0a34f7..506ff87c1d4b 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -48,7 +48,7 @@
48 48
49static void smb_delete_inode(struct inode *); 49static void smb_delete_inode(struct inode *);
50static void smb_put_super(struct super_block *); 50static void smb_put_super(struct super_block *);
51static int smb_statfs(struct super_block *, struct kstatfs *); 51static int smb_statfs(struct dentry *, struct kstatfs *);
52static int smb_show_options(struct seq_file *, struct vfsmount *); 52static int smb_show_options(struct seq_file *, struct vfsmount *);
53 53
54static kmem_cache_t *smb_inode_cachep; 54static kmem_cache_t *smb_inode_cachep;
@@ -641,13 +641,13 @@ out_no_server:
641} 641}
642 642
643static int 643static int
644smb_statfs(struct super_block *sb, struct kstatfs *buf) 644smb_statfs(struct dentry *dentry, struct kstatfs *buf)
645{ 645{
646 int result; 646 int result;
647 647
648 lock_kernel(); 648 lock_kernel();
649 649
650 result = smb_proc_dskattr(sb, buf); 650 result = smb_proc_dskattr(dentry, buf);
651 651
652 unlock_kernel(); 652 unlock_kernel();
653 653
@@ -782,10 +782,10 @@ out:
782 return error; 782 return error;
783} 783}
784 784
785static struct super_block *smb_get_sb(struct file_system_type *fs_type, 785static int smb_get_sb(struct file_system_type *fs_type,
786 int flags, const char *dev_name, void *data) 786 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
787{ 787{
788 return get_sb_nodev(fs_type, flags, data, smb_fill_super); 788 return get_sb_nodev(fs_type, flags, data, smb_fill_super, mnt);
789} 789}
790 790
791static struct file_system_type smb_fs_type = { 791static struct file_system_type smb_fs_type = {
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
index b1b878b81730..c3495059889d 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -3226,9 +3226,9 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
3226} 3226}
3227 3227
3228int 3228int
3229smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr) 3229smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr)
3230{ 3230{
3231 struct smb_sb_info *server = SMB_SB(sb); 3231 struct smb_sb_info *server = SMB_SB(dentry->d_sb);
3232 int result; 3232 int result;
3233 char *p; 3233 char *p;
3234 long unit; 3234 long unit;
diff --git a/fs/smbfs/proto.h b/fs/smbfs/proto.h
index 47664597e6b1..972ed7dad388 100644
--- a/fs/smbfs/proto.h
+++ b/fs/smbfs/proto.h
@@ -29,7 +29,7 @@ extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
29extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr); 29extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
30extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor); 30extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor);
31extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr); 31extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr);
32extern int smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr); 32extern int smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr);
33extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len); 33extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len);
34extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath); 34extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
35extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry); 35extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
diff --git a/fs/splice.c b/fs/splice.c
index a285fd746dc0..05fd2787be98 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -55,31 +55,43 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
55 struct pipe_buffer *buf) 55 struct pipe_buffer *buf)
56{ 56{
57 struct page *page = buf->page; 57 struct page *page = buf->page;
58 struct address_space *mapping = page_mapping(page); 58 struct address_space *mapping;
59 59
60 lock_page(page); 60 lock_page(page);
61 61
62 WARN_ON(!PageUptodate(page)); 62 mapping = page_mapping(page);
63 if (mapping) {
64 WARN_ON(!PageUptodate(page));
63 65
64 /* 66 /*
65 * At least for ext2 with nobh option, we need to wait on writeback 67 * At least for ext2 with nobh option, we need to wait on
66 * completing on this page, since we'll remove it from the pagecache. 68 * writeback completing on this page, since we'll remove it
67 * Otherwise truncate wont wait on the page, allowing the disk 69 * from the pagecache. Otherwise truncate wont wait on the
68 * blocks to be reused by someone else before we actually wrote our 70 * page, allowing the disk blocks to be reused by someone else
69 * data to them. fs corruption ensues. 71 * before we actually wrote our data to them. fs corruption
70 */ 72 * ensues.
71 wait_on_page_writeback(page); 73 */
74 wait_on_page_writeback(page);
72 75
73 if (PagePrivate(page)) 76 if (PagePrivate(page))
74 try_to_release_page(page, mapping_gfp_mask(mapping)); 77 try_to_release_page(page, mapping_gfp_mask(mapping));
75 78
76 if (!remove_mapping(mapping, page)) { 79 /*
77 unlock_page(page); 80 * If we succeeded in removing the mapping, set LRU flag
78 return 1; 81 * and return good.
82 */
83 if (remove_mapping(mapping, page)) {
84 buf->flags |= PIPE_BUF_FLAG_LRU;
85 return 0;
86 }
79 } 87 }
80 88
81 buf->flags |= PIPE_BUF_FLAG_LRU; 89 /*
82 return 0; 90 * Raced with truncate or failed to remove page from current
91 * address space, unlock and return failure.
92 */
93 unlock_page(page);
94 return 1;
83} 95}
84 96
85static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe, 97static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
diff --git a/fs/super.c b/fs/super.c
index 15f2afdbf82e..8a669f6f3f52 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -231,7 +231,7 @@ void generic_shutdown_super(struct super_block *sb)
231 if (root) { 231 if (root) {
232 sb->s_root = NULL; 232 sb->s_root = NULL;
233 shrink_dcache_parent(root); 233 shrink_dcache_parent(root);
234 shrink_dcache_anon(&sb->s_anon); 234 shrink_dcache_sb(sb);
235 dput(root); 235 dput(root);
236 fsync_super(sb); 236 fsync_super(sb);
237 lock_super(sb); 237 lock_super(sb);
@@ -486,7 +486,7 @@ asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
486 s = user_get_super(new_decode_dev(dev)); 486 s = user_get_super(new_decode_dev(dev));
487 if (s == NULL) 487 if (s == NULL)
488 goto out; 488 goto out;
489 err = vfs_statfs(s, &sbuf); 489 err = vfs_statfs(s->s_root, &sbuf);
490 drop_super(s); 490 drop_super(s);
491 if (err) 491 if (err)
492 goto out; 492 goto out;
@@ -676,9 +676,10 @@ static void bdev_uevent(struct block_device *bdev, enum kobject_action action)
676 } 676 }
677} 677}
678 678
679struct super_block *get_sb_bdev(struct file_system_type *fs_type, 679int get_sb_bdev(struct file_system_type *fs_type,
680 int flags, const char *dev_name, void *data, 680 int flags, const char *dev_name, void *data,
681 int (*fill_super)(struct super_block *, void *, int)) 681 int (*fill_super)(struct super_block *, void *, int),
682 struct vfsmount *mnt)
682{ 683{
683 struct block_device *bdev; 684 struct block_device *bdev;
684 struct super_block *s; 685 struct super_block *s;
@@ -686,7 +687,7 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
686 687
687 bdev = open_bdev_excl(dev_name, flags, fs_type); 688 bdev = open_bdev_excl(dev_name, flags, fs_type);
688 if (IS_ERR(bdev)) 689 if (IS_ERR(bdev))
689 return (struct super_block *)bdev; 690 return PTR_ERR(bdev);
690 691
691 /* 692 /*
692 * once the super is inserted into the list by sget, s_umount 693 * once the super is inserted into the list by sget, s_umount
@@ -697,15 +698,17 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
697 s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); 698 s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
698 mutex_unlock(&bdev->bd_mount_mutex); 699 mutex_unlock(&bdev->bd_mount_mutex);
699 if (IS_ERR(s)) 700 if (IS_ERR(s))
700 goto out; 701 goto error_s;
701 702
702 if (s->s_root) { 703 if (s->s_root) {
703 if ((flags ^ s->s_flags) & MS_RDONLY) { 704 if ((flags ^ s->s_flags) & MS_RDONLY) {
704 up_write(&s->s_umount); 705 up_write(&s->s_umount);
705 deactivate_super(s); 706 deactivate_super(s);
706 s = ERR_PTR(-EBUSY); 707 error = -EBUSY;
708 goto error_bdev;
707 } 709 }
708 goto out; 710
711 close_bdev_excl(bdev);
709 } else { 712 } else {
710 char b[BDEVNAME_SIZE]; 713 char b[BDEVNAME_SIZE];
711 714
@@ -716,18 +719,21 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
716 if (error) { 719 if (error) {
717 up_write(&s->s_umount); 720 up_write(&s->s_umount);
718 deactivate_super(s); 721 deactivate_super(s);
719 s = ERR_PTR(error); 722 goto error;
720 } else {
721 s->s_flags |= MS_ACTIVE;
722 bdev_uevent(bdev, KOBJ_MOUNT);
723 } 723 }
724
725 s->s_flags |= MS_ACTIVE;
726 bdev_uevent(bdev, KOBJ_MOUNT);
724 } 727 }
725 728
726 return s; 729 return simple_set_mnt(mnt, s);
727 730
728out: 731error_s:
732 error = PTR_ERR(s);
733error_bdev:
729 close_bdev_excl(bdev); 734 close_bdev_excl(bdev);
730 return s; 735error:
736 return error;
731} 737}
732 738
733EXPORT_SYMBOL(get_sb_bdev); 739EXPORT_SYMBOL(get_sb_bdev);
@@ -744,15 +750,16 @@ void kill_block_super(struct super_block *sb)
744 750
745EXPORT_SYMBOL(kill_block_super); 751EXPORT_SYMBOL(kill_block_super);
746 752
747struct super_block *get_sb_nodev(struct file_system_type *fs_type, 753int get_sb_nodev(struct file_system_type *fs_type,
748 int flags, void *data, 754 int flags, void *data,
749 int (*fill_super)(struct super_block *, void *, int)) 755 int (*fill_super)(struct super_block *, void *, int),
756 struct vfsmount *mnt)
750{ 757{
751 int error; 758 int error;
752 struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL); 759 struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);
753 760
754 if (IS_ERR(s)) 761 if (IS_ERR(s))
755 return s; 762 return PTR_ERR(s);
756 763
757 s->s_flags = flags; 764 s->s_flags = flags;
758 765
@@ -760,10 +767,10 @@ struct super_block *get_sb_nodev(struct file_system_type *fs_type,
760 if (error) { 767 if (error) {
761 up_write(&s->s_umount); 768 up_write(&s->s_umount);
762 deactivate_super(s); 769 deactivate_super(s);
763 return ERR_PTR(error); 770 return error;
764 } 771 }
765 s->s_flags |= MS_ACTIVE; 772 s->s_flags |= MS_ACTIVE;
766 return s; 773 return simple_set_mnt(mnt, s);
767} 774}
768 775
769EXPORT_SYMBOL(get_sb_nodev); 776EXPORT_SYMBOL(get_sb_nodev);
@@ -773,28 +780,29 @@ static int compare_single(struct super_block *s, void *p)
773 return 1; 780 return 1;
774} 781}
775 782
776struct super_block *get_sb_single(struct file_system_type *fs_type, 783int get_sb_single(struct file_system_type *fs_type,
777 int flags, void *data, 784 int flags, void *data,
778 int (*fill_super)(struct super_block *, void *, int)) 785 int (*fill_super)(struct super_block *, void *, int),
786 struct vfsmount *mnt)
779{ 787{
780 struct super_block *s; 788 struct super_block *s;
781 int error; 789 int error;
782 790
783 s = sget(fs_type, compare_single, set_anon_super, NULL); 791 s = sget(fs_type, compare_single, set_anon_super, NULL);
784 if (IS_ERR(s)) 792 if (IS_ERR(s))
785 return s; 793 return PTR_ERR(s);
786 if (!s->s_root) { 794 if (!s->s_root) {
787 s->s_flags = flags; 795 s->s_flags = flags;
788 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); 796 error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
789 if (error) { 797 if (error) {
790 up_write(&s->s_umount); 798 up_write(&s->s_umount);
791 deactivate_super(s); 799 deactivate_super(s);
792 return ERR_PTR(error); 800 return error;
793 } 801 }
794 s->s_flags |= MS_ACTIVE; 802 s->s_flags |= MS_ACTIVE;
795 } 803 }
796 do_remount_sb(s, flags, data, 0); 804 do_remount_sb(s, flags, data, 0);
797 return s; 805 return simple_set_mnt(mnt, s);
798} 806}
799 807
800EXPORT_SYMBOL(get_sb_single); 808EXPORT_SYMBOL(get_sb_single);
@@ -802,52 +810,51 @@ EXPORT_SYMBOL(get_sb_single);
802struct vfsmount * 810struct vfsmount *
803vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) 811vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
804{ 812{
805 struct super_block *sb = ERR_PTR(-ENOMEM);
806 struct vfsmount *mnt; 813 struct vfsmount *mnt;
807 int error;
808 char *secdata = NULL; 814 char *secdata = NULL;
815 int error;
816
817 if (!type)
818 return ERR_PTR(-ENODEV);
809 819
820 error = -ENOMEM;
810 mnt = alloc_vfsmnt(name); 821 mnt = alloc_vfsmnt(name);
811 if (!mnt) 822 if (!mnt)
812 goto out; 823 goto out;
813 824
814 if (data) { 825 if (data) {
815 secdata = alloc_secdata(); 826 secdata = alloc_secdata();
816 if (!secdata) { 827 if (!secdata)
817 sb = ERR_PTR(-ENOMEM);
818 goto out_mnt; 828 goto out_mnt;
819 }
820 829
821 error = security_sb_copy_data(type, data, secdata); 830 error = security_sb_copy_data(type, data, secdata);
822 if (error) { 831 if (error)
823 sb = ERR_PTR(error);
824 goto out_free_secdata; 832 goto out_free_secdata;
825 }
826 } 833 }
827 834
828 sb = type->get_sb(type, flags, name, data); 835 error = type->get_sb(type, flags, name, data, mnt);
829 if (IS_ERR(sb)) 836 if (error < 0)
830 goto out_free_secdata; 837 goto out_free_secdata;
831 error = security_sb_kern_mount(sb, secdata); 838
839 error = security_sb_kern_mount(mnt->mnt_sb, secdata);
832 if (error) 840 if (error)
833 goto out_sb; 841 goto out_sb;
834 mnt->mnt_sb = sb; 842
835 mnt->mnt_root = dget(sb->s_root); 843 mnt->mnt_mountpoint = mnt->mnt_root;
836 mnt->mnt_mountpoint = sb->s_root;
837 mnt->mnt_parent = mnt; 844 mnt->mnt_parent = mnt;
838 up_write(&sb->s_umount); 845 up_write(&mnt->mnt_sb->s_umount);
839 free_secdata(secdata); 846 free_secdata(secdata);
840 return mnt; 847 return mnt;
841out_sb: 848out_sb:
842 up_write(&sb->s_umount); 849 dput(mnt->mnt_root);
843 deactivate_super(sb); 850 up_write(&mnt->mnt_sb->s_umount);
844 sb = ERR_PTR(error); 851 deactivate_super(mnt->mnt_sb);
845out_free_secdata: 852out_free_secdata:
846 free_secdata(secdata); 853 free_secdata(secdata);
847out_mnt: 854out_mnt:
848 free_vfsmnt(mnt); 855 free_vfsmnt(mnt);
849out: 856out:
850 return (struct vfsmount *)sb; 857 return ERR_PTR(error);
851} 858}
852 859
853EXPORT_SYMBOL_GPL(vfs_kern_mount); 860EXPORT_SYMBOL_GPL(vfs_kern_mount);
diff --git a/fs/sync.c b/fs/sync.c
index aab5ffe77e9f..955aef04da28 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -100,7 +100,7 @@ asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
100 } 100 }
101 101
102 if (nbytes == 0) 102 if (nbytes == 0)
103 endbyte = -1; 103 endbyte = LLONG_MAX;
104 else 104 else
105 endbyte--; /* inclusive */ 105 endbyte--; /* inclusive */
106 106
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index f1117e885bd6..40190c489271 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -66,10 +66,10 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
66 return 0; 66 return 0;
67} 67}
68 68
69static struct super_block *sysfs_get_sb(struct file_system_type *fs_type, 69static int sysfs_get_sb(struct file_system_type *fs_type,
70 int flags, const char *dev_name, void *data) 70 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
71{ 71{
72 return get_sb_single(fs_type, flags, data, sysfs_fill_super); 72 return get_sb_single(fs_type, flags, data, sysfs_fill_super, mnt);
73} 73}
74 74
75static struct file_system_type sysfs_fs_type = { 75static struct file_system_type sysfs_fs_type = {
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index d7074341ee87..f2bef962d309 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -53,8 +53,7 @@ static int dir_commit_chunk(struct page *page, unsigned from, unsigned to)
53static struct page * dir_get_page(struct inode *dir, unsigned long n) 53static struct page * dir_get_page(struct inode *dir, unsigned long n)
54{ 54{
55 struct address_space *mapping = dir->i_mapping; 55 struct address_space *mapping = dir->i_mapping;
56 struct page *page = read_cache_page(mapping, n, 56 struct page *page = read_mapping_page(mapping, n, NULL);
57 (filler_t*)mapping->a_ops->readpage, NULL);
58 if (!IS_ERR(page)) { 57 if (!IS_ERR(page)) {
59 wait_on_page_locked(page); 58 wait_on_page_locked(page);
60 kmap(page); 59 kmap(page);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 3ff89cc5833a..58b2d22142ba 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -85,8 +85,9 @@ static void sysv_put_super(struct super_block *sb)
85 kfree(sbi); 85 kfree(sbi);
86} 86}
87 87
88static int sysv_statfs(struct super_block *sb, struct kstatfs *buf) 88static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf)
89{ 89{
90 struct super_block *sb = dentry->d_sb;
90 struct sysv_sb_info *sbi = SYSV_SB(sb); 91 struct sysv_sb_info *sbi = SYSV_SB(sb);
91 92
92 buf->f_type = sb->s_magic; 93 buf->f_type = sb->s_magic;
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index e92b991e6dda..876639b93321 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -506,16 +506,17 @@ failed:
506 506
507/* Every kernel module contains stuff like this. */ 507/* Every kernel module contains stuff like this. */
508 508
509static struct super_block *sysv_get_sb(struct file_system_type *fs_type, 509static int sysv_get_sb(struct file_system_type *fs_type,
510 int flags, const char *dev_name, void *data) 510 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
511{ 511{
512 return get_sb_bdev(fs_type, flags, dev_name, data, sysv_fill_super); 512 return get_sb_bdev(fs_type, flags, dev_name, data, sysv_fill_super,
513 mnt);
513} 514}
514 515
515static struct super_block *v7_get_sb(struct file_system_type *fs_type, 516static int v7_get_sb(struct file_system_type *fs_type,
516 int flags, const char *dev_name, void *data) 517 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
517{ 518{
518 return get_sb_bdev(fs_type, flags, dev_name, data, v7_fill_super); 519 return get_sb_bdev(fs_type, flags, dev_name, data, v7_fill_super, mnt);
519} 520}
520 521
521static struct file_system_type sysv_fs_type = { 522static struct file_system_type sysv_fs_type = {
diff --git a/fs/udf/super.c b/fs/udf/super.c
index e45789fe38e8..44fe2cb0bbb2 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -91,13 +91,13 @@ static void udf_load_partdesc(struct super_block *, struct buffer_head *);
91static void udf_open_lvid(struct super_block *); 91static void udf_open_lvid(struct super_block *);
92static void udf_close_lvid(struct super_block *); 92static void udf_close_lvid(struct super_block *);
93static unsigned int udf_count_free(struct super_block *); 93static unsigned int udf_count_free(struct super_block *);
94static int udf_statfs(struct super_block *, struct kstatfs *); 94static int udf_statfs(struct dentry *, struct kstatfs *);
95 95
96/* UDF filesystem type */ 96/* UDF filesystem type */
97static struct super_block *udf_get_sb(struct file_system_type *fs_type, 97static int udf_get_sb(struct file_system_type *fs_type,
98 int flags, const char *dev_name, void *data) 98 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
99{ 99{
100 return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super); 100 return get_sb_bdev(fs_type, flags, dev_name, data, udf_fill_super, mnt);
101} 101}
102 102
103static struct file_system_type udf_fstype = { 103static struct file_system_type udf_fstype = {
@@ -1779,8 +1779,10 @@ udf_put_super(struct super_block *sb)
1779 * Written, tested, and released. 1779 * Written, tested, and released.
1780 */ 1780 */
1781static int 1781static int
1782udf_statfs(struct super_block *sb, struct kstatfs *buf) 1782udf_statfs(struct dentry *dentry, struct kstatfs *buf)
1783{ 1783{
1784 struct super_block *sb = dentry->d_sb;
1785
1784 buf->f_type = UDF_SUPER_MAGIC; 1786 buf->f_type = UDF_SUPER_MAGIC;
1785 buf->f_bsize = sb->s_blocksize; 1787 buf->f_bsize = sb->s_blocksize;
1786 buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb)); 1788 buf->f_blocks = UDF_SB_PARTLEN(sb, UDF_SB_PARTITION(sb));
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index db98a4c71e63..fe5ab2aa2899 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1113,8 +1113,9 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1113 return 0; 1113 return 0;
1114} 1114}
1115 1115
1116static int ufs_statfs (struct super_block *sb, struct kstatfs *buf) 1116static int ufs_statfs (struct dentry *dentry, struct kstatfs *buf)
1117{ 1117{
1118 struct super_block *sb = dentry->d_sb;
1118 struct ufs_sb_private_info * uspi; 1119 struct ufs_sb_private_info * uspi;
1119 struct ufs_super_block_first * usb1; 1120 struct ufs_super_block_first * usb1;
1120 struct ufs_super_block * usb; 1121 struct ufs_super_block * usb;
@@ -1311,10 +1312,10 @@ out:
1311 1312
1312#endif 1313#endif
1313 1314
1314static struct super_block *ufs_get_sb(struct file_system_type *fs_type, 1315static int ufs_get_sb(struct file_system_type *fs_type,
1315 int flags, const char *dev_name, void *data) 1316 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1316{ 1317{
1317 return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super); 1318 return get_sb_bdev(fs_type, flags, dev_name, data, ufs_fill_super, mnt);
1318} 1319}
1319 1320
1320static struct file_system_type ufs_fs_type = { 1321static struct file_system_type ufs_fs_type = {
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index a56cec3be5f0..9a8f48bae956 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -1023,11 +1023,12 @@ static int vfat_fill_super(struct super_block *sb, void *data, int silent)
1023 return 0; 1023 return 0;
1024} 1024}
1025 1025
1026static struct super_block *vfat_get_sb(struct file_system_type *fs_type, 1026static int vfat_get_sb(struct file_system_type *fs_type,
1027 int flags, const char *dev_name, 1027 int flags, const char *dev_name,
1028 void *data) 1028 void *data, struct vfsmount *mnt)
1029{ 1029{
1030 return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super); 1030 return get_sb_bdev(fs_type, flags, dev_name, data, vfat_fill_super,
1031 mnt);
1031} 1032}
1032 1033
1033static struct file_system_type vfat_fs_type = { 1034static struct file_system_type vfat_fs_type = {
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig
index bac27d66151d..26b364c9d62c 100644
--- a/fs/xfs/Kconfig
+++ b/fs/xfs/Kconfig
@@ -1,6 +1,5 @@
1config XFS_FS 1config XFS_FS
2 tristate "XFS filesystem support" 2 tristate "XFS filesystem support"
3 select EXPORTFS if NFSD!=n
4 help 3 help
5 XFS is a high performance journaling filesystem which originated 4 XFS is a high performance journaling filesystem which originated
6 on the SGI IRIX platform. It is completely multi-threaded, can 5 on the SGI IRIX platform. It is completely multi-threaded, can
@@ -18,11 +17,6 @@ config XFS_FS
18 system of your root partition is compiled as a module, you'll need 17 system of your root partition is compiled as a module, you'll need
19 to use an initial ramdisk (initrd) to boot. 18 to use an initial ramdisk (initrd) to boot.
20 19
21config XFS_EXPORT
22 bool
23 depends on XFS_FS && EXPORTFS
24 default y
25
26config XFS_QUOTA 20config XFS_QUOTA
27 bool "XFS Quota support" 21 bool "XFS Quota support"
28 depends on XFS_FS 22 depends on XFS_FS
@@ -65,18 +59,19 @@ config XFS_POSIX_ACL
65 If you don't know what Access Control Lists are, say N. 59 If you don't know what Access Control Lists are, say N.
66 60
67config XFS_RT 61config XFS_RT
68 bool "XFS Realtime support (EXPERIMENTAL)" 62 bool "XFS Realtime subvolume support"
69 depends on XFS_FS && EXPERIMENTAL 63 depends on XFS_FS
70 help 64 help
71 If you say Y here you will be able to mount and use XFS filesystems 65 If you say Y here you will be able to mount and use XFS filesystems
72 which contain a realtime subvolume. The realtime subvolume is a 66 which contain a realtime subvolume. The realtime subvolume is a
73 separate area of disk space where only file data is stored. The 67 separate area of disk space where only file data is stored. It was
74 realtime subvolume is designed to provide very deterministic 68 originally designed to provide deterministic data rates suitable
75 data rates suitable for media streaming applications. 69 for media streaming applications, but is also useful as a generic
76 70 mechanism for ensuring data and metadata/log I/Os are completely
77 See the xfs man page in section 5 for a bit more information. 71 separated. Regular file I/Os are isolated to a separate device
72 from all other requests, and this can be done quite transparently
73 to applications via the inherit-realtime directory inode flag.
78 74
79 This feature is unsupported at this time, is not yet fully 75 See the xfs man page in section 5 for additional information.
80 functional, and may cause serious problems.
81 76
82 If unsure, say N. 77 If unsure, say N.
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6
index 5d73eaa1971f..9e7f85986d0d 100644
--- a/fs/xfs/Makefile-linux-2.6
+++ b/fs/xfs/Makefile-linux-2.6
@@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
59xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o 59xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o
60xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o 60xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o
61xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o 61xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o
62xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o
63 62
64 63
65xfs-y += xfs_alloc.o \ 64xfs-y += xfs_alloc.o \
@@ -73,14 +72,12 @@ xfs-y += xfs_alloc.o \
73 xfs_btree.o \ 72 xfs_btree.o \
74 xfs_buf_item.o \ 73 xfs_buf_item.o \
75 xfs_da_btree.o \ 74 xfs_da_btree.o \
76 xfs_dir.o \
77 xfs_dir2.o \ 75 xfs_dir2.o \
78 xfs_dir2_block.o \ 76 xfs_dir2_block.o \
79 xfs_dir2_data.o \ 77 xfs_dir2_data.o \
80 xfs_dir2_leaf.o \ 78 xfs_dir2_leaf.o \
81 xfs_dir2_node.o \ 79 xfs_dir2_node.o \
82 xfs_dir2_sf.o \ 80 xfs_dir2_sf.o \
83 xfs_dir_leaf.o \
84 xfs_error.o \ 81 xfs_error.o \
85 xfs_extfree_item.o \ 82 xfs_extfree_item.o \
86 xfs_fsops.o \ 83 xfs_fsops.o \
@@ -117,6 +114,7 @@ xfs-y += $(addprefix $(XFS_LINUX)/, \
117 kmem.o \ 114 kmem.o \
118 xfs_aops.o \ 115 xfs_aops.o \
119 xfs_buf.o \ 116 xfs_buf.o \
117 xfs_export.o \
120 xfs_file.o \ 118 xfs_file.o \
121 xfs_fs_subr.o \ 119 xfs_fs_subr.o \
122 xfs_globals.o \ 120 xfs_globals.o \
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h
index 2cfd33d4d8aa..939bd84bc7ee 100644
--- a/fs/xfs/linux-2.6/kmem.h
+++ b/fs/xfs/linux-2.6/kmem.h
@@ -23,42 +23,6 @@
23#include <linux/mm.h> 23#include <linux/mm.h>
24 24
25/* 25/*
26 * Process flags handling
27 */
28
29#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO)
30#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
31
32#define PFLAGS_SET_NOIO() do { \
33 current->flags |= PF_NOIO; \
34} while (0)
35
36#define PFLAGS_CLEAR_NOIO() do { \
37 current->flags &= ~PF_NOIO; \
38} while (0)
39
40/* these could be nested, so we save state */
41#define PFLAGS_SET_FSTRANS(STATEP) do { \
42 *(STATEP) = current->flags; \
43 current->flags |= PF_FSTRANS; \
44} while (0)
45
46#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
47 *(STATEP) = current->flags; \
48 current->flags &= ~PF_FSTRANS; \
49} while (0)
50
51/* Restore the PF_FSTRANS state to what was saved in STATEP */
52#define PFLAGS_RESTORE_FSTRANS(STATEP) do { \
53 current->flags = ((current->flags & ~PF_FSTRANS) | \
54 (*(STATEP) & PF_FSTRANS)); \
55} while (0)
56
57#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
58 *(NSTATEP) = *(OSTATEP); \
59} while (0)
60
61/*
62 * General memory allocation interfaces 26 * General memory allocation interfaces
63 */ 27 */
64 28
@@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags)
83 lflags = GFP_ATOMIC | __GFP_NOWARN; 47 lflags = GFP_ATOMIC | __GFP_NOWARN;
84 } else { 48 } else {
85 lflags = GFP_KERNEL | __GFP_NOWARN; 49 lflags = GFP_KERNEL | __GFP_NOWARN;
86 if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS)) 50 if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
87 lflags &= ~__GFP_FS; 51 lflags &= ~__GFP_FS;
88 } 52 }
89 return lflags; 53 return lflags;
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h
index 1b262b790d9c..32e1ce0f04c9 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/linux-2.6/mrlock.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@ typedef struct {
28} mrlock_t; 28} mrlock_t;
29 29
30#define mrinit(mrp, name) \ 30#define mrinit(mrp, name) \
31 ( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) ) 31 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
32#define mrlock_init(mrp, t,n,s) mrinit(mrp, n) 32#define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
33#define mrfree(mrp) do { } while (0) 33#define mrfree(mrp) do { } while (0)
34#define mraccess(mrp) mraccessf(mrp, 0) 34#define mraccess(mrp) mraccessf(mrp, 0)
diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h
index 194a84490bd1..b25090094cca 100644
--- a/fs/xfs/linux-2.6/sema.h
+++ b/fs/xfs/linux-2.6/sema.h
@@ -34,20 +34,21 @@ typedef struct semaphore sema_t;
34#define initnsema(sp, val, name) sema_init(sp, val) 34#define initnsema(sp, val, name) sema_init(sp, val)
35#define psema(sp, b) down(sp) 35#define psema(sp, b) down(sp)
36#define vsema(sp) up(sp) 36#define vsema(sp) up(sp)
37#define valusema(sp) (atomic_read(&(sp)->count)) 37#define freesema(sema) do { } while (0)
38#define freesema(sema) 38
39static inline int issemalocked(sema_t *sp)
40{
41 return down_trylock(sp) || (up(sp), 0);
42}
39 43
40/* 44/*
41 * Map cpsema (try to get the sema) to down_trylock. We need to switch 45 * Map cpsema (try to get the sema) to down_trylock. We need to switch
42 * the return values since cpsema returns 1 (acquired) 0 (failed) and 46 * the return values since cpsema returns 1 (acquired) 0 (failed) and
43 * down_trylock returns the reverse 0 (acquired) 1 (failed). 47 * down_trylock returns the reverse 0 (acquired) 1 (failed).
44 */ 48 */
45 49static inline int cpsema(sema_t *sp)
46#define cpsema(sp) (down_trylock(sp) ? 0 : 1) 50{
47 51 return down_trylock(sp) ? 0 : 1;
48/* 52}
49 * Didn't do cvsema(sp). Not sure how to map this to up/down/...
50 * It does a vsema if the values is < 0 other wise nothing.
51 */
52 53
53#endif /* __XFS_SUPPORT_SEMA_H__ */ 54#endif /* __XFS_SUPPORT_SEMA_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 4d191ef39b67..3e807b828e22 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -21,7 +21,6 @@
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_sb.h" 22#include "xfs_sb.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_trans.h" 25#include "xfs_trans.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
@@ -29,7 +28,6 @@
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_alloc_btree.h" 29#include "xfs_alloc_btree.h"
31#include "xfs_ialloc_btree.h" 30#include "xfs_ialloc_btree.h"
32#include "xfs_dir_sf.h"
33#include "xfs_dir2_sf.h" 31#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
35#include "xfs_dinode.h" 33#include "xfs_dinode.h"
@@ -76,7 +74,7 @@ xfs_page_trace(
76 int mask) 74 int mask)
77{ 75{
78 xfs_inode_t *ip; 76 xfs_inode_t *ip;
79 vnode_t *vp = vn_from_inode(inode); 77 bhv_vnode_t *vp = vn_from_inode(inode);
80 loff_t isize = i_size_read(inode); 78 loff_t isize = i_size_read(inode);
81 loff_t offset = page_offset(page); 79 loff_t offset = page_offset(page);
82 int delalloc = -1, unmapped = -1, unwritten = -1; 80 int delalloc = -1, unmapped = -1, unwritten = -1;
@@ -136,9 +134,10 @@ xfs_destroy_ioend(
136 134
137 for (bh = ioend->io_buffer_head; bh; bh = next) { 135 for (bh = ioend->io_buffer_head; bh; bh = next) {
138 next = bh->b_private; 136 next = bh->b_private;
139 bh->b_end_io(bh, ioend->io_uptodate); 137 bh->b_end_io(bh, !ioend->io_error);
140 } 138 }
141 139 if (unlikely(ioend->io_error))
140 vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
142 vn_iowake(ioend->io_vnode); 141 vn_iowake(ioend->io_vnode);
143 mempool_free(ioend, xfs_ioend_pool); 142 mempool_free(ioend, xfs_ioend_pool);
144} 143}
@@ -180,13 +179,12 @@ xfs_end_bio_unwritten(
180 void *data) 179 void *data)
181{ 180{
182 xfs_ioend_t *ioend = data; 181 xfs_ioend_t *ioend = data;
183 vnode_t *vp = ioend->io_vnode; 182 bhv_vnode_t *vp = ioend->io_vnode;
184 xfs_off_t offset = ioend->io_offset; 183 xfs_off_t offset = ioend->io_offset;
185 size_t size = ioend->io_size; 184 size_t size = ioend->io_size;
186 int error;
187 185
188 if (ioend->io_uptodate) 186 if (likely(!ioend->io_error))
189 VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error); 187 bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
190 xfs_destroy_ioend(ioend); 188 xfs_destroy_ioend(ioend);
191} 189}
192 190
@@ -211,7 +209,7 @@ xfs_alloc_ioend(
211 * all the I/O from calling the completion routine too early. 209 * all the I/O from calling the completion routine too early.
212 */ 210 */
213 atomic_set(&ioend->io_remaining, 1); 211 atomic_set(&ioend->io_remaining, 1);
214 ioend->io_uptodate = 1; /* cleared if any I/O fails */ 212 ioend->io_error = 0;
215 ioend->io_list = NULL; 213 ioend->io_list = NULL;
216 ioend->io_type = type; 214 ioend->io_type = type;
217 ioend->io_vnode = vn_from_inode(inode); 215 ioend->io_vnode = vn_from_inode(inode);
@@ -239,10 +237,10 @@ xfs_map_blocks(
239 xfs_iomap_t *mapp, 237 xfs_iomap_t *mapp,
240 int flags) 238 int flags)
241{ 239{
242 vnode_t *vp = vn_from_inode(inode); 240 bhv_vnode_t *vp = vn_from_inode(inode);
243 int error, nmaps = 1; 241 int error, nmaps = 1;
244 242
245 VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error); 243 error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps);
246 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE))) 244 if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
247 VMODIFY(vp); 245 VMODIFY(vp);
248 return -error; 246 return -error;
@@ -271,16 +269,14 @@ xfs_end_bio(
271 if (bio->bi_size) 269 if (bio->bi_size)
272 return 1; 270 return 1;
273 271
274 ASSERT(ioend);
275 ASSERT(atomic_read(&bio->bi_cnt) >= 1); 272 ASSERT(atomic_read(&bio->bi_cnt) >= 1);
273 ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
276 274
277 /* Toss bio and pass work off to an xfsdatad thread */ 275 /* Toss bio and pass work off to an xfsdatad thread */
278 if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
279 ioend->io_uptodate = 0;
280 bio->bi_private = NULL; 276 bio->bi_private = NULL;
281 bio->bi_end_io = NULL; 277 bio->bi_end_io = NULL;
282
283 bio_put(bio); 278 bio_put(bio);
279
284 xfs_finish_ioend(ioend); 280 xfs_finish_ioend(ioend);
285 return 0; 281 return 0;
286} 282}
@@ -1127,7 +1123,7 @@ xfs_vm_writepage(
1127 * then mark the page dirty again and leave the page 1123 * then mark the page dirty again and leave the page
1128 * as is. 1124 * as is.
1129 */ 1125 */
1130 if (PFLAGS_TEST_FSTRANS() && need_trans) 1126 if (current_test_flags(PF_FSTRANS) && need_trans)
1131 goto out_fail; 1127 goto out_fail;
1132 1128
1133 /* 1129 /*
@@ -1158,6 +1154,18 @@ out_unlock:
1158 return error; 1154 return error;
1159} 1155}
1160 1156
1157STATIC int
1158xfs_vm_writepages(
1159 struct address_space *mapping,
1160 struct writeback_control *wbc)
1161{
1162 struct bhv_vnode *vp = vn_from_inode(mapping->host);
1163
1164 if (VN_TRUNC(vp))
1165 VUNTRUNCATE(vp);
1166 return generic_writepages(mapping, wbc);
1167}
1168
1161/* 1169/*
1162 * Called to move a page into cleanable state - and from there 1170 * Called to move a page into cleanable state - and from there
1163 * to be released. Possibly the page is already clean. We always 1171 * to be released. Possibly the page is already clean. We always
@@ -1204,7 +1212,7 @@ xfs_vm_releasepage(
1204 /* If we are already inside a transaction or the thread cannot 1212 /* If we are already inside a transaction or the thread cannot
1205 * do I/O, we cannot release this page. 1213 * do I/O, we cannot release this page.
1206 */ 1214 */
1207 if (PFLAGS_TEST_FSTRANS()) 1215 if (current_test_flags(PF_FSTRANS))
1208 return 0; 1216 return 0;
1209 1217
1210 /* 1218 /*
@@ -1231,7 +1239,7 @@ __xfs_get_blocks(
1231 int direct, 1239 int direct,
1232 bmapi_flags_t flags) 1240 bmapi_flags_t flags)
1233{ 1241{
1234 vnode_t *vp = vn_from_inode(inode); 1242 bhv_vnode_t *vp = vn_from_inode(inode);
1235 xfs_iomap_t iomap; 1243 xfs_iomap_t iomap;
1236 xfs_off_t offset; 1244 xfs_off_t offset;
1237 ssize_t size; 1245 ssize_t size;
@@ -1241,8 +1249,8 @@ __xfs_get_blocks(
1241 offset = (xfs_off_t)iblock << inode->i_blkbits; 1249 offset = (xfs_off_t)iblock << inode->i_blkbits;
1242 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); 1250 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
1243 size = bh_result->b_size; 1251 size = bh_result->b_size;
1244 VOP_BMAP(vp, offset, size, 1252 error = bhv_vop_bmap(vp, offset, size,
1245 create ? flags : BMAPI_READ, &iomap, &niomap, error); 1253 create ? flags : BMAPI_READ, &iomap, &niomap);
1246 if (error) 1254 if (error)
1247 return -error; 1255 return -error;
1248 if (niomap == 0) 1256 if (niomap == 0)
@@ -1370,13 +1378,13 @@ xfs_vm_direct_IO(
1370{ 1378{
1371 struct file *file = iocb->ki_filp; 1379 struct file *file = iocb->ki_filp;
1372 struct inode *inode = file->f_mapping->host; 1380 struct inode *inode = file->f_mapping->host;
1373 vnode_t *vp = vn_from_inode(inode); 1381 bhv_vnode_t *vp = vn_from_inode(inode);
1374 xfs_iomap_t iomap; 1382 xfs_iomap_t iomap;
1375 int maps = 1; 1383 int maps = 1;
1376 int error; 1384 int error;
1377 ssize_t ret; 1385 ssize_t ret;
1378 1386
1379 VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error); 1387 error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps);
1380 if (error) 1388 if (error)
1381 return -error; 1389 return -error;
1382 1390
@@ -1409,14 +1417,12 @@ xfs_vm_bmap(
1409 sector_t block) 1417 sector_t block)
1410{ 1418{
1411 struct inode *inode = (struct inode *)mapping->host; 1419 struct inode *inode = (struct inode *)mapping->host;
1412 vnode_t *vp = vn_from_inode(inode); 1420 bhv_vnode_t *vp = vn_from_inode(inode);
1413 int error;
1414 1421
1415 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 1422 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
1416 1423 bhv_vop_rwlock(vp, VRWLOCK_READ);
1417 VOP_RWLOCK(vp, VRWLOCK_READ); 1424 bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
1418 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 1425 bhv_vop_rwunlock(vp, VRWLOCK_READ);
1419 VOP_RWUNLOCK(vp, VRWLOCK_READ);
1420 return generic_block_bmap(mapping, block, xfs_get_blocks); 1426 return generic_block_bmap(mapping, block, xfs_get_blocks);
1421} 1427}
1422 1428
@@ -1452,6 +1458,7 @@ struct address_space_operations xfs_address_space_operations = {
1452 .readpage = xfs_vm_readpage, 1458 .readpage = xfs_vm_readpage,
1453 .readpages = xfs_vm_readpages, 1459 .readpages = xfs_vm_readpages,
1454 .writepage = xfs_vm_writepage, 1460 .writepage = xfs_vm_writepage,
1461 .writepages = xfs_vm_writepages,
1455 .sync_page = block_sync_page, 1462 .sync_page = block_sync_page,
1456 .releasepage = xfs_vm_releasepage, 1463 .releasepage = xfs_vm_releasepage,
1457 .invalidatepage = xfs_vm_invalidatepage, 1464 .invalidatepage = xfs_vm_invalidatepage,
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 60716543c68b..706d8c781b8a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005 Silicon Graphics, Inc. 2 * Copyright (c) 2005-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -30,9 +30,9 @@ typedef void (*xfs_ioend_func_t)(void *);
30typedef struct xfs_ioend { 30typedef struct xfs_ioend {
31 struct xfs_ioend *io_list; /* next ioend in chain */ 31 struct xfs_ioend *io_list; /* next ioend in chain */
32 unsigned int io_type; /* delalloc / unwritten */ 32 unsigned int io_type; /* delalloc / unwritten */
33 unsigned int io_uptodate; /* I/O status register */ 33 int io_error; /* I/O error code */
34 atomic_t io_remaining; /* hold count */ 34 atomic_t io_remaining; /* hold count */
35 struct vnode *io_vnode; /* file being written to */ 35 struct bhv_vnode *io_vnode; /* file being written to */
36 struct buffer_head *io_buffer_head;/* buffer linked list head */ 36 struct buffer_head *io_buffer_head;/* buffer linked list head */
37 struct buffer_head *io_buffer_tail;/* buffer linked list tail */ 37 struct buffer_head *io_buffer_tail;/* buffer linked list tail */
38 size_t io_size; /* size of the extent */ 38 size_t io_size; /* size of the extent */
@@ -43,4 +43,4 @@ typedef struct xfs_ioend {
43extern struct address_space_operations xfs_address_space_operations; 43extern struct address_space_operations xfs_address_space_operations;
44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); 44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
45 45
46#endif /* __XFS_IOPS_H__ */ 46#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index b768ea910bbe..5fb75d9151f2 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -21,7 +21,6 @@
21#include "xfs_log.h" 21#include "xfs_log.h"
22#include "xfs_trans.h" 22#include "xfs_trans.h"
23#include "xfs_sb.h" 23#include "xfs_sb.h"
24#include "xfs_dir.h"
25#include "xfs_mount.h" 24#include "xfs_mount.h"
26#include "xfs_export.h" 25#include "xfs_export.h"
27 26
@@ -97,7 +96,7 @@ xfs_fs_encode_fh(
97 int len; 96 int len;
98 int is64 = 0; 97 int is64 = 0;
99#if XFS_BIG_INUMS 98#if XFS_BIG_INUMS
100 vfs_t *vfs = vfs_from_sb(inode->i_sb); 99 bhv_vfs_t *vfs = vfs_from_sb(inode->i_sb);
101 100
102 if (!(vfs->vfs_flag & VFS_32BITINODES)) { 101 if (!(vfs->vfs_flag & VFS_32BITINODES)) {
103 /* filesystem may contain 64bit inode numbers */ 102 /* filesystem may contain 64bit inode numbers */
@@ -136,13 +135,13 @@ xfs_fs_get_dentry(
136 struct super_block *sb, 135 struct super_block *sb,
137 void *data) 136 void *data)
138{ 137{
139 vnode_t *vp; 138 bhv_vnode_t *vp;
140 struct inode *inode; 139 struct inode *inode;
141 struct dentry *result; 140 struct dentry *result;
142 vfs_t *vfsp = vfs_from_sb(sb); 141 bhv_vfs_t *vfsp = vfs_from_sb(sb);
143 int error; 142 int error;
144 143
145 VFS_VGET(vfsp, &vp, (fid_t *)data, error); 144 error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data);
146 if (error || vp == NULL) 145 if (error || vp == NULL)
147 return ERR_PTR(-ESTALE) ; 146 return ERR_PTR(-ESTALE) ;
148 147
@@ -160,12 +159,12 @@ xfs_fs_get_parent(
160 struct dentry *child) 159 struct dentry *child)
161{ 160{
162 int error; 161 int error;
163 vnode_t *vp, *cvp; 162 bhv_vnode_t *vp, *cvp;
164 struct dentry *parent; 163 struct dentry *parent;
165 164
166 cvp = NULL; 165 cvp = NULL;
167 vp = vn_from_inode(child->d_inode); 166 vp = vn_from_inode(child->d_inode);
168 VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error); 167 error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
169 if (unlikely(error)) 168 if (unlikely(error))
170 return ERR_PTR(-error); 169 return ERR_PTR(-error);
171 170
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index c847416f6d10..70662371bb11 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -21,7 +21,6 @@
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_sb.h" 22#include "xfs_sb.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_trans.h" 25#include "xfs_trans.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_alloc.h" 31#include "xfs_alloc.h"
33#include "xfs_btree.h" 32#include "xfs_btree.h"
34#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
38#include "xfs_inode.h" 36#include "xfs_inode.h"
@@ -58,15 +56,12 @@ __xfs_file_read(
58{ 56{
59 struct iovec iov = {buf, count}; 57 struct iovec iov = {buf, count};
60 struct file *file = iocb->ki_filp; 58 struct file *file = iocb->ki_filp;
61 vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); 59 bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
62 ssize_t rval;
63 60
64 BUG_ON(iocb->ki_pos != pos); 61 BUG_ON(iocb->ki_pos != pos);
65
66 if (unlikely(file->f_flags & O_DIRECT)) 62 if (unlikely(file->f_flags & O_DIRECT))
67 ioflags |= IO_ISDIRECT; 63 ioflags |= IO_ISDIRECT;
68 VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval); 64 return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
69 return rval;
70} 65}
71 66
72STATIC ssize_t 67STATIC ssize_t
@@ -100,15 +95,12 @@ __xfs_file_write(
100 struct iovec iov = {(void __user *)buf, count}; 95 struct iovec iov = {(void __user *)buf, count};
101 struct file *file = iocb->ki_filp; 96 struct file *file = iocb->ki_filp;
102 struct inode *inode = file->f_mapping->host; 97 struct inode *inode = file->f_mapping->host;
103 vnode_t *vp = vn_from_inode(inode); 98 bhv_vnode_t *vp = vn_from_inode(inode);
104 ssize_t rval;
105 99
106 BUG_ON(iocb->ki_pos != pos); 100 BUG_ON(iocb->ki_pos != pos);
107 if (unlikely(file->f_flags & O_DIRECT)) 101 if (unlikely(file->f_flags & O_DIRECT))
108 ioflags |= IO_ISDIRECT; 102 ioflags |= IO_ISDIRECT;
109 103 return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
110 VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
111 return rval;
112} 104}
113 105
114STATIC ssize_t 106STATIC ssize_t
@@ -140,7 +132,7 @@ __xfs_file_readv(
140 loff_t *ppos) 132 loff_t *ppos)
141{ 133{
142 struct inode *inode = file->f_mapping->host; 134 struct inode *inode = file->f_mapping->host;
143 vnode_t *vp = vn_from_inode(inode); 135 bhv_vnode_t *vp = vn_from_inode(inode);
144 struct kiocb kiocb; 136 struct kiocb kiocb;
145 ssize_t rval; 137 ssize_t rval;
146 138
@@ -149,7 +141,8 @@ __xfs_file_readv(
149 141
150 if (unlikely(file->f_flags & O_DIRECT)) 142 if (unlikely(file->f_flags & O_DIRECT))
151 ioflags |= IO_ISDIRECT; 143 ioflags |= IO_ISDIRECT;
152 VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); 144 rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
145 &kiocb.ki_pos, ioflags, NULL);
153 146
154 *ppos = kiocb.ki_pos; 147 *ppos = kiocb.ki_pos;
155 return rval; 148 return rval;
@@ -184,7 +177,7 @@ __xfs_file_writev(
184 loff_t *ppos) 177 loff_t *ppos)
185{ 178{
186 struct inode *inode = file->f_mapping->host; 179 struct inode *inode = file->f_mapping->host;
187 vnode_t *vp = vn_from_inode(inode); 180 bhv_vnode_t *vp = vn_from_inode(inode);
188 struct kiocb kiocb; 181 struct kiocb kiocb;
189 ssize_t rval; 182 ssize_t rval;
190 183
@@ -193,7 +186,8 @@ __xfs_file_writev(
193 if (unlikely(file->f_flags & O_DIRECT)) 186 if (unlikely(file->f_flags & O_DIRECT))
194 ioflags |= IO_ISDIRECT; 187 ioflags |= IO_ISDIRECT;
195 188
196 VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval); 189 rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
190 &kiocb.ki_pos, ioflags, NULL);
197 191
198 *ppos = kiocb.ki_pos; 192 *ppos = kiocb.ki_pos;
199 return rval; 193 return rval;
@@ -227,11 +221,8 @@ xfs_file_sendfile(
227 read_actor_t actor, 221 read_actor_t actor,
228 void *target) 222 void *target)
229{ 223{
230 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 224 return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
231 ssize_t rval; 225 filp, pos, 0, count, actor, target, NULL);
232
233 VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
234 return rval;
235} 226}
236 227
237STATIC ssize_t 228STATIC ssize_t
@@ -242,11 +233,8 @@ xfs_file_sendfile_invis(
242 read_actor_t actor, 233 read_actor_t actor,
243 void *target) 234 void *target)
244{ 235{
245 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 236 return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
246 ssize_t rval; 237 filp, pos, IO_INVIS, count, actor, target, NULL);
247
248 VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
249 return rval;
250} 238}
251 239
252STATIC ssize_t 240STATIC ssize_t
@@ -257,11 +245,8 @@ xfs_file_splice_read(
257 size_t len, 245 size_t len,
258 unsigned int flags) 246 unsigned int flags)
259{ 247{
260 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); 248 return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
261 ssize_t rval; 249 infilp, ppos, pipe, len, flags, 0, NULL);
262
263 VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval);
264 return rval;
265} 250}
266 251
267STATIC ssize_t 252STATIC ssize_t
@@ -272,11 +257,9 @@ xfs_file_splice_read_invis(
272 size_t len, 257 size_t len,
273 unsigned int flags) 258 unsigned int flags)
274{ 259{
275 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); 260 return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
276 ssize_t rval; 261 infilp, ppos, pipe, len, flags, IO_INVIS,
277 262 NULL);
278 VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval);
279 return rval;
280} 263}
281 264
282STATIC ssize_t 265STATIC ssize_t
@@ -287,11 +270,8 @@ xfs_file_splice_write(
287 size_t len, 270 size_t len,
288 unsigned int flags) 271 unsigned int flags)
289{ 272{
290 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); 273 return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
291 ssize_t rval; 274 pipe, outfilp, ppos, len, flags, 0, NULL);
292
293 VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval);
294 return rval;
295} 275}
296 276
297STATIC ssize_t 277STATIC ssize_t
@@ -302,11 +282,9 @@ xfs_file_splice_write_invis(
302 size_t len, 282 size_t len,
303 unsigned int flags) 283 unsigned int flags)
304{ 284{
305 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); 285 return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
306 ssize_t rval; 286 pipe, outfilp, ppos, len, flags, IO_INVIS,
307 287 NULL);
308 VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval);
309 return rval;
310} 288}
311 289
312STATIC int 290STATIC int
@@ -314,13 +292,17 @@ xfs_file_open(
314 struct inode *inode, 292 struct inode *inode,
315 struct file *filp) 293 struct file *filp)
316{ 294{
317 vnode_t *vp = vn_from_inode(inode);
318 int error;
319
320 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 295 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
321 return -EFBIG; 296 return -EFBIG;
322 VOP_OPEN(vp, NULL, error); 297 return -bhv_vop_open(vn_from_inode(inode), NULL);
323 return -error; 298}
299
300STATIC int
301xfs_file_close(
302 struct file *filp)
303{
304 return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
305 file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
324} 306}
325 307
326STATIC int 308STATIC int
@@ -328,12 +310,11 @@ xfs_file_release(
328 struct inode *inode, 310 struct inode *inode,
329 struct file *filp) 311 struct file *filp)
330{ 312{
331 vnode_t *vp = vn_from_inode(inode); 313 bhv_vnode_t *vp = vn_from_inode(inode);
332 int error = 0;
333 314
334 if (vp) 315 if (vp)
335 VOP_RELEASE(vp, error); 316 return -bhv_vop_release(vp);
336 return -error; 317 return 0;
337} 318}
338 319
339STATIC int 320STATIC int
@@ -342,15 +323,14 @@ xfs_file_fsync(
342 struct dentry *dentry, 323 struct dentry *dentry,
343 int datasync) 324 int datasync)
344{ 325{
345 struct inode *inode = dentry->d_inode; 326 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
346 vnode_t *vp = vn_from_inode(inode);
347 int error;
348 int flags = FSYNC_WAIT; 327 int flags = FSYNC_WAIT;
349 328
350 if (datasync) 329 if (datasync)
351 flags |= FSYNC_DATA; 330 flags |= FSYNC_DATA;
352 VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); 331 if (VN_TRUNC(vp))
353 return -error; 332 VUNTRUNCATE(vp);
333 return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
354} 334}
355 335
356#ifdef CONFIG_XFS_DMAPI 336#ifdef CONFIG_XFS_DMAPI
@@ -361,16 +341,11 @@ xfs_vm_nopage(
361 int *type) 341 int *type)
362{ 342{
363 struct inode *inode = area->vm_file->f_dentry->d_inode; 343 struct inode *inode = area->vm_file->f_dentry->d_inode;
364 vnode_t *vp = vn_from_inode(inode); 344 bhv_vnode_t *vp = vn_from_inode(inode);
365 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
366 int error;
367 345
368 ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI); 346 ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
369 347 if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
370 error = XFS_SEND_MMAP(mp, area, 0);
371 if (error)
372 return NULL; 348 return NULL;
373
374 return filemap_nopage(area, address, type); 349 return filemap_nopage(area, address, type);
375} 350}
376#endif /* CONFIG_XFS_DMAPI */ 351#endif /* CONFIG_XFS_DMAPI */
@@ -382,7 +357,7 @@ xfs_file_readdir(
382 filldir_t filldir) 357 filldir_t filldir)
383{ 358{
384 int error = 0; 359 int error = 0;
385 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 360 bhv_vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
386 uio_t uio; 361 uio_t uio;
387 iovec_t iov; 362 iovec_t iov;
388 int eof = 0; 363 int eof = 0;
@@ -417,7 +392,7 @@ xfs_file_readdir(
417 392
418 start_offset = uio.uio_offset; 393 start_offset = uio.uio_offset;
419 394
420 VOP_READDIR(vp, &uio, NULL, &eof, error); 395 error = bhv_vop_readdir(vp, &uio, NULL, &eof);
421 if ((uio.uio_offset == start_offset) || error) { 396 if ((uio.uio_offset == start_offset) || error) {
422 size = 0; 397 size = 0;
423 break; 398 break;
@@ -456,38 +431,28 @@ xfs_file_mmap(
456 struct file *filp, 431 struct file *filp,
457 struct vm_area_struct *vma) 432 struct vm_area_struct *vma)
458{ 433{
459 struct inode *ip = filp->f_dentry->d_inode;
460 vnode_t *vp = vn_from_inode(ip);
461 vattr_t vattr;
462 int error;
463
464 vma->vm_ops = &xfs_file_vm_ops; 434 vma->vm_ops = &xfs_file_vm_ops;
465 435
466#ifdef CONFIG_XFS_DMAPI 436#ifdef CONFIG_XFS_DMAPI
467 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 437 if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
468 vma->vm_ops = &xfs_dmapi_file_vm_ops; 438 vma->vm_ops = &xfs_dmapi_file_vm_ops;
469 }
470#endif /* CONFIG_XFS_DMAPI */ 439#endif /* CONFIG_XFS_DMAPI */
471 440
472 vattr.va_mask = XFS_AT_UPDATIME; 441 file_accessed(filp);
473 VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
474 if (likely(!error))
475 __vn_revalidate(vp, &vattr); /* update flags */
476 return 0; 442 return 0;
477} 443}
478 444
479
480STATIC long 445STATIC long
481xfs_file_ioctl( 446xfs_file_ioctl(
482 struct file *filp, 447 struct file *filp,
483 unsigned int cmd, 448 unsigned int cmd,
484 unsigned long arg) 449 unsigned long p)
485{ 450{
486 int error; 451 int error;
487 struct inode *inode = filp->f_dentry->d_inode; 452 struct inode *inode = filp->f_dentry->d_inode;
488 vnode_t *vp = vn_from_inode(inode); 453 bhv_vnode_t *vp = vn_from_inode(inode);
489 454
490 VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error); 455 error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
491 VMODIFY(vp); 456 VMODIFY(vp);
492 457
493 /* NOTE: some of the ioctl's return positive #'s as a 458 /* NOTE: some of the ioctl's return positive #'s as a
@@ -503,13 +468,13 @@ STATIC long
503xfs_file_ioctl_invis( 468xfs_file_ioctl_invis(
504 struct file *filp, 469 struct file *filp,
505 unsigned int cmd, 470 unsigned int cmd,
506 unsigned long arg) 471 unsigned long p)
507{ 472{
508 struct inode *inode = filp->f_dentry->d_inode;
509 vnode_t *vp = vn_from_inode(inode);
510 int error; 473 int error;
474 struct inode *inode = filp->f_dentry->d_inode;
475 bhv_vnode_t *vp = vn_from_inode(inode);
511 476
512 VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); 477 error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
513 VMODIFY(vp); 478 VMODIFY(vp);
514 479
515 /* NOTE: some of the ioctl's return positive #'s as a 480 /* NOTE: some of the ioctl's return positive #'s as a
@@ -528,7 +493,7 @@ xfs_vm_mprotect(
528 struct vm_area_struct *vma, 493 struct vm_area_struct *vma,
529 unsigned int newflags) 494 unsigned int newflags)
530{ 495{
531 vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode); 496 bhv_vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
532 int error = 0; 497 int error = 0;
533 498
534 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 499 if (vp->v_vfsp->vfs_flag & VFS_DMI) {
@@ -554,24 +519,19 @@ STATIC int
554xfs_file_open_exec( 519xfs_file_open_exec(
555 struct inode *inode) 520 struct inode *inode)
556{ 521{
557 vnode_t *vp = vn_from_inode(inode); 522 bhv_vnode_t *vp = vn_from_inode(inode);
558 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
559 int error = 0;
560 xfs_inode_t *ip;
561 523
562 if (vp->v_vfsp->vfs_flag & VFS_DMI) { 524 if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
563 ip = xfs_vtoi(vp); 525 xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
564 if (!ip) { 526 xfs_inode_t *ip = xfs_vtoi(vp);
565 error = -EINVAL; 527
566 goto open_exec_out; 528 if (!ip)
567 } 529 return -EINVAL;
568 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) { 530 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
569 error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp, 531 return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
570 0, 0, 0, NULL); 532 0, 0, 0, NULL);
571 }
572 } 533 }
573open_exec_out: 534 return 0;
574 return error;
575} 535}
576#endif /* HAVE_FOP_OPEN_EXEC */ 536#endif /* HAVE_FOP_OPEN_EXEC */
577 537
@@ -592,6 +552,7 @@ const struct file_operations xfs_file_operations = {
592#endif 552#endif
593 .mmap = xfs_file_mmap, 553 .mmap = xfs_file_mmap,
594 .open = xfs_file_open, 554 .open = xfs_file_open,
555 .flush = xfs_file_close,
595 .release = xfs_file_release, 556 .release = xfs_file_release,
596 .fsync = xfs_file_fsync, 557 .fsync = xfs_file_fsync,
597#ifdef HAVE_FOP_OPEN_EXEC 558#ifdef HAVE_FOP_OPEN_EXEC
@@ -616,6 +577,7 @@ const struct file_operations xfs_invis_file_operations = {
616#endif 577#endif
617 .mmap = xfs_file_mmap, 578 .mmap = xfs_file_mmap,
618 .open = xfs_file_open, 579 .open = xfs_file_open,
580 .flush = xfs_file_close,
619 .release = xfs_file_release, 581 .release = xfs_file_release,
620 .fsync = xfs_file_fsync, 582 .fsync = xfs_file_fsync,
621}; 583};
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index 575f2a790f31..dc0562828e76 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -15,40 +15,12 @@
15 * along with this program; if not, write the Free Software Foundation, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18
19#include "xfs.h" 18#include "xfs.h"
20 19
21/* 20int fs_noerr(void) { return 0; }
22 * Stub for no-op vnode operations that return error status. 21int fs_nosys(void) { return ENOSYS; }
23 */ 22void fs_noval(void) { return; }
24int
25fs_noerr(void)
26{
27 return 0;
28}
29 23
30/*
31 * Operation unsupported under this file system.
32 */
33int
34fs_nosys(void)
35{
36 return ENOSYS;
37}
38
39/*
40 * Stub for inactive, strategy, and read/write lock/unlock. Does nothing.
41 */
42/* ARGSUSED */
43void
44fs_noval(void)
45{
46}
47
48/*
49 * vnode pcache layer for vnode_tosspages.
50 * 'last' parameter unused but left in for IRIX compatibility
51 */
52void 24void
53fs_tosspages( 25fs_tosspages(
54 bhv_desc_t *bdp, 26 bhv_desc_t *bdp,
@@ -56,18 +28,13 @@ fs_tosspages(
56 xfs_off_t last, 28 xfs_off_t last,
57 int fiopt) 29 int fiopt)
58{ 30{
59 vnode_t *vp = BHV_TO_VNODE(bdp); 31 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
60 struct inode *ip = vn_to_inode(vp); 32 struct inode *ip = vn_to_inode(vp);
61 33
62 if (VN_CACHED(vp)) 34 if (VN_CACHED(vp))
63 truncate_inode_pages(ip->i_mapping, first); 35 truncate_inode_pages(ip->i_mapping, first);
64} 36}
65 37
66
67/*
68 * vnode pcache layer for vnode_flushinval_pages.
69 * 'last' parameter unused but left in for IRIX compatibility
70 */
71void 38void
72fs_flushinval_pages( 39fs_flushinval_pages(
73 bhv_desc_t *bdp, 40 bhv_desc_t *bdp,
@@ -75,20 +42,17 @@ fs_flushinval_pages(
75 xfs_off_t last, 42 xfs_off_t last,
76 int fiopt) 43 int fiopt)
77{ 44{
78 vnode_t *vp = BHV_TO_VNODE(bdp); 45 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
79 struct inode *ip = vn_to_inode(vp); 46 struct inode *ip = vn_to_inode(vp);
80 47
81 if (VN_CACHED(vp)) { 48 if (VN_CACHED(vp)) {
49 if (VN_TRUNC(vp))
50 VUNTRUNCATE(vp);
82 filemap_write_and_wait(ip->i_mapping); 51 filemap_write_and_wait(ip->i_mapping);
83
84 truncate_inode_pages(ip->i_mapping, first); 52 truncate_inode_pages(ip->i_mapping, first);
85 } 53 }
86} 54}
87 55
88/*
89 * vnode pcache layer for vnode_flush_pages.
90 * 'last' parameter unused but left in for IRIX compatibility
91 */
92int 56int
93fs_flush_pages( 57fs_flush_pages(
94 bhv_desc_t *bdp, 58 bhv_desc_t *bdp,
@@ -97,15 +61,16 @@ fs_flush_pages(
97 uint64_t flags, 61 uint64_t flags,
98 int fiopt) 62 int fiopt)
99{ 63{
100 vnode_t *vp = BHV_TO_VNODE(bdp); 64 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
101 struct inode *ip = vn_to_inode(vp); 65 struct inode *ip = vn_to_inode(vp);
102 66
103 if (VN_CACHED(vp)) { 67 if (VN_DIRTY(vp)) {
68 if (VN_TRUNC(vp))
69 VUNTRUNCATE(vp);
104 filemap_fdatawrite(ip->i_mapping); 70 filemap_fdatawrite(ip->i_mapping);
105 if (flags & XFS_B_ASYNC) 71 if (flags & XFS_B_ASYNC)
106 return 0; 72 return 0;
107 filemap_fdatawait(ip->i_mapping); 73 filemap_fdatawait(ip->i_mapping);
108 } 74 }
109
110 return 0; 75 return 0;
111} 76}
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c
index 6e8085f34635..6c162c3dde7e 100644
--- a/fs/xfs/linux-2.6/xfs_globals.c
+++ b/fs/xfs/linux-2.6/xfs_globals.c
@@ -45,6 +45,7 @@ xfs_param_t xfs_params = {
45 .xfs_buf_age = { 1*100, 15*100, 7200*100}, 45 .xfs_buf_age = { 1*100, 15*100, 7200*100},
46 .inherit_nosym = { 0, 0, 1 }, 46 .inherit_nosym = { 0, 0, 1 },
47 .rotorstep = { 1, 1, 255 }, 47 .rotorstep = { 1, 1, 255 },
48 .inherit_nodfrg = { 0, 1, 1 },
48}; 49};
49 50
50/* 51/*
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 84478491609b..6e52a5dd38d8 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -31,7 +30,6 @@
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -78,7 +76,7 @@ xfs_find_handle(
78 xfs_handle_t handle; 76 xfs_handle_t handle;
79 xfs_fsop_handlereq_t hreq; 77 xfs_fsop_handlereq_t hreq;
80 struct inode *inode; 78 struct inode *inode;
81 struct vnode *vp; 79 bhv_vnode_t *vp;
82 80
83 if (copy_from_user(&hreq, arg, sizeof(hreq))) 81 if (copy_from_user(&hreq, arg, sizeof(hreq)))
84 return -XFS_ERROR(EFAULT); 82 return -XFS_ERROR(EFAULT);
@@ -192,7 +190,7 @@ xfs_vget_fsop_handlereq(
192 xfs_mount_t *mp, 190 xfs_mount_t *mp,
193 struct inode *parinode, /* parent inode pointer */ 191 struct inode *parinode, /* parent inode pointer */
194 xfs_fsop_handlereq_t *hreq, 192 xfs_fsop_handlereq_t *hreq,
195 vnode_t **vp, 193 bhv_vnode_t **vp,
196 struct inode **inode) 194 struct inode **inode)
197{ 195{
198 void __user *hanp; 196 void __user *hanp;
@@ -202,7 +200,7 @@ xfs_vget_fsop_handlereq(
202 xfs_handle_t handle; 200 xfs_handle_t handle;
203 xfs_inode_t *ip; 201 xfs_inode_t *ip;
204 struct inode *inodep; 202 struct inode *inodep;
205 vnode_t *vpp; 203 bhv_vnode_t *vpp;
206 xfs_ino_t ino; 204 xfs_ino_t ino;
207 __u32 igen; 205 __u32 igen;
208 int error; 206 int error;
@@ -277,7 +275,7 @@ xfs_open_by_handle(
277 struct file *filp; 275 struct file *filp;
278 struct inode *inode; 276 struct inode *inode;
279 struct dentry *dentry; 277 struct dentry *dentry;
280 vnode_t *vp; 278 bhv_vnode_t *vp;
281 xfs_fsop_handlereq_t hreq; 279 xfs_fsop_handlereq_t hreq;
282 280
283 if (!capable(CAP_SYS_ADMIN)) 281 if (!capable(CAP_SYS_ADMIN))
@@ -362,7 +360,7 @@ xfs_readlink_by_handle(
362 struct uio auio; 360 struct uio auio;
363 struct inode *inode; 361 struct inode *inode;
364 xfs_fsop_handlereq_t hreq; 362 xfs_fsop_handlereq_t hreq;
365 vnode_t *vp; 363 bhv_vnode_t *vp;
366 __u32 olen; 364 __u32 olen;
367 365
368 if (!capable(CAP_SYS_ADMIN)) 366 if (!capable(CAP_SYS_ADMIN))
@@ -393,9 +391,11 @@ xfs_readlink_by_handle(
393 auio.uio_segflg = UIO_USERSPACE; 391 auio.uio_segflg = UIO_USERSPACE;
394 auio.uio_resid = olen; 392 auio.uio_resid = olen;
395 393
396 VOP_READLINK(vp, &auio, IO_INVIS, NULL, error); 394 error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
397
398 VN_RELE(vp); 395 VN_RELE(vp);
396 if (error)
397 return -error;
398
399 return (olen - auio.uio_resid); 399 return (olen - auio.uio_resid);
400} 400}
401 401
@@ -411,7 +411,7 @@ xfs_fssetdm_by_handle(
411 xfs_fsop_setdm_handlereq_t dmhreq; 411 xfs_fsop_setdm_handlereq_t dmhreq;
412 struct inode *inode; 412 struct inode *inode;
413 bhv_desc_t *bdp; 413 bhv_desc_t *bdp;
414 vnode_t *vp; 414 bhv_vnode_t *vp;
415 415
416 if (!capable(CAP_MKNOD)) 416 if (!capable(CAP_MKNOD))
417 return -XFS_ERROR(EPERM); 417 return -XFS_ERROR(EPERM);
@@ -452,7 +452,7 @@ xfs_attrlist_by_handle(
452 attrlist_cursor_kern_t *cursor; 452 attrlist_cursor_kern_t *cursor;
453 xfs_fsop_attrlist_handlereq_t al_hreq; 453 xfs_fsop_attrlist_handlereq_t al_hreq;
454 struct inode *inode; 454 struct inode *inode;
455 vnode_t *vp; 455 bhv_vnode_t *vp;
456 char *kbuf; 456 char *kbuf;
457 457
458 if (!capable(CAP_SYS_ADMIN)) 458 if (!capable(CAP_SYS_ADMIN))
@@ -472,8 +472,8 @@ xfs_attrlist_by_handle(
472 goto out_vn_rele; 472 goto out_vn_rele;
473 473
474 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos; 474 cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
475 VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags, 475 error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
476 cursor, NULL, error); 476 cursor, NULL);
477 if (error) 477 if (error)
478 goto out_kfree; 478 goto out_kfree;
479 479
@@ -490,7 +490,7 @@ xfs_attrlist_by_handle(
490 490
491STATIC int 491STATIC int
492xfs_attrmulti_attr_get( 492xfs_attrmulti_attr_get(
493 struct vnode *vp, 493 bhv_vnode_t *vp,
494 char *name, 494 char *name,
495 char __user *ubuf, 495 char __user *ubuf,
496 __uint32_t *len, 496 __uint32_t *len,
@@ -505,7 +505,7 @@ xfs_attrmulti_attr_get(
505 if (!kbuf) 505 if (!kbuf)
506 return ENOMEM; 506 return ENOMEM;
507 507
508 VOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error); 508 error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
509 if (error) 509 if (error)
510 goto out_kfree; 510 goto out_kfree;
511 511
@@ -519,7 +519,7 @@ xfs_attrmulti_attr_get(
519 519
520STATIC int 520STATIC int
521xfs_attrmulti_attr_set( 521xfs_attrmulti_attr_set(
522 struct vnode *vp, 522 bhv_vnode_t *vp,
523 char *name, 523 char *name,
524 const char __user *ubuf, 524 const char __user *ubuf,
525 __uint32_t len, 525 __uint32_t len,
@@ -542,7 +542,7 @@ xfs_attrmulti_attr_set(
542 if (copy_from_user(kbuf, ubuf, len)) 542 if (copy_from_user(kbuf, ubuf, len))
543 goto out_kfree; 543 goto out_kfree;
544 544
545 VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error); 545 error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
546 546
547 out_kfree: 547 out_kfree:
548 kfree(kbuf); 548 kfree(kbuf);
@@ -551,20 +551,15 @@ xfs_attrmulti_attr_set(
551 551
552STATIC int 552STATIC int
553xfs_attrmulti_attr_remove( 553xfs_attrmulti_attr_remove(
554 struct vnode *vp, 554 bhv_vnode_t *vp,
555 char *name, 555 char *name,
556 __uint32_t flags) 556 __uint32_t flags)
557{ 557{
558 int error;
559
560
561 if (IS_RDONLY(&vp->v_inode)) 558 if (IS_RDONLY(&vp->v_inode))
562 return -EROFS; 559 return -EROFS;
563 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode)) 560 if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
564 return EPERM; 561 return EPERM;
565 562 return bhv_vop_attr_remove(vp, name, flags, NULL);
566 VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
567 return error;
568} 563}
569 564
570STATIC int 565STATIC int
@@ -578,7 +573,7 @@ xfs_attrmulti_by_handle(
578 xfs_attr_multiop_t *ops; 573 xfs_attr_multiop_t *ops;
579 xfs_fsop_attrmulti_handlereq_t am_hreq; 574 xfs_fsop_attrmulti_handlereq_t am_hreq;
580 struct inode *inode; 575 struct inode *inode;
581 vnode_t *vp; 576 bhv_vnode_t *vp;
582 unsigned int i, size; 577 unsigned int i, size;
583 char *attr_name; 578 char *attr_name;
584 579
@@ -658,7 +653,7 @@ xfs_attrmulti_by_handle(
658STATIC int 653STATIC int
659xfs_ioc_space( 654xfs_ioc_space(
660 bhv_desc_t *bdp, 655 bhv_desc_t *bdp,
661 vnode_t *vp, 656 bhv_vnode_t *vp,
662 struct file *filp, 657 struct file *filp,
663 int flags, 658 int flags,
664 unsigned int cmd, 659 unsigned int cmd,
@@ -682,7 +677,7 @@ xfs_ioc_fsgeometry(
682 677
683STATIC int 678STATIC int
684xfs_ioc_xattr( 679xfs_ioc_xattr(
685 vnode_t *vp, 680 bhv_vnode_t *vp,
686 xfs_inode_t *ip, 681 xfs_inode_t *ip,
687 struct file *filp, 682 struct file *filp,
688 unsigned int cmd, 683 unsigned int cmd,
@@ -711,7 +706,7 @@ xfs_ioctl(
711 void __user *arg) 706 void __user *arg)
712{ 707{
713 int error; 708 int error;
714 vnode_t *vp; 709 bhv_vnode_t *vp;
715 xfs_inode_t *ip; 710 xfs_inode_t *ip;
716 xfs_mount_t *mp; 711 xfs_mount_t *mp;
717 712
@@ -962,7 +957,7 @@ xfs_ioctl(
962STATIC int 957STATIC int
963xfs_ioc_space( 958xfs_ioc_space(
964 bhv_desc_t *bdp, 959 bhv_desc_t *bdp,
965 vnode_t *vp, 960 bhv_vnode_t *vp,
966 struct file *filp, 961 struct file *filp,
967 int ioflags, 962 int ioflags,
968 unsigned int cmd, 963 unsigned int cmd,
@@ -1153,14 +1148,14 @@ xfs_di2lxflags(
1153 1148
1154STATIC int 1149STATIC int
1155xfs_ioc_xattr( 1150xfs_ioc_xattr(
1156 vnode_t *vp, 1151 bhv_vnode_t *vp,
1157 xfs_inode_t *ip, 1152 xfs_inode_t *ip,
1158 struct file *filp, 1153 struct file *filp,
1159 unsigned int cmd, 1154 unsigned int cmd,
1160 void __user *arg) 1155 void __user *arg)
1161{ 1156{
1162 struct fsxattr fa; 1157 struct fsxattr fa;
1163 struct vattr *vattr; 1158 struct bhv_vattr *vattr;
1164 int error = 0; 1159 int error = 0;
1165 int attr_flags; 1160 int attr_flags;
1166 unsigned int flags; 1161 unsigned int flags;
@@ -1173,7 +1168,7 @@ xfs_ioc_xattr(
1173 case XFS_IOC_FSGETXATTR: { 1168 case XFS_IOC_FSGETXATTR: {
1174 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1169 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1175 XFS_AT_NEXTENTS | XFS_AT_PROJID; 1170 XFS_AT_NEXTENTS | XFS_AT_PROJID;
1176 VOP_GETATTR(vp, vattr, 0, NULL, error); 1171 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1177 if (unlikely(error)) { 1172 if (unlikely(error)) {
1178 error = -error; 1173 error = -error;
1179 break; 1174 break;
@@ -1206,7 +1201,7 @@ xfs_ioc_xattr(
1206 vattr->va_extsize = fa.fsx_extsize; 1201 vattr->va_extsize = fa.fsx_extsize;
1207 vattr->va_projid = fa.fsx_projid; 1202 vattr->va_projid = fa.fsx_projid;
1208 1203
1209 VOP_SETATTR(vp, vattr, attr_flags, NULL, error); 1204 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
1210 if (likely(!error)) 1205 if (likely(!error))
1211 __vn_revalidate(vp, vattr); /* update flags */ 1206 __vn_revalidate(vp, vattr); /* update flags */
1212 error = -error; 1207 error = -error;
@@ -1216,7 +1211,7 @@ xfs_ioc_xattr(
1216 case XFS_IOC_FSGETXATTRA: { 1211 case XFS_IOC_FSGETXATTRA: {
1217 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \ 1212 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
1218 XFS_AT_ANEXTENTS | XFS_AT_PROJID; 1213 XFS_AT_ANEXTENTS | XFS_AT_PROJID;
1219 VOP_GETATTR(vp, vattr, 0, NULL, error); 1214 error = bhv_vop_getattr(vp, vattr, 0, NULL);
1220 if (unlikely(error)) { 1215 if (unlikely(error)) {
1221 error = -error; 1216 error = -error;
1222 break; 1217 break;
@@ -1262,7 +1257,7 @@ xfs_ioc_xattr(
1262 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 1257 vattr->va_xflags = xfs_merge_ioc_xflags(flags,
1263 xfs_ip2xflags(ip)); 1258 xfs_ip2xflags(ip));
1264 1259
1265 VOP_SETATTR(vp, vattr, attr_flags, NULL, error); 1260 error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
1266 if (likely(!error)) 1261 if (likely(!error))
1267 __vn_revalidate(vp, vattr); /* update flags */ 1262 __vn_revalidate(vp, vattr); /* update flags */
1268 error = -error; 1263 error = -error;
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 251bfe451a3f..601f01c92f7f 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -114,7 +114,7 @@ xfs_compat_ioctl(
114 unsigned long arg) 114 unsigned long arg)
115{ 115{
116 struct inode *inode = file->f_dentry->d_inode; 116 struct inode *inode = file->f_dentry->d_inode;
117 vnode_t *vp = vn_from_inode(inode); 117 bhv_vnode_t *vp = vn_from_inode(inode);
118 int error; 118 int error;
119 119
120 switch (cmd) { 120 switch (cmd) {
@@ -193,7 +193,7 @@ xfs_compat_ioctl(
193 return -ENOIOCTLCMD; 193 return -ENOIOCTLCMD;
194 } 194 }
195 195
196 VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error); 196 error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg);
197 VMODIFY(vp); 197 VMODIFY(vp);
198 198
199 return error; 199 return error;
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 2e2e275c786f..12810baeb5d4 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -61,7 +59,7 @@
61 */ 59 */
62xfs_inode_t * 60xfs_inode_t *
63xfs_vtoi( 61xfs_vtoi(
64 struct vnode *vp) 62 bhv_vnode_t *vp)
65{ 63{
66 bhv_desc_t *bdp; 64 bhv_desc_t *bdp;
67 65
@@ -80,7 +78,7 @@ void
80xfs_synchronize_atime( 78xfs_synchronize_atime(
81 xfs_inode_t *ip) 79 xfs_inode_t *ip)
82{ 80{
83 vnode_t *vp; 81 bhv_vnode_t *vp;
84 82
85 vp = XFS_ITOV_NULL(ip); 83 vp = XFS_ITOV_NULL(ip);
86 if (vp) { 84 if (vp) {
@@ -200,14 +198,10 @@ xfs_ichgtime_fast(
200STATIC void 198STATIC void
201xfs_validate_fields( 199xfs_validate_fields(
202 struct inode *ip, 200 struct inode *ip,
203 struct vattr *vattr) 201 bhv_vattr_t *vattr)
204{ 202{
205 vnode_t *vp = vn_from_inode(ip);
206 int error;
207
208 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS; 203 vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
209 VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error); 204 if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) {
210 if (likely(!error)) {
211 ip->i_nlink = vattr->va_nlink; 205 ip->i_nlink = vattr->va_nlink;
212 ip->i_blocks = vattr->va_nblocks; 206 ip->i_blocks = vattr->va_nblocks;
213 207
@@ -225,7 +219,7 @@ xfs_validate_fields(
225 */ 219 */
226STATIC int 220STATIC int
227xfs_init_security( 221xfs_init_security(
228 struct vnode *vp, 222 bhv_vnode_t *vp,
229 struct inode *dir) 223 struct inode *dir)
230{ 224{
231 struct inode *ip = vn_to_inode(vp); 225 struct inode *ip = vn_to_inode(vp);
@@ -241,7 +235,7 @@ xfs_init_security(
241 return -error; 235 return -error;
242 } 236 }
243 237
244 VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error); 238 error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL);
245 if (!error) 239 if (!error)
246 VMODIFY(vp); 240 VMODIFY(vp);
247 241
@@ -264,13 +258,12 @@ xfs_has_fs_struct(struct task_struct *task)
264 258
265STATIC inline void 259STATIC inline void
266xfs_cleanup_inode( 260xfs_cleanup_inode(
267 vnode_t *dvp, 261 bhv_vnode_t *dvp,
268 vnode_t *vp, 262 bhv_vnode_t *vp,
269 struct dentry *dentry, 263 struct dentry *dentry,
270 int mode) 264 int mode)
271{ 265{
272 struct dentry teardown = {}; 266 struct dentry teardown = {};
273 int error;
274 267
275 /* Oh, the horror. 268 /* Oh, the horror.
276 * If we can't add the ACL or we fail in 269 * If we can't add the ACL or we fail in
@@ -281,9 +274,9 @@ xfs_cleanup_inode(
281 teardown.d_name = dentry->d_name; 274 teardown.d_name = dentry->d_name;
282 275
283 if (S_ISDIR(mode)) 276 if (S_ISDIR(mode))
284 VOP_RMDIR(dvp, &teardown, NULL, error); 277 bhv_vop_rmdir(dvp, &teardown, NULL);
285 else 278 else
286 VOP_REMOVE(dvp, &teardown, NULL, error); 279 bhv_vop_remove(dvp, &teardown, NULL);
287 VN_RELE(vp); 280 VN_RELE(vp);
288} 281}
289 282
@@ -295,8 +288,8 @@ xfs_vn_mknod(
295 dev_t rdev) 288 dev_t rdev)
296{ 289{
297 struct inode *ip; 290 struct inode *ip;
298 vattr_t vattr = { 0 }; 291 bhv_vattr_t vattr = { 0 };
299 vnode_t *vp = NULL, *dvp = vn_from_inode(dir); 292 bhv_vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
300 xfs_acl_t *default_acl = NULL; 293 xfs_acl_t *default_acl = NULL;
301 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; 294 attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
302 int error; 295 int error;
@@ -330,10 +323,10 @@ xfs_vn_mknod(
330 vattr.va_mask |= XFS_AT_RDEV; 323 vattr.va_mask |= XFS_AT_RDEV;
331 /*FALLTHROUGH*/ 324 /*FALLTHROUGH*/
332 case S_IFREG: 325 case S_IFREG:
333 VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error); 326 error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL);
334 break; 327 break;
335 case S_IFDIR: 328 case S_IFDIR:
336 VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error); 329 error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL);
337 break; 330 break;
338 default: 331 default:
339 error = EINVAL; 332 error = EINVAL;
@@ -396,14 +389,14 @@ xfs_vn_lookup(
396 struct dentry *dentry, 389 struct dentry *dentry,
397 struct nameidata *nd) 390 struct nameidata *nd)
398{ 391{
399 struct vnode *vp = vn_from_inode(dir), *cvp; 392 bhv_vnode_t *vp = vn_from_inode(dir), *cvp;
400 int error; 393 int error;
401 394
402 if (dentry->d_name.len >= MAXNAMELEN) 395 if (dentry->d_name.len >= MAXNAMELEN)
403 return ERR_PTR(-ENAMETOOLONG); 396 return ERR_PTR(-ENAMETOOLONG);
404 397
405 VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error); 398 error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL);
406 if (error) { 399 if (unlikely(error)) {
407 if (unlikely(error != ENOENT)) 400 if (unlikely(error != ENOENT))
408 return ERR_PTR(-error); 401 return ERR_PTR(-error);
409 d_add(dentry, NULL); 402 d_add(dentry, NULL);
@@ -420,9 +413,9 @@ xfs_vn_link(
420 struct dentry *dentry) 413 struct dentry *dentry)
421{ 414{
422 struct inode *ip; /* inode of guy being linked to */ 415 struct inode *ip; /* inode of guy being linked to */
423 vnode_t *tdvp; /* target directory for new name/link */ 416 bhv_vnode_t *tdvp; /* target directory for new name/link */
424 vnode_t *vp; /* vp of name being linked */ 417 bhv_vnode_t *vp; /* vp of name being linked */
425 vattr_t vattr; 418 bhv_vattr_t vattr;
426 int error; 419 int error;
427 420
428 ip = old_dentry->d_inode; /* inode being linked to */ 421 ip = old_dentry->d_inode; /* inode being linked to */
@@ -432,7 +425,7 @@ xfs_vn_link(
432 tdvp = vn_from_inode(dir); 425 tdvp = vn_from_inode(dir);
433 vp = vn_from_inode(ip); 426 vp = vn_from_inode(ip);
434 427
435 VOP_LINK(tdvp, vp, dentry, NULL, error); 428 error = bhv_vop_link(tdvp, vp, dentry, NULL);
436 if (likely(!error)) { 429 if (likely(!error)) {
437 VMODIFY(tdvp); 430 VMODIFY(tdvp);
438 VN_HOLD(vp); 431 VN_HOLD(vp);
@@ -448,14 +441,14 @@ xfs_vn_unlink(
448 struct dentry *dentry) 441 struct dentry *dentry)
449{ 442{
450 struct inode *inode; 443 struct inode *inode;
451 vnode_t *dvp; /* directory containing name to remove */ 444 bhv_vnode_t *dvp; /* directory containing name to remove */
452 vattr_t vattr; 445 bhv_vattr_t vattr;
453 int error; 446 int error;
454 447
455 inode = dentry->d_inode; 448 inode = dentry->d_inode;
456 dvp = vn_from_inode(dir); 449 dvp = vn_from_inode(dir);
457 450
458 VOP_REMOVE(dvp, dentry, NULL, error); 451 error = bhv_vop_remove(dvp, dentry, NULL);
459 if (likely(!error)) { 452 if (likely(!error)) {
460 xfs_validate_fields(dir, &vattr); /* size needs update */ 453 xfs_validate_fields(dir, &vattr); /* size needs update */
461 xfs_validate_fields(inode, &vattr); 454 xfs_validate_fields(inode, &vattr);
@@ -470,27 +463,26 @@ xfs_vn_symlink(
470 const char *symname) 463 const char *symname)
471{ 464{
472 struct inode *ip; 465 struct inode *ip;
473 vattr_t vattr = { 0 }; 466 bhv_vattr_t va = { 0 };
474 vnode_t *dvp; /* directory containing name of symlink */ 467 bhv_vnode_t *dvp; /* directory containing name of symlink */
475 vnode_t *cvp; /* used to lookup symlink to put in dentry */ 468 bhv_vnode_t *cvp; /* used to lookup symlink to put in dentry */
476 int error; 469 int error;
477 470
478 dvp = vn_from_inode(dir); 471 dvp = vn_from_inode(dir);
479 cvp = NULL; 472 cvp = NULL;
480 473
481 vattr.va_mode = S_IFLNK | 474 va.va_mode = S_IFLNK |
482 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); 475 (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
483 vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE; 476 va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
484 477
485 error = 0; 478 error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL);
486 VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error);
487 if (likely(!error && cvp)) { 479 if (likely(!error && cvp)) {
488 error = xfs_init_security(cvp, dir); 480 error = xfs_init_security(cvp, dir);
489 if (likely(!error)) { 481 if (likely(!error)) {
490 ip = vn_to_inode(cvp); 482 ip = vn_to_inode(cvp);
491 d_instantiate(dentry, ip); 483 d_instantiate(dentry, ip);
492 xfs_validate_fields(dir, &vattr); 484 xfs_validate_fields(dir, &va);
493 xfs_validate_fields(ip, &vattr); 485 xfs_validate_fields(ip, &va);
494 } else { 486 } else {
495 xfs_cleanup_inode(dvp, cvp, dentry, 0); 487 xfs_cleanup_inode(dvp, cvp, dentry, 0);
496 } 488 }
@@ -504,11 +496,11 @@ xfs_vn_rmdir(
504 struct dentry *dentry) 496 struct dentry *dentry)
505{ 497{
506 struct inode *inode = dentry->d_inode; 498 struct inode *inode = dentry->d_inode;
507 vnode_t *dvp = vn_from_inode(dir); 499 bhv_vnode_t *dvp = vn_from_inode(dir);
508 vattr_t vattr; 500 bhv_vattr_t vattr;
509 int error; 501 int error;
510 502
511 VOP_RMDIR(dvp, dentry, NULL, error); 503 error = bhv_vop_rmdir(dvp, dentry, NULL);
512 if (likely(!error)) { 504 if (likely(!error)) {
513 xfs_validate_fields(inode, &vattr); 505 xfs_validate_fields(inode, &vattr);
514 xfs_validate_fields(dir, &vattr); 506 xfs_validate_fields(dir, &vattr);
@@ -524,15 +516,15 @@ xfs_vn_rename(
524 struct dentry *ndentry) 516 struct dentry *ndentry)
525{ 517{
526 struct inode *new_inode = ndentry->d_inode; 518 struct inode *new_inode = ndentry->d_inode;
527 vnode_t *fvp; /* from directory */ 519 bhv_vnode_t *fvp; /* from directory */
528 vnode_t *tvp; /* target directory */ 520 bhv_vnode_t *tvp; /* target directory */
529 vattr_t vattr; 521 bhv_vattr_t vattr;
530 int error; 522 int error;
531 523
532 fvp = vn_from_inode(odir); 524 fvp = vn_from_inode(odir);
533 tvp = vn_from_inode(ndir); 525 tvp = vn_from_inode(ndir);
534 526
535 VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error); 527 error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL);
536 if (likely(!error)) { 528 if (likely(!error)) {
537 if (new_inode) 529 if (new_inode)
538 xfs_validate_fields(new_inode, &vattr); 530 xfs_validate_fields(new_inode, &vattr);
@@ -553,7 +545,7 @@ xfs_vn_follow_link(
553 struct dentry *dentry, 545 struct dentry *dentry,
554 struct nameidata *nd) 546 struct nameidata *nd)
555{ 547{
556 vnode_t *vp; 548 bhv_vnode_t *vp;
557 uio_t *uio; 549 uio_t *uio;
558 iovec_t iov; 550 iovec_t iov;
559 int error; 551 int error;
@@ -586,8 +578,8 @@ xfs_vn_follow_link(
586 uio->uio_resid = MAXPATHLEN; 578 uio->uio_resid = MAXPATHLEN;
587 uio->uio_iovcnt = 1; 579 uio->uio_iovcnt = 1;
588 580
589 VOP_READLINK(vp, uio, 0, NULL, error); 581 error = bhv_vop_readlink(vp, uio, 0, NULL);
590 if (error) { 582 if (unlikely(error)) {
591 kfree(link); 583 kfree(link);
592 link = ERR_PTR(-error); 584 link = ERR_PTR(-error);
593 } else { 585 } else {
@@ -618,12 +610,7 @@ xfs_vn_permission(
618 int mode, 610 int mode,
619 struct nameidata *nd) 611 struct nameidata *nd)
620{ 612{
621 vnode_t *vp = vn_from_inode(inode); 613 return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
622 int error;
623
624 mode <<= 6; /* convert from linux to vnode access bits */
625 VOP_ACCESS(vp, mode, NULL, error);
626 return -error;
627} 614}
628#else 615#else
629#define xfs_vn_permission NULL 616#define xfs_vn_permission NULL
@@ -636,14 +623,14 @@ xfs_vn_getattr(
636 struct kstat *stat) 623 struct kstat *stat)
637{ 624{
638 struct inode *inode = dentry->d_inode; 625 struct inode *inode = dentry->d_inode;
639 vnode_t *vp = vn_from_inode(inode); 626 bhv_vnode_t *vp = vn_from_inode(inode);
640 int error = 0; 627 int error = 0;
641 628
642 if (unlikely(vp->v_flag & VMODIFIED)) 629 if (unlikely(vp->v_flag & VMODIFIED))
643 error = vn_revalidate(vp); 630 error = vn_revalidate(vp);
644 if (!error) 631 if (!error)
645 generic_fillattr(inode, stat); 632 generic_fillattr(inode, stat);
646 return 0; 633 return -error;
647} 634}
648 635
649STATIC int 636STATIC int
@@ -653,8 +640,8 @@ xfs_vn_setattr(
653{ 640{
654 struct inode *inode = dentry->d_inode; 641 struct inode *inode = dentry->d_inode;
655 unsigned int ia_valid = attr->ia_valid; 642 unsigned int ia_valid = attr->ia_valid;
656 vnode_t *vp = vn_from_inode(inode); 643 bhv_vnode_t *vp = vn_from_inode(inode);
657 vattr_t vattr = { 0 }; 644 bhv_vattr_t vattr = { 0 };
658 int flags = 0; 645 int flags = 0;
659 int error; 646 int error;
660 647
@@ -697,7 +684,7 @@ xfs_vn_setattr(
697 flags |= ATTR_NONBLOCK; 684 flags |= ATTR_NONBLOCK;
698#endif 685#endif
699 686
700 VOP_SETATTR(vp, &vattr, flags, NULL, error); 687 error = bhv_vop_setattr(vp, &vattr, flags, NULL);
701 if (likely(!error)) 688 if (likely(!error))
702 __vn_revalidate(vp, &vattr); 689 __vn_revalidate(vp, &vattr);
703 return -error; 690 return -error;
@@ -718,7 +705,7 @@ xfs_vn_setxattr(
718 size_t size, 705 size_t size,
719 int flags) 706 int flags)
720{ 707{
721 vnode_t *vp = vn_from_inode(dentry->d_inode); 708 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
722 char *attr = (char *)name; 709 char *attr = (char *)name;
723 attrnames_t *namesp; 710 attrnames_t *namesp;
724 int xflags = 0; 711 int xflags = 0;
@@ -748,7 +735,7 @@ xfs_vn_getxattr(
748 void *data, 735 void *data,
749 size_t size) 736 size_t size)
750{ 737{
751 vnode_t *vp = vn_from_inode(dentry->d_inode); 738 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
752 char *attr = (char *)name; 739 char *attr = (char *)name;
753 attrnames_t *namesp; 740 attrnames_t *namesp;
754 int xflags = 0; 741 int xflags = 0;
@@ -777,7 +764,7 @@ xfs_vn_listxattr(
777 char *data, 764 char *data,
778 size_t size) 765 size_t size)
779{ 766{
780 vnode_t *vp = vn_from_inode(dentry->d_inode); 767 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
781 int error, xflags = ATTR_KERNAMELS; 768 int error, xflags = ATTR_KERNAMELS;
782 ssize_t result; 769 ssize_t result;
783 770
@@ -796,7 +783,7 @@ xfs_vn_removexattr(
796 struct dentry *dentry, 783 struct dentry *dentry,
797 const char *name) 784 const char *name)
798{ 785{
799 vnode_t *vp = vn_from_inode(dentry->d_inode); 786 bhv_vnode_t *vp = vn_from_inode(dentry->d_inode);
800 char *attr = (char *)name; 787 char *attr = (char *)name;
801 attrnames_t *namesp; 788 attrnames_t *namesp;
802 int xflags = 0; 789 int xflags = 0;
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index e9fe43d74768..aa26ab906c88 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten);
134#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val 134#define xfs_buf_age_centisecs xfs_params.xfs_buf_age.val
135#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val 135#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
136#define xfs_rotorstep xfs_params.rotorstep.val 136#define xfs_rotorstep xfs_params.rotorstep.val
137#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
137 138
138#ifndef raw_smp_processor_id 139#define current_cpu() (raw_smp_processor_id())
139#define raw_smp_processor_id() smp_processor_id()
140#endif
141#define current_cpu() raw_smp_processor_id()
142#define current_pid() (current->pid) 140#define current_pid() (current->pid)
143#define current_fsuid(cred) (current->fsuid) 141#define current_fsuid(cred) (current->fsuid)
144#define current_fsgid(cred) (current->fsgid) 142#define current_fsgid(cred) (current->fsgid)
143#define current_set_flags(f) (current->flags |= (f))
144#define current_test_flags(f) (current->flags & (f))
145#define current_clear_flags(f) (current->flags & ~(f))
146#define current_set_flags_nested(sp, f) \
147 (*(sp) = current->flags, current->flags |= (f))
148#define current_clear_flags_nested(sp, f) \
149 (*(sp) = current->flags, current->flags &= ~(f))
150#define current_restore_flags_nested(sp, f) \
151 (current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
145 152
146#define NBPP PAGE_SIZE 153#define NBPP PAGE_SIZE
147#define DPPSHFT (PAGE_SHIFT - 9) 154#define DPPSHFT (PAGE_SHIFT - 9)
@@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten);
187/* bytes to clicks */ 194/* bytes to clicks */
188#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) 195#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
189 196
190#ifndef ENOATTR
191#define ENOATTR ENODATA /* Attribute not found */ 197#define ENOATTR ENODATA /* Attribute not found */
192#endif 198#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
193 199#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
194/* Note: EWRONGFS never visible outside the kernel */
195#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
196
197/*
198 * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
199 * return codes out of its known range in errno.
200 * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
201 * conflict with any code we use already or any code a driver may use)
202 * XXX Some options (currently we do #2):
203 * 1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
204 * 2/ 990 ["Unknown error 990"]
205 * 3/ EUCLEAN ["Structure needs cleaning"]
206 * 4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
207 */
208#define EFSCORRUPTED 990 /* Filesystem is corrupted */
209 200
210#define SYNCHRONIZE() barrier() 201#define SYNCHRONIZE() barrier()
211#define __return_address __builtin_return_address(0) 202#define __return_address __builtin_return_address(0)
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 67efe3308980..5d9cfd91ad08 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -206,7 +204,7 @@ xfs_read(
206 xfs_fsize_t n; 204 xfs_fsize_t n;
207 xfs_inode_t *ip; 205 xfs_inode_t *ip;
208 xfs_mount_t *mp; 206 xfs_mount_t *mp;
209 vnode_t *vp; 207 bhv_vnode_t *vp;
210 unsigned long seg; 208 unsigned long seg;
211 209
212 ip = XFS_BHVTOI(bdp); 210 ip = XFS_BHVTOI(bdp);
@@ -258,7 +256,7 @@ xfs_read(
258 256
259 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 257 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
260 !(ioflags & IO_INVIS)) { 258 !(ioflags & IO_INVIS)) {
261 vrwlock_t locktype = VRWLOCK_READ; 259 bhv_vrwlock_t locktype = VRWLOCK_READ;
262 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); 260 int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
263 261
264 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, 262 ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
@@ -271,7 +269,7 @@ xfs_read(
271 } 269 }
272 270
273 if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) 271 if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
274 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)), 272 bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
275 -1, FI_REMAPF_LOCKED); 273 -1, FI_REMAPF_LOCKED);
276 274
277 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, 275 xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
@@ -313,7 +311,7 @@ xfs_sendfile(
313 311
314 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && 312 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
315 (!(ioflags & IO_INVIS))) { 313 (!(ioflags & IO_INVIS))) {
316 vrwlock_t locktype = VRWLOCK_READ; 314 bhv_vrwlock_t locktype = VRWLOCK_READ;
317 int error; 315 int error;
318 316
319 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 317 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -357,7 +355,7 @@ xfs_splice_read(
357 355
358 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) && 356 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
359 (!(ioflags & IO_INVIS))) { 357 (!(ioflags & IO_INVIS))) {
360 vrwlock_t locktype = VRWLOCK_READ; 358 bhv_vrwlock_t locktype = VRWLOCK_READ;
361 int error; 359 int error;
362 360
363 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), 361 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -401,7 +399,7 @@ xfs_splice_write(
401 399
402 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) && 400 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
403 (!(ioflags & IO_INVIS))) { 401 (!(ioflags & IO_INVIS))) {
404 vrwlock_t locktype = VRWLOCK_WRITE; 402 bhv_vrwlock_t locktype = VRWLOCK_WRITE;
405 int error; 403 int error;
406 404
407 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp), 405 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
@@ -458,7 +456,7 @@ xfs_zero_last_block(
458 last_fsb = XFS_B_TO_FSBT(mp, isize); 456 last_fsb = XFS_B_TO_FSBT(mp, isize);
459 nimaps = 1; 457 nimaps = 1;
460 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap, 458 error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
461 &nimaps, NULL); 459 &nimaps, NULL, NULL);
462 if (error) { 460 if (error) {
463 return error; 461 return error;
464 } 462 }
@@ -499,7 +497,7 @@ xfs_zero_last_block(
499 497
500int /* error (positive) */ 498int /* error (positive) */
501xfs_zero_eof( 499xfs_zero_eof(
502 vnode_t *vp, 500 bhv_vnode_t *vp,
503 xfs_iocore_t *io, 501 xfs_iocore_t *io,
504 xfs_off_t offset, /* starting I/O offset */ 502 xfs_off_t offset, /* starting I/O offset */
505 xfs_fsize_t isize, /* current inode size */ 503 xfs_fsize_t isize, /* current inode size */
@@ -510,7 +508,6 @@ xfs_zero_eof(
510 xfs_fileoff_t end_zero_fsb; 508 xfs_fileoff_t end_zero_fsb;
511 xfs_fileoff_t zero_count_fsb; 509 xfs_fileoff_t zero_count_fsb;
512 xfs_fileoff_t last_fsb; 510 xfs_fileoff_t last_fsb;
513 xfs_extlen_t buf_len_fsb;
514 xfs_mount_t *mp = io->io_mount; 511 xfs_mount_t *mp = io->io_mount;
515 int nimaps; 512 int nimaps;
516 int error = 0; 513 int error = 0;
@@ -556,7 +553,7 @@ xfs_zero_eof(
556 nimaps = 1; 553 nimaps = 1;
557 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1; 554 zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
558 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb, 555 error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
559 0, NULL, 0, &imap, &nimaps, NULL); 556 0, NULL, 0, &imap, &nimaps, NULL, NULL);
560 if (error) { 557 if (error) {
561 ASSERT(ismrlocked(io->io_lock, MR_UPDATE)); 558 ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
562 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 559 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -579,16 +576,7 @@ xfs_zero_eof(
579 } 576 }
580 577
581 /* 578 /*
582 * There are blocks in the range requested. 579 * There are blocks we need to zero.
583 * Zero them a single write at a time. We actually
584 * don't zero the entire range returned if it is
585 * too big and simply loop around to get the rest.
586 * That is not the most efficient thing to do, but it
587 * is simple and this path should not be exercised often.
588 */
589 buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount,
590 mp->m_writeio_blocks << 8);
591 /*
592 * Drop the inode lock while we're doing the I/O. 580 * Drop the inode lock while we're doing the I/O.
593 * We'll still have the iolock to protect us. 581 * We'll still have the iolock to protect us.
594 */ 582 */
@@ -596,14 +584,13 @@ xfs_zero_eof(
596 584
597 error = xfs_iozero(ip, 585 error = xfs_iozero(ip,
598 XFS_FSB_TO_B(mp, start_zero_fsb), 586 XFS_FSB_TO_B(mp, start_zero_fsb),
599 XFS_FSB_TO_B(mp, buf_len_fsb), 587 XFS_FSB_TO_B(mp, imap.br_blockcount),
600 end_size); 588 end_size);
601
602 if (error) { 589 if (error) {
603 goto out_lock; 590 goto out_lock;
604 } 591 }
605 592
606 start_zero_fsb = imap.br_startoff + buf_len_fsb; 593 start_zero_fsb = imap.br_startoff + imap.br_blockcount;
607 ASSERT(start_zero_fsb <= (end_zero_fsb + 1)); 594 ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
608 595
609 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 596 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@@ -637,11 +624,11 @@ xfs_write(
637 ssize_t ret = 0, error = 0; 624 ssize_t ret = 0, error = 0;
638 xfs_fsize_t isize, new_size; 625 xfs_fsize_t isize, new_size;
639 xfs_iocore_t *io; 626 xfs_iocore_t *io;
640 vnode_t *vp; 627 bhv_vnode_t *vp;
641 unsigned long seg; 628 unsigned long seg;
642 int iolock; 629 int iolock;
643 int eventsent = 0; 630 int eventsent = 0;
644 vrwlock_t locktype; 631 bhv_vrwlock_t locktype;
645 size_t ocount = 0, count; 632 size_t ocount = 0, count;
646 loff_t pos; 633 loff_t pos;
647 int need_i_mutex = 1, need_flush = 0; 634 int need_i_mutex = 1, need_flush = 0;
@@ -679,11 +666,11 @@ xfs_write(
679 io = &xip->i_iocore; 666 io = &xip->i_iocore;
680 mp = io->io_mount; 667 mp = io->io_mount;
681 668
669 vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
670
682 if (XFS_FORCED_SHUTDOWN(mp)) 671 if (XFS_FORCED_SHUTDOWN(mp))
683 return -EIO; 672 return -EIO;
684 673
685 fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
686
687 if (ioflags & IO_ISDIRECT) { 674 if (ioflags & IO_ISDIRECT) {
688 xfs_buftarg_t *target = 675 xfs_buftarg_t *target =
689 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? 676 (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@@ -814,7 +801,7 @@ retry:
814 if (need_flush) { 801 if (need_flush) {
815 xfs_inval_cached_trace(io, pos, -1, 802 xfs_inval_cached_trace(io, pos, -1,
816 ctooff(offtoct(pos)), -1); 803 ctooff(offtoct(pos)), -1);
817 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)), 804 bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
818 -1, FI_REMAPF_LOCKED); 805 -1, FI_REMAPF_LOCKED);
819 } 806 }
820 807
@@ -903,79 +890,9 @@ retry:
903 890
904 /* Handle various SYNC-type writes */ 891 /* Handle various SYNC-type writes */
905 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) { 892 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
906 /* 893 error = xfs_write_sync_logforce(mp, xip);
907 * If we're treating this as O_DSYNC and we have not updated the 894 if (error)
908 * size, force the log. 895 goto out_unlock_internal;
909 */
910 if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
911 !(xip->i_update_size)) {
912 xfs_inode_log_item_t *iip = xip->i_itemp;
913
914 /*
915 * If an allocation transaction occurred
916 * without extending the size, then we have to force
917 * the log up the proper point to ensure that the
918 * allocation is permanent. We can't count on
919 * the fact that buffered writes lock out direct I/O
920 * writes - the direct I/O write could have extended
921 * the size nontransactionally, then finished before
922 * we started. xfs_write_file will think that the file
923 * didn't grow but the update isn't safe unless the
924 * size change is logged.
925 *
926 * Force the log if we've committed a transaction
927 * against the inode or if someone else has and
928 * the commit record hasn't gone to disk (e.g.
929 * the inode is pinned). This guarantees that
930 * all changes affecting the inode are permanent
931 * when we return.
932 */
933 if (iip && iip->ili_last_lsn) {
934 xfs_log_force(mp, iip->ili_last_lsn,
935 XFS_LOG_FORCE | XFS_LOG_SYNC);
936 } else if (xfs_ipincount(xip) > 0) {
937 xfs_log_force(mp, (xfs_lsn_t)0,
938 XFS_LOG_FORCE | XFS_LOG_SYNC);
939 }
940
941 } else {
942 xfs_trans_t *tp;
943
944 /*
945 * O_SYNC or O_DSYNC _with_ a size update are handled
946 * the same way.
947 *
948 * If the write was synchronous then we need to make
949 * sure that the inode modification time is permanent.
950 * We'll have updated the timestamp above, so here
951 * we use a synchronous transaction to log the inode.
952 * It's not fast, but it's necessary.
953 *
954 * If this a dsync write and the size got changed
955 * non-transactionally, then we need to ensure that
956 * the size change gets logged in a synchronous
957 * transaction.
958 */
959
960 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
961 if ((error = xfs_trans_reserve(tp, 0,
962 XFS_SWRITE_LOG_RES(mp),
963 0, 0, 0))) {
964 /* Transaction reserve failed */
965 xfs_trans_cancel(tp, 0);
966 } else {
967 /* Transaction reserve successful */
968 xfs_ilock(xip, XFS_ILOCK_EXCL);
969 xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
970 xfs_trans_ihold(tp, xip);
971 xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
972 xfs_trans_set_sync(tp);
973 error = xfs_trans_commit(tp, 0, NULL);
974 xfs_iunlock(xip, XFS_ILOCK_EXCL);
975 }
976 if (error)
977 goto out_unlock_internal;
978 }
979 896
980 xfs_rwunlock(bdp, locktype); 897 xfs_rwunlock(bdp, locktype);
981 if (need_i_mutex) 898 if (need_i_mutex)
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 8f4539952350..c77e62efb742 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -18,8 +18,8 @@
18#ifndef __XFS_LRW_H__ 18#ifndef __XFS_LRW_H__
19#define __XFS_LRW_H__ 19#define __XFS_LRW_H__
20 20
21struct vnode;
22struct bhv_desc; 21struct bhv_desc;
22struct bhv_vnode;
23struct xfs_mount; 23struct xfs_mount;
24struct xfs_iocore; 24struct xfs_iocore;
25struct xfs_inode; 25struct xfs_inode;
@@ -49,7 +49,7 @@ struct xfs_iomap;
49#define XFS_CTRUNC4 14 49#define XFS_CTRUNC4 14
50#define XFS_CTRUNC5 15 50#define XFS_CTRUNC5 15
51#define XFS_CTRUNC6 16 51#define XFS_CTRUNC6 16
52#define XFS_BUNMAPI 17 52#define XFS_BUNMAP 17
53#define XFS_INVAL_CACHED 18 53#define XFS_INVAL_CACHED 18
54#define XFS_DIORD_ENTER 19 54#define XFS_DIORD_ENTER 19
55#define XFS_DIOWR_ENTER 20 55#define XFS_DIOWR_ENTER 20
@@ -82,7 +82,7 @@ extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
82extern int xfs_bdstrat_cb(struct xfs_buf *); 82extern int xfs_bdstrat_cb(struct xfs_buf *);
83extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 83extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
84 84
85extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, 85extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t,
86 xfs_fsize_t, xfs_fsize_t); 86 xfs_fsize_t, xfs_fsize_t);
87extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, 87extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
88 const struct iovec *, unsigned int, 88 const struct iovec *, unsigned int,
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c
index 1f0589a05eca..e480b6102051 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/linux-2.6/xfs_stats.c
@@ -62,7 +62,7 @@ xfs_read_xfsstats(
62 while (j < xstats[i].endpoint) { 62 while (j < xstats[i].endpoint) {
63 val = 0; 63 val = 0;
64 /* sum over all cpus */ 64 /* sum over all cpus */
65 for_each_cpu(c) 65 for_each_possible_cpu(c)
66 val += *(((__u32*)&per_cpu(xfsstats, c) + j)); 66 val += *(((__u32*)&per_cpu(xfsstats, c) + j));
67 len += sprintf(buffer + len, " %u", val); 67 len += sprintf(buffer + len, " %u", val);
68 j++; 68 j++;
@@ -70,7 +70,7 @@ xfs_read_xfsstats(
70 buffer[len++] = '\n'; 70 buffer[len++] = '\n';
71 } 71 }
72 /* extra precision counters */ 72 /* extra precision counters */
73 for_each_cpu(i) { 73 for_each_possible_cpu(i) {
74 xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes; 74 xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes;
75 xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes; 75 xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes;
76 xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; 76 xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 68f4793e8a11..9bdef9d51900 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-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -151,7 +149,7 @@ xfs_set_inodeops(
151STATIC __inline__ void 149STATIC __inline__ void
152xfs_revalidate_inode( 150xfs_revalidate_inode(
153 xfs_mount_t *mp, 151 xfs_mount_t *mp,
154 vnode_t *vp, 152 bhv_vnode_t *vp,
155 xfs_inode_t *ip) 153 xfs_inode_t *ip)
156{ 154{
157 struct inode *inode = vn_to_inode(vp); 155 struct inode *inode = vn_to_inode(vp);
@@ -206,7 +204,7 @@ xfs_revalidate_inode(
206void 204void
207xfs_initialize_vnode( 205xfs_initialize_vnode(
208 bhv_desc_t *bdp, 206 bhv_desc_t *bdp,
209 vnode_t *vp, 207 bhv_vnode_t *vp,
210 bhv_desc_t *inode_bhv, 208 bhv_desc_t *inode_bhv,
211 int unlock) 209 int unlock)
212{ 210{
@@ -336,7 +334,7 @@ STATIC struct inode *
336xfs_fs_alloc_inode( 334xfs_fs_alloc_inode(
337 struct super_block *sb) 335 struct super_block *sb)
338{ 336{
339 vnode_t *vp; 337 bhv_vnode_t *vp;
340 338
341 vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP); 339 vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
342 if (unlikely(!vp)) 340 if (unlikely(!vp))
@@ -359,13 +357,13 @@ xfs_fs_inode_init_once(
359{ 357{
360 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == 358 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
361 SLAB_CTOR_CONSTRUCTOR) 359 SLAB_CTOR_CONSTRUCTOR)
362 inode_init_once(vn_to_inode((vnode_t *)vnode)); 360 inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
363} 361}
364 362
365STATIC int 363STATIC int
366xfs_init_zones(void) 364xfs_init_zones(void)
367{ 365{
368 xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t", 366 xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
369 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | 367 KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
370 KM_ZONE_SPREAD, 368 KM_ZONE_SPREAD,
371 xfs_fs_inode_init_once); 369 xfs_fs_inode_init_once);
@@ -409,22 +407,17 @@ xfs_fs_write_inode(
409 struct inode *inode, 407 struct inode *inode,
410 int sync) 408 int sync)
411{ 409{
412 vnode_t *vp = vn_from_inode(inode); 410 bhv_vnode_t *vp = vn_from_inode(inode);
413 int error = 0, flags = FLUSH_INODE; 411 int error = 0, flags = FLUSH_INODE;
414 412
415 if (vp) { 413 if (vp) {
416 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 414 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
417 if (sync) 415 if (sync)
418 flags |= FLUSH_SYNC; 416 flags |= FLUSH_SYNC;
419 VOP_IFLUSH(vp, flags, error); 417 error = bhv_vop_iflush(vp, flags);
420 if (error == EAGAIN) { 418 if (error == EAGAIN)
421 if (sync) 419 error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
422 VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
423 else
424 error = 0;
425 }
426 } 420 }
427
428 return -error; 421 return -error;
429} 422}
430 423
@@ -432,8 +425,7 @@ STATIC void
432xfs_fs_clear_inode( 425xfs_fs_clear_inode(
433 struct inode *inode) 426 struct inode *inode)
434{ 427{
435 vnode_t *vp = vn_from_inode(inode); 428 bhv_vnode_t *vp = vn_from_inode(inode);
436 int error, cache;
437 429
438 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 430 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
439 431
@@ -446,20 +438,18 @@ xfs_fs_clear_inode(
446 * This can happen because xfs_iget_core calls xfs_idestroy if we 438 * This can happen because xfs_iget_core calls xfs_idestroy if we
447 * find an inode with di_mode == 0 but without IGET_CREATE set. 439 * find an inode with di_mode == 0 but without IGET_CREATE set.
448 */ 440 */
449 if (vp->v_fbhv) 441 if (VNHEAD(vp))
450 VOP_INACTIVE(vp, NULL, cache); 442 bhv_vop_inactive(vp, NULL);
451 443
452 VN_LOCK(vp); 444 VN_LOCK(vp);
453 vp->v_flag &= ~VMODIFIED; 445 vp->v_flag &= ~VMODIFIED;
454 VN_UNLOCK(vp, 0); 446 VN_UNLOCK(vp, 0);
455 447
456 if (vp->v_fbhv) { 448 if (VNHEAD(vp))
457 VOP_RECLAIM(vp, error); 449 if (bhv_vop_reclaim(vp))
458 if (error) 450 panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp);
459 panic("vn_purge: cannot reclaim");
460 }
461 451
462 ASSERT(vp->v_fbhv == NULL); 452 ASSERT(VNHEAD(vp) == NULL);
463 453
464#ifdef XFS_VNODE_TRACE 454#ifdef XFS_VNODE_TRACE
465 ktrace_free(vp->v_trace); 455 ktrace_free(vp->v_trace);
@@ -475,13 +465,13 @@ xfs_fs_clear_inode(
475 */ 465 */
476STATIC void 466STATIC void
477xfs_syncd_queue_work( 467xfs_syncd_queue_work(
478 struct vfs *vfs, 468 struct bhv_vfs *vfs,
479 void *data, 469 void *data,
480 void (*syncer)(vfs_t *, void *)) 470 void (*syncer)(bhv_vfs_t *, void *))
481{ 471{
482 vfs_sync_work_t *work; 472 struct bhv_vfs_sync_work *work;
483 473
484 work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP); 474 work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP);
485 INIT_LIST_HEAD(&work->w_list); 475 INIT_LIST_HEAD(&work->w_list);
486 work->w_syncer = syncer; 476 work->w_syncer = syncer;
487 work->w_data = data; 477 work->w_data = data;
@@ -500,7 +490,7 @@ xfs_syncd_queue_work(
500 */ 490 */
501STATIC void 491STATIC void
502xfs_flush_inode_work( 492xfs_flush_inode_work(
503 vfs_t *vfs, 493 bhv_vfs_t *vfs,
504 void *inode) 494 void *inode)
505{ 495{
506 filemap_flush(((struct inode *)inode)->i_mapping); 496 filemap_flush(((struct inode *)inode)->i_mapping);
@@ -512,7 +502,7 @@ xfs_flush_inode(
512 xfs_inode_t *ip) 502 xfs_inode_t *ip)
513{ 503{
514 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 504 struct inode *inode = vn_to_inode(XFS_ITOV(ip));
515 struct vfs *vfs = XFS_MTOVFS(ip->i_mount); 505 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
516 506
517 igrab(inode); 507 igrab(inode);
518 xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work); 508 xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
@@ -525,7 +515,7 @@ xfs_flush_inode(
525 */ 515 */
526STATIC void 516STATIC void
527xfs_flush_device_work( 517xfs_flush_device_work(
528 vfs_t *vfs, 518 bhv_vfs_t *vfs,
529 void *inode) 519 void *inode)
530{ 520{
531 sync_blockdev(vfs->vfs_super->s_bdev); 521 sync_blockdev(vfs->vfs_super->s_bdev);
@@ -537,7 +527,7 @@ xfs_flush_device(
537 xfs_inode_t *ip) 527 xfs_inode_t *ip)
538{ 528{
539 struct inode *inode = vn_to_inode(XFS_ITOV(ip)); 529 struct inode *inode = vn_to_inode(XFS_ITOV(ip));
540 struct vfs *vfs = XFS_MTOVFS(ip->i_mount); 530 struct bhv_vfs *vfs = XFS_MTOVFS(ip->i_mount);
541 531
542 igrab(inode); 532 igrab(inode);
543 xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work); 533 xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
@@ -545,16 +535,16 @@ xfs_flush_device(
545 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC); 535 xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
546} 536}
547 537
548#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
549STATIC void 538STATIC void
550vfs_sync_worker( 539vfs_sync_worker(
551 vfs_t *vfsp, 540 bhv_vfs_t *vfsp,
552 void *unused) 541 void *unused)
553{ 542{
554 int error; 543 int error;
555 544
556 if (!(vfsp->vfs_flag & VFS_RDONLY)) 545 if (!(vfsp->vfs_flag & VFS_RDONLY))
557 VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error); 546 error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
547 SYNC_ATTR | SYNC_REFCACHE, NULL);
558 vfsp->vfs_sync_seq++; 548 vfsp->vfs_sync_seq++;
559 wmb(); 549 wmb();
560 wake_up(&vfsp->vfs_wait_single_sync_task); 550 wake_up(&vfsp->vfs_wait_single_sync_task);
@@ -565,8 +555,8 @@ xfssyncd(
565 void *arg) 555 void *arg)
566{ 556{
567 long timeleft; 557 long timeleft;
568 vfs_t *vfsp = (vfs_t *) arg; 558 bhv_vfs_t *vfsp = (bhv_vfs_t *) arg;
569 struct vfs_sync_work *work, *n; 559 bhv_vfs_sync_work_t *work, *n;
570 LIST_HEAD (tmp); 560 LIST_HEAD (tmp);
571 561
572 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10); 562 timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
@@ -600,7 +590,7 @@ xfssyncd(
600 list_del(&work->w_list); 590 list_del(&work->w_list);
601 if (work == &vfsp->vfs_sync_work) 591 if (work == &vfsp->vfs_sync_work)
602 continue; 592 continue;
603 kmem_free(work, sizeof(struct vfs_sync_work)); 593 kmem_free(work, sizeof(struct bhv_vfs_sync_work));
604 } 594 }
605 } 595 }
606 596
@@ -609,7 +599,7 @@ xfssyncd(
609 599
610STATIC int 600STATIC int
611xfs_fs_start_syncd( 601xfs_fs_start_syncd(
612 vfs_t *vfsp) 602 bhv_vfs_t *vfsp)
613{ 603{
614 vfsp->vfs_sync_work.w_syncer = vfs_sync_worker; 604 vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
615 vfsp->vfs_sync_work.w_vfs = vfsp; 605 vfsp->vfs_sync_work.w_vfs = vfsp;
@@ -621,7 +611,7 @@ xfs_fs_start_syncd(
621 611
622STATIC void 612STATIC void
623xfs_fs_stop_syncd( 613xfs_fs_stop_syncd(
624 vfs_t *vfsp) 614 bhv_vfs_t *vfsp)
625{ 615{
626 kthread_stop(vfsp->vfs_sync_task); 616 kthread_stop(vfsp->vfs_sync_task);
627} 617}
@@ -630,35 +620,26 @@ STATIC void
630xfs_fs_put_super( 620xfs_fs_put_super(
631 struct super_block *sb) 621 struct super_block *sb)
632{ 622{
633 vfs_t *vfsp = vfs_from_sb(sb); 623 bhv_vfs_t *vfsp = vfs_from_sb(sb);
634 int error; 624 int error;
635 625
636 xfs_fs_stop_syncd(vfsp); 626 xfs_fs_stop_syncd(vfsp);
637 VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error); 627 bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL);
638 if (!error) 628 error = bhv_vfs_unmount(vfsp, 0, NULL);
639 VFS_UNMOUNT(vfsp, 0, NULL, error);
640 if (error) { 629 if (error) {
641 printk("XFS unmount got error %d\n", error); 630 printk("XFS: unmount got error=%d\n", error);
642 printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp); 631 printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
643 return; 632 } else {
633 vfs_deallocate(vfsp);
644 } 634 }
645
646 vfs_deallocate(vfsp);
647} 635}
648 636
649STATIC void 637STATIC void
650xfs_fs_write_super( 638xfs_fs_write_super(
651 struct super_block *sb) 639 struct super_block *sb)
652{ 640{
653 vfs_t *vfsp = vfs_from_sb(sb); 641 if (!(sb->s_flags & MS_RDONLY))
654 int error; 642 bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL);
655
656 if (sb->s_flags & MS_RDONLY) {
657 sb->s_dirt = 0; /* paranoia */
658 return;
659 }
660 /* Push the log and superblock a little */
661 VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
662 sb->s_dirt = 0; 643 sb->s_dirt = 0;
663} 644}
664 645
@@ -667,16 +648,16 @@ xfs_fs_sync_super(
667 struct super_block *sb, 648 struct super_block *sb,
668 int wait) 649 int wait)
669{ 650{
670 vfs_t *vfsp = vfs_from_sb(sb); 651 bhv_vfs_t *vfsp = vfs_from_sb(sb);
671 int error; 652 int error;
672 int flags = SYNC_FSDATA; 653 int flags;
673 654
674 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) 655 if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
675 flags = SYNC_QUIESCE; 656 flags = SYNC_QUIESCE;
676 else 657 else
677 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); 658 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
678 659
679 VFS_SYNC(vfsp, flags, NULL, error); 660 error = bhv_vfs_sync(vfsp, flags, NULL);
680 sb->s_dirt = 0; 661 sb->s_dirt = 0;
681 662
682 if (unlikely(laptop_mode)) { 663 if (unlikely(laptop_mode)) {
@@ -703,14 +684,11 @@ xfs_fs_sync_super(
703 684
704STATIC int 685STATIC int
705xfs_fs_statfs( 686xfs_fs_statfs(
706 struct super_block *sb, 687 struct dentry *dentry,
707 struct kstatfs *statp) 688 struct kstatfs *statp)
708{ 689{
709 vfs_t *vfsp = vfs_from_sb(sb); 690 return -bhv_vfs_statvfs(vfs_from_sb(dentry->d_sb), statp,
710 int error; 691 vn_from_inode(dentry->d_inode));
711
712 VFS_STATVFS(vfsp, statp, NULL, error);
713 return -error;
714} 692}
715 693
716STATIC int 694STATIC int
@@ -719,13 +697,13 @@ xfs_fs_remount(
719 int *flags, 697 int *flags,
720 char *options) 698 char *options)
721{ 699{
722 vfs_t *vfsp = vfs_from_sb(sb); 700 bhv_vfs_t *vfsp = vfs_from_sb(sb);
723 struct xfs_mount_args *args = xfs_args_allocate(sb, 0); 701 struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
724 int error; 702 int error;
725 703
726 VFS_PARSEARGS(vfsp, options, args, 1, error); 704 error = bhv_vfs_parseargs(vfsp, options, args, 1);
727 if (!error) 705 if (!error)
728 VFS_MNTUPDATE(vfsp, flags, args, error); 706 error = bhv_vfs_mntupdate(vfsp, flags, args);
729 kmem_free(args, sizeof(*args)); 707 kmem_free(args, sizeof(*args));
730 return -error; 708 return -error;
731} 709}
@@ -734,7 +712,7 @@ STATIC void
734xfs_fs_lockfs( 712xfs_fs_lockfs(
735 struct super_block *sb) 713 struct super_block *sb)
736{ 714{
737 VFS_FREEZE(vfs_from_sb(sb)); 715 bhv_vfs_freeze(vfs_from_sb(sb));
738} 716}
739 717
740STATIC int 718STATIC int
@@ -742,11 +720,7 @@ xfs_fs_show_options(
742 struct seq_file *m, 720 struct seq_file *m,
743 struct vfsmount *mnt) 721 struct vfsmount *mnt)
744{ 722{
745 struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb); 723 return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m);
746 int error;
747
748 VFS_SHOWARGS(vfsp, m, error);
749 return error;
750} 724}
751 725
752STATIC int 726STATIC int
@@ -754,11 +728,7 @@ xfs_fs_quotasync(
754 struct super_block *sb, 728 struct super_block *sb,
755 int type) 729 int type)
756{ 730{
757 struct vfs *vfsp = vfs_from_sb(sb); 731 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
758 int error;
759
760 VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
761 return -error;
762} 732}
763 733
764STATIC int 734STATIC int
@@ -766,11 +736,7 @@ xfs_fs_getxstate(
766 struct super_block *sb, 736 struct super_block *sb,
767 struct fs_quota_stat *fqs) 737 struct fs_quota_stat *fqs)
768{ 738{
769 struct vfs *vfsp = vfs_from_sb(sb); 739 return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
770 int error;
771
772 VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
773 return -error;
774} 740}
775 741
776STATIC int 742STATIC int
@@ -779,11 +745,7 @@ xfs_fs_setxstate(
779 unsigned int flags, 745 unsigned int flags,
780 int op) 746 int op)
781{ 747{
782 struct vfs *vfsp = vfs_from_sb(sb); 748 return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
783 int error;
784
785 VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
786 return -error;
787} 749}
788 750
789STATIC int 751STATIC int
@@ -793,13 +755,10 @@ xfs_fs_getxquota(
793 qid_t id, 755 qid_t id,
794 struct fs_disk_quota *fdq) 756 struct fs_disk_quota *fdq)
795{ 757{
796 struct vfs *vfsp = vfs_from_sb(sb); 758 return -bhv_vfs_quotactl(vfs_from_sb(sb),
797 int error, getmode; 759 (type == USRQUOTA) ? Q_XGETQUOTA :
798 760 ((type == GRPQUOTA) ? Q_XGETGQUOTA :
799 getmode = (type == USRQUOTA) ? Q_XGETQUOTA : 761 Q_XGETPQUOTA), id, (caddr_t)fdq);
800 ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
801 VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
802 return -error;
803} 762}
804 763
805STATIC int 764STATIC int
@@ -809,13 +768,10 @@ xfs_fs_setxquota(
809 qid_t id, 768 qid_t id,
810 struct fs_disk_quota *fdq) 769 struct fs_disk_quota *fdq)
811{ 770{
812 struct vfs *vfsp = vfs_from_sb(sb); 771 return -bhv_vfs_quotactl(vfs_from_sb(sb),
813 int error, setmode; 772 (type == USRQUOTA) ? Q_XSETQLIM :
814 773 ((type == GRPQUOTA) ? Q_XSETGQLIM :
815 setmode = (type == USRQUOTA) ? Q_XSETQLIM : 774 Q_XSETPQLIM), id, (caddr_t)fdq);
816 ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
817 VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
818 return -error;
819} 775}
820 776
821STATIC int 777STATIC int
@@ -824,34 +780,32 @@ xfs_fs_fill_super(
824 void *data, 780 void *data,
825 int silent) 781 int silent)
826{ 782{
827 vnode_t *rootvp; 783 struct bhv_vnode *rootvp;
828 struct vfs *vfsp = vfs_allocate(sb); 784 struct bhv_vfs *vfsp = vfs_allocate(sb);
829 struct xfs_mount_args *args = xfs_args_allocate(sb, silent); 785 struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
830 struct kstatfs statvfs; 786 struct kstatfs statvfs;
831 int error, error2; 787 int error;
832 788
833 bhv_insert_all_vfsops(vfsp); 789 bhv_insert_all_vfsops(vfsp);
834 790
835 VFS_PARSEARGS(vfsp, (char *)data, args, 0, error); 791 error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0);
836 if (error) { 792 if (error) {
837 bhv_remove_all_vfsops(vfsp, 1); 793 bhv_remove_all_vfsops(vfsp, 1);
838 goto fail_vfsop; 794 goto fail_vfsop;
839 } 795 }
840 796
841 sb_min_blocksize(sb, BBSIZE); 797 sb_min_blocksize(sb, BBSIZE);
842#ifdef CONFIG_XFS_EXPORT
843 sb->s_export_op = &xfs_export_operations; 798 sb->s_export_op = &xfs_export_operations;
844#endif
845 sb->s_qcop = &xfs_quotactl_operations; 799 sb->s_qcop = &xfs_quotactl_operations;
846 sb->s_op = &xfs_super_operations; 800 sb->s_op = &xfs_super_operations;
847 801
848 VFS_MOUNT(vfsp, args, NULL, error); 802 error = bhv_vfs_mount(vfsp, args, NULL);
849 if (error) { 803 if (error) {
850 bhv_remove_all_vfsops(vfsp, 1); 804 bhv_remove_all_vfsops(vfsp, 1);
851 goto fail_vfsop; 805 goto fail_vfsop;
852 } 806 }
853 807
854 VFS_STATVFS(vfsp, &statvfs, NULL, error); 808 error = bhv_vfs_statvfs(vfsp, &statvfs, NULL);
855 if (error) 809 if (error)
856 goto fail_unmount; 810 goto fail_unmount;
857 811
@@ -863,7 +817,7 @@ xfs_fs_fill_super(
863 sb->s_time_gran = 1; 817 sb->s_time_gran = 1;
864 set_posix_acl_flag(sb); 818 set_posix_acl_flag(sb);
865 819
866 VFS_ROOT(vfsp, &rootvp, error); 820 error = bhv_vfs_root(vfsp, &rootvp);
867 if (error) 821 if (error)
868 goto fail_unmount; 822 goto fail_unmount;
869 823
@@ -892,7 +846,7 @@ fail_vnrele:
892 } 846 }
893 847
894fail_unmount: 848fail_unmount:
895 VFS_UNMOUNT(vfsp, 0, NULL, error2); 849 bhv_vfs_unmount(vfsp, 0, NULL);
896 850
897fail_vfsop: 851fail_vfsop:
898 vfs_deallocate(vfsp); 852 vfs_deallocate(vfsp);
@@ -900,14 +854,16 @@ fail_vfsop:
900 return -error; 854 return -error;
901} 855}
902 856
903STATIC struct super_block * 857STATIC int
904xfs_fs_get_sb( 858xfs_fs_get_sb(
905 struct file_system_type *fs_type, 859 struct file_system_type *fs_type,
906 int flags, 860 int flags,
907 const char *dev_name, 861 const char *dev_name,
908 void *data) 862 void *data,
863 struct vfsmount *mnt)
909{ 864{
910 return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super); 865 return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super,
866 mnt);
911} 867}
912 868
913STATIC struct super_operations xfs_super_operations = { 869STATIC struct super_operations xfs_super_operations = {
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index 376b96cb513a..33dd1ca13245 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -105,7 +105,7 @@ struct block_device;
105 105
106extern __uint64_t xfs_max_file_offset(unsigned int); 106extern __uint64_t xfs_max_file_offset(unsigned int);
107 107
108extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int); 108extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int);
109 109
110extern void xfs_flush_inode(struct xfs_inode *); 110extern void xfs_flush_inode(struct xfs_inode *);
111extern void xfs_flush_device(struct xfs_inode *); 111extern void xfs_flush_device(struct xfs_inode *);
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index 7079cc837210..af246532fbfb 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -38,7 +38,7 @@ xfs_stats_clear_proc_handler(
38 38
39 if (!ret && write && *valp) { 39 if (!ret && write && *valp) {
40 printk("XFS Clearing xfsstats\n"); 40 printk("XFS Clearing xfsstats\n");
41 for_each_cpu(c) { 41 for_each_possible_cpu(c) {
42 preempt_disable(); 42 preempt_disable();
43 /* save vn_active, it's a universal truth! */ 43 /* save vn_active, it's a universal truth! */
44 vn_active = per_cpu(xfsstats, c).vn_active; 44 vn_active = per_cpu(xfsstats, c).vn_active;
@@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = {
120 &sysctl_intvec, NULL, 120 &sysctl_intvec, NULL,
121 &xfs_params.rotorstep.min, &xfs_params.rotorstep.max}, 121 &xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
122 122
123 {XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
124 sizeof(int), 0644, NULL, &proc_dointvec_minmax,
125 &sysctl_intvec, NULL,
126 &xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
127
123 /* please keep this the last entry */ 128 /* please keep this the last entry */
124#ifdef CONFIG_PROC_FS 129#ifdef CONFIG_PROC_FS
125 {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val, 130 {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/linux-2.6/xfs_sysctl.h
index bc8c11f13722..a631fb8cc5ac 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.h
+++ b/fs/xfs/linux-2.6/xfs_sysctl.h
@@ -46,6 +46,7 @@ typedef struct xfs_param {
46 xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */ 46 xfs_sysctl_val_t xfs_buf_age; /* Metadata buffer age before flush. */
47 xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */ 47 xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
48 xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ 48 xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
49 xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
49} xfs_param_t; 50} xfs_param_t;
50 51
51/* 52/*
@@ -84,6 +85,7 @@ enum {
84 /* XFS_IO_BYPASS = 18 */ 85 /* XFS_IO_BYPASS = 18 */
85 XFS_INHERIT_NOSYM = 19, 86 XFS_INHERIT_NOSYM = 19,
86 XFS_ROTORSTEP = 20, 87 XFS_ROTORSTEP = 20,
88 XFS_INHERIT_NODFRG = 21,
87}; 89};
88 90
89extern xfs_param_t xfs_params; 91extern xfs_param_t xfs_params;
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c
index 6f7c9f7a8624..6145e8bd0be2 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.c
+++ b/fs/xfs/linux-2.6/xfs_vfs.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_imap.h" 27#include "xfs_imap.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
@@ -104,7 +103,7 @@ vfs_mntupdate(
104int 103int
105vfs_root( 104vfs_root(
106 struct bhv_desc *bdp, 105 struct bhv_desc *bdp,
107 struct vnode **vpp) 106 struct bhv_vnode **vpp)
108{ 107{
109 struct bhv_desc *next = bdp; 108 struct bhv_desc *next = bdp;
110 109
@@ -117,15 +116,15 @@ vfs_root(
117int 116int
118vfs_statvfs( 117vfs_statvfs(
119 struct bhv_desc *bdp, 118 struct bhv_desc *bdp,
120 xfs_statfs_t *sp, 119 bhv_statvfs_t *statp,
121 struct vnode *vp) 120 struct bhv_vnode *vp)
122{ 121{
123 struct bhv_desc *next = bdp; 122 struct bhv_desc *next = bdp;
124 123
125 ASSERT(next); 124 ASSERT(next);
126 while (! (bhvtovfsops(next))->vfs_statvfs) 125 while (! (bhvtovfsops(next))->vfs_statvfs)
127 next = BHV_NEXT(next); 126 next = BHV_NEXT(next);
128 return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp)); 127 return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
129} 128}
130 129
131int 130int
@@ -145,7 +144,7 @@ vfs_sync(
145int 144int
146vfs_vget( 145vfs_vget(
147 struct bhv_desc *bdp, 146 struct bhv_desc *bdp,
148 struct vnode **vpp, 147 struct bhv_vnode **vpp,
149 struct fid *fidp) 148 struct fid *fidp)
150{ 149{
151 struct bhv_desc *next = bdp; 150 struct bhv_desc *next = bdp;
@@ -187,7 +186,7 @@ vfs_quotactl(
187void 186void
188vfs_init_vnode( 187vfs_init_vnode(
189 struct bhv_desc *bdp, 188 struct bhv_desc *bdp,
190 struct vnode *vp, 189 struct bhv_vnode *vp,
191 struct bhv_desc *bp, 190 struct bhv_desc *bp,
192 int unlock) 191 int unlock)
193{ 192{
@@ -226,13 +225,13 @@ vfs_freeze(
226 ((*bhvtovfsops(next)->vfs_freeze)(next)); 225 ((*bhvtovfsops(next)->vfs_freeze)(next));
227} 226}
228 227
229vfs_t * 228bhv_vfs_t *
230vfs_allocate( 229vfs_allocate(
231 struct super_block *sb) 230 struct super_block *sb)
232{ 231{
233 struct vfs *vfsp; 232 struct bhv_vfs *vfsp;
234 233
235 vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP); 234 vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
236 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs"); 235 bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
237 INIT_LIST_HEAD(&vfsp->vfs_sync_list); 236 INIT_LIST_HEAD(&vfsp->vfs_sync_list);
238 spin_lock_init(&vfsp->vfs_sync_lock); 237 spin_lock_init(&vfsp->vfs_sync_lock);
@@ -247,25 +246,25 @@ vfs_allocate(
247 return vfsp; 246 return vfsp;
248} 247}
249 248
250vfs_t * 249bhv_vfs_t *
251vfs_from_sb( 250vfs_from_sb(
252 struct super_block *sb) 251 struct super_block *sb)
253{ 252{
254 return (vfs_t *)sb->s_fs_info; 253 return (bhv_vfs_t *)sb->s_fs_info;
255} 254}
256 255
257void 256void
258vfs_deallocate( 257vfs_deallocate(
259 struct vfs *vfsp) 258 struct bhv_vfs *vfsp)
260{ 259{
261 bhv_head_destroy(VFS_BHVHEAD(vfsp)); 260 bhv_head_destroy(VFS_BHVHEAD(vfsp));
262 kmem_free(vfsp, sizeof(vfs_t)); 261 kmem_free(vfsp, sizeof(bhv_vfs_t));
263} 262}
264 263
265void 264void
266vfs_insertops( 265vfs_insertops(
267 struct vfs *vfsp, 266 struct bhv_vfs *vfsp,
268 struct bhv_vfsops *vfsops) 267 struct bhv_module_vfsops *vfsops)
269{ 268{
270 struct bhv_desc *bdp; 269 struct bhv_desc *bdp;
271 270
@@ -276,9 +275,9 @@ vfs_insertops(
276 275
277void 276void
278vfs_insertbhv( 277vfs_insertbhv(
279 struct vfs *vfsp, 278 struct bhv_vfs *vfsp,
280 struct bhv_desc *bdp, 279 struct bhv_desc *bdp,
281 struct vfsops *vfsops, 280 struct bhv_vfsops *vfsops,
282 void *mount) 281 void *mount)
283{ 282{
284 bhv_desc_init(bdp, mount, vfsp, vfsops); 283 bhv_desc_init(bdp, mount, vfsp, vfsops);
@@ -287,7 +286,7 @@ vfs_insertbhv(
287 286
288void 287void
289bhv_remove_vfsops( 288bhv_remove_vfsops(
290 struct vfs *vfsp, 289 struct bhv_vfs *vfsp,
291 int pos) 290 int pos)
292{ 291{
293 struct bhv_desc *bhv; 292 struct bhv_desc *bhv;
@@ -301,7 +300,7 @@ bhv_remove_vfsops(
301 300
302void 301void
303bhv_remove_all_vfsops( 302bhv_remove_all_vfsops(
304 struct vfs *vfsp, 303 struct bhv_vfs *vfsp,
305 int freebase) 304 int freebase)
306{ 305{
307 struct xfs_mount *mp; 306 struct xfs_mount *mp;
@@ -317,7 +316,7 @@ bhv_remove_all_vfsops(
317 316
318void 317void
319bhv_insert_all_vfsops( 318bhv_insert_all_vfsops(
320 struct vfs *vfsp) 319 struct bhv_vfs *vfsp)
321{ 320{
322 struct xfs_mount *mp; 321 struct xfs_mount *mp;
323 322
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 841200c03092..91fc2c4b3353 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -21,42 +21,40 @@
21#include <linux/vfs.h> 21#include <linux/vfs.h>
22#include "xfs_fs.h" 22#include "xfs_fs.h"
23 23
24struct bhv_vfs;
25struct bhv_vnode;
26
24struct fid; 27struct fid;
25struct vfs;
26struct cred; 28struct cred;
27struct vnode;
28struct kstatfs;
29struct seq_file; 29struct seq_file;
30struct super_block; 30struct super_block;
31struct xfs_mount_args; 31struct xfs_mount_args;
32 32
33typedef struct kstatfs xfs_statfs_t; 33typedef struct kstatfs bhv_statvfs_t;
34 34
35typedef struct vfs_sync_work { 35typedef struct bhv_vfs_sync_work {
36 struct list_head w_list; 36 struct list_head w_list;
37 struct vfs *w_vfs; 37 struct bhv_vfs *w_vfs;
38 void *w_data; /* syncer routine argument */ 38 void *w_data; /* syncer routine argument */
39 void (*w_syncer)(struct vfs *, void *); 39 void (*w_syncer)(struct bhv_vfs *, void *);
40} vfs_sync_work_t; 40} bhv_vfs_sync_work_t;
41 41
42typedef struct vfs { 42typedef struct bhv_vfs {
43 u_int vfs_flag; /* flags */ 43 u_int vfs_flag; /* flags */
44 xfs_fsid_t vfs_fsid; /* file system ID */ 44 xfs_fsid_t vfs_fsid; /* file system ID */
45 xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */ 45 xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
46 bhv_head_t vfs_bh; /* head of vfs behavior chain */ 46 bhv_head_t vfs_bh; /* head of vfs behavior chain */
47 struct super_block *vfs_super; /* generic superblock pointer */ 47 struct super_block *vfs_super; /* generic superblock pointer */
48 struct task_struct *vfs_sync_task; /* generalised sync thread */ 48 struct task_struct *vfs_sync_task; /* generalised sync thread */
49 vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */ 49 bhv_vfs_sync_work_t vfs_sync_work; /* work item for VFS_SYNC */
50 struct list_head vfs_sync_list; /* sync thread work item list */ 50 struct list_head vfs_sync_list; /* sync thread work item list */
51 spinlock_t vfs_sync_lock; /* work item list lock */ 51 spinlock_t vfs_sync_lock; /* work item list lock */
52 int vfs_sync_seq; /* sync thread generation no. */ 52 int vfs_sync_seq; /* sync thread generation no. */
53 wait_queue_head_t vfs_wait_single_sync_task; 53 wait_queue_head_t vfs_wait_single_sync_task;
54} vfs_t; 54} bhv_vfs_t;
55
56#define vfs_fbhv vfs_bh.bh_first /* 1st on vfs behavior chain */
57 55
58#define bhvtovfs(bdp) ( (struct vfs *)BHV_VOBJ(bdp) ) 56#define bhvtovfs(bdp) ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
59#define bhvtovfsops(bdp) ( (struct vfsops *)BHV_OPS(bdp) ) 57#define bhvtovfsops(bdp) ( (struct bhv_vfsops *)BHV_OPS(bdp) )
60#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh ) 58#define VFS_BHVHEAD(vfs) ( &(vfs)->vfs_bh )
61#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) ) 59#define VFS_REMOVEBHV(vfs, bdp) ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
62 60
@@ -71,7 +69,7 @@ typedef enum {
71 VFS_BHV_QM, /* quota manager */ 69 VFS_BHV_QM, /* quota manager */
72 VFS_BHV_IO, /* IO path */ 70 VFS_BHV_IO, /* IO path */
73 VFS_BHV_END /* housekeeping end-of-range */ 71 VFS_BHV_END /* housekeeping end-of-range */
74} vfs_bhv_t; 72} bhv_vfs_type_t;
75 73
76#define VFS_POSITION_XFS (BHV_POSITION_BASE) 74#define VFS_POSITION_XFS (BHV_POSITION_BASE)
77#define VFS_POSITION_DM (VFS_POSITION_BASE+10) 75#define VFS_POSITION_DM (VFS_POSITION_BASE+10)
@@ -81,8 +79,9 @@ typedef enum {
81#define VFS_RDONLY 0x0001 /* read-only vfs */ 79#define VFS_RDONLY 0x0001 /* read-only vfs */
82#define VFS_GRPID 0x0002 /* group-ID assigned from directory */ 80#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
83#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ 81#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
84#define VFS_32BITINODES 0x0008 /* do not use inums above 32 bits */ 82#define VFS_UMOUNT 0x0008 /* unmount in progress */
85#define VFS_END 0x0008 /* max flag */ 83#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
84#define VFS_END 0x0010 /* max flag */
86 85
87#define SYNC_ATTR 0x0001 /* sync attributes */ 86#define SYNC_ATTR 0x0001 /* sync attributes */
88#define SYNC_CLOSE 0x0002 /* close file system down */ 87#define SYNC_CLOSE 0x0002 /* close file system down */
@@ -92,7 +91,14 @@ typedef enum {
92#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ 91#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
93#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ 92#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
94#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ 93#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
95#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */ 94#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */
95
96#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
97#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
98#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
99#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
100#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
101#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
96 102
97typedef int (*vfs_mount_t)(bhv_desc_t *, 103typedef int (*vfs_mount_t)(bhv_desc_t *,
98 struct xfs_mount_args *, struct cred *); 104 struct xfs_mount_args *, struct cred *);
@@ -102,18 +108,19 @@ typedef int (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
102typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); 108typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
103typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, 109typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *,
104 struct xfs_mount_args *); 110 struct xfs_mount_args *);
105typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **); 111typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
106typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *); 112typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
113 struct bhv_vnode *);
107typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); 114typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
108typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *); 115typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
109typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); 116typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
110typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); 117typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
111typedef void (*vfs_init_vnode_t)(bhv_desc_t *, 118typedef void (*vfs_init_vnode_t)(bhv_desc_t *,
112 struct vnode *, bhv_desc_t *, int); 119 struct bhv_vnode *, bhv_desc_t *, int);
113typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); 120typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
114typedef void (*vfs_freeze_t)(bhv_desc_t *); 121typedef void (*vfs_freeze_t)(bhv_desc_t *);
115 122
116typedef struct vfsops { 123typedef struct bhv_vfsops {
117 bhv_position_t vf_position; /* behavior chain position */ 124 bhv_position_t vf_position; /* behavior chain position */
118 vfs_mount_t vfs_mount; /* mount file system */ 125 vfs_mount_t vfs_mount; /* mount file system */
119 vfs_parseargs_t vfs_parseargs; /* parse mount options */ 126 vfs_parseargs_t vfs_parseargs; /* parse mount options */
@@ -129,82 +136,82 @@ typedef struct vfsops {
129 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */ 136 vfs_init_vnode_t vfs_init_vnode; /* initialize a new vnode */
130 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */ 137 vfs_force_shutdown_t vfs_force_shutdown; /* crash and burn */
131 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */ 138 vfs_freeze_t vfs_freeze; /* freeze fs for snapshot */
132} vfsops_t; 139} bhv_vfsops_t;
133 140
134/* 141/*
135 * VFS's. Operates on vfs structure pointers (starts at bhv head). 142 * Virtual filesystem operations, operating from head bhv.
136 */ 143 */
137#define VHEAD(v) ((v)->vfs_fbhv) 144#define VFSHEAD(v) ((v)->vfs_bh.bh_first)
138#define VFS_MOUNT(v, ma,cr, rv) ((rv) = vfs_mount(VHEAD(v), ma,cr)) 145#define bhv_vfs_mount(v, ma,cr) vfs_mount(VFSHEAD(v), ma,cr)
139#define VFS_PARSEARGS(v, o,ma,f, rv) ((rv) = vfs_parseargs(VHEAD(v), o,ma,f)) 146#define bhv_vfs_parseargs(v, o,ma,f) vfs_parseargs(VFSHEAD(v), o,ma,f)
140#define VFS_SHOWARGS(v, m, rv) ((rv) = vfs_showargs(VHEAD(v), m)) 147#define bhv_vfs_showargs(v, m) vfs_showargs(VFSHEAD(v), m)
141#define VFS_UNMOUNT(v, f, cr, rv) ((rv) = vfs_unmount(VHEAD(v), f,cr)) 148#define bhv_vfs_unmount(v, f,cr) vfs_unmount(VFSHEAD(v), f,cr)
142#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args)) 149#define bhv_vfs_mntupdate(v, fl,args) vfs_mntupdate(VFSHEAD(v), fl,args)
143#define VFS_ROOT(v, vpp, rv) ((rv) = vfs_root(VHEAD(v), vpp)) 150#define bhv_vfs_root(v, vpp) vfs_root(VFSHEAD(v), vpp)
144#define VFS_STATVFS(v, sp,vp, rv) ((rv) = vfs_statvfs(VHEAD(v), sp,vp)) 151#define bhv_vfs_statvfs(v, sp,vp) vfs_statvfs(VFSHEAD(v), sp,vp)
145#define VFS_SYNC(v, flag,cr, rv) ((rv) = vfs_sync(VHEAD(v), flag,cr)) 152#define bhv_vfs_sync(v, flag,cr) vfs_sync(VFSHEAD(v), flag,cr)
146#define VFS_VGET(v, vpp,fidp, rv) ((rv) = vfs_vget(VHEAD(v), vpp,fidp)) 153#define bhv_vfs_vget(v, vpp,fidp) vfs_vget(VFSHEAD(v), vpp,fidp)
147#define VFS_DMAPIOPS(v, p, rv) ((rv) = vfs_dmapiops(VHEAD(v), p)) 154#define bhv_vfs_dmapiops(v, p) vfs_dmapiops(VFSHEAD(v), p)
148#define VFS_QUOTACTL(v, c,id,p, rv) ((rv) = vfs_quotactl(VHEAD(v), c,id,p)) 155#define bhv_vfs_quotactl(v, c,id,p) vfs_quotactl(VFSHEAD(v), c,id,p)
149#define VFS_INIT_VNODE(v, vp,b,ul) ( vfs_init_vnode(VHEAD(v), vp,b,ul) ) 156#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
150#define VFS_FORCE_SHUTDOWN(v, fl,f,l) ( vfs_force_shutdown(VHEAD(v), fl,f,l) ) 157#define bhv_vfs_force_shutdown(v,u,f,l) vfs_force_shutdown(VFSHEAD(v), u,f,l)
151#define VFS_FREEZE(v) ( vfs_freeze(VHEAD(v)) ) 158#define bhv_vfs_freeze(v) vfs_freeze(VFSHEAD(v))
152 159
153/* 160/*
154 * PVFS's. Operates on behavior descriptor pointers. 161 * Virtual filesystem operations, operating from next bhv.
155 */ 162 */
156#define PVFS_MOUNT(b, ma,cr, rv) ((rv) = vfs_mount(b, ma,cr)) 163#define bhv_next_vfs_mount(b, ma,cr) vfs_mount(b, ma,cr)
157#define PVFS_PARSEARGS(b, o,ma,f, rv) ((rv) = vfs_parseargs(b, o,ma,f)) 164#define bhv_next_vfs_parseargs(b, o,ma,f) vfs_parseargs(b, o,ma,f)
158#define PVFS_SHOWARGS(b, m, rv) ((rv) = vfs_showargs(b, m)) 165#define bhv_next_vfs_showargs(b, m) vfs_showargs(b, m)
159#define PVFS_UNMOUNT(b, f,cr, rv) ((rv) = vfs_unmount(b, f,cr)) 166#define bhv_next_vfs_unmount(b, f,cr) vfs_unmount(b, f,cr)
160#define PVFS_MNTUPDATE(b, fl, args, rv) ((rv) = vfs_mntupdate(b, fl, args)) 167#define bhv_next_vfs_mntupdate(b, fl,args) vfs_mntupdate(b, fl, args)
161#define PVFS_ROOT(b, vpp, rv) ((rv) = vfs_root(b, vpp)) 168#define bhv_next_vfs_root(b, vpp) vfs_root(b, vpp)
162#define PVFS_STATVFS(b, sp,vp, rv) ((rv) = vfs_statvfs(b, sp,vp)) 169#define bhv_next_vfs_statvfs(b, sp,vp) vfs_statvfs(b, sp,vp)
163#define PVFS_SYNC(b, flag,cr, rv) ((rv) = vfs_sync(b, flag,cr)) 170#define bhv_next_vfs_sync(b, flag,cr) vfs_sync(b, flag,cr)
164#define PVFS_VGET(b, vpp,fidp, rv) ((rv) = vfs_vget(b, vpp,fidp)) 171#define bhv_next_vfs_vget(b, vpp,fidp) vfs_vget(b, vpp,fidp)
165#define PVFS_DMAPIOPS(b, p, rv) ((rv) = vfs_dmapiops(b, p)) 172#define bhv_next_vfs_dmapiops(b, p) vfs_dmapiops(b, p)
166#define PVFS_QUOTACTL(b, c,id,p, rv) ((rv) = vfs_quotactl(b, c,id,p)) 173#define bhv_next_vfs_quotactl(b, c,id,p) vfs_quotactl(b, c,id,p)
167#define PVFS_INIT_VNODE(b, vp,b2,ul) ( vfs_init_vnode(b, vp,b2,ul) ) 174#define bhv_next_vfs_init_vnode(b, vp,b2,ul) vfs_init_vnode(b, vp,b2,ul)
168#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) ) 175#define bhv_next_force_shutdown(b, fl,f,l) vfs_force_shutdown(b, fl,f,l)
169#define PVFS_FREEZE(b) ( vfs_freeze(b) ) 176#define bhv_next_vfs_freeze(b) vfs_freeze(b)
170 177
171extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); 178extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
172extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); 179extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
173extern int vfs_showargs(bhv_desc_t *, struct seq_file *); 180extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
174extern int vfs_unmount(bhv_desc_t *, int, struct cred *); 181extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
175extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); 182extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
176extern int vfs_root(bhv_desc_t *, struct vnode **); 183extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
177extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *); 184extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
178extern int vfs_sync(bhv_desc_t *, int, struct cred *); 185extern int vfs_sync(bhv_desc_t *, int, struct cred *);
179extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *); 186extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
180extern int vfs_dmapiops(bhv_desc_t *, caddr_t); 187extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
181extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); 188extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
182extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int); 189extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
183extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); 190extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
184extern void vfs_freeze(bhv_desc_t *); 191extern void vfs_freeze(bhv_desc_t *);
185 192
186typedef struct bhv_vfsops { 193#define vfs_test_for_freeze(vfs) ((vfs)->vfs_super->s_frozen)
187 struct vfsops bhv_common; 194#define vfs_wait_for_freeze(vfs,l) vfs_check_frozen((vfs)->vfs_super, (l))
195
196typedef struct bhv_module_vfsops {
197 struct bhv_vfsops bhv_common;
188 void * bhv_custom; 198 void * bhv_custom;
189} bhv_vfsops_t; 199} bhv_module_vfsops_t;
190 200
191#define vfs_bhv_lookup(v, id) ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) ) 201#define vfs_bhv_lookup(v, id) (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
192#define vfs_bhv_custom(b) ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom ) 202#define vfs_bhv_custom(b) (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
193#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o)) 203#define vfs_bhv_set_custom(b,o) ((b)->bhv_custom = (void *)(o))
194#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL ) 204#define vfs_bhv_clr_custom(b) ((b)->bhv_custom = NULL)
195 205
196extern vfs_t *vfs_allocate(struct super_block *); 206extern bhv_vfs_t *vfs_allocate(struct super_block *);
197extern vfs_t *vfs_from_sb(struct super_block *); 207extern bhv_vfs_t *vfs_from_sb(struct super_block *);
198extern void vfs_deallocate(vfs_t *); 208extern void vfs_deallocate(bhv_vfs_t *);
199extern void vfs_insertops(vfs_t *, bhv_vfsops_t *); 209extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
200extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
201 210
202extern void bhv_insert_all_vfsops(struct vfs *); 211extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
203extern void bhv_remove_all_vfsops(struct vfs *, int);
204extern void bhv_remove_vfsops(struct vfs *, int);
205 212
206#define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen) 213extern void bhv_insert_all_vfsops(struct bhv_vfs *);
207#define fs_check_frozen(vfsp, level) \ 214extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
208 vfs_check_frozen(vfsp->vfs_super, level); 215extern void bhv_remove_vfsops(struct bhv_vfs *, int);
209 216
210#endif /* __XFS_VFS_H__ */ 217#endif /* __XFS_VFS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index d27c25b27ccd..6628d96b6fd6 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -39,7 +39,7 @@ vn_init(void)
39 39
40void 40void
41vn_iowait( 41vn_iowait(
42 struct vnode *vp) 42 bhv_vnode_t *vp)
43{ 43{
44 wait_queue_head_t *wq = vptosync(vp); 44 wait_queue_head_t *wq = vptosync(vp);
45 45
@@ -48,17 +48,33 @@ vn_iowait(
48 48
49void 49void
50vn_iowake( 50vn_iowake(
51 struct vnode *vp) 51 bhv_vnode_t *vp)
52{ 52{
53 if (atomic_dec_and_test(&vp->v_iocount)) 53 if (atomic_dec_and_test(&vp->v_iocount))
54 wake_up(vptosync(vp)); 54 wake_up(vptosync(vp));
55} 55}
56 56
57struct vnode * 57/*
58 * Volume managers supporting multiple paths can send back ENODEV when the
59 * final path disappears. In this case continuing to fill the page cache
60 * with dirty data which cannot be written out is evil, so prevent that.
61 */
62void
63vn_ioerror(
64 bhv_vnode_t *vp,
65 int error,
66 char *f,
67 int l)
68{
69 if (unlikely(error == -ENODEV))
70 bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
71}
72
73bhv_vnode_t *
58vn_initialize( 74vn_initialize(
59 struct inode *inode) 75 struct inode *inode)
60{ 76{
61 struct vnode *vp = vn_from_inode(inode); 77 bhv_vnode_t *vp = vn_from_inode(inode);
62 78
63 XFS_STATS_INC(vn_active); 79 XFS_STATS_INC(vn_active);
64 XFS_STATS_INC(vn_alloc); 80 XFS_STATS_INC(vn_alloc);
@@ -94,8 +110,8 @@ vn_initialize(
94 */ 110 */
95void 111void
96vn_revalidate_core( 112vn_revalidate_core(
97 struct vnode *vp, 113 bhv_vnode_t *vp,
98 vattr_t *vap) 114 bhv_vattr_t *vap)
99{ 115{
100 struct inode *inode = vn_to_inode(vp); 116 struct inode *inode = vn_to_inode(vp);
101 117
@@ -130,14 +146,14 @@ vn_revalidate_core(
130 */ 146 */
131int 147int
132__vn_revalidate( 148__vn_revalidate(
133 struct vnode *vp, 149 bhv_vnode_t *vp,
134 struct vattr *vattr) 150 bhv_vattr_t *vattr)
135{ 151{
136 int error; 152 int error;
137 153
138 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 154 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
139 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS; 155 vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
140 VOP_GETATTR(vp, vattr, 0, NULL, error); 156 error = bhv_vop_getattr(vp, vattr, 0, NULL);
141 if (likely(!error)) { 157 if (likely(!error)) {
142 vn_revalidate_core(vp, vattr); 158 vn_revalidate_core(vp, vattr);
143 VUNMODIFY(vp); 159 VUNMODIFY(vp);
@@ -147,9 +163,9 @@ __vn_revalidate(
147 163
148int 164int
149vn_revalidate( 165vn_revalidate(
150 struct vnode *vp) 166 bhv_vnode_t *vp)
151{ 167{
152 vattr_t vattr; 168 bhv_vattr_t vattr;
153 169
154 return __vn_revalidate(vp, &vattr); 170 return __vn_revalidate(vp, &vattr);
155} 171}
@@ -157,9 +173,9 @@ vn_revalidate(
157/* 173/*
158 * Add a reference to a referenced vnode. 174 * Add a reference to a referenced vnode.
159 */ 175 */
160struct vnode * 176bhv_vnode_t *
161vn_hold( 177vn_hold(
162 struct vnode *vp) 178 bhv_vnode_t *vp)
163{ 179{
164 struct inode *inode; 180 struct inode *inode;
165 181
@@ -192,31 +208,31 @@ vn_hold(
192 * Vnode tracing code. 208 * Vnode tracing code.
193 */ 209 */
194void 210void
195vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) 211vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra)
196{ 212{
197 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); 213 KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
198} 214}
199 215
200void 216void
201vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) 217vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra)
202{ 218{
203 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); 219 KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
204} 220}
205 221
206void 222void
207vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra) 223vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
208{ 224{
209 KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra); 225 KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
210} 226}
211 227
212void 228void
213vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra) 229vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
214{ 230{
215 KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra); 231 KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
216} 232}
217 233
218void 234void
219vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra) 235vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
220{ 236{
221 KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra); 237 KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
222} 238}
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 2a8e16c22353..35c6a01963a7 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -14,57 +14,35 @@
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Portions Copyright (c) 1989, 1993
19 * The Regents of the University of California. All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. Neither the name of the University nor the names of its contributors
30 * may be used to endorse or promote products derived from this software
31 * without specific prior written permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 */ 17 */
45#ifndef __XFS_VNODE_H__ 18#ifndef __XFS_VNODE_H__
46#define __XFS_VNODE_H__ 19#define __XFS_VNODE_H__
47 20
48struct uio; 21struct uio;
49struct file; 22struct file;
50struct vattr; 23struct bhv_vfs;
24struct bhv_vattr;
51struct xfs_iomap; 25struct xfs_iomap;
52struct attrlist_cursor_kern; 26struct attrlist_cursor_kern;
53 27
28typedef struct dentry bhv_vname_t;
29typedef __u64 bhv_vnumber_t;
54 30
55typedef xfs_ino_t vnumber_t; 31typedef enum bhv_vflags {
56typedef struct dentry vname_t; 32 VMODIFIED = 0x08, /* XFS inode state possibly differs */
57typedef bhv_head_t vn_bhv_head_t; 33 /* to the Linux inode state. */
34 VTRUNCATED = 0x40, /* truncated down so flush-on-close */
35} bhv_vflags_t;
58 36
59/* 37/*
60 * MP locking protocols: 38 * MP locking protocols:
61 * v_flag, v_vfsp VN_LOCK/VN_UNLOCK 39 * v_flag, v_vfsp VN_LOCK/VN_UNLOCK
62 */ 40 */
63typedef struct vnode { 41typedef struct bhv_vnode {
64 __u32 v_flag; /* vnode flags (see below) */ 42 bhv_vflags_t v_flag; /* vnode flags (see above) */
65 struct vfs *v_vfsp; /* ptr to containing VFS */ 43 bhv_vfs_t *v_vfsp; /* ptr to containing VFS */
66 vnumber_t v_number; /* in-core vnode number */ 44 bhv_vnumber_t v_number; /* in-core vnode number */
67 vn_bhv_head_t v_bh; /* behavior head */ 45 bhv_head_t v_bh; /* behavior head */
68 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ 46 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
69 atomic_t v_iocount; /* outstanding I/O count */ 47 atomic_t v_iocount; /* outstanding I/O count */
70#ifdef XFS_VNODE_TRACE 48#ifdef XFS_VNODE_TRACE
@@ -72,7 +50,7 @@ typedef struct vnode {
72#endif 50#endif
73 struct inode v_inode; /* Linux inode */ 51 struct inode v_inode; /* Linux inode */
74 /* inode MUST be last */ 52 /* inode MUST be last */
75} vnode_t; 53} bhv_vnode_t;
76 54
77#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode) 55#define VN_ISLNK(vp) S_ISLNK((vp)->v_inode.i_mode)
78#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode) 56#define VN_ISREG(vp) S_ISREG((vp)->v_inode.i_mode)
@@ -80,9 +58,6 @@ typedef struct vnode {
80#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode) 58#define VN_ISCHR(vp) S_ISCHR((vp)->v_inode.i_mode)
81#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode) 59#define VN_ISBLK(vp) S_ISBLK((vp)->v_inode.i_mode)
82 60
83#define v_fbhv v_bh.bh_first /* first behavior */
84#define v_fops v_bh.bh_first->bd_ops /* first behavior ops */
85
86#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */ 61#define VNODE_POSITION_BASE BHV_POSITION_BASE /* chain bottom */
87#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */ 62#define VNODE_POSITION_TOP BHV_POSITION_TOP /* chain top */
88#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */ 63#define VNODE_POSITION_INVALID BHV_POSITION_INVALID /* invalid pos. num */
@@ -104,8 +79,8 @@ typedef enum {
104/* 79/*
105 * Macros for dealing with the behavior descriptor inside of the vnode. 80 * Macros for dealing with the behavior descriptor inside of the vnode.
106 */ 81 */
107#define BHV_TO_VNODE(bdp) ((vnode_t *)BHV_VOBJ(bdp)) 82#define BHV_TO_VNODE(bdp) ((bhv_vnode_t *)BHV_VOBJ(bdp))
108#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp)) 83#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
109 84
110#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) 85#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
111#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) 86#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
@@ -116,35 +91,29 @@ typedef enum {
116/* 91/*
117 * Vnode to Linux inode mapping. 92 * Vnode to Linux inode mapping.
118 */ 93 */
119static inline struct vnode *vn_from_inode(struct inode *inode) 94static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
120{ 95{
121 return (vnode_t *)list_entry(inode, vnode_t, v_inode); 96 return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode);
122} 97}
123static inline struct inode *vn_to_inode(struct vnode *vnode) 98static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
124{ 99{
125 return &vnode->v_inode; 100 return &vnode->v_inode;
126} 101}
127 102
128/* 103/*
129 * Vnode flags. 104 * Values for the vop_rwlock/rwunlock flags parameter.
130 */
131#define VMODIFIED 0x8 /* XFS inode state possibly differs */
132 /* to the Linux inode state. */
133
134/*
135 * Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
136 */ 105 */
137typedef enum vrwlock { 106typedef enum bhv_vrwlock {
138 VRWLOCK_NONE, 107 VRWLOCK_NONE,
139 VRWLOCK_READ, 108 VRWLOCK_READ,
140 VRWLOCK_WRITE, 109 VRWLOCK_WRITE,
141 VRWLOCK_WRITE_DIRECT, 110 VRWLOCK_WRITE_DIRECT,
142 VRWLOCK_TRY_READ, 111 VRWLOCK_TRY_READ,
143 VRWLOCK_TRY_WRITE 112 VRWLOCK_TRY_WRITE
144} vrwlock_t; 113} bhv_vrwlock_t;
145 114
146/* 115/*
147 * Return values for VOP_INACTIVE. A return value of 116 * Return values for bhv_vop_inactive. A return value of
148 * VN_INACTIVE_NOCACHE implies that the file system behavior 117 * VN_INACTIVE_NOCACHE implies that the file system behavior
149 * has disassociated its state and bhv_desc_t from the vnode. 118 * has disassociated its state and bhv_desc_t from the vnode.
150 */ 119 */
@@ -152,18 +121,20 @@ typedef enum vrwlock {
152#define VN_INACTIVE_NOCACHE 1 121#define VN_INACTIVE_NOCACHE 1
153 122
154/* 123/*
155 * Values for the cmd code given to VOP_VNODE_CHANGE. 124 * Values for the cmd code given to vop_vnode_change.
156 */ 125 */
157typedef enum vchange { 126typedef enum bhv_vchange {
158 VCHANGE_FLAGS_FRLOCKS = 0, 127 VCHANGE_FLAGS_FRLOCKS = 0,
159 VCHANGE_FLAGS_ENF_LOCKING = 1, 128 VCHANGE_FLAGS_ENF_LOCKING = 1,
160 VCHANGE_FLAGS_TRUNCATED = 2, 129 VCHANGE_FLAGS_TRUNCATED = 2,
161 VCHANGE_FLAGS_PAGE_DIRTY = 3, 130 VCHANGE_FLAGS_PAGE_DIRTY = 3,
162 VCHANGE_FLAGS_IOEXCL_COUNT = 4 131 VCHANGE_FLAGS_IOEXCL_COUNT = 4
163} vchange_t; 132} bhv_vchange_t;
164 133
134typedef enum { L_FALSE, L_TRUE } lastclose_t;
165 135
166typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); 136typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
137typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *);
167typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, 138typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
168 const struct iovec *, unsigned int, 139 const struct iovec *, unsigned int,
169 loff_t *, int, struct cred *); 140 loff_t *, int, struct cred *);
@@ -181,27 +152,27 @@ typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
181 struct cred *); 152 struct cred *);
182typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, 153typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
183 int, unsigned int, void __user *); 154 int, unsigned int, void __user *);
184typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, 155typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
185 struct cred *); 156 struct cred *);
186typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int, 157typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
187 struct cred *); 158 struct cred *);
188typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); 159typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *);
189typedef int (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **, 160typedef int (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
190 int, vnode_t *, struct cred *); 161 int, bhv_vnode_t *, struct cred *);
191typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *, 162typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
192 vnode_t **, struct cred *); 163 bhv_vnode_t **, struct cred *);
193typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *); 164typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
194typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *, 165typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
195 struct cred *);
196typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *,
197 struct cred *); 166 struct cred *);
198typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *, 167typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
199 vnode_t **, struct cred *); 168 bhv_vname_t *, struct cred *);
200typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *); 169typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
170 bhv_vnode_t **, struct cred *);
171typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
201typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, 172typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
202 int *); 173 int *);
203typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *, 174typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
204 char *, vnode_t **, struct cred *); 175 char *, bhv_vnode_t **, struct cred *);
205typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, 176typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
206 struct cred *); 177 struct cred *);
207typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, 178typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
@@ -209,8 +180,8 @@ typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
209typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); 180typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *);
210typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); 181typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *);
211typedef int (*vop_release_t)(bhv_desc_t *); 182typedef int (*vop_release_t)(bhv_desc_t *);
212typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t); 183typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
213typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t); 184typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
214typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, 185typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
215 struct xfs_iomap *, int *); 186 struct xfs_iomap *, int *);
216typedef int (*vop_reclaim_t)(bhv_desc_t *); 187typedef int (*vop_reclaim_t)(bhv_desc_t *);
@@ -222,8 +193,8 @@ typedef int (*vop_attr_remove_t)(bhv_desc_t *, const char *,
222 int, struct cred *); 193 int, struct cred *);
223typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, 194typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
224 struct attrlist_cursor_kern *, struct cred *); 195 struct attrlist_cursor_kern *, struct cred *);
225typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int); 196typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
226typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t); 197typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
227typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 198typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
228typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); 199typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
229typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, 200typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
@@ -231,9 +202,10 @@ typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
231typedef int (*vop_iflush_t)(bhv_desc_t *, int); 202typedef int (*vop_iflush_t)(bhv_desc_t *, int);
232 203
233 204
234typedef struct vnodeops { 205typedef struct bhv_vnodeops {
235 bhv_position_t vn_position; /* position within behavior chain */ 206 bhv_position_t vn_position; /* position within behavior chain */
236 vop_open_t vop_open; 207 vop_open_t vop_open;
208 vop_close_t vop_close;
237 vop_read_t vop_read; 209 vop_read_t vop_read;
238 vop_write_t vop_write; 210 vop_write_t vop_write;
239 vop_sendfile_t vop_sendfile; 211 vop_sendfile_t vop_sendfile;
@@ -271,103 +243,80 @@ typedef struct vnodeops {
271 vop_pflushvp_t vop_flush_pages; 243 vop_pflushvp_t vop_flush_pages;
272 vop_release_t vop_release; 244 vop_release_t vop_release;
273 vop_iflush_t vop_iflush; 245 vop_iflush_t vop_iflush;
274} vnodeops_t; 246} bhv_vnodeops_t;
275 247
276/* 248/*
277 * VOP's. 249 * Virtual node operations, operating from head bhv.
278 */
279#define _VOP_(op, vp) (*((vnodeops_t *)(vp)->v_fops)->op)
280
281#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv) \
282 rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
283#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv) \
284 rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
285#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
286 rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
287#define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
288 rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
289#define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv) \
290 rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
291#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
292 rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
293#define VOP_OPEN(vp, cr, rv) \
294 rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
295#define VOP_GETATTR(vp, vap, f, cr, rv) \
296 rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
297#define VOP_SETATTR(vp, vap, f, cr, rv) \
298 rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
299#define VOP_ACCESS(vp, mode, cr, rv) \
300 rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr)
301#define VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv) \
302 rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
303#define VOP_CREATE(dvp,d,vap,vpp,cr,rv) \
304 rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
305#define VOP_REMOVE(dvp,d,cr,rv) \
306 rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
307#define VOP_LINK(tdvp,fvp,d,cr,rv) \
308 rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
309#define VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv) \
310 rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
311#define VOP_MKDIR(dp,d,vap,vpp,cr,rv) \
312 rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
313#define VOP_RMDIR(dp,d,cr,rv) \
314 rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
315#define VOP_READDIR(vp,uiop,cr,eofp,rv) \
316 rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
317#define VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv) \
318 rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
319#define VOP_READLINK(vp,uiop,fl,cr,rv) \
320 rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
321#define VOP_FSYNC(vp,f,cr,b,e,rv) \
322 rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
323#define VOP_INACTIVE(vp, cr, rv) \
324 rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
325#define VOP_RELEASE(vp, rv) \
326 rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
327#define VOP_FID2(vp, fidp, rv) \
328 rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
329#define VOP_RWLOCK(vp,i) \
330 (void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
331#define VOP_RWLOCK_TRY(vp,i) \
332 _VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
333#define VOP_RWUNLOCK(vp,i) \
334 (void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
335#define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv) \
336 rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
337#define VOP_RECLAIM(vp, rv) \
338 rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
339#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv) \
340 rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
341#define VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv) \
342 rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
343#define VOP_ATTR_REMOVE(vp, name, flags, cred, rv) \
344 rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
345#define VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv) \
346 rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
347#define VOP_LINK_REMOVED(vp, dvp, linkzero) \
348 (void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
349#define VOP_VNODE_CHANGE(vp, cmd, val) \
350 (void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
351/*
352 * These are page cache functions that now go thru VOPs.
353 * 'last' parameter is unused and left in for IRIX compatibility
354 */ 250 */
355#define VOP_TOSS_PAGES(vp, first, last, fiopt) \ 251#define VNHEAD(vp) ((vp)->v_bh.bh_first)
356 _VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt) 252#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
357/* 253#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
358 * 'last' parameter is unused and left in for IRIX compatibility 254#define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
359 */ 255#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
360#define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt) \ 256 VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
361 _VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt) 257#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \
362/* 258 VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
363 * 'last' parameter is unused and left in for IRIX compatibility 259#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr) \
364 */ 260 VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
365#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv) \ 261#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr) \
366 rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt) 262 VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
367#define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv) \ 263#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr) \
368 rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg) 264 VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
369#define VOP_IFLUSH(vp, flags, rv) \ 265#define bhv_vop_bmap(vp,of,sz,rw,b,n) \
370 rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags) 266 VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
267#define bhv_vop_getattr(vp, vap,f,cr) \
268 VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
269#define bhv_vop_setattr(vp, vap,f,cr) \
270 VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
271#define bhv_vop_access(vp, mode,cr) VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
272#define bhv_vop_lookup(vp,d,vpp,f,rdir,cr) \
273 VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
274#define bhv_vop_create(dvp,d,vap,vpp,cr) \
275 VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
276#define bhv_vop_remove(dvp,d,cr) VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
277#define bhv_vop_link(dvp,fvp,d,cr) VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
278#define bhv_vop_rename(fvp,fnm,tdvp,tnm,cr) \
279 VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
280#define bhv_vop_mkdir(dp,d,vap,vpp,cr) \
281 VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
282#define bhv_vop_rmdir(dp,d,cr) VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
283#define bhv_vop_readdir(vp,uiop,cr,eofp) \
284 VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
285#define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \
286 VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
287#define bhv_vop_readlink(vp,uiop,fl,cr) \
288 VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
289#define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
290#define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr)
291#define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp))
292#define bhv_vop_fid2(vp,fidp) VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
293#define bhv_vop_rwlock(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
294#define bhv_vop_rwlock_try(vp,i) VOP(vop_rwlock, vp)(VNHEAD(vp),i)
295#define bhv_vop_rwunlock(vp,i) VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
296#define bhv_vop_frlock(vp,c,fl,flags,offset,fr) \
297 VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
298#define bhv_vop_reclaim(vp) VOP(vop_reclaim, vp)(VNHEAD(vp))
299#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred) \
300 VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
301#define bhv_vop_attr_set(vp, name, val, vallen, fl, cred) \
302 VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
303#define bhv_vop_attr_remove(vp, name, flags, cred) \
304 VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
305#define bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred) \
306 VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
307#define bhv_vop_link_removed(vp, dvp, linkzero) \
308 VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
309#define bhv_vop_vnode_change(vp, cmd, val) \
310 VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
311#define bhv_vop_toss_pages(vp, first, last, fiopt) \
312 VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
313#define bhv_vop_flushinval_pages(vp, first, last, fiopt) \
314 VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
315#define bhv_vop_flush_pages(vp, first, last, flags, fiopt) \
316 VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
317#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg) \
318 VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
319#define bhv_vop_iflush(vp, flags) VOP(vop_iflush, vp)(VNHEAD(vp), flags)
371 320
372/* 321/*
373 * Flags for read/write calls - same values as IRIX 322 * Flags for read/write calls - same values as IRIX
@@ -377,7 +326,7 @@ typedef struct vnodeops {
377#define IO_INVIS 0x00020 /* don't update inode timestamps */ 326#define IO_INVIS 0x00020 /* don't update inode timestamps */
378 327
379/* 328/*
380 * Flags for VOP_IFLUSH call 329 * Flags for vop_iflush call
381 */ 330 */
382#define FLUSH_SYNC 1 /* wait for flush to complete */ 331#define FLUSH_SYNC 1 /* wait for flush to complete */
383#define FLUSH_INODE 2 /* flush the inode itself */ 332#define FLUSH_INODE 2 /* flush the inode itself */
@@ -385,8 +334,7 @@ typedef struct vnodeops {
385 * this inode out to disk */ 334 * this inode out to disk */
386 335
387/* 336/*
388 * Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and 337 * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
389 * VOP_FLUSH_PAGES.
390 */ 338 */
391#define FI_NONE 0 /* none */ 339#define FI_NONE 0 /* none */
392#define FI_REMAPF 1 /* Do a remapf prior to the operation */ 340#define FI_REMAPF 1 /* Do a remapf prior to the operation */
@@ -398,7 +346,7 @@ typedef struct vnodeops {
398 * Vnode attributes. va_mask indicates those attributes the caller 346 * Vnode attributes. va_mask indicates those attributes the caller
399 * wants to set or extract. 347 * wants to set or extract.
400 */ 348 */
401typedef struct vattr { 349typedef struct bhv_vattr {
402 int va_mask; /* bit-mask of attributes present */ 350 int va_mask; /* bit-mask of attributes present */
403 mode_t va_mode; /* file access mode and type */ 351 mode_t va_mode; /* file access mode and type */
404 xfs_nlink_t va_nlink; /* number of references to file */ 352 xfs_nlink_t va_nlink; /* number of references to file */
@@ -418,7 +366,7 @@ typedef struct vattr {
418 u_long va_nextents; /* number of extents in file */ 366 u_long va_nextents; /* number of extents in file */
419 u_long va_anextents; /* number of attr extents in file */ 367 u_long va_anextents; /* number of attr extents in file */
420 prid_t va_projid; /* project id */ 368 prid_t va_projid; /* project id */
421} vattr_t; 369} bhv_vattr_t;
422 370
423/* 371/*
424 * setattr or getattr attributes 372 * setattr or getattr attributes
@@ -492,29 +440,17 @@ typedef struct vattr {
492 (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID) 440 (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
493 441
494extern void vn_init(void); 442extern void vn_init(void);
495extern vnode_t *vn_initialize(struct inode *); 443extern bhv_vnode_t *vn_initialize(struct inode *);
496 444extern int vn_revalidate(struct bhv_vnode *);
497/* 445extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *);
498 * vnode_map structures _must_ match vn_epoch and vnode structure sizes. 446extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *);
499 */
500typedef struct vnode_map {
501 vfs_t *v_vfsp;
502 vnumber_t v_number; /* in-core vnode number */
503 xfs_ino_t v_ino; /* inode # */
504} vmap_t;
505
506#define VMAP(vp, vmap) {(vmap).v_vfsp = (vp)->v_vfsp, \
507 (vmap).v_number = (vp)->v_number, \
508 (vmap).v_ino = (vp)->v_inode.i_ino; }
509 447
510extern int vn_revalidate(struct vnode *); 448extern void vn_iowait(struct bhv_vnode *vp);
511extern int __vn_revalidate(struct vnode *, vattr_t *); 449extern void vn_iowake(struct bhv_vnode *vp);
512extern void vn_revalidate_core(struct vnode *, vattr_t *);
513 450
514extern void vn_iowait(struct vnode *vp); 451extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
515extern void vn_iowake(struct vnode *vp);
516 452
517static inline int vn_count(struct vnode *vp) 453static inline int vn_count(struct bhv_vnode *vp)
518{ 454{
519 return atomic_read(&vn_to_inode(vp)->i_count); 455 return atomic_read(&vn_to_inode(vp)->i_count);
520} 456}
@@ -522,7 +458,7 @@ static inline int vn_count(struct vnode *vp)
522/* 458/*
523 * Vnode reference counting functions (and macros for compatibility). 459 * Vnode reference counting functions (and macros for compatibility).
524 */ 460 */
525extern vnode_t *vn_hold(struct vnode *); 461extern bhv_vnode_t *vn_hold(struct bhv_vnode *);
526 462
527#if defined(XFS_VNODE_TRACE) 463#if defined(XFS_VNODE_TRACE)
528#define VN_HOLD(vp) \ 464#define VN_HOLD(vp) \
@@ -536,7 +472,7 @@ extern vnode_t *vn_hold(struct vnode *);
536#define VN_RELE(vp) (iput(vn_to_inode(vp))) 472#define VN_RELE(vp) (iput(vn_to_inode(vp)))
537#endif 473#endif
538 474
539static inline struct vnode *vn_grab(struct vnode *vp) 475static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
540{ 476{
541 struct inode *inode = igrab(vn_to_inode(vp)); 477 struct inode *inode = igrab(vn_to_inode(vp));
542 return inode ? vn_from_inode(inode) : NULL; 478 return inode ? vn_from_inode(inode) : NULL;
@@ -554,32 +490,39 @@ static inline struct vnode *vn_grab(struct vnode *vp)
554 */ 490 */
555#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock) 491#define VN_LOCK(vp) mutex_spinlock(&(vp)->v_lock)
556#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s) 492#define VN_UNLOCK(vp, s) mutex_spinunlock(&(vp)->v_lock, s)
557#define VN_FLAGSET(vp,b) vn_flagset(vp,b)
558#define VN_FLAGCLR(vp,b) vn_flagclr(vp,b)
559 493
560static __inline__ void vn_flagset(struct vnode *vp, uint flag) 494static __inline__ void vn_flagset(struct bhv_vnode *vp, uint flag)
561{ 495{
562 spin_lock(&vp->v_lock); 496 spin_lock(&vp->v_lock);
563 vp->v_flag |= flag; 497 vp->v_flag |= flag;
564 spin_unlock(&vp->v_lock); 498 spin_unlock(&vp->v_lock);
565} 499}
566 500
567static __inline__ void vn_flagclr(struct vnode *vp, uint flag) 501static __inline__ uint vn_flagclr(struct bhv_vnode *vp, uint flag)
568{ 502{
503 uint cleared;
504
569 spin_lock(&vp->v_lock); 505 spin_lock(&vp->v_lock);
506 cleared = (vp->v_flag & flag);
570 vp->v_flag &= ~flag; 507 vp->v_flag &= ~flag;
571 spin_unlock(&vp->v_lock); 508 spin_unlock(&vp->v_lock);
509 return cleared;
572} 510}
573 511
512#define VMODIFY(vp) vn_flagset(vp, VMODIFIED)
513#define VUNMODIFY(vp) vn_flagclr(vp, VMODIFIED)
514#define VTRUNCATE(vp) vn_flagset(vp, VTRUNCATED)
515#define VUNTRUNCATE(vp) vn_flagclr(vp, VTRUNCATED)
516
574/* 517/*
575 * Dealing with bad inodes 518 * Dealing with bad inodes
576 */ 519 */
577static inline void vn_mark_bad(struct vnode *vp) 520static inline void vn_mark_bad(struct bhv_vnode *vp)
578{ 521{
579 make_bad_inode(vn_to_inode(vp)); 522 make_bad_inode(vn_to_inode(vp));
580} 523}
581 524
582static inline int VN_BAD(struct vnode *vp) 525static inline int VN_BAD(struct bhv_vnode *vp)
583{ 526{
584 return is_bad_inode(vn_to_inode(vp)); 527 return is_bad_inode(vn_to_inode(vp));
585} 528}
@@ -587,18 +530,18 @@ static inline int VN_BAD(struct vnode *vp)
587/* 530/*
588 * Extracting atime values in various formats 531 * Extracting atime values in various formats
589 */ 532 */
590static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime) 533static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
591{ 534{
592 bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec; 535 bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
593 bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec; 536 bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
594} 537}
595 538
596static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts) 539static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
597{ 540{
598 *ts = vp->v_inode.i_atime; 541 *ts = vp->v_inode.i_atime;
599} 542}
600 543
601static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) 544static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
602{ 545{
603 *tt = vp->v_inode.i_atime.tv_sec; 546 *tt = vp->v_inode.i_atime.tv_sec;
604} 547}
@@ -610,11 +553,10 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
610#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) 553#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
611#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ 554#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
612 PAGECACHE_TAG_DIRTY) 555 PAGECACHE_TAG_DIRTY)
613#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED) 556#define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED)
614#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
615 557
616/* 558/*
617 * Flags to VOP_SETATTR/VOP_GETATTR. 559 * Flags to vop_setattr/getattr.
618 */ 560 */
619#define ATTR_UTIME 0x01 /* non-default utime(2) request */ 561#define ATTR_UTIME 0x01 /* non-default utime(2) request */
620#define ATTR_DMI 0x08 /* invocation from a DMI function */ 562#define ATTR_DMI 0x08 /* invocation from a DMI function */
@@ -624,7 +566,7 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
624#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */ 566#define ATTR_NOSIZETOK 0x400 /* Don't get the SIZE token */
625 567
626/* 568/*
627 * Flags to VOP_FSYNC and VOP_RECLAIM. 569 * Flags to vop_fsync/reclaim.
628 */ 570 */
629#define FSYNC_NOWAIT 0 /* asynchronous flush */ 571#define FSYNC_NOWAIT 0 /* asynchronous flush */
630#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */ 572#define FSYNC_WAIT 0x1 /* synchronous fsync or forced reclaim */
@@ -643,11 +585,11 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
643#define VNODE_KTRACE_REF 4 585#define VNODE_KTRACE_REF 4
644#define VNODE_KTRACE_RELE 5 586#define VNODE_KTRACE_RELE 5
645 587
646extern void vn_trace_entry(struct vnode *, const char *, inst_t *); 588extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
647extern void vn_trace_exit(struct vnode *, const char *, inst_t *); 589extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
648extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); 590extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
649extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); 591extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
650extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); 592extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
651 593
652#define VN_TRACE(vp) \ 594#define VN_TRACE(vp) \
653 vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address) 595 vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 772ac48329ea..3aa771531856 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -444,7 +442,7 @@ xfs_qm_dqalloc(
444 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, 442 XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
445 &firstblock, 443 &firstblock,
446 XFS_QM_DQALLOC_SPACE_RES(mp), 444 XFS_QM_DQALLOC_SPACE_RES(mp),
447 &map, &nmaps, &flist))) { 445 &map, &nmaps, &flist, NULL))) {
448 goto error0; 446 goto error0;
449 } 447 }
450 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); 448 ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -559,7 +557,7 @@ xfs_qm_dqtobp(
559 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset, 557 error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
560 XFS_DQUOT_CLUSTER_SIZE_FSB, 558 XFS_DQUOT_CLUSTER_SIZE_FSB,
561 XFS_BMAPI_METADATA, 559 XFS_BMAPI_METADATA,
562 NULL, 0, &map, &nmaps, NULL); 560 NULL, 0, &map, &nmaps, NULL, NULL);
563 561
564 xfs_iunlock(quotip, XFS_ILOCK_SHARED); 562 xfs_iunlock(quotip, XFS_ILOCK_SHARED);
565 if (error) 563 if (error)
@@ -1261,7 +1259,7 @@ xfs_qm_dqflush(
1261 1259
1262 if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id), 1260 if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id),
1263 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) { 1261 0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
1264 xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE); 1262 xfs_force_shutdown(dqp->q_mount, SHUTDOWN_CORRUPT_INCORE);
1265 return XFS_ERROR(EIO); 1263 return XFS_ERROR(EIO);
1266 } 1264 }
1267 1265
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index c0c629663a5c..78d3ab95c5fd 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
119 */ 119 */
120#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\ 120#define xfs_dqflock(dqp) { psema(&((dqp)->q_flock), PINOD | PRECALC);\
121 (dqp)->dq_flags |= XFS_DQ_FLOCKED; } 121 (dqp)->dq_flags |= XFS_DQ_FLOCKED; }
122#define xfs_dqfunlock(dqp) { ASSERT(valusema(&((dqp)->q_flock)) <= 0); \ 122#define xfs_dqfunlock(dqp) { ASSERT(issemalocked(&((dqp)->q_flock))); \
123 vsema(&((dqp)->q_flock)); \ 123 vsema(&((dqp)->q_flock)); \
124 (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); } 124 (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); }
125 125
@@ -128,7 +128,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
128#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \ 128#define XFS_DQ_PINUNLOCK(dqp, s) mutex_spinunlock( \
129 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s) 129 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s)
130 130
131#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (valusema(&((dqp)->q_flock)) <= 0) 131#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock)))
132#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp)) 132#define XFS_DQ_IS_ON_FREELIST(dqp) ((dqp)->dq_flnext != (dqp))
133#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) 133#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY)
134#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) 134#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER)
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index 546f48af882a..5b2dcc58b244 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -248,7 +246,7 @@ xfs_qm_dquot_logitem_pushbuf(
248 * inode flush completed and the inode was taken off the AIL. 246 * inode flush completed and the inode was taken off the AIL.
249 * So, just get out. 247 * So, just get out.
250 */ 248 */
251 if ((valusema(&(dqp->q_flock)) > 0) || 249 if (!issemalocked(&(dqp->q_flock)) ||
252 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { 250 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
253 qip->qli_pushbuf_flag = 0; 251 qip->qli_pushbuf_flag = 0;
254 xfs_dqunlock(dqp); 252 xfs_dqunlock(dqp);
@@ -261,7 +259,7 @@ xfs_qm_dquot_logitem_pushbuf(
261 if (bp != NULL) { 259 if (bp != NULL) {
262 if (XFS_BUF_ISDELAYWRITE(bp)) { 260 if (XFS_BUF_ISDELAYWRITE(bp)) {
263 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && 261 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
264 (valusema(&(dqp->q_flock)) <= 0)); 262 issemalocked(&(dqp->q_flock)));
265 qip->qli_pushbuf_flag = 0; 263 qip->qli_pushbuf_flag = 0;
266 xfs_dqunlock(dqp); 264 xfs_dqunlock(dqp);
267 265
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 7fb5eca9bd50..e23e45535c48 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -1603,7 +1601,7 @@ xfs_qm_dqiterate(
1603 maxlblkcnt - lblkno, 1601 maxlblkcnt - lblkno,
1604 XFS_BMAPI_METADATA, 1602 XFS_BMAPI_METADATA,
1605 NULL, 1603 NULL,
1606 0, map, &nmaps, NULL); 1604 0, map, &nmaps, NULL, NULL);
1607 xfs_iunlock(qip, XFS_ILOCK_SHARED); 1605 xfs_iunlock(qip, XFS_ILOCK_SHARED);
1608 if (error) 1606 if (error)
1609 break; 1607 break;
@@ -1905,9 +1903,7 @@ xfs_qm_quotacheck(
1905 */ 1903 */
1906 if ((error = xfs_bulkstat(mp, &lastino, &count, 1904 if ((error = xfs_bulkstat(mp, &lastino, &count,
1907 xfs_qm_dqusage_adjust, NULL, 1905 xfs_qm_dqusage_adjust, NULL,
1908 structsz, NULL, 1906 structsz, NULL, BULKSTAT_FG_IGET, &done)))
1909 BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
1910 &done)))
1911 break; 1907 break;
1912 1908
1913 } while (! done); 1909 } while (! done);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index 6838b36d95a9..e95e99f7168f 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_alloc.h" 28#include "xfs_alloc.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -129,7 +127,7 @@ xfs_qm_parseargs(
129 return XFS_ERROR(EINVAL); 127 return XFS_ERROR(EINVAL);
130 } 128 }
131 129
132 PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error); 130 error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
133 if (!error && !referenced) 131 if (!error && !referenced)
134 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM); 132 bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
135 return error; 133 return error;
@@ -140,9 +138,8 @@ xfs_qm_showargs(
140 struct bhv_desc *bhv, 138 struct bhv_desc *bhv,
141 struct seq_file *m) 139 struct seq_file *m)
142{ 140{
143 struct vfs *vfsp = bhvtovfs(bhv); 141 struct bhv_vfs *vfsp = bhvtovfs(bhv);
144 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 142 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
145 int error;
146 143
147 if (mp->m_qflags & XFS_UQUOTA_ACCT) { 144 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
148 (mp->m_qflags & XFS_UQUOTA_ENFD) ? 145 (mp->m_qflags & XFS_UQUOTA_ENFD) ?
@@ -165,8 +162,7 @@ xfs_qm_showargs(
165 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) 162 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
166 seq_puts(m, "," MNTOPT_NOQUOTA); 163 seq_puts(m, "," MNTOPT_NOQUOTA);
167 164
168 PVFS_SHOWARGS(BHV_NEXT(bhv), m, error); 165 return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
169 return error;
170} 166}
171 167
172STATIC int 168STATIC int
@@ -175,14 +171,67 @@ xfs_qm_mount(
175 struct xfs_mount_args *args, 171 struct xfs_mount_args *args,
176 struct cred *cr) 172 struct cred *cr)
177{ 173{
178 struct vfs *vfsp = bhvtovfs(bhv); 174 struct bhv_vfs *vfsp = bhvtovfs(bhv);
179 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 175 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
180 int error;
181 176
182 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA)) 177 if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
183 xfs_qm_mount_quotainit(mp, args->flags); 178 xfs_qm_mount_quotainit(mp, args->flags);
184 PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error); 179 return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
185 return error; 180}
181
182/*
183 * Directory tree accounting is implemented using project quotas, where
184 * the project identifier is inherited from parent directories.
185 * A statvfs (df, etc.) of a directory that is using project quota should
186 * return a statvfs of the project, not the entire filesystem.
187 * This makes such trees appear as if they are filesystems in themselves.
188 */
189STATIC int
190xfs_qm_statvfs(
191 struct bhv_desc *bhv,
192 bhv_statvfs_t *statp,
193 struct bhv_vnode *vnode)
194{
195 xfs_mount_t *mp;
196 xfs_inode_t *ip;
197 xfs_dquot_t *dqp;
198 xfs_disk_dquot_t *dp;
199 __uint64_t limit;
200 int error;
201
202 error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
203 if (error || !vnode)
204 return error;
205
206 mp = XFS_BHVTOM(bhv);
207 ip = xfs_vtoi(vnode);
208
209 if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
210 return 0;
211 if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
212 return 0;
213 if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
214 return 0;
215
216 if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
217 return 0;
218 dp = &dqp->q_core;
219
220 limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit;
221 if (limit && statp->f_blocks > limit) {
222 statp->f_blocks = limit;
223 statp->f_bfree = (statp->f_blocks > dp->d_bcount) ?
224 (statp->f_blocks - dp->d_bcount) : 0;
225 }
226 limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit;
227 if (limit && statp->f_files > limit) {
228 statp->f_files = limit;
229 statp->f_ffree = (statp->f_files > dp->d_icount) ?
230 (statp->f_ffree - dp->d_icount) : 0;
231 }
232
233 xfs_qm_dqput(dqp);
234 return 0;
186} 235}
187 236
188STATIC int 237STATIC int
@@ -191,7 +240,7 @@ xfs_qm_syncall(
191 int flags, 240 int flags,
192 cred_t *credp) 241 cred_t *credp)
193{ 242{
194 struct vfs *vfsp = bhvtovfs(bhv); 243 struct bhv_vfs *vfsp = bhvtovfs(bhv);
195 struct xfs_mount *mp = XFS_VFSTOM(vfsp); 244 struct xfs_mount *mp = XFS_VFSTOM(vfsp);
196 int error; 245 int error;
197 246
@@ -210,8 +259,7 @@ xfs_qm_syncall(
210 } 259 }
211 } 260 }
212 } 261 }
213 PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error); 262 return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
214 return error;
215} 263}
216 264
217STATIC int 265STATIC int
@@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = {
346 .xfs_dqtrxops = &xfs_trans_dquot_ops, 394 .xfs_dqtrxops = &xfs_trans_dquot_ops,
347}; 395};
348 396
349struct bhv_vfsops xfs_qmops = { { 397struct bhv_module_vfsops xfs_qmops = { {
350 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM), 398 BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
351 .vfs_parseargs = xfs_qm_parseargs, 399 .vfs_parseargs = xfs_qm_parseargs,
352 .vfs_showargs = xfs_qm_showargs, 400 .vfs_showargs = xfs_qm_showargs,
353 .vfs_mount = xfs_qm_mount, 401 .vfs_mount = xfs_qm_mount,
402 .vfs_statvfs = xfs_qm_statvfs,
354 .vfs_sync = xfs_qm_syncall, 403 .vfs_sync = xfs_qm_syncall,
355 .vfs_quotactl = xfs_qm_quotactl, }, 404 .vfs_quotactl = xfs_qm_quotactl, },
356}; 405};
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c
index 0570f7733550..6f858fb81a36 100644
--- a/fs/xfs/quota/xfs_qm_stats.c
+++ b/fs/xfs/quota/xfs_qm_stats.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index c55db463bbf2..ed620c4d1594 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -26,7 +26,6 @@
26#include "xfs_trans.h" 26#include "xfs_trans.h"
27#include "xfs_sb.h" 27#include "xfs_sb.h"
28#include "xfs_ag.h" 28#include "xfs_ag.h"
29#include "xfs_dir.h"
30#include "xfs_dir2.h" 29#include "xfs_dir2.h"
31#include "xfs_alloc.h" 30#include "xfs_alloc.h"
32#include "xfs_dmapi.h" 31#include "xfs_dmapi.h"
@@ -35,7 +34,6 @@
35#include "xfs_bmap_btree.h" 34#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 35#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 36#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 37#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 38#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 39#include "xfs_dinode.h"
@@ -91,8 +89,8 @@ xfs_qm_quotactl(
91 xfs_caddr_t addr) 89 xfs_caddr_t addr)
92{ 90{
93 xfs_mount_t *mp; 91 xfs_mount_t *mp;
92 bhv_vfs_t *vfsp;
94 int error; 93 int error;
95 struct vfs *vfsp;
96 94
97 vfsp = bhvtovfs(bdp); 95 vfsp = bhvtovfs(bdp);
98 mp = XFS_VFSTOM(vfsp); 96 mp = XFS_VFSTOM(vfsp);
@@ -1035,7 +1033,7 @@ xfs_qm_dqrele_all_inodes(
1035{ 1033{
1036 xfs_inode_t *ip, *topino; 1034 xfs_inode_t *ip, *topino;
1037 uint ireclaims; 1035 uint ireclaims;
1038 vnode_t *vp; 1036 bhv_vnode_t *vp;
1039 boolean_t vnode_refd; 1037 boolean_t vnode_refd;
1040 1038
1041 ASSERT(mp->m_quotainfo); 1039 ASSERT(mp->m_quotainfo);
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 9168918db252..0242e9666e8e 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
39#include "xfs_inode.h" 37#include "xfs_inode.h"
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index b08b3d9345b7..36fbeccdc722 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -47,7 +47,7 @@ cmn_err(register int level, char *fmt, ...)
47 va_start(ap, fmt); 47 va_start(ap, fmt);
48 if (*fmt == '!') fp++; 48 if (*fmt == '!') fp++;
49 len = vsprintf(message, fp, ap); 49 len = vsprintf(message, fp, ap);
50 if (message[len-1] != '\n') 50 if (level != CE_DEBUG && message[len-1] != '\n')
51 strcat(message, "\n"); 51 strcat(message, "\n");
52 printk("%s%s", err_level[level], message); 52 printk("%s%s", err_level[level], message);
53 va_end(ap); 53 va_end(ap);
@@ -68,7 +68,7 @@ icmn_err(register int level, char *fmt, va_list ap)
68 level = XFS_MAX_ERR_LEVEL; 68 level = XFS_MAX_ERR_LEVEL;
69 spin_lock_irqsave(&xfs_err_lock,flags); 69 spin_lock_irqsave(&xfs_err_lock,flags);
70 len = vsprintf(message, fmt, ap); 70 len = vsprintf(message, fmt, ap);
71 if (message[len-1] != '\n') 71 if (level != CE_DEBUG && message[len-1] != '\n')
72 strcat(message, "\n"); 72 strcat(message, "\n");
73 spin_unlock_irqrestore(&xfs_err_lock,flags); 73 spin_unlock_irqrestore(&xfs_err_lock,flags);
74 printk("%s%s", err_level[level], message); 74 printk("%s%s", err_level[level], message);
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
index e3bf58112e7e..4f54dca662a8 100644
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...)
33 __attribute__ ((format (printf, 2, 3))); 33 __attribute__ ((format (printf, 2, 3)));
34extern void assfail(char *expr, char *f, int l); 34extern void assfail(char *expr, char *f, int l);
35 35
36#define prdev(fmt,targ,args...) \
37 printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
38
39#define ASSERT_ALWAYS(expr) \ 36#define ASSERT_ALWAYS(expr) \
40 (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 37 (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
41 38
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 2539af34eb63..4b0cb474be4c 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -21,12 +21,10 @@
21#include "xfs_bit.h" 21#include "xfs_bit.h"
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_ag.h" 23#include "xfs_ag.h"
24#include "xfs_dir.h"
25#include "xfs_dir2.h" 24#include "xfs_dir2.h"
26#include "xfs_bmap_btree.h" 25#include "xfs_bmap_btree.h"
27#include "xfs_alloc_btree.h" 26#include "xfs_alloc_btree.h"
28#include "xfs_ialloc_btree.h" 27#include "xfs_ialloc_btree.h"
29#include "xfs_dir_sf.h"
30#include "xfs_dir2_sf.h" 28#include "xfs_dir2_sf.h"
31#include "xfs_attr_sf.h" 29#include "xfs_attr_sf.h"
32#include "xfs_dinode.h" 30#include "xfs_dinode.h"
@@ -39,15 +37,15 @@
39#include <linux/capability.h> 37#include <linux/capability.h>
40#include <linux/posix_acl_xattr.h> 38#include <linux/posix_acl_xattr.h>
41 39
42STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *); 40STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *);
43STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); 41STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *);
44STATIC void xfs_acl_get_endian(xfs_acl_t *); 42STATIC void xfs_acl_get_endian(xfs_acl_t *);
45STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); 43STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
46STATIC int xfs_acl_invalid(xfs_acl_t *); 44STATIC int xfs_acl_invalid(xfs_acl_t *);
47STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); 45STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *);
48STATIC void xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *); 46STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *);
49STATIC void xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *); 47STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *);
50STATIC int xfs_acl_allow_set(vnode_t *, int); 48STATIC int xfs_acl_allow_set(bhv_vnode_t *, int);
51 49
52kmem_zone_t *xfs_acl_zone; 50kmem_zone_t *xfs_acl_zone;
53 51
@@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone;
57 */ 55 */
58int 56int
59xfs_acl_vhasacl_access( 57xfs_acl_vhasacl_access(
60 vnode_t *vp) 58 bhv_vnode_t *vp)
61{ 59{
62 int error; 60 int error;
63 61
@@ -70,7 +68,7 @@ xfs_acl_vhasacl_access(
70 */ 68 */
71int 69int
72xfs_acl_vhasacl_default( 70xfs_acl_vhasacl_default(
73 vnode_t *vp) 71 bhv_vnode_t *vp)
74{ 72{
75 int error; 73 int error;
76 74
@@ -209,7 +207,7 @@ posix_acl_xfs_to_xattr(
209 207
210int 208int
211xfs_acl_vget( 209xfs_acl_vget(
212 vnode_t *vp, 210 bhv_vnode_t *vp,
213 void *acl, 211 void *acl,
214 size_t size, 212 size_t size,
215 int kind) 213 int kind)
@@ -241,10 +239,10 @@ xfs_acl_vget(
241 goto out; 239 goto out;
242 } 240 }
243 if (kind == _ACL_TYPE_ACCESS) { 241 if (kind == _ACL_TYPE_ACCESS) {
244 vattr_t va; 242 bhv_vattr_t va;
245 243
246 va.va_mask = XFS_AT_MODE; 244 va.va_mask = XFS_AT_MODE;
247 VOP_GETATTR(vp, &va, 0, sys_cred, error); 245 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
248 if (error) 246 if (error)
249 goto out; 247 goto out;
250 xfs_acl_sync_mode(va.va_mode, xfs_acl); 248 xfs_acl_sync_mode(va.va_mode, xfs_acl);
@@ -260,7 +258,7 @@ out:
260 258
261int 259int
262xfs_acl_vremove( 260xfs_acl_vremove(
263 vnode_t *vp, 261 bhv_vnode_t *vp,
264 int kind) 262 int kind)
265{ 263{
266 int error; 264 int error;
@@ -268,9 +266,9 @@ xfs_acl_vremove(
268 VN_HOLD(vp); 266 VN_HOLD(vp);
269 error = xfs_acl_allow_set(vp, kind); 267 error = xfs_acl_allow_set(vp, kind);
270 if (!error) { 268 if (!error) {
271 VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT? 269 error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT?
272 SGI_ACL_DEFAULT: SGI_ACL_FILE, 270 SGI_ACL_DEFAULT: SGI_ACL_FILE,
273 ATTR_ROOT, sys_cred, error); 271 ATTR_ROOT, sys_cred);
274 if (error == ENOATTR) 272 if (error == ENOATTR)
275 error = 0; /* 'scool */ 273 error = 0; /* 'scool */
276 } 274 }
@@ -280,7 +278,7 @@ xfs_acl_vremove(
280 278
281int 279int
282xfs_acl_vset( 280xfs_acl_vset(
283 vnode_t *vp, 281 bhv_vnode_t *vp,
284 void *acl, 282 void *acl,
285 size_t size, 283 size_t size,
286 int kind) 284 int kind)
@@ -370,10 +368,10 @@ xfs_acl_iaccess(
370 368
371STATIC int 369STATIC int
372xfs_acl_allow_set( 370xfs_acl_allow_set(
373 vnode_t *vp, 371 bhv_vnode_t *vp,
374 int kind) 372 int kind)
375{ 373{
376 vattr_t va; 374 bhv_vattr_t va;
377 int error; 375 int error;
378 376
379 if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) 377 if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
@@ -383,7 +381,7 @@ xfs_acl_allow_set(
383 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 381 if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
384 return EROFS; 382 return EROFS;
385 va.va_mask = XFS_AT_UID; 383 va.va_mask = XFS_AT_UID;
386 VOP_GETATTR(vp, &va, 0, NULL, error); 384 error = bhv_vop_getattr(vp, &va, 0, NULL);
387 if (error) 385 if (error)
388 return error; 386 return error;
389 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER)) 387 if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
@@ -606,7 +604,7 @@ xfs_acl_get_endian(
606 */ 604 */
607STATIC void 605STATIC void
608xfs_acl_get_attr( 606xfs_acl_get_attr(
609 vnode_t *vp, 607 bhv_vnode_t *vp,
610 xfs_acl_t *aclp, 608 xfs_acl_t *aclp,
611 int kind, 609 int kind,
612 int flags, 610 int flags,
@@ -616,9 +614,9 @@ xfs_acl_get_attr(
616 614
617 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); 615 ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
618 flags |= ATTR_ROOT; 616 flags |= ATTR_ROOT;
619 VOP_ATTR_GET(vp, 617 *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ?
620 kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT, 618 SGI_ACL_FILE : SGI_ACL_DEFAULT,
621 (char *)aclp, &len, flags, sys_cred, *error); 619 (char *)aclp, &len, flags, sys_cred);
622 if (*error || (flags & ATTR_KERNOVAL)) 620 if (*error || (flags & ATTR_KERNOVAL))
623 return; 621 return;
624 xfs_acl_get_endian(aclp); 622 xfs_acl_get_endian(aclp);
@@ -629,7 +627,7 @@ xfs_acl_get_attr(
629 */ 627 */
630STATIC void 628STATIC void
631xfs_acl_set_attr( 629xfs_acl_set_attr(
632 vnode_t *vp, 630 bhv_vnode_t *vp,
633 xfs_acl_t *aclp, 631 xfs_acl_t *aclp,
634 int kind, 632 int kind,
635 int *error) 633 int *error)
@@ -654,19 +652,19 @@ xfs_acl_set_attr(
654 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm); 652 INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
655 } 653 }
656 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt); 654 INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
657 VOP_ATTR_SET(vp, 655 *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ?
658 kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT, 656 SGI_ACL_FILE: SGI_ACL_DEFAULT,
659 (char *)newacl, len, ATTR_ROOT, sys_cred, *error); 657 (char *)newacl, len, ATTR_ROOT, sys_cred);
660 _ACL_FREE(newacl); 658 _ACL_FREE(newacl);
661} 659}
662 660
663int 661int
664xfs_acl_vtoacl( 662xfs_acl_vtoacl(
665 vnode_t *vp, 663 bhv_vnode_t *vp,
666 xfs_acl_t *access_acl, 664 xfs_acl_t *access_acl,
667 xfs_acl_t *default_acl) 665 xfs_acl_t *default_acl)
668{ 666{
669 vattr_t va; 667 bhv_vattr_t va;
670 int error = 0; 668 int error = 0;
671 669
672 if (access_acl) { 670 if (access_acl) {
@@ -678,7 +676,7 @@ xfs_acl_vtoacl(
678 if (!error) { 676 if (!error) {
679 /* Got the ACL, need the mode... */ 677 /* Got the ACL, need the mode... */
680 va.va_mask = XFS_AT_MODE; 678 va.va_mask = XFS_AT_MODE;
681 VOP_GETATTR(vp, &va, 0, sys_cred, error); 679 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
682 } 680 }
683 681
684 if (error) 682 if (error)
@@ -701,8 +699,8 @@ xfs_acl_vtoacl(
701 */ 699 */
702int 700int
703xfs_acl_inherit( 701xfs_acl_inherit(
704 vnode_t *vp, 702 bhv_vnode_t *vp,
705 vattr_t *vap, 703 bhv_vattr_t *vap,
706 xfs_acl_t *pdaclp) 704 xfs_acl_t *pdaclp)
707{ 705{
708 xfs_acl_t *cacl; 706 xfs_acl_t *cacl;
@@ -757,11 +755,11 @@ xfs_acl_inherit(
757 */ 755 */
758STATIC int 756STATIC int
759xfs_acl_setmode( 757xfs_acl_setmode(
760 vnode_t *vp, 758 bhv_vnode_t *vp,
761 xfs_acl_t *acl, 759 xfs_acl_t *acl,
762 int *basicperms) 760 int *basicperms)
763{ 761{
764 vattr_t va; 762 bhv_vattr_t va;
765 xfs_acl_entry_t *ap; 763 xfs_acl_entry_t *ap;
766 xfs_acl_entry_t *gap = NULL; 764 xfs_acl_entry_t *gap = NULL;
767 int i, error, nomask = 1; 765 int i, error, nomask = 1;
@@ -776,7 +774,7 @@ xfs_acl_setmode(
776 * mode. The m:: bits take precedence over the g:: bits. 774 * mode. The m:: bits take precedence over the g:: bits.
777 */ 775 */
778 va.va_mask = XFS_AT_MODE; 776 va.va_mask = XFS_AT_MODE;
779 VOP_GETATTR(vp, &va, 0, sys_cred, error); 777 error = bhv_vop_getattr(vp, &va, 0, sys_cred);
780 if (error) 778 if (error)
781 return error; 779 return error;
782 780
@@ -810,8 +808,7 @@ xfs_acl_setmode(
810 if (gap && nomask) 808 if (gap && nomask)
811 va.va_mode |= gap->ae_perm << 3; 809 va.va_mode |= gap->ae_perm << 3;
812 810
813 VOP_SETATTR(vp, &va, 0, sys_cred, error); 811 return bhv_vop_setattr(vp, &va, 0, sys_cred);
814 return error;
815} 812}
816 813
817/* 814/*
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 538d0d65b04c..f853cf1a6270 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -50,7 +50,7 @@ typedef struct xfs_acl {
50#ifdef CONFIG_XFS_POSIX_ACL 50#ifdef CONFIG_XFS_POSIX_ACL
51 51
52struct vattr; 52struct vattr;
53struct vnode; 53struct bhv_vnode;
54struct xfs_inode; 54struct xfs_inode;
55 55
56extern struct kmem_zone *xfs_acl_zone; 56extern struct kmem_zone *xfs_acl_zone;
@@ -58,14 +58,14 @@ extern struct kmem_zone *xfs_acl_zone;
58 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name)) 58 (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
59#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone) 59#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
60 60
61extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *); 61extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *);
62extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); 62extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
63extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *); 63extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
64extern int xfs_acl_vhasacl_access(struct vnode *); 64extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
65extern int xfs_acl_vhasacl_default(struct vnode *); 65extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
66extern int xfs_acl_vset(struct vnode *, void *, size_t, int); 66extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
67extern int xfs_acl_vget(struct vnode *, void *, size_t, int); 67extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
68extern int xfs_acl_vremove(struct vnode *vp, int); 68extern int xfs_acl_vremove(struct bhv_vnode *, int);
69 69
70#define _ACL_TYPE_ACCESS 1 70#define _ACL_TYPE_ACCESS 1
71#define _ACL_TYPE_DEFAULT 2 71#define _ACL_TYPE_DEFAULT 2
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 8558226281c4..eef6763f3a67 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist(
1862 (pag->pagf_longest - delta) : 1860 (pag->pagf_longest - delta) :
1863 (pag->pagf_flcount > 0 || pag->pagf_longest > 0); 1861 (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
1864 if (args->minlen + args->alignment + args->minalignslop - 1 > longest || 1862 if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
1865 (args->minleft && 1863 (!(flags & XFS_ALLOC_FLAG_FREEING) &&
1866 (int)(pag->pagf_freeblks + pag->pagf_flcount - 1864 (int)(pag->pagf_freeblks + pag->pagf_flcount -
1867 need - args->total) < 1865 need - args->total) <
1868 (int)args->minleft)) { 1866 (int)args->minleft)) {
@@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist(
1898 longest = (longest > delta) ? (longest - delta) : 1896 longest = (longest > delta) ? (longest - delta) :
1899 (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); 1897 (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
1900 if (args->minlen + args->alignment + args->minalignslop - 1 > longest || 1898 if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
1901 (args->minleft && 1899 (!(flags & XFS_ALLOC_FLAG_FREEING) &&
1902 (int)(be32_to_cpu(agf->agf_freeblks) + 1900 (int)(be32_to_cpu(agf->agf_freeblks) +
1903 be32_to_cpu(agf->agf_flcount) - need - args->total) < 1901 be32_to_cpu(agf->agf_flcount) - need - args->total) <
1904 (int)args->minleft)) { 1902 (int)args->minleft)) {
@@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist(
1951 * the restrictions correctly. Can happen for free calls 1949 * the restrictions correctly. Can happen for free calls
1952 * on a completely full ag. 1950 * on a completely full ag.
1953 */ 1951 */
1954 if (targs.agbno == NULLAGBLOCK) 1952 if (targs.agbno == NULLAGBLOCK) {
1953 if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
1954 xfs_trans_brelse(tp, agflbp);
1955 args->agbp = NULL;
1956 return 0;
1957 }
1955 break; 1958 break;
1959 }
1956 /* 1960 /*
1957 * Put each allocated block on the list. 1961 * Put each allocated block on the list.
1958 */ 1962 */
@@ -2360,8 +2364,19 @@ xfs_alloc_vextent(
2360 if (args->agno == sagno && 2364 if (args->agno == sagno &&
2361 type == XFS_ALLOCTYPE_START_BNO) 2365 type == XFS_ALLOCTYPE_START_BNO)
2362 args->type = XFS_ALLOCTYPE_THIS_AG; 2366 args->type = XFS_ALLOCTYPE_THIS_AG;
2363 if (++(args->agno) == mp->m_sb.sb_agcount) 2367 /*
2364 args->agno = 0; 2368 * For the first allocation, we can try any AG to get
2369 * space. However, if we already have allocated a
2370 * block, we don't want to try AGs whose number is below
2371 * sagno. Otherwise, we may end up with out-of-order
2372 * locking of AGF, which might cause deadlock.
2373 */
2374 if (++(args->agno) == mp->m_sb.sb_agcount) {
2375 if (args->firstblock != NULLFSBLOCK)
2376 args->agno = sagno;
2377 else
2378 args->agno = 0;
2379 }
2365 /* 2380 /*
2366 * Reached the starting a.g., must either be done 2381 * Reached the starting a.g., must either be done
2367 * or switch to non-trylock mode. 2382 * or switch to non-trylock mode.
@@ -2443,7 +2458,7 @@ xfs_free_extent(
2443 args.minlen = args.minleft = args.minalignslop = 0; 2458 args.minlen = args.minleft = args.minalignslop = 0;
2444 down_read(&args.mp->m_peraglock); 2459 down_read(&args.mp->m_peraglock);
2445 args.pag = &args.mp->m_perag[args.agno]; 2460 args.pag = &args.mp->m_perag[args.agno];
2446 if ((error = xfs_alloc_fix_freelist(&args, 0))) 2461 if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
2447 goto error0; 2462 goto error0;
2448#ifdef DEBUG 2463#ifdef DEBUG
2449 ASSERT(args.agbp != NULL); 2464 ASSERT(args.agbp != NULL);
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 2d1f8928b267..650591f999ae 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -41,6 +41,7 @@ typedef enum xfs_alloctype
41 * Flags for xfs_alloc_fix_freelist. 41 * Flags for xfs_alloc_fix_freelist.
42 */ 42 */
43#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ 43#define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */
44#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
44 45
45/* 46/*
46 * Argument structure for xfs_alloc routines. 47 * Argument structure for xfs_alloc routines.
@@ -70,6 +71,7 @@ typedef struct xfs_alloc_arg {
70 char wasfromfl; /* set if allocation is from freelist */ 71 char wasfromfl; /* set if allocation is from freelist */
71 char isfl; /* set if is freelist blocks - !acctg */ 72 char isfl; /* set if is freelist blocks - !acctg */
72 char userdata; /* set if this is user data */ 73 char userdata; /* set if this is user data */
74 xfs_fsblock_t firstblock; /* io first block allocated */
73} xfs_alloc_arg_t; 75} xfs_alloc_arg_t;
74 76
75/* 77/*
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index a1d92da86ccd..7446556e8021 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index b6e1e02bbb28..1a2101043275 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -27,7 +27,6 @@
27#include "xfs_trans.h" 27#include "xfs_trans.h"
28#include "xfs_sb.h" 28#include "xfs_sb.h"
29#include "xfs_ag.h" 29#include "xfs_ag.h"
30#include "xfs_dir.h"
31#include "xfs_dir2.h" 30#include "xfs_dir2.h"
32#include "xfs_dmapi.h" 31#include "xfs_dmapi.h"
33#include "xfs_mount.h" 32#include "xfs_mount.h"
@@ -35,7 +34,6 @@
35#include "xfs_bmap_btree.h" 34#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 35#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 36#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 37#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 38#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 39#include "xfs_dinode.h"
@@ -1910,7 +1908,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
1910 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno, 1908 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
1911 args->rmtblkcnt, 1909 args->rmtblkcnt,
1912 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 1910 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
1913 NULL, 0, map, &nmap, NULL); 1911 NULL, 0, map, &nmap, NULL, NULL);
1914 if (error) 1912 if (error)
1915 return(error); 1913 return(error);
1916 ASSERT(nmap >= 1); 1914 ASSERT(nmap >= 1);
@@ -1988,7 +1986,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
1988 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | 1986 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
1989 XFS_BMAPI_WRITE, 1987 XFS_BMAPI_WRITE,
1990 args->firstblock, args->total, &map, &nmap, 1988 args->firstblock, args->total, &map, &nmap,
1991 args->flist); 1989 args->flist, NULL);
1992 if (!error) { 1990 if (!error) {
1993 error = xfs_bmap_finish(&args->trans, args->flist, 1991 error = xfs_bmap_finish(&args->trans, args->flist,
1994 *args->firstblock, &committed); 1992 *args->firstblock, &committed);
@@ -2039,7 +2037,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
2039 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno, 2037 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
2040 args->rmtblkcnt, 2038 args->rmtblkcnt,
2041 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2039 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2042 args->firstblock, 0, &map, &nmap, NULL); 2040 args->firstblock, 0, &map, &nmap,
2041 NULL, NULL);
2043 if (error) { 2042 if (error) {
2044 return(error); 2043 return(error);
2045 } 2044 }
@@ -2104,7 +2103,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2104 args->rmtblkcnt, 2103 args->rmtblkcnt,
2105 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2104 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2106 args->firstblock, 0, &map, &nmap, 2105 args->firstblock, 0, &map, &nmap,
2107 args->flist); 2106 args->flist, NULL);
2108 if (error) { 2107 if (error) {
2109 return(error); 2108 return(error);
2110 } 2109 }
@@ -2142,7 +2141,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
2142 XFS_BMAP_INIT(args->flist, args->firstblock); 2141 XFS_BMAP_INIT(args->flist, args->firstblock);
2143 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, 2142 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
2144 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2143 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2145 1, args->firstblock, args->flist, &done); 2144 1, args->firstblock, args->flist,
2145 NULL, &done);
2146 if (!error) { 2146 if (!error) {
2147 error = xfs_bmap_finish(&args->trans, args->flist, 2147 error = xfs_bmap_finish(&args->trans, args->flist,
2148 *args->firstblock, &committed); 2148 *args->firstblock, &committed);
@@ -2322,56 +2322,56 @@ xfs_attr_trace_enter(int type, char *where,
2322 2322
2323STATIC int 2323STATIC int
2324posix_acl_access_set( 2324posix_acl_access_set(
2325 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2325 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2326{ 2326{
2327 return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS); 2327 return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
2328} 2328}
2329 2329
2330STATIC int 2330STATIC int
2331posix_acl_access_remove( 2331posix_acl_access_remove(
2332 struct vnode *vp, char *name, int xflags) 2332 bhv_vnode_t *vp, char *name, int xflags)
2333{ 2333{
2334 return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); 2334 return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
2335} 2335}
2336 2336
2337STATIC int 2337STATIC int
2338posix_acl_access_get( 2338posix_acl_access_get(
2339 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2339 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2340{ 2340{
2341 return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); 2341 return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
2342} 2342}
2343 2343
2344STATIC int 2344STATIC int
2345posix_acl_access_exists( 2345posix_acl_access_exists(
2346 vnode_t *vp) 2346 bhv_vnode_t *vp)
2347{ 2347{
2348 return xfs_acl_vhasacl_access(vp); 2348 return xfs_acl_vhasacl_access(vp);
2349} 2349}
2350 2350
2351STATIC int 2351STATIC int
2352posix_acl_default_set( 2352posix_acl_default_set(
2353 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2353 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2354{ 2354{
2355 return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT); 2355 return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
2356} 2356}
2357 2357
2358STATIC int 2358STATIC int
2359posix_acl_default_get( 2359posix_acl_default_get(
2360 vnode_t *vp, char *name, void *data, size_t size, int xflags) 2360 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2361{ 2361{
2362 return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); 2362 return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
2363} 2363}
2364 2364
2365STATIC int 2365STATIC int
2366posix_acl_default_remove( 2366posix_acl_default_remove(
2367 struct vnode *vp, char *name, int xflags) 2367 bhv_vnode_t *vp, char *name, int xflags)
2368{ 2368{
2369 return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); 2369 return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
2370} 2370}
2371 2371
2372STATIC int 2372STATIC int
2373posix_acl_default_exists( 2373posix_acl_default_exists(
2374 vnode_t *vp) 2374 bhv_vnode_t *vp)
2375{ 2375{
2376 return xfs_acl_vhasacl_default(vp); 2376 return xfs_acl_vhasacl_default(vp);
2377} 2377}
@@ -2404,21 +2404,18 @@ STATIC struct attrnames *attr_system_names[] =
2404 2404
2405STATIC int 2405STATIC int
2406attr_generic_set( 2406attr_generic_set(
2407 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2407 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2408{ 2408{
2409 int error; 2409 return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL);
2410
2411 VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
2412 return -error;
2413} 2410}
2414 2411
2415STATIC int 2412STATIC int
2416attr_generic_get( 2413attr_generic_get(
2417 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2414 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2418{ 2415{
2419 int error, asize = size; 2416 int error, asize = size;
2420 2417
2421 VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error); 2418 error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL);
2422 if (!error) 2419 if (!error)
2423 return asize; 2420 return asize;
2424 return -error; 2421 return -error;
@@ -2426,12 +2423,9 @@ attr_generic_get(
2426 2423
2427STATIC int 2424STATIC int
2428attr_generic_remove( 2425attr_generic_remove(
2429 struct vnode *vp, char *name, int xflags) 2426 bhv_vnode_t *vp, char *name, int xflags)
2430{ 2427{
2431 int error; 2428 return -bhv_vop_attr_remove(vp, name, xflags, NULL);
2432
2433 VOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
2434 return -error;
2435} 2429}
2436 2430
2437STATIC int 2431STATIC int
@@ -2459,7 +2453,7 @@ attr_generic_listadd(
2459 2453
2460STATIC int 2454STATIC int
2461attr_system_list( 2455attr_system_list(
2462 struct vnode *vp, 2456 bhv_vnode_t *vp,
2463 void *data, 2457 void *data,
2464 size_t size, 2458 size_t size,
2465 ssize_t *result) 2459 ssize_t *result)
@@ -2481,12 +2475,12 @@ attr_system_list(
2481 2475
2482int 2476int
2483attr_generic_list( 2477attr_generic_list(
2484 struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result) 2478 bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
2485{ 2479{
2486 attrlist_cursor_kern_t cursor = { 0 }; 2480 attrlist_cursor_kern_t cursor = { 0 };
2487 int error; 2481 int error;
2488 2482
2489 VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); 2483 error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL);
2490 if (error > 0) 2484 if (error > 0)
2491 return -error; 2485 return -error;
2492 *result = -error; 2486 *result = -error;
@@ -2514,7 +2508,7 @@ attr_lookup_namespace(
2514 */ 2508 */
2515STATIC int 2509STATIC int
2516attr_user_capable( 2510attr_user_capable(
2517 struct vnode *vp, 2511 bhv_vnode_t *vp,
2518 cred_t *cred) 2512 cred_t *cred)
2519{ 2513{
2520 struct inode *inode = vn_to_inode(vp); 2514 struct inode *inode = vn_to_inode(vp);
@@ -2532,7 +2526,7 @@ attr_user_capable(
2532 2526
2533STATIC int 2527STATIC int
2534attr_trusted_capable( 2528attr_trusted_capable(
2535 struct vnode *vp, 2529 bhv_vnode_t *vp,
2536 cred_t *cred) 2530 cred_t *cred)
2537{ 2531{
2538 struct inode *inode = vn_to_inode(vp); 2532 struct inode *inode = vn_to_inode(vp);
@@ -2546,7 +2540,7 @@ attr_trusted_capable(
2546 2540
2547STATIC int 2541STATIC int
2548attr_secure_capable( 2542attr_secure_capable(
2549 struct vnode *vp, 2543 bhv_vnode_t *vp,
2550 cred_t *cred) 2544 cred_t *cred)
2551{ 2545{
2552 return -ENOSECURITY; 2546 return -ENOSECURITY;
@@ -2554,7 +2548,7 @@ attr_secure_capable(
2554 2548
2555STATIC int 2549STATIC int
2556attr_system_set( 2550attr_system_set(
2557 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2551 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2558{ 2552{
2559 attrnames_t *namesp; 2553 attrnames_t *namesp;
2560 int error; 2554 int error;
@@ -2573,7 +2567,7 @@ attr_system_set(
2573 2567
2574STATIC int 2568STATIC int
2575attr_system_get( 2569attr_system_get(
2576 struct vnode *vp, char *name, void *data, size_t size, int xflags) 2570 bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
2577{ 2571{
2578 attrnames_t *namesp; 2572 attrnames_t *namesp;
2579 2573
@@ -2585,7 +2579,7 @@ attr_system_get(
2585 2579
2586STATIC int 2580STATIC int
2587attr_system_remove( 2581attr_system_remove(
2588 struct vnode *vp, char *name, int xflags) 2582 bhv_vnode_t *vp, char *name, int xflags)
2589{ 2583{
2590 attrnames_t *namesp; 2584 attrnames_t *namesp;
2591 2585
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
index b2c7b9fcded3..981633f6c077 100644
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -36,13 +36,13 @@
36 *========================================================================*/ 36 *========================================================================*/
37 37
38struct cred; 38struct cred;
39struct vnode; 39struct bhv_vnode;
40 40
41typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int); 41typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
42typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int); 42typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
43typedef int (*attrremove_t)(struct vnode *, char *, int); 43typedef int (*attrremove_t)(struct bhv_vnode *, char *, int);
44typedef int (*attrexists_t)(struct vnode *); 44typedef int (*attrexists_t)(struct bhv_vnode *);
45typedef int (*attrcapable_t)(struct vnode *, struct cred *); 45typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *);
46 46
47typedef struct attrnames { 47typedef struct attrnames {
48 char * attr_name; 48 char * attr_name;
@@ -63,7 +63,7 @@ extern struct attrnames attr_trusted;
63extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; 63extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
64 64
65extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); 65extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
66extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); 66extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *);
67 67
68#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ 68#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */
69#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ 69#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 9462be86aa14..9455051f0120 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -34,7 +33,6 @@
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_alloc.h" 34#include "xfs_alloc.h"
36#include "xfs_btree.h" 35#include "xfs_btree.h"
37#include "xfs_dir_sf.h"
38#include "xfs_dir2_sf.h" 36#include "xfs_dir2_sf.h"
39#include "xfs_attr_sf.h" 37#include "xfs_attr_sf.h"
40#include "xfs_dinode.h" 38#include "xfs_dinode.h"
@@ -2990,7 +2988,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
2990 nmap = 1; 2988 nmap = 1;
2991 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt, 2989 error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
2992 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, 2990 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2993 NULL, 0, &map, &nmap, NULL); 2991 NULL, 0, &map, &nmap, NULL, NULL);
2994 if (error) { 2992 if (error) {
2995 return(error); 2993 return(error);
2996 } 2994 }
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 26939d364bc4..3a6137539064 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,13 +24,11 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h" 30#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h" 31#include "xfs_ialloc_btree.h"
33#include "xfs_dir_sf.h"
34#include "xfs_dir2_sf.h" 32#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h" 33#include "xfs_attr_sf.h"
36#include "xfs_dinode.h" 34#include "xfs_dinode.h"
@@ -40,13 +38,15 @@
40#include "xfs_mount.h" 38#include "xfs_mount.h"
41#include "xfs_ialloc.h" 39#include "xfs_ialloc.h"
42#include "xfs_itable.h" 40#include "xfs_itable.h"
41#include "xfs_dir2_data.h"
42#include "xfs_dir2_leaf.h"
43#include "xfs_dir2_block.h"
43#include "xfs_inode_item.h" 44#include "xfs_inode_item.h"
44#include "xfs_extfree_item.h" 45#include "xfs_extfree_item.h"
45#include "xfs_alloc.h" 46#include "xfs_alloc.h"
46#include "xfs_bmap.h" 47#include "xfs_bmap.h"
47#include "xfs_rtalloc.h" 48#include "xfs_rtalloc.h"
48#include "xfs_error.h" 49#include "xfs_error.h"
49#include "xfs_dir_leaf.h"
50#include "xfs_attr_leaf.h" 50#include "xfs_attr_leaf.h"
51#include "xfs_rw.h" 51#include "xfs_rw.h"
52#include "xfs_quota.h" 52#include "xfs_quota.h"
@@ -101,6 +101,7 @@ xfs_bmap_add_extent(
101 xfs_fsblock_t *first, /* pointer to firstblock variable */ 101 xfs_fsblock_t *first, /* pointer to firstblock variable */
102 xfs_bmap_free_t *flist, /* list of extents to be freed */ 102 xfs_bmap_free_t *flist, /* list of extents to be freed */
103 int *logflagsp, /* inode logging flags */ 103 int *logflagsp, /* inode logging flags */
104 xfs_extdelta_t *delta, /* Change made to incore extents */
104 int whichfork, /* data or attr fork */ 105 int whichfork, /* data or attr fork */
105 int rsvd); /* OK to allocate reserved blocks */ 106 int rsvd); /* OK to allocate reserved blocks */
106 107
@@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(
118 xfs_fsblock_t *first, /* pointer to firstblock variable */ 119 xfs_fsblock_t *first, /* pointer to firstblock variable */
119 xfs_bmap_free_t *flist, /* list of extents to be freed */ 120 xfs_bmap_free_t *flist, /* list of extents to be freed */
120 int *logflagsp, /* inode logging flags */ 121 int *logflagsp, /* inode logging flags */
122 xfs_extdelta_t *delta, /* Change made to incore extents */
121 int rsvd); /* OK to allocate reserved blocks */ 123 int rsvd); /* OK to allocate reserved blocks */
122 124
123/* 125/*
@@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(
131 xfs_btree_cur_t *cur, /* if null, not a btree */ 133 xfs_btree_cur_t *cur, /* if null, not a btree */
132 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 134 xfs_bmbt_irec_t *new, /* new data to add to file extents */
133 int *logflagsp,/* inode logging flags */ 135 int *logflagsp,/* inode logging flags */
136 xfs_extdelta_t *delta, /* Change made to incore extents */
134 int rsvd); /* OK to allocate reserved blocks */ 137 int rsvd); /* OK to allocate reserved blocks */
135 138
136/* 139/*
@@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(
144 xfs_btree_cur_t *cur, /* if null, not a btree */ 147 xfs_btree_cur_t *cur, /* if null, not a btree */
145 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 148 xfs_bmbt_irec_t *new, /* new data to add to file extents */
146 int *logflagsp, /* inode logging flags */ 149 int *logflagsp, /* inode logging flags */
150 xfs_extdelta_t *delta, /* Change made to incore extents */
147 int whichfork); /* data or attr fork */ 151 int whichfork); /* data or attr fork */
148 152
149/* 153/*
@@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(
156 xfs_extnum_t idx, /* extent number to update/insert */ 160 xfs_extnum_t idx, /* extent number to update/insert */
157 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 161 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
158 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 162 xfs_bmbt_irec_t *new, /* new data to add to file extents */
159 int *logflagsp); /* inode logging flags */ 163 int *logflagsp, /* inode logging flags */
164 xfs_extdelta_t *delta); /* Change made to incore extents */
160 165
161/* 166/*
162 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. 167 * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
@@ -203,6 +208,7 @@ xfs_bmap_del_extent(
203 xfs_btree_cur_t *cur, /* if null, not a btree */ 208 xfs_btree_cur_t *cur, /* if null, not a btree */
204 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 209 xfs_bmbt_irec_t *new, /* new data to add to file extents */
205 int *logflagsp,/* inode logging flags */ 210 int *logflagsp,/* inode logging flags */
211 xfs_extdelta_t *delta, /* Change made to incore extents */
206 int whichfork, /* data or attr fork */ 212 int whichfork, /* data or attr fork */
207 int rsvd); /* OK to allocate reserved blocks */ 213 int rsvd); /* OK to allocate reserved blocks */
208 214
@@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local(
510 dargs.total = mp->m_dirblkfsbs; 516 dargs.total = mp->m_dirblkfsbs;
511 dargs.whichfork = XFS_DATA_FORK; 517 dargs.whichfork = XFS_DATA_FORK;
512 dargs.trans = tp; 518 dargs.trans = tp;
513 error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); 519 error = xfs_dir2_sf_to_block(&dargs);
514 } else 520 } else
515 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, 521 error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
516 XFS_DATA_FORK); 522 XFS_DATA_FORK);
@@ -530,6 +536,7 @@ xfs_bmap_add_extent(
530 xfs_fsblock_t *first, /* pointer to firstblock variable */ 536 xfs_fsblock_t *first, /* pointer to firstblock variable */
531 xfs_bmap_free_t *flist, /* list of extents to be freed */ 537 xfs_bmap_free_t *flist, /* list of extents to be freed */
532 int *logflagsp, /* inode logging flags */ 538 int *logflagsp, /* inode logging flags */
539 xfs_extdelta_t *delta, /* Change made to incore extents */
533 int whichfork, /* data or attr fork */ 540 int whichfork, /* data or attr fork */
534 int rsvd) /* OK to use reserved data blocks */ 541 int rsvd) /* OK to use reserved data blocks */
535{ 542{
@@ -567,6 +574,15 @@ xfs_bmap_add_extent(
567 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 574 logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
568 } else 575 } else
569 logflags = 0; 576 logflags = 0;
577 /* DELTA: single new extent */
578 if (delta) {
579 if (delta->xed_startoff > new->br_startoff)
580 delta->xed_startoff = new->br_startoff;
581 if (delta->xed_blockcount <
582 new->br_startoff + new->br_blockcount)
583 delta->xed_blockcount = new->br_startoff +
584 new->br_blockcount;
585 }
570 } 586 }
571 /* 587 /*
572 * Any kind of new delayed allocation goes here. 588 * Any kind of new delayed allocation goes here.
@@ -576,7 +592,7 @@ xfs_bmap_add_extent(
576 ASSERT((cur->bc_private.b.flags & 592 ASSERT((cur->bc_private.b.flags &
577 XFS_BTCUR_BPRV_WASDEL) == 0); 593 XFS_BTCUR_BPRV_WASDEL) == 0);
578 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new, 594 if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
579 &logflags, rsvd))) 595 &logflags, delta, rsvd)))
580 goto done; 596 goto done;
581 } 597 }
582 /* 598 /*
@@ -587,7 +603,7 @@ xfs_bmap_add_extent(
587 ASSERT((cur->bc_private.b.flags & 603 ASSERT((cur->bc_private.b.flags &
588 XFS_BTCUR_BPRV_WASDEL) == 0); 604 XFS_BTCUR_BPRV_WASDEL) == 0);
589 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new, 605 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
590 &logflags, whichfork))) 606 &logflags, delta, whichfork)))
591 goto done; 607 goto done;
592 } else { 608 } else {
593 xfs_bmbt_irec_t prev; /* old extent at offset idx */ 609 xfs_bmbt_irec_t prev; /* old extent at offset idx */
@@ -612,17 +628,17 @@ xfs_bmap_add_extent(
612 XFS_BTCUR_BPRV_WASDEL); 628 XFS_BTCUR_BPRV_WASDEL);
613 if ((error = xfs_bmap_add_extent_delay_real(ip, 629 if ((error = xfs_bmap_add_extent_delay_real(ip,
614 idx, &cur, new, &da_new, first, flist, 630 idx, &cur, new, &da_new, first, flist,
615 &logflags, rsvd))) 631 &logflags, delta, rsvd)))
616 goto done; 632 goto done;
617 } else if (new->br_state == XFS_EXT_NORM) { 633 } else if (new->br_state == XFS_EXT_NORM) {
618 ASSERT(new->br_state == XFS_EXT_NORM); 634 ASSERT(new->br_state == XFS_EXT_NORM);
619 if ((error = xfs_bmap_add_extent_unwritten_real( 635 if ((error = xfs_bmap_add_extent_unwritten_real(
620 ip, idx, &cur, new, &logflags))) 636 ip, idx, &cur, new, &logflags, delta)))
621 goto done; 637 goto done;
622 } else { 638 } else {
623 ASSERT(new->br_state == XFS_EXT_UNWRITTEN); 639 ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
624 if ((error = xfs_bmap_add_extent_unwritten_real( 640 if ((error = xfs_bmap_add_extent_unwritten_real(
625 ip, idx, &cur, new, &logflags))) 641 ip, idx, &cur, new, &logflags, delta)))
626 goto done; 642 goto done;
627 } 643 }
628 ASSERT(*curp == cur || *curp == NULL); 644 ASSERT(*curp == cur || *curp == NULL);
@@ -635,7 +651,7 @@ xfs_bmap_add_extent(
635 ASSERT((cur->bc_private.b.flags & 651 ASSERT((cur->bc_private.b.flags &
636 XFS_BTCUR_BPRV_WASDEL) == 0); 652 XFS_BTCUR_BPRV_WASDEL) == 0);
637 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, 653 if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
638 new, &logflags, whichfork))) 654 new, &logflags, delta, whichfork)))
639 goto done; 655 goto done;
640 } 656 }
641 } 657 }
@@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
700 xfs_fsblock_t *first, /* pointer to firstblock variable */ 716 xfs_fsblock_t *first, /* pointer to firstblock variable */
701 xfs_bmap_free_t *flist, /* list of extents to be freed */ 717 xfs_bmap_free_t *flist, /* list of extents to be freed */
702 int *logflagsp, /* inode logging flags */ 718 int *logflagsp, /* inode logging flags */
719 xfs_extdelta_t *delta, /* Change made to incore extents */
703 int rsvd) /* OK to use reserved data block allocation */ 720 int rsvd) /* OK to use reserved data block allocation */
704{ 721{
705 xfs_btree_cur_t *cur; /* btree cursor */ 722 xfs_btree_cur_t *cur; /* btree cursor */
@@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(
716 /* left is 0, right is 1, prev is 2 */ 733 /* left is 0, right is 1, prev is 2 */
717 int rval=0; /* return value (logging flags) */ 734 int rval=0; /* return value (logging flags) */
718 int state = 0;/* state bits, accessed thru macros */ 735 int state = 0;/* state bits, accessed thru macros */
719 xfs_filblks_t temp; /* value for dnew calculations */ 736 xfs_filblks_t temp=0; /* value for dnew calculations */
720 xfs_filblks_t temp2; /* value for dnew calculations */ 737 xfs_filblks_t temp2=0;/* value for dnew calculations */
721 int tmp_rval; /* partial logging flags */ 738 int tmp_rval; /* partial logging flags */
722 enum { /* bit number definitions for state */ 739 enum { /* bit number definitions for state */
723 LEFT_CONTIG, RIGHT_CONTIG, 740 LEFT_CONTIG, RIGHT_CONTIG,
@@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
839 goto done; 856 goto done;
840 } 857 }
841 *dnew = 0; 858 *dnew = 0;
859 /* DELTA: Three in-core extents are replaced by one. */
860 temp = LEFT.br_startoff;
861 temp2 = LEFT.br_blockcount +
862 PREV.br_blockcount +
863 RIGHT.br_blockcount;
842 break; 864 break;
843 865
844 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 866 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
872 goto done; 894 goto done;
873 } 895 }
874 *dnew = 0; 896 *dnew = 0;
897 /* DELTA: Two in-core extents are replaced by one. */
898 temp = LEFT.br_startoff;
899 temp2 = LEFT.br_blockcount +
900 PREV.br_blockcount;
875 break; 901 break;
876 902
877 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 903 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
906 goto done; 932 goto done;
907 } 933 }
908 *dnew = 0; 934 *dnew = 0;
935 /* DELTA: Two in-core extents are replaced by one. */
936 temp = PREV.br_startoff;
937 temp2 = PREV.br_blockcount +
938 RIGHT.br_blockcount;
909 break; 939 break;
910 940
911 case MASK2(LEFT_FILLING, RIGHT_FILLING): 941 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
936 ASSERT(i == 1); 966 ASSERT(i == 1);
937 } 967 }
938 *dnew = 0; 968 *dnew = 0;
969 /* DELTA: The in-core extent described by new changed type. */
970 temp = new->br_startoff;
971 temp2 = new->br_blockcount;
939 break; 972 break;
940 973
941 case MASK2(LEFT_FILLING, LEFT_CONTIG): 974 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(
978 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, 1011 xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
979 XFS_DATA_FORK); 1012 XFS_DATA_FORK);
980 *dnew = temp; 1013 *dnew = temp;
1014 /* DELTA: The boundary between two in-core extents moved. */
1015 temp = LEFT.br_startoff;
1016 temp2 = LEFT.br_blockcount +
1017 PREV.br_blockcount;
981 break; 1018 break;
982 1019
983 case MASK(LEFT_FILLING): 1020 case MASK(LEFT_FILLING):
@@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(
1025 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, 1062 xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
1026 XFS_DATA_FORK); 1063 XFS_DATA_FORK);
1027 *dnew = temp; 1064 *dnew = temp;
1065 /* DELTA: One in-core extent is split in two. */
1066 temp = PREV.br_startoff;
1067 temp2 = PREV.br_blockcount;
1028 break; 1068 break;
1029 1069
1030 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1070 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(
1067 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, 1107 xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
1068 XFS_DATA_FORK); 1108 XFS_DATA_FORK);
1069 *dnew = temp; 1109 *dnew = temp;
1110 /* DELTA: The boundary between two in-core extents moved. */
1111 temp = PREV.br_startoff;
1112 temp2 = PREV.br_blockcount +
1113 RIGHT.br_blockcount;
1070 break; 1114 break;
1071 1115
1072 case MASK(RIGHT_FILLING): 1116 case MASK(RIGHT_FILLING):
@@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
1112 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); 1156 xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
1113 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); 1157 xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
1114 *dnew = temp; 1158 *dnew = temp;
1159 /* DELTA: One in-core extent is split in two. */
1160 temp = PREV.br_startoff;
1161 temp2 = PREV.br_blockcount;
1115 break; 1162 break;
1116 1163
1117 case 0: 1164 case 0:
@@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
1194 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, 1241 xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
1195 XFS_DATA_FORK); 1242 XFS_DATA_FORK);
1196 *dnew = temp + temp2; 1243 *dnew = temp + temp2;
1244 /* DELTA: One in-core extent is split in three. */
1245 temp = PREV.br_startoff;
1246 temp2 = PREV.br_blockcount;
1197 break; 1247 break;
1198 1248
1199 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1249 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
1209 ASSERT(0); 1259 ASSERT(0);
1210 } 1260 }
1211 *curp = cur; 1261 *curp = cur;
1262 if (delta) {
1263 temp2 += temp;
1264 if (delta->xed_startoff > temp)
1265 delta->xed_startoff = temp;
1266 if (delta->xed_blockcount < temp2)
1267 delta->xed_blockcount = temp2;
1268 }
1212done: 1269done:
1213 *logflagsp = rval; 1270 *logflagsp = rval;
1214 return error; 1271 return error;
@@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
1235 xfs_extnum_t idx, /* extent number to update/insert */ 1292 xfs_extnum_t idx, /* extent number to update/insert */
1236 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ 1293 xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
1237 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1294 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1238 int *logflagsp) /* inode logging flags */ 1295 int *logflagsp, /* inode logging flags */
1296 xfs_extdelta_t *delta) /* Change made to incore extents */
1239{ 1297{
1240 xfs_btree_cur_t *cur; /* btree cursor */ 1298 xfs_btree_cur_t *cur; /* btree cursor */
1241 xfs_bmbt_rec_t *ep; /* extent entry for idx */ 1299 xfs_bmbt_rec_t *ep; /* extent entry for idx */
@@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(
1252 /* left is 0, right is 1, prev is 2 */ 1310 /* left is 0, right is 1, prev is 2 */
1253 int rval=0; /* return value (logging flags) */ 1311 int rval=0; /* return value (logging flags) */
1254 int state = 0;/* state bits, accessed thru macros */ 1312 int state = 0;/* state bits, accessed thru macros */
1313 xfs_filblks_t temp=0;
1314 xfs_filblks_t temp2=0;
1255 enum { /* bit number definitions for state */ 1315 enum { /* bit number definitions for state */
1256 LEFT_CONTIG, RIGHT_CONTIG, 1316 LEFT_CONTIG, RIGHT_CONTIG,
1257 LEFT_FILLING, RIGHT_FILLING, 1317 LEFT_FILLING, RIGHT_FILLING,
@@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
1380 RIGHT.br_blockcount, LEFT.br_state))) 1440 RIGHT.br_blockcount, LEFT.br_state)))
1381 goto done; 1441 goto done;
1382 } 1442 }
1443 /* DELTA: Three in-core extents are replaced by one. */
1444 temp = LEFT.br_startoff;
1445 temp2 = LEFT.br_blockcount +
1446 PREV.br_blockcount +
1447 RIGHT.br_blockcount;
1383 break; 1448 break;
1384 1449
1385 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG): 1450 case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
1419 LEFT.br_state))) 1484 LEFT.br_state)))
1420 goto done; 1485 goto done;
1421 } 1486 }
1487 /* DELTA: Two in-core extents are replaced by one. */
1488 temp = LEFT.br_startoff;
1489 temp2 = LEFT.br_blockcount +
1490 PREV.br_blockcount;
1422 break; 1491 break;
1423 1492
1424 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG): 1493 case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
1459 newext))) 1528 newext)))
1460 goto done; 1529 goto done;
1461 } 1530 }
1531 /* DELTA: Two in-core extents are replaced by one. */
1532 temp = PREV.br_startoff;
1533 temp2 = PREV.br_blockcount +
1534 RIGHT.br_blockcount;
1462 break; 1535 break;
1463 1536
1464 case MASK2(LEFT_FILLING, RIGHT_FILLING): 1537 case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
1487 newext))) 1560 newext)))
1488 goto done; 1561 goto done;
1489 } 1562 }
1563 /* DELTA: The in-core extent described by new changed type. */
1564 temp = new->br_startoff;
1565 temp2 = new->br_blockcount;
1490 break; 1566 break;
1491 1567
1492 case MASK2(LEFT_FILLING, LEFT_CONTIG): 1568 case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
1534 LEFT.br_state)) 1610 LEFT.br_state))
1535 goto done; 1611 goto done;
1536 } 1612 }
1613 /* DELTA: The boundary between two in-core extents moved. */
1614 temp = LEFT.br_startoff;
1615 temp2 = LEFT.br_blockcount +
1616 PREV.br_blockcount;
1537 break; 1617 break;
1538 1618
1539 case MASK(LEFT_FILLING): 1619 case MASK(LEFT_FILLING):
@@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
1574 goto done; 1654 goto done;
1575 ASSERT(i == 1); 1655 ASSERT(i == 1);
1576 } 1656 }
1657 /* DELTA: One in-core extent is split in two. */
1658 temp = PREV.br_startoff;
1659 temp2 = PREV.br_blockcount;
1577 break; 1660 break;
1578 1661
1579 case MASK2(RIGHT_FILLING, RIGHT_CONTIG): 1662 case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
1617 newext))) 1700 newext)))
1618 goto done; 1701 goto done;
1619 } 1702 }
1703 /* DELTA: The boundary between two in-core extents moved. */
1704 temp = PREV.br_startoff;
1705 temp2 = PREV.br_blockcount +
1706 RIGHT.br_blockcount;
1620 break; 1707 break;
1621 1708
1622 case MASK(RIGHT_FILLING): 1709 case MASK(RIGHT_FILLING):
@@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
1657 goto done; 1744 goto done;
1658 ASSERT(i == 1); 1745 ASSERT(i == 1);
1659 } 1746 }
1747 /* DELTA: One in-core extent is split in two. */
1748 temp = PREV.br_startoff;
1749 temp2 = PREV.br_blockcount;
1660 break; 1750 break;
1661 1751
1662 case 0: 1752 case 0:
@@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
1710 goto done; 1800 goto done;
1711 ASSERT(i == 1); 1801 ASSERT(i == 1);
1712 } 1802 }
1803 /* DELTA: One in-core extent is split in three. */
1804 temp = PREV.br_startoff;
1805 temp2 = PREV.br_blockcount;
1713 break; 1806 break;
1714 1807
1715 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG): 1808 case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
1725 ASSERT(0); 1818 ASSERT(0);
1726 } 1819 }
1727 *curp = cur; 1820 *curp = cur;
1821 if (delta) {
1822 temp2 += temp;
1823 if (delta->xed_startoff > temp)
1824 delta->xed_startoff = temp;
1825 if (delta->xed_blockcount < temp2)
1826 delta->xed_blockcount = temp2;
1827 }
1728done: 1828done:
1729 *logflagsp = rval; 1829 *logflagsp = rval;
1730 return error; 1830 return error;
@@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
1753 xfs_btree_cur_t *cur, /* if null, not a btree */ 1853 xfs_btree_cur_t *cur, /* if null, not a btree */
1754 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 1854 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1755 int *logflagsp, /* inode logging flags */ 1855 int *logflagsp, /* inode logging flags */
1856 xfs_extdelta_t *delta, /* Change made to incore extents */
1756 int rsvd) /* OK to allocate reserved blocks */ 1857 int rsvd) /* OK to allocate reserved blocks */
1757{ 1858{
1758 xfs_bmbt_rec_t *ep; /* extent record for idx */ 1859 xfs_bmbt_rec_t *ep; /* extent record for idx */
@@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(
1765 xfs_filblks_t oldlen=0; /* old indirect size */ 1866 xfs_filblks_t oldlen=0; /* old indirect size */
1766 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 1867 xfs_bmbt_irec_t right; /* right neighbor extent entry */
1767 int state; /* state bits, accessed thru macros */ 1868 int state; /* state bits, accessed thru macros */
1768 xfs_filblks_t temp; /* temp for indirect calculations */ 1869 xfs_filblks_t temp=0; /* temp for indirect calculations */
1870 xfs_filblks_t temp2=0;
1769 enum { /* bit number definitions for state */ 1871 enum { /* bit number definitions for state */
1770 LEFT_CONTIG, RIGHT_CONTIG, 1872 LEFT_CONTIG, RIGHT_CONTIG,
1771 LEFT_DELAY, RIGHT_DELAY, 1873 LEFT_DELAY, RIGHT_DELAY,
@@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
1844 XFS_DATA_FORK); 1946 XFS_DATA_FORK);
1845 xfs_iext_remove(ifp, idx, 1); 1947 xfs_iext_remove(ifp, idx, 1);
1846 ip->i_df.if_lastex = idx - 1; 1948 ip->i_df.if_lastex = idx - 1;
1949 /* DELTA: Two in-core extents were replaced by one. */
1950 temp2 = temp;
1951 temp = left.br_startoff;
1847 break; 1952 break;
1848 1953
1849 case MASK(LEFT_CONTIG): 1954 case MASK(LEFT_CONTIG):
@@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(
1864 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, 1969 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
1865 XFS_DATA_FORK); 1970 XFS_DATA_FORK);
1866 ip->i_df.if_lastex = idx - 1; 1971 ip->i_df.if_lastex = idx - 1;
1972 /* DELTA: One in-core extent grew into a hole. */
1973 temp2 = temp;
1974 temp = left.br_startoff;
1867 break; 1975 break;
1868 1976
1869 case MASK(RIGHT_CONTIG): 1977 case MASK(RIGHT_CONTIG):
@@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
1881 NULLSTARTBLOCK((int)newlen), temp, right.br_state); 1989 NULLSTARTBLOCK((int)newlen), temp, right.br_state);
1882 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); 1990 xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
1883 ip->i_df.if_lastex = idx; 1991 ip->i_df.if_lastex = idx;
1992 /* DELTA: One in-core extent grew into a hole. */
1993 temp2 = temp;
1994 temp = new->br_startoff;
1884 break; 1995 break;
1885 1996
1886 case 0: 1997 case 0:
@@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
1894 XFS_DATA_FORK); 2005 XFS_DATA_FORK);
1895 xfs_iext_insert(ifp, idx, 1, new); 2006 xfs_iext_insert(ifp, idx, 1, new);
1896 ip->i_df.if_lastex = idx; 2007 ip->i_df.if_lastex = idx;
2008 /* DELTA: A new in-core extent was added in a hole. */
2009 temp2 = new->br_blockcount;
2010 temp = new->br_startoff;
1897 break; 2011 break;
1898 } 2012 }
1899 if (oldlen != newlen) { 2013 if (oldlen != newlen) {
@@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
1904 * Nothing to do for disk quota accounting here. 2018 * Nothing to do for disk quota accounting here.
1905 */ 2019 */
1906 } 2020 }
2021 if (delta) {
2022 temp2 += temp;
2023 if (delta->xed_startoff > temp)
2024 delta->xed_startoff = temp;
2025 if (delta->xed_blockcount < temp2)
2026 delta->xed_blockcount = temp2;
2027 }
1907 *logflagsp = 0; 2028 *logflagsp = 0;
1908 return 0; 2029 return 0;
1909#undef MASK 2030#undef MASK
@@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
1925 xfs_btree_cur_t *cur, /* if null, not a btree */ 2046 xfs_btree_cur_t *cur, /* if null, not a btree */
1926 xfs_bmbt_irec_t *new, /* new data to add to file extents */ 2047 xfs_bmbt_irec_t *new, /* new data to add to file extents */
1927 int *logflagsp, /* inode logging flags */ 2048 int *logflagsp, /* inode logging flags */
2049 xfs_extdelta_t *delta, /* Change made to incore extents */
1928 int whichfork) /* data or attr fork */ 2050 int whichfork) /* data or attr fork */
1929{ 2051{
1930 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ 2052 xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */
@@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(
1936 xfs_ifork_t *ifp; /* inode fork pointer */ 2058 xfs_ifork_t *ifp; /* inode fork pointer */
1937 xfs_bmbt_irec_t left; /* left neighbor extent entry */ 2059 xfs_bmbt_irec_t left; /* left neighbor extent entry */
1938 xfs_bmbt_irec_t right; /* right neighbor extent entry */ 2060 xfs_bmbt_irec_t right; /* right neighbor extent entry */
2061 int rval=0; /* return value (logging flags) */
1939 int state; /* state bits, accessed thru macros */ 2062 int state; /* state bits, accessed thru macros */
2063 xfs_filblks_t temp=0;
2064 xfs_filblks_t temp2=0;
1940 enum { /* bit number definitions for state */ 2065 enum { /* bit number definitions for state */
1941 LEFT_CONTIG, RIGHT_CONTIG, 2066 LEFT_CONTIG, RIGHT_CONTIG,
1942 LEFT_DELAY, RIGHT_DELAY, 2067 LEFT_DELAY, RIGHT_DELAY,
@@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
1993 left.br_blockcount + new->br_blockcount + 2118 left.br_blockcount + new->br_blockcount +
1994 right.br_blockcount <= MAXEXTLEN)); 2119 right.br_blockcount <= MAXEXTLEN));
1995 2120
2121 error = 0;
1996 /* 2122 /*
1997 * Select which case we're in here, and implement it. 2123 * Select which case we're in here, and implement it.
1998 */ 2124 */
@@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(
2018 XFS_IFORK_NEXT_SET(ip, whichfork, 2144 XFS_IFORK_NEXT_SET(ip, whichfork,
2019 XFS_IFORK_NEXTENTS(ip, whichfork) - 1); 2145 XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
2020 if (cur == NULL) { 2146 if (cur == NULL) {
2021 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2147 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2022 return 0; 2148 } else {
2149 rval = XFS_ILOG_CORE;
2150 if ((error = xfs_bmbt_lookup_eq(cur,
2151 right.br_startoff,
2152 right.br_startblock,
2153 right.br_blockcount, &i)))
2154 goto done;
2155 ASSERT(i == 1);
2156 if ((error = xfs_bmbt_delete(cur, &i)))
2157 goto done;
2158 ASSERT(i == 1);
2159 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2160 goto done;
2161 ASSERT(i == 1);
2162 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2163 left.br_startblock,
2164 left.br_blockcount +
2165 new->br_blockcount +
2166 right.br_blockcount,
2167 left.br_state)))
2168 goto done;
2023 } 2169 }
2024 *logflagsp = XFS_ILOG_CORE; 2170 /* DELTA: Two in-core extents were replaced by one. */
2025 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2171 temp = left.br_startoff;
2026 right.br_startblock, right.br_blockcount, &i))) 2172 temp2 = left.br_blockcount +
2027 return error; 2173 new->br_blockcount +
2028 ASSERT(i == 1); 2174 right.br_blockcount;
2029 if ((error = xfs_bmbt_delete(cur, &i))) 2175 break;
2030 return error;
2031 ASSERT(i == 1);
2032 if ((error = xfs_bmbt_decrement(cur, 0, &i)))
2033 return error;
2034 ASSERT(i == 1);
2035 error = xfs_bmbt_update(cur, left.br_startoff,
2036 left.br_startblock,
2037 left.br_blockcount + new->br_blockcount +
2038 right.br_blockcount, left.br_state);
2039 return error;
2040 2176
2041 case MASK(LEFT_CONTIG): 2177 case MASK(LEFT_CONTIG):
2042 /* 2178 /*
@@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(
2050 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); 2186 xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
2051 ifp->if_lastex = idx - 1; 2187 ifp->if_lastex = idx - 1;
2052 if (cur == NULL) { 2188 if (cur == NULL) {
2053 *logflagsp = XFS_ILOG_FEXT(whichfork); 2189 rval = XFS_ILOG_FEXT(whichfork);
2054 return 0; 2190 } else {
2191 rval = 0;
2192 if ((error = xfs_bmbt_lookup_eq(cur,
2193 left.br_startoff,
2194 left.br_startblock,
2195 left.br_blockcount, &i)))
2196 goto done;
2197 ASSERT(i == 1);
2198 if ((error = xfs_bmbt_update(cur, left.br_startoff,
2199 left.br_startblock,
2200 left.br_blockcount +
2201 new->br_blockcount,
2202 left.br_state)))
2203 goto done;
2055 } 2204 }
2056 *logflagsp = 0; 2205 /* DELTA: One in-core extent grew. */
2057 if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff, 2206 temp = left.br_startoff;
2058 left.br_startblock, left.br_blockcount, &i))) 2207 temp2 = left.br_blockcount +
2059 return error; 2208 new->br_blockcount;
2060 ASSERT(i == 1); 2209 break;
2061 error = xfs_bmbt_update(cur, left.br_startoff,
2062 left.br_startblock,
2063 left.br_blockcount + new->br_blockcount,
2064 left.br_state);
2065 return error;
2066 2210
2067 case MASK(RIGHT_CONTIG): 2211 case MASK(RIGHT_CONTIG):
2068 /* 2212 /*
@@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
2077 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); 2221 xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
2078 ifp->if_lastex = idx; 2222 ifp->if_lastex = idx;
2079 if (cur == NULL) { 2223 if (cur == NULL) {
2080 *logflagsp = XFS_ILOG_FEXT(whichfork); 2224 rval = XFS_ILOG_FEXT(whichfork);
2081 return 0; 2225 } else {
2226 rval = 0;
2227 if ((error = xfs_bmbt_lookup_eq(cur,
2228 right.br_startoff,
2229 right.br_startblock,
2230 right.br_blockcount, &i)))
2231 goto done;
2232 ASSERT(i == 1);
2233 if ((error = xfs_bmbt_update(cur, new->br_startoff,
2234 new->br_startblock,
2235 new->br_blockcount +
2236 right.br_blockcount,
2237 right.br_state)))
2238 goto done;
2082 } 2239 }
2083 *logflagsp = 0; 2240 /* DELTA: One in-core extent grew. */
2084 if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff, 2241 temp = new->br_startoff;
2085 right.br_startblock, right.br_blockcount, &i))) 2242 temp2 = new->br_blockcount +
2086 return error; 2243 right.br_blockcount;
2087 ASSERT(i == 1); 2244 break;
2088 error = xfs_bmbt_update(cur, new->br_startoff,
2089 new->br_startblock,
2090 new->br_blockcount + right.br_blockcount,
2091 right.br_state);
2092 return error;
2093 2245
2094 case 0: 2246 case 0:
2095 /* 2247 /*
@@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
2104 XFS_IFORK_NEXT_SET(ip, whichfork, 2256 XFS_IFORK_NEXT_SET(ip, whichfork,
2105 XFS_IFORK_NEXTENTS(ip, whichfork) + 1); 2257 XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
2106 if (cur == NULL) { 2258 if (cur == NULL) {
2107 *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork); 2259 rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
2108 return 0; 2260 } else {
2261 rval = XFS_ILOG_CORE;
2262 if ((error = xfs_bmbt_lookup_eq(cur,
2263 new->br_startoff,
2264 new->br_startblock,
2265 new->br_blockcount, &i)))
2266 goto done;
2267 ASSERT(i == 0);
2268 cur->bc_rec.b.br_state = new->br_state;
2269 if ((error = xfs_bmbt_insert(cur, &i)))
2270 goto done;
2271 ASSERT(i == 1);
2109 } 2272 }
2110 *logflagsp = XFS_ILOG_CORE; 2273 /* DELTA: A new extent was added in a hole. */
2111 if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff, 2274 temp = new->br_startoff;
2112 new->br_startblock, new->br_blockcount, &i))) 2275 temp2 = new->br_blockcount;
2113 return error; 2276 break;
2114 ASSERT(i == 0); 2277 }
2115 cur->bc_rec.b.br_state = new->br_state; 2278 if (delta) {
2116 if ((error = xfs_bmbt_insert(cur, &i))) 2279 temp2 += temp;
2117 return error; 2280 if (delta->xed_startoff > temp)
2118 ASSERT(i == 1); 2281 delta->xed_startoff = temp;
2119 return 0; 2282 if (delta->xed_blockcount < temp2)
2283 delta->xed_blockcount = temp2;
2120 } 2284 }
2285done:
2286 *logflagsp = rval;
2287 return error;
2121#undef MASK 2288#undef MASK
2122#undef MASK2 2289#undef MASK2
2123#undef STATE_SET 2290#undef STATE_SET
2124#undef STATE_TEST 2291#undef STATE_TEST
2125#undef STATE_SET_TEST 2292#undef STATE_SET_TEST
2126#undef SWITCH_STATE 2293#undef SWITCH_STATE
2127 /* NOTREACHED */
2128 ASSERT(0);
2129 return 0; /* keep gcc quite */
2130} 2294}
2131 2295
2132/* 2296/*
@@ -2598,6 +2762,7 @@ xfs_bmap_btalloc(
2598 args.mp = mp; 2762 args.mp = mp;
2599 args.fsbno = ap->rval; 2763 args.fsbno = ap->rval;
2600 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); 2764 args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
2765 args.firstblock = ap->firstblock;
2601 blen = 0; 2766 blen = 0;
2602 if (nullfb) { 2767 if (nullfb) {
2603 args.type = XFS_ALLOCTYPE_START_BNO; 2768 args.type = XFS_ALLOCTYPE_START_BNO;
@@ -2657,7 +2822,7 @@ xfs_bmap_btalloc(
2657 else 2822 else
2658 args.minlen = ap->alen; 2823 args.minlen = ap->alen;
2659 } else if (ap->low) { 2824 } else if (ap->low) {
2660 args.type = XFS_ALLOCTYPE_FIRST_AG; 2825 args.type = XFS_ALLOCTYPE_START_BNO;
2661 args.total = args.minlen = ap->minlen; 2826 args.total = args.minlen = ap->minlen;
2662 } else { 2827 } else {
2663 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2828 args.type = XFS_ALLOCTYPE_NEAR_BNO;
@@ -2669,7 +2834,7 @@ xfs_bmap_btalloc(
2669 args.prod = ap->ip->i_d.di_extsize; 2834 args.prod = ap->ip->i_d.di_extsize;
2670 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) 2835 if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
2671 args.mod = (xfs_extlen_t)(args.prod - args.mod); 2836 args.mod = (xfs_extlen_t)(args.prod - args.mod);
2672 } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) { 2837 } else if (mp->m_sb.sb_blocksize >= NBPP) {
2673 args.prod = 1; 2838 args.prod = 1;
2674 args.mod = 0; 2839 args.mod = 0;
2675 } else { 2840 } else {
@@ -2885,6 +3050,7 @@ xfs_bmap_del_extent(
2885 xfs_btree_cur_t *cur, /* if null, not a btree */ 3050 xfs_btree_cur_t *cur, /* if null, not a btree */
2886 xfs_bmbt_irec_t *del, /* data to remove from extents */ 3051 xfs_bmbt_irec_t *del, /* data to remove from extents */
2887 int *logflagsp, /* inode logging flags */ 3052 int *logflagsp, /* inode logging flags */
3053 xfs_extdelta_t *delta, /* Change made to incore extents */
2888 int whichfork, /* data or attr fork */ 3054 int whichfork, /* data or attr fork */
2889 int rsvd) /* OK to allocate reserved blocks */ 3055 int rsvd) /* OK to allocate reserved blocks */
2890{ 3056{
@@ -3193,6 +3359,14 @@ xfs_bmap_del_extent(
3193 if (da_old > da_new) 3359 if (da_old > da_new)
3194 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new), 3360 xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
3195 rsvd); 3361 rsvd);
3362 if (delta) {
3363 /* DELTA: report the original extent. */
3364 if (delta->xed_startoff > got.br_startoff)
3365 delta->xed_startoff = got.br_startoff;
3366 if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
3367 delta->xed_blockcount = got.br_startoff +
3368 got.br_blockcount;
3369 }
3196done: 3370done:
3197 *logflagsp = flags; 3371 *logflagsp = flags;
3198 return error; 3372 return error;
@@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree(
3279 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE); 3453 XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
3280 args.tp = tp; 3454 args.tp = tp;
3281 args.mp = mp; 3455 args.mp = mp;
3456 args.firstblock = *firstblock;
3282 if (*firstblock == NULLFSBLOCK) { 3457 if (*firstblock == NULLFSBLOCK) {
3283 args.type = XFS_ALLOCTYPE_START_BNO; 3458 args.type = XFS_ALLOCTYPE_START_BNO;
3284 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino); 3459 args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
@@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents(
3414 3589
3415 args.tp = tp; 3590 args.tp = tp;
3416 args.mp = ip->i_mount; 3591 args.mp = ip->i_mount;
3592 args.firstblock = *firstblock;
3417 ASSERT((ifp->if_flags & 3593 ASSERT((ifp->if_flags &
3418 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE); 3594 (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
3419 /* 3595 /*
@@ -3753,7 +3929,7 @@ xfs_bunmap_trace(
3753 if (ip->i_rwtrace == NULL) 3929 if (ip->i_rwtrace == NULL)
3754 return; 3930 return;
3755 ktrace_enter(ip->i_rwtrace, 3931 ktrace_enter(ip->i_rwtrace,
3756 (void *)(__psint_t)XFS_BUNMAPI, 3932 (void *)(__psint_t)XFS_BUNMAP,
3757 (void *)ip, 3933 (void *)ip,
3758 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff), 3934 (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
3759 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff), 3935 (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
@@ -4087,8 +4263,8 @@ xfs_bmap_finish(
4087 if (!XFS_FORCED_SHUTDOWN(mp)) 4263 if (!XFS_FORCED_SHUTDOWN(mp))
4088 xfs_force_shutdown(mp, 4264 xfs_force_shutdown(mp,
4089 (error == EFSCORRUPTED) ? 4265 (error == EFSCORRUPTED) ?
4090 XFS_CORRUPT_INCORE : 4266 SHUTDOWN_CORRUPT_INCORE :
4091 XFS_METADATA_IO_ERROR); 4267 SHUTDOWN_META_IO_ERROR);
4092 return error; 4268 return error;
4093 } 4269 }
4094 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock, 4270 xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
@@ -4538,7 +4714,8 @@ xfs_bmapi(
4538 xfs_extlen_t total, /* total blocks needed */ 4714 xfs_extlen_t total, /* total blocks needed */
4539 xfs_bmbt_irec_t *mval, /* output: map values */ 4715 xfs_bmbt_irec_t *mval, /* output: map values */
4540 int *nmap, /* i/o: mval size/count */ 4716 int *nmap, /* i/o: mval size/count */
4541 xfs_bmap_free_t *flist) /* i/o: list extents to free */ 4717 xfs_bmap_free_t *flist, /* i/o: list extents to free */
4718 xfs_extdelta_t *delta) /* o: change made to incore extents */
4542{ 4719{
4543 xfs_fsblock_t abno; /* allocated block number */ 4720 xfs_fsblock_t abno; /* allocated block number */
4544 xfs_extlen_t alen; /* allocated extent length */ 4721 xfs_extlen_t alen; /* allocated extent length */
@@ -4650,6 +4827,10 @@ xfs_bmapi(
4650 end = bno + len; 4827 end = bno + len;
4651 obno = bno; 4828 obno = bno;
4652 bma.ip = NULL; 4829 bma.ip = NULL;
4830 if (delta) {
4831 delta->xed_startoff = NULLFILEOFF;
4832 delta->xed_blockcount = 0;
4833 }
4653 while (bno < end && n < *nmap) { 4834 while (bno < end && n < *nmap) {
4654 /* 4835 /*
4655 * Reading past eof, act as though there's a hole 4836 * Reading past eof, act as though there's a hole
@@ -4886,8 +5067,8 @@ xfs_bmapi(
4886 got.br_state = XFS_EXT_UNWRITTEN; 5067 got.br_state = XFS_EXT_UNWRITTEN;
4887 } 5068 }
4888 error = xfs_bmap_add_extent(ip, lastx, &cur, &got, 5069 error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
4889 firstblock, flist, &tmp_logflags, whichfork, 5070 firstblock, flist, &tmp_logflags, delta,
4890 (flags & XFS_BMAPI_RSVBLOCKS)); 5071 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4891 logflags |= tmp_logflags; 5072 logflags |= tmp_logflags;
4892 if (error) 5073 if (error)
4893 goto error0; 5074 goto error0;
@@ -4983,8 +5164,8 @@ xfs_bmapi(
4983 } 5164 }
4984 mval->br_state = XFS_EXT_NORM; 5165 mval->br_state = XFS_EXT_NORM;
4985 error = xfs_bmap_add_extent(ip, lastx, &cur, mval, 5166 error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
4986 firstblock, flist, &tmp_logflags, whichfork, 5167 firstblock, flist, &tmp_logflags, delta,
4987 (flags & XFS_BMAPI_RSVBLOCKS)); 5168 whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
4988 logflags |= tmp_logflags; 5169 logflags |= tmp_logflags;
4989 if (error) 5170 if (error)
4990 goto error0; 5171 goto error0;
@@ -5073,7 +5254,14 @@ xfs_bmapi(
5073 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE || 5254 ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
5074 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max); 5255 XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
5075 error = 0; 5256 error = 0;
5076 5257 if (delta && delta->xed_startoff != NULLFILEOFF) {
5258 /* A change was actually made.
5259 * Note that delta->xed_blockount is an offset at this
5260 * point and needs to be converted to a block count.
5261 */
5262 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5263 delta->xed_blockcount -= delta->xed_startoff;
5264 }
5077error0: 5265error0:
5078 /* 5266 /*
5079 * Log everything. Do this after conversion, there's no point in 5267 * Log everything. Do this after conversion, there's no point in
@@ -5185,6 +5373,8 @@ xfs_bunmapi(
5185 xfs_fsblock_t *firstblock, /* first allocated block 5373 xfs_fsblock_t *firstblock, /* first allocated block
5186 controls a.g. for allocs */ 5374 controls a.g. for allocs */
5187 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 5375 xfs_bmap_free_t *flist, /* i/o: list extents to free */
5376 xfs_extdelta_t *delta, /* o: change made to incore
5377 extents */
5188 int *done) /* set if not done yet */ 5378 int *done) /* set if not done yet */
5189{ 5379{
5190 xfs_btree_cur_t *cur; /* bmap btree cursor */ 5380 xfs_btree_cur_t *cur; /* bmap btree cursor */
@@ -5242,6 +5432,10 @@ xfs_bunmapi(
5242 bno = start + len - 1; 5432 bno = start + len - 1;
5243 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, 5433 ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
5244 &prev); 5434 &prev);
5435 if (delta) {
5436 delta->xed_startoff = NULLFILEOFF;
5437 delta->xed_blockcount = 0;
5438 }
5245 /* 5439 /*
5246 * Check to see if the given block number is past the end of the 5440 * Check to see if the given block number is past the end of the
5247 * file, back up to the last block if so... 5441 * file, back up to the last block if so...
@@ -5340,7 +5534,8 @@ xfs_bunmapi(
5340 } 5534 }
5341 del.br_state = XFS_EXT_UNWRITTEN; 5535 del.br_state = XFS_EXT_UNWRITTEN;
5342 error = xfs_bmap_add_extent(ip, lastx, &cur, &del, 5536 error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
5343 firstblock, flist, &logflags, XFS_DATA_FORK, 0); 5537 firstblock, flist, &logflags, delta,
5538 XFS_DATA_FORK, 0);
5344 if (error) 5539 if (error)
5345 goto error0; 5540 goto error0;
5346 goto nodelete; 5541 goto nodelete;
@@ -5394,7 +5589,7 @@ xfs_bunmapi(
5394 prev.br_state = XFS_EXT_UNWRITTEN; 5589 prev.br_state = XFS_EXT_UNWRITTEN;
5395 error = xfs_bmap_add_extent(ip, lastx - 1, &cur, 5590 error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
5396 &prev, firstblock, flist, &logflags, 5591 &prev, firstblock, flist, &logflags,
5397 XFS_DATA_FORK, 0); 5592 delta, XFS_DATA_FORK, 0);
5398 if (error) 5593 if (error)
5399 goto error0; 5594 goto error0;
5400 goto nodelete; 5595 goto nodelete;
@@ -5403,7 +5598,7 @@ xfs_bunmapi(
5403 del.br_state = XFS_EXT_UNWRITTEN; 5598 del.br_state = XFS_EXT_UNWRITTEN;
5404 error = xfs_bmap_add_extent(ip, lastx, &cur, 5599 error = xfs_bmap_add_extent(ip, lastx, &cur,
5405 &del, firstblock, flist, &logflags, 5600 &del, firstblock, flist, &logflags,
5406 XFS_DATA_FORK, 0); 5601 delta, XFS_DATA_FORK, 0);
5407 if (error) 5602 if (error)
5408 goto error0; 5603 goto error0;
5409 goto nodelete; 5604 goto nodelete;
@@ -5456,7 +5651,7 @@ xfs_bunmapi(
5456 goto error0; 5651 goto error0;
5457 } 5652 }
5458 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del, 5653 error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
5459 &tmp_logflags, whichfork, rsvd); 5654 &tmp_logflags, delta, whichfork, rsvd);
5460 logflags |= tmp_logflags; 5655 logflags |= tmp_logflags;
5461 if (error) 5656 if (error)
5462 goto error0; 5657 goto error0;
@@ -5513,6 +5708,14 @@ nodelete:
5513 ASSERT(ifp->if_ext_max == 5708 ASSERT(ifp->if_ext_max ==
5514 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); 5709 XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
5515 error = 0; 5710 error = 0;
5711 if (delta && delta->xed_startoff != NULLFILEOFF) {
5712 /* A change was actually made.
5713 * Note that delta->xed_blockount is an offset at this
5714 * point and needs to be converted to a block count.
5715 */
5716 ASSERT(delta->xed_blockcount > delta->xed_startoff);
5717 delta->xed_blockcount -= delta->xed_startoff;
5718 }
5516error0: 5719error0:
5517 /* 5720 /*
5518 * Log everything. Do this after conversion, there's no point in 5721 * Log everything. Do this after conversion, there's no point in
@@ -5556,7 +5759,7 @@ xfs_getbmap(
5556 __int64_t fixlen; /* length for -1 case */ 5759 __int64_t fixlen; /* length for -1 case */
5557 int i; /* extent number */ 5760 int i; /* extent number */
5558 xfs_inode_t *ip; /* xfs incore inode pointer */ 5761 xfs_inode_t *ip; /* xfs incore inode pointer */
5559 vnode_t *vp; /* corresponding vnode */ 5762 bhv_vnode_t *vp; /* corresponding vnode */
5560 int lock; /* lock state */ 5763 int lock; /* lock state */
5561 xfs_bmbt_irec_t *map; /* buffer for user's data */ 5764 xfs_bmbt_irec_t *map; /* buffer for user's data */
5562 xfs_mount_t *mp; /* file system mount point */ 5765 xfs_mount_t *mp; /* file system mount point */
@@ -5653,7 +5856,7 @@ xfs_getbmap(
5653 5856
5654 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) { 5857 if (whichfork == XFS_DATA_FORK && ip->i_delayed_blks) {
5655 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5858 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5656 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 5859 error = bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
5657 } 5860 }
5658 5861
5659 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); 5862 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0);
@@ -5689,7 +5892,8 @@ xfs_getbmap(
5689 nmap = (nexleft > subnex) ? subnex : nexleft; 5892 nmap = (nexleft > subnex) ? subnex : nexleft;
5690 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset), 5893 error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
5691 XFS_BB_TO_FSB(mp, bmv->bmv_length), 5894 XFS_BB_TO_FSB(mp, bmv->bmv_length),
5692 bmapi_flags, NULL, 0, map, &nmap, NULL); 5895 bmapi_flags, NULL, 0, map, &nmap,
5896 NULL, NULL);
5693 if (error) 5897 if (error)
5694 goto unlock_and_return; 5898 goto unlock_and_return;
5695 ASSERT(nmap <= subnex); 5899 ASSERT(nmap <= subnex);
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 8e0d73d9ccc4..80e93409b78d 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -26,6 +26,20 @@ struct xfs_mount;
26struct xfs_trans; 26struct xfs_trans;
27 27
28/* 28/*
29 * DELTA: describe a change to the in-core extent list.
30 *
31 * Internally the use of xed_blockount is somewhat funky.
32 * xed_blockcount contains an offset much of the time because this
33 * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
34 * the same underlying type).
35 */
36typedef struct xfs_extdelta
37{
38 xfs_fileoff_t xed_startoff; /* offset of range */
39 xfs_filblks_t xed_blockcount; /* blocks in range */
40} xfs_extdelta_t;
41
42/*
29 * List of extents to be free "later". 43 * List of extents to be free "later".
30 * The list is kept sorted on xbf_startblock. 44 * The list is kept sorted on xbf_startblock.
31 */ 45 */
@@ -275,7 +289,9 @@ xfs_bmapi(
275 xfs_extlen_t total, /* total blocks needed */ 289 xfs_extlen_t total, /* total blocks needed */
276 struct xfs_bmbt_irec *mval, /* output: map values */ 290 struct xfs_bmbt_irec *mval, /* output: map values */
277 int *nmap, /* i/o: mval size/count */ 291 int *nmap, /* i/o: mval size/count */
278 xfs_bmap_free_t *flist); /* i/o: list extents to free */ 292 xfs_bmap_free_t *flist, /* i/o: list extents to free */
293 xfs_extdelta_t *delta); /* o: change made to incore
294 extents */
279 295
280/* 296/*
281 * Map file blocks to filesystem blocks, simple version. 297 * Map file blocks to filesystem blocks, simple version.
@@ -309,6 +325,8 @@ xfs_bunmapi(
309 xfs_fsblock_t *firstblock, /* first allocated block 325 xfs_fsblock_t *firstblock, /* first allocated block
310 controls a.g. for allocs */ 326 controls a.g. for allocs */
311 xfs_bmap_free_t *flist, /* i/o: list extents to free */ 327 xfs_bmap_free_t *flist, /* i/o: list extents to free */
328 xfs_extdelta_t *delta, /* o: change made to incore
329 extents */
312 int *done); /* set if not done yet */ 330 int *done); /* set if not done yet */
313 331
314/* 332/*
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index bea44709afbe..18fb7385d719 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1569,12 +1567,11 @@ xfs_bmbt_split(
1569 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp)); 1567 lbno = XFS_DADDR_TO_FSB(args.mp, XFS_BUF_ADDR(lbp));
1570 left = XFS_BUF_TO_BMBT_BLOCK(lbp); 1568 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
1571 args.fsbno = cur->bc_private.b.firstblock; 1569 args.fsbno = cur->bc_private.b.firstblock;
1570 args.firstblock = args.fsbno;
1572 if (args.fsbno == NULLFSBLOCK) { 1571 if (args.fsbno == NULLFSBLOCK) {
1573 args.fsbno = lbno; 1572 args.fsbno = lbno;
1574 args.type = XFS_ALLOCTYPE_START_BNO; 1573 args.type = XFS_ALLOCTYPE_START_BNO;
1575 } else if (cur->bc_private.b.flist->xbf_low) 1574 } else
1576 args.type = XFS_ALLOCTYPE_FIRST_AG;
1577 else
1578 args.type = XFS_ALLOCTYPE_NEAR_BNO; 1575 args.type = XFS_ALLOCTYPE_NEAR_BNO;
1579 args.mod = args.minleft = args.alignment = args.total = args.isfl = 1576 args.mod = args.minleft = args.alignment = args.total = args.isfl =
1580 args.userdata = args.minalignslop = 0; 1577 args.userdata = args.minalignslop = 0;
@@ -2356,6 +2353,7 @@ xfs_bmbt_newroot(
2356 args.userdata = args.minalignslop = 0; 2353 args.userdata = args.minalignslop = 0;
2357 args.minlen = args.maxlen = args.prod = 1; 2354 args.minlen = args.maxlen = args.prod = 1;
2358 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; 2355 args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL;
2356 args.firstblock = args.fsbno;
2359 if (args.fsbno == NULLFSBLOCK) { 2357 if (args.fsbno == NULLFSBLOCK) {
2360#ifdef DEBUG 2358#ifdef DEBUG
2361 if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { 2359 if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
@@ -2365,9 +2363,7 @@ xfs_bmbt_newroot(
2365#endif 2363#endif
2366 args.fsbno = INT_GET(*pp, ARCH_CONVERT); 2364 args.fsbno = INT_GET(*pp, ARCH_CONVERT);
2367 args.type = XFS_ALLOCTYPE_START_BNO; 2365 args.type = XFS_ALLOCTYPE_START_BNO;
2368 } else if (args.wasdel) 2366 } else
2369 args.type = XFS_ALLOCTYPE_FIRST_AG;
2370 else
2371 args.type = XFS_ALLOCTYPE_NEAR_BNO; 2367 args.type = XFS_ALLOCTYPE_NEAR_BNO;
2372 if ((error = xfs_alloc_vextent(&args))) { 2368 if ((error = xfs_alloc_vextent(&args))) {
2373 XFS_BMBT_TRACE_CURSOR(cur, ERROR); 2369 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 52d5d095fc35..ee2255bd6562 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 5fed15682dda..a4aa53974f76 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -23,7 +23,6 @@
23#include "xfs_inum.h" 23#include "xfs_inum.h"
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_dir.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_buf_item.h" 28#include "xfs_buf_item.h"
@@ -1030,9 +1029,9 @@ xfs_buf_iodone_callbacks(
1030 if ((XFS_BUF_TARGET(bp) != lasttarg) || 1029 if ((XFS_BUF_TARGET(bp) != lasttarg) ||
1031 (time_after(jiffies, (lasttime + 5*HZ)))) { 1030 (time_after(jiffies, (lasttime + 5*HZ)))) {
1032 lasttime = jiffies; 1031 lasttime = jiffies;
1033 prdev("XFS write error in file system meta-data " 1032 cmn_err(CE_ALERT, "Device %s, XFS metadata write error"
1034 "block 0x%llx in %s", 1033 " block 0x%llx in %s",
1035 XFS_BUF_TARGET(bp), 1034 XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)),
1036 (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname); 1035 (__uint64_t)XFS_BUF_ADDR(bp), mp->m_fsname);
1037 } 1036 }
1038 lasttarg = XFS_BUF_TARGET(bp); 1037 lasttarg = XFS_BUF_TARGET(bp);
@@ -1108,7 +1107,7 @@ xfs_buf_error_relse(
1108 XFS_BUF_ERROR(bp,0); 1107 XFS_BUF_ERROR(bp,0);
1109 xfs_buftrace("BUF_ERROR_RELSE", bp); 1108 xfs_buftrace("BUF_ERROR_RELSE", bp);
1110 if (! XFS_FORCED_SHUTDOWN(mp)) 1109 if (! XFS_FORCED_SHUTDOWN(mp))
1111 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 1110 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1112 /* 1111 /*
1113 * We have to unpin the pinned buffers so do the 1112 * We have to unpin the pinned buffers so do the
1114 * callbacks. 1113 * callbacks.
diff --git a/fs/xfs/xfs_cap.h b/fs/xfs/xfs_cap.h
index d0035c6e9514..7a0e482dd436 100644
--- a/fs/xfs/xfs_cap.h
+++ b/fs/xfs/xfs_cap.h
@@ -49,12 +49,12 @@ typedef struct xfs_cap_set {
49 49
50#include <linux/posix_cap_xattr.h> 50#include <linux/posix_cap_xattr.h>
51 51
52struct vnode; 52struct bhv_vnode;
53 53
54extern int xfs_cap_vhascap(struct vnode *); 54extern int xfs_cap_vhascap(struct bhv_vnode *);
55extern int xfs_cap_vset(struct vnode *, void *, size_t); 55extern int xfs_cap_vset(struct bhv_vnode *, void *, size_t);
56extern int xfs_cap_vget(struct vnode *, void *, size_t); 56extern int xfs_cap_vget(struct bhv_vnode *, void *, size_t);
57extern int xfs_cap_vremove(struct vnode *vp); 57extern int xfs_cap_vremove(struct bhv_vnode *);
58 58
59#define _CAP_EXISTS xfs_cap_vhascap 59#define _CAP_EXISTS xfs_cap_vhascap
60 60
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 8988b9051175..32ab61d17ace 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -43,7 +41,6 @@
43#include "xfs_bmap.h" 41#include "xfs_bmap.h"
44#include "xfs_attr.h" 42#include "xfs_attr.h"
45#include "xfs_attr_leaf.h" 43#include "xfs_attr_leaf.h"
46#include "xfs_dir_leaf.h"
47#include "xfs_dir2_data.h" 44#include "xfs_dir2_data.h"
48#include "xfs_dir2_leaf.h" 45#include "xfs_dir2_leaf.h"
49#include "xfs_dir2_block.h" 46#include "xfs_dir2_block.h"
@@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state)
159 max = state->path.active - 1; 156 max = state->path.active - 1;
160 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); 157 ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH));
161 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || 158 ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC ||
162 state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 159 state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC);
163 160
164 addblk = &state->path.blk[max]; /* initial dummy value */ 161 addblk = &state->path.blk[max]; /* initial dummy value */
165 for (i = max; (i >= 0) && addblk; state->path.active--, i--) { 162 for (i = max; (i >= 0) && addblk; state->path.active--, i--) {
@@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state)
199 return(error); /* GROT: attr inconsistent */ 196 return(error); /* GROT: attr inconsistent */
200 addblk = newblk; 197 addblk = newblk;
201 break; 198 break;
202 case XFS_DIR_LEAF_MAGIC:
203 ASSERT(XFS_DIR_IS_V1(state->mp));
204 error = xfs_dir_leaf_split(state, oldblk, newblk);
205 if ((error != 0) && (error != ENOSPC)) {
206 return(error); /* GROT: dir is inconsistent */
207 }
208 if (!error) {
209 addblk = newblk;
210 break;
211 }
212 /*
213 * Entry wouldn't fit, split the leaf again.
214 */
215 state->extravalid = 1;
216 if (state->inleaf) {
217 state->extraafter = 0; /* before newblk */
218 error = xfs_dir_leaf_split(state, oldblk,
219 &state->extrablk);
220 if (error)
221 return(error); /* GROT: dir incon. */
222 addblk = newblk;
223 } else {
224 state->extraafter = 1; /* after newblk */
225 error = xfs_dir_leaf_split(state, newblk,
226 &state->extrablk);
227 if (error)
228 return(error); /* GROT: dir incon. */
229 addblk = newblk;
230 }
231 break;
232 case XFS_DIR2_LEAFN_MAGIC: 199 case XFS_DIR2_LEAFN_MAGIC:
233 ASSERT(XFS_DIR_IS_V2(state->mp));
234 error = xfs_dir2_leafn_split(state, oldblk, newblk); 200 error = xfs_dir2_leafn_split(state, oldblk, newblk);
235 if (error) 201 if (error)
236 return error; 202 return error;
@@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
363 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - 329 size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
364 (char *)oldroot); 330 (char *)oldroot);
365 } else { 331 } else {
366 ASSERT(XFS_DIR_IS_V2(mp));
367 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); 332 ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
368 leaf = (xfs_dir2_leaf_t *)oldroot; 333 leaf = (xfs_dir2_leaf_t *)oldroot;
369 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - 334 size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
@@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
379 * Set up the new root node. 344 * Set up the new root node.
380 */ 345 */
381 error = xfs_da_node_create(args, 346 error = xfs_da_node_create(args,
382 args->whichfork == XFS_DATA_FORK && 347 (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0,
383 XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
384 be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); 348 be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
385 if (error) 349 if (error)
386 return(error); 350 return(error);
@@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
427 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 391 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
428 392
429 /* 393 /*
430 * With V2 the extra block is data or freespace. 394 * With V2 dirs the extra block is data or freespace.
431 */ 395 */
432 useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || 396 useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK;
433 state->args->whichfork == XFS_ATTR_FORK);
434 newcount = 1 + useextra; 397 newcount = 1 + useextra;
435 /* 398 /*
436 * Do we have to split the node? 399 * Do we have to split the node?
@@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
624 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); 587 ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
625 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); 588 ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
626 ASSERT(newblk->blkno != 0); 589 ASSERT(newblk->blkno != 0);
627 if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 590 if (state->args->whichfork == XFS_DATA_FORK)
628 ASSERT(newblk->blkno >= mp->m_dirleafblk && 591 ASSERT(newblk->blkno >= mp->m_dirleafblk &&
629 newblk->blkno < mp->m_dirfreeblk); 592 newblk->blkno < mp->m_dirfreeblk);
630 593
@@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state)
670 save_blk = &state->altpath.blk[ state->path.active-1 ]; 633 save_blk = &state->altpath.blk[ state->path.active-1 ];
671 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); 634 ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC);
672 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || 635 ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC ||
673 drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); 636 drop_blk->magic == XFS_DIR2_LEAFN_MAGIC);
674 637
675 /* 638 /*
676 * Walk back up the tree joining/deallocating as necessary. 639 * Walk back up the tree joining/deallocating as necessary.
@@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state)
693 return(0); 656 return(0);
694 xfs_attr_leaf_unbalance(state, drop_blk, save_blk); 657 xfs_attr_leaf_unbalance(state, drop_blk, save_blk);
695 break; 658 break;
696 case XFS_DIR_LEAF_MAGIC:
697 ASSERT(XFS_DIR_IS_V1(state->mp));
698 error = xfs_dir_leaf_toosmall(state, &action);
699 if (error)
700 return(error);
701 if (action == 0)
702 return(0);
703 xfs_dir_leaf_unbalance(state, drop_blk, save_blk);
704 break;
705 case XFS_DIR2_LEAFN_MAGIC: 659 case XFS_DIR2_LEAFN_MAGIC:
706 ASSERT(XFS_DIR_IS_V2(state->mp));
707 error = xfs_dir2_leafn_toosmall(state, &action); 660 error = xfs_dir2_leafn_toosmall(state, &action);
708 if (error) 661 if (error)
709 return error; 662 return error;
@@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
790 ASSERT(bp != NULL); 743 ASSERT(bp != NULL);
791 blkinfo = bp->data; 744 blkinfo = bp->data;
792 if (be16_to_cpu(oldroot->hdr.level) == 1) { 745 if (be16_to_cpu(oldroot->hdr.level) == 1) {
793 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 746 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC ||
794 be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); 747 be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
795 } else { 748 } else {
796 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); 749 ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
@@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
951 if (count == 0) 904 if (count == 0)
952 return; 905 return;
953 break; 906 break;
954 case XFS_DIR_LEAF_MAGIC:
955 ASSERT(XFS_DIR_IS_V1(state->mp));
956 lasthash = xfs_dir_leaf_lasthash(blk->bp, &count);
957 if (count == 0)
958 return;
959 break;
960 case XFS_DIR2_LEAFN_MAGIC: 907 case XFS_DIR2_LEAFN_MAGIC:
961 ASSERT(XFS_DIR_IS_V2(state->mp));
962 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); 908 lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count);
963 if (count == 0) 909 if (count == 0)
964 return; 910 return;
@@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1117 * Descend thru the B-tree searching each level for the right 1063 * Descend thru the B-tree searching each level for the right
1118 * node to use, until the right hashval is found. 1064 * node to use, until the right hashval is found.
1119 */ 1065 */
1120 if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) 1066 blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0;
1121 blkno = state->mp->m_dirleafblk;
1122 else
1123 blkno = 0;
1124 for (blk = &state->path.blk[0], state->path.active = 1; 1067 for (blk = &state->path.blk[0], state->path.active = 1;
1125 state->path.active <= XFS_DA_NODE_MAXDEPTH; 1068 state->path.active <= XFS_DA_NODE_MAXDEPTH;
1126 blk++, state->path.active++) { 1069 blk++, state->path.active++) {
@@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1137 } 1080 }
1138 curr = blk->bp->data; 1081 curr = blk->bp->data;
1139 ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || 1082 ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
1140 be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1083 be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
1141 be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); 1084 be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
1142 1085
1143 /* 1086 /*
@@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1190 blk->index = probe; 1133 blk->index = probe;
1191 blkno = be32_to_cpu(btree->before); 1134 blkno = be32_to_cpu(btree->before);
1192 } 1135 }
1193 } 1136 } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
1194 else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
1195 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); 1137 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
1196 break; 1138 break;
1197 } 1139 } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
1198 else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) {
1199 blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
1200 break;
1201 }
1202 else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
1203 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); 1140 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
1204 break; 1141 break;
1205 } 1142 }
@@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
1212 * next leaf and keep searching. 1149 * next leaf and keep searching.
1213 */ 1150 */
1214 for (;;) { 1151 for (;;) {
1215 if (blk->magic == XFS_DIR_LEAF_MAGIC) { 1152 if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
1216 ASSERT(XFS_DIR_IS_V1(state->mp));
1217 retval = xfs_dir_leaf_lookup_int(blk->bp, args,
1218 &blk->index);
1219 } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
1220 ASSERT(XFS_DIR_IS_V2(state->mp));
1221 retval = xfs_dir2_leafn_lookup_int(blk->bp, args, 1153 retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
1222 &blk->index, state); 1154 &blk->index, state);
1223 } 1155 }
@@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
1270 old_info = old_blk->bp->data; 1202 old_info = old_blk->bp->data;
1271 new_info = new_blk->bp->data; 1203 new_info = new_blk->bp->data;
1272 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || 1204 ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
1273 old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1205 old_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
1274 old_blk->magic == XFS_ATTR_LEAF_MAGIC); 1206 old_blk->magic == XFS_ATTR_LEAF_MAGIC);
1275 ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); 1207 ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
1276 ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); 1208 ASSERT(new_blk->magic == be16_to_cpu(new_info->magic));
@@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
1280 case XFS_ATTR_LEAF_MAGIC: 1212 case XFS_ATTR_LEAF_MAGIC:
1281 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); 1213 before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp);
1282 break; 1214 break;
1283 case XFS_DIR_LEAF_MAGIC:
1284 ASSERT(XFS_DIR_IS_V1(state->mp));
1285 before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp);
1286 break;
1287 case XFS_DIR2_LEAFN_MAGIC: 1215 case XFS_DIR2_LEAFN_MAGIC:
1288 ASSERT(XFS_DIR_IS_V2(state->mp));
1289 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); 1216 before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp);
1290 break; 1217 break;
1291 case XFS_DA_NODE_MAGIC: 1218 case XFS_DA_NODE_MAGIC:
@@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1404 save_info = save_blk->bp->data; 1331 save_info = save_blk->bp->data;
1405 drop_info = drop_blk->bp->data; 1332 drop_info = drop_blk->bp->data;
1406 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || 1333 ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
1407 save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || 1334 save_blk->magic == XFS_DIR2_LEAFN_MAGIC ||
1408 save_blk->magic == XFS_ATTR_LEAF_MAGIC); 1335 save_blk->magic == XFS_ATTR_LEAF_MAGIC);
1409 ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); 1336 ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
1410 ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); 1337 ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic));
@@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1529 ASSERT(blk->bp != NULL); 1456 ASSERT(blk->bp != NULL);
1530 info = blk->bp->data; 1457 info = blk->bp->data;
1531 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || 1458 ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC ||
1532 be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || 1459 be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC ||
1533 be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); 1460 be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
1534 blk->magic = be16_to_cpu(info->magic); 1461 blk->magic = be16_to_cpu(info->magic);
1535 if (blk->magic == XFS_DA_NODE_MAGIC) { 1462 if (blk->magic == XFS_DA_NODE_MAGIC) {
@@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
1548 blk->hashval = xfs_attr_leaf_lasthash(blk->bp, 1475 blk->hashval = xfs_attr_leaf_lasthash(blk->bp,
1549 NULL); 1476 NULL);
1550 break; 1477 break;
1551 case XFS_DIR_LEAF_MAGIC:
1552 ASSERT(XFS_DIR_IS_V1(state->mp));
1553 blk->hashval = xfs_dir_leaf_lasthash(blk->bp,
1554 NULL);
1555 break;
1556 case XFS_DIR2_LEAFN_MAGIC: 1478 case XFS_DIR2_LEAFN_MAGIC:
1557 ASSERT(XFS_DIR_IS_V2(state->mp));
1558 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, 1479 blk->hashval = xfs_dir2_leafn_lasthash(blk->bp,
1559 NULL); 1480 NULL);
1560 break; 1481 break;
1561 default: 1482 default:
1562 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || 1483 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC ||
1563 blk->magic == 1484 blk->magic == XFS_DIR2_LEAFN_MAGIC);
1564 XFS_DIRX_LEAF_MAGIC(state->mp));
1565 break; 1485 break;
1566 } 1486 }
1567 } 1487 }
@@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1620 xfs_bmbt_irec_t *mapp; 1540 xfs_bmbt_irec_t *mapp;
1621 xfs_inode_t *dp; 1541 xfs_inode_t *dp;
1622 int nmap, error, w, count, c, got, i, mapi; 1542 int nmap, error, w, count, c, got, i, mapi;
1623 xfs_fsize_t size;
1624 xfs_trans_t *tp; 1543 xfs_trans_t *tp;
1625 xfs_mount_t *mp; 1544 xfs_mount_t *mp;
1626 1545
@@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1631 /* 1550 /*
1632 * For new directories adjust the file offset and block count. 1551 * For new directories adjust the file offset and block count.
1633 */ 1552 */
1634 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { 1553 if (w == XFS_DATA_FORK) {
1635 bno = mp->m_dirleafblk; 1554 bno = mp->m_dirleafblk;
1636 count = mp->m_dirblkfsbs; 1555 count = mp->m_dirblkfsbs;
1637 } else { 1556 } else {
@@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1641 /* 1560 /*
1642 * Find a spot in the file space to put the new block. 1561 * Find a spot in the file space to put the new block.
1643 */ 1562 */
1644 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { 1563 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w)))
1645 return error; 1564 return error;
1646 } 1565 if (w == XFS_DATA_FORK)
1647 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
1648 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); 1566 ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk);
1649 /* 1567 /*
1650 * Try mapping it in one filesystem block. 1568 * Try mapping it in one filesystem block.
@@ -1655,7 +1573,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1655 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| 1573 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
1656 XFS_BMAPI_CONTIG, 1574 XFS_BMAPI_CONTIG,
1657 args->firstblock, args->total, &map, &nmap, 1575 args->firstblock, args->total, &map, &nmap,
1658 args->flist))) { 1576 args->flist, NULL))) {
1659 return error; 1577 return error;
1660 } 1578 }
1661 ASSERT(nmap <= 1); 1579 ASSERT(nmap <= 1);
@@ -1676,7 +1594,8 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1676 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE| 1594 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_WRITE|
1677 XFS_BMAPI_METADATA, 1595 XFS_BMAPI_METADATA,
1678 args->firstblock, args->total, 1596 args->firstblock, args->total,
1679 &mapp[mapi], &nmap, args->flist))) { 1597 &mapp[mapi], &nmap, args->flist,
1598 NULL))) {
1680 kmem_free(mapp, sizeof(*mapp) * count); 1599 kmem_free(mapp, sizeof(*mapp) * count);
1681 return error; 1600 return error;
1682 } 1601 }
@@ -1705,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
1705 if (mapp != &map) 1624 if (mapp != &map)
1706 kmem_free(mapp, sizeof(*mapp) * count); 1625 kmem_free(mapp, sizeof(*mapp) * count);
1707 *new_blkno = (xfs_dablk_t)bno; 1626 *new_blkno = (xfs_dablk_t)bno;
1708 /*
1709 * For version 1 directories, adjust the file size if it changed.
1710 */
1711 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1712 ASSERT(mapi == 1);
1713 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1714 return error;
1715 size = XFS_FSB_TO_B(mp, bno);
1716 if (size != dp->i_d.di_size) {
1717 dp->i_d.di_size = size;
1718 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1719 }
1720 }
1721 return 0; 1627 return 0;
1722} 1628}
1723 1629
@@ -1742,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1742 int error, w, entno, level, dead_level; 1648 int error, w, entno, level, dead_level;
1743 xfs_da_blkinfo_t *dead_info, *sib_info; 1649 xfs_da_blkinfo_t *dead_info, *sib_info;
1744 xfs_da_intnode_t *par_node, *dead_node; 1650 xfs_da_intnode_t *par_node, *dead_node;
1745 xfs_dir_leafblock_t *dead_leaf;
1746 xfs_dir2_leaf_t *dead_leaf2; 1651 xfs_dir2_leaf_t *dead_leaf2;
1747 xfs_dahash_t dead_hash; 1652 xfs_dahash_t dead_hash;
1748 1653
@@ -1753,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1753 w = args->whichfork; 1658 w = args->whichfork;
1754 ASSERT(w == XFS_DATA_FORK); 1659 ASSERT(w == XFS_DATA_FORK);
1755 mp = ip->i_mount; 1660 mp = ip->i_mount;
1756 if (XFS_DIR_IS_V2(mp)) { 1661 lastoff = mp->m_dirfreeblk;
1757 lastoff = mp->m_dirfreeblk; 1662 error = xfs_bmap_last_before(tp, ip, &lastoff, w);
1758 error = xfs_bmap_last_before(tp, ip, &lastoff, w);
1759 } else
1760 error = xfs_bmap_last_offset(tp, ip, &lastoff, w);
1761 if (error) 1663 if (error)
1762 return error; 1664 return error;
1763 if (unlikely(lastoff == 0)) { 1665 if (unlikely(lastoff == 0)) {
@@ -1780,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1780 /* 1682 /*
1781 * Get values from the moved block. 1683 * Get values from the moved block.
1782 */ 1684 */
1783 if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) { 1685 if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
1784 ASSERT(XFS_DIR_IS_V1(mp));
1785 dead_leaf = (xfs_dir_leafblock_t *)dead_info;
1786 dead_level = 0;
1787 dead_hash =
1788 INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
1789 } else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
1790 ASSERT(XFS_DIR_IS_V2(mp));
1791 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; 1686 dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
1792 dead_level = 0; 1687 dead_level = 0;
1793 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); 1688 dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
@@ -1842,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
1842 xfs_da_buf_done(sib_buf); 1737 xfs_da_buf_done(sib_buf);
1843 sib_buf = NULL; 1738 sib_buf = NULL;
1844 } 1739 }
1845 par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; 1740 par_blkno = mp->m_dirleafblk;
1846 level = -1; 1741 level = -1;
1847 /* 1742 /*
1848 * Walk down the tree looking for the parent of the moved block. 1743 * Walk down the tree looking for the parent of the moved block.
@@ -1941,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1941{ 1836{
1942 xfs_inode_t *dp; 1837 xfs_inode_t *dp;
1943 int done, error, w, count; 1838 int done, error, w, count;
1944 xfs_fileoff_t bno;
1945 xfs_fsize_t size;
1946 xfs_trans_t *tp; 1839 xfs_trans_t *tp;
1947 xfs_mount_t *mp; 1840 xfs_mount_t *mp;
1948 1841
@@ -1950,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1950 w = args->whichfork; 1843 w = args->whichfork;
1951 tp = args->trans; 1844 tp = args->trans;
1952 mp = dp->i_mount; 1845 mp = dp->i_mount;
1953 if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1846 if (w == XFS_DATA_FORK)
1954 count = mp->m_dirblkfsbs; 1847 count = mp->m_dirblkfsbs;
1955 else 1848 else
1956 count = 1; 1849 count = 1;
@@ -1961,34 +1854,17 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
1961 */ 1854 */
1962 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count, 1855 if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
1963 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA, 1856 XFS_BMAPI_AFLAG(w)|XFS_BMAPI_METADATA,
1964 0, args->firstblock, args->flist, 1857 0, args->firstblock, args->flist, NULL,
1965 &done)) == ENOSPC) { 1858 &done)) == ENOSPC) {
1966 if (w != XFS_DATA_FORK) 1859 if (w != XFS_DATA_FORK)
1967 goto done; 1860 break;
1968 if ((error = xfs_da_swap_lastblock(args, &dead_blkno, 1861 if ((error = xfs_da_swap_lastblock(args, &dead_blkno,
1969 &dead_buf))) 1862 &dead_buf)))
1970 goto done; 1863 break;
1971 } else if (error) 1864 } else {
1972 goto done;
1973 else
1974 break; 1865 break;
1975 }
1976 ASSERT(done);
1977 xfs_da_binval(tp, dead_buf);
1978 /*
1979 * Adjust the directory size for version 1.
1980 */
1981 if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) {
1982 if ((error = xfs_bmap_last_offset(tp, dp, &bno, w)))
1983 return error;
1984 size = XFS_FSB_TO_B(dp->i_mount, bno);
1985 if (size != dp->i_d.di_size) {
1986 dp->i_d.di_size = size;
1987 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1988 } 1866 }
1989 } 1867 }
1990 return 0;
1991done:
1992 xfs_da_binval(tp, dead_buf); 1868 xfs_da_binval(tp, dead_buf);
1993 return error; 1869 return error;
1994} 1870}
@@ -2049,10 +1925,7 @@ xfs_da_do_buf(
2049 xfs_dabuf_t *rbp; 1925 xfs_dabuf_t *rbp;
2050 1926
2051 mp = dp->i_mount; 1927 mp = dp->i_mount;
2052 if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) 1928 nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1;
2053 nfsb = mp->m_dirblkfsbs;
2054 else
2055 nfsb = 1;
2056 mappedbno = *mappedbnop; 1929 mappedbno = *mappedbnop;
2057 /* 1930 /*
2058 * Caller doesn't have a mapping. -2 means don't complain 1931 * Caller doesn't have a mapping. -2 means don't complain
@@ -2086,7 +1959,7 @@ xfs_da_do_buf(
2086 nfsb, 1959 nfsb,
2087 XFS_BMAPI_METADATA | 1960 XFS_BMAPI_METADATA |
2088 XFS_BMAPI_AFLAG(whichfork), 1961 XFS_BMAPI_AFLAG(whichfork),
2089 NULL, 0, mapp, &nmap, NULL))) 1962 NULL, 0, mapp, &nmap, NULL, NULL)))
2090 goto exit0; 1963 goto exit0;
2091 } 1964 }
2092 } else { 1965 } else {
@@ -2198,7 +2071,6 @@ xfs_da_do_buf(
2198 magic1 = be32_to_cpu(data->hdr.magic); 2071 magic1 = be32_to_cpu(data->hdr.magic);
2199 if (unlikely( 2072 if (unlikely(
2200 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && 2073 XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
2201 (magic != XFS_DIR_LEAF_MAGIC) &&
2202 (magic != XFS_ATTR_LEAF_MAGIC) && 2074 (magic != XFS_ATTR_LEAF_MAGIC) &&
2203 (magic != XFS_DIR2_LEAF1_MAGIC) && 2075 (magic != XFS_DIR2_LEAF1_MAGIC) &&
2204 (magic != XFS_DIR2_LEAFN_MAGIC) && 2076 (magic != XFS_DIR2_LEAFN_MAGIC) &&
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 243a730d5ec8..4ab865ec8b82 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -36,14 +36,10 @@ struct zone;
36 * level in the Btree, and to identify which type of block this is. 36 * level in the Btree, and to identify which type of block this is.
37 */ 37 */
38#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ 38#define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */
39#define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */
40#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ 39#define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
41#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ 40#define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */
42#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ 41#define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */
43 42
44#define XFS_DIRX_LEAF_MAGIC(mp) \
45 (XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC)
46
47typedef struct xfs_da_blkinfo { 43typedef struct xfs_da_blkinfo {
48 __be32 forw; /* previous block in list */ 44 __be32 forw; /* previous block in list */
49 __be32 back; /* following block in list */ 45 __be32 back; /* following block in list */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 4968a6358e61..80562b60fb95 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -54,24 +52,14 @@ xfs_swapext(
54 xfs_swapext_t __user *sxu) 52 xfs_swapext_t __user *sxu)
55{ 53{
56 xfs_swapext_t *sxp; 54 xfs_swapext_t *sxp;
57 xfs_inode_t *ip=NULL, *tip=NULL, *ips[2]; 55 xfs_inode_t *ip=NULL, *tip=NULL;
58 xfs_trans_t *tp;
59 xfs_mount_t *mp; 56 xfs_mount_t *mp;
60 xfs_bstat_t *sbp;
61 struct file *fp = NULL, *tfp = NULL; 57 struct file *fp = NULL, *tfp = NULL;
62 vnode_t *vp, *tvp; 58 bhv_vnode_t *vp, *tvp;
63 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
64 int ilf_fields, tilf_fields;
65 int error = 0; 59 int error = 0;
66 xfs_ifork_t *tempifp, *ifp, *tifp;
67 __uint64_t tmp;
68 int aforkblks = 0;
69 int taforkblks = 0;
70 char locked = 0;
71 60
72 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL); 61 sxp = kmem_alloc(sizeof(xfs_swapext_t), KM_MAYFAIL);
73 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); 62 if (!sxp) {
74 if (!sxp || !tempifp) {
75 error = XFS_ERROR(ENOMEM); 63 error = XFS_ERROR(ENOMEM);
76 goto error0; 64 goto error0;
77 } 65 }
@@ -118,14 +106,56 @@ xfs_swapext(
118 106
119 mp = ip->i_mount; 107 mp = ip->i_mount;
120 108
121 sbp = &sxp->sx_stat;
122
123 if (XFS_FORCED_SHUTDOWN(mp)) { 109 if (XFS_FORCED_SHUTDOWN(mp)) {
124 error = XFS_ERROR(EIO); 110 error = XFS_ERROR(EIO);
125 goto error0; 111 goto error0;
126 } 112 }
127 113
128 locked = 1; 114 error = XFS_SWAP_EXTENTS(mp, &ip->i_iocore, &tip->i_iocore, sxp);
115
116 error0:
117 if (fp != NULL)
118 fput(fp);
119 if (tfp != NULL)
120 fput(tfp);
121
122 if (sxp != NULL)
123 kmem_free(sxp, sizeof(xfs_swapext_t));
124
125 return error;
126}
127
128int
129xfs_swap_extents(
130 xfs_inode_t *ip,
131 xfs_inode_t *tip,
132 xfs_swapext_t *sxp)
133{
134 xfs_mount_t *mp;
135 xfs_inode_t *ips[2];
136 xfs_trans_t *tp;
137 xfs_bstat_t *sbp = &sxp->sx_stat;
138 bhv_vnode_t *vp, *tvp;
139 xfs_ifork_t *tempifp, *ifp, *tifp;
140 int ilf_fields, tilf_fields;
141 static uint lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
142 int error = 0;
143 int aforkblks = 0;
144 int taforkblks = 0;
145 __uint64_t tmp;
146 char locked = 0;
147
148 mp = ip->i_mount;
149
150 tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
151 if (!tempifp) {
152 error = XFS_ERROR(ENOMEM);
153 goto error0;
154 }
155
156 sbp = &sxp->sx_stat;
157 vp = XFS_ITOV(ip);
158 tvp = XFS_ITOV(tip);
129 159
130 /* Lock in i_ino order */ 160 /* Lock in i_ino order */
131 if (ip->i_ino < tip->i_ino) { 161 if (ip->i_ino < tip->i_ino) {
@@ -137,6 +167,7 @@ xfs_swapext(
137 } 167 }
138 168
139 xfs_lock_inodes(ips, 2, 0, lock_flags); 169 xfs_lock_inodes(ips, 2, 0, lock_flags);
170 locked = 1;
140 171
141 /* Check permissions */ 172 /* Check permissions */
142 error = xfs_iaccess(ip, S_IWUSR, NULL); 173 error = xfs_iaccess(ip, S_IWUSR, NULL);
@@ -169,7 +200,7 @@ xfs_swapext(
169 200
170 if (VN_CACHED(tvp) != 0) { 201 if (VN_CACHED(tvp) != 0) {
171 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1); 202 xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
172 VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED); 203 bhv_vop_flushinval_pages(tvp, 0, -1, FI_REMAPF_LOCKED);
173 } 204 }
174 205
175 /* Verify O_DIRECT for ftmp */ 206 /* Verify O_DIRECT for ftmp */
@@ -214,7 +245,7 @@ xfs_swapext(
214 /* We need to fail if the file is memory mapped. Once we have tossed 245 /* We need to fail if the file is memory mapped. Once we have tossed
215 * all existing pages, the page fault will have no option 246 * all existing pages, the page fault will have no option
216 * but to go to the filesystem for pages. By making the page fault call 247 * but to go to the filesystem for pages. By making the page fault call
217 * VOP_READ (or write in the case of autogrow) they block on the iolock 248 * vop_read (or write in the case of autogrow) they block on the iolock
218 * until we have switched the extents. 249 * until we have switched the extents.
219 */ 250 */
220 if (VN_MAPPED(vp)) { 251 if (VN_MAPPED(vp)) {
@@ -233,7 +264,7 @@ xfs_swapext(
233 * fields change. 264 * fields change.
234 */ 265 */
235 266
236 VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); 267 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
237 268
238 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); 269 tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT);
239 if ((error = xfs_trans_reserve(tp, 0, 270 if ((error = xfs_trans_reserve(tp, 0,
@@ -360,16 +391,7 @@ xfs_swapext(
360 xfs_iunlock(ip, lock_flags); 391 xfs_iunlock(ip, lock_flags);
361 xfs_iunlock(tip, lock_flags); 392 xfs_iunlock(tip, lock_flags);
362 } 393 }
363
364 if (fp != NULL)
365 fput(fp);
366 if (tfp != NULL)
367 fput(tfp);
368
369 if (sxp != NULL)
370 kmem_free(sxp, sizeof(xfs_swapext_t));
371 if (tempifp != NULL) 394 if (tempifp != NULL)
372 kmem_free(tempifp, sizeof(xfs_ifork_t)); 395 kmem_free(tempifp, sizeof(xfs_ifork_t));
373
374 return error; 396 return error;
375} 397}
diff --git a/fs/xfs/xfs_dfrag.h b/fs/xfs/xfs_dfrag.h
index f678559abc45..da178205be68 100644
--- a/fs/xfs/xfs_dfrag.h
+++ b/fs/xfs/xfs_dfrag.h
@@ -48,6 +48,9 @@ typedef struct xfs_swapext
48 */ 48 */
49int xfs_swapext(struct xfs_swapext __user *sx); 49int xfs_swapext(struct xfs_swapext __user *sx);
50 50
51int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,
52 struct xfs_swapext *sxp);
53
51#endif /* __KERNEL__ */ 54#endif /* __KERNEL__ */
52 55
53#endif /* __XFS_DFRAG_H__ */ 56#endif /* __XFS_DFRAG_H__ */
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index 79d0d9e1fbab..b33826961c45 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -85,7 +85,6 @@ typedef struct xfs_dinode
85 union { 85 union {
86 xfs_bmdr_block_t di_bmbt; /* btree root block */ 86 xfs_bmdr_block_t di_bmbt; /* btree root block */
87 xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ 87 xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
88 xfs_dir_shortform_t di_dirsf; /* shortform directory */
89 xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ 88 xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
90 char di_c[1]; /* local contents */ 89 char di_c[1]; /* local contents */
91 xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ 90 xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
@@ -257,6 +256,7 @@ typedef enum xfs_dinode_fmt
257#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */ 256#define XFS_DIFLAG_NOSYMLINKS_BIT 10 /* disallow symlink creation */
258#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ 257#define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */
259#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ 258#define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */
259#define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */
260#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) 260#define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT)
261#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) 261#define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT)
262#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) 262#define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT)
@@ -270,12 +270,13 @@ typedef enum xfs_dinode_fmt
270#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT) 270#define XFS_DIFLAG_NOSYMLINKS (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
271#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) 271#define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT)
272#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) 272#define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT)
273#define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
273 274
274#define XFS_DIFLAG_ANY \ 275#define XFS_DIFLAG_ANY \
275 (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ 276 (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
276 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ 277 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
277 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ 278 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
278 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ 279 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \
279 XFS_DIFLAG_EXTSZINHERIT) 280 XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG)
280 281
281#endif /* __XFS_DINODE_H__ */ 282#endif /* __XFS_DINODE_H__ */
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
deleted file mode 100644
index 9cc702a839a3..000000000000
--- a/fs/xfs/xfs_dir.c
+++ /dev/null
@@ -1,1217 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_types.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h"
27#include "xfs_dmapi.h"
28#include "xfs_mount.h"
29#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h"
33#include "xfs_alloc.h"
34#include "xfs_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h"
38#include "xfs_dinode.h"
39#include "xfs_inode.h"
40#include "xfs_bmap.h"
41#include "xfs_dir_leaf.h"
42#include "xfs_error.h"
43
44/*
45 * xfs_dir.c
46 *
47 * Provide the external interfaces to manage directories.
48 */
49
50/*========================================================================
51 * Function prototypes for the kernel.
52 *========================================================================*/
53
54/*
55 * Functions for the dirops interfaces.
56 */
57static void xfs_dir_mount(struct xfs_mount *mp);
58
59static int xfs_dir_isempty(struct xfs_inode *dp);
60
61static int xfs_dir_init(struct xfs_trans *trans,
62 struct xfs_inode *dir,
63 struct xfs_inode *parent_dir);
64
65static int xfs_dir_createname(struct xfs_trans *trans,
66 struct xfs_inode *dp,
67 char *name_string,
68 int name_len,
69 xfs_ino_t inode_number,
70 xfs_fsblock_t *firstblock,
71 xfs_bmap_free_t *flist,
72 xfs_extlen_t total);
73
74static int xfs_dir_lookup(struct xfs_trans *tp,
75 struct xfs_inode *dp,
76 char *name_string,
77 int name_length,
78 xfs_ino_t *inode_number);
79
80static int xfs_dir_removename(struct xfs_trans *trans,
81 struct xfs_inode *dp,
82 char *name_string,
83 int name_length,
84 xfs_ino_t ino,
85 xfs_fsblock_t *firstblock,
86 xfs_bmap_free_t *flist,
87 xfs_extlen_t total);
88
89static int xfs_dir_getdents(struct xfs_trans *tp,
90 struct xfs_inode *dp,
91 struct uio *uiop,
92 int *eofp);
93
94static int xfs_dir_replace(struct xfs_trans *tp,
95 struct xfs_inode *dp,
96 char *name_string,
97 int name_length,
98 xfs_ino_t inode_number,
99 xfs_fsblock_t *firstblock,
100 xfs_bmap_free_t *flist,
101 xfs_extlen_t total);
102
103static int xfs_dir_canenter(struct xfs_trans *tp,
104 struct xfs_inode *dp,
105 char *name_string,
106 int name_length);
107
108static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp,
109 xfs_dinode_t *dip);
110
111xfs_dirops_t xfsv1_dirops = {
112 .xd_mount = xfs_dir_mount,
113 .xd_isempty = xfs_dir_isempty,
114 .xd_init = xfs_dir_init,
115 .xd_createname = xfs_dir_createname,
116 .xd_lookup = xfs_dir_lookup,
117 .xd_removename = xfs_dir_removename,
118 .xd_getdents = xfs_dir_getdents,
119 .xd_replace = xfs_dir_replace,
120 .xd_canenter = xfs_dir_canenter,
121 .xd_shortform_validate_ondisk = xfs_dir_shortform_validate_ondisk,
122 .xd_shortform_to_single = xfs_dir_shortform_to_leaf,
123};
124
125/*
126 * Internal routines when dirsize == XFS_LBSIZE(mp).
127 */
128STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args);
129STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries,
130 int *total_namebytes);
131STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
132 uio_t *uio, int *eofp,
133 xfs_dirent_t *dbp,
134 xfs_dir_put_t put);
135STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args);
136
137/*
138 * Internal routines when dirsize > XFS_LBSIZE(mp).
139 */
140STATIC int xfs_dir_node_addname(xfs_da_args_t *args);
141STATIC int xfs_dir_node_lookup(xfs_da_args_t *args);
142STATIC int xfs_dir_node_removename(xfs_da_args_t *args);
143STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp,
144 uio_t *uio, int *eofp,
145 xfs_dirent_t *dbp,
146 xfs_dir_put_t put);
147STATIC int xfs_dir_node_replace(xfs_da_args_t *args);
148
149#if defined(XFS_DIR_TRACE)
150ktrace_t *xfs_dir_trace_buf;
151#endif
152
153
154/*========================================================================
155 * Overall external interface routines.
156 *========================================================================*/
157
158xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
159
160/*
161 * One-time startup routine called from xfs_init().
162 */
163void
164xfs_dir_startup(void)
165{
166 xfs_dir_hash_dot = xfs_da_hashname(".", 1);
167 xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
168}
169
170/*
171 * Initialize directory-related fields in the mount structure.
172 */
173static void
174xfs_dir_mount(xfs_mount_t *mp)
175{
176 uint shortcount, leafcount, count;
177
178 mp->m_dirversion = 1;
179 if (!(mp->m_flags & XFS_MOUNT_ATTR2)) {
180 shortcount = (mp->m_attroffset -
181 (uint)sizeof(xfs_dir_sf_hdr_t)) /
182 (uint)sizeof(xfs_dir_sf_entry_t);
183 leafcount = (XFS_LBSIZE(mp) -
184 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
185 ((uint)sizeof(xfs_dir_leaf_entry_t) +
186 (uint)sizeof(xfs_dir_leaf_name_t));
187 } else {
188 shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) -
189 (uint)sizeof(xfs_dir_sf_hdr_t)) /
190 (uint)sizeof(xfs_dir_sf_entry_t);
191 leafcount = (XFS_LBSIZE(mp) -
192 (uint)sizeof(xfs_dir_leaf_hdr_t)) /
193 ((uint)sizeof(xfs_dir_leaf_entry_t) +
194 (uint)sizeof(xfs_dir_leaf_name_t));
195 }
196 count = shortcount > leafcount ? shortcount : leafcount;
197 mp->m_dircook_elog = xfs_da_log2_roundup(count + 1);
198 ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog);
199 mp->m_dir_node_ents = mp->m_attr_node_ents =
200 (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) /
201 (uint)sizeof(xfs_da_node_entry_t);
202 mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100;
203 mp->m_dirblksize = mp->m_sb.sb_blocksize;
204 mp->m_dirblkfsbs = 1;
205}
206
207/*
208 * Return 1 if directory contains only "." and "..".
209 */
210static int
211xfs_dir_isempty(xfs_inode_t *dp)
212{
213 xfs_dir_sf_hdr_t *hdr;
214
215 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
216 if (dp->i_d.di_size == 0)
217 return(1);
218 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
219 return(0);
220 hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
221 return(hdr->count == 0);
222}
223
224/*
225 * Initialize a directory with its "." and ".." entries.
226 */
227static int
228xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir)
229{
230 xfs_da_args_t args;
231 int error;
232
233 memset((char *)&args, 0, sizeof(args));
234 args.dp = dir;
235 args.trans = trans;
236
237 ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR);
238 if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino)))
239 return error;
240
241 return(xfs_dir_shortform_create(&args, parent_dir->i_ino));
242}
243
244/*
245 * Generic handler routine to add a name to a directory.
246 * Transitions directory from shortform to Btree as necessary.
247 */
248static int /* error */
249xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
250 int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock,
251 xfs_bmap_free_t *flist, xfs_extlen_t total)
252{
253 xfs_da_args_t args;
254 int retval, newsize, done;
255
256 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
257
258 if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
259 return (retval);
260
261 XFS_STATS_INC(xs_dir_create);
262 /*
263 * Fill in the arg structure for this request.
264 */
265 args.name = name;
266 args.namelen = namelen;
267 args.hashval = xfs_da_hashname(name, namelen);
268 args.inumber = inum;
269 args.dp = dp;
270 args.firstblock = firstblock;
271 args.flist = flist;
272 args.total = total;
273 args.whichfork = XFS_DATA_FORK;
274 args.trans = trans;
275 args.justcheck = 0;
276 args.addname = args.oknoent = 1;
277
278 /*
279 * Decide on what work routines to call based on the inode size.
280 */
281 done = 0;
282 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
283 newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
284 if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) {
285 retval = xfs_dir_shortform_addname(&args);
286 done = 1;
287 } else {
288 if (total == 0)
289 return XFS_ERROR(ENOSPC);
290 retval = xfs_dir_shortform_to_leaf(&args);
291 done = retval != 0;
292 }
293 }
294 if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
295 retval = xfs_dir_leaf_addname(&args);
296 done = retval != ENOSPC;
297 if (!done) {
298 if (total == 0)
299 return XFS_ERROR(ENOSPC);
300 retval = xfs_dir_leaf_to_node(&args);
301 done = retval != 0;
302 }
303 }
304 if (!done) {
305 retval = xfs_dir_node_addname(&args);
306 }
307 return(retval);
308}
309
310/*
311 * Generic handler routine to check if a name can be added to a directory,
312 * without adding any blocks to the directory.
313 */
314static int /* error */
315xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen)
316{
317 xfs_da_args_t args;
318 int retval, newsize;
319
320 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
321 /*
322 * Fill in the arg structure for this request.
323 */
324 args.name = name;
325 args.namelen = namelen;
326 args.hashval = xfs_da_hashname(name, namelen);
327 args.inumber = 0;
328 args.dp = dp;
329 args.firstblock = NULL;
330 args.flist = NULL;
331 args.total = 0;
332 args.whichfork = XFS_DATA_FORK;
333 args.trans = trans;
334 args.justcheck = args.addname = args.oknoent = 1;
335
336 /*
337 * Decide on what work routines to call based on the inode size.
338 */
339 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
340 newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen);
341 if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp))
342 retval = 0;
343 else
344 retval = XFS_ERROR(ENOSPC);
345 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
346 retval = xfs_dir_leaf_addname(&args);
347 } else {
348 retval = xfs_dir_node_addname(&args);
349 }
350 return(retval);
351}
352
353/*
354 * Generic handler routine to remove a name from a directory.
355 * Transitions directory from Btree to shortform as necessary.
356 */
357static int /* error */
358xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name,
359 int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock,
360 xfs_bmap_free_t *flist, xfs_extlen_t total)
361{
362 xfs_da_args_t args;
363 int count, totallen, newsize, retval;
364
365 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
366 XFS_STATS_INC(xs_dir_remove);
367 /*
368 * Fill in the arg structure for this request.
369 */
370 args.name = name;
371 args.namelen = namelen;
372 args.hashval = xfs_da_hashname(name, namelen);
373 args.inumber = ino;
374 args.dp = dp;
375 args.firstblock = firstblock;
376 args.flist = flist;
377 args.total = total;
378 args.whichfork = XFS_DATA_FORK;
379 args.trans = trans;
380 args.justcheck = args.addname = args.oknoent = 0;
381
382 /*
383 * Decide on what work routines to call based on the inode size.
384 */
385 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
386 retval = xfs_dir_shortform_removename(&args);
387 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
388 retval = xfs_dir_leaf_removename(&args, &count, &totallen);
389 if (retval == 0) {
390 newsize = XFS_DIR_SF_ALLFIT(count, totallen);
391 if (newsize <= XFS_IFORK_DSIZE(dp)) {
392 retval = xfs_dir_leaf_to_shortform(&args);
393 }
394 }
395 } else {
396 retval = xfs_dir_node_removename(&args);
397 }
398 return(retval);
399}
400
401static int /* error */
402xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
403 xfs_ino_t *inum)
404{
405 xfs_da_args_t args;
406 int retval;
407
408 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
409
410 XFS_STATS_INC(xs_dir_lookup);
411 /*
412 * Fill in the arg structure for this request.
413 */
414 args.name = name;
415 args.namelen = namelen;
416 args.hashval = xfs_da_hashname(name, namelen);
417 args.inumber = 0;
418 args.dp = dp;
419 args.firstblock = NULL;
420 args.flist = NULL;
421 args.total = 0;
422 args.whichfork = XFS_DATA_FORK;
423 args.trans = trans;
424 args.justcheck = args.addname = 0;
425 args.oknoent = 1;
426
427 /*
428 * Decide on what work routines to call based on the inode size.
429 */
430 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
431 retval = xfs_dir_shortform_lookup(&args);
432 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
433 retval = xfs_dir_leaf_lookup(&args);
434 } else {
435 retval = xfs_dir_node_lookup(&args);
436 }
437 if (retval == EEXIST)
438 retval = 0;
439 *inum = args.inumber;
440 return(retval);
441}
442
443/*
444 * Implement readdir.
445 */
446static int /* error */
447xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp)
448{
449 xfs_dirent_t *dbp;
450 int alignment, retval;
451 xfs_dir_put_t put;
452
453 XFS_STATS_INC(xs_dir_getdents);
454 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
455
456 /*
457 * If our caller has given us a single contiguous memory buffer,
458 * just work directly within that buffer. If it's in user memory,
459 * lock it down first.
460 */
461 alignment = sizeof(xfs_off_t) - 1;
462 if ((uio->uio_iovcnt == 1) &&
463 (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) &&
464 ((uio->uio_iov[0].iov_len & alignment) == 0)) {
465 dbp = NULL;
466 put = xfs_dir_put_dirent64_direct;
467 } else {
468 dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP);
469 put = xfs_dir_put_dirent64_uio;
470 }
471
472 /*
473 * Decide on what work routines to call based on the inode size.
474 */
475 *eofp = 0;
476
477 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
478 retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put);
479 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
480 retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put);
481 } else {
482 retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put);
483 }
484 if (dbp != NULL)
485 kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN);
486
487 return(retval);
488}
489
490static int /* error */
491xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen,
492 xfs_ino_t inum, xfs_fsblock_t *firstblock,
493 xfs_bmap_free_t *flist, xfs_extlen_t total)
494{
495 xfs_da_args_t args;
496 int retval;
497
498 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
499
500 if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
501 return retval;
502
503 /*
504 * Fill in the arg structure for this request.
505 */
506 args.name = name;
507 args.namelen = namelen;
508 args.hashval = xfs_da_hashname(name, namelen);
509 args.inumber = inum;
510 args.dp = dp;
511 args.firstblock = firstblock;
512 args.flist = flist;
513 args.total = total;
514 args.whichfork = XFS_DATA_FORK;
515 args.trans = trans;
516 args.justcheck = args.addname = args.oknoent = 0;
517
518 /*
519 * Decide on what work routines to call based on the inode size.
520 */
521 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
522 retval = xfs_dir_shortform_replace(&args);
523 } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) {
524 retval = xfs_dir_leaf_replace(&args);
525 } else {
526 retval = xfs_dir_node_replace(&args);
527 }
528
529 return(retval);
530}
531
532static int
533xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp)
534{
535 xfs_ino_t ino;
536 int namelen_sum;
537 int count;
538 xfs_dir_shortform_t *sf;
539 xfs_dir_sf_entry_t *sfe;
540 int i;
541
542
543
544 if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) {
545 return 0;
546 }
547 if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) {
548 return 0;
549 }
550 if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) {
551 xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p",
552 dp);
553 return 1;
554 }
555 sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf);
556 ino = XFS_GET_DIR_INO8(sf->hdr.parent);
557 if (xfs_dir_ino_validate(mp, ino))
558 return 1;
559
560 count = sf->hdr.count;
561 if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) {
562 xfs_fs_cmn_err(CE_WARN, mp,
563 "Invalid shortform count: dp 0x%p", dp);
564 return(1);
565 }
566
567 if (count == 0) {
568 return 0;
569 }
570
571 namelen_sum = 0;
572 sfe = &sf->list[0];
573 for (i = sf->hdr.count - 1; i >= 0; i--) {
574 ino = XFS_GET_DIR_INO8(sfe->inumber);
575 xfs_dir_ino_validate(mp, ino);
576 if (sfe->namelen >= XFS_LITINO(mp)) {
577 xfs_fs_cmn_err(CE_WARN, mp,
578 "Invalid shortform namelen: dp 0x%p", dp);
579 return 1;
580 }
581 namelen_sum += sfe->namelen;
582 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
583 }
584 if (namelen_sum >= XFS_LITINO(mp)) {
585 xfs_fs_cmn_err(CE_WARN, mp,
586 "Invalid shortform namelen: dp 0x%p", dp);
587 return 1;
588 }
589
590 return 0;
591}
592
593/*========================================================================
594 * External routines when dirsize == XFS_LBSIZE(dp->i_mount).
595 *========================================================================*/
596
597/*
598 * Add a name to the leaf directory structure
599 * This is the external routine.
600 */
601int
602xfs_dir_leaf_addname(xfs_da_args_t *args)
603{
604 int index, retval;
605 xfs_dabuf_t *bp;
606
607 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
608 XFS_DATA_FORK);
609 if (retval)
610 return(retval);
611 ASSERT(bp != NULL);
612
613 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
614 if (retval == ENOENT)
615 retval = xfs_dir_leaf_add(bp, args, index);
616 xfs_da_buf_done(bp);
617 return(retval);
618}
619
620/*
621 * Remove a name from the leaf directory structure
622 * This is the external routine.
623 */
624STATIC int
625xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen)
626{
627 xfs_dir_leafblock_t *leaf;
628 int index, retval;
629 xfs_dabuf_t *bp;
630
631 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
632 XFS_DATA_FORK);
633 if (retval)
634 return(retval);
635 ASSERT(bp != NULL);
636 leaf = bp->data;
637 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
638 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
639 if (retval == EEXIST) {
640 (void)xfs_dir_leaf_remove(args->trans, bp, index);
641 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
642 *totallen = INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
643 retval = 0;
644 }
645 xfs_da_buf_done(bp);
646 return(retval);
647}
648
649/*
650 * Look up a name in a leaf directory structure.
651 * This is the external routine.
652 */
653STATIC int
654xfs_dir_leaf_lookup(xfs_da_args_t *args)
655{
656 int index, retval;
657 xfs_dabuf_t *bp;
658
659 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
660 XFS_DATA_FORK);
661 if (retval)
662 return(retval);
663 ASSERT(bp != NULL);
664 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
665 xfs_da_brelse(args->trans, bp);
666 return(retval);
667}
668
669/*
670 * Copy out directory entries for getdents(), for leaf directories.
671 */
672STATIC int
673xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
674 int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
675{
676 xfs_dabuf_t *bp;
677 int retval, eob;
678
679 retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK);
680 if (retval)
681 return(retval);
682 ASSERT(bp != NULL);
683 retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1);
684 xfs_da_brelse(trans, bp);
685 *eofp = (eob == 0);
686 return(retval);
687}
688
689/*
690 * Look up a name in a leaf directory structure, replace the inode number.
691 * This is the external routine.
692 */
693STATIC int
694xfs_dir_leaf_replace(xfs_da_args_t *args)
695{
696 int index, retval;
697 xfs_dabuf_t *bp;
698 xfs_ino_t inum;
699 xfs_dir_leafblock_t *leaf;
700 xfs_dir_leaf_entry_t *entry;
701 xfs_dir_leaf_name_t *namest;
702
703 inum = args->inumber;
704 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
705 XFS_DATA_FORK);
706 if (retval)
707 return(retval);
708 ASSERT(bp != NULL);
709 retval = xfs_dir_leaf_lookup_int(bp, args, &index);
710 if (retval == EEXIST) {
711 leaf = bp->data;
712 entry = &leaf->entries[index];
713 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
714 /* XXX - replace assert? */
715 XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
716 xfs_da_log_buf(args->trans, bp,
717 XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
718 xfs_da_buf_done(bp);
719 retval = 0;
720 } else
721 xfs_da_brelse(args->trans, bp);
722 return(retval);
723}
724
725
726/*========================================================================
727 * External routines when dirsize > XFS_LBSIZE(mp).
728 *========================================================================*/
729
730/*
731 * Add a name to a Btree-format directory.
732 *
733 * This will involve walking down the Btree, and may involve splitting
734 * leaf nodes and even splitting intermediate nodes up to and including
735 * the root node (a special case of an intermediate node).
736 */
737STATIC int
738xfs_dir_node_addname(xfs_da_args_t *args)
739{
740 xfs_da_state_t *state;
741 xfs_da_state_blk_t *blk;
742 int retval, error;
743
744 /*
745 * Fill in bucket of arguments/results/context to carry around.
746 */
747 state = xfs_da_state_alloc();
748 state->args = args;
749 state->mp = args->dp->i_mount;
750 state->blocksize = state->mp->m_sb.sb_blocksize;
751 state->node_ents = state->mp->m_dir_node_ents;
752
753 /*
754 * Search to see if name already exists, and get back a pointer
755 * to where it should go.
756 */
757 error = xfs_da_node_lookup_int(state, &retval);
758 if (error)
759 retval = error;
760 if (retval != ENOENT)
761 goto error;
762 blk = &state->path.blk[ state->path.active-1 ];
763 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
764 retval = xfs_dir_leaf_add(blk->bp, args, blk->index);
765 if (retval == 0) {
766 /*
767 * Addition succeeded, update Btree hashvals.
768 */
769 if (!args->justcheck)
770 xfs_da_fixhashpath(state, &state->path);
771 } else {
772 /*
773 * Addition failed, split as many Btree elements as required.
774 */
775 if (args->total == 0) {
776 ASSERT(retval == ENOSPC);
777 goto error;
778 }
779 retval = xfs_da_split(state);
780 }
781error:
782 xfs_da_state_free(state);
783
784 return(retval);
785}
786
787/*
788 * Remove a name from a B-tree directory.
789 *
790 * This will involve walking down the Btree, and may involve joining
791 * leaf nodes and even joining intermediate nodes up to and including
792 * the root node (a special case of an intermediate node).
793 */
794STATIC int
795xfs_dir_node_removename(xfs_da_args_t *args)
796{
797 xfs_da_state_t *state;
798 xfs_da_state_blk_t *blk;
799 int retval, error;
800
801 state = xfs_da_state_alloc();
802 state->args = args;
803 state->mp = args->dp->i_mount;
804 state->blocksize = state->mp->m_sb.sb_blocksize;
805 state->node_ents = state->mp->m_dir_node_ents;
806
807 /*
808 * Search to see if name exists, and get back a pointer to it.
809 */
810 error = xfs_da_node_lookup_int(state, &retval);
811 if (error)
812 retval = error;
813 if (retval != EEXIST) {
814 xfs_da_state_free(state);
815 return(retval);
816 }
817
818 /*
819 * Remove the name and update the hashvals in the tree.
820 */
821 blk = &state->path.blk[ state->path.active-1 ];
822 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
823 retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index);
824 xfs_da_fixhashpath(state, &state->path);
825
826 /*
827 * Check to see if the tree needs to be collapsed.
828 */
829 error = 0;
830 if (retval) {
831 error = xfs_da_join(state);
832 }
833
834 xfs_da_state_free(state);
835 if (error)
836 return(error);
837 return(0);
838}
839
840/*
841 * Look up a filename in a int directory.
842 * Use an internal routine to actually do all the work.
843 */
844STATIC int
845xfs_dir_node_lookup(xfs_da_args_t *args)
846{
847 xfs_da_state_t *state;
848 int retval, error, i;
849
850 state = xfs_da_state_alloc();
851 state->args = args;
852 state->mp = args->dp->i_mount;
853 state->blocksize = state->mp->m_sb.sb_blocksize;
854 state->node_ents = state->mp->m_dir_node_ents;
855
856 /*
857 * Search to see if name exists,
858 * and get back a pointer to it.
859 */
860 error = xfs_da_node_lookup_int(state, &retval);
861 if (error) {
862 retval = error;
863 }
864
865 /*
866 * If not in a transaction, we have to release all the buffers.
867 */
868 for (i = 0; i < state->path.active; i++) {
869 xfs_da_brelse(args->trans, state->path.blk[i].bp);
870 state->path.blk[i].bp = NULL;
871 }
872
873 xfs_da_state_free(state);
874 return(retval);
875}
876
877STATIC int
878xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
879 int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put)
880{
881 xfs_da_intnode_t *node;
882 xfs_da_node_entry_t *btree;
883 xfs_dir_leafblock_t *leaf = NULL;
884 xfs_dablk_t bno, nextbno;
885 xfs_dahash_t cookhash;
886 xfs_mount_t *mp;
887 int error, eob, i;
888 xfs_dabuf_t *bp;
889 xfs_daddr_t nextda;
890
891 /*
892 * Pick up our context.
893 */
894 mp = dp->i_mount;
895 bp = NULL;
896 bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset);
897 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
898
899 xfs_dir_trace_g_du("node: start", dp, uio);
900
901 /*
902 * Re-find our place, even if we're confused about what our place is.
903 *
904 * First we check the block number from the magic cookie, it is a
905 * cache of where we ended last time. If we find a leaf block, and
906 * the starting hashval in that block is less than our desired
907 * hashval, then we run with it.
908 */
909 if (bno > 0) {
910 error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK);
911 if ((error != 0) && (error != EFSCORRUPTED))
912 return(error);
913 if (bp)
914 leaf = bp->data;
915 if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
916 xfs_dir_trace_g_dub("node: block not a leaf",
917 dp, uio, bno);
918 xfs_da_brelse(trans, bp);
919 bp = NULL;
920 }
921 if (bp && INT_GET(leaf->entries[0].hashval, ARCH_CONVERT) > cookhash) {
922 xfs_dir_trace_g_dub("node: leaf hash too large",
923 dp, uio, bno);
924 xfs_da_brelse(trans, bp);
925 bp = NULL;
926 }
927 if (bp &&
928 cookhash > INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)) {
929 xfs_dir_trace_g_dub("node: leaf hash too small",
930 dp, uio, bno);
931 xfs_da_brelse(trans, bp);
932 bp = NULL;
933 }
934 }
935
936 /*
937 * If we did not find a leaf block from the blockno in the cookie,
938 * or we there was no blockno in the cookie (eg: first time thru),
939 * the we start at the top of the Btree and re-find our hashval.
940 */
941 if (bp == NULL) {
942 xfs_dir_trace_g_du("node: start at root" , dp, uio);
943 bno = 0;
944 for (;;) {
945 error = xfs_da_read_buf(trans, dp, bno, -1, &bp,
946 XFS_DATA_FORK);
947 if (error)
948 return(error);
949 if (bp == NULL)
950 return(XFS_ERROR(EFSCORRUPTED));
951 node = bp->data;
952 if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)
953 break;
954 btree = &node->btree[0];
955 xfs_dir_trace_g_dun("node: node detail", dp, uio, node);
956 for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) {
957 if (be32_to_cpu(btree->hashval) >= cookhash) {
958 bno = be32_to_cpu(btree->before);
959 break;
960 }
961 }
962 if (i == be16_to_cpu(node->hdr.count)) {
963 xfs_da_brelse(trans, bp);
964 xfs_dir_trace_g_du("node: hash beyond EOF",
965 dp, uio);
966 uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0,
967 XFS_DA_MAXHASH);
968 *eofp = 1;
969 return(0);
970 }
971 xfs_dir_trace_g_dub("node: going to block",
972 dp, uio, bno);
973 xfs_da_brelse(trans, bp);
974 }
975 }
976 ASSERT(cookhash != XFS_DA_MAXHASH);
977
978 /*
979 * We've dropped down to the (first) leaf block that contains the
980 * hashval we are interested in. Continue rolling upward thru the
981 * leaf blocks until we fill up our buffer.
982 */
983 for (;;) {
984 leaf = bp->data;
985 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) {
986 xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
987 xfs_da_brelse(trans, bp);
988 XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
989 XFS_ERRLEVEL_LOW, mp, leaf);
990 return XFS_ERROR(EFSCORRUPTED);
991 }
992 xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
993 if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) {
994 nextda = xfs_da_reada_buf(trans, dp, nextbno,
995 XFS_DATA_FORK);
996 } else
997 nextda = -1;
998 error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp,
999 put, nextda);
1000 xfs_da_brelse(trans, bp);
1001 bno = nextbno;
1002 if (eob) {
1003 xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno);
1004 *eofp = 0;
1005 return(error);
1006 }
1007 if (bno == 0)
1008 break;
1009 error = xfs_da_read_buf(trans, dp, bno, nextda, &bp,
1010 XFS_DATA_FORK);
1011 if (error)
1012 return(error);
1013 if (unlikely(bp == NULL)) {
1014 XFS_ERROR_REPORT("xfs_dir_node_getdents(2)",
1015 XFS_ERRLEVEL_LOW, mp);
1016 return(XFS_ERROR(EFSCORRUPTED));
1017 }
1018 }
1019 *eofp = 1;
1020 xfs_dir_trace_g_du("node: E-O-F", dp, uio);
1021 return(0);
1022}
1023
1024/*
1025 * Look up a filename in an int directory, replace the inode number.
1026 * Use an internal routine to actually do the lookup.
1027 */
1028STATIC int
1029xfs_dir_node_replace(xfs_da_args_t *args)
1030{
1031 xfs_da_state_t *state;
1032 xfs_da_state_blk_t *blk;
1033 xfs_dir_leafblock_t *leaf;
1034 xfs_dir_leaf_entry_t *entry;
1035 xfs_dir_leaf_name_t *namest;
1036 xfs_ino_t inum;
1037 int retval, error, i;
1038 xfs_dabuf_t *bp;
1039
1040 state = xfs_da_state_alloc();
1041 state->args = args;
1042 state->mp = args->dp->i_mount;
1043 state->blocksize = state->mp->m_sb.sb_blocksize;
1044 state->node_ents = state->mp->m_dir_node_ents;
1045 inum = args->inumber;
1046
1047 /*
1048 * Search to see if name exists,
1049 * and get back a pointer to it.
1050 */
1051 error = xfs_da_node_lookup_int(state, &retval);
1052 if (error) {
1053 retval = error;
1054 }
1055
1056 if (retval == EEXIST) {
1057 blk = &state->path.blk[state->path.active - 1];
1058 ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC);
1059 bp = blk->bp;
1060 leaf = bp->data;
1061 entry = &leaf->entries[blk->index];
1062 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1063 /* XXX - replace assert ? */
1064 XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber);
1065 xfs_da_log_buf(args->trans, bp,
1066 XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber)));
1067 xfs_da_buf_done(bp);
1068 blk->bp = NULL;
1069 retval = 0;
1070 } else {
1071 i = state->path.active - 1;
1072 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1073 state->path.blk[i].bp = NULL;
1074 }
1075 for (i = 0; i < state->path.active - 1; i++) {
1076 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1077 state->path.blk[i].bp = NULL;
1078 }
1079
1080 xfs_da_state_free(state);
1081 return(retval);
1082}
1083
1084#if defined(XFS_DIR_TRACE)
1085/*
1086 * Add a trace buffer entry for an inode and a uio.
1087 */
1088void
1089xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio)
1090{
1091 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where,
1092 (void *)dp, (void *)dp->i_mount,
1093 (void *)((unsigned long)(uio->uio_offset >> 32)),
1094 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1095 (void *)(unsigned long)uio->uio_resid,
1096 NULL, NULL, NULL, NULL, NULL, NULL, NULL);
1097}
1098
1099/*
1100 * Add a trace buffer entry for an inode and a uio.
1101 */
1102void
1103xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno)
1104{
1105 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where,
1106 (void *)dp, (void *)dp->i_mount,
1107 (void *)((unsigned long)(uio->uio_offset >> 32)),
1108 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1109 (void *)(unsigned long)uio->uio_resid,
1110 (void *)(unsigned long)bno,
1111 NULL, NULL, NULL, NULL, NULL, NULL);
1112}
1113
1114/*
1115 * Add a trace buffer entry for an inode and a uio.
1116 */
1117void
1118xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio,
1119 xfs_da_intnode_t *node)
1120{
1121 int last = be16_to_cpu(node->hdr.count) - 1;
1122
1123 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where,
1124 (void *)dp, (void *)dp->i_mount,
1125 (void *)((unsigned long)(uio->uio_offset >> 32)),
1126 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1127 (void *)(unsigned long)uio->uio_resid,
1128 (void *)(unsigned long)be32_to_cpu(node->hdr.info.forw),
1129 (void *)(unsigned long)
1130 be16_to_cpu(node->hdr.count),
1131 (void *)(unsigned long)
1132 be32_to_cpu(node->btree[0].hashval),
1133 (void *)(unsigned long)
1134 be32_to_cpu(node->btree[last].hashval),
1135 NULL, NULL, NULL);
1136}
1137
1138/*
1139 * Add a trace buffer entry for an inode and a uio.
1140 */
1141void
1142xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio,
1143 xfs_dir_leafblock_t *leaf)
1144{
1145 int last = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;
1146
1147 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where,
1148 (void *)dp, (void *)dp->i_mount,
1149 (void *)((unsigned long)(uio->uio_offset >> 32)),
1150 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1151 (void *)(unsigned long)uio->uio_resid,
1152 (void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw),
1153 (void *)(unsigned long)
1154 INT_GET(leaf->hdr.count, ARCH_CONVERT),
1155 (void *)(unsigned long)
1156 INT_GET(leaf->entries[0].hashval, ARCH_CONVERT),
1157 (void *)(unsigned long)
1158 INT_GET(leaf->entries[last].hashval, ARCH_CONVERT),
1159 NULL, NULL, NULL);
1160}
1161
1162/*
1163 * Add a trace buffer entry for an inode and a uio.
1164 */
1165void
1166xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio,
1167 xfs_dir_leaf_entry_t *entry)
1168{
1169 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where,
1170 (void *)dp, (void *)dp->i_mount,
1171 (void *)((unsigned long)(uio->uio_offset >> 32)),
1172 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1173 (void *)(unsigned long)uio->uio_resid,
1174 (void *)(unsigned long)
1175 INT_GET(entry->hashval, ARCH_CONVERT),
1176 NULL, NULL, NULL, NULL, NULL, NULL);
1177}
1178
1179/*
1180 * Add a trace buffer entry for an inode and a uio.
1181 */
1182void
1183xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie)
1184{
1185 xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where,
1186 (void *)dp, (void *)dp->i_mount,
1187 (void *)((unsigned long)(uio->uio_offset >> 32)),
1188 (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
1189 (void *)(unsigned long)uio->uio_resid,
1190 (void *)((unsigned long)(cookie >> 32)),
1191 (void *)((unsigned long)(cookie & 0xFFFFFFFF)),
1192 NULL, NULL, NULL, NULL, NULL);
1193}
1194
1195/*
1196 * Add a trace buffer entry for the arguments given to the routine,
1197 * generic form.
1198 */
1199void
1200xfs_dir_trace_enter(int type, char *where,
1201 void * a0, void * a1,
1202 void * a2, void * a3,
1203 void * a4, void * a5,
1204 void * a6, void * a7,
1205 void * a8, void * a9,
1206 void * a10, void * a11)
1207{
1208 ASSERT(xfs_dir_trace_buf);
1209 ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type,
1210 (void *)where,
1211 (void *)a0, (void *)a1, (void *)a2,
1212 (void *)a3, (void *)a4, (void *)a5,
1213 (void *)a6, (void *)a7, (void *)a8,
1214 (void *)a9, (void *)a10, (void *)a11,
1215 NULL, NULL);
1216}
1217#endif /* XFS_DIR_TRACE */
diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h
deleted file mode 100644
index 8cc8afb9f6c0..000000000000
--- a/fs/xfs/xfs_dir.h
+++ /dev/null
@@ -1,142 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR_H__
19#define __XFS_DIR_H__
20
21/*
22 * Large directories are structured around Btrees where all the data
23 * elements are in the leaf nodes. Filenames are hashed into an int,
24 * then that int is used as the index into the Btree. Since the hashval
25 * of a filename may not be unique, we may have duplicate keys. The
26 * internal links in the Btree are logical block offsets into the file.
27 *
28 * Small directories use a different format and are packed as tightly
29 * as possible so as to fit into the literal area of the inode.
30 */
31
32/*========================================================================
33 * Function prototypes for the kernel.
34 *========================================================================*/
35
36struct uio;
37struct xfs_bmap_free;
38struct xfs_da_args;
39struct xfs_dinode;
40struct xfs_inode;
41struct xfs_mount;
42struct xfs_trans;
43
44/*
45 * Directory function types.
46 * Put in structures (xfs_dirops_t) for v1 and v2 directories.
47 */
48typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp);
49typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp);
50typedef int (*xfs_dir_init_t)(struct xfs_trans *tp,
51 struct xfs_inode *dp,
52 struct xfs_inode *pdp);
53typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp,
54 struct xfs_inode *dp,
55 char *name,
56 int namelen,
57 xfs_ino_t inum,
58 xfs_fsblock_t *first,
59 struct xfs_bmap_free *flist,
60 xfs_extlen_t total);
61typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp,
62 struct xfs_inode *dp,
63 char *name,
64 int namelen,
65 xfs_ino_t *inum);
66typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp,
67 struct xfs_inode *dp,
68 char *name,
69 int namelen,
70 xfs_ino_t ino,
71 xfs_fsblock_t *first,
72 struct xfs_bmap_free *flist,
73 xfs_extlen_t total);
74typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp,
75 struct xfs_inode *dp,
76 struct uio *uio,
77 int *eofp);
78typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp,
79 struct xfs_inode *dp,
80 char *name,
81 int namelen,
82 xfs_ino_t inum,
83 xfs_fsblock_t *first,
84 struct xfs_bmap_free *flist,
85 xfs_extlen_t total);
86typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp,
87 struct xfs_inode *dp,
88 char *name,
89 int namelen);
90typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp,
91 struct xfs_dinode *dip);
92typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args);
93
94typedef struct xfs_dirops {
95 xfs_dir_mount_t xd_mount;
96 xfs_dir_isempty_t xd_isempty;
97 xfs_dir_init_t xd_init;
98 xfs_dir_createname_t xd_createname;
99 xfs_dir_lookup_t xd_lookup;
100 xfs_dir_removename_t xd_removename;
101 xfs_dir_getdents_t xd_getdents;
102 xfs_dir_replace_t xd_replace;
103 xfs_dir_canenter_t xd_canenter;
104 xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk;
105 xfs_dir_shortform_to_single_t xd_shortform_to_single;
106} xfs_dirops_t;
107
108/*
109 * Overall external interface routines.
110 */
111void xfs_dir_startup(void); /* called exactly once */
112
113#define XFS_DIR_MOUNT(mp) \
114 ((mp)->m_dirops.xd_mount(mp))
115#define XFS_DIR_ISEMPTY(mp,dp) \
116 ((mp)->m_dirops.xd_isempty(dp))
117#define XFS_DIR_INIT(mp,tp,dp,pdp) \
118 ((mp)->m_dirops.xd_init(tp,dp,pdp))
119#define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \
120 ((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\
121 total))
122#define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \
123 ((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum))
124#define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \
125 ((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total))
126#define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \
127 ((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp))
128#define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \
129 ((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total))
130#define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \
131 ((mp)->m_dirops.xd_canenter(tp,dp,name,namelen))
132#define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \
133 ((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip))
134#define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \
135 ((mp)->m_dirops.xd_shortform_to_single(args))
136
137#define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1)
138#define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2)
139extern xfs_dirops_t xfsv1_dirops;
140extern xfs_dirops_t xfsv2_dirops;
141
142#endif /* __XFS_DIR_H__ */
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 022c8398ab62..8edbe1adb95b 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -24,21 +24,18 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_da_btree.h" 30#include "xfs_da_btree.h"
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
38#include "xfs_inode.h" 36#include "xfs_inode.h"
39#include "xfs_inode_item.h" 37#include "xfs_inode_item.h"
40#include "xfs_bmap.h" 38#include "xfs_bmap.h"
41#include "xfs_dir_leaf.h"
42#include "xfs_dir2_data.h" 39#include "xfs_dir2_data.h"
43#include "xfs_dir2_leaf.h" 40#include "xfs_dir2_leaf.h"
44#include "xfs_dir2_block.h" 41#include "xfs_dir2_block.h"
@@ -46,69 +43,14 @@
46#include "xfs_dir2_trace.h" 43#include "xfs_dir2_trace.h"
47#include "xfs_error.h" 44#include "xfs_error.h"
48 45
49/*
50 * Declarations for interface routines.
51 */
52static void xfs_dir2_mount(xfs_mount_t *mp);
53static int xfs_dir2_isempty(xfs_inode_t *dp);
54static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp,
55 xfs_inode_t *pdp);
56static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp,
57 char *name, int namelen, xfs_ino_t inum,
58 xfs_fsblock_t *first,
59 xfs_bmap_free_t *flist, xfs_extlen_t total);
60static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
61 int namelen, xfs_ino_t *inum);
62static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp,
63 char *name, int namelen, xfs_ino_t ino,
64 xfs_fsblock_t *first,
65 xfs_bmap_free_t *flist, xfs_extlen_t total);
66static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio,
67 int *eofp);
68static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
69 int namelen, xfs_ino_t inum,
70 xfs_fsblock_t *first, xfs_bmap_free_t *flist,
71 xfs_extlen_t total);
72static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name,
73 int namelen);
74static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp,
75 xfs_dinode_t *dip);
76
77/*
78 * Utility routine declarations.
79 */
80static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); 46static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa);
81static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); 47static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa);
82 48
83/* 49void
84 * Directory operations vector. 50xfs_dir_mount(
85 */ 51 xfs_mount_t *mp)
86xfs_dirops_t xfsv2_dirops = {
87 .xd_mount = xfs_dir2_mount,
88 .xd_isempty = xfs_dir2_isempty,
89 .xd_init = xfs_dir2_init,
90 .xd_createname = xfs_dir2_createname,
91 .xd_lookup = xfs_dir2_lookup,
92 .xd_removename = xfs_dir2_removename,
93 .xd_getdents = xfs_dir2_getdents,
94 .xd_replace = xfs_dir2_replace,
95 .xd_canenter = xfs_dir2_canenter,
96 .xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk,
97 .xd_shortform_to_single = xfs_dir2_sf_to_block,
98};
99
100/*
101 * Interface routines.
102 */
103
104/*
105 * Initialize directory-related fields in the mount structure.
106 */
107static void
108xfs_dir2_mount(
109 xfs_mount_t *mp) /* filesystem mount point */
110{ 52{
111 mp->m_dirversion = 2; 53 ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));
112 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= 54 ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
113 XFS_MAX_BLOCKSIZE); 55 XFS_MAX_BLOCKSIZE);
114 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); 56 mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
@@ -128,19 +70,15 @@ xfs_dir2_mount(
128/* 70/*
129 * Return 1 if directory contains only "." and "..". 71 * Return 1 if directory contains only "." and "..".
130 */ 72 */
131static int /* return code */ 73int
132xfs_dir2_isempty( 74xfs_dir_isempty(
133 xfs_inode_t *dp) /* incore inode structure */ 75 xfs_inode_t *dp)
134{ 76{
135 xfs_dir2_sf_t *sfp; /* shortform directory structure */ 77 xfs_dir2_sf_t *sfp;
136 78
137 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 79 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
138 /* 80 if (dp->i_d.di_size == 0) /* might happen during shutdown. */
139 * Might happen during shutdown.
140 */
141 if (dp->i_d.di_size == 0) {
142 return 1; 81 return 1;
143 }
144 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) 82 if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp))
145 return 0; 83 return 0;
146 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 84 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
@@ -148,53 +86,83 @@ xfs_dir2_isempty(
148} 86}
149 87
150/* 88/*
89 * Validate a given inode number.
90 */
91int
92xfs_dir_ino_validate(
93 xfs_mount_t *mp,
94 xfs_ino_t ino)
95{
96 xfs_agblock_t agblkno;
97 xfs_agino_t agino;
98 xfs_agnumber_t agno;
99 int ino_ok;
100 int ioff;
101
102 agno = XFS_INO_TO_AGNO(mp, ino);
103 agblkno = XFS_INO_TO_AGBNO(mp, ino);
104 ioff = XFS_INO_TO_OFFSET(mp, ino);
105 agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
106 ino_ok =
107 agno < mp->m_sb.sb_agcount &&
108 agblkno < mp->m_sb.sb_agblocks &&
109 agblkno != 0 &&
110 ioff < (1 << mp->m_sb.sb_inopblog) &&
111 XFS_AGINO_TO_INO(mp, agno, agino) == ino;
112 if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
113 XFS_RANDOM_DIR_INO_VALIDATE))) {
114 xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
115 (unsigned long long) ino);
116 XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
117 return XFS_ERROR(EFSCORRUPTED);
118 }
119 return 0;
120}
121
122/*
151 * Initialize a directory with its "." and ".." entries. 123 * Initialize a directory with its "." and ".." entries.
152 */ 124 */
153static int /* error */ 125int
154xfs_dir2_init( 126xfs_dir_init(
155 xfs_trans_t *tp, /* transaction pointer */ 127 xfs_trans_t *tp,
156 xfs_inode_t *dp, /* incore directory inode */ 128 xfs_inode_t *dp,
157 xfs_inode_t *pdp) /* incore parent directory inode */ 129 xfs_inode_t *pdp)
158{ 130{
159 xfs_da_args_t args; /* operation arguments */ 131 xfs_da_args_t args;
160 int error; /* error return value */ 132 int error;
161 133
162 memset((char *)&args, 0, sizeof(args)); 134 memset((char *)&args, 0, sizeof(args));
163 args.dp = dp; 135 args.dp = dp;
164 args.trans = tp; 136 args.trans = tp;
165 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 137 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
166 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) { 138 if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino)))
167 return error; 139 return error;
168 }
169 return xfs_dir2_sf_create(&args, pdp->i_ino); 140 return xfs_dir2_sf_create(&args, pdp->i_ino);
170} 141}
171 142
172/* 143/*
173 Enter a name in a directory. 144 Enter a name in a directory.
174 */ 145 */
175static int /* error */ 146int
176xfs_dir2_createname( 147xfs_dir_createname(
177 xfs_trans_t *tp, /* transaction pointer */ 148 xfs_trans_t *tp,
178 xfs_inode_t *dp, /* incore directory inode */ 149 xfs_inode_t *dp,
179 char *name, /* new entry name */ 150 char *name,
180 int namelen, /* new entry name length */ 151 int namelen,
181 xfs_ino_t inum, /* new entry inode number */ 152 xfs_ino_t inum, /* new entry inode number */
182 xfs_fsblock_t *first, /* bmap's firstblock */ 153 xfs_fsblock_t *first, /* bmap's firstblock */
183 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 154 xfs_bmap_free_t *flist, /* bmap's freeblock list */
184 xfs_extlen_t total) /* bmap's total block count */ 155 xfs_extlen_t total) /* bmap's total block count */
185{ 156{
186 xfs_da_args_t args; /* operation arguments */ 157 xfs_da_args_t args;
187 int rval; /* return value */ 158 int rval;
188 int v; /* type-checking value */ 159 int v; /* type-checking value */
189 160
190 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 161 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
191 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { 162 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
192 return rval; 163 return rval;
193 }
194 XFS_STATS_INC(xs_dir_create); 164 XFS_STATS_INC(xs_dir_create);
195 /* 165
196 * Fill in the arg structure for this request.
197 */
198 args.name = name; 166 args.name = name;
199 args.namelen = namelen; 167 args.namelen = namelen;
200 args.hashval = xfs_da_hashname(name, namelen); 168 args.hashval = xfs_da_hashname(name, namelen);
@@ -207,18 +175,16 @@ xfs_dir2_createname(
207 args.trans = tp; 175 args.trans = tp;
208 args.justcheck = 0; 176 args.justcheck = 0;
209 args.addname = args.oknoent = 1; 177 args.addname = args.oknoent = 1;
210 /* 178
211 * Decide on what work routines to call based on the inode size.
212 */
213 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 179 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
214 rval = xfs_dir2_sf_addname(&args); 180 rval = xfs_dir2_sf_addname(&args);
215 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 181 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
216 return rval; 182 return rval;
217 } else if (v) 183 else if (v)
218 rval = xfs_dir2_block_addname(&args); 184 rval = xfs_dir2_block_addname(&args);
219 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 185 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
220 return rval; 186 return rval;
221 } else if (v) 187 else if (v)
222 rval = xfs_dir2_leaf_addname(&args); 188 rval = xfs_dir2_leaf_addname(&args);
223 else 189 else
224 rval = xfs_dir2_node_addname(&args); 190 rval = xfs_dir2_node_addname(&args);
@@ -228,24 +194,21 @@ xfs_dir2_createname(
228/* 194/*
229 * Lookup a name in a directory, give back the inode number. 195 * Lookup a name in a directory, give back the inode number.
230 */ 196 */
231static int /* error */ 197int
232xfs_dir2_lookup( 198xfs_dir_lookup(
233 xfs_trans_t *tp, /* transaction pointer */ 199 xfs_trans_t *tp,
234 xfs_inode_t *dp, /* incore directory inode */ 200 xfs_inode_t *dp,
235 char *name, /* lookup name */ 201 char *name,
236 int namelen, /* lookup name length */ 202 int namelen,
237 xfs_ino_t *inum) /* out: inode number */ 203 xfs_ino_t *inum) /* out: inode number */
238{ 204{
239 xfs_da_args_t args; /* operation arguments */ 205 xfs_da_args_t args;
240 int rval; /* return value */ 206 int rval;
241 int v; /* type-checking value */ 207 int v; /* type-checking value */
242 208
243 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 209 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
244 XFS_STATS_INC(xs_dir_lookup); 210 XFS_STATS_INC(xs_dir_lookup);
245 211
246 /*
247 * Fill in the arg structure for this request.
248 */
249 args.name = name; 212 args.name = name;
250 args.namelen = namelen; 213 args.namelen = namelen;
251 args.hashval = xfs_da_hashname(name, namelen); 214 args.hashval = xfs_da_hashname(name, namelen);
@@ -258,18 +221,16 @@ xfs_dir2_lookup(
258 args.trans = tp; 221 args.trans = tp;
259 args.justcheck = args.addname = 0; 222 args.justcheck = args.addname = 0;
260 args.oknoent = 1; 223 args.oknoent = 1;
261 /* 224
262 * Decide on what work routines to call based on the inode size.
263 */
264 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 225 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
265 rval = xfs_dir2_sf_lookup(&args); 226 rval = xfs_dir2_sf_lookup(&args);
266 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 227 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
267 return rval; 228 return rval;
268 } else if (v) 229 else if (v)
269 rval = xfs_dir2_block_lookup(&args); 230 rval = xfs_dir2_block_lookup(&args);
270 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 231 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
271 return rval; 232 return rval;
272 } else if (v) 233 else if (v)
273 rval = xfs_dir2_leaf_lookup(&args); 234 rval = xfs_dir2_leaf_lookup(&args);
274 else 235 else
275 rval = xfs_dir2_node_lookup(&args); 236 rval = xfs_dir2_node_lookup(&args);
@@ -283,26 +244,24 @@ xfs_dir2_lookup(
283/* 244/*
284 * Remove an entry from a directory. 245 * Remove an entry from a directory.
285 */ 246 */
286static int /* error */ 247int
287xfs_dir2_removename( 248xfs_dir_removename(
288 xfs_trans_t *tp, /* transaction pointer */ 249 xfs_trans_t *tp,
289 xfs_inode_t *dp, /* incore directory inode */ 250 xfs_inode_t *dp,
290 char *name, /* name of entry to remove */ 251 char *name,
291 int namelen, /* name length of entry to remove */ 252 int namelen,
292 xfs_ino_t ino, /* inode number of entry to remove */ 253 xfs_ino_t ino,
293 xfs_fsblock_t *first, /* bmap's firstblock */ 254 xfs_fsblock_t *first, /* bmap's firstblock */
294 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 255 xfs_bmap_free_t *flist, /* bmap's freeblock list */
295 xfs_extlen_t total) /* bmap's total block count */ 256 xfs_extlen_t total) /* bmap's total block count */
296{ 257{
297 xfs_da_args_t args; /* operation arguments */ 258 xfs_da_args_t args;
298 int rval; /* return value */ 259 int rval;
299 int v; /* type-checking value */ 260 int v; /* type-checking value */
300 261
301 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 262 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
302 XFS_STATS_INC(xs_dir_remove); 263 XFS_STATS_INC(xs_dir_remove);
303 /* 264
304 * Fill in the arg structure for this request.
305 */
306 args.name = name; 265 args.name = name;
307 args.namelen = namelen; 266 args.namelen = namelen;
308 args.hashval = xfs_da_hashname(name, namelen); 267 args.hashval = xfs_da_hashname(name, namelen);
@@ -314,18 +273,16 @@ xfs_dir2_removename(
314 args.whichfork = XFS_DATA_FORK; 273 args.whichfork = XFS_DATA_FORK;
315 args.trans = tp; 274 args.trans = tp;
316 args.justcheck = args.addname = args.oknoent = 0; 275 args.justcheck = args.addname = args.oknoent = 0;
317 /* 276
318 * Decide on what work routines to call based on the inode size.
319 */
320 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 277 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
321 rval = xfs_dir2_sf_removename(&args); 278 rval = xfs_dir2_sf_removename(&args);
322 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 279 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
323 return rval; 280 return rval;
324 } else if (v) 281 else if (v)
325 rval = xfs_dir2_block_removename(&args); 282 rval = xfs_dir2_block_removename(&args);
326 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 283 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
327 return rval; 284 return rval;
328 } else if (v) 285 else if (v)
329 rval = xfs_dir2_leaf_removename(&args); 286 rval = xfs_dir2_leaf_removename(&args);
330 else 287 else
331 rval = xfs_dir2_node_removename(&args); 288 rval = xfs_dir2_node_removename(&args);
@@ -335,10 +292,10 @@ xfs_dir2_removename(
335/* 292/*
336 * Read a directory. 293 * Read a directory.
337 */ 294 */
338static int /* error */ 295int
339xfs_dir2_getdents( 296xfs_dir_getdents(
340 xfs_trans_t *tp, /* transaction pointer */ 297 xfs_trans_t *tp,
341 xfs_inode_t *dp, /* incore directory inode */ 298 xfs_inode_t *dp,
342 uio_t *uio, /* caller's buffer control */ 299 uio_t *uio, /* caller's buffer control */
343 int *eofp) /* out: eof reached */ 300 int *eofp) /* out: eof reached */
344{ 301{
@@ -367,14 +324,11 @@ xfs_dir2_getdents(
367 } 324 }
368 325
369 *eofp = 0; 326 *eofp = 0;
370 /*
371 * Decide on what work routines to call based on the inode size.
372 */
373 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 327 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
374 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); 328 rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put);
375 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 329 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
376 ; 330 ;
377 } else if (v) 331 else if (v)
378 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); 332 rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put);
379 else 333 else
380 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); 334 rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put);
@@ -386,29 +340,26 @@ xfs_dir2_getdents(
386/* 340/*
387 * Replace the inode number of a directory entry. 341 * Replace the inode number of a directory entry.
388 */ 342 */
389static int /* error */ 343int
390xfs_dir2_replace( 344xfs_dir_replace(
391 xfs_trans_t *tp, /* transaction pointer */ 345 xfs_trans_t *tp,
392 xfs_inode_t *dp, /* incore directory inode */ 346 xfs_inode_t *dp,
393 char *name, /* name of entry to replace */ 347 char *name, /* name of entry to replace */
394 int namelen, /* name length of entry to replace */ 348 int namelen,
395 xfs_ino_t inum, /* new inode number */ 349 xfs_ino_t inum, /* new inode number */
396 xfs_fsblock_t *first, /* bmap's firstblock */ 350 xfs_fsblock_t *first, /* bmap's firstblock */
397 xfs_bmap_free_t *flist, /* bmap's freeblock list */ 351 xfs_bmap_free_t *flist, /* bmap's freeblock list */
398 xfs_extlen_t total) /* bmap's total block count */ 352 xfs_extlen_t total) /* bmap's total block count */
399{ 353{
400 xfs_da_args_t args; /* operation arguments */ 354 xfs_da_args_t args;
401 int rval; /* return value */ 355 int rval;
402 int v; /* type-checking value */ 356 int v; /* type-checking value */
403 357
404 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 358 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
405 359
406 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { 360 if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum)))
407 return rval; 361 return rval;
408 } 362
409 /*
410 * Fill in the arg structure for this request.
411 */
412 args.name = name; 363 args.name = name;
413 args.namelen = namelen; 364 args.namelen = namelen;
414 args.hashval = xfs_da_hashname(name, namelen); 365 args.hashval = xfs_da_hashname(name, namelen);
@@ -420,18 +371,16 @@ xfs_dir2_replace(
420 args.whichfork = XFS_DATA_FORK; 371 args.whichfork = XFS_DATA_FORK;
421 args.trans = tp; 372 args.trans = tp;
422 args.justcheck = args.addname = args.oknoent = 0; 373 args.justcheck = args.addname = args.oknoent = 0;
423 /* 374
424 * Decide on what work routines to call based on the inode size.
425 */
426 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 375 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
427 rval = xfs_dir2_sf_replace(&args); 376 rval = xfs_dir2_sf_replace(&args);
428 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 377 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
429 return rval; 378 return rval;
430 } else if (v) 379 else if (v)
431 rval = xfs_dir2_block_replace(&args); 380 rval = xfs_dir2_block_replace(&args);
432 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 381 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
433 return rval; 382 return rval;
434 } else if (v) 383 else if (v)
435 rval = xfs_dir2_leaf_replace(&args); 384 rval = xfs_dir2_leaf_replace(&args);
436 else 385 else
437 rval = xfs_dir2_node_replace(&args); 386 rval = xfs_dir2_node_replace(&args);
@@ -441,21 +390,19 @@ xfs_dir2_replace(
441/* 390/*
442 * See if this entry can be added to the directory without allocating space. 391 * See if this entry can be added to the directory without allocating space.
443 */ 392 */
444static int /* error */ 393int
445xfs_dir2_canenter( 394xfs_dir_canenter(
446 xfs_trans_t *tp, /* transaction pointer */ 395 xfs_trans_t *tp,
447 xfs_inode_t *dp, /* incore directory inode */ 396 xfs_inode_t *dp,
448 char *name, /* name of entry to add */ 397 char *name, /* name of entry to add */
449 int namelen) /* name length of entry to add */ 398 int namelen)
450{ 399{
451 xfs_da_args_t args; /* operation arguments */ 400 xfs_da_args_t args;
452 int rval; /* return value */ 401 int rval;
453 int v; /* type-checking value */ 402 int v; /* type-checking value */
454 403
455 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); 404 ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR);
456 /* 405
457 * Fill in the arg structure for this request.
458 */
459 args.name = name; 406 args.name = name;
460 args.namelen = namelen; 407 args.namelen = namelen;
461 args.hashval = xfs_da_hashname(name, namelen); 408 args.hashval = xfs_da_hashname(name, namelen);
@@ -467,18 +414,16 @@ xfs_dir2_canenter(
467 args.whichfork = XFS_DATA_FORK; 414 args.whichfork = XFS_DATA_FORK;
468 args.trans = tp; 415 args.trans = tp;
469 args.justcheck = args.addname = args.oknoent = 1; 416 args.justcheck = args.addname = args.oknoent = 1;
470 /* 417
471 * Decide on what work routines to call based on the inode size.
472 */
473 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 418 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
474 rval = xfs_dir2_sf_addname(&args); 419 rval = xfs_dir2_sf_addname(&args);
475 else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { 420 else if ((rval = xfs_dir2_isblock(tp, dp, &v)))
476 return rval; 421 return rval;
477 } else if (v) 422 else if (v)
478 rval = xfs_dir2_block_addname(&args); 423 rval = xfs_dir2_block_addname(&args);
479 else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { 424 else if ((rval = xfs_dir2_isleaf(tp, dp, &v)))
480 return rval; 425 return rval;
481 } else if (v) 426 else if (v)
482 rval = xfs_dir2_leaf_addname(&args); 427 rval = xfs_dir2_leaf_addname(&args);
483 else 428 else
484 rval = xfs_dir2_node_addname(&args); 429 rval = xfs_dir2_node_addname(&args);
@@ -486,19 +431,6 @@ xfs_dir2_canenter(
486} 431}
487 432
488/* 433/*
489 * Dummy routine for shortform inode validation.
490 * Can't really do this.
491 */
492/* ARGSUSED */
493static int /* error */
494xfs_dir2_shortform_validate_ondisk(
495 xfs_mount_t *mp, /* filesystem mount point */
496 xfs_dinode_t *dip) /* ondisk inode */
497{
498 return 0;
499}
500
501/*
502 * Utility routines. 434 * Utility routines.
503 */ 435 */
504 436
@@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk(
507 * This routine is for data and free blocks, not leaf/node blocks 439 * This routine is for data and free blocks, not leaf/node blocks
508 * which are handled by xfs_da_grow_inode. 440 * which are handled by xfs_da_grow_inode.
509 */ 441 */
510int /* error */ 442int
511xfs_dir2_grow_inode( 443xfs_dir2_grow_inode(
512 xfs_da_args_t *args, /* operation arguments */ 444 xfs_da_args_t *args,
513 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ 445 int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
514 xfs_dir2_db_t *dbp) /* out: block number added */ 446 xfs_dir2_db_t *dbp) /* out: block number added */
515{ 447{
516 xfs_fileoff_t bno; /* directory offset of new block */ 448 xfs_fileoff_t bno; /* directory offset of new block */
517 int count; /* count of filesystem blocks */ 449 int count; /* count of filesystem blocks */
518 xfs_inode_t *dp; /* incore directory inode */ 450 xfs_inode_t *dp; /* incore directory inode */
519 int error; /* error return value */ 451 int error;
520 int got; /* blocks actually mapped */ 452 int got; /* blocks actually mapped */
521 int i; /* temp mapping index */ 453 int i;
522 xfs_bmbt_irec_t map; /* single structure for bmap */ 454 xfs_bmbt_irec_t map; /* single structure for bmap */
523 int mapi; /* mapping index */ 455 int mapi; /* mapping index */
524 xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ 456 xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */
525 xfs_mount_t *mp; /* filesystem mount point */ 457 xfs_mount_t *mp;
526 int nmap; /* number of bmap entries */ 458 int nmap; /* number of bmap entries */
527 xfs_trans_t *tp; /* transaction pointer */ 459 xfs_trans_t *tp;
528 460
529 xfs_dir2_trace_args_s("grow_inode", args, space); 461 xfs_dir2_trace_args_s("grow_inode", args, space);
530 dp = args->dp; 462 dp = args->dp;
@@ -538,9 +470,8 @@ xfs_dir2_grow_inode(
538 /* 470 /*
539 * Find the first hole for our block. 471 * Find the first hole for our block.
540 */ 472 */
541 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) { 473 if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK)))
542 return error; 474 return error;
543 }
544 nmap = 1; 475 nmap = 1;
545 ASSERT(args->firstblock != NULL); 476 ASSERT(args->firstblock != NULL);
546 /* 477 /*
@@ -549,13 +480,9 @@ xfs_dir2_grow_inode(
549 if ((error = xfs_bmapi(tp, dp, bno, count, 480 if ((error = xfs_bmapi(tp, dp, bno, count,
550 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, 481 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
551 args->firstblock, args->total, &map, &nmap, 482 args->firstblock, args->total, &map, &nmap,
552 args->flist))) { 483 args->flist, NULL)))
553 return error; 484 return error;
554 }
555 ASSERT(nmap <= 1); 485 ASSERT(nmap <= 1);
556 /*
557 * Got it in 1.
558 */
559 if (nmap == 1) { 486 if (nmap == 1) {
560 mapp = &map; 487 mapp = &map;
561 mapi = 1; 488 mapi = 1;
@@ -585,7 +512,8 @@ xfs_dir2_grow_inode(
585 if ((error = xfs_bmapi(tp, dp, b, c, 512 if ((error = xfs_bmapi(tp, dp, b, c,
586 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA, 513 XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
587 args->firstblock, args->total, 514 args->firstblock, args->total,
588 &mapp[mapi], &nmap, args->flist))) { 515 &mapp[mapi], &nmap, args->flist,
516 NULL))) {
589 kmem_free(mapp, sizeof(*mapp) * count); 517 kmem_free(mapp, sizeof(*mapp) * count);
590 return error; 518 return error;
591 } 519 }
@@ -645,20 +573,19 @@ xfs_dir2_grow_inode(
645/* 573/*
646 * See if the directory is a single-block form directory. 574 * See if the directory is a single-block form directory.
647 */ 575 */
648int /* error */ 576int
649xfs_dir2_isblock( 577xfs_dir2_isblock(
650 xfs_trans_t *tp, /* transaction pointer */ 578 xfs_trans_t *tp,
651 xfs_inode_t *dp, /* incore directory inode */ 579 xfs_inode_t *dp,
652 int *vp) /* out: 1 is block, 0 is not block */ 580 int *vp) /* out: 1 is block, 0 is not block */
653{ 581{
654 xfs_fileoff_t last; /* last file offset */ 582 xfs_fileoff_t last; /* last file offset */
655 xfs_mount_t *mp; /* filesystem mount point */ 583 xfs_mount_t *mp;
656 int rval; /* return value */ 584 int rval;
657 585
658 mp = dp->i_mount; 586 mp = dp->i_mount;
659 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { 587 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
660 return rval; 588 return rval;
661 }
662 rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; 589 rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize;
663 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); 590 ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize);
664 *vp = rval; 591 *vp = rval;
@@ -668,20 +595,19 @@ xfs_dir2_isblock(
668/* 595/*
669 * See if the directory is a single-leaf form directory. 596 * See if the directory is a single-leaf form directory.
670 */ 597 */
671int /* error */ 598int
672xfs_dir2_isleaf( 599xfs_dir2_isleaf(
673 xfs_trans_t *tp, /* transaction pointer */ 600 xfs_trans_t *tp,
674 xfs_inode_t *dp, /* incore directory inode */ 601 xfs_inode_t *dp,
675 int *vp) /* out: 1 is leaf, 0 is not leaf */ 602 int *vp) /* out: 1 is leaf, 0 is not leaf */
676{ 603{
677 xfs_fileoff_t last; /* last file offset */ 604 xfs_fileoff_t last; /* last file offset */
678 xfs_mount_t *mp; /* filesystem mount point */ 605 xfs_mount_t *mp;
679 int rval; /* return value */ 606 int rval;
680 607
681 mp = dp->i_mount; 608 mp = dp->i_mount;
682 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { 609 if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK)))
683 return rval; 610 return rval;
684 }
685 *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); 611 *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog);
686 return 0; 612 return 0;
687} 613}
@@ -689,9 +615,9 @@ xfs_dir2_isleaf(
689/* 615/*
690 * Getdents put routine for 64-bit ABI, direct form. 616 * Getdents put routine for 64-bit ABI, direct form.
691 */ 617 */
692static int /* error */ 618static int
693xfs_dir2_put_dirent64_direct( 619xfs_dir2_put_dirent64_direct(
694 xfs_dir2_put_args_t *pa) /* argument bundle */ 620 xfs_dir2_put_args_t *pa)
695{ 621{
696 xfs_dirent_t *idbp; /* dirent pointer */ 622 xfs_dirent_t *idbp; /* dirent pointer */
697 iovec_t *iovp; /* io vector */ 623 iovec_t *iovp; /* io vector */
@@ -726,9 +652,9 @@ xfs_dir2_put_dirent64_direct(
726/* 652/*
727 * Getdents put routine for 64-bit ABI, uio form. 653 * Getdents put routine for 64-bit ABI, uio form.
728 */ 654 */
729static int /* error */ 655static int
730xfs_dir2_put_dirent64_uio( 656xfs_dir2_put_dirent64_uio(
731 xfs_dir2_put_args_t *pa) /* argument bundle */ 657 xfs_dir2_put_args_t *pa)
732{ 658{
733 xfs_dirent_t *idbp; /* dirent pointer */ 659 xfs_dirent_t *idbp; /* dirent pointer */
734 int namelen; /* entry name length */ 660 int namelen; /* entry name length */
@@ -764,17 +690,17 @@ xfs_dir2_put_dirent64_uio(
764 */ 690 */
765int 691int
766xfs_dir2_shrink_inode( 692xfs_dir2_shrink_inode(
767 xfs_da_args_t *args, /* operation arguments */ 693 xfs_da_args_t *args,
768 xfs_dir2_db_t db, /* directory block number */ 694 xfs_dir2_db_t db,
769 xfs_dabuf_t *bp) /* block's buffer */ 695 xfs_dabuf_t *bp)
770{ 696{
771 xfs_fileoff_t bno; /* directory file offset */ 697 xfs_fileoff_t bno; /* directory file offset */
772 xfs_dablk_t da; /* directory file offset */ 698 xfs_dablk_t da; /* directory file offset */
773 int done; /* bunmap is finished */ 699 int done; /* bunmap is finished */
774 xfs_inode_t *dp; /* incore directory inode */ 700 xfs_inode_t *dp;
775 int error; /* error return value */ 701 int error;
776 xfs_mount_t *mp; /* filesystem mount point */ 702 xfs_mount_t *mp;
777 xfs_trans_t *tp; /* transaction pointer */ 703 xfs_trans_t *tp;
778 704
779 xfs_dir2_trace_args_db("shrink_inode", args, db, bp); 705 xfs_dir2_trace_args_db("shrink_inode", args, db, bp);
780 dp = args->dp; 706 dp = args->dp;
@@ -786,7 +712,7 @@ xfs_dir2_shrink_inode(
786 */ 712 */
787 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, 713 if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
788 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, 714 XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
789 &done))) { 715 NULL, &done))) {
790 /* 716 /*
791 * ENOSPC actually can happen if we're in a removename with 717 * ENOSPC actually can happen if we're in a removename with
792 * no space reservation, and the resulting block removal 718 * no space reservation, and the resulting block removal
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 7dd364b1e038..86560b6f794c 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -22,7 +22,9 @@ struct uio;
22struct xfs_dabuf; 22struct xfs_dabuf;
23struct xfs_da_args; 23struct xfs_da_args;
24struct xfs_dir2_put_args; 24struct xfs_dir2_put_args;
25struct xfs_bmap_free;
25struct xfs_inode; 26struct xfs_inode;
27struct xfs_mount;
26struct xfs_trans; 28struct xfs_trans;
27 29
28/* 30/*
@@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args {
73} xfs_dir2_put_args_t; 75} xfs_dir2_put_args_t;
74 76
75/* 77/*
76 * Other interfaces used by the rest of the dir v2 code. 78 * Generic directory interface routines
79 */
80extern void xfs_dir_startup(void);
81extern void xfs_dir_mount(struct xfs_mount *mp);
82extern int xfs_dir_isempty(struct xfs_inode *dp);
83extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
84 struct xfs_inode *pdp);
85extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp,
86 char *name, int namelen, xfs_ino_t inum,
87 xfs_fsblock_t *first,
88 struct xfs_bmap_free *flist, xfs_extlen_t tot);
89extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp,
90 char *name, int namelen, xfs_ino_t *inum);
91extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp,
92 char *name, int namelen, xfs_ino_t ino,
93 xfs_fsblock_t *first,
94 struct xfs_bmap_free *flist, xfs_extlen_t tot);
95extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp,
96 uio_t *uio, int *eofp);
97extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp,
98 char *name, int namelen, xfs_ino_t inum,
99 xfs_fsblock_t *first,
100 struct xfs_bmap_free *flist, xfs_extlen_t tot);
101extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp,
102 char *name, int namelen);
103extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
104
105/*
106 * Utility routines for v2 directories.
77 */ 107 */
78extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, 108extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
79 xfs_dir2_db_t *dbp); 109 xfs_dir2_db_t *dbp);
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 972ded595476..9d7438bba30d 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -22,19 +22,16 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_inode_item.h" 34#include "xfs_inode_item.h"
37#include "xfs_dir_leaf.h"
38#include "xfs_dir2_data.h" 35#include "xfs_dir2_data.h"
39#include "xfs_dir2_leaf.h" 36#include "xfs_dir2_leaf.h"
40#include "xfs_dir2_block.h" 37#include "xfs_dir2_block.h"
@@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp,
51 int *entno); 48 int *entno);
52static int xfs_dir2_block_sort(const void *a, const void *b); 49static int xfs_dir2_block_sort(const void *a, const void *b);
53 50
51static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
52
53/*
54 * One-time startup routine called from xfs_init().
55 */
56void
57xfs_dir_startup(void)
58{
59 xfs_dir_hash_dot = xfs_da_hashname(".", 1);
60 xfs_dir_hash_dotdot = xfs_da_hashname("..", 2);
61}
62
54/* 63/*
55 * Add an entry to a block directory. 64 * Add an entry to a block directory.
56 */ 65 */
@@ -400,7 +409,7 @@ xfs_dir2_block_addname(
400 /* 409 /*
401 * Create the new data entry. 410 * Create the new data entry.
402 */ 411 */
403 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 412 dep->inumber = cpu_to_be64(args->inumber);
404 dep->namelen = args->namelen; 413 dep->namelen = args->namelen;
405 memcpy(dep->name, args->name, args->namelen); 414 memcpy(dep->name, args->name, args->namelen);
406 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 415 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -508,7 +517,7 @@ xfs_dir2_block_getdents(
508 517
509 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, 518 p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
510 ptr - (char *)block); 519 ptr - (char *)block);
511 p.ino = INT_GET(dep->inumber, ARCH_CONVERT); 520 p.ino = be64_to_cpu(dep->inumber);
512#if XFS_BIG_INUMS 521#if XFS_BIG_INUMS
513 p.ino += mp->m_inoadd; 522 p.ino += mp->m_inoadd;
514#endif 523#endif
@@ -626,7 +635,7 @@ xfs_dir2_block_lookup(
626 /* 635 /*
627 * Fill in inode number, release the block. 636 * Fill in inode number, release the block.
628 */ 637 */
629 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 638 args->inumber = be64_to_cpu(dep->inumber);
630 xfs_da_brelse(args->trans, bp); 639 xfs_da_brelse(args->trans, bp);
631 return XFS_ERROR(EEXIST); 640 return XFS_ERROR(EEXIST);
632} 641}
@@ -844,11 +853,11 @@ xfs_dir2_block_replace(
844 */ 853 */
845 dep = (xfs_dir2_data_entry_t *) 854 dep = (xfs_dir2_data_entry_t *)
846 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); 855 ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
847 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber); 856 ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
848 /* 857 /*
849 * Change the inode number to the new value. 858 * Change the inode number to the new value.
850 */ 859 */
851 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 860 dep->inumber = cpu_to_be64(args->inumber);
852 xfs_dir2_data_log_entry(args->trans, bp, dep); 861 xfs_dir2_data_log_entry(args->trans, bp, dep);
853 xfs_dir2_data_check(dp, bp); 862 xfs_dir2_data_check(dp, bp);
854 xfs_da_buf_done(bp); 863 xfs_da_buf_done(bp);
@@ -1130,7 +1139,7 @@ xfs_dir2_sf_to_block(
1130 */ 1139 */
1131 dep = (xfs_dir2_data_entry_t *) 1140 dep = (xfs_dir2_data_entry_t *)
1132 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); 1141 ((char *)block + XFS_DIR2_DATA_DOT_OFFSET);
1133 INT_SET(dep->inumber, ARCH_CONVERT, dp->i_ino); 1142 dep->inumber = cpu_to_be64(dp->i_ino);
1134 dep->namelen = 1; 1143 dep->namelen = 1;
1135 dep->name[0] = '.'; 1144 dep->name[0] = '.';
1136 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1145 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1144,7 +1153,7 @@ xfs_dir2_sf_to_block(
1144 */ 1153 */
1145 dep = (xfs_dir2_data_entry_t *) 1154 dep = (xfs_dir2_data_entry_t *)
1146 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); 1155 ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET);
1147 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); 1156 dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
1148 dep->namelen = 2; 1157 dep->namelen = 2;
1149 dep->name[0] = dep->name[1] = '.'; 1158 dep->name[0] = dep->name[1] = '.';
1150 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1159 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1193,7 +1202,7 @@ xfs_dir2_sf_to_block(
1193 * Copy a real entry. 1202 * Copy a real entry.
1194 */ 1203 */
1195 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); 1204 dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset);
1196 INT_SET(dep->inumber, ARCH_CONVERT, XFS_DIR2_SF_GET_INUMBER(sfp, 1205 dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp,
1197 XFS_DIR2_SF_INUMBERP(sfep))); 1206 XFS_DIR2_SF_INUMBERP(sfep)));
1198 dep->namelen = sfep->namelen; 1207 dep->namelen = sfep->namelen;
1199 memcpy(dep->name, sfep->name, dep->namelen); 1208 memcpy(dep->name, sfep->name, dep->namelen);
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index bb3d03ff002b..f7c799217072 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -22,18 +22,15 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_dir_leaf.h"
37#include "xfs_dir2_data.h" 34#include "xfs_dir2_data.h"
38#include "xfs_dir2_leaf.h" 35#include "xfs_dir2_leaf.h"
39#include "xfs_dir2_block.h" 36#include "xfs_dir2_block.h"
@@ -133,7 +130,7 @@ xfs_dir2_data_check(
133 */ 130 */
134 dep = (xfs_dir2_data_entry_t *)p; 131 dep = (xfs_dir2_data_entry_t *)p;
135 ASSERT(dep->namelen != 0); 132 ASSERT(dep->namelen != 0);
136 ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0); 133 ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0);
137 ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) == 134 ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) ==
138 (char *)dep - (char *)d); 135 (char *)dep - (char *)d);
139 count++; 136 count++;
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index 0847cbb53e17..a6ae2d21c40a 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -85,11 +85,11 @@ typedef struct xfs_dir2_data_hdr {
85 * Tag appears as the last 2 bytes. 85 * Tag appears as the last 2 bytes.
86 */ 86 */
87typedef struct xfs_dir2_data_entry { 87typedef struct xfs_dir2_data_entry {
88 xfs_ino_t inumber; /* inode number */ 88 __be64 inumber; /* inode number */
89 __uint8_t namelen; /* name length */ 89 __u8 namelen; /* name length */
90 __uint8_t name[1]; /* name bytes, no null */ 90 __u8 name[1]; /* name bytes, no null */
91 /* variable offset */ 91 /* variable offset */
92 xfs_dir2_data_off_t tag; /* starting offset of us */ 92 __be16 tag; /* starting offset of us */
93} xfs_dir2_data_entry_t; 93} xfs_dir2_data_entry_t;
94 94
95/* 95/*
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 0f5e2f2ce6ec..b1cf1fbf423d 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_da_btree.h" 30#include "xfs_da_btree.h"
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_dinode.h" 34#include "xfs_dinode.h"
37#include "xfs_inode.h" 35#include "xfs_inode.h"
@@ -407,7 +405,7 @@ xfs_dir2_leaf_addname(
407 * Initialize our new entry (at last). 405 * Initialize our new entry (at last).
408 */ 406 */
409 dep = (xfs_dir2_data_entry_t *)dup; 407 dep = (xfs_dir2_data_entry_t *)dup;
410 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 408 dep->inumber = cpu_to_be64(args->inumber);
411 dep->namelen = args->namelen; 409 dep->namelen = args->namelen;
412 memcpy(dep->name, args->name, dep->namelen); 410 memcpy(dep->name, args->name, dep->namelen);
413 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 411 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -884,7 +882,7 @@ xfs_dir2_leaf_getdents(
884 XFS_DIR2_BYTE_TO_DA(mp, 882 XFS_DIR2_BYTE_TO_DA(mp,
885 XFS_DIR2_LEAF_OFFSET) - map_off, 883 XFS_DIR2_LEAF_OFFSET) - map_off,
886 XFS_BMAPI_METADATA, NULL, 0, 884 XFS_BMAPI_METADATA, NULL, 0,
887 &map[map_valid], &nmap, NULL); 885 &map[map_valid], &nmap, NULL, NULL);
888 /* 886 /*
889 * Don't know if we should ignore this or 887 * Don't know if we should ignore this or
890 * try to return an error. 888 * try to return an error.
@@ -1098,7 +1096,7 @@ xfs_dir2_leaf_getdents(
1098 1096
1099 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); 1097 p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
1100 1098
1101 p->ino = INT_GET(dep->inumber, ARCH_CONVERT); 1099 p->ino = be64_to_cpu(dep->inumber);
1102#if XFS_BIG_INUMS 1100#if XFS_BIG_INUMS
1103 p->ino += mp->m_inoadd; 1101 p->ino += mp->m_inoadd;
1104#endif 1102#endif
@@ -1319,7 +1317,7 @@ xfs_dir2_leaf_lookup(
1319 /* 1317 /*
1320 * Return the found inode number. 1318 * Return the found inode number.
1321 */ 1319 */
1322 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 1320 args->inumber = be64_to_cpu(dep->inumber);
1323 xfs_da_brelse(tp, dbp); 1321 xfs_da_brelse(tp, dbp);
1324 xfs_da_brelse(tp, lbp); 1322 xfs_da_brelse(tp, lbp);
1325 return XFS_ERROR(EEXIST); 1323 return XFS_ERROR(EEXIST);
@@ -1606,11 +1604,11 @@ xfs_dir2_leaf_replace(
1606 dep = (xfs_dir2_data_entry_t *) 1604 dep = (xfs_dir2_data_entry_t *)
1607 ((char *)dbp->data + 1605 ((char *)dbp->data +
1608 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); 1606 XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
1609 ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT)); 1607 ASSERT(args->inumber != be64_to_cpu(dep->inumber));
1610 /* 1608 /*
1611 * Put the new inode number in, log it. 1609 * Put the new inode number in, log it.
1612 */ 1610 */
1613 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1611 dep->inumber = cpu_to_be64(args->inumber);
1614 tp = args->trans; 1612 tp = args->trans;
1615 xfs_dir2_data_log_entry(tp, dbp, dep); 1613 xfs_dir2_data_log_entry(tp, dbp, dep);
1616 xfs_da_buf_done(dbp); 1614 xfs_da_buf_done(dbp);
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index ac511ab9c52d..9ca71719b683 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -22,13 +22,11 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
@@ -505,7 +503,6 @@ xfs_dir2_leafn_lookup_int(
505 XFS_DATA_FORK))) { 503 XFS_DATA_FORK))) {
506 return error; 504 return error;
507 } 505 }
508 curfdb = newfdb;
509 free = curbp->data; 506 free = curbp->data;
510 ASSERT(be32_to_cpu(free->hdr.magic) == 507 ASSERT(be32_to_cpu(free->hdr.magic) ==
511 XFS_DIR2_FREE_MAGIC); 508 XFS_DIR2_FREE_MAGIC);
@@ -527,8 +524,11 @@ xfs_dir2_leafn_lookup_int(
527 if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) { 524 if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) {
528 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int", 525 XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
529 XFS_ERRLEVEL_LOW, mp); 526 XFS_ERRLEVEL_LOW, mp);
527 if (curfdb != newfdb)
528 xfs_da_brelse(tp, curbp);
530 return XFS_ERROR(EFSCORRUPTED); 529 return XFS_ERROR(EFSCORRUPTED);
531 } 530 }
531 curfdb = newfdb;
532 if (be16_to_cpu(free->bests[fi]) >= length) { 532 if (be16_to_cpu(free->bests[fi]) >= length) {
533 *indexp = index; 533 *indexp = index;
534 state->extravalid = 1; 534 state->extravalid = 1;
@@ -580,7 +580,7 @@ xfs_dir2_leafn_lookup_int(
580 if (dep->namelen == args->namelen && 580 if (dep->namelen == args->namelen &&
581 dep->name[0] == args->name[0] && 581 dep->name[0] == args->name[0] &&
582 memcmp(dep->name, args->name, args->namelen) == 0) { 582 memcmp(dep->name, args->name, args->namelen) == 0) {
583 args->inumber = INT_GET(dep->inumber, ARCH_CONVERT); 583 args->inumber = be64_to_cpu(dep->inumber);
584 *indexp = index; 584 *indexp = index;
585 state->extravalid = 1; 585 state->extravalid = 1;
586 state->extrablk.bp = curbp; 586 state->extrablk.bp = curbp;
@@ -970,7 +970,7 @@ xfs_dir2_leafn_remove(
970 /* 970 /*
971 * One less used entry in the free table. 971 * One less used entry in the free table.
972 */ 972 */
973 free->hdr.nused = cpu_to_be32(-1); 973 be32_add(&free->hdr.nused, -1);
974 xfs_dir2_free_log_header(tp, fbp); 974 xfs_dir2_free_log_header(tp, fbp);
975 /* 975 /*
976 * If this was the last entry in the table, we can 976 * If this was the last entry in the table, we can
@@ -1695,7 +1695,7 @@ xfs_dir2_node_addname_int(
1695 * Fill in the new entry and log it. 1695 * Fill in the new entry and log it.
1696 */ 1696 */
1697 dep = (xfs_dir2_data_entry_t *)dup; 1697 dep = (xfs_dir2_data_entry_t *)dup;
1698 INT_SET(dep->inumber, ARCH_CONVERT, args->inumber); 1698 dep->inumber = cpu_to_be64(args->inumber);
1699 dep->namelen = args->namelen; 1699 dep->namelen = args->namelen;
1700 memcpy(dep->name, args->name, dep->namelen); 1700 memcpy(dep->name, args->name, dep->namelen);
1701 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); 1701 tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
@@ -1905,11 +1905,11 @@ xfs_dir2_node_replace(
1905 dep = (xfs_dir2_data_entry_t *) 1905 dep = (xfs_dir2_data_entry_t *)
1906 ((char *)data + 1906 ((char *)data +
1907 XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address))); 1907 XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address)));
1908 ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT)); 1908 ASSERT(inum != be64_to_cpu(dep->inumber));
1909 /* 1909 /*
1910 * Fill in the new inode number and log the entry. 1910 * Fill in the new inode number and log the entry.
1911 */ 1911 */
1912 INT_SET(dep->inumber, ARCH_CONVERT, inum); 1912 dep->inumber = cpu_to_be64(inum);
1913 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); 1913 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep);
1914 rval = 0; 1914 rval = 0;
1915 } 1915 }
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index d98a41d1fe63..0cd77b17bf92 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -22,19 +22,16 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
35#include "xfs_inode.h" 33#include "xfs_inode.h"
36#include "xfs_inode_item.h" 34#include "xfs_inode_item.h"
37#include "xfs_dir_leaf.h"
38#include "xfs_error.h" 35#include "xfs_error.h"
39#include "xfs_dir2_data.h" 36#include "xfs_dir2_data.h"
40#include "xfs_dir2_leaf.h" 37#include "xfs_dir2_leaf.h"
@@ -117,13 +114,13 @@ xfs_dir2_block_sfsize(
117 dep->name[0] == '.' && dep->name[1] == '.'; 114 dep->name[0] == '.' && dep->name[1] == '.';
118#if XFS_BIG_INUMS 115#if XFS_BIG_INUMS
119 if (!isdot) 116 if (!isdot)
120 i8count += INT_GET(dep->inumber, ARCH_CONVERT) > XFS_DIR2_MAX_SHORT_INUM; 117 i8count += be64_to_cpu(dep->inumber) > XFS_DIR2_MAX_SHORT_INUM;
121#endif 118#endif
122 if (!isdot && !isdotdot) { 119 if (!isdot && !isdotdot) {
123 count++; 120 count++;
124 namelen += dep->namelen; 121 namelen += dep->namelen;
125 } else if (isdotdot) 122 } else if (isdotdot)
126 parent = INT_GET(dep->inumber, ARCH_CONVERT); 123 parent = be64_to_cpu(dep->inumber);
127 /* 124 /*
128 * Calculate the new size, see if we should give up yet. 125 * Calculate the new size, see if we should give up yet.
129 */ 126 */
@@ -229,13 +226,13 @@ xfs_dir2_block_to_sf(
229 * Skip . 226 * Skip .
230 */ 227 */
231 if (dep->namelen == 1 && dep->name[0] == '.') 228 if (dep->namelen == 1 && dep->name[0] == '.')
232 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == dp->i_ino); 229 ASSERT(be64_to_cpu(dep->inumber) == dp->i_ino);
233 /* 230 /*
234 * Skip .., but make sure the inode number is right. 231 * Skip .., but make sure the inode number is right.
235 */ 232 */
236 else if (dep->namelen == 2 && 233 else if (dep->namelen == 2 &&
237 dep->name[0] == '.' && dep->name[1] == '.') 234 dep->name[0] == '.' && dep->name[1] == '.')
238 ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) == 235 ASSERT(be64_to_cpu(dep->inumber) ==
239 XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); 236 XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent));
240 /* 237 /*
241 * Normal entry, copy it into shortform. 238 * Normal entry, copy it into shortform.
@@ -246,7 +243,7 @@ xfs_dir2_block_to_sf(
246 (xfs_dir2_data_aoff_t) 243 (xfs_dir2_data_aoff_t)
247 ((char *)dep - (char *)block)); 244 ((char *)dep - (char *)block));
248 memcpy(sfep->name, dep->name, dep->namelen); 245 memcpy(sfep->name, dep->name, dep->namelen);
249 temp=INT_GET(dep->inumber, ARCH_CONVERT); 246 temp = be64_to_cpu(dep->inumber);
250 XFS_DIR2_SF_PUT_INUMBER(sfp, &temp, 247 XFS_DIR2_SF_PUT_INUMBER(sfp, &temp,
251 XFS_DIR2_SF_INUMBERP(sfep)); 248 XFS_DIR2_SF_INUMBERP(sfep));
252 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); 249 sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c
index c626943b4112..f3fb2ffd6f5c 100644
--- a/fs/xfs/xfs_dir2_trace.c
+++ b/fs/xfs/xfs_dir2_trace.c
@@ -19,11 +19,9 @@
19#include "xfs_fs.h" 19#include "xfs_fs.h"
20#include "xfs_types.h" 20#include "xfs_types.h"
21#include "xfs_inum.h" 21#include "xfs_inum.h"
22#include "xfs_dir.h"
23#include "xfs_dir2.h" 22#include "xfs_dir2.h"
24#include "xfs_da_btree.h" 23#include "xfs_da_btree.h"
25#include "xfs_bmap_btree.h" 24#include "xfs_bmap_btree.h"
26#include "xfs_dir_sf.h"
27#include "xfs_dir2_sf.h" 25#include "xfs_dir2_sf.h"
28#include "xfs_attr_sf.h" 26#include "xfs_attr_sf.h"
29#include "xfs_dinode.h" 27#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
deleted file mode 100644
index 6d711869262f..000000000000
--- a/fs/xfs/xfs_dir_leaf.c
+++ /dev/null
@@ -1,2213 +0,0 @@
1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_types.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h"
27#include "xfs_dmapi.h"
28#include "xfs_mount.h"
29#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h"
33#include "xfs_dir_sf.h"
34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
36#include "xfs_dinode.h"
37#include "xfs_inode.h"
38#include "xfs_inode_item.h"
39#include "xfs_alloc.h"
40#include "xfs_btree.h"
41#include "xfs_bmap.h"
42#include "xfs_dir_leaf.h"
43#include "xfs_error.h"
44
45/*
46 * xfs_dir_leaf.c
47 *
48 * Routines to implement leaf blocks of directories as Btrees of hashed names.
49 */
50
51/*========================================================================
52 * Function prototypes for the kernel.
53 *========================================================================*/
54
55/*
56 * Routines used for growing the Btree.
57 */
58STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
59 int insertion_index,
60 int freemap_index);
61STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer,
62 int musthave, int justcheck);
63STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state,
64 xfs_da_state_blk_t *blk1,
65 xfs_da_state_blk_t *blk2);
66STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
67 xfs_da_state_blk_t *leaf_blk_1,
68 xfs_da_state_blk_t *leaf_blk_2,
69 int *number_entries_in_blk1,
70 int *number_namebytes_in_blk1);
71
72STATIC int xfs_dir_leaf_create(struct xfs_da_args *args,
73 xfs_dablk_t which_block,
74 struct xfs_dabuf **bpp);
75
76/*
77 * Utility routines.
78 */
79STATIC void xfs_dir_leaf_moveents(xfs_dir_leafblock_t *src_leaf,
80 int src_start,
81 xfs_dir_leafblock_t *dst_leaf,
82 int dst_start, int move_count,
83 xfs_mount_t *mp);
84
85
86/*========================================================================
87 * External routines when dirsize < XFS_IFORK_DSIZE(dp).
88 *========================================================================*/
89
90
91/*
92 * Validate a given inode number.
93 */
94int
95xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino)
96{
97 xfs_agblock_t agblkno;
98 xfs_agino_t agino;
99 xfs_agnumber_t agno;
100 int ino_ok;
101 int ioff;
102
103 agno = XFS_INO_TO_AGNO(mp, ino);
104 agblkno = XFS_INO_TO_AGBNO(mp, ino);
105 ioff = XFS_INO_TO_OFFSET(mp, ino);
106 agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff);
107 ino_ok =
108 agno < mp->m_sb.sb_agcount &&
109 agblkno < mp->m_sb.sb_agblocks &&
110 agblkno != 0 &&
111 ioff < (1 << mp->m_sb.sb_inopblog) &&
112 XFS_AGINO_TO_INO(mp, agno, agino) == ino;
113 if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE,
114 XFS_RANDOM_DIR_INO_VALIDATE))) {
115 xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx",
116 (unsigned long long) ino);
117 XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp);
118 return XFS_ERROR(EFSCORRUPTED);
119 }
120 return 0;
121}
122
123/*
124 * Create the initial contents of a shortform directory.
125 */
126int
127xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent)
128{
129 xfs_dir_sf_hdr_t *hdr;
130 xfs_inode_t *dp;
131
132 dp = args->dp;
133 ASSERT(dp != NULL);
134 ASSERT(dp->i_d.di_size == 0);
135 if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) {
136 dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */
137 dp->i_d.di_format = XFS_DINODE_FMT_LOCAL;
138 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
139 dp->i_df.if_flags |= XFS_IFINLINE;
140 }
141 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
142 ASSERT(dp->i_df.if_bytes == 0);
143 xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK);
144 hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data;
145 XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent);
146
147 hdr->count = 0;
148 dp->i_d.di_size = sizeof(*hdr);
149 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
150 return 0;
151}
152
153/*
154 * Add a name to the shortform directory structure.
155 * Overflow from the inode has already been checked for.
156 */
157int
158xfs_dir_shortform_addname(xfs_da_args_t *args)
159{
160 xfs_dir_shortform_t *sf;
161 xfs_dir_sf_entry_t *sfe;
162 int i, offset, size;
163 xfs_inode_t *dp;
164
165 dp = args->dp;
166 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
167 /*
168 * Catch the case where the conversion from shortform to leaf
169 * failed part way through.
170 */
171 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
172 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
173 return XFS_ERROR(EIO);
174 }
175 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
176 ASSERT(dp->i_df.if_u1.if_data != NULL);
177 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
178 sfe = &sf->list[0];
179 for (i = sf->hdr.count-1; i >= 0; i--) {
180 if (sfe->namelen == args->namelen &&
181 args->name[0] == sfe->name[0] &&
182 memcmp(args->name, sfe->name, args->namelen) == 0)
183 return XFS_ERROR(EEXIST);
184 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
185 }
186
187 offset = (int)((char *)sfe - (char *)sf);
188 size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen);
189 xfs_idata_realloc(dp, size, XFS_DATA_FORK);
190 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
191 sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset);
192
193 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
194 sfe->namelen = args->namelen;
195 memcpy(sfe->name, args->name, sfe->namelen);
196 sf->hdr.count++;
197
198 dp->i_d.di_size += size;
199 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
200
201 return 0;
202}
203
204/*
205 * Remove a name from the shortform directory structure.
206 */
207int
208xfs_dir_shortform_removename(xfs_da_args_t *args)
209{
210 xfs_dir_shortform_t *sf;
211 xfs_dir_sf_entry_t *sfe;
212 int base, size = 0, i;
213 xfs_inode_t *dp;
214
215 dp = args->dp;
216 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
217 /*
218 * Catch the case where the conversion from shortform to leaf
219 * failed part way through.
220 */
221 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
222 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
223 return XFS_ERROR(EIO);
224 }
225 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
226 ASSERT(dp->i_df.if_u1.if_data != NULL);
227 base = sizeof(xfs_dir_sf_hdr_t);
228 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
229 sfe = &sf->list[0];
230 for (i = sf->hdr.count-1; i >= 0; i--) {
231 size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe);
232 if (sfe->namelen == args->namelen &&
233 sfe->name[0] == args->name[0] &&
234 memcmp(sfe->name, args->name, args->namelen) == 0)
235 break;
236 base += size;
237 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
238 }
239 if (i < 0) {
240 ASSERT(args->oknoent);
241 return XFS_ERROR(ENOENT);
242 }
243
244 if ((base + size) != dp->i_d.di_size) {
245 memmove(&((char *)sf)[base], &((char *)sf)[base+size],
246 dp->i_d.di_size - (base+size));
247 }
248 sf->hdr.count--;
249
250 xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
251 dp->i_d.di_size -= size;
252 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
253
254 return 0;
255}
256
257/*
258 * Look up a name in a shortform directory structure.
259 */
260int
261xfs_dir_shortform_lookup(xfs_da_args_t *args)
262{
263 xfs_dir_shortform_t *sf;
264 xfs_dir_sf_entry_t *sfe;
265 int i;
266 xfs_inode_t *dp;
267
268 dp = args->dp;
269 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
270 /*
271 * Catch the case where the conversion from shortform to leaf
272 * failed part way through.
273 */
274 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
275 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
276 return XFS_ERROR(EIO);
277 }
278 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
279 ASSERT(dp->i_df.if_u1.if_data != NULL);
280 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
281 if (args->namelen == 2 &&
282 args->name[0] == '.' && args->name[1] == '.') {
283 XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber);
284 return(XFS_ERROR(EEXIST));
285 }
286 if (args->namelen == 1 && args->name[0] == '.') {
287 args->inumber = dp->i_ino;
288 return(XFS_ERROR(EEXIST));
289 }
290 sfe = &sf->list[0];
291 for (i = sf->hdr.count-1; i >= 0; i--) {
292 if (sfe->namelen == args->namelen &&
293 sfe->name[0] == args->name[0] &&
294 memcmp(args->name, sfe->name, args->namelen) == 0) {
295 XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber);
296 return(XFS_ERROR(EEXIST));
297 }
298 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
299 }
300 ASSERT(args->oknoent);
301 return(XFS_ERROR(ENOENT));
302}
303
304/*
305 * Convert from using the shortform to the leaf.
306 */
307int
308xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs)
309{
310 xfs_inode_t *dp;
311 xfs_dir_shortform_t *sf;
312 xfs_dir_sf_entry_t *sfe;
313 xfs_da_args_t args;
314 xfs_ino_t inumber;
315 char *tmpbuffer;
316 int retval, i, size;
317 xfs_dablk_t blkno;
318 xfs_dabuf_t *bp;
319
320 dp = iargs->dp;
321 /*
322 * Catch the case where the conversion from shortform to leaf
323 * failed part way through.
324 */
325 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
326 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
327 return XFS_ERROR(EIO);
328 }
329 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
330 ASSERT(dp->i_df.if_u1.if_data != NULL);
331 size = dp->i_df.if_bytes;
332 tmpbuffer = kmem_alloc(size, KM_SLEEP);
333 ASSERT(tmpbuffer != NULL);
334
335 memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size);
336
337 sf = (xfs_dir_shortform_t *)tmpbuffer;
338 XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber);
339
340 xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
341 dp->i_d.di_size = 0;
342 xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE);
343 retval = xfs_da_grow_inode(iargs, &blkno);
344 if (retval)
345 goto out;
346
347 ASSERT(blkno == 0);
348 retval = xfs_dir_leaf_create(iargs, blkno, &bp);
349 if (retval)
350 goto out;
351 xfs_da_buf_done(bp);
352
353 args.name = ".";
354 args.namelen = 1;
355 args.hashval = xfs_dir_hash_dot;
356 args.inumber = dp->i_ino;
357 args.dp = dp;
358 args.firstblock = iargs->firstblock;
359 args.flist = iargs->flist;
360 args.total = iargs->total;
361 args.whichfork = XFS_DATA_FORK;
362 args.trans = iargs->trans;
363 args.justcheck = 0;
364 args.addname = args.oknoent = 1;
365 retval = xfs_dir_leaf_addname(&args);
366 if (retval)
367 goto out;
368
369 args.name = "..";
370 args.namelen = 2;
371 args.hashval = xfs_dir_hash_dotdot;
372 args.inumber = inumber;
373 retval = xfs_dir_leaf_addname(&args);
374 if (retval)
375 goto out;
376
377 sfe = &sf->list[0];
378 for (i = 0; i < sf->hdr.count; i++) {
379 args.name = (char *)(sfe->name);
380 args.namelen = sfe->namelen;
381 args.hashval = xfs_da_hashname((char *)(sfe->name),
382 sfe->namelen);
383 XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber);
384 retval = xfs_dir_leaf_addname(&args);
385 if (retval)
386 goto out;
387 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
388 }
389 retval = 0;
390
391out:
392 kmem_free(tmpbuffer, size);
393 return retval;
394}
395
396STATIC int
397xfs_dir_shortform_compare(const void *a, const void *b)
398{
399 xfs_dir_sf_sort_t *sa, *sb;
400
401 sa = (xfs_dir_sf_sort_t *)a;
402 sb = (xfs_dir_sf_sort_t *)b;
403 if (sa->hash < sb->hash)
404 return -1;
405 else if (sa->hash > sb->hash)
406 return 1;
407 else
408 return sa->entno - sb->entno;
409}
410
411/*
412 * Copy out directory entries for getdents(), for shortform directories.
413 */
414/*ARGSUSED*/
415int
416xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
417 xfs_dirent_t *dbp, xfs_dir_put_t put)
418{
419 xfs_dir_shortform_t *sf;
420 xfs_dir_sf_entry_t *sfe;
421 int retval, i, sbsize, nsbuf, lastresid=0, want_entno;
422 xfs_mount_t *mp;
423 xfs_dahash_t cookhash, hash;
424 xfs_dir_put_args_t p;
425 xfs_dir_sf_sort_t *sbuf, *sbp;
426
427 mp = dp->i_mount;
428 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
429 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
430 want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
431 nsbuf = sf->hdr.count + 2;
432 sbsize = (nsbuf + 1) * sizeof(*sbuf);
433 sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP);
434
435 xfs_dir_trace_g_du("sf: start", dp, uio);
436
437 /*
438 * Collect all the entries into the buffer.
439 * Entry 0 is .
440 */
441 sbp->entno = 0;
442 sbp->seqno = 0;
443 sbp->hash = xfs_dir_hash_dot;
444 sbp->ino = dp->i_ino;
445 sbp->name = ".";
446 sbp->namelen = 1;
447 sbp++;
448
449 /*
450 * Entry 1 is ..
451 */
452 sbp->entno = 1;
453 sbp->seqno = 0;
454 sbp->hash = xfs_dir_hash_dotdot;
455 sbp->ino = XFS_GET_DIR_INO8(sf->hdr.parent);
456 sbp->name = "..";
457 sbp->namelen = 2;
458 sbp++;
459
460 /*
461 * Scan the directory data for the rest of the entries.
462 */
463 for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
464
465 if (unlikely(
466 ((char *)sfe < (char *)sf) ||
467 ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) {
468 xfs_dir_trace_g_du("sf: corrupted", dp, uio);
469 XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents",
470 XFS_ERRLEVEL_LOW, mp, sfe);
471 kmem_free(sbuf, sbsize);
472 return XFS_ERROR(EFSCORRUPTED);
473 }
474
475 sbp->entno = i + 2;
476 sbp->seqno = 0;
477 sbp->hash = xfs_da_hashname((char *)sfe->name, sfe->namelen);
478 sbp->ino = XFS_GET_DIR_INO8(sfe->inumber);
479 sbp->name = (char *)sfe->name;
480 sbp->namelen = sfe->namelen;
481 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
482 sbp++;
483 }
484
485 /*
486 * Sort the entries on hash then entno.
487 */
488 xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare);
489 /*
490 * Stuff in last entry.
491 */
492 sbp->entno = nsbuf;
493 sbp->hash = XFS_DA_MAXHASH;
494 sbp->seqno = 0;
495 /*
496 * Figure out the sequence numbers in case there's a hash duplicate.
497 */
498 for (hash = sbuf->hash, sbp = sbuf + 1;
499 sbp < &sbuf[nsbuf + 1]; sbp++) {
500 if (sbp->hash == hash)
501 sbp->seqno = sbp[-1].seqno + 1;
502 else
503 hash = sbp->hash;
504 }
505
506 /*
507 * Set up put routine.
508 */
509 p.dbp = dbp;
510 p.put = put;
511 p.uio = uio;
512
513 /*
514 * Find our place.
515 */
516 for (sbp = sbuf; sbp < &sbuf[nsbuf + 1]; sbp++) {
517 if (sbp->hash > cookhash ||
518 (sbp->hash == cookhash && sbp->seqno >= want_entno))
519 break;
520 }
521
522 /*
523 * Did we fail to find anything? We stop at the last entry,
524 * the one we put maxhash into.
525 */
526 if (sbp == &sbuf[nsbuf]) {
527 kmem_free(sbuf, sbsize);
528 xfs_dir_trace_g_du("sf: hash beyond end", dp, uio);
529 uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
530 *eofp = 1;
531 return 0;
532 }
533
534 /*
535 * Loop putting entries into the user buffer.
536 */
537 while (sbp < &sbuf[nsbuf]) {
538 /*
539 * Save the first resid in a run of equal-hashval entries
540 * so that we can back them out if they don't all fit.
541 */
542 if (sbp->seqno == 0 || sbp == sbuf)
543 lastresid = uio->uio_resid;
544 XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash);
545 p.ino = sbp->ino;
546#if XFS_BIG_INUMS
547 p.ino += mp->m_inoadd;
548#endif
549 p.name = sbp->name;
550 p.namelen = sbp->namelen;
551 retval = p.put(&p);
552 if (!p.done) {
553 uio->uio_offset =
554 XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash);
555 kmem_free(sbuf, sbsize);
556 uio->uio_resid = lastresid;
557 xfs_dir_trace_g_du("sf: E-O-B", dp, uio);
558 return retval;
559 }
560 sbp++;
561 }
562 kmem_free(sbuf, sbsize);
563 uio->uio_offset = p.cook.o;
564 *eofp = 1;
565 xfs_dir_trace_g_du("sf: E-O-F", dp, uio);
566 return 0;
567}
568
569/*
570 * Look up a name in a shortform directory structure, replace the inode number.
571 */
572int
573xfs_dir_shortform_replace(xfs_da_args_t *args)
574{
575 xfs_dir_shortform_t *sf;
576 xfs_dir_sf_entry_t *sfe;
577 xfs_inode_t *dp;
578 int i;
579
580 dp = args->dp;
581 ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
582 /*
583 * Catch the case where the conversion from shortform to leaf
584 * failed part way through.
585 */
586 if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) {
587 ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
588 return XFS_ERROR(EIO);
589 }
590 ASSERT(dp->i_df.if_bytes == dp->i_d.di_size);
591 ASSERT(dp->i_df.if_u1.if_data != NULL);
592 sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
593 if (args->namelen == 2 &&
594 args->name[0] == '.' && args->name[1] == '.') {
595 /* XXX - replace assert? */
596 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent);
597 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
598 return 0;
599 }
600 ASSERT(args->namelen != 1 || args->name[0] != '.');
601 sfe = &sf->list[0];
602 for (i = sf->hdr.count-1; i >= 0; i--) {
603 if (sfe->namelen == args->namelen &&
604 sfe->name[0] == args->name[0] &&
605 memcmp(args->name, sfe->name, args->namelen) == 0) {
606 ASSERT(memcmp((char *)&args->inumber,
607 (char *)&sfe->inumber, sizeof(xfs_ino_t)));
608 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
609 xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA);
610 return 0;
611 }
612 sfe = XFS_DIR_SF_NEXTENTRY(sfe);
613 }
614 ASSERT(args->oknoent);
615 return XFS_ERROR(ENOENT);
616}
617
618/*
619 * Convert a leaf directory to shortform structure
620 */
621int
622xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs)
623{
624 xfs_dir_leafblock_t *leaf;
625 xfs_dir_leaf_hdr_t *hdr;
626 xfs_dir_leaf_entry_t *entry;
627 xfs_dir_leaf_name_t *namest;
628 xfs_da_args_t args;
629 xfs_inode_t *dp;
630 xfs_ino_t parent = 0;
631 char *tmpbuffer;
632 int retval, i;
633 xfs_dabuf_t *bp;
634
635 dp = iargs->dp;
636 tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP);
637 ASSERT(tmpbuffer != NULL);
638
639 retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp,
640 XFS_DATA_FORK);
641 if (retval)
642 goto out;
643 ASSERT(bp != NULL);
644 memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount));
645 leaf = (xfs_dir_leafblock_t *)tmpbuffer;
646 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
647 memset(bp->data, 0, XFS_LBSIZE(dp->i_mount));
648
649 /*
650 * Find and special case the parent inode number
651 */
652 hdr = &leaf->hdr;
653 entry = &leaf->entries[0];
654 for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
655 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
656 if ((entry->namelen == 2) &&
657 (namest->name[0] == '.') &&
658 (namest->name[1] == '.')) {
659 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent);
660 entry->nameidx = 0;
661 } else if ((entry->namelen == 1) && (namest->name[0] == '.')) {
662 entry->nameidx = 0;
663 }
664 }
665 retval = xfs_da_shrink_inode(iargs, 0, bp);
666 if (retval)
667 goto out;
668 retval = xfs_dir_shortform_create(iargs, parent);
669 if (retval)
670 goto out;
671
672 /*
673 * Copy the rest of the filenames
674 */
675 entry = &leaf->entries[0];
676 args.dp = dp;
677 args.firstblock = iargs->firstblock;
678 args.flist = iargs->flist;
679 args.total = iargs->total;
680 args.whichfork = XFS_DATA_FORK;
681 args.trans = iargs->trans;
682 args.justcheck = 0;
683 args.addname = args.oknoent = 1;
684 for (i = 0; i < INT_GET(hdr->count, ARCH_CONVERT); entry++, i++) {
685 if (!entry->nameidx)
686 continue;
687 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
688 args.name = (char *)(namest->name);
689 args.namelen = entry->namelen;
690 args.hashval = INT_GET(entry->hashval, ARCH_CONVERT);
691 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber);
692 xfs_dir_shortform_addname(&args);
693 }
694
695out:
696 kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount));
697 return retval;
698}
699
700/*
701 * Convert from using a single leaf to a root node and a leaf.
702 */
703int
704xfs_dir_leaf_to_node(xfs_da_args_t *args)
705{
706 xfs_dir_leafblock_t *leaf;
707 xfs_da_intnode_t *node;
708 xfs_inode_t *dp;
709 xfs_dabuf_t *bp1, *bp2;
710 xfs_dablk_t blkno;
711 int retval;
712
713 dp = args->dp;
714 retval = xfs_da_grow_inode(args, &blkno);
715 ASSERT(blkno == 1);
716 if (retval)
717 return retval;
718 retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1,
719 XFS_DATA_FORK);
720 if (retval)
721 return retval;
722 ASSERT(bp1 != NULL);
723 retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2,
724 XFS_DATA_FORK);
725 if (retval) {
726 xfs_da_buf_done(bp1);
727 return retval;
728 }
729 ASSERT(bp2 != NULL);
730 memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount));
731 xfs_da_buf_done(bp1);
732 xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1);
733
734 /*
735 * Set up the new root node.
736 */
737 retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK);
738 if (retval) {
739 xfs_da_buf_done(bp2);
740 return retval;
741 }
742 node = bp1->data;
743 leaf = bp2->data;
744 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
745 node->btree[0].hashval = cpu_to_be32(
746 INT_GET(leaf->entries[
747 INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
748 xfs_da_buf_done(bp2);
749 node->btree[0].before = cpu_to_be32(blkno);
750 node->hdr.count = cpu_to_be16(1);
751 xfs_da_log_buf(args->trans, bp1,
752 XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0])));
753 xfs_da_buf_done(bp1);
754
755 return retval;
756}
757
758
759/*========================================================================
760 * Routines used for growing the Btree.
761 *========================================================================*/
762
763/*
764 * Create the initial contents of a leaf directory
765 * or a leaf in a node directory.
766 */
767STATIC int
768xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
769{
770 xfs_dir_leafblock_t *leaf;
771 xfs_dir_leaf_hdr_t *hdr;
772 xfs_inode_t *dp;
773 xfs_dabuf_t *bp;
774 int retval;
775
776 dp = args->dp;
777 ASSERT(dp != NULL);
778 retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK);
779 if (retval)
780 return retval;
781 ASSERT(bp != NULL);
782 leaf = bp->data;
783 memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
784 hdr = &leaf->hdr;
785 hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC);
786 INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount));
787 if (!hdr->firstused)
788 INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount) - 1);
789 INT_SET(hdr->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
790 INT_SET(hdr->freemap[0].size, ARCH_CONVERT, INT_GET(hdr->firstused, ARCH_CONVERT) - INT_GET(hdr->freemap[0].base, ARCH_CONVERT));
791
792 xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1);
793
794 *bpp = bp;
795 return 0;
796}
797
798/*
799 * Split the leaf node, rebalance, then add the new entry.
800 */
801int
802xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
803 xfs_da_state_blk_t *newblk)
804{
805 xfs_dablk_t blkno;
806 xfs_da_args_t *args;
807 int error;
808
809 /*
810 * Allocate space for a new leaf node.
811 */
812 args = state->args;
813 ASSERT(args != NULL);
814 ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC);
815 error = xfs_da_grow_inode(args, &blkno);
816 if (error)
817 return error;
818 error = xfs_dir_leaf_create(args, blkno, &newblk->bp);
819 if (error)
820 return error;
821 newblk->blkno = blkno;
822 newblk->magic = XFS_DIR_LEAF_MAGIC;
823
824 /*
825 * Rebalance the entries across the two leaves.
826 */
827 xfs_dir_leaf_rebalance(state, oldblk, newblk);
828 error = xfs_da_blk_link(state, oldblk, newblk);
829 if (error)
830 return error;
831
832 /*
833 * Insert the new entry in the correct block.
834 */
835 if (state->inleaf) {
836 error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index);
837 } else {
838 error = xfs_dir_leaf_add(newblk->bp, args, newblk->index);
839 }
840
841 /*
842 * Update last hashval in each block since we added the name.
843 */
844 oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL);
845 newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL);
846 return error;
847}
848
849/*
850 * Add a name to the leaf directory structure.
851 *
852 * Must take into account fragmented leaves and leaves where spacemap has
853 * lost some freespace information (ie: holes).
854 */
855int
856xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index)
857{
858 xfs_dir_leafblock_t *leaf;
859 xfs_dir_leaf_hdr_t *hdr;
860 xfs_dir_leaf_map_t *map;
861 int tablesize, entsize, sum, i, tmp, error;
862
863 leaf = bp->data;
864 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
865 ASSERT((index >= 0) && (index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
866 hdr = &leaf->hdr;
867 entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen);
868
869 /*
870 * Search through freemap for first-fit on new name length.
871 * (may need to figure in size of entry struct too)
872 */
873 tablesize = (INT_GET(hdr->count, ARCH_CONVERT) + 1) * (uint)sizeof(xfs_dir_leaf_entry_t)
874 + (uint)sizeof(xfs_dir_leaf_hdr_t);
875 map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1];
876 for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) {
877 if (tablesize > INT_GET(hdr->firstused, ARCH_CONVERT)) {
878 sum += INT_GET(map->size, ARCH_CONVERT);
879 continue;
880 }
881 if (!map->size)
882 continue; /* no space in this map */
883 tmp = entsize;
884 if (INT_GET(map->base, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
885 tmp += (uint)sizeof(xfs_dir_leaf_entry_t);
886 if (INT_GET(map->size, ARCH_CONVERT) >= tmp) {
887 if (!args->justcheck)
888 xfs_dir_leaf_add_work(bp, args, index, i);
889 return 0;
890 }
891 sum += INT_GET(map->size, ARCH_CONVERT);
892 }
893
894 /*
895 * If there are no holes in the address space of the block,
896 * and we don't have enough freespace, then compaction will do us
897 * no good and we should just give up.
898 */
899 if (!hdr->holes && (sum < entsize))
900 return XFS_ERROR(ENOSPC);
901
902 /*
903 * Compact the entries to coalesce free space.
904 * Pass the justcheck flag so the checking pass can return
905 * an error, without changing anything, if it won't fit.
906 */
907 error = xfs_dir_leaf_compact(args->trans, bp,
908 args->total == 0 ?
909 entsize +
910 (uint)sizeof(xfs_dir_leaf_entry_t) : 0,
911 args->justcheck);
912 if (error)
913 return error;
914 /*
915 * After compaction, the block is guaranteed to have only one
916 * free region, in freemap[0]. If it is not big enough, give up.
917 */
918 if (INT_GET(hdr->freemap[0].size, ARCH_CONVERT) <
919 (entsize + (uint)sizeof(xfs_dir_leaf_entry_t)))
920 return XFS_ERROR(ENOSPC);
921
922 if (!args->justcheck)
923 xfs_dir_leaf_add_work(bp, args, index, 0);
924 return 0;
925}
926
927/*
928 * Add a name to a leaf directory structure.
929 */
930STATIC void
931xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index,
932 int mapindex)
933{
934 xfs_dir_leafblock_t *leaf;
935 xfs_dir_leaf_hdr_t *hdr;
936 xfs_dir_leaf_entry_t *entry;
937 xfs_dir_leaf_name_t *namest;
938 xfs_dir_leaf_map_t *map;
939 /* REFERENCED */
940 xfs_mount_t *mp;
941 int tmp, i;
942
943 leaf = bp->data;
944 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
945 hdr = &leaf->hdr;
946 ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE));
947 ASSERT((index >= 0) && (index <= INT_GET(hdr->count, ARCH_CONVERT)));
948
949 /*
950 * Force open some space in the entry array and fill it in.
951 */
952 entry = &leaf->entries[index];
953 if (index < INT_GET(hdr->count, ARCH_CONVERT)) {
954 tmp = INT_GET(hdr->count, ARCH_CONVERT) - index;
955 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
956 memmove(entry + 1, entry, tmp);
957 xfs_da_log_buf(args->trans, bp,
958 XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
959 }
960 INT_MOD(hdr->count, ARCH_CONVERT, +1);
961
962 /*
963 * Allocate space for the new string (at the end of the run).
964 */
965 map = &hdr->freemap[mapindex];
966 mp = args->trans->t_mountp;
967 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
968 ASSERT(INT_GET(map->size, ARCH_CONVERT) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen));
969 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
970 INT_MOD(map->size, ARCH_CONVERT, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)));
971 INT_SET(entry->nameidx, ARCH_CONVERT, INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT));
972 INT_SET(entry->hashval, ARCH_CONVERT, args->hashval);
973 entry->namelen = args->namelen;
974 xfs_da_log_buf(args->trans, bp,
975 XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
976
977 /*
978 * Copy the string and inode number into the new space.
979 */
980 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
981 XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber);
982 memcpy(namest->name, args->name, args->namelen);
983 xfs_da_log_buf(args->trans, bp,
984 XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry)));
985
986 /*
987 * Update the control info for this leaf node
988 */
989 if (INT_GET(entry->nameidx, ARCH_CONVERT) < INT_GET(hdr->firstused, ARCH_CONVERT))
990 INT_COPY(hdr->firstused, entry->nameidx, ARCH_CONVERT);
991 ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
992 tmp = (INT_GET(hdr->count, ARCH_CONVERT)-1) * (uint)sizeof(xfs_dir_leaf_entry_t)
993 + (uint)sizeof(xfs_dir_leaf_hdr_t);
994 map = &hdr->freemap[0];
995 for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
996 if (INT_GET(map->base, ARCH_CONVERT) == tmp) {
997 INT_MOD(map->base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
998 INT_MOD(map->size, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
999 }
1000 }
1001 INT_MOD(hdr->namebytes, ARCH_CONVERT, args->namelen);
1002 xfs_da_log_buf(args->trans, bp,
1003 XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
1004}
1005
1006/*
1007 * Garbage collect a leaf directory block by copying it to a new buffer.
1008 */
1009STATIC int
1010xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave,
1011 int justcheck)
1012{
1013 xfs_dir_leafblock_t *leaf_s, *leaf_d;
1014 xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
1015 xfs_mount_t *mp;
1016 char *tmpbuffer;
1017 char *tmpbuffer2=NULL;
1018 int rval;
1019 int lbsize;
1020
1021 mp = trans->t_mountp;
1022 lbsize = XFS_LBSIZE(mp);
1023 tmpbuffer = kmem_alloc(lbsize, KM_SLEEP);
1024 ASSERT(tmpbuffer != NULL);
1025 memcpy(tmpbuffer, bp->data, lbsize);
1026
1027 /*
1028 * Make a second copy in case xfs_dir_leaf_moveents()
1029 * below destroys the original.
1030 */
1031 if (musthave || justcheck) {
1032 tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP);
1033 memcpy(tmpbuffer2, bp->data, lbsize);
1034 }
1035 memset(bp->data, 0, lbsize);
1036
1037 /*
1038 * Copy basic information
1039 */
1040 leaf_s = (xfs_dir_leafblock_t *)tmpbuffer;
1041 leaf_d = bp->data;
1042 hdr_s = &leaf_s->hdr;
1043 hdr_d = &leaf_d->hdr;
1044 hdr_d->info = hdr_s->info; /* struct copy */
1045 INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize);
1046 if (!hdr_d->firstused)
1047 INT_SET(hdr_d->firstused, ARCH_CONVERT, lbsize - 1);
1048 hdr_d->namebytes = 0;
1049 hdr_d->count = 0;
1050 hdr_d->holes = 0;
1051 INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, sizeof(xfs_dir_leaf_hdr_t));
1052 INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
1053
1054 /*
1055 * Copy all entry's in the same (sorted) order,
1056 * but allocate filenames packed and in sequence.
1057 * This changes the source (leaf_s) as well.
1058 */
1059 xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, (int)INT_GET(hdr_s->count, ARCH_CONVERT), mp);
1060
1061 if (musthave && INT_GET(hdr_d->freemap[0].size, ARCH_CONVERT) < musthave)
1062 rval = XFS_ERROR(ENOSPC);
1063 else
1064 rval = 0;
1065
1066 if (justcheck || rval == ENOSPC) {
1067 ASSERT(tmpbuffer2);
1068 memcpy(bp->data, tmpbuffer2, lbsize);
1069 } else {
1070 xfs_da_log_buf(trans, bp, 0, lbsize - 1);
1071 }
1072
1073 kmem_free(tmpbuffer, lbsize);
1074 if (musthave || justcheck)
1075 kmem_free(tmpbuffer2, lbsize);
1076 return rval;
1077}
1078
1079/*
1080 * Redistribute the directory entries between two leaf nodes,
1081 * taking into account the size of the new entry.
1082 *
1083 * NOTE: if new block is empty, then it will get the upper half of old block.
1084 */
1085STATIC void
1086xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
1087 xfs_da_state_blk_t *blk2)
1088{
1089 xfs_da_state_blk_t *tmp_blk;
1090 xfs_dir_leafblock_t *leaf1, *leaf2;
1091 xfs_dir_leaf_hdr_t *hdr1, *hdr2;
1092 int count, totallen, max, space, swap;
1093
1094 /*
1095 * Set up environment.
1096 */
1097 ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC);
1098 ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC);
1099 leaf1 = blk1->bp->data;
1100 leaf2 = blk2->bp->data;
1101 ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1102 ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1103
1104 /*
1105 * Check ordering of blocks, reverse if it makes things simpler.
1106 */
1107 swap = 0;
1108 if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) {
1109 tmp_blk = blk1;
1110 blk1 = blk2;
1111 blk2 = tmp_blk;
1112 leaf1 = blk1->bp->data;
1113 leaf2 = blk2->bp->data;
1114 swap = 1;
1115 }
1116 hdr1 = &leaf1->hdr;
1117 hdr2 = &leaf2->hdr;
1118
1119 /*
1120 * Examine entries until we reduce the absolute difference in
1121 * byte usage between the two blocks to a minimum. Then get
1122 * the direction to copy and the number of elements to move.
1123 */
1124 state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2,
1125 &count, &totallen);
1126 if (swap)
1127 state->inleaf = !state->inleaf;
1128
1129 /*
1130 * Move any entries required from leaf to leaf:
1131 */
1132 if (count < INT_GET(hdr1->count, ARCH_CONVERT)) {
1133 /*
1134 * Figure the total bytes to be added to the destination leaf.
1135 */
1136 count = INT_GET(hdr1->count, ARCH_CONVERT) - count; /* number entries being moved */
1137 space = INT_GET(hdr1->namebytes, ARCH_CONVERT) - totallen;
1138 space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
1139 space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
1140
1141 /*
1142 * leaf2 is the destination, compact it if it looks tight.
1143 */
1144 max = INT_GET(hdr2->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
1145 max -= INT_GET(hdr2->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1146 if (space > max) {
1147 xfs_dir_leaf_compact(state->args->trans, blk2->bp,
1148 0, 0);
1149 }
1150
1151 /*
1152 * Move high entries from leaf1 to low end of leaf2.
1153 */
1154 xfs_dir_leaf_moveents(leaf1, INT_GET(hdr1->count, ARCH_CONVERT) - count,
1155 leaf2, 0, count, state->mp);
1156
1157 xfs_da_log_buf(state->args->trans, blk1->bp, 0,
1158 state->blocksize-1);
1159 xfs_da_log_buf(state->args->trans, blk2->bp, 0,
1160 state->blocksize-1);
1161
1162 } else if (count > INT_GET(hdr1->count, ARCH_CONVERT)) {
1163 /*
1164 * Figure the total bytes to be added to the destination leaf.
1165 */
1166 count -= INT_GET(hdr1->count, ARCH_CONVERT); /* number entries being moved */
1167 space = totallen - INT_GET(hdr1->namebytes, ARCH_CONVERT);
1168 space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1);
1169 space += count * (uint)sizeof(xfs_dir_leaf_entry_t);
1170
1171 /*
1172 * leaf1 is the destination, compact it if it looks tight.
1173 */
1174 max = INT_GET(hdr1->firstused, ARCH_CONVERT) - (uint)sizeof(xfs_dir_leaf_hdr_t);
1175 max -= INT_GET(hdr1->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1176 if (space > max) {
1177 xfs_dir_leaf_compact(state->args->trans, blk1->bp,
1178 0, 0);
1179 }
1180
1181 /*
1182 * Move low entries from leaf2 to high end of leaf1.
1183 */
1184 xfs_dir_leaf_moveents(leaf2, 0, leaf1, (int)INT_GET(hdr1->count, ARCH_CONVERT),
1185 count, state->mp);
1186
1187 xfs_da_log_buf(state->args->trans, blk1->bp, 0,
1188 state->blocksize-1);
1189 xfs_da_log_buf(state->args->trans, blk2->bp, 0,
1190 state->blocksize-1);
1191 }
1192
1193 /*
1194 * Copy out last hashval in each block for B-tree code.
1195 */
1196 blk1->hashval = INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1197 blk2->hashval = INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1198
1199 /*
1200 * Adjust the expected index for insertion.
1201 * GROT: this doesn't work unless blk2 was originally empty.
1202 */
1203 if (!state->inleaf) {
1204 blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT);
1205 }
1206}
1207
1208/*
1209 * Examine entries until we reduce the absolute difference in
1210 * byte usage between the two blocks to a minimum.
1211 * GROT: Is this really necessary? With other than a 512 byte blocksize,
1212 * GROT: there will always be enough room in either block for a new entry.
1213 * GROT: Do a double-split for this case?
1214 */
1215STATIC int
1216xfs_dir_leaf_figure_balance(xfs_da_state_t *state,
1217 xfs_da_state_blk_t *blk1,
1218 xfs_da_state_blk_t *blk2,
1219 int *countarg, int *namebytesarg)
1220{
1221 xfs_dir_leafblock_t *leaf1, *leaf2;
1222 xfs_dir_leaf_hdr_t *hdr1, *hdr2;
1223 xfs_dir_leaf_entry_t *entry;
1224 int count, max, totallen, half;
1225 int lastdelta, foundit, tmp;
1226
1227 /*
1228 * Set up environment.
1229 */
1230 leaf1 = blk1->bp->data;
1231 leaf2 = blk2->bp->data;
1232 hdr1 = &leaf1->hdr;
1233 hdr2 = &leaf2->hdr;
1234 foundit = 0;
1235 totallen = 0;
1236
1237 /*
1238 * Examine entries until we reduce the absolute difference in
1239 * byte usage between the two blocks to a minimum.
1240 */
1241 max = INT_GET(hdr1->count, ARCH_CONVERT) + INT_GET(hdr2->count, ARCH_CONVERT);
1242 half = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
1243 half += INT_GET(hdr1->namebytes, ARCH_CONVERT) + INT_GET(hdr2->namebytes, ARCH_CONVERT) + state->args->namelen;
1244 half /= 2;
1245 lastdelta = state->blocksize;
1246 entry = &leaf1->entries[0];
1247 for (count = 0; count < max; entry++, count++) {
1248
1249#define XFS_DIR_ABS(A) (((A) < 0) ? -(A) : (A))
1250 /*
1251 * The new entry is in the first block, account for it.
1252 */
1253 if (count == blk1->index) {
1254 tmp = totallen + (uint)sizeof(*entry)
1255 + XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen);
1256 if (XFS_DIR_ABS(half - tmp) > lastdelta)
1257 break;
1258 lastdelta = XFS_DIR_ABS(half - tmp);
1259 totallen = tmp;
1260 foundit = 1;
1261 }
1262
1263 /*
1264 * Wrap around into the second block if necessary.
1265 */
1266 if (count == INT_GET(hdr1->count, ARCH_CONVERT)) {
1267 leaf1 = leaf2;
1268 entry = &leaf1->entries[0];
1269 }
1270
1271 /*
1272 * Figure out if next leaf entry would be too much.
1273 */
1274 tmp = totallen + (uint)sizeof(*entry)
1275 + XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
1276 if (XFS_DIR_ABS(half - tmp) > lastdelta)
1277 break;
1278 lastdelta = XFS_DIR_ABS(half - tmp);
1279 totallen = tmp;
1280#undef XFS_DIR_ABS
1281 }
1282
1283 /*
1284 * Calculate the number of namebytes that will end up in lower block.
1285 * If new entry not in lower block, fix up the count.
1286 */
1287 totallen -=
1288 count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1);
1289 if (foundit) {
1290 totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) +
1291 state->args->namelen;
1292 }
1293
1294 *countarg = count;
1295 *namebytesarg = totallen;
1296 return foundit;
1297}
1298
1299/*========================================================================
1300 * Routines used for shrinking the Btree.
1301 *========================================================================*/
1302
1303/*
1304 * Check a leaf block and its neighbors to see if the block should be
1305 * collapsed into one or the other neighbor. Always keep the block
1306 * with the smaller block number.
1307 * If the current block is over 50% full, don't try to join it, return 0.
1308 * If the block is empty, fill in the state structure and return 2.
1309 * If it can be collapsed, fill in the state structure and return 1.
1310 * If nothing can be done, return 0.
1311 */
1312int
1313xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
1314{
1315 xfs_dir_leafblock_t *leaf;
1316 xfs_da_state_blk_t *blk;
1317 xfs_da_blkinfo_t *info;
1318 int count, bytes, forward, error, retval, i;
1319 xfs_dablk_t blkno;
1320 xfs_dabuf_t *bp;
1321
1322 /*
1323 * Check for the degenerate case of the block being over 50% full.
1324 * If so, it's not worth even looking to see if we might be able
1325 * to coalesce with a sibling.
1326 */
1327 blk = &state->path.blk[ state->path.active-1 ];
1328 info = blk->bp->data;
1329 ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC);
1330 leaf = (xfs_dir_leafblock_t *)info;
1331 count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1332 bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) +
1333 count * (uint)sizeof(xfs_dir_leaf_entry_t) +
1334 count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) +
1335 INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1336 if (bytes > (state->blocksize >> 1)) {
1337 *action = 0; /* blk over 50%, don't try to join */
1338 return 0;
1339 }
1340
1341 /*
1342 * Check for the degenerate case of the block being empty.
1343 * If the block is empty, we'll simply delete it, no need to
1344 * coalesce it with a sibling block. We choose (arbitrarily)
1345 * to merge with the forward block unless it is NULL.
1346 */
1347 if (count == 0) {
1348 /*
1349 * Make altpath point to the block we want to keep and
1350 * path point to the block we want to drop (this one).
1351 */
1352 forward = (info->forw != 0);
1353 memcpy(&state->altpath, &state->path, sizeof(state->path));
1354 error = xfs_da_path_shift(state, &state->altpath, forward,
1355 0, &retval);
1356 if (error)
1357 return error;
1358 if (retval) {
1359 *action = 0;
1360 } else {
1361 *action = 2;
1362 }
1363 return 0;
1364 }
1365
1366 /*
1367 * Examine each sibling block to see if we can coalesce with
1368 * at least 25% free space to spare. We need to figure out
1369 * whether to merge with the forward or the backward block.
1370 * We prefer coalescing with the lower numbered sibling so as
1371 * to shrink a directory over time.
1372 */
1373 forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); /* start with smaller blk num */
1374 for (i = 0; i < 2; forward = !forward, i++) {
1375 if (forward)
1376 blkno = be32_to_cpu(info->forw);
1377 else
1378 blkno = be32_to_cpu(info->back);
1379 if (blkno == 0)
1380 continue;
1381 error = xfs_da_read_buf(state->args->trans, state->args->dp,
1382 blkno, -1, &bp,
1383 XFS_DATA_FORK);
1384 if (error)
1385 return error;
1386 ASSERT(bp != NULL);
1387
1388 leaf = (xfs_dir_leafblock_t *)info;
1389 count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1390 bytes = state->blocksize - (state->blocksize>>2);
1391 bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1392 leaf = bp->data;
1393 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1394 count += INT_GET(leaf->hdr.count, ARCH_CONVERT);
1395 bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1396 bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
1397 bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t);
1398 bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t);
1399 if (bytes >= 0)
1400 break; /* fits with at least 25% to spare */
1401
1402 xfs_da_brelse(state->args->trans, bp);
1403 }
1404 if (i >= 2) {
1405 *action = 0;
1406 return 0;
1407 }
1408 xfs_da_buf_done(bp);
1409
1410 /*
1411 * Make altpath point to the block we want to keep (the lower
1412 * numbered block) and path point to the block we want to drop.
1413 */
1414 memcpy(&state->altpath, &state->path, sizeof(state->path));
1415 if (blkno < blk->blkno) {
1416 error = xfs_da_path_shift(state, &state->altpath, forward,
1417 0, &retval);
1418 } else {
1419 error = xfs_da_path_shift(state, &state->path, forward,
1420 0, &retval);
1421 }
1422 if (error)
1423 return error;
1424 if (retval) {
1425 *action = 0;
1426 } else {
1427 *action = 1;
1428 }
1429 return 0;
1430}
1431
1432/*
1433 * Remove a name from the leaf directory structure.
1434 *
1435 * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
1436 * If two leaves are 37% full, when combined they will leave 25% free.
1437 */
1438int
1439xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index)
1440{
1441 xfs_dir_leafblock_t *leaf;
1442 xfs_dir_leaf_hdr_t *hdr;
1443 xfs_dir_leaf_map_t *map;
1444 xfs_dir_leaf_entry_t *entry;
1445 xfs_dir_leaf_name_t *namest;
1446 int before, after, smallest, entsize;
1447 int tablesize, tmp, i;
1448 xfs_mount_t *mp;
1449
1450 leaf = bp->data;
1451 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1452 hdr = &leaf->hdr;
1453 mp = trans->t_mountp;
1454 ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
1455 ASSERT((index >= 0) && (index < INT_GET(hdr->count, ARCH_CONVERT)));
1456 ASSERT(INT_GET(hdr->firstused, ARCH_CONVERT) >= ((INT_GET(hdr->count, ARCH_CONVERT)*sizeof(*entry))+sizeof(*hdr)));
1457 entry = &leaf->entries[index];
1458 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
1459 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
1460
1461 /*
1462 * Scan through free region table:
1463 * check for adjacency of free'd entry with an existing one,
1464 * find smallest free region in case we need to replace it,
1465 * adjust any map that borders the entry table,
1466 */
1467 tablesize = INT_GET(hdr->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
1468 + (uint)sizeof(xfs_dir_leaf_hdr_t);
1469 map = &hdr->freemap[0];
1470 tmp = INT_GET(map->size, ARCH_CONVERT);
1471 before = after = -1;
1472 smallest = XFS_DIR_LEAF_MAPSIZE - 1;
1473 entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry);
1474 for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) {
1475 ASSERT(INT_GET(map->base, ARCH_CONVERT) < XFS_LBSIZE(mp));
1476 ASSERT(INT_GET(map->size, ARCH_CONVERT) < XFS_LBSIZE(mp));
1477 if (INT_GET(map->base, ARCH_CONVERT) == tablesize) {
1478 INT_MOD(map->base, ARCH_CONVERT, -((uint)sizeof(xfs_dir_leaf_entry_t)));
1479 INT_MOD(map->size, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_entry_t));
1480 }
1481
1482 if ((INT_GET(map->base, ARCH_CONVERT) + INT_GET(map->size, ARCH_CONVERT)) == INT_GET(entry->nameidx, ARCH_CONVERT)) {
1483 before = i;
1484 } else if (INT_GET(map->base, ARCH_CONVERT) == (INT_GET(entry->nameidx, ARCH_CONVERT) + entsize)) {
1485 after = i;
1486 } else if (INT_GET(map->size, ARCH_CONVERT) < tmp) {
1487 tmp = INT_GET(map->size, ARCH_CONVERT);
1488 smallest = i;
1489 }
1490 }
1491
1492 /*
1493 * Coalesce adjacent freemap regions,
1494 * or replace the smallest region.
1495 */
1496 if ((before >= 0) || (after >= 0)) {
1497 if ((before >= 0) && (after >= 0)) {
1498 map = &hdr->freemap[before];
1499 INT_MOD(map->size, ARCH_CONVERT, entsize);
1500 INT_MOD(map->size, ARCH_CONVERT, INT_GET(hdr->freemap[after].size, ARCH_CONVERT));
1501 hdr->freemap[after].base = 0;
1502 hdr->freemap[after].size = 0;
1503 } else if (before >= 0) {
1504 map = &hdr->freemap[before];
1505 INT_MOD(map->size, ARCH_CONVERT, entsize);
1506 } else {
1507 map = &hdr->freemap[after];
1508 INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
1509 INT_MOD(map->size, ARCH_CONVERT, entsize);
1510 }
1511 } else {
1512 /*
1513 * Replace smallest region (if it is smaller than free'd entry)
1514 */
1515 map = &hdr->freemap[smallest];
1516 if (INT_GET(map->size, ARCH_CONVERT) < entsize) {
1517 INT_COPY(map->base, entry->nameidx, ARCH_CONVERT);
1518 INT_SET(map->size, ARCH_CONVERT, entsize);
1519 }
1520 }
1521
1522 /*
1523 * Did we remove the first entry?
1524 */
1525 if (INT_GET(entry->nameidx, ARCH_CONVERT) == INT_GET(hdr->firstused, ARCH_CONVERT))
1526 smallest = 1;
1527 else
1528 smallest = 0;
1529
1530 /*
1531 * Compress the remaining entries and zero out the removed stuff.
1532 */
1533 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1534 memset((char *)namest, 0, entsize);
1535 xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize));
1536
1537 INT_MOD(hdr->namebytes, ARCH_CONVERT, -(entry->namelen));
1538 tmp = (INT_GET(hdr->count, ARCH_CONVERT) - index) * (uint)sizeof(xfs_dir_leaf_entry_t);
1539 memmove(entry, entry + 1, tmp);
1540 INT_MOD(hdr->count, ARCH_CONVERT, -1);
1541 xfs_da_log_buf(trans, bp,
1542 XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry)));
1543 entry = &leaf->entries[INT_GET(hdr->count, ARCH_CONVERT)];
1544 memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t));
1545
1546 /*
1547 * If we removed the first entry, re-find the first used byte
1548 * in the name area. Note that if the entry was the "firstused",
1549 * then we don't have a "hole" in our block resulting from
1550 * removing the name.
1551 */
1552 if (smallest) {
1553 tmp = XFS_LBSIZE(mp);
1554 entry = &leaf->entries[0];
1555 for (i = INT_GET(hdr->count, ARCH_CONVERT)-1; i >= 0; entry++, i--) {
1556 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) >= INT_GET(hdr->firstused, ARCH_CONVERT));
1557 ASSERT(INT_GET(entry->nameidx, ARCH_CONVERT) < XFS_LBSIZE(mp));
1558 if (INT_GET(entry->nameidx, ARCH_CONVERT) < tmp)
1559 tmp = INT_GET(entry->nameidx, ARCH_CONVERT);
1560 }
1561 INT_SET(hdr->firstused, ARCH_CONVERT, tmp);
1562 if (!hdr->firstused)
1563 INT_SET(hdr->firstused, ARCH_CONVERT, tmp - 1);
1564 } else {
1565 hdr->holes = 1; /* mark as needing compaction */
1566 }
1567
1568 xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr)));
1569
1570 /*
1571 * Check if leaf is less than 50% full, caller may want to
1572 * "join" the leaf with a sibling if so.
1573 */
1574 tmp = (uint)sizeof(xfs_dir_leaf_hdr_t);
1575 tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t);
1576 tmp += INT_GET(leaf->hdr.count, ARCH_CONVERT) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
1577 tmp += INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
1578 if (tmp < mp->m_dir_magicpct)
1579 return 1; /* leaf is < 37% full */
1580 return 0;
1581}
1582
1583/*
1584 * Move all the directory entries from drop_leaf into save_leaf.
1585 */
1586void
1587xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
1588 xfs_da_state_blk_t *save_blk)
1589{
1590 xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf;
1591 xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr;
1592 xfs_mount_t *mp;
1593 char *tmpbuffer;
1594
1595 /*
1596 * Set up environment.
1597 */
1598 mp = state->mp;
1599 ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC);
1600 ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC);
1601 drop_leaf = drop_blk->bp->data;
1602 save_leaf = save_blk->bp->data;
1603 ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1604 ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1605 drop_hdr = &drop_leaf->hdr;
1606 save_hdr = &save_leaf->hdr;
1607
1608 /*
1609 * Save last hashval from dying block for later Btree fixup.
1610 */
1611 drop_blk->hashval = INT_GET(drop_leaf->entries[ drop_leaf->hdr.count-1 ].hashval, ARCH_CONVERT);
1612
1613 /*
1614 * Check if we need a temp buffer, or can we do it in place.
1615 * Note that we don't check "leaf" for holes because we will
1616 * always be dropping it, toosmall() decided that for us already.
1617 */
1618 if (save_hdr->holes == 0) {
1619 /*
1620 * dest leaf has no holes, so we add there. May need
1621 * to make some room in the entry array.
1622 */
1623 if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
1624 xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0,
1625 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1626 } else {
1627 xfs_dir_leaf_moveents(drop_leaf, 0,
1628 save_leaf, INT_GET(save_hdr->count, ARCH_CONVERT),
1629 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1630 }
1631 } else {
1632 /*
1633 * Destination has holes, so we make a temporary copy
1634 * of the leaf and add them both to that.
1635 */
1636 tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP);
1637 ASSERT(tmpbuffer != NULL);
1638 memset(tmpbuffer, 0, state->blocksize);
1639 tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer;
1640 tmp_hdr = &tmp_leaf->hdr;
1641 tmp_hdr->info = save_hdr->info; /* struct copy */
1642 tmp_hdr->count = 0;
1643 INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize);
1644 if (!tmp_hdr->firstused)
1645 INT_SET(tmp_hdr->firstused, ARCH_CONVERT, state->blocksize - 1);
1646 tmp_hdr->namebytes = 0;
1647 if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) {
1648 xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0,
1649 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1650 xfs_dir_leaf_moveents(save_leaf, 0,
1651 tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
1652 (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
1653 } else {
1654 xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0,
1655 (int)INT_GET(save_hdr->count, ARCH_CONVERT), mp);
1656 xfs_dir_leaf_moveents(drop_leaf, 0,
1657 tmp_leaf, INT_GET(tmp_leaf->hdr.count, ARCH_CONVERT),
1658 (int)INT_GET(drop_hdr->count, ARCH_CONVERT), mp);
1659 }
1660 memcpy(save_leaf, tmp_leaf, state->blocksize);
1661 kmem_free(tmpbuffer, state->blocksize);
1662 }
1663
1664 xfs_da_log_buf(state->args->trans, save_blk->bp, 0,
1665 state->blocksize - 1);
1666
1667 /*
1668 * Copy out last hashval in each block for B-tree code.
1669 */
1670 save_blk->hashval = INT_GET(save_leaf->entries[ INT_GET(save_leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
1671}
1672
1673/*========================================================================
1674 * Routines used for finding things in the Btree.
1675 *========================================================================*/
1676
1677/*
1678 * Look up a name in a leaf directory structure.
1679 * This is the internal routine, it uses the caller's buffer.
1680 *
1681 * Note that duplicate keys are allowed, but only check within the
1682 * current leaf node. The Btree code must check in adjacent leaf nodes.
1683 *
1684 * Return in *index the index into the entry[] array of either the found
1685 * entry, or where the entry should have been (insert before that entry).
1686 *
1687 * Don't change the args->inumber unless we find the filename.
1688 */
1689int
1690xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index)
1691{
1692 xfs_dir_leafblock_t *leaf;
1693 xfs_dir_leaf_entry_t *entry;
1694 xfs_dir_leaf_name_t *namest;
1695 int probe, span;
1696 xfs_dahash_t hashval;
1697
1698 leaf = bp->data;
1699 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1700 ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) < (XFS_LBSIZE(args->dp->i_mount)/8));
1701
1702 /*
1703 * Binary search. (note: small blocks will skip this loop)
1704 */
1705 hashval = args->hashval;
1706 probe = span = INT_GET(leaf->hdr.count, ARCH_CONVERT) / 2;
1707 for (entry = &leaf->entries[probe]; span > 4;
1708 entry = &leaf->entries[probe]) {
1709 span /= 2;
1710 if (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)
1711 probe += span;
1712 else if (INT_GET(entry->hashval, ARCH_CONVERT) > hashval)
1713 probe -= span;
1714 else
1715 break;
1716 }
1717 ASSERT((probe >= 0) && \
1718 ((!leaf->hdr.count) || (probe < INT_GET(leaf->hdr.count, ARCH_CONVERT))));
1719 ASSERT((span <= 4) || (INT_GET(entry->hashval, ARCH_CONVERT) == hashval));
1720
1721 /*
1722 * Since we may have duplicate hashval's, find the first matching
1723 * hashval in the leaf.
1724 */
1725 while ((probe > 0) && (INT_GET(entry->hashval, ARCH_CONVERT) >= hashval)) {
1726 entry--;
1727 probe--;
1728 }
1729 while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) < hashval)) {
1730 entry++;
1731 probe++;
1732 }
1733 if ((probe == INT_GET(leaf->hdr.count, ARCH_CONVERT)) || (INT_GET(entry->hashval, ARCH_CONVERT) != hashval)) {
1734 *index = probe;
1735 ASSERT(args->oknoent);
1736 return XFS_ERROR(ENOENT);
1737 }
1738
1739 /*
1740 * Duplicate keys may be present, so search all of them for a match.
1741 */
1742 while ((probe < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (INT_GET(entry->hashval, ARCH_CONVERT) == hashval)) {
1743 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, INT_GET(entry->nameidx, ARCH_CONVERT));
1744 if (entry->namelen == args->namelen &&
1745 namest->name[0] == args->name[0] &&
1746 memcmp(args->name, namest->name, args->namelen) == 0) {
1747 XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber);
1748 *index = probe;
1749 return XFS_ERROR(EEXIST);
1750 }
1751 entry++;
1752 probe++;
1753 }
1754 *index = probe;
1755 ASSERT(probe == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent);
1756 return XFS_ERROR(ENOENT);
1757}
1758
1759/*========================================================================
1760 * Utility routines.
1761 *========================================================================*/
1762
1763/*
1764 * Move the indicated entries from one leaf to another.
1765 * NOTE: this routine modifies both source and destination leaves.
1766 */
1767/* ARGSUSED */
1768STATIC void
1769xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s,
1770 xfs_dir_leafblock_t *leaf_d, int start_d,
1771 int count, xfs_mount_t *mp)
1772{
1773 xfs_dir_leaf_hdr_t *hdr_s, *hdr_d;
1774 xfs_dir_leaf_entry_t *entry_s, *entry_d;
1775 int tmp, i;
1776
1777 /*
1778 * Check for nothing to do.
1779 */
1780 if (count == 0)
1781 return;
1782
1783 /*
1784 * Set up environment.
1785 */
1786 ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1787 ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1788 hdr_s = &leaf_s->hdr;
1789 hdr_d = &leaf_d->hdr;
1790 ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) && (INT_GET(hdr_s->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
1791 ASSERT(INT_GET(hdr_s->firstused, ARCH_CONVERT) >=
1792 ((INT_GET(hdr_s->count, ARCH_CONVERT)*sizeof(*entry_s))+sizeof(*hdr_s)));
1793 ASSERT(INT_GET(hdr_d->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8));
1794 ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >=
1795 ((INT_GET(hdr_d->count, ARCH_CONVERT)*sizeof(*entry_d))+sizeof(*hdr_d)));
1796
1797 ASSERT(start_s < INT_GET(hdr_s->count, ARCH_CONVERT));
1798 ASSERT(start_d <= INT_GET(hdr_d->count, ARCH_CONVERT));
1799 ASSERT(count <= INT_GET(hdr_s->count, ARCH_CONVERT));
1800
1801 /*
1802 * Move the entries in the destination leaf up to make a hole?
1803 */
1804 if (start_d < INT_GET(hdr_d->count, ARCH_CONVERT)) {
1805 tmp = INT_GET(hdr_d->count, ARCH_CONVERT) - start_d;
1806 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
1807 entry_s = &leaf_d->entries[start_d];
1808 entry_d = &leaf_d->entries[start_d + count];
1809 memcpy(entry_d, entry_s, tmp);
1810 }
1811
1812 /*
1813 * Copy all entry's in the same (sorted) order,
1814 * but allocate filenames packed and in sequence.
1815 */
1816 entry_s = &leaf_s->entries[start_s];
1817 entry_d = &leaf_d->entries[start_d];
1818 for (i = 0; i < count; entry_s++, entry_d++, i++) {
1819 ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) >= INT_GET(hdr_s->firstused, ARCH_CONVERT));
1820 tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s);
1821 INT_MOD(hdr_d->firstused, ARCH_CONVERT, -(tmp));
1822 entry_d->hashval = entry_s->hashval; /* INT_: direct copy */
1823 INT_COPY(entry_d->nameidx, hdr_d->firstused, ARCH_CONVERT);
1824 entry_d->namelen = entry_s->namelen;
1825 ASSERT(INT_GET(entry_d->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
1826 memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, INT_GET(entry_d->nameidx, ARCH_CONVERT)),
1827 XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)), tmp);
1828 ASSERT(INT_GET(entry_s->nameidx, ARCH_CONVERT) + tmp <= XFS_LBSIZE(mp));
1829 memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, INT_GET(entry_s->nameidx, ARCH_CONVERT)),
1830 0, tmp);
1831 INT_MOD(hdr_s->namebytes, ARCH_CONVERT, -(entry_d->namelen));
1832 INT_MOD(hdr_d->namebytes, ARCH_CONVERT, entry_d->namelen);
1833 INT_MOD(hdr_s->count, ARCH_CONVERT, -1);
1834 INT_MOD(hdr_d->count, ARCH_CONVERT, +1);
1835 tmp = INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t)
1836 + (uint)sizeof(xfs_dir_leaf_hdr_t);
1837 ASSERT(INT_GET(hdr_d->firstused, ARCH_CONVERT) >= tmp);
1838
1839 }
1840
1841 /*
1842 * Zero out the entries we just copied.
1843 */
1844 if (start_s == INT_GET(hdr_s->count, ARCH_CONVERT)) {
1845 tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
1846 entry_s = &leaf_s->entries[start_s];
1847 ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
1848 memset((char *)entry_s, 0, tmp);
1849 } else {
1850 /*
1851 * Move the remaining entries down to fill the hole,
1852 * then zero the entries at the top.
1853 */
1854 tmp = INT_GET(hdr_s->count, ARCH_CONVERT) - count;
1855 tmp *= (uint)sizeof(xfs_dir_leaf_entry_t);
1856 entry_s = &leaf_s->entries[start_s + count];
1857 entry_d = &leaf_s->entries[start_s];
1858 memcpy(entry_d, entry_s, tmp);
1859
1860 tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t);
1861 entry_s = &leaf_s->entries[INT_GET(hdr_s->count, ARCH_CONVERT)];
1862 ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp));
1863 memset((char *)entry_s, 0, tmp);
1864 }
1865
1866 /*
1867 * Fill in the freemap information
1868 */
1869 INT_SET(hdr_d->freemap[0].base, ARCH_CONVERT, (uint)sizeof(xfs_dir_leaf_hdr_t));
1870 INT_MOD(hdr_d->freemap[0].base, ARCH_CONVERT, INT_GET(hdr_d->count, ARCH_CONVERT) * (uint)sizeof(xfs_dir_leaf_entry_t));
1871 INT_SET(hdr_d->freemap[0].size, ARCH_CONVERT, INT_GET(hdr_d->firstused, ARCH_CONVERT) - INT_GET(hdr_d->freemap[0].base, ARCH_CONVERT));
1872 INT_SET(hdr_d->freemap[1].base, ARCH_CONVERT, (hdr_d->freemap[2].base = 0));
1873 INT_SET(hdr_d->freemap[1].size, ARCH_CONVERT, (hdr_d->freemap[2].size = 0));
1874 hdr_s->holes = 1; /* leaf may not be compact */
1875}
1876
1877/*
1878 * Compare two leaf blocks "order".
1879 */
1880int
1881xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp)
1882{
1883 xfs_dir_leafblock_t *leaf1, *leaf2;
1884
1885 leaf1 = leaf1_bp->data;
1886 leaf2 = leaf2_bp->data;
1887 ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) &&
1888 (be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC));
1889 if ((INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) &&
1890 ((INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) <
1891 INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) ||
1892 (INT_GET(leaf2->entries[ INT_GET(leaf2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
1893 INT_GET(leaf1->entries[ INT_GET(leaf1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
1894 return 1;
1895 }
1896 return 0;
1897}
1898
1899/*
1900 * Pick up the last hashvalue from a leaf block.
1901 */
1902xfs_dahash_t
1903xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count)
1904{
1905 xfs_dir_leafblock_t *leaf;
1906
1907 leaf = bp->data;
1908 ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
1909 if (count)
1910 *count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
1911 if (!leaf->hdr.count)
1912 return(0);
1913 return(INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT));
1914}
1915
1916/*
1917 * Copy out directory entries for getdents(), for leaf directories.
1918 */
1919int
1920xfs_dir_leaf_getdents_int(
1921 xfs_dabuf_t *bp,
1922 xfs_inode_t *dp,
1923 xfs_dablk_t bno,
1924 uio_t *uio,
1925 int *eobp,
1926 xfs_dirent_t *dbp,
1927 xfs_dir_put_t put,
1928 xfs_daddr_t nextda)
1929{
1930 xfs_dir_leafblock_t *leaf;
1931 xfs_dir_leaf_entry_t *entry;
1932 xfs_dir_leaf_name_t *namest;
1933 int entno, want_entno, i, nextentno;
1934 xfs_mount_t *mp;
1935 xfs_dahash_t cookhash;
1936 xfs_dahash_t nexthash = 0;
1937#if (BITS_PER_LONG == 32)
1938 xfs_dahash_t lasthash = XFS_DA_MAXHASH;
1939#endif
1940 xfs_dir_put_args_t p;
1941
1942 mp = dp->i_mount;
1943 leaf = bp->data;
1944 if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
1945 *eobp = 1;
1946 return XFS_ERROR(ENOENT); /* XXX wrong code */
1947 }
1948
1949 want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
1950
1951 cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
1952
1953 xfs_dir_trace_g_dul("leaf: start", dp, uio, leaf);
1954
1955 /*
1956 * Re-find our place.
1957 */
1958 for (i = entno = 0, entry = &leaf->entries[0];
1959 i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
1960 entry++, i++) {
1961
1962 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
1963 INT_GET(entry->nameidx, ARCH_CONVERT));
1964
1965 if (unlikely(
1966 ((char *)namest < (char *)leaf) ||
1967 ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
1968 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)",
1969 XFS_ERRLEVEL_LOW, mp, leaf);
1970 xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
1971 return XFS_ERROR(EFSCORRUPTED);
1972 }
1973 if (INT_GET(entry->hashval, ARCH_CONVERT) >= cookhash) {
1974 if ( entno < want_entno
1975 && INT_GET(entry->hashval, ARCH_CONVERT)
1976 == cookhash) {
1977 /*
1978 * Trying to get to a particular offset in a
1979 * run of equal-hashval entries.
1980 */
1981 entno++;
1982 } else if ( want_entno > 0
1983 && entno == want_entno
1984 && INT_GET(entry->hashval, ARCH_CONVERT)
1985 == cookhash) {
1986 break;
1987 } else {
1988 entno = 0;
1989 break;
1990 }
1991 }
1992 }
1993
1994 if (i == INT_GET(leaf->hdr.count, ARCH_CONVERT)) {
1995 xfs_dir_trace_g_du("leaf: hash not found", dp, uio);
1996 if (!leaf->hdr.info.forw)
1997 uio->uio_offset =
1998 XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
1999 /*
2000 * Don't set uio_offset if there's another block:
2001 * the node code will be setting uio_offset anyway.
2002 */
2003 *eobp = 0;
2004 return 0;
2005 }
2006 xfs_dir_trace_g_due("leaf: hash found", dp, uio, entry);
2007
2008 p.dbp = dbp;
2009 p.put = put;
2010 p.uio = uio;
2011
2012 /*
2013 * We're synchronized, start copying entries out to the user.
2014 */
2015 for (; entno >= 0 && i < INT_GET(leaf->hdr.count, ARCH_CONVERT);
2016 entry++, i++, (entno = nextentno)) {
2017 int lastresid=0, retval;
2018 xfs_dircook_t lastoffset;
2019 xfs_dahash_t thishash;
2020
2021 /*
2022 * Check for a damaged directory leaf block and pick up
2023 * the inode number from this entry.
2024 */
2025 namest = XFS_DIR_LEAF_NAMESTRUCT(leaf,
2026 INT_GET(entry->nameidx, ARCH_CONVERT));
2027
2028 if (unlikely(
2029 ((char *)namest < (char *)leaf) ||
2030 ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) {
2031 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)",
2032 XFS_ERRLEVEL_LOW, mp, leaf);
2033 xfs_dir_trace_g_du("leaf: corrupted", dp, uio);
2034 return XFS_ERROR(EFSCORRUPTED);
2035 }
2036
2037 xfs_dir_trace_g_duc("leaf: middle cookie ",
2038 dp, uio, p.cook.o);
2039
2040 if (i < (INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1)) {
2041 nexthash = INT_GET(entry[1].hashval, ARCH_CONVERT);
2042
2043 if (nexthash == INT_GET(entry->hashval, ARCH_CONVERT))
2044 nextentno = entno + 1;
2045 else
2046 nextentno = 0;
2047 XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash);
2048 xfs_dir_trace_g_duc("leaf: middle cookie ",
2049 dp, uio, p.cook.o);
2050
2051 } else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) {
2052 xfs_dabuf_t *bp2;
2053 xfs_dir_leafblock_t *leaf2;
2054
2055 ASSERT(nextda != -1);
2056
2057 retval = xfs_da_read_buf(dp->i_transp, dp, thishash,
2058 nextda, &bp2, XFS_DATA_FORK);
2059 if (retval)
2060 return retval;
2061
2062 ASSERT(bp2 != NULL);
2063
2064 leaf2 = bp2->data;
2065
2066 if (unlikely(
2067 (be16_to_cpu(leaf2->hdr.info.magic)
2068 != XFS_DIR_LEAF_MAGIC)
2069 || (be32_to_cpu(leaf2->hdr.info.back)
2070 != bno))) { /* GROT */
2071 XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)",
2072 XFS_ERRLEVEL_LOW, mp,
2073 leaf2);
2074 xfs_da_brelse(dp->i_transp, bp2);
2075
2076 return XFS_ERROR(EFSCORRUPTED);
2077 }
2078
2079 nexthash = INT_GET(leaf2->entries[0].hashval,
2080 ARCH_CONVERT);
2081 nextentno = -1;
2082 XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash);
2083 xfs_da_brelse(dp->i_transp, bp2);
2084 xfs_dir_trace_g_duc("leaf: next blk cookie",
2085 dp, uio, p.cook.o);
2086 } else {
2087 nextentno = -1;
2088 XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH);
2089 }
2090
2091 /*
2092 * Save off the cookie so we can fall back should the
2093 * 'put' into the outgoing buffer fails. To handle a run
2094 * of equal-hashvals, the off_t structure on 64bit
2095 * builds has entno built into the cookie to ID the
2096 * entry. On 32bit builds, we only have space for the
2097 * hashval so we can't ID specific entries within a group
2098 * of same hashval entries. For this, lastoffset is set
2099 * to the first in the run of equal hashvals so we don't
2100 * include any entries unless we can include all entries
2101 * that share the same hashval. Hopefully the buffer
2102 * provided is big enough to handle it (see pv763517).
2103 */
2104#if (BITS_PER_LONG == 32)
2105 if ((thishash = INT_GET(entry->hashval, ARCH_CONVERT))
2106 != lasthash) {
2107 XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
2108 lastresid = uio->uio_resid;
2109 lasthash = thishash;
2110 } else {
2111 xfs_dir_trace_g_duc("leaf: DUP COOKIES, skipped",
2112 dp, uio, p.cook.o);
2113 }
2114#else
2115 thishash = INT_GET(entry->hashval, ARCH_CONVERT);
2116 XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash);
2117 lastresid = uio->uio_resid;
2118#endif /* BITS_PER_LONG == 32 */
2119
2120 /*
2121 * Put the current entry into the outgoing buffer. If we fail
2122 * then restore the UIO to the first entry in the current
2123 * run of equal-hashval entries (probably one 1 entry long).
2124 */
2125 p.ino = XFS_GET_DIR_INO8(namest->inumber);
2126#if XFS_BIG_INUMS
2127 p.ino += mp->m_inoadd;
2128#endif
2129 p.name = (char *)namest->name;
2130 p.namelen = entry->namelen;
2131
2132 retval = p.put(&p);
2133
2134 if (!p.done) {
2135 uio->uio_offset = lastoffset.o;
2136 uio->uio_resid = lastresid;
2137
2138 *eobp = 1;
2139
2140 xfs_dir_trace_g_du("leaf: E-O-B", dp, uio);
2141
2142 return retval;
2143 }
2144 }
2145
2146 uio->uio_offset = p.cook.o;
2147
2148 *eobp = 0;
2149
2150 xfs_dir_trace_g_du("leaf: E-O-F", dp, uio);
2151
2152 return 0;
2153}
2154
2155/*
2156 * Format a dirent64 structure and copy it out the the user's buffer.
2157 */
2158int
2159xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa)
2160{
2161 iovec_t *iovp;
2162 int reclen, namelen;
2163 xfs_dirent_t *idbp;
2164 uio_t *uio;
2165
2166 namelen = pa->namelen;
2167 reclen = DIRENTSIZE(namelen);
2168 uio = pa->uio;
2169 if (reclen > uio->uio_resid) {
2170 pa->done = 0;
2171 return 0;
2172 }
2173 iovp = uio->uio_iov;
2174 idbp = (xfs_dirent_t *)iovp->iov_base;
2175 iovp->iov_base = (char *)idbp + reclen;
2176 iovp->iov_len -= reclen;
2177 uio->uio_resid -= reclen;
2178 idbp->d_reclen = reclen;
2179 idbp->d_ino = pa->ino;
2180 idbp->d_off = pa->cook.o;
2181 idbp->d_name[namelen] = '\0';
2182 pa->done = 1;
2183 memcpy(idbp->d_name, pa->name, namelen);
2184 return 0;
2185}
2186
2187/*
2188 * Format a dirent64 structure and copy it out the the user's buffer.
2189 */
2190int
2191xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa)
2192{
2193 int retval, reclen, namelen;
2194 xfs_dirent_t *idbp;
2195 uio_t *uio;
2196
2197 namelen = pa->namelen;
2198 reclen = DIRENTSIZE(namelen);
2199 uio = pa->uio;
2200 if (reclen > uio->uio_resid) {
2201 pa->done = 0;
2202 return 0;
2203 }
2204 idbp = pa->dbp;
2205 idbp->d_reclen = reclen;
2206 idbp->d_ino = pa->ino;
2207 idbp->d_off = pa->cook.o;
2208 idbp->d_name[namelen] = '\0';
2209 memcpy(idbp->d_name, pa->name, namelen);
2210 retval = uio_read((caddr_t)idbp, reclen, uio);
2211 pa->done = (retval == 0);
2212 return retval;
2213}
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
deleted file mode 100644
index eb8cd9a4667f..000000000000
--- a/fs/xfs/xfs_dir_leaf.h
+++ /dev/null
@@ -1,231 +0,0 @@
1/*
2 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR_LEAF_H__
19#define __XFS_DIR_LEAF_H__
20
21/*
22 * Directory layout, internal structure, access macros, etc.
23 *
24 * Large directories are structured around Btrees where all the data
25 * elements are in the leaf nodes. Filenames are hashed into an int,
26 * then that int is used as the index into the Btree. Since the hashval
27 * of a filename may not be unique, we may have duplicate keys. The
28 * internal links in the Btree are logical block offsets into the file.
29 */
30
31struct uio;
32struct xfs_bmap_free;
33struct xfs_dabuf;
34struct xfs_da_args;
35struct xfs_da_state;
36struct xfs_da_state_blk;
37struct xfs_dir_put_args;
38struct xfs_inode;
39struct xfs_mount;
40struct xfs_trans;
41
42/*========================================================================
43 * Directory Structure when equal to XFS_LBSIZE(mp) bytes.
44 *========================================================================*/
45
46/*
47 * This is the structure of the leaf nodes in the Btree.
48 *
49 * Struct leaf_entry's are packed from the top. Names grow from the bottom
50 * but are not packed. The freemap contains run-length-encoded entries
51 * for the free bytes after the leaf_entry's, but only the N largest such,
52 * smaller runs are dropped. When the freemap doesn't show enough space
53 * for an allocation, we compact the namelist area and try again. If we
54 * still don't have enough space, then we have to split the block.
55 *
56 * Since we have duplicate hash keys, for each key that matches, compare
57 * the actual string. The root and intermediate node search always takes
58 * the first-in-the-block key match found, so we should only have to work
59 * "forw"ard. If none matches, continue with the "forw"ard leaf nodes
60 * until the hash key changes or the filename is found.
61 *
62 * The parent directory and the self-pointer are explicitly represented
63 * (ie: there are entries for "." and "..").
64 *
65 * Note that the count being a __uint16_t limits us to something like a
66 * blocksize of 1.3MB in the face of worst case (short) filenames.
67 */
68#define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */
69
70typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */
71 __uint16_t base; /* base of free region */
72 __uint16_t size; /* run length of free region */
73} xfs_dir_leaf_map_t;
74
75typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */
76 xfs_da_blkinfo_t info; /* block type, links, etc. */
77 __uint16_t count; /* count of active leaf_entry's */
78 __uint16_t namebytes; /* num bytes of name strings stored */
79 __uint16_t firstused; /* first used byte in name area */
80 __uint8_t holes; /* != 0 if blk needs compaction */
81 __uint8_t pad1;
82 xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE];
83} xfs_dir_leaf_hdr_t;
84
85typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */
86 xfs_dahash_t hashval; /* hash value of name */
87 __uint16_t nameidx; /* index into buffer of name */
88 __uint8_t namelen; /* length of name string */
89 __uint8_t pad2;
90} xfs_dir_leaf_entry_t;
91
92typedef struct xfs_dir_leaf_name {
93 xfs_dir_ino_t inumber; /* inode number for this key */
94 __uint8_t name[1]; /* name string itself */
95} xfs_dir_leaf_name_t;
96
97typedef struct xfs_dir_leafblock {
98 xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */
99 xfs_dir_leaf_entry_t entries[1]; /* var sized array */
100 xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */
101} xfs_dir_leafblock_t;
102
103/*
104 * Length of name for which a 512-byte block filesystem
105 * can get a double split.
106 */
107#define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \
108 (512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \
109 (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \
110 (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1)
111
112typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa);
113
114typedef union {
115 xfs_off_t o; /* offset (cookie) */
116 /*
117 * Watch the order here (endian-ness dependent).
118 */
119 struct {
120#ifndef XFS_NATIVE_HOST
121 xfs_dahash_t h; /* hash value */
122 __uint32_t be; /* block and entry */
123#else
124 __uint32_t be; /* block and entry */
125 xfs_dahash_t h; /* hash value */
126#endif /* XFS_NATIVE_HOST */
127 } s;
128} xfs_dircook_t;
129
130#define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \
131 ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash))
132
133typedef struct xfs_dir_put_args {
134 xfs_dircook_t cook; /* cookie of (next) entry */
135 xfs_intino_t ino; /* inode number */
136 struct xfs_dirent *dbp; /* buffer pointer */
137 char *name; /* directory entry name */
138 int namelen; /* length of name */
139 int done; /* output: set if value was stored */
140 xfs_dir_put_t put; /* put function ptr (i/o) */
141 struct uio *uio; /* uio control structure */
142} xfs_dir_put_args_t;
143
144#define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \
145 xfs_dir_leaf_entsize_byname(len)
146static inline int xfs_dir_leaf_entsize_byname(int len)
147{
148 return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len;
149}
150
151#define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \
152 xfs_dir_leaf_entsize_byentry(entry)
153static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry)
154{
155 return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen;
156}
157
158#define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \
159 xfs_dir_leaf_namestruct(leafp,offset)
160static inline xfs_dir_leaf_name_t *
161xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset)
162{
163 return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset];
164}
165
166/*========================================================================
167 * Function prototypes for the kernel.
168 *========================================================================*/
169
170/*
171 * Internal routines when dirsize < XFS_LITINO(mp).
172 */
173int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent);
174int xfs_dir_shortform_addname(struct xfs_da_args *args);
175int xfs_dir_shortform_lookup(struct xfs_da_args *args);
176int xfs_dir_shortform_to_leaf(struct xfs_da_args *args);
177int xfs_dir_shortform_removename(struct xfs_da_args *args);
178int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp,
179 struct xfs_dirent *dbp, xfs_dir_put_t put);
180int xfs_dir_shortform_replace(struct xfs_da_args *args);
181
182/*
183 * Internal routines when dirsize == XFS_LBSIZE(mp).
184 */
185int xfs_dir_leaf_to_node(struct xfs_da_args *args);
186int xfs_dir_leaf_to_shortform(struct xfs_da_args *args);
187
188/*
189 * Routines used for growing the Btree.
190 */
191int xfs_dir_leaf_split(struct xfs_da_state *state,
192 struct xfs_da_state_blk *oldblk,
193 struct xfs_da_state_blk *newblk);
194int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer,
195 struct xfs_da_args *args, int insertion_index);
196int xfs_dir_leaf_addname(struct xfs_da_args *args);
197int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer,
198 struct xfs_da_args *args,
199 int *index_found_at);
200int xfs_dir_leaf_remove(struct xfs_trans *trans,
201 struct xfs_dabuf *leaf_buffer,
202 int index_to_remove);
203int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp,
204 xfs_dablk_t bno, struct uio *uio,
205 int *eobp, struct xfs_dirent *dbp,
206 xfs_dir_put_t put, xfs_daddr_t nextda);
207
208/*
209 * Routines used for shrinking the Btree.
210 */
211int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval);
212void xfs_dir_leaf_unbalance(struct xfs_da_state *state,
213 struct xfs_da_state_blk *drop_blk,
214 struct xfs_da_state_blk *save_blk);
215
216/*
217 * Utility routines.
218 */
219uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count);
220int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp,
221 struct xfs_dabuf *leaf2_bp);
222int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa);
223int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa);
224int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
225
226/*
227 * Global data.
228 */
229extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot;
230
231#endif /* __XFS_DIR_LEAF_H__ */
diff --git a/fs/xfs/xfs_dir_sf.h b/fs/xfs/xfs_dir_sf.h
deleted file mode 100644
index 5b20b4d3f57d..000000000000
--- a/fs/xfs/xfs_dir_sf.h
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * Copyright (c) 2000,2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18#ifndef __XFS_DIR_SF_H__
19#define __XFS_DIR_SF_H__
20
21/*
22 * Directory layout when stored internal to an inode.
23 *
24 * Small directories are packed as tightly as possible so as to
25 * fit into the literal area of the inode.
26 */
27
28typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t;
29
30/*
31 * The parent directory has a dedicated field, and the self-pointer must
32 * be calculated on the fly.
33 *
34 * Entries are packed toward the top as tight as possible. The header
35 * and the elements much be memcpy'd out into a work area to get correct
36 * alignment for the inode number fields.
37 */
38typedef struct xfs_dir_sf_hdr { /* constant-structure header block */
39 xfs_dir_ino_t parent; /* parent dir inode number */
40 __uint8_t count; /* count of active entries */
41} xfs_dir_sf_hdr_t;
42
43typedef struct xfs_dir_sf_entry {
44 xfs_dir_ino_t inumber; /* referenced inode number */
45 __uint8_t namelen; /* actual length of name (no NULL) */
46 __uint8_t name[1]; /* name */
47} xfs_dir_sf_entry_t;
48
49typedef struct xfs_dir_shortform {
50 xfs_dir_sf_hdr_t hdr;
51 xfs_dir_sf_entry_t list[1]; /* variable sized array */
52} xfs_dir_shortform_t;
53
54/*
55 * We generate this then sort it, so that readdirs are returned in
56 * hash-order. Else seekdir won't work.
57 */
58typedef struct xfs_dir_sf_sort {
59 __uint8_t entno; /* .=0, ..=1, else entry# + 2 */
60 __uint8_t seqno; /* sequence # with same hash value */
61 __uint8_t namelen; /* length of name value (no null) */
62 xfs_dahash_t hash; /* this entry's hash value */
63 xfs_intino_t ino; /* this entry's inode number */
64 char *name; /* name value, pointer into buffer */
65} xfs_dir_sf_sort_t;
66
67#define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to)
68static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to)
69{
70 *(to) = XFS_GET_DIR_INO8(*from);
71}
72
73#define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to)
74static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to)
75{
76 XFS_PUT_DIR_INO8(*(from), *(to));
77}
78
79#define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len)
80static inline int xfs_dir_sf_entsize_byname(int len)
81{
82 return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len);
83}
84
85#define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep)
86static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep)
87{
88 return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen;
89}
90
91#define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep)
92static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep)
93{
94 return (xfs_dir_sf_entry_t *) \
95 ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep));
96}
97
98#define XFS_DIR_SF_ALLFIT(count,totallen) \
99 xfs_dir_sf_allfit(count,totallen)
100static inline int xfs_dir_sf_allfit(int count, int totallen)
101{
102 return ((uint)sizeof(xfs_dir_sf_hdr_t) + \
103 ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen));
104}
105
106#if defined(XFS_DIR_TRACE)
107
108/*
109 * Kernel tracing support for directories.
110 */
111struct uio;
112struct xfs_inode;
113struct xfs_da_intnode;
114struct xfs_dinode;
115struct xfs_dir_leafblock;
116struct xfs_dir_leaf_entry;
117
118#define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */
119extern ktrace_t *xfs_dir_trace_buf;
120
121/*
122 * Trace record types.
123 */
124#define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */
125#define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */
126#define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */
127#define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */
128#define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */
129#define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */
130
131void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio);
132void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio,
133 xfs_dablk_t bno);
134void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio,
135 struct xfs_da_intnode *node);
136void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio,
137 struct xfs_dir_leafblock *leaf);
138void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio,
139 struct xfs_dir_leaf_entry *entry);
140void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio,
141 xfs_off_t cookie);
142void xfs_dir_trace_enter(int type, char *where,
143 void *a0, void *a1, void *a2, void *a3,
144 void *a4, void *a5, void *a6, void *a7,
145 void *a8, void *a9, void *a10, void *a11);
146#else
147#define xfs_dir_trace_g_du(w,d,u)
148#define xfs_dir_trace_g_dub(w,d,u,b)
149#define xfs_dir_trace_g_dun(w,d,u,n)
150#define xfs_dir_trace_g_dul(w,d,u,l)
151#define xfs_dir_trace_g_due(w,d,u,e)
152#define xfs_dir_trace_g_duc(w,d,u,c)
153#endif /* DEBUG */
154
155#endif /* __XFS_DIR_SF_H__ */
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 00b1540f8108..4e7865ad6f0e 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -189,6 +189,6 @@ typedef enum {
189#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0) 189#define AT_DELAY_FLAG(f) ((f&ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
190 190
191 191
192extern struct bhv_vfsops xfs_dmops; 192extern struct bhv_module_vfsops xfs_dmops;
193 193
194#endif /* __XFS_DMAPI_H__ */ 194#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index 629795b3b3d5..1e4a35ddf7f9 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
29#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index 2a21c5024017..b95681b03d81 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -22,12 +22,10 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_bmap_btree.h" 28#include "xfs_bmap_btree.h"
30#include "xfs_dir_sf.h"
31#include "xfs_dir2_sf.h" 29#include "xfs_dir2_sf.h"
32#include "xfs_attr_sf.h" 30#include "xfs_attr_sf.h"
33#include "xfs_dinode.h" 31#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index f19282ec8549..6cf6d8769b97 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_buf_item.h" 24#include "xfs_buf_item.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_dir.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_trans_priv.h" 28#include "xfs_trans_priv.h"
@@ -294,6 +293,62 @@ xfs_efi_init(xfs_mount_t *mp,
294} 293}
295 294
296/* 295/*
296 * Copy an EFI format buffer from the given buf, and into the destination
297 * EFI format structure.
298 * The given buffer can be in 32 bit or 64 bit form (which has different padding),
299 * one of which will be the native format for this kernel.
300 * It will handle the conversion of formats if necessary.
301 */
302int
303xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
304{
305 xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
306 uint i;
307 uint len = sizeof(xfs_efi_log_format_t) +
308 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
309 uint len32 = sizeof(xfs_efi_log_format_32_t) +
310 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_32_t);
311 uint len64 = sizeof(xfs_efi_log_format_64_t) +
312 (src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_64_t);
313
314 if (buf->i_len == len) {
315 memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
316 return 0;
317 } else if (buf->i_len == len32) {
318 xfs_efi_log_format_32_t *src_efi_fmt_32 =
319 (xfs_efi_log_format_32_t *)buf->i_addr;
320
321 dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
322 dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
323 dst_efi_fmt->efi_nextents = src_efi_fmt_32->efi_nextents;
324 dst_efi_fmt->efi_id = src_efi_fmt_32->efi_id;
325 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
326 dst_efi_fmt->efi_extents[i].ext_start =
327 src_efi_fmt_32->efi_extents[i].ext_start;
328 dst_efi_fmt->efi_extents[i].ext_len =
329 src_efi_fmt_32->efi_extents[i].ext_len;
330 }
331 return 0;
332 } else if (buf->i_len == len64) {
333 xfs_efi_log_format_64_t *src_efi_fmt_64 =
334 (xfs_efi_log_format_64_t *)buf->i_addr;
335
336 dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
337 dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
338 dst_efi_fmt->efi_nextents = src_efi_fmt_64->efi_nextents;
339 dst_efi_fmt->efi_id = src_efi_fmt_64->efi_id;
340 for (i = 0; i < dst_efi_fmt->efi_nextents; i++) {
341 dst_efi_fmt->efi_extents[i].ext_start =
342 src_efi_fmt_64->efi_extents[i].ext_start;
343 dst_efi_fmt->efi_extents[i].ext_len =
344 src_efi_fmt_64->efi_extents[i].ext_len;
345 }
346 return 0;
347 }
348 return EFSCORRUPTED;
349}
350
351/*
297 * This is called by the efd item code below to release references to 352 * This is called by the efd item code below to release references to
298 * the given efi item. Each efd calls this with the number of 353 * the given efi item. Each efd calls this with the number of
299 * extents that it has logged, and when the sum of these reaches 354 * extents that it has logged, and when the sum of these reaches
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 5bf681708fec..0ea45edaab03 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -27,6 +27,24 @@ typedef struct xfs_extent {
27} xfs_extent_t; 27} xfs_extent_t;
28 28
29/* 29/*
30 * Since an xfs_extent_t has types (start:64, len: 32)
31 * there are different alignments on 32 bit and 64 bit kernels.
32 * So we provide the different variants for use by a
33 * conversion routine.
34 */
35
36typedef struct xfs_extent_32 {
37 xfs_dfsbno_t ext_start;
38 xfs_extlen_t ext_len;
39} __attribute__((packed)) xfs_extent_32_t;
40
41typedef struct xfs_extent_64 {
42 xfs_dfsbno_t ext_start;
43 xfs_extlen_t ext_len;
44 __uint32_t ext_pad;
45} xfs_extent_64_t;
46
47/*
30 * This is the structure used to lay out an efi log item in the 48 * This is the structure used to lay out an efi log item in the
31 * log. The efi_extents field is a variable size array whose 49 * log. The efi_extents field is a variable size array whose
32 * size is given by efi_nextents. 50 * size is given by efi_nextents.
@@ -39,6 +57,22 @@ typedef struct xfs_efi_log_format {
39 xfs_extent_t efi_extents[1]; /* array of extents to free */ 57 xfs_extent_t efi_extents[1]; /* array of extents to free */
40} xfs_efi_log_format_t; 58} xfs_efi_log_format_t;
41 59
60typedef struct xfs_efi_log_format_32 {
61 unsigned short efi_type; /* efi log item type */
62 unsigned short efi_size; /* size of this item */
63 uint efi_nextents; /* # extents to free */
64 __uint64_t efi_id; /* efi identifier */
65 xfs_extent_32_t efi_extents[1]; /* array of extents to free */
66} __attribute__((packed)) xfs_efi_log_format_32_t;
67
68typedef struct xfs_efi_log_format_64 {
69 unsigned short efi_type; /* efi log item type */
70 unsigned short efi_size; /* size of this item */
71 uint efi_nextents; /* # extents to free */
72 __uint64_t efi_id; /* efi identifier */
73 xfs_extent_64_t efi_extents[1]; /* array of extents to free */
74} xfs_efi_log_format_64_t;
75
42/* 76/*
43 * This is the structure used to lay out an efd log item in the 77 * This is the structure used to lay out an efd log item in the
44 * log. The efd_extents array is a variable size array whose 78 * log. The efd_extents array is a variable size array whose
@@ -52,6 +86,22 @@ typedef struct xfs_efd_log_format {
52 xfs_extent_t efd_extents[1]; /* array of extents freed */ 86 xfs_extent_t efd_extents[1]; /* array of extents freed */
53} xfs_efd_log_format_t; 87} xfs_efd_log_format_t;
54 88
89typedef struct xfs_efd_log_format_32 {
90 unsigned short efd_type; /* efd log item type */
91 unsigned short efd_size; /* size of this item */
92 uint efd_nextents; /* # of extents freed */
93 __uint64_t efd_efi_id; /* id of corresponding efi */
94 xfs_extent_32_t efd_extents[1]; /* array of extents freed */
95} __attribute__((packed)) xfs_efd_log_format_32_t;
96
97typedef struct xfs_efd_log_format_64 {
98 unsigned short efd_type; /* efd log item type */
99 unsigned short efd_size; /* size of this item */
100 uint efd_nextents; /* # of extents freed */
101 __uint64_t efd_efi_id; /* id of corresponding efi */
102 xfs_extent_64_t efd_extents[1]; /* array of extents freed */
103} xfs_efd_log_format_64_t;
104
55 105
56#ifdef __KERNEL__ 106#ifdef __KERNEL__
57 107
@@ -103,7 +153,8 @@ extern struct kmem_zone *xfs_efd_zone;
103xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); 153xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint);
104xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, 154xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
105 uint); 155 uint);
106 156int xfs_efi_copy_format(xfs_log_iovec_t *buf,
157 xfs_efi_log_format_t *dst_efi_fmt);
107void xfs_efi_item_free(xfs_efi_log_item_t *); 158void xfs_efi_item_free(xfs_efi_log_item_t *);
108 159
109#endif /* __KERNEL__ */ 160#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 14010f1fa82f..0f0ad1535951 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -67,14 +67,15 @@ struct fsxattr {
67#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */ 67#define XFS_XFLAG_NOSYMLINKS 0x00000400 /* disallow symlink creation */
68#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ 68#define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */
69#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ 69#define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */
70#define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */
70#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ 71#define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */
71 72
72/* 73/*
73 * Structure for XFS_IOC_GETBMAP. 74 * Structure for XFS_IOC_GETBMAP.
74 * On input, fill in bmv_offset and bmv_length of the first structure 75 * On input, fill in bmv_offset and bmv_length of the first structure
75 * to indicate the area of interest in the file, and bmv_entry with the 76 * to indicate the area of interest in the file, and bmv_entries with
76 * number of array elements given. The first structure is updated on 77 * the number of array elements given back. The first structure is
77 * return to give the offset and length for the next call. 78 * updated on return to give the offset and length for the next call.
78 */ 79 */
79#ifndef HAVE_GETBMAP 80#ifndef HAVE_GETBMAP
80struct getbmap { 81struct getbmap {
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index dfa3527b20a7..077629bab532 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -542,14 +540,13 @@ xfs_reserve_blocks(
542} 540}
543 541
544void 542void
545xfs_fs_log_dummy(xfs_mount_t *mp) 543xfs_fs_log_dummy(
544 xfs_mount_t *mp)
546{ 545{
547 xfs_trans_t *tp; 546 xfs_trans_t *tp;
548 xfs_inode_t *ip; 547 xfs_inode_t *ip;
549
550 548
551 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1); 549 tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
552 atomic_inc(&mp->m_active_trans);
553 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) { 550 if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
554 xfs_trans_cancel(tp, 0); 551 xfs_trans_cancel(tp, 0);
555 return; 552 return;
@@ -574,21 +571,22 @@ xfs_fs_goingdown(
574{ 571{
575 switch (inflags) { 572 switch (inflags) {
576 case XFS_FSOP_GOING_FLAGS_DEFAULT: { 573 case XFS_FSOP_GOING_FLAGS_DEFAULT: {
577 struct vfs *vfsp = XFS_MTOVFS(mp); 574 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
578 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev); 575 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
579 576
580 if (sb && !IS_ERR(sb)) { 577 if (sb && !IS_ERR(sb)) {
581 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); 578 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
582 thaw_bdev(sb->s_bdev, sb); 579 thaw_bdev(sb->s_bdev, sb);
583 } 580 }
584 581
585 break; 582 break;
586 } 583 }
587 case XFS_FSOP_GOING_FLAGS_LOGFLUSH: 584 case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
588 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); 585 xfs_force_shutdown(mp, SHUTDOWN_FORCE_UMOUNT);
589 break; 586 break;
590 case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH: 587 case XFS_FSOP_GOING_FLAGS_NOLOGFLUSH:
591 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT|XFS_LOG_IO_ERROR); 588 xfs_force_shutdown(mp,
589 SHUTDOWN_FORCE_UMOUNT | SHUTDOWN_LOG_IO_ERROR);
592 break; 590 break;
593 default: 591 default:
594 return XFS_ERROR(EINVAL); 592 return XFS_ERROR(EINVAL);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index deddbd03c166..33164a85aa9d 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -1174,6 +1172,9 @@ xfs_dilocate(
1174 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks || 1172 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
1175 ino != XFS_AGINO_TO_INO(mp, agno, agino)) { 1173 ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
1176#ifdef DEBUG 1174#ifdef DEBUG
1175 /* no diagnostics for bulkstat, ino comes from userspace */
1176 if (flags & XFS_IMAP_BULKSTAT)
1177 return XFS_ERROR(EINVAL);
1177 if (agno >= mp->m_sb.sb_agcount) { 1178 if (agno >= mp->m_sb.sb_agcount) {
1178 xfs_fs_cmn_err(CE_ALERT, mp, 1179 xfs_fs_cmn_err(CE_ALERT, mp,
1179 "xfs_dilocate: agno (%d) >= " 1180 "xfs_dilocate: agno (%d) >= "
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 60c65683462d..616eeeb6953e 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index b53854325266..0724df7fabb7 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -186,7 +184,7 @@ xfs_ihash_promote(
186 */ 184 */
187STATIC int 185STATIC int
188xfs_iget_core( 186xfs_iget_core(
189 vnode_t *vp, 187 bhv_vnode_t *vp,
190 xfs_mount_t *mp, 188 xfs_mount_t *mp,
191 xfs_trans_t *tp, 189 xfs_trans_t *tp,
192 xfs_ino_t ino, 190 xfs_ino_t ino,
@@ -198,7 +196,7 @@ xfs_iget_core(
198 xfs_ihash_t *ih; 196 xfs_ihash_t *ih;
199 xfs_inode_t *ip; 197 xfs_inode_t *ip;
200 xfs_inode_t *iq; 198 xfs_inode_t *iq;
201 vnode_t *inode_vp; 199 bhv_vnode_t *inode_vp;
202 ulong version; 200 ulong version;
203 int error; 201 int error;
204 /* REFERENCED */ 202 /* REFERENCED */
@@ -468,7 +466,7 @@ finish_inode:
468 * If we have a real type for an on-disk inode, we can set ops(&unlock) 466 * If we have a real type for an on-disk inode, we can set ops(&unlock)
469 * now. If it's a new inode being created, xfs_ialloc will handle it. 467 * now. If it's a new inode being created, xfs_ialloc will handle it.
470 */ 468 */
471 VFS_INIT_VNODE(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1); 469 bhv_vfs_init_vnode(XFS_MTOVFS(mp), vp, XFS_ITOBHV(ip), 1);
472 470
473 return 0; 471 return 0;
474} 472}
@@ -489,7 +487,7 @@ xfs_iget(
489 xfs_daddr_t bno) 487 xfs_daddr_t bno)
490{ 488{
491 struct inode *inode; 489 struct inode *inode;
492 vnode_t *vp = NULL; 490 bhv_vnode_t *vp = NULL;
493 int error; 491 int error;
494 492
495 XFS_STATS_INC(xs_ig_attempts); 493 XFS_STATS_INC(xs_ig_attempts);
@@ -543,7 +541,7 @@ retry:
543void 541void
544xfs_inode_lock_init( 542xfs_inode_lock_init(
545 xfs_inode_t *ip, 543 xfs_inode_t *ip,
546 vnode_t *vp) 544 bhv_vnode_t *vp)
547{ 545{
548 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, 546 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
549 "xfsino", (long)vp->v_number); 547 "xfsino", (long)vp->v_number);
@@ -603,12 +601,10 @@ void
603xfs_iput(xfs_inode_t *ip, 601xfs_iput(xfs_inode_t *ip,
604 uint lock_flags) 602 uint lock_flags)
605{ 603{
606 vnode_t *vp = XFS_ITOV(ip); 604 bhv_vnode_t *vp = XFS_ITOV(ip);
607 605
608 vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address); 606 vn_trace_entry(vp, "xfs_iput", (inst_t *)__return_address);
609
610 xfs_iunlock(ip, lock_flags); 607 xfs_iunlock(ip, lock_flags);
611
612 VN_RELE(vp); 608 VN_RELE(vp);
613} 609}
614 610
@@ -619,7 +615,7 @@ void
619xfs_iput_new(xfs_inode_t *ip, 615xfs_iput_new(xfs_inode_t *ip,
620 uint lock_flags) 616 uint lock_flags)
621{ 617{
622 vnode_t *vp = XFS_ITOV(ip); 618 bhv_vnode_t *vp = XFS_ITOV(ip);
623 struct inode *inode = vn_to_inode(vp); 619 struct inode *inode = vn_to_inode(vp);
624 620
625 vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); 621 vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
@@ -645,7 +641,7 @@ xfs_iput_new(xfs_inode_t *ip,
645void 641void
646xfs_ireclaim(xfs_inode_t *ip) 642xfs_ireclaim(xfs_inode_t *ip)
647{ 643{
648 vnode_t *vp; 644 bhv_vnode_t *vp;
649 645
650 /* 646 /*
651 * Remove from old hash list and mount list. 647 * Remove from old hash list and mount list.
@@ -1033,6 +1029,6 @@ xfs_iflock_nowait(xfs_inode_t *ip)
1033void 1029void
1034xfs_ifunlock(xfs_inode_t *ip) 1030xfs_ifunlock(xfs_inode_t *ip)
1035{ 1031{
1036 ASSERT(valusema(&(ip->i_flock)) <= 0); 1032 ASSERT(issemalocked(&(ip->i_flock)));
1037 vsema(&(ip->i_flock)); 1033 vsema(&(ip->i_flock));
1038} 1034}
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 94b60dd03801..5fa0adb7e173 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -26,14 +26,12 @@
26#include "xfs_trans_priv.h" 26#include "xfs_trans_priv.h"
27#include "xfs_sb.h" 27#include "xfs_sb.h"
28#include "xfs_ag.h" 28#include "xfs_ag.h"
29#include "xfs_dir.h"
30#include "xfs_dir2.h" 29#include "xfs_dir2.h"
31#include "xfs_dmapi.h" 30#include "xfs_dmapi.h"
32#include "xfs_mount.h" 31#include "xfs_mount.h"
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -256,13 +254,11 @@ xfs_itobp(
256 xfs_daddr_t bno, 254 xfs_daddr_t bno,
257 uint imap_flags) 255 uint imap_flags)
258{ 256{
257 xfs_imap_t imap;
259 xfs_buf_t *bp; 258 xfs_buf_t *bp;
260 int error; 259 int error;
261 xfs_imap_t imap;
262#ifdef __KERNEL__
263 int i; 260 int i;
264 int ni; 261 int ni;
265#endif
266 262
267 if (ip->i_blkno == (xfs_daddr_t)0) { 263 if (ip->i_blkno == (xfs_daddr_t)0) {
268 /* 264 /*
@@ -319,7 +315,6 @@ xfs_itobp(
319 */ 315 */
320 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno, 316 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap.im_blkno,
321 (int)imap.im_len, XFS_BUF_LOCK, &bp); 317 (int)imap.im_len, XFS_BUF_LOCK, &bp);
322
323 if (error) { 318 if (error) {
324#ifdef DEBUG 319#ifdef DEBUG
325 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: " 320 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_itobp: "
@@ -330,17 +325,21 @@ xfs_itobp(
330#endif /* DEBUG */ 325#endif /* DEBUG */
331 return error; 326 return error;
332 } 327 }
333#ifdef __KERNEL__ 328
334 /* 329 /*
335 * Validate the magic number and version of every inode in the buffer 330 * Validate the magic number and version of every inode in the buffer
336 * (if DEBUG kernel) or the first inode in the buffer, otherwise. 331 * (if DEBUG kernel) or the first inode in the buffer, otherwise.
332 * No validation is done here in userspace (xfs_repair).
337 */ 333 */
338#ifdef DEBUG 334#if !defined(__KERNEL__)
335 ni = 0;
336#elif defined(DEBUG)
339 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 337 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 :
340 (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog); 338 (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog);
341#else 339#else /* usual case */
342 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1; 340 ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1;
343#endif 341#endif
342
344 for (i = 0; i < ni; i++) { 343 for (i = 0; i < ni; i++) {
345 int di_ok; 344 int di_ok;
346 xfs_dinode_t *dip; 345 xfs_dinode_t *dip;
@@ -352,8 +351,11 @@ xfs_itobp(
352 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, 351 if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP,
353 XFS_RANDOM_ITOBP_INOTOBP))) { 352 XFS_RANDOM_ITOBP_INOTOBP))) {
354#ifdef DEBUG 353#ifdef DEBUG
355 prdev("bad inode magic/vsn daddr %lld #%d (magic=%x)", 354 if (!(imap_flags & XFS_IMAP_BULKSTAT))
356 mp->m_ddev_targp, 355 cmn_err(CE_ALERT,
356 "Device %s - bad inode magic/vsn "
357 "daddr %lld #%d (magic=%x)",
358 XFS_BUFTARG_NAME(mp->m_ddev_targp),
357 (unsigned long long)imap.im_blkno, i, 359 (unsigned long long)imap.im_blkno, i,
358 INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); 360 INT_GET(dip->di_core.di_magic, ARCH_CONVERT));
359#endif 361#endif
@@ -363,7 +365,6 @@ xfs_itobp(
363 return XFS_ERROR(EFSCORRUPTED); 365 return XFS_ERROR(EFSCORRUPTED);
364 } 366 }
365 } 367 }
366#endif /* __KERNEL__ */
367 368
368 xfs_inobp_check(mp, bp); 369 xfs_inobp_check(mp, bp);
369 370
@@ -782,7 +783,6 @@ xfs_xlate_dinode_core(
782 783
783STATIC uint 784STATIC uint
784_xfs_dic2xflags( 785_xfs_dic2xflags(
785 xfs_dinode_core_t *dic,
786 __uint16_t di_flags) 786 __uint16_t di_flags)
787{ 787{
788 uint flags = 0; 788 uint flags = 0;
@@ -812,6 +812,8 @@ _xfs_dic2xflags(
812 flags |= XFS_XFLAG_EXTSIZE; 812 flags |= XFS_XFLAG_EXTSIZE;
813 if (di_flags & XFS_DIFLAG_EXTSZINHERIT) 813 if (di_flags & XFS_DIFLAG_EXTSZINHERIT)
814 flags |= XFS_XFLAG_EXTSZINHERIT; 814 flags |= XFS_XFLAG_EXTSZINHERIT;
815 if (di_flags & XFS_DIFLAG_NODEFRAG)
816 flags |= XFS_XFLAG_NODEFRAG;
815 } 817 }
816 818
817 return flags; 819 return flags;
@@ -823,16 +825,16 @@ xfs_ip2xflags(
823{ 825{
824 xfs_dinode_core_t *dic = &ip->i_d; 826 xfs_dinode_core_t *dic = &ip->i_d;
825 827
826 return _xfs_dic2xflags(dic, dic->di_flags) | 828 return _xfs_dic2xflags(dic->di_flags) |
827 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); 829 (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0);
828} 830}
829 831
830uint 832uint
831xfs_dic2xflags( 833xfs_dic2xflags(
832 xfs_dinode_core_t *dic) 834 xfs_dinode_core_t *dic)
833{ 835{
834 return _xfs_dic2xflags(dic, INT_GET(dic->di_flags, ARCH_CONVERT)) | 836 return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) |
835 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); 837 (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0);
836} 838}
837 839
838/* 840/*
@@ -1083,7 +1085,7 @@ xfs_ialloc(
1083{ 1085{
1084 xfs_ino_t ino; 1086 xfs_ino_t ino;
1085 xfs_inode_t *ip; 1087 xfs_inode_t *ip;
1086 vnode_t *vp; 1088 bhv_vnode_t *vp;
1087 uint flags; 1089 uint flags;
1088 int error; 1090 int error;
1089 1091
@@ -1221,6 +1223,9 @@ xfs_ialloc(
1221 di_flags |= XFS_DIFLAG_NOSYMLINKS; 1223 di_flags |= XFS_DIFLAG_NOSYMLINKS;
1222 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) 1224 if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
1223 di_flags |= XFS_DIFLAG_PROJINHERIT; 1225 di_flags |= XFS_DIFLAG_PROJINHERIT;
1226 if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) &&
1227 xfs_inherit_nodefrag)
1228 di_flags |= XFS_DIFLAG_NODEFRAG;
1224 ip->i_d.di_flags |= di_flags; 1229 ip->i_d.di_flags |= di_flags;
1225 } 1230 }
1226 /* FALLTHROUGH */ 1231 /* FALLTHROUGH */
@@ -1244,8 +1249,8 @@ xfs_ialloc(
1244 */ 1249 */
1245 xfs_trans_log_inode(tp, ip, flags); 1250 xfs_trans_log_inode(tp, ip, flags);
1246 1251
1247 /* now that we have an i_mode we can set Linux inode ops (& unlock) */ 1252 /* now that we have an i_mode we can setup inode ops and unlock */
1248 VFS_INIT_VNODE(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); 1253 bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1);
1249 1254
1250 *ipp = ip; 1255 *ipp = ip;
1251 return 0; 1256 return 0;
@@ -1285,7 +1290,7 @@ xfs_isize_check(
1285 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) - 1290 (xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
1286 map_first), 1291 map_first),
1287 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps, 1292 XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
1288 NULL)) 1293 NULL, NULL))
1289 return; 1294 return;
1290 ASSERT(nimaps == 1); 1295 ASSERT(nimaps == 1);
1291 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK); 1296 ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
@@ -1421,7 +1426,7 @@ xfs_itruncate_start(
1421 xfs_fsize_t last_byte; 1426 xfs_fsize_t last_byte;
1422 xfs_off_t toss_start; 1427 xfs_off_t toss_start;
1423 xfs_mount_t *mp; 1428 xfs_mount_t *mp;
1424 vnode_t *vp; 1429 bhv_vnode_t *vp;
1425 1430
1426 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0); 1431 ASSERT(ismrlocked(&ip->i_iolock, MR_UPDATE) != 0);
1427 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size)); 1432 ASSERT((new_size == 0) || (new_size <= ip->i_d.di_size));
@@ -1434,9 +1439,9 @@ xfs_itruncate_start(
1434 vn_iowait(vp); /* wait for the completion of any pending DIOs */ 1439 vn_iowait(vp); /* wait for the completion of any pending DIOs */
1435 1440
1436 /* 1441 /*
1437 * Call VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES() to get rid of pages and buffers 1442 * Call toss_pages or flushinval_pages to get rid of pages
1438 * overlapping the region being removed. We have to use 1443 * overlapping the region being removed. We have to use
1439 * the less efficient VOP_FLUSHINVAL_PAGES() in the case that the 1444 * the less efficient flushinval_pages in the case that the
1440 * caller may not be able to finish the truncate without 1445 * caller may not be able to finish the truncate without
1441 * dropping the inode's I/O lock. Make sure 1446 * dropping the inode's I/O lock. Make sure
1442 * to catch any pages brought in by buffers overlapping 1447 * to catch any pages brought in by buffers overlapping
@@ -1445,10 +1450,10 @@ xfs_itruncate_start(
1445 * so that we don't toss things on the same block as 1450 * so that we don't toss things on the same block as
1446 * new_size but before it. 1451 * new_size but before it.
1447 * 1452 *
1448 * Before calling VOP_TOSS_PAGES() or VOP_FLUSHINVAL_PAGES(), make sure to 1453 * Before calling toss_page or flushinval_pages, make sure to
1449 * call remapf() over the same region if the file is mapped. 1454 * call remapf() over the same region if the file is mapped.
1450 * This frees up mapped file references to the pages in the 1455 * This frees up mapped file references to the pages in the
1451 * given range and for the VOP_FLUSHINVAL_PAGES() case it ensures 1456 * given range and for the flushinval_pages case it ensures
1452 * that we get the latest mapped changes flushed out. 1457 * that we get the latest mapped changes flushed out.
1453 */ 1458 */
1454 toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); 1459 toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size);
@@ -1466,9 +1471,9 @@ xfs_itruncate_start(
1466 last_byte); 1471 last_byte);
1467 if (last_byte > toss_start) { 1472 if (last_byte > toss_start) {
1468 if (flags & XFS_ITRUNC_DEFINITE) { 1473 if (flags & XFS_ITRUNC_DEFINITE) {
1469 VOP_TOSS_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); 1474 bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1470 } else { 1475 } else {
1471 VOP_FLUSHINVAL_PAGES(vp, toss_start, -1, FI_REMAPF_LOCKED); 1476 bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED);
1472 } 1477 }
1473 } 1478 }
1474 1479
@@ -1666,12 +1671,13 @@ xfs_itruncate_finish(
1666 * runs. 1671 * runs.
1667 */ 1672 */
1668 XFS_BMAP_INIT(&free_list, &first_block); 1673 XFS_BMAP_INIT(&free_list, &first_block);
1669 error = xfs_bunmapi(ntp, ip, first_unmap_block, 1674 error = XFS_BUNMAPI(mp, ntp, &ip->i_iocore,
1670 unmap_len, 1675 first_unmap_block, unmap_len,
1671 XFS_BMAPI_AFLAG(fork) | 1676 XFS_BMAPI_AFLAG(fork) |
1672 (sync ? 0 : XFS_BMAPI_ASYNC), 1677 (sync ? 0 : XFS_BMAPI_ASYNC),
1673 XFS_ITRUNC_MAX_EXTENTS, 1678 XFS_ITRUNC_MAX_EXTENTS,
1674 &first_block, &free_list, &done); 1679 &first_block, &free_list,
1680 NULL, &done);
1675 if (error) { 1681 if (error) {
1676 /* 1682 /*
1677 * If the bunmapi call encounters an error, 1683 * If the bunmapi call encounters an error,
@@ -2745,13 +2751,14 @@ xfs_iunpin(
2745 * the inode to become unpinned. 2751 * the inode to become unpinned.
2746 */ 2752 */
2747 if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { 2753 if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
2748 vnode_t *vp = XFS_ITOV_NULL(ip); 2754 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
2749 2755
2750 /* make sync come back and flush this inode */ 2756 /* make sync come back and flush this inode */
2751 if (vp) { 2757 if (vp) {
2752 struct inode *inode = vn_to_inode(vp); 2758 struct inode *inode = vn_to_inode(vp);
2753 2759
2754 if (!(inode->i_state & I_NEW)) 2760 if (!(inode->i_state &
2761 (I_NEW|I_FREEING|I_CLEAR)))
2755 mark_inode_dirty_sync(inode); 2762 mark_inode_dirty_sync(inode);
2756 } 2763 }
2757 } 2764 }
@@ -2916,13 +2923,6 @@ xfs_iflush_fork(
2916 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); 2923 ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
2917 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); 2924 memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
2918 } 2925 }
2919 if (whichfork == XFS_DATA_FORK) {
2920 if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) {
2921 XFS_ERROR_REPORT("xfs_iflush_fork",
2922 XFS_ERRLEVEL_LOW, mp);
2923 return XFS_ERROR(EFSCORRUPTED);
2924 }
2925 }
2926 break; 2926 break;
2927 2927
2928 case XFS_DINODE_FMT_EXTENTS: 2928 case XFS_DINODE_FMT_EXTENTS:
@@ -3006,7 +3006,7 @@ xfs_iflush(
3006 XFS_STATS_INC(xs_iflush_count); 3006 XFS_STATS_INC(xs_iflush_count);
3007 3007
3008 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); 3008 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
3009 ASSERT(valusema(&ip->i_flock) <= 0); 3009 ASSERT(issemalocked(&(ip->i_flock)));
3010 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3010 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3011 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3011 ip->i_d.di_nextents > ip->i_df.if_ext_max);
3012 3012
@@ -3199,7 +3199,7 @@ xfs_iflush(
3199 3199
3200corrupt_out: 3200corrupt_out:
3201 xfs_buf_relse(bp); 3201 xfs_buf_relse(bp);
3202 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 3202 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3203 xfs_iflush_abort(ip); 3203 xfs_iflush_abort(ip);
3204 /* 3204 /*
3205 * Unlocks the flush lock 3205 * Unlocks the flush lock
@@ -3221,7 +3221,7 @@ cluster_corrupt_out:
3221 xfs_buf_relse(bp); 3221 xfs_buf_relse(bp);
3222 } 3222 }
3223 3223
3224 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 3224 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
3225 3225
3226 if(!bufwasdelwri) { 3226 if(!bufwasdelwri) {
3227 /* 3227 /*
@@ -3264,7 +3264,7 @@ xfs_iflush_int(
3264 SPLDECL(s); 3264 SPLDECL(s);
3265 3265
3266 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS)); 3266 ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE|MR_ACCESS));
3267 ASSERT(valusema(&ip->i_flock) <= 0); 3267 ASSERT(issemalocked(&(ip->i_flock)));
3268 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || 3268 ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
3269 ip->i_d.di_nextents > ip->i_df.if_ext_max); 3269 ip->i_d.di_nextents > ip->i_df.if_ext_max);
3270 3270
@@ -3504,7 +3504,7 @@ xfs_iflush_all(
3504 xfs_mount_t *mp) 3504 xfs_mount_t *mp)
3505{ 3505{
3506 xfs_inode_t *ip; 3506 xfs_inode_t *ip;
3507 vnode_t *vp; 3507 bhv_vnode_t *vp;
3508 3508
3509 again: 3509 again:
3510 XFS_MOUNT_ILOCK(mp); 3510 XFS_MOUNT_ILOCK(mp);
@@ -4180,7 +4180,7 @@ xfs_iext_direct_to_inline(
4180 */ 4180 */
4181 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, 4181 memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
4182 nextents * sizeof(xfs_bmbt_rec_t)); 4182 nextents * sizeof(xfs_bmbt_rec_t));
4183 kmem_free(ifp->if_u1.if_extents, KM_SLEEP); 4183 kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
4184 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; 4184 ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
4185 ifp->if_real_bytes = 0; 4185 ifp->if_real_bytes = 0;
4186} 4186}
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 3b544db1790b..d10b76ed1e5b 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -102,9 +102,9 @@ typedef struct xfs_ifork {
102 102
103#ifdef __KERNEL__ 103#ifdef __KERNEL__
104struct bhv_desc; 104struct bhv_desc;
105struct bhv_vnode;
105struct cred; 106struct cred;
106struct ktrace; 107struct ktrace;
107struct vnode;
108struct xfs_buf; 108struct xfs_buf;
109struct xfs_bmap_free; 109struct xfs_bmap_free;
110struct xfs_bmbt_irec; 110struct xfs_bmbt_irec;
@@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *);
400void xfs_chash_free(struct xfs_mount *); 400void xfs_chash_free(struct xfs_mount *);
401xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, 401xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
402 struct xfs_trans *); 402 struct xfs_trans *);
403void xfs_inode_lock_init(xfs_inode_t *, struct vnode *); 403void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *);
404int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 404int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
405 uint, uint, xfs_inode_t **, xfs_daddr_t); 405 uint, uint, xfs_inode_t **, xfs_daddr_t);
406void xfs_iput(xfs_inode_t *, uint); 406void xfs_iput(xfs_inode_t *, uint);
@@ -461,7 +461,7 @@ void xfs_ichgtime(xfs_inode_t *, int);
461xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); 461xfs_fsize_t xfs_file_last_byte(xfs_inode_t *);
462void xfs_lock_inodes(xfs_inode_t **, int, int, uint); 462void xfs_lock_inodes(xfs_inode_t **, int, int, uint);
463 463
464xfs_inode_t *xfs_vtoi(struct vnode *vp); 464xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp);
465 465
466void xfs_synchronize_atime(xfs_inode_t *); 466void xfs_synchronize_atime(xfs_inode_t *);
467 467
@@ -509,7 +509,6 @@ extern struct kmem_zone *xfs_chashlist_zone;
509extern struct kmem_zone *xfs_ifork_zone; 509extern struct kmem_zone *xfs_ifork_zone;
510extern struct kmem_zone *xfs_inode_zone; 510extern struct kmem_zone *xfs_inode_zone;
511extern struct kmem_zone *xfs_ili_zone; 511extern struct kmem_zone *xfs_ili_zone;
512extern struct vnodeops xfs_vnodeops;
513 512
514#endif /* __KERNEL__ */ 513#endif /* __KERNEL__ */
515 514
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 7497a481b2f5..f8e80d8e7237 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -25,7 +25,6 @@
25#include "xfs_buf_item.h" 25#include "xfs_buf_item.h"
26#include "xfs_sb.h" 26#include "xfs_sb.h"
27#include "xfs_ag.h" 27#include "xfs_ag.h"
28#include "xfs_dir.h"
29#include "xfs_dir2.h" 28#include "xfs_dir2.h"
30#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
31#include "xfs_mount.h" 30#include "xfs_mount.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -794,7 +792,7 @@ xfs_inode_item_pushbuf(
794 * inode flush completed and the inode was taken off the AIL. 792 * inode flush completed and the inode was taken off the AIL.
795 * So, just get out. 793 * So, just get out.
796 */ 794 */
797 if ((valusema(&(ip->i_flock)) > 0) || 795 if (!issemalocked(&(ip->i_flock)) ||
798 ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) { 796 ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
799 iip->ili_pushbuf_flag = 0; 797 iip->ili_pushbuf_flag = 0;
800 xfs_iunlock(ip, XFS_ILOCK_SHARED); 798 xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -816,7 +814,7 @@ xfs_inode_item_pushbuf(
816 * If not, we can flush it async. 814 * If not, we can flush it async.
817 */ 815 */
818 dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) && 816 dopush = ((iip->ili_item.li_flags & XFS_LI_IN_AIL) &&
819 (valusema(&(ip->i_flock)) <= 0)); 817 issemalocked(&(ip->i_flock)));
820 iip->ili_pushbuf_flag = 0; 818 iip->ili_pushbuf_flag = 0;
821 xfs_iunlock(ip, XFS_ILOCK_SHARED); 819 xfs_iunlock(ip, XFS_ILOCK_SHARED);
822 xfs_buftrace("INODE ITEM PUSH", bp); 820 xfs_buftrace("INODE ITEM PUSH", bp);
@@ -864,7 +862,7 @@ xfs_inode_item_push(
864 ip = iip->ili_inode; 862 ip = iip->ili_inode;
865 863
866 ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS)); 864 ASSERT(ismrlocked(&(ip->i_lock), MR_ACCESS));
867 ASSERT(valusema(&(ip->i_flock)) <= 0); 865 ASSERT(issemalocked(&(ip->i_flock)));
868 /* 866 /*
869 * Since we were able to lock the inode's flush lock and 867 * Since we were able to lock the inode's flush lock and
870 * we found it on the AIL, the inode must be dirty. This 868 * we found it on the AIL, the inode must be dirty. This
@@ -1084,3 +1082,52 @@ xfs_istale_done(
1084{ 1082{
1085 xfs_iflush_abort(iip->ili_inode); 1083 xfs_iflush_abort(iip->ili_inode);
1086} 1084}
1085
1086/*
1087 * convert an xfs_inode_log_format struct from either 32 or 64 bit versions
1088 * (which can have different field alignments) to the native version
1089 */
1090int
1091xfs_inode_item_format_convert(
1092 xfs_log_iovec_t *buf,
1093 xfs_inode_log_format_t *in_f)
1094{
1095 if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
1096 xfs_inode_log_format_32_t *in_f32;
1097
1098 in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr;
1099 in_f->ilf_type = in_f32->ilf_type;
1100 in_f->ilf_size = in_f32->ilf_size;
1101 in_f->ilf_fields = in_f32->ilf_fields;
1102 in_f->ilf_asize = in_f32->ilf_asize;
1103 in_f->ilf_dsize = in_f32->ilf_dsize;
1104 in_f->ilf_ino = in_f32->ilf_ino;
1105 /* copy biggest field of ilf_u */
1106 memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
1107 in_f32->ilf_u.ilfu_uuid.__u_bits,
1108 sizeof(uuid_t));
1109 in_f->ilf_blkno = in_f32->ilf_blkno;
1110 in_f->ilf_len = in_f32->ilf_len;
1111 in_f->ilf_boffset = in_f32->ilf_boffset;
1112 return 0;
1113 } else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
1114 xfs_inode_log_format_64_t *in_f64;
1115
1116 in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr;
1117 in_f->ilf_type = in_f64->ilf_type;
1118 in_f->ilf_size = in_f64->ilf_size;
1119 in_f->ilf_fields = in_f64->ilf_fields;
1120 in_f->ilf_asize = in_f64->ilf_asize;
1121 in_f->ilf_dsize = in_f64->ilf_dsize;
1122 in_f->ilf_ino = in_f64->ilf_ino;
1123 /* copy biggest field of ilf_u */
1124 memcpy(in_f->ilf_u.ilfu_uuid.__u_bits,
1125 in_f64->ilf_u.ilfu_uuid.__u_bits,
1126 sizeof(uuid_t));
1127 in_f->ilf_blkno = in_f64->ilf_blkno;
1128 in_f->ilf_len = in_f64->ilf_len;
1129 in_f->ilf_boffset = in_f64->ilf_boffset;
1130 return 0;
1131 }
1132 return EFSCORRUPTED;
1133}
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index c5dbf93b6661..5db6cd1b4cf3 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -23,25 +23,6 @@
23 * log. The size of the inline data/extents/b-tree root to be logged 23 * log. The size of the inline data/extents/b-tree root to be logged
24 * (if any) is indicated in the ilf_dsize field. Changes to this structure 24 * (if any) is indicated in the ilf_dsize field. Changes to this structure
25 * must be added on to the end. 25 * must be added on to the end.
26 *
27 * Convention for naming inode log item versions : The current version
28 * is always named XFS_LI_INODE. When an inode log item gets superseded,
29 * add the latest version of IRIX that will generate logs with that item
30 * to the version name.
31 *
32 * -Version 1 of this structure (XFS_LI_5_3_INODE) included up to the first
33 * union (ilf_u) field. This was released with IRIX 5.3-XFS.
34 * -Version 2 of this structure (XFS_LI_6_1_INODE) is currently the entire
35 * structure. This was released with IRIX 6.0.1-XFS and IRIX 6.1.
36 * -Version 3 of this structure (XFS_LI_INODE) is the same as version 2
37 * so a new structure definition wasn't necessary. However, we had
38 * to add a new type because the inode cluster size changed from 4K
39 * to 8K and the version number had to be rev'ved to keep older kernels
40 * from trying to recover logs with the 8K buffers in them. The logging
41 * code can handle recovery on different-sized clusters now so hopefully
42 * this'll be the last time we need to change the inode log item just
43 * for a change in the inode cluster size. This new version was
44 * released with IRIX 6.2.
45 */ 26 */
46typedef struct xfs_inode_log_format { 27typedef struct xfs_inode_log_format {
47 unsigned short ilf_type; /* inode log item type */ 28 unsigned short ilf_type; /* inode log item type */
@@ -59,18 +40,38 @@ typedef struct xfs_inode_log_format {
59 int ilf_boffset; /* off of inode in buffer */ 40 int ilf_boffset; /* off of inode in buffer */
60} xfs_inode_log_format_t; 41} xfs_inode_log_format_t;
61 42
62/* Initial version shipped with IRIX 5.3-XFS */ 43typedef struct xfs_inode_log_format_32 {
63typedef struct xfs_inode_log_format_v1 { 44 unsigned short ilf_type; /* 16: inode log item type */
64 unsigned short ilf_type; /* inode log item type */ 45 unsigned short ilf_size; /* 16: size of this item */
65 unsigned short ilf_size; /* size of this item */ 46 uint ilf_fields; /* 32: flags for fields logged */
66 uint ilf_fields; /* flags for fields logged */ 47 ushort ilf_asize; /* 32: size of attr d/ext/root */
67 uint ilf_dsize; /* size of data/ext/root */ 48 ushort ilf_dsize; /* 32: size of data/ext/root */
68 xfs_ino_t ilf_ino; /* inode number */ 49 xfs_ino_t ilf_ino; /* 64: inode number */
69 union { 50 union {
70 xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/ 51 xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
71 uuid_t ilfu_uuid; /* mount point value */ 52 uuid_t ilfu_uuid; /* 128: mount point value */
53 } ilf_u;
54 __int64_t ilf_blkno; /* 64: blkno of inode buffer */
55 int ilf_len; /* 32: len of inode buffer */
56 int ilf_boffset; /* 32: off of inode in buffer */
57} __attribute__((packed)) xfs_inode_log_format_32_t;
58
59typedef struct xfs_inode_log_format_64 {
60 unsigned short ilf_type; /* 16: inode log item type */
61 unsigned short ilf_size; /* 16: size of this item */
62 uint ilf_fields; /* 32: flags for fields logged */
63 ushort ilf_asize; /* 32: size of attr d/ext/root */
64 ushort ilf_dsize; /* 32: size of data/ext/root */
65 __uint32_t ilf_pad; /* 32: pad for 64 bit boundary */
66 xfs_ino_t ilf_ino; /* 64: inode number */
67 union {
68 xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
69 uuid_t ilfu_uuid; /* 128: mount point value */
72 } ilf_u; 70 } ilf_u;
73} xfs_inode_log_format_t_v1; 71 __int64_t ilf_blkno; /* 64: blkno of inode buffer */
72 int ilf_len; /* 32: len of inode buffer */
73 int ilf_boffset; /* 32: off of inode in buffer */
74} xfs_inode_log_format_64_t;
74 75
75/* 76/*
76 * Flags for xfs_trans_log_inode flags field. 77 * Flags for xfs_trans_log_inode flags field.
@@ -172,6 +173,8 @@ extern void xfs_inode_item_destroy(struct xfs_inode *);
172extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); 173extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
173extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *); 174extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
174extern void xfs_iflush_abort(struct xfs_inode *); 175extern void xfs_iflush_abort(struct xfs_inode *);
176extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
177 xfs_inode_log_format_t *);
175 178
176#endif /* __KERNEL__ */ 179#endif /* __KERNEL__ */
177 180
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c
index a07815661a8c..06d710c9ce4b 100644
--- a/fs/xfs/xfs_iocore.c
+++ b/fs/xfs/xfs_iocore.c
@@ -24,14 +24,13 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
28#include "xfs_dfrag.h"
29#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
30#include "xfs_mount.h" 30#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -58,7 +57,7 @@ xfs_size_fn(
58 57
59STATIC int 58STATIC int
60xfs_ioinit( 59xfs_ioinit(
61 struct vfs *vfsp, 60 struct bhv_vfs *vfsp,
62 struct xfs_mount_args *mntargs, 61 struct xfs_mount_args *mntargs,
63 int flags) 62 int flags)
64{ 63{
@@ -68,6 +67,7 @@ xfs_ioinit(
68xfs_ioops_t xfs_iocore_xfs = { 67xfs_ioops_t xfs_iocore_xfs = {
69 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit, 68 .xfs_ioinit = (xfs_ioinit_t) xfs_ioinit,
70 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi, 69 .xfs_bmapi_func = (xfs_bmapi_t) xfs_bmapi,
70 .xfs_bunmapi_func = (xfs_bunmapi_t) xfs_bunmapi,
71 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof, 71 .xfs_bmap_eof_func = (xfs_bmap_eof_t) xfs_bmap_eof,
72 .xfs_iomap_write_direct = 72 .xfs_iomap_write_direct =
73 (xfs_iomap_write_direct_t) xfs_iomap_write_direct, 73 (xfs_iomap_write_direct_t) xfs_iomap_write_direct,
@@ -84,6 +84,7 @@ xfs_ioops_t xfs_iocore_xfs = {
84 .xfs_unlock = (xfs_unlk_t) xfs_iunlock, 84 .xfs_unlock = (xfs_unlk_t) xfs_iunlock,
85 .xfs_size_func = (xfs_size_t) xfs_size_fn, 85 .xfs_size_func = (xfs_size_t) xfs_size_fn,
86 .xfs_iodone = (xfs_iodone_t) fs_noerr, 86 .xfs_iodone = (xfs_iodone_t) fs_noerr,
87 .xfs_swap_extents_func = (xfs_swap_extents_t) xfs_swap_extents,
87}; 88};
88 89
89void 90void
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index d5dfedcb8922..f1949c16df15 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_alloc.h" 27#include "xfs_alloc.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -252,7 +250,7 @@ xfs_iomap(
252 error = XFS_BMAPI(mp, NULL, io, offset_fsb, 250 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
253 (xfs_filblks_t)(end_fsb - offset_fsb), 251 (xfs_filblks_t)(end_fsb - offset_fsb),
254 bmapi_flags, NULL, 0, &imap, 252 bmapi_flags, NULL, 0, &imap,
255 &nimaps, NULL); 253 &nimaps, NULL, NULL);
256 254
257 if (error) 255 if (error)
258 goto out; 256 goto out;
@@ -519,8 +517,8 @@ xfs_iomap_write_direct(
519 */ 517 */
520 XFS_BMAP_INIT(&free_list, &firstfsb); 518 XFS_BMAP_INIT(&free_list, &firstfsb);
521 nimaps = 1; 519 nimaps = 1;
522 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 520 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb, bmapi_flag,
523 bmapi_flag, &firstfsb, 0, &imap, &nimaps, &free_list); 521 &firstfsb, 0, &imap, &nimaps, &free_list, NULL);
524 if (error) 522 if (error)
525 goto error0; 523 goto error0;
526 524
@@ -610,8 +608,8 @@ xfs_iomap_eof_want_preallocate(
610 while (count_fsb > 0) { 608 while (count_fsb > 0) {
611 imaps = nimaps; 609 imaps = nimaps;
612 firstblock = NULLFSBLOCK; 610 firstblock = NULLFSBLOCK;
613 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 611 error = XFS_BMAPI(mp, NULL, io, start_fsb, count_fsb, 0,
614 0, &firstblock, 0, imap, &imaps, NULL); 612 &firstblock, 0, imap, &imaps, NULL, NULL);
615 if (error) 613 if (error)
616 return error; 614 return error;
617 for (n = 0; n < imaps; n++) { 615 for (n = 0; n < imaps; n++) {
@@ -695,11 +693,11 @@ retry:
695 693
696 nimaps = XFS_WRITE_IMAPS; 694 nimaps = XFS_WRITE_IMAPS;
697 firstblock = NULLFSBLOCK; 695 firstblock = NULLFSBLOCK;
698 error = xfs_bmapi(NULL, ip, offset_fsb, 696 error = XFS_BMAPI(mp, NULL, io, offset_fsb,
699 (xfs_filblks_t)(last_fsb - offset_fsb), 697 (xfs_filblks_t)(last_fsb - offset_fsb),
700 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | 698 XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
701 XFS_BMAPI_ENTIRE, &firstblock, 1, imap, 699 XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
702 &nimaps, NULL); 700 &nimaps, NULL, NULL);
703 if (error && (error != ENOSPC)) 701 if (error && (error != ENOSPC))
704 return XFS_ERROR(error); 702 return XFS_ERROR(error);
705 703
@@ -832,9 +830,9 @@ xfs_iomap_write_allocate(
832 } 830 }
833 831
834 /* Go get the actual blocks */ 832 /* Go get the actual blocks */
835 error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, 833 error = XFS_BMAPI(mp, tp, io, map_start_fsb, count_fsb,
836 XFS_BMAPI_WRITE, &first_block, 1, 834 XFS_BMAPI_WRITE, &first_block, 1,
837 imap, &nimaps, &free_list); 835 imap, &nimaps, &free_list, NULL);
838 if (error) 836 if (error)
839 goto trans_cancel; 837 goto trans_cancel;
840 838
@@ -955,9 +953,9 @@ xfs_iomap_write_unwritten(
955 */ 953 */
956 XFS_BMAP_INIT(&free_list, &firstfsb); 954 XFS_BMAP_INIT(&free_list, &firstfsb);
957 nimaps = 1; 955 nimaps = 1;
958 error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, 956 error = XFS_BMAPI(mp, tp, io, offset_fsb, count_fsb,
959 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, 957 XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
960 1, &imap, &nimaps, &free_list); 958 1, &imap, &nimaps, &free_list, NULL);
961 if (error) 959 if (error)
962 goto error_on_bmapi_transaction; 960 goto error_on_bmapi_transaction;
963 961
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 94068d014f27..46249e4d1fea 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -41,11 +39,6 @@
41#include "xfs_error.h" 39#include "xfs_error.h"
42#include "xfs_btree.h" 40#include "xfs_btree.h"
43 41
44#ifndef HAVE_USERACC
45#define useracc(ubuffer, size, flags, foo) (0)
46#define unuseracc(ubuffer, size, flags)
47#endif
48
49STATIC int 42STATIC int
50xfs_bulkstat_one_iget( 43xfs_bulkstat_one_iget(
51 xfs_mount_t *mp, /* mount point for filesystem */ 44 xfs_mount_t *mp, /* mount point for filesystem */
@@ -56,7 +49,7 @@ xfs_bulkstat_one_iget(
56{ 49{
57 xfs_dinode_core_t *dic; /* dinode core info pointer */ 50 xfs_dinode_core_t *dic; /* dinode core info pointer */
58 xfs_inode_t *ip; /* incore inode pointer */ 51 xfs_inode_t *ip; /* incore inode pointer */
59 vnode_t *vp; 52 bhv_vnode_t *vp;
60 int error; 53 int error;
61 54
62 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); 55 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
@@ -336,15 +329,6 @@ xfs_bulkstat(
336 nimask = ~(nicluster - 1); 329 nimask = ~(nicluster - 1);
337 nbcluster = nicluster >> mp->m_sb.sb_inopblog; 330 nbcluster = nicluster >> mp->m_sb.sb_inopblog;
338 /* 331 /*
339 * Lock down the user's buffer. If a buffer was not sent, as in the case
340 * disk quota code calls here, we skip this.
341 */
342 if (ubuffer &&
343 (error = useracc(ubuffer, ubcount * statstruct_size,
344 (B_READ|B_PHYS), NULL))) {
345 return error;
346 }
347 /*
348 * Allocate a page-sized buffer for inode btree records. 332 * Allocate a page-sized buffer for inode btree records.
349 * We could try allocating something smaller, but for normal 333 * We could try allocating something smaller, but for normal
350 * calls we'll always (potentially) need the whole page. 334 * calls we'll always (potentially) need the whole page.
@@ -650,8 +634,6 @@ xfs_bulkstat(
650 * Done, we're either out of filesystem or space to put the data. 634 * Done, we're either out of filesystem or space to put the data.
651 */ 635 */
652 kmem_free(irbuf, NBPC); 636 kmem_free(irbuf, NBPC);
653 if (ubuffer)
654 unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
655 *ubcountp = ubelem; 637 *ubcountp = ubelem;
656 if (agno >= mp->m_sb.sb_agcount) { 638 if (agno >= mp->m_sb.sb_agcount) {
657 /* 639 /*
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 11eb4e1b18c4..be5f12e07d22 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -45,7 +45,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
45 */ 45 */
46#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ 46#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
47#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ 47#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
48#define BULKSTAT_FG_VFSLOCKED 0x4 /* Already have vfs lock */
49 48
50/* 49/*
51 * Return stat information in bulk (by-inode) for the filesystem. 50 * Return stat information in bulk (by-inode) for the filesystem.
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 32e841d2f26d..d8f5d4cbe8b7 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -36,7 +35,6 @@
36#include "xfs_ialloc_btree.h" 35#include "xfs_ialloc_btree.h"
37#include "xfs_log_recover.h" 36#include "xfs_log_recover.h"
38#include "xfs_trans_priv.h" 37#include "xfs_trans_priv.h"
39#include "xfs_dir_sf.h"
40#include "xfs_dir2_sf.h" 38#include "xfs_dir2_sf.h"
41#include "xfs_attr_sf.h" 39#include "xfs_attr_sf.h"
42#include "xfs_dinode.h" 40#include "xfs_dinode.h"
@@ -402,7 +400,7 @@ xfs_log_release_iclog(xfs_mount_t *mp,
402 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; 400 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
403 401
404 if (xlog_state_release_iclog(log, iclog)) { 402 if (xlog_state_release_iclog(log, iclog)) {
405 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 403 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
406 return EIO; 404 return EIO;
407 } 405 }
408 406
@@ -498,9 +496,8 @@ xfs_log_mount(xfs_mount_t *mp,
498 * just worked. 496 * just worked.
499 */ 497 */
500 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { 498 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
501 int error; 499 bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
502 vfs_t *vfsp = XFS_MTOVFS(mp); 500 int error, readonly = (vfsp->vfs_flag & VFS_RDONLY);
503 int readonly = (vfsp->vfs_flag & VFS_RDONLY);
504 501
505 if (readonly) 502 if (readonly)
506 vfsp->vfs_flag &= ~VFS_RDONLY; 503 vfsp->vfs_flag &= ~VFS_RDONLY;
@@ -726,7 +723,7 @@ xfs_log_write(xfs_mount_t * mp,
726 return XFS_ERROR(EIO); 723 return XFS_ERROR(EIO);
727 724
728 if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) { 725 if ((error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0))) {
729 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 726 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
730 } 727 }
731 return error; 728 return error;
732} /* xfs_log_write */ 729} /* xfs_log_write */
@@ -816,9 +813,9 @@ xfs_log_need_covered(xfs_mount_t *mp)
816 SPLDECL(s); 813 SPLDECL(s);
817 int needed = 0, gen; 814 int needed = 0, gen;
818 xlog_t *log = mp->m_log; 815 xlog_t *log = mp->m_log;
819 vfs_t *vfsp = XFS_MTOVFS(mp); 816 bhv_vfs_t *vfsp = XFS_MTOVFS(mp);
820 817
821 if (fs_frozen(vfsp) || XFS_FORCED_SHUTDOWN(mp) || 818 if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) ||
822 (vfsp->vfs_flag & VFS_RDONLY)) 819 (vfsp->vfs_flag & VFS_RDONLY))
823 return 0; 820 return 0;
824 821
@@ -956,7 +953,7 @@ xlog_iodone(xfs_buf_t *bp)
956 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { 953 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
957 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp)); 954 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
958 XFS_BUF_STALE(bp); 955 XFS_BUF_STALE(bp);
959 xfs_force_shutdown(l->l_mp, XFS_LOG_IO_ERROR); 956 xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR);
960 /* 957 /*
961 * This flag will be propagated to the trans-committed 958 * This flag will be propagated to the trans-committed
962 * callback routines to let them know that the log-commit 959 * callback routines to let them know that the log-commit
@@ -1261,7 +1258,7 @@ xlog_commit_record(xfs_mount_t *mp,
1261 ASSERT_ALWAYS(iclog); 1258 ASSERT_ALWAYS(iclog);
1262 if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, 1259 if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp,
1263 iclog, XLOG_COMMIT_TRANS))) { 1260 iclog, XLOG_COMMIT_TRANS))) {
1264 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 1261 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
1265 } 1262 }
1266 return error; 1263 return error;
1267} /* xlog_commit_record */ 1264} /* xlog_commit_record */
@@ -1790,7 +1787,7 @@ xlog_write(xfs_mount_t * mp,
1790 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp, 1787 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
1791 "xfs_log_write: reservation ran out. Need to up reservation"); 1788 "xfs_log_write: reservation ran out. Need to up reservation");
1792 /* If we did not panic, shutdown the filesystem */ 1789 /* If we did not panic, shutdown the filesystem */
1793 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 1790 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1794#endif 1791#endif
1795 } else 1792 } else
1796 ticket->t_curr_res -= len; 1793 ticket->t_curr_res -= len;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 1f0016b0b4ec..55b4237c2153 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_alloc_btree.h" 32#include "xfs_alloc_btree.h"
34#include "xfs_ialloc_btree.h" 33#include "xfs_ialloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -193,14 +191,14 @@ xlog_header_check_dump(
193{ 191{
194 int b; 192 int b;
195 193
196 printk("%s: SB : uuid = ", __FUNCTION__); 194 cmn_err(CE_DEBUG, "%s: SB : uuid = ", __FUNCTION__);
197 for (b = 0; b < 16; b++) 195 for (b = 0; b < 16; b++)
198 printk("%02x",((unsigned char *)&mp->m_sb.sb_uuid)[b]); 196 cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
199 printk(", fmt = %d\n", XLOG_FMT); 197 cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
200 printk(" log : uuid = "); 198 cmn_err(CE_DEBUG, " log : uuid = ");
201 for (b = 0; b < 16; b++) 199 for (b = 0; b < 16; b++)
202 printk("%02x",((unsigned char *)&head->h_fs_uuid)[b]); 200 cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
203 printk(", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT)); 201 cmn_err(CE_DEBUG, ", fmt = %d\n", INT_GET(head->h_fmt, ARCH_CONVERT));
204} 202}
205#else 203#else
206#define xlog_header_check_dump(mp, head) 204#define xlog_header_check_dump(mp, head)
@@ -282,7 +280,7 @@ xlog_recover_iodone(
282 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *); 280 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
283 xfs_ioerror_alert("xlog_recover_iodone", 281 xfs_ioerror_alert("xlog_recover_iodone",
284 mp, bp, XFS_BUF_ADDR(bp)); 282 mp, bp, XFS_BUF_ADDR(bp));
285 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 283 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
286 } 284 }
287 XFS_BUF_SET_FSPRIVATE(bp, NULL); 285 XFS_BUF_SET_FSPRIVATE(bp, NULL);
288 XFS_BUF_CLR_IODONE_FUNC(bp); 286 XFS_BUF_CLR_IODONE_FUNC(bp);
@@ -1889,7 +1887,7 @@ xlog_recover_do_inode_buffer(
1889 1887
1890 buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp, 1888 buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
1891 next_unlinked_offset); 1889 next_unlinked_offset);
1892 INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp); 1890 *buffer_nextp = *logged_nextp;
1893 } 1891 }
1894 1892
1895 return 0; 1893 return 0;
@@ -2292,12 +2290,22 @@ xlog_recover_do_inode_trans(
2292 int attr_index; 2290 int attr_index;
2293 uint fields; 2291 uint fields;
2294 xfs_dinode_core_t *dicp; 2292 xfs_dinode_core_t *dicp;
2293 int need_free = 0;
2295 2294
2296 if (pass == XLOG_RECOVER_PASS1) { 2295 if (pass == XLOG_RECOVER_PASS1) {
2297 return 0; 2296 return 0;
2298 } 2297 }
2299 2298
2300 in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr; 2299 if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
2300 in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
2301 } else {
2302 in_f = (xfs_inode_log_format_t *)kmem_alloc(
2303 sizeof(xfs_inode_log_format_t), KM_SLEEP);
2304 need_free = 1;
2305 error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
2306 if (error)
2307 goto error;
2308 }
2301 ino = in_f->ilf_ino; 2309 ino = in_f->ilf_ino;
2302 mp = log->l_mp; 2310 mp = log->l_mp;
2303 if (ITEM_TYPE(item) == XFS_LI_INODE) { 2311 if (ITEM_TYPE(item) == XFS_LI_INODE) {
@@ -2323,8 +2331,10 @@ xlog_recover_do_inode_trans(
2323 * Inode buffers can be freed, look out for it, 2331 * Inode buffers can be freed, look out for it,
2324 * and do not replay the inode. 2332 * and do not replay the inode.
2325 */ 2333 */
2326 if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) 2334 if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) {
2327 return 0; 2335 error = 0;
2336 goto error;
2337 }
2328 2338
2329 bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len, 2339 bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len,
2330 XFS_BUF_LOCK); 2340 XFS_BUF_LOCK);
@@ -2333,7 +2343,7 @@ xlog_recover_do_inode_trans(
2333 bp, imap.im_blkno); 2343 bp, imap.im_blkno);
2334 error = XFS_BUF_GETERROR(bp); 2344 error = XFS_BUF_GETERROR(bp);
2335 xfs_buf_relse(bp); 2345 xfs_buf_relse(bp);
2336 return error; 2346 goto error;
2337 } 2347 }
2338 error = 0; 2348 error = 0;
2339 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); 2349 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
@@ -2350,7 +2360,8 @@ xlog_recover_do_inode_trans(
2350 dip, bp, ino); 2360 dip, bp, ino);
2351 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)", 2361 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)",
2352 XFS_ERRLEVEL_LOW, mp); 2362 XFS_ERRLEVEL_LOW, mp);
2353 return XFS_ERROR(EFSCORRUPTED); 2363 error = EFSCORRUPTED;
2364 goto error;
2354 } 2365 }
2355 dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr); 2366 dicp = (xfs_dinode_core_t*)(item->ri_buf[1].i_addr);
2356 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) { 2367 if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
@@ -2360,7 +2371,8 @@ xlog_recover_do_inode_trans(
2360 item, ino); 2371 item, ino);
2361 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)", 2372 XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)",
2362 XFS_ERRLEVEL_LOW, mp); 2373 XFS_ERRLEVEL_LOW, mp);
2363 return XFS_ERROR(EFSCORRUPTED); 2374 error = EFSCORRUPTED;
2375 goto error;
2364 } 2376 }
2365 2377
2366 /* Skip replay when the on disk inode is newer than the log one */ 2378 /* Skip replay when the on disk inode is newer than the log one */
@@ -2376,7 +2388,8 @@ xlog_recover_do_inode_trans(
2376 /* do nothing */ 2388 /* do nothing */
2377 } else { 2389 } else {
2378 xfs_buf_relse(bp); 2390 xfs_buf_relse(bp);
2379 return 0; 2391 error = 0;
2392 goto error;
2380 } 2393 }
2381 } 2394 }
2382 /* Take the opportunity to reset the flush iteration count */ 2395 /* Take the opportunity to reset the flush iteration count */
@@ -2391,7 +2404,8 @@ xlog_recover_do_inode_trans(
2391 xfs_fs_cmn_err(CE_ALERT, mp, 2404 xfs_fs_cmn_err(CE_ALERT, mp,
2392 "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2405 "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2393 item, dip, bp, ino); 2406 item, dip, bp, ino);
2394 return XFS_ERROR(EFSCORRUPTED); 2407 error = EFSCORRUPTED;
2408 goto error;
2395 } 2409 }
2396 } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) { 2410 } else if (unlikely((dicp->di_mode & S_IFMT) == S_IFDIR)) {
2397 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && 2411 if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) &&
@@ -2403,7 +2417,8 @@ xlog_recover_do_inode_trans(
2403 xfs_fs_cmn_err(CE_ALERT, mp, 2417 xfs_fs_cmn_err(CE_ALERT, mp,
2404 "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", 2418 "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld",
2405 item, dip, bp, ino); 2419 item, dip, bp, ino);
2406 return XFS_ERROR(EFSCORRUPTED); 2420 error = EFSCORRUPTED;
2421 goto error;
2407 } 2422 }
2408 } 2423 }
2409 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ 2424 if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){
@@ -2415,7 +2430,8 @@ xlog_recover_do_inode_trans(
2415 item, dip, bp, ino, 2430 item, dip, bp, ino,
2416 dicp->di_nextents + dicp->di_anextents, 2431 dicp->di_nextents + dicp->di_anextents,
2417 dicp->di_nblocks); 2432 dicp->di_nblocks);
2418 return XFS_ERROR(EFSCORRUPTED); 2433 error = EFSCORRUPTED;
2434 goto error;
2419 } 2435 }
2420 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { 2436 if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) {
2421 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)", 2437 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)",
@@ -2424,7 +2440,8 @@ xlog_recover_do_inode_trans(
2424 xfs_fs_cmn_err(CE_ALERT, mp, 2440 xfs_fs_cmn_err(CE_ALERT, mp,
2425 "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x", 2441 "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x",
2426 item, dip, bp, ino, dicp->di_forkoff); 2442 item, dip, bp, ino, dicp->di_forkoff);
2427 return XFS_ERROR(EFSCORRUPTED); 2443 error = EFSCORRUPTED;
2444 goto error;
2428 } 2445 }
2429 if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) { 2446 if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
2430 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)", 2447 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
@@ -2433,7 +2450,8 @@ xlog_recover_do_inode_trans(
2433 xfs_fs_cmn_err(CE_ALERT, mp, 2450 xfs_fs_cmn_err(CE_ALERT, mp,
2434 "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p", 2451 "xfs_inode_recover: Bad inode log record length %d, rec ptr 0x%p",
2435 item->ri_buf[1].i_len, item); 2452 item->ri_buf[1].i_len, item);
2436 return XFS_ERROR(EFSCORRUPTED); 2453 error = EFSCORRUPTED;
2454 goto error;
2437 } 2455 }
2438 2456
2439 /* The core is in in-core format */ 2457 /* The core is in in-core format */
@@ -2521,7 +2539,8 @@ xlog_recover_do_inode_trans(
2521 xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag"); 2539 xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag");
2522 ASSERT(0); 2540 ASSERT(0);
2523 xfs_buf_relse(bp); 2541 xfs_buf_relse(bp);
2524 return XFS_ERROR(EIO); 2542 error = EIO;
2543 goto error;
2525 } 2544 }
2526 } 2545 }
2527 2546
@@ -2537,7 +2556,10 @@ write_inode_buffer:
2537 error = xfs_bwrite(mp, bp); 2556 error = xfs_bwrite(mp, bp);
2538 } 2557 }
2539 2558
2540 return (error); 2559error:
2560 if (need_free)
2561 kmem_free(in_f, sizeof(*in_f));
2562 return XFS_ERROR(error);
2541} 2563}
2542 2564
2543/* 2565/*
@@ -2674,32 +2696,32 @@ xlog_recover_do_dquot_trans(
2674 * structure into it, and adds the efi to the AIL with the given 2696 * structure into it, and adds the efi to the AIL with the given
2675 * LSN. 2697 * LSN.
2676 */ 2698 */
2677STATIC void 2699STATIC int
2678xlog_recover_do_efi_trans( 2700xlog_recover_do_efi_trans(
2679 xlog_t *log, 2701 xlog_t *log,
2680 xlog_recover_item_t *item, 2702 xlog_recover_item_t *item,
2681 xfs_lsn_t lsn, 2703 xfs_lsn_t lsn,
2682 int pass) 2704 int pass)
2683{ 2705{
2706 int error;
2684 xfs_mount_t *mp; 2707 xfs_mount_t *mp;
2685 xfs_efi_log_item_t *efip; 2708 xfs_efi_log_item_t *efip;
2686 xfs_efi_log_format_t *efi_formatp; 2709 xfs_efi_log_format_t *efi_formatp;
2687 SPLDECL(s); 2710 SPLDECL(s);
2688 2711
2689 if (pass == XLOG_RECOVER_PASS1) { 2712 if (pass == XLOG_RECOVER_PASS1) {
2690 return; 2713 return 0;
2691 } 2714 }
2692 2715
2693 efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr; 2716 efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
2694 ASSERT(item->ri_buf[0].i_len ==
2695 (sizeof(xfs_efi_log_format_t) +
2696 ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))));
2697 2717
2698 mp = log->l_mp; 2718 mp = log->l_mp;
2699 efip = xfs_efi_init(mp, efi_formatp->efi_nextents); 2719 efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
2700 memcpy((char *)&(efip->efi_format), (char *)efi_formatp, 2720 if ((error = xfs_efi_copy_format(&(item->ri_buf[0]),
2701 sizeof(xfs_efi_log_format_t) + 2721 &(efip->efi_format)))) {
2702 ((efi_formatp->efi_nextents - 1) * sizeof(xfs_extent_t))); 2722 xfs_efi_item_free(efip);
2723 return error;
2724 }
2703 efip->efi_next_extent = efi_formatp->efi_nextents; 2725 efip->efi_next_extent = efi_formatp->efi_nextents;
2704 efip->efi_flags |= XFS_EFI_COMMITTED; 2726 efip->efi_flags |= XFS_EFI_COMMITTED;
2705 2727
@@ -2708,6 +2730,7 @@ xlog_recover_do_efi_trans(
2708 * xfs_trans_update_ail() drops the AIL lock. 2730 * xfs_trans_update_ail() drops the AIL lock.
2709 */ 2731 */
2710 xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s); 2732 xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn, s);
2733 return 0;
2711} 2734}
2712 2735
2713 2736
@@ -2738,9 +2761,10 @@ xlog_recover_do_efd_trans(
2738 } 2761 }
2739 2762
2740 efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr; 2763 efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
2741 ASSERT(item->ri_buf[0].i_len == 2764 ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
2742 (sizeof(xfs_efd_log_format_t) + 2765 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
2743 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_t)))); 2766 (item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
2767 ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_64_t)))));
2744 efi_id = efd_formatp->efd_efi_id; 2768 efi_id = efd_formatp->efd_efi_id;
2745 2769
2746 /* 2770 /*
@@ -2810,15 +2834,14 @@ xlog_recover_do_trans(
2810 if ((error = xlog_recover_do_buffer_trans(log, item, 2834 if ((error = xlog_recover_do_buffer_trans(log, item,
2811 pass))) 2835 pass)))
2812 break; 2836 break;
2813 } else if ((ITEM_TYPE(item) == XFS_LI_INODE) || 2837 } else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
2814 (ITEM_TYPE(item) == XFS_LI_6_1_INODE) ||
2815 (ITEM_TYPE(item) == XFS_LI_5_3_INODE)) {
2816 if ((error = xlog_recover_do_inode_trans(log, item, 2838 if ((error = xlog_recover_do_inode_trans(log, item,
2817 pass))) 2839 pass)))
2818 break; 2840 break;
2819 } else if (ITEM_TYPE(item) == XFS_LI_EFI) { 2841 } else if (ITEM_TYPE(item) == XFS_LI_EFI) {
2820 xlog_recover_do_efi_trans(log, item, trans->r_lsn, 2842 if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
2821 pass); 2843 pass)))
2844 break;
2822 } else if (ITEM_TYPE(item) == XFS_LI_EFD) { 2845 } else if (ITEM_TYPE(item) == XFS_LI_EFD) {
2823 xlog_recover_do_efd_trans(log, item, pass); 2846 xlog_recover_do_efd_trans(log, item, pass);
2824 } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) { 2847 } else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
@@ -3419,13 +3442,13 @@ xlog_unpack_data_checksum(
3419 if (rhead->h_chksum || 3442 if (rhead->h_chksum ||
3420 ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) { 3443 ((log->l_flags & XLOG_CHKSUM_MISMATCH) == 0)) {
3421 cmn_err(CE_DEBUG, 3444 cmn_err(CE_DEBUG,
3422 "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)", 3445 "XFS: LogR chksum mismatch: was (0x%x) is (0x%x)\n",
3423 INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum); 3446 INT_GET(rhead->h_chksum, ARCH_CONVERT), chksum);
3424 cmn_err(CE_DEBUG, 3447 cmn_err(CE_DEBUG,
3425"XFS: Disregard message if filesystem was created with non-DEBUG kernel"); 3448"XFS: Disregard message if filesystem was created with non-DEBUG kernel");
3426 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { 3449 if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
3427 cmn_err(CE_DEBUG, 3450 cmn_err(CE_DEBUG,
3428 "XFS: LogR this is a LogV2 filesystem"); 3451 "XFS: LogR this is a LogV2 filesystem\n");
3429 } 3452 }
3430 log->l_flags |= XLOG_CHKSUM_MISMATCH; 3453 log->l_flags |= XLOG_CHKSUM_MISMATCH;
3431 } 3454 }
@@ -3798,7 +3821,7 @@ xlog_do_log_recovery(
3798 error = xlog_do_recovery_pass(log, head_blk, tail_blk, 3821 error = xlog_do_recovery_pass(log, head_blk, tail_blk,
3799 XLOG_RECOVER_PASS2); 3822 XLOG_RECOVER_PASS2);
3800#ifdef DEBUG 3823#ifdef DEBUG
3801 { 3824 if (!error) {
3802 int i; 3825 int i;
3803 3826
3804 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) 3827 for (i = 0; i < XLOG_BC_TABLE_SIZE; i++)
@@ -3974,7 +3997,7 @@ xlog_recover_finish(
3974 log->l_flags &= ~XLOG_RECOVERY_NEEDED; 3997 log->l_flags &= ~XLOG_RECOVERY_NEEDED;
3975 } else { 3998 } else {
3976 cmn_err(CE_DEBUG, 3999 cmn_err(CE_DEBUG,
3977 "!Ending clean XFS mount for filesystem: %s", 4000 "!Ending clean XFS mount for filesystem: %s\n",
3978 log->l_mp->m_fsname); 4001 log->l_mp->m_fsname);
3979 } 4002 }
3980 return 0; 4003 return 0;
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index c0b1c2906880..10dbf203c62f 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -196,7 +194,7 @@ xfs_mount_free(
196 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); 194 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
197 195
198 if (remove_bhv) { 196 if (remove_bhv) {
199 struct vfs *vfsp = XFS_MTOVFS(mp); 197 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
200 198
201 bhv_remove_all_vfsops(vfsp, 0); 199 bhv_remove_all_vfsops(vfsp, 0);
202 VFS_REMOVEBHV(vfsp, &mp->m_bhv); 200 VFS_REMOVEBHV(vfsp, &mp->m_bhv);
@@ -337,7 +335,7 @@ xfs_mount_validate_sb(
337 335
338xfs_agnumber_t 336xfs_agnumber_t
339xfs_initialize_perag( 337xfs_initialize_perag(
340 struct vfs *vfs, 338 bhv_vfs_t *vfs,
341 xfs_mount_t *mp, 339 xfs_mount_t *mp,
342 xfs_agnumber_t agcount) 340 xfs_agnumber_t agcount)
343{ 341{
@@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
651 */ 649 */
652int 650int
653xfs_mountfs( 651xfs_mountfs(
654 vfs_t *vfsp, 652 bhv_vfs_t *vfsp,
655 xfs_mount_t *mp, 653 xfs_mount_t *mp,
656 int mfsi_flags) 654 int mfsi_flags)
657{ 655{
658 xfs_buf_t *bp; 656 xfs_buf_t *bp;
659 xfs_sb_t *sbp = &(mp->m_sb); 657 xfs_sb_t *sbp = &(mp->m_sb);
660 xfs_inode_t *rip; 658 xfs_inode_t *rip;
661 vnode_t *rvp = NULL; 659 bhv_vnode_t *rvp = NULL;
662 int readio_log, writeio_log; 660 int readio_log, writeio_log;
663 xfs_daddr_t d; 661 xfs_daddr_t d;
664 __uint64_t ret64; 662 __uint64_t ret64;
@@ -934,18 +932,7 @@ xfs_mountfs(
934 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; 932 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
935 mp->m_dmevmask = 0; /* not persistent; set after each mount */ 933 mp->m_dmevmask = 0; /* not persistent; set after each mount */
936 934
937 /* 935 xfs_dir_mount(mp);
938 * Select the right directory manager.
939 */
940 mp->m_dirops =
941 XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
942 xfsv2_dirops :
943 xfsv1_dirops;
944
945 /*
946 * Initialize directory manager's entries.
947 */
948 XFS_DIR_MOUNT(mp);
949 936
950 /* 937 /*
951 * Initialize the attribute manager's entries. 938 * Initialize the attribute manager's entries.
@@ -1006,8 +993,9 @@ xfs_mountfs(
1006 993
1007 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { 994 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
1008 cmn_err(CE_WARN, "XFS: corrupted root inode"); 995 cmn_err(CE_WARN, "XFS: corrupted root inode");
1009 prdev("Root inode %llu is not a directory", 996 cmn_err(CE_WARN, "Device %s - root %llu is not a directory",
1010 mp->m_ddev_targp, (unsigned long long)rip->i_ino); 997 XFS_BUFTARG_NAME(mp->m_ddev_targp),
998 (unsigned long long)rip->i_ino);
1011 xfs_iunlock(rip, XFS_ILOCK_EXCL); 999 xfs_iunlock(rip, XFS_ILOCK_EXCL);
1012 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, 1000 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
1013 mp); 1001 mp);
@@ -1094,7 +1082,7 @@ xfs_mountfs(
1094int 1082int
1095xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) 1083xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1096{ 1084{
1097 struct vfs *vfsp = XFS_MTOVFS(mp); 1085 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1098#if defined(DEBUG) || defined(INDUCE_IO_ERROR) 1086#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
1099 int64_t fsid; 1087 int64_t fsid;
1100#endif 1088#endif
@@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
1254 1242
1255 xfs_trans_log_buf(tp, bp, first, last); 1243 xfs_trans_log_buf(tp, bp, first, last);
1256} 1244}
1245
1246/*
1247 * In order to avoid ENOSPC-related deadlock caused by
1248 * out-of-order locking of AGF buffer (PV 947395), we place
1249 * constraints on the relationship among actual allocations for
1250 * data blocks, freelist blocks, and potential file data bmap
1251 * btree blocks. However, these restrictions may result in no
1252 * actual space allocated for a delayed extent, for example, a data
1253 * block in a certain AG is allocated but there is no additional
1254 * block for the additional bmap btree block due to a split of the
1255 * bmap btree of the file. The result of this may lead to an
1256 * infinite loop in xfssyncd when the file gets flushed to disk and
1257 * all delayed extents need to be actually allocated. To get around
1258 * this, we explicitly set aside a few blocks which will not be
1259 * reserved in delayed allocation. Considering the minimum number of
1260 * needed freelist blocks is 4 fsbs, a potential split of file's bmap
1261 * btree requires 1 fsb, so we set the number of set-aside blocks to 8.
1262*/
1263#define SET_ASIDE_BLOCKS 8
1264
1257/* 1265/*
1258 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply 1266 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
1259 * a delta to a specified field in the in-core superblock. Simply 1267 * a delta to a specified field in the in-core superblock. Simply
@@ -1298,7 +1306,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1298 return 0; 1306 return 0;
1299 case XFS_SBS_FDBLOCKS: 1307 case XFS_SBS_FDBLOCKS:
1300 1308
1301 lcounter = (long long)mp->m_sb.sb_fdblocks; 1309 lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS;
1302 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail); 1310 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
1303 1311
1304 if (delta > 0) { /* Putting blocks back */ 1312 if (delta > 0) { /* Putting blocks back */
@@ -1332,7 +1340,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1332 } 1340 }
1333 } 1341 }
1334 1342
1335 mp->m_sb.sb_fdblocks = lcounter; 1343 mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS;
1336 return 0; 1344 return 0;
1337 case XFS_SBS_FREXTENTS: 1345 case XFS_SBS_FREXTENTS:
1338 lcounter = (long long)mp->m_sb.sb_frextents; 1346 lcounter = (long long)mp->m_sb.sb_frextents;
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 668ad23fd37c..b2bd4be4200a 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -53,8 +53,8 @@ typedef struct xfs_trans_reservations {
53#else 53#else
54struct cred; 54struct cred;
55struct log; 55struct log;
56struct vfs; 56struct bhv_vfs;
57struct vnode; 57struct bhv_vnode;
58struct xfs_mount_args; 58struct xfs_mount_args;
59struct xfs_ihash; 59struct xfs_ihash;
60struct xfs_chash; 60struct xfs_chash;
@@ -63,9 +63,11 @@ struct xfs_perag;
63struct xfs_iocore; 63struct xfs_iocore;
64struct xfs_bmbt_irec; 64struct xfs_bmbt_irec;
65struct xfs_bmap_free; 65struct xfs_bmap_free;
66struct xfs_extdelta;
67struct xfs_swapext;
66 68
67extern struct vfsops xfs_vfsops; 69extern struct bhv_vfsops xfs_vfsops;
68extern struct vnodeops xfs_vnodeops; 70extern struct bhv_vnodeops xfs_vnodeops;
69 71
70#define AIL_LOCK_T lock_t 72#define AIL_LOCK_T lock_t
71#define AIL_LOCKINIT(x,y) spinlock_init(x,y) 73#define AIL_LOCKINIT(x,y) spinlock_init(x,y)
@@ -78,15 +80,15 @@ extern struct vnodeops xfs_vnodeops;
78 * Prototypes and functions for the Data Migration subsystem. 80 * Prototypes and functions for the Data Migration subsystem.
79 */ 81 */
80 82
81typedef int (*xfs_send_data_t)(int, struct vnode *, 83typedef int (*xfs_send_data_t)(int, struct bhv_vnode *,
82 xfs_off_t, size_t, int, vrwlock_t *); 84 xfs_off_t, size_t, int, bhv_vrwlock_t *);
83typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); 85typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
84typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t); 86typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t);
85typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *, 87typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct bhv_vfs *,
86 struct vnode *, 88 struct bhv_vnode *,
87 dm_right_t, struct vnode *, dm_right_t, 89 dm_right_t, struct bhv_vnode *, dm_right_t,
88 char *, char *, mode_t, int, int); 90 char *, char *, mode_t, int, int);
89typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *, 91typedef void (*xfs_send_unmount_t)(struct bhv_vfs *, struct bhv_vnode *,
90 dm_right_t, mode_t, int, int); 92 dm_right_t, mode_t, int, int);
91 93
92typedef struct xfs_dmops { 94typedef struct xfs_dmops {
@@ -188,13 +190,18 @@ typedef struct xfs_qmops {
188 * Prototypes and functions for I/O core modularization. 190 * Prototypes and functions for I/O core modularization.
189 */ 191 */
190 192
191typedef int (*xfs_ioinit_t)(struct vfs *, 193typedef int (*xfs_ioinit_t)(struct bhv_vfs *,
192 struct xfs_mount_args *, int); 194 struct xfs_mount_args *, int);
193typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, 195typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *,
194 xfs_fileoff_t, xfs_filblks_t, int, 196 xfs_fileoff_t, xfs_filblks_t, int,
195 xfs_fsblock_t *, xfs_extlen_t, 197 xfs_fsblock_t *, xfs_extlen_t,
196 struct xfs_bmbt_irec *, int *, 198 struct xfs_bmbt_irec *, int *,
197 struct xfs_bmap_free *); 199 struct xfs_bmap_free *, struct xfs_extdelta *);
200typedef int (*xfs_bunmapi_t)(struct xfs_trans *,
201 void *, xfs_fileoff_t,
202 xfs_filblks_t, int, xfs_extnum_t,
203 xfs_fsblock_t *, struct xfs_bmap_free *,
204 struct xfs_extdelta *, int *);
198typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); 205typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *);
199typedef int (*xfs_iomap_write_direct_t)( 206typedef int (*xfs_iomap_write_direct_t)(
200 void *, xfs_off_t, size_t, int, 207 void *, xfs_off_t, size_t, int,
@@ -213,11 +220,14 @@ typedef void (*xfs_lock_demote_t)(void *, uint);
213typedef int (*xfs_lock_nowait_t)(void *, uint); 220typedef int (*xfs_lock_nowait_t)(void *, uint);
214typedef void (*xfs_unlk_t)(void *, unsigned int); 221typedef void (*xfs_unlk_t)(void *, unsigned int);
215typedef xfs_fsize_t (*xfs_size_t)(void *); 222typedef xfs_fsize_t (*xfs_size_t)(void *);
216typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); 223typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *);
224typedef int (*xfs_swap_extents_t)(void *, void *,
225 struct xfs_swapext*);
217 226
218typedef struct xfs_ioops { 227typedef struct xfs_ioops {
219 xfs_ioinit_t xfs_ioinit; 228 xfs_ioinit_t xfs_ioinit;
220 xfs_bmapi_t xfs_bmapi_func; 229 xfs_bmapi_t xfs_bmapi_func;
230 xfs_bunmapi_t xfs_bunmapi_func;
221 xfs_bmap_eof_t xfs_bmap_eof_func; 231 xfs_bmap_eof_t xfs_bmap_eof_func;
222 xfs_iomap_write_direct_t xfs_iomap_write_direct; 232 xfs_iomap_write_direct_t xfs_iomap_write_direct;
223 xfs_iomap_write_delay_t xfs_iomap_write_delay; 233 xfs_iomap_write_delay_t xfs_iomap_write_delay;
@@ -230,13 +240,17 @@ typedef struct xfs_ioops {
230 xfs_unlk_t xfs_unlock; 240 xfs_unlk_t xfs_unlock;
231 xfs_size_t xfs_size_func; 241 xfs_size_t xfs_size_func;
232 xfs_iodone_t xfs_iodone; 242 xfs_iodone_t xfs_iodone;
243 xfs_swap_extents_t xfs_swap_extents_func;
233} xfs_ioops_t; 244} xfs_ioops_t;
234 245
235#define XFS_IOINIT(vfsp, args, flags) \ 246#define XFS_IOINIT(vfsp, args, flags) \
236 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags) 247 (*(mp)->m_io_ops.xfs_ioinit)(vfsp, args, flags)
237#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist) \ 248#define XFS_BMAPI(mp, trans,io,bno,len,f,first,tot,mval,nmap,flist,delta) \
238 (*(mp)->m_io_ops.xfs_bmapi_func) \ 249 (*(mp)->m_io_ops.xfs_bmapi_func) \
239 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist) 250 (trans,(io)->io_obj,bno,len,f,first,tot,mval,nmap,flist,delta)
251#define XFS_BUNMAPI(mp, trans,io,bno,len,f,nexts,first,flist,delta,done) \
252 (*(mp)->m_io_ops.xfs_bunmapi_func) \
253 (trans,(io)->io_obj,bno,len,f,nexts,first,flist,delta,done)
240#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \ 254#define XFS_BMAP_EOF(mp, io, endoff, whichfork, eof) \
241 (*(mp)->m_io_ops.xfs_bmap_eof_func) \ 255 (*(mp)->m_io_ops.xfs_bmap_eof_func) \
242 ((io)->io_obj, endoff, whichfork, eof) 256 ((io)->io_obj, endoff, whichfork, eof)
@@ -266,6 +280,9 @@ typedef struct xfs_ioops {
266 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj) 280 (*(mp)->m_io_ops.xfs_size_func)((io)->io_obj)
267#define XFS_IODONE(vfsp) \ 281#define XFS_IODONE(vfsp) \
268 (*(mp)->m_io_ops.xfs_iodone)(vfsp) 282 (*(mp)->m_io_ops.xfs_iodone)(vfsp)
283#define XFS_SWAP_EXTENTS(mp, io, tio, sxp) \
284 (*(mp)->m_io_ops.xfs_swap_extents_func) \
285 ((io)->io_obj, (tio)->io_obj, sxp)
269 286
270#ifdef HAVE_PERCPU_SB 287#ifdef HAVE_PERCPU_SB
271 288
@@ -386,8 +403,6 @@ typedef struct xfs_mount {
386 __uint8_t m_inode_quiesce;/* call quiesce on new inodes. 403 __uint8_t m_inode_quiesce;/* call quiesce on new inodes.
387 field governed by m_ilock */ 404 field governed by m_ilock */
388 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ 405 __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
389 __uint8_t m_dirversion; /* 1 or 2 */
390 xfs_dirops_t m_dirops; /* table of dir funcs */
391 int m_dirblksize; /* directory block sz--bytes */ 406 int m_dirblksize; /* directory block sz--bytes */
392 int m_dirblkfsbs; /* directory block sz--fsbs */ 407 int m_dirblkfsbs; /* directory block sz--fsbs */
393 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ 408 xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
@@ -494,16 +509,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
494 509
495#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) 510#define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN)
496#define xfs_force_shutdown(m,f) \ 511#define xfs_force_shutdown(m,f) \
497 VFS_FORCE_SHUTDOWN((XFS_MTOVFS(m)), f, __FILE__, __LINE__) 512 bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__)
498
499/*
500 * Flags sent to xfs_force_shutdown.
501 */
502#define XFS_METADATA_IO_ERROR 0x1
503#define XFS_LOG_IO_ERROR 0x2
504#define XFS_FORCE_UMOUNT 0x4
505#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
506#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
507 513
508/* 514/*
509 * Flags for xfs_mountfs 515 * Flags for xfs_mountfs
@@ -521,7 +527,7 @@ xfs_preferred_iosize(xfs_mount_t *mp)
521 * Macros for getting from mount to vfs and back. 527 * Macros for getting from mount to vfs and back.
522 */ 528 */
523#define XFS_MTOVFS(mp) xfs_mtovfs(mp) 529#define XFS_MTOVFS(mp) xfs_mtovfs(mp)
524static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp) 530static inline struct bhv_vfs *xfs_mtovfs(xfs_mount_t *mp)
525{ 531{
526 return bhvtovfs(&mp->m_bhv); 532 return bhvtovfs(&mp->m_bhv);
527} 533}
@@ -533,7 +539,7 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
533} 539}
534 540
535#define XFS_VFSTOM(vfs) xfs_vfstom(vfs) 541#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
536static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs) 542static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
537{ 543{
538 return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); 544 return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
539} 545}
@@ -571,7 +577,7 @@ typedef struct xfs_mod_sb {
571extern xfs_mount_t *xfs_mount_init(void); 577extern xfs_mount_t *xfs_mount_init(void);
572extern void xfs_mod_sb(xfs_trans_t *, __int64_t); 578extern void xfs_mod_sb(xfs_trans_t *, __int64_t);
573extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); 579extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv);
574extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); 580extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int);
575extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); 581extern void xfs_mountfs_check_barriers(xfs_mount_t *mp);
576 582
577extern int xfs_unmountfs(xfs_mount_t *, struct cred *); 583extern int xfs_unmountfs(xfs_mount_t *, struct cred *);
@@ -589,7 +595,7 @@ extern void xfs_freesb(xfs_mount_t *);
589extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); 595extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
590extern int xfs_syncsub(xfs_mount_t *, int, int, int *); 596extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
591extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); 597extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *);
592extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *, 598extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *,
593 xfs_agnumber_t); 599 xfs_agnumber_t);
594extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); 600extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t);
595 601
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 1408a32eef88..320d63ff9ca2 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -23,7 +23,6 @@
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_ag.h" 25#include "xfs_ag.h"
26#include "xfs_dir.h"
27#include "xfs_dir2.h" 26#include "xfs_dir2.h"
28#include "xfs_dmapi.h" 27#include "xfs_dmapi.h"
29#include "xfs_mount.h" 28#include "xfs_mount.h"
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 7fbef974bce6..acb853b33ebb 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -365,7 +365,7 @@ typedef struct xfs_dqtrxops {
365extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); 365extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *);
366extern int xfs_mount_reset_sbqflags(struct xfs_mount *); 366extern int xfs_mount_reset_sbqflags(struct xfs_mount *);
367 367
368extern struct bhv_vfsops xfs_qmops; 368extern struct bhv_module_vfsops xfs_qmops;
369 369
370#endif /* __KERNEL__ */ 370#endif /* __KERNEL__ */
371 371
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 1f148762eb28..d98171deaa1c 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -22,13 +22,11 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dir2.h" 25#include "xfs_dir2.h"
27#include "xfs_dmapi.h" 26#include "xfs_dmapi.h"
28#include "xfs_mount.h" 27#include "xfs_mount.h"
29#include "xfs_da_btree.h" 28#include "xfs_da_btree.h"
30#include "xfs_bmap_btree.h" 29#include "xfs_bmap_btree.h"
31#include "xfs_dir_sf.h"
32#include "xfs_dir2_sf.h" 30#include "xfs_dir2_sf.h"
33#include "xfs_attr_sf.h" 31#include "xfs_attr_sf.h"
34#include "xfs_dinode.h" 32#include "xfs_dinode.h"
@@ -40,7 +38,6 @@
40#include "xfs_refcache.h" 38#include "xfs_refcache.h"
41#include "xfs_utils.h" 39#include "xfs_utils.h"
42#include "xfs_trans_space.h" 40#include "xfs_trans_space.h"
43#include "xfs_dir_leaf.h"
44 41
45 42
46/* 43/*
@@ -87,8 +84,8 @@ STATIC int
87xfs_lock_for_rename( 84xfs_lock_for_rename(
88 xfs_inode_t *dp1, /* old (source) directory inode */ 85 xfs_inode_t *dp1, /* old (source) directory inode */
89 xfs_inode_t *dp2, /* new (target) directory inode */ 86 xfs_inode_t *dp2, /* new (target) directory inode */
90 vname_t *vname1,/* old entry name */ 87 bhv_vname_t *vname1,/* old entry name */
91 vname_t *vname2,/* new entry name */ 88 bhv_vname_t *vname2,/* new entry name */
92 xfs_inode_t **ipp1, /* inode of old entry */ 89 xfs_inode_t **ipp1, /* inode of old entry */
93 xfs_inode_t **ipp2, /* inode of new entry, if it 90 xfs_inode_t **ipp2, /* inode of new entry, if it
94 already exists, NULL otherwise. */ 91 already exists, NULL otherwise. */
@@ -225,9 +222,9 @@ xfs_lock_for_rename(
225int 222int
226xfs_rename( 223xfs_rename(
227 bhv_desc_t *src_dir_bdp, 224 bhv_desc_t *src_dir_bdp,
228 vname_t *src_vname, 225 bhv_vname_t *src_vname,
229 vnode_t *target_dir_vp, 226 bhv_vnode_t *target_dir_vp,
230 vname_t *target_vname, 227 bhv_vname_t *target_vname,
231 cred_t *credp) 228 cred_t *credp)
232{ 229{
233 xfs_trans_t *tp; 230 xfs_trans_t *tp;
@@ -242,7 +239,7 @@ xfs_rename(
242 int committed; 239 int committed;
243 xfs_inode_t *inodes[4]; 240 xfs_inode_t *inodes[4];
244 int target_ip_dropped = 0; /* dropped target_ip link? */ 241 int target_ip_dropped = 0; /* dropped target_ip link? */
245 vnode_t *src_dir_vp; 242 bhv_vnode_t *src_dir_vp;
246 int spaceres; 243 int spaceres;
247 int target_link_zero = 0; 244 int target_link_zero = 0;
248 int num_inodes; 245 int num_inodes;
@@ -398,34 +395,29 @@ xfs_rename(
398 * fit before actually inserting it. 395 * fit before actually inserting it.
399 */ 396 */
400 if (spaceres == 0 && 397 if (spaceres == 0 &&
401 (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, 398 (error = xfs_dir_canenter(tp, target_dp, target_name,
402 target_namelen))) { 399 target_namelen)))
403 goto error_return; 400 goto error_return;
404 }
405 /* 401 /*
406 * If target does not exist and the rename crosses 402 * If target does not exist and the rename crosses
407 * directories, adjust the target directory link count 403 * directories, adjust the target directory link count
408 * to account for the ".." reference from the new entry. 404 * to account for the ".." reference from the new entry.
409 */ 405 */
410 error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name, 406 error = xfs_dir_createname(tp, target_dp, target_name,
411 target_namelen, src_ip->i_ino, 407 target_namelen, src_ip->i_ino,
412 &first_block, &free_list, spaceres); 408 &first_block, &free_list, spaceres);
413 if (error == ENOSPC) { 409 if (error == ENOSPC)
414 goto error_return; 410 goto error_return;
415 } 411 if (error)
416 if (error) {
417 goto abort_return; 412 goto abort_return;
418 }
419 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 413 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
420 414
421 if (new_parent && src_is_directory) { 415 if (new_parent && src_is_directory) {
422 error = xfs_bumplink(tp, target_dp); 416 error = xfs_bumplink(tp, target_dp);
423 if (error) { 417 if (error)
424 goto abort_return; 418 goto abort_return;
425 }
426 } 419 }
427 } else { /* target_ip != NULL */ 420 } else { /* target_ip != NULL */
428
429 /* 421 /*
430 * If target exists and it's a directory, check that both 422 * If target exists and it's a directory, check that both
431 * target and source are directories and that target can be 423 * target and source are directories and that target can be
@@ -435,7 +427,7 @@ xfs_rename(
435 /* 427 /*
436 * Make sure target dir is empty. 428 * Make sure target dir is empty.
437 */ 429 */
438 if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || 430 if (!(xfs_dir_isempty(target_ip)) ||
439 (target_ip->i_d.di_nlink > 2)) { 431 (target_ip->i_d.di_nlink > 2)) {
440 error = XFS_ERROR(EEXIST); 432 error = XFS_ERROR(EEXIST);
441 goto error_return; 433 goto error_return;
@@ -451,12 +443,11 @@ xfs_rename(
451 * In case there is already an entry with the same 443 * In case there is already an entry with the same
452 * name at the destination directory, remove it first. 444 * name at the destination directory, remove it first.
453 */ 445 */
454 error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name, 446 error = xfs_dir_replace(tp, target_dp, target_name,
455 target_namelen, src_ip->i_ino, &first_block, 447 target_namelen, src_ip->i_ino,
456 &free_list, spaceres); 448 &first_block, &free_list, spaceres);
457 if (error) { 449 if (error)
458 goto abort_return; 450 goto abort_return;
459 }
460 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 451 xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
461 452
462 /* 453 /*
@@ -464,9 +455,8 @@ xfs_rename(
464 * dir no longer points to it. 455 * dir no longer points to it.
465 */ 456 */
466 error = xfs_droplink(tp, target_ip); 457 error = xfs_droplink(tp, target_ip);
467 if (error) { 458 if (error)
468 goto abort_return; 459 goto abort_return;
469 }
470 target_ip_dropped = 1; 460 target_ip_dropped = 1;
471 461
472 if (src_is_directory) { 462 if (src_is_directory) {
@@ -474,9 +464,8 @@ xfs_rename(
474 * Drop the link from the old "." entry. 464 * Drop the link from the old "." entry.
475 */ 465 */
476 error = xfs_droplink(tp, target_ip); 466 error = xfs_droplink(tp, target_ip);
477 if (error) { 467 if (error)
478 goto abort_return; 468 goto abort_return;
479 }
480 } 469 }
481 470
482 /* Do this test while we still hold the locks */ 471 /* Do this test while we still hold the locks */
@@ -488,18 +477,15 @@ xfs_rename(
488 * Remove the source. 477 * Remove the source.
489 */ 478 */
490 if (new_parent && src_is_directory) { 479 if (new_parent && src_is_directory) {
491
492 /* 480 /*
493 * Rewrite the ".." entry to point to the new 481 * Rewrite the ".." entry to point to the new
494 * directory. 482 * directory.
495 */ 483 */
496 error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2, 484 error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino,
497 target_dp->i_ino, &first_block, 485 &first_block, &free_list, spaceres);
498 &free_list, spaceres);
499 ASSERT(error != EEXIST); 486 ASSERT(error != EEXIST);
500 if (error) { 487 if (error)
501 goto abort_return; 488 goto abort_return;
502 }
503 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 489 xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
504 490
505 } else { 491 } else {
@@ -527,16 +513,14 @@ xfs_rename(
527 * entry that's moved no longer points to it. 513 * entry that's moved no longer points to it.
528 */ 514 */
529 error = xfs_droplink(tp, src_dp); 515 error = xfs_droplink(tp, src_dp);
530 if (error) { 516 if (error)
531 goto abort_return; 517 goto abort_return;
532 }
533 } 518 }
534 519
535 error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, 520 error = xfs_dir_removename(tp, src_dp, src_name, src_namelen,
536 src_ip->i_ino, &first_block, &free_list, spaceres); 521 src_ip->i_ino, &first_block, &free_list, spaceres);
537 if (error) { 522 if (error)
538 goto abort_return; 523 goto abort_return;
539 }
540 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 524 xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
541 525
542 /* 526 /*
@@ -609,7 +593,7 @@ xfs_rename(
609 * Let interposed file systems know about removed links. 593 * Let interposed file systems know about removed links.
610 */ 594 */
611 if (target_ip_dropped) { 595 if (target_ip_dropped) {
612 VOP_LINK_REMOVED(XFS_ITOV(target_ip), target_dir_vp, 596 bhv_vop_link_removed(XFS_ITOV(target_ip), target_dir_vp,
613 target_link_zero); 597 target_link_zero);
614 IRELE(target_ip); 598 IRELE(target_ip);
615 } 599 }
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 5b413946b1c5..0c1e42b037ef 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -141,7 +139,7 @@ xfs_growfs_rt_alloc(
141 cancelflags |= XFS_TRANS_ABORT; 139 cancelflags |= XFS_TRANS_ABORT;
142 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks, 140 error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
143 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, 141 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
144 resblks, &map, &nmap, &flist); 142 resblks, &map, &nmap, &flist, NULL);
145 if (!error && nmap < 1) 143 if (!error && nmap < 1)
146 error = XFS_ERROR(ENOSPC); 144 error = XFS_ERROR(ENOSPC);
147 if (error) 145 if (error)
@@ -2404,10 +2402,10 @@ xfs_rtprint_range(
2404{ 2402{
2405 xfs_extlen_t i; /* block number in the extent */ 2403 xfs_extlen_t i; /* block number in the extent */
2406 2404
2407 printk("%Ld: ", (long long)start); 2405 cmn_err(CE_DEBUG, "%Ld: ", (long long)start);
2408 for (i = 0; i < len; i++) 2406 for (i = 0; i < len; i++)
2409 printk("%d", xfs_rtcheck_bit(mp, tp, start + i, 1)); 2407 cmn_err(CE_DEBUG, "%d", xfs_rtcheck_bit(mp, tp, start + i, 1));
2410 printk("\n"); 2408 cmn_err(CE_DEBUG, "\n");
2411} 2409}
2412 2410
2413/* 2411/*
@@ -2431,17 +2429,17 @@ xfs_rtprint_summary(
2431 (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c); 2429 (void)xfs_rtget_summary(mp, tp, l, i, &sumbp, &sb, &c);
2432 if (c) { 2430 if (c) {
2433 if (!p) { 2431 if (!p) {
2434 printk("%Ld-%Ld:", 1LL << l, 2432 cmn_err(CE_DEBUG, "%Ld-%Ld:", 1LL << l,
2435 XFS_RTMIN((1LL << l) + 2433 XFS_RTMIN((1LL << l) +
2436 ((1LL << l) - 1LL), 2434 ((1LL << l) - 1LL),
2437 mp->m_sb.sb_rextents)); 2435 mp->m_sb.sb_rextents));
2438 p = 1; 2436 p = 1;
2439 } 2437 }
2440 printk(" %Ld:%d", (long long)i, c); 2438 cmn_err(CE_DEBUG, " %Ld:%d", (long long)i, c);
2441 } 2439 }
2442 } 2440 }
2443 if (p) 2441 if (p)
2444 printk("\n"); 2442 cmn_err(CE_DEBUG, "\n");
2445 } 2443 }
2446 if (sumbp) 2444 if (sumbp)
2447 xfs_trans_brelse(tp, sumbp); 2445 xfs_trans_brelse(tp, sumbp);
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index a59c102cf214..defb2febaaf5 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -92,6 +90,90 @@ xfs_write_clear_setuid(
92} 90}
93 91
94/* 92/*
93 * Handle logging requirements of various synchronous types of write.
94 */
95int
96xfs_write_sync_logforce(
97 xfs_mount_t *mp,
98 xfs_inode_t *ip)
99{
100 int error = 0;
101
102 /*
103 * If we're treating this as O_DSYNC and we have not updated the
104 * size, force the log.
105 */
106 if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
107 !(ip->i_update_size)) {
108 xfs_inode_log_item_t *iip = ip->i_itemp;
109
110 /*
111 * If an allocation transaction occurred
112 * without extending the size, then we have to force
113 * the log up the proper point to ensure that the
114 * allocation is permanent. We can't count on
115 * the fact that buffered writes lock out direct I/O
116 * writes - the direct I/O write could have extended
117 * the size nontransactionally, then finished before
118 * we started. xfs_write_file will think that the file
119 * didn't grow but the update isn't safe unless the
120 * size change is logged.
121 *
122 * Force the log if we've committed a transaction
123 * against the inode or if someone else has and
124 * the commit record hasn't gone to disk (e.g.
125 * the inode is pinned). This guarantees that
126 * all changes affecting the inode are permanent
127 * when we return.
128 */
129 if (iip && iip->ili_last_lsn) {
130 xfs_log_force(mp, iip->ili_last_lsn,
131 XFS_LOG_FORCE | XFS_LOG_SYNC);
132 } else if (xfs_ipincount(ip) > 0) {
133 xfs_log_force(mp, (xfs_lsn_t)0,
134 XFS_LOG_FORCE | XFS_LOG_SYNC);
135 }
136
137 } else {
138 xfs_trans_t *tp;
139
140 /*
141 * O_SYNC or O_DSYNC _with_ a size update are handled
142 * the same way.
143 *
144 * If the write was synchronous then we need to make
145 * sure that the inode modification time is permanent.
146 * We'll have updated the timestamp above, so here
147 * we use a synchronous transaction to log the inode.
148 * It's not fast, but it's necessary.
149 *
150 * If this a dsync write and the size got changed
151 * non-transactionally, then we need to ensure that
152 * the size change gets logged in a synchronous
153 * transaction.
154 */
155 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
156 if ((error = xfs_trans_reserve(tp, 0,
157 XFS_SWRITE_LOG_RES(mp),
158 0, 0, 0))) {
159 /* Transaction reserve failed */
160 xfs_trans_cancel(tp, 0);
161 } else {
162 /* Transaction reserve successful */
163 xfs_ilock(ip, XFS_ILOCK_EXCL);
164 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
165 xfs_trans_ihold(tp, ip);
166 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
167 xfs_trans_set_sync(tp);
168 error = xfs_trans_commit(tp, 0, NULL);
169 xfs_iunlock(ip, XFS_ILOCK_EXCL);
170 }
171 }
172
173 return error;
174}
175
176/*
95 * Force a shutdown of the filesystem instantly while keeping 177 * Force a shutdown of the filesystem instantly while keeping
96 * the filesystem consistent. We don't do an unmount here; just shutdown 178 * the filesystem consistent. We don't do an unmount here; just shutdown
97 * the shop, make sure that absolutely nothing persistent happens to 179 * the shop, make sure that absolutely nothing persistent happens to
@@ -109,12 +191,12 @@ xfs_do_force_shutdown(
109 xfs_mount_t *mp; 191 xfs_mount_t *mp;
110 192
111 mp = XFS_BHVTOM(bdp); 193 mp = XFS_BHVTOM(bdp);
112 logerror = flags & XFS_LOG_IO_ERROR; 194 logerror = flags & SHUTDOWN_LOG_IO_ERROR;
113 195
114 if (!(flags & XFS_FORCE_UMOUNT)) { 196 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
115 cmn_err(CE_NOTE, 197 cmn_err(CE_NOTE, "xfs_force_shutdown(%s,0x%x) called from "
116 "xfs_force_shutdown(%s,0x%x) called from line %d of file %s. Return address = 0x%p", 198 "line %d of file %s. Return address = 0x%p",
117 mp->m_fsname,flags,lnnum,fname,__return_address); 199 mp->m_fsname, flags, lnnum, fname, __return_address);
118 } 200 }
119 /* 201 /*
120 * No need to duplicate efforts. 202 * No need to duplicate efforts.
@@ -125,33 +207,37 @@ xfs_do_force_shutdown(
125 /* 207 /*
126 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't 208 * This flags XFS_MOUNT_FS_SHUTDOWN, makes sure that we don't
127 * queue up anybody new on the log reservations, and wakes up 209 * queue up anybody new on the log reservations, and wakes up
128 * everybody who's sleeping on log reservations and tells 210 * everybody who's sleeping on log reservations to tell them
129 * them the bad news. 211 * the bad news.
130 */ 212 */
131 if (xfs_log_force_umount(mp, logerror)) 213 if (xfs_log_force_umount(mp, logerror))
132 return; 214 return;
133 215
134 if (flags & XFS_CORRUPT_INCORE) { 216 if (flags & SHUTDOWN_CORRUPT_INCORE) {
135 xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp, 217 xfs_cmn_err(XFS_PTAG_SHUTDOWN_CORRUPT, CE_ALERT, mp,
136 "Corruption of in-memory data detected. Shutting down filesystem: %s", 218 "Corruption of in-memory data detected. Shutting down filesystem: %s",
137 mp->m_fsname); 219 mp->m_fsname);
138 if (XFS_ERRLEVEL_HIGH <= xfs_error_level) { 220 if (XFS_ERRLEVEL_HIGH <= xfs_error_level) {
139 xfs_stack_trace(); 221 xfs_stack_trace();
140 } 222 }
141 } else if (!(flags & XFS_FORCE_UMOUNT)) { 223 } else if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
142 if (logerror) { 224 if (logerror) {
143 xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp, 225 xfs_cmn_err(XFS_PTAG_SHUTDOWN_LOGERROR, CE_ALERT, mp,
144 "Log I/O Error Detected. Shutting down filesystem: %s", 226 "Log I/O Error Detected. Shutting down filesystem: %s",
227 mp->m_fsname);
228 } else if (flags & SHUTDOWN_DEVICE_REQ) {
229 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
230 "All device paths lost. Shutting down filesystem: %s",
145 mp->m_fsname); 231 mp->m_fsname);
146 } else if (!(flags & XFS_SHUTDOWN_REMOTE_REQ)) { 232 } else if (!(flags & SHUTDOWN_REMOTE_REQ)) {
147 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp, 233 xfs_cmn_err(XFS_PTAG_SHUTDOWN_IOERROR, CE_ALERT, mp,
148 "I/O Error Detected. Shutting down filesystem: %s", 234 "I/O Error Detected. Shutting down filesystem: %s",
149 mp->m_fsname); 235 mp->m_fsname);
150 } 236 }
151 } 237 }
152 if (!(flags & XFS_FORCE_UMOUNT)) { 238 if (!(flags & SHUTDOWN_FORCE_UMOUNT)) {
153 cmn_err(CE_ALERT, 239 cmn_err(CE_ALERT, "Please umount the filesystem, "
154 "Please umount the filesystem, and rectify the problem(s)"); 240 "and rectify the problem(s)");
155 } 241 }
156} 242}
157 243
@@ -335,7 +421,7 @@ xfs_bwrite(
335 * from bwrite and we could be tracing a buffer that has 421 * from bwrite and we could be tracing a buffer that has
336 * been reused. 422 * been reused.
337 */ 423 */
338 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 424 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
339 } 425 }
340 return (error); 426 return (error);
341} 427}
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index e63795644478..188b296ff50c 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -75,6 +75,7 @@ xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb)
75 * Prototypes for functions in xfs_rw.c. 75 * Prototypes for functions in xfs_rw.c.
76 */ 76 */
77extern int xfs_write_clear_setuid(struct xfs_inode *ip); 77extern int xfs_write_clear_setuid(struct xfs_inode *ip);
78extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);
78extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); 79extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
79extern int xfs_bioerror(struct xfs_buf *bp); 80extern int xfs_bioerror(struct xfs_buf *bp);
80extern int xfs_bioerror_relse(struct xfs_buf *bp); 81extern int xfs_bioerror_relse(struct xfs_buf *bp);
@@ -87,9 +88,10 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
87/* 88/*
88 * Prototypes for functions in xfs_vnodeops.c. 89 * Prototypes for functions in xfs_vnodeops.c.
89 */ 90 */
90extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock); 91extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
91extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock); 92extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock);
92extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp); 93extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags,
94 cred_t *credp);
93extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, 95extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
94 xfs_off_t offset, cred_t *credp, int flags); 96 xfs_off_t offset, cred_t *credp, int flags);
95extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, 97extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 8d056cef5d1f..ee2721e0de4d 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -33,7 +32,6 @@
33#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
36#include "xfs_dir_sf.h"
37#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
38#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
39#include "xfs_dinode.h" 37#include "xfs_dinode.h"
@@ -236,11 +234,8 @@ xfs_trans_alloc(
236 xfs_mount_t *mp, 234 xfs_mount_t *mp,
237 uint type) 235 uint type)
238{ 236{
239 fs_check_frozen(XFS_MTOVFS(mp), SB_FREEZE_TRANS); 237 vfs_wait_for_freeze(XFS_MTOVFS(mp), SB_FREEZE_TRANS);
240 atomic_inc(&mp->m_active_trans); 238 return _xfs_trans_alloc(mp, type);
241
242 return (_xfs_trans_alloc(mp, type));
243
244} 239}
245 240
246xfs_trans_t * 241xfs_trans_t *
@@ -250,12 +245,9 @@ _xfs_trans_alloc(
250{ 245{
251 xfs_trans_t *tp; 246 xfs_trans_t *tp;
252 247
253 ASSERT(xfs_trans_zone != NULL); 248 atomic_inc(&mp->m_active_trans);
254 tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
255 249
256 /* 250 tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
257 * Initialize the transaction structure.
258 */
259 tp->t_magic = XFS_TRANS_MAGIC; 251 tp->t_magic = XFS_TRANS_MAGIC;
260 tp->t_type = type; 252 tp->t_type = type;
261 tp->t_mountp = mp; 253 tp->t_mountp = mp;
@@ -263,8 +255,7 @@ _xfs_trans_alloc(
263 tp->t_busy_free = XFS_LBC_NUM_SLOTS; 255 tp->t_busy_free = XFS_LBC_NUM_SLOTS;
264 XFS_LIC_INIT(&(tp->t_items)); 256 XFS_LIC_INIT(&(tp->t_items));
265 XFS_LBC_INIT(&(tp->t_busy)); 257 XFS_LBC_INIT(&(tp->t_busy));
266 258 return tp;
267 return (tp);
268} 259}
269 260
270/* 261/*
@@ -303,7 +294,7 @@ xfs_trans_dup(
303 tp->t_blk_res = tp->t_blk_res_used; 294 tp->t_blk_res = tp->t_blk_res_used;
304 ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used; 295 ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
305 tp->t_rtx_res = tp->t_rtx_res_used; 296 tp->t_rtx_res = tp->t_rtx_res_used;
306 PFLAGS_DUP(&tp->t_pflags, &ntp->t_pflags); 297 ntp->t_pflags = tp->t_pflags;
307 298
308 XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp); 299 XFS_TRANS_DUP_DQINFO(tp->t_mountp, tp, ntp);
309 300
@@ -335,14 +326,11 @@ xfs_trans_reserve(
335 uint logcount) 326 uint logcount)
336{ 327{
337 int log_flags; 328 int log_flags;
338 int error; 329 int error = 0;
339 int rsvd; 330 int rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
340
341 error = 0;
342 rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
343 331
344 /* Mark this thread as being in a transaction */ 332 /* Mark this thread as being in a transaction */
345 PFLAGS_SET_FSTRANS(&tp->t_pflags); 333 current_set_flags_nested(&tp->t_pflags, PF_FSTRANS);
346 334
347 /* 335 /*
348 * Attempt to reserve the needed disk blocks by decrementing 336 * Attempt to reserve the needed disk blocks by decrementing
@@ -353,7 +341,7 @@ xfs_trans_reserve(
353 error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, 341 error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS,
354 -blocks, rsvd); 342 -blocks, rsvd);
355 if (error != 0) { 343 if (error != 0) {
356 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 344 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
357 return (XFS_ERROR(ENOSPC)); 345 return (XFS_ERROR(ENOSPC));
358 } 346 }
359 tp->t_blk_res += blocks; 347 tp->t_blk_res += blocks;
@@ -426,9 +414,9 @@ undo_blocks:
426 tp->t_blk_res = 0; 414 tp->t_blk_res = 0;
427 } 415 }
428 416
429 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 417 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
430 418
431 return (error); 419 return error;
432} 420}
433 421
434 422
@@ -819,7 +807,7 @@ shut_us_down:
819 if (commit_lsn == -1 && !shutdown) 807 if (commit_lsn == -1 && !shutdown)
820 shutdown = XFS_ERROR(EIO); 808 shutdown = XFS_ERROR(EIO);
821 } 809 }
822 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 810 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
823 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0); 811 xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0);
824 xfs_trans_free_busy(tp); 812 xfs_trans_free_busy(tp);
825 xfs_trans_free(tp); 813 xfs_trans_free(tp);
@@ -846,7 +834,7 @@ shut_us_down:
846 */ 834 */
847 nvec = xfs_trans_count_vecs(tp); 835 nvec = xfs_trans_count_vecs(tp);
848 if (nvec == 0) { 836 if (nvec == 0) {
849 xfs_force_shutdown(mp, XFS_LOG_IO_ERROR); 837 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
850 goto shut_us_down; 838 goto shut_us_down;
851 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) { 839 } else if (nvec <= XFS_TRANS_LOGVEC_COUNT) {
852 log_vector = log_vector_fast; 840 log_vector = log_vector_fast;
@@ -884,7 +872,7 @@ shut_us_down:
884 * had pinned, clean up, free trans structure, and return error. 872 * had pinned, clean up, free trans structure, and return error.
885 */ 873 */
886 if (error || commit_lsn == -1) { 874 if (error || commit_lsn == -1) {
887 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 875 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
888 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT); 876 xfs_trans_uncommit(tp, flags|XFS_TRANS_ABORT);
889 return XFS_ERROR(EIO); 877 return XFS_ERROR(EIO);
890 } 878 }
@@ -926,7 +914,7 @@ shut_us_down:
926 /* 914 /*
927 * Mark this thread as no longer being in a transaction 915 * Mark this thread as no longer being in a transaction
928 */ 916 */
929 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 917 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
930 918
931 /* 919 /*
932 * Once all the items of the transaction have been copied 920 * Once all the items of the transaction have been copied
@@ -1148,7 +1136,7 @@ xfs_trans_cancel(
1148 */ 1136 */
1149 if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) { 1137 if ((tp->t_flags & XFS_TRANS_DIRTY) && !XFS_FORCED_SHUTDOWN(mp)) {
1150 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp); 1138 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
1151 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 1139 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1152 } 1140 }
1153#ifdef DEBUG 1141#ifdef DEBUG
1154 if (!(flags & XFS_TRANS_ABORT)) { 1142 if (!(flags & XFS_TRANS_ABORT)) {
@@ -1182,7 +1170,7 @@ xfs_trans_cancel(
1182 } 1170 }
1183 1171
1184 /* mark this thread as no longer being in a transaction */ 1172 /* mark this thread as no longer being in a transaction */
1185 PFLAGS_RESTORE_FSTRANS(&tp->t_pflags); 1173 current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
1186 1174
1187 xfs_trans_free_items(tp, flags); 1175 xfs_trans_free_items(tp, flags);
1188 xfs_trans_free_busy(tp); 1176 xfs_trans_free_busy(tp);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 100d9a4b38ee..cb65c3a603f5 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -805,12 +805,9 @@ typedef struct xfs_trans {
805 ((mp)->m_sb.sb_inodesize + \ 805 ((mp)->m_sb.sb_inodesize + \
806 (mp)->m_sb.sb_sectsize * 2 + \ 806 (mp)->m_sb.sb_sectsize * 2 + \
807 (mp)->m_dirblksize + \ 807 (mp)->m_dirblksize + \
808 (XFS_DIR_IS_V1(mp) ? 0 : \ 808 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \
809 XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \
810 XFS_ALLOCFREE_LOG_RES(mp, 1) + \ 809 XFS_ALLOCFREE_LOG_RES(mp, 1) + \
811 (128 * (4 + \ 810 (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
812 (XFS_DIR_IS_V1(mp) ? 0 : \
813 XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \
814 XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) 811 XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
815 812
816#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) 813#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 19ab24af1c1c..558c87ff0c41 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -22,7 +22,6 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dmapi.h" 25#include "xfs_dmapi.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_trans_priv.h" 27#include "xfs_trans_priv.h"
@@ -363,9 +362,10 @@ xfs_trans_delete_ail(
363 AIL_UNLOCK(mp, s); 362 AIL_UNLOCK(mp, s);
364 else { 363 else {
365 xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, 364 xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp,
366 "xfs_trans_delete_ail: attempting to delete a log item that is not in the AIL"); 365 "%s: attempting to delete a log item that is not in the AIL",
366 __FUNCTION__);
367 AIL_UNLOCK(mp, s); 367 AIL_UNLOCK(mp, s);
368 xfs_force_shutdown(mp, XFS_CORRUPT_INCORE); 368 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
369 } 369 }
370 } 370 }
371} 371}
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index c74c31ebc81c..60b6b898022b 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -320,7 +318,7 @@ xfs_trans_read_buf(
320 if (xfs_error_target == target) { 318 if (xfs_error_target == target) {
321 if (((xfs_req_num++) % xfs_error_mod) == 0) { 319 if (((xfs_req_num++) % xfs_error_mod) == 0) {
322 xfs_buf_relse(bp); 320 xfs_buf_relse(bp);
323 printk("Returning error!\n"); 321 cmn_err(CE_DEBUG, "Returning error!\n");
324 return XFS_ERROR(EIO); 322 return XFS_ERROR(EIO);
325 } 323 }
326 } 324 }
@@ -369,7 +367,7 @@ xfs_trans_read_buf(
369 */ 367 */
370 if (tp->t_flags & XFS_TRANS_DIRTY) 368 if (tp->t_flags & XFS_TRANS_DIRTY)
371 xfs_force_shutdown(tp->t_mountp, 369 xfs_force_shutdown(tp->t_mountp,
372 XFS_METADATA_IO_ERROR); 370 SHUTDOWN_META_IO_ERROR);
373 return error; 371 return error;
374 } 372 }
375 } 373 }
@@ -414,7 +412,7 @@ xfs_trans_read_buf(
414 xfs_ioerror_alert("xfs_trans_read_buf", mp, 412 xfs_ioerror_alert("xfs_trans_read_buf", mp,
415 bp, blkno); 413 bp, blkno);
416 if (tp->t_flags & XFS_TRANS_DIRTY) 414 if (tp->t_flags & XFS_TRANS_DIRTY)
417 xfs_force_shutdown(tp->t_mountp, XFS_METADATA_IO_ERROR); 415 xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
418 xfs_buf_relse(bp); 416 xfs_buf_relse(bp);
419 return error; 417 return error;
420 } 418 }
@@ -423,9 +421,9 @@ xfs_trans_read_buf(
423 if (xfs_error_target == target) { 421 if (xfs_error_target == target) {
424 if (((xfs_req_num++) % xfs_error_mod) == 0) { 422 if (((xfs_req_num++) % xfs_error_mod) == 0) {
425 xfs_force_shutdown(tp->t_mountp, 423 xfs_force_shutdown(tp->t_mountp,
426 XFS_METADATA_IO_ERROR); 424 SHUTDOWN_META_IO_ERROR);
427 xfs_buf_relse(bp); 425 xfs_buf_relse(bp);
428 printk("Returning error in trans!\n"); 426 cmn_err(CE_DEBUG, "Returning trans error!\n");
429 return XFS_ERROR(EIO); 427 return XFS_ERROR(EIO);
430 } 428 }
431 } 429 }
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index 7d7d627f25df..b290270dd4a6 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -22,7 +22,6 @@
22#include "xfs_inum.h" 22#include "xfs_inum.h"
23#include "xfs_trans.h" 23#include "xfs_trans.h"
24#include "xfs_sb.h" 24#include "xfs_sb.h"
25#include "xfs_dir.h"
26#include "xfs_dmapi.h" 25#include "xfs_dmapi.h"
27#include "xfs_mount.h" 26#include "xfs_mount.h"
28#include "xfs_trans_priv.h" 27#include "xfs_trans_priv.h"
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 7c5894d59f81..b8db1d5cde5a 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c
index 1117d600d741..2912aac07c7b 100644
--- a/fs/xfs/xfs_trans_item.c
+++ b/fs/xfs/xfs_trans_item.c
@@ -493,7 +493,7 @@ xfs_trans_add_busy(xfs_trans_t *tp, xfs_agnumber_t ag, xfs_extlen_t idx)
493 break; 493 break;
494 } else { 494 } else {
495 /* out-of-order vacancy */ 495 /* out-of-order vacancy */
496 printk("OOO vacancy lbcp 0x%p\n", lbcp); 496 cmn_err(CE_DEBUG, "OOO vacancy lbcp 0x%p\n", lbcp);
497 ASSERT(0); 497 ASSERT(0);
498 } 498 }
499 } 499 }
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h
index 7fe3792b18df..4ea2e5074bdd 100644
--- a/fs/xfs/xfs_trans_space.h
+++ b/fs/xfs/xfs_trans_space.h
@@ -30,8 +30,7 @@
30 XFS_EXTENTADD_SPACE_RES(mp,w)) 30 XFS_EXTENTADD_SPACE_RES(mp,w))
31#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) 31#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1)
32#define XFS_DAENTER_DBS(mp,w) \ 32#define XFS_DAENTER_DBS(mp,w) \
33 (XFS_DA_NODE_MAXDEPTH + \ 33 (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))
34 ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0))
35#define XFS_DAENTER_BLOCKS(mp,w) \ 34#define XFS_DAENTER_BLOCKS(mp,w) \
36 (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) 35 (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w))
37#define XFS_DAENTER_BMAP1B(mp,w) \ 36#define XFS_DAENTER_BMAP1B(mp,w) \
@@ -41,10 +40,7 @@
41#define XFS_DAENTER_SPACE_RES(mp,w) \ 40#define XFS_DAENTER_SPACE_RES(mp,w) \
42 (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) 41 (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w))
43#define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) 42#define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w)
44#define XFS_DIRENTER_MAX_SPLIT(mp,nl) \ 43#define XFS_DIRENTER_MAX_SPLIT(mp,nl) 1
45 (((mp)->m_sb.sb_blocksize == 512 && \
46 XFS_DIR_IS_V1(mp) && \
47 (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1)
48#define XFS_DIRENTER_SPACE_RES(mp,nl) \ 44#define XFS_DIRENTER_SPACE_RES(mp,nl) \
49 (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ 45 (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \
50 XFS_DIRENTER_MAX_SPLIT(mp,nl)) 46 XFS_DIRENTER_MAX_SPLIT(mp,nl))
@@ -57,8 +53,7 @@
57 * Space reservation values for various transactions. 53 * Space reservation values for various transactions.
58 */ 54 */
59#define XFS_ADDAFORK_SPACE_RES(mp) \ 55#define XFS_ADDAFORK_SPACE_RES(mp) \
60 ((mp)->m_dirblkfsbs + \ 56 ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
61 (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)))
62#define XFS_ATTRRM_SPACE_RES(mp) \ 57#define XFS_ATTRRM_SPACE_RES(mp) \
63 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) 58 XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
64/* This macro is not used - see inline code in xfs_attr_set */ 59/* This macro is not used - see inline code in xfs_attr_set */
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 34654ec6ae10..9014d7e44488 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -24,12 +24,10 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_dir_sf.h"
33#include "xfs_dir2_sf.h" 31#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h" 32#include "xfs_attr_sf.h"
35#include "xfs_dinode.h" 33#include "xfs_dinode.h"
@@ -51,10 +49,10 @@
51 */ 49 */
52int 50int
53xfs_get_dir_entry( 51xfs_get_dir_entry(
54 vname_t *dentry, 52 bhv_vname_t *dentry,
55 xfs_inode_t **ipp) 53 xfs_inode_t **ipp)
56{ 54{
57 vnode_t *vp; 55 bhv_vnode_t *vp;
58 56
59 vp = VNAME_TO_VNODE(dentry); 57 vp = VNAME_TO_VNODE(dentry);
60 58
@@ -69,11 +67,11 @@ int
69xfs_dir_lookup_int( 67xfs_dir_lookup_int(
70 bhv_desc_t *dir_bdp, 68 bhv_desc_t *dir_bdp,
71 uint lock_mode, 69 uint lock_mode,
72 vname_t *dentry, 70 bhv_vname_t *dentry,
73 xfs_ino_t *inum, 71 xfs_ino_t *inum,
74 xfs_inode_t **ipp) 72 xfs_inode_t **ipp)
75{ 73{
76 vnode_t *dir_vp; 74 bhv_vnode_t *dir_vp;
77 xfs_inode_t *dp; 75 xfs_inode_t *dp;
78 int error; 76 int error;
79 77
@@ -82,8 +80,7 @@ xfs_dir_lookup_int(
82 80
83 dp = XFS_BHVTOI(dir_bdp); 81 dp = XFS_BHVTOI(dir_bdp);
84 82
85 error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp, 83 error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum);
86 VNAME(dentry), VNAMELEN(dentry), inum);
87 if (!error) { 84 if (!error) {
88 /* 85 /*
89 * Unlock the directory. We do this because we can't 86 * Unlock the directory. We do this because we can't
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h
index 472661a3b6d8..fe953e98afa7 100644
--- a/fs/xfs/xfs_utils.h
+++ b/fs/xfs/xfs_utils.h
@@ -23,9 +23,10 @@
23#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \ 23#define ITRACE(ip) vn_trace_ref(XFS_ITOV(ip), __FILE__, __LINE__, \
24 (inst_t *)__return_address) 24 (inst_t *)__return_address)
25 25
26extern int xfs_rename (bhv_desc_t *, vname_t *, vnode_t *, vname_t *, cred_t *); 26extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
27extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); 27 bhv_vname_t *, cred_t *);
28extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, 28extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **);
29extern int xfs_dir_lookup_int (bhv_desc_t *, uint, bhv_vname_t *, xfs_ino_t *,
29 xfs_inode_t **); 30 xfs_inode_t **);
30extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); 31extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *);
31extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, 32extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t,
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 36ea1b2094f2..6c96391f3f1a 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -24,7 +24,6 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
@@ -32,7 +31,6 @@
32#include "xfs_bmap_btree.h" 31#include "xfs_bmap_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
35#include "xfs_dir_sf.h"
36#include "xfs_dir2_sf.h" 34#include "xfs_dir2_sf.h"
37#include "xfs_attr_sf.h" 35#include "xfs_attr_sf.h"
38#include "xfs_dinode.h" 36#include "xfs_dinode.h"
@@ -131,9 +129,6 @@ xfs_init(void)
131#ifdef XFS_BMBT_TRACE 129#ifdef XFS_BMBT_TRACE
132 xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP); 130 xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP);
133#endif 131#endif
134#ifdef XFS_DIR_TRACE
135 xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP);
136#endif
137#ifdef XFS_ATTR_TRACE 132#ifdef XFS_ATTR_TRACE
138 xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP); 133 xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP);
139#endif 134#endif
@@ -177,9 +172,6 @@ xfs_cleanup(void)
177#ifdef XFS_ATTR_TRACE 172#ifdef XFS_ATTR_TRACE
178 ktrace_free(xfs_attr_trace_buf); 173 ktrace_free(xfs_attr_trace_buf);
179#endif 174#endif
180#ifdef XFS_DIR_TRACE
181 ktrace_free(xfs_dir_trace_buf);
182#endif
183#ifdef XFS_BMBT_TRACE 175#ifdef XFS_BMBT_TRACE
184 ktrace_free(xfs_bmbt_trace_buf); 176 ktrace_free(xfs_bmbt_trace_buf);
185#endif 177#endif
@@ -212,7 +204,7 @@ xfs_cleanup(void)
212 */ 204 */
213STATIC int 205STATIC int
214xfs_start_flags( 206xfs_start_flags(
215 struct vfs *vfs, 207 struct bhv_vfs *vfs,
216 struct xfs_mount_args *ap, 208 struct xfs_mount_args *ap,
217 struct xfs_mount *mp) 209 struct xfs_mount *mp)
218{ 210{
@@ -337,7 +329,7 @@ xfs_start_flags(
337 */ 329 */
338STATIC int 330STATIC int
339xfs_finish_flags( 331xfs_finish_flags(
340 struct vfs *vfs, 332 struct bhv_vfs *vfs,
341 struct xfs_mount_args *ap, 333 struct xfs_mount_args *ap,
342 struct xfs_mount *mp) 334 struct xfs_mount *mp)
343{ 335{
@@ -423,7 +415,7 @@ xfs_mount(
423 struct xfs_mount_args *args, 415 struct xfs_mount_args *args,
424 cred_t *credp) 416 cred_t *credp)
425{ 417{
426 struct vfs *vfsp = bhvtovfs(bhvp); 418 struct bhv_vfs *vfsp = bhvtovfs(bhvp);
427 struct bhv_desc *p; 419 struct bhv_desc *p;
428 struct xfs_mount *mp = XFS_BHVTOM(bhvp); 420 struct xfs_mount *mp = XFS_BHVTOM(bhvp);
429 struct block_device *ddev, *logdev, *rtdev; 421 struct block_device *ddev, *logdev, *rtdev;
@@ -552,10 +544,10 @@ xfs_unmount(
552 int flags, 544 int flags,
553 cred_t *credp) 545 cred_t *credp)
554{ 546{
555 struct vfs *vfsp = bhvtovfs(bdp); 547 bhv_vfs_t *vfsp = bhvtovfs(bdp);
556 xfs_mount_t *mp = XFS_BHVTOM(bdp); 548 xfs_mount_t *mp = XFS_BHVTOM(bdp);
557 xfs_inode_t *rip; 549 xfs_inode_t *rip;
558 vnode_t *rvp; 550 bhv_vnode_t *rvp;
559 int unmount_event_wanted = 0; 551 int unmount_event_wanted = 0;
560 int unmount_event_flags = 0; 552 int unmount_event_flags = 0;
561 int xfs_unmountfs_needed = 0; 553 int xfs_unmountfs_needed = 0;
@@ -665,9 +657,8 @@ xfs_mntupdate(
665 int *flags, 657 int *flags,
666 struct xfs_mount_args *args) 658 struct xfs_mount_args *args)
667{ 659{
668 struct vfs *vfsp = bhvtovfs(bdp); 660 bhv_vfs_t *vfsp = bhvtovfs(bdp);
669 xfs_mount_t *mp = XFS_BHVTOM(bdp); 661 xfs_mount_t *mp = XFS_BHVTOM(bdp);
670 int error;
671 662
672 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ 663 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */
673 if (vfsp->vfs_flag & VFS_RDONLY) 664 if (vfsp->vfs_flag & VFS_RDONLY)
@@ -679,7 +670,7 @@ xfs_mntupdate(
679 mp->m_flags &= ~XFS_MOUNT_BARRIER; 670 mp->m_flags &= ~XFS_MOUNT_BARRIER;
680 } 671 }
681 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ 672 } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */
682 VFS_SYNC(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL, error); 673 bhv_vfs_sync(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL);
683 xfs_quiesce_fs(mp); 674 xfs_quiesce_fs(mp);
684 xfs_log_unmount_write(mp); 675 xfs_log_unmount_write(mp);
685 xfs_unmountfs_writesb(mp); 676 xfs_unmountfs_writesb(mp);
@@ -702,7 +693,7 @@ xfs_unmount_flush(
702 xfs_inode_t *rip = mp->m_rootip; 693 xfs_inode_t *rip = mp->m_rootip;
703 xfs_inode_t *rbmip; 694 xfs_inode_t *rbmip;
704 xfs_inode_t *rsumip = NULL; 695 xfs_inode_t *rsumip = NULL;
705 vnode_t *rvp = XFS_ITOV(rip); 696 bhv_vnode_t *rvp = XFS_ITOV(rip);
706 int error; 697 int error;
707 698
708 xfs_ilock(rip, XFS_ILOCK_EXCL); 699 xfs_ilock(rip, XFS_ILOCK_EXCL);
@@ -781,9 +772,9 @@ fscorrupt_out2:
781STATIC int 772STATIC int
782xfs_root( 773xfs_root(
783 bhv_desc_t *bdp, 774 bhv_desc_t *bdp,
784 vnode_t **vpp) 775 bhv_vnode_t **vpp)
785{ 776{
786 vnode_t *vp; 777 bhv_vnode_t *vp;
787 778
788 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip); 779 vp = XFS_ITOV((XFS_BHVTOM(bdp))->m_rootip);
789 VN_HOLD(vp); 780 VN_HOLD(vp);
@@ -801,8 +792,8 @@ xfs_root(
801STATIC int 792STATIC int
802xfs_statvfs( 793xfs_statvfs(
803 bhv_desc_t *bdp, 794 bhv_desc_t *bdp,
804 xfs_statfs_t *statp, 795 bhv_statvfs_t *statp,
805 vnode_t *vp) 796 bhv_vnode_t *vp)
806{ 797{
807 __uint64_t fakeinos; 798 __uint64_t fakeinos;
808 xfs_extlen_t lsize; 799 xfs_extlen_t lsize;
@@ -900,7 +891,7 @@ xfs_sync(
900/* 891/*
901 * xfs sync routine for internal use 892 * xfs sync routine for internal use
902 * 893 *
903 * This routine supports all of the flags defined for the generic VFS_SYNC 894 * This routine supports all of the flags defined for the generic vfs_sync
904 * interface as explained above under xfs_sync. In the interests of not 895 * interface as explained above under xfs_sync. In the interests of not
905 * changing interfaces within the 6.5 family, additional internally- 896 * changing interfaces within the 6.5 family, additional internally-
906 * required functions are specified within a separate xflags parameter, 897 * required functions are specified within a separate xflags parameter,
@@ -917,7 +908,7 @@ xfs_sync_inodes(
917 xfs_inode_t *ip = NULL; 908 xfs_inode_t *ip = NULL;
918 xfs_inode_t *ip_next; 909 xfs_inode_t *ip_next;
919 xfs_buf_t *bp; 910 xfs_buf_t *bp;
920 vnode_t *vp = NULL; 911 bhv_vnode_t *vp = NULL;
921 int error; 912 int error;
922 int last_error; 913 int last_error;
923 uint64_t fflag; 914 uint64_t fflag;
@@ -1156,9 +1147,9 @@ xfs_sync_inodes(
1156 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1147 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1157 1148
1158 if (XFS_FORCED_SHUTDOWN(mp)) { 1149 if (XFS_FORCED_SHUTDOWN(mp)) {
1159 VOP_TOSS_PAGES(vp, 0, -1, FI_REMAPF); 1150 bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF);
1160 } else { 1151 } else {
1161 VOP_FLUSHINVAL_PAGES(vp, 0, -1, FI_REMAPF); 1152 bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF);
1162 } 1153 }
1163 1154
1164 xfs_ilock(ip, XFS_ILOCK_SHARED); 1155 xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -1178,8 +1169,8 @@ xfs_sync_inodes(
1178 * across calls to the buffer cache. 1169 * across calls to the buffer cache.
1179 */ 1170 */
1180 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1171 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1181 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 1172 error = bhv_vop_flush_pages(vp, (xfs_off_t)0,
1182 fflag, FI_NONE, error); 1173 -1, fflag, FI_NONE);
1183 xfs_ilock(ip, XFS_ILOCK_SHARED); 1174 xfs_ilock(ip, XFS_ILOCK_SHARED);
1184 } 1175 }
1185 1176
@@ -1231,9 +1222,7 @@ xfs_sync_inodes(
1231 * marker and free it. 1222 * marker and free it.
1232 */ 1223 */
1233 XFS_MOUNT_ILOCK(mp); 1224 XFS_MOUNT_ILOCK(mp);
1234
1235 IPOINTER_REMOVE(ip, mp); 1225 IPOINTER_REMOVE(ip, mp);
1236
1237 XFS_MOUNT_IUNLOCK(mp); 1226 XFS_MOUNT_IUNLOCK(mp);
1238 1227
1239 ASSERT(!(lock_flags & 1228 ASSERT(!(lock_flags &
@@ -1421,7 +1410,7 @@ xfs_sync_inodes(
1421/* 1410/*
1422 * xfs sync routine for internal use 1411 * xfs sync routine for internal use
1423 * 1412 *
1424 * This routine supports all of the flags defined for the generic VFS_SYNC 1413 * This routine supports all of the flags defined for the generic vfs_sync
1425 * interface as explained above under xfs_sync. In the interests of not 1414 * interface as explained above under xfs_sync. In the interests of not
1426 * changing interfaces within the 6.5 family, additional internally- 1415 * changing interfaces within the 6.5 family, additional internally-
1427 * required functions are specified within a separate xflags parameter, 1416 * required functions are specified within a separate xflags parameter,
@@ -1574,7 +1563,7 @@ xfs_syncsub(
1574STATIC int 1563STATIC int
1575xfs_vget( 1564xfs_vget(
1576 bhv_desc_t *bdp, 1565 bhv_desc_t *bdp,
1577 vnode_t **vpp, 1566 bhv_vnode_t **vpp,
1578 fid_t *fidp) 1567 fid_t *fidp)
1579{ 1568{
1580 xfs_mount_t *mp = XFS_BHVTOM(bdp); 1569 xfs_mount_t *mp = XFS_BHVTOM(bdp);
@@ -1657,10 +1646,10 @@ xfs_vget(
1657#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ 1646#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1658 1647
1659STATIC unsigned long 1648STATIC unsigned long
1660suffix_strtoul(const char *cp, char **endp, unsigned int base) 1649suffix_strtoul(char *s, char **endp, unsigned int base)
1661{ 1650{
1662 int last, shift_left_factor = 0; 1651 int last, shift_left_factor = 0;
1663 char *value = (char *)cp; 1652 char *value = s;
1664 1653
1665 last = strlen(value) - 1; 1654 last = strlen(value) - 1;
1666 if (value[last] == 'K' || value[last] == 'k') { 1655 if (value[last] == 'K' || value[last] == 'k') {
@@ -1676,7 +1665,7 @@ suffix_strtoul(const char *cp, char **endp, unsigned int base)
1676 value[last] = '\0'; 1665 value[last] = '\0';
1677 } 1666 }
1678 1667
1679 return simple_strtoul(cp, endp, base) << shift_left_factor; 1668 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
1680} 1669}
1681 1670
1682STATIC int 1671STATIC int
@@ -1686,7 +1675,7 @@ xfs_parseargs(
1686 struct xfs_mount_args *args, 1675 struct xfs_mount_args *args,
1687 int update) 1676 int update)
1688{ 1677{
1689 struct vfs *vfsp = bhvtovfs(bhv); 1678 bhv_vfs_t *vfsp = bhvtovfs(bhv);
1690 char *this_char, *value, *eov; 1679 char *this_char, *value, *eov;
1691 int dsunit, dswidth, vol_dsunit, vol_dswidth; 1680 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1692 int iosize; 1681 int iosize;
@@ -1708,42 +1697,48 @@ xfs_parseargs(
1708 1697
1709 if (!strcmp(this_char, MNTOPT_LOGBUFS)) { 1698 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
1710 if (!value || !*value) { 1699 if (!value || !*value) {
1711 printk("XFS: %s option requires an argument\n", 1700 cmn_err(CE_WARN,
1701 "XFS: %s option requires an argument",
1712 this_char); 1702 this_char);
1713 return EINVAL; 1703 return EINVAL;
1714 } 1704 }
1715 args->logbufs = simple_strtoul(value, &eov, 10); 1705 args->logbufs = simple_strtoul(value, &eov, 10);
1716 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { 1706 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
1717 if (!value || !*value) { 1707 if (!value || !*value) {
1718 printk("XFS: %s option requires an argument\n", 1708 cmn_err(CE_WARN,
1709 "XFS: %s option requires an argument",
1719 this_char); 1710 this_char);
1720 return EINVAL; 1711 return EINVAL;
1721 } 1712 }
1722 args->logbufsize = suffix_strtoul(value, &eov, 10); 1713 args->logbufsize = suffix_strtoul(value, &eov, 10);
1723 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { 1714 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
1724 if (!value || !*value) { 1715 if (!value || !*value) {
1725 printk("XFS: %s option requires an argument\n", 1716 cmn_err(CE_WARN,
1717 "XFS: %s option requires an argument",
1726 this_char); 1718 this_char);
1727 return EINVAL; 1719 return EINVAL;
1728 } 1720 }
1729 strncpy(args->logname, value, MAXNAMELEN); 1721 strncpy(args->logname, value, MAXNAMELEN);
1730 } else if (!strcmp(this_char, MNTOPT_MTPT)) { 1722 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
1731 if (!value || !*value) { 1723 if (!value || !*value) {
1732 printk("XFS: %s option requires an argument\n", 1724 cmn_err(CE_WARN,
1725 "XFS: %s option requires an argument",
1733 this_char); 1726 this_char);
1734 return EINVAL; 1727 return EINVAL;
1735 } 1728 }
1736 strncpy(args->mtpt, value, MAXNAMELEN); 1729 strncpy(args->mtpt, value, MAXNAMELEN);
1737 } else if (!strcmp(this_char, MNTOPT_RTDEV)) { 1730 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
1738 if (!value || !*value) { 1731 if (!value || !*value) {
1739 printk("XFS: %s option requires an argument\n", 1732 cmn_err(CE_WARN,
1733 "XFS: %s option requires an argument",
1740 this_char); 1734 this_char);
1741 return EINVAL; 1735 return EINVAL;
1742 } 1736 }
1743 strncpy(args->rtname, value, MAXNAMELEN); 1737 strncpy(args->rtname, value, MAXNAMELEN);
1744 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { 1738 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
1745 if (!value || !*value) { 1739 if (!value || !*value) {
1746 printk("XFS: %s option requires an argument\n", 1740 cmn_err(CE_WARN,
1741 "XFS: %s option requires an argument",
1747 this_char); 1742 this_char);
1748 return EINVAL; 1743 return EINVAL;
1749 } 1744 }
@@ -1752,7 +1747,8 @@ xfs_parseargs(
1752 args->iosizelog = (uint8_t) iosize; 1747 args->iosizelog = (uint8_t) iosize;
1753 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { 1748 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
1754 if (!value || !*value) { 1749 if (!value || !*value) {
1755 printk("XFS: %s option requires an argument\n", 1750 cmn_err(CE_WARN,
1751 "XFS: %s option requires an argument",
1756 this_char); 1752 this_char);
1757 return EINVAL; 1753 return EINVAL;
1758 } 1754 }
@@ -1761,7 +1757,8 @@ xfs_parseargs(
1761 args->iosizelog = ffs(iosize) - 1; 1757 args->iosizelog = ffs(iosize) - 1;
1762 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { 1758 } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) {
1763 if (!value || !*value) { 1759 if (!value || !*value) {
1764 printk("XFS: %s option requires an argument\n", 1760 cmn_err(CE_WARN,
1761 "XFS: %s option requires an argument",
1765 this_char); 1762 this_char);
1766 return EINVAL; 1763 return EINVAL;
1767 } 1764 }
@@ -1782,7 +1779,8 @@ xfs_parseargs(
1782 } else if (!strcmp(this_char, MNTOPT_INO64)) { 1779 } else if (!strcmp(this_char, MNTOPT_INO64)) {
1783 args->flags |= XFSMNT_INO64; 1780 args->flags |= XFSMNT_INO64;
1784#if !XFS_BIG_INUMS 1781#if !XFS_BIG_INUMS
1785 printk("XFS: %s option not allowed on this system\n", 1782 cmn_err(CE_WARN,
1783 "XFS: %s option not allowed on this system",
1786 this_char); 1784 this_char);
1787 return EINVAL; 1785 return EINVAL;
1788#endif 1786#endif
@@ -1792,14 +1790,16 @@ xfs_parseargs(
1792 args->flags |= XFSMNT_SWALLOC; 1790 args->flags |= XFSMNT_SWALLOC;
1793 } else if (!strcmp(this_char, MNTOPT_SUNIT)) { 1791 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
1794 if (!value || !*value) { 1792 if (!value || !*value) {
1795 printk("XFS: %s option requires an argument\n", 1793 cmn_err(CE_WARN,
1794 "XFS: %s option requires an argument",
1796 this_char); 1795 this_char);
1797 return EINVAL; 1796 return EINVAL;
1798 } 1797 }
1799 dsunit = simple_strtoul(value, &eov, 10); 1798 dsunit = simple_strtoul(value, &eov, 10);
1800 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { 1799 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
1801 if (!value || !*value) { 1800 if (!value || !*value) {
1802 printk("XFS: %s option requires an argument\n", 1801 cmn_err(CE_WARN,
1802 "XFS: %s option requires an argument",
1803 this_char); 1803 this_char);
1804 return EINVAL; 1804 return EINVAL;
1805 } 1805 }
@@ -1807,7 +1807,8 @@ xfs_parseargs(
1807 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) { 1807 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
1808 args->flags &= ~XFSMNT_32BITINODES; 1808 args->flags &= ~XFSMNT_32BITINODES;
1809#if !XFS_BIG_INUMS 1809#if !XFS_BIG_INUMS
1810 printk("XFS: %s option not allowed on this system\n", 1810 cmn_err(CE_WARN,
1811 "XFS: %s option not allowed on this system",
1811 this_char); 1812 this_char);
1812 return EINVAL; 1813 return EINVAL;
1813#endif 1814#endif
@@ -1831,36 +1832,41 @@ xfs_parseargs(
1831 args->flags &= ~XFSMNT_ATTR2; 1832 args->flags &= ~XFSMNT_ATTR2;
1832 } else if (!strcmp(this_char, "osyncisdsync")) { 1833 } else if (!strcmp(this_char, "osyncisdsync")) {
1833 /* no-op, this is now the default */ 1834 /* no-op, this is now the default */
1834printk("XFS: osyncisdsync is now the default, option is deprecated.\n"); 1835 cmn_err(CE_WARN,
1836 "XFS: osyncisdsync is now the default, option is deprecated.");
1835 } else if (!strcmp(this_char, "irixsgid")) { 1837 } else if (!strcmp(this_char, "irixsgid")) {
1836printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n"); 1838 cmn_err(CE_WARN,
1839 "XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
1837 } else { 1840 } else {
1838 printk("XFS: unknown mount option [%s].\n", this_char); 1841 cmn_err(CE_WARN,
1842 "XFS: unknown mount option [%s].", this_char);
1839 return EINVAL; 1843 return EINVAL;
1840 } 1844 }
1841 } 1845 }
1842 1846
1843 if (args->flags & XFSMNT_NORECOVERY) { 1847 if (args->flags & XFSMNT_NORECOVERY) {
1844 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { 1848 if ((vfsp->vfs_flag & VFS_RDONLY) == 0) {
1845 printk("XFS: no-recovery mounts must be read-only.\n"); 1849 cmn_err(CE_WARN,
1850 "XFS: no-recovery mounts must be read-only.");
1846 return EINVAL; 1851 return EINVAL;
1847 } 1852 }
1848 } 1853 }
1849 1854
1850 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { 1855 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
1851 printk( 1856 cmn_err(CE_WARN,
1852 "XFS: sunit and swidth options incompatible with the noalign option\n"); 1857 "XFS: sunit and swidth options incompatible with the noalign option");
1853 return EINVAL; 1858 return EINVAL;
1854 } 1859 }
1855 1860
1856 if ((dsunit && !dswidth) || (!dsunit && dswidth)) { 1861 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1857 printk("XFS: sunit and swidth must be specified together\n"); 1862 cmn_err(CE_WARN,
1863 "XFS: sunit and swidth must be specified together");
1858 return EINVAL; 1864 return EINVAL;
1859 } 1865 }
1860 1866
1861 if (dsunit && (dswidth % dsunit != 0)) { 1867 if (dsunit && (dswidth % dsunit != 0)) {
1862 printk( 1868 cmn_err(CE_WARN,
1863 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n", 1869 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",
1864 dswidth, dsunit); 1870 dswidth, dsunit);
1865 return EINVAL; 1871 return EINVAL;
1866 } 1872 }
@@ -1907,7 +1913,7 @@ xfs_showargs(
1907 }; 1913 };
1908 struct proc_xfs_info *xfs_infop; 1914 struct proc_xfs_info *xfs_infop;
1909 struct xfs_mount *mp = XFS_BHVTOM(bhv); 1915 struct xfs_mount *mp = XFS_BHVTOM(bhv);
1910 struct vfs *vfsp = XFS_MTOVFS(mp); 1916 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1911 1917
1912 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) { 1918 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
1913 if (mp->m_flags & xfs_infop->flag) 1919 if (mp->m_flags & xfs_infop->flag)
@@ -1967,7 +1973,7 @@ xfs_freeze(
1967} 1973}
1968 1974
1969 1975
1970vfsops_t xfs_vfsops = { 1976bhv_vfsops_t xfs_vfsops = {
1971 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS), 1977 BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
1972 .vfs_parseargs = xfs_parseargs, 1978 .vfs_parseargs = xfs_parseargs,
1973 .vfs_showargs = xfs_showargs, 1979 .vfs_showargs = xfs_showargs,
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 7027ae68ee38..00a6b7dc24a0 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * All Rights Reserved. 3 * All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -16,8 +16,6 @@
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18 18
19#include <linux/capability.h>
20
21#include "xfs.h" 19#include "xfs.h"
22#include "xfs_fs.h" 20#include "xfs_fs.h"
23#include "xfs_types.h" 21#include "xfs_types.h"
@@ -27,7 +25,6 @@
27#include "xfs_trans.h" 25#include "xfs_trans.h"
28#include "xfs_sb.h" 26#include "xfs_sb.h"
29#include "xfs_ag.h" 27#include "xfs_ag.h"
30#include "xfs_dir.h"
31#include "xfs_dir2.h" 28#include "xfs_dir2.h"
32#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
33#include "xfs_mount.h" 30#include "xfs_mount.h"
@@ -35,13 +32,11 @@
35#include "xfs_bmap_btree.h" 32#include "xfs_bmap_btree.h"
36#include "xfs_alloc_btree.h" 33#include "xfs_alloc_btree.h"
37#include "xfs_ialloc_btree.h" 34#include "xfs_ialloc_btree.h"
38#include "xfs_dir_sf.h"
39#include "xfs_dir2_sf.h" 35#include "xfs_dir2_sf.h"
40#include "xfs_attr_sf.h" 36#include "xfs_attr_sf.h"
41#include "xfs_dinode.h" 37#include "xfs_dinode.h"
42#include "xfs_inode.h" 38#include "xfs_inode.h"
43#include "xfs_inode_item.h" 39#include "xfs_inode_item.h"
44#include "xfs_dir_leaf.h"
45#include "xfs_itable.h" 40#include "xfs_itable.h"
46#include "xfs_btree.h" 41#include "xfs_btree.h"
47#include "xfs_ialloc.h" 42#include "xfs_ialloc.h"
@@ -58,32 +53,14 @@
58#include "xfs_log_priv.h" 53#include "xfs_log_priv.h"
59#include "xfs_mac.h" 54#include "xfs_mac.h"
60 55
61
62/*
63 * The maximum pathlen is 1024 bytes. Since the minimum file system
64 * blocksize is 512 bytes, we can get a max of 2 extents back from
65 * bmapi.
66 */
67#define SYMLINK_MAPS 2
68
69/*
70 * For xfs, we check that the file isn't too big to be opened by this kernel.
71 * No other open action is required for regular files. Devices are handled
72 * through the specfs file system, pipes through fifofs. Device and
73 * fifo vnodes are "wrapped" by specfs and fifofs vnodes, respectively,
74 * when a new vnode is first looked up or created.
75 */
76STATIC int 56STATIC int
77xfs_open( 57xfs_open(
78 bhv_desc_t *bdp, 58 bhv_desc_t *bdp,
79 cred_t *credp) 59 cred_t *credp)
80{ 60{
81 int mode; 61 int mode;
82 vnode_t *vp; 62 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
83 xfs_inode_t *ip; 63 xfs_inode_t *ip = XFS_BHVTOI(bdp);
84
85 vp = BHV_TO_VNODE(bdp);
86 ip = XFS_BHVTOI(bdp);
87 64
88 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) 65 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
89 return XFS_ERROR(EIO); 66 return XFS_ERROR(EIO);
@@ -101,6 +78,35 @@ xfs_open(
101 return 0; 78 return 0;
102} 79}
103 80
81STATIC int
82xfs_close(
83 bhv_desc_t *bdp,
84 int flags,
85 lastclose_t lastclose,
86 cred_t *credp)
87{
88 bhv_vnode_t *vp = BHV_TO_VNODE(bdp);
89 xfs_inode_t *ip = XFS_BHVTOI(bdp);
90
91 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
92 return XFS_ERROR(EIO);
93
94 if (lastclose != L_TRUE || !VN_ISREG(vp))
95 return 0;
96
97 /*
98 * If we previously truncated this file and removed old data in
99 * the process, we want to initiate "early" writeout on the last
100 * close. This is an attempt to combat the notorious NULL files
101 * problem which is particularly noticable from a truncate down,
102 * buffered (re-)write (delalloc), followed by a crash. What we
103 * are effectively doing here is significantly reducing the time
104 * window where we'd otherwise be exposed to that problem.
105 */
106 if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
107 return bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE);
108 return 0;
109}
104 110
105/* 111/*
106 * xfs_getattr 112 * xfs_getattr
@@ -108,13 +114,13 @@ xfs_open(
108STATIC int 114STATIC int
109xfs_getattr( 115xfs_getattr(
110 bhv_desc_t *bdp, 116 bhv_desc_t *bdp,
111 vattr_t *vap, 117 bhv_vattr_t *vap,
112 int flags, 118 int flags,
113 cred_t *credp) 119 cred_t *credp)
114{ 120{
115 xfs_inode_t *ip; 121 xfs_inode_t *ip;
116 xfs_mount_t *mp; 122 xfs_mount_t *mp;
117 vnode_t *vp; 123 bhv_vnode_t *vp;
118 124
119 vp = BHV_TO_VNODE(bdp); 125 vp = BHV_TO_VNODE(bdp);
120 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 126 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -241,7 +247,7 @@ xfs_getattr(
241int 247int
242xfs_setattr( 248xfs_setattr(
243 bhv_desc_t *bdp, 249 bhv_desc_t *bdp,
244 vattr_t *vap, 250 bhv_vattr_t *vap,
245 int flags, 251 int flags,
246 cred_t *credp) 252 cred_t *credp)
247{ 253{
@@ -255,7 +261,7 @@ xfs_setattr(
255 uid_t uid=0, iuid=0; 261 uid_t uid=0, iuid=0;
256 gid_t gid=0, igid=0; 262 gid_t gid=0, igid=0;
257 int timeflags = 0; 263 int timeflags = 0;
258 vnode_t *vp; 264 bhv_vnode_t *vp;
259 xfs_prid_t projid=0, iprojid=0; 265 xfs_prid_t projid=0, iprojid=0;
260 int mandlock_before, mandlock_after; 266 int mandlock_before, mandlock_after;
261 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; 267 struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
@@ -347,7 +353,6 @@ xfs_setattr(
347 */ 353 */
348 tp = NULL; 354 tp = NULL;
349 lock_flags = XFS_ILOCK_EXCL; 355 lock_flags = XFS_ILOCK_EXCL;
350 ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1);
351 if (flags & ATTR_NOLOCK) 356 if (flags & ATTR_NOLOCK)
352 need_iolock = 0; 357 need_iolock = 0;
353 if (!(mask & XFS_AT_SIZE)) { 358 if (!(mask & XFS_AT_SIZE)) {
@@ -666,9 +671,17 @@ xfs_setattr(
666 ((ip->i_d.di_nlink != 0 || 671 ((ip->i_d.di_nlink != 0 ||
667 !(mp->m_flags & XFS_MOUNT_WSYNC)) 672 !(mp->m_flags & XFS_MOUNT_WSYNC))
668 ? 1 : 0)); 673 ? 1 : 0));
669 if (code) { 674 if (code)
670 goto abort_return; 675 goto abort_return;
671 } 676 /*
677 * Truncated "down", so we're removing references
678 * to old data here - if we now delay flushing for
679 * a long time, we expose ourselves unduly to the
680 * notorious NULL files problem. So, we mark this
681 * vnode and flush it when the file is closed, and
682 * do not wait the usual (long) time for writeout.
683 */
684 VTRUNCATE(vp);
672 } 685 }
673 /* 686 /*
674 * Have to do this even if the file's size doesn't change. 687 * Have to do this even if the file's size doesn't change.
@@ -800,6 +813,8 @@ xfs_setattr(
800 di_flags |= XFS_DIFLAG_NODUMP; 813 di_flags |= XFS_DIFLAG_NODUMP;
801 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT) 814 if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
802 di_flags |= XFS_DIFLAG_PROJINHERIT; 815 di_flags |= XFS_DIFLAG_PROJINHERIT;
816 if (vap->va_xflags & XFS_XFLAG_NODEFRAG)
817 di_flags |= XFS_DIFLAG_NODEFRAG;
803 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { 818 if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
804 if (vap->va_xflags & XFS_XFLAG_RTINHERIT) 819 if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
805 di_flags |= XFS_DIFLAG_RTINHERIT; 820 di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -869,7 +884,7 @@ xfs_setattr(
869 */ 884 */
870 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode); 885 mandlock_after = MANDLOCK(vp, ip->i_d.di_mode);
871 if (mandlock_before != mandlock_after) { 886 if (mandlock_before != mandlock_after) {
872 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_ENF_LOCKING, 887 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING,
873 mandlock_after); 888 mandlock_after);
874 } 889 }
875 890
@@ -936,6 +951,13 @@ xfs_access(
936 951
937 952
938/* 953/*
954 * The maximum pathlen is 1024 bytes. Since the minimum file system
955 * blocksize is 512 bytes, we can get a max of 2 extents back from
956 * bmapi.
957 */
958#define SYMLINK_MAPS 2
959
960/*
939 * xfs_readlink 961 * xfs_readlink
940 * 962 *
941 */ 963 */
@@ -950,7 +972,7 @@ xfs_readlink(
950 int count; 972 int count;
951 xfs_off_t offset; 973 xfs_off_t offset;
952 int pathlen; 974 int pathlen;
953 vnode_t *vp; 975 bhv_vnode_t *vp;
954 int error = 0; 976 int error = 0;
955 xfs_mount_t *mp; 977 xfs_mount_t *mp;
956 int nmaps; 978 int nmaps;
@@ -1000,7 +1022,7 @@ xfs_readlink(
1000 nmaps = SYMLINK_MAPS; 1022 nmaps = SYMLINK_MAPS;
1001 1023
1002 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 1024 error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen),
1003 0, NULL, 0, mval, &nmaps, NULL); 1025 0, NULL, 0, mval, &nmaps, NULL, NULL);
1004 1026
1005 if (error) { 1027 if (error) {
1006 goto error_return; 1028 goto error_return;
@@ -1208,8 +1230,8 @@ xfs_inactive_free_eofblocks(
1208 1230
1209 nimaps = 1; 1231 nimaps = 1;
1210 xfs_ilock(ip, XFS_ILOCK_SHARED); 1232 xfs_ilock(ip, XFS_ILOCK_SHARED);
1211 error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0, 1233 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, end_fsb, map_len, 0,
1212 NULL, 0, &imap, &nimaps, NULL); 1234 NULL, 0, &imap, &nimaps, NULL, NULL);
1213 xfs_iunlock(ip, XFS_ILOCK_SHARED); 1235 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1214 1236
1215 if (!error && (nimaps != 0) && 1237 if (!error && (nimaps != 0) &&
@@ -1338,7 +1360,7 @@ xfs_inactive_symlink_rmt(
1338 nmaps = ARRAY_SIZE(mval); 1360 nmaps = ARRAY_SIZE(mval);
1339 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size), 1361 if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size),
1340 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps, 1362 XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps,
1341 &free_list))) 1363 &free_list, NULL)))
1342 goto error0; 1364 goto error0;
1343 /* 1365 /*
1344 * Invalidate the block(s). 1366 * Invalidate the block(s).
@@ -1353,7 +1375,7 @@ xfs_inactive_symlink_rmt(
1353 * Unmap the dead block(s) to the free_list. 1375 * Unmap the dead block(s) to the free_list.
1354 */ 1376 */
1355 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps, 1377 if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps,
1356 &first_block, &free_list, &done))) 1378 &first_block, &free_list, NULL, &done)))
1357 goto error1; 1379 goto error1;
1358 ASSERT(done); 1380 ASSERT(done);
1359 /* 1381 /*
@@ -1469,9 +1491,6 @@ xfs_inactive_symlink_local(
1469 return 0; 1491 return 0;
1470} 1492}
1471 1493
1472/*
1473 *
1474 */
1475STATIC int 1494STATIC int
1476xfs_inactive_attrs( 1495xfs_inactive_attrs(
1477 xfs_inode_t *ip, 1496 xfs_inode_t *ip,
@@ -1524,16 +1543,16 @@ xfs_release(
1524 bhv_desc_t *bdp) 1543 bhv_desc_t *bdp)
1525{ 1544{
1526 xfs_inode_t *ip; 1545 xfs_inode_t *ip;
1527 vnode_t *vp; 1546 bhv_vnode_t *vp;
1528 xfs_mount_t *mp; 1547 xfs_mount_t *mp;
1529 int error; 1548 int error;
1530 1549
1531 vp = BHV_TO_VNODE(bdp); 1550 vp = BHV_TO_VNODE(bdp);
1532 ip = XFS_BHVTOI(bdp); 1551 ip = XFS_BHVTOI(bdp);
1552 mp = ip->i_mount;
1533 1553
1534 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) { 1554 if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0))
1535 return 0; 1555 return 0;
1536 }
1537 1556
1538 /* If this is a read-only mount, don't do this (would generate I/O) */ 1557 /* If this is a read-only mount, don't do this (would generate I/O) */
1539 if (vp->v_vfsp->vfs_flag & VFS_RDONLY) 1558 if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
@@ -1545,8 +1564,6 @@ xfs_release(
1545 return 0; 1564 return 0;
1546#endif 1565#endif
1547 1566
1548 mp = ip->i_mount;
1549
1550 if (ip->i_d.di_nlink != 0) { 1567 if (ip->i_d.di_nlink != 0) {
1551 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && 1568 if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) &&
1552 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 || 1569 ((ip->i_d.di_size > 0) || (VN_CACHED(vp) > 0 ||
@@ -1579,8 +1596,8 @@ xfs_inactive(
1579 cred_t *credp) 1596 cred_t *credp)
1580{ 1597{
1581 xfs_inode_t *ip; 1598 xfs_inode_t *ip;
1582 vnode_t *vp; 1599 bhv_vnode_t *vp;
1583 xfs_bmap_free_t free_list; 1600 xfs_bmap_free_t free_list;
1584 xfs_fsblock_t first_block; 1601 xfs_fsblock_t first_block;
1585 int committed; 1602 int committed;
1586 xfs_trans_t *tp; 1603 xfs_trans_t *tp;
@@ -1760,7 +1777,7 @@ xfs_inactive(
1760 cmn_err(CE_NOTE, 1777 cmn_err(CE_NOTE,
1761 "xfs_inactive: xfs_ifree() returned an error = %d on %s", 1778 "xfs_inactive: xfs_ifree() returned an error = %d on %s",
1762 error, mp->m_fsname); 1779 error, mp->m_fsname);
1763 xfs_force_shutdown(mp, XFS_METADATA_IO_ERROR); 1780 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1764 } 1781 }
1765 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); 1782 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1766 } else { 1783 } else {
@@ -1795,17 +1812,17 @@ xfs_inactive(
1795STATIC int 1812STATIC int
1796xfs_lookup( 1813xfs_lookup(
1797 bhv_desc_t *dir_bdp, 1814 bhv_desc_t *dir_bdp,
1798 vname_t *dentry, 1815 bhv_vname_t *dentry,
1799 vnode_t **vpp, 1816 bhv_vnode_t **vpp,
1800 int flags, 1817 int flags,
1801 vnode_t *rdir, 1818 bhv_vnode_t *rdir,
1802 cred_t *credp) 1819 cred_t *credp)
1803{ 1820{
1804 xfs_inode_t *dp, *ip; 1821 xfs_inode_t *dp, *ip;
1805 xfs_ino_t e_inum; 1822 xfs_ino_t e_inum;
1806 int error; 1823 int error;
1807 uint lock_mode; 1824 uint lock_mode;
1808 vnode_t *dir_vp; 1825 bhv_vnode_t *dir_vp;
1809 1826
1810 dir_vp = BHV_TO_VNODE(dir_bdp); 1827 dir_vp = BHV_TO_VNODE(dir_bdp);
1811 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address); 1828 vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
@@ -1832,15 +1849,15 @@ xfs_lookup(
1832STATIC int 1849STATIC int
1833xfs_create( 1850xfs_create(
1834 bhv_desc_t *dir_bdp, 1851 bhv_desc_t *dir_bdp,
1835 vname_t *dentry, 1852 bhv_vname_t *dentry,
1836 vattr_t *vap, 1853 bhv_vattr_t *vap,
1837 vnode_t **vpp, 1854 bhv_vnode_t **vpp,
1838 cred_t *credp) 1855 cred_t *credp)
1839{ 1856{
1840 char *name = VNAME(dentry); 1857 char *name = VNAME(dentry);
1841 vnode_t *dir_vp; 1858 bhv_vnode_t *dir_vp;
1842 xfs_inode_t *dp, *ip; 1859 xfs_inode_t *dp, *ip;
1843 vnode_t *vp=NULL; 1860 bhv_vnode_t *vp = NULL;
1844 xfs_trans_t *tp; 1861 xfs_trans_t *tp;
1845 xfs_mount_t *mp; 1862 xfs_mount_t *mp;
1846 xfs_dev_t rdev; 1863 xfs_dev_t rdev;
@@ -1938,8 +1955,7 @@ xfs_create(
1938 if (error) 1955 if (error)
1939 goto error_return; 1956 goto error_return;
1940 1957
1941 if (resblks == 0 && 1958 if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen)))
1942 (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen)))
1943 goto error_return; 1959 goto error_return;
1944 rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; 1960 rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
1945 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, 1961 error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1,
@@ -1970,9 +1986,9 @@ xfs_create(
1970 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 1986 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
1971 dp_joined_to_trans = B_TRUE; 1987 dp_joined_to_trans = B_TRUE;
1972 1988
1973 error = XFS_DIR_CREATENAME(mp, tp, dp, name, namelen, ip->i_ino, 1989 error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino,
1974 &first_block, &free_list, 1990 &first_block, &free_list, resblks ?
1975 resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 1991 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
1976 if (error) { 1992 if (error) {
1977 ASSERT(error != ENOSPC); 1993 ASSERT(error != ENOSPC);
1978 goto abort_return; 1994 goto abort_return;
@@ -2026,7 +2042,7 @@ xfs_create(
2026 * Propagate the fact that the vnode changed after the 2042 * Propagate the fact that the vnode changed after the
2027 * xfs_inode locks have been released. 2043 * xfs_inode locks have been released.
2028 */ 2044 */
2029 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3); 2045 bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3);
2030 2046
2031 *vpp = vp; 2047 *vpp = vp;
2032 2048
@@ -2107,7 +2123,7 @@ int xfs_rm_attempts;
2107STATIC int 2123STATIC int
2108xfs_lock_dir_and_entry( 2124xfs_lock_dir_and_entry(
2109 xfs_inode_t *dp, 2125 xfs_inode_t *dp,
2110 vname_t *dentry, 2126 bhv_vname_t *dentry,
2111 xfs_inode_t *ip) /* inode of entry 'name' */ 2127 xfs_inode_t *ip) /* inode of entry 'name' */
2112{ 2128{
2113 int attempts; 2129 int attempts;
@@ -2321,10 +2337,10 @@ int remove_which_error_return = 0;
2321STATIC int 2337STATIC int
2322xfs_remove( 2338xfs_remove(
2323 bhv_desc_t *dir_bdp, 2339 bhv_desc_t *dir_bdp,
2324 vname_t *dentry, 2340 bhv_vname_t *dentry,
2325 cred_t *credp) 2341 cred_t *credp)
2326{ 2342{
2327 vnode_t *dir_vp; 2343 bhv_vnode_t *dir_vp;
2328 char *name = VNAME(dentry); 2344 char *name = VNAME(dentry);
2329 xfs_inode_t *dp, *ip; 2345 xfs_inode_t *dp, *ip;
2330 xfs_trans_t *tp = NULL; 2346 xfs_trans_t *tp = NULL;
@@ -2448,8 +2464,8 @@ xfs_remove(
2448 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. 2464 * Entry must exist since we did a lookup in xfs_lock_dir_and_entry.
2449 */ 2465 */
2450 XFS_BMAP_INIT(&free_list, &first_block); 2466 XFS_BMAP_INIT(&free_list, &first_block);
2451 error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, ip->i_ino, 2467 error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino,
2452 &first_block, &free_list, 0); 2468 &first_block, &free_list, 0);
2453 if (error) { 2469 if (error) {
2454 ASSERT(error != ENOENT); 2470 ASSERT(error != ENOENT);
2455 REMOVE_DEBUG_TRACE(__LINE__); 2471 REMOVE_DEBUG_TRACE(__LINE__);
@@ -2511,7 +2527,7 @@ xfs_remove(
2511 /* 2527 /*
2512 * Let interposed file systems know about removed links. 2528 * Let interposed file systems know about removed links.
2513 */ 2529 */
2514 VOP_LINK_REMOVED(XFS_ITOV(ip), dir_vp, link_zero); 2530 bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero);
2515 2531
2516 IRELE(ip); 2532 IRELE(ip);
2517 2533
@@ -2564,8 +2580,8 @@ xfs_remove(
2564STATIC int 2580STATIC int
2565xfs_link( 2581xfs_link(
2566 bhv_desc_t *target_dir_bdp, 2582 bhv_desc_t *target_dir_bdp,
2567 vnode_t *src_vp, 2583 bhv_vnode_t *src_vp,
2568 vname_t *dentry, 2584 bhv_vname_t *dentry,
2569 cred_t *credp) 2585 cred_t *credp)
2570{ 2586{
2571 xfs_inode_t *tdp, *sip; 2587 xfs_inode_t *tdp, *sip;
@@ -2577,7 +2593,7 @@ xfs_link(
2577 xfs_fsblock_t first_block; 2593 xfs_fsblock_t first_block;
2578 int cancel_flags; 2594 int cancel_flags;
2579 int committed; 2595 int committed;
2580 vnode_t *target_dir_vp; 2596 bhv_vnode_t *target_dir_vp;
2581 int resblks; 2597 int resblks;
2582 char *target_name = VNAME(dentry); 2598 char *target_name = VNAME(dentry);
2583 int target_namelen; 2599 int target_namelen;
@@ -2668,13 +2684,12 @@ xfs_link(
2668 } 2684 }
2669 2685
2670 if (resblks == 0 && 2686 if (resblks == 0 &&
2671 (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, 2687 (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen)))
2672 target_namelen)))
2673 goto error_return; 2688 goto error_return;
2674 2689
2675 XFS_BMAP_INIT(&free_list, &first_block); 2690 XFS_BMAP_INIT(&free_list, &first_block);
2676 2691
2677 error = XFS_DIR_CREATENAME(mp, tp, tdp, target_name, target_namelen, 2692 error = xfs_dir_createname(tp, tdp, target_name, target_namelen,
2678 sip->i_ino, &first_block, &free_list, 2693 sip->i_ino, &first_block, &free_list,
2679 resblks); 2694 resblks);
2680 if (error) 2695 if (error)
@@ -2734,15 +2749,15 @@ std_return:
2734STATIC int 2749STATIC int
2735xfs_mkdir( 2750xfs_mkdir(
2736 bhv_desc_t *dir_bdp, 2751 bhv_desc_t *dir_bdp,
2737 vname_t *dentry, 2752 bhv_vname_t *dentry,
2738 vattr_t *vap, 2753 bhv_vattr_t *vap,
2739 vnode_t **vpp, 2754 bhv_vnode_t **vpp,
2740 cred_t *credp) 2755 cred_t *credp)
2741{ 2756{
2742 char *dir_name = VNAME(dentry); 2757 char *dir_name = VNAME(dentry);
2743 xfs_inode_t *dp; 2758 xfs_inode_t *dp;
2744 xfs_inode_t *cdp; /* inode of created dir */ 2759 xfs_inode_t *cdp; /* inode of created dir */
2745 vnode_t *cvp; /* vnode of created dir */ 2760 bhv_vnode_t *cvp; /* vnode of created dir */
2746 xfs_trans_t *tp; 2761 xfs_trans_t *tp;
2747 xfs_mount_t *mp; 2762 xfs_mount_t *mp;
2748 int cancel_flags; 2763 int cancel_flags;
@@ -2750,7 +2765,7 @@ xfs_mkdir(
2750 int committed; 2765 int committed;
2751 xfs_bmap_free_t free_list; 2766 xfs_bmap_free_t free_list;
2752 xfs_fsblock_t first_block; 2767 xfs_fsblock_t first_block;
2753 vnode_t *dir_vp; 2768 bhv_vnode_t *dir_vp;
2754 boolean_t dp_joined_to_trans; 2769 boolean_t dp_joined_to_trans;
2755 boolean_t created = B_FALSE; 2770 boolean_t created = B_FALSE;
2756 int dm_event_sent = 0; 2771 int dm_event_sent = 0;
@@ -2840,7 +2855,7 @@ xfs_mkdir(
2840 goto error_return; 2855 goto error_return;
2841 2856
2842 if (resblks == 0 && 2857 if (resblks == 0 &&
2843 (error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen))) 2858 (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen)))
2844 goto error_return; 2859 goto error_return;
2845 /* 2860 /*
2846 * create the directory inode. 2861 * create the directory inode.
@@ -2867,9 +2882,9 @@ xfs_mkdir(
2867 2882
2868 XFS_BMAP_INIT(&free_list, &first_block); 2883 XFS_BMAP_INIT(&free_list, &first_block);
2869 2884
2870 error = XFS_DIR_CREATENAME(mp, tp, dp, dir_name, dir_namelen, 2885 error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino,
2871 cdp->i_ino, &first_block, &free_list, 2886 &first_block, &free_list, resblks ?
2872 resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); 2887 resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
2873 if (error) { 2888 if (error) {
2874 ASSERT(error != ENOSPC); 2889 ASSERT(error != ENOSPC);
2875 goto error1; 2890 goto error1;
@@ -2883,16 +2898,14 @@ xfs_mkdir(
2883 */ 2898 */
2884 dp->i_gen++; 2899 dp->i_gen++;
2885 2900
2886 error = XFS_DIR_INIT(mp, tp, cdp, dp); 2901 error = xfs_dir_init(tp, cdp, dp);
2887 if (error) { 2902 if (error)
2888 goto error2; 2903 goto error2;
2889 }
2890 2904
2891 cdp->i_gen = 1; 2905 cdp->i_gen = 1;
2892 error = xfs_bumplink(tp, dp); 2906 error = xfs_bumplink(tp, dp);
2893 if (error) { 2907 if (error)
2894 goto error2; 2908 goto error2;
2895 }
2896 2909
2897 cvp = XFS_ITOV(cdp); 2910 cvp = XFS_ITOV(cdp);
2898 2911
@@ -2969,7 +2982,7 @@ std_return:
2969STATIC int 2982STATIC int
2970xfs_rmdir( 2983xfs_rmdir(
2971 bhv_desc_t *dir_bdp, 2984 bhv_desc_t *dir_bdp,
2972 vname_t *dentry, 2985 bhv_vname_t *dentry,
2973 cred_t *credp) 2986 cred_t *credp)
2974{ 2987{
2975 char *name = VNAME(dentry); 2988 char *name = VNAME(dentry);
@@ -2982,7 +2995,7 @@ xfs_rmdir(
2982 xfs_fsblock_t first_block; 2995 xfs_fsblock_t first_block;
2983 int cancel_flags; 2996 int cancel_flags;
2984 int committed; 2997 int committed;
2985 vnode_t *dir_vp; 2998 bhv_vnode_t *dir_vp;
2986 int dm_di_mode = 0; 2999 int dm_di_mode = 0;
2987 int last_cdp_link; 3000 int last_cdp_link;
2988 int namelen; 3001 int namelen;
@@ -3101,16 +3114,15 @@ xfs_rmdir(
3101 error = XFS_ERROR(ENOTEMPTY); 3114 error = XFS_ERROR(ENOTEMPTY);
3102 goto error_return; 3115 goto error_return;
3103 } 3116 }
3104 if (!XFS_DIR_ISEMPTY(mp, cdp)) { 3117 if (!xfs_dir_isempty(cdp)) {
3105 error = XFS_ERROR(ENOTEMPTY); 3118 error = XFS_ERROR(ENOTEMPTY);
3106 goto error_return; 3119 goto error_return;
3107 } 3120 }
3108 3121
3109 error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, cdp->i_ino, 3122 error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino,
3110 &first_block, &free_list, resblks); 3123 &first_block, &free_list, resblks);
3111 if (error) { 3124 if (error)
3112 goto error1; 3125 goto error1;
3113 }
3114 3126
3115 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3127 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3116 3128
@@ -3181,7 +3193,7 @@ xfs_rmdir(
3181 /* 3193 /*
3182 * Let interposed file systems know about removed links. 3194 * Let interposed file systems know about removed links.
3183 */ 3195 */
3184 VOP_LINK_REMOVED(XFS_ITOV(cdp), dir_vp, last_cdp_link); 3196 bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link);
3185 3197
3186 IRELE(cdp); 3198 IRELE(cdp);
3187 3199
@@ -3209,8 +3221,6 @@ xfs_rmdir(
3209 3221
3210 3222
3211/* 3223/*
3212 * xfs_readdir
3213 *
3214 * Read dp's entries starting at uiop->uio_offset and translate them into 3224 * Read dp's entries starting at uiop->uio_offset and translate them into
3215 * bufsize bytes worth of struct dirents starting at bufbase. 3225 * bufsize bytes worth of struct dirents starting at bufbase.
3216 */ 3226 */
@@ -3230,28 +3240,23 @@ xfs_readdir(
3230 (inst_t *)__return_address); 3240 (inst_t *)__return_address);
3231 dp = XFS_BHVTOI(dir_bdp); 3241 dp = XFS_BHVTOI(dir_bdp);
3232 3242
3233 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) { 3243 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
3234 return XFS_ERROR(EIO); 3244 return XFS_ERROR(EIO);
3235 }
3236 3245
3237 lock_mode = xfs_ilock_map_shared(dp); 3246 lock_mode = xfs_ilock_map_shared(dp);
3238 error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); 3247 error = xfs_dir_getdents(tp, dp, uiop, eofp);
3239 xfs_iunlock_map_shared(dp, lock_mode); 3248 xfs_iunlock_map_shared(dp, lock_mode);
3240 return error; 3249 return error;
3241} 3250}
3242 3251
3243 3252
3244/*
3245 * xfs_symlink
3246 *
3247 */
3248STATIC int 3253STATIC int
3249xfs_symlink( 3254xfs_symlink(
3250 bhv_desc_t *dir_bdp, 3255 bhv_desc_t *dir_bdp,
3251 vname_t *dentry, 3256 bhv_vname_t *dentry,
3252 vattr_t *vap, 3257 bhv_vattr_t *vap,
3253 char *target_path, 3258 char *target_path,
3254 vnode_t **vpp, 3259 bhv_vnode_t **vpp,
3255 cred_t *credp) 3260 cred_t *credp)
3256{ 3261{
3257 xfs_trans_t *tp; 3262 xfs_trans_t *tp;
@@ -3263,7 +3268,7 @@ xfs_symlink(
3263 xfs_bmap_free_t free_list; 3268 xfs_bmap_free_t free_list;
3264 xfs_fsblock_t first_block; 3269 xfs_fsblock_t first_block;
3265 boolean_t dp_joined_to_trans; 3270 boolean_t dp_joined_to_trans;
3266 vnode_t *dir_vp; 3271 bhv_vnode_t *dir_vp;
3267 uint cancel_flags; 3272 uint cancel_flags;
3268 int committed; 3273 int committed;
3269 xfs_fileoff_t first_fsb; 3274 xfs_fileoff_t first_fsb;
@@ -3308,7 +3313,7 @@ xfs_symlink(
3308 int len, total; 3313 int len, total;
3309 char *path; 3314 char *path;
3310 3315
3311 for(total = 0, path = target_path; total < pathlen;) { 3316 for (total = 0, path = target_path; total < pathlen;) {
3312 /* 3317 /*
3313 * Skip any slashes. 3318 * Skip any slashes.
3314 */ 3319 */
@@ -3402,7 +3407,7 @@ xfs_symlink(
3402 * Check for ability to enter directory entry, if no space reserved. 3407 * Check for ability to enter directory entry, if no space reserved.
3403 */ 3408 */
3404 if (resblks == 0 && 3409 if (resblks == 0 &&
3405 (error = XFS_DIR_CANENTER(mp, tp, dp, link_name, link_namelen))) 3410 (error = xfs_dir_canenter(tp, dp, link_name, link_namelen)))
3406 goto error_return; 3411 goto error_return;
3407 /* 3412 /*
3408 * Initialize the bmap freelist prior to calling either 3413 * Initialize the bmap freelist prior to calling either
@@ -3457,7 +3462,7 @@ xfs_symlink(
3457 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks, 3462 error = xfs_bmapi(tp, ip, first_fsb, fs_blocks,
3458 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, 3463 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
3459 &first_block, resblks, mval, &nmaps, 3464 &first_block, resblks, mval, &nmaps,
3460 &free_list); 3465 &free_list, NULL);
3461 if (error) { 3466 if (error) {
3462 goto error1; 3467 goto error1;
3463 } 3468 }
@@ -3489,11 +3494,10 @@ xfs_symlink(
3489 /* 3494 /*
3490 * Create the directory entry for the symlink. 3495 * Create the directory entry for the symlink.
3491 */ 3496 */
3492 error = XFS_DIR_CREATENAME(mp, tp, dp, link_name, link_namelen, 3497 error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino,
3493 ip->i_ino, &first_block, &free_list, resblks); 3498 &first_block, &free_list, resblks);
3494 if (error) { 3499 if (error)
3495 goto error1; 3500 goto error1;
3496 }
3497 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 3501 xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
3498 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 3502 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
3499 3503
@@ -3541,7 +3545,7 @@ std_return:
3541 } 3545 }
3542 3546
3543 if (!error) { 3547 if (!error) {
3544 vnode_t *vp; 3548 bhv_vnode_t *vp;
3545 3549
3546 ASSERT(ip); 3550 ASSERT(ip);
3547 vp = XFS_ITOV(ip); 3551 vp = XFS_ITOV(ip);
@@ -3606,10 +3610,10 @@ xfs_fid2(
3606int 3610int
3607xfs_rwlock( 3611xfs_rwlock(
3608 bhv_desc_t *bdp, 3612 bhv_desc_t *bdp,
3609 vrwlock_t locktype) 3613 bhv_vrwlock_t locktype)
3610{ 3614{
3611 xfs_inode_t *ip; 3615 xfs_inode_t *ip;
3612 vnode_t *vp; 3616 bhv_vnode_t *vp;
3613 3617
3614 vp = BHV_TO_VNODE(bdp); 3618 vp = BHV_TO_VNODE(bdp);
3615 if (VN_ISDIR(vp)) 3619 if (VN_ISDIR(vp))
@@ -3637,10 +3641,10 @@ xfs_rwlock(
3637void 3641void
3638xfs_rwunlock( 3642xfs_rwunlock(
3639 bhv_desc_t *bdp, 3643 bhv_desc_t *bdp,
3640 vrwlock_t locktype) 3644 bhv_vrwlock_t locktype)
3641{ 3645{
3642 xfs_inode_t *ip; 3646 xfs_inode_t *ip;
3643 vnode_t *vp; 3647 bhv_vnode_t *vp;
3644 3648
3645 vp = BHV_TO_VNODE(bdp); 3649 vp = BHV_TO_VNODE(bdp);
3646 if (VN_ISDIR(vp)) 3650 if (VN_ISDIR(vp))
@@ -3744,7 +3748,6 @@ xfs_inode_flush(
3744 return error; 3748 return error;
3745} 3749}
3746 3750
3747
3748int 3751int
3749xfs_set_dmattrs ( 3752xfs_set_dmattrs (
3750 bhv_desc_t *bdp, 3753 bhv_desc_t *bdp,
@@ -3785,16 +3788,12 @@ xfs_set_dmattrs (
3785 return error; 3788 return error;
3786} 3789}
3787 3790
3788
3789/*
3790 * xfs_reclaim
3791 */
3792STATIC int 3791STATIC int
3793xfs_reclaim( 3792xfs_reclaim(
3794 bhv_desc_t *bdp) 3793 bhv_desc_t *bdp)
3795{ 3794{
3796 xfs_inode_t *ip; 3795 xfs_inode_t *ip;
3797 vnode_t *vp; 3796 bhv_vnode_t *vp;
3798 3797
3799 vp = BHV_TO_VNODE(bdp); 3798 vp = BHV_TO_VNODE(bdp);
3800 ip = XFS_BHVTOI(bdp); 3799 ip = XFS_BHVTOI(bdp);
@@ -3849,7 +3848,7 @@ xfs_finish_reclaim(
3849 int sync_mode) 3848 int sync_mode)
3850{ 3849{
3851 xfs_ihash_t *ih = ip->i_hash; 3850 xfs_ihash_t *ih = ip->i_hash;
3852 vnode_t *vp = XFS_ITOV_NULL(ip); 3851 bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
3853 int error; 3852 int error;
3854 3853
3855 if (vp && VN_BAD(vp)) 3854 if (vp && VN_BAD(vp))
@@ -4116,10 +4115,10 @@ retry:
4116 * Issue the xfs_bmapi() call to allocate the blocks 4115 * Issue the xfs_bmapi() call to allocate the blocks
4117 */ 4116 */
4118 XFS_BMAP_INIT(&free_list, &firstfsb); 4117 XFS_BMAP_INIT(&free_list, &firstfsb);
4119 error = xfs_bmapi(tp, ip, startoffset_fsb, 4118 error = XFS_BMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4120 allocatesize_fsb, bmapi_flag, 4119 allocatesize_fsb, bmapi_flag,
4121 &firstfsb, 0, imapp, &nimaps, 4120 &firstfsb, 0, imapp, &nimaps,
4122 &free_list); 4121 &free_list, NULL);
4123 if (error) { 4122 if (error) {
4124 goto error0; 4123 goto error0;
4125 } 4124 }
@@ -4199,8 +4198,8 @@ xfs_zero_remaining_bytes(
4199 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { 4198 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
4200 offset_fsb = XFS_B_TO_FSBT(mp, offset); 4199 offset_fsb = XFS_B_TO_FSBT(mp, offset);
4201 nimap = 1; 4200 nimap = 1;
4202 error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0, NULL, 0, &imap, 4201 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, offset_fsb, 1, 0,
4203 &nimap, NULL); 4202 NULL, 0, &imap, &nimap, NULL, NULL);
4204 if (error || nimap < 1) 4203 if (error || nimap < 1)
4205 break; 4204 break;
4206 ASSERT(imap.br_blockcount >= 1); 4205 ASSERT(imap.br_blockcount >= 1);
@@ -4259,7 +4258,7 @@ xfs_free_file_space(
4259 xfs_off_t len, 4258 xfs_off_t len,
4260 int attr_flags) 4259 int attr_flags)
4261{ 4260{
4262 vnode_t *vp; 4261 bhv_vnode_t *vp;
4263 int committed; 4262 int committed;
4264 int done; 4263 int done;
4265 xfs_off_t end_dmi_offset; 4264 xfs_off_t end_dmi_offset;
@@ -4308,7 +4307,6 @@ xfs_free_file_space(
4308 return error; 4307 return error;
4309 } 4308 }
4310 4309
4311 ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
4312 if (attr_flags & ATTR_NOLOCK) 4310 if (attr_flags & ATTR_NOLOCK)
4313 need_iolock = 0; 4311 need_iolock = 0;
4314 if (need_iolock) { 4312 if (need_iolock) {
@@ -4326,7 +4324,7 @@ xfs_free_file_space(
4326 if (VN_CACHED(vp) != 0) { 4324 if (VN_CACHED(vp) != 0) {
4327 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1, 4325 xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
4328 ctooff(offtoct(ioffset)), -1); 4326 ctooff(offtoct(ioffset)), -1);
4329 VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)), 4327 bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
4330 -1, FI_REMAPF_LOCKED); 4328 -1, FI_REMAPF_LOCKED);
4331 } 4329 }
4332 4330
@@ -4338,8 +4336,8 @@ xfs_free_file_space(
4338 */ 4336 */
4339 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { 4337 if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
4340 nimap = 1; 4338 nimap = 1;
4341 error = xfs_bmapi(NULL, ip, startoffset_fsb, 1, 0, NULL, 0, 4339 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, startoffset_fsb,
4342 &imap, &nimap, NULL); 4340 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4343 if (error) 4341 if (error)
4344 goto out_unlock_iolock; 4342 goto out_unlock_iolock;
4345 ASSERT(nimap == 0 || nimap == 1); 4343 ASSERT(nimap == 0 || nimap == 1);
@@ -4353,8 +4351,8 @@ xfs_free_file_space(
4353 startoffset_fsb += mp->m_sb.sb_rextsize - mod; 4351 startoffset_fsb += mp->m_sb.sb_rextsize - mod;
4354 } 4352 }
4355 nimap = 1; 4353 nimap = 1;
4356 error = xfs_bmapi(NULL, ip, endoffset_fsb - 1, 1, 0, NULL, 0, 4354 error = XFS_BMAPI(mp, NULL, &ip->i_iocore, endoffset_fsb - 1,
4357 &imap, &nimap, NULL); 4355 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
4358 if (error) 4356 if (error)
4359 goto out_unlock_iolock; 4357 goto out_unlock_iolock;
4360 ASSERT(nimap == 0 || nimap == 1); 4358 ASSERT(nimap == 0 || nimap == 1);
@@ -4426,9 +4424,9 @@ xfs_free_file_space(
4426 * issue the bunmapi() call to free the blocks 4424 * issue the bunmapi() call to free the blocks
4427 */ 4425 */
4428 XFS_BMAP_INIT(&free_list, &firstfsb); 4426 XFS_BMAP_INIT(&free_list, &firstfsb);
4429 error = xfs_bunmapi(tp, ip, startoffset_fsb, 4427 error = XFS_BUNMAPI(mp, tp, &ip->i_iocore, startoffset_fsb,
4430 endoffset_fsb - startoffset_fsb, 4428 endoffset_fsb - startoffset_fsb,
4431 0, 2, &firstfsb, &free_list, &done); 4429 0, 2, &firstfsb, &free_list, NULL, &done);
4432 if (error) { 4430 if (error) {
4433 goto error0; 4431 goto error0;
4434 } 4432 }
@@ -4488,8 +4486,8 @@ xfs_change_file_space(
4488 xfs_off_t startoffset; 4486 xfs_off_t startoffset;
4489 xfs_off_t llen; 4487 xfs_off_t llen;
4490 xfs_trans_t *tp; 4488 xfs_trans_t *tp;
4491 vattr_t va; 4489 bhv_vattr_t va;
4492 vnode_t *vp; 4490 bhv_vnode_t *vp;
4493 4491
4494 vp = BHV_TO_VNODE(bdp); 4492 vp = BHV_TO_VNODE(bdp);
4495 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 4493 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
@@ -4642,9 +4640,10 @@ xfs_change_file_space(
4642 return error; 4640 return error;
4643} 4641}
4644 4642
4645vnodeops_t xfs_vnodeops = { 4643bhv_vnodeops_t xfs_vnodeops = {
4646 BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), 4644 BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
4647 .vop_open = xfs_open, 4645 .vop_open = xfs_open,
4646 .vop_close = xfs_close,
4648 .vop_read = xfs_read, 4647 .vop_read = xfs_read,
4649#ifdef HAVE_SENDFILE 4648#ifdef HAVE_SENDFILE
4650 .vop_sendfile = xfs_sendfile, 4649 .vop_sendfile = xfs_sendfile,