diff options
Diffstat (limited to 'fs/nfs/nfs4super.c')
-rw-r--r-- | fs/nfs/nfs4super.c | 106 |
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 | ||
17 | static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc); | ||
18 | static void nfs4_evict_inode(struct inode *inode); | ||
14 | static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, | 19 | static 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); |
16 | static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type, | ||
17 | int flags, const char *dev_name, void *raw_data); | ||
18 | static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, | 21 | static 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); |
20 | static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, | 23 | static 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 | ||
39 | struct 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 | |||
47 | static struct file_system_type nfs4_remote_referral_fs_type = { | 42 | static 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 | ||
73 | struct 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 | |||
82 | static 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 | */ |
81 | static void nfs4_fill_super(struct super_block *sb, | 105 | static 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 | ||
118 | out: | 139 | out: |
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 | ||
230 | struct dentry *nfs4_try_mount(int flags, const char *dev_name, | 251 | struct 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 | */ | ||
259 | static struct dentry * | ||
260 | nfs4_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 | |||
271 | static struct dentry * | 276 | static struct dentry * |
272 | nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, | 277 | nfs4_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); |
297 | out: | 302 | out: |
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 | ||
330 | int __init init_nfs_v4(void) | 335 | static 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; |
347 | out2: | 353 | out2: |
348 | nfs4_unregister_sysctl(); | 354 | nfs4_unregister_sysctl(); |
@@ -352,9 +358,15 @@ out: | |||
352 | return err; | 358 | return err; |
353 | } | 359 | } |
354 | 360 | ||
355 | void exit_nfs_v4(void) | 361 | static 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 | |||
369 | MODULE_LICENSE("GPL"); | ||
370 | |||
371 | module_init(init_nfs_v4); | ||
372 | module_exit(exit_nfs_v4); | ||