diff options
Diffstat (limited to 'fs/ceph/dir.c')
| -rw-r--r-- | fs/ceph/dir.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index fd11fb231a2e..fadc243dfb28 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
| @@ -38,7 +38,7 @@ int ceph_init_dentry(struct dentry *dentry) | |||
| 38 | if (dentry->d_fsdata) | 38 | if (dentry->d_fsdata) |
| 39 | return 0; | 39 | return 0; |
| 40 | 40 | ||
| 41 | di = kmem_cache_alloc(ceph_dentry_cachep, GFP_KERNEL | __GFP_ZERO); | 41 | di = kmem_cache_zalloc(ceph_dentry_cachep, GFP_KERNEL); |
| 42 | if (!di) | 42 | if (!di) |
| 43 | return -ENOMEM; /* oh well */ | 43 | return -ENOMEM; /* oh well */ |
| 44 | 44 | ||
| @@ -68,23 +68,6 @@ out_unlock: | |||
| 68 | return 0; | 68 | return 0; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | struct inode *ceph_get_dentry_parent_inode(struct dentry *dentry) | ||
| 72 | { | ||
| 73 | struct inode *inode = NULL; | ||
| 74 | |||
| 75 | if (!dentry) | ||
| 76 | return NULL; | ||
| 77 | |||
| 78 | spin_lock(&dentry->d_lock); | ||
| 79 | if (!IS_ROOT(dentry)) { | ||
| 80 | inode = d_inode(dentry->d_parent); | ||
| 81 | ihold(inode); | ||
| 82 | } | ||
| 83 | spin_unlock(&dentry->d_lock); | ||
| 84 | return inode; | ||
| 85 | } | ||
| 86 | |||
| 87 | |||
| 88 | /* | 71 | /* |
| 89 | * for readdir, we encode the directory frag and offset within that | 72 | * for readdir, we encode the directory frag and offset within that |
| 90 | * frag into f_pos. | 73 | * frag into f_pos. |
| @@ -624,6 +607,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | |||
| 624 | struct ceph_mds_client *mdsc = fsc->mdsc; | 607 | struct ceph_mds_client *mdsc = fsc->mdsc; |
| 625 | struct ceph_mds_request *req; | 608 | struct ceph_mds_request *req; |
| 626 | int op; | 609 | int op; |
| 610 | int mask; | ||
| 627 | int err; | 611 | int err; |
| 628 | 612 | ||
| 629 | dout("lookup %p dentry %p '%pd'\n", | 613 | dout("lookup %p dentry %p '%pd'\n", |
| @@ -666,8 +650,12 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | |||
| 666 | return ERR_CAST(req); | 650 | return ERR_CAST(req); |
| 667 | req->r_dentry = dget(dentry); | 651 | req->r_dentry = dget(dentry); |
| 668 | req->r_num_caps = 2; | 652 | req->r_num_caps = 2; |
| 669 | /* we only need inode linkage */ | 653 | |
| 670 | req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); | 654 | mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED; |
| 655 | if (ceph_security_xattr_wanted(dir)) | ||
| 656 | mask |= CEPH_CAP_XATTR_SHARED; | ||
| 657 | req->r_args.getattr.mask = cpu_to_le32(mask); | ||
| 658 | |||
| 671 | req->r_locked_dir = dir; | 659 | req->r_locked_dir = dir; |
| 672 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 660 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
| 673 | err = ceph_handle_snapdir(req, dentry, err); | 661 | err = ceph_handle_snapdir(req, dentry, err); |
| @@ -1095,6 +1083,7 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry) | |||
| 1095 | static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) | 1083 | static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) |
| 1096 | { | 1084 | { |
| 1097 | int valid = 0; | 1085 | int valid = 0; |
| 1086 | struct dentry *parent; | ||
| 1098 | struct inode *dir; | 1087 | struct inode *dir; |
| 1099 | 1088 | ||
| 1100 | if (flags & LOOKUP_RCU) | 1089 | if (flags & LOOKUP_RCU) |
| @@ -1103,7 +1092,8 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
| 1103 | dout("d_revalidate %p '%pd' inode %p offset %lld\n", dentry, | 1092 | dout("d_revalidate %p '%pd' inode %p offset %lld\n", dentry, |
| 1104 | dentry, d_inode(dentry), ceph_dentry(dentry)->offset); | 1093 | dentry, d_inode(dentry), ceph_dentry(dentry)->offset); |
| 1105 | 1094 | ||
| 1106 | dir = ceph_get_dentry_parent_inode(dentry); | 1095 | parent = dget_parent(dentry); |
| 1096 | dir = d_inode(parent); | ||
| 1107 | 1097 | ||
| 1108 | /* always trust cached snapped dentries, snapdir dentry */ | 1098 | /* always trust cached snapped dentries, snapdir dentry */ |
| 1109 | if (ceph_snap(dir) != CEPH_NOSNAP) { | 1099 | if (ceph_snap(dir) != CEPH_NOSNAP) { |
| @@ -1121,13 +1111,48 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
| 1121 | valid = 1; | 1111 | valid = 1; |
| 1122 | } | 1112 | } |
| 1123 | 1113 | ||
| 1114 | if (!valid) { | ||
| 1115 | struct ceph_mds_client *mdsc = | ||
| 1116 | ceph_sb_to_client(dir->i_sb)->mdsc; | ||
| 1117 | struct ceph_mds_request *req; | ||
| 1118 | int op, mask, err; | ||
| 1119 | |||
| 1120 | op = ceph_snap(dir) == CEPH_SNAPDIR ? | ||
| 1121 | CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; | ||
| 1122 | req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS); | ||
| 1123 | if (!IS_ERR(req)) { | ||
| 1124 | req->r_dentry = dget(dentry); | ||
| 1125 | req->r_num_caps = 2; | ||
| 1126 | |||
| 1127 | mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED; | ||
| 1128 | if (ceph_security_xattr_wanted(dir)) | ||
| 1129 | mask |= CEPH_CAP_XATTR_SHARED; | ||
| 1130 | req->r_args.getattr.mask = mask; | ||
| 1131 | |||
| 1132 | req->r_locked_dir = dir; | ||
| 1133 | err = ceph_mdsc_do_request(mdsc, NULL, req); | ||
| 1134 | if (err == 0 || err == -ENOENT) { | ||
| 1135 | if (dentry == req->r_dentry) { | ||
| 1136 | valid = !d_unhashed(dentry); | ||
| 1137 | } else { | ||
| 1138 | d_invalidate(req->r_dentry); | ||
| 1139 | err = -EAGAIN; | ||
| 1140 | } | ||
| 1141 | } | ||
| 1142 | ceph_mdsc_put_request(req); | ||
| 1143 | dout("d_revalidate %p lookup result=%d\n", | ||
| 1144 | dentry, err); | ||
| 1145 | } | ||
| 1146 | } | ||
| 1147 | |||
| 1124 | dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid"); | 1148 | dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid"); |
| 1125 | if (valid) { | 1149 | if (valid) { |
| 1126 | ceph_dentry_lru_touch(dentry); | 1150 | ceph_dentry_lru_touch(dentry); |
| 1127 | } else { | 1151 | } else { |
| 1128 | ceph_dir_clear_complete(dir); | 1152 | ceph_dir_clear_complete(dir); |
| 1129 | } | 1153 | } |
| 1130 | iput(dir); | 1154 | |
| 1155 | dput(parent); | ||
| 1131 | return valid; | 1156 | return valid; |
| 1132 | } | 1157 | } |
| 1133 | 1158 | ||
