0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/kernel.h>
0014 #include <linux/mm.h>
0015 #include <linux/string.h>
0016 #include <linux/stat.h>
0017 #include <linux/errno.h>
0018 #include <linux/unistd.h>
0019 #include <linux/mutex.h>
0020 #include <linux/spinlock.h>
0021 #include <linux/file.h>
0022 #include <linux/vfs.h>
0023 #include <linux/slab.h>
0024 #include <linux/pid_namespace.h>
0025 #include <linux/uaccess.h>
0026 #include <linux/fs.h>
0027 #include <linux/vmalloc.h>
0028
0029 #include <linux/coda.h>
0030 #include "coda_psdev.h"
0031 #include "coda_linux.h"
0032 #include "coda_cache.h"
0033
0034 #include "coda_int.h"
0035
0036
0037 static void coda_evict_inode(struct inode *);
0038 static void coda_put_super(struct super_block *);
0039 static int coda_statfs(struct dentry *dentry, struct kstatfs *buf);
0040
0041 static struct kmem_cache * coda_inode_cachep;
0042
0043 static struct inode *coda_alloc_inode(struct super_block *sb)
0044 {
0045 struct coda_inode_info *ei;
0046 ei = alloc_inode_sb(sb, coda_inode_cachep, GFP_KERNEL);
0047 if (!ei)
0048 return NULL;
0049 memset(&ei->c_fid, 0, sizeof(struct CodaFid));
0050 ei->c_flags = 0;
0051 ei->c_uid = GLOBAL_ROOT_UID;
0052 ei->c_cached_perm = 0;
0053 spin_lock_init(&ei->c_lock);
0054 return &ei->vfs_inode;
0055 }
0056
0057 static void coda_free_inode(struct inode *inode)
0058 {
0059 kmem_cache_free(coda_inode_cachep, ITOC(inode));
0060 }
0061
0062 static void init_once(void *foo)
0063 {
0064 struct coda_inode_info *ei = (struct coda_inode_info *) foo;
0065
0066 inode_init_once(&ei->vfs_inode);
0067 }
0068
0069 int __init coda_init_inodecache(void)
0070 {
0071 coda_inode_cachep = kmem_cache_create("coda_inode_cache",
0072 sizeof(struct coda_inode_info), 0,
0073 SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|
0074 SLAB_ACCOUNT, init_once);
0075 if (coda_inode_cachep == NULL)
0076 return -ENOMEM;
0077 return 0;
0078 }
0079
0080 void coda_destroy_inodecache(void)
0081 {
0082
0083
0084
0085
0086 rcu_barrier();
0087 kmem_cache_destroy(coda_inode_cachep);
0088 }
0089
0090 static int coda_remount(struct super_block *sb, int *flags, char *data)
0091 {
0092 sync_filesystem(sb);
0093 *flags |= SB_NOATIME;
0094 return 0;
0095 }
0096
0097
0098 static const struct super_operations coda_super_operations =
0099 {
0100 .alloc_inode = coda_alloc_inode,
0101 .free_inode = coda_free_inode,
0102 .evict_inode = coda_evict_inode,
0103 .put_super = coda_put_super,
0104 .statfs = coda_statfs,
0105 .remount_fs = coda_remount,
0106 };
0107
0108 static int get_device_index(struct coda_mount_data *data)
0109 {
0110 struct fd f;
0111 struct inode *inode;
0112 int idx;
0113
0114 if (data == NULL) {
0115 pr_warn("%s: Bad mount data\n", __func__);
0116 return -1;
0117 }
0118
0119 if (data->version != CODA_MOUNT_VERSION) {
0120 pr_warn("%s: Bad mount version\n", __func__);
0121 return -1;
0122 }
0123
0124 f = fdget(data->fd);
0125 if (!f.file)
0126 goto Ebadf;
0127 inode = file_inode(f.file);
0128 if (!S_ISCHR(inode->i_mode) || imajor(inode) != CODA_PSDEV_MAJOR) {
0129 fdput(f);
0130 goto Ebadf;
0131 }
0132
0133 idx = iminor(inode);
0134 fdput(f);
0135
0136 if (idx < 0 || idx >= MAX_CODADEVS) {
0137 pr_warn("%s: Bad minor number\n", __func__);
0138 return -1;
0139 }
0140
0141 return idx;
0142 Ebadf:
0143 pr_warn("%s: Bad file\n", __func__);
0144 return -1;
0145 }
0146
0147 static int coda_fill_super(struct super_block *sb, void *data, int silent)
0148 {
0149 struct inode *root = NULL;
0150 struct venus_comm *vc;
0151 struct CodaFid fid;
0152 int error;
0153 int idx;
0154
0155 if (task_active_pid_ns(current) != &init_pid_ns)
0156 return -EINVAL;
0157
0158 idx = get_device_index((struct coda_mount_data *) data);
0159
0160
0161 if(idx == -1)
0162 idx = 0;
0163
0164 pr_info("%s: device index: %i\n", __func__, idx);
0165
0166 vc = &coda_comms[idx];
0167 mutex_lock(&vc->vc_mutex);
0168
0169 if (!vc->vc_inuse) {
0170 pr_warn("%s: No pseudo device\n", __func__);
0171 error = -EINVAL;
0172 goto unlock_out;
0173 }
0174
0175 if (vc->vc_sb) {
0176 pr_warn("%s: Device already mounted\n", __func__);
0177 error = -EBUSY;
0178 goto unlock_out;
0179 }
0180
0181 vc->vc_sb = sb;
0182 mutex_unlock(&vc->vc_mutex);
0183
0184 sb->s_fs_info = vc;
0185 sb->s_flags |= SB_NOATIME;
0186 sb->s_blocksize = 4096;
0187 sb->s_blocksize_bits = 12;
0188 sb->s_magic = CODA_SUPER_MAGIC;
0189 sb->s_op = &coda_super_operations;
0190 sb->s_d_op = &coda_dentry_operations;
0191 sb->s_time_gran = 1;
0192 sb->s_time_min = S64_MIN;
0193 sb->s_time_max = S64_MAX;
0194
0195 error = super_setup_bdi(sb);
0196 if (error)
0197 goto error;
0198
0199
0200 error = venus_rootfid(sb, &fid);
0201 if ( error ) {
0202 pr_warn("%s: coda_get_rootfid failed with %d\n",
0203 __func__, error);
0204 goto error;
0205 }
0206 pr_info("%s: rootfid is %s\n", __func__, coda_f2s(&fid));
0207
0208
0209 root = coda_cnode_make(&fid, sb);
0210 if (IS_ERR(root)) {
0211 error = PTR_ERR(root);
0212 pr_warn("Failure of coda_cnode_make for root: error %d\n",
0213 error);
0214 goto error;
0215 }
0216
0217 pr_info("%s: rootinode is %ld dev %s\n",
0218 __func__, root->i_ino, root->i_sb->s_id);
0219 sb->s_root = d_make_root(root);
0220 if (!sb->s_root) {
0221 error = -EINVAL;
0222 goto error;
0223 }
0224 return 0;
0225
0226 error:
0227 mutex_lock(&vc->vc_mutex);
0228 vc->vc_sb = NULL;
0229 sb->s_fs_info = NULL;
0230 unlock_out:
0231 mutex_unlock(&vc->vc_mutex);
0232 return error;
0233 }
0234
0235 static void coda_put_super(struct super_block *sb)
0236 {
0237 struct venus_comm *vcp = coda_vcp(sb);
0238 mutex_lock(&vcp->vc_mutex);
0239 vcp->vc_sb = NULL;
0240 sb->s_fs_info = NULL;
0241 mutex_unlock(&vcp->vc_mutex);
0242 mutex_destroy(&vcp->vc_mutex);
0243
0244 pr_info("Bye bye.\n");
0245 }
0246
0247 static void coda_evict_inode(struct inode *inode)
0248 {
0249 truncate_inode_pages_final(&inode->i_data);
0250 clear_inode(inode);
0251 coda_cache_clear_inode(inode);
0252 }
0253
0254 int coda_getattr(struct user_namespace *mnt_userns, const struct path *path,
0255 struct kstat *stat, u32 request_mask, unsigned int flags)
0256 {
0257 int err = coda_revalidate_inode(d_inode(path->dentry));
0258 if (!err)
0259 generic_fillattr(&init_user_ns, d_inode(path->dentry), stat);
0260 return err;
0261 }
0262
0263 int coda_setattr(struct user_namespace *mnt_userns, struct dentry *de,
0264 struct iattr *iattr)
0265 {
0266 struct inode *inode = d_inode(de);
0267 struct coda_vattr vattr;
0268 int error;
0269
0270 memset(&vattr, 0, sizeof(vattr));
0271
0272 inode->i_ctime = current_time(inode);
0273 coda_iattr_to_vattr(iattr, &vattr);
0274 vattr.va_type = C_VNON;
0275
0276
0277 error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr);
0278
0279 if (!error) {
0280 coda_vattr_to_iattr(inode, &vattr);
0281 coda_cache_clear_inode(inode);
0282 }
0283 return error;
0284 }
0285
0286 const struct inode_operations coda_file_inode_operations = {
0287 .permission = coda_permission,
0288 .getattr = coda_getattr,
0289 .setattr = coda_setattr,
0290 };
0291
0292 static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
0293 {
0294 int error;
0295
0296 error = venus_statfs(dentry, buf);
0297
0298 if (error) {
0299
0300 buf->f_blocks = 9000000;
0301 buf->f_bfree = 9000000;
0302 buf->f_bavail = 9000000;
0303 buf->f_files = 9000000;
0304 buf->f_ffree = 9000000;
0305 }
0306
0307
0308 buf->f_type = CODA_SUPER_MAGIC;
0309 buf->f_bsize = 4096;
0310 buf->f_namelen = CODA_MAXNAMLEN;
0311
0312 return 0;
0313 }
0314
0315
0316
0317 static struct dentry *coda_mount(struct file_system_type *fs_type,
0318 int flags, const char *dev_name, void *data)
0319 {
0320 return mount_nodev(fs_type, flags, data, coda_fill_super);
0321 }
0322
0323 struct file_system_type coda_fs_type = {
0324 .owner = THIS_MODULE,
0325 .name = "coda",
0326 .mount = coda_mount,
0327 .kill_sb = kill_anon_super,
0328 .fs_flags = FS_BINARY_MOUNTDATA,
0329 };
0330 MODULE_ALIAS_FS("coda");
0331