1 Index: linux-2.6.12.2/fs/namei.c
2 ===================================================================
3 --- linux-2.6.12.2.orig/fs/namei.c 2005-07-23 12:25:12.241868120 +0200
4 +++ linux-2.6.12.2/fs/namei.c 2005-07-23 12:25:14.440533872 +0200
9 - error = do_truncate(dentry, 0);
10 + error = do_truncate(dentry, 0, 1);
12 put_write_access(inode);
16 struct dentry * dentry;
18 + intent_init(&nd.intent, IT_LOOKUP);
22 @@ -1729,6 +1730,15 @@
23 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
27 + if (nd.dentry->d_inode->i_op->mknod_raw) {
28 + struct inode_operations *op = nd.dentry->d_inode->i_op;
29 + error = op->mknod_raw(&nd, mode, dev);
30 + /* the file system wants to use normal vfs path now */
31 + if (error != -EOPNOTSUPP)
35 dentry = lookup_create(&nd, 0);
36 error = PTR_ERR(dentry);
41 up(&nd.dentry->d_inode->i_sem);
46 @@ -1796,10 +1807,18 @@
48 struct dentry *dentry;
50 + intent_init(&nd.intent, IT_LOOKUP);
52 error = path_lookup(tmp, LOOKUP_PARENT, &nd);
55 + if (nd.dentry->d_inode->i_op->mkdir_raw) {
56 + struct inode_operations *op = nd.dentry->d_inode->i_op;
57 + error = op->mkdir_raw(&nd, mode);
58 + /* the file system wants to use normal vfs path now */
59 + if (error != -EOPNOTSUPP)
62 dentry = lookup_create(&nd, 1);
63 error = PTR_ERR(dentry);
64 if (!IS_ERR(dentry)) {
68 up(&nd.dentry->d_inode->i_sem);
75 struct dentry *dentry;
77 + intent_init(&nd.intent, IT_LOOKUP);
79 name = getname(pathname);
81 @@ -1905,6 +1926,16 @@
86 + if (nd.dentry->d_inode->i_op->rmdir_raw) {
87 + struct inode_operations *op = nd.dentry->d_inode->i_op;
89 + error = op->rmdir_raw(&nd);
90 + /* the file system wants to use normal vfs path now */
91 + if (error != -EOPNOTSUPP)
95 down(&nd.dentry->d_inode->i_sem);
96 dentry = lookup_hash(&nd.last, nd.dentry);
97 error = PTR_ERR(dentry);
99 struct dentry *dentry;
101 struct inode *inode = NULL;
102 + intent_init(&nd.intent, IT_LOOKUP);
104 name = getname(pathname);
106 @@ -1974,6 +2006,13 @@
108 if (nd.last_type != LAST_NORM)
110 + if (nd.dentry->d_inode->i_op->unlink_raw) {
111 + struct inode_operations *op = nd.dentry->d_inode->i_op;
112 + error = op->unlink_raw(&nd);
113 + /* the file system wants to use normal vfs path now */
114 + if (error != -EOPNOTSUPP)
117 down(&nd.dentry->d_inode->i_sem);
118 dentry = lookup_hash(&nd.last, nd.dentry);
119 error = PTR_ERR(dentry);
120 @@ -2040,10 +2079,18 @@
122 struct dentry *dentry;
124 + intent_init(&nd.intent, IT_LOOKUP);
126 error = path_lookup(to, LOOKUP_PARENT, &nd);
129 + if (nd.dentry->d_inode->i_op->symlink_raw) {
130 + struct inode_operations *op = nd.dentry->d_inode->i_op;
131 + error = op->symlink_raw(&nd, from);
132 + /* the file system wants to use normal vfs path now */
133 + if (error != -EOPNOTSUPP)
136 dentry = lookup_create(&nd, 0);
137 error = PTR_ERR(dentry);
138 if (!IS_ERR(dentry)) {
139 @@ -2051,6 +2098,7 @@
142 up(&nd.dentry->d_inode->i_sem);
147 @@ -2114,6 +2162,8 @@
148 struct nameidata nd, old_nd;
151 + intent_init(&nd.intent, IT_LOOKUP);
152 + intent_init(&old_nd.intent, IT_LOOKUP);
154 to = getname(newname);
156 @@ -2128,6 +2178,13 @@
158 if (old_nd.mnt != nd.mnt)
160 + if (nd.dentry->d_inode->i_op->link_raw) {
161 + struct inode_operations *op = nd.dentry->d_inode->i_op;
162 + error = op->link_raw(&old_nd, &nd);
163 + /* the file system wants to use normal vfs path now */
164 + if (error != -EOPNOTSUPP)
167 new_dentry = lookup_create(&nd, 0);
168 error = PTR_ERR(new_dentry);
169 if (!IS_ERR(new_dentry)) {
170 @@ -2300,6 +2357,8 @@
171 struct dentry * old_dentry, *new_dentry;
172 struct dentry * trap;
173 struct nameidata oldnd, newnd;
174 + intent_init(&oldnd.intent, IT_LOOKUP);
175 + intent_init(&newnd.intent, IT_LOOKUP);
177 error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
179 @@ -2322,6 +2381,13 @@
180 if (newnd.last_type != LAST_NORM)
183 + if (old_dir->d_inode->i_op->rename_raw) {
184 + error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd);
185 + /* the file system wants to use normal vfs path now */
186 + if (error != -EOPNOTSUPP)
190 trap = lock_rename(new_dir, old_dir);
192 old_dentry = lookup_hash(&oldnd.last, old_dir);
193 @@ -2353,8 +2419,7 @@
194 if (new_dentry == trap)
197 - error = vfs_rename(old_dir->d_inode, old_dentry,
198 - new_dir->d_inode, new_dentry);
199 + error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry);
203 Index: linux-2.6.12.2/fs/open.c
204 ===================================================================
205 --- linux-2.6.12.2.orig/fs/open.c 2005-07-23 12:25:12.248867056 +0200
206 +++ linux-2.6.12.2/fs/open.c 2005-07-23 12:28:13.221355056 +0200
211 -int do_truncate(struct dentry *dentry, loff_t length)
212 +int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
215 + struct inode_operations *op = dentry->d_inode->i_op;
216 struct iattr newattrs;
218 /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
220 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
222 down(&dentry->d_inode->i_sem);
223 - err = notify_change(dentry, &newattrs);
224 + if (called_from_open)
225 + newattrs.ia_valid |= ATTR_FROM_OPEN;
226 + if (op->setattr_raw) {
227 + newattrs.ia_valid |= ATTR_RAW;
228 + newattrs.ia_ctime = CURRENT_TIME;
229 + down_write(&dentry->d_inode->i_alloc_sem);
230 + err = op->setattr_raw(dentry->d_inode, &newattrs);
231 + up_write(&dentry->d_inode->i_alloc_sem);
233 + err = notify_change(dentry, &newattrs);
234 up(&dentry->d_inode->i_sem);
238 error = locks_verify_truncate(inode, NULL, length);
241 - error = do_truncate(nd.dentry, length);
242 + error = do_truncate(nd.dentry, length, 0);
244 put_write_access(inode);
248 error = locks_verify_truncate(inode, file, length);
250 - error = do_truncate(dentry, length);
251 + error = do_truncate(dentry, length, 0);
256 (error = permission(inode,MAY_WRITE,&nd)) != 0)
259 - down(&inode->i_sem);
260 - error = notify_change(nd.dentry, &newattrs);
262 + if (inode->i_op->setattr_raw) {
263 + struct inode_operations *op = nd.dentry->d_inode->i_op;
265 + newattrs.ia_valid |= ATTR_RAW;
266 + error = op->setattr_raw(inode, &newattrs);
267 + /* the file system wants to use normal vfs path now */
268 + if (error != -EOPNOTSUPP)
271 + down(&inode->i_sem);
272 + error = notify_change(nd.dentry, &newattrs);
279 (error = permission(inode,MAY_WRITE,&nd)) != 0)
282 - down(&inode->i_sem);
283 - error = notify_change(nd.dentry, &newattrs);
285 + if (inode->i_op->setattr_raw) {
286 + struct inode_operations *op = nd.dentry->d_inode->i_op;
288 + newattrs.ia_valid |= ATTR_RAW;
289 + error = op->setattr_raw(inode, &newattrs);
290 + /* the file system wants to use normal vfs path now */
291 + if (error != -EOPNOTSUPP)
294 + down(&inode->i_sem);
295 + error = notify_change(nd.dentry, &newattrs);
301 @@ -596,36 +626,52 @@
305 -asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
306 +int chmod_common(struct dentry *dentry, mode_t mode)
308 - struct inode * inode;
309 - struct dentry * dentry;
310 - struct file * file;
312 + struct inode * inode = dentry->d_inode;
313 struct iattr newattrs;
314 + int error = -EROFS;
318 + if (IS_RDONLY(inode))
321 + if (inode->i_op->setattr_raw) {
322 + struct inode_operations *op = dentry->d_inode->i_op;
324 + newattrs.ia_mode = mode;
325 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
326 + newattrs.ia_valid |= ATTR_RAW;
327 + error = op->setattr_raw(inode, &newattrs);
328 + /* the file system wants to use normal vfs path now */
329 + if (error != -EOPNOTSUPP)
333 - dentry = file->f_dentry;
334 - inode = dentry->d_inode;
337 - if (IS_RDONLY(inode))
341 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
346 if (mode == (mode_t) -1)
347 mode = inode->i_mode;
348 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
349 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
350 - err = notify_change(dentry, &newattrs);
351 + error = notify_change(dentry, &newattrs);
358 +asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
360 + struct file * file;
367 + err = chmod_common(file->f_dentry, mode);
371 @@ -634,32 +680,13 @@
372 asmlinkage long sys_chmod(const char __user * filename, mode_t mode)
375 - struct inode * inode;
377 - struct iattr newattrs;
379 error = user_path_walk(filename, &nd);
382 - inode = nd.dentry->d_inode;
385 - if (IS_RDONLY(inode))
389 - if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
392 - down(&inode->i_sem);
393 - if (mode == (mode_t) -1)
394 - mode = inode->i_mode;
395 - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
396 - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
397 - error = notify_change(nd.dentry, &newattrs);
401 + error = chmod_common(nd.dentry, mode);
406 if (IS_RDONLY(inode))
409 + if (inode->i_op->setattr_raw) {
410 + struct inode_operations *op = dentry->d_inode->i_op;
412 + newattrs.ia_uid = user;
413 + newattrs.ia_gid = group;
414 + newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
415 + newattrs.ia_valid |= ATTR_RAW;
416 + error = op->setattr_raw(inode, &newattrs);
417 + /* the file system wants to use normal vfs path now */
418 + if (error != -EOPNOTSUPP)
421 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
423 newattrs.ia_valid = ATTR_CTIME;
426 if (!S_ISDIR(inode->i_mode))
427 newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
430 error = notify_change(dentry, &newattrs);
432 Index: linux-2.6.12.2/fs/exec.c
433 ===================================================================
434 --- linux-2.6.12.2.orig/fs/exec.c 2005-07-23 12:25:12.229869944 +0200
435 +++ linux-2.6.12.2/fs/exec.c 2005-07-23 12:25:14.442533568 +0200
436 @@ -1488,7 +1488,7 @@
438 if (!file->f_op->write)
440 - if (do_truncate(file->f_dentry, 0) != 0)
441 + if (do_truncate(file->f_dentry, 0, 0) != 0)
444 retval = binfmt->core_dump(signr, regs, file);
445 Index: linux-2.6.12.2/include/linux/fs.h
446 ===================================================================
447 --- linux-2.6.12.2.orig/include/linux/fs.h 2005-07-23 12:25:12.279862344 +0200
448 +++ linux-2.6.12.2/include/linux/fs.h 2005-07-23 12:25:14.443533416 +0200
449 @@ -960,13 +960,20 @@
450 int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
451 struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
452 int (*link) (struct dentry *,struct inode *,struct dentry *);
453 + int (*link_raw) (struct nameidata *,struct nameidata *);
454 int (*unlink) (struct inode *,struct dentry *);
455 + int (*unlink_raw) (struct nameidata *);
456 int (*symlink) (struct inode *,struct dentry *,const char *);
457 + int (*symlink_raw) (struct nameidata *,const char *);
458 int (*mkdir) (struct inode *,struct dentry *,int);
459 + int (*mkdir_raw) (struct nameidata *,int);
460 int (*rmdir) (struct inode *,struct dentry *);
461 + int (*rmdir_raw) (struct nameidata *);
462 int (*mknod) (struct inode *,struct dentry *,int,dev_t);
463 + int (*mknod_raw) (struct nameidata *,int,dev_t);
464 int (*rename) (struct inode *, struct dentry *,
465 struct inode *, struct dentry *);
466 + int (*rename_raw) (struct nameidata *, struct nameidata *);
467 int (*readlink) (struct dentry *, char __user *,int);
468 int (*follow_link) (struct dentry *, struct nameidata *);
469 void (*put_link) (struct dentry *, struct nameidata *);
470 @@ -1268,7 +1275,7 @@
474 -extern int do_truncate(struct dentry *, loff_t start);
475 +extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
476 extern struct file *filp_open(const char *, int, int);
477 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
478 extern struct file * dentry_open_it(struct dentry *, struct vfsmount *, int, struct lookup_intent *);
479 Index: linux-2.6.12.2/net/unix/af_unix.c
480 ===================================================================
481 --- linux-2.6.12.2.orig/net/unix/af_unix.c 2005-06-30 01:00:53.000000000 +0200
482 +++ linux-2.6.12.2/net/unix/af_unix.c 2005-07-23 12:25:14.445533112 +0200
486 if (sunname->sun_path[0]) {
487 + intent_init(&nd.intent, IT_LOOKUP);
488 err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);