aboutsummaryrefslogtreecommitdiff
path: root/fs/smbfs/file.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-10-04 22:55:57 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-05 09:08:21 -0700
commit2116b7a473bf1c8d26998b477c294e7fe294921f (patch)
tree5f06aca6b425916f763d83fa4516bca51c8f9a60 /fs/smbfs/file.c
parent5af74aa5e97fcc0cc3955bc2a7ff6f3a13fa41cb (diff)
smbfs: move to drivers/staging
smbfs has been scheduled for removal in 2.6.27, so maybe we can now move it to drivers/staging on the way out. smbfs still uses the big kernel lock and nobody is going to fix that, so we should be getting rid of it soon. This removes the 32 bit compat mount and ioctl handling code, which is implemented in common fs code, and moves all smbfs related files into drivers/staging/smbfs. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/smbfs/file.c')
-rw-r--r--fs/smbfs/file.c454
1 files changed, 0 insertions, 454 deletions
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
deleted file mode 100644
index 8e187a0f94b..00000000000
--- a/fs/smbfs/file.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * file.c
- *
- * Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke
- * Copyright (C) 1997 by Volker Lendecke
- *
- * Please add a note about your changes to smbfs in the ChangeLog file.
- */
-
-#include <linux/time.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
-#include <linux/net.h>
-#include <linux/aio.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/smbno.h>
-#include <linux/smb_fs.h>
-
-#include "smb_debug.h"
-#include "proto.h"
-
-static int
-smb_fsync(struct file *file, int datasync)
-{
- struct dentry *dentry = file->f_path.dentry;
- struct smb_sb_info *server = server_from_dentry(dentry);
- int result;
-
- VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry));
-
- /*
- * The VFS will writepage() all dirty pages for us, but we
- * should send a SMBflush to the server, letting it know that
- * we want things synchronized with actual storage.
- *
- * Note: this function requires all pages to have been written already
- * (should be ok with writepage_sync)
- */
- result = smb_proc_flush(server, SMB_I(dentry->d_inode)->fileid);
- return result;
-}
-
-/*
- * Read a page synchronously.
- */
-static int
-smb_readpage_sync(struct dentry *dentry, struct page *page)
-{
- char *buffer = kmap(page);
- loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
- struct smb_sb_info *server = server_from_dentry(dentry);
- unsigned int rsize = smb_get_rsize(server);
- int count = PAGE_SIZE;
- int result;
-
- VERBOSE("file %s/%s, count=%d@%Ld, rsize=%d\n",
- DENTRY_PATH(dentry), count, offset, rsize);
-
- result = smb_open(dentry, SMB_O_RDONLY);
- if (result < 0)
- goto io_error;
-
- do {
- if (count < rsize)
- rsize = count;
-
- result = server->ops->read(dentry->d_inode,offset,rsize,buffer);
- if (result < 0)
- goto io_error;
-
- count -= result;
- offset += result;
- buffer += result;
- dentry->d_inode->i_atime =
- current_fs_time(dentry->d_inode->i_sb);
- if (result < rsize)
- break;
- } while (count);
-
- memset(buffer, 0, count);
- flush_dcache_page(page);
- SetPageUptodate(page);
- result = 0;
-
-io_error:
- kunmap(page);
- unlock_page(page);
- return result;
-}
-
-/*
- * We are called with the page locked and we unlock it when done.
- */
-static int
-smb_readpage(struct file *file, struct page *page)
-{
- int error;
- struct dentry *dentry = file->f_path.dentry;
-
- page_cache_get(page);
- error = smb_readpage_sync(dentry, page);
- page_cache_release(page);
- return error;
-}
-
-/*
- * Write a page synchronously.
- * Offset is the data offset within the page.
- */
-static int
-smb_writepage_sync(struct inode *inode, struct page *page,
- unsigned long pageoffset, unsigned int count)
-{
- loff_t offset;
- char *buffer = kmap(page) + pageoffset;
- struct smb_sb_info *server = server_from_inode(inode);
- unsigned int wsize = smb_get_wsize(server);
- int ret = 0;
-
- offset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageoffset;
- VERBOSE("file ino=%ld, fileid=%d, count=%d@%Ld, wsize=%d\n",
- inode->i_ino, SMB_I(inode)->fileid, count, offset, wsize);
-
- do {
- int write_ret;
-
- if (count < wsize)
- wsize = count;
-
- write_ret = server->ops->write(inode, offset, wsize, buffer);
- if (write_ret < 0) {
- PARANOIA("failed write, wsize=%d, write_ret=%d\n",
- wsize, write_ret);
- ret = write_ret;
- break;
- }
- /* N.B. what if result < wsize?? */
-#ifdef SMBFS_PARANOIA
- if (write_ret < wsize)
- PARANOIA("short write, wsize=%d, write_ret=%d\n",
- wsize, write_ret);
-#endif
- buffer += wsize;
- offset += wsize;
- count -= wsize;
- /*
- * Update the inode now rather than waiting for a refresh.
- */
- inode->i_mtime = inode->i_atime = current_fs_time(inode->i_sb);
- SMB_I(inode)->flags |= SMB_F_LOCALWRITE;
- if (offset > inode->i_size)
- inode->i_size = offset;
- } while (count);
-
- kunmap(page);
- return ret;
-}
-
-/*
- * Write a page to the server. This will be used for NFS swapping only
- * (for now), and we currently do this synchronously only.
- *
- * We are called with the page locked and we unlock it when done.
- */
-static int
-smb_writepage(struct page *page, struct writeback_control *wbc)
-{
- struct address_space *mapping = page->mapping;
- struct inode *inode;
- unsigned long end_index;
- unsigned offset = PAGE_CACHE_SIZE;
- int err;
-
- BUG_ON(!mapping);
- inode = mapping->host;
- BUG_ON(!inode);
-
- end_index = inode->i_size >> PAGE_CACHE_SHIFT;
-
- /* easy case */
- if (page->index < end_index)
- goto do_it;
- /* things got complicated... */
- offset = inode->i_size & (PAGE_CACHE_SIZE-1);
- /* OK, are we completely out? */
- if (page->index >= end_index+1 || !offset)
- return 0; /* truncated - don't care */
-do_it:
- page_cache_get(page);
- err = smb_writepage_sync(inode, page, 0, offset);
- SetPageUptodate(page);
- unlock_page(page);
- page_cache_release(page);
- return err;
-}
-
-static int
-smb_updatepage(struct file *file, struct page *page, unsigned long offset,
- unsigned int count)
-{
- struct dentry *dentry = file->f_path.dentry;
-
- DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count,
- ((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset);
-
- return smb_writepage_sync(dentry->d_inode, page, offset, count);
-}
-
-static ssize_t
-smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- struct file * file = iocb->ki_filp;
- struct dentry * dentry = file->f_path.dentry;
- ssize_t status;
-
- VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry),
- (unsigned long) iocb->ki_left, (unsigned long) pos);
-
- status = smb_revalidate_inode(dentry);
- if (status) {
- PARANOIA("%s/%s validation failed, error=%Zd\n",
- DENTRY_PATH(dentry), status);
- goto out;
- }
-
- VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n",
- (long)dentry->d_inode->i_size,
- dentry->d_inode->i_flags, dentry->d_inode->i_atime.tv_sec);
-
- status = generic_file_aio_read(iocb, iov, nr_segs, pos);
-out:
- return status;
-}
-
-static int
-smb_file_mmap(struct file * file, struct vm_area_struct * vma)
-{
- struct dentry * dentry = file->f_path.dentry;
- int status;
-
- VERBOSE("file %s/%s, address %lu - %lu\n",
- DENTRY_PATH(dentry), vma->vm_start, vma->vm_end);
-
- status = smb_revalidate_inode(dentry);
- if (status) {
- PARANOIA("%s/%s validation failed, error=%d\n",
- DENTRY_PATH(dentry), status);
- goto out;
- }
- status = generic_file_mmap(file, vma);
-out:
- return status;
-}
-
-static ssize_t
-smb_file_splice_read(struct file *file, loff_t *ppos,
- struct pipe_inode_info *pipe, size_t count,
- unsigned int flags)
-{
- struct dentry *dentry = file->f_path.dentry;
- ssize_t status;
-
- VERBOSE("file %s/%s, pos=%Ld, count=%lu\n",
- DENTRY_PATH(dentry), *ppos, count);
-
- status = smb_revalidate_inode(dentry);
- if (status) {
- PARANOIA("%s/%s validation failed, error=%Zd\n",
- DENTRY_PATH(dentry), status);
- goto out;
- }
- status = generic_file_splice_read(file, ppos, pipe, count, flags);
-out:
- return status;
-}
-
-/*
- * This does the "real" work of the write. The generic routine has
- * allocated the page, locked it, done all the page alignment stuff
- * calculations etc. Now we should just copy the data from user
- * space and write it back to the real medium..
- *
- * If the writer ends up delaying the write, the writer needs to
- * increment the page use counts until he is done with the page.
- */
-static int smb_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
-{
- pgoff_t index = pos >> PAGE_CACHE_SHIFT;
- *pagep = grab_cache_page_write_begin(mapping, index, flags);
- if (!*pagep)
- return -ENOMEM;
- return 0;
-}
-
-static int smb_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
-{
- int status;
- unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
-
- lock_kernel();
- status = smb_updatepage(file, page, offset, copied);
- unlock_kernel();
-
- if (!status) {
- if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
- SetPageUptodate(page);
- status = copied;
- }
-
- unlock_page(page);
- page_cache_release(page);
-
- return status;
-}
-
-const struct address_space_operations smb_file_aops = {
- .readpage = smb_readpage,
- .writepage = smb_writepage,
- .write_begin = smb_write_begin,
- .write_end = smb_write_end,
-};
-
-/*
- * Write to a file (through the page cache).
- */
-static ssize_t
-smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- struct file * file = iocb->ki_filp;
- struct dentry * dentry = file->f_path.dentry;
- ssize_t result;
-
- VERBOSE("file %s/%s, count=%lu@%lu\n",
- DENTRY_PATH(dentry),
- (unsigned long) iocb->ki_left, (unsigned long) pos);
-
- result = smb_revalidate_inode(dentry);
- if (result) {
- PARANOIA("%s/%s validation failed, error=%Zd\n",
- DENTRY_PATH(dentry), result);
- goto out;
- }
-
- result = smb_open(dentry, SMB_O_WRONLY);
- if (result)
- goto out;
-
- if (iocb->ki_left > 0) {
- result = generic_file_aio_write(iocb, iov, nr_segs, pos);
- VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
- (long) file->f_pos, (long) dentry->d_inode->i_size,
- dentry->d_inode->i_mtime.tv_sec,
- dentry->d_inode->i_atime.tv_sec);
- }
-out:
- return result;
-}
-
-static int
-smb_file_open(struct inode *inode, struct file * file)
-{
- int result;
- struct dentry *dentry = file->f_path.dentry;
- int smb_mode = (file->f_mode & O_ACCMODE) - 1;
-
- lock_kernel();
- result = smb_open(dentry, smb_mode);
- if (result)
- goto out;
- SMB_I(inode)->openers++;
-out:
- unlock_kernel();
- return result;
-}
-
-static int
-smb_file_release(struct inode *inode, struct file * file)
-{
- lock_kernel();
- if (!--SMB_I(inode)->openers) {
- /* We must flush any dirty pages now as we won't be able to
- write anything after close. mmap can trigger this.
- "openers" should perhaps include mmap'ers ... */
- filemap_write_and_wait(inode->i_mapping);
- smb_close(inode);
- }
- unlock_kernel();
- return 0;
-}
-
-/*
- * Check whether the required access is compatible with
- * an inode's permission. SMB doesn't recognize superuser
- * privileges, so we need our own check for this.
- */
-static int
-smb_file_permission(struct inode *inode, int mask)
-{
- int mode = inode->i_mode;
- int error = 0;
-
- VERBOSE("mode=%x, mask=%x\n", mode, mask);
-
- /* Look at user permissions */
- mode >>= 6;
- if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC))
- error = -EACCES;
- return error;
-}
-
-static loff_t smb_remote_llseek(struct file *file, loff_t offset, int origin)
-{
- loff_t ret;
- lock_kernel();
- ret = generic_file_llseek_unlocked(file, offset, origin);
- unlock_kernel();
- return ret;
-}
-
-const struct file_operations smb_file_operations =
-{
- .llseek = smb_remote_llseek,
- .read = do_sync_read,
- .aio_read = smb_file_aio_read,
- .write = do_sync_write,
- .aio_write = smb_file_aio_write,
- .unlocked_ioctl = smb_ioctl,
- .mmap = smb_file_mmap,
- .open = smb_file_open,
- .release = smb_file_release,
- .fsync = smb_fsync,
- .splice_read = smb_file_splice_read,
-};
-
-const struct inode_operations smb_file_inode_operations =
-{
- .permission = smb_file_permission,
- .getattr = smb_getattr,
- .setattr = smb_notify_change,
-};