diff options
Diffstat (limited to 'fs')
66 files changed, 489 insertions, 393 deletions
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 1feb68ecef95..842d00048a65 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -94,25 +94,21 @@ static struct dentry *get_next_positive_subdir(struct dentry *prev, | |||
94 | { | 94 | { |
95 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); | 95 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); |
96 | struct list_head *next; | 96 | struct list_head *next; |
97 | struct dentry *p, *q; | 97 | struct dentry *q; |
98 | 98 | ||
99 | spin_lock(&sbi->lookup_lock); | 99 | spin_lock(&sbi->lookup_lock); |
100 | spin_lock(&root->d_lock); | ||
100 | 101 | ||
101 | if (prev == NULL) { | 102 | if (prev) |
102 | spin_lock(&root->d_lock); | 103 | next = prev->d_u.d_child.next; |
104 | else { | ||
103 | prev = dget_dlock(root); | 105 | prev = dget_dlock(root); |
104 | next = prev->d_subdirs.next; | 106 | next = prev->d_subdirs.next; |
105 | p = prev; | ||
106 | goto start; | ||
107 | } | 107 | } |
108 | 108 | ||
109 | p = prev; | 109 | cont: |
110 | spin_lock(&p->d_lock); | ||
111 | again: | ||
112 | next = p->d_u.d_child.next; | ||
113 | start: | ||
114 | if (next == &root->d_subdirs) { | 110 | if (next == &root->d_subdirs) { |
115 | spin_unlock(&p->d_lock); | 111 | spin_unlock(&root->d_lock); |
116 | spin_unlock(&sbi->lookup_lock); | 112 | spin_unlock(&sbi->lookup_lock); |
117 | dput(prev); | 113 | dput(prev); |
118 | return NULL; | 114 | return NULL; |
@@ -121,16 +117,15 @@ start: | |||
121 | q = list_entry(next, struct dentry, d_u.d_child); | 117 | q = list_entry(next, struct dentry, d_u.d_child); |
122 | 118 | ||
123 | spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); | 119 | spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); |
124 | /* Negative dentry - try next */ | 120 | /* Already gone or negative dentry (under construction) - try next */ |
125 | if (!simple_positive(q)) { | 121 | if (q->d_count == 0 || !simple_positive(q)) { |
126 | spin_unlock(&p->d_lock); | 122 | spin_unlock(&q->d_lock); |
127 | lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_); | 123 | next = q->d_u.d_child.next; |
128 | p = q; | 124 | goto cont; |
129 | goto again; | ||
130 | } | 125 | } |
131 | dget_dlock(q); | 126 | dget_dlock(q); |
132 | spin_unlock(&q->d_lock); | 127 | spin_unlock(&q->d_lock); |
133 | spin_unlock(&p->d_lock); | 128 | spin_unlock(&root->d_lock); |
134 | spin_unlock(&sbi->lookup_lock); | 129 | spin_unlock(&sbi->lookup_lock); |
135 | 130 | ||
136 | dput(prev); | 131 | dput(prev); |
@@ -404,11 +399,6 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
404 | DPRINTK("checking mountpoint %p %.*s", | 399 | DPRINTK("checking mountpoint %p %.*s", |
405 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | 400 | dentry, (int)dentry->d_name.len, dentry->d_name.name); |
406 | 401 | ||
407 | /* Path walk currently on this dentry? */ | ||
408 | ino_count = atomic_read(&ino->count) + 2; | ||
409 | if (dentry->d_count > ino_count) | ||
410 | goto next; | ||
411 | |||
412 | /* Can we umount this guy */ | 402 | /* Can we umount this guy */ |
413 | if (autofs4_mount_busy(mnt, dentry)) | 403 | if (autofs4_mount_busy(mnt, dentry)) |
414 | goto next; | 404 | goto next; |
@@ -73,7 +73,7 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) | |||
73 | { | 73 | { |
74 | unsigned int sz = sizeof(struct bio) + extra_size; | 74 | unsigned int sz = sizeof(struct bio) + extra_size; |
75 | struct kmem_cache *slab = NULL; | 75 | struct kmem_cache *slab = NULL; |
76 | struct bio_slab *bslab; | 76 | struct bio_slab *bslab, *new_bio_slabs; |
77 | unsigned int i, entry = -1; | 77 | unsigned int i, entry = -1; |
78 | 78 | ||
79 | mutex_lock(&bio_slab_lock); | 79 | mutex_lock(&bio_slab_lock); |
@@ -97,11 +97,12 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size) | |||
97 | 97 | ||
98 | if (bio_slab_nr == bio_slab_max && entry == -1) { | 98 | if (bio_slab_nr == bio_slab_max && entry == -1) { |
99 | bio_slab_max <<= 1; | 99 | bio_slab_max <<= 1; |
100 | bio_slabs = krealloc(bio_slabs, | 100 | new_bio_slabs = krealloc(bio_slabs, |
101 | bio_slab_max * sizeof(struct bio_slab), | 101 | bio_slab_max * sizeof(struct bio_slab), |
102 | GFP_KERNEL); | 102 | GFP_KERNEL); |
103 | if (!bio_slabs) | 103 | if (!new_bio_slabs) |
104 | goto out_unlock; | 104 | goto out_unlock; |
105 | bio_slabs = new_bio_slabs; | ||
105 | } | 106 | } |
106 | if (entry == -1) | 107 | if (entry == -1) |
107 | entry = bio_slab_nr++; | 108 | entry = bio_slab_nr++; |
@@ -1312,7 +1313,7 @@ EXPORT_SYMBOL(bio_copy_kern); | |||
1312 | * Note that this code is very hard to test under normal circumstances because | 1313 | * Note that this code is very hard to test under normal circumstances because |
1313 | * direct-io pins the pages with get_user_pages(). This makes | 1314 | * direct-io pins the pages with get_user_pages(). This makes |
1314 | * is_page_cache_freeable return false, and the VM will not clean the pages. | 1315 | * is_page_cache_freeable return false, and the VM will not clean the pages. |
1315 | * But other code (eg, pdflush) could clean the pages if they are mapped | 1316 | * But other code (eg, flusher threads) could clean the pages if they are mapped |
1316 | * pagecache. | 1317 | * pagecache. |
1317 | * | 1318 | * |
1318 | * Simply disabling the call to bio_set_pages_dirty() is a good way to test the | 1319 | * Simply disabling the call to bio_set_pages_dirty() is a good way to test the |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 1e519195d45b..38e721b35d45 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -1578,10 +1578,12 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1578 | unsigned long nr_segs, loff_t pos) | 1578 | unsigned long nr_segs, loff_t pos) |
1579 | { | 1579 | { |
1580 | struct file *file = iocb->ki_filp; | 1580 | struct file *file = iocb->ki_filp; |
1581 | struct blk_plug plug; | ||
1581 | ssize_t ret; | 1582 | ssize_t ret; |
1582 | 1583 | ||
1583 | BUG_ON(iocb->ki_pos != pos); | 1584 | BUG_ON(iocb->ki_pos != pos); |
1584 | 1585 | ||
1586 | blk_start_plug(&plug); | ||
1585 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); | 1587 | ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
1586 | if (ret > 0 || ret == -EIOCBQUEUED) { | 1588 | if (ret > 0 || ret == -EIOCBQUEUED) { |
1587 | ssize_t err; | 1589 | ssize_t err; |
@@ -1590,6 +1592,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
1590 | if (err < 0 && ret > 0) | 1592 | if (err < 0 && ret > 0) |
1591 | ret = err; | 1593 | ret = err; |
1592 | } | 1594 | } |
1595 | blk_finish_plug(&plug); | ||
1593 | return ret; | 1596 | return ret; |
1594 | } | 1597 | } |
1595 | EXPORT_SYMBOL_GPL(blkdev_aio_write); | 1598 | EXPORT_SYMBOL_GPL(blkdev_aio_write); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 83baec24946d..6e8f416773d4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -324,7 +324,8 @@ static noinline int add_async_extent(struct async_cow *cow, | |||
324 | * If this code finds it can't get good compression, it puts an | 324 | * If this code finds it can't get good compression, it puts an |
325 | * entry onto the work queue to write the uncompressed bytes. This | 325 | * entry onto the work queue to write the uncompressed bytes. This |
326 | * makes sure that both compressed inodes and uncompressed inodes | 326 | * makes sure that both compressed inodes and uncompressed inodes |
327 | * are written in the same order that pdflush sent them down. | 327 | * are written in the same order that the flusher thread sent them |
328 | * down. | ||
328 | */ | 329 | */ |
329 | static noinline int compress_file_range(struct inode *inode, | 330 | static noinline int compress_file_range(struct inode *inode, |
330 | struct page *locked_page, | 331 | struct page *locked_page, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index bc2f6ffff3cf..7bb755677a22 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -664,10 +664,6 @@ static noinline int btrfs_mksubvol(struct path *parent, | |||
664 | struct dentry *dentry; | 664 | struct dentry *dentry; |
665 | int error; | 665 | int error; |
666 | 666 | ||
667 | error = mnt_want_write(parent->mnt); | ||
668 | if (error) | ||
669 | return error; | ||
670 | |||
671 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | 667 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
672 | 668 | ||
673 | dentry = lookup_one_len(name, parent->dentry, namelen); | 669 | dentry = lookup_one_len(name, parent->dentry, namelen); |
@@ -703,7 +699,6 @@ out_dput: | |||
703 | dput(dentry); | 699 | dput(dentry); |
704 | out_unlock: | 700 | out_unlock: |
705 | mutex_unlock(&dir->i_mutex); | 701 | mutex_unlock(&dir->i_mutex); |
706 | mnt_drop_write(parent->mnt); | ||
707 | return error; | 702 | return error; |
708 | } | 703 | } |
709 | 704 | ||
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 643335a4fe3c..051c7fe551dd 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -596,7 +596,7 @@ void btrfs_start_ordered_extent(struct inode *inode, | |||
596 | /* | 596 | /* |
597 | * pages in the range can be dirty, clean or writeback. We | 597 | * pages in the range can be dirty, clean or writeback. We |
598 | * start IO on any dirty ones so the wait doesn't stall waiting | 598 | * start IO on any dirty ones so the wait doesn't stall waiting |
599 | * for pdflush to find them | 599 | * for the flusher thread to find them |
600 | */ | 600 | */ |
601 | if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags)) | 601 | if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags)) |
602 | filemap_fdatawrite_range(inode->i_mapping, start, end); | 602 | filemap_fdatawrite_range(inode->i_mapping, start, end); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8c6e61d6eed5..f2eb24c477a3 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -100,10 +100,6 @@ static void __save_error_info(struct btrfs_fs_info *fs_info) | |||
100 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; | 100 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; |
101 | } | 101 | } |
102 | 102 | ||
103 | /* NOTE: | ||
104 | * We move write_super stuff at umount in order to avoid deadlock | ||
105 | * for umount hold all lock. | ||
106 | */ | ||
107 | static void save_error_info(struct btrfs_fs_info *fs_info) | 103 | static void save_error_info(struct btrfs_fs_info *fs_info) |
108 | { | 104 | { |
109 | __save_error_info(fs_info); | 105 | __save_error_info(fs_info); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index b8708f994e67..e86ae04abe6a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1744,10 +1744,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1744 | 1744 | ||
1745 | device->fs_devices = root->fs_info->fs_devices; | 1745 | device->fs_devices = root->fs_info->fs_devices; |
1746 | 1746 | ||
1747 | /* | ||
1748 | * we don't want write_supers to jump in here with our device | ||
1749 | * half setup | ||
1750 | */ | ||
1751 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | 1747 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); |
1752 | list_add_rcu(&device->dev_list, &root->fs_info->fs_devices->devices); | 1748 | list_add_rcu(&device->dev_list, &root->fs_info->fs_devices->devices); |
1753 | list_add(&device->dev_alloc_list, | 1749 | list_add(&device->dev_alloc_list, |
diff --git a/fs/buffer.c b/fs/buffer.c index 9f6d2e41281d..58e2e7b77372 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -914,7 +914,7 @@ link_dev_buffers(struct page *page, struct buffer_head *head) | |||
914 | /* | 914 | /* |
915 | * Initialise the state of a blockdev page's buffers. | 915 | * Initialise the state of a blockdev page's buffers. |
916 | */ | 916 | */ |
917 | static void | 917 | static sector_t |
918 | init_page_buffers(struct page *page, struct block_device *bdev, | 918 | init_page_buffers(struct page *page, struct block_device *bdev, |
919 | sector_t block, int size) | 919 | sector_t block, int size) |
920 | { | 920 | { |
@@ -936,33 +936,41 @@ init_page_buffers(struct page *page, struct block_device *bdev, | |||
936 | block++; | 936 | block++; |
937 | bh = bh->b_this_page; | 937 | bh = bh->b_this_page; |
938 | } while (bh != head); | 938 | } while (bh != head); |
939 | |||
940 | /* | ||
941 | * Caller needs to validate requested block against end of device. | ||
942 | */ | ||
943 | return end_block; | ||
939 | } | 944 | } |
940 | 945 | ||
941 | /* | 946 | /* |
942 | * Create the page-cache page that contains the requested block. | 947 | * Create the page-cache page that contains the requested block. |
943 | * | 948 | * |
944 | * This is user purely for blockdev mappings. | 949 | * This is used purely for blockdev mappings. |
945 | */ | 950 | */ |
946 | static struct page * | 951 | static int |
947 | grow_dev_page(struct block_device *bdev, sector_t block, | 952 | grow_dev_page(struct block_device *bdev, sector_t block, |
948 | pgoff_t index, int size) | 953 | pgoff_t index, int size, int sizebits) |
949 | { | 954 | { |
950 | struct inode *inode = bdev->bd_inode; | 955 | struct inode *inode = bdev->bd_inode; |
951 | struct page *page; | 956 | struct page *page; |
952 | struct buffer_head *bh; | 957 | struct buffer_head *bh; |
958 | sector_t end_block; | ||
959 | int ret = 0; /* Will call free_more_memory() */ | ||
953 | 960 | ||
954 | page = find_or_create_page(inode->i_mapping, index, | 961 | page = find_or_create_page(inode->i_mapping, index, |
955 | (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE); | 962 | (mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS)|__GFP_MOVABLE); |
956 | if (!page) | 963 | if (!page) |
957 | return NULL; | 964 | return ret; |
958 | 965 | ||
959 | BUG_ON(!PageLocked(page)); | 966 | BUG_ON(!PageLocked(page)); |
960 | 967 | ||
961 | if (page_has_buffers(page)) { | 968 | if (page_has_buffers(page)) { |
962 | bh = page_buffers(page); | 969 | bh = page_buffers(page); |
963 | if (bh->b_size == size) { | 970 | if (bh->b_size == size) { |
964 | init_page_buffers(page, bdev, block, size); | 971 | end_block = init_page_buffers(page, bdev, |
965 | return page; | 972 | index << sizebits, size); |
973 | goto done; | ||
966 | } | 974 | } |
967 | if (!try_to_free_buffers(page)) | 975 | if (!try_to_free_buffers(page)) |
968 | goto failed; | 976 | goto failed; |
@@ -982,14 +990,14 @@ grow_dev_page(struct block_device *bdev, sector_t block, | |||
982 | */ | 990 | */ |
983 | spin_lock(&inode->i_mapping->private_lock); | 991 | spin_lock(&inode->i_mapping->private_lock); |
984 | link_dev_buffers(page, bh); | 992 | link_dev_buffers(page, bh); |
985 | init_page_buffers(page, bdev, block, size); | 993 | end_block = init_page_buffers(page, bdev, index << sizebits, size); |
986 | spin_unlock(&inode->i_mapping->private_lock); | 994 | spin_unlock(&inode->i_mapping->private_lock); |
987 | return page; | 995 | done: |
988 | 996 | ret = (block < end_block) ? 1 : -ENXIO; | |
989 | failed: | 997 | failed: |
990 | unlock_page(page); | 998 | unlock_page(page); |
991 | page_cache_release(page); | 999 | page_cache_release(page); |
992 | return NULL; | 1000 | return ret; |
993 | } | 1001 | } |
994 | 1002 | ||
995 | /* | 1003 | /* |
@@ -999,7 +1007,6 @@ failed: | |||
999 | static int | 1007 | static int |
1000 | grow_buffers(struct block_device *bdev, sector_t block, int size) | 1008 | grow_buffers(struct block_device *bdev, sector_t block, int size) |
1001 | { | 1009 | { |
1002 | struct page *page; | ||
1003 | pgoff_t index; | 1010 | pgoff_t index; |
1004 | int sizebits; | 1011 | int sizebits; |
1005 | 1012 | ||
@@ -1023,22 +1030,14 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) | |||
1023 | bdevname(bdev, b)); | 1030 | bdevname(bdev, b)); |
1024 | return -EIO; | 1031 | return -EIO; |
1025 | } | 1032 | } |
1026 | block = index << sizebits; | 1033 | |
1027 | /* Create a page with the proper size buffers.. */ | 1034 | /* Create a page with the proper size buffers.. */ |
1028 | page = grow_dev_page(bdev, block, index, size); | 1035 | return grow_dev_page(bdev, block, index, size, sizebits); |
1029 | if (!page) | ||
1030 | return 0; | ||
1031 | unlock_page(page); | ||
1032 | page_cache_release(page); | ||
1033 | return 1; | ||
1034 | } | 1036 | } |
1035 | 1037 | ||
1036 | static struct buffer_head * | 1038 | static struct buffer_head * |
1037 | __getblk_slow(struct block_device *bdev, sector_t block, int size) | 1039 | __getblk_slow(struct block_device *bdev, sector_t block, int size) |
1038 | { | 1040 | { |
1039 | int ret; | ||
1040 | struct buffer_head *bh; | ||
1041 | |||
1042 | /* Size must be multiple of hard sectorsize */ | 1041 | /* Size must be multiple of hard sectorsize */ |
1043 | if (unlikely(size & (bdev_logical_block_size(bdev)-1) || | 1042 | if (unlikely(size & (bdev_logical_block_size(bdev)-1) || |
1044 | (size < 512 || size > PAGE_SIZE))) { | 1043 | (size < 512 || size > PAGE_SIZE))) { |
@@ -1051,21 +1050,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) | |||
1051 | return NULL; | 1050 | return NULL; |
1052 | } | 1051 | } |
1053 | 1052 | ||
1054 | retry: | 1053 | for (;;) { |
1055 | bh = __find_get_block(bdev, block, size); | 1054 | struct buffer_head *bh; |
1056 | if (bh) | 1055 | int ret; |
1057 | return bh; | ||
1058 | 1056 | ||
1059 | ret = grow_buffers(bdev, block, size); | ||
1060 | if (ret == 0) { | ||
1061 | free_more_memory(); | ||
1062 | goto retry; | ||
1063 | } else if (ret > 0) { | ||
1064 | bh = __find_get_block(bdev, block, size); | 1057 | bh = __find_get_block(bdev, block, size); |
1065 | if (bh) | 1058 | if (bh) |
1066 | return bh; | 1059 | return bh; |
1060 | |||
1061 | ret = grow_buffers(bdev, block, size); | ||
1062 | if (ret < 0) | ||
1063 | return NULL; | ||
1064 | if (ret == 0) | ||
1065 | free_more_memory(); | ||
1067 | } | 1066 | } |
1068 | return NULL; | ||
1069 | } | 1067 | } |
1070 | 1068 | ||
1071 | /* | 1069 | /* |
@@ -1321,10 +1319,6 @@ EXPORT_SYMBOL(__find_get_block); | |||
1321 | * which corresponds to the passed block_device, block and size. The | 1319 | * which corresponds to the passed block_device, block and size. The |
1322 | * returned buffer has its reference count incremented. | 1320 | * returned buffer has its reference count incremented. |
1323 | * | 1321 | * |
1324 | * __getblk() cannot fail - it just keeps trying. If you pass it an | ||
1325 | * illegal block number, __getblk() will happily return a buffer_head | ||
1326 | * which represents the non-existent block. Very weird. | ||
1327 | * | ||
1328 | * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers() | 1322 | * __getblk() will lock up the machine if grow_dev_page's try_to_free_buffers() |
1329 | * attempt is failing. FIXME, perhaps? | 1323 | * attempt is failing. FIXME, perhaps? |
1330 | */ | 1324 | */ |
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index fb962efdacee..6d59006bfa27 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c | |||
@@ -201,6 +201,7 @@ int ceph_fs_debugfs_init(struct ceph_fs_client *fsc) | |||
201 | int err = -ENOMEM; | 201 | int err = -ENOMEM; |
202 | 202 | ||
203 | dout("ceph_fs_debugfs_init\n"); | 203 | dout("ceph_fs_debugfs_init\n"); |
204 | BUG_ON(!fsc->client->debugfs_dir); | ||
204 | fsc->debugfs_congestion_kb = | 205 | fsc->debugfs_congestion_kb = |
205 | debugfs_create_file("writeback_congestion_kb", | 206 | debugfs_create_file("writeback_congestion_kb", |
206 | 0600, | 207 | 0600, |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 9fff9f3b17e4..4b5762ef7c2b 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -992,11 +992,15 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
992 | if (rinfo->head->is_dentry) { | 992 | if (rinfo->head->is_dentry) { |
993 | struct inode *dir = req->r_locked_dir; | 993 | struct inode *dir = req->r_locked_dir; |
994 | 994 | ||
995 | err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, | 995 | if (dir) { |
996 | session, req->r_request_started, -1, | 996 | err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag, |
997 | &req->r_caps_reservation); | 997 | session, req->r_request_started, -1, |
998 | if (err < 0) | 998 | &req->r_caps_reservation); |
999 | return err; | 999 | if (err < 0) |
1000 | return err; | ||
1001 | } else { | ||
1002 | WARN_ON_ONCE(1); | ||
1003 | } | ||
1000 | } | 1004 | } |
1001 | 1005 | ||
1002 | /* | 1006 | /* |
@@ -1004,6 +1008,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
1004 | * will have trouble splicing in the virtual snapdir later | 1008 | * will have trouble splicing in the virtual snapdir later |
1005 | */ | 1009 | */ |
1006 | if (rinfo->head->is_dentry && !req->r_aborted && | 1010 | if (rinfo->head->is_dentry && !req->r_aborted && |
1011 | req->r_locked_dir && | ||
1007 | (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name, | 1012 | (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name, |
1008 | fsc->mount_options->snapdir_name, | 1013 | fsc->mount_options->snapdir_name, |
1009 | req->r_dentry->d_name.len))) { | 1014 | req->r_dentry->d_name.len))) { |
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 8e3fb69fbe62..1396ceb46797 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
@@ -42,7 +42,8 @@ static long __validate_layout(struct ceph_mds_client *mdsc, | |||
42 | /* validate striping parameters */ | 42 | /* validate striping parameters */ |
43 | if ((l->object_size & ~PAGE_MASK) || | 43 | if ((l->object_size & ~PAGE_MASK) || |
44 | (l->stripe_unit & ~PAGE_MASK) || | 44 | (l->stripe_unit & ~PAGE_MASK) || |
45 | ((unsigned)l->object_size % (unsigned)l->stripe_unit)) | 45 | (l->stripe_unit != 0 && |
46 | ((unsigned)l->object_size % (unsigned)l->stripe_unit))) | ||
46 | return -EINVAL; | 47 | return -EINVAL; |
47 | 48 | ||
48 | /* make sure it's a valid data pool */ | 49 | /* make sure it's a valid data pool */ |
diff --git a/fs/compat.c b/fs/compat.c index 6161255fac45..1bdb350ea5d3 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1155,11 +1155,14 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, | |||
1155 | struct file *file; | 1155 | struct file *file; |
1156 | int fput_needed; | 1156 | int fput_needed; |
1157 | ssize_t ret; | 1157 | ssize_t ret; |
1158 | loff_t pos; | ||
1158 | 1159 | ||
1159 | file = fget_light(fd, &fput_needed); | 1160 | file = fget_light(fd, &fput_needed); |
1160 | if (!file) | 1161 | if (!file) |
1161 | return -EBADF; | 1162 | return -EBADF; |
1162 | ret = compat_readv(file, vec, vlen, &file->f_pos); | 1163 | pos = file->f_pos; |
1164 | ret = compat_readv(file, vec, vlen, &pos); | ||
1165 | file->f_pos = pos; | ||
1163 | fput_light(file, fput_needed); | 1166 | fput_light(file, fput_needed); |
1164 | return ret; | 1167 | return ret; |
1165 | } | 1168 | } |
@@ -1221,11 +1224,14 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, | |||
1221 | struct file *file; | 1224 | struct file *file; |
1222 | int fput_needed; | 1225 | int fput_needed; |
1223 | ssize_t ret; | 1226 | ssize_t ret; |
1227 | loff_t pos; | ||
1224 | 1228 | ||
1225 | file = fget_light(fd, &fput_needed); | 1229 | file = fget_light(fd, &fput_needed); |
1226 | if (!file) | 1230 | if (!file) |
1227 | return -EBADF; | 1231 | return -EBADF; |
1228 | ret = compat_writev(file, vec, vlen, &file->f_pos); | 1232 | pos = file->f_pos; |
1233 | ret = compat_writev(file, vec, vlen, &pos); | ||
1234 | file->f_pos = pos; | ||
1229 | fput_light(file, fput_needed); | 1235 | fput_light(file, fput_needed); |
1230 | return ret; | 1236 | return ret; |
1231 | } | 1237 | } |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 1faf4cb56f39..f86c720dba0e 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1062,6 +1062,7 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1062 | unsigned long user_addr; | 1062 | unsigned long user_addr; |
1063 | size_t bytes; | 1063 | size_t bytes; |
1064 | struct buffer_head map_bh = { 0, }; | 1064 | struct buffer_head map_bh = { 0, }; |
1065 | struct blk_plug plug; | ||
1065 | 1066 | ||
1066 | if (rw & WRITE) | 1067 | if (rw & WRITE) |
1067 | rw = WRITE_ODIRECT; | 1068 | rw = WRITE_ODIRECT; |
@@ -1177,6 +1178,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1177 | PAGE_SIZE - user_addr / PAGE_SIZE); | 1178 | PAGE_SIZE - user_addr / PAGE_SIZE); |
1178 | } | 1179 | } |
1179 | 1180 | ||
1181 | blk_start_plug(&plug); | ||
1182 | |||
1180 | for (seg = 0; seg < nr_segs; seg++) { | 1183 | for (seg = 0; seg < nr_segs; seg++) { |
1181 | user_addr = (unsigned long)iov[seg].iov_base; | 1184 | user_addr = (unsigned long)iov[seg].iov_base; |
1182 | sdio.size += bytes = iov[seg].iov_len; | 1185 | sdio.size += bytes = iov[seg].iov_len; |
@@ -1235,6 +1238,8 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1235 | if (sdio.bio) | 1238 | if (sdio.bio) |
1236 | dio_bio_submit(dio, &sdio); | 1239 | dio_bio_submit(dio, &sdio); |
1237 | 1240 | ||
1241 | blk_finish_plug(&plug); | ||
1242 | |||
1238 | /* | 1243 | /* |
1239 | * It is possible that, we return short IO due to end of file. | 1244 | * It is possible that, we return short IO due to end of file. |
1240 | * In that case, we need to release all the pages we got hold on. | 1245 | * In that case, we need to release all the pages we got hold on. |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 1c8b55670804..eedec84c1809 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -1654,8 +1654,8 @@ SYSCALL_DEFINE1(epoll_create1, int, flags) | |||
1654 | error = PTR_ERR(file); | 1654 | error = PTR_ERR(file); |
1655 | goto out_free_fd; | 1655 | goto out_free_fd; |
1656 | } | 1656 | } |
1657 | fd_install(fd, file); | ||
1658 | ep->file = file; | 1657 | ep->file = file; |
1658 | fd_install(fd, file); | ||
1659 | return fd; | 1659 | return fd; |
1660 | 1660 | ||
1661 | out_free_fd: | 1661 | out_free_fd: |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 5badb0c039de..1562c27a2fab 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -37,15 +37,12 @@ | |||
37 | 37 | ||
38 | #define EXOFS_DBGMSG2(M...) do {} while (0) | 38 | #define EXOFS_DBGMSG2(M...) do {} while (0) |
39 | 39 | ||
40 | enum {MAX_PAGES_KMALLOC = PAGE_SIZE / sizeof(struct page *), }; | ||
41 | |||
42 | unsigned exofs_max_io_pages(struct ore_layout *layout, | 40 | unsigned exofs_max_io_pages(struct ore_layout *layout, |
43 | unsigned expected_pages) | 41 | unsigned expected_pages) |
44 | { | 42 | { |
45 | unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); | 43 | unsigned pages = min_t(unsigned, expected_pages, |
44 | layout->max_io_length / PAGE_SIZE); | ||
46 | 45 | ||
47 | /* TODO: easily support bio chaining */ | ||
48 | pages = min_t(unsigned, pages, layout->max_io_length / PAGE_SIZE); | ||
49 | return pages; | 46 | return pages; |
50 | } | 47 | } |
51 | 48 | ||
@@ -101,7 +98,8 @@ static void _pcol_reset(struct page_collect *pcol) | |||
101 | * it might not end here. don't be left with nothing | 98 | * it might not end here. don't be left with nothing |
102 | */ | 99 | */ |
103 | if (!pcol->expected_pages) | 100 | if (!pcol->expected_pages) |
104 | pcol->expected_pages = MAX_PAGES_KMALLOC; | 101 | pcol->expected_pages = |
102 | exofs_max_io_pages(&pcol->sbi->layout, ~0); | ||
105 | } | 103 | } |
106 | 104 | ||
107 | static int pcol_try_alloc(struct page_collect *pcol) | 105 | static int pcol_try_alloc(struct page_collect *pcol) |
@@ -389,6 +387,8 @@ static int readpage_strip(void *data, struct page *page) | |||
389 | size_t len; | 387 | size_t len; |
390 | int ret; | 388 | int ret; |
391 | 389 | ||
390 | BUG_ON(!PageLocked(page)); | ||
391 | |||
392 | /* FIXME: Just for debugging, will be removed */ | 392 | /* FIXME: Just for debugging, will be removed */ |
393 | if (PageUptodate(page)) | 393 | if (PageUptodate(page)) |
394 | EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino, | 394 | EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino, |
@@ -572,8 +572,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) | |||
572 | 572 | ||
573 | if (!pcol->that_locked_page || | 573 | if (!pcol->that_locked_page || |
574 | (pcol->that_locked_page->index != index)) { | 574 | (pcol->that_locked_page->index != index)) { |
575 | struct page *page = find_get_page(pcol->inode->i_mapping, index); | 575 | struct page *page; |
576 | loff_t i_size = i_size_read(pcol->inode); | ||
577 | |||
578 | if (offset >= i_size) { | ||
579 | *uptodate = true; | ||
580 | EXOFS_DBGMSG("offset >= i_size index=0x%lx\n", index); | ||
581 | return ZERO_PAGE(0); | ||
582 | } | ||
576 | 583 | ||
584 | page = find_get_page(pcol->inode->i_mapping, index); | ||
577 | if (!page) { | 585 | if (!page) { |
578 | page = find_or_create_page(pcol->inode->i_mapping, | 586 | page = find_or_create_page(pcol->inode->i_mapping, |
579 | index, GFP_NOFS); | 587 | index, GFP_NOFS); |
@@ -602,12 +610,13 @@ static void __r4w_put_page(void *priv, struct page *page) | |||
602 | { | 610 | { |
603 | struct page_collect *pcol = priv; | 611 | struct page_collect *pcol = priv; |
604 | 612 | ||
605 | if (pcol->that_locked_page != page) { | 613 | if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) { |
606 | EXOFS_DBGMSG("index=0x%lx\n", page->index); | 614 | EXOFS_DBGMSG("index=0x%lx\n", page->index); |
607 | page_cache_release(page); | 615 | page_cache_release(page); |
608 | return; | 616 | return; |
609 | } | 617 | } |
610 | EXOFS_DBGMSG("that_locked_page index=0x%lx\n", page->index); | 618 | EXOFS_DBGMSG("that_locked_page index=0x%lx\n", |
619 | ZERO_PAGE(0) == page ? -1 : page->index); | ||
611 | } | 620 | } |
612 | 621 | ||
613 | static const struct _ore_r4w_op _r4w_op = { | 622 | static const struct _ore_r4w_op _r4w_op = { |
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c index 24a49d47e935..1585db1aa365 100644 --- a/fs/exofs/ore.c +++ b/fs/exofs/ore.c | |||
@@ -837,11 +837,11 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) | |||
837 | bio->bi_rw |= REQ_WRITE; | 837 | bio->bi_rw |= REQ_WRITE; |
838 | } | 838 | } |
839 | 839 | ||
840 | osd_req_write(or, _ios_obj(ios, dev), per_dev->offset, | 840 | osd_req_write(or, _ios_obj(ios, cur_comp), |
841 | bio, per_dev->length); | 841 | per_dev->offset, bio, per_dev->length); |
842 | ORE_DBGMSG("write(0x%llx) offset=0x%llx " | 842 | ORE_DBGMSG("write(0x%llx) offset=0x%llx " |
843 | "length=0x%llx dev=%d\n", | 843 | "length=0x%llx dev=%d\n", |
844 | _LLU(_ios_obj(ios, dev)->id), | 844 | _LLU(_ios_obj(ios, cur_comp)->id), |
845 | _LLU(per_dev->offset), | 845 | _LLU(per_dev->offset), |
846 | _LLU(per_dev->length), dev); | 846 | _LLU(per_dev->length), dev); |
847 | } else if (ios->kern_buff) { | 847 | } else if (ios->kern_buff) { |
@@ -853,20 +853,20 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) | |||
853 | (ios->si.unit_off + ios->length > | 853 | (ios->si.unit_off + ios->length > |
854 | ios->layout->stripe_unit)); | 854 | ios->layout->stripe_unit)); |
855 | 855 | ||
856 | ret = osd_req_write_kern(or, _ios_obj(ios, per_dev->dev), | 856 | ret = osd_req_write_kern(or, _ios_obj(ios, cur_comp), |
857 | per_dev->offset, | 857 | per_dev->offset, |
858 | ios->kern_buff, ios->length); | 858 | ios->kern_buff, ios->length); |
859 | if (unlikely(ret)) | 859 | if (unlikely(ret)) |
860 | goto out; | 860 | goto out; |
861 | ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx " | 861 | ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx " |
862 | "length=0x%llx dev=%d\n", | 862 | "length=0x%llx dev=%d\n", |
863 | _LLU(_ios_obj(ios, dev)->id), | 863 | _LLU(_ios_obj(ios, cur_comp)->id), |
864 | _LLU(per_dev->offset), | 864 | _LLU(per_dev->offset), |
865 | _LLU(ios->length), per_dev->dev); | 865 | _LLU(ios->length), per_dev->dev); |
866 | } else { | 866 | } else { |
867 | osd_req_set_attributes(or, _ios_obj(ios, dev)); | 867 | osd_req_set_attributes(or, _ios_obj(ios, cur_comp)); |
868 | ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", | 868 | ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", |
869 | _LLU(_ios_obj(ios, dev)->id), | 869 | _LLU(_ios_obj(ios, cur_comp)->id), |
870 | ios->out_attr_len, dev); | 870 | ios->out_attr_len, dev); |
871 | } | 871 | } |
872 | 872 | ||
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 433783624d10..dde41a75c7c8 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -400,8 +400,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait) | |||
400 | ret = ore_write(ios); | 400 | ret = ore_write(ios); |
401 | if (unlikely(ret)) | 401 | if (unlikely(ret)) |
402 | EXOFS_ERR("%s: ore_write failed.\n", __func__); | 402 | EXOFS_ERR("%s: ore_write failed.\n", __func__); |
403 | else | ||
404 | sb->s_dirt = 0; | ||
405 | 403 | ||
406 | 404 | ||
407 | unlock_super(sb); | 405 | unlock_super(sb); |
@@ -412,14 +410,6 @@ out: | |||
412 | return ret; | 410 | return ret; |
413 | } | 411 | } |
414 | 412 | ||
415 | static void exofs_write_super(struct super_block *sb) | ||
416 | { | ||
417 | if (!(sb->s_flags & MS_RDONLY)) | ||
418 | exofs_sync_fs(sb, 1); | ||
419 | else | ||
420 | sb->s_dirt = 0; | ||
421 | } | ||
422 | |||
423 | static void _exofs_print_device(const char *msg, const char *dev_path, | 413 | static void _exofs_print_device(const char *msg, const char *dev_path, |
424 | struct osd_dev *od, u64 pid) | 414 | struct osd_dev *od, u64 pid) |
425 | { | 415 | { |
@@ -952,7 +942,6 @@ static const struct super_operations exofs_sops = { | |||
952 | .write_inode = exofs_write_inode, | 942 | .write_inode = exofs_write_inode, |
953 | .evict_inode = exofs_evict_inode, | 943 | .evict_inode = exofs_evict_inode, |
954 | .put_super = exofs_put_super, | 944 | .put_super = exofs_put_super, |
955 | .write_super = exofs_write_super, | ||
956 | .sync_fs = exofs_sync_fs, | 945 | .sync_fs = exofs_sync_fs, |
957 | .statfs = exofs_statfs, | 946 | .statfs = exofs_statfs, |
958 | }; | 947 | }; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 9a4a5c48b1c9..a07597307fd1 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -3459,14 +3459,6 @@ ext3_reserve_inode_write(handle_t *handle, struct inode *inode, | |||
3459 | * inode out, but prune_icache isn't a user-visible syncing function. | 3459 | * inode out, but prune_icache isn't a user-visible syncing function. |
3460 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) | 3460 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) |
3461 | * we start and wait on commits. | 3461 | * we start and wait on commits. |
3462 | * | ||
3463 | * Is this efficient/effective? Well, we're being nice to the system | ||
3464 | * by cleaning up our inodes proactively so they can be reaped | ||
3465 | * without I/O. But we are potentially leaving up to five seconds' | ||
3466 | * worth of inodes floating about which prune_icache wants us to | ||
3467 | * write out. One way to fix that would be to get prune_icache() | ||
3468 | * to do a write_super() to free up some memory. It has the desired | ||
3469 | * effect. | ||
3470 | */ | 3462 | */ |
3471 | int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) | 3463 | int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) |
3472 | { | 3464 | { |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index ff9bcdc5b0d5..8c892e93d8e7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -64,11 +64,6 @@ static int ext3_freeze(struct super_block *sb); | |||
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Wrappers for journal_start/end. | 66 | * Wrappers for journal_start/end. |
67 | * | ||
68 | * The only special thing we need to do here is to make sure that all | ||
69 | * journal_end calls result in the superblock being marked dirty, so | ||
70 | * that sync() will call the filesystem's write_super callback if | ||
71 | * appropriate. | ||
72 | */ | 67 | */ |
73 | handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) | 68 | handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) |
74 | { | 69 | { |
@@ -90,12 +85,6 @@ handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) | |||
90 | return journal_start(journal, nblocks); | 85 | return journal_start(journal, nblocks); |
91 | } | 86 | } |
92 | 87 | ||
93 | /* | ||
94 | * The only special thing we need to do here is to make sure that all | ||
95 | * journal_stop calls result in the superblock being marked dirty, so | ||
96 | * that sync() will call the filesystem's write_super callback if | ||
97 | * appropriate. | ||
98 | */ | ||
99 | int __ext3_journal_stop(const char *where, handle_t *handle) | 88 | int __ext3_journal_stop(const char *where, handle_t *handle) |
100 | { | 89 | { |
101 | struct super_block *sb; | 90 | struct super_block *sb; |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index d23b31ca9d7a..1b5089067d01 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -280,14 +280,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
280 | return desc; | 280 | return desc; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int ext4_valid_block_bitmap(struct super_block *sb, | 283 | /* |
284 | struct ext4_group_desc *desc, | 284 | * Return the block number which was discovered to be invalid, or 0 if |
285 | unsigned int block_group, | 285 | * the block bitmap is valid. |
286 | struct buffer_head *bh) | 286 | */ |
287 | static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb, | ||
288 | struct ext4_group_desc *desc, | ||
289 | unsigned int block_group, | ||
290 | struct buffer_head *bh) | ||
287 | { | 291 | { |
288 | ext4_grpblk_t offset; | 292 | ext4_grpblk_t offset; |
289 | ext4_grpblk_t next_zero_bit; | 293 | ext4_grpblk_t next_zero_bit; |
290 | ext4_fsblk_t bitmap_blk; | 294 | ext4_fsblk_t blk; |
291 | ext4_fsblk_t group_first_block; | 295 | ext4_fsblk_t group_first_block; |
292 | 296 | ||
293 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { | 297 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { |
@@ -297,37 +301,33 @@ static int ext4_valid_block_bitmap(struct super_block *sb, | |||
297 | * or it has to also read the block group where the bitmaps | 301 | * or it has to also read the block group where the bitmaps |
298 | * are located to verify they are set. | 302 | * are located to verify they are set. |
299 | */ | 303 | */ |
300 | return 1; | 304 | return 0; |
301 | } | 305 | } |
302 | group_first_block = ext4_group_first_block_no(sb, block_group); | 306 | group_first_block = ext4_group_first_block_no(sb, block_group); |
303 | 307 | ||
304 | /* check whether block bitmap block number is set */ | 308 | /* check whether block bitmap block number is set */ |
305 | bitmap_blk = ext4_block_bitmap(sb, desc); | 309 | blk = ext4_block_bitmap(sb, desc); |
306 | offset = bitmap_blk - group_first_block; | 310 | offset = blk - group_first_block; |
307 | if (!ext4_test_bit(offset, bh->b_data)) | 311 | if (!ext4_test_bit(offset, bh->b_data)) |
308 | /* bad block bitmap */ | 312 | /* bad block bitmap */ |
309 | goto err_out; | 313 | return blk; |
310 | 314 | ||
311 | /* check whether the inode bitmap block number is set */ | 315 | /* check whether the inode bitmap block number is set */ |
312 | bitmap_blk = ext4_inode_bitmap(sb, desc); | 316 | blk = ext4_inode_bitmap(sb, desc); |
313 | offset = bitmap_blk - group_first_block; | 317 | offset = blk - group_first_block; |
314 | if (!ext4_test_bit(offset, bh->b_data)) | 318 | if (!ext4_test_bit(offset, bh->b_data)) |
315 | /* bad block bitmap */ | 319 | /* bad block bitmap */ |
316 | goto err_out; | 320 | return blk; |
317 | 321 | ||
318 | /* check whether the inode table block number is set */ | 322 | /* check whether the inode table block number is set */ |
319 | bitmap_blk = ext4_inode_table(sb, desc); | 323 | blk = ext4_inode_table(sb, desc); |
320 | offset = bitmap_blk - group_first_block; | 324 | offset = blk - group_first_block; |
321 | next_zero_bit = ext4_find_next_zero_bit(bh->b_data, | 325 | next_zero_bit = ext4_find_next_zero_bit(bh->b_data, |
322 | offset + EXT4_SB(sb)->s_itb_per_group, | 326 | offset + EXT4_SB(sb)->s_itb_per_group, |
323 | offset); | 327 | offset); |
324 | if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group) | 328 | if (next_zero_bit < offset + EXT4_SB(sb)->s_itb_per_group) |
325 | /* good bitmap for inode tables */ | 329 | /* bad bitmap for inode tables */ |
326 | return 1; | 330 | return blk; |
327 | |||
328 | err_out: | ||
329 | ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu", | ||
330 | block_group, bitmap_blk); | ||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | 333 | ||
@@ -336,14 +336,26 @@ void ext4_validate_block_bitmap(struct super_block *sb, | |||
336 | unsigned int block_group, | 336 | unsigned int block_group, |
337 | struct buffer_head *bh) | 337 | struct buffer_head *bh) |
338 | { | 338 | { |
339 | ext4_fsblk_t blk; | ||
340 | |||
339 | if (buffer_verified(bh)) | 341 | if (buffer_verified(bh)) |
340 | return; | 342 | return; |
341 | 343 | ||
342 | ext4_lock_group(sb, block_group); | 344 | ext4_lock_group(sb, block_group); |
343 | if (ext4_valid_block_bitmap(sb, desc, block_group, bh) && | 345 | blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); |
344 | ext4_block_bitmap_csum_verify(sb, block_group, desc, bh, | 346 | if (unlikely(blk != 0)) { |
345 | EXT4_BLOCKS_PER_GROUP(sb) / 8)) | 347 | ext4_unlock_group(sb, block_group); |
346 | set_buffer_verified(bh); | 348 | ext4_error(sb, "bg %u: block %llu: invalid block bitmap", |
349 | block_group, blk); | ||
350 | return; | ||
351 | } | ||
352 | if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, | ||
353 | desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) { | ||
354 | ext4_unlock_group(sb, block_group); | ||
355 | ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); | ||
356 | return; | ||
357 | } | ||
358 | set_buffer_verified(bh); | ||
347 | ext4_unlock_group(sb, block_group); | 359 | ext4_unlock_group(sb, block_group); |
348 | } | 360 | } |
349 | 361 | ||
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index f8716eab9995..5c2d1813ebe9 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c | |||
@@ -79,7 +79,6 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | |||
79 | if (provided == calculated) | 79 | if (provided == calculated) |
80 | return 1; | 80 | return 1; |
81 | 81 | ||
82 | ext4_error(sb, "Bad block bitmap checksum: block_group = %u", group); | ||
83 | return 0; | 82 | return 0; |
84 | } | 83 | } |
85 | 84 | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index cd0c7ed06772..aabbb3f53683 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2662,6 +2662,7 @@ cont: | |||
2662 | } | 2662 | } |
2663 | path[0].p_depth = depth; | 2663 | path[0].p_depth = depth; |
2664 | path[0].p_hdr = ext_inode_hdr(inode); | 2664 | path[0].p_hdr = ext_inode_hdr(inode); |
2665 | i = 0; | ||
2665 | 2666 | ||
2666 | if (ext4_ext_check(inode, path[0].p_hdr, depth)) { | 2667 | if (ext4_ext_check(inode, path[0].p_hdr, depth)) { |
2667 | err = -EIO; | 2668 | err = -EIO; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 6324f74e0342..dff171c3a123 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1970,7 +1970,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate); | |||
1970 | * This function can get called via... | 1970 | * This function can get called via... |
1971 | * - ext4_da_writepages after taking page lock (have journal handle) | 1971 | * - ext4_da_writepages after taking page lock (have journal handle) |
1972 | * - journal_submit_inode_data_buffers (no journal handle) | 1972 | * - journal_submit_inode_data_buffers (no journal handle) |
1973 | * - shrink_page_list via pdflush (no journal handle) | 1973 | * - shrink_page_list via the kswapd/direct reclaim (no journal handle) |
1974 | * - grab_page_cache when doing write_begin (have journal handle) | 1974 | * - grab_page_cache when doing write_begin (have journal handle) |
1975 | * | 1975 | * |
1976 | * We don't do any block allocation in this function. If we have page with | 1976 | * We don't do any block allocation in this function. If we have page with |
@@ -4589,14 +4589,6 @@ static int ext4_expand_extra_isize(struct inode *inode, | |||
4589 | * inode out, but prune_icache isn't a user-visible syncing function. | 4589 | * inode out, but prune_icache isn't a user-visible syncing function. |
4590 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) | 4590 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) |
4591 | * we start and wait on commits. | 4591 | * we start and wait on commits. |
4592 | * | ||
4593 | * Is this efficient/effective? Well, we're being nice to the system | ||
4594 | * by cleaning up our inodes proactively so they can be reaped | ||
4595 | * without I/O. But we are potentially leaving up to five seconds' | ||
4596 | * worth of inodes floating about which prune_icache wants us to | ||
4597 | * write out. One way to fix that would be to get prune_icache() | ||
4598 | * to do a write_super() to free up some memory. It has the desired | ||
4599 | * effect. | ||
4600 | */ | 4592 | */ |
4601 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | 4593 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) |
4602 | { | 4594 | { |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d76ec8277d3f..c6e0cb3d1f4a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -326,11 +326,6 @@ static void ext4_put_nojournal(handle_t *handle) | |||
326 | 326 | ||
327 | /* | 327 | /* |
328 | * Wrappers for jbd2_journal_start/end. | 328 | * Wrappers for jbd2_journal_start/end. |
329 | * | ||
330 | * The only special thing we need to do here is to make sure that all | ||
331 | * journal_end calls result in the superblock being marked dirty, so | ||
332 | * that sync() will call the filesystem's write_super callback if | ||
333 | * appropriate. | ||
334 | */ | 329 | */ |
335 | handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | 330 | handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) |
336 | { | 331 | { |
@@ -356,12 +351,6 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | |||
356 | return jbd2_journal_start(journal, nblocks); | 351 | return jbd2_journal_start(journal, nblocks); |
357 | } | 352 | } |
358 | 353 | ||
359 | /* | ||
360 | * The only special thing we need to do here is to make sure that all | ||
361 | * jbd2_journal_stop calls result in the superblock being marked dirty, so | ||
362 | * that sync() will call the filesystem's write_super callback if | ||
363 | * appropriate. | ||
364 | */ | ||
365 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) | 354 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) |
366 | { | 355 | { |
367 | struct super_block *sb; | 356 | struct super_block *sb; |
@@ -959,6 +948,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
959 | ei->i_reserved_meta_blocks = 0; | 948 | ei->i_reserved_meta_blocks = 0; |
960 | ei->i_allocated_meta_blocks = 0; | 949 | ei->i_allocated_meta_blocks = 0; |
961 | ei->i_da_metadata_calc_len = 0; | 950 | ei->i_da_metadata_calc_len = 0; |
951 | ei->i_da_metadata_calc_last_lblock = 0; | ||
962 | spin_lock_init(&(ei->i_block_reservation_lock)); | 952 | spin_lock_init(&(ei->i_block_reservation_lock)); |
963 | #ifdef CONFIG_QUOTA | 953 | #ifdef CONFIG_QUOTA |
964 | ei->i_reserved_quota = 0; | 954 | ei->i_reserved_quota = 0; |
@@ -3119,6 +3109,10 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp, | |||
3119 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); | 3109 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
3120 | int s, j, count = 0; | 3110 | int s, j, count = 0; |
3121 | 3111 | ||
3112 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC)) | ||
3113 | return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) + | ||
3114 | sbi->s_itb_per_group + 2); | ||
3115 | |||
3122 | first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + | 3116 | first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + |
3123 | (grp * EXT4_BLOCKS_PER_GROUP(sb)); | 3117 | (grp * EXT4_BLOCKS_PER_GROUP(sb)); |
3124 | last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; | 3118 | last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; |
@@ -4430,6 +4424,7 @@ static void ext4_clear_journal_err(struct super_block *sb, | |||
4430 | ext4_commit_super(sb, 1); | 4424 | ext4_commit_super(sb, 1); |
4431 | 4425 | ||
4432 | jbd2_journal_clear_err(journal); | 4426 | jbd2_journal_clear_err(journal); |
4427 | jbd2_journal_update_sb_errno(journal); | ||
4433 | } | 4428 | } |
4434 | } | 4429 | } |
4435 | 4430 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8964cf3999b2..324bc0850534 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
383 | struct fuse_entry_out outentry; | 383 | struct fuse_entry_out outentry; |
384 | struct fuse_file *ff; | 384 | struct fuse_file *ff; |
385 | 385 | ||
386 | /* Userspace expects S_IFREG in create mode */ | ||
387 | BUG_ON((mode & S_IFMT) != S_IFREG); | ||
388 | |||
386 | forget = fuse_alloc_forget(); | 389 | forget = fuse_alloc_forget(); |
387 | err = -ENOMEM; | 390 | err = -ENOMEM; |
388 | if (!forget) | 391 | if (!forget) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 93d8d6c9494d..aba15f1b7ad2 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -703,13 +703,16 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
703 | unsigned long nr_segs, loff_t pos) | 703 | unsigned long nr_segs, loff_t pos) |
704 | { | 704 | { |
705 | struct inode *inode = iocb->ki_filp->f_mapping->host; | 705 | struct inode *inode = iocb->ki_filp->f_mapping->host; |
706 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
706 | 707 | ||
707 | if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) { | 708 | /* |
709 | * In auto invalidate mode, always update attributes on read. | ||
710 | * Otherwise, only update if we attempt to read past EOF (to ensure | ||
711 | * i_size is up to date). | ||
712 | */ | ||
713 | if (fc->auto_inval_data || | ||
714 | (pos + iov_length(iov, nr_segs) > i_size_read(inode))) { | ||
708 | int err; | 715 | int err; |
709 | /* | ||
710 | * If trying to read past EOF, make sure the i_size | ||
711 | * attribute is up-to-date. | ||
712 | */ | ||
713 | err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); | 716 | err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); |
714 | if (err) | 717 | if (err) |
715 | return err; | 718 | return err; |
@@ -1700,7 +1703,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) | |||
1700 | size_t n; | 1703 | size_t n; |
1701 | u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; | 1704 | u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; |
1702 | 1705 | ||
1703 | for (n = 0; n < count; n++) { | 1706 | for (n = 0; n < count; n++, iov++) { |
1704 | if (iov->iov_len > (size_t) max) | 1707 | if (iov->iov_len > (size_t) max) |
1705 | return -ENOMEM; | 1708 | return -ENOMEM; |
1706 | max -= iov->iov_len; | 1709 | max -= iov->iov_len; |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 771fb6322c07..e24dd74e3068 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -484,6 +484,9 @@ struct fuse_conn { | |||
484 | /** Is fallocate not implemented by fs? */ | 484 | /** Is fallocate not implemented by fs? */ |
485 | unsigned no_fallocate:1; | 485 | unsigned no_fallocate:1; |
486 | 486 | ||
487 | /** Use enhanced/automatic page cache invalidation. */ | ||
488 | unsigned auto_inval_data:1; | ||
489 | |||
487 | /** The number of requests waiting for completion */ | 490 | /** The number of requests waiting for completion */ |
488 | atomic_t num_waiting; | 491 | atomic_t num_waiting; |
489 | 492 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1cd61652018c..ce0a2838ccd0 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -197,6 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | |||
197 | struct fuse_conn *fc = get_fuse_conn(inode); | 197 | struct fuse_conn *fc = get_fuse_conn(inode); |
198 | struct fuse_inode *fi = get_fuse_inode(inode); | 198 | struct fuse_inode *fi = get_fuse_inode(inode); |
199 | loff_t oldsize; | 199 | loff_t oldsize; |
200 | struct timespec old_mtime; | ||
200 | 201 | ||
201 | spin_lock(&fc->lock); | 202 | spin_lock(&fc->lock); |
202 | if (attr_version != 0 && fi->attr_version > attr_version) { | 203 | if (attr_version != 0 && fi->attr_version > attr_version) { |
@@ -204,15 +205,35 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | |||
204 | return; | 205 | return; |
205 | } | 206 | } |
206 | 207 | ||
208 | old_mtime = inode->i_mtime; | ||
207 | fuse_change_attributes_common(inode, attr, attr_valid); | 209 | fuse_change_attributes_common(inode, attr, attr_valid); |
208 | 210 | ||
209 | oldsize = inode->i_size; | 211 | oldsize = inode->i_size; |
210 | i_size_write(inode, attr->size); | 212 | i_size_write(inode, attr->size); |
211 | spin_unlock(&fc->lock); | 213 | spin_unlock(&fc->lock); |
212 | 214 | ||
213 | if (S_ISREG(inode->i_mode) && oldsize != attr->size) { | 215 | if (S_ISREG(inode->i_mode)) { |
214 | truncate_pagecache(inode, oldsize, attr->size); | 216 | bool inval = false; |
215 | invalidate_inode_pages2(inode->i_mapping); | 217 | |
218 | if (oldsize != attr->size) { | ||
219 | truncate_pagecache(inode, oldsize, attr->size); | ||
220 | inval = true; | ||
221 | } else if (fc->auto_inval_data) { | ||
222 | struct timespec new_mtime = { | ||
223 | .tv_sec = attr->mtime, | ||
224 | .tv_nsec = attr->mtimensec, | ||
225 | }; | ||
226 | |||
227 | /* | ||
228 | * Auto inval mode also checks and invalidates if mtime | ||
229 | * has changed. | ||
230 | */ | ||
231 | if (!timespec_equal(&old_mtime, &new_mtime)) | ||
232 | inval = true; | ||
233 | } | ||
234 | |||
235 | if (inval) | ||
236 | invalidate_inode_pages2(inode->i_mapping); | ||
216 | } | 237 | } |
217 | } | 238 | } |
218 | 239 | ||
@@ -834,6 +855,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
834 | fc->big_writes = 1; | 855 | fc->big_writes = 1; |
835 | if (arg->flags & FUSE_DONT_MASK) | 856 | if (arg->flags & FUSE_DONT_MASK) |
836 | fc->dont_mask = 1; | 857 | fc->dont_mask = 1; |
858 | if (arg->flags & FUSE_AUTO_INVAL_DATA) | ||
859 | fc->auto_inval_data = 1; | ||
837 | } else { | 860 | } else { |
838 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 861 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
839 | fc->no_lock = 1; | 862 | fc->no_lock = 1; |
@@ -859,7 +882,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) | |||
859 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; | 882 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; |
860 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | | 883 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | |
861 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | | 884 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | |
862 | FUSE_FLOCK_LOCKS; | 885 | FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | |
886 | FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA; | ||
863 | req->in.h.opcode = FUSE_INIT; | 887 | req->in.h.opcode = FUSE_INIT; |
864 | req->in.numargs = 1; | 888 | req->in.numargs = 1; |
865 | req->in.args[0].size = sizeof(*arg); | 889 | req->in.args[0].size = sizeof(*arg); |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 3a56c8d94de0..22255d96b27e 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -52,7 +52,7 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb | |||
52 | /* | 52 | /* |
53 | * If it's a fully non-blocking write attempt and we cannot | 53 | * If it's a fully non-blocking write attempt and we cannot |
54 | * lock the buffer then redirty the page. Note that this can | 54 | * lock the buffer then redirty the page. Note that this can |
55 | * potentially cause a busy-wait loop from pdflush and kswapd | 55 | * potentially cause a busy-wait loop from flusher thread and kswapd |
56 | * activity, but those code paths have their own higher-level | 56 | * activity, but those code paths have their own higher-level |
57 | * throttling. | 57 | * throttling. |
58 | */ | 58 | */ |
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 5fd51a5833ff..b7ec224910c5 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c | |||
@@ -236,10 +236,10 @@ out: | |||
236 | * hfs_mdb_commit() | 236 | * hfs_mdb_commit() |
237 | * | 237 | * |
238 | * Description: | 238 | * Description: |
239 | * This updates the MDB on disk (look also at hfs_write_super()). | 239 | * This updates the MDB on disk. |
240 | * It does not check, if the superblock has been modified, or | 240 | * It does not check, if the superblock has been modified, or |
241 | * if the filesystem has been mounted read-only. It is mainly | 241 | * if the filesystem has been mounted read-only. It is mainly |
242 | * called by hfs_write_super() and hfs_btree_extend(). | 242 | * called by hfs_sync_fs() and flush_mdb(). |
243 | * Input Variable(s): | 243 | * Input Variable(s): |
244 | * struct hfs_mdb *mdb: Pointer to the hfs MDB | 244 | * struct hfs_mdb *mdb: Pointer to the hfs MDB |
245 | * int backup; | 245 | * int backup; |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 425c2f2cf170..a2862339323b 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -534,8 +534,8 @@ int journal_start_commit(journal_t *journal, tid_t *ptid) | |||
534 | ret = 1; | 534 | ret = 1; |
535 | } else if (journal->j_committing_transaction) { | 535 | } else if (journal->j_committing_transaction) { |
536 | /* | 536 | /* |
537 | * If ext3_write_super() recently started a commit, then we | 537 | * If commit has been started, then we have to wait for |
538 | * have to wait for completion of that transaction | 538 | * completion of that transaction. |
539 | */ | 539 | */ |
540 | if (ptid) | 540 | if (ptid) |
541 | *ptid = journal->j_committing_transaction->t_tid; | 541 | *ptid = journal->j_committing_transaction->t_tid; |
@@ -1113,6 +1113,11 @@ static void mark_journal_empty(journal_t *journal) | |||
1113 | 1113 | ||
1114 | BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); | 1114 | BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); |
1115 | spin_lock(&journal->j_state_lock); | 1115 | spin_lock(&journal->j_state_lock); |
1116 | /* Is it already empty? */ | ||
1117 | if (sb->s_start == 0) { | ||
1118 | spin_unlock(&journal->j_state_lock); | ||
1119 | return; | ||
1120 | } | ||
1116 | jbd_debug(1, "JBD: Marking journal as empty (seq %d)\n", | 1121 | jbd_debug(1, "JBD: Marking journal as empty (seq %d)\n", |
1117 | journal->j_tail_sequence); | 1122 | journal->j_tail_sequence); |
1118 | 1123 | ||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index e9a3c4c85594..e149b99a7ffb 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -612,8 +612,8 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) | |||
612 | ret = 1; | 612 | ret = 1; |
613 | } else if (journal->j_committing_transaction) { | 613 | } else if (journal->j_committing_transaction) { |
614 | /* | 614 | /* |
615 | * If ext3_write_super() recently started a commit, then we | 615 | * If commit has been started, then we have to wait for |
616 | * have to wait for completion of that transaction | 616 | * completion of that transaction. |
617 | */ | 617 | */ |
618 | if (ptid) | 618 | if (ptid) |
619 | *ptid = journal->j_committing_transaction->t_tid; | 619 | *ptid = journal->j_committing_transaction->t_tid; |
@@ -1377,7 +1377,7 @@ static void jbd2_mark_journal_empty(journal_t *journal) | |||
1377 | * Update a journal's errno. Write updated superblock to disk waiting for IO | 1377 | * Update a journal's errno. Write updated superblock to disk waiting for IO |
1378 | * to complete. | 1378 | * to complete. |
1379 | */ | 1379 | */ |
1380 | static void jbd2_journal_update_sb_errno(journal_t *journal) | 1380 | void jbd2_journal_update_sb_errno(journal_t *journal) |
1381 | { | 1381 | { |
1382 | journal_superblock_t *sb = journal->j_superblock; | 1382 | journal_superblock_t *sb = journal->j_superblock; |
1383 | 1383 | ||
@@ -1390,6 +1390,7 @@ static void jbd2_journal_update_sb_errno(journal_t *journal) | |||
1390 | 1390 | ||
1391 | jbd2_write_superblock(journal, WRITE_SYNC); | 1391 | jbd2_write_superblock(journal, WRITE_SYNC); |
1392 | } | 1392 | } |
1393 | EXPORT_SYMBOL(jbd2_journal_update_sb_errno); | ||
1393 | 1394 | ||
1394 | /* | 1395 | /* |
1395 | * Read the superblock for a given journal, performing initial | 1396 | * Read the superblock for a given journal, performing initial |
diff --git a/fs/namei.c b/fs/namei.c index 1b464390dde8..dd1ed1b8e98e 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -352,6 +352,7 @@ int __inode_permission(struct inode *inode, int mask) | |||
352 | /** | 352 | /** |
353 | * sb_permission - Check superblock-level permissions | 353 | * sb_permission - Check superblock-level permissions |
354 | * @sb: Superblock of inode to check permission on | 354 | * @sb: Superblock of inode to check permission on |
355 | * @inode: Inode to check permission on | ||
355 | * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) | 356 | * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) |
356 | * | 357 | * |
357 | * Separate out file-system wide checks from inode-specific permission checks. | 358 | * Separate out file-system wide checks from inode-specific permission checks. |
@@ -656,6 +657,7 @@ int sysctl_protected_hardlinks __read_mostly = 1; | |||
656 | /** | 657 | /** |
657 | * may_follow_link - Check symlink following for unsafe situations | 658 | * may_follow_link - Check symlink following for unsafe situations |
658 | * @link: The path of the symlink | 659 | * @link: The path of the symlink |
660 | * @nd: nameidata pathwalk data | ||
659 | * | 661 | * |
660 | * In the case of the sysctl_protected_symlinks sysctl being enabled, | 662 | * In the case of the sysctl_protected_symlinks sysctl being enabled, |
661 | * CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is | 663 | * CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is |
@@ -2414,7 +2416,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2414 | goto out; | 2416 | goto out; |
2415 | } | 2417 | } |
2416 | 2418 | ||
2417 | mode = op->mode & S_IALLUGO; | 2419 | mode = op->mode; |
2418 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) | 2420 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) |
2419 | mode &= ~current_umask(); | 2421 | mode &= ~current_umask(); |
2420 | 2422 | ||
@@ -2452,7 +2454,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2452 | } | 2454 | } |
2453 | 2455 | ||
2454 | if (open_flag & O_CREAT) { | 2456 | if (open_flag & O_CREAT) { |
2455 | error = may_o_create(&nd->path, dentry, op->mode); | 2457 | error = may_o_create(&nd->path, dentry, mode); |
2456 | if (error) { | 2458 | if (error) { |
2457 | create_error = error; | 2459 | create_error = error; |
2458 | if (open_flag & O_EXCL) | 2460 | if (open_flag & O_EXCL) |
@@ -2489,6 +2491,10 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2489 | dput(dentry); | 2491 | dput(dentry); |
2490 | dentry = file->f_path.dentry; | 2492 | dentry = file->f_path.dentry; |
2491 | } | 2493 | } |
2494 | if (create_error && dentry->d_inode == NULL) { | ||
2495 | error = create_error; | ||
2496 | goto out; | ||
2497 | } | ||
2492 | goto looked_up; | 2498 | goto looked_up; |
2493 | } | 2499 | } |
2494 | 2500 | ||
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile index 8bf3a3f6925a..b7db60897f91 100644 --- a/fs/nfs/Makefile +++ b/fs/nfs/Makefile | |||
@@ -12,19 +12,19 @@ nfs-$(CONFIG_ROOT_NFS) += nfsroot.o | |||
12 | nfs-$(CONFIG_SYSCTL) += sysctl.o | 12 | nfs-$(CONFIG_SYSCTL) += sysctl.o |
13 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o | 13 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o |
14 | 14 | ||
15 | obj-$(CONFIG_NFS_V2) += nfs2.o | 15 | obj-$(CONFIG_NFS_V2) += nfsv2.o |
16 | nfs2-y := nfs2super.o proc.o nfs2xdr.o | 16 | nfsv2-y := nfs2super.o proc.o nfs2xdr.o |
17 | 17 | ||
18 | obj-$(CONFIG_NFS_V3) += nfs3.o | 18 | obj-$(CONFIG_NFS_V3) += nfsv3.o |
19 | nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o | 19 | nfsv3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o |
20 | nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o | 20 | nfsv3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o |
21 | 21 | ||
22 | obj-$(CONFIG_NFS_V4) += nfs4.o | 22 | obj-$(CONFIG_NFS_V4) += nfsv4.o |
23 | nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \ | 23 | nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \ |
24 | delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \ | 24 | delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \ |
25 | nfs4namespace.o nfs4getroot.o nfs4client.o | 25 | nfs4namespace.o nfs4getroot.o nfs4client.o |
26 | nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o | 26 | nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o |
27 | nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o | 27 | nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o |
28 | 28 | ||
29 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o | 29 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o |
30 | nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o | 30 | nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 9fc0d9dfc91b..99694442b93f 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -105,7 +105,7 @@ struct nfs_subversion *get_nfs_version(unsigned int version) | |||
105 | 105 | ||
106 | if (IS_ERR(nfs)) { | 106 | if (IS_ERR(nfs)) { |
107 | mutex_lock(&nfs_version_mutex); | 107 | mutex_lock(&nfs_version_mutex); |
108 | request_module("nfs%d", version); | 108 | request_module("nfsv%d", version); |
109 | nfs = find_nfs_version(version); | 109 | nfs = find_nfs_version(version); |
110 | mutex_unlock(&nfs_version_mutex); | 110 | mutex_unlock(&nfs_version_mutex); |
111 | } | 111 | } |
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index b701358c39c3..a850079467d8 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -61,6 +61,12 @@ struct idmap { | |||
61 | struct mutex idmap_mutex; | 61 | struct mutex idmap_mutex; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | struct idmap_legacy_upcalldata { | ||
65 | struct rpc_pipe_msg pipe_msg; | ||
66 | struct idmap_msg idmap_msg; | ||
67 | struct idmap *idmap; | ||
68 | }; | ||
69 | |||
64 | /** | 70 | /** |
65 | * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields | 71 | * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields |
66 | * @fattr: fully initialised struct nfs_fattr | 72 | * @fattr: fully initialised struct nfs_fattr |
@@ -324,6 +330,7 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen, | |||
324 | ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, | 330 | ret = nfs_idmap_request_key(&key_type_id_resolver_legacy, |
325 | name, namelen, type, data, | 331 | name, namelen, type, data, |
326 | data_size, idmap); | 332 | data_size, idmap); |
333 | idmap->idmap_key_cons = NULL; | ||
327 | mutex_unlock(&idmap->idmap_mutex); | 334 | mutex_unlock(&idmap->idmap_mutex); |
328 | } | 335 | } |
329 | return ret; | 336 | return ret; |
@@ -380,11 +387,13 @@ static const match_table_t nfs_idmap_tokens = { | |||
380 | static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); | 387 | static int nfs_idmap_legacy_upcall(struct key_construction *, const char *, void *); |
381 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, | 388 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, |
382 | size_t); | 389 | size_t); |
390 | static void idmap_release_pipe(struct inode *); | ||
383 | static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); | 391 | static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); |
384 | 392 | ||
385 | static const struct rpc_pipe_ops idmap_upcall_ops = { | 393 | static const struct rpc_pipe_ops idmap_upcall_ops = { |
386 | .upcall = rpc_pipe_generic_upcall, | 394 | .upcall = rpc_pipe_generic_upcall, |
387 | .downcall = idmap_pipe_downcall, | 395 | .downcall = idmap_pipe_downcall, |
396 | .release_pipe = idmap_release_pipe, | ||
388 | .destroy_msg = idmap_pipe_destroy_msg, | 397 | .destroy_msg = idmap_pipe_destroy_msg, |
389 | }; | 398 | }; |
390 | 399 | ||
@@ -616,7 +625,8 @@ void nfs_idmap_quit(void) | |||
616 | nfs_idmap_quit_keyring(); | 625 | nfs_idmap_quit_keyring(); |
617 | } | 626 | } |
618 | 627 | ||
619 | static int nfs_idmap_prepare_message(char *desc, struct idmap_msg *im, | 628 | static int nfs_idmap_prepare_message(char *desc, struct idmap *idmap, |
629 | struct idmap_msg *im, | ||
620 | struct rpc_pipe_msg *msg) | 630 | struct rpc_pipe_msg *msg) |
621 | { | 631 | { |
622 | substring_t substr; | 632 | substring_t substr; |
@@ -659,6 +669,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, | |||
659 | const char *op, | 669 | const char *op, |
660 | void *aux) | 670 | void *aux) |
661 | { | 671 | { |
672 | struct idmap_legacy_upcalldata *data; | ||
662 | struct rpc_pipe_msg *msg; | 673 | struct rpc_pipe_msg *msg; |
663 | struct idmap_msg *im; | 674 | struct idmap_msg *im; |
664 | struct idmap *idmap = (struct idmap *)aux; | 675 | struct idmap *idmap = (struct idmap *)aux; |
@@ -666,15 +677,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, | |||
666 | int ret = -ENOMEM; | 677 | int ret = -ENOMEM; |
667 | 678 | ||
668 | /* msg and im are freed in idmap_pipe_destroy_msg */ | 679 | /* msg and im are freed in idmap_pipe_destroy_msg */ |
669 | msg = kmalloc(sizeof(*msg), GFP_KERNEL); | 680 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
670 | if (!msg) | 681 | if (!data) |
671 | goto out0; | ||
672 | |||
673 | im = kmalloc(sizeof(*im), GFP_KERNEL); | ||
674 | if (!im) | ||
675 | goto out1; | 682 | goto out1; |
676 | 683 | ||
677 | ret = nfs_idmap_prepare_message(key->description, im, msg); | 684 | msg = &data->pipe_msg; |
685 | im = &data->idmap_msg; | ||
686 | data->idmap = idmap; | ||
687 | |||
688 | ret = nfs_idmap_prepare_message(key->description, idmap, im, msg); | ||
678 | if (ret < 0) | 689 | if (ret < 0) |
679 | goto out2; | 690 | goto out2; |
680 | 691 | ||
@@ -683,15 +694,15 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, | |||
683 | 694 | ||
684 | ret = rpc_queue_upcall(idmap->idmap_pipe, msg); | 695 | ret = rpc_queue_upcall(idmap->idmap_pipe, msg); |
685 | if (ret < 0) | 696 | if (ret < 0) |
686 | goto out2; | 697 | goto out3; |
687 | 698 | ||
688 | return ret; | 699 | return ret; |
689 | 700 | ||
701 | out3: | ||
702 | idmap->idmap_key_cons = NULL; | ||
690 | out2: | 703 | out2: |
691 | kfree(im); | 704 | kfree(data); |
692 | out1: | 705 | out1: |
693 | kfree(msg); | ||
694 | out0: | ||
695 | complete_request_key(cons, ret); | 706 | complete_request_key(cons, ret); |
696 | return ret; | 707 | return ret; |
697 | } | 708 | } |
@@ -749,9 +760,8 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
749 | } | 760 | } |
750 | 761 | ||
751 | if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { | 762 | if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { |
752 | ret = mlen; | 763 | ret = -ENOKEY; |
753 | complete_request_key(cons, -ENOKEY); | 764 | goto out; |
754 | goto out_incomplete; | ||
755 | } | 765 | } |
756 | 766 | ||
757 | namelen_in = strnlen(im.im_name, IDMAP_NAMESZ); | 767 | namelen_in = strnlen(im.im_name, IDMAP_NAMESZ); |
@@ -768,16 +778,32 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
768 | 778 | ||
769 | out: | 779 | out: |
770 | complete_request_key(cons, ret); | 780 | complete_request_key(cons, ret); |
771 | out_incomplete: | ||
772 | return ret; | 781 | return ret; |
773 | } | 782 | } |
774 | 783 | ||
775 | static void | 784 | static void |
776 | idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) | 785 | idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) |
777 | { | 786 | { |
787 | struct idmap_legacy_upcalldata *data = container_of(msg, | ||
788 | struct idmap_legacy_upcalldata, | ||
789 | pipe_msg); | ||
790 | struct idmap *idmap = data->idmap; | ||
791 | struct key_construction *cons; | ||
792 | if (msg->errno) { | ||
793 | cons = ACCESS_ONCE(idmap->idmap_key_cons); | ||
794 | idmap->idmap_key_cons = NULL; | ||
795 | complete_request_key(cons, msg->errno); | ||
796 | } | ||
778 | /* Free memory allocated in nfs_idmap_legacy_upcall() */ | 797 | /* Free memory allocated in nfs_idmap_legacy_upcall() */ |
779 | kfree(msg->data); | 798 | kfree(data); |
780 | kfree(msg); | 799 | } |
800 | |||
801 | static void | ||
802 | idmap_release_pipe(struct inode *inode) | ||
803 | { | ||
804 | struct rpc_inode *rpci = RPC_I(inode); | ||
805 | struct idmap *idmap = (struct idmap *)rpci->private; | ||
806 | idmap->idmap_key_cons = NULL; | ||
781 | } | 807 | } |
782 | 808 | ||
783 | int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) | 809 | int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 0952c791df36..d6b3b5f2d779 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -69,7 +69,7 @@ do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle, | |||
69 | nfs_fattr_init(info->fattr); | 69 | nfs_fattr_init(info->fattr); |
70 | status = rpc_call_sync(client, &msg, 0); | 70 | status = rpc_call_sync(client, &msg, 0); |
71 | dprintk("%s: reply fsinfo: %d\n", __func__, status); | 71 | dprintk("%s: reply fsinfo: %d\n", __func__, status); |
72 | if (!(info->fattr->valid & NFS_ATTR_FATTR)) { | 72 | if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) { |
73 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; | 73 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; |
74 | msg.rpc_resp = info->fattr; | 74 | msg.rpc_resp = info->fattr; |
75 | status = rpc_call_sync(client, &msg, 0); | 75 | status = rpc_call_sync(client, &msg, 0); |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 3b950dd81e81..da0618aeeadb 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -205,6 +205,9 @@ extern const struct dentry_operations nfs4_dentry_operations; | |||
205 | int nfs_atomic_open(struct inode *, struct dentry *, struct file *, | 205 | int nfs_atomic_open(struct inode *, struct dentry *, struct file *, |
206 | unsigned, umode_t, int *); | 206 | unsigned, umode_t, int *); |
207 | 207 | ||
208 | /* super.c */ | ||
209 | extern struct file_system_type nfs4_fs_type; | ||
210 | |||
208 | /* nfs4namespace.c */ | 211 | /* nfs4namespace.c */ |
209 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); | 212 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); |
210 | struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); | 213 | struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); |
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index cbcdfaf32505..24eb663f8ed5 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -74,7 +74,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) | |||
74 | return clp; | 74 | return clp; |
75 | 75 | ||
76 | error: | 76 | error: |
77 | kfree(clp); | 77 | nfs_free_client(clp); |
78 | return ERR_PTR(err); | 78 | return ERR_PTR(err); |
79 | } | 79 | } |
80 | 80 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a99a8d948721..635274140b18 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -3737,9 +3737,10 @@ out: | |||
3737 | static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) | 3737 | static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) |
3738 | { | 3738 | { |
3739 | struct nfs4_cached_acl *acl; | 3739 | struct nfs4_cached_acl *acl; |
3740 | size_t buflen = sizeof(*acl) + acl_len; | ||
3740 | 3741 | ||
3741 | if (pages && acl_len <= PAGE_SIZE) { | 3742 | if (pages && buflen <= PAGE_SIZE) { |
3742 | acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL); | 3743 | acl = kmalloc(buflen, GFP_KERNEL); |
3743 | if (acl == NULL) | 3744 | if (acl == NULL) |
3744 | goto out; | 3745 | goto out; |
3745 | acl->cached = 1; | 3746 | acl->cached = 1; |
@@ -3819,7 +3820,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
3819 | if (ret) | 3820 | if (ret) |
3820 | goto out_free; | 3821 | goto out_free; |
3821 | 3822 | ||
3822 | acl_len = res.acl_len - res.acl_data_offset; | 3823 | acl_len = res.acl_len; |
3823 | if (acl_len > args.acl_len) | 3824 | if (acl_len > args.acl_len) |
3824 | nfs4_write_cached_acl(inode, NULL, 0, acl_len); | 3825 | nfs4_write_cached_acl(inode, NULL, 0, acl_len); |
3825 | else | 3826 | else |
@@ -6223,11 +6224,58 @@ static void nfs4_layoutget_done(struct rpc_task *task, void *calldata) | |||
6223 | dprintk("<-- %s\n", __func__); | 6224 | dprintk("<-- %s\n", __func__); |
6224 | } | 6225 | } |
6225 | 6226 | ||
6227 | static size_t max_response_pages(struct nfs_server *server) | ||
6228 | { | ||
6229 | u32 max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; | ||
6230 | return nfs_page_array_len(0, max_resp_sz); | ||
6231 | } | ||
6232 | |||
6233 | static void nfs4_free_pages(struct page **pages, size_t size) | ||
6234 | { | ||
6235 | int i; | ||
6236 | |||
6237 | if (!pages) | ||
6238 | return; | ||
6239 | |||
6240 | for (i = 0; i < size; i++) { | ||
6241 | if (!pages[i]) | ||
6242 | break; | ||
6243 | __free_page(pages[i]); | ||
6244 | } | ||
6245 | kfree(pages); | ||
6246 | } | ||
6247 | |||
6248 | static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags) | ||
6249 | { | ||
6250 | struct page **pages; | ||
6251 | int i; | ||
6252 | |||
6253 | pages = kcalloc(size, sizeof(struct page *), gfp_flags); | ||
6254 | if (!pages) { | ||
6255 | dprintk("%s: can't alloc array of %zu pages\n", __func__, size); | ||
6256 | return NULL; | ||
6257 | } | ||
6258 | |||
6259 | for (i = 0; i < size; i++) { | ||
6260 | pages[i] = alloc_page(gfp_flags); | ||
6261 | if (!pages[i]) { | ||
6262 | dprintk("%s: failed to allocate page\n", __func__); | ||
6263 | nfs4_free_pages(pages, size); | ||
6264 | return NULL; | ||
6265 | } | ||
6266 | } | ||
6267 | |||
6268 | return pages; | ||
6269 | } | ||
6270 | |||
6226 | static void nfs4_layoutget_release(void *calldata) | 6271 | static void nfs4_layoutget_release(void *calldata) |
6227 | { | 6272 | { |
6228 | struct nfs4_layoutget *lgp = calldata; | 6273 | struct nfs4_layoutget *lgp = calldata; |
6274 | struct nfs_server *server = NFS_SERVER(lgp->args.inode); | ||
6275 | size_t max_pages = max_response_pages(server); | ||
6229 | 6276 | ||
6230 | dprintk("--> %s\n", __func__); | 6277 | dprintk("--> %s\n", __func__); |
6278 | nfs4_free_pages(lgp->args.layout.pages, max_pages); | ||
6231 | put_nfs_open_context(lgp->args.ctx); | 6279 | put_nfs_open_context(lgp->args.ctx); |
6232 | kfree(calldata); | 6280 | kfree(calldata); |
6233 | dprintk("<-- %s\n", __func__); | 6281 | dprintk("<-- %s\n", __func__); |
@@ -6239,9 +6287,10 @@ static const struct rpc_call_ops nfs4_layoutget_call_ops = { | |||
6239 | .rpc_release = nfs4_layoutget_release, | 6287 | .rpc_release = nfs4_layoutget_release, |
6240 | }; | 6288 | }; |
6241 | 6289 | ||
6242 | int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | 6290 | void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) |
6243 | { | 6291 | { |
6244 | struct nfs_server *server = NFS_SERVER(lgp->args.inode); | 6292 | struct nfs_server *server = NFS_SERVER(lgp->args.inode); |
6293 | size_t max_pages = max_response_pages(server); | ||
6245 | struct rpc_task *task; | 6294 | struct rpc_task *task; |
6246 | struct rpc_message msg = { | 6295 | struct rpc_message msg = { |
6247 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET], | 6296 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LAYOUTGET], |
@@ -6259,12 +6308,19 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | |||
6259 | 6308 | ||
6260 | dprintk("--> %s\n", __func__); | 6309 | dprintk("--> %s\n", __func__); |
6261 | 6310 | ||
6311 | lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags); | ||
6312 | if (!lgp->args.layout.pages) { | ||
6313 | nfs4_layoutget_release(lgp); | ||
6314 | return; | ||
6315 | } | ||
6316 | lgp->args.layout.pglen = max_pages * PAGE_SIZE; | ||
6317 | |||
6262 | lgp->res.layoutp = &lgp->args.layout; | 6318 | lgp->res.layoutp = &lgp->args.layout; |
6263 | lgp->res.seq_res.sr_slot = NULL; | 6319 | lgp->res.seq_res.sr_slot = NULL; |
6264 | nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); | 6320 | nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0); |
6265 | task = rpc_run_task(&task_setup_data); | 6321 | task = rpc_run_task(&task_setup_data); |
6266 | if (IS_ERR(task)) | 6322 | if (IS_ERR(task)) |
6267 | return PTR_ERR(task); | 6323 | return; |
6268 | status = nfs4_wait_for_completion_rpc_task(task); | 6324 | status = nfs4_wait_for_completion_rpc_task(task); |
6269 | if (status == 0) | 6325 | if (status == 0) |
6270 | status = task->tk_status; | 6326 | status = task->tk_status; |
@@ -6272,7 +6328,7 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp) | |||
6272 | status = pnfs_layout_process(lgp); | 6328 | status = pnfs_layout_process(lgp); |
6273 | rpc_put_task(task); | 6329 | rpc_put_task(task); |
6274 | dprintk("<-- %s status=%d\n", __func__, status); | 6330 | dprintk("<-- %s status=%d\n", __func__, status); |
6275 | return status; | 6331 | return; |
6276 | } | 6332 | } |
6277 | 6333 | ||
6278 | static void | 6334 | static void |
@@ -6304,12 +6360,8 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata) | |||
6304 | return; | 6360 | return; |
6305 | } | 6361 | } |
6306 | spin_lock(&lo->plh_inode->i_lock); | 6362 | spin_lock(&lo->plh_inode->i_lock); |
6307 | if (task->tk_status == 0) { | 6363 | if (task->tk_status == 0 && lrp->res.lrs_present) |
6308 | if (lrp->res.lrs_present) { | 6364 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); |
6309 | pnfs_set_layout_stateid(lo, &lrp->res.stateid, true); | ||
6310 | } else | ||
6311 | BUG_ON(!list_empty(&lo->plh_segs)); | ||
6312 | } | ||
6313 | lo->plh_block_lgets--; | 6365 | lo->plh_block_lgets--; |
6314 | spin_unlock(&lo->plh_inode->i_lock); | 6366 | spin_unlock(&lo->plh_inode->i_lock); |
6315 | dprintk("<-- %s\n", __func__); | 6367 | dprintk("<-- %s\n", __func__); |
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 12a31a9dbcdd..bd61221ad2c5 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c | |||
@@ -23,14 +23,6 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, | |||
23 | static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, | 23 | static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, |
24 | int flags, const char *dev_name, void *raw_data); | 24 | int flags, const char *dev_name, void *raw_data); |
25 | 25 | ||
26 | static struct file_system_type nfs4_fs_type = { | ||
27 | .owner = THIS_MODULE, | ||
28 | .name = "nfs4", | ||
29 | .mount = nfs_fs_mount, | ||
30 | .kill_sb = nfs_kill_super, | ||
31 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | ||
32 | }; | ||
33 | |||
34 | static struct file_system_type nfs4_remote_fs_type = { | 26 | static struct file_system_type nfs4_remote_fs_type = { |
35 | .owner = THIS_MODULE, | 27 | .owner = THIS_MODULE, |
36 | .name = "nfs4", | 28 | .name = "nfs4", |
@@ -344,14 +336,8 @@ static int __init init_nfs_v4(void) | |||
344 | if (err) | 336 | if (err) |
345 | goto out1; | 337 | goto out1; |
346 | 338 | ||
347 | err = register_filesystem(&nfs4_fs_type); | ||
348 | if (err < 0) | ||
349 | goto out2; | ||
350 | |||
351 | register_nfs_version(&nfs_v4); | 339 | register_nfs_version(&nfs_v4); |
352 | return 0; | 340 | return 0; |
353 | out2: | ||
354 | nfs4_unregister_sysctl(); | ||
355 | out1: | 341 | out1: |
356 | nfs_idmap_quit(); | 342 | nfs_idmap_quit(); |
357 | out: | 343 | out: |
@@ -361,7 +347,6 @@ out: | |||
361 | static void __exit exit_nfs_v4(void) | 347 | static void __exit exit_nfs_v4(void) |
362 | { | 348 | { |
363 | unregister_nfs_version(&nfs_v4); | 349 | unregister_nfs_version(&nfs_v4); |
364 | unregister_filesystem(&nfs4_fs_type); | ||
365 | nfs4_unregister_sysctl(); | 350 | nfs4_unregister_sysctl(); |
366 | nfs_idmap_quit(); | 351 | nfs_idmap_quit(); |
367 | } | 352 | } |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index ca13483edd60..1bfbd67c556d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -5045,22 +5045,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
5045 | struct nfs_getaclres *res) | 5045 | struct nfs_getaclres *res) |
5046 | { | 5046 | { |
5047 | unsigned int savep; | 5047 | unsigned int savep; |
5048 | __be32 *bm_p; | ||
5049 | uint32_t attrlen, | 5048 | uint32_t attrlen, |
5050 | bitmap[3] = {0}; | 5049 | bitmap[3] = {0}; |
5051 | int status; | 5050 | int status; |
5052 | size_t page_len = xdr->buf->page_len; | 5051 | unsigned int pg_offset; |
5053 | 5052 | ||
5054 | res->acl_len = 0; | 5053 | res->acl_len = 0; |
5055 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) | 5054 | if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) |
5056 | goto out; | 5055 | goto out; |
5057 | 5056 | ||
5058 | bm_p = xdr->p; | 5057 | xdr_enter_page(xdr, xdr->buf->page_len); |
5059 | res->acl_data_offset = be32_to_cpup(bm_p) + 2; | 5058 | |
5060 | res->acl_data_offset <<= 2; | 5059 | /* Calculate the offset of the page data */ |
5061 | /* Check if the acl data starts beyond the allocated buffer */ | 5060 | pg_offset = xdr->buf->head[0].iov_len; |
5062 | if (res->acl_data_offset > page_len) | ||
5063 | return -ERANGE; | ||
5064 | 5061 | ||
5065 | if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) | 5062 | if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) |
5066 | goto out; | 5063 | goto out; |
@@ -5074,23 +5071,20 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
5074 | /* The bitmap (xdr len + bitmaps) and the attr xdr len words | 5071 | /* The bitmap (xdr len + bitmaps) and the attr xdr len words |
5075 | * are stored with the acl data to handle the problem of | 5072 | * are stored with the acl data to handle the problem of |
5076 | * variable length bitmaps.*/ | 5073 | * variable length bitmaps.*/ |
5077 | xdr->p = bm_p; | 5074 | res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; |
5078 | 5075 | ||
5079 | /* We ignore &savep and don't do consistency checks on | 5076 | /* We ignore &savep and don't do consistency checks on |
5080 | * the attr length. Let userspace figure it out.... */ | 5077 | * the attr length. Let userspace figure it out.... */ |
5081 | attrlen += res->acl_data_offset; | 5078 | res->acl_len = attrlen; |
5082 | if (attrlen > page_len) { | 5079 | if (attrlen > (xdr->nwords << 2)) { |
5083 | if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { | 5080 | if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { |
5084 | /* getxattr interface called with a NULL buf */ | 5081 | /* getxattr interface called with a NULL buf */ |
5085 | res->acl_len = attrlen; | ||
5086 | goto out; | 5082 | goto out; |
5087 | } | 5083 | } |
5088 | dprintk("NFS: acl reply: attrlen %u > page_len %zu\n", | 5084 | dprintk("NFS: acl reply: attrlen %u > page_len %u\n", |
5089 | attrlen, page_len); | 5085 | attrlen, xdr->nwords << 2); |
5090 | return -EINVAL; | 5086 | return -EINVAL; |
5091 | } | 5087 | } |
5092 | xdr_read_pages(xdr, attrlen); | ||
5093 | res->acl_len = attrlen; | ||
5094 | } else | 5088 | } else |
5095 | status = -EOPNOTSUPP; | 5089 | status = -EOPNOTSUPP; |
5096 | 5090 | ||
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index f50d3e8d6f22..ea6d111b03e9 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -570,17 +570,66 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio, | |||
570 | return false; | 570 | return false; |
571 | 571 | ||
572 | return pgio->pg_count + req->wb_bytes <= | 572 | return pgio->pg_count + req->wb_bytes <= |
573 | OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; | 573 | (unsigned long)pgio->pg_layout_private; |
574 | } | ||
575 | |||
576 | void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) | ||
577 | { | ||
578 | pnfs_generic_pg_init_read(pgio, req); | ||
579 | if (unlikely(pgio->pg_lseg == NULL)) | ||
580 | return; /* Not pNFS */ | ||
581 | |||
582 | pgio->pg_layout_private = (void *) | ||
583 | OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; | ||
584 | } | ||
585 | |||
586 | static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout, | ||
587 | unsigned long *stripe_end) | ||
588 | { | ||
589 | u32 stripe_off; | ||
590 | unsigned stripe_size; | ||
591 | |||
592 | if (layout->raid_algorithm == PNFS_OSD_RAID_0) | ||
593 | return true; | ||
594 | |||
595 | stripe_size = layout->stripe_unit * | ||
596 | (layout->group_width - layout->parity); | ||
597 | |||
598 | div_u64_rem(offset, stripe_size, &stripe_off); | ||
599 | if (!stripe_off) | ||
600 | return true; | ||
601 | |||
602 | *stripe_end = stripe_size - stripe_off; | ||
603 | return false; | ||
604 | } | ||
605 | |||
606 | void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) | ||
607 | { | ||
608 | unsigned long stripe_end = 0; | ||
609 | |||
610 | pnfs_generic_pg_init_write(pgio, req); | ||
611 | if (unlikely(pgio->pg_lseg == NULL)) | ||
612 | return; /* Not pNFS */ | ||
613 | |||
614 | if (req->wb_offset || | ||
615 | !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE, | ||
616 | &OBJIO_LSEG(pgio->pg_lseg)->layout, | ||
617 | &stripe_end)) { | ||
618 | pgio->pg_layout_private = (void *)stripe_end; | ||
619 | } else { | ||
620 | pgio->pg_layout_private = (void *) | ||
621 | OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; | ||
622 | } | ||
574 | } | 623 | } |
575 | 624 | ||
576 | static const struct nfs_pageio_ops objio_pg_read_ops = { | 625 | static const struct nfs_pageio_ops objio_pg_read_ops = { |
577 | .pg_init = pnfs_generic_pg_init_read, | 626 | .pg_init = objio_init_read, |
578 | .pg_test = objio_pg_test, | 627 | .pg_test = objio_pg_test, |
579 | .pg_doio = pnfs_generic_pg_readpages, | 628 | .pg_doio = pnfs_generic_pg_readpages, |
580 | }; | 629 | }; |
581 | 630 | ||
582 | static const struct nfs_pageio_ops objio_pg_write_ops = { | 631 | static const struct nfs_pageio_ops objio_pg_write_ops = { |
583 | .pg_init = pnfs_generic_pg_init_write, | 632 | .pg_init = objio_init_write, |
584 | .pg_test = objio_pg_test, | 633 | .pg_test = objio_pg_test, |
585 | .pg_doio = pnfs_generic_pg_writepages, | 634 | .pg_doio = pnfs_generic_pg_writepages, |
586 | }; | 635 | }; |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 1a6732ed04a4..311a79681e2b 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -49,6 +49,7 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, | |||
49 | hdr->io_start = req_offset(hdr->req); | 49 | hdr->io_start = req_offset(hdr->req); |
50 | hdr->good_bytes = desc->pg_count; | 50 | hdr->good_bytes = desc->pg_count; |
51 | hdr->dreq = desc->pg_dreq; | 51 | hdr->dreq = desc->pg_dreq; |
52 | hdr->layout_private = desc->pg_layout_private; | ||
52 | hdr->release = release; | 53 | hdr->release = release; |
53 | hdr->completion_ops = desc->pg_completion_ops; | 54 | hdr->completion_ops = desc->pg_completion_ops; |
54 | if (hdr->completion_ops->init_hdr) | 55 | if (hdr->completion_ops->init_hdr) |
@@ -268,6 +269,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
268 | desc->pg_error = 0; | 269 | desc->pg_error = 0; |
269 | desc->pg_lseg = NULL; | 270 | desc->pg_lseg = NULL; |
270 | desc->pg_dreq = NULL; | 271 | desc->pg_dreq = NULL; |
272 | desc->pg_layout_private = NULL; | ||
271 | } | 273 | } |
272 | EXPORT_SYMBOL_GPL(nfs_pageio_init); | 274 | EXPORT_SYMBOL_GPL(nfs_pageio_init); |
273 | 275 | ||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 76875bfcf19c..2e00feacd4be 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -583,9 +583,6 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
583 | struct nfs_server *server = NFS_SERVER(ino); | 583 | struct nfs_server *server = NFS_SERVER(ino); |
584 | struct nfs4_layoutget *lgp; | 584 | struct nfs4_layoutget *lgp; |
585 | struct pnfs_layout_segment *lseg = NULL; | 585 | struct pnfs_layout_segment *lseg = NULL; |
586 | struct page **pages = NULL; | ||
587 | int i; | ||
588 | u32 max_resp_sz, max_pages; | ||
589 | 586 | ||
590 | dprintk("--> %s\n", __func__); | 587 | dprintk("--> %s\n", __func__); |
591 | 588 | ||
@@ -594,20 +591,6 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
594 | if (lgp == NULL) | 591 | if (lgp == NULL) |
595 | return NULL; | 592 | return NULL; |
596 | 593 | ||
597 | /* allocate pages for xdr post processing */ | ||
598 | max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; | ||
599 | max_pages = nfs_page_array_len(0, max_resp_sz); | ||
600 | |||
601 | pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); | ||
602 | if (!pages) | ||
603 | goto out_err_free; | ||
604 | |||
605 | for (i = 0; i < max_pages; i++) { | ||
606 | pages[i] = alloc_page(gfp_flags); | ||
607 | if (!pages[i]) | ||
608 | goto out_err_free; | ||
609 | } | ||
610 | |||
611 | lgp->args.minlength = PAGE_CACHE_SIZE; | 594 | lgp->args.minlength = PAGE_CACHE_SIZE; |
612 | if (lgp->args.minlength > range->length) | 595 | if (lgp->args.minlength > range->length) |
613 | lgp->args.minlength = range->length; | 596 | lgp->args.minlength = range->length; |
@@ -616,39 +599,19 @@ send_layoutget(struct pnfs_layout_hdr *lo, | |||
616 | lgp->args.type = server->pnfs_curr_ld->id; | 599 | lgp->args.type = server->pnfs_curr_ld->id; |
617 | lgp->args.inode = ino; | 600 | lgp->args.inode = ino; |
618 | lgp->args.ctx = get_nfs_open_context(ctx); | 601 | lgp->args.ctx = get_nfs_open_context(ctx); |
619 | lgp->args.layout.pages = pages; | ||
620 | lgp->args.layout.pglen = max_pages * PAGE_SIZE; | ||
621 | lgp->lsegpp = &lseg; | 602 | lgp->lsegpp = &lseg; |
622 | lgp->gfp_flags = gfp_flags; | 603 | lgp->gfp_flags = gfp_flags; |
623 | 604 | ||
624 | /* Synchronously retrieve layout information from server and | 605 | /* Synchronously retrieve layout information from server and |
625 | * store in lseg. | 606 | * store in lseg. |
626 | */ | 607 | */ |
627 | nfs4_proc_layoutget(lgp); | 608 | nfs4_proc_layoutget(lgp, gfp_flags); |
628 | if (!lseg) { | 609 | if (!lseg) { |
629 | /* remember that LAYOUTGET failed and suspend trying */ | 610 | /* remember that LAYOUTGET failed and suspend trying */ |
630 | set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); | 611 | set_bit(lo_fail_bit(range->iomode), &lo->plh_flags); |
631 | } | 612 | } |
632 | 613 | ||
633 | /* free xdr pages */ | ||
634 | for (i = 0; i < max_pages; i++) | ||
635 | __free_page(pages[i]); | ||
636 | kfree(pages); | ||
637 | |||
638 | return lseg; | 614 | return lseg; |
639 | |||
640 | out_err_free: | ||
641 | /* free any allocated xdr pages, lgp as it's not used */ | ||
642 | if (pages) { | ||
643 | for (i = 0; i < max_pages; i++) { | ||
644 | if (!pages[i]) | ||
645 | break; | ||
646 | __free_page(pages[i]); | ||
647 | } | ||
648 | kfree(pages); | ||
649 | } | ||
650 | kfree(lgp); | ||
651 | return NULL; | ||
652 | } | 615 | } |
653 | 616 | ||
654 | /* | 617 | /* |
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 2c6c80503ba4..745aa1b39e7c 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h | |||
@@ -172,7 +172,7 @@ extern int nfs4_proc_getdevicelist(struct nfs_server *server, | |||
172 | struct pnfs_devicelist *devlist); | 172 | struct pnfs_devicelist *devlist); |
173 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, | 173 | extern int nfs4_proc_getdeviceinfo(struct nfs_server *server, |
174 | struct pnfs_device *dev); | 174 | struct pnfs_device *dev); |
175 | extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp); | 175 | extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags); |
176 | extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); | 176 | extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp); |
177 | 177 | ||
178 | /* pnfs.c */ | 178 | /* pnfs.c */ |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ac6a3c55dce4..239aff7338eb 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -319,6 +319,34 @@ EXPORT_SYMBOL_GPL(nfs_sops); | |||
319 | static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); | 319 | static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); |
320 | static int nfs4_validate_mount_data(void *options, | 320 | static int nfs4_validate_mount_data(void *options, |
321 | struct nfs_parsed_mount_data *args, const char *dev_name); | 321 | struct nfs_parsed_mount_data *args, const char *dev_name); |
322 | |||
323 | struct file_system_type nfs4_fs_type = { | ||
324 | .owner = THIS_MODULE, | ||
325 | .name = "nfs4", | ||
326 | .mount = nfs_fs_mount, | ||
327 | .kill_sb = nfs_kill_super, | ||
328 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, | ||
329 | }; | ||
330 | EXPORT_SYMBOL_GPL(nfs4_fs_type); | ||
331 | |||
332 | static int __init register_nfs4_fs(void) | ||
333 | { | ||
334 | return register_filesystem(&nfs4_fs_type); | ||
335 | } | ||
336 | |||
337 | static void unregister_nfs4_fs(void) | ||
338 | { | ||
339 | unregister_filesystem(&nfs4_fs_type); | ||
340 | } | ||
341 | #else | ||
342 | static int __init register_nfs4_fs(void) | ||
343 | { | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static void unregister_nfs4_fs(void) | ||
348 | { | ||
349 | } | ||
322 | #endif | 350 | #endif |
323 | 351 | ||
324 | static struct shrinker acl_shrinker = { | 352 | static struct shrinker acl_shrinker = { |
@@ -337,12 +365,18 @@ int __init register_nfs_fs(void) | |||
337 | if (ret < 0) | 365 | if (ret < 0) |
338 | goto error_0; | 366 | goto error_0; |
339 | 367 | ||
340 | ret = nfs_register_sysctl(); | 368 | ret = register_nfs4_fs(); |
341 | if (ret < 0) | 369 | if (ret < 0) |
342 | goto error_1; | 370 | goto error_1; |
371 | |||
372 | ret = nfs_register_sysctl(); | ||
373 | if (ret < 0) | ||
374 | goto error_2; | ||
343 | register_shrinker(&acl_shrinker); | 375 | register_shrinker(&acl_shrinker); |
344 | return 0; | 376 | return 0; |
345 | 377 | ||
378 | error_2: | ||
379 | unregister_nfs4_fs(); | ||
346 | error_1: | 380 | error_1: |
347 | unregister_filesystem(&nfs_fs_type); | 381 | unregister_filesystem(&nfs_fs_type); |
348 | error_0: | 382 | error_0: |
@@ -356,6 +390,7 @@ void __exit unregister_nfs_fs(void) | |||
356 | { | 390 | { |
357 | unregister_shrinker(&acl_shrinker); | 391 | unregister_shrinker(&acl_shrinker); |
358 | nfs_unregister_sysctl(); | 392 | nfs_unregister_sysctl(); |
393 | unregister_nfs4_fs(); | ||
359 | unregister_filesystem(&nfs_fs_type); | 394 | unregister_filesystem(&nfs_fs_type); |
360 | } | 395 | } |
361 | 396 | ||
@@ -2645,4 +2680,6 @@ MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 " | |||
2645 | module_param(send_implementation_id, ushort, 0644); | 2680 | module_param(send_implementation_id, ushort, 0644); |
2646 | MODULE_PARM_DESC(send_implementation_id, | 2681 | MODULE_PARM_DESC(send_implementation_id, |
2647 | "Send implementation ID with NFSv4.1 exchange_id"); | 2682 | "Send implementation ID with NFSv4.1 exchange_id"); |
2683 | MODULE_ALIAS("nfs4"); | ||
2684 | |||
2648 | #endif /* CONFIG_NFS_V4 */ | 2685 | #endif /* CONFIG_NFS_V4 */ |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 5829d0ce7cfb..e3b55372726c 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -1814,19 +1814,19 @@ int __init nfs_init_writepagecache(void) | |||
1814 | nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE, | 1814 | nfs_wdata_mempool = mempool_create_slab_pool(MIN_POOL_WRITE, |
1815 | nfs_wdata_cachep); | 1815 | nfs_wdata_cachep); |
1816 | if (nfs_wdata_mempool == NULL) | 1816 | if (nfs_wdata_mempool == NULL) |
1817 | return -ENOMEM; | 1817 | goto out_destroy_write_cache; |
1818 | 1818 | ||
1819 | nfs_cdata_cachep = kmem_cache_create("nfs_commit_data", | 1819 | nfs_cdata_cachep = kmem_cache_create("nfs_commit_data", |
1820 | sizeof(struct nfs_commit_data), | 1820 | sizeof(struct nfs_commit_data), |
1821 | 0, SLAB_HWCACHE_ALIGN, | 1821 | 0, SLAB_HWCACHE_ALIGN, |
1822 | NULL); | 1822 | NULL); |
1823 | if (nfs_cdata_cachep == NULL) | 1823 | if (nfs_cdata_cachep == NULL) |
1824 | return -ENOMEM; | 1824 | goto out_destroy_write_mempool; |
1825 | 1825 | ||
1826 | nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, | 1826 | nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, |
1827 | nfs_wdata_cachep); | 1827 | nfs_wdata_cachep); |
1828 | if (nfs_commit_mempool == NULL) | 1828 | if (nfs_commit_mempool == NULL) |
1829 | return -ENOMEM; | 1829 | goto out_destroy_commit_cache; |
1830 | 1830 | ||
1831 | /* | 1831 | /* |
1832 | * NFS congestion size, scale with available memory. | 1832 | * NFS congestion size, scale with available memory. |
@@ -1849,11 +1849,20 @@ int __init nfs_init_writepagecache(void) | |||
1849 | nfs_congestion_kb = 256*1024; | 1849 | nfs_congestion_kb = 256*1024; |
1850 | 1850 | ||
1851 | return 0; | 1851 | return 0; |
1852 | |||
1853 | out_destroy_commit_cache: | ||
1854 | kmem_cache_destroy(nfs_cdata_cachep); | ||
1855 | out_destroy_write_mempool: | ||
1856 | mempool_destroy(nfs_wdata_mempool); | ||
1857 | out_destroy_write_cache: | ||
1858 | kmem_cache_destroy(nfs_wdata_cachep); | ||
1859 | return -ENOMEM; | ||
1852 | } | 1860 | } |
1853 | 1861 | ||
1854 | void nfs_destroy_writepagecache(void) | 1862 | void nfs_destroy_writepagecache(void) |
1855 | { | 1863 | { |
1856 | mempool_destroy(nfs_commit_mempool); | 1864 | mempool_destroy(nfs_commit_mempool); |
1865 | kmem_cache_destroy(nfs_cdata_cachep); | ||
1857 | mempool_destroy(nfs_wdata_mempool); | 1866 | mempool_destroy(nfs_wdata_mempool); |
1858 | kmem_cache_destroy(nfs_wdata_cachep); | 1867 | kmem_cache_destroy(nfs_wdata_cachep); |
1859 | } | 1868 | } |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index cbaf4f8bb7b7..4c7bd35b1876 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -651,12 +651,12 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c | |||
651 | 651 | ||
652 | if (clp->cl_minorversion == 0) { | 652 | if (clp->cl_minorversion == 0) { |
653 | if (!clp->cl_cred.cr_principal && | 653 | if (!clp->cl_cred.cr_principal && |
654 | (clp->cl_flavor >= RPC_AUTH_GSS_KRB5)) | 654 | (clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5)) |
655 | return -EINVAL; | 655 | return -EINVAL; |
656 | args.client_name = clp->cl_cred.cr_principal; | 656 | args.client_name = clp->cl_cred.cr_principal; |
657 | args.prognumber = conn->cb_prog, | 657 | args.prognumber = conn->cb_prog, |
658 | args.protocol = XPRT_TRANSPORT_TCP; | 658 | args.protocol = XPRT_TRANSPORT_TCP; |
659 | args.authflavor = clp->cl_flavor; | 659 | args.authflavor = clp->cl_cred.cr_flavor; |
660 | clp->cl_cb_ident = conn->cb_ident; | 660 | clp->cl_cb_ident = conn->cb_ident; |
661 | } else { | 661 | } else { |
662 | if (!conn->cb_xprt) | 662 | if (!conn->cb_xprt) |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index e6173147f982..22bd0a66c356 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -231,7 +231,6 @@ struct nfs4_client { | |||
231 | nfs4_verifier cl_verifier; /* generated by client */ | 231 | nfs4_verifier cl_verifier; /* generated by client */ |
232 | time_t cl_time; /* time of last lease renewal */ | 232 | time_t cl_time; /* time of last lease renewal */ |
233 | struct sockaddr_storage cl_addr; /* client ipaddress */ | 233 | struct sockaddr_storage cl_addr; /* client ipaddress */ |
234 | u32 cl_flavor; /* setclientid pseudoflavor */ | ||
235 | struct svc_cred cl_cred; /* setclientid principal */ | 234 | struct svc_cred cl_cred; /* setclientid principal */ |
236 | clientid_t cl_clientid; /* generated by server */ | 235 | clientid_t cl_clientid; /* generated by server */ |
237 | nfs4_verifier cl_confirm; /* generated by server */ | 236 | nfs4_verifier cl_confirm; /* generated by server */ |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 6522cac6057c..6a10812711c1 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -676,17 +676,13 @@ static const struct super_operations nilfs_sops = { | |||
676 | .alloc_inode = nilfs_alloc_inode, | 676 | .alloc_inode = nilfs_alloc_inode, |
677 | .destroy_inode = nilfs_destroy_inode, | 677 | .destroy_inode = nilfs_destroy_inode, |
678 | .dirty_inode = nilfs_dirty_inode, | 678 | .dirty_inode = nilfs_dirty_inode, |
679 | /* .write_inode = nilfs_write_inode, */ | ||
680 | /* .drop_inode = nilfs_drop_inode, */ | ||
681 | .evict_inode = nilfs_evict_inode, | 679 | .evict_inode = nilfs_evict_inode, |
682 | .put_super = nilfs_put_super, | 680 | .put_super = nilfs_put_super, |
683 | /* .write_super = nilfs_write_super, */ | ||
684 | .sync_fs = nilfs_sync_fs, | 681 | .sync_fs = nilfs_sync_fs, |
685 | .freeze_fs = nilfs_freeze, | 682 | .freeze_fs = nilfs_freeze, |
686 | .unfreeze_fs = nilfs_unfreeze, | 683 | .unfreeze_fs = nilfs_unfreeze, |
687 | .statfs = nilfs_statfs, | 684 | .statfs = nilfs_statfs, |
688 | .remount_fs = nilfs_remount, | 685 | .remount_fs = nilfs_remount, |
689 | /* .umount_begin */ | ||
690 | .show_options = nilfs_show_options | 686 | .show_options = nilfs_show_options |
691 | }; | 687 | }; |
692 | 688 | ||
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 6eee4177807b..be1267a34cea 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -107,8 +107,6 @@ struct the_nilfs { | |||
107 | * used for | 107 | * used for |
108 | * - loading the latest checkpoint exclusively. | 108 | * - loading the latest checkpoint exclusively. |
109 | * - allocating a new full segment. | 109 | * - allocating a new full segment. |
110 | * - protecting s_dirt in the super_block struct | ||
111 | * (see nilfs_write_super) and the following fields. | ||
112 | */ | 110 | */ |
113 | struct buffer_head *ns_sbh[2]; | 111 | struct buffer_head *ns_sbh[2]; |
114 | struct nilfs_super_block *ns_sbp[2]; | 112 | struct nilfs_super_block *ns_sbp[2]; |
@@ -717,7 +717,7 @@ cleanup_all: | |||
717 | * here, so just reset the state. | 717 | * here, so just reset the state. |
718 | */ | 718 | */ |
719 | file_reset_write(f); | 719 | file_reset_write(f); |
720 | mnt_drop_write(f->f_path.mnt); | 720 | __mnt_drop_write(f->f_path.mnt); |
721 | } | 721 | } |
722 | } | 722 | } |
723 | cleanup_file: | 723 | cleanup_file: |
@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
852 | int lookup_flags = 0; | 852 | int lookup_flags = 0; |
853 | int acc_mode; | 853 | int acc_mode; |
854 | 854 | ||
855 | if (!(flags & O_CREAT)) | 855 | if (flags & O_CREAT) |
856 | mode = 0; | 856 | op->mode = (mode & S_IALLUGO) | S_IFREG; |
857 | op->mode = mode; | 857 | else |
858 | op->mode = 0; | ||
858 | 859 | ||
859 | /* Must never be set by userspace */ | 860 | /* Must never be set by userspace */ |
860 | flags &= ~FMODE_NONOTIFY; | 861 | flags &= ~FMODE_NONOTIFY; |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 36a29b753c79..c495a3055e2a 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -1589,10 +1589,10 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1589 | goto out; | 1589 | goto out; |
1590 | } | 1590 | } |
1591 | 1591 | ||
1592 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1593 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1592 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1594 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1593 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1595 | 1594 | ||
1595 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1596 | spin_lock(&dq_data_lock); | 1596 | spin_lock(&dq_data_lock); |
1597 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1597 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1598 | if (!dquots[cnt]) | 1598 | if (!dquots[cnt]) |
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 4c0c7d163d15..a98b7740a0fc 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -1334,9 +1334,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1334 | else if (bitmap == 0) | 1334 | else if (bitmap == 0) |
1335 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; | 1335 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; |
1336 | 1336 | ||
1337 | reiserfs_write_unlock(sb); | ||
1338 | bh = sb_bread(sb, block); | 1337 | bh = sb_bread(sb, block); |
1339 | reiserfs_write_lock(sb); | ||
1340 | if (bh == NULL) | 1338 | if (bh == NULL) |
1341 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) " | 1339 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) " |
1342 | "reading failed", __func__, block); | 1340 | "reading failed", __func__, block); |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a6d4268fb6c1..855da58db145 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -76,10 +76,10 @@ void reiserfs_evict_inode(struct inode *inode) | |||
76 | ; | 76 | ; |
77 | } | 77 | } |
78 | out: | 78 | out: |
79 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
79 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ | 80 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ |
80 | dquot_drop(inode); | 81 | dquot_drop(inode); |
81 | inode->i_blocks = 0; | 82 | inode->i_blocks = 0; |
82 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
83 | return; | 83 | return; |
84 | 84 | ||
85 | no_delete: | 85 | no_delete: |
diff --git a/fs/super.c b/fs/super.c index b05cf47463d0..0902cfa6a12e 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -537,46 +537,6 @@ void drop_super(struct super_block *sb) | |||
537 | EXPORT_SYMBOL(drop_super); | 537 | EXPORT_SYMBOL(drop_super); |
538 | 538 | ||
539 | /** | 539 | /** |
540 | * sync_supers - helper for periodic superblock writeback | ||
541 | * | ||
542 | * Call the write_super method if present on all dirty superblocks in | ||
543 | * the system. This is for the periodic writeback used by most older | ||
544 | * filesystems. For data integrity superblock writeback use | ||
545 | * sync_filesystems() instead. | ||
546 | * | ||
547 | * Note: check the dirty flag before waiting, so we don't | ||
548 | * hold up the sync while mounting a device. (The newly | ||
549 | * mounted device won't need syncing.) | ||
550 | */ | ||
551 | void sync_supers(void) | ||
552 | { | ||
553 | struct super_block *sb, *p = NULL; | ||
554 | |||
555 | spin_lock(&sb_lock); | ||
556 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
557 | if (hlist_unhashed(&sb->s_instances)) | ||
558 | continue; | ||
559 | if (sb->s_op->write_super && sb->s_dirt) { | ||
560 | sb->s_count++; | ||
561 | spin_unlock(&sb_lock); | ||
562 | |||
563 | down_read(&sb->s_umount); | ||
564 | if (sb->s_root && sb->s_dirt && (sb->s_flags & MS_BORN)) | ||
565 | sb->s_op->write_super(sb); | ||
566 | up_read(&sb->s_umount); | ||
567 | |||
568 | spin_lock(&sb_lock); | ||
569 | if (p) | ||
570 | __put_super(p); | ||
571 | p = sb; | ||
572 | } | ||
573 | } | ||
574 | if (p) | ||
575 | __put_super(p); | ||
576 | spin_unlock(&sb_lock); | ||
577 | } | ||
578 | |||
579 | /** | ||
580 | * iterate_supers - call function for all active superblocks | 540 | * iterate_supers - call function for all active superblocks |
581 | * @f: function to call | 541 | * @f: function to call |
582 | * @arg: argument to pass to it | 542 | * @arg: argument to pass to it |
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 8b8cc4e945f4..760de723dadb 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
@@ -167,7 +167,7 @@ struct ubifs_global_debug_info { | |||
167 | #define ubifs_dbg_msg(type, fmt, ...) \ | 167 | #define ubifs_dbg_msg(type, fmt, ...) \ |
168 | pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__) | 168 | pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__) |
169 | 169 | ||
170 | #define DBG_KEY_BUF_LEN 32 | 170 | #define DBG_KEY_BUF_LEN 48 |
171 | #define ubifs_dbg_msg_key(type, key, fmt, ...) do { \ | 171 | #define ubifs_dbg_msg_key(type, key, fmt, ...) do { \ |
172 | char __tmp_key_buf[DBG_KEY_BUF_LEN]; \ | 172 | char __tmp_key_buf[DBG_KEY_BUF_LEN]; \ |
173 | pr_debug("UBIFS DBG " type ": " fmt "%s\n", ##__VA_ARGS__, \ | 173 | pr_debug("UBIFS DBG " type ": " fmt "%s\n", ##__VA_ARGS__, \ |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 35389ca2d267..7bd6e72afd11 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -37,11 +37,11 @@ | |||
37 | * | 37 | * |
38 | * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we | 38 | * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we |
39 | * implement. However, this is not true for 'ubifs_writepage()', which may be | 39 | * implement. However, this is not true for 'ubifs_writepage()', which may be |
40 | * called with @i_mutex unlocked. For example, when pdflush is doing background | 40 | * called with @i_mutex unlocked. For example, when flusher thread is doing |
41 | * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal" | 41 | * background write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. |
42 | * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the | 42 | * At "normal" work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. |
43 | * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()' | 43 | * in the "sys_write -> alloc_pages -> direct reclaim path". So, in |
44 | * we are only guaranteed that the page is locked. | 44 | * 'ubifs_writepage()' we are only guaranteed that the page is locked. |
45 | * | 45 | * |
46 | * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the | 46 | * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the |
47 | * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> | 47 | * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> |
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index ce33b2beb151..8640920766ed 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c | |||
@@ -1749,7 +1749,10 @@ int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr) | |||
1749 | return 0; | 1749 | return 0; |
1750 | 1750 | ||
1751 | out_err: | 1751 | out_err: |
1752 | ubifs_lpt_free(c, 0); | 1752 | if (wr) |
1753 | ubifs_lpt_free(c, 1); | ||
1754 | if (rd) | ||
1755 | ubifs_lpt_free(c, 0); | ||
1753 | return err; | 1756 | return err; |
1754 | } | 1757 | } |
1755 | 1758 | ||
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index c30d976b4be8..edeec499c048 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -788,7 +788,7 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
788 | 788 | ||
789 | corrupted_rescan: | 789 | corrupted_rescan: |
790 | /* Re-scan the corrupted data with verbose messages */ | 790 | /* Re-scan the corrupted data with verbose messages */ |
791 | ubifs_err("corruptio %d", ret); | 791 | ubifs_err("corruption %d", ret); |
792 | ubifs_scan_a_node(c, buf, len, lnum, offs, 1); | 792 | ubifs_scan_a_node(c, buf, len, lnum, offs, 1); |
793 | corrupted: | 793 | corrupted: |
794 | ubifs_scanned_corruption(c, lnum, offs, buf); | 794 | ubifs_scanned_corruption(c, lnum, offs, buf); |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index eba46d4a7619..94d78fc5d4e0 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -1026,7 +1026,6 @@ int ubifs_replay_journal(struct ubifs_info *c) | |||
1026 | c->replaying = 1; | 1026 | c->replaying = 1; |
1027 | lnum = c->ltail_lnum = c->lhead_lnum; | 1027 | lnum = c->ltail_lnum = c->lhead_lnum; |
1028 | 1028 | ||
1029 | lnum = UBIFS_LOG_LNUM; | ||
1030 | do { | 1029 | do { |
1031 | err = replay_log_leb(c, lnum, 0, c->sbuf); | 1030 | err = replay_log_leb(c, lnum, 0, c->sbuf); |
1032 | if (err == 1) | 1031 | if (err == 1) |
@@ -1035,7 +1034,7 @@ int ubifs_replay_journal(struct ubifs_info *c) | |||
1035 | if (err) | 1034 | if (err) |
1036 | goto out; | 1035 | goto out; |
1037 | lnum = ubifs_next_log_lnum(c, lnum); | 1036 | lnum = ubifs_next_log_lnum(c, lnum); |
1038 | } while (lnum != UBIFS_LOG_LNUM); | 1037 | } while (lnum != c->ltail_lnum); |
1039 | 1038 | ||
1040 | err = replay_buds(c); | 1039 | err = replay_buds(c); |
1041 | if (err) | 1040 | if (err) |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 1c766c39c038..71a197f0f93d 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -303,7 +303,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
303 | mutex_lock(&ui->ui_mutex); | 303 | mutex_lock(&ui->ui_mutex); |
304 | /* | 304 | /* |
305 | * Due to races between write-back forced by budgeting | 305 | * Due to races between write-back forced by budgeting |
306 | * (see 'sync_some_inodes()') and pdflush write-back, the inode may | 306 | * (see 'sync_some_inodes()') and background write-back, the inode may |
307 | * have already been synchronized, do not do this again. This might | 307 | * have already been synchronized, do not do this again. This might |
308 | * also happen if it was synchronized in an VFS operation, e.g. | 308 | * also happen if it was synchronized in an VFS operation, e.g. |
309 | * 'ubifs_link()'. | 309 | * 'ubifs_link()'. |
@@ -1157,9 +1157,6 @@ static int check_free_space(struct ubifs_info *c) | |||
1157 | * | 1157 | * |
1158 | * This function mounts UBIFS file system. Returns zero in case of success and | 1158 | * This function mounts UBIFS file system. Returns zero in case of success and |
1159 | * a negative error code in case of failure. | 1159 | * a negative error code in case of failure. |
1160 | * | ||
1161 | * Note, the function does not de-allocate resources it it fails half way | ||
1162 | * through, and the caller has to do this instead. | ||
1163 | */ | 1160 | */ |
1164 | static int mount_ubifs(struct ubifs_info *c) | 1161 | static int mount_ubifs(struct ubifs_info *c) |
1165 | { | 1162 | { |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index fafaad795cd6..aa233469b3c1 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1124,14 +1124,17 @@ int udf_setsize(struct inode *inode, loff_t newsize) | |||
1124 | if (err) | 1124 | if (err) |
1125 | return err; | 1125 | return err; |
1126 | down_write(&iinfo->i_data_sem); | 1126 | down_write(&iinfo->i_data_sem); |
1127 | } else | 1127 | } else { |
1128 | iinfo->i_lenAlloc = newsize; | 1128 | iinfo->i_lenAlloc = newsize; |
1129 | goto set_size; | ||
1130 | } | ||
1129 | } | 1131 | } |
1130 | err = udf_extend_file(inode, newsize); | 1132 | err = udf_extend_file(inode, newsize); |
1131 | if (err) { | 1133 | if (err) { |
1132 | up_write(&iinfo->i_data_sem); | 1134 | up_write(&iinfo->i_data_sem); |
1133 | return err; | 1135 | return err; |
1134 | } | 1136 | } |
1137 | set_size: | ||
1135 | truncate_setsize(inode, newsize); | 1138 | truncate_setsize(inode, newsize); |
1136 | up_write(&iinfo->i_data_sem); | 1139 | up_write(&iinfo->i_data_sem); |
1137 | } else { | 1140 | } else { |
diff --git a/fs/udf/super.c b/fs/udf/super.c index dcbf98722afc..18fc038a438d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1344,6 +1344,7 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1344 | udf_err(sb, "error loading logical volume descriptor: " | 1344 | udf_err(sb, "error loading logical volume descriptor: " |
1345 | "Partition table too long (%u > %lu)\n", table_len, | 1345 | "Partition table too long (%u > %lu)\n", table_len, |
1346 | sb->s_blocksize - sizeof(*lvd)); | 1346 | sb->s_blocksize - sizeof(*lvd)); |
1347 | ret = 1; | ||
1347 | goto out_bh; | 1348 | goto out_bh; |
1348 | } | 1349 | } |
1349 | 1350 | ||
@@ -1388,8 +1389,10 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1388 | UDF_ID_SPARABLE, | 1389 | UDF_ID_SPARABLE, |
1389 | strlen(UDF_ID_SPARABLE))) { | 1390 | strlen(UDF_ID_SPARABLE))) { |
1390 | if (udf_load_sparable_map(sb, map, | 1391 | if (udf_load_sparable_map(sb, map, |
1391 | (struct sparablePartitionMap *)gpm) < 0) | 1392 | (struct sparablePartitionMap *)gpm) < 0) { |
1393 | ret = 1; | ||
1392 | goto out_bh; | 1394 | goto out_bh; |
1395 | } | ||
1393 | } else if (!strncmp(upm2->partIdent.ident, | 1396 | } else if (!strncmp(upm2->partIdent.ident, |
1394 | UDF_ID_METADATA, | 1397 | UDF_ID_METADATA, |
1395 | strlen(UDF_ID_METADATA))) { | 1398 | strlen(UDF_ID_METADATA))) { |
@@ -2000,6 +2003,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
2000 | if (!silent) | 2003 | if (!silent) |
2001 | pr_notice("Rescanning with blocksize %d\n", | 2004 | pr_notice("Rescanning with blocksize %d\n", |
2002 | UDF_DEFAULT_BLOCKSIZE); | 2005 | UDF_DEFAULT_BLOCKSIZE); |
2006 | brelse(sbi->s_lvid_bh); | ||
2007 | sbi->s_lvid_bh = NULL; | ||
2003 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; | 2008 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; |
2004 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | 2009 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
2005 | } | 2010 | } |