diff options
author | Mark Brown <broonie@linaro.org> | 2014-04-29 13:01:28 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-04-29 13:01:28 -0400 |
commit | 3e93457b45a1a8c69227ce596ee2005fa06f20dd (patch) | |
tree | 248c27e432533b1af80a9b2240eaa8e48e3b87cc /fs | |
parent | 290414499cf94284a97cc3c33214d13ccfcd896a (diff) | |
parent | c42ba72ec3a7a1b6aa30122931f1f4b91b601c31 (diff) |
Merge tag 'ib-mfd-regulator-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into regulator-tps65090
Immutable branch between MFD and Regulator due for v3.16 merge-window.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifsfs.c | 14 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 8 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 3 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 3 | ||||
-rw-r--r-- | fs/cifs/file.c | 35 | ||||
-rw-r--r-- | fs/cifs/misc.c | 74 | ||||
-rw-r--r-- | fs/cifs/smb1ops.c | 11 | ||||
-rw-r--r-- | fs/cifs/smb2misc.c | 18 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 14 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 2 | ||||
-rw-r--r-- | fs/coredump.c | 7 | ||||
-rw-r--r-- | fs/kernfs/inode.c | 14 | ||||
-rw-r--r-- | fs/super.c | 5 | ||||
-rw-r--r-- | fs/sysfs/file.c | 92 | ||||
-rw-r--r-- | fs/xfs/xfs_aops.c | 51 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 17 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 13 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.c | 16 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 20 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 53 | ||||
-rw-r--r-- | fs/xfs/xfs_trace.h | 1 |
24 files changed, 336 insertions, 144 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index df9c9141c099..5be1f997ecde 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -253,6 +253,11 @@ cifs_alloc_inode(struct super_block *sb) | |||
253 | cifs_set_oplock_level(cifs_inode, 0); | 253 | cifs_set_oplock_level(cifs_inode, 0); |
254 | cifs_inode->delete_pending = false; | 254 | cifs_inode->delete_pending = false; |
255 | cifs_inode->invalid_mapping = false; | 255 | cifs_inode->invalid_mapping = false; |
256 | clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cifs_inode->flags); | ||
257 | clear_bit(CIFS_INODE_PENDING_WRITERS, &cifs_inode->flags); | ||
258 | clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cifs_inode->flags); | ||
259 | spin_lock_init(&cifs_inode->writers_lock); | ||
260 | cifs_inode->writers = 0; | ||
256 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ | 261 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ |
257 | cifs_inode->server_eof = 0; | 262 | cifs_inode->server_eof = 0; |
258 | cifs_inode->uniqueid = 0; | 263 | cifs_inode->uniqueid = 0; |
@@ -732,19 +737,26 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
732 | unsigned long nr_segs, loff_t pos) | 737 | unsigned long nr_segs, loff_t pos) |
733 | { | 738 | { |
734 | struct inode *inode = file_inode(iocb->ki_filp); | 739 | struct inode *inode = file_inode(iocb->ki_filp); |
740 | struct cifsInodeInfo *cinode = CIFS_I(inode); | ||
735 | ssize_t written; | 741 | ssize_t written; |
736 | int rc; | 742 | int rc; |
737 | 743 | ||
744 | written = cifs_get_writer(cinode); | ||
745 | if (written) | ||
746 | return written; | ||
747 | |||
738 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); | 748 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); |
739 | 749 | ||
740 | if (CIFS_CACHE_WRITE(CIFS_I(inode))) | 750 | if (CIFS_CACHE_WRITE(CIFS_I(inode))) |
741 | return written; | 751 | goto out; |
742 | 752 | ||
743 | rc = filemap_fdatawrite(inode->i_mapping); | 753 | rc = filemap_fdatawrite(inode->i_mapping); |
744 | if (rc) | 754 | if (rc) |
745 | cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n", | 755 | cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n", |
746 | rc, inode); | 756 | rc, inode); |
747 | 757 | ||
758 | out: | ||
759 | cifs_put_writer(cinode); | ||
748 | return written; | 760 | return written; |
749 | } | 761 | } |
750 | 762 | ||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index c0f3718b77a8..30f6e9251a4a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -228,6 +228,8 @@ struct smb_version_operations { | |||
228 | /* verify the message */ | 228 | /* verify the message */ |
229 | int (*check_message)(char *, unsigned int); | 229 | int (*check_message)(char *, unsigned int); |
230 | bool (*is_oplock_break)(char *, struct TCP_Server_Info *); | 230 | bool (*is_oplock_break)(char *, struct TCP_Server_Info *); |
231 | void (*downgrade_oplock)(struct TCP_Server_Info *, | ||
232 | struct cifsInodeInfo *, bool); | ||
231 | /* process transaction2 response */ | 233 | /* process transaction2 response */ |
232 | bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, | 234 | bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, |
233 | char *, int); | 235 | char *, int); |
@@ -1113,6 +1115,12 @@ struct cifsInodeInfo { | |||
1113 | unsigned int epoch; /* used to track lease state changes */ | 1115 | unsigned int epoch; /* used to track lease state changes */ |
1114 | bool delete_pending; /* DELETE_ON_CLOSE is set */ | 1116 | bool delete_pending; /* DELETE_ON_CLOSE is set */ |
1115 | bool invalid_mapping; /* pagecache is invalid */ | 1117 | bool invalid_mapping; /* pagecache is invalid */ |
1118 | unsigned long flags; | ||
1119 | #define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */ | ||
1120 | #define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */ | ||
1121 | #define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2) /* Downgrade oplock to L2 */ | ||
1122 | spinlock_t writers_lock; | ||
1123 | unsigned int writers; /* Number of writers on this inode */ | ||
1116 | unsigned long time; /* jiffies of last update of inode */ | 1124 | unsigned long time; /* jiffies of last update of inode */ |
1117 | u64 server_eof; /* current file size on server -- protected by i_lock */ | 1125 | u64 server_eof; /* current file size on server -- protected by i_lock */ |
1118 | u64 uniqueid; /* server inode number */ | 1126 | u64 uniqueid; /* server inode number */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index acc4ee8ed075..ca7980a1e303 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -127,6 +127,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec); | |||
127 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, | 127 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, |
128 | int offset); | 128 | int offset); |
129 | extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); | 129 | extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); |
130 | extern int cifs_get_writer(struct cifsInodeInfo *cinode); | ||
131 | extern void cifs_put_writer(struct cifsInodeInfo *cinode); | ||
132 | extern void cifs_done_oplock_break(struct cifsInodeInfo *cinode); | ||
130 | extern int cifs_unlock_range(struct cifsFileInfo *cfile, | 133 | extern int cifs_unlock_range(struct cifsFileInfo *cfile, |
131 | struct file_lock *flock, const unsigned int xid); | 134 | struct file_lock *flock, const unsigned int xid); |
132 | extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile); | 135 | extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f3264bd7a83d..6ce4e0954b98 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -6197,6 +6197,9 @@ QAllEAsRetry: | |||
6197 | cifs_dbg(FYI, "ea length %d\n", list_len); | 6197 | cifs_dbg(FYI, "ea length %d\n", list_len); |
6198 | if (list_len <= 8) { | 6198 | if (list_len <= 8) { |
6199 | cifs_dbg(FYI, "empty EA list returned from server\n"); | 6199 | cifs_dbg(FYI, "empty EA list returned from server\n"); |
6200 | /* didn't find the named attribute */ | ||
6201 | if (ea_name) | ||
6202 | rc = -ENODATA; | ||
6200 | goto QAllEAsOut; | 6203 | goto QAllEAsOut; |
6201 | } | 6204 | } |
6202 | 6205 | ||
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8add25538a3b..5ed03e0b8b40 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2599,7 +2599,7 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2599 | ssize_t err; | 2599 | ssize_t err; |
2600 | 2600 | ||
2601 | err = generic_write_sync(file, iocb->ki_pos - rc, rc); | 2601 | err = generic_write_sync(file, iocb->ki_pos - rc, rc); |
2602 | if (rc < 0) | 2602 | if (err < 0) |
2603 | rc = err; | 2603 | rc = err; |
2604 | } | 2604 | } |
2605 | } else { | 2605 | } else { |
@@ -2621,12 +2621,20 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2621 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 2621 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
2622 | ssize_t written; | 2622 | ssize_t written; |
2623 | 2623 | ||
2624 | written = cifs_get_writer(cinode); | ||
2625 | if (written) | ||
2626 | return written; | ||
2627 | |||
2624 | if (CIFS_CACHE_WRITE(cinode)) { | 2628 | if (CIFS_CACHE_WRITE(cinode)) { |
2625 | if (cap_unix(tcon->ses) && | 2629 | if (cap_unix(tcon->ses) && |
2626 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) | 2630 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) |
2627 | && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | 2631 | && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { |
2628 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | 2632 | written = generic_file_aio_write( |
2629 | return cifs_writev(iocb, iov, nr_segs, pos); | 2633 | iocb, iov, nr_segs, pos); |
2634 | goto out; | ||
2635 | } | ||
2636 | written = cifs_writev(iocb, iov, nr_segs, pos); | ||
2637 | goto out; | ||
2630 | } | 2638 | } |
2631 | /* | 2639 | /* |
2632 | * For non-oplocked files in strict cache mode we need to write the data | 2640 | * For non-oplocked files in strict cache mode we need to write the data |
@@ -2646,6 +2654,8 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | |||
2646 | inode); | 2654 | inode); |
2647 | cinode->oplock = 0; | 2655 | cinode->oplock = 0; |
2648 | } | 2656 | } |
2657 | out: | ||
2658 | cifs_put_writer(cinode); | ||
2649 | return written; | 2659 | return written; |
2650 | } | 2660 | } |
2651 | 2661 | ||
@@ -2872,7 +2882,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov, | |||
2872 | cifs_uncached_readv_complete); | 2882 | cifs_uncached_readv_complete); |
2873 | if (!rdata) { | 2883 | if (!rdata) { |
2874 | rc = -ENOMEM; | 2884 | rc = -ENOMEM; |
2875 | goto error; | 2885 | break; |
2876 | } | 2886 | } |
2877 | 2887 | ||
2878 | rc = cifs_read_allocate_pages(rdata, npages); | 2888 | rc = cifs_read_allocate_pages(rdata, npages); |
@@ -3621,6 +3631,13 @@ static int cifs_launder_page(struct page *page) | |||
3621 | return rc; | 3631 | return rc; |
3622 | } | 3632 | } |
3623 | 3633 | ||
3634 | static int | ||
3635 | cifs_pending_writers_wait(void *unused) | ||
3636 | { | ||
3637 | schedule(); | ||
3638 | return 0; | ||
3639 | } | ||
3640 | |||
3624 | void cifs_oplock_break(struct work_struct *work) | 3641 | void cifs_oplock_break(struct work_struct *work) |
3625 | { | 3642 | { |
3626 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | 3643 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, |
@@ -3628,8 +3645,15 @@ void cifs_oplock_break(struct work_struct *work) | |||
3628 | struct inode *inode = cfile->dentry->d_inode; | 3645 | struct inode *inode = cfile->dentry->d_inode; |
3629 | struct cifsInodeInfo *cinode = CIFS_I(inode); | 3646 | struct cifsInodeInfo *cinode = CIFS_I(inode); |
3630 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 3647 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
3648 | struct TCP_Server_Info *server = tcon->ses->server; | ||
3631 | int rc = 0; | 3649 | int rc = 0; |
3632 | 3650 | ||
3651 | wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, | ||
3652 | cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE); | ||
3653 | |||
3654 | server->ops->downgrade_oplock(server, cinode, | ||
3655 | test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags)); | ||
3656 | |||
3633 | if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && | 3657 | if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && |
3634 | cifs_has_mand_locks(cinode)) { | 3658 | cifs_has_mand_locks(cinode)) { |
3635 | cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", | 3659 | cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", |
@@ -3666,6 +3690,7 @@ void cifs_oplock_break(struct work_struct *work) | |||
3666 | cinode); | 3690 | cinode); |
3667 | cifs_dbg(FYI, "Oplock release rc = %d\n", rc); | 3691 | cifs_dbg(FYI, "Oplock release rc = %d\n", rc); |
3668 | } | 3692 | } |
3693 | cifs_done_oplock_break(cinode); | ||
3669 | } | 3694 | } |
3670 | 3695 | ||
3671 | /* | 3696 | /* |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 2f9f3790679d..3b0c62e622da 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -466,8 +466,22 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) | |||
466 | cifs_dbg(FYI, "file id match, oplock break\n"); | 466 | cifs_dbg(FYI, "file id match, oplock break\n"); |
467 | pCifsInode = CIFS_I(netfile->dentry->d_inode); | 467 | pCifsInode = CIFS_I(netfile->dentry->d_inode); |
468 | 468 | ||
469 | cifs_set_oplock_level(pCifsInode, | 469 | set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, |
470 | pSMB->OplockLevel ? OPLOCK_READ : 0); | 470 | &pCifsInode->flags); |
471 | |||
472 | /* | ||
473 | * Set flag if the server downgrades the oplock | ||
474 | * to L2 else clear. | ||
475 | */ | ||
476 | if (pSMB->OplockLevel) | ||
477 | set_bit( | ||
478 | CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, | ||
479 | &pCifsInode->flags); | ||
480 | else | ||
481 | clear_bit( | ||
482 | CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, | ||
483 | &pCifsInode->flags); | ||
484 | |||
471 | queue_work(cifsiod_wq, | 485 | queue_work(cifsiod_wq, |
472 | &netfile->oplock_break); | 486 | &netfile->oplock_break); |
473 | netfile->oplock_break_cancelled = false; | 487 | netfile->oplock_break_cancelled = false; |
@@ -551,6 +565,62 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) | |||
551 | cinode->oplock = 0; | 565 | cinode->oplock = 0; |
552 | } | 566 | } |
553 | 567 | ||
568 | static int | ||
569 | cifs_oplock_break_wait(void *unused) | ||
570 | { | ||
571 | schedule(); | ||
572 | return signal_pending(current) ? -ERESTARTSYS : 0; | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * We wait for oplock breaks to be processed before we attempt to perform | ||
577 | * writes. | ||
578 | */ | ||
579 | int cifs_get_writer(struct cifsInodeInfo *cinode) | ||
580 | { | ||
581 | int rc; | ||
582 | |||
583 | start: | ||
584 | rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK, | ||
585 | cifs_oplock_break_wait, TASK_KILLABLE); | ||
586 | if (rc) | ||
587 | return rc; | ||
588 | |||
589 | spin_lock(&cinode->writers_lock); | ||
590 | if (!cinode->writers) | ||
591 | set_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); | ||
592 | cinode->writers++; | ||
593 | /* Check to see if we have started servicing an oplock break */ | ||
594 | if (test_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags)) { | ||
595 | cinode->writers--; | ||
596 | if (cinode->writers == 0) { | ||
597 | clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); | ||
598 | wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); | ||
599 | } | ||
600 | spin_unlock(&cinode->writers_lock); | ||
601 | goto start; | ||
602 | } | ||
603 | spin_unlock(&cinode->writers_lock); | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | void cifs_put_writer(struct cifsInodeInfo *cinode) | ||
608 | { | ||
609 | spin_lock(&cinode->writers_lock); | ||
610 | cinode->writers--; | ||
611 | if (cinode->writers == 0) { | ||
612 | clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); | ||
613 | wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); | ||
614 | } | ||
615 | spin_unlock(&cinode->writers_lock); | ||
616 | } | ||
617 | |||
618 | void cifs_done_oplock_break(struct cifsInodeInfo *cinode) | ||
619 | { | ||
620 | clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags); | ||
621 | wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK); | ||
622 | } | ||
623 | |||
554 | bool | 624 | bool |
555 | backup_cred(struct cifs_sb_info *cifs_sb) | 625 | backup_cred(struct cifs_sb_info *cifs_sb) |
556 | { | 626 | { |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 526fb89f9230..d1fdfa848703 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -372,6 +372,16 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) | |||
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
374 | 374 | ||
375 | static void | ||
376 | cifs_downgrade_oplock(struct TCP_Server_Info *server, | ||
377 | struct cifsInodeInfo *cinode, bool set_level2) | ||
378 | { | ||
379 | if (set_level2) | ||
380 | cifs_set_oplock_level(cinode, OPLOCK_READ); | ||
381 | else | ||
382 | cifs_set_oplock_level(cinode, 0); | ||
383 | } | ||
384 | |||
375 | static bool | 385 | static bool |
376 | cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, | 386 | cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, |
377 | char *buf, int malformed) | 387 | char *buf, int malformed) |
@@ -1019,6 +1029,7 @@ struct smb_version_operations smb1_operations = { | |||
1019 | .clear_stats = cifs_clear_stats, | 1029 | .clear_stats = cifs_clear_stats, |
1020 | .print_stats = cifs_print_stats, | 1030 | .print_stats = cifs_print_stats, |
1021 | .is_oplock_break = is_valid_oplock_break, | 1031 | .is_oplock_break = is_valid_oplock_break, |
1032 | .downgrade_oplock = cifs_downgrade_oplock, | ||
1022 | .check_trans2 = cifs_check_trans2, | 1033 | .check_trans2 = cifs_check_trans2, |
1023 | .need_neg = cifs_need_neg, | 1034 | .need_neg = cifs_need_neg, |
1024 | .negotiate = cifs_negotiate, | 1035 | .negotiate = cifs_negotiate, |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index fb3966265b6e..b8021fde987d 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -575,9 +575,21 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) | |||
575 | else | 575 | else |
576 | cfile->oplock_break_cancelled = false; | 576 | cfile->oplock_break_cancelled = false; |
577 | 577 | ||
578 | server->ops->set_oplock_level(cinode, | 578 | set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, |
579 | rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0, | 579 | &cinode->flags); |
580 | 0, NULL); | 580 | |
581 | /* | ||
582 | * Set flag if the server downgrades the oplock | ||
583 | * to L2 else clear. | ||
584 | */ | ||
585 | if (rsp->OplockLevel) | ||
586 | set_bit( | ||
587 | CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, | ||
588 | &cinode->flags); | ||
589 | else | ||
590 | clear_bit( | ||
591 | CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, | ||
592 | &cinode->flags); | ||
581 | 593 | ||
582 | queue_work(cifsiod_wq, &cfile->oplock_break); | 594 | queue_work(cifsiod_wq, &cfile->oplock_break); |
583 | 595 | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 192f51a12cf1..35ddc3ed119d 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -905,6 +905,17 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
905 | } | 905 | } |
906 | 906 | ||
907 | static void | 907 | static void |
908 | smb2_downgrade_oplock(struct TCP_Server_Info *server, | ||
909 | struct cifsInodeInfo *cinode, bool set_level2) | ||
910 | { | ||
911 | if (set_level2) | ||
912 | server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II, | ||
913 | 0, NULL); | ||
914 | else | ||
915 | server->ops->set_oplock_level(cinode, 0, 0, NULL); | ||
916 | } | ||
917 | |||
918 | static void | ||
908 | smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, | 919 | smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, |
909 | unsigned int epoch, bool *purge_cache) | 920 | unsigned int epoch, bool *purge_cache) |
910 | { | 921 | { |
@@ -1110,6 +1121,7 @@ struct smb_version_operations smb20_operations = { | |||
1110 | .clear_stats = smb2_clear_stats, | 1121 | .clear_stats = smb2_clear_stats, |
1111 | .print_stats = smb2_print_stats, | 1122 | .print_stats = smb2_print_stats, |
1112 | .is_oplock_break = smb2_is_valid_oplock_break, | 1123 | .is_oplock_break = smb2_is_valid_oplock_break, |
1124 | .downgrade_oplock = smb2_downgrade_oplock, | ||
1113 | .need_neg = smb2_need_neg, | 1125 | .need_neg = smb2_need_neg, |
1114 | .negotiate = smb2_negotiate, | 1126 | .negotiate = smb2_negotiate, |
1115 | .negotiate_wsize = smb2_negotiate_wsize, | 1127 | .negotiate_wsize = smb2_negotiate_wsize, |
@@ -1184,6 +1196,7 @@ struct smb_version_operations smb21_operations = { | |||
1184 | .clear_stats = smb2_clear_stats, | 1196 | .clear_stats = smb2_clear_stats, |
1185 | .print_stats = smb2_print_stats, | 1197 | .print_stats = smb2_print_stats, |
1186 | .is_oplock_break = smb2_is_valid_oplock_break, | 1198 | .is_oplock_break = smb2_is_valid_oplock_break, |
1199 | .downgrade_oplock = smb2_downgrade_oplock, | ||
1187 | .need_neg = smb2_need_neg, | 1200 | .need_neg = smb2_need_neg, |
1188 | .negotiate = smb2_negotiate, | 1201 | .negotiate = smb2_negotiate, |
1189 | .negotiate_wsize = smb2_negotiate_wsize, | 1202 | .negotiate_wsize = smb2_negotiate_wsize, |
@@ -1259,6 +1272,7 @@ struct smb_version_operations smb30_operations = { | |||
1259 | .print_stats = smb2_print_stats, | 1272 | .print_stats = smb2_print_stats, |
1260 | .dump_share_caps = smb2_dump_share_caps, | 1273 | .dump_share_caps = smb2_dump_share_caps, |
1261 | .is_oplock_break = smb2_is_valid_oplock_break, | 1274 | .is_oplock_break = smb2_is_valid_oplock_break, |
1275 | .downgrade_oplock = smb2_downgrade_oplock, | ||
1262 | .need_neg = smb2_need_neg, | 1276 | .need_neg = smb2_need_neg, |
1263 | .negotiate = smb2_negotiate, | 1277 | .negotiate = smb2_negotiate, |
1264 | .negotiate_wsize = smb2_negotiate_wsize, | 1278 | .negotiate_wsize = smb2_negotiate_wsize, |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 860344701067..3802f8c94acc 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1352,7 +1352,6 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | |||
1352 | u64 persistent_fid, u64 volatile_fid) | 1352 | u64 persistent_fid, u64 volatile_fid) |
1353 | { | 1353 | { |
1354 | int rc; | 1354 | int rc; |
1355 | char *res_key = NULL; | ||
1356 | struct compress_ioctl fsctl_input; | 1355 | struct compress_ioctl fsctl_input; |
1357 | char *ret_data = NULL; | 1356 | char *ret_data = NULL; |
1358 | 1357 | ||
@@ -1365,7 +1364,6 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | |||
1365 | 2 /* in data len */, &ret_data /* out data */, NULL); | 1364 | 2 /* in data len */, &ret_data /* out data */, NULL); |
1366 | 1365 | ||
1367 | cifs_dbg(FYI, "set compression rc %d\n", rc); | 1366 | cifs_dbg(FYI, "set compression rc %d\n", rc); |
1368 | kfree(res_key); | ||
1369 | 1367 | ||
1370 | return rc; | 1368 | return rc; |
1371 | } | 1369 | } |
diff --git a/fs/coredump.c b/fs/coredump.c index e3ad709a4232..0b2528fb640e 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -73,10 +73,15 @@ static int expand_corename(struct core_name *cn, int size) | |||
73 | static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg) | 73 | static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg) |
74 | { | 74 | { |
75 | int free, need; | 75 | int free, need; |
76 | va_list arg_copy; | ||
76 | 77 | ||
77 | again: | 78 | again: |
78 | free = cn->size - cn->used; | 79 | free = cn->size - cn->used; |
79 | need = vsnprintf(cn->corename + cn->used, free, fmt, arg); | 80 | |
81 | va_copy(arg_copy, arg); | ||
82 | need = vsnprintf(cn->corename + cn->used, free, fmt, arg_copy); | ||
83 | va_end(arg_copy); | ||
84 | |||
80 | if (need < free) { | 85 | if (need < free) { |
81 | cn->used += need; | 86 | cn->used += need; |
82 | return 0; | 87 | return 0; |
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index abb0f1f53d93..985217626e66 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c | |||
@@ -48,14 +48,18 @@ void __init kernfs_inode_init(void) | |||
48 | 48 | ||
49 | static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) | 49 | static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) |
50 | { | 50 | { |
51 | static DEFINE_MUTEX(iattr_mutex); | ||
52 | struct kernfs_iattrs *ret; | ||
51 | struct iattr *iattrs; | 53 | struct iattr *iattrs; |
52 | 54 | ||
55 | mutex_lock(&iattr_mutex); | ||
56 | |||
53 | if (kn->iattr) | 57 | if (kn->iattr) |
54 | return kn->iattr; | 58 | goto out_unlock; |
55 | 59 | ||
56 | kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL); | 60 | kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL); |
57 | if (!kn->iattr) | 61 | if (!kn->iattr) |
58 | return NULL; | 62 | goto out_unlock; |
59 | iattrs = &kn->iattr->ia_iattr; | 63 | iattrs = &kn->iattr->ia_iattr; |
60 | 64 | ||
61 | /* assign default attributes */ | 65 | /* assign default attributes */ |
@@ -65,8 +69,10 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) | |||
65 | iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; | 69 | iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; |
66 | 70 | ||
67 | simple_xattrs_init(&kn->iattr->xattrs); | 71 | simple_xattrs_init(&kn->iattr->xattrs); |
68 | 72 | out_unlock: | |
69 | return kn->iattr; | 73 | ret = kn->iattr; |
74 | mutex_unlock(&iattr_mutex); | ||
75 | return ret; | ||
70 | } | 76 | } |
71 | 77 | ||
72 | static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) | 78 | static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) |
diff --git a/fs/super.c b/fs/super.c index e9dc3c3fe159..48377f7463c0 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -800,7 +800,10 @@ void emergency_remount(void) | |||
800 | 800 | ||
801 | static DEFINE_IDA(unnamed_dev_ida); | 801 | static DEFINE_IDA(unnamed_dev_ida); |
802 | static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ | 802 | static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ |
803 | static int unnamed_dev_start = 0; /* don't bother trying below it */ | 803 | /* Many userspace utilities consider an FSID of 0 invalid. |
804 | * Always return at least 1 from get_anon_bdev. | ||
805 | */ | ||
806 | static int unnamed_dev_start = 1; | ||
804 | 807 | ||
805 | int get_anon_bdev(dev_t *p) | 808 | int get_anon_bdev(dev_t *p) |
806 | { | 809 | { |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 1b8b91b67fdb..28cc1acd5439 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -453,95 +453,3 @@ void sysfs_remove_bin_file(struct kobject *kobj, | |||
453 | kernfs_remove_by_name(kobj->sd, attr->attr.name); | 453 | kernfs_remove_by_name(kobj->sd, attr->attr.name); |
454 | } | 454 | } |
455 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); | 455 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); |
456 | |||
457 | struct sysfs_schedule_callback_struct { | ||
458 | struct list_head workq_list; | ||
459 | struct kobject *kobj; | ||
460 | void (*func)(void *); | ||
461 | void *data; | ||
462 | struct module *owner; | ||
463 | struct work_struct work; | ||
464 | }; | ||
465 | |||
466 | static struct workqueue_struct *sysfs_workqueue; | ||
467 | static DEFINE_MUTEX(sysfs_workq_mutex); | ||
468 | static LIST_HEAD(sysfs_workq); | ||
469 | static void sysfs_schedule_callback_work(struct work_struct *work) | ||
470 | { | ||
471 | struct sysfs_schedule_callback_struct *ss = container_of(work, | ||
472 | struct sysfs_schedule_callback_struct, work); | ||
473 | |||
474 | (ss->func)(ss->data); | ||
475 | kobject_put(ss->kobj); | ||
476 | module_put(ss->owner); | ||
477 | mutex_lock(&sysfs_workq_mutex); | ||
478 | list_del(&ss->workq_list); | ||
479 | mutex_unlock(&sysfs_workq_mutex); | ||
480 | kfree(ss); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * sysfs_schedule_callback - helper to schedule a callback for a kobject | ||
485 | * @kobj: object we're acting for. | ||
486 | * @func: callback function to invoke later. | ||
487 | * @data: argument to pass to @func. | ||
488 | * @owner: module owning the callback code | ||
489 | * | ||
490 | * sysfs attribute methods must not unregister themselves or their parent | ||
491 | * kobject (which would amount to the same thing). Attempts to do so will | ||
492 | * deadlock, since unregistration is mutually exclusive with driver | ||
493 | * callbacks. | ||
494 | * | ||
495 | * Instead methods can call this routine, which will attempt to allocate | ||
496 | * and schedule a workqueue request to call back @func with @data as its | ||
497 | * argument in the workqueue's process context. @kobj will be pinned | ||
498 | * until @func returns. | ||
499 | * | ||
500 | * Returns 0 if the request was submitted, -ENOMEM if storage could not | ||
501 | * be allocated, -ENODEV if a reference to @owner isn't available, | ||
502 | * -EAGAIN if a callback has already been scheduled for @kobj. | ||
503 | */ | ||
504 | int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | ||
505 | void *data, struct module *owner) | ||
506 | { | ||
507 | struct sysfs_schedule_callback_struct *ss, *tmp; | ||
508 | |||
509 | if (!try_module_get(owner)) | ||
510 | return -ENODEV; | ||
511 | |||
512 | mutex_lock(&sysfs_workq_mutex); | ||
513 | list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) | ||
514 | if (ss->kobj == kobj) { | ||
515 | module_put(owner); | ||
516 | mutex_unlock(&sysfs_workq_mutex); | ||
517 | return -EAGAIN; | ||
518 | } | ||
519 | mutex_unlock(&sysfs_workq_mutex); | ||
520 | |||
521 | if (sysfs_workqueue == NULL) { | ||
522 | sysfs_workqueue = create_singlethread_workqueue("sysfsd"); | ||
523 | if (sysfs_workqueue == NULL) { | ||
524 | module_put(owner); | ||
525 | return -ENOMEM; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); | ||
530 | if (!ss) { | ||
531 | module_put(owner); | ||
532 | return -ENOMEM; | ||
533 | } | ||
534 | kobject_get(kobj); | ||
535 | ss->kobj = kobj; | ||
536 | ss->func = func; | ||
537 | ss->data = data; | ||
538 | ss->owner = owner; | ||
539 | INIT_WORK(&ss->work, sysfs_schedule_callback_work); | ||
540 | INIT_LIST_HEAD(&ss->workq_list); | ||
541 | mutex_lock(&sysfs_workq_mutex); | ||
542 | list_add_tail(&ss->workq_list, &sysfs_workq); | ||
543 | mutex_unlock(&sysfs_workq_mutex); | ||
544 | queue_work(sysfs_workqueue, &ss->work); | ||
545 | return 0; | ||
546 | } | ||
547 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | ||
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 75df77d09f75..0479c32c5eb1 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -1344,6 +1344,14 @@ __xfs_get_blocks( | |||
1344 | /* | 1344 | /* |
1345 | * If this is O_DIRECT or the mpage code calling tell them how large | 1345 | * If this is O_DIRECT or the mpage code calling tell them how large |
1346 | * the mapping is, so that we can avoid repeated get_blocks calls. | 1346 | * the mapping is, so that we can avoid repeated get_blocks calls. |
1347 | * | ||
1348 | * If the mapping spans EOF, then we have to break the mapping up as the | ||
1349 | * mapping for blocks beyond EOF must be marked new so that sub block | ||
1350 | * regions can be correctly zeroed. We can't do this for mappings within | ||
1351 | * EOF unless the mapping was just allocated or is unwritten, otherwise | ||
1352 | * the callers would overwrite existing data with zeros. Hence we have | ||
1353 | * to split the mapping into a range up to and including EOF, and a | ||
1354 | * second mapping for beyond EOF. | ||
1347 | */ | 1355 | */ |
1348 | if (direct || size > (1 << inode->i_blkbits)) { | 1356 | if (direct || size > (1 << inode->i_blkbits)) { |
1349 | xfs_off_t mapping_size; | 1357 | xfs_off_t mapping_size; |
@@ -1354,6 +1362,12 @@ __xfs_get_blocks( | |||
1354 | ASSERT(mapping_size > 0); | 1362 | ASSERT(mapping_size > 0); |
1355 | if (mapping_size > size) | 1363 | if (mapping_size > size) |
1356 | mapping_size = size; | 1364 | mapping_size = size; |
1365 | if (offset < i_size_read(inode) && | ||
1366 | offset + mapping_size >= i_size_read(inode)) { | ||
1367 | /* limit mapping to block that spans EOF */ | ||
1368 | mapping_size = roundup_64(i_size_read(inode) - offset, | ||
1369 | 1 << inode->i_blkbits); | ||
1370 | } | ||
1357 | if (mapping_size > LONG_MAX) | 1371 | if (mapping_size > LONG_MAX) |
1358 | mapping_size = LONG_MAX; | 1372 | mapping_size = LONG_MAX; |
1359 | 1373 | ||
@@ -1566,6 +1580,16 @@ xfs_vm_write_failed( | |||
1566 | 1580 | ||
1567 | xfs_vm_kill_delalloc_range(inode, block_offset, | 1581 | xfs_vm_kill_delalloc_range(inode, block_offset, |
1568 | block_offset + bh->b_size); | 1582 | block_offset + bh->b_size); |
1583 | |||
1584 | /* | ||
1585 | * This buffer does not contain data anymore. make sure anyone | ||
1586 | * who finds it knows that for certain. | ||
1587 | */ | ||
1588 | clear_buffer_delay(bh); | ||
1589 | clear_buffer_uptodate(bh); | ||
1590 | clear_buffer_mapped(bh); | ||
1591 | clear_buffer_new(bh); | ||
1592 | clear_buffer_dirty(bh); | ||
1569 | } | 1593 | } |
1570 | 1594 | ||
1571 | } | 1595 | } |
@@ -1599,12 +1623,21 @@ xfs_vm_write_begin( | |||
1599 | status = __block_write_begin(page, pos, len, xfs_get_blocks); | 1623 | status = __block_write_begin(page, pos, len, xfs_get_blocks); |
1600 | if (unlikely(status)) { | 1624 | if (unlikely(status)) { |
1601 | struct inode *inode = mapping->host; | 1625 | struct inode *inode = mapping->host; |
1626 | size_t isize = i_size_read(inode); | ||
1602 | 1627 | ||
1603 | xfs_vm_write_failed(inode, page, pos, len); | 1628 | xfs_vm_write_failed(inode, page, pos, len); |
1604 | unlock_page(page); | 1629 | unlock_page(page); |
1605 | 1630 | ||
1606 | if (pos + len > i_size_read(inode)) | 1631 | /* |
1607 | truncate_pagecache(inode, i_size_read(inode)); | 1632 | * If the write is beyond EOF, we only want to kill blocks |
1633 | * allocated in this write, not blocks that were previously | ||
1634 | * written successfully. | ||
1635 | */ | ||
1636 | if (pos + len > isize) { | ||
1637 | ssize_t start = max_t(ssize_t, pos, isize); | ||
1638 | |||
1639 | truncate_pagecache_range(inode, start, pos + len); | ||
1640 | } | ||
1608 | 1641 | ||
1609 | page_cache_release(page); | 1642 | page_cache_release(page); |
1610 | page = NULL; | 1643 | page = NULL; |
@@ -1615,9 +1648,12 @@ xfs_vm_write_begin( | |||
1615 | } | 1648 | } |
1616 | 1649 | ||
1617 | /* | 1650 | /* |
1618 | * On failure, we only need to kill delalloc blocks beyond EOF because they | 1651 | * On failure, we only need to kill delalloc blocks beyond EOF in the range of |
1619 | * will never be written. For blocks within EOF, generic_write_end() zeros them | 1652 | * this specific write because they will never be written. Previous writes |
1620 | * so they are safe to leave alone and be written with all the other valid data. | 1653 | * beyond EOF where block allocation succeeded do not need to be trashed, so |
1654 | * only new blocks from this write should be trashed. For blocks within | ||
1655 | * EOF, generic_write_end() zeros them so they are safe to leave alone and be | ||
1656 | * written with all the other valid data. | ||
1621 | */ | 1657 | */ |
1622 | STATIC int | 1658 | STATIC int |
1623 | xfs_vm_write_end( | 1659 | xfs_vm_write_end( |
@@ -1640,8 +1676,11 @@ xfs_vm_write_end( | |||
1640 | loff_t to = pos + len; | 1676 | loff_t to = pos + len; |
1641 | 1677 | ||
1642 | if (to > isize) { | 1678 | if (to > isize) { |
1643 | truncate_pagecache(inode, isize); | 1679 | /* only kill blocks in this write beyond EOF */ |
1680 | if (pos > isize) | ||
1681 | isize = pos; | ||
1644 | xfs_vm_kill_delalloc_range(inode, isize, to); | 1682 | xfs_vm_kill_delalloc_range(inode, isize, to); |
1683 | truncate_pagecache_range(inode, isize, to); | ||
1645 | } | 1684 | } |
1646 | } | 1685 | } |
1647 | return ret; | 1686 | return ret; |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 5b6092ef51ef..f0efc7e970ef 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -5413,6 +5413,7 @@ xfs_bmap_shift_extents( | |||
5413 | int whichfork = XFS_DATA_FORK; | 5413 | int whichfork = XFS_DATA_FORK; |
5414 | int logflags; | 5414 | int logflags; |
5415 | xfs_filblks_t blockcount = 0; | 5415 | xfs_filblks_t blockcount = 0; |
5416 | int total_extents; | ||
5416 | 5417 | ||
5417 | if (unlikely(XFS_TEST_ERROR( | 5418 | if (unlikely(XFS_TEST_ERROR( |
5418 | (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && | 5419 | (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && |
@@ -5429,7 +5430,6 @@ xfs_bmap_shift_extents( | |||
5429 | ASSERT(current_ext != NULL); | 5430 | ASSERT(current_ext != NULL); |
5430 | 5431 | ||
5431 | ifp = XFS_IFORK_PTR(ip, whichfork); | 5432 | ifp = XFS_IFORK_PTR(ip, whichfork); |
5432 | |||
5433 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { | 5433 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { |
5434 | /* Read in all the extents */ | 5434 | /* Read in all the extents */ |
5435 | error = xfs_iread_extents(tp, ip, whichfork); | 5435 | error = xfs_iread_extents(tp, ip, whichfork); |
@@ -5456,7 +5456,6 @@ xfs_bmap_shift_extents( | |||
5456 | 5456 | ||
5457 | /* We are going to change core inode */ | 5457 | /* We are going to change core inode */ |
5458 | logflags = XFS_ILOG_CORE; | 5458 | logflags = XFS_ILOG_CORE; |
5459 | |||
5460 | if (ifp->if_flags & XFS_IFBROOT) { | 5459 | if (ifp->if_flags & XFS_IFBROOT) { |
5461 | cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); | 5460 | cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); |
5462 | cur->bc_private.b.firstblock = *firstblock; | 5461 | cur->bc_private.b.firstblock = *firstblock; |
@@ -5467,8 +5466,14 @@ xfs_bmap_shift_extents( | |||
5467 | logflags |= XFS_ILOG_DEXT; | 5466 | logflags |= XFS_ILOG_DEXT; |
5468 | } | 5467 | } |
5469 | 5468 | ||
5470 | while (nexts++ < num_exts && | 5469 | /* |
5471 | *current_ext < XFS_IFORK_NEXTENTS(ip, whichfork)) { | 5470 | * There may be delalloc extents in the data fork before the range we |
5471 | * are collapsing out, so we cannot | ||
5472 | * use the count of real extents here. Instead we have to calculate it | ||
5473 | * from the incore fork. | ||
5474 | */ | ||
5475 | total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); | ||
5476 | while (nexts++ < num_exts && *current_ext < total_extents) { | ||
5472 | 5477 | ||
5473 | gotp = xfs_iext_get_ext(ifp, *current_ext); | 5478 | gotp = xfs_iext_get_ext(ifp, *current_ext); |
5474 | xfs_bmbt_get_all(gotp, &got); | 5479 | xfs_bmbt_get_all(gotp, &got); |
@@ -5556,10 +5561,11 @@ xfs_bmap_shift_extents( | |||
5556 | } | 5561 | } |
5557 | 5562 | ||
5558 | (*current_ext)++; | 5563 | (*current_ext)++; |
5564 | total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); | ||
5559 | } | 5565 | } |
5560 | 5566 | ||
5561 | /* Check if we are done */ | 5567 | /* Check if we are done */ |
5562 | if (*current_ext == XFS_IFORK_NEXTENTS(ip, whichfork)) | 5568 | if (*current_ext == total_extents) |
5563 | *done = 1; | 5569 | *done = 1; |
5564 | 5570 | ||
5565 | del_cursor: | 5571 | del_cursor: |
@@ -5568,6 +5574,5 @@ del_cursor: | |||
5568 | error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); | 5574 | error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); |
5569 | 5575 | ||
5570 | xfs_trans_log_inode(tp, ip, logflags); | 5576 | xfs_trans_log_inode(tp, ip, logflags); |
5571 | |||
5572 | return error; | 5577 | return error; |
5573 | } | 5578 | } |
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 01f6a646caa1..296160b8e78c 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c | |||
@@ -1418,6 +1418,8 @@ xfs_zero_file_space( | |||
1418 | xfs_off_t end_boundary; | 1418 | xfs_off_t end_boundary; |
1419 | int error; | 1419 | int error; |
1420 | 1420 | ||
1421 | trace_xfs_zero_file_space(ip); | ||
1422 | |||
1421 | granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); | 1423 | granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); |
1422 | 1424 | ||
1423 | /* | 1425 | /* |
@@ -1432,9 +1434,18 @@ xfs_zero_file_space( | |||
1432 | ASSERT(end_boundary <= offset + len); | 1434 | ASSERT(end_boundary <= offset + len); |
1433 | 1435 | ||
1434 | if (start_boundary < end_boundary - 1) { | 1436 | if (start_boundary < end_boundary - 1) { |
1435 | /* punch out the page cache over the conversion range */ | 1437 | /* |
1438 | * punch out delayed allocation blocks and the page cache over | ||
1439 | * the conversion range | ||
1440 | */ | ||
1441 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
1442 | error = xfs_bmap_punch_delalloc_range(ip, | ||
1443 | XFS_B_TO_FSBT(mp, start_boundary), | ||
1444 | XFS_B_TO_FSB(mp, end_boundary - start_boundary)); | ||
1445 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1436 | truncate_pagecache_range(VFS_I(ip), start_boundary, | 1446 | truncate_pagecache_range(VFS_I(ip), start_boundary, |
1437 | end_boundary - 1); | 1447 | end_boundary - 1); |
1448 | |||
1438 | /* convert the blocks */ | 1449 | /* convert the blocks */ |
1439 | error = xfs_alloc_file_space(ip, start_boundary, | 1450 | error = xfs_alloc_file_space(ip, start_boundary, |
1440 | end_boundary - start_boundary - 1, | 1451 | end_boundary - start_boundary - 1, |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 107f2fdfe41f..cb10a0aaab3a 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -1372,21 +1372,29 @@ xfs_buf_iorequest( | |||
1372 | xfs_buf_wait_unpin(bp); | 1372 | xfs_buf_wait_unpin(bp); |
1373 | xfs_buf_hold(bp); | 1373 | xfs_buf_hold(bp); |
1374 | 1374 | ||
1375 | /* Set the count to 1 initially, this will stop an I/O | 1375 | /* |
1376 | * Set the count to 1 initially, this will stop an I/O | ||
1376 | * completion callout which happens before we have started | 1377 | * completion callout which happens before we have started |
1377 | * all the I/O from calling xfs_buf_ioend too early. | 1378 | * all the I/O from calling xfs_buf_ioend too early. |
1378 | */ | 1379 | */ |
1379 | atomic_set(&bp->b_io_remaining, 1); | 1380 | atomic_set(&bp->b_io_remaining, 1); |
1380 | _xfs_buf_ioapply(bp); | 1381 | _xfs_buf_ioapply(bp); |
1381 | _xfs_buf_ioend(bp, 1); | 1382 | /* |
1383 | * If _xfs_buf_ioapply failed, we'll get back here with | ||
1384 | * only the reference we took above. _xfs_buf_ioend will | ||
1385 | * drop it to zero, so we'd better not queue it for later, | ||
1386 | * or we'll free it before it's done. | ||
1387 | */ | ||
1388 | _xfs_buf_ioend(bp, bp->b_error ? 0 : 1); | ||
1382 | 1389 | ||
1383 | xfs_buf_rele(bp); | 1390 | xfs_buf_rele(bp); |
1384 | } | 1391 | } |
1385 | 1392 | ||
1386 | /* | 1393 | /* |
1387 | * Waits for I/O to complete on the buffer supplied. It returns immediately if | 1394 | * Waits for I/O to complete on the buffer supplied. It returns immediately if |
1388 | * no I/O is pending or there is already a pending error on the buffer. It | 1395 | * no I/O is pending or there is already a pending error on the buffer, in which |
1389 | * returns the I/O error code, if any, or 0 if there was no error. | 1396 | * case nothing will ever complete. It returns the I/O error code, if any, or |
1397 | * 0 if there was no error. | ||
1390 | */ | 1398 | */ |
1391 | int | 1399 | int |
1392 | xfs_buf_iowait( | 1400 | xfs_buf_iowait( |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 79e96ce98733..82afdcb33183 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -679,7 +679,7 @@ xfs_file_dio_aio_write( | |||
679 | goto out; | 679 | goto out; |
680 | 680 | ||
681 | if (mapping->nrpages) { | 681 | if (mapping->nrpages) { |
682 | ret = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, | 682 | ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, |
683 | pos, -1); | 683 | pos, -1); |
684 | if (ret) | 684 | if (ret) |
685 | goto out; | 685 | goto out; |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 5e7a38fa6ee6..768087bedbac 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1334,7 +1334,8 @@ int | |||
1334 | xfs_create_tmpfile( | 1334 | xfs_create_tmpfile( |
1335 | struct xfs_inode *dp, | 1335 | struct xfs_inode *dp, |
1336 | struct dentry *dentry, | 1336 | struct dentry *dentry, |
1337 | umode_t mode) | 1337 | umode_t mode, |
1338 | struct xfs_inode **ipp) | ||
1338 | { | 1339 | { |
1339 | struct xfs_mount *mp = dp->i_mount; | 1340 | struct xfs_mount *mp = dp->i_mount; |
1340 | struct xfs_inode *ip = NULL; | 1341 | struct xfs_inode *ip = NULL; |
@@ -1402,7 +1403,6 @@ xfs_create_tmpfile( | |||
1402 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); | 1403 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); |
1403 | 1404 | ||
1404 | ip->i_d.di_nlink--; | 1405 | ip->i_d.di_nlink--; |
1405 | d_tmpfile(dentry, VFS_I(ip)); | ||
1406 | error = xfs_iunlink(tp, ip); | 1406 | error = xfs_iunlink(tp, ip); |
1407 | if (error) | 1407 | if (error) |
1408 | goto out_trans_abort; | 1408 | goto out_trans_abort; |
@@ -1415,6 +1415,7 @@ xfs_create_tmpfile( | |||
1415 | xfs_qm_dqrele(gdqp); | 1415 | xfs_qm_dqrele(gdqp); |
1416 | xfs_qm_dqrele(pdqp); | 1416 | xfs_qm_dqrele(pdqp); |
1417 | 1417 | ||
1418 | *ipp = ip; | ||
1418 | return 0; | 1419 | return 0; |
1419 | 1420 | ||
1420 | out_trans_abort: | 1421 | out_trans_abort: |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 396cc1fafd0d..f2fcde52b66d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -334,7 +334,7 @@ int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, | |||
334 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, | 334 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, |
335 | umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp); | 335 | umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp); |
336 | int xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry, | 336 | int xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry, |
337 | umode_t mode); | 337 | umode_t mode, struct xfs_inode **ipp); |
338 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, | 338 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, |
339 | struct xfs_inode *ip); | 339 | struct xfs_inode *ip); |
340 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, | 340 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 89b07e43ca28..ef1ca010f417 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -1053,11 +1053,25 @@ xfs_vn_tmpfile( | |||
1053 | struct dentry *dentry, | 1053 | struct dentry *dentry, |
1054 | umode_t mode) | 1054 | umode_t mode) |
1055 | { | 1055 | { |
1056 | int error; | 1056 | int error; |
1057 | struct xfs_inode *ip; | ||
1058 | struct inode *inode; | ||
1057 | 1059 | ||
1058 | error = xfs_create_tmpfile(XFS_I(dir), dentry, mode); | 1060 | error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); |
1061 | if (unlikely(error)) | ||
1062 | return -error; | ||
1059 | 1063 | ||
1060 | return -error; | 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; | ||
1061 | } | 1075 | } |
1062 | 1076 | ||
1063 | static const struct inode_operations xfs_inode_operations = { | 1077 | static const struct inode_operations xfs_inode_operations = { |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 8497a00e399d..08624dc67317 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1181,11 +1181,14 @@ xlog_iodone(xfs_buf_t *bp) | |||
1181 | /* log I/O is always issued ASYNC */ | 1181 | /* log I/O is always issued ASYNC */ |
1182 | ASSERT(XFS_BUF_ISASYNC(bp)); | 1182 | ASSERT(XFS_BUF_ISASYNC(bp)); |
1183 | xlog_state_done_syncing(iclog, aborted); | 1183 | xlog_state_done_syncing(iclog, aborted); |
1184 | |||
1184 | /* | 1185 | /* |
1185 | * do not reference the buffer (bp) here as we could race | 1186 | * drop the buffer lock now that we are done. Nothing references |
1186 | * with it being freed after writing the unmount record to the | 1187 | * the buffer after this, so an unmount waiting on this lock can now |
1187 | * log. | 1188 | * tear it down safely. As such, it is unsafe to reference the buffer |
1189 | * (bp) after the unlock as we could race with it being freed. | ||
1188 | */ | 1190 | */ |
1191 | xfs_buf_unlock(bp); | ||
1189 | } | 1192 | } |
1190 | 1193 | ||
1191 | /* | 1194 | /* |
@@ -1368,8 +1371,16 @@ xlog_alloc_log( | |||
1368 | bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0); | 1371 | bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0); |
1369 | if (!bp) | 1372 | if (!bp) |
1370 | goto out_free_log; | 1373 | goto out_free_log; |
1371 | bp->b_iodone = xlog_iodone; | 1374 | |
1375 | /* | ||
1376 | * The iclogbuf buffer locks are held over IO but we are not going to do | ||
1377 | * IO yet. Hence unlock the buffer so that the log IO path can grab it | ||
1378 | * when appropriately. | ||
1379 | */ | ||
1372 | ASSERT(xfs_buf_islocked(bp)); | 1380 | ASSERT(xfs_buf_islocked(bp)); |
1381 | xfs_buf_unlock(bp); | ||
1382 | |||
1383 | bp->b_iodone = xlog_iodone; | ||
1373 | log->l_xbuf = bp; | 1384 | log->l_xbuf = bp; |
1374 | 1385 | ||
1375 | spin_lock_init(&log->l_icloglock); | 1386 | spin_lock_init(&log->l_icloglock); |
@@ -1398,6 +1409,9 @@ xlog_alloc_log( | |||
1398 | if (!bp) | 1409 | if (!bp) |
1399 | goto out_free_iclog; | 1410 | goto out_free_iclog; |
1400 | 1411 | ||
1412 | ASSERT(xfs_buf_islocked(bp)); | ||
1413 | xfs_buf_unlock(bp); | ||
1414 | |||
1401 | bp->b_iodone = xlog_iodone; | 1415 | bp->b_iodone = xlog_iodone; |
1402 | iclog->ic_bp = bp; | 1416 | iclog->ic_bp = bp; |
1403 | iclog->ic_data = bp->b_addr; | 1417 | iclog->ic_data = bp->b_addr; |
@@ -1422,7 +1436,6 @@ xlog_alloc_log( | |||
1422 | iclog->ic_callback_tail = &(iclog->ic_callback); | 1436 | iclog->ic_callback_tail = &(iclog->ic_callback); |
1423 | iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize; | 1437 | iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize; |
1424 | 1438 | ||
1425 | ASSERT(xfs_buf_islocked(iclog->ic_bp)); | ||
1426 | init_waitqueue_head(&iclog->ic_force_wait); | 1439 | init_waitqueue_head(&iclog->ic_force_wait); |
1427 | init_waitqueue_head(&iclog->ic_write_wait); | 1440 | init_waitqueue_head(&iclog->ic_write_wait); |
1428 | 1441 | ||
@@ -1631,6 +1644,12 @@ xlog_cksum( | |||
1631 | * we transition the iclogs to IOERROR state *after* flushing all existing | 1644 | * we transition the iclogs to IOERROR state *after* flushing all existing |
1632 | * iclogs to disk. This is because we don't want anymore new transactions to be | 1645 | * iclogs to disk. This is because we don't want anymore new transactions to be |
1633 | * started or completed afterwards. | 1646 | * started or completed afterwards. |
1647 | * | ||
1648 | * We lock the iclogbufs here so that we can serialise against IO completion | ||
1649 | * during unmount. We might be processing a shutdown triggered during unmount, | ||
1650 | * and that can occur asynchronously to the unmount thread, and hence we need to | ||
1651 | * ensure that completes before tearing down the iclogbufs. Hence we need to | ||
1652 | * hold the buffer lock across the log IO to acheive that. | ||
1634 | */ | 1653 | */ |
1635 | STATIC int | 1654 | STATIC int |
1636 | xlog_bdstrat( | 1655 | xlog_bdstrat( |
@@ -1638,6 +1657,7 @@ xlog_bdstrat( | |||
1638 | { | 1657 | { |
1639 | struct xlog_in_core *iclog = bp->b_fspriv; | 1658 | struct xlog_in_core *iclog = bp->b_fspriv; |
1640 | 1659 | ||
1660 | xfs_buf_lock(bp); | ||
1641 | if (iclog->ic_state & XLOG_STATE_IOERROR) { | 1661 | if (iclog->ic_state & XLOG_STATE_IOERROR) { |
1642 | xfs_buf_ioerror(bp, EIO); | 1662 | xfs_buf_ioerror(bp, EIO); |
1643 | xfs_buf_stale(bp); | 1663 | xfs_buf_stale(bp); |
@@ -1645,7 +1665,8 @@ xlog_bdstrat( | |||
1645 | /* | 1665 | /* |
1646 | * It would seem logical to return EIO here, but we rely on | 1666 | * It would seem logical to return EIO here, but we rely on |
1647 | * the log state machine to propagate I/O errors instead of | 1667 | * the log state machine to propagate I/O errors instead of |
1648 | * doing it here. | 1668 | * doing it here. Similarly, IO completion will unlock the |
1669 | * buffer, so we don't do it here. | ||
1649 | */ | 1670 | */ |
1650 | return 0; | 1671 | return 0; |
1651 | } | 1672 | } |
@@ -1847,14 +1868,28 @@ xlog_dealloc_log( | |||
1847 | xlog_cil_destroy(log); | 1868 | xlog_cil_destroy(log); |
1848 | 1869 | ||
1849 | /* | 1870 | /* |
1850 | * always need to ensure that the extra buffer does not point to memory | 1871 | * Cycle all the iclogbuf locks to make sure all log IO completion |
1851 | * owned by another log buffer before we free it. | 1872 | * is done before we tear down these buffers. |
1852 | */ | 1873 | */ |
1874 | iclog = log->l_iclog; | ||
1875 | for (i = 0; i < log->l_iclog_bufs; i++) { | ||
1876 | xfs_buf_lock(iclog->ic_bp); | ||
1877 | xfs_buf_unlock(iclog->ic_bp); | ||
1878 | iclog = iclog->ic_next; | ||
1879 | } | ||
1880 | |||
1881 | /* | ||
1882 | * Always need to ensure that the extra buffer does not point to memory | ||
1883 | * owned by another log buffer before we free it. Also, cycle the lock | ||
1884 | * first to ensure we've completed IO on it. | ||
1885 | */ | ||
1886 | xfs_buf_lock(log->l_xbuf); | ||
1887 | xfs_buf_unlock(log->l_xbuf); | ||
1853 | xfs_buf_set_empty(log->l_xbuf, BTOBB(log->l_iclog_size)); | 1888 | xfs_buf_set_empty(log->l_xbuf, BTOBB(log->l_iclog_size)); |
1854 | xfs_buf_free(log->l_xbuf); | 1889 | xfs_buf_free(log->l_xbuf); |
1855 | 1890 | ||
1856 | iclog = log->l_iclog; | 1891 | iclog = log->l_iclog; |
1857 | for (i=0; i<log->l_iclog_bufs; i++) { | 1892 | for (i = 0; i < log->l_iclog_bufs; i++) { |
1858 | xfs_buf_free(iclog->ic_bp); | 1893 | xfs_buf_free(iclog->ic_bp); |
1859 | next_iclog = iclog->ic_next; | 1894 | next_iclog = iclog->ic_next; |
1860 | kmem_free(iclog); | 1895 | kmem_free(iclog); |
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index a4ae41c179a8..65d8c793a25c 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -603,6 +603,7 @@ DEFINE_INODE_EVENT(xfs_readlink); | |||
603 | DEFINE_INODE_EVENT(xfs_inactive_symlink); | 603 | DEFINE_INODE_EVENT(xfs_inactive_symlink); |
604 | DEFINE_INODE_EVENT(xfs_alloc_file_space); | 604 | DEFINE_INODE_EVENT(xfs_alloc_file_space); |
605 | DEFINE_INODE_EVENT(xfs_free_file_space); | 605 | DEFINE_INODE_EVENT(xfs_free_file_space); |
606 | DEFINE_INODE_EVENT(xfs_zero_file_space); | ||
606 | DEFINE_INODE_EVENT(xfs_collapse_file_space); | 607 | DEFINE_INODE_EVENT(xfs_collapse_file_space); |
607 | DEFINE_INODE_EVENT(xfs_readdir); | 608 | DEFINE_INODE_EVENT(xfs_readdir); |
608 | #ifdef CONFIG_XFS_POSIX_ACL | 609 | #ifdef CONFIG_XFS_POSIX_ACL |