#include <linux/coda_psdev.h>
#include <linux/coda_fs_i.h>
#include <linux/coda_cache.h>
-#include <linux/coda_proc.h>
#include "coda_int.h"
.read = generic_read_dir,
.readdir = coda_readdir,
.open = coda_open,
- .flush = coda_flush,
.release = coda_release,
.fsync = coda_fsync,
};
/* access routines: lookup, readlink, permission */
static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
{
- struct inode *res_inode = NULL;
+ struct inode *inode = NULL;
struct CodaFid resfid = { { 0, } };
- int dropme = 0; /* to indicate entry should not be cached */
int type = 0;
int error = 0;
const char *name = entry->d_name.name;
size_t length = entry->d_name.len;
-
- if ( length > CODA_MAXNAMLEN ) {
- printk("name too long: lookup, %s (%*s)\n",
+
+ if (length > CODA_MAXNAMLEN) {
+ printk(KERN_ERR "name too long: lookup, %s (%*s)\n",
coda_i2s(dir), (int)length, name);
return ERR_PTR(-ENAMETOOLONG);
}
+ /* control object, create inode on the fly */
+ if (coda_isroot(dir) && coda_iscontrol(name, length)) {
+ error = coda_cnode_makectl(&inode, dir->i_sb);
+ type = CODA_NOCACHE;
+ goto exit;
+ }
+
lock_kernel();
- /* control object, create inode on the fly */
- if (coda_isroot(dir) && coda_iscontrol(name, length)) {
- error = coda_cnode_makectl(&res_inode, dir->i_sb);
- dropme = 1;
- goto exit;
- }
- error = venus_lookup(dir->i_sb, coda_i2f(dir),
- (const char *)name, length, &type, &resfid);
+ error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
+ &type, &resfid);
+ if (!error)
+ error = coda_cnode_make(&inode, &resfid, dir->i_sb);
- res_inode = NULL;
- if (!error) {
- if (type & CODA_NOCACHE) {
- type &= (~CODA_NOCACHE);
- dropme = 1;
- }
+ unlock_kernel();
- error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
- if (error) {
- unlock_kernel();
- return ERR_PTR(error);
- }
- } else if (error != -ENOENT) {
- unlock_kernel();
+ if (error && error != -ENOENT)
return ERR_PTR(error);
- }
exit:
- entry->d_time = 0;
entry->d_op = &coda_dentry_operations;
- d_add(entry, res_inode);
- if ( dropme ) {
- d_drop(entry);
- coda_flag_inode(res_inode, C_VATTR);
- }
- unlock_kernel();
- return NULL;
+
+ if (inode && (type & CODA_NOCACHE))
+ coda_flag_inode(inode, C_VATTR | C_PURGE);
+
+ return d_splice_alias(inode, entry);
}
lock_kernel();
- coda_vfs_stat.permission++;
-
if (coda_cache_check(inode, mask))
goto out;
struct coda_vattr attrs;
lock_kernel();
- coda_vfs_stat.create++;
if (coda_isroot(dir) && coda_iscontrol(name, length)) {
unlock_kernel();
struct CodaFid newfid;
lock_kernel();
- coda_vfs_stat.mkdir++;
if (coda_isroot(dir) && coda_iscontrol(name, len)) {
unlock_kernel();
int error;
lock_kernel();
- coda_vfs_stat.link++;
if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
unlock_kernel();
const char *name = de->d_name.name;
int len = de->d_name.len;
int symlen;
- int error=0;
-
+ int error = 0;
+
lock_kernel();
- coda_vfs_stat.symlink++;
if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
unlock_kernel();
int len = de->d_name.len;
lock_kernel();
- coda_vfs_stat.unlink++;
error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
if ( error ) {
int error;
lock_kernel();
- coda_vfs_stat.rmdir++;
error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
if (!error) {
int error;
lock_kernel();
- coda_vfs_stat.rename++;
error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
coda_i2f(new_dir), old_length, new_length,
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
host_file = cfi->cfi_container;
- coda_vfs_stat.readdir++;
-
if (!host_file->f_op)
return -ENOTDIR;
vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
if (!vdir) return -ENOMEM;
- switch (coda_file->f_pos) {
- case 0:
+ if (coda_file->f_pos == 0) {
ret = filldir(buf, ".", 1, 0, de->d_inode->i_ino, DT_DIR);
- if (ret < 0) break;
+ if (ret < 0)
+ goto out;
result++;
coda_file->f_pos++;
- /* fallthrough */
- case 1:
+ }
+ if (coda_file->f_pos == 1) {
ret = filldir(buf, "..", 2, 1, de->d_parent->d_inode->i_ino, DT_DIR);
- if (ret < 0) break;
+ if (ret < 0)
+ goto out;
result++;
coda_file->f_pos++;
- /* fallthrough */
- default:
+ }
while (1) {
/* read entries from the directory file */
ret = kernel_read(host_file, coda_file->f_pos - 2, (char *)vdir,
* we've already established it is non-zero. */
coda_file->f_pos += vdir->d_reclen;
}
- }
+out:
kfree(vdir);
return result ? result : ret;
}