16
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
/* $Id: misc.c,v 1.33 2007/06/04 02:17:35 sfjro Exp $ */
19
/* $Id: misc.c,v 1.47 2007/11/12 01:40:06 sfjro Exp $ */
21
21
//#include <linux/fs.h>
22
22
//#include <linux/namei.h>
31
LKTRTrace("p %p, nused %d, sz %d, ksize %d\n",
32
p, nused, new_sz, ksize(p));
31
LKTRTrace("p %p, nused %d, sz %d\n", p, nused, new_sz);
33
32
AuDebugOn(new_sz <= 0);
34
33
if (new_sz <= nused)
36
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
37
q = krealloc(p, new_sz, gfp);
39
memset(q + nused, 0, new_sz - nused);
42
LKTRTrace("ksize %d\n", ksize(p));
36
43
if (new_sz <= ksize(p)) {
37
44
memset(p + nused, 0, new_sz - nused);
57
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) */
52
60
/* ---------------------------------------------------------------------- */
62
struct nameidata *au_dup_nd(struct aufs_sbinfo *sbinfo, struct nameidata *dst,
63
struct nameidata *src)
65
LKTRTrace("src %p\n", src);
69
dst->flags &= ~LOOKUP_PARENT;
70
if (unlikely(AuFlag(sbinfo, f_wbr_create) != AuWbrCreate_TDP)) {
71
dst->flags &= ~LOOKUP_CREATE;
72
dst->intent.open.flags &= ~O_CREAT;
54
80
// todo: make it inline
55
struct nameidata *fake_dm(struct nameidata *fake_nd, struct nameidata *nd,
56
struct super_block *sb, aufs_bindex_t bindex)
81
struct nameidata *au_fake_dm(struct nameidata *fake_nd, struct nameidata *nd,
82
struct super_block *sb, aufs_bindex_t bindex)
58
84
LKTRTrace("nd %p, b%d\n", nd, bindex);
120
int au_h_create(struct inode *h_dir, struct dentry *h_dentry, int mode,
121
int dlgt, struct nameidata *nd, struct vfsmount *nfsmnt)
125
LKTRTrace("hi%lu, %.*s, 0%o, nd %d, nfsmnt %d\n",
126
h_dir->i_ino, AuDLNPair(h_dentry), mode, !!nd, !!nfsmnt);
130
err = vfsub_create(h_dir, h_dentry, mode, /*nd*/NULL, dlgt);
132
#ifndef CONFIG_AUFS_FAKE_DM
133
struct nameidata fake_nd;
138
memset(&fake_nd, 0, sizeof(fake_nd));
139
fake_nd.dentry = dget(h_dentry);
140
fake_nd.mnt = mntget(nfsmnt);
141
fake_nd.flags = LOOKUP_CREATE;
142
fake_nd.intent.open.flags = O_CREAT | FMODE_READ;
143
fake_nd.intent.open.create_mode = mode;
145
err = vfsub_create(h_dir, h_dentry, mode, &fake_nd, dlgt);
146
path_release(&fake_nd);
94
154
/* ---------------------------------------------------------------------- */
96
156
int au_copy_file(struct file *dst, struct file *src, loff_t len,
97
struct super_block *sb, int *sparse)
157
struct super_block *sb)
99
int err, all_zero, dlgt;
100
160
unsigned long blksize;
162
struct vfsub_args vargs;
102
163
/* reduce stack space */
103
164
struct iattr *ia;
105
166
LKTRTrace("%.*s, %.*s\n",
106
DLNPair(dst->f_dentry), DLNPair(src->f_dentry));
167
AuDLNPair(dst->f_dentry), AuDLNPair(src->f_dentry));
107
168
AuDebugOn(!(dst->f_mode & FMODE_WRITE));
108
169
#ifdef CONFIG_AUFS_DEBUG
119
180
if (!blksize || PAGE_SIZE < blksize)
120
181
blksize = PAGE_SIZE;
121
182
LKTRTrace("blksize %lu\n", blksize);
122
buf = kmalloc(blksize, GFP_KERNEL);
183
buf = kmalloc(blksize, GFP_TEMPORARY);
124
185
if (unlikely(!buf))
126
ia = kmalloc(sizeof(*ia), GFP_KERNEL);
187
ia = kmalloc(sizeof(*ia), GFP_TEMPORARY);
127
188
if (unlikely(!ia))
130
dlgt = need_dlgt(sb);
132
dst->f_pos = src->f_pos = 0;
191
#ifdef CONFIG_AUFS_DEBUG
193
AuWarn("copying a large file %Ld\n", (long long)len);
195
vfsub_args_init(&vargs, NULL, au_need_dlgt(sb), 0);
134
201
size_t sz, rbytes, wbytes, i;
142
209
/* support LSM and notify */
144
while (!rbytes || err == -EAGAIN || err == -EINTR)
145
err = rbytes = vfsub_read_k(src, buf, sz, &src->f_pos,
212
while (!rbytes || err == -EAGAIN || err == -EINTR) {
213
rbytes = vfsub_read_k(src, buf, sz, &src->f_pos,
147
217
if (unlikely(err < 0))
162
232
/* support LSM and notify */
163
err = b = vfsub_write_k(dst, p, wbytes,
233
b = vfsub_write_k(dst, p, wbytes, &dst->f_pos,
165
237
if (unlikely(err == -EAGAIN || err == -EINTR))
167
239
if (unlikely(err < 0))
189
261
LKTRLabel(last hole);
191
err = vfsub_write_k(dst, "\0", 1, &dst->f_pos, dlgt);
264
err = vfsub_write_k(dst, "\0", 1, &dst->f_pos, &vargs);
192
265
} while (err == -EAGAIN || err == -EINTR);
194
267
ia->ia_size = dst->f_pos;
195
268
ia->ia_valid = ATTR_SIZE | ATTR_FILE;
196
269
ia->ia_file = dst;
198
err = vfsub_notify_change(h_d, ia, dlgt);
270
vfsub_i_lock_nested(h_i, AuLsc_I_CHILD2);
271
err = vfsub_notify_change(h_d, ia, &vargs);
211
284
/* ---------------------------------------------------------------------- */
213
int test_ro(struct super_block *sb, aufs_bindex_t bindex, struct inode *inode)
286
int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
217
291
err = br_rdonly(stobr(sb, bindex));
293
/* pseudo-link after flushed may out of bounds */
296
&& ibstart(inode) <= bindex
297
&& bindex <= ibend(inode)) {
299
* permission check is unnecessary since later vfsub routine
219
302
struct inode *hi = au_h_iptr_i(inode, bindex);
221
304
err = IS_IMMUTABLE(hi) ? -EROFS : 0;
228
313
if (!current->fsuid)
230
if (unlikely(au_is_nfs(hidden_inode->i_sb)
315
if (unlikely(au_test_nfs(hidden_inode->i_sb)
231
316
&& (mask & MAY_WRITE)
232
317
&& S_ISDIR(hidden_inode->i_mode)))
233
318
mask |= MAY_READ; /* force permission check */
319
//todo: fake nameidata
234
320
return vfsub_permission(hidden_inode, mask, NULL, dlgt);