]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.7pre2 2.3.7pre2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:25:26 +0000 (15:25 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:25:26 +0000 (15:25 -0500)
17 files changed:
Documentation/Configure.help
arch/i386/kernel/smp.c
drivers/net/ibmtr.c
drivers/net/irda/irport.c
drivers/scsi/scsi_error.c
fs/Config.in
fs/buffer.c
fs/smbfs/inode.c
fs/smbfs/proc.c
include/linux/mm.h
include/linux/pagemap.h
include/linux/smb.h
include/linux/smb_fs.h
mm/filemap.c
mm/page_io.c
mm/swap_state.c
net/ipv4/udp.c

index 6bb6e2e11b7982fcd55f6a6a2cdd6b4fb822a701..07439cbf281f110e2f037765054fa835c6fd959d 100644 (file)
@@ -7723,13 +7723,6 @@ CONFIG_SMB_FS
   want), say M here and read Documentation/modules.txt. The module
   will be called smbfs.o. Most people say N, however.
 
-SMB Win95 bug work-around
-CONFIG_SMB_WIN95
-  If you want to connect to a share exported by Windows 95, you should
-  say Y here. The Windows 95 server contains a bug that makes listing
-  directories unreliable. This option slows down the listing of
-  directories. This makes the Windows 95 server a bit more stable.
-
 Coda filesystem support
 CONFIG_CODA_FS
   Coda is an advanced network filesystem, similar to NFS in that it
index 5588f5ca8174f1cd7c58efaf746bc87204b33da7..9d3a8b4b58f26b21e54331afe248cfc156b0f484 100644 (file)
@@ -1164,6 +1164,7 @@ static void smp_tune_scheduling (void)
 }
 
 unsigned int prof_multiplier[NR_CPUS];
+unsigned int prof_old_multiplier[NR_CPUS];
 unsigned int prof_counter[NR_CPUS];
 
 /*
@@ -1187,6 +1188,7 @@ void __init smp_boot_cpus(void)
        for (i = 0; i < NR_CPUS; i++) {
                cpu_number_map[i] = -1;
                prof_counter[i] = 1;
+               prof_old_multiplier[i] = 1;
                prof_multiplier[i] = 1;
        }
 
@@ -1733,6 +1735,10 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
        return 0;
 }
 
+static unsigned int calibration_result;
+
+void setup_APIC_timer(unsigned int clocks);
+
 /*
  * Local timer interrupt handler. It does both profiling and
  * process statistics/rescheduling.
@@ -1745,6 +1751,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
 
 void smp_local_timer_interrupt(struct pt_regs * regs)
 {
+       int user = (user_mode(regs) != 0);
        int cpu = smp_processor_id();
 
        /*
@@ -1753,13 +1760,27 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
         * updated with atomic operations). This is especially
         * useful with a profiling multiplier != 1
         */
-       if (!user_mode(regs))
+       if (!user)
                x86_do_profile(regs->eip);
 
        if (!--prof_counter[cpu]) {
-               int user=0,system=0;
+               int system = 1 - user;
                struct task_struct * p = current;
 
+               /*
+                * The multiplier may have changed since the last time we got
+                * to this point as a result of the user writing to
+                * /proc/profile.  In this case we need to adjust the APIC
+                * timer accordingly.
+                *
+                * Interrupts are already masked off at this point.
+                */
+               prof_counter[cpu] = prof_multiplier[cpu];
+               if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
+                       setup_APIC_timer(calibration_result/prof_counter[cpu]);
+                       prof_old_multiplier[cpu] = prof_counter[cpu];
+               }
+
                /*
                 * After doing the above, we need to make like
                 * a normal interrupt - otherwise timer interrupts
@@ -1767,11 +1788,6 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
                 * WrongThing (tm) to do.
                 */
 
-               if (user_mode(regs))
-                       user=1;
-               else
-                       system=1;
-
                irq_enter(cpu, 0);
                update_one_process(p, 1, user, system, cpu);
                if (p->pid) {
@@ -1791,7 +1807,6 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
                        kstat.per_cpu_system[cpu] += system;
 
                }
-               prof_counter[cpu]=prof_multiplier[cpu];
                irq_exit(cpu, 0);
        }
 
@@ -2064,8 +2079,6 @@ int __init calibrate_APIC_clock(void)
        return calibration_result;
 }
 
-static unsigned int calibration_result;
-
 void __init setup_APIC_clock(void)
 {
        unsigned long flags;
@@ -2117,13 +2130,10 @@ void __init setup_APIC_clock(void)
 /*
  * the frequency of the profiling timer can be changed
  * by writing a multiplier value into /proc/profile.
- *
- * usually you want to run this on all CPUs ;)
  */
 int setup_profiling_timer(unsigned int multiplier)
 {
-       int cpu = smp_processor_id();
-       unsigned long flags;
+       int i;
 
        /*
         * Sanity check. [at least 500 APIC cycles should be
@@ -2133,11 +2143,14 @@ int setup_profiling_timer(unsigned int multiplier)
        if ( (!multiplier) || (calibration_result/multiplier < 500))
                return -EINVAL;
 
-       save_flags(flags);
-       cli();
-       setup_APIC_timer(calibration_result/multiplier);
-       prof_multiplier[cpu]=multiplier;
-       restore_flags(flags);
+       /* 
+        * Set the new multiplier for each CPU.  CPUs don't start using the
+        * new values until the next timer interrupt in which they do process
+        * accounting.  At that time they also adjust their APIC timers
+        * accordingly.
+        */
+       for (i = 0; i < NR_CPUS; ++i)
+               prof_multiplier[i] = multiplier;
 
        return 0;
 }
index f8d53cea4cca9523a4a54c25f4ceb5838c2e376a..29356bbbf3556a89c14b534604434a5137227b13 100644 (file)
@@ -515,7 +515,7 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
        /* How much shared RAM is on adapter ? */
 #ifdef PCMCIA
        ti->avail_shared_ram = pcmcia_reality_check(get_sram_size(ti));
-       ibmtr_mem_base = ti->sram_base ; 
+       ibmtr_mem_base = ti->sram_base << 12 
 #else
        ti->avail_shared_ram = get_sram_size(ti);
 #endif
@@ -835,6 +835,9 @@ static int tok_close(struct device *dev)
                        (int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
 
         dev->start = 0;
+#ifdef PCMCIA
+       ti->sram = 0 ;
+#endif
        DPRINTK("Adapter closed.\n");
        MOD_DEC_USE_COUNT;
 
index 5fb0cd4f28d22025cb0f2466cc30faf7726602bd..e813fe8a4ce76583f3b5188f7236bca573682530 100644 (file)
@@ -321,7 +321,7 @@ void irport_change_speed(struct irda_device *idev, int speed)
        /* Turn on interrups */
        outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, iobase+UART_IER);
 
-       spin_unlock_irqrestore(&self->lock, flags);
+       spin_unlock_irqrestore(&idev->lock, flags);
 }
 
 /*
index 9bb08ce58b62a169559edc69a072cc37778cb419..d7150954872bdcbde7f840efa8ba327d387372c7 100644 (file)
@@ -1926,6 +1926,7 @@ scsi_error_handler(void * data)
        int                    rtn;
         DECLARE_MUTEX_LOCKED(sem);
         unsigned long flags;
+        struct fs_struct *fs;
 
        lock_kernel();
 
@@ -1936,16 +1937,18 @@ scsi_error_handler(void * data)
         */
        exit_mm(current);
 
-
        current->session = 1;
        current->pgrp = 1;
-        /*
-         * FIXME(eric) this is still a child process of the one that did the insmod.
-         * This needs to be attached to task[0] instead.
-         */
+       
+       /* Become as one with the init task */
+       
+       exit_fs(current);       /* current->fs->count--; */
+       fs = init_task.fs;
+       current->fs = fs;
+       atomic_inc(&fs->count);
 
        siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
-        current->fs->umask = 0;
+
 
        /*
         * Set the name of this process.
index 0d1c4ac0d4c07b272979ed3dfa2e19019d0279ea..5edc348ad5a2893d580cdc4bdb594343f4d213f4 100644 (file)
@@ -90,9 +90,6 @@ if [ "$CONFIG_INET" = "y" ]; then
     fi
   fi
   tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS
-  if [ "$CONFIG_SMB_FS" != "n" ]; then
-    bool 'SMB Win95 bug work-around' CONFIG_SMB_WIN95
-  fi
 fi
 if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then
   tristate 'NCP filesystem support (to mount NetWare volumes)' CONFIG_NCP_FS
index 3e1ace5d03a611d826c2c2169a0865d0db520396..9ea490ef43a51a730566d7e1112928424f7709f3 100644 (file)
@@ -1231,7 +1231,9 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate)
         */
        if (!PageError(page))
                SetPageUptodate(page);
-       page->owner = (int)current; // HACK, FIXME, will go away.
+       if (page->owner != -1)
+               PAGE_BUG(page);
+       page->owner = (int)current;
        UnlockPage(page);
 
        return;
@@ -1276,17 +1278,6 @@ static int create_page_buffers (int rw, struct page *page, kdev_t dev, int b[],
                        unlock_kernel();
                        memset(bh->b_data, 0, size);
                        lock_kernel();
-               } else {
-                       struct buffer_head *alias = find_buffer(dev, block, size);
-                       /*
-                        * Tricky issue. It is legal to have an alias here,
-                        * because the buffer-cache layer can increase the
-                        * b_counter even if the buffer goes inactive
-                        * meanwhile.
-                        */
-                       if (alias) {
-                               printk(" buffer %p has nonzero alias %p which is locked!!! hoping that it will go away.\n", bh, alias);
-                       }
                }
        }
        tail->b_this_page = head;
@@ -1532,7 +1523,7 @@ int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size, int bmap)
        int nr, fresh, block;
 
 
-       if ((rw == READ) && !PageLocked(page))
+       if (!PageLocked(page))
                panic("brw_page: page not locked for I/O");
 //     clear_bit(PG_error, &page->flags);
        /*
@@ -1546,6 +1537,7 @@ int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size, int bmap)
        }
        if (!page->buffers)
                BUG();
+       page->owner = -1;
 
        head = page->buffers;
        bh = head;
@@ -1583,6 +1575,7 @@ int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size, int bmap)
                                bh->b_list = BUF_DIRTY;
                                insert_into_dirty_queue(bh);
                        }
+                       arr[nr++] = bh;
                }
                bh = bh->b_this_page;
        } while (bh != head);
@@ -1597,8 +1590,14 @@ int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size, int bmap)
        } else {
                if (!nr && rw == READ) {
                        SetPageUptodate(page);
+                       page->owner = (int)current;
                        UnlockPage(page);
                }
+               if (nr && (rw == WRITE)) {
+                       unlock_kernel();
+                       ll_rw_block(rw, nr, arr);
+                       lock_kernel();
+               }
        }
        return 0;
 }
index d43292af5b3806a931e192f4baf86536712a6a0b..627186cae2a761f9a8f941a097cb213303e22b45 100644 (file)
@@ -376,9 +376,6 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
        *mnt = *((struct smb_mount_data *) raw_data);
        /* ** temp ** pass config flags in file mode */
        mnt->version = (mnt->file_mode >> 9);
-#ifdef CONFIG_SMB_WIN95
-       mnt->version |= SMB_FIX_WIN95;
-#endif
        mnt->file_mode &= (S_IRWXU | S_IRWXG | S_IRWXO);
        mnt->file_mode |= S_IFREG;
        mnt->dir_mode  &= (S_IRWXU | S_IRWXG | S_IRWXO);
@@ -387,8 +384,6 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
        /*
         * Display the enabled options
         */
-       if (mnt->version & SMB_FIX_WIN95)
-               printk("SMBFS: Win 95 bug fixes enabled\n");
        if (mnt->version & SMB_FIX_OLDATTR)
                printk("SMBFS: Using core getattr (Win 95 speedup)\n");
        else if (mnt->version & SMB_FIX_DIRATTR)
index 42981d4836f7f14c24e12b2864378c0afcda649e..06cd5dda9a774fa783eed33c0e76252bb4279d52 100644 (file)
@@ -39,6 +39,9 @@
 #define SMB_DIRINFO_SIZE 43
 #define SMB_STATUS_SIZE  21
 
+/* yes, this deliberately has two parts */
+#define DENTRY_PATH(dentry) (dentry)->d_parent->d_name.name,(dentry)->d_name.name
+
 static int smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
                                struct smb_fattr *);
 static inline int
@@ -174,24 +177,22 @@ static int day_n[] =
                  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
 
 
-extern struct timezone sys_tz;
-
 static time_t
-utc2local(time_t time)
+utc2local(struct smb_sb_info *server, time_t time)
 {
-       return time - sys_tz.tz_minuteswest * 60 - (sys_tz.tz_dsttime ? 3600 :0);
+       return time - server->opt.serverzone*60;
 }
 
 static time_t
-local2utc(time_t time)
+local2utc(struct smb_sb_info *server, time_t time)
 {
-       return time + sys_tz.tz_minuteswest * 60 + (sys_tz.tz_dsttime ? 3600 : 0);
+       return time + server->opt.serverzone*60;
 }
 
 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
 
 static time_t
-date_dos2unix(__u16 date, __u16 time)
+date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time)
 {
        int month, year;
        time_t secs;
@@ -202,18 +203,19 @@ date_dos2unix(__u16 date, __u16 time)
            ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
                                                   month < 2 ? 1 : 0) + 3653);
        /* days since 1.1.70 plus 80's leap day */
-       return local2utc(secs);
+       return local2utc(server, secs);
 }
 
 
 /* Convert linear UNIX date to a MS-DOS time/date pair. */
 
 static void
-date_unix2dos(int unix_date, __u16 *date, __u16 *time)
+date_unix2dos(struct smb_sb_info *server,
+             int unix_date, __u16 *date, __u16 *time)
 {
        int day, year, nl_day, month;
 
-       unix_date = utc2local(unix_date);
+       unix_date = utc2local(server, unix_date);
        *time = (unix_date % 60) / 2 +
                (((unix_date / 60) % 60) << 5) +
                (((unix_date / 3600) % 24) << 11);
@@ -355,6 +357,11 @@ smb_errno(struct smb_sb_info *server)
        int error  = server->err;
        char *class = "Unknown";
 
+#ifdef SMBFS_DEBUG_VERBOSE
+       printk("smb_errno: errcls %d  code %d  from command 0x%x\n",
+               errcls, error, SMB_CMD(server->packet));
+#endif
+
        if (errcls == ERRDOS)
                switch (error)
                {
@@ -456,7 +463,7 @@ smb_errno(struct smb_sb_info *server)
                class = "ERRCMD";
 
 err_unknown:
-       printk("smb_errno: class %s, code %d from command %x\n",
+       printk("smb_errno: class %s, code %d from command 0x%x\n",
                class, error, SMB_CMD(server->packet));
        return EIO;
 }
@@ -646,9 +653,27 @@ printk("smb_newconn: fd=%d, pid=%d\n", opt->fd, current->pid);
        server->generation += 1;
        server->state = CONN_VALID;
        error = 0;
+
+       /* check if we have an old smbmount that uses seconds for the 
+          serverzone */
+       if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60)
+               server->opt.serverzone /= 60;
+
+       /* now that we have an established connection we can detect the server
+          type and enable bug workarounds */
+       if (server->opt.protocol == SMB_PROTOCOL_NT1 &&
+           (server->opt.max_xmit < 0x1000) &&
+           !(server->opt.capabilities & SMB_CAP_NT_SMBS)) {
+               server->mnt->version |= SMB_FIX_WIN95;
+#ifdef SMBFS_DEBUG_VERBOSE
+               printk("smb_newconn: detected WIN95 server\n");
+#endif
+       }
+
 #ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_newconn: protocol=%d, max_xmit=%d, pid=%d\n",
-server->opt.protocol, server->opt.max_xmit, server->conn_pid);
+printk("smb_newconn: protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
+       server->opt.protocol, server->opt.max_xmit, server->conn_pid,
+       server->opt.capabilities);
 #endif
 
 out:
@@ -755,7 +780,7 @@ smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
                {
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_open: %s/%s R/W failed, error=%d, retrying R/O\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, error);
+       DENTRY_PATH(dentry), error);
 #endif
                        mode = read_only;
                        goto retry;
@@ -789,7 +814,7 @@ smb_open(struct dentry *dentry, int wish)
        if (!inode)
        {
                printk("smb_open: no inode for dentry %s/%s\n",
-                       dentry->d_parent->d_name.name, dentry->d_name.name);
+                      DENTRY_PATH(dentry));
                goto out;
        }
 
@@ -810,7 +835,7 @@ smb_open(struct dentry *dentry, int wish)
                {
 #ifdef SMBFS_PARANOIA
 printk("smb_open: %s/%s open failed, result=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, result);
+       DENTRY_PATH(dentry), result);
 #endif
                        goto out;
                }
@@ -829,8 +854,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, result);
        {
 #ifdef SMBFS_PARANOIA
 printk("smb_open: %s/%s access denied, access=%x, wish=%x\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-inode->u.smbfs_i.access, wish);
+       DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
 #endif
                result = -EACCES;
        }
@@ -845,7 +869,7 @@ smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime)
 {
        smb_setup_header(server, SMBclose, 3, 0);
        WSET(server->packet, smb_vwv0, fileid);
-       DSET(server->packet, smb_vwv1, utc2local(mtime));
+       DSET(server->packet, smb_vwv1, utc2local(server, mtime));
        return smb_request_ok(server, SMBclose, 0, 0);
 }
 
@@ -946,7 +970,7 @@ smb_close_dentry(struct dentry * dentry)
                        {
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_close_dentry: closing %s/%s, count=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
+       DENTRY_PATH(dentry), dentry->d_count);
 #endif
                                smb_proc_close_inode(server, ino);
                        }
@@ -954,7 +978,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
                }
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_close_dentry: closed %s/%s, count=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
+       DENTRY_PATH(dentry), dentry->d_count);
 #endif
        }
 }
@@ -1014,7 +1038,7 @@ smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
 out:
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_read: file %s/%s, count=%d, result=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, count, result);
+       DENTRY_PATH(dentry), count, result);
 #endif
        smb_unlock_server(server);
        return result;
@@ -1029,8 +1053,7 @@ smb_proc_write(struct dentry *dentry, off_t offset, int count, const char *data)
 
 #if SMBFS_DEBUG_VERBOSE
 printk("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, 
-count, offset, server->packet_size);
+       DENTRY_PATH(dentry), count, offset, server->packet_size);
 #endif
        smb_lock_server(server);
        p = smb_setup_header(server, SMBwrite, 5, count + 3);
@@ -1063,7 +1086,7 @@ smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid)
       retry:
        p = smb_setup_header(server, SMBcreate, 3, 0);
        WSET(server->packet, smb_vwv0, attr);
-       DSET(server->packet, smb_vwv1, utc2local(ctime));
+       DSET(server->packet, smb_vwv1, utc2local(server, ctime));
        *p++ = 4;
        p = smb_encode_path(server, p, dentry, NULL);
        smb_setup_bcc(server, p);
@@ -1323,7 +1346,7 @@ smb_proc_readdir_short(struct smb_sb_info *server, struct dentry *dir, int fpos,
 
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_readdir_short: %s/%s, pos=%d\n",
-dir->d_parent->d_name.name, dir->d_name.name, fpos);
+       DENTRY_PATH(dir), fpos);
 #endif
 
        smb_lock_server(server);
@@ -1804,15 +1827,15 @@ mask, resp_data_len, WVAL(resp_param, 2));
         */
        date = WVAL(resp_data, 0);
        time = WVAL(resp_data, 2);
-       fattr->f_ctime = date_dos2unix(date, time);
+       fattr->f_ctime = date_dos2unix(server, date, time);
 
        date = WVAL(resp_data, 4);
        time = WVAL(resp_data, 6);
-       fattr->f_atime = date_dos2unix(date, time);
+       fattr->f_atime = date_dos2unix(server, date, time);
 
        date = WVAL(resp_data, 8);
        time = WVAL(resp_data, 10);
-       fattr->f_mtime = date_dos2unix(date, time);
+       fattr->f_mtime = date_dos2unix(server, date, time);
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_getattr_ff: name=%s, date=%x, time=%x, mtime=%ld\n",
 mask, date, time, fattr->f_mtime);
@@ -1831,7 +1854,7 @@ out:
  */
 static int
 smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
-                       struct smb_fattr *fattr)
+                     struct smb_fattr *fattr)
 {
        int result;
        char *p;
@@ -1849,13 +1872,13 @@ smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
                goto out;
        }
        fattr->attr    = WVAL(server->packet, smb_vwv0);
-       fattr->f_mtime = local2utc(DVAL(server->packet, smb_vwv1));
+       fattr->f_mtime = local2utc(server, DVAL(server->packet, smb_vwv1));
        fattr->f_size  = DVAL(server->packet, smb_vwv3);
        fattr->f_ctime = fattr->f_mtime; 
        fattr->f_atime = fattr->f_mtime; 
 #ifdef SMBFS_DEBUG_TIMESTAMP
 printk("getattr_core: %s/%s, mtime=%ld\n",
-dir->d_name.name, name->name, fattr->f_mtime);
+       DENTRY_PATH(dir), fattr->f_mtime);
 #endif
        result = 0;
 
@@ -1926,18 +1949,18 @@ printk("smb_proc_getattr_trans2: not enough data for %s, len=%d\n",
        }
        date = WVAL(resp_data, off_date);
        time = WVAL(resp_data, off_time);
-       attr->f_ctime = date_dos2unix(date, time);
+       attr->f_ctime = date_dos2unix(server, date, time);
 
        date = WVAL(resp_data, 4 + off_date);
        time = WVAL(resp_data, 4 + off_time);
-       attr->f_atime = date_dos2unix(date, time);
+       attr->f_atime = date_dos2unix(server, date, time);
 
        date = WVAL(resp_data, 8 + off_date);
        time = WVAL(resp_data, 8 + off_time);
-       attr->f_mtime = date_dos2unix(date, time);
+       attr->f_mtime = date_dos2unix(server, date, time);
 #ifdef SMBFS_DEBUG_TIMESTAMP
 printk("getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
-dir->d_name.name, name->name, date, time, attr->f_mtime);
+       DENTRY_PATH(dir), date, time, attr->f_mtime);
 #endif
        attr->f_size = DVAL(resp_data, 12);
        attr->attr = WVAL(resp_data, 20);
@@ -1980,6 +2003,7 @@ smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
        return result;
 }
 
+
 /*
  * Called with the server locked. Because of bugs in the
  * core protocol, we use this only to set attributes. See
@@ -1994,7 +2018,7 @@ smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
  */
 static int
 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
-                       __u16 attr)
+                     __u16 attr)
 {
        char *p;
        int result;
@@ -2009,11 +2033,6 @@ smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
        WSET(server->packet, smb_vwv6, 0);
        WSET(server->packet, smb_vwv7, 0);
        *p++ = 4;
-       /*
-        * Samba uses three leading '\', so we'll do it too.
-        */
-       *p++ = '\\';
-       *p++ = '\\';
        p = smb_encode_path(server, p, dentry, NULL);
        *p++ = 4;
        *p++ = 0;
@@ -2044,7 +2063,7 @@ smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr)
 
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_setattr: setting %s/%s, open=%d\n", 
-dir->d_parent->d_name.name, dir->d_name.name, smb_is_open(dir->d_inode));
+       DENTRY_PATH(dir), smb_is_open(dir->d_inode));
 #endif
        smb_lock_server(server);
        result = smb_proc_setattr_core(server, dir, fattr->attr);
@@ -2069,10 +2088,10 @@ smb_proc_setattr_ext(struct smb_sb_info *server,
        /* We don't change the creation time */
        WSET(server->packet, smb_vwv1, 0);
        WSET(server->packet, smb_vwv2, 0);
-       date_unix2dos(fattr->f_atime, &date, &time);
+       date_unix2dos(server, fattr->f_atime, &date, &time);
        WSET(server->packet, smb_vwv3, date);
        WSET(server->packet, smb_vwv4, time);
-       date_unix2dos(fattr->f_mtime, &date, &time);
+       date_unix2dos(server, fattr->f_mtime, &date, &time);
        WSET(server->packet, smb_vwv5, date);
        WSET(server->packet, smb_vwv6, time);
 #ifdef SMBFS_DEBUG_TIMESTAMP
@@ -2119,15 +2138,15 @@ smb_proc_setattr_trans2(struct smb_sb_info *server,
 
        WSET(data, 0, 0); /* creation time */
        WSET(data, 2, 0);
-       date_unix2dos(fattr->f_atime, &date, &time);
+       date_unix2dos(server, fattr->f_atime, &date, &time);
        WSET(data, 4, date);
        WSET(data, 6, time);
-       date_unix2dos(fattr->f_mtime, &date, &time);
+       date_unix2dos(server, fattr->f_mtime, &date, &time);
        WSET(data, 8, date);
        WSET(data, 10, time);
 #ifdef SMBFS_DEBUG_TIMESTAMP
 printk("setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 
-dir->d_parent->d_name.name, dir->d_name.name, date, time, fattr->f_mtime);
+       DENTRY_PATH(dir), date, time, fattr->f_mtime);
 #endif
        DSET(data, 12, 0); /* size */
        DSET(data, 16, 0); /* blksize */
@@ -2174,10 +2193,12 @@ smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
 
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_settime: setting %s/%s, open=%d\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, smb_is_open(inode));
+       DENTRY_PATH(dentry), smb_is_open(inode));
 #endif
        smb_lock_server(server);
-       if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
+       /* setting the time on a Win95 server fails (tridge) */
+       if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 && 
+           !(server->mnt->version & SMB_FIX_WIN95))
        {
                if (smb_is_open(inode) &&
                    inode->u.smbfs_i.access != SMB_O_RDONLY)
@@ -2194,12 +2215,13 @@ dentry->d_parent->d_name.name, dentry->d_name.name, smb_is_open(inode));
                {
                        /*
                         * Set the mtime by opening and closing the file.
+                        * Note that the file is opened read-only, but this
+                        * still allows us to set the date (tridge)
                         */
                        result = -EACCES;
                        if (!smb_is_open(inode))
-                               smb_proc_open(server, dentry, SMB_O_WRONLY);
-                       if (smb_is_open(inode) &&
-                           inode->u.smbfs_i.access != SMB_O_RDONLY)
+                               smb_proc_open(server, dentry, SMB_O_RDONLY);
+                       if (smb_is_open(inode))
                        {
                                inode->i_mtime = fattr->f_mtime;
                                result = smb_proc_close_inode(server, inode);
index c5e3f5bc95b689057a7bde873e305b4318686076..1bc5eb00b6aef4e7a3866c62b36d6582c0d1ab1b 100644 (file)
@@ -167,6 +167,7 @@ typedef struct page {
 #define LockPage(page)         \
        do { int _ret = test_and_set_bit(PG_locked, &(page)->flags); \
        if (_ret) PAGE_BUG(page); \
+       if (page->owner) PAGE_BUG(page); \
        page->owner = (int)current; } while (0)
 #define TryLockPage(page)      ({ int _ret = test_and_set_bit(PG_locked, &(page)->flags); \
                                if (!_ret) page->owner = (int)current; _ret; })
@@ -174,7 +175,7 @@ typedef struct page {
                                        if (page->owner != (int)current) { \
 BUG(); } page->owner = 0; \
 if (!test_and_clear_bit(PG_locked, &(page)->flags)) { \
-                               BUG(); } wake_up(&page->wait); } while (0)
+                       PAGE_BUG(page); } wake_up(&page->wait); } while (0)
 #define PageError(page)                (test_bit(PG_error, &(page)->flags))
 #define SetPageError(page)     ({ int _ret = test_and_set_bit(PG_error, &(page)->flags); _ret; })
 #define ClearPageError(page)   do { if (!test_and_clear_bit(PG_error, &(page)->flags)) BUG(); } while (0)
index 1e0f1265b2bad67c398e2d2e89634e11c43047d5..0f7a128e9e4c1a4dfce68af40a5b8bdc2b00e0c5 100644 (file)
@@ -70,6 +70,7 @@ extern struct page * __find_get_page (struct inode * inode,
                __find_get_page(inode, offset, *page_hash(inode, offset))
 extern struct page * __find_lock_page (struct inode * inode,
                                unsigned long offset, struct page *page);
+extern void lock_page(struct page *page);
 #define find_lock_page(inode, offset) \
                __find_lock_page(inode, offset, *page_hash(inode, offset))
 
index 8953686b07adae3bfdf171a256e9e9040feec866..852d5b0dd89cb915527462dc917ab80e1c5265fe 100644 (file)
@@ -57,7 +57,7 @@ struct smb_conn_opt {
        /* The following are NT LM 0.12 options */
        __u32              maxraw;
        __u32              capabilities;
-       __u16              serverzone;
+       __s16              serverzone;
 };
 
 #ifdef __KERNEL__
index a151a75e66406909f9312b28f68b60e935afd00f..11dfce7ddba07d81d45f0b4bfa54f5885f178ca2 100644 (file)
@@ -77,6 +77,22 @@ smb_vfree(void *obj)
 #define SMB_FIX_OLDATTR        0x0002  /* Use core getattr (Win 95 speedup) */
 #define SMB_FIX_DIRATTR        0x0004  /* Use find_first for getattr */
 
+
+/* NT1 protocol capability bits */
+#define SMB_CAP_RAW_MODE         0x0001
+#define SMB_CAP_MPX_MODE         0x0002
+#define SMB_CAP_UNICODE          0x0004
+#define SMB_CAP_LARGE_FILES      0x0008
+#define SMB_CAP_NT_SMBS          0x0010
+#define SMB_CAP_RPC_REMOTE_APIS  0x0020
+#define SMB_CAP_STATUS32         0x0040
+#define SMB_CAP_LEVEL_II_OPLOCKS 0x0080
+#define SMB_CAP_LOCK_AND_READ    0x0100
+#define SMB_CAP_NT_FIND          0x0200
+#define SMB_CAP_DFS              0x1000
+#define SMB_CAP_LARGE_READX      0x4000
+
+
 /* linux/fs/smbfs/mmap.c */
 int smb_mmap(struct file *, struct vm_area_struct *);
 
index 0edd3eeb57e4dae03e1e1138d7353de1578375d5..2ad26debb47607c85e0ea4711e2bd1b1f581f644 100644 (file)
@@ -80,7 +80,6 @@ static void remove_page_from_hash_queue(struct page * page)
        atomic_dec(&page_cache_size);
 }
 
-
 void invalidate_inode_pages(struct inode * inode)
 {
        struct page ** p;
@@ -468,7 +467,7 @@ repeat:
 /*
  * Get an exclusive lock on the page..
  */
-static void lock_page(struct page *page)
+void lock_page(struct page *page)
 {
        if (TryLockPage(page)) {
                struct task_struct *tsk = current;
@@ -479,6 +478,7 @@ static void lock_page(struct page *page)
                tsk->state = TASK_UNINTERRUPTIBLE;
 
                while (TryLockPage(page)) {
+                       run_task_queue(&tq_disk);
                        schedule();
                        tsk->state = TASK_UNINTERRUPTIBLE;
                }
@@ -1381,10 +1381,8 @@ static inline int do_write_page(struct inode * inode, struct file * file,
        retval = -EIO;
        writepage = inode->i_op->writepage;
        page = mem_map + MAP_NR(page_addr);
-repeat:
-       wait_on_page(page);
-       if (TryLockPage(page))
-               goto repeat;
+       lock_page(page);
+
        if (writepage) {
                retval = writepage(file, page);
        } else {
index c94030ded1132df99682882bbf55853ec1906be6..2226c2c9da7b41bc9b1649180e13b42fe27ce895 100644 (file)
@@ -183,9 +183,6 @@ static void rw_swap_page_base(int rw, unsigned long entry, struct page *page, in
        /* block_size == PAGE_SIZE/zones_used */
        brw_page(rw, page, dev, zones, block_size, 0);
 
-       if (rw == WRITE) // HACK, FIXME
-               UnlockPage(page);
        /* Note! For consistency we do all of the logic,
         * decrementing the page count, and unlocking the page in the
         * swap lock map - in the IO completion handler.
index e0e667339c195145c0182c1f8a279b2f817a39ed..1b33794fd9206e51ed0e0e44e1895fc94cabe1ad 100644 (file)
@@ -219,7 +219,6 @@ static inline void remove_from_swap_cache(struct page *page)
 #endif
        PageClearSwapCache(page);
        remove_inode_page(page);
-       page_cache_release(page);
 }
 
 
@@ -231,7 +230,7 @@ void delete_from_swap_cache(struct page *page)
 {
        long entry = page->offset;
 
-       LockPage(page);
+       lock_page(page);
 
 #ifdef SWAP_CACHE_INFO
        swap_cache_del_total++;
@@ -242,8 +241,9 @@ void delete_from_swap_cache(struct page *page)
                   page_address(page), page_count(page), entry);
 #endif
        remove_from_swap_cache (page);
-       swap_free (entry);
        UnlockPage(page);
+       page_cache_release(page);
+       swap_free (entry);
 }
 
 /* 
index 320e5151eec1472099b7b30493bfd0ba2f2084d7..d43ebe0d35ee6d2b38d016554453ae03cc4deab5 100644 (file)
@@ -655,11 +655,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len)
                if (msg->msg_namelen < sizeof(*usin))
                        return(-EINVAL);
                if (usin->sin_family != AF_INET) {
-                       static int complained;
-                       if (!complained++)
-                               printk(KERN_WARNING "%s forgot to set AF_INET in udp sendmsg. Fix it!\n", current->comm);
-                       if (usin->sin_family)
-                               return -EINVAL;
+                       return -EINVAL;
                }
                ufh.daddr = usin->sin_addr.s_addr;
                ufh.uh.dest = usin->sin_port;