Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Apr 2008 19:06:46 +0000 (12:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Apr 2008 19:06:46 +0000 (12:06 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild:
  kbuild: fix depmod comment
  kbuild: Add new Kbuild variable KBUILD_EXTRA_SYMBOLS
  kbuild: support loading extra symbols in modpost
  Add option to enable -Wframe-larger-than= on gcc 4.4
  kbuild: add kconfig symbols to tags output
  kbuild: fix some minor typoes
  kbuild: error out on missing MODULE_LICENSE

17 files changed:
Documentation/HOWTO
Documentation/filesystems/nfs-rdma.txt
Documentation/filesystems/seq_file.txt
arch/x86/kernel/alternative.c
arch/x86/mm/init_64.c
fs/lockd/svclock.c
fs/lockd/svcsubs.c
fs/locks.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
include/asm-x86/fixmap.h
include/asm-x86/fixmap_32.h
include/asm-x86/fixmap_64.h
include/linux/fs.h
include/linux/lockd/lockd.h
include/linux/nfsd/nfsd.h

index 54835610b3d6564945ac5be5f32077bf07626923..0291ade44c172882087b49cd6069267c12a4df3c 100644 (file)
@@ -249,9 +249,11 @@ process is as follows:
     release a new -rc kernel every week.
   - Process continues until the kernel is considered "ready", the
     process should last around 6 weeks.
-  - A list of known regressions present in each -rc release is
-    tracked at the following URI:
-    http://kernelnewbies.org/known_regressions
+  - Known regressions in each release are periodically posted to the 
+    linux-kernel mailing list.  The goal is to reduce the length of 
+    that list to zero before declaring the kernel to be "ready," but, in
+    the real world, a small number of regressions often remain at 
+    release time.
 
 It is worth mentioning what Andrew Morton wrote on the linux-kernel
 mailing list about kernel releases:
@@ -261,7 +263,7 @@ mailing list about kernel releases:
 
 2.6.x.y -stable kernel tree
 ---------------------------
-Kernels with 4 digit versions are -stable kernels. They contain
+Kernels with 4-part versions are -stable kernels. They contain
 relatively small and critical fixes for security problems or significant
 regressions discovered in a given 2.6.x kernel.
 
@@ -273,7 +275,10 @@ If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
 kernel is the current stable kernel.
 
 2.6.x.y are maintained by the "stable" team <stable@kernel.org>, and are
-released almost every other week.
+released as needs dictate.  The normal release period is approximately 
+two weeks, but it can be longer if there are no pressing problems.  A
+security-related problem, instead, can cause a release to happen almost
+instantly.
 
 The file Documentation/stable_kernel_rules.txt in the kernel tree
 documents what kinds of changes are acceptable for the -stable tree, and
@@ -298,7 +303,9 @@ a while Andrew or the subsystem maintainer pushes it on to Linus for
 inclusion in mainline.
 
 It is heavily encouraged that all new patches get tested in the -mm tree
-before they are sent to Linus for inclusion in the main kernel tree.
+before they are sent to Linus for inclusion in the main kernel tree.  Code
+which does not make an appearance in -mm before the opening of the merge
+window will prove hard to merge into the mainline.
 
 These kernels are not appropriate for use on systems that are supposed
 to be stable and they are more risky to run than any of the other
@@ -354,11 +361,12 @@ Here is a list of some of the different kernel trees available:
     - SCSI, James Bottomley <James.Bottomley@SteelEye.com>
        git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 
+    - x86, Ingo Molnar <mingo@elte.hu>
+       git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
+
   quilt trees:
-    - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman <gregkh@suse.de>
+    - USB, Driver Core, and I2C, Greg Kroah-Hartman <gregkh@suse.de>
        kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
-    - x86-64, partly i386, Andi Kleen <ak@suse.de>
-        ftp.firstfloor.org:/pub/ak/x86_64/quilt/
 
   Other kernel trees can be found listed at http://git.kernel.org/ and in
   the MAINTAINERS file.
@@ -392,8 +400,8 @@ If you want to be advised of the future bug reports, you can subscribe to the
 bugme-new mailing list (only new bug reports are mailed here) or to the
 bugme-janitor mailing list (every change in the bugzilla is mailed here)
 
-       http://lists.osdl.org/mailman/listinfo/bugme-new
-       http://lists.osdl.org/mailman/listinfo/bugme-janitors
+       http://lists.linux-foundation.org/mailman/listinfo/bugme-new
+       http://lists.linux-foundation.org/mailman/listinfo/bugme-janitors
 
 
 
index 1ae34879574b6c616f9de8f1c15851096772502e..d0ec45ae4e7dfa4585fa74c0757be4d80dc02bf5 100644 (file)
@@ -5,7 +5,7 @@
 ################################################################################
 
  Author: NetApp and Open Grid Computing
- Date: February 25, 2008
+ Date: April 15, 2008
 
 Table of Contents
 ~~~~~~~~~~~~~~~~~
@@ -197,12 +197,16 @@ NFS/RDMA Setup
   - On the server system, configure the /etc/exports file and
     start the NFS/RDMA server.
 
-    Exports entries with the following format have been tested:
+    Exports entries with the following formats have been tested:
 
-    /vol0   10.97.103.47(rw,async) 192.168.0.47(rw,async,insecure,no_root_squash)
+    /vol0   192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
+    /vol0   192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
 
-    Here the first IP address is the client's Ethernet address and the second
-    IP address is the clients IPoIB address.
+    The IP address(es) is(are) the client's IPoIB address for an InfiniBand HCA or the
+    cleint's iWARP address(es) for an RNIC.
+
+    NOTE: The "insecure" option must be used because the NFS/RDMA client does not
+    use a reserved port.
 
  Each time a machine boots:
 
index 7fb8e6dc62bfb596032725264c3b911a0cca2b2b..b843743aa0b5928630771a0ba6e22ec65c206654 100644 (file)
@@ -122,8 +122,7 @@ stop() is the place to free it.
        }
 
 Finally, the show() function should format the object currently pointed to
-by the iterator for output. It should return zero, or an error code if
-something goes wrong. The example module's show() function is:
+by the iterator for output.  The example module's show() function is:
 
        static int ct_seq_show(struct seq_file *s, void *v)
        {
@@ -132,6 +131,12 @@ something goes wrong. The example module's show() function is:
                return 0;
        }
 
+If all is well, the show() function should return zero.  A negative error
+code in the usual manner indicates that something went wrong; it will be
+passed back to user space.  This function can also return SEQ_SKIP, which
+causes the current item to be skipped; if the show() function has already
+generated output before returning SEQ_SKIP, that output will be dropped.
+
 We will look at seq_printf() in a moment. But first, the definition of the
 seq_file iterator is finished by creating a seq_operations structure with
 the four functions we have just defined:
@@ -182,12 +187,18 @@ The first two output a single character and a string, just like one would
 expect. seq_escape() is like seq_puts(), except that any character in s
 which is in the string esc will be represented in octal form in the output.
 
-There is also a function for printing filenames:
+There is also a pair of functions for printing filenames:
 
        int seq_path(struct seq_file *m, struct path *path, char *esc);
+       int seq_path_root(struct seq_file *m, struct path *path,
+                         struct path *root, char *esc)
 
 Here, path indicates the file of interest, and esc is a set of characters
-which should be escaped in the output.
+which should be escaped in the output.  A call to seq_path() will output
+the path relative to the current process's filesystem root.  If a different
+root is desired, it can be used with seq_path_root().  Note that, if it
+turns out that path cannot be reached from root, the value of root will be
+changed in seq_file_root() to a root which *does* work.
 
 
 Making it all work
index df4099dc1c682eb4af7c4af22badf4e4f3cd770c..65c7857a90ddfc6ff084c6817baba045ced0ad71 100644 (file)
@@ -511,31 +511,30 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
        unsigned long flags;
        char *vaddr;
        int nr_pages = 2;
+       struct page *pages[2];
+       int i;
 
-       BUG_ON(len > sizeof(long));
-       BUG_ON((((long)addr + len - 1) & ~(sizeof(long) - 1))
-               - ((long)addr & ~(sizeof(long) - 1)));
-       if (kernel_text_address((unsigned long)addr)) {
-               struct page *pages[2] = { virt_to_page(addr),
-                       virt_to_page(addr + PAGE_SIZE) };
-               if (!pages[1])
-                       nr_pages = 1;
-               vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
-               BUG_ON(!vaddr);
-               local_irq_save(flags);
-               memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
-               local_irq_restore(flags);
-               vunmap(vaddr);
+       if (!core_kernel_text((unsigned long)addr)) {
+               pages[0] = vmalloc_to_page(addr);
+               pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
        } else {
-               /*
-                * modules are in vmalloc'ed memory, always writable.
-                */
-               local_irq_save(flags);
-               memcpy(addr, opcode, len);
-               local_irq_restore(flags);
+               pages[0] = virt_to_page(addr);
+               WARN_ON(!PageReserved(pages[0]));
+               pages[1] = virt_to_page(addr + PAGE_SIZE);
        }
+       BUG_ON(!pages[0]);
+       if (!pages[1])
+               nr_pages = 1;
+       vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
+       BUG_ON(!vaddr);
+       local_irq_save(flags);
+       memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
+       local_irq_restore(flags);
+       vunmap(vaddr);
        sync_core();
        /* Could also do a CLFLUSH here to speed up CPU recovery; but
           that causes hangs on some VIA CPUs. */
+       for (i = 0; i < len; i++)
+               BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
        return addr;
 }
index 1ff7906a9a4dbc7afa6dfdd24f274e077cd26773..b798e7b92b1709819a5985f51d40782363da6c51 100644 (file)
@@ -135,7 +135,7 @@ static __init void *spp_getpage(void)
        return ptr;
 }
 
-static __init void
+static void
 set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
 {
        pgd_t *pgd;
@@ -173,7 +173,7 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot)
        new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
 
        pte = pte_offset_kernel(pmd, vaddr);
-       if (!pte_none(*pte) &&
+       if (!pte_none(*pte) && pte_val(new_pte) &&
            pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
                pte_ERROR(*pte);
        set_pte(pte, new_pte);
@@ -214,8 +214,7 @@ void __init cleanup_highmap(void)
 }
 
 /* NOTE: this is meant to be run only at boot */
-void __init
-__set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
+void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
 {
        unsigned long address = __fix_to_virt(idx);
 
index 1f122c1940afa069a6deb31f82103b990867136a..4d81553d29485e69dd19e746a1edadf4618c8d91 100644 (file)
@@ -632,7 +632,7 @@ nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
                block->b_flags |= B_TIMED_OUT;
        if (conf) {
                if (block->b_fl)
-                       locks_copy_lock(block->b_fl, conf);
+                       __locks_copy_lock(block->b_fl, conf);
        }
 }
 
index dbbefbcd671255935c61783e5cf73d4122346cd7..d1c48b539df8723bd8979e502448eee35d4f9adf 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/lockd/lockd.h>
 #include <linux/lockd/share.h>
 #include <linux/lockd/sm_inter.h>
+#include <linux/module.h>
+#include <linux/mount.h>
 
 #define NLMDBG_FACILITY                NLMDBG_SVCSUBS
 
@@ -194,6 +196,12 @@ again:
        return 0;
 }
 
+static int
+nlmsvc_always_match(void *dummy1, struct nlm_host *dummy2)
+{
+       return 1;
+}
+
 /*
  * Inspect a single file
  */
@@ -230,7 +238,8 @@ nlm_file_inuse(struct nlm_file *file)
  * Loop over all files in the file table.
  */
 static int
-nlm_traverse_files(struct nlm_host *host, nlm_host_match_fn_t match)
+nlm_traverse_files(void *data, nlm_host_match_fn_t match,
+               int (*is_failover_file)(void *data, struct nlm_file *file))
 {
        struct hlist_node *pos, *next;
        struct nlm_file *file;
@@ -239,12 +248,14 @@ nlm_traverse_files(struct nlm_host *host, nlm_host_match_fn_t match)
        mutex_lock(&nlm_file_mutex);
        for (i = 0; i < FILE_NRHASH; i++) {
                hlist_for_each_entry_safe(file, pos, next, &nlm_files[i], f_list) {
+                       if (is_failover_file && !is_failover_file(data, file))
+                               continue;
                        file->f_count++;
                        mutex_unlock(&nlm_file_mutex);
 
                        /* Traverse locks, blocks and shares of this file
                         * and update file->f_locks count */
-                       if (nlm_inspect_file(host, file, match))
+                       if (nlm_inspect_file(data, file, match))
                                ret = 1;
 
                        mutex_lock(&nlm_file_mutex);
@@ -303,21 +314,27 @@ nlm_release_file(struct nlm_file *file)
  *     Used by nlmsvc_invalidate_all
  */
 static int
-nlmsvc_mark_host(struct nlm_host *host, struct nlm_host *dummy)
+nlmsvc_mark_host(void *data, struct nlm_host *dummy)
 {
+       struct nlm_host *host = data;
+
        host->h_inuse = 1;
        return 0;
 }
 
 static int
-nlmsvc_same_host(struct nlm_host *host, struct nlm_host *other)
+nlmsvc_same_host(void *data, struct nlm_host *other)
 {
+       struct nlm_host *host = data;
+
        return host == other;
 }
 
 static int
-nlmsvc_is_client(struct nlm_host *host, struct nlm_host *dummy)
+nlmsvc_is_client(void *data, struct nlm_host *dummy)
 {
+       struct nlm_host *host = data;
+
        if (host->h_server) {
                /* we are destroying locks even though the client
                 * hasn't asked us too, so don't unmonitor the
@@ -337,7 +354,7 @@ void
 nlmsvc_mark_resources(void)
 {
        dprintk("lockd: nlmsvc_mark_resources\n");
-       nlm_traverse_files(NULL, nlmsvc_mark_host);
+       nlm_traverse_files(NULL, nlmsvc_mark_host, NULL);
 }
 
 /*
@@ -348,7 +365,7 @@ nlmsvc_free_host_resources(struct nlm_host *host)
 {
        dprintk("lockd: nlmsvc_free_host_resources\n");
 
-       if (nlm_traverse_files(host, nlmsvc_same_host)) {
+       if (nlm_traverse_files(host, nlmsvc_same_host, NULL)) {
                printk(KERN_WARNING
                        "lockd: couldn't remove all locks held by %s\n",
                        host->h_name);
@@ -368,5 +385,41 @@ nlmsvc_invalidate_all(void)
         * turn, which is about as inefficient as it gets.
         * Now we just do it once in nlm_traverse_files.
         */
-       nlm_traverse_files(NULL, nlmsvc_is_client);
+       nlm_traverse_files(NULL, nlmsvc_is_client, NULL);
+}
+
+static int
+nlmsvc_match_sb(void *datap, struct nlm_file *file)
+{
+       struct super_block *sb = datap;
+
+       return sb == file->f_file->f_path.mnt->mnt_sb;
+}
+
+int
+nlmsvc_unlock_all_by_sb(struct super_block *sb)
+{
+       int ret;
+
+       ret = nlm_traverse_files(sb, nlmsvc_always_match, nlmsvc_match_sb);
+       return ret ? -EIO : 0;
+}
+EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_sb);
+
+static int
+nlmsvc_match_ip(void *datap, struct nlm_host *host)
+{
+       __be32 *server_addr = datap;
+
+       return host->h_saddr.sin_addr.s_addr == *server_addr;
+}
+
+int
+nlmsvc_unlock_all_by_ip(__be32 server_addr)
+{
+       int ret;
+       ret = nlm_traverse_files(&server_addr, nlmsvc_match_ip, NULL);
+       return ret ? -EIO : 0;
+
 }
+EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_ip);
index 592faadbcec12f19b2f6ea158e956e2a3b01c838..e1ea2fe036811a7a4f68702655a39c28111e033a 100644 (file)
@@ -224,7 +224,7 @@ static void locks_copy_private(struct file_lock *new, struct file_lock *fl)
 /*
  * Initialize a new lock from an existing file_lock structure.
  */
-static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
+void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl)
 {
        new->fl_owner = fl->fl_owner;
        new->fl_pid = fl->fl_pid;
@@ -833,7 +833,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str
                        if (!posix_locks_conflict(request, fl))
                                continue;
                        if (conflock)
-                               locks_copy_lock(conflock, fl);
+                               __locks_copy_lock(conflock, fl);
                        error = -EAGAIN;
                        if (!(request->fl_flags & FL_SLEEP))
                                goto out;
@@ -1367,18 +1367,20 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
 
        lease = *flp;
 
-       error = -EAGAIN;
-       if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
-               goto out;
-       if ((arg == F_WRLCK)
-           && ((atomic_read(&dentry->d_count) > 1)
-               || (atomic_read(&inode->i_count) > 1)))
-               goto out;
+       if (arg != F_UNLCK) {
+               error = -ENOMEM;
+               new_fl = locks_alloc_lock();
+               if (new_fl == NULL)
+                       goto out;
 
-       error = -ENOMEM;
-       new_fl = locks_alloc_lock();
-       if (new_fl == NULL)
-               goto out;
+               error = -EAGAIN;
+               if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
+                       goto out;
+               if ((arg == F_WRLCK)
+                   && ((atomic_read(&dentry->d_count) > 1)
+                       || (atomic_read(&inode->i_count) > 1)))
+                       goto out;
+       }
 
        /*
         * At this point, we know that if there is an exclusive
@@ -1404,6 +1406,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
                        rdlease_count++;
        }
 
+       error = -EAGAIN;
        if ((arg == F_RDLCK && (wrlease_count > 0)) ||
            (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0)))
                goto out;
@@ -1490,8 +1493,7 @@ EXPORT_SYMBOL_GPL(vfs_setlease);
 int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
 {
        struct file_lock fl, *flp = &fl;
-       struct dentry *dentry = filp->f_path.dentry;
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = filp->f_path.dentry->d_inode;
        int error;
 
        locks_init_lock(&fl);
index 55dfdd71f1b0d8be42a3ce01a4a15e8228b9aaa0..8799b8708188a3acf901f1d09b8e773865d139c5 100644 (file)
@@ -2712,9 +2712,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        * Note: locks.c uses the BKL to protect the inode's lock list.
        */
 
-       /* XXX?: Just to divert the locks_release_private at the start of
-        * locks_copy_lock: */
-       locks_init_lock(&conflock);
        err = vfs_lock_file(filp, cmd, &file_lock, &conflock);
        switch (-err) {
        case 0: /* success! */
index 1ba7ad981935d6f455d5c3185c78ba0842913898..c513bbdf2d36a2188d286ae1e32cbb81fab16107 100644 (file)
@@ -376,20 +376,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *ia
                        goto xdr_error;
                }
        }
-       if (bmval[1] & FATTR4_WORD1_TIME_METADATA) {
-               /* We require the high 32 bits of 'seconds' to be 0, and we ignore
-                  all 32 bits of 'nseconds'. */
-               READ_BUF(12);
-               len += 12;
-               READ32(dummy32);
-               if (dummy32)
-                       return nfserr_inval;
-               READ32(iattr->ia_ctime.tv_sec);
-               READ32(iattr->ia_ctime.tv_nsec);
-               if (iattr->ia_ctime.tv_nsec >= (u32)1000000000)
-                       return nfserr_inval;
-               iattr->ia_valid |= ATTR_CTIME;
-       }
        if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
                READ_BUF(4);
                len += 4;
index 613bcb8171a5da1a649f5a5ab01601e42830a9f5..42f3820ee8f543ca022d019b3b1de49e5907648c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/seq_file.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/inet.h>
 #include <linux/string.h>
 #include <linux/smp_lock.h>
 #include <linux/ctype.h>
@@ -35,6 +36,7 @@
 #include <linux/nfsd/cache.h>
 #include <linux/nfsd/xdr.h>
 #include <linux/nfsd/syscall.h>
+#include <linux/lockd/lockd.h>
 
 #include <asm/uaccess.h>
 #include <net/ipv6.h>
@@ -53,6 +55,8 @@ enum {
        NFSD_Getfs,
        NFSD_List,
        NFSD_Fh,
+       NFSD_FO_UnlockIP,
+       NFSD_FO_UnlockFS,
        NFSD_Threads,
        NFSD_Pool_Threads,
        NFSD_Versions,
@@ -89,6 +93,9 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
 #endif
 
+static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size);
+static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size);
+
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_Svc] = write_svc,
        [NFSD_Add] = write_add,
@@ -98,6 +105,8 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_Getfd] = write_getfd,
        [NFSD_Getfs] = write_getfs,
        [NFSD_Fh] = write_filehandle,
+       [NFSD_FO_UnlockIP] = failover_unlock_ip,
+       [NFSD_FO_UnlockFS] = failover_unlock_fs,
        [NFSD_Threads] = write_threads,
        [NFSD_Pool_Threads] = write_pool_threads,
        [NFSD_Versions] = write_versions,
@@ -298,6 +307,58 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size)
        return err;
 }
 
+static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
+{
+       __be32 server_ip;
+       char *fo_path, c;
+       int b1, b2, b3, b4;
+
+       /* sanity check */
+       if (size == 0)
+               return -EINVAL;
+
+       if (buf[size-1] != '\n')
+               return -EINVAL;
+
+       fo_path = buf;
+       if (qword_get(&buf, fo_path, size) < 0)
+               return -EINVAL;
+
+       /* get ipv4 address */
+       if (sscanf(fo_path, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
+               return -EINVAL;
+       server_ip = htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
+
+       return nlmsvc_unlock_all_by_ip(server_ip);
+}
+
+static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
+{
+       struct nameidata nd;
+       char *fo_path;
+       int error;
+
+       /* sanity check */
+       if (size == 0)
+               return -EINVAL;
+
+       if (buf[size-1] != '\n')
+               return -EINVAL;
+
+       fo_path = buf;
+       if (qword_get(&buf, fo_path, size) < 0)
+               return -EINVAL;
+
+       error = path_lookup(fo_path, 0, &nd);
+       if (error)
+               return error;
+
+       error = nlmsvc_unlock_all_by_sb(nd.path.mnt->mnt_sb);
+
+       path_put(&nd.path);
+       return error;
+}
+
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
 {
        /* request is:
@@ -700,6 +761,10 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
                [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_List] = {"exports", &exports_operations, S_IRUGO},
+               [NFSD_FO_UnlockIP] = {"unlock_ip",
+                                       &transaction_ops, S_IWUSR|S_IRUSR},
+               [NFSD_FO_UnlockFS] = {"unlock_filesystem",
+                                       &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
index 382eb271a89203cc2439fe8a1fb4b38250725648..5bd206973dca3cf184b859a1c2031ce6d3501ff3 100644 (file)
@@ -1,5 +1,13 @@
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
 #ifdef CONFIG_X86_32
 # include "fixmap_32.h"
 #else
 # include "fixmap_64.h"
 #endif
+
+#define clear_fixmap(idx)                      \
+       __set_fixmap(idx, 0, __pgprot(0))
+
+#endif
index eb1665125c443fac0cb1a474b2d7ae4d4c76f4de..4b96148e90c15587f715969f2ff4c6fd5a07d4d8 100644 (file)
@@ -10,8 +10,8 @@
  * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
  */
 
-#ifndef _ASM_FIXMAP_H
-#define _ASM_FIXMAP_H
+#ifndef _ASM_FIXMAP_32_H
+#define _ASM_FIXMAP_32_H
 
 
 /* used by vmalloc.c, vsyscall.lds.S.
@@ -121,9 +121,6 @@ extern void reserve_top_address(unsigned long reserve);
 #define set_fixmap_nocache(idx, phys)                  \
        __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
 
-#define clear_fixmap(idx)                      \
-       __set_fixmap(idx, 0, __pgprot(0))
-
 #define FIXADDR_TOP    ((unsigned long)__FIXADDR_TOP)
 
 #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
index f3d76858c0e6f4b5c380736a1db9b79afcc4242f..355d26a75a821a87aa298ee52f79617015dc7a8e 100644 (file)
@@ -8,8 +8,8 @@
  * Copyright (C) 1998 Ingo Molnar
  */
 
-#ifndef _ASM_FIXMAP_H
-#define _ASM_FIXMAP_H
+#ifndef _ASM_FIXMAP_64_H
+#define _ASM_FIXMAP_64_H
 
 #include <linux/kernel.h>
 #include <asm/apicdef.h>
index cc2be2cf7d4158108965ce5f9394595c68c651e0..6556f2f967e5d32f255a0176764268b30b5f87d5 100644 (file)
@@ -973,6 +973,7 @@ extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset,
 /* fs/locks.c */
 extern void locks_init_lock(struct file_lock *);
 extern void locks_copy_lock(struct file_lock *, struct file_lock *);
+extern void __locks_copy_lock(struct file_lock *, const struct file_lock *);
 extern void locks_remove_posix(struct file *, fl_owner_t);
 extern void locks_remove_flock(struct file *);
 extern void posix_test_lock(struct file *, struct file_lock *);
index 94649a8da01403975c0c24e657f8062b9ec5dc80..102d928f7206b4bce0e242c8779b2de01117e8d5 100644 (file)
@@ -194,7 +194,7 @@ void                  nsm_release(struct nsm_handle *);
  * This is used in garbage collection and resource reclaim
  * A return value != 0 means destroy the lock/block/share
  */
-typedef int      (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref);
+typedef int      (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
 
 /*
  * Server-side lock handling
@@ -220,6 +220,12 @@ void                 nlmsvc_mark_resources(void);
 void             nlmsvc_free_host_resources(struct nlm_host *);
 void             nlmsvc_invalidate_all(void);
 
+/*
+ * Cluster failover support
+ */
+int           nlmsvc_unlock_all_by_sb(struct super_block *sb);
+int           nlmsvc_unlock_all_by_ip(__be32 server_addr);
+
 static inline struct inode *nlmsvc_file_inode(struct nlm_file *file)
 {
        return file->f_file->f_path.dentry->d_inode;
index 21ee440dd3e768eb2bbb1e72f3a33d54c31b69da..41d30c9c9de6e4b33045d232239f0366d2349916 100644 (file)
@@ -329,7 +329,7 @@ extern struct timeval       nfssvc_boot;
 (FATTR4_WORD0_SIZE              | FATTR4_WORD0_ACL                                         )
 #define NFSD_WRITEABLE_ATTRS_WORD1                                                          \
 (FATTR4_WORD1_MODE              | FATTR4_WORD1_OWNER         | FATTR4_WORD1_OWNER_GROUP     \
- | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY_SET)
+ | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
 
 #endif /* CONFIG_NFSD_V4 */