diff options
| author | Ralf Baechle <ralf@linux-mips.org> | 2014-03-31 12:17:33 -0400 |
|---|---|---|
| committer | Ralf Baechle <ralf@linux-mips.org> | 2014-03-31 12:17:33 -0400 |
| commit | ade63aada79c61bcd5f51cbd310f237399892268 (patch) | |
| tree | 4f8605528bfd9b6261679883974b9ac4870223dd /fs | |
| parent | 9a1724c7506bfa7d3d9dcab13f83e9e6446929f9 (diff) | |
| parent | c14af233fbe279d0e561ecf84f1208b1bae087ef (diff) | |
Merge branch '3.14-fixes' into mips-for-linux-next
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/bio-integrity.c | 5 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/file.c | 24 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 29 | ||||
| -rw-r--r-- | fs/file.c | 56 | ||||
| -rw-r--r-- | fs/file_table.c | 1 | ||||
| -rw-r--r-- | fs/hfsplus/catalog.c | 41 | ||||
| -rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 1 | ||||
| -rw-r--r-- | fs/hfsplus/hfsplus_raw.h | 6 | ||||
| -rw-r--r-- | fs/hfsplus/inode.c | 9 | ||||
| -rw-r--r-- | fs/hfsplus/options.c | 2 | ||||
| -rw-r--r-- | fs/namei.c | 2 | ||||
| -rw-r--r-- | fs/nfs/delegation.c | 11 | ||||
| -rw-r--r-- | fs/nfs/nfs4filelayout.c | 10 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 24 | ||||
| -rw-r--r-- | fs/nfs/nfs4state.c | 14 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 8 | ||||
| -rw-r--r-- | fs/ocfs2/quota_global.c | 27 | ||||
| -rw-r--r-- | fs/ocfs2/quota_local.c | 4 | ||||
| -rw-r--r-- | fs/open.c | 4 | ||||
| -rw-r--r-- | fs/proc/base.c | 1 | ||||
| -rw-r--r-- | fs/proc/page.c | 5 | ||||
| -rw-r--r-- | fs/read_write.c | 40 |
23 files changed, 222 insertions, 104 deletions
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 0129b78a6908..4f70f383132c 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
| @@ -458,11 +458,10 @@ static int bio_integrity_verify(struct bio *bio) | |||
| 458 | struct blk_integrity_exchg bix; | 458 | struct blk_integrity_exchg bix; |
| 459 | struct bio_vec *bv; | 459 | struct bio_vec *bv; |
| 460 | sector_t sector = bio->bi_integrity->bip_iter.bi_sector; | 460 | sector_t sector = bio->bi_integrity->bip_iter.bi_sector; |
| 461 | unsigned int sectors, total, ret; | 461 | unsigned int sectors, ret = 0; |
| 462 | void *prot_buf = bio->bi_integrity->bip_buf; | 462 | void *prot_buf = bio->bi_integrity->bip_buf; |
| 463 | int i; | 463 | int i; |
| 464 | 464 | ||
| 465 | ret = total = 0; | ||
| 466 | bix.disk_name = bio->bi_bdev->bd_disk->disk_name; | 465 | bix.disk_name = bio->bi_bdev->bd_disk->disk_name; |
| 467 | bix.sector_size = bi->sector_size; | 466 | bix.sector_size = bi->sector_size; |
| 468 | 467 | ||
| @@ -484,8 +483,6 @@ static int bio_integrity_verify(struct bio *bio) | |||
| 484 | sectors = bv->bv_len / bi->sector_size; | 483 | sectors = bv->bv_len / bi->sector_size; |
| 485 | sector += sectors; | 484 | sector += sectors; |
| 486 | prot_buf += sectors * bi->tuple_size; | 485 | prot_buf += sectors * bi->tuple_size; |
| 487 | total += sectors * bi->tuple_size; | ||
| 488 | BUG_ON(total > bio->bi_integrity->bip_iter.bi_size); | ||
| 489 | 486 | ||
| 490 | kunmap_atomic(kaddr); | 487 | kunmap_atomic(kaddr); |
| 491 | } | 488 | } |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cf32f0393369..c0f3718b77a8 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -513,7 +513,7 @@ struct cifs_mnt_data { | |||
| 513 | static inline unsigned int | 513 | static inline unsigned int |
| 514 | get_rfc1002_length(void *buf) | 514 | get_rfc1002_length(void *buf) |
| 515 | { | 515 | { |
| 516 | return be32_to_cpu(*((__be32 *)buf)); | 516 | return be32_to_cpu(*((__be32 *)buf)) & 0xffffff; |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | static inline void | 519 | static inline void |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 53c15074bb36..834fce759d80 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -2579,31 +2579,19 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov, | |||
| 2579 | struct cifsInodeInfo *cinode = CIFS_I(inode); | 2579 | struct cifsInodeInfo *cinode = CIFS_I(inode); |
| 2580 | struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; | 2580 | struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; |
| 2581 | ssize_t rc = -EACCES; | 2581 | ssize_t rc = -EACCES; |
| 2582 | loff_t lock_pos = pos; | ||
| 2582 | 2583 | ||
| 2583 | BUG_ON(iocb->ki_pos != pos); | 2584 | if (file->f_flags & O_APPEND) |
| 2584 | 2585 | lock_pos = i_size_read(inode); | |
| 2585 | /* | 2586 | /* |
| 2586 | * We need to hold the sem to be sure nobody modifies lock list | 2587 | * We need to hold the sem to be sure nobody modifies lock list |
| 2587 | * with a brlock that prevents writing. | 2588 | * with a brlock that prevents writing. |
| 2588 | */ | 2589 | */ |
| 2589 | down_read(&cinode->lock_sem); | 2590 | down_read(&cinode->lock_sem); |
| 2590 | if (!cifs_find_lock_conflict(cfile, pos, iov_length(iov, nr_segs), | 2591 | if (!cifs_find_lock_conflict(cfile, lock_pos, iov_length(iov, nr_segs), |
| 2591 | server->vals->exclusive_lock_type, NULL, | 2592 | server->vals->exclusive_lock_type, NULL, |
| 2592 | CIFS_WRITE_OP)) { | 2593 | CIFS_WRITE_OP)) |
| 2593 | mutex_lock(&inode->i_mutex); | 2594 | rc = generic_file_aio_write(iocb, iov, nr_segs, pos); |
| 2594 | rc = __generic_file_aio_write(iocb, iov, nr_segs, | ||
| 2595 | &iocb->ki_pos); | ||
| 2596 | mutex_unlock(&inode->i_mutex); | ||
| 2597 | } | ||
| 2598 | |||
| 2599 | if (rc > 0) { | ||
| 2600 | ssize_t err; | ||
| 2601 | |||
| 2602 | err = generic_write_sync(file, iocb->ki_pos - rc, rc); | ||
| 2603 | if (err < 0) | ||
| 2604 | rc = err; | ||
| 2605 | } | ||
| 2606 | |||
| 2607 | up_read(&cinode->lock_sem); | 2595 | up_read(&cinode->lock_sem); |
| 2608 | return rc; | 2596 | return rc; |
| 2609 | } | 2597 | } |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index b37570952846..18cd5650a5fc 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -270,6 +270,26 @@ cifs_rqst_page_to_kvec(struct smb_rqst *rqst, unsigned int idx, | |||
| 270 | iov->iov_len = rqst->rq_pagesz; | 270 | iov->iov_len = rqst->rq_pagesz; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | static unsigned long | ||
| 274 | rqst_len(struct smb_rqst *rqst) | ||
| 275 | { | ||
| 276 | unsigned int i; | ||
| 277 | struct kvec *iov = rqst->rq_iov; | ||
| 278 | unsigned long buflen = 0; | ||
| 279 | |||
| 280 | /* total up iov array first */ | ||
| 281 | for (i = 0; i < rqst->rq_nvec; i++) | ||
| 282 | buflen += iov[i].iov_len; | ||
| 283 | |||
| 284 | /* add in the page array if there is one */ | ||
| 285 | if (rqst->rq_npages) { | ||
| 286 | buflen += rqst->rq_pagesz * (rqst->rq_npages - 1); | ||
| 287 | buflen += rqst->rq_tailsz; | ||
| 288 | } | ||
| 289 | |||
| 290 | return buflen; | ||
| 291 | } | ||
| 292 | |||
| 273 | static int | 293 | static int |
| 274 | smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) | 294 | smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) |
| 275 | { | 295 | { |
| @@ -277,6 +297,7 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) | |||
| 277 | struct kvec *iov = rqst->rq_iov; | 297 | struct kvec *iov = rqst->rq_iov; |
| 278 | int n_vec = rqst->rq_nvec; | 298 | int n_vec = rqst->rq_nvec; |
| 279 | unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base); | 299 | unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base); |
| 300 | unsigned long send_length; | ||
| 280 | unsigned int i; | 301 | unsigned int i; |
| 281 | size_t total_len = 0, sent; | 302 | size_t total_len = 0, sent; |
| 282 | struct socket *ssocket = server->ssocket; | 303 | struct socket *ssocket = server->ssocket; |
| @@ -285,6 +306,14 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) | |||
| 285 | if (ssocket == NULL) | 306 | if (ssocket == NULL) |
| 286 | return -ENOTSOCK; | 307 | return -ENOTSOCK; |
| 287 | 308 | ||
| 309 | /* sanity check send length */ | ||
| 310 | send_length = rqst_len(rqst); | ||
| 311 | if (send_length != smb_buf_length + 4) { | ||
| 312 | WARN(1, "Send length mismatch(send_length=%lu smb_buf_length=%u)\n", | ||
| 313 | send_length, smb_buf_length); | ||
| 314 | return -EIO; | ||
| 315 | } | ||
| 316 | |||
| 288 | cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length); | 317 | cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length); |
| 289 | dump_smb(iov[0].iov_base, iov[0].iov_len); | 318 | dump_smb(iov[0].iov_base, iov[0].iov_len); |
| 290 | 319 | ||
| @@ -683,35 +683,65 @@ EXPORT_SYMBOL(fget_raw); | |||
| 683 | * The fput_needed flag returned by fget_light should be passed to the | 683 | * The fput_needed flag returned by fget_light should be passed to the |
| 684 | * corresponding fput_light. | 684 | * corresponding fput_light. |
| 685 | */ | 685 | */ |
| 686 | struct file *__fget_light(unsigned int fd, fmode_t mask, int *fput_needed) | 686 | static unsigned long __fget_light(unsigned int fd, fmode_t mask) |
| 687 | { | 687 | { |
| 688 | struct files_struct *files = current->files; | 688 | struct files_struct *files = current->files; |
| 689 | struct file *file; | 689 | struct file *file; |
| 690 | 690 | ||
| 691 | *fput_needed = 0; | ||
| 692 | if (atomic_read(&files->count) == 1) { | 691 | if (atomic_read(&files->count) == 1) { |
| 693 | file = __fcheck_files(files, fd); | 692 | file = __fcheck_files(files, fd); |
| 694 | if (file && (file->f_mode & mask)) | 693 | if (!file || unlikely(file->f_mode & mask)) |
| 695 | file = NULL; | 694 | return 0; |
| 695 | return (unsigned long)file; | ||
| 696 | } else { | 696 | } else { |
| 697 | file = __fget(fd, mask); | 697 | file = __fget(fd, mask); |
| 698 | if (file) | 698 | if (!file) |
| 699 | *fput_needed = 1; | 699 | return 0; |
| 700 | return FDPUT_FPUT | (unsigned long)file; | ||
| 700 | } | 701 | } |
| 701 | |||
| 702 | return file; | ||
| 703 | } | 702 | } |
| 704 | struct file *fget_light(unsigned int fd, int *fput_needed) | 703 | unsigned long __fdget(unsigned int fd) |
| 705 | { | 704 | { |
| 706 | return __fget_light(fd, FMODE_PATH, fput_needed); | 705 | return __fget_light(fd, FMODE_PATH); |
| 707 | } | 706 | } |
| 708 | EXPORT_SYMBOL(fget_light); | 707 | EXPORT_SYMBOL(__fdget); |
| 709 | 708 | ||
| 710 | struct file *fget_raw_light(unsigned int fd, int *fput_needed) | 709 | unsigned long __fdget_raw(unsigned int fd) |
| 711 | { | 710 | { |
| 712 | return __fget_light(fd, 0, fput_needed); | 711 | return __fget_light(fd, 0); |
| 712 | } | ||
| 713 | |||
| 714 | unsigned long __fdget_pos(unsigned int fd) | ||
| 715 | { | ||
| 716 | struct files_struct *files = current->files; | ||
| 717 | struct file *file; | ||
| 718 | unsigned long v; | ||
| 719 | |||
| 720 | if (atomic_read(&files->count) == 1) { | ||
| 721 | file = __fcheck_files(files, fd); | ||
| 722 | v = 0; | ||
| 723 | } else { | ||
| 724 | file = __fget(fd, 0); | ||
| 725 | v = FDPUT_FPUT; | ||
| 726 | } | ||
| 727 | if (!file) | ||
| 728 | return 0; | ||
| 729 | |||
| 730 | if (file->f_mode & FMODE_ATOMIC_POS) { | ||
| 731 | if (file_count(file) > 1) { | ||
| 732 | v |= FDPUT_POS_UNLOCK; | ||
| 733 | mutex_lock(&file->f_pos_lock); | ||
| 734 | } | ||
| 735 | } | ||
| 736 | return v | (unsigned long)file; | ||
| 713 | } | 737 | } |
| 714 | 738 | ||
| 739 | /* | ||
| 740 | * We only lock f_pos if we have threads or if the file might be | ||
| 741 | * shared with another process. In both cases we'll have an elevated | ||
| 742 | * file count (done either by fdget() or by fork()). | ||
| 743 | */ | ||
| 744 | |||
| 715 | void set_close_on_exec(unsigned int fd, int flag) | 745 | void set_close_on_exec(unsigned int fd, int flag) |
| 716 | { | 746 | { |
| 717 | struct files_struct *files = current->files; | 747 | struct files_struct *files = current->files; |
diff --git a/fs/file_table.c b/fs/file_table.c index 5fff9030be34..5b24008ea4f6 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
| @@ -135,6 +135,7 @@ struct file *get_empty_filp(void) | |||
| 135 | atomic_long_set(&f->f_count, 1); | 135 | atomic_long_set(&f->f_count, 1); |
| 136 | rwlock_init(&f->f_owner.lock); | 136 | rwlock_init(&f->f_owner.lock); |
| 137 | spin_lock_init(&f->f_lock); | 137 | spin_lock_init(&f->f_lock); |
| 138 | mutex_init(&f->f_pos_lock); | ||
| 138 | eventpoll_init_file(f); | 139 | eventpoll_init_file(f); |
| 139 | /* f->f_version: 0 */ | 140 | /* f->f_version: 0 */ |
| 140 | return f; | 141 | return f; |
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index 968ce411db53..32602c667b4a 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c | |||
| @@ -103,6 +103,8 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, | |||
| 103 | folder = &entry->folder; | 103 | folder = &entry->folder; |
| 104 | memset(folder, 0, sizeof(*folder)); | 104 | memset(folder, 0, sizeof(*folder)); |
| 105 | folder->type = cpu_to_be16(HFSPLUS_FOLDER); | 105 | folder->type = cpu_to_be16(HFSPLUS_FOLDER); |
| 106 | if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) | ||
| 107 | folder->flags |= cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT); | ||
| 106 | folder->id = cpu_to_be32(inode->i_ino); | 108 | folder->id = cpu_to_be32(inode->i_ino); |
| 107 | HFSPLUS_I(inode)->create_date = | 109 | HFSPLUS_I(inode)->create_date = |
| 108 | folder->create_date = | 110 | folder->create_date = |
| @@ -203,6 +205,36 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid, | |||
| 203 | return hfs_brec_find(fd, hfs_find_rec_by_key); | 205 | return hfs_brec_find(fd, hfs_find_rec_by_key); |
| 204 | } | 206 | } |
| 205 | 207 | ||
| 208 | static void hfsplus_subfolders_inc(struct inode *dir) | ||
| 209 | { | ||
| 210 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); | ||
| 211 | |||
| 212 | if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) { | ||
| 213 | /* | ||
| 214 | * Increment subfolder count. Note, the value is only meaningful | ||
| 215 | * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set. | ||
| 216 | */ | ||
| 217 | HFSPLUS_I(dir)->subfolders++; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | static void hfsplus_subfolders_dec(struct inode *dir) | ||
| 222 | { | ||
| 223 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); | ||
| 224 | |||
| 225 | if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) { | ||
| 226 | /* | ||
| 227 | * Decrement subfolder count. Note, the value is only meaningful | ||
| 228 | * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set. | ||
| 229 | * | ||
| 230 | * Check for zero. Some subfolders may have been created | ||
| 231 | * by an implementation ignorant of this counter. | ||
| 232 | */ | ||
| 233 | if (HFSPLUS_I(dir)->subfolders) | ||
| 234 | HFSPLUS_I(dir)->subfolders--; | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 206 | int hfsplus_create_cat(u32 cnid, struct inode *dir, | 238 | int hfsplus_create_cat(u32 cnid, struct inode *dir, |
| 207 | struct qstr *str, struct inode *inode) | 239 | struct qstr *str, struct inode *inode) |
| 208 | { | 240 | { |
| @@ -247,6 +279,8 @@ int hfsplus_create_cat(u32 cnid, struct inode *dir, | |||
| 247 | goto err1; | 279 | goto err1; |
| 248 | 280 | ||
| 249 | dir->i_size++; | 281 | dir->i_size++; |
| 282 | if (S_ISDIR(inode->i_mode)) | ||
| 283 | hfsplus_subfolders_inc(dir); | ||
| 250 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 284 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; |
| 251 | hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); | 285 | hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); |
| 252 | 286 | ||
| @@ -336,6 +370,8 @@ int hfsplus_delete_cat(u32 cnid, struct inode *dir, struct qstr *str) | |||
| 336 | goto out; | 370 | goto out; |
| 337 | 371 | ||
| 338 | dir->i_size--; | 372 | dir->i_size--; |
| 373 | if (type == HFSPLUS_FOLDER) | ||
| 374 | hfsplus_subfolders_dec(dir); | ||
| 339 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; | 375 | dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; |
| 340 | hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); | 376 | hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); |
| 341 | 377 | ||
| @@ -380,6 +416,7 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 380 | 416 | ||
| 381 | hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, | 417 | hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, |
| 382 | src_fd.entrylength); | 418 | src_fd.entrylength); |
| 419 | type = be16_to_cpu(entry.type); | ||
| 383 | 420 | ||
| 384 | /* create new dir entry with the data from the old entry */ | 421 | /* create new dir entry with the data from the old entry */ |
| 385 | hfsplus_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name); | 422 | hfsplus_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name); |
| @@ -394,6 +431,8 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 394 | if (err) | 431 | if (err) |
| 395 | goto out; | 432 | goto out; |
| 396 | dst_dir->i_size++; | 433 | dst_dir->i_size++; |
| 434 | if (type == HFSPLUS_FOLDER) | ||
| 435 | hfsplus_subfolders_inc(dst_dir); | ||
| 397 | dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC; | 436 | dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC; |
| 398 | 437 | ||
| 399 | /* finally remove the old entry */ | 438 | /* finally remove the old entry */ |
| @@ -405,6 +444,8 @@ int hfsplus_rename_cat(u32 cnid, | |||
| 405 | if (err) | 444 | if (err) |
| 406 | goto out; | 445 | goto out; |
| 407 | src_dir->i_size--; | 446 | src_dir->i_size--; |
| 447 | if (type == HFSPLUS_FOLDER) | ||
| 448 | hfsplus_subfolders_dec(src_dir); | ||
| 408 | src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC; | 449 | src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC; |
| 409 | 450 | ||
| 410 | /* remove old thread entry */ | 451 | /* remove old thread entry */ |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 08846425b67f..62d571eb69ba 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
| @@ -242,6 +242,7 @@ struct hfsplus_inode_info { | |||
| 242 | */ | 242 | */ |
| 243 | sector_t fs_blocks; | 243 | sector_t fs_blocks; |
| 244 | u8 userflags; /* BSD user file flags */ | 244 | u8 userflags; /* BSD user file flags */ |
| 245 | u32 subfolders; /* Subfolder count (HFSX only) */ | ||
| 245 | struct list_head open_dir_list; | 246 | struct list_head open_dir_list; |
| 246 | loff_t phys_size; | 247 | loff_t phys_size; |
| 247 | 248 | ||
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h index 8ffb3a8ffe75..5a126828d85e 100644 --- a/fs/hfsplus/hfsplus_raw.h +++ b/fs/hfsplus/hfsplus_raw.h | |||
| @@ -261,7 +261,7 @@ struct hfsplus_cat_folder { | |||
| 261 | struct DInfo user_info; | 261 | struct DInfo user_info; |
| 262 | struct DXInfo finder_info; | 262 | struct DXInfo finder_info; |
| 263 | __be32 text_encoding; | 263 | __be32 text_encoding; |
| 264 | u32 reserved; | 264 | __be32 subfolders; /* Subfolder count in HFSX. Reserved in HFS+. */ |
| 265 | } __packed; | 265 | } __packed; |
| 266 | 266 | ||
| 267 | /* HFS file info (stolen from hfs.h) */ | 267 | /* HFS file info (stolen from hfs.h) */ |
| @@ -301,11 +301,13 @@ struct hfsplus_cat_file { | |||
| 301 | struct hfsplus_fork_raw rsrc_fork; | 301 | struct hfsplus_fork_raw rsrc_fork; |
| 302 | } __packed; | 302 | } __packed; |
| 303 | 303 | ||
| 304 | /* File attribute bits */ | 304 | /* File and folder flag bits */ |
| 305 | #define HFSPLUS_FILE_LOCKED 0x0001 | 305 | #define HFSPLUS_FILE_LOCKED 0x0001 |
| 306 | #define HFSPLUS_FILE_THREAD_EXISTS 0x0002 | 306 | #define HFSPLUS_FILE_THREAD_EXISTS 0x0002 |
| 307 | #define HFSPLUS_XATTR_EXISTS 0x0004 | 307 | #define HFSPLUS_XATTR_EXISTS 0x0004 |
| 308 | #define HFSPLUS_ACL_EXISTS 0x0008 | 308 | #define HFSPLUS_ACL_EXISTS 0x0008 |
| 309 | #define HFSPLUS_HAS_FOLDER_COUNT 0x0010 /* Folder has subfolder count | ||
| 310 | * (HFSX only) */ | ||
| 309 | 311 | ||
| 310 | /* HFS+ catalog thread (part of a cat_entry) */ | 312 | /* HFS+ catalog thread (part of a cat_entry) */ |
| 311 | struct hfsplus_cat_thread { | 313 | struct hfsplus_cat_thread { |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index fa929f325f87..a4f45bd88a63 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
| @@ -375,6 +375,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode) | |||
| 375 | hip->extent_state = 0; | 375 | hip->extent_state = 0; |
| 376 | hip->flags = 0; | 376 | hip->flags = 0; |
| 377 | hip->userflags = 0; | 377 | hip->userflags = 0; |
| 378 | hip->subfolders = 0; | ||
| 378 | memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec)); | 379 | memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec)); |
| 379 | memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); | 380 | memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); |
| 380 | hip->alloc_blocks = 0; | 381 | hip->alloc_blocks = 0; |
| @@ -494,6 +495,10 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
| 494 | inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); | 495 | inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); |
| 495 | HFSPLUS_I(inode)->create_date = folder->create_date; | 496 | HFSPLUS_I(inode)->create_date = folder->create_date; |
| 496 | HFSPLUS_I(inode)->fs_blocks = 0; | 497 | HFSPLUS_I(inode)->fs_blocks = 0; |
| 498 | if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) { | ||
| 499 | HFSPLUS_I(inode)->subfolders = | ||
| 500 | be32_to_cpu(folder->subfolders); | ||
| 501 | } | ||
| 497 | inode->i_op = &hfsplus_dir_inode_operations; | 502 | inode->i_op = &hfsplus_dir_inode_operations; |
| 498 | inode->i_fop = &hfsplus_dir_operations; | 503 | inode->i_fop = &hfsplus_dir_operations; |
| 499 | } else if (type == HFSPLUS_FILE) { | 504 | } else if (type == HFSPLUS_FILE) { |
| @@ -566,6 +571,10 @@ int hfsplus_cat_write_inode(struct inode *inode) | |||
| 566 | folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); | 571 | folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); |
| 567 | folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); | 572 | folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); |
| 568 | folder->valence = cpu_to_be32(inode->i_size - 2); | 573 | folder->valence = cpu_to_be32(inode->i_size - 2); |
| 574 | if (folder->flags & cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT)) { | ||
| 575 | folder->subfolders = | ||
| 576 | cpu_to_be32(HFSPLUS_I(inode)->subfolders); | ||
| 577 | } | ||
| 569 | hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, | 578 | hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, |
| 570 | sizeof(struct hfsplus_cat_folder)); | 579 | sizeof(struct hfsplus_cat_folder)); |
| 571 | } else if (HFSPLUS_IS_RSRC(inode)) { | 580 | } else if (HFSPLUS_IS_RSRC(inode)) { |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index 968eab5bc1f5..68537e8b7a09 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
| @@ -75,7 +75,7 @@ int hfsplus_parse_options_remount(char *input, int *force) | |||
| 75 | int token; | 75 | int token; |
| 76 | 76 | ||
| 77 | if (!input) | 77 | if (!input) |
| 78 | return 0; | 78 | return 1; |
| 79 | 79 | ||
| 80 | while ((p = strsep(&input, ",")) != NULL) { | 80 | while ((p = strsep(&input, ",")) != NULL) { |
| 81 | if (!*p) | 81 | if (!*p) |
diff --git a/fs/namei.c b/fs/namei.c index 385f7817bfcc..2f730ef9b4b3 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1884,7 +1884,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, | |||
| 1884 | 1884 | ||
| 1885 | nd->path = f.file->f_path; | 1885 | nd->path = f.file->f_path; |
| 1886 | if (flags & LOOKUP_RCU) { | 1886 | if (flags & LOOKUP_RCU) { |
| 1887 | if (f.need_put) | 1887 | if (f.flags & FDPUT_FPUT) |
| 1888 | *fp = f.file; | 1888 | *fp = f.file; |
| 1889 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); | 1889 | nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq); |
| 1890 | rcu_read_lock(); | 1890 | rcu_read_lock(); |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index ef792f29f831..5d8ccecf5f5c 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
| @@ -659,16 +659,19 @@ int nfs_async_inode_return_delegation(struct inode *inode, | |||
| 659 | 659 | ||
| 660 | rcu_read_lock(); | 660 | rcu_read_lock(); |
| 661 | delegation = rcu_dereference(NFS_I(inode)->delegation); | 661 | delegation = rcu_dereference(NFS_I(inode)->delegation); |
| 662 | if (delegation == NULL) | ||
| 663 | goto out_enoent; | ||
| 662 | 664 | ||
| 663 | if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) { | 665 | if (!clp->cl_mvops->match_stateid(&delegation->stateid, stateid)) |
| 664 | rcu_read_unlock(); | 666 | goto out_enoent; |
| 665 | return -ENOENT; | ||
| 666 | } | ||
| 667 | nfs_mark_return_delegation(server, delegation); | 667 | nfs_mark_return_delegation(server, delegation); |
| 668 | rcu_read_unlock(); | 668 | rcu_read_unlock(); |
| 669 | 669 | ||
| 670 | nfs_delegation_run_state_manager(clp); | 670 | nfs_delegation_run_state_manager(clp); |
| 671 | return 0; | 671 | return 0; |
| 672 | out_enoent: | ||
| 673 | rcu_read_unlock(); | ||
| 674 | return -ENOENT; | ||
| 672 | } | 675 | } |
| 673 | 676 | ||
| 674 | static struct inode * | 677 | static struct inode * |
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 12c8132ad408..b9a35c05b60f 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
| @@ -324,8 +324,9 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data) | |||
| 324 | &rdata->res.seq_res, | 324 | &rdata->res.seq_res, |
| 325 | task)) | 325 | task)) |
| 326 | return; | 326 | return; |
| 327 | nfs4_set_rw_stateid(&rdata->args.stateid, rdata->args.context, | 327 | if (nfs4_set_rw_stateid(&rdata->args.stateid, rdata->args.context, |
| 328 | rdata->args.lock_context, FMODE_READ); | 328 | rdata->args.lock_context, FMODE_READ) == -EIO) |
| 329 | rpc_exit(task, -EIO); /* lost lock, terminate I/O */ | ||
| 329 | } | 330 | } |
| 330 | 331 | ||
| 331 | static void filelayout_read_call_done(struct rpc_task *task, void *data) | 332 | static void filelayout_read_call_done(struct rpc_task *task, void *data) |
| @@ -435,8 +436,9 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data) | |||
| 435 | &wdata->res.seq_res, | 436 | &wdata->res.seq_res, |
| 436 | task)) | 437 | task)) |
| 437 | return; | 438 | return; |
| 438 | nfs4_set_rw_stateid(&wdata->args.stateid, wdata->args.context, | 439 | if (nfs4_set_rw_stateid(&wdata->args.stateid, wdata->args.context, |
| 439 | wdata->args.lock_context, FMODE_WRITE); | 440 | wdata->args.lock_context, FMODE_WRITE) == -EIO) |
| 441 | rpc_exit(task, -EIO); /* lost lock, terminate I/O */ | ||
| 440 | } | 442 | } |
| 441 | 443 | ||
| 442 | static void filelayout_write_call_done(struct rpc_task *task, void *data) | 444 | static void filelayout_write_call_done(struct rpc_task *task, void *data) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2da6a698b8f7..450bfedbe2f4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -2398,13 +2398,16 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, | |||
| 2398 | 2398 | ||
| 2399 | if (nfs4_copy_delegation_stateid(&arg.stateid, inode, fmode)) { | 2399 | if (nfs4_copy_delegation_stateid(&arg.stateid, inode, fmode)) { |
| 2400 | /* Use that stateid */ | 2400 | /* Use that stateid */ |
| 2401 | } else if (truncate && state != NULL && nfs4_valid_open_stateid(state)) { | 2401 | } else if (truncate && state != NULL) { |
| 2402 | struct nfs_lockowner lockowner = { | 2402 | struct nfs_lockowner lockowner = { |
| 2403 | .l_owner = current->files, | 2403 | .l_owner = current->files, |
| 2404 | .l_pid = current->tgid, | 2404 | .l_pid = current->tgid, |
| 2405 | }; | 2405 | }; |
| 2406 | nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, | 2406 | if (!nfs4_valid_open_stateid(state)) |
| 2407 | &lockowner); | 2407 | return -EBADF; |
| 2408 | if (nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE, | ||
| 2409 | &lockowner) == -EIO) | ||
| 2410 | return -EBADF; | ||
| 2408 | } else | 2411 | } else |
| 2409 | nfs4_stateid_copy(&arg.stateid, &zero_stateid); | 2412 | nfs4_stateid_copy(&arg.stateid, &zero_stateid); |
| 2410 | 2413 | ||
| @@ -4011,8 +4014,9 @@ static bool nfs4_stateid_is_current(nfs4_stateid *stateid, | |||
| 4011 | { | 4014 | { |
| 4012 | nfs4_stateid current_stateid; | 4015 | nfs4_stateid current_stateid; |
| 4013 | 4016 | ||
| 4014 | if (nfs4_set_rw_stateid(¤t_stateid, ctx, l_ctx, fmode)) | 4017 | /* If the current stateid represents a lost lock, then exit */ |
| 4015 | return false; | 4018 | if (nfs4_set_rw_stateid(¤t_stateid, ctx, l_ctx, fmode) == -EIO) |
| 4019 | return true; | ||
| 4016 | return nfs4_stateid_match(stateid, ¤t_stateid); | 4020 | return nfs4_stateid_match(stateid, ¤t_stateid); |
| 4017 | } | 4021 | } |
| 4018 | 4022 | ||
| @@ -5828,8 +5832,7 @@ struct nfs_release_lockowner_data { | |||
| 5828 | struct nfs4_lock_state *lsp; | 5832 | struct nfs4_lock_state *lsp; |
| 5829 | struct nfs_server *server; | 5833 | struct nfs_server *server; |
| 5830 | struct nfs_release_lockowner_args args; | 5834 | struct nfs_release_lockowner_args args; |
| 5831 | struct nfs4_sequence_args seq_args; | 5835 | struct nfs_release_lockowner_res res; |
| 5832 | struct nfs4_sequence_res seq_res; | ||
| 5833 | unsigned long timestamp; | 5836 | unsigned long timestamp; |
| 5834 | }; | 5837 | }; |
| 5835 | 5838 | ||
| @@ -5837,7 +5840,7 @@ static void nfs4_release_lockowner_prepare(struct rpc_task *task, void *calldata | |||
| 5837 | { | 5840 | { |
| 5838 | struct nfs_release_lockowner_data *data = calldata; | 5841 | struct nfs_release_lockowner_data *data = calldata; |
| 5839 | nfs40_setup_sequence(data->server, | 5842 | nfs40_setup_sequence(data->server, |
| 5840 | &data->seq_args, &data->seq_res, task); | 5843 | &data->args.seq_args, &data->res.seq_res, task); |
| 5841 | data->timestamp = jiffies; | 5844 | data->timestamp = jiffies; |
| 5842 | } | 5845 | } |
| 5843 | 5846 | ||
| @@ -5846,7 +5849,7 @@ static void nfs4_release_lockowner_done(struct rpc_task *task, void *calldata) | |||
| 5846 | struct nfs_release_lockowner_data *data = calldata; | 5849 | struct nfs_release_lockowner_data *data = calldata; |
| 5847 | struct nfs_server *server = data->server; | 5850 | struct nfs_server *server = data->server; |
| 5848 | 5851 | ||
| 5849 | nfs40_sequence_done(task, &data->seq_res); | 5852 | nfs40_sequence_done(task, &data->res.seq_res); |
| 5850 | 5853 | ||
| 5851 | switch (task->tk_status) { | 5854 | switch (task->tk_status) { |
| 5852 | case 0: | 5855 | case 0: |
| @@ -5887,7 +5890,6 @@ static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_st | |||
| 5887 | data = kmalloc(sizeof(*data), GFP_NOFS); | 5890 | data = kmalloc(sizeof(*data), GFP_NOFS); |
| 5888 | if (!data) | 5891 | if (!data) |
| 5889 | return -ENOMEM; | 5892 | return -ENOMEM; |
| 5890 | nfs4_init_sequence(&data->seq_args, &data->seq_res, 0); | ||
| 5891 | data->lsp = lsp; | 5893 | data->lsp = lsp; |
| 5892 | data->server = server; | 5894 | data->server = server; |
| 5893 | data->args.lock_owner.clientid = server->nfs_client->cl_clientid; | 5895 | data->args.lock_owner.clientid = server->nfs_client->cl_clientid; |
| @@ -5895,6 +5897,8 @@ static int nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_st | |||
| 5895 | data->args.lock_owner.s_dev = server->s_dev; | 5897 | data->args.lock_owner.s_dev = server->s_dev; |
| 5896 | 5898 | ||
| 5897 | msg.rpc_argp = &data->args; | 5899 | msg.rpc_argp = &data->args; |
| 5900 | msg.rpc_resp = &data->res; | ||
| 5901 | nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 0); | ||
| 5898 | rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); | 5902 | rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); |
| 5899 | return 0; | 5903 | return 0; |
| 5900 | } | 5904 | } |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e1a47217c05e..0deb32105ccf 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -974,9 +974,6 @@ static int nfs4_copy_lock_stateid(nfs4_stateid *dst, | |||
| 974 | else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { | 974 | else if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) { |
| 975 | nfs4_stateid_copy(dst, &lsp->ls_stateid); | 975 | nfs4_stateid_copy(dst, &lsp->ls_stateid); |
| 976 | ret = 0; | 976 | ret = 0; |
| 977 | smp_rmb(); | ||
| 978 | if (!list_empty(&lsp->ls_seqid.list)) | ||
| 979 | ret = -EWOULDBLOCK; | ||
| 980 | } | 977 | } |
| 981 | spin_unlock(&state->state_lock); | 978 | spin_unlock(&state->state_lock); |
| 982 | nfs4_put_lock_state(lsp); | 979 | nfs4_put_lock_state(lsp); |
| @@ -984,10 +981,9 @@ out: | |||
| 984 | return ret; | 981 | return ret; |
| 985 | } | 982 | } |
| 986 | 983 | ||
| 987 | static int nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) | 984 | static void nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) |
| 988 | { | 985 | { |
| 989 | const nfs4_stateid *src; | 986 | const nfs4_stateid *src; |
| 990 | int ret; | ||
| 991 | int seq; | 987 | int seq; |
| 992 | 988 | ||
| 993 | do { | 989 | do { |
| @@ -996,12 +992,7 @@ static int nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state) | |||
| 996 | if (test_bit(NFS_OPEN_STATE, &state->flags)) | 992 | if (test_bit(NFS_OPEN_STATE, &state->flags)) |
| 997 | src = &state->open_stateid; | 993 | src = &state->open_stateid; |
| 998 | nfs4_stateid_copy(dst, src); | 994 | nfs4_stateid_copy(dst, src); |
| 999 | ret = 0; | ||
| 1000 | smp_rmb(); | ||
| 1001 | if (!list_empty(&state->owner->so_seqid.list)) | ||
| 1002 | ret = -EWOULDBLOCK; | ||
| 1003 | } while (read_seqretry(&state->seqlock, seq)); | 995 | } while (read_seqretry(&state->seqlock, seq)); |
| 1004 | return ret; | ||
| 1005 | } | 996 | } |
| 1006 | 997 | ||
| 1007 | /* | 998 | /* |
| @@ -1026,7 +1017,8 @@ int nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state, | |||
| 1026 | * choose to use. | 1017 | * choose to use. |
| 1027 | */ | 1018 | */ |
| 1028 | goto out; | 1019 | goto out; |
| 1029 | ret = nfs4_copy_open_stateid(dst, state); | 1020 | nfs4_copy_open_stateid(dst, state); |
| 1021 | ret = 0; | ||
| 1030 | out: | 1022 | out: |
| 1031 | if (nfs_server_capable(state->inode, NFS_CAP_STATEID_NFSV41)) | 1023 | if (nfs_server_capable(state->inode, NFS_CAP_STATEID_NFSV41)) |
| 1032 | dst->seqid = 0; | 1024 | dst->seqid = 0; |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8450262bcf2a..51632c40e896 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -2393,8 +2393,8 @@ out_dio: | |||
| 2393 | 2393 | ||
| 2394 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || | 2394 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || |
| 2395 | ((file->f_flags & O_DIRECT) && !direct_io)) { | 2395 | ((file->f_flags & O_DIRECT) && !direct_io)) { |
| 2396 | ret = filemap_fdatawrite_range(file->f_mapping, pos, | 2396 | ret = filemap_fdatawrite_range(file->f_mapping, *ppos, |
| 2397 | pos + count - 1); | 2397 | *ppos + count - 1); |
| 2398 | if (ret < 0) | 2398 | if (ret < 0) |
| 2399 | written = ret; | 2399 | written = ret; |
| 2400 | 2400 | ||
| @@ -2407,8 +2407,8 @@ out_dio: | |||
| 2407 | } | 2407 | } |
| 2408 | 2408 | ||
| 2409 | if (!ret) | 2409 | if (!ret) |
| 2410 | ret = filemap_fdatawait_range(file->f_mapping, pos, | 2410 | ret = filemap_fdatawait_range(file->f_mapping, *ppos, |
| 2411 | pos + count - 1); | 2411 | *ppos + count - 1); |
| 2412 | } | 2412 | } |
| 2413 | 2413 | ||
| 2414 | /* | 2414 | /* |
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index aaa50611ec66..d7b5108789e2 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
| @@ -717,6 +717,12 @@ static int ocfs2_release_dquot(struct dquot *dquot) | |||
| 717 | */ | 717 | */ |
| 718 | if (status < 0) | 718 | if (status < 0) |
| 719 | mlog_errno(status); | 719 | mlog_errno(status); |
| 720 | /* | ||
| 721 | * Clear dq_off so that we search for the structure in quota file next | ||
| 722 | * time we acquire it. The structure might be deleted and reallocated | ||
| 723 | * elsewhere by another node while our dquot structure is on freelist. | ||
| 724 | */ | ||
| 725 | dquot->dq_off = 0; | ||
| 720 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); | 726 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); |
| 721 | out_trans: | 727 | out_trans: |
| 722 | ocfs2_commit_trans(osb, handle); | 728 | ocfs2_commit_trans(osb, handle); |
| @@ -756,16 +762,17 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) | |||
| 756 | status = ocfs2_lock_global_qf(info, 1); | 762 | status = ocfs2_lock_global_qf(info, 1); |
| 757 | if (status < 0) | 763 | if (status < 0) |
| 758 | goto out; | 764 | goto out; |
| 759 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) { | 765 | status = ocfs2_qinfo_lock(info, 0); |
| 760 | status = ocfs2_qinfo_lock(info, 0); | 766 | if (status < 0) |
| 761 | if (status < 0) | 767 | goto out_dq; |
| 762 | goto out_dq; | 768 | /* |
| 763 | status = qtree_read_dquot(&info->dqi_gi, dquot); | 769 | * We always want to read dquot structure from disk because we don't |
| 764 | ocfs2_qinfo_unlock(info, 0); | 770 | * know what happened with it while it was on freelist. |
| 765 | if (status < 0) | 771 | */ |
| 766 | goto out_dq; | 772 | status = qtree_read_dquot(&info->dqi_gi, dquot); |
| 767 | } | 773 | ocfs2_qinfo_unlock(info, 0); |
| 768 | set_bit(DQ_READ_B, &dquot->dq_flags); | 774 | if (status < 0) |
| 775 | goto out_dq; | ||
| 769 | 776 | ||
| 770 | OCFS2_DQUOT(dquot)->dq_use_count++; | 777 | OCFS2_DQUOT(dquot)->dq_use_count++; |
| 771 | OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; | 778 | OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; |
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 2e4344be3b96..2001862bf2b1 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c | |||
| @@ -1303,10 +1303,6 @@ int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot) | |||
| 1303 | ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh); | 1303 | ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh); |
| 1304 | 1304 | ||
| 1305 | out: | 1305 | out: |
| 1306 | /* Clear the read bit so that next time someone uses this | ||
| 1307 | * dquot he reads fresh info from disk and allocates local | ||
| 1308 | * dquot structure */ | ||
| 1309 | clear_bit(DQ_READ_B, &dquot->dq_flags); | ||
| 1310 | return status; | 1306 | return status; |
| 1311 | } | 1307 | } |
| 1312 | 1308 | ||
| @@ -705,6 +705,10 @@ static int do_dentry_open(struct file *f, | |||
| 705 | return 0; | 705 | return 0; |
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | /* POSIX.1-2008/SUSv4 Section XSI 2.9.7 */ | ||
| 709 | if (S_ISREG(inode->i_mode)) | ||
| 710 | f->f_mode |= FMODE_ATOMIC_POS; | ||
| 711 | |||
| 708 | f->f_op = fops_get(inode->i_fop); | 712 | f->f_op = fops_get(inode->i_fop); |
| 709 | if (unlikely(WARN_ON(!f->f_op))) { | 713 | if (unlikely(WARN_ON(!f->f_op))) { |
| 710 | error = -ENODEV; | 714 | error = -ENODEV; |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 51507065263b..b9760628e1fd 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -1824,6 +1824,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) | |||
| 1824 | if (rc) | 1824 | if (rc) |
| 1825 | goto out_mmput; | 1825 | goto out_mmput; |
| 1826 | 1826 | ||
| 1827 | rc = -ENOENT; | ||
| 1827 | down_read(&mm->mmap_sem); | 1828 | down_read(&mm->mmap_sem); |
| 1828 | vma = find_exact_vma(mm, vm_start, vm_end); | 1829 | vma = find_exact_vma(mm, vm_start, vm_end); |
| 1829 | if (vma && vma->vm_file) { | 1830 | if (vma && vma->vm_file) { |
diff --git a/fs/proc/page.c b/fs/proc/page.c index 02174a610315..e647c55275d9 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
| @@ -121,9 +121,8 @@ u64 stable_page_flags(struct page *page) | |||
| 121 | * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon | 121 | * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon |
| 122 | * to make sure a given page is a thp, not a non-huge compound page. | 122 | * to make sure a given page is a thp, not a non-huge compound page. |
| 123 | */ | 123 | */ |
| 124 | else if (PageTransCompound(page) && | 124 | else if (PageTransCompound(page) && (PageLRU(compound_head(page)) || |
| 125 | (PageLRU(compound_trans_head(page)) || | 125 | PageAnon(compound_head(page)))) |
| 126 | PageAnon(compound_trans_head(page)))) | ||
| 127 | u |= 1 << KPF_THP; | 126 | u |= 1 << KPF_THP; |
| 128 | 127 | ||
| 129 | /* | 128 | /* |
diff --git a/fs/read_write.c b/fs/read_write.c index edc5746a902a..54e19b9392dc 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -264,10 +264,22 @@ loff_t vfs_llseek(struct file *file, loff_t offset, int whence) | |||
| 264 | } | 264 | } |
| 265 | EXPORT_SYMBOL(vfs_llseek); | 265 | EXPORT_SYMBOL(vfs_llseek); |
| 266 | 266 | ||
| 267 | static inline struct fd fdget_pos(int fd) | ||
| 268 | { | ||
| 269 | return __to_fd(__fdget_pos(fd)); | ||
| 270 | } | ||
| 271 | |||
| 272 | static inline void fdput_pos(struct fd f) | ||
| 273 | { | ||
| 274 | if (f.flags & FDPUT_POS_UNLOCK) | ||
| 275 | mutex_unlock(&f.file->f_pos_lock); | ||
| 276 | fdput(f); | ||
| 277 | } | ||
| 278 | |||
| 267 | SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) | 279 | SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) |
| 268 | { | 280 | { |
| 269 | off_t retval; | 281 | off_t retval; |
| 270 | struct fd f = fdget(fd); | 282 | struct fd f = fdget_pos(fd); |
| 271 | if (!f.file) | 283 | if (!f.file) |
| 272 | return -EBADF; | 284 | return -EBADF; |
| 273 | 285 | ||
| @@ -278,7 +290,7 @@ SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence) | |||
| 278 | if (res != (loff_t)retval) | 290 | if (res != (loff_t)retval) |
| 279 | retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ | 291 | retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ |
| 280 | } | 292 | } |
| 281 | fdput(f); | 293 | fdput_pos(f); |
| 282 | return retval; | 294 | return retval; |
| 283 | } | 295 | } |
| 284 | 296 | ||
| @@ -498,7 +510,7 @@ static inline void file_pos_write(struct file *file, loff_t pos) | |||
| 498 | 510 | ||
| 499 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) | 511 | SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) |
| 500 | { | 512 | { |
| 501 | struct fd f = fdget(fd); | 513 | struct fd f = fdget_pos(fd); |
| 502 | ssize_t ret = -EBADF; | 514 | ssize_t ret = -EBADF; |
| 503 | 515 | ||
| 504 | if (f.file) { | 516 | if (f.file) { |
| @@ -506,7 +518,7 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) | |||
| 506 | ret = vfs_read(f.file, buf, count, &pos); | 518 | ret = vfs_read(f.file, buf, count, &pos); |
| 507 | if (ret >= 0) | 519 | if (ret >= 0) |
| 508 | file_pos_write(f.file, pos); | 520 | file_pos_write(f.file, pos); |
| 509 | fdput(f); | 521 | fdput_pos(f); |
| 510 | } | 522 | } |
| 511 | return ret; | 523 | return ret; |
| 512 | } | 524 | } |
| @@ -514,7 +526,7 @@ SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) | |||
| 514 | SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, | 526 | SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, |
| 515 | size_t, count) | 527 | size_t, count) |
| 516 | { | 528 | { |
| 517 | struct fd f = fdget(fd); | 529 | struct fd f = fdget_pos(fd); |
| 518 | ssize_t ret = -EBADF; | 530 | ssize_t ret = -EBADF; |
| 519 | 531 | ||
| 520 | if (f.file) { | 532 | if (f.file) { |
| @@ -522,7 +534,7 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, | |||
| 522 | ret = vfs_write(f.file, buf, count, &pos); | 534 | ret = vfs_write(f.file, buf, count, &pos); |
| 523 | if (ret >= 0) | 535 | if (ret >= 0) |
| 524 | file_pos_write(f.file, pos); | 536 | file_pos_write(f.file, pos); |
| 525 | fdput(f); | 537 | fdput_pos(f); |
| 526 | } | 538 | } |
| 527 | 539 | ||
| 528 | return ret; | 540 | return ret; |
| @@ -797,7 +809,7 @@ EXPORT_SYMBOL(vfs_writev); | |||
| 797 | SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | 809 | SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, |
| 798 | unsigned long, vlen) | 810 | unsigned long, vlen) |
| 799 | { | 811 | { |
| 800 | struct fd f = fdget(fd); | 812 | struct fd f = fdget_pos(fd); |
| 801 | ssize_t ret = -EBADF; | 813 | ssize_t ret = -EBADF; |
| 802 | 814 | ||
| 803 | if (f.file) { | 815 | if (f.file) { |
| @@ -805,7 +817,7 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | |||
| 805 | ret = vfs_readv(f.file, vec, vlen, &pos); | 817 | ret = vfs_readv(f.file, vec, vlen, &pos); |
| 806 | if (ret >= 0) | 818 | if (ret >= 0) |
| 807 | file_pos_write(f.file, pos); | 819 | file_pos_write(f.file, pos); |
| 808 | fdput(f); | 820 | fdput_pos(f); |
| 809 | } | 821 | } |
| 810 | 822 | ||
| 811 | if (ret > 0) | 823 | if (ret > 0) |
| @@ -817,7 +829,7 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, | |||
| 817 | SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, | 829 | SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, |
| 818 | unsigned long, vlen) | 830 | unsigned long, vlen) |
| 819 | { | 831 | { |
| 820 | struct fd f = fdget(fd); | 832 | struct fd f = fdget_pos(fd); |
| 821 | ssize_t ret = -EBADF; | 833 | ssize_t ret = -EBADF; |
| 822 | 834 | ||
| 823 | if (f.file) { | 835 | if (f.file) { |
| @@ -825,7 +837,7 @@ SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, | |||
| 825 | ret = vfs_writev(f.file, vec, vlen, &pos); | 837 | ret = vfs_writev(f.file, vec, vlen, &pos); |
| 826 | if (ret >= 0) | 838 | if (ret >= 0) |
| 827 | file_pos_write(f.file, pos); | 839 | file_pos_write(f.file, pos); |
| 828 | fdput(f); | 840 | fdput_pos(f); |
| 829 | } | 841 | } |
| 830 | 842 | ||
| 831 | if (ret > 0) | 843 | if (ret > 0) |
| @@ -968,7 +980,7 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, | |||
| 968 | const struct compat_iovec __user *,vec, | 980 | const struct compat_iovec __user *,vec, |
| 969 | compat_ulong_t, vlen) | 981 | compat_ulong_t, vlen) |
| 970 | { | 982 | { |
| 971 | struct fd f = fdget(fd); | 983 | struct fd f = fdget_pos(fd); |
| 972 | ssize_t ret; | 984 | ssize_t ret; |
| 973 | loff_t pos; | 985 | loff_t pos; |
| 974 | 986 | ||
| @@ -978,7 +990,7 @@ COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd, | |||
| 978 | ret = compat_readv(f.file, vec, vlen, &pos); | 990 | ret = compat_readv(f.file, vec, vlen, &pos); |
| 979 | if (ret >= 0) | 991 | if (ret >= 0) |
| 980 | f.file->f_pos = pos; | 992 | f.file->f_pos = pos; |
| 981 | fdput(f); | 993 | fdput_pos(f); |
| 982 | return ret; | 994 | return ret; |
| 983 | } | 995 | } |
| 984 | 996 | ||
| @@ -1035,7 +1047,7 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, | |||
| 1035 | const struct compat_iovec __user *, vec, | 1047 | const struct compat_iovec __user *, vec, |
| 1036 | compat_ulong_t, vlen) | 1048 | compat_ulong_t, vlen) |
| 1037 | { | 1049 | { |
| 1038 | struct fd f = fdget(fd); | 1050 | struct fd f = fdget_pos(fd); |
| 1039 | ssize_t ret; | 1051 | ssize_t ret; |
| 1040 | loff_t pos; | 1052 | loff_t pos; |
| 1041 | 1053 | ||
| @@ -1045,7 +1057,7 @@ COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd, | |||
| 1045 | ret = compat_writev(f.file, vec, vlen, &pos); | 1057 | ret = compat_writev(f.file, vec, vlen, &pos); |
| 1046 | if (ret >= 0) | 1058 | if (ret >= 0) |
| 1047 | f.file->f_pos = pos; | 1059 | f.file->f_pos = pos; |
| 1048 | fdput(f); | 1060 | fdput_pos(f); |
| 1049 | return ret; | 1061 | return ret; |
| 1050 | } | 1062 | } |
| 1051 | 1063 | ||
