aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c75
1 files changed, 42 insertions, 33 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index c933bdfbcb1f..0fac2cb1ea18 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -437,6 +437,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
437 struct dentry *alias; 437 struct dentry *alias;
438 struct inode *dir = parent->d_inode; 438 struct inode *dir = parent->d_inode;
439 struct inode *inode; 439 struct inode *inode;
440 int status;
440 441
441 if (filename.name[0] == '.') { 442 if (filename.name[0] == '.') {
442 if (filename.len == 1) 443 if (filename.len == 1)
@@ -449,7 +450,9 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
449 dentry = d_lookup(parent, &filename); 450 dentry = d_lookup(parent, &filename);
450 if (dentry != NULL) { 451 if (dentry != NULL) {
451 if (nfs_same_file(dentry, entry)) { 452 if (nfs_same_file(dentry, entry)) {
452 nfs_refresh_inode(dentry->d_inode, entry->fattr); 453 status = nfs_refresh_inode(dentry->d_inode, entry->fattr);
454 if (!status)
455 nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label);
453 goto out; 456 goto out;
454 } else { 457 } else {
455 if (d_invalidate(dentry) != 0) 458 if (d_invalidate(dentry) != 0)
@@ -462,7 +465,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
462 if (dentry == NULL) 465 if (dentry == NULL)
463 return; 466 return;
464 467
465 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); 468 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label);
466 if (IS_ERR(inode)) 469 if (IS_ERR(inode))
467 goto out; 470 goto out;
468 471
@@ -587,10 +590,16 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
587 if (entry.fh == NULL || entry.fattr == NULL) 590 if (entry.fh == NULL || entry.fattr == NULL)
588 goto out; 591 goto out;
589 592
593 entry.label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
594 if (IS_ERR(entry.label)) {
595 status = PTR_ERR(entry.label);
596 goto out;
597 }
598
590 array = nfs_readdir_get_array(page); 599 array = nfs_readdir_get_array(page);
591 if (IS_ERR(array)) { 600 if (IS_ERR(array)) {
592 status = PTR_ERR(array); 601 status = PTR_ERR(array);
593 goto out; 602 goto out_label_free;
594 } 603 }
595 memset(array, 0, sizeof(struct nfs_cache_array)); 604 memset(array, 0, sizeof(struct nfs_cache_array));
596 array->eof_index = -1; 605 array->eof_index = -1;
@@ -616,6 +625,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
616 nfs_readdir_free_large_page(pages_ptr, pages, array_size); 625 nfs_readdir_free_large_page(pages_ptr, pages, array_size);
617out_release_array: 626out_release_array:
618 nfs_readdir_release_array(page); 627 nfs_readdir_release_array(page);
628out_label_free:
629 nfs4_label_free(entry.label);
619out: 630out:
620 nfs_free_fattr(entry.fattr); 631 nfs_free_fattr(entry.fattr);
621 nfs_free_fhandle(entry.fh); 632 nfs_free_fhandle(entry.fh);
@@ -1040,6 +1051,7 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1040 struct dentry *parent; 1051 struct dentry *parent;
1041 struct nfs_fh *fhandle = NULL; 1052 struct nfs_fh *fhandle = NULL;
1042 struct nfs_fattr *fattr = NULL; 1053 struct nfs_fattr *fattr = NULL;
1054 struct nfs4_label *label = NULL;
1043 int error; 1055 int error;
1044 1056
1045 if (flags & LOOKUP_RCU) 1057 if (flags & LOOKUP_RCU)
@@ -1082,7 +1094,11 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1082 if (fhandle == NULL || fattr == NULL) 1094 if (fhandle == NULL || fattr == NULL)
1083 goto out_error; 1095 goto out_error;
1084 1096
1085 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1097 label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
1098 if (IS_ERR(label))
1099 goto out_error;
1100
1101 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1086 if (error) 1102 if (error)
1087 goto out_bad; 1103 goto out_bad;
1088 if (nfs_compare_fh(NFS_FH(inode), fhandle)) 1104 if (nfs_compare_fh(NFS_FH(inode), fhandle))
@@ -1090,8 +1106,12 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1090 if ((error = nfs_refresh_inode(inode, fattr)) != 0) 1106 if ((error = nfs_refresh_inode(inode, fattr)) != 0)
1091 goto out_bad; 1107 goto out_bad;
1092 1108
1109 nfs_setsecurity(inode, fattr, label);
1110
1093 nfs_free_fattr(fattr); 1111 nfs_free_fattr(fattr);
1094 nfs_free_fhandle(fhandle); 1112 nfs_free_fhandle(fhandle);
1113 nfs4_label_free(label);
1114
1095out_set_verifier: 1115out_set_verifier:
1096 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1116 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1097 out_valid: 1117 out_valid:
@@ -1108,6 +1128,7 @@ out_zap_parent:
1108 out_bad: 1128 out_bad:
1109 nfs_free_fattr(fattr); 1129 nfs_free_fattr(fattr);
1110 nfs_free_fhandle(fhandle); 1130 nfs_free_fhandle(fhandle);
1131 nfs4_label_free(label);
1111 nfs_mark_for_revalidate(dir); 1132 nfs_mark_for_revalidate(dir);
1112 if (inode && S_ISDIR(inode->i_mode)) { 1133 if (inode && S_ISDIR(inode->i_mode)) {
1113 /* Purge readdir caches. */ 1134 /* Purge readdir caches. */
@@ -1128,6 +1149,7 @@ out_zap_parent:
1128out_error: 1149out_error:
1129 nfs_free_fattr(fattr); 1150 nfs_free_fattr(fattr);
1130 nfs_free_fhandle(fhandle); 1151 nfs_free_fhandle(fhandle);
1152 nfs4_label_free(label);
1131 dput(parent); 1153 dput(parent);
1132 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n", 1154 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n",
1133 __func__, dentry->d_parent->d_name.name, 1155 __func__, dentry->d_parent->d_name.name,
@@ -1256,6 +1278,7 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
1256 struct inode *inode = NULL; 1278 struct inode *inode = NULL;
1257 struct nfs_fh *fhandle = NULL; 1279 struct nfs_fh *fhandle = NULL;
1258 struct nfs_fattr *fattr = NULL; 1280 struct nfs_fattr *fattr = NULL;
1281 struct nfs4_label *label = NULL;
1259 int error; 1282 int error;
1260 1283
1261 dfprintk(VFS, "NFS: lookup(%s/%s)\n", 1284 dfprintk(VFS, "NFS: lookup(%s/%s)\n",
@@ -1282,17 +1305,21 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
1282 if (fhandle == NULL || fattr == NULL) 1305 if (fhandle == NULL || fattr == NULL)
1283 goto out; 1306 goto out;
1284 1307
1308 label = nfs4_label_alloc(NFS_SERVER(dir), GFP_NOWAIT);
1309 if (IS_ERR(label))
1310 goto out;
1311
1285 parent = dentry->d_parent; 1312 parent = dentry->d_parent;
1286 /* Protect against concurrent sillydeletes */ 1313 /* Protect against concurrent sillydeletes */
1287 nfs_block_sillyrename(parent); 1314 nfs_block_sillyrename(parent);
1288 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1315 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1289 if (error == -ENOENT) 1316 if (error == -ENOENT)
1290 goto no_entry; 1317 goto no_entry;
1291 if (error < 0) { 1318 if (error < 0) {
1292 res = ERR_PTR(error); 1319 res = ERR_PTR(error);
1293 goto out_unblock_sillyrename; 1320 goto out_unblock_sillyrename;
1294 } 1321 }
1295 inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1322 inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
1296 res = ERR_CAST(inode); 1323 res = ERR_CAST(inode);
1297 if (IS_ERR(res)) 1324 if (IS_ERR(res))
1298 goto out_unblock_sillyrename; 1325 goto out_unblock_sillyrename;
@@ -1310,6 +1337,7 @@ no_entry:
1310 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1337 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1311out_unblock_sillyrename: 1338out_unblock_sillyrename:
1312 nfs_unblock_sillyrename(parent); 1339 nfs_unblock_sillyrename(parent);
1340 nfs4_label_free(label);
1313out: 1341out:
1314 nfs_free_fattr(fattr); 1342 nfs_free_fattr(fattr);
1315 nfs_free_fhandle(fhandle); 1343 nfs_free_fhandle(fhandle);
@@ -1357,18 +1385,6 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
1357{ 1385{
1358 int err; 1386 int err;
1359 1387
1360 if (ctx->dentry != dentry) {
1361 dput(ctx->dentry);
1362 ctx->dentry = dget(dentry);
1363 }
1364
1365 /* If the open_intent is for execute, we have an extra check to make */
1366 if (ctx->mode & FMODE_EXEC) {
1367 err = nfs_may_open(dentry->d_inode, ctx->cred, open_flags);
1368 if (err < 0)
1369 goto out;
1370 }
1371
1372 err = finish_open(file, dentry, do_open, opened); 1388 err = finish_open(file, dentry, do_open, opened);
1373 if (err) 1389 if (err)
1374 goto out; 1390 goto out;
@@ -1427,13 +1443,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1427 1443
1428 nfs_block_sillyrename(dentry->d_parent); 1444 nfs_block_sillyrename(dentry->d_parent);
1429 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); 1445 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr);
1430 d_drop(dentry); 1446 nfs_unblock_sillyrename(dentry->d_parent);
1431 if (IS_ERR(inode)) { 1447 if (IS_ERR(inode)) {
1432 nfs_unblock_sillyrename(dentry->d_parent);
1433 put_nfs_open_context(ctx); 1448 put_nfs_open_context(ctx);
1434 err = PTR_ERR(inode); 1449 err = PTR_ERR(inode);
1435 switch (err) { 1450 switch (err) {
1436 case -ENOENT: 1451 case -ENOENT:
1452 d_drop(dentry);
1437 d_add(dentry, NULL); 1453 d_add(dentry, NULL);
1438 break; 1454 break;
1439 case -EISDIR: 1455 case -EISDIR:
@@ -1449,16 +1465,8 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1449 } 1465 }
1450 goto out; 1466 goto out;
1451 } 1467 }
1452 res = d_add_unique(dentry, inode);
1453 if (res != NULL)
1454 dentry = res;
1455
1456 nfs_unblock_sillyrename(dentry->d_parent);
1457 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1458
1459 err = nfs_finish_open(ctx, dentry, file, open_flags, opened);
1460 1468
1461 dput(res); 1469 err = nfs_finish_open(ctx, ctx->dentry, file, open_flags, opened);
1462out: 1470out:
1463 return err; 1471 return err;
1464 1472
@@ -1528,7 +1536,8 @@ no_open:
1528 * Code common to create, mkdir, and mknod. 1536 * Code common to create, mkdir, and mknod.
1529 */ 1537 */
1530int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, 1538int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
1531 struct nfs_fattr *fattr) 1539 struct nfs_fattr *fattr,
1540 struct nfs4_label *label)
1532{ 1541{
1533 struct dentry *parent = dget_parent(dentry); 1542 struct dentry *parent = dget_parent(dentry);
1534 struct inode *dir = parent->d_inode; 1543 struct inode *dir = parent->d_inode;
@@ -1541,18 +1550,18 @@ int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
1541 if (dentry->d_inode) 1550 if (dentry->d_inode)
1542 goto out; 1551 goto out;
1543 if (fhandle->size == 0) { 1552 if (fhandle->size == 0) {
1544 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); 1553 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL);
1545 if (error) 1554 if (error)
1546 goto out_error; 1555 goto out_error;
1547 } 1556 }
1548 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1557 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1549 if (!(fattr->valid & NFS_ATTR_FATTR)) { 1558 if (!(fattr->valid & NFS_ATTR_FATTR)) {
1550 struct nfs_server *server = NFS_SB(dentry->d_sb); 1559 struct nfs_server *server = NFS_SB(dentry->d_sb);
1551 error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr); 1560 error = server->nfs_client->rpc_ops->getattr(server, fhandle, fattr, NULL);
1552 if (error < 0) 1561 if (error < 0)
1553 goto out_error; 1562 goto out_error;
1554 } 1563 }
1555 inode = nfs_fhget(dentry->d_sb, fhandle, fattr); 1564 inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
1556 error = PTR_ERR(inode); 1565 error = PTR_ERR(inode);
1557 if (IS_ERR(inode)) 1566 if (IS_ERR(inode))
1558 goto out_error; 1567 goto out_error;