Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 231516
b: refs/heads/master
c: 8c13a67
h: refs/heads/master
v: v3
  • Loading branch information
Ian Kent authored and Al Viro committed Jan 16, 2011
1 parent a25b548 commit b45a344
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 251 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: b5b801779d59165c4ecf1009009109545bd1f642
refs/heads/master: 8c13a676d5a56495c350f3141824a5ef6c6b4606
7 changes: 0 additions & 7 deletions trunk/fs/autofs4/autofs_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,6 @@ static inline int autofs4_ispending(struct dentry *dentry)
return 0;
}

static inline void autofs4_copy_atime(struct file *src, struct file *dst)
{
dst->f_path.dentry->d_inode->i_atime =
src->f_path.dentry->d_inode->i_atime;
return;
}

struct inode *autofs4_get_inode(struct super_block *, struct autofs_info *);
void autofs4_free_ino(struct autofs_info *);

Expand Down
243 changes: 0 additions & 243 deletions trunk/fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long);
static int autofs4_dir_open(struct inode *inode, struct file *file);
static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *);

#define TRIGGER_FLAGS (LOOKUP_CONTINUE | LOOKUP_DIRECTORY)
#define TRIGGER_INTENTS (LOOKUP_OPEN | LOOKUP_CREATE)

const struct file_operations autofs4_root_operations = {
.open = dcache_dir_open,
.release = dcache_dir_close,
Expand Down Expand Up @@ -114,14 +111,6 @@ static void autofs4_del_active(struct dentry *dentry)
return;
}

static unsigned int autofs4_need_mount(unsigned int flags)
{
unsigned int res = 0;
if (flags & (TRIGGER_FLAGS | TRIGGER_INTENTS))
res = 1;
return res;
}

static int autofs4_dir_open(struct inode *inode, struct file *file)
{
struct dentry *dentry = file->f_path.dentry;
Expand Down Expand Up @@ -156,238 +145,6 @@ static int autofs4_dir_open(struct inode *inode, struct file *file)
return dcache_dir_open(inode, file);
}

static int try_to_fill_dentry(struct dentry *dentry, int flags)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
int status;

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

/*
* Wait for a pending mount, triggering one if there
* isn't one already
*/
if (dentry->d_inode == NULL) {
DPRINTK("waiting for mount name=%.*s",
dentry->d_name.len, dentry->d_name.name);

status = autofs4_wait(sbi, dentry, NFY_MOUNT);

DPRINTK("mount done status=%d", status);

/* Turn this into a real negative dentry? */
if (status == -ENOENT) {
spin_lock(&sbi->fs_lock);
ino->flags &= ~AUTOFS_INF_PENDING;
spin_unlock(&sbi->fs_lock);
return status;
} else if (status) {
/* Return a negative dentry, but leave it "pending" */
return status;
}
/* Trigger mount for path component or follow link */
} else if (ino->flags & AUTOFS_INF_PENDING ||
autofs4_need_mount(flags)) {
DPRINTK("waiting for mount name=%.*s",
dentry->d_name.len, dentry->d_name.name);

spin_lock(&sbi->fs_lock);
ino->flags |= AUTOFS_INF_PENDING;
spin_unlock(&sbi->fs_lock);
status = autofs4_wait(sbi, dentry, NFY_MOUNT);

DPRINTK("mount done status=%d", status);

if (status) {
spin_lock(&sbi->fs_lock);
ino->flags &= ~AUTOFS_INF_PENDING;
spin_unlock(&sbi->fs_lock);
return status;
}
}

/* Initialize expiry counter after successful mount */
ino->last_used = jiffies;

spin_lock(&sbi->fs_lock);
ino->flags &= ~AUTOFS_INF_PENDING;
spin_unlock(&sbi->fs_lock);

return 0;
}

/* For autofs direct mounts the follow link triggers the mount */
static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
int oz_mode = autofs4_oz_mode(sbi);
unsigned int lookup_type;
int status;

DPRINTK("dentry=%p %.*s oz_mode=%d nd->flags=%d",
dentry, dentry->d_name.len, dentry->d_name.name, oz_mode,
nd->flags);
/*
* For an expire of a covered direct or offset mount we need
* to break out of follow_down_one() at the autofs mount trigger
* (d_mounted--), so we can see the expiring flag, and manage
* the blocking and following here until the expire is completed.
*/
if (oz_mode) {
spin_lock(&sbi->fs_lock);
if (ino->flags & AUTOFS_INF_EXPIRING) {
spin_unlock(&sbi->fs_lock);
/* Follow down to our covering mount. */
if (!follow_down_one(&nd->path))
goto done;
goto follow;
}
spin_unlock(&sbi->fs_lock);
goto done;
}

/* If an expire request is pending everyone must wait. */
autofs4_expire_wait(dentry);

/* We trigger a mount for almost all flags */
lookup_type = autofs4_need_mount(nd->flags);
spin_lock(&sbi->fs_lock);
spin_lock(&autofs4_lock);
spin_lock(&dentry->d_lock);
if (!(lookup_type || ino->flags & AUTOFS_INF_PENDING)) {
spin_unlock(&dentry->d_lock);
spin_unlock(&autofs4_lock);
spin_unlock(&sbi->fs_lock);
goto follow;
}

/*
* If the dentry contains directories then it is an autofs
* multi-mount with no root mount offset. So don't try to
* mount it again.
*/
if (ino->flags & AUTOFS_INF_PENDING ||
(!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs))) {
spin_unlock(&dentry->d_lock);
spin_unlock(&autofs4_lock);
spin_unlock(&sbi->fs_lock);

status = try_to_fill_dentry(dentry, nd->flags);
if (status)
goto out_error;

goto follow;
}
spin_unlock(&dentry->d_lock);
spin_unlock(&autofs4_lock);
spin_unlock(&sbi->fs_lock);
follow:
/*
* If there is no root mount it must be an autofs
* multi-mount with no root offset so we don't need
* to follow it.
*/
if (d_managed(dentry)) {
status = follow_down(&nd->path, false);
if (status < 0)
goto out_error;
}

done:
return NULL;

out_error:
path_put(&nd->path);
return ERR_PTR(status);
}

/*
* Revalidate is called on every cache lookup. Some of those
* cache lookups may actually happen while the dentry is not
* yet completely filled in, and revalidate has to delay such
* lookups..
*/
static int autofs4_revalidate(struct dentry *dentry, struct nameidata *nd)
{
struct inode *dir;
struct autofs_sb_info *sbi;
int oz_mode;
int flags = nd ? nd->flags : 0;
int status = 1;

if (flags & LOOKUP_RCU)
return -ECHILD;

dir = dentry->d_parent->d_inode;
sbi = autofs4_sbi(dir->i_sb);
oz_mode = autofs4_oz_mode(sbi);

/* Pending dentry */
spin_lock(&sbi->fs_lock);
if (autofs4_ispending(dentry)) {
/* The daemon never causes a mount to trigger */
spin_unlock(&sbi->fs_lock);

if (oz_mode)
return 1;

/*
* If the directory has gone away due to an expire
* we have been called as ->d_revalidate() and so
* we need to return false and proceed to ->lookup().
*/
if (autofs4_expire_wait(dentry) == -EAGAIN)
return 0;

/*
* A zero status is success otherwise we have a
* negative error code.
*/
status = try_to_fill_dentry(dentry, flags);
if (status == 0)
return 1;

return status;
}
spin_unlock(&sbi->fs_lock);

/* Negative dentry.. invalidate if "old" */
if (dentry->d_inode == NULL)
return 0;

/* Check for a non-mountpoint directory with no contents */
spin_lock(&autofs4_lock);
spin_lock(&dentry->d_lock);
if (S_ISDIR(dentry->d_inode->i_mode) &&
!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) {
DPRINTK("dentry=%p %.*s, emptydir",
dentry, dentry->d_name.len, dentry->d_name.name);
spin_unlock(&dentry->d_lock);
spin_unlock(&autofs4_lock);

/* The daemon never causes a mount to trigger */
if (oz_mode)
return 1;

/*
* A zero status is success otherwise we have a
* negative error code.
*/
status = try_to_fill_dentry(dentry, flags);
if (status == 0)
return 1;

return status;
}
spin_unlock(&dentry->d_lock);
spin_unlock(&autofs4_lock);

return 1;
}

void autofs4_dentry_release(struct dentry *de)
{
struct autofs_info *inf;
Expand Down

0 comments on commit b45a344

Please sign in to comment.