diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/nfs/inode.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 461 |
1 files changed, 179 insertions, 282 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index ebeb94ce1b0..679d2f50b14 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -32,14 +32,14 @@ | |||
32 | #include <linux/lockd/bind.h> | 32 | #include <linux/lockd/bind.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | #include <linux/mount.h> | 34 | #include <linux/mount.h> |
35 | #include <linux/nfs_idmap.h> | ||
35 | #include <linux/vfs.h> | 36 | #include <linux/vfs.h> |
36 | #include <linux/inet.h> | 37 | #include <linux/inet.h> |
37 | #include <linux/nfs_xdr.h> | 38 | #include <linux/nfs_xdr.h> |
38 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
39 | #include <linux/compat.h> | 40 | #include <linux/compat.h> |
40 | #include <linux/freezer.h> | ||
41 | #include <linux/crc32.h> | ||
42 | 41 | ||
42 | #include <asm/system.h> | ||
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | 44 | ||
45 | #include "nfs4_fs.h" | 45 | #include "nfs4_fs.h" |
@@ -50,15 +50,13 @@ | |||
50 | #include "fscache.h" | 50 | #include "fscache.h" |
51 | #include "dns_resolve.h" | 51 | #include "dns_resolve.h" |
52 | #include "pnfs.h" | 52 | #include "pnfs.h" |
53 | #include "nfs.h" | ||
54 | #include "netns.h" | ||
55 | 53 | ||
56 | #define NFSDBG_FACILITY NFSDBG_VFS | 54 | #define NFSDBG_FACILITY NFSDBG_VFS |
57 | 55 | ||
58 | #define NFS_64_BIT_INODE_NUMBERS_ENABLED 1 | 56 | #define NFS_64_BIT_INODE_NUMBERS_ENABLED 1 |
59 | 57 | ||
60 | /* Default is to see 64-bit inode numbers */ | 58 | /* Default is to see 64-bit inode numbers */ |
61 | static bool enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED; | 59 | static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED; |
62 | 60 | ||
63 | static void nfs_invalidate_inode(struct inode *); | 61 | static void nfs_invalidate_inode(struct inode *); |
64 | static int nfs_update_inode(struct inode *, struct nfs_fattr *); | 62 | static int nfs_update_inode(struct inode *, struct nfs_fattr *); |
@@ -79,10 +77,9 @@ int nfs_wait_bit_killable(void *word) | |||
79 | { | 77 | { |
80 | if (fatal_signal_pending(current)) | 78 | if (fatal_signal_pending(current)) |
81 | return -ERESTARTSYS; | 79 | return -ERESTARTSYS; |
82 | freezable_schedule(); | 80 | schedule(); |
83 | return 0; | 81 | return 0; |
84 | } | 82 | } |
85 | EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); | ||
86 | 83 | ||
87 | /** | 84 | /** |
88 | * nfs_compat_user_ino64 - returns the user-visible inode number | 85 | * nfs_compat_user_ino64 - returns the user-visible inode number |
@@ -107,29 +104,22 @@ u64 nfs_compat_user_ino64(u64 fileid) | |||
107 | return ino; | 104 | return ino; |
108 | } | 105 | } |
109 | 106 | ||
110 | int nfs_drop_inode(struct inode *inode) | 107 | static void nfs_clear_inode(struct inode *inode) |
111 | { | ||
112 | return NFS_STALE(inode) || generic_drop_inode(inode); | ||
113 | } | ||
114 | EXPORT_SYMBOL_GPL(nfs_drop_inode); | ||
115 | |||
116 | void nfs_clear_inode(struct inode *inode) | ||
117 | { | 108 | { |
118 | /* | 109 | /* |
119 | * The following should never happen... | 110 | * The following should never happen... |
120 | */ | 111 | */ |
121 | WARN_ON_ONCE(nfs_have_writebacks(inode)); | 112 | BUG_ON(nfs_have_writebacks(inode)); |
122 | WARN_ON_ONCE(!list_empty(&NFS_I(inode)->open_files)); | 113 | BUG_ON(!list_empty(&NFS_I(inode)->open_files)); |
123 | nfs_zap_acl_cache(inode); | 114 | nfs_zap_acl_cache(inode); |
124 | nfs_access_zap_cache(inode); | 115 | nfs_access_zap_cache(inode); |
125 | nfs_fscache_release_inode_cookie(inode); | 116 | nfs_fscache_release_inode_cookie(inode); |
126 | } | 117 | } |
127 | EXPORT_SYMBOL_GPL(nfs_clear_inode); | ||
128 | 118 | ||
129 | void nfs_evict_inode(struct inode *inode) | 119 | void nfs_evict_inode(struct inode *inode) |
130 | { | 120 | { |
131 | truncate_inode_pages(&inode->i_data, 0); | 121 | truncate_inode_pages(&inode->i_data, 0); |
132 | clear_inode(inode); | 122 | end_writeback(inode); |
133 | nfs_clear_inode(inode); | 123 | nfs_clear_inode(inode); |
134 | } | 124 | } |
135 | 125 | ||
@@ -160,13 +150,11 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
160 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 150 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
161 | nfsi->attrtimeo_timestamp = jiffies; | 151 | nfsi->attrtimeo_timestamp = jiffies; |
162 | 152 | ||
163 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); | 153 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); |
164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { | 154 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) |
165 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 155 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
166 | nfs_fscache_invalidate(inode); | 156 | else |
167 | } else { | ||
168 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 157 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
169 | } | ||
170 | } | 158 | } |
171 | 159 | ||
172 | void nfs_zap_caches(struct inode *inode) | 160 | void nfs_zap_caches(struct inode *inode) |
@@ -181,7 +169,6 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) | |||
181 | if (mapping->nrpages != 0) { | 169 | if (mapping->nrpages != 0) { |
182 | spin_lock(&inode->i_lock); | 170 | spin_lock(&inode->i_lock); |
183 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; | 171 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; |
184 | nfs_fscache_invalidate(inode); | ||
185 | spin_unlock(&inode->i_lock); | 172 | spin_unlock(&inode->i_lock); |
186 | } | 173 | } |
187 | } | 174 | } |
@@ -197,7 +184,6 @@ void nfs_zap_acl_cache(struct inode *inode) | |||
197 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL; | 184 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL; |
198 | spin_unlock(&inode->i_lock); | 185 | spin_unlock(&inode->i_lock); |
199 | } | 186 | } |
200 | EXPORT_SYMBOL_GPL(nfs_zap_acl_cache); | ||
201 | 187 | ||
202 | void nfs_invalidate_atime(struct inode *inode) | 188 | void nfs_invalidate_atime(struct inode *inode) |
203 | { | 189 | { |
@@ -205,7 +191,6 @@ void nfs_invalidate_atime(struct inode *inode) | |||
205 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; | 191 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; |
206 | spin_unlock(&inode->i_lock); | 192 | spin_unlock(&inode->i_lock); |
207 | } | 193 | } |
208 | EXPORT_SYMBOL_GPL(nfs_invalidate_atime); | ||
209 | 194 | ||
210 | /* | 195 | /* |
211 | * Invalidate, but do not unhash, the inode. | 196 | * Invalidate, but do not unhash, the inode. |
@@ -298,7 +283,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
298 | inode->i_mode = fattr->mode; | 283 | inode->i_mode = fattr->mode; |
299 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 | 284 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 |
300 | && nfs_server_capable(inode, NFS_CAP_MODE)) | 285 | && nfs_server_capable(inode, NFS_CAP_MODE)) |
301 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 286 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
287 | | NFS_INO_INVALID_ACCESS | ||
288 | | NFS_INO_INVALID_ACL; | ||
302 | /* Why so? Because we want revalidate for devices/FIFOs, and | 289 | /* Why so? Because we want revalidate for devices/FIFOs, and |
303 | * that's precisely what we have in nfs_file_inode_operations. | 290 | * that's precisely what we have in nfs_file_inode_operations. |
304 | */ | 291 | */ |
@@ -311,6 +298,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
311 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; | 298 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; |
312 | inode->i_fop = &nfs_dir_operations; | 299 | inode->i_fop = &nfs_dir_operations; |
313 | inode->i_data.a_ops = &nfs_dir_aops; | 300 | inode->i_data.a_ops = &nfs_dir_aops; |
301 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)) | ||
302 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); | ||
314 | /* Deal with crossing mountpoints */ | 303 | /* Deal with crossing mountpoints */ |
315 | if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT || | 304 | if (fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT || |
316 | fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { | 305 | fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) { |
@@ -329,15 +318,13 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
329 | memset(&inode->i_atime, 0, sizeof(inode->i_atime)); | 318 | memset(&inode->i_atime, 0, sizeof(inode->i_atime)); |
330 | memset(&inode->i_mtime, 0, sizeof(inode->i_mtime)); | 319 | memset(&inode->i_mtime, 0, sizeof(inode->i_mtime)); |
331 | memset(&inode->i_ctime, 0, sizeof(inode->i_ctime)); | 320 | memset(&inode->i_ctime, 0, sizeof(inode->i_ctime)); |
332 | inode->i_version = 0; | 321 | nfsi->change_attr = 0; |
333 | inode->i_size = 0; | 322 | inode->i_size = 0; |
334 | clear_nlink(inode); | 323 | inode->i_nlink = 0; |
335 | inode->i_uid = -2; | 324 | inode->i_uid = -2; |
336 | inode->i_gid = -2; | 325 | inode->i_gid = -2; |
337 | inode->i_blocks = 0; | 326 | inode->i_blocks = 0; |
338 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); | 327 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); |
339 | nfsi->write_io = 0; | ||
340 | nfsi->read_io = 0; | ||
341 | 328 | ||
342 | nfsi->read_cache_jiffies = fattr->time_start; | 329 | nfsi->read_cache_jiffies = fattr->time_start; |
343 | nfsi->attr_gencount = fattr->gencount; | 330 | nfsi->attr_gencount = fattr->gencount; |
@@ -348,32 +335,41 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
348 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) | 335 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) |
349 | inode->i_mtime = fattr->mtime; | 336 | inode->i_mtime = fattr->mtime; |
350 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) | 337 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) |
351 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 338 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
339 | | NFS_INO_INVALID_DATA; | ||
352 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) | 340 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
353 | inode->i_ctime = fattr->ctime; | 341 | inode->i_ctime = fattr->ctime; |
354 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) | 342 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) |
355 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 343 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
344 | | NFS_INO_INVALID_ACCESS | ||
345 | | NFS_INO_INVALID_ACL; | ||
356 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) | 346 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) |
357 | inode->i_version = fattr->change_attr; | 347 | nfsi->change_attr = fattr->change_attr; |
358 | else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) | 348 | else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) |
359 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 349 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
350 | | NFS_INO_INVALID_DATA; | ||
360 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) | 351 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) |
361 | inode->i_size = nfs_size_to_loff_t(fattr->size); | 352 | inode->i_size = nfs_size_to_loff_t(fattr->size); |
362 | else | 353 | else |
363 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 354 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
355 | | NFS_INO_INVALID_DATA | ||
364 | | NFS_INO_REVAL_PAGECACHE; | 356 | | NFS_INO_REVAL_PAGECACHE; |
365 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) | 357 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) |
366 | set_nlink(inode, fattr->nlink); | 358 | inode->i_nlink = fattr->nlink; |
367 | else if (nfs_server_capable(inode, NFS_CAP_NLINK)) | 359 | else if (nfs_server_capable(inode, NFS_CAP_NLINK)) |
368 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 360 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; |
369 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) | 361 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) |
370 | inode->i_uid = fattr->uid; | 362 | inode->i_uid = fattr->uid; |
371 | else if (nfs_server_capable(inode, NFS_CAP_OWNER)) | 363 | else if (nfs_server_capable(inode, NFS_CAP_OWNER)) |
372 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 364 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
365 | | NFS_INO_INVALID_ACCESS | ||
366 | | NFS_INO_INVALID_ACL; | ||
373 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) | 367 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) |
374 | inode->i_gid = fattr->gid; | 368 | inode->i_gid = fattr->gid; |
375 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) | 369 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) |
376 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 370 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
371 | | NFS_INO_INVALID_ACCESS | ||
372 | | NFS_INO_INVALID_ACL; | ||
377 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) | 373 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) |
378 | inode->i_blocks = fattr->du.nfs2.blocks; | 374 | inode->i_blocks = fattr->du.nfs2.blocks; |
379 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { | 375 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { |
@@ -391,10 +387,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
391 | unlock_new_inode(inode); | 387 | unlock_new_inode(inode); |
392 | } else | 388 | } else |
393 | nfs_refresh_inode(inode, fattr); | 389 | nfs_refresh_inode(inode, fattr); |
394 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", | 390 | dprintk("NFS: nfs_fhget(%s/%Ld ct=%d)\n", |
395 | inode->i_sb->s_id, | 391 | inode->i_sb->s_id, |
396 | (long long)NFS_FILEID(inode), | 392 | (long long)NFS_FILEID(inode), |
397 | nfs_display_fhandle_hash(fh), | ||
398 | atomic_read(&inode->i_count)); | 393 | atomic_read(&inode->i_count)); |
399 | 394 | ||
400 | out: | 395 | out: |
@@ -404,9 +399,8 @@ out_no_inode: | |||
404 | dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode)); | 399 | dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode)); |
405 | goto out; | 400 | goto out; |
406 | } | 401 | } |
407 | EXPORT_SYMBOL_GPL(nfs_fhget); | ||
408 | 402 | ||
409 | #define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN) | 403 | #define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE) |
410 | 404 | ||
411 | int | 405 | int |
412 | nfs_setattr(struct dentry *dentry, struct iattr *attr) | 406 | nfs_setattr(struct dentry *dentry, struct iattr *attr) |
@@ -428,14 +422,12 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
428 | 422 | ||
429 | /* Optimization: if the end result is no change, don't RPC */ | 423 | /* Optimization: if the end result is no change, don't RPC */ |
430 | attr->ia_valid &= NFS_VALID_ATTRS; | 424 | attr->ia_valid &= NFS_VALID_ATTRS; |
431 | if ((attr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0) | 425 | if ((attr->ia_valid & ~ATTR_FILE) == 0) |
432 | return 0; | 426 | return 0; |
433 | 427 | ||
434 | /* Write all dirty data */ | 428 | /* Write all dirty data */ |
435 | if (S_ISREG(inode->i_mode)) { | 429 | if (S_ISREG(inode->i_mode)) |
436 | nfs_inode_dio_wait(inode); | ||
437 | nfs_wb_all(inode); | 430 | nfs_wb_all(inode); |
438 | } | ||
439 | 431 | ||
440 | fattr = nfs_alloc_fattr(); | 432 | fattr = nfs_alloc_fattr(); |
441 | if (fattr == NULL) | 433 | if (fattr == NULL) |
@@ -444,7 +436,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
444 | * Return any delegations if we're going to change ACLs | 436 | * Return any delegations if we're going to change ACLs |
445 | */ | 437 | */ |
446 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) | 438 | if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) |
447 | NFS_PROTO(inode)->return_delegation(inode); | 439 | nfs_inode_return_delegation(inode); |
448 | error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); | 440 | error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); |
449 | if (error == 0) | 441 | if (error == 0) |
450 | nfs_refresh_inode(inode, fattr); | 442 | nfs_refresh_inode(inode, fattr); |
@@ -452,7 +444,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
452 | out: | 444 | out: |
453 | return error; | 445 | return error; |
454 | } | 446 | } |
455 | EXPORT_SYMBOL_GPL(nfs_setattr); | ||
456 | 447 | ||
457 | /** | 448 | /** |
458 | * nfs_vmtruncate - unmap mappings "freed" by truncate() syscall | 449 | * nfs_vmtruncate - unmap mappings "freed" by truncate() syscall |
@@ -511,7 +502,6 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) | |||
511 | nfs_vmtruncate(inode, attr->ia_size); | 502 | nfs_vmtruncate(inode, attr->ia_size); |
512 | } | 503 | } |
513 | } | 504 | } |
514 | EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); | ||
515 | 505 | ||
516 | int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 506 | int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
517 | { | 507 | { |
@@ -521,7 +511,6 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
521 | 511 | ||
522 | /* Flush out writes to the server in order to update c/mtime. */ | 512 | /* Flush out writes to the server in order to update c/mtime. */ |
523 | if (S_ISREG(inode->i_mode)) { | 513 | if (S_ISREG(inode->i_mode)) { |
524 | nfs_inode_dio_wait(inode); | ||
525 | err = filemap_write_and_wait(inode->i_mapping); | 514 | err = filemap_write_and_wait(inode->i_mapping); |
526 | if (err) | 515 | if (err) |
527 | goto out; | 516 | goto out; |
@@ -551,13 +540,12 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
551 | out: | 540 | out: |
552 | return err; | 541 | return err; |
553 | } | 542 | } |
554 | EXPORT_SYMBOL_GPL(nfs_getattr); | ||
555 | 543 | ||
556 | static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) | 544 | static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) |
557 | { | 545 | { |
558 | atomic_set(&l_ctx->count, 1); | 546 | atomic_set(&l_ctx->count, 1); |
559 | l_ctx->lockowner.l_owner = current->files; | 547 | l_ctx->lockowner = current->files; |
560 | l_ctx->lockowner.l_pid = current->tgid; | 548 | l_ctx->pid = current->tgid; |
561 | INIT_LIST_HEAD(&l_ctx->list); | 549 | INIT_LIST_HEAD(&l_ctx->list); |
562 | } | 550 | } |
563 | 551 | ||
@@ -566,9 +554,9 @@ static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context | |||
566 | struct nfs_lock_context *pos; | 554 | struct nfs_lock_context *pos; |
567 | 555 | ||
568 | list_for_each_entry(pos, &ctx->lock_context.list, list) { | 556 | list_for_each_entry(pos, &ctx->lock_context.list, list) { |
569 | if (pos->lockowner.l_owner != current->files) | 557 | if (pos->lockowner != current->files) |
570 | continue; | 558 | continue; |
571 | if (pos->lockowner.l_pid != current->tgid) | 559 | if (pos->pid != current->tgid) |
572 | continue; | 560 | continue; |
573 | atomic_inc(&pos->count); | 561 | atomic_inc(&pos->count); |
574 | return pos; | 562 | return pos; |
@@ -587,7 +575,7 @@ struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx) | |||
587 | spin_unlock(&inode->i_lock); | 575 | spin_unlock(&inode->i_lock); |
588 | new = kmalloc(sizeof(*new), GFP_KERNEL); | 576 | new = kmalloc(sizeof(*new), GFP_KERNEL); |
589 | if (new == NULL) | 577 | if (new == NULL) |
590 | return ERR_PTR(-ENOMEM); | 578 | return NULL; |
591 | nfs_init_lock_context(new); | 579 | nfs_init_lock_context(new); |
592 | spin_lock(&inode->i_lock); | 580 | spin_lock(&inode->i_lock); |
593 | res = __nfs_find_lock_context(ctx); | 581 | res = __nfs_find_lock_context(ctx); |
@@ -640,34 +628,26 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync) | |||
640 | return; | 628 | return; |
641 | nfs_revalidate_inode(server, inode); | 629 | nfs_revalidate_inode(server, inode); |
642 | } | 630 | } |
643 | EXPORT_SYMBOL_GPL(nfs_close_context); | ||
644 | 631 | ||
645 | struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode) | 632 | struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred, fmode_t f_mode) |
646 | { | 633 | { |
647 | struct nfs_open_context *ctx; | 634 | struct nfs_open_context *ctx; |
648 | struct rpc_cred *cred = rpc_lookup_cred(); | ||
649 | if (IS_ERR(cred)) | ||
650 | return ERR_CAST(cred); | ||
651 | 635 | ||
652 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | 636 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
653 | if (!ctx) { | 637 | if (ctx != NULL) { |
654 | put_rpccred(cred); | 638 | nfs_sb_active(dentry->d_sb); |
655 | return ERR_PTR(-ENOMEM); | 639 | ctx->dentry = dget(dentry); |
640 | ctx->cred = get_rpccred(cred); | ||
641 | ctx->state = NULL; | ||
642 | ctx->mode = f_mode; | ||
643 | ctx->flags = 0; | ||
644 | ctx->error = 0; | ||
645 | nfs_init_lock_context(&ctx->lock_context); | ||
646 | ctx->lock_context.open_context = ctx; | ||
647 | INIT_LIST_HEAD(&ctx->list); | ||
656 | } | 648 | } |
657 | nfs_sb_active(dentry->d_sb); | ||
658 | ctx->dentry = dget(dentry); | ||
659 | ctx->cred = cred; | ||
660 | ctx->state = NULL; | ||
661 | ctx->mode = f_mode; | ||
662 | ctx->flags = 0; | ||
663 | ctx->error = 0; | ||
664 | nfs_init_lock_context(&ctx->lock_context); | ||
665 | ctx->lock_context.open_context = ctx; | ||
666 | INIT_LIST_HEAD(&ctx->list); | ||
667 | ctx->mdsthreshold = NULL; | ||
668 | return ctx; | 649 | return ctx; |
669 | } | 650 | } |
670 | EXPORT_SYMBOL_GPL(alloc_nfs_open_context); | ||
671 | 651 | ||
672 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | 652 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) |
673 | { | 653 | { |
@@ -675,7 +655,6 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | |||
675 | atomic_inc(&ctx->lock_context.count); | 655 | atomic_inc(&ctx->lock_context.count); |
676 | return ctx; | 656 | return ctx; |
677 | } | 657 | } |
678 | EXPORT_SYMBOL_GPL(get_nfs_open_context); | ||
679 | 658 | ||
680 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) | 659 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) |
681 | { | 660 | { |
@@ -694,11 +673,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) | |||
694 | if (ctx->cred != NULL) | 673 | if (ctx->cred != NULL) |
695 | put_rpccred(ctx->cred); | 674 | put_rpccred(ctx->cred); |
696 | dput(ctx->dentry); | 675 | dput(ctx->dentry); |
697 | if (is_sync) | 676 | nfs_sb_deactive(sb); |
698 | nfs_sb_deactive(sb); | ||
699 | else | ||
700 | nfs_sb_deactive_async(sb); | ||
701 | kfree(ctx->mdsthreshold); | ||
702 | kfree(ctx); | 677 | kfree(ctx); |
703 | } | 678 | } |
704 | 679 | ||
@@ -706,7 +681,6 @@ void put_nfs_open_context(struct nfs_open_context *ctx) | |||
706 | { | 681 | { |
707 | __put_nfs_open_context(ctx, 0); | 682 | __put_nfs_open_context(ctx, 0); |
708 | } | 683 | } |
709 | EXPORT_SYMBOL_GPL(put_nfs_open_context); | ||
710 | 684 | ||
711 | /* | 685 | /* |
712 | * Ensure that mmap has a recent RPC credential for use when writing out | 686 | * Ensure that mmap has a recent RPC credential for use when writing out |
@@ -722,7 +696,6 @@ void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx) | |||
722 | list_add(&ctx->list, &nfsi->open_files); | 696 | list_add(&ctx->list, &nfsi->open_files); |
723 | spin_unlock(&inode->i_lock); | 697 | spin_unlock(&inode->i_lock); |
724 | } | 698 | } |
725 | EXPORT_SYMBOL_GPL(nfs_file_set_open_context); | ||
726 | 699 | ||
727 | /* | 700 | /* |
728 | * Given an inode, search for an open context with the desired characteristics | 701 | * Given an inode, search for an open context with the desired characteristics |
@@ -765,10 +738,15 @@ static void nfs_file_clear_open_context(struct file *filp) | |||
765 | int nfs_open(struct inode *inode, struct file *filp) | 738 | int nfs_open(struct inode *inode, struct file *filp) |
766 | { | 739 | { |
767 | struct nfs_open_context *ctx; | 740 | struct nfs_open_context *ctx; |
741 | struct rpc_cred *cred; | ||
768 | 742 | ||
769 | ctx = alloc_nfs_open_context(filp->f_path.dentry, filp->f_mode); | 743 | cred = rpc_lookup_cred(); |
770 | if (IS_ERR(ctx)) | 744 | if (IS_ERR(cred)) |
771 | return PTR_ERR(ctx); | 745 | return PTR_ERR(cred); |
746 | ctx = alloc_nfs_open_context(filp->f_path.dentry, cred, filp->f_mode); | ||
747 | put_rpccred(cred); | ||
748 | if (ctx == NULL) | ||
749 | return -ENOMEM; | ||
772 | nfs_file_set_open_context(filp, ctx); | 750 | nfs_file_set_open_context(filp, ctx); |
773 | put_nfs_open_context(ctx); | 751 | put_nfs_open_context(ctx); |
774 | nfs_fscache_set_inode_cookie(inode, filp); | 752 | nfs_fscache_set_inode_cookie(inode, filp); |
@@ -867,7 +845,6 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
867 | return NFS_STALE(inode) ? -ESTALE : 0; | 845 | return NFS_STALE(inode) ? -ESTALE : 0; |
868 | return __nfs_revalidate_inode(server, inode); | 846 | return __nfs_revalidate_inode(server, inode); |
869 | } | 847 | } |
870 | EXPORT_SYMBOL_GPL(nfs_revalidate_inode); | ||
871 | 848 | ||
872 | static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping) | 849 | static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping) |
873 | { | 850 | { |
@@ -884,21 +861,12 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map | |||
884 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); | 861 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); |
885 | spin_unlock(&inode->i_lock); | 862 | spin_unlock(&inode->i_lock); |
886 | nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); | 863 | nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); |
887 | nfs_fscache_wait_on_invalidate(inode); | 864 | nfs_fscache_reset_inode_cookie(inode); |
888 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", | 865 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", |
889 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); | 866 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); |
890 | return 0; | 867 | return 0; |
891 | } | 868 | } |
892 | 869 | ||
893 | static bool nfs_mapping_need_revalidate_inode(struct inode *inode) | ||
894 | { | ||
895 | if (nfs_have_delegated_attributes(inode)) | ||
896 | return false; | ||
897 | return (NFS_I(inode)->cache_validity & NFS_INO_REVAL_PAGECACHE) | ||
898 | || nfs_attribute_timeout(inode) | ||
899 | || NFS_STALE(inode); | ||
900 | } | ||
901 | |||
902 | /** | 870 | /** |
903 | * nfs_revalidate_mapping - Revalidate the pagecache | 871 | * nfs_revalidate_mapping - Revalidate the pagecache |
904 | * @inode - pointer to host inode | 872 | * @inode - pointer to host inode |
@@ -909,11 +877,9 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | |||
909 | struct nfs_inode *nfsi = NFS_I(inode); | 877 | struct nfs_inode *nfsi = NFS_I(inode); |
910 | int ret = 0; | 878 | int ret = 0; |
911 | 879 | ||
912 | /* swapfiles are not supposed to be shared. */ | 880 | if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) |
913 | if (IS_SWAPFILE(inode)) | 881 | || nfs_attribute_cache_expired(inode) |
914 | goto out; | 882 | || NFS_STALE(inode)) { |
915 | |||
916 | if (nfs_mapping_need_revalidate_inode(inode)) { | ||
917 | ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode); | 883 | ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode); |
918 | if (ret < 0) | 884 | if (ret < 0) |
919 | goto out; | 885 | goto out; |
@@ -931,8 +897,8 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
931 | 897 | ||
932 | if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE) | 898 | if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE) |
933 | && (fattr->valid & NFS_ATTR_FATTR_CHANGE) | 899 | && (fattr->valid & NFS_ATTR_FATTR_CHANGE) |
934 | && inode->i_version == fattr->pre_change_attr) { | 900 | && nfsi->change_attr == fattr->pre_change_attr) { |
935 | inode->i_version = fattr->change_attr; | 901 | nfsi->change_attr = fattr->change_attr; |
936 | if (S_ISDIR(inode->i_mode)) | 902 | if (S_ISDIR(inode->i_mode)) |
937 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 903 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; |
938 | ret |= NFS_INO_INVALID_ATTR; | 904 | ret |= NFS_INO_INVALID_ATTR; |
@@ -960,10 +926,6 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
960 | i_size_write(inode, nfs_size_to_loff_t(fattr->size)); | 926 | i_size_write(inode, nfs_size_to_loff_t(fattr->size)); |
961 | ret |= NFS_INO_INVALID_ATTR; | 927 | ret |= NFS_INO_INVALID_ATTR; |
962 | } | 928 | } |
963 | |||
964 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) | ||
965 | nfs_fscache_invalidate(inode); | ||
966 | |||
967 | return ret; | 929 | return ret; |
968 | } | 930 | } |
969 | 931 | ||
@@ -983,8 +945,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
983 | unsigned long invalid = 0; | 945 | unsigned long invalid = 0; |
984 | 946 | ||
985 | 947 | ||
986 | if (nfs_have_delegated_attributes(inode)) | ||
987 | return 0; | ||
988 | /* Has the inode gone and changed behind our back? */ | 948 | /* Has the inode gone and changed behind our back? */ |
989 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) | 949 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) |
990 | return -EIO; | 950 | return -EIO; |
@@ -992,12 +952,12 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
992 | return -EIO; | 952 | return -EIO; |
993 | 953 | ||
994 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && | 954 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && |
995 | inode->i_version != fattr->change_attr) | 955 | nfsi->change_attr != fattr->change_attr) |
996 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; | 956 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; |
997 | 957 | ||
998 | /* Verify a few of the more important attributes */ | 958 | /* Verify a few of the more important attributes */ |
999 | if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime)) | 959 | if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime)) |
1000 | invalid |= NFS_INO_INVALID_ATTR; | 960 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; |
1001 | 961 | ||
1002 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) { | 962 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) { |
1003 | cur_size = i_size_read(inode); | 963 | cur_size = i_size_read(inode); |
@@ -1059,10 +1019,7 @@ void nfs_fattr_init(struct nfs_fattr *fattr) | |||
1059 | fattr->valid = 0; | 1019 | fattr->valid = 0; |
1060 | fattr->time_start = jiffies; | 1020 | fattr->time_start = jiffies; |
1061 | fattr->gencount = nfs_inc_attr_generation_counter(); | 1021 | fattr->gencount = nfs_inc_attr_generation_counter(); |
1062 | fattr->owner_name = NULL; | ||
1063 | fattr->group_name = NULL; | ||
1064 | } | 1022 | } |
1065 | EXPORT_SYMBOL_GPL(nfs_fattr_init); | ||
1066 | 1023 | ||
1067 | struct nfs_fattr *nfs_alloc_fattr(void) | 1024 | struct nfs_fattr *nfs_alloc_fattr(void) |
1068 | { | 1025 | { |
@@ -1073,7 +1030,6 @@ struct nfs_fattr *nfs_alloc_fattr(void) | |||
1073 | nfs_fattr_init(fattr); | 1030 | nfs_fattr_init(fattr); |
1074 | return fattr; | 1031 | return fattr; |
1075 | } | 1032 | } |
1076 | EXPORT_SYMBOL_GPL(nfs_alloc_fattr); | ||
1077 | 1033 | ||
1078 | struct nfs_fh *nfs_alloc_fhandle(void) | 1034 | struct nfs_fh *nfs_alloc_fhandle(void) |
1079 | { | 1035 | { |
@@ -1084,68 +1040,6 @@ struct nfs_fh *nfs_alloc_fhandle(void) | |||
1084 | fh->size = 0; | 1040 | fh->size = 0; |
1085 | return fh; | 1041 | return fh; |
1086 | } | 1042 | } |
1087 | EXPORT_SYMBOL_GPL(nfs_alloc_fhandle); | ||
1088 | |||
1089 | #ifdef NFS_DEBUG | ||
1090 | /* | ||
1091 | * _nfs_display_fhandle_hash - calculate the crc32 hash for the filehandle | ||
1092 | * in the same way that wireshark does | ||
1093 | * | ||
1094 | * @fh: file handle | ||
1095 | * | ||
1096 | * For debugging only. | ||
1097 | */ | ||
1098 | u32 _nfs_display_fhandle_hash(const struct nfs_fh *fh) | ||
1099 | { | ||
1100 | /* wireshark uses 32-bit AUTODIN crc and does a bitwise | ||
1101 | * not on the result */ | ||
1102 | return ~crc32(0xFFFFFFFF, &fh->data[0], fh->size); | ||
1103 | } | ||
1104 | |||
1105 | /* | ||
1106 | * _nfs_display_fhandle - display an NFS file handle on the console | ||
1107 | * | ||
1108 | * @fh: file handle to display | ||
1109 | * @caption: display caption | ||
1110 | * | ||
1111 | * For debugging only. | ||
1112 | */ | ||
1113 | void _nfs_display_fhandle(const struct nfs_fh *fh, const char *caption) | ||
1114 | { | ||
1115 | unsigned short i; | ||
1116 | |||
1117 | if (fh == NULL || fh->size == 0) { | ||
1118 | printk(KERN_DEFAULT "%s at %p is empty\n", caption, fh); | ||
1119 | return; | ||
1120 | } | ||
1121 | |||
1122 | printk(KERN_DEFAULT "%s at %p is %u bytes, crc: 0x%08x:\n", | ||
1123 | caption, fh, fh->size, _nfs_display_fhandle_hash(fh)); | ||
1124 | for (i = 0; i < fh->size; i += 16) { | ||
1125 | __be32 *pos = (__be32 *)&fh->data[i]; | ||
1126 | |||
1127 | switch ((fh->size - i - 1) >> 2) { | ||
1128 | case 0: | ||
1129 | printk(KERN_DEFAULT " %08x\n", | ||
1130 | be32_to_cpup(pos)); | ||
1131 | break; | ||
1132 | case 1: | ||
1133 | printk(KERN_DEFAULT " %08x %08x\n", | ||
1134 | be32_to_cpup(pos), be32_to_cpup(pos + 1)); | ||
1135 | break; | ||
1136 | case 2: | ||
1137 | printk(KERN_DEFAULT " %08x %08x %08x\n", | ||
1138 | be32_to_cpup(pos), be32_to_cpup(pos + 1), | ||
1139 | be32_to_cpup(pos + 2)); | ||
1140 | break; | ||
1141 | default: | ||
1142 | printk(KERN_DEFAULT " %08x %08x %08x %08x\n", | ||
1143 | be32_to_cpup(pos), be32_to_cpup(pos + 1), | ||
1144 | be32_to_cpup(pos + 2), be32_to_cpup(pos + 3)); | ||
1145 | } | ||
1146 | } | ||
1147 | } | ||
1148 | #endif | ||
1149 | 1043 | ||
1150 | /** | 1044 | /** |
1151 | * nfs_inode_attrs_need_update - check if the inode attributes need updating | 1045 | * nfs_inode_attrs_need_update - check if the inode attributes need updating |
@@ -1205,17 +1099,14 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1205 | 1099 | ||
1206 | return status; | 1100 | return status; |
1207 | } | 1101 | } |
1208 | EXPORT_SYMBOL_GPL(nfs_refresh_inode); | ||
1209 | 1102 | ||
1210 | static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) | 1103 | static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) |
1211 | { | 1104 | { |
1212 | struct nfs_inode *nfsi = NFS_I(inode); | 1105 | struct nfs_inode *nfsi = NFS_I(inode); |
1213 | 1106 | ||
1214 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; | 1107 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; |
1215 | if (S_ISDIR(inode->i_mode)) { | 1108 | if (S_ISDIR(inode->i_mode)) |
1216 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1109 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; |
1217 | nfs_fscache_invalidate(inode); | ||
1218 | } | ||
1219 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | 1110 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) |
1220 | return 0; | 1111 | return 0; |
1221 | return nfs_refresh_inode_locked(inode, fattr); | 1112 | return nfs_refresh_inode_locked(inode, fattr); |
@@ -1244,7 +1135,6 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1244 | spin_unlock(&inode->i_lock); | 1135 | spin_unlock(&inode->i_lock); |
1245 | return status; | 1136 | return status; |
1246 | } | 1137 | } |
1247 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); | ||
1248 | 1138 | ||
1249 | /** | 1139 | /** |
1250 | * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache | 1140 | * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache |
@@ -1273,7 +1163,7 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa | |||
1273 | } | 1163 | } |
1274 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && | 1164 | if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && |
1275 | (fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) { | 1165 | (fattr->valid & NFS_ATTR_FATTR_PRECHANGE) == 0) { |
1276 | fattr->pre_change_attr = inode->i_version; | 1166 | fattr->pre_change_attr = NFS_I(inode)->change_attr; |
1277 | fattr->valid |= NFS_ATTR_FATTR_PRECHANGE; | 1167 | fattr->valid |= NFS_ATTR_FATTR_PRECHANGE; |
1278 | } | 1168 | } |
1279 | if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 && | 1169 | if ((fattr->valid & NFS_ATTR_FATTR_CTIME) != 0 && |
@@ -1296,7 +1186,6 @@ out_noforce: | |||
1296 | spin_unlock(&inode->i_lock); | 1186 | spin_unlock(&inode->i_lock); |
1297 | return status; | 1187 | return status; |
1298 | } | 1188 | } |
1299 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc); | ||
1300 | 1189 | ||
1301 | /* | 1190 | /* |
1302 | * Many nfs protocol calls return the new file attributes after | 1191 | * Many nfs protocol calls return the new file attributes after |
@@ -1319,31 +1208,18 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1319 | unsigned long now = jiffies; | 1208 | unsigned long now = jiffies; |
1320 | unsigned long save_cache_validity; | 1209 | unsigned long save_cache_validity; |
1321 | 1210 | ||
1322 | dfprintk(VFS, "NFS: %s(%s/%ld fh_crc=0x%08x ct=%d info=0x%x)\n", | 1211 | dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", |
1323 | __func__, inode->i_sb->s_id, inode->i_ino, | 1212 | __func__, inode->i_sb->s_id, inode->i_ino, |
1324 | nfs_display_fhandle_hash(NFS_FH(inode)), | ||
1325 | atomic_read(&inode->i_count), fattr->valid); | 1213 | atomic_read(&inode->i_count), fattr->valid); |
1326 | 1214 | ||
1327 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) { | 1215 | if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid) |
1328 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" | 1216 | goto out_fileid; |
1329 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", | ||
1330 | NFS_SERVER(inode)->nfs_client->cl_hostname, | ||
1331 | inode->i_sb->s_id, (long long)nfsi->fileid, | ||
1332 | (long long)fattr->fileid); | ||
1333 | goto out_err; | ||
1334 | } | ||
1335 | 1217 | ||
1336 | /* | 1218 | /* |
1337 | * Make sure the inode's type hasn't changed. | 1219 | * Make sure the inode's type hasn't changed. |
1338 | */ | 1220 | */ |
1339 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) { | 1221 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) |
1340 | /* | 1222 | goto out_changed; |
1341 | * Big trouble! The inode has become a different object. | ||
1342 | */ | ||
1343 | printk(KERN_DEBUG "NFS: %s: inode %ld mode changed, %07o to %07o\n", | ||
1344 | __func__, inode->i_ino, inode->i_mode, fattr->mode); | ||
1345 | goto out_err; | ||
1346 | } | ||
1347 | 1223 | ||
1348 | server = NFS_SERVER(inode); | 1224 | server = NFS_SERVER(inode); |
1349 | /* Update the fsid? */ | 1225 | /* Update the fsid? */ |
@@ -1368,31 +1244,50 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1368 | 1244 | ||
1369 | /* More cache consistency checks */ | 1245 | /* More cache consistency checks */ |
1370 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) { | 1246 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) { |
1371 | if (inode->i_version != fattr->change_attr) { | 1247 | if (nfsi->change_attr != fattr->change_attr) { |
1372 | dprintk("NFS: change_attr change on server for file %s/%ld\n", | 1248 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
1373 | inode->i_sb->s_id, inode->i_ino); | 1249 | inode->i_sb->s_id, inode->i_ino); |
1374 | invalid |= NFS_INO_INVALID_ATTR | 1250 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1375 | | NFS_INO_INVALID_DATA | ||
1376 | | NFS_INO_INVALID_ACCESS | ||
1377 | | NFS_INO_INVALID_ACL | ||
1378 | | NFS_INO_REVAL_PAGECACHE; | ||
1379 | if (S_ISDIR(inode->i_mode)) | 1251 | if (S_ISDIR(inode->i_mode)) |
1380 | nfs_force_lookup_revalidate(inode); | 1252 | nfs_force_lookup_revalidate(inode); |
1381 | inode->i_version = fattr->change_attr; | 1253 | nfsi->change_attr = fattr->change_attr; |
1382 | } | 1254 | } |
1383 | } else if (server->caps & NFS_CAP_CHANGE_ATTR) | 1255 | } else if (server->caps & NFS_CAP_CHANGE_ATTR) |
1384 | invalid |= save_cache_validity; | 1256 | invalid |= save_cache_validity; |
1385 | 1257 | ||
1386 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) { | 1258 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) { |
1387 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1259 | /* NFSv2/v3: Check if the mtime agrees */ |
1260 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { | ||
1261 | dprintk("NFS: mtime change on server for file %s/%ld\n", | ||
1262 | inode->i_sb->s_id, inode->i_ino); | ||
1263 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | ||
1264 | if (S_ISDIR(inode->i_mode)) | ||
1265 | nfs_force_lookup_revalidate(inode); | ||
1266 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | ||
1267 | } | ||
1388 | } else if (server->caps & NFS_CAP_MTIME) | 1268 | } else if (server->caps & NFS_CAP_MTIME) |
1389 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | 1269 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR |
1270 | | NFS_INO_INVALID_DATA | ||
1271 | | NFS_INO_REVAL_PAGECACHE | ||
1390 | | NFS_INO_REVAL_FORCED); | 1272 | | NFS_INO_REVAL_FORCED); |
1391 | 1273 | ||
1392 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) { | 1274 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) { |
1393 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | 1275 | /* If ctime has changed we should definitely clear access+acl caches */ |
1276 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { | ||
1277 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | ||
1278 | /* and probably clear data for a directory too as utimes can cause | ||
1279 | * havoc with our cache. | ||
1280 | */ | ||
1281 | if (S_ISDIR(inode->i_mode)) { | ||
1282 | invalid |= NFS_INO_INVALID_DATA; | ||
1283 | nfs_force_lookup_revalidate(inode); | ||
1284 | } | ||
1285 | memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); | ||
1286 | } | ||
1394 | } else if (server->caps & NFS_CAP_CTIME) | 1287 | } else if (server->caps & NFS_CAP_CTIME) |
1395 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | 1288 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR |
1289 | | NFS_INO_INVALID_ACCESS | ||
1290 | | NFS_INO_INVALID_ACL | ||
1396 | | NFS_INO_REVAL_FORCED); | 1291 | | NFS_INO_REVAL_FORCED); |
1397 | 1292 | ||
1398 | /* Check if our cached file size is stale */ | 1293 | /* Check if our cached file size is stale */ |
@@ -1466,7 +1361,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1466 | invalid |= NFS_INO_INVALID_ATTR; | 1361 | invalid |= NFS_INO_INVALID_ATTR; |
1467 | if (S_ISDIR(inode->i_mode)) | 1362 | if (S_ISDIR(inode->i_mode)) |
1468 | invalid |= NFS_INO_INVALID_DATA; | 1363 | invalid |= NFS_INO_INVALID_DATA; |
1469 | set_nlink(inode, fattr->nlink); | 1364 | inode->i_nlink = fattr->nlink; |
1470 | } | 1365 | } |
1471 | } else if (server->caps & NFS_CAP_NLINK) | 1366 | } else if (server->caps & NFS_CAP_NLINK) |
1472 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR | 1367 | invalid |= save_cache_validity & (NFS_INO_INVALID_ATTR |
@@ -1499,14 +1394,17 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1499 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1394 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1500 | || S_ISLNK(inode->i_mode))) | 1395 | || S_ISLNK(inode->i_mode))) |
1501 | invalid &= ~NFS_INO_INVALID_DATA; | 1396 | invalid &= ~NFS_INO_INVALID_DATA; |
1502 | if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) || | 1397 | if (!nfs_have_delegation(inode, FMODE_READ) || |
1503 | (save_cache_validity & NFS_INO_REVAL_FORCED)) | 1398 | (save_cache_validity & NFS_INO_REVAL_FORCED)) |
1504 | nfsi->cache_validity |= invalid; | 1399 | nfsi->cache_validity |= invalid; |
1505 | 1400 | ||
1506 | if (invalid & NFS_INO_INVALID_DATA) | ||
1507 | nfs_fscache_invalidate(inode); | ||
1508 | |||
1509 | return 0; | 1401 | return 0; |
1402 | out_changed: | ||
1403 | /* | ||
1404 | * Big trouble! The inode has become a different object. | ||
1405 | */ | ||
1406 | printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", | ||
1407 | __func__, inode->i_ino, inode->i_mode, fattr->mode); | ||
1510 | out_err: | 1408 | out_err: |
1511 | /* | 1409 | /* |
1512 | * No need to worry about unhashing the dentry, as the | 1410 | * No need to worry about unhashing the dentry, as the |
@@ -1515,7 +1413,35 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1515 | */ | 1413 | */ |
1516 | nfs_invalidate_inode(inode); | 1414 | nfs_invalidate_inode(inode); |
1517 | return -ESTALE; | 1415 | return -ESTALE; |
1416 | |||
1417 | out_fileid: | ||
1418 | printk(KERN_ERR "NFS: server %s error: fileid changed\n" | ||
1419 | "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n", | ||
1420 | NFS_SERVER(inode)->nfs_client->cl_hostname, inode->i_sb->s_id, | ||
1421 | (long long)nfsi->fileid, (long long)fattr->fileid); | ||
1422 | goto out_err; | ||
1423 | } | ||
1424 | |||
1425 | |||
1426 | #ifdef CONFIG_NFS_V4 | ||
1427 | |||
1428 | /* | ||
1429 | * Clean out any remaining NFSv4 state that might be left over due | ||
1430 | * to open() calls that passed nfs_atomic_lookup, but failed to call | ||
1431 | * nfs_open(). | ||
1432 | */ | ||
1433 | void nfs4_evict_inode(struct inode *inode) | ||
1434 | { | ||
1435 | truncate_inode_pages(&inode->i_data, 0); | ||
1436 | end_writeback(inode); | ||
1437 | pnfs_return_layout(inode); | ||
1438 | pnfs_destroy_layout(NFS_I(inode)); | ||
1439 | /* If we are holding a delegation, return it! */ | ||
1440 | nfs_inode_return_delegation_noreclaim(inode); | ||
1441 | /* First call standard NFS clear_inode() code */ | ||
1442 | nfs_clear_inode(inode); | ||
1518 | } | 1443 | } |
1444 | #endif | ||
1519 | 1445 | ||
1520 | struct inode *nfs_alloc_inode(struct super_block *sb) | 1446 | struct inode *nfs_alloc_inode(struct super_block *sb) |
1521 | { | 1447 | { |
@@ -1529,16 +1455,16 @@ struct inode *nfs_alloc_inode(struct super_block *sb) | |||
1529 | nfsi->acl_access = ERR_PTR(-EAGAIN); | 1455 | nfsi->acl_access = ERR_PTR(-EAGAIN); |
1530 | nfsi->acl_default = ERR_PTR(-EAGAIN); | 1456 | nfsi->acl_default = ERR_PTR(-EAGAIN); |
1531 | #endif | 1457 | #endif |
1532 | #if IS_ENABLED(CONFIG_NFS_V4) | 1458 | #ifdef CONFIG_NFS_V4 |
1533 | nfsi->nfs4_acl = NULL; | 1459 | nfsi->nfs4_acl = NULL; |
1534 | #endif /* CONFIG_NFS_V4 */ | 1460 | #endif /* CONFIG_NFS_V4 */ |
1535 | return &nfsi->vfs_inode; | 1461 | return &nfsi->vfs_inode; |
1536 | } | 1462 | } |
1537 | EXPORT_SYMBOL_GPL(nfs_alloc_inode); | ||
1538 | 1463 | ||
1539 | static void nfs_i_callback(struct rcu_head *head) | 1464 | static void nfs_i_callback(struct rcu_head *head) |
1540 | { | 1465 | { |
1541 | struct inode *inode = container_of(head, struct inode, i_rcu); | 1466 | struct inode *inode = container_of(head, struct inode, i_rcu); |
1467 | INIT_LIST_HEAD(&inode->i_dentry); | ||
1542 | kmem_cache_free(nfs_inode_cachep, NFS_I(inode)); | 1468 | kmem_cache_free(nfs_inode_cachep, NFS_I(inode)); |
1543 | } | 1469 | } |
1544 | 1470 | ||
@@ -1546,16 +1472,16 @@ void nfs_destroy_inode(struct inode *inode) | |||
1546 | { | 1472 | { |
1547 | call_rcu(&inode->i_rcu, nfs_i_callback); | 1473 | call_rcu(&inode->i_rcu, nfs_i_callback); |
1548 | } | 1474 | } |
1549 | EXPORT_SYMBOL_GPL(nfs_destroy_inode); | ||
1550 | 1475 | ||
1551 | static inline void nfs4_init_once(struct nfs_inode *nfsi) | 1476 | static inline void nfs4_init_once(struct nfs_inode *nfsi) |
1552 | { | 1477 | { |
1553 | #if IS_ENABLED(CONFIG_NFS_V4) | 1478 | #ifdef CONFIG_NFS_V4 |
1554 | INIT_LIST_HEAD(&nfsi->open_states); | 1479 | INIT_LIST_HEAD(&nfsi->open_states); |
1555 | nfsi->delegation = NULL; | 1480 | nfsi->delegation = NULL; |
1556 | nfsi->delegation_state = 0; | 1481 | nfsi->delegation_state = 0; |
1557 | init_rwsem(&nfsi->rwsem); | 1482 | init_rwsem(&nfsi->rwsem); |
1558 | nfsi->layout = NULL; | 1483 | nfsi->layout = NULL; |
1484 | atomic_set(&nfsi->commits_outstanding, 0); | ||
1559 | #endif | 1485 | #endif |
1560 | } | 1486 | } |
1561 | 1487 | ||
@@ -1567,10 +1493,9 @@ static void init_once(void *foo) | |||
1567 | INIT_LIST_HEAD(&nfsi->open_files); | 1493 | INIT_LIST_HEAD(&nfsi->open_files); |
1568 | INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); | 1494 | INIT_LIST_HEAD(&nfsi->access_cache_entry_lru); |
1569 | INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); | 1495 | INIT_LIST_HEAD(&nfsi->access_cache_inode_lru); |
1570 | INIT_LIST_HEAD(&nfsi->commit_info.list); | 1496 | INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC); |
1571 | nfsi->npages = 0; | 1497 | nfsi->npages = 0; |
1572 | nfsi->commit_info.ncommit = 0; | 1498 | nfsi->ncommit = 0; |
1573 | atomic_set(&nfsi->commit_info.rpcs_out, 0); | ||
1574 | atomic_set(&nfsi->silly_count, 1); | 1499 | atomic_set(&nfsi->silly_count, 1); |
1575 | INIT_HLIST_HEAD(&nfsi->silly_list); | 1500 | INIT_HLIST_HEAD(&nfsi->silly_list); |
1576 | init_waitqueue_head(&nfsi->waitqueue); | 1501 | init_waitqueue_head(&nfsi->waitqueue); |
@@ -1592,16 +1517,10 @@ static int __init nfs_init_inodecache(void) | |||
1592 | 1517 | ||
1593 | static void nfs_destroy_inodecache(void) | 1518 | static void nfs_destroy_inodecache(void) |
1594 | { | 1519 | { |
1595 | /* | ||
1596 | * Make sure all delayed rcu free inodes are flushed before we | ||
1597 | * destroy cache. | ||
1598 | */ | ||
1599 | rcu_barrier(); | ||
1600 | kmem_cache_destroy(nfs_inode_cachep); | 1520 | kmem_cache_destroy(nfs_inode_cachep); |
1601 | } | 1521 | } |
1602 | 1522 | ||
1603 | struct workqueue_struct *nfsiod_workqueue; | 1523 | struct workqueue_struct *nfsiod_workqueue; |
1604 | EXPORT_SYMBOL_GPL(nfsiod_workqueue); | ||
1605 | 1524 | ||
1606 | /* | 1525 | /* |
1607 | * start up the nfsiod workqueue | 1526 | * start up the nfsiod workqueue |
@@ -1631,28 +1550,6 @@ static void nfsiod_stop(void) | |||
1631 | destroy_workqueue(wq); | 1550 | destroy_workqueue(wq); |
1632 | } | 1551 | } |
1633 | 1552 | ||
1634 | int nfs_net_id; | ||
1635 | EXPORT_SYMBOL_GPL(nfs_net_id); | ||
1636 | |||
1637 | static int nfs_net_init(struct net *net) | ||
1638 | { | ||
1639 | nfs_clients_init(net); | ||
1640 | return nfs_dns_resolver_cache_init(net); | ||
1641 | } | ||
1642 | |||
1643 | static void nfs_net_exit(struct net *net) | ||
1644 | { | ||
1645 | nfs_dns_resolver_cache_destroy(net); | ||
1646 | nfs_cleanup_cb_ident_idr(net); | ||
1647 | } | ||
1648 | |||
1649 | static struct pernet_operations nfs_net_ops = { | ||
1650 | .init = nfs_net_init, | ||
1651 | .exit = nfs_net_exit, | ||
1652 | .id = &nfs_net_id, | ||
1653 | .size = sizeof(struct nfs_net), | ||
1654 | }; | ||
1655 | |||
1656 | /* | 1553 | /* |
1657 | * Initialize NFS | 1554 | * Initialize NFS |
1658 | */ | 1555 | */ |
@@ -1660,77 +1557,76 @@ static int __init init_nfs_fs(void) | |||
1660 | { | 1557 | { |
1661 | int err; | 1558 | int err; |
1662 | 1559 | ||
1663 | err = nfs_dns_resolver_init(); | 1560 | err = nfs_idmap_init(); |
1664 | if (err < 0) | 1561 | if (err < 0) |
1665 | goto out10;; | 1562 | goto out9; |
1666 | 1563 | ||
1667 | err = register_pernet_subsys(&nfs_net_ops); | 1564 | err = nfs_dns_resolver_init(); |
1668 | if (err < 0) | 1565 | if (err < 0) |
1669 | goto out9; | 1566 | goto out8; |
1670 | 1567 | ||
1671 | err = nfs_fscache_register(); | 1568 | err = nfs_fscache_register(); |
1672 | if (err < 0) | 1569 | if (err < 0) |
1673 | goto out8; | 1570 | goto out7; |
1674 | 1571 | ||
1675 | err = nfsiod_start(); | 1572 | err = nfsiod_start(); |
1676 | if (err) | 1573 | if (err) |
1677 | goto out7; | 1574 | goto out6; |
1678 | 1575 | ||
1679 | err = nfs_fs_proc_init(); | 1576 | err = nfs_fs_proc_init(); |
1680 | if (err) | 1577 | if (err) |
1681 | goto out6; | 1578 | goto out5; |
1682 | 1579 | ||
1683 | err = nfs_init_nfspagecache(); | 1580 | err = nfs_init_nfspagecache(); |
1684 | if (err) | 1581 | if (err) |
1685 | goto out5; | 1582 | goto out4; |
1686 | 1583 | ||
1687 | err = nfs_init_inodecache(); | 1584 | err = nfs_init_inodecache(); |
1688 | if (err) | 1585 | if (err) |
1689 | goto out4; | 1586 | goto out3; |
1690 | 1587 | ||
1691 | err = nfs_init_readpagecache(); | 1588 | err = nfs_init_readpagecache(); |
1692 | if (err) | 1589 | if (err) |
1693 | goto out3; | 1590 | goto out2; |
1694 | 1591 | ||
1695 | err = nfs_init_writepagecache(); | 1592 | err = nfs_init_writepagecache(); |
1696 | if (err) | 1593 | if (err) |
1697 | goto out2; | 1594 | goto out1; |
1698 | 1595 | ||
1699 | err = nfs_init_directcache(); | 1596 | err = nfs_init_directcache(); |
1700 | if (err) | 1597 | if (err) |
1701 | goto out1; | 1598 | goto out0; |
1702 | 1599 | ||
1703 | #ifdef CONFIG_PROC_FS | 1600 | #ifdef CONFIG_PROC_FS |
1704 | rpc_proc_register(&init_net, &nfs_rpcstat); | 1601 | rpc_proc_register(&nfs_rpcstat); |
1705 | #endif | 1602 | #endif |
1706 | if ((err = register_nfs_fs()) != 0) | 1603 | if ((err = register_nfs_fs()) != 0) |
1707 | goto out0; | 1604 | goto out; |
1708 | |||
1709 | return 0; | 1605 | return 0; |
1710 | out0: | 1606 | out: |
1711 | #ifdef CONFIG_PROC_FS | 1607 | #ifdef CONFIG_PROC_FS |
1712 | rpc_proc_unregister(&init_net, "nfs"); | 1608 | rpc_proc_unregister("nfs"); |
1713 | #endif | 1609 | #endif |
1714 | nfs_destroy_directcache(); | 1610 | nfs_destroy_directcache(); |
1715 | out1: | 1611 | out0: |
1716 | nfs_destroy_writepagecache(); | 1612 | nfs_destroy_writepagecache(); |
1717 | out2: | 1613 | out1: |
1718 | nfs_destroy_readpagecache(); | 1614 | nfs_destroy_readpagecache(); |
1719 | out3: | 1615 | out2: |
1720 | nfs_destroy_inodecache(); | 1616 | nfs_destroy_inodecache(); |
1721 | out4: | 1617 | out3: |
1722 | nfs_destroy_nfspagecache(); | 1618 | nfs_destroy_nfspagecache(); |
1723 | out5: | 1619 | out4: |
1724 | nfs_fs_proc_exit(); | 1620 | nfs_fs_proc_exit(); |
1725 | out6: | 1621 | out5: |
1726 | nfsiod_stop(); | 1622 | nfsiod_stop(); |
1727 | out7: | 1623 | out6: |
1728 | nfs_fscache_unregister(); | 1624 | nfs_fscache_unregister(); |
1625 | out7: | ||
1626 | nfs_dns_resolver_destroy(); | ||
1729 | out8: | 1627 | out8: |
1730 | unregister_pernet_subsys(&nfs_net_ops); | 1628 | nfs_idmap_quit(); |
1731 | out9: | 1629 | out9: |
1732 | nfs_dns_resolver_destroy(); | ||
1733 | out10: | ||
1734 | return err; | 1630 | return err; |
1735 | } | 1631 | } |
1736 | 1632 | ||
@@ -1742,11 +1638,12 @@ static void __exit exit_nfs_fs(void) | |||
1742 | nfs_destroy_inodecache(); | 1638 | nfs_destroy_inodecache(); |
1743 | nfs_destroy_nfspagecache(); | 1639 | nfs_destroy_nfspagecache(); |
1744 | nfs_fscache_unregister(); | 1640 | nfs_fscache_unregister(); |
1745 | unregister_pernet_subsys(&nfs_net_ops); | ||
1746 | nfs_dns_resolver_destroy(); | 1641 | nfs_dns_resolver_destroy(); |
1642 | nfs_idmap_quit(); | ||
1747 | #ifdef CONFIG_PROC_FS | 1643 | #ifdef CONFIG_PROC_FS |
1748 | rpc_proc_unregister(&init_net, "nfs"); | 1644 | rpc_proc_unregister("nfs"); |
1749 | #endif | 1645 | #endif |
1646 | nfs_cleanup_cb_ident_idr(); | ||
1750 | unregister_nfs_fs(); | 1647 | unregister_nfs_fs(); |
1751 | nfs_fs_proc_exit(); | 1648 | nfs_fs_proc_exit(); |
1752 | nfsiod_stop(); | 1649 | nfsiod_stop(); |