dout(10, "readdir querying mds for ino %llx.%llx frag %x\n",
ceph_vinop(inode), frag);
- req = ceph_mdsc_create_request(mdsc, op, filp->f_dentry, NULL,
- NULL, NULL, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
+ req->r_inode = igrab(inode);
+ req->r_dentry = dget(filp->f_dentry);
/* hints to request -> mds selection code */
req->r_direct_mode = USE_AUTH_MDS;
req->r_direct_hash = frag_value(frag);
spin_unlock(&dir->i_lock);
}
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUP,
- dentry, NULL, NULL, NULL,
- USE_ANY_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUP, USE_ANY_MDS);
if (IS_ERR(req))
return ERR_PTR(PTR_ERR(req));
+ req->r_dentry = dget(dentry);
/* we only need inode linkage */
req->r_args.stat.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
req->r_locked_dir = dir;
dout(5, "mknod in dir %p dentry %p mode 0%o rdev %d\n",
dir, dentry, mode, rdev);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, dentry, NULL,
- NULL, NULL, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_MKNOD, USE_AUTH_MDS);
if (IS_ERR(req)) {
d_drop(dentry);
return PTR_ERR(req);
}
+ req->r_dentry = dget(dentry);
req->r_locked_dir = dir;
req->r_args.mknod.mode = cpu_to_le32(mode);
req->r_args.mknod.rdev = cpu_to_le32(rdev);
return -EROFS;
dout(5, "symlink in dir %p dentry %p to '%s'\n", dir, dentry, dest);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK,
- dentry, NULL, NULL, dest, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SYMLINK, USE_AUTH_MDS);
if (IS_ERR(req)) {
d_drop(dentry);
return PTR_ERR(req);
}
+ req->r_dentry = dget(dentry);
+ req->r_path2 = dest;
req->r_locked_dir = dir;
if (!ceph_caps_issued_mask(ceph_inode(dir), CEPH_CAP_FILE_EXCL))
ceph_release_caps(dir, CEPH_CAP_FILE_RDCACHE);
} else {
dout(5, "mkdir dir %p dn %p mode 0%o\n", dir, dentry, mode);
}
- req = ceph_mdsc_create_request(mdsc, op, pathdentry, NULL,
- NULL, snap, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
if (pathdentry != dentry)
dput(pathdentry);
if (IS_ERR(req)) {
err = PTR_ERR(req);
goto out;
}
-
+ req->r_dentry = dget(dentry);
+ req->r_path2 = snap;
req->r_locked_dir = dir;
req->r_args.mkdir.mode = cpu_to_le32(mode);
dout(5, "link in dir %p old_dentry %p dentry %p\n", dir,
old_dentry, dentry);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, dentry,
- old_dentry, NULL, NULL, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, USE_AUTH_MDS);
if (IS_ERR(req)) {
d_drop(dentry);
return PTR_ERR(req);
}
-
+ req->r_dentry = dget(dentry);
+ req->r_old_dentry = dget(old_dentry); /* or inode? hrm. */
req->r_locked_dir = dir;
if (!ceph_caps_issued_mask(ceph_inode(dir), CEPH_CAP_FILE_EXCL))
dout(5, "unlink/rmdir dir %p dn %p inode %p\n",
dir, dentry, inode);
}
- req = ceph_mdsc_create_request(mdsc, op, pathdentry, NULL, NULL, snap,
- USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
if (pathdentry != dentry)
dput(pathdentry);
if (IS_ERR(req)) {
err = PTR_ERR(req);
goto out;
}
-
+ req->r_dentry = dget(pathdentry);
+ req->r_path2 = snap;
req->r_locked_dir = dir;
if (!ceph_caps_issued_mask(ceph_inode(dir), CEPH_CAP_FILE_EXCL))
dout(5, "rename dir %p dentry %p to dir %p dentry %p\n",
old_dir, old_dentry, new_dir, new_dentry);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME,
- new_dentry, old_dentry, NULL, NULL,
- USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RENAME, USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
+ req->r_dentry = dget(new_dentry);
+ req->r_old_dentry = dget(old_dentry);
req->r_locked_dir = new_dir;
if (!ceph_caps_issued_mask(ceph_inode(old_dir), CEPH_CAP_FILE_EXCL))
ceph_release_caps(old_dir, CEPH_CAP_FILE_RDCACHE);
if (!inode) {
struct ceph_mds_request *req;
derr(10, "fh_to_dentry %llx.%x -- no inode\n", vino.ino, hash);
- req = ceph_mdsc_create_request(mdsc,
- CEPH_MDS_OP_FINDINODE,
- NULL, NULL,
- (char *)fh, (void *)&len,
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_FINDINODE,
USE_ANY_MDS);
if (IS_ERR(req))
return ERR_PTR(PTR_ERR(req));
+ req->r_path1 = (char *)fh;
+ req->r_path2 = (void *)&len;
err = ceph_mdsc_do_request(mdsc, NULL, req);
ceph_mdsc_put_request(req);
inode = ceph_find_inode(sb, vino);
* inopportune ENOMEM later.
*/
static struct ceph_mds_request *
-prepare_open_request(struct super_block *sb, struct dentry *dentry,
- int flags, int create_mode)
+prepare_open_request(struct super_block *sb, int flags, int create_mode)
{
struct ceph_client *client = ceph_sb_to_client(sb);
struct ceph_mds_client *mdsc = &client->mdsc;
if (flags & (O_WRONLY|O_RDWR|O_CREAT|O_TRUNC))
want_auth = USE_AUTH_MDS;
- dout(5, "prepare_open_request dentry %p name '%s' flags %d\n", dentry,
- dentry->d_name.name, flags);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_OPEN, dentry, NULL,
- NULL, NULL, want_auth);
+ dout(5, "prepare_open_request flags %d\n", flags);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_OPEN, want_auth);
if (IS_ERR(req))
goto out;
req->r_fmode = ceph_flags_to_mode(flags);
return -ESTALE; /* yuck */
if (!ceph_caps_issued_mask(ceph_inode(inode), CEPH_CAP_FILE_EXCL))
ceph_release_caps(inode, CEPH_CAP_FILE_RDCACHE);
- req = prepare_open_request(inode->i_sb, dentry, flags, 0);
+ req = prepare_open_request(inode->i_sb, flags, 0);
if (IS_ERR(req)) {
err = PTR_ERR(req);
goto out;
}
+ req->r_inode = igrab(inode);
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
if (!err)
err = ceph_init_file(inode, file, req->r_fmode);
dentry, dentry->d_name.len, dentry->d_name.name, flags, mode);
/* do the open */
- req = prepare_open_request(dir->i_sb, dentry, flags, mode);
+ req = prepare_open_request(dir->i_sb, flags, mode);
if (IS_ERR(req))
return ERR_PTR(PTR_ERR(req));
+ req->r_dentry = dget(dentry);
if ((flags & O_CREAT) &&
(!ceph_caps_issued_mask(ceph_inode(dir), CEPH_CAP_FILE_EXCL)))
ceph_release_caps(dir, CEPH_CAP_FILE_RDCACHE);
req->r_old_dentry->d_name.len,
req->r_old_dentry->d_name.name,
dn, dn->d_name.len, dn->d_name.name);
- dput(dn); /* dn is dropped */
+ //dput(dn); /* dn is dropped */
dn = req->r_old_dentry; /* use old_dentry */
- req->r_old_dentry = NULL;
+ in = dn->d_inode;
}
/* null dentry? */
}
/* attach proper inode */
- BUG_ON(dn->d_inode);
-
ininfo = rinfo->targeti.in;
vino.ino = le64_to_cpu(ininfo->ino);
vino.snap = le64_to_cpu(ininfo->snapid);
- in = ceph_get_inode(dn->d_sb, vino);
- if (IS_ERR(in)) {
- derr(30, "get_inode badness\n");
- err = PTR_ERR(in);
- d_delete(dn);
- goto done;
- }
- dn = splice_dentry(dn, in, &have_lease);
- if (IS_ERR(dn)) {
- err = PTR_ERR(dn);
- goto done;
+ if (!dn->d_inode) {
+ in = ceph_get_inode(dn->d_sb, vino);
+ if (IS_ERR(in)) {
+ derr(30, "get_inode badness\n");
+ err = PTR_ERR(in);
+ d_delete(dn);
+ goto done;
+ }
+ dn = splice_dentry(dn, in, &have_lease);
+ if (IS_ERR(dn)) {
+ err = PTR_ERR(dn);
+ goto done;
+ }
+ req->r_dentry = dn; /* may have spliced */
+ } else if (ceph_ino(in) != vino.ino ||
+ ceph_snap(in) != vino.snap) {
+ dout(10, " %p links to %p %llx.%llx, not %llx.%llx\n",
+ dn, in, ceph_ino(in), ceph_snap(in),
+ vino.ino, vino.snap);
+ have_lease = false;
+ in = NULL;
}
- req->r_dentry = dn; /* may have changed from the splice */
if (have_lease)
update_dentry_lease(dn, rinfo->dlease, session,
}
spin_unlock(&inode->i_lock);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LCHOWN, dentry, NULL,
- NULL, NULL, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LCHOWN, USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
+ req->r_inode = igrab(inode);
if (ia_valid & ATTR_UID) {
req->r_args.chown.uid = cpu_to_le32(attr->ia_uid);
mask |= CEPH_CHOWN_UID;
}
spin_unlock(&inode->i_lock);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LCHMOD, dentry, NULL,
- NULL, NULL, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LCHMOD, USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
+ req->r_inode = igrab(inode);
req->r_args.chmod.mode = cpu_to_le32(attr->ia_mode);
ceph_release_caps(inode, CEPH_CAP_AUTH_RDCACHE);
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
spin_unlock(&inode->i_lock);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LUTIME, dentry, NULL,
- NULL, NULL, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LUTIME, USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
+ req->r_inode = igrab(inode);
ceph_encode_timespec(&req->r_args.utime.mtime, &attr->ia_mtime);
ceph_encode_timespec(&req->r_args.utime.atime, &attr->ia_atime);
}
spin_unlock(&inode->i_lock);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LTRUNCATE, dentry,
- NULL, NULL, NULL, USE_AUTH_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LTRUNCATE,
+ USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
+ req->r_inode = igrab(inode);
req->r_args.truncate.length = cpu_to_le64(attr->ia_size);
req->r_args.truncate.old_length = cpu_to_le64(inode->i_size);
//ceph_release_caps(inode, CEPH_CAP_FILE_RDCACHE);
{
struct ceph_client *client = ceph_sb_to_client(dentry->d_sb);
struct ceph_mds_client *mdsc = &client->mdsc;
+ struct inode *inode = dentry->d_inode;
struct ceph_mds_request *req;
int err;
- if (ceph_snap(dentry->d_inode) == CEPH_SNAPDIR) {
+ if (ceph_snap(inode) == CEPH_SNAPDIR) {
dout(30, "do_getattr dentry %p inode %p SNAPDIR\n", dentry,
- dentry->d_inode);
+ inode);
return 0;
}
dout(30, "do_getattr dentry %p inode %p mask %s\n", dentry,
- dentry->d_inode, ceph_cap_string(mask));
- if (ceph_caps_issued_mask(ceph_inode(dentry->d_inode), mask))
+ inode, ceph_cap_string(mask));
+ if (ceph_caps_issued_mask(ceph_inode(inode), mask))
return 0;
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT,
- dentry, NULL, NULL, NULL,
- USE_ANY_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT, USE_ANY_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
+ req->r_inode = igrab(inode);
req->r_args.stat.mask = cpu_to_le32(mask);
err = ceph_mdsc_do_request(mdsc, NULL, req);
ceph_mdsc_put_request(req); /* will dput(dentry) */
/* do request */
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSETXATTR,
- dentry, NULL, NULL, NULL, USE_AUTH_MDS);
+ USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
-
+ req->r_inode = igrab(inode);
req->r_args.setxattr.flags = cpu_to_le32(flags);
req->r_request->pages = pages;
return -EOPNOTSUPP;
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LRMXATTR,
- dentry, NULL, NULL, NULL, USE_AUTH_MDS);
+ USE_AUTH_MDS);
if (IS_ERR(req))
return PTR_ERR(req);
-
+ req->r_inode = igrab(inode);
ceph_release_caps(inode, CEPH_CAP_XATTR_RDCACHE);
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
ceph_mdsc_put_request(req);
return -EFAULT;
req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSETLAYOUT,
- file->f_dentry, NULL, NULL, NULL,
USE_AUTH_MDS);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+ req->r_inode = igrab(inode);
req->r_args.setlayout.layout = layout;
ceph_release_caps(inode, CEPH_CAP_FILE_RDCACHE);
err = ceph_mdsc_do_request(mdsc, parent_inode, req);
ceph_msg_put(req->r_reply);
destroy_reply_info(&req->r_reply_info);
}
+ if (req->r_inode)
+ iput(req->r_inode);
if (req->r_target_inode)
iput(req->r_target_inode);
if (req->r_dentry)
* Create an mds request.
*/
struct ceph_mds_request *
-ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op,
- struct dentry *dentry, struct dentry *old_dentry,
- const char *path1, const char *path2, int mode)
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
{
struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
INIT_LIST_HEAD(&req->r_unsafe_item);
req->r_op = op;
- if (dentry)
- req->r_dentry = dget(dentry);
- if (old_dentry)
- req->r_old_dentry = dget(old_dentry);
- req->r_path1 = path1;
- req->r_path2 = path2;
req->r_direct_mode = mode;
return req;
}
{
struct ceph_msg *msg;
struct ceph_mds_request_head *head;
- char *path1 = (char *)req->r_path1;
- char *path2 = (char *)req->r_path2;
+ const char *path1 = req->r_path1;
+ const char *path2 = req->r_path2;
u64 ino1 = 1, ino2 = 0;
int pathlen1 = 0, pathlen2 = 0;
int pathlen;
} else {
if (path1)
pathlen1 = strlen(path1);
- else if (req->r_dentry)
- path1 = ceph_mdsc_build_path(req->r_dentry, &pathlen1, &ino1,
- mds);
+ else if (req->r_inode) {
+ ino1 = ceph_ino(req->r_inode);
+ } else {
+ path1 = req->r_dentry->d_name.name;
+ pathlen1 = req->r_dentry->d_name.len;
+ ino1 = ceph_ino(req->r_dentry->d_parent->d_inode);
+ }
+
if (path2)
pathlen2 = strlen(path2);
- else if (req->r_old_dentry)
- path2 = ceph_mdsc_build_path(req->r_old_dentry, &pathlen2, &ino2,
- mds);
+ else if (req->r_old_dentry) {
+ path2 = req->r_old_dentry->d_name.name;
+ pathlen2 = req->r_old_dentry->d_name.len;
+ ino2 = ceph_ino(req->r_old_dentry->d_parent->d_inode);
+ }
pathlen = pathlen1 + pathlen2 + 2*(sizeof(u32) + sizeof(u64));
}
if (path2)
dout(10, "create_request_message path2 %llx/%s\n",
ino2, path2);
- if (req->r_dentry)
- kfree(path1);
- if (req->r_old_dentry)
- kfree(path2);
}
BUG_ON(p != end);
dout(20, " r_locked_dir = %p\n", req->r_locked_dir);
rhead->num_dentries_wanted = req->r_locked_dir ? 1:0;
- if (req->r_target_inode)
+ if (req->r_target_inode && req->r_got_unsafe)
rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));
else
rhead->ino = 0;
u64 r_tid; /* transaction id */
int r_op;
+ struct inode *r_inode;
struct dentry *r_dentry;
struct dentry *r_old_dentry; /* rename from or link from */
const char *r_path1, *r_path2;
union ceph_mds_request_args r_args;
+ struct inode *r_target_inode;
+
struct ceph_msg *r_request; /* original request */
struct ceph_msg *r_reply;
struct ceph_mds_reply_info_parsed r_reply_info;
/* references to the trailing dentry and inode from parsing the
* mds response. also used to feed a VFS-provided dentry into
* the reply handler */
- struct inode *r_target_inode;
int r_fmode; /* file mode, if expecting cap */
struct ceph_mds_session *r_session;
struct ceph_mds_session *r_fwd_session; /* forwarded from */
struct dentry *dn, int mask);
extern struct ceph_mds_request *
-ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op,
- struct dentry *dentry, struct dentry *old_dentry,
- const char *path1, const char *path2,
- int mode);
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode);
extern void ceph_mdsc_submit_request(struct ceph_mds_client *mdsc,
struct ceph_mds_request *req);
extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
/* open dir */
dout(30, "open_root_inode opening '%s'\n", path);
- req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT,
- NULL, NULL, path, NULL,
- USE_ANY_MDS);
+ req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT, USE_ANY_MDS);
if (IS_ERR(req))
return ERR_PTR(PTR_ERR(req));
+ req->r_path1 = path;
req->r_started = started;
req->r_timeout = client->mount_args.mount_timeout * HZ;
req->r_args.stat.mask = cpu_to_le32(CEPH_STAT_CAP_INODE);
mds->balancer->hit_inode(mdr->now, cur, META_POP_IRD,
mdr->client_request->get_orig_source().num());
- reply_request(mdr, 0);
+ reply_request(mdr, 0, cur);
}