1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <linux/iversion.h>
7*4882a593Smuzhiyun #include <linux/namei.h>
8*4882a593Smuzhiyun #include <linux/slab.h>
9*4882a593Smuzhiyun #include <linux/buffer_head.h>
10*4882a593Smuzhiyun #include <linux/nls.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include "exfat_raw.h"
13*4882a593Smuzhiyun #include "exfat_fs.h"
14*4882a593Smuzhiyun
exfat_d_version(struct dentry * dentry)15*4882a593Smuzhiyun static inline unsigned long exfat_d_version(struct dentry *dentry)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun return (unsigned long) dentry->d_fsdata;
18*4882a593Smuzhiyun }
19*4882a593Smuzhiyun
exfat_d_version_set(struct dentry * dentry,unsigned long version)20*4882a593Smuzhiyun static inline void exfat_d_version_set(struct dentry *dentry,
21*4882a593Smuzhiyun unsigned long version)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun dentry->d_fsdata = (void *) version;
24*4882a593Smuzhiyun }
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun * If new entry was created in the parent, it could create the 8.3 alias (the
28*4882a593Smuzhiyun * shortname of logname). So, the parent may have the negative-dentry which
29*4882a593Smuzhiyun * matches the created 8.3 alias.
30*4882a593Smuzhiyun *
31*4882a593Smuzhiyun * If it happened, the negative dentry isn't actually negative anymore. So,
32*4882a593Smuzhiyun * drop it.
33*4882a593Smuzhiyun */
exfat_d_revalidate(struct dentry * dentry,unsigned int flags)34*4882a593Smuzhiyun static int exfat_d_revalidate(struct dentry *dentry, unsigned int flags)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun int ret;
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun if (flags & LOOKUP_RCU)
39*4882a593Smuzhiyun return -ECHILD;
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun * This is not negative dentry. Always valid.
43*4882a593Smuzhiyun *
44*4882a593Smuzhiyun * Note, rename() to existing directory entry will have ->d_inode, and
45*4882a593Smuzhiyun * will use existing name which isn't specified name by user.
46*4882a593Smuzhiyun *
47*4882a593Smuzhiyun * We may be able to drop this positive dentry here. But dropping
48*4882a593Smuzhiyun * positive dentry isn't good idea. So it's unsupported like
49*4882a593Smuzhiyun * rename("filename", "FILENAME") for now.
50*4882a593Smuzhiyun */
51*4882a593Smuzhiyun if (d_really_is_positive(dentry))
52*4882a593Smuzhiyun return 1;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /*
55*4882a593Smuzhiyun * Drop the negative dentry, in order to make sure to use the case
56*4882a593Smuzhiyun * sensitive name which is specified by user if this is for creation.
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
59*4882a593Smuzhiyun return 0;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun spin_lock(&dentry->d_lock);
62*4882a593Smuzhiyun ret = inode_eq_iversion(d_inode(dentry->d_parent),
63*4882a593Smuzhiyun exfat_d_version(dentry));
64*4882a593Smuzhiyun spin_unlock(&dentry->d_lock);
65*4882a593Smuzhiyun return ret;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* returns the length of a struct qstr, ignoring trailing dots */
exfat_striptail_len(unsigned int len,const char * name)69*4882a593Smuzhiyun static unsigned int exfat_striptail_len(unsigned int len, const char *name)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun while (len && name[len - 1] == '.')
72*4882a593Smuzhiyun len--;
73*4882a593Smuzhiyun return len;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /*
77*4882a593Smuzhiyun * Compute the hash for the exfat name corresponding to the dentry. If the name
78*4882a593Smuzhiyun * is invalid, we leave the hash code unchanged so that the existing dentry can
79*4882a593Smuzhiyun * be used. The exfat fs routines will return ENOENT or EINVAL as appropriate.
80*4882a593Smuzhiyun */
exfat_d_hash(const struct dentry * dentry,struct qstr * qstr)81*4882a593Smuzhiyun static int exfat_d_hash(const struct dentry *dentry, struct qstr *qstr)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun struct super_block *sb = dentry->d_sb;
84*4882a593Smuzhiyun struct nls_table *t = EXFAT_SB(sb)->nls_io;
85*4882a593Smuzhiyun const unsigned char *name = qstr->name;
86*4882a593Smuzhiyun unsigned int len = exfat_striptail_len(qstr->len, qstr->name);
87*4882a593Smuzhiyun unsigned long hash = init_name_hash(dentry);
88*4882a593Smuzhiyun int i, charlen;
89*4882a593Smuzhiyun wchar_t c;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun for (i = 0; i < len; i += charlen) {
92*4882a593Smuzhiyun charlen = t->char2uni(&name[i], len - i, &c);
93*4882a593Smuzhiyun if (charlen < 0)
94*4882a593Smuzhiyun return charlen;
95*4882a593Smuzhiyun hash = partial_name_hash(exfat_toupper(sb, c), hash);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun qstr->hash = end_name_hash(hash);
99*4882a593Smuzhiyun return 0;
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
exfat_d_cmp(const struct dentry * dentry,unsigned int len,const char * str,const struct qstr * name)102*4882a593Smuzhiyun static int exfat_d_cmp(const struct dentry *dentry, unsigned int len,
103*4882a593Smuzhiyun const char *str, const struct qstr *name)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun struct super_block *sb = dentry->d_sb;
106*4882a593Smuzhiyun struct nls_table *t = EXFAT_SB(sb)->nls_io;
107*4882a593Smuzhiyun unsigned int alen = exfat_striptail_len(name->len, name->name);
108*4882a593Smuzhiyun unsigned int blen = exfat_striptail_len(len, str);
109*4882a593Smuzhiyun wchar_t c1, c2;
110*4882a593Smuzhiyun int charlen, i;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun if (alen != blen)
113*4882a593Smuzhiyun return 1;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun for (i = 0; i < len; i += charlen) {
116*4882a593Smuzhiyun charlen = t->char2uni(&name->name[i], alen - i, &c1);
117*4882a593Smuzhiyun if (charlen < 0)
118*4882a593Smuzhiyun return 1;
119*4882a593Smuzhiyun if (charlen != t->char2uni(&str[i], blen - i, &c2))
120*4882a593Smuzhiyun return 1;
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun if (exfat_toupper(sb, c1) != exfat_toupper(sb, c2))
123*4882a593Smuzhiyun return 1;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun return 0;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun const struct dentry_operations exfat_dentry_ops = {
130*4882a593Smuzhiyun .d_revalidate = exfat_d_revalidate,
131*4882a593Smuzhiyun .d_hash = exfat_d_hash,
132*4882a593Smuzhiyun .d_compare = exfat_d_cmp,
133*4882a593Smuzhiyun };
134*4882a593Smuzhiyun
exfat_utf8_d_hash(const struct dentry * dentry,struct qstr * qstr)135*4882a593Smuzhiyun static int exfat_utf8_d_hash(const struct dentry *dentry, struct qstr *qstr)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun struct super_block *sb = dentry->d_sb;
138*4882a593Smuzhiyun const unsigned char *name = qstr->name;
139*4882a593Smuzhiyun unsigned int len = exfat_striptail_len(qstr->len, qstr->name);
140*4882a593Smuzhiyun unsigned long hash = init_name_hash(dentry);
141*4882a593Smuzhiyun int i, charlen;
142*4882a593Smuzhiyun unicode_t u;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun for (i = 0; i < len; i += charlen) {
145*4882a593Smuzhiyun charlen = utf8_to_utf32(&name[i], len - i, &u);
146*4882a593Smuzhiyun if (charlen < 0)
147*4882a593Smuzhiyun return charlen;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /*
150*4882a593Smuzhiyun * exfat_toupper() works only for code points up to the U+FFFF.
151*4882a593Smuzhiyun */
152*4882a593Smuzhiyun hash = partial_name_hash(u <= 0xFFFF ? exfat_toupper(sb, u) : u,
153*4882a593Smuzhiyun hash);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun qstr->hash = end_name_hash(hash);
157*4882a593Smuzhiyun return 0;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
exfat_utf8_d_cmp(const struct dentry * dentry,unsigned int len,const char * str,const struct qstr * name)160*4882a593Smuzhiyun static int exfat_utf8_d_cmp(const struct dentry *dentry, unsigned int len,
161*4882a593Smuzhiyun const char *str, const struct qstr *name)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun struct super_block *sb = dentry->d_sb;
164*4882a593Smuzhiyun unsigned int alen = exfat_striptail_len(name->len, name->name);
165*4882a593Smuzhiyun unsigned int blen = exfat_striptail_len(len, str);
166*4882a593Smuzhiyun unicode_t u_a, u_b;
167*4882a593Smuzhiyun int charlen, i;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun if (alen != blen)
170*4882a593Smuzhiyun return 1;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun for (i = 0; i < alen; i += charlen) {
173*4882a593Smuzhiyun charlen = utf8_to_utf32(&name->name[i], alen - i, &u_a);
174*4882a593Smuzhiyun if (charlen < 0)
175*4882a593Smuzhiyun return 1;
176*4882a593Smuzhiyun if (charlen != utf8_to_utf32(&str[i], blen - i, &u_b))
177*4882a593Smuzhiyun return 1;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun if (u_a <= 0xFFFF && u_b <= 0xFFFF) {
180*4882a593Smuzhiyun if (exfat_toupper(sb, u_a) != exfat_toupper(sb, u_b))
181*4882a593Smuzhiyun return 1;
182*4882a593Smuzhiyun } else {
183*4882a593Smuzhiyun if (u_a != u_b)
184*4882a593Smuzhiyun return 1;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun return 0;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun const struct dentry_operations exfat_utf8_dentry_ops = {
192*4882a593Smuzhiyun .d_revalidate = exfat_d_revalidate,
193*4882a593Smuzhiyun .d_hash = exfat_utf8_d_hash,
194*4882a593Smuzhiyun .d_compare = exfat_utf8_d_cmp,
195*4882a593Smuzhiyun };
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /* used only in search empty_slot() */
198*4882a593Smuzhiyun #define CNT_UNUSED_NOHIT (-1)
199*4882a593Smuzhiyun #define CNT_UNUSED_HIT (-2)
200*4882a593Smuzhiyun /* search EMPTY CONTINUOUS "num_entries" entries */
exfat_search_empty_slot(struct super_block * sb,struct exfat_hint_femp * hint_femp,struct exfat_chain * p_dir,int num_entries)201*4882a593Smuzhiyun static int exfat_search_empty_slot(struct super_block *sb,
202*4882a593Smuzhiyun struct exfat_hint_femp *hint_femp, struct exfat_chain *p_dir,
203*4882a593Smuzhiyun int num_entries)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun int i, dentry, num_empty = 0;
206*4882a593Smuzhiyun int dentries_per_clu;
207*4882a593Smuzhiyun unsigned int type;
208*4882a593Smuzhiyun struct exfat_chain clu;
209*4882a593Smuzhiyun struct exfat_dentry *ep;
210*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
211*4882a593Smuzhiyun struct buffer_head *bh;
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun dentries_per_clu = sbi->dentries_per_clu;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun if (hint_femp->eidx != EXFAT_HINT_NONE) {
216*4882a593Smuzhiyun dentry = hint_femp->eidx;
217*4882a593Smuzhiyun if (num_entries <= hint_femp->count) {
218*4882a593Smuzhiyun hint_femp->eidx = EXFAT_HINT_NONE;
219*4882a593Smuzhiyun return dentry;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun exfat_chain_dup(&clu, &hint_femp->cur);
223*4882a593Smuzhiyun } else {
224*4882a593Smuzhiyun exfat_chain_dup(&clu, p_dir);
225*4882a593Smuzhiyun dentry = 0;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun while (clu.dir != EXFAT_EOF_CLUSTER) {
229*4882a593Smuzhiyun i = dentry & (dentries_per_clu - 1);
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun for (; i < dentries_per_clu; i++, dentry++) {
232*4882a593Smuzhiyun ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
233*4882a593Smuzhiyun if (!ep)
234*4882a593Smuzhiyun return -EIO;
235*4882a593Smuzhiyun type = exfat_get_entry_type(ep);
236*4882a593Smuzhiyun brelse(bh);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun if (type == TYPE_UNUSED || type == TYPE_DELETED) {
239*4882a593Smuzhiyun num_empty++;
240*4882a593Smuzhiyun if (hint_femp->eidx == EXFAT_HINT_NONE) {
241*4882a593Smuzhiyun hint_femp->eidx = dentry;
242*4882a593Smuzhiyun hint_femp->count = CNT_UNUSED_NOHIT;
243*4882a593Smuzhiyun exfat_chain_set(&hint_femp->cur,
244*4882a593Smuzhiyun clu.dir, clu.size, clu.flags);
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun if (type == TYPE_UNUSED &&
248*4882a593Smuzhiyun hint_femp->count != CNT_UNUSED_HIT)
249*4882a593Smuzhiyun hint_femp->count = CNT_UNUSED_HIT;
250*4882a593Smuzhiyun } else {
251*4882a593Smuzhiyun if (hint_femp->eidx != EXFAT_HINT_NONE &&
252*4882a593Smuzhiyun hint_femp->count == CNT_UNUSED_HIT) {
253*4882a593Smuzhiyun /* unused empty group means
254*4882a593Smuzhiyun * an empty group which includes
255*4882a593Smuzhiyun * unused dentry
256*4882a593Smuzhiyun */
257*4882a593Smuzhiyun exfat_fs_error(sb,
258*4882a593Smuzhiyun "found bogus dentry(%d) beyond unused empty group(%d) (start_clu : %u, cur_clu : %u)",
259*4882a593Smuzhiyun dentry, hint_femp->eidx,
260*4882a593Smuzhiyun p_dir->dir, clu.dir);
261*4882a593Smuzhiyun return -EIO;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun num_empty = 0;
265*4882a593Smuzhiyun hint_femp->eidx = EXFAT_HINT_NONE;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun if (num_empty >= num_entries) {
269*4882a593Smuzhiyun /* found and invalidate hint_femp */
270*4882a593Smuzhiyun hint_femp->eidx = EXFAT_HINT_NONE;
271*4882a593Smuzhiyun return (dentry - (num_entries - 1));
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun if (clu.flags == ALLOC_NO_FAT_CHAIN) {
276*4882a593Smuzhiyun if (--clu.size > 0)
277*4882a593Smuzhiyun clu.dir++;
278*4882a593Smuzhiyun else
279*4882a593Smuzhiyun clu.dir = EXFAT_EOF_CLUSTER;
280*4882a593Smuzhiyun } else {
281*4882a593Smuzhiyun if (exfat_get_next_cluster(sb, &clu.dir))
282*4882a593Smuzhiyun return -EIO;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun return -ENOSPC;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
exfat_check_max_dentries(struct inode * inode)289*4882a593Smuzhiyun static int exfat_check_max_dentries(struct inode *inode)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun if (EXFAT_B_TO_DEN(i_size_read(inode)) >= MAX_EXFAT_DENTRIES) {
292*4882a593Smuzhiyun /*
293*4882a593Smuzhiyun * exFAT spec allows a dir to grow up to 8388608(256MB)
294*4882a593Smuzhiyun * dentries
295*4882a593Smuzhiyun */
296*4882a593Smuzhiyun return -ENOSPC;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun return 0;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /* find empty directory entry.
302*4882a593Smuzhiyun * if there isn't any empty slot, expand cluster chain.
303*4882a593Smuzhiyun */
exfat_find_empty_entry(struct inode * inode,struct exfat_chain * p_dir,int num_entries)304*4882a593Smuzhiyun static int exfat_find_empty_entry(struct inode *inode,
305*4882a593Smuzhiyun struct exfat_chain *p_dir, int num_entries)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun int dentry;
308*4882a593Smuzhiyun unsigned int ret, last_clu;
309*4882a593Smuzhiyun sector_t sector;
310*4882a593Smuzhiyun loff_t size = 0;
311*4882a593Smuzhiyun struct exfat_chain clu;
312*4882a593Smuzhiyun struct exfat_dentry *ep = NULL;
313*4882a593Smuzhiyun struct super_block *sb = inode->i_sb;
314*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
315*4882a593Smuzhiyun struct exfat_inode_info *ei = EXFAT_I(inode);
316*4882a593Smuzhiyun struct exfat_hint_femp hint_femp;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun hint_femp.eidx = EXFAT_HINT_NONE;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun if (ei->hint_femp.eidx != EXFAT_HINT_NONE) {
321*4882a593Smuzhiyun hint_femp = ei->hint_femp;
322*4882a593Smuzhiyun ei->hint_femp.eidx = EXFAT_HINT_NONE;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun while ((dentry = exfat_search_empty_slot(sb, &hint_femp, p_dir,
326*4882a593Smuzhiyun num_entries)) < 0) {
327*4882a593Smuzhiyun if (dentry == -EIO)
328*4882a593Smuzhiyun break;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun if (exfat_check_max_dentries(inode))
331*4882a593Smuzhiyun return -ENOSPC;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun /* we trust p_dir->size regardless of FAT type */
334*4882a593Smuzhiyun if (exfat_find_last_cluster(sb, p_dir, &last_clu))
335*4882a593Smuzhiyun return -EIO;
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun /*
338*4882a593Smuzhiyun * Allocate new cluster to this directory
339*4882a593Smuzhiyun */
340*4882a593Smuzhiyun exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags);
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /* allocate a cluster */
343*4882a593Smuzhiyun ret = exfat_alloc_cluster(inode, 1, &clu, IS_DIRSYNC(inode));
344*4882a593Smuzhiyun if (ret)
345*4882a593Smuzhiyun return ret;
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun if (exfat_zeroed_cluster(inode, clu.dir))
348*4882a593Smuzhiyun return -EIO;
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun /* append to the FAT chain */
351*4882a593Smuzhiyun if (clu.flags != p_dir->flags) {
352*4882a593Smuzhiyun /* no-fat-chain bit is disabled,
353*4882a593Smuzhiyun * so fat-chain should be synced with alloc-bitmap
354*4882a593Smuzhiyun */
355*4882a593Smuzhiyun exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size);
356*4882a593Smuzhiyun p_dir->flags = ALLOC_FAT_CHAIN;
357*4882a593Smuzhiyun hint_femp.cur.flags = ALLOC_FAT_CHAIN;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun if (clu.flags == ALLOC_FAT_CHAIN)
361*4882a593Smuzhiyun if (exfat_ent_set(sb, last_clu, clu.dir))
362*4882a593Smuzhiyun return -EIO;
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun if (hint_femp.eidx == EXFAT_HINT_NONE) {
365*4882a593Smuzhiyun /* the special case that new dentry
366*4882a593Smuzhiyun * should be allocated from the start of new cluster
367*4882a593Smuzhiyun */
368*4882a593Smuzhiyun hint_femp.eidx = EXFAT_B_TO_DEN_IDX(p_dir->size, sbi);
369*4882a593Smuzhiyun hint_femp.count = sbi->dentries_per_clu;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun exfat_chain_set(&hint_femp.cur, clu.dir, 0, clu.flags);
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun hint_femp.cur.size++;
374*4882a593Smuzhiyun p_dir->size++;
375*4882a593Smuzhiyun size = EXFAT_CLU_TO_B(p_dir->size, sbi);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun /* update the directory entry */
378*4882a593Smuzhiyun if (p_dir->dir != sbi->root_dir) {
379*4882a593Smuzhiyun struct buffer_head *bh;
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun ep = exfat_get_dentry(sb,
382*4882a593Smuzhiyun &(ei->dir), ei->entry + 1, &bh, §or);
383*4882a593Smuzhiyun if (!ep)
384*4882a593Smuzhiyun return -EIO;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun ep->dentry.stream.valid_size = cpu_to_le64(size);
387*4882a593Smuzhiyun ep->dentry.stream.size = ep->dentry.stream.valid_size;
388*4882a593Smuzhiyun ep->dentry.stream.flags = p_dir->flags;
389*4882a593Smuzhiyun exfat_update_bh(bh, IS_DIRSYNC(inode));
390*4882a593Smuzhiyun brelse(bh);
391*4882a593Smuzhiyun if (exfat_update_dir_chksum(inode, &(ei->dir),
392*4882a593Smuzhiyun ei->entry))
393*4882a593Smuzhiyun return -EIO;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun /* directory inode should be updated in here */
397*4882a593Smuzhiyun i_size_write(inode, size);
398*4882a593Smuzhiyun ei->i_size_ondisk += sbi->cluster_size;
399*4882a593Smuzhiyun ei->i_size_aligned += sbi->cluster_size;
400*4882a593Smuzhiyun ei->flags = p_dir->flags;
401*4882a593Smuzhiyun inode->i_blocks += 1 << sbi->sect_per_clus_bits;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun return dentry;
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun /*
408*4882a593Smuzhiyun * Name Resolution Functions :
409*4882a593Smuzhiyun * Zero if it was successful; otherwise nonzero.
410*4882a593Smuzhiyun */
__exfat_resolve_path(struct inode * inode,const unsigned char * path,struct exfat_chain * p_dir,struct exfat_uni_name * p_uniname,int lookup)411*4882a593Smuzhiyun static int __exfat_resolve_path(struct inode *inode, const unsigned char *path,
412*4882a593Smuzhiyun struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
413*4882a593Smuzhiyun int lookup)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun int namelen;
416*4882a593Smuzhiyun int lossy = NLS_NAME_NO_LOSSY;
417*4882a593Smuzhiyun struct super_block *sb = inode->i_sb;
418*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
419*4882a593Smuzhiyun struct exfat_inode_info *ei = EXFAT_I(inode);
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun /* strip all trailing periods */
422*4882a593Smuzhiyun namelen = exfat_striptail_len(strlen(path), path);
423*4882a593Smuzhiyun if (!namelen)
424*4882a593Smuzhiyun return -ENOENT;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun if (strlen(path) > (MAX_NAME_LENGTH * MAX_CHARSET_SIZE))
427*4882a593Smuzhiyun return -ENAMETOOLONG;
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /*
430*4882a593Smuzhiyun * strip all leading spaces :
431*4882a593Smuzhiyun * "MS windows 7" supports leading spaces.
432*4882a593Smuzhiyun * So we should skip this preprocessing for compatibility.
433*4882a593Smuzhiyun */
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun /* file name conversion :
436*4882a593Smuzhiyun * If lookup case, we allow bad-name for compatibility.
437*4882a593Smuzhiyun */
438*4882a593Smuzhiyun namelen = exfat_nls_to_utf16(sb, path, namelen, p_uniname,
439*4882a593Smuzhiyun &lossy);
440*4882a593Smuzhiyun if (namelen < 0)
441*4882a593Smuzhiyun return namelen; /* return error value */
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun if ((lossy && !lookup) || !namelen)
444*4882a593Smuzhiyun return -EINVAL;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun exfat_chain_set(p_dir, ei->start_clu,
447*4882a593Smuzhiyun EXFAT_B_TO_CLU(i_size_read(inode), sbi), ei->flags);
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun return 0;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
exfat_resolve_path(struct inode * inode,const unsigned char * path,struct exfat_chain * dir,struct exfat_uni_name * uni)452*4882a593Smuzhiyun static inline int exfat_resolve_path(struct inode *inode,
453*4882a593Smuzhiyun const unsigned char *path, struct exfat_chain *dir,
454*4882a593Smuzhiyun struct exfat_uni_name *uni)
455*4882a593Smuzhiyun {
456*4882a593Smuzhiyun return __exfat_resolve_path(inode, path, dir, uni, 0);
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun
exfat_resolve_path_for_lookup(struct inode * inode,const unsigned char * path,struct exfat_chain * dir,struct exfat_uni_name * uni)459*4882a593Smuzhiyun static inline int exfat_resolve_path_for_lookup(struct inode *inode,
460*4882a593Smuzhiyun const unsigned char *path, struct exfat_chain *dir,
461*4882a593Smuzhiyun struct exfat_uni_name *uni)
462*4882a593Smuzhiyun {
463*4882a593Smuzhiyun return __exfat_resolve_path(inode, path, dir, uni, 1);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun
exfat_make_i_pos(struct exfat_dir_entry * info)466*4882a593Smuzhiyun static inline loff_t exfat_make_i_pos(struct exfat_dir_entry *info)
467*4882a593Smuzhiyun {
468*4882a593Smuzhiyun return ((loff_t) info->dir.dir << 32) | (info->entry & 0xffffffff);
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
exfat_add_entry(struct inode * inode,const char * path,struct exfat_chain * p_dir,unsigned int type,struct exfat_dir_entry * info)471*4882a593Smuzhiyun static int exfat_add_entry(struct inode *inode, const char *path,
472*4882a593Smuzhiyun struct exfat_chain *p_dir, unsigned int type,
473*4882a593Smuzhiyun struct exfat_dir_entry *info)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun int ret, dentry, num_entries;
476*4882a593Smuzhiyun struct super_block *sb = inode->i_sb;
477*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
478*4882a593Smuzhiyun struct exfat_uni_name uniname;
479*4882a593Smuzhiyun struct exfat_chain clu;
480*4882a593Smuzhiyun int clu_size = 0;
481*4882a593Smuzhiyun unsigned int start_clu = EXFAT_FREE_CLUSTER;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun ret = exfat_resolve_path(inode, path, p_dir, &uniname);
484*4882a593Smuzhiyun if (ret)
485*4882a593Smuzhiyun goto out;
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun num_entries = exfat_calc_num_entries(&uniname);
488*4882a593Smuzhiyun if (num_entries < 0) {
489*4882a593Smuzhiyun ret = num_entries;
490*4882a593Smuzhiyun goto out;
491*4882a593Smuzhiyun }
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun /* exfat_find_empty_entry must be called before alloc_cluster() */
494*4882a593Smuzhiyun dentry = exfat_find_empty_entry(inode, p_dir, num_entries);
495*4882a593Smuzhiyun if (dentry < 0) {
496*4882a593Smuzhiyun ret = dentry; /* -EIO or -ENOSPC */
497*4882a593Smuzhiyun goto out;
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun if (type == TYPE_DIR) {
501*4882a593Smuzhiyun ret = exfat_alloc_new_dir(inode, &clu);
502*4882a593Smuzhiyun if (ret)
503*4882a593Smuzhiyun goto out;
504*4882a593Smuzhiyun start_clu = clu.dir;
505*4882a593Smuzhiyun clu_size = sbi->cluster_size;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun /* update the directory entry */
509*4882a593Smuzhiyun /* fill the dos name directory entry information of the created file.
510*4882a593Smuzhiyun * the first cluster is not determined yet. (0)
511*4882a593Smuzhiyun */
512*4882a593Smuzhiyun ret = exfat_init_dir_entry(inode, p_dir, dentry, type,
513*4882a593Smuzhiyun start_clu, clu_size);
514*4882a593Smuzhiyun if (ret)
515*4882a593Smuzhiyun goto out;
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun ret = exfat_init_ext_entry(inode, p_dir, dentry, num_entries, &uniname);
518*4882a593Smuzhiyun if (ret)
519*4882a593Smuzhiyun goto out;
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun info->dir = *p_dir;
522*4882a593Smuzhiyun info->entry = dentry;
523*4882a593Smuzhiyun info->flags = ALLOC_NO_FAT_CHAIN;
524*4882a593Smuzhiyun info->type = type;
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun if (type == TYPE_FILE) {
527*4882a593Smuzhiyun info->attr = ATTR_ARCHIVE;
528*4882a593Smuzhiyun info->start_clu = EXFAT_EOF_CLUSTER;
529*4882a593Smuzhiyun info->size = 0;
530*4882a593Smuzhiyun info->num_subdirs = 0;
531*4882a593Smuzhiyun } else {
532*4882a593Smuzhiyun info->attr = ATTR_SUBDIR;
533*4882a593Smuzhiyun info->start_clu = start_clu;
534*4882a593Smuzhiyun info->size = clu_size;
535*4882a593Smuzhiyun info->num_subdirs = EXFAT_MIN_SUBDIR;
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun memset(&info->crtime, 0, sizeof(info->crtime));
538*4882a593Smuzhiyun memset(&info->mtime, 0, sizeof(info->mtime));
539*4882a593Smuzhiyun memset(&info->atime, 0, sizeof(info->atime));
540*4882a593Smuzhiyun out:
541*4882a593Smuzhiyun return ret;
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun
exfat_create(struct inode * dir,struct dentry * dentry,umode_t mode,bool excl)544*4882a593Smuzhiyun static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
545*4882a593Smuzhiyun bool excl)
546*4882a593Smuzhiyun {
547*4882a593Smuzhiyun struct super_block *sb = dir->i_sb;
548*4882a593Smuzhiyun struct inode *inode;
549*4882a593Smuzhiyun struct exfat_chain cdir;
550*4882a593Smuzhiyun struct exfat_dir_entry info;
551*4882a593Smuzhiyun loff_t i_pos;
552*4882a593Smuzhiyun int err;
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun mutex_lock(&EXFAT_SB(sb)->s_lock);
555*4882a593Smuzhiyun exfat_set_volume_dirty(sb);
556*4882a593Smuzhiyun err = exfat_add_entry(dir, dentry->d_name.name, &cdir, TYPE_FILE,
557*4882a593Smuzhiyun &info);
558*4882a593Smuzhiyun exfat_clear_volume_dirty(sb);
559*4882a593Smuzhiyun if (err)
560*4882a593Smuzhiyun goto unlock;
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun inode_inc_iversion(dir);
563*4882a593Smuzhiyun dir->i_ctime = dir->i_mtime = current_time(dir);
564*4882a593Smuzhiyun if (IS_DIRSYNC(dir))
565*4882a593Smuzhiyun exfat_sync_inode(dir);
566*4882a593Smuzhiyun else
567*4882a593Smuzhiyun mark_inode_dirty(dir);
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun i_pos = exfat_make_i_pos(&info);
570*4882a593Smuzhiyun inode = exfat_build_inode(sb, &info, i_pos);
571*4882a593Smuzhiyun err = PTR_ERR_OR_ZERO(inode);
572*4882a593Smuzhiyun if (err)
573*4882a593Smuzhiyun goto unlock;
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun inode_inc_iversion(inode);
576*4882a593Smuzhiyun inode->i_mtime = inode->i_atime = inode->i_ctime =
577*4882a593Smuzhiyun EXFAT_I(inode)->i_crtime = current_time(inode);
578*4882a593Smuzhiyun exfat_truncate_atime(&inode->i_atime);
579*4882a593Smuzhiyun /* timestamp is already written, so mark_inode_dirty() is unneeded. */
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun d_instantiate(dentry, inode);
582*4882a593Smuzhiyun unlock:
583*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(sb)->s_lock);
584*4882a593Smuzhiyun return err;
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun /* lookup a file */
exfat_find(struct inode * dir,struct qstr * qname,struct exfat_dir_entry * info)588*4882a593Smuzhiyun static int exfat_find(struct inode *dir, struct qstr *qname,
589*4882a593Smuzhiyun struct exfat_dir_entry *info)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun int ret, dentry, num_entries, count;
592*4882a593Smuzhiyun struct exfat_chain cdir;
593*4882a593Smuzhiyun struct exfat_uni_name uni_name;
594*4882a593Smuzhiyun struct super_block *sb = dir->i_sb;
595*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
596*4882a593Smuzhiyun struct exfat_inode_info *ei = EXFAT_I(dir);
597*4882a593Smuzhiyun struct exfat_dentry *ep, *ep2;
598*4882a593Smuzhiyun struct exfat_entry_set_cache *es;
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun if (qname->len == 0)
601*4882a593Smuzhiyun return -ENOENT;
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun /* check the validity of directory name in the given pathname */
604*4882a593Smuzhiyun ret = exfat_resolve_path_for_lookup(dir, qname->name, &cdir, &uni_name);
605*4882a593Smuzhiyun if (ret)
606*4882a593Smuzhiyun return ret;
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun num_entries = exfat_calc_num_entries(&uni_name);
609*4882a593Smuzhiyun if (num_entries < 0)
610*4882a593Smuzhiyun return num_entries;
611*4882a593Smuzhiyun
612*4882a593Smuzhiyun /* check the validation of hint_stat and initialize it if required */
613*4882a593Smuzhiyun if (ei->version != (inode_peek_iversion_raw(dir) & 0xffffffff)) {
614*4882a593Smuzhiyun ei->hint_stat.clu = cdir.dir;
615*4882a593Smuzhiyun ei->hint_stat.eidx = 0;
616*4882a593Smuzhiyun ei->version = (inode_peek_iversion_raw(dir) & 0xffffffff);
617*4882a593Smuzhiyun ei->hint_femp.eidx = EXFAT_HINT_NONE;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun /* search the file name for directories */
621*4882a593Smuzhiyun dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name,
622*4882a593Smuzhiyun num_entries, TYPE_ALL);
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun if (dentry < 0)
625*4882a593Smuzhiyun return dentry; /* -error value */
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun info->dir = cdir;
628*4882a593Smuzhiyun info->entry = dentry;
629*4882a593Smuzhiyun info->num_subdirs = 0;
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES);
632*4882a593Smuzhiyun if (!es)
633*4882a593Smuzhiyun return -EIO;
634*4882a593Smuzhiyun ep = exfat_get_dentry_cached(es, 0);
635*4882a593Smuzhiyun ep2 = exfat_get_dentry_cached(es, 1);
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun info->type = exfat_get_entry_type(ep);
638*4882a593Smuzhiyun info->attr = le16_to_cpu(ep->dentry.file.attr);
639*4882a593Smuzhiyun info->size = le64_to_cpu(ep2->dentry.stream.valid_size);
640*4882a593Smuzhiyun if ((info->type == TYPE_FILE) && (info->size == 0)) {
641*4882a593Smuzhiyun info->flags = ALLOC_NO_FAT_CHAIN;
642*4882a593Smuzhiyun info->start_clu = EXFAT_EOF_CLUSTER;
643*4882a593Smuzhiyun } else {
644*4882a593Smuzhiyun info->flags = ep2->dentry.stream.flags;
645*4882a593Smuzhiyun info->start_clu =
646*4882a593Smuzhiyun le32_to_cpu(ep2->dentry.stream.start_clu);
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun exfat_get_entry_time(sbi, &info->crtime,
650*4882a593Smuzhiyun ep->dentry.file.create_tz,
651*4882a593Smuzhiyun ep->dentry.file.create_time,
652*4882a593Smuzhiyun ep->dentry.file.create_date,
653*4882a593Smuzhiyun ep->dentry.file.create_time_cs);
654*4882a593Smuzhiyun exfat_get_entry_time(sbi, &info->mtime,
655*4882a593Smuzhiyun ep->dentry.file.modify_tz,
656*4882a593Smuzhiyun ep->dentry.file.modify_time,
657*4882a593Smuzhiyun ep->dentry.file.modify_date,
658*4882a593Smuzhiyun ep->dentry.file.modify_time_cs);
659*4882a593Smuzhiyun exfat_get_entry_time(sbi, &info->atime,
660*4882a593Smuzhiyun ep->dentry.file.access_tz,
661*4882a593Smuzhiyun ep->dentry.file.access_time,
662*4882a593Smuzhiyun ep->dentry.file.access_date,
663*4882a593Smuzhiyun 0);
664*4882a593Smuzhiyun exfat_free_dentry_set(es, false);
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun if (ei->start_clu == EXFAT_FREE_CLUSTER) {
667*4882a593Smuzhiyun exfat_fs_error(sb,
668*4882a593Smuzhiyun "non-zero size file starts with zero cluster (size : %llu, p_dir : %u, entry : 0x%08x)",
669*4882a593Smuzhiyun i_size_read(dir), ei->dir.dir, ei->entry);
670*4882a593Smuzhiyun return -EIO;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun if (info->type == TYPE_DIR) {
674*4882a593Smuzhiyun exfat_chain_set(&cdir, info->start_clu,
675*4882a593Smuzhiyun EXFAT_B_TO_CLU(info->size, sbi), info->flags);
676*4882a593Smuzhiyun count = exfat_count_dir_entries(sb, &cdir);
677*4882a593Smuzhiyun if (count < 0)
678*4882a593Smuzhiyun return -EIO;
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun info->num_subdirs = count + EXFAT_MIN_SUBDIR;
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun return 0;
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun
exfat_d_anon_disconn(struct dentry * dentry)685*4882a593Smuzhiyun static int exfat_d_anon_disconn(struct dentry *dentry)
686*4882a593Smuzhiyun {
687*4882a593Smuzhiyun return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED);
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun
exfat_lookup(struct inode * dir,struct dentry * dentry,unsigned int flags)690*4882a593Smuzhiyun static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry,
691*4882a593Smuzhiyun unsigned int flags)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun struct super_block *sb = dir->i_sb;
694*4882a593Smuzhiyun struct inode *inode;
695*4882a593Smuzhiyun struct dentry *alias;
696*4882a593Smuzhiyun struct exfat_dir_entry info;
697*4882a593Smuzhiyun int err;
698*4882a593Smuzhiyun loff_t i_pos;
699*4882a593Smuzhiyun mode_t i_mode;
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun mutex_lock(&EXFAT_SB(sb)->s_lock);
702*4882a593Smuzhiyun err = exfat_find(dir, &dentry->d_name, &info);
703*4882a593Smuzhiyun if (err) {
704*4882a593Smuzhiyun if (err == -ENOENT) {
705*4882a593Smuzhiyun inode = NULL;
706*4882a593Smuzhiyun goto out;
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun goto unlock;
709*4882a593Smuzhiyun }
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun i_pos = exfat_make_i_pos(&info);
712*4882a593Smuzhiyun inode = exfat_build_inode(sb, &info, i_pos);
713*4882a593Smuzhiyun err = PTR_ERR_OR_ZERO(inode);
714*4882a593Smuzhiyun if (err)
715*4882a593Smuzhiyun goto unlock;
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun i_mode = inode->i_mode;
718*4882a593Smuzhiyun alias = d_find_alias(inode);
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun /*
721*4882a593Smuzhiyun * Checking "alias->d_parent == dentry->d_parent" to make sure
722*4882a593Smuzhiyun * FS is not corrupted (especially double linked dir).
723*4882a593Smuzhiyun */
724*4882a593Smuzhiyun if (alias && alias->d_parent == dentry->d_parent &&
725*4882a593Smuzhiyun !exfat_d_anon_disconn(alias)) {
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun /*
728*4882a593Smuzhiyun * Unhashed alias is able to exist because of revalidate()
729*4882a593Smuzhiyun * called by lookup_fast. You can easily make this status
730*4882a593Smuzhiyun * by calling create and lookup concurrently
731*4882a593Smuzhiyun * In such case, we reuse an alias instead of new dentry
732*4882a593Smuzhiyun */
733*4882a593Smuzhiyun if (d_unhashed(alias)) {
734*4882a593Smuzhiyun WARN_ON(alias->d_name.hash_len !=
735*4882a593Smuzhiyun dentry->d_name.hash_len);
736*4882a593Smuzhiyun exfat_info(sb, "rehashed a dentry(%p) in read lookup",
737*4882a593Smuzhiyun alias);
738*4882a593Smuzhiyun d_drop(dentry);
739*4882a593Smuzhiyun d_rehash(alias);
740*4882a593Smuzhiyun } else if (!S_ISDIR(i_mode)) {
741*4882a593Smuzhiyun /*
742*4882a593Smuzhiyun * This inode has non anonymous-DCACHE_DISCONNECTED
743*4882a593Smuzhiyun * dentry. This means, the user did ->lookup() by an
744*4882a593Smuzhiyun * another name (longname vs 8.3 alias of it) in past.
745*4882a593Smuzhiyun *
746*4882a593Smuzhiyun * Switch to new one for reason of locality if possible.
747*4882a593Smuzhiyun */
748*4882a593Smuzhiyun d_move(alias, dentry);
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun iput(inode);
751*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(sb)->s_lock);
752*4882a593Smuzhiyun return alias;
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun dput(alias);
755*4882a593Smuzhiyun out:
756*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(sb)->s_lock);
757*4882a593Smuzhiyun if (!inode)
758*4882a593Smuzhiyun exfat_d_version_set(dentry, inode_query_iversion(dir));
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun return d_splice_alias(inode, dentry);
761*4882a593Smuzhiyun unlock:
762*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(sb)->s_lock);
763*4882a593Smuzhiyun return ERR_PTR(err);
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun /* remove an entry, BUT don't truncate */
exfat_unlink(struct inode * dir,struct dentry * dentry)767*4882a593Smuzhiyun static int exfat_unlink(struct inode *dir, struct dentry *dentry)
768*4882a593Smuzhiyun {
769*4882a593Smuzhiyun struct exfat_chain cdir;
770*4882a593Smuzhiyun struct exfat_dentry *ep;
771*4882a593Smuzhiyun struct super_block *sb = dir->i_sb;
772*4882a593Smuzhiyun struct inode *inode = dentry->d_inode;
773*4882a593Smuzhiyun struct exfat_inode_info *ei = EXFAT_I(inode);
774*4882a593Smuzhiyun struct buffer_head *bh;
775*4882a593Smuzhiyun sector_t sector;
776*4882a593Smuzhiyun int num_entries, entry, err = 0;
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun mutex_lock(&EXFAT_SB(sb)->s_lock);
779*4882a593Smuzhiyun exfat_chain_dup(&cdir, &ei->dir);
780*4882a593Smuzhiyun entry = ei->entry;
781*4882a593Smuzhiyun if (ei->dir.dir == DIR_DELETED) {
782*4882a593Smuzhiyun exfat_err(sb, "abnormal access to deleted dentry");
783*4882a593Smuzhiyun err = -ENOENT;
784*4882a593Smuzhiyun goto unlock;
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun ep = exfat_get_dentry(sb, &cdir, entry, &bh, §or);
788*4882a593Smuzhiyun if (!ep) {
789*4882a593Smuzhiyun err = -EIO;
790*4882a593Smuzhiyun goto unlock;
791*4882a593Smuzhiyun }
792*4882a593Smuzhiyun num_entries = exfat_count_ext_entries(sb, &cdir, entry, ep);
793*4882a593Smuzhiyun if (num_entries < 0) {
794*4882a593Smuzhiyun err = -EIO;
795*4882a593Smuzhiyun brelse(bh);
796*4882a593Smuzhiyun goto unlock;
797*4882a593Smuzhiyun }
798*4882a593Smuzhiyun num_entries++;
799*4882a593Smuzhiyun brelse(bh);
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun exfat_set_volume_dirty(sb);
802*4882a593Smuzhiyun /* update the directory entry */
803*4882a593Smuzhiyun if (exfat_remove_entries(dir, &cdir, entry, 0, num_entries)) {
804*4882a593Smuzhiyun err = -EIO;
805*4882a593Smuzhiyun goto unlock;
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun /* This doesn't modify ei */
809*4882a593Smuzhiyun ei->dir.dir = DIR_DELETED;
810*4882a593Smuzhiyun exfat_clear_volume_dirty(sb);
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun inode_inc_iversion(dir);
813*4882a593Smuzhiyun dir->i_mtime = dir->i_atime = current_time(dir);
814*4882a593Smuzhiyun exfat_truncate_atime(&dir->i_atime);
815*4882a593Smuzhiyun if (IS_DIRSYNC(dir))
816*4882a593Smuzhiyun exfat_sync_inode(dir);
817*4882a593Smuzhiyun else
818*4882a593Smuzhiyun mark_inode_dirty(dir);
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun clear_nlink(inode);
821*4882a593Smuzhiyun inode->i_mtime = inode->i_atime = current_time(inode);
822*4882a593Smuzhiyun exfat_truncate_atime(&inode->i_atime);
823*4882a593Smuzhiyun exfat_unhash_inode(inode);
824*4882a593Smuzhiyun exfat_d_version_set(dentry, inode_query_iversion(dir));
825*4882a593Smuzhiyun unlock:
826*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(sb)->s_lock);
827*4882a593Smuzhiyun return err;
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
exfat_mkdir(struct inode * dir,struct dentry * dentry,umode_t mode)830*4882a593Smuzhiyun static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
831*4882a593Smuzhiyun {
832*4882a593Smuzhiyun struct super_block *sb = dir->i_sb;
833*4882a593Smuzhiyun struct inode *inode;
834*4882a593Smuzhiyun struct exfat_dir_entry info;
835*4882a593Smuzhiyun struct exfat_chain cdir;
836*4882a593Smuzhiyun loff_t i_pos;
837*4882a593Smuzhiyun int err;
838*4882a593Smuzhiyun
839*4882a593Smuzhiyun mutex_lock(&EXFAT_SB(sb)->s_lock);
840*4882a593Smuzhiyun exfat_set_volume_dirty(sb);
841*4882a593Smuzhiyun err = exfat_add_entry(dir, dentry->d_name.name, &cdir, TYPE_DIR,
842*4882a593Smuzhiyun &info);
843*4882a593Smuzhiyun exfat_clear_volume_dirty(sb);
844*4882a593Smuzhiyun if (err)
845*4882a593Smuzhiyun goto unlock;
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun inode_inc_iversion(dir);
848*4882a593Smuzhiyun dir->i_ctime = dir->i_mtime = current_time(dir);
849*4882a593Smuzhiyun if (IS_DIRSYNC(dir))
850*4882a593Smuzhiyun exfat_sync_inode(dir);
851*4882a593Smuzhiyun else
852*4882a593Smuzhiyun mark_inode_dirty(dir);
853*4882a593Smuzhiyun inc_nlink(dir);
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun i_pos = exfat_make_i_pos(&info);
856*4882a593Smuzhiyun inode = exfat_build_inode(sb, &info, i_pos);
857*4882a593Smuzhiyun err = PTR_ERR_OR_ZERO(inode);
858*4882a593Smuzhiyun if (err)
859*4882a593Smuzhiyun goto unlock;
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun inode_inc_iversion(inode);
862*4882a593Smuzhiyun inode->i_mtime = inode->i_atime = inode->i_ctime =
863*4882a593Smuzhiyun EXFAT_I(inode)->i_crtime = current_time(inode);
864*4882a593Smuzhiyun exfat_truncate_atime(&inode->i_atime);
865*4882a593Smuzhiyun /* timestamp is already written, so mark_inode_dirty() is unneeded. */
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun d_instantiate(dentry, inode);
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun unlock:
870*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(sb)->s_lock);
871*4882a593Smuzhiyun return err;
872*4882a593Smuzhiyun }
873*4882a593Smuzhiyun
exfat_check_dir_empty(struct super_block * sb,struct exfat_chain * p_dir)874*4882a593Smuzhiyun static int exfat_check_dir_empty(struct super_block *sb,
875*4882a593Smuzhiyun struct exfat_chain *p_dir)
876*4882a593Smuzhiyun {
877*4882a593Smuzhiyun int i, dentries_per_clu;
878*4882a593Smuzhiyun unsigned int type;
879*4882a593Smuzhiyun struct exfat_chain clu;
880*4882a593Smuzhiyun struct exfat_dentry *ep;
881*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
882*4882a593Smuzhiyun struct buffer_head *bh;
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun dentries_per_clu = sbi->dentries_per_clu;
885*4882a593Smuzhiyun
886*4882a593Smuzhiyun exfat_chain_dup(&clu, p_dir);
887*4882a593Smuzhiyun
888*4882a593Smuzhiyun while (clu.dir != EXFAT_EOF_CLUSTER) {
889*4882a593Smuzhiyun for (i = 0; i < dentries_per_clu; i++) {
890*4882a593Smuzhiyun ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
891*4882a593Smuzhiyun if (!ep)
892*4882a593Smuzhiyun return -EIO;
893*4882a593Smuzhiyun type = exfat_get_entry_type(ep);
894*4882a593Smuzhiyun brelse(bh);
895*4882a593Smuzhiyun if (type == TYPE_UNUSED)
896*4882a593Smuzhiyun return 0;
897*4882a593Smuzhiyun
898*4882a593Smuzhiyun if (type != TYPE_FILE && type != TYPE_DIR)
899*4882a593Smuzhiyun continue;
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun return -ENOTEMPTY;
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun
904*4882a593Smuzhiyun if (clu.flags == ALLOC_NO_FAT_CHAIN) {
905*4882a593Smuzhiyun if (--clu.size > 0)
906*4882a593Smuzhiyun clu.dir++;
907*4882a593Smuzhiyun else
908*4882a593Smuzhiyun clu.dir = EXFAT_EOF_CLUSTER;
909*4882a593Smuzhiyun } else {
910*4882a593Smuzhiyun if (exfat_get_next_cluster(sb, &(clu.dir)))
911*4882a593Smuzhiyun return -EIO;
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun }
914*4882a593Smuzhiyun
915*4882a593Smuzhiyun return 0;
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun
exfat_rmdir(struct inode * dir,struct dentry * dentry)918*4882a593Smuzhiyun static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
919*4882a593Smuzhiyun {
920*4882a593Smuzhiyun struct inode *inode = dentry->d_inode;
921*4882a593Smuzhiyun struct exfat_dentry *ep;
922*4882a593Smuzhiyun struct exfat_chain cdir, clu_to_free;
923*4882a593Smuzhiyun struct super_block *sb = inode->i_sb;
924*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
925*4882a593Smuzhiyun struct exfat_inode_info *ei = EXFAT_I(inode);
926*4882a593Smuzhiyun struct buffer_head *bh;
927*4882a593Smuzhiyun sector_t sector;
928*4882a593Smuzhiyun int num_entries, entry, err;
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock);
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun exfat_chain_dup(&cdir, &ei->dir);
933*4882a593Smuzhiyun entry = ei->entry;
934*4882a593Smuzhiyun
935*4882a593Smuzhiyun if (ei->dir.dir == DIR_DELETED) {
936*4882a593Smuzhiyun exfat_err(sb, "abnormal access to deleted dentry");
937*4882a593Smuzhiyun err = -ENOENT;
938*4882a593Smuzhiyun goto unlock;
939*4882a593Smuzhiyun }
940*4882a593Smuzhiyun
941*4882a593Smuzhiyun exfat_chain_set(&clu_to_free, ei->start_clu,
942*4882a593Smuzhiyun EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi), ei->flags);
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun err = exfat_check_dir_empty(sb, &clu_to_free);
945*4882a593Smuzhiyun if (err) {
946*4882a593Smuzhiyun if (err == -EIO)
947*4882a593Smuzhiyun exfat_err(sb, "failed to exfat_check_dir_empty : err(%d)",
948*4882a593Smuzhiyun err);
949*4882a593Smuzhiyun goto unlock;
950*4882a593Smuzhiyun }
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun ep = exfat_get_dentry(sb, &cdir, entry, &bh, §or);
953*4882a593Smuzhiyun if (!ep) {
954*4882a593Smuzhiyun err = -EIO;
955*4882a593Smuzhiyun goto unlock;
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun
958*4882a593Smuzhiyun num_entries = exfat_count_ext_entries(sb, &cdir, entry, ep);
959*4882a593Smuzhiyun if (num_entries < 0) {
960*4882a593Smuzhiyun err = -EIO;
961*4882a593Smuzhiyun brelse(bh);
962*4882a593Smuzhiyun goto unlock;
963*4882a593Smuzhiyun }
964*4882a593Smuzhiyun num_entries++;
965*4882a593Smuzhiyun brelse(bh);
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun exfat_set_volume_dirty(sb);
968*4882a593Smuzhiyun err = exfat_remove_entries(dir, &cdir, entry, 0, num_entries);
969*4882a593Smuzhiyun if (err) {
970*4882a593Smuzhiyun exfat_err(sb, "failed to exfat_remove_entries : err(%d)", err);
971*4882a593Smuzhiyun goto unlock;
972*4882a593Smuzhiyun }
973*4882a593Smuzhiyun ei->dir.dir = DIR_DELETED;
974*4882a593Smuzhiyun exfat_clear_volume_dirty(sb);
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun inode_inc_iversion(dir);
977*4882a593Smuzhiyun dir->i_mtime = dir->i_atime = current_time(dir);
978*4882a593Smuzhiyun exfat_truncate_atime(&dir->i_atime);
979*4882a593Smuzhiyun if (IS_DIRSYNC(dir))
980*4882a593Smuzhiyun exfat_sync_inode(dir);
981*4882a593Smuzhiyun else
982*4882a593Smuzhiyun mark_inode_dirty(dir);
983*4882a593Smuzhiyun drop_nlink(dir);
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun clear_nlink(inode);
986*4882a593Smuzhiyun inode->i_mtime = inode->i_atime = current_time(inode);
987*4882a593Smuzhiyun exfat_truncate_atime(&inode->i_atime);
988*4882a593Smuzhiyun exfat_unhash_inode(inode);
989*4882a593Smuzhiyun exfat_d_version_set(dentry, inode_query_iversion(dir));
990*4882a593Smuzhiyun unlock:
991*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock);
992*4882a593Smuzhiyun return err;
993*4882a593Smuzhiyun }
994*4882a593Smuzhiyun
exfat_rename_file(struct inode * inode,struct exfat_chain * p_dir,int oldentry,struct exfat_uni_name * p_uniname,struct exfat_inode_info * ei)995*4882a593Smuzhiyun static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
996*4882a593Smuzhiyun int oldentry, struct exfat_uni_name *p_uniname,
997*4882a593Smuzhiyun struct exfat_inode_info *ei)
998*4882a593Smuzhiyun {
999*4882a593Smuzhiyun int ret, num_old_entries, num_new_entries;
1000*4882a593Smuzhiyun sector_t sector_old, sector_new;
1001*4882a593Smuzhiyun struct exfat_dentry *epold, *epnew;
1002*4882a593Smuzhiyun struct super_block *sb = inode->i_sb;
1003*4882a593Smuzhiyun struct buffer_head *new_bh, *old_bh;
1004*4882a593Smuzhiyun int sync = IS_DIRSYNC(inode);
1005*4882a593Smuzhiyun
1006*4882a593Smuzhiyun epold = exfat_get_dentry(sb, p_dir, oldentry, &old_bh, §or_old);
1007*4882a593Smuzhiyun if (!epold)
1008*4882a593Smuzhiyun return -EIO;
1009*4882a593Smuzhiyun
1010*4882a593Smuzhiyun num_old_entries = exfat_count_ext_entries(sb, p_dir, oldentry, epold);
1011*4882a593Smuzhiyun if (num_old_entries < 0)
1012*4882a593Smuzhiyun return -EIO;
1013*4882a593Smuzhiyun num_old_entries++;
1014*4882a593Smuzhiyun
1015*4882a593Smuzhiyun num_new_entries = exfat_calc_num_entries(p_uniname);
1016*4882a593Smuzhiyun if (num_new_entries < 0)
1017*4882a593Smuzhiyun return num_new_entries;
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun if (num_old_entries < num_new_entries) {
1020*4882a593Smuzhiyun int newentry;
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun newentry =
1023*4882a593Smuzhiyun exfat_find_empty_entry(inode, p_dir, num_new_entries);
1024*4882a593Smuzhiyun if (newentry < 0)
1025*4882a593Smuzhiyun return newentry; /* -EIO or -ENOSPC */
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun epnew = exfat_get_dentry(sb, p_dir, newentry, &new_bh,
1028*4882a593Smuzhiyun §or_new);
1029*4882a593Smuzhiyun if (!epnew)
1030*4882a593Smuzhiyun return -EIO;
1031*4882a593Smuzhiyun
1032*4882a593Smuzhiyun *epnew = *epold;
1033*4882a593Smuzhiyun if (exfat_get_entry_type(epnew) == TYPE_FILE) {
1034*4882a593Smuzhiyun epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE);
1035*4882a593Smuzhiyun ei->attr |= ATTR_ARCHIVE;
1036*4882a593Smuzhiyun }
1037*4882a593Smuzhiyun exfat_update_bh(new_bh, sync);
1038*4882a593Smuzhiyun brelse(old_bh);
1039*4882a593Smuzhiyun brelse(new_bh);
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun epold = exfat_get_dentry(sb, p_dir, oldentry + 1, &old_bh,
1042*4882a593Smuzhiyun §or_old);
1043*4882a593Smuzhiyun if (!epold)
1044*4882a593Smuzhiyun return -EIO;
1045*4882a593Smuzhiyun epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh,
1046*4882a593Smuzhiyun §or_new);
1047*4882a593Smuzhiyun if (!epnew) {
1048*4882a593Smuzhiyun brelse(old_bh);
1049*4882a593Smuzhiyun return -EIO;
1050*4882a593Smuzhiyun }
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun *epnew = *epold;
1053*4882a593Smuzhiyun exfat_update_bh(new_bh, sync);
1054*4882a593Smuzhiyun brelse(old_bh);
1055*4882a593Smuzhiyun brelse(new_bh);
1056*4882a593Smuzhiyun
1057*4882a593Smuzhiyun ret = exfat_init_ext_entry(inode, p_dir, newentry,
1058*4882a593Smuzhiyun num_new_entries, p_uniname);
1059*4882a593Smuzhiyun if (ret)
1060*4882a593Smuzhiyun return ret;
1061*4882a593Smuzhiyun
1062*4882a593Smuzhiyun exfat_remove_entries(inode, p_dir, oldentry, 0,
1063*4882a593Smuzhiyun num_old_entries);
1064*4882a593Smuzhiyun ei->entry = newentry;
1065*4882a593Smuzhiyun } else {
1066*4882a593Smuzhiyun if (exfat_get_entry_type(epold) == TYPE_FILE) {
1067*4882a593Smuzhiyun epold->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE);
1068*4882a593Smuzhiyun ei->attr |= ATTR_ARCHIVE;
1069*4882a593Smuzhiyun }
1070*4882a593Smuzhiyun exfat_update_bh(old_bh, sync);
1071*4882a593Smuzhiyun brelse(old_bh);
1072*4882a593Smuzhiyun ret = exfat_init_ext_entry(inode, p_dir, oldentry,
1073*4882a593Smuzhiyun num_new_entries, p_uniname);
1074*4882a593Smuzhiyun if (ret)
1075*4882a593Smuzhiyun return ret;
1076*4882a593Smuzhiyun
1077*4882a593Smuzhiyun exfat_remove_entries(inode, p_dir, oldentry, num_new_entries,
1078*4882a593Smuzhiyun num_old_entries);
1079*4882a593Smuzhiyun }
1080*4882a593Smuzhiyun return 0;
1081*4882a593Smuzhiyun }
1082*4882a593Smuzhiyun
exfat_move_file(struct inode * inode,struct exfat_chain * p_olddir,int oldentry,struct exfat_chain * p_newdir,struct exfat_uni_name * p_uniname,struct exfat_inode_info * ei)1083*4882a593Smuzhiyun static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,
1084*4882a593Smuzhiyun int oldentry, struct exfat_chain *p_newdir,
1085*4882a593Smuzhiyun struct exfat_uni_name *p_uniname, struct exfat_inode_info *ei)
1086*4882a593Smuzhiyun {
1087*4882a593Smuzhiyun int ret, newentry, num_new_entries, num_old_entries;
1088*4882a593Smuzhiyun sector_t sector_mov, sector_new;
1089*4882a593Smuzhiyun struct exfat_dentry *epmov, *epnew;
1090*4882a593Smuzhiyun struct super_block *sb = inode->i_sb;
1091*4882a593Smuzhiyun struct buffer_head *mov_bh, *new_bh;
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun epmov = exfat_get_dentry(sb, p_olddir, oldentry, &mov_bh, §or_mov);
1094*4882a593Smuzhiyun if (!epmov)
1095*4882a593Smuzhiyun return -EIO;
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun num_old_entries = exfat_count_ext_entries(sb, p_olddir, oldentry,
1098*4882a593Smuzhiyun epmov);
1099*4882a593Smuzhiyun if (num_old_entries < 0)
1100*4882a593Smuzhiyun return -EIO;
1101*4882a593Smuzhiyun num_old_entries++;
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun num_new_entries = exfat_calc_num_entries(p_uniname);
1104*4882a593Smuzhiyun if (num_new_entries < 0)
1105*4882a593Smuzhiyun return num_new_entries;
1106*4882a593Smuzhiyun
1107*4882a593Smuzhiyun newentry = exfat_find_empty_entry(inode, p_newdir, num_new_entries);
1108*4882a593Smuzhiyun if (newentry < 0)
1109*4882a593Smuzhiyun return newentry; /* -EIO or -ENOSPC */
1110*4882a593Smuzhiyun
1111*4882a593Smuzhiyun epnew = exfat_get_dentry(sb, p_newdir, newentry, &new_bh, §or_new);
1112*4882a593Smuzhiyun if (!epnew)
1113*4882a593Smuzhiyun return -EIO;
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun *epnew = *epmov;
1116*4882a593Smuzhiyun if (exfat_get_entry_type(epnew) == TYPE_FILE) {
1117*4882a593Smuzhiyun epnew->dentry.file.attr |= cpu_to_le16(ATTR_ARCHIVE);
1118*4882a593Smuzhiyun ei->attr |= ATTR_ARCHIVE;
1119*4882a593Smuzhiyun }
1120*4882a593Smuzhiyun exfat_update_bh(new_bh, IS_DIRSYNC(inode));
1121*4882a593Smuzhiyun brelse(mov_bh);
1122*4882a593Smuzhiyun brelse(new_bh);
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun epmov = exfat_get_dentry(sb, p_olddir, oldentry + 1, &mov_bh,
1125*4882a593Smuzhiyun §or_mov);
1126*4882a593Smuzhiyun if (!epmov)
1127*4882a593Smuzhiyun return -EIO;
1128*4882a593Smuzhiyun epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh,
1129*4882a593Smuzhiyun §or_new);
1130*4882a593Smuzhiyun if (!epnew) {
1131*4882a593Smuzhiyun brelse(mov_bh);
1132*4882a593Smuzhiyun return -EIO;
1133*4882a593Smuzhiyun }
1134*4882a593Smuzhiyun
1135*4882a593Smuzhiyun *epnew = *epmov;
1136*4882a593Smuzhiyun exfat_update_bh(new_bh, IS_DIRSYNC(inode));
1137*4882a593Smuzhiyun brelse(mov_bh);
1138*4882a593Smuzhiyun brelse(new_bh);
1139*4882a593Smuzhiyun
1140*4882a593Smuzhiyun ret = exfat_init_ext_entry(inode, p_newdir, newentry, num_new_entries,
1141*4882a593Smuzhiyun p_uniname);
1142*4882a593Smuzhiyun if (ret)
1143*4882a593Smuzhiyun return ret;
1144*4882a593Smuzhiyun
1145*4882a593Smuzhiyun exfat_remove_entries(inode, p_olddir, oldentry, 0, num_old_entries);
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun exfat_chain_set(&ei->dir, p_newdir->dir, p_newdir->size,
1148*4882a593Smuzhiyun p_newdir->flags);
1149*4882a593Smuzhiyun
1150*4882a593Smuzhiyun ei->entry = newentry;
1151*4882a593Smuzhiyun return 0;
1152*4882a593Smuzhiyun }
1153*4882a593Smuzhiyun
exfat_update_parent_info(struct exfat_inode_info * ei,struct inode * parent_inode)1154*4882a593Smuzhiyun static void exfat_update_parent_info(struct exfat_inode_info *ei,
1155*4882a593Smuzhiyun struct inode *parent_inode)
1156*4882a593Smuzhiyun {
1157*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(parent_inode->i_sb);
1158*4882a593Smuzhiyun struct exfat_inode_info *parent_ei = EXFAT_I(parent_inode);
1159*4882a593Smuzhiyun loff_t parent_isize = i_size_read(parent_inode);
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun /*
1162*4882a593Smuzhiyun * the problem that struct exfat_inode_info caches wrong parent info.
1163*4882a593Smuzhiyun *
1164*4882a593Smuzhiyun * because of flag-mismatch of ei->dir,
1165*4882a593Smuzhiyun * there is abnormal traversing cluster chain.
1166*4882a593Smuzhiyun */
1167*4882a593Smuzhiyun if (unlikely(parent_ei->flags != ei->dir.flags ||
1168*4882a593Smuzhiyun parent_isize != EXFAT_CLU_TO_B(ei->dir.size, sbi) ||
1169*4882a593Smuzhiyun parent_ei->start_clu != ei->dir.dir)) {
1170*4882a593Smuzhiyun exfat_chain_set(&ei->dir, parent_ei->start_clu,
1171*4882a593Smuzhiyun EXFAT_B_TO_CLU_ROUND_UP(parent_isize, sbi),
1172*4882a593Smuzhiyun parent_ei->flags);
1173*4882a593Smuzhiyun }
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun
1176*4882a593Smuzhiyun /* rename or move a old file into a new file */
__exfat_rename(struct inode * old_parent_inode,struct exfat_inode_info * ei,struct inode * new_parent_inode,struct dentry * new_dentry)1177*4882a593Smuzhiyun static int __exfat_rename(struct inode *old_parent_inode,
1178*4882a593Smuzhiyun struct exfat_inode_info *ei, struct inode *new_parent_inode,
1179*4882a593Smuzhiyun struct dentry *new_dentry)
1180*4882a593Smuzhiyun {
1181*4882a593Smuzhiyun int ret;
1182*4882a593Smuzhiyun int dentry;
1183*4882a593Smuzhiyun struct exfat_chain olddir, newdir;
1184*4882a593Smuzhiyun struct exfat_chain *p_dir = NULL;
1185*4882a593Smuzhiyun struct exfat_uni_name uni_name;
1186*4882a593Smuzhiyun struct exfat_dentry *ep;
1187*4882a593Smuzhiyun struct super_block *sb = old_parent_inode->i_sb;
1188*4882a593Smuzhiyun struct exfat_sb_info *sbi = EXFAT_SB(sb);
1189*4882a593Smuzhiyun const unsigned char *new_path = new_dentry->d_name.name;
1190*4882a593Smuzhiyun struct inode *new_inode = new_dentry->d_inode;
1191*4882a593Smuzhiyun int num_entries;
1192*4882a593Smuzhiyun struct exfat_inode_info *new_ei = NULL;
1193*4882a593Smuzhiyun unsigned int new_entry_type = TYPE_UNUSED;
1194*4882a593Smuzhiyun int new_entry = 0;
1195*4882a593Smuzhiyun struct buffer_head *old_bh, *new_bh = NULL;
1196*4882a593Smuzhiyun
1197*4882a593Smuzhiyun /* check the validity of pointer parameters */
1198*4882a593Smuzhiyun if (new_path == NULL || strlen(new_path) == 0)
1199*4882a593Smuzhiyun return -EINVAL;
1200*4882a593Smuzhiyun
1201*4882a593Smuzhiyun if (ei->dir.dir == DIR_DELETED) {
1202*4882a593Smuzhiyun exfat_err(sb, "abnormal access to deleted source dentry");
1203*4882a593Smuzhiyun return -ENOENT;
1204*4882a593Smuzhiyun }
1205*4882a593Smuzhiyun
1206*4882a593Smuzhiyun exfat_update_parent_info(ei, old_parent_inode);
1207*4882a593Smuzhiyun
1208*4882a593Smuzhiyun exfat_chain_dup(&olddir, &ei->dir);
1209*4882a593Smuzhiyun dentry = ei->entry;
1210*4882a593Smuzhiyun
1211*4882a593Smuzhiyun ep = exfat_get_dentry(sb, &olddir, dentry, &old_bh, NULL);
1212*4882a593Smuzhiyun if (!ep) {
1213*4882a593Smuzhiyun ret = -EIO;
1214*4882a593Smuzhiyun goto out;
1215*4882a593Smuzhiyun }
1216*4882a593Smuzhiyun brelse(old_bh);
1217*4882a593Smuzhiyun
1218*4882a593Smuzhiyun /* check whether new dir is existing directory and empty */
1219*4882a593Smuzhiyun if (new_inode) {
1220*4882a593Smuzhiyun ret = -EIO;
1221*4882a593Smuzhiyun new_ei = EXFAT_I(new_inode);
1222*4882a593Smuzhiyun
1223*4882a593Smuzhiyun if (new_ei->dir.dir == DIR_DELETED) {
1224*4882a593Smuzhiyun exfat_err(sb, "abnormal access to deleted target dentry");
1225*4882a593Smuzhiyun goto out;
1226*4882a593Smuzhiyun }
1227*4882a593Smuzhiyun
1228*4882a593Smuzhiyun exfat_update_parent_info(new_ei, new_parent_inode);
1229*4882a593Smuzhiyun
1230*4882a593Smuzhiyun p_dir = &(new_ei->dir);
1231*4882a593Smuzhiyun new_entry = new_ei->entry;
1232*4882a593Smuzhiyun ep = exfat_get_dentry(sb, p_dir, new_entry, &new_bh, NULL);
1233*4882a593Smuzhiyun if (!ep)
1234*4882a593Smuzhiyun goto out;
1235*4882a593Smuzhiyun
1236*4882a593Smuzhiyun new_entry_type = exfat_get_entry_type(ep);
1237*4882a593Smuzhiyun brelse(new_bh);
1238*4882a593Smuzhiyun
1239*4882a593Smuzhiyun /* if new_inode exists, update ei */
1240*4882a593Smuzhiyun if (new_entry_type == TYPE_DIR) {
1241*4882a593Smuzhiyun struct exfat_chain new_clu;
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun new_clu.dir = new_ei->start_clu;
1244*4882a593Smuzhiyun new_clu.size =
1245*4882a593Smuzhiyun EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode),
1246*4882a593Smuzhiyun sbi);
1247*4882a593Smuzhiyun new_clu.flags = new_ei->flags;
1248*4882a593Smuzhiyun
1249*4882a593Smuzhiyun ret = exfat_check_dir_empty(sb, &new_clu);
1250*4882a593Smuzhiyun if (ret)
1251*4882a593Smuzhiyun goto out;
1252*4882a593Smuzhiyun }
1253*4882a593Smuzhiyun }
1254*4882a593Smuzhiyun
1255*4882a593Smuzhiyun /* check the validity of directory name in the given new pathname */
1256*4882a593Smuzhiyun ret = exfat_resolve_path(new_parent_inode, new_path, &newdir,
1257*4882a593Smuzhiyun &uni_name);
1258*4882a593Smuzhiyun if (ret)
1259*4882a593Smuzhiyun goto out;
1260*4882a593Smuzhiyun
1261*4882a593Smuzhiyun exfat_set_volume_dirty(sb);
1262*4882a593Smuzhiyun
1263*4882a593Smuzhiyun if (olddir.dir == newdir.dir)
1264*4882a593Smuzhiyun ret = exfat_rename_file(new_parent_inode, &olddir, dentry,
1265*4882a593Smuzhiyun &uni_name, ei);
1266*4882a593Smuzhiyun else
1267*4882a593Smuzhiyun ret = exfat_move_file(new_parent_inode, &olddir, dentry,
1268*4882a593Smuzhiyun &newdir, &uni_name, ei);
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun if (!ret && new_inode) {
1271*4882a593Smuzhiyun /* delete entries of new_dir */
1272*4882a593Smuzhiyun ep = exfat_get_dentry(sb, p_dir, new_entry, &new_bh, NULL);
1273*4882a593Smuzhiyun if (!ep) {
1274*4882a593Smuzhiyun ret = -EIO;
1275*4882a593Smuzhiyun goto del_out;
1276*4882a593Smuzhiyun }
1277*4882a593Smuzhiyun
1278*4882a593Smuzhiyun num_entries = exfat_count_ext_entries(sb, p_dir, new_entry, ep);
1279*4882a593Smuzhiyun if (num_entries < 0) {
1280*4882a593Smuzhiyun ret = -EIO;
1281*4882a593Smuzhiyun goto del_out;
1282*4882a593Smuzhiyun }
1283*4882a593Smuzhiyun brelse(new_bh);
1284*4882a593Smuzhiyun
1285*4882a593Smuzhiyun if (exfat_remove_entries(new_inode, p_dir, new_entry, 0,
1286*4882a593Smuzhiyun num_entries + 1)) {
1287*4882a593Smuzhiyun ret = -EIO;
1288*4882a593Smuzhiyun goto del_out;
1289*4882a593Smuzhiyun }
1290*4882a593Smuzhiyun
1291*4882a593Smuzhiyun /* Free the clusters if new_inode is a dir(as if exfat_rmdir) */
1292*4882a593Smuzhiyun if (new_entry_type == TYPE_DIR) {
1293*4882a593Smuzhiyun /* new_ei, new_clu_to_free */
1294*4882a593Smuzhiyun struct exfat_chain new_clu_to_free;
1295*4882a593Smuzhiyun
1296*4882a593Smuzhiyun exfat_chain_set(&new_clu_to_free, new_ei->start_clu,
1297*4882a593Smuzhiyun EXFAT_B_TO_CLU_ROUND_UP(i_size_read(new_inode),
1298*4882a593Smuzhiyun sbi), new_ei->flags);
1299*4882a593Smuzhiyun
1300*4882a593Smuzhiyun if (exfat_free_cluster(new_inode, &new_clu_to_free)) {
1301*4882a593Smuzhiyun /* just set I/O error only */
1302*4882a593Smuzhiyun ret = -EIO;
1303*4882a593Smuzhiyun }
1304*4882a593Smuzhiyun
1305*4882a593Smuzhiyun i_size_write(new_inode, 0);
1306*4882a593Smuzhiyun new_ei->start_clu = EXFAT_EOF_CLUSTER;
1307*4882a593Smuzhiyun new_ei->flags = ALLOC_NO_FAT_CHAIN;
1308*4882a593Smuzhiyun }
1309*4882a593Smuzhiyun del_out:
1310*4882a593Smuzhiyun /* Update new_inode ei
1311*4882a593Smuzhiyun * Prevent syncing removed new_inode
1312*4882a593Smuzhiyun * (new_ei is already initialized above code ("if (new_inode)")
1313*4882a593Smuzhiyun */
1314*4882a593Smuzhiyun new_ei->dir.dir = DIR_DELETED;
1315*4882a593Smuzhiyun }
1316*4882a593Smuzhiyun exfat_clear_volume_dirty(sb);
1317*4882a593Smuzhiyun out:
1318*4882a593Smuzhiyun return ret;
1319*4882a593Smuzhiyun }
1320*4882a593Smuzhiyun
exfat_rename(struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)1321*4882a593Smuzhiyun static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
1322*4882a593Smuzhiyun struct inode *new_dir, struct dentry *new_dentry,
1323*4882a593Smuzhiyun unsigned int flags)
1324*4882a593Smuzhiyun {
1325*4882a593Smuzhiyun struct inode *old_inode, *new_inode;
1326*4882a593Smuzhiyun struct super_block *sb = old_dir->i_sb;
1327*4882a593Smuzhiyun loff_t i_pos;
1328*4882a593Smuzhiyun int err;
1329*4882a593Smuzhiyun
1330*4882a593Smuzhiyun /*
1331*4882a593Smuzhiyun * The VFS already checks for existence, so for local filesystems
1332*4882a593Smuzhiyun * the RENAME_NOREPLACE implementation is equivalent to plain rename.
1333*4882a593Smuzhiyun * Don't support any other flags
1334*4882a593Smuzhiyun */
1335*4882a593Smuzhiyun if (flags & ~RENAME_NOREPLACE)
1336*4882a593Smuzhiyun return -EINVAL;
1337*4882a593Smuzhiyun
1338*4882a593Smuzhiyun mutex_lock(&EXFAT_SB(sb)->s_lock);
1339*4882a593Smuzhiyun old_inode = old_dentry->d_inode;
1340*4882a593Smuzhiyun new_inode = new_dentry->d_inode;
1341*4882a593Smuzhiyun
1342*4882a593Smuzhiyun err = __exfat_rename(old_dir, EXFAT_I(old_inode), new_dir, new_dentry);
1343*4882a593Smuzhiyun if (err)
1344*4882a593Smuzhiyun goto unlock;
1345*4882a593Smuzhiyun
1346*4882a593Smuzhiyun inode_inc_iversion(new_dir);
1347*4882a593Smuzhiyun new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
1348*4882a593Smuzhiyun EXFAT_I(new_dir)->i_crtime = current_time(new_dir);
1349*4882a593Smuzhiyun exfat_truncate_atime(&new_dir->i_atime);
1350*4882a593Smuzhiyun if (IS_DIRSYNC(new_dir))
1351*4882a593Smuzhiyun exfat_sync_inode(new_dir);
1352*4882a593Smuzhiyun else
1353*4882a593Smuzhiyun mark_inode_dirty(new_dir);
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun i_pos = ((loff_t)EXFAT_I(old_inode)->dir.dir << 32) |
1356*4882a593Smuzhiyun (EXFAT_I(old_inode)->entry & 0xffffffff);
1357*4882a593Smuzhiyun exfat_unhash_inode(old_inode);
1358*4882a593Smuzhiyun exfat_hash_inode(old_inode, i_pos);
1359*4882a593Smuzhiyun if (IS_DIRSYNC(new_dir))
1360*4882a593Smuzhiyun exfat_sync_inode(old_inode);
1361*4882a593Smuzhiyun else
1362*4882a593Smuzhiyun mark_inode_dirty(old_inode);
1363*4882a593Smuzhiyun
1364*4882a593Smuzhiyun if (S_ISDIR(old_inode->i_mode) && old_dir != new_dir) {
1365*4882a593Smuzhiyun drop_nlink(old_dir);
1366*4882a593Smuzhiyun if (!new_inode)
1367*4882a593Smuzhiyun inc_nlink(new_dir);
1368*4882a593Smuzhiyun }
1369*4882a593Smuzhiyun
1370*4882a593Smuzhiyun inode_inc_iversion(old_dir);
1371*4882a593Smuzhiyun old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
1372*4882a593Smuzhiyun if (IS_DIRSYNC(old_dir))
1373*4882a593Smuzhiyun exfat_sync_inode(old_dir);
1374*4882a593Smuzhiyun else
1375*4882a593Smuzhiyun mark_inode_dirty(old_dir);
1376*4882a593Smuzhiyun
1377*4882a593Smuzhiyun if (new_inode) {
1378*4882a593Smuzhiyun exfat_unhash_inode(new_inode);
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun /* skip drop_nlink if new_inode already has been dropped */
1381*4882a593Smuzhiyun if (new_inode->i_nlink) {
1382*4882a593Smuzhiyun drop_nlink(new_inode);
1383*4882a593Smuzhiyun if (S_ISDIR(new_inode->i_mode))
1384*4882a593Smuzhiyun drop_nlink(new_inode);
1385*4882a593Smuzhiyun } else {
1386*4882a593Smuzhiyun exfat_warn(sb, "abnormal access to an inode dropped");
1387*4882a593Smuzhiyun WARN_ON(new_inode->i_nlink == 0);
1388*4882a593Smuzhiyun }
1389*4882a593Smuzhiyun new_inode->i_ctime = EXFAT_I(new_inode)->i_crtime =
1390*4882a593Smuzhiyun current_time(new_inode);
1391*4882a593Smuzhiyun }
1392*4882a593Smuzhiyun
1393*4882a593Smuzhiyun unlock:
1394*4882a593Smuzhiyun mutex_unlock(&EXFAT_SB(sb)->s_lock);
1395*4882a593Smuzhiyun return err;
1396*4882a593Smuzhiyun }
1397*4882a593Smuzhiyun
1398*4882a593Smuzhiyun const struct inode_operations exfat_dir_inode_operations = {
1399*4882a593Smuzhiyun .create = exfat_create,
1400*4882a593Smuzhiyun .lookup = exfat_lookup,
1401*4882a593Smuzhiyun .unlink = exfat_unlink,
1402*4882a593Smuzhiyun .mkdir = exfat_mkdir,
1403*4882a593Smuzhiyun .rmdir = exfat_rmdir,
1404*4882a593Smuzhiyun .rename = exfat_rename,
1405*4882a593Smuzhiyun .setattr = exfat_setattr,
1406*4882a593Smuzhiyun .getattr = exfat_getattr,
1407*4882a593Smuzhiyun };
1408