mirror of
https://github.com/ceph/ceph
synced 2025-04-01 00:26:47 +00:00
kclient: set min depth for ceph_build_path_dentry (fixes spurious Invalid argument errors)
This commit is contained in:
parent
795ccbeb01
commit
c7ba63980d
@ -26,8 +26,12 @@ static int ceph_dentry_revalidate(struct dentry *dentry, struct nameidata *nd);
|
||||
* revalidated during path traversal, and revalidated _again_ when we
|
||||
* reconstruct the reverse path. lame. unfortunately the VFS doesn't
|
||||
* tell us the path it traversed, so i'm not sure we can do any better.
|
||||
*
|
||||
* always include at least @min dentry(ies), or else paths for
|
||||
* namespace operations (link, rename, etc.) are meaningless.
|
||||
*/
|
||||
char *ceph_build_dentry_path(struct dentry *dentry, int *plen, __u64 *base)
|
||||
char *ceph_build_dentry_path(struct dentry *dentry, int *plen, __u64 *base,
|
||||
int min)
|
||||
{
|
||||
struct dentry *temp;
|
||||
char *path;
|
||||
@ -39,7 +43,8 @@ char *ceph_build_dentry_path(struct dentry *dentry, int *plen, __u64 *base)
|
||||
retry:
|
||||
len = 0;
|
||||
for (temp = dentry; !IS_ROOT(temp);) {
|
||||
if (temp->d_inode &&
|
||||
if (len >= min &&
|
||||
temp->d_inode &&
|
||||
!ceph_dentry_revalidate(temp, 0))
|
||||
break;
|
||||
len += 1 + temp->d_name.len;
|
||||
@ -304,7 +309,7 @@ struct dentry *ceph_do_lookup(struct super_block *sb, struct dentry *dentry,
|
||||
} else {
|
||||
/* build path */
|
||||
u64 pathbase;
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 1);
|
||||
if (IS_ERR(path))
|
||||
return ERR_PTR(PTR_ERR(path));
|
||||
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT,
|
||||
@ -357,7 +362,7 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
|
||||
|
||||
dout(5, "dir_mknod in dir %p dentry %p mode 0%o rdev %d\n",
|
||||
dir, dentry, mode, rdev);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 1);
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(path);
|
||||
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD,
|
||||
@ -424,7 +429,7 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
|
||||
int err;
|
||||
|
||||
dout(5, "dir_symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 1);
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(path);
|
||||
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK,
|
||||
@ -458,7 +463,7 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
||||
int err;
|
||||
|
||||
dout(5, "dir_mkdir in dir %p dentry %p mode 0%o\n", dir, dentry, mode);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 1);
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(path);
|
||||
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKDIR,
|
||||
@ -495,10 +500,11 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
|
||||
|
||||
dout(5, "dir_link in dir %p old_dentry %p dentry %p\n", dir,
|
||||
old_dentry, dentry);
|
||||
oldpath = ceph_build_dentry_path(old_dentry, &oldpathlen, &oldpathbase);
|
||||
oldpath = ceph_build_dentry_path(old_dentry, &oldpathlen, &oldpathbase,
|
||||
1);
|
||||
if (IS_ERR(oldpath))
|
||||
return PTR_ERR(oldpath);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 1);
|
||||
if (IS_ERR(path)) {
|
||||
kfree(oldpath);
|
||||
return PTR_ERR(path);
|
||||
@ -550,7 +556,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
|
||||
|
||||
dout(5, "dir_unlink/rmdir in dir %p dentry %p inode %p\n",
|
||||
dir, dentry, inode);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 1);
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(path);
|
||||
req = ceph_mdsc_create_request(mdsc, op,
|
||||
@ -589,10 +595,12 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
|
||||
dout(5, "dir_rename in dir %p dentry %p to dir %p dentry %p\n",
|
||||
old_dir, old_dentry, new_dir, new_dentry);
|
||||
oldpath = ceph_build_dentry_path(old_dentry, &oldpathlen, &oldpathbase);
|
||||
oldpath = ceph_build_dentry_path(old_dentry, &oldpathlen, &oldpathbase,
|
||||
1);
|
||||
if (IS_ERR(oldpath))
|
||||
return PTR_ERR(oldpath);
|
||||
newpath = ceph_build_dentry_path(new_dentry, &newpathlen, &newpathbase);
|
||||
newpath = ceph_build_dentry_path(new_dentry, &newpathlen, &newpathbase,
|
||||
1);
|
||||
if (IS_ERR(newpath)) {
|
||||
kfree(oldpath);
|
||||
return PTR_ERR(newpath);
|
||||
|
@ -33,7 +33,7 @@ prepare_open_request(struct super_block *sb, struct dentry *dentry,
|
||||
|
||||
dout(5, "prepare_open_request dentry %p name '%s' flags %d\n", dentry,
|
||||
dentry->d_name.name, flags);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 0);
|
||||
if (IS_ERR(path))
|
||||
return ERR_PTR(PTR_ERR(path));
|
||||
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_OPEN, pathbase, path,
|
||||
|
@ -1727,7 +1727,7 @@ static struct ceph_mds_request *prepare_setattr(struct ceph_mds_client *mdsc,
|
||||
dentry, USE_CAP_MDS);
|
||||
} else {
|
||||
dout(5, "prepare_setattr dentry %p (full path)\n", dentry);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 0);
|
||||
if (IS_ERR(path))
|
||||
return ERR_PTR(PTR_ERR(path));
|
||||
req = ceph_mdsc_create_request(mdsc, op, pathbase, path, 0, 0,
|
||||
@ -2185,7 +2185,7 @@ int ceph_setxattr(struct dentry *dentry, const char *name,
|
||||
}
|
||||
|
||||
/* do request */
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 0);
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(path);
|
||||
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSETXATTR,
|
||||
@ -2230,7 +2230,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name)
|
||||
if (strncmp(name, "user.", 5) != 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase);
|
||||
path = ceph_build_dentry_path(dentry, &pathlen, &pathbase, 0);
|
||||
if (IS_ERR(path))
|
||||
return PTR_ERR(path);
|
||||
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LRMXATTR,
|
||||
|
@ -1349,7 +1349,7 @@ retry:
|
||||
dentry = d_find_alias(&ci->vfs_inode);
|
||||
if (dentry) {
|
||||
path = ceph_build_dentry_path(dentry, &pathlen,
|
||||
&pathbase);
|
||||
&pathbase, 9999);
|
||||
if (IS_ERR(path)) {
|
||||
err = PTR_ERR(path);
|
||||
BUG_ON(err);
|
||||
|
@ -509,7 +509,8 @@ extern const struct inode_operations ceph_dir_iops;
|
||||
extern const struct file_operations ceph_dir_fops;
|
||||
extern struct dentry_operations ceph_dentry_ops;
|
||||
|
||||
extern char *ceph_build_dentry_path(struct dentry *dn, int *len, __u64 *base);
|
||||
extern char *ceph_build_dentry_path(struct dentry *dn, int *len, __u64 *base,
|
||||
int min);
|
||||
extern struct dentry *ceph_do_lookup(struct super_block *sb,
|
||||
struct dentry *dentry,
|
||||
int mask, int on_inode);
|
||||
|
Loading…
Reference in New Issue
Block a user