* built from @dentry.
*/
struct dentry *ceph_do_lookup(struct super_block *sb, struct dentry *dentry,
- int mask, int on_inode)
+ int mask, int on_inode, int locked_dir)
{
struct ceph_client *client = ceph_sb_to_client(sb);
struct ceph_mds_client *mdsc = &client->mdsc;
rhead->args.stat.mask = cpu_to_le32(mask);
dget(dentry); /* to match put_request below */
req->r_last_dentry = dentry; /* use this dentry in fill_trace */
+ req->r_locked_dir = dentry->d_parent->d_inode;
err = ceph_mdsc_do_request(mdsc, req);
dentry = ceph_finish_lookup(req, dentry, err);
ceph_mdsc_put_request(req); /* will dput(dentry) */
(nd->flags & LOOKUP_CONTINUE) == 0 && /* only open last component */
!(nd->intent.open.flags & O_CREAT)) {
int mode = nd->intent.open.create_mode & ~current->fs->umask;
- return ceph_lookup_open(dir, dentry, nd, mode);
+ return ceph_lookup_open(dir, dentry, nd, mode, 1);
}
- return ceph_do_lookup(dir->i_sb, dentry, CEPH_STAT_MASK_INODE_ALL, 0);
+ return ceph_do_lookup(dir->i_sb, dentry, CEPH_STAT_MASK_INODE_ALL, 0,1);
}
static int ceph_mknod(struct inode *dir, struct dentry *dentry,
/* no trace. do lookup, in case we are called from create. */
struct dentry *d;
d = ceph_do_lookup(dir->i_sb, dentry, CEPH_STAT_MASK_INODE_ALL,
- 0);
+ 0, 0);
if (d) {
/* ick. this is untested... */
dput(d);
dir, dentry, dentry->d_name.len, dentry->d_name.name);
if (nd) {
BUG_ON((nd->flags & LOOKUP_OPEN) == 0);
- dentry = ceph_lookup_open(dir, dentry, nd, mode);
+ dentry = ceph_lookup_open(dir, dentry, nd, mode, 0);
/* hrm, what should i do here if we get aliased? */
if (IS_ERR(dentry))
return PTR_ERR(dentry);
* path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE
*/
struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
- struct nameidata *nd, int mode)
+ struct nameidata *nd, int mode,
+ int locked_dir)
{
struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
struct ceph_mds_client *mdsc = &client->mdsc;
ceph_mdsc_lease_release(mdsc, dir, 0, CEPH_LOCK_ICONTENT);
dget(dentry); /* to match put_request below */
req->r_last_dentry = dentry; /* use this dentry in fill_trace */
+ req->r_locked_dir = dir; /* caller holds dir->i_mutex */
err = ceph_mdsc_do_request(mdsc, req);
dentry = ceph_finish_lookup(req, dentry, err);
if (err == 0)
extern const struct address_space_operations ceph_aops;
extern int ceph_open(struct inode *inode, struct file *file);
extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
- struct nameidata *nd, int mode);
+ struct nameidata *nd, int mode,
+ int locked_dir);
extern int ceph_release(struct inode *inode, struct file *filp);
int min);
extern struct dentry *ceph_do_lookup(struct super_block *sb,
struct dentry *dentry,
- int mask, int on_inode);
+ int mask, int on_inode, int locked_dir);
extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
struct dentry *dentry, int err);