Merge branch 'nfs-for-2.6.32'
Trond Myklebust [Fri, 11 Sep 2009 18:59:37 +0000 (14:59 -0400)]
1  2 
fs/nfs/client.c
net/sunrpc/clnt.c

diff --combined fs/nfs/client.c
@@@ -809,6 -809,9 +809,9 @@@ static int nfs_init_server(struct nfs_s
        /* Initialise the client representation from the mount data */
        server->flags = data->flags;
        server->options = data->options;
+       server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
+               NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
+               NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
  
        if (data->rsize)
                server->rsize = nfs_block_size(data->rsize, NULL);
@@@ -879,7 -882,6 +882,7 @@@ static void nfs_server_set_fsinfo(struc
                server->rsize = NFS_MAX_FILE_IO_SIZE;
        server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
  
 +      server->backing_dev_info.name = "nfs";
        server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
  
        if (server->wsize > max_rpc_payload)
@@@ -1075,10 -1077,6 +1078,6 @@@ struct nfs_server *nfs_create_server(co
                (unsigned long long) server->fsid.major,
                (unsigned long long) server->fsid.minor);
  
-       BUG_ON(!server->nfs_client);
-       BUG_ON(!server->nfs_client->rpc_ops);
-       BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
        spin_lock(&nfs_client_lock);
        list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
        list_add_tail(&server->master_link, &nfs_volume_list);
@@@ -1275,7 -1273,7 +1274,7 @@@ static int nfs4_init_server(struct nfs_
  
        /* Initialise the client representation from the mount data */
        server->flags = data->flags;
-       server->caps |= NFS_CAP_ATOMIC_OPEN;
+       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
        server->options = data->options;
  
        /* Get a client record */
@@@ -1360,10 -1358,6 +1359,6 @@@ struct nfs_server *nfs4_create_server(c
        if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
                server->namelen = NFS4_MAXNAMLEN;
  
-       BUG_ON(!server->nfs_client);
-       BUG_ON(!server->nfs_client->rpc_ops);
-       BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
        spin_lock(&nfs_client_lock);
        list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);
        list_add_tail(&server->master_link, &nfs_volume_list);
@@@ -1401,7 -1395,7 +1396,7 @@@ struct nfs_server *nfs4_create_referral
  
        /* Initialise the client representation from the parent server */
        nfs_server_copy_userdata(server, parent_server);
-       server->caps |= NFS_CAP_ATOMIC_OPEN;
+       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
  
        /* Get a client representation.
         * Note: NFSv4 always uses TCP, */
diff --combined net/sunrpc/clnt.c
@@@ -27,6 -27,8 +27,8 @@@
  #include <linux/types.h>
  #include <linux/kallsyms.h>
  #include <linux/mm.h>
+ #include <linux/namei.h>
+ #include <linux/mount.h>
  #include <linux/slab.h>
  #include <linux/utsname.h>
  #include <linux/workqueue.h>
@@@ -97,33 -99,49 +99,49 @@@ static in
  rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
  {
        static uint32_t clntid;
+       struct nameidata nd;
+       struct path path;
+       char name[15];
+       struct qstr q = {
+               .name = name,
+       };
        int error;
  
-       clnt->cl_vfsmnt = ERR_PTR(-ENOENT);
-       clnt->cl_dentry = ERR_PTR(-ENOENT);
+       clnt->cl_path.mnt = ERR_PTR(-ENOENT);
+       clnt->cl_path.dentry = ERR_PTR(-ENOENT);
        if (dir_name == NULL)
                return 0;
  
-       clnt->cl_vfsmnt = rpc_get_mount();
-       if (IS_ERR(clnt->cl_vfsmnt))
-               return PTR_ERR(clnt->cl_vfsmnt);
+       path.mnt = rpc_get_mount();
+       if (IS_ERR(path.mnt))
+               return PTR_ERR(path.mnt);
+       error = vfs_path_lookup(path.mnt->mnt_root, path.mnt, dir_name, 0, &nd);
+       if (error)
+               goto err;
  
        for (;;) {
-               snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
-                               "%s/clnt%x", dir_name,
-                               (unsigned int)clntid++);
-               clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0';
-               clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt);
-               if (!IS_ERR(clnt->cl_dentry))
-                       return 0;
-               error = PTR_ERR(clnt->cl_dentry);
+               q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++);
+               name[sizeof(name) - 1] = '\0';
+               q.hash = full_name_hash(q.name, q.len);
+               path.dentry = rpc_create_client_dir(nd.path.dentry, &q, clnt);
+               if (!IS_ERR(path.dentry))
+                       break;
+               error = PTR_ERR(path.dentry);
                if (error != -EEXIST) {
-                       printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n",
-                                       clnt->cl_pathname, error);
-                       rpc_put_mount();
-                       return error;
+                       printk(KERN_INFO "RPC: Couldn't create pipefs entry"
+                                       " %s/%s, error %d\n",
+                                       dir_name, name, error);
+                       goto err_path_put;
                }
        }
+       path_put(&nd.path);
+       clnt->cl_path = path;
+       return 0;
+ err_path_put:
+       path_put(&nd.path);
+ err:
+       rpc_put_mount();
+       return error;
  }
  
  static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
        return clnt;
  
  out_no_auth:
-       if (!IS_ERR(clnt->cl_dentry)) {
-               rpc_rmdir(clnt->cl_dentry);
+       if (!IS_ERR(clnt->cl_path.dentry)) {
+               rpc_remove_client_dir(clnt->cl_path.dentry);
                rpc_put_mount();
        }
  out_no_path:
@@@ -423,8 -441,8 +441,8 @@@ rpc_free_client(struct kref *kref
  
        dprintk("RPC:       destroying %s client for %s\n",
                        clnt->cl_protname, clnt->cl_server);
-       if (!IS_ERR(clnt->cl_dentry)) {
-               rpc_rmdir(clnt->cl_dentry);
+       if (!IS_ERR(clnt->cl_path.dentry)) {
+               rpc_remove_client_dir(clnt->cl_path.dentry);
                rpc_put_mount();
        }
        if (clnt->cl_parent != clnt) {
@@@ -937,7 -955,6 +955,7 @@@ static inline voi
  rpc_task_force_reencode(struct rpc_task *task)
  {
        task->tk_rqstp->rq_snd_buf.len = 0;
 +      task->tk_rqstp->rq_bytes_sent = 0;
  }
  
  static inline void