diff for duplicates of <4781BB0D.90706@redhat.com> diff --git a/a/1.txt b/N1/1.txt index 885808e..dc45553 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -31,11 +31,3 @@ Acknowledgment goes to Neil Brown who has been offered support and guidance during our prototype efforts. -- Wendy - --------------- next part -------------- -A non-text attachment was scrubbed... -Name: unlock_001.patch -Type: text/x-patch -Size: 11591 bytes -Desc: not available -URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20080107/5c32265e/attachment.bin> diff --git a/N1/2.hdr b/N1/2.hdr new file mode 100644 index 0000000..bd67b31 --- /dev/null +++ b/N1/2.hdr @@ -0,0 +1,5 @@ +Content-Type: text/x-patch; + name="unlock_001.patch" +Content-Transfer-Encoding: 7bit +Content-Disposition: inline; + filename="unlock_001.patch" diff --git a/N1/2.txt b/N1/2.txt new file mode 100644 index 0000000..2b56509 --- /dev/null +++ b/N1/2.txt @@ -0,0 +1,379 @@ +Two new NFSD procfs files are added: + /proc/fs/nfsd/unlock_ip + /proc/fs/nfsd/unlock_filesystem + +They are intended to allow admin or user mode script to release NLM locks +based on either a path name or a server in-bound ip address (ipv4 for now) +as; + +shell> echo 10.1.1.2 > /proc/fs/nfsd/unlock_ip +shell> echo /mnt/sfs1 > /proc/fs/nfsd/unlock_filesystem + +Signed-off-by: S. Wendy Cheng <wcheng@redhat.com> +Signed-off-by: Lon Hohberger <lhh@redhat.com> + + fs/lockd/svcsubs.c | 117 +++++++++++++++++++++++++++++++++++++++++++- + fs/nfsd/export.c | 20 +++++++ + fs/nfsd/nfsctl.c | 60 ++++++++++++++++++++++ + include/linux/lockd/bind.h | 2 + include/linux/lockd/lockd.h | 14 ++++- + include/linux/nfsd/export.h | 12 ++++ + 6 files changed, 221 insertions(+), 4 deletions(-) + +--- linux-o/include/linux/nfsd/export.h 2008-01-04 10:01:08.000000000 -0500 ++++ linux/include/linux/nfsd/export.h 2008-01-06 15:33:13.000000000 -0500 +@@ -138,6 +138,18 @@ int exp_rootfh(struct auth_domain *, + __be32 exp_pseudoroot(struct svc_rqst *, struct svc_fh *); + __be32 nfserrno(int errno); + ++/* cluster failover support */ ++ ++#define NFSD_FO_VIP 0 ++#define NFSD_FO_PATH 1 ++ ++#define DEBUG 0 ++#define fo_printk(x...) ((void)(DEBUG && printk(x))) ++ ++int nfsd_fo_cmd(int cmd, char *datap, int grace_time); ++ ++/* end of failover addition */ ++ + extern struct cache_detail svc_export_cache; + + static inline void exp_put(struct svc_export *exp) +--- linux-o/fs/nfsd/nfsctl.c 2008-01-04 10:01:08.000000000 -0500 ++++ linux/fs/nfsd/nfsctl.c 2008-01-06 15:27:34.000000000 -0500 +@@ -52,6 +52,8 @@ enum { + NFSD_Getfs, + NFSD_List, + NFSD_Fh, ++ NFSD_FO_UnlockIP, ++ NFSD_FO_UnlockFS, + NFSD_Threads, + NFSD_Pool_Threads, + NFSD_Versions, +@@ -88,6 +90,9 @@ static ssize_t write_leasetime(struct fi + 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, +@@ -97,6 +102,8 @@ static ssize_t (*write_op[])(struct file + [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, +@@ -288,6 +295,56 @@ static ssize_t write_getfd(struct file * + return err; + } + ++extern __u32 in_aton(const char *str); ++ ++static ++ssize_t failover_parse(int where, struct file *file, char *buf, size_t size) ++{ ++ char *fo_path, *mesg; ++ __be32 server_ip[4]; ++ ++ /* sanity check */ ++ if (size <= 0) { ++ fo_printk("nfsd fo buf size not correct\n"); ++ return -EINVAL; ++ } ++ if (buf[size-1] == '\n') ++ buf[size-1] = 0; ++ ++ /* get the string */ ++ fo_printk("nfsd fo buf = %s\n", buf); ++ ++ fo_path = mesg = buf; ++ if (qword_get(&mesg, fo_path, size) < 0) ++ return EINVAL; ++ ++ fo_printk("fo_dev=%s\n", fo_path); ++ ++ switch (where) { ++ case NFSD_FO_PATH: ++ break; ++ case NFSD_FO_VIP: ++ server_ip[0] = in_aton(fo_path); ++ fo_path = (char *) server_ip; ++ break; ++ default: ++ fo_printk("nfsd unknown fo cmd (%d)\n", where); ++ return -EINVAL; ++ } ++ ++ return (nfsd_fo_cmd(where, fo_path, 0)); ++} ++ ++static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size) ++{ ++ return (failover_parse(NFSD_FO_VIP, file, buf, size)); ++} ++ ++static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size) ++{ ++ return (failover_parse(NFSD_FO_PATH, file, buf, size)); ++} ++ + static ssize_t write_filehandle(struct file *file, char *buf, size_t size) + { + /* request is: +@@ -646,6 +703,8 @@ static int nfsd_fill_super(struct super_ + [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}, +@@ -717,7 +776,6 @@ static void __exit exit_nfsd(void) + nfsd4_free_slabs(); + unregister_filesystem(&nfsd_fs_type); + } +- + MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); + MODULE_LICENSE("GPL"); + module_init(init_nfsd) +--- linux-o/fs/nfsd/export.c 2008-01-04 10:01:08.000000000 -0500 ++++ linux/fs/nfsd/export.c 2008-01-06 15:14:55.000000000 -0500 +@@ -1679,3 +1679,23 @@ nfsd_export_shutdown(void) + exp_writeunlock(); + dprintk("nfsd: export shutdown complete.\n"); + } ++ ++int ++nfsd_fo_cmd(int cmd, char *datap, int grace_period) ++{ ++ struct nameidata nd; ++ void *objp = (void *)datap; ++ int rc=0; ++ ++ if (cmd == NFSD_FO_PATH) { ++ rc = path_lookup((const char *)datap, 0, &nd); ++ if (rc) { ++ fo_printk("nfsd: nfsd_fo path (%s) not found\n", datap); ++ return rc; ++ } ++ fo_printk("nfsd: nfsd_fo lookup path = (0x%p,0x%p)\n", ++ nd.mnt, nd.dentry); ++ objp = (void *) &nd; ++ } ++ return (nlmsvc_fo_cmd(cmd, objp, grace_period)); ++} +--- linux-o/fs/lockd/svcsubs.c 2008-01-04 10:01:08.000000000 -0500 ++++ linux/fs/lockd/svcsubs.c 2008-01-06 16:20:37.000000000 -0500 +@@ -18,10 +18,11 @@ + #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 + +- + /* + * Global file hash table + */ +@@ -87,7 +88,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, + unsigned int hash; + __be32 nfserr; + +- nlm_debug_print_fh("nlm_file_lookup", f); ++ nlm_debug_print_fh("nlm_lookup_file", f); + + hash = file_hash(f); + +@@ -123,6 +124,11 @@ nlm_lookup_file(struct svc_rqst *rqstp, + + hlist_add_head(&file->f_list, &nlm_files[hash]); + ++ /* fill in f_iaddr for nlm lock failover */ ++ file->f_iaddr = rqstp->rq_daddr; ++ fo_printk("lockd: file->f_iaddr = %u.%u.%u.%u\n", ++ NIPQUAD(file->f_iaddr.addr.s_addr)); ++ + found: + dprintk("lockd: found file %p (count %d)\n", file, file->f_count); + *result = file; +@@ -194,12 +200,88 @@ again: + return 0; + } + ++static inline int ++nlmsvc_fo_unlock_match(void *datap, struct nlm_file *file) ++{ ++ nlm_fo_cmd *fo_cmd = (nlm_fo_cmd *) datap; ++ int cmd = fo_cmd->cmd; ++ struct path *f_path; ++ ++ fo_printk("nlm_fo_unlock_match cmd=%d\n", cmd); ++ ++ if (cmd == NFSD_FO_VIP) { ++ if (file->f_iaddr.addr.s_addr == ++ ((struct in_addr *)fo_cmd->datap)->s_addr) { ++ fo_printk("lockd: fo ip matches %u.%u.%u.%u\n", ++ NIPQUAD(file->f_iaddr.addr.s_addr)); ++ goto nlmsvc_fo_unlock_match_found; ++ } else { ++ fo_printk("lockd: fo ip no match %u.%u.%u.%u\n", ++ NIPQUAD(((struct in_addr *)fo_cmd->datap)->s_addr)); ++ return 0; ++ } ++ } ++ ++ /* looking for match using file's vfsmount */ ++ f_path = &(file->f_file->f_path); ++ ++ if (cmd == NFSD_FO_PATH) { ++ struct path fo_path; ++ /* ++ * The dentry is not really used but stays here for ++ * debugging purpose. ++ */ ++ fo_path.mnt = ((struct nameidata *) fo_cmd->datap)->mnt; ++ fo_path.dentry = ((struct nameidata *) fo_cmd->datap)->dentry; ++ fo_printk("f_path->mnt (0x%p) f_path->dentry (0x%p)\n", ++ f_path->mnt, f_path->dentry); ++ fo_printk("fo_path (0x%p) fo_path->dentry (0x%p)\n", ++ fo_path.mnt, fo_path.dentry); ++ /* check vfsmount */ ++ if (fo_path.mnt == f_path->mnt) ++ goto nlmsvc_fo_unlock_match_found; ++ return 0; /* not found */ ++ } ++ ++ fo_printk("nlmsvc_fo_unlock_match - unknown cmd\n"); ++ return 0; /* should never reach here */ ++ ++nlmsvc_fo_unlock_match_found: ++ fo_printk("nlmsvc_fo_unlock_match found file=0x%p\n", file); ++ fo_cmd->stat++; ++ return 1; ++} ++ ++/* To fit the logic into current lockd code structure, we add a ++ * little wrapper function here. The real matching task should be ++ * carried out by nlm_fo_check_fsid(). ++ */ ++int nlmsvc_fo_match(struct nlm_host *dummy1, struct nlm_host *dummy2) ++{ ++ return 1; ++} ++ + /* + * Inspect a single file + */ + static inline int + nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, nlm_host_match_fn_t match) + { ++ /* Cluster failover has timing constraints. There is a slight ++ * performance hit if nlm_fo_unlock_match() is implemented as ++ * a match fn (since it will be invoked for each block, share, ++ * and lock later when the lists are traversed). Instead, we ++ * add path-matching logic into the following unlikely clause. ++ * If matches, the dummy nlmsvc_fo_match will always return ++ * true. ++ */ ++ dprintk("nlm_inspect_files: file=%p\n", file); ++ if (unlikely(match == nlmsvc_fo_match)) { ++ if (!nlmsvc_fo_unlock_match((void *)host, file)) ++ return 0; ++ fo_printk("nlm_fo find lock file entry (0x%p)\n", file); ++ } ++ + nlmsvc_traverse_blocks(host, file, match); + nlmsvc_traverse_shares(host, file, match); + return nlm_traverse_locks(host, file, match); +@@ -370,3 +452,34 @@ nlmsvc_invalidate_all(void) + */ + nlm_traverse_files(NULL, nlmsvc_is_client); + } ++ ++/* ++ * Release locks associated with an export fsid upon failover ++ * invoked via nfsd nfsctl call (write_fo_unlock). ++ */ ++int ++nlmsvc_fo_cmd(int cmd, void *datap, int grace_time) ++{ ++ nlm_fo_cmd fo_cmd; ++ int rc=-EINVAL; ++ ++ fo_printk("lockd: nlmsvc_fo_cmd enter, cmd=%d, datap=0x%p, gp=%d\n", ++ cmd, datap, grace_time); ++ ++ fo_cmd.cmd = cmd; ++ fo_cmd.stat = 0; ++ fo_cmd.gp = 0; ++ fo_cmd.datap = datap; ++ ++ /* "if" place holder for NFSD_FO_RESUME */ ++ { ++ /* fo_start */ ++ rc = nlm_traverse_files((struct nlm_host*) &fo_cmd, ++ nlmsvc_fo_match); ++ fo_printk("nlmsvc_fo_cmd rc=%d, stat=%d\n", rc, fo_cmd.stat); ++ } ++ ++ return rc; ++} ++ ++EXPORT_SYMBOL(nlmsvc_fo_cmd); +--- linux-o/include/linux/lockd/bind.h 2008-01-04 10:01:08.000000000 -0500 ++++ linux/include/linux/lockd/bind.h 2008-01-06 15:14:55.000000000 -0500 +@@ -47,4 +47,6 @@ unsigned long get_nfs4_grace_period(void + static inline unsigned long get_nfs4_grace_period(void) {return 0;} + #endif + ++extern int nlmsvc_fo_cmd(int cmd, void *datap, int grace_time); ++ + #endif /* LINUX_LOCKD_BIND_H */ +--- linux-o/include/linux/lockd/lockd.h 2008-01-04 10:01:08.000000000 -0500 ++++ linux/include/linux/lockd/lockd.h 2008-01-06 15:14:55.000000000 -0500 +@@ -39,7 +39,7 @@ + struct nlm_host { + struct hlist_node h_hash; /* doubly linked list */ + struct sockaddr_in h_addr; /* peer address */ +- struct sockaddr_in h_saddr; /* our address (optional) */ ++ struct sockaddr_in h_saddr; /* our address (optional) */ + struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */ + char * h_name; /* remote hostname */ + u32 h_version; /* interface version */ +@@ -113,6 +113,7 @@ struct nlm_file { + unsigned int f_locks; /* guesstimate # of locks */ + unsigned int f_count; /* reference count */ + struct mutex f_mutex; /* avoid concurrent access */ ++ union svc_addr_u f_iaddr; /* server ip for failover */ + }; + + /* +@@ -214,6 +215,17 @@ void nlmsvc_mark_resources(void); + void nlmsvc_free_host_resources(struct nlm_host *); + void nlmsvc_invalidate_all(void); + ++/* cluster failover support */ ++ ++typedef struct { ++ int cmd; ++ int stat; ++ int gp; ++ void *datap; ++} nlm_fo_cmd; ++ ++int nlmsvc_fo_cmd(int cmd, void *datap, int grace_time); ++ + static __inline__ struct inode * + nlmsvc_file_inode(struct nlm_file *file) + { diff --git a/a/content_digest b/N1/content_digest index b47c4ff..fa36687 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,8 +1,9 @@ "From\0Wendy Cheng <wcheng@redhat.com>\0" - "Subject\0[Cluster-devel] [PATCH 1/2] NLM failover unlock commands\0" + "Subject\0[PATCH 1/2] NLM failover unlock commands\0" "Date\0Mon, 07 Jan 2008 00:39:25 -0500\0" - "To\0cluster-devel.redhat.com\0" - "\00:1\0" + "To\0NFS list <linux-nfs@vger.kernel.org>\0" + "Cc\0cluster-devel@redhat.com\0" + "\01:1\0" "b\0" "We've implemented two new NFSD procfs files:\n" "\n" @@ -36,14 +37,388 @@ "Acknowledgment goes to Neil Brown who has been offered support and \n" "guidance during our prototype efforts.\n" "\n" - "-- Wendy\n" + -- Wendy + "\01:2\0" + "fn\0unlock_001.patch\0" + "b\0" + "Two new NFSD procfs files are added:\n" + " /proc/fs/nfsd/unlock_ip\n" + " /proc/fs/nfsd/unlock_filesystem\n" + "\n" + "They are intended to allow admin or user mode script to release NLM locks\n" + "based on either a path name or a server in-bound ip address (ipv4 for now)\n" + "as;\n" + "\n" + "shell> echo 10.1.1.2 > /proc/fs/nfsd/unlock_ip\n" + "shell> echo /mnt/sfs1 > /proc/fs/nfsd/unlock_filesystem\n" + "\n" + "Signed-off-by: S. Wendy Cheng <wcheng@redhat.com>\n" + "Signed-off-by: Lon Hohberger <lhh@redhat.com>\n" + "\n" + " fs/lockd/svcsubs.c | 117 +++++++++++++++++++++++++++++++++++++++++++-\n" + " fs/nfsd/export.c | 20 +++++++\n" + " fs/nfsd/nfsctl.c | 60 ++++++++++++++++++++++\n" + " include/linux/lockd/bind.h | 2 \n" + " include/linux/lockd/lockd.h | 14 ++++-\n" + " include/linux/nfsd/export.h | 12 ++++\n" + " 6 files changed, 221 insertions(+), 4 deletions(-)\n" "\n" - "-------------- next part --------------\n" - "A non-text attachment was scrubbed...\n" - "Name: unlock_001.patch\n" - "Type: text/x-patch\n" - "Size: 11591 bytes\n" - "Desc: not available\n" - URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20080107/5c32265e/attachment.bin> + "--- linux-o/include/linux/nfsd/export.h\t2008-01-04 10:01:08.000000000 -0500\n" + "+++ linux/include/linux/nfsd/export.h\t2008-01-06 15:33:13.000000000 -0500\n" + "@@ -138,6 +138,18 @@ int\t\t\texp_rootfh(struct auth_domain *, \n" + " __be32\t\t\texp_pseudoroot(struct svc_rqst *, struct svc_fh *);\n" + " __be32\t\t\tnfserrno(int errno);\n" + " \n" + "+/* cluster failover support */\n" + "+\n" + "+#define NFSD_FO_VIP 0\n" + "+#define NFSD_FO_PATH 1\n" + "+\n" + "+#define DEBUG 0\n" + "+#define fo_printk(x...) ((void)(DEBUG && printk(x)))\n" + "+\n" + "+int nfsd_fo_cmd(int cmd, char *datap, int grace_time);\n" + "+\n" + "+/* end of failover addition */\n" + "+\n" + " extern struct cache_detail svc_export_cache;\n" + " \n" + " static inline void exp_put(struct svc_export *exp)\n" + "--- linux-o/fs/nfsd/nfsctl.c\t2008-01-04 10:01:08.000000000 -0500\n" + "+++ linux/fs/nfsd/nfsctl.c\t2008-01-06 15:27:34.000000000 -0500\n" + "@@ -52,6 +52,8 @@ enum {\n" + " \tNFSD_Getfs,\n" + " \tNFSD_List,\n" + " \tNFSD_Fh,\n" + "+\tNFSD_FO_UnlockIP,\n" + "+\tNFSD_FO_UnlockFS,\n" + " \tNFSD_Threads,\n" + " \tNFSD_Pool_Threads,\n" + " \tNFSD_Versions,\n" + "@@ -88,6 +90,9 @@ static ssize_t write_leasetime(struct fi\n" + " static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);\n" + " #endif\n" + " \n" + "+static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size);\n" + "+static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size);\n" + "+\n" + " static ssize_t (*write_op[])(struct file *, char *, size_t) = {\n" + " \t[NFSD_Svc] = write_svc,\n" + " \t[NFSD_Add] = write_add,\n" + "@@ -97,6 +102,8 @@ static ssize_t (*write_op[])(struct file\n" + " \t[NFSD_Getfd] = write_getfd,\n" + " \t[NFSD_Getfs] = write_getfs,\n" + " \t[NFSD_Fh] = write_filehandle,\n" + "+\t[NFSD_FO_UnlockIP] = failover_unlock_ip,\n" + "+\t[NFSD_FO_UnlockFS] = failover_unlock_fs,\n" + " \t[NFSD_Threads] = write_threads,\n" + " \t[NFSD_Pool_Threads] = write_pool_threads,\n" + " \t[NFSD_Versions] = write_versions,\n" + "@@ -288,6 +295,56 @@ static ssize_t write_getfd(struct file *\n" + " \treturn err;\n" + " }\n" + " \n" + "+extern __u32 in_aton(const char *str);\n" + "+\n" + "+static\n" + "+ssize_t failover_parse(int where, struct file *file, char *buf, size_t size)\n" + "+{\n" + "+\tchar *fo_path, *mesg;\n" + "+\t__be32 server_ip[4];\n" + "+\n" + "+\t/* sanity check */\n" + "+\tif (size <= 0) {\n" + "+\t\tfo_printk(\"nfsd fo buf size not correct\\n\");\n" + "+\t\treturn -EINVAL;\n" + "+\t}\n" + "+\tif (buf[size-1] == '\\n') \n" + "+\t\tbuf[size-1] = 0;\n" + "+\n" + "+\t/* get the string */\n" + "+\tfo_printk(\"nfsd fo buf = %s\\n\", buf);\n" + "+\n" + "+\tfo_path = mesg = buf;\n" + "+\tif (qword_get(&mesg, fo_path, size) < 0)\n" + "+\t\treturn EINVAL;\n" + "+\n" + "+\tfo_printk(\"fo_dev=%s\\n\", fo_path);\n" + "+\n" + "+\tswitch (where) {\n" + "+\t\tcase NFSD_FO_PATH:\n" + "+\t\t\tbreak;\n" + "+\t\tcase NFSD_FO_VIP:\n" + "+\t\t\tserver_ip[0] = in_aton(fo_path);\n" + "+\t\t\tfo_path = (char *) server_ip;\n" + "+\t\t\tbreak;\n" + "+\t\tdefault:\n" + "+\t\t\tfo_printk(\"nfsd unknown fo cmd (%d)\\n\", where);\n" + "+\t\t\treturn -EINVAL;\n" + "+\t}\n" + "+\n" + "+\treturn (nfsd_fo_cmd(where, fo_path, 0));\n" + "+}\n" + "+\n" + "+static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)\n" + "+{\n" + "+\treturn (failover_parse(NFSD_FO_VIP, file, buf, size));\n" + "+}\n" + "+\n" + "+static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)\n" + "+{\n" + "+\treturn (failover_parse(NFSD_FO_PATH, file, buf, size));\n" + "+}\n" + "+\n" + " static ssize_t write_filehandle(struct file *file, char *buf, size_t size)\n" + " {\n" + " \t/* request is:\n" + "@@ -646,6 +703,8 @@ static int nfsd_fill_super(struct super_\n" + " \t\t[NFSD_Getfd] = {\".getfd\", &transaction_ops, S_IWUSR|S_IRUSR},\n" + " \t\t[NFSD_Getfs] = {\".getfs\", &transaction_ops, S_IWUSR|S_IRUSR},\n" + " \t\t[NFSD_List] = {\"exports\", &exports_operations, S_IRUGO},\n" + "+\t\t[NFSD_FO_UnlockIP] = {\"unlock_ip\", &transaction_ops, S_IWUSR|S_IRUSR},\n" + "+\t\t[NFSD_FO_UnlockFS] = {\"unlock_filesystem\", &transaction_ops, S_IWUSR|S_IRUSR},\n" + " \t\t[NFSD_Fh] = {\"filehandle\", &transaction_ops, S_IWUSR|S_IRUSR},\n" + " \t\t[NFSD_Threads] = {\"threads\", &transaction_ops, S_IWUSR|S_IRUSR},\n" + " \t\t[NFSD_Pool_Threads] = {\"pool_threads\", &transaction_ops, S_IWUSR|S_IRUSR},\n" + "@@ -717,7 +776,6 @@ static void __exit exit_nfsd(void)\n" + " \tnfsd4_free_slabs();\n" + " \tunregister_filesystem(&nfsd_fs_type);\n" + " }\n" + "-\n" + " MODULE_AUTHOR(\"Olaf Kirch <okir@monad.swb.de>\");\n" + " MODULE_LICENSE(\"GPL\");\n" + " module_init(init_nfsd)\n" + "--- linux-o/fs/nfsd/export.c\t2008-01-04 10:01:08.000000000 -0500\n" + "+++ linux/fs/nfsd/export.c\t2008-01-06 15:14:55.000000000 -0500\n" + "@@ -1679,3 +1679,23 @@ nfsd_export_shutdown(void)\n" + " \texp_writeunlock();\n" + " \tdprintk(\"nfsd: export shutdown complete.\\n\");\n" + " }\n" + "+\n" + "+int\n" + "+nfsd_fo_cmd(int cmd, char *datap, int grace_period)\n" + "+{\n" + "+\tstruct nameidata nd;\n" + "+\tvoid *objp = (void *)datap;\n" + "+\tint rc=0;\n" + "+\n" + "+\tif (cmd == NFSD_FO_PATH) { \n" + "+\t\trc = path_lookup((const char *)datap, 0, &nd);\n" + "+\t\tif (rc) {\n" + "+\t\t\tfo_printk(\"nfsd: nfsd_fo path (%s) not found\\n\", datap);\n" + "+\t\t\treturn rc;\n" + "+\t\t}\n" + "+\t\tfo_printk(\"nfsd: nfsd_fo lookup path = (0x%p,0x%p)\\n\", \n" + "+\t\t\tnd.mnt, nd.dentry);\n" + "+\t\tobjp = (void *) &nd;\n" + "+\t} \n" + "+\treturn (nlmsvc_fo_cmd(cmd, objp, grace_period));\n" + "+}\n" + "--- linux-o/fs/lockd/svcsubs.c\t2008-01-04 10:01:08.000000000 -0500\n" + "+++ linux/fs/lockd/svcsubs.c\t2008-01-06 16:20:37.000000000 -0500\n" + "@@ -18,10 +18,11 @@\n" + " #include <linux/lockd/lockd.h>\n" + " #include <linux/lockd/share.h>\n" + " #include <linux/lockd/sm_inter.h>\n" + "+#include <linux/module.h>\n" + "+#include <linux/mount.h>\n" + " \n" + " #define NLMDBG_FACILITY\t\tNLMDBG_SVCSUBS\n" + " \n" + "-\n" + " /*\n" + " * Global file hash table\n" + " */\n" + "@@ -87,7 +88,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, \n" + " \tunsigned int\thash;\n" + " \t__be32\t\tnfserr;\n" + " \n" + "-\tnlm_debug_print_fh(\"nlm_file_lookup\", f);\n" + "+\tnlm_debug_print_fh(\"nlm_lookup_file\", f);\n" + " \n" + " \thash = file_hash(f);\n" + " \n" + "@@ -123,6 +124,11 @@ nlm_lookup_file(struct svc_rqst *rqstp, \n" + " \n" + " \thlist_add_head(&file->f_list, &nlm_files[hash]);\n" + " \n" + "+\t/* fill in f_iaddr for nlm lock failover */\n" + "+\tfile->f_iaddr = rqstp->rq_daddr;\n" + "+\tfo_printk(\"lockd: file->f_iaddr = %u.%u.%u.%u\\n\", \n" + "+\t\t\tNIPQUAD(file->f_iaddr.addr.s_addr));\n" + "+\n" + " found:\n" + " \tdprintk(\"lockd: found file %p (count %d)\\n\", file, file->f_count);\n" + " \t*result = file;\n" + "@@ -194,12 +200,88 @@ again:\n" + " \treturn 0;\n" + " }\n" + " \n" + "+static inline int\n" + "+nlmsvc_fo_unlock_match(void *datap, struct nlm_file *file)\n" + "+{\n" + "+\tnlm_fo_cmd *fo_cmd = (nlm_fo_cmd *) datap;\n" + "+\tint cmd = fo_cmd->cmd;\n" + "+\tstruct path *f_path;\n" + "+\n" + "+\tfo_printk(\"nlm_fo_unlock_match cmd=%d\\n\", cmd);\n" + "+\n" + "+\tif (cmd == NFSD_FO_VIP) {\n" + "+\t\tif (file->f_iaddr.addr.s_addr == \n" + "+\t\t\t((struct in_addr *)fo_cmd->datap)->s_addr) {\n" + "+\t\t\t\tfo_printk(\"lockd: fo ip matches %u.%u.%u.%u\\n\",\n" + "+\t\t\t\t\tNIPQUAD(file->f_iaddr.addr.s_addr));\n" + "+\t\t\t\tgoto nlmsvc_fo_unlock_match_found;\n" + "+\t\t} else {\n" + "+\t\t\tfo_printk(\"lockd: fo ip no match %u.%u.%u.%u\\n\",\n" + "+\t\t\t\tNIPQUAD(((struct in_addr *)fo_cmd->datap)->s_addr));\n" + "+\t\t\treturn 0;\n" + "+\t\t}\n" + "+\t}\n" + "+\n" + "+\t/* looking for match using file's vfsmount */\n" + "+\tf_path = &(file->f_file->f_path);\n" + "+\n" + "+\tif (cmd == NFSD_FO_PATH) {\n" + "+\t\tstruct path fo_path;\n" + "+\t\t/* \n" + "+\t\t * The dentry is not really used but stays here for\n" + "+\t\t * debugging purpose.\n" + "+\t\t */\n" + "+\t\tfo_path.mnt = ((struct nameidata *) fo_cmd->datap)->mnt;\n" + "+\t\tfo_path.dentry = ((struct nameidata *) fo_cmd->datap)->dentry;\n" + "+\t\tfo_printk(\"f_path->mnt (0x%p) f_path->dentry (0x%p)\\n\",\n" + "+\t\t\tf_path->mnt, f_path->dentry);\n" + "+\t\tfo_printk(\"fo_path (0x%p) fo_path->dentry (0x%p)\\n\",\n" + "+\t\t\tfo_path.mnt, fo_path.dentry);\n" + "+\t\t/* check vfsmount */\n" + "+\t\tif (fo_path.mnt == f_path->mnt)\n" + "+\t\t\tgoto nlmsvc_fo_unlock_match_found;\n" + "+\t\treturn 0; /* not found */\n" + "+\t} \n" + "+\n" + "+\tfo_printk(\"nlmsvc_fo_unlock_match - unknown cmd\\n\");\n" + "+\treturn 0; /* should never reach here */\n" + "+\n" + "+nlmsvc_fo_unlock_match_found:\n" + "+\tfo_printk(\"nlmsvc_fo_unlock_match found file=0x%p\\n\", file);\n" + "+\tfo_cmd->stat++;\t\n" + "+\treturn 1;\n" + "+}\n" + "+\n" + "+/* To fit the logic into current lockd code structure, we add a\n" + "+ * little wrapper function here. The real matching task should be\n" + "+ * carried out by nlm_fo_check_fsid().\n" + "+ */\n" + "+int nlmsvc_fo_match(struct nlm_host *dummy1, struct nlm_host *dummy2)\n" + "+{\n" + "+ return 1;\n" + "+}\n" + "+\n" + " /*\n" + " * Inspect a single file\n" + " */\n" + " static inline int\n" + " nlm_inspect_file(struct nlm_host *host, struct nlm_file *file, nlm_host_match_fn_t match)\n" + " {\n" + "+\t/* Cluster failover has timing constraints. There is a slight\n" + "+\t * performance hit if nlm_fo_unlock_match() is implemented as \n" + "+\t * a match fn (since it will be invoked for each block, share,\n" + "+\t * and lock later when the lists are traversed). Instead, we \n" + "+\t * add path-matching logic into the following unlikely clause. \n" + "+\t * If matches, the dummy nlmsvc_fo_match will always return \n" + "+\t * true. \n" + "+\t */\n" + "+\tdprintk(\"nlm_inspect_files: file=%p\\n\", file);\n" + "+\tif (unlikely(match == nlmsvc_fo_match)) {\n" + "+\t\tif (!nlmsvc_fo_unlock_match((void *)host, file))\n" + "+\t\t\treturn 0;\n" + "+\t\tfo_printk(\"nlm_fo find lock file entry (0x%p)\\n\", file);\n" + "+\t}\n" + "+\n" + " \tnlmsvc_traverse_blocks(host, file, match);\n" + " \tnlmsvc_traverse_shares(host, file, match);\n" + " \treturn nlm_traverse_locks(host, file, match);\n" + "@@ -370,3 +452,34 @@ nlmsvc_invalidate_all(void)\n" + " \t */\n" + " \tnlm_traverse_files(NULL, nlmsvc_is_client);\n" + " }\n" + "+\n" + "+/*\n" + "+ * Release locks associated with an export fsid upon failover\n" + "+ * invoked via nfsd nfsctl call (write_fo_unlock).\n" + "+ */\n" + "+int\n" + "+nlmsvc_fo_cmd(int cmd, void *datap, int grace_time)\n" + "+{\n" + "+\tnlm_fo_cmd fo_cmd;\n" + "+\tint rc=-EINVAL;\n" + "+\n" + "+\tfo_printk(\"lockd: nlmsvc_fo_cmd enter, cmd=%d, datap=0x%p, gp=%d\\n\",\n" + "+\t\tcmd, datap, grace_time);\n" + "+\n" + "+\tfo_cmd.cmd = cmd;\n" + "+\tfo_cmd.stat = 0;\n" + "+\tfo_cmd.gp = 0;\n" + "+\tfo_cmd.datap = datap;\n" + "+\n" + "+\t/* \"if\" place holder for NFSD_FO_RESUME */\n" + "+\t{\n" + "+\t\t/* fo_start */\n" + "+\t\trc = nlm_traverse_files((struct nlm_host*) &fo_cmd, \n" + "+\t\t\t\t\tnlmsvc_fo_match);\n" + "+\t\tfo_printk(\"nlmsvc_fo_cmd rc=%d, stat=%d\\n\", rc, fo_cmd.stat);\n" + "+\t} \n" + "+\n" + "+\treturn rc;\n" + "+}\n" + "+\n" + "+EXPORT_SYMBOL(nlmsvc_fo_cmd);\n" + "--- linux-o/include/linux/lockd/bind.h\t2008-01-04 10:01:08.000000000 -0500\n" + "+++ linux/include/linux/lockd/bind.h\t2008-01-06 15:14:55.000000000 -0500\n" + "@@ -47,4 +47,6 @@ unsigned long get_nfs4_grace_period(void\n" + " static inline unsigned long get_nfs4_grace_period(void) {return 0;}\n" + " #endif\n" + " \n" + "+extern int nlmsvc_fo_cmd(int cmd, void *datap, int grace_time);\n" + "+\n" + " #endif /* LINUX_LOCKD_BIND_H */\n" + "--- linux-o/include/linux/lockd/lockd.h\t2008-01-04 10:01:08.000000000 -0500\n" + "+++ linux/include/linux/lockd/lockd.h\t2008-01-06 15:14:55.000000000 -0500\n" + "@@ -39,7 +39,7 @@\n" + " struct nlm_host {\n" + " \tstruct hlist_node\th_hash;\t\t/* doubly linked list */\n" + " \tstruct sockaddr_in\th_addr;\t\t/* peer address */\n" + "-\tstruct sockaddr_in\th_saddr;\t/* our address (optional) */\n" + "+\tstruct sockaddr_in h_saddr; /* our address (optional) */\n" + " \tstruct rpc_clnt\t*\th_rpcclnt;\t/* RPC client to talk to peer */\n" + " \tchar *\t\t\th_name;\t\t/* remote hostname */\n" + " \tu32\t\t\th_version;\t/* interface version */\n" + "@@ -113,6 +113,7 @@ struct nlm_file {\n" + " \tunsigned int\t\tf_locks;\t/* guesstimate # of locks */\n" + " \tunsigned int\t\tf_count;\t/* reference count */\n" + " \tstruct mutex\t\tf_mutex;\t/* avoid concurrent access */\n" + "+\tunion svc_addr_u\tf_iaddr;\t/* server ip for failover */\n" + " };\n" + " \n" + " /*\n" + "@@ -214,6 +215,17 @@ void\t\t nlmsvc_mark_resources(void);\n" + " void\t\t nlmsvc_free_host_resources(struct nlm_host *);\n" + " void\t\t nlmsvc_invalidate_all(void);\n" + " \n" + "+/* cluster failover support */\n" + "+\n" + "+typedef struct {\n" + "+\tint cmd;\n" + "+\tint stat;\n" + "+\tint gp;\n" + "+\tvoid *datap;\n" + "+} nlm_fo_cmd;\n" + "+\n" + "+int nlmsvc_fo_cmd(int cmd, void *datap, int grace_time);\n" + "+\n" + " static __inline__ struct inode *\n" + " nlmsvc_file_inode(struct nlm_file *file)\n" + { -0bcf7e6e180a5787e4362843a881eda86f9035a65b5d9cc116bd668053d890cd +6c2aba3f6ed07a3480baa8ff8ad4ee96afeefbfb28b70d192acb8a06278fcb98
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.