Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 24242
b: refs/heads/master
c: f360ce3
h: refs/heads/master
v: v3
  • Loading branch information
Ian Kent authored and Linus Torvalds committed Mar 27, 2006
1 parent d79c877 commit 401120f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 87 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: 718c604a28e35848754a65b839e4877ec34b2fca
refs/heads/master: f360ce3be466d50de153b001b24561ca7593042b
126 changes: 40 additions & 86 deletions trunk/fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ 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 int autofs4_dcache_readdir(struct file *, void *, filldir_t);

struct file_operations autofs4_root_operations = {
.open = dcache_dir_open,
Expand Down Expand Up @@ -82,7 +81,7 @@ static int autofs4_root_readdir(struct file *file, void *dirent,

DPRINTK("needs_reghost = %d", sbi->needs_reghost);

return autofs4_dcache_readdir(file, dirent, filldir);
return dcache_readdir(file, dirent, filldir);
}

/* Update usage from here to top of tree, so that scan of
Expand All @@ -103,75 +102,21 @@ static void autofs4_update_usage(struct vfsmount *mnt, struct dentry *dentry)
spin_unlock(&dcache_lock);
}

/*
* From 2.4 kernel readdir.c
*/
static int autofs4_dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
int i;
struct dentry *dentry = filp->f_dentry;

i = filp->f_pos;
switch (i) {
case 0:
if (filldir(dirent, ".", 1, i, dentry->d_inode->i_ino, DT_DIR) < 0)
break;
i++;
filp->f_pos++;
/* fallthrough */
case 1:
if (filldir(dirent, "..", 2, i, dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
break;
i++;
filp->f_pos++;
/* fallthrough */
default: {
struct list_head *list;
int j = i-2;

spin_lock(&dcache_lock);
list = dentry->d_subdirs.next;

for (;;) {
if (list == &dentry->d_subdirs) {
spin_unlock(&dcache_lock);
return 0;
}
if (!j)
break;
j--;
list = list->next;
}

while(1) {
struct dentry *de = list_entry(list,
struct dentry, d_u.d_child);

if (!d_unhashed(de) && de->d_inode) {
spin_unlock(&dcache_lock);
if (filldir(dirent, de->d_name.name, de->d_name.len, filp->f_pos, de->d_inode->i_ino, DT_UNKNOWN) < 0)
break;
spin_lock(&dcache_lock);
}
filp->f_pos++;
list = list->next;
if (list != &dentry->d_subdirs)
continue;
spin_unlock(&dcache_lock);
break;
}
}
}
return 0;
}

static int autofs4_dir_open(struct inode *inode, struct file *file)
{
struct dentry *dentry = file->f_dentry;
struct vfsmount *mnt = file->f_vfsmnt;
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);

Expand All @@ -180,12 +125,15 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)

if (autofs4_ispending(dentry)) {
DPRINTK("dentry busy");
return -EBUSY;
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;
int empty, ret;

/* In case there are stale directory dentrys from a failed mount */
spin_lock(&dcache_lock);
Expand All @@ -195,13 +143,13 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
if (!empty)
d_invalidate(dentry);

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

if (!status)
return -ENOENT;
if (!ret) {
dcache_dir_close(inode, file);
goto out;
}
}

if (d_mountpoint(dentry)) {
Expand All @@ -212,25 +160,29 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) {
dput(fp_dentry);
mntput(fp_mnt);
return -ENOENT;
dcache_dir_close(inode, file);
goto out;
}

fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
status = PTR_ERR(fp);
if (IS_ERR(fp)) {
file->private_data = NULL;
return status;
dcache_dir_close(inode, file);
goto out;
}
file->private_data = fp;
cursor->d_fsdata = fp;
}
out:
return 0;
out:
return status;
}

static int autofs4_dir_close(struct inode *inode, struct file *file)
{
struct dentry *dentry = file->f_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);
Expand All @@ -240,26 +192,28 @@ static int autofs4_dir_close(struct inode *inode, struct file *file)

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

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

if (!fp)
return -ENOENT;

struct file *fp = cursor->d_fsdata;
if (!fp) {
status = -ENOENT;
goto out;
}
filp_close(fp, current->files);
file->private_data = NULL;
}
out:
return 0;
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_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",
Expand All @@ -274,7 +228,7 @@ static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldi
}

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

if (!fp)
return -ENOENT;
Expand All @@ -289,7 +243,7 @@ static int autofs4_dir_readdir(struct file *file, void *dirent, filldir_t filldi
return status;
}
out:
return autofs4_dcache_readdir(file, dirent, filldir);
return dcache_readdir(file, dirent, filldir);
}

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

0 comments on commit 401120f

Please sign in to comment.