[patch] smbfs misc fixes

From: Urban Widmark (urban@teststation.com)
Date: Tue Oct 02 2001 - 16:28:37 EST


Hello

Below are a few things I have collected during the summer but not taken
the time to split from the larger pile of "not-for-2.4" things. Just a few
small fixes.

Please include this in 2.4.11-pre3 or whatever the next -pre might be.

/Urban

diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/ChangeLog linux-2.4.11-pre2-smbfs/fs/smbfs/ChangeLog
--- linux-2.4.11-pre2-orig/fs/smbfs/ChangeLog Sun Aug 19 12:08:18 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/ChangeLog Tue Oct 2 23:22:37 2001
@@ -1,5 +1,30 @@
 ChangeLog for smbfs.
 
+2001-09-17 Urban Widmark <urban@teststation.com>
+
+ * proc.c: Use 4096 (was 512) as the blocksize for better write
+ performance (patch originally by Jan Kratochvil)
+ * proc.c: Skip disconnect smb, allows umount on unreachable servers.
+ * proc.c: Go back to the interruptible sleep as reconnects seem to
+ handle it now.
+ * *.c: use autogenerated and private proto.h
+
+2000-11-22 Igor Zhbanov <bsg@uniyar.ac.ru>
+
+ * proc.c: fixed date_unix2dos for dates earlier than 01/01/1980
+ and date_dos2unix for date==0 (from 2.2)
+
+2001-07-13 Rob Radez <rob@osinvestor.com>
+
+ * proc.c: make smb_errno return negative error values
+
+2001-07-09 Jochen Dolze <dolze@epcnet.de>
+
+ * inode.c: smb_statfs always returned success.
+ * proc.c, ioctl.c: Allow smbmount to signal failure to reconnect with
+ a NULL argument to SMB_IOC_NEWCONN (speeds up error detection).
+ * proc.c: Add some of the missing error codes to smb_errno
+
 2001-06-12 Urban Widmark <urban@teststation.com>
 
         * proc.c: replace the win95-flush fix with smb_seek, when needed.
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/Makefile linux-2.4.11-pre2-smbfs/fs/smbfs/Makefile
--- linux-2.4.11-pre2-orig/fs/smbfs/Makefile Thu Feb 22 20:52:03 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/Makefile Tue Oct 2 23:22:37 2001
@@ -23,3 +23,19 @@
 #EXTRA_CFLAGS += -Werror
 
 include $(TOPDIR)/Rules.make
+
+#
+# Maintainer rules
+#
+
+# getopt.c not included. It is intentionally separate
+SRC = proc.c dir.c cache.c sock.c inode.c file.c ioctl.c
+
+proto:
+ -rm -f proto.h
+ @echo > proto2.h "/*"
+ @echo >> proto2.h " * Autogenerated with cproto on: " `date`
+ @echo >> proto2.h " */"
+ @echo >> proto2.h ""
+ cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
+ mv proto2.h proto.h
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/cache.c linux-2.4.11-pre2-smbfs/fs/smbfs/cache.c
--- linux-2.4.11-pre2-orig/fs/smbfs/cache.c Sun Aug 19 12:08:00 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/cache.c Tue Oct 2 23:22:37 2001
@@ -20,6 +20,7 @@
 #include <asm/page.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 /*
  * Force the next attempt to use the cache to be a timeout.
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/dir.c linux-2.4.11-pre2-smbfs/fs/smbfs/dir.c
--- linux-2.4.11-pre2-orig/fs/smbfs/dir.c Sun Aug 19 12:08:13 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/dir.c Tue Oct 2 23:22:37 2001
@@ -18,6 +18,7 @@
 #include <linux/smbno.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 static int smb_readdir(struct file *, void *, filldir_t);
 static int smb_dir_open(struct inode *, struct file *);
@@ -452,8 +453,7 @@
         if (!inode)
                 goto out_no_inode;
 
- if (have_id)
- {
+ if (have_id) {
                 inode->u.smbfs_i.fileid = fileid;
                 inode->u.smbfs_i.access = SMB_O_RDWR;
                 inode->u.smbfs_i.open = server->generation;
@@ -465,8 +465,7 @@
 out_no_inode:
         error = -EACCES;
 out_close:
- if (have_id)
- {
+ if (have_id) {
                 PARANOIA("%s/%s failed, error=%d, closing %u\n",
                          DENTRY_PATH(dentry), error, fileid);
                 smb_close_fileid(dentry, fileid);
@@ -562,12 +561,10 @@
          */
         if (old_dentry->d_inode)
                 smb_close(old_dentry->d_inode);
- if (new_dentry->d_inode)
- {
+ if (new_dentry->d_inode) {
                 smb_close(new_dentry->d_inode);
                 error = smb_proc_unlink(new_dentry);
- if (error)
- {
+ if (error) {
                         VERBOSE("unlink %s/%s, error=%d\n",
                                 DENTRY_PATH(new_dentry), error);
                         goto out;
@@ -579,8 +576,7 @@
         smb_invalid_dir_cache(old_dir);
         smb_invalid_dir_cache(new_dir);
         error = smb_proc_mv(old_dentry, new_dentry);
- if (!error)
- {
+ if (!error) {
                 smb_renew_times(old_dentry);
                 smb_renew_times(new_dentry);
         }
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/file.c linux-2.4.11-pre2-smbfs/fs/smbfs/file.c
--- linux-2.4.11-pre2-orig/fs/smbfs/file.c Sun Aug 19 12:08:28 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/file.c Tue Oct 2 23:22:37 2001
@@ -24,6 +24,7 @@
 #include <linux/smb_fs.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 static int
 smb_fsync(struct file *file, struct dentry * dentry, int datasync)
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/inode.c linux-2.4.11-pre2-smbfs/fs/smbfs/inode.c
--- linux-2.4.11-pre2-orig/fs/smbfs/inode.c Tue Oct 2 23:19:39 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/inode.c Tue Oct 2 23:22:51 2001
@@ -32,6 +32,7 @@
 
 #include "smb_debug.h"
 #include "getopt.h"
+#include "proto.h"
 
 /* Always pick a default string */
 #ifdef CONFIG_SMB_NLS_REMOTE
@@ -259,7 +260,7 @@
 }
 
 /* FIXME: flags and has_arg could probably be merged. */
-struct option opts[] = {
+static struct option opts[] = {
         { "version", 1, 0, 'v' },
         { "win95", 0, SMB_MOUNT_WIN95, 1 },
         { "oldattr", 0, SMB_MOUNT_OLDATTR, 1 },
@@ -344,7 +345,6 @@
         struct smb_sb_info *server = &(sb->u.smbfs_sb);
 
         if (server->sock_file) {
- smb_proc_disconnect(server);
                 smb_dont_catch_keepalive(server);
                 fput(server->sock_file);
         }
@@ -353,23 +353,24 @@
                kill_proc(server->conn_pid, SIGTERM, 1);
 
         smb_kfree(server->mnt);
- smb_kfree(sb->u.smbfs_sb.temp_buf);
+ smb_kfree(server->temp_buf);
         if (server->packet)
                 smb_vfree(server->packet);
 
- if(sb->u.smbfs_sb.remote_nls) {
- unload_nls(sb->u.smbfs_sb.remote_nls);
- sb->u.smbfs_sb.remote_nls = NULL;
- }
- if(sb->u.smbfs_sb.local_nls) {
- unload_nls(sb->u.smbfs_sb.local_nls);
- sb->u.smbfs_sb.local_nls = NULL;
+ if (server->remote_nls) {
+ unload_nls(server->remote_nls);
+ server->remote_nls = NULL;
+ }
+ if (server->local_nls) {
+ unload_nls(server->local_nls);
+ server->local_nls = NULL;
         }
 }
 
 struct super_block *
 smb_read_super(struct super_block *sb, void *raw_data, int silent)
 {
+ struct smb_sb_info *server = &sb->u.smbfs_sb;
         struct smb_mount_data_kernel *mnt;
         struct smb_mount_data *oldmnt;
         struct inode *root_inode;
@@ -389,34 +390,34 @@
         sb->s_magic = SMB_SUPER_MAGIC;
         sb->s_op = &smb_sops;
 
- sb->u.smbfs_sb.mnt = NULL;
- sb->u.smbfs_sb.sock_file = NULL;
- init_MUTEX(&sb->u.smbfs_sb.sem);
- init_waitqueue_head(&sb->u.smbfs_sb.wait);
- sb->u.smbfs_sb.conn_pid = 0;
- sb->u.smbfs_sb.state = CONN_INVALID; /* no connection yet */
- sb->u.smbfs_sb.generation = 0;
- sb->u.smbfs_sb.packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE);
- sb->u.smbfs_sb.packet = smb_vmalloc(sb->u.smbfs_sb.packet_size);
- if (!sb->u.smbfs_sb.packet)
+ server->mnt = NULL;
+ server->sock_file = NULL;
+ init_MUTEX(&server->sem);
+ init_waitqueue_head(&server->wait);
+ server->conn_pid = 0;
+ server->state = CONN_INVALID; /* no connection yet */
+ server->generation = 0;
+ server->packet_size = smb_round_length(SMB_INITIAL_PACKET_SIZE);
+ server->packet = smb_vmalloc(server->packet_size);
+ if (!server->packet)
                 goto out_no_mem;
 
         /* Allocate the global temp buffer */
- sb->u.smbfs_sb.temp_buf = smb_kmalloc(2*SMB_MAXPATHLEN+20, GFP_KERNEL);
- if (!sb->u.smbfs_sb.temp_buf)
+ server->temp_buf = smb_kmalloc(2*SMB_MAXPATHLEN+20, GFP_KERNEL);
+ if (!server->temp_buf)
                 goto out_no_temp;
 
         /* Setup NLS stuff */
- sb->u.smbfs_sb.remote_nls = NULL;
- sb->u.smbfs_sb.local_nls = NULL;
- sb->u.smbfs_sb.name_buf = sb->u.smbfs_sb.temp_buf + SMB_MAXPATHLEN + 20;
+ server->remote_nls = NULL;
+ server->local_nls = NULL;
+ server->name_buf = server->temp_buf + SMB_MAXPATHLEN + 20;
 
         /* Allocate the mount data structure */
         /* FIXME: merge this with the other malloc and get a whole page? */
         mnt = smb_kmalloc(sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
         if (!mnt)
                 goto out_no_mount;
- sb->u.smbfs_sb.mnt = mnt;
+ server->mnt = mnt;
 
         memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
         strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
@@ -447,9 +448,7 @@
 
                 mnt->mounted_uid = current->uid;
         }
- smb_setcodepage(&sb->u.smbfs_sb, &mnt->codepage);
- if (!sb->u.smbfs_sb.convert)
- PARANOIA("convert funcptr was NULL!\n");
+ smb_setcodepage(server, &mnt->codepage);
 
         /*
          * Display the enabled options
@@ -463,7 +462,7 @@
         /*
          * Keep the super block locked while we get the root inode.
          */
- smb_init_root_dirent(&(sb->u.smbfs_sb), &root);
+ smb_init_root_dirent(server, &root);
         root_inode = smb_iget(sb, &root);
         if (!root_inode)
                 goto out_no_root;
@@ -478,13 +477,13 @@
 out_no_root:
         iput(root_inode);
 out_bad_option:
- smb_kfree(sb->u.smbfs_sb.mnt);
+ smb_kfree(server->mnt);
 out_no_mount:
- smb_kfree(sb->u.smbfs_sb.temp_buf);
+ smb_kfree(server->temp_buf);
 out_no_temp:
- smb_vfree(sb->u.smbfs_sb.packet);
+ smb_vfree(server->packet);
 out_no_mem:
- if (!sb->u.smbfs_sb.mnt)
+ if (!server->mnt)
                 printk(KERN_ERR "smb_read_super: allocation failure\n");
         goto out_fail;
 out_wrong_data:
@@ -499,11 +498,11 @@
 static int
 smb_statfs(struct super_block *sb, struct statfs *buf)
 {
- smb_proc_dskattr(sb, buf);
+ int result = smb_proc_dskattr(sb, buf);
 
         buf->f_type = SMB_SUPER_MAGIC;
         buf->f_namelen = SMB_MAXPATHLEN;
- return 0;
+ return result;
 }
 
 int
@@ -532,8 +531,7 @@
         if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask))
                 goto out;
 
- if ((attr->ia_valid & ATTR_SIZE) != 0)
- {
+ if ((attr->ia_valid & ATTR_SIZE) != 0) {
                 VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
                         DENTRY_PATH(dentry),
                         (long) inode->i_size, (long) attr->ia_size);
@@ -558,20 +556,17 @@
         smb_get_inode_attr(inode, &fattr);
 
         changed = 0;
- if ((attr->ia_valid & ATTR_MTIME) != 0)
- {
+ if ((attr->ia_valid & ATTR_MTIME) != 0) {
                 fattr.f_mtime = attr->ia_mtime;
                 changed = 1;
         }
- if ((attr->ia_valid & ATTR_ATIME) != 0)
- {
+ if ((attr->ia_valid & ATTR_ATIME) != 0) {
                 fattr.f_atime = attr->ia_atime;
                 /* Earlier protocols don't have an access time */
                 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
                         changed = 1;
         }
- if (changed)
- {
+ if (changed) {
                 error = smb_proc_settime(dentry, &fattr);
                 if (error)
                         goto out;
@@ -582,27 +577,22 @@
          * Check for mode changes ... we're extremely limited in
          * what can be set for SMB servers: just the read-only bit.
          */
- if ((attr->ia_valid & ATTR_MODE) != 0)
- {
+ if ((attr->ia_valid & ATTR_MODE) != 0) {
                 VERBOSE("%s/%s mode change, old=%x, new=%x\n",
                         DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode);
                 changed = 0;
- if (attr->ia_mode & S_IWUSR)
- {
- if (fattr.attr & aRONLY)
- {
+ if (attr->ia_mode & S_IWUSR) {
+ if (fattr.attr & aRONLY) {
                                 fattr.attr &= ~aRONLY;
                                 changed = 1;
                         }
                 } else {
- if (!(fattr.attr & aRONLY))
- {
+ if (!(fattr.attr & aRONLY)) {
                                 fattr.attr |= aRONLY;
                                 changed = 1;
                         }
                 }
- if (changed)
- {
+ if (changed) {
                         error = smb_proc_setattr(dentry, &fattr);
                         if (error)
                                 goto out;
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/ioctl.c linux-2.4.11-pre2-smbfs/fs/smbfs/ioctl.c
--- linux-2.4.11-pre2-orig/fs/smbfs/ioctl.c Sun Aug 19 12:08:13 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/ioctl.c Tue Oct 2 23:22:37 2001
@@ -19,6 +19,8 @@
 
 #include <asm/uaccess.h>
 
+#include "proto.h"
+
 int
 smb_ioctl(struct inode *inode, struct file *filp,
           unsigned int cmd, unsigned long arg)
@@ -37,9 +39,11 @@
                 break;
 
         case SMB_IOC_NEWCONN:
- /* require an argument == smb_conn_opt, else it is EINVAL */
- if (!arg)
+ /* arg is smb_conn_opt, or NULL if no connection was made */
+ if (!arg) {
+ result = smb_wakeup(server);
                         break;
+ }
 
                 result = -EFAULT;
                 if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/proc.c linux-2.4.11-pre2-smbfs/fs/smbfs/proc.c
--- linux-2.4.11-pre2-orig/fs/smbfs/proc.c Sun Aug 19 12:08:18 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/proc.c Tue Oct 2 23:22:37 2001
@@ -23,16 +23,18 @@
 #include <linux/smb_mount.h>
 
 #include <asm/string.h>
+#include <asm/div64.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 
 /* Features. Undefine if they cause problems, this should perhaps be a
    config option. */
 #define SMBFS_POSIX_UNLINK 1
 
-/* Allow smb_retry to be interrupted. Not sure of the benefit ... */
-/* #define SMB_RETRY_INTR */
+/* Allow smb_retry to be interrupted. */
+#define SMB_RETRY_INTR
 
 #define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN)
 #define SMB_CMD(packet) (*(packet+8))
@@ -43,6 +45,9 @@
 #define SMB_DIRINFO_SIZE 43
 #define SMB_STATUS_SIZE 21
 
+#define SMB_ST_BLKSIZE (PAGE_SIZE)
+#define SMB_ST_BLKSHIFT (PAGE_SHIFT)
+
 static int
 smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
                      struct smb_fattr *);
@@ -137,8 +142,7 @@
         return len;
 }
 
-static int setcodepage(struct smb_sb_info *server,
- struct nls_table **p, char *name)
+static int setcodepage(struct nls_table **p, char *name)
 {
         struct nls_table *nls;
 
@@ -160,16 +164,20 @@
 /* Handles all changes to codepage settings. */
 int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp)
 {
- int n;
+ int n = 0;
 
         smb_lock_server(server);
 
- n = setcodepage(server, &server->local_nls, cp->local_name);
+ /* Don't load any nls_* at all, if no remote is requested */
+ if (!*cp->remote_name)
+ goto out;
+
+ n = setcodepage(&server->local_nls, cp->local_name);
         if (n != 0)
                 goto out;
- n = setcodepage(server, &server->remote_nls, cp->remote_name);
+ n = setcodepage(&server->remote_nls, cp->remote_name);
         if (n != 0)
- setcodepage(server, &server->local_nls, NULL);
+ setcodepage(&server->local_nls, NULL);
 
 out:
         if (server->local_nls != NULL && server->remote_nls != NULL)
@@ -188,7 +196,7 @@
 /* */
 /*****************************************************************************/
 
-__u8 *
+static __u8 *
 smb_encode_smb_length(__u8 * p, __u32 len)
 {
         *p = 0;
@@ -308,7 +316,9 @@
         int month, year;
         time_t secs;
 
- month = ((date >> 5) & 15) - 1;
+ /* first subtract and mask after that... Otherwise, if
+ date == 0, bad things happen */
+ month = ((date >> 5) - 1) & 15;
         year = date >> 9;
         secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
             ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
@@ -327,6 +337,9 @@
         int day, year, nl_day, month;
 
         unix_date = utc2local(server, unix_date);
+ if (unix_date < 315532800)
+ unix_date = 315532800;
+
         *time = (unix_date % 60) / 2 +
                 (((unix_date / 60) % 60) << 5) +
                 (((unix_date / 3600) % 24) << 11);
@@ -350,57 +363,20 @@
 
 /* The following are taken from fs/ntfs/util.c */
 
+#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
+
 /*
  * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
  * into Unix UTC (based 1970-01-01, in seconds).
- *
- * This is very gross because
- * 1: We must do 64-bit division on a 32-bit machine
- * 2: We can't use libgcc for long long operations in the kernel
- * 3: Floating point math in the kernel would corrupt user data
  */
 static time_t
-smb_ntutc2unixutc(struct smb_sb_info *server, u64 ntutc)
+smb_ntutc2unixutc(u64 ntutc)
 {
- const unsigned int D = 10000000;
- unsigned int H = (unsigned int)(ntutc >> 32);
- unsigned int L = (unsigned int)ntutc;
- unsigned int numerator2;
- unsigned int lowseconds;
- unsigned int result;
-
- /*
- * It is best to subtract 0x019db1ded53e8000 first.
- * Then the 1601-based date becomes a 1970-based date.
- */
- if (L < (unsigned)0xd53e8000) H--;
- L -= (unsigned)0xd53e8000;
- H -= (unsigned)0x019db1de;
-
- /*
- * Now divide 64-bit numbers on a 32-bit machine :-)
- * With the subtraction already done, the result fits in 32 bits.
- * The numerator fits in 56 bits and the denominator fits
- * in 24 bits, so we can shift by 8 bits to make this work.
- */
-
- numerator2 = (H<<8) | (L>>24);
- result = (numerator2 / D); /* shifted 24 right!! */
- lowseconds = result << 24;
-
- numerator2 = ((numerator2-result*D)<<8) | ((L>>16)&0xff);
- result = (numerator2 / D); /* shifted 16 right!! */
- lowseconds |= result << 16;
-
- numerator2 = ((numerator2-result*D)<<8) | ((L>>8)&0xff);
- result = (numerator2 / D); /* shifted 8 right!! */
- lowseconds |= result << 8;
-
- numerator2 = ((numerator2-result*D)<<8) | (L&0xff);
- result = (numerator2 / D); /* not shifted */
- lowseconds |= result;
-
- return lowseconds;
+ /* FIXME: what about the timezone difference? */
+ /* Subtract the NTFS time offset, then convert to 1s intervals. */
+ u64 t = ntutc - NTFS_TIME_OFFSET;
+ do_div(t, 10000000);
+ return (time_t)t;
 }
 
 #if 0
@@ -409,7 +385,7 @@
 smb_unixutc2ntutc(struct smb_sb_info *server, time_t t)
 {
         /* Note: timezone conversion is probably wrong. */
- return ((utc2local(server, t) + (u64)(369*365+89)*24*3600) * 10000000);
+ return ((u64)utc2local(server, t)) * 10000000 + NTFS_TIME_OFFSET;
 }
 #endif
 
@@ -519,6 +495,9 @@
         return size;
 }
 
+/*
+ * Convert SMB error codes to -E... errno values.
+ */
 int
 smb_errno(struct smb_sb_info *server)
 {
@@ -529,110 +508,115 @@
         VERBOSE("errcls %d code %d from command 0x%x\n",
                 errcls, error, SMB_CMD(server->packet));
 
- if (errcls == ERRDOS)
- switch (error)
- {
+ if (errcls == ERRDOS) {
+ switch (error) {
                 case ERRbadfunc:
- return EINVAL;
+ return -EINVAL;
                 case ERRbadfile:
                 case ERRbadpath:
- return ENOENT;
+ return -ENOENT;
                 case ERRnofids:
- return EMFILE;
+ return -EMFILE;
                 case ERRnoaccess:
- return EACCES;
+ return -EACCES;
                 case ERRbadfid:
- return EBADF;
+ return -EBADF;
                 case ERRbadmcb:
- return EREMOTEIO;
+ return -EREMOTEIO;
                 case ERRnomem:
- return ENOMEM;
+ return -ENOMEM;
                 case ERRbadmem:
- return EFAULT;
+ return -EFAULT;
                 case ERRbadenv:
                 case ERRbadformat:
- return EREMOTEIO;
+ return -EREMOTEIO;
                 case ERRbadaccess:
- return EACCES;
+ return -EACCES;
                 case ERRbaddata:
- return E2BIG;
+ return -E2BIG;
                 case ERRbaddrive:
- return ENXIO;
+ return -ENXIO;
                 case ERRremcd:
- return EREMOTEIO;
+ return -EREMOTEIO;
                 case ERRdiffdevice:
- return EXDEV;
- case ERRnofiles: /* Why is this mapped to 0?? */
- return 0;
+ return -EXDEV;
+ case ERRnofiles:
+ return -ENOENT;
                 case ERRbadshare:
- return ETXTBSY;
+ return -ETXTBSY;
                 case ERRlock:
- return EDEADLK;
+ return -EDEADLK;
                 case ERRfilexists:
- return EEXIST;
- case 87: /* should this map to 0?? */
- return 0; /* Unknown error!! */
- case 123: /* Invalid name?? e.g. .tmp* */
- return ENOENT;
- case 145: /* Win NT 4.0: non-empty directory? */
- return ENOTEMPTY;
- /* This next error seems to occur on an mv when
- * the destination exists */
- case 183:
- return EEXIST;
+ return -EEXIST;
+ case ERRinvalidparam:
+ return -EINVAL;
+ case ERRdiskfull:
+ return -ENOSPC;
+ case ERRinvalidname:
+ return -ENOENT;
+ case ERRdirnotempty:
+ return -ENOTEMPTY;
+ case ERRnotlocked:
+ return -ENOLCK;
+ case ERRexists:
+ return -EEXIST;
                 default:
                         class = "ERRDOS";
                         goto err_unknown;
- } else if (errcls == ERRSRV)
- switch (error)
- {
+ }
+ } else if (errcls == ERRSRV) {
+ switch (error) {
                 /* N.B. This is wrong ... EIO ? */
                 case ERRerror:
- return ENFILE;
+ return -ENFILE;
                 case ERRbadpw:
- return EINVAL;
+ return -EINVAL;
                 case ERRbadtype:
- return EIO;
+ return -EIO;
                 case ERRaccess:
- return EACCES;
+ return -EACCES;
                 /*
                  * This is a fatal error, as it means the "tree ID"
                  * for this connection is no longer valid. We map
                  * to a special error code and get a new connection.
                  */
                 case ERRinvnid:
- return EBADSLT;
+ return -EBADSLT;
                 default:
                         class = "ERRSRV";
                         goto err_unknown;
- } else if (errcls == ERRHRD)
- switch (error)
- {
+ }
+ } else if (errcls == ERRHRD) {
+ switch (error) {
                 case ERRnowrite:
- return EROFS;
+ return -EROFS;
                 case ERRbadunit:
- return ENODEV;
+ return -ENODEV;
                 case ERRnotready:
- return EUCLEAN;
+ return -EUCLEAN;
                 case ERRbadcmd:
                 case ERRdata:
- return EIO;
+ return -EIO;
                 case ERRbadreq:
- return ERANGE;
+ return -ERANGE;
                 case ERRbadshare:
- return ETXTBSY;
+ return -ETXTBSY;
                 case ERRlock:
- return EDEADLK;
+ return -EDEADLK;
                 default:
                         class = "ERRHRD";
                         goto err_unknown;
- } else if (errcls == ERRCMD)
+ }
+ } else if (errcls == ERRCMD) {
                 class = "ERRCMD";
+ } else if (errcls == SUCCESS) {
+ return 0; /* This is the only valid 0 return */
+ }
 
 err_unknown:
         printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
                class, error, SMB_CMD(server->packet));
- return EIO;
+ return -EIO;
 }
 
 /*
@@ -749,12 +733,10 @@
         }
 
         /*
- * Check for server errors. The current smb_errno() routine
- * is squashing some error codes, but I don't think this is
- * correct: after a server error the packet won't be valid.
+ * Check for server errors.
          */
         if (s->rcls != 0) {
- result = -smb_errno(s);
+ result = smb_errno(s);
                 if (!result)
                         printk(KERN_DEBUG "smb_request_ok: rcls=%d, err=%d mapped to 0\n",
                                 s->rcls, s->err);
@@ -850,17 +832,23 @@
 
 out:
         smb_unlock_server(server);
+ smb_wakeup(server);
+ return error;
+
+out_putf:
+ fput(filp);
+ goto out;
+}
 
+int
+smb_wakeup(struct smb_sb_info *server)
+{
 #ifdef SMB_RETRY_INTR
         wake_up_interruptible(&server->wait);
 #else
         wake_up(&server->wait);
 #endif
- return error;
-
-out_putf:
- fput(filp);
- goto out;
+ return 0;
 }
 
 /* smb_setup_header: We completely set up the packet. You only have to
@@ -1490,7 +1478,7 @@
         fattr->f_nlink = 1;
         fattr->f_uid = server->mnt->uid;
         fattr->f_gid = server->mnt->gid;
- fattr->f_blksize = 512;
+ fattr->f_blksize = SMB_ST_BLKSIZE;
 }
 
 static void
@@ -1500,18 +1488,16 @@
         if (fattr->attr & aDIR)
         {
                 fattr->f_mode = server->mnt->dir_mode;
- fattr->f_size = 512;
+ fattr->f_size = SMB_ST_BLKSIZE;
         }
         /* Check the read-only flag */
         if (fattr->attr & aRONLY)
                 fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
 
+ /* How many 512 byte blocks do we need for this file? */
         fattr->f_blocks = 0;
- if ((fattr->f_blksize != 0) && (fattr->f_size != 0))
- {
- fattr->f_blocks =
- (fattr->f_size - 1) / fattr->f_blksize + 1;
- }
+ if (fattr->f_size != 0)
+ fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9);
         return;
 }
 
@@ -1770,9 +1756,9 @@
                 if (len && qname->name[len-1] == '\0')
                         len--;
 
- fattr->f_ctime = smb_ntutc2unixutc(server, LVAL(p, 8));
- fattr->f_atime = smb_ntutc2unixutc(server, LVAL(p, 16));
- fattr->f_mtime = smb_ntutc2unixutc(server, LVAL(p, 24));
+ fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8));
+ fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16));
+ fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24));
                 /* change time (32) */
                 fattr->f_size = DVAL(p, 40);
                 /* alloc size (48) */
@@ -1940,7 +1926,7 @@
                 }
 
                 if (server->rcls != 0) {
- result = -smb_errno(server);
+ result = smb_errno(server);
                         PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",
                                  mask, result, server->rcls, server->err);
                         break;
@@ -2104,7 +2090,7 @@
         }
         if (server->rcls != 0)
         {
- result = -smb_errno(server);
+ result = smb_errno(server);
 #ifdef SMBFS_PARANOIA
                 if (result != -ENOENT)
                         PARANOIA("error for %s, rcls=%d, err=%d\n",
@@ -2227,7 +2213,7 @@
         {
                 VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
                         &param[6], result, server->rcls, server->err);
- result = -smb_errno(server);
+ result = smb_errno(server);
                 goto out;
         }
         result = -ENOENT;
@@ -2490,7 +2476,7 @@
         }
         result = 0;
         if (server->rcls != 0)
- result = -smb_errno(server);
+ result = smb_errno(server);
 
 out:
         return result;
@@ -2559,6 +2545,7 @@
         struct smb_sb_info *server = &(sb->u.smbfs_sb);
         int result;
         char *p;
+ long unit;
 
         smb_lock_server(server);
 
@@ -2571,23 +2558,13 @@
                 goto out;
         }
         p = SMB_VWV(server->packet);
- attr->f_blocks = WVAL(p, 0);
- attr->f_bsize = WVAL(p, 2) * WVAL(p, 4);
- attr->f_bavail = attr->f_bfree = WVAL(p, 6);
+ unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT;
+ attr->f_blocks = WVAL(p, 0) * unit;
+ attr->f_bsize = SMB_ST_BLKSIZE;
+ attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit;
         result = 0;
 
 out:
- smb_unlock_server(server);
- return result;
-}
-
-int
-smb_proc_disconnect(struct smb_sb_info *server)
-{
- int result;
- smb_lock_server(server);
- smb_setup_header(server, SMBtdis, 0, 0);
- result = smb_request_ok(server, SMBtdis, 0, 0);
         smb_unlock_server(server);
         return result;
 }
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/proto.h linux-2.4.11-pre2-smbfs/fs/smbfs/proto.h
--- linux-2.4.11-pre2-orig/fs/smbfs/proto.h Thu Jan 1 01:00:00 1970
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/proto.h Tue Oct 2 23:22:37 2001
@@ -0,0 +1,63 @@
+/*
+ * Autogenerated with cproto on: Tue Oct 2 20:40:54 CEST 2001
+ */
+
+/* proc.c */
+extern int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp);
+extern __u32 smb_len(__u8 *p);
+extern int smb_get_rsize(struct smb_sb_info *server);
+extern int smb_get_wsize(struct smb_sb_info *server);
+extern int smb_errno(struct smb_sb_info *server);
+extern int smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt);
+extern int smb_wakeup(struct smb_sb_info *server);
+extern __u8 *smb_setup_header(struct smb_sb_info *server, __u8 command, __u16 wct, __u16 bcc);
+extern int smb_open(struct dentry *dentry, int wish);
+extern int smb_close(struct inode *ino);
+extern int smb_close_fileid(struct dentry *dentry, __u16 fileid);
+extern int smb_proc_read(struct inode *inode, off_t offset, int count, char *data);
+extern int smb_proc_write(struct inode *inode, off_t offset, int count, const char *data);
+extern int smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid);
+extern int smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry);
+extern int smb_proc_mkdir(struct dentry *dentry);
+extern int smb_proc_rmdir(struct dentry *dentry);
+extern int smb_proc_unlink(struct dentry *dentry);
+extern int smb_proc_flush(struct smb_sb_info *server, __u16 fileid);
+extern int smb_proc_trunc(struct smb_sb_info *server, __u16 fid, __u32 length);
+extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
+extern int smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir, struct smb_cache_control *ctl);
+extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
+extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
+extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr);
+extern int smb_proc_dskattr(struct super_block *sb, struct statfs *attr);
+/* dir.c */
+extern struct file_operations smb_dir_operations;
+extern struct inode_operations smb_dir_inode_operations;
+extern void smb_new_dentry(struct dentry *dentry);
+extern void smb_renew_times(struct dentry *dentry);
+/* cache.c */
+extern void smb_invalid_dir_cache(struct inode *dir);
+extern void smb_invalidate_dircache_entries(struct dentry *parent);
+extern struct dentry *smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos);
+extern int smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, struct smb_cache_control *ctrl, struct qstr *qname, struct smb_fattr *entry);
+/* sock.c */
+extern int smb_valid_socket(struct inode *inode);
+extern int smb_catch_keepalive(struct smb_sb_info *server);
+extern int smb_dont_catch_keepalive(struct smb_sb_info *server);
+extern void smb_close_socket(struct smb_sb_info *server);
+extern int smb_round_length(int len);
+extern int smb_request(struct smb_sb_info *server);
+extern int smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, int ldata, unsigned char *data, int lparam, unsigned char *param, int *lrdata, unsigned char **rdata, int *lrparam, unsigned char **rparam);
+/* inode.c */
+extern struct inode *smb_iget(struct super_block *sb, struct smb_fattr *fattr);
+extern void smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr);
+extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr);
+extern void smb_invalidate_inodes(struct smb_sb_info *server);
+extern int smb_revalidate_inode(struct dentry *dentry);
+extern struct super_block *smb_read_super(struct super_block *sb, void *raw_data, int silent);
+extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
+/* file.c */
+extern struct address_space_operations smb_file_aops;
+extern struct file_operations smb_file_operations;
+extern struct inode_operations smb_file_inode_operations;
+/* ioctl.c */
+extern int smb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
diff -urN -X exclude linux-2.4.11-pre2-orig/fs/smbfs/sock.c linux-2.4.11-pre2-smbfs/fs/smbfs/sock.c
--- linux-2.4.11-pre2-orig/fs/smbfs/sock.c Sun Aug 19 12:08:13 2001
+++ linux-2.4.11-pre2-smbfs/fs/smbfs/sock.c Tue Oct 2 23:22:37 2001
@@ -27,6 +27,7 @@
 #include <asm/uaccess.h>
 
 #include "smb_debug.h"
+#include "proto.h"
 
 
 static int
@@ -674,7 +675,7 @@
          */
         if (server->rcls) {
                 int error = smb_errno(server);
- if (error == EBADSLT) {
+ if (error == -EBADSLT) {
                         printk(KERN_ERR "smb_request: tree ID invalid\n");
                         result = error;
                         goto bad_conn;
@@ -866,7 +867,7 @@
          */
         if (server->rcls) {
                 int error = smb_errno(server);
- if (error == EBADSLT) {
+ if (error == -EBADSLT) {
                         printk(KERN_ERR "smb_request: tree ID invalid\n");
                         result = error;
                         goto bad_conn;
diff -urN -X exclude linux-2.4.11-pre2-orig/include/linux/smb_fs.h linux-2.4.11-pre2-smbfs/include/linux/smb_fs.h
--- linux-2.4.11-pre2-orig/include/linux/smb_fs.h Sun Sep 16 19:00:52 2001
+++ linux-2.4.11-pre2-smbfs/include/linux/smb_fs.h Tue Oct 2 23:22:37 2001
@@ -161,84 +161,6 @@
 }
 
 
-/* FIXME! the prototype list is probably not correct. Automate? */
-
-/* linux/fs/smbfs/file.c */
-extern struct inode_operations smb_file_inode_operations;
-extern struct file_operations smb_file_operations;
-extern struct address_space_operations smb_file_aops;
-
-/* linux/fs/smbfs/dir.c */
-extern struct inode_operations smb_dir_inode_operations;
-extern struct file_operations smb_dir_operations;
-void smb_new_dentry(struct dentry *dentry);
-void smb_renew_times(struct dentry *);
-
-/* linux/fs/smbfs/ioctl.c */
-int smb_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
-
-/* linux/fs/smbfs/inode.c */
-struct super_block *smb_read_super(struct super_block *, void *, int);
-void smb_get_inode_attr(struct inode *, struct smb_fattr *);
-void smb_set_inode_attr(struct inode *, struct smb_fattr *);
-void smb_invalidate_inodes(struct smb_sb_info *);
-int smb_revalidate_inode(struct dentry *);
-int smb_notify_change(struct dentry *, struct iattr *);
-struct inode *smb_iget(struct super_block *, struct smb_fattr *);
-
-/* linux/fs/smbfs/proc.c */
-int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp);
-__u32 smb_len(unsigned char *);
-__u8 *smb_setup_header(struct smb_sb_info *, __u8, __u16, __u16);
-int smb_get_rsize(struct smb_sb_info *);
-int smb_get_wsize(struct smb_sb_info *);
-int smb_newconn(struct smb_sb_info *, struct smb_conn_opt *);
-int smb_errno(struct smb_sb_info *);
-int smb_close(struct inode *);
-int smb_close_fileid(struct dentry *, __u16);
-int smb_open(struct dentry *, int);
-int smb_proc_read(struct inode *, off_t, int, char *);
-int smb_proc_write(struct inode *, off_t, int, const char *);
-int smb_proc_create(struct dentry *, __u16, time_t, __u16 *);
-int smb_proc_mv(struct dentry *, struct dentry *);
-int smb_proc_mkdir(struct dentry *);
-int smb_proc_rmdir(struct dentry *);
-int smb_proc_unlink(struct dentry *);
-int smb_proc_readdir(struct file *filp, void *dirent, filldir_t filldir,
- struct smb_cache_control *ctl);
-int smb_proc_getattr(struct dentry *, struct smb_fattr *);
-int smb_proc_setattr(struct dentry *, struct smb_fattr *);
-int smb_proc_settime(struct dentry *, struct smb_fattr *);
-int smb_proc_dskattr(struct super_block *, struct statfs *);
-int smb_proc_disconnect(struct smb_sb_info *);
-int smb_proc_trunc(struct smb_sb_info *, __u16, __u32);
-int smb_proc_flush(struct smb_sb_info *, __u16);
-void smb_init_root_dirent(struct smb_sb_info *, struct smb_fattr *);
-
-/* linux/fs/smbfs/sock.c */
-int smb_round_length(int);
-int smb_valid_socket(struct inode *);
-void smb_close_socket(struct smb_sb_info *);
-int smb_request(struct smb_sb_info *server);
-int smb_catch_keepalive(struct smb_sb_info *server);
-int smb_dont_catch_keepalive(struct smb_sb_info *server);
-int smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
- int ldata, unsigned char *data,
- int lparam, unsigned char *param,
- int *lrdata, unsigned char **rdata,
- int *lrparam, unsigned char **rparam);
-
-/* fs/smbfs/cache.c */
-
-void smb_invalid_dir_cache(struct inode * dir);
-void smb_invalidate_dircache_entries(struct dentry *parent);
-struct dentry * smb_dget_fpos(struct dentry *dentry, struct dentry *parent,
- unsigned long fpos);
-int smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
- struct smb_cache_control *ctrl, struct qstr *qname,
- struct smb_fattr *entry);
-
-
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SMB_FS_H */
diff -urN -X exclude linux-2.4.11-pre2-orig/include/linux/smbno.h linux-2.4.11-pre2-smbfs/include/linux/smbno.h
--- linux-2.4.11-pre2-orig/include/linux/smbno.h Mon Nov 24 19:30:40 1997
+++ linux-2.4.11-pre2-smbfs/include/linux/smbno.h Tue Oct 2 23:22:37 2001
@@ -39,7 +39,12 @@
 #define ERRbadshare 32 /* Share mode on file conflict with open mode */
 #define ERRlock 33 /* Lock request conflicts with existing lock */
 #define ERRfilexists 80 /* File in operation already exists */
-#define ERRundocumented1 123 /* Invalid name?? e.g. .tmp* */
+#define ERRinvalidparam 87 /* ERROR_INVALID_PARAMETER */
+#define ERRdiskfull 112 /* ERROR_DISK_FULL */
+#define ERRinvalidname 123 /* ERROR_INVALID_NAME */
+#define ERRdirnotempty 145 /* ERROR_DIR_NOT_EMPTY */
+#define ERRnotlocked 158 /* ERROR_NOT_LOCKED */
+#define ERRexists 183 /* ERROR_ALREADY_EXISTS, see also 80 */
 #define ERRbadpipe 230 /* Named pipe invalid */
 #define ERRpipebusy 231 /* All instances of pipe are busy */
 #define ERRpipeclosing 232 /* named pipe close in progress */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Oct 07 2001 - 21:00:24 EST