2
* Copyright (C) 2005-2008 Junjiro Okajima
4
* This program, aufs is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
* $Id: finfo.c,v 1.2 2008/04/21 01:35:14 sfjro Exp $
27
struct au_finfo *au_fi(struct file *file)
29
struct au_finfo *finfo = file->private_data;
32
|| (0 < finfo->fi_bend
33
&& (/* au_sbi(file->f_dentry->d_sb)->si_bend
35
|| */ finfo->fi_bend < finfo->fi_bstart)));
39
struct au_branch *au_fbr(struct file *file, aufs_bindex_t bindex)
41
struct au_finfo *finfo = au_fi(file);
46
|| finfo->fi_bstart < 0
47
|| bindex < finfo->fi_bstart
48
|| finfo->fi_bend < bindex);
49
hf = finfo->fi_hfile + bindex;
50
AuDebugOn(hf->hf_br && au_br_count(hf->hf_br) <= 0);
54
struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex)
56
struct au_finfo *finfo = au_fi(file);
61
|| finfo->fi_bstart < 0
62
|| bindex < finfo->fi_bstart
63
|| finfo->fi_bend < bindex);
64
hf = finfo->fi_hfile + bindex;
66
&& file_count(hf->hf_file) <= 0
67
&& au_br_count(hf->hf_br) <= 0);
71
void au_hfput(struct au_hfile *hf)
73
if (hf->hf_file->f_mode & FMODE_EXEC)
74
au_allow_write_access(hf->hf_file);
77
AuDebugOn(!hf->hf_br);
82
void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val)
84
struct au_finfo *finfo = au_fi(file);
87
FiMustWriteLock(file);
89
|| finfo->fi_bstart < 0
90
|| bindex < finfo->fi_bstart
91
|| finfo->fi_bend < bindex);
92
AuDebugOn(val && file_count(val) <= 0);
93
hf = finfo->fi_hfile + bindex;
94
AuDebugOn(val && hf->hf_file);
99
hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex);
103
void au_finfo_fin(struct file *file)
105
struct au_finfo *finfo;
106
struct dentry *dentry;
107
aufs_bindex_t bindex, bend;
109
dentry = file->f_dentry;
110
LKTRTrace("%.*s\n", AuDLNPair(dentry));
111
SiMustAnyLock(dentry->d_sb);
114
bend = au_fbend(file);
115
bindex = au_fbstart(file);
117
for (; bindex <= bend; bindex++)
118
au_set_h_fptr(file, bindex, NULL);
121
#ifdef CONFIG_AUFS_DEBUG
122
if (finfo->fi_bstart >= 0) {
123
bend = au_fbend(file);
124
for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) {
126
hf = finfo->fi_hfile + bindex;
127
AuDebugOn(hf->hf_file || hf->hf_br);
132
kfree(finfo->fi_hfile);
133
fi_write_unlock(file);
134
au_cache_free_finfo(finfo);
135
//file->private_data = NULL;
138
int au_finfo_init(struct file *file)
140
struct au_finfo *finfo;
141
struct dentry *dentry;
147
dentry = file->f_dentry;
148
LKTRTrace("%.*s\n", AuDLNPair(dentry));
149
AuDebugOn(!dentry->d_inode);
151
finfo = au_cache_alloc_finfo();
153
finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1,
154
sizeof(*finfo->fi_hfile), GFP_KERNEL);
155
if (finfo->fi_hfile) {
156
au_rw_init_wlock(&finfo->fi_rwsem);
157
finfo->fi_bstart = -1;
159
atomic_set(&finfo->fi_generation, au_digen(dentry));
160
//smp_mb(); /* atomic_set */
163
* a dirty trick for handling FMODE_EXEC and
164
* deny_write_access().
165
* because FMODE_EXEC flag is not passed to
167
* aufs set it to file->private_data temporary in lookup
168
* or dentry revalidation operations.
169
* restore the flag to f_mode here.
171
u.p = file->private_data;
172
if (u.ul & FMODE_EXEC) {
173
file->f_mode |= FMODE_EXEC;
174
smp_mb(); /* flush f_mode */
177
file->private_data = finfo;
178
return 0; /* success */
180
au_cache_free_finfo(finfo);