diff options
Diffstat (limited to 'fs')
43 files changed, 542 insertions, 511 deletions
diff --git a/fs/affs/super.c b/fs/affs/super.c index 6d589f28bf9b..895ac7dc9dbf 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -340,8 +340,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
340 | &blocksize,&sbi->s_prefix, | 340 | &blocksize,&sbi->s_prefix, |
341 | sbi->s_volume, &mount_flags)) { | 341 | sbi->s_volume, &mount_flags)) { |
342 | printk(KERN_ERR "AFFS: Error parsing options\n"); | 342 | printk(KERN_ERR "AFFS: Error parsing options\n"); |
343 | kfree(sbi->s_prefix); | ||
344 | kfree(sbi); | ||
345 | return -EINVAL; | 343 | return -EINVAL; |
346 | } | 344 | } |
347 | /* N.B. after this point s_prefix must be released */ | 345 | /* N.B. after this point s_prefix must be released */ |
@@ -112,6 +112,11 @@ struct kioctx { | |||
112 | 112 | ||
113 | struct work_struct free_work; | 113 | struct work_struct free_work; |
114 | 114 | ||
115 | /* | ||
116 | * signals when all in-flight requests are done | ||
117 | */ | ||
118 | struct completion *requests_done; | ||
119 | |||
115 | struct { | 120 | struct { |
116 | /* | 121 | /* |
117 | * This counts the number of available slots in the ringbuffer, | 122 | * This counts the number of available slots in the ringbuffer, |
@@ -508,6 +513,10 @@ static void free_ioctx_reqs(struct percpu_ref *ref) | |||
508 | { | 513 | { |
509 | struct kioctx *ctx = container_of(ref, struct kioctx, reqs); | 514 | struct kioctx *ctx = container_of(ref, struct kioctx, reqs); |
510 | 515 | ||
516 | /* At this point we know that there are no any in-flight requests */ | ||
517 | if (ctx->requests_done) | ||
518 | complete(ctx->requests_done); | ||
519 | |||
511 | INIT_WORK(&ctx->free_work, free_ioctx); | 520 | INIT_WORK(&ctx->free_work, free_ioctx); |
512 | schedule_work(&ctx->free_work); | 521 | schedule_work(&ctx->free_work); |
513 | } | 522 | } |
@@ -718,7 +727,8 @@ err: | |||
718 | * when the processes owning a context have all exited to encourage | 727 | * when the processes owning a context have all exited to encourage |
719 | * the rapid destruction of the kioctx. | 728 | * the rapid destruction of the kioctx. |
720 | */ | 729 | */ |
721 | static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx) | 730 | static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, |
731 | struct completion *requests_done) | ||
722 | { | 732 | { |
723 | if (!atomic_xchg(&ctx->dead, 1)) { | 733 | if (!atomic_xchg(&ctx->dead, 1)) { |
724 | struct kioctx_table *table; | 734 | struct kioctx_table *table; |
@@ -747,7 +757,11 @@ static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx) | |||
747 | if (ctx->mmap_size) | 757 | if (ctx->mmap_size) |
748 | vm_munmap(ctx->mmap_base, ctx->mmap_size); | 758 | vm_munmap(ctx->mmap_base, ctx->mmap_size); |
749 | 759 | ||
760 | ctx->requests_done = requests_done; | ||
750 | percpu_ref_kill(&ctx->users); | 761 | percpu_ref_kill(&ctx->users); |
762 | } else { | ||
763 | if (requests_done) | ||
764 | complete(requests_done); | ||
751 | } | 765 | } |
752 | } | 766 | } |
753 | 767 | ||
@@ -809,7 +823,7 @@ void exit_aio(struct mm_struct *mm) | |||
809 | */ | 823 | */ |
810 | ctx->mmap_size = 0; | 824 | ctx->mmap_size = 0; |
811 | 825 | ||
812 | kill_ioctx(mm, ctx); | 826 | kill_ioctx(mm, ctx, NULL); |
813 | } | 827 | } |
814 | } | 828 | } |
815 | 829 | ||
@@ -1185,7 +1199,7 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) | |||
1185 | if (!IS_ERR(ioctx)) { | 1199 | if (!IS_ERR(ioctx)) { |
1186 | ret = put_user(ioctx->user_id, ctxp); | 1200 | ret = put_user(ioctx->user_id, ctxp); |
1187 | if (ret) | 1201 | if (ret) |
1188 | kill_ioctx(current->mm, ioctx); | 1202 | kill_ioctx(current->mm, ioctx, NULL); |
1189 | percpu_ref_put(&ioctx->users); | 1203 | percpu_ref_put(&ioctx->users); |
1190 | } | 1204 | } |
1191 | 1205 | ||
@@ -1203,8 +1217,22 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) | |||
1203 | { | 1217 | { |
1204 | struct kioctx *ioctx = lookup_ioctx(ctx); | 1218 | struct kioctx *ioctx = lookup_ioctx(ctx); |
1205 | if (likely(NULL != ioctx)) { | 1219 | if (likely(NULL != ioctx)) { |
1206 | kill_ioctx(current->mm, ioctx); | 1220 | struct completion requests_done = |
1221 | COMPLETION_INITIALIZER_ONSTACK(requests_done); | ||
1222 | |||
1223 | /* Pass requests_done to kill_ioctx() where it can be set | ||
1224 | * in a thread-safe way. If we try to set it here then we have | ||
1225 | * a race condition if two io_destroy() called simultaneously. | ||
1226 | */ | ||
1227 | kill_ioctx(current->mm, ioctx, &requests_done); | ||
1207 | percpu_ref_put(&ioctx->users); | 1228 | percpu_ref_put(&ioctx->users); |
1229 | |||
1230 | /* Wait until all IO for the context are done. Otherwise kernel | ||
1231 | * keep using user-space buffers even if user thinks the context | ||
1232 | * is destroyed. | ||
1233 | */ | ||
1234 | wait_for_completion(&requests_done); | ||
1235 | |||
1208 | return 0; | 1236 | return 0; |
1209 | } | 1237 | } |
1210 | pr_debug("EINVAL: io_destroy: invalid context id\n"); | 1238 | pr_debug("EINVAL: io_destroy: invalid context id\n"); |
@@ -1299,10 +1327,8 @@ rw_common: | |||
1299 | &iovec, compat) | 1327 | &iovec, compat) |
1300 | : aio_setup_single_vector(req, rw, buf, &nr_segs, | 1328 | : aio_setup_single_vector(req, rw, buf, &nr_segs, |
1301 | iovec); | 1329 | iovec); |
1302 | if (ret) | 1330 | if (!ret) |
1303 | return ret; | 1331 | ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes); |
1304 | |||
1305 | ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes); | ||
1306 | if (ret < 0) { | 1332 | if (ret < 0) { |
1307 | if (iovec != &inline_vec) | 1333 | if (iovec != &inline_vec) |
1308 | kfree(iovec); | 1334 | kfree(iovec); |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 2caf36ac3e93..cc87c1abac97 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -179,7 +179,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
179 | spin_lock(&active->d_lock); | 179 | spin_lock(&active->d_lock); |
180 | 180 | ||
181 | /* Already gone? */ | 181 | /* Already gone? */ |
182 | if (!d_count(active)) | 182 | if ((int) d_count(active) <= 0) |
183 | goto next; | 183 | goto next; |
184 | 184 | ||
185 | qstr = &active->d_name; | 185 | qstr = &active->d_name; |
@@ -230,7 +230,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
230 | 230 | ||
231 | spin_lock(&expiring->d_lock); | 231 | spin_lock(&expiring->d_lock); |
232 | 232 | ||
233 | /* Bad luck, we've already been dentry_iput */ | 233 | /* We've already been dentry_iput or unlinked */ |
234 | if (!expiring->d_inode) | 234 | if (!expiring->d_inode) |
235 | goto next; | 235 | goto next; |
236 | 236 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 2ad7de94efef..2f6d7b13b5bd 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -3120,6 +3120,8 @@ process_slot: | |||
3120 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { | 3120 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { |
3121 | u64 skip = 0; | 3121 | u64 skip = 0; |
3122 | u64 trim = 0; | 3122 | u64 trim = 0; |
3123 | u64 aligned_end = 0; | ||
3124 | |||
3123 | if (off > key.offset) { | 3125 | if (off > key.offset) { |
3124 | skip = off - key.offset; | 3126 | skip = off - key.offset; |
3125 | new_key.offset += skip; | 3127 | new_key.offset += skip; |
@@ -3136,9 +3138,11 @@ process_slot: | |||
3136 | size -= skip + trim; | 3138 | size -= skip + trim; |
3137 | datal -= skip + trim; | 3139 | datal -= skip + trim; |
3138 | 3140 | ||
3141 | aligned_end = ALIGN(new_key.offset + datal, | ||
3142 | root->sectorsize); | ||
3139 | ret = btrfs_drop_extents(trans, root, inode, | 3143 | ret = btrfs_drop_extents(trans, root, inode, |
3140 | new_key.offset, | 3144 | new_key.offset, |
3141 | new_key.offset + datal, | 3145 | aligned_end, |
3142 | 1); | 3146 | 1); |
3143 | if (ret) { | 3147 | if (ret) { |
3144 | if (ret != -EOPNOTSUPP) | 3148 | if (ret != -EOPNOTSUPP) |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index eb6537a08c1b..fd38b5053479 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -1668,7 +1668,7 @@ static int get_first_ref(struct btrfs_root *root, u64 ino, | |||
1668 | goto out; | 1668 | goto out; |
1669 | } | 1669 | } |
1670 | 1670 | ||
1671 | if (key.type == BTRFS_INODE_REF_KEY) { | 1671 | if (found_key.type == BTRFS_INODE_REF_KEY) { |
1672 | struct btrfs_inode_ref *iref; | 1672 | struct btrfs_inode_ref *iref; |
1673 | iref = btrfs_item_ptr(path->nodes[0], path->slots[0], | 1673 | iref = btrfs_item_ptr(path->nodes[0], path->slots[0], |
1674 | struct btrfs_inode_ref); | 1674 | struct btrfs_inode_ref); |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 2e5e648eb5c3..c561b628ebce 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -3261,7 +3261,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode, | |||
3261 | rel->seq = cpu_to_le32(cap->seq); | 3261 | rel->seq = cpu_to_le32(cap->seq); |
3262 | rel->issue_seq = cpu_to_le32(cap->issue_seq), | 3262 | rel->issue_seq = cpu_to_le32(cap->issue_seq), |
3263 | rel->mseq = cpu_to_le32(cap->mseq); | 3263 | rel->mseq = cpu_to_le32(cap->mseq); |
3264 | rel->caps = cpu_to_le32(cap->issued); | 3264 | rel->caps = cpu_to_le32(cap->implemented); |
3265 | rel->wanted = cpu_to_le32(cap->mds_wanted); | 3265 | rel->wanted = cpu_to_le32(cap->mds_wanted); |
3266 | rel->dname_len = 0; | 3266 | rel->dname_len = 0; |
3267 | rel->dname_seq = 0; | 3267 | rel->dname_seq = 0; |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 766410a12c2c..c29d6ae68874 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -141,7 +141,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, | |||
141 | 141 | ||
142 | /* start at beginning? */ | 142 | /* start at beginning? */ |
143 | if (ctx->pos == 2 || last == NULL || | 143 | if (ctx->pos == 2 || last == NULL || |
144 | ctx->pos < ceph_dentry(last)->offset) { | 144 | fpos_cmp(ctx->pos, ceph_dentry(last)->offset) < 0) { |
145 | if (list_empty(&parent->d_subdirs)) | 145 | if (list_empty(&parent->d_subdirs)) |
146 | goto out_unlock; | 146 | goto out_unlock; |
147 | p = parent->d_subdirs.prev; | 147 | p = parent->d_subdirs.prev; |
@@ -182,9 +182,16 @@ more: | |||
182 | spin_unlock(&dentry->d_lock); | 182 | spin_unlock(&dentry->d_lock); |
183 | spin_unlock(&parent->d_lock); | 183 | spin_unlock(&parent->d_lock); |
184 | 184 | ||
185 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ | ||
186 | if (!ceph_dir_is_complete(dir)) { | ||
187 | dout(" lost dir complete on %p; falling back to mds\n", dir); | ||
188 | dput(dentry); | ||
189 | err = -EAGAIN; | ||
190 | goto out; | ||
191 | } | ||
192 | |||
185 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, | 193 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, |
186 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); | 194 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); |
187 | ctx->pos = di->offset; | ||
188 | if (!dir_emit(ctx, dentry->d_name.name, | 195 | if (!dir_emit(ctx, dentry->d_name.name, |
189 | dentry->d_name.len, | 196 | dentry->d_name.len, |
190 | ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), | 197 | ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), |
@@ -198,19 +205,12 @@ more: | |||
198 | return 0; | 205 | return 0; |
199 | } | 206 | } |
200 | 207 | ||
208 | ctx->pos = di->offset + 1; | ||
209 | |||
201 | if (last) | 210 | if (last) |
202 | dput(last); | 211 | dput(last); |
203 | last = dentry; | 212 | last = dentry; |
204 | 213 | ||
205 | ctx->pos++; | ||
206 | |||
207 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ | ||
208 | if (!ceph_dir_is_complete(dir)) { | ||
209 | dout(" lost dir complete on %p; falling back to mds\n", dir); | ||
210 | err = -EAGAIN; | ||
211 | goto out; | ||
212 | } | ||
213 | |||
214 | spin_lock(&parent->d_lock); | 214 | spin_lock(&parent->d_lock); |
215 | p = p->prev; /* advance to next dentry */ | 215 | p = p->prev; /* advance to next dentry */ |
216 | goto more; | 216 | goto more; |
@@ -296,6 +296,8 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) | |||
296 | err = __dcache_readdir(file, ctx, shared_gen); | 296 | err = __dcache_readdir(file, ctx, shared_gen); |
297 | if (err != -EAGAIN) | 297 | if (err != -EAGAIN) |
298 | return err; | 298 | return err; |
299 | frag = fpos_frag(ctx->pos); | ||
300 | off = fpos_off(ctx->pos); | ||
299 | } else { | 301 | } else { |
300 | spin_unlock(&ci->i_ceph_lock); | 302 | spin_unlock(&ci->i_ceph_lock); |
301 | } | 303 | } |
@@ -446,7 +448,6 @@ more: | |||
446 | if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { | 448 | if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { |
447 | dout(" marking %p complete\n", inode); | 449 | dout(" marking %p complete\n", inode); |
448 | __ceph_dir_set_complete(ci, fi->dir_release_count); | 450 | __ceph_dir_set_complete(ci, fi->dir_release_count); |
449 | ci->i_max_offset = ctx->pos; | ||
450 | } | 451 | } |
451 | spin_unlock(&ci->i_ceph_lock); | 452 | spin_unlock(&ci->i_ceph_lock); |
452 | 453 | ||
@@ -935,14 +936,16 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
935 | * to do it here. | 936 | * to do it here. |
936 | */ | 937 | */ |
937 | 938 | ||
938 | /* d_move screws up d_subdirs order */ | ||
939 | ceph_dir_clear_complete(new_dir); | ||
940 | |||
941 | d_move(old_dentry, new_dentry); | 939 | d_move(old_dentry, new_dentry); |
942 | 940 | ||
943 | /* ensure target dentry is invalidated, despite | 941 | /* ensure target dentry is invalidated, despite |
944 | rehashing bug in vfs_rename_dir */ | 942 | rehashing bug in vfs_rename_dir */ |
945 | ceph_invalidate_dentry_lease(new_dentry); | 943 | ceph_invalidate_dentry_lease(new_dentry); |
944 | |||
945 | /* d_move screws up sibling dentries' offsets */ | ||
946 | ceph_dir_clear_complete(old_dir); | ||
947 | ceph_dir_clear_complete(new_dir); | ||
948 | |||
946 | } | 949 | } |
947 | ceph_mdsc_put_request(req); | 950 | ceph_mdsc_put_request(req); |
948 | return err; | 951 | return err; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 0b0728e5be2d..233c6f96910a 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -744,7 +744,6 @@ static int fill_inode(struct inode *inode, | |||
744 | !__ceph_dir_is_complete(ci)) { | 744 | !__ceph_dir_is_complete(ci)) { |
745 | dout(" marking %p complete (empty)\n", inode); | 745 | dout(" marking %p complete (empty)\n", inode); |
746 | __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count)); | 746 | __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count)); |
747 | ci->i_max_offset = 2; | ||
748 | } | 747 | } |
749 | no_change: | 748 | no_change: |
750 | /* only update max_size on auth cap */ | 749 | /* only update max_size on auth cap */ |
@@ -890,41 +889,6 @@ out_unlock: | |||
890 | } | 889 | } |
891 | 890 | ||
892 | /* | 891 | /* |
893 | * Set dentry's directory position based on the current dir's max, and | ||
894 | * order it in d_subdirs, so that dcache_readdir behaves. | ||
895 | * | ||
896 | * Always called under directory's i_mutex. | ||
897 | */ | ||
898 | static void ceph_set_dentry_offset(struct dentry *dn) | ||
899 | { | ||
900 | struct dentry *dir = dn->d_parent; | ||
901 | struct inode *inode = dir->d_inode; | ||
902 | struct ceph_inode_info *ci; | ||
903 | struct ceph_dentry_info *di; | ||
904 | |||
905 | BUG_ON(!inode); | ||
906 | |||
907 | ci = ceph_inode(inode); | ||
908 | di = ceph_dentry(dn); | ||
909 | |||
910 | spin_lock(&ci->i_ceph_lock); | ||
911 | if (!__ceph_dir_is_complete(ci)) { | ||
912 | spin_unlock(&ci->i_ceph_lock); | ||
913 | return; | ||
914 | } | ||
915 | di->offset = ceph_inode(inode)->i_max_offset++; | ||
916 | spin_unlock(&ci->i_ceph_lock); | ||
917 | |||
918 | spin_lock(&dir->d_lock); | ||
919 | spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); | ||
920 | list_move(&dn->d_u.d_child, &dir->d_subdirs); | ||
921 | dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, | ||
922 | dn->d_u.d_child.prev, dn->d_u.d_child.next); | ||
923 | spin_unlock(&dn->d_lock); | ||
924 | spin_unlock(&dir->d_lock); | ||
925 | } | ||
926 | |||
927 | /* | ||
928 | * splice a dentry to an inode. | 892 | * splice a dentry to an inode. |
929 | * caller must hold directory i_mutex for this to be safe. | 893 | * caller must hold directory i_mutex for this to be safe. |
930 | * | 894 | * |
@@ -933,7 +897,7 @@ static void ceph_set_dentry_offset(struct dentry *dn) | |||
933 | * the caller) if we fail. | 897 | * the caller) if we fail. |
934 | */ | 898 | */ |
935 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | 899 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, |
936 | bool *prehash, bool set_offset) | 900 | bool *prehash) |
937 | { | 901 | { |
938 | struct dentry *realdn; | 902 | struct dentry *realdn; |
939 | 903 | ||
@@ -965,8 +929,6 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | |||
965 | } | 929 | } |
966 | if ((!prehash || *prehash) && d_unhashed(dn)) | 930 | if ((!prehash || *prehash) && d_unhashed(dn)) |
967 | d_rehash(dn); | 931 | d_rehash(dn); |
968 | if (set_offset) | ||
969 | ceph_set_dentry_offset(dn); | ||
970 | out: | 932 | out: |
971 | return dn; | 933 | return dn; |
972 | } | 934 | } |
@@ -987,7 +949,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
987 | { | 949 | { |
988 | struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; | 950 | struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; |
989 | struct inode *in = NULL; | 951 | struct inode *in = NULL; |
990 | struct ceph_mds_reply_inode *ininfo; | ||
991 | struct ceph_vino vino; | 952 | struct ceph_vino vino; |
992 | struct ceph_fs_client *fsc = ceph_sb_to_client(sb); | 953 | struct ceph_fs_client *fsc = ceph_sb_to_client(sb); |
993 | int err = 0; | 954 | int err = 0; |
@@ -1161,6 +1122,9 @@ retry_lookup: | |||
1161 | 1122 | ||
1162 | /* rename? */ | 1123 | /* rename? */ |
1163 | if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) { | 1124 | if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) { |
1125 | struct inode *olddir = req->r_old_dentry_dir; | ||
1126 | BUG_ON(!olddir); | ||
1127 | |||
1164 | dout(" src %p '%.*s' dst %p '%.*s'\n", | 1128 | dout(" src %p '%.*s' dst %p '%.*s'\n", |
1165 | req->r_old_dentry, | 1129 | req->r_old_dentry, |
1166 | req->r_old_dentry->d_name.len, | 1130 | req->r_old_dentry->d_name.len, |
@@ -1180,13 +1144,10 @@ retry_lookup: | |||
1180 | rehashing bug in vfs_rename_dir */ | 1144 | rehashing bug in vfs_rename_dir */ |
1181 | ceph_invalidate_dentry_lease(dn); | 1145 | ceph_invalidate_dentry_lease(dn); |
1182 | 1146 | ||
1183 | /* | 1147 | /* d_move screws up sibling dentries' offsets */ |
1184 | * d_move() puts the renamed dentry at the end of | 1148 | ceph_dir_clear_complete(dir); |
1185 | * d_subdirs. We need to assign it an appropriate | 1149 | ceph_dir_clear_complete(olddir); |
1186 | * directory offset so we can behave when dir is | 1150 | |
1187 | * complete. | ||
1188 | */ | ||
1189 | ceph_set_dentry_offset(req->r_old_dentry); | ||
1190 | dout("dn %p gets new offset %lld\n", req->r_old_dentry, | 1151 | dout("dn %p gets new offset %lld\n", req->r_old_dentry, |
1191 | ceph_dentry(req->r_old_dentry)->offset); | 1152 | ceph_dentry(req->r_old_dentry)->offset); |
1192 | 1153 | ||
@@ -1213,8 +1174,9 @@ retry_lookup: | |||
1213 | 1174 | ||
1214 | /* attach proper inode */ | 1175 | /* attach proper inode */ |
1215 | if (!dn->d_inode) { | 1176 | if (!dn->d_inode) { |
1177 | ceph_dir_clear_complete(dir); | ||
1216 | ihold(in); | 1178 | ihold(in); |
1217 | dn = splice_dentry(dn, in, &have_lease, true); | 1179 | dn = splice_dentry(dn, in, &have_lease); |
1218 | if (IS_ERR(dn)) { | 1180 | if (IS_ERR(dn)) { |
1219 | err = PTR_ERR(dn); | 1181 | err = PTR_ERR(dn); |
1220 | goto done; | 1182 | goto done; |
@@ -1235,17 +1197,16 @@ retry_lookup: | |||
1235 | (req->r_op == CEPH_MDS_OP_LOOKUPSNAP || | 1197 | (req->r_op == CEPH_MDS_OP_LOOKUPSNAP || |
1236 | req->r_op == CEPH_MDS_OP_MKSNAP)) { | 1198 | req->r_op == CEPH_MDS_OP_MKSNAP)) { |
1237 | struct dentry *dn = req->r_dentry; | 1199 | struct dentry *dn = req->r_dentry; |
1200 | struct inode *dir = req->r_locked_dir; | ||
1238 | 1201 | ||
1239 | /* fill out a snapdir LOOKUPSNAP dentry */ | 1202 | /* fill out a snapdir LOOKUPSNAP dentry */ |
1240 | BUG_ON(!dn); | 1203 | BUG_ON(!dn); |
1241 | BUG_ON(!req->r_locked_dir); | 1204 | BUG_ON(!dir); |
1242 | BUG_ON(ceph_snap(req->r_locked_dir) != CEPH_SNAPDIR); | 1205 | BUG_ON(ceph_snap(dir) != CEPH_SNAPDIR); |
1243 | ininfo = rinfo->targeti.in; | ||
1244 | vino.ino = le64_to_cpu(ininfo->ino); | ||
1245 | vino.snap = le64_to_cpu(ininfo->snapid); | ||
1246 | dout(" linking snapped dir %p to dn %p\n", in, dn); | 1206 | dout(" linking snapped dir %p to dn %p\n", in, dn); |
1207 | ceph_dir_clear_complete(dir); | ||
1247 | ihold(in); | 1208 | ihold(in); |
1248 | dn = splice_dentry(dn, in, NULL, true); | 1209 | dn = splice_dentry(dn, in, NULL); |
1249 | if (IS_ERR(dn)) { | 1210 | if (IS_ERR(dn)) { |
1250 | err = PTR_ERR(dn); | 1211 | err = PTR_ERR(dn); |
1251 | goto done; | 1212 | goto done; |
@@ -1407,7 +1368,7 @@ retry_lookup: | |||
1407 | } | 1368 | } |
1408 | 1369 | ||
1409 | if (!dn->d_inode) { | 1370 | if (!dn->d_inode) { |
1410 | dn = splice_dentry(dn, in, NULL, false); | 1371 | dn = splice_dentry(dn, in, NULL); |
1411 | if (IS_ERR(dn)) { | 1372 | if (IS_ERR(dn)) { |
1412 | err = PTR_ERR(dn); | 1373 | err = PTR_ERR(dn); |
1413 | dn = NULL; | 1374 | dn = NULL; |
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index fdf941b44ff1..a822a6e58290 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
@@ -109,6 +109,8 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
109 | return PTR_ERR(req); | 109 | return PTR_ERR(req); |
110 | req->r_inode = inode; | 110 | req->r_inode = inode; |
111 | ihold(inode); | 111 | ihold(inode); |
112 | req->r_num_caps = 1; | ||
113 | |||
112 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; | 114 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; |
113 | 115 | ||
114 | req->r_args.setlayout.layout.fl_stripe_unit = | 116 | req->r_args.setlayout.layout.fl_stripe_unit = |
@@ -153,6 +155,7 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg) | |||
153 | return PTR_ERR(req); | 155 | return PTR_ERR(req); |
154 | req->r_inode = inode; | 156 | req->r_inode = inode; |
155 | ihold(inode); | 157 | ihold(inode); |
158 | req->r_num_caps = 1; | ||
156 | 159 | ||
157 | req->r_args.setlayout.layout.fl_stripe_unit = | 160 | req->r_args.setlayout.layout.fl_stripe_unit = |
158 | cpu_to_le32(l.stripe_unit); | 161 | cpu_to_le32(l.stripe_unit); |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index d94ba0df9f4d..191398852a2e 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -45,6 +45,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
45 | return PTR_ERR(req); | 45 | return PTR_ERR(req); |
46 | req->r_inode = inode; | 46 | req->r_inode = inode; |
47 | ihold(inode); | 47 | ihold(inode); |
48 | req->r_num_caps = 1; | ||
48 | 49 | ||
49 | /* mds requires start and length rather than start and end */ | 50 | /* mds requires start and length rather than start and end */ |
50 | if (LLONG_MAX == fl->fl_end) | 51 | if (LLONG_MAX == fl->fl_end) |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 7866cd05a6bb..ead05cc1f447 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -266,7 +266,6 @@ struct ceph_inode_info { | |||
266 | struct timespec i_rctime; | 266 | struct timespec i_rctime; |
267 | u64 i_rbytes, i_rfiles, i_rsubdirs; | 267 | u64 i_rbytes, i_rfiles, i_rsubdirs; |
268 | u64 i_files, i_subdirs; | 268 | u64 i_files, i_subdirs; |
269 | u64 i_max_offset; /* largest readdir offset, set with complete dir */ | ||
270 | 269 | ||
271 | struct rb_root i_fragtree; | 270 | struct rb_root i_fragtree; |
272 | struct mutex i_fragtree_mutex; | 271 | struct mutex i_fragtree_mutex; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index aadc2b68678b..a22d667f1069 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1737,6 +1737,9 @@ cifs_inode_needs_reval(struct inode *inode) | |||
1737 | if (cifs_i->time == 0) | 1737 | if (cifs_i->time == 0) |
1738 | return true; | 1738 | return true; |
1739 | 1739 | ||
1740 | if (!cifs_sb->actimeo) | ||
1741 | return true; | ||
1742 | |||
1740 | if (!time_in_range(jiffies, cifs_i->time, | 1743 | if (!time_in_range(jiffies, cifs_i->time, |
1741 | cifs_i->time + cifs_sb->actimeo)) | 1744 | cifs_i->time + cifs_sb->actimeo)) |
1742 | return true; | 1745 | return true; |
diff --git a/fs/dcache.c b/fs/dcache.c index 40707d88a945..42ae01eefc07 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -246,16 +246,8 @@ static void __d_free(struct rcu_head *head) | |||
246 | kmem_cache_free(dentry_cache, dentry); | 246 | kmem_cache_free(dentry_cache, dentry); |
247 | } | 247 | } |
248 | 248 | ||
249 | /* | 249 | static void dentry_free(struct dentry *dentry) |
250 | * no locks, please. | ||
251 | */ | ||
252 | static void d_free(struct dentry *dentry) | ||
253 | { | 250 | { |
254 | BUG_ON((int)dentry->d_lockref.count > 0); | ||
255 | this_cpu_dec(nr_dentry); | ||
256 | if (dentry->d_op && dentry->d_op->d_release) | ||
257 | dentry->d_op->d_release(dentry); | ||
258 | |||
259 | /* if dentry was never visible to RCU, immediate free is OK */ | 251 | /* if dentry was never visible to RCU, immediate free is OK */ |
260 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) | 252 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) |
261 | __d_free(&dentry->d_u.d_rcu); | 253 | __d_free(&dentry->d_u.d_rcu); |
@@ -403,56 +395,6 @@ static void dentry_lru_add(struct dentry *dentry) | |||
403 | d_lru_add(dentry); | 395 | d_lru_add(dentry); |
404 | } | 396 | } |
405 | 397 | ||
406 | /* | ||
407 | * Remove a dentry with references from the LRU. | ||
408 | * | ||
409 | * If we are on the shrink list, then we can get to try_prune_one_dentry() and | ||
410 | * lose our last reference through the parent walk. In this case, we need to | ||
411 | * remove ourselves from the shrink list, not the LRU. | ||
412 | */ | ||
413 | static void dentry_lru_del(struct dentry *dentry) | ||
414 | { | ||
415 | if (dentry->d_flags & DCACHE_LRU_LIST) { | ||
416 | if (dentry->d_flags & DCACHE_SHRINK_LIST) | ||
417 | return d_shrink_del(dentry); | ||
418 | d_lru_del(dentry); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * d_kill - kill dentry and return parent | ||
424 | * @dentry: dentry to kill | ||
425 | * @parent: parent dentry | ||
426 | * | ||
427 | * The dentry must already be unhashed and removed from the LRU. | ||
428 | * | ||
429 | * If this is the root of the dentry tree, return NULL. | ||
430 | * | ||
431 | * dentry->d_lock and parent->d_lock must be held by caller, and are dropped by | ||
432 | * d_kill. | ||
433 | */ | ||
434 | static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) | ||
435 | __releases(dentry->d_lock) | ||
436 | __releases(parent->d_lock) | ||
437 | __releases(dentry->d_inode->i_lock) | ||
438 | { | ||
439 | list_del(&dentry->d_u.d_child); | ||
440 | /* | ||
441 | * Inform d_walk() that we are no longer attached to the | ||
442 | * dentry tree | ||
443 | */ | ||
444 | dentry->d_flags |= DCACHE_DENTRY_KILLED; | ||
445 | if (parent) | ||
446 | spin_unlock(&parent->d_lock); | ||
447 | dentry_iput(dentry); | ||
448 | /* | ||
449 | * dentry_iput drops the locks, at which point nobody (except | ||
450 | * transient RCU lookups) can reach this dentry. | ||
451 | */ | ||
452 | d_free(dentry); | ||
453 | return parent; | ||
454 | } | ||
455 | |||
456 | /** | 398 | /** |
457 | * d_drop - drop a dentry | 399 | * d_drop - drop a dentry |
458 | * @dentry: dentry to drop | 400 | * @dentry: dentry to drop |
@@ -510,7 +452,14 @@ dentry_kill(struct dentry *dentry, int unlock_on_failure) | |||
510 | __releases(dentry->d_lock) | 452 | __releases(dentry->d_lock) |
511 | { | 453 | { |
512 | struct inode *inode; | 454 | struct inode *inode; |
513 | struct dentry *parent; | 455 | struct dentry *parent = NULL; |
456 | bool can_free = true; | ||
457 | |||
458 | if (unlikely(dentry->d_flags & DCACHE_DENTRY_KILLED)) { | ||
459 | can_free = dentry->d_flags & DCACHE_MAY_FREE; | ||
460 | spin_unlock(&dentry->d_lock); | ||
461 | goto out; | ||
462 | } | ||
514 | 463 | ||
515 | inode = dentry->d_inode; | 464 | inode = dentry->d_inode; |
516 | if (inode && !spin_trylock(&inode->i_lock)) { | 465 | if (inode && !spin_trylock(&inode->i_lock)) { |
@@ -521,9 +470,7 @@ relock: | |||
521 | } | 470 | } |
522 | return dentry; /* try again with same dentry */ | 471 | return dentry; /* try again with same dentry */ |
523 | } | 472 | } |
524 | if (IS_ROOT(dentry)) | 473 | if (!IS_ROOT(dentry)) |
525 | parent = NULL; | ||
526 | else | ||
527 | parent = dentry->d_parent; | 474 | parent = dentry->d_parent; |
528 | if (parent && !spin_trylock(&parent->d_lock)) { | 475 | if (parent && !spin_trylock(&parent->d_lock)) { |
529 | if (inode) | 476 | if (inode) |
@@ -543,10 +490,40 @@ relock: | |||
543 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && !d_unhashed(dentry)) | 490 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && !d_unhashed(dentry)) |
544 | dentry->d_op->d_prune(dentry); | 491 | dentry->d_op->d_prune(dentry); |
545 | 492 | ||
546 | dentry_lru_del(dentry); | 493 | if (dentry->d_flags & DCACHE_LRU_LIST) { |
494 | if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) | ||
495 | d_lru_del(dentry); | ||
496 | } | ||
547 | /* if it was on the hash then remove it */ | 497 | /* if it was on the hash then remove it */ |
548 | __d_drop(dentry); | 498 | __d_drop(dentry); |
549 | return d_kill(dentry, parent); | 499 | list_del(&dentry->d_u.d_child); |
500 | /* | ||
501 | * Inform d_walk() that we are no longer attached to the | ||
502 | * dentry tree | ||
503 | */ | ||
504 | dentry->d_flags |= DCACHE_DENTRY_KILLED; | ||
505 | if (parent) | ||
506 | spin_unlock(&parent->d_lock); | ||
507 | dentry_iput(dentry); | ||
508 | /* | ||
509 | * dentry_iput drops the locks, at which point nobody (except | ||
510 | * transient RCU lookups) can reach this dentry. | ||
511 | */ | ||
512 | BUG_ON((int)dentry->d_lockref.count > 0); | ||
513 | this_cpu_dec(nr_dentry); | ||
514 | if (dentry->d_op && dentry->d_op->d_release) | ||
515 | dentry->d_op->d_release(dentry); | ||
516 | |||
517 | spin_lock(&dentry->d_lock); | ||
518 | if (dentry->d_flags & DCACHE_SHRINK_LIST) { | ||
519 | dentry->d_flags |= DCACHE_MAY_FREE; | ||
520 | can_free = false; | ||
521 | } | ||
522 | spin_unlock(&dentry->d_lock); | ||
523 | out: | ||
524 | if (likely(can_free)) | ||
525 | dentry_free(dentry); | ||
526 | return parent; | ||
550 | } | 527 | } |
551 | 528 | ||
552 | /* | 529 | /* |
@@ -815,65 +792,13 @@ restart: | |||
815 | } | 792 | } |
816 | EXPORT_SYMBOL(d_prune_aliases); | 793 | EXPORT_SYMBOL(d_prune_aliases); |
817 | 794 | ||
818 | /* | ||
819 | * Try to throw away a dentry - free the inode, dput the parent. | ||
820 | * Requires dentry->d_lock is held, and dentry->d_count == 0. | ||
821 | * Releases dentry->d_lock. | ||
822 | * | ||
823 | * This may fail if locks cannot be acquired no problem, just try again. | ||
824 | */ | ||
825 | static struct dentry * try_prune_one_dentry(struct dentry *dentry) | ||
826 | __releases(dentry->d_lock) | ||
827 | { | ||
828 | struct dentry *parent; | ||
829 | |||
830 | parent = dentry_kill(dentry, 0); | ||
831 | /* | ||
832 | * If dentry_kill returns NULL, we have nothing more to do. | ||
833 | * if it returns the same dentry, trylocks failed. In either | ||
834 | * case, just loop again. | ||
835 | * | ||
836 | * Otherwise, we need to prune ancestors too. This is necessary | ||
837 | * to prevent quadratic behavior of shrink_dcache_parent(), but | ||
838 | * is also expected to be beneficial in reducing dentry cache | ||
839 | * fragmentation. | ||
840 | */ | ||
841 | if (!parent) | ||
842 | return NULL; | ||
843 | if (parent == dentry) | ||
844 | return dentry; | ||
845 | |||
846 | /* Prune ancestors. */ | ||
847 | dentry = parent; | ||
848 | while (dentry) { | ||
849 | if (lockref_put_or_lock(&dentry->d_lockref)) | ||
850 | return NULL; | ||
851 | dentry = dentry_kill(dentry, 1); | ||
852 | } | ||
853 | return NULL; | ||
854 | } | ||
855 | |||
856 | static void shrink_dentry_list(struct list_head *list) | 795 | static void shrink_dentry_list(struct list_head *list) |
857 | { | 796 | { |
858 | struct dentry *dentry; | 797 | struct dentry *dentry, *parent; |
859 | 798 | ||
860 | rcu_read_lock(); | 799 | while (!list_empty(list)) { |
861 | for (;;) { | 800 | dentry = list_entry(list->prev, struct dentry, d_lru); |
862 | dentry = list_entry_rcu(list->prev, struct dentry, d_lru); | ||
863 | if (&dentry->d_lru == list) | ||
864 | break; /* empty */ | ||
865 | |||
866 | /* | ||
867 | * Get the dentry lock, and re-verify that the dentry is | ||
868 | * this on the shrinking list. If it is, we know that | ||
869 | * DCACHE_SHRINK_LIST and DCACHE_LRU_LIST are set. | ||
870 | */ | ||
871 | spin_lock(&dentry->d_lock); | 801 | spin_lock(&dentry->d_lock); |
872 | if (dentry != list_entry(list->prev, struct dentry, d_lru)) { | ||
873 | spin_unlock(&dentry->d_lock); | ||
874 | continue; | ||
875 | } | ||
876 | |||
877 | /* | 802 | /* |
878 | * The dispose list is isolated and dentries are not accounted | 803 | * The dispose list is isolated and dentries are not accounted |
879 | * to the LRU here, so we can simply remove it from the list | 804 | * to the LRU here, so we can simply remove it from the list |
@@ -885,30 +810,38 @@ static void shrink_dentry_list(struct list_head *list) | |||
885 | * We found an inuse dentry which was not removed from | 810 | * We found an inuse dentry which was not removed from |
886 | * the LRU because of laziness during lookup. Do not free it. | 811 | * the LRU because of laziness during lookup. Do not free it. |
887 | */ | 812 | */ |
888 | if (dentry->d_lockref.count) { | 813 | if ((int)dentry->d_lockref.count > 0) { |
889 | spin_unlock(&dentry->d_lock); | 814 | spin_unlock(&dentry->d_lock); |
890 | continue; | 815 | continue; |
891 | } | 816 | } |
892 | rcu_read_unlock(); | ||
893 | 817 | ||
818 | parent = dentry_kill(dentry, 0); | ||
894 | /* | 819 | /* |
895 | * If 'try_to_prune()' returns a dentry, it will | 820 | * If dentry_kill returns NULL, we have nothing more to do. |
896 | * be the same one we passed in, and d_lock will | ||
897 | * have been held the whole time, so it will not | ||
898 | * have been added to any other lists. We failed | ||
899 | * to get the inode lock. | ||
900 | * | ||
901 | * We just add it back to the shrink list. | ||
902 | */ | 821 | */ |
903 | dentry = try_prune_one_dentry(dentry); | 822 | if (!parent) |
823 | continue; | ||
904 | 824 | ||
905 | rcu_read_lock(); | 825 | if (unlikely(parent == dentry)) { |
906 | if (dentry) { | 826 | /* |
827 | * trylocks have failed and d_lock has been held the | ||
828 | * whole time, so it could not have been added to any | ||
829 | * other lists. Just add it back to the shrink list. | ||
830 | */ | ||
907 | d_shrink_add(dentry, list); | 831 | d_shrink_add(dentry, list); |
908 | spin_unlock(&dentry->d_lock); | 832 | spin_unlock(&dentry->d_lock); |
833 | continue; | ||
909 | } | 834 | } |
835 | /* | ||
836 | * We need to prune ancestors too. This is necessary to prevent | ||
837 | * quadratic behavior of shrink_dcache_parent(), but is also | ||
838 | * expected to be beneficial in reducing dentry cache | ||
839 | * fragmentation. | ||
840 | */ | ||
841 | dentry = parent; | ||
842 | while (dentry && !lockref_put_or_lock(&dentry->d_lockref)) | ||
843 | dentry = dentry_kill(dentry, 1); | ||
910 | } | 844 | } |
911 | rcu_read_unlock(); | ||
912 | } | 845 | } |
913 | 846 | ||
914 | static enum lru_status | 847 | static enum lru_status |
@@ -1261,34 +1194,23 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry) | |||
1261 | if (data->start == dentry) | 1194 | if (data->start == dentry) |
1262 | goto out; | 1195 | goto out; |
1263 | 1196 | ||
1264 | /* | 1197 | if (dentry->d_flags & DCACHE_SHRINK_LIST) { |
1265 | * move only zero ref count dentries to the dispose list. | ||
1266 | * | ||
1267 | * Those which are presently on the shrink list, being processed | ||
1268 | * by shrink_dentry_list(), shouldn't be moved. Otherwise the | ||
1269 | * loop in shrink_dcache_parent() might not make any progress | ||
1270 | * and loop forever. | ||
1271 | */ | ||
1272 | if (dentry->d_lockref.count) { | ||
1273 | dentry_lru_del(dentry); | ||
1274 | } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { | ||
1275 | /* | ||
1276 | * We can't use d_lru_shrink_move() because we | ||
1277 | * need to get the global LRU lock and do the | ||
1278 | * LRU accounting. | ||
1279 | */ | ||
1280 | d_lru_del(dentry); | ||
1281 | d_shrink_add(dentry, &data->dispose); | ||
1282 | data->found++; | 1198 | data->found++; |
1283 | ret = D_WALK_NORETRY; | 1199 | } else { |
1200 | if (dentry->d_flags & DCACHE_LRU_LIST) | ||
1201 | d_lru_del(dentry); | ||
1202 | if (!dentry->d_lockref.count) { | ||
1203 | d_shrink_add(dentry, &data->dispose); | ||
1204 | data->found++; | ||
1205 | } | ||
1284 | } | 1206 | } |
1285 | /* | 1207 | /* |
1286 | * We can return to the caller if we have found some (this | 1208 | * We can return to the caller if we have found some (this |
1287 | * ensures forward progress). We'll be coming back to find | 1209 | * ensures forward progress). We'll be coming back to find |
1288 | * the rest. | 1210 | * the rest. |
1289 | */ | 1211 | */ |
1290 | if (data->found && need_resched()) | 1212 | if (!list_empty(&data->dispose)) |
1291 | ret = D_WALK_QUIT; | 1213 | ret = need_resched() ? D_WALK_QUIT : D_WALK_NORETRY; |
1292 | out: | 1214 | out: |
1293 | return ret; | 1215 | return ret; |
1294 | } | 1216 | } |
@@ -1318,45 +1240,35 @@ void shrink_dcache_parent(struct dentry *parent) | |||
1318 | } | 1240 | } |
1319 | EXPORT_SYMBOL(shrink_dcache_parent); | 1241 | EXPORT_SYMBOL(shrink_dcache_parent); |
1320 | 1242 | ||
1321 | static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) | 1243 | static enum d_walk_ret umount_check(void *_data, struct dentry *dentry) |
1322 | { | 1244 | { |
1323 | struct select_data *data = _data; | 1245 | /* it has busy descendents; complain about those instead */ |
1324 | enum d_walk_ret ret = D_WALK_CONTINUE; | 1246 | if (!list_empty(&dentry->d_subdirs)) |
1247 | return D_WALK_CONTINUE; | ||
1325 | 1248 | ||
1326 | if (dentry->d_lockref.count) { | 1249 | /* root with refcount 1 is fine */ |
1327 | dentry_lru_del(dentry); | 1250 | if (dentry == _data && dentry->d_lockref.count == 1) |
1328 | if (likely(!list_empty(&dentry->d_subdirs))) | 1251 | return D_WALK_CONTINUE; |
1329 | goto out; | 1252 | |
1330 | if (dentry == data->start && dentry->d_lockref.count == 1) | 1253 | printk(KERN_ERR "BUG: Dentry %p{i=%lx,n=%pd} " |
1331 | goto out; | 1254 | " still in use (%d) [unmount of %s %s]\n", |
1332 | printk(KERN_ERR | ||
1333 | "BUG: Dentry %p{i=%lx,n=%s}" | ||
1334 | " still in use (%d)" | ||
1335 | " [unmount of %s %s]\n", | ||
1336 | dentry, | 1255 | dentry, |
1337 | dentry->d_inode ? | 1256 | dentry->d_inode ? |
1338 | dentry->d_inode->i_ino : 0UL, | 1257 | dentry->d_inode->i_ino : 0UL, |
1339 | dentry->d_name.name, | 1258 | dentry, |
1340 | dentry->d_lockref.count, | 1259 | dentry->d_lockref.count, |
1341 | dentry->d_sb->s_type->name, | 1260 | dentry->d_sb->s_type->name, |
1342 | dentry->d_sb->s_id); | 1261 | dentry->d_sb->s_id); |
1343 | BUG(); | 1262 | WARN_ON(1); |
1344 | } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { | 1263 | return D_WALK_CONTINUE; |
1345 | /* | 1264 | } |
1346 | * We can't use d_lru_shrink_move() because we | 1265 | |
1347 | * need to get the global LRU lock and do the | 1266 | static void do_one_tree(struct dentry *dentry) |
1348 | * LRU accounting. | 1267 | { |
1349 | */ | 1268 | shrink_dcache_parent(dentry); |
1350 | if (dentry->d_flags & DCACHE_LRU_LIST) | 1269 | d_walk(dentry, dentry, umount_check, NULL); |
1351 | d_lru_del(dentry); | 1270 | d_drop(dentry); |
1352 | d_shrink_add(dentry, &data->dispose); | 1271 | dput(dentry); |
1353 | data->found++; | ||
1354 | ret = D_WALK_NORETRY; | ||
1355 | } | ||
1356 | out: | ||
1357 | if (data->found && need_resched()) | ||
1358 | ret = D_WALK_QUIT; | ||
1359 | return ret; | ||
1360 | } | 1272 | } |
1361 | 1273 | ||
1362 | /* | 1274 | /* |
@@ -1366,40 +1278,15 @@ void shrink_dcache_for_umount(struct super_block *sb) | |||
1366 | { | 1278 | { |
1367 | struct dentry *dentry; | 1279 | struct dentry *dentry; |
1368 | 1280 | ||
1369 | if (down_read_trylock(&sb->s_umount)) | 1281 | WARN(down_read_trylock(&sb->s_umount), "s_umount should've been locked"); |
1370 | BUG(); | ||
1371 | 1282 | ||
1372 | dentry = sb->s_root; | 1283 | dentry = sb->s_root; |
1373 | sb->s_root = NULL; | 1284 | sb->s_root = NULL; |
1374 | for (;;) { | 1285 | do_one_tree(dentry); |
1375 | struct select_data data; | ||
1376 | |||
1377 | INIT_LIST_HEAD(&data.dispose); | ||
1378 | data.start = dentry; | ||
1379 | data.found = 0; | ||
1380 | |||
1381 | d_walk(dentry, &data, umount_collect, NULL); | ||
1382 | if (!data.found) | ||
1383 | break; | ||
1384 | |||
1385 | shrink_dentry_list(&data.dispose); | ||
1386 | cond_resched(); | ||
1387 | } | ||
1388 | d_drop(dentry); | ||
1389 | dput(dentry); | ||
1390 | 1286 | ||
1391 | while (!hlist_bl_empty(&sb->s_anon)) { | 1287 | while (!hlist_bl_empty(&sb->s_anon)) { |
1392 | struct select_data data; | 1288 | dentry = dget(hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash)); |
1393 | dentry = hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash); | 1289 | do_one_tree(dentry); |
1394 | |||
1395 | INIT_LIST_HEAD(&data.dispose); | ||
1396 | data.start = NULL; | ||
1397 | data.found = 0; | ||
1398 | |||
1399 | d_walk(dentry, &data, umount_collect, NULL); | ||
1400 | if (data.found) | ||
1401 | shrink_dentry_list(&data.dispose); | ||
1402 | cond_resched(); | ||
1403 | } | 1290 | } |
1404 | } | 1291 | } |
1405 | 1292 | ||
@@ -1647,8 +1534,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
1647 | unsigned add_flags = d_flags_for_inode(inode); | 1534 | unsigned add_flags = d_flags_for_inode(inode); |
1648 | 1535 | ||
1649 | spin_lock(&dentry->d_lock); | 1536 | spin_lock(&dentry->d_lock); |
1650 | dentry->d_flags &= ~DCACHE_ENTRY_TYPE; | 1537 | __d_set_type(dentry, add_flags); |
1651 | dentry->d_flags |= add_flags; | ||
1652 | if (inode) | 1538 | if (inode) |
1653 | hlist_add_head(&dentry->d_alias, &inode->i_dentry); | 1539 | hlist_add_head(&dentry->d_alias, &inode->i_dentry); |
1654 | dentry->d_inode = inode; | 1540 | dentry->d_inode = inode; |
@@ -657,10 +657,10 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
657 | unsigned long rlim_stack; | 657 | unsigned long rlim_stack; |
658 | 658 | ||
659 | #ifdef CONFIG_STACK_GROWSUP | 659 | #ifdef CONFIG_STACK_GROWSUP |
660 | /* Limit stack size to 1GB */ | 660 | /* Limit stack size */ |
661 | stack_base = rlimit_max(RLIMIT_STACK); | 661 | stack_base = rlimit_max(RLIMIT_STACK); |
662 | if (stack_base > (1 << 30)) | 662 | if (stack_base > STACK_SIZE_MAX) |
663 | stack_base = 1 << 30; | 663 | stack_base = STACK_SIZE_MAX; |
664 | 664 | ||
665 | /* Make sure we didn't let the argument array grow too large. */ | 665 | /* Make sure we didn't let the argument array grow too large. */ |
666 | if (vma->vm_end - vma->vm_start > stack_base) | 666 | if (vma->vm_end - vma->vm_start > stack_base) |
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index a0b0855d00a9..205e0d5d5307 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
@@ -348,7 +348,7 @@ int __init fuse_ctl_init(void) | |||
348 | return register_filesystem(&fuse_ctl_fs_type); | 348 | return register_filesystem(&fuse_ctl_fs_type); |
349 | } | 349 | } |
350 | 350 | ||
351 | void fuse_ctl_cleanup(void) | 351 | void __exit fuse_ctl_cleanup(void) |
352 | { | 352 | { |
353 | unregister_filesystem(&fuse_ctl_fs_type); | 353 | unregister_filesystem(&fuse_ctl_fs_type); |
354 | } | 354 | } |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 5b4e035b364c..42198359fa1b 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -679,6 +679,14 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry, | |||
679 | return create_new_entry(fc, req, dir, entry, S_IFLNK); | 679 | return create_new_entry(fc, req, dir, entry, S_IFLNK); |
680 | } | 680 | } |
681 | 681 | ||
682 | static inline void fuse_update_ctime(struct inode *inode) | ||
683 | { | ||
684 | if (!IS_NOCMTIME(inode)) { | ||
685 | inode->i_ctime = current_fs_time(inode->i_sb); | ||
686 | mark_inode_dirty_sync(inode); | ||
687 | } | ||
688 | } | ||
689 | |||
682 | static int fuse_unlink(struct inode *dir, struct dentry *entry) | 690 | static int fuse_unlink(struct inode *dir, struct dentry *entry) |
683 | { | 691 | { |
684 | int err; | 692 | int err; |
@@ -713,6 +721,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) | |||
713 | fuse_invalidate_attr(inode); | 721 | fuse_invalidate_attr(inode); |
714 | fuse_invalidate_attr(dir); | 722 | fuse_invalidate_attr(dir); |
715 | fuse_invalidate_entry_cache(entry); | 723 | fuse_invalidate_entry_cache(entry); |
724 | fuse_update_ctime(inode); | ||
716 | } else if (err == -EINTR) | 725 | } else if (err == -EINTR) |
717 | fuse_invalidate_entry(entry); | 726 | fuse_invalidate_entry(entry); |
718 | return err; | 727 | return err; |
@@ -743,23 +752,26 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
743 | return err; | 752 | return err; |
744 | } | 753 | } |
745 | 754 | ||
746 | static int fuse_rename(struct inode *olddir, struct dentry *oldent, | 755 | static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, |
747 | struct inode *newdir, struct dentry *newent) | 756 | struct inode *newdir, struct dentry *newent, |
757 | unsigned int flags, int opcode, size_t argsize) | ||
748 | { | 758 | { |
749 | int err; | 759 | int err; |
750 | struct fuse_rename_in inarg; | 760 | struct fuse_rename2_in inarg; |
751 | struct fuse_conn *fc = get_fuse_conn(olddir); | 761 | struct fuse_conn *fc = get_fuse_conn(olddir); |
752 | struct fuse_req *req = fuse_get_req_nopages(fc); | 762 | struct fuse_req *req; |
753 | 763 | ||
764 | req = fuse_get_req_nopages(fc); | ||
754 | if (IS_ERR(req)) | 765 | if (IS_ERR(req)) |
755 | return PTR_ERR(req); | 766 | return PTR_ERR(req); |
756 | 767 | ||
757 | memset(&inarg, 0, sizeof(inarg)); | 768 | memset(&inarg, 0, argsize); |
758 | inarg.newdir = get_node_id(newdir); | 769 | inarg.newdir = get_node_id(newdir); |
759 | req->in.h.opcode = FUSE_RENAME; | 770 | inarg.flags = flags; |
771 | req->in.h.opcode = opcode; | ||
760 | req->in.h.nodeid = get_node_id(olddir); | 772 | req->in.h.nodeid = get_node_id(olddir); |
761 | req->in.numargs = 3; | 773 | req->in.numargs = 3; |
762 | req->in.args[0].size = sizeof(inarg); | 774 | req->in.args[0].size = argsize; |
763 | req->in.args[0].value = &inarg; | 775 | req->in.args[0].value = &inarg; |
764 | req->in.args[1].size = oldent->d_name.len + 1; | 776 | req->in.args[1].size = oldent->d_name.len + 1; |
765 | req->in.args[1].value = oldent->d_name.name; | 777 | req->in.args[1].value = oldent->d_name.name; |
@@ -771,15 +783,22 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
771 | if (!err) { | 783 | if (!err) { |
772 | /* ctime changes */ | 784 | /* ctime changes */ |
773 | fuse_invalidate_attr(oldent->d_inode); | 785 | fuse_invalidate_attr(oldent->d_inode); |
786 | fuse_update_ctime(oldent->d_inode); | ||
787 | |||
788 | if (flags & RENAME_EXCHANGE) { | ||
789 | fuse_invalidate_attr(newent->d_inode); | ||
790 | fuse_update_ctime(newent->d_inode); | ||
791 | } | ||
774 | 792 | ||
775 | fuse_invalidate_attr(olddir); | 793 | fuse_invalidate_attr(olddir); |
776 | if (olddir != newdir) | 794 | if (olddir != newdir) |
777 | fuse_invalidate_attr(newdir); | 795 | fuse_invalidate_attr(newdir); |
778 | 796 | ||
779 | /* newent will end up negative */ | 797 | /* newent will end up negative */ |
780 | if (newent->d_inode) { | 798 | if (!(flags & RENAME_EXCHANGE) && newent->d_inode) { |
781 | fuse_invalidate_attr(newent->d_inode); | 799 | fuse_invalidate_attr(newent->d_inode); |
782 | fuse_invalidate_entry_cache(newent); | 800 | fuse_invalidate_entry_cache(newent); |
801 | fuse_update_ctime(newent->d_inode); | ||
783 | } | 802 | } |
784 | } else if (err == -EINTR) { | 803 | } else if (err == -EINTR) { |
785 | /* If request was interrupted, DEITY only knows if the | 804 | /* If request was interrupted, DEITY only knows if the |
@@ -795,6 +814,36 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
795 | return err; | 814 | return err; |
796 | } | 815 | } |
797 | 816 | ||
817 | static int fuse_rename(struct inode *olddir, struct dentry *oldent, | ||
818 | struct inode *newdir, struct dentry *newent) | ||
819 | { | ||
820 | return fuse_rename_common(olddir, oldent, newdir, newent, 0, | ||
821 | FUSE_RENAME, sizeof(struct fuse_rename_in)); | ||
822 | } | ||
823 | |||
824 | static int fuse_rename2(struct inode *olddir, struct dentry *oldent, | ||
825 | struct inode *newdir, struct dentry *newent, | ||
826 | unsigned int flags) | ||
827 | { | ||
828 | struct fuse_conn *fc = get_fuse_conn(olddir); | ||
829 | int err; | ||
830 | |||
831 | if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) | ||
832 | return -EINVAL; | ||
833 | |||
834 | if (fc->no_rename2 || fc->minor < 23) | ||
835 | return -EINVAL; | ||
836 | |||
837 | err = fuse_rename_common(olddir, oldent, newdir, newent, flags, | ||
838 | FUSE_RENAME2, sizeof(struct fuse_rename2_in)); | ||
839 | if (err == -ENOSYS) { | ||
840 | fc->no_rename2 = 1; | ||
841 | err = -EINVAL; | ||
842 | } | ||
843 | return err; | ||
844 | |||
845 | } | ||
846 | |||
798 | static int fuse_link(struct dentry *entry, struct inode *newdir, | 847 | static int fuse_link(struct dentry *entry, struct inode *newdir, |
799 | struct dentry *newent) | 848 | struct dentry *newent) |
800 | { | 849 | { |
@@ -829,6 +878,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, | |||
829 | inc_nlink(inode); | 878 | inc_nlink(inode); |
830 | spin_unlock(&fc->lock); | 879 | spin_unlock(&fc->lock); |
831 | fuse_invalidate_attr(inode); | 880 | fuse_invalidate_attr(inode); |
881 | fuse_update_ctime(inode); | ||
832 | } else if (err == -EINTR) { | 882 | } else if (err == -EINTR) { |
833 | fuse_invalidate_attr(inode); | 883 | fuse_invalidate_attr(inode); |
834 | } | 884 | } |
@@ -846,6 +896,8 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, | |||
846 | attr->size = i_size_read(inode); | 896 | attr->size = i_size_read(inode); |
847 | attr->mtime = inode->i_mtime.tv_sec; | 897 | attr->mtime = inode->i_mtime.tv_sec; |
848 | attr->mtimensec = inode->i_mtime.tv_nsec; | 898 | attr->mtimensec = inode->i_mtime.tv_nsec; |
899 | attr->ctime = inode->i_ctime.tv_sec; | ||
900 | attr->ctimensec = inode->i_ctime.tv_nsec; | ||
849 | } | 901 | } |
850 | 902 | ||
851 | stat->dev = inode->i_sb->s_dev; | 903 | stat->dev = inode->i_sb->s_dev; |
@@ -1504,7 +1556,7 @@ static bool update_mtime(unsigned ivalid, bool trust_local_mtime) | |||
1504 | } | 1556 | } |
1505 | 1557 | ||
1506 | static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, | 1558 | static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, |
1507 | bool trust_local_mtime) | 1559 | bool trust_local_cmtime) |
1508 | { | 1560 | { |
1509 | unsigned ivalid = iattr->ia_valid; | 1561 | unsigned ivalid = iattr->ia_valid; |
1510 | 1562 | ||
@@ -1523,13 +1575,18 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, | |||
1523 | if (!(ivalid & ATTR_ATIME_SET)) | 1575 | if (!(ivalid & ATTR_ATIME_SET)) |
1524 | arg->valid |= FATTR_ATIME_NOW; | 1576 | arg->valid |= FATTR_ATIME_NOW; |
1525 | } | 1577 | } |
1526 | if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_mtime)) { | 1578 | if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) { |
1527 | arg->valid |= FATTR_MTIME; | 1579 | arg->valid |= FATTR_MTIME; |
1528 | arg->mtime = iattr->ia_mtime.tv_sec; | 1580 | arg->mtime = iattr->ia_mtime.tv_sec; |
1529 | arg->mtimensec = iattr->ia_mtime.tv_nsec; | 1581 | arg->mtimensec = iattr->ia_mtime.tv_nsec; |
1530 | if (!(ivalid & ATTR_MTIME_SET) && !trust_local_mtime) | 1582 | if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime) |
1531 | arg->valid |= FATTR_MTIME_NOW; | 1583 | arg->valid |= FATTR_MTIME_NOW; |
1532 | } | 1584 | } |
1585 | if ((ivalid & ATTR_CTIME) && trust_local_cmtime) { | ||
1586 | arg->valid |= FATTR_CTIME; | ||
1587 | arg->ctime = iattr->ia_ctime.tv_sec; | ||
1588 | arg->ctimensec = iattr->ia_ctime.tv_nsec; | ||
1589 | } | ||
1533 | } | 1590 | } |
1534 | 1591 | ||
1535 | /* | 1592 | /* |
@@ -1597,39 +1654,38 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req, | |||
1597 | /* | 1654 | /* |
1598 | * Flush inode->i_mtime to the server | 1655 | * Flush inode->i_mtime to the server |
1599 | */ | 1656 | */ |
1600 | int fuse_flush_mtime(struct file *file, bool nofail) | 1657 | int fuse_flush_times(struct inode *inode, struct fuse_file *ff) |
1601 | { | 1658 | { |
1602 | struct inode *inode = file->f_mapping->host; | ||
1603 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
1604 | struct fuse_conn *fc = get_fuse_conn(inode); | 1659 | struct fuse_conn *fc = get_fuse_conn(inode); |
1605 | struct fuse_req *req = NULL; | 1660 | struct fuse_req *req; |
1606 | struct fuse_setattr_in inarg; | 1661 | struct fuse_setattr_in inarg; |
1607 | struct fuse_attr_out outarg; | 1662 | struct fuse_attr_out outarg; |
1608 | int err; | 1663 | int err; |
1609 | 1664 | ||
1610 | if (nofail) { | 1665 | req = fuse_get_req_nopages(fc); |
1611 | req = fuse_get_req_nofail_nopages(fc, file); | 1666 | if (IS_ERR(req)) |
1612 | } else { | 1667 | return PTR_ERR(req); |
1613 | req = fuse_get_req_nopages(fc); | ||
1614 | if (IS_ERR(req)) | ||
1615 | return PTR_ERR(req); | ||
1616 | } | ||
1617 | 1668 | ||
1618 | memset(&inarg, 0, sizeof(inarg)); | 1669 | memset(&inarg, 0, sizeof(inarg)); |
1619 | memset(&outarg, 0, sizeof(outarg)); | 1670 | memset(&outarg, 0, sizeof(outarg)); |
1620 | 1671 | ||
1621 | inarg.valid |= FATTR_MTIME; | 1672 | inarg.valid = FATTR_MTIME; |
1622 | inarg.mtime = inode->i_mtime.tv_sec; | 1673 | inarg.mtime = inode->i_mtime.tv_sec; |
1623 | inarg.mtimensec = inode->i_mtime.tv_nsec; | 1674 | inarg.mtimensec = inode->i_mtime.tv_nsec; |
1624 | 1675 | if (fc->minor >= 23) { | |
1676 | inarg.valid |= FATTR_CTIME; | ||
1677 | inarg.ctime = inode->i_ctime.tv_sec; | ||
1678 | inarg.ctimensec = inode->i_ctime.tv_nsec; | ||
1679 | } | ||
1680 | if (ff) { | ||
1681 | inarg.valid |= FATTR_FH; | ||
1682 | inarg.fh = ff->fh; | ||
1683 | } | ||
1625 | fuse_setattr_fill(fc, req, inode, &inarg, &outarg); | 1684 | fuse_setattr_fill(fc, req, inode, &inarg, &outarg); |
1626 | fuse_request_send(fc, req); | 1685 | fuse_request_send(fc, req); |
1627 | err = req->out.h.error; | 1686 | err = req->out.h.error; |
1628 | fuse_put_request(fc, req); | 1687 | fuse_put_request(fc, req); |
1629 | 1688 | ||
1630 | if (!err) | ||
1631 | clear_bit(FUSE_I_MTIME_DIRTY, &fi->state); | ||
1632 | |||
1633 | return err; | 1689 | return err; |
1634 | } | 1690 | } |
1635 | 1691 | ||
@@ -1653,7 +1709,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, | |||
1653 | bool is_wb = fc->writeback_cache; | 1709 | bool is_wb = fc->writeback_cache; |
1654 | loff_t oldsize; | 1710 | loff_t oldsize; |
1655 | int err; | 1711 | int err; |
1656 | bool trust_local_mtime = is_wb && S_ISREG(inode->i_mode); | 1712 | bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode); |
1657 | 1713 | ||
1658 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) | 1714 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) |
1659 | attr->ia_valid |= ATTR_FORCE; | 1715 | attr->ia_valid |= ATTR_FORCE; |
@@ -1678,11 +1734,13 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, | |||
1678 | if (is_truncate) { | 1734 | if (is_truncate) { |
1679 | fuse_set_nowrite(inode); | 1735 | fuse_set_nowrite(inode); |
1680 | set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); | 1736 | set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); |
1737 | if (trust_local_cmtime && attr->ia_size != inode->i_size) | ||
1738 | attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; | ||
1681 | } | 1739 | } |
1682 | 1740 | ||
1683 | memset(&inarg, 0, sizeof(inarg)); | 1741 | memset(&inarg, 0, sizeof(inarg)); |
1684 | memset(&outarg, 0, sizeof(outarg)); | 1742 | memset(&outarg, 0, sizeof(outarg)); |
1685 | iattr_to_fattr(attr, &inarg, trust_local_mtime); | 1743 | iattr_to_fattr(attr, &inarg, trust_local_cmtime); |
1686 | if (file) { | 1744 | if (file) { |
1687 | struct fuse_file *ff = file->private_data; | 1745 | struct fuse_file *ff = file->private_data; |
1688 | inarg.valid |= FATTR_FH; | 1746 | inarg.valid |= FATTR_FH; |
@@ -1711,9 +1769,12 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, | |||
1711 | 1769 | ||
1712 | spin_lock(&fc->lock); | 1770 | spin_lock(&fc->lock); |
1713 | /* the kernel maintains i_mtime locally */ | 1771 | /* the kernel maintains i_mtime locally */ |
1714 | if (trust_local_mtime && (attr->ia_valid & ATTR_MTIME)) { | 1772 | if (trust_local_cmtime) { |
1715 | inode->i_mtime = attr->ia_mtime; | 1773 | if (attr->ia_valid & ATTR_MTIME) |
1716 | clear_bit(FUSE_I_MTIME_DIRTY, &fi->state); | 1774 | inode->i_mtime = attr->ia_mtime; |
1775 | if (attr->ia_valid & ATTR_CTIME) | ||
1776 | inode->i_ctime = attr->ia_ctime; | ||
1777 | /* FIXME: clear I_DIRTY_SYNC? */ | ||
1717 | } | 1778 | } |
1718 | 1779 | ||
1719 | fuse_change_attributes_common(inode, &outarg.attr, | 1780 | fuse_change_attributes_common(inode, &outarg.attr, |
@@ -1810,8 +1871,10 @@ static int fuse_setxattr(struct dentry *entry, const char *name, | |||
1810 | fc->no_setxattr = 1; | 1871 | fc->no_setxattr = 1; |
1811 | err = -EOPNOTSUPP; | 1872 | err = -EOPNOTSUPP; |
1812 | } | 1873 | } |
1813 | if (!err) | 1874 | if (!err) { |
1814 | fuse_invalidate_attr(inode); | 1875 | fuse_invalidate_attr(inode); |
1876 | fuse_update_ctime(inode); | ||
1877 | } | ||
1815 | return err; | 1878 | return err; |
1816 | } | 1879 | } |
1817 | 1880 | ||
@@ -1941,20 +2004,11 @@ static int fuse_removexattr(struct dentry *entry, const char *name) | |||
1941 | fc->no_removexattr = 1; | 2004 | fc->no_removexattr = 1; |
1942 | err = -EOPNOTSUPP; | 2005 | err = -EOPNOTSUPP; |
1943 | } | 2006 | } |
1944 | if (!err) | 2007 | if (!err) { |
1945 | fuse_invalidate_attr(inode); | 2008 | fuse_invalidate_attr(inode); |
1946 | return err; | 2009 | fuse_update_ctime(inode); |
1947 | } | ||
1948 | |||
1949 | static int fuse_update_time(struct inode *inode, struct timespec *now, | ||
1950 | int flags) | ||
1951 | { | ||
1952 | if (flags & S_MTIME) { | ||
1953 | inode->i_mtime = *now; | ||
1954 | set_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state); | ||
1955 | BUG_ON(!S_ISREG(inode->i_mode)); | ||
1956 | } | 2010 | } |
1957 | return 0; | 2011 | return err; |
1958 | } | 2012 | } |
1959 | 2013 | ||
1960 | static const struct inode_operations fuse_dir_inode_operations = { | 2014 | static const struct inode_operations fuse_dir_inode_operations = { |
@@ -1964,6 +2018,7 @@ static const struct inode_operations fuse_dir_inode_operations = { | |||
1964 | .unlink = fuse_unlink, | 2018 | .unlink = fuse_unlink, |
1965 | .rmdir = fuse_rmdir, | 2019 | .rmdir = fuse_rmdir, |
1966 | .rename = fuse_rename, | 2020 | .rename = fuse_rename, |
2021 | .rename2 = fuse_rename2, | ||
1967 | .link = fuse_link, | 2022 | .link = fuse_link, |
1968 | .setattr = fuse_setattr, | 2023 | .setattr = fuse_setattr, |
1969 | .create = fuse_create, | 2024 | .create = fuse_create, |
@@ -1996,7 +2051,6 @@ static const struct inode_operations fuse_common_inode_operations = { | |||
1996 | .getxattr = fuse_getxattr, | 2051 | .getxattr = fuse_getxattr, |
1997 | .listxattr = fuse_listxattr, | 2052 | .listxattr = fuse_listxattr, |
1998 | .removexattr = fuse_removexattr, | 2053 | .removexattr = fuse_removexattr, |
1999 | .update_time = fuse_update_time, | ||
2000 | }; | 2054 | }; |
2001 | 2055 | ||
2002 | static const struct inode_operations fuse_symlink_inode_operations = { | 2056 | static const struct inode_operations fuse_symlink_inode_operations = { |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 13f8bdec5110..96d513e01a5d 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -223,6 +223,8 @@ void fuse_finish_open(struct inode *inode, struct file *file) | |||
223 | i_size_write(inode, 0); | 223 | i_size_write(inode, 0); |
224 | spin_unlock(&fc->lock); | 224 | spin_unlock(&fc->lock); |
225 | fuse_invalidate_attr(inode); | 225 | fuse_invalidate_attr(inode); |
226 | if (fc->writeback_cache) | ||
227 | file_update_time(file); | ||
226 | } | 228 | } |
227 | if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) | 229 | if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) |
228 | fuse_link_write_file(file); | 230 | fuse_link_write_file(file); |
@@ -232,18 +234,26 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) | |||
232 | { | 234 | { |
233 | struct fuse_conn *fc = get_fuse_conn(inode); | 235 | struct fuse_conn *fc = get_fuse_conn(inode); |
234 | int err; | 236 | int err; |
237 | bool lock_inode = (file->f_flags & O_TRUNC) && | ||
238 | fc->atomic_o_trunc && | ||
239 | fc->writeback_cache; | ||
235 | 240 | ||
236 | err = generic_file_open(inode, file); | 241 | err = generic_file_open(inode, file); |
237 | if (err) | 242 | if (err) |
238 | return err; | 243 | return err; |
239 | 244 | ||
245 | if (lock_inode) | ||
246 | mutex_lock(&inode->i_mutex); | ||
247 | |||
240 | err = fuse_do_open(fc, get_node_id(inode), file, isdir); | 248 | err = fuse_do_open(fc, get_node_id(inode), file, isdir); |
241 | if (err) | ||
242 | return err; | ||
243 | 249 | ||
244 | fuse_finish_open(inode, file); | 250 | if (!err) |
251 | fuse_finish_open(inode, file); | ||
245 | 252 | ||
246 | return 0; | 253 | if (lock_inode) |
254 | mutex_unlock(&inode->i_mutex); | ||
255 | |||
256 | return err; | ||
247 | } | 257 | } |
248 | 258 | ||
249 | static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode) | 259 | static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode) |
@@ -314,10 +324,7 @@ static int fuse_release(struct inode *inode, struct file *file) | |||
314 | 324 | ||
315 | /* see fuse_vma_close() for !writeback_cache case */ | 325 | /* see fuse_vma_close() for !writeback_cache case */ |
316 | if (fc->writeback_cache) | 326 | if (fc->writeback_cache) |
317 | filemap_write_and_wait(file->f_mapping); | 327 | write_inode_now(inode, 1); |
318 | |||
319 | if (test_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state)) | ||
320 | fuse_flush_mtime(file, true); | ||
321 | 328 | ||
322 | fuse_release_common(file, FUSE_RELEASE); | 329 | fuse_release_common(file, FUSE_RELEASE); |
323 | 330 | ||
@@ -439,7 +446,7 @@ static int fuse_flush(struct file *file, fl_owner_t id) | |||
439 | if (fc->no_flush) | 446 | if (fc->no_flush) |
440 | return 0; | 447 | return 0; |
441 | 448 | ||
442 | err = filemap_write_and_wait(file->f_mapping); | 449 | err = write_inode_now(inode, 1); |
443 | if (err) | 450 | if (err) |
444 | return err; | 451 | return err; |
445 | 452 | ||
@@ -480,13 +487,6 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, | |||
480 | if (is_bad_inode(inode)) | 487 | if (is_bad_inode(inode)) |
481 | return -EIO; | 488 | return -EIO; |
482 | 489 | ||
483 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
484 | if (err) | ||
485 | return err; | ||
486 | |||
487 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) | ||
488 | return 0; | ||
489 | |||
490 | mutex_lock(&inode->i_mutex); | 490 | mutex_lock(&inode->i_mutex); |
491 | 491 | ||
492 | /* | 492 | /* |
@@ -494,17 +494,17 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, | |||
494 | * wait for all outstanding writes, before sending the FSYNC | 494 | * wait for all outstanding writes, before sending the FSYNC |
495 | * request. | 495 | * request. |
496 | */ | 496 | */ |
497 | err = write_inode_now(inode, 0); | 497 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); |
498 | if (err) | 498 | if (err) |
499 | goto out; | 499 | goto out; |
500 | 500 | ||
501 | fuse_sync_writes(inode); | 501 | fuse_sync_writes(inode); |
502 | err = sync_inode_metadata(inode, 1); | ||
503 | if (err) | ||
504 | goto out; | ||
502 | 505 | ||
503 | if (test_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state)) { | 506 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) |
504 | int err = fuse_flush_mtime(file, false); | 507 | goto out; |
505 | if (err) | ||
506 | goto out; | ||
507 | } | ||
508 | 508 | ||
509 | req = fuse_get_req_nopages(fc); | 509 | req = fuse_get_req_nopages(fc); |
510 | if (IS_ERR(req)) { | 510 | if (IS_ERR(req)) { |
@@ -1659,13 +1659,13 @@ static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_req *req) | |||
1659 | fuse_writepage_free(fc, req); | 1659 | fuse_writepage_free(fc, req); |
1660 | } | 1660 | } |
1661 | 1661 | ||
1662 | static struct fuse_file *fuse_write_file_get(struct fuse_conn *fc, | 1662 | static struct fuse_file *__fuse_write_file_get(struct fuse_conn *fc, |
1663 | struct fuse_inode *fi) | 1663 | struct fuse_inode *fi) |
1664 | { | 1664 | { |
1665 | struct fuse_file *ff = NULL; | 1665 | struct fuse_file *ff = NULL; |
1666 | 1666 | ||
1667 | spin_lock(&fc->lock); | 1667 | spin_lock(&fc->lock); |
1668 | if (!WARN_ON(list_empty(&fi->write_files))) { | 1668 | if (!list_empty(&fi->write_files)) { |
1669 | ff = list_entry(fi->write_files.next, struct fuse_file, | 1669 | ff = list_entry(fi->write_files.next, struct fuse_file, |
1670 | write_entry); | 1670 | write_entry); |
1671 | fuse_file_get(ff); | 1671 | fuse_file_get(ff); |
@@ -1675,6 +1675,29 @@ static struct fuse_file *fuse_write_file_get(struct fuse_conn *fc, | |||
1675 | return ff; | 1675 | return ff; |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | static struct fuse_file *fuse_write_file_get(struct fuse_conn *fc, | ||
1679 | struct fuse_inode *fi) | ||
1680 | { | ||
1681 | struct fuse_file *ff = __fuse_write_file_get(fc, fi); | ||
1682 | WARN_ON(!ff); | ||
1683 | return ff; | ||
1684 | } | ||
1685 | |||
1686 | int fuse_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
1687 | { | ||
1688 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
1689 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
1690 | struct fuse_file *ff; | ||
1691 | int err; | ||
1692 | |||
1693 | ff = __fuse_write_file_get(fc, fi); | ||
1694 | err = fuse_flush_times(inode, ff); | ||
1695 | if (ff) | ||
1696 | fuse_file_put(ff, 0); | ||
1697 | |||
1698 | return err; | ||
1699 | } | ||
1700 | |||
1678 | static int fuse_writepage_locked(struct page *page) | 1701 | static int fuse_writepage_locked(struct page *page) |
1679 | { | 1702 | { |
1680 | struct address_space *mapping = page->mapping; | 1703 | struct address_space *mapping = page->mapping; |
@@ -2972,6 +2995,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2972 | bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || | 2995 | bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || |
2973 | (mode & FALLOC_FL_PUNCH_HOLE); | 2996 | (mode & FALLOC_FL_PUNCH_HOLE); |
2974 | 2997 | ||
2998 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) | ||
2999 | return -EOPNOTSUPP; | ||
3000 | |||
2975 | if (fc->no_fallocate) | 3001 | if (fc->no_fallocate) |
2976 | return -EOPNOTSUPP; | 3002 | return -EOPNOTSUPP; |
2977 | 3003 | ||
@@ -3017,12 +3043,8 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
3017 | if (!(mode & FALLOC_FL_KEEP_SIZE)) { | 3043 | if (!(mode & FALLOC_FL_KEEP_SIZE)) { |
3018 | bool changed = fuse_write_update_size(inode, offset + length); | 3044 | bool changed = fuse_write_update_size(inode, offset + length); |
3019 | 3045 | ||
3020 | if (changed && fc->writeback_cache) { | 3046 | if (changed && fc->writeback_cache) |
3021 | struct fuse_inode *fi = get_fuse_inode(inode); | 3047 | file_update_time(file); |
3022 | |||
3023 | inode->i_mtime = current_fs_time(inode->i_sb); | ||
3024 | set_bit(FUSE_I_MTIME_DIRTY, &fi->state); | ||
3025 | } | ||
3026 | } | 3048 | } |
3027 | 3049 | ||
3028 | if (mode & FALLOC_FL_PUNCH_HOLE) | 3050 | if (mode & FALLOC_FL_PUNCH_HOLE) |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index a257ed8ebee6..7aa5c75e0de1 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -119,8 +119,6 @@ enum { | |||
119 | FUSE_I_INIT_RDPLUS, | 119 | FUSE_I_INIT_RDPLUS, |
120 | /** An operation changing file size is in progress */ | 120 | /** An operation changing file size is in progress */ |
121 | FUSE_I_SIZE_UNSTABLE, | 121 | FUSE_I_SIZE_UNSTABLE, |
122 | /** i_mtime has been updated locally; a flush to userspace needed */ | ||
123 | FUSE_I_MTIME_DIRTY, | ||
124 | }; | 122 | }; |
125 | 123 | ||
126 | struct fuse_conn; | 124 | struct fuse_conn; |
@@ -544,6 +542,9 @@ struct fuse_conn { | |||
544 | /** Is fallocate not implemented by fs? */ | 542 | /** Is fallocate not implemented by fs? */ |
545 | unsigned no_fallocate:1; | 543 | unsigned no_fallocate:1; |
546 | 544 | ||
545 | /** Is rename with flags implemented by fs? */ | ||
546 | unsigned no_rename2:1; | ||
547 | |||
547 | /** Use enhanced/automatic page cache invalidation. */ | 548 | /** Use enhanced/automatic page cache invalidation. */ |
548 | unsigned auto_inval_data:1; | 549 | unsigned auto_inval_data:1; |
549 | 550 | ||
@@ -725,7 +726,7 @@ int fuse_dev_init(void); | |||
725 | void fuse_dev_cleanup(void); | 726 | void fuse_dev_cleanup(void); |
726 | 727 | ||
727 | int fuse_ctl_init(void); | 728 | int fuse_ctl_init(void); |
728 | void fuse_ctl_cleanup(void); | 729 | void __exit fuse_ctl_cleanup(void); |
729 | 730 | ||
730 | /** | 731 | /** |
731 | * Allocate a request | 732 | * Allocate a request |
@@ -891,7 +892,8 @@ int fuse_dev_release(struct inode *inode, struct file *file); | |||
891 | 892 | ||
892 | bool fuse_write_update_size(struct inode *inode, loff_t pos); | 893 | bool fuse_write_update_size(struct inode *inode, loff_t pos); |
893 | 894 | ||
894 | int fuse_flush_mtime(struct file *file, bool nofail); | 895 | int fuse_flush_times(struct inode *inode, struct fuse_file *ff); |
896 | int fuse_write_inode(struct inode *inode, struct writeback_control *wbc); | ||
895 | 897 | ||
896 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, | 898 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, |
897 | struct file *file); | 899 | struct file *file); |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 8d611696fcad..754dcf23de8a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -175,9 +175,9 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | |||
175 | if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) { | 175 | if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) { |
176 | inode->i_mtime.tv_sec = attr->mtime; | 176 | inode->i_mtime.tv_sec = attr->mtime; |
177 | inode->i_mtime.tv_nsec = attr->mtimensec; | 177 | inode->i_mtime.tv_nsec = attr->mtimensec; |
178 | inode->i_ctime.tv_sec = attr->ctime; | ||
179 | inode->i_ctime.tv_nsec = attr->ctimensec; | ||
178 | } | 180 | } |
179 | inode->i_ctime.tv_sec = attr->ctime; | ||
180 | inode->i_ctime.tv_nsec = attr->ctimensec; | ||
181 | 181 | ||
182 | if (attr->blksize != 0) | 182 | if (attr->blksize != 0) |
183 | inode->i_blkbits = ilog2(attr->blksize); | 183 | inode->i_blkbits = ilog2(attr->blksize); |
@@ -256,6 +256,8 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) | |||
256 | inode->i_size = attr->size; | 256 | inode->i_size = attr->size; |
257 | inode->i_mtime.tv_sec = attr->mtime; | 257 | inode->i_mtime.tv_sec = attr->mtime; |
258 | inode->i_mtime.tv_nsec = attr->mtimensec; | 258 | inode->i_mtime.tv_nsec = attr->mtimensec; |
259 | inode->i_ctime.tv_sec = attr->ctime; | ||
260 | inode->i_ctime.tv_nsec = attr->ctimensec; | ||
259 | if (S_ISREG(inode->i_mode)) { | 261 | if (S_ISREG(inode->i_mode)) { |
260 | fuse_init_common(inode); | 262 | fuse_init_common(inode); |
261 | fuse_init_file_inode(inode); | 263 | fuse_init_file_inode(inode); |
@@ -303,7 +305,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, | |||
303 | 305 | ||
304 | if ((inode->i_state & I_NEW)) { | 306 | if ((inode->i_state & I_NEW)) { |
305 | inode->i_flags |= S_NOATIME; | 307 | inode->i_flags |= S_NOATIME; |
306 | if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) | 308 | if (!fc->writeback_cache || !S_ISREG(attr->mode)) |
307 | inode->i_flags |= S_NOCMTIME; | 309 | inode->i_flags |= S_NOCMTIME; |
308 | inode->i_generation = generation; | 310 | inode->i_generation = generation; |
309 | inode->i_data.backing_dev_info = &fc->bdi; | 311 | inode->i_data.backing_dev_info = &fc->bdi; |
@@ -788,6 +790,7 @@ static const struct super_operations fuse_super_operations = { | |||
788 | .alloc_inode = fuse_alloc_inode, | 790 | .alloc_inode = fuse_alloc_inode, |
789 | .destroy_inode = fuse_destroy_inode, | 791 | .destroy_inode = fuse_destroy_inode, |
790 | .evict_inode = fuse_evict_inode, | 792 | .evict_inode = fuse_evict_inode, |
793 | .write_inode = fuse_write_inode, | ||
791 | .drop_inode = generic_delete_inode, | 794 | .drop_inode = generic_delete_inode, |
792 | .remount_fs = fuse_remount_fs, | 795 | .remount_fs = fuse_remount_fs, |
793 | .put_super = fuse_put_super, | 796 | .put_super = fuse_put_super, |
@@ -890,6 +893,11 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
890 | fc->async_dio = 1; | 893 | fc->async_dio = 1; |
891 | if (arg->flags & FUSE_WRITEBACK_CACHE) | 894 | if (arg->flags & FUSE_WRITEBACK_CACHE) |
892 | fc->writeback_cache = 1; | 895 | fc->writeback_cache = 1; |
896 | if (arg->time_gran && arg->time_gran <= 1000000000) | ||
897 | fc->sb->s_time_gran = arg->time_gran; | ||
898 | else | ||
899 | fc->sb->s_time_gran = 1000000000; | ||
900 | |||
893 | } else { | 901 | } else { |
894 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 902 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
895 | fc->no_lock = 1; | 903 | fc->no_lock = 1; |
@@ -996,7 +1004,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
996 | if (sb->s_flags & MS_MANDLOCK) | 1004 | if (sb->s_flags & MS_MANDLOCK) |
997 | goto err; | 1005 | goto err; |
998 | 1006 | ||
999 | sb->s_flags &= ~MS_NOSEC; | 1007 | sb->s_flags &= ~(MS_NOSEC | MS_I_VERSION); |
1000 | 1008 | ||
1001 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) | 1009 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
1002 | goto err; | 1010 | goto err; |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 204027520937..e19d4c0cacae 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -1030,6 +1030,11 @@ static int __init init_hugetlbfs_fs(void) | |||
1030 | int error; | 1030 | int error; |
1031 | int i; | 1031 | int i; |
1032 | 1032 | ||
1033 | if (!hugepages_supported()) { | ||
1034 | pr_info("hugetlbfs: disabling because there are no supported hugepage sizes\n"); | ||
1035 | return -ENOTSUPP; | ||
1036 | } | ||
1037 | |||
1033 | error = bdi_init(&hugetlbfs_backing_dev_info); | 1038 | error = bdi_init(&hugetlbfs_backing_dev_info); |
1034 | if (error) | 1039 | if (error) |
1035 | return error; | 1040 | return error; |
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 40251cd741a0..e3d37f607f97 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c | |||
@@ -611,6 +611,7 @@ static void kernfs_put_open_node(struct kernfs_node *kn, | |||
611 | static int kernfs_fop_open(struct inode *inode, struct file *file) | 611 | static int kernfs_fop_open(struct inode *inode, struct file *file) |
612 | { | 612 | { |
613 | struct kernfs_node *kn = file->f_path.dentry->d_fsdata; | 613 | struct kernfs_node *kn = file->f_path.dentry->d_fsdata; |
614 | struct kernfs_root *root = kernfs_root(kn); | ||
614 | const struct kernfs_ops *ops; | 615 | const struct kernfs_ops *ops; |
615 | struct kernfs_open_file *of; | 616 | struct kernfs_open_file *of; |
616 | bool has_read, has_write, has_mmap; | 617 | bool has_read, has_write, has_mmap; |
@@ -625,14 +626,16 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) | |||
625 | has_write = ops->write || ops->mmap; | 626 | has_write = ops->write || ops->mmap; |
626 | has_mmap = ops->mmap; | 627 | has_mmap = ops->mmap; |
627 | 628 | ||
628 | /* check perms and supported operations */ | 629 | /* see the flag definition for details */ |
629 | if ((file->f_mode & FMODE_WRITE) && | 630 | if (root->flags & KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK) { |
630 | (!(inode->i_mode & S_IWUGO) || !has_write)) | 631 | if ((file->f_mode & FMODE_WRITE) && |
631 | goto err_out; | 632 | (!(inode->i_mode & S_IWUGO) || !has_write)) |
633 | goto err_out; | ||
632 | 634 | ||
633 | if ((file->f_mode & FMODE_READ) && | 635 | if ((file->f_mode & FMODE_READ) && |
634 | (!(inode->i_mode & S_IRUGO) || !has_read)) | 636 | (!(inode->i_mode & S_IRUGO) || !has_read)) |
635 | goto err_out; | 637 | goto err_out; |
638 | } | ||
636 | 639 | ||
637 | /* allocate a kernfs_open_file for the file */ | 640 | /* allocate a kernfs_open_file for the file */ |
638 | error = -ENOMEM; | 641 | error = -ENOMEM; |
diff --git a/fs/locks.c b/fs/locks.c index e663aeac579e..e390bd9ae068 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -389,18 +389,6 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, | |||
389 | fl->fl_ops = NULL; | 389 | fl->fl_ops = NULL; |
390 | fl->fl_lmops = NULL; | 390 | fl->fl_lmops = NULL; |
391 | 391 | ||
392 | /* Ensure that fl->fl_filp has compatible f_mode */ | ||
393 | switch (l->l_type) { | ||
394 | case F_RDLCK: | ||
395 | if (!(filp->f_mode & FMODE_READ)) | ||
396 | return -EBADF; | ||
397 | break; | ||
398 | case F_WRLCK: | ||
399 | if (!(filp->f_mode & FMODE_WRITE)) | ||
400 | return -EBADF; | ||
401 | break; | ||
402 | } | ||
403 | |||
404 | return assign_type(fl, l->l_type); | 392 | return assign_type(fl, l->l_type); |
405 | } | 393 | } |
406 | 394 | ||
@@ -2034,6 +2022,22 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd, | |||
2034 | return error; | 2022 | return error; |
2035 | } | 2023 | } |
2036 | 2024 | ||
2025 | /* Ensure that fl->fl_filp has compatible f_mode for F_SETLK calls */ | ||
2026 | static int | ||
2027 | check_fmode_for_setlk(struct file_lock *fl) | ||
2028 | { | ||
2029 | switch (fl->fl_type) { | ||
2030 | case F_RDLCK: | ||
2031 | if (!(fl->fl_file->f_mode & FMODE_READ)) | ||
2032 | return -EBADF; | ||
2033 | break; | ||
2034 | case F_WRLCK: | ||
2035 | if (!(fl->fl_file->f_mode & FMODE_WRITE)) | ||
2036 | return -EBADF; | ||
2037 | } | ||
2038 | return 0; | ||
2039 | } | ||
2040 | |||
2037 | /* Apply the lock described by l to an open file descriptor. | 2041 | /* Apply the lock described by l to an open file descriptor. |
2038 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). | 2042 | * This implements both the F_SETLK and F_SETLKW commands of fcntl(). |
2039 | */ | 2043 | */ |
@@ -2071,6 +2075,10 @@ again: | |||
2071 | if (error) | 2075 | if (error) |
2072 | goto out; | 2076 | goto out; |
2073 | 2077 | ||
2078 | error = check_fmode_for_setlk(file_lock); | ||
2079 | if (error) | ||
2080 | goto out; | ||
2081 | |||
2074 | /* | 2082 | /* |
2075 | * If the cmd is requesting file-private locks, then set the | 2083 | * If the cmd is requesting file-private locks, then set the |
2076 | * FL_OFDLCK flag and override the owner. | 2084 | * FL_OFDLCK flag and override the owner. |
@@ -2206,6 +2214,10 @@ again: | |||
2206 | if (error) | 2214 | if (error) |
2207 | goto out; | 2215 | goto out; |
2208 | 2216 | ||
2217 | error = check_fmode_for_setlk(file_lock); | ||
2218 | if (error) | ||
2219 | goto out; | ||
2220 | |||
2209 | /* | 2221 | /* |
2210 | * If the cmd is requesting file-private locks, then set the | 2222 | * If the cmd is requesting file-private locks, then set the |
2211 | * FL_OFDLCK flag and override the owner. | 2223 | * FL_OFDLCK flag and override the owner. |
diff --git a/fs/namei.c b/fs/namei.c index c6157c894fce..80168273396b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1542,7 +1542,7 @@ static inline int walk_component(struct nameidata *nd, struct path *path, | |||
1542 | inode = path->dentry->d_inode; | 1542 | inode = path->dentry->d_inode; |
1543 | } | 1543 | } |
1544 | err = -ENOENT; | 1544 | err = -ENOENT; |
1545 | if (!inode) | 1545 | if (!inode || d_is_negative(path->dentry)) |
1546 | goto out_path_put; | 1546 | goto out_path_put; |
1547 | 1547 | ||
1548 | if (should_follow_link(path->dentry, follow)) { | 1548 | if (should_follow_link(path->dentry, follow)) { |
@@ -2249,7 +2249,7 @@ mountpoint_last(struct nameidata *nd, struct path *path) | |||
2249 | mutex_unlock(&dir->d_inode->i_mutex); | 2249 | mutex_unlock(&dir->d_inode->i_mutex); |
2250 | 2250 | ||
2251 | done: | 2251 | done: |
2252 | if (!dentry->d_inode) { | 2252 | if (!dentry->d_inode || d_is_negative(dentry)) { |
2253 | error = -ENOENT; | 2253 | error = -ENOENT; |
2254 | dput(dentry); | 2254 | dput(dentry); |
2255 | goto out; | 2255 | goto out; |
@@ -2994,7 +2994,7 @@ retry_lookup: | |||
2994 | finish_lookup: | 2994 | finish_lookup: |
2995 | /* we _can_ be in RCU mode here */ | 2995 | /* we _can_ be in RCU mode here */ |
2996 | error = -ENOENT; | 2996 | error = -ENOENT; |
2997 | if (d_is_negative(path->dentry)) { | 2997 | if (!inode || d_is_negative(path->dentry)) { |
2998 | path_to_nameidata(path, nd); | 2998 | path_to_nameidata(path, nd); |
2999 | goto out; | 2999 | goto out; |
3000 | } | 3000 | } |
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6f3f392d48af..b6f46013dddf 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -402,8 +402,10 @@ sort_pacl(struct posix_acl *pacl) | |||
402 | * by uid/gid. */ | 402 | * by uid/gid. */ |
403 | int i, j; | 403 | int i, j; |
404 | 404 | ||
405 | if (pacl->a_count <= 4) | 405 | /* no users or groups */ |
406 | return; /* no users or groups */ | 406 | if (!pacl || pacl->a_count <= 4) |
407 | return; | ||
408 | |||
407 | i = 1; | 409 | i = 1; |
408 | while (pacl->a_entries[i].e_tag == ACL_USER) | 410 | while (pacl->a_entries[i].e_tag == ACL_USER) |
409 | i++; | 411 | i++; |
@@ -530,13 +532,12 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) | |||
530 | 532 | ||
531 | /* | 533 | /* |
532 | * ACLs with no ACEs are treated differently in the inheritable | 534 | * ACLs with no ACEs are treated differently in the inheritable |
533 | * and effective cases: when there are no inheritable ACEs, we | 535 | * and effective cases: when there are no inheritable ACEs, |
534 | * set a zero-length default posix acl: | 536 | * calls ->set_acl with a NULL ACL structure. |
535 | */ | 537 | */ |
536 | if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) { | 538 | if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) |
537 | pacl = posix_acl_alloc(0, GFP_KERNEL); | 539 | return NULL; |
538 | return pacl ? pacl : ERR_PTR(-ENOMEM); | 540 | |
539 | } | ||
540 | /* | 541 | /* |
541 | * When there are no effective ACEs, the following will end | 542 | * When there are no effective ACEs, the following will end |
542 | * up setting a 3-element effective posix ACL with all | 543 | * up setting a 3-element effective posix ACL with all |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 3ba65979a3cd..32b699bebb9c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1078,6 +1078,18 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name) | |||
1078 | return NULL; | 1078 | return NULL; |
1079 | } | 1079 | } |
1080 | clp->cl_name.len = name.len; | 1080 | clp->cl_name.len = name.len; |
1081 | INIT_LIST_HEAD(&clp->cl_sessions); | ||
1082 | idr_init(&clp->cl_stateids); | ||
1083 | atomic_set(&clp->cl_refcount, 0); | ||
1084 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; | ||
1085 | INIT_LIST_HEAD(&clp->cl_idhash); | ||
1086 | INIT_LIST_HEAD(&clp->cl_openowners); | ||
1087 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
1088 | INIT_LIST_HEAD(&clp->cl_lru); | ||
1089 | INIT_LIST_HEAD(&clp->cl_callbacks); | ||
1090 | INIT_LIST_HEAD(&clp->cl_revoked); | ||
1091 | spin_lock_init(&clp->cl_lock); | ||
1092 | rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); | ||
1081 | return clp; | 1093 | return clp; |
1082 | } | 1094 | } |
1083 | 1095 | ||
@@ -1095,6 +1107,7 @@ free_client(struct nfs4_client *clp) | |||
1095 | WARN_ON_ONCE(atomic_read(&ses->se_ref)); | 1107 | WARN_ON_ONCE(atomic_read(&ses->se_ref)); |
1096 | free_session(ses); | 1108 | free_session(ses); |
1097 | } | 1109 | } |
1110 | rpc_destroy_wait_queue(&clp->cl_cb_waitq); | ||
1098 | free_svc_cred(&clp->cl_cred); | 1111 | free_svc_cred(&clp->cl_cred); |
1099 | kfree(clp->cl_name.data); | 1112 | kfree(clp->cl_name.data); |
1100 | idr_destroy(&clp->cl_stateids); | 1113 | idr_destroy(&clp->cl_stateids); |
@@ -1347,7 +1360,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, | |||
1347 | if (clp == NULL) | 1360 | if (clp == NULL) |
1348 | return NULL; | 1361 | return NULL; |
1349 | 1362 | ||
1350 | INIT_LIST_HEAD(&clp->cl_sessions); | ||
1351 | ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred); | 1363 | ret = copy_cred(&clp->cl_cred, &rqstp->rq_cred); |
1352 | if (ret) { | 1364 | if (ret) { |
1353 | spin_lock(&nn->client_lock); | 1365 | spin_lock(&nn->client_lock); |
@@ -1355,20 +1367,9 @@ static struct nfs4_client *create_client(struct xdr_netobj name, | |||
1355 | spin_unlock(&nn->client_lock); | 1367 | spin_unlock(&nn->client_lock); |
1356 | return NULL; | 1368 | return NULL; |
1357 | } | 1369 | } |
1358 | idr_init(&clp->cl_stateids); | ||
1359 | atomic_set(&clp->cl_refcount, 0); | ||
1360 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; | ||
1361 | INIT_LIST_HEAD(&clp->cl_idhash); | ||
1362 | INIT_LIST_HEAD(&clp->cl_openowners); | ||
1363 | INIT_LIST_HEAD(&clp->cl_delegations); | ||
1364 | INIT_LIST_HEAD(&clp->cl_lru); | ||
1365 | INIT_LIST_HEAD(&clp->cl_callbacks); | ||
1366 | INIT_LIST_HEAD(&clp->cl_revoked); | ||
1367 | spin_lock_init(&clp->cl_lock); | ||
1368 | nfsd4_init_callback(&clp->cl_cb_null); | 1370 | nfsd4_init_callback(&clp->cl_cb_null); |
1369 | clp->cl_time = get_seconds(); | 1371 | clp->cl_time = get_seconds(); |
1370 | clear_bit(0, &clp->cl_cb_slot_busy); | 1372 | clear_bit(0, &clp->cl_cb_slot_busy); |
1371 | rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); | ||
1372 | copy_verf(clp, verf); | 1373 | copy_verf(clp, verf); |
1373 | rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); | 1374 | rpc_copy_addr((struct sockaddr *) &clp->cl_addr, sa); |
1374 | gen_confirm(clp); | 1375 | gen_confirm(clp); |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 4e565c814309..732648b270dc 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -698,6 +698,8 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
698 | } | 698 | } |
699 | group->overflow_event = &oevent->fse; | 699 | group->overflow_event = &oevent->fse; |
700 | 700 | ||
701 | if (force_o_largefile()) | ||
702 | event_f_flags |= O_LARGEFILE; | ||
701 | group->fanotify_data.f_flags = event_f_flags; | 703 | group->fanotify_data.f_flags = event_f_flags; |
702 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 704 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
703 | spin_lock_init(&group->fanotify_data.access_lock); | 705 | spin_lock_init(&group->fanotify_data.access_lock); |
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 9e363e41dacc..0855f772cd41 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -246,6 +246,12 @@ posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p) | |||
246 | umode_t mode = 0; | 246 | umode_t mode = 0; |
247 | int not_equiv = 0; | 247 | int not_equiv = 0; |
248 | 248 | ||
249 | /* | ||
250 | * A null ACL can always be presented as mode bits. | ||
251 | */ | ||
252 | if (!acl) | ||
253 | return 0; | ||
254 | |||
249 | FOREACH_ACL_ENTRY(pa, acl, pe) { | 255 | FOREACH_ACL_ENTRY(pa, acl, pe) { |
250 | switch (pa->e_tag) { | 256 | switch (pa->e_tag) { |
251 | case ACL_USER_OBJ: | 257 | case ACL_USER_OBJ: |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 28cc1acd5439..e9ef59b3abb1 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -47,12 +47,13 @@ static int sysfs_kf_seq_show(struct seq_file *sf, void *v) | |||
47 | ssize_t count; | 47 | ssize_t count; |
48 | char *buf; | 48 | char *buf; |
49 | 49 | ||
50 | /* acquire buffer and ensure that it's >= PAGE_SIZE */ | 50 | /* acquire buffer and ensure that it's >= PAGE_SIZE and clear */ |
51 | count = seq_get_buf(sf, &buf); | 51 | count = seq_get_buf(sf, &buf); |
52 | if (count < PAGE_SIZE) { | 52 | if (count < PAGE_SIZE) { |
53 | seq_commit(sf, -1); | 53 | seq_commit(sf, -1); |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | memset(buf, 0, PAGE_SIZE); | ||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * Invoke show(). Control may reach here via seq file lseek even | 59 | * Invoke show(). Control may reach here via seq file lseek even |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index a66ad6196f59..8794423f7efb 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -63,7 +63,8 @@ int __init sysfs_init(void) | |||
63 | { | 63 | { |
64 | int err; | 64 | int err; |
65 | 65 | ||
66 | sysfs_root = kernfs_create_root(NULL, 0, NULL); | 66 | sysfs_root = kernfs_create_root(NULL, KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK, |
67 | NULL); | ||
67 | if (IS_ERR(sysfs_root)) | 68 | if (IS_ERR(sysfs_root)) |
68 | return PTR_ERR(sysfs_root); | 69 | return PTR_ERR(sysfs_root); |
69 | 70 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index a1266089eca1..a81c7b556896 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1556,7 +1556,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1556 | if (c->space_fixup) { | 1556 | if (c->space_fixup) { |
1557 | err = ubifs_fixup_free_space(c); | 1557 | err = ubifs_fixup_free_space(c); |
1558 | if (err) | 1558 | if (err) |
1559 | return err; | 1559 | goto out; |
1560 | } | 1560 | } |
1561 | 1561 | ||
1562 | err = check_free_space(c); | 1562 | err = check_free_space(c); |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 01b6a0102fbd..abda1124a70f 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -213,7 +213,7 @@ xfs_attr_calc_size( | |||
213 | * Out of line attribute, cannot double split, but | 213 | * Out of line attribute, cannot double split, but |
214 | * make room for the attribute value itself. | 214 | * make room for the attribute value itself. |
215 | */ | 215 | */ |
216 | uint dblocks = XFS_B_TO_FSB(mp, valuelen); | 216 | uint dblocks = xfs_attr3_rmt_blocks(mp, valuelen); |
217 | nblks += dblocks; | 217 | nblks += dblocks; |
218 | nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); | 218 | nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); |
219 | } | 219 | } |
@@ -698,11 +698,22 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
698 | 698 | ||
699 | trace_xfs_attr_leaf_replace(args); | 699 | trace_xfs_attr_leaf_replace(args); |
700 | 700 | ||
701 | /* save the attribute state for later removal*/ | ||
701 | args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ | 702 | args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ |
702 | args->blkno2 = args->blkno; /* set 2nd entry info*/ | 703 | args->blkno2 = args->blkno; /* set 2nd entry info*/ |
703 | args->index2 = args->index; | 704 | args->index2 = args->index; |
704 | args->rmtblkno2 = args->rmtblkno; | 705 | args->rmtblkno2 = args->rmtblkno; |
705 | args->rmtblkcnt2 = args->rmtblkcnt; | 706 | args->rmtblkcnt2 = args->rmtblkcnt; |
707 | args->rmtvaluelen2 = args->rmtvaluelen; | ||
708 | |||
709 | /* | ||
710 | * clear the remote attr state now that it is saved so that the | ||
711 | * values reflect the state of the attribute we are about to | ||
712 | * add, not the attribute we just found and will remove later. | ||
713 | */ | ||
714 | args->rmtblkno = 0; | ||
715 | args->rmtblkcnt = 0; | ||
716 | args->rmtvaluelen = 0; | ||
706 | } | 717 | } |
707 | 718 | ||
708 | /* | 719 | /* |
@@ -794,6 +805,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
794 | args->blkno = args->blkno2; | 805 | args->blkno = args->blkno2; |
795 | args->rmtblkno = args->rmtblkno2; | 806 | args->rmtblkno = args->rmtblkno2; |
796 | args->rmtblkcnt = args->rmtblkcnt2; | 807 | args->rmtblkcnt = args->rmtblkcnt2; |
808 | args->rmtvaluelen = args->rmtvaluelen2; | ||
797 | if (args->rmtblkno) { | 809 | if (args->rmtblkno) { |
798 | error = xfs_attr_rmtval_remove(args); | 810 | error = xfs_attr_rmtval_remove(args); |
799 | if (error) | 811 | if (error) |
@@ -999,13 +1011,22 @@ restart: | |||
999 | 1011 | ||
1000 | trace_xfs_attr_node_replace(args); | 1012 | trace_xfs_attr_node_replace(args); |
1001 | 1013 | ||
1014 | /* save the attribute state for later removal*/ | ||
1002 | args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ | 1015 | args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ |
1003 | args->blkno2 = args->blkno; /* set 2nd entry info*/ | 1016 | args->blkno2 = args->blkno; /* set 2nd entry info*/ |
1004 | args->index2 = args->index; | 1017 | args->index2 = args->index; |
1005 | args->rmtblkno2 = args->rmtblkno; | 1018 | args->rmtblkno2 = args->rmtblkno; |
1006 | args->rmtblkcnt2 = args->rmtblkcnt; | 1019 | args->rmtblkcnt2 = args->rmtblkcnt; |
1020 | args->rmtvaluelen2 = args->rmtvaluelen; | ||
1021 | |||
1022 | /* | ||
1023 | * clear the remote attr state now that it is saved so that the | ||
1024 | * values reflect the state of the attribute we are about to | ||
1025 | * add, not the attribute we just found and will remove later. | ||
1026 | */ | ||
1007 | args->rmtblkno = 0; | 1027 | args->rmtblkno = 0; |
1008 | args->rmtblkcnt = 0; | 1028 | args->rmtblkcnt = 0; |
1029 | args->rmtvaluelen = 0; | ||
1009 | } | 1030 | } |
1010 | 1031 | ||
1011 | retval = xfs_attr3_leaf_add(blk->bp, state->args); | 1032 | retval = xfs_attr3_leaf_add(blk->bp, state->args); |
@@ -1133,6 +1154,7 @@ restart: | |||
1133 | args->blkno = args->blkno2; | 1154 | args->blkno = args->blkno2; |
1134 | args->rmtblkno = args->rmtblkno2; | 1155 | args->rmtblkno = args->rmtblkno2; |
1135 | args->rmtblkcnt = args->rmtblkcnt2; | 1156 | args->rmtblkcnt = args->rmtblkcnt2; |
1157 | args->rmtvaluelen = args->rmtvaluelen2; | ||
1136 | if (args->rmtblkno) { | 1158 | if (args->rmtblkno) { |
1137 | error = xfs_attr_rmtval_remove(args); | 1159 | error = xfs_attr_rmtval_remove(args); |
1138 | if (error) | 1160 | if (error) |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index fe9587fab17a..511c283459b1 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -1229,6 +1229,7 @@ xfs_attr3_leaf_add_work( | |||
1229 | name_rmt->valueblk = 0; | 1229 | name_rmt->valueblk = 0; |
1230 | args->rmtblkno = 1; | 1230 | args->rmtblkno = 1; |
1231 | args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); | 1231 | args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); |
1232 | args->rmtvaluelen = args->valuelen; | ||
1232 | } | 1233 | } |
1233 | xfs_trans_log_buf(args->trans, bp, | 1234 | xfs_trans_log_buf(args->trans, bp, |
1234 | XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), | 1235 | XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), |
@@ -2167,11 +2168,11 @@ xfs_attr3_leaf_lookup_int( | |||
2167 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) | 2168 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) |
2168 | continue; | 2169 | continue; |
2169 | args->index = probe; | 2170 | args->index = probe; |
2170 | args->valuelen = be32_to_cpu(name_rmt->valuelen); | 2171 | args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen); |
2171 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); | 2172 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
2172 | args->rmtblkcnt = xfs_attr3_rmt_blocks( | 2173 | args->rmtblkcnt = xfs_attr3_rmt_blocks( |
2173 | args->dp->i_mount, | 2174 | args->dp->i_mount, |
2174 | args->valuelen); | 2175 | args->rmtvaluelen); |
2175 | return XFS_ERROR(EEXIST); | 2176 | return XFS_ERROR(EEXIST); |
2176 | } | 2177 | } |
2177 | } | 2178 | } |
@@ -2220,19 +2221,19 @@ xfs_attr3_leaf_getvalue( | |||
2220 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); | 2221 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); |
2221 | ASSERT(name_rmt->namelen == args->namelen); | 2222 | ASSERT(name_rmt->namelen == args->namelen); |
2222 | ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); | 2223 | ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); |
2223 | valuelen = be32_to_cpu(name_rmt->valuelen); | 2224 | args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen); |
2224 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); | 2225 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
2225 | args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, | 2226 | args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, |
2226 | valuelen); | 2227 | args->rmtvaluelen); |
2227 | if (args->flags & ATTR_KERNOVAL) { | 2228 | if (args->flags & ATTR_KERNOVAL) { |
2228 | args->valuelen = valuelen; | 2229 | args->valuelen = args->rmtvaluelen; |
2229 | return 0; | 2230 | return 0; |
2230 | } | 2231 | } |
2231 | if (args->valuelen < valuelen) { | 2232 | if (args->valuelen < args->rmtvaluelen) { |
2232 | args->valuelen = valuelen; | 2233 | args->valuelen = args->rmtvaluelen; |
2233 | return XFS_ERROR(ERANGE); | 2234 | return XFS_ERROR(ERANGE); |
2234 | } | 2235 | } |
2235 | args->valuelen = valuelen; | 2236 | args->valuelen = args->rmtvaluelen; |
2236 | } | 2237 | } |
2237 | return 0; | 2238 | return 0; |
2238 | } | 2239 | } |
@@ -2519,7 +2520,7 @@ xfs_attr3_leaf_clearflag( | |||
2519 | ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); | 2520 | ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); |
2520 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); | 2521 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); |
2521 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); | 2522 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); |
2522 | name_rmt->valuelen = cpu_to_be32(args->valuelen); | 2523 | name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen); |
2523 | xfs_trans_log_buf(args->trans, bp, | 2524 | xfs_trans_log_buf(args->trans, bp, |
2524 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); | 2525 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); |
2525 | } | 2526 | } |
@@ -2677,7 +2678,7 @@ xfs_attr3_leaf_flipflags( | |||
2677 | ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); | 2678 | ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); |
2678 | name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index); | 2679 | name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index); |
2679 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); | 2680 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); |
2680 | name_rmt->valuelen = cpu_to_be32(args->valuelen); | 2681 | name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen); |
2681 | xfs_trans_log_buf(args->trans, bp1, | 2682 | xfs_trans_log_buf(args->trans, bp1, |
2682 | XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); | 2683 | XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); |
2683 | } | 2684 | } |
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 01db96f60cf0..833fe5d98d80 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c | |||
@@ -447,6 +447,7 @@ xfs_attr3_leaf_list_int( | |||
447 | args.dp = context->dp; | 447 | args.dp = context->dp; |
448 | args.whichfork = XFS_ATTR_FORK; | 448 | args.whichfork = XFS_ATTR_FORK; |
449 | args.valuelen = valuelen; | 449 | args.valuelen = valuelen; |
450 | args.rmtvaluelen = valuelen; | ||
450 | args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); | 451 | args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); |
451 | args.rmtblkno = be32_to_cpu(name_rmt->valueblk); | 452 | args.rmtblkno = be32_to_cpu(name_rmt->valueblk); |
452 | args.rmtblkcnt = xfs_attr3_rmt_blocks( | 453 | args.rmtblkcnt = xfs_attr3_rmt_blocks( |
diff --git a/fs/xfs/xfs_attr_remote.c b/fs/xfs/xfs_attr_remote.c index 6e37823e2932..d2e6e948cec7 100644 --- a/fs/xfs/xfs_attr_remote.c +++ b/fs/xfs/xfs_attr_remote.c | |||
@@ -337,7 +337,7 @@ xfs_attr_rmtval_get( | |||
337 | struct xfs_buf *bp; | 337 | struct xfs_buf *bp; |
338 | xfs_dablk_t lblkno = args->rmtblkno; | 338 | xfs_dablk_t lblkno = args->rmtblkno; |
339 | __uint8_t *dst = args->value; | 339 | __uint8_t *dst = args->value; |
340 | int valuelen = args->valuelen; | 340 | int valuelen; |
341 | int nmap; | 341 | int nmap; |
342 | int error; | 342 | int error; |
343 | int blkcnt = args->rmtblkcnt; | 343 | int blkcnt = args->rmtblkcnt; |
@@ -347,7 +347,9 @@ xfs_attr_rmtval_get( | |||
347 | trace_xfs_attr_rmtval_get(args); | 347 | trace_xfs_attr_rmtval_get(args); |
348 | 348 | ||
349 | ASSERT(!(args->flags & ATTR_KERNOVAL)); | 349 | ASSERT(!(args->flags & ATTR_KERNOVAL)); |
350 | ASSERT(args->rmtvaluelen == args->valuelen); | ||
350 | 351 | ||
352 | valuelen = args->rmtvaluelen; | ||
351 | while (valuelen > 0) { | 353 | while (valuelen > 0) { |
352 | nmap = ATTR_RMTVALUE_MAPSIZE; | 354 | nmap = ATTR_RMTVALUE_MAPSIZE; |
353 | error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, | 355 | error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, |
@@ -415,7 +417,7 @@ xfs_attr_rmtval_set( | |||
415 | * attributes have headers, we can't just do a straight byte to FSB | 417 | * attributes have headers, we can't just do a straight byte to FSB |
416 | * conversion and have to take the header space into account. | 418 | * conversion and have to take the header space into account. |
417 | */ | 419 | */ |
418 | blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); | 420 | blkcnt = xfs_attr3_rmt_blocks(mp, args->rmtvaluelen); |
419 | error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, | 421 | error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, |
420 | XFS_ATTR_FORK); | 422 | XFS_ATTR_FORK); |
421 | if (error) | 423 | if (error) |
@@ -480,7 +482,7 @@ xfs_attr_rmtval_set( | |||
480 | */ | 482 | */ |
481 | lblkno = args->rmtblkno; | 483 | lblkno = args->rmtblkno; |
482 | blkcnt = args->rmtblkcnt; | 484 | blkcnt = args->rmtblkcnt; |
483 | valuelen = args->valuelen; | 485 | valuelen = args->rmtvaluelen; |
484 | while (valuelen > 0) { | 486 | while (valuelen > 0) { |
485 | struct xfs_buf *bp; | 487 | struct xfs_buf *bp; |
486 | xfs_daddr_t dblkno; | 488 | xfs_daddr_t dblkno; |
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 6e95ea79f5d7..201c6091d26a 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
@@ -60,10 +60,12 @@ typedef struct xfs_da_args { | |||
60 | int index; /* index of attr of interest in blk */ | 60 | int index; /* index of attr of interest in blk */ |
61 | xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ | 61 | xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ |
62 | int rmtblkcnt; /* remote attr value block count */ | 62 | int rmtblkcnt; /* remote attr value block count */ |
63 | int rmtvaluelen; /* remote attr value length in bytes */ | ||
63 | xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ | 64 | xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ |
64 | int index2; /* index of 2nd attr in blk */ | 65 | int index2; /* index of 2nd attr in blk */ |
65 | xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ | 66 | xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ |
66 | int rmtblkcnt2; /* remote attr value block count */ | 67 | int rmtblkcnt2; /* remote attr value block count */ |
68 | int rmtvaluelen2; /* remote attr value length in bytes */ | ||
67 | int op_flags; /* operation flags */ | 69 | int op_flags; /* operation flags */ |
68 | enum xfs_dacmp cmpresult; /* name compare result for lookups */ | 70 | enum xfs_dacmp cmpresult; /* name compare result for lookups */ |
69 | } xfs_da_args_t; | 71 | } xfs_da_args_t; |
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index 1399e187d425..753e467aa1a5 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c | |||
@@ -237,7 +237,7 @@ xfs_fs_nfs_commit_metadata( | |||
237 | 237 | ||
238 | if (!lsn) | 238 | if (!lsn) |
239 | return 0; | 239 | return 0; |
240 | return _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); | 240 | return -_xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); |
241 | } | 241 | } |
242 | 242 | ||
243 | const struct export_operations xfs_export_operations = { | 243 | const struct export_operations xfs_export_operations = { |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 951a2321ee01..830c1c937b88 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -155,7 +155,7 @@ xfs_dir_fsync( | |||
155 | 155 | ||
156 | if (!lsn) | 156 | if (!lsn) |
157 | return 0; | 157 | return 0; |
158 | return _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); | 158 | return -_xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, NULL); |
159 | } | 159 | } |
160 | 160 | ||
161 | STATIC int | 161 | STATIC int |
@@ -295,7 +295,7 @@ xfs_file_aio_read( | |||
295 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); | 295 | xfs_rw_ilock(ip, XFS_IOLOCK_EXCL); |
296 | 296 | ||
297 | if (inode->i_mapping->nrpages) { | 297 | if (inode->i_mapping->nrpages) { |
298 | ret = -filemap_write_and_wait_range( | 298 | ret = filemap_write_and_wait_range( |
299 | VFS_I(ip)->i_mapping, | 299 | VFS_I(ip)->i_mapping, |
300 | pos, -1); | 300 | pos, -1); |
301 | if (ret) { | 301 | if (ret) { |
@@ -837,7 +837,7 @@ xfs_file_fallocate( | |||
837 | unsigned blksize_mask = (1 << inode->i_blkbits) - 1; | 837 | unsigned blksize_mask = (1 << inode->i_blkbits) - 1; |
838 | 838 | ||
839 | if (offset & blksize_mask || len & blksize_mask) { | 839 | if (offset & blksize_mask || len & blksize_mask) { |
840 | error = -EINVAL; | 840 | error = EINVAL; |
841 | goto out_unlock; | 841 | goto out_unlock; |
842 | } | 842 | } |
843 | 843 | ||
@@ -846,7 +846,7 @@ xfs_file_fallocate( | |||
846 | * in which case it is effectively a truncate operation | 846 | * in which case it is effectively a truncate operation |
847 | */ | 847 | */ |
848 | if (offset + len >= i_size_read(inode)) { | 848 | if (offset + len >= i_size_read(inode)) { |
849 | error = -EINVAL; | 849 | error = EINVAL; |
850 | goto out_unlock; | 850 | goto out_unlock; |
851 | } | 851 | } |
852 | 852 | ||
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index ef1ca010f417..36d630319a27 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -72,8 +72,8 @@ xfs_initxattrs( | |||
72 | int error = 0; | 72 | int error = 0; |
73 | 73 | ||
74 | for (xattr = xattr_array; xattr->name != NULL; xattr++) { | 74 | for (xattr = xattr_array; xattr->name != NULL; xattr++) { |
75 | error = xfs_attr_set(ip, xattr->name, xattr->value, | 75 | error = -xfs_attr_set(ip, xattr->name, xattr->value, |
76 | xattr->value_len, ATTR_SECURE); | 76 | xattr->value_len, ATTR_SECURE); |
77 | if (error < 0) | 77 | if (error < 0) |
78 | break; | 78 | break; |
79 | } | 79 | } |
@@ -93,8 +93,8 @@ xfs_init_security( | |||
93 | struct inode *dir, | 93 | struct inode *dir, |
94 | const struct qstr *qstr) | 94 | const struct qstr *qstr) |
95 | { | 95 | { |
96 | return security_inode_init_security(inode, dir, qstr, | 96 | return -security_inode_init_security(inode, dir, qstr, |
97 | &xfs_initxattrs, NULL); | 97 | &xfs_initxattrs, NULL); |
98 | } | 98 | } |
99 | 99 | ||
100 | static void | 100 | static void |
@@ -124,15 +124,15 @@ xfs_cleanup_inode( | |||
124 | xfs_dentry_to_name(&teardown, dentry, 0); | 124 | xfs_dentry_to_name(&teardown, dentry, 0); |
125 | 125 | ||
126 | xfs_remove(XFS_I(dir), &teardown, XFS_I(inode)); | 126 | xfs_remove(XFS_I(dir), &teardown, XFS_I(inode)); |
127 | iput(inode); | ||
128 | } | 127 | } |
129 | 128 | ||
130 | STATIC int | 129 | STATIC int |
131 | xfs_vn_mknod( | 130 | xfs_generic_create( |
132 | struct inode *dir, | 131 | struct inode *dir, |
133 | struct dentry *dentry, | 132 | struct dentry *dentry, |
134 | umode_t mode, | 133 | umode_t mode, |
135 | dev_t rdev) | 134 | dev_t rdev, |
135 | bool tmpfile) /* unnamed file */ | ||
136 | { | 136 | { |
137 | struct inode *inode; | 137 | struct inode *inode; |
138 | struct xfs_inode *ip = NULL; | 138 | struct xfs_inode *ip = NULL; |
@@ -156,8 +156,12 @@ xfs_vn_mknod( | |||
156 | if (error) | 156 | if (error) |
157 | return error; | 157 | return error; |
158 | 158 | ||
159 | xfs_dentry_to_name(&name, dentry, mode); | 159 | if (!tmpfile) { |
160 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); | 160 | xfs_dentry_to_name(&name, dentry, mode); |
161 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); | ||
162 | } else { | ||
163 | error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); | ||
164 | } | ||
161 | if (unlikely(error)) | 165 | if (unlikely(error)) |
162 | goto out_free_acl; | 166 | goto out_free_acl; |
163 | 167 | ||
@@ -169,18 +173,22 @@ xfs_vn_mknod( | |||
169 | 173 | ||
170 | #ifdef CONFIG_XFS_POSIX_ACL | 174 | #ifdef CONFIG_XFS_POSIX_ACL |
171 | if (default_acl) { | 175 | if (default_acl) { |
172 | error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); | 176 | error = -xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); |
173 | if (error) | 177 | if (error) |
174 | goto out_cleanup_inode; | 178 | goto out_cleanup_inode; |
175 | } | 179 | } |
176 | if (acl) { | 180 | if (acl) { |
177 | error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); | 181 | error = -xfs_set_acl(inode, acl, ACL_TYPE_ACCESS); |
178 | if (error) | 182 | if (error) |
179 | goto out_cleanup_inode; | 183 | goto out_cleanup_inode; |
180 | } | 184 | } |
181 | #endif | 185 | #endif |
182 | 186 | ||
183 | d_instantiate(dentry, inode); | 187 | if (tmpfile) |
188 | d_tmpfile(dentry, inode); | ||
189 | else | ||
190 | d_instantiate(dentry, inode); | ||
191 | |||
184 | out_free_acl: | 192 | out_free_acl: |
185 | if (default_acl) | 193 | if (default_acl) |
186 | posix_acl_release(default_acl); | 194 | posix_acl_release(default_acl); |
@@ -189,11 +197,23 @@ xfs_vn_mknod( | |||
189 | return -error; | 197 | return -error; |
190 | 198 | ||
191 | out_cleanup_inode: | 199 | out_cleanup_inode: |
192 | xfs_cleanup_inode(dir, inode, dentry); | 200 | if (!tmpfile) |
201 | xfs_cleanup_inode(dir, inode, dentry); | ||
202 | iput(inode); | ||
193 | goto out_free_acl; | 203 | goto out_free_acl; |
194 | } | 204 | } |
195 | 205 | ||
196 | STATIC int | 206 | STATIC int |
207 | xfs_vn_mknod( | ||
208 | struct inode *dir, | ||
209 | struct dentry *dentry, | ||
210 | umode_t mode, | ||
211 | dev_t rdev) | ||
212 | { | ||
213 | return xfs_generic_create(dir, dentry, mode, rdev, false); | ||
214 | } | ||
215 | |||
216 | STATIC int | ||
197 | xfs_vn_create( | 217 | xfs_vn_create( |
198 | struct inode *dir, | 218 | struct inode *dir, |
199 | struct dentry *dentry, | 219 | struct dentry *dentry, |
@@ -353,6 +373,7 @@ xfs_vn_symlink( | |||
353 | 373 | ||
354 | out_cleanup_inode: | 374 | out_cleanup_inode: |
355 | xfs_cleanup_inode(dir, inode, dentry); | 375 | xfs_cleanup_inode(dir, inode, dentry); |
376 | iput(inode); | ||
356 | out: | 377 | out: |
357 | return -error; | 378 | return -error; |
358 | } | 379 | } |
@@ -1053,25 +1074,7 @@ xfs_vn_tmpfile( | |||
1053 | struct dentry *dentry, | 1074 | struct dentry *dentry, |
1054 | umode_t mode) | 1075 | umode_t mode) |
1055 | { | 1076 | { |
1056 | int error; | 1077 | return xfs_generic_create(dir, dentry, mode, 0, true); |
1057 | struct xfs_inode *ip; | ||
1058 | struct inode *inode; | ||
1059 | |||
1060 | error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); | ||
1061 | if (unlikely(error)) | ||
1062 | return -error; | ||
1063 | |||
1064 | inode = VFS_I(ip); | ||
1065 | |||
1066 | error = xfs_init_security(inode, dir, &dentry->d_name); | ||
1067 | if (unlikely(error)) { | ||
1068 | iput(inode); | ||
1069 | return -error; | ||
1070 | } | ||
1071 | |||
1072 | d_tmpfile(dentry, inode); | ||
1073 | |||
1074 | return 0; | ||
1075 | } | 1078 | } |
1076 | 1079 | ||
1077 | static const struct inode_operations xfs_inode_operations = { | 1080 | static const struct inode_operations xfs_inode_operations = { |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 08624dc67317..a5f8bd9899d3 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -616,11 +616,13 @@ xfs_log_mount( | |||
616 | int error = 0; | 616 | int error = 0; |
617 | int min_logfsbs; | 617 | int min_logfsbs; |
618 | 618 | ||
619 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) | 619 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { |
620 | xfs_notice(mp, "Mounting Filesystem"); | 620 | xfs_notice(mp, "Mounting V%d Filesystem", |
621 | else { | 621 | XFS_SB_VERSION_NUM(&mp->m_sb)); |
622 | } else { | ||
622 | xfs_notice(mp, | 623 | xfs_notice(mp, |
623 | "Mounting filesystem in no-recovery mode. Filesystem will be inconsistent."); | 624 | "Mounting V%d filesystem in no-recovery mode. Filesystem will be inconsistent.", |
625 | XFS_SB_VERSION_NUM(&mp->m_sb)); | ||
624 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); | 626 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); |
625 | } | 627 | } |
626 | 628 | ||
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 993cb19e7d39..944f3d9456a8 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -743,8 +743,6 @@ xfs_mountfs( | |||
743 | new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE; | 743 | new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE; |
744 | if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) | 744 | if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) |
745 | mp->m_inode_cluster_size = new_size; | 745 | mp->m_inode_cluster_size = new_size; |
746 | xfs_info(mp, "Using inode cluster size of %d bytes", | ||
747 | mp->m_inode_cluster_size); | ||
748 | } | 746 | } |
749 | 747 | ||
750 | /* | 748 | /* |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 348e4d2ed6e6..dc977b6e6a36 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -843,22 +843,17 @@ xfs_qm_init_quotainfo( | |||
843 | 843 | ||
844 | qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP); | 844 | qinf = mp->m_quotainfo = kmem_zalloc(sizeof(xfs_quotainfo_t), KM_SLEEP); |
845 | 845 | ||
846 | if ((error = list_lru_init(&qinf->qi_lru))) { | 846 | error = -list_lru_init(&qinf->qi_lru); |
847 | kmem_free(qinf); | 847 | if (error) |
848 | mp->m_quotainfo = NULL; | 848 | goto out_free_qinf; |
849 | return error; | ||
850 | } | ||
851 | 849 | ||
852 | /* | 850 | /* |
853 | * See if quotainodes are setup, and if not, allocate them, | 851 | * See if quotainodes are setup, and if not, allocate them, |
854 | * and change the superblock accordingly. | 852 | * and change the superblock accordingly. |
855 | */ | 853 | */ |
856 | if ((error = xfs_qm_init_quotainos(mp))) { | 854 | error = xfs_qm_init_quotainos(mp); |
857 | list_lru_destroy(&qinf->qi_lru); | 855 | if (error) |
858 | kmem_free(qinf); | 856 | goto out_free_lru; |
859 | mp->m_quotainfo = NULL; | ||
860 | return error; | ||
861 | } | ||
862 | 857 | ||
863 | INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS); | 858 | INIT_RADIX_TREE(&qinf->qi_uquota_tree, GFP_NOFS); |
864 | INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS); | 859 | INIT_RADIX_TREE(&qinf->qi_gquota_tree, GFP_NOFS); |
@@ -918,7 +913,7 @@ xfs_qm_init_quotainfo( | |||
918 | qinf->qi_isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit); | 913 | qinf->qi_isoftlimit = be64_to_cpu(ddqp->d_ino_softlimit); |
919 | qinf->qi_rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); | 914 | qinf->qi_rtbhardlimit = be64_to_cpu(ddqp->d_rtb_hardlimit); |
920 | qinf->qi_rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit); | 915 | qinf->qi_rtbsoftlimit = be64_to_cpu(ddqp->d_rtb_softlimit); |
921 | 916 | ||
922 | xfs_qm_dqdestroy(dqp); | 917 | xfs_qm_dqdestroy(dqp); |
923 | } else { | 918 | } else { |
924 | qinf->qi_btimelimit = XFS_QM_BTIMELIMIT; | 919 | qinf->qi_btimelimit = XFS_QM_BTIMELIMIT; |
@@ -935,6 +930,13 @@ xfs_qm_init_quotainfo( | |||
935 | qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; | 930 | qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; |
936 | register_shrinker(&qinf->qi_shrinker); | 931 | register_shrinker(&qinf->qi_shrinker); |
937 | return 0; | 932 | return 0; |
933 | |||
934 | out_free_lru: | ||
935 | list_lru_destroy(&qinf->qi_lru); | ||
936 | out_free_qinf: | ||
937 | kmem_free(qinf); | ||
938 | mp->m_quotainfo = NULL; | ||
939 | return error; | ||
938 | } | 940 | } |
939 | 941 | ||
940 | 942 | ||
diff --git a/fs/xfs/xfs_sb.c b/fs/xfs/xfs_sb.c index 0c0e41bbe4e3..8baf61afae1d 100644 --- a/fs/xfs/xfs_sb.c +++ b/fs/xfs/xfs_sb.c | |||
@@ -201,10 +201,6 @@ xfs_mount_validate_sb( | |||
201 | * write validation, we don't need to check feature masks. | 201 | * write validation, we don't need to check feature masks. |
202 | */ | 202 | */ |
203 | if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { | 203 | if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { |
204 | xfs_alert(mp, | ||
205 | "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" | ||
206 | "Use of these features in this kernel is at your own risk!"); | ||
207 | |||
208 | if (xfs_sb_has_compat_feature(sbp, | 204 | if (xfs_sb_has_compat_feature(sbp, |
209 | XFS_SB_FEAT_COMPAT_UNKNOWN)) { | 205 | XFS_SB_FEAT_COMPAT_UNKNOWN)) { |
210 | xfs_warn(mp, | 206 | xfs_warn(mp, |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 205376776377..3494eff8e4eb 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1433,11 +1433,11 @@ xfs_fs_fill_super( | |||
1433 | if (error) | 1433 | if (error) |
1434 | goto out_free_fsname; | 1434 | goto out_free_fsname; |
1435 | 1435 | ||
1436 | error = xfs_init_mount_workqueues(mp); | 1436 | error = -xfs_init_mount_workqueues(mp); |
1437 | if (error) | 1437 | if (error) |
1438 | goto out_close_devices; | 1438 | goto out_close_devices; |
1439 | 1439 | ||
1440 | error = xfs_icsb_init_counters(mp); | 1440 | error = -xfs_icsb_init_counters(mp); |
1441 | if (error) | 1441 | if (error) |
1442 | goto out_destroy_workqueues; | 1442 | goto out_destroy_workqueues; |
1443 | 1443 | ||