Merge tag 'ktest-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux-2.6-microblaze.git] / fs / cifs / file.c
index 75ddce8..6d00190 100644 (file)
@@ -44,6 +44,7 @@
 #include "cifs_fs_sb.h"
 #include "fscache.h"
 #include "smbdirect.h"
+#include "fs_context.h"
 
 static inline int cifs_convert_flags(unsigned int flags)
 {
@@ -243,6 +244,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
        if (rc)
                goto out;
 
+       /* TODO: Add support for calling posix query info but with passing in fid */
        if (tcon->unix_ext)
                rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
                                              xid);
@@ -415,6 +417,8 @@ static void cifsFileInfo_put_work(struct work_struct *work)
  * cifsFileInfo_put - release a reference of file priv data
  *
  * Always potentially wait for oplock handler. See _cifsFileInfo_put().
+ *
+ * @cifs_file: cifs/smb3 specific info (eg refcounts) for an open file
  */
 void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
 {
@@ -430,8 +434,11 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
  *
  * If @wait_for_oplock_handler is true and we are releasing the last
  * reference, wait for any running oplock break handler of the file
- * and cancel any pending one. If calling this function from the
- * oplock break handler, you need to pass false.
+ * and cancel any pending one.
+ *
+ * @cifs_file: cifs/smb3 specific info (eg refcounts) for an open file
+ * @wait_oplock_handler: must be false if called from oplock_break_handler
+ * @offload:   not offloaded on close and oplock breaks
  *
  */
 void _cifsFileInfo_put(struct cifsFileInfo *cifs_file,
@@ -565,7 +572,7 @@ int cifs_open(struct inode *inode, struct file *file)
                                le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                /* can not refresh inode info since size could be stale */
                rc = cifs_posix_open(full_path, &inode, inode->i_sb,
-                               cifs_sb->mnt_file_mode /* ignored */,
+                               cifs_sb->ctx->file_mode /* ignored */,
                                file->f_flags, &oplock, &fid.netfid, xid);
                if (rc == 0) {
                        cifs_dbg(FYI, "posix open succeeded\n");
@@ -734,7 +741,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
                                                ~(O_CREAT | O_EXCL | O_TRUNC);
 
                rc = cifs_posix_open(full_path, NULL, inode->i_sb,
-                                    cifs_sb->mnt_file_mode /* ignored */,
+                                    cifs_sb->ctx->file_mode /* ignored */,
                                     oflags, &oplock, &cfile->fid.netfid, xid);
                if (rc == 0) {
                        cifs_dbg(FYI, "posix reopen succeeded\n");
@@ -800,7 +807,9 @@ reopen_success:
                if (!is_interrupt_error(rc))
                        mapping_set_error(inode->i_mapping, rc);
 
-               if (tcon->unix_ext)
+               if (tcon->posix_extensions)
+                       rc = smb311_posix_get_inode_info(&inode, full_path, inode->i_sb, xid);
+               else if (tcon->unix_ext)
                        rc = cifs_get_inode_info_unix(&inode, full_path,
                                                      inode->i_sb, xid);
                else
@@ -857,7 +866,7 @@ cifs_reopen_persistent_handles(struct cifs_tcon *tcon)
 
        tcon->need_reopen_files = false;
 
-       cifs_dbg(FYI, "Reopen persistent handles");
+       cifs_dbg(FYI, "Reopen persistent handles\n");
        INIT_LIST_HEAD(&tmp_list);
 
        /* list all files open on tree connection, reopen resilient handles  */
@@ -1146,20 +1155,20 @@ cifs_posix_lock_test(struct file *file, struct file_lock *flock)
 
 /*
  * Set the byte-range lock (posix style). Returns:
- * 1) 0, if we set the lock and don't need to request to the server;
- * 2) 1, if we need to request to the server;
- * 3) <0, if the error occurs while setting the lock.
+ * 1) <0, if the error occurs while setting the lock;
+ * 2) 0, if we set the lock and don't need to request to the server;
+ * 3) FILE_LOCK_DEFERRED, if we will wait for some other file_lock;
+ * 4) FILE_LOCK_DEFERRED + 1, if we need to request to the server.
  */
 static int
 cifs_posix_lock_set(struct file *file, struct file_lock *flock)
 {
        struct cifsInodeInfo *cinode = CIFS_I(file_inode(file));
-       int rc = 1;
+       int rc = FILE_LOCK_DEFERRED + 1;
 
        if ((flock->fl_flags & FL_POSIX) == 0)
                return rc;
 
-try_again:
        cifs_down_write(&cinode->lock_sem);
        if (!cinode->can_cache_brlcks) {
                up_write(&cinode->lock_sem);
@@ -1168,13 +1177,6 @@ try_again:
 
        rc = posix_lock_file(file, flock, NULL);
        up_write(&cinode->lock_sem);
-       if (rc == FILE_LOCK_DEFERRED) {
-               rc = wait_event_interruptible(flock->fl_wait,
-                                       list_empty(&flock->fl_blocked_member));
-               if (!rc)
-                       goto try_again;
-               locks_delete_block(flock);
-       }
        return rc;
 }
 
@@ -1649,7 +1651,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
                int posix_lock_type;
 
                rc = cifs_posix_lock_set(file, flock);
-               if (!rc || rc < 0)
+               if (rc <= FILE_LOCK_DEFERRED)
                        return rc;
 
                if (type & server->vals->shared_lock_type)
@@ -1853,7 +1855,7 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data,
        unsigned int xid;
        struct dentry *dentry = open_file->dentry;
        struct cifsInodeInfo *cifsi = CIFS_I(d_inode(dentry));
-       struct cifs_io_parms io_parms;
+       struct cifs_io_parms io_parms = {0};
 
        cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n",
                 write_size, *offset, dentry);
@@ -2056,7 +2058,7 @@ find_writable_file(struct cifsInodeInfo *cifs_inode, int flags)
 
        rc = cifs_get_writable_file(cifs_inode, flags, &cfile);
        if (rc)
-               cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc);
+               cifs_dbg(FYI, "Couldn't find writable handle rc=%d\n", rc);
 
        return cfile;
 }
@@ -2292,8 +2294,6 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
                 struct address_space *mapping, struct writeback_control *wbc)
 {
        int rc;
-       struct TCP_Server_Info *server =
-                               tlink_tcon(wdata->cfile->tlink)->ses->server;
 
        wdata->sync_mode = wbc->sync_mode;
        wdata->nr_pages = nr_pages;
@@ -2305,14 +2305,15 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
        wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz;
        wdata->pid = wdata->cfile->pid;
 
-       rc = adjust_credits(server, &wdata->credits, wdata->bytes);
+       rc = adjust_credits(wdata->server, &wdata->credits, wdata->bytes);
        if (rc)
                return rc;
 
        if (wdata->cfile->invalidHandle)
                rc = -EAGAIN;
        else
-               rc = server->ops->async_writev(wdata, cifs_writedata_release);
+               rc = wdata->server->ops->async_writev(wdata,
+                                                     cifs_writedata_release);
 
        return rc;
 }
@@ -2335,7 +2336,7 @@ static int cifs_writepages(struct address_space *mapping,
         * If wsize is smaller than the page cache size, default to writing
         * one page at a time via cifs_writepage
         */
-       if (cifs_sb->wsize < PAGE_SIZE)
+       if (cifs_sb->ctx->wsize < PAGE_SIZE)
                return generic_writepages(mapping, wbc);
 
        xid = get_xid();
@@ -2349,7 +2350,8 @@ static int cifs_writepages(struct address_space *mapping,
                        range_whole = true;
                scanned = true;
        }
-       server = cifs_sb_master_tcon(cifs_sb)->ses->server;
+       server = cifs_pick_channel(cifs_sb_master_tcon(cifs_sb)->ses);
+
 retry:
        while (!done && index <= end) {
                unsigned int i, nr_pages, found_pages, wsize;
@@ -2367,7 +2369,7 @@ retry:
                if (rc)
                        get_file_rc = rc;
 
-               rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
+               rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize,
                                                   &wsize, credits);
                if (rc != 0) {
                        done = true;
@@ -2403,6 +2405,7 @@ retry:
 
                wdata->credits = credits_on_stack;
                wdata->cfile = cfile;
+               wdata->server = server;
                cfile = NULL;
 
                if (!wdata->cfile) {
@@ -2806,8 +2809,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
        unsigned int wsize;
        struct cifs_credits credits;
        int rc;
-       struct TCP_Server_Info *server =
-               tlink_tcon(wdata->cfile->tlink)->ses->server;
+       struct TCP_Server_Info *server = wdata->server;
 
        do {
                if (wdata->cfile->invalidHandle) {
@@ -2893,7 +2895,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
        else
                pid = current->tgid;
 
-       server = tlink_tcon(open_file->tlink)->ses->server;
+       server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
        xid = get_xid();
 
        do {
@@ -2909,7 +2911,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
                                break;
                }
 
-               rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
+               rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize,
                                                   &wsize, credits);
                if (rc)
                        break;
@@ -2923,11 +2925,9 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
                                from, &pagevec, cur_len, &start);
                        if (result < 0) {
                                cifs_dbg(VFS,
-                                       "direct_writev couldn't get user pages "
-                                       "(rc=%zd) iter type %d iov_offset %zd "
-                                       "count %zd\n",
-                                       result, iov_iter_type(from),
-                                       from->iov_offset, from->count);
+                                        "direct_writev couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n",
+                                        result, iov_iter_type(from),
+                                        from->iov_offset, from->count);
                                dump_stack();
 
                                rc = result;
@@ -2999,6 +2999,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
                wdata->nr_pages = nr_pages;
                wdata->offset = (__u64)offset;
                wdata->cfile = cifsFileInfo_get(open_file);
+               wdata->server = server;
                wdata->pid = pid;
                wdata->bytes = cur_len;
                wdata->pagesz = PAGE_SIZE;
@@ -3540,8 +3541,10 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
        unsigned int rsize;
        struct cifs_credits credits;
        int rc;
-       struct TCP_Server_Info *server =
-               tlink_tcon(rdata->cfile->tlink)->ses->server;
+       struct TCP_Server_Info *server;
+
+       /* XXX: should we pick a new channel here? */
+       server = rdata->server;
 
        do {
                if (rdata->cfile->invalidHandle) {
@@ -3620,7 +3623,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
        size_t start;
        struct iov_iter direct_iov = ctx->iter;
 
-       server = tlink_tcon(open_file->tlink)->ses->server;
+       server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
 
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
                pid = open_file->pid;
@@ -3639,7 +3642,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
                                break;
                }
 
-               rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
+               rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
                                                   &rsize, credits);
                if (rc)
                        break;
@@ -3654,12 +3657,10 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
                                        cur_len, &start);
                        if (result < 0) {
                                cifs_dbg(VFS,
-                                       "couldn't get user pages (rc=%zd)"
-                                       " iter type %d"
-                                       " iov_offset %zd count %zd\n",
-                                       result, iov_iter_type(&direct_iov),
-                                       direct_iov.iov_offset,
-                                       direct_iov.count);
+                                        "Couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n",
+                                        result, iov_iter_type(&direct_iov),
+                                        direct_iov.iov_offset,
+                                        direct_iov.count);
                                dump_stack();
 
                                rc = result;
@@ -3706,6 +3707,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
                        rdata->tailsz = PAGE_SIZE;
                }
 
+               rdata->server = server;
                rdata->cfile = cifsFileInfo_get(open_file);
                rdata->nr_pages = npages;
                rdata->offset = offset;
@@ -4018,7 +4020,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
        unsigned int xid;
        char *cur_offset;
        struct cifsFileInfo *open_file;
-       struct cifs_io_parms io_parms;
+       struct cifs_io_parms io_parms = {0};
        int buf_type = CIFS_NO_BUFFER;
        __u32 pid;
 
@@ -4026,7 +4028,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
        cifs_sb = CIFS_FILE_SB(file);
 
        /* FIXME: set up handlers for larger reads and/or convert to async */
-       rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
+       rsize = min_t(unsigned int, cifs_sb->ctx->rsize, CIFSMaxBufSize);
 
        if (file->private_data == NULL) {
                rc = -EBADF;
@@ -4035,7 +4037,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
        }
        open_file = file->private_data;
        tcon = tlink_tcon(open_file->tlink);
-       server = tcon->ses->server;
+       server = cifs_pick_channel(tcon->ses);
 
        if (!server->ops->sync_read) {
                free_xid(xid);
@@ -4074,6 +4076,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
                        io_parms.tcon = tcon;
                        io_parms.offset = *offset;
                        io_parms.length = current_read_size;
+                       io_parms.server = server;
                        rc = server->ops->sync_read(xid, &open_file->fid, &io_parms,
                                                    &bytes_read, &cur_offset,
                                                    &buf_type);
@@ -4162,7 +4165,7 @@ cifs_readv_complete(struct work_struct *work)
        for (i = 0; i < rdata->nr_pages; i++) {
                struct page *page = rdata->pages[i];
 
-               lru_cache_add_file(page);
+               lru_cache_add(page);
 
                if (rdata->result == 0 ||
                    (rdata->result == -EAGAIN && got_bytes)) {
@@ -4232,7 +4235,7 @@ readpages_fill_pages(struct TCP_Server_Info *server,
                         * fill them until the writes are flushed.
                         */
                        zero_user(page, 0, PAGE_SIZE);
-                       lru_cache_add_file(page);
+                       lru_cache_add(page);
                        flush_dcache_page(page);
                        SetPageUptodate(page);
                        unlock_page(page);
@@ -4242,7 +4245,7 @@ readpages_fill_pages(struct TCP_Server_Info *server,
                        continue;
                } else {
                        /* no need to hold page hostage */
-                       lru_cache_add_file(page);
+                       lru_cache_add(page);
                        unlock_page(page);
                        put_page(page);
                        rdata->pages[i] = NULL;
@@ -4332,7 +4335,8 @@ readpages_get_pages(struct address_space *mapping, struct list_head *page_list,
                        break;
 
                __SetPageLocked(page);
-               if (add_to_page_cache_locked(page, mapping, page->index, gfp)) {
+               rc = add_to_page_cache_locked(page, mapping, page->index, gfp);
+               if (rc) {
                        __ClearPageLocked(page);
                        break;
                }
@@ -4348,6 +4352,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        struct list_head *page_list, unsigned num_pages)
 {
        int rc;
+       int err = 0;
        struct list_head tmplist;
        struct cifsFileInfo *open_file = file->private_data;
        struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
@@ -4376,7 +4381,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                pid = current->tgid;
 
        rc = 0;
-       server = tlink_tcon(open_file->tlink)->ses->server;
+       server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
 
        cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n",
                 __func__, file, mapping, num_pages);
@@ -4392,7 +4397,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
         * the order of declining indexes. When we put the pages in
         * the rdata->pages, then we want them in increasing order.
         */
-       while (!list_empty(page_list)) {
+       while (!list_empty(page_list) && !err) {
                unsigned int i, nr_pages, bytes, rsize;
                loff_t offset;
                struct page *page, *tpage;
@@ -4408,7 +4413,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                                break;
                }
 
-               rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
+               rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
                                                   &rsize, credits);
                if (rc)
                        break;
@@ -4425,9 +4430,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                        return 0;
                }
 
-               rc = readpages_get_pages(mapping, page_list, rsize, &tmplist,
+               nr_pages = 0;
+               err = readpages_get_pages(mapping, page_list, rsize, &tmplist,
                                         &nr_pages, &offset, &bytes);
-               if (rc) {
+               if (!nr_pages) {
                        add_credits_and_wake_if(server, credits, 0);
                        break;
                }
@@ -4437,7 +4443,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                        /* best to give up if we're out of mem */
                        list_for_each_entry_safe(page, tpage, &tmplist, lru) {
                                list_del(&page->lru);
-                               lru_cache_add_file(page);
+                               lru_cache_add(page);
                                unlock_page(page);
                                put_page(page);
                        }
@@ -4447,6 +4453,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                }
 
                rdata->cfile = cifsFileInfo_get(open_file);
+               rdata->server = server;
                rdata->mapping = mapping;
                rdata->offset = offset;
                rdata->bytes = bytes;
@@ -4475,7 +4482,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                        add_credits_and_wake_if(server, &rdata->credits, 0);
                        for (i = 0; i < rdata->nr_pages; i++) {
                                page = rdata->pages[i];
-                               lru_cache_add_file(page);
+                               lru_cache_add(page);
                                unlock_page(page);
                                put_page(page);
                        }
@@ -4828,7 +4835,7 @@ static int cifs_swap_activate(struct swap_info_struct *sis,
        }
        *span = sis->pages;
 
-       printk_once(KERN_WARNING "Swap support over SMB3 is experimental\n");
+       pr_warn_once("Swap support over SMB3 is experimental\n");
 
        /*
         * TODO: consider adding ACL (or documenting how) to prevent other