aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4super.c')
-rw-r--r--fs/nfs/nfs4super.c106
1 files changed, 59 insertions, 47 deletions
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 59264fb335c8..12a31a9dbcdd 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -6,15 +6,18 @@
6#include <linux/nfs_idmap.h> 6#include <linux/nfs_idmap.h>
7#include <linux/nfs4_mount.h> 7#include <linux/nfs4_mount.h>
8#include <linux/nfs_fs.h> 8#include <linux/nfs_fs.h>
9#include "delegation.h"
9#include "internal.h" 10#include "internal.h"
10#include "nfs4_fs.h" 11#include "nfs4_fs.h"
12#include "pnfs.h"
13#include "nfs.h"
11 14
12#define NFSDBG_FACILITY NFSDBG_VFS 15#define NFSDBG_FACILITY NFSDBG_VFS
13 16
17static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc);
18static void nfs4_evict_inode(struct inode *inode);
14static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, 19static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
15 int flags, const char *dev_name, void *raw_data); 20 int flags, const char *dev_name, void *raw_data);
16static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
17 int flags, const char *dev_name, void *raw_data);
18static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, 21static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
19 int flags, const char *dev_name, void *raw_data); 22 int flags, const char *dev_name, void *raw_data);
20static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, 23static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
@@ -36,14 +39,6 @@ static struct file_system_type nfs4_remote_fs_type = {
36 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 39 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
37}; 40};
38 41
39struct file_system_type nfs4_xdev_fs_type = {
40 .owner = THIS_MODULE,
41 .name = "nfs4",
42 .mount = nfs4_xdev_mount,
43 .kill_sb = nfs_kill_super,
44 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
45};
46
47static struct file_system_type nfs4_remote_referral_fs_type = { 42static struct file_system_type nfs4_remote_referral_fs_type = {
48 .owner = THIS_MODULE, 43 .owner = THIS_MODULE,
49 .name = "nfs4", 44 .name = "nfs4",
@@ -75,21 +70,48 @@ static const struct super_operations nfs4_sops = {
75 .remount_fs = nfs_remount, 70 .remount_fs = nfs_remount,
76}; 71};
77 72
73struct nfs_subversion nfs_v4 = {
74 .owner = THIS_MODULE,
75 .nfs_fs = &nfs4_fs_type,
76 .rpc_vers = &nfs_version4,
77 .rpc_ops = &nfs_v4_clientops,
78 .sops = &nfs4_sops,
79 .xattr = nfs4_xattr_handlers,
80};
81
82static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
83{
84 int ret = nfs_write_inode(inode, wbc);
85
86 if (ret >= 0 && test_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags)) {
87 int status;
88 bool sync = true;
89
90 if (wbc->sync_mode == WB_SYNC_NONE)
91 sync = false;
92
93 status = pnfs_layoutcommit_inode(inode, sync);
94 if (status < 0)
95 return status;
96 }
97 return ret;
98}
99
78/* 100/*
79 * Set up an NFS4 superblock 101 * Clean out any remaining NFSv4 state that might be left over due
102 * to open() calls that passed nfs_atomic_lookup, but failed to call
103 * nfs_open().
80 */ 104 */
81static void nfs4_fill_super(struct super_block *sb, 105static void nfs4_evict_inode(struct inode *inode)
82 struct nfs_mount_info *mount_info)
83{ 106{
84 sb->s_time_gran = 1; 107 truncate_inode_pages(&inode->i_data, 0);
85 sb->s_op = &nfs4_sops; 108 clear_inode(inode);
86 /* 109 pnfs_return_layout(inode);
87 * The VFS shouldn't apply the umask to mode bits. We will do 110 pnfs_destroy_layout(NFS_I(inode));
88 * so ourselves when necessary. 111 /* If we are holding a delegation, return it! */
89 */ 112 nfs_inode_return_delegation_noreclaim(inode);
90 sb->s_flags |= MS_POSIXACL; 113 /* First call standard NFS clear_inode() code */
91 sb->s_xattr = nfs4_xattr_handlers; 114 nfs_clear_inode(inode);
92 nfs_initialise_sb(sb);
93} 115}
94 116
95/* 117/*
@@ -103,17 +125,16 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
103 struct nfs_server *server; 125 struct nfs_server *server;
104 struct dentry *mntroot = ERR_PTR(-ENOMEM); 126 struct dentry *mntroot = ERR_PTR(-ENOMEM);
105 127
106 mount_info->fill_super = nfs4_fill_super;
107 mount_info->set_security = nfs_set_sb_security; 128 mount_info->set_security = nfs_set_sb_security;
108 129
109 /* Get a volume representation */ 130 /* Get a volume representation */
110 server = nfs4_create_server(mount_info->parsed, mount_info->mntfh); 131 server = nfs4_create_server(mount_info, &nfs_v4);
111 if (IS_ERR(server)) { 132 if (IS_ERR(server)) {
112 mntroot = ERR_CAST(server); 133 mntroot = ERR_CAST(server);
113 goto out; 134 goto out;
114 } 135 }
115 136
116 mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info); 137 mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4);
117 138
118out: 139out:
119 return mntroot; 140 return mntroot;
@@ -228,7 +249,8 @@ static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
228} 249}
229 250
230struct dentry *nfs4_try_mount(int flags, const char *dev_name, 251struct dentry *nfs4_try_mount(int flags, const char *dev_name,
231 struct nfs_mount_info *mount_info) 252 struct nfs_mount_info *mount_info,
253 struct nfs_subversion *nfs_mod)
232{ 254{
233 char *export_path; 255 char *export_path;
234 struct vfsmount *root_mnt; 256 struct vfsmount *root_mnt;
@@ -237,8 +259,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
237 259
238 dfprintk(MOUNT, "--> nfs4_try_mount()\n"); 260 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
239 261
240 mount_info->fill_super = nfs4_fill_super;
241
242 export_path = data->nfs_server.export_path; 262 export_path = data->nfs_server.export_path;
243 data->nfs_server.export_path = "/"; 263 data->nfs_server.export_path = "/";
244 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, 264 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
@@ -253,27 +273,12 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
253 return res; 273 return res;
254} 274}
255 275
256/*
257 * Clone an NFS4 server record on xdev traversal (FSID-change)
258 */
259static struct dentry *
260nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
261 const char *dev_name, void *raw_data)
262{
263 struct nfs_mount_info mount_info = {
264 .fill_super = nfs_clone_super,
265 .set_security = nfs_clone_sb_security,
266 .cloned = raw_data,
267 };
268 return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
269}
270
271static struct dentry * 276static struct dentry *
272nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, 277nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
273 const char *dev_name, void *raw_data) 278 const char *dev_name, void *raw_data)
274{ 279{
275 struct nfs_mount_info mount_info = { 280 struct nfs_mount_info mount_info = {
276 .fill_super = nfs4_fill_super, 281 .fill_super = nfs_fill_super,
277 .set_security = nfs_clone_sb_security, 282 .set_security = nfs_clone_sb_security,
278 .cloned = raw_data, 283 .cloned = raw_data,
279 }; 284 };
@@ -293,7 +298,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
293 goto out; 298 goto out;
294 } 299 }
295 300
296 mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, &mount_info); 301 mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4);
297out: 302out:
298 nfs_free_fhandle(mount_info.mntfh); 303 nfs_free_fhandle(mount_info.mntfh);
299 return mntroot; 304 return mntroot;
@@ -327,7 +332,7 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
327} 332}
328 333
329 334
330int __init init_nfs_v4(void) 335static int __init init_nfs_v4(void)
331{ 336{
332 int err; 337 int err;
333 338
@@ -343,6 +348,7 @@ int __init init_nfs_v4(void)
343 if (err < 0) 348 if (err < 0)
344 goto out2; 349 goto out2;
345 350
351 register_nfs_version(&nfs_v4);
346 return 0; 352 return 0;
347out2: 353out2:
348 nfs4_unregister_sysctl(); 354 nfs4_unregister_sysctl();
@@ -352,9 +358,15 @@ out:
352 return err; 358 return err;
353} 359}
354 360
355void exit_nfs_v4(void) 361static void __exit exit_nfs_v4(void)
356{ 362{
363 unregister_nfs_version(&nfs_v4);
357 unregister_filesystem(&nfs4_fs_type); 364 unregister_filesystem(&nfs4_fs_type);
358 nfs4_unregister_sysctl(); 365 nfs4_unregister_sysctl();
359 nfs_idmap_quit(); 366 nfs_idmap_quit();
360} 367}
368
369MODULE_LICENSE("GPL");
370
371module_init(init_nfs_v4);
372module_exit(exit_nfs_v4);