hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/fs/cifs/file.c
....@@ -33,6 +33,7 @@
3333 #include <linux/mount.h>
3434 #include <linux/slab.h>
3535 #include <linux/swap.h>
36
+#include <linux/mm.h>
3637 #include <asm/div64.h>
3738 #include "cifsfs.h"
3839 #include "cifspdu.h"
....@@ -222,9 +223,6 @@
222223 if (!buf)
223224 return -ENOMEM;
224225
225
- if (backup_cred(cifs_sb))
226
- create_options |= CREATE_OPEN_BACKUP_INTENT;
227
-
228226 /* O_SYNC also has bit for O_DSYNC so following check picks up either */
229227 if (f_flags & O_SYNC)
230228 create_options |= CREATE_WRITE_THROUGH;
....@@ -235,7 +233,7 @@
235233 oparms.tcon = tcon;
236234 oparms.cifs_sb = cifs_sb;
237235 oparms.desired_access = desired_access;
238
- oparms.create_options = create_options;
236
+ oparms.create_options = cifs_create_options(cifs_sb, create_options);
239237 oparms.disposition = disposition;
240238 oparms.path = full_path;
241239 oparms.fid = fid;
....@@ -246,6 +244,7 @@
246244 if (rc)
247245 goto out;
248246
247
+ /* TODO: Add support for calling posix query info but with passing in fid */
249248 if (tcon->unix_ext)
250249 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
251250 xid);
....@@ -288,6 +287,8 @@
288287 msleep(10);
289288 }
290289
290
+static void cifsFileInfo_put_work(struct work_struct *work);
291
+
291292 struct cifsFileInfo *
292293 cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
293294 struct tcon_link *tlink, __u32 oplock)
....@@ -322,6 +323,7 @@
322323 cfile->invalidHandle = false;
323324 cfile->tlink = cifs_get_tlink(tlink);
324325 INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
326
+ INIT_WORK(&cfile->put, cifsFileInfo_put_work);
325327 mutex_init(&cfile->fh_mutex);
326328 spin_lock_init(&cfile->file_info_lock);
327329
....@@ -349,6 +351,7 @@
349351 server->ops->set_fid(cfile, fid, oplock);
350352
351353 list_add(&cfile->tlist, &tcon->openFileList);
354
+ atomic_inc(&tcon->num_local_opens);
352355
353356 /* if readable file instance put first in list*/
354357 spin_lock(&cinode->open_file_lock);
....@@ -375,6 +378,41 @@
375378 return cifs_file;
376379 }
377380
381
+static void cifsFileInfo_put_final(struct cifsFileInfo *cifs_file)
382
+{
383
+ struct inode *inode = d_inode(cifs_file->dentry);
384
+ struct cifsInodeInfo *cifsi = CIFS_I(inode);
385
+ struct cifsLockInfo *li, *tmp;
386
+ struct super_block *sb = inode->i_sb;
387
+
388
+ /*
389
+ * Delete any outstanding lock records. We'll lose them when the file
390
+ * is closed anyway.
391
+ */
392
+ cifs_down_write(&cifsi->lock_sem);
393
+ list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) {
394
+ list_del(&li->llist);
395
+ cifs_del_lock_waiters(li);
396
+ kfree(li);
397
+ }
398
+ list_del(&cifs_file->llist->llist);
399
+ kfree(cifs_file->llist);
400
+ up_write(&cifsi->lock_sem);
401
+
402
+ cifs_put_tlink(cifs_file->tlink);
403
+ dput(cifs_file->dentry);
404
+ cifs_sb_deactive(sb);
405
+ kfree(cifs_file);
406
+}
407
+
408
+static void cifsFileInfo_put_work(struct work_struct *work)
409
+{
410
+ struct cifsFileInfo *cifs_file = container_of(work,
411
+ struct cifsFileInfo, put);
412
+
413
+ cifsFileInfo_put_final(cifs_file);
414
+}
415
+
378416 /**
379417 * cifsFileInfo_put - release a reference of file priv data
380418 *
....@@ -382,15 +420,15 @@
382420 */
383421 void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
384422 {
385
- _cifsFileInfo_put(cifs_file, true);
423
+ _cifsFileInfo_put(cifs_file, true, true);
386424 }
387425
388426 /**
389427 * _cifsFileInfo_put - release a reference of file priv data
390428 *
391429 * This may involve closing the filehandle @cifs_file out on the
392
- * server. Must be called without holding tcon->open_file_lock and
393
- * cifs_file->file_info_lock.
430
+ * server. Must be called without holding tcon->open_file_lock,
431
+ * cinode->open_file_lock and cifs_file->file_info_lock.
394432 *
395433 * If @wait_for_oplock_handler is true and we are releasing the last
396434 * reference, wait for any running oplock break handler of the file
....@@ -398,7 +436,8 @@
398436 * oplock break handler, you need to pass false.
399437 *
400438 */
401
-void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler)
439
+void _cifsFileInfo_put(struct cifsFileInfo *cifs_file,
440
+ bool wait_oplock_handler, bool offload)
402441 {
403442 struct inode *inode = d_inode(cifs_file->dentry);
404443 struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
....@@ -406,7 +445,6 @@
406445 struct cifsInodeInfo *cifsi = CIFS_I(inode);
407446 struct super_block *sb = inode->i_sb;
408447 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
409
- struct cifsLockInfo *li, *tmp;
410448 struct cifs_fid fid;
411449 struct cifs_pending_open open;
412450 bool oplock_break_cancelled;
....@@ -431,6 +469,7 @@
431469 /* remove it from the lists */
432470 list_del(&cifs_file->flist);
433471 list_del(&cifs_file->tlist);
472
+ atomic_dec(&tcon->num_local_opens);
434473
435474 if (list_empty(&cifsi->openFileList)) {
436475 cifs_dbg(FYI, "closing last open instance for inode %p\n",
....@@ -456,7 +495,9 @@
456495 unsigned int xid;
457496
458497 xid = get_xid();
459
- if (server->ops->close)
498
+ if (server->ops->close_getattr)
499
+ server->ops->close_getattr(xid, tcon, cifs_file);
500
+ else if (server->ops->close)
460501 server->ops->close(xid, tcon, &cifs_file->fid);
461502 _free_xid(xid);
462503 }
....@@ -466,24 +507,10 @@
466507
467508 cifs_del_pending_open(&open);
468509
469
- /*
470
- * Delete any outstanding lock records. We'll lose them when the file
471
- * is closed anyway.
472
- */
473
- cifs_down_write(&cifsi->lock_sem);
474
- list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) {
475
- list_del(&li->llist);
476
- cifs_del_lock_waiters(li);
477
- kfree(li);
478
- }
479
- list_del(&cifs_file->llist->llist);
480
- kfree(cifs_file->llist);
481
- up_write(&cifsi->lock_sem);
482
-
483
- cifs_put_tlink(cifs_file->tlink);
484
- dput(cifs_file->dentry);
485
- cifs_sb_deactive(sb);
486
- kfree(cifs_file);
510
+ if (offload)
511
+ queue_work(fileinfo_put_wq, &cifs_file->put);
512
+ else
513
+ cifsFileInfo_put_final(cifs_file);
487514 }
488515
489516 int cifs_open(struct inode *inode, struct file *file)
....@@ -724,9 +751,6 @@
724751
725752 desired_access = cifs_convert_flags(cfile->f_flags);
726753
727
- if (backup_cred(cifs_sb))
728
- create_options |= CREATE_OPEN_BACKUP_INTENT;
729
-
730754 /* O_SYNC also has bit for O_DSYNC so following check picks up either */
731755 if (cfile->f_flags & O_SYNC)
732756 create_options |= CREATE_WRITE_THROUGH;
....@@ -740,7 +764,7 @@
740764 oparms.tcon = tcon;
741765 oparms.cifs_sb = cifs_sb;
742766 oparms.desired_access = desired_access;
743
- oparms.create_options = create_options;
767
+ oparms.create_options = cifs_create_options(cifs_sb, create_options);
744768 oparms.disposition = disposition;
745769 oparms.path = full_path;
746770 oparms.fid = &cfile->fid;
....@@ -778,7 +802,9 @@
778802 if (!is_interrupt_error(rc))
779803 mapping_set_error(inode->i_mapping, rc);
780804
781
- if (tcon->unix_ext)
805
+ if (tcon->posix_extensions)
806
+ rc = smb311_posix_get_inode_info(&inode, full_path, inode->i_sb, xid);
807
+ else if (tcon->unix_ext)
782808 rc = cifs_get_inode_info_unix(&inode, full_path,
783809 inode->i_sb, xid);
784810 else
....@@ -814,7 +840,7 @@
814840 int cifs_close(struct inode *inode, struct file *file)
815841 {
816842 if (file->private_data != NULL) {
817
- cifsFileInfo_put(file->private_data);
843
+ _cifsFileInfo_put(file->private_data, true, false);
818844 file->private_data = NULL;
819845 }
820846
....@@ -835,7 +861,7 @@
835861
836862 tcon->need_reopen_files = false;
837863
838
- cifs_dbg(FYI, "Reopen persistent handles");
864
+ cifs_dbg(FYI, "Reopen persistent handles\n");
839865 INIT_LIST_HEAD(&tmp_list);
840866
841867 /* list all files open on tree connection, reopen resilient handles */
....@@ -910,7 +936,7 @@
910936 }
911937
912938 static struct cifsLockInfo *
913
-cifs_lock_init(__u64 offset, __u64 length, __u8 type)
939
+cifs_lock_init(__u64 offset, __u64 length, __u8 type, __u16 flags)
914940 {
915941 struct cifsLockInfo *lock =
916942 kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
....@@ -920,6 +946,7 @@
920946 lock->length = length;
921947 lock->type = type;
922948 lock->pid = current->tgid;
949
+ lock->flags = flags;
923950 INIT_LIST_HEAD(&lock->blist);
924951 init_waitqueue_head(&lock->block_q);
925952 return lock;
....@@ -942,7 +969,8 @@
942969 /* @rw_check : 0 - no op, 1 - read, 2 - write */
943970 static bool
944971 cifs_find_fid_lock_conflict(struct cifs_fid_locks *fdlocks, __u64 offset,
945
- __u64 length, __u8 type, struct cifsFileInfo *cfile,
972
+ __u64 length, __u8 type, __u16 flags,
973
+ struct cifsFileInfo *cfile,
946974 struct cifsLockInfo **conf_lock, int rw_check)
947975 {
948976 struct cifsLockInfo *li;
....@@ -964,6 +992,10 @@
964992 ((server->ops->compare_fids(cfile, cur_cfile) &&
965993 current->tgid == li->pid) || type == li->type))
966994 continue;
995
+ if (rw_check == CIFS_LOCK_OP &&
996
+ (flags & FL_OFDLCK) && (li->flags & FL_OFDLCK) &&
997
+ server->ops->compare_fids(cfile, cur_cfile))
998
+ continue;
967999 if (conf_lock)
9681000 *conf_lock = li;
9691001 return true;
....@@ -973,8 +1005,8 @@
9731005
9741006 bool
9751007 cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
976
- __u8 type, struct cifsLockInfo **conf_lock,
977
- int rw_check)
1008
+ __u8 type, __u16 flags,
1009
+ struct cifsLockInfo **conf_lock, int rw_check)
9781010 {
9791011 bool rc = false;
9801012 struct cifs_fid_locks *cur;
....@@ -982,7 +1014,8 @@
9821014
9831015 list_for_each_entry(cur, &cinode->llist, llist) {
9841016 rc = cifs_find_fid_lock_conflict(cur, offset, length, type,
985
- cfile, conf_lock, rw_check);
1017
+ flags, cfile, conf_lock,
1018
+ rw_check);
9861019 if (rc)
9871020 break;
9881021 }
....@@ -1010,7 +1043,8 @@
10101043 down_read(&cinode->lock_sem);
10111044
10121045 exist = cifs_find_lock_conflict(cfile, offset, length, type,
1013
- &conf_lock, CIFS_LOCK_OP);
1046
+ flock->fl_flags, &conf_lock,
1047
+ CIFS_LOCK_OP);
10141048 if (exist) {
10151049 flock->fl_start = conf_lock->offset;
10161050 flock->fl_end = conf_lock->offset + conf_lock->length - 1;
....@@ -1041,7 +1075,7 @@
10411075 * Set the byte-range lock (mandatory style). Returns:
10421076 * 1) 0, if we set the lock and don't need to request to the server;
10431077 * 2) 1, if no locks prevent us but we need to request to the server;
1044
- * 3) -EACCESS, if there is a lock that prevents us and wait is false.
1078
+ * 3) -EACCES, if there is a lock that prevents us and wait is false.
10451079 */
10461080 static int
10471081 cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock,
....@@ -1057,7 +1091,8 @@
10571091 cifs_down_write(&cinode->lock_sem);
10581092
10591093 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length,
1060
- lock->type, &conf_lock, CIFS_LOCK_OP);
1094
+ lock->type, lock->flags, &conf_lock,
1095
+ CIFS_LOCK_OP);
10611096 if (!exist && cinode->can_cache_brlcks) {
10621097 list_add_tail(&lock->llist, &cfile->llist->locks);
10631098 up_write(&cinode->lock_sem);
....@@ -1115,20 +1150,20 @@
11151150
11161151 /*
11171152 * Set the byte-range lock (posix style). Returns:
1118
- * 1) 0, if we set the lock and don't need to request to the server;
1119
- * 2) 1, if we need to request to the server;
1120
- * 3) <0, if the error occurs while setting the lock.
1153
+ * 1) <0, if the error occurs while setting the lock;
1154
+ * 2) 0, if we set the lock and don't need to request to the server;
1155
+ * 3) FILE_LOCK_DEFERRED, if we will wait for some other file_lock;
1156
+ * 4) FILE_LOCK_DEFERRED + 1, if we need to request to the server.
11211157 */
11221158 static int
11231159 cifs_posix_lock_set(struct file *file, struct file_lock *flock)
11241160 {
11251161 struct cifsInodeInfo *cinode = CIFS_I(file_inode(file));
1126
- int rc = 1;
1162
+ int rc = FILE_LOCK_DEFERRED + 1;
11271163
11281164 if ((flock->fl_flags & FL_POSIX) == 0)
11291165 return rc;
11301166
1131
-try_again:
11321167 cifs_down_write(&cinode->lock_sem);
11331168 if (!cinode->can_cache_brlcks) {
11341169 up_write(&cinode->lock_sem);
....@@ -1137,12 +1172,6 @@
11371172
11381173 rc = posix_lock_file(file, flock, NULL);
11391174 up_write(&cinode->lock_sem);
1140
- if (rc == FILE_LOCK_DEFERRED) {
1141
- rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next);
1142
- if (!rc)
1143
- goto try_again;
1144
- posix_unblock_lock(flock);
1145
- }
11461175 return rc;
11471176 }
11481177
....@@ -1371,7 +1400,7 @@
13711400 cifs_dbg(FYI, "Lease on file - not implemented yet\n");
13721401 if (flock->fl_flags &
13731402 (~(FL_POSIX | FL_FLOCK | FL_SLEEP |
1374
- FL_ACCESS | FL_LEASE | FL_CLOSE)))
1403
+ FL_ACCESS | FL_LEASE | FL_CLOSE | FL_OFDLCK)))
13751404 cifs_dbg(FYI, "Unknown lock flags 0x%x\n", flock->fl_flags);
13761405
13771406 *type = server->vals->large_lock_type;
....@@ -1617,7 +1646,7 @@
16171646 int posix_lock_type;
16181647
16191648 rc = cifs_posix_lock_set(file, flock);
1620
- if (!rc || rc < 0)
1649
+ if (rc <= FILE_LOCK_DEFERRED)
16211650 return rc;
16221651
16231652 if (type & server->vals->shared_lock_type)
....@@ -1638,7 +1667,8 @@
16381667 if (lock) {
16391668 struct cifsLockInfo *lock;
16401669
1641
- lock = cifs_lock_init(flock->fl_start, length, type);
1670
+ lock = cifs_lock_init(flock->fl_start, length, type,
1671
+ flock->fl_flags);
16421672 if (!lock)
16431673 return -ENOMEM;
16441674
....@@ -1677,7 +1707,7 @@
16771707 rc = server->ops->mand_unlock_range(cfile, flock, xid);
16781708
16791709 out:
1680
- if (flock->fl_flags & FL_POSIX) {
1710
+ if ((flock->fl_flags & FL_POSIX) || (flock->fl_flags & FL_FLOCK)) {
16811711 /*
16821712 * If this is a request to remove all locks because we
16831713 * are closing the file, it doesn't matter if the
....@@ -1694,6 +1724,55 @@
16941724 return rc;
16951725 }
16961726
1727
+int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
1728
+{
1729
+ int rc, xid;
1730
+ int lock = 0, unlock = 0;
1731
+ bool wait_flag = false;
1732
+ bool posix_lck = false;
1733
+ struct cifs_sb_info *cifs_sb;
1734
+ struct cifs_tcon *tcon;
1735
+ struct cifsFileInfo *cfile;
1736
+ __u32 type;
1737
+
1738
+ xid = get_xid();
1739
+
1740
+ if (!(fl->fl_flags & FL_FLOCK)) {
1741
+ rc = -ENOLCK;
1742
+ free_xid(xid);
1743
+ return rc;
1744
+ }
1745
+
1746
+ cfile = (struct cifsFileInfo *)file->private_data;
1747
+ tcon = tlink_tcon(cfile->tlink);
1748
+
1749
+ cifs_read_flock(fl, &type, &lock, &unlock, &wait_flag,
1750
+ tcon->ses->server);
1751
+ cifs_sb = CIFS_FILE_SB(file);
1752
+
1753
+ if (cap_unix(tcon->ses) &&
1754
+ (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
1755
+ ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
1756
+ posix_lck = true;
1757
+
1758
+ if (!lock && !unlock) {
1759
+ /*
1760
+ * if no lock or unlock then nothing to do since we do not
1761
+ * know what it is
1762
+ */
1763
+ rc = -EOPNOTSUPP;
1764
+ free_xid(xid);
1765
+ return rc;
1766
+ }
1767
+
1768
+ rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
1769
+ xid);
1770
+ free_xid(xid);
1771
+ return rc;
1772
+
1773
+
1774
+}
1775
+
16971776 int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
16981777 {
16991778 int rc, xid;
....@@ -1702,9 +1781,7 @@
17021781 bool posix_lck = false;
17031782 struct cifs_sb_info *cifs_sb;
17041783 struct cifs_tcon *tcon;
1705
- struct cifsInodeInfo *cinode;
17061784 struct cifsFileInfo *cfile;
1707
- __u16 netfid;
17081785 __u32 type;
17091786
17101787 rc = -EACCES;
....@@ -1719,10 +1796,7 @@
17191796
17201797 cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag,
17211798 tcon->ses->server);
1722
-
17231799 cifs_sb = CIFS_FILE_SB(file);
1724
- netfid = cfile->fid.netfid;
1725
- cinode = CIFS_I(file_inode(file));
17261800
17271801 if (cap_unix(tcon->ses) &&
17281802 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
....@@ -1774,15 +1848,12 @@
17741848 int rc = 0;
17751849 unsigned int bytes_written = 0;
17761850 unsigned int total_written;
1777
- struct cifs_sb_info *cifs_sb;
17781851 struct cifs_tcon *tcon;
17791852 struct TCP_Server_Info *server;
17801853 unsigned int xid;
17811854 struct dentry *dentry = open_file->dentry;
17821855 struct cifsInodeInfo *cifsi = CIFS_I(d_inode(dentry));
1783
- struct cifs_io_parms io_parms;
1784
-
1785
- cifs_sb = CIFS_SB(dentry->d_sb);
1856
+ struct cifs_io_parms io_parms = {0};
17861857
17871858 cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n",
17881859 write_size, *offset, dentry);
....@@ -1886,23 +1957,30 @@
18861957 return NULL;
18871958 }
18881959
1889
-struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1890
- bool fsuid_only)
1960
+/* Return -EBADF if no handle is found and general rc otherwise */
1961
+int
1962
+cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags,
1963
+ struct cifsFileInfo **ret_file)
18911964 {
18921965 struct cifsFileInfo *open_file, *inv_file = NULL;
18931966 struct cifs_sb_info *cifs_sb;
18941967 bool any_available = false;
1895
- int rc;
1968
+ int rc = -EBADF;
18961969 unsigned int refind = 0;
1970
+ bool fsuid_only = flags & FIND_WR_FSUID_ONLY;
1971
+ bool with_delete = flags & FIND_WR_WITH_DELETE;
1972
+ *ret_file = NULL;
18971973
1898
- /* Having a null inode here (because mapping->host was set to zero by
1899
- the VFS or MM) should not happen but we had reports of on oops (due to
1900
- it being zero) during stress testcases so we need to check for it */
1974
+ /*
1975
+ * Having a null inode here (because mapping->host was set to zero by
1976
+ * the VFS or MM) should not happen but we had reports of on oops (due
1977
+ * to it being zero) during stress testcases so we need to check for it
1978
+ */
19011979
19021980 if (cifs_inode == NULL) {
19031981 cifs_dbg(VFS, "Null inode passed to cifs_writeable_file\n");
19041982 dump_stack();
1905
- return NULL;
1983
+ return rc;
19061984 }
19071985
19081986 cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
....@@ -1915,19 +1993,22 @@
19151993 refind_writable:
19161994 if (refind > MAX_REOPEN_ATT) {
19171995 spin_unlock(&cifs_inode->open_file_lock);
1918
- return NULL;
1996
+ return rc;
19191997 }
19201998 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
19211999 if (!any_available && open_file->pid != current->tgid)
19222000 continue;
19232001 if (fsuid_only && !uid_eq(open_file->uid, current_fsuid()))
19242002 continue;
2003
+ if (with_delete && !(open_file->fid.access & DELETE))
2004
+ continue;
19252005 if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
19262006 if (!open_file->invalidHandle) {
19272007 /* found a good writable file */
19282008 cifsFileInfo_get(open_file);
19292009 spin_unlock(&cifs_inode->open_file_lock);
1930
- return open_file;
2010
+ *ret_file = open_file;
2011
+ return 0;
19312012 } else {
19322013 if (!inv_file)
19332014 inv_file = open_file;
....@@ -1949,22 +2030,107 @@
19492030
19502031 if (inv_file) {
19512032 rc = cifs_reopen_file(inv_file, false);
1952
- if (!rc)
1953
- return inv_file;
1954
- else {
1955
- spin_lock(&cifs_inode->open_file_lock);
1956
- list_move_tail(&inv_file->flist,
1957
- &cifs_inode->openFileList);
1958
- spin_unlock(&cifs_inode->open_file_lock);
1959
- cifsFileInfo_put(inv_file);
1960
- ++refind;
1961
- inv_file = NULL;
1962
- spin_lock(&cifs_inode->open_file_lock);
1963
- goto refind_writable;
2033
+ if (!rc) {
2034
+ *ret_file = inv_file;
2035
+ return 0;
19642036 }
2037
+
2038
+ spin_lock(&cifs_inode->open_file_lock);
2039
+ list_move_tail(&inv_file->flist, &cifs_inode->openFileList);
2040
+ spin_unlock(&cifs_inode->open_file_lock);
2041
+ cifsFileInfo_put(inv_file);
2042
+ ++refind;
2043
+ inv_file = NULL;
2044
+ spin_lock(&cifs_inode->open_file_lock);
2045
+ goto refind_writable;
19652046 }
19662047
1967
- return NULL;
2048
+ return rc;
2049
+}
2050
+
2051
+struct cifsFileInfo *
2052
+find_writable_file(struct cifsInodeInfo *cifs_inode, int flags)
2053
+{
2054
+ struct cifsFileInfo *cfile;
2055
+ int rc;
2056
+
2057
+ rc = cifs_get_writable_file(cifs_inode, flags, &cfile);
2058
+ if (rc)
2059
+ cifs_dbg(FYI, "Couldn't find writable handle rc=%d\n", rc);
2060
+
2061
+ return cfile;
2062
+}
2063
+
2064
+int
2065
+cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
2066
+ int flags,
2067
+ struct cifsFileInfo **ret_file)
2068
+{
2069
+ struct list_head *tmp;
2070
+ struct cifsFileInfo *cfile;
2071
+ struct cifsInodeInfo *cinode;
2072
+ char *full_path;
2073
+
2074
+ *ret_file = NULL;
2075
+
2076
+ spin_lock(&tcon->open_file_lock);
2077
+ list_for_each(tmp, &tcon->openFileList) {
2078
+ cfile = list_entry(tmp, struct cifsFileInfo,
2079
+ tlist);
2080
+ full_path = build_path_from_dentry(cfile->dentry);
2081
+ if (full_path == NULL) {
2082
+ spin_unlock(&tcon->open_file_lock);
2083
+ return -ENOMEM;
2084
+ }
2085
+ if (strcmp(full_path, name)) {
2086
+ kfree(full_path);
2087
+ continue;
2088
+ }
2089
+
2090
+ kfree(full_path);
2091
+ cinode = CIFS_I(d_inode(cfile->dentry));
2092
+ spin_unlock(&tcon->open_file_lock);
2093
+ return cifs_get_writable_file(cinode, flags, ret_file);
2094
+ }
2095
+
2096
+ spin_unlock(&tcon->open_file_lock);
2097
+ return -ENOENT;
2098
+}
2099
+
2100
+int
2101
+cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
2102
+ struct cifsFileInfo **ret_file)
2103
+{
2104
+ struct list_head *tmp;
2105
+ struct cifsFileInfo *cfile;
2106
+ struct cifsInodeInfo *cinode;
2107
+ char *full_path;
2108
+
2109
+ *ret_file = NULL;
2110
+
2111
+ spin_lock(&tcon->open_file_lock);
2112
+ list_for_each(tmp, &tcon->openFileList) {
2113
+ cfile = list_entry(tmp, struct cifsFileInfo,
2114
+ tlist);
2115
+ full_path = build_path_from_dentry(cfile->dentry);
2116
+ if (full_path == NULL) {
2117
+ spin_unlock(&tcon->open_file_lock);
2118
+ return -ENOMEM;
2119
+ }
2120
+ if (strcmp(full_path, name)) {
2121
+ kfree(full_path);
2122
+ continue;
2123
+ }
2124
+
2125
+ kfree(full_path);
2126
+ cinode = CIFS_I(d_inode(cfile->dentry));
2127
+ spin_unlock(&tcon->open_file_lock);
2128
+ *ret_file = find_readable_file(cinode, 0);
2129
+ return *ret_file ? 0 : -ENOENT;
2130
+ }
2131
+
2132
+ spin_unlock(&tcon->open_file_lock);
2133
+ return -ENOENT;
19682134 }
19692135
19702136 static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
....@@ -2001,8 +2167,9 @@
20012167 if (mapping->host->i_size - offset < (loff_t)to)
20022168 to = (unsigned)(mapping->host->i_size - offset);
20032169
2004
- open_file = find_writable_file(CIFS_I(mapping->host), false);
2005
- if (open_file) {
2170
+ rc = cifs_get_writable_file(CIFS_I(mapping->host), FIND_WR_ANY,
2171
+ &open_file);
2172
+ if (!rc) {
20062173 bytes_written = cifs_write(open_file, open_file->pid,
20072174 write_data, to - from, &offset);
20082175 cifsFileInfo_put(open_file);
....@@ -2012,9 +2179,12 @@
20122179 rc = 0;
20132180 else if (bytes_written < 0)
20142181 rc = bytes_written;
2182
+ else
2183
+ rc = -EFAULT;
20152184 } else {
2016
- cifs_dbg(FYI, "No writeable filehandles for inode\n");
2017
- rc = -EIO;
2185
+ cifs_dbg(FYI, "No writable handle for write page rc=%d\n", rc);
2186
+ if (!is_retryable_error(rc))
2187
+ rc = -EIO;
20182188 }
20192189
20202190 kunmap(page);
....@@ -2121,9 +2291,7 @@
21212291 wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
21222292 struct address_space *mapping, struct writeback_control *wbc)
21232293 {
2124
- int rc = 0;
2125
- struct TCP_Server_Info *server;
2126
- unsigned int i;
2294
+ int rc;
21272295
21282296 wdata->sync_mode = wbc->sync_mode;
21292297 wdata->nr_pages = nr_pages;
....@@ -2133,21 +2301,17 @@
21332301 page_offset(wdata->pages[nr_pages - 1]),
21342302 (loff_t)PAGE_SIZE);
21352303 wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz;
2304
+ wdata->pid = wdata->cfile->pid;
21362305
2137
- if (wdata->cfile != NULL)
2138
- cifsFileInfo_put(wdata->cfile);
2139
- wdata->cfile = find_writable_file(CIFS_I(mapping->host), false);
2140
- if (!wdata->cfile) {
2141
- cifs_dbg(VFS, "No writable handles for inode\n");
2142
- rc = -EBADF;
2143
- } else {
2144
- wdata->pid = wdata->cfile->pid;
2145
- server = tlink_tcon(wdata->cfile->tlink)->ses->server;
2146
- rc = server->ops->async_writev(wdata, cifs_writedata_release);
2147
- }
2306
+ rc = adjust_credits(wdata->server, &wdata->credits, wdata->bytes);
2307
+ if (rc)
2308
+ return rc;
21482309
2149
- for (i = 0; i < nr_pages; ++i)
2150
- unlock_page(wdata->pages[i]);
2310
+ if (wdata->cfile->invalidHandle)
2311
+ rc = -EAGAIN;
2312
+ else
2313
+ rc = wdata->server->ops->async_writev(wdata,
2314
+ cifs_writedata_release);
21512315
21522316 return rc;
21532317 }
....@@ -2155,13 +2319,16 @@
21552319 static int cifs_writepages(struct address_space *mapping,
21562320 struct writeback_control *wbc)
21572321 {
2158
- struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb);
2322
+ struct inode *inode = mapping->host;
2323
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
21592324 struct TCP_Server_Info *server;
21602325 bool done = false, scanned = false, range_whole = false;
21612326 pgoff_t end, index;
21622327 struct cifs_writedata *wdata;
2328
+ struct cifsFileInfo *cfile = NULL;
21632329 int rc = 0;
21642330 int saved_rc = 0;
2331
+ unsigned int xid;
21652332
21662333 /*
21672334 * If wsize is smaller than the page cache size, default to writing
....@@ -2170,6 +2337,7 @@
21702337 if (cifs_sb->wsize < PAGE_SIZE)
21712338 return generic_writepages(mapping, wbc);
21722339
2340
+ xid = get_xid();
21732341 if (wbc->range_cyclic) {
21742342 index = mapping->writeback_index; /* Start from prev offset */
21752343 end = -1;
....@@ -2180,14 +2348,27 @@
21802348 range_whole = true;
21812349 scanned = true;
21822350 }
2183
- server = cifs_sb_master_tcon(cifs_sb)->ses->server;
2351
+ server = cifs_pick_channel(cifs_sb_master_tcon(cifs_sb)->ses);
2352
+
21842353 retry:
21852354 while (!done && index <= end) {
2186
- unsigned int i, nr_pages, found_pages, wsize, credits;
2355
+ unsigned int i, nr_pages, found_pages, wsize;
21872356 pgoff_t next = 0, tofind, saved_index = index;
2357
+ struct cifs_credits credits_on_stack;
2358
+ struct cifs_credits *credits = &credits_on_stack;
2359
+ int get_file_rc = 0;
2360
+
2361
+ if (cfile)
2362
+ cifsFileInfo_put(cfile);
2363
+
2364
+ rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile);
2365
+
2366
+ /* in case of an error store it to return later */
2367
+ if (rc)
2368
+ get_file_rc = rc;
21882369
21892370 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2190
- &wsize, &credits);
2371
+ &wsize, credits);
21912372 if (rc != 0) {
21922373 done = true;
21932374 break;
....@@ -2220,13 +2401,27 @@
22202401 continue;
22212402 }
22222403
2223
- wdata->credits = credits;
2404
+ wdata->credits = credits_on_stack;
2405
+ wdata->cfile = cfile;
2406
+ wdata->server = server;
2407
+ cfile = NULL;
22242408
2225
- rc = wdata_send_pages(wdata, nr_pages, mapping, wbc);
2409
+ if (!wdata->cfile) {
2410
+ cifs_dbg(VFS, "No writable handle in writepages rc=%d\n",
2411
+ get_file_rc);
2412
+ if (is_retryable_error(get_file_rc))
2413
+ rc = get_file_rc;
2414
+ else
2415
+ rc = -EBADF;
2416
+ } else
2417
+ rc = wdata_send_pages(wdata, nr_pages, mapping, wbc);
2418
+
2419
+ for (i = 0; i < nr_pages; ++i)
2420
+ unlock_page(wdata->pages[i]);
22262421
22272422 /* send failure -- clean up the mess */
22282423 if (rc != 0) {
2229
- add_credits_and_wake_if(server, wdata->credits, 0);
2424
+ add_credits_and_wake_if(server, &wdata->credits, 0);
22302425 for (i = 0; i < nr_pages; ++i) {
22312426 if (is_retryable_error(rc))
22322427 redirty_page_for_writepage(wbc,
....@@ -2278,6 +2473,9 @@
22782473 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
22792474 mapping->writeback_index = index;
22802475
2476
+ if (cfile)
2477
+ cifsFileInfo_put(cfile);
2478
+ free_xid(xid);
22812479 return rc;
22822480 }
22832481
....@@ -2402,9 +2600,10 @@
24022600 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
24032601
24042602 rc = file_write_and_wait_range(file, start, end);
2405
- if (rc)
2603
+ if (rc) {
2604
+ trace_cifs_fsync_err(inode->i_ino, rc);
24062605 return rc;
2407
- inode_lock(inode);
2606
+ }
24082607
24092608 xid = get_xid();
24102609
....@@ -2422,14 +2621,24 @@
24222621 tcon = tlink_tcon(smbfile->tlink);
24232622 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
24242623 server = tcon->ses->server;
2425
- if (server->ops->flush)
2426
- rc = server->ops->flush(xid, tcon, &smbfile->fid);
2427
- else
2624
+ if (server->ops->flush == NULL) {
24282625 rc = -ENOSYS;
2626
+ goto strict_fsync_exit;
2627
+ }
2628
+
2629
+ if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
2630
+ smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
2631
+ if (smbfile) {
2632
+ rc = server->ops->flush(xid, tcon, &smbfile->fid);
2633
+ cifsFileInfo_put(smbfile);
2634
+ } else
2635
+ cifs_dbg(FYI, "ignore fsync for file not open for write\n");
2636
+ } else
2637
+ rc = server->ops->flush(xid, tcon, &smbfile->fid);
24292638 }
24302639
2640
+strict_fsync_exit:
24312641 free_xid(xid);
2432
- inode_unlock(inode);
24332642 return rc;
24342643 }
24352644
....@@ -2440,13 +2649,14 @@
24402649 struct cifs_tcon *tcon;
24412650 struct TCP_Server_Info *server;
24422651 struct cifsFileInfo *smbfile = file->private_data;
2652
+ struct inode *inode = file_inode(file);
24432653 struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
2444
- struct inode *inode = file->f_mapping->host;
24452654
24462655 rc = file_write_and_wait_range(file, start, end);
2447
- if (rc)
2656
+ if (rc) {
2657
+ trace_cifs_fsync_err(file_inode(file)->i_ino, rc);
24482658 return rc;
2449
- inode_lock(inode);
2659
+ }
24502660
24512661 xid = get_xid();
24522662
....@@ -2456,14 +2666,24 @@
24562666 tcon = tlink_tcon(smbfile->tlink);
24572667 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
24582668 server = tcon->ses->server;
2459
- if (server->ops->flush)
2460
- rc = server->ops->flush(xid, tcon, &smbfile->fid);
2461
- else
2669
+ if (server->ops->flush == NULL) {
24622670 rc = -ENOSYS;
2671
+ goto fsync_exit;
2672
+ }
2673
+
2674
+ if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
2675
+ smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
2676
+ if (smbfile) {
2677
+ rc = server->ops->flush(xid, tcon, &smbfile->fid);
2678
+ cifsFileInfo_put(smbfile);
2679
+ } else
2680
+ cifs_dbg(FYI, "ignore fsync for file not open for write\n");
2681
+ } else
2682
+ rc = server->ops->flush(xid, tcon, &smbfile->fid);
24632683 }
24642684
2685
+fsync_exit:
24652686 free_xid(xid);
2466
- inode_unlock(inode);
24672687 return rc;
24682688 }
24692689
....@@ -2480,7 +2700,8 @@
24802700 rc = filemap_write_and_wait(inode->i_mapping);
24812701
24822702 cifs_dbg(FYI, "Flush inode %p file %p rc %d\n", inode, file, rc);
2483
-
2703
+ if (rc)
2704
+ trace_cifs_flush_err(inode->i_ino, rc);
24842705 return rc;
24852706 }
24862707
....@@ -2603,6 +2824,76 @@
26032824 }
26042825
26052826 static int
2827
+cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2828
+ struct cifs_aio_ctx *ctx)
2829
+{
2830
+ unsigned int wsize;
2831
+ struct cifs_credits credits;
2832
+ int rc;
2833
+ struct TCP_Server_Info *server = wdata->server;
2834
+
2835
+ do {
2836
+ if (wdata->cfile->invalidHandle) {
2837
+ rc = cifs_reopen_file(wdata->cfile, false);
2838
+ if (rc == -EAGAIN)
2839
+ continue;
2840
+ else if (rc)
2841
+ break;
2842
+ }
2843
+
2844
+
2845
+ /*
2846
+ * Wait for credits to resend this wdata.
2847
+ * Note: we are attempting to resend the whole wdata not in
2848
+ * segments
2849
+ */
2850
+ do {
2851
+ rc = server->ops->wait_mtu_credits(server, wdata->bytes,
2852
+ &wsize, &credits);
2853
+ if (rc)
2854
+ goto fail;
2855
+
2856
+ if (wsize < wdata->bytes) {
2857
+ add_credits_and_wake_if(server, &credits, 0);
2858
+ msleep(1000);
2859
+ }
2860
+ } while (wsize < wdata->bytes);
2861
+ wdata->credits = credits;
2862
+
2863
+ rc = adjust_credits(server, &wdata->credits, wdata->bytes);
2864
+
2865
+ if (!rc) {
2866
+ if (wdata->cfile->invalidHandle)
2867
+ rc = -EAGAIN;
2868
+ else {
2869
+#ifdef CONFIG_CIFS_SMB_DIRECT
2870
+ if (wdata->mr) {
2871
+ wdata->mr->need_invalidate = true;
2872
+ smbd_deregister_mr(wdata->mr);
2873
+ wdata->mr = NULL;
2874
+ }
2875
+#endif
2876
+ rc = server->ops->async_writev(wdata,
2877
+ cifs_uncached_writedata_release);
2878
+ }
2879
+ }
2880
+
2881
+ /* If the write was successfully sent, we are done */
2882
+ if (!rc) {
2883
+ list_add_tail(&wdata->list, wdata_list);
2884
+ return 0;
2885
+ }
2886
+
2887
+ /* Roll back credits and retry if needed */
2888
+ add_credits_and_wake_if(server, &wdata->credits, 0);
2889
+ } while (rc == -EAGAIN);
2890
+
2891
+fail:
2892
+ kref_put(&wdata->refcount, cifs_uncached_writedata_release);
2893
+ return rc;
2894
+}
2895
+
2896
+static int
26062897 cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
26072898 struct cifsFileInfo *open_file,
26082899 struct cifs_sb_info *cifs_sb, struct list_head *wdata_list,
....@@ -2616,73 +2907,139 @@
26162907 loff_t saved_offset = offset;
26172908 pid_t pid;
26182909 struct TCP_Server_Info *server;
2910
+ struct page **pagevec;
2911
+ size_t start;
2912
+ unsigned int xid;
26192913
26202914 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
26212915 pid = open_file->pid;
26222916 else
26232917 pid = current->tgid;
26242918
2625
- server = tlink_tcon(open_file->tlink)->ses->server;
2919
+ server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
2920
+ xid = get_xid();
26262921
26272922 do {
2628
- unsigned int wsize, credits;
2923
+ unsigned int wsize;
2924
+ struct cifs_credits credits_on_stack;
2925
+ struct cifs_credits *credits = &credits_on_stack;
2926
+
2927
+ if (open_file->invalidHandle) {
2928
+ rc = cifs_reopen_file(open_file, false);
2929
+ if (rc == -EAGAIN)
2930
+ continue;
2931
+ else if (rc)
2932
+ break;
2933
+ }
26292934
26302935 rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
2631
- &wsize, &credits);
2936
+ &wsize, credits);
26322937 if (rc)
26332938 break;
26342939
2635
- nr_pages = get_numpages(wsize, len, &cur_len);
2636
- wdata = cifs_writedata_alloc(nr_pages,
2940
+ cur_len = min_t(const size_t, len, wsize);
2941
+
2942
+ if (ctx->direct_io) {
2943
+ ssize_t result;
2944
+
2945
+ result = iov_iter_get_pages_alloc(
2946
+ from, &pagevec, cur_len, &start);
2947
+ if (result < 0) {
2948
+ cifs_dbg(VFS,
2949
+ "direct_writev couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n",
2950
+ result, iov_iter_type(from),
2951
+ from->iov_offset, from->count);
2952
+ dump_stack();
2953
+
2954
+ rc = result;
2955
+ add_credits_and_wake_if(server, credits, 0);
2956
+ break;
2957
+ }
2958
+ cur_len = (size_t)result;
2959
+ iov_iter_advance(from, cur_len);
2960
+
2961
+ nr_pages =
2962
+ (cur_len + start + PAGE_SIZE - 1) / PAGE_SIZE;
2963
+
2964
+ wdata = cifs_writedata_direct_alloc(pagevec,
26372965 cifs_uncached_writev_complete);
2638
- if (!wdata) {
2639
- rc = -ENOMEM;
2640
- add_credits_and_wake_if(server, credits, 0);
2641
- break;
2642
- }
2966
+ if (!wdata) {
2967
+ rc = -ENOMEM;
2968
+ add_credits_and_wake_if(server, credits, 0);
2969
+ break;
2970
+ }
26432971
2644
- rc = cifs_write_allocate_pages(wdata->pages, nr_pages);
2645
- if (rc) {
2646
- kfree(wdata);
2647
- add_credits_and_wake_if(server, credits, 0);
2648
- break;
2649
- }
26502972
2651
- num_pages = nr_pages;
2652
- rc = wdata_fill_from_iovec(wdata, from, &cur_len, &num_pages);
2653
- if (rc) {
2654
- for (i = 0; i < nr_pages; i++)
2655
- put_page(wdata->pages[i]);
2656
- kfree(wdata);
2657
- add_credits_and_wake_if(server, credits, 0);
2658
- break;
2659
- }
2973
+ wdata->page_offset = start;
2974
+ wdata->tailsz =
2975
+ nr_pages > 1 ?
2976
+ cur_len - (PAGE_SIZE - start) -
2977
+ (nr_pages - 2) * PAGE_SIZE :
2978
+ cur_len;
2979
+ } else {
2980
+ nr_pages = get_numpages(wsize, len, &cur_len);
2981
+ wdata = cifs_writedata_alloc(nr_pages,
2982
+ cifs_uncached_writev_complete);
2983
+ if (!wdata) {
2984
+ rc = -ENOMEM;
2985
+ add_credits_and_wake_if(server, credits, 0);
2986
+ break;
2987
+ }
26602988
2661
- /*
2662
- * Bring nr_pages down to the number of pages we actually used,
2663
- * and free any pages that we didn't use.
2664
- */
2665
- for ( ; nr_pages > num_pages; nr_pages--)
2666
- put_page(wdata->pages[nr_pages - 1]);
2989
+ rc = cifs_write_allocate_pages(wdata->pages, nr_pages);
2990
+ if (rc) {
2991
+ kvfree(wdata->pages);
2992
+ kfree(wdata);
2993
+ add_credits_and_wake_if(server, credits, 0);
2994
+ break;
2995
+ }
2996
+
2997
+ num_pages = nr_pages;
2998
+ rc = wdata_fill_from_iovec(
2999
+ wdata, from, &cur_len, &num_pages);
3000
+ if (rc) {
3001
+ for (i = 0; i < nr_pages; i++)
3002
+ put_page(wdata->pages[i]);
3003
+ kvfree(wdata->pages);
3004
+ kfree(wdata);
3005
+ add_credits_and_wake_if(server, credits, 0);
3006
+ break;
3007
+ }
3008
+
3009
+ /*
3010
+ * Bring nr_pages down to the number of pages we
3011
+ * actually used, and free any pages that we didn't use.
3012
+ */
3013
+ for ( ; nr_pages > num_pages; nr_pages--)
3014
+ put_page(wdata->pages[nr_pages - 1]);
3015
+
3016
+ wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE);
3017
+ }
26673018
26683019 wdata->sync_mode = WB_SYNC_ALL;
26693020 wdata->nr_pages = nr_pages;
26703021 wdata->offset = (__u64)offset;
26713022 wdata->cfile = cifsFileInfo_get(open_file);
3023
+ wdata->server = server;
26723024 wdata->pid = pid;
26733025 wdata->bytes = cur_len;
26743026 wdata->pagesz = PAGE_SIZE;
2675
- wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE);
2676
- wdata->credits = credits;
3027
+ wdata->credits = credits_on_stack;
26773028 wdata->ctx = ctx;
26783029 kref_get(&ctx->refcount);
26793030
2680
- if (!wdata->cfile->invalidHandle ||
2681
- !(rc = cifs_reopen_file(wdata->cfile, false)))
2682
- rc = server->ops->async_writev(wdata,
3031
+ rc = adjust_credits(server, &wdata->credits, wdata->bytes);
3032
+
3033
+ if (!rc) {
3034
+ if (wdata->cfile->invalidHandle)
3035
+ rc = -EAGAIN;
3036
+ else
3037
+ rc = server->ops->async_writev(wdata,
26833038 cifs_uncached_writedata_release);
3039
+ }
3040
+
26843041 if (rc) {
2685
- add_credits_and_wake_if(server, wdata->credits, 0);
3042
+ add_credits_and_wake_if(server, &wdata->credits, 0);
26863043 kref_put(&wdata->refcount,
26873044 cifs_uncached_writedata_release);
26883045 if (rc == -EAGAIN) {
....@@ -2698,6 +3055,7 @@
26983055 len -= cur_len;
26993056 } while (len > 0);
27003057
3058
+ free_xid(xid);
27013059 return rc;
27023060 }
27033061
....@@ -2707,8 +3065,7 @@
27073065 struct cifs_tcon *tcon;
27083066 struct cifs_sb_info *cifs_sb;
27093067 struct dentry *dentry = ctx->cfile->dentry;
2710
- unsigned int i;
2711
- int rc;
3068
+ ssize_t rc;
27123069
27133070 tcon = tlink_tcon(ctx->cfile->tlink);
27143071 cifs_sb = CIFS_SB(dentry->d_sb);
....@@ -2747,27 +3104,29 @@
27473104 INIT_LIST_HEAD(&tmp_list);
27483105 list_del_init(&wdata->list);
27493106
2750
- iov_iter_advance(&tmp_from,
3107
+ if (ctx->direct_io)
3108
+ rc = cifs_resend_wdata(
3109
+ wdata, &tmp_list, ctx);
3110
+ else {
3111
+ iov_iter_advance(&tmp_from,
27513112 wdata->offset - ctx->pos);
27523113
2753
- rc = cifs_write_from_iter(wdata->offset,
3114
+ rc = cifs_write_from_iter(wdata->offset,
27543115 wdata->bytes, &tmp_from,
27553116 ctx->cfile, cifs_sb, &tmp_list,
27563117 ctx);
27573118
2758
- list_splice(&tmp_list, &ctx->list);
3119
+ kref_put(&wdata->refcount,
3120
+ cifs_uncached_writedata_release);
3121
+ }
27593122
2760
- kref_put(&wdata->refcount,
2761
- cifs_uncached_writedata_release);
3123
+ list_splice(&tmp_list, &ctx->list);
27623124 goto restart_loop;
27633125 }
27643126 }
27653127 list_del_init(&wdata->list);
27663128 kref_put(&wdata->refcount, cifs_uncached_writedata_release);
27673129 }
2768
-
2769
- for (i = 0; i < ctx->npages; i++)
2770
- put_page(ctx->bv[i].bv_page);
27713130
27723131 cifs_stats_bytes_written(tcon, ctx->total_len);
27733132 set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(dentry->d_inode)->flags);
....@@ -2782,7 +3141,8 @@
27823141 complete(&ctx->done);
27833142 }
27843143
2785
-ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
3144
+static ssize_t __cifs_writev(
3145
+ struct kiocb *iocb, struct iov_iter *from, bool direct)
27863146 {
27873147 struct file *file = iocb->ki_filp;
27883148 ssize_t total_written = 0;
....@@ -2791,13 +3151,18 @@
27913151 struct cifs_sb_info *cifs_sb;
27923152 struct cifs_aio_ctx *ctx;
27933153 struct iov_iter saved_from = *from;
3154
+ size_t len = iov_iter_count(from);
27943155 int rc;
27953156
27963157 /*
2797
- * BB - optimize the way when signing is disabled. We can drop this
2798
- * extra memory-to-memory copying and use iovec buffers for constructing
2799
- * write request.
3158
+ * iov_iter_get_pages_alloc doesn't work with ITER_KVEC.
3159
+ * In this case, fall back to non-direct write function.
3160
+ * this could be improved by getting pages directly in ITER_KVEC
28003161 */
3162
+ if (direct && iov_iter_is_kvec(from)) {
3163
+ cifs_dbg(FYI, "use non-direct cifs_writev for kvec I/O\n");
3164
+ direct = false;
3165
+ }
28013166
28023167 rc = generic_write_checks(iocb, from);
28033168 if (rc <= 0)
....@@ -2821,10 +3186,16 @@
28213186
28223187 ctx->pos = iocb->ki_pos;
28233188
2824
- rc = setup_aio_ctx_iter(ctx, from, WRITE);
2825
- if (rc) {
2826
- kref_put(&ctx->refcount, cifs_aio_ctx_release);
2827
- return rc;
3189
+ if (direct) {
3190
+ ctx->direct_io = true;
3191
+ ctx->iter = *from;
3192
+ ctx->len = len;
3193
+ } else {
3194
+ rc = setup_aio_ctx_iter(ctx, from, WRITE);
3195
+ if (rc) {
3196
+ kref_put(&ctx->refcount, cifs_aio_ctx_release);
3197
+ return rc;
3198
+ }
28283199 }
28293200
28303201 /* grab a lock here due to read response handlers can access ctx */
....@@ -2874,6 +3245,19 @@
28743245 return total_written;
28753246 }
28763247
3248
+ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from)
3249
+{
3250
+ struct file *file = iocb->ki_filp;
3251
+
3252
+ cifs_revalidate_mapping(file->f_inode);
3253
+ return __cifs_writev(iocb, from, true);
3254
+}
3255
+
3256
+ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
3257
+{
3258
+ return __cifs_writev(iocb, from, false);
3259
+}
3260
+
28773261 static ssize_t
28783262 cifs_writev(struct kiocb *iocb, struct iov_iter *from)
28793263 {
....@@ -2896,8 +3280,8 @@
28963280 goto out;
28973281
28983282 if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
2899
- server->vals->exclusive_lock_type, NULL,
2900
- CIFS_WRITE_OP))
3283
+ server->vals->exclusive_lock_type, 0,
3284
+ NULL, CIFS_WRITE_OP))
29013285 rc = __generic_file_write_iter(iocb, from);
29023286 else
29033287 rc = -EACCES;
....@@ -3048,7 +3432,6 @@
30483432 kref_put(&rdata->ctx->refcount, cifs_aio_ctx_release);
30493433 for (i = 0; i < rdata->nr_pages; i++) {
30503434 put_page(rdata->pages[i]);
3051
- rdata->pages[i] = NULL;
30523435 }
30533436 cifs_readdata_release(refcount);
30543437 }
....@@ -3073,7 +3456,7 @@
30733456 size_t copy = min_t(size_t, remaining, PAGE_SIZE);
30743457 size_t written;
30753458
3076
- if (unlikely(iter->type & ITER_PIPE)) {
3459
+ if (unlikely(iov_iter_is_pipe(iter))) {
30773460 void *addr = kmap_atomic(page);
30783461
30793462 written = copy_to_iter(addr, copy, iter);
....@@ -3175,70 +3558,209 @@
31753558 return uncached_fill_pages(server, rdata, iter, iter->count);
31763559 }
31773560
3561
+static int cifs_resend_rdata(struct cifs_readdata *rdata,
3562
+ struct list_head *rdata_list,
3563
+ struct cifs_aio_ctx *ctx)
3564
+{
3565
+ unsigned int rsize;
3566
+ struct cifs_credits credits;
3567
+ int rc;
3568
+ struct TCP_Server_Info *server;
3569
+
3570
+ /* XXX: should we pick a new channel here? */
3571
+ server = rdata->server;
3572
+
3573
+ do {
3574
+ if (rdata->cfile->invalidHandle) {
3575
+ rc = cifs_reopen_file(rdata->cfile, true);
3576
+ if (rc == -EAGAIN)
3577
+ continue;
3578
+ else if (rc)
3579
+ break;
3580
+ }
3581
+
3582
+ /*
3583
+ * Wait for credits to resend this rdata.
3584
+ * Note: we are attempting to resend the whole rdata not in
3585
+ * segments
3586
+ */
3587
+ do {
3588
+ rc = server->ops->wait_mtu_credits(server, rdata->bytes,
3589
+ &rsize, &credits);
3590
+
3591
+ if (rc)
3592
+ goto fail;
3593
+
3594
+ if (rsize < rdata->bytes) {
3595
+ add_credits_and_wake_if(server, &credits, 0);
3596
+ msleep(1000);
3597
+ }
3598
+ } while (rsize < rdata->bytes);
3599
+ rdata->credits = credits;
3600
+
3601
+ rc = adjust_credits(server, &rdata->credits, rdata->bytes);
3602
+ if (!rc) {
3603
+ if (rdata->cfile->invalidHandle)
3604
+ rc = -EAGAIN;
3605
+ else {
3606
+#ifdef CONFIG_CIFS_SMB_DIRECT
3607
+ if (rdata->mr) {
3608
+ rdata->mr->need_invalidate = true;
3609
+ smbd_deregister_mr(rdata->mr);
3610
+ rdata->mr = NULL;
3611
+ }
3612
+#endif
3613
+ rc = server->ops->async_readv(rdata);
3614
+ }
3615
+ }
3616
+
3617
+ /* If the read was successfully sent, we are done */
3618
+ if (!rc) {
3619
+ /* Add to aio pending list */
3620
+ list_add_tail(&rdata->list, rdata_list);
3621
+ return 0;
3622
+ }
3623
+
3624
+ /* Roll back credits and retry if needed */
3625
+ add_credits_and_wake_if(server, &rdata->credits, 0);
3626
+ } while (rc == -EAGAIN);
3627
+
3628
+fail:
3629
+ kref_put(&rdata->refcount, cifs_uncached_readdata_release);
3630
+ return rc;
3631
+}
3632
+
31783633 static int
31793634 cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
31803635 struct cifs_sb_info *cifs_sb, struct list_head *rdata_list,
31813636 struct cifs_aio_ctx *ctx)
31823637 {
31833638 struct cifs_readdata *rdata;
3184
- unsigned int npages, rsize, credits;
3639
+ unsigned int npages, rsize;
3640
+ struct cifs_credits credits_on_stack;
3641
+ struct cifs_credits *credits = &credits_on_stack;
31853642 size_t cur_len;
31863643 int rc;
31873644 pid_t pid;
31883645 struct TCP_Server_Info *server;
3646
+ struct page **pagevec;
3647
+ size_t start;
3648
+ struct iov_iter direct_iov = ctx->iter;
31893649
3190
- server = tlink_tcon(open_file->tlink)->ses->server;
3650
+ server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
31913651
31923652 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
31933653 pid = open_file->pid;
31943654 else
31953655 pid = current->tgid;
31963656
3657
+ if (ctx->direct_io)
3658
+ iov_iter_advance(&direct_iov, offset - ctx->pos);
3659
+
31973660 do {
3661
+ if (open_file->invalidHandle) {
3662
+ rc = cifs_reopen_file(open_file, true);
3663
+ if (rc == -EAGAIN)
3664
+ continue;
3665
+ else if (rc)
3666
+ break;
3667
+ }
3668
+
31983669 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
3199
- &rsize, &credits);
3670
+ &rsize, credits);
32003671 if (rc)
32013672 break;
32023673
32033674 cur_len = min_t(const size_t, len, rsize);
3204
- npages = DIV_ROUND_UP(cur_len, PAGE_SIZE);
32053675
3206
- /* allocate a readdata struct */
3207
- rdata = cifs_readdata_alloc(npages,
3676
+ if (ctx->direct_io) {
3677
+ ssize_t result;
3678
+
3679
+ result = iov_iter_get_pages_alloc(
3680
+ &direct_iov, &pagevec,
3681
+ cur_len, &start);
3682
+ if (result < 0) {
3683
+ cifs_dbg(VFS,
3684
+ "Couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n",
3685
+ result, iov_iter_type(&direct_iov),
3686
+ direct_iov.iov_offset,
3687
+ direct_iov.count);
3688
+ dump_stack();
3689
+
3690
+ rc = result;
3691
+ add_credits_and_wake_if(server, credits, 0);
3692
+ break;
3693
+ }
3694
+ cur_len = (size_t)result;
3695
+ iov_iter_advance(&direct_iov, cur_len);
3696
+
3697
+ rdata = cifs_readdata_direct_alloc(
3698
+ pagevec, cifs_uncached_readv_complete);
3699
+ if (!rdata) {
3700
+ add_credits_and_wake_if(server, credits, 0);
3701
+ rc = -ENOMEM;
3702
+ break;
3703
+ }
3704
+
3705
+ npages = (cur_len + start + PAGE_SIZE-1) / PAGE_SIZE;
3706
+ rdata->page_offset = start;
3707
+ rdata->tailsz = npages > 1 ?
3708
+ cur_len-(PAGE_SIZE-start)-(npages-2)*PAGE_SIZE :
3709
+ cur_len;
3710
+
3711
+ } else {
3712
+
3713
+ npages = DIV_ROUND_UP(cur_len, PAGE_SIZE);
3714
+ /* allocate a readdata struct */
3715
+ rdata = cifs_readdata_alloc(npages,
32083716 cifs_uncached_readv_complete);
3209
- if (!rdata) {
3210
- add_credits_and_wake_if(server, credits, 0);
3211
- rc = -ENOMEM;
3212
- break;
3717
+ if (!rdata) {
3718
+ add_credits_and_wake_if(server, credits, 0);
3719
+ rc = -ENOMEM;
3720
+ break;
3721
+ }
3722
+
3723
+ rc = cifs_read_allocate_pages(rdata, npages);
3724
+ if (rc) {
3725
+ kvfree(rdata->pages);
3726
+ kfree(rdata);
3727
+ add_credits_and_wake_if(server, credits, 0);
3728
+ break;
3729
+ }
3730
+
3731
+ rdata->tailsz = PAGE_SIZE;
32133732 }
32143733
3215
- rc = cifs_read_allocate_pages(rdata, npages);
3216
- if (rc)
3217
- goto error;
3218
-
3734
+ rdata->server = server;
32193735 rdata->cfile = cifsFileInfo_get(open_file);
32203736 rdata->nr_pages = npages;
32213737 rdata->offset = offset;
32223738 rdata->bytes = cur_len;
32233739 rdata->pid = pid;
32243740 rdata->pagesz = PAGE_SIZE;
3225
- rdata->tailsz = PAGE_SIZE;
32263741 rdata->read_into_pages = cifs_uncached_read_into_pages;
32273742 rdata->copy_into_pages = cifs_uncached_copy_into_pages;
3228
- rdata->credits = credits;
3743
+ rdata->credits = credits_on_stack;
32293744 rdata->ctx = ctx;
32303745 kref_get(&ctx->refcount);
32313746
3232
- if (!rdata->cfile->invalidHandle ||
3233
- !(rc = cifs_reopen_file(rdata->cfile, true)))
3234
- rc = server->ops->async_readv(rdata);
3235
-error:
3747
+ rc = adjust_credits(server, &rdata->credits, rdata->bytes);
3748
+
3749
+ if (!rc) {
3750
+ if (rdata->cfile->invalidHandle)
3751
+ rc = -EAGAIN;
3752
+ else
3753
+ rc = server->ops->async_readv(rdata);
3754
+ }
3755
+
32363756 if (rc) {
3237
- add_credits_and_wake_if(server, rdata->credits, 0);
3757
+ add_credits_and_wake_if(server, &rdata->credits, 0);
32383758 kref_put(&rdata->refcount,
3239
- cifs_uncached_readdata_release);
3240
- if (rc == -EAGAIN)
3759
+ cifs_uncached_readdata_release);
3760
+ if (rc == -EAGAIN) {
3761
+ iov_iter_revert(&direct_iov, cur_len);
32413762 continue;
3763
+ }
32423764 break;
32433765 }
32443766
....@@ -3256,11 +3778,8 @@
32563778 struct cifs_readdata *rdata, *tmp;
32573779 struct iov_iter *to = &ctx->iter;
32583780 struct cifs_sb_info *cifs_sb;
3259
- struct cifs_tcon *tcon;
3260
- unsigned int i;
32613781 int rc;
32623782
3263
- tcon = tlink_tcon(ctx->cfile->tlink);
32643783 cifs_sb = CIFS_SB(ctx->cfile->dentry->d_sb);
32653784
32663785 mutex_lock(&ctx->aio_mutex);
....@@ -3294,47 +3813,55 @@
32943813 * reading.
32953814 */
32963815 if (got_bytes && got_bytes < rdata->bytes) {
3297
- rc = cifs_readdata_to_iov(rdata, to);
3816
+ rc = 0;
3817
+ if (!ctx->direct_io)
3818
+ rc = cifs_readdata_to_iov(rdata, to);
32983819 if (rc) {
32993820 kref_put(&rdata->refcount,
3300
- cifs_uncached_readdata_release);
3821
+ cifs_uncached_readdata_release);
33013822 continue;
33023823 }
33033824 }
33043825
3305
- rc = cifs_send_async_read(
3826
+ if (ctx->direct_io) {
3827
+ /*
3828
+ * Re-use rdata as this is a
3829
+ * direct I/O
3830
+ */
3831
+ rc = cifs_resend_rdata(
3832
+ rdata,
3833
+ &tmp_list, ctx);
3834
+ } else {
3835
+ rc = cifs_send_async_read(
33063836 rdata->offset + got_bytes,
33073837 rdata->bytes - got_bytes,
33083838 rdata->cfile, cifs_sb,
33093839 &tmp_list, ctx);
33103840
3841
+ kref_put(&rdata->refcount,
3842
+ cifs_uncached_readdata_release);
3843
+ }
3844
+
33113845 list_splice(&tmp_list, &ctx->list);
33123846
3313
- kref_put(&rdata->refcount,
3314
- cifs_uncached_readdata_release);
33153847 goto again;
33163848 } else if (rdata->result)
33173849 rc = rdata->result;
3318
- else
3850
+ else if (!ctx->direct_io)
33193851 rc = cifs_readdata_to_iov(rdata, to);
33203852
33213853 /* if there was a short read -- discard anything left */
33223854 if (rdata->got_bytes && rdata->got_bytes < rdata->bytes)
33233855 rc = -ENODATA;
3856
+
3857
+ ctx->total_len += rdata->got_bytes;
33243858 }
33253859 list_del_init(&rdata->list);
33263860 kref_put(&rdata->refcount, cifs_uncached_readdata_release);
33273861 }
33283862
3329
- for (i = 0; i < ctx->npages; i++) {
3330
- if (ctx->should_dirty)
3331
- set_page_dirty(ctx->bv[i].bv_page);
3332
- put_page(ctx->bv[i].bv_page);
3333
- }
3334
-
3335
- ctx->total_len = ctx->len - iov_iter_count(to);
3336
-
3337
- cifs_stats_bytes_read(tcon, ctx->total_len);
3863
+ if (!ctx->direct_io)
3864
+ ctx->total_len = ctx->len - iov_iter_count(to);
33383865
33393866 /* mask nodata case */
33403867 if (rc == -ENODATA)
....@@ -3350,17 +3877,27 @@
33503877 complete(&ctx->done);
33513878 }
33523879
3353
-ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
3880
+static ssize_t __cifs_readv(
3881
+ struct kiocb *iocb, struct iov_iter *to, bool direct)
33543882 {
3355
- struct file *file = iocb->ki_filp;
3356
- ssize_t rc;
33573883 size_t len;
3358
- ssize_t total_read = 0;
3359
- loff_t offset = iocb->ki_pos;
3884
+ struct file *file = iocb->ki_filp;
33603885 struct cifs_sb_info *cifs_sb;
3361
- struct cifs_tcon *tcon;
33623886 struct cifsFileInfo *cfile;
3887
+ struct cifs_tcon *tcon;
3888
+ ssize_t rc, total_read = 0;
3889
+ loff_t offset = iocb->ki_pos;
33633890 struct cifs_aio_ctx *ctx;
3891
+
3892
+ /*
3893
+ * iov_iter_get_pages_alloc() doesn't work with ITER_KVEC,
3894
+ * fall back to data copy read path
3895
+ * this could be improved by getting pages directly in ITER_KVEC
3896
+ */
3897
+ if (direct && iov_iter_is_kvec(to)) {
3898
+ cifs_dbg(FYI, "use non-direct cifs_user_readv for kvec I/O\n");
3899
+ direct = false;
3900
+ }
33643901
33653902 len = iov_iter_count(to);
33663903 if (!len)
....@@ -3385,16 +3922,31 @@
33853922 if (!is_sync_kiocb(iocb))
33863923 ctx->iocb = iocb;
33873924
3388
- if (to->type == ITER_IOVEC)
3925
+ if (iter_is_iovec(to))
33893926 ctx->should_dirty = true;
33903927
3391
- rc = setup_aio_ctx_iter(ctx, to, READ);
3392
- if (rc) {
3393
- kref_put(&ctx->refcount, cifs_aio_ctx_release);
3394
- return rc;
3928
+ if (direct) {
3929
+ ctx->pos = offset;
3930
+ ctx->direct_io = true;
3931
+ ctx->iter = *to;
3932
+ ctx->len = len;
3933
+ } else {
3934
+ rc = setup_aio_ctx_iter(ctx, to, READ);
3935
+ if (rc) {
3936
+ kref_put(&ctx->refcount, cifs_aio_ctx_release);
3937
+ return rc;
3938
+ }
3939
+ len = ctx->len;
33953940 }
33963941
3397
- len = ctx->len;
3942
+ if (direct) {
3943
+ rc = filemap_write_and_wait_range(file->f_inode->i_mapping,
3944
+ offset, offset + len - 1);
3945
+ if (rc) {
3946
+ kref_put(&ctx->refcount, cifs_aio_ctx_release);
3947
+ return -EAGAIN;
3948
+ }
3949
+ }
33983950
33993951 /* grab a lock here due to read response handlers can access ctx */
34003952 mutex_lock(&ctx->aio_mutex);
....@@ -3437,6 +3989,16 @@
34373989 return rc;
34383990 }
34393991
3992
+ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to)
3993
+{
3994
+ return __cifs_readv(iocb, to, true);
3995
+}
3996
+
3997
+ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
3998
+{
3999
+ return __cifs_readv(iocb, to, false);
4000
+}
4001
+
34404002 ssize_t
34414003 cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
34424004 {
....@@ -3471,7 +4033,7 @@
34714033 down_read(&cinode->lock_sem);
34724034 if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(to),
34734035 tcon->ses->server->vals->shared_lock_type,
3474
- NULL, CIFS_READ_OP))
4036
+ 0, NULL, CIFS_READ_OP))
34754037 rc = generic_file_read_iter(iocb, to);
34764038 up_read(&cinode->lock_sem);
34774039 return rc;
....@@ -3491,7 +4053,7 @@
34914053 unsigned int xid;
34924054 char *cur_offset;
34934055 struct cifsFileInfo *open_file;
3494
- struct cifs_io_parms io_parms;
4056
+ struct cifs_io_parms io_parms = {0};
34954057 int buf_type = CIFS_NO_BUFFER;
34964058 __u32 pid;
34974059
....@@ -3508,7 +4070,7 @@
35084070 }
35094071 open_file = file->private_data;
35104072 tcon = tlink_tcon(open_file->tlink);
3511
- server = tcon->ses->server;
4073
+ server = cifs_pick_channel(tcon->ses);
35124074
35134075 if (!server->ops->sync_read) {
35144076 free_xid(xid);
....@@ -3547,6 +4109,7 @@
35474109 io_parms.tcon = tcon;
35484110 io_parms.offset = *offset;
35494111 io_parms.length = current_read_size;
4112
+ io_parms.server = server;
35504113 rc = server->ops->sync_read(xid, &open_file->fid, &io_parms,
35514114 &bytes_read, &cur_offset,
35524115 &buf_type);
....@@ -3635,7 +4198,7 @@
36354198 for (i = 0; i < rdata->nr_pages; i++) {
36364199 struct page *page = rdata->pages[i];
36374200
3638
- lru_cache_add_file(page);
4201
+ lru_cache_add(page);
36394202
36404203 if (rdata->result == 0 ||
36414204 (rdata->result == -EAGAIN && got_bytes)) {
....@@ -3705,7 +4268,7 @@
37054268 * fill them until the writes are flushed.
37064269 */
37074270 zero_user(page, 0, PAGE_SIZE);
3708
- lru_cache_add_file(page);
4271
+ lru_cache_add(page);
37094272 flush_dcache_page(page);
37104273 SetPageUptodate(page);
37114274 unlock_page(page);
....@@ -3715,7 +4278,7 @@
37154278 continue;
37164279 } else {
37174280 /* no need to hold page hostage */
3718
- lru_cache_add_file(page);
4281
+ lru_cache_add(page);
37194282 unlock_page(page);
37204283 put_page(page);
37214284 rdata->pages[i] = NULL;
....@@ -3770,7 +4333,7 @@
37704333
37714334 INIT_LIST_HEAD(tmplist);
37724335
3773
- page = list_entry(page_list->prev, struct page, lru);
4336
+ page = lru_to_page(page_list);
37744337
37754338 /*
37764339 * Lock the page and put it in the cache. Since no one else
....@@ -3828,7 +4391,9 @@
38284391 struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
38294392 struct TCP_Server_Info *server;
38304393 pid_t pid;
4394
+ unsigned int xid;
38314395
4396
+ xid = get_xid();
38324397 /*
38334398 * Reads as many pages as possible from fscache. Returns -ENOBUFS
38344399 * immediately if the cookie is negative
....@@ -3838,8 +4403,10 @@
38384403 */
38394404 rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
38404405 &num_pages);
3841
- if (rc == 0)
4406
+ if (rc == 0) {
4407
+ free_xid(xid);
38424408 return rc;
4409
+ }
38434410
38444411 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
38454412 pid = open_file->pid;
....@@ -3847,7 +4414,7 @@
38474414 pid = current->tgid;
38484415
38494416 rc = 0;
3850
- server = tlink_tcon(open_file->tlink)->ses->server;
4417
+ server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
38514418
38524419 cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n",
38534420 __func__, file, mapping, num_pages);
....@@ -3868,10 +4435,19 @@
38684435 loff_t offset;
38694436 struct page *page, *tpage;
38704437 struct cifs_readdata *rdata;
3871
- unsigned credits;
4438
+ struct cifs_credits credits_on_stack;
4439
+ struct cifs_credits *credits = &credits_on_stack;
4440
+
4441
+ if (open_file->invalidHandle) {
4442
+ rc = cifs_reopen_file(open_file, true);
4443
+ if (rc == -EAGAIN)
4444
+ continue;
4445
+ else if (rc)
4446
+ break;
4447
+ }
38724448
38734449 rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
3874
- &rsize, &credits);
4450
+ &rsize, credits);
38754451 if (rc)
38764452 break;
38774453
....@@ -3883,6 +4459,7 @@
38834459 */
38844460 if (unlikely(rsize < PAGE_SIZE)) {
38854461 add_credits_and_wake_if(server, credits, 0);
4462
+ free_xid(xid);
38864463 return 0;
38874464 }
38884465
....@@ -3899,7 +4476,7 @@
38994476 /* best to give up if we're out of mem */
39004477 list_for_each_entry_safe(page, tpage, &tmplist, lru) {
39014478 list_del(&page->lru);
3902
- lru_cache_add_file(page);
4479
+ lru_cache_add(page);
39034480 unlock_page(page);
39044481 put_page(page);
39054482 }
....@@ -3909,6 +4486,7 @@
39094486 }
39104487
39114488 rdata->cfile = cifsFileInfo_get(open_file);
4489
+ rdata->server = server;
39124490 rdata->mapping = mapping;
39134491 rdata->offset = offset;
39144492 rdata->bytes = bytes;
....@@ -3917,21 +4495,27 @@
39174495 rdata->tailsz = PAGE_SIZE;
39184496 rdata->read_into_pages = cifs_readpages_read_into_pages;
39194497 rdata->copy_into_pages = cifs_readpages_copy_into_pages;
3920
- rdata->credits = credits;
4498
+ rdata->credits = credits_on_stack;
39214499
39224500 list_for_each_entry_safe(page, tpage, &tmplist, lru) {
39234501 list_del(&page->lru);
39244502 rdata->pages[rdata->nr_pages++] = page;
39254503 }
39264504
3927
- if (!rdata->cfile->invalidHandle ||
3928
- !(rc = cifs_reopen_file(rdata->cfile, true)))
3929
- rc = server->ops->async_readv(rdata);
4505
+ rc = adjust_credits(server, &rdata->credits, rdata->bytes);
4506
+
4507
+ if (!rc) {
4508
+ if (rdata->cfile->invalidHandle)
4509
+ rc = -EAGAIN;
4510
+ else
4511
+ rc = server->ops->async_readv(rdata);
4512
+ }
4513
+
39304514 if (rc) {
3931
- add_credits_and_wake_if(server, rdata->credits, 0);
4515
+ add_credits_and_wake_if(server, &rdata->credits, 0);
39324516 for (i = 0; i < rdata->nr_pages; i++) {
39334517 page = rdata->pages[i];
3934
- lru_cache_add_file(page);
4518
+ lru_cache_add(page);
39354519 unlock_page(page);
39364520 put_page(page);
39374521 }
....@@ -3948,6 +4532,7 @@
39484532 * allocator.
39494533 */
39504534 cifs_fscache_readpages_cancel(mapping->host, page_list);
4535
+ free_xid(xid);
39514536 return rc;
39524537 }
39534538
....@@ -3975,8 +4560,12 @@
39754560 else
39764561 cifs_dbg(FYI, "Bytes read %d\n", rc);
39774562
3978
- file_inode(file)->i_atime =
3979
- current_time(file_inode(file));
4563
+ /* we do not want atime to be less than mtime, it broke some apps */
4564
+ file_inode(file)->i_atime = current_time(file_inode(file));
4565
+ if (timespec64_compare(&(file_inode(file)->i_atime), &(file_inode(file)->i_mtime)))
4566
+ file_inode(file)->i_atime = file_inode(file)->i_mtime;
4567
+ else
4568
+ file_inode(file)->i_atime = current_time(file_inode(file));
39804569
39814570 if (PAGE_SIZE > rc)
39824571 memset(read_data + rc, 0, PAGE_SIZE - rc);
....@@ -3999,7 +4588,7 @@
39994588
40004589 static int cifs_readpage(struct file *file, struct page *page)
40014590 {
4002
- loff_t offset = (loff_t)page->index << PAGE_SHIFT;
4591
+ loff_t offset = page_file_offset(page);
40034592 int rc = -EACCES;
40044593 unsigned int xid;
40054594
....@@ -4236,7 +4825,7 @@
42364825 cinode);
42374826 cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
42384827 }
4239
- _cifsFileInfo_put(cfile, false /* do not wait for ourself */);
4828
+ _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
42404829 cifs_done_oplock_break(cinode);
42414830 }
42424831
....@@ -4259,6 +4848,60 @@
42594848 return -EINVAL;
42604849 }
42614850
4851
+static int cifs_swap_activate(struct swap_info_struct *sis,
4852
+ struct file *swap_file, sector_t *span)
4853
+{
4854
+ struct cifsFileInfo *cfile = swap_file->private_data;
4855
+ struct inode *inode = swap_file->f_mapping->host;
4856
+ unsigned long blocks;
4857
+ long long isize;
4858
+
4859
+ cifs_dbg(FYI, "swap activate\n");
4860
+
4861
+ spin_lock(&inode->i_lock);
4862
+ blocks = inode->i_blocks;
4863
+ isize = inode->i_size;
4864
+ spin_unlock(&inode->i_lock);
4865
+ if (blocks*512 < isize) {
4866
+ pr_warn("swap activate: swapfile has holes\n");
4867
+ return -EINVAL;
4868
+ }
4869
+ *span = sis->pages;
4870
+
4871
+ pr_warn_once("Swap support over SMB3 is experimental\n");
4872
+
4873
+ /*
4874
+ * TODO: consider adding ACL (or documenting how) to prevent other
4875
+ * users (on this or other systems) from reading it
4876
+ */
4877
+
4878
+
4879
+ /* TODO: add sk_set_memalloc(inet) or similar */
4880
+
4881
+ if (cfile)
4882
+ cfile->swapfile = true;
4883
+ /*
4884
+ * TODO: Since file already open, we can't open with DENY_ALL here
4885
+ * but we could add call to grab a byte range lock to prevent others
4886
+ * from reading or writing the file
4887
+ */
4888
+
4889
+ return 0;
4890
+}
4891
+
4892
+static void cifs_swap_deactivate(struct file *file)
4893
+{
4894
+ struct cifsFileInfo *cfile = file->private_data;
4895
+
4896
+ cifs_dbg(FYI, "swap deactivate\n");
4897
+
4898
+ /* TODO: undo sk_set_memalloc(inet) will eventually be needed */
4899
+
4900
+ if (cfile)
4901
+ cfile->swapfile = false;
4902
+
4903
+ /* do we need to unpin (or unlock) the file */
4904
+}
42624905
42634906 const struct address_space_operations cifs_addr_ops = {
42644907 .readpage = cifs_readpage,
....@@ -4272,6 +4915,13 @@
42724915 .direct_IO = cifs_direct_io,
42734916 .invalidatepage = cifs_invalidate_page,
42744917 .launder_page = cifs_launder_page,
4918
+ /*
4919
+ * TODO: investigate and if useful we could add an cifs_migratePage
4920
+ * helper (under an CONFIG_MIGRATION) in the future, and also
4921
+ * investigate and add an is_dirty_writeback helper if needed
4922
+ */
4923
+ .swap_activate = cifs_swap_activate,
4924
+ .swap_deactivate = cifs_swap_deactivate,
42754925 };
42764926
42774927 /*