diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_elf.c | 3 | ||||
-rw-r--r-- | fs/block_dev.c | 10 | ||||
-rw-r--r-- | fs/buffer.c | 13 | ||||
-rw-r--r-- | fs/dcache.c | 68 | ||||
-rw-r--r-- | fs/exec.c | 8 | ||||
-rw-r--r-- | fs/ext4/resize.c | 3 | ||||
-rw-r--r-- | fs/fuse/inode.c | 4 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 23 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 | ||||
-rw-r--r-- | fs/locks.c | 6 | ||||
-rw-r--r-- | fs/namei.c | 26 | ||||
-rw-r--r-- | fs/nfs/mount_clnt.c | 5 | ||||
-rw-r--r-- | fs/nfs/super.c | 76 | ||||
-rw-r--r-- | fs/nfs/write.c | 7 | ||||
-rw-r--r-- | fs/ocfs2/cluster/nodemanager.c | 74 | ||||
-rw-r--r-- | fs/ocfs2/cluster/nodemanager.h | 4 | ||||
-rw-r--r-- | fs/ocfs2/stack_o2cb.c | 41 | ||||
-rw-r--r-- | fs/ocfs2/stack_user.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/stackglue.c | 119 | ||||
-rw-r--r-- | fs/ocfs2/stackglue.h | 19 | ||||
-rw-r--r-- | fs/pipe.c | 10 | ||||
-rw-r--r-- | fs/select.c | 2 | ||||
-rw-r--r-- | fs/udf/super.c | 57 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 2 | ||||
-rw-r--r-- | fs/utimes.c | 59 |
25 files changed, 315 insertions, 329 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 0fa95b198e6e..d48ff5f370f4 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
19 | #include <linux/a.out.h> | ||
20 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
21 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
22 | #include <linux/binfmts.h> | 21 | #include <linux/binfmts.h> |
@@ -548,7 +547,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
548 | struct { | 547 | struct { |
549 | struct elfhdr elf_ex; | 548 | struct elfhdr elf_ex; |
550 | struct elfhdr interp_elf_ex; | 549 | struct elfhdr interp_elf_ex; |
551 | struct exec interp_ex; | ||
552 | } *loc; | 550 | } *loc; |
553 | 551 | ||
554 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); | 552 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); |
@@ -680,7 +678,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
680 | } | 678 | } |
681 | 679 | ||
682 | /* Get the exec headers */ | 680 | /* Get the exec headers */ |
683 | loc->interp_ex = *((struct exec *)bprm->buf); | ||
684 | loc->interp_elf_ex = *((struct elfhdr *)bprm->buf); | 681 | loc->interp_elf_ex = *((struct elfhdr *)bprm->buf); |
685 | break; | 682 | break; |
686 | } | 683 | } |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 470c10ceb0fb..10d8a0aa871a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -931,8 +931,16 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
931 | struct gendisk *disk; | 931 | struct gendisk *disk; |
932 | int ret; | 932 | int ret; |
933 | int part; | 933 | int part; |
934 | int perm = 0; | ||
934 | 935 | ||
935 | ret = devcgroup_inode_permission(bdev->bd_inode, file->f_mode); | 936 | if (file->f_mode & FMODE_READ) |
937 | perm |= MAY_READ; | ||
938 | if (file->f_mode & FMODE_WRITE) | ||
939 | perm |= MAY_WRITE; | ||
940 | /* | ||
941 | * hooks: /n/, see "layering violations". | ||
942 | */ | ||
943 | ret = devcgroup_inode_permission(bdev->bd_inode, perm); | ||
936 | if (ret != 0) | 944 | if (ret != 0) |
937 | return ret; | 945 | return ret; |
938 | 946 | ||
diff --git a/fs/buffer.c b/fs/buffer.c index a073f3f4f013..0f51c0f7c266 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -821,7 +821,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) | |||
821 | * contents - it is a noop if I/O is still in | 821 | * contents - it is a noop if I/O is still in |
822 | * flight on potentially older contents. | 822 | * flight on potentially older contents. |
823 | */ | 823 | */ |
824 | ll_rw_block(SWRITE, 1, &bh); | 824 | ll_rw_block(SWRITE_SYNC, 1, &bh); |
825 | brelse(bh); | 825 | brelse(bh); |
826 | spin_lock(lock); | 826 | spin_lock(lock); |
827 | } | 827 | } |
@@ -2940,16 +2940,19 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | |||
2940 | for (i = 0; i < nr; i++) { | 2940 | for (i = 0; i < nr; i++) { |
2941 | struct buffer_head *bh = bhs[i]; | 2941 | struct buffer_head *bh = bhs[i]; |
2942 | 2942 | ||
2943 | if (rw == SWRITE) | 2943 | if (rw == SWRITE || rw == SWRITE_SYNC) |
2944 | lock_buffer(bh); | 2944 | lock_buffer(bh); |
2945 | else if (test_set_buffer_locked(bh)) | 2945 | else if (test_set_buffer_locked(bh)) |
2946 | continue; | 2946 | continue; |
2947 | 2947 | ||
2948 | if (rw == WRITE || rw == SWRITE) { | 2948 | if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC) { |
2949 | if (test_clear_buffer_dirty(bh)) { | 2949 | if (test_clear_buffer_dirty(bh)) { |
2950 | bh->b_end_io = end_buffer_write_sync; | 2950 | bh->b_end_io = end_buffer_write_sync; |
2951 | get_bh(bh); | 2951 | get_bh(bh); |
2952 | submit_bh(WRITE, bh); | 2952 | if (rw == SWRITE_SYNC) |
2953 | submit_bh(WRITE_SYNC, bh); | ||
2954 | else | ||
2955 | submit_bh(WRITE, bh); | ||
2953 | continue; | 2956 | continue; |
2954 | } | 2957 | } |
2955 | } else { | 2958 | } else { |
@@ -2978,7 +2981,7 @@ int sync_dirty_buffer(struct buffer_head *bh) | |||
2978 | if (test_clear_buffer_dirty(bh)) { | 2981 | if (test_clear_buffer_dirty(bh)) { |
2979 | get_bh(bh); | 2982 | get_bh(bh); |
2980 | bh->b_end_io = end_buffer_write_sync; | 2983 | bh->b_end_io = end_buffer_write_sync; |
2981 | ret = submit_bh(WRITE, bh); | 2984 | ret = submit_bh(WRITE_SYNC, bh); |
2982 | wait_on_buffer(bh); | 2985 | wait_on_buffer(bh); |
2983 | if (buffer_eopnotsupp(bh)) { | 2986 | if (buffer_eopnotsupp(bh)) { |
2984 | clear_buffer_eopnotsupp(bh); | 2987 | clear_buffer_eopnotsupp(bh); |
diff --git a/fs/dcache.c b/fs/dcache.c index 3ee588d5f585..6068c25b393c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/fdtable.h> | ||
20 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
21 | #include <linux/fsnotify.h> | 22 | #include <linux/fsnotify.h> |
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
@@ -106,9 +107,10 @@ static void dentry_lru_remove(struct dentry *dentry) | |||
106 | /* | 107 | /* |
107 | * Release the dentry's inode, using the filesystem | 108 | * Release the dentry's inode, using the filesystem |
108 | * d_iput() operation if defined. | 109 | * d_iput() operation if defined. |
109 | * Called with dcache_lock and per dentry lock held, drops both. | ||
110 | */ | 110 | */ |
111 | static void dentry_iput(struct dentry * dentry) | 111 | static void dentry_iput(struct dentry * dentry) |
112 | __releases(dentry->d_lock) | ||
113 | __releases(dcache_lock) | ||
112 | { | 114 | { |
113 | struct inode *inode = dentry->d_inode; | 115 | struct inode *inode = dentry->d_inode; |
114 | if (inode) { | 116 | if (inode) { |
@@ -132,12 +134,13 @@ static void dentry_iput(struct dentry * dentry) | |||
132 | * d_kill - kill dentry and return parent | 134 | * d_kill - kill dentry and return parent |
133 | * @dentry: dentry to kill | 135 | * @dentry: dentry to kill |
134 | * | 136 | * |
135 | * Called with dcache_lock and d_lock, releases both. The dentry must | 137 | * The dentry must already be unhashed and removed from the LRU. |
136 | * already be unhashed and removed from the LRU. | ||
137 | * | 138 | * |
138 | * If this is the root of the dentry tree, return NULL. | 139 | * If this is the root of the dentry tree, return NULL. |
139 | */ | 140 | */ |
140 | static struct dentry *d_kill(struct dentry *dentry) | 141 | static struct dentry *d_kill(struct dentry *dentry) |
142 | __releases(dentry->d_lock) | ||
143 | __releases(dcache_lock) | ||
141 | { | 144 | { |
142 | struct dentry *parent; | 145 | struct dentry *parent; |
143 | 146 | ||
@@ -383,11 +386,11 @@ restart: | |||
383 | * Try to prune ancestors as well. This is necessary to prevent | 386 | * Try to prune ancestors as well. This is necessary to prevent |
384 | * quadratic behavior of shrink_dcache_parent(), but is also expected | 387 | * quadratic behavior of shrink_dcache_parent(), but is also expected |
385 | * to be beneficial in reducing dentry cache fragmentation. | 388 | * to be beneficial in reducing dentry cache fragmentation. |
386 | * | ||
387 | * Called with dcache_lock, drops it and then regains. | ||
388 | * Called with dentry->d_lock held, drops it. | ||
389 | */ | 389 | */ |
390 | static void prune_one_dentry(struct dentry * dentry) | 390 | static void prune_one_dentry(struct dentry * dentry) |
391 | __releases(dentry->d_lock) | ||
392 | __releases(dcache_lock) | ||
393 | __acquires(dcache_lock) | ||
391 | { | 394 | { |
392 | __d_drop(dentry); | 395 | __d_drop(dentry); |
393 | dentry = d_kill(dentry); | 396 | dentry = d_kill(dentry); |
@@ -1604,10 +1607,9 @@ static int d_isparent(struct dentry *p1, struct dentry *p2) | |||
1604 | * | 1607 | * |
1605 | * Note: If ever the locking in lock_rename() changes, then please | 1608 | * Note: If ever the locking in lock_rename() changes, then please |
1606 | * remember to update this too... | 1609 | * remember to update this too... |
1607 | * | ||
1608 | * On return, dcache_lock will have been unlocked. | ||
1609 | */ | 1610 | */ |
1610 | static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) | 1611 | static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias) |
1612 | __releases(dcache_lock) | ||
1611 | { | 1613 | { |
1612 | struct mutex *m1 = NULL, *m2 = NULL; | 1614 | struct mutex *m1 = NULL, *m2 = NULL; |
1613 | struct dentry *ret; | 1615 | struct dentry *ret; |
@@ -1743,11 +1745,9 @@ out_nolock: | |||
1743 | shouldnt_be_hashed: | 1745 | shouldnt_be_hashed: |
1744 | spin_unlock(&dcache_lock); | 1746 | spin_unlock(&dcache_lock); |
1745 | BUG(); | 1747 | BUG(); |
1746 | goto shouldnt_be_hashed; | ||
1747 | } | 1748 | } |
1748 | 1749 | ||
1749 | static int prepend(char **buffer, int *buflen, const char *str, | 1750 | static int prepend(char **buffer, int *buflen, const char *str, int namelen) |
1750 | int namelen) | ||
1751 | { | 1751 | { |
1752 | *buflen -= namelen; | 1752 | *buflen -= namelen; |
1753 | if (*buflen < 0) | 1753 | if (*buflen < 0) |
@@ -1757,8 +1757,13 @@ static int prepend(char **buffer, int *buflen, const char *str, | |||
1757 | return 0; | 1757 | return 0; |
1758 | } | 1758 | } |
1759 | 1759 | ||
1760 | static int prepend_name(char **buffer, int *buflen, struct qstr *name) | ||
1761 | { | ||
1762 | return prepend(buffer, buflen, name->name, name->len); | ||
1763 | } | ||
1764 | |||
1760 | /** | 1765 | /** |
1761 | * d_path - return the path of a dentry | 1766 | * __d_path - return the path of a dentry |
1762 | * @path: the dentry/vfsmount to report | 1767 | * @path: the dentry/vfsmount to report |
1763 | * @root: root vfsmnt/dentry (may be modified by this function) | 1768 | * @root: root vfsmnt/dentry (may be modified by this function) |
1764 | * @buffer: buffer to return value in | 1769 | * @buffer: buffer to return value in |
@@ -1779,9 +1784,10 @@ char *__d_path(const struct path *path, struct path *root, | |||
1779 | { | 1784 | { |
1780 | struct dentry *dentry = path->dentry; | 1785 | struct dentry *dentry = path->dentry; |
1781 | struct vfsmount *vfsmnt = path->mnt; | 1786 | struct vfsmount *vfsmnt = path->mnt; |
1782 | char * end = buffer+buflen; | 1787 | char *end = buffer + buflen; |
1783 | char * retval; | 1788 | char *retval; |
1784 | 1789 | ||
1790 | spin_lock(&vfsmount_lock); | ||
1785 | prepend(&end, &buflen, "\0", 1); | 1791 | prepend(&end, &buflen, "\0", 1); |
1786 | if (!IS_ROOT(dentry) && d_unhashed(dentry) && | 1792 | if (!IS_ROOT(dentry) && d_unhashed(dentry) && |
1787 | (prepend(&end, &buflen, " (deleted)", 10) != 0)) | 1793 | (prepend(&end, &buflen, " (deleted)", 10) != 0)) |
@@ -1800,38 +1806,37 @@ char *__d_path(const struct path *path, struct path *root, | |||
1800 | break; | 1806 | break; |
1801 | if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { | 1807 | if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { |
1802 | /* Global root? */ | 1808 | /* Global root? */ |
1803 | spin_lock(&vfsmount_lock); | ||
1804 | if (vfsmnt->mnt_parent == vfsmnt) { | 1809 | if (vfsmnt->mnt_parent == vfsmnt) { |
1805 | spin_unlock(&vfsmount_lock); | ||
1806 | goto global_root; | 1810 | goto global_root; |
1807 | } | 1811 | } |
1808 | dentry = vfsmnt->mnt_mountpoint; | 1812 | dentry = vfsmnt->mnt_mountpoint; |
1809 | vfsmnt = vfsmnt->mnt_parent; | 1813 | vfsmnt = vfsmnt->mnt_parent; |
1810 | spin_unlock(&vfsmount_lock); | ||
1811 | continue; | 1814 | continue; |
1812 | } | 1815 | } |
1813 | parent = dentry->d_parent; | 1816 | parent = dentry->d_parent; |
1814 | prefetch(parent); | 1817 | prefetch(parent); |
1815 | if ((prepend(&end, &buflen, dentry->d_name.name, | 1818 | if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) || |
1816 | dentry->d_name.len) != 0) || | ||
1817 | (prepend(&end, &buflen, "/", 1) != 0)) | 1819 | (prepend(&end, &buflen, "/", 1) != 0)) |
1818 | goto Elong; | 1820 | goto Elong; |
1819 | retval = end; | 1821 | retval = end; |
1820 | dentry = parent; | 1822 | dentry = parent; |
1821 | } | 1823 | } |
1822 | 1824 | ||
1825 | out: | ||
1826 | spin_unlock(&vfsmount_lock); | ||
1823 | return retval; | 1827 | return retval; |
1824 | 1828 | ||
1825 | global_root: | 1829 | global_root: |
1826 | retval += 1; /* hit the slash */ | 1830 | retval += 1; /* hit the slash */ |
1827 | if (prepend(&retval, &buflen, dentry->d_name.name, | 1831 | if (prepend_name(&retval, &buflen, &dentry->d_name) != 0) |
1828 | dentry->d_name.len) != 0) | ||
1829 | goto Elong; | 1832 | goto Elong; |
1830 | root->mnt = vfsmnt; | 1833 | root->mnt = vfsmnt; |
1831 | root->dentry = dentry; | 1834 | root->dentry = dentry; |
1832 | return retval; | 1835 | goto out; |
1836 | |||
1833 | Elong: | 1837 | Elong: |
1834 | return ERR_PTR(-ENAMETOOLONG); | 1838 | retval = ERR_PTR(-ENAMETOOLONG); |
1839 | goto out; | ||
1835 | } | 1840 | } |
1836 | 1841 | ||
1837 | /** | 1842 | /** |
@@ -1845,9 +1850,9 @@ Elong: | |||
1845 | * | 1850 | * |
1846 | * Returns the buffer or an error code if the path was too long. | 1851 | * Returns the buffer or an error code if the path was too long. |
1847 | * | 1852 | * |
1848 | * "buflen" should be positive. Caller holds the dcache_lock. | 1853 | * "buflen" should be positive. |
1849 | */ | 1854 | */ |
1850 | char *d_path(struct path *path, char *buf, int buflen) | 1855 | char *d_path(const struct path *path, char *buf, int buflen) |
1851 | { | 1856 | { |
1852 | char *res; | 1857 | char *res; |
1853 | struct path root; | 1858 | struct path root; |
@@ -1915,16 +1920,11 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen) | |||
1915 | retval = end-1; | 1920 | retval = end-1; |
1916 | *retval = '/'; | 1921 | *retval = '/'; |
1917 | 1922 | ||
1918 | for (;;) { | 1923 | while (!IS_ROOT(dentry)) { |
1919 | struct dentry *parent; | 1924 | struct dentry *parent = dentry->d_parent; |
1920 | if (IS_ROOT(dentry)) | ||
1921 | break; | ||
1922 | 1925 | ||
1923 | parent = dentry->d_parent; | ||
1924 | prefetch(parent); | 1926 | prefetch(parent); |
1925 | 1927 | if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) || | |
1926 | if ((prepend(&end, &buflen, dentry->d_name.name, | ||
1927 | dentry->d_name.len) != 0) || | ||
1928 | (prepend(&end, &buflen, "/", 1) != 0)) | 1928 | (prepend(&end, &buflen, "/", 1) != 0)) |
1929 | goto Elong; | 1929 | goto Elong; |
1930 | 1930 | ||
@@ -1975,7 +1975,7 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) | |||
1975 | error = -ENOENT; | 1975 | error = -ENOENT; |
1976 | /* Has the current directory has been unlinked? */ | 1976 | /* Has the current directory has been unlinked? */ |
1977 | spin_lock(&dcache_lock); | 1977 | spin_lock(&dcache_lock); |
1978 | if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { | 1978 | if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) { |
1979 | unsigned long len; | 1979 | unsigned long len; |
1980 | struct path tmp = root; | 1980 | struct path tmp = root; |
1981 | char * cwd; | 1981 | char * cwd; |
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/file.h> | 26 | #include <linux/file.h> |
27 | #include <linux/fdtable.h> | 27 | #include <linux/fdtable.h> |
28 | #include <linux/mman.h> | 28 | #include <linux/mman.h> |
29 | #include <linux/a.out.h> | ||
30 | #include <linux/stat.h> | 29 | #include <linux/stat.h> |
31 | #include <linux/fcntl.h> | 30 | #include <linux/fcntl.h> |
32 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
@@ -61,6 +60,11 @@ | |||
61 | #include <linux/kmod.h> | 60 | #include <linux/kmod.h> |
62 | #endif | 61 | #endif |
63 | 62 | ||
63 | #ifdef __alpha__ | ||
64 | /* for /sbin/loader handling in search_binary_handler() */ | ||
65 | #include <linux/a.out.h> | ||
66 | #endif | ||
67 | |||
64 | int core_uses_pid; | 68 | int core_uses_pid; |
65 | char core_pattern[CORENAME_MAX_SIZE] = "core"; | 69 | char core_pattern[CORENAME_MAX_SIZE] = "core"; |
66 | int suid_dumpable = 0; | 70 | int suid_dumpable = 0; |
@@ -1155,7 +1159,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | |||
1155 | { | 1159 | { |
1156 | int try,retval; | 1160 | int try,retval; |
1157 | struct linux_binfmt *fmt; | 1161 | struct linux_binfmt *fmt; |
1158 | #if defined(__alpha__) && defined(CONFIG_ARCH_SUPPORTS_AOUT) | 1162 | #ifdef __alpha__ |
1159 | /* handle /sbin/loader.. */ | 1163 | /* handle /sbin/loader.. */ |
1160 | { | 1164 | { |
1161 | struct exec * eh = (struct exec *) bprm->buf; | 1165 | struct exec * eh = (struct exec *) bprm->buf; |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9ecb92f68543..9ff7b1c04239 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -855,7 +855,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
855 | */ | 855 | */ |
856 | 856 | ||
857 | /* Update group descriptor block for new group */ | 857 | /* Update group descriptor block for new group */ |
858 | gdp = (struct ext4_group_desc *)primary->b_data + gdb_off; | 858 | gdp = (struct ext4_group_desc *)((char *)primary->b_data + |
859 | gdb_off * EXT4_DESC_SIZE(sb)); | ||
859 | 860 | ||
860 | ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ | 861 | ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ |
861 | ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ | 862 | ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 43e99513334a..3141690558c8 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -591,7 +591,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
591 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); | 591 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); |
592 | fc->minor = arg->minor; | 592 | fc->minor = arg->minor; |
593 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; | 593 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; |
594 | fc->max_write = min_t(unsigned, 4096, fc->max_write); | 594 | fc->max_write = max_t(unsigned, 4096, fc->max_write); |
595 | fc->conn_init = 1; | 595 | fc->conn_init = 1; |
596 | } | 596 | } |
597 | fuse_put_request(fc, req); | 597 | fuse_put_request(fc, req); |
@@ -667,7 +667,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
667 | fc->flags = d.flags; | 667 | fc->flags = d.flags; |
668 | fc->user_id = d.user_id; | 668 | fc->user_id = d.user_id; |
669 | fc->group_id = d.group_id; | 669 | fc->group_id = d.group_id; |
670 | fc->max_read = min_t(unsigned, 4096, d.max_read); | 670 | fc->max_read = max_t(unsigned, 4096, d.max_read); |
671 | 671 | ||
672 | /* Used by get_root_inode() */ | 672 | /* Used by get_root_inode() */ |
673 | sb->s_fs_info = fc; | 673 | sb->s_fs_info = fc; |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index c19184f2e70e..bec76b1c2bb0 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -246,15 +246,11 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block, | |||
246 | 246 | ||
247 | } | 247 | } |
248 | 248 | ||
249 | static inline unsigned int zero_metapath_length(const struct metapath *mp, | 249 | static inline unsigned int metapath_branch_start(const struct metapath *mp) |
250 | unsigned height) | ||
251 | { | 250 | { |
252 | unsigned int i; | 251 | if (mp->mp_list[0] == 0) |
253 | for (i = 0; i < height - 1; i++) { | 252 | return 2; |
254 | if (mp->mp_list[i] != 0) | 253 | return 1; |
255 | return i; | ||
256 | } | ||
257 | return height; | ||
258 | } | 254 | } |
259 | 255 | ||
260 | /** | 256 | /** |
@@ -436,7 +432,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, | |||
436 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 432 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
437 | struct buffer_head *dibh = mp->mp_bh[0]; | 433 | struct buffer_head *dibh = mp->mp_bh[0]; |
438 | u64 bn, dblock = 0; | 434 | u64 bn, dblock = 0; |
439 | unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0; | 435 | unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0; |
440 | unsigned dblks = 0; | 436 | unsigned dblks = 0; |
441 | unsigned ptrs_per_blk; | 437 | unsigned ptrs_per_blk; |
442 | const unsigned end_of_metadata = height - 1; | 438 | const unsigned end_of_metadata = height - 1; |
@@ -471,9 +467,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, | |||
471 | /* Building up tree height */ | 467 | /* Building up tree height */ |
472 | state = ALLOC_GROW_HEIGHT; | 468 | state = ALLOC_GROW_HEIGHT; |
473 | iblks = height - ip->i_height; | 469 | iblks = height - ip->i_height; |
474 | zmpl = zero_metapath_length(mp, height); | 470 | branch_start = metapath_branch_start(mp); |
475 | iblks -= zmpl; | 471 | iblks += (height - branch_start); |
476 | iblks += height; | ||
477 | } | 472 | } |
478 | } | 473 | } |
479 | 474 | ||
@@ -509,13 +504,13 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, | |||
509 | sizeof(struct gfs2_meta_header)); | 504 | sizeof(struct gfs2_meta_header)); |
510 | *ptr = zero_bn; | 505 | *ptr = zero_bn; |
511 | state = ALLOC_GROW_DEPTH; | 506 | state = ALLOC_GROW_DEPTH; |
512 | for(i = zmpl; i < height; i++) { | 507 | for(i = branch_start; i < height; i++) { |
513 | if (mp->mp_bh[i] == NULL) | 508 | if (mp->mp_bh[i] == NULL) |
514 | break; | 509 | break; |
515 | brelse(mp->mp_bh[i]); | 510 | brelse(mp->mp_bh[i]); |
516 | mp->mp_bh[i] = NULL; | 511 | mp->mp_bh[i] = NULL; |
517 | } | 512 | } |
518 | i = zmpl; | 513 | i = branch_start; |
519 | } | 514 | } |
520 | if (n == 0) | 515 | if (n == 0) |
521 | break; | 516 | break; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 6387523a3153..3401628d742b 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -195,7 +195,7 @@ ulong_aligned: | |||
195 | depending on architecture. I've experimented with several ways | 195 | depending on architecture. I've experimented with several ways |
196 | of writing this section such as using an else before the goto | 196 | of writing this section such as using an else before the goto |
197 | but this one seems to be the fastest. */ | 197 | but this one seems to be the fastest. */ |
198 | while ((unsigned char *)plong < end - 1) { | 198 | while ((unsigned char *)plong < end - sizeof(unsigned long)) { |
199 | prefetch(plong + 1); | 199 | prefetch(plong + 1); |
200 | if (((*plong) & LBITMASK) != lskipval) | 200 | if (((*plong) & LBITMASK) != lskipval) |
201 | break; | 201 | break; |
diff --git a/fs/locks.c b/fs/locks.c index 11dbf08651b7..dce8c747371c 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -561,9 +561,6 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl) | |||
561 | /* insert into file's list */ | 561 | /* insert into file's list */ |
562 | fl->fl_next = *pos; | 562 | fl->fl_next = *pos; |
563 | *pos = fl; | 563 | *pos = fl; |
564 | |||
565 | if (fl->fl_ops && fl->fl_ops->fl_insert) | ||
566 | fl->fl_ops->fl_insert(fl); | ||
567 | } | 564 | } |
568 | 565 | ||
569 | /* | 566 | /* |
@@ -586,9 +583,6 @@ static void locks_delete_lock(struct file_lock **thisfl_p) | |||
586 | fl->fl_fasync = NULL; | 583 | fl->fl_fasync = NULL; |
587 | } | 584 | } |
588 | 585 | ||
589 | if (fl->fl_ops && fl->fl_ops->fl_remove) | ||
590 | fl->fl_ops->fl_remove(fl); | ||
591 | |||
592 | if (fl->fl_nspid) { | 586 | if (fl->fl_nspid) { |
593 | put_pid(fl->fl_nspid); | 587 | put_pid(fl->fl_nspid); |
594 | fl->fl_nspid = NULL; | 588 | fl->fl_nspid = NULL; |
diff --git a/fs/namei.c b/fs/namei.c index c7e43536c49a..01e67dddcc3d 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -581,15 +581,13 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd | |||
581 | int result; | 581 | int result; |
582 | 582 | ||
583 | /* make sure the stuff we saved doesn't go away */ | 583 | /* make sure the stuff we saved doesn't go away */ |
584 | dget(save.dentry); | 584 | path_get(&save); |
585 | mntget(save.mnt); | ||
586 | 585 | ||
587 | result = __link_path_walk(name, nd); | 586 | result = __link_path_walk(name, nd); |
588 | if (result == -ESTALE) { | 587 | if (result == -ESTALE) { |
589 | /* nd->path had been dropped */ | 588 | /* nd->path had been dropped */ |
590 | nd->path = save; | 589 | nd->path = save; |
591 | dget(nd->path.dentry); | 590 | path_get(&nd->path); |
592 | mntget(nd->path.mnt); | ||
593 | nd->flags |= LOOKUP_REVAL; | 591 | nd->flags |= LOOKUP_REVAL; |
594 | result = __link_path_walk(name, nd); | 592 | result = __link_path_walk(name, nd); |
595 | } | 593 | } |
@@ -1216,8 +1214,9 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, | |||
1216 | nd->flags = flags; | 1214 | nd->flags = flags; |
1217 | nd->depth = 0; | 1215 | nd->depth = 0; |
1218 | 1216 | ||
1219 | nd->path.mnt = mntget(mnt); | 1217 | nd->path.dentry = dentry; |
1220 | nd->path.dentry = dget(dentry); | 1218 | nd->path.mnt = mnt; |
1219 | path_get(&nd->path); | ||
1221 | 1220 | ||
1222 | retval = path_walk(name, nd); | 1221 | retval = path_walk(name, nd); |
1223 | if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && | 1222 | if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && |
@@ -2857,16 +2856,17 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) | |||
2857 | { | 2856 | { |
2858 | struct nameidata nd; | 2857 | struct nameidata nd; |
2859 | void *cookie; | 2858 | void *cookie; |
2859 | int res; | ||
2860 | 2860 | ||
2861 | nd.depth = 0; | 2861 | nd.depth = 0; |
2862 | cookie = dentry->d_inode->i_op->follow_link(dentry, &nd); | 2862 | cookie = dentry->d_inode->i_op->follow_link(dentry, &nd); |
2863 | if (!IS_ERR(cookie)) { | 2863 | if (IS_ERR(cookie)) |
2864 | int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); | 2864 | return PTR_ERR(cookie); |
2865 | if (dentry->d_inode->i_op->put_link) | 2865 | |
2866 | dentry->d_inode->i_op->put_link(dentry, &nd, cookie); | 2866 | res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); |
2867 | cookie = ERR_PTR(res); | 2867 | if (dentry->d_inode->i_op->put_link) |
2868 | } | 2868 | dentry->d_inode->i_op->put_link(dentry, &nd, cookie); |
2869 | return PTR_ERR(cookie); | 2869 | return res; |
2870 | } | 2870 | } |
2871 | 2871 | ||
2872 | int vfs_follow_link(struct nameidata *nd, const char *link) | 2872 | int vfs_follow_link(struct nameidata *nd, const char *link) |
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 49c7cd0502cc..779d2eb649c5 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
@@ -130,10 +130,11 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, | |||
130 | struct mnt_fhstatus *res) | 130 | struct mnt_fhstatus *res) |
131 | { | 131 | { |
132 | struct nfs_fh *fh = res->fh; | 132 | struct nfs_fh *fh = res->fh; |
133 | unsigned size; | ||
133 | 134 | ||
134 | if ((res->status = ntohl(*p++)) == 0) { | 135 | if ((res->status = ntohl(*p++)) == 0) { |
135 | int size = ntohl(*p++); | 136 | size = ntohl(*p++); |
136 | if (size <= NFS3_FHSIZE) { | 137 | if (size <= NFS3_FHSIZE && size != 0) { |
137 | fh->size = size; | 138 | fh->size = size; |
138 | memcpy(fh->data, p, size); | 139 | memcpy(fh->data, p, size); |
139 | } else | 140 | } else |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2a4a024a4e7b..614efeed5437 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1216,8 +1216,6 @@ static int nfs_validate_mount_data(void *options, | |||
1216 | { | 1216 | { |
1217 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; | 1217 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; |
1218 | 1218 | ||
1219 | memset(args, 0, sizeof(*args)); | ||
1220 | |||
1221 | if (data == NULL) | 1219 | if (data == NULL) |
1222 | goto out_no_data; | 1220 | goto out_no_data; |
1223 | 1221 | ||
@@ -1251,13 +1249,13 @@ static int nfs_validate_mount_data(void *options, | |||
1251 | case 5: | 1249 | case 5: |
1252 | memset(data->context, 0, sizeof(data->context)); | 1250 | memset(data->context, 0, sizeof(data->context)); |
1253 | case 6: | 1251 | case 6: |
1254 | if (data->flags & NFS_MOUNT_VER3) | 1252 | if (data->flags & NFS_MOUNT_VER3) { |
1253 | if (data->root.size > NFS3_FHSIZE || data->root.size == 0) | ||
1254 | goto out_invalid_fh; | ||
1255 | mntfh->size = data->root.size; | 1255 | mntfh->size = data->root.size; |
1256 | else | 1256 | } else |
1257 | mntfh->size = NFS2_FHSIZE; | 1257 | mntfh->size = NFS2_FHSIZE; |
1258 | 1258 | ||
1259 | if (mntfh->size > sizeof(mntfh->data)) | ||
1260 | goto out_invalid_fh; | ||
1261 | 1259 | ||
1262 | memcpy(mntfh->data, data->root.data, mntfh->size); | 1260 | memcpy(mntfh->data, data->root.data, mntfh->size); |
1263 | if (mntfh->size < sizeof(mntfh->data)) | 1261 | if (mntfh->size < sizeof(mntfh->data)) |
@@ -1585,24 +1583,29 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1585 | { | 1583 | { |
1586 | struct nfs_server *server = NULL; | 1584 | struct nfs_server *server = NULL; |
1587 | struct super_block *s; | 1585 | struct super_block *s; |
1588 | struct nfs_fh mntfh; | 1586 | struct nfs_parsed_mount_data *data; |
1589 | struct nfs_parsed_mount_data data; | 1587 | struct nfs_fh *mntfh; |
1590 | struct dentry *mntroot; | 1588 | struct dentry *mntroot; |
1591 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | 1589 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; |
1592 | struct nfs_sb_mountdata sb_mntdata = { | 1590 | struct nfs_sb_mountdata sb_mntdata = { |
1593 | .mntflags = flags, | 1591 | .mntflags = flags, |
1594 | }; | 1592 | }; |
1595 | int error; | 1593 | int error = -ENOMEM; |
1594 | |||
1595 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
1596 | mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); | ||
1597 | if (data == NULL || mntfh == NULL) | ||
1598 | goto out_free_fh; | ||
1596 | 1599 | ||
1597 | security_init_mnt_opts(&data.lsm_opts); | 1600 | security_init_mnt_opts(&data->lsm_opts); |
1598 | 1601 | ||
1599 | /* Validate the mount data */ | 1602 | /* Validate the mount data */ |
1600 | error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); | 1603 | error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name); |
1601 | if (error < 0) | 1604 | if (error < 0) |
1602 | goto out; | 1605 | goto out; |
1603 | 1606 | ||
1604 | /* Get a volume representation */ | 1607 | /* Get a volume representation */ |
1605 | server = nfs_create_server(&data, &mntfh); | 1608 | server = nfs_create_server(data, mntfh); |
1606 | if (IS_ERR(server)) { | 1609 | if (IS_ERR(server)) { |
1607 | error = PTR_ERR(server); | 1610 | error = PTR_ERR(server); |
1608 | goto out; | 1611 | goto out; |
@@ -1630,16 +1633,16 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1630 | 1633 | ||
1631 | if (!s->s_root) { | 1634 | if (!s->s_root) { |
1632 | /* initial superblock/root creation */ | 1635 | /* initial superblock/root creation */ |
1633 | nfs_fill_super(s, &data); | 1636 | nfs_fill_super(s, data); |
1634 | } | 1637 | } |
1635 | 1638 | ||
1636 | mntroot = nfs_get_root(s, &mntfh); | 1639 | mntroot = nfs_get_root(s, mntfh); |
1637 | if (IS_ERR(mntroot)) { | 1640 | if (IS_ERR(mntroot)) { |
1638 | error = PTR_ERR(mntroot); | 1641 | error = PTR_ERR(mntroot); |
1639 | goto error_splat_super; | 1642 | goto error_splat_super; |
1640 | } | 1643 | } |
1641 | 1644 | ||
1642 | error = security_sb_set_mnt_opts(s, &data.lsm_opts); | 1645 | error = security_sb_set_mnt_opts(s, &data->lsm_opts); |
1643 | if (error) | 1646 | if (error) |
1644 | goto error_splat_root; | 1647 | goto error_splat_root; |
1645 | 1648 | ||
@@ -1649,9 +1652,12 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1649 | error = 0; | 1652 | error = 0; |
1650 | 1653 | ||
1651 | out: | 1654 | out: |
1652 | kfree(data.nfs_server.hostname); | 1655 | kfree(data->nfs_server.hostname); |
1653 | kfree(data.mount_server.hostname); | 1656 | kfree(data->mount_server.hostname); |
1654 | security_free_mnt_opts(&data.lsm_opts); | 1657 | security_free_mnt_opts(&data->lsm_opts); |
1658 | out_free_fh: | ||
1659 | kfree(mntfh); | ||
1660 | kfree(data); | ||
1655 | return error; | 1661 | return error; |
1656 | 1662 | ||
1657 | out_err_nosb: | 1663 | out_err_nosb: |
@@ -1800,8 +1806,6 @@ static int nfs4_validate_mount_data(void *options, | |||
1800 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; | 1806 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; |
1801 | char *c; | 1807 | char *c; |
1802 | 1808 | ||
1803 | memset(args, 0, sizeof(*args)); | ||
1804 | |||
1805 | if (data == NULL) | 1809 | if (data == NULL) |
1806 | goto out_no_data; | 1810 | goto out_no_data; |
1807 | 1811 | ||
@@ -1959,26 +1963,31 @@ out_no_client_address: | |||
1959 | static int nfs4_get_sb(struct file_system_type *fs_type, | 1963 | static int nfs4_get_sb(struct file_system_type *fs_type, |
1960 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) | 1964 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
1961 | { | 1965 | { |
1962 | struct nfs_parsed_mount_data data; | 1966 | struct nfs_parsed_mount_data *data; |
1963 | struct super_block *s; | 1967 | struct super_block *s; |
1964 | struct nfs_server *server; | 1968 | struct nfs_server *server; |
1965 | struct nfs_fh mntfh; | 1969 | struct nfs_fh *mntfh; |
1966 | struct dentry *mntroot; | 1970 | struct dentry *mntroot; |
1967 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; | 1971 | int (*compare_super)(struct super_block *, void *) = nfs_compare_super; |
1968 | struct nfs_sb_mountdata sb_mntdata = { | 1972 | struct nfs_sb_mountdata sb_mntdata = { |
1969 | .mntflags = flags, | 1973 | .mntflags = flags, |
1970 | }; | 1974 | }; |
1971 | int error; | 1975 | int error = -ENOMEM; |
1972 | 1976 | ||
1973 | security_init_mnt_opts(&data.lsm_opts); | 1977 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
1978 | mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); | ||
1979 | if (data == NULL || mntfh == NULL) | ||
1980 | goto out_free_fh; | ||
1981 | |||
1982 | security_init_mnt_opts(&data->lsm_opts); | ||
1974 | 1983 | ||
1975 | /* Validate the mount data */ | 1984 | /* Validate the mount data */ |
1976 | error = nfs4_validate_mount_data(raw_data, &data, dev_name); | 1985 | error = nfs4_validate_mount_data(raw_data, data, dev_name); |
1977 | if (error < 0) | 1986 | if (error < 0) |
1978 | goto out; | 1987 | goto out; |
1979 | 1988 | ||
1980 | /* Get a volume representation */ | 1989 | /* Get a volume representation */ |
1981 | server = nfs4_create_server(&data, &mntfh); | 1990 | server = nfs4_create_server(data, mntfh); |
1982 | if (IS_ERR(server)) { | 1991 | if (IS_ERR(server)) { |
1983 | error = PTR_ERR(server); | 1992 | error = PTR_ERR(server); |
1984 | goto out; | 1993 | goto out; |
@@ -2009,13 +2018,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
2009 | nfs4_fill_super(s); | 2018 | nfs4_fill_super(s); |
2010 | } | 2019 | } |
2011 | 2020 | ||
2012 | mntroot = nfs4_get_root(s, &mntfh); | 2021 | mntroot = nfs4_get_root(s, mntfh); |
2013 | if (IS_ERR(mntroot)) { | 2022 | if (IS_ERR(mntroot)) { |
2014 | error = PTR_ERR(mntroot); | 2023 | error = PTR_ERR(mntroot); |
2015 | goto error_splat_super; | 2024 | goto error_splat_super; |
2016 | } | 2025 | } |
2017 | 2026 | ||
2018 | error = security_sb_set_mnt_opts(s, &data.lsm_opts); | 2027 | error = security_sb_set_mnt_opts(s, &data->lsm_opts); |
2019 | if (error) | 2028 | if (error) |
2020 | goto error_splat_root; | 2029 | goto error_splat_root; |
2021 | 2030 | ||
@@ -2025,10 +2034,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
2025 | error = 0; | 2034 | error = 0; |
2026 | 2035 | ||
2027 | out: | 2036 | out: |
2028 | kfree(data.client_address); | 2037 | kfree(data->client_address); |
2029 | kfree(data.nfs_server.export_path); | 2038 | kfree(data->nfs_server.export_path); |
2030 | kfree(data.nfs_server.hostname); | 2039 | kfree(data->nfs_server.hostname); |
2031 | security_free_mnt_opts(&data.lsm_opts); | 2040 | security_free_mnt_opts(&data->lsm_opts); |
2041 | out_free_fh: | ||
2042 | kfree(mntfh); | ||
2043 | kfree(data); | ||
2032 | return error; | 2044 | return error; |
2033 | 2045 | ||
2034 | out_free: | 2046 | out_free: |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 6d8ace3e3259..f333848fd3be 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -739,12 +739,13 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
739 | } | 739 | } |
740 | 740 | ||
741 | status = nfs_writepage_setup(ctx, page, offset, count); | 741 | status = nfs_writepage_setup(ctx, page, offset, count); |
742 | __set_page_dirty_nobuffers(page); | 742 | if (status < 0) |
743 | nfs_set_pageerror(page); | ||
744 | else | ||
745 | __set_page_dirty_nobuffers(page); | ||
743 | 746 | ||
744 | dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", | 747 | dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", |
745 | status, (long long)i_size_read(inode)); | 748 | status, (long long)i_size_read(inode)); |
746 | if (status < 0) | ||
747 | nfs_set_pageerror(page); | ||
748 | return status; | 749 | return status; |
749 | } | 750 | } |
750 | 751 | ||
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index cf9401e8cd0b..cfdb08b484ed 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/sysctl.h> | ||
25 | #include <linux/configfs.h> | 24 | #include <linux/configfs.h> |
26 | 25 | ||
27 | #include "tcp.h" | 26 | #include "tcp.h" |
@@ -36,65 +35,6 @@ | |||
36 | * cluster references throughout where nodes are looked up */ | 35 | * cluster references throughout where nodes are looked up */ |
37 | struct o2nm_cluster *o2nm_single_cluster = NULL; | 36 | struct o2nm_cluster *o2nm_single_cluster = NULL; |
38 | 37 | ||
39 | #define OCFS2_MAX_HB_CTL_PATH 256 | ||
40 | static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl"; | ||
41 | |||
42 | static ctl_table ocfs2_nm_table[] = { | ||
43 | { | ||
44 | .ctl_name = 1, | ||
45 | .procname = "hb_ctl_path", | ||
46 | .data = ocfs2_hb_ctl_path, | ||
47 | .maxlen = OCFS2_MAX_HB_CTL_PATH, | ||
48 | .mode = 0644, | ||
49 | .proc_handler = &proc_dostring, | ||
50 | .strategy = &sysctl_string, | ||
51 | }, | ||
52 | { .ctl_name = 0 } | ||
53 | }; | ||
54 | |||
55 | static ctl_table ocfs2_mod_table[] = { | ||
56 | { | ||
57 | .ctl_name = FS_OCFS2_NM, | ||
58 | .procname = "nm", | ||
59 | .data = NULL, | ||
60 | .maxlen = 0, | ||
61 | .mode = 0555, | ||
62 | .child = ocfs2_nm_table | ||
63 | }, | ||
64 | { .ctl_name = 0} | ||
65 | }; | ||
66 | |||
67 | static ctl_table ocfs2_kern_table[] = { | ||
68 | { | ||
69 | .ctl_name = FS_OCFS2, | ||
70 | .procname = "ocfs2", | ||
71 | .data = NULL, | ||
72 | .maxlen = 0, | ||
73 | .mode = 0555, | ||
74 | .child = ocfs2_mod_table | ||
75 | }, | ||
76 | { .ctl_name = 0} | ||
77 | }; | ||
78 | |||
79 | static ctl_table ocfs2_root_table[] = { | ||
80 | { | ||
81 | .ctl_name = CTL_FS, | ||
82 | .procname = "fs", | ||
83 | .data = NULL, | ||
84 | .maxlen = 0, | ||
85 | .mode = 0555, | ||
86 | .child = ocfs2_kern_table | ||
87 | }, | ||
88 | { .ctl_name = 0 } | ||
89 | }; | ||
90 | |||
91 | static struct ctl_table_header *ocfs2_table_header = NULL; | ||
92 | |||
93 | const char *o2nm_get_hb_ctl_path(void) | ||
94 | { | ||
95 | return ocfs2_hb_ctl_path; | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path); | ||
98 | 38 | ||
99 | struct o2nm_node *o2nm_get_node_by_num(u8 node_num) | 39 | struct o2nm_node *o2nm_get_node_by_num(u8 node_num) |
100 | { | 40 | { |
@@ -941,9 +881,6 @@ void o2nm_undepend_this_node(void) | |||
941 | 881 | ||
942 | static void __exit exit_o2nm(void) | 882 | static void __exit exit_o2nm(void) |
943 | { | 883 | { |
944 | if (ocfs2_table_header) | ||
945 | unregister_sysctl_table(ocfs2_table_header); | ||
946 | |||
947 | /* XXX sync with hb callbacks and shut down hb? */ | 884 | /* XXX sync with hb callbacks and shut down hb? */ |
948 | o2net_unregister_hb_callbacks(); | 885 | o2net_unregister_hb_callbacks(); |
949 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); | 886 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); |
@@ -964,16 +901,9 @@ static int __init init_o2nm(void) | |||
964 | if (ret) | 901 | if (ret) |
965 | goto out; | 902 | goto out; |
966 | 903 | ||
967 | ocfs2_table_header = register_sysctl_table(ocfs2_root_table); | ||
968 | if (!ocfs2_table_header) { | ||
969 | printk(KERN_ERR "nodemanager: unable to register sysctl\n"); | ||
970 | ret = -ENOMEM; /* or something. */ | ||
971 | goto out_o2net; | ||
972 | } | ||
973 | |||
974 | ret = o2net_register_hb_callbacks(); | 904 | ret = o2net_register_hb_callbacks(); |
975 | if (ret) | 905 | if (ret) |
976 | goto out_sysctl; | 906 | goto out_o2net; |
977 | 907 | ||
978 | config_group_init(&o2nm_cluster_group.cs_subsys.su_group); | 908 | config_group_init(&o2nm_cluster_group.cs_subsys.su_group); |
979 | mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); | 909 | mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); |
@@ -990,8 +920,6 @@ static int __init init_o2nm(void) | |||
990 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); | 920 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); |
991 | out_callbacks: | 921 | out_callbacks: |
992 | o2net_unregister_hb_callbacks(); | 922 | o2net_unregister_hb_callbacks(); |
993 | out_sysctl: | ||
994 | unregister_sysctl_table(ocfs2_table_header); | ||
995 | out_o2net: | 923 | out_o2net: |
996 | o2net_exit(); | 924 | o2net_exit(); |
997 | out: | 925 | out: |
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h index 7c860361b8dd..c992ea0da4ad 100644 --- a/fs/ocfs2/cluster/nodemanager.h +++ b/fs/ocfs2/cluster/nodemanager.h | |||
@@ -33,10 +33,6 @@ | |||
33 | #include <linux/configfs.h> | 33 | #include <linux/configfs.h> |
34 | #include <linux/rbtree.h> | 34 | #include <linux/rbtree.h> |
35 | 35 | ||
36 | #define FS_OCFS2_NM 1 | ||
37 | |||
38 | const char *o2nm_get_hb_ctl_path(void); | ||
39 | |||
40 | struct o2nm_node { | 36 | struct o2nm_node { |
41 | spinlock_t nd_lock; | 37 | spinlock_t nd_lock; |
42 | struct config_item nd_item; | 38 | struct config_item nd_item; |
diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c index bbd1667aa7d3..fcd120f1493a 100644 --- a/fs/ocfs2/stack_o2cb.c +++ b/fs/ocfs2/stack_o2cb.c | |||
@@ -317,8 +317,7 @@ out: | |||
317 | return rc; | 317 | return rc; |
318 | } | 318 | } |
319 | 319 | ||
320 | static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn, | 320 | static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn) |
321 | int hangup_pending) | ||
322 | { | 321 | { |
323 | struct dlm_ctxt *dlm = conn->cc_lockspace; | 322 | struct dlm_ctxt *dlm = conn->cc_lockspace; |
324 | struct o2dlm_private *priv = conn->cc_private; | 323 | struct o2dlm_private *priv = conn->cc_private; |
@@ -333,43 +332,6 @@ static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn, | |||
333 | return 0; | 332 | return 0; |
334 | } | 333 | } |
335 | 334 | ||
336 | static void o2hb_stop(const char *group) | ||
337 | { | ||
338 | int ret; | ||
339 | char *argv[5], *envp[3]; | ||
340 | |||
341 | argv[0] = (char *)o2nm_get_hb_ctl_path(); | ||
342 | argv[1] = "-K"; | ||
343 | argv[2] = "-u"; | ||
344 | argv[3] = (char *)group; | ||
345 | argv[4] = NULL; | ||
346 | |||
347 | mlog(0, "Run: %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]); | ||
348 | |||
349 | /* minimal command environment taken from cpu_run_sbin_hotplug */ | ||
350 | envp[0] = "HOME=/"; | ||
351 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | ||
352 | envp[2] = NULL; | ||
353 | |||
354 | ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); | ||
355 | if (ret < 0) | ||
356 | mlog_errno(ret); | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * Hangup is a hack for tools compatibility. Older ocfs2-tools software | ||
361 | * expects the filesystem to call "ocfs2_hb_ctl" during unmount. This | ||
362 | * happens regardless of whether the DLM got started, so we can't do it | ||
363 | * in ocfs2_cluster_disconnect(). We bring the o2hb_stop() function into | ||
364 | * the glue and provide a "hangup" API for super.c to call. | ||
365 | * | ||
366 | * Other stacks will eventually provide a NULL ->hangup() pointer. | ||
367 | */ | ||
368 | static void o2cb_cluster_hangup(const char *group, int grouplen) | ||
369 | { | ||
370 | o2hb_stop(group); | ||
371 | } | ||
372 | |||
373 | static int o2cb_cluster_this_node(unsigned int *node) | 335 | static int o2cb_cluster_this_node(unsigned int *node) |
374 | { | 336 | { |
375 | int node_num; | 337 | int node_num; |
@@ -388,7 +350,6 @@ static int o2cb_cluster_this_node(unsigned int *node) | |||
388 | static struct ocfs2_stack_operations o2cb_stack_ops = { | 350 | static struct ocfs2_stack_operations o2cb_stack_ops = { |
389 | .connect = o2cb_cluster_connect, | 351 | .connect = o2cb_cluster_connect, |
390 | .disconnect = o2cb_cluster_disconnect, | 352 | .disconnect = o2cb_cluster_disconnect, |
391 | .hangup = o2cb_cluster_hangup, | ||
392 | .this_node = o2cb_cluster_this_node, | 353 | .this_node = o2cb_cluster_this_node, |
393 | .dlm_lock = o2cb_dlm_lock, | 354 | .dlm_lock = o2cb_dlm_lock, |
394 | .dlm_unlock = o2cb_dlm_unlock, | 355 | .dlm_unlock = o2cb_dlm_unlock, |
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index 6b97d11f6bf8..c021280dd462 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c | |||
@@ -816,8 +816,7 @@ out: | |||
816 | return rc; | 816 | return rc; |
817 | } | 817 | } |
818 | 818 | ||
819 | static int user_cluster_disconnect(struct ocfs2_cluster_connection *conn, | 819 | static int user_cluster_disconnect(struct ocfs2_cluster_connection *conn) |
820 | int hangup_pending) | ||
821 | { | 820 | { |
822 | dlm_release_lockspace(conn->cc_lockspace, 2); | 821 | dlm_release_lockspace(conn->cc_lockspace, 2); |
823 | conn->cc_lockspace = NULL; | 822 | conn->cc_lockspace = NULL; |
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index 119f60cea9cc..10e149ae5e3a 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/kobject.h> | 27 | #include <linux/kobject.h> |
28 | #include <linux/sysfs.h> | 28 | #include <linux/sysfs.h> |
29 | #include <linux/sysctl.h> | ||
29 | 30 | ||
30 | #include "ocfs2_fs.h" | 31 | #include "ocfs2_fs.h" |
31 | 32 | ||
@@ -33,11 +34,13 @@ | |||
33 | 34 | ||
34 | #define OCFS2_STACK_PLUGIN_O2CB "o2cb" | 35 | #define OCFS2_STACK_PLUGIN_O2CB "o2cb" |
35 | #define OCFS2_STACK_PLUGIN_USER "user" | 36 | #define OCFS2_STACK_PLUGIN_USER "user" |
37 | #define OCFS2_MAX_HB_CTL_PATH 256 | ||
36 | 38 | ||
37 | static struct ocfs2_locking_protocol *lproto; | 39 | static struct ocfs2_locking_protocol *lproto; |
38 | static DEFINE_SPINLOCK(ocfs2_stack_lock); | 40 | static DEFINE_SPINLOCK(ocfs2_stack_lock); |
39 | static LIST_HEAD(ocfs2_stack_list); | 41 | static LIST_HEAD(ocfs2_stack_list); |
40 | static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1]; | 42 | static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1]; |
43 | static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl"; | ||
41 | 44 | ||
42 | /* | 45 | /* |
43 | * The stack currently in use. If not null, active_stack->sp_count > 0, | 46 | * The stack currently in use. If not null, active_stack->sp_count > 0, |
@@ -349,7 +352,7 @@ int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn, | |||
349 | 352 | ||
350 | BUG_ON(conn == NULL); | 353 | BUG_ON(conn == NULL); |
351 | 354 | ||
352 | ret = active_stack->sp_ops->disconnect(conn, hangup_pending); | 355 | ret = active_stack->sp_ops->disconnect(conn); |
353 | 356 | ||
354 | /* XXX Should we free it anyway? */ | 357 | /* XXX Should we free it anyway? */ |
355 | if (!ret) { | 358 | if (!ret) { |
@@ -362,13 +365,48 @@ int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn, | |||
362 | } | 365 | } |
363 | EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect); | 366 | EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect); |
364 | 367 | ||
368 | /* | ||
369 | * Leave the group for this filesystem. This is executed by a userspace | ||
370 | * program (stored in ocfs2_hb_ctl_path). | ||
371 | */ | ||
372 | static void ocfs2_leave_group(const char *group) | ||
373 | { | ||
374 | int ret; | ||
375 | char *argv[5], *envp[3]; | ||
376 | |||
377 | argv[0] = ocfs2_hb_ctl_path; | ||
378 | argv[1] = "-K"; | ||
379 | argv[2] = "-u"; | ||
380 | argv[3] = (char *)group; | ||
381 | argv[4] = NULL; | ||
382 | |||
383 | /* minimal command environment taken from cpu_run_sbin_hotplug */ | ||
384 | envp[0] = "HOME=/"; | ||
385 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | ||
386 | envp[2] = NULL; | ||
387 | |||
388 | ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); | ||
389 | if (ret < 0) { | ||
390 | printk(KERN_ERR | ||
391 | "ocfs2: Error %d running user helper " | ||
392 | "\"%s %s %s %s\"\n", | ||
393 | ret, argv[0], argv[1], argv[2], argv[3]); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * Hangup is a required post-umount. ocfs2-tools software expects the | ||
399 | * filesystem to call "ocfs2_hb_ctl" during unmount. This happens | ||
400 | * regardless of whether the DLM got started, so we can't do it | ||
401 | * in ocfs2_cluster_disconnect(). The ocfs2_leave_group() function does | ||
402 | * the actual work. | ||
403 | */ | ||
365 | void ocfs2_cluster_hangup(const char *group, int grouplen) | 404 | void ocfs2_cluster_hangup(const char *group, int grouplen) |
366 | { | 405 | { |
367 | BUG_ON(group == NULL); | 406 | BUG_ON(group == NULL); |
368 | BUG_ON(group[grouplen] != '\0'); | 407 | BUG_ON(group[grouplen] != '\0'); |
369 | 408 | ||
370 | if (active_stack->sp_ops->hangup) | 409 | ocfs2_leave_group(group); |
371 | active_stack->sp_ops->hangup(group, grouplen); | ||
372 | 410 | ||
373 | /* cluster_disconnect() was called with hangup_pending==1 */ | 411 | /* cluster_disconnect() was called with hangup_pending==1 */ |
374 | ocfs2_stack_driver_put(); | 412 | ocfs2_stack_driver_put(); |
@@ -548,10 +586,83 @@ error: | |||
548 | return ret; | 586 | return ret; |
549 | } | 587 | } |
550 | 588 | ||
589 | /* | ||
590 | * Sysctl bits | ||
591 | * | ||
592 | * The sysctl lives at /proc/sys/fs/ocfs2/nm/hb_ctl_path. The 'nm' doesn't | ||
593 | * make as much sense in a multiple cluster stack world, but it's safer | ||
594 | * and easier to preserve the name. | ||
595 | */ | ||
596 | |||
597 | #define FS_OCFS2_NM 1 | ||
598 | |||
599 | static ctl_table ocfs2_nm_table[] = { | ||
600 | { | ||
601 | .ctl_name = 1, | ||
602 | .procname = "hb_ctl_path", | ||
603 | .data = ocfs2_hb_ctl_path, | ||
604 | .maxlen = OCFS2_MAX_HB_CTL_PATH, | ||
605 | .mode = 0644, | ||
606 | .proc_handler = &proc_dostring, | ||
607 | .strategy = &sysctl_string, | ||
608 | }, | ||
609 | { .ctl_name = 0 } | ||
610 | }; | ||
611 | |||
612 | static ctl_table ocfs2_mod_table[] = { | ||
613 | { | ||
614 | .ctl_name = FS_OCFS2_NM, | ||
615 | .procname = "nm", | ||
616 | .data = NULL, | ||
617 | .maxlen = 0, | ||
618 | .mode = 0555, | ||
619 | .child = ocfs2_nm_table | ||
620 | }, | ||
621 | { .ctl_name = 0} | ||
622 | }; | ||
623 | |||
624 | static ctl_table ocfs2_kern_table[] = { | ||
625 | { | ||
626 | .ctl_name = FS_OCFS2, | ||
627 | .procname = "ocfs2", | ||
628 | .data = NULL, | ||
629 | .maxlen = 0, | ||
630 | .mode = 0555, | ||
631 | .child = ocfs2_mod_table | ||
632 | }, | ||
633 | { .ctl_name = 0} | ||
634 | }; | ||
635 | |||
636 | static ctl_table ocfs2_root_table[] = { | ||
637 | { | ||
638 | .ctl_name = CTL_FS, | ||
639 | .procname = "fs", | ||
640 | .data = NULL, | ||
641 | .maxlen = 0, | ||
642 | .mode = 0555, | ||
643 | .child = ocfs2_kern_table | ||
644 | }, | ||
645 | { .ctl_name = 0 } | ||
646 | }; | ||
647 | |||
648 | static struct ctl_table_header *ocfs2_table_header = NULL; | ||
649 | |||
650 | |||
651 | /* | ||
652 | * Initialization | ||
653 | */ | ||
654 | |||
551 | static int __init ocfs2_stack_glue_init(void) | 655 | static int __init ocfs2_stack_glue_init(void) |
552 | { | 656 | { |
553 | strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB); | 657 | strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB); |
554 | 658 | ||
659 | ocfs2_table_header = register_sysctl_table(ocfs2_root_table); | ||
660 | if (!ocfs2_table_header) { | ||
661 | printk(KERN_ERR | ||
662 | "ocfs2 stack glue: unable to register sysctl\n"); | ||
663 | return -ENOMEM; /* or something. */ | ||
664 | } | ||
665 | |||
555 | return ocfs2_sysfs_init(); | 666 | return ocfs2_sysfs_init(); |
556 | } | 667 | } |
557 | 668 | ||
@@ -559,6 +670,8 @@ static void __exit ocfs2_stack_glue_exit(void) | |||
559 | { | 670 | { |
560 | lproto = NULL; | 671 | lproto = NULL; |
561 | ocfs2_sysfs_exit(); | 672 | ocfs2_sysfs_exit(); |
673 | if (ocfs2_table_header) | ||
674 | unregister_sysctl_table(ocfs2_table_header); | ||
562 | } | 675 | } |
563 | 676 | ||
564 | MODULE_AUTHOR("Oracle"); | 677 | MODULE_AUTHOR("Oracle"); |
diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h index 005e4f170e0f..db56281dd1be 100644 --- a/fs/ocfs2/stackglue.h +++ b/fs/ocfs2/stackglue.h | |||
@@ -134,22 +134,10 @@ struct ocfs2_stack_operations { | |||
134 | * be freed. Thus, a stack must not return from ->disconnect() | 134 | * be freed. Thus, a stack must not return from ->disconnect() |
135 | * until it will no longer reference the conn pointer. | 135 | * until it will no longer reference the conn pointer. |
136 | * | 136 | * |
137 | * If hangup_pending is zero, ocfs2_cluster_disconnect() will also | 137 | * Once this call returns, the stack glue will be dropping this |
138 | * be dropping the reference on the module. | 138 | * connection's reference on the module. |
139 | */ | 139 | */ |
140 | int (*disconnect)(struct ocfs2_cluster_connection *conn, | 140 | int (*disconnect)(struct ocfs2_cluster_connection *conn); |
141 | int hangup_pending); | ||
142 | |||
143 | /* | ||
144 | * ocfs2_cluster_hangup() exists for compatibility with older | ||
145 | * ocfs2 tools. Only the classic stack really needs it. As such | ||
146 | * ->hangup() is not required of all stacks. See the comment by | ||
147 | * ocfs2_cluster_hangup() for more details. | ||
148 | * | ||
149 | * Note that ocfs2_cluster_hangup() can only be called if | ||
150 | * hangup_pending was passed to ocfs2_cluster_disconnect(). | ||
151 | */ | ||
152 | void (*hangup)(const char *group, int grouplen); | ||
153 | 141 | ||
154 | /* | 142 | /* |
155 | * ->this_node() returns the cluster's unique identifier for the | 143 | * ->this_node() returns the cluster's unique identifier for the |
@@ -258,4 +246,5 @@ void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto) | |||
258 | /* Used by stack plugins */ | 246 | /* Used by stack plugins */ |
259 | int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin); | 247 | int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin); |
260 | void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin); | 248 | void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin); |
249 | |||
261 | #endif /* STACKGLUE_H */ | 250 | #endif /* STACKGLUE_H */ |
@@ -1003,8 +1003,7 @@ struct file *create_write_pipe(void) | |||
1003 | void free_write_pipe(struct file *f) | 1003 | void free_write_pipe(struct file *f) |
1004 | { | 1004 | { |
1005 | free_pipe_info(f->f_dentry->d_inode); | 1005 | free_pipe_info(f->f_dentry->d_inode); |
1006 | dput(f->f_path.dentry); | 1006 | path_put(&f->f_path); |
1007 | mntput(f->f_path.mnt); | ||
1008 | put_filp(f); | 1007 | put_filp(f); |
1009 | } | 1008 | } |
1010 | 1009 | ||
@@ -1015,8 +1014,8 @@ struct file *create_read_pipe(struct file *wrf) | |||
1015 | return ERR_PTR(-ENFILE); | 1014 | return ERR_PTR(-ENFILE); |
1016 | 1015 | ||
1017 | /* Grab pipe from the writer */ | 1016 | /* Grab pipe from the writer */ |
1018 | f->f_path.mnt = mntget(wrf->f_path.mnt); | 1017 | f->f_path = wrf->f_path; |
1019 | f->f_path.dentry = dget(wrf->f_path.dentry); | 1018 | path_get(&wrf->f_path); |
1020 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; | 1019 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; |
1021 | 1020 | ||
1022 | f->f_pos = 0; | 1021 | f->f_pos = 0; |
@@ -1068,8 +1067,7 @@ int do_pipe(int *fd) | |||
1068 | err_fdr: | 1067 | err_fdr: |
1069 | put_unused_fd(fdr); | 1068 | put_unused_fd(fdr); |
1070 | err_read_pipe: | 1069 | err_read_pipe: |
1071 | dput(fr->f_dentry); | 1070 | path_put(&fr->f_path); |
1072 | mntput(fr->f_vfsmnt); | ||
1073 | put_filp(fr); | 1071 | put_filp(fr); |
1074 | err_write_pipe: | 1072 | err_write_pipe: |
1075 | free_write_pipe(fw); | 1073 | free_write_pipe(fw); |
diff --git a/fs/select.c b/fs/select.c index 8dda969614a9..da0e88201c3a 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -249,7 +249,6 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) | |||
249 | retval++; | 249 | retval++; |
250 | } | 250 | } |
251 | } | 251 | } |
252 | cond_resched(); | ||
253 | } | 252 | } |
254 | if (res_in) | 253 | if (res_in) |
255 | *rinp = res_in; | 254 | *rinp = res_in; |
@@ -257,6 +256,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout) | |||
257 | *routp = res_out; | 256 | *routp = res_out; |
258 | if (res_ex) | 257 | if (res_ex) |
259 | *rexp = res_ex; | 258 | *rexp = res_ex; |
259 | cond_resched(); | ||
260 | } | 260 | } |
261 | wait = NULL; | 261 | wait = NULL; |
262 | if (retval || !*timeout || signal_pending(current)) | 262 | if (retval || !*timeout || signal_pending(current)) |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 7a5f69be6ac2..44cc702f96cc 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -682,38 +682,26 @@ static int udf_vrs(struct super_block *sb, int silent) | |||
682 | /* | 682 | /* |
683 | * Check whether there is an anchor block in the given block | 683 | * Check whether there is an anchor block in the given block |
684 | */ | 684 | */ |
685 | static int udf_check_anchor_block(struct super_block *sb, sector_t block, | 685 | static int udf_check_anchor_block(struct super_block *sb, sector_t block) |
686 | bool varconv) | ||
687 | { | 686 | { |
688 | struct buffer_head *bh = NULL; | 687 | struct buffer_head *bh; |
689 | tag *t; | ||
690 | uint16_t ident; | 688 | uint16_t ident; |
691 | uint32_t location; | ||
692 | 689 | ||
693 | if (varconv) { | 690 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && |
694 | if (udf_fixed_to_variable(block) >= | 691 | udf_fixed_to_variable(block) >= |
695 | sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) | 692 | sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits) |
696 | return 0; | 693 | return 0; |
697 | bh = sb_bread(sb, udf_fixed_to_variable(block)); | ||
698 | } | ||
699 | else | ||
700 | bh = sb_bread(sb, block); | ||
701 | 694 | ||
695 | bh = udf_read_tagged(sb, block, block, &ident); | ||
702 | if (!bh) | 696 | if (!bh) |
703 | return 0; | 697 | return 0; |
704 | |||
705 | t = (tag *)bh->b_data; | ||
706 | ident = le16_to_cpu(t->tagIdent); | ||
707 | location = le32_to_cpu(t->tagLocation); | ||
708 | brelse(bh); | 698 | brelse(bh); |
709 | if (ident != TAG_IDENT_AVDP) | 699 | |
710 | return 0; | 700 | return ident == TAG_IDENT_AVDP; |
711 | return location == block; | ||
712 | } | 701 | } |
713 | 702 | ||
714 | /* Search for an anchor volume descriptor pointer */ | 703 | /* Search for an anchor volume descriptor pointer */ |
715 | static sector_t udf_scan_anchors(struct super_block *sb, bool varconv, | 704 | static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) |
716 | sector_t lastblock) | ||
717 | { | 705 | { |
718 | sector_t last[6]; | 706 | sector_t last[6]; |
719 | int i; | 707 | int i; |
@@ -739,7 +727,7 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv, | |||
739 | sb->s_blocksize_bits) | 727 | sb->s_blocksize_bits) |
740 | continue; | 728 | continue; |
741 | 729 | ||
742 | if (udf_check_anchor_block(sb, last[i], varconv)) { | 730 | if (udf_check_anchor_block(sb, last[i])) { |
743 | sbi->s_anchor[0] = last[i]; | 731 | sbi->s_anchor[0] = last[i]; |
744 | sbi->s_anchor[1] = last[i] - 256; | 732 | sbi->s_anchor[1] = last[i] - 256; |
745 | return last[i]; | 733 | return last[i]; |
@@ -748,17 +736,17 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv, | |||
748 | if (last[i] < 256) | 736 | if (last[i] < 256) |
749 | continue; | 737 | continue; |
750 | 738 | ||
751 | if (udf_check_anchor_block(sb, last[i] - 256, varconv)) { | 739 | if (udf_check_anchor_block(sb, last[i] - 256)) { |
752 | sbi->s_anchor[1] = last[i] - 256; | 740 | sbi->s_anchor[1] = last[i] - 256; |
753 | return last[i]; | 741 | return last[i]; |
754 | } | 742 | } |
755 | } | 743 | } |
756 | 744 | ||
757 | if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) { | 745 | if (udf_check_anchor_block(sb, sbi->s_session + 256)) { |
758 | sbi->s_anchor[0] = sbi->s_session + 256; | 746 | sbi->s_anchor[0] = sbi->s_session + 256; |
759 | return last[0]; | 747 | return last[0]; |
760 | } | 748 | } |
761 | if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) { | 749 | if (udf_check_anchor_block(sb, sbi->s_session + 512)) { |
762 | sbi->s_anchor[0] = sbi->s_session + 512; | 750 | sbi->s_anchor[0] = sbi->s_session + 512; |
763 | return last[0]; | 751 | return last[0]; |
764 | } | 752 | } |
@@ -780,23 +768,24 @@ static void udf_find_anchor(struct super_block *sb) | |||
780 | int i; | 768 | int i; |
781 | struct udf_sb_info *sbi = UDF_SB(sb); | 769 | struct udf_sb_info *sbi = UDF_SB(sb); |
782 | 770 | ||
783 | lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block); | 771 | lastblock = udf_scan_anchors(sb, sbi->s_last_block); |
784 | if (lastblock) | 772 | if (lastblock) |
785 | goto check_anchor; | 773 | goto check_anchor; |
786 | 774 | ||
787 | /* No anchor found? Try VARCONV conversion of block numbers */ | 775 | /* No anchor found? Try VARCONV conversion of block numbers */ |
776 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
788 | /* Firstly, we try to not convert number of the last block */ | 777 | /* Firstly, we try to not convert number of the last block */ |
789 | lastblock = udf_scan_anchors(sb, 1, | 778 | lastblock = udf_scan_anchors(sb, |
790 | udf_variable_to_fixed(sbi->s_last_block)); | 779 | udf_variable_to_fixed(sbi->s_last_block)); |
791 | if (lastblock) { | 780 | if (lastblock) |
792 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | ||
793 | goto check_anchor; | 781 | goto check_anchor; |
794 | } | ||
795 | 782 | ||
796 | /* Secondly, we try with converted number of the last block */ | 783 | /* Secondly, we try with converted number of the last block */ |
797 | lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block); | 784 | lastblock = udf_scan_anchors(sb, sbi->s_last_block); |
798 | if (lastblock) | 785 | if (!lastblock) { |
799 | UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); | 786 | /* VARCONV didn't help. Clear it. */ |
787 | UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); | ||
788 | } | ||
800 | 789 | ||
801 | check_anchor: | 790 | check_anchor: |
802 | /* | 791 | /* |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 8fa9c2d70911..8ec865de5f13 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define UDF_PREALLOCATE | 16 | #define UDF_PREALLOCATE |
17 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 | 17 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 |
18 | 18 | ||
19 | #define UDFFS_DEBUG | 19 | #undef UDFFS_DEBUG |
20 | 20 | ||
21 | #ifdef UDFFS_DEBUG | 21 | #ifdef UDFFS_DEBUG |
22 | #define udf_debug(f, a...) \ | 22 | #define udf_debug(f, a...) \ |
diff --git a/fs/utimes.c b/fs/utimes.c index af059d5cb485..b6b664e7145e 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -40,14 +40,9 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) | |||
40 | 40 | ||
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | static bool nsec_special(long nsec) | ||
44 | { | ||
45 | return nsec == UTIME_OMIT || nsec == UTIME_NOW; | ||
46 | } | ||
47 | |||
48 | static bool nsec_valid(long nsec) | 43 | static bool nsec_valid(long nsec) |
49 | { | 44 | { |
50 | if (nsec_special(nsec)) | 45 | if (nsec == UTIME_OMIT || nsec == UTIME_NOW) |
51 | return true; | 46 | return true; |
52 | 47 | ||
53 | return nsec >= 0 && nsec <= 999999999; | 48 | return nsec >= 0 && nsec <= 999999999; |
@@ -102,7 +97,11 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags | |||
102 | if (error) | 97 | if (error) |
103 | goto dput_and_out; | 98 | goto dput_and_out; |
104 | 99 | ||
105 | /* Don't worry, the checks are done in inode_change_ok() */ | 100 | if (times && times[0].tv_nsec == UTIME_NOW && |
101 | times[1].tv_nsec == UTIME_NOW) | ||
102 | times = NULL; | ||
103 | |||
104 | /* In most cases, the checks are done in inode_change_ok() */ | ||
106 | newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; | 105 | newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; |
107 | if (times) { | 106 | if (times) { |
108 | error = -EPERM; | 107 | error = -EPERM; |
@@ -124,28 +123,34 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags | |||
124 | newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; | 123 | newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; |
125 | newattrs.ia_valid |= ATTR_MTIME_SET; | 124 | newattrs.ia_valid |= ATTR_MTIME_SET; |
126 | } | 125 | } |
127 | } | ||
128 | 126 | ||
129 | /* | 127 | /* |
130 | * If times is NULL or both times are either UTIME_OMIT or | 128 | * For the UTIME_OMIT/UTIME_NOW and UTIME_NOW/UTIME_OMIT |
131 | * UTIME_NOW, then need to check permissions, because | 129 | * cases, we need to make an extra check that is not done by |
132 | * inode_change_ok() won't do it. | 130 | * inode_change_ok(). |
133 | */ | 131 | */ |
134 | if (!times || (nsec_special(times[0].tv_nsec) && | 132 | if (((times[0].tv_nsec == UTIME_NOW && |
135 | nsec_special(times[1].tv_nsec))) { | 133 | times[1].tv_nsec == UTIME_OMIT) |
134 | || | ||
135 | (times[0].tv_nsec == UTIME_OMIT && | ||
136 | times[1].tv_nsec == UTIME_NOW)) | ||
137 | && !is_owner_or_cap(inode)) | ||
138 | goto mnt_drop_write_and_out; | ||
139 | } else { | ||
140 | |||
141 | /* | ||
142 | * If times is NULL (or both times are UTIME_NOW), | ||
143 | * then we need to check permissions, because | ||
144 | * inode_change_ok() won't do it. | ||
145 | */ | ||
136 | error = -EACCES; | 146 | error = -EACCES; |
137 | if (IS_IMMUTABLE(inode)) | 147 | if (IS_IMMUTABLE(inode)) |
138 | goto mnt_drop_write_and_out; | 148 | goto mnt_drop_write_and_out; |
139 | 149 | ||
140 | if (!is_owner_or_cap(inode)) { | 150 | if (!is_owner_or_cap(inode)) { |
141 | if (f) { | 151 | error = permission(inode, MAY_WRITE, NULL); |
142 | if (!(f->f_mode & FMODE_WRITE)) | 152 | if (error) |
143 | goto mnt_drop_write_and_out; | 153 | goto mnt_drop_write_and_out; |
144 | } else { | ||
145 | error = vfs_permission(&nd, MAY_WRITE); | ||
146 | if (error) | ||
147 | goto mnt_drop_write_and_out; | ||
148 | } | ||
149 | } | 154 | } |
150 | } | 155 | } |
151 | mutex_lock(&inode->i_mutex); | 156 | mutex_lock(&inode->i_mutex); |
@@ -169,14 +174,6 @@ asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __ | |||
169 | if (utimes) { | 174 | if (utimes) { |
170 | if (copy_from_user(&tstimes, utimes, sizeof(tstimes))) | 175 | if (copy_from_user(&tstimes, utimes, sizeof(tstimes))) |
171 | return -EFAULT; | 176 | return -EFAULT; |
172 | if ((tstimes[0].tv_nsec == UTIME_OMIT || | ||
173 | tstimes[0].tv_nsec == UTIME_NOW) && | ||
174 | tstimes[0].tv_sec != 0) | ||
175 | return -EINVAL; | ||
176 | if ((tstimes[1].tv_nsec == UTIME_OMIT || | ||
177 | tstimes[1].tv_nsec == UTIME_NOW) && | ||
178 | tstimes[1].tv_sec != 0) | ||
179 | return -EINVAL; | ||
180 | 177 | ||
181 | /* Nothing to do, we must not even check the path. */ | 178 | /* Nothing to do, we must not even check the path. */ |
182 | if (tstimes[0].tv_nsec == UTIME_OMIT && | 179 | if (tstimes[0].tv_nsec == UTIME_OMIT && |