diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 12e8ad85ae50..f908af672197 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -162,11 +162,19 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
162 | 162 | ||
163 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); | 163 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); |
164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { | 164 | 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; | ||
166 | nfs_fscache_invalidate(inode); | 165 | nfs_fscache_invalidate(inode); |
167 | } else { | 166 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR |
168 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 167 | | NFS_INO_INVALID_LABEL |
169 | } | 168 | | NFS_INO_INVALID_DATA |
169 | | NFS_INO_INVALID_ACCESS | ||
170 | | NFS_INO_INVALID_ACL | ||
171 | | NFS_INO_REVAL_PAGECACHE; | ||
172 | } else | ||
173 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
174 | | NFS_INO_INVALID_LABEL | ||
175 | | NFS_INO_INVALID_ACCESS | ||
176 | | NFS_INO_INVALID_ACL | ||
177 | | NFS_INO_REVAL_PAGECACHE; | ||
170 | } | 178 | } |
171 | 179 | ||
172 | void nfs_zap_caches(struct inode *inode) | 180 | void nfs_zap_caches(struct inode *inode) |
@@ -258,6 +266,32 @@ nfs_init_locked(struct inode *inode, void *opaque) | |||
258 | } | 266 | } |
259 | 267 | ||
260 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL | 268 | #ifdef CONFIG_NFS_V4_SECURITY_LABEL |
269 | void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | ||
270 | struct nfs4_label *label) | ||
271 | { | ||
272 | int error; | ||
273 | |||
274 | if (label == NULL) | ||
275 | return; | ||
276 | |||
277 | if (nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL) == 0) | ||
278 | return; | ||
279 | |||
280 | if (NFS_SERVER(inode)->nfs_client->cl_minorversion < 2) | ||
281 | return; | ||
282 | |||
283 | if ((fattr->valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL) && inode->i_security) { | ||
284 | error = security_inode_notifysecctx(inode, label->label, | ||
285 | label->len); | ||
286 | if (error) | ||
287 | printk(KERN_ERR "%s() %s %d " | ||
288 | "security_inode_notifysecctx() %d\n", | ||
289 | __func__, | ||
290 | (char *)label->label, | ||
291 | label->len, error); | ||
292 | } | ||
293 | } | ||
294 | |||
261 | struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) | 295 | struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) |
262 | { | 296 | { |
263 | struct nfs4_label *label = NULL; | 297 | struct nfs4_label *label = NULL; |
@@ -283,7 +317,13 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) | |||
283 | return label; | 317 | return label; |
284 | } | 318 | } |
285 | EXPORT_SYMBOL_GPL(nfs4_label_alloc); | 319 | EXPORT_SYMBOL_GPL(nfs4_label_alloc); |
320 | #else | ||
321 | void inline nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, | ||
322 | struct nfs4_label *label) | ||
323 | { | ||
324 | } | ||
286 | #endif | 325 | #endif |
326 | EXPORT_SYMBOL_GPL(nfs_setsecurity); | ||
287 | 327 | ||
288 | /* | 328 | /* |
289 | * This is our front-end to iget that looks up inodes by file handle | 329 | * This is our front-end to iget that looks up inodes by file handle |
@@ -412,6 +452,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
412 | */ | 452 | */ |
413 | inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); | 453 | inode->i_blocks = nfs_calc_block_size(fattr->du.nfs3.used); |
414 | } | 454 | } |
455 | |||
456 | nfs_setsecurity(inode, fattr, label); | ||
457 | |||
415 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 458 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
416 | nfsi->attrtimeo_timestamp = now; | 459 | nfsi->attrtimeo_timestamp = now; |
417 | nfsi->access_cache = RB_ROOT; | 460 | nfsi->access_cache = RB_ROOT; |
@@ -421,6 +464,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
421 | unlock_new_inode(inode); | 464 | unlock_new_inode(inode); |
422 | } else | 465 | } else |
423 | nfs_refresh_inode(inode, fattr); | 466 | nfs_refresh_inode(inode, fattr); |
467 | nfs_setsecurity(inode, fattr, label); | ||
424 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", | 468 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", |
425 | inode->i_sb->s_id, | 469 | inode->i_sb->s_id, |
426 | (long long)NFS_FILEID(inode), | 470 | (long long)NFS_FILEID(inode), |
@@ -477,7 +521,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
477 | NFS_PROTO(inode)->return_delegation(inode); | 521 | NFS_PROTO(inode)->return_delegation(inode); |
478 | error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); | 522 | error = NFS_PROTO(inode)->setattr(dentry, fattr, attr); |
479 | if (error == 0) | 523 | if (error == 0) |
480 | nfs_refresh_inode(inode, fattr); | 524 | error = nfs_refresh_inode(inode, fattr); |
481 | nfs_free_fattr(fattr); | 525 | nfs_free_fattr(fattr); |
482 | out: | 526 | out: |
483 | return error; | 527 | return error; |
@@ -901,7 +945,8 @@ static int nfs_attribute_cache_expired(struct inode *inode) | |||
901 | */ | 945 | */ |
902 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | 946 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) |
903 | { | 947 | { |
904 | if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR) | 948 | if (!(NFS_I(inode)->cache_validity & |
949 | (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) | ||
905 | && !nfs_attribute_cache_expired(inode)) | 950 | && !nfs_attribute_cache_expired(inode)) |
906 | return NFS_STALE(inode) ? -ESTALE : 0; | 951 | return NFS_STALE(inode) ? -ESTALE : 0; |
907 | return __nfs_revalidate_inode(server, inode); | 952 | return __nfs_revalidate_inode(server, inode); |
@@ -1281,6 +1326,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1281 | spin_lock(&inode->i_lock); | 1326 | spin_lock(&inode->i_lock); |
1282 | status = nfs_post_op_update_inode_locked(inode, fattr); | 1327 | status = nfs_post_op_update_inode_locked(inode, fattr); |
1283 | spin_unlock(&inode->i_lock); | 1328 | spin_unlock(&inode->i_lock); |
1329 | |||
1284 | return status; | 1330 | return status; |
1285 | } | 1331 | } |
1286 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); | 1332 | EXPORT_SYMBOL_GPL(nfs_post_op_update_inode); |
@@ -1521,7 +1567,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1521 | inode->i_blocks = fattr->du.nfs2.blocks; | 1567 | inode->i_blocks = fattr->du.nfs2.blocks; |
1522 | 1568 | ||
1523 | /* Update attrtimeo value if we're out of the unstable period */ | 1569 | /* Update attrtimeo value if we're out of the unstable period */ |
1524 | if (invalid & NFS_INO_INVALID_ATTR) { | 1570 | if (invalid & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL)) { |
1525 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); | 1571 | nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE); |
1526 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 1572 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
1527 | nfsi->attrtimeo_timestamp = now; | 1573 | nfsi->attrtimeo_timestamp = now; |
@@ -1534,6 +1580,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1534 | } | 1580 | } |
1535 | } | 1581 | } |
1536 | invalid &= ~NFS_INO_INVALID_ATTR; | 1582 | invalid &= ~NFS_INO_INVALID_ATTR; |
1583 | invalid &= ~NFS_INO_INVALID_LABEL; | ||
1537 | /* Don't invalidate the data if we were to blame */ | 1584 | /* Don't invalidate the data if we were to blame */ |
1538 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) | 1585 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
1539 | || S_ISLNK(inode->i_mode))) | 1586 | || S_ISLNK(inode->i_mode))) |