diff options
Diffstat (limited to 'fs')
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 | ||
| 105 | static struct super_block *v9fs_get_sb(struct file_system_type | 106 | static 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 | ||
| 189 | out_close_session: | 192 | out_close_session: |
| 190 | v9fs_session_close(v9ses); | 193 | v9fs_session_close(v9ses); |
| 191 | out_free_session: | 194 | out_free_session: |
| 192 | kfree(v9ses); | 195 | kfree(v9ses); |
| 193 | return sb; | 196 | return retval; |
| 194 | 197 | ||
| 195 | put_back_sb: | 198 | put_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 | ||
| 54 | config EXT2_FS_XIP | 54 | config 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 | ||
| 199 | static int adfs_statfs(struct super_block *sb, struct kstatfs *buf) | 199 | static 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 | ||
| 473 | static struct super_block *adfs_get_sb(struct file_system_type *fs_type, | 473 | static 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 | ||
| 479 | static struct file_system_type adfs_fs_type = { | 480 | static 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 | ||
| 19 | extern struct timezone sys_tz; | 19 | extern struct timezone sys_tz; |
| 20 | 20 | ||
| 21 | static int affs_statfs(struct super_block *sb, struct kstatfs *buf); | 21 | static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 22 | static int affs_remount (struct super_block *sb, int *flags, char *data); | 22 | static int affs_remount (struct super_block *sb, int *flags, char *data); |
| 23 | 23 | ||
| 24 | static void | 24 | static void |
| @@ -508,8 +508,9 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | static int | 510 | static int |
| 511 | affs_statfs(struct super_block *sb, struct kstatfs *buf) | 511 | affs_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 | ||
| 527 | static struct super_block *affs_get_sb(struct file_system_type *fs_type, | 528 | static 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 | ||
| 533 | static struct file_system_type affs_fs_type = { | 535 | static 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; | |||
| 63 | int afs_mntpt_check_symlink(struct afs_vnode *vnode) | 63 | int 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 { | |||
| 38 | static void afs_i_init_once(void *foo, kmem_cache_t *cachep, | 38 | static void afs_i_init_once(void *foo, kmem_cache_t *cachep, |
| 39 | unsigned long flags); | 39 | unsigned long flags); |
| 40 | 40 | ||
| 41 | static struct super_block *afs_get_sb(struct file_system_type *fs_type, | 41 | static 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 | ||
| 45 | static struct inode *afs_alloc_inode(struct super_block *sb); | 45 | static 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 | */ |
| 297 | static struct super_block *afs_get_sb(struct file_system_type *fs_type, | 297 | static 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 | /*****************************************************************************/ |
| @@ -777,11 +777,11 @@ out: | |||
| 777 | static int __aio_run_iocbs(struct kioctx *ctx) | 777 | static 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 | ||
| 17 | static struct super_block *autofs_get_sb(struct file_system_type *fs_type, | 17 | static 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 | ||
| 23 | static struct file_system_type autofs_fs_type = { | 23 | static 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 | ||
| 17 | static struct super_block *autofs_get_sb(struct file_system_type *fs_type, | 17 | static 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 | ||
| 23 | static struct file_system_type autofs_fs_type = { | 23 | static 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); |
| 50 | static void befs_put_super(struct super_block *); | 50 | static void befs_put_super(struct super_block *); |
| 51 | static int befs_remount(struct super_block *, int *, char *); | 51 | static int befs_remount(struct super_block *, int *, char *); |
| 52 | static int befs_statfs(struct super_block *, struct kstatfs *); | 52 | static int befs_statfs(struct dentry *, struct kstatfs *); |
| 53 | static int parse_options(char *, befs_mount_options *); | 53 | static int parse_options(char *, befs_mount_options *); |
| 54 | 54 | ||
| 55 | static const struct super_operations befs_sops = { | 55 | static const struct super_operations befs_sops = { |
| @@ -880,8 +880,9 @@ befs_remount(struct super_block *sb, int *flags, char *data) | |||
| 880 | } | 880 | } |
| 881 | 881 | ||
| 882 | static int | 882 | static int |
| 883 | befs_statfs(struct super_block *sb, struct kstatfs *buf) | 883 | befs_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 | ||
| 902 | static struct super_block * | 903 | static int |
| 903 | befs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, | 904 | befs_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 | ||
| 909 | static struct file_system_type befs_fs_type = { | 911 | static 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 | ||
| 206 | static int bfs_statfs(struct super_block *s, struct kstatfs *buf) | 206 | static 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 | ||
| 413 | static struct super_block *bfs_get_sb(struct file_system_type *fs_type, | 414 | static 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 | ||
| 419 | static struct file_system_type bfs_fs_type = { | 420 | static 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> | 46 | static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); |
| 47 | 47 | static int load_elf_library(struct file *); | |
| 48 | static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs); | ||
| 49 | static int load_elf_library(struct file*); | ||
| 50 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); | 48 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); |
| 51 | extern int dump_fpu (struct pt_regs *, elf_fpregset_t *); | 49 | extern 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) |
| 62 | static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file); | 60 | static 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 | ||
| 91 | static int set_brk(unsigned long start, unsigned long end) | 89 | static 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 | |||
| 114 | static int padzero(unsigned long elf_bss) | 110 | static 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 | ||
| 140 | static int | 138 | static int |
| 141 | create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, | 139 | create_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 | ||
| 287 | static unsigned long elf_map(struct file *filep, unsigned long addr, | 288 | static 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 | ||
| 313 | static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, | 314 | static 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 | ||
| 441 | out_close: | 449 | out_close: |
| 442 | kfree(elf_phdata); | 450 | kfree(elf_phdata); |
| @@ -444,8 +452,8 @@ out: | |||
| 444 | return error; | 452 | return error; |
| 445 | } | 453 | } |
| 446 | 454 | ||
| 447 | static unsigned long load_aout_interp(struct exec * interp_ex, | 455 | static 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(¤t->mm->mmap_sem); | 491 | down_write(¤t->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 | ||
| 522 | static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) | 529 | static 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(¤t->mm->mmap_sem); | 998 | down_write(¤t->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 | |||
| 1041 | static int load_elf_library(struct file *file) | 1052 | static 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(¤t->mm->mmap_sem); | 1122 | down_write(¤t->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 */ |
| 1180 | struct memelfnote | 1192 | struct 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 | */ |
| 1283 | static void fill_prstatus(struct elf_prstatus *prstatus, | 1295 | static 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 | */ |
| 1372 | static int elf_dump_thread_status(long signr, struct elf_thread_status *t) | 1384 | static 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 | */ |
| 1408 | static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) | 1424 | static 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(¬es[numnote++], "CORE", NT_AUXV, | 1542 | fill_note(¬es[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 | ||
| 744 | static struct super_block *bm_get_sb(struct file_system_type *fs_type, | 743 | static 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 | ||
| 750 | static struct linux_binfmt misc_format = { | 749 | static 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 | ||
| 303 | static struct super_block *bd_get_sb(struct file_system_type *fs_type, | 303 | static 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 | ||
| 309 | static struct file_system_type bd_type = { | 309 | static struct file_system_type bd_type = { |
| @@ -414,21 +414,31 @@ EXPORT_SYMBOL(bdput); | |||
| 414 | static struct block_device *bd_acquire(struct inode *inode) | 414 | static 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 | ||
| 439 | void bd_forget(struct inode *inode) | 449 | void 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 | ||
| 447 | int bd_claim(struct block_device *bdev, void *holder) | 465 | int 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; | ||
| 350 | out: | 348 | out: |
| 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 | ||
| 168 | static int | 168 | static int |
| 169 | cifs_statfs(struct super_block *sb, struct kstatfs *buf) | 169 | cifs_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 | ||
| 465 | static struct super_block * | 466 | static int |
| 466 | cifs_get_sb(struct file_system_type *fs_type, | 467 | cifs_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 | ||
| 489 | static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, | 490 | static 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); |
| 75 | extern int cifs_lock(struct file *, int, struct file_lock *); | 75 | extern int cifs_lock(struct file *, int, struct file_lock *); |
| 76 | extern int cifs_fsync(struct file *, struct dentry *, int); | 76 | extern int cifs_fsync(struct file *, struct dentry *, int); |
| 77 | extern int cifs_flush(struct file *); | 77 | extern int cifs_flush(struct file *, fl_owner_t id); |
| 78 | extern int cifs_file_mmap(struct file * , struct vm_area_struct *); | 78 | extern int cifs_file_mmap(struct file * , struct vm_area_struct *); |
| 79 | extern const struct file_operations cifs_dir_ops; | 79 | extern const struct file_operations cifs_dir_ops; |
| 80 | extern int cifs_dir_open(struct inode *inode, struct file *file); | 80 | extern 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 | } |
| 1137 | retry: | 1135 | retry: |
| @@ -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 | */ |
| 1422 | int cifs_flush(struct file *file) | 1420 | int 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 | ||
| 167 | int coda_flush(struct file *coda_file) | 167 | int 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 */ |
| 37 | static void coda_clear_inode(struct inode *); | 37 | static void coda_clear_inode(struct inode *); |
| 38 | static void coda_put_super(struct super_block *); | 38 | static void coda_put_super(struct super_block *); |
| 39 | static int coda_statfs(struct super_block *sb, struct kstatfs *buf); | 39 | static int coda_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 40 | 40 | ||
| 41 | static kmem_cache_t * coda_inode_cachep; | 41 | static 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 | ||
| 281 | static int coda_statfs(struct super_block *sb, struct kstatfs *buf) | 281 | static 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 | ||
| 310 | static struct super_block *coda_get_sb(struct file_system_type *fs_type, | 310 | static 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 | ||
| 316 | struct file_system_type coda_fs_type = { | 316 | struct 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 | ||
| 614 | int venus_statfs(struct super_block *sb, struct kstatfs *sfs) | 614 | int 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 | ||
| 106 | static struct super_block *configfs_get_sb(struct file_system_type *fs_type, | 106 | static 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 | ||
| 112 | static struct file_system_type configfs_fs_type = { | 112 | static 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 | ||
| 325 | static int cramfs_statfs(struct super_block *sb, struct kstatfs *buf) | 323 | static 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 | ||
| 531 | static struct super_block *cramfs_get_sb(struct file_system_type *fs_type, | 531 | static 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 | ||
| 537 | static struct file_system_type cramfs_fs_type = { | 538 | static 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 | */ |
| 367 | static inline void prune_one_dentry(struct dentry * dentry) | 368 | static 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 | ||
| 395 | static void prune_dcache(int count) | 398 | static 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 | */ | ||
| 646 | void 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 | ||
| 114 | static struct super_block *debug_get_sb(struct file_system_type *fs_type, | 114 | static 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 | ||
| 121 | static struct file_system_type debug_fs_type = { | 121 | static 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 | ||
| 2552 | static struct super_block *devfs_get_sb(struct file_system_type *fs_type, | 2552 | static 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 | ||
| 2559 | static struct file_system_type devfs_fs_type = { | 2559 | static 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 | ||
| 133 | static struct super_block *devpts_get_sb(struct file_system_type *fs_type, | 133 | static 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 | ||
| 139 | static struct file_system_type devpts_fs_type = { | 139 | static 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(¤t->mm->mmap_sem); | 163 | up_read(¤t->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 | } |
| 1291 | EXPORT_SYMBOL(__blockdev_direct_IO); | 1289 | EXPORT_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 | ||
| 18 | static int efs_statfs(struct super_block *s, struct kstatfs *buf); | 18 | static int efs_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 19 | static int efs_fill_super(struct super_block *s, void *d, int silent); | 19 | static int efs_fill_super(struct super_block *s, void *d, int silent); |
| 20 | 20 | ||
| 21 | static struct super_block *efs_get_sb(struct file_system_type *fs_type, | 21 | static 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 | ||
| 27 | static struct file_system_type efs_fs_type = { | 27 | static struct file_system_type efs_fs_type = { |
| @@ -322,8 +322,8 @@ out_no_fs: | |||
| 322 | return -EINVAL; | 322 | return -EINVAL; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | static int efs_statfs(struct super_block *s, struct kstatfs *buf) { | 325 | static 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); |
| 269 | static int eventpollfs_delete_dentry(struct dentry *dentry); | 269 | static int eventpollfs_delete_dentry(struct dentry *dentry); |
| 270 | static struct inode *ep_eventpoll_inode(void); | 270 | static struct inode *ep_eventpoll_inode(void); |
| 271 | static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type, | 271 | static 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 | ||
| 1598 | static struct super_block * | 1598 | static int |
| 1599 | eventpollfs_get_sb(struct file_system_type *fs_type, int flags, | 1599 | eventpollfs_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 | ||
| @@ -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: | |||
| 159 | static struct page * ext2_get_page(struct inode *dir, unsigned long n) | 159 | static 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 @@ | |||
| 39 | static void ext2_sync_super(struct super_block *sb, | 39 | static void ext2_sync_super(struct super_block *sb, |
| 40 | struct ext2_super_block *es); | 40 | struct ext2_super_block *es); |
| 41 | static int ext2_remount (struct super_block * sb, int * flags, char * data); | 41 | static int ext2_remount (struct super_block * sb, int * flags, char * data); |
| 42 | static int ext2_statfs (struct super_block * sb, struct kstatfs * buf); | 42 | static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf); |
| 43 | 43 | ||
| 44 | void ext2_error (struct super_block * sb, const char * function, | 44 | void 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 | ||
| 897 | cantfind_ext2: | 895 | cantfind_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 | 900 | failed_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); | ||
| 903 | failed_mount2: | 904 | failed_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 | ||
| 1041 | static int ext2_statfs (struct super_block * sb, struct kstatfs * buf) | 1042 | static 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 | ||
| 1090 | static struct super_block *ext2_get_sb(struct file_system_type *fs_type, | 1092 | static 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); | |||
| 58 | static const char *ext3_decode_error(struct super_block * sb, int errno, | 58 | static const char *ext3_decode_error(struct super_block * sb, int errno, |
| 59 | char nbuf[16]); | 59 | char nbuf[16]); |
| 60 | static int ext3_remount (struct super_block * sb, int * flags, char * data); | 60 | static int ext3_remount (struct super_block * sb, int * flags, char * data); |
| 61 | static int ext3_statfs (struct super_block * sb, struct kstatfs * buf); | 61 | static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf); |
| 62 | static void ext3_unlockfs(struct super_block *sb); | 62 | static void ext3_unlockfs(struct super_block *sb); |
| 63 | static void ext3_write_super (struct super_block * sb); | 63 | static void ext3_write_super (struct super_block * sb); |
| 64 | static void ext3_write_super_lockfs(struct super_block *sb); | 64 | static 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 | ||
| 518 | static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb) | 519 | static 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 | ||
| 1742 | failed_mount3: | 1741 | failed_mount4: |
| 1743 | journal_destroy(sbi->s_journal); | 1742 | journal_destroy(sbi->s_journal); |
| 1743 | failed_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); | ||
| 1744 | failed_mount2: | 1747 | failed_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 | ||
| 2321 | static int ext3_statfs (struct super_block * sb, struct kstatfs * buf) | 2324 | static 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 | ||
| 2649 | static struct super_block *ext3_get_sb(struct file_system_type *fs_type, | 2653 | static 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 | ||
| 2655 | static struct file_system_type ext3_fs_type = { | 2659 | static 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 | ||
| 542 | static int fat_statfs(struct super_block *sb, struct kstatfs *buf) | 542 | static 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 | ||
| 213 | EXPORT_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 | ||
| 57 | static void vxfs_put_super(struct super_block *); | 58 | static void vxfs_put_super(struct super_block *); |
| 58 | static int vxfs_statfs(struct super_block *, struct kstatfs *); | 59 | static int vxfs_statfs(struct dentry *, struct kstatfs *); |
| 59 | static int vxfs_remount(struct super_block *, int *, char *); | 60 | static int vxfs_remount(struct super_block *, int *, char *); |
| 60 | 61 | ||
| 61 | static struct super_operations vxfs_super_ops = { | 62 | static 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 | */ |
| 109 | static int | 110 | static int |
| 110 | vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp) | 111 | vxfs_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 | */ |
| 244 | static struct super_block *vxfs_get_sb(struct file_system_type *fs_type, | 245 | static 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 | ||
| 250 | static struct file_system_type vxfs_fs_type = { | 252 | static 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 | ||
| 172 | static int fuse_flush(struct file *file) | 172 | static 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 | ||
| 240 | static int fuse_statfs(struct super_block *sb, struct kstatfs *buf) | 240 | static 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 | ||
| 573 | static struct super_block *fuse_get_sb(struct file_system_type *fs_type, | 574 | static 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 | ||
| 580 | static struct file_system_type fuse_fs_type = { | 581 | static 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 | */ |
| 83 | static int hfs_statfs(struct super_block *sb, struct kstatfs *buf) | 83 | static 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 | ||
| 416 | static struct super_block *hfs_get_sb(struct file_system_type *fs_type, | 418 | static 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 | ||
| 422 | static struct file_system_type hfs_fs_type = { | 425 | static 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 | ||
| 215 | static int hfsplus_statfs(struct super_block *sb, struct kstatfs *buf) | 215 | static 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 | ||
| 453 | static struct super_block *hfsplus_get_sb(struct file_system_type *fs_type, | 455 | static 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 | ||
| 459 | static struct file_system_type hfsplus_fs_type = { | 463 | static 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 | ||
| 242 | int hostfs_statfs(struct super_block *sb, struct kstatfs *sf) | 242 | int 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 | ||
| 996 | static struct super_block *hostfs_read_sb(struct file_system_type *type, | 996 | static 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 | ||
| 1003 | static struct file_system_type hostfs_type = { | 1003 | static 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 | ||
| 138 | static int hpfs_statfs(struct super_block *s, struct kstatfs *buf) | 138 | static 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 | ||
| 665 | static struct super_block *hpfs_get_sb(struct file_system_type *fs_type, | 666 | static 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 | ||
| 671 | static struct file_system_type hpfs_fs_type = { | 673 | static 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 | ||
| 619 | static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf) | 619 | static 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 | ||
| 772 | static struct super_block *hppfs_read_super(struct file_system_type *type, | 772 | static 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 | ||
| 779 | static struct file_system_type hppfs_type = { | 779 | static 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) | |||
| 59 | static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | 59 | static 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 | ||
| 230 | static void hugetlbfs_delete_inode(struct inode *inode) | 228 | static 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 | ||
| 470 | static int hugetlbfs_statfs(struct super_block *sb, struct kstatfs *buf) | 469 | static 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 | ||
| 726 | static struct super_block *hugetlbfs_get_sb(struct file_system_type *fs_type, | 724 | static 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 | ||
| 732 | static struct file_system_type hugetlbfs_fs_type = { | 730 | static 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 | ||
| 675 | static struct super_block * | 675 | static int |
| 676 | inotify_get_sb(struct file_system_type *fs_type, int flags, | 676 | inotify_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 | ||
| 682 | static struct file_system_type inotify_fs_type = { | 682 | static 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 | ||
| 28 | static int set_task_ioprio(struct task_struct *task, int ioprio) | 29 | static 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 | ||
| 58 | static void isofs_read_inode(struct inode *); | 58 | static void isofs_read_inode(struct inode *); |
| 59 | static int isofs_statfs (struct super_block *, struct kstatfs *); | 59 | static int isofs_statfs (struct dentry *, struct kstatfs *); |
| 60 | 60 | ||
| 61 | static kmem_cache_t *isofs_inode_cachep; | 61 | static kmem_cache_t *isofs_inode_cachep; |
| 62 | 62 | ||
| @@ -901,8 +901,10 @@ out_freesbi: | |||
| 901 | return -EINVAL; | 901 | return -EINVAL; |
| 902 | } | 902 | } |
| 903 | 903 | ||
| 904 | static int isofs_statfs (struct super_block *sb, struct kstatfs *buf) | 904 | static 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 | ||
| 1402 | static struct super_block *isofs_get_sb(struct file_system_type *fs_type, | 1404 | static 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 | ||
| 1408 | static struct file_system_type iso9660_fs_type = { | 1411 | static 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 | 31 | static inline void __buffer_unlink_first(struct journal_head *jh) | |
| 32 | static 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 | */ | ||
| 49 | static 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 | */ | ||
| 66 | static 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 | */ |
| 131 | static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) | 164 | static 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) | 172 | restart: |
| 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; | ||
| 194 | out_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 | */ |
| 227 | static int __flush_buffer(journal_t *journal, struct journal_head *jh, | 233 | static 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 | */ |
| 283 | int log_do_checkpoint(journal_t *journal) | 298 | int 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; | ||
| 325 | restart: | ||
| 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 | } |
| 374 | out: | ||
| 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 | |||
| 472 | static 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 | ||
| 468 | int __journal_clean_checkpoint_list(journal_t *journal) | 520 | int __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); |
| 506 | out: | 556 | out: |
| 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 | ||
| 527 | void __journal_remove_checkpoint(struct journal_head *jh) | 580 | int __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; | ||
| 568 | out: | 625 | out: |
| 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); |
| 229 | out: | 229 | out: |
| 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 | ||
| 726 | out: | 727 | out: |
| 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); |
| 904 | out: | 906 | out: |
| 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. */ |
| 379 | static int | 379 | static int |
| 380 | jffs_statfs(struct super_block *sb, struct kstatfs *buf) | 380 | jffs_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 | ||
| 1788 | static struct super_block *jffs_get_sb(struct file_system_type *fs_type, | 1788 | static 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 | ||
| 1794 | static struct file_system_type jffs_fs_type = { | 1795 | static 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 | ||
| 195 | int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) | 195 | int 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 *); | |||
| 175 | void jffs2_dirty_inode(struct inode *inode); | 175 | void jffs2_dirty_inode(struct inode *inode); |
| 176 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, | 176 | struct inode *jffs2_new_inode (struct inode *dir_i, int mode, |
| 177 | struct jffs2_raw_inode *ri); | 177 | struct jffs2_raw_inode *ri); |
| 178 | int jffs2_statfs (struct super_block *, struct kstatfs *); | 178 | int jffs2_statfs (struct dentry *, struct kstatfs *); |
| 179 | void jffs2_write_super (struct super_block *); | 179 | void jffs2_write_super (struct super_block *); |
| 180 | int jffs2_remount_fs (struct super_block *, int *, char *); | 180 | int jffs2_remount_fs (struct super_block *, int *, char *); |
| 181 | int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); | 181 | int 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 | ||
| 114 | static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, | 114 | static 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 | ||
| 172 | out_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 | ||
| 177 | static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type, | 181 | static 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 | ||
| 192 | static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, | 197 | static 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 | ||
| 274 | out: | 279 | out: |
| 275 | path_release(&nd); | 280 | path_release(&nd); |
| 276 | return ERR_PTR(err); | 281 | return err; |
| 277 | } | 282 | } |
| 278 | 283 | ||
| 279 | static void jffs2_put_super (struct super_block *sb) | 284 | static 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 | ||
| 142 | static int jfs_statfs(struct super_block *sb, struct kstatfs *buf) | 142 | static 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 | ||
| 568 | static struct super_block *jfs_get_sb(struct file_system_type *fs_type, | 568 | static 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 | ||
| 574 | static int jfs_sync_fs(struct super_block *sb, int wait) | 575 | static 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 | ||
| 23 | int simple_statfs(struct super_block *sb, struct kstatfs *buf) | 23 | int 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 | */ |
| 199 | struct super_block * | 199 | int get_sb_pseudo(struct file_system_type *fs_type, char *name, |
| 200 | get_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 | ||
| 237 | Enomem: | 237 | Enomem: |
| 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 | ||
| 243 | int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) | 243 | int 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 | */ |
| 706 | int posix_locks_deadlock(struct file_lock *caller_fl, | 706 | static 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 | ||
| 725 | EXPORT_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: | |||
| 794 | static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, struct file_lock *conflock) | 792 | static 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 | */ |
| 1882 | void locks_remove_posix(struct file *filp, fl_owner_t owner) | 1895 | void 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(); | ||
| 1923 | out: | ||
| 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 | ||
| 2207 | EXPORT_SYMBOL(lock_may_write); | 2205 | EXPORT_SYMBOL(lock_may_write); |
| 2208 | 2206 | ||
| 2209 | static 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 | */ | ||
| 2227 | void 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 | } | ||
| 2264 | EXPORT_SYMBOL(steal_locks); | ||
| 2265 | |||
| 2266 | static int __init filelock_init(void) | 2207 | static 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) | |||
| 60 | static struct page * dir_get_page(struct inode *dir, unsigned long n) | 60 | static 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 | ||
| 20 | static void minix_read_inode(struct inode * inode); | 20 | static void minix_read_inode(struct inode * inode); |
| 21 | static int minix_write_inode(struct inode * inode, int wait); | 21 | static int minix_write_inode(struct inode * inode, int wait); |
| 22 | static int minix_statfs(struct super_block *sb, struct kstatfs *buf); | 22 | static int minix_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 23 | static int minix_remount (struct super_block * sb, int * flags, char * data); | 23 | static int minix_remount (struct super_block * sb, int * flags, char * data); |
| 24 | 24 | ||
| 25 | static void minix_delete_inode(struct inode *inode) | 25 | static void minix_delete_inode(struct inode *inode) |
| @@ -296,11 +296,11 @@ out_bad_sb: | |||
| 296 | return -EINVAL; | 296 | return -EINVAL; |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | static int minix_statfs(struct super_block *sb, struct kstatfs *buf) | 299 | static 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 | ||
| 562 | static struct super_block *minix_get_sb(struct file_system_type *fs_type, | 562 | static 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 | ||
| 568 | static struct file_system_type minix_fs_type = { | 569 | static 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 | } |
| 736 | retry: | 734 | retry: |
| @@ -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 | ||
| 664 | static struct super_block *msdos_get_sb(struct file_system_type *fs_type, | 664 | static 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 | ||
| 671 | static struct file_system_type msdos_fs_type = { | 672 | static 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 | ||
| 89 | int 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 | |||
| 96 | EXPORT_SYMBOL(simple_set_mnt); | ||
| 97 | |||
| 89 | void free_vfsmnt(struct vfsmount *mnt) | 98 | void 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 | ||
| 40 | static void ncp_delete_inode(struct inode *); | 40 | static void ncp_delete_inode(struct inode *); |
| 41 | static void ncp_put_super(struct super_block *); | 41 | static void ncp_put_super(struct super_block *); |
| 42 | static int ncp_statfs(struct super_block *, struct kstatfs *); | 42 | static int ncp_statfs(struct dentry *, struct kstatfs *); |
| 43 | 43 | ||
| 44 | static kmem_cache_t * ncp_inode_cachep; | 44 | static 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 | ||
| 727 | static int ncp_statfs(struct super_block *sb, struct kstatfs *buf) | 727 | static 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 | ||
| 960 | static struct super_block *ncp_get_sb(struct file_system_type *fs_type, | 961 | static 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 | ||
| 966 | static struct file_system_type ncp_fs_type = { | 967 | static 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 *); | |||
| 43 | static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); | 43 | static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); |
| 44 | static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); | 44 | static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); |
| 45 | static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); | 45 | static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); |
| 46 | static int nfs_file_flush(struct file *); | 46 | static int nfs_file_flush(struct file *, fl_owner_t id); |
| 47 | static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); | 47 | static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); |
| 48 | static int nfs_check_flags(int flags); | 48 | static int nfs_check_flags(int flags); |
| 49 | static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); | 49 | static 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 | */ |
| 173 | static int | 173 | static int |
| 174 | nfs_file_flush(struct file *file) | 174 | nfs_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 | ||
| 109 | static void nfs_umount_begin(struct vfsmount *, int); | 109 | static void nfs_umount_begin(struct vfsmount *, int); |
| 110 | static int nfs_statfs(struct super_block *, struct kstatfs *); | 110 | static int nfs_statfs(struct dentry *, struct kstatfs *); |
| 111 | static int nfs_show_options(struct seq_file *, struct vfsmount *); | 111 | static int nfs_show_options(struct seq_file *, struct vfsmount *); |
| 112 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); | 112 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); |
| 113 | static struct super_block *nfs_get_sb(struct file_system_type *, int, const char *, void *); | 113 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); |
| 114 | static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type, | 114 | static 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); |
| 116 | static void nfs_kill_super(struct super_block *); | 116 | static void nfs_kill_super(struct super_block *); |
| 117 | 117 | ||
| 118 | static struct file_system_type nfs_fs_type = { | 118 | static 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 |
| 146 | static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | 146 | static 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); |
| 148 | static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type, | 148 | static 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); |
| 150 | static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type, | 150 | static 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); |
| 152 | static void nfs4_kill_super(struct super_block *sb); | 152 | static void nfs4_kill_super(struct super_block *sb); |
| 153 | 153 | ||
| 154 | static struct file_system_type nfs4_fs_type = { | 154 | static 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 | */ |
| 266 | static int nfs_statfs(struct super_block *sb, struct kstatfs *buf) | 266 | static 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 | */ |
| 773 | static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data, | 774 | static 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); | ||
| 805 | out_deactivate: | 815 | out_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; |
| 819 | out_rpciod_down: | ||
| 820 | rpciod_down(); | ||
| 821 | kfree(server->hostname); | ||
| 822 | kfree(server); | ||
| 823 | return simple_set_mnt(mnt, sb); | ||
| 809 | kill_rpciod: | 824 | kill_rpciod: |
| 810 | rpciod_down(); | 825 | rpciod_down(); |
| 811 | free_hostname: | 826 | free_hostname: |
| @@ -813,7 +828,7 @@ free_hostname: | |||
| 813 | free_server: | 828 | free_server: |
| 814 | kfree(server); | 829 | kfree(server); |
| 815 | out_err: | 830 | out_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 | ||
| 942 | static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | 957 | static 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 | |||
| 1043 | out_rpciod_down: | 1064 | out_rpciod_down: |
| 1044 | rpciod_down(); | 1065 | rpciod_down(); |
| 1066 | kfree(server); | ||
| 1067 | return simple_set_mnt(mnt, s); | ||
| 1068 | |||
| 1069 | out_err_rpciod: | ||
| 1070 | rpciod_down(); | ||
| 1045 | out_err: | 1071 | out_err: |
| 1046 | kfree(server); | 1072 | kfree(server); |
| 1047 | return s; | 1073 | out_err_noserver: |
| 1074 | return error; | ||
| 1048 | } | 1075 | } |
| 1049 | 1076 | ||
| 1050 | static void nfs_kill_super(struct super_block *s) | 1077 | static 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 | ||
| 1086 | static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type, | 1113 | static 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 | ||
| 1269 | static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | 1296 | static 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); |
| 1349 | out_err: | 1385 | out_err: |
| 1350 | s = (struct super_block *)p; | 1386 | error = PTR_ERR(p); |
| 1351 | out_free: | 1387 | out_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 | ||
| 1358 | static void nfs4_kill_super(struct super_block *sb) | 1394 | static void nfs4_kill_super(struct super_block *sb) |
| @@ -1430,11 +1466,11 @@ err: | |||
| 1430 | return sb; | 1466 | return sb; |
| 1431 | } | 1467 | } |
| 1432 | 1468 | ||
| 1433 | static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type, | 1469 | static 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 | ||
| 1440 | static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data) | 1476 | static 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 | ||
| 1490 | static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type, | 1526 | static 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 | ||
| 497 | static struct super_block *nfsd_get_sb(struct file_system_type *fs_type, | 497 | static 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 | ||
| 503 | static struct file_system_type nfsd_fs_type = { | 503 | static 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 | |||
| 1737 | nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) | 1737 | nfsd_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) | |||
| 86 | static inline struct page *ntfs_map_page(struct address_space *mapping, | 86 | static 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 | */ |
| 2620 | static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs) | 2620 | static 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. */ |
| 3094 | DEFINE_MUTEX(ntfs_lock); | 3095 | DEFINE_MUTEX(ntfs_lock); |
| 3095 | 3096 | ||
| 3096 | static struct super_block *ntfs_get_sb(struct file_system_type *fs_type, | 3097 | static 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 | ||
| 3102 | static struct file_system_type ntfs_fs_type = { | 3104 | static 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 | ||
| 577 | static struct super_block *dlmfs_get_sb(struct file_system_type *fs_type, | 577 | static 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 | ||
| 583 | static struct file_system_type dlmfs_fs_type = { | 583 | static 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); | |||
| 100 | static void ocfs2_free_mem_caches(void); | 100 | static void ocfs2_free_mem_caches(void); |
| 101 | static void ocfs2_delete_osb(struct ocfs2_super *osb); | 101 | static void ocfs2_delete_osb(struct ocfs2_super *osb); |
| 102 | 102 | ||
| 103 | static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf); | 103 | static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 104 | 104 | ||
| 105 | static int ocfs2_sync_fs(struct super_block *sb, int wait); | 105 | static 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 | ||
| 675 | static struct super_block *ocfs2_get_sb(struct file_system_type *fs_type, | 675 | static 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 | ||
| 683 | static struct file_system_type ocfs2_fs_type = { | 685 | static 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 | ||
| 858 | static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf) | 860 | static 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); |
| @@ -31,18 +31,18 @@ | |||
| 31 | 31 | ||
| 32 | #include <asm/unistd.h> | 32 | #include <asm/unistd.h> |
| 33 | 33 | ||
| 34 | int vfs_statfs(struct super_block *sb, struct kstatfs *buf) | 34 | int 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 | ||
| 53 | EXPORT_SYMBOL(vfs_statfs); | 53 | EXPORT_SYMBOL(vfs_statfs); |
| 54 | 54 | ||
| 55 | static int vfs_statfs_native(struct super_block *sb, struct statfs *buf) | 55 | static 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 | ||
| 98 | static int vfs_statfs64(struct super_block *sb, struct statfs64 *buf) | 98 | static 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 | ||
| 1057 | static struct super_block *openprom_get_sb(struct file_system_type *fs_type, | 1057 | static 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 | ||
| 1063 | static struct file_system_type openprom_fs_type = { | 1063 | static 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 | } |
| @@ -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 | 982 | static int pipefs_get_sb(struct file_system_type *fs_type, | |
| 983 | static struct super_block * | 983 | int flags, const char *dev_name, void *data, |
| 984 | pipefs_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 | ||
| 990 | static struct file_system_type pipe_fs_type = { | 989 | static 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 | |||
| 26 | struct proc_dir_entry *proc_sys_root; | 26 | struct proc_dir_entry *proc_sys_root; |
| 27 | #endif | 27 | #endif |
| 28 | 28 | ||
| 29 | static struct super_block *proc_get_sb(struct file_system_type *fs_type, | 29 | static 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 | ||
| 35 | static struct file_system_type proc_fs_type = { | 35 | static 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); | |||
| 128 | static void qnx4_destroy_inode(struct inode *inode); | 128 | static void qnx4_destroy_inode(struct inode *inode); |
| 129 | static void qnx4_read_inode(struct inode *); | 129 | static void qnx4_read_inode(struct inode *); |
| 130 | static int qnx4_remount(struct super_block *sb, int *flags, char *data); | 130 | static int qnx4_remount(struct super_block *sb, int *flags, char *data); |
| 131 | static int qnx4_statfs(struct super_block *, struct kstatfs *); | 131 | static int qnx4_statfs(struct dentry *, struct kstatfs *); |
| 132 | 132 | ||
| 133 | static struct super_operations qnx4_sops = | 133 | static 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 | ||
| 285 | static int qnx4_statfs(struct super_block *sb, struct kstatfs *buf) | 285 | static 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 | ||
| 564 | static struct super_block *qnx4_get_sb(struct file_system_type *fs_type, | 566 | static 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 | ||
| 570 | static struct file_system_type qnx4_fs_type = { | 573 | static 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 | ||
| 188 | struct super_block *ramfs_get_sb(struct file_system_type *fs_type, | 188 | int 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 | ||
| 194 | static struct super_block *rootfs_get_sb(struct file_system_type *fs_type, | 194 | static 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 | ||
| 200 | static struct file_system_type ramfs_fs_type = { | 201 | static 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 | ||
| 62 | static int reiserfs_remount(struct super_block *s, int *flags, char *data); | 62 | static int reiserfs_remount(struct super_block *s, int *flags, char *data); |
| 63 | static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf); | 63 | static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 64 | 64 | ||
| 65 | static int reiserfs_sync_fs(struct super_block *s, int wait) | 65 | static 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 | ||
| 1941 | static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf) | 1941 | static 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 | ||
| 2252 | static struct super_block *get_super_block(struct file_system_type *fs_type, | 2252 | static 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 | ||
| 2259 | static int __init init_reiserfs_fs(void) | 2260 | static 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 | ||
| 181 | static int | 181 | static int |
| 182 | romfs_statfs(struct super_block *sb, struct kstatfs *buf) | 182 | romfs_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 | ||
| 610 | static struct super_block *romfs_get_sb(struct file_system_type *fs_type, | 610 | static 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 | ||
| 616 | static struct file_system_type romfs_fs_type = { | 617 | static 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 | ||
| 549 | static 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 | */ | ||
| 556 | static 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 | ||
| 582 | static int do_poll(unsigned int nfds, struct poll_list *list, | 583 | static 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 | ||
| 49 | static void smb_delete_inode(struct inode *); | 49 | static void smb_delete_inode(struct inode *); |
| 50 | static void smb_put_super(struct super_block *); | 50 | static void smb_put_super(struct super_block *); |
| 51 | static int smb_statfs(struct super_block *, struct kstatfs *); | 51 | static int smb_statfs(struct dentry *, struct kstatfs *); |
| 52 | static int smb_show_options(struct seq_file *, struct vfsmount *); | 52 | static int smb_show_options(struct seq_file *, struct vfsmount *); |
| 53 | 53 | ||
| 54 | static kmem_cache_t *smb_inode_cachep; | 54 | static kmem_cache_t *smb_inode_cachep; |
| @@ -641,13 +641,13 @@ out_no_server: | |||
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | static int | 643 | static int |
| 644 | smb_statfs(struct super_block *sb, struct kstatfs *buf) | 644 | smb_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 | ||
| 785 | static struct super_block *smb_get_sb(struct file_system_type *fs_type, | 785 | static 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 | ||
| 791 | static struct file_system_type smb_fs_type = { | 791 | static 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 | ||
| 3228 | int | 3228 | int |
| 3229 | smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr) | 3229 | smb_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); | |||
| 29 | extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr); | 29 | extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr); |
| 30 | extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor); | 30 | extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor); |
| 31 | extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr); | 31 | extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr); |
| 32 | extern int smb_proc_dskattr(struct super_block *sb, struct kstatfs *attr); | 32 | extern int smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr); |
| 33 | extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len); | 33 | extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len); |
| 34 | extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath); | 34 | extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath); |
| 35 | extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry); | 35 | extern 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 | ||
| 85 | static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe, | 97 | static 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 | ||
| 679 | struct super_block *get_sb_bdev(struct file_system_type *fs_type, | 679 | int 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 | ||
| 728 | out: | 731 | error_s: |
| 732 | error = PTR_ERR(s); | ||
| 733 | error_bdev: | ||
| 729 | close_bdev_excl(bdev); | 734 | close_bdev_excl(bdev); |
| 730 | return s; | 735 | error: |
| 736 | return error; | ||
| 731 | } | 737 | } |
| 732 | 738 | ||
| 733 | EXPORT_SYMBOL(get_sb_bdev); | 739 | EXPORT_SYMBOL(get_sb_bdev); |
| @@ -744,15 +750,16 @@ void kill_block_super(struct super_block *sb) | |||
| 744 | 750 | ||
| 745 | EXPORT_SYMBOL(kill_block_super); | 751 | EXPORT_SYMBOL(kill_block_super); |
| 746 | 752 | ||
| 747 | struct super_block *get_sb_nodev(struct file_system_type *fs_type, | 753 | int 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 | ||
| 769 | EXPORT_SYMBOL(get_sb_nodev); | 776 | EXPORT_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 | ||
| 776 | struct super_block *get_sb_single(struct file_system_type *fs_type, | 783 | int 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 | ||
| 800 | EXPORT_SYMBOL(get_sb_single); | 808 | EXPORT_SYMBOL(get_sb_single); |
| @@ -802,52 +810,51 @@ EXPORT_SYMBOL(get_sb_single); | |||
| 802 | struct vfsmount * | 810 | struct vfsmount * |
| 803 | vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data) | 811 | vfs_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; |
| 841 | out_sb: | 848 | out_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); |
| 845 | out_free_secdata: | 852 | out_free_secdata: |
| 846 | free_secdata(secdata); | 853 | free_secdata(secdata); |
| 847 | out_mnt: | 854 | out_mnt: |
| 848 | free_vfsmnt(mnt); | 855 | free_vfsmnt(mnt); |
| 849 | out: | 856 | out: |
| 850 | return (struct vfsmount *)sb; | 857 | return ERR_PTR(error); |
| 851 | } | 858 | } |
| 852 | 859 | ||
| 853 | EXPORT_SYMBOL_GPL(vfs_kern_mount); | 860 | EXPORT_SYMBOL_GPL(vfs_kern_mount); |
| @@ -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 | ||
| 69 | static struct super_block *sysfs_get_sb(struct file_system_type *fs_type, | 69 | static 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 | ||
| 75 | static struct file_system_type sysfs_fs_type = { | 75 | static 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) | |||
| 53 | static struct page * dir_get_page(struct inode *dir, unsigned long n) | 53 | static 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 | ||
| 88 | static int sysv_statfs(struct super_block *sb, struct kstatfs *buf) | 88 | static 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 | ||
| 509 | static struct super_block *sysv_get_sb(struct file_system_type *fs_type, | 509 | static 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 | ||
| 515 | static struct super_block *v7_get_sb(struct file_system_type *fs_type, | 516 | static 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 | ||
| 521 | static struct file_system_type sysv_fs_type = { | 522 | static 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 *); | |||
| 91 | static void udf_open_lvid(struct super_block *); | 91 | static void udf_open_lvid(struct super_block *); |
| 92 | static void udf_close_lvid(struct super_block *); | 92 | static void udf_close_lvid(struct super_block *); |
| 93 | static unsigned int udf_count_free(struct super_block *); | 93 | static unsigned int udf_count_free(struct super_block *); |
| 94 | static int udf_statfs(struct super_block *, struct kstatfs *); | 94 | static int udf_statfs(struct dentry *, struct kstatfs *); |
| 95 | 95 | ||
| 96 | /* UDF filesystem type */ | 96 | /* UDF filesystem type */ |
| 97 | static struct super_block *udf_get_sb(struct file_system_type *fs_type, | 97 | static 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 | ||
| 103 | static struct file_system_type udf_fstype = { | 103 | static 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 | */ |
| 1781 | static int | 1781 | static int |
| 1782 | udf_statfs(struct super_block *sb, struct kstatfs *buf) | 1782 | udf_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 | ||
| 1116 | static int ufs_statfs (struct super_block *sb, struct kstatfs *buf) | 1116 | static 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 | ||
| 1314 | static struct super_block *ufs_get_sb(struct file_system_type *fs_type, | 1315 | static 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 | ||
| 1320 | static struct file_system_type ufs_fs_type = { | 1321 | static 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 | ||
| 1026 | static struct super_block *vfat_get_sb(struct file_system_type *fs_type, | 1026 | static 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 | ||
| 1033 | static struct file_system_type vfat_fs_type = { | 1034 | static 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 @@ | |||
| 1 | config XFS_FS | 1 | config 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 | ||
| 21 | config XFS_EXPORT | ||
| 22 | bool | ||
| 23 | depends on XFS_FS && EXPORTFS | ||
| 24 | default y | ||
| 25 | |||
| 26 | config XFS_QUOTA | 20 | config 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 | ||
| 67 | config XFS_RT | 61 | config 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 | |||
| 59 | xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o | 59 | xfs-$(CONFIG_PROC_FS) += $(XFS_LINUX)/xfs_stats.o |
| 60 | xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o | 60 | xfs-$(CONFIG_SYSCTL) += $(XFS_LINUX)/xfs_sysctl.o |
| 61 | xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o | 61 | xfs-$(CONFIG_COMPAT) += $(XFS_LINUX)/xfs_ioctl32.o |
| 62 | xfs-$(CONFIG_XFS_EXPORT) += $(XFS_LINUX)/xfs_export.o | ||
| 63 | 62 | ||
| 64 | 63 | ||
| 65 | xfs-y += xfs_alloc.o \ | 64 | xfs-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 | |
| 39 | static 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 | 49 | static 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 | ||
| 1157 | STATIC int | ||
| 1158 | xfs_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 *); | |||
| 30 | typedef struct xfs_ioend { | 30 | typedef 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 { | |||
| 43 | extern struct address_space_operations xfs_address_space_operations; | 43 | extern struct address_space_operations xfs_address_space_operations; |
| 44 | extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); | 44 | extern 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 | ||
| 72 | STATIC ssize_t | 67 | STATIC 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 | ||
| 114 | STATIC ssize_t | 106 | STATIC 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 | ||
| 237 | STATIC ssize_t | 228 | STATIC 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 | ||
| 252 | STATIC ssize_t | 240 | STATIC 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 | ||
| 267 | STATIC ssize_t | 252 | STATIC 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 | ||
| 282 | STATIC ssize_t | 265 | STATIC 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 | ||
| 297 | STATIC ssize_t | 277 | STATIC 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 | ||
| 312 | STATIC int | 290 | STATIC 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 | |||
| 300 | STATIC int | ||
| 301 | xfs_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 | ||
| 326 | STATIC int | 308 | STATIC 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 | ||
| 339 | STATIC int | 320 | STATIC 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 | |||
| 480 | STATIC long | 445 | STATIC long |
| 481 | xfs_file_ioctl( | 446 | xfs_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 | |||
| 503 | xfs_file_ioctl_invis( | 468 | xfs_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 | |||
| 554 | xfs_file_open_exec( | 519 | xfs_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 | } |
| 573 | open_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 | /* | 20 | int fs_noerr(void) { return 0; } |
| 22 | * Stub for no-op vnode operations that return error status. | 21 | int fs_nosys(void) { return ENOSYS; } |
| 23 | */ | 22 | void fs_noval(void) { return; } |
| 24 | int | ||
| 25 | fs_noerr(void) | ||
| 26 | { | ||
| 27 | return 0; | ||
| 28 | } | ||
| 29 | 23 | ||
| 30 | /* | ||
| 31 | * Operation unsupported under this file system. | ||
| 32 | */ | ||
| 33 | int | ||
| 34 | fs_nosys(void) | ||
| 35 | { | ||
| 36 | return ENOSYS; | ||
| 37 | } | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Stub for inactive, strategy, and read/write lock/unlock. Does nothing. | ||
| 41 | */ | ||
| 42 | /* ARGSUSED */ | ||
| 43 | void | ||
| 44 | fs_noval(void) | ||
| 45 | { | ||
| 46 | } | ||
| 47 | |||
| 48 | /* | ||
| 49 | * vnode pcache layer for vnode_tosspages. | ||
| 50 | * 'last' parameter unused but left in for IRIX compatibility | ||
| 51 | */ | ||
| 52 | void | 24 | void |
| 53 | fs_tosspages( | 25 | fs_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 | */ | ||
| 71 | void | 38 | void |
| 72 | fs_flushinval_pages( | 39 | fs_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 | */ | ||
| 92 | int | 56 | int |
| 93 | fs_flush_pages( | 57 | fs_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 | ||
| 491 | STATIC int | 491 | STATIC int |
| 492 | xfs_attrmulti_attr_get( | 492 | xfs_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 | ||
| 520 | STATIC int | 520 | STATIC int |
| 521 | xfs_attrmulti_attr_set( | 521 | xfs_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 | ||
| 552 | STATIC int | 552 | STATIC int |
| 553 | xfs_attrmulti_attr_remove( | 553 | xfs_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 | ||
| 570 | STATIC int | 565 | STATIC 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( | |||
| 658 | STATIC int | 653 | STATIC int |
| 659 | xfs_ioc_space( | 654 | xfs_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 | ||
| 683 | STATIC int | 678 | STATIC int |
| 684 | xfs_ioc_xattr( | 679 | xfs_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( | |||
| 962 | STATIC int | 957 | STATIC int |
| 963 | xfs_ioc_space( | 958 | xfs_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 | ||
| 1154 | STATIC int | 1149 | STATIC int |
| 1155 | xfs_ioc_xattr( | 1150 | xfs_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 | */ |
| 62 | xfs_inode_t * | 60 | xfs_inode_t * |
| 63 | xfs_vtoi( | 61 | xfs_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 | |||
| 80 | xfs_synchronize_atime( | 78 | xfs_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( | |||
| 200 | STATIC void | 198 | STATIC void |
| 201 | xfs_validate_fields( | 199 | xfs_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 | */ |
| 226 | STATIC int | 220 | STATIC int |
| 227 | xfs_init_security( | 221 | xfs_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 | ||
| 265 | STATIC inline void | 259 | STATIC inline void |
| 266 | xfs_cleanup_inode( | 260 | xfs_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 | ||
| 649 | STATIC int | 636 | STATIC 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 | ||
| 500 | int /* error (positive) */ | 498 | int /* error (positive) */ |
| 501 | xfs_zero_eof( | 499 | xfs_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 | ||
| 21 | struct vnode; | ||
| 22 | struct bhv_desc; | 21 | struct bhv_desc; |
| 22 | struct bhv_vnode; | ||
| 23 | struct xfs_mount; | 23 | struct xfs_mount; |
| 24 | struct xfs_iocore; | 24 | struct xfs_iocore; |
| 25 | struct xfs_inode; | 25 | struct 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 *); | |||
| 82 | extern int xfs_bdstrat_cb(struct xfs_buf *); | 82 | extern int xfs_bdstrat_cb(struct xfs_buf *); |
| 83 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); | 83 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); |
| 84 | 84 | ||
| 85 | extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, | 85 | extern 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); |
| 87 | extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *, | 87 | extern 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( | |||
| 151 | STATIC __inline__ void | 149 | STATIC __inline__ void |
| 152 | xfs_revalidate_inode( | 150 | xfs_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( | |||
| 206 | void | 204 | void |
| 207 | xfs_initialize_vnode( | 205 | xfs_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 * | |||
| 336 | xfs_fs_alloc_inode( | 334 | xfs_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 | ||
| 365 | STATIC int | 363 | STATIC int |
| 366 | xfs_init_zones(void) | 364 | xfs_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 | |||
| 432 | xfs_fs_clear_inode( | 425 | xfs_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 | */ |
| 476 | STATIC void | 466 | STATIC void |
| 477 | xfs_syncd_queue_work( | 467 | xfs_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 | */ |
| 501 | STATIC void | 491 | STATIC void |
| 502 | xfs_flush_inode_work( | 492 | xfs_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 | */ |
| 526 | STATIC void | 516 | STATIC void |
| 527 | xfs_flush_device_work( | 517 | xfs_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) | ||
| 549 | STATIC void | 538 | STATIC void |
| 550 | vfs_sync_worker( | 539 | vfs_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 | ||
| 610 | STATIC int | 600 | STATIC int |
| 611 | xfs_fs_start_syncd( | 601 | xfs_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 | ||
| 622 | STATIC void | 612 | STATIC void |
| 623 | xfs_fs_stop_syncd( | 613 | xfs_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 | |||
| 630 | xfs_fs_put_super( | 620 | xfs_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 | ||
| 649 | STATIC void | 637 | STATIC void |
| 650 | xfs_fs_write_super( | 638 | xfs_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 | ||
| 704 | STATIC int | 685 | STATIC int |
| 705 | xfs_fs_statfs( | 686 | xfs_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 | ||
| 716 | STATIC int | 694 | STATIC 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 | |||
| 734 | xfs_fs_lockfs( | 712 | xfs_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 | ||
| 740 | STATIC int | 718 | STATIC 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 | ||
| 752 | STATIC int | 726 | STATIC 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 | ||
| 764 | STATIC int | 734 | STATIC 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 | ||
| 776 | STATIC int | 742 | STATIC 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 | ||
| 789 | STATIC int | 751 | STATIC 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 | ||
| 805 | STATIC int | 764 | STATIC 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 | ||
| 821 | STATIC int | 777 | STATIC 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 | ||
| 894 | fail_unmount: | 848 | fail_unmount: |
| 895 | VFS_UNMOUNT(vfsp, 0, NULL, error2); | 849 | bhv_vfs_unmount(vfsp, 0, NULL); |
| 896 | 850 | ||
| 897 | fail_vfsop: | 851 | fail_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 | ||
| 903 | STATIC struct super_block * | 857 | STATIC int |
| 904 | xfs_fs_get_sb( | 858 | xfs_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 | ||
| 913 | STATIC struct super_operations xfs_super_operations = { | 869 | STATIC 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 | ||
| 106 | extern __uint64_t xfs_max_file_offset(unsigned int); | 106 | extern __uint64_t xfs_max_file_offset(unsigned int); |
| 107 | 107 | ||
| 108 | extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int); | 108 | extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int); |
| 109 | 109 | ||
| 110 | extern void xfs_flush_inode(struct xfs_inode *); | 110 | extern void xfs_flush_inode(struct xfs_inode *); |
| 111 | extern void xfs_flush_device(struct xfs_inode *); | 111 | extern 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 | ||
| 89 | extern xfs_param_t xfs_params; | 91 | extern 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( | |||
| 104 | int | 103 | int |
| 105 | vfs_root( | 104 | vfs_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( | |||
| 117 | int | 116 | int |
| 118 | vfs_statvfs( | 117 | vfs_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 | ||
| 131 | int | 130 | int |
| @@ -145,7 +144,7 @@ vfs_sync( | |||
| 145 | int | 144 | int |
| 146 | vfs_vget( | 145 | vfs_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( | |||
| 187 | void | 186 | void |
| 188 | vfs_init_vnode( | 187 | vfs_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 | ||
| 229 | vfs_t * | 228 | bhv_vfs_t * |
| 230 | vfs_allocate( | 229 | vfs_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 | ||
| 250 | vfs_t * | 249 | bhv_vfs_t * |
| 251 | vfs_from_sb( | 250 | vfs_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 | ||
| 257 | void | 256 | void |
| 258 | vfs_deallocate( | 257 | vfs_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 | ||
| 265 | void | 264 | void |
| 266 | vfs_insertops( | 265 | vfs_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 | ||
| 277 | void | 276 | void |
| 278 | vfs_insertbhv( | 277 | vfs_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 | ||
| 288 | void | 287 | void |
| 289 | bhv_remove_vfsops( | 288 | bhv_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 | ||
| 302 | void | 301 | void |
| 303 | bhv_remove_all_vfsops( | 302 | bhv_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 | ||
| 318 | void | 317 | void |
| 319 | bhv_insert_all_vfsops( | 318 | bhv_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 | ||
| 24 | struct bhv_vfs; | ||
| 25 | struct bhv_vnode; | ||
| 26 | |||
| 24 | struct fid; | 27 | struct fid; |
| 25 | struct vfs; | ||
| 26 | struct cred; | 28 | struct cred; |
| 27 | struct vnode; | ||
| 28 | struct kstatfs; | ||
| 29 | struct seq_file; | 29 | struct seq_file; |
| 30 | struct super_block; | 30 | struct super_block; |
| 31 | struct xfs_mount_args; | 31 | struct xfs_mount_args; |
| 32 | 32 | ||
| 33 | typedef struct kstatfs xfs_statfs_t; | 33 | typedef struct kstatfs bhv_statvfs_t; |
| 34 | 34 | ||
| 35 | typedef struct vfs_sync_work { | 35 | typedef 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 | ||
| 42 | typedef struct vfs { | 42 | typedef 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 | ||
| 97 | typedef int (*vfs_mount_t)(bhv_desc_t *, | 103 | typedef 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 *); | |||
| 102 | typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); | 108 | typedef int (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *); |
| 103 | typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, | 109 | typedef int (*vfs_mntupdate_t)(bhv_desc_t *, int *, |
| 104 | struct xfs_mount_args *); | 110 | struct xfs_mount_args *); |
| 105 | typedef int (*vfs_root_t)(bhv_desc_t *, struct vnode **); | 111 | typedef int (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **); |
| 106 | typedef int (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *); | 112 | typedef int (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *, |
| 113 | struct bhv_vnode *); | ||
| 107 | typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); | 114 | typedef int (*vfs_sync_t)(bhv_desc_t *, int, struct cred *); |
| 108 | typedef int (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *); | 115 | typedef int (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *); |
| 109 | typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); | 116 | typedef int (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t); |
| 110 | typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); | 117 | typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t); |
| 111 | typedef void (*vfs_init_vnode_t)(bhv_desc_t *, | 118 | typedef void (*vfs_init_vnode_t)(bhv_desc_t *, |
| 112 | struct vnode *, bhv_desc_t *, int); | 119 | struct bhv_vnode *, bhv_desc_t *, int); |
| 113 | typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); | 120 | typedef void (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int); |
| 114 | typedef void (*vfs_freeze_t)(bhv_desc_t *); | 121 | typedef void (*vfs_freeze_t)(bhv_desc_t *); |
| 115 | 122 | ||
| 116 | typedef struct vfsops { | 123 | typedef 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 | ||
| 171 | extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); | 178 | extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *); |
| 172 | extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); | 179 | extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int); |
| 173 | extern int vfs_showargs(bhv_desc_t *, struct seq_file *); | 180 | extern int vfs_showargs(bhv_desc_t *, struct seq_file *); |
| 174 | extern int vfs_unmount(bhv_desc_t *, int, struct cred *); | 181 | extern int vfs_unmount(bhv_desc_t *, int, struct cred *); |
| 175 | extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); | 182 | extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *); |
| 176 | extern int vfs_root(bhv_desc_t *, struct vnode **); | 183 | extern int vfs_root(bhv_desc_t *, struct bhv_vnode **); |
| 177 | extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *); | 184 | extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *); |
| 178 | extern int vfs_sync(bhv_desc_t *, int, struct cred *); | 185 | extern int vfs_sync(bhv_desc_t *, int, struct cred *); |
| 179 | extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *); | 186 | extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *); |
| 180 | extern int vfs_dmapiops(bhv_desc_t *, caddr_t); | 187 | extern int vfs_dmapiops(bhv_desc_t *, caddr_t); |
| 181 | extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); | 188 | extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t); |
| 182 | extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int); | 189 | extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int); |
| 183 | extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); | 190 | extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int); |
| 184 | extern void vfs_freeze(bhv_desc_t *); | 191 | extern void vfs_freeze(bhv_desc_t *); |
| 185 | 192 | ||
| 186 | typedef 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 | |||
| 196 | typedef 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 | ||
| 196 | extern vfs_t *vfs_allocate(struct super_block *); | 206 | extern bhv_vfs_t *vfs_allocate(struct super_block *); |
| 197 | extern vfs_t *vfs_from_sb(struct super_block *); | 207 | extern bhv_vfs_t *vfs_from_sb(struct super_block *); |
| 198 | extern void vfs_deallocate(vfs_t *); | 208 | extern void vfs_deallocate(bhv_vfs_t *); |
| 199 | extern void vfs_insertops(vfs_t *, bhv_vfsops_t *); | 209 | extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *); |
| 200 | extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *); | ||
| 201 | 210 | ||
| 202 | extern void bhv_insert_all_vfsops(struct vfs *); | 211 | extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *); |
| 203 | extern void bhv_remove_all_vfsops(struct vfs *, int); | ||
| 204 | extern void bhv_remove_vfsops(struct vfs *, int); | ||
| 205 | 212 | ||
| 206 | #define fs_frozen(vfsp) ((vfsp)->vfs_super->s_frozen) | 213 | extern void bhv_insert_all_vfsops(struct bhv_vfs *); |
| 207 | #define fs_check_frozen(vfsp, level) \ | 214 | extern void bhv_remove_all_vfsops(struct bhv_vfs *, int); |
| 208 | vfs_check_frozen(vfsp->vfs_super, level); | 215 | extern 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 | ||
| 40 | void | 40 | void |
| 41 | vn_iowait( | 41 | vn_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 | ||
| 49 | void | 49 | void |
| 50 | vn_iowake( | 50 | vn_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 | ||
| 57 | struct 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 | */ | ||
| 62 | void | ||
| 63 | vn_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 | |||
| 73 | bhv_vnode_t * | ||
| 58 | vn_initialize( | 74 | vn_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 | */ |
| 95 | void | 111 | void |
| 96 | vn_revalidate_core( | 112 | vn_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 | */ |
| 131 | int | 147 | int |
| 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 | ||
| 148 | int | 164 | int |
| 149 | vn_revalidate( | 165 | vn_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 | */ |
| 160 | struct vnode * | 176 | bhv_vnode_t * |
| 161 | vn_hold( | 177 | vn_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 | */ |
| 194 | void | 210 | void |
| 195 | vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) | 211 | vn_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 | ||
| 200 | void | 216 | void |
| 201 | vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) | 217 | vn_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 | ||
| 206 | void | 222 | void |
| 207 | vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra) | 223 | vn_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 | ||
| 212 | void | 228 | void |
| 213 | vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra) | 229 | vn_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 | ||
| 218 | void | 234 | void |
| 219 | vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra) | 235 | vn_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 | ||
| 48 | struct uio; | 21 | struct uio; |
| 49 | struct file; | 22 | struct file; |
| 50 | struct vattr; | 23 | struct bhv_vfs; |
| 24 | struct bhv_vattr; | ||
| 51 | struct xfs_iomap; | 25 | struct xfs_iomap; |
| 52 | struct attrlist_cursor_kern; | 26 | struct attrlist_cursor_kern; |
| 53 | 27 | ||
| 28 | typedef struct dentry bhv_vname_t; | ||
| 29 | typedef __u64 bhv_vnumber_t; | ||
| 54 | 30 | ||
| 55 | typedef xfs_ino_t vnumber_t; | 31 | typedef enum bhv_vflags { |
| 56 | typedef struct dentry vname_t; | 32 | VMODIFIED = 0x08, /* XFS inode state possibly differs */ |
| 57 | typedef 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 | */ |
| 63 | typedef struct vnode { | 41 | typedef 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 | */ |
| 119 | static inline struct vnode *vn_from_inode(struct inode *inode) | 94 | static 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 | } |
| 123 | static inline struct inode *vn_to_inode(struct vnode *vnode) | 98 | static 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 | */ |
| 137 | typedef enum vrwlock { | 106 | typedef 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 | */ |
| 157 | typedef enum vchange { | 126 | typedef 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 | ||
| 134 | typedef enum { L_FALSE, L_TRUE } lastclose_t; | ||
| 165 | 135 | ||
| 166 | typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); | 136 | typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); |
| 137 | typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *); | ||
| 167 | typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, | 138 | typedef 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 *); |
| 182 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, | 153 | typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, |
| 183 | int, unsigned int, void __user *); | 154 | int, unsigned int, void __user *); |
| 184 | typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, | 155 | typedef int (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int, |
| 185 | struct cred *); | 156 | struct cred *); |
| 186 | typedef int (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int, | 157 | typedef int (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int, |
| 187 | struct cred *); | 158 | struct cred *); |
| 188 | typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); | 159 | typedef int (*vop_access_t)(bhv_desc_t *, int, struct cred *); |
| 189 | typedef int (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **, | 160 | typedef 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 *); |
| 191 | typedef int (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *, | 162 | typedef int (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *, |
| 192 | vnode_t **, struct cred *); | 163 | bhv_vnode_t **, struct cred *); |
| 193 | typedef int (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *); | 164 | typedef int (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *); |
| 194 | typedef int (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *, | 165 | typedef int (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *, |
| 195 | struct cred *); | ||
| 196 | typedef int (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *, | ||
| 197 | struct cred *); | 166 | struct cred *); |
| 198 | typedef int (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *, | 167 | typedef int (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *, |
| 199 | vnode_t **, struct cred *); | 168 | bhv_vname_t *, struct cred *); |
| 200 | typedef int (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *); | 169 | typedef int (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *, |
| 170 | bhv_vnode_t **, struct cred *); | ||
| 171 | typedef int (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *); | ||
| 201 | typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, | 172 | typedef int (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *, |
| 202 | int *); | 173 | int *); |
| 203 | typedef int (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *, | 174 | typedef 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 *); |
| 205 | typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, | 176 | typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, |
| 206 | struct cred *); | 177 | struct cred *); |
| 207 | typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, | 178 | typedef 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 *, | |||
| 209 | typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); | 180 | typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); |
| 210 | typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); | 181 | typedef int (*vop_fid2_t)(bhv_desc_t *, struct fid *); |
| 211 | typedef int (*vop_release_t)(bhv_desc_t *); | 182 | typedef int (*vop_release_t)(bhv_desc_t *); |
| 212 | typedef int (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t); | 183 | typedef int (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t); |
| 213 | typedef void (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t); | 184 | typedef void (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t); |
| 214 | typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, | 185 | typedef int (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int, |
| 215 | struct xfs_iomap *, int *); | 186 | struct xfs_iomap *, int *); |
| 216 | typedef int (*vop_reclaim_t)(bhv_desc_t *); | 187 | typedef 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 *); |
| 223 | typedef int (*vop_attr_list_t)(bhv_desc_t *, char *, int, int, | 194 | typedef 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 *); |
| 225 | typedef void (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int); | 196 | typedef void (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int); |
| 226 | typedef void (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t); | 197 | typedef void (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t); |
| 227 | typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | 198 | typedef void (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); |
| 228 | typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); | 199 | typedef void (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int); |
| 229 | typedef int (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, | 200 | typedef 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, | |||
| 231 | typedef int (*vop_iflush_t)(bhv_desc_t *, int); | 202 | typedef int (*vop_iflush_t)(bhv_desc_t *, int); |
| 232 | 203 | ||
| 233 | 204 | ||
| 234 | typedef struct vnodeops { | 205 | typedef 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 | */ |
| 401 | typedef struct vattr { | 349 | typedef 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 | ||
| 494 | extern void vn_init(void); | 442 | extern void vn_init(void); |
| 495 | extern vnode_t *vn_initialize(struct inode *); | 443 | extern bhv_vnode_t *vn_initialize(struct inode *); |
| 496 | 444 | extern int vn_revalidate(struct bhv_vnode *); | |
| 497 | /* | 445 | extern int __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *); |
| 498 | * vnode_map structures _must_ match vn_epoch and vnode structure sizes. | 446 | extern void vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *); |
| 499 | */ | ||
| 500 | typedef 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 | ||
| 510 | extern int vn_revalidate(struct vnode *); | 448 | extern void vn_iowait(struct bhv_vnode *vp); |
| 511 | extern int __vn_revalidate(struct vnode *, vattr_t *); | 449 | extern void vn_iowake(struct bhv_vnode *vp); |
| 512 | extern void vn_revalidate_core(struct vnode *, vattr_t *); | ||
| 513 | 450 | ||
| 514 | extern void vn_iowait(struct vnode *vp); | 451 | extern void vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l); |
| 515 | extern void vn_iowake(struct vnode *vp); | ||
| 516 | 452 | ||
| 517 | static inline int vn_count(struct vnode *vp) | 453 | static 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 | */ |
| 525 | extern vnode_t *vn_hold(struct vnode *); | 461 | extern 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 | ||
| 539 | static inline struct vnode *vn_grab(struct vnode *vp) | 475 | static 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 | ||
| 560 | static __inline__ void vn_flagset(struct vnode *vp, uint flag) | 494 | static __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 | ||
| 567 | static __inline__ void vn_flagclr(struct vnode *vp, uint flag) | 501 | static __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 | */ |
| 577 | static inline void vn_mark_bad(struct vnode *vp) | 520 | static 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 | ||
| 582 | static inline int VN_BAD(struct vnode *vp) | 525 | static 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 | */ |
| 590 | static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime) | 533 | static 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 | ||
| 596 | static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts) | 539 | static 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 | ||
| 601 | static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt) | 544 | static 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 | ||
| 646 | extern void vn_trace_entry(struct vnode *, const char *, inst_t *); | 588 | extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *); |
| 647 | extern void vn_trace_exit(struct vnode *, const char *, inst_t *); | 589 | extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *); |
| 648 | extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); | 590 | extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *); |
| 649 | extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); | 591 | extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *); |
| 650 | extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); | 592 | extern 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 | ||
| 172 | STATIC int | 168 | STATIC 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 | */ | ||
| 189 | STATIC int | ||
| 190 | xfs_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 | ||
| 188 | STATIC int | 237 | STATIC 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 | ||
| 217 | STATIC int | 265 | STATIC 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 | ||
| 349 | struct bhv_vfsops xfs_qmops = { { | 397 | struct 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))); |
| 34 | extern void assfail(char *expr, char *f, int l); | 34 | extern 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 | ||
| 42 | STATIC int xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *); | 40 | STATIC int xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *); |
| 43 | STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); | 41 | STATIC void xfs_acl_filter_mode(mode_t, xfs_acl_t *); |
| 44 | STATIC void xfs_acl_get_endian(xfs_acl_t *); | 42 | STATIC void xfs_acl_get_endian(xfs_acl_t *); |
| 45 | STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); | 43 | STATIC int xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *); |
| 46 | STATIC int xfs_acl_invalid(xfs_acl_t *); | 44 | STATIC int xfs_acl_invalid(xfs_acl_t *); |
| 47 | STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); | 45 | STATIC void xfs_acl_sync_mode(mode_t, xfs_acl_t *); |
| 48 | STATIC void xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *); | 46 | STATIC void xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *); |
| 49 | STATIC void xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *); | 47 | STATIC void xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *); |
| 50 | STATIC int xfs_acl_allow_set(vnode_t *, int); | 48 | STATIC int xfs_acl_allow_set(bhv_vnode_t *, int); |
| 51 | 49 | ||
| 52 | kmem_zone_t *xfs_acl_zone; | 50 | kmem_zone_t *xfs_acl_zone; |
| 53 | 51 | ||
| @@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone; | |||
| 57 | */ | 55 | */ |
| 58 | int | 56 | int |
| 59 | xfs_acl_vhasacl_access( | 57 | xfs_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 | */ |
| 71 | int | 69 | int |
| 72 | xfs_acl_vhasacl_default( | 70 | xfs_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 | ||
| 210 | int | 208 | int |
| 211 | xfs_acl_vget( | 209 | xfs_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 | ||
| 261 | int | 259 | int |
| 262 | xfs_acl_vremove( | 260 | xfs_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 | ||
| 281 | int | 279 | int |
| 282 | xfs_acl_vset( | 280 | xfs_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 | ||
| 371 | STATIC int | 369 | STATIC int |
| 372 | xfs_acl_allow_set( | 370 | xfs_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 | */ |
| 607 | STATIC void | 605 | STATIC void |
| 608 | xfs_acl_get_attr( | 606 | xfs_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 | */ |
| 630 | STATIC void | 628 | STATIC void |
| 631 | xfs_acl_set_attr( | 629 | xfs_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 | ||
| 663 | int | 661 | int |
| 664 | xfs_acl_vtoacl( | 662 | xfs_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 | */ |
| 702 | int | 700 | int |
| 703 | xfs_acl_inherit( | 701 | xfs_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 | */ |
| 758 | STATIC int | 756 | STATIC int |
| 759 | xfs_acl_setmode( | 757 | xfs_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 | ||
| 52 | struct vattr; | 52 | struct vattr; |
| 53 | struct vnode; | 53 | struct bhv_vnode; |
| 54 | struct xfs_inode; | 54 | struct xfs_inode; |
| 55 | 55 | ||
| 56 | extern struct kmem_zone *xfs_acl_zone; | 56 | extern 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 | ||
| 61 | extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *); | 61 | extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *); |
| 62 | extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); | 62 | extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *); |
| 63 | extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *); | 63 | extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *); |
| 64 | extern int xfs_acl_vhasacl_access(struct vnode *); | 64 | extern int xfs_acl_vhasacl_access(struct bhv_vnode *); |
| 65 | extern int xfs_acl_vhasacl_default(struct vnode *); | 65 | extern int xfs_acl_vhasacl_default(struct bhv_vnode *); |
| 66 | extern int xfs_acl_vset(struct vnode *, void *, size_t, int); | 66 | extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int); |
| 67 | extern int xfs_acl_vget(struct vnode *, void *, size_t, int); | 67 | extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int); |
| 68 | extern int xfs_acl_vremove(struct vnode *vp, int); | 68 | extern 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 | ||
| 2323 | STATIC int | 2323 | STATIC int |
| 2324 | posix_acl_access_set( | 2324 | posix_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 | ||
| 2330 | STATIC int | 2330 | STATIC int |
| 2331 | posix_acl_access_remove( | 2331 | posix_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 | ||
| 2337 | STATIC int | 2337 | STATIC int |
| 2338 | posix_acl_access_get( | 2338 | posix_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 | ||
| 2344 | STATIC int | 2344 | STATIC int |
| 2345 | posix_acl_access_exists( | 2345 | posix_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 | ||
| 2351 | STATIC int | 2351 | STATIC int |
| 2352 | posix_acl_default_set( | 2352 | posix_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 | ||
| 2358 | STATIC int | 2358 | STATIC int |
| 2359 | posix_acl_default_get( | 2359 | posix_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 | ||
| 2365 | STATIC int | 2365 | STATIC int |
| 2366 | posix_acl_default_remove( | 2366 | posix_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 | ||
| 2372 | STATIC int | 2372 | STATIC int |
| 2373 | posix_acl_default_exists( | 2373 | posix_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 | ||
| 2405 | STATIC int | 2405 | STATIC int |
| 2406 | attr_generic_set( | 2406 | attr_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 | ||
| 2415 | STATIC int | 2412 | STATIC int |
| 2416 | attr_generic_get( | 2413 | attr_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 | ||
| 2427 | STATIC int | 2424 | STATIC int |
| 2428 | attr_generic_remove( | 2425 | attr_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 | ||
| 2437 | STATIC int | 2431 | STATIC int |
| @@ -2459,7 +2453,7 @@ attr_generic_listadd( | |||
| 2459 | 2453 | ||
| 2460 | STATIC int | 2454 | STATIC int |
| 2461 | attr_system_list( | 2455 | attr_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 | ||
| 2482 | int | 2476 | int |
| 2483 | attr_generic_list( | 2477 | attr_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 | */ |
| 2515 | STATIC int | 2509 | STATIC int |
| 2516 | attr_user_capable( | 2510 | attr_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 | ||
| 2533 | STATIC int | 2527 | STATIC int |
| 2534 | attr_trusted_capable( | 2528 | attr_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 | ||
| 2547 | STATIC int | 2541 | STATIC int |
| 2548 | attr_secure_capable( | 2542 | attr_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 | ||
| 2555 | STATIC int | 2549 | STATIC int |
| 2556 | attr_system_set( | 2550 | attr_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 | ||
| 2574 | STATIC int | 2568 | STATIC int |
| 2575 | attr_system_get( | 2569 | attr_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 | ||
| 2586 | STATIC int | 2580 | STATIC int |
| 2587 | attr_system_remove( | 2581 | attr_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 | ||
| 38 | struct cred; | 38 | struct cred; |
| 39 | struct vnode; | 39 | struct bhv_vnode; |
| 40 | 40 | ||
| 41 | typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int); | 41 | typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int); |
| 42 | typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int); | 42 | typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int); |
| 43 | typedef int (*attrremove_t)(struct vnode *, char *, int); | 43 | typedef int (*attrremove_t)(struct bhv_vnode *, char *, int); |
| 44 | typedef int (*attrexists_t)(struct vnode *); | 44 | typedef int (*attrexists_t)(struct bhv_vnode *); |
| 45 | typedef int (*attrcapable_t)(struct vnode *, struct cred *); | 45 | typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *); |
| 46 | 46 | ||
| 47 | typedef struct attrnames { | 47 | typedef struct attrnames { |
| 48 | char * attr_name; | 48 | char * attr_name; |
| @@ -63,7 +63,7 @@ extern struct attrnames attr_trusted; | |||
| 63 | extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; | 63 | extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; |
| 64 | 64 | ||
| 65 | extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); | 65 | extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); |
| 66 | extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); | 66 | extern 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 | } | ||
| 1212 | done: | 1269 | done: |
| 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 | } | ||
| 1728 | done: | 1828 | done: |
| 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 | } |
| 2285 | done: | ||
| 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 | } | ||
| 3196 | done: | 3370 | done: |
| 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 | } | ||
| 5077 | error0: | 5265 | error0: |
| 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 | } | ||
| 5516 | error0: | 5719 | error0: |
| 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; | |||
| 26 | struct xfs_trans; | 26 | struct 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 | */ | ||
| 36 | typedef 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 | ||
| 52 | struct vnode; | 52 | struct bhv_vnode; |
| 53 | 53 | ||
| 54 | extern int xfs_cap_vhascap(struct vnode *); | 54 | extern int xfs_cap_vhascap(struct bhv_vnode *); |
| 55 | extern int xfs_cap_vset(struct vnode *, void *, size_t); | 55 | extern int xfs_cap_vset(struct bhv_vnode *, void *, size_t); |
| 56 | extern int xfs_cap_vget(struct vnode *, void *, size_t); | 56 | extern int xfs_cap_vget(struct bhv_vnode *, void *, size_t); |
| 57 | extern int xfs_cap_vremove(struct vnode *vp); | 57 | extern 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; | ||
| 1991 | done: | ||
| 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 | |||
| 47 | typedef struct xfs_da_blkinfo { | 43 | typedef 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 | |||
| 128 | int | ||
| 129 | xfs_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 | */ |
| 49 | int xfs_swapext(struct xfs_swapext __user *sx); | 49 | int xfs_swapext(struct xfs_swapext __user *sx); |
| 50 | 50 | ||
| 51 | int 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 | */ | ||
| 57 | static void xfs_dir_mount(struct xfs_mount *mp); | ||
| 58 | |||
| 59 | static int xfs_dir_isempty(struct xfs_inode *dp); | ||
| 60 | |||
| 61 | static int xfs_dir_init(struct xfs_trans *trans, | ||
| 62 | struct xfs_inode *dir, | ||
| 63 | struct xfs_inode *parent_dir); | ||
| 64 | |||
| 65 | static 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 | |||
| 74 | static 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 | |||
| 80 | static 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 | |||
| 89 | static int xfs_dir_getdents(struct xfs_trans *tp, | ||
| 90 | struct xfs_inode *dp, | ||
| 91 | struct uio *uiop, | ||
| 92 | int *eofp); | ||
| 93 | |||
| 94 | static 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 | |||
| 103 | static int xfs_dir_canenter(struct xfs_trans *tp, | ||
| 104 | struct xfs_inode *dp, | ||
| 105 | char *name_string, | ||
| 106 | int name_length); | ||
| 107 | |||
| 108 | static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, | ||
| 109 | xfs_dinode_t *dip); | ||
| 110 | |||
| 111 | xfs_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 | */ | ||
| 128 | STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args); | ||
| 129 | STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries, | ||
| 130 | int *total_namebytes); | ||
| 131 | STATIC 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); | ||
| 135 | STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args); | ||
| 136 | |||
| 137 | /* | ||
| 138 | * Internal routines when dirsize > XFS_LBSIZE(mp). | ||
| 139 | */ | ||
| 140 | STATIC int xfs_dir_node_addname(xfs_da_args_t *args); | ||
| 141 | STATIC int xfs_dir_node_lookup(xfs_da_args_t *args); | ||
| 142 | STATIC int xfs_dir_node_removename(xfs_da_args_t *args); | ||
| 143 | STATIC 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); | ||
| 147 | STATIC int xfs_dir_node_replace(xfs_da_args_t *args); | ||
| 148 | |||
| 149 | #if defined(XFS_DIR_TRACE) | ||
| 150 | ktrace_t *xfs_dir_trace_buf; | ||
| 151 | #endif | ||
| 152 | |||
| 153 | |||
| 154 | /*======================================================================== | ||
| 155 | * Overall external interface routines. | ||
| 156 | *========================================================================*/ | ||
| 157 | |||
| 158 | xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
| 159 | |||
| 160 | /* | ||
| 161 | * One-time startup routine called from xfs_init(). | ||
| 162 | */ | ||
| 163 | void | ||
| 164 | xfs_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 | */ | ||
| 173 | static void | ||
| 174 | xfs_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 | */ | ||
| 210 | static int | ||
| 211 | xfs_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 | */ | ||
| 227 | static int | ||
| 228 | xfs_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 | */ | ||
| 248 | static int /* error */ | ||
| 249 | xfs_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 | */ | ||
| 314 | static int /* error */ | ||
| 315 | xfs_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 | */ | ||
| 357 | static int /* error */ | ||
| 358 | xfs_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 | |||
| 401 | static int /* error */ | ||
| 402 | xfs_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 | */ | ||
| 446 | static int /* error */ | ||
| 447 | xfs_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 | |||
| 490 | static int /* error */ | ||
| 491 | xfs_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 | |||
| 532 | static int | ||
| 533 | xfs_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 | */ | ||
| 601 | int | ||
| 602 | xfs_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 | */ | ||
| 624 | STATIC int | ||
| 625 | xfs_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 | */ | ||
| 653 | STATIC int | ||
| 654 | xfs_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 | */ | ||
| 672 | STATIC int | ||
| 673 | xfs_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 | */ | ||
| 693 | STATIC int | ||
| 694 | xfs_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 | */ | ||
| 737 | STATIC int | ||
| 738 | xfs_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 | } | ||
| 781 | error: | ||
| 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 | */ | ||
| 794 | STATIC int | ||
| 795 | xfs_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 | */ | ||
| 844 | STATIC int | ||
| 845 | xfs_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 | |||
| 877 | STATIC int | ||
| 878 | xfs_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 | */ | ||
| 1028 | STATIC int | ||
| 1029 | xfs_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 | */ | ||
| 1088 | void | ||
| 1089 | xfs_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 | */ | ||
| 1102 | void | ||
| 1103 | xfs_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 | */ | ||
| 1117 | void | ||
| 1118 | xfs_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 | */ | ||
| 1141 | void | ||
| 1142 | xfs_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 | */ | ||
| 1165 | void | ||
| 1166 | xfs_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 | */ | ||
| 1182 | void | ||
| 1183 | xfs_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 | */ | ||
| 1199 | void | ||
| 1200 | xfs_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 | |||
| 36 | struct uio; | ||
| 37 | struct xfs_bmap_free; | ||
| 38 | struct xfs_da_args; | ||
| 39 | struct xfs_dinode; | ||
| 40 | struct xfs_inode; | ||
| 41 | struct xfs_mount; | ||
| 42 | struct xfs_trans; | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Directory function types. | ||
| 46 | * Put in structures (xfs_dirops_t) for v1 and v2 directories. | ||
| 47 | */ | ||
| 48 | typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp); | ||
| 49 | typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp); | ||
| 50 | typedef int (*xfs_dir_init_t)(struct xfs_trans *tp, | ||
| 51 | struct xfs_inode *dp, | ||
| 52 | struct xfs_inode *pdp); | ||
| 53 | typedef 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); | ||
| 61 | typedef 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); | ||
| 66 | typedef 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); | ||
| 74 | typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp, | ||
| 75 | struct xfs_inode *dp, | ||
| 76 | struct uio *uio, | ||
| 77 | int *eofp); | ||
| 78 | typedef 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); | ||
| 86 | typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp, | ||
| 87 | struct xfs_inode *dp, | ||
| 88 | char *name, | ||
| 89 | int namelen); | ||
| 90 | typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp, | ||
| 91 | struct xfs_dinode *dip); | ||
| 92 | typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args); | ||
| 93 | |||
| 94 | typedef 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 | */ | ||
| 111 | void 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) | ||
| 139 | extern xfs_dirops_t xfsv1_dirops; | ||
| 140 | extern 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 | */ | ||
| 52 | static void xfs_dir2_mount(xfs_mount_t *mp); | ||
| 53 | static int xfs_dir2_isempty(xfs_inode_t *dp); | ||
| 54 | static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp, | ||
| 55 | xfs_inode_t *pdp); | ||
| 56 | static 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); | ||
| 60 | static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
| 61 | int namelen, xfs_ino_t *inum); | ||
| 62 | static 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); | ||
| 66 | static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio, | ||
| 67 | int *eofp); | ||
| 68 | static 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); | ||
| 72 | static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
| 73 | int namelen); | ||
| 74 | static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp, | ||
| 75 | xfs_dinode_t *dip); | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Utility routine declarations. | ||
| 79 | */ | ||
| 80 | static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); | 46 | static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); |
| 81 | static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); | 47 | static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); |
| 82 | 48 | ||
| 83 | /* | 49 | void |
| 84 | * Directory operations vector. | 50 | xfs_dir_mount( |
| 85 | */ | 51 | xfs_mount_t *mp) |
| 86 | xfs_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 | */ | ||
| 107 | static void | ||
| 108 | xfs_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 | */ |
| 131 | static int /* return code */ | 73 | int |
| 132 | xfs_dir2_isempty( | 74 | xfs_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 | */ | ||
| 91 | int | ||
| 92 | xfs_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 | */ |
| 153 | static int /* error */ | 125 | int |
| 154 | xfs_dir2_init( | 126 | xfs_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 | */ |
| 175 | static int /* error */ | 146 | int |
| 176 | xfs_dir2_createname( | 147 | xfs_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 | */ |
| 231 | static int /* error */ | 197 | int |
| 232 | xfs_dir2_lookup( | 198 | xfs_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 | */ |
| 286 | static int /* error */ | 247 | int |
| 287 | xfs_dir2_removename( | 248 | xfs_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 | */ |
| 338 | static int /* error */ | 295 | int |
| 339 | xfs_dir2_getdents( | 296 | xfs_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 | */ |
| 389 | static int /* error */ | 343 | int |
| 390 | xfs_dir2_replace( | 344 | xfs_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 | */ |
| 444 | static int /* error */ | 393 | int |
| 445 | xfs_dir2_canenter( | 394 | xfs_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 */ | ||
| 493 | static int /* error */ | ||
| 494 | xfs_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 | */ |
| 510 | int /* error */ | 442 | int |
| 511 | xfs_dir2_grow_inode( | 443 | xfs_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 = ↦ | 487 | mapp = ↦ |
| 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 | */ |
| 648 | int /* error */ | 576 | int |
| 649 | xfs_dir2_isblock( | 577 | xfs_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 | */ |
| 671 | int /* error */ | 598 | int |
| 672 | xfs_dir2_isleaf( | 599 | xfs_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 | */ |
| 692 | static int /* error */ | 618 | static int |
| 693 | xfs_dir2_put_dirent64_direct( | 619 | xfs_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 | */ |
| 729 | static int /* error */ | 655 | static int |
| 730 | xfs_dir2_put_dirent64_uio( | 656 | xfs_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 | */ |
| 765 | int | 691 | int |
| 766 | xfs_dir2_shrink_inode( | 692 | xfs_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; | |||
| 22 | struct xfs_dabuf; | 22 | struct xfs_dabuf; |
| 23 | struct xfs_da_args; | 23 | struct xfs_da_args; |
| 24 | struct xfs_dir2_put_args; | 24 | struct xfs_dir2_put_args; |
| 25 | struct xfs_bmap_free; | ||
| 25 | struct xfs_inode; | 26 | struct xfs_inode; |
| 27 | struct xfs_mount; | ||
| 26 | struct xfs_trans; | 28 | struct 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 | */ | ||
| 80 | extern void xfs_dir_startup(void); | ||
| 81 | extern void xfs_dir_mount(struct xfs_mount *mp); | ||
| 82 | extern int xfs_dir_isempty(struct xfs_inode *dp); | ||
| 83 | extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 84 | struct xfs_inode *pdp); | ||
| 85 | extern 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); | ||
| 89 | extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 90 | char *name, int namelen, xfs_ino_t *inum); | ||
| 91 | extern 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); | ||
| 95 | extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 96 | uio_t *uio, int *eofp); | ||
| 97 | extern 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); | ||
| 101 | extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 102 | char *name, int namelen); | ||
| 103 | extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); | ||
| 104 | |||
| 105 | /* | ||
| 106 | * Utility routines for v2 directories. | ||
| 77 | */ | 107 | */ |
| 78 | extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, | 108 | extern 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); |
| 52 | static int xfs_dir2_block_sort(const void *a, const void *b); | 49 | static int xfs_dir2_block_sort(const void *a, const void *b); |
| 53 | 50 | ||
| 51 | static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
| 52 | |||
| 53 | /* | ||
| 54 | * One-time startup routine called from xfs_init(). | ||
| 55 | */ | ||
| 56 | void | ||
| 57 | xfs_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 | */ |
| 87 | typedef struct xfs_dir2_data_entry { | 87 | typedef 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 | */ | ||
| 58 | STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, | ||
| 59 | int insertion_index, | ||
| 60 | int freemap_index); | ||
| 61 | STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer, | ||
| 62 | int musthave, int justcheck); | ||
| 63 | STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state, | ||
| 64 | xfs_da_state_blk_t *blk1, | ||
| 65 | xfs_da_state_blk_t *blk2); | ||
| 66 | STATIC 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 | |||
| 72 | STATIC 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 | */ | ||
| 79 | STATIC 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 | */ | ||
| 94 | int | ||
| 95 | xfs_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 | */ | ||
| 126 | int | ||
| 127 | xfs_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 | */ | ||
| 157 | int | ||
| 158 | xfs_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 | */ | ||
| 207 | int | ||
| 208 | xfs_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 | */ | ||
| 260 | int | ||
| 261 | xfs_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 | */ | ||
| 307 | int | ||
| 308 | xfs_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 | |||
| 391 | out: | ||
| 392 | kmem_free(tmpbuffer, size); | ||
| 393 | return retval; | ||
| 394 | } | ||
| 395 | |||
| 396 | STATIC int | ||
| 397 | xfs_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*/ | ||
| 415 | int | ||
| 416 | xfs_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 | */ | ||
| 572 | int | ||
| 573 | xfs_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 | */ | ||
| 621 | int | ||
| 622 | xfs_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 | |||
| 695 | out: | ||
| 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 | */ | ||
| 703 | int | ||
| 704 | xfs_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 | */ | ||
| 767 | STATIC int | ||
| 768 | xfs_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 | */ | ||
| 801 | int | ||
| 802 | xfs_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 | */ | ||
| 855 | int | ||
| 856 | xfs_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 | */ | ||
| 930 | STATIC void | ||
| 931 | xfs_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 | */ | ||
| 1009 | STATIC int | ||
| 1010 | xfs_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 | */ | ||
| 1085 | STATIC void | ||
| 1086 | xfs_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 | */ | ||
| 1215 | STATIC int | ||
| 1216 | xfs_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 | */ | ||
| 1312 | int | ||
| 1313 | xfs_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 | */ | ||
| 1438 | int | ||
| 1439 | xfs_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 | */ | ||
| 1586 | void | ||
| 1587 | xfs_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 | */ | ||
| 1689 | int | ||
| 1690 | xfs_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 */ | ||
| 1768 | STATIC void | ||
| 1769 | xfs_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 | */ | ||
| 1880 | int | ||
| 1881 | xfs_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 | */ | ||
| 1902 | xfs_dahash_t | ||
| 1903 | xfs_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 | */ | ||
| 1919 | int | ||
| 1920 | xfs_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 | */ | ||
| 2158 | int | ||
| 2159 | xfs_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 | */ | ||
| 2190 | int | ||
| 2191 | xfs_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 | |||
| 31 | struct uio; | ||
| 32 | struct xfs_bmap_free; | ||
| 33 | struct xfs_dabuf; | ||
| 34 | struct xfs_da_args; | ||
| 35 | struct xfs_da_state; | ||
| 36 | struct xfs_da_state_blk; | ||
| 37 | struct xfs_dir_put_args; | ||
| 38 | struct xfs_inode; | ||
| 39 | struct xfs_mount; | ||
| 40 | struct 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 | |||
| 70 | typedef 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 | |||
| 75 | typedef 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 | |||
| 85 | typedef 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 | |||
| 92 | typedef 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 | |||
| 97 | typedef 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 | |||
| 112 | typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa); | ||
| 113 | |||
| 114 | typedef 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 | |||
| 133 | typedef 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) | ||
| 146 | static 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) | ||
| 153 | static 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) | ||
| 160 | static inline xfs_dir_leaf_name_t * | ||
| 161 | xfs_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 | */ | ||
| 173 | int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent); | ||
| 174 | int xfs_dir_shortform_addname(struct xfs_da_args *args); | ||
| 175 | int xfs_dir_shortform_lookup(struct xfs_da_args *args); | ||
| 176 | int xfs_dir_shortform_to_leaf(struct xfs_da_args *args); | ||
| 177 | int xfs_dir_shortform_removename(struct xfs_da_args *args); | ||
| 178 | int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp, | ||
| 179 | struct xfs_dirent *dbp, xfs_dir_put_t put); | ||
| 180 | int xfs_dir_shortform_replace(struct xfs_da_args *args); | ||
| 181 | |||
| 182 | /* | ||
| 183 | * Internal routines when dirsize == XFS_LBSIZE(mp). | ||
| 184 | */ | ||
| 185 | int xfs_dir_leaf_to_node(struct xfs_da_args *args); | ||
| 186 | int xfs_dir_leaf_to_shortform(struct xfs_da_args *args); | ||
| 187 | |||
| 188 | /* | ||
| 189 | * Routines used for growing the Btree. | ||
| 190 | */ | ||
| 191 | int xfs_dir_leaf_split(struct xfs_da_state *state, | ||
| 192 | struct xfs_da_state_blk *oldblk, | ||
| 193 | struct xfs_da_state_blk *newblk); | ||
| 194 | int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer, | ||
| 195 | struct xfs_da_args *args, int insertion_index); | ||
| 196 | int xfs_dir_leaf_addname(struct xfs_da_args *args); | ||
| 197 | int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer, | ||
| 198 | struct xfs_da_args *args, | ||
| 199 | int *index_found_at); | ||
| 200 | int xfs_dir_leaf_remove(struct xfs_trans *trans, | ||
| 201 | struct xfs_dabuf *leaf_buffer, | ||
| 202 | int index_to_remove); | ||
| 203 | int 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 | */ | ||
| 211 | int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval); | ||
| 212 | void 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 | */ | ||
| 219 | uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count); | ||
| 220 | int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp, | ||
| 221 | struct xfs_dabuf *leaf2_bp); | ||
| 222 | int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa); | ||
| 223 | int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa); | ||
| 224 | int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); | ||
| 225 | |||
| 226 | /* | ||
| 227 | * Global data. | ||
| 228 | */ | ||
| 229 | extern 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 | |||
| 28 | typedef 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 | */ | ||
| 38 | typedef 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 | |||
| 43 | typedef 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 | |||
| 49 | typedef 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 | */ | ||
| 58 | typedef 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) | ||
| 68 | static 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) | ||
| 74 | static 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) | ||
| 80 | static 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) | ||
| 86 | static 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) | ||
| 92 | static 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) | ||
| 100 | static 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 | */ | ||
| 111 | struct uio; | ||
| 112 | struct xfs_inode; | ||
| 113 | struct xfs_da_intnode; | ||
| 114 | struct xfs_dinode; | ||
| 115 | struct xfs_dir_leafblock; | ||
| 116 | struct xfs_dir_leaf_entry; | ||
| 117 | |||
| 118 | #define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */ | ||
| 119 | extern 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 | |||
| 131 | void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio); | ||
| 132 | void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 133 | xfs_dablk_t bno); | ||
| 134 | void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 135 | struct xfs_da_intnode *node); | ||
| 136 | void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 137 | struct xfs_dir_leafblock *leaf); | ||
| 138 | void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 139 | struct xfs_dir_leaf_entry *entry); | ||
| 140 | void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 141 | xfs_off_t cookie); | ||
| 142 | void 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 | ||
| 192 | extern struct bhv_vfsops xfs_dmops; | 192 | extern 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 | */ | ||
| 302 | int | ||
| 303 | xfs_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 | |||
| 36 | typedef struct xfs_extent_32 { | ||
| 37 | xfs_dfsbno_t ext_start; | ||
| 38 | xfs_extlen_t ext_len; | ||
| 39 | } __attribute__((packed)) xfs_extent_32_t; | ||
| 40 | |||
| 41 | typedef 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 | ||
| 60 | typedef 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 | |||
| 68 | typedef 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 | ||
| 89 | typedef 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 | |||
| 97 | typedef 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; | |||
| 103 | xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); | 153 | xfs_efi_log_item_t *xfs_efi_init(struct xfs_mount *, uint); |
| 104 | xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, | 154 | xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *, |
| 105 | uint); | 155 | uint); |
| 106 | 156 | int xfs_efi_copy_format(xfs_log_iovec_t *buf, | |
| 157 | xfs_efi_log_format_t *dst_efi_fmt); | ||
| 107 | void xfs_efi_item_free(xfs_efi_log_item_t *); | 158 | void 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 |
| 80 | struct getbmap { | 81 | struct 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 | ||
| 544 | void | 542 | void |
| 545 | xfs_fs_log_dummy(xfs_mount_t *mp) | 543 | xfs_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 | */ |
| 187 | STATIC int | 185 | STATIC int |
| 188 | xfs_iget_core( | 186 | xfs_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: | |||
| 543 | void | 541 | void |
| 544 | xfs_inode_lock_init( | 542 | xfs_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 | |||
| 603 | xfs_iput(xfs_inode_t *ip, | 601 | xfs_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 | |||
| 619 | xfs_iput_new(xfs_inode_t *ip, | 615 | xfs_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, | |||
| 645 | void | 641 | void |
| 646 | xfs_ireclaim(xfs_inode_t *ip) | 642 | xfs_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) | |||
| 1033 | void | 1029 | void |
| 1034 | xfs_ifunlock(xfs_inode_t *ip) | 1030 | xfs_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 | ||
| 783 | STATIC uint | 784 | STATIC 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 | ||
| 830 | uint | 832 | uint |
| 831 | xfs_dic2xflags( | 833 | xfs_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 | ||
| 3200 | corrupt_out: | 3200 | corrupt_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__ |
| 104 | struct bhv_desc; | 104 | struct bhv_desc; |
| 105 | struct bhv_vnode; | ||
| 105 | struct cred; | 106 | struct cred; |
| 106 | struct ktrace; | 107 | struct ktrace; |
| 107 | struct vnode; | ||
| 108 | struct xfs_buf; | 108 | struct xfs_buf; |
| 109 | struct xfs_bmap_free; | 109 | struct xfs_bmap_free; |
| 110 | struct xfs_bmbt_irec; | 110 | struct xfs_bmbt_irec; |
| @@ -400,7 +400,7 @@ void xfs_chash_init(struct xfs_mount *); | |||
| 400 | void xfs_chash_free(struct xfs_mount *); | 400 | void xfs_chash_free(struct xfs_mount *); |
| 401 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, | 401 | xfs_inode_t *xfs_inode_incore(struct xfs_mount *, xfs_ino_t, |
| 402 | struct xfs_trans *); | 402 | struct xfs_trans *); |
| 403 | void xfs_inode_lock_init(xfs_inode_t *, struct vnode *); | 403 | void xfs_inode_lock_init(xfs_inode_t *, struct bhv_vnode *); |
| 404 | int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 404 | int 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); |
| 406 | void xfs_iput(xfs_inode_t *, uint); | 406 | void xfs_iput(xfs_inode_t *, uint); |
| @@ -461,7 +461,7 @@ void xfs_ichgtime(xfs_inode_t *, int); | |||
| 461 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); | 461 | xfs_fsize_t xfs_file_last_byte(xfs_inode_t *); |
| 462 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); | 462 | void xfs_lock_inodes(xfs_inode_t **, int, int, uint); |
| 463 | 463 | ||
| 464 | xfs_inode_t *xfs_vtoi(struct vnode *vp); | 464 | xfs_inode_t *xfs_vtoi(struct bhv_vnode *vp); |
| 465 | 465 | ||
| 466 | void xfs_synchronize_atime(xfs_inode_t *); | 466 | void xfs_synchronize_atime(xfs_inode_t *); |
| 467 | 467 | ||
| @@ -509,7 +509,6 @@ extern struct kmem_zone *xfs_chashlist_zone; | |||
| 509 | extern struct kmem_zone *xfs_ifork_zone; | 509 | extern struct kmem_zone *xfs_ifork_zone; |
| 510 | extern struct kmem_zone *xfs_inode_zone; | 510 | extern struct kmem_zone *xfs_inode_zone; |
| 511 | extern struct kmem_zone *xfs_ili_zone; | 511 | extern struct kmem_zone *xfs_ili_zone; |
| 512 | extern 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 | */ | ||
| 1090 | int | ||
| 1091 | xfs_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 | */ |
| 46 | typedef struct xfs_inode_log_format { | 27 | typedef 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 */ | 43 | typedef struct xfs_inode_log_format_32 { |
| 63 | typedef 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 | |||
| 59 | typedef 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 *); | |||
| 172 | extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); | 173 | extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *); |
| 173 | extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *); | 174 | extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *); |
| 174 | extern void xfs_iflush_abort(struct xfs_inode *); | 175 | extern void xfs_iflush_abort(struct xfs_inode *); |
| 176 | extern 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 | ||
| 59 | STATIC int | 58 | STATIC int |
| 60 | xfs_ioinit( | 59 | xfs_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( | |||
| 68 | xfs_ioops_t xfs_iocore_xfs = { | 67 | xfs_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 | ||
| 89 | void | 90 | void |
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 | |||
| 49 | STATIC int | 42 | STATIC int |
| 50 | xfs_bulkstat_one_iget( | 43 | xfs_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); | 2559 | error: |
| 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 | */ |
| 2677 | STATIC void | 2699 | STATIC int |
| 2678 | xlog_recover_do_efi_trans( | 2700 | xlog_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 | ||
| 338 | xfs_agnumber_t | 336 | xfs_agnumber_t |
| 339 | xfs_initialize_perag( | 337 | xfs_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 | */ |
| 652 | int | 650 | int |
| 653 | xfs_mountfs( | 651 | xfs_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( | |||
| 1094 | int | 1082 | int |
| 1095 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | 1083 | xfs_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 |
| 54 | struct cred; | 54 | struct cred; |
| 55 | struct log; | 55 | struct log; |
| 56 | struct vfs; | 56 | struct bhv_vfs; |
| 57 | struct vnode; | 57 | struct bhv_vnode; |
| 58 | struct xfs_mount_args; | 58 | struct xfs_mount_args; |
| 59 | struct xfs_ihash; | 59 | struct xfs_ihash; |
| 60 | struct xfs_chash; | 60 | struct xfs_chash; |
| @@ -63,9 +63,11 @@ struct xfs_perag; | |||
| 63 | struct xfs_iocore; | 63 | struct xfs_iocore; |
| 64 | struct xfs_bmbt_irec; | 64 | struct xfs_bmbt_irec; |
| 65 | struct xfs_bmap_free; | 65 | struct xfs_bmap_free; |
| 66 | struct xfs_extdelta; | ||
| 67 | struct xfs_swapext; | ||
| 66 | 68 | ||
| 67 | extern struct vfsops xfs_vfsops; | 69 | extern struct bhv_vfsops xfs_vfsops; |
| 68 | extern struct vnodeops xfs_vnodeops; | 70 | extern 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 | ||
| 81 | typedef int (*xfs_send_data_t)(int, struct vnode *, | 83 | typedef 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 *); |
| 83 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); | 85 | typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint); |
| 84 | typedef int (*xfs_send_destroy_t)(struct vnode *, dm_right_t); | 86 | typedef int (*xfs_send_destroy_t)(struct bhv_vnode *, dm_right_t); |
| 85 | typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct vfs *, | 87 | typedef 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); |
| 89 | typedef void (*xfs_send_unmount_t)(struct vfs *, struct vnode *, | 91 | typedef 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 | ||
| 92 | typedef struct xfs_dmops { | 94 | typedef 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 | ||
| 191 | typedef int (*xfs_ioinit_t)(struct vfs *, | 193 | typedef int (*xfs_ioinit_t)(struct bhv_vfs *, |
| 192 | struct xfs_mount_args *, int); | 194 | struct xfs_mount_args *, int); |
| 193 | typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, | 195 | typedef 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 *); |
| 200 | typedef 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 *); | ||
| 198 | typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); | 205 | typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); |
| 199 | typedef int (*xfs_iomap_write_direct_t)( | 206 | typedef 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); | |||
| 213 | typedef int (*xfs_lock_nowait_t)(void *, uint); | 220 | typedef int (*xfs_lock_nowait_t)(void *, uint); |
| 214 | typedef void (*xfs_unlk_t)(void *, unsigned int); | 221 | typedef void (*xfs_unlk_t)(void *, unsigned int); |
| 215 | typedef xfs_fsize_t (*xfs_size_t)(void *); | 222 | typedef xfs_fsize_t (*xfs_size_t)(void *); |
| 216 | typedef xfs_fsize_t (*xfs_iodone_t)(struct vfs *); | 223 | typedef xfs_fsize_t (*xfs_iodone_t)(struct bhv_vfs *); |
| 224 | typedef int (*xfs_swap_extents_t)(void *, void *, | ||
| 225 | struct xfs_swapext*); | ||
| 217 | 226 | ||
| 218 | typedef struct xfs_ioops { | 227 | typedef 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) |
| 524 | static inline struct vfs *xfs_mtovfs(xfs_mount_t *mp) | 530 | static 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) |
| 536 | static inline xfs_mount_t *xfs_vfstom(vfs_t *vfs) | 542 | static 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 { | |||
| 571 | extern xfs_mount_t *xfs_mount_init(void); | 577 | extern xfs_mount_t *xfs_mount_init(void); |
| 572 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); | 578 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); |
| 573 | extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); | 579 | extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); |
| 574 | extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); | 580 | extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int); |
| 575 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 581 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); |
| 576 | 582 | ||
| 577 | extern int xfs_unmountfs(xfs_mount_t *, struct cred *); | 583 | extern int xfs_unmountfs(xfs_mount_t *, struct cred *); |
| @@ -589,7 +595,7 @@ extern void xfs_freesb(xfs_mount_t *); | |||
| 589 | extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); | 595 | extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); |
| 590 | extern int xfs_syncsub(xfs_mount_t *, int, int, int *); | 596 | extern int xfs_syncsub(xfs_mount_t *, int, int, int *); |
| 591 | extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); | 597 | extern int xfs_sync_inodes(xfs_mount_t *, int, int, int *); |
| 592 | extern xfs_agnumber_t xfs_initialize_perag(struct vfs *, xfs_mount_t *, | 598 | extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, |
| 593 | xfs_agnumber_t); | 599 | xfs_agnumber_t); |
| 594 | extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); | 600 | extern 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 { | |||
| 365 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); | 365 | extern int xfs_qm_dqcheck(xfs_disk_dquot_t *, xfs_dqid_t, uint, uint, char *); |
| 366 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); | 366 | extern int xfs_mount_reset_sbqflags(struct xfs_mount *); |
| 367 | 367 | ||
| 368 | extern struct bhv_vfsops xfs_qmops; | 368 | extern 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 | |||
| 87 | xfs_lock_for_rename( | 84 | xfs_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( | |||
| 225 | int | 222 | int |
| 226 | xfs_rename( | 223 | xfs_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 | */ | ||
| 95 | int | ||
| 96 | xfs_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 | */ |
| 77 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); | 77 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); |
| 78 | extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip); | ||
| 78 | extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); | 79 | extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); |
| 79 | extern int xfs_bioerror(struct xfs_buf *bp); | 80 | extern int xfs_bioerror(struct xfs_buf *bp); |
| 80 | extern int xfs_bioerror_relse(struct xfs_buf *bp); | 81 | extern 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 | */ |
| 90 | extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock); | 91 | extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); |
| 91 | extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock); | 92 | extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); |
| 92 | extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp); | 93 | extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags, |
| 94 | cred_t *credp); | ||
| 93 | extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, | 95 | extern 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); |
| 95 | extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, | 97 | extern 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 | ||
| 246 | xfs_trans_t * | 241 | xfs_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 | */ |
| 52 | int | 50 | int |
| 53 | xfs_get_dir_entry( | 51 | xfs_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 | |||
| 69 | xfs_dir_lookup_int( | 67 | xfs_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 | ||
| 26 | extern int xfs_rename (bhv_desc_t *, vname_t *, vnode_t *, vname_t *, cred_t *); | 26 | extern int xfs_rename (bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *, |
| 27 | extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); | 27 | bhv_vname_t *, cred_t *); |
| 28 | extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, | 28 | extern int xfs_get_dir_entry (bhv_vname_t *, xfs_inode_t **); |
| 29 | extern int xfs_dir_lookup_int (bhv_desc_t *, uint, bhv_vname_t *, xfs_ino_t *, | ||
| 29 | xfs_inode_t **); | 30 | xfs_inode_t **); |
| 30 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); | 31 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); |
| 31 | extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, | 32 | extern 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 | */ |
| 213 | STATIC int | 205 | STATIC int |
| 214 | xfs_start_flags( | 206 | xfs_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 | */ |
| 338 | STATIC int | 330 | STATIC int |
| 339 | xfs_finish_flags( | 331 | xfs_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: | |||
| 781 | STATIC int | 772 | STATIC int |
| 782 | xfs_root( | 773 | xfs_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( | |||
| 801 | STATIC int | 792 | STATIC int |
| 802 | xfs_statvfs( | 793 | xfs_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( | |||
| 1574 | STATIC int | 1563 | STATIC int |
| 1575 | xfs_vget( | 1564 | xfs_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 | ||
| 1659 | STATIC unsigned long | 1648 | STATIC unsigned long |
| 1660 | suffix_strtoul(const char *cp, char **endp, unsigned int base) | 1649 | suffix_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 | ||
| 1682 | STATIC int | 1671 | STATIC 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 */ |
| 1834 | printk("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")) { |
| 1836 | printk("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 | ||
| 1970 | vfsops_t xfs_vfsops = { | 1976 | bhv_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 | */ | ||
| 76 | STATIC int | 56 | STATIC int |
| 77 | xfs_open( | 57 | xfs_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 | ||
| 81 | STATIC int | ||
| 82 | xfs_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( | |||
| 108 | STATIC int | 114 | STATIC int |
| 109 | xfs_getattr( | 115 | xfs_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( | |||
| 241 | int | 247 | int |
| 242 | xfs_setattr( | 248 | xfs_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 | */ | ||
| 1475 | STATIC int | 1494 | STATIC int |
| 1476 | xfs_inactive_attrs( | 1495 | xfs_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( | |||
| 1795 | STATIC int | 1812 | STATIC int |
| 1796 | xfs_lookup( | 1813 | xfs_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( | |||
| 1832 | STATIC int | 1849 | STATIC int |
| 1833 | xfs_create( | 1850 | xfs_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; | |||
| 2107 | STATIC int | 2123 | STATIC int |
| 2108 | xfs_lock_dir_and_entry( | 2124 | xfs_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; | |||
| 2321 | STATIC int | 2337 | STATIC int |
| 2322 | xfs_remove( | 2338 | xfs_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( | |||
| 2564 | STATIC int | 2580 | STATIC int |
| 2565 | xfs_link( | 2581 | xfs_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: | |||
| 2734 | STATIC int | 2749 | STATIC int |
| 2735 | xfs_mkdir( | 2750 | xfs_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: | |||
| 2969 | STATIC int | 2982 | STATIC int |
| 2970 | xfs_rmdir( | 2983 | xfs_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 | */ | ||
| 3248 | STATIC int | 3253 | STATIC int |
| 3249 | xfs_symlink( | 3254 | xfs_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( | |||
| 3606 | int | 3610 | int |
| 3607 | xfs_rwlock( | 3611 | xfs_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( | |||
| 3637 | void | 3641 | void |
| 3638 | xfs_rwunlock( | 3642 | xfs_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 | |||
| 3748 | int | 3751 | int |
| 3749 | xfs_set_dmattrs ( | 3752 | xfs_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 | */ | ||
| 3792 | STATIC int | 3791 | STATIC int |
| 3793 | xfs_reclaim( | 3792 | xfs_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 | ||
| 4645 | vnodeops_t xfs_vnodeops = { | 4643 | bhv_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, |
