0001
0002
0003
0004
0005
0006 #include <linux/types.h>
0007 #include <linux/string.h>
0008 #include <linux/time.h>
0009
0010 #include <linux/coda.h>
0011 #include <linux/pagemap.h>
0012 #include "coda_psdev.h"
0013 #include "coda_linux.h"
0014
0015 static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2)
0016 {
0017 return memcmp(fid1, fid2, sizeof(*fid1)) == 0;
0018 }
0019
0020 static const struct inode_operations coda_symlink_inode_operations = {
0021 .get_link = page_get_link,
0022 .setattr = coda_setattr,
0023 };
0024
0025
0026 static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
0027 {
0028 coda_vattr_to_iattr(inode, attr);
0029
0030 if (S_ISREG(inode->i_mode)) {
0031 inode->i_op = &coda_file_inode_operations;
0032 inode->i_fop = &coda_file_operations;
0033 } else if (S_ISDIR(inode->i_mode)) {
0034 inode->i_op = &coda_dir_inode_operations;
0035 inode->i_fop = &coda_dir_operations;
0036 } else if (S_ISLNK(inode->i_mode)) {
0037 inode->i_op = &coda_symlink_inode_operations;
0038 inode_nohighmem(inode);
0039 inode->i_data.a_ops = &coda_symlink_aops;
0040 inode->i_mapping = &inode->i_data;
0041 } else
0042 init_special_inode(inode, inode->i_mode, huge_decode_dev(attr->va_rdev));
0043 }
0044
0045 static int coda_test_inode(struct inode *inode, void *data)
0046 {
0047 struct CodaFid *fid = (struct CodaFid *)data;
0048 struct coda_inode_info *cii = ITOC(inode);
0049 return coda_fideq(&cii->c_fid, fid);
0050 }
0051
0052 static int coda_set_inode(struct inode *inode, void *data)
0053 {
0054 struct CodaFid *fid = (struct CodaFid *)data;
0055 struct coda_inode_info *cii = ITOC(inode);
0056 cii->c_fid = *fid;
0057 return 0;
0058 }
0059
0060 struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,
0061 struct coda_vattr * attr)
0062 {
0063 struct inode *inode;
0064 struct coda_inode_info *cii;
0065 unsigned long hash = coda_f2i(fid);
0066 umode_t inode_type = coda_inode_type(attr);
0067
0068 retry:
0069 inode = iget5_locked(sb, hash, coda_test_inode, coda_set_inode, fid);
0070 if (!inode)
0071 return ERR_PTR(-ENOMEM);
0072
0073 if (inode->i_state & I_NEW) {
0074 cii = ITOC(inode);
0075
0076 inode->i_ino = hash;
0077
0078 cii->c_mapcount = 0;
0079 coda_fill_inode(inode, attr);
0080 unlock_new_inode(inode);
0081 } else if ((inode->i_mode & S_IFMT) != inode_type) {
0082
0083 remove_inode_hash(inode);
0084 coda_flag_inode(inode, C_PURGE);
0085 iput(inode);
0086 goto retry;
0087 }
0088 return inode;
0089 }
0090
0091
0092
0093
0094
0095
0096
0097 struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb)
0098 {
0099 struct coda_vattr attr;
0100 struct inode *inode;
0101 int error;
0102
0103
0104 error = venus_getattr(sb, fid, &attr);
0105 if (error)
0106 return ERR_PTR(error);
0107
0108 inode = coda_iget(sb, fid, &attr);
0109 if (IS_ERR(inode))
0110 pr_warn("%s: coda_iget failed\n", __func__);
0111 return inode;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid,
0124 struct CodaFid *newfid)
0125 {
0126 struct coda_inode_info *cii = ITOC(inode);
0127 unsigned long hash = coda_f2i(newfid);
0128
0129 BUG_ON(!coda_fideq(&cii->c_fid, oldfid));
0130
0131
0132
0133 remove_inode_hash(inode);
0134 cii->c_fid = *newfid;
0135 inode->i_ino = hash;
0136 __insert_inode_hash(inode, hash);
0137 }
0138
0139
0140 struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)
0141 {
0142 struct inode *inode;
0143 unsigned long hash = coda_f2i(fid);
0144
0145 inode = ilookup5(sb, hash, coda_test_inode, fid);
0146 if ( !inode )
0147 return NULL;
0148
0149
0150
0151 BUG_ON(inode->i_state & I_NEW);
0152
0153 return inode;
0154 }
0155
0156 struct coda_file_info *coda_ftoc(struct file *file)
0157 {
0158 struct coda_file_info *cfi = file->private_data;
0159
0160 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
0161
0162 return cfi;
0163
0164 }
0165
0166
0167 struct inode *coda_cnode_makectl(struct super_block *sb)
0168 {
0169 struct inode *inode = new_inode(sb);
0170 if (inode) {
0171 inode->i_ino = CTL_INO;
0172 inode->i_op = &coda_ioctl_inode_operations;
0173 inode->i_fop = &coda_ioctl_operations;
0174 inode->i_mode = 0444;
0175 return inode;
0176 }
0177 return ERR_PTR(-ENOMEM);
0178 }
0179