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, |