aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/coda
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'fs/coda')
-rw-r--r--fs/coda/cache.c10
-rw-r--r--fs/coda/cnode.c38
-rw-r--r--fs/coda/coda_fs_i.h4
-rw-r--r--fs/coda/coda_linux.c2
-rw-r--r--fs/coda/coda_linux.h5
-rw-r--r--fs/coda/dir.c49
-rw-r--r--fs/coda/inode.c55
-rw-r--r--fs/coda/psdev.c1
-rw-r--r--fs/coda/upcall.c1
9 files changed, 91 insertions, 74 deletions
diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 958ae0e0ff8..69015787618 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -89,13 +89,17 @@ int coda_cache_check(struct inode *inode, int mask)
89/* this won't do any harm: just flag all children */ 89/* this won't do any harm: just flag all children */
90static void coda_flag_children(struct dentry *parent, int flag) 90static void coda_flag_children(struct dentry *parent, int flag)
91{ 91{
92 struct list_head *child;
92 struct dentry *de; 93 struct dentry *de;
93 94
94 spin_lock(&parent->d_lock); 95 spin_lock(&parent->d_lock);
95 list_for_each_entry(de, &parent->d_subdirs, d_u.d_child) { 96 list_for_each(child, &parent->d_subdirs)
97 {
98 de = list_entry(child, struct dentry, d_u.d_child);
96 /* don't know what to do with negative dentries */ 99 /* don't know what to do with negative dentries */
97 if (de->d_inode ) 100 if ( ! de->d_inode )
98 coda_flag_inode(de->d_inode, flag); 101 continue;
102 coda_flag_inode(de->d_inode, flag);
99 } 103 }
100 spin_unlock(&parent->d_lock); 104 spin_unlock(&parent->d_lock);
101 return; 105 return;
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c
index 911cf30d057..6475877b076 100644
--- a/fs/coda/cnode.c
+++ b/fs/coda/cnode.c
@@ -88,21 +88,24 @@ struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,
88 - link the two up if this is needed 88 - link the two up if this is needed
89 - fill in the attributes 89 - fill in the attributes
90*/ 90*/
91struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb) 91int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_block *sb)
92{ 92{
93 struct coda_vattr attr; 93 struct coda_vattr attr;
94 struct inode *inode;
95 int error; 94 int error;
96 95
97 /* We get inode numbers from Venus -- see venus source */ 96 /* We get inode numbers from Venus -- see venus source */
98 error = venus_getattr(sb, fid, &attr); 97 error = venus_getattr(sb, fid, &attr);
99 if (error) 98 if ( error ) {
100 return ERR_PTR(error); 99 *inode = NULL;
100 return error;
101 }
101 102
102 inode = coda_iget(sb, fid, &attr); 103 *inode = coda_iget(sb, fid, &attr);
103 if (IS_ERR(inode)) 104 if ( IS_ERR(*inode) ) {
104 printk("coda_cnode_make: coda_iget failed\n"); 105 printk("coda_cnode_make: coda_iget failed\n");
105 return inode; 106 return PTR_ERR(*inode);
107 }
108 return 0;
106} 109}
107 110
108 111
@@ -153,16 +156,19 @@ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)
153} 156}
154 157
155/* the CONTROL inode is made without asking attributes from Venus */ 158/* the CONTROL inode is made without asking attributes from Venus */
156struct inode *coda_cnode_makectl(struct super_block *sb) 159int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
157{ 160{
158 struct inode *inode = new_inode(sb); 161 int error = -ENOMEM;
159 if (inode) { 162
160 inode->i_ino = CTL_INO; 163 *inode = new_inode(sb);
161 inode->i_op = &coda_ioctl_inode_operations; 164 if (*inode) {
162 inode->i_fop = &coda_ioctl_operations; 165 (*inode)->i_ino = CTL_INO;
163 inode->i_mode = 0444; 166 (*inode)->i_op = &coda_ioctl_inode_operations;
164 return inode; 167 (*inode)->i_fop = &coda_ioctl_operations;
168 (*inode)->i_mode = 0444;
169 error = 0;
165 } 170 }
166 return ERR_PTR(-ENOMEM); 171
172 return error;
167} 173}
168 174
diff --git a/fs/coda/coda_fs_i.h b/fs/coda/coda_fs_i.h
index b24fdfd8a3f..e35071b1de0 100644
--- a/fs/coda/coda_fs_i.h
+++ b/fs/coda/coda_fs_i.h
@@ -49,9 +49,9 @@ struct coda_file_info {
49#define C_DYING 0x4 /* from venus (which died) */ 49#define C_DYING 0x4 /* from venus (which died) */
50#define C_PURGE 0x8 50#define C_PURGE 0x8
51 51
52struct inode *coda_cnode_make(struct CodaFid *, struct super_block *); 52int coda_cnode_make(struct inode **, struct CodaFid *, struct super_block *);
53struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr); 53struct inode *coda_iget(struct super_block *sb, struct CodaFid *fid, struct coda_vattr *attr);
54struct inode *coda_cnode_makectl(struct super_block *sb); 54int coda_cnode_makectl(struct inode **inode, struct super_block *sb);
55struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb); 55struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb);
56void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *); 56void coda_replace_fid(struct inode *, struct CodaFid *, struct CodaFid *);
57 57
diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c
index 854ace71268..2bdbcc11b37 100644
--- a/fs/coda/coda_linux.c
+++ b/fs/coda/coda_linux.c
@@ -104,7 +104,7 @@ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)
104 if (attr->va_gid != -1) 104 if (attr->va_gid != -1)
105 inode->i_gid = (gid_t) attr->va_gid; 105 inode->i_gid = (gid_t) attr->va_gid;
106 if (attr->va_nlink != -1) 106 if (attr->va_nlink != -1)
107 set_nlink(inode, attr->va_nlink); 107 inode->i_nlink = attr->va_nlink;
108 if (attr->va_size != -1) 108 if (attr->va_size != -1)
109 inode->i_size = attr->va_size; 109 inode->i_size = attr->va_size;
110 if (attr->va_size != -1) 110 if (attr->va_size != -1)
diff --git a/fs/coda/coda_linux.h b/fs/coda/coda_linux.h
index cc0ea9fe5ec..44e17e9c21a 100644
--- a/fs/coda/coda_linux.h
+++ b/fs/coda/coda_linux.h
@@ -59,11 +59,12 @@ void coda_sysctl_clean(void);
59 59
60#define CODA_ALLOC(ptr, cast, size) do { \ 60#define CODA_ALLOC(ptr, cast, size) do { \
61 if (size < PAGE_SIZE) \ 61 if (size < PAGE_SIZE) \
62 ptr = kzalloc((unsigned long) size, GFP_KERNEL); \ 62 ptr = kmalloc((unsigned long) size, GFP_KERNEL); \
63 else \ 63 else \
64 ptr = (cast)vzalloc((unsigned long) size); \ 64 ptr = (cast)vmalloc((unsigned long) size); \
65 if (!ptr) \ 65 if (!ptr) \
66 printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \ 66 printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
67 else memset( ptr, 0, size ); \
67} while (0) 68} while (0)
68 69
69 70
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 49fe52d2560..0239433f50c 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -30,14 +30,14 @@
30#include "coda_int.h" 30#include "coda_int.h"
31 31
32/* dir inode-ops */ 32/* dir inode-ops */
33static int coda_create(struct inode *dir, struct dentry *new, umode_t mode, bool excl); 33static int coda_create(struct inode *dir, struct dentry *new, int mode, struct nameidata *nd);
34static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, unsigned int flags); 34static struct dentry *coda_lookup(struct inode *dir, struct dentry *target, struct nameidata *nd);
35static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, 35static int coda_link(struct dentry *old_dentry, struct inode *dir_inode,
36 struct dentry *entry); 36 struct dentry *entry);
37static int coda_unlink(struct inode *dir_inode, struct dentry *entry); 37static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
38static int coda_symlink(struct inode *dir_inode, struct dentry *entry, 38static int coda_symlink(struct inode *dir_inode, struct dentry *entry,
39 const char *symname); 39 const char *symname);
40static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, umode_t mode); 40static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode);
41static int coda_rmdir(struct inode *dir_inode, struct dentry *entry); 41static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
42static int coda_rename(struct inode *old_inode, struct dentry *old_dentry, 42static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
43 struct inode *new_inode, struct dentry *new_dentry); 43 struct inode *new_inode, struct dentry *new_dentry);
@@ -46,7 +46,7 @@ static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
46static int coda_readdir(struct file *file, void *buf, filldir_t filldir); 46static int coda_readdir(struct file *file, void *buf, filldir_t filldir);
47 47
48/* dentry ops */ 48/* dentry ops */
49static int coda_dentry_revalidate(struct dentry *de, unsigned int flags); 49static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd);
50static int coda_dentry_delete(const struct dentry *); 50static int coda_dentry_delete(const struct dentry *);
51 51
52/* support routines */ 52/* support routines */
@@ -94,13 +94,14 @@ const struct file_operations coda_dir_operations = {
94 94
95/* inode operations for directories */ 95/* inode operations for directories */
96/* access routines: lookup, readlink, permission */ 96/* access routines: lookup, readlink, permission */
97static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsigned int flags) 97static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
98{ 98{
99 struct super_block *sb = dir->i_sb; 99 struct inode *inode = NULL;
100 struct CodaFid resfid = { { 0, } };
101 int type = 0;
102 int error = 0;
100 const char *name = entry->d_name.name; 103 const char *name = entry->d_name.name;
101 size_t length = entry->d_name.len; 104 size_t length = entry->d_name.len;
102 struct inode *inode;
103 int type = 0;
104 105
105 if (length > CODA_MAXNAMLEN) { 106 if (length > CODA_MAXNAMLEN) {
106 printk(KERN_ERR "name too long: lookup, %s (%*s)\n", 107 printk(KERN_ERR "name too long: lookup, %s (%*s)\n",
@@ -110,20 +111,22 @@ static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, unsig
110 111
111 /* control object, create inode on the fly */ 112 /* control object, create inode on the fly */
112 if (coda_isroot(dir) && coda_iscontrol(name, length)) { 113 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
113 inode = coda_cnode_makectl(sb); 114 error = coda_cnode_makectl(&inode, dir->i_sb);
114 type = CODA_NOCACHE; 115 type = CODA_NOCACHE;
115 } else { 116 goto exit;
116 struct CodaFid fid = { { 0, } };
117 int error = venus_lookup(sb, coda_i2f(dir), name, length,
118 &type, &fid);
119 inode = !error ? coda_cnode_make(&fid, sb) : ERR_PTR(error);
120 } 117 }
121 118
122 if (!IS_ERR(inode) && (type & CODA_NOCACHE)) 119 error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
123 coda_flag_inode(inode, C_VATTR | C_PURGE); 120 &type, &resfid);
121 if (!error)
122 error = coda_cnode_make(&inode, &resfid, dir->i_sb);
123
124 if (error && error != -ENOENT)
125 return ERR_PTR(error);
124 126
125 if (inode == ERR_PTR(-ENOENT)) 127exit:
126 inode = NULL; 128 if (inode && (type & CODA_NOCACHE))
129 coda_flag_inode(inode, C_VATTR | C_PURGE);
127 130
128 return d_splice_alias(inode, entry); 131 return d_splice_alias(inode, entry);
129} 132}
@@ -188,7 +191,7 @@ static inline void coda_dir_drop_nlink(struct inode *dir)
188} 191}
189 192
190/* creation routines: create, mknod, mkdir, link, symlink */ 193/* creation routines: create, mknod, mkdir, link, symlink */
191static int coda_create(struct inode *dir, struct dentry *de, umode_t mode, bool excl) 194static int coda_create(struct inode *dir, struct dentry *de, int mode, struct nameidata *nd)
192{ 195{
193 int error; 196 int error;
194 const char *name=de->d_name.name; 197 const char *name=de->d_name.name;
@@ -220,7 +223,7 @@ err_out:
220 return error; 223 return error;
221} 224}
222 225
223static int coda_mkdir(struct inode *dir, struct dentry *de, umode_t mode) 226static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
224{ 227{
225 struct inode *inode; 228 struct inode *inode;
226 struct coda_vattr attrs; 229 struct coda_vattr attrs;
@@ -337,7 +340,7 @@ static int coda_rmdir(struct inode *dir, struct dentry *de)
337 if (!error) { 340 if (!error) {
338 /* VFS may delete the child */ 341 /* VFS may delete the child */
339 if (de->d_inode) 342 if (de->d_inode)
340 clear_nlink(de->d_inode); 343 de->d_inode->i_nlink = 0;
341 344
342 /* fix the link count of the parent */ 345 /* fix the link count of the parent */
343 coda_dir_drop_nlink(dir); 346 coda_dir_drop_nlink(dir);
@@ -536,12 +539,12 @@ out:
536} 539}
537 540
538/* called when a cache lookup succeeds */ 541/* called when a cache lookup succeeds */
539static int coda_dentry_revalidate(struct dentry *de, unsigned int flags) 542static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd)
540{ 543{
541 struct inode *inode; 544 struct inode *inode;
542 struct coda_inode_info *cii; 545 struct coda_inode_info *cii;
543 546
544 if (flags & LOOKUP_RCU) 547 if (nd->flags & LOOKUP_RCU)
545 return -ECHILD; 548 return -ECHILD;
546 549
547 inode = de->d_inode; 550 inode = de->d_inode;
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index be2aa490948..871b2771546 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -21,6 +21,7 @@
21#include <linux/vfs.h> 21#include <linux/vfs.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23 23
24#include <asm/system.h>
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25 26
26#include <linux/fs.h> 27#include <linux/fs.h>
@@ -57,6 +58,7 @@ static struct inode *coda_alloc_inode(struct super_block *sb)
57static void coda_i_callback(struct rcu_head *head) 58static void coda_i_callback(struct rcu_head *head)
58{ 59{
59 struct inode *inode = container_of(head, struct inode, i_rcu); 60 struct inode *inode = container_of(head, struct inode, i_rcu);
61 INIT_LIST_HEAD(&inode->i_dentry);
60 kmem_cache_free(coda_inode_cachep, ITOC(inode)); 62 kmem_cache_free(coda_inode_cachep, ITOC(inode));
61} 63}
62 64
@@ -85,11 +87,6 @@ int coda_init_inodecache(void)
85 87
86void coda_destroy_inodecache(void) 88void coda_destroy_inodecache(void)
87{ 89{
88 /*
89 * Make sure all delayed rcu free inodes are flushed before we
90 * destroy cache.
91 */
92 rcu_barrier();
93 kmem_cache_destroy(coda_inode_cachep); 90 kmem_cache_destroy(coda_inode_cachep);
94} 91}
95 92
@@ -112,41 +109,43 @@ static const struct super_operations coda_super_operations =
112 109
113static int get_device_index(struct coda_mount_data *data) 110static int get_device_index(struct coda_mount_data *data)
114{ 111{
115 struct fd f; 112 struct file *file;
116 struct inode *inode; 113 struct inode *inode;
117 int idx; 114 int idx;
118 115
119 if (data == NULL) { 116 if(data == NULL) {
120 printk("coda_read_super: Bad mount data\n"); 117 printk("coda_read_super: Bad mount data\n");
121 return -1; 118 return -1;
122 } 119 }
123 120
124 if (data->version != CODA_MOUNT_VERSION) { 121 if(data->version != CODA_MOUNT_VERSION) {
125 printk("coda_read_super: Bad mount version\n"); 122 printk("coda_read_super: Bad mount version\n");
126 return -1; 123 return -1;
127 } 124 }
128 125
129 f = fdget(data->fd); 126 file = fget(data->fd);
130 if (!f.file) 127 inode = NULL;
131 goto Ebadf; 128 if(file)
132 inode = f.file->f_path.dentry->d_inode; 129 inode = file->f_path.dentry->d_inode;
133 if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) { 130
134 fdput(f); 131 if(!inode || !S_ISCHR(inode->i_mode) ||
135 goto Ebadf; 132 imajor(inode) != CODA_PSDEV_MAJOR) {
133 if(file)
134 fput(file);
135
136 printk("coda_read_super: Bad file\n");
137 return -1;
136 } 138 }
137 139
138 idx = iminor(inode); 140 idx = iminor(inode);
139 fdput(f); 141 fput(file);
140 142
141 if (idx < 0 || idx >= MAX_CODADEVS) { 143 if(idx < 0 || idx >= MAX_CODADEVS) {
142 printk("coda_read_super: Bad minor number\n"); 144 printk("coda_read_super: Bad minor number\n");
143 return -1; 145 return -1;
144 } 146 }
145 147
146 return idx; 148 return idx;
147Ebadf:
148 printk("coda_read_super: Bad file\n");
149 return -1;
150} 149}
151 150
152static int coda_fill_super(struct super_block *sb, void *data, int silent) 151static int coda_fill_super(struct super_block *sb, void *data, int silent)
@@ -206,16 +205,15 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
206 printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid)); 205 printk("coda_read_super: rootfid is %s\n", coda_f2s(&fid));
207 206
208 /* make root inode */ 207 /* make root inode */
209 root = coda_cnode_make(&fid, sb); 208 error = coda_cnode_make(&root, &fid, sb);
210 if (IS_ERR(root)) { 209 if ( error || !root ) {
211 error = PTR_ERR(root); 210 printk("Failure of coda_cnode_make for root: error %d\n", error);
212 printk("Failure of coda_cnode_make for root: error %d\n", error); 211 goto error;
213 goto error;
214 } 212 }
215 213
216 printk("coda_read_super: rootinode is %ld dev %s\n", 214 printk("coda_read_super: rootinode is %ld dev %s\n",
217 root->i_ino, root->i_sb->s_id); 215 root->i_ino, root->i_sb->s_id);
218 sb->s_root = d_make_root(root); 216 sb->s_root = d_alloc_root(root);
219 if (!sb->s_root) { 217 if (!sb->s_root) {
220 error = -EINVAL; 218 error = -EINVAL;
221 goto error; 219 goto error;
@@ -223,6 +221,9 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
223 return 0; 221 return 0;
224 222
225error: 223error:
224 if (root)
225 iput(root);
226
226 mutex_lock(&vc->vc_mutex); 227 mutex_lock(&vc->vc_mutex);
227 bdi_destroy(&vc->bdi); 228 bdi_destroy(&vc->bdi);
228 vc->vc_sb = NULL; 229 vc->vc_sb = NULL;
@@ -247,7 +248,7 @@ static void coda_put_super(struct super_block *sb)
247static void coda_evict_inode(struct inode *inode) 248static void coda_evict_inode(struct inode *inode)
248{ 249{
249 truncate_inode_pages(&inode->i_data, 0); 250 truncate_inode_pages(&inode->i_data, 0);
250 clear_inode(inode); 251 end_writeback(inode);
251 coda_cache_clear_inode(inode); 252 coda_cache_clear_inode(inode);
252} 253}
253 254
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 761d5b31b18..8f616e0e252 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -38,6 +38,7 @@
38#include <linux/mutex.h> 38#include <linux/mutex.h>
39#include <linux/device.h> 39#include <linux/device.h>
40#include <asm/io.h> 40#include <asm/io.h>
41#include <asm/system.h>
41#include <asm/poll.h> 42#include <asm/poll.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
43 44
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 0c68fd31fbf..9727e0c5257 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -14,6 +14,7 @@
14 * improvements to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>. 14 * improvements to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>.
15 */ 15 */
16 16
17#include <asm/system.h>
17#include <linux/signal.h> 18#include <linux/signal.h>
18#include <linux/sched.h> 19#include <linux/sched.h>
19#include <linux/types.h> 20#include <linux/types.h>