Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Tue, 2 Oct 2001 17:28:53 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Tue, 2 Oct 2001 17:28:45 -0400 Received: from fungus.teststation.com ([212.32.186.211]:27667 "EHLO fungus.teststation.com") by vger.kernel.org with ESMTP id ; Tue, 2 Oct 2001 17:28:24 -0400 Date: Tue, 2 Oct 2001 23:28:37 +0200 (CEST) From: Urban Widmark To: Linus Torvalds cc: Subject: [patch] smbfs misc fixes Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org 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 + + * 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 + + * 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 + + * proc.c: make smb_errno return negative error values + +2001-07-09 Jochen Dolze + + * 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 * 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 #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 #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 #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 +#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 #include +#include #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", ¶m[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 #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/