diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /fs/autofs/root.c | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'fs/autofs/root.c')
-rw-r--r-- | fs/autofs/root.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 561904318..c0caee9df 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -16,7 +16,7 @@ #include "autofs_i.h" static int autofs_root_readdir(struct file *,void *,filldir_t); -static int autofs_root_lookup(struct inode *,struct dentry *); +static struct dentry *autofs_root_lookup(struct inode *,struct dentry *); static int autofs_root_symlink(struct inode *,struct dentry *,const char *); static int autofs_root_unlink(struct inode *,struct dentry *); static int autofs_root_rmdir(struct inode *,struct dentry *); @@ -168,7 +168,7 @@ static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, str * yet completely filled in, and revalidate has to delay such * lookups.. */ -static int autofs_revalidate(struct dentry * dentry) +static int autofs_revalidate(struct dentry * dentry, int flags) { struct inode * dir = dentry->d_parent->d_inode; struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb); @@ -209,7 +209,7 @@ static struct dentry_operations autofs_dentry_operations = { NULL, /* d_compare */ }; -static int autofs_root_lookup(struct inode *dir, struct dentry * dentry) +static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry) { struct autofs_sb_info *sbi; int oz_mode; @@ -217,8 +217,8 @@ static int autofs_root_lookup(struct inode *dir, struct dentry * dentry) DPRINTK(("autofs_root_lookup: name = ")); autofs_say(dentry->d_name.name,dentry->d_name.len); - if (!S_ISDIR(dir->i_mode)) - return -ENOTDIR; + if (dentry->d_name.len > NAME_MAX) + return ERR_PTR(-ENOENT);/* File name too long to exist */ sbi = autofs_sbi(dir->i_sb); @@ -241,7 +241,7 @@ static int autofs_root_lookup(struct inode *dir, struct dentry * dentry) d_add(dentry, NULL); up(&dir->i_sem); - autofs_revalidate(dentry); + autofs_revalidate(dentry, 0); down(&dir->i_sem); /* @@ -250,7 +250,7 @@ static int autofs_root_lookup(struct inode *dir, struct dentry * dentry) */ if (dentry->d_flags & DCACHE_AUTOFS_PENDING) { if (signal_pending(current)) - return -ERESTARTNOINTR; + return ERR_PTR(-ERESTARTNOINTR); } /* @@ -260,9 +260,9 @@ static int autofs_root_lookup(struct inode *dir, struct dentry * dentry) * be OK for the operations we permit from an autofs. */ if ( dentry->d_inode && list_empty(&dentry->d_hash) ) - return -ENOENT; + return ERR_PTR(-ENOENT); - return 0; + return NULL; } static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname) @@ -278,7 +278,10 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c autofs_say(dentry->d_name.name,dentry->d_name.len); if ( !autofs_oz_mode(sbi) ) - return -EPERM; + return -EACCES; + + if ( dentry->d_name.len > NAME_MAX ) + return -ENAMETOOLONG; if ( autofs_hash_lookup(dh, &dentry->d_name) ) return -EEXIST; @@ -343,17 +346,20 @@ static int autofs_root_unlink(struct inode *dir, struct dentry *dentry) struct autofs_dir_ent *ent; unsigned int n; - if ( !autofs_oz_mode(sbi) ) - return -EPERM; + /* This allows root to remove symlinks */ + if ( !autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN) ) + return -EACCES; ent = autofs_hash_lookup(dh, &dentry->d_name); if ( !ent ) return -ENOENT; n = ent->ino - AUTOFS_FIRST_SYMLINK; - if ( n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap) ) - return -EINVAL; /* Not a symlink inode, can't unlink */ - + if ( n >= AUTOFS_MAX_SYMLINKS ) + return -EISDIR; /* It's a directory, dummy */ + if ( !test_bit(n,sbi->symlink_bitmap) ) + return -EINVAL; /* Nonexistent symlink? Shouldn't happen */ + dentry->d_time = (unsigned long)(struct autofs_dirhash *)NULL; autofs_hash_delete(ent); clear_bit(n,sbi->symlink_bitmap); @@ -370,7 +376,7 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry) struct autofs_dir_ent *ent; if ( !autofs_oz_mode(sbi) ) - return -EPERM; + return -EACCES; ent = autofs_hash_lookup(dh, &dentry->d_name); if ( !ent ) @@ -399,7 +405,10 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) ino_t ino; if ( !autofs_oz_mode(sbi) ) - return -EPERM; + return -EACCES; + + if ( dentry->d_name.len > NAME_MAX ) + return -ENAMETOOLONG; ent = autofs_hash_lookup(dh, &dentry->d_name); if ( ent ) |