summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/adfs/dir.c8
-rw-r--r--fs/affs/namei.c6
-rw-r--r--fs/autofs/root.c4
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/binfmt_em86.c4
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/buffer.c19
-rw-r--r--fs/coda/dir.c10
-rw-r--r--fs/devfs/base.c112
-rw-r--r--fs/devpts/root.c4
-rw-r--r--fs/exec.c3
-rw-r--r--fs/fat/fatfs_syms.c1
-rw-r--r--fs/fifo.c1
-rw-r--r--fs/hfs/sysdep.c10
-rw-r--r--fs/hpfs/dentry.c6
-rw-r--r--fs/isofs/inode.c24
-rw-r--r--fs/minix/namei.c6
-rw-r--r--fs/msdos/namei.c8
-rw-r--r--fs/namei.c217
-rw-r--r--fs/ncpfs/dir.c8
-rw-r--r--fs/nfs/dir.c9
-rw-r--r--fs/nfsd/nfsfh.c5
-rw-r--r--fs/nfsd/vfs.c106
-rw-r--r--fs/ntfs/fs.c1
-rw-r--r--fs/pipe.c19
-rw-r--r--fs/proc/base.c17
-rw-r--r--fs/proc/generic.c5
-rw-r--r--fs/proc/proc_misc.c9
-rw-r--r--fs/proc/root.c3
-rw-r--r--fs/readdir.c73
-rw-r--r--fs/smbfs/dir.c8
-rw-r--r--fs/udf/udfdecl.h1
-rw-r--r--fs/umsdos/dir.c6
-rw-r--r--fs/vfat/namei.c26
34 files changed, 329 insertions, 414 deletions
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index a7da5eeda..794097871 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -256,12 +256,8 @@ adfs_compare(struct dentry *parent, struct qstr *entry, struct qstr *name)
}
struct dentry_operations adfs_dentry_operations = {
- NULL, /* revalidate */
- adfs_hash,
- adfs_compare,
- NULL, /* delete = called by dput */
- NULL, /* release - called by d_free */
- NULL /* iput - called by dentry_iput */
+ d_hash: adfs_hash,
+ d_compare: adfs_compare,
};
struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry)
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 43085a64b..38e5bccbe 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -44,10 +44,8 @@ affs_intl_toupper(unsigned int ch)
static int affs_hash_dentry(struct dentry *, struct qstr *);
static int affs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
struct dentry_operations affs_dentry_operations = {
- NULL, /* d_validate */
- affs_hash_dentry, /* d_hash */
- affs_compare_dentry, /* d_compare */
- NULL /* d_delete */
+ d_hash: affs_hash_dentry,
+ d_compare: affs_compare_dentry,
};
/*
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index ea517f0b1..35afe3cdc 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -174,9 +174,7 @@ static int autofs_revalidate(struct dentry * dentry, int flags)
}
static struct dentry_operations autofs_dentry_operations = {
- autofs_revalidate, /* d_revalidate */
- NULL, /* d_hash */
- NULL, /* d_compare */
+ d_revalidate: autofs_revalidate,
};
static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 52e9fe7b8..96190fed2 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -715,7 +715,9 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
__MOD_INC_USE_COUNT(current->binfmt->module);
#ifndef VM_STACK_FLAGS
+ lock_kernel();
current->executable = dget(bprm->dentry);
+ unlock_kernel();
#endif
compute_creds(bprm);
current->flags &= ~PF_FORKNOEXEC;
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 2c76e5592..d89bd9ca8 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -42,7 +42,9 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
}
bprm->sh_bang++; /* Well, the bang-shell is implicit... */
+ lock_kernel();
dput(bprm->dentry);
+ unlock_kernel();
bprm->dentry = NULL;
/* Unlike in the script case, we don't have to do any hairy
@@ -78,7 +80,9 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
* Note that we use open_namei() as the name is now in kernel
* space, and we don't need to copy it.
*/
+ lock_kernel();
dentry = open_namei(interp, 0, 0);
+ unlock_kernel();
if (IS_ERR(dentry))
return PTR_ERR(dentry);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 5a202c7e1..c455a735d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -630,7 +630,7 @@ int blkdev_put(struct block_device *bdev, int kind)
/* syncing will go here */
if (kind == BDEV_FILE || kind == BDEV_FS)
fsync_dev(rdev);
- if (atomic_dec_and_test(&bdev->bd_openers) && MAJOR(rdev) != RAMDISK_MAJOR) {
+ if (atomic_dec_and_test(&bdev->bd_openers)) {
/* invalidating buffers will go here */
invalidate_buffers(rdev);
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 6d31f18e8..4e79483e4 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2474,6 +2474,7 @@ asmlinkage long sys_bdflush(int func, long data)
*/
int bdflush(void * unused)
{
+ struct task_struct *tsk = current;
int flushed;
/*
* We have a bare-bones task_struct, and really should fill
@@ -2481,17 +2482,17 @@ int bdflush(void * unused)
* display semi-sane things. Not real crucial though...
*/
- current->session = 1;
- current->pgrp = 1;
- sprintf(current->comm, "kflushd");
- bdflush_tsk = current;
+ tsk->session = 1;
+ tsk->pgrp = 1;
+ strcpy(tsk->comm, "kflushd");
+ bdflush_tsk = tsk;
/* avoid getting signals */
- spin_lock_irq(&current->sigmask_lock);
- flush_signals(current);
- sigfillset(&current->blocked);
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
+ spin_lock_irq(&tsk->sigmask_lock);
+ flush_signals(tsk);
+ sigfillset(&tsk->blocked);
+ recalc_sigpending(tsk);
+ spin_unlock_irq(&tsk->sigmask_lock);
for (;;) {
CHECK_EMERGENCY_SYNC
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index dac8e8884..8e25fccd6 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -57,10 +57,8 @@ int coda_hasmknod = 0;
struct dentry_operations coda_dentry_operations =
{
- coda_dentry_revalidate, /* revalidate */
- NULL, /* hash */
- NULL, /* compare */
- coda_dentry_delete /* delete */
+ d_revalidate: coda_dentry_revalidate,
+ d_delete: coda_dentry_delete,
};
struct inode_operations coda_dir_inode_operations =
@@ -541,9 +539,7 @@ int coda_readdir(struct file *file, void *dirent, filldir_t filldir)
result = coda_venus_readdir(&open_file, dirent, filldir);
} else {
/* potemkin case: we are handed a directory inode */
- down(&cnp->c_ovp->i_sem);
- result = open_file.f_op->readdir(&open_file, dirent, filldir);
- up(&cnp->c_ovp->i_sem);
+ result = vfs_readdir(&open_file, filldir, dirent);
}
coda_restore_codafile(inode, file, cnp->c_ovp, &open_file);
EXIT;
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index ad50e21b9..f2e09cd6e 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -426,6 +426,12 @@
Removed <devfs_fill_file>.
Work sponsored by SGI.
v0.92
+ 20000306 Richard Gooch <rgooch@atnf.csiro.au>
+ Added DEVFS_FL_NO_PERSISTENCE flag.
+ Removed unnecessary call to <update_devfs_inode_from_entry> in
+ <devfs_readdir>.
+ Work sponsored by SGI.
+ v0.93
*/
#include <linux/types.h>
#include <linux/errno.h>
@@ -460,7 +466,7 @@
#include <asm/bitops.h>
#include <asm/atomic.h>
-#define DEVFS_VERSION "0.92 (20000203)"
+#define DEVFS_VERSION "0.93 (20000306)"
#ifndef DEVFS_NAME
# define DEVFS_NAME "devfs"
@@ -601,6 +607,7 @@ struct devfs_entry
unsigned char registered:1;
unsigned char show_unreg:1;
unsigned char hide:1;
+ unsigned char no_persistence:1;
char name[1]; /* This is just a dummy: the allocated array is
bigger. This is NULL-terminated */
};
@@ -1240,6 +1247,7 @@ devfs_handle_t devfs_register (devfs_handle_t dir,
de->show_unreg = ( (boot_options & OPTION_SHOW)
|| (flags & DEVFS_FL_SHOW_UNREG) ) ? TRUE : FALSE;
de->hide = (flags & DEVFS_FL_HIDE) ? TRUE : FALSE;
+ de->no_persistence = (flags & DEVFS_FL_NO_PERSISTENCE) ? TRUE : FALSE;
devfsd_notify (de, DEVFSD_NOTIFY_REGISTERED, flags & DEVFS_FL_WAIT);
return de;
} /* End Function devfs_register */
@@ -1983,24 +1991,17 @@ static void update_devfs_inode_from_entry (struct devfs_inode *di)
else
{
if (di->de->u.fcb.auto_owner)
- {
- mode_t mode = di->de->mode;
-
- di->mode = (mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO;
- }
- else
- {
- di->mode = di->de->mode;
- }
+ di->mode = (di->de->mode & ~S_IALLUGO) | S_IRUGO | S_IWUGO;
+ else di->mode = di->de->mode;
di->uid = di->de->u.fcb.default_uid;
di->gid = di->de->u.fcb.default_gid;
}
} /* End Function update_devfs_inode_from_entry */
-static struct devfs_inode *create_devfs_inode (struct devfs_entry *entry,
+static struct devfs_inode *create_devfs_inode (struct devfs_entry *de,
struct fs_info *fs_info)
/* [SUMMARY] Create a devfs inode entry.
- <entry> The devfs entry to associate the new inode with.
+ <de> The devfs entry to associate the new inode with.
<fs_info> The FS info.
[RETURNS] A pointer to the devfs inode on success, else NULL.
*/
@@ -2032,12 +2033,12 @@ static struct devfs_inode *create_devfs_inode (struct devfs_entry *entry,
di->nlink = 1;
fs_info->table[fs_info->num_inodes] = di;
++fs_info->num_inodes;
- di->de = entry;
+ di->de = de;
di->fs_info = fs_info;
- di->prev = entry->last_inode;
- if (entry->first_inode == NULL) entry->first_inode = di;
- else entry->last_inode->next = di;
- entry->last_inode = di;
+ di->prev = de->last_inode;
+ if (de->first_inode == NULL) de->first_inode = di;
+ else de->last_inode->next = di;
+ de->last_inode = di;
update_devfs_inode_from_entry (di);
#ifdef CONFIG_DEVFS_DEBUG
if (devfs_debug & DEBUG_I_CREATE)
@@ -2183,8 +2184,9 @@ static int get_removable_partition (struct devfs_entry *dir, const char *name,
/* Superblock operations follow */
-extern struct inode_operations devfs_iops;
+static struct inode_operations devfs_iops;
static struct file_operations devfs_fops;
+static struct inode_operations devfs_symlink_iops;
static void devfs_read_inode (struct inode *inode)
{
@@ -2206,22 +2208,29 @@ static void devfs_read_inode (struct inode *inode)
inode->i_blocks = 0;
inode->i_blksize = 1024;
inode->i_op = &devfs_iops;
- inode->i_fop = &devfs_fops;
inode->i_rdev = NODEV;
- if ( S_ISCHR (di->mode) )
+ if ( S_ISCHR (di->mode) ) {
inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major,
di->de->u.fcb.u.device.minor);
- else if ( S_ISBLK (di->mode) )
- {
+ inode->i_fop = &devfs_fops;
+ } else if ( S_ISBLK (di->mode) ) {
inode->i_rdev = MKDEV (di->de->u.fcb.u.device.major,
di->de->u.fcb.u.device.minor);
inode->i_bdev = bdget (inode->i_rdev);
if (inode->i_bdev) inode->i_bdev->bd_op = di->de->u.fcb.ops;
else printk ("%s: read_inode(%d): no block device from bdget()\n",
DEVFS_NAME, (int) inode->i_ino);
+ inode->i_fop = &devfs_fops;
+ } else if ( S_ISFIFO (di->mode) ) {
+ inode->i_fop = &def_fifo_fops;
+ } else if ( S_ISREG (di->mode) ) {
+ inode->i_size = di->de->u.fcb.u.file.size;
+ inode->i_fop = &devfs_fops;
+ } else if (S_ISLNK(di->mode)) {
+ inode->i_op = &devfs_symlink_iops;
+ } else {
+ inode->i_fop = &devfs_fops;
}
- else if ( S_ISFIFO (di->mode) ) inode->i_fop = &def_fifo_fops;
- else if ( S_ISREG (di->mode) ) inode->i_size = di->de->u.fcb.u.file.size;
inode->i_mode = di->mode;
inode->i_uid = di->uid;
inode->i_gid = di->gid;
@@ -2438,11 +2447,10 @@ static int devfs_readdir (struct file *file, void *dirent, filldir_t filldir)
if (di == NULL)
{
if (fs_info->require_explicit) continue;
- /* Have to create the inode right now */
+ /* Have to create the inode right now to get the inum */
di = create_devfs_inode (de, fs_info);
if (di == NULL) return -ENOMEM;
}
- else if (di->ctime == 0) update_devfs_inode_from_entry (di);
err = (*filldir) (dirent, de->name, de->namelen,
file->f_pos, di->ino);
if (err == -EINVAL) break;
@@ -2659,6 +2667,7 @@ static int devfs_d_revalidate_wait (struct dentry *dentry, int flags)
/* Create an inode, now that the driver information is available
*/
if (di == NULL) di = create_devfs_inode (de, fs_info);
+ else if (de->no_persistence) update_devfs_inode_from_entry (di);
else if (di->ctime == 0) update_devfs_inode_from_entry (di);
else di->mode = (de->mode & ~S_IALLUGO) | (di->mode & S_IALLUGO);
if (di == NULL) return 1;
@@ -2784,6 +2793,7 @@ static struct dentry *devfs_lookup (struct inode *dir, struct dentry *dentry)
}
/* Create an inode, now that the driver information is available */
if (di == NULL) di = create_devfs_inode (de, fs_info);
+ else if (de->no_persistence) update_devfs_inode_from_entry (di);
else if (di->ctime == 0) update_devfs_inode_from_entry (di);
else di->mode = (de->mode & ~S_IALLUGO) | (di->mode & S_IALLUGO);
if (di == NULL) return ERR_PTR (-ENOMEM);
@@ -3079,49 +3089,24 @@ static int devfs_mknod (struct inode *dir, struct dentry *dentry, int mode,
static int devfs_readlink (struct dentry *dentry, char *buffer, int buflen)
{
- struct inode *inode = dentry->d_inode;
- struct devfs_inode *di;
+ struct devfs_inode *di=get_devfs_inode_from_vfs_inode(dentry->d_inode);
+ char *name = ERR_PTR(-ENOENT);
- if ( !inode || !S_ISLNK (inode->i_mode) ) return -EINVAL;
- di = get_devfs_inode_from_vfs_inode (inode);
- if (di == NULL) return -ENOENT;
- if (!di->de->registered) return -ENOENT;
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_RLINK)
- printk ("%s: readlink(): dentry: %p\n", DEVFS_NAME, dentry);
-#endif
- if (buflen > di->de->u.symlink.length + 1)
- buflen = di->de->u.symlink.length + 1;
- if (copy_to_user (buffer, di->de->u.symlink.linkname, buflen) == 0)
- return buflen;
- return -EFAULT;
+ if (di && di->de->registered)
+ name = di->de->u.symlink.linkname;
+ return vfs_readlink(dentry, buffer, buflen, name);
} /* End Function devfs_readlink */
static struct dentry *devfs_follow_link (struct dentry *dentry,
struct dentry *base,
unsigned int follow)
{
- struct inode *inode = dentry->d_inode;
- struct devfs_inode *di;
+ struct devfs_inode *di=get_devfs_inode_from_vfs_inode(dentry->d_inode);
+ char *name = ERR_PTR(-ENOENT);
- if ( !inode || !S_ISLNK (inode->i_mode) )
- {
- dget (dentry);
- dput (base);
- return dentry;
- }
-#ifdef CONFIG_DEVFS_DEBUG
- if (devfs_debug & DEBUG_I_FLINK)
- printk ("%s: follow_link(): dentry: %p\n", DEVFS_NAME, dentry);
-#endif
- di = get_devfs_inode_from_vfs_inode (inode);
- if ( (di == NULL) || !di->de->registered )
- {
- dput (base);
- return ERR_PTR (-ENOENT);
- }
- base = lookup_dentry (di->de->u.symlink.linkname, base, follow);
- return base;
+ if (di && di->de->registered)
+ name = di->de->u.symlink.linkname;
+ return vfs_follow_link(dentry, base, follow, name);
} /* End Function devfs_follow_link */
static struct inode_operations devfs_iops =
@@ -3133,6 +3118,11 @@ static struct inode_operations devfs_iops =
mkdir: devfs_mkdir,
rmdir: devfs_rmdir,
mknod: devfs_mknod,
+ setattr: devfs_notify_change,
+};
+
+static struct inode_operations devfs_symlink_iops =
+{
readlink: devfs_readlink,
follow_link: devfs_follow_link,
setattr: devfs_notify_change,
diff --git a/fs/devpts/root.c b/fs/devpts/root.c
index ed6258663..93df8a8ec 100644
--- a/fs/devpts/root.c
+++ b/fs/devpts/root.c
@@ -30,9 +30,7 @@ struct inode_operations devpts_root_inode_operations = {
};
static struct dentry_operations devpts_dentry_operations = {
- devpts_revalidate, /* d_revalidate */
- NULL, /* d_hash */
- NULL, /* d_compare */
+ d_revalidate: devpts_revalidate,
};
/*
diff --git a/fs/exec.c b/fs/exec.c
index 694bba675..1b881e123 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -84,6 +84,7 @@ int open_dentry(struct dentry * dentry, int mode)
struct list_head * l = NULL;
int fd, error;
+ lock_kernel();
if (inode->i_sb)
l = &inode->i_sb->s_files;
@@ -111,6 +112,7 @@ int open_dentry(struct dentry * dentry, int mode)
fd_install(fd, f);
dget(dentry);
}
+ unlock_kernel();
return fd;
out_filp:
@@ -120,6 +122,7 @@ out_filp:
out_fd:
put_unused_fd(fd);
out:
+ unlock_kernel();
return error;
}
diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c
index b8bcbd9e6..3a2e4ea82 100644
--- a/fs/fat/fatfs_syms.c
+++ b/fs/fat/fatfs_syms.c
@@ -52,6 +52,7 @@ EXPORT_SYMBOL(unlock_fat);
EXPORT_SYMBOL(fat_dir_ioctl);
EXPORT_SYMBOL(fat_add_entries);
EXPORT_SYMBOL(fat_dir_empty);
+EXPORT_SYMBOL(fat_truncate);
int init_fat_fs(void)
{
diff --git a/fs/fifo.c b/fs/fifo.c
index 33663cdf2..fcaf45f9f 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -41,6 +41,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
PIPE_BASE(*inode) = (char *) page;
PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
+ PIPE_WAITING_WRITERS(*inode) = PIPE_WAITING_READERS(*inode) = 0;
}
switch (filp->f_mode) {
diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c
index fb68e9ab2..0caa01ad0 100644
--- a/fs/hfs/sysdep.c
+++ b/fs/hfs/sysdep.c
@@ -24,12 +24,10 @@ static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
static void hfs_dentry_iput(struct dentry *, struct inode *);
struct dentry_operations hfs_dentry_operations =
{
- hfs_revalidate_dentry, /* d_revalidate(struct dentry *) */
- hfs_hash_dentry, /* d_hash */
- hfs_compare_dentry, /* d_compare */
- NULL, /* d_delete(struct dentry *) */
- NULL, /* d_release(struct dentry *) */
- hfs_dentry_iput /* d_iput(struct dentry *, struct inode *) */
+ d_revalidate: hfs_revalidate_dentry,
+ d_hash: hfs_hash_dentry,
+ d_compare: hfs_compare_dentry,
+ d_iput: hfs_dentry_iput,
};
/*
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c
index b5c3cf2e8..3aad4ba50 100644
--- a/fs/hpfs/dentry.c
+++ b/fs/hpfs/dentry.c
@@ -50,10 +50,8 @@ int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
}
struct dentry_operations hpfs_dentry_operations = {
- NULL, /* d_validate */
- hpfs_hash_dentry, /* d_hash */
- hpfs_compare_dentry, /* d_compare */
- NULL /* d_delete */
+ d_hash: hpfs_hash_dentry,
+ d_compare: hpfs_compare_dentry,
};
void hpfs_set_dentry_operations(struct dentry *dentry)
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index b4a633e9f..996d5ba68 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -84,29 +84,21 @@ static struct super_operations isofs_sops = {
static struct dentry_operations isofs_dentry_ops[] = {
{
- NULL, /* d_revalidate */
- isofs_hash,
- isofs_cmp,
- NULL /* d_delete */
+ d_hash: isofs_hash,
+ d_compare: isofs_cmp,
},
{
- NULL, /* d_revalidate */
- isofs_hashi,
- isofs_cmpi,
- NULL /* d_delete */
+ d_hash: isofs_hashi,
+ d_compare: isofs_cmpi,
},
#ifdef CONFIG_JOLIET
{
- NULL, /* d_revalidate */
- isofs_hash_ms,
- isofs_cmp_ms,
- NULL /* d_delete */
+ d_hash: isofs_hash_ms,
+ d_compare: isofs_cmp_ms,
},
{
- NULL, /* d_revalidate */
- isofs_hashi_ms,
- isofs_cmpi_ms,
- NULL /* d_delete */
+ d_hash: isofs_hashi_ms,
+ d_compare: isofs_cmpi_ms,
}
#endif
};
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index baef110d2..c18b46a37 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -106,13 +106,9 @@ static int minix_hash(struct dentry *dentry, struct qstr *qstr)
#endif
struct dentry_operations minix_dentry_operations = {
- 0, /* revalidate */
#ifndef NO_TRUNCATE
- minix_hash,
-#else
- 0,
+ d_hash: minix_hash,
#endif
- 0 /* compare */
};
static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index d74c71049..87a49fb47 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -200,12 +200,8 @@ old_compare:
static struct dentry_operations msdos_dentry_operations = {
- NULL, /* d_revalidate */
- msdos_hash,
- msdos_cmp,
- NULL, /* d_delete */
- NULL,
- NULL
+ d_hash: msdos_hash,
+ d_compare: msdos_cmp,
};
/*
diff --git a/fs/namei.c b/fs/namei.c
index 102f0e432..5f148b5a8 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -403,10 +403,10 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
if (IS_ERR(dentry))
break;
}
- }
- /* Check mountpoints.. */
- dentry = follow_mount(dentry);
+ /* Check mountpoints.. */
+ dentry = follow_mount(dentry);
+ }
base = do_follow_link(base, dentry, flags);
if (IS_ERR(base))
@@ -577,6 +577,9 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
int error;
+ mode &= S_IALLUGO & ~current->fs->umask;
+ mode |= S_IFREG;
+
error = may_create(dir, dentry);
if (error)
goto exit_lock;
@@ -610,9 +613,6 @@ struct dentry * open_namei(const char * pathname, int flag, int mode)
struct inode *inode;
struct dentry *dentry;
- mode &= S_IALLUGO & ~current->fs->umask;
- mode |= S_IFREG;
-
dentry = lookup_dentry(pathname, NULL, lookup_flags(flag));
if (IS_ERR(dentry))
return dentry;
@@ -739,14 +739,36 @@ exit:
return ERR_PTR(error);
}
+int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+{
+ int error = -EPERM;
+
+ mode &= ~current->fs->umask;
+
+ if (!S_ISFIFO(mode) && !capable(CAP_MKNOD))
+ goto exit_lock;
+
+ error = may_create(dir, dentry);
+ if (error)
+ goto exit_lock;
+
+ error = -EPERM;
+ if (!dir->i_op || !dir->i_op->mknod)
+ goto exit_lock;
+
+ DQUOT_INIT(dir);
+ error = dir->i_op->mknod(dir, dentry, mode, dev);
+exit_lock:
+ return error;
+}
+
struct dentry * do_mknod(const char * filename, int mode, dev_t dev)
{
int error;
struct dentry *dir;
struct dentry *dentry, *retval;
- mode &= ~current->fs->umask;
- dentry = lookup_dentry(filename, NULL, LOOKUP_FOLLOW);
+ dentry = lookup_dentry(filename, NULL, 0);
if (IS_ERR(dentry))
return dentry;
@@ -755,16 +777,8 @@ struct dentry * do_mknod(const char * filename, int mode, dev_t dev)
if (!check_parent(dir, dentry))
goto exit_lock;
- error = may_create(dir->d_inode, dentry);
- if (error)
- goto exit_lock;
+ error = vfs_mknod(dir->d_inode, dentry, mode, dev);
- error = -EPERM;
- if (!dir->d_inode->i_op || !dir->d_inode->i_op->mknod)
- goto exit_lock;
-
- DQUOT_INIT(dir->d_inode);
- error = dir->d_inode->i_op->mknod(dir->d_inode, dentry, mode, dev);
exit_lock:
retval = ERR_PTR(error);
if (!error)
@@ -778,47 +792,66 @@ asmlinkage long sys_mknod(const char * filename, int mode, dev_t dev)
{
int error;
char * tmp;
- struct dentry * dentry;
+ struct dentry * dentry, *dir;
- if (S_ISDIR(mode) || (!S_ISFIFO(mode) && !capable(CAP_MKNOD)))
+ if (S_ISDIR(mode))
return -EPERM;
tmp = getname(filename);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
- error = -EINVAL;
lock_kernel();
+ dentry = lookup_dentry(tmp, NULL, 0);
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
+ goto out;
+ dir = lock_parent(dentry);
+ error = -ENOENT;
+ if (!check_parent(dir, dentry))
+ goto out_unlock;
switch (mode & S_IFMT) {
- case 0:
- mode |= S_IFREG; /* fallthrough */
- case S_IFREG:
- mode &= ~current->fs->umask;
- dentry = lookup_dentry(filename, NULL, LOOKUP_FOLLOW);
- if (IS_ERR(dentry))
- error = PTR_ERR(dentry);
- else {
- struct dentry *dir = lock_parent(dentry);
- error = -ENOENT;
- if (check_parent(dir, dentry))
- error = vfs_create(dir->d_inode, dentry, mode);
- dput(dentry);
- }
+ case 0: case S_IFREG:
+ error = vfs_create(dir->d_inode, dentry, mode);
break;
case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
- dentry = do_mknod(tmp,mode,dev);
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
- dput(dentry);
- error = 0;
- }
+ error = vfs_mknod(dir->d_inode, dentry, mode, dev);
break;
+ case S_IFDIR:
+ error = -EPERM;
+ break;
+ default:
+ error = -EINVAL;
}
+out_unlock:
+ unlock_dir(dir);
+ dput(dentry);
+out:
unlock_kernel();
putname(tmp);
return error;
}
+int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ int error;
+
+ error = may_create(dir, dentry);
+ if (error)
+ goto exit_lock;
+
+ error = -EPERM;
+ if (!dir->i_op || !dir->i_op->mkdir)
+ goto exit_lock;
+
+ DQUOT_INIT(dir);
+ mode &= (S_IRWXUGO|S_ISVTX) & ~current->fs->umask;
+ error = dir->i_op->mkdir(dir, dentry, mode);
+
+exit_lock:
+ return error;
+}
+
static inline int do_mkdir(const char * pathname, int mode)
{
int error;
@@ -843,17 +876,7 @@ static inline int do_mkdir(const char * pathname, int mode)
if (!check_parent(dir, dentry))
goto exit_lock;
- error = may_create(dir->d_inode, dentry);
- if (error)
- goto exit_lock;
-
- error = -EPERM;
- if (!dir->d_inode->i_op || !dir->d_inode->i_op->mkdir)
- goto exit_lock;
-
- DQUOT_INIT(dir->d_inode);
- mode &= (S_IRWXUGO|S_ISVTX) & ~current->fs->umask;
- error = dir->d_inode->i_op->mkdir(dir->d_inode, dentry, mode);
+ error = vfs_mkdir(dir->d_inode, dentry, mode);
exit_lock:
unlock_dir(dir);
@@ -1027,6 +1050,25 @@ asmlinkage long sys_unlink(const char * pathname)
return error;
}
+int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
+{
+ int error;
+
+ error = may_create(dir, dentry);
+ if (error)
+ goto exit_lock;
+
+ error = -EPERM;
+ if (!dir->i_op || !dir->i_op->symlink)
+ goto exit_lock;
+
+ DQUOT_INIT(dir);
+ error = dir->i_op->symlink(dir, dentry, oldname);
+
+exit_lock:
+ return error;
+}
+
static inline int do_symlink(const char * oldname, const char * newname)
{
int error;
@@ -1044,16 +1086,7 @@ static inline int do_symlink(const char * oldname, const char * newname)
if (!check_parent(dir, dentry))
goto exit_lock;
- error = may_create(dir->d_inode, dentry);
- if (error)
- goto exit_lock;
-
- error = -EPERM;
- if (!dir->d_inode->i_op || !dir->d_inode->i_op->symlink)
- goto exit_lock;
-
- DQUOT_INIT(dir->d_inode);
- error = dir->d_inode->i_op->symlink(dir->d_inode, dentry, oldname);
+ error = vfs_symlink(dir->d_inode, dentry, oldname);
exit_lock:
unlock_dir(dir);
@@ -1083,10 +1116,43 @@ asmlinkage long sys_symlink(const char * oldname, const char * newname)
return error;
}
+int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
+{
+ struct inode *inode;
+ int error;
+
+ error = -ENOENT;
+ inode = old_dentry->d_inode;
+ if (!inode)
+ goto exit_lock;
+
+ error = may_create(dir, new_dentry);
+ if (error)
+ goto exit_lock;
+
+ error = -EXDEV;
+ if (dir->i_dev != inode->i_dev)
+ goto exit_lock;
+
+ /*
+ * A link to an append-only or immutable file cannot be created.
+ */
+ error = -EPERM;
+ if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+ goto exit_lock;
+ if (!dir->i_op || !dir->i_op->link)
+ goto exit_lock;
+
+ DQUOT_INIT(dir);
+ error = dir->i_op->link(old_dentry, dir, new_dentry);
+
+exit_lock:
+ return error;
+}
+
static inline int do_link(const char * oldname, const char * newname)
{
struct dentry *old_dentry, *new_dentry, *dir;
- struct inode *inode;
int error;
/*
@@ -1113,32 +1179,7 @@ static inline int do_link(const char * oldname, const char * newname)
if (!check_parent(dir, new_dentry))
goto exit_lock;
- error = -ENOENT;
- inode = old_dentry->d_inode;
- if (!inode)
- goto exit_lock;
-
- error = may_create(dir->d_inode, new_dentry);
- if (error)
- goto exit_lock;
-
- error = -EXDEV;
- if (dir->d_inode->i_dev != inode->i_dev)
- goto exit_lock;
-
- /*
- * A link to an append-only or immutable file cannot be created.
- */
- error = -EPERM;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- goto exit_lock;
-
- error = -EPERM;
- if (!dir->d_inode->i_op || !dir->d_inode->i_op->link)
- goto exit_lock;
-
- DQUOT_INIT(dir->d_inode);
- error = dir->d_inode->i_op->link(old_dentry, dir->d_inode, new_dentry);
+ error = vfs_link(old_dentry, dir->d_inode, new_dentry);
exit_lock:
unlock_dir(dir);
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 5c23664e3..ae5c13962 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -75,10 +75,10 @@ static void ncp_delete_dentry(struct dentry *);
struct dentry_operations ncp_dentry_operations =
{
- ncp_lookup_validate, /* d_revalidate(struct dentry *, int) */
- ncp_hash_dentry, /* d_hash */
- ncp_compare_dentry, /* d_compare */
- ncp_delete_dentry /* d_delete(struct dentry *) */
+ d_revalidate: ncp_lookup_validate,
+ d_hash: ncp_hash_dentry,
+ d_compare: ncp_compare_dentry,
+ d_delete: ncp_delete_dentry,
};
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 9dfc2f055..d111076c0 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -654,12 +654,9 @@ static void nfs_dentry_release(struct dentry *dentry)
}
struct dentry_operations nfs_dentry_operations = {
- nfs_lookup_revalidate, /* d_revalidate(struct dentry *, int) */
- NULL, /* d_hash */
- NULL, /* d_compare */
- nfs_dentry_delete, /* d_delete(struct dentry *) */
- nfs_dentry_release, /* d_release(struct dentry *) */
- NULL /* d_iput */
+ d_revalidate: nfs_lookup_revalidate,
+ d_delete: nfs_dentry_delete,
+ d_release: nfs_dentry_release,
};
#if 0 /* dead code */
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index aa03c0a16..084a17d9b 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -63,7 +63,10 @@ dprintk("filldir_one: seq=%d, ino=%ld, name=%s\n", buf->sequence, ino, name);
}
/*
- * Read a directory and return the name of the specified entry. i_sem is already down().
+ * Read a directory and return the name of the specified entry.
+ * i_sem is already down().
+ * The whole thing is a total BS. It should not be done via readdir(), damnit!
+ * Oh, well, as soon as it will be in filesystems...
*/
static int get_ino_name(struct dentry *dentry, struct qstr *name, unsigned long ino)
{
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 55c351852..c8389381f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -801,7 +801,6 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
{
struct dentry *dentry, *dchild;
struct inode *dirp;
- nfsd_dirop_t opfunc = NULL;
int err;
err = nfserr_perm;
@@ -856,45 +855,31 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
goto out;
}
+ if (!(iap->ia_valid & ATTR_MODE))
+ iap->ia_mode = 0;
+ iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type;
+
/*
* Get the dir op function pointer.
*/
err = nfserr_perm;
switch (type) {
case S_IFREG:
- opfunc = (nfsd_dirop_t) dirp->i_op->create;
+ err = vfs_create(dirp, dchild, iap->ia_mode);
break;
case S_IFDIR:
- opfunc = (nfsd_dirop_t) dirp->i_op->mkdir;
+ err = vfs_mkdir(dirp, dchild, iap->ia_mode);
break;
case S_IFCHR:
case S_IFBLK:
- /* The client is _NOT_ required to do security enforcement */
- if(!capable(CAP_SYS_ADMIN))
- {
- err = -EPERM;
- goto out;
- }
case S_IFIFO:
case S_IFSOCK:
- opfunc = dirp->i_op->mknod;
+ err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
break;
default:
printk("nfsd: bad file type %o in nfsd_create\n", type);
- err = nfserr_inval;
+ err = -EINVAL;
}
- if (!opfunc)
- goto out;
-
- if (!(iap->ia_valid & ATTR_MODE))
- iap->ia_mode = 0;
- iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type;
-
- /*
- * Call the dir op function to create the object.
- */
- DQUOT_INIT(dirp);
- err = opfunc(dirp, dchild, iap->ia_mode, rdev);
if (err < 0)
goto out_nfserr;
@@ -954,9 +939,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
err = nfserr_notdir;
if(!dirp->i_op || !dirp->i_op->lookup)
goto out;
- err = nfserr_perm;
- if(!dirp->i_op->create)
- goto out;
/*
* Compose the response file handle.
@@ -1003,7 +985,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
goto out;
}
- err = dirp->i_op->create(dirp, dchild, iap->ia_mode);
+ err = vfs_create(dirp, dchild, iap->ia_mode);
if (err < 0)
goto out_nfserr;
@@ -1101,7 +1083,6 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct iattr *iap)
{
struct dentry *dentry, *dnew;
- struct inode *dirp;
int err;
err = nfserr_noent;
@@ -1113,11 +1094,6 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
goto out;
dentry = fhp->fh_dentry;
- err = nfserr_perm;
- dirp = dentry->d_inode;
- if (!dirp->i_op || !dirp->i_op->symlink)
- goto out;
-
dnew = lookup_dentry(fname, dget(dentry), 0);
err = PTR_ERR(dnew);
if (IS_ERR(dnew))
@@ -1130,27 +1106,23 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
if (err)
goto out_compose;
- err = nfserr_exist;
- if (!dnew->d_inode) {
- DQUOT_INIT(dirp);
- err = dirp->i_op->symlink(dirp, dnew, path);
- if (!err) {
- if (EX_ISSYNC(fhp->fh_export))
- nfsd_sync_dir(dentry);
- if (iap) {
- iap->ia_valid &= ATTR_MODE /* ~(ATTR_MODE|ATTR_UID|ATTR_GID)*/;
- if (iap->ia_valid) {
- iap->ia_valid |= ATTR_CTIME;
- iap->ia_mode = (iap->ia_mode&S_IALLUGO)
- | S_IFLNK;
- err = notify_change(dnew, iap);
- if (!err && EX_ISSYNC(fhp->fh_export))
- write_inode_now(dentry->d_inode);
- }
- }
- } else
- err = nfserrno(-err);
- }
+ err = vfs_symlink(dentry->d_inode, dnew, path);
+ if (!err) {
+ if (EX_ISSYNC(fhp->fh_export))
+ nfsd_sync_dir(dentry);
+ if (iap) {
+ iap->ia_valid &= ATTR_MODE /* ~(ATTR_MODE|ATTR_UID|ATTR_GID)*/;
+ if (iap->ia_valid) {
+ iap->ia_valid |= ATTR_CTIME;
+ iap->ia_mode = (iap->ia_mode&S_IALLUGO)
+ | S_IFLNK;
+ err = notify_change(dnew, iap);
+ if (!err && EX_ISSYNC(fhp->fh_export))
+ write_inode_now(dentry->d_inode);
+ }
+ }
+ } else
+ err = nfserrno(-err);
fh_unlock(fhp);
/* Compose the fh so the dentry will be freed ... */
@@ -1201,34 +1173,22 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
if (err)
goto out_dput;
- err = nfserr_exist;
- if (dnew->d_inode)
- goto out_unlock;
-
dold = tfhp->fh_dentry;
dest = dold->d_inode;
- err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev;
- if (dirp->i_dev != dest->i_dev)
- goto out_unlock;
-
- err = nfserr_perm;
- if (IS_IMMUTABLE(dest) || IS_APPEND(dest))
- goto out_unlock;
- if (!dirp->i_op || !dirp->i_op->link)
- goto out_unlock;
-
- DQUOT_INIT(dirp);
- err = dirp->i_op->link(dold, dirp, dnew);
+ err = vfs_link(dold, dirp, dnew);
if (!err) {
if (EX_ISSYNC(ffhp->fh_export)) {
nfsd_sync_dir(ddir);
write_inode_now(dest);
}
- } else
- err = nfserrno(-err);
+ } else {
+ if (err == -EXDEV && rqstp->rq_vers == 2)
+ err = nfserr_acces;
+ else
+ err = nfserrno(-err);
+ }
-out_unlock:
fh_unlock(ffhp);
out_dput:
dput(dnew);
diff --git a/fs/ntfs/fs.c b/fs/ntfs/fs.c
index 6db74a14e..89888bb60 100644
--- a/fs/ntfs/fs.c
+++ b/fs/ntfs/fs.c
@@ -31,6 +31,7 @@
/* Forward declarations */
static struct inode_operations ntfs_dir_inode_operations;
+static struct file_operations ntfs_dir_operations;
#define ITEM_SIZE 2040
diff --git a/fs/pipe.c b/fs/pipe.c
index 6f8452534..020416013 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -41,6 +41,7 @@ static void pipe_wait(struct inode * inode)
schedule();
remove_wait_queue(PIPE_WAIT(*inode), &wait);
current->state = TASK_RUNNING;
+ down(PIPE_SEM(*inode));
}
static ssize_t
@@ -81,9 +82,7 @@ do_more_read:
PIPE_WAITING_READERS(*inode)--;
ret = -ERESTARTSYS;
if (signal_pending(current))
- goto out_nolock;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
+ goto out;
ret = 0;
if (!PIPE_EMPTY(*inode))
break;
@@ -162,7 +161,6 @@ pipe_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
if (down_interruptible(PIPE_SEM(*inode)))
goto out_nolock;
-do_more_write:
/* No readers yields SIGPIPE. */
if (!PIPE_READERS(*inode))
goto sigpipe;
@@ -182,9 +180,7 @@ do_more_write:
PIPE_WAITING_WRITERS(*inode)--;
ret = -ERESTARTSYS;
if (signal_pending(current))
- goto out_nolock;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
+ goto out;
if (!PIPE_READERS(*inode))
goto sigpipe;
@@ -230,20 +226,13 @@ do_more_write:
pipe_wait(inode);
PIPE_WAITING_WRITERS(*inode)--;
if (signal_pending(current))
- goto out_nolock;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
+ goto out;
if (!PIPE_READERS(*inode))
goto sigpipe;
} while (!PIPE_FREE(*inode));
ret = -EFAULT;
}
- if (count && PIPE_WAITING_READERS(*inode) &&
- !(filp->f_flags & O_NONBLOCK)) {
- wake_up_interruptible_sync(PIPE_WAIT(*inode));
- goto do_more_write;
- }
/* Signal readers asynchronously that there is more data. */
wake_up_interruptible(PIPE_WAIT(*inode));
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 54d93e131..4a191bfef 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -631,26 +631,19 @@ static void pid_delete_dentry(struct dentry * dentry)
static struct dentry_operations pid_fd_dentry_operations =
{
- pid_fd_revalidate, /* revalidate */
- NULL, /* d_hash */
- NULL, /* d_compare */
- pid_delete_dentry /* d_delete(struct dentry *) */
+ d_revalidate: pid_fd_revalidate,
+ d_delete: pid_delete_dentry,
};
static struct dentry_operations pid_dentry_operations =
{
- NULL, /* revalidate */
- NULL, /* d_hash */
- NULL, /* d_compare */
- pid_delete_dentry /* d_delete(struct dentry *) */
+ d_delete: pid_delete_dentry,
};
static struct dentry_operations pid_base_dentry_operations =
{
- pid_base_revalidate, /* revalidate */
- NULL, /* d_hash */
- NULL, /* d_compare */
- pid_delete_dentry /* d_delete(struct dentry *) */
+ d_revalidate: pid_base_revalidate,
+ d_delete: pid_delete_dentry,
};
/* Lookups */
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index fcfadbc99..28e0c08e5 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -226,10 +226,7 @@ proc_delete_dentry(struct dentry * dentry)
static struct dentry_operations proc_dentry_operations =
{
- NULL, /* revalidate */
- NULL, /* d_hash */
- NULL, /* d_compare */
- proc_delete_dentry /* d_delete(struct dentry *) */
+ d_delete: proc_delete_dentry,
};
/*
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 1f7ba6b99..b16b9a9df 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -665,8 +665,11 @@ void __init proc_misc_init(void)
}
}
#ifdef __powerpc__
- entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
- if (entry)
- entry->proc_fops = &ppc_htab_operations;
+ {
+ extern struct file_operations ppc_htab_operations;
+ entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
+ if (entry)
+ entry->proc_fops = &ppc_htab_operations;
+ }
#endif
}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 6cdb2ad19..cce48d845 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -70,9 +70,6 @@ void __init proc_root_init(void)
proc_mkdir("openprom", 0);
#endif
proc_tty_init();
-#ifdef __powerpc__
- proc_register(&proc_root, &proc_root_ppc_htab);
-#endif
#ifdef CONFIG_PROC_DEVICETREE
proc_device_tree_init();
#endif
diff --git a/fs/readdir.c b/fs/readdir.c
index 31bc56cc2..4bf222288 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -13,6 +13,21 @@
#include <asm/uaccess.h>
+int vfs_readdir(struct file *file,
+ int (*filler)(void *,const char *,int,off_t,ino_t),
+ void *buf)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ int res = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out;
+ down(&inode->i_sem);
+ res = file->f_op->readdir(file, buf, filler);
+ up(&inode->i_sem);
+out:
+ return res;
+}
+
/*
* Traditional linux readdir() handling..
*
@@ -57,46 +72,24 @@ asmlinkage int old_readdir(unsigned int fd, void * dirent, unsigned int count)
{
int error;
struct file * file;
- struct dentry * dentry;
- struct inode * inode;
struct readdir_callback buf;
- lock_kernel();
error = -EBADF;
file = fget(fd);
if (!file)
goto out;
- dentry = file->f_dentry;
- if (!dentry)
- goto out_putf;
-
- inode = dentry->d_inode;
- if (!inode)
- goto out_putf;
-
buf.count = 0;
buf.dirent = dirent;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
- /*
- * Get the inode's semaphore to prevent changes
- * to the directory while we read it.
- */
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, fillonedir);
- up(&inode->i_sem);
- if (error < 0)
- goto out_putf;
- error = buf.count;
+ lock_kernel();
+ error = vfs_readdir(file, fillonedir, &buf);
+ if (error >= 0)
+ error = buf.count;
+ unlock_kernel();
-out_putf:
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -145,42 +138,22 @@ static int filldir(void * __buf, const char * name, int namlen, off_t offset, in
asmlinkage long sys_getdents(unsigned int fd, void * dirent, unsigned int count)
{
struct file * file;
- struct dentry * dentry;
- struct inode * inode;
struct linux_dirent * lastdirent;
struct getdents_callback buf;
int error;
- lock_kernel();
error = -EBADF;
file = fget(fd);
if (!file)
goto out;
- dentry = file->f_dentry;
- if (!dentry)
- goto out_putf;
-
- inode = dentry->d_inode;
- if (!inode)
- goto out_putf;
-
buf.current_dir = (struct linux_dirent *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
- /*
- * Get the inode's semaphore to prevent changes
- * to the directory while we read it.
- */
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, filldir);
- up(&inode->i_sem);
+ lock_kernel();
+ error = vfs_readdir(file, filldir, &buf);
if (error < 0)
goto out_putf;
error = buf.error;
@@ -191,8 +164,8 @@ asmlinkage long sys_getdents(unsigned int fd, void * dirent, unsigned int count)
}
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c
index ca98fc9ca..91061a28f 100644
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -172,10 +172,10 @@ static void smb_delete_dentry(struct dentry *);
static struct dentry_operations smbfs_dentry_operations =
{
- smb_lookup_validate, /* d_revalidate(struct dentry *) */
- smb_hash_dentry, /* d_hash */
- smb_compare_dentry, /* d_compare */
- smb_delete_dentry /* d_delete(struct dentry *) */
+ d_revalidate: smb_lookup_validate,
+ d_hash: smb_hash_dentry,
+ d_compare: smb_compare_dentry,
+ d_delete: smb_delete_dentry,
};
/*
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index b2d7f1ab4..b92eed7db 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -9,6 +9,7 @@
#ifdef __KERNEL__
+#include <linux/config.h>
#include <linux/types.h>
#ifndef LINUX_VERSION_CODE
diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c
index be27c54a7..18dd76572 100644
--- a/fs/umsdos/dir.c
+++ b/fs/umsdos/dir.c
@@ -46,10 +46,8 @@ static void umsdos_dentry_dput(struct dentry *dentry)
struct dentry_operations umsdos_dentry_operations =
{
- umsdos_dentry_validate, /* d_revalidate(struct dentry *, int) */
- NULL, /* d_hash */
- NULL, /* d_compare */
- umsdos_dentry_dput /* d_delete(struct dentry *) */
+ d_revalidate: umsdos_dentry_validate,
+ d_delete: umsdos_dentry_dput,
};
struct UMSDOS_DIR_ONCE {
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index b07708286..476a09e9c 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -59,28 +59,22 @@ static int vfat_revalidate(struct dentry *dentry, int);
static struct dentry_operations vfat_dentry_ops[4] = {
{
- NULL, /* d_revalidate */
- vfat_hashi,
- vfat_cmpi,
- NULL /* d_delete */
+ d_hash: vfat_hashi,
+ d_compare: vfat_cmpi,
},
{
- vfat_revalidate,
- vfat_hashi,
- vfat_cmpi,
- NULL /* d_delete */
+ d_revalidate: vfat_revalidate,
+ d_hash: vfat_hashi,
+ d_compare: vfat_cmpi,
},
{
- NULL, /* d_revalidate */
- vfat_hash,
- vfat_cmp,
- NULL /* d_delete */
+ d_hash: vfat_hash,
+ d_compare: vfat_cmp,
},
{
- vfat_revalidate,
- vfat_hash,
- vfat_cmp,
- NULL /* d_delete */
+ d_revalidate: vfat_revalidate,
+ d_hash: vfat_hash,
+ d_compare: vfat_cmp,
}
};