Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 105469
b: refs/heads/master
c: ff9cd49
h: refs/heads/master
i:
  105467: f04907b
v: v3
  • Loading branch information
Ian Kent authored and Linus Torvalds committed Jul 24, 2008
1 parent 1a3d79a commit c2ca9ca
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 134 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c72305b5472522299bb6f45b736080128eb1c822
refs/heads/master: ff9cd499d6258952385cb2f12e9a3c0908fd5786
149 changes: 16 additions & 133 deletions trunk/fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ static int autofs4_dir_rmdir(struct inode *,struct dentry *);
static int autofs4_dir_mkdir(struct inode *,struct dentry *,int);
static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
static int autofs4_dir_open(struct inode *inode, struct file *file);
static int autofs4_dir_close(struct inode *inode, struct file *file);
static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir);
static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);
static void *autofs4_follow_link(struct dentry *, struct nameidata *);
Expand All @@ -44,9 +42,9 @@ const struct file_operations autofs4_root_operations = {

const struct file_operations autofs4_dir_operations = {
.open = autofs4_dir_open,
.release = autofs4_dir_close,
.release = dcache_dir_close,
.read = generic_read_dir,
.readdir = autofs4_dir_readdir,
.readdir = dcache_readdir,
};

const struct inode_operations autofs4_indirect_root_inode_operations = {
Expand Down Expand Up @@ -98,147 +96,32 @@ static int autofs4_root_readdir(struct file *file, void *dirent,
static int autofs4_dir_open(struct inode *inode, struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
struct vfsmount *mnt = file->f_path.mnt;
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct dentry *cursor;
int status;

status = dcache_dir_open(inode, file);
if (status)
goto out;

cursor = file->private_data;
cursor->d_fsdata = NULL;

DPRINTK("file=%p dentry=%p %.*s",
file, dentry, dentry->d_name.len, dentry->d_name.name);

if (autofs4_oz_mode(sbi))
goto out;

if (autofs4_ispending(dentry)) {
DPRINTK("dentry busy");
dcache_dir_close(inode, file);
status = -EBUSY;
goto out;
}

status = -ENOENT;
if (!d_mountpoint(dentry) && dentry->d_op && dentry->d_op->d_revalidate) {
struct nameidata nd;
int empty, ret;

/* In case there are stale directory dentrys from a failed mount */
spin_lock(&dcache_lock);
empty = list_empty(&dentry->d_subdirs);
/*
* An empty directory in an autofs file system is always a
* mount point. The daemon must have failed to mount this
* during lookup so it doesn't exist. This can happen, for
* example, if user space returns an incorrect status for a
* mount request. Otherwise we're doing a readdir on the
* autofs file system so just let the libfs routines handle
* it.
*/
spin_lock(&dcache_lock);
if (!d_mountpoint(dentry) && __simple_empty(dentry)) {
spin_unlock(&dcache_lock);

if (!empty)
d_invalidate(dentry);

nd.flags = LOOKUP_DIRECTORY;
ret = (dentry->d_op->d_revalidate)(dentry, &nd);

if (ret <= 0) {
if (ret < 0)
status = ret;
dcache_dir_close(inode, file);
goto out;
}
return -ENOENT;
}
spin_unlock(&dcache_lock);

if (d_mountpoint(dentry)) {
struct file *fp = NULL;
struct path fp_path = { .dentry = dentry, .mnt = mnt };

path_get(&fp_path);

if (!autofs4_follow_mount(&fp_path.mnt, &fp_path.dentry)) {
path_put(&fp_path);
dcache_dir_close(inode, file);
goto out;
}

fp = dentry_open(fp_path.dentry, fp_path.mnt, file->f_flags);
status = PTR_ERR(fp);
if (IS_ERR(fp)) {
dcache_dir_close(inode, file);
goto out;
}
cursor->d_fsdata = fp;
}
return 0;
out:
return status;
}

static int autofs4_dir_close(struct inode *inode, struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct dentry *cursor = file->private_data;
int status = 0;

DPRINTK("file=%p dentry=%p %.*s",
file, dentry, dentry->d_name.len, dentry->d_name.name);

if (autofs4_oz_mode(sbi))
goto out;

if (autofs4_ispending(dentry)) {
DPRINTK("dentry busy");
status = -EBUSY;
goto out;
}

if (d_mountpoint(dentry)) {
struct file *fp = cursor->d_fsdata;
if (!fp) {
status = -ENOENT;
goto out;
}
filp_close(fp, current->files);
}
out:
dcache_dir_close(inode, file);
return status;
}

static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldir)
{
struct dentry *dentry = file->f_path.dentry;
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct dentry *cursor = file->private_data;
int status;

DPRINTK("file=%p dentry=%p %.*s",
file, dentry, dentry->d_name.len, dentry->d_name.name);

if (autofs4_oz_mode(sbi))
goto out;

if (autofs4_ispending(dentry)) {
DPRINTK("dentry busy");
return -EBUSY;
}

if (d_mountpoint(dentry)) {
struct file *fp = cursor->d_fsdata;

if (!fp)
return -ENOENT;

if (!fp->f_op || !fp->f_op->readdir)
goto out;

status = vfs_readdir(fp, filldir, dirent);
file->f_pos = fp->f_pos;
if (status)
autofs4_copy_atime(file, fp);
return status;
}
out:
return dcache_readdir(file, dirent, filldir);
return dcache_dir_open(inode, file);
}

static int try_to_fill_dentry(struct dentry *dentry, int flags)
Expand Down

0 comments on commit c2ca9ca

Please sign in to comment.