diff options
Diffstat (limited to 'fs')
147 files changed, 2363 insertions, 1730 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 22f7ccd58d38..0f628041e3f7 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -460,8 +460,10 @@ static int __init init_v9fs(void) | |||
460 | 460 | ||
461 | ret = v9fs_mux_global_init(); | 461 | ret = v9fs_mux_global_init(); |
462 | if (!ret) | 462 | if (!ret) |
463 | ret = register_filesystem(&v9fs_fs_type); | 463 | return ret; |
464 | 464 | ret = register_filesystem(&v9fs_fs_type); | |
465 | if (!ret) | ||
466 | v9fs_mux_global_exit(); | ||
465 | return ret; | 467 | return ret; |
466 | } | 468 | } |
467 | 469 | ||
diff --git a/fs/Kconfig b/fs/Kconfig index d311198bba43..1453d2d164f7 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -4,6 +4,8 @@ | |||
4 | 4 | ||
5 | menu "File systems" | 5 | menu "File systems" |
6 | 6 | ||
7 | if BLOCK | ||
8 | |||
7 | config EXT2_FS | 9 | config EXT2_FS |
8 | tristate "Second extended fs support" | 10 | tristate "Second extended fs support" |
9 | help | 11 | help |
@@ -399,6 +401,8 @@ config ROMFS_FS | |||
399 | If you don't know whether you need it, then you don't need it: | 401 | If you don't know whether you need it, then you don't need it: |
400 | answer N. | 402 | answer N. |
401 | 403 | ||
404 | endif | ||
405 | |||
402 | config INOTIFY | 406 | config INOTIFY |
403 | bool "Inotify file change notification support" | 407 | bool "Inotify file change notification support" |
404 | default y | 408 | default y |
@@ -530,6 +534,7 @@ config FUSE_FS | |||
530 | If you want to develop a userspace FS, or if you want to use | 534 | If you want to develop a userspace FS, or if you want to use |
531 | a filesystem based on FUSE, answer Y or M. | 535 | a filesystem based on FUSE, answer Y or M. |
532 | 536 | ||
537 | if BLOCK | ||
533 | menu "CD-ROM/DVD Filesystems" | 538 | menu "CD-ROM/DVD Filesystems" |
534 | 539 | ||
535 | config ISO9660_FS | 540 | config ISO9660_FS |
@@ -597,7 +602,9 @@ config UDF_NLS | |||
597 | depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y) | 602 | depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y) |
598 | 603 | ||
599 | endmenu | 604 | endmenu |
605 | endif | ||
600 | 606 | ||
607 | if BLOCK | ||
601 | menu "DOS/FAT/NT Filesystems" | 608 | menu "DOS/FAT/NT Filesystems" |
602 | 609 | ||
603 | config FAT_FS | 610 | config FAT_FS |
@@ -782,6 +789,7 @@ config NTFS_RW | |||
782 | It is perfectly safe to say N here. | 789 | It is perfectly safe to say N here. |
783 | 790 | ||
784 | endmenu | 791 | endmenu |
792 | endif | ||
785 | 793 | ||
786 | menu "Pseudo filesystems" | 794 | menu "Pseudo filesystems" |
787 | 795 | ||
@@ -881,6 +889,19 @@ config TMPFS | |||
881 | 889 | ||
882 | See <file:Documentation/filesystems/tmpfs.txt> for details. | 890 | See <file:Documentation/filesystems/tmpfs.txt> for details. |
883 | 891 | ||
892 | config TMPFS_POSIX_ACL | ||
893 | bool "Tmpfs POSIX Access Control Lists" | ||
894 | depends on TMPFS | ||
895 | select GENERIC_ACL | ||
896 | help | ||
897 | POSIX Access Control Lists (ACLs) support permissions for users and | ||
898 | groups beyond the owner/group/world scheme. | ||
899 | |||
900 | To learn more about Access Control Lists, visit the POSIX ACLs for | ||
901 | Linux website <http://acl.bestbits.at/>. | ||
902 | |||
903 | If you don't know what Access Control Lists are, say N. | ||
904 | |||
884 | config HUGETLBFS | 905 | config HUGETLBFS |
885 | bool "HugeTLB file system support" | 906 | bool "HugeTLB file system support" |
886 | depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN | 907 | depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN |
@@ -926,7 +947,7 @@ menu "Miscellaneous filesystems" | |||
926 | 947 | ||
927 | config ADFS_FS | 948 | config ADFS_FS |
928 | tristate "ADFS file system support (EXPERIMENTAL)" | 949 | tristate "ADFS file system support (EXPERIMENTAL)" |
929 | depends on EXPERIMENTAL | 950 | depends on BLOCK && EXPERIMENTAL |
930 | help | 951 | help |
931 | The Acorn Disc Filing System is the standard file system of the | 952 | The Acorn Disc Filing System is the standard file system of the |
932 | RiscOS operating system which runs on Acorn's ARM-based Risc PC | 953 | RiscOS operating system which runs on Acorn's ARM-based Risc PC |
@@ -954,7 +975,7 @@ config ADFS_FS_RW | |||
954 | 975 | ||
955 | config AFFS_FS | 976 | config AFFS_FS |
956 | tristate "Amiga FFS file system support (EXPERIMENTAL)" | 977 | tristate "Amiga FFS file system support (EXPERIMENTAL)" |
957 | depends on EXPERIMENTAL | 978 | depends on BLOCK && EXPERIMENTAL |
958 | help | 979 | help |
959 | The Fast File System (FFS) is the common file system used on hard | 980 | The Fast File System (FFS) is the common file system used on hard |
960 | disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y | 981 | disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y |
@@ -976,7 +997,7 @@ config AFFS_FS | |||
976 | 997 | ||
977 | config HFS_FS | 998 | config HFS_FS |
978 | tristate "Apple Macintosh file system support (EXPERIMENTAL)" | 999 | tristate "Apple Macintosh file system support (EXPERIMENTAL)" |
979 | depends on EXPERIMENTAL | 1000 | depends on BLOCK && EXPERIMENTAL |
980 | select NLS | 1001 | select NLS |
981 | help | 1002 | help |
982 | If you say Y here, you will be able to mount Macintosh-formatted | 1003 | If you say Y here, you will be able to mount Macintosh-formatted |
@@ -989,6 +1010,7 @@ config HFS_FS | |||
989 | 1010 | ||
990 | config HFSPLUS_FS | 1011 | config HFSPLUS_FS |
991 | tristate "Apple Extended HFS file system support" | 1012 | tristate "Apple Extended HFS file system support" |
1013 | depends on BLOCK | ||
992 | select NLS | 1014 | select NLS |
993 | select NLS_UTF8 | 1015 | select NLS_UTF8 |
994 | help | 1016 | help |
@@ -1002,7 +1024,7 @@ config HFSPLUS_FS | |||
1002 | 1024 | ||
1003 | config BEFS_FS | 1025 | config BEFS_FS |
1004 | tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)" | 1026 | tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)" |
1005 | depends on EXPERIMENTAL | 1027 | depends on BLOCK && EXPERIMENTAL |
1006 | select NLS | 1028 | select NLS |
1007 | help | 1029 | help |
1008 | The BeOS File System (BeFS) is the native file system of Be, Inc's | 1030 | The BeOS File System (BeFS) is the native file system of Be, Inc's |
@@ -1029,7 +1051,7 @@ config BEFS_DEBUG | |||
1029 | 1051 | ||
1030 | config BFS_FS | 1052 | config BFS_FS |
1031 | tristate "BFS file system support (EXPERIMENTAL)" | 1053 | tristate "BFS file system support (EXPERIMENTAL)" |
1032 | depends on EXPERIMENTAL | 1054 | depends on BLOCK && EXPERIMENTAL |
1033 | help | 1055 | help |
1034 | Boot File System (BFS) is a file system used under SCO UnixWare to | 1056 | Boot File System (BFS) is a file system used under SCO UnixWare to |
1035 | allow the bootloader access to the kernel image and other important | 1057 | allow the bootloader access to the kernel image and other important |
@@ -1051,7 +1073,7 @@ config BFS_FS | |||
1051 | 1073 | ||
1052 | config EFS_FS | 1074 | config EFS_FS |
1053 | tristate "EFS file system support (read only) (EXPERIMENTAL)" | 1075 | tristate "EFS file system support (read only) (EXPERIMENTAL)" |
1054 | depends on EXPERIMENTAL | 1076 | depends on BLOCK && EXPERIMENTAL |
1055 | help | 1077 | help |
1056 | EFS is an older file system used for non-ISO9660 CD-ROMs and hard | 1078 | EFS is an older file system used for non-ISO9660 CD-ROMs and hard |
1057 | disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer | 1079 | disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer |
@@ -1066,7 +1088,7 @@ config EFS_FS | |||
1066 | 1088 | ||
1067 | config JFFS_FS | 1089 | config JFFS_FS |
1068 | tristate "Journalling Flash File System (JFFS) support" | 1090 | tristate "Journalling Flash File System (JFFS) support" |
1069 | depends on MTD | 1091 | depends on MTD && BLOCK |
1070 | help | 1092 | help |
1071 | JFFS is the Journaling Flash File System developed by Axis | 1093 | JFFS is the Journaling Flash File System developed by Axis |
1072 | Communications in Sweden, aimed at providing a crash/powerdown-safe | 1094 | Communications in Sweden, aimed at providing a crash/powerdown-safe |
@@ -1251,6 +1273,7 @@ endchoice | |||
1251 | 1273 | ||
1252 | config CRAMFS | 1274 | config CRAMFS |
1253 | tristate "Compressed ROM file system support (cramfs)" | 1275 | tristate "Compressed ROM file system support (cramfs)" |
1276 | depends on BLOCK | ||
1254 | select ZLIB_INFLATE | 1277 | select ZLIB_INFLATE |
1255 | help | 1278 | help |
1256 | Saying Y here includes support for CramFs (Compressed ROM File | 1279 | Saying Y here includes support for CramFs (Compressed ROM File |
@@ -1270,6 +1293,7 @@ config CRAMFS | |||
1270 | 1293 | ||
1271 | config VXFS_FS | 1294 | config VXFS_FS |
1272 | tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" | 1295 | tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" |
1296 | depends on BLOCK | ||
1273 | help | 1297 | help |
1274 | FreeVxFS is a file system driver that support the VERITAS VxFS(TM) | 1298 | FreeVxFS is a file system driver that support the VERITAS VxFS(TM) |
1275 | file system format. VERITAS VxFS(TM) is the standard file system | 1299 | file system format. VERITAS VxFS(TM) is the standard file system |
@@ -1287,6 +1311,7 @@ config VXFS_FS | |||
1287 | 1311 | ||
1288 | config HPFS_FS | 1312 | config HPFS_FS |
1289 | tristate "OS/2 HPFS file system support" | 1313 | tristate "OS/2 HPFS file system support" |
1314 | depends on BLOCK | ||
1290 | help | 1315 | help |
1291 | OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS | 1316 | OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS |
1292 | is the file system used for organizing files on OS/2 hard disk | 1317 | is the file system used for organizing files on OS/2 hard disk |
@@ -1303,6 +1328,7 @@ config HPFS_FS | |||
1303 | 1328 | ||
1304 | config QNX4FS_FS | 1329 | config QNX4FS_FS |
1305 | tristate "QNX4 file system support (read only)" | 1330 | tristate "QNX4 file system support (read only)" |
1331 | depends on BLOCK | ||
1306 | help | 1332 | help |
1307 | This is the file system used by the real-time operating systems | 1333 | This is the file system used by the real-time operating systems |
1308 | QNX 4 and QNX 6 (the latter is also called QNX RTP). | 1334 | QNX 4 and QNX 6 (the latter is also called QNX RTP). |
@@ -1330,6 +1356,7 @@ config QNX4FS_RW | |||
1330 | 1356 | ||
1331 | config SYSV_FS | 1357 | config SYSV_FS |
1332 | tristate "System V/Xenix/V7/Coherent file system support" | 1358 | tristate "System V/Xenix/V7/Coherent file system support" |
1359 | depends on BLOCK | ||
1333 | help | 1360 | help |
1334 | SCO, Xenix and Coherent are commercial Unix systems for Intel | 1361 | SCO, Xenix and Coherent are commercial Unix systems for Intel |
1335 | machines, and Version 7 was used on the DEC PDP-11. Saying Y | 1362 | machines, and Version 7 was used on the DEC PDP-11. Saying Y |
@@ -1368,6 +1395,7 @@ config SYSV_FS | |||
1368 | 1395 | ||
1369 | config UFS_FS | 1396 | config UFS_FS |
1370 | tristate "UFS file system support (read only)" | 1397 | tristate "UFS file system support (read only)" |
1398 | depends on BLOCK | ||
1371 | help | 1399 | help |
1372 | BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, | 1400 | BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, |
1373 | OpenBSD and NeXTstep) use a file system called UFS. Some System V | 1401 | OpenBSD and NeXTstep) use a file system called UFS. Some System V |
@@ -1940,13 +1968,19 @@ config 9P_FS | |||
1940 | 1968 | ||
1941 | If unsure, say N. | 1969 | If unsure, say N. |
1942 | 1970 | ||
1971 | config GENERIC_ACL | ||
1972 | bool | ||
1973 | select FS_POSIX_ACL | ||
1974 | |||
1943 | endmenu | 1975 | endmenu |
1944 | 1976 | ||
1977 | if BLOCK | ||
1945 | menu "Partition Types" | 1978 | menu "Partition Types" |
1946 | 1979 | ||
1947 | source "fs/partitions/Kconfig" | 1980 | source "fs/partitions/Kconfig" |
1948 | 1981 | ||
1949 | endmenu | 1982 | endmenu |
1983 | endif | ||
1950 | 1984 | ||
1951 | source "fs/nls/Kconfig" | 1985 | source "fs/nls/Kconfig" |
1952 | 1986 | ||
diff --git a/fs/Makefile b/fs/Makefile index 89135428a539..a503e6ce0f32 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -5,12 +5,18 @@ | |||
5 | # Rewritten to use lists instead of if-statements. | 5 | # Rewritten to use lists instead of if-statements. |
6 | # | 6 | # |
7 | 7 | ||
8 | obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \ | 8 | obj-y := open.o read_write.o file_table.o super.o \ |
9 | block_dev.o char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ | 9 | char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ |
10 | ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ | 10 | ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ |
11 | attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ | 11 | attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ |
12 | seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ | 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ |
13 | ioprio.o pnode.o drop_caches.o splice.o sync.o | 13 | pnode.o drop_caches.o splice.o sync.o |
14 | |||
15 | ifeq ($(CONFIG_BLOCK),y) | ||
16 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o | ||
17 | else | ||
18 | obj-y += no-block.o | ||
19 | endif | ||
14 | 20 | ||
15 | obj-$(CONFIG_INOTIFY) += inotify.o | 21 | obj-$(CONFIG_INOTIFY) += inotify.o |
16 | obj-$(CONFIG_INOTIFY_USER) += inotify_user.o | 22 | obj-$(CONFIG_INOTIFY_USER) += inotify_user.o |
@@ -35,6 +41,7 @@ obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o | |||
35 | obj-$(CONFIG_FS_MBCACHE) += mbcache.o | 41 | obj-$(CONFIG_FS_MBCACHE) += mbcache.o |
36 | obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o | 42 | obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o |
37 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ | 43 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ |
44 | obj-$(CONFIG_GENERIC_ACL) += generic_acl.o | ||
38 | 45 | ||
39 | obj-$(CONFIG_QUOTA) += dquot.o | 46 | obj-$(CONFIG_QUOTA) += dquot.o |
40 | obj-$(CONFIG_QFMT_V1) += quota_v1.o | 47 | obj-$(CONFIG_QFMT_V1) += quota_v1.o |
diff --git a/fs/afs/file.c b/fs/afs/file.c index 67d6634101fd..2e8c42639eaa 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/buffer_head.h> | ||
20 | #include "volume.h" | 19 | #include "volume.h" |
21 | #include "vnode.h" | 20 | #include "vnode.h" |
22 | #include <rxrpc/call.h> | 21 | #include <rxrpc/call.h> |
@@ -37,7 +36,6 @@ struct inode_operations afs_file_inode_operations = { | |||
37 | 36 | ||
38 | const struct address_space_operations afs_fs_aops = { | 37 | const struct address_space_operations afs_fs_aops = { |
39 | .readpage = afs_file_readpage, | 38 | .readpage = afs_file_readpage, |
40 | .sync_page = block_sync_page, | ||
41 | .set_page_dirty = __set_page_dirty_nobuffers, | 39 | .set_page_dirty = __set_page_dirty_nobuffers, |
42 | .releasepage = afs_file_releasepage, | 40 | .releasepage = afs_file_releasepage, |
43 | .invalidatepage = afs_file_invalidatepage, | 41 | .invalidatepage = afs_file_invalidatepage, |
diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 101d21b6c037..86463ec9ccb4 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c | |||
@@ -775,6 +775,7 @@ static int afs_proc_cell_servers_release(struct inode *inode, | |||
775 | * first item | 775 | * first item |
776 | */ | 776 | */ |
777 | static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos) | 777 | static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos) |
778 | __acquires(m->private->sv_lock) | ||
778 | { | 779 | { |
779 | struct list_head *_p; | 780 | struct list_head *_p; |
780 | struct afs_cell *cell = m->private; | 781 | struct afs_cell *cell = m->private; |
@@ -823,6 +824,7 @@ static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, | |||
823 | * clean up after reading from the cells list | 824 | * clean up after reading from the cells list |
824 | */ | 825 | */ |
825 | static void afs_proc_cell_servers_stop(struct seq_file *p, void *v) | 826 | static void afs_proc_cell_servers_stop(struct seq_file *p, void *v) |
827 | __releases(p->private->sv_lock) | ||
826 | { | 828 | { |
827 | struct afs_cell *cell = p->private; | 829 | struct afs_cell *cell = p->private; |
828 | 830 | ||
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 27e17f96cada..563ef9d7da9f 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -281,9 +281,6 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags) | |||
281 | 281 | ||
282 | DPRINTK("mount done status=%d", status); | 282 | DPRINTK("mount done status=%d", status); |
283 | 283 | ||
284 | if (status && dentry->d_inode) | ||
285 | return status; /* Try to get the kernel to invalidate this dentry */ | ||
286 | |||
287 | /* Turn this into a real negative dentry? */ | 284 | /* Turn this into a real negative dentry? */ |
288 | if (status == -ENOENT) { | 285 | if (status == -ENOENT) { |
289 | spin_lock(&dentry->d_lock); | 286 | spin_lock(&dentry->d_lock); |
@@ -359,7 +356,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
359 | * don't try to mount it again. | 356 | * don't try to mount it again. |
360 | */ | 357 | */ |
361 | spin_lock(&dcache_lock); | 358 | spin_lock(&dcache_lock); |
362 | if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { | 359 | if (!d_mountpoint(dentry) && __simple_empty(dentry)) { |
363 | spin_unlock(&dcache_lock); | 360 | spin_unlock(&dcache_lock); |
364 | 361 | ||
365 | status = try_to_fill_dentry(dentry, 0); | 362 | status = try_to_fill_dentry(dentry, 0); |
@@ -540,6 +537,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
540 | return ERR_PTR(-ERESTARTNOINTR); | 537 | return ERR_PTR(-ERESTARTNOINTR); |
541 | } | 538 | } |
542 | } | 539 | } |
540 | spin_lock(&dentry->d_lock); | ||
541 | dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; | ||
542 | spin_unlock(&dentry->d_lock); | ||
543 | } | 543 | } |
544 | 544 | ||
545 | /* | 545 | /* |
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index f312103434d4..517e111bb7ef 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -278,6 +278,13 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
278 | return -ENOEXEC; | 278 | return -ENOEXEC; |
279 | } | 279 | } |
280 | 280 | ||
281 | /* | ||
282 | * Requires a mmap handler. This prevents people from using a.out | ||
283 | * as part of an exploit attack against /proc-related vulnerabilities. | ||
284 | */ | ||
285 | if (!bprm->file->f_op || !bprm->file->f_op->mmap) | ||
286 | return -ENOEXEC; | ||
287 | |||
281 | fd_offset = N_TXTOFF(ex); | 288 | fd_offset = N_TXTOFF(ex); |
282 | 289 | ||
283 | /* Check initial limits. This avoids letting people circumvent | 290 | /* Check initial limits. This avoids letting people circumvent |
@@ -476,6 +483,13 @@ static int load_aout_library(struct file *file) | |||
476 | goto out; | 483 | goto out; |
477 | } | 484 | } |
478 | 485 | ||
486 | /* | ||
487 | * Requires a mmap handler. This prevents people from using a.out | ||
488 | * as part of an exploit attack against /proc-related vulnerabilities. | ||
489 | */ | ||
490 | if (!file->f_op || !file->f_op->mmap) | ||
491 | goto out; | ||
492 | |||
479 | if (N_FLAGS(ex)) | 493 | if (N_FLAGS(ex)) |
480 | goto out; | 494 | goto out; |
481 | 495 | ||
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index dfd8cfb7fb5d..bad52433de69 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -46,7 +46,6 @@ | |||
46 | static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); | 46 | static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); |
47 | static int load_elf_library(struct file *); | 47 | static int load_elf_library(struct file *); |
48 | 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); |
49 | extern int dump_fpu (struct pt_regs *, elf_fpregset_t *); | ||
50 | 49 | ||
51 | #ifndef elf_addr_t | 50 | #ifndef elf_addr_t |
52 | #define elf_addr_t unsigned long | 51 | #define elf_addr_t unsigned long |
@@ -1038,10 +1037,8 @@ out_free_interp: | |||
1038 | out_free_file: | 1037 | out_free_file: |
1039 | sys_close(elf_exec_fileno); | 1038 | sys_close(elf_exec_fileno); |
1040 | out_free_fh: | 1039 | out_free_fh: |
1041 | if (files) { | 1040 | if (files) |
1042 | put_files_struct(current->files); | 1041 | reset_files_struct(current, files); |
1043 | current->files = files; | ||
1044 | } | ||
1045 | out_free_ph: | 1042 | out_free_ph: |
1046 | kfree(elf_phdata); | 1043 | kfree(elf_phdata); |
1047 | goto out; | 1044 | goto out; |
@@ -1481,20 +1478,19 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1481 | 1478 | ||
1482 | if (signr) { | 1479 | if (signr) { |
1483 | struct elf_thread_status *tmp; | 1480 | struct elf_thread_status *tmp; |
1484 | read_lock(&tasklist_lock); | 1481 | rcu_read_lock(); |
1485 | do_each_thread(g,p) | 1482 | do_each_thread(g,p) |
1486 | if (current->mm == p->mm && current != p) { | 1483 | if (current->mm == p->mm && current != p) { |
1487 | tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); | 1484 | tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); |
1488 | if (!tmp) { | 1485 | if (!tmp) { |
1489 | read_unlock(&tasklist_lock); | 1486 | rcu_read_unlock(); |
1490 | goto cleanup; | 1487 | goto cleanup; |
1491 | } | 1488 | } |
1492 | INIT_LIST_HEAD(&tmp->list); | ||
1493 | tmp->thread = p; | 1489 | tmp->thread = p; |
1494 | list_add(&tmp->list, &thread_list); | 1490 | list_add(&tmp->list, &thread_list); |
1495 | } | 1491 | } |
1496 | while_each_thread(g,p); | 1492 | while_each_thread(g,p); |
1497 | read_unlock(&tasklist_lock); | 1493 | rcu_read_unlock(); |
1498 | list_for_each(t, &thread_list) { | 1494 | list_for_each(t, &thread_list) { |
1499 | struct elf_thread_status *tmp; | 1495 | struct elf_thread_status *tmp; |
1500 | int sz; | 1496 | int sz; |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 2f3365829229..f86d5c9ce5eb 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1597,20 +1597,19 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1597 | 1597 | ||
1598 | if (signr) { | 1598 | if (signr) { |
1599 | struct elf_thread_status *tmp; | 1599 | struct elf_thread_status *tmp; |
1600 | read_lock(&tasklist_lock); | 1600 | rcu_read_lock(); |
1601 | do_each_thread(g,p) | 1601 | do_each_thread(g,p) |
1602 | if (current->mm == p->mm && current != p) { | 1602 | if (current->mm == p->mm && current != p) { |
1603 | tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); | 1603 | tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); |
1604 | if (!tmp) { | 1604 | if (!tmp) { |
1605 | read_unlock(&tasklist_lock); | 1605 | rcu_read_unlock(); |
1606 | goto cleanup; | 1606 | goto cleanup; |
1607 | } | 1607 | } |
1608 | INIT_LIST_HEAD(&tmp->list); | ||
1609 | tmp->thread = p; | 1608 | tmp->thread = p; |
1610 | list_add(&tmp->list, &thread_list); | 1609 | list_add(&tmp->list, &thread_list); |
1611 | } | 1610 | } |
1612 | while_each_thread(g,p); | 1611 | while_each_thread(g,p); |
1613 | read_unlock(&tasklist_lock); | 1612 | rcu_read_unlock(); |
1614 | list_for_each(t, &thread_list) { | 1613 | list_for_each(t, &thread_list) { |
1615 | struct elf_thread_status *tmp; | 1614 | struct elf_thread_status *tmp; |
1616 | int sz; | 1615 | int sz; |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 66ba137f8661..1713c48fef54 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -215,10 +215,8 @@ _error: | |||
215 | bprm->interp_flags = 0; | 215 | bprm->interp_flags = 0; |
216 | bprm->interp_data = 0; | 216 | bprm->interp_data = 0; |
217 | _unshare: | 217 | _unshare: |
218 | if (files) { | 218 | if (files) |
219 | put_files_struct(current->files); | 219 | reset_files_struct(current, files); |
220 | current->files = files; | ||
221 | } | ||
222 | goto _ret; | 220 | goto _ret; |
223 | } | 221 | } |
224 | 222 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Jens Axboe <axboe@suse.de> | 2 | * Copyright (C) 2001 Jens Axboe <axboe@kernel.dk> |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
@@ -1142,7 +1142,7 @@ static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale) | |||
1142 | struct biovec_slab *bp = bvec_slabs + i; | 1142 | struct biovec_slab *bp = bvec_slabs + i; |
1143 | mempool_t **bvp = bs->bvec_pools + i; | 1143 | mempool_t **bvp = bs->bvec_pools + i; |
1144 | 1144 | ||
1145 | if (i >= scale) | 1145 | if (pool_entries > 1 && i >= scale) |
1146 | pool_entries >>= 1; | 1146 | pool_entries >>= 1; |
1147 | 1147 | ||
1148 | *bvp = mempool_create_slab_pool(pool_entries, bp->slab); | 1148 | *bvp = mempool_create_slab_pool(pool_entries, bp->slab); |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 045f98854f14..0c361ea7e5a6 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -17,11 +17,13 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/blkpg.h> | 18 | #include <linux/blkpg.h> |
19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
20 | #include <linux/writeback.h> | ||
20 | #include <linux/mpage.h> | 21 | #include <linux/mpage.h> |
21 | #include <linux/mount.h> | 22 | #include <linux/mount.h> |
22 | #include <linux/uio.h> | 23 | #include <linux/uio.h> |
23 | #include <linux/namei.h> | 24 | #include <linux/namei.h> |
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | #include "internal.h" | ||
25 | 27 | ||
26 | struct bdev_inode { | 28 | struct bdev_inode { |
27 | struct block_device bdev; | 29 | struct block_device bdev; |
@@ -543,11 +545,11 @@ static struct kobject *bdev_get_holder(struct block_device *bdev) | |||
543 | return kobject_get(bdev->bd_disk->holder_dir); | 545 | return kobject_get(bdev->bd_disk->holder_dir); |
544 | } | 546 | } |
545 | 547 | ||
546 | static void add_symlink(struct kobject *from, struct kobject *to) | 548 | static int add_symlink(struct kobject *from, struct kobject *to) |
547 | { | 549 | { |
548 | if (!from || !to) | 550 | if (!from || !to) |
549 | return; | 551 | return 0; |
550 | sysfs_create_link(from, to, kobject_name(to)); | 552 | return sysfs_create_link(from, to, kobject_name(to)); |
551 | } | 553 | } |
552 | 554 | ||
553 | static void del_symlink(struct kobject *from, struct kobject *to) | 555 | static void del_symlink(struct kobject *from, struct kobject *to) |
@@ -648,30 +650,38 @@ static void free_bd_holder(struct bd_holder *bo) | |||
648 | * If there is no matching entry with @bo in @bdev->bd_holder_list, | 650 | * If there is no matching entry with @bo in @bdev->bd_holder_list, |
649 | * add @bo to the list, create symlinks. | 651 | * add @bo to the list, create symlinks. |
650 | * | 652 | * |
651 | * Returns 1 if @bo was added to the list. | 653 | * Returns 0 if symlinks are created or already there. |
652 | * Returns 0 if @bo wasn't used by any reason and should be freed. | 654 | * Returns -ve if something fails and @bo can be freed. |
653 | */ | 655 | */ |
654 | static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) | 656 | static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) |
655 | { | 657 | { |
656 | struct bd_holder *tmp; | 658 | struct bd_holder *tmp; |
659 | int ret; | ||
657 | 660 | ||
658 | if (!bo) | 661 | if (!bo) |
659 | return 0; | 662 | return -EINVAL; |
660 | 663 | ||
661 | list_for_each_entry(tmp, &bdev->bd_holder_list, list) { | 664 | list_for_each_entry(tmp, &bdev->bd_holder_list, list) { |
662 | if (tmp->sdir == bo->sdir) { | 665 | if (tmp->sdir == bo->sdir) { |
663 | tmp->count++; | 666 | tmp->count++; |
667 | /* We've already done what we need to do here. */ | ||
668 | free_bd_holder(bo); | ||
664 | return 0; | 669 | return 0; |
665 | } | 670 | } |
666 | } | 671 | } |
667 | 672 | ||
668 | if (!bd_holder_grab_dirs(bdev, bo)) | 673 | if (!bd_holder_grab_dirs(bdev, bo)) |
669 | return 0; | 674 | return -EBUSY; |
670 | 675 | ||
671 | add_symlink(bo->sdir, bo->sdev); | 676 | ret = add_symlink(bo->sdir, bo->sdev); |
672 | add_symlink(bo->hdir, bo->hdev); | 677 | if (ret == 0) { |
673 | list_add_tail(&bo->list, &bdev->bd_holder_list); | 678 | ret = add_symlink(bo->hdir, bo->hdev); |
674 | return 1; | 679 | if (ret) |
680 | del_symlink(bo->sdir, bo->sdev); | ||
681 | } | ||
682 | if (ret == 0) | ||
683 | list_add_tail(&bo->list, &bdev->bd_holder_list); | ||
684 | return ret; | ||
675 | } | 685 | } |
676 | 686 | ||
677 | /** | 687 | /** |
@@ -741,7 +751,9 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, | |||
741 | 751 | ||
742 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); | 752 | mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); |
743 | res = bd_claim(bdev, holder); | 753 | res = bd_claim(bdev, holder); |
744 | if (res || !add_bd_holder(bdev, bo)) | 754 | if (res == 0) |
755 | res = add_bd_holder(bdev, bo); | ||
756 | if (res) | ||
745 | free_bd_holder(bo); | 757 | free_bd_holder(bo); |
746 | mutex_unlock(&bdev->bd_mutex); | 758 | mutex_unlock(&bdev->bd_mutex); |
747 | 759 | ||
@@ -1021,7 +1033,7 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass) | |||
1021 | rescan_partitions(bdev->bd_disk, bdev); | 1033 | rescan_partitions(bdev->bd_disk, bdev); |
1022 | } else { | 1034 | } else { |
1023 | mutex_lock_nested(&bdev->bd_contains->bd_mutex, | 1035 | mutex_lock_nested(&bdev->bd_contains->bd_mutex, |
1024 | BD_MUTEX_PARTITION); | 1036 | BD_MUTEX_WHOLE); |
1025 | bdev->bd_contains->bd_part_count++; | 1037 | bdev->bd_contains->bd_part_count++; |
1026 | mutex_unlock(&bdev->bd_contains->bd_mutex); | 1038 | mutex_unlock(&bdev->bd_contains->bd_mutex); |
1027 | } | 1039 | } |
@@ -1303,3 +1315,24 @@ void close_bdev_excl(struct block_device *bdev) | |||
1303 | } | 1315 | } |
1304 | 1316 | ||
1305 | EXPORT_SYMBOL(close_bdev_excl); | 1317 | EXPORT_SYMBOL(close_bdev_excl); |
1318 | |||
1319 | int __invalidate_device(struct block_device *bdev) | ||
1320 | { | ||
1321 | struct super_block *sb = get_super(bdev); | ||
1322 | int res = 0; | ||
1323 | |||
1324 | if (sb) { | ||
1325 | /* | ||
1326 | * no need to lock the super, get_super holds the | ||
1327 | * read mutex so the filesystem cannot go away | ||
1328 | * under us (->put_super runs with the write lock | ||
1329 | * hold). | ||
1330 | */ | ||
1331 | shrink_dcache_sb(sb); | ||
1332 | res = invalidate_inodes(sb); | ||
1333 | drop_super(sb); | ||
1334 | } | ||
1335 | invalidate_bdev(bdev, 0); | ||
1336 | return res; | ||
1337 | } | ||
1338 | EXPORT_SYMBOL(__invalidate_device); | ||
diff --git a/fs/buffer.c b/fs/buffer.c index 3b6d701073e7..16cfbcd254f1 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -159,31 +159,6 @@ int sync_blockdev(struct block_device *bdev) | |||
159 | } | 159 | } |
160 | EXPORT_SYMBOL(sync_blockdev); | 160 | EXPORT_SYMBOL(sync_blockdev); |
161 | 161 | ||
162 | static void __fsync_super(struct super_block *sb) | ||
163 | { | ||
164 | sync_inodes_sb(sb, 0); | ||
165 | DQUOT_SYNC(sb); | ||
166 | lock_super(sb); | ||
167 | if (sb->s_dirt && sb->s_op->write_super) | ||
168 | sb->s_op->write_super(sb); | ||
169 | unlock_super(sb); | ||
170 | if (sb->s_op->sync_fs) | ||
171 | sb->s_op->sync_fs(sb, 1); | ||
172 | sync_blockdev(sb->s_bdev); | ||
173 | sync_inodes_sb(sb, 1); | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Write out and wait upon all dirty data associated with this | ||
178 | * superblock. Filesystem data as well as the underlying block | ||
179 | * device. Takes the superblock lock. | ||
180 | */ | ||
181 | int fsync_super(struct super_block *sb) | ||
182 | { | ||
183 | __fsync_super(sb); | ||
184 | return sync_blockdev(sb->s_bdev); | ||
185 | } | ||
186 | |||
187 | /* | 162 | /* |
188 | * Write out and wait upon all dirty data associated with this | 163 | * Write out and wait upon all dirty data associated with this |
189 | * device. Filesystem data as well as the underlying block | 164 | * device. Filesystem data as well as the underlying block |
@@ -260,118 +235,6 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb) | |||
260 | EXPORT_SYMBOL(thaw_bdev); | 235 | EXPORT_SYMBOL(thaw_bdev); |
261 | 236 | ||
262 | /* | 237 | /* |
263 | * sync everything. Start out by waking pdflush, because that writes back | ||
264 | * all queues in parallel. | ||
265 | */ | ||
266 | static void do_sync(unsigned long wait) | ||
267 | { | ||
268 | wakeup_pdflush(0); | ||
269 | sync_inodes(0); /* All mappings, inodes and their blockdevs */ | ||
270 | DQUOT_SYNC(NULL); | ||
271 | sync_supers(); /* Write the superblocks */ | ||
272 | sync_filesystems(0); /* Start syncing the filesystems */ | ||
273 | sync_filesystems(wait); /* Waitingly sync the filesystems */ | ||
274 | sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ | ||
275 | if (!wait) | ||
276 | printk("Emergency Sync complete\n"); | ||
277 | if (unlikely(laptop_mode)) | ||
278 | laptop_sync_completion(); | ||
279 | } | ||
280 | |||
281 | asmlinkage long sys_sync(void) | ||
282 | { | ||
283 | do_sync(1); | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | void emergency_sync(void) | ||
288 | { | ||
289 | pdflush_operation(do_sync, 0); | ||
290 | } | ||
291 | |||
292 | /* | ||
293 | * Generic function to fsync a file. | ||
294 | * | ||
295 | * filp may be NULL if called via the msync of a vma. | ||
296 | */ | ||
297 | |||
298 | int file_fsync(struct file *filp, struct dentry *dentry, int datasync) | ||
299 | { | ||
300 | struct inode * inode = dentry->d_inode; | ||
301 | struct super_block * sb; | ||
302 | int ret, err; | ||
303 | |||
304 | /* sync the inode to buffers */ | ||
305 | ret = write_inode_now(inode, 0); | ||
306 | |||
307 | /* sync the superblock to buffers */ | ||
308 | sb = inode->i_sb; | ||
309 | lock_super(sb); | ||
310 | if (sb->s_op->write_super) | ||
311 | sb->s_op->write_super(sb); | ||
312 | unlock_super(sb); | ||
313 | |||
314 | /* .. finally sync the buffers to disk */ | ||
315 | err = sync_blockdev(sb->s_bdev); | ||
316 | if (!ret) | ||
317 | ret = err; | ||
318 | return ret; | ||
319 | } | ||
320 | |||
321 | long do_fsync(struct file *file, int datasync) | ||
322 | { | ||
323 | int ret; | ||
324 | int err; | ||
325 | struct address_space *mapping = file->f_mapping; | ||
326 | |||
327 | if (!file->f_op || !file->f_op->fsync) { | ||
328 | /* Why? We can still call filemap_fdatawrite */ | ||
329 | ret = -EINVAL; | ||
330 | goto out; | ||
331 | } | ||
332 | |||
333 | ret = filemap_fdatawrite(mapping); | ||
334 | |||
335 | /* | ||
336 | * We need to protect against concurrent writers, which could cause | ||
337 | * livelocks in fsync_buffers_list(). | ||
338 | */ | ||
339 | mutex_lock(&mapping->host->i_mutex); | ||
340 | err = file->f_op->fsync(file, file->f_dentry, datasync); | ||
341 | if (!ret) | ||
342 | ret = err; | ||
343 | mutex_unlock(&mapping->host->i_mutex); | ||
344 | err = filemap_fdatawait(mapping); | ||
345 | if (!ret) | ||
346 | ret = err; | ||
347 | out: | ||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static long __do_fsync(unsigned int fd, int datasync) | ||
352 | { | ||
353 | struct file *file; | ||
354 | int ret = -EBADF; | ||
355 | |||
356 | file = fget(fd); | ||
357 | if (file) { | ||
358 | ret = do_fsync(file, datasync); | ||
359 | fput(file); | ||
360 | } | ||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | asmlinkage long sys_fsync(unsigned int fd) | ||
365 | { | ||
366 | return __do_fsync(fd, 0); | ||
367 | } | ||
368 | |||
369 | asmlinkage long sys_fdatasync(unsigned int fd) | ||
370 | { | ||
371 | return __do_fsync(fd, 1); | ||
372 | } | ||
373 | |||
374 | /* | ||
375 | * Various filesystems appear to want __find_get_block to be non-blocking. | 238 | * Various filesystems appear to want __find_get_block to be non-blocking. |
376 | * But it's the page lock which protects the buffers. To get around this, | 239 | * But it's the page lock which protects the buffers. To get around this, |
377 | * we get exclusion from try_to_free_buffers with the blockdev mapping's | 240 | * we get exclusion from try_to_free_buffers with the blockdev mapping's |
@@ -1551,35 +1414,6 @@ static void discard_buffer(struct buffer_head * bh) | |||
1551 | } | 1414 | } |
1552 | 1415 | ||
1553 | /** | 1416 | /** |
1554 | * try_to_release_page() - release old fs-specific metadata on a page | ||
1555 | * | ||
1556 | * @page: the page which the kernel is trying to free | ||
1557 | * @gfp_mask: memory allocation flags (and I/O mode) | ||
1558 | * | ||
1559 | * The address_space is to try to release any data against the page | ||
1560 | * (presumably at page->private). If the release was successful, return `1'. | ||
1561 | * Otherwise return zero. | ||
1562 | * | ||
1563 | * The @gfp_mask argument specifies whether I/O may be performed to release | ||
1564 | * this page (__GFP_IO), and whether the call may block (__GFP_WAIT). | ||
1565 | * | ||
1566 | * NOTE: @gfp_mask may go away, and this function may become non-blocking. | ||
1567 | */ | ||
1568 | int try_to_release_page(struct page *page, gfp_t gfp_mask) | ||
1569 | { | ||
1570 | struct address_space * const mapping = page->mapping; | ||
1571 | |||
1572 | BUG_ON(!PageLocked(page)); | ||
1573 | if (PageWriteback(page)) | ||
1574 | return 0; | ||
1575 | |||
1576 | if (mapping && mapping->a_ops->releasepage) | ||
1577 | return mapping->a_ops->releasepage(page, gfp_mask); | ||
1578 | return try_to_free_buffers(page); | ||
1579 | } | ||
1580 | EXPORT_SYMBOL(try_to_release_page); | ||
1581 | |||
1582 | /** | ||
1583 | * block_invalidatepage - invalidate part of all of a buffer-backed page | 1417 | * block_invalidatepage - invalidate part of all of a buffer-backed page |
1584 | * | 1418 | * |
1585 | * @page: the page which is affected | 1419 | * @page: the page which is affected |
@@ -1630,14 +1464,6 @@ out: | |||
1630 | } | 1464 | } |
1631 | EXPORT_SYMBOL(block_invalidatepage); | 1465 | EXPORT_SYMBOL(block_invalidatepage); |
1632 | 1466 | ||
1633 | void do_invalidatepage(struct page *page, unsigned long offset) | ||
1634 | { | ||
1635 | void (*invalidatepage)(struct page *, unsigned long); | ||
1636 | invalidatepage = page->mapping->a_ops->invalidatepage ? : | ||
1637 | block_invalidatepage; | ||
1638 | (*invalidatepage)(page, offset); | ||
1639 | } | ||
1640 | |||
1641 | /* | 1467 | /* |
1642 | * We attach and possibly dirty the buffers atomically wrt | 1468 | * We attach and possibly dirty the buffers atomically wrt |
1643 | * __set_page_dirty_buffers() via private_lock. try_to_free_buffers | 1469 | * __set_page_dirty_buffers() via private_lock. try_to_free_buffers |
diff --git a/fs/char_dev.c b/fs/char_dev.c index 0009346d827f..a885f46ca001 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #ifdef CONFIG_KMOD | 24 | #ifdef CONFIG_KMOD |
25 | #include <linux/kmod.h> | 25 | #include <linux/kmod.h> |
26 | #endif | 26 | #endif |
27 | #include "internal.h" | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * capabilities for /dev/mem, /dev/kmem and similar directly mappable character | 30 | * capabilities for /dev/mem, /dev/kmem and similar directly mappable character |
@@ -128,13 +129,31 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, | |||
128 | 129 | ||
129 | for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) | 130 | for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) |
130 | if ((*cp)->major > major || | 131 | if ((*cp)->major > major || |
131 | ((*cp)->major == major && (*cp)->baseminor >= baseminor)) | 132 | ((*cp)->major == major && |
133 | (((*cp)->baseminor >= baseminor) || | ||
134 | ((*cp)->baseminor + (*cp)->minorct > baseminor)))) | ||
132 | break; | 135 | break; |
133 | if (*cp && (*cp)->major == major && | 136 | |
134 | (*cp)->baseminor < baseminor + minorct) { | 137 | /* Check for overlapping minor ranges. */ |
135 | ret = -EBUSY; | 138 | if (*cp && (*cp)->major == major) { |
136 | goto out; | 139 | int old_min = (*cp)->baseminor; |
140 | int old_max = (*cp)->baseminor + (*cp)->minorct - 1; | ||
141 | int new_min = baseminor; | ||
142 | int new_max = baseminor + minorct - 1; | ||
143 | |||
144 | /* New driver overlaps from the left. */ | ||
145 | if (new_max >= old_min && new_max <= old_max) { | ||
146 | ret = -EBUSY; | ||
147 | goto out; | ||
148 | } | ||
149 | |||
150 | /* New driver overlaps from the right. */ | ||
151 | if (new_min <= old_max && new_min >= old_min) { | ||
152 | ret = -EBUSY; | ||
153 | goto out; | ||
154 | } | ||
137 | } | 155 | } |
156 | |||
138 | cd->next = *cp; | 157 | cd->next = *cp; |
139 | *cp = cd; | 158 | *cp = cd; |
140 | mutex_unlock(&chrdevs_lock); | 159 | mutex_unlock(&chrdevs_lock); |
@@ -165,6 +184,15 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) | |||
165 | return cd; | 184 | return cd; |
166 | } | 185 | } |
167 | 186 | ||
187 | /** | ||
188 | * register_chrdev_region() - register a range of device numbers | ||
189 | * @from: the first in the desired range of device numbers; must include | ||
190 | * the major number. | ||
191 | * @count: the number of consecutive device numbers required | ||
192 | * @name: the name of the device or driver. | ||
193 | * | ||
194 | * Return value is zero on success, a negative error code on failure. | ||
195 | */ | ||
168 | int register_chrdev_region(dev_t from, unsigned count, const char *name) | 196 | int register_chrdev_region(dev_t from, unsigned count, const char *name) |
169 | { | 197 | { |
170 | struct char_device_struct *cd; | 198 | struct char_device_struct *cd; |
@@ -190,6 +218,17 @@ fail: | |||
190 | return PTR_ERR(cd); | 218 | return PTR_ERR(cd); |
191 | } | 219 | } |
192 | 220 | ||
221 | /** | ||
222 | * alloc_chrdev_region() - register a range of char device numbers | ||
223 | * @dev: output parameter for first assigned number | ||
224 | * @baseminor: first of the requested range of minor numbers | ||
225 | * @count: the number of minor numbers required | ||
226 | * @name: the name of the associated device or driver | ||
227 | * | ||
228 | * Allocates a range of char device numbers. The major number will be | ||
229 | * chosen dynamically, and returned (along with the first minor number) | ||
230 | * in @dev. Returns zero or a negative error code. | ||
231 | */ | ||
193 | int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, | 232 | int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, |
194 | const char *name) | 233 | const char *name) |
195 | { | 234 | { |
@@ -259,6 +298,15 @@ out2: | |||
259 | return err; | 298 | return err; |
260 | } | 299 | } |
261 | 300 | ||
301 | /** | ||
302 | * unregister_chrdev_region() - return a range of device numbers | ||
303 | * @from: the first in the range of numbers to unregister | ||
304 | * @count: the number of device numbers to unregister | ||
305 | * | ||
306 | * This function will unregister a range of @count device numbers, | ||
307 | * starting with @from. The caller should normally be the one who | ||
308 | * allocated those numbers in the first place... | ||
309 | */ | ||
262 | void unregister_chrdev_region(dev_t from, unsigned count) | 310 | void unregister_chrdev_region(dev_t from, unsigned count) |
263 | { | 311 | { |
264 | dev_t to = from + count; | 312 | dev_t to = from + count; |
@@ -396,6 +444,16 @@ static int exact_lock(dev_t dev, void *data) | |||
396 | return cdev_get(p) ? 0 : -1; | 444 | return cdev_get(p) ? 0 : -1; |
397 | } | 445 | } |
398 | 446 | ||
447 | /** | ||
448 | * cdev_add() - add a char device to the system | ||
449 | * @p: the cdev structure for the device | ||
450 | * @dev: the first device number for which this device is responsible | ||
451 | * @count: the number of consecutive minor numbers corresponding to this | ||
452 | * device | ||
453 | * | ||
454 | * cdev_add() adds the device represented by @p to the system, making it | ||
455 | * live immediately. A negative error code is returned on failure. | ||
456 | */ | ||
399 | int cdev_add(struct cdev *p, dev_t dev, unsigned count) | 457 | int cdev_add(struct cdev *p, dev_t dev, unsigned count) |
400 | { | 458 | { |
401 | p->dev = dev; | 459 | p->dev = dev; |
@@ -408,6 +466,13 @@ static void cdev_unmap(dev_t dev, unsigned count) | |||
408 | kobj_unmap(cdev_map, dev, count); | 466 | kobj_unmap(cdev_map, dev, count); |
409 | } | 467 | } |
410 | 468 | ||
469 | /** | ||
470 | * cdev_del() - remove a cdev from the system | ||
471 | * @p: the cdev structure to be removed | ||
472 | * | ||
473 | * cdev_del() removes @p from the system, possibly freeing the structure | ||
474 | * itself. | ||
475 | */ | ||
411 | void cdev_del(struct cdev *p) | 476 | void cdev_del(struct cdev *p) |
412 | { | 477 | { |
413 | cdev_unmap(p->dev, p->count); | 478 | cdev_unmap(p->dev, p->count); |
@@ -436,6 +501,11 @@ static struct kobj_type ktype_cdev_dynamic = { | |||
436 | .release = cdev_dynamic_release, | 501 | .release = cdev_dynamic_release, |
437 | }; | 502 | }; |
438 | 503 | ||
504 | /** | ||
505 | * cdev_alloc() - allocate a cdev structure | ||
506 | * | ||
507 | * Allocates and returns a cdev structure, or NULL on failure. | ||
508 | */ | ||
439 | struct cdev *cdev_alloc(void) | 509 | struct cdev *cdev_alloc(void) |
440 | { | 510 | { |
441 | struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); | 511 | struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); |
@@ -447,6 +517,14 @@ struct cdev *cdev_alloc(void) | |||
447 | return p; | 517 | return p; |
448 | } | 518 | } |
449 | 519 | ||
520 | /** | ||
521 | * cdev_init() - initialize a cdev structure | ||
522 | * @cdev: the structure to initialize | ||
523 | * @fops: the file_operations for this device | ||
524 | * | ||
525 | * Initializes @cdev, remembering @fops, making it ready to add to the | ||
526 | * system with cdev_add(). | ||
527 | */ | ||
450 | void cdev_init(struct cdev *cdev, const struct file_operations *fops) | 528 | void cdev_init(struct cdev *cdev, const struct file_operations *fops) |
451 | { | 529 | { |
452 | memset(cdev, 0, sizeof *cdev); | 530 | memset(cdev, 0, sizeof *cdev); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ddb012a68023..976a691c5a68 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/backing-dev.h> | 25 | #include <linux/backing-dev.h> |
26 | #include <linux/stat.h> | 26 | #include <linux/stat.h> |
27 | #include <linux/fcntl.h> | 27 | #include <linux/fcntl.h> |
28 | #include <linux/mpage.h> | ||
29 | #include <linux/pagemap.h> | 28 | #include <linux/pagemap.h> |
30 | #include <linux/pagevec.h> | 29 | #include <linux/pagevec.h> |
31 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b88147c1dc27..05f874c7441b 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -19,7 +19,6 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/buffer_head.h> | ||
23 | #include <linux/stat.h> | 22 | #include <linux/stat.h> |
24 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
25 | #include <asm/div64.h> | 24 | #include <asm/div64.h> |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index b0ea6687ab55..e34c7db00f6f 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -22,7 +22,6 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/ext2_fs.h> | ||
26 | #include "cifspdu.h" | 25 | #include "cifspdu.h" |
27 | #include "cifsglob.h" | 26 | #include "cifsglob.h" |
28 | #include "cifsproto.h" | 27 | #include "cifsproto.h" |
@@ -74,7 +73,7 @@ int cifs_ioctl (struct inode * inode, struct file * filep, | |||
74 | } | 73 | } |
75 | break; | 74 | break; |
76 | #ifdef CONFIG_CIFS_POSIX | 75 | #ifdef CONFIG_CIFS_POSIX |
77 | case EXT2_IOC_GETFLAGS: | 76 | case FS_IOC_GETFLAGS: |
78 | if(CIFS_UNIX_EXTATTR_CAP & caps) { | 77 | if(CIFS_UNIX_EXTATTR_CAP & caps) { |
79 | if (pSMBFile == NULL) | 78 | if (pSMBFile == NULL) |
80 | break; | 79 | break; |
@@ -82,12 +81,12 @@ int cifs_ioctl (struct inode * inode, struct file * filep, | |||
82 | &ExtAttrBits, &ExtAttrMask); | 81 | &ExtAttrBits, &ExtAttrMask); |
83 | if(rc == 0) | 82 | if(rc == 0) |
84 | rc = put_user(ExtAttrBits & | 83 | rc = put_user(ExtAttrBits & |
85 | EXT2_FL_USER_VISIBLE, | 84 | FS_FL_USER_VISIBLE, |
86 | (int __user *)arg); | 85 | (int __user *)arg); |
87 | } | 86 | } |
88 | break; | 87 | break; |
89 | 88 | ||
90 | case EXT2_IOC_SETFLAGS: | 89 | case FS_IOC_SETFLAGS: |
91 | if(CIFS_UNIX_EXTATTR_CAP & caps) { | 90 | if(CIFS_UNIX_EXTATTR_CAP & caps) { |
92 | if(get_user(ExtAttrBits,(int __user *)arg)) { | 91 | if(get_user(ExtAttrBits,(int __user *)arg)) { |
93 | rc = -EFAULT; | 92 | rc = -EFAULT; |
diff --git a/fs/compat.c b/fs/compat.c index ce982f6e8c80..122b4e3992b5 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -52,11 +52,12 @@ | |||
52 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
53 | #include <asm/mmu_context.h> | 53 | #include <asm/mmu_context.h> |
54 | #include <asm/ioctls.h> | 54 | #include <asm/ioctls.h> |
55 | 55 | #include "internal.h" | |
56 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); | ||
57 | 56 | ||
58 | int compat_log = 1; | 57 | int compat_log = 1; |
59 | 58 | ||
59 | extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); | ||
60 | |||
60 | int compat_printk(const char *fmt, ...) | 61 | int compat_printk(const char *fmt, ...) |
61 | { | 62 | { |
62 | va_list ap; | 63 | va_list ap; |
@@ -313,9 +314,6 @@ out: | |||
313 | #define IOCTL_HASHSIZE 256 | 314 | #define IOCTL_HASHSIZE 256 |
314 | static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; | 315 | static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; |
315 | 316 | ||
316 | extern struct ioctl_trans ioctl_start[]; | ||
317 | extern int ioctl_table_size; | ||
318 | |||
319 | static inline unsigned long ioctl32_hash(unsigned long cmd) | 317 | static inline unsigned long ioctl32_hash(unsigned long cmd) |
320 | { | 318 | { |
321 | return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; | 319 | return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; |
@@ -838,8 +836,6 @@ static int do_nfs4_super_data_conv(void *raw_data) | |||
838 | return 0; | 836 | return 0; |
839 | } | 837 | } |
840 | 838 | ||
841 | extern int copy_mount_options (const void __user *, unsigned long *); | ||
842 | |||
843 | #define SMBFS_NAME "smbfs" | 839 | #define SMBFS_NAME "smbfs" |
844 | #define NCPFS_NAME "ncpfs" | 840 | #define NCPFS_NAME "ncpfs" |
845 | #define NFS4_NAME "nfs4" | 841 | #define NFS4_NAME "nfs4" |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 4063a9396977..64b34533edea 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -40,15 +40,11 @@ | |||
40 | #include <linux/if_pppox.h> | 40 | #include <linux/if_pppox.h> |
41 | #include <linux/mtio.h> | 41 | #include <linux/mtio.h> |
42 | #include <linux/cdrom.h> | 42 | #include <linux/cdrom.h> |
43 | #include <linux/loop.h> | ||
44 | #include <linux/auto_fs.h> | 43 | #include <linux/auto_fs.h> |
45 | #include <linux/auto_fs4.h> | 44 | #include <linux/auto_fs4.h> |
46 | #include <linux/tty.h> | 45 | #include <linux/tty.h> |
47 | #include <linux/vt_kern.h> | 46 | #include <linux/vt_kern.h> |
48 | #include <linux/fb.h> | 47 | #include <linux/fb.h> |
49 | #include <linux/ext2_fs.h> | ||
50 | #include <linux/ext3_jbd.h> | ||
51 | #include <linux/ext3_fs.h> | ||
52 | #include <linux/videodev.h> | 48 | #include <linux/videodev.h> |
53 | #include <linux/netdevice.h> | 49 | #include <linux/netdevice.h> |
54 | #include <linux/raw.h> | 50 | #include <linux/raw.h> |
@@ -60,7 +56,6 @@ | |||
60 | #include <linux/pci.h> | 56 | #include <linux/pci.h> |
61 | #include <linux/module.h> | 57 | #include <linux/module.h> |
62 | #include <linux/serial.h> | 58 | #include <linux/serial.h> |
63 | #include <linux/reiserfs_fs.h> | ||
64 | #include <linux/if_tun.h> | 59 | #include <linux/if_tun.h> |
65 | #include <linux/ctype.h> | 60 | #include <linux/ctype.h> |
66 | #include <linux/ioctl32.h> | 61 | #include <linux/ioctl32.h> |
@@ -113,7 +108,6 @@ | |||
113 | #include <linux/nbd.h> | 108 | #include <linux/nbd.h> |
114 | #include <linux/random.h> | 109 | #include <linux/random.h> |
115 | #include <linux/filter.h> | 110 | #include <linux/filter.h> |
116 | #include <linux/msdos_fs.h> | ||
117 | #include <linux/pktcdvd.h> | 111 | #include <linux/pktcdvd.h> |
118 | 112 | ||
119 | #include <linux/hiddev.h> | 113 | #include <linux/hiddev.h> |
@@ -124,21 +118,6 @@ | |||
124 | #include <linux/dvb/video.h> | 118 | #include <linux/dvb/video.h> |
125 | #include <linux/lp.h> | 119 | #include <linux/lp.h> |
126 | 120 | ||
127 | /* Aiee. Someone does not find a difference between int and long */ | ||
128 | #define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) | ||
129 | #define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) | ||
130 | #define EXT3_IOC32_GETVERSION _IOR('f', 3, int) | ||
131 | #define EXT3_IOC32_SETVERSION _IOW('f', 4, int) | ||
132 | #define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) | ||
133 | #define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) | ||
134 | #define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) | ||
135 | #ifdef CONFIG_JBD_DEBUG | ||
136 | #define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) | ||
137 | #endif | ||
138 | |||
139 | #define EXT2_IOC32_GETVERSION _IOR('v', 1, int) | ||
140 | #define EXT2_IOC32_SETVERSION _IOW('v', 2, int) | ||
141 | |||
142 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, | 121 | static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, |
143 | unsigned long arg, struct file *f) | 122 | unsigned long arg, struct file *f) |
144 | { | 123 | { |
@@ -176,34 +155,6 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
176 | return err; | 155 | return err; |
177 | } | 156 | } |
178 | 157 | ||
179 | static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
180 | { | ||
181 | /* These are just misnamed, they actually get/put from/to user an int */ | ||
182 | switch (cmd) { | ||
183 | case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break; | ||
184 | case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break; | ||
185 | case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; | ||
186 | case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; | ||
187 | } | ||
188 | return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); | ||
189 | } | ||
190 | |||
191 | static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
192 | { | ||
193 | /* These are just misnamed, they actually get/put from/to user an int */ | ||
194 | switch (cmd) { | ||
195 | case EXT3_IOC32_GETVERSION: cmd = EXT3_IOC_GETVERSION; break; | ||
196 | case EXT3_IOC32_SETVERSION: cmd = EXT3_IOC_SETVERSION; break; | ||
197 | case EXT3_IOC32_GETRSVSZ: cmd = EXT3_IOC_GETRSVSZ; break; | ||
198 | case EXT3_IOC32_SETRSVSZ: cmd = EXT3_IOC_SETRSVSZ; break; | ||
199 | case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break; | ||
200 | #ifdef CONFIG_JBD_DEBUG | ||
201 | case EXT3_IOC32_WAIT_FOR_READONLY: cmd = EXT3_IOC_WAIT_FOR_READONLY; break; | ||
202 | #endif | ||
203 | } | ||
204 | return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); | ||
205 | } | ||
206 | |||
207 | struct compat_video_event { | 158 | struct compat_video_event { |
208 | int32_t type; | 159 | int32_t type; |
209 | compat_time_t timestamp; | 160 | compat_time_t timestamp; |
@@ -694,6 +645,7 @@ out: | |||
694 | } | 645 | } |
695 | #endif | 646 | #endif |
696 | 647 | ||
648 | #ifdef CONFIG_BLOCK | ||
697 | struct hd_geometry32 { | 649 | struct hd_geometry32 { |
698 | unsigned char heads; | 650 | unsigned char heads; |
699 | unsigned char sectors; | 651 | unsigned char sectors; |
@@ -918,6 +870,7 @@ static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
918 | } | 870 | } |
919 | return err; | 871 | return err; |
920 | } | 872 | } |
873 | #endif /* CONFIG_BLOCK */ | ||
921 | 874 | ||
922 | struct sock_fprog32 { | 875 | struct sock_fprog32 { |
923 | unsigned short len; | 876 | unsigned short len; |
@@ -1041,6 +994,7 @@ static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
1041 | } | 994 | } |
1042 | 995 | ||
1043 | 996 | ||
997 | #ifdef CONFIG_BLOCK | ||
1044 | struct mtget32 { | 998 | struct mtget32 { |
1045 | compat_long_t mt_type; | 999 | compat_long_t mt_type; |
1046 | compat_long_t mt_resid; | 1000 | compat_long_t mt_resid; |
@@ -1213,73 +1167,7 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar | |||
1213 | 1167 | ||
1214 | return err; | 1168 | return err; |
1215 | } | 1169 | } |
1216 | 1170 | #endif /* CONFIG_BLOCK */ | |
1217 | struct loop_info32 { | ||
1218 | compat_int_t lo_number; /* ioctl r/o */ | ||
1219 | compat_dev_t lo_device; /* ioctl r/o */ | ||
1220 | compat_ulong_t lo_inode; /* ioctl r/o */ | ||
1221 | compat_dev_t lo_rdevice; /* ioctl r/o */ | ||
1222 | compat_int_t lo_offset; | ||
1223 | compat_int_t lo_encrypt_type; | ||
1224 | compat_int_t lo_encrypt_key_size; /* ioctl w/o */ | ||
1225 | compat_int_t lo_flags; /* ioctl r/o */ | ||
1226 | char lo_name[LO_NAME_SIZE]; | ||
1227 | unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ | ||
1228 | compat_ulong_t lo_init[2]; | ||
1229 | char reserved[4]; | ||
1230 | }; | ||
1231 | |||
1232 | static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
1233 | { | ||
1234 | mm_segment_t old_fs = get_fs(); | ||
1235 | struct loop_info l; | ||
1236 | struct loop_info32 __user *ul; | ||
1237 | int err = -EINVAL; | ||
1238 | |||
1239 | ul = compat_ptr(arg); | ||
1240 | switch(cmd) { | ||
1241 | case LOOP_SET_STATUS: | ||
1242 | err = get_user(l.lo_number, &ul->lo_number); | ||
1243 | err |= __get_user(l.lo_device, &ul->lo_device); | ||
1244 | err |= __get_user(l.lo_inode, &ul->lo_inode); | ||
1245 | err |= __get_user(l.lo_rdevice, &ul->lo_rdevice); | ||
1246 | err |= __copy_from_user(&l.lo_offset, &ul->lo_offset, | ||
1247 | 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); | ||
1248 | if (err) { | ||
1249 | err = -EFAULT; | ||
1250 | } else { | ||
1251 | set_fs (KERNEL_DS); | ||
1252 | err = sys_ioctl (fd, cmd, (unsigned long)&l); | ||
1253 | set_fs (old_fs); | ||
1254 | } | ||
1255 | break; | ||
1256 | case LOOP_GET_STATUS: | ||
1257 | set_fs (KERNEL_DS); | ||
1258 | err = sys_ioctl (fd, cmd, (unsigned long)&l); | ||
1259 | set_fs (old_fs); | ||
1260 | if (!err) { | ||
1261 | err = put_user(l.lo_number, &ul->lo_number); | ||
1262 | err |= __put_user(l.lo_device, &ul->lo_device); | ||
1263 | err |= __put_user(l.lo_inode, &ul->lo_inode); | ||
1264 | err |= __put_user(l.lo_rdevice, &ul->lo_rdevice); | ||
1265 | err |= __copy_to_user(&ul->lo_offset, &l.lo_offset, | ||
1266 | (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); | ||
1267 | if (err) | ||
1268 | err = -EFAULT; | ||
1269 | } | ||
1270 | break; | ||
1271 | default: { | ||
1272 | static int count; | ||
1273 | if (++count <= 20) | ||
1274 | printk("%s: Unknown loop ioctl cmd, fd(%d) " | ||
1275 | "cmd(%08x) arg(%08lx)\n", | ||
1276 | __FUNCTION__, fd, cmd, arg); | ||
1277 | } | ||
1278 | } | ||
1279 | return err; | ||
1280 | } | ||
1281 | |||
1282 | extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); | ||
1283 | 1171 | ||
1284 | #ifdef CONFIG_VT | 1172 | #ifdef CONFIG_VT |
1285 | 1173 | ||
@@ -1607,6 +1495,7 @@ ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
1607 | return -EINVAL; | 1495 | return -EINVAL; |
1608 | } | 1496 | } |
1609 | 1497 | ||
1498 | #ifdef CONFIG_BLOCK | ||
1610 | static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg) | 1499 | static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg) |
1611 | { | 1500 | { |
1612 | /* The mkswap binary hard codes it to Intel value :-((( */ | 1501 | /* The mkswap binary hard codes it to Intel value :-((( */ |
@@ -1641,12 +1530,14 @@ static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar | |||
1641 | 1530 | ||
1642 | return sys_ioctl(fd, cmd, (unsigned long)a); | 1531 | return sys_ioctl(fd, cmd, (unsigned long)a); |
1643 | } | 1532 | } |
1533 | #endif | ||
1644 | 1534 | ||
1645 | static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) | 1535 | static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) |
1646 | { | 1536 | { |
1647 | return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); | 1537 | return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); |
1648 | } | 1538 | } |
1649 | 1539 | ||
1540 | #ifdef CONFIG_BLOCK | ||
1650 | /* Fix sizeof(sizeof()) breakage */ | 1541 | /* Fix sizeof(sizeof()) breakage */ |
1651 | #define BLKBSZGET_32 _IOR(0x12,112,int) | 1542 | #define BLKBSZGET_32 _IOR(0x12,112,int) |
1652 | #define BLKBSZSET_32 _IOW(0x12,113,int) | 1543 | #define BLKBSZSET_32 _IOW(0x12,113,int) |
@@ -1667,6 +1558,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd, | |||
1667 | { | 1558 | { |
1668 | return sys_ioctl(fd, BLKGETSIZE64, (unsigned long)compat_ptr(arg)); | 1559 | return sys_ioctl(fd, BLKGETSIZE64, (unsigned long)compat_ptr(arg)); |
1669 | } | 1560 | } |
1561 | #endif | ||
1670 | 1562 | ||
1671 | /* Bluetooth ioctls */ | 1563 | /* Bluetooth ioctls */ |
1672 | #define HCIUARTSETPROTO _IOW('U', 200, int) | 1564 | #define HCIUARTSETPROTO _IOW('U', 200, int) |
@@ -1687,6 +1579,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd, | |||
1687 | #define HIDPGETCONNLIST _IOR('H', 210, int) | 1579 | #define HIDPGETCONNLIST _IOR('H', 210, int) |
1688 | #define HIDPGETCONNINFO _IOR('H', 211, int) | 1580 | #define HIDPGETCONNINFO _IOR('H', 211, int) |
1689 | 1581 | ||
1582 | #ifdef CONFIG_BLOCK | ||
1690 | struct floppy_struct32 { | 1583 | struct floppy_struct32 { |
1691 | compat_uint_t size; | 1584 | compat_uint_t size; |
1692 | compat_uint_t sect; | 1585 | compat_uint_t sect; |
@@ -2011,6 +1904,7 @@ out: | |||
2011 | kfree(karg); | 1904 | kfree(karg); |
2012 | return err; | 1905 | return err; |
2013 | } | 1906 | } |
1907 | #endif | ||
2014 | 1908 | ||
2015 | struct mtd_oob_buf32 { | 1909 | struct mtd_oob_buf32 { |
2016 | u_int32_t start; | 1910 | u_int32_t start; |
@@ -2052,61 +1946,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
2052 | return err; | 1946 | return err; |
2053 | } | 1947 | } |
2054 | 1948 | ||
2055 | #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) | 1949 | #ifdef CONFIG_BLOCK |
2056 | #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) | ||
2057 | |||
2058 | static long | ||
2059 | put_dirent32 (struct dirent *d, struct compat_dirent __user *d32) | ||
2060 | { | ||
2061 | if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) | ||
2062 | return -EFAULT; | ||
2063 | |||
2064 | __put_user(d->d_ino, &d32->d_ino); | ||
2065 | __put_user(d->d_off, &d32->d_off); | ||
2066 | __put_user(d->d_reclen, &d32->d_reclen); | ||
2067 | if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) | ||
2068 | return -EFAULT; | ||
2069 | |||
2070 | return 0; | ||
2071 | } | ||
2072 | |||
2073 | static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg) | ||
2074 | { | ||
2075 | struct compat_dirent __user *p = compat_ptr(arg); | ||
2076 | int ret; | ||
2077 | mm_segment_t oldfs = get_fs(); | ||
2078 | struct dirent d[2]; | ||
2079 | |||
2080 | switch(cmd) | ||
2081 | { | ||
2082 | case VFAT_IOCTL_READDIR_BOTH32: | ||
2083 | cmd = VFAT_IOCTL_READDIR_BOTH; | ||
2084 | break; | ||
2085 | case VFAT_IOCTL_READDIR_SHORT32: | ||
2086 | cmd = VFAT_IOCTL_READDIR_SHORT; | ||
2087 | break; | ||
2088 | } | ||
2089 | |||
2090 | set_fs(KERNEL_DS); | ||
2091 | ret = sys_ioctl(fd,cmd,(unsigned long)&d); | ||
2092 | set_fs(oldfs); | ||
2093 | if (ret >= 0) { | ||
2094 | ret |= put_dirent32(&d[0], p); | ||
2095 | ret |= put_dirent32(&d[1], p + 1); | ||
2096 | } | ||
2097 | return ret; | ||
2098 | } | ||
2099 | |||
2100 | #define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int) | ||
2101 | |||
2102 | static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr) | ||
2103 | { | ||
2104 | if (cmd == REISERFS_IOC_UNPACK32) | ||
2105 | cmd = REISERFS_IOC_UNPACK; | ||
2106 | |||
2107 | return sys_ioctl(fd,cmd,ptr); | ||
2108 | } | ||
2109 | |||
2110 | struct raw32_config_request | 1950 | struct raw32_config_request |
2111 | { | 1951 | { |
2112 | compat_int_t raw_minor; | 1952 | compat_int_t raw_minor; |
@@ -2171,6 +2011,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
2171 | } | 2011 | } |
2172 | return ret; | 2012 | return ret; |
2173 | } | 2013 | } |
2014 | #endif /* CONFIG_BLOCK */ | ||
2174 | 2015 | ||
2175 | struct serial_struct32 { | 2016 | struct serial_struct32 { |
2176 | compat_int_t type; | 2017 | compat_int_t type; |
@@ -2777,6 +2618,7 @@ HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc) | |||
2777 | HANDLE_IOCTL(SIOCRTMSG, ret_einval) | 2618 | HANDLE_IOCTL(SIOCRTMSG, ret_einval) |
2778 | HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) | 2619 | HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) |
2779 | #endif | 2620 | #endif |
2621 | #ifdef CONFIG_BLOCK | ||
2780 | HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo) | 2622 | HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo) |
2781 | HANDLE_IOCTL(BLKRAGET, w_long) | 2623 | HANDLE_IOCTL(BLKRAGET, w_long) |
2782 | HANDLE_IOCTL(BLKGETSIZE, w_long) | 2624 | HANDLE_IOCTL(BLKGETSIZE, w_long) |
@@ -2802,16 +2644,17 @@ HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans) | |||
2802 | HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans) | 2644 | HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans) |
2803 | HANDLE_IOCTL(SG_IO,sg_ioctl_trans) | 2645 | HANDLE_IOCTL(SG_IO,sg_ioctl_trans) |
2804 | HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans) | 2646 | HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans) |
2647 | #endif | ||
2805 | HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) | 2648 | HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) |
2806 | HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) | 2649 | HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) |
2807 | HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) | 2650 | HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) |
2808 | HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans) | 2651 | HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans) |
2652 | #ifdef CONFIG_BLOCK | ||
2809 | HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) | 2653 | HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) |
2810 | HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) | 2654 | HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) |
2811 | HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans) | 2655 | HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans) |
2812 | HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans) | 2656 | HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans) |
2813 | HANDLE_IOCTL(LOOP_SET_STATUS, loop_status) | 2657 | #endif |
2814 | HANDLE_IOCTL(LOOP_GET_STATUS, loop_status) | ||
2815 | #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) | 2658 | #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) |
2816 | HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) | 2659 | HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) |
2817 | #ifdef CONFIG_VT | 2660 | #ifdef CONFIG_VT |
@@ -2821,19 +2664,6 @@ HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl) | |||
2821 | HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl) | 2664 | HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl) |
2822 | HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl) | 2665 | HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl) |
2823 | #endif | 2666 | #endif |
2824 | HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) | ||
2825 | HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) | ||
2826 | HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) | ||
2827 | HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl) | ||
2828 | HANDLE_IOCTL(EXT3_IOC32_GETVERSION, do_ext3_ioctl) | ||
2829 | HANDLE_IOCTL(EXT3_IOC32_SETVERSION, do_ext3_ioctl) | ||
2830 | HANDLE_IOCTL(EXT3_IOC32_GETRSVSZ, do_ext3_ioctl) | ||
2831 | HANDLE_IOCTL(EXT3_IOC32_SETRSVSZ, do_ext3_ioctl) | ||
2832 | HANDLE_IOCTL(EXT3_IOC32_GROUP_EXTEND, do_ext3_ioctl) | ||
2833 | COMPATIBLE_IOCTL(EXT3_IOC_GROUP_ADD) | ||
2834 | #ifdef CONFIG_JBD_DEBUG | ||
2835 | HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl) | ||
2836 | #endif | ||
2837 | /* One SMB ioctl needs translations. */ | 2667 | /* One SMB ioctl needs translations. */ |
2838 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) | 2668 | #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) |
2839 | HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) | 2669 | HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) |
@@ -2863,16 +2693,14 @@ HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl) | |||
2863 | HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) | 2693 | HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) |
2864 | HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) | 2694 | HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) |
2865 | /* block stuff */ | 2695 | /* block stuff */ |
2696 | #ifdef CONFIG_BLOCK | ||
2866 | HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget) | 2697 | HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget) |
2867 | HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset) | 2698 | HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset) |
2868 | HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64) | 2699 | HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64) |
2869 | /* vfat */ | ||
2870 | HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32) | ||
2871 | HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32) | ||
2872 | HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32) | ||
2873 | /* Raw devices */ | 2700 | /* Raw devices */ |
2874 | HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) | 2701 | HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) |
2875 | HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) | 2702 | HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) |
2703 | #endif | ||
2876 | /* Serial */ | 2704 | /* Serial */ |
2877 | HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl) | 2705 | HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl) |
2878 | HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) | 2706 | HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index ad96b6990715..a624c3ec8189 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -543,8 +543,15 @@ static struct file_system_type cramfs_fs_type = { | |||
543 | 543 | ||
544 | static int __init init_cramfs_fs(void) | 544 | static int __init init_cramfs_fs(void) |
545 | { | 545 | { |
546 | cramfs_uncompress_init(); | 546 | int rv; |
547 | return register_filesystem(&cramfs_fs_type); | 547 | |
548 | rv = cramfs_uncompress_init(); | ||
549 | if (rv < 0) | ||
550 | return rv; | ||
551 | rv = register_filesystem(&cramfs_fs_type); | ||
552 | if (rv < 0) | ||
553 | cramfs_uncompress_exit(); | ||
554 | return rv; | ||
548 | } | 555 | } |
549 | 556 | ||
550 | static void __exit exit_cramfs_fs(void) | 557 | static void __exit exit_cramfs_fs(void) |
diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index 8def89f2c438..fc3ccb74626f 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c | |||
@@ -68,11 +68,10 @@ int cramfs_uncompress_init(void) | |||
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | int cramfs_uncompress_exit(void) | 71 | void cramfs_uncompress_exit(void) |
72 | { | 72 | { |
73 | if (!--initialized) { | 73 | if (!--initialized) { |
74 | zlib_inflateEnd(&stream); | 74 | zlib_inflateEnd(&stream); |
75 | vfree(stream.workspace); | 75 | vfree(stream.workspace); |
76 | } | 76 | } |
77 | return 0; | ||
78 | } | 77 | } |
diff --git a/fs/dcache.c b/fs/dcache.c index 17b392a2049e..fc2faa44f8d1 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/seqlock.h> | 32 | #include <linux/seqlock.h> |
33 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
34 | #include <linux/bootmem.h> | 34 | #include <linux/bootmem.h> |
35 | #include "internal.h" | ||
35 | 36 | ||
36 | 37 | ||
37 | int sysctl_vfs_cache_pressure __read_mostly = 100; | 38 | int sysctl_vfs_cache_pressure __read_mostly = 100; |
@@ -1877,9 +1878,6 @@ kmem_cache_t *filp_cachep __read_mostly; | |||
1877 | 1878 | ||
1878 | EXPORT_SYMBOL(d_genocide); | 1879 | EXPORT_SYMBOL(d_genocide); |
1879 | 1880 | ||
1880 | extern void bdev_cache_init(void); | ||
1881 | extern void chrdev_init(void); | ||
1882 | |||
1883 | void __init vfs_caches_init_early(void) | 1881 | void __init vfs_caches_init_early(void) |
1884 | { | 1882 | { |
1885 | dcache_init_early(); | 1883 | dcache_init_early(); |
diff --git a/fs/dquot.c b/fs/dquot.c index 0122a279106a..9af789567e51 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -834,6 +834,9 @@ static void print_warning(struct dquot *dquot, const char warntype) | |||
834 | if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags))) | 834 | if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags))) |
835 | return; | 835 | return; |
836 | 836 | ||
837 | mutex_lock(&tty_mutex); | ||
838 | if (!current->signal->tty) | ||
839 | goto out_lock; | ||
837 | tty_write_message(current->signal->tty, dquot->dq_sb->s_id); | 840 | tty_write_message(current->signal->tty, dquot->dq_sb->s_id); |
838 | if (warntype == ISOFTWARN || warntype == BSOFTWARN) | 841 | if (warntype == ISOFTWARN || warntype == BSOFTWARN) |
839 | tty_write_message(current->signal->tty, ": warning, "); | 842 | tty_write_message(current->signal->tty, ": warning, "); |
@@ -861,6 +864,8 @@ static void print_warning(struct dquot *dquot, const char warntype) | |||
861 | break; | 864 | break; |
862 | } | 865 | } |
863 | tty_write_message(current->signal->tty, msg); | 866 | tty_write_message(current->signal->tty, msg); |
867 | out_lock: | ||
868 | mutex_unlock(&tty_mutex); | ||
864 | } | 869 | } |
865 | 870 | ||
866 | static inline void flush_warnings(struct dquot **dquots, char *warntype) | 871 | static inline void flush_warnings(struct dquot **dquots, char *warntype) |
@@ -898,8 +898,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
898 | return 0; | 898 | return 0; |
899 | 899 | ||
900 | mmap_failed: | 900 | mmap_failed: |
901 | put_files_struct(current->files); | 901 | reset_files_struct(current, files); |
902 | current->files = files; | ||
903 | out: | 902 | out: |
904 | return retval; | 903 | return retval; |
905 | } | 904 | } |
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 92ea8265d7d5..3e7a84a1e509 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -661,5 +661,8 @@ const struct file_operations ext2_dir_operations = { | |||
661 | .read = generic_read_dir, | 661 | .read = generic_read_dir, |
662 | .readdir = ext2_readdir, | 662 | .readdir = ext2_readdir, |
663 | .ioctl = ext2_ioctl, | 663 | .ioctl = ext2_ioctl, |
664 | #ifdef CONFIG_COMPAT | ||
665 | .compat_ioctl = ext2_compat_ioctl, | ||
666 | #endif | ||
664 | .fsync = ext2_sync_file, | 667 | .fsync = ext2_sync_file, |
665 | }; | 668 | }; |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index e65a019fc7a5..c19ac153f56b 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -137,6 +137,7 @@ extern void ext2_set_inode_flags(struct inode *inode); | |||
137 | /* ioctl.c */ | 137 | /* ioctl.c */ |
138 | extern int ext2_ioctl (struct inode *, struct file *, unsigned int, | 138 | extern int ext2_ioctl (struct inode *, struct file *, unsigned int, |
139 | unsigned long); | 139 | unsigned long); |
140 | extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); | ||
140 | 141 | ||
141 | /* namei.c */ | 142 | /* namei.c */ |
142 | struct dentry *ext2_get_parent(struct dentry *child); | 143 | struct dentry *ext2_get_parent(struct dentry *child); |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 23e2c7ccec1d..e8bbed9dd268 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -46,6 +46,9 @@ const struct file_operations ext2_file_operations = { | |||
46 | .aio_read = generic_file_aio_read, | 46 | .aio_read = generic_file_aio_read, |
47 | .aio_write = generic_file_aio_write, | 47 | .aio_write = generic_file_aio_write, |
48 | .ioctl = ext2_ioctl, | 48 | .ioctl = ext2_ioctl, |
49 | #ifdef CONFIG_COMPAT | ||
50 | .compat_ioctl = ext2_compat_ioctl, | ||
51 | #endif | ||
49 | .mmap = generic_file_mmap, | 52 | .mmap = generic_file_mmap, |
50 | .open = generic_file_open, | 53 | .open = generic_file_open, |
51 | .release = ext2_release_file, | 54 | .release = ext2_release_file, |
@@ -63,6 +66,9 @@ const struct file_operations ext2_xip_file_operations = { | |||
63 | .read = xip_file_read, | 66 | .read = xip_file_read, |
64 | .write = xip_file_write, | 67 | .write = xip_file_write, |
65 | .ioctl = ext2_ioctl, | 68 | .ioctl = ext2_ioctl, |
69 | #ifdef CONFIG_COMPAT | ||
70 | .compat_ioctl = ext2_compat_ioctl, | ||
71 | #endif | ||
66 | .mmap = xip_file_mmap, | 72 | .mmap = xip_file_mmap, |
67 | .open = generic_file_open, | 73 | .open = generic_file_open, |
68 | .release = ext2_release_file, | 74 | .release = ext2_release_file, |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 3ca9afdf713d..1dfba77eab10 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/capability.h> | 11 | #include <linux/capability.h> |
12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/compat.h> | ||
15 | #include <linux/smp_lock.h> | ||
14 | #include <asm/current.h> | 16 | #include <asm/current.h> |
15 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
16 | 18 | ||
@@ -80,3 +82,33 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
80 | return -ENOTTY; | 82 | return -ENOTTY; |
81 | } | 83 | } |
82 | } | 84 | } |
85 | |||
86 | #ifdef CONFIG_COMPAT | ||
87 | long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
88 | { | ||
89 | struct inode *inode = file->f_dentry->d_inode; | ||
90 | int ret; | ||
91 | |||
92 | /* These are just misnamed, they actually get/put from/to user an int */ | ||
93 | switch (cmd) { | ||
94 | case EXT2_IOC32_GETFLAGS: | ||
95 | cmd = EXT2_IOC_GETFLAGS; | ||
96 | break; | ||
97 | case EXT2_IOC32_SETFLAGS: | ||
98 | cmd = EXT2_IOC_SETFLAGS; | ||
99 | break; | ||
100 | case EXT2_IOC32_GETVERSION: | ||
101 | cmd = EXT2_IOC_GETVERSION; | ||
102 | break; | ||
103 | case EXT2_IOC32_SETVERSION: | ||
104 | cmd = EXT2_IOC_SETVERSION; | ||
105 | break; | ||
106 | default: | ||
107 | return -ENOIOCTLCMD; | ||
108 | } | ||
109 | lock_kernel(); | ||
110 | ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | ||
111 | unlock_kernel(); | ||
112 | return ret; | ||
113 | } | ||
114 | #endif | ||
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 429acbb4e064..d0b54f30b914 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -44,6 +44,9 @@ const struct file_operations ext3_dir_operations = { | |||
44 | .read = generic_read_dir, | 44 | .read = generic_read_dir, |
45 | .readdir = ext3_readdir, /* we take BKL. needed?*/ | 45 | .readdir = ext3_readdir, /* we take BKL. needed?*/ |
46 | .ioctl = ext3_ioctl, /* BKL held */ | 46 | .ioctl = ext3_ioctl, /* BKL held */ |
47 | #ifdef CONFIG_COMPAT | ||
48 | .compat_ioctl = ext3_compat_ioctl, | ||
49 | #endif | ||
47 | .fsync = ext3_sync_file, /* BKL held */ | 50 | .fsync = ext3_sync_file, /* BKL held */ |
48 | #ifdef CONFIG_EXT3_INDEX | 51 | #ifdef CONFIG_EXT3_INDEX |
49 | .release = ext3_release_dir, | 52 | .release = ext3_release_dir, |
diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 994efd189f4e..74ff20f9d09b 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c | |||
@@ -114,6 +114,9 @@ const struct file_operations ext3_file_operations = { | |||
114 | .readv = generic_file_readv, | 114 | .readv = generic_file_readv, |
115 | .writev = generic_file_writev, | 115 | .writev = generic_file_writev, |
116 | .ioctl = ext3_ioctl, | 116 | .ioctl = ext3_ioctl, |
117 | #ifdef CONFIG_COMPAT | ||
118 | .compat_ioctl = ext3_compat_ioctl, | ||
119 | #endif | ||
117 | .mmap = generic_file_mmap, | 120 | .mmap = generic_file_mmap, |
118 | .open = generic_file_open, | 121 | .open = generic_file_open, |
119 | .release = ext3_release_file, | 122 | .release = ext3_release_file, |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index dcf4f1dd108b..03ba5bcab186 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/writeback.h> | 36 | #include <linux/writeback.h> |
37 | #include <linux/mpage.h> | 37 | #include <linux/mpage.h> |
38 | #include <linux/uio.h> | 38 | #include <linux/uio.h> |
39 | #include <linux/bio.h> | ||
39 | #include "xattr.h" | 40 | #include "xattr.h" |
40 | #include "acl.h" | 41 | #include "acl.h" |
41 | 42 | ||
@@ -1073,7 +1074,7 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode *inode, | |||
1073 | return bh; | 1074 | return bh; |
1074 | if (buffer_uptodate(bh)) | 1075 | if (buffer_uptodate(bh)) |
1075 | return bh; | 1076 | return bh; |
1076 | ll_rw_block(READ, 1, &bh); | 1077 | ll_rw_block(READ_META, 1, &bh); |
1077 | wait_on_buffer(bh); | 1078 | wait_on_buffer(bh); |
1078 | if (buffer_uptodate(bh)) | 1079 | if (buffer_uptodate(bh)) |
1079 | return bh; | 1080 | return bh; |
@@ -2540,7 +2541,7 @@ make_io: | |||
2540 | */ | 2541 | */ |
2541 | get_bh(bh); | 2542 | get_bh(bh); |
2542 | bh->b_end_io = end_buffer_read_sync; | 2543 | bh->b_end_io = end_buffer_read_sync; |
2543 | submit_bh(READ, bh); | 2544 | submit_bh(READ_META, bh); |
2544 | wait_on_buffer(bh); | 2545 | wait_on_buffer(bh); |
2545 | if (!buffer_uptodate(bh)) { | 2546 | if (!buffer_uptodate(bh)) { |
2546 | ext3_error(inode->i_sb, "ext3_get_inode_loc", | 2547 | ext3_error(inode->i_sb, "ext3_get_inode_loc", |
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 3a6b012d120c..12daa6869572 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -13,9 +13,10 @@ | |||
13 | #include <linux/ext3_fs.h> | 13 | #include <linux/ext3_fs.h> |
14 | #include <linux/ext3_jbd.h> | 14 | #include <linux/ext3_jbd.h> |
15 | #include <linux/time.h> | 15 | #include <linux/time.h> |
16 | #include <linux/compat.h> | ||
17 | #include <linux/smp_lock.h> | ||
16 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
17 | 19 | ||
18 | |||
19 | int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | 20 | int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, |
20 | unsigned long arg) | 21 | unsigned long arg) |
21 | { | 22 | { |
@@ -252,3 +253,55 @@ flags_err: | |||
252 | return -ENOTTY; | 253 | return -ENOTTY; |
253 | } | 254 | } |
254 | } | 255 | } |
256 | |||
257 | #ifdef CONFIG_COMPAT | ||
258 | long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
259 | { | ||
260 | struct inode *inode = file->f_dentry->d_inode; | ||
261 | int ret; | ||
262 | |||
263 | /* These are just misnamed, they actually get/put from/to user an int */ | ||
264 | switch (cmd) { | ||
265 | case EXT3_IOC32_GETFLAGS: | ||
266 | cmd = EXT3_IOC_GETFLAGS; | ||
267 | break; | ||
268 | case EXT3_IOC32_SETFLAGS: | ||
269 | cmd = EXT3_IOC_SETFLAGS; | ||
270 | break; | ||
271 | case EXT3_IOC32_GETVERSION: | ||
272 | cmd = EXT3_IOC_GETVERSION; | ||
273 | break; | ||
274 | case EXT3_IOC32_SETVERSION: | ||
275 | cmd = EXT3_IOC_SETVERSION; | ||
276 | break; | ||
277 | case EXT3_IOC32_GROUP_EXTEND: | ||
278 | cmd = EXT3_IOC_GROUP_EXTEND; | ||
279 | break; | ||
280 | case EXT3_IOC32_GETVERSION_OLD: | ||
281 | cmd = EXT3_IOC_GETVERSION_OLD; | ||
282 | break; | ||
283 | case EXT3_IOC32_SETVERSION_OLD: | ||
284 | cmd = EXT3_IOC_SETVERSION_OLD; | ||
285 | break; | ||
286 | #ifdef CONFIG_JBD_DEBUG | ||
287 | case EXT3_IOC32_WAIT_FOR_READONLY: | ||
288 | cmd = EXT3_IOC_WAIT_FOR_READONLY; | ||
289 | break; | ||
290 | #endif | ||
291 | case EXT3_IOC32_GETRSVSZ: | ||
292 | cmd = EXT3_IOC_GETRSVSZ; | ||
293 | break; | ||
294 | case EXT3_IOC32_SETRSVSZ: | ||
295 | cmd = EXT3_IOC_SETRSVSZ; | ||
296 | break; | ||
297 | case EXT3_IOC_GROUP_ADD: | ||
298 | break; | ||
299 | default: | ||
300 | return -ENOIOCTLCMD; | ||
301 | } | ||
302 | lock_kernel(); | ||
303 | ret = ext3_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | ||
304 | unlock_kernel(); | ||
305 | return ret; | ||
306 | } | ||
307 | #endif | ||
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 85d132c37ee0..235e77b52ea5 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/quotaops.h> | 36 | #include <linux/quotaops.h> |
37 | #include <linux/buffer_head.h> | 37 | #include <linux/buffer_head.h> |
38 | #include <linux/bio.h> | ||
38 | #include <linux/smp_lock.h> | 39 | #include <linux/smp_lock.h> |
39 | 40 | ||
40 | #include "namei.h" | 41 | #include "namei.h" |
@@ -870,7 +871,7 @@ restart: | |||
870 | bh = ext3_getblk(NULL, dir, b++, 0, &err); | 871 | bh = ext3_getblk(NULL, dir, b++, 0, &err); |
871 | bh_use[ra_max] = bh; | 872 | bh_use[ra_max] = bh; |
872 | if (bh) | 873 | if (bh) |
873 | ll_rw_block(READ, 1, &bh); | 874 | ll_rw_block(READ_META, 1, &bh); |
874 | } | 875 | } |
875 | } | 876 | } |
876 | if ((bh = bh_use[ra_ptr++]) == NULL) | 877 | if ((bh = bh_use[ra_ptr++]) == NULL) |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 698b85bb1dd4..3e50a4166283 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/dirent.h> | 20 | #include <linux/dirent.h> |
21 | #include <linux/smp_lock.h> | 21 | #include <linux/smp_lock.h> |
22 | #include <linux/buffer_head.h> | 22 | #include <linux/buffer_head.h> |
23 | #include <linux/compat.h> | ||
23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
24 | 25 | ||
25 | static inline loff_t fat_make_i_pos(struct super_block *sb, | 26 | static inline loff_t fat_make_i_pos(struct super_block *sb, |
@@ -741,10 +742,65 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, | |||
741 | return ret; | 742 | return ret; |
742 | } | 743 | } |
743 | 744 | ||
745 | #ifdef CONFIG_COMPAT | ||
746 | #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) | ||
747 | #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) | ||
748 | |||
749 | static long fat_compat_put_dirent32(struct dirent *d, | ||
750 | struct compat_dirent __user *d32) | ||
751 | { | ||
752 | if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) | ||
753 | return -EFAULT; | ||
754 | |||
755 | __put_user(d->d_ino, &d32->d_ino); | ||
756 | __put_user(d->d_off, &d32->d_off); | ||
757 | __put_user(d->d_reclen, &d32->d_reclen); | ||
758 | if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) | ||
759 | return -EFAULT; | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static long fat_compat_dir_ioctl(struct file *file, unsigned cmd, | ||
765 | unsigned long arg) | ||
766 | { | ||
767 | struct compat_dirent __user *p = compat_ptr(arg); | ||
768 | int ret; | ||
769 | mm_segment_t oldfs = get_fs(); | ||
770 | struct dirent d[2]; | ||
771 | |||
772 | switch (cmd) { | ||
773 | case VFAT_IOCTL_READDIR_BOTH32: | ||
774 | cmd = VFAT_IOCTL_READDIR_BOTH; | ||
775 | break; | ||
776 | case VFAT_IOCTL_READDIR_SHORT32: | ||
777 | cmd = VFAT_IOCTL_READDIR_SHORT; | ||
778 | break; | ||
779 | default: | ||
780 | return -ENOIOCTLCMD; | ||
781 | } | ||
782 | |||
783 | set_fs(KERNEL_DS); | ||
784 | lock_kernel(); | ||
785 | ret = fat_dir_ioctl(file->f_dentry->d_inode, file, | ||
786 | cmd, (unsigned long) &d); | ||
787 | unlock_kernel(); | ||
788 | set_fs(oldfs); | ||
789 | if (ret >= 0) { | ||
790 | ret |= fat_compat_put_dirent32(&d[0], p); | ||
791 | ret |= fat_compat_put_dirent32(&d[1], p + 1); | ||
792 | } | ||
793 | return ret; | ||
794 | } | ||
795 | #endif /* CONFIG_COMPAT */ | ||
796 | |||
744 | const struct file_operations fat_dir_operations = { | 797 | const struct file_operations fat_dir_operations = { |
745 | .read = generic_read_dir, | 798 | .read = generic_read_dir, |
746 | .readdir = fat_readdir, | 799 | .readdir = fat_readdir, |
747 | .ioctl = fat_dir_ioctl, | 800 | .ioctl = fat_dir_ioctl, |
801 | #ifdef CONFIG_COMPAT | ||
802 | .compat_ioctl = fat_compat_dir_ioctl, | ||
803 | #endif | ||
748 | .fsync = file_fsync, | 804 | .fsync = file_fsync, |
749 | }; | 805 | }; |
750 | 806 | ||
diff --git a/fs/fat/file.c b/fs/fat/file.c index 1ee25232e6af..d50fc47169c1 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/smp_lock.h> | 13 | #include <linux/smp_lock.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/writeback.h> | 15 | #include <linux/writeback.h> |
16 | #include <linux/blkdev.h> | ||
16 | 17 | ||
17 | int fat_generic_ioctl(struct inode *inode, struct file *filp, | 18 | int fat_generic_ioctl(struct inode *inode, struct file *filp, |
18 | unsigned int cmd, unsigned long arg) | 19 | unsigned int cmd, unsigned long arg) |
@@ -112,6 +113,16 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, | |||
112 | } | 113 | } |
113 | } | 114 | } |
114 | 115 | ||
116 | static int fat_file_release(struct inode *inode, struct file *filp) | ||
117 | { | ||
118 | if ((filp->f_mode & FMODE_WRITE) && | ||
119 | MSDOS_SB(inode->i_sb)->options.flush) { | ||
120 | fat_flush_inodes(inode->i_sb, inode, NULL); | ||
121 | blk_congestion_wait(WRITE, HZ/10); | ||
122 | } | ||
123 | return 0; | ||
124 | } | ||
125 | |||
115 | const struct file_operations fat_file_operations = { | 126 | const struct file_operations fat_file_operations = { |
116 | .llseek = generic_file_llseek, | 127 | .llseek = generic_file_llseek, |
117 | .read = do_sync_read, | 128 | .read = do_sync_read, |
@@ -121,6 +132,7 @@ const struct file_operations fat_file_operations = { | |||
121 | .aio_read = generic_file_aio_read, | 132 | .aio_read = generic_file_aio_read, |
122 | .aio_write = generic_file_aio_write, | 133 | .aio_write = generic_file_aio_write, |
123 | .mmap = generic_file_mmap, | 134 | .mmap = generic_file_mmap, |
135 | .release = fat_file_release, | ||
124 | .ioctl = fat_generic_ioctl, | 136 | .ioctl = fat_generic_ioctl, |
125 | .fsync = file_fsync, | 137 | .fsync = file_fsync, |
126 | .sendfile = generic_file_sendfile, | 138 | .sendfile = generic_file_sendfile, |
@@ -289,6 +301,7 @@ void fat_truncate(struct inode *inode) | |||
289 | lock_kernel(); | 301 | lock_kernel(); |
290 | fat_free(inode, nr_clusters); | 302 | fat_free(inode, nr_clusters); |
291 | unlock_kernel(); | 303 | unlock_kernel(); |
304 | fat_flush_inodes(inode->i_sb, inode, NULL); | ||
292 | } | 305 | } |
293 | 306 | ||
294 | struct inode_operations fat_file_inode_operations = { | 307 | struct inode_operations fat_file_inode_operations = { |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index ab96ae823753..045738032a83 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/vfs.h> | 24 | #include <linux/vfs.h> |
25 | #include <linux/parser.h> | 25 | #include <linux/parser.h> |
26 | #include <linux/uio.h> | 26 | #include <linux/uio.h> |
27 | #include <linux/writeback.h> | ||
27 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
28 | 29 | ||
29 | #ifndef CONFIG_FAT_DEFAULT_IOCHARSET | 30 | #ifndef CONFIG_FAT_DEFAULT_IOCHARSET |
@@ -853,7 +854,7 @@ enum { | |||
853 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, | 854 | Opt_charset, Opt_shortname_lower, Opt_shortname_win95, |
854 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, | 855 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, |
855 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 856 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, |
856 | Opt_obsolate, Opt_err, | 857 | Opt_obsolate, Opt_flush, Opt_err, |
857 | }; | 858 | }; |
858 | 859 | ||
859 | static match_table_t fat_tokens = { | 860 | static match_table_t fat_tokens = { |
@@ -885,7 +886,8 @@ static match_table_t fat_tokens = { | |||
885 | {Opt_obsolate, "cvf_format=%20s"}, | 886 | {Opt_obsolate, "cvf_format=%20s"}, |
886 | {Opt_obsolate, "cvf_options=%100s"}, | 887 | {Opt_obsolate, "cvf_options=%100s"}, |
887 | {Opt_obsolate, "posix"}, | 888 | {Opt_obsolate, "posix"}, |
888 | {Opt_err, NULL} | 889 | {Opt_flush, "flush"}, |
890 | {Opt_err, NULL}, | ||
889 | }; | 891 | }; |
890 | static match_table_t msdos_tokens = { | 892 | static match_table_t msdos_tokens = { |
891 | {Opt_nodots, "nodots"}, | 893 | {Opt_nodots, "nodots"}, |
@@ -1026,6 +1028,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
1026 | return 0; | 1028 | return 0; |
1027 | opts->codepage = option; | 1029 | opts->codepage = option; |
1028 | break; | 1030 | break; |
1031 | case Opt_flush: | ||
1032 | opts->flush = 1; | ||
1033 | break; | ||
1029 | 1034 | ||
1030 | /* msdos specific */ | 1035 | /* msdos specific */ |
1031 | case Opt_dots: | 1036 | case Opt_dots: |
@@ -1425,6 +1430,56 @@ out_fail: | |||
1425 | 1430 | ||
1426 | EXPORT_SYMBOL_GPL(fat_fill_super); | 1431 | EXPORT_SYMBOL_GPL(fat_fill_super); |
1427 | 1432 | ||
1433 | /* | ||
1434 | * helper function for fat_flush_inodes. This writes both the inode | ||
1435 | * and the file data blocks, waiting for in flight data blocks before | ||
1436 | * the start of the call. It does not wait for any io started | ||
1437 | * during the call | ||
1438 | */ | ||
1439 | static int writeback_inode(struct inode *inode) | ||
1440 | { | ||
1441 | |||
1442 | int ret; | ||
1443 | struct address_space *mapping = inode->i_mapping; | ||
1444 | struct writeback_control wbc = { | ||
1445 | .sync_mode = WB_SYNC_NONE, | ||
1446 | .nr_to_write = 0, | ||
1447 | }; | ||
1448 | /* if we used WB_SYNC_ALL, sync_inode waits for the io for the | ||
1449 | * inode to finish. So WB_SYNC_NONE is sent down to sync_inode | ||
1450 | * and filemap_fdatawrite is used for the data blocks | ||
1451 | */ | ||
1452 | ret = sync_inode(inode, &wbc); | ||
1453 | if (!ret) | ||
1454 | ret = filemap_fdatawrite(mapping); | ||
1455 | return ret; | ||
1456 | } | ||
1457 | |||
1458 | /* | ||
1459 | * write data and metadata corresponding to i1 and i2. The io is | ||
1460 | * started but we do not wait for any of it to finish. | ||
1461 | * | ||
1462 | * filemap_flush is used for the block device, so if there is a dirty | ||
1463 | * page for a block already in flight, we will not wait and start the | ||
1464 | * io over again | ||
1465 | */ | ||
1466 | int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2) | ||
1467 | { | ||
1468 | int ret = 0; | ||
1469 | if (!MSDOS_SB(sb)->options.flush) | ||
1470 | return 0; | ||
1471 | if (i1) | ||
1472 | ret = writeback_inode(i1); | ||
1473 | if (!ret && i2) | ||
1474 | ret = writeback_inode(i2); | ||
1475 | if (!ret && sb) { | ||
1476 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; | ||
1477 | ret = filemap_flush(mapping); | ||
1478 | } | ||
1479 | return ret; | ||
1480 | } | ||
1481 | EXPORT_SYMBOL_GPL(fat_flush_inodes); | ||
1482 | |||
1428 | static int __init init_fat_fs(void) | 1483 | static int __init init_fat_fs(void) |
1429 | { | 1484 | { |
1430 | int err; | 1485 | int err; |
@@ -288,71 +288,63 @@ out: | |||
288 | } | 288 | } |
289 | 289 | ||
290 | /* | 290 | /* |
291 | * Expands the file descriptor table - it will allocate a new fdtable and | 291 | * Expand the file descriptor table. |
292 | * both fd array and fdset. It is expected to be called with the | 292 | * This function will allocate a new fdtable and both fd array and fdset, of |
293 | * files_lock held. | 293 | * the given size. |
294 | * Return <0 error code on error; 1 on successful completion. | ||
295 | * The files->file_lock should be held on entry, and will be held on exit. | ||
294 | */ | 296 | */ |
295 | static int expand_fdtable(struct files_struct *files, int nr) | 297 | static int expand_fdtable(struct files_struct *files, int nr) |
296 | __releases(files->file_lock) | 298 | __releases(files->file_lock) |
297 | __acquires(files->file_lock) | 299 | __acquires(files->file_lock) |
298 | { | 300 | { |
299 | int error = 0; | 301 | struct fdtable *new_fdt, *cur_fdt; |
300 | struct fdtable *fdt; | ||
301 | struct fdtable *nfdt = NULL; | ||
302 | 302 | ||
303 | spin_unlock(&files->file_lock); | 303 | spin_unlock(&files->file_lock); |
304 | nfdt = alloc_fdtable(nr); | 304 | new_fdt = alloc_fdtable(nr); |
305 | if (!nfdt) { | ||
306 | error = -ENOMEM; | ||
307 | spin_lock(&files->file_lock); | ||
308 | goto out; | ||
309 | } | ||
310 | |||
311 | spin_lock(&files->file_lock); | 305 | spin_lock(&files->file_lock); |
312 | fdt = files_fdtable(files); | 306 | if (!new_fdt) |
307 | return -ENOMEM; | ||
313 | /* | 308 | /* |
314 | * Check again since another task may have expanded the | 309 | * Check again since another task may have expanded the fd table while |
315 | * fd table while we dropped the lock | 310 | * we dropped the lock |
316 | */ | 311 | */ |
317 | if (nr >= fdt->max_fds || nr >= fdt->max_fdset) { | 312 | cur_fdt = files_fdtable(files); |
318 | copy_fdtable(nfdt, fdt); | 313 | if (nr >= cur_fdt->max_fds || nr >= cur_fdt->max_fdset) { |
314 | /* Continue as planned */ | ||
315 | copy_fdtable(new_fdt, cur_fdt); | ||
316 | rcu_assign_pointer(files->fdt, new_fdt); | ||
317 | free_fdtable(cur_fdt); | ||
319 | } else { | 318 | } else { |
320 | /* Somebody expanded while we dropped file_lock */ | 319 | /* Somebody else expanded, so undo our attempt */ |
321 | spin_unlock(&files->file_lock); | 320 | __free_fdtable(new_fdt); |
322 | __free_fdtable(nfdt); | ||
323 | spin_lock(&files->file_lock); | ||
324 | goto out; | ||
325 | } | 321 | } |
326 | rcu_assign_pointer(files->fdt, nfdt); | 322 | return 1; |
327 | free_fdtable(fdt); | ||
328 | out: | ||
329 | return error; | ||
330 | } | 323 | } |
331 | 324 | ||
332 | /* | 325 | /* |
333 | * Expand files. | 326 | * Expand files. |
334 | * Return <0 on error; 0 nothing done; 1 files expanded, we may have blocked. | 327 | * This function will expand the file structures, if the requested size exceeds |
335 | * Should be called with the files->file_lock spinlock held for write. | 328 | * the current capacity and there is room for expansion. |
329 | * Return <0 error code on error; 0 when nothing done; 1 when files were | ||
330 | * expanded and execution may have blocked. | ||
331 | * The files->file_lock should be held on entry, and will be held on exit. | ||
336 | */ | 332 | */ |
337 | int expand_files(struct files_struct *files, int nr) | 333 | int expand_files(struct files_struct *files, int nr) |
338 | { | 334 | { |
339 | int err, expand = 0; | ||
340 | struct fdtable *fdt; | 335 | struct fdtable *fdt; |
341 | 336 | ||
342 | fdt = files_fdtable(files); | 337 | fdt = files_fdtable(files); |
343 | if (nr >= fdt->max_fdset || nr >= fdt->max_fds) { | 338 | /* Do we need to expand? */ |
344 | if (fdt->max_fdset >= NR_OPEN || | 339 | if (nr < fdt->max_fdset && nr < fdt->max_fds) |
345 | fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) { | 340 | return 0; |
346 | err = -EMFILE; | 341 | /* Can we expand? */ |
347 | goto out; | 342 | if (fdt->max_fdset >= NR_OPEN || fdt->max_fds >= NR_OPEN || |
348 | } | 343 | nr >= NR_OPEN) |
349 | expand = 1; | 344 | return -EMFILE; |
350 | if ((err = expand_fdtable(files, nr))) | 345 | |
351 | goto out; | 346 | /* All good, so we try */ |
352 | } | 347 | return expand_fdtable(files, nr); |
353 | err = expand; | ||
354 | out: | ||
355 | return err; | ||
356 | } | 348 | } |
357 | 349 | ||
358 | static void __devinit fdtable_defer_list_init(int cpu) | 350 | static void __devinit fdtable_defer_list_init(int cpu) |
diff --git a/fs/filesystems.c b/fs/filesystems.c index 9f1072836c8e..e3fa77c6ed56 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c | |||
@@ -69,8 +69,6 @@ int register_filesystem(struct file_system_type * fs) | |||
69 | int res = 0; | 69 | int res = 0; |
70 | struct file_system_type ** p; | 70 | struct file_system_type ** p; |
71 | 71 | ||
72 | if (!fs) | ||
73 | return -EINVAL; | ||
74 | if (fs->next) | 72 | if (fs->next) |
75 | return -EBUSY; | 73 | return -EBUSY; |
76 | INIT_LIST_HEAD(&fs->fs_supers); | 74 | INIT_LIST_HEAD(&fs->fs_supers); |
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index b74b791fc23b..ac28b0835ffc 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c | |||
@@ -260,12 +260,17 @@ static struct file_system_type vxfs_fs_type = { | |||
260 | static int __init | 260 | static int __init |
261 | vxfs_init(void) | 261 | vxfs_init(void) |
262 | { | 262 | { |
263 | int rv; | ||
264 | |||
263 | vxfs_inode_cachep = kmem_cache_create("vxfs_inode", | 265 | vxfs_inode_cachep = kmem_cache_create("vxfs_inode", |
264 | sizeof(struct vxfs_inode_info), 0, | 266 | sizeof(struct vxfs_inode_info), 0, |
265 | SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL, NULL); | 267 | SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL, NULL); |
266 | if (vxfs_inode_cachep) | 268 | if (!vxfs_inode_cachep) |
267 | return register_filesystem(&vxfs_fs_type); | 269 | return -ENOMEM; |
268 | return -ENOMEM; | 270 | rv = register_filesystem(&vxfs_fs_type); |
271 | if (rv < 0) | ||
272 | kmem_cache_destroy(vxfs_inode_cachep); | ||
273 | return rv; | ||
269 | } | 274 | } |
270 | 275 | ||
271 | static void __exit | 276 | static void __exit |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 892643dc9af1..c403b66ec83c 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -22,8 +22,7 @@ | |||
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/backing-dev.h> | 23 | #include <linux/backing-dev.h> |
24 | #include <linux/buffer_head.h> | 24 | #include <linux/buffer_head.h> |
25 | 25 | #include "internal.h" | |
26 | extern struct super_block *blockdev_superblock; | ||
27 | 26 | ||
28 | /** | 27 | /** |
29 | * __mark_inode_dirty - internal function | 28 | * __mark_inode_dirty - internal function |
@@ -320,7 +319,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) | |||
320 | 319 | ||
321 | if (!bdi_cap_writeback_dirty(bdi)) { | 320 | if (!bdi_cap_writeback_dirty(bdi)) { |
322 | list_move(&inode->i_list, &sb->s_dirty); | 321 | list_move(&inode->i_list, &sb->s_dirty); |
323 | if (sb == blockdev_superblock) { | 322 | if (sb_is_blkdev_sb(sb)) { |
324 | /* | 323 | /* |
325 | * Dirty memory-backed blockdev: the ramdisk | 324 | * Dirty memory-backed blockdev: the ramdisk |
326 | * driver does this. Skip just this inode | 325 | * driver does this. Skip just this inode |
@@ -337,14 +336,14 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) | |||
337 | 336 | ||
338 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 337 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |
339 | wbc->encountered_congestion = 1; | 338 | wbc->encountered_congestion = 1; |
340 | if (sb != blockdev_superblock) | 339 | if (!sb_is_blkdev_sb(sb)) |
341 | break; /* Skip a congested fs */ | 340 | break; /* Skip a congested fs */ |
342 | list_move(&inode->i_list, &sb->s_dirty); | 341 | list_move(&inode->i_list, &sb->s_dirty); |
343 | continue; /* Skip a congested blockdev */ | 342 | continue; /* Skip a congested blockdev */ |
344 | } | 343 | } |
345 | 344 | ||
346 | if (wbc->bdi && bdi != wbc->bdi) { | 345 | if (wbc->bdi && bdi != wbc->bdi) { |
347 | if (sb != blockdev_superblock) | 346 | if (!sb_is_blkdev_sb(sb)) |
348 | break; /* fs has the wrong queue */ | 347 | break; /* fs has the wrong queue */ |
349 | list_move(&inode->i_list, &sb->s_dirty); | 348 | list_move(&inode->i_list, &sb->s_dirty); |
350 | continue; /* blockdev has wrong queue */ | 349 | continue; /* blockdev has wrong queue */ |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 1e2006caf158..4fc557c40cc0 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -212,6 +212,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) | |||
212 | * Called with fc->lock, unlocks it | 212 | * Called with fc->lock, unlocks it |
213 | */ | 213 | */ |
214 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) | 214 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) |
215 | __releases(fc->lock) | ||
215 | { | 216 | { |
216 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | 217 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; |
217 | req->end = NULL; | 218 | req->end = NULL; |
@@ -640,6 +641,7 @@ static void request_wait(struct fuse_conn *fc) | |||
640 | */ | 641 | */ |
641 | static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, | 642 | static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, |
642 | const struct iovec *iov, unsigned long nr_segs) | 643 | const struct iovec *iov, unsigned long nr_segs) |
644 | __releases(fc->lock) | ||
643 | { | 645 | { |
644 | struct fuse_copy_state cs; | 646 | struct fuse_copy_state cs; |
645 | struct fuse_in_header ih; | 647 | struct fuse_in_header ih; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 409ce6a7cca4..f85b2a282f13 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -776,7 +776,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
776 | if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) | 776 | if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) |
777 | return -EACCES; | 777 | return -EACCES; |
778 | 778 | ||
779 | if (nd && (nd->flags & LOOKUP_ACCESS)) | 779 | if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) |
780 | return fuse_access(inode, mask); | 780 | return fuse_access(inode, mask); |
781 | return 0; | 781 | return 0; |
782 | } | 782 | } |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index cb7cadb0b790..7d0a9aee01f2 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -251,6 +251,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
251 | memset(&outarg, 0, sizeof(outarg)); | 251 | memset(&outarg, 0, sizeof(outarg)); |
252 | req->in.numargs = 0; | 252 | req->in.numargs = 0; |
253 | req->in.h.opcode = FUSE_STATFS; | 253 | req->in.h.opcode = FUSE_STATFS; |
254 | req->in.h.nodeid = get_node_id(dentry->d_inode); | ||
254 | req->out.numargs = 1; | 255 | req->out.numargs = 1; |
255 | req->out.args[0].size = | 256 | req->out.args[0].size = |
256 | fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); | 257 | fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); |
diff --git a/fs/generic_acl.c b/fs/generic_acl.c new file mode 100644 index 000000000000..9ccb78947171 --- /dev/null +++ b/fs/generic_acl.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * fs/generic_acl.c | ||
3 | * | ||
4 | * (C) 2005 Andreas Gruenbacher <agruen@suse.de> | ||
5 | * | ||
6 | * This file is released under the GPL. | ||
7 | */ | ||
8 | |||
9 | #include <linux/sched.h> | ||
10 | #include <linux/fs.h> | ||
11 | #include <linux/generic_acl.h> | ||
12 | |||
13 | /** | ||
14 | * generic_acl_list - Generic xattr_handler->list() operation | ||
15 | * @ops: Filesystem specific getacl and setacl callbacks | ||
16 | */ | ||
17 | size_t | ||
18 | generic_acl_list(struct inode *inode, struct generic_acl_operations *ops, | ||
19 | int type, char *list, size_t list_size) | ||
20 | { | ||
21 | struct posix_acl *acl; | ||
22 | const char *name; | ||
23 | size_t size; | ||
24 | |||
25 | acl = ops->getacl(inode, type); | ||
26 | if (!acl) | ||
27 | return 0; | ||
28 | posix_acl_release(acl); | ||
29 | |||
30 | switch(type) { | ||
31 | case ACL_TYPE_ACCESS: | ||
32 | name = POSIX_ACL_XATTR_ACCESS; | ||
33 | break; | ||
34 | |||
35 | case ACL_TYPE_DEFAULT: | ||
36 | name = POSIX_ACL_XATTR_DEFAULT; | ||
37 | break; | ||
38 | |||
39 | default: | ||
40 | return 0; | ||
41 | } | ||
42 | size = strlen(name) + 1; | ||
43 | if (list && size <= list_size) | ||
44 | memcpy(list, name, size); | ||
45 | return size; | ||
46 | } | ||
47 | |||
48 | /** | ||
49 | * generic_acl_get - Generic xattr_handler->get() operation | ||
50 | * @ops: Filesystem specific getacl and setacl callbacks | ||
51 | */ | ||
52 | int | ||
53 | generic_acl_get(struct inode *inode, struct generic_acl_operations *ops, | ||
54 | int type, void *buffer, size_t size) | ||
55 | { | ||
56 | struct posix_acl *acl; | ||
57 | int error; | ||
58 | |||
59 | acl = ops->getacl(inode, type); | ||
60 | if (!acl) | ||
61 | return -ENODATA; | ||
62 | error = posix_acl_to_xattr(acl, buffer, size); | ||
63 | posix_acl_release(acl); | ||
64 | |||
65 | return error; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * generic_acl_set - Generic xattr_handler->set() operation | ||
70 | * @ops: Filesystem specific getacl and setacl callbacks | ||
71 | */ | ||
72 | int | ||
73 | generic_acl_set(struct inode *inode, struct generic_acl_operations *ops, | ||
74 | int type, const void *value, size_t size) | ||
75 | { | ||
76 | struct posix_acl *acl = NULL; | ||
77 | int error; | ||
78 | |||
79 | if (S_ISLNK(inode->i_mode)) | ||
80 | return -EOPNOTSUPP; | ||
81 | if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) | ||
82 | return -EPERM; | ||
83 | if (value) { | ||
84 | acl = posix_acl_from_xattr(value, size); | ||
85 | if (IS_ERR(acl)) | ||
86 | return PTR_ERR(acl); | ||
87 | } | ||
88 | if (acl) { | ||
89 | mode_t mode; | ||
90 | |||
91 | error = posix_acl_valid(acl); | ||
92 | if (error) | ||
93 | goto failed; | ||
94 | switch(type) { | ||
95 | case ACL_TYPE_ACCESS: | ||
96 | mode = inode->i_mode; | ||
97 | error = posix_acl_equiv_mode(acl, &mode); | ||
98 | if (error < 0) | ||
99 | goto failed; | ||
100 | inode->i_mode = mode; | ||
101 | if (error == 0) { | ||
102 | posix_acl_release(acl); | ||
103 | acl = NULL; | ||
104 | } | ||
105 | break; | ||
106 | |||
107 | case ACL_TYPE_DEFAULT: | ||
108 | if (!S_ISDIR(inode->i_mode)) { | ||
109 | error = -EINVAL; | ||
110 | goto failed; | ||
111 | } | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | ops->setacl(inode, type, acl); | ||
116 | error = 0; | ||
117 | failed: | ||
118 | posix_acl_release(acl); | ||
119 | return error; | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * generic_acl_init - Take care of acl inheritance at @inode create time | ||
124 | * @ops: Filesystem specific getacl and setacl callbacks | ||
125 | * | ||
126 | * Files created inside a directory with a default ACL inherit the | ||
127 | * directory's default ACL. | ||
128 | */ | ||
129 | int | ||
130 | generic_acl_init(struct inode *inode, struct inode *dir, | ||
131 | struct generic_acl_operations *ops) | ||
132 | { | ||
133 | struct posix_acl *acl = NULL; | ||
134 | mode_t mode = inode->i_mode; | ||
135 | int error; | ||
136 | |||
137 | inode->i_mode = mode & ~current->fs->umask; | ||
138 | if (!S_ISLNK(inode->i_mode)) | ||
139 | acl = ops->getacl(dir, ACL_TYPE_DEFAULT); | ||
140 | if (acl) { | ||
141 | struct posix_acl *clone; | ||
142 | |||
143 | if (S_ISDIR(inode->i_mode)) { | ||
144 | clone = posix_acl_clone(acl, GFP_KERNEL); | ||
145 | error = -ENOMEM; | ||
146 | if (!clone) | ||
147 | goto cleanup; | ||
148 | ops->setacl(inode, ACL_TYPE_DEFAULT, clone); | ||
149 | posix_acl_release(clone); | ||
150 | } | ||
151 | clone = posix_acl_clone(acl, GFP_KERNEL); | ||
152 | error = -ENOMEM; | ||
153 | if (!clone) | ||
154 | goto cleanup; | ||
155 | error = posix_acl_create_masq(clone, &mode); | ||
156 | if (error >= 0) { | ||
157 | inode->i_mode = mode; | ||
158 | if (error > 0) | ||
159 | ops->setacl(inode, ACL_TYPE_ACCESS, clone); | ||
160 | } | ||
161 | posix_acl_release(clone); | ||
162 | } | ||
163 | error = 0; | ||
164 | |||
165 | cleanup: | ||
166 | posix_acl_release(acl); | ||
167 | return error; | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * generic_acl_chmod - change the access acl of @inode upon chmod() | ||
172 | * @ops: FIlesystem specific getacl and setacl callbacks | ||
173 | * | ||
174 | * A chmod also changes the permissions of the owner, group/mask, and | ||
175 | * other ACL entries. | ||
176 | */ | ||
177 | int | ||
178 | generic_acl_chmod(struct inode *inode, struct generic_acl_operations *ops) | ||
179 | { | ||
180 | struct posix_acl *acl, *clone; | ||
181 | int error = 0; | ||
182 | |||
183 | if (S_ISLNK(inode->i_mode)) | ||
184 | return -EOPNOTSUPP; | ||
185 | acl = ops->getacl(inode, ACL_TYPE_ACCESS); | ||
186 | if (acl) { | ||
187 | clone = posix_acl_clone(acl, GFP_KERNEL); | ||
188 | posix_acl_release(acl); | ||
189 | if (!clone) | ||
190 | return -ENOMEM; | ||
191 | error = posix_acl_chmod_masq(clone, inode->i_mode); | ||
192 | if (!error) | ||
193 | ops->setacl(inode, ACL_TYPE_ACCESS, clone); | ||
194 | posix_acl_release(clone); | ||
195 | } | ||
196 | return error; | ||
197 | } | ||
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 8a1ca5ef7ada..3915635b4470 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -246,12 +246,8 @@ struct hfsplus_readdir_data { | |||
246 | 246 | ||
247 | /* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support | 247 | /* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support |
248 | * chattr/lsattr */ | 248 | * chattr/lsattr */ |
249 | #define HFSPLUS_IOC_EXT2_GETFLAGS _IOR('f', 1, long) | 249 | #define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS |
250 | #define HFSPLUS_IOC_EXT2_SETFLAGS _IOW('f', 2, long) | 250 | #define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS |
251 | |||
252 | #define EXT2_FLAG_IMMUTABLE 0x00000010 /* Immutable file */ | ||
253 | #define EXT2_FLAG_APPEND 0x00000020 /* writes to file may only append */ | ||
254 | #define EXT2_FLAG_NODUMP 0x00000040 /* do not dump file */ | ||
255 | 251 | ||
256 | 252 | ||
257 | /* | 253 | /* |
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index 13cf848ac833..79fd10402ea3 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c | |||
@@ -28,11 +28,11 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
28 | case HFSPLUS_IOC_EXT2_GETFLAGS: | 28 | case HFSPLUS_IOC_EXT2_GETFLAGS: |
29 | flags = 0; | 29 | flags = 0; |
30 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_IMMUTABLE) | 30 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_IMMUTABLE) |
31 | flags |= EXT2_FLAG_IMMUTABLE; /* EXT2_IMMUTABLE_FL */ | 31 | flags |= FS_IMMUTABLE_FL; /* EXT2_IMMUTABLE_FL */ |
32 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_APPEND) | 32 | if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_APPEND) |
33 | flags |= EXT2_FLAG_APPEND; /* EXT2_APPEND_FL */ | 33 | flags |= FS_APPEND_FL; /* EXT2_APPEND_FL */ |
34 | if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP) | 34 | if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP) |
35 | flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */ | 35 | flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */ |
36 | return put_user(flags, (int __user *)arg); | 36 | return put_user(flags, (int __user *)arg); |
37 | case HFSPLUS_IOC_EXT2_SETFLAGS: { | 37 | case HFSPLUS_IOC_EXT2_SETFLAGS: { |
38 | if (IS_RDONLY(inode)) | 38 | if (IS_RDONLY(inode)) |
@@ -44,32 +44,31 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
44 | if (get_user(flags, (int __user *)arg)) | 44 | if (get_user(flags, (int __user *)arg)) |
45 | return -EFAULT; | 45 | return -EFAULT; |
46 | 46 | ||
47 | if (flags & (EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND) || | 47 | if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || |
48 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { | 48 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { |
49 | if (!capable(CAP_LINUX_IMMUTABLE)) | 49 | if (!capable(CAP_LINUX_IMMUTABLE)) |
50 | return -EPERM; | 50 | return -EPERM; |
51 | } | 51 | } |
52 | 52 | ||
53 | /* don't silently ignore unsupported ext2 flags */ | 53 | /* don't silently ignore unsupported ext2 flags */ |
54 | if (flags & ~(EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND| | 54 | if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) |
55 | EXT2_FLAG_NODUMP)) | ||
56 | return -EOPNOTSUPP; | 55 | return -EOPNOTSUPP; |
57 | 56 | ||
58 | if (flags & EXT2_FLAG_IMMUTABLE) { /* EXT2_IMMUTABLE_FL */ | 57 | if (flags & FS_IMMUTABLE_FL) { /* EXT2_IMMUTABLE_FL */ |
59 | inode->i_flags |= S_IMMUTABLE; | 58 | inode->i_flags |= S_IMMUTABLE; |
60 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; | 59 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; |
61 | } else { | 60 | } else { |
62 | inode->i_flags &= ~S_IMMUTABLE; | 61 | inode->i_flags &= ~S_IMMUTABLE; |
63 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_IMMUTABLE; | 62 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_IMMUTABLE; |
64 | } | 63 | } |
65 | if (flags & EXT2_FLAG_APPEND) { /* EXT2_APPEND_FL */ | 64 | if (flags & FS_APPEND_FL) { /* EXT2_APPEND_FL */ |
66 | inode->i_flags |= S_APPEND; | 65 | inode->i_flags |= S_APPEND; |
67 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_APPEND; | 66 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_APPEND; |
68 | } else { | 67 | } else { |
69 | inode->i_flags &= ~S_APPEND; | 68 | inode->i_flags &= ~S_APPEND; |
70 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND; | 69 | HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND; |
71 | } | 70 | } |
72 | if (flags & EXT2_FLAG_NODUMP) /* EXT2_NODUMP_FL */ | 71 | if (flags & FS_NODUMP_FL) /* EXT2_NODUMP_FL */ |
73 | HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP; | 72 | HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP; |
74 | else | 73 | else |
75 | HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP; | 74 | HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP; |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index e025a31b4c64..f5b8f329aca6 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -229,7 +229,7 @@ static void hugetlbfs_delete_inode(struct inode *inode) | |||
229 | clear_inode(inode); | 229 | clear_inode(inode); |
230 | } | 230 | } |
231 | 231 | ||
232 | static void hugetlbfs_forget_inode(struct inode *inode) | 232 | static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock) |
233 | { | 233 | { |
234 | struct super_block *sb = inode->i_sb; | 234 | struct super_block *sb = inode->i_sb; |
235 | 235 | ||
diff --git a/fs/inode.c b/fs/inode.c index f5c04dd9ae8a..ada7643104e1 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -133,7 +133,6 @@ static struct inode *alloc_inode(struct super_block *sb) | |||
133 | inode->i_bdev = NULL; | 133 | inode->i_bdev = NULL; |
134 | inode->i_cdev = NULL; | 134 | inode->i_cdev = NULL; |
135 | inode->i_rdev = 0; | 135 | inode->i_rdev = 0; |
136 | inode->i_security = NULL; | ||
137 | inode->dirtied_when = 0; | 136 | inode->dirtied_when = 0; |
138 | if (security_inode_alloc(inode)) { | 137 | if (security_inode_alloc(inode)) { |
139 | if (inode->i_sb->s_op->destroy_inode) | 138 | if (inode->i_sb->s_op->destroy_inode) |
@@ -363,27 +362,6 @@ int invalidate_inodes(struct super_block * sb) | |||
363 | } | 362 | } |
364 | 363 | ||
365 | EXPORT_SYMBOL(invalidate_inodes); | 364 | EXPORT_SYMBOL(invalidate_inodes); |
366 | |||
367 | int __invalidate_device(struct block_device *bdev) | ||
368 | { | ||
369 | struct super_block *sb = get_super(bdev); | ||
370 | int res = 0; | ||
371 | |||
372 | if (sb) { | ||
373 | /* | ||
374 | * no need to lock the super, get_super holds the | ||
375 | * read mutex so the filesystem cannot go away | ||
376 | * under us (->put_super runs with the write lock | ||
377 | * hold). | ||
378 | */ | ||
379 | shrink_dcache_sb(sb); | ||
380 | res = invalidate_inodes(sb); | ||
381 | drop_super(sb); | ||
382 | } | ||
383 | invalidate_bdev(bdev, 0); | ||
384 | return res; | ||
385 | } | ||
386 | EXPORT_SYMBOL(__invalidate_device); | ||
387 | 365 | ||
388 | static int can_unuse(struct inode *inode) | 366 | static int can_unuse(struct inode *inode) |
389 | { | 367 | { |
diff --git a/fs/internal.h b/fs/internal.h new file mode 100644 index 000000000000..ea00126c9a59 --- /dev/null +++ b/fs/internal.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* fs/ internal definitions | ||
2 | * | ||
3 | * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/ioctl32.h> | ||
13 | |||
14 | struct super_block; | ||
15 | |||
16 | /* | ||
17 | * block_dev.c | ||
18 | */ | ||
19 | #ifdef CONFIG_BLOCK | ||
20 | extern struct super_block *blockdev_superblock; | ||
21 | extern void __init bdev_cache_init(void); | ||
22 | |||
23 | static inline int sb_is_blkdev_sb(struct super_block *sb) | ||
24 | { | ||
25 | return sb == blockdev_superblock; | ||
26 | } | ||
27 | |||
28 | #else | ||
29 | static inline void bdev_cache_init(void) | ||
30 | { | ||
31 | } | ||
32 | |||
33 | static inline int sb_is_blkdev_sb(struct super_block *sb) | ||
34 | { | ||
35 | return 0; | ||
36 | } | ||
37 | #endif | ||
38 | |||
39 | /* | ||
40 | * char_dev.c | ||
41 | */ | ||
42 | extern void __init chrdev_init(void); | ||
43 | |||
44 | /* | ||
45 | * compat_ioctl.c | ||
46 | */ | ||
47 | #ifdef CONFIG_COMPAT | ||
48 | extern struct ioctl_trans ioctl_start[]; | ||
49 | extern int ioctl_table_size; | ||
50 | #endif | ||
51 | |||
52 | /* | ||
53 | * namespace.c | ||
54 | */ | ||
55 | extern int copy_mount_options(const void __user *, unsigned long *); | ||
diff --git a/fs/ioprio.c b/fs/ioprio.c index 78b1deae3fa2..6dc6721d9e82 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/ioprio.c | 2 | * fs/ioprio.c |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Jens Axboe <axboe@suse.de> | 4 | * Copyright (C) 2004 Jens Axboe <axboe@kernel.dk> |
5 | * | 5 | * |
6 | * Helper functions for setting/querying io priorities of processes. The | 6 | * Helper functions for setting/querying io priorities of processes. The |
7 | * system calls closely mimmick getpriority/setpriority, see the man page for | 7 | * system calls closely mimmick getpriority/setpriority, see the man page for |
@@ -47,8 +47,8 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) | |||
47 | /* see wmb() in current_io_context() */ | 47 | /* see wmb() in current_io_context() */ |
48 | smp_read_barrier_depends(); | 48 | smp_read_barrier_depends(); |
49 | 49 | ||
50 | if (ioc && ioc->set_ioprio) | 50 | if (ioc) |
51 | ioc->set_ioprio(ioc, ioprio); | 51 | ioc->ioprio_changed = 1; |
52 | 52 | ||
53 | task_unlock(task); | 53 | task_unlock(task); |
54 | return 0; | 54 | return 0; |
@@ -81,7 +81,12 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | ret = -ESRCH; | 83 | ret = -ESRCH; |
84 | read_lock_irq(&tasklist_lock); | 84 | /* |
85 | * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic", | ||
86 | * so we can't use rcu_read_lock(). See re-copy of ->ioprio | ||
87 | * in copy_process(). | ||
88 | */ | ||
89 | read_lock(&tasklist_lock); | ||
85 | switch (which) { | 90 | switch (which) { |
86 | case IOPRIO_WHO_PROCESS: | 91 | case IOPRIO_WHO_PROCESS: |
87 | if (!who) | 92 | if (!who) |
@@ -124,7 +129,7 @@ free_uid: | |||
124 | ret = -EINVAL; | 129 | ret = -EINVAL; |
125 | } | 130 | } |
126 | 131 | ||
127 | read_unlock_irq(&tasklist_lock); | 132 | read_unlock(&tasklist_lock); |
128 | return ret; | 133 | return ret; |
129 | } | 134 | } |
130 | 135 | ||
@@ -170,7 +175,7 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
170 | int ret = -ESRCH; | 175 | int ret = -ESRCH; |
171 | int tmpio; | 176 | int tmpio; |
172 | 177 | ||
173 | read_lock_irq(&tasklist_lock); | 178 | read_lock(&tasklist_lock); |
174 | switch (which) { | 179 | switch (which) { |
175 | case IOPRIO_WHO_PROCESS: | 180 | case IOPRIO_WHO_PROCESS: |
176 | if (!who) | 181 | if (!who) |
@@ -221,7 +226,7 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
221 | ret = -EINVAL; | 226 | ret = -EINVAL; |
222 | } | 227 | } |
223 | 228 | ||
224 | read_unlock_irq(&tasklist_lock); | 229 | read_unlock(&tasklist_lock); |
225 | return ret; | 230 | return ret; |
226 | } | 231 | } |
227 | 232 | ||
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 4527692f432b..c34b862cdbf2 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -960,30 +960,30 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s, | |||
960 | goto abort; | 960 | goto abort; |
961 | } | 961 | } |
962 | 962 | ||
963 | if (nextblk) { | 963 | /* On the last section, nextblk == 0, section size is likely to |
964 | while (b_off >= (offset + sect_size)) { | 964 | * exceed sect_size by a partial block, and access beyond the |
965 | struct inode *ninode; | 965 | * end of the file will reach beyond the section size, too. |
966 | 966 | */ | |
967 | offset += sect_size; | 967 | while (nextblk && (b_off >= (offset + sect_size))) { |
968 | if (nextblk == 0) | 968 | struct inode *ninode; |
969 | goto abort; | 969 | |
970 | ninode = isofs_iget(inode->i_sb, nextblk, nextoff); | 970 | offset += sect_size; |
971 | if (!ninode) | 971 | ninode = isofs_iget(inode->i_sb, nextblk, nextoff); |
972 | goto abort; | 972 | if (!ninode) |
973 | firstext = ISOFS_I(ninode)->i_first_extent; | 973 | goto abort; |
974 | sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode); | 974 | firstext = ISOFS_I(ninode)->i_first_extent; |
975 | nextblk = ISOFS_I(ninode)->i_next_section_block; | 975 | sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode); |
976 | nextoff = ISOFS_I(ninode)->i_next_section_offset; | 976 | nextblk = ISOFS_I(ninode)->i_next_section_block; |
977 | iput(ninode); | 977 | nextoff = ISOFS_I(ninode)->i_next_section_offset; |
978 | 978 | iput(ninode); | |
979 | if (++section > 100) { | 979 | |
980 | printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n"); | 980 | if (++section > 100) { |
981 | printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u " | 981 | printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n"); |
982 | "nextblk=%lu nextoff=%lu\n", | 982 | printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u " |
983 | iblock, firstext, (unsigned) sect_size, | 983 | "nextblk=%lu nextoff=%lu\n", |
984 | nextblk, nextoff); | 984 | iblock, firstext, (unsigned) sect_size, |
985 | goto abort; | 985 | nextblk, nextoff); |
986 | } | 986 | goto abort; |
987 | } | 987 | } |
988 | } | 988 | } |
989 | 989 | ||
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 2fc66c3e6681..7af6099c911c 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -715,18 +715,8 @@ journal_t * journal_init_dev(struct block_device *bdev, | |||
715 | if (!journal) | 715 | if (!journal) |
716 | return NULL; | 716 | return NULL; |
717 | 717 | ||
718 | journal->j_dev = bdev; | ||
719 | journal->j_fs_dev = fs_dev; | ||
720 | journal->j_blk_offset = start; | ||
721 | journal->j_maxlen = len; | ||
722 | journal->j_blocksize = blocksize; | ||
723 | |||
724 | bh = __getblk(journal->j_dev, start, journal->j_blocksize); | ||
725 | J_ASSERT(bh != NULL); | ||
726 | journal->j_sb_buffer = bh; | ||
727 | journal->j_superblock = (journal_superblock_t *)bh->b_data; | ||
728 | |||
729 | /* journal descriptor can store up to n blocks -bzzz */ | 718 | /* journal descriptor can store up to n blocks -bzzz */ |
719 | journal->j_blocksize = blocksize; | ||
730 | n = journal->j_blocksize / sizeof(journal_block_tag_t); | 720 | n = journal->j_blocksize / sizeof(journal_block_tag_t); |
731 | journal->j_wbufsize = n; | 721 | journal->j_wbufsize = n; |
732 | journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); | 722 | journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); |
@@ -736,6 +726,15 @@ journal_t * journal_init_dev(struct block_device *bdev, | |||
736 | kfree(journal); | 726 | kfree(journal); |
737 | journal = NULL; | 727 | journal = NULL; |
738 | } | 728 | } |
729 | journal->j_dev = bdev; | ||
730 | journal->j_fs_dev = fs_dev; | ||
731 | journal->j_blk_offset = start; | ||
732 | journal->j_maxlen = len; | ||
733 | |||
734 | bh = __getblk(journal->j_dev, start, journal->j_blocksize); | ||
735 | J_ASSERT(bh != NULL); | ||
736 | journal->j_sb_buffer = bh; | ||
737 | journal->j_superblock = (journal_superblock_t *)bh->b_data; | ||
739 | 738 | ||
740 | return journal; | 739 | return journal; |
741 | } | 740 | } |
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c index 445eed6ce5dc..11563fe2a52b 100644 --- a/fs/jbd/recovery.c +++ b/fs/jbd/recovery.c | |||
@@ -46,7 +46,7 @@ static int scan_revoke_records(journal_t *, struct buffer_head *, | |||
46 | #ifdef __KERNEL__ | 46 | #ifdef __KERNEL__ |
47 | 47 | ||
48 | /* Release readahead buffers after use */ | 48 | /* Release readahead buffers after use */ |
49 | void journal_brelse_array(struct buffer_head *b[], int n) | 49 | static void journal_brelse_array(struct buffer_head *b[], int n) |
50 | { | 50 | { |
51 | while (--n >= 0) | 51 | while (--n >= 0) |
52 | brelse (b[n]); | 52 | brelse (b[n]); |
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index 67b3774820eb..37db52488262 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c | |||
@@ -6,7 +6,6 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/ext2_fs.h> | ||
10 | #include <linux/ctype.h> | 9 | #include <linux/ctype.h> |
11 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
12 | #include <linux/time.h> | 11 | #include <linux/time.h> |
@@ -22,13 +21,13 @@ static struct { | |||
22 | long jfs_flag; | 21 | long jfs_flag; |
23 | long ext2_flag; | 22 | long ext2_flag; |
24 | } jfs_map[] = { | 23 | } jfs_map[] = { |
25 | {JFS_NOATIME_FL, EXT2_NOATIME_FL}, | 24 | {JFS_NOATIME_FL, FS_NOATIME_FL}, |
26 | {JFS_DIRSYNC_FL, EXT2_DIRSYNC_FL}, | 25 | {JFS_DIRSYNC_FL, FS_DIRSYNC_FL}, |
27 | {JFS_SYNC_FL, EXT2_SYNC_FL}, | 26 | {JFS_SYNC_FL, FS_SYNC_FL}, |
28 | {JFS_SECRM_FL, EXT2_SECRM_FL}, | 27 | {JFS_SECRM_FL, FS_SECRM_FL}, |
29 | {JFS_UNRM_FL, EXT2_UNRM_FL}, | 28 | {JFS_UNRM_FL, FS_UNRM_FL}, |
30 | {JFS_APPEND_FL, EXT2_APPEND_FL}, | 29 | {JFS_APPEND_FL, FS_APPEND_FL}, |
31 | {JFS_IMMUTABLE_FL, EXT2_IMMUTABLE_FL}, | 30 | {JFS_IMMUTABLE_FL, FS_IMMUTABLE_FL}, |
32 | {0, 0}, | 31 | {0, 0}, |
33 | }; | 32 | }; |
34 | 33 | ||
diff --git a/fs/libfs.c b/fs/libfs.c index 8db5afb7b0a7..3793aaa14577 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -317,17 +317,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
317 | 317 | ||
318 | int simple_readpage(struct file *file, struct page *page) | 318 | int simple_readpage(struct file *file, struct page *page) |
319 | { | 319 | { |
320 | void *kaddr; | 320 | clear_highpage(page); |
321 | |||
322 | if (PageUptodate(page)) | ||
323 | goto out; | ||
324 | |||
325 | kaddr = kmap_atomic(page, KM_USER0); | ||
326 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
327 | kunmap_atomic(kaddr, KM_USER0); | ||
328 | flush_dcache_page(page); | 321 | flush_dcache_page(page); |
329 | SetPageUptodate(page); | 322 | SetPageUptodate(page); |
330 | out: | ||
331 | unlock_page(page); | 323 | unlock_page(page); |
332 | return 0; | 324 | return 0; |
333 | } | 325 | } |
diff --git a/fs/mbcache.c b/fs/mbcache.c index e4fde1ab22cd..0ff71256e65b 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c | |||
@@ -160,6 +160,7 @@ __mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask) | |||
160 | 160 | ||
161 | static void | 161 | static void |
162 | __mb_cache_entry_release_unlock(struct mb_cache_entry *ce) | 162 | __mb_cache_entry_release_unlock(struct mb_cache_entry *ce) |
163 | __releases(mb_cache_spinlock) | ||
163 | { | 164 | { |
164 | /* Wake up all processes queuing for this cache entry. */ | 165 | /* Wake up all processes queuing for this cache entry. */ |
165 | if (ce->e_queued) | 166 | if (ce->e_queued) |
diff --git a/fs/mpage.c b/fs/mpage.c index 1e4598247d0b..692a3e578fc8 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -693,6 +693,8 @@ out: | |||
693 | * the call was made get new I/O started against them. If wbc->sync_mode is | 693 | * the call was made get new I/O started against them. If wbc->sync_mode is |
694 | * WB_SYNC_ALL then we were called for data integrity and we must wait for | 694 | * WB_SYNC_ALL then we were called for data integrity and we must wait for |
695 | * existing IO to complete. | 695 | * existing IO to complete. |
696 | * | ||
697 | * If you fix this you should check generic_writepages() also! | ||
696 | */ | 698 | */ |
697 | int | 699 | int |
698 | mpage_writepages(struct address_space *mapping, | 700 | mpage_writepages(struct address_space *mapping, |
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index 9e44158a7540..d220165d4918 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c | |||
@@ -280,7 +280,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode, | |||
280 | struct nameidata *nd) | 280 | struct nameidata *nd) |
281 | { | 281 | { |
282 | struct super_block *sb = dir->i_sb; | 282 | struct super_block *sb = dir->i_sb; |
283 | struct inode *inode; | 283 | struct inode *inode = NULL; |
284 | struct fat_slot_info sinfo; | 284 | struct fat_slot_info sinfo; |
285 | struct timespec ts; | 285 | struct timespec ts; |
286 | unsigned char msdos_name[MSDOS_NAME]; | 286 | unsigned char msdos_name[MSDOS_NAME]; |
@@ -316,6 +316,8 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode, | |||
316 | d_instantiate(dentry, inode); | 316 | d_instantiate(dentry, inode); |
317 | out: | 317 | out: |
318 | unlock_kernel(); | 318 | unlock_kernel(); |
319 | if (!err) | ||
320 | err = fat_flush_inodes(sb, dir, inode); | ||
319 | return err; | 321 | return err; |
320 | } | 322 | } |
321 | 323 | ||
@@ -348,6 +350,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) | |||
348 | fat_detach(inode); | 350 | fat_detach(inode); |
349 | out: | 351 | out: |
350 | unlock_kernel(); | 352 | unlock_kernel(); |
353 | if (!err) | ||
354 | err = fat_flush_inodes(inode->i_sb, dir, inode); | ||
351 | 355 | ||
352 | return err; | 356 | return err; |
353 | } | 357 | } |
@@ -401,6 +405,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
401 | d_instantiate(dentry, inode); | 405 | d_instantiate(dentry, inode); |
402 | 406 | ||
403 | unlock_kernel(); | 407 | unlock_kernel(); |
408 | fat_flush_inodes(sb, dir, inode); | ||
404 | return 0; | 409 | return 0; |
405 | 410 | ||
406 | out_free: | 411 | out_free: |
@@ -430,6 +435,8 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry) | |||
430 | fat_detach(inode); | 435 | fat_detach(inode); |
431 | out: | 436 | out: |
432 | unlock_kernel(); | 437 | unlock_kernel(); |
438 | if (!err) | ||
439 | err = fat_flush_inodes(inode->i_sb, dir, inode); | ||
433 | 440 | ||
434 | return err; | 441 | return err; |
435 | } | 442 | } |
@@ -635,6 +642,8 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
635 | new_dir, new_msdos_name, new_dentry, is_hid); | 642 | new_dir, new_msdos_name, new_dentry, is_hid); |
636 | out: | 643 | out: |
637 | unlock_kernel(); | 644 | unlock_kernel(); |
645 | if (!err) | ||
646 | err = fat_flush_inodes(old_dir->i_sb, old_dir, new_dir); | ||
638 | return err; | 647 | return err; |
639 | } | 648 | } |
640 | 649 | ||
diff --git a/fs/namei.c b/fs/namei.c index 808e4ea2bb94..2892e68d3a86 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -518,18 +518,20 @@ static int __emul_lookup_dentry(const char *, struct nameidata *); | |||
518 | static __always_inline int | 518 | static __always_inline int |
519 | walk_init_root(const char *name, struct nameidata *nd) | 519 | walk_init_root(const char *name, struct nameidata *nd) |
520 | { | 520 | { |
521 | read_lock(¤t->fs->lock); | 521 | struct fs_struct *fs = current->fs; |
522 | if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 522 | |
523 | nd->mnt = mntget(current->fs->altrootmnt); | 523 | read_lock(&fs->lock); |
524 | nd->dentry = dget(current->fs->altroot); | 524 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { |
525 | read_unlock(¤t->fs->lock); | 525 | nd->mnt = mntget(fs->altrootmnt); |
526 | nd->dentry = dget(fs->altroot); | ||
527 | read_unlock(&fs->lock); | ||
526 | if (__emul_lookup_dentry(name,nd)) | 528 | if (__emul_lookup_dentry(name,nd)) |
527 | return 0; | 529 | return 0; |
528 | read_lock(¤t->fs->lock); | 530 | read_lock(&fs->lock); |
529 | } | 531 | } |
530 | nd->mnt = mntget(current->fs->rootmnt); | 532 | nd->mnt = mntget(fs->rootmnt); |
531 | nd->dentry = dget(current->fs->root); | 533 | nd->dentry = dget(fs->root); |
532 | read_unlock(¤t->fs->lock); | 534 | read_unlock(&fs->lock); |
533 | return 1; | 535 | return 1; |
534 | } | 536 | } |
535 | 537 | ||
@@ -724,17 +726,19 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry) | |||
724 | 726 | ||
725 | static __always_inline void follow_dotdot(struct nameidata *nd) | 727 | static __always_inline void follow_dotdot(struct nameidata *nd) |
726 | { | 728 | { |
729 | struct fs_struct *fs = current->fs; | ||
730 | |||
727 | while(1) { | 731 | while(1) { |
728 | struct vfsmount *parent; | 732 | struct vfsmount *parent; |
729 | struct dentry *old = nd->dentry; | 733 | struct dentry *old = nd->dentry; |
730 | 734 | ||
731 | read_lock(¤t->fs->lock); | 735 | read_lock(&fs->lock); |
732 | if (nd->dentry == current->fs->root && | 736 | if (nd->dentry == fs->root && |
733 | nd->mnt == current->fs->rootmnt) { | 737 | nd->mnt == fs->rootmnt) { |
734 | read_unlock(¤t->fs->lock); | 738 | read_unlock(&fs->lock); |
735 | break; | 739 | break; |
736 | } | 740 | } |
737 | read_unlock(¤t->fs->lock); | 741 | read_unlock(&fs->lock); |
738 | spin_lock(&dcache_lock); | 742 | spin_lock(&dcache_lock); |
739 | if (nd->dentry != nd->mnt->mnt_root) { | 743 | if (nd->dentry != nd->mnt->mnt_root) { |
740 | nd->dentry = dget(nd->dentry->d_parent); | 744 | nd->dentry = dget(nd->dentry->d_parent); |
@@ -1042,15 +1046,17 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) | |||
1042 | struct vfsmount *old_mnt = nd->mnt; | 1046 | struct vfsmount *old_mnt = nd->mnt; |
1043 | struct qstr last = nd->last; | 1047 | struct qstr last = nd->last; |
1044 | int last_type = nd->last_type; | 1048 | int last_type = nd->last_type; |
1049 | struct fs_struct *fs = current->fs; | ||
1050 | |||
1045 | /* | 1051 | /* |
1046 | * NAME was not found in alternate root or it's a directory. Try to find | 1052 | * NAME was not found in alternate root or it's a directory. |
1047 | * it in the normal root: | 1053 | * Try to find it in the normal root: |
1048 | */ | 1054 | */ |
1049 | nd->last_type = LAST_ROOT; | 1055 | nd->last_type = LAST_ROOT; |
1050 | read_lock(¤t->fs->lock); | 1056 | read_lock(&fs->lock); |
1051 | nd->mnt = mntget(current->fs->rootmnt); | 1057 | nd->mnt = mntget(fs->rootmnt); |
1052 | nd->dentry = dget(current->fs->root); | 1058 | nd->dentry = dget(fs->root); |
1053 | read_unlock(¤t->fs->lock); | 1059 | read_unlock(&fs->lock); |
1054 | if (path_walk(name, nd) == 0) { | 1060 | if (path_walk(name, nd) == 0) { |
1055 | if (nd->dentry->d_inode) { | 1061 | if (nd->dentry->d_inode) { |
1056 | dput(old_dentry); | 1062 | dput(old_dentry); |
@@ -1074,6 +1080,7 @@ void set_fs_altroot(void) | |||
1074 | struct vfsmount *mnt = NULL, *oldmnt; | 1080 | struct vfsmount *mnt = NULL, *oldmnt; |
1075 | struct dentry *dentry = NULL, *olddentry; | 1081 | struct dentry *dentry = NULL, *olddentry; |
1076 | int err; | 1082 | int err; |
1083 | struct fs_struct *fs = current->fs; | ||
1077 | 1084 | ||
1078 | if (!emul) | 1085 | if (!emul) |
1079 | goto set_it; | 1086 | goto set_it; |
@@ -1083,12 +1090,12 @@ void set_fs_altroot(void) | |||
1083 | dentry = nd.dentry; | 1090 | dentry = nd.dentry; |
1084 | } | 1091 | } |
1085 | set_it: | 1092 | set_it: |
1086 | write_lock(¤t->fs->lock); | 1093 | write_lock(&fs->lock); |
1087 | oldmnt = current->fs->altrootmnt; | 1094 | oldmnt = fs->altrootmnt; |
1088 | olddentry = current->fs->altroot; | 1095 | olddentry = fs->altroot; |
1089 | current->fs->altrootmnt = mnt; | 1096 | fs->altrootmnt = mnt; |
1090 | current->fs->altroot = dentry; | 1097 | fs->altroot = dentry; |
1091 | write_unlock(¤t->fs->lock); | 1098 | write_unlock(&fs->lock); |
1092 | if (olddentry) { | 1099 | if (olddentry) { |
1093 | dput(olddentry); | 1100 | dput(olddentry); |
1094 | mntput(oldmnt); | 1101 | mntput(oldmnt); |
@@ -1102,29 +1109,30 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
1102 | int retval = 0; | 1109 | int retval = 0; |
1103 | int fput_needed; | 1110 | int fput_needed; |
1104 | struct file *file; | 1111 | struct file *file; |
1112 | struct fs_struct *fs = current->fs; | ||
1105 | 1113 | ||
1106 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ | 1114 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ |
1107 | nd->flags = flags; | 1115 | nd->flags = flags; |
1108 | nd->depth = 0; | 1116 | nd->depth = 0; |
1109 | 1117 | ||
1110 | if (*name=='/') { | 1118 | if (*name=='/') { |
1111 | read_lock(¤t->fs->lock); | 1119 | read_lock(&fs->lock); |
1112 | if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 1120 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { |
1113 | nd->mnt = mntget(current->fs->altrootmnt); | 1121 | nd->mnt = mntget(fs->altrootmnt); |
1114 | nd->dentry = dget(current->fs->altroot); | 1122 | nd->dentry = dget(fs->altroot); |
1115 | read_unlock(¤t->fs->lock); | 1123 | read_unlock(&fs->lock); |
1116 | if (__emul_lookup_dentry(name,nd)) | 1124 | if (__emul_lookup_dentry(name,nd)) |
1117 | goto out; /* found in altroot */ | 1125 | goto out; /* found in altroot */ |
1118 | read_lock(¤t->fs->lock); | 1126 | read_lock(&fs->lock); |
1119 | } | 1127 | } |
1120 | nd->mnt = mntget(current->fs->rootmnt); | 1128 | nd->mnt = mntget(fs->rootmnt); |
1121 | nd->dentry = dget(current->fs->root); | 1129 | nd->dentry = dget(fs->root); |
1122 | read_unlock(¤t->fs->lock); | 1130 | read_unlock(&fs->lock); |
1123 | } else if (dfd == AT_FDCWD) { | 1131 | } else if (dfd == AT_FDCWD) { |
1124 | read_lock(¤t->fs->lock); | 1132 | read_lock(&fs->lock); |
1125 | nd->mnt = mntget(current->fs->pwdmnt); | 1133 | nd->mnt = mntget(fs->pwdmnt); |
1126 | nd->dentry = dget(current->fs->pwd); | 1134 | nd->dentry = dget(fs->pwd); |
1127 | read_unlock(¤t->fs->lock); | 1135 | read_unlock(&fs->lock); |
1128 | } else { | 1136 | } else { |
1129 | struct dentry *dentry; | 1137 | struct dentry *dentry; |
1130 | 1138 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 36d180858136..66d921e14fee 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/smp_lock.h> | 14 | #include <linux/smp_lock.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/kernel.h> | ||
16 | #include <linux/quotaops.h> | 17 | #include <linux/quotaops.h> |
17 | #include <linux/acct.h> | 18 | #include <linux/acct.h> |
18 | #include <linux/capability.h> | 19 | #include <linux/capability.h> |
@@ -23,12 +24,11 @@ | |||
23 | #include <linux/namei.h> | 24 | #include <linux/namei.h> |
24 | #include <linux/security.h> | 25 | #include <linux/security.h> |
25 | #include <linux/mount.h> | 26 | #include <linux/mount.h> |
27 | #include <linux/ramfs.h> | ||
26 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
27 | #include <asm/unistd.h> | 29 | #include <asm/unistd.h> |
28 | #include "pnode.h" | 30 | #include "pnode.h" |
29 | 31 | ||
30 | extern int __init init_rootfs(void); | ||
31 | |||
32 | /* spinlock for vfsmount related operations, inplace of dcache_lock */ | 32 | /* spinlock for vfsmount related operations, inplace of dcache_lock */ |
33 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); | 33 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); |
34 | 34 | ||
@@ -1813,6 +1813,7 @@ void __init mnt_init(unsigned long mempages) | |||
1813 | struct list_head *d; | 1813 | struct list_head *d; |
1814 | unsigned int nr_hash; | 1814 | unsigned int nr_hash; |
1815 | int i; | 1815 | int i; |
1816 | int err; | ||
1816 | 1817 | ||
1817 | init_rwsem(&namespace_sem); | 1818 | init_rwsem(&namespace_sem); |
1818 | 1819 | ||
@@ -1853,8 +1854,14 @@ void __init mnt_init(unsigned long mempages) | |||
1853 | d++; | 1854 | d++; |
1854 | i--; | 1855 | i--; |
1855 | } while (i); | 1856 | } while (i); |
1856 | sysfs_init(); | 1857 | err = sysfs_init(); |
1857 | subsystem_register(&fs_subsys); | 1858 | if (err) |
1859 | printk(KERN_WARNING "%s: sysfs_init error: %d\n", | ||
1860 | __FUNCTION__, err); | ||
1861 | err = subsystem_register(&fs_subsys); | ||
1862 | if (err) | ||
1863 | printk(KERN_WARNING "%s: subsystem_register error: %d\n", | ||
1864 | __FUNCTION__, err); | ||
1858 | init_rootfs(); | 1865 | init_rootfs(); |
1859 | init_mount_tree(); | 1866 | init_mount_tree(); |
1860 | } | 1867 | } |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b674462793d3..f6675d2c386c 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <linux/mm.h> | 51 | #include <linux/mm.h> |
52 | #include <linux/pagemap.h> | 52 | #include <linux/pagemap.h> |
53 | #include <linux/file.h> | 53 | #include <linux/file.h> |
54 | #include <linux/mpage.h> | ||
55 | #include <linux/writeback.h> | 54 | #include <linux/writeback.h> |
56 | 55 | ||
57 | #include <linux/sunrpc/clnt.h> | 56 | #include <linux/sunrpc/clnt.h> |
diff --git a/fs/no-block.c b/fs/no-block.c new file mode 100644 index 000000000000..d269a93d3467 --- /dev/null +++ b/fs/no-block.c | |||
@@ -0,0 +1,22 @@ | |||
1 | /* no-block.c: implementation of routines required for non-BLOCK configuration | ||
2 | * | ||
3 | * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/fs.h> | ||
14 | |||
15 | static int no_blkdev_open(struct inode * inode, struct file * filp) | ||
16 | { | ||
17 | return -ENODEV; | ||
18 | } | ||
19 | |||
20 | const struct file_operations def_blk_fops = { | ||
21 | .open = no_blkdev_open, | ||
22 | }; | ||
@@ -546,7 +546,8 @@ asmlinkage long sys_chdir(const char __user * filename) | |||
546 | struct nameidata nd; | 546 | struct nameidata nd; |
547 | int error; | 547 | int error; |
548 | 548 | ||
549 | error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd); | 549 | error = __user_walk(filename, |
550 | LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd); | ||
550 | if (error) | 551 | if (error) |
551 | goto out; | 552 | goto out; |
552 | 553 | ||
@@ -1172,6 +1173,7 @@ asmlinkage long sys_close(unsigned int fd) | |||
1172 | struct file * filp; | 1173 | struct file * filp; |
1173 | struct files_struct *files = current->files; | 1174 | struct files_struct *files = current->files; |
1174 | struct fdtable *fdt; | 1175 | struct fdtable *fdt; |
1176 | int retval; | ||
1175 | 1177 | ||
1176 | spin_lock(&files->file_lock); | 1178 | spin_lock(&files->file_lock); |
1177 | fdt = files_fdtable(files); | 1179 | fdt = files_fdtable(files); |
@@ -1184,7 +1186,16 @@ asmlinkage long sys_close(unsigned int fd) | |||
1184 | FD_CLR(fd, fdt->close_on_exec); | 1186 | FD_CLR(fd, fdt->close_on_exec); |
1185 | __put_unused_fd(files, fd); | 1187 | __put_unused_fd(files, fd); |
1186 | spin_unlock(&files->file_lock); | 1188 | spin_unlock(&files->file_lock); |
1187 | return filp_close(filp, files); | 1189 | retval = filp_close(filp, files); |
1190 | |||
1191 | /* can't restart close syscall because file table entry was cleared */ | ||
1192 | if (unlikely(retval == -ERESTARTSYS || | ||
1193 | retval == -ERESTARTNOINTR || | ||
1194 | retval == -ERESTARTNOHAND || | ||
1195 | retval == -ERESTART_RESTARTBLOCK)) | ||
1196 | retval = -EINTR; | ||
1197 | |||
1198 | return retval; | ||
1188 | 1199 | ||
1189 | out_unlock: | 1200 | out_unlock: |
1190 | spin_unlock(&files->file_lock); | 1201 | spin_unlock(&files->file_lock); |
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index d713ce6b3e12..67e665fdb7fc 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := check.o | 5 | obj-$(CONFIG_BLOCK) := check.o |
6 | 6 | ||
7 | obj-$(CONFIG_ACORN_PARTITION) += acorn.o | 7 | obj-$(CONFIG_ACORN_PARTITION) += acorn.o |
8 | obj-$(CONFIG_AMIGA_PARTITION) += amiga.o | 8 | obj-$(CONFIG_AMIGA_PARTITION) += amiga.o |
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 8f12587c3129..4f8df71e49d3 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c | |||
@@ -58,6 +58,31 @@ msdos_magic_present(unsigned char *p) | |||
58 | return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); | 58 | return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); |
59 | } | 59 | } |
60 | 60 | ||
61 | /* Value is EBCDIC 'IBMA' */ | ||
62 | #define AIX_LABEL_MAGIC1 0xC9 | ||
63 | #define AIX_LABEL_MAGIC2 0xC2 | ||
64 | #define AIX_LABEL_MAGIC3 0xD4 | ||
65 | #define AIX_LABEL_MAGIC4 0xC1 | ||
66 | static int aix_magic_present(unsigned char *p, struct block_device *bdev) | ||
67 | { | ||
68 | Sector sect; | ||
69 | unsigned char *d; | ||
70 | int ret = 0; | ||
71 | |||
72 | if (p[0] != AIX_LABEL_MAGIC1 && | ||
73 | p[1] != AIX_LABEL_MAGIC2 && | ||
74 | p[2] != AIX_LABEL_MAGIC3 && | ||
75 | p[3] != AIX_LABEL_MAGIC4) | ||
76 | return 0; | ||
77 | d = read_dev_sector(bdev, 7, §); | ||
78 | if (d) { | ||
79 | if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M') | ||
80 | ret = 1; | ||
81 | put_dev_sector(sect); | ||
82 | }; | ||
83 | return ret; | ||
84 | } | ||
85 | |||
61 | /* | 86 | /* |
62 | * Create devices for each logical partition in an extended partition. | 87 | * Create devices for each logical partition in an extended partition. |
63 | * The logical partitions form a linked list, with each entry being | 88 | * The logical partitions form a linked list, with each entry being |
@@ -393,6 +418,12 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
393 | return 0; | 418 | return 0; |
394 | } | 419 | } |
395 | 420 | ||
421 | if (aix_magic_present(data, bdev)) { | ||
422 | put_dev_sector(sect); | ||
423 | printk( " [AIX]"); | ||
424 | return 0; | ||
425 | } | ||
426 | |||
396 | /* | 427 | /* |
397 | * Now that the 55aa signature is present, this is probably | 428 | * Now that the 55aa signature is present, this is probably |
398 | * either the boot sector of a FAT filesystem or a DOS-type | 429 | * either the boot sector of a FAT filesystem or a DOS-type |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 0b615d62a159..c0e554971df0 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -347,6 +347,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
347 | sigemptyset(&sigign); | 347 | sigemptyset(&sigign); |
348 | sigemptyset(&sigcatch); | 348 | sigemptyset(&sigcatch); |
349 | cutime = cstime = utime = stime = cputime_zero; | 349 | cutime = cstime = utime = stime = cputime_zero; |
350 | |||
351 | mutex_lock(&tty_mutex); | ||
350 | read_lock(&tasklist_lock); | 352 | read_lock(&tasklist_lock); |
351 | if (task->sighand) { | 353 | if (task->sighand) { |
352 | spin_lock_irq(&task->sighand->siglock); | 354 | spin_lock_irq(&task->sighand->siglock); |
@@ -388,6 +390,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
388 | } | 390 | } |
389 | ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0; | 391 | ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0; |
390 | read_unlock(&tasklist_lock); | 392 | read_unlock(&tasklist_lock); |
393 | mutex_unlock(&tty_mutex); | ||
391 | 394 | ||
392 | if (!whole || num_threads<2) | 395 | if (!whole || num_threads<2) |
393 | wchan = get_wchan(task); | 396 | wchan = get_wchan(task); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index fe8d55fb17cc..89c20d9d50bf 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -797,7 +797,7 @@ out_no_task: | |||
797 | static ssize_t mem_write(struct file * file, const char * buf, | 797 | static ssize_t mem_write(struct file * file, const char * buf, |
798 | size_t count, loff_t *ppos) | 798 | size_t count, loff_t *ppos) |
799 | { | 799 | { |
800 | int copied = 0; | 800 | int copied; |
801 | char *page; | 801 | char *page; |
802 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); | 802 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); |
803 | unsigned long dst = *ppos; | 803 | unsigned long dst = *ppos; |
@@ -814,6 +814,7 @@ static ssize_t mem_write(struct file * file, const char * buf, | |||
814 | if (!page) | 814 | if (!page) |
815 | goto out; | 815 | goto out; |
816 | 816 | ||
817 | copied = 0; | ||
817 | while (count > 0) { | 818 | while (count > 0) { |
818 | int this_len, retval; | 819 | int this_len, retval; |
819 | 820 | ||
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 3ceff3857272..1294eda4acae 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -100,7 +100,7 @@ static int notesize(struct memelfnote *en) | |||
100 | int sz; | 100 | int sz; |
101 | 101 | ||
102 | sz = sizeof(struct elf_note); | 102 | sz = sizeof(struct elf_note); |
103 | sz += roundup(strlen(en->name), 4); | 103 | sz += roundup((strlen(en->name) + 1), 4); |
104 | sz += roundup(en->datasz, 4); | 104 | sz += roundup(en->datasz, 4); |
105 | 105 | ||
106 | return sz; | 106 | return sz; |
@@ -116,7 +116,7 @@ static char *storenote(struct memelfnote *men, char *bufp) | |||
116 | 116 | ||
117 | #define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0) | 117 | #define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0) |
118 | 118 | ||
119 | en.n_namesz = strlen(men->name); | 119 | en.n_namesz = strlen(men->name) + 1; |
120 | en.n_descsz = men->datasz; | 120 | en.n_descsz = men->datasz; |
121 | en.n_type = men->type; | 121 | en.n_type = men->type; |
122 | 122 | ||
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 5bbd60896050..66bc425f2f3d 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -277,12 +277,15 @@ static int devinfo_show(struct seq_file *f, void *v) | |||
277 | if (i == 0) | 277 | if (i == 0) |
278 | seq_printf(f, "Character devices:\n"); | 278 | seq_printf(f, "Character devices:\n"); |
279 | chrdev_show(f, i); | 279 | chrdev_show(f, i); |
280 | } else { | 280 | } |
281 | #ifdef CONFIG_BLOCK | ||
282 | else { | ||
281 | i -= CHRDEV_MAJOR_HASH_SIZE; | 283 | i -= CHRDEV_MAJOR_HASH_SIZE; |
282 | if (i == 0) | 284 | if (i == 0) |
283 | seq_printf(f, "\nBlock devices:\n"); | 285 | seq_printf(f, "\nBlock devices:\n"); |
284 | blkdev_show(f, i); | 286 | blkdev_show(f, i); |
285 | } | 287 | } |
288 | #endif | ||
286 | return 0; | 289 | return 0; |
287 | } | 290 | } |
288 | 291 | ||
@@ -355,6 +358,7 @@ static int stram_read_proc(char *page, char **start, off_t off, | |||
355 | } | 358 | } |
356 | #endif | 359 | #endif |
357 | 360 | ||
361 | #ifdef CONFIG_BLOCK | ||
358 | extern struct seq_operations partitions_op; | 362 | extern struct seq_operations partitions_op; |
359 | static int partitions_open(struct inode *inode, struct file *file) | 363 | static int partitions_open(struct inode *inode, struct file *file) |
360 | { | 364 | { |
@@ -378,6 +382,7 @@ static struct file_operations proc_diskstats_operations = { | |||
378 | .llseek = seq_lseek, | 382 | .llseek = seq_lseek, |
379 | .release = seq_release, | 383 | .release = seq_release, |
380 | }; | 384 | }; |
385 | #endif | ||
381 | 386 | ||
382 | #ifdef CONFIG_MODULES | 387 | #ifdef CONFIG_MODULES |
383 | extern struct seq_operations modules_op; | 388 | extern struct seq_operations modules_op; |
@@ -695,7 +700,9 @@ void __init proc_misc_init(void) | |||
695 | entry->proc_fops = &proc_kmsg_operations; | 700 | entry->proc_fops = &proc_kmsg_operations; |
696 | create_seq_entry("devices", 0, &proc_devinfo_operations); | 701 | create_seq_entry("devices", 0, &proc_devinfo_operations); |
697 | create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); | 702 | create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); |
703 | #ifdef CONFIG_BLOCK | ||
698 | create_seq_entry("partitions", 0, &proc_partitions_operations); | 704 | create_seq_entry("partitions", 0, &proc_partitions_operations); |
705 | #endif | ||
699 | create_seq_entry("stat", 0, &proc_stat_operations); | 706 | create_seq_entry("stat", 0, &proc_stat_operations); |
700 | create_seq_entry("interrupts", 0, &proc_interrupts_operations); | 707 | create_seq_entry("interrupts", 0, &proc_interrupts_operations); |
701 | #ifdef CONFIG_SLAB | 708 | #ifdef CONFIG_SLAB |
@@ -707,7 +714,9 @@ void __init proc_misc_init(void) | |||
707 | create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); | 714 | create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); |
708 | create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); | 715 | create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); |
709 | create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); | 716 | create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); |
717 | #ifdef CONFIG_BLOCK | ||
710 | create_seq_entry("diskstats", 0, &proc_diskstats_operations); | 718 | create_seq_entry("diskstats", 0, &proc_diskstats_operations); |
719 | #endif | ||
711 | #ifdef CONFIG_MODULES | 720 | #ifdef CONFIG_MODULES |
712 | create_seq_entry("modules", 0, &proc_modules_operations); | 721 | create_seq_entry("modules", 0, &proc_modules_operations); |
713 | #endif | 722 | #endif |
diff --git a/fs/quota.c b/fs/quota.c index d6a2be826e29..b9dae76a0b6e 100644 --- a/fs/quota.c +++ b/fs/quota.c | |||
@@ -338,6 +338,34 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void | |||
338 | } | 338 | } |
339 | 339 | ||
340 | /* | 340 | /* |
341 | * look up a superblock on which quota ops will be performed | ||
342 | * - use the name of a block device to find the superblock thereon | ||
343 | */ | ||
344 | static inline struct super_block *quotactl_block(const char __user *special) | ||
345 | { | ||
346 | #ifdef CONFIG_BLOCK | ||
347 | struct block_device *bdev; | ||
348 | struct super_block *sb; | ||
349 | char *tmp = getname(special); | ||
350 | |||
351 | if (IS_ERR(tmp)) | ||
352 | return ERR_PTR(PTR_ERR(tmp)); | ||
353 | bdev = lookup_bdev(tmp); | ||
354 | putname(tmp); | ||
355 | if (IS_ERR(bdev)) | ||
356 | return ERR_PTR(PTR_ERR(bdev)); | ||
357 | sb = get_super(bdev); | ||
358 | bdput(bdev); | ||
359 | if (!sb) | ||
360 | return ERR_PTR(-ENODEV); | ||
361 | |||
362 | return sb; | ||
363 | #else | ||
364 | return ERR_PTR(-ENODEV); | ||
365 | #endif | ||
366 | } | ||
367 | |||
368 | /* | ||
341 | * This is the system call interface. This communicates with | 369 | * This is the system call interface. This communicates with |
342 | * the user-level programs. Currently this only supports diskquota | 370 | * the user-level programs. Currently this only supports diskquota |
343 | * calls. Maybe we need to add the process quotas etc. in the future, | 371 | * calls. Maybe we need to add the process quotas etc. in the future, |
@@ -347,25 +375,15 @@ asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t | |||
347 | { | 375 | { |
348 | uint cmds, type; | 376 | uint cmds, type; |
349 | struct super_block *sb = NULL; | 377 | struct super_block *sb = NULL; |
350 | struct block_device *bdev; | ||
351 | char *tmp; | ||
352 | int ret; | 378 | int ret; |
353 | 379 | ||
354 | cmds = cmd >> SUBCMDSHIFT; | 380 | cmds = cmd >> SUBCMDSHIFT; |
355 | type = cmd & SUBCMDMASK; | 381 | type = cmd & SUBCMDMASK; |
356 | 382 | ||
357 | if (cmds != Q_SYNC || special) { | 383 | if (cmds != Q_SYNC || special) { |
358 | tmp = getname(special); | 384 | sb = quotactl_block(special); |
359 | if (IS_ERR(tmp)) | 385 | if (IS_ERR(sb)) |
360 | return PTR_ERR(tmp); | 386 | return PTR_ERR(sb); |
361 | bdev = lookup_bdev(tmp); | ||
362 | putname(tmp); | ||
363 | if (IS_ERR(bdev)) | ||
364 | return PTR_ERR(bdev); | ||
365 | sb = get_super(bdev); | ||
366 | bdput(bdev); | ||
367 | if (!sb) | ||
368 | return -ENODEV; | ||
369 | } | 387 | } |
370 | 388 | ||
371 | ret = check_quotactl_valid(sb, type, cmds, id); | 389 | ret = check_quotactl_valid(sb, type, cmds, id); |
diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile index 3a59309f3ca9..0eb7ac080484 100644 --- a/fs/reiserfs/Makefile +++ b/fs/reiserfs/Makefile | |||
@@ -28,7 +28,7 @@ endif | |||
28 | # will work around it. If any other architecture displays this behavior, | 28 | # will work around it. If any other architecture displays this behavior, |
29 | # add it here. | 29 | # add it here. |
30 | ifeq ($(CONFIG_PPC32),y) | 30 | ifeq ($(CONFIG_PPC32),y) |
31 | EXTRA_CFLAGS := -O1 | 31 | EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0400, -O1) |
32 | endif | 32 | endif |
33 | 33 | ||
34 | TAGS: | 34 | TAGS: |
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 9aabcc0ccd2d..657050ad7430 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -22,6 +22,9 @@ const struct file_operations reiserfs_dir_operations = { | |||
22 | .readdir = reiserfs_readdir, | 22 | .readdir = reiserfs_readdir, |
23 | .fsync = reiserfs_dir_fsync, | 23 | .fsync = reiserfs_dir_fsync, |
24 | .ioctl = reiserfs_ioctl, | 24 | .ioctl = reiserfs_ioctl, |
25 | #ifdef CONFIG_COMPAT | ||
26 | .compat_ioctl = reiserfs_compat_ioctl, | ||
27 | #endif | ||
25 | }; | 28 | }; |
26 | 29 | ||
27 | static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, | 30 | static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 1627edd50810..3e08f7161a3d 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README | 2 | * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/config.h> | ||
5 | #include <linux/time.h> | 6 | #include <linux/time.h> |
6 | #include <linux/reiserfs_fs.h> | 7 | #include <linux/reiserfs_fs.h> |
7 | #include <linux/reiserfs_acl.h> | 8 | #include <linux/reiserfs_acl.h> |
@@ -130,7 +131,7 @@ static int reiserfs_sync_file(struct file *p_s_filp, | |||
130 | reiserfs_write_lock(p_s_inode->i_sb); | 131 | reiserfs_write_lock(p_s_inode->i_sb); |
131 | barrier_done = reiserfs_commit_for_inode(p_s_inode); | 132 | barrier_done = reiserfs_commit_for_inode(p_s_inode); |
132 | reiserfs_write_unlock(p_s_inode->i_sb); | 133 | reiserfs_write_unlock(p_s_inode->i_sb); |
133 | if (barrier_done != 1) | 134 | if (barrier_done != 1 && reiserfs_barrier_flush(p_s_inode->i_sb)) |
134 | blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL); | 135 | blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL); |
135 | if (barrier_done < 0) | 136 | if (barrier_done < 0) |
136 | return barrier_done; | 137 | return barrier_done; |
@@ -1568,6 +1569,9 @@ const struct file_operations reiserfs_file_operations = { | |||
1568 | .read = generic_file_read, | 1569 | .read = generic_file_read, |
1569 | .write = reiserfs_file_write, | 1570 | .write = reiserfs_file_write, |
1570 | .ioctl = reiserfs_ioctl, | 1571 | .ioctl = reiserfs_ioctl, |
1572 | #ifdef CONFIG_COMPAT | ||
1573 | .compat_ioctl = reiserfs_compat_ioctl, | ||
1574 | #endif | ||
1571 | .mmap = generic_file_mmap, | 1575 | .mmap = generic_file_mmap, |
1572 | .release = reiserfs_file_release, | 1576 | .release = reiserfs_file_release, |
1573 | .fsync = reiserfs_sync_file, | 1577 | .fsync = reiserfs_sync_file, |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 8810fda0da46..7e5a2f5ebeb0 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1127,9 +1127,9 @@ static void init_inode(struct inode *inode, struct path *path) | |||
1127 | REISERFS_I(inode)->i_prealloc_count = 0; | 1127 | REISERFS_I(inode)->i_prealloc_count = 0; |
1128 | REISERFS_I(inode)->i_trans_id = 0; | 1128 | REISERFS_I(inode)->i_trans_id = 0; |
1129 | REISERFS_I(inode)->i_jl = NULL; | 1129 | REISERFS_I(inode)->i_jl = NULL; |
1130 | REISERFS_I(inode)->i_acl_access = NULL; | 1130 | reiserfs_init_acl_access(inode); |
1131 | REISERFS_I(inode)->i_acl_default = NULL; | 1131 | reiserfs_init_acl_default(inode); |
1132 | init_rwsem(&REISERFS_I(inode)->xattr_sem); | 1132 | reiserfs_init_xattr_rwsem(inode); |
1133 | 1133 | ||
1134 | if (stat_data_v1(ih)) { | 1134 | if (stat_data_v1(ih)) { |
1135 | struct stat_data_v1 *sd = | 1135 | struct stat_data_v1 *sd = |
@@ -1834,9 +1834,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1834 | REISERFS_I(inode)->i_attrs = | 1834 | REISERFS_I(inode)->i_attrs = |
1835 | REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; | 1835 | REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; |
1836 | sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); | 1836 | sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); |
1837 | REISERFS_I(inode)->i_acl_access = NULL; | 1837 | reiserfs_init_acl_access(inode); |
1838 | REISERFS_I(inode)->i_acl_default = NULL; | 1838 | reiserfs_init_acl_default(inode); |
1839 | init_rwsem(&REISERFS_I(inode)->xattr_sem); | 1839 | reiserfs_init_xattr_rwsem(inode); |
1840 | 1840 | ||
1841 | if (old_format_only(sb)) | 1841 | if (old_format_only(sb)) |
1842 | make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, | 1842 | make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, |
@@ -1974,11 +1974,13 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1974 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking | 1974 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking |
1975 | * code really needs to be reworked, but this will take care of it | 1975 | * code really needs to be reworked, but this will take care of it |
1976 | * for now. -jeffm */ | 1976 | * for now. -jeffm */ |
1977 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
1977 | if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) { | 1978 | if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) { |
1978 | reiserfs_write_unlock_xattrs(dir->i_sb); | 1979 | reiserfs_write_unlock_xattrs(dir->i_sb); |
1979 | iput(inode); | 1980 | iput(inode); |
1980 | reiserfs_write_lock_xattrs(dir->i_sb); | 1981 | reiserfs_write_lock_xattrs(dir->i_sb); |
1981 | } else | 1982 | } else |
1983 | #endif | ||
1982 | iput(inode); | 1984 | iput(inode); |
1983 | return err; | 1985 | return err; |
1984 | } | 1986 | } |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index a986b5e1e288..9c57578cb831 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
10 | #include <linux/pagemap.h> | 10 | #include <linux/pagemap.h> |
11 | #include <linux/smp_lock.h> | 11 | #include <linux/smp_lock.h> |
12 | #include <linux/compat.h> | ||
12 | 13 | ||
13 | static int reiserfs_unpack(struct inode *inode, struct file *filp); | 14 | static int reiserfs_unpack(struct inode *inode, struct file *filp); |
14 | 15 | ||
@@ -94,6 +95,40 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
94 | } | 95 | } |
95 | } | 96 | } |
96 | 97 | ||
98 | #ifdef CONFIG_COMPAT | ||
99 | long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, | ||
100 | unsigned long arg) | ||
101 | { | ||
102 | struct inode *inode = file->f_dentry->d_inode; | ||
103 | int ret; | ||
104 | |||
105 | /* These are just misnamed, they actually get/put from/to user an int */ | ||
106 | switch (cmd) { | ||
107 | case REISERFS_IOC32_UNPACK: | ||
108 | cmd = REISERFS_IOC_UNPACK; | ||
109 | break; | ||
110 | case REISERFS_IOC32_GETFLAGS: | ||
111 | cmd = REISERFS_IOC_GETFLAGS; | ||
112 | break; | ||
113 | case REISERFS_IOC32_SETFLAGS: | ||
114 | cmd = REISERFS_IOC_SETFLAGS; | ||
115 | break; | ||
116 | case REISERFS_IOC32_GETVERSION: | ||
117 | cmd = REISERFS_IOC_GETVERSION; | ||
118 | break; | ||
119 | case REISERFS_IOC32_SETVERSION: | ||
120 | cmd = REISERFS_IOC_SETVERSION; | ||
121 | break; | ||
122 | default: | ||
123 | return -ENOIOCTLCMD; | ||
124 | } | ||
125 | lock_kernel(); | ||
126 | ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | ||
127 | unlock_kernel(); | ||
128 | return ret; | ||
129 | } | ||
130 | #endif | ||
131 | |||
97 | /* | 132 | /* |
98 | ** reiserfs_unpack | 133 | ** reiserfs_unpack |
99 | ** Function try to convert tail from direct item into indirect. | 134 | ** Function try to convert tail from direct item into indirect. |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 9b3672d69367..e6b5ccf23f15 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -1186,6 +1186,21 @@ static struct reiserfs_journal_list *find_newer_jl_for_cn(struct | |||
1186 | return NULL; | 1186 | return NULL; |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | static int newer_jl_done(struct reiserfs_journal_cnode *cn) | ||
1190 | { | ||
1191 | struct super_block *sb = cn->sb; | ||
1192 | b_blocknr_t blocknr = cn->blocknr; | ||
1193 | |||
1194 | cn = cn->hprev; | ||
1195 | while (cn) { | ||
1196 | if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist && | ||
1197 | atomic_read(&cn->jlist->j_commit_left) != 0) | ||
1198 | return 0; | ||
1199 | cn = cn->hprev; | ||
1200 | } | ||
1201 | return 1; | ||
1202 | } | ||
1203 | |||
1189 | static void remove_journal_hash(struct super_block *, | 1204 | static void remove_journal_hash(struct super_block *, |
1190 | struct reiserfs_journal_cnode **, | 1205 | struct reiserfs_journal_cnode **, |
1191 | struct reiserfs_journal_list *, unsigned long, | 1206 | struct reiserfs_journal_list *, unsigned long, |
@@ -1604,6 +1619,31 @@ static int flush_journal_list(struct super_block *s, | |||
1604 | return err; | 1619 | return err; |
1605 | } | 1620 | } |
1606 | 1621 | ||
1622 | static int test_transaction(struct super_block *s, | ||
1623 | struct reiserfs_journal_list *jl) | ||
1624 | { | ||
1625 | struct reiserfs_journal_cnode *cn; | ||
1626 | |||
1627 | if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0) | ||
1628 | return 1; | ||
1629 | |||
1630 | cn = jl->j_realblock; | ||
1631 | while (cn) { | ||
1632 | /* if the blocknr == 0, this has been cleared from the hash, | ||
1633 | ** skip it | ||
1634 | */ | ||
1635 | if (cn->blocknr == 0) { | ||
1636 | goto next; | ||
1637 | } | ||
1638 | if (cn->bh && !newer_jl_done(cn)) | ||
1639 | return 0; | ||
1640 | next: | ||
1641 | cn = cn->next; | ||
1642 | cond_resched(); | ||
1643 | } | ||
1644 | return 0; | ||
1645 | } | ||
1646 | |||
1607 | static int write_one_transaction(struct super_block *s, | 1647 | static int write_one_transaction(struct super_block *s, |
1608 | struct reiserfs_journal_list *jl, | 1648 | struct reiserfs_journal_list *jl, |
1609 | struct buffer_chunk *chunk) | 1649 | struct buffer_chunk *chunk) |
@@ -3433,16 +3473,6 @@ static void flush_async_commits(void *p) | |||
3433 | flush_commit_list(p_s_sb, jl, 1); | 3473 | flush_commit_list(p_s_sb, jl, 1); |
3434 | } | 3474 | } |
3435 | unlock_kernel(); | 3475 | unlock_kernel(); |
3436 | /* | ||
3437 | * this is a little racey, but there's no harm in missing | ||
3438 | * the filemap_fdata_write | ||
3439 | */ | ||
3440 | if (!atomic_read(&journal->j_async_throttle) | ||
3441 | && !reiserfs_is_journal_aborted(journal)) { | ||
3442 | atomic_inc(&journal->j_async_throttle); | ||
3443 | filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping); | ||
3444 | atomic_dec(&journal->j_async_throttle); | ||
3445 | } | ||
3446 | } | 3476 | } |
3447 | 3477 | ||
3448 | /* | 3478 | /* |
@@ -3844,7 +3874,9 @@ static void flush_old_journal_lists(struct super_block *s) | |||
3844 | entry = journal->j_journal_list.next; | 3874 | entry = journal->j_journal_list.next; |
3845 | jl = JOURNAL_LIST_ENTRY(entry); | 3875 | jl = JOURNAL_LIST_ENTRY(entry); |
3846 | /* this check should always be run, to send old lists to disk */ | 3876 | /* this check should always be run, to send old lists to disk */ |
3847 | if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) { | 3877 | if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) && |
3878 | atomic_read(&jl->j_commit_left) == 0 && | ||
3879 | test_transaction(s, jl)) { | ||
3848 | flush_used_journal_lists(s, jl); | 3880 | flush_used_journal_lists(s, jl); |
3849 | } else { | 3881 | } else { |
3850 | break; | 3882 | break; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b40d4d64d598..80fc3b32802f 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -510,8 +510,10 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) | |||
510 | SLAB_CTOR_CONSTRUCTOR) { | 510 | SLAB_CTOR_CONSTRUCTOR) { |
511 | INIT_LIST_HEAD(&ei->i_prealloc_list); | 511 | INIT_LIST_HEAD(&ei->i_prealloc_list); |
512 | inode_init_once(&ei->vfs_inode); | 512 | inode_init_once(&ei->vfs_inode); |
513 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
513 | ei->i_acl_access = NULL; | 514 | ei->i_acl_access = NULL; |
514 | ei->i_acl_default = NULL; | 515 | ei->i_acl_default = NULL; |
516 | #endif | ||
515 | } | 517 | } |
516 | } | 518 | } |
517 | 519 | ||
@@ -560,6 +562,7 @@ static void reiserfs_dirty_inode(struct inode *inode) | |||
560 | reiserfs_write_unlock(inode->i_sb); | 562 | reiserfs_write_unlock(inode->i_sb); |
561 | } | 563 | } |
562 | 564 | ||
565 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
563 | static void reiserfs_clear_inode(struct inode *inode) | 566 | static void reiserfs_clear_inode(struct inode *inode) |
564 | { | 567 | { |
565 | struct posix_acl *acl; | 568 | struct posix_acl *acl; |
@@ -574,6 +577,9 @@ static void reiserfs_clear_inode(struct inode *inode) | |||
574 | posix_acl_release(acl); | 577 | posix_acl_release(acl); |
575 | REISERFS_I(inode)->i_acl_default = NULL; | 578 | REISERFS_I(inode)->i_acl_default = NULL; |
576 | } | 579 | } |
580 | #else | ||
581 | #define reiserfs_clear_inode NULL | ||
582 | #endif | ||
577 | 583 | ||
578 | #ifdef CONFIG_QUOTA | 584 | #ifdef CONFIG_QUOTA |
579 | static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, | 585 | static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, |
diff --git a/fs/select.c b/fs/select.c index 33b72ba0f86f..dcbc1112b7ec 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -658,8 +658,6 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout) | |||
658 | unsigned int i; | 658 | unsigned int i; |
659 | struct poll_list *head; | 659 | struct poll_list *head; |
660 | struct poll_list *walk; | 660 | struct poll_list *walk; |
661 | struct fdtable *fdt; | ||
662 | int max_fdset; | ||
663 | /* Allocate small arguments on the stack to save memory and be | 661 | /* Allocate small arguments on the stack to save memory and be |
664 | faster - use long to make sure the buffer is aligned properly | 662 | faster - use long to make sure the buffer is aligned properly |
665 | on 64 bit archs to avoid unaligned access */ | 663 | on 64 bit archs to avoid unaligned access */ |
@@ -667,11 +665,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout) | |||
667 | struct poll_list *stack_pp = NULL; | 665 | struct poll_list *stack_pp = NULL; |
668 | 666 | ||
669 | /* Do a sanity check on nfds ... */ | 667 | /* Do a sanity check on nfds ... */ |
670 | rcu_read_lock(); | 668 | if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
671 | fdt = files_fdtable(current->files); | ||
672 | max_fdset = fdt->max_fdset; | ||
673 | rcu_read_unlock(); | ||
674 | if (nfds > max_fdset && nfds > OPEN_MAX) | ||
675 | return -EINVAL; | 669 | return -EINVAL; |
676 | 670 | ||
677 | poll_initwait(&table); | 671 | poll_initwait(&table); |
diff --git a/fs/splice.c b/fs/splice.c index 684bca3d3a10..13e92dd19fbb 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * Jens to support splicing to files, network, direct splicing, etc and | 12 | * Jens to support splicing to files, network, direct splicing, etc and |
13 | * fixing lots of bugs. | 13 | * fixing lots of bugs. |
14 | * | 14 | * |
15 | * Copyright (C) 2005-2006 Jens Axboe <axboe@suse.de> | 15 | * Copyright (C) 2005-2006 Jens Axboe <axboe@kernel.dk> |
16 | * Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org> | 16 | * Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org> |
17 | * Copyright (C) 2006 Ingo Molnar <mingo@elte.hu> | 17 | * Copyright (C) 2006 Ingo Molnar <mingo@elte.hu> |
18 | * | 18 | * |
diff --git a/fs/super.c b/fs/super.c index 5c4c94d5495e..aec99ddbe53f 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(deactivate_super); | |||
199 | * success, 0 if we had failed (superblock contents was already dead or | 199 | * success, 0 if we had failed (superblock contents was already dead or |
200 | * dying when grab_super() had been called). | 200 | * dying when grab_super() had been called). |
201 | */ | 201 | */ |
202 | static int grab_super(struct super_block *s) | 202 | static int grab_super(struct super_block *s) __releases(sb_lock) |
203 | { | 203 | { |
204 | s->s_count++; | 204 | s->s_count++; |
205 | spin_unlock(&sb_lock); | 205 | spin_unlock(&sb_lock); |
@@ -220,6 +220,37 @@ static int grab_super(struct super_block *s) | |||
220 | return 0; | 220 | return 0; |
221 | } | 221 | } |
222 | 222 | ||
223 | /* | ||
224 | * Write out and wait upon all dirty data associated with this | ||
225 | * superblock. Filesystem data as well as the underlying block | ||
226 | * device. Takes the superblock lock. Requires a second blkdev | ||
227 | * flush by the caller to complete the operation. | ||
228 | */ | ||
229 | void __fsync_super(struct super_block *sb) | ||
230 | { | ||
231 | sync_inodes_sb(sb, 0); | ||
232 | DQUOT_SYNC(sb); | ||
233 | lock_super(sb); | ||
234 | if (sb->s_dirt && sb->s_op->write_super) | ||
235 | sb->s_op->write_super(sb); | ||
236 | unlock_super(sb); | ||
237 | if (sb->s_op->sync_fs) | ||
238 | sb->s_op->sync_fs(sb, 1); | ||
239 | sync_blockdev(sb->s_bdev); | ||
240 | sync_inodes_sb(sb, 1); | ||
241 | } | ||
242 | |||
243 | /* | ||
244 | * Write out and wait upon all dirty data associated with this | ||
245 | * superblock. Filesystem data as well as the underlying block | ||
246 | * device. Takes the superblock lock. | ||
247 | */ | ||
248 | int fsync_super(struct super_block *sb) | ||
249 | { | ||
250 | __fsync_super(sb); | ||
251 | return sync_blockdev(sb->s_bdev); | ||
252 | } | ||
253 | |||
223 | /** | 254 | /** |
224 | * generic_shutdown_super - common helper for ->kill_sb() | 255 | * generic_shutdown_super - common helper for ->kill_sb() |
225 | * @sb: superblock to kill | 256 | * @sb: superblock to kill |
@@ -540,8 +571,10 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) | |||
540 | { | 571 | { |
541 | int retval; | 572 | int retval; |
542 | 573 | ||
574 | #ifdef CONFIG_BLOCK | ||
543 | if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) | 575 | if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) |
544 | return -EACCES; | 576 | return -EACCES; |
577 | #endif | ||
545 | if (flags & MS_RDONLY) | 578 | if (flags & MS_RDONLY) |
546 | acct_auto_close(sb); | 579 | acct_auto_close(sb); |
547 | shrink_dcache_sb(sb); | 580 | shrink_dcache_sb(sb); |
@@ -661,6 +694,7 @@ void kill_litter_super(struct super_block *sb) | |||
661 | 694 | ||
662 | EXPORT_SYMBOL(kill_litter_super); | 695 | EXPORT_SYMBOL(kill_litter_super); |
663 | 696 | ||
697 | #ifdef CONFIG_BLOCK | ||
664 | static int set_bdev_super(struct super_block *s, void *data) | 698 | static int set_bdev_super(struct super_block *s, void *data) |
665 | { | 699 | { |
666 | s->s_bdev = data; | 700 | s->s_bdev = data; |
@@ -756,6 +790,7 @@ void kill_block_super(struct super_block *sb) | |||
756 | } | 790 | } |
757 | 791 | ||
758 | EXPORT_SYMBOL(kill_block_super); | 792 | EXPORT_SYMBOL(kill_block_super); |
793 | #endif | ||
759 | 794 | ||
760 | int get_sb_nodev(struct file_system_type *fs_type, | 795 | int get_sb_nodev(struct file_system_type *fs_type, |
761 | int flags, void *data, | 796 | int flags, void *data, |
@@ -10,11 +10,124 @@ | |||
10 | #include <linux/syscalls.h> | 10 | #include <linux/syscalls.h> |
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/quotaops.h> | ||
14 | #include <linux/buffer_head.h> | ||
13 | 15 | ||
14 | #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ | 16 | #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ |
15 | SYNC_FILE_RANGE_WAIT_AFTER) | 17 | SYNC_FILE_RANGE_WAIT_AFTER) |
16 | 18 | ||
17 | /* | 19 | /* |
20 | * sync everything. Start out by waking pdflush, because that writes back | ||
21 | * all queues in parallel. | ||
22 | */ | ||
23 | static void do_sync(unsigned long wait) | ||
24 | { | ||
25 | wakeup_pdflush(0); | ||
26 | sync_inodes(0); /* All mappings, inodes and their blockdevs */ | ||
27 | DQUOT_SYNC(NULL); | ||
28 | sync_supers(); /* Write the superblocks */ | ||
29 | sync_filesystems(0); /* Start syncing the filesystems */ | ||
30 | sync_filesystems(wait); /* Waitingly sync the filesystems */ | ||
31 | sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ | ||
32 | if (!wait) | ||
33 | printk("Emergency Sync complete\n"); | ||
34 | if (unlikely(laptop_mode)) | ||
35 | laptop_sync_completion(); | ||
36 | } | ||
37 | |||
38 | asmlinkage long sys_sync(void) | ||
39 | { | ||
40 | do_sync(1); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | void emergency_sync(void) | ||
45 | { | ||
46 | pdflush_operation(do_sync, 0); | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * Generic function to fsync a file. | ||
51 | * | ||
52 | * filp may be NULL if called via the msync of a vma. | ||
53 | */ | ||
54 | int file_fsync(struct file *filp, struct dentry *dentry, int datasync) | ||
55 | { | ||
56 | struct inode * inode = dentry->d_inode; | ||
57 | struct super_block * sb; | ||
58 | int ret, err; | ||
59 | |||
60 | /* sync the inode to buffers */ | ||
61 | ret = write_inode_now(inode, 0); | ||
62 | |||
63 | /* sync the superblock to buffers */ | ||
64 | sb = inode->i_sb; | ||
65 | lock_super(sb); | ||
66 | if (sb->s_op->write_super) | ||
67 | sb->s_op->write_super(sb); | ||
68 | unlock_super(sb); | ||
69 | |||
70 | /* .. finally sync the buffers to disk */ | ||
71 | err = sync_blockdev(sb->s_bdev); | ||
72 | if (!ret) | ||
73 | ret = err; | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | long do_fsync(struct file *file, int datasync) | ||
78 | { | ||
79 | int ret; | ||
80 | int err; | ||
81 | struct address_space *mapping = file->f_mapping; | ||
82 | |||
83 | if (!file->f_op || !file->f_op->fsync) { | ||
84 | /* Why? We can still call filemap_fdatawrite */ | ||
85 | ret = -EINVAL; | ||
86 | goto out; | ||
87 | } | ||
88 | |||
89 | ret = filemap_fdatawrite(mapping); | ||
90 | |||
91 | /* | ||
92 | * We need to protect against concurrent writers, which could cause | ||
93 | * livelocks in fsync_buffers_list(). | ||
94 | */ | ||
95 | mutex_lock(&mapping->host->i_mutex); | ||
96 | err = file->f_op->fsync(file, file->f_dentry, datasync); | ||
97 | if (!ret) | ||
98 | ret = err; | ||
99 | mutex_unlock(&mapping->host->i_mutex); | ||
100 | err = filemap_fdatawait(mapping); | ||
101 | if (!ret) | ||
102 | ret = err; | ||
103 | out: | ||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | static long __do_fsync(unsigned int fd, int datasync) | ||
108 | { | ||
109 | struct file *file; | ||
110 | int ret = -EBADF; | ||
111 | |||
112 | file = fget(fd); | ||
113 | if (file) { | ||
114 | ret = do_fsync(file, datasync); | ||
115 | fput(file); | ||
116 | } | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | asmlinkage long sys_fsync(unsigned int fd) | ||
121 | { | ||
122 | return __do_fsync(fd, 0); | ||
123 | } | ||
124 | |||
125 | asmlinkage long sys_fdatasync(unsigned int fd) | ||
126 | { | ||
127 | return __do_fsync(fd, 1); | ||
128 | } | ||
129 | |||
130 | /* | ||
18 | * sys_sync_file_range() permits finely controlled syncing over a segment of | 131 | * sys_sync_file_range() permits finely controlled syncing over a segment of |
19 | * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is | 132 | * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is |
20 | * zero then sys_sync_file_range() will operate from offset out to EOF. | 133 | * zero then sys_sync_file_range() will operate from offset out to EOF. |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 5dd356cbbda6..1d3b5d2070e5 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1621,6 +1621,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1621 | goto error_out; | 1621 | goto error_out; |
1622 | } | 1622 | } |
1623 | 1623 | ||
1624 | if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) | ||
1625 | printk("UDF-fs: Partition marked readonly; forcing readonly mount\n"); | ||
1626 | sb->s_flags |= MS_RDONLY; | ||
1627 | |||
1624 | if ( udf_find_fileset(sb, &fileset, &rootdir) ) | 1628 | if ( udf_find_fileset(sb, &fileset, &rootdir) ) |
1625 | { | 1629 | { |
1626 | printk("UDF-fs: No fileset found\n"); | 1630 | printk("UDF-fs: No fileset found\n"); |
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 26b364c9d62c..35115bca036e 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config XFS_FS | 1 | config XFS_FS |
2 | tristate "XFS filesystem support" | 2 | tristate "XFS filesystem support" |
3 | depends on BLOCK | ||
3 | help | 4 | help |
4 | XFS is a high performance journaling filesystem which originated | 5 | XFS is a high performance journaling filesystem which originated |
5 | on the SGI IRIX platform. It is completely multi-threaded, can | 6 | on the SGI IRIX platform. It is completely multi-threaded, can |
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index 9e7f85986d0d..291948d5085a 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 | |||
@@ -30,7 +30,6 @@ ifeq ($(CONFIG_XFS_TRACE),y) | |||
30 | EXTRA_CFLAGS += -DXFS_BLI_TRACE | 30 | EXTRA_CFLAGS += -DXFS_BLI_TRACE |
31 | EXTRA_CFLAGS += -DXFS_BMAP_TRACE | 31 | EXTRA_CFLAGS += -DXFS_BMAP_TRACE |
32 | EXTRA_CFLAGS += -DXFS_BMBT_TRACE | 32 | EXTRA_CFLAGS += -DXFS_BMBT_TRACE |
33 | EXTRA_CFLAGS += -DXFS_DIR_TRACE | ||
34 | EXTRA_CFLAGS += -DXFS_DIR2_TRACE | 33 | EXTRA_CFLAGS += -DXFS_DIR2_TRACE |
35 | EXTRA_CFLAGS += -DXFS_DQUOT_TRACE | 34 | EXTRA_CFLAGS += -DXFS_DQUOT_TRACE |
36 | EXTRA_CFLAGS += -DXFS_ILOCK_TRACE | 35 | EXTRA_CFLAGS += -DXFS_ILOCK_TRACE |
diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c index aba7fcf881a2..d59737589815 100644 --- a/fs/xfs/linux-2.6/kmem.c +++ b/fs/xfs/linux-2.6/kmem.c | |||
@@ -34,6 +34,14 @@ kmem_alloc(size_t size, unsigned int __nocast flags) | |||
34 | gfp_t lflags = kmem_flags_convert(flags); | 34 | gfp_t lflags = kmem_flags_convert(flags); |
35 | void *ptr; | 35 | void *ptr; |
36 | 36 | ||
37 | #ifdef DEBUG | ||
38 | if (unlikely(!(flags & KM_LARGE) && (size > PAGE_SIZE))) { | ||
39 | printk(KERN_WARNING "Large %s attempt, size=%ld\n", | ||
40 | __FUNCTION__, (long)size); | ||
41 | dump_stack(); | ||
42 | } | ||
43 | #endif | ||
44 | |||
37 | do { | 45 | do { |
38 | if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS) | 46 | if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS) |
39 | ptr = kmalloc(size, lflags); | 47 | ptr = kmalloc(size, lflags); |
@@ -60,6 +68,27 @@ kmem_zalloc(size_t size, unsigned int __nocast flags) | |||
60 | return ptr; | 68 | return ptr; |
61 | } | 69 | } |
62 | 70 | ||
71 | void * | ||
72 | kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize, | ||
73 | unsigned int __nocast flags) | ||
74 | { | ||
75 | void *ptr; | ||
76 | size_t kmsize = maxsize; | ||
77 | unsigned int kmflags = (flags & ~KM_SLEEP) | KM_NOSLEEP; | ||
78 | |||
79 | while (!(ptr = kmem_zalloc(kmsize, kmflags))) { | ||
80 | if ((kmsize <= minsize) && (flags & KM_NOSLEEP)) | ||
81 | break; | ||
82 | if ((kmsize >>= 1) <= minsize) { | ||
83 | kmsize = minsize; | ||
84 | kmflags = flags; | ||
85 | } | ||
86 | } | ||
87 | if (ptr) | ||
88 | *size = kmsize; | ||
89 | return ptr; | ||
90 | } | ||
91 | |||
63 | void | 92 | void |
64 | kmem_free(void *ptr, size_t size) | 93 | kmem_free(void *ptr, size_t size) |
65 | { | 94 | { |
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index 0e8293c5a32f..9ebabdf7829c 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define KM_NOSLEEP 0x0002u | 30 | #define KM_NOSLEEP 0x0002u |
31 | #define KM_NOFS 0x0004u | 31 | #define KM_NOFS 0x0004u |
32 | #define KM_MAYFAIL 0x0008u | 32 | #define KM_MAYFAIL 0x0008u |
33 | #define KM_LARGE 0x0010u | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * We use a special process flag to avoid recursive callbacks into | 36 | * We use a special process flag to avoid recursive callbacks into |
@@ -41,7 +42,7 @@ kmem_flags_convert(unsigned int __nocast flags) | |||
41 | { | 42 | { |
42 | gfp_t lflags; | 43 | gfp_t lflags; |
43 | 44 | ||
44 | BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL)); | 45 | BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL|KM_LARGE)); |
45 | 46 | ||
46 | if (flags & KM_NOSLEEP) { | 47 | if (flags & KM_NOSLEEP) { |
47 | lflags = GFP_ATOMIC | __GFP_NOWARN; | 48 | lflags = GFP_ATOMIC | __GFP_NOWARN; |
@@ -54,8 +55,9 @@ kmem_flags_convert(unsigned int __nocast flags) | |||
54 | } | 55 | } |
55 | 56 | ||
56 | extern void *kmem_alloc(size_t, unsigned int __nocast); | 57 | extern void *kmem_alloc(size_t, unsigned int __nocast); |
57 | extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast); | ||
58 | extern void *kmem_zalloc(size_t, unsigned int __nocast); | 58 | extern void *kmem_zalloc(size_t, unsigned int __nocast); |
59 | extern void *kmem_zalloc_greedy(size_t *, size_t, size_t, unsigned int __nocast); | ||
60 | extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast); | ||
59 | extern void kmem_free(void *, size_t); | 61 | extern void kmem_free(void *, size_t); |
60 | 62 | ||
61 | /* | 63 | /* |
diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h index b25090094cca..2009e6d922ce 100644 --- a/fs/xfs/linux-2.6/sema.h +++ b/fs/xfs/linux-2.6/sema.h | |||
@@ -29,8 +29,6 @@ | |||
29 | 29 | ||
30 | typedef struct semaphore sema_t; | 30 | typedef struct semaphore sema_t; |
31 | 31 | ||
32 | #define init_sema(sp, val, c, d) sema_init(sp, val) | ||
33 | #define initsema(sp, val) sema_init(sp, val) | ||
34 | #define initnsema(sp, val, name) sema_init(sp, val) | 32 | #define initnsema(sp, val, name) sema_init(sp, val) |
35 | #define psema(sp, b) down(sp) | 33 | #define psema(sp, b) down(sp) |
36 | #define vsema(sp) up(sp) | 34 | #define vsema(sp) up(sp) |
diff --git a/fs/xfs/linux-2.6/sv.h b/fs/xfs/linux-2.6/sv.h index 9a8ad481b008..351a8f454bd1 100644 --- a/fs/xfs/linux-2.6/sv.h +++ b/fs/xfs/linux-2.6/sv.h | |||
@@ -53,8 +53,6 @@ static inline void _sv_wait(sv_t *sv, spinlock_t *lock, int state, | |||
53 | remove_wait_queue(&sv->waiters, &wait); | 53 | remove_wait_queue(&sv->waiters, &wait); |
54 | } | 54 | } |
55 | 55 | ||
56 | #define init_sv(sv,type,name,flag) \ | ||
57 | init_waitqueue_head(&(sv)->waiters) | ||
58 | #define sv_init(sv,flag,name) \ | 56 | #define sv_init(sv,flag,name) \ |
59 | init_waitqueue_head(&(sv)->waiters) | 57 | init_waitqueue_head(&(sv)->waiters) |
60 | #define sv_destroy(sv) \ | 58 | #define sv_destroy(sv) \ |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 34dcb43a7837..09360cf1e1f2 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -71,7 +71,7 @@ xfs_page_trace( | |||
71 | int tag, | 71 | int tag, |
72 | struct inode *inode, | 72 | struct inode *inode, |
73 | struct page *page, | 73 | struct page *page, |
74 | int mask) | 74 | unsigned long pgoff) |
75 | { | 75 | { |
76 | xfs_inode_t *ip; | 76 | xfs_inode_t *ip; |
77 | bhv_vnode_t *vp = vn_from_inode(inode); | 77 | bhv_vnode_t *vp = vn_from_inode(inode); |
@@ -91,7 +91,7 @@ xfs_page_trace( | |||
91 | (void *)ip, | 91 | (void *)ip, |
92 | (void *)inode, | 92 | (void *)inode, |
93 | (void *)page, | 93 | (void *)page, |
94 | (void *)((unsigned long)mask), | 94 | (void *)pgoff, |
95 | (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), | 95 | (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), |
96 | (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), | 96 | (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), |
97 | (void *)((unsigned long)((isize >> 32) & 0xffffffff)), | 97 | (void *)((unsigned long)((isize >> 32) & 0xffffffff)), |
@@ -105,7 +105,7 @@ xfs_page_trace( | |||
105 | (void *)NULL); | 105 | (void *)NULL); |
106 | } | 106 | } |
107 | #else | 107 | #else |
108 | #define xfs_page_trace(tag, inode, page, mask) | 108 | #define xfs_page_trace(tag, inode, page, pgoff) |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | /* | 111 | /* |
@@ -1197,7 +1197,7 @@ xfs_vm_releasepage( | |||
1197 | .nr_to_write = 1, | 1197 | .nr_to_write = 1, |
1198 | }; | 1198 | }; |
1199 | 1199 | ||
1200 | xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask); | 1200 | xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, 0); |
1201 | 1201 | ||
1202 | if (!page_has_buffers(page)) | 1202 | if (!page_has_buffers(page)) |
1203 | return 0; | 1203 | return 0; |
@@ -1356,7 +1356,6 @@ xfs_end_io_direct( | |||
1356 | ioend->io_size = size; | 1356 | ioend->io_size = size; |
1357 | xfs_finish_ioend(ioend); | 1357 | xfs_finish_ioend(ioend); |
1358 | } else { | 1358 | } else { |
1359 | ASSERT(size >= 0); | ||
1360 | xfs_destroy_ioend(ioend); | 1359 | xfs_destroy_ioend(ioend); |
1361 | } | 1360 | } |
1362 | 1361 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 2af528dcfb04..9bbadafdcb00 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.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 |
@@ -318,8 +318,12 @@ xfs_buf_free( | |||
318 | if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) | 318 | if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) |
319 | free_address(bp->b_addr - bp->b_offset); | 319 | free_address(bp->b_addr - bp->b_offset); |
320 | 320 | ||
321 | for (i = 0; i < bp->b_page_count; i++) | 321 | for (i = 0; i < bp->b_page_count; i++) { |
322 | page_cache_release(bp->b_pages[i]); | 322 | struct page *page = bp->b_pages[i]; |
323 | |||
324 | ASSERT(!PagePrivate(page)); | ||
325 | page_cache_release(page); | ||
326 | } | ||
323 | _xfs_buf_free_pages(bp); | 327 | _xfs_buf_free_pages(bp); |
324 | } else if (bp->b_flags & _XBF_KMEM_ALLOC) { | 328 | } else if (bp->b_flags & _XBF_KMEM_ALLOC) { |
325 | /* | 329 | /* |
@@ -400,6 +404,7 @@ _xfs_buf_lookup_pages( | |||
400 | nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset); | 404 | nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset); |
401 | size -= nbytes; | 405 | size -= nbytes; |
402 | 406 | ||
407 | ASSERT(!PagePrivate(page)); | ||
403 | if (!PageUptodate(page)) { | 408 | if (!PageUptodate(page)) { |
404 | page_count--; | 409 | page_count--; |
405 | if (blocksize >= PAGE_CACHE_SIZE) { | 410 | if (blocksize >= PAGE_CACHE_SIZE) { |
@@ -768,7 +773,7 @@ xfs_buf_get_noaddr( | |||
768 | _xfs_buf_initialize(bp, target, 0, len, 0); | 773 | _xfs_buf_initialize(bp, target, 0, len, 0); |
769 | 774 | ||
770 | try_again: | 775 | try_again: |
771 | data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL); | 776 | data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE); |
772 | if (unlikely(data == NULL)) | 777 | if (unlikely(data == NULL)) |
773 | goto fail_free_buf; | 778 | goto fail_free_buf; |
774 | 779 | ||
@@ -1117,10 +1122,10 @@ xfs_buf_bio_end_io( | |||
1117 | do { | 1122 | do { |
1118 | struct page *page = bvec->bv_page; | 1123 | struct page *page = bvec->bv_page; |
1119 | 1124 | ||
1125 | ASSERT(!PagePrivate(page)); | ||
1120 | if (unlikely(bp->b_error)) { | 1126 | if (unlikely(bp->b_error)) { |
1121 | if (bp->b_flags & XBF_READ) | 1127 | if (bp->b_flags & XBF_READ) |
1122 | ClearPageUptodate(page); | 1128 | ClearPageUptodate(page); |
1123 | SetPageError(page); | ||
1124 | } else if (blocksize >= PAGE_CACHE_SIZE) { | 1129 | } else if (blocksize >= PAGE_CACHE_SIZE) { |
1125 | SetPageUptodate(page); | 1130 | SetPageUptodate(page); |
1126 | } else if (!PagePrivate(page) && | 1131 | } else if (!PagePrivate(page) && |
@@ -1156,16 +1161,16 @@ _xfs_buf_ioapply( | |||
1156 | total_nr_pages = bp->b_page_count; | 1161 | total_nr_pages = bp->b_page_count; |
1157 | map_i = 0; | 1162 | map_i = 0; |
1158 | 1163 | ||
1159 | if (bp->b_flags & _XBF_RUN_QUEUES) { | ||
1160 | bp->b_flags &= ~_XBF_RUN_QUEUES; | ||
1161 | rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC; | ||
1162 | } else { | ||
1163 | rw = (bp->b_flags & XBF_READ) ? READ : WRITE; | ||
1164 | } | ||
1165 | |||
1166 | if (bp->b_flags & XBF_ORDERED) { | 1164 | if (bp->b_flags & XBF_ORDERED) { |
1167 | ASSERT(!(bp->b_flags & XBF_READ)); | 1165 | ASSERT(!(bp->b_flags & XBF_READ)); |
1168 | rw = WRITE_BARRIER; | 1166 | rw = WRITE_BARRIER; |
1167 | } else if (bp->b_flags & _XBF_RUN_QUEUES) { | ||
1168 | ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); | ||
1169 | bp->b_flags &= ~_XBF_RUN_QUEUES; | ||
1170 | rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC; | ||
1171 | } else { | ||
1172 | rw = (bp->b_flags & XBF_WRITE) ? WRITE : | ||
1173 | (bp->b_flags & XBF_READ_AHEAD) ? READA : READ; | ||
1169 | } | 1174 | } |
1170 | 1175 | ||
1171 | /* Special code path for reading a sub page size buffer in -- | 1176 | /* Special code path for reading a sub page size buffer in -- |
@@ -1681,6 +1686,7 @@ xfsbufd( | |||
1681 | xfs_buf_t *bp, *n; | 1686 | xfs_buf_t *bp, *n; |
1682 | struct list_head *dwq = &target->bt_delwrite_queue; | 1687 | struct list_head *dwq = &target->bt_delwrite_queue; |
1683 | spinlock_t *dwlk = &target->bt_delwrite_lock; | 1688 | spinlock_t *dwlk = &target->bt_delwrite_lock; |
1689 | int count; | ||
1684 | 1690 | ||
1685 | current->flags |= PF_MEMALLOC; | 1691 | current->flags |= PF_MEMALLOC; |
1686 | 1692 | ||
@@ -1696,6 +1702,7 @@ xfsbufd( | |||
1696 | schedule_timeout_interruptible( | 1702 | schedule_timeout_interruptible( |
1697 | xfs_buf_timer_centisecs * msecs_to_jiffies(10)); | 1703 | xfs_buf_timer_centisecs * msecs_to_jiffies(10)); |
1698 | 1704 | ||
1705 | count = 0; | ||
1699 | age = xfs_buf_age_centisecs * msecs_to_jiffies(10); | 1706 | age = xfs_buf_age_centisecs * msecs_to_jiffies(10); |
1700 | spin_lock(dwlk); | 1707 | spin_lock(dwlk); |
1701 | list_for_each_entry_safe(bp, n, dwq, b_list) { | 1708 | list_for_each_entry_safe(bp, n, dwq, b_list) { |
@@ -1711,9 +1718,11 @@ xfsbufd( | |||
1711 | break; | 1718 | break; |
1712 | } | 1719 | } |
1713 | 1720 | ||
1714 | bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); | 1721 | bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q| |
1722 | _XBF_RUN_QUEUES); | ||
1715 | bp->b_flags |= XBF_WRITE; | 1723 | bp->b_flags |= XBF_WRITE; |
1716 | list_move(&bp->b_list, &tmp); | 1724 | list_move_tail(&bp->b_list, &tmp); |
1725 | count++; | ||
1717 | } | 1726 | } |
1718 | } | 1727 | } |
1719 | spin_unlock(dwlk); | 1728 | spin_unlock(dwlk); |
@@ -1724,12 +1733,12 @@ xfsbufd( | |||
1724 | 1733 | ||
1725 | list_del_init(&bp->b_list); | 1734 | list_del_init(&bp->b_list); |
1726 | xfs_buf_iostrategy(bp); | 1735 | xfs_buf_iostrategy(bp); |
1727 | |||
1728 | blk_run_address_space(target->bt_mapping); | ||
1729 | } | 1736 | } |
1730 | 1737 | ||
1731 | if (as_list_len > 0) | 1738 | if (as_list_len > 0) |
1732 | purge_addresses(); | 1739 | purge_addresses(); |
1740 | if (count) | ||
1741 | blk_run_address_space(target->bt_mapping); | ||
1733 | 1742 | ||
1734 | clear_bit(XBT_FORCE_FLUSH, &target->bt_flags); | 1743 | clear_bit(XBT_FORCE_FLUSH, &target->bt_flags); |
1735 | } while (!kthread_should_stop()); | 1744 | } while (!kthread_should_stop()); |
@@ -1767,7 +1776,7 @@ xfs_flush_buftarg( | |||
1767 | continue; | 1776 | continue; |
1768 | } | 1777 | } |
1769 | 1778 | ||
1770 | list_move(&bp->b_list, &tmp); | 1779 | list_move_tail(&bp->b_list, &tmp); |
1771 | } | 1780 | } |
1772 | spin_unlock(dwlk); | 1781 | spin_unlock(dwlk); |
1773 | 1782 | ||
@@ -1776,7 +1785,7 @@ xfs_flush_buftarg( | |||
1776 | */ | 1785 | */ |
1777 | list_for_each_entry_safe(bp, n, &tmp, b_list) { | 1786 | list_for_each_entry_safe(bp, n, &tmp, b_list) { |
1778 | xfs_buf_lock(bp); | 1787 | xfs_buf_lock(bp); |
1779 | bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); | 1788 | bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|_XBF_RUN_QUEUES); |
1780 | bp->b_flags |= XBF_WRITE; | 1789 | bp->b_flags |= XBF_WRITE; |
1781 | if (wait) | 1790 | if (wait) |
1782 | bp->b_flags &= ~XBF_ASYNC; | 1791 | bp->b_flags &= ~XBF_ASYNC; |
@@ -1786,6 +1795,9 @@ xfs_flush_buftarg( | |||
1786 | xfs_buf_iostrategy(bp); | 1795 | xfs_buf_iostrategy(bp); |
1787 | } | 1796 | } |
1788 | 1797 | ||
1798 | if (wait) | ||
1799 | blk_run_address_space(target->bt_mapping); | ||
1800 | |||
1789 | /* | 1801 | /* |
1790 | * Remaining list items must be flushed before returning | 1802 | * Remaining list items must be flushed before returning |
1791 | */ | 1803 | */ |
@@ -1797,9 +1809,6 @@ xfs_flush_buftarg( | |||
1797 | xfs_buf_relse(bp); | 1809 | xfs_buf_relse(bp); |
1798 | } | 1810 | } |
1799 | 1811 | ||
1800 | if (wait) | ||
1801 | blk_run_address_space(target->bt_mapping); | ||
1802 | |||
1803 | return pincount; | 1812 | return pincount; |
1804 | } | 1813 | } |
1805 | 1814 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 7858703ed84c..9dd235cb0107 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -298,11 +298,6 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *); | |||
298 | #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) | 298 | #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) |
299 | #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) | 299 | #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) |
300 | 300 | ||
301 | #define XFS_BUF_ISUNINITIAL(bp) (0) | ||
302 | #define XFS_BUF_UNUNINITIAL(bp) (0) | ||
303 | |||
304 | #define XFS_BUF_BP_ISMAPPED(bp) (1) | ||
305 | |||
306 | #define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone) | 301 | #define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone) |
307 | #define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func)) | 302 | #define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func)) |
308 | #define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL) | 303 | #define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL) |
@@ -393,8 +388,6 @@ static inline int XFS_bwrite(xfs_buf_t *bp) | |||
393 | return error; | 388 | return error; |
394 | } | 389 | } |
395 | 390 | ||
396 | #define XFS_bdwrite(bp) xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC) | ||
397 | |||
398 | static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp) | 391 | static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp) |
399 | { | 392 | { |
400 | bp->b_strat = xfs_bdstrat_cb; | 393 | bp->b_strat = xfs_bdstrat_cb; |
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c index 6c162c3dde7e..ed3a5e1b4b67 100644 --- a/fs/xfs/linux-2.6/xfs_globals.c +++ b/fs/xfs/linux-2.6/xfs_globals.c | |||
@@ -34,7 +34,7 @@ xfs_param_t xfs_params = { | |||
34 | .restrict_chown = { 0, 1, 1 }, | 34 | .restrict_chown = { 0, 1, 1 }, |
35 | .sgid_inherit = { 0, 0, 1 }, | 35 | .sgid_inherit = { 0, 0, 1 }, |
36 | .symlink_mode = { 0, 0, 1 }, | 36 | .symlink_mode = { 0, 0, 1 }, |
37 | .panic_mask = { 0, 0, 127 }, | 37 | .panic_mask = { 0, 0, 255 }, |
38 | .error_level = { 0, 3, 11 }, | 38 | .error_level = { 0, 3, 11 }, |
39 | .syncd_timer = { 1*100, 30*100, 7200*100}, | 39 | .syncd_timer = { 1*100, 30*100, 7200*100}, |
40 | .stats_clear = { 0, 0, 1 }, | 40 | .stats_clear = { 0, 0, 1 }, |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 6e52a5dd38d8..a74f854d91e6 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -653,7 +653,7 @@ xfs_attrmulti_by_handle( | |||
653 | STATIC int | 653 | STATIC int |
654 | xfs_ioc_space( | 654 | xfs_ioc_space( |
655 | bhv_desc_t *bdp, | 655 | bhv_desc_t *bdp, |
656 | bhv_vnode_t *vp, | 656 | struct inode *inode, |
657 | struct file *filp, | 657 | struct file *filp, |
658 | int flags, | 658 | int flags, |
659 | unsigned int cmd, | 659 | unsigned int cmd, |
@@ -735,7 +735,7 @@ xfs_ioctl( | |||
735 | !capable(CAP_SYS_ADMIN)) | 735 | !capable(CAP_SYS_ADMIN)) |
736 | return -EPERM; | 736 | return -EPERM; |
737 | 737 | ||
738 | return xfs_ioc_space(bdp, vp, filp, ioflags, cmd, arg); | 738 | return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg); |
739 | 739 | ||
740 | case XFS_IOC_DIOINFO: { | 740 | case XFS_IOC_DIOINFO: { |
741 | struct dioattr da; | 741 | struct dioattr da; |
@@ -763,6 +763,8 @@ xfs_ioctl( | |||
763 | return xfs_ioc_fsgeometry(mp, arg); | 763 | return xfs_ioc_fsgeometry(mp, arg); |
764 | 764 | ||
765 | case XFS_IOC_GETVERSION: | 765 | case XFS_IOC_GETVERSION: |
766 | return put_user(inode->i_generation, (int __user *)arg); | ||
767 | |||
766 | case XFS_IOC_GETXFLAGS: | 768 | case XFS_IOC_GETXFLAGS: |
767 | case XFS_IOC_SETXFLAGS: | 769 | case XFS_IOC_SETXFLAGS: |
768 | case XFS_IOC_FSGETXATTR: | 770 | case XFS_IOC_FSGETXATTR: |
@@ -957,7 +959,7 @@ xfs_ioctl( | |||
957 | STATIC int | 959 | STATIC int |
958 | xfs_ioc_space( | 960 | xfs_ioc_space( |
959 | bhv_desc_t *bdp, | 961 | bhv_desc_t *bdp, |
960 | bhv_vnode_t *vp, | 962 | struct inode *inode, |
961 | struct file *filp, | 963 | struct file *filp, |
962 | int ioflags, | 964 | int ioflags, |
963 | unsigned int cmd, | 965 | unsigned int cmd, |
@@ -967,13 +969,13 @@ xfs_ioc_space( | |||
967 | int attr_flags = 0; | 969 | int attr_flags = 0; |
968 | int error; | 970 | int error; |
969 | 971 | ||
970 | if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) | 972 | if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) |
971 | return -XFS_ERROR(EPERM); | 973 | return -XFS_ERROR(EPERM); |
972 | 974 | ||
973 | if (!(filp->f_mode & FMODE_WRITE)) | 975 | if (!(filp->f_mode & FMODE_WRITE)) |
974 | return -XFS_ERROR(EBADF); | 976 | return -XFS_ERROR(EBADF); |
975 | 977 | ||
976 | if (!VN_ISREG(vp)) | 978 | if (!S_ISREG(inode->i_mode)) |
977 | return -XFS_ERROR(EINVAL); | 979 | return -XFS_ERROR(EINVAL); |
978 | 980 | ||
979 | if (copy_from_user(&bf, arg, sizeof(bf))) | 981 | if (copy_from_user(&bf, arg, sizeof(bf))) |
@@ -1264,13 +1266,6 @@ xfs_ioc_xattr( | |||
1264 | break; | 1266 | break; |
1265 | } | 1267 | } |
1266 | 1268 | ||
1267 | case XFS_IOC_GETVERSION: { | ||
1268 | flags = vn_to_inode(vp)->i_generation; | ||
1269 | if (copy_to_user(arg, &flags, sizeof(flags))) | ||
1270 | error = -EFAULT; | ||
1271 | break; | ||
1272 | } | ||
1273 | |||
1274 | default: | 1269 | default: |
1275 | error = -ENOTTY; | 1270 | error = -ENOTTY; |
1276 | break; | 1271 | break; |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 22e3b714f629..3ba814ae3bba 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -623,12 +623,27 @@ xfs_vn_getattr( | |||
623 | { | 623 | { |
624 | struct inode *inode = dentry->d_inode; | 624 | struct inode *inode = dentry->d_inode; |
625 | bhv_vnode_t *vp = vn_from_inode(inode); | 625 | bhv_vnode_t *vp = vn_from_inode(inode); |
626 | int error = 0; | 626 | bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT }; |
627 | int error; | ||
627 | 628 | ||
628 | if (unlikely(vp->v_flag & VMODIFIED)) | 629 | error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL); |
629 | error = vn_revalidate(vp); | 630 | if (likely(!error)) { |
630 | if (!error) | 631 | stat->size = i_size_read(inode); |
631 | generic_fillattr(inode, stat); | 632 | stat->dev = inode->i_sb->s_dev; |
633 | stat->rdev = (vattr.va_rdev == 0) ? 0 : | ||
634 | MKDEV(sysv_major(vattr.va_rdev) & 0x1ff, | ||
635 | sysv_minor(vattr.va_rdev)); | ||
636 | stat->mode = vattr.va_mode; | ||
637 | stat->nlink = vattr.va_nlink; | ||
638 | stat->uid = vattr.va_uid; | ||
639 | stat->gid = vattr.va_gid; | ||
640 | stat->ino = vattr.va_nodeid; | ||
641 | stat->atime = vattr.va_atime; | ||
642 | stat->mtime = vattr.va_mtime; | ||
643 | stat->ctime = vattr.va_ctime; | ||
644 | stat->blocks = vattr.va_nblocks; | ||
645 | stat->blksize = vattr.va_blocksize; | ||
646 | } | ||
632 | return -error; | 647 | return -error; |
633 | } | 648 | } |
634 | 649 | ||
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index a13f75c1a936..2b0e0018738a 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -148,11 +148,7 @@ BUFFER_FNS(PrivateStart, unwritten); | |||
148 | (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) | 148 | (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) |
149 | 149 | ||
150 | #define NBPP PAGE_SIZE | 150 | #define NBPP PAGE_SIZE |
151 | #define DPPSHFT (PAGE_SHIFT - 9) | ||
152 | #define NDPP (1 << (PAGE_SHIFT - 9)) | 151 | #define NDPP (1 << (PAGE_SHIFT - 9)) |
153 | #define dtop(DD) (((DD) + NDPP - 1) >> DPPSHFT) | ||
154 | #define dtopt(DD) ((DD) >> DPPSHFT) | ||
155 | #define dpoff(DD) ((DD) & (NDPP-1)) | ||
156 | 152 | ||
157 | #define NBBY 8 /* number of bits per byte */ | 153 | #define NBBY 8 /* number of bits per byte */ |
158 | #define NBPC PAGE_SIZE /* Number of bytes per click */ | 154 | #define NBPC PAGE_SIZE /* Number of bytes per click */ |
@@ -172,8 +168,6 @@ BUFFER_FNS(PrivateStart, unwritten); | |||
172 | #define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) | 168 | #define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) |
173 | #define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) | 169 | #define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) |
174 | #define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT) | 170 | #define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT) |
175 | #define io_btoc(x) (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT) | ||
176 | #define io_btoct(x) ((__psunsigned_t)(x)>>IO_BPCSHIFT) | ||
177 | 171 | ||
178 | /* off_t bytes to clicks */ | 172 | /* off_t bytes to clicks */ |
179 | #define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) | 173 | #define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) |
@@ -186,7 +180,6 @@ BUFFER_FNS(PrivateStart, unwritten); | |||
186 | #define ctob(x) ((__psunsigned_t)(x)<<BPCSHIFT) | 180 | #define ctob(x) ((__psunsigned_t)(x)<<BPCSHIFT) |
187 | #define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) | 181 | #define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) |
188 | #define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT) | 182 | #define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT) |
189 | #define io_ctob(x) ((__psunsigned_t)(x)<<IO_BPCSHIFT) | ||
190 | 183 | ||
191 | /* bytes to clicks */ | 184 | /* bytes to clicks */ |
192 | #define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) | 185 | #define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT) |
@@ -339,4 +332,11 @@ static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y) | |||
339 | return(x * y); | 332 | return(x * y); |
340 | } | 333 | } |
341 | 334 | ||
335 | static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y) | ||
336 | { | ||
337 | x += y - 1; | ||
338 | do_div(x, y); | ||
339 | return x; | ||
340 | } | ||
341 | |||
342 | #endif /* __XFS_LINUX__ */ | 342 | #endif /* __XFS_LINUX__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index ee788b1cb364..55992b40353c 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -270,12 +270,12 @@ xfs_read( | |||
270 | } | 270 | } |
271 | } | 271 | } |
272 | 272 | ||
273 | if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) | 273 | if (unlikely(ioflags & IO_ISDIRECT)) { |
274 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), | 274 | if (VN_CACHED(vp)) |
275 | -1, FI_REMAPF_LOCKED); | 275 | bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), |
276 | 276 | -1, FI_REMAPF_LOCKED); | |
277 | if (unlikely(ioflags & IO_ISDIRECT)) | ||
278 | mutex_unlock(&inode->i_mutex); | 277 | mutex_unlock(&inode->i_mutex); |
278 | } | ||
279 | 279 | ||
280 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, | 280 | xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, |
281 | (void *)iovp, segs, *offset, ioflags); | 281 | (void *)iovp, segs, *offset, ioflags); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 9df9ed37d219..38c4d128a8c0 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -227,7 +227,9 @@ xfs_initialize_vnode( | |||
227 | xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); | 227 | xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); |
228 | xfs_set_inodeops(inode); | 228 | xfs_set_inodeops(inode); |
229 | 229 | ||
230 | spin_lock(&ip->i_flags_lock); | ||
230 | ip->i_flags &= ~XFS_INEW; | 231 | ip->i_flags &= ~XFS_INEW; |
232 | spin_unlock(&ip->i_flags_lock); | ||
231 | barrier(); | 233 | barrier(); |
232 | 234 | ||
233 | unlock_new_inode(inode); | 235 | unlock_new_inode(inode); |
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index 91fc2c4b3353..da255bdf5260 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h | |||
@@ -79,7 +79,7 @@ typedef enum { | |||
79 | #define VFS_RDONLY 0x0001 /* read-only vfs */ | 79 | #define VFS_RDONLY 0x0001 /* read-only vfs */ |
80 | #define VFS_GRPID 0x0002 /* group-ID assigned from directory */ | 80 | #define VFS_GRPID 0x0002 /* group-ID assigned from directory */ |
81 | #define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ | 81 | #define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ |
82 | #define VFS_UMOUNT 0x0008 /* unmount in progress */ | 82 | /* ---- VFS_UMOUNT ---- 0x0008 -- unneeded, fixed via kthread APIs */ |
83 | #define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */ | 83 | #define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */ |
84 | #define VFS_END 0x0010 /* max flag */ | 84 | #define VFS_END 0x0010 /* max flag */ |
85 | 85 | ||
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index c42b3221b20c..515f5fdea57a 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -85,8 +85,6 @@ typedef enum { | |||
85 | #define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) | 85 | #define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) |
86 | #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) |
87 | #define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp) | 87 | #define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp) |
88 | #define vn_bhv_lookup(bhp,ops) bhv_lookup(bhp,ops) | ||
89 | #define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops) | ||
90 | 88 | ||
91 | /* | 89 | /* |
92 | * Vnode to Linux inode mapping. | 90 | * Vnode to Linux inode mapping. |
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index 5b2dcc58b244..33ad5af386e0 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -382,18 +382,6 @@ xfs_qm_dquot_logitem_unlock( | |||
382 | 382 | ||
383 | 383 | ||
384 | /* | 384 | /* |
385 | * The transaction with the dquot locked has aborted. The dquot | ||
386 | * must not be dirty within the transaction. We simply unlock just | ||
387 | * as if the transaction had been cancelled. | ||
388 | */ | ||
389 | STATIC void | ||
390 | xfs_qm_dquot_logitem_abort( | ||
391 | xfs_dq_logitem_t *ql) | ||
392 | { | ||
393 | xfs_qm_dquot_logitem_unlock(ql); | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * this needs to stamp an lsn into the dquot, I think. | 385 | * this needs to stamp an lsn into the dquot, I think. |
398 | * rpc's that look at user dquot's would then have to | 386 | * rpc's that look at user dquot's would then have to |
399 | * push on the dependency recorded in the dquot | 387 | * push on the dependency recorded in the dquot |
@@ -426,7 +414,6 @@ STATIC struct xfs_item_ops xfs_dquot_item_ops = { | |||
426 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 414 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
427 | xfs_qm_dquot_logitem_committed, | 415 | xfs_qm_dquot_logitem_committed, |
428 | .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push, | 416 | .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push, |
429 | .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_abort, | ||
430 | .iop_pushbuf = (void(*)(xfs_log_item_t*)) | 417 | .iop_pushbuf = (void(*)(xfs_log_item_t*)) |
431 | xfs_qm_dquot_logitem_pushbuf, | 418 | xfs_qm_dquot_logitem_pushbuf, |
432 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 419 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
@@ -559,17 +546,6 @@ xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn) | |||
559 | } | 546 | } |
560 | 547 | ||
561 | /* | 548 | /* |
562 | * The transaction of which this QUOTAOFF is a part has been aborted. | ||
563 | * Just clean up after ourselves. | ||
564 | * Shouldn't this never happen in the case of qoffend logitems? XXX | ||
565 | */ | ||
566 | STATIC void | ||
567 | xfs_qm_qoff_logitem_abort(xfs_qoff_logitem_t *qf) | ||
568 | { | ||
569 | kmem_free(qf, sizeof(xfs_qoff_logitem_t)); | ||
570 | } | ||
571 | |||
572 | /* | ||
573 | * There isn't much you can do to push on an quotaoff item. It is simply | 549 | * There isn't much you can do to push on an quotaoff item. It is simply |
574 | * stuck waiting for the log to be flushed to disk. | 550 | * stuck waiting for the log to be flushed to disk. |
575 | */ | 551 | */ |
@@ -644,7 +620,6 @@ STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { | |||
644 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 620 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
645 | xfs_qm_qoffend_logitem_committed, | 621 | xfs_qm_qoffend_logitem_committed, |
646 | .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, | 622 | .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, |
647 | .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort, | ||
648 | .iop_pushbuf = NULL, | 623 | .iop_pushbuf = NULL, |
649 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 624 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
650 | xfs_qm_qoffend_logitem_committing | 625 | xfs_qm_qoffend_logitem_committing |
@@ -667,7 +642,6 @@ STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = { | |||
667 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 642 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
668 | xfs_qm_qoff_logitem_committed, | 643 | xfs_qm_qoff_logitem_committed, |
669 | .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, | 644 | .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, |
670 | .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort, | ||
671 | .iop_pushbuf = NULL, | 645 | .iop_pushbuf = NULL, |
672 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 646 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
673 | xfs_qm_qoff_logitem_committing | 647 | xfs_qm_qoff_logitem_committing |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index e23e45535c48..7c6a3a50379e 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -112,17 +112,17 @@ xfs_Gqm_init(void) | |||
112 | { | 112 | { |
113 | xfs_dqhash_t *udqhash, *gdqhash; | 113 | xfs_dqhash_t *udqhash, *gdqhash; |
114 | xfs_qm_t *xqm; | 114 | xfs_qm_t *xqm; |
115 | uint i, hsize, flags = KM_SLEEP | KM_MAYFAIL; | 115 | size_t hsize; |
116 | uint i; | ||
116 | 117 | ||
117 | /* | 118 | /* |
118 | * Initialize the dquot hash tables. | 119 | * Initialize the dquot hash tables. |
119 | */ | 120 | */ |
120 | hsize = XFS_QM_HASHSIZE_HIGH; | 121 | udqhash = kmem_zalloc_greedy(&hsize, |
121 | while (!(udqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), flags))) { | 122 | XFS_QM_HASHSIZE_LOW, XFS_QM_HASHSIZE_HIGH, |
122 | if ((hsize >>= 1) <= XFS_QM_HASHSIZE_LOW) | 123 | KM_SLEEP | KM_MAYFAIL | KM_LARGE); |
123 | flags = KM_SLEEP; | 124 | gdqhash = kmem_zalloc(hsize, KM_SLEEP | KM_LARGE); |
124 | } | 125 | hsize /= sizeof(xfs_dqhash_t); |
125 | gdqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), KM_SLEEP); | ||
126 | ndquot = hsize << 8; | 126 | ndquot = hsize << 8; |
127 | 127 | ||
128 | xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP); | 128 | xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP); |
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 4568deb6da86..689407de0a20 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h | |||
@@ -56,12 +56,6 @@ extern kmem_zone_t *qm_dqtrxzone; | |||
56 | #define XFS_QM_HASHSIZE_HIGH ((NBPP * 4) / sizeof(xfs_dqhash_t)) | 56 | #define XFS_QM_HASHSIZE_HIGH ((NBPP * 4) / sizeof(xfs_dqhash_t)) |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * We output a cmn_err when quotachecking a quota file with more than | ||
60 | * this many fsbs. | ||
61 | */ | ||
62 | #define XFS_QM_BIG_QCHECK_NBLKS 500 | ||
63 | |||
64 | /* | ||
65 | * This defines the unit of allocation of dquots. | 59 | * This defines the unit of allocation of dquots. |
66 | * Currently, it is just one file system block, and a 4K blk contains 30 | 60 | * Currently, it is just one file system block, and a 4K blk contains 30 |
67 | * (136 * 30 = 4080) dquots. It's probably not worth trying to make | 61 | * (136 * 30 = 4080) dquots. It's probably not worth trying to make |
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index b7ddd04aae32..a8b85e2be9d5 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h | |||
@@ -75,7 +75,6 @@ static inline int XQMISLCKD(struct xfs_dqhash *h) | |||
75 | 75 | ||
76 | #define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist)) | 76 | #define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist)) |
77 | #define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist)) | 77 | #define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist)) |
78 | #define XFS_QM_IS_FREELIST_LOCKED(qm) XQMISLCKD(&((qm)->qm_dqfreelist)) | ||
79 | 78 | ||
80 | /* | 79 | /* |
81 | * Hash into a bucket in the dquot hash table, based on <mp, id>. | 80 | * Hash into a bucket in the dquot hash table, based on <mp, id>. |
@@ -170,6 +169,5 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ | |||
170 | #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ | 169 | #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ |
171 | (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ | 170 | (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ |
172 | (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) | 171 | (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) |
173 | #define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") | ||
174 | 172 | ||
175 | #endif /* __XFS_QUOTA_PRIV_H__ */ | 173 | #endif /* __XFS_QUOTA_PRIV_H__ */ |
diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c index addf5a7ea06c..5cf2e86caa71 100644 --- a/fs/xfs/support/ktrace.c +++ b/fs/xfs/support/ktrace.c | |||
@@ -75,7 +75,7 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep) | |||
75 | sleep); | 75 | sleep); |
76 | } else { | 76 | } else { |
77 | ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)), | 77 | ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)), |
78 | sleep); | 78 | sleep | KM_LARGE); |
79 | } | 79 | } |
80 | 80 | ||
81 | if (ktep == NULL) { | 81 | if (ktep == NULL) { |
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index dc2361dd740a..9ece7f87ec5b 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -150,7 +150,7 @@ typedef struct xfs_agi { | |||
150 | #define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) | 150 | #define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) |
151 | 151 | ||
152 | typedef struct xfs_agfl { | 152 | typedef struct xfs_agfl { |
153 | xfs_agblock_t agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ | 153 | __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ |
154 | } xfs_agfl_t; | 154 | } xfs_agfl_t; |
155 | 155 | ||
156 | /* | 156 | /* |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index d2bbcd882a69..e80dda3437d1 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -1477,8 +1477,10 @@ xfs_alloc_ag_vextent_small( | |||
1477 | /* | 1477 | /* |
1478 | * Can't allocate from the freelist for some reason. | 1478 | * Can't allocate from the freelist for some reason. |
1479 | */ | 1479 | */ |
1480 | else | 1480 | else { |
1481 | fbno = NULLAGBLOCK; | ||
1481 | flen = 0; | 1482 | flen = 0; |
1483 | } | ||
1482 | /* | 1484 | /* |
1483 | * Can't do the allocation, give up. | 1485 | * Can't do the allocation, give up. |
1484 | */ | 1486 | */ |
@@ -2021,7 +2023,7 @@ xfs_alloc_get_freelist( | |||
2021 | /* | 2023 | /* |
2022 | * Get the block number and update the data structures. | 2024 | * Get the block number and update the data structures. |
2023 | */ | 2025 | */ |
2024 | bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT); | 2026 | bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]); |
2025 | be32_add(&agf->agf_flfirst, 1); | 2027 | be32_add(&agf->agf_flfirst, 1); |
2026 | xfs_trans_brelse(tp, agflbp); | 2028 | xfs_trans_brelse(tp, agflbp); |
2027 | if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) | 2029 | if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) |
@@ -2108,7 +2110,7 @@ xfs_alloc_put_freelist( | |||
2108 | { | 2110 | { |
2109 | xfs_agf_t *agf; /* a.g. freespace structure */ | 2111 | xfs_agf_t *agf; /* a.g. freespace structure */ |
2110 | xfs_agfl_t *agfl; /* a.g. free block array */ | 2112 | xfs_agfl_t *agfl; /* a.g. free block array */ |
2111 | xfs_agblock_t *blockp;/* pointer to array entry */ | 2113 | __be32 *blockp;/* pointer to array entry */ |
2112 | int error; | 2114 | int error; |
2113 | #ifdef XFS_ALLOC_TRACE | 2115 | #ifdef XFS_ALLOC_TRACE |
2114 | static char fname[] = "xfs_alloc_put_freelist"; | 2116 | static char fname[] = "xfs_alloc_put_freelist"; |
@@ -2132,7 +2134,7 @@ xfs_alloc_put_freelist( | |||
2132 | pag->pagf_flcount++; | 2134 | pag->pagf_flcount++; |
2133 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); | 2135 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); |
2134 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; | 2136 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; |
2135 | INT_SET(*blockp, ARCH_CONVERT, bno); | 2137 | *blockp = cpu_to_be32(bno); |
2136 | TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); | 2138 | TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); |
2137 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); | 2139 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); |
2138 | xfs_trans_log_buf(tp, agflbp, | 2140 | xfs_trans_log_buf(tp, agflbp, |
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 7446556e8021..74cadf95d4e8 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -92,6 +92,7 @@ xfs_alloc_delrec( | |||
92 | xfs_alloc_key_t *rkp; /* right block key pointer */ | 92 | xfs_alloc_key_t *rkp; /* right block key pointer */ |
93 | xfs_alloc_ptr_t *rpp; /* right block address pointer */ | 93 | xfs_alloc_ptr_t *rpp; /* right block address pointer */ |
94 | int rrecs=0; /* number of records in right block */ | 94 | int rrecs=0; /* number of records in right block */ |
95 | int numrecs; | ||
95 | xfs_alloc_rec_t *rrp; /* right block record pointer */ | 96 | xfs_alloc_rec_t *rrp; /* right block record pointer */ |
96 | xfs_btree_cur_t *tcur; /* temporary btree cursor */ | 97 | xfs_btree_cur_t *tcur; /* temporary btree cursor */ |
97 | 98 | ||
@@ -115,7 +116,8 @@ xfs_alloc_delrec( | |||
115 | /* | 116 | /* |
116 | * Fail if we're off the end of the block. | 117 | * Fail if we're off the end of the block. |
117 | */ | 118 | */ |
118 | if (ptr > be16_to_cpu(block->bb_numrecs)) { | 119 | numrecs = be16_to_cpu(block->bb_numrecs); |
120 | if (ptr > numrecs) { | ||
119 | *stat = 0; | 121 | *stat = 0; |
120 | return 0; | 122 | return 0; |
121 | } | 123 | } |
@@ -129,18 +131,18 @@ xfs_alloc_delrec( | |||
129 | lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur); | 131 | lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur); |
130 | lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur); | 132 | lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur); |
131 | #ifdef DEBUG | 133 | #ifdef DEBUG |
132 | for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) { | 134 | for (i = ptr; i < numrecs; i++) { |
133 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level))) | 135 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level))) |
134 | return error; | 136 | return error; |
135 | } | 137 | } |
136 | #endif | 138 | #endif |
137 | if (ptr < be16_to_cpu(block->bb_numrecs)) { | 139 | if (ptr < numrecs) { |
138 | memmove(&lkp[ptr - 1], &lkp[ptr], | 140 | memmove(&lkp[ptr - 1], &lkp[ptr], |
139 | (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp)); | 141 | (numrecs - ptr) * sizeof(*lkp)); |
140 | memmove(&lpp[ptr - 1], &lpp[ptr], | 142 | memmove(&lpp[ptr - 1], &lpp[ptr], |
141 | (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp)); | 143 | (numrecs - ptr) * sizeof(*lpp)); |
142 | xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); | 144 | xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1); |
143 | xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); | 145 | xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1); |
144 | } | 146 | } |
145 | } | 147 | } |
146 | /* | 148 | /* |
@@ -149,10 +151,10 @@ xfs_alloc_delrec( | |||
149 | */ | 151 | */ |
150 | else { | 152 | else { |
151 | lrp = XFS_ALLOC_REC_ADDR(block, 1, cur); | 153 | lrp = XFS_ALLOC_REC_ADDR(block, 1, cur); |
152 | if (ptr < be16_to_cpu(block->bb_numrecs)) { | 154 | if (ptr < numrecs) { |
153 | memmove(&lrp[ptr - 1], &lrp[ptr], | 155 | memmove(&lrp[ptr - 1], &lrp[ptr], |
154 | (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp)); | 156 | (numrecs - ptr) * sizeof(*lrp)); |
155 | xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); | 157 | xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1); |
156 | } | 158 | } |
157 | /* | 159 | /* |
158 | * If it's the first record in the block, we'll need a key | 160 | * If it's the first record in the block, we'll need a key |
@@ -167,7 +169,8 @@ xfs_alloc_delrec( | |||
167 | /* | 169 | /* |
168 | * Decrement and log the number of entries in the block. | 170 | * Decrement and log the number of entries in the block. |
169 | */ | 171 | */ |
170 | be16_add(&block->bb_numrecs, -1); | 172 | numrecs--; |
173 | block->bb_numrecs = cpu_to_be16(numrecs); | ||
171 | xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); | 174 | xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); |
172 | /* | 175 | /* |
173 | * See if the longest free extent in the allocation group was | 176 | * See if the longest free extent in the allocation group was |
@@ -181,14 +184,14 @@ xfs_alloc_delrec( | |||
181 | if (level == 0 && | 184 | if (level == 0 && |
182 | cur->bc_btnum == XFS_BTNUM_CNT && | 185 | cur->bc_btnum == XFS_BTNUM_CNT && |
183 | be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK && | 186 | be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK && |
184 | ptr > be16_to_cpu(block->bb_numrecs)) { | 187 | ptr > numrecs) { |
185 | ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1); | 188 | ASSERT(ptr == numrecs + 1); |
186 | /* | 189 | /* |
187 | * There are still records in the block. Grab the size | 190 | * There are still records in the block. Grab the size |
188 | * from the last one. | 191 | * from the last one. |
189 | */ | 192 | */ |
190 | if (be16_to_cpu(block->bb_numrecs)) { | 193 | if (numrecs) { |
191 | rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur); | 194 | rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur); |
192 | agf->agf_longest = rrp->ar_blockcount; | 195 | agf->agf_longest = rrp->ar_blockcount; |
193 | } | 196 | } |
194 | /* | 197 | /* |
@@ -211,7 +214,7 @@ xfs_alloc_delrec( | |||
211 | * and it's NOT the leaf level, | 214 | * and it's NOT the leaf level, |
212 | * then we can get rid of this level. | 215 | * then we can get rid of this level. |
213 | */ | 216 | */ |
214 | if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) { | 217 | if (numrecs == 1 && level > 0) { |
215 | /* | 218 | /* |
216 | * lpp is still set to the first pointer in the block. | 219 | * lpp is still set to the first pointer in the block. |
217 | * Make it the new root of the btree. | 220 | * Make it the new root of the btree. |
@@ -267,7 +270,7 @@ xfs_alloc_delrec( | |||
267 | * If the number of records remaining in the block is at least | 270 | * If the number of records remaining in the block is at least |
268 | * the minimum, we're done. | 271 | * the minimum, we're done. |
269 | */ | 272 | */ |
270 | if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { | 273 | if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { |
271 | if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i))) | 274 | if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i))) |
272 | return error; | 275 | return error; |
273 | *stat = 1; | 276 | *stat = 1; |
@@ -419,19 +422,21 @@ xfs_alloc_delrec( | |||
419 | * See if we can join with the left neighbor block. | 422 | * See if we can join with the left neighbor block. |
420 | */ | 423 | */ |
421 | if (lbno != NULLAGBLOCK && | 424 | if (lbno != NULLAGBLOCK && |
422 | lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { | 425 | lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { |
423 | /* | 426 | /* |
424 | * Set "right" to be the starting block, | 427 | * Set "right" to be the starting block, |
425 | * "left" to be the left neighbor. | 428 | * "left" to be the left neighbor. |
426 | */ | 429 | */ |
427 | rbno = bno; | 430 | rbno = bno; |
428 | right = block; | 431 | right = block; |
432 | rrecs = be16_to_cpu(right->bb_numrecs); | ||
429 | rbp = bp; | 433 | rbp = bp; |
430 | if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, | 434 | if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, |
431 | cur->bc_private.a.agno, lbno, 0, &lbp, | 435 | cur->bc_private.a.agno, lbno, 0, &lbp, |
432 | XFS_ALLOC_BTREE_REF))) | 436 | XFS_ALLOC_BTREE_REF))) |
433 | return error; | 437 | return error; |
434 | left = XFS_BUF_TO_ALLOC_BLOCK(lbp); | 438 | left = XFS_BUF_TO_ALLOC_BLOCK(lbp); |
439 | lrecs = be16_to_cpu(left->bb_numrecs); | ||
435 | if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) | 440 | if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) |
436 | return error; | 441 | return error; |
437 | } | 442 | } |
@@ -439,20 +444,21 @@ xfs_alloc_delrec( | |||
439 | * If that won't work, see if we can join with the right neighbor block. | 444 | * If that won't work, see if we can join with the right neighbor block. |
440 | */ | 445 | */ |
441 | else if (rbno != NULLAGBLOCK && | 446 | else if (rbno != NULLAGBLOCK && |
442 | rrecs + be16_to_cpu(block->bb_numrecs) <= | 447 | rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { |
443 | XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { | ||
444 | /* | 448 | /* |
445 | * Set "left" to be the starting block, | 449 | * Set "left" to be the starting block, |
446 | * "right" to be the right neighbor. | 450 | * "right" to be the right neighbor. |
447 | */ | 451 | */ |
448 | lbno = bno; | 452 | lbno = bno; |
449 | left = block; | 453 | left = block; |
454 | lrecs = be16_to_cpu(left->bb_numrecs); | ||
450 | lbp = bp; | 455 | lbp = bp; |
451 | if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, | 456 | if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, |
452 | cur->bc_private.a.agno, rbno, 0, &rbp, | 457 | cur->bc_private.a.agno, rbno, 0, &rbp, |
453 | XFS_ALLOC_BTREE_REF))) | 458 | XFS_ALLOC_BTREE_REF))) |
454 | return error; | 459 | return error; |
455 | right = XFS_BUF_TO_ALLOC_BLOCK(rbp); | 460 | right = XFS_BUF_TO_ALLOC_BLOCK(rbp); |
461 | rrecs = be16_to_cpu(right->bb_numrecs); | ||
456 | if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) | 462 | if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) |
457 | return error; | 463 | return error; |
458 | } | 464 | } |
@@ -474,34 +480,28 @@ xfs_alloc_delrec( | |||
474 | /* | 480 | /* |
475 | * It's a non-leaf. Move keys and pointers. | 481 | * It's a non-leaf. Move keys and pointers. |
476 | */ | 482 | */ |
477 | lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); | 483 | lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur); |
478 | lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); | 484 | lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur); |
479 | rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur); | 485 | rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur); |
480 | rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur); | 486 | rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur); |
481 | #ifdef DEBUG | 487 | #ifdef DEBUG |
482 | for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { | 488 | for (i = 0; i < rrecs; i++) { |
483 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level))) | 489 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level))) |
484 | return error; | 490 | return error; |
485 | } | 491 | } |
486 | #endif | 492 | #endif |
487 | memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp)); | 493 | memcpy(lkp, rkp, rrecs * sizeof(*lkp)); |
488 | memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp)); | 494 | memcpy(lpp, rpp, rrecs * sizeof(*lpp)); |
489 | xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, | 495 | xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs); |
490 | be16_to_cpu(left->bb_numrecs) + | 496 | xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs); |
491 | be16_to_cpu(right->bb_numrecs)); | ||
492 | xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, | ||
493 | be16_to_cpu(left->bb_numrecs) + | ||
494 | be16_to_cpu(right->bb_numrecs)); | ||
495 | } else { | 497 | } else { |
496 | /* | 498 | /* |
497 | * It's a leaf. Move records. | 499 | * It's a leaf. Move records. |
498 | */ | 500 | */ |
499 | lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); | 501 | lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur); |
500 | rrp = XFS_ALLOC_REC_ADDR(right, 1, cur); | 502 | rrp = XFS_ALLOC_REC_ADDR(right, 1, cur); |
501 | memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp)); | 503 | memcpy(lrp, rrp, rrecs * sizeof(*lrp)); |
502 | xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, | 504 | xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs); |
503 | be16_to_cpu(left->bb_numrecs) + | ||
504 | be16_to_cpu(right->bb_numrecs)); | ||
505 | } | 505 | } |
506 | /* | 506 | /* |
507 | * If we joined with the left neighbor, set the buffer in the | 507 | * If we joined with the left neighbor, set the buffer in the |
@@ -509,7 +509,7 @@ xfs_alloc_delrec( | |||
509 | */ | 509 | */ |
510 | if (bp != lbp) { | 510 | if (bp != lbp) { |
511 | xfs_btree_setbuf(cur, level, lbp); | 511 | xfs_btree_setbuf(cur, level, lbp); |
512 | cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs); | 512 | cur->bc_ptrs[level] += lrecs; |
513 | } | 513 | } |
514 | /* | 514 | /* |
515 | * If we joined with the right neighbor and there's a level above | 515 | * If we joined with the right neighbor and there's a level above |
@@ -521,7 +521,8 @@ xfs_alloc_delrec( | |||
521 | /* | 521 | /* |
522 | * Fix up the number of records in the surviving block. | 522 | * Fix up the number of records in the surviving block. |
523 | */ | 523 | */ |
524 | be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs)); | 524 | lrecs += rrecs; |
525 | left->bb_numrecs = cpu_to_be16(lrecs); | ||
525 | /* | 526 | /* |
526 | * Fix up the right block pointer in the surviving block, and log it. | 527 | * Fix up the right block pointer in the surviving block, and log it. |
527 | */ | 528 | */ |
@@ -608,6 +609,7 @@ xfs_alloc_insrec( | |||
608 | xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */ | 609 | xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */ |
609 | xfs_alloc_key_t nkey; /* new key value, from split */ | 610 | xfs_alloc_key_t nkey; /* new key value, from split */ |
610 | xfs_alloc_rec_t nrec; /* new record value, for caller */ | 611 | xfs_alloc_rec_t nrec; /* new record value, for caller */ |
612 | int numrecs; | ||
611 | int optr; /* old ptr value */ | 613 | int optr; /* old ptr value */ |
612 | xfs_alloc_ptr_t *pp; /* pointer to btree addresses */ | 614 | xfs_alloc_ptr_t *pp; /* pointer to btree addresses */ |
613 | int ptr; /* index in btree block for this rec */ | 615 | int ptr; /* index in btree block for this rec */ |
@@ -653,13 +655,14 @@ xfs_alloc_insrec( | |||
653 | */ | 655 | */ |
654 | bp = cur->bc_bufs[level]; | 656 | bp = cur->bc_bufs[level]; |
655 | block = XFS_BUF_TO_ALLOC_BLOCK(bp); | 657 | block = XFS_BUF_TO_ALLOC_BLOCK(bp); |
658 | numrecs = be16_to_cpu(block->bb_numrecs); | ||
656 | #ifdef DEBUG | 659 | #ifdef DEBUG |
657 | if ((error = xfs_btree_check_sblock(cur, block, level, bp))) | 660 | if ((error = xfs_btree_check_sblock(cur, block, level, bp))) |
658 | return error; | 661 | return error; |
659 | /* | 662 | /* |
660 | * Check that the new entry is being inserted in the right place. | 663 | * Check that the new entry is being inserted in the right place. |
661 | */ | 664 | */ |
662 | if (ptr <= be16_to_cpu(block->bb_numrecs)) { | 665 | if (ptr <= numrecs) { |
663 | if (level == 0) { | 666 | if (level == 0) { |
664 | rp = XFS_ALLOC_REC_ADDR(block, ptr, cur); | 667 | rp = XFS_ALLOC_REC_ADDR(block, ptr, cur); |
665 | xfs_btree_check_rec(cur->bc_btnum, recp, rp); | 668 | xfs_btree_check_rec(cur->bc_btnum, recp, rp); |
@@ -670,12 +673,12 @@ xfs_alloc_insrec( | |||
670 | } | 673 | } |
671 | #endif | 674 | #endif |
672 | nbno = NULLAGBLOCK; | 675 | nbno = NULLAGBLOCK; |
673 | ncur = (xfs_btree_cur_t *)0; | 676 | ncur = NULL; |
674 | /* | 677 | /* |
675 | * If the block is full, we can't insert the new entry until we | 678 | * If the block is full, we can't insert the new entry until we |
676 | * make the block un-full. | 679 | * make the block un-full. |
677 | */ | 680 | */ |
678 | if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { | 681 | if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { |
679 | /* | 682 | /* |
680 | * First, try shifting an entry to the right neighbor. | 683 | * First, try shifting an entry to the right neighbor. |
681 | */ | 684 | */ |
@@ -729,6 +732,7 @@ xfs_alloc_insrec( | |||
729 | * At this point we know there's room for our new entry in the block | 732 | * At this point we know there's room for our new entry in the block |
730 | * we're pointing at. | 733 | * we're pointing at. |
731 | */ | 734 | */ |
735 | numrecs = be16_to_cpu(block->bb_numrecs); | ||
732 | if (level > 0) { | 736 | if (level > 0) { |
733 | /* | 737 | /* |
734 | * It's a non-leaf entry. Make a hole for the new data | 738 | * It's a non-leaf entry. Make a hole for the new data |
@@ -737,15 +741,15 @@ xfs_alloc_insrec( | |||
737 | kp = XFS_ALLOC_KEY_ADDR(block, 1, cur); | 741 | kp = XFS_ALLOC_KEY_ADDR(block, 1, cur); |
738 | pp = XFS_ALLOC_PTR_ADDR(block, 1, cur); | 742 | pp = XFS_ALLOC_PTR_ADDR(block, 1, cur); |
739 | #ifdef DEBUG | 743 | #ifdef DEBUG |
740 | for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) { | 744 | for (i = numrecs; i >= ptr; i--) { |
741 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level))) | 745 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level))) |
742 | return error; | 746 | return error; |
743 | } | 747 | } |
744 | #endif | 748 | #endif |
745 | memmove(&kp[ptr], &kp[ptr - 1], | 749 | memmove(&kp[ptr], &kp[ptr - 1], |
746 | (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp)); | 750 | (numrecs - ptr + 1) * sizeof(*kp)); |
747 | memmove(&pp[ptr], &pp[ptr - 1], | 751 | memmove(&pp[ptr], &pp[ptr - 1], |
748 | (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp)); | 752 | (numrecs - ptr + 1) * sizeof(*pp)); |
749 | #ifdef DEBUG | 753 | #ifdef DEBUG |
750 | if ((error = xfs_btree_check_sptr(cur, *bnop, level))) | 754 | if ((error = xfs_btree_check_sptr(cur, *bnop, level))) |
751 | return error; | 755 | return error; |
@@ -755,11 +759,12 @@ xfs_alloc_insrec( | |||
755 | */ | 759 | */ |
756 | kp[ptr - 1] = key; | 760 | kp[ptr - 1] = key; |
757 | pp[ptr - 1] = cpu_to_be32(*bnop); | 761 | pp[ptr - 1] = cpu_to_be32(*bnop); |
758 | be16_add(&block->bb_numrecs, 1); | 762 | numrecs++; |
759 | xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); | 763 | block->bb_numrecs = cpu_to_be16(numrecs); |
760 | xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); | 764 | xfs_alloc_log_keys(cur, bp, ptr, numrecs); |
765 | xfs_alloc_log_ptrs(cur, bp, ptr, numrecs); | ||
761 | #ifdef DEBUG | 766 | #ifdef DEBUG |
762 | if (ptr < be16_to_cpu(block->bb_numrecs)) | 767 | if (ptr < numrecs) |
763 | xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1, | 768 | xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1, |
764 | kp + ptr); | 769 | kp + ptr); |
765 | #endif | 770 | #endif |
@@ -769,16 +774,17 @@ xfs_alloc_insrec( | |||
769 | */ | 774 | */ |
770 | rp = XFS_ALLOC_REC_ADDR(block, 1, cur); | 775 | rp = XFS_ALLOC_REC_ADDR(block, 1, cur); |
771 | memmove(&rp[ptr], &rp[ptr - 1], | 776 | memmove(&rp[ptr], &rp[ptr - 1], |
772 | (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp)); | 777 | (numrecs - ptr + 1) * sizeof(*rp)); |
773 | /* | 778 | /* |
774 | * Now stuff the new record in, bump numrecs | 779 | * Now stuff the new record in, bump numrecs |
775 | * and log the new data. | 780 | * and log the new data. |
776 | */ | 781 | */ |
777 | rp[ptr - 1] = *recp; /* INT_: struct copy */ | 782 | rp[ptr - 1] = *recp; |
778 | be16_add(&block->bb_numrecs, 1); | 783 | numrecs++; |
779 | xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); | 784 | block->bb_numrecs = cpu_to_be16(numrecs); |
785 | xfs_alloc_log_recs(cur, bp, ptr, numrecs); | ||
780 | #ifdef DEBUG | 786 | #ifdef DEBUG |
781 | if (ptr < be16_to_cpu(block->bb_numrecs)) | 787 | if (ptr < numrecs) |
782 | xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1, | 788 | xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1, |
783 | rp + ptr); | 789 | rp + ptr); |
784 | #endif | 790 | #endif |
@@ -819,8 +825,8 @@ xfs_alloc_insrec( | |||
819 | */ | 825 | */ |
820 | *bnop = nbno; | 826 | *bnop = nbno; |
821 | if (nbno != NULLAGBLOCK) { | 827 | if (nbno != NULLAGBLOCK) { |
822 | *recp = nrec; /* INT_: struct copy */ | 828 | *recp = nrec; |
823 | *curp = ncur; /* INT_: struct copy */ | 829 | *curp = ncur; |
824 | } | 830 | } |
825 | *stat = 1; | 831 | *stat = 1; |
826 | return 0; | 832 | return 0; |
@@ -981,7 +987,7 @@ xfs_alloc_lookup( | |||
981 | */ | 987 | */ |
982 | bp = cur->bc_bufs[level]; | 988 | bp = cur->bc_bufs[level]; |
983 | if (bp && XFS_BUF_ADDR(bp) != d) | 989 | if (bp && XFS_BUF_ADDR(bp) != d) |
984 | bp = (xfs_buf_t *)0; | 990 | bp = NULL; |
985 | if (!bp) { | 991 | if (!bp) { |
986 | /* | 992 | /* |
987 | * Need to get a new buffer. Read it, then | 993 | * Need to get a new buffer. Read it, then |
@@ -1229,7 +1235,7 @@ xfs_alloc_lshift( | |||
1229 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) | 1235 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) |
1230 | return error; | 1236 | return error; |
1231 | #endif | 1237 | #endif |
1232 | *lpp = *rpp; /* INT_: copy */ | 1238 | *lpp = *rpp; |
1233 | xfs_alloc_log_ptrs(cur, lbp, nrec, nrec); | 1239 | xfs_alloc_log_ptrs(cur, lbp, nrec, nrec); |
1234 | xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp); | 1240 | xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp); |
1235 | } | 1241 | } |
@@ -1406,8 +1412,8 @@ xfs_alloc_newroot( | |||
1406 | 1412 | ||
1407 | kp = XFS_ALLOC_KEY_ADDR(new, 1, cur); | 1413 | kp = XFS_ALLOC_KEY_ADDR(new, 1, cur); |
1408 | if (be16_to_cpu(left->bb_level) > 0) { | 1414 | if (be16_to_cpu(left->bb_level) > 0) { |
1409 | kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */ | 1415 | kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); |
1410 | kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */ | 1416 | kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur); |
1411 | } else { | 1417 | } else { |
1412 | xfs_alloc_rec_t *rp; /* btree record pointer */ | 1418 | xfs_alloc_rec_t *rp; /* btree record pointer */ |
1413 | 1419 | ||
@@ -1527,8 +1533,8 @@ xfs_alloc_rshift( | |||
1527 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) | 1533 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) |
1528 | return error; | 1534 | return error; |
1529 | #endif | 1535 | #endif |
1530 | *rkp = *lkp; /* INT_: copy */ | 1536 | *rkp = *lkp; |
1531 | *rpp = *lpp; /* INT_: copy */ | 1537 | *rpp = *lpp; |
1532 | xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1538 | xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1533 | xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1539 | xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1534 | xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1); | 1540 | xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1); |
@@ -2044,7 +2050,7 @@ xfs_alloc_insert( | |||
2044 | nbno = NULLAGBLOCK; | 2050 | nbno = NULLAGBLOCK; |
2045 | nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock); | 2051 | nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock); |
2046 | nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount); | 2052 | nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount); |
2047 | ncur = (xfs_btree_cur_t *)0; | 2053 | ncur = NULL; |
2048 | pcur = cur; | 2054 | pcur = cur; |
2049 | /* | 2055 | /* |
2050 | * Loop going up the tree, starting at the leaf level. | 2056 | * Loop going up the tree, starting at the leaf level. |
@@ -2076,7 +2082,7 @@ xfs_alloc_insert( | |||
2076 | */ | 2082 | */ |
2077 | if (ncur) { | 2083 | if (ncur) { |
2078 | pcur = ncur; | 2084 | pcur = ncur; |
2079 | ncur = (xfs_btree_cur_t *)0; | 2085 | ncur = NULL; |
2080 | } | 2086 | } |
2081 | } while (nbno != NULLAGBLOCK); | 2087 | } while (nbno != NULLAGBLOCK); |
2082 | *stat = i; | 2088 | *stat = i; |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 1a2101043275..9ada7bdbae52 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -91,7 +91,6 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state); | |||
91 | /* | 91 | /* |
92 | * Routines to manipulate out-of-line attribute values. | 92 | * Routines to manipulate out-of-line attribute values. |
93 | */ | 93 | */ |
94 | STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args); | ||
95 | STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); | 94 | STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); |
96 | STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); | 95 | STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); |
97 | 96 | ||
@@ -180,7 +179,7 @@ xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp, | |||
180 | return(error); | 179 | return(error); |
181 | } | 180 | } |
182 | 181 | ||
183 | STATIC int | 182 | int |
184 | xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, | 183 | xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, |
185 | char *value, int valuelen, int flags) | 184 | char *value, int valuelen, int flags) |
186 | { | 185 | { |
@@ -440,7 +439,7 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f | |||
440 | * Generic handler routine to remove a name from an attribute list. | 439 | * Generic handler routine to remove a name from an attribute list. |
441 | * Transitions attribute list from Btree to shortform as necessary. | 440 | * Transitions attribute list from Btree to shortform as necessary. |
442 | */ | 441 | */ |
443 | STATIC int | 442 | int |
444 | xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) | 443 | xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) |
445 | { | 444 | { |
446 | xfs_da_args_t args; | 445 | xfs_da_args_t args; |
@@ -591,6 +590,110 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) | |||
591 | return xfs_attr_remove_int(dp, name, namelen, flags); | 590 | return xfs_attr_remove_int(dp, name, namelen, flags); |
592 | } | 591 | } |
593 | 592 | ||
593 | int /* error */ | ||
594 | xfs_attr_list_int(xfs_attr_list_context_t *context) | ||
595 | { | ||
596 | int error; | ||
597 | xfs_inode_t *dp = context->dp; | ||
598 | |||
599 | /* | ||
600 | * Decide on what work routines to call based on the inode size. | ||
601 | */ | ||
602 | if (XFS_IFORK_Q(dp) == 0 || | ||
603 | (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && | ||
604 | dp->i_d.di_anextents == 0)) { | ||
605 | error = 0; | ||
606 | } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { | ||
607 | error = xfs_attr_shortform_list(context); | ||
608 | } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { | ||
609 | error = xfs_attr_leaf_list(context); | ||
610 | } else { | ||
611 | error = xfs_attr_node_list(context); | ||
612 | } | ||
613 | return error; | ||
614 | } | ||
615 | |||
616 | #define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \ | ||
617 | (((struct attrlist_ent *) 0)->a_name - (char *) 0) | ||
618 | #define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \ | ||
619 | ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \ | ||
620 | & ~(sizeof(u_int32_t)-1)) | ||
621 | |||
622 | /* | ||
623 | * Format an attribute and copy it out to the user's buffer. | ||
624 | * Take care to check values and protect against them changing later, | ||
625 | * we may be reading them directly out of a user buffer. | ||
626 | */ | ||
627 | /*ARGSUSED*/ | ||
628 | STATIC int | ||
629 | xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp, | ||
630 | char *name, int namelen, | ||
631 | int valuelen, char *value) | ||
632 | { | ||
633 | attrlist_ent_t *aep; | ||
634 | int arraytop; | ||
635 | |||
636 | ASSERT(!(context->flags & ATTR_KERNOVAL)); | ||
637 | ASSERT(context->count >= 0); | ||
638 | ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); | ||
639 | ASSERT(context->firstu >= sizeof(*context->alist)); | ||
640 | ASSERT(context->firstu <= context->bufsize); | ||
641 | |||
642 | arraytop = sizeof(*context->alist) + | ||
643 | context->count * sizeof(context->alist->al_offset[0]); | ||
644 | context->firstu -= ATTR_ENTSIZE(namelen); | ||
645 | if (context->firstu < arraytop) { | ||
646 | xfs_attr_trace_l_c("buffer full", context); | ||
647 | context->alist->al_more = 1; | ||
648 | context->seen_enough = 1; | ||
649 | return 1; | ||
650 | } | ||
651 | |||
652 | aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]); | ||
653 | aep->a_valuelen = valuelen; | ||
654 | memcpy(aep->a_name, name, namelen); | ||
655 | aep->a_name[ namelen ] = 0; | ||
656 | context->alist->al_offset[ context->count++ ] = context->firstu; | ||
657 | context->alist->al_count = context->count; | ||
658 | xfs_attr_trace_l_c("add", context); | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | STATIC int | ||
663 | xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp, | ||
664 | char *name, int namelen, | ||
665 | int valuelen, char *value) | ||
666 | { | ||
667 | char *offset; | ||
668 | int arraytop; | ||
669 | |||
670 | ASSERT(context->count >= 0); | ||
671 | |||
672 | arraytop = context->count + namesp->attr_namelen + namelen + 1; | ||
673 | if (arraytop > context->firstu) { | ||
674 | context->count = -1; /* insufficient space */ | ||
675 | return 1; | ||
676 | } | ||
677 | offset = (char *)context->alist + context->count; | ||
678 | strncpy(offset, namesp->attr_name, namesp->attr_namelen); | ||
679 | offset += namesp->attr_namelen; | ||
680 | strncpy(offset, name, namelen); /* real name */ | ||
681 | offset += namelen; | ||
682 | *offset = '\0'; | ||
683 | context->count += namesp->attr_namelen + namelen + 1; | ||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | /*ARGSUSED*/ | ||
688 | STATIC int | ||
689 | xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp, | ||
690 | char *name, int namelen, | ||
691 | int valuelen, char *value) | ||
692 | { | ||
693 | context->count += namesp->attr_namelen + namelen + 1; | ||
694 | return 0; | ||
695 | } | ||
696 | |||
594 | /* | 697 | /* |
595 | * Generate a list of extended attribute names and optionally | 698 | * Generate a list of extended attribute names and optionally |
596 | * also value lengths. Positive return value follows the XFS | 699 | * also value lengths. Positive return value follows the XFS |
@@ -615,13 +718,13 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, | |||
615 | return(XFS_ERROR(EINVAL)); | 718 | return(XFS_ERROR(EINVAL)); |
616 | if ((cursor->initted == 0) && | 719 | if ((cursor->initted == 0) && |
617 | (cursor->hashval || cursor->blkno || cursor->offset)) | 720 | (cursor->hashval || cursor->blkno || cursor->offset)) |
618 | return(XFS_ERROR(EINVAL)); | 721 | return XFS_ERROR(EINVAL); |
619 | 722 | ||
620 | /* | 723 | /* |
621 | * Check for a properly aligned buffer. | 724 | * Check for a properly aligned buffer. |
622 | */ | 725 | */ |
623 | if (((long)buffer) & (sizeof(int)-1)) | 726 | if (((long)buffer) & (sizeof(int)-1)) |
624 | return(XFS_ERROR(EFAULT)); | 727 | return XFS_ERROR(EFAULT); |
625 | if (flags & ATTR_KERNOVAL) | 728 | if (flags & ATTR_KERNOVAL) |
626 | bufsize = 0; | 729 | bufsize = 0; |
627 | 730 | ||
@@ -634,53 +737,47 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, | |||
634 | context.dupcnt = 0; | 737 | context.dupcnt = 0; |
635 | context.resynch = 1; | 738 | context.resynch = 1; |
636 | context.flags = flags; | 739 | context.flags = flags; |
637 | if (!(flags & ATTR_KERNAMELS)) { | 740 | context.seen_enough = 0; |
741 | context.alist = (attrlist_t *)buffer; | ||
742 | context.put_value = 0; | ||
743 | |||
744 | if (flags & ATTR_KERNAMELS) { | ||
745 | context.bufsize = bufsize; | ||
746 | context.firstu = context.bufsize; | ||
747 | if (flags & ATTR_KERNOVAL) | ||
748 | context.put_listent = xfs_attr_kern_list_sizes; | ||
749 | else | ||
750 | context.put_listent = xfs_attr_kern_list; | ||
751 | } else { | ||
638 | context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */ | 752 | context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */ |
639 | context.firstu = context.bufsize; | 753 | context.firstu = context.bufsize; |
640 | context.alist = (attrlist_t *)buffer; | ||
641 | context.alist->al_count = 0; | 754 | context.alist->al_count = 0; |
642 | context.alist->al_more = 0; | 755 | context.alist->al_more = 0; |
643 | context.alist->al_offset[0] = context.bufsize; | 756 | context.alist->al_offset[0] = context.bufsize; |
644 | } | 757 | context.put_listent = xfs_attr_put_listent; |
645 | else { | ||
646 | context.bufsize = bufsize; | ||
647 | context.firstu = context.bufsize; | ||
648 | context.alist = (attrlist_t *)buffer; | ||
649 | } | 758 | } |
650 | 759 | ||
651 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 760 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
652 | return (EIO); | 761 | return EIO; |
653 | 762 | ||
654 | xfs_ilock(dp, XFS_ILOCK_SHARED); | 763 | xfs_ilock(dp, XFS_ILOCK_SHARED); |
655 | /* | ||
656 | * Decide on what work routines to call based on the inode size. | ||
657 | */ | ||
658 | xfs_attr_trace_l_c("syscall start", &context); | 764 | xfs_attr_trace_l_c("syscall start", &context); |
659 | if (XFS_IFORK_Q(dp) == 0 || | 765 | |
660 | (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && | 766 | error = xfs_attr_list_int(&context); |
661 | dp->i_d.di_anextents == 0)) { | 767 | |
662 | error = 0; | ||
663 | } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { | ||
664 | error = xfs_attr_shortform_list(&context); | ||
665 | } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { | ||
666 | error = xfs_attr_leaf_list(&context); | ||
667 | } else { | ||
668 | error = xfs_attr_node_list(&context); | ||
669 | } | ||
670 | xfs_iunlock(dp, XFS_ILOCK_SHARED); | 768 | xfs_iunlock(dp, XFS_ILOCK_SHARED); |
671 | xfs_attr_trace_l_c("syscall end", &context); | 769 | xfs_attr_trace_l_c("syscall end", &context); |
672 | 770 | ||
673 | if (!(context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS))) { | 771 | if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) { |
674 | ASSERT(error >= 0); | 772 | /* must return negated buffer size or the error */ |
675 | } | ||
676 | else { /* must return negated buffer size or the error */ | ||
677 | if (context.count < 0) | 773 | if (context.count < 0) |
678 | error = XFS_ERROR(ERANGE); | 774 | error = XFS_ERROR(ERANGE); |
679 | else | 775 | else |
680 | error = -context.count; | 776 | error = -context.count; |
681 | } | 777 | } else |
778 | ASSERT(error >= 0); | ||
682 | 779 | ||
683 | return(error); | 780 | return error; |
684 | } | 781 | } |
685 | 782 | ||
686 | int /* error */ | 783 | int /* error */ |
@@ -1122,19 +1219,19 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context) | |||
1122 | context->cursor->blkno = 0; | 1219 | context->cursor->blkno = 0; |
1123 | error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK); | 1220 | error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK); |
1124 | if (error) | 1221 | if (error) |
1125 | return(error); | 1222 | return XFS_ERROR(error); |
1126 | ASSERT(bp != NULL); | 1223 | ASSERT(bp != NULL); |
1127 | leaf = bp->data; | 1224 | leaf = bp->data; |
1128 | if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) { | 1225 | if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) { |
1129 | XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, | 1226 | XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, |
1130 | context->dp->i_mount, leaf); | 1227 | context->dp->i_mount, leaf); |
1131 | xfs_da_brelse(NULL, bp); | 1228 | xfs_da_brelse(NULL, bp); |
1132 | return(XFS_ERROR(EFSCORRUPTED)); | 1229 | return XFS_ERROR(EFSCORRUPTED); |
1133 | } | 1230 | } |
1134 | 1231 | ||
1135 | (void)xfs_attr_leaf_list_int(bp, context); | 1232 | error = xfs_attr_leaf_list_int(bp, context); |
1136 | xfs_da_brelse(NULL, bp); | 1233 | xfs_da_brelse(NULL, bp); |
1137 | return(0); | 1234 | return XFS_ERROR(error); |
1138 | } | 1235 | } |
1139 | 1236 | ||
1140 | 1237 | ||
@@ -1858,8 +1955,12 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1858 | return(XFS_ERROR(EFSCORRUPTED)); | 1955 | return(XFS_ERROR(EFSCORRUPTED)); |
1859 | } | 1956 | } |
1860 | error = xfs_attr_leaf_list_int(bp, context); | 1957 | error = xfs_attr_leaf_list_int(bp, context); |
1861 | if (error || !leaf->hdr.info.forw) | 1958 | if (error) { |
1862 | break; /* not really an error, buffer full or EOF */ | 1959 | xfs_da_brelse(NULL, bp); |
1960 | return error; | ||
1961 | } | ||
1962 | if (context->seen_enough || leaf->hdr.info.forw == 0) | ||
1963 | break; | ||
1863 | cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); | 1964 | cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); |
1864 | xfs_da_brelse(NULL, bp); | 1965 | xfs_da_brelse(NULL, bp); |
1865 | error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, | 1966 | error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, |
@@ -1886,7 +1987,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) | |||
1886 | * Read the value associated with an attribute from the out-of-line buffer | 1987 | * Read the value associated with an attribute from the out-of-line buffer |
1887 | * that we stored it in. | 1988 | * that we stored it in. |
1888 | */ | 1989 | */ |
1889 | STATIC int | 1990 | int |
1890 | xfs_attr_rmtval_get(xfs_da_args_t *args) | 1991 | xfs_attr_rmtval_get(xfs_da_args_t *args) |
1891 | { | 1992 | { |
1892 | xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; | 1993 | xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; |
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index 981633f6c077..783977d3ea71 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | struct cred; | 38 | struct cred; |
39 | struct bhv_vnode; | 39 | struct bhv_vnode; |
40 | struct xfs_attr_list_context; | ||
40 | 41 | ||
41 | typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int); | 42 | typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int); |
42 | typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int); | 43 | typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int); |
@@ -160,13 +161,16 @@ struct xfs_da_args; | |||
160 | */ | 161 | */ |
161 | int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *); | 162 | int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *); |
162 | int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *); | 163 | int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *); |
164 | int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int); | ||
163 | int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *); | 165 | int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *); |
164 | int xfs_attr_list(bhv_desc_t *, char *, int, int, | 166 | int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int); |
165 | struct attrlist_cursor_kern *, struct cred *); | 167 | int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *); |
168 | int xfs_attr_list_int(struct xfs_attr_list_context *); | ||
166 | int xfs_attr_inactive(struct xfs_inode *dp); | 169 | int xfs_attr_inactive(struct xfs_inode *dp); |
167 | 170 | ||
168 | int xfs_attr_shortform_getvalue(struct xfs_da_args *); | 171 | int xfs_attr_shortform_getvalue(struct xfs_da_args *); |
169 | int xfs_attr_fetch(struct xfs_inode *, const char *, int, | 172 | int xfs_attr_fetch(struct xfs_inode *, const char *, int, |
170 | char *, int *, int, struct cred *); | 173 | char *, int *, int, struct cred *); |
174 | int xfs_attr_rmtval_get(struct xfs_da_args *args); | ||
171 | 175 | ||
172 | #endif /* __XFS_ATTR_H__ */ | 176 | #endif /* __XFS_ATTR_H__ */ |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 9455051f0120..9719bbef122c 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -89,9 +89,46 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, | |||
89 | int dst_start, int move_count, | 89 | int dst_start, int move_count, |
90 | xfs_mount_t *mp); | 90 | xfs_mount_t *mp); |
91 | STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); | 91 | STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); |
92 | STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context, | 92 | |
93 | attrnames_t *, char *name, int namelen, | 93 | /*======================================================================== |
94 | int valuelen); | 94 | * Namespace helper routines |
95 | *========================================================================*/ | ||
96 | |||
97 | STATIC inline attrnames_t * | ||
98 | xfs_attr_flags_namesp(int flags) | ||
99 | { | ||
100 | return ((flags & XFS_ATTR_SECURE) ? &attr_secure: | ||
101 | ((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user)); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * If namespace bits don't match return 0. | ||
106 | * If all match then return 1. | ||
107 | */ | ||
108 | STATIC inline int | ||
109 | xfs_attr_namesp_match(int arg_flags, int ondisk_flags) | ||
110 | { | ||
111 | return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * If namespace bits don't match and we don't have an override for it | ||
116 | * then return 0. | ||
117 | * If all match or are overridable then return 1. | ||
118 | */ | ||
119 | STATIC inline int | ||
120 | xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags) | ||
121 | { | ||
122 | if (((arg_flags & ATTR_SECURE) == 0) != | ||
123 | ((ondisk_flags & XFS_ATTR_SECURE) == 0) && | ||
124 | !(arg_flags & ATTR_KERNORMALS)) | ||
125 | return 0; | ||
126 | if (((arg_flags & ATTR_ROOT) == 0) != | ||
127 | ((ondisk_flags & XFS_ATTR_ROOT) == 0) && | ||
128 | !(arg_flags & ATTR_KERNROOTLS)) | ||
129 | return 0; | ||
130 | return 1; | ||
131 | } | ||
95 | 132 | ||
96 | 133 | ||
97 | /*======================================================================== | 134 | /*======================================================================== |
@@ -228,11 +265,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) | |||
228 | continue; | 265 | continue; |
229 | if (memcmp(args->name, sfe->nameval, args->namelen) != 0) | 266 | if (memcmp(args->name, sfe->nameval, args->namelen) != 0) |
230 | continue; | 267 | continue; |
231 | if (((args->flags & ATTR_SECURE) != 0) != | 268 | if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
232 | ((sfe->flags & XFS_ATTR_SECURE) != 0)) | ||
233 | continue; | ||
234 | if (((args->flags & ATTR_ROOT) != 0) != | ||
235 | ((sfe->flags & XFS_ATTR_ROOT) != 0)) | ||
236 | continue; | 269 | continue; |
237 | ASSERT(0); | 270 | ASSERT(0); |
238 | #endif | 271 | #endif |
@@ -246,8 +279,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) | |||
246 | 279 | ||
247 | sfe->namelen = args->namelen; | 280 | sfe->namelen = args->namelen; |
248 | sfe->valuelen = args->valuelen; | 281 | sfe->valuelen = args->valuelen; |
249 | sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : | 282 | sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); |
250 | ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); | ||
251 | memcpy(sfe->nameval, args->name, args->namelen); | 283 | memcpy(sfe->nameval, args->name, args->namelen); |
252 | memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); | 284 | memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); |
253 | sf->hdr.count++; | 285 | sf->hdr.count++; |
@@ -282,11 +314,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) | |||
282 | continue; | 314 | continue; |
283 | if (memcmp(sfe->nameval, args->name, args->namelen) != 0) | 315 | if (memcmp(sfe->nameval, args->name, args->namelen) != 0) |
284 | continue; | 316 | continue; |
285 | if (((args->flags & ATTR_SECURE) != 0) != | 317 | if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
286 | ((sfe->flags & XFS_ATTR_SECURE) != 0)) | ||
287 | continue; | ||
288 | if (((args->flags & ATTR_ROOT) != 0) != | ||
289 | ((sfe->flags & XFS_ATTR_ROOT) != 0)) | ||
290 | continue; | 318 | continue; |
291 | break; | 319 | break; |
292 | } | 320 | } |
@@ -363,11 +391,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args) | |||
363 | continue; | 391 | continue; |
364 | if (memcmp(args->name, sfe->nameval, args->namelen) != 0) | 392 | if (memcmp(args->name, sfe->nameval, args->namelen) != 0) |
365 | continue; | 393 | continue; |
366 | if (((args->flags & ATTR_SECURE) != 0) != | 394 | if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
367 | ((sfe->flags & XFS_ATTR_SECURE) != 0)) | ||
368 | continue; | ||
369 | if (((args->flags & ATTR_ROOT) != 0) != | ||
370 | ((sfe->flags & XFS_ATTR_ROOT) != 0)) | ||
371 | continue; | 395 | continue; |
372 | return(XFS_ERROR(EEXIST)); | 396 | return(XFS_ERROR(EEXIST)); |
373 | } | 397 | } |
@@ -394,11 +418,7 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args) | |||
394 | continue; | 418 | continue; |
395 | if (memcmp(args->name, sfe->nameval, args->namelen) != 0) | 419 | if (memcmp(args->name, sfe->nameval, args->namelen) != 0) |
396 | continue; | 420 | continue; |
397 | if (((args->flags & ATTR_SECURE) != 0) != | 421 | if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
398 | ((sfe->flags & XFS_ATTR_SECURE) != 0)) | ||
399 | continue; | ||
400 | if (((args->flags & ATTR_ROOT) != 0) != | ||
401 | ((sfe->flags & XFS_ATTR_ROOT) != 0)) | ||
402 | continue; | 422 | continue; |
403 | if (args->flags & ATTR_KERNOVAL) { | 423 | if (args->flags & ATTR_KERNOVAL) { |
404 | args->valuelen = sfe->valuelen; | 424 | args->valuelen = sfe->valuelen; |
@@ -485,8 +505,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) | |||
485 | nargs.valuelen = sfe->valuelen; | 505 | nargs.valuelen = sfe->valuelen; |
486 | nargs.hashval = xfs_da_hashname((char *)sfe->nameval, | 506 | nargs.hashval = xfs_da_hashname((char *)sfe->nameval, |
487 | sfe->namelen); | 507 | sfe->namelen); |
488 | nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : | 508 | nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); |
489 | ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); | ||
490 | error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ | 509 | error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ |
491 | ASSERT(error == ENOATTR); | 510 | ASSERT(error == ENOATTR); |
492 | error = xfs_attr_leaf_add(bp, &nargs); | 511 | error = xfs_attr_leaf_add(bp, &nargs); |
@@ -520,6 +539,10 @@ xfs_attr_shortform_compare(const void *a, const void *b) | |||
520 | } | 539 | } |
521 | } | 540 | } |
522 | 541 | ||
542 | |||
543 | #define XFS_ISRESET_CURSOR(cursor) \ | ||
544 | (!((cursor)->initted) && !((cursor)->hashval) && \ | ||
545 | !((cursor)->blkno) && !((cursor)->offset)) | ||
523 | /* | 546 | /* |
524 | * Copy out entries of shortform attribute lists for attr_list(). | 547 | * Copy out entries of shortform attribute lists for attr_list(). |
525 | * Shortform attribute lists are not stored in hashval sorted order. | 548 | * Shortform attribute lists are not stored in hashval sorted order. |
@@ -537,6 +560,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) | |||
537 | xfs_attr_sf_entry_t *sfe; | 560 | xfs_attr_sf_entry_t *sfe; |
538 | xfs_inode_t *dp; | 561 | xfs_inode_t *dp; |
539 | int sbsize, nsbuf, count, i; | 562 | int sbsize, nsbuf, count, i; |
563 | int error; | ||
540 | 564 | ||
541 | ASSERT(context != NULL); | 565 | ASSERT(context != NULL); |
542 | dp = context->dp; | 566 | dp = context->dp; |
@@ -552,46 +576,51 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) | |||
552 | xfs_attr_trace_l_c("sf start", context); | 576 | xfs_attr_trace_l_c("sf start", context); |
553 | 577 | ||
554 | /* | 578 | /* |
555 | * If the buffer is large enough, do not bother with sorting. | 579 | * If the buffer is large enough and the cursor is at the start, |
580 | * do not bother with sorting since we will return everything in | ||
581 | * one buffer and another call using the cursor won't need to be | ||
582 | * made. | ||
556 | * Note the generous fudge factor of 16 overhead bytes per entry. | 583 | * Note the generous fudge factor of 16 overhead bytes per entry. |
584 | * If bufsize is zero then put_listent must be a search function | ||
585 | * and can just scan through what we have. | ||
557 | */ | 586 | */ |
558 | if ((dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize) { | 587 | if (context->bufsize == 0 || |
588 | (XFS_ISRESET_CURSOR(cursor) && | ||
589 | (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { | ||
559 | for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { | 590 | for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { |
560 | attrnames_t *namesp; | 591 | attrnames_t *namesp; |
561 | 592 | ||
562 | if (((context->flags & ATTR_SECURE) != 0) != | 593 | if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) { |
563 | ((sfe->flags & XFS_ATTR_SECURE) != 0) && | ||
564 | !(context->flags & ATTR_KERNORMALS)) { | ||
565 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); | ||
566 | continue; | ||
567 | } | ||
568 | if (((context->flags & ATTR_ROOT) != 0) != | ||
569 | ((sfe->flags & XFS_ATTR_ROOT) != 0) && | ||
570 | !(context->flags & ATTR_KERNROOTLS)) { | ||
571 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); | 594 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); |
572 | continue; | 595 | continue; |
573 | } | 596 | } |
574 | namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure: | 597 | namesp = xfs_attr_flags_namesp(sfe->flags); |
575 | ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : | 598 | error = context->put_listent(context, |
576 | &attr_user); | 599 | namesp, |
577 | if (context->flags & ATTR_KERNOVAL) { | 600 | (char *)sfe->nameval, |
578 | ASSERT(context->flags & ATTR_KERNAMELS); | 601 | (int)sfe->namelen, |
579 | context->count += namesp->attr_namelen + | 602 | (int)sfe->valuelen, |
580 | sfe->namelen + 1; | 603 | (char*)&sfe->nameval[sfe->namelen]); |
581 | } | 604 | |
582 | else { | 605 | /* |
583 | if (xfs_attr_put_listent(context, namesp, | 606 | * Either search callback finished early or |
584 | (char *)sfe->nameval, | 607 | * didn't fit it all in the buffer after all. |
585 | (int)sfe->namelen, | 608 | */ |
586 | (int)sfe->valuelen)) | 609 | if (context->seen_enough) |
587 | break; | 610 | break; |
588 | } | 611 | |
612 | if (error) | ||
613 | return error; | ||
589 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); | 614 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); |
590 | } | 615 | } |
591 | xfs_attr_trace_l_c("sf big-gulp", context); | 616 | xfs_attr_trace_l_c("sf big-gulp", context); |
592 | return(0); | 617 | return(0); |
593 | } | 618 | } |
594 | 619 | ||
620 | /* do no more for a search callback */ | ||
621 | if (context->bufsize == 0) | ||
622 | return 0; | ||
623 | |||
595 | /* | 624 | /* |
596 | * It didn't all fit, so we have to sort everything on hashval. | 625 | * It didn't all fit, so we have to sort everything on hashval. |
597 | */ | 626 | */ |
@@ -614,15 +643,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) | |||
614 | kmem_free(sbuf, sbsize); | 643 | kmem_free(sbuf, sbsize); |
615 | return XFS_ERROR(EFSCORRUPTED); | 644 | return XFS_ERROR(EFSCORRUPTED); |
616 | } | 645 | } |
617 | if (((context->flags & ATTR_SECURE) != 0) != | 646 | if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) { |
618 | ((sfe->flags & XFS_ATTR_SECURE) != 0) && | ||
619 | !(context->flags & ATTR_KERNORMALS)) { | ||
620 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); | ||
621 | continue; | ||
622 | } | ||
623 | if (((context->flags & ATTR_ROOT) != 0) != | ||
624 | ((sfe->flags & XFS_ATTR_ROOT) != 0) && | ||
625 | !(context->flags & ATTR_KERNROOTLS)) { | ||
626 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); | 647 | sfe = XFS_ATTR_SF_NEXTENTRY(sfe); |
627 | continue; | 648 | continue; |
628 | } | 649 | } |
@@ -671,24 +692,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) | |||
671 | for ( ; i < nsbuf; i++, sbp++) { | 692 | for ( ; i < nsbuf; i++, sbp++) { |
672 | attrnames_t *namesp; | 693 | attrnames_t *namesp; |
673 | 694 | ||
674 | namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure : | 695 | namesp = xfs_attr_flags_namesp(sbp->flags); |
675 | ((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted : | ||
676 | &attr_user); | ||
677 | 696 | ||
678 | if (cursor->hashval != sbp->hash) { | 697 | if (cursor->hashval != sbp->hash) { |
679 | cursor->hashval = sbp->hash; | 698 | cursor->hashval = sbp->hash; |
680 | cursor->offset = 0; | 699 | cursor->offset = 0; |
681 | } | 700 | } |
682 | if (context->flags & ATTR_KERNOVAL) { | 701 | error = context->put_listent(context, |
683 | ASSERT(context->flags & ATTR_KERNAMELS); | 702 | namesp, |
684 | context->count += namesp->attr_namelen + | 703 | sbp->name, |
685 | sbp->namelen + 1; | 704 | sbp->namelen, |
686 | } else { | 705 | sbp->valuelen, |
687 | if (xfs_attr_put_listent(context, namesp, | 706 | &sbp->name[sbp->namelen]); |
688 | sbp->name, sbp->namelen, | 707 | if (error) |
689 | sbp->valuelen)) | 708 | return error; |
690 | break; | 709 | if (context->seen_enough) |
691 | } | 710 | break; |
692 | cursor->offset++; | 711 | cursor->offset++; |
693 | } | 712 | } |
694 | 713 | ||
@@ -810,8 +829,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) | |||
810 | nargs.value = (char *)&name_loc->nameval[nargs.namelen]; | 829 | nargs.value = (char *)&name_loc->nameval[nargs.namelen]; |
811 | nargs.valuelen = be16_to_cpu(name_loc->valuelen); | 830 | nargs.valuelen = be16_to_cpu(name_loc->valuelen); |
812 | nargs.hashval = be32_to_cpu(entry->hashval); | 831 | nargs.hashval = be32_to_cpu(entry->hashval); |
813 | nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : | 832 | nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags); |
814 | ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); | ||
815 | xfs_attr_shortform_add(&nargs, forkoff); | 833 | xfs_attr_shortform_add(&nargs, forkoff); |
816 | } | 834 | } |
817 | error = 0; | 835 | error = 0; |
@@ -1098,8 +1116,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1098 | be16_to_cpu(map->size)); | 1116 | be16_to_cpu(map->size)); |
1099 | entry->hashval = cpu_to_be32(args->hashval); | 1117 | entry->hashval = cpu_to_be32(args->hashval); |
1100 | entry->flags = tmp ? XFS_ATTR_LOCAL : 0; | 1118 | entry->flags = tmp ? XFS_ATTR_LOCAL : 0; |
1101 | entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : | 1119 | entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); |
1102 | ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); | ||
1103 | if (args->rename) { | 1120 | if (args->rename) { |
1104 | entry->flags |= XFS_ATTR_INCOMPLETE; | 1121 | entry->flags |= XFS_ATTR_INCOMPLETE; |
1105 | if ((args->blkno2 == args->blkno) && | 1122 | if ((args->blkno2 == args->blkno) && |
@@ -1926,7 +1943,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1926 | else | 1943 | else |
1927 | break; | 1944 | break; |
1928 | } | 1945 | } |
1929 | ASSERT((probe >= 0) && | 1946 | ASSERT((probe >= 0) && |
1930 | (!leaf->hdr.count | 1947 | (!leaf->hdr.count |
1931 | || (probe < be16_to_cpu(leaf->hdr.count)))); | 1948 | || (probe < be16_to_cpu(leaf->hdr.count)))); |
1932 | ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); | 1949 | ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); |
@@ -1971,14 +1988,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1971 | name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe); | 1988 | name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe); |
1972 | if (name_loc->namelen != args->namelen) | 1989 | if (name_loc->namelen != args->namelen) |
1973 | continue; | 1990 | continue; |
1974 | if (memcmp(args->name, (char *)name_loc->nameval, | 1991 | if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) |
1975 | args->namelen) != 0) | ||
1976 | continue; | 1992 | continue; |
1977 | if (((args->flags & ATTR_SECURE) != 0) != | 1993 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) |
1978 | ((entry->flags & XFS_ATTR_SECURE) != 0)) | ||
1979 | continue; | ||
1980 | if (((args->flags & ATTR_ROOT) != 0) != | ||
1981 | ((entry->flags & XFS_ATTR_ROOT) != 0)) | ||
1982 | continue; | 1994 | continue; |
1983 | args->index = probe; | 1995 | args->index = probe; |
1984 | return(XFS_ERROR(EEXIST)); | 1996 | return(XFS_ERROR(EEXIST)); |
@@ -1989,11 +2001,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1989 | if (memcmp(args->name, (char *)name_rmt->name, | 2001 | if (memcmp(args->name, (char *)name_rmt->name, |
1990 | args->namelen) != 0) | 2002 | args->namelen) != 0) |
1991 | continue; | 2003 | continue; |
1992 | if (((args->flags & ATTR_SECURE) != 0) != | 2004 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) |
1993 | ((entry->flags & XFS_ATTR_SECURE) != 0)) | ||
1994 | continue; | ||
1995 | if (((args->flags & ATTR_ROOT) != 0) != | ||
1996 | ((entry->flags & XFS_ATTR_ROOT) != 0)) | ||
1997 | continue; | 2005 | continue; |
1998 | args->index = probe; | 2006 | args->index = probe; |
1999 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); | 2007 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
@@ -2312,8 +2320,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) | |||
2312 | attrlist_cursor_kern_t *cursor; | 2320 | attrlist_cursor_kern_t *cursor; |
2313 | xfs_attr_leafblock_t *leaf; | 2321 | xfs_attr_leafblock_t *leaf; |
2314 | xfs_attr_leaf_entry_t *entry; | 2322 | xfs_attr_leaf_entry_t *entry; |
2315 | xfs_attr_leaf_name_local_t *name_loc; | ||
2316 | xfs_attr_leaf_name_remote_t *name_rmt; | ||
2317 | int retval, i; | 2323 | int retval, i; |
2318 | 2324 | ||
2319 | ASSERT(bp != NULL); | 2325 | ASSERT(bp != NULL); |
@@ -2355,9 +2361,8 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) | |||
2355 | * We have found our place, start copying out the new attributes. | 2361 | * We have found our place, start copying out the new attributes. |
2356 | */ | 2362 | */ |
2357 | retval = 0; | 2363 | retval = 0; |
2358 | for ( ; (i < be16_to_cpu(leaf->hdr.count)) | 2364 | for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) { |
2359 | && (retval == 0); entry++, i++) { | 2365 | attrnames_t *namesp; |
2360 | attrnames_t *namesp; | ||
2361 | 2366 | ||
2362 | if (be32_to_cpu(entry->hashval) != cursor->hashval) { | 2367 | if (be32_to_cpu(entry->hashval) != cursor->hashval) { |
2363 | cursor->hashval = be32_to_cpu(entry->hashval); | 2368 | cursor->hashval = be32_to_cpu(entry->hashval); |
@@ -2366,115 +2371,69 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) | |||
2366 | 2371 | ||
2367 | if (entry->flags & XFS_ATTR_INCOMPLETE) | 2372 | if (entry->flags & XFS_ATTR_INCOMPLETE) |
2368 | continue; /* skip incomplete entries */ | 2373 | continue; /* skip incomplete entries */ |
2369 | if (((context->flags & ATTR_SECURE) != 0) != | 2374 | if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags)) |
2370 | ((entry->flags & XFS_ATTR_SECURE) != 0) && | 2375 | continue; |
2371 | !(context->flags & ATTR_KERNORMALS)) | 2376 | |
2372 | continue; /* skip non-matching entries */ | 2377 | namesp = xfs_attr_flags_namesp(entry->flags); |
2373 | if (((context->flags & ATTR_ROOT) != 0) != | ||
2374 | ((entry->flags & XFS_ATTR_ROOT) != 0) && | ||
2375 | !(context->flags & ATTR_KERNROOTLS)) | ||
2376 | continue; /* skip non-matching entries */ | ||
2377 | |||
2378 | namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure : | ||
2379 | ((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted : | ||
2380 | &attr_user); | ||
2381 | 2378 | ||
2382 | if (entry->flags & XFS_ATTR_LOCAL) { | 2379 | if (entry->flags & XFS_ATTR_LOCAL) { |
2383 | name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); | 2380 | xfs_attr_leaf_name_local_t *name_loc = |
2384 | if (context->flags & ATTR_KERNOVAL) { | 2381 | XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); |
2385 | ASSERT(context->flags & ATTR_KERNAMELS); | 2382 | |
2386 | context->count += namesp->attr_namelen + | 2383 | retval = context->put_listent(context, |
2387 | (int)name_loc->namelen + 1; | 2384 | namesp, |
2388 | } else { | 2385 | (char *)name_loc->nameval, |
2389 | retval = xfs_attr_put_listent(context, namesp, | 2386 | (int)name_loc->namelen, |
2390 | (char *)name_loc->nameval, | 2387 | be16_to_cpu(name_loc->valuelen), |
2391 | (int)name_loc->namelen, | 2388 | (char *)&name_loc->nameval[name_loc->namelen]); |
2392 | be16_to_cpu(name_loc->valuelen)); | 2389 | if (retval) |
2393 | } | 2390 | return retval; |
2394 | } else { | 2391 | } else { |
2395 | name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); | 2392 | xfs_attr_leaf_name_remote_t *name_rmt = |
2396 | if (context->flags & ATTR_KERNOVAL) { | 2393 | XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); |
2397 | ASSERT(context->flags & ATTR_KERNAMELS); | 2394 | |
2398 | context->count += namesp->attr_namelen + | 2395 | int valuelen = be32_to_cpu(name_rmt->valuelen); |
2399 | (int)name_rmt->namelen + 1; | 2396 | |
2400 | } else { | 2397 | if (context->put_value) { |
2401 | retval = xfs_attr_put_listent(context, namesp, | 2398 | xfs_da_args_t args; |
2402 | (char *)name_rmt->name, | 2399 | |
2403 | (int)name_rmt->namelen, | 2400 | memset((char *)&args, 0, sizeof(args)); |
2404 | be32_to_cpu(name_rmt->valuelen)); | 2401 | args.dp = context->dp; |
2402 | args.whichfork = XFS_ATTR_FORK; | ||
2403 | args.valuelen = valuelen; | ||
2404 | args.value = kmem_alloc(valuelen, KM_SLEEP); | ||
2405 | args.rmtblkno = be32_to_cpu(name_rmt->valueblk); | ||
2406 | args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen); | ||
2407 | retval = xfs_attr_rmtval_get(&args); | ||
2408 | if (retval) | ||
2409 | return retval; | ||
2410 | retval = context->put_listent(context, | ||
2411 | namesp, | ||
2412 | (char *)name_rmt->name, | ||
2413 | (int)name_rmt->namelen, | ||
2414 | valuelen, | ||
2415 | (char*)args.value); | ||
2416 | kmem_free(args.value, valuelen); | ||
2405 | } | 2417 | } |
2418 | else { | ||
2419 | retval = context->put_listent(context, | ||
2420 | namesp, | ||
2421 | (char *)name_rmt->name, | ||
2422 | (int)name_rmt->namelen, | ||
2423 | valuelen, | ||
2424 | NULL); | ||
2425 | } | ||
2426 | if (retval) | ||
2427 | return retval; | ||
2406 | } | 2428 | } |
2407 | if (retval == 0) { | 2429 | if (context->seen_enough) |
2408 | cursor->offset++; | 2430 | break; |
2409 | } | 2431 | cursor->offset++; |
2410 | } | 2432 | } |
2411 | xfs_attr_trace_l_cl("blk end", context, leaf); | 2433 | xfs_attr_trace_l_cl("blk end", context, leaf); |
2412 | return(retval); | 2434 | return(retval); |
2413 | } | 2435 | } |
2414 | 2436 | ||
2415 | #define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \ | ||
2416 | (((struct attrlist_ent *) 0)->a_name - (char *) 0) | ||
2417 | #define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \ | ||
2418 | ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \ | ||
2419 | & ~(sizeof(u_int32_t)-1)) | ||
2420 | |||
2421 | /* | ||
2422 | * Format an attribute and copy it out to the user's buffer. | ||
2423 | * Take care to check values and protect against them changing later, | ||
2424 | * we may be reading them directly out of a user buffer. | ||
2425 | */ | ||
2426 | /*ARGSUSED*/ | ||
2427 | STATIC int | ||
2428 | xfs_attr_put_listent(xfs_attr_list_context_t *context, | ||
2429 | attrnames_t *namesp, char *name, int namelen, int valuelen) | ||
2430 | { | ||
2431 | attrlist_ent_t *aep; | ||
2432 | int arraytop; | ||
2433 | |||
2434 | ASSERT(!(context->flags & ATTR_KERNOVAL)); | ||
2435 | if (context->flags & ATTR_KERNAMELS) { | ||
2436 | char *offset; | ||
2437 | |||
2438 | ASSERT(context->count >= 0); | ||
2439 | |||
2440 | arraytop = context->count + namesp->attr_namelen + namelen + 1; | ||
2441 | if (arraytop > context->firstu) { | ||
2442 | context->count = -1; /* insufficient space */ | ||
2443 | return(1); | ||
2444 | } | ||
2445 | offset = (char *)context->alist + context->count; | ||
2446 | strncpy(offset, namesp->attr_name, namesp->attr_namelen); | ||
2447 | offset += namesp->attr_namelen; | ||
2448 | strncpy(offset, name, namelen); /* real name */ | ||
2449 | offset += namelen; | ||
2450 | *offset = '\0'; | ||
2451 | context->count += namesp->attr_namelen + namelen + 1; | ||
2452 | return(0); | ||
2453 | } | ||
2454 | |||
2455 | ASSERT(context->count >= 0); | ||
2456 | ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); | ||
2457 | ASSERT(context->firstu >= sizeof(*context->alist)); | ||
2458 | ASSERT(context->firstu <= context->bufsize); | ||
2459 | |||
2460 | arraytop = sizeof(*context->alist) + | ||
2461 | context->count * sizeof(context->alist->al_offset[0]); | ||
2462 | context->firstu -= ATTR_ENTSIZE(namelen); | ||
2463 | if (context->firstu < arraytop) { | ||
2464 | xfs_attr_trace_l_c("buffer full", context); | ||
2465 | context->alist->al_more = 1; | ||
2466 | return(1); | ||
2467 | } | ||
2468 | |||
2469 | aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]); | ||
2470 | aep->a_valuelen = valuelen; | ||
2471 | memcpy(aep->a_name, name, namelen); | ||
2472 | aep->a_name[ namelen ] = 0; | ||
2473 | context->alist->al_offset[ context->count++ ] = context->firstu; | ||
2474 | context->alist->al_count = context->count; | ||
2475 | xfs_attr_trace_l_c("add", context); | ||
2476 | return(0); | ||
2477 | } | ||
2478 | 2437 | ||
2479 | /*======================================================================== | 2438 | /*======================================================================== |
2480 | * Manage the INCOMPLETE flag in a leaf entry | 2439 | * Manage the INCOMPLETE flag in a leaf entry |
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index 51c3ee156b2f..040f732ce1e2 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h | |||
@@ -130,6 +130,19 @@ typedef struct xfs_attr_leafblock { | |||
130 | #define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) | 130 | #define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) |
131 | 131 | ||
132 | /* | 132 | /* |
133 | * Conversion macros for converting namespace bits from argument flags | ||
134 | * to ondisk flags. | ||
135 | */ | ||
136 | #define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE) | ||
137 | #define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) | ||
138 | #define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK) | ||
139 | #define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK) | ||
140 | #define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\ | ||
141 | ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0)) | ||
142 | #define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\ | ||
143 | ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0)) | ||
144 | |||
145 | /* | ||
133 | * Alignment for namelist and valuelist entries (since they are mixed | 146 | * Alignment for namelist and valuelist entries (since they are mixed |
134 | * there can be only one alignment value) | 147 | * there can be only one alignment value) |
135 | */ | 148 | */ |
@@ -196,16 +209,26 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize) | |||
196 | * Structure used to pass context around among the routines. | 209 | * Structure used to pass context around among the routines. |
197 | *========================================================================*/ | 210 | *========================================================================*/ |
198 | 211 | ||
212 | |||
213 | struct xfs_attr_list_context; | ||
214 | |||
215 | typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *, | ||
216 | char *, int, int, char *); | ||
217 | |||
199 | typedef struct xfs_attr_list_context { | 218 | typedef struct xfs_attr_list_context { |
200 | struct xfs_inode *dp; /* inode */ | 219 | struct xfs_inode *dp; /* inode */ |
201 | struct attrlist_cursor_kern *cursor;/* position in list */ | 220 | struct attrlist_cursor_kern *cursor; /* position in list */ |
202 | struct attrlist *alist; /* output buffer */ | 221 | struct attrlist *alist; /* output buffer */ |
203 | int count; /* num used entries */ | 222 | int seen_enough; /* T/F: seen enough of list? */ |
204 | int dupcnt; /* count dup hashvals seen */ | 223 | int count; /* num used entries */ |
205 | int bufsize;/* total buffer size */ | 224 | int dupcnt; /* count dup hashvals seen */ |
206 | int firstu; /* first used byte in buffer */ | 225 | int bufsize; /* total buffer size */ |
207 | int flags; /* from VOP call */ | 226 | int firstu; /* first used byte in buffer */ |
208 | int resynch;/* T/F: resynch with cursor */ | 227 | int flags; /* from VOP call */ |
228 | int resynch; /* T/F: resynch with cursor */ | ||
229 | int put_value; /* T/F: need value for listent */ | ||
230 | put_listent_func_t put_listent; /* list output fmt function */ | ||
231 | int index; /* index into output buffer */ | ||
209 | } xfs_attr_list_context_t; | 232 | } xfs_attr_list_context_t; |
210 | 233 | ||
211 | /* | 234 | /* |
diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c index f4fe3715a803..0dc17219d412 100644 --- a/fs/xfs/xfs_behavior.c +++ b/fs/xfs/xfs_behavior.c | |||
@@ -110,26 +110,6 @@ bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * Look for a specific ops vector on the specified behavior chain. | ||
114 | * Return the associated behavior descriptor. Or NULL, if not found. | ||
115 | */ | ||
116 | bhv_desc_t * | ||
117 | bhv_lookup(bhv_head_t *bhp, void *ops) | ||
118 | { | ||
119 | bhv_desc_t *curdesc; | ||
120 | |||
121 | for (curdesc = bhp->bh_first; | ||
122 | curdesc != NULL; | ||
123 | curdesc = curdesc->bd_next) { | ||
124 | |||
125 | if (curdesc->bd_ops == ops) | ||
126 | return curdesc; | ||
127 | } | ||
128 | |||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * Looks for the first behavior within a specified range of positions. | 113 | * Looks for the first behavior within a specified range of positions. |
134 | * Return the associated behavior descriptor. Or NULL, if none found. | 114 | * Return the associated behavior descriptor. Or NULL, if none found. |
135 | */ | 115 | */ |
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h index 6e6e56fb352d..e7ca1fed955a 100644 --- a/fs/xfs/xfs_behavior.h +++ b/fs/xfs/xfs_behavior.h | |||
@@ -176,12 +176,10 @@ extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *); | |||
176 | * Behavior module prototypes. | 176 | * Behavior module prototypes. |
177 | */ | 177 | */ |
178 | extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp); | 178 | extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp); |
179 | extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops); | ||
180 | extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high); | 179 | extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high); |
181 | extern bhv_desc_t * bhv_base(bhv_head_t *bhp); | 180 | extern bhv_desc_t * bhv_base(bhv_head_t *bhp); |
182 | 181 | ||
183 | /* No bhv locking on Linux */ | 182 | /* No bhv locking on Linux */ |
184 | #define bhv_lookup_unlocked bhv_lookup | ||
185 | #define bhv_base_unlocked bhv_base | 183 | #define bhv_base_unlocked bhv_base |
186 | 184 | ||
187 | #endif /* __XFS_BEHAVIOR_H__ */ | 185 | #endif /* __XFS_BEHAVIOR_H__ */ |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index bf46fae303af..5b050c06795f 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -2999,7 +2999,7 @@ xfs_bmap_btree_to_extents( | |||
2999 | int error; /* error return value */ | 2999 | int error; /* error return value */ |
3000 | xfs_ifork_t *ifp; /* inode fork data */ | 3000 | xfs_ifork_t *ifp; /* inode fork data */ |
3001 | xfs_mount_t *mp; /* mount point structure */ | 3001 | xfs_mount_t *mp; /* mount point structure */ |
3002 | xfs_bmbt_ptr_t *pp; /* ptr to block address */ | 3002 | __be64 *pp; /* ptr to block address */ |
3003 | xfs_bmbt_block_t *rblock;/* root btree block */ | 3003 | xfs_bmbt_block_t *rblock;/* root btree block */ |
3004 | 3004 | ||
3005 | ifp = XFS_IFORK_PTR(ip, whichfork); | 3005 | ifp = XFS_IFORK_PTR(ip, whichfork); |
@@ -3011,12 +3011,12 @@ xfs_bmap_btree_to_extents( | |||
3011 | ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1); | 3011 | ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1); |
3012 | mp = ip->i_mount; | 3012 | mp = ip->i_mount; |
3013 | pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes); | 3013 | pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes); |
3014 | cbno = be64_to_cpu(*pp); | ||
3014 | *logflagsp = 0; | 3015 | *logflagsp = 0; |
3015 | #ifdef DEBUG | 3016 | #ifdef DEBUG |
3016 | if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1))) | 3017 | if ((error = xfs_btree_check_lptr(cur, cbno, 1))) |
3017 | return error; | 3018 | return error; |
3018 | #endif | 3019 | #endif |
3019 | cbno = INT_GET(*pp, ARCH_CONVERT); | ||
3020 | if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, | 3020 | if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, |
3021 | XFS_BMAP_BTREE_REF))) | 3021 | XFS_BMAP_BTREE_REF))) |
3022 | return error; | 3022 | return error; |
@@ -3512,9 +3512,9 @@ xfs_bmap_extents_to_btree( | |||
3512 | */ | 3512 | */ |
3513 | kp = XFS_BMAP_KEY_IADDR(block, 1, cur); | 3513 | kp = XFS_BMAP_KEY_IADDR(block, 1, cur); |
3514 | arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); | 3514 | arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); |
3515 | INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp)); | 3515 | kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); |
3516 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); | 3516 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); |
3517 | INT_SET(*pp, ARCH_CONVERT, args.fsbno); | 3517 | *pp = cpu_to_be64(args.fsbno); |
3518 | /* | 3518 | /* |
3519 | * Do all this logging at the end so that | 3519 | * Do all this logging at the end so that |
3520 | * the root is at the right level. | 3520 | * the root is at the right level. |
@@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ | |||
3705 | xfs_bmap_search_extents( | 3705 | xfs_bmap_search_extents( |
3706 | xfs_inode_t *ip, /* incore inode pointer */ | 3706 | xfs_inode_t *ip, /* incore inode pointer */ |
3707 | xfs_fileoff_t bno, /* block number searched for */ | 3707 | xfs_fileoff_t bno, /* block number searched for */ |
3708 | int whichfork, /* data or attr fork */ | 3708 | int fork, /* data or attr fork */ |
3709 | int *eofp, /* out: end of file found */ | 3709 | int *eofp, /* out: end of file found */ |
3710 | xfs_extnum_t *lastxp, /* out: last extent index */ | 3710 | xfs_extnum_t *lastxp, /* out: last extent index */ |
3711 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ | 3711 | xfs_bmbt_irec_t *gotp, /* out: extent entry found */ |
@@ -3713,25 +3713,28 @@ xfs_bmap_search_extents( | |||
3713 | { | 3713 | { |
3714 | xfs_ifork_t *ifp; /* inode fork pointer */ | 3714 | xfs_ifork_t *ifp; /* inode fork pointer */ |
3715 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 3715 | xfs_bmbt_rec_t *ep; /* extent record pointer */ |
3716 | int rt; /* realtime flag */ | ||
3717 | 3716 | ||
3718 | XFS_STATS_INC(xs_look_exlist); | 3717 | XFS_STATS_INC(xs_look_exlist); |
3719 | ifp = XFS_IFORK_PTR(ip, whichfork); | 3718 | ifp = XFS_IFORK_PTR(ip, fork); |
3720 | 3719 | ||
3721 | ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); | 3720 | ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); |
3722 | 3721 | ||
3723 | rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); | 3722 | if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && |
3724 | if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) { | 3723 | !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { |
3725 | cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld " | 3724 | xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, |
3726 | "start_block : %llx start_off : %llx blkcnt : %llx " | 3725 | "Access to block zero in inode %llu " |
3727 | "extent-state : %x \n", | 3726 | "start_block: %llx start_off: %llx " |
3728 | (ip->i_mount)->m_fsname, (long long)ip->i_ino, | 3727 | "blkcnt: %llx extent-state: %x lastx: %x\n", |
3728 | (unsigned long long)ip->i_ino, | ||
3729 | (unsigned long long)gotp->br_startblock, | 3729 | (unsigned long long)gotp->br_startblock, |
3730 | (unsigned long long)gotp->br_startoff, | 3730 | (unsigned long long)gotp->br_startoff, |
3731 | (unsigned long long)gotp->br_blockcount, | 3731 | (unsigned long long)gotp->br_blockcount, |
3732 | gotp->br_state); | 3732 | gotp->br_state, *lastxp); |
3733 | } | 3733 | *lastxp = NULLEXTNUM; |
3734 | return ep; | 3734 | *eofp = 1; |
3735 | return NULL; | ||
3736 | } | ||
3737 | return ep; | ||
3735 | } | 3738 | } |
3736 | 3739 | ||
3737 | 3740 | ||
@@ -4494,7 +4497,7 @@ xfs_bmap_read_extents( | |||
4494 | xfs_ifork_t *ifp; /* fork structure */ | 4497 | xfs_ifork_t *ifp; /* fork structure */ |
4495 | int level; /* btree level, for checking */ | 4498 | int level; /* btree level, for checking */ |
4496 | xfs_mount_t *mp; /* file system mount structure */ | 4499 | xfs_mount_t *mp; /* file system mount structure */ |
4497 | xfs_bmbt_ptr_t *pp; /* pointer to block address */ | 4500 | __be64 *pp; /* pointer to block address */ |
4498 | /* REFERENCED */ | 4501 | /* REFERENCED */ |
4499 | xfs_extnum_t room; /* number of entries there's room for */ | 4502 | xfs_extnum_t room; /* number of entries there's room for */ |
4500 | 4503 | ||
@@ -4510,10 +4513,10 @@ xfs_bmap_read_extents( | |||
4510 | level = be16_to_cpu(block->bb_level); | 4513 | level = be16_to_cpu(block->bb_level); |
4511 | ASSERT(level > 0); | 4514 | ASSERT(level > 0); |
4512 | pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); | 4515 | pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); |
4513 | ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); | 4516 | bno = be64_to_cpu(*pp); |
4514 | ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); | 4517 | ASSERT(bno != NULLDFSBNO); |
4515 | ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); | 4518 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); |
4516 | bno = INT_GET(*pp, ARCH_CONVERT); | 4519 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); |
4517 | /* | 4520 | /* |
4518 | * Go down the tree until leaf level is reached, following the first | 4521 | * Go down the tree until leaf level is reached, following the first |
4519 | * pointer (leftmost) at each level. | 4522 | * pointer (leftmost) at each level. |
@@ -4530,10 +4533,8 @@ xfs_bmap_read_extents( | |||
4530 | break; | 4533 | break; |
4531 | pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, | 4534 | pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, |
4532 | 1, mp->m_bmap_dmxr[1]); | 4535 | 1, mp->m_bmap_dmxr[1]); |
4533 | XFS_WANT_CORRUPTED_GOTO( | 4536 | bno = be64_to_cpu(*pp); |
4534 | XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), | 4537 | XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); |
4535 | error0); | ||
4536 | bno = INT_GET(*pp, ARCH_CONVERT); | ||
4537 | xfs_trans_brelse(tp, bp); | 4538 | xfs_trans_brelse(tp, bp); |
4538 | } | 4539 | } |
4539 | /* | 4540 | /* |
@@ -6141,7 +6142,7 @@ xfs_check_block( | |||
6141 | short sz) | 6142 | short sz) |
6142 | { | 6143 | { |
6143 | int i, j, dmxr; | 6144 | int i, j, dmxr; |
6144 | xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */ | 6145 | __be64 *pp, *thispa; /* pointer to block address */ |
6145 | xfs_bmbt_key_t *prevp, *keyp; | 6146 | xfs_bmbt_key_t *prevp, *keyp; |
6146 | 6147 | ||
6147 | ASSERT(be16_to_cpu(block->bb_level) > 0); | 6148 | ASSERT(be16_to_cpu(block->bb_level) > 0); |
@@ -6179,11 +6180,10 @@ xfs_check_block( | |||
6179 | thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, | 6180 | thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, |
6180 | xfs_bmbt, block, j, dmxr); | 6181 | xfs_bmbt, block, j, dmxr); |
6181 | } | 6182 | } |
6182 | if (INT_GET(*thispa, ARCH_CONVERT) == | 6183 | if (*thispa == *pp) { |
6183 | INT_GET(*pp, ARCH_CONVERT)) { | ||
6184 | cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld", | 6184 | cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld", |
6185 | __FUNCTION__, j, i, | 6185 | __FUNCTION__, j, i, |
6186 | INT_GET(*thispa, ARCH_CONVERT)); | 6186 | (unsigned long long)be64_to_cpu(*thispa)); |
6187 | panic("%s: ptrs are equal in node\n", | 6187 | panic("%s: ptrs are equal in node\n", |
6188 | __FUNCTION__); | 6188 | __FUNCTION__); |
6189 | } | 6189 | } |
@@ -6210,7 +6210,7 @@ xfs_bmap_check_leaf_extents( | |||
6210 | xfs_ifork_t *ifp; /* fork structure */ | 6210 | xfs_ifork_t *ifp; /* fork structure */ |
6211 | int level; /* btree level, for checking */ | 6211 | int level; /* btree level, for checking */ |
6212 | xfs_mount_t *mp; /* file system mount structure */ | 6212 | xfs_mount_t *mp; /* file system mount structure */ |
6213 | xfs_bmbt_ptr_t *pp; /* pointer to block address */ | 6213 | __be64 *pp; /* pointer to block address */ |
6214 | xfs_bmbt_rec_t *ep; /* pointer to current extent */ | 6214 | xfs_bmbt_rec_t *ep; /* pointer to current extent */ |
6215 | xfs_bmbt_rec_t *lastp; /* pointer to previous extent */ | 6215 | xfs_bmbt_rec_t *lastp; /* pointer to previous extent */ |
6216 | xfs_bmbt_rec_t *nextp; /* pointer to next extent */ | 6216 | xfs_bmbt_rec_t *nextp; /* pointer to next extent */ |
@@ -6231,10 +6231,12 @@ xfs_bmap_check_leaf_extents( | |||
6231 | ASSERT(level > 0); | 6231 | ASSERT(level > 0); |
6232 | xfs_check_block(block, mp, 1, ifp->if_broot_bytes); | 6232 | xfs_check_block(block, mp, 1, ifp->if_broot_bytes); |
6233 | pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); | 6233 | pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); |
6234 | ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); | 6234 | bno = be64_to_cpu(*pp); |
6235 | ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); | 6235 | |
6236 | ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); | 6236 | ASSERT(bno != NULLDFSBNO); |
6237 | bno = INT_GET(*pp, ARCH_CONVERT); | 6237 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); |
6238 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); | ||
6239 | |||
6238 | /* | 6240 | /* |
6239 | * Go down the tree until leaf level is reached, following the first | 6241 | * Go down the tree until leaf level is reached, following the first |
6240 | * pointer (leftmost) at each level. | 6242 | * pointer (leftmost) at each level. |
@@ -6265,8 +6267,8 @@ xfs_bmap_check_leaf_extents( | |||
6265 | xfs_check_block(block, mp, 0, 0); | 6267 | xfs_check_block(block, mp, 0, 0); |
6266 | pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, | 6268 | pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, |
6267 | 1, mp->m_bmap_dmxr[1]); | 6269 | 1, mp->m_bmap_dmxr[1]); |
6268 | XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), error0); | 6270 | bno = be64_to_cpu(*pp); |
6269 | bno = INT_GET(*pp, ARCH_CONVERT); | 6271 | XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); |
6270 | if (bp_release) { | 6272 | if (bp_release) { |
6271 | bp_release = 0; | 6273 | bp_release = 0; |
6272 | xfs_trans_brelse(NULL, bp); | 6274 | xfs_trans_brelse(NULL, bp); |
@@ -6372,7 +6374,7 @@ xfs_bmap_count_blocks( | |||
6372 | xfs_ifork_t *ifp; /* fork structure */ | 6374 | xfs_ifork_t *ifp; /* fork structure */ |
6373 | int level; /* btree level, for checking */ | 6375 | int level; /* btree level, for checking */ |
6374 | xfs_mount_t *mp; /* file system mount structure */ | 6376 | xfs_mount_t *mp; /* file system mount structure */ |
6375 | xfs_bmbt_ptr_t *pp; /* pointer to block address */ | 6377 | __be64 *pp; /* pointer to block address */ |
6376 | 6378 | ||
6377 | bno = NULLFSBLOCK; | 6379 | bno = NULLFSBLOCK; |
6378 | mp = ip->i_mount; | 6380 | mp = ip->i_mount; |
@@ -6395,10 +6397,10 @@ xfs_bmap_count_blocks( | |||
6395 | level = be16_to_cpu(block->bb_level); | 6397 | level = be16_to_cpu(block->bb_level); |
6396 | ASSERT(level > 0); | 6398 | ASSERT(level > 0); |
6397 | pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); | 6399 | pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); |
6398 | ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); | 6400 | bno = be64_to_cpu(*pp); |
6399 | ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); | 6401 | ASSERT(bno != NULLDFSBNO); |
6400 | ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); | 6402 | ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); |
6401 | bno = INT_GET(*pp, ARCH_CONVERT); | 6403 | ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); |
6402 | 6404 | ||
6403 | if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) { | 6405 | if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) { |
6404 | XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW, | 6406 | XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW, |
@@ -6425,7 +6427,7 @@ xfs_bmap_count_tree( | |||
6425 | int error; | 6427 | int error; |
6426 | xfs_buf_t *bp, *nbp; | 6428 | xfs_buf_t *bp, *nbp; |
6427 | int level = levelin; | 6429 | int level = levelin; |
6428 | xfs_bmbt_ptr_t *pp; | 6430 | __be64 *pp; |
6429 | xfs_fsblock_t bno = blockno; | 6431 | xfs_fsblock_t bno = blockno; |
6430 | xfs_fsblock_t nextbno; | 6432 | xfs_fsblock_t nextbno; |
6431 | xfs_bmbt_block_t *block, *nextblock; | 6433 | xfs_bmbt_block_t *block, *nextblock; |
@@ -6452,7 +6454,7 @@ xfs_bmap_count_tree( | |||
6452 | /* Dive to the next level */ | 6454 | /* Dive to the next level */ |
6453 | pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, | 6455 | pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, |
6454 | xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); | 6456 | xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); |
6455 | bno = INT_GET(*pp, ARCH_CONVERT); | 6457 | bno = be64_to_cpu(*pp); |
6456 | if (unlikely((error = | 6458 | if (unlikely((error = |
6457 | xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) { | 6459 | xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) { |
6458 | xfs_trans_brelse(tp, bp); | 6460 | xfs_trans_brelse(tp, bp); |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 18fb7385d719..a7b835bf870a 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -58,7 +58,7 @@ STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); | |||
58 | STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *); | 58 | STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *); |
59 | STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *); | 59 | STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *); |
60 | STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *, | 60 | STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *, |
61 | xfs_bmbt_key_t *, xfs_btree_cur_t **, int *); | 61 | __uint64_t *, xfs_btree_cur_t **, int *); |
62 | STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int); | 62 | STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int); |
63 | 63 | ||
64 | 64 | ||
@@ -192,16 +192,11 @@ xfs_bmbt_trace_argifk( | |||
192 | xfs_btree_cur_t *cur, | 192 | xfs_btree_cur_t *cur, |
193 | int i, | 193 | int i, |
194 | xfs_fsblock_t f, | 194 | xfs_fsblock_t f, |
195 | xfs_bmbt_key_t *k, | 195 | xfs_dfiloff_t o, |
196 | int line) | 196 | int line) |
197 | { | 197 | { |
198 | xfs_dfsbno_t d; | ||
199 | xfs_dfiloff_t o; | ||
200 | |||
201 | d = (xfs_dfsbno_t)f; | ||
202 | o = INT_GET(k->br_startoff, ARCH_CONVERT); | ||
203 | xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line, | 198 | xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line, |
204 | i, d >> 32, (int)d, o >> 32, | 199 | i, (xfs_dfsbno_t)f >> 32, (int)f, o >> 32, |
205 | (int)o, 0, 0, 0, | 200 | (int)o, 0, 0, 0, |
206 | 0, 0, 0); | 201 | 0, 0, 0); |
207 | } | 202 | } |
@@ -248,7 +243,7 @@ xfs_bmbt_trace_argik( | |||
248 | { | 243 | { |
249 | xfs_dfiloff_t o; | 244 | xfs_dfiloff_t o; |
250 | 245 | ||
251 | o = INT_GET(k->br_startoff, ARCH_CONVERT); | 246 | o = be64_to_cpu(k->br_startoff); |
252 | xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line, | 247 | xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line, |
253 | i, o >> 32, (int)o, 0, | 248 | i, o >> 32, (int)o, 0, |
254 | 0, 0, 0, 0, | 249 | 0, 0, 0, 0, |
@@ -286,8 +281,8 @@ xfs_bmbt_trace_cursor( | |||
286 | xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__) | 281 | xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__) |
287 | #define XFS_BMBT_TRACE_ARGI(c,i) \ | 282 | #define XFS_BMBT_TRACE_ARGI(c,i) \ |
288 | xfs_bmbt_trace_argi(fname, c, i, __LINE__) | 283 | xfs_bmbt_trace_argi(fname, c, i, __LINE__) |
289 | #define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) \ | 284 | #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \ |
290 | xfs_bmbt_trace_argifk(fname, c, i, f, k, __LINE__) | 285 | xfs_bmbt_trace_argifk(fname, c, i, f, s, __LINE__) |
291 | #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \ | 286 | #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \ |
292 | xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__) | 287 | xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__) |
293 | #define XFS_BMBT_TRACE_ARGIK(c,i,k) \ | 288 | #define XFS_BMBT_TRACE_ARGIK(c,i,k) \ |
@@ -299,7 +294,7 @@ xfs_bmbt_trace_cursor( | |||
299 | #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) | 294 | #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) |
300 | #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) | 295 | #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) |
301 | #define XFS_BMBT_TRACE_ARGI(c,i) | 296 | #define XFS_BMBT_TRACE_ARGI(c,i) |
302 | #define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) | 297 | #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) |
303 | #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) | 298 | #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) |
304 | #define XFS_BMBT_TRACE_ARGIK(c,i,k) | 299 | #define XFS_BMBT_TRACE_ARGIK(c,i,k) |
305 | #define XFS_BMBT_TRACE_CURSOR(c,s) | 300 | #define XFS_BMBT_TRACE_CURSOR(c,s) |
@@ -357,7 +352,7 @@ xfs_bmbt_delrec( | |||
357 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | 352 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); |
358 | XFS_BMBT_TRACE_ARGI(cur, level); | 353 | XFS_BMBT_TRACE_ARGI(cur, level); |
359 | ptr = cur->bc_ptrs[level]; | 354 | ptr = cur->bc_ptrs[level]; |
360 | tcur = (xfs_btree_cur_t *)0; | 355 | tcur = NULL; |
361 | if (ptr == 0) { | 356 | if (ptr == 0) { |
362 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | 357 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); |
363 | *stat = 0; | 358 | *stat = 0; |
@@ -382,7 +377,7 @@ xfs_bmbt_delrec( | |||
382 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); | 377 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); |
383 | #ifdef DEBUG | 378 | #ifdef DEBUG |
384 | for (i = ptr; i < numrecs; i++) { | 379 | for (i = ptr; i < numrecs; i++) { |
385 | if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) { | 380 | if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { |
386 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 381 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
387 | goto error0; | 382 | goto error0; |
388 | } | 383 | } |
@@ -404,7 +399,8 @@ xfs_bmbt_delrec( | |||
404 | xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1); | 399 | xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1); |
405 | } | 400 | } |
406 | if (ptr == 1) { | 401 | if (ptr == 1) { |
407 | INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp)); | 402 | key.br_startoff = |
403 | cpu_to_be64(xfs_bmbt_disk_get_startoff(rp)); | ||
408 | kp = &key; | 404 | kp = &key; |
409 | } | 405 | } |
410 | } | 406 | } |
@@ -621,7 +617,7 @@ xfs_bmbt_delrec( | |||
621 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); | 617 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); |
622 | #ifdef DEBUG | 618 | #ifdef DEBUG |
623 | for (i = 0; i < numrrecs; i++) { | 619 | for (i = 0; i < numrrecs; i++) { |
624 | if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) { | 620 | if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) { |
625 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 621 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
626 | goto error0; | 622 | goto error0; |
627 | } | 623 | } |
@@ -748,7 +744,7 @@ xfs_bmbt_insrec( | |||
748 | int logflags; /* inode logging flags */ | 744 | int logflags; /* inode logging flags */ |
749 | xfs_fsblock_t nbno; /* new block number */ | 745 | xfs_fsblock_t nbno; /* new block number */ |
750 | struct xfs_btree_cur *ncur; /* new btree cursor */ | 746 | struct xfs_btree_cur *ncur; /* new btree cursor */ |
751 | xfs_bmbt_key_t nkey; /* new btree key value */ | 747 | __uint64_t startoff; /* new btree key value */ |
752 | xfs_bmbt_rec_t nrec; /* new record count */ | 748 | xfs_bmbt_rec_t nrec; /* new record count */ |
753 | int optr; /* old key/record index */ | 749 | int optr; /* old key/record index */ |
754 | xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ | 750 | xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ |
@@ -759,9 +755,8 @@ xfs_bmbt_insrec( | |||
759 | ASSERT(level < cur->bc_nlevels); | 755 | ASSERT(level < cur->bc_nlevels); |
760 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | 756 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); |
761 | XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp); | 757 | XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp); |
762 | ncur = (xfs_btree_cur_t *)0; | 758 | ncur = NULL; |
763 | INT_SET(key.br_startoff, ARCH_CONVERT, | 759 | key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp)); |
764 | xfs_bmbt_disk_get_startoff(recp)); | ||
765 | optr = ptr = cur->bc_ptrs[level]; | 760 | optr = ptr = cur->bc_ptrs[level]; |
766 | if (ptr == 0) { | 761 | if (ptr == 0) { |
767 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | 762 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); |
@@ -820,7 +815,7 @@ xfs_bmbt_insrec( | |||
820 | optr = ptr = cur->bc_ptrs[level]; | 815 | optr = ptr = cur->bc_ptrs[level]; |
821 | } else { | 816 | } else { |
822 | if ((error = xfs_bmbt_split(cur, level, | 817 | if ((error = xfs_bmbt_split(cur, level, |
823 | &nbno, &nkey, &ncur, | 818 | &nbno, &startoff, &ncur, |
824 | &i))) { | 819 | &i))) { |
825 | XFS_BMBT_TRACE_CURSOR(cur, | 820 | XFS_BMBT_TRACE_CURSOR(cur, |
826 | ERROR); | 821 | ERROR); |
@@ -840,7 +835,7 @@ xfs_bmbt_insrec( | |||
840 | #endif | 835 | #endif |
841 | ptr = cur->bc_ptrs[level]; | 836 | ptr = cur->bc_ptrs[level]; |
842 | xfs_bmbt_disk_set_allf(&nrec, | 837 | xfs_bmbt_disk_set_allf(&nrec, |
843 | nkey.br_startoff, 0, 0, | 838 | startoff, 0, 0, |
844 | XFS_EXT_NORM); | 839 | XFS_EXT_NORM); |
845 | } else { | 840 | } else { |
846 | XFS_BMBT_TRACE_CURSOR(cur, | 841 | XFS_BMBT_TRACE_CURSOR(cur, |
@@ -858,7 +853,7 @@ xfs_bmbt_insrec( | |||
858 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); | 853 | pp = XFS_BMAP_PTR_IADDR(block, 1, cur); |
859 | #ifdef DEBUG | 854 | #ifdef DEBUG |
860 | for (i = numrecs; i >= ptr; i--) { | 855 | for (i = numrecs; i >= ptr; i--) { |
861 | if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT), | 856 | if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1], |
862 | level))) { | 857 | level))) { |
863 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 858 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
864 | return error; | 859 | return error; |
@@ -870,14 +865,13 @@ xfs_bmbt_insrec( | |||
870 | memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */ | 865 | memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */ |
871 | (numrecs - ptr + 1) * sizeof(*pp)); | 866 | (numrecs - ptr + 1) * sizeof(*pp)); |
872 | #ifdef DEBUG | 867 | #ifdef DEBUG |
873 | if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)*bnop, | 868 | if ((error = xfs_btree_check_lptr(cur, *bnop, level))) { |
874 | level))) { | ||
875 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 869 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
876 | return error; | 870 | return error; |
877 | } | 871 | } |
878 | #endif | 872 | #endif |
879 | kp[ptr - 1] = key; | 873 | kp[ptr - 1] = key; |
880 | INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop); | 874 | pp[ptr - 1] = cpu_to_be64(*bnop); |
881 | numrecs++; | 875 | numrecs++; |
882 | block->bb_numrecs = cpu_to_be16(numrecs); | 876 | block->bb_numrecs = cpu_to_be16(numrecs); |
883 | xfs_bmbt_log_keys(cur, bp, ptr, numrecs); | 877 | xfs_bmbt_log_keys(cur, bp, ptr, numrecs); |
@@ -988,7 +982,7 @@ xfs_bmbt_killroot( | |||
988 | cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); | 982 | cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); |
989 | #ifdef DEBUG | 983 | #ifdef DEBUG |
990 | for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { | 984 | for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { |
991 | if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) { | 985 | if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) { |
992 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 986 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
993 | return error; | 987 | return error; |
994 | } | 988 | } |
@@ -1132,7 +1126,7 @@ xfs_bmbt_lookup( | |||
1132 | d = XFS_FSB_TO_DADDR(mp, fsbno); | 1126 | d = XFS_FSB_TO_DADDR(mp, fsbno); |
1133 | bp = cur->bc_bufs[level]; | 1127 | bp = cur->bc_bufs[level]; |
1134 | if (bp && XFS_BUF_ADDR(bp) != d) | 1128 | if (bp && XFS_BUF_ADDR(bp) != d) |
1135 | bp = (xfs_buf_t *)0; | 1129 | bp = NULL; |
1136 | if (!bp) { | 1130 | if (!bp) { |
1137 | if ((error = xfs_btree_read_bufl(mp, tp, fsbno, | 1131 | if ((error = xfs_btree_read_bufl(mp, tp, fsbno, |
1138 | 0, &bp, XFS_BMAP_BTREE_REF))) { | 1132 | 0, &bp, XFS_BMAP_BTREE_REF))) { |
@@ -1170,7 +1164,7 @@ xfs_bmbt_lookup( | |||
1170 | keyno = (low + high) >> 1; | 1164 | keyno = (low + high) >> 1; |
1171 | if (level > 0) { | 1165 | if (level > 0) { |
1172 | kkp = kkbase + keyno - 1; | 1166 | kkp = kkbase + keyno - 1; |
1173 | startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT); | 1167 | startoff = be64_to_cpu(kkp->br_startoff); |
1174 | } else { | 1168 | } else { |
1175 | krp = krbase + keyno - 1; | 1169 | krp = krbase + keyno - 1; |
1176 | startoff = xfs_bmbt_disk_get_startoff(krp); | 1170 | startoff = xfs_bmbt_disk_get_startoff(krp); |
@@ -1189,13 +1183,13 @@ xfs_bmbt_lookup( | |||
1189 | if (diff > 0 && --keyno < 1) | 1183 | if (diff > 0 && --keyno < 1) |
1190 | keyno = 1; | 1184 | keyno = 1; |
1191 | pp = XFS_BMAP_PTR_IADDR(block, keyno, cur); | 1185 | pp = XFS_BMAP_PTR_IADDR(block, keyno, cur); |
1186 | fsbno = be64_to_cpu(*pp); | ||
1192 | #ifdef DEBUG | 1187 | #ifdef DEBUG |
1193 | if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { | 1188 | if ((error = xfs_btree_check_lptr(cur, fsbno, level))) { |
1194 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 1189 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
1195 | return error; | 1190 | return error; |
1196 | } | 1191 | } |
1197 | #endif | 1192 | #endif |
1198 | fsbno = INT_GET(*pp, ARCH_CONVERT); | ||
1199 | cur->bc_ptrs[level] = keyno; | 1193 | cur->bc_ptrs[level] = keyno; |
1200 | } | 1194 | } |
1201 | } | 1195 | } |
@@ -1313,7 +1307,7 @@ xfs_bmbt_lshift( | |||
1313 | lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur); | 1307 | lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur); |
1314 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); | 1308 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); |
1315 | #ifdef DEBUG | 1309 | #ifdef DEBUG |
1316 | if ((error = xfs_btree_check_lptr(cur, INT_GET(*rpp, ARCH_CONVERT), level))) { | 1310 | if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) { |
1317 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 1311 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
1318 | return error; | 1312 | return error; |
1319 | } | 1313 | } |
@@ -1340,7 +1334,7 @@ xfs_bmbt_lshift( | |||
1340 | if (level > 0) { | 1334 | if (level > 0) { |
1341 | #ifdef DEBUG | 1335 | #ifdef DEBUG |
1342 | for (i = 0; i < rrecs; i++) { | 1336 | for (i = 0; i < rrecs; i++) { |
1343 | if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT), | 1337 | if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1], |
1344 | level))) { | 1338 | level))) { |
1345 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 1339 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
1346 | return error; | 1340 | return error; |
@@ -1354,8 +1348,7 @@ xfs_bmbt_lshift( | |||
1354 | } else { | 1348 | } else { |
1355 | memmove(rrp, rrp + 1, rrecs * sizeof(*rrp)); | 1349 | memmove(rrp, rrp + 1, rrecs * sizeof(*rrp)); |
1356 | xfs_bmbt_log_recs(cur, rbp, 1, rrecs); | 1350 | xfs_bmbt_log_recs(cur, rbp, 1, rrecs); |
1357 | INT_SET(key.br_startoff, ARCH_CONVERT, | 1351 | key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); |
1358 | xfs_bmbt_disk_get_startoff(rrp)); | ||
1359 | rkp = &key; | 1352 | rkp = &key; |
1360 | } | 1353 | } |
1361 | if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) { | 1354 | if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) { |
@@ -1445,7 +1438,7 @@ xfs_bmbt_rshift( | |||
1445 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); | 1438 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); |
1446 | #ifdef DEBUG | 1439 | #ifdef DEBUG |
1447 | for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) { | 1440 | for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) { |
1448 | if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) { | 1441 | if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) { |
1449 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 1442 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
1450 | return error; | 1443 | return error; |
1451 | } | 1444 | } |
@@ -1454,7 +1447,7 @@ xfs_bmbt_rshift( | |||
1454 | memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); | 1447 | memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); |
1455 | memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); | 1448 | memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); |
1456 | #ifdef DEBUG | 1449 | #ifdef DEBUG |
1457 | if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) { | 1450 | if ((error = xfs_btree_check_lptr_disk(cur, *lpp, level))) { |
1458 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 1451 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
1459 | return error; | 1452 | return error; |
1460 | } | 1453 | } |
@@ -1469,8 +1462,7 @@ xfs_bmbt_rshift( | |||
1469 | memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); | 1462 | memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); |
1470 | *rrp = *lrp; | 1463 | *rrp = *lrp; |
1471 | xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1464 | xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1472 | INT_SET(key.br_startoff, ARCH_CONVERT, | 1465 | key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); |
1473 | xfs_bmbt_disk_get_startoff(rrp)); | ||
1474 | rkp = &key; | 1466 | rkp = &key; |
1475 | } | 1467 | } |
1476 | be16_add(&left->bb_numrecs, -1); | 1468 | be16_add(&left->bb_numrecs, -1); |
@@ -1535,7 +1527,7 @@ xfs_bmbt_split( | |||
1535 | xfs_btree_cur_t *cur, | 1527 | xfs_btree_cur_t *cur, |
1536 | int level, | 1528 | int level, |
1537 | xfs_fsblock_t *bnop, | 1529 | xfs_fsblock_t *bnop, |
1538 | xfs_bmbt_key_t *keyp, | 1530 | __uint64_t *startoff, |
1539 | xfs_btree_cur_t **curp, | 1531 | xfs_btree_cur_t **curp, |
1540 | int *stat) /* success/failure */ | 1532 | int *stat) /* success/failure */ |
1541 | { | 1533 | { |
@@ -1560,7 +1552,7 @@ xfs_bmbt_split( | |||
1560 | xfs_bmbt_rec_t *rrp; /* right record pointer */ | 1552 | xfs_bmbt_rec_t *rrp; /* right record pointer */ |
1561 | 1553 | ||
1562 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | 1554 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); |
1563 | XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, keyp); | 1555 | XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff); |
1564 | args.tp = cur->bc_tp; | 1556 | args.tp = cur->bc_tp; |
1565 | args.mp = cur->bc_mp; | 1557 | args.mp = cur->bc_mp; |
1566 | lbp = cur->bc_bufs[level]; | 1558 | lbp = cur->bc_bufs[level]; |
@@ -1619,7 +1611,7 @@ xfs_bmbt_split( | |||
1619 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); | 1611 | rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); |
1620 | #ifdef DEBUG | 1612 | #ifdef DEBUG |
1621 | for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { | 1613 | for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { |
1622 | if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) { | 1614 | if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) { |
1623 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 1615 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
1624 | return error; | 1616 | return error; |
1625 | } | 1617 | } |
@@ -1629,13 +1621,13 @@ xfs_bmbt_split( | |||
1629 | memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); | 1621 | memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); |
1630 | xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); | 1622 | xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); |
1631 | xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); | 1623 | xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); |
1632 | keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT); | 1624 | *startoff = be64_to_cpu(rkp->br_startoff); |
1633 | } else { | 1625 | } else { |
1634 | lrp = XFS_BMAP_REC_IADDR(left, i, cur); | 1626 | lrp = XFS_BMAP_REC_IADDR(left, i, cur); |
1635 | rrp = XFS_BMAP_REC_IADDR(right, 1, cur); | 1627 | rrp = XFS_BMAP_REC_IADDR(right, 1, cur); |
1636 | memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); | 1628 | memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); |
1637 | xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); | 1629 | xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); |
1638 | keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp); | 1630 | *startoff = xfs_bmbt_disk_get_startoff(rrp); |
1639 | } | 1631 | } |
1640 | be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); | 1632 | be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); |
1641 | right->bb_rightsib = left->bb_rightsib; | 1633 | right->bb_rightsib = left->bb_rightsib; |
@@ -1728,9 +1720,9 @@ xfs_bmdr_to_bmbt( | |||
1728 | { | 1720 | { |
1729 | int dmxr; | 1721 | int dmxr; |
1730 | xfs_bmbt_key_t *fkp; | 1722 | xfs_bmbt_key_t *fkp; |
1731 | xfs_bmbt_ptr_t *fpp; | 1723 | __be64 *fpp; |
1732 | xfs_bmbt_key_t *tkp; | 1724 | xfs_bmbt_key_t *tkp; |
1733 | xfs_bmbt_ptr_t *tpp; | 1725 | __be64 *tpp; |
1734 | 1726 | ||
1735 | rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); | 1727 | rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); |
1736 | rblock->bb_level = dblock->bb_level; | 1728 | rblock->bb_level = dblock->bb_level; |
@@ -1745,7 +1737,7 @@ xfs_bmdr_to_bmbt( | |||
1745 | tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); | 1737 | tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); |
1746 | dmxr = be16_to_cpu(dblock->bb_numrecs); | 1738 | dmxr = be16_to_cpu(dblock->bb_numrecs); |
1747 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); | 1739 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); |
1748 | memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */ | 1740 | memcpy(tpp, fpp, sizeof(*fpp) * dmxr); |
1749 | } | 1741 | } |
1750 | 1742 | ||
1751 | /* | 1743 | /* |
@@ -1805,7 +1797,7 @@ xfs_bmbt_decrement( | |||
1805 | tp = cur->bc_tp; | 1797 | tp = cur->bc_tp; |
1806 | mp = cur->bc_mp; | 1798 | mp = cur->bc_mp; |
1807 | for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { | 1799 | for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { |
1808 | fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT); | 1800 | fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur)); |
1809 | if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, | 1801 | if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, |
1810 | XFS_BMAP_BTREE_REF))) { | 1802 | XFS_BMAP_BTREE_REF))) { |
1811 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 1803 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
@@ -2135,7 +2127,7 @@ xfs_bmbt_increment( | |||
2135 | tp = cur->bc_tp; | 2127 | tp = cur->bc_tp; |
2136 | mp = cur->bc_mp; | 2128 | mp = cur->bc_mp; |
2137 | for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { | 2129 | for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { |
2138 | fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT); | 2130 | fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur)); |
2139 | if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, | 2131 | if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, |
2140 | XFS_BMAP_BTREE_REF))) { | 2132 | XFS_BMAP_BTREE_REF))) { |
2141 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 2133 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
@@ -2178,7 +2170,7 @@ xfs_bmbt_insert( | |||
2178 | level = 0; | 2170 | level = 0; |
2179 | nbno = NULLFSBLOCK; | 2171 | nbno = NULLFSBLOCK; |
2180 | xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b); | 2172 | xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b); |
2181 | ncur = (xfs_btree_cur_t *)0; | 2173 | ncur = NULL; |
2182 | pcur = cur; | 2174 | pcur = cur; |
2183 | do { | 2175 | do { |
2184 | if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur, | 2176 | if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur, |
@@ -2205,7 +2197,7 @@ xfs_bmbt_insert( | |||
2205 | } | 2197 | } |
2206 | if (ncur) { | 2198 | if (ncur) { |
2207 | pcur = ncur; | 2199 | pcur = ncur; |
2208 | ncur = (xfs_btree_cur_t *)0; | 2200 | ncur = NULL; |
2209 | } | 2201 | } |
2210 | } while (nbno != NULLFSBLOCK); | 2202 | } while (nbno != NULLFSBLOCK); |
2211 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | 2203 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); |
@@ -2356,12 +2348,12 @@ xfs_bmbt_newroot( | |||
2356 | args.firstblock = args.fsbno; | 2348 | args.firstblock = args.fsbno; |
2357 | if (args.fsbno == NULLFSBLOCK) { | 2349 | if (args.fsbno == NULLFSBLOCK) { |
2358 | #ifdef DEBUG | 2350 | #ifdef DEBUG |
2359 | if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { | 2351 | if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { |
2360 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 2352 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
2361 | return error; | 2353 | return error; |
2362 | } | 2354 | } |
2363 | #endif | 2355 | #endif |
2364 | args.fsbno = INT_GET(*pp, ARCH_CONVERT); | 2356 | args.fsbno = be64_to_cpu(*pp); |
2365 | args.type = XFS_ALLOCTYPE_START_BNO; | 2357 | args.type = XFS_ALLOCTYPE_START_BNO; |
2366 | } else | 2358 | } else |
2367 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 2359 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
@@ -2393,7 +2385,7 @@ xfs_bmbt_newroot( | |||
2393 | cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); | 2385 | cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); |
2394 | #ifdef DEBUG | 2386 | #ifdef DEBUG |
2395 | for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { | 2387 | for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { |
2396 | if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) { | 2388 | if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { |
2397 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 2389 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
2398 | return error; | 2390 | return error; |
2399 | } | 2391 | } |
@@ -2401,13 +2393,12 @@ xfs_bmbt_newroot( | |||
2401 | #endif | 2393 | #endif |
2402 | memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp)); | 2394 | memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp)); |
2403 | #ifdef DEBUG | 2395 | #ifdef DEBUG |
2404 | if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno, | 2396 | if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) { |
2405 | level))) { | ||
2406 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 2397 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
2407 | return error; | 2398 | return error; |
2408 | } | 2399 | } |
2409 | #endif | 2400 | #endif |
2410 | INT_SET(*pp, ARCH_CONVERT, args.fsbno); | 2401 | *pp = cpu_to_be64(args.fsbno); |
2411 | xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs), | 2402 | xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs), |
2412 | cur->bc_private.b.whichfork); | 2403 | cur->bc_private.b.whichfork); |
2413 | xfs_btree_setbuf(cur, level, bp); | 2404 | xfs_btree_setbuf(cur, level, bp); |
@@ -2681,9 +2672,9 @@ xfs_bmbt_to_bmdr( | |||
2681 | { | 2672 | { |
2682 | int dmxr; | 2673 | int dmxr; |
2683 | xfs_bmbt_key_t *fkp; | 2674 | xfs_bmbt_key_t *fkp; |
2684 | xfs_bmbt_ptr_t *fpp; | 2675 | __be64 *fpp; |
2685 | xfs_bmbt_key_t *tkp; | 2676 | xfs_bmbt_key_t *tkp; |
2686 | xfs_bmbt_ptr_t *tpp; | 2677 | __be64 *tpp; |
2687 | 2678 | ||
2688 | ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); | 2679 | ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); |
2689 | ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO); | 2680 | ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO); |
@@ -2698,7 +2689,7 @@ xfs_bmbt_to_bmdr( | |||
2698 | tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr); | 2689 | tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr); |
2699 | dmxr = be16_to_cpu(dblock->bb_numrecs); | 2690 | dmxr = be16_to_cpu(dblock->bb_numrecs); |
2700 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); | 2691 | memcpy(tkp, fkp, sizeof(*fkp) * dmxr); |
2701 | memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */ | 2692 | memcpy(tpp, fpp, sizeof(*fpp) * dmxr); |
2702 | } | 2693 | } |
2703 | 2694 | ||
2704 | /* | 2695 | /* |
@@ -2740,7 +2731,7 @@ xfs_bmbt_update( | |||
2740 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); | 2731 | XFS_BMBT_TRACE_CURSOR(cur, EXIT); |
2741 | return 0; | 2732 | return 0; |
2742 | } | 2733 | } |
2743 | INT_SET(key.br_startoff, ARCH_CONVERT, off); | 2734 | key.br_startoff = cpu_to_be64(off); |
2744 | if ((error = xfs_bmbt_updkey(cur, &key, 1))) { | 2735 | if ((error = xfs_bmbt_updkey(cur, &key, 1))) { |
2745 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); | 2736 | XFS_BMBT_TRACE_CURSOR(cur, ERROR); |
2746 | return error; | 2737 | return error; |
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 6478cfa0e539..49539de9525b 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h | |||
@@ -163,13 +163,14 @@ typedef struct xfs_bmbt_irec | |||
163 | /* | 163 | /* |
164 | * Key structure for non-leaf levels of the tree. | 164 | * Key structure for non-leaf levels of the tree. |
165 | */ | 165 | */ |
166 | typedef struct xfs_bmbt_key | 166 | typedef struct xfs_bmbt_key { |
167 | { | 167 | __be64 br_startoff; /* starting file offset */ |
168 | xfs_dfiloff_t br_startoff; /* starting file offset */ | ||
169 | } xfs_bmbt_key_t, xfs_bmdr_key_t; | 168 | } xfs_bmbt_key_t, xfs_bmdr_key_t; |
170 | 169 | ||
171 | typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */ | 170 | /* btree pointer type */ |
172 | /* btree block header type */ | 171 | typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; |
172 | |||
173 | /* btree block header type */ | ||
173 | typedef struct xfs_btree_lblock xfs_bmbt_block_t; | 174 | typedef struct xfs_btree_lblock xfs_bmbt_block_t; |
174 | 175 | ||
175 | #define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp)) | 176 | #define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp)) |
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index ee2255bd6562..aeb87ca69fcc 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c | |||
@@ -161,7 +161,7 @@ xfs_btree_check_key( | |||
161 | 161 | ||
162 | k1 = ak1; | 162 | k1 = ak1; |
163 | k2 = ak2; | 163 | k2 = ak2; |
164 | ASSERT(INT_GET(k1->br_startoff, ARCH_CONVERT) < INT_GET(k2->br_startoff, ARCH_CONVERT)); | 164 | ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff)); |
165 | break; | 165 | break; |
166 | } | 166 | } |
167 | case XFS_BTNUM_INO: { | 167 | case XFS_BTNUM_INO: { |
@@ -170,7 +170,7 @@ xfs_btree_check_key( | |||
170 | 170 | ||
171 | k1 = ak1; | 171 | k1 = ak1; |
172 | k2 = ak2; | 172 | k2 = ak2; |
173 | ASSERT(INT_GET(k1->ir_startino, ARCH_CONVERT) < INT_GET(k2->ir_startino, ARCH_CONVERT)); | 173 | ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino)); |
174 | break; | 174 | break; |
175 | } | 175 | } |
176 | default: | 176 | default: |
@@ -285,8 +285,8 @@ xfs_btree_check_rec( | |||
285 | 285 | ||
286 | r1 = ar1; | 286 | r1 = ar1; |
287 | r2 = ar2; | 287 | r2 = ar2; |
288 | ASSERT(INT_GET(r1->ir_startino, ARCH_CONVERT) + XFS_INODES_PER_CHUNK <= | 288 | ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <= |
289 | INT_GET(r2->ir_startino, ARCH_CONVERT)); | 289 | be32_to_cpu(r2->ir_startino)); |
290 | break; | 290 | break; |
291 | } | 291 | } |
292 | default: | 292 | default: |
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 44f1bd98064a..892b06c54263 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h | |||
@@ -145,7 +145,7 @@ typedef struct xfs_btree_cur | |||
145 | union { | 145 | union { |
146 | xfs_alloc_rec_incore_t a; | 146 | xfs_alloc_rec_incore_t a; |
147 | xfs_bmbt_irec_t b; | 147 | xfs_bmbt_irec_t b; |
148 | xfs_inobt_rec_t i; | 148 | xfs_inobt_rec_incore_t i; |
149 | } bc_rec; /* current insert/search record value */ | 149 | } bc_rec; /* current insert/search record value */ |
150 | struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ | 150 | struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ |
151 | int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ | 151 | int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ |
@@ -243,6 +243,9 @@ xfs_btree_check_lptr( | |||
243 | xfs_dfsbno_t ptr, /* btree block disk address */ | 243 | xfs_dfsbno_t ptr, /* btree block disk address */ |
244 | int level); /* btree block level */ | 244 | int level); /* btree block level */ |
245 | 245 | ||
246 | #define xfs_btree_check_lptr_disk(cur, ptr, level) \ | ||
247 | xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level) | ||
248 | |||
246 | /* | 249 | /* |
247 | * Checking routine: check that short form block header is ok. | 250 | * Checking routine: check that short form block header is ok. |
248 | */ | 251 | */ |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index a4aa53974f76..7a55c248ea70 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -234,7 +234,6 @@ xfs_buf_item_format( | |||
234 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || | 234 | ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || |
235 | (bip->bli_flags & XFS_BLI_STALE)); | 235 | (bip->bli_flags & XFS_BLI_STALE)); |
236 | bp = bip->bli_buf; | 236 | bp = bip->bli_buf; |
237 | ASSERT(XFS_BUF_BP_ISMAPPED(bp)); | ||
238 | vecp = log_vector; | 237 | vecp = log_vector; |
239 | 238 | ||
240 | /* | 239 | /* |
@@ -628,25 +627,6 @@ xfs_buf_item_committed( | |||
628 | } | 627 | } |
629 | 628 | ||
630 | /* | 629 | /* |
631 | * This is called when the transaction holding the buffer is aborted. | ||
632 | * Just behave as if the transaction had been cancelled. If we're shutting down | ||
633 | * and have aborted this transaction, we'll trap this buffer when it tries to | ||
634 | * get written out. | ||
635 | */ | ||
636 | STATIC void | ||
637 | xfs_buf_item_abort( | ||
638 | xfs_buf_log_item_t *bip) | ||
639 | { | ||
640 | xfs_buf_t *bp; | ||
641 | |||
642 | bp = bip->bli_buf; | ||
643 | xfs_buftrace("XFS_ABORT", bp); | ||
644 | XFS_BUF_SUPER_STALE(bp); | ||
645 | xfs_buf_item_unlock(bip); | ||
646 | return; | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * This is called to asynchronously write the buffer associated with this | 630 | * This is called to asynchronously write the buffer associated with this |
651 | * buf log item out to disk. The buffer will already have been locked by | 631 | * buf log item out to disk. The buffer will already have been locked by |
652 | * a successful call to xfs_buf_item_trylock(). If the buffer still has | 632 | * a successful call to xfs_buf_item_trylock(). If the buffer still has |
@@ -693,7 +673,6 @@ STATIC struct xfs_item_ops xfs_buf_item_ops = { | |||
693 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 673 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
694 | xfs_buf_item_committed, | 674 | xfs_buf_item_committed, |
695 | .iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push, | 675 | .iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push, |
696 | .iop_abort = (void(*)(xfs_log_item_t*))xfs_buf_item_abort, | ||
697 | .iop_pushbuf = NULL, | 676 | .iop_pushbuf = NULL, |
698 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 677 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
699 | xfs_buf_item_committing | 678 | xfs_buf_item_committing |
@@ -901,7 +880,6 @@ xfs_buf_item_relse( | |||
901 | XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list); | 880 | XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list); |
902 | if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) && | 881 | if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) && |
903 | (XFS_BUF_IODONE_FUNC(bp) != NULL)) { | 882 | (XFS_BUF_IODONE_FUNC(bp) != NULL)) { |
904 | ASSERT((XFS_BUF_ISUNINITIAL(bp)) == 0); | ||
905 | XFS_BUF_CLR_IODONE_FUNC(bp); | 883 | XFS_BUF_CLR_IODONE_FUNC(bp); |
906 | } | 884 | } |
907 | 885 | ||
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 32ab61d17ace..a68bc1f1a313 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -1054,7 +1054,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1054 | xfs_da_node_entry_t *btree; | 1054 | xfs_da_node_entry_t *btree; |
1055 | xfs_dablk_t blkno; | 1055 | xfs_dablk_t blkno; |
1056 | int probe, span, max, error, retval; | 1056 | int probe, span, max, error, retval; |
1057 | xfs_dahash_t hashval; | 1057 | xfs_dahash_t hashval, btreehashval; |
1058 | xfs_da_args_t *args; | 1058 | xfs_da_args_t *args; |
1059 | 1059 | ||
1060 | args = state->args; | 1060 | args = state->args; |
@@ -1079,30 +1079,32 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1079 | return(error); | 1079 | return(error); |
1080 | } | 1080 | } |
1081 | curr = blk->bp->data; | 1081 | curr = blk->bp->data; |
1082 | ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || | 1082 | blk->magic = be16_to_cpu(curr->magic); |
1083 | be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC || | 1083 | ASSERT(blk->magic == XFS_DA_NODE_MAGIC || |
1084 | be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); | 1084 | blk->magic == XFS_DIR2_LEAFN_MAGIC || |
1085 | blk->magic == XFS_ATTR_LEAF_MAGIC); | ||
1085 | 1086 | ||
1086 | /* | 1087 | /* |
1087 | * Search an intermediate node for a match. | 1088 | * Search an intermediate node for a match. |
1088 | */ | 1089 | */ |
1089 | blk->magic = be16_to_cpu(curr->magic); | ||
1090 | if (blk->magic == XFS_DA_NODE_MAGIC) { | 1090 | if (blk->magic == XFS_DA_NODE_MAGIC) { |
1091 | node = blk->bp->data; | 1091 | node = blk->bp->data; |
1092 | blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); | 1092 | max = be16_to_cpu(node->hdr.count); |
1093 | btreehashval = node->btree[max-1].hashval; | ||
1094 | blk->hashval = be32_to_cpu(btreehashval); | ||
1093 | 1095 | ||
1094 | /* | 1096 | /* |
1095 | * Binary search. (note: small blocks will skip loop) | 1097 | * Binary search. (note: small blocks will skip loop) |
1096 | */ | 1098 | */ |
1097 | max = be16_to_cpu(node->hdr.count); | ||
1098 | probe = span = max / 2; | 1099 | probe = span = max / 2; |
1099 | hashval = args->hashval; | 1100 | hashval = args->hashval; |
1100 | for (btree = &node->btree[probe]; span > 4; | 1101 | for (btree = &node->btree[probe]; span > 4; |
1101 | btree = &node->btree[probe]) { | 1102 | btree = &node->btree[probe]) { |
1102 | span /= 2; | 1103 | span /= 2; |
1103 | if (be32_to_cpu(btree->hashval) < hashval) | 1104 | btreehashval = be32_to_cpu(btree->hashval); |
1105 | if (btreehashval < hashval) | ||
1104 | probe += span; | 1106 | probe += span; |
1105 | else if (be32_to_cpu(btree->hashval) > hashval) | 1107 | else if (btreehashval > hashval) |
1106 | probe -= span; | 1108 | probe -= span; |
1107 | else | 1109 | else |
1108 | break; | 1110 | break; |
@@ -1133,10 +1135,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1133 | blk->index = probe; | 1135 | blk->index = probe; |
1134 | blkno = be32_to_cpu(btree->before); | 1136 | blkno = be32_to_cpu(btree->before); |
1135 | } | 1137 | } |
1136 | } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { | 1138 | } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { |
1137 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); | 1139 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); |
1138 | break; | 1140 | break; |
1139 | } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { | 1141 | } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { |
1140 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); | 1142 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); |
1141 | break; | 1143 | break; |
1142 | } | 1144 | } |
@@ -1152,11 +1154,13 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1152 | if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { | 1154 | if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { |
1153 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, | 1155 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, |
1154 | &blk->index, state); | 1156 | &blk->index, state); |
1155 | } | 1157 | } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { |
1156 | else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { | ||
1157 | retval = xfs_attr_leaf_lookup_int(blk->bp, args); | 1158 | retval = xfs_attr_leaf_lookup_int(blk->bp, args); |
1158 | blk->index = args->index; | 1159 | blk->index = args->index; |
1159 | args->blkno = blk->blkno; | 1160 | args->blkno = blk->blkno; |
1161 | } else { | ||
1162 | ASSERT(0); | ||
1163 | return XFS_ERROR(EFSCORRUPTED); | ||
1160 | } | 1164 | } |
1161 | if (((retval == ENOENT) || (retval == ENOATTR)) && | 1165 | if (((retval == ENOENT) || (retval == ENOATTR)) && |
1162 | (blk->hashval == args->hashval)) { | 1166 | (blk->hashval == args->hashval)) { |
@@ -1166,8 +1170,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1166 | return(error); | 1170 | return(error); |
1167 | if (retval == 0) { | 1171 | if (retval == 0) { |
1168 | continue; | 1172 | continue; |
1169 | } | 1173 | } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { |
1170 | else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { | ||
1171 | /* path_shift() gives ENOENT */ | 1174 | /* path_shift() gives ENOENT */ |
1172 | retval = XFS_ERROR(ENOATTR); | 1175 | retval = XFS_ERROR(ENOATTR); |
1173 | } | 1176 | } |
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index bc43163456ef..0893e16b7d83 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h | |||
@@ -18,14 +18,6 @@ | |||
18 | #ifndef __XFS_ERROR_H__ | 18 | #ifndef __XFS_ERROR_H__ |
19 | #define __XFS_ERROR_H__ | 19 | #define __XFS_ERROR_H__ |
20 | 20 | ||
21 | #define XFS_ERECOVER 1 /* Failure to recover log */ | ||
22 | #define XFS_ELOGSTAT 2 /* Failure to stat log in user space */ | ||
23 | #define XFS_ENOLOGSPACE 3 /* Reservation too large */ | ||
24 | #define XFS_ENOTSUP 4 /* Operation not supported */ | ||
25 | #define XFS_ENOLSN 5 /* Can't find the lsn you asked for */ | ||
26 | #define XFS_ENOTFOUND 6 | ||
27 | #define XFS_ENOTXFS 7 /* Not XFS filesystem */ | ||
28 | |||
29 | #ifdef DEBUG | 21 | #ifdef DEBUG |
30 | #define XFS_ERROR_NTRAP 10 | 22 | #define XFS_ERROR_NTRAP 10 |
31 | extern int xfs_etrap[XFS_ERROR_NTRAP]; | 23 | extern int xfs_etrap[XFS_ERROR_NTRAP]; |
@@ -175,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud); | |||
175 | #define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 | 167 | #define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 |
176 | #define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 | 168 | #define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 |
177 | #define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 | 169 | #define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 |
170 | #define XFS_PTAG_FSBLOCK_ZERO 0x00000080 | ||
178 | 171 | ||
179 | struct xfs_mount; | 172 | struct xfs_mount; |
180 | /* PRINTFLIKE4 */ | 173 | /* PRINTFLIKE4 */ |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 6cf6d8769b97..6dba78199faf 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -33,9 +33,6 @@ kmem_zone_t *xfs_efi_zone; | |||
33 | kmem_zone_t *xfs_efd_zone; | 33 | kmem_zone_t *xfs_efd_zone; |
34 | 34 | ||
35 | STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *); | 35 | STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *); |
36 | STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *); | ||
37 | STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *); | ||
38 | |||
39 | 36 | ||
40 | void | 37 | void |
41 | xfs_efi_item_free(xfs_efi_log_item_t *efip) | 38 | xfs_efi_item_free(xfs_efi_log_item_t *efip) |
@@ -184,7 +181,7 @@ STATIC void | |||
184 | xfs_efi_item_unlock(xfs_efi_log_item_t *efip) | 181 | xfs_efi_item_unlock(xfs_efi_log_item_t *efip) |
185 | { | 182 | { |
186 | if (efip->efi_item.li_flags & XFS_LI_ABORTED) | 183 | if (efip->efi_item.li_flags & XFS_LI_ABORTED) |
187 | xfs_efi_item_abort(efip); | 184 | xfs_efi_item_free(efip); |
188 | return; | 185 | return; |
189 | } | 186 | } |
190 | 187 | ||
@@ -202,18 +199,6 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn) | |||
202 | } | 199 | } |
203 | 200 | ||
204 | /* | 201 | /* |
205 | * This is called when the transaction logging the EFI is aborted. | ||
206 | * Free up the EFI and return. No need to clean up the slot for | ||
207 | * the item in the transaction. That was done by the unpin code | ||
208 | * which is called prior to this routine in the abort/fs-shutdown path. | ||
209 | */ | ||
210 | STATIC void | ||
211 | xfs_efi_item_abort(xfs_efi_log_item_t *efip) | ||
212 | { | ||
213 | xfs_efi_item_free(efip); | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * There isn't much you can do to push on an efi item. It is simply | 202 | * There isn't much you can do to push on an efi item. It is simply |
218 | * stuck waiting for all of its corresponding efd items to be | 203 | * stuck waiting for all of its corresponding efd items to be |
219 | * committed to disk. | 204 | * committed to disk. |
@@ -255,7 +240,6 @@ STATIC struct xfs_item_ops xfs_efi_item_ops = { | |||
255 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 240 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
256 | xfs_efi_item_committed, | 241 | xfs_efi_item_committed, |
257 | .iop_push = (void(*)(xfs_log_item_t*))xfs_efi_item_push, | 242 | .iop_push = (void(*)(xfs_log_item_t*))xfs_efi_item_push, |
258 | .iop_abort = (void(*)(xfs_log_item_t*))xfs_efi_item_abort, | ||
259 | .iop_pushbuf = NULL, | 243 | .iop_pushbuf = NULL, |
260 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 244 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
261 | xfs_efi_item_committing | 245 | xfs_efi_item_committing |
@@ -386,33 +370,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip, | |||
386 | } | 370 | } |
387 | } | 371 | } |
388 | 372 | ||
389 | /* | ||
390 | * This is called when the transaction that should be committing the | ||
391 | * EFD corresponding to the given EFI is aborted. The committed and | ||
392 | * canceled flags are used to coordinate the freeing of the EFI and | ||
393 | * the references by the transaction that committed it. | ||
394 | */ | ||
395 | STATIC void | ||
396 | xfs_efi_cancel( | ||
397 | xfs_efi_log_item_t *efip) | ||
398 | { | ||
399 | xfs_mount_t *mp; | ||
400 | SPLDECL(s); | ||
401 | |||
402 | mp = efip->efi_item.li_mountp; | ||
403 | AIL_LOCK(mp, s); | ||
404 | if (efip->efi_flags & XFS_EFI_COMMITTED) { | ||
405 | /* | ||
406 | * xfs_trans_delete_ail() drops the AIL lock. | ||
407 | */ | ||
408 | xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); | ||
409 | xfs_efi_item_free(efip); | ||
410 | } else { | ||
411 | efip->efi_flags |= XFS_EFI_CANCELED; | ||
412 | AIL_UNLOCK(mp, s); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | STATIC void | 373 | STATIC void |
417 | xfs_efd_item_free(xfs_efd_log_item_t *efdp) | 374 | xfs_efd_item_free(xfs_efd_log_item_t *efdp) |
418 | { | 375 | { |
@@ -514,7 +471,7 @@ STATIC void | |||
514 | xfs_efd_item_unlock(xfs_efd_log_item_t *efdp) | 471 | xfs_efd_item_unlock(xfs_efd_log_item_t *efdp) |
515 | { | 472 | { |
516 | if (efdp->efd_item.li_flags & XFS_LI_ABORTED) | 473 | if (efdp->efd_item.li_flags & XFS_LI_ABORTED) |
517 | xfs_efd_item_abort(efdp); | 474 | xfs_efd_item_free(efdp); |
518 | return; | 475 | return; |
519 | } | 476 | } |
520 | 477 | ||
@@ -541,27 +498,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn) | |||
541 | } | 498 | } |
542 | 499 | ||
543 | /* | 500 | /* |
544 | * The transaction of which this EFD is a part has been aborted. | ||
545 | * Inform its companion EFI of this fact and then clean up after | ||
546 | * ourselves. No need to clean up the slot for the item in the | ||
547 | * transaction. That was done by the unpin code which is called | ||
548 | * prior to this routine in the abort/fs-shutdown path. | ||
549 | */ | ||
550 | STATIC void | ||
551 | xfs_efd_item_abort(xfs_efd_log_item_t *efdp) | ||
552 | { | ||
553 | /* | ||
554 | * If we got a log I/O error, it's always the case that the LR with the | ||
555 | * EFI got unpinned and freed before the EFD got aborted. So don't | ||
556 | * reference the EFI at all in that case. | ||
557 | */ | ||
558 | if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) | ||
559 | xfs_efi_cancel(efdp->efd_efip); | ||
560 | |||
561 | xfs_efd_item_free(efdp); | ||
562 | } | ||
563 | |||
564 | /* | ||
565 | * There isn't much you can do to push on an efd item. It is simply | 501 | * There isn't much you can do to push on an efd item. It is simply |
566 | * stuck waiting for the log to be flushed to disk. | 502 | * stuck waiting for the log to be flushed to disk. |
567 | */ | 503 | */ |
@@ -602,7 +538,6 @@ STATIC struct xfs_item_ops xfs_efd_item_ops = { | |||
602 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 538 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
603 | xfs_efd_item_committed, | 539 | xfs_efd_item_committed, |
604 | .iop_push = (void(*)(xfs_log_item_t*))xfs_efd_item_push, | 540 | .iop_push = (void(*)(xfs_log_item_t*))xfs_efd_item_push, |
605 | .iop_abort = (void(*)(xfs_log_item_t*))xfs_efd_item_abort, | ||
606 | .iop_pushbuf = NULL, | 541 | .iop_pushbuf = NULL, |
607 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 542 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
608 | xfs_efd_item_committing | 543 | xfs_efd_item_committing |
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h index 0ea45edaab03..2f049f63e85f 100644 --- a/fs/xfs/xfs_extfree_item.h +++ b/fs/xfs/xfs_extfree_item.h | |||
@@ -33,14 +33,16 @@ typedef struct xfs_extent { | |||
33 | * conversion routine. | 33 | * conversion routine. |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #ifndef HAVE_FORMAT32 | ||
36 | typedef struct xfs_extent_32 { | 37 | typedef struct xfs_extent_32 { |
37 | xfs_dfsbno_t ext_start; | 38 | __uint64_t ext_start; |
38 | xfs_extlen_t ext_len; | 39 | __uint32_t ext_len; |
39 | } __attribute__((packed)) xfs_extent_32_t; | 40 | } __attribute__((packed)) xfs_extent_32_t; |
41 | #endif | ||
40 | 42 | ||
41 | typedef struct xfs_extent_64 { | 43 | typedef struct xfs_extent_64 { |
42 | xfs_dfsbno_t ext_start; | 44 | __uint64_t ext_start; |
43 | xfs_extlen_t ext_len; | 45 | __uint32_t ext_len; |
44 | __uint32_t ext_pad; | 46 | __uint32_t ext_pad; |
45 | } xfs_extent_64_t; | 47 | } xfs_extent_64_t; |
46 | 48 | ||
@@ -50,25 +52,27 @@ typedef struct xfs_extent_64 { | |||
50 | * size is given by efi_nextents. | 52 | * size is given by efi_nextents. |
51 | */ | 53 | */ |
52 | typedef struct xfs_efi_log_format { | 54 | typedef struct xfs_efi_log_format { |
53 | unsigned short efi_type; /* efi log item type */ | 55 | __uint16_t efi_type; /* efi log item type */ |
54 | unsigned short efi_size; /* size of this item */ | 56 | __uint16_t efi_size; /* size of this item */ |
55 | uint efi_nextents; /* # extents to free */ | 57 | __uint32_t efi_nextents; /* # extents to free */ |
56 | __uint64_t efi_id; /* efi identifier */ | 58 | __uint64_t efi_id; /* efi identifier */ |
57 | xfs_extent_t efi_extents[1]; /* array of extents to free */ | 59 | xfs_extent_t efi_extents[1]; /* array of extents to free */ |
58 | } xfs_efi_log_format_t; | 60 | } xfs_efi_log_format_t; |
59 | 61 | ||
62 | #ifndef HAVE_FORMAT32 | ||
60 | typedef struct xfs_efi_log_format_32 { | 63 | typedef struct xfs_efi_log_format_32 { |
61 | unsigned short efi_type; /* efi log item type */ | 64 | __uint16_t efi_type; /* efi log item type */ |
62 | unsigned short efi_size; /* size of this item */ | 65 | __uint16_t efi_size; /* size of this item */ |
63 | uint efi_nextents; /* # extents to free */ | 66 | __uint32_t efi_nextents; /* # extents to free */ |
64 | __uint64_t efi_id; /* efi identifier */ | 67 | __uint64_t efi_id; /* efi identifier */ |
65 | xfs_extent_32_t efi_extents[1]; /* array of extents to free */ | 68 | xfs_extent_32_t efi_extents[1]; /* array of extents to free */ |
66 | } __attribute__((packed)) xfs_efi_log_format_32_t; | 69 | } __attribute__((packed)) xfs_efi_log_format_32_t; |
70 | #endif | ||
67 | 71 | ||
68 | typedef struct xfs_efi_log_format_64 { | 72 | typedef struct xfs_efi_log_format_64 { |
69 | unsigned short efi_type; /* efi log item type */ | 73 | __uint16_t efi_type; /* efi log item type */ |
70 | unsigned short efi_size; /* size of this item */ | 74 | __uint16_t efi_size; /* size of this item */ |
71 | uint efi_nextents; /* # extents to free */ | 75 | __uint32_t efi_nextents; /* # extents to free */ |
72 | __uint64_t efi_id; /* efi identifier */ | 76 | __uint64_t efi_id; /* efi identifier */ |
73 | xfs_extent_64_t efi_extents[1]; /* array of extents to free */ | 77 | xfs_extent_64_t efi_extents[1]; /* array of extents to free */ |
74 | } xfs_efi_log_format_64_t; | 78 | } xfs_efi_log_format_64_t; |
@@ -79,25 +83,27 @@ typedef struct xfs_efi_log_format_64 { | |||
79 | * size is given by efd_nextents; | 83 | * size is given by efd_nextents; |
80 | */ | 84 | */ |
81 | typedef struct xfs_efd_log_format { | 85 | typedef struct xfs_efd_log_format { |
82 | unsigned short efd_type; /* efd log item type */ | 86 | __uint16_t efd_type; /* efd log item type */ |
83 | unsigned short efd_size; /* size of this item */ | 87 | __uint16_t efd_size; /* size of this item */ |
84 | uint efd_nextents; /* # of extents freed */ | 88 | __uint32_t efd_nextents; /* # of extents freed */ |
85 | __uint64_t efd_efi_id; /* id of corresponding efi */ | 89 | __uint64_t efd_efi_id; /* id of corresponding efi */ |
86 | xfs_extent_t efd_extents[1]; /* array of extents freed */ | 90 | xfs_extent_t efd_extents[1]; /* array of extents freed */ |
87 | } xfs_efd_log_format_t; | 91 | } xfs_efd_log_format_t; |
88 | 92 | ||
93 | #ifndef HAVE_FORMAT32 | ||
89 | typedef struct xfs_efd_log_format_32 { | 94 | typedef struct xfs_efd_log_format_32 { |
90 | unsigned short efd_type; /* efd log item type */ | 95 | __uint16_t efd_type; /* efd log item type */ |
91 | unsigned short efd_size; /* size of this item */ | 96 | __uint16_t efd_size; /* size of this item */ |
92 | uint efd_nextents; /* # of extents freed */ | 97 | __uint32_t efd_nextents; /* # of extents freed */ |
93 | __uint64_t efd_efi_id; /* id of corresponding efi */ | 98 | __uint64_t efd_efi_id; /* id of corresponding efi */ |
94 | xfs_extent_32_t efd_extents[1]; /* array of extents freed */ | 99 | xfs_extent_32_t efd_extents[1]; /* array of extents freed */ |
95 | } __attribute__((packed)) xfs_efd_log_format_32_t; | 100 | } __attribute__((packed)) xfs_efd_log_format_32_t; |
101 | #endif | ||
96 | 102 | ||
97 | typedef struct xfs_efd_log_format_64 { | 103 | typedef struct xfs_efd_log_format_64 { |
98 | unsigned short efd_type; /* efd log item type */ | 104 | __uint16_t efd_type; /* efd log item type */ |
99 | unsigned short efd_size; /* size of this item */ | 105 | __uint16_t efd_size; /* size of this item */ |
100 | uint efd_nextents; /* # of extents freed */ | 106 | __uint32_t efd_nextents; /* # of extents freed */ |
101 | __uint64_t efd_efi_id; /* id of corresponding efi */ | 107 | __uint64_t efd_efi_id; /* id of corresponding efi */ |
102 | xfs_extent_64_t efd_extents[1]; /* array of extents freed */ | 108 | xfs_extent_64_t efd_extents[1]; /* array of extents freed */ |
103 | } xfs_efd_log_format_64_t; | 109 | } xfs_efd_log_format_64_t; |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 0f0ad1535951..1335449841cd 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -22,8 +22,6 @@ | |||
22 | * SGI's XFS filesystem's major stuff (constants, structures) | 22 | * SGI's XFS filesystem's major stuff (constants, structures) |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define XFS_NAME "xfs" | ||
26 | |||
27 | /* | 25 | /* |
28 | * Direct I/O attribute record used with XFS_IOC_DIOINFO | 26 | * Direct I/O attribute record used with XFS_IOC_DIOINFO |
29 | * d_miniosz is the min xfer size, xfer size multiple and file seek offset | 27 | * d_miniosz is the min xfer size, xfer size multiple and file seek offset |
@@ -426,11 +424,7 @@ typedef struct xfs_handle { | |||
426 | - (char *) &(handle)) \ | 424 | - (char *) &(handle)) \ |
427 | + (handle).ha_fid.xfs_fid_len) | 425 | + (handle).ha_fid.xfs_fid_len) |
428 | 426 | ||
429 | #define XFS_HANDLE_CMP(h1, h2) memcmp(h1, h2, sizeof(xfs_handle_t)) | 427 | /* |
430 | |||
431 | #define FSHSIZE sizeof(fsid_t) | ||
432 | |||
433 | /* | ||
434 | * Flags for going down operation | 428 | * Flags for going down operation |
435 | */ | 429 | */ |
436 | #define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */ | 430 | #define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */ |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 33164a85aa9d..a446e5a115c6 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -458,7 +458,7 @@ nextag: | |||
458 | */ | 458 | */ |
459 | if (XFS_FORCED_SHUTDOWN(mp)) { | 459 | if (XFS_FORCED_SHUTDOWN(mp)) { |
460 | up_read(&mp->m_peraglock); | 460 | up_read(&mp->m_peraglock); |
461 | return (xfs_buf_t *)0; | 461 | return NULL; |
462 | } | 462 | } |
463 | agno++; | 463 | agno++; |
464 | if (agno >= agcount) | 464 | if (agno >= agcount) |
@@ -466,7 +466,7 @@ nextag: | |||
466 | if (agno == pagno) { | 466 | if (agno == pagno) { |
467 | if (flags == 0) { | 467 | if (flags == 0) { |
468 | up_read(&mp->m_peraglock); | 468 | up_read(&mp->m_peraglock); |
469 | return (xfs_buf_t *)0; | 469 | return NULL; |
470 | } | 470 | } |
471 | flags = 0; | 471 | flags = 0; |
472 | } | 472 | } |
@@ -529,10 +529,10 @@ xfs_dialloc( | |||
529 | int offset; /* index of inode in chunk */ | 529 | int offset; /* index of inode in chunk */ |
530 | xfs_agino_t pagino; /* parent's a.g. relative inode # */ | 530 | xfs_agino_t pagino; /* parent's a.g. relative inode # */ |
531 | xfs_agnumber_t pagno; /* parent's allocation group number */ | 531 | xfs_agnumber_t pagno; /* parent's allocation group number */ |
532 | xfs_inobt_rec_t rec; /* inode allocation record */ | 532 | xfs_inobt_rec_incore_t rec; /* inode allocation record */ |
533 | xfs_agnumber_t tagno; /* testing allocation group number */ | 533 | xfs_agnumber_t tagno; /* testing allocation group number */ |
534 | xfs_btree_cur_t *tcur; /* temp cursor */ | 534 | xfs_btree_cur_t *tcur; /* temp cursor */ |
535 | xfs_inobt_rec_t trec; /* temp inode allocation record */ | 535 | xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ |
536 | 536 | ||
537 | 537 | ||
538 | if (*IO_agbp == NULL) { | 538 | if (*IO_agbp == NULL) { |
@@ -945,7 +945,7 @@ xfs_difree( | |||
945 | int ilen; /* inodes in an inode cluster */ | 945 | int ilen; /* inodes in an inode cluster */ |
946 | xfs_mount_t *mp; /* mount structure for filesystem */ | 946 | xfs_mount_t *mp; /* mount structure for filesystem */ |
947 | int off; /* offset of inode in inode chunk */ | 947 | int off; /* offset of inode in inode chunk */ |
948 | xfs_inobt_rec_t rec; /* btree record */ | 948 | xfs_inobt_rec_incore_t rec; /* btree record */ |
949 | 949 | ||
950 | mp = tp->t_mountp; | 950 | mp = tp->t_mountp; |
951 | 951 | ||
@@ -1195,6 +1195,7 @@ xfs_dilocate( | |||
1195 | "(0x%llx)", | 1195 | "(0x%llx)", |
1196 | ino, XFS_AGINO_TO_INO(mp, agno, agino)); | 1196 | ino, XFS_AGINO_TO_INO(mp, agno, agino)); |
1197 | } | 1197 | } |
1198 | xfs_stack_trace(); | ||
1198 | #endif /* DEBUG */ | 1199 | #endif /* DEBUG */ |
1199 | return XFS_ERROR(EINVAL); | 1200 | return XFS_ERROR(EINVAL); |
1200 | } | 1201 | } |
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 616eeeb6953e..8cdeeaf8632b 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c | |||
@@ -568,7 +568,7 @@ xfs_inobt_insrec( | |||
568 | /* | 568 | /* |
569 | * Make a key out of the record data to be inserted, and save it. | 569 | * Make a key out of the record data to be inserted, and save it. |
570 | */ | 570 | */ |
571 | key.ir_startino = recp->ir_startino; /* INT_: direct copy */ | 571 | key.ir_startino = recp->ir_startino; |
572 | optr = ptr = cur->bc_ptrs[level]; | 572 | optr = ptr = cur->bc_ptrs[level]; |
573 | /* | 573 | /* |
574 | * If we're off the left edge, return failure. | 574 | * If we're off the left edge, return failure. |
@@ -600,7 +600,7 @@ xfs_inobt_insrec( | |||
600 | } | 600 | } |
601 | #endif | 601 | #endif |
602 | nbno = NULLAGBLOCK; | 602 | nbno = NULLAGBLOCK; |
603 | ncur = (xfs_btree_cur_t *)0; | 603 | ncur = NULL; |
604 | /* | 604 | /* |
605 | * If the block is full, we can't insert the new entry until we | 605 | * If the block is full, we can't insert the new entry until we |
606 | * make the block un-full. | 606 | * make the block un-full. |
@@ -641,7 +641,7 @@ xfs_inobt_insrec( | |||
641 | return error; | 641 | return error; |
642 | #endif | 642 | #endif |
643 | ptr = cur->bc_ptrs[level]; | 643 | ptr = cur->bc_ptrs[level]; |
644 | nrec.ir_startino = nkey.ir_startino; /* INT_: direct copy */ | 644 | nrec.ir_startino = nkey.ir_startino; |
645 | } else { | 645 | } else { |
646 | /* | 646 | /* |
647 | * Otherwise the insert fails. | 647 | * Otherwise the insert fails. |
@@ -681,7 +681,7 @@ xfs_inobt_insrec( | |||
681 | if ((error = xfs_btree_check_sptr(cur, *bnop, level))) | 681 | if ((error = xfs_btree_check_sptr(cur, *bnop, level))) |
682 | return error; | 682 | return error; |
683 | #endif | 683 | #endif |
684 | kp[ptr - 1] = key; /* INT_: struct copy */ | 684 | kp[ptr - 1] = key; |
685 | pp[ptr - 1] = cpu_to_be32(*bnop); | 685 | pp[ptr - 1] = cpu_to_be32(*bnop); |
686 | numrecs++; | 686 | numrecs++; |
687 | block->bb_numrecs = cpu_to_be16(numrecs); | 687 | block->bb_numrecs = cpu_to_be16(numrecs); |
@@ -698,7 +698,7 @@ xfs_inobt_insrec( | |||
698 | * Now stuff the new record in, bump numrecs | 698 | * Now stuff the new record in, bump numrecs |
699 | * and log the new data. | 699 | * and log the new data. |
700 | */ | 700 | */ |
701 | rp[ptr - 1] = *recp; /* INT_: struct copy */ | 701 | rp[ptr - 1] = *recp; |
702 | numrecs++; | 702 | numrecs++; |
703 | block->bb_numrecs = cpu_to_be16(numrecs); | 703 | block->bb_numrecs = cpu_to_be16(numrecs); |
704 | xfs_inobt_log_recs(cur, bp, ptr, numrecs); | 704 | xfs_inobt_log_recs(cur, bp, ptr, numrecs); |
@@ -731,7 +731,7 @@ xfs_inobt_insrec( | |||
731 | */ | 731 | */ |
732 | *bnop = nbno; | 732 | *bnop = nbno; |
733 | if (nbno != NULLAGBLOCK) { | 733 | if (nbno != NULLAGBLOCK) { |
734 | *recp = nrec; /* INT_: struct copy */ | 734 | *recp = nrec; |
735 | *curp = ncur; | 735 | *curp = ncur; |
736 | } | 736 | } |
737 | *stat = 1; | 737 | *stat = 1; |
@@ -878,7 +878,7 @@ xfs_inobt_lookup( | |||
878 | */ | 878 | */ |
879 | bp = cur->bc_bufs[level]; | 879 | bp = cur->bc_bufs[level]; |
880 | if (bp && XFS_BUF_ADDR(bp) != d) | 880 | if (bp && XFS_BUF_ADDR(bp) != d) |
881 | bp = (xfs_buf_t *)0; | 881 | bp = NULL; |
882 | if (!bp) { | 882 | if (!bp) { |
883 | /* | 883 | /* |
884 | * Need to get a new buffer. Read it, then | 884 | * Need to get a new buffer. Read it, then |
@@ -950,12 +950,12 @@ xfs_inobt_lookup( | |||
950 | xfs_inobt_key_t *kkp; | 950 | xfs_inobt_key_t *kkp; |
951 | 951 | ||
952 | kkp = kkbase + keyno - 1; | 952 | kkp = kkbase + keyno - 1; |
953 | startino = INT_GET(kkp->ir_startino, ARCH_CONVERT); | 953 | startino = be32_to_cpu(kkp->ir_startino); |
954 | } else { | 954 | } else { |
955 | xfs_inobt_rec_t *krp; | 955 | xfs_inobt_rec_t *krp; |
956 | 956 | ||
957 | krp = krbase + keyno - 1; | 957 | krp = krbase + keyno - 1; |
958 | startino = INT_GET(krp->ir_startino, ARCH_CONVERT); | 958 | startino = be32_to_cpu(krp->ir_startino); |
959 | } | 959 | } |
960 | /* | 960 | /* |
961 | * Compute difference to get next direction. | 961 | * Compute difference to get next direction. |
@@ -1117,7 +1117,7 @@ xfs_inobt_lshift( | |||
1117 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) | 1117 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) |
1118 | return error; | 1118 | return error; |
1119 | #endif | 1119 | #endif |
1120 | *lpp = *rpp; /* INT_: no-change copy */ | 1120 | *lpp = *rpp; |
1121 | xfs_inobt_log_ptrs(cur, lbp, nrec, nrec); | 1121 | xfs_inobt_log_ptrs(cur, lbp, nrec, nrec); |
1122 | } | 1122 | } |
1123 | /* | 1123 | /* |
@@ -1160,7 +1160,7 @@ xfs_inobt_lshift( | |||
1160 | } else { | 1160 | } else { |
1161 | memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); | 1161 | memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); |
1162 | xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); | 1162 | xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); |
1163 | key.ir_startino = rrp->ir_startino; /* INT_: direct copy */ | 1163 | key.ir_startino = rrp->ir_startino; |
1164 | rkp = &key; | 1164 | rkp = &key; |
1165 | } | 1165 | } |
1166 | /* | 1166 | /* |
@@ -1297,13 +1297,13 @@ xfs_inobt_newroot( | |||
1297 | */ | 1297 | */ |
1298 | kp = XFS_INOBT_KEY_ADDR(new, 1, cur); | 1298 | kp = XFS_INOBT_KEY_ADDR(new, 1, cur); |
1299 | if (be16_to_cpu(left->bb_level) > 0) { | 1299 | if (be16_to_cpu(left->bb_level) > 0) { |
1300 | kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */ | 1300 | kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); |
1301 | kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */ | 1301 | kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); |
1302 | } else { | 1302 | } else { |
1303 | rp = XFS_INOBT_REC_ADDR(left, 1, cur); | 1303 | rp = XFS_INOBT_REC_ADDR(left, 1, cur); |
1304 | INT_COPY(kp[0].ir_startino, rp->ir_startino, ARCH_CONVERT); | 1304 | kp[0].ir_startino = rp->ir_startino; |
1305 | rp = XFS_INOBT_REC_ADDR(right, 1, cur); | 1305 | rp = XFS_INOBT_REC_ADDR(right, 1, cur); |
1306 | INT_COPY(kp[1].ir_startino, rp->ir_startino, ARCH_CONVERT); | 1306 | kp[1].ir_startino = rp->ir_startino; |
1307 | } | 1307 | } |
1308 | xfs_inobt_log_keys(cur, nbp, 1, 2); | 1308 | xfs_inobt_log_keys(cur, nbp, 1, 2); |
1309 | /* | 1309 | /* |
@@ -1410,8 +1410,8 @@ xfs_inobt_rshift( | |||
1410 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) | 1410 | if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) |
1411 | return error; | 1411 | return error; |
1412 | #endif | 1412 | #endif |
1413 | *rkp = *lkp; /* INT_: no change copy */ | 1413 | *rkp = *lkp; |
1414 | *rpp = *lpp; /* INT_: no change copy */ | 1414 | *rpp = *lpp; |
1415 | xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1415 | xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1416 | xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1416 | xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1417 | } else { | 1417 | } else { |
@@ -1420,7 +1420,7 @@ xfs_inobt_rshift( | |||
1420 | memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); | 1420 | memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); |
1421 | *rrp = *lrp; | 1421 | *rrp = *lrp; |
1422 | xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); | 1422 | xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); |
1423 | key.ir_startino = rrp->ir_startino; /* INT_: direct copy */ | 1423 | key.ir_startino = rrp->ir_startino; |
1424 | rkp = &key; | 1424 | rkp = &key; |
1425 | } | 1425 | } |
1426 | /* | 1426 | /* |
@@ -1559,7 +1559,7 @@ xfs_inobt_split( | |||
1559 | rrp = XFS_INOBT_REC_ADDR(right, 1, cur); | 1559 | rrp = XFS_INOBT_REC_ADDR(right, 1, cur); |
1560 | memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); | 1560 | memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); |
1561 | xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); | 1561 | xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); |
1562 | keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */ | 1562 | keyp->ir_startino = rrp->ir_startino; |
1563 | } | 1563 | } |
1564 | /* | 1564 | /* |
1565 | * Find the left block number by looking in the buffer. | 1565 | * Find the left block number by looking in the buffer. |
@@ -1813,9 +1813,9 @@ xfs_inobt_get_rec( | |||
1813 | * Point to the record and extract its data. | 1813 | * Point to the record and extract its data. |
1814 | */ | 1814 | */ |
1815 | rec = XFS_INOBT_REC_ADDR(block, ptr, cur); | 1815 | rec = XFS_INOBT_REC_ADDR(block, ptr, cur); |
1816 | *ino = INT_GET(rec->ir_startino, ARCH_CONVERT); | 1816 | *ino = be32_to_cpu(rec->ir_startino); |
1817 | *fcnt = INT_GET(rec->ir_freecount, ARCH_CONVERT); | 1817 | *fcnt = be32_to_cpu(rec->ir_freecount); |
1818 | *free = INT_GET(rec->ir_free, ARCH_CONVERT); | 1818 | *free = be64_to_cpu(rec->ir_free); |
1819 | *stat = 1; | 1819 | *stat = 1; |
1820 | return 0; | 1820 | return 0; |
1821 | } | 1821 | } |
@@ -1930,10 +1930,10 @@ xfs_inobt_insert( | |||
1930 | 1930 | ||
1931 | level = 0; | 1931 | level = 0; |
1932 | nbno = NULLAGBLOCK; | 1932 | nbno = NULLAGBLOCK; |
1933 | INT_SET(nrec.ir_startino, ARCH_CONVERT, cur->bc_rec.i.ir_startino); | 1933 | nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino); |
1934 | INT_SET(nrec.ir_freecount, ARCH_CONVERT, cur->bc_rec.i.ir_freecount); | 1934 | nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount); |
1935 | INT_SET(nrec.ir_free, ARCH_CONVERT, cur->bc_rec.i.ir_free); | 1935 | nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free); |
1936 | ncur = (xfs_btree_cur_t *)0; | 1936 | ncur = NULL; |
1937 | pcur = cur; | 1937 | pcur = cur; |
1938 | /* | 1938 | /* |
1939 | * Loop going up the tree, starting at the leaf level. | 1939 | * Loop going up the tree, starting at the leaf level. |
@@ -1965,7 +1965,7 @@ xfs_inobt_insert( | |||
1965 | */ | 1965 | */ |
1966 | if (ncur) { | 1966 | if (ncur) { |
1967 | pcur = ncur; | 1967 | pcur = ncur; |
1968 | ncur = (xfs_btree_cur_t *)0; | 1968 | ncur = NULL; |
1969 | } | 1969 | } |
1970 | } while (nbno != NULLAGBLOCK); | 1970 | } while (nbno != NULLAGBLOCK); |
1971 | *stat = i; | 1971 | *stat = i; |
@@ -2060,9 +2060,9 @@ xfs_inobt_update( | |||
2060 | /* | 2060 | /* |
2061 | * Fill in the new contents and log them. | 2061 | * Fill in the new contents and log them. |
2062 | */ | 2062 | */ |
2063 | INT_SET(rp->ir_startino, ARCH_CONVERT, ino); | 2063 | rp->ir_startino = cpu_to_be32(ino); |
2064 | INT_SET(rp->ir_freecount, ARCH_CONVERT, fcnt); | 2064 | rp->ir_freecount = cpu_to_be32(fcnt); |
2065 | INT_SET(rp->ir_free, ARCH_CONVERT, free); | 2065 | rp->ir_free = cpu_to_be64(free); |
2066 | xfs_inobt_log_recs(cur, bp, ptr, ptr); | 2066 | xfs_inobt_log_recs(cur, bp, ptr, ptr); |
2067 | /* | 2067 | /* |
2068 | * Updating first record in leaf. Pass new key value up to our parent. | 2068 | * Updating first record in leaf. Pass new key value up to our parent. |
@@ -2070,7 +2070,7 @@ xfs_inobt_update( | |||
2070 | if (ptr == 1) { | 2070 | if (ptr == 1) { |
2071 | xfs_inobt_key_t key; /* key containing [ino] */ | 2071 | xfs_inobt_key_t key; /* key containing [ino] */ |
2072 | 2072 | ||
2073 | INT_SET(key.ir_startino, ARCH_CONVERT, ino); | 2073 | key.ir_startino = cpu_to_be32(ino); |
2074 | if ((error = xfs_inobt_updkey(cur, &key, 1))) | 2074 | if ((error = xfs_inobt_updkey(cur, &key, 1))) |
2075 | return error; | 2075 | return error; |
2076 | } | 2076 | } |
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h index ae3904cb1ee8..2c0e49893ff7 100644 --- a/fs/xfs/xfs_ialloc_btree.h +++ b/fs/xfs/xfs_ialloc_btree.h | |||
@@ -47,19 +47,24 @@ static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) | |||
47 | /* | 47 | /* |
48 | * Data record structure | 48 | * Data record structure |
49 | */ | 49 | */ |
50 | typedef struct xfs_inobt_rec | 50 | typedef struct xfs_inobt_rec { |
51 | { | 51 | __be32 ir_startino; /* starting inode number */ |
52 | __be32 ir_freecount; /* count of free inodes (set bits) */ | ||
53 | __be64 ir_free; /* free inode mask */ | ||
54 | } xfs_inobt_rec_t; | ||
55 | |||
56 | typedef struct xfs_inobt_rec_incore { | ||
52 | xfs_agino_t ir_startino; /* starting inode number */ | 57 | xfs_agino_t ir_startino; /* starting inode number */ |
53 | __int32_t ir_freecount; /* count of free inodes (set bits) */ | 58 | __int32_t ir_freecount; /* count of free inodes (set bits) */ |
54 | xfs_inofree_t ir_free; /* free inode mask */ | 59 | xfs_inofree_t ir_free; /* free inode mask */ |
55 | } xfs_inobt_rec_t; | 60 | } xfs_inobt_rec_incore_t; |
61 | |||
56 | 62 | ||
57 | /* | 63 | /* |
58 | * Key structure | 64 | * Key structure |
59 | */ | 65 | */ |
60 | typedef struct xfs_inobt_key | 66 | typedef struct xfs_inobt_key { |
61 | { | 67 | __be32 ir_startino; /* starting inode number */ |
62 | xfs_agino_t ir_startino; /* starting inode number */ | ||
63 | } xfs_inobt_key_t; | 68 | } xfs_inobt_key_t; |
64 | 69 | ||
65 | /* btree pointer type */ | 70 | /* btree pointer type */ |
@@ -77,7 +82,7 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t; | |||
77 | #define XFS_INOBT_IS_FREE(rp,i) \ | 82 | #define XFS_INOBT_IS_FREE(rp,i) \ |
78 | (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) | 83 | (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) |
79 | #define XFS_INOBT_IS_FREE_DISK(rp,i) \ | 84 | #define XFS_INOBT_IS_FREE_DISK(rp,i) \ |
80 | ((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0) | 85 | ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0) |
81 | #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) | 86 | #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) |
82 | #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) | 87 | #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) |
83 | 88 | ||
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 0724df7fabb7..b73d216ecaf9 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -50,7 +50,7 @@ void | |||
50 | xfs_ihash_init(xfs_mount_t *mp) | 50 | xfs_ihash_init(xfs_mount_t *mp) |
51 | { | 51 | { |
52 | __uint64_t icount; | 52 | __uint64_t icount; |
53 | uint i, flags = KM_SLEEP | KM_MAYFAIL; | 53 | uint i; |
54 | 54 | ||
55 | if (!mp->m_ihsize) { | 55 | if (!mp->m_ihsize) { |
56 | icount = mp->m_maxicount ? mp->m_maxicount : | 56 | icount = mp->m_maxicount ? mp->m_maxicount : |
@@ -61,14 +61,13 @@ xfs_ihash_init(xfs_mount_t *mp) | |||
61 | (64 * NBPP) / sizeof(xfs_ihash_t)); | 61 | (64 * NBPP) / sizeof(xfs_ihash_t)); |
62 | } | 62 | } |
63 | 63 | ||
64 | while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize * | 64 | mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize, |
65 | sizeof(xfs_ihash_t), flags))) { | 65 | NBPC * sizeof(xfs_ihash_t), |
66 | if ((mp->m_ihsize >>= 1) <= NBPP) | 66 | mp->m_ihsize * sizeof(xfs_ihash_t), |
67 | flags = KM_SLEEP; | 67 | KM_SLEEP | KM_MAYFAIL | KM_LARGE); |
68 | } | 68 | mp->m_ihsize /= sizeof(xfs_ihash_t); |
69 | for (i = 0; i < mp->m_ihsize; i++) { | 69 | for (i = 0; i < mp->m_ihsize; i++) |
70 | rwlock_init(&(mp->m_ihash[i].ih_lock)); | 70 | rwlock_init(&(mp->m_ihash[i].ih_lock)); |
71 | } | ||
72 | } | 71 | } |
73 | 72 | ||
74 | /* | 73 | /* |
@@ -77,7 +76,7 @@ xfs_ihash_init(xfs_mount_t *mp) | |||
77 | void | 76 | void |
78 | xfs_ihash_free(xfs_mount_t *mp) | 77 | xfs_ihash_free(xfs_mount_t *mp) |
79 | { | 78 | { |
80 | kmem_free(mp->m_ihash, mp->m_ihsize*sizeof(xfs_ihash_t)); | 79 | kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t)); |
81 | mp->m_ihash = NULL; | 80 | mp->m_ihash = NULL; |
82 | } | 81 | } |
83 | 82 | ||
@@ -95,7 +94,7 @@ xfs_chash_init(xfs_mount_t *mp) | |||
95 | mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize); | 94 | mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize); |
96 | mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize | 95 | mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize |
97 | * sizeof(xfs_chash_t), | 96 | * sizeof(xfs_chash_t), |
98 | KM_SLEEP); | 97 | KM_SLEEP | KM_LARGE); |
99 | for (i = 0; i < mp->m_chsize; i++) { | 98 | for (i = 0; i < mp->m_chsize; i++) { |
100 | spinlock_init(&mp->m_chash[i].ch_lock,"xfshash"); | 99 | spinlock_init(&mp->m_chash[i].ch_lock,"xfshash"); |
101 | } | 100 | } |
@@ -244,7 +243,9 @@ again: | |||
244 | 243 | ||
245 | XFS_STATS_INC(xs_ig_found); | 244 | XFS_STATS_INC(xs_ig_found); |
246 | 245 | ||
246 | spin_lock(&ip->i_flags_lock); | ||
247 | ip->i_flags &= ~XFS_IRECLAIMABLE; | 247 | ip->i_flags &= ~XFS_IRECLAIMABLE; |
248 | spin_unlock(&ip->i_flags_lock); | ||
248 | version = ih->ih_version; | 249 | version = ih->ih_version; |
249 | read_unlock(&ih->ih_lock); | 250 | read_unlock(&ih->ih_lock); |
250 | xfs_ihash_promote(ih, ip, version); | 251 | xfs_ihash_promote(ih, ip, version); |
@@ -290,15 +291,17 @@ again: | |||
290 | 291 | ||
291 | finish_inode: | 292 | finish_inode: |
292 | if (ip->i_d.di_mode == 0) { | 293 | if (ip->i_d.di_mode == 0) { |
293 | if (!(flags & IGET_CREATE)) | 294 | if (!(flags & XFS_IGET_CREATE)) |
294 | return ENOENT; | 295 | return ENOENT; |
295 | xfs_iocore_inode_reinit(ip); | 296 | xfs_iocore_inode_reinit(ip); |
296 | } | 297 | } |
297 | 298 | ||
298 | if (lock_flags != 0) | 299 | if (lock_flags != 0) |
299 | xfs_ilock(ip, lock_flags); | 300 | xfs_ilock(ip, lock_flags); |
300 | 301 | ||
302 | spin_lock(&ip->i_flags_lock); | ||
301 | ip->i_flags &= ~XFS_ISTALE; | 303 | ip->i_flags &= ~XFS_ISTALE; |
304 | spin_unlock(&ip->i_flags_lock); | ||
302 | 305 | ||
303 | vn_trace_exit(vp, "xfs_iget.found", | 306 | vn_trace_exit(vp, "xfs_iget.found", |
304 | (inst_t *)__return_address); | 307 | (inst_t *)__return_address); |
@@ -320,21 +323,20 @@ finish_inode: | |||
320 | * Read the disk inode attributes into a new inode structure and get | 323 | * Read the disk inode attributes into a new inode structure and get |
321 | * a new vnode for it. This should also initialize i_ino and i_mount. | 324 | * a new vnode for it. This should also initialize i_ino and i_mount. |
322 | */ | 325 | */ |
323 | error = xfs_iread(mp, tp, ino, &ip, bno); | 326 | error = xfs_iread(mp, tp, ino, &ip, bno, |
324 | if (error) { | 327 | (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0); |
328 | if (error) | ||
325 | return error; | 329 | return error; |
326 | } | ||
327 | 330 | ||
328 | vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address); | 331 | vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address); |
329 | 332 | ||
330 | xfs_inode_lock_init(ip, vp); | 333 | xfs_inode_lock_init(ip, vp); |
331 | xfs_iocore_inode_init(ip); | 334 | xfs_iocore_inode_init(ip); |
332 | 335 | ||
333 | if (lock_flags != 0) { | 336 | if (lock_flags) |
334 | xfs_ilock(ip, lock_flags); | 337 | xfs_ilock(ip, lock_flags); |
335 | } | 338 | |
336 | 339 | if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { | |
337 | if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) { | ||
338 | xfs_idestroy(ip); | 340 | xfs_idestroy(ip); |
339 | return ENOENT; | 341 | return ENOENT; |
340 | } | 342 | } |
@@ -369,7 +371,9 @@ finish_inode: | |||
369 | ih->ih_next = ip; | 371 | ih->ih_next = ip; |
370 | ip->i_udquot = ip->i_gdquot = NULL; | 372 | ip->i_udquot = ip->i_gdquot = NULL; |
371 | ih->ih_version++; | 373 | ih->ih_version++; |
374 | spin_lock(&ip->i_flags_lock); | ||
372 | ip->i_flags |= XFS_INEW; | 375 | ip->i_flags |= XFS_INEW; |
376 | spin_unlock(&ip->i_flags_lock); | ||
373 | 377 | ||
374 | write_unlock(&ih->ih_lock); | 378 | write_unlock(&ih->ih_lock); |
375 | 379 | ||
@@ -548,7 +552,7 @@ xfs_inode_lock_init( | |||
548 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number); | 552 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number); |
549 | init_waitqueue_head(&ip->i_ipin_wait); | 553 | init_waitqueue_head(&ip->i_ipin_wait); |
550 | atomic_set(&ip->i_pincount, 0); | 554 | atomic_set(&ip->i_pincount, 0); |
551 | init_sema(&ip->i_flock, 1, "xfsfino", vp->v_number); | 555 | initnsema(&ip->i_flock, 1, "xfsfino"); |
552 | } | 556 | } |
553 | 557 | ||
554 | /* | 558 | /* |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1f8ecff8553a..c27d7d495aa0 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -854,7 +854,8 @@ xfs_iread( | |||
854 | xfs_trans_t *tp, | 854 | xfs_trans_t *tp, |
855 | xfs_ino_t ino, | 855 | xfs_ino_t ino, |
856 | xfs_inode_t **ipp, | 856 | xfs_inode_t **ipp, |
857 | xfs_daddr_t bno) | 857 | xfs_daddr_t bno, |
858 | uint imap_flags) | ||
858 | { | 859 | { |
859 | xfs_buf_t *bp; | 860 | xfs_buf_t *bp; |
860 | xfs_dinode_t *dip; | 861 | xfs_dinode_t *dip; |
@@ -866,6 +867,7 @@ xfs_iread( | |||
866 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); | 867 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); |
867 | ip->i_ino = ino; | 868 | ip->i_ino = ino; |
868 | ip->i_mount = mp; | 869 | ip->i_mount = mp; |
870 | spin_lock_init(&ip->i_flags_lock); | ||
869 | 871 | ||
870 | /* | 872 | /* |
871 | * Get pointer's to the on-disk inode and the buffer containing it. | 873 | * Get pointer's to the on-disk inode and the buffer containing it. |
@@ -874,7 +876,7 @@ xfs_iread( | |||
874 | * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will | 876 | * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will |
875 | * know that this is a new incore inode. | 877 | * know that this is a new incore inode. |
876 | */ | 878 | */ |
877 | error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0); | 879 | error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags); |
878 | if (error) { | 880 | if (error) { |
879 | kmem_zone_free(xfs_inode_zone, ip); | 881 | kmem_zone_free(xfs_inode_zone, ip); |
880 | return error; | 882 | return error; |
@@ -1113,7 +1115,7 @@ xfs_ialloc( | |||
1113 | * to prevent others from looking at until we're done. | 1115 | * to prevent others from looking at until we're done. |
1114 | */ | 1116 | */ |
1115 | error = xfs_trans_iget(tp->t_mountp, tp, ino, | 1117 | error = xfs_trans_iget(tp->t_mountp, tp, ino, |
1116 | IGET_CREATE, XFS_ILOCK_EXCL, &ip); | 1118 | XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); |
1117 | if (error != 0) { | 1119 | if (error != 0) { |
1118 | return error; | 1120 | return error; |
1119 | } | 1121 | } |
@@ -2213,7 +2215,9 @@ xfs_ifree_cluster( | |||
2213 | 2215 | ||
2214 | if (ip == free_ip) { | 2216 | if (ip == free_ip) { |
2215 | if (xfs_iflock_nowait(ip)) { | 2217 | if (xfs_iflock_nowait(ip)) { |
2218 | spin_lock(&ip->i_flags_lock); | ||
2216 | ip->i_flags |= XFS_ISTALE; | 2219 | ip->i_flags |= XFS_ISTALE; |
2220 | spin_unlock(&ip->i_flags_lock); | ||
2217 | 2221 | ||
2218 | if (xfs_inode_clean(ip)) { | 2222 | if (xfs_inode_clean(ip)) { |
2219 | xfs_ifunlock(ip); | 2223 | xfs_ifunlock(ip); |
@@ -2227,7 +2231,9 @@ xfs_ifree_cluster( | |||
2227 | 2231 | ||
2228 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2232 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { |
2229 | if (xfs_iflock_nowait(ip)) { | 2233 | if (xfs_iflock_nowait(ip)) { |
2234 | spin_lock(&ip->i_flags_lock); | ||
2230 | ip->i_flags |= XFS_ISTALE; | 2235 | ip->i_flags |= XFS_ISTALE; |
2236 | spin_unlock(&ip->i_flags_lock); | ||
2231 | 2237 | ||
2232 | if (xfs_inode_clean(ip)) { | 2238 | if (xfs_inode_clean(ip)) { |
2233 | xfs_ifunlock(ip); | 2239 | xfs_ifunlock(ip); |
@@ -2257,7 +2263,9 @@ xfs_ifree_cluster( | |||
2257 | AIL_LOCK(mp,s); | 2263 | AIL_LOCK(mp,s); |
2258 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2264 | iip->ili_flush_lsn = iip->ili_item.li_lsn; |
2259 | AIL_UNLOCK(mp, s); | 2265 | AIL_UNLOCK(mp, s); |
2266 | spin_lock(&iip->ili_inode->i_flags_lock); | ||
2260 | iip->ili_inode->i_flags |= XFS_ISTALE; | 2267 | iip->ili_inode->i_flags |= XFS_ISTALE; |
2268 | spin_unlock(&iip->ili_inode->i_flags_lock); | ||
2261 | pre_flushed++; | 2269 | pre_flushed++; |
2262 | } | 2270 | } |
2263 | lip = lip->li_bio_list; | 2271 | lip = lip->li_bio_list; |
@@ -2753,19 +2761,29 @@ xfs_iunpin( | |||
2753 | * call as the inode reclaim may be blocked waiting for | 2761 | * call as the inode reclaim may be blocked waiting for |
2754 | * the inode to become unpinned. | 2762 | * the inode to become unpinned. |
2755 | */ | 2763 | */ |
2764 | struct inode *inode = NULL; | ||
2765 | |||
2766 | spin_lock(&ip->i_flags_lock); | ||
2756 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { | 2767 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { |
2757 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | 2768 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
2758 | 2769 | ||
2759 | /* make sync come back and flush this inode */ | 2770 | /* make sync come back and flush this inode */ |
2760 | if (vp) { | 2771 | if (vp) { |
2761 | struct inode *inode = vn_to_inode(vp); | 2772 | inode = vn_to_inode(vp); |
2762 | 2773 | ||
2763 | if (!(inode->i_state & | 2774 | if (!(inode->i_state & |
2764 | (I_NEW|I_FREEING|I_CLEAR))) | 2775 | (I_NEW|I_FREEING|I_CLEAR))) { |
2765 | mark_inode_dirty_sync(inode); | 2776 | inode = igrab(inode); |
2777 | if (inode) | ||
2778 | mark_inode_dirty_sync(inode); | ||
2779 | } else | ||
2780 | inode = NULL; | ||
2766 | } | 2781 | } |
2767 | } | 2782 | } |
2783 | spin_unlock(&ip->i_flags_lock); | ||
2768 | wake_up(&ip->i_ipin_wait); | 2784 | wake_up(&ip->i_ipin_wait); |
2785 | if (inode) | ||
2786 | iput(inode); | ||
2769 | } | 2787 | } |
2770 | } | 2788 | } |
2771 | 2789 | ||
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index d10b76ed1e5b..e96eb0835fe6 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -267,6 +267,7 @@ typedef struct xfs_inode { | |||
267 | sema_t i_flock; /* inode flush lock */ | 267 | sema_t i_flock; /* inode flush lock */ |
268 | atomic_t i_pincount; /* inode pin count */ | 268 | atomic_t i_pincount; /* inode pin count */ |
269 | wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ | 269 | wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ |
270 | spinlock_t i_flags_lock; /* inode i_flags lock */ | ||
270 | #ifdef HAVE_REFCACHE | 271 | #ifdef HAVE_REFCACHE |
271 | struct xfs_inode **i_refcache; /* ptr to entry in ref cache */ | 272 | struct xfs_inode **i_refcache; /* ptr to entry in ref cache */ |
272 | struct xfs_inode *i_release; /* inode to unref */ | 273 | struct xfs_inode *i_release; /* inode to unref */ |
@@ -389,11 +390,14 @@ typedef struct xfs_inode { | |||
389 | (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)) | 390 | (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)) |
390 | 391 | ||
391 | /* | 392 | /* |
392 | * xfs_iget.c prototypes. | 393 | * Flags for xfs_iget() |
393 | */ | 394 | */ |
395 | #define XFS_IGET_CREATE 0x1 | ||
396 | #define XFS_IGET_BULKSTAT 0x2 | ||
394 | 397 | ||
395 | #define IGET_CREATE 1 | 398 | /* |
396 | 399 | * xfs_iget.c prototypes. | |
400 | */ | ||
397 | void xfs_ihash_init(struct xfs_mount *); | 401 | void xfs_ihash_init(struct xfs_mount *); |
398 | void xfs_ihash_free(struct xfs_mount *); | 402 | void xfs_ihash_free(struct xfs_mount *); |
399 | void xfs_chash_init(struct xfs_mount *); | 403 | void xfs_chash_init(struct xfs_mount *); |
@@ -425,7 +429,7 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *, | |||
425 | xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, | 429 | xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, |
426 | xfs_daddr_t, uint); | 430 | xfs_daddr_t, uint); |
427 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 431 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
428 | xfs_inode_t **, xfs_daddr_t); | 432 | xfs_inode_t **, xfs_daddr_t, uint); |
429 | int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); | 433 | int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); |
430 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, | 434 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, |
431 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, | 435 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index f8e80d8e7237..a7a92251eb56 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -743,21 +743,6 @@ xfs_inode_item_committed( | |||
743 | } | 743 | } |
744 | 744 | ||
745 | /* | 745 | /* |
746 | * The transaction with the inode locked has aborted. The inode | ||
747 | * must not be dirty within the transaction (unless we're forcibly | ||
748 | * shutting down). We simply unlock just as if the transaction | ||
749 | * had been cancelled. | ||
750 | */ | ||
751 | STATIC void | ||
752 | xfs_inode_item_abort( | ||
753 | xfs_inode_log_item_t *iip) | ||
754 | { | ||
755 | xfs_inode_item_unlock(iip); | ||
756 | return; | ||
757 | } | ||
758 | |||
759 | |||
760 | /* | ||
761 | * This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK | 746 | * This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK |
762 | * failed to get the inode flush lock but did get the inode locked SHARED. | 747 | * failed to get the inode flush lock but did get the inode locked SHARED. |
763 | * Here we're trying to see if the inode buffer is incore, and if so whether it's | 748 | * Here we're trying to see if the inode buffer is incore, and if so whether it's |
@@ -915,7 +900,6 @@ STATIC struct xfs_item_ops xfs_inode_item_ops = { | |||
915 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) | 900 | .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) |
916 | xfs_inode_item_committed, | 901 | xfs_inode_item_committed, |
917 | .iop_push = (void(*)(xfs_log_item_t*))xfs_inode_item_push, | 902 | .iop_push = (void(*)(xfs_log_item_t*))xfs_inode_item_push, |
918 | .iop_abort = (void(*)(xfs_log_item_t*))xfs_inode_item_abort, | ||
919 | .iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf, | 903 | .iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf, |
920 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) | 904 | .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) |
921 | xfs_inode_item_committing | 905 | xfs_inode_item_committing |
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 5db6cd1b4cf3..bfe92ea17952 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h | |||
@@ -25,52 +25,54 @@ | |||
25 | * must be added on to the end. | 25 | * must be added on to the end. |
26 | */ | 26 | */ |
27 | typedef struct xfs_inode_log_format { | 27 | typedef struct xfs_inode_log_format { |
28 | unsigned short ilf_type; /* inode log item type */ | 28 | __uint16_t ilf_type; /* inode log item type */ |
29 | unsigned short ilf_size; /* size of this item */ | 29 | __uint16_t ilf_size; /* size of this item */ |
30 | uint ilf_fields; /* flags for fields logged */ | 30 | __uint32_t ilf_fields; /* flags for fields logged */ |
31 | ushort ilf_asize; /* size of attr d/ext/root */ | 31 | __uint16_t ilf_asize; /* size of attr d/ext/root */ |
32 | ushort ilf_dsize; /* size of data/ext/root */ | 32 | __uint16_t ilf_dsize; /* size of data/ext/root */ |
33 | xfs_ino_t ilf_ino; /* inode number */ | 33 | __uint64_t ilf_ino; /* inode number */ |
34 | union { | 34 | union { |
35 | xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/ | 35 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ |
36 | uuid_t ilfu_uuid; /* mount point value */ | 36 | uuid_t ilfu_uuid; /* mount point value */ |
37 | } ilf_u; | 37 | } ilf_u; |
38 | __int64_t ilf_blkno; /* blkno of inode buffer */ | 38 | __int64_t ilf_blkno; /* blkno of inode buffer */ |
39 | int ilf_len; /* len of inode buffer */ | 39 | __int32_t ilf_len; /* len of inode buffer */ |
40 | int ilf_boffset; /* off of inode in buffer */ | 40 | __int32_t ilf_boffset; /* off of inode in buffer */ |
41 | } xfs_inode_log_format_t; | 41 | } xfs_inode_log_format_t; |
42 | 42 | ||
43 | #ifndef HAVE_FORMAT32 | ||
43 | typedef struct xfs_inode_log_format_32 { | 44 | typedef struct xfs_inode_log_format_32 { |
44 | unsigned short ilf_type; /* 16: inode log item type */ | 45 | __uint16_t ilf_type; /* inode log item type */ |
45 | unsigned short ilf_size; /* 16: size of this item */ | 46 | __uint16_t ilf_size; /* size of this item */ |
46 | uint ilf_fields; /* 32: flags for fields logged */ | 47 | __uint32_t ilf_fields; /* flags for fields logged */ |
47 | ushort ilf_asize; /* 32: size of attr d/ext/root */ | 48 | __uint16_t ilf_asize; /* size of attr d/ext/root */ |
48 | ushort ilf_dsize; /* 32: size of data/ext/root */ | 49 | __uint16_t ilf_dsize; /* size of data/ext/root */ |
49 | xfs_ino_t ilf_ino; /* 64: inode number */ | 50 | __uint64_t ilf_ino; /* inode number */ |
50 | union { | 51 | union { |
51 | xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/ | 52 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ |
52 | uuid_t ilfu_uuid; /* 128: mount point value */ | 53 | uuid_t ilfu_uuid; /* mount point value */ |
53 | } ilf_u; | 54 | } ilf_u; |
54 | __int64_t ilf_blkno; /* 64: blkno of inode buffer */ | 55 | __int64_t ilf_blkno; /* blkno of inode buffer */ |
55 | int ilf_len; /* 32: len of inode buffer */ | 56 | __int32_t ilf_len; /* len of inode buffer */ |
56 | int ilf_boffset; /* 32: off of inode in buffer */ | 57 | __int32_t ilf_boffset; /* off of inode in buffer */ |
57 | } __attribute__((packed)) xfs_inode_log_format_32_t; | 58 | } __attribute__((packed)) xfs_inode_log_format_32_t; |
59 | #endif | ||
58 | 60 | ||
59 | typedef struct xfs_inode_log_format_64 { | 61 | typedef struct xfs_inode_log_format_64 { |
60 | unsigned short ilf_type; /* 16: inode log item type */ | 62 | __uint16_t ilf_type; /* inode log item type */ |
61 | unsigned short ilf_size; /* 16: size of this item */ | 63 | __uint16_t ilf_size; /* size of this item */ |
62 | uint ilf_fields; /* 32: flags for fields logged */ | 64 | __uint32_t ilf_fields; /* flags for fields logged */ |
63 | ushort ilf_asize; /* 32: size of attr d/ext/root */ | 65 | __uint16_t ilf_asize; /* size of attr d/ext/root */ |
64 | ushort ilf_dsize; /* 32: size of data/ext/root */ | 66 | __uint16_t ilf_dsize; /* size of data/ext/root */ |
65 | __uint32_t ilf_pad; /* 32: pad for 64 bit boundary */ | 67 | __uint32_t ilf_pad; /* pad for 64 bit boundary */ |
66 | xfs_ino_t ilf_ino; /* 64: inode number */ | 68 | __uint64_t ilf_ino; /* inode number */ |
67 | union { | 69 | union { |
68 | xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/ | 70 | __uint32_t ilfu_rdev; /* rdev value for dev inode*/ |
69 | uuid_t ilfu_uuid; /* 128: mount point value */ | 71 | uuid_t ilfu_uuid; /* mount point value */ |
70 | } ilf_u; | 72 | } ilf_u; |
71 | __int64_t ilf_blkno; /* 64: blkno of inode buffer */ | 73 | __int64_t ilf_blkno; /* blkno of inode buffer */ |
72 | int ilf_len; /* 32: len of inode buffer */ | 74 | __int32_t ilf_len; /* len of inode buffer */ |
73 | int ilf_boffset; /* 32: off of inode in buffer */ | 75 | __int32_t ilf_boffset; /* off of inode in buffer */ |
74 | } xfs_inode_log_format_64_t; | 76 | } xfs_inode_log_format_64_t; |
75 | 77 | ||
76 | /* | 78 | /* |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index f1949c16df15..19655124da78 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -398,6 +398,23 @@ xfs_flush_space( | |||
398 | return 1; | 398 | return 1; |
399 | } | 399 | } |
400 | 400 | ||
401 | STATIC int | ||
402 | xfs_cmn_err_fsblock_zero( | ||
403 | xfs_inode_t *ip, | ||
404 | xfs_bmbt_irec_t *imap) | ||
405 | { | ||
406 | xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, | ||
407 | "Access to block zero in inode %llu " | ||
408 | "start_block: %llx start_off: %llx " | ||
409 | "blkcnt: %llx extent-state: %x\n", | ||
410 | (unsigned long long)ip->i_ino, | ||
411 | (unsigned long long)imap->br_startblock, | ||
412 | (unsigned long long)imap->br_startoff, | ||
413 | (unsigned long long)imap->br_blockcount, | ||
414 | imap->br_state); | ||
415 | return EFSCORRUPTED; | ||
416 | } | ||
417 | |||
401 | int | 418 | int |
402 | xfs_iomap_write_direct( | 419 | xfs_iomap_write_direct( |
403 | xfs_inode_t *ip, | 420 | xfs_inode_t *ip, |
@@ -536,23 +553,17 @@ xfs_iomap_write_direct( | |||
536 | * Copy any maps to caller's array and return any error. | 553 | * Copy any maps to caller's array and return any error. |
537 | */ | 554 | */ |
538 | if (nimaps == 0) { | 555 | if (nimaps == 0) { |
539 | error = (ENOSPC); | 556 | error = ENOSPC; |
557 | goto error_out; | ||
558 | } | ||
559 | |||
560 | if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) { | ||
561 | error = xfs_cmn_err_fsblock_zero(ip, &imap); | ||
540 | goto error_out; | 562 | goto error_out; |
541 | } | 563 | } |
542 | 564 | ||
543 | *ret_imap = imap; | 565 | *ret_imap = imap; |
544 | *nmaps = 1; | 566 | *nmaps = 1; |
545 | if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { | ||
546 | cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld " | ||
547 | "start_block : %llx start_off : %llx blkcnt : %llx " | ||
548 | "extent-state : %x \n", | ||
549 | (ip->i_mount)->m_fsname, | ||
550 | (long long)ip->i_ino, | ||
551 | (unsigned long long)ret_imap->br_startblock, | ||
552 | (unsigned long long)ret_imap->br_startoff, | ||
553 | (unsigned long long)ret_imap->br_blockcount, | ||
554 | ret_imap->br_state); | ||
555 | } | ||
556 | return 0; | 567 | return 0; |
557 | 568 | ||
558 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ | 569 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ |
@@ -715,17 +726,8 @@ retry: | |||
715 | goto retry; | 726 | goto retry; |
716 | } | 727 | } |
717 | 728 | ||
718 | if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) { | 729 | if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT))) |
719 | cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld " | 730 | return xfs_cmn_err_fsblock_zero(ip, &imap[0]); |
720 | "start_block : %llx start_off : %llx blkcnt : %llx " | ||
721 | "extent-state : %x \n", | ||
722 | (ip->i_mount)->m_fsname, | ||
723 | (long long)ip->i_ino, | ||
724 | (unsigned long long)ret_imap->br_startblock, | ||
725 | (unsigned long long)ret_imap->br_startoff, | ||
726 | (unsigned long long)ret_imap->br_blockcount, | ||
727 | ret_imap->br_state); | ||
728 | } | ||
729 | 731 | ||
730 | *ret_imap = imap[0]; | 732 | *ret_imap = imap[0]; |
731 | *nmaps = 1; | 733 | *nmaps = 1; |
@@ -853,24 +855,10 @@ xfs_iomap_write_allocate( | |||
853 | * See if we were able to allocate an extent that | 855 | * See if we were able to allocate an extent that |
854 | * covers at least part of the callers request | 856 | * covers at least part of the callers request |
855 | */ | 857 | */ |
856 | |||
857 | for (i = 0; i < nimaps; i++) { | 858 | for (i = 0; i < nimaps; i++) { |
858 | if (!(io->io_flags & XFS_IOCORE_RT) && | 859 | if (unlikely(!imap[i].br_startblock && |
859 | !imap[i].br_startblock) { | 860 | !(io->io_flags & XFS_IOCORE_RT))) |
860 | cmn_err(CE_PANIC,"Access to block zero: " | 861 | return xfs_cmn_err_fsblock_zero(ip, &imap[i]); |
861 | "fs <%s> inode: %lld " | ||
862 | "start_block : %llx start_off : %llx " | ||
863 | "blkcnt : %llx extent-state : %x \n", | ||
864 | (ip->i_mount)->m_fsname, | ||
865 | (long long)ip->i_ino, | ||
866 | (unsigned long long) | ||
867 | imap[i].br_startblock, | ||
868 | (unsigned long long) | ||
869 | imap[i].br_startoff, | ||
870 | (unsigned long long) | ||
871 | imap[i].br_blockcount, | ||
872 | imap[i].br_state); | ||
873 | } | ||
874 | if ((offset_fsb >= imap[i].br_startoff) && | 862 | if ((offset_fsb >= imap[i].br_startoff) && |
875 | (offset_fsb < (imap[i].br_startoff + | 863 | (offset_fsb < (imap[i].br_startoff + |
876 | imap[i].br_blockcount))) { | 864 | imap[i].br_blockcount))) { |
@@ -941,7 +929,7 @@ xfs_iomap_write_unwritten( | |||
941 | XFS_WRITE_LOG_COUNT); | 929 | XFS_WRITE_LOG_COUNT); |
942 | if (error) { | 930 | if (error) { |
943 | xfs_trans_cancel(tp, 0); | 931 | xfs_trans_cancel(tp, 0); |
944 | goto error0; | 932 | return XFS_ERROR(error); |
945 | } | 933 | } |
946 | 934 | ||
947 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 935 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
@@ -967,19 +955,11 @@ xfs_iomap_write_unwritten( | |||
967 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); | 955 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); |
968 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 956 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
969 | if (error) | 957 | if (error) |
970 | goto error0; | 958 | return XFS_ERROR(error); |
971 | 959 | ||
972 | if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) { | 960 | if (unlikely(!imap.br_startblock && |
973 | cmn_err(CE_PANIC,"Access to block zero: fs <%s> " | 961 | !(io->io_flags & XFS_IOCORE_RT))) |
974 | "inode: %lld start_block : %llx start_off : " | 962 | return xfs_cmn_err_fsblock_zero(ip, &imap); |
975 | "%llx blkcnt : %llx extent-state : %x \n", | ||
976 | (ip->i_mount)->m_fsname, | ||
977 | (long long)ip->i_ino, | ||
978 | (unsigned long long)imap.br_startblock, | ||
979 | (unsigned long long)imap.br_startoff, | ||
980 | (unsigned long long)imap.br_blockcount, | ||
981 | imap.br_state); | ||
982 | } | ||
983 | 963 | ||
984 | if ((numblks_fsb = imap.br_blockcount) == 0) { | 964 | if ((numblks_fsb = imap.br_blockcount) == 0) { |
985 | /* | 965 | /* |
@@ -999,6 +979,5 @@ error_on_bmapi_transaction: | |||
999 | xfs_bmap_cancel(&free_list); | 979 | xfs_bmap_cancel(&free_list); |
1000 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); | 980 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); |
1001 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 981 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
1002 | error0: | ||
1003 | return XFS_ERROR(error); | 982 | return XFS_ERROR(error); |
1004 | } | 983 | } |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 46249e4d1fea..7775ddc0b3c6 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -39,6 +39,16 @@ | |||
39 | #include "xfs_error.h" | 39 | #include "xfs_error.h" |
40 | #include "xfs_btree.h" | 40 | #include "xfs_btree.h" |
41 | 41 | ||
42 | int | ||
43 | xfs_internal_inum( | ||
44 | xfs_mount_t *mp, | ||
45 | xfs_ino_t ino) | ||
46 | { | ||
47 | return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || | ||
48 | (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | ||
49 | (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); | ||
50 | } | ||
51 | |||
42 | STATIC int | 52 | STATIC int |
43 | xfs_bulkstat_one_iget( | 53 | xfs_bulkstat_one_iget( |
44 | xfs_mount_t *mp, /* mount point for filesystem */ | 54 | xfs_mount_t *mp, /* mount point for filesystem */ |
@@ -52,7 +62,8 @@ xfs_bulkstat_one_iget( | |||
52 | bhv_vnode_t *vp; | 62 | bhv_vnode_t *vp; |
53 | int error; | 63 | int error; |
54 | 64 | ||
55 | error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); | 65 | error = xfs_iget(mp, NULL, ino, |
66 | XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno); | ||
56 | if (error) { | 67 | if (error) { |
57 | *stat = BULKSTAT_RV_NOTHING; | 68 | *stat = BULKSTAT_RV_NOTHING; |
58 | return error; | 69 | return error; |
@@ -212,17 +223,12 @@ xfs_bulkstat_one( | |||
212 | xfs_dinode_t *dip; /* dinode inode pointer */ | 223 | xfs_dinode_t *dip; /* dinode inode pointer */ |
213 | 224 | ||
214 | dip = (xfs_dinode_t *)dibuff; | 225 | dip = (xfs_dinode_t *)dibuff; |
226 | *stat = BULKSTAT_RV_NOTHING; | ||
215 | 227 | ||
216 | if (!buffer || ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || | 228 | if (!buffer || xfs_internal_inum(mp, ino)) |
217 | (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | ||
218 | (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))) { | ||
219 | *stat = BULKSTAT_RV_NOTHING; | ||
220 | return XFS_ERROR(EINVAL); | 229 | return XFS_ERROR(EINVAL); |
221 | } | 230 | if (ubsize < sizeof(*buf)) |
222 | if (ubsize < sizeof(*buf)) { | ||
223 | *stat = BULKSTAT_RV_NOTHING; | ||
224 | return XFS_ERROR(ENOMEM); | 231 | return XFS_ERROR(ENOMEM); |
225 | } | ||
226 | 232 | ||
227 | buf = kmem_alloc(sizeof(*buf), KM_SLEEP); | 233 | buf = kmem_alloc(sizeof(*buf), KM_SLEEP); |
228 | 234 | ||
@@ -238,8 +244,7 @@ xfs_bulkstat_one( | |||
238 | } | 244 | } |
239 | 245 | ||
240 | if (copy_to_user(buffer, buf, sizeof(*buf))) { | 246 | if (copy_to_user(buffer, buf, sizeof(*buf))) { |
241 | *stat = BULKSTAT_RV_NOTHING; | 247 | error = EFAULT; |
242 | error = EFAULT; | ||
243 | goto out_free; | 248 | goto out_free; |
244 | } | 249 | } |
245 | 250 | ||
@@ -253,6 +258,46 @@ xfs_bulkstat_one( | |||
253 | } | 258 | } |
254 | 259 | ||
255 | /* | 260 | /* |
261 | * Test to see whether we can use the ondisk inode directly, based | ||
262 | * on the given bulkstat flags, filling in dipp accordingly. | ||
263 | * Returns zero if the inode is dodgey. | ||
264 | */ | ||
265 | STATIC int | ||
266 | xfs_bulkstat_use_dinode( | ||
267 | xfs_mount_t *mp, | ||
268 | int flags, | ||
269 | xfs_buf_t *bp, | ||
270 | int clustidx, | ||
271 | xfs_dinode_t **dipp) | ||
272 | { | ||
273 | xfs_dinode_t *dip; | ||
274 | unsigned int aformat; | ||
275 | |||
276 | *dipp = NULL; | ||
277 | if (!bp || (flags & BULKSTAT_FG_IGET)) | ||
278 | return 1; | ||
279 | dip = (xfs_dinode_t *) | ||
280 | xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); | ||
281 | if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC || | ||
282 | !XFS_DINODE_GOOD_VERSION( | ||
283 | INT_GET(dip->di_core.di_version, ARCH_CONVERT))) | ||
284 | return 0; | ||
285 | if (flags & BULKSTAT_FG_QUICK) { | ||
286 | *dipp = dip; | ||
287 | return 1; | ||
288 | } | ||
289 | /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ | ||
290 | aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT); | ||
291 | if ((XFS_CFORK_Q(&dip->di_core) == 0) || | ||
292 | (aformat == XFS_DINODE_FMT_LOCAL) || | ||
293 | (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { | ||
294 | *dipp = dip; | ||
295 | return 1; | ||
296 | } | ||
297 | return 1; | ||
298 | } | ||
299 | |||
300 | /* | ||
256 | * Return stat information in bulk (by-inode) for the filesystem. | 301 | * Return stat information in bulk (by-inode) for the filesystem. |
257 | */ | 302 | */ |
258 | int /* error status */ | 303 | int /* error status */ |
@@ -284,10 +329,11 @@ xfs_bulkstat( | |||
284 | xfs_agino_t gino; /* current btree rec's start inode */ | 329 | xfs_agino_t gino; /* current btree rec's start inode */ |
285 | int i; /* loop index */ | 330 | int i; /* loop index */ |
286 | int icount; /* count of inodes good in irbuf */ | 331 | int icount; /* count of inodes good in irbuf */ |
332 | size_t irbsize; /* size of irec buffer in bytes */ | ||
287 | xfs_ino_t ino; /* inode number (filesystem) */ | 333 | xfs_ino_t ino; /* inode number (filesystem) */ |
288 | xfs_inobt_rec_t *irbp; /* current irec buffer pointer */ | 334 | xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ |
289 | xfs_inobt_rec_t *irbuf; /* start of irec buffer */ | 335 | xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ |
290 | xfs_inobt_rec_t *irbufend; /* end of good irec buffer entries */ | 336 | xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */ |
291 | xfs_ino_t lastino=0; /* last inode number returned */ | 337 | xfs_ino_t lastino=0; /* last inode number returned */ |
292 | int nbcluster; /* # of blocks in a cluster */ | 338 | int nbcluster; /* # of blocks in a cluster */ |
293 | int nicluster; /* # of inodes in a cluster */ | 339 | int nicluster; /* # of inodes in a cluster */ |
@@ -328,13 +374,10 @@ xfs_bulkstat( | |||
328 | (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); | 374 | (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); |
329 | nimask = ~(nicluster - 1); | 375 | nimask = ~(nicluster - 1); |
330 | nbcluster = nicluster >> mp->m_sb.sb_inopblog; | 376 | nbcluster = nicluster >> mp->m_sb.sb_inopblog; |
331 | /* | 377 | irbuf = kmem_zalloc_greedy(&irbsize, NBPC, NBPC * 4, |
332 | * Allocate a page-sized buffer for inode btree records. | 378 | KM_SLEEP | KM_MAYFAIL | KM_LARGE); |
333 | * We could try allocating something smaller, but for normal | 379 | nirbuf = irbsize / sizeof(*irbuf); |
334 | * calls we'll always (potentially) need the whole page. | 380 | |
335 | */ | ||
336 | irbuf = kmem_alloc(NBPC, KM_SLEEP); | ||
337 | nirbuf = NBPC / sizeof(*irbuf); | ||
338 | /* | 381 | /* |
339 | * Loop over the allocation groups, starting from the last | 382 | * Loop over the allocation groups, starting from the last |
340 | * inode returned; 0 means start of the allocation group. | 383 | * inode returned; 0 means start of the allocation group. |
@@ -358,7 +401,7 @@ xfs_bulkstat( | |||
358 | * Allocate and initialize a btree cursor for ialloc btree. | 401 | * Allocate and initialize a btree cursor for ialloc btree. |
359 | */ | 402 | */ |
360 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO, | 403 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO, |
361 | (xfs_inode_t *)0, 0); | 404 | (xfs_inode_t *)0, 0); |
362 | irbp = irbuf; | 405 | irbp = irbuf; |
363 | irbufend = irbuf + nirbuf; | 406 | irbufend = irbuf + nirbuf; |
364 | end_of_ag = 0; | 407 | end_of_ag = 0; |
@@ -395,9 +438,9 @@ xfs_bulkstat( | |||
395 | gcnt++; | 438 | gcnt++; |
396 | } | 439 | } |
397 | gfree |= XFS_INOBT_MASKN(0, chunkidx); | 440 | gfree |= XFS_INOBT_MASKN(0, chunkidx); |
398 | INT_SET(irbp->ir_startino, ARCH_CONVERT, gino); | 441 | irbp->ir_startino = gino; |
399 | INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt); | 442 | irbp->ir_freecount = gcnt; |
400 | INT_SET(irbp->ir_free, ARCH_CONVERT, gfree); | 443 | irbp->ir_free = gfree; |
401 | irbp++; | 444 | irbp++; |
402 | agino = gino + XFS_INODES_PER_CHUNK; | 445 | agino = gino + XFS_INODES_PER_CHUNK; |
403 | icount = XFS_INODES_PER_CHUNK - gcnt; | 446 | icount = XFS_INODES_PER_CHUNK - gcnt; |
@@ -451,11 +494,27 @@ xfs_bulkstat( | |||
451 | } | 494 | } |
452 | /* | 495 | /* |
453 | * If this chunk has any allocated inodes, save it. | 496 | * If this chunk has any allocated inodes, save it. |
497 | * Also start read-ahead now for this chunk. | ||
454 | */ | 498 | */ |
455 | if (gcnt < XFS_INODES_PER_CHUNK) { | 499 | if (gcnt < XFS_INODES_PER_CHUNK) { |
456 | INT_SET(irbp->ir_startino, ARCH_CONVERT, gino); | 500 | /* |
457 | INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt); | 501 | * Loop over all clusters in the next chunk. |
458 | INT_SET(irbp->ir_free, ARCH_CONVERT, gfree); | 502 | * Do a readahead if there are any allocated |
503 | * inodes in that cluster. | ||
504 | */ | ||
505 | for (agbno = XFS_AGINO_TO_AGBNO(mp, gino), | ||
506 | chunkidx = 0; | ||
507 | chunkidx < XFS_INODES_PER_CHUNK; | ||
508 | chunkidx += nicluster, | ||
509 | agbno += nbcluster) { | ||
510 | if (XFS_INOBT_MASKN(chunkidx, | ||
511 | nicluster) & ~gfree) | ||
512 | xfs_btree_reada_bufs(mp, agno, | ||
513 | agbno, nbcluster); | ||
514 | } | ||
515 | irbp->ir_startino = gino; | ||
516 | irbp->ir_freecount = gcnt; | ||
517 | irbp->ir_free = gfree; | ||
459 | irbp++; | 518 | irbp++; |
460 | icount += XFS_INODES_PER_CHUNK - gcnt; | 519 | icount += XFS_INODES_PER_CHUNK - gcnt; |
461 | } | 520 | } |
@@ -479,33 +538,11 @@ xfs_bulkstat( | |||
479 | for (irbp = irbuf; | 538 | for (irbp = irbuf; |
480 | irbp < irbufend && ubleft >= statstruct_size; irbp++) { | 539 | irbp < irbufend && ubleft >= statstruct_size; irbp++) { |
481 | /* | 540 | /* |
482 | * Read-ahead the next chunk's worth of inodes. | ||
483 | */ | ||
484 | if (&irbp[1] < irbufend) { | ||
485 | /* | ||
486 | * Loop over all clusters in the next chunk. | ||
487 | * Do a readahead if there are any allocated | ||
488 | * inodes in that cluster. | ||
489 | */ | ||
490 | for (agbno = XFS_AGINO_TO_AGBNO(mp, | ||
491 | INT_GET(irbp[1].ir_startino, ARCH_CONVERT)), | ||
492 | chunkidx = 0; | ||
493 | chunkidx < XFS_INODES_PER_CHUNK; | ||
494 | chunkidx += nicluster, | ||
495 | agbno += nbcluster) { | ||
496 | if (XFS_INOBT_MASKN(chunkidx, | ||
497 | nicluster) & | ||
498 | ~(INT_GET(irbp[1].ir_free, ARCH_CONVERT))) | ||
499 | xfs_btree_reada_bufs(mp, agno, | ||
500 | agbno, nbcluster); | ||
501 | } | ||
502 | } | ||
503 | /* | ||
504 | * Now process this chunk of inodes. | 541 | * Now process this chunk of inodes. |
505 | */ | 542 | */ |
506 | for (agino = INT_GET(irbp->ir_startino, ARCH_CONVERT), chunkidx = 0, clustidx = 0; | 543 | for (agino = irbp->ir_startino, chunkidx = clustidx = 0; |
507 | ubleft > 0 && | 544 | ubleft > 0 && |
508 | INT_GET(irbp->ir_freecount, ARCH_CONVERT) < XFS_INODES_PER_CHUNK; | 545 | irbp->ir_freecount < XFS_INODES_PER_CHUNK; |
509 | chunkidx++, clustidx++, agino++) { | 546 | chunkidx++, clustidx++, agino++) { |
510 | ASSERT(chunkidx < XFS_INODES_PER_CHUNK); | 547 | ASSERT(chunkidx < XFS_INODES_PER_CHUNK); |
511 | /* | 548 | /* |
@@ -525,11 +562,12 @@ xfs_bulkstat( | |||
525 | */ | 562 | */ |
526 | if ((chunkidx & (nicluster - 1)) == 0) { | 563 | if ((chunkidx & (nicluster - 1)) == 0) { |
527 | agbno = XFS_AGINO_TO_AGBNO(mp, | 564 | agbno = XFS_AGINO_TO_AGBNO(mp, |
528 | INT_GET(irbp->ir_startino, ARCH_CONVERT)) + | 565 | irbp->ir_startino) + |
529 | ((chunkidx & nimask) >> | 566 | ((chunkidx & nimask) >> |
530 | mp->m_sb.sb_inopblog); | 567 | mp->m_sb.sb_inopblog); |
531 | 568 | ||
532 | if (flags & BULKSTAT_FG_QUICK) { | 569 | if (flags & (BULKSTAT_FG_QUICK | |
570 | BULKSTAT_FG_INLINE)) { | ||
533 | ino = XFS_AGINO_TO_INO(mp, agno, | 571 | ino = XFS_AGINO_TO_INO(mp, agno, |
534 | agino); | 572 | agino); |
535 | bno = XFS_AGB_TO_DADDR(mp, agno, | 573 | bno = XFS_AGB_TO_DADDR(mp, agno, |
@@ -543,6 +581,7 @@ xfs_bulkstat( | |||
543 | KM_SLEEP); | 581 | KM_SLEEP); |
544 | ip->i_ino = ino; | 582 | ip->i_ino = ino; |
545 | ip->i_mount = mp; | 583 | ip->i_mount = mp; |
584 | spin_lock_init(&ip->i_flags_lock); | ||
546 | if (bp) | 585 | if (bp) |
547 | xfs_buf_relse(bp); | 586 | xfs_buf_relse(bp); |
548 | error = xfs_itobp(mp, NULL, ip, | 587 | error = xfs_itobp(mp, NULL, ip, |
@@ -564,30 +603,34 @@ xfs_bulkstat( | |||
564 | /* | 603 | /* |
565 | * Skip if this inode is free. | 604 | * Skip if this inode is free. |
566 | */ | 605 | */ |
567 | if (XFS_INOBT_MASK(chunkidx) & INT_GET(irbp->ir_free, ARCH_CONVERT)) | 606 | if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) |
568 | continue; | 607 | continue; |
569 | /* | 608 | /* |
570 | * Count used inodes as free so we can tell | 609 | * Count used inodes as free so we can tell |
571 | * when the chunk is used up. | 610 | * when the chunk is used up. |
572 | */ | 611 | */ |
573 | INT_MOD(irbp->ir_freecount, ARCH_CONVERT, +1); | 612 | irbp->ir_freecount++; |
574 | ino = XFS_AGINO_TO_INO(mp, agno, agino); | 613 | ino = XFS_AGINO_TO_INO(mp, agno, agino); |
575 | bno = XFS_AGB_TO_DADDR(mp, agno, agbno); | 614 | bno = XFS_AGB_TO_DADDR(mp, agno, agbno); |
576 | if (flags & BULKSTAT_FG_QUICK) { | 615 | if (!xfs_bulkstat_use_dinode(mp, flags, bp, |
577 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, | 616 | clustidx, &dip)) |
578 | (clustidx << mp->m_sb.sb_inodelog)); | 617 | continue; |
579 | 618 | /* | |
580 | if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) | 619 | * If we need to do an iget, cannot hold bp. |
581 | != XFS_DINODE_MAGIC | 620 | * Drop it, until starting the next cluster. |
582 | || !XFS_DINODE_GOOD_VERSION( | 621 | */ |
583 | INT_GET(dip->di_core.di_version, ARCH_CONVERT))) | 622 | if ((flags & BULKSTAT_FG_INLINE) && !dip) { |
584 | continue; | 623 | if (bp) |
624 | xfs_buf_relse(bp); | ||
625 | bp = NULL; | ||
585 | } | 626 | } |
586 | 627 | ||
587 | /* | 628 | /* |
588 | * Get the inode and fill in a single buffer. | 629 | * Get the inode and fill in a single buffer. |
589 | * BULKSTAT_FG_QUICK uses dip to fill it in. | 630 | * BULKSTAT_FG_QUICK uses dip to fill it in. |
590 | * BULKSTAT_FG_IGET uses igets. | 631 | * BULKSTAT_FG_IGET uses igets. |
632 | * BULKSTAT_FG_INLINE uses dip if we have an | ||
633 | * inline attr fork, else igets. | ||
591 | * See: xfs_bulkstat_one & xfs_dm_bulkstat_one. | 634 | * See: xfs_bulkstat_one & xfs_dm_bulkstat_one. |
592 | * This is also used to count inodes/blks, etc | 635 | * This is also used to count inodes/blks, etc |
593 | * in xfs_qm_quotacheck. | 636 | * in xfs_qm_quotacheck. |
@@ -597,8 +640,15 @@ xfs_bulkstat( | |||
597 | ubleft, private_data, | 640 | ubleft, private_data, |
598 | bno, &ubused, dip, &fmterror); | 641 | bno, &ubused, dip, &fmterror); |
599 | if (fmterror == BULKSTAT_RV_NOTHING) { | 642 | if (fmterror == BULKSTAT_RV_NOTHING) { |
600 | if (error == ENOMEM) | 643 | if (error == EFAULT) { |
644 | ubleft = 0; | ||
645 | rval = error; | ||
646 | break; | ||
647 | } | ||
648 | else if (error == ENOMEM) | ||
601 | ubleft = 0; | 649 | ubleft = 0; |
650 | else | ||
651 | lastino = ino; | ||
602 | continue; | 652 | continue; |
603 | } | 653 | } |
604 | if (fmterror == BULKSTAT_RV_GIVEUP) { | 654 | if (fmterror == BULKSTAT_RV_GIVEUP) { |
@@ -633,7 +683,7 @@ xfs_bulkstat( | |||
633 | /* | 683 | /* |
634 | * Done, we're either out of filesystem or space to put the data. | 684 | * Done, we're either out of filesystem or space to put the data. |
635 | */ | 685 | */ |
636 | kmem_free(irbuf, NBPC); | 686 | kmem_free(irbuf, irbsize); |
637 | *ubcountp = ubelem; | 687 | *ubcountp = ubelem; |
638 | if (agno >= mp->m_sb.sb_agcount) { | 688 | if (agno >= mp->m_sb.sb_agcount) { |
639 | /* | 689 | /* |
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index be5f12e07d22..f25a28862a17 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h | |||
@@ -36,15 +36,16 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, | |||
36 | /* | 36 | /* |
37 | * Values for stat return value. | 37 | * Values for stat return value. |
38 | */ | 38 | */ |
39 | #define BULKSTAT_RV_NOTHING 0 | 39 | #define BULKSTAT_RV_NOTHING 0 |
40 | #define BULKSTAT_RV_DIDONE 1 | 40 | #define BULKSTAT_RV_DIDONE 1 |
41 | #define BULKSTAT_RV_GIVEUP 2 | 41 | #define BULKSTAT_RV_GIVEUP 2 |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Values for bulkstat flag argument. | 44 | * Values for bulkstat flag argument. |
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_INLINE 0x4 /* No iget if inline attrs */ | ||
48 | 49 | ||
49 | /* | 50 | /* |
50 | * Return stat information in bulk (by-inode) for the filesystem. | 51 | * Return stat information in bulk (by-inode) for the filesystem. |
@@ -80,6 +81,11 @@ xfs_bulkstat_one( | |||
80 | void *dibuff, | 81 | void *dibuff, |
81 | int *stat); | 82 | int *stat); |
82 | 83 | ||
84 | int | ||
85 | xfs_internal_inum( | ||
86 | xfs_mount_t *mp, | ||
87 | xfs_ino_t ino); | ||
88 | |||
83 | int /* error status */ | 89 | int /* error status */ |
84 | xfs_inumbers( | 90 | xfs_inumbers( |
85 | xfs_mount_t *mp, /* mount point for filesystem */ | 91 | xfs_mount_t *mp, /* mount point for filesystem */ |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 21ac1a67e3e0..c48bf61f17bd 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -617,7 +617,8 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
617 | reg[0].i_len = sizeof(magic); | 617 | reg[0].i_len = sizeof(magic); |
618 | XLOG_VEC_SET_TYPE(®[0], XLOG_REG_TYPE_UNMOUNT); | 618 | XLOG_VEC_SET_TYPE(®[0], XLOG_REG_TYPE_UNMOUNT); |
619 | 619 | ||
620 | error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0); | 620 | error = xfs_log_reserve(mp, 600, 1, &tic, |
621 | XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE); | ||
621 | if (!error) { | 622 | if (!error) { |
622 | /* remove inited flag */ | 623 | /* remove inited flag */ |
623 | ((xlog_ticket_t *)tic)->t_flags = 0; | 624 | ((xlog_ticket_t *)tic)->t_flags = 0; |
@@ -655,8 +656,11 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
655 | } else { | 656 | } else { |
656 | LOG_UNLOCK(log, s); | 657 | LOG_UNLOCK(log, s); |
657 | } | 658 | } |
658 | if (tic) | 659 | if (tic) { |
660 | xlog_trace_loggrant(log, tic, "unmount rec"); | ||
661 | xlog_ungrant_log_space(log, tic); | ||
659 | xlog_state_put_ticket(log, tic); | 662 | xlog_state_put_ticket(log, tic); |
663 | } | ||
660 | } else { | 664 | } else { |
661 | /* | 665 | /* |
662 | * We're already in forced_shutdown mode, couldn't | 666 | * We're already in forced_shutdown mode, couldn't |
@@ -1196,7 +1200,7 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1196 | kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP); | 1200 | kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP); |
1197 | iclog = *iclogp; | 1201 | iclog = *iclogp; |
1198 | iclog->hic_data = (xlog_in_core_2_t *) | 1202 | iclog->hic_data = (xlog_in_core_2_t *) |
1199 | kmem_zalloc(iclogsize, KM_SLEEP); | 1203 | kmem_zalloc(iclogsize, KM_SLEEP | KM_LARGE); |
1200 | 1204 | ||
1201 | iclog->ic_prev = prev_iclog; | 1205 | iclog->ic_prev = prev_iclog; |
1202 | prev_iclog = iclog; | 1206 | prev_iclog = iclog; |
@@ -2212,9 +2216,13 @@ xlog_state_do_callback( | |||
2212 | 2216 | ||
2213 | iclog = iclog->ic_next; | 2217 | iclog = iclog->ic_next; |
2214 | } while (first_iclog != iclog); | 2218 | } while (first_iclog != iclog); |
2215 | if (repeats && (repeats % 10) == 0) { | 2219 | |
2220 | if (repeats > 5000) { | ||
2221 | flushcnt += repeats; | ||
2222 | repeats = 0; | ||
2216 | xfs_fs_cmn_err(CE_WARN, log->l_mp, | 2223 | xfs_fs_cmn_err(CE_WARN, log->l_mp, |
2217 | "xlog_state_do_callback: looping %d", repeats); | 2224 | "%s: possible infinite loop (%d iterations)", |
2225 | __FUNCTION__, flushcnt); | ||
2218 | } | 2226 | } |
2219 | } while (!ioerrors && loopdidcallbacks); | 2227 | } while (!ioerrors && loopdidcallbacks); |
2220 | 2228 | ||
@@ -2246,6 +2254,7 @@ xlog_state_do_callback( | |||
2246 | } | 2254 | } |
2247 | #endif | 2255 | #endif |
2248 | 2256 | ||
2257 | flushcnt = 0; | ||
2249 | if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) { | 2258 | if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) { |
2250 | flushcnt = log->l_flushcnt; | 2259 | flushcnt = log->l_flushcnt; |
2251 | log->l_flushcnt = 0; | 2260 | log->l_flushcnt = 0; |
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index eacb3d4987f2..ebbe93f4f97b 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h | |||
@@ -48,16 +48,10 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) | |||
48 | */ | 48 | */ |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Flags to xfs_log_mount | ||
52 | */ | ||
53 | #define XFS_LOG_RECOVER 0x1 | ||
54 | |||
55 | /* | ||
56 | * Flags to xfs_log_done() | 51 | * Flags to xfs_log_done() |
57 | */ | 52 | */ |
58 | #define XFS_LOG_REL_PERM_RESERV 0x1 | 53 | #define XFS_LOG_REL_PERM_RESERV 0x1 |
59 | 54 | ||
60 | |||
61 | /* | 55 | /* |
62 | * Flags to xfs_log_reserve() | 56 | * Flags to xfs_log_reserve() |
63 | * | 57 | * |
@@ -70,8 +64,6 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) | |||
70 | #define XFS_LOG_SLEEP 0x0 | 64 | #define XFS_LOG_SLEEP 0x0 |
71 | #define XFS_LOG_NOSLEEP 0x1 | 65 | #define XFS_LOG_NOSLEEP 0x1 |
72 | #define XFS_LOG_PERM_RESERV 0x2 | 66 | #define XFS_LOG_PERM_RESERV 0x2 |
73 | #define XFS_LOG_RESV_ALL (XFS_LOG_NOSLEEP|XFS_LOG_PERM_RESERV) | ||
74 | |||
75 | 67 | ||
76 | /* | 68 | /* |
77 | * Flags to xfs_log_force() | 69 | * Flags to xfs_log_force() |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 34bcbf50789c..9bd3cdf11a87 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -32,7 +32,6 @@ struct xfs_mount; | |||
32 | #define XLOG_MIN_ICLOGS 2 | 32 | #define XLOG_MIN_ICLOGS 2 |
33 | #define XLOG_MED_ICLOGS 4 | 33 | #define XLOG_MED_ICLOGS 4 |
34 | #define XLOG_MAX_ICLOGS 8 | 34 | #define XLOG_MAX_ICLOGS 8 |
35 | #define XLOG_CALLBACK_SIZE 10 | ||
36 | #define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ | 35 | #define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ |
37 | #define XLOG_VERSION_1 1 | 36 | #define XLOG_VERSION_1 1 |
38 | #define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ | 37 | #define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ |
@@ -149,9 +148,6 @@ struct xfs_mount; | |||
149 | #define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */ | 148 | #define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */ |
150 | #define XLOG_END_TRANS 0x10 /* End a continued transaction */ | 149 | #define XLOG_END_TRANS 0x10 /* End a continued transaction */ |
151 | #define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */ | 150 | #define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */ |
152 | #define XLOG_SKIP_TRANS (XLOG_COMMIT_TRANS | XLOG_CONTINUE_TRANS | \ | ||
153 | XLOG_WAS_CONT_TRANS | XLOG_END_TRANS | \ | ||
154 | XLOG_UNMOUNT_TRANS) | ||
155 | 151 | ||
156 | #ifdef __KERNEL__ | 152 | #ifdef __KERNEL__ |
157 | /* | 153 | /* |
@@ -506,6 +502,12 @@ extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); | |||
506 | #define XLOG_TRACE_SLEEP_FLUSH 3 | 502 | #define XLOG_TRACE_SLEEP_FLUSH 3 |
507 | #define XLOG_TRACE_WAKE_FLUSH 4 | 503 | #define XLOG_TRACE_WAKE_FLUSH 4 |
508 | 504 | ||
505 | /* | ||
506 | * Unmount record type is used as a pseudo transaction type for the ticket. | ||
507 | * It's value must be outside the range of XFS_TRANS_* values. | ||
508 | */ | ||
509 | #define XLOG_UNMOUNT_REC_TYPE (-1U) | ||
510 | |||
509 | #endif /* __KERNEL__ */ | 511 | #endif /* __KERNEL__ */ |
510 | 512 | ||
511 | #endif /* __XFS_LOG_PRIV_H__ */ | 513 | #endif /* __XFS_LOG_PRIV_H__ */ |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index b2bd4be4200a..e5f396ff9a3d 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -331,7 +331,7 @@ typedef struct xfs_mount { | |||
331 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ | 331 | xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ |
332 | lock_t m_agirotor_lock;/* .. and lock protecting it */ | 332 | lock_t m_agirotor_lock;/* .. and lock protecting it */ |
333 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ | 333 | xfs_agnumber_t m_maxagi; /* highest inode alloc group */ |
334 | uint m_ihsize; /* size of next field */ | 334 | size_t m_ihsize; /* size of next field */ |
335 | struct xfs_ihash *m_ihash; /* fs private inode hash table*/ | 335 | struct xfs_ihash *m_ihash; /* fs private inode hash table*/ |
336 | struct xfs_inode *m_inodes; /* active inode list */ | 336 | struct xfs_inode *m_inodes; /* active inode list */ |
337 | struct list_head m_del_inodes; /* inodes to reclaim */ | 337 | struct list_head m_del_inodes; /* inodes to reclaim */ |
@@ -541,7 +541,8 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp) | |||
541 | #define XFS_VFSTOM(vfs) xfs_vfstom(vfs) | 541 | #define XFS_VFSTOM(vfs) xfs_vfstom(vfs) |
542 | static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs) | 542 | static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs) |
543 | { | 543 | { |
544 | return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); | 544 | return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs), |
545 | VFS_POSITION_XFS, VFS_POSITION_XFS)); | ||
545 | } | 546 | } |
546 | 547 | ||
547 | #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) | 548 | #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) |
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index acb853b33ebb..9dcb32aa4e2e 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h | |||
@@ -281,8 +281,6 @@ typedef struct xfs_qoff_logformat { | |||
281 | XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ | 281 | XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ |
282 | XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ | 282 | XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ |
283 | XFS_GQUOTA_ACCT) | 283 | XFS_GQUOTA_ACCT) |
284 | #define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ | ||
285 | XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE) | ||
286 | 284 | ||
287 | 285 | ||
288 | /* | 286 | /* |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 5a0b678956e0..880c73271c05 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -1948,7 +1948,7 @@ xfs_growfs_rt( | |||
1948 | */ | 1948 | */ |
1949 | nrextents = nrblocks; | 1949 | nrextents = nrblocks; |
1950 | do_div(nrextents, in->extsize); | 1950 | do_div(nrextents, in->extsize); |
1951 | nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize); | 1951 | nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize); |
1952 | nrextslog = xfs_highbit32(nrextents); | 1952 | nrextslog = xfs_highbit32(nrextents); |
1953 | nrsumlevels = nrextslog + 1; | 1953 | nrsumlevels = nrextslog + 1; |
1954 | nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks; | 1954 | nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks; |
@@ -1976,7 +1976,10 @@ xfs_growfs_rt( | |||
1976 | if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, | 1976 | if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, |
1977 | mp->m_sb.sb_rsumino))) | 1977 | mp->m_sb.sb_rsumino))) |
1978 | return error; | 1978 | return error; |
1979 | nmp = NULL; | 1979 | /* |
1980 | * Allocate a new (fake) mount/sb. | ||
1981 | */ | ||
1982 | nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP); | ||
1980 | /* | 1983 | /* |
1981 | * Loop over the bitmap blocks. | 1984 | * Loop over the bitmap blocks. |
1982 | * We will do everything one bitmap block at a time. | 1985 | * We will do everything one bitmap block at a time. |
@@ -1987,10 +1990,6 @@ xfs_growfs_rt( | |||
1987 | ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); | 1990 | ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); |
1988 | bmbno < nrbmblocks; | 1991 | bmbno < nrbmblocks; |
1989 | bmbno++) { | 1992 | bmbno++) { |
1990 | /* | ||
1991 | * Allocate a new (fake) mount/sb. | ||
1992 | */ | ||
1993 | nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP); | ||
1994 | *nmp = *mp; | 1993 | *nmp = *mp; |
1995 | nsbp = &nmp->m_sb; | 1994 | nsbp = &nmp->m_sb; |
1996 | /* | 1995 | /* |
@@ -2018,13 +2017,13 @@ xfs_growfs_rt( | |||
2018 | cancelflags = 0; | 2017 | cancelflags = 0; |
2019 | if ((error = xfs_trans_reserve(tp, 0, | 2018 | if ((error = xfs_trans_reserve(tp, 0, |
2020 | XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0))) | 2019 | XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0))) |
2021 | goto error_exit; | 2020 | break; |
2022 | /* | 2021 | /* |
2023 | * Lock out other callers by grabbing the bitmap inode lock. | 2022 | * Lock out other callers by grabbing the bitmap inode lock. |
2024 | */ | 2023 | */ |
2025 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, | 2024 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, |
2026 | XFS_ILOCK_EXCL, &ip))) | 2025 | XFS_ILOCK_EXCL, &ip))) |
2027 | goto error_exit; | 2026 | break; |
2028 | ASSERT(ip == mp->m_rbmip); | 2027 | ASSERT(ip == mp->m_rbmip); |
2029 | /* | 2028 | /* |
2030 | * Update the bitmap inode's size. | 2029 | * Update the bitmap inode's size. |
@@ -2038,7 +2037,7 @@ xfs_growfs_rt( | |||
2038 | */ | 2037 | */ |
2039 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, | 2038 | if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, |
2040 | XFS_ILOCK_EXCL, &ip))) | 2039 | XFS_ILOCK_EXCL, &ip))) |
2041 | goto error_exit; | 2040 | break; |
2042 | ASSERT(ip == mp->m_rsumip); | 2041 | ASSERT(ip == mp->m_rsumip); |
2043 | /* | 2042 | /* |
2044 | * Update the summary inode's size. | 2043 | * Update the summary inode's size. |
@@ -2053,7 +2052,7 @@ xfs_growfs_rt( | |||
2053 | mp->m_rsumlevels != nmp->m_rsumlevels) { | 2052 | mp->m_rsumlevels != nmp->m_rsumlevels) { |
2054 | error = xfs_rtcopy_summary(mp, nmp, tp); | 2053 | error = xfs_rtcopy_summary(mp, nmp, tp); |
2055 | if (error) | 2054 | if (error) |
2056 | goto error_exit; | 2055 | break; |
2057 | } | 2056 | } |
2058 | /* | 2057 | /* |
2059 | * Update superblock fields. | 2058 | * Update superblock fields. |
@@ -2080,18 +2079,13 @@ xfs_growfs_rt( | |||
2080 | error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, | 2079 | error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, |
2081 | nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); | 2080 | nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); |
2082 | if (error) | 2081 | if (error) |
2083 | goto error_exit; | 2082 | break; |
2084 | /* | 2083 | /* |
2085 | * Mark more blocks free in the superblock. | 2084 | * Mark more blocks free in the superblock. |
2086 | */ | 2085 | */ |
2087 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, | 2086 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, |
2088 | nsbp->sb_rextents - sbp->sb_rextents); | 2087 | nsbp->sb_rextents - sbp->sb_rextents); |
2089 | /* | 2088 | /* |
2090 | * Free the fake mp structure. | ||
2091 | */ | ||
2092 | kmem_free(nmp, sizeof(*nmp)); | ||
2093 | nmp = NULL; | ||
2094 | /* | ||
2095 | * Update mp values into the real mp structure. | 2089 | * Update mp values into the real mp structure. |
2096 | */ | 2090 | */ |
2097 | mp->m_rsumlevels = nrsumlevels; | 2091 | mp->m_rsumlevels = nrsumlevels; |
@@ -2101,15 +2095,15 @@ xfs_growfs_rt( | |||
2101 | */ | 2095 | */ |
2102 | xfs_trans_commit(tp, 0, NULL); | 2096 | xfs_trans_commit(tp, 0, NULL); |
2103 | } | 2097 | } |
2104 | return 0; | 2098 | |
2099 | if (error) | ||
2100 | xfs_trans_cancel(tp, cancelflags); | ||
2105 | 2101 | ||
2106 | /* | 2102 | /* |
2107 | * Error paths come here. | 2103 | * Free the fake mp structure. |
2108 | */ | 2104 | */ |
2109 | error_exit: | 2105 | kmem_free(nmp, sizeof(*nmp)); |
2110 | if (nmp) | 2106 | |
2111 | kmem_free(nmp, sizeof(*nmp)); | ||
2112 | xfs_trans_cancel(tp, cancelflags); | ||
2113 | return error; | 2107 | return error; |
2114 | } | 2108 | } |
2115 | 2109 | ||
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index bf168a91ddb8..467854b45c8f 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h | |||
@@ -60,10 +60,6 @@ struct xfs_mount; | |||
60 | XFS_SB_VERSION_LOGV2BIT | \ | 60 | XFS_SB_VERSION_LOGV2BIT | \ |
61 | XFS_SB_VERSION_SECTORBIT | \ | 61 | XFS_SB_VERSION_SECTORBIT | \ |
62 | XFS_SB_VERSION_MOREBITSBIT) | 62 | XFS_SB_VERSION_MOREBITSBIT) |
63 | #define XFS_SB_VERSION_OKSASHBITS \ | ||
64 | (XFS_SB_VERSION_NUMBITS | \ | ||
65 | XFS_SB_VERSION_REALFBITS | \ | ||
66 | XFS_SB_VERSION_OKSASHFBITS) | ||
67 | #define XFS_SB_VERSION_OKREALBITS \ | 63 | #define XFS_SB_VERSION_OKREALBITS \ |
68 | (XFS_SB_VERSION_NUMBITS | \ | 64 | (XFS_SB_VERSION_NUMBITS | \ |
69 | XFS_SB_VERSION_OKREALFBITS | \ | 65 | XFS_SB_VERSION_OKREALFBITS | \ |
@@ -81,9 +77,6 @@ struct xfs_mount; | |||
81 | #define XFS_SB_VERSION2_RESERVED2BIT 0x00000002 | 77 | #define XFS_SB_VERSION2_RESERVED2BIT 0x00000002 |
82 | #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 | 78 | #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 |
83 | #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ | 79 | #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ |
84 | #define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that | ||
85 | require changing | ||
86 | PROM and SASH */ | ||
87 | 80 | ||
88 | #define XFS_SB_VERSION2_OKREALFBITS \ | 81 | #define XFS_SB_VERSION2_OKREALFBITS \ |
89 | (XFS_SB_VERSION2_ATTR2BIT) | 82 | (XFS_SB_VERSION2_ATTR2BIT) |
@@ -238,12 +231,6 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp) | |||
238 | } | 231 | } |
239 | #endif /* __KERNEL__ */ | 232 | #endif /* __KERNEL__ */ |
240 | 233 | ||
241 | #define XFS_SB_GOOD_SASH_VERSION(sbp) \ | ||
242 | ((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \ | ||
243 | ((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \ | ||
244 | ((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | ||
245 | !((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKSASHBITS))) | ||
246 | |||
247 | #define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v) | 234 | #define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v) |
248 | static inline unsigned xfs_sb_version_tonew(unsigned v) | 235 | static inline unsigned xfs_sb_version_tonew(unsigned v) |
249 | { | 236 | { |
@@ -461,15 +448,6 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) | |||
461 | * File system sector to basic block conversions. | 448 | * File system sector to basic block conversions. |
462 | */ | 449 | */ |
463 | #define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log) | 450 | #define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log) |
464 | #define XFS_BB_TO_FSS(mp,bb) \ | ||
465 | (((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log) | ||
466 | #define XFS_BB_TO_FSST(mp,bb) ((bb) >> (mp)->m_sectbb_log) | ||
467 | |||
468 | /* | ||
469 | * File system sector to byte conversions. | ||
470 | */ | ||
471 | #define XFS_FSS_TO_B(mp,sectno) ((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog) | ||
472 | #define XFS_B_TO_FSST(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog) | ||
473 | 451 | ||
474 | /* | 452 | /* |
475 | * File system block to basic block conversions. | 453 | * File system block to basic block conversions. |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 9dc88b380608..c68e00105d23 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -149,7 +149,6 @@ typedef struct xfs_item_ops { | |||
149 | void (*iop_unlock)(xfs_log_item_t *); | 149 | void (*iop_unlock)(xfs_log_item_t *); |
150 | xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); | 150 | xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); |
151 | void (*iop_push)(xfs_log_item_t *); | 151 | void (*iop_push)(xfs_log_item_t *); |
152 | void (*iop_abort)(xfs_log_item_t *); | ||
153 | void (*iop_pushbuf)(xfs_log_item_t *); | 152 | void (*iop_pushbuf)(xfs_log_item_t *); |
154 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); | 153 | void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); |
155 | } xfs_item_ops_t; | 154 | } xfs_item_ops_t; |
@@ -163,7 +162,6 @@ typedef struct xfs_item_ops { | |||
163 | #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) | 162 | #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) |
164 | #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) | 163 | #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) |
165 | #define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) | 164 | #define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) |
166 | #define IOP_ABORT(ip) (*(ip)->li_ops->iop_abort)(ip) | ||
167 | #define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) | 165 | #define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) |
168 | #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) | 166 | #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) |
169 | 167 | ||
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 558c87ff0c41..fc39b166d403 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -276,7 +276,7 @@ xfs_trans_update_ail( | |||
276 | xfs_mount_t *mp, | 276 | xfs_mount_t *mp, |
277 | xfs_log_item_t *lip, | 277 | xfs_log_item_t *lip, |
278 | xfs_lsn_t lsn, | 278 | xfs_lsn_t lsn, |
279 | unsigned long s) | 279 | unsigned long s) __releases(mp->m_ail_lock) |
280 | { | 280 | { |
281 | xfs_ail_entry_t *ailp; | 281 | xfs_ail_entry_t *ailp; |
282 | xfs_log_item_t *dlip=NULL; | 282 | xfs_log_item_t *dlip=NULL; |
@@ -328,7 +328,7 @@ void | |||
328 | xfs_trans_delete_ail( | 328 | xfs_trans_delete_ail( |
329 | xfs_mount_t *mp, | 329 | xfs_mount_t *mp, |
330 | xfs_log_item_t *lip, | 330 | xfs_log_item_t *lip, |
331 | unsigned long s) | 331 | unsigned long s) __releases(mp->m_ail_lock) |
332 | { | 332 | { |
333 | xfs_ail_entry_t *ailp; | 333 | xfs_ail_entry_t *ailp; |
334 | xfs_log_item_t *dlip; | 334 | xfs_log_item_t *dlip; |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 13edab8a9e94..447ac4308c91 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -46,11 +46,13 @@ xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp, | |||
46 | /* | 46 | /* |
47 | * From xfs_trans_ail.c | 47 | * From xfs_trans_ail.c |
48 | */ | 48 | */ |
49 | void xfs_trans_update_ail(struct xfs_mount *, | 49 | void xfs_trans_update_ail(struct xfs_mount *mp, |
50 | struct xfs_log_item *, xfs_lsn_t, | 50 | struct xfs_log_item *lip, xfs_lsn_t lsn, |
51 | unsigned long); | 51 | unsigned long s) |
52 | void xfs_trans_delete_ail(struct xfs_mount *, | 52 | __releases(mp->m_ail_lock); |
53 | struct xfs_log_item *, unsigned long); | 53 | void xfs_trans_delete_ail(struct xfs_mount *mp, |
54 | struct xfs_log_item *lip, unsigned long s) | ||
55 | __releases(mp->m_ail_lock); | ||
54 | struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *); | 56 | struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *); |
55 | struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *, | 57 | struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *, |
56 | struct xfs_log_item *, int *, int *); | 58 | struct xfs_log_item *, int *, int *); |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index a34796e57afb..62336a4cc5a4 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -1922,7 +1922,7 @@ xfs_showargs( | |||
1922 | } | 1922 | } |
1923 | 1923 | ||
1924 | if (mp->m_flags & XFS_MOUNT_IHASHSIZE) | 1924 | if (mp->m_flags & XFS_MOUNT_IHASHSIZE) |
1925 | seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize); | 1925 | seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize); |
1926 | 1926 | ||
1927 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | 1927 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) |
1928 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", | 1928 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 23cfa5837728..061e2ffdd1de 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -2366,10 +2366,15 @@ xfs_remove( | |||
2366 | 2366 | ||
2367 | namelen = VNAMELEN(dentry); | 2367 | namelen = VNAMELEN(dentry); |
2368 | 2368 | ||
2369 | if (!xfs_get_dir_entry(dentry, &ip)) { | ||
2370 | dm_di_mode = ip->i_d.di_mode; | ||
2371 | IRELE(ip); | ||
2372 | } | ||
2373 | |||
2369 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 2374 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { |
2370 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, | 2375 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, |
2371 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, | 2376 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, |
2372 | name, NULL, 0, 0, 0); | 2377 | name, NULL, dm_di_mode, 0, 0); |
2373 | if (error) | 2378 | if (error) |
2374 | return error; | 2379 | return error; |
2375 | } | 2380 | } |
@@ -2995,7 +3000,7 @@ xfs_rmdir( | |||
2995 | int cancel_flags; | 3000 | int cancel_flags; |
2996 | int committed; | 3001 | int committed; |
2997 | bhv_vnode_t *dir_vp; | 3002 | bhv_vnode_t *dir_vp; |
2998 | int dm_di_mode = 0; | 3003 | int dm_di_mode = S_IFDIR; |
2999 | int last_cdp_link; | 3004 | int last_cdp_link; |
3000 | int namelen; | 3005 | int namelen; |
3001 | uint resblks; | 3006 | uint resblks; |
@@ -3010,11 +3015,16 @@ xfs_rmdir( | |||
3010 | return XFS_ERROR(EIO); | 3015 | return XFS_ERROR(EIO); |
3011 | namelen = VNAMELEN(dentry); | 3016 | namelen = VNAMELEN(dentry); |
3012 | 3017 | ||
3018 | if (!xfs_get_dir_entry(dentry, &cdp)) { | ||
3019 | dm_di_mode = cdp->i_d.di_mode; | ||
3020 | IRELE(cdp); | ||
3021 | } | ||
3022 | |||
3013 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 3023 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { |
3014 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, | 3024 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, |
3015 | dir_vp, DM_RIGHT_NULL, | 3025 | dir_vp, DM_RIGHT_NULL, |
3016 | NULL, DM_RIGHT_NULL, | 3026 | NULL, DM_RIGHT_NULL, |
3017 | name, NULL, 0, 0, 0); | 3027 | name, NULL, dm_di_mode, 0, 0); |
3018 | if (error) | 3028 | if (error) |
3019 | return XFS_ERROR(error); | 3029 | return XFS_ERROR(error); |
3020 | } | 3030 | } |
@@ -3834,7 +3844,9 @@ xfs_reclaim( | |||
3834 | XFS_MOUNT_ILOCK(mp); | 3844 | XFS_MOUNT_ILOCK(mp); |
3835 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); | 3845 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); |
3836 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); | 3846 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); |
3847 | spin_lock(&ip->i_flags_lock); | ||
3837 | ip->i_flags |= XFS_IRECLAIMABLE; | 3848 | ip->i_flags |= XFS_IRECLAIMABLE; |
3849 | spin_unlock(&ip->i_flags_lock); | ||
3838 | XFS_MOUNT_IUNLOCK(mp); | 3850 | XFS_MOUNT_IUNLOCK(mp); |
3839 | } | 3851 | } |
3840 | return 0; | 3852 | return 0; |
@@ -3859,8 +3871,10 @@ xfs_finish_reclaim( | |||
3859 | * us. | 3871 | * us. |
3860 | */ | 3872 | */ |
3861 | write_lock(&ih->ih_lock); | 3873 | write_lock(&ih->ih_lock); |
3874 | spin_lock(&ip->i_flags_lock); | ||
3862 | if ((ip->i_flags & XFS_IRECLAIM) || | 3875 | if ((ip->i_flags & XFS_IRECLAIM) || |
3863 | (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) { | 3876 | (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) { |
3877 | spin_unlock(&ip->i_flags_lock); | ||
3864 | write_unlock(&ih->ih_lock); | 3878 | write_unlock(&ih->ih_lock); |
3865 | if (locked) { | 3879 | if (locked) { |
3866 | xfs_ifunlock(ip); | 3880 | xfs_ifunlock(ip); |
@@ -3869,6 +3883,7 @@ xfs_finish_reclaim( | |||
3869 | return 1; | 3883 | return 1; |
3870 | } | 3884 | } |
3871 | ip->i_flags |= XFS_IRECLAIM; | 3885 | ip->i_flags |= XFS_IRECLAIM; |
3886 | spin_unlock(&ip->i_flags_lock); | ||
3872 | write_unlock(&ih->ih_lock); | 3887 | write_unlock(&ih->ih_lock); |
3873 | 3888 | ||
3874 | /* | 3889 | /* |
@@ -4272,7 +4287,7 @@ xfs_free_file_space( | |||
4272 | xfs_mount_t *mp; | 4287 | xfs_mount_t *mp; |
4273 | int nimap; | 4288 | int nimap; |
4274 | uint resblks; | 4289 | uint resblks; |
4275 | int rounding; | 4290 | uint rounding; |
4276 | int rt; | 4291 | int rt; |
4277 | xfs_fileoff_t startoffset_fsb; | 4292 | xfs_fileoff_t startoffset_fsb; |
4278 | xfs_trans_t *tp; | 4293 | xfs_trans_t *tp; |
@@ -4313,8 +4328,7 @@ xfs_free_file_space( | |||
4313 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 4328 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ |
4314 | } | 4329 | } |
4315 | 4330 | ||
4316 | rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), | 4331 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); |
4317 | (__uint8_t)NBPP); | ||
4318 | ilen = len + (offset & (rounding - 1)); | 4332 | ilen = len + (offset & (rounding - 1)); |
4319 | ioffset = offset & ~(rounding - 1); | 4333 | ioffset = offset & ~(rounding - 1); |
4320 | if (ilen & (rounding - 1)) | 4334 | if (ilen & (rounding - 1)) |