0001
0002
0003
0004
0005
0006
0007
0008 #include "minix.h"
0009
0010 static int add_nondir(struct dentry *dentry, struct inode *inode)
0011 {
0012 int err = minix_add_link(dentry, inode);
0013 if (!err) {
0014 d_instantiate(dentry, inode);
0015 return 0;
0016 }
0017 inode_dec_link_count(inode);
0018 iput(inode);
0019 return err;
0020 }
0021
0022 static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
0023 {
0024 struct inode * inode = NULL;
0025 ino_t ino;
0026
0027 if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen)
0028 return ERR_PTR(-ENAMETOOLONG);
0029
0030 ino = minix_inode_by_name(dentry);
0031 if (ino)
0032 inode = minix_iget(dir->i_sb, ino);
0033 return d_splice_alias(inode, dentry);
0034 }
0035
0036 static int minix_mknod(struct user_namespace *mnt_userns, struct inode *dir,
0037 struct dentry *dentry, umode_t mode, dev_t rdev)
0038 {
0039 int error;
0040 struct inode *inode;
0041
0042 if (!old_valid_dev(rdev))
0043 return -EINVAL;
0044
0045 inode = minix_new_inode(dir, mode, &error);
0046
0047 if (inode) {
0048 minix_set_inode(inode, rdev);
0049 mark_inode_dirty(inode);
0050 error = add_nondir(dentry, inode);
0051 }
0052 return error;
0053 }
0054
0055 static int minix_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
0056 struct dentry *dentry, umode_t mode)
0057 {
0058 int error;
0059 struct inode *inode = minix_new_inode(dir, mode, &error);
0060 if (inode) {
0061 minix_set_inode(inode, 0);
0062 mark_inode_dirty(inode);
0063 d_tmpfile(dentry, inode);
0064 }
0065 return error;
0066 }
0067
0068 static int minix_create(struct user_namespace *mnt_userns, struct inode *dir,
0069 struct dentry *dentry, umode_t mode, bool excl)
0070 {
0071 return minix_mknod(mnt_userns, dir, dentry, mode, 0);
0072 }
0073
0074 static int minix_symlink(struct user_namespace *mnt_userns, struct inode *dir,
0075 struct dentry *dentry, const char *symname)
0076 {
0077 int err = -ENAMETOOLONG;
0078 int i = strlen(symname)+1;
0079 struct inode * inode;
0080
0081 if (i > dir->i_sb->s_blocksize)
0082 goto out;
0083
0084 inode = minix_new_inode(dir, S_IFLNK | 0777, &err);
0085 if (!inode)
0086 goto out;
0087
0088 minix_set_inode(inode, 0);
0089 err = page_symlink(inode, symname, i);
0090 if (err)
0091 goto out_fail;
0092
0093 err = add_nondir(dentry, inode);
0094 out:
0095 return err;
0096
0097 out_fail:
0098 inode_dec_link_count(inode);
0099 iput(inode);
0100 goto out;
0101 }
0102
0103 static int minix_link(struct dentry * old_dentry, struct inode * dir,
0104 struct dentry *dentry)
0105 {
0106 struct inode *inode = d_inode(old_dentry);
0107
0108 inode->i_ctime = current_time(inode);
0109 inode_inc_link_count(inode);
0110 ihold(inode);
0111 return add_nondir(dentry, inode);
0112 }
0113
0114 static int minix_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
0115 struct dentry *dentry, umode_t mode)
0116 {
0117 struct inode * inode;
0118 int err;
0119
0120 inode_inc_link_count(dir);
0121
0122 inode = minix_new_inode(dir, S_IFDIR | mode, &err);
0123 if (!inode)
0124 goto out_dir;
0125
0126 minix_set_inode(inode, 0);
0127
0128 inode_inc_link_count(inode);
0129
0130 err = minix_make_empty(inode, dir);
0131 if (err)
0132 goto out_fail;
0133
0134 err = minix_add_link(dentry, inode);
0135 if (err)
0136 goto out_fail;
0137
0138 d_instantiate(dentry, inode);
0139 out:
0140 return err;
0141
0142 out_fail:
0143 inode_dec_link_count(inode);
0144 inode_dec_link_count(inode);
0145 iput(inode);
0146 out_dir:
0147 inode_dec_link_count(dir);
0148 goto out;
0149 }
0150
0151 static int minix_unlink(struct inode * dir, struct dentry *dentry)
0152 {
0153 int err = -ENOENT;
0154 struct inode * inode = d_inode(dentry);
0155 struct page * page;
0156 struct minix_dir_entry * de;
0157
0158 de = minix_find_entry(dentry, &page);
0159 if (!de)
0160 goto end_unlink;
0161
0162 err = minix_delete_entry(de, page);
0163 if (err)
0164 goto end_unlink;
0165
0166 inode->i_ctime = dir->i_ctime;
0167 inode_dec_link_count(inode);
0168 end_unlink:
0169 return err;
0170 }
0171
0172 static int minix_rmdir(struct inode * dir, struct dentry *dentry)
0173 {
0174 struct inode * inode = d_inode(dentry);
0175 int err = -ENOTEMPTY;
0176
0177 if (minix_empty_dir(inode)) {
0178 err = minix_unlink(dir, dentry);
0179 if (!err) {
0180 inode_dec_link_count(dir);
0181 inode_dec_link_count(inode);
0182 }
0183 }
0184 return err;
0185 }
0186
0187 static int minix_rename(struct user_namespace *mnt_userns,
0188 struct inode *old_dir, struct dentry *old_dentry,
0189 struct inode *new_dir, struct dentry *new_dentry,
0190 unsigned int flags)
0191 {
0192 struct inode * old_inode = d_inode(old_dentry);
0193 struct inode * new_inode = d_inode(new_dentry);
0194 struct page * dir_page = NULL;
0195 struct minix_dir_entry * dir_de = NULL;
0196 struct page * old_page;
0197 struct minix_dir_entry * old_de;
0198 int err = -ENOENT;
0199
0200 if (flags & ~RENAME_NOREPLACE)
0201 return -EINVAL;
0202
0203 old_de = minix_find_entry(old_dentry, &old_page);
0204 if (!old_de)
0205 goto out;
0206
0207 if (S_ISDIR(old_inode->i_mode)) {
0208 err = -EIO;
0209 dir_de = minix_dotdot(old_inode, &dir_page);
0210 if (!dir_de)
0211 goto out_old;
0212 }
0213
0214 if (new_inode) {
0215 struct page * new_page;
0216 struct minix_dir_entry * new_de;
0217
0218 err = -ENOTEMPTY;
0219 if (dir_de && !minix_empty_dir(new_inode))
0220 goto out_dir;
0221
0222 err = -ENOENT;
0223 new_de = minix_find_entry(new_dentry, &new_page);
0224 if (!new_de)
0225 goto out_dir;
0226 minix_set_link(new_de, new_page, old_inode);
0227 new_inode->i_ctime = current_time(new_inode);
0228 if (dir_de)
0229 drop_nlink(new_inode);
0230 inode_dec_link_count(new_inode);
0231 } else {
0232 err = minix_add_link(new_dentry, old_inode);
0233 if (err)
0234 goto out_dir;
0235 if (dir_de)
0236 inode_inc_link_count(new_dir);
0237 }
0238
0239 minix_delete_entry(old_de, old_page);
0240 mark_inode_dirty(old_inode);
0241
0242 if (dir_de) {
0243 minix_set_link(dir_de, dir_page, new_dir);
0244 inode_dec_link_count(old_dir);
0245 }
0246 return 0;
0247
0248 out_dir:
0249 if (dir_de) {
0250 kunmap(dir_page);
0251 put_page(dir_page);
0252 }
0253 out_old:
0254 kunmap(old_page);
0255 put_page(old_page);
0256 out:
0257 return err;
0258 }
0259
0260
0261
0262
0263 const struct inode_operations minix_dir_inode_operations = {
0264 .create = minix_create,
0265 .lookup = minix_lookup,
0266 .link = minix_link,
0267 .unlink = minix_unlink,
0268 .symlink = minix_symlink,
0269 .mkdir = minix_mkdir,
0270 .rmdir = minix_rmdir,
0271 .mknod = minix_mknod,
0272 .rename = minix_rename,
0273 .getattr = minix_getattr,
0274 .tmpfile = minix_tmpfile,
0275 };