1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * JFFS2 -- Journalling Flash File System, Version 2.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright © 2001-2007 Red Hat, Inc.
5*4882a593Smuzhiyun * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Created by David Woodhouse <dwmw2@infradead.org>
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * For licensing information, see the file 'LICENCE' in this directory.
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/slab.h>
17*4882a593Smuzhiyun #include <linux/fs.h>
18*4882a593Smuzhiyun #include <linux/crc32.h>
19*4882a593Smuzhiyun #include <linux/jffs2.h>
20*4882a593Smuzhiyun #include "jffs2_fs_i.h"
21*4882a593Smuzhiyun #include "jffs2_fs_sb.h"
22*4882a593Smuzhiyun #include <linux/time.h>
23*4882a593Smuzhiyun #include "nodelist.h"
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun static int jffs2_readdir (struct file *, struct dir_context *);
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun static int jffs2_create (struct inode *,struct dentry *,umode_t,
28*4882a593Smuzhiyun bool);
29*4882a593Smuzhiyun static struct dentry *jffs2_lookup (struct inode *,struct dentry *,
30*4882a593Smuzhiyun unsigned int);
31*4882a593Smuzhiyun static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
32*4882a593Smuzhiyun static int jffs2_unlink (struct inode *,struct dentry *);
33*4882a593Smuzhiyun static int jffs2_symlink (struct inode *,struct dentry *,const char *);
34*4882a593Smuzhiyun static int jffs2_mkdir (struct inode *,struct dentry *,umode_t);
35*4882a593Smuzhiyun static int jffs2_rmdir (struct inode *,struct dentry *);
36*4882a593Smuzhiyun static int jffs2_mknod (struct inode *,struct dentry *,umode_t,dev_t);
37*4882a593Smuzhiyun static int jffs2_rename (struct inode *, struct dentry *,
38*4882a593Smuzhiyun struct inode *, struct dentry *,
39*4882a593Smuzhiyun unsigned int);
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun const struct file_operations jffs2_dir_operations =
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun .read = generic_read_dir,
44*4882a593Smuzhiyun .iterate_shared=jffs2_readdir,
45*4882a593Smuzhiyun .unlocked_ioctl=jffs2_ioctl,
46*4882a593Smuzhiyun .fsync = jffs2_fsync,
47*4882a593Smuzhiyun .llseek = generic_file_llseek,
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun const struct inode_operations jffs2_dir_inode_operations =
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun .create = jffs2_create,
54*4882a593Smuzhiyun .lookup = jffs2_lookup,
55*4882a593Smuzhiyun .link = jffs2_link,
56*4882a593Smuzhiyun .unlink = jffs2_unlink,
57*4882a593Smuzhiyun .symlink = jffs2_symlink,
58*4882a593Smuzhiyun .mkdir = jffs2_mkdir,
59*4882a593Smuzhiyun .rmdir = jffs2_rmdir,
60*4882a593Smuzhiyun .mknod = jffs2_mknod,
61*4882a593Smuzhiyun .rename = jffs2_rename,
62*4882a593Smuzhiyun .get_acl = jffs2_get_acl,
63*4882a593Smuzhiyun .set_acl = jffs2_set_acl,
64*4882a593Smuzhiyun .setattr = jffs2_setattr,
65*4882a593Smuzhiyun .listxattr = jffs2_listxattr,
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /***********************************************************************/
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun /* We keep the dirent list sorted in increasing order of name hash,
72*4882a593Smuzhiyun and we use the same hash function as the dentries. Makes this
73*4882a593Smuzhiyun nice and simple
74*4882a593Smuzhiyun */
jffs2_lookup(struct inode * dir_i,struct dentry * target,unsigned int flags)75*4882a593Smuzhiyun static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
76*4882a593Smuzhiyun unsigned int flags)
77*4882a593Smuzhiyun {
78*4882a593Smuzhiyun struct jffs2_inode_info *dir_f;
79*4882a593Smuzhiyun struct jffs2_full_dirent *fd = NULL, *fd_list;
80*4882a593Smuzhiyun uint32_t ino = 0;
81*4882a593Smuzhiyun struct inode *inode = NULL;
82*4882a593Smuzhiyun unsigned int nhash;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun jffs2_dbg(1, "jffs2_lookup()\n");
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun if (target->d_name.len > JFFS2_MAX_NAME_LEN)
87*4882a593Smuzhiyun return ERR_PTR(-ENAMETOOLONG);
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun dir_f = JFFS2_INODE_INFO(dir_i);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* The 'nhash' on the fd_list is not the same as the dentry hash */
92*4882a593Smuzhiyun nhash = full_name_hash(NULL, target->d_name.name, target->d_name.len);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun mutex_lock(&dir_f->sem);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
97*4882a593Smuzhiyun for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= nhash; fd_list = fd_list->next) {
98*4882a593Smuzhiyun if (fd_list->nhash == nhash &&
99*4882a593Smuzhiyun (!fd || fd_list->version > fd->version) &&
100*4882a593Smuzhiyun strlen(fd_list->name) == target->d_name.len &&
101*4882a593Smuzhiyun !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) {
102*4882a593Smuzhiyun fd = fd_list;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun if (fd)
106*4882a593Smuzhiyun ino = fd->ino;
107*4882a593Smuzhiyun mutex_unlock(&dir_f->sem);
108*4882a593Smuzhiyun if (ino) {
109*4882a593Smuzhiyun inode = jffs2_iget(dir_i->i_sb, ino);
110*4882a593Smuzhiyun if (IS_ERR(inode))
111*4882a593Smuzhiyun pr_warn("iget() failed for ino #%u\n", ino);
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun return d_splice_alias(inode, target);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /***********************************************************************/
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun
jffs2_readdir(struct file * file,struct dir_context * ctx)120*4882a593Smuzhiyun static int jffs2_readdir(struct file *file, struct dir_context *ctx)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun struct inode *inode = file_inode(file);
123*4882a593Smuzhiyun struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
124*4882a593Smuzhiyun struct jffs2_full_dirent *fd;
125*4882a593Smuzhiyun unsigned long curofs = 1;
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun jffs2_dbg(1, "jffs2_readdir() for dir_i #%lu\n", inode->i_ino);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun if (!dir_emit_dots(file, ctx))
130*4882a593Smuzhiyun return 0;
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun mutex_lock(&f->sem);
133*4882a593Smuzhiyun for (fd = f->dents; fd; fd = fd->next) {
134*4882a593Smuzhiyun curofs++;
135*4882a593Smuzhiyun /* First loop: curofs = 2; pos = 2 */
136*4882a593Smuzhiyun if (curofs < ctx->pos) {
137*4882a593Smuzhiyun jffs2_dbg(2, "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
138*4882a593Smuzhiyun fd->name, fd->ino, fd->type, curofs, (unsigned long)ctx->pos);
139*4882a593Smuzhiyun continue;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun if (!fd->ino) {
142*4882a593Smuzhiyun jffs2_dbg(2, "Skipping deletion dirent \"%s\"\n",
143*4882a593Smuzhiyun fd->name);
144*4882a593Smuzhiyun ctx->pos++;
145*4882a593Smuzhiyun continue;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun jffs2_dbg(2, "Dirent %ld: \"%s\", ino #%u, type %d\n",
148*4882a593Smuzhiyun (unsigned long)ctx->pos, fd->name, fd->ino, fd->type);
149*4882a593Smuzhiyun if (!dir_emit(ctx, fd->name, strlen(fd->name), fd->ino, fd->type))
150*4882a593Smuzhiyun break;
151*4882a593Smuzhiyun ctx->pos++;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun mutex_unlock(&f->sem);
154*4882a593Smuzhiyun return 0;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun /***********************************************************************/
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun
jffs2_create(struct inode * dir_i,struct dentry * dentry,umode_t mode,bool excl)160*4882a593Smuzhiyun static int jffs2_create(struct inode *dir_i, struct dentry *dentry,
161*4882a593Smuzhiyun umode_t mode, bool excl)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun struct jffs2_raw_inode *ri;
164*4882a593Smuzhiyun struct jffs2_inode_info *f, *dir_f;
165*4882a593Smuzhiyun struct jffs2_sb_info *c;
166*4882a593Smuzhiyun struct inode *inode;
167*4882a593Smuzhiyun int ret;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun ri = jffs2_alloc_raw_inode();
170*4882a593Smuzhiyun if (!ri)
171*4882a593Smuzhiyun return -ENOMEM;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun c = JFFS2_SB_INFO(dir_i->i_sb);
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun jffs2_dbg(1, "%s()\n", __func__);
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun inode = jffs2_new_inode(dir_i, mode, ri);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun if (IS_ERR(inode)) {
180*4882a593Smuzhiyun jffs2_dbg(1, "jffs2_new_inode() failed\n");
181*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
182*4882a593Smuzhiyun return PTR_ERR(inode);
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun inode->i_op = &jffs2_file_inode_operations;
186*4882a593Smuzhiyun inode->i_fop = &jffs2_file_operations;
187*4882a593Smuzhiyun inode->i_mapping->a_ops = &jffs2_file_address_operations;
188*4882a593Smuzhiyun inode->i_mapping->nrpages = 0;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun f = JFFS2_INODE_INFO(inode);
191*4882a593Smuzhiyun dir_f = JFFS2_INODE_INFO(dir_i);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /* jffs2_do_create() will want to lock it, _after_ reserving
194*4882a593Smuzhiyun space and taking c-alloc_sem. If we keep it locked here,
195*4882a593Smuzhiyun lockdep gets unhappy (although it's a false positive;
196*4882a593Smuzhiyun nothing else will be looking at this inode yet so there's
197*4882a593Smuzhiyun no chance of AB-BA deadlock involving its f->sem). */
198*4882a593Smuzhiyun mutex_unlock(&f->sem);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun ret = jffs2_do_create(c, dir_f, f, ri, &dentry->d_name);
201*4882a593Smuzhiyun if (ret)
202*4882a593Smuzhiyun goto fail;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime));
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun jffs2_dbg(1, "%s(): Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
209*4882a593Smuzhiyun __func__, inode->i_ino, inode->i_mode, inode->i_nlink,
210*4882a593Smuzhiyun f->inocache->pino_nlink, inode->i_mapping->nrpages);
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun d_instantiate_new(dentry, inode);
213*4882a593Smuzhiyun return 0;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun fail:
216*4882a593Smuzhiyun iget_failed(inode);
217*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
218*4882a593Smuzhiyun return ret;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun /***********************************************************************/
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun
jffs2_unlink(struct inode * dir_i,struct dentry * dentry)224*4882a593Smuzhiyun static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb);
227*4882a593Smuzhiyun struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
228*4882a593Smuzhiyun struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(d_inode(dentry));
229*4882a593Smuzhiyun int ret;
230*4882a593Smuzhiyun uint32_t now = JFFS2_NOW();
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
233*4882a593Smuzhiyun dentry->d_name.len, dead_f, now);
234*4882a593Smuzhiyun if (dead_f->inocache)
235*4882a593Smuzhiyun set_nlink(d_inode(dentry), dead_f->inocache->pino_nlink);
236*4882a593Smuzhiyun if (!ret)
237*4882a593Smuzhiyun dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
238*4882a593Smuzhiyun return ret;
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun /***********************************************************************/
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun
jffs2_link(struct dentry * old_dentry,struct inode * dir_i,struct dentry * dentry)243*4882a593Smuzhiyun static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_sb);
246*4882a593Smuzhiyun struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(old_dentry));
247*4882a593Smuzhiyun struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
248*4882a593Smuzhiyun int ret;
249*4882a593Smuzhiyun uint8_t type;
250*4882a593Smuzhiyun uint32_t now;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* Don't let people make hard links to bad inodes. */
253*4882a593Smuzhiyun if (!f->inocache)
254*4882a593Smuzhiyun return -EIO;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun if (d_is_dir(old_dentry))
257*4882a593Smuzhiyun return -EPERM;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun /* XXX: This is ugly */
260*4882a593Smuzhiyun type = (d_inode(old_dentry)->i_mode & S_IFMT) >> 12;
261*4882a593Smuzhiyun if (!type) type = DT_REG;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun now = JFFS2_NOW();
264*4882a593Smuzhiyun ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun if (!ret) {
267*4882a593Smuzhiyun mutex_lock(&f->sem);
268*4882a593Smuzhiyun set_nlink(d_inode(old_dentry), ++f->inocache->pino_nlink);
269*4882a593Smuzhiyun mutex_unlock(&f->sem);
270*4882a593Smuzhiyun d_instantiate(dentry, d_inode(old_dentry));
271*4882a593Smuzhiyun dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
272*4882a593Smuzhiyun ihold(d_inode(old_dentry));
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun return ret;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun /***********************************************************************/
278*4882a593Smuzhiyun
jffs2_symlink(struct inode * dir_i,struct dentry * dentry,const char * target)279*4882a593Smuzhiyun static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char *target)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun struct jffs2_inode_info *f, *dir_f;
282*4882a593Smuzhiyun struct jffs2_sb_info *c;
283*4882a593Smuzhiyun struct inode *inode;
284*4882a593Smuzhiyun struct jffs2_raw_inode *ri;
285*4882a593Smuzhiyun struct jffs2_raw_dirent *rd;
286*4882a593Smuzhiyun struct jffs2_full_dnode *fn;
287*4882a593Smuzhiyun struct jffs2_full_dirent *fd;
288*4882a593Smuzhiyun int namelen;
289*4882a593Smuzhiyun uint32_t alloclen;
290*4882a593Smuzhiyun int ret, targetlen = strlen(target);
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun /* FIXME: If you care. We'd need to use frags for the target
293*4882a593Smuzhiyun if it grows much more than this */
294*4882a593Smuzhiyun if (targetlen > 254)
295*4882a593Smuzhiyun return -ENAMETOOLONG;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun ri = jffs2_alloc_raw_inode();
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun if (!ri)
300*4882a593Smuzhiyun return -ENOMEM;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun c = JFFS2_SB_INFO(dir_i->i_sb);
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /* Try to reserve enough space for both node and dirent.
305*4882a593Smuzhiyun * Just the node will do for now, though
306*4882a593Smuzhiyun */
307*4882a593Smuzhiyun namelen = dentry->d_name.len;
308*4882a593Smuzhiyun ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &alloclen,
309*4882a593Smuzhiyun ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun if (ret) {
312*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
313*4882a593Smuzhiyun return ret;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri);
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun if (IS_ERR(inode)) {
319*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
320*4882a593Smuzhiyun jffs2_complete_reservation(c);
321*4882a593Smuzhiyun return PTR_ERR(inode);
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun inode->i_op = &jffs2_symlink_inode_operations;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun f = JFFS2_INODE_INFO(inode);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun inode->i_size = targetlen;
329*4882a593Smuzhiyun ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
330*4882a593Smuzhiyun ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
331*4882a593Smuzhiyun ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun ri->compr = JFFS2_COMPR_NONE;
334*4882a593Smuzhiyun ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
335*4882a593Smuzhiyun ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun fn = jffs2_write_dnode(c, f, ri, target, targetlen, ALLOC_NORMAL);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun if (IS_ERR(fn)) {
342*4882a593Smuzhiyun /* Eeek. Wave bye bye */
343*4882a593Smuzhiyun mutex_unlock(&f->sem);
344*4882a593Smuzhiyun jffs2_complete_reservation(c);
345*4882a593Smuzhiyun ret = PTR_ERR(fn);
346*4882a593Smuzhiyun goto fail;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun /* We use f->target field to store the target path. */
350*4882a593Smuzhiyun f->target = kmemdup(target, targetlen + 1, GFP_KERNEL);
351*4882a593Smuzhiyun if (!f->target) {
352*4882a593Smuzhiyun pr_warn("Can't allocate %d bytes of memory\n", targetlen + 1);
353*4882a593Smuzhiyun mutex_unlock(&f->sem);
354*4882a593Smuzhiyun jffs2_complete_reservation(c);
355*4882a593Smuzhiyun ret = -ENOMEM;
356*4882a593Smuzhiyun goto fail;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun inode->i_link = f->target;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun jffs2_dbg(1, "%s(): symlink's target '%s' cached\n",
361*4882a593Smuzhiyun __func__, (char *)f->target);
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun /* No data here. Only a metadata node, which will be
364*4882a593Smuzhiyun obsoleted by the first data write
365*4882a593Smuzhiyun */
366*4882a593Smuzhiyun f->metadata = fn;
367*4882a593Smuzhiyun mutex_unlock(&f->sem);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun jffs2_complete_reservation(c);
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
372*4882a593Smuzhiyun if (ret)
373*4882a593Smuzhiyun goto fail;
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun ret = jffs2_init_acl_post(inode);
376*4882a593Smuzhiyun if (ret)
377*4882a593Smuzhiyun goto fail;
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
380*4882a593Smuzhiyun ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
381*4882a593Smuzhiyun if (ret)
382*4882a593Smuzhiyun goto fail;
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun rd = jffs2_alloc_raw_dirent();
385*4882a593Smuzhiyun if (!rd) {
386*4882a593Smuzhiyun /* Argh. Now we treat it like a normal delete */
387*4882a593Smuzhiyun jffs2_complete_reservation(c);
388*4882a593Smuzhiyun ret = -ENOMEM;
389*4882a593Smuzhiyun goto fail;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun dir_f = JFFS2_INODE_INFO(dir_i);
393*4882a593Smuzhiyun mutex_lock(&dir_f->sem);
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
396*4882a593Smuzhiyun rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
397*4882a593Smuzhiyun rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
398*4882a593Smuzhiyun rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun rd->pino = cpu_to_je32(dir_i->i_ino);
401*4882a593Smuzhiyun rd->version = cpu_to_je32(++dir_f->highest_version);
402*4882a593Smuzhiyun rd->ino = cpu_to_je32(inode->i_ino);
403*4882a593Smuzhiyun rd->mctime = cpu_to_je32(JFFS2_NOW());
404*4882a593Smuzhiyun rd->nsize = namelen;
405*4882a593Smuzhiyun rd->type = DT_LNK;
406*4882a593Smuzhiyun rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
407*4882a593Smuzhiyun rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun if (IS_ERR(fd)) {
412*4882a593Smuzhiyun /* dirent failed to write. Delete the inode normally
413*4882a593Smuzhiyun as if it were the final unlink() */
414*4882a593Smuzhiyun jffs2_complete_reservation(c);
415*4882a593Smuzhiyun jffs2_free_raw_dirent(rd);
416*4882a593Smuzhiyun mutex_unlock(&dir_f->sem);
417*4882a593Smuzhiyun ret = PTR_ERR(fd);
418*4882a593Smuzhiyun goto fail;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun jffs2_free_raw_dirent(rd);
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun /* Link the fd into the inode's list, obsoleting an old
426*4882a593Smuzhiyun one if necessary. */
427*4882a593Smuzhiyun jffs2_add_fd_to_list(c, fd, &dir_f->dents);
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun mutex_unlock(&dir_f->sem);
430*4882a593Smuzhiyun jffs2_complete_reservation(c);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun d_instantiate_new(dentry, inode);
433*4882a593Smuzhiyun return 0;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun fail:
436*4882a593Smuzhiyun iget_failed(inode);
437*4882a593Smuzhiyun return ret;
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun
jffs2_mkdir(struct inode * dir_i,struct dentry * dentry,umode_t mode)441*4882a593Smuzhiyun static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t mode)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun struct jffs2_inode_info *f, *dir_f;
444*4882a593Smuzhiyun struct jffs2_sb_info *c;
445*4882a593Smuzhiyun struct inode *inode;
446*4882a593Smuzhiyun struct jffs2_raw_inode *ri;
447*4882a593Smuzhiyun struct jffs2_raw_dirent *rd;
448*4882a593Smuzhiyun struct jffs2_full_dnode *fn;
449*4882a593Smuzhiyun struct jffs2_full_dirent *fd;
450*4882a593Smuzhiyun int namelen;
451*4882a593Smuzhiyun uint32_t alloclen;
452*4882a593Smuzhiyun int ret;
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun mode |= S_IFDIR;
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun ri = jffs2_alloc_raw_inode();
457*4882a593Smuzhiyun if (!ri)
458*4882a593Smuzhiyun return -ENOMEM;
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun c = JFFS2_SB_INFO(dir_i->i_sb);
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun /* Try to reserve enough space for both node and dirent.
463*4882a593Smuzhiyun * Just the node will do for now, though
464*4882a593Smuzhiyun */
465*4882a593Smuzhiyun namelen = dentry->d_name.len;
466*4882a593Smuzhiyun ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL,
467*4882a593Smuzhiyun JFFS2_SUMMARY_INODE_SIZE);
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun if (ret) {
470*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
471*4882a593Smuzhiyun return ret;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun inode = jffs2_new_inode(dir_i, mode, ri);
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun if (IS_ERR(inode)) {
477*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
478*4882a593Smuzhiyun jffs2_complete_reservation(c);
479*4882a593Smuzhiyun return PTR_ERR(inode);
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun inode->i_op = &jffs2_dir_inode_operations;
483*4882a593Smuzhiyun inode->i_fop = &jffs2_dir_operations;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun f = JFFS2_INODE_INFO(inode);
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun /* Directories get nlink 2 at start */
488*4882a593Smuzhiyun set_nlink(inode, 2);
489*4882a593Smuzhiyun /* but ic->pino_nlink is the parent ino# */
490*4882a593Smuzhiyun f->inocache->pino_nlink = dir_i->i_ino;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun ri->data_crc = cpu_to_je32(0);
493*4882a593Smuzhiyun ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL);
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun if (IS_ERR(fn)) {
500*4882a593Smuzhiyun /* Eeek. Wave bye bye */
501*4882a593Smuzhiyun mutex_unlock(&f->sem);
502*4882a593Smuzhiyun jffs2_complete_reservation(c);
503*4882a593Smuzhiyun ret = PTR_ERR(fn);
504*4882a593Smuzhiyun goto fail;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun /* No data here. Only a metadata node, which will be
507*4882a593Smuzhiyun obsoleted by the first data write
508*4882a593Smuzhiyun */
509*4882a593Smuzhiyun f->metadata = fn;
510*4882a593Smuzhiyun mutex_unlock(&f->sem);
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun jffs2_complete_reservation(c);
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
515*4882a593Smuzhiyun if (ret)
516*4882a593Smuzhiyun goto fail;
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun ret = jffs2_init_acl_post(inode);
519*4882a593Smuzhiyun if (ret)
520*4882a593Smuzhiyun goto fail;
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
523*4882a593Smuzhiyun ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
524*4882a593Smuzhiyun if (ret)
525*4882a593Smuzhiyun goto fail;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun rd = jffs2_alloc_raw_dirent();
528*4882a593Smuzhiyun if (!rd) {
529*4882a593Smuzhiyun /* Argh. Now we treat it like a normal delete */
530*4882a593Smuzhiyun jffs2_complete_reservation(c);
531*4882a593Smuzhiyun ret = -ENOMEM;
532*4882a593Smuzhiyun goto fail;
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun dir_f = JFFS2_INODE_INFO(dir_i);
536*4882a593Smuzhiyun mutex_lock(&dir_f->sem);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
539*4882a593Smuzhiyun rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
540*4882a593Smuzhiyun rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
541*4882a593Smuzhiyun rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun rd->pino = cpu_to_je32(dir_i->i_ino);
544*4882a593Smuzhiyun rd->version = cpu_to_je32(++dir_f->highest_version);
545*4882a593Smuzhiyun rd->ino = cpu_to_je32(inode->i_ino);
546*4882a593Smuzhiyun rd->mctime = cpu_to_je32(JFFS2_NOW());
547*4882a593Smuzhiyun rd->nsize = namelen;
548*4882a593Smuzhiyun rd->type = DT_DIR;
549*4882a593Smuzhiyun rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
550*4882a593Smuzhiyun rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun if (IS_ERR(fd)) {
555*4882a593Smuzhiyun /* dirent failed to write. Delete the inode normally
556*4882a593Smuzhiyun as if it were the final unlink() */
557*4882a593Smuzhiyun jffs2_complete_reservation(c);
558*4882a593Smuzhiyun jffs2_free_raw_dirent(rd);
559*4882a593Smuzhiyun mutex_unlock(&dir_f->sem);
560*4882a593Smuzhiyun ret = PTR_ERR(fd);
561*4882a593Smuzhiyun goto fail;
562*4882a593Smuzhiyun }
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
565*4882a593Smuzhiyun inc_nlink(dir_i);
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun jffs2_free_raw_dirent(rd);
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun /* Link the fd into the inode's list, obsoleting an old
570*4882a593Smuzhiyun one if necessary. */
571*4882a593Smuzhiyun jffs2_add_fd_to_list(c, fd, &dir_f->dents);
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun mutex_unlock(&dir_f->sem);
574*4882a593Smuzhiyun jffs2_complete_reservation(c);
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun d_instantiate_new(dentry, inode);
577*4882a593Smuzhiyun return 0;
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun fail:
580*4882a593Smuzhiyun iget_failed(inode);
581*4882a593Smuzhiyun return ret;
582*4882a593Smuzhiyun }
583*4882a593Smuzhiyun
jffs2_rmdir(struct inode * dir_i,struct dentry * dentry)584*4882a593Smuzhiyun static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb);
587*4882a593Smuzhiyun struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
588*4882a593Smuzhiyun struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(dentry));
589*4882a593Smuzhiyun struct jffs2_full_dirent *fd;
590*4882a593Smuzhiyun int ret;
591*4882a593Smuzhiyun uint32_t now = JFFS2_NOW();
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun mutex_lock(&f->sem);
594*4882a593Smuzhiyun for (fd = f->dents ; fd; fd = fd->next) {
595*4882a593Smuzhiyun if (fd->ino) {
596*4882a593Smuzhiyun mutex_unlock(&f->sem);
597*4882a593Smuzhiyun return -ENOTEMPTY;
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun mutex_unlock(&f->sem);
601*4882a593Smuzhiyun
602*4882a593Smuzhiyun ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
603*4882a593Smuzhiyun dentry->d_name.len, f, now);
604*4882a593Smuzhiyun if (!ret) {
605*4882a593Smuzhiyun dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
606*4882a593Smuzhiyun clear_nlink(d_inode(dentry));
607*4882a593Smuzhiyun drop_nlink(dir_i);
608*4882a593Smuzhiyun }
609*4882a593Smuzhiyun return ret;
610*4882a593Smuzhiyun }
611*4882a593Smuzhiyun
jffs2_mknod(struct inode * dir_i,struct dentry * dentry,umode_t mode,dev_t rdev)612*4882a593Smuzhiyun static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev)
613*4882a593Smuzhiyun {
614*4882a593Smuzhiyun struct jffs2_inode_info *f, *dir_f;
615*4882a593Smuzhiyun struct jffs2_sb_info *c;
616*4882a593Smuzhiyun struct inode *inode;
617*4882a593Smuzhiyun struct jffs2_raw_inode *ri;
618*4882a593Smuzhiyun struct jffs2_raw_dirent *rd;
619*4882a593Smuzhiyun struct jffs2_full_dnode *fn;
620*4882a593Smuzhiyun struct jffs2_full_dirent *fd;
621*4882a593Smuzhiyun int namelen;
622*4882a593Smuzhiyun union jffs2_device_node dev;
623*4882a593Smuzhiyun int devlen = 0;
624*4882a593Smuzhiyun uint32_t alloclen;
625*4882a593Smuzhiyun int ret;
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun ri = jffs2_alloc_raw_inode();
628*4882a593Smuzhiyun if (!ri)
629*4882a593Smuzhiyun return -ENOMEM;
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun c = JFFS2_SB_INFO(dir_i->i_sb);
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun if (S_ISBLK(mode) || S_ISCHR(mode))
634*4882a593Smuzhiyun devlen = jffs2_encode_dev(&dev, rdev);
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun /* Try to reserve enough space for both node and dirent.
637*4882a593Smuzhiyun * Just the node will do for now, though
638*4882a593Smuzhiyun */
639*4882a593Smuzhiyun namelen = dentry->d_name.len;
640*4882a593Smuzhiyun ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &alloclen,
641*4882a593Smuzhiyun ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
642*4882a593Smuzhiyun
643*4882a593Smuzhiyun if (ret) {
644*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
645*4882a593Smuzhiyun return ret;
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun inode = jffs2_new_inode(dir_i, mode, ri);
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun if (IS_ERR(inode)) {
651*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
652*4882a593Smuzhiyun jffs2_complete_reservation(c);
653*4882a593Smuzhiyun return PTR_ERR(inode);
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun inode->i_op = &jffs2_file_inode_operations;
656*4882a593Smuzhiyun init_special_inode(inode, inode->i_mode, rdev);
657*4882a593Smuzhiyun
658*4882a593Smuzhiyun f = JFFS2_INODE_INFO(inode);
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun ri->dsize = ri->csize = cpu_to_je32(devlen);
661*4882a593Smuzhiyun ri->totlen = cpu_to_je32(sizeof(*ri) + devlen);
662*4882a593Smuzhiyun ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun ri->compr = JFFS2_COMPR_NONE;
665*4882a593Smuzhiyun ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
666*4882a593Smuzhiyun ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, ALLOC_NORMAL);
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun jffs2_free_raw_inode(ri);
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun if (IS_ERR(fn)) {
673*4882a593Smuzhiyun /* Eeek. Wave bye bye */
674*4882a593Smuzhiyun mutex_unlock(&f->sem);
675*4882a593Smuzhiyun jffs2_complete_reservation(c);
676*4882a593Smuzhiyun ret = PTR_ERR(fn);
677*4882a593Smuzhiyun goto fail;
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun /* No data here. Only a metadata node, which will be
680*4882a593Smuzhiyun obsoleted by the first data write
681*4882a593Smuzhiyun */
682*4882a593Smuzhiyun f->metadata = fn;
683*4882a593Smuzhiyun mutex_unlock(&f->sem);
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun jffs2_complete_reservation(c);
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun ret = jffs2_init_security(inode, dir_i, &dentry->d_name);
688*4882a593Smuzhiyun if (ret)
689*4882a593Smuzhiyun goto fail;
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun ret = jffs2_init_acl_post(inode);
692*4882a593Smuzhiyun if (ret)
693*4882a593Smuzhiyun goto fail;
694*4882a593Smuzhiyun
695*4882a593Smuzhiyun ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
696*4882a593Smuzhiyun ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
697*4882a593Smuzhiyun if (ret)
698*4882a593Smuzhiyun goto fail;
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun rd = jffs2_alloc_raw_dirent();
701*4882a593Smuzhiyun if (!rd) {
702*4882a593Smuzhiyun /* Argh. Now we treat it like a normal delete */
703*4882a593Smuzhiyun jffs2_complete_reservation(c);
704*4882a593Smuzhiyun ret = -ENOMEM;
705*4882a593Smuzhiyun goto fail;
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun dir_f = JFFS2_INODE_INFO(dir_i);
709*4882a593Smuzhiyun mutex_lock(&dir_f->sem);
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
712*4882a593Smuzhiyun rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
713*4882a593Smuzhiyun rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
714*4882a593Smuzhiyun rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun rd->pino = cpu_to_je32(dir_i->i_ino);
717*4882a593Smuzhiyun rd->version = cpu_to_je32(++dir_f->highest_version);
718*4882a593Smuzhiyun rd->ino = cpu_to_je32(inode->i_ino);
719*4882a593Smuzhiyun rd->mctime = cpu_to_je32(JFFS2_NOW());
720*4882a593Smuzhiyun rd->nsize = namelen;
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun /* XXX: This is ugly. */
723*4882a593Smuzhiyun rd->type = (mode & S_IFMT) >> 12;
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
726*4882a593Smuzhiyun rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun if (IS_ERR(fd)) {
731*4882a593Smuzhiyun /* dirent failed to write. Delete the inode normally
732*4882a593Smuzhiyun as if it were the final unlink() */
733*4882a593Smuzhiyun jffs2_complete_reservation(c);
734*4882a593Smuzhiyun jffs2_free_raw_dirent(rd);
735*4882a593Smuzhiyun mutex_unlock(&dir_f->sem);
736*4882a593Smuzhiyun ret = PTR_ERR(fd);
737*4882a593Smuzhiyun goto fail;
738*4882a593Smuzhiyun }
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
741*4882a593Smuzhiyun
742*4882a593Smuzhiyun jffs2_free_raw_dirent(rd);
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun /* Link the fd into the inode's list, obsoleting an old
745*4882a593Smuzhiyun one if necessary. */
746*4882a593Smuzhiyun jffs2_add_fd_to_list(c, fd, &dir_f->dents);
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun mutex_unlock(&dir_f->sem);
749*4882a593Smuzhiyun jffs2_complete_reservation(c);
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun d_instantiate_new(dentry, inode);
752*4882a593Smuzhiyun return 0;
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun fail:
755*4882a593Smuzhiyun iget_failed(inode);
756*4882a593Smuzhiyun return ret;
757*4882a593Smuzhiyun }
758*4882a593Smuzhiyun
jffs2_rename(struct inode * old_dir_i,struct dentry * old_dentry,struct inode * new_dir_i,struct dentry * new_dentry,unsigned int flags)759*4882a593Smuzhiyun static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
760*4882a593Smuzhiyun struct inode *new_dir_i, struct dentry *new_dentry,
761*4882a593Smuzhiyun unsigned int flags)
762*4882a593Smuzhiyun {
763*4882a593Smuzhiyun int ret;
764*4882a593Smuzhiyun struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
765*4882a593Smuzhiyun struct jffs2_inode_info *victim_f = NULL;
766*4882a593Smuzhiyun uint8_t type;
767*4882a593Smuzhiyun uint32_t now;
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun if (flags & ~RENAME_NOREPLACE)
770*4882a593Smuzhiyun return -EINVAL;
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun /* The VFS will check for us and prevent trying to rename a
773*4882a593Smuzhiyun * file over a directory and vice versa, but if it's a directory,
774*4882a593Smuzhiyun * the VFS can't check whether the victim is empty. The filesystem
775*4882a593Smuzhiyun * needs to do that for itself.
776*4882a593Smuzhiyun */
777*4882a593Smuzhiyun if (d_really_is_positive(new_dentry)) {
778*4882a593Smuzhiyun victim_f = JFFS2_INODE_INFO(d_inode(new_dentry));
779*4882a593Smuzhiyun if (d_is_dir(new_dentry)) {
780*4882a593Smuzhiyun struct jffs2_full_dirent *fd;
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun mutex_lock(&victim_f->sem);
783*4882a593Smuzhiyun for (fd = victim_f->dents; fd; fd = fd->next) {
784*4882a593Smuzhiyun if (fd->ino) {
785*4882a593Smuzhiyun mutex_unlock(&victim_f->sem);
786*4882a593Smuzhiyun return -ENOTEMPTY;
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun }
789*4882a593Smuzhiyun mutex_unlock(&victim_f->sem);
790*4882a593Smuzhiyun }
791*4882a593Smuzhiyun }
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun /* XXX: We probably ought to alloc enough space for
794*4882a593Smuzhiyun both nodes at the same time. Writing the new link,
795*4882a593Smuzhiyun then getting -ENOSPC, is quite bad :)
796*4882a593Smuzhiyun */
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun /* Make a hard link */
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun /* XXX: This is ugly */
801*4882a593Smuzhiyun type = (d_inode(old_dentry)->i_mode & S_IFMT) >> 12;
802*4882a593Smuzhiyun if (!type) type = DT_REG;
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun now = JFFS2_NOW();
805*4882a593Smuzhiyun ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
806*4882a593Smuzhiyun d_inode(old_dentry)->i_ino, type,
807*4882a593Smuzhiyun new_dentry->d_name.name, new_dentry->d_name.len, now);
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun if (ret)
810*4882a593Smuzhiyun return ret;
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun if (victim_f) {
813*4882a593Smuzhiyun /* There was a victim. Kill it off nicely */
814*4882a593Smuzhiyun if (d_is_dir(new_dentry))
815*4882a593Smuzhiyun clear_nlink(d_inode(new_dentry));
816*4882a593Smuzhiyun else
817*4882a593Smuzhiyun drop_nlink(d_inode(new_dentry));
818*4882a593Smuzhiyun /* Don't oops if the victim was a dirent pointing to an
819*4882a593Smuzhiyun inode which didn't exist. */
820*4882a593Smuzhiyun if (victim_f->inocache) {
821*4882a593Smuzhiyun mutex_lock(&victim_f->sem);
822*4882a593Smuzhiyun if (d_is_dir(new_dentry))
823*4882a593Smuzhiyun victim_f->inocache->pino_nlink = 0;
824*4882a593Smuzhiyun else
825*4882a593Smuzhiyun victim_f->inocache->pino_nlink--;
826*4882a593Smuzhiyun mutex_unlock(&victim_f->sem);
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun /* If it was a directory we moved, and there was no victim,
831*4882a593Smuzhiyun increase i_nlink on its new parent */
832*4882a593Smuzhiyun if (d_is_dir(old_dentry) && !victim_f)
833*4882a593Smuzhiyun inc_nlink(new_dir_i);
834*4882a593Smuzhiyun
835*4882a593Smuzhiyun /* Unlink the original */
836*4882a593Smuzhiyun ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
837*4882a593Smuzhiyun old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun /* We don't touch inode->i_nlink */
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun if (ret) {
842*4882a593Smuzhiyun /* Oh shit. We really ought to make a single node which can do both atomically */
843*4882a593Smuzhiyun struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(old_dentry));
844*4882a593Smuzhiyun mutex_lock(&f->sem);
845*4882a593Smuzhiyun inc_nlink(d_inode(old_dentry));
846*4882a593Smuzhiyun if (f->inocache && !d_is_dir(old_dentry))
847*4882a593Smuzhiyun f->inocache->pino_nlink++;
848*4882a593Smuzhiyun mutex_unlock(&f->sem);
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n",
851*4882a593Smuzhiyun __func__, ret);
852*4882a593Smuzhiyun /*
853*4882a593Smuzhiyun * We can't keep the target in dcache after that.
854*4882a593Smuzhiyun * For one thing, we can't afford dentry aliases for directories.
855*4882a593Smuzhiyun * For another, if there was a victim, we _can't_ set new inode
856*4882a593Smuzhiyun * for that sucker and we have to trigger mount eviction - the
857*4882a593Smuzhiyun * caller won't do it on its own since we are returning an error.
858*4882a593Smuzhiyun */
859*4882a593Smuzhiyun d_invalidate(new_dentry);
860*4882a593Smuzhiyun new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
861*4882a593Smuzhiyun return ret;
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun if (d_is_dir(old_dentry))
865*4882a593Smuzhiyun drop_nlink(old_dir_i);
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun return 0;
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun
872