Loading fs/ceph/mds_client.c +16 −3 Original line number Diff line number Diff line Loading @@ -1438,12 +1438,15 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, struct dentry *temp; char *path; int len, pos; unsigned seq; if (dentry == NULL) return ERR_PTR(-EINVAL); retry: len = 0; seq = read_seqbegin(&rename_lock); rcu_read_lock(); for (temp = dentry; !IS_ROOT(temp);) { struct inode *inode = temp->d_inode; if (inode && ceph_snap(inode) == CEPH_SNAPDIR) Loading @@ -1455,10 +1458,12 @@ retry: len += 1 + temp->d_name.len; temp = temp->d_parent; if (temp == NULL) { rcu_read_unlock(); pr_err("build_path corrupt dentry %p\n", dentry); return ERR_PTR(-EINVAL); } } rcu_read_unlock(); if (len) len--; /* no leading '/' */ Loading @@ -1467,9 +1472,12 @@ retry: return ERR_PTR(-ENOMEM); pos = len; path[pos] = 0; /* trailing null */ rcu_read_lock(); for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) { struct inode *inode = temp->d_inode; struct inode *inode; spin_lock(&temp->d_lock); inode = temp->d_inode; if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { dout("build_path path+%d: %p SNAPDIR\n", pos, temp); Loading @@ -1478,21 +1486,26 @@ retry: break; } else { pos -= temp->d_name.len; if (pos < 0) if (pos < 0) { spin_unlock(&temp->d_lock); break; } strncpy(path + pos, temp->d_name.name, temp->d_name.len); } spin_unlock(&temp->d_lock); if (pos) path[--pos] = '/'; temp = temp->d_parent; if (temp == NULL) { rcu_read_unlock(); pr_err("build_path corrupt dentry\n"); kfree(path); return ERR_PTR(-EINVAL); } } if (pos != 0) { rcu_read_unlock(); if (pos != 0 || read_seqretry(&rename_lock, seq)) { pr_err("build_path did not end path lookup where " "expected, namelen is %d, pos is %d\n", len, pos); /* presumably this is only possible if racing with a Loading Loading
fs/ceph/mds_client.c +16 −3 Original line number Diff line number Diff line Loading @@ -1438,12 +1438,15 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, struct dentry *temp; char *path; int len, pos; unsigned seq; if (dentry == NULL) return ERR_PTR(-EINVAL); retry: len = 0; seq = read_seqbegin(&rename_lock); rcu_read_lock(); for (temp = dentry; !IS_ROOT(temp);) { struct inode *inode = temp->d_inode; if (inode && ceph_snap(inode) == CEPH_SNAPDIR) Loading @@ -1455,10 +1458,12 @@ retry: len += 1 + temp->d_name.len; temp = temp->d_parent; if (temp == NULL) { rcu_read_unlock(); pr_err("build_path corrupt dentry %p\n", dentry); return ERR_PTR(-EINVAL); } } rcu_read_unlock(); if (len) len--; /* no leading '/' */ Loading @@ -1467,9 +1472,12 @@ retry: return ERR_PTR(-ENOMEM); pos = len; path[pos] = 0; /* trailing null */ rcu_read_lock(); for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) { struct inode *inode = temp->d_inode; struct inode *inode; spin_lock(&temp->d_lock); inode = temp->d_inode; if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { dout("build_path path+%d: %p SNAPDIR\n", pos, temp); Loading @@ -1478,21 +1486,26 @@ retry: break; } else { pos -= temp->d_name.len; if (pos < 0) if (pos < 0) { spin_unlock(&temp->d_lock); break; } strncpy(path + pos, temp->d_name.name, temp->d_name.len); } spin_unlock(&temp->d_lock); if (pos) path[--pos] = '/'; temp = temp->d_parent; if (temp == NULL) { rcu_read_unlock(); pr_err("build_path corrupt dentry\n"); kfree(path); return ERR_PTR(-EINVAL); } } if (pos != 0) { rcu_read_unlock(); if (pos != 0 || read_seqretry(&rename_lock, seq)) { pr_err("build_path did not end path lookup where " "expected, namelen is %d, pos is %d\n", len, pos); /* presumably this is only possible if racing with a Loading