1 Index: linux-2.6/net/unix/af_unix.c
2 ===================================================================
3 --- linux-2.6.orig/net/unix/af_unix.c 2006-07-15 21:01:06.000000000 +0800
4 +++ linux-2.6/net/unix/af_unix.c 2006-07-15 21:01:13.000000000 +0800
5 @@ -706,6 +706,7 @@ static struct sock *unix_find_other(stru
8 if (sunname->sun_path[0]) {
9 + intent_init(&nd.intent, IT_LOOKUP);
10 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
13 Index: linux-2.6/fs/open.c
14 ===================================================================
15 --- linux-2.6.orig/fs/open.c 2006-07-15 21:01:10.000000000 +0800
16 +++ linux-2.6/fs/open.c 2006-07-15 21:01:31.000000000 +0800
17 @@ -198,9 +198,10 @@ out:
20 int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
22 + struct file *filp, int called_from_open)
25 + struct inode_operations *op = dentry->d_inode->i_op;
26 struct iattr newattrs;
28 /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
29 @@ -215,7 +216,17 @@ int do_truncate(struct dentry *dentry, l
32 mutex_lock(&dentry->d_inode->i_mutex);
33 - err = notify_change(dentry, &newattrs);
34 + if (called_from_open)
35 + newattrs.ia_valid |= ATTR_FROM_OPEN;
36 + if (op->setattr_raw) {
37 + newattrs.ia_valid |= ATTR_RAW;
38 + newattrs.ia_ctime = CURRENT_TIME;
39 + down_write(&dentry->d_inode->i_alloc_sem);
40 + err = op->setattr_raw(dentry->d_inode, &newattrs);
41 + up_write(&dentry->d_inode->i_alloc_sem);
43 + err = notify_change(dentry, &newattrs);
45 mutex_unlock(&dentry->d_inode->i_mutex);
48 @@ -270,7 +281,7 @@ static long do_sys_truncate(const char _
49 error = locks_verify_truncate(inode, NULL, length);
52 - error = do_truncate(nd.dentry, length, 0, NULL);
53 + error = do_truncate(nd.dentry, length, 0, NULL, 0);
55 put_write_access(inode);
57 @@ -322,7 +333,7 @@ static long do_sys_ftruncate(unsigned in
59 error = locks_verify_truncate(inode, file, length);
61 - error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
62 + error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file, 0);
66 @@ -407,9 +418,20 @@ asmlinkage long sys_utime(char __user *
67 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
70 - mutex_lock(&inode->i_mutex);
71 - error = notify_change(nd.dentry, &newattrs);
72 - mutex_unlock(&inode->i_mutex);
73 + if (inode->i_op->setattr_raw) {
74 + struct inode_operations *op = nd.dentry->d_inode->i_op;
76 + newattrs.ia_valid |= ATTR_RAW;
77 + error = op->setattr_raw(inode, &newattrs);
78 + /* the file system wants to use normal vfs path now */
79 + if (error != -EOPNOTSUPP)
82 + mutex_lock(&inode->i_mutex);
83 + error = notify_change(nd.dentry, &newattrs);
84 + mutex_unlock(&inode->i_mutex);
90 @@ -621,38 +643,53 @@ out:
94 -asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
95 +int chmod_common(struct dentry *dentry, mode_t mode)
97 - struct inode * inode;
98 - struct dentry * dentry;
101 + struct inode * inode = dentry->d_inode;
102 struct iattr newattrs;
106 + int error = -EROFS;
108 + if (IS_RDONLY(inode))
111 - dentry = file->f_dentry;
112 - inode = dentry->d_inode;
113 + if (inode->i_op->setattr_raw) {
114 + struct inode_operations *op = dentry->d_inode->i_op;
116 - audit_inode(NULL, inode);
117 + newattrs.ia_mode = mode;
118 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
119 + newattrs.ia_valid |= ATTR_RAW;
120 + error = op->setattr_raw(inode, &newattrs);
121 + /* the file system wants to use normal vfs path now */
122 + if (error != -EOPNOTSUPP)
127 - if (IS_RDONLY(inode))
131 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
135 mutex_lock(&inode->i_mutex);
136 if (mode == (mode_t) -1)
137 mode = inode->i_mode;
138 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
139 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
140 - err = notify_change(dentry, &newattrs);
141 + error = notify_change(dentry, &newattrs);
142 mutex_unlock(&inode->i_mutex);
149 +asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
151 + struct file * file;
158 + err = chmod_common(file->f_dentry, mode);
162 @@ -662,32 +699,12 @@ asmlinkage long sys_fchmodat(int dfd, co
166 - struct inode * inode;
168 - struct iattr newattrs;
170 error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
173 - inode = nd.dentry->d_inode;
176 - if (IS_RDONLY(inode))
180 - if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
183 - mutex_lock(&inode->i_mutex);
184 - if (mode == (mode_t) -1)
185 - mode = inode->i_mode;
186 - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
187 - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
188 - error = notify_change(nd.dentry, &newattrs);
189 - mutex_unlock(&inode->i_mutex);
192 + error = chmod_common(nd.dentry, mode);
196 @@ -713,6 +730,18 @@ static int chown_common(struct dentry *
197 if (IS_RDONLY(inode))
200 + if (inode->i_op->setattr_raw) {
201 + struct inode_operations *op = dentry->d_inode->i_op;
203 + newattrs.ia_uid = user;
204 + newattrs.ia_gid = group;
205 + newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
206 + newattrs.ia_valid |= ATTR_RAW;
207 + error = op->setattr_raw(inode, &newattrs);
208 + /* the file system wants to use normal vfs path now */
209 + if (error != -EOPNOTSUPP)
212 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
214 newattrs.ia_valid = ATTR_CTIME;
215 Index: linux-2.6/fs/namei.c
216 ===================================================================
217 --- linux-2.6.orig/fs/namei.c 2006-07-15 21:01:10.000000000 +0800
218 +++ linux-2.6/fs/namei.c 2006-07-15 21:01:13.000000000 +0800
219 @@ -1642,7 +1642,7 @@ int may_open(struct nameidata *nd, int a
223 - error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
224 + error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL, 1);
226 put_write_access(inode);
228 @@ -1916,6 +1916,7 @@ asmlinkage long sys_mknodat(int dfd, con
230 struct dentry * dentry;
232 + intent_init(&nd.intent, IT_LOOKUP);
236 @@ -1926,6 +1927,15 @@ asmlinkage long sys_mknodat(int dfd, con
237 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
241 + if (nd.dentry->d_inode->i_op->mknod_raw) {
242 + struct inode_operations *op = nd.dentry->d_inode->i_op;
243 + error = op->mknod_raw(&nd, mode, dev);
244 + /* the file system wants to use normal vfs path now */
245 + if (error != -EOPNOTSUPP)
249 dentry = lookup_create(&nd, 0);
250 error = PTR_ERR(dentry);
252 @@ -1952,6 +1962,7 @@ asmlinkage long sys_mknodat(int dfd, con
255 mutex_unlock(&nd.dentry->d_inode->i_mutex);
260 @@ -1997,9 +2008,18 @@ asmlinkage long sys_mkdirat(int dfd, con
261 struct dentry *dentry;
264 + intent_init(&nd.intent, IT_LOOKUP);
265 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
268 + if (nd.dentry->d_inode->i_op->mkdir_raw) {
269 + struct inode_operations *op = nd.dentry->d_inode->i_op;
270 + error = op->mkdir_raw(&nd, mode);
271 + /* the file system wants to use normal vfs path now */
272 + if (error != -EOPNOTSUPP)
276 dentry = lookup_create(&nd, 1);
277 error = PTR_ERR(dentry);
278 if (!IS_ERR(dentry)) {
279 @@ -2009,6 +2029,7 @@ asmlinkage long sys_mkdirat(int dfd, con
282 mutex_unlock(&nd.dentry->d_inode->i_mutex);
287 @@ -2089,6 +2110,7 @@ static long do_rmdir(int dfd, const char
289 struct dentry *dentry;
291 + intent_init(&nd.intent, IT_LOOKUP);
293 name = getname(pathname);
295 @@ -2109,6 +2131,14 @@ static long do_rmdir(int dfd, const char
299 + if (nd.dentry->d_inode->i_op->rmdir_raw) {
300 + struct inode_operations *op = nd.dentry->d_inode->i_op;
302 + error = op->rmdir_raw(&nd);
303 + /* the file system wants to use normal vfs path now */
304 + if (error != -EOPNOTSUPP)
307 mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
308 dentry = lookup_hash(&nd);
309 error = PTR_ERR(dentry);
310 @@ -2172,6 +2202,7 @@ static long do_unlinkat(int dfd, const c
311 struct dentry *dentry;
313 struct inode *inode = NULL;
314 + intent_init(&nd.intent, IT_LOOKUP);
316 name = getname(pathname);
318 @@ -2183,6 +2214,13 @@ static long do_unlinkat(int dfd, const c
320 if (nd.last_type != LAST_NORM)
322 + if (nd.dentry->d_inode->i_op->unlink_raw) {
323 + struct inode_operations *op = nd.dentry->d_inode->i_op;
324 + error = op->unlink_raw(&nd);
325 + /* the file system wants to use normal vfs path now */
326 + if (error != -EOPNOTSUPP)
329 mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
330 dentry = lookup_hash(&nd);
331 error = PTR_ERR(dentry);
332 @@ -2265,9 +2303,17 @@ asmlinkage long sys_symlinkat(const char
333 struct dentry *dentry;
336 + intent_init(&nd.intent, IT_LOOKUP);
337 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
340 + if (nd.dentry->d_inode->i_op->symlink_raw) {
341 + struct inode_operations *op = nd.dentry->d_inode->i_op;
342 + error = op->symlink_raw(&nd, from);
343 + /* the file system wants to use normal vfs path now */
344 + if (error != -EOPNOTSUPP)
347 dentry = lookup_create(&nd, 0);
348 error = PTR_ERR(dentry);
349 if (!IS_ERR(dentry)) {
350 @@ -2275,6 +2321,7 @@ asmlinkage long sys_symlinkat(const char
353 mutex_unlock(&nd.dentry->d_inode->i_mutex);
358 @@ -2365,6 +2412,13 @@ asmlinkage long sys_linkat(int olddfd, c
360 if (old_nd.mnt != nd.mnt)
362 + if (nd.dentry->d_inode->i_op->link_raw) {
363 + struct inode_operations *op = nd.dentry->d_inode->i_op;
364 + error = op->link_raw(&old_nd, &nd);
365 + /* the file system wants to use normal vfs path now */
366 + if (error != -EOPNOTSUPP)
369 new_dentry = lookup_create(&nd, 0);
370 error = PTR_ERR(new_dentry);
371 if (!IS_ERR(new_dentry)) {
372 @@ -2541,6 +2595,8 @@ static int do_rename(int olddfd, const c
373 struct dentry * old_dentry, *new_dentry;
374 struct dentry * trap;
375 struct nameidata oldnd, newnd;
376 + intent_init(&oldnd.intent, IT_LOOKUP);
377 + intent_init(&newnd.intent, IT_LOOKUP);
379 error = do_path_lookup(olddfd, oldname, LOOKUP_PARENT, &oldnd);
381 @@ -2563,6 +2619,13 @@ static int do_rename(int olddfd, const c
382 if (newnd.last_type != LAST_NORM)
385 + if (old_dir->d_inode->i_op->rename_raw) {
386 + error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
387 + /* the file system wants to use normal vfs path now */
388 + if (error != -EOPNOTSUPP)
392 trap = lock_rename(new_dir, old_dir);
394 old_dentry = lookup_hash(&oldnd);
395 @@ -2594,8 +2657,7 @@ static int do_rename(int olddfd, const c
396 if (new_dentry == trap)
399 - error = vfs_rename(old_dir->d_inode, old_dentry,
400 - new_dir->d_inode, new_dentry);
401 + error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry);
405 Index: linux-2.6/fs/exec.c
406 ===================================================================
407 --- linux-2.6.orig/fs/exec.c 2006-07-15 21:01:10.000000000 +0800
408 +++ linux-2.6/fs/exec.c 2006-07-15 21:01:13.000000000 +0800
409 @@ -1533,7 +1533,7 @@ int do_coredump(long signr, int exit_cod
411 if (!file->f_op->write)
413 - if (do_truncate(file->f_dentry, 0, 0, file) != 0)
414 + if (do_truncate(file->f_dentry, 0, 0, file, 0) != 0)
417 retval = binfmt->core_dump(signr, regs, file);
418 Index: linux-2.6/include/linux/fs.h
419 ===================================================================
420 --- linux-2.6.orig/include/linux/fs.h 2006-07-15 21:01:10.000000000 +0800
421 +++ linux-2.6/include/linux/fs.h 2006-07-15 21:01:13.000000000 +0800
422 @@ -1090,13 +1090,20 @@ struct inode_operations {
423 int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
424 struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
425 int (*link) (struct dentry *,struct inode *,struct dentry *);
426 + int (*link_raw) (struct nameidata *,struct nameidata *);
427 int (*unlink) (struct inode *,struct dentry *);
428 + int (*unlink_raw) (struct nameidata *);
429 int (*symlink) (struct inode *,struct dentry *,const char *);
430 + int (*symlink_raw) (struct nameidata *,const char *);
431 int (*mkdir) (struct inode *,struct dentry *,int);
432 + int (*mkdir_raw) (struct nameidata *,int);
433 int (*rmdir) (struct inode *,struct dentry *);
434 + int (*rmdir_raw) (struct nameidata *);
435 int (*mknod) (struct inode *,struct dentry *,int,dev_t);
436 + int (*mknod_raw) (struct nameidata *,int,dev_t);
437 int (*rename) (struct inode *, struct dentry *,
438 struct inode *, struct dentry *);
439 + int (*rename_raw) (struct nameidata *, struct nameidata *);
440 int (*readlink) (struct dentry *, char __user *,int);
441 void * (*follow_link) (struct dentry *, struct nameidata *);
442 void (*put_link) (struct dentry *, struct nameidata *, void *);
443 @@ -1426,7 +1433,7 @@ static inline int break_lease(struct ino
446 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
447 - struct file *filp);
448 + struct file *filp, int called_from_open);
449 extern long do_sys_open(int fdf, const char __user *filename, int flags,
451 extern struct file *filp_open(const char *, int, int);