#include <linux/coda_cache.h>
#include <linux/coda_proc.h>
+#include "coda_int.h"
+
/* dir inode-ops */
static int coda_create(struct inode *dir, struct dentry *new, int mode, struct nameidata *nd);
-static int coda_mknod(struct inode *dir, struct dentry *new, int mode, dev_t rdev);
static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd);
static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
struct dentry *entry);
/* support routines */
static int coda_venus_readdir(struct file *filp, filldir_t filldir,
void *dirent, struct dentry *dir);
-int coda_fsync(struct file *, struct dentry *dentry, int datasync);
-int coda_hasmknod;
+/* same as fs/bad_inode.c */
+static int coda_return_EIO(void)
+{
+ return -EIO;
+}
+#define CODA_EIO_ERROR ((void *) (coda_return_EIO))
-struct dentry_operations coda_dentry_operations =
+static struct dentry_operations coda_dentry_operations =
{
.d_revalidate = coda_dentry_revalidate,
.d_delete = coda_dentry_delete,
.symlink = coda_symlink,
.mkdir = coda_mkdir,
.rmdir = coda_rmdir,
- .mknod = coda_mknod,
+ .mknod = CODA_EIO_ERROR,
.rename = coda_rename,
.permission = coda_permission,
.getattr = coda_getattr,
.setattr = coda_setattr,
};
-struct file_operations coda_dir_operations = {
+const struct file_operations coda_dir_operations = {
.llseek = generic_file_llseek,
.read = generic_read_dir,
.readdir = coda_readdir,
/* optimistically we can also act as if our nose bleeds. The
* granularity of the mtime is coarse anyways so we might actually be
* right most of the time. Note: we only do this for directories. */
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
#endif
if (link)
dir->i_nlink += link;
}
error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
- 0, mode, 0, &newfid, &attrs);
+ 0, mode, &newfid, &attrs);
if ( error ) {
unlock_kernel();
return 0;
}
-static int coda_mknod(struct inode *dir, struct dentry *de, int mode, dev_t rdev)
-{
- int error=0;
- const char *name=de->d_name.name;
- int length=de->d_name.len;
- struct inode *inode;
- struct CodaFid newfid;
- struct coda_vattr attrs;
-
- if ( coda_hasmknod == 0 )
- return -EIO;
-
- if (!old_valid_dev(rdev))
- return -EINVAL;
-
- lock_kernel();
- coda_vfs_stat.create++;
-
- if (coda_isroot(dir) && coda_iscontrol(name, length)) {
- unlock_kernel();
- return -EPERM;
- }
-
- error = venus_create(dir->i_sb, coda_i2f(dir), name, length,
- 0, mode, rdev, &newfid, &attrs);
-
- if ( error ) {
- unlock_kernel();
- d_drop(de);
- return error;
- }
-
- inode = coda_iget(dir->i_sb, &newfid, &attrs);
- if ( IS_ERR(inode) ) {
- unlock_kernel();
- d_drop(de);
- return PTR_ERR(inode);
- }
-
- /* invalidate the directory cnode's attributes */
- coda_dir_changed(dir, 0);
- unlock_kernel();
- d_instantiate(de, inode);
- return 0;
-}
-
static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
{
struct inode *inode;
coda_dir_changed(dir_inode, 0);
atomic_inc(&inode->i_count);
d_instantiate(de, inode);
- inode->i_nlink++;
+ inc_nlink(inode);
out:
unlock_kernel();
}
coda_dir_changed(dir, 0);
- de->d_inode->i_nlink--;
+ drop_nlink(de->d_inode);
unlock_kernel();
return 0;
}
coda_dir_changed(dir, -1);
- de->d_inode->i_nlink--;
+ drop_nlink(de->d_inode);
d_delete(de);
unlock_kernel();
/* file operations for directories */
int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir)
{
- struct dentry *coda_dentry = coda_file->f_dentry;
+ struct dentry *coda_dentry = coda_file->f_path.dentry;
struct coda_file_info *cfi;
struct file *host_file;
struct inode *host_inode;
coda_vfs_stat.readdir++;
- host_inode = host_file->f_dentry->d_inode;
- down(&host_inode->i_sem);
+ host_inode = host_file->f_path.dentry->d_inode;
+ mutex_lock(&host_inode->i_mutex);
host_file->f_pos = coda_file->f_pos;
if (!host_file->f_op->readdir) {
}
out:
coda_file->f_pos = host_file->f_pos;
- up(&host_inode->i_sem);
+ mutex_unlock(&host_inode->i_mutex);
return ret;
}
ino_t ino;
int ret, i;
- vdir = (struct venus_dirent *)kmalloc(sizeof(*vdir), GFP_KERNEL);
+ vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
if (!vdir) return -ENOMEM;
i = filp->f_pos;
/* catch truncated reads */
if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
printk("coda_venus_readdir: short read: %ld\n",
- filp->f_dentry->d_inode->i_ino);
+ filp->f_path.dentry->d_inode->i_ino);
ret = -EBADF;
break;
}
/* validate whether the directory file actually makes sense */
if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
printk("coda_venus_readdir: Invalid dir: %ld\n",
- filp->f_dentry->d_inode->i_ino);
+ filp->f_path.dentry->d_inode->i_ino);
ret = -EBADF;
break;
}