Merge branch 'osd-devel' into nfs-for-next
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 3 Nov 2011 03:56:40 +0000 (23:56 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 3 Nov 2011 03:56:40 +0000 (23:56 -0400)
1  2 
fs/nfs/file.c
include/linux/sunrpc/clnt.h
include/linux/sunrpc/svc.h
net/sunrpc/svc.c

diff --combined fs/nfs/file.c
index bd7dff001106297c767f7bfdc886f7632afd682c,91c01f0a4c3b1c25be85bc1a673ebbf7186e8df4..0a1f8312b4dcf0fe9272310f1ab6d00178cdd2a8
@@@ -137,9 -137,11 +137,9 @@@ nfs_file_open(struct inode *inode, stru
  static int
  nfs_file_release(struct inode *inode, struct file *filp)
  {
 -      struct dentry *dentry = filp->f_path.dentry;
 -
        dprintk("NFS: release(%s/%s)\n",
 -                      dentry->d_parent->d_name.name,
 -                      dentry->d_name.name);
 +                      filp->f_path.dentry->d_parent->d_name.name,
 +                      filp->f_path.dentry->d_name.name);
  
        nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
        return nfs_release(inode, filp);
@@@ -178,8 -180,6 +178,6 @@@ force_reval
  
  static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
  {
-       loff_t loff;
        dprintk("NFS: llseek file(%s/%s, %lld, %d)\n",
                        filp->f_path.dentry->d_parent->d_name.name,
                        filp->f_path.dentry->d_name.name,
                int retval = nfs_revalidate_file_size(inode, filp);
                if (retval < 0)
                        return (loff_t)retval;
+       }
  
-               spin_lock(&inode->i_lock);
-               loff = generic_file_llseek_unlocked(filp, offset, origin);
-               spin_unlock(&inode->i_lock);
-       } else
-               loff = generic_file_llseek_unlocked(filp, offset, origin);
-       return loff;
+       return generic_file_llseek(filp, offset, origin);
  }
  
  /*
@@@ -232,13 -228,14 +226,13 @@@ nfs_file_read(struct kiocb *iocb, cons
        struct dentry * dentry = iocb->ki_filp->f_path.dentry;
        struct inode * inode = dentry->d_inode;
        ssize_t result;
 -      size_t count = iov_length(iov, nr_segs);
  
        if (iocb->ki_filp->f_flags & O_DIRECT)
                return nfs_file_direct_read(iocb, iov, nr_segs, pos);
  
        dprintk("NFS: read(%s/%s, %lu@%lu)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name,
 -              (unsigned long) count, (unsigned long) pos);
 +              (unsigned long) iov_length(iov, nr_segs), (unsigned long) pos);
  
        result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
        if (!result) {
index ad09bed239fc70dc2e3039c52417c112b923dfb5,492486a74484f9c6bdc77986f0f35e2dc2754d1d..3d8f9c44e27d8a161daed9f8bcdd50591d906991
@@@ -136,8 -136,6 +136,8 @@@ void               rpc_shutdown_client(struct rpc_cl
  void          rpc_release_client(struct rpc_clnt *);
  void          rpc_task_release_client(struct rpc_task *);
  
 +int           rpcb_create_local(void);
 +void          rpcb_put_local(void);
  int           rpcb_register(u32, u32, int, unsigned short);
  int           rpcb_v4_register(const u32 program, const u32 version,
                                 const struct sockaddr *address,
@@@ -221,7 -219,13 +221,13 @@@ static inline bool __rpc_cmp_addr6(cons
  {
        const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
        const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
-       return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr);
+       if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
+               return false;
+       else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+               return sin1->sin6_scope_id == sin2->sin6_scope_id;
+       return true;
  }
  
  static inline bool __rpc_copy_addr6(struct sockaddr *dst,
index 5e71a306216f907721047acef441ce43bcbe93ea,d8d5d93071b3809315e48a567a93ae340d04c0a8..35b37b1e9299e37825fe79a281a29055aa4d273a
@@@ -212,11 -212,6 +212,6 @@@ static inline void svc_putu32(struct kv
        iov->iov_len += sizeof(__be32);
  }
  
- union svc_addr_u {
-     struct in_addr    addr;
-     struct in6_addr   addr6;
- };
  /*
   * The context of a single thread, including the request currently being
   * processed.
@@@ -225,8 -220,12 +220,12 @@@ struct svc_rqst 
        struct list_head        rq_list;        /* idle list */
        struct list_head        rq_all;         /* all threads list */
        struct svc_xprt *       rq_xprt;        /* transport ptr */
        struct sockaddr_storage rq_addr;        /* peer address */
        size_t                  rq_addrlen;
+       struct sockaddr_storage rq_daddr;       /* dest addr of request
+                                                *  - reply from here */
+       size_t                  rq_daddrlen;
  
        struct svc_serv *       rq_server;      /* RPC service definition */
        struct svc_pool *       rq_pool;        /* thread pool */
        unsigned short
                                rq_secure  : 1; /* secure port */
  
-       union svc_addr_u        rq_daddr;       /* dest addr of request
-                                                *  - reply from here */
        void *                  rq_argp;        /* decoded arguments */
        void *                  rq_resp;        /* xdr'd results */
        void *                  rq_auth_data;   /* flavor-specific data */
@@@ -300,6 -296,21 +296,21 @@@ static inline struct sockaddr *svc_addr
        return (struct sockaddr *) &rqst->rq_addr;
  }
  
+ static inline struct sockaddr_in *svc_daddr_in(const struct svc_rqst *rqst)
+ {
+       return (struct sockaddr_in *) &rqst->rq_daddr;
+ }
+ static inline struct sockaddr_in6 *svc_daddr_in6(const struct svc_rqst *rqst)
+ {
+       return (struct sockaddr_in6 *) &rqst->rq_daddr;
+ }
+ static inline struct sockaddr *svc_daddr(const struct svc_rqst *rqst)
+ {
+       return (struct sockaddr *) &rqst->rq_daddr;
+ }
  /*
   * Check buffer bounds after decoding arguments
   */
@@@ -340,7 -351,8 +351,8 @@@ struct svc_deferred_req 
        struct svc_xprt         *xprt;
        struct sockaddr_storage addr;   /* where reply must go */
        size_t                  addrlen;
-       union svc_addr_u        daddr;  /* where reply must come from */
+       struct sockaddr_storage daddr;  /* where reply must come from */
+       size_t                  daddrlen;
        struct cache_deferred_req handle;
        size_t                  xprt_hlen;
        int                     argslen;
@@@ -401,11 -413,10 +413,11 @@@ struct svc_procedure 
  /*
   * Function prototypes.
   */
 +void svc_rpcb_cleanup(struct svc_serv *serv);
  struct svc_serv *svc_create(struct svc_program *, unsigned int,
                            void (*shutdown)(struct svc_serv *));
  struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
-                                       struct svc_pool *pool);
+                                       struct svc_pool *pool, int node);
  void             svc_exit_thread(struct svc_rqst *);
  struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
                        void (*shutdown)(struct svc_serv *),
diff --combined net/sunrpc/svc.c
index 252552a685dcc0c0c416eff95cf37cb57530cd46,dd5cc00ed5593c04e66825ab9cdb0beb19810592..6e038884ae0c1760178cf7647cc7ad3156331f5e
@@@ -295,6 -295,18 +295,18 @@@ svc_pool_map_put(void
  }
  
  
+ static int svc_pool_map_get_node(unsigned int pidx)
+ {
+       const struct svc_pool_map *m = &svc_pool_map;
+       if (m->count) {
+               if (m->mode == SVC_POOL_PERCPU)
+                       return cpu_to_node(m->pool_to[pidx]);
+               if (m->mode == SVC_POOL_PERNODE)
+                       return m->pool_to[pidx];
+       }
+       return NUMA_NO_NODE;
+ }
  /*
   * Set the given thread's cpus_allowed mask so that it
   * will only run on cpus in the given pool.
@@@ -354,42 -366,6 +366,42 @@@ svc_pool_for_cpu(struct svc_serv *serv
        return &serv->sv_pools[pidx % serv->sv_nrpools];
  }
  
 +static int svc_rpcb_setup(struct svc_serv *serv)
 +{
 +      int err;
 +
 +      err = rpcb_create_local();
 +      if (err)
 +              return err;
 +
 +      /* Remove any stale portmap registrations */
 +      svc_unregister(serv);
 +      return 0;
 +}
 +
 +void svc_rpcb_cleanup(struct svc_serv *serv)
 +{
 +      svc_unregister(serv);
 +      rpcb_put_local();
 +}
 +EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
 +
 +static int svc_uses_rpcbind(struct svc_serv *serv)
 +{
 +      struct svc_program      *progp;
 +      unsigned int            i;
 +
 +      for (progp = serv->sv_program; progp; progp = progp->pg_next) {
 +              for (i = 0; i < progp->pg_nvers; i++) {
 +                      if (progp->pg_vers[i] == NULL)
 +                              continue;
 +                      if (progp->pg_vers[i]->vs_hidden == 0)
 +                              return 1;
 +              }
 +      }
 +
 +      return 0;
 +}
  
  /*
   * Create an RPC service
@@@ -455,15 -431,8 +467,15 @@@ __svc_create(struct svc_program *prog, 
                spin_lock_init(&pool->sp_lock);
        }
  
 -      /* Remove any stale portmap registrations */
 -      svc_unregister(serv);
 +      if (svc_uses_rpcbind(serv)) {
 +              if (svc_rpcb_setup(serv) < 0) {
 +                      kfree(serv->sv_pools);
 +                      kfree(serv);
 +                      return NULL;
 +              }
 +              if (!serv->sv_shutdown)
 +                      serv->sv_shutdown = svc_rpcb_cleanup;
 +      }
  
        return serv;
  }
@@@ -531,6 -500,7 +543,6 @@@ svc_destroy(struct svc_serv *serv
        if (svc_serv_is_pooled(serv))
                svc_pool_map_put();
  
 -      svc_unregister(serv);
        kfree(serv->sv_pools);
        kfree(serv);
  }
@@@ -541,7 -511,7 +553,7 @@@ EXPORT_SYMBOL_GPL(svc_destroy)
   * We allocate pages and place them in rq_argpages.
   */
  static int
- svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
+ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size, int node)
  {
        unsigned int pages, arghi;
  
        arghi = 0;
        BUG_ON(pages > RPCSVC_MAXPAGES);
        while (pages) {
-               struct page *p = alloc_page(GFP_KERNEL);
+               struct page *p = alloc_pages_node(node, GFP_KERNEL, 0);
                if (!p)
                        break;
                rqstp->rq_pages[arghi++] = p;
@@@ -578,11 -548,11 +590,11 @@@ svc_release_buffer(struct svc_rqst *rqs
  }
  
  struct svc_rqst *
- svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool)
+ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
  {
        struct svc_rqst *rqstp;
  
-       rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL);
+       rqstp = kzalloc_node(sizeof(*rqstp), GFP_KERNEL, node);
        if (!rqstp)
                goto out_enomem;
  
        rqstp->rq_server = serv;
        rqstp->rq_pool = pool;
  
-       rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL);
+       rqstp->rq_argp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node);
        if (!rqstp->rq_argp)
                goto out_thread;
  
-       rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL);
+       rqstp->rq_resp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node);
        if (!rqstp->rq_resp)
                goto out_thread;
  
-       if (!svc_init_buffer(rqstp, serv->sv_max_mesg))
+       if (!svc_init_buffer(rqstp, serv->sv_max_mesg, node))
                goto out_thread;
  
        return rqstp;
@@@ -689,6 -659,7 +701,7 @@@ svc_set_num_threads(struct svc_serv *se
        struct svc_pool *chosen_pool;
        int error = 0;
        unsigned int state = serv->sv_nrthreads-1;
+       int node;
  
        if (pool == NULL) {
                /* The -1 assumes caller has done a svc_get() */
                nrservs--;
                chosen_pool = choose_pool(serv, pool, &state);
  
-               rqstp = svc_prepare_thread(serv, chosen_pool);
+               node = svc_pool_map_get_node(chosen_pool->sp_id);
+               rqstp = svc_prepare_thread(serv, chosen_pool, node);
                if (IS_ERR(rqstp)) {
                        error = PTR_ERR(rqstp);
                        break;
                }
  
                __module_get(serv->sv_module);
-               task = kthread_create(serv->sv_function, rqstp, serv->sv_name);
+               task = kthread_create_on_node(serv->sv_function, rqstp,
+                                             node, serv->sv_name);
                if (IS_ERR(task)) {
                        error = PTR_ERR(task);
                        module_put(serv->sv_module);
@@@ -998,9 -971,8 +1013,8 @@@ static void svc_unregister(const struc
  /*
   * Printk the given error with the address of the client that caused it.
   */
- static int
- __attribute__ ((format (printf, 2, 3)))
- svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
+ static __printf(2, 3)
+ int svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
  {
        va_list args;
        int     r;