patch-2.1.56 linux/fs/smbfs/file.c
Next file: linux/fs/smbfs/inode.c
Previous file: linux/fs/smbfs/dir.c
Back to the patch index
Back to the overall index
- Lines: 238
- Date:
Sun Sep 14 15:14:56 1997
- Orig file:
v2.1.55/linux/fs/smbfs/file.c
- Orig date:
Wed Sep 3 20:52:43 1997
diff -u --recursive --new-file v2.1.55/linux/fs/smbfs/file.c linux/fs/smbfs/file.c
@@ -19,6 +19,10 @@
#include <asm/uaccess.h>
#include <asm/system.h>
+#define SMBFS_PARANOIA 1
+/* #define SMBFS_DEBUG_VERBOSE 1 */
+/* #define pr_debug printk */
+
static inline int
min(int a, int b)
{
@@ -26,8 +30,10 @@
}
static int
-smb_fsync(struct inode *inode, struct file *file)
+smb_fsync(struct file *file, struct dentry * dentry)
{
+ printk("smb_fsync: sync file %s/%s\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name);
return 0;
}
@@ -39,6 +45,7 @@
{
unsigned long offset = page->offset;
char *buffer = (char *) page_address(page);
+ struct dentry * dentry = inode->u.smbfs_i.dentry;
int rsize = SMB_SERVER(inode)->opt.max_xmit - (SMB_HEADER_LEN+15);
int result, refresh = 0;
int count = PAGE_SIZE;
@@ -46,14 +53,26 @@
pr_debug("SMB: smb_readpage_sync(%p)\n", page);
clear_bit(PG_error, &page->flags);
- result = smb_open(inode, O_RDONLY);
+ result = -EIO;
+ if (!dentry) {
+ printk("smb_readpage_sync: no dentry for inode %ld\n",
+ inode->i_ino);
+ goto io_error;
+ }
+
+ result = smb_open(dentry, O_RDONLY);
if (result < 0)
goto io_error;
+ /* Should revalidate inode ... */
do {
if (count < rsize)
rsize = count;
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_readpage: reading %s/%s, offset=%ld, buffer=%p, size=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, offset, buffer, rsize);
+#endif
result = smb_proc_read(inode, offset, rsize, buffer);
if (result < 0)
goto io_error;
@@ -81,15 +100,17 @@
int
smb_readpage(struct inode *inode, struct page *page)
{
- unsigned long address;
- int error = -1;
+ int error;
pr_debug("SMB: smb_readpage %08lx\n", page_address(page));
+#ifdef SMBFS_PARANOIA
+ if (test_bit(PG_locked, &page->flags))
+ printk("smb_readpage: page already locked!\n");
+#endif
set_bit(PG_locked, &page->flags);
- address = page_address(page);
atomic_inc(&page->count);
error = smb_readpage_sync(inode, page);
- free_page(address);
+ __free_page(page);
return error;
}
@@ -123,6 +144,11 @@
clear_bit(PG_uptodate, &page->flags);
goto io_error;
}
+ /* N.B. what if result < wsize?? */
+#ifdef SMBFS_PARANOIA
+if (result < wsize)
+printk("smb_writepage_sync: short write, wsize=%d, result=%d\n", wsize, result);
+#endif
refresh = 1;
buffer += wsize;
offset += wsize;
@@ -135,6 +161,7 @@
smb_refresh_inode(inode);
clear_bit(PG_locked, &page->flags);
+ wake_up(&page->wait);
return written ? written : result;
}
@@ -145,7 +172,17 @@
static int
smb_writepage(struct inode *inode, struct page *page)
{
- return smb_writepage_sync(inode, page, 0, PAGE_SIZE);
+ int result;
+
+#ifdef SMBFS_PARANOIA
+ if (test_bit(PG_locked, &page->flags))
+ printk("smb_writepage: page already locked!\n");
+#endif
+ set_bit(PG_locked, &page->flags);
+ atomic_inc(&page->count);
+ result = smb_writepage_sync(inode, page, 0, PAGE_SIZE);
+ __free_page(page);
+ return result;
}
static int
@@ -153,15 +190,35 @@
unsigned long offset, unsigned int count, int sync)
{
u8 *page_addr;
+ int result;
pr_debug("SMB: smb_updatepage(%x/%ld %d@%ld, sync=%d)\n",
inode->i_dev, inode->i_ino,
count, page->offset+offset, sync);
+#ifdef SMBFS_PARANOIA
+ if (test_bit(PG_locked, &page->flags))
+ printk("smb_updatepage: page already locked!\n");
+#endif
+ set_bit(PG_locked, &page->flags);
+ atomic_inc(&page->count);
+
page_addr = (u8 *) page_address(page);
- copy_from_user(page_addr + offset, buffer, count);
- return smb_writepage_sync(inode, page, offset, count);
+ if (copy_from_user(page_addr + offset, buffer, count))
+ goto bad_fault;
+ result = smb_writepage_sync(inode, page, offset, count);
+out:
+ __free_page(page);
+ return result;
+
+bad_fault:
+ printk("smb_updatepage: fault at page=%p buffer=%p\n", page, buffer);
+ result = -EFAULT;
+ clear_bit(PG_uptodate, &page->flags);
+ clear_bit(PG_locked, &page->flags);
+ wake_up(&page->wait);
+ goto out;
}
static long
@@ -175,23 +232,26 @@
count, (unsigned long) file->f_pos);
status = smb_revalidate_inode(inode);
- if (status < 0)
- return status;
-
- return generic_file_read(inode, file, buf, count);
+ if (status >= 0)
+ {
+ status = generic_file_read(inode, file, buf, count);
+ }
+ return status;
}
static int
-smb_file_mmap(struct inode * inode, struct file * file,
- struct vm_area_struct * vma)
+smb_file_mmap(struct file * file, struct vm_area_struct * vma)
{
+ struct dentry * dentry = file->f_dentry;
+ struct inode * inode = dentry->d_inode;
int status;
status = smb_revalidate_inode(inode);
- if (status < 0)
- return status;
-
- return generic_file_mmap(inode, file, vma);
+ if (status >= 0)
+ {
+ status = generic_file_mmap(file, vma);
+ }
+ return status;
}
/*
@@ -207,28 +267,34 @@
inode->i_dev, inode->i_ino, inode->i_count,
count, (unsigned long) file->f_pos);
+ result = -EINVAL;
if (!inode) {
printk("smb_file_write: inode = NULL\n");
- return -EINVAL;
+ goto out;
}
result = smb_revalidate_inode(inode);
if (result < 0)
- return result;
+ goto out;
- result = smb_open(inode, O_WRONLY);
+ result = smb_open(file->f_dentry, O_WRONLY);
if (result < 0)
- return result;
+ goto out;
+ result = -EINVAL;
if (!S_ISREG(inode->i_mode)) {
printk("smb_file_write: write to non-file, mode %07o\n",
inode->i_mode);
- return -EINVAL;
+ goto out;
}
- if (count <= 0)
- return 0;
- return generic_file_write(inode, file, buf, count);
+ result = 0;
+ if (count > 0)
+ {
+ result = generic_file_write(inode, file, buf, count);
+ }
+out:
+ return result;
}
static struct file_operations smb_file_operations =
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov